| | // src/block.ts |
| | var createDefaultMatcher = (name) => (args, index) => { |
| | if (name === args[index]) { |
| | return { jumpNext: 0, match: true }; |
| | } |
| | return { jumpNext: 0, match: false }; |
| | }; |
| |
|
| | class Block { |
| | arg; |
| | params; |
| | description; |
| | matcher; |
| | children = []; |
| | constructor({ |
| | arg, |
| | params, |
| | description, |
| | matcher, |
| | children = [] |
| | }) { |
| | this.arg = arg; |
| | this.params = params; |
| | this.description = description; |
| | this.children = children; |
| | if (matcher) { |
| | this.matcher = matcher; |
| | } else { |
| | this.matcher = createDefaultMatcher(this.arg); |
| | } |
| | } |
| | findParam(name) { |
| | for (const param of this.params) { |
| | if (param.name === name) { |
| | return param; |
| | } |
| | } |
| | } |
| | findShortParam(name) { |
| | for (const param of this.params) { |
| | if (param.short === name) { |
| | return param; |
| | } |
| | } |
| | } |
| | } |
| |
|
| | // src/parse-param/full.ts |
| | var checkFull = (arg) => { |
| | if (arg.startsWith("--")) { |
| | return true; |
| | } |
| | return false; |
| | }; |
| | var parseFull = (arg1, arg2, block) => { |
| | if (arg1.includes("=")) { |
| | const { name: name2, value } = getNameFromEq(arg1.slice(2)); |
| | const param2 = block.findParam(name2); |
| | if (!param2) { |
| | throw new Error("Unknown param " + arg1); |
| | } |
| | return { values: [{ param: param2, value }], jumpNext: 0 }; |
| | } |
| | const name = arg1.slice(2); |
| | const param = block.findParam(name); |
| | if (!param) { |
| | throw new Error("Unknown param " + arg1); |
| | } |
| | if (param.type === "boolean") { |
| | if (checkBoolValue(arg2)) { |
| | return { values: [{ param, value: arg2 }], jumpNext: 1 }; |
| | } |
| | return { values: [{ param, value: "1" }], jumpNext: 0 }; |
| | } |
| | return { values: [{ param, value: arg2 }], jumpNext: 1 }; |
| | }; |
| |
|
| | // src/parse-param/no.ts |
| | var checkNo = (arg1) => { |
| | if (arg1.startsWith("--no-")) { |
| | return true; |
| | } |
| | return false; |
| | }; |
| | var parseNo = (arg1, block) => { |
| | const param = block.findParam(arg1.slice(5)); |
| | if (!param) { |
| | throw new Error("Unknown param " + arg1); |
| | } |
| | return { values: [{ param, value: "0" }], jumpNext: 0 }; |
| | }; |
| |
|
| | // src/parse-param/short.ts |
| | var checkShort = (arg) => { |
| | if (arg.startsWith("-") && !arg.startsWith("--")) { |
| | return true; |
| | } |
| | return false; |
| | }; |
| | var parseShort = (arg1, arg2, block) => { |
| | if (arg1.length > 2) { |
| | if (arg1.includes("=")) { |
| | const { name: name2, value } = getNameFromEq(arg1.slice(1)); |
| | const param2 = block.findShortParam(name2); |
| | if (!param2) { |
| | throw new Error("Unknown param " + arg1); |
| | } |
| | return { values: [{ param: param2, value }], jumpNext: 0 }; |
| | } |
| | const values = arg1.slice(1).split("").map((name2) => { |
| | const param2 = block.findShortParam(name2); |
| | if (!param2) { |
| | throw new Error("Unknown param: " + arg1 + " No param property for shortkey: " + name2); |
| | } |
| | return { param: param2, value: "1" }; |
| | }); |
| | return { values, jumpNext: 0 }; |
| | } |
| | const name = arg1[1]; |
| | const param = block.findShortParam(name); |
| | if (!param) { |
| | throw new Error("Unknown param " + arg1); |
| | } |
| | if (param.type === "boolean") { |
| | if (checkBoolValue(arg2)) { |
| | return { values: [{ param, value: arg2 }], jumpNext: 1 }; |
| | } |
| | return { values: [{ param, value: "1" }], jumpNext: 0 }; |
| | } |
| | return { values: [{ param, value: arg2 }], jumpNext: 1 }; |
| | }; |
| |
|
| | // src/parse-param/parse-param.ts |
| | var getNameFromEq = (str) => { |
| | const [name, ...values] = str.split("="); |
| | return { |
| | name, |
| | value: values.join("=") |
| | }; |
| | }; |
| | var checkBoolValue = (str) => { |
| | if (str === "1" || str === "0" || str === "true" || str === "false") { |
| | return true; |
| | } |
| | return false; |
| | }; |
| | var parseParam = (arg1, arg2, block) => { |
| | if (checkNo(arg1)) { |
| | return parseNo(arg1, block); |
| | } |
| | if (checkShort(arg1)) { |
| | return parseShort(arg1, arg2, block); |
| | } |
| | if (checkFull(arg1)) { |
| | return parseFull(arg1, arg2, block); |
| | } |
| | return null; |
| | }; |
| |
|
| | // src/parse.ts |
| | var globalArg = "globalArg"; |
| | var createDefaultGlobalBlock = (children) => { |
| | return new Block({ |
| | arg: globalArg, |
| | params: [], |
| | description: `Default global params for app`, |
| | children |
| | }); |
| | }; |
| | var parse = (args, blocks) => { |
| | if (blocks.length === 0) { |
| | throw new Error("Empty blocks"); |
| | } |
| | const globalArgInit = blocks.length === 1 && blocks[0].arg === globalArg; |
| | let currentBlock = globalArgInit ? blocks[0] : createDefaultGlobalBlock(blocks); |
| | const parsedBlocks = [{ arg: currentBlock.arg, params: {} }]; |
| | outer: |
| | for (let i = 0;i < args.length; i++) { |
| | const arg = args[i]; |
| | if (arg.startsWith("-")) { |
| | const nextArg = args[i + 1] || ""; |
| | const { jumpNext, values } = parseParam(arg, nextArg, currentBlock); |
| | const lastParsedBlock = parsedBlocks.at(-1); |
| | for (const { param, value } of values) { |
| | if (param.name in lastParsedBlock.params) { |
| | throw new Error("Param dublicated: " + arg); |
| | } |
| | lastParsedBlock.params[param.name] = value; |
| | } |
| | i += jumpNext; |
| | continue; |
| | } |
| | for (const childBlock of currentBlock.children) { |
| | const { jumpNext, match } = childBlock.matcher(args, i); |
| | if (!match) { |
| | continue; |
| | } |
| | i += jumpNext; |
| | const arg2 = args.slice(i, i + 1 + jumpNext); |
| | parsedBlocks.push({ |
| | arg: arg2.join(" "), |
| | params: {} |
| | }); |
| | currentBlock = childBlock; |
| | continue outer; |
| | } |
| | throw new Error(`Not param or arg: ${arg}`); |
| | } |
| | return globalArgInit ? parsedBlocks : parsedBlocks.slice(1); |
| | }; |
| |
|
| | // src/param.ts |
| | class Param { |
| | name; |
| | type; |
| | short; |
| | defaultValue; |
| | constructor({ |
| | type, |
| | short, |
| | name, |
| | defaultValue |
| | }) { |
| | this.type = type; |
| | this.short = short; |
| | this.name = name; |
| | this.defaultValue = defaultValue; |
| | } |
| | } |
| | export { |
| | parse, |
| | globalArg, |
| | Param, |
| | Block |
| | }; |