zod-commander 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,85 @@
1
+ 'use strict';
2
+
3
+ var commander = require('commander');
4
+ var zod = require('zod');
5
+
6
+ var __defProp = Object.defineProperty;
7
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
8
+ var zodCore = /* @__PURE__ */ __name((zod$1, fn) => {
9
+ const types = [zod.z.ZodDefault, zod.z.ZodNullable, zod.z.ZodOptional];
10
+ for (const type of types)
11
+ if (zod$1 instanceof type) return zodCore(zod$1._def.innerType, fn);
12
+ if (zod$1 instanceof zod.z.ZodEffects) return zodCore(zod$1._def.schema, fn);
13
+ return fn(zod$1);
14
+ }, "zodCore");
15
+ var zodEnumVals = /* @__PURE__ */ __name((zod$1) => zodCore(zod$1, (zod2) => zod2 instanceof zod.z.ZodEnum ? zod2._def.values : null), "zodEnumVals");
16
+ var zodIsBoolean = /* @__PURE__ */ __name((zod$1) => zodCore(zod$1, (zod2) => zod2 instanceof zod.z.ZodBoolean), "zodIsBoolean");
17
+ var zodDefault = /* @__PURE__ */ __name((zod$1) => zod$1 instanceof zod.z.ZodEffects ? zodDefault(zod$1._def.schema) : zod$1 instanceof zod.z.ZodDefault ? zod$1._def.defaultValue() : void 0, "zodDefault");
18
+ var utils = {
19
+ zodCore,
20
+ zodEnumVals,
21
+ zodIsBoolean,
22
+ zodDefault
23
+ };
24
+ var utils_default = utils;
25
+
26
+ // src/index.ts
27
+ var zodParser = /* @__PURE__ */ __name((zod, opt) => (value) => {
28
+ const result = zod.safeParse(value);
29
+ if (result.success) return result.data;
30
+ const msg = result.error.issues[0].message;
31
+ if (opt) throw new commander.InvalidOptionArgumentError(msg);
32
+ throw new commander.InvalidArgumentError(msg);
33
+ }, "zodParser");
34
+ var zodArgument = /* @__PURE__ */ __name((key, zod) => {
35
+ const flag = zod.isOptional() ? `[${key}]` : `<${key}>`;
36
+ const arg = new commander.Argument(flag, zod.description);
37
+ const def = utils_default.zodDefault(zod);
38
+ if (def !== void 0) arg.default(zod.parse(def));
39
+ const choices = utils_default.zodEnumVals(zod);
40
+ if (choices) arg.choices(choices);
41
+ return arg.argParser(zodParser(zod));
42
+ }, "zodArgument");
43
+ var zodOption = /* @__PURE__ */ __name((key, zod) => {
44
+ const abbr = zod.description?.match(/^(\w);/)?.[1];
45
+ const description = abbr ? zod.description.slice(2) : zod.description;
46
+ const arg = key.includes("_") ? key.split("_").slice(1).join("-") : key;
47
+ if (key.includes("_")) [key] = key.split("_");
48
+ const isBoolean = utils_default.zodIsBoolean(zod);
49
+ const flag = `--${key}${isBoolean ? "" : ` <${arg}>`}`;
50
+ const flags = abbr ? `-${abbr}, ${flag}` : flag;
51
+ const opt = new commander.Option(flags, description);
52
+ if (isBoolean) opt.optional = true;
53
+ else if (!zod.isOptional()) opt.makeOptionMandatory();
54
+ const def = utils_default.zodDefault(zod);
55
+ if (def !== void 0) opt.default(zod.parse(def));
56
+ const choices = utils_default.zodEnumVals(zod);
57
+ if (choices) opt.choices(choices);
58
+ return opt.argParser(zodParser(zod, "opt"));
59
+ }, "zodOption");
60
+ var zodCommand = /* @__PURE__ */ __name(({
61
+ name,
62
+ description,
63
+ args,
64
+ opts,
65
+ action
66
+ }) => {
67
+ const command = new commander.Command(name);
68
+ if (description) command.description(description);
69
+ for (const key in args) command.addArgument(zodArgument(key, args[key]));
70
+ for (const key in opts) command.addOption(zodOption(key, opts[key]));
71
+ command.action(async (...all) => {
72
+ const resultArgs = Object.fromEntries(
73
+ Object.keys(args ?? {}).map((key, i) => [key, all[i]])
74
+ );
75
+ const resultOpts = all[Object.keys(args ?? {}).length];
76
+ await action(resultArgs, resultOpts);
77
+ });
78
+ return command;
79
+ }, "zodCommand");
80
+
81
+ exports.zodArgument = zodArgument;
82
+ exports.zodCommand = zodCommand;
83
+ exports.zodOption = zodOption;
84
+ //# sourceMappingURL=index.cjs.map
85
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils.ts","../src/index.ts"],"names":["zod","z","InvalidOptionArgumentError","InvalidArgumentError","Argument","Option","Command"],"mappings":"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","file":"index.cjs","sourcesContent":["import { z } from 'zod'\n\nconst zodCore = <T>(zod: z.ZodTypeAny, fn: (zod: z.ZodTypeAny) => T): T => {\n\tconst types = [z.ZodDefault, z.ZodNullable, z.ZodOptional]\n\tfor (const type of types)\n\t\tif (zod instanceof type) return zodCore(zod._def.innerType, fn)\n\tif (zod instanceof z.ZodEffects) return zodCore(zod._def.schema, fn)\n\treturn fn(zod)\n}\n\nconst zodEnumVals = (zod: z.ZodTypeAny): string[] | null =>\n\tzodCore(zod, (zod) => (zod instanceof z.ZodEnum ? zod._def.values : null))\n\nconst zodIsBoolean = (zod: z.ZodTypeAny): boolean =>\n\tzodCore(zod, (zod) => zod instanceof z.ZodBoolean)\n\nconst zodDefault = <Output, Def extends z.ZodTypeDef, Input>(\n\tzod: z.ZodType<Output, Def, Input>,\n): Input | undefined =>\n\tzod instanceof z.ZodEffects\n\t\t? zodDefault(zod._def.schema)\n\t\t: zod instanceof z.ZodDefault\n\t\t\t? zod._def.defaultValue()\n\t\t\t: undefined\n\nconst utils = {\n\tzodCore,\n\tzodEnumVals,\n\tzodIsBoolean,\n\tzodDefault,\n}\n\nexport default utils\n","import {\n\tArgument,\n\tCommand,\n\tInvalidArgumentError,\n\tInvalidOptionArgumentError,\n\tOption,\n} from 'commander'\nimport type { z } from 'zod'\nimport utils from './utils.js'\n\ntype BeforeFirstUnderscore<S> = S extends `${infer T}_${infer _}` ? T : S\n\ntype ReplaceKeyTypes<Type extends z.ZodRawShape> = {\n\t[Key in keyof Type as BeforeFirstUnderscore<Key>]: Type[Key]\n}\n\ntype Prettify<T> = {\n\t[K in keyof T]: T[K]\n} & {}\n\n/**\n * The action function signature for a Zod-powered command.\n * @template A - ZodRawShape for arguments\n * @template O - ZodRawShape for options\n * @param args - Parsed and validated arguments\n * @param opts - Parsed and validated options (with key normalization)\n * @returns A Promise or void\n */\nexport type ZodCommandAction<\n\tA extends z.ZodRawShape,\n\tO extends z.ZodRawShape,\n> = ZodCommandProps<A, O>['action']\n\ntype ZodCommandProps<A extends z.ZodRawShape, O extends z.ZodRawShape> = {\n\tname: string\n\tdescription?: string\n\targs?: A\n\topts?: O\n\taction: (\n\t\targs: Prettify<z.infer<z.ZodObject<A>>>,\n\t\topts: Prettify<z.infer<z.ZodObject<ReplaceKeyTypes<O>>>>,\n\t) => Promise<void> | void\n}\n\nconst zodParser = (zod: z.ZodTypeAny, opt?: 'opt') => (value: string) => {\n\tconst result = zod.safeParse(value)\n\tif (result.success) return result.data\n\tconst msg = result.error.issues[0].message\n\tif (opt) throw new InvalidOptionArgumentError(msg)\n\tthrow new InvalidArgumentError(msg)\n}\n\n/**\n * Creates a Commander.js Argument from a Zod schema.\n * Handles optionality, default values, and enum choices.\n * @param key - The argument name\n * @param zod - The Zod schema for the argument\n * @returns A Commander Argument instance\n */\nexport const zodArgument = (key: string, zod: z.ZodTypeAny): Argument => {\n\tconst flag = zod.isOptional() ? `[${key}]` : `<${key}>`\n\tconst arg = new Argument(flag, zod.description)\n\n\tconst def = utils.zodDefault(zod)\n\tif (def !== undefined) arg.default(zod.parse(def))\n\n\tconst choices = utils.zodEnumVals(zod)\n\tif (choices) arg.choices(choices)\n\n\t// parsing must be done at the end to override default parsers\n\treturn arg.argParser(zodParser(zod))\n}\n\n/**\n * Creates a Commander.js Option from a Zod schema.\n * Handles optionality, default values, enum choices, and boolean flags.\n * Supports short flags via description prefix (e.g., 's;...').\n * @param key - The option name (can include underscores for grouping)\n * @param zod - The Zod schema for the option\n * @returns A Commander Option instance\n */\nexport const zodOption = (key: string, zod: z.ZodTypeAny): Option => {\n\tconst abbr = zod.description?.match(/^(\\w);/)?.[1]\n\tconst description = abbr ? zod.description.slice(2) : zod.description\n\tconst arg = key.includes('_') ? key.split('_').slice(1).join('-') : key\n\tif (key.includes('_')) [key] = key.split('_')\n\tconst isBoolean = utils.zodIsBoolean(zod)\n\tconst flag = `--${key}${isBoolean ? '' : ` <${arg}>`}`\n\tconst flags = abbr ? `-${abbr}, ${flag}` : flag\n\tconst opt = new Option(flags, description)\n\n\t// required for boolean flags\n\tif (isBoolean) opt.optional = true\n\telse if (!zod.isOptional()) opt.makeOptionMandatory()\n\n\tconst def = utils.zodDefault(zod)\n\tif (def !== undefined) opt.default(zod.parse(def))\n\n\tconst choices = utils.zodEnumVals(zod)\n\tif (choices) opt.choices(choices)\n\n\t// parsing must be done at the end to override default parsers\n\treturn opt.argParser(zodParser(zod, 'opt'))\n}\n\n/**\n * Defines a Commander.js Command using Zod schemas for arguments and options.\n * Automatically wires up parsing, validation, and help configuration.\n * @template A - ZodRawShape for arguments\n * @template O - ZodRawShape for options\n * @param props - Command properties (name, description, args, opts, action)\n * @returns A Commander Command instance\n */\nexport const zodCommand = <A extends z.ZodRawShape, O extends z.ZodRawShape>({\n\tname,\n\tdescription,\n\targs,\n\topts,\n\taction,\n}: ZodCommandProps<A, O>): Command => {\n\tconst command = new Command(name)\n\tif (description) command.description(description)\n\tfor (const key in args) command.addArgument(zodArgument(key, args[key]))\n\tfor (const key in opts) command.addOption(zodOption(key, opts[key]))\n\tcommand.action(async (...all) => {\n\t\tconst resultArgs = Object.fromEntries(\n\t\t\tObject.keys(args ?? {}).map((key, i) => [key, all[i]]),\n\t\t) as z.infer<z.ZodObject<A>>\n\t\tconst resultOpts = all[Object.keys(args ?? {}).length] as z.infer<\n\t\t\tz.ZodObject<ReplaceKeyTypes<O>>\n\t\t>\n\t\tawait action(resultArgs, resultOpts)\n\t})\n\treturn command\n}\n"]}
@@ -0,0 +1,54 @@
1
+ import { Argument, Option, Command } from 'commander';
2
+ import { z } from 'zod';
3
+
4
+ type BeforeFirstUnderscore<S> = S extends `${infer T}_${infer _}` ? T : S;
5
+ type ReplaceKeyTypes<Type extends z.ZodRawShape> = {
6
+ [Key in keyof Type as BeforeFirstUnderscore<Key>]: Type[Key];
7
+ };
8
+ type Prettify<T> = {
9
+ [K in keyof T]: T[K];
10
+ } & {};
11
+ /**
12
+ * The action function signature for a Zod-powered command.
13
+ * @template A - ZodRawShape for arguments
14
+ * @template O - ZodRawShape for options
15
+ * @param args - Parsed and validated arguments
16
+ * @param opts - Parsed and validated options (with key normalization)
17
+ * @returns A Promise or void
18
+ */
19
+ type ZodCommandAction<A extends z.ZodRawShape, O extends z.ZodRawShape> = ZodCommandProps<A, O>['action'];
20
+ type ZodCommandProps<A extends z.ZodRawShape, O extends z.ZodRawShape> = {
21
+ name: string;
22
+ description?: string;
23
+ args?: A;
24
+ opts?: O;
25
+ action: (args: Prettify<z.infer<z.ZodObject<A>>>, opts: Prettify<z.infer<z.ZodObject<ReplaceKeyTypes<O>>>>) => Promise<void> | void;
26
+ };
27
+ /**
28
+ * Creates a Commander.js Argument from a Zod schema.
29
+ * Handles optionality, default values, and enum choices.
30
+ * @param key - The argument name
31
+ * @param zod - The Zod schema for the argument
32
+ * @returns A Commander Argument instance
33
+ */
34
+ declare const zodArgument: (key: string, zod: z.ZodTypeAny) => Argument;
35
+ /**
36
+ * Creates a Commander.js Option from a Zod schema.
37
+ * Handles optionality, default values, enum choices, and boolean flags.
38
+ * Supports short flags via description prefix (e.g., 's;...').
39
+ * @param key - The option name (can include underscores for grouping)
40
+ * @param zod - The Zod schema for the option
41
+ * @returns A Commander Option instance
42
+ */
43
+ declare const zodOption: (key: string, zod: z.ZodTypeAny) => Option;
44
+ /**
45
+ * Defines a Commander.js Command using Zod schemas for arguments and options.
46
+ * Automatically wires up parsing, validation, and help configuration.
47
+ * @template A - ZodRawShape for arguments
48
+ * @template O - ZodRawShape for options
49
+ * @param props - Command properties (name, description, args, opts, action)
50
+ * @returns A Commander Command instance
51
+ */
52
+ declare const zodCommand: <A extends z.ZodRawShape, O extends z.ZodRawShape>({ name, description, args, opts, action, }: ZodCommandProps<A, O>) => Command;
53
+
54
+ export { type ZodCommandAction, zodArgument, zodCommand, zodOption };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- import { Argument, Command, Option } from 'commander';
2
- import type { z } from 'zod';
1
+ import { Argument, Option, Command } from 'commander';
2
+ import { z } from 'zod';
3
+
3
4
  type BeforeFirstUnderscore<S> = S extends `${infer T}_${infer _}` ? T : S;
4
5
  type ReplaceKeyTypes<Type extends z.ZodRawShape> = {
5
6
  [Key in keyof Type as BeforeFirstUnderscore<Key>]: Type[Key];
@@ -15,7 +16,7 @@ type Prettify<T> = {
15
16
  * @param opts - Parsed and validated options (with key normalization)
16
17
  * @returns A Promise or void
17
18
  */
18
- export type ZodCommandAction<A extends z.ZodRawShape, O extends z.ZodRawShape> = ZodCommandProps<A, O>['action'];
19
+ type ZodCommandAction<A extends z.ZodRawShape, O extends z.ZodRawShape> = ZodCommandProps<A, O>['action'];
19
20
  type ZodCommandProps<A extends z.ZodRawShape, O extends z.ZodRawShape> = {
20
21
  name: string;
21
22
  description?: string;
@@ -30,7 +31,7 @@ type ZodCommandProps<A extends z.ZodRawShape, O extends z.ZodRawShape> = {
30
31
  * @param zod - The Zod schema for the argument
31
32
  * @returns A Commander Argument instance
32
33
  */
33
- export declare const zodArgument: (key: string, zod: z.ZodTypeAny) => Argument;
34
+ declare const zodArgument: (key: string, zod: z.ZodTypeAny) => Argument;
34
35
  /**
35
36
  * Creates a Commander.js Option from a Zod schema.
36
37
  * Handles optionality, default values, enum choices, and boolean flags.
@@ -39,7 +40,7 @@ export declare const zodArgument: (key: string, zod: z.ZodTypeAny) => Argument;
39
40
  * @param zod - The Zod schema for the option
40
41
  * @returns A Commander Option instance
41
42
  */
42
- export declare const zodOption: (key: string, zod: z.ZodTypeAny) => Option;
43
+ declare const zodOption: (key: string, zod: z.ZodTypeAny) => Option;
43
44
  /**
44
45
  * Defines a Commander.js Command using Zod schemas for arguments and options.
45
46
  * Automatically wires up parsing, validation, and help configuration.
@@ -48,5 +49,6 @@ export declare const zodOption: (key: string, zod: z.ZodTypeAny) => Option;
48
49
  * @param props - Command properties (name, description, args, opts, action)
49
50
  * @returns A Commander Command instance
50
51
  */
51
- export declare const zodCommand: <A extends z.ZodRawShape, O extends z.ZodRawShape>({ name, description, args, opts, action, }: ZodCommandProps<A, O>) => Command;
52
- export {};
52
+ declare const zodCommand: <A extends z.ZodRawShape, O extends z.ZodRawShape>({ name, description, args, opts, action, }: ZodCommandProps<A, O>) => Command;
53
+
54
+ export { type ZodCommandAction, zodArgument, zodCommand, zodOption };
package/dist/index.js CHANGED
@@ -1,94 +1,81 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
1
+ import { Argument, Option, Command, InvalidOptionArgumentError, InvalidArgumentError } from 'commander';
2
+ import { z } from 'zod';
3
+
4
+ var __defProp = Object.defineProperty;
5
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
6
+ var zodCore = /* @__PURE__ */ __name((zod, fn) => {
7
+ const types = [z.ZodDefault, z.ZodNullable, z.ZodOptional];
8
+ for (const type of types)
9
+ if (zod instanceof type) return zodCore(zod._def.innerType, fn);
10
+ if (zod instanceof z.ZodEffects) return zodCore(zod._def.schema, fn);
11
+ return fn(zod);
12
+ }, "zodCore");
13
+ var zodEnumVals = /* @__PURE__ */ __name((zod) => zodCore(zod, (zod2) => zod2 instanceof z.ZodEnum ? zod2._def.values : null), "zodEnumVals");
14
+ var zodIsBoolean = /* @__PURE__ */ __name((zod) => zodCore(zod, (zod2) => zod2 instanceof z.ZodBoolean), "zodIsBoolean");
15
+ var zodDefault = /* @__PURE__ */ __name((zod) => zod instanceof z.ZodEffects ? zodDefault(zod._def.schema) : zod instanceof z.ZodDefault ? zod._def.defaultValue() : void 0, "zodDefault");
16
+ var utils = {
17
+ zodCore,
18
+ zodEnumVals,
19
+ zodIsBoolean,
20
+ zodDefault
4
21
  };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.zodCommand = exports.zodOption = exports.zodArgument = void 0;
7
- const commander_1 = require("commander");
8
- const utils_1 = __importDefault(require("./utils"));
9
- const zodParser = (zod, opt) => (value) => {
10
- const result = zod.safeParse(value);
11
- if (result.success)
12
- return result.data;
13
- const msg = result.error.issues[0].message;
14
- if (opt)
15
- throw new commander_1.InvalidOptionArgumentError(msg);
16
- throw new commander_1.InvalidArgumentError(msg);
17
- };
18
- /**
19
- * Creates a Commander.js Argument from a Zod schema.
20
- * Handles optionality, default values, and enum choices.
21
- * @param key - The argument name
22
- * @param zod - The Zod schema for the argument
23
- * @returns A Commander Argument instance
24
- */
25
- const zodArgument = (key, zod) => {
26
- const flag = zod.isOptional() ? `[${key}]` : `<${key}>`;
27
- const arg = new commander_1.Argument(flag, zod.description);
28
- const def = utils_1.default.zodDefault(zod);
29
- if (def !== undefined)
30
- arg.default(zod.parse(def));
31
- const choices = utils_1.default.zodEnumVals(zod);
32
- if (choices)
33
- arg.choices(choices);
34
- // parsing must be done at the end to override default parsers
35
- return arg.argParser(zodParser(zod));
36
- };
37
- exports.zodArgument = zodArgument;
38
- /**
39
- * Creates a Commander.js Option from a Zod schema.
40
- * Handles optionality, default values, enum choices, and boolean flags.
41
- * Supports short flags via description prefix (e.g., 's;...').
42
- * @param key - The option name (can include underscores for grouping)
43
- * @param zod - The Zod schema for the option
44
- * @returns A Commander Option instance
45
- */
46
- const zodOption = (key, zod) => {
47
- const abbr = zod.description?.match(/^(\w);/)?.[1];
48
- const description = abbr ? zod.description.slice(2) : zod.description;
49
- const arg = key.includes('_') ? key.split('_').slice(1).join('-') : key;
50
- if (key.includes('_'))
51
- [key] = key.split('_');
52
- const isBoolean = utils_1.default.zodIsBoolean(zod);
53
- const flag = `--${key}${isBoolean ? '' : ` <${arg}>`}`;
54
- const flags = abbr ? `-${abbr}, ${flag}` : flag;
55
- const opt = new commander_1.Option(flags, description);
56
- // required for boolean flags
57
- if (isBoolean)
58
- opt.optional = true;
59
- else if (!zod.isOptional())
60
- opt.makeOptionMandatory();
61
- const def = utils_1.default.zodDefault(zod);
62
- if (def !== undefined)
63
- opt.default(zod.parse(def));
64
- const choices = utils_1.default.zodEnumVals(zod);
65
- if (choices)
66
- opt.choices(choices);
67
- // parsing must be done at the end to override default parsers
68
- return opt.argParser(zodParser(zod, 'opt'));
69
- };
70
- exports.zodOption = zodOption;
71
- /**
72
- * Defines a Commander.js Command using Zod schemas for arguments and options.
73
- * Automatically wires up parsing, validation, and help configuration.
74
- * @template A - ZodRawShape for arguments
75
- * @template O - ZodRawShape for options
76
- * @param props - Command properties (name, description, args, opts, action)
77
- * @returns A Commander Command instance
78
- */
79
- const zodCommand = ({ name, description, args, opts, action, }) => {
80
- const command = new commander_1.Command(name);
81
- if (description)
82
- command.description(description);
83
- for (const key in args)
84
- command.addArgument((0, exports.zodArgument)(key, args[key]));
85
- for (const key in opts)
86
- command.addOption((0, exports.zodOption)(key, opts[key]));
87
- command.action(async (...all) => {
88
- const resultArgs = Object.fromEntries(Object.keys(args ?? {}).map((key, i) => [key, all[i]]));
89
- const resultOpts = all[Object.keys(args ?? {}).length];
90
- await action(resultArgs, resultOpts);
91
- });
92
- return command;
93
- };
94
- exports.zodCommand = zodCommand;
22
+ var utils_default = utils;
23
+
24
+ // src/index.ts
25
+ var zodParser = /* @__PURE__ */ __name((zod, opt) => (value) => {
26
+ const result = zod.safeParse(value);
27
+ if (result.success) return result.data;
28
+ const msg = result.error.issues[0].message;
29
+ if (opt) throw new InvalidOptionArgumentError(msg);
30
+ throw new InvalidArgumentError(msg);
31
+ }, "zodParser");
32
+ var zodArgument = /* @__PURE__ */ __name((key, zod) => {
33
+ const flag = zod.isOptional() ? `[${key}]` : `<${key}>`;
34
+ const arg = new Argument(flag, zod.description);
35
+ const def = utils_default.zodDefault(zod);
36
+ if (def !== void 0) arg.default(zod.parse(def));
37
+ const choices = utils_default.zodEnumVals(zod);
38
+ if (choices) arg.choices(choices);
39
+ return arg.argParser(zodParser(zod));
40
+ }, "zodArgument");
41
+ var zodOption = /* @__PURE__ */ __name((key, zod) => {
42
+ const abbr = zod.description?.match(/^(\w);/)?.[1];
43
+ const description = abbr ? zod.description.slice(2) : zod.description;
44
+ const arg = key.includes("_") ? key.split("_").slice(1).join("-") : key;
45
+ if (key.includes("_")) [key] = key.split("_");
46
+ const isBoolean = utils_default.zodIsBoolean(zod);
47
+ const flag = `--${key}${isBoolean ? "" : ` <${arg}>`}`;
48
+ const flags = abbr ? `-${abbr}, ${flag}` : flag;
49
+ const opt = new Option(flags, description);
50
+ if (isBoolean) opt.optional = true;
51
+ else if (!zod.isOptional()) opt.makeOptionMandatory();
52
+ const def = utils_default.zodDefault(zod);
53
+ if (def !== void 0) opt.default(zod.parse(def));
54
+ const choices = utils_default.zodEnumVals(zod);
55
+ if (choices) opt.choices(choices);
56
+ return opt.argParser(zodParser(zod, "opt"));
57
+ }, "zodOption");
58
+ var zodCommand = /* @__PURE__ */ __name(({
59
+ name,
60
+ description,
61
+ args,
62
+ opts,
63
+ action
64
+ }) => {
65
+ const command = new Command(name);
66
+ if (description) command.description(description);
67
+ for (const key in args) command.addArgument(zodArgument(key, args[key]));
68
+ for (const key in opts) command.addOption(zodOption(key, opts[key]));
69
+ command.action(async (...all) => {
70
+ const resultArgs = Object.fromEntries(
71
+ Object.keys(args ?? {}).map((key, i) => [key, all[i]])
72
+ );
73
+ const resultOpts = all[Object.keys(args ?? {}).length];
74
+ await action(resultArgs, resultOpts);
75
+ });
76
+ return command;
77
+ }, "zodCommand");
78
+
79
+ export { zodArgument, zodCommand, zodOption };
80
+ //# sourceMappingURL=index.js.map
81
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils.ts","../src/index.ts"],"names":["zod"],"mappings":"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","file":"index.js","sourcesContent":["import { z } from 'zod'\n\nconst zodCore = <T>(zod: z.ZodTypeAny, fn: (zod: z.ZodTypeAny) => T): T => {\n\tconst types = [z.ZodDefault, z.ZodNullable, z.ZodOptional]\n\tfor (const type of types)\n\t\tif (zod instanceof type) return zodCore(zod._def.innerType, fn)\n\tif (zod instanceof z.ZodEffects) return zodCore(zod._def.schema, fn)\n\treturn fn(zod)\n}\n\nconst zodEnumVals = (zod: z.ZodTypeAny): string[] | null =>\n\tzodCore(zod, (zod) => (zod instanceof z.ZodEnum ? zod._def.values : null))\n\nconst zodIsBoolean = (zod: z.ZodTypeAny): boolean =>\n\tzodCore(zod, (zod) => zod instanceof z.ZodBoolean)\n\nconst zodDefault = <Output, Def extends z.ZodTypeDef, Input>(\n\tzod: z.ZodType<Output, Def, Input>,\n): Input | undefined =>\n\tzod instanceof z.ZodEffects\n\t\t? zodDefault(zod._def.schema)\n\t\t: zod instanceof z.ZodDefault\n\t\t\t? zod._def.defaultValue()\n\t\t\t: undefined\n\nconst utils = {\n\tzodCore,\n\tzodEnumVals,\n\tzodIsBoolean,\n\tzodDefault,\n}\n\nexport default utils\n","import {\n\tArgument,\n\tCommand,\n\tInvalidArgumentError,\n\tInvalidOptionArgumentError,\n\tOption,\n} from 'commander'\nimport type { z } from 'zod'\nimport utils from './utils.js'\n\ntype BeforeFirstUnderscore<S> = S extends `${infer T}_${infer _}` ? T : S\n\ntype ReplaceKeyTypes<Type extends z.ZodRawShape> = {\n\t[Key in keyof Type as BeforeFirstUnderscore<Key>]: Type[Key]\n}\n\ntype Prettify<T> = {\n\t[K in keyof T]: T[K]\n} & {}\n\n/**\n * The action function signature for a Zod-powered command.\n * @template A - ZodRawShape for arguments\n * @template O - ZodRawShape for options\n * @param args - Parsed and validated arguments\n * @param opts - Parsed and validated options (with key normalization)\n * @returns A Promise or void\n */\nexport type ZodCommandAction<\n\tA extends z.ZodRawShape,\n\tO extends z.ZodRawShape,\n> = ZodCommandProps<A, O>['action']\n\ntype ZodCommandProps<A extends z.ZodRawShape, O extends z.ZodRawShape> = {\n\tname: string\n\tdescription?: string\n\targs?: A\n\topts?: O\n\taction: (\n\t\targs: Prettify<z.infer<z.ZodObject<A>>>,\n\t\topts: Prettify<z.infer<z.ZodObject<ReplaceKeyTypes<O>>>>,\n\t) => Promise<void> | void\n}\n\nconst zodParser = (zod: z.ZodTypeAny, opt?: 'opt') => (value: string) => {\n\tconst result = zod.safeParse(value)\n\tif (result.success) return result.data\n\tconst msg = result.error.issues[0].message\n\tif (opt) throw new InvalidOptionArgumentError(msg)\n\tthrow new InvalidArgumentError(msg)\n}\n\n/**\n * Creates a Commander.js Argument from a Zod schema.\n * Handles optionality, default values, and enum choices.\n * @param key - The argument name\n * @param zod - The Zod schema for the argument\n * @returns A Commander Argument instance\n */\nexport const zodArgument = (key: string, zod: z.ZodTypeAny): Argument => {\n\tconst flag = zod.isOptional() ? `[${key}]` : `<${key}>`\n\tconst arg = new Argument(flag, zod.description)\n\n\tconst def = utils.zodDefault(zod)\n\tif (def !== undefined) arg.default(zod.parse(def))\n\n\tconst choices = utils.zodEnumVals(zod)\n\tif (choices) arg.choices(choices)\n\n\t// parsing must be done at the end to override default parsers\n\treturn arg.argParser(zodParser(zod))\n}\n\n/**\n * Creates a Commander.js Option from a Zod schema.\n * Handles optionality, default values, enum choices, and boolean flags.\n * Supports short flags via description prefix (e.g., 's;...').\n * @param key - The option name (can include underscores for grouping)\n * @param zod - The Zod schema for the option\n * @returns A Commander Option instance\n */\nexport const zodOption = (key: string, zod: z.ZodTypeAny): Option => {\n\tconst abbr = zod.description?.match(/^(\\w);/)?.[1]\n\tconst description = abbr ? zod.description.slice(2) : zod.description\n\tconst arg = key.includes('_') ? key.split('_').slice(1).join('-') : key\n\tif (key.includes('_')) [key] = key.split('_')\n\tconst isBoolean = utils.zodIsBoolean(zod)\n\tconst flag = `--${key}${isBoolean ? '' : ` <${arg}>`}`\n\tconst flags = abbr ? `-${abbr}, ${flag}` : flag\n\tconst opt = new Option(flags, description)\n\n\t// required for boolean flags\n\tif (isBoolean) opt.optional = true\n\telse if (!zod.isOptional()) opt.makeOptionMandatory()\n\n\tconst def = utils.zodDefault(zod)\n\tif (def !== undefined) opt.default(zod.parse(def))\n\n\tconst choices = utils.zodEnumVals(zod)\n\tif (choices) opt.choices(choices)\n\n\t// parsing must be done at the end to override default parsers\n\treturn opt.argParser(zodParser(zod, 'opt'))\n}\n\n/**\n * Defines a Commander.js Command using Zod schemas for arguments and options.\n * Automatically wires up parsing, validation, and help configuration.\n * @template A - ZodRawShape for arguments\n * @template O - ZodRawShape for options\n * @param props - Command properties (name, description, args, opts, action)\n * @returns A Commander Command instance\n */\nexport const zodCommand = <A extends z.ZodRawShape, O extends z.ZodRawShape>({\n\tname,\n\tdescription,\n\targs,\n\topts,\n\taction,\n}: ZodCommandProps<A, O>): Command => {\n\tconst command = new Command(name)\n\tif (description) command.description(description)\n\tfor (const key in args) command.addArgument(zodArgument(key, args[key]))\n\tfor (const key in opts) command.addOption(zodOption(key, opts[key]))\n\tcommand.action(async (...all) => {\n\t\tconst resultArgs = Object.fromEntries(\n\t\t\tObject.keys(args ?? {}).map((key, i) => [key, all[i]]),\n\t\t) as z.infer<z.ZodObject<A>>\n\t\tconst resultOpts = all[Object.keys(args ?? {}).length] as z.infer<\n\t\t\tz.ZodObject<ReplaceKeyTypes<O>>\n\t\t>\n\t\tawait action(resultArgs, resultOpts)\n\t})\n\treturn command\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zod-commander",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "description": "A TypeScript utility for building type-safe CLI commands using commander and zod.",
5
5
  "author": "Román Via-Dufresne Saus <roman910dev@gmail.com>(https://github.com/roman910dev)",
6
6
  "license": "MIT",
@@ -16,22 +16,23 @@
16
16
  ],
17
17
  "devDependencies": {
18
18
  "@biomejs/biome": "^2.0.6",
19
- "@jest/globals": "^30.0.4",
20
19
  "@types/node": "^22.16.3",
21
20
  "commander": "^14.0.0",
22
21
  "husky": "^9.1.7",
23
- "jest": "^30.0.4",
24
- "ts-jest": "^29.4.0",
22
+ "tsup": "^8.5.0",
25
23
  "typescript": "^5.8.3",
24
+ "vitest": "^3.2.4",
26
25
  "zod": "^3.25.0"
27
26
  },
28
- "main": "dist/index.js",
29
- "types": "dist/index.d.ts",
27
+ "main": "./dist/index.cjs",
28
+ "module": "./dist/index.js",
29
+ "types": "./dist/index.d.ts",
30
30
  "exports": {
31
31
  ".": {
32
+ "types": "./dist/index.d.ts",
32
33
  "import": "./dist/index.js",
33
- "require": "./dist/index.js",
34
- "types": "./dist/index.d.ts"
34
+ "require": "./dist/index.cjs",
35
+ "default": "./dist/index.js"
35
36
  }
36
37
  },
37
38
  "files": [
@@ -47,12 +48,16 @@
47
48
  "commander": ">=8 <15",
48
49
  "zod": ">=3.20.0 <4"
49
50
  },
51
+ "type": "module",
50
52
  "scripts": {
51
- "build": "tsc --project tsconfig.build.json",
52
- "lint": "biome check .",
53
- "lint:fix": "biome check --fix --formatter-enabled=false .",
54
- "format": "biome format --write .",
53
+ "build": "tsup",
54
+ "check": "biome check .",
55
+ "fix": "biome check . --write",
56
+ "format": "biome format . --write",
57
+ "full-check": "pnpm ts && pnpm check",
58
+ "lint": "biome lint .",
55
59
  "ci": "biome ci --threads=4",
56
- "test": "jest"
60
+ "test": "vitest",
61
+ "ts": "tsc --noEmit"
57
62
  }
58
63
  }
package/dist/utils.d.ts DELETED
@@ -1,8 +0,0 @@
1
- import { z } from 'zod';
2
- declare const utils: {
3
- zodCore: <T>(zod: z.ZodTypeAny, fn: (zod: z.ZodTypeAny) => T) => T;
4
- zodEnumVals: (zod: z.ZodTypeAny) => string[] | null;
5
- zodIsBoolean: (zod: z.ZodTypeAny) => boolean;
6
- zodDefault: <Output, Def extends z.ZodTypeDef, Input>(zod: z.ZodType<Output, Def, Input>) => Input | undefined;
7
- };
8
- export default utils;
package/dist/utils.js DELETED
@@ -1,26 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const zod_1 = require("zod");
4
- const zodCore = (zod, fn) => {
5
- const types = [zod_1.z.ZodDefault, zod_1.z.ZodNullable, zod_1.z.ZodOptional];
6
- for (const type of types)
7
- if (zod instanceof type)
8
- return zodCore(zod._def.innerType, fn);
9
- if (zod instanceof zod_1.z.ZodEffects)
10
- return zodCore(zod._def.schema, fn);
11
- return fn(zod);
12
- };
13
- const zodEnumVals = (zod) => zodCore(zod, (zod) => (zod instanceof zod_1.z.ZodEnum ? zod._def.values : null));
14
- const zodIsBoolean = (zod) => zodCore(zod, (zod) => zod instanceof zod_1.z.ZodBoolean);
15
- const zodDefault = (zod) => zod instanceof zod_1.z.ZodEffects
16
- ? zodDefault(zod._def.schema)
17
- : zod instanceof zod_1.z.ZodDefault
18
- ? zod._def.defaultValue()
19
- : undefined;
20
- const utils = {
21
- zodCore,
22
- zodEnumVals,
23
- zodIsBoolean,
24
- zodDefault,
25
- };
26
- exports.default = utils;