A typescript wrapper for command-line-args that allow you to generate config from existing TS interfaces
Installations
npm install ts-command-line-args
Developer Guide
Typescript
Yes
Module System
CommonJS
Node Version
16.20.0
NPM Version
8.19.4
Score
98.4
Supply Chain
99.6
Quality
75.2
Maintenance
100
Vulnerability
99.3
License
Releases
Contributors
Unable to fetch Contributors
Languages
TypeScript (93.59%)
JavaScript (6.41%)
Developer
Roaders
Download Statistics
Total Downloads
22,302,078
Last Day
41,260
Last Week
206,361
Last Month
788,298
Last Year
9,520,490
GitHub Statistics
29 Stars
220 Commits
12 Forks
4 Watching
3 Branches
6 Contributors
Bundle Size
94.55 kB
Minified
29.92 kB
Minified + Gzipped
Package Meta Information
Latest Version
2.5.1
Package Id
ts-command-line-args@2.5.1
Unpacked Size
776.18 kB
Size
116.82 kB
File Count
86
NPM Version
8.19.4
Node Version
16.20.0
Publised On
02 Jun 2023
Total Downloads
Cumulative downloads
Total Downloads
22,302,078
Last day
-8.3%
41,260
Compared to previous day
Last week
-16.4%
206,361
Compared to previous week
Last month
-4.2%
788,298
Compared to previous month
Last year
10.4%
9,520,490
Compared to previous year
Daily Downloads
Weekly Downloads
Monthly Downloads
Yearly Downloads
Dev Dependencies
25
ts-command-line-args
A Typescript wrapper around
command-line-args
with additional support for markdown usage guide generation
Features
- Converts command line arguments:
1$ myExampleCli --sourcePath=pathOne --targetPath=pathTwo
into strongly typed objects:
1{ sourcePath: "pathOne", targetPath: "pathTwo"}
- Support for optional values, multiple values, aliases
- Prints a useful error message and exits the process if required arguments are missing:
$ myExampleCli
Required parameter 'sourcePath' was not passed. Please provide a value by running 'myExampleCli --sourcePath=passedValue'
Required parameter 'targetPath' was not passed. Please provide a value by running 'myExampleCli --targetPath=passedValue'
To view the help guide run 'myExampleCli -h'
- Supports printing usage guides to the console with a help argument:
$ myExampleCli -h
My Example CLI
Thanks for using Our Awesome Library
Options
--sourcePath string
--targetPath string
-h, --help Prints this usage guide
- Supports writing the same usage guide to markdown (see Markdown Generation section below, generated by
write-markdown
)
Usage
Take a typescript interface (or type or class):
1interface ICopyFilesArguments{ 2 sourcePath: string; 3 targetPath: string; 4 copyFiles: boolean; 5 resetPermissions: boolean; 6 filter?: string; 7 excludePaths?: string[]; 8}
and use this to enforce the correct generation of options for command-line-args
:
1import { parse } from 'ts-command-line-args'; 2 3// args typed as ICopyFilesArguments 4export const args = parse<ICopyFilesArguments>({ 5 sourcePath: String, 6 targetPath: String, 7 copyFiles: { type: Boolean, alias: 'c' }, 8 resetPermissions: Boolean, 9 filter: { type: String, optional: true }, 10 excludePaths: { type: String, multiple: true, optional: true }, 11});
With the above setup these commands will all work
1$ node exampleConfig.js --sourcePath=source --targetPath=target 2$ node exampleConfig.js --sourcePath source --targetPath target --copyFiles 3$ node exampleConfig.js --sourcePath source --targetPath target -c 4$ node exampleConfig.js --sourcePath source --targetPath target --filter src --excludePaths=one --excludePaths=two 5$ node exampleConfig.js --sourcePath source --targetPath target --filter src --excludePaths one two
Usage Guide
command-line-usage
support is included:
1import { parse } from 'ts-command-line-args'; 2 3interface ICopyFilesArguments { 4 sourcePath: string; 5 targetPath: string; 6 copyFiles: boolean; 7 resetPermissions: boolean; 8 filter?: string; 9 excludePaths?: string[]; 10 help?: boolean; 11} 12 13export const args = parse<ICopyFilesArguments>( 14 { 15 sourcePath: String, 16 targetPath: String, 17 copyFiles: { type: Boolean, alias: 'c', description: 'Copies files rather than moves them' }, 18 resetPermissions: Boolean, 19 filter: { type: String, optional: true }, 20 excludePaths: { type: String, multiple: true, optional: true }, 21 help: { type: Boolean, optional: true, alias: 'h', description: 'Prints this usage guide' }, 22 }, 23 { 24 helpArg: 'help', 25 headerContentSections: [{ header: 'My Example Config', content: 'Thanks for using Our Awesome Library' }], 26 footerContentSections: [{ header: 'Footer', content: `Copyright: Big Faceless Corp. inc.` }], 27 }, 28);
with the above config these commands:
1$ node exampleConfigWithHelp.js -h 2$ node exampleConfigWithHelp.js --help
will give the following output:
My Example Config
Thanks for using Our Awesome Library
Options
--sourcePath string
--targetPath string
-c, --copyFiles Copies files rather than moves them
--resetPermissions
--filter string
--excludePaths string[]
-h, --help Prints this usage guide
Footer
Copyright: Big Faceless Corp. inc.
Loading Config from File
The arguments for an application can also be defined in a config file. The following config allows this:
1interface ICopyFilesArguments { 2 sourcePath: string; 3 targetPath: string; 4 copyFiles: boolean; 5 resetPermissions: boolean; 6 filter?: string; 7 excludePaths?: string[]; 8 configFile?: string; 9 jsonPath?: string; 10} 11 12export const args = parse<ICopyFilesArguments>( 13 { 14 sourcePath: String, 15 targetPath: String, 16 copyFiles: { type: Boolean }, 17 resetPermissions: Boolean, 18 filter: { type: String, optional: true }, 19 excludePaths: { type: String, multiple: true, optional: true }, 20 configFile: { type: String, optional: true }, 21 jsonPath: { type: String, optional: true }, 22 }, 23 { 24 loadFromFileArg: 'configFile', 25 loadFromFileJsonPathArg: 'jsonPath', 26 }, 27);
With this configuration the same command line arguments can be passed:
1$ node exampleConfig.js --sourcePath source --targetPath target
but the user of the script can use a config file instead:
package.json (for example)
1{ 2 "name": "myPackage", 3 "version": "0.1.1", 4 "copyFileConfig": { 5 "copyFileOne": { 6 "sourcePath": "source", 7 "targetPath": "target", 8 "copyFiles": true, 9 "resetPermissions": false, 10 "excludePaths": ["one", "two", "three"] 11 } 12 } 13}
1$ node exampleConfig.js --configFile package.json --jsonPath copyFileConfig.copyFileOne
Any params passed on the command line will ovverride those defined in the file:
1$ node exampleConfig.js --configFile package.json --jsonPath copyFileConfig.copyFileOne --resetPermissions
Boolean values in a file can be overridden by just specfying the argName for true specifying the value:
1$ myCommand --booleanOne --booleanTwo=false --booleanThree false -b=false -o=true --booleanFour=1
When defining settings in a json file the values are still passed through the type
function defined in your config so for this setup:
1interface ISampleConfig { 2 startDate: Date; 3 endDate: Date; 4 inclusive: boolean; 5 includeStart: boolean; 6 includeEnd: boolean; 7} 8 9function parseDate(value: any) { 10 return new Date(Date.parse(value)); 11} 12 13export const args = parse<ISampleConfig>({ 14 startDate: { type: parseDate }, 15 endDate: { type: parseDate }, 16 initialCount: Number, 17 endCount: Number, 18 inclusive: Boolean, 19 includeStart: Boolean, 20 includeEnd: Boolean, 21});
This settings file would be correctly parsed:
1{ 2 "startDate": "01/01/2020", 3 "endDate": "00010201T000000Z", 4 "initialCount": 1, 5 "endCount": "2", 6 "inclusive": true, 7 "includeStart": "false", 8 "includeEnd": 1, 9}
Markdown Generation
A markdown version of the usage guide can be generated and inserted into an existing markdown document.
Markers in the document describe where the content should be inserted, existing content betweeen the markers is overwritten.
write-markdown -m README.MD -j usageGuideConstants.js
write-markdown cli options
Argument | Alias | Type | Description |
---|---|---|---|
markdownPath | m | string | The file to write to. Without replacement markers the whole file content will be replaced. Path can be absolute or relative. |
replaceBelow | string | A marker in the file to replace text below. | |
replaceAbove | string | A marker in the file to replace text above. | |
insertCodeBelow | string | A marker in the file to insert code below. File path to insert must be added at the end of the line and optionally codeComment flag: 'insertToken file="path/toFile.md" codeComment="ts"' | |
insertCodeAbove | string | A marker in the file to insert code above. | |
copyCodeBelow | string | A marker in the file being inserted to say only copy code below this line | |
copyCodeAbove | string | A marker in the file being inserted to say only copy code above this line | |
jsFile | j | string[] | jsFile to 'require' that has an export with the 'UsageGuideConfig' export. Multiple files can be specified. |
configImportName | c | string[] | Export name of the 'UsageGuideConfig' object. Defaults to 'usageGuideInfo'. Multiple exports can be specified. |
verify | v | boolean | Verify the markdown file. Does not update the file but returns a non zero exit code if the markdown file is not correct. Useful for a pre-publish script. |
configFile | f | string | Optional config file to load config from. package.json can be used if jsonPath specified as well |
jsonPath | p | string | Used in conjunction with 'configFile'. The path within the config file to load the config from. For example: 'configs.writeMarkdown' |
verifyMessage | string | Optional message that is printed when markdown verification fails. Use '{fileName}' to refer to the file being processed. | |
removeDoubleBlankLines | boolean | When replacing content removes any more than a single blank line | |
skipFooter | boolean | Does not add the 'Markdown Generated by...' footer to the end of the markdown | |
help | h | boolean | Show this usage guide. |
Default Replacement Markers
replaceBelow defaults to:
'[//]: ####ts-command-line-args_write-markdown_replaceBelow'
replaceAbove defaults to:
'[//]: ####ts-command-line-args_write-markdown_replaceAbove'
insertCodeBelow defaults to:
'[//]: # (ts-command-line-args_write-markdown_insertCodeBelow'
insertCodeAbove defaults to:
'[//]: # (ts-command-line-args_write-markdown_insertCodeAbove)'
copyCodeBelow defaults to:
'// ts-command-line-args_write-markdown_copyCodeBelow'
copyCodeAbove defaults to:
'// ts-command-line-args_write-markdown_copyCodeAbove'
(the Markdown Generation section above was generated using write-markdown
)
Insert Code
Markdown generation can also insert some or all of a file into your markdown. This is useful for including example code. Rather than copying code that will likely get out of date you can directly include code that is checked by your compiler as part of your normal build.
To include code markers must be added to your markdown that indicates which file to copy from. The default marker (which can be changed if desired) is:
[//]: # (ts-command-line-args_write-markdown_insertCodeBelow file="path/from/markdown/to/file.ts" )
CODE INSERTED HERE
[//]: # (ts-command-line-args_write-markdown_insertCodeBelow
Whatever marker you use you must include the file="path/from/markdown/to/file.ts"
in that format.
You can also surround the inserted code with a triple backticks by including codeComment
or codeComment="myLanguage"
. For example:
[//]: # (ts-command-line-args_write-markdown_insertCodeBelow file="path/from/markdown/to/file.ts" codeComment="typescript" )
Areas to include from the file that is being inserted can be designated with more markers within the file. For example:
1export const someExport = "not copied"; 2// ts-command-line-args_write-markdown_copyCodeBelow 3export function (){ 4 //this function will be copied 5} 6// ts-command-line-args_write-markdown_copyCodeAbove
Insert code can also be performed in code:
1async function insertSampleCode() { 2 // this function is inserted into markdown from a ts file using insertCode 3 await insertCode('src/example/insert-code-sample.md', { 4 insertCodeBelow: insertCodeBelowDefault, 5 insertCodeAbove: insertCodeAboveDefault, 6 copyCodeBelow: copyCodeBelowDefault, 7 copyCodeAbove: copyCodeAboveDefault, 8 }); 9}
Snippets
If you have a file that you want to copy multiple chunks of code from snippetName
can be used to specify which section of code you want to copy:
[//]: # (ts-command-line-args_write-markdown_insertCodeBelow file="path/from/markdown/to/file.ts" snippetName="mySnippet" )
1export const someExport = "not copied"; 2// ts-command-line-args_write-markdown_copyCodeBelow mySnippet 3export function (){ 4 //this function will be copied 5} 6// ts-command-line-args_write-markdown_copyCodeAbove
String Formatting
The only chalk modifiers supported when converting to markdown are bold
and italic
.
For example:
{bold bold text} {italic italic text} {italic.bold bold italic text}
will be converted to:
**boldText** *italic text* ***bold italic text***
Additional Modifiers
Two additional style modifiers have been added that are supported when writing markdown. They are removed when printing to the console.
{highlight someText}
surrounds the text in backticks:
someText
and
{code.typescript function(message: string)\\{console.log(message);\\}}
Surrounds the text in triple back ticks (with an optional language specifer, in this case typescript):
1function(message: string){console.log(message);}
Javascript Exports
To generate markdown we must export the argument definitions and options used by command-line-usage
so that we can require
the javascript file and import the definitions when running write-markdown
. We cannot export these values from a javascript file that has any side effects (such as copying files in the case of a copy-files
node executable) as the same side effects would be executed when we are just trying to generate markdown.
For example, if we had a copy-files
application you would organise you code like this:
copy-file.constants.ts:
1export interface ICopyFilesArguments { 2 sourcePath: string; 3 targetPath: string; 4 help?: boolean; 5} 6 7const argumentConfig: ArgumentConfig<ICopyFilesArguments> = { 8 sourcePath: String, 9 targetPath: String, 10 help: { type: Boolean, optional: true, alias: 'h', description: 'Prints this usage guide' }, 11}; 12 13const parseOptions: ParseOptions<ICopyFilesArguments> = { 14 helpArg: 'help', 15 headerContentSections: [{ header: 'copy-files', content: 'Copies files from sourcePath to targetPath' }], 16 } 17 18export const usageGuideInfo: UsageGuideConfig<ICopyFilesArguments> = { 19 arguments: argumentConfig, 20 parseOptions, 21};
copy-file.ts:
1// The file that actually does the work and is executed by node to copy files 2import { usageGuideInfo } from "./copy-file-constants" 3 4const args: ICopyFilesArguments = parse(usageGuideInfo.arguments, usageGuideInfo.parseOptions); 5 6// Perform file copy operations
The usage guide would be displayed on the command line with the following command:
1$ copy-files -h
and markdown would be generated (after typescript had been transpiled into javascript) with:
1$ write-markdown -m markdownFile.md -j copy-file.constants.js
Documentation
This library is a wrapper around command-line-args
so any docs or options for that library should apply to this library as well.
Parse
1function parse<T>(config: ArgumentConfig<T>, options: ParseOptions = {}, exitProcess = true): T
parse
will return an object containing all of your command line options. For example with this config:
1import {parse} from 'ts-command-line-args'; 2 3export const args = parse<ICopyFilesArguments>({ 4 sourcePath: String, 5 targetPath: { type: String, alias: 't' }, 6 copyFiles: { type: Boolean, alias: 'c' }, 7 resetPermissions: Boolean, 8 filter: { type: String, optional: true }, 9 excludePaths: { type: String, multiple: true, optional: true }, 10});
and this command:
1$ node exampleConfig.js --sourcePath mySource --targetPath myTarget
the following object will be returned:
1{ 2 "sourcePath":"mySource", 3 "targetPath":"myTarget", 4 "copyFiles":false, 5 "resetPermissions":false 6}
(booleans are defaulted to false unless they are marked as optional
)
If any required options are omitted (in this case just sourcePath
and targetPath
) then an error message will be logged and the process will exit with no further code will be executed after the call to parse
:
1$ node exampleConfigWithHelp.js 2Required parameter 'sourcePath' was not passed. Please provide a value by passing '--sourcePath=passedValue' in command line arguments 3Required parameter 'targetPath' was not passed. Please provide a value by passing '--targetPath=passedValue' or '-t passedValue' in command line arguments
If you do not want the process to exit that this can be disabled by passing false as the last argument:
1import {parse} from 'ts-command-line-args'; 2 3export const args = parse<ICopyFilesArguments>({ 4 sourcePath: String, 5 targetPath: { type: String, alias: 't' }, 6 copyFiles: { type: Boolean, alias: 'c' }, 7 resetPermissions: Boolean, 8 filter: { type: String, optional: true }, 9 excludePaths: { type: String, multiple: true, optional: true }, 10}, 11{}, // empty options object 12false 13);
In this case errors will still be logged to the console but the process will not exit and code execution will continue after the call to parse
.
Option Definitions
Option definitions must be passed to parse
. For the most part option definitions are the same as OptionDefinition
from command-line-args
except that name
is not required. Name is not required as we pass an object:
1{ 2 propertyName: {} 3}
rather than an array of options:
1[ 2 { name: "propertyName" } 3]
Simple Arguments
For a simple, single, required argument you only need to define the type
:
1parse<IMyInterface>({ 2 stringArg: String, 3 numberArg: Number, 4 });
the type
can be any function with the signature (value?: string) => T | undefined
. The javascript provided functions String
, Number
and Boolean
all do this for simple data types but a function could be written to convert a passed in string value to a Date
for example:
1function parseDate(value?: string) { 2 return value ? new Date(Date.parse(value)) : undefined; 3} 4 5parse<IMyInterface>({ myDate: parseDate });
A similar function could be written for any complex type.
Further Configuration
For anything other than a single, required, simple argument a configuration object must be defined for each argument. This call:
1parse<IMyInterface>({ 2 stringArg: String, 3 numberArg: Number 4 });
and this:
1parse<IMyInterface>({ 2 stringArg: { type: String }, 3 numberArg: { type: Number }, 4 });
are identical.
Optional Arguments
If an argument is optional it must be defined as such to avoid console errors being logged and the process exiting when parse
is called.
This interface:
1{ 2 requiredArg: string, 3 optionalArg?: string, 4}
defines optionalArg
as optional. This must be reflected in the config passed to parse
:
1parse<IMyInterface>({ 2 requiredArg: String, 3 requiredArg: { type: String, optional: true }, 4 });
Typescript compilation will fail in the above case without optional: true
being added.
Multiple Values
If multiple values can be passed then the argument should be defined as an array:
1{ 2 users: string[], 3}
and it must defined as multiple
in the config:
1parse<IMyInterface>({ 2 users: {requiredArg: Number, multiple: true}, 3 });
Typescript compilation will fail in the above case without multiple: true
being added.
Multiple values can be passed on the command line as follows:
1$ node myApp.js users=Jeoff users=Frank users=Dave 2$ node myApp.js users Jeoff users Frank users Dave 3$ node myApp.js users=Jeoff Frank Dave 4$ node myApp.js users Jeoff Frank Dave
For further Option Definition documentation refer to these docs.
Options
Most of the available options are the same as the options defined by command-line-args
: https://github.com/75lb/command-line-args/blob/master/doc/API.md.
A few additional options have been added:
logger - used for logging errors or help guide to the console. Defaults to console.log
and console.error
.
helpArg - used to defined the argument used to generate the usage guide. This is expected to be boolean but the comparison is not strict so any argument type / value that is resolved as truthy will work.
headerContentSections / footerContentSections - optional help sections that will appear before / after the Options
section that is generated from the option config. In most cases you should probably include one header section that explains what the application does.
Markdown Generated by ts-command-line-args
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
no dangerous workflow patterns detected
Reason
3 existing vulnerabilities detected
Details
- Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg
- Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275
- Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv
Reason
dependency not pinned by hash detected -- score normalized to 3
Details
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/Roaders/ts-command-line-args/build.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/Roaders/ts-command-line-args/build.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/create-release.yaml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/Roaders/ts-command-line-args/create-release.yaml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/create-release.yaml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/Roaders/ts-command-line-args/create-release.yaml/main?enable=pin
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/create-release.yaml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/Roaders/ts-command-line-args/create-release.yaml/main?enable=pin
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/create-release.yaml:36: update your workflow using https://app.stepsecurity.io/secureworkflow/Roaders/ts-command-line-args/create-release.yaml/main?enable=pin
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/create-release.yaml:41: update your workflow using https://app.stepsecurity.io/secureworkflow/Roaders/ts-command-line-args/create-release.yaml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test-typescript.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/Roaders/ts-command-line-args/test-typescript.yml/main?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test-typescript.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/Roaders/ts-command-line-args/test-typescript.yml/main?enable=pin
- Warn: npmCommand not pinned by hash: .github/workflows/test-typescript.yml:27
- Info: 0 out of 6 GitHub-owned GitHubAction dependencies pinned
- Info: 0 out of 3 third-party GitHubAction dependencies pinned
- Info: 3 out of 4 npmCommand dependencies pinned
Reason
Found 3/14 approved changesets -- score normalized to 2
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
detected GitHub workflow tokens with excessive permissions
Details
- Warn: no topLevel permission defined: .github/workflows/build.yml:1
- Warn: no topLevel permission defined: .github/workflows/create-release.yaml:1
- Warn: no topLevel permission defined: .github/workflows/test-typescript.yml:1
- Info: no jobLevel write permissions found
Reason
no effort to earn an OpenSSF best practices badge detected
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
Reason
license file not detected
Details
- Warn: project does not have a license file
Reason
project is not fuzzed
Details
- Warn: no fuzzer integrations found
Reason
branch protection not enabled on development/release branches
Details
- Warn: branch protection not enabled for branch 'main'
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
- Warn: 0 commits out of 20 are checked with a SAST tool
Score
3.2
/10
Last Scanned on 2025-01-20
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn MoreOther packages similar to ts-command-line-args
ts-commands
ts-commands
@why-ts/cli
Building robust and maintainable command-line interfaces (CLIs) in TypeScript.
ts-cmdline-prsr
parsing command line args
@hishprorg/dolore-nam
## Note this is a fork of jsinspect that now supports ES2020 standard (and most proposed features), TS and TSX files. It uses Babel 8's parser, upgrading from babylon to the new babel/parser. Support for Flow has been removed in favour of TS.