Node.jsのCLIなツールをいくつかTypeScriptで作っています。
毎回コマンドラインパラメーターの解析が似たような処理になるので、関数にして使い回していました。
せっかくなのでパッケージとして公開しています。
特徴
- コマンドラインパラメーターの解析として、当然指定されたパラメーターの情報に合わせて解析します。
TypeScript用なので解析結果は指定した名前と型のプロパティを持つオブジェクトとして返します。
このときのオブジェクトの型は可能な限り指定されたパラメーターの情報を反映したものにしてあります。 - 指定されたパラメーター情報からヘルプ用の文字列を生成します。
CLIに指定されたパラメーターにエラーがあれば自動的にヘルプ用文字列を表示するようにもできます。 - プロパティの型情報にはパラメーターのヘルプ用の文字列や制約などの情報を載せています。
VS Code
などの型を表示してくれるエディターであれば、プロパティにマウスカーソルを合わせるだけで、そのパラメーターの情報を表示してくれます。
使い方
まずはパッケージをインストールします。
npm install optionalist
ソースコードからインポートします。
import { parse, unnamed, helpString } from 'optionalist';
parseが解析用の関数、unnamed、helpStringは使用するシンボルです。
コマンドラインパラメータの解析にはparse関数にコマンドラインの詳細を指定します。
const options = parse({
help: {
type: 'boolean',
alone: true,
describe: 'このヘルプを表示します。',
},
timeout: {
type: 'number',
default: 5000,
describe: 'タイムアウトまでの時間(単位ミリ秒)を指定します。',
example: 'milliseconds',
},
list: {
multiple: true,
describe: '処理対象のファイルを記載したファイルを指定します。',
example: 'filepath',
},
[unnamed]: {
describe: '処理対象のファイルを指定します。',
example: 'filepath',
},
[helpString]: {
describe: 'サンプル用のプログラム',
showUsageOnError: true,
},
} as const);
解析結果のoptions
はalone: true
が指定されたパラメーターhelp
があるのでUnion型になっています。
そのままでは扱いにくいので、まずはhelp
から処理していきます。
if (options.help) {
options;
// const options: {
// readonly help: true & {
// [description]: ["--help: このヘルプを表示します。", "is specified alone."];
// };
// readonly timeout?: undefined;
// readonly list?: undefined;
// readonly [unnamed]?: undefined;
// readonly [helpString]: string;
// }
process.stdout.write(options[helpString]);
process.exit(0);
}
options.help
がtrueになっていると他のプロパティ([helpString]
を除く)はundefined
になっていてhelp
以外はアクセスできなくなっています。
[helpString]
だけはアクセスできるようになっているので、表示して終了してしまいます。
早期exit
でoptions.help
がtrue
である可能性を潰したら、options
の型はこんな感じになっています。
options;
// const options: {
// readonly [unnamed]: readonly string[];
// readonly [helpString]: string;
// readonly help?: undefined;
// readonly timeout: number & {
// [description]: ["--timeout milliseconds: タイムアウトまでの時間(単位ミリ秒)を指定します。", "as 5000 if omitted."];
// };
// readonly list: readonly string[] & {
// ...;
// };
// }
timeout
はデフォルト値が指定されているので非オプショナルなnumber
、list
は複数指定可能なので string
の配列になっています。
正確にはそれぞれヘルプ用文字列やデフォルト値、複数指定可能などの情報が付加されています。
options.timeout;
// (property) timeout: number & {
// [description]: ["--timeout milliseconds: タイムアウトまでの時間(単位ミリ秒)を指定します。", "as 5000 if omitted."];
// }
options.list;
// (property) list: readonly string[] & {
// [description]: ["--list filepath: 処理対象のファイルを記載したファイルを指定します。", "can be specified multiple."];
// }
パラメーター情報にどういうものが指定できるかはoptionalistの方で確認してください。