{"id":17448246,"url":"https://github.com/gregbrimble/zodcli","last_synced_at":"2025-04-14T19:43:49.745Z","repository":{"id":143179012,"uuid":"614120580","full_name":"GregBrimble/zodcli","owner":"GregBrimble","description":"A CLI parser built with Zod.","archived":false,"fork":false,"pushed_at":"2023-05-15T01:42:04.000Z","size":50,"stargazers_count":43,"open_issues_count":3,"forks_count":3,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-05T02:47:08.462Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/GregBrimble.png","metadata":{"files":{"readme":"README.md","changelog":null,"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":"2023-03-14T23:50:10.000Z","updated_at":"2025-01-07T10:18:27.000Z","dependencies_parsed_at":null,"dependency_job_id":"7c4d7283-42cc-4c73-9640-427037829129","html_url":"https://github.com/GregBrimble/zodcli","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GregBrimble%2Fzodcli","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GregBrimble%2Fzodcli/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GregBrimble%2Fzodcli/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GregBrimble%2Fzodcli/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GregBrimble","download_url":"https://codeload.github.com/GregBrimble/zodcli/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248949670,"owners_count":21188123,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-10-17T20:06:35.259Z","updated_at":"2025-04-14T19:43:49.727Z","avatar_url":"https://github.com/GregBrimble.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# zodcli\n\nA CLI parser built with Zod.\n\n## Getting Started\n\n```\nnpm install --save zodcli zod\n```\n\n```ts\nimport { z } from \"zod\";\nimport { argumentParser } from \"zodcli\";\n\nargumentParser({ options: z.object({ foo: z.string() }).strict() }).parse([\n\t\"--foo=bar\",\n]);\n```\n\n### Using in a CLI\n\nYou can get CLI arguments passed to the script by using `process.argv.slice(2)`:\n\n```ts\n// ./cli.js\n\nimport { z } from \"zod\";\nimport { argumentParser } from \"zodcli\";\n\nconsole.log(\n\targumentParser({ options: z.object({ foo: z.string() }).strict() }).parse(\n\t\tprocess.argv.slice(2)\n\t)\n);\n\n// $ node cli.js --foo=bar\n// { foo: 'bar' }\n```\n\n## API\n\n### `argumentParser`\n\n`argumentParser` is a function which takes an object with the following properties: [`options`](#options) and [`aliases`](#aliases).\n\n#### `options`\n\n`options` is a required property and **must** have a value of a strict Zod object (`z.object({}).strict()`). This ensures that any unrecognized arguments are rejected.\n\n- All properties **must** be in ['camelCase'](https://en.wikipedia.org/wiki/Camel_case) and be exclusively composed of a-z characters. For example:\n\n  - Valid:\n    - `foo`\n    - `catDog`\n  - Invalid:\n    - `Foo`\n    - `cat_dog`\n    - `5`\n    - `a5`\n\n  When parsed, ['--kebab-case'](https://en.wikipedia.org/wiki/Letter_case#Kebab_case) arguments are converted to their respective 'camelCase' properties.\n\n  For example:\n\n  ```ts\n  import { z } from \"zod\";\n  import { argumentParser } from \"zodcli\";\n\n  const options = z\n  \t.object({\n  \t\tfoo: z.string(),\n  \t\tcatDog: z.string(),\n  \t})\n  \t.strict();\n\n  const result = argumentParser({\n  \toptions,\n  }).parse([\"--foo=bar\", \"--cat-dog=fish\"]);\n\n  console.log(result);\n  // { foo: 'bar', catDog: 'fish' }\n  ```\n\n- All values **must** be one of the following Zod types:\n\n  - [`z.literal()`](https://zod.dev/?id=literals)\n  - [`z.string()`](https://zod.dev/?id=strings)\n  - [`z.number()`](https://zod.dev/?id=numbers)\n  - [`z.null()`](https://zod.dev/?id=primitives)\n\n  And these values can be modified/wrapped with any of the following:\n\n  - [`.transform()`](https://zod.dev/?id=transform)\n  - [`.optional()`](https://zod.dev/?id=optional)\n  - [`.default()`](https://zod.dev/?id=default)\n  - [`z.union()`](https://zod.dev/?id=unions)\n  - [`z.array()`](https://zod.dev/?id=arrays)\n\n#### `aliases`\n\n`aliases` is an optional property which allows you to configure argument aliases for options. It is an object where: the properties are lowercase and composed of exclusively a-z charaters; and the values are 'camelCase' strings and appear as properties in the [`options`](#options) object.\n\n## Tips and Tricks\n\n### Parsing\n\nParsing requires an explict `=` between the argument name and its value. For example:\n\n- Valid:\n  - `--foo=bar --cat-dog=fish`\n- Invalid:\n  - `--foo bar --cat-dog fish`\n\n### Implicit Booleans\n\nIf an argument value is omitted, it will be set as `null`. You can use this to accept implicit booleans (boolean arguments whose presence implies `true`) by using a `z.union()`. For example:\n\n```ts\nimport { z } from \"zod\";\nimport { argumentParser } from \"zodcli\";\n\nconst options = z\n\t.object({\n\t\tfoo: z\n\t\t\t.union([\n\t\t\t\tz.literal(\"true\").transform(() =\u003e true),\n\t\t\t\tz.literal(\"false\").transform(() =\u003e false),\n\t\t\t\tz.null().transform(() =\u003e true),\n\t\t\t])\n\t\t\t.default(\"false\"),\n\t})\n\t.strict();\n\nconst result = argumentParser({\n\toptions,\n}).parse([\"--foo\"]);\n\nconsole.log(result);\n// { foo: true }\n```\n\n### Optional Options\n\nYou can make options optional by using the [`.optional()`](https://zod.dev/?id=optionals) modifier. For example:\n\n```ts\nimport { z } from \"zod\";\nimport { argumentParser } from \"zodcli\";\n\nconst options = z\n\t.object({\n\t\tfoo: z.string(),\n\t\tcatDog: z.string().optional(),\n\t})\n\t.strict();\n\nconst result = argumentParser({\n\toptions,\n}).parse([\"--foo=bar\"]);\n\nconsole.log(result);\n// { foo: 'bar' }\n```\n\nOr, to make all options optional, you can use [`.partial()`](https://zod.dev/?id=partial) on the object. For example:\n\n```ts\nimport { z } from \"zod\";\nimport { argumentParser } from \"zodcli\";\n\nconst options = z\n\t.object({\n\t\tfoo: z.string(),\n\t\tcatDog: z.string(),\n\t})\n\t.partial()\n\t.strict();\n\nconst result = argumentParser({\n\toptions,\n}).parse([\"--foo=bar\"]);\n\nconsole.log(result);\n// { foo: 'bar' }\n```\n\nNote, however, that for booleans, you will likely want to keep them required and simply provide a `.default()` false value. For example:\n\n```ts\nimport { z } from \"zod\";\nimport { argumentParser } from \"zodcli\";\n\nconst options = z\n\t.object({\n\t\tfoo: z\n\t\t\t.union([\n\t\t\t\tz.literal(\"true\").transform(() =\u003e true),\n\t\t\t\tz.literal(\"false\").transform(() =\u003e false),\n\t\t\t\tz.null().transform(() =\u003e true),\n\t\t\t])\n\t\t\t.default(\"false\"),\n\t\tcatDog: z.string(),\n\t})\n\t.partial()\n\t.required({ foo: true })\n\t.strict();\n\nconst result = argumentParser({\n\toptions,\n}).parse([]);\n\nconsole.log(result);\n// { foo: false }\n```\n\n### Coercion\n\nYou can [coerce non-string values using Zod](https://zod.dev/?id=coercion-for-primitives). For example:\n\n```ts\nimport { z } from \"zod\";\nimport { argumentParser } from \"zodcli\";\n\nconst options = z\n\t.object({\n\t\tfoo: z.coerce.number(),\n\t})\n\t.strict();\n\nconst result = argumentParser({\n\toptions,\n}).parse([\"--foo=2.2\"]);\n\nconsole.log(result);\n// { foo: 2.2 }\n```\n\n## Roadmap\n\n- [ ] Help message\n- [ ] Commands support\n- [ ] Positionals support\n- [ ] Object support\n- [x] Strict typing of aliases\n- [ ] Improve optionality/booleans\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgregbrimble%2Fzodcli","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgregbrimble%2Fzodcli","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgregbrimble%2Fzodcli/lists"}