{"id":24649201,"url":"https://github.com/daankets/node-cli-advanced","last_synced_at":"2026-04-09T02:32:30.533Z","repository":{"id":42235998,"uuid":"386070956","full_name":"daankets/node-cli-advanced","owner":"daankets","description":"Advanced Node Command Line Interpreter","archived":false,"fork":false,"pushed_at":"2024-06-17T01:08:15.000Z","size":403,"stargazers_count":1,"open_issues_count":5,"forks_count":0,"subscribers_count":1,"default_branch":"develop","last_synced_at":"2026-01-03T20:56:39.476Z","etag":null,"topics":["argument","cli","javascript","node","parser","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/daankets.png","metadata":{"files":{"readme":"README.md","changelog":"HISTORY.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-07-14T20:40:29.000Z","updated_at":"2023-11-27T13:41:59.000Z","dependencies_parsed_at":"2023-11-27T14:44:43.088Z","dependency_job_id":"472c837a-2a69-46b4-907e-77841836a698","html_url":"https://github.com/daankets/node-cli-advanced","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/daankets/node-cli-advanced","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daankets%2Fnode-cli-advanced","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daankets%2Fnode-cli-advanced/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daankets%2Fnode-cli-advanced/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daankets%2Fnode-cli-advanced/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/daankets","download_url":"https://codeload.github.com/daankets/node-cli-advanced/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daankets%2Fnode-cli-advanced/sbom","scorecard":{"id":316171,"data":{"date":"2025-08-11","repo":{"name":"github.com/daankets/node-cli-advanced","commit":"0e3fdbcdea9433d7db0acd5c55f366233297f43c"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Info: jobLevel 'actions' permission set to 'read': .github/workflows/codeql-analysis.yml:28","Info: jobLevel 'contents' permission set to 'read': .github/workflows/codeql-analysis.yml:29","Warn: no topLevel permission defined: .github/workflows/build.yml:1","Warn: no topLevel permission defined: .github/workflows/codeql-analysis.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Code-Review","score":0,"reason":"Found 0/10 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":1,"reason":"dependency not pinned by hash detected -- score normalized to 1","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/daankets/node-cli-advanced/build.yml/develop?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/daankets/node-cli-advanced/build.yml/develop?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:42: update your workflow using https://app.stepsecurity.io/secureworkflow/daankets/node-cli-advanced/codeql-analysis.yml/develop?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:46: update your workflow using https://app.stepsecurity.io/secureworkflow/daankets/node-cli-advanced/codeql-analysis.yml/develop?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:57: update your workflow using https://app.stepsecurity.io/secureworkflow/daankets/node-cli-advanced/codeql-analysis.yml/develop?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:71: update your workflow using https://app.stepsecurity.io/secureworkflow/daankets/node-cli-advanced/codeql-analysis.yml/develop?enable=pin","Info:   0 out of   6 GitHub-owned GitHubAction dependencies pinned","Info:   1 out of   1 npmCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact 1.0.0 not signed: https://api.github.com/repos/daankets/node-cli-advanced/releases/46214304","Warn: release artifact 1.0.0 does not have provenance: https://api.github.com/repos/daankets/node-cli-advanced/releases/46214304"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during GetBranch(master): error during branchesHandler.query: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":7,"reason":"SAST tool detected but not run on all commits","details":["Info: SAST configuration detected: CodeQL","Warn: 0 commits out of 12 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"12 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-4q6p-r6v2-jvc5","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-qrpm-p2h7-hrv2","Warn: Project is vulnerable to: GHSA-mwcw-c2x4-8c55","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-76p7-773f-r4q5","Warn: Project is vulnerable to: GHSA-j8xg-fqg3-53r7"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-18T00:13:32.939Z","repository_id":42235998,"created_at":"2025-08-18T00:13:32.939Z","updated_at":"2025-08-18T00:13:32.939Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31582714,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-08T14:31:17.711Z","status":"online","status_checked_at":"2026-04-09T02:00:06.848Z","response_time":112,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["argument","cli","javascript","node","parser","typescript"],"created_at":"2025-01-25T17:16:20.695Z","updated_at":"2026-04-09T02:32:30.501Z","avatar_url":"https://github.com/daankets.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Node.js CI](https://github.com/daankets/node-cli-advanced/actions/workflows/build.yml/badge.svg)](https://github.com/daankets/node-cli-advanced/actions/workflows/build.yml)\n[![CodeQL](https://github.com/daankets/node-cli-advanced/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/daankets/node-cli-advanced/actions/workflows/codeql-analysis.yml)\n\n# _Advanced\\*_ NodeJS Command Line Interpreter\n\n* See the [Release History](./HISTORY.md)\n\n## Motivation\n\nThis is a TypeScript port and improvement from one of my earlier projects, that I decided to make available as a utility, after using it in various other\nprojects. This typescript based library (ES2015) allows for setting up command line interfaces in a declarative way. I hope it will save you a lot of time.\n\n\u003e **Disclaimer**\n\u003e\n\u003e i've called this package _\\*advanced_ as it is an advancement of the previous version, and has\n\u003e quite a few of new features. But it's up to you to make up your own mind :-)\n\n## Features\n\n- Declare a new CLI Command by creating a Command instance\n- Declare arguments by adding them to the command instance\n- Add parsers for built-in and custom argument types\n\t- String\n\t\t- Pattern (RegExp based)\n\t\t  \u003e **Example**\n\t\t  \u003e\n\t\t  \u003e --examplePattern BE1234567890\n\t\t- RegExp (an expression)\n\t\t  \u003e **Example**\n\t\t  \u003e\n\t\t  \u003e --exampleWithoutFlags ^yes|no$ --exampleWithFlags \"/^yes|no$/i\"\n\t\t- Path (ParsedPath)\n\t\t  \u003e **Example**\n\t\t  \u003e\n\t\t  \u003e --examplePath /some/path/to/a/file/or/dir\n\t- Boolean\n\t  \u003e **Example**\n\t  \u003e\n\t  \u003e --example yes (true)\n\t  \u003e --example false (fals)\n\t  \u003e --example (flag)\n\t- Number\n\t  \u003e **Example**\n\t  \u003e\n\t  \u003e --exampleFloat 1234.5678 --exampleInt 1234\n\t\t- Integer (Number)\n\t\t  \u003e **Example**\n\t\t  \u003e\n\t\t  \u003e --example 1234\n\t- Date (understands literal now)\n\t  \u003e **Example**\n\t  \u003e\n\t  \u003e --when 2021-01-01\n\t- Moment (understands literals now, today, tomorrow, yesterday)\n\t  \u003e **Example**\n\t  \u003e\n\t  \u003e --from 2021-01-01T00:00:00.000+0100 --to today\n\t- Enum\n\t\t- String\n\t\t- Numerical\n\t- ... whatever you implement a parser for\n\n- Declare single vs array arguments (comma separated)\n- Performs validation if required\n- Conditionally required arguments (based on value or absence of other arguments for example)\n- Named arguments (`--say Hello`)\n- Argument shortcodes (`-s Hello`)\n- Positional arguments (`cp \u003csource\u003e \u003ctarget\u003e`)\n- Boolean flag arguments (-R) without value (`cp -R \u003csource\u003e \u003ctarget\u003e`)\n- Set a callback for execution of the command, or provide a diffent callback every time\n- Parsing command lines\n\t- Parse a string\n\t- Parse a string array ()\n\t- Parse process argv\n- Execute after parsing\n- Provide help text and usage (by default on `--help or -?`)\n- Use a custom logger (defaults to console)\n- Strict mode (disallow undeclared arguments)\n- Loading command arguments from an object or file (json, yaml...)\n\n## Usage\n\n### Installation\n\n```bash\n# Install via NPM\nnpm install --save node-commandline-advanced\n\n# Optionally install moment if you are using the moment parser\nnpm install --save moment\n```\n\n\u003e **Note**\n\u003e\n\u003e The library contains TypeScript declarations and source maps\n\n### Declaring a command\n\n```typescript\n// A demo command with strict parsing disabled and a description.\nconst demoCommand = new Command(\"demo\", {strict: false})\n\t.info(\"A demo command\");\n```\n\n### Declaring arguments\n\n```typescript\nconst demoCommand = new Command(\"demo\", true)\n\t.info(\"A demo command\")\n\t// A flag argument\n\t.addArgument({\n\t\tname: \"fast\",\n\t\tshortCode: \"f\",\n\t\tdescription: \"Execute fast!\",\n\t\t// required: false // ALWAYS FALSE FOR FLAGS,\n\t\tparser: BooleanParser,\n\t\t// array: false // ALWAYS FALSE FOR FLAGS\n\t})\n\t.addArgument({\n\t\tname: \"in\",\n\t\tshortCode: \"i\",\n\t\tdescription: \"Input file\",\n\t\t// required: true // REQUIRED BY DEFAULT\n\t\t// parser: null // Default parser parses strings,\n\t\tarray: true // Allow for multiple input files!\n\t})\n\t.addArgument({\n\t\tname: \"optional\",\n\t\trequired: false\n\t})\n```\n\n### All options for `addArgument(...)`\n\n\u003e See the **IArgument** Type as a reference\n\n#### name: string\n\nThe name of the argument. This name will be used in order to add the argument value into the argument Map.\n\nMust be unique.\n\n### parser: IArgumentParser\u003cT\u003e\n\nThe parser defines the type, and can be either:\n\n- A class (constructor) implementing `IArgumentParser\u003cT\u003e`\n- An intance of `IArgumentParser\u003cT\u003e`\n\nA parser instance provides both the parse function and the name property. The name is intended to provide the type for documentation and help output.\n\n### Array arguments\n\nArguments declared as array will first be split on each comma character. Then, the parser will be applied to each part. You can escape a comma within an\nargument using a backslash.\n\n#### For example:\n\n`--example one,two,three,fo\\,ur` will be parsed as `[\"one\",\"tow\",\"three\", \"fo,ur\"]`\n\n## Parsing a command line\n\n```typescript\n// Assume the previously declared demoCommand...\n// parsing will throw if the input is invalid!\nconst instance = demoCommand.parse(\"--fast\", \"-i\", \"/some/path,/some/other/path\");\nconst fast: Boolean = instance.get(\"fast\");\nconst inputFiles: String[] = instance.get(\"in\");\nconst optional: string = instance.get(\"optional\", \"Some optional default\");\n```\n\n## Parsing Node process args\n\n```typescript\nexport {myCommand} from \"./my-command.ts\";\n// Set async handler\nmyCommand.onExecute(async function (args) {\n\t// this is the command instance\n\n\t// Do something async ;-)\n\treturn Promise.resolve(args);\n});\n\n// If this module is the main module, parse process args and execute!\nif (require.main === module) {\n\tconst instance = myCommand.parseProcessArgs();\n\texport default instance.execute();\n}\n```\n\n## Loading argumens from a file\n\n```typescript\nexport {myCommand} from \"./my-command.ts\";\n// Set async handler\nmyCommand.onExecute(async function (args) {\n// this is the command instance\n\n\t// Do something async ;-)\n\treturn Promise.resolve(args);\n});\n\n// If this module is the main module, parse process args and execute!\nif (require.main === module) {\n\t/**\n\t * The second argument is a parser that parsed from string to object, the encoding is optional and defaults to utf-8\n\t * The sectionName option indicates under what key in the object to find the config arguments.\n\t */\n\tconst instance = myCommand.loadFromFile(\"/some/file.json\", (data) =\u003e JSON.parse(data), {encoding: \"utf-8\", sectionName: \"test\"});\n\t// Note that loadFromObject() is available too, and works in a similar way (skips the parser).\n\texport default instance.execute();\n}\n```\n\n## Override --help\n\nBy default, the command instance will add the \"help\" argument with shortcode \"?\" if not declared by your command upon parsing. If the command typed is invalid,\nthe output will be sent to the console.\n\n## Override logging\n\nYou can prevent or redirect logging by providing an alternative logger. Setting the logger to null will prevent logging. The logger expexts the IConsole\ninterface\n\n```typescript\nconst command = new Command(\"demo\", {logger: console});\n```\n\n## Parsers\n\nA parser allows conversion of a string argument into a typed value. They can either be passed to the argument as a class (newable) or as an instance (required\nif the parser needs extra information, like the EnumParser or the PatternParser).\n\n````typescript\n// The enum parsers must be either instantiated with an Enum\nparser: new EnumParser(Demo1Enum)\n// or extended as a custom parser\nparser: Demo1EnumParser\n// Same for PatternParser\nconst ipAddressPattern = /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/\nparser: new PatternParser(ipAddressPattern)\n````\n\nThe following argument parsers are supported out of the box\n\n|parser|type|remark|\n|---|---|---|\n| null | String | Default |\n| BooleanParser | Boolean | Case insensitive, supports 0/1, yes/no, true/false |\n| DateParser | Date | Checks for invalid dates, supports 'now' literal |\n| MomentParser | Moment | Requires MomentJS optional dependency, supports 'now','today','tomorrow','yesterdat' literals. |\n| NumberParser | Number |\n| IntParser | Number | Restricted to integers |\n| ObjectParser | Object | Parses JSON into an object\n| PathParser | ParsedPath | Does not check for target existence |\n| RegExpParser | RegExp | Parses patterns AND flags if provided |\n| EnumParser | enum type | Parses enum keys to their respective values |\n\n## License and Copyright\n\nCopyright ©2021 Daan Kets\n\nThis software is distributed under the included MIT license.\u003cbr\u003e\n_See the included [LICENSE](./LICENSE) file_\n\n## Depencencies\n\n* [moment.js](https://momentjs.com/) - MIT license\n\n  This project can optionally use (but does not depend upon or distribute) the momentjs library.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdaankets%2Fnode-cli-advanced","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdaankets%2Fnode-cli-advanced","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdaankets%2Fnode-cli-advanced/lists"}