🗂

Zod でコマンドライン引数をパースするだけのツールを作った

2022/08/02に公開

自分が欲しい物がなかったのでサクッとでっち上げました

https://github.com/mizchi/zodiarg

なぜ作ったか

  • 軽量で TS フレンドリな CLI ツールがほしい
  • oclif がサブコマンドまで管理してくれるが色々と過剰
    • ジェネレータの生成コードが最新バージョンのものではなく怪しい(メンテされてる?)
    • tsconfig の縛りがあったり、他のライブラリの一部に混ぜづらい
    • type: module で実行できない (手元にESM生成物があった)
  • cmd-ts が使いづらい
    • 単なるバリデータではなく実行 handler まで渡さないといけない
    • これ以上ライブラリ専用の DSL を覚えたくない
  • => 引数パースを突っ込むだけの zod のラッパーでいいじゃん

使い方

$ npm install --save zodiarg zod
// npx ts-node examples/sample.ts --name mizchi --age 34 --dry xxx 1
import { z } from "zod";
import { asNumberString, asBooleanString, parse } from "zodiarg";

const parsed = parse(
  {
    // --key value | --key=value
    options: {
      name: z.string().describe("input your name"),
      env: z.enum(['a', 'b']).describe("env"),
      age: asNumberString.default('1').describe("xxx"), // parse as number
      active: asBooleanString.default('false') // parse as boolean
    },
    // --flagA, --flagB
    flags: {
      dry: z.boolean().default(false),
      shortable: z.boolean().default(false).describe("shortable example"),
    },
    // ... positional args: miz 10
    args: [
      z.string().describe("input your first name"),
      z.string().regex(/^\d+$/).transform(Number)
    ],
    // alias map: s => shortable
    alias: {
      s: 'shortable',
    }
  },
  process.argv.slice(2),
  // Options(default)
  // { help: true, helpWithNoArgs: true }
);

type ParsedInput = typeof parsed; // Inferenced by Zod

main(parsed).catch((err) => {
  console.error(err);
  process.exit(1);
});

async function main(input: ParsedInput) {
  console.log('Parsed Input', input);
}

実行

$ npx ts-node examples/sample.ts --name mizchi --age 34 --dry xxx 1 -s --env a

Parsed Input {
  flags: { dry: true, shortable: true },
  options: { name: 'mizchi', env: 'a', age: 34 },
  args: [ 'xxx', 1 ]
}

-h--help があるとヘルプを実行します

$ npx ts-node examples/sample.ts -h
OPTIONS:
  --name <string>       input your name
  --env <enum: [a] [b]> env
  --age (Optional: 1)   xxx
FLAGS:
  --dry
  --shortable, -s       shortable example
ARGS:
  0     input your first name
  1

便利な点

  • zod の enum や正規表現で入力を表現できる
  • 引数パース以外余計なことをしない | 実行側に要求しない(これが自分にとって一番大事)
  • 簡単な help を自動生成

使ってみてください。 help の生成は雑です。

Discussion