The commandline parser for TypeScript.
optionalistはTypeScript向けに作られたコマンドラインパーザーです。
optionalist.parse
にコマンドラインの詳細を渡して、解析した結果を受け取ります。
const options = optionalist.parse({
[optionalist.helpString]: {
describe: 'The description for command.',
showUsageOnError: true,
},
help: {
type: 'boolean',
alias: ['?', 'h'],
alone: true,
describe: 'Show this help.',
},
init: {
type: 'boolean',
alone: true,
describe: 'Initialize your project.',
},
output: {
type: 'string',
required: true,
describe: 'Specify the filename to output.',
example: 'output_filename',
},
config: {
default: path.resolve('config.json'),
describe: 'Specify the configuration file for your project.',
example: 'config_filename',
},
watch: {
type: 'boolean',
describe: 'Specify when you want to set the watch mode.',
},
timeout: {
type: 'number',
},
[optionalist.unnamed]: {
example: 'script_filename',
describe: 'Specify the script filename(s) to execute.',
},
} as const);
options.help ? options : options.init ? options : options;
// この時点でのoptionsは
// const options:
// | {
// readonly help: true;
// readonly init?: never;
// readonly output?: never;
// readonly config?: never;
// readonly watch?: never;
// readonly timeout?: never;
// readonly [unnamed]?: never;
// readonly [helpString]: string;
// }
// | {
// readonly init: true;
// readonly help?: never;
// readonly output?: never;
// readonly config?: never;
// readonly watch?: never;
// readonly timeout?: never;
// readonly [unnamed]?: never;
// readonly [helpString]: string;
// }
// | {
// readonly [unnamed]: readonly string[];
// readonly [helpString]: string;
// readonly help?: never;
// readonly init?: never;
// readonly output: string;
// readonly config: string;
// readonly watch?: true;
// readonly timeout?: number;
// };
受け取った結果は自動的に型付けされ、もし指定されていればデフォルト値が設定された状態になっています。
// --helpが指定されたとき
if (options.help) {
options;
// このスコープでのoptionsは
// const options: {
// readonly help: true;
// readonly init?: never;
// readonly output?: never;
// readonly config?: never;
// readonly watch?: never;
// readonly timeout?: never;
// readonly [unnamed]?: never;
// readonly [helpString]: string;
// };
// [optionalist.helpString]はコマンドの説明用文字列を返す。
console.log(options[optionalist.helpString]);
// この例では以下のような文字列になる。
// Version: sample 0.0.1
// Usage:
// node sample --output output_filename [--config config_filename] [--watch] [--timeout parameter] [--] [script_filename...]
// node sample --help
// node sample --init
// Description:
// The description for command.
// Options:
// --help, -?, -h
// Show this help.
// --init
// Initialize your project.
// --output output_filename
// Specify the filename to output.
// --config config_filename
// Specify the configuration file for your project.
// --watch
// Specify when you want to set the watch mode.
// --timeout parameter
// [--] [script_filename...]
// Specify the script filename(s) to execute.
//
process.exit(0);
}
options.init ? options : options;
// この時点でのoptionsは
// const options:
// | {
// readonly init: true;
// readonly help?: never;
// readonly output?: never;
// readonly config?: never;
// readonly watch?: never;
// readonly timeout?: never;
// readonly [unnamed]?: never;
// readonly [helpString]: string;
// }
// | {
// readonly [unnamed]: readonly string[];
// readonly [helpString]: string;
// readonly help?: never;
// readonly init?: never;
// readonly output: string;
// readonly config: string;
// readonly watch?: true;
// readonly timeout?: number;
// };
// --initが指定されたとき
if (options.init) {
options;
// このスコープでのoptionsは
// const options: {
// readonly init: true;
// readonly help?: never;
// readonly output?: never;
// readonly config?: never;
// readonly watch?: never;
// readonly timeout?: never;
// readonly [unnamed]?: never;
// readonly [helpString]: string;
// };
initializeProject();
process.exit(0);
}
options;
// この時点でのoptionsは
// const options: {
// readonly [unnamed]: readonly string[];
// readonly [helpString]: string;
// readonly help?: never;
// readonly init?: never;
// readonly output: string;
// readonly config: string;
// readonly watch?: true;
// readonly timeout?: number;
// };
// プロパティはそれぞれ指定された型になっている。
loadConfigfile(options.config);
for (const file of options[optionalist.unnamed]) {
executeFile(file, options.output);
}
if (options.watch) {
const list = options[optionalist.unnamed].slice(0);
watch(list, file => executeFile(file, options.output));
}
コマンドラインの詳細はoptionalist.parse
の第1引数に、以下のように指定します。
-
[optionalist.helpString]
: コマンド全体に関する指定を行います。-
describe
: ヘルプ用文字列で表示される、コマンドの説明を指定します。省略時にはコマンドの説明が表示されません。
-
showUsageOnError
: コマンドラインでの指定に不備があった場合、ヘルプ用文字列を表示して終了するのであればtrue
を指定します。
-
-
[name: string]
: 各オプションの詳細を指定します。実際にコマンドラインパラメーターとして指定するには、
name
が一文字だけの場合は-x
、2文字以上の場合は--xxx
のように指定します。-
type
: オプションの型を指定します。'string'
、'number'
、'boolean'
のいずれかを指定します。'string'
の場合には文字列型、'number'
の場合には数値型、‘boolean'
の場合には真偽値型になります。省略時には
'string'
が指定されたものと見なします。 -
constraints
: 文字列型、数値型の場合、指定できる値への制約を指定します。-
配列が指定された場合は、その中の1つが指定されていないとエラーになります。(
type: 'number'
、もしくはtype: 'string'
) -
min
プロパティを持つオブジェクトが指定された場合は、min
未満の値が指定されるとエラーになります。(type: 'number'
)max
もしくはmaxExclusive
と同時に指定できます。 -
max
プロパティを持つオブジェクトが指定された場合は、max
より大きい値が指定されるとエラーになります。(type: 'number'
)min
もしくはminExclusive
と同時に指定できます。 -
minExclusive
プロパティを持つオブジェクトが指定された場合は、minExclusive
以下の値が指定されるとエラーになります。(type: 'number'
)max
もしくはmaxExclusive
と同時に指定できます。 -
maxExclusive
プロパティを持つオブジェクトが指定された場合は、maxExclusive
以上の値が指定されるとエラーになります。(type: 'number'
)min
もしくはminExclusive
と同時に指定できます。 -
正規表現が指定された場合は、その正規表現にマッチしない値が指定されるとエラーになります。(
type: 'string'
)
type: 'boolean'
の場合には指定できません。 -
-
example
: ヘルプ用文字列でパラメーターとして使用される文字列を指定します。たとえば
{alpha: {example: 'filename'}}
と指定した場合、ヘルプ用文字列では--alpha filename
のように使用されます。type: 'boolean'
の場合には指定できません。 -
alone
: 単独で指定するオプションのときにtrue
を指定します。ほかのオプションは名前付き、無名にかかわらず指定するとエラーになります。
-
required
: 指定が必須なオプションのときにtrue
を指定します。このオプションが指定されていないとエラーになります。
type: 'boolean'
の場合には指定できません。 -
default
: このオプションが省略されたときに使用するデフォルト値を指定します。デフォルト値には
type: 'string'
の場合には文字列を、type: 'number'
の場合には数値を指定しなければなりません。type: 'boolean'
の場合には指定できません。 -
alias
: オプションの別名を指定します。実際にコマンドラインで使用する場合には、
name
と同様に一文字だけの場合は-x
、2文字以上の場合は--xxx
のように指定します。複数指定するには配列で指定します。
-
describe
: オプションの説明を指定します。ヘルプ用文字列で使用されます。
オブジェクトではなく文字列、数値、
true
を指定することも可能です。- 文字列を指定すると
{default: その文字列}
を指定したように扱います。 - 数値を指定すると、
{type: 'number', default: その数値}
を指定したように扱います。 true
を指定すると{type: 'boolean'}
を指定したように扱います。
-
-
[optionalist.unnamed]
: 無名オプションの詳細を指定します。-
example
: ヘルプ用文字列の中で無名オプションを指す名前を指定します。 -
describe
: ヘルプ用文字列の中で使用される無名オプションの説明を指定します。 -
min
: 無名オプションの最小個数を指定します。省略時には最小個数のチェックを行いません。
-
max
: 無名オプションの最大個数を指定します。省略時には最大個数のチェックを行いません。
-
parse
の第2引数には解析するコマンドラインを指定します。
省略時にはprocess.argv
の3番目から解析を開始します。
配列だけでなくIterable<string>
を指定することが可能です。
返値には解析結果を指定されたオプションの名前と型を持つオブジェクトにして返します。
alone
を指定したオプションがある場合は、alone
を指定したオプションだけの型と、それ以外のオプションだけの型のUnion型になっています。
const options = optionalist.parse({aaa: {alone: true, type: 'boolean'}, bbb: '', ccc: 0});
// options:
// | {
// aaa: true; // aaaだけが存在する。
// bbb?: never;
// ccc?: never;
// [unnamed]?: never; // unnamedもなし
// [helpString]: string; // helpStringだけはヘルプのため常に追加
// }
// | {
// aaa?:never; // aaaはなし
// bbb: string;
// ccc: number;
// [unnamed]: string[];
// [helpString]: string; // helpStringだけはヘルプのため常に追加
// }
alone
なオプションが指定された場合、その他のオプションは指定されていないためundefined
になっていることに注意してください。
逆にその他のオプションを使うときはすべてのalone
なオプションが指定されていないことを確認してからでないと、通常のプロパティのようにアクセスできません。これによりalone
なオプションの処理漏れが防げます。
if (options.aaa) {
assert(options.bbb === undefined);
assert(options.ccc === undefined);
process.exit(0);
}
const { bbb,ccc } = options;
assert(typeof bbb === 'string');
assert(typeof ccc === 'number');
通常のオプションはoptionalになっていますが、必須のオプション、およびデフォルト値の指定されたオプションは非optionalとなっています。
const options = optionalist.parse({
aaa: {
type: 'string',
},
bbb: {
required: true,
},
ccc: {
default: 'ccc',
},
});
const { aaa, bbb, ccc } = options;
// aaaにはrequiredもdefaultも指定されていないのでoptional
assert(aaa === undefined || typeof aaa === 'string');
// bbbにはrequiredが指定されているので非optional
assert(typeof bbb === 'string');
// cccにはdefaultが指定されているので非非optional
assert(typeof ccc === 'string');
無名オプションは[optionalist.unnamed]
でstring
の配列として取得できます。
for (const arg of options[optionalist.unnamed]) {
// ...
}
使い方を表示したい場合には、指定された情報から自動的に生成したヘルプ用文字列が[optionalist.helpString]
で取得できます。
またparseの第1引数の[optionalist.helpString]
にshowUsageOnError
を指定していると、コマンドライン引数にエラーがあったとき、使い方を表示して終了します。
const options = optionalist.parse({
// ...
help: {alone: true, type: 'boolean'},
[optionalist.helpString]: {
// コマンドライン引数での指定にエラーがあれば使い方を表示して終了
showUsageOnError: true,
},
});
if (options.help) {
// --helpが指定されたらヘルプを表示して終了
console.log(options[optionalist.helpString]);
process.exit(0);
}
VS Codeなどの型情報が表示されるエディターを使用しているなら、型情報として各パラメーターの説明が表示されます。
const options = optionalist.parse({
// ...
output: {
type: 'string',
required: true,
describe: 'Specify the filename to output.',
example: 'output_filename',
},
// ...
});
のように記述していれば
executeFile(file, options.output);
と記述したときに、output
にマウスカーソルを合わせれば、
(property) output: string & {
[description]: ["--output output_filename: Specify the filename to output.", "is specified always."];
}
のように表示されます。
実際にコマンドラインパラメーターとして指定する際の文字列 --output output_filename
および説明 Specify the filename to output.
と、required
が指定されているので必須パラメーターであることを示す is specified always.
が表示されています。同様にalone
やdefault
などを指定した場合も説明が追加されます。
ただし実際にこの説明文をプロパティとして保持しているわけではないため、アクセスできないことに注意してください。