@optique/zod 1.0.0-dev.1495 → 1.0.0-dev.1500

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/README.md CHANGED
@@ -37,7 +37,9 @@ import { z } from "zod";
37
37
 
38
38
  const cli = run(
39
39
  object({
40
- email: option("--email", zod(z.string().email())),
40
+ email: option("--email",
41
+ zod(z.string().email(), { placeholder: "" }),
42
+ ),
41
43
  }),
42
44
  );
43
45
 
@@ -65,7 +67,9 @@ import { option } from "@optique/core/primitives";
65
67
  import { zod } from "@optique/zod";
66
68
  import { z } from "zod";
67
69
 
68
- const email = option("--email", zod(z.string().email()));
70
+ const email = option("--email",
71
+ zod(z.string().email(), { placeholder: "" }),
72
+ );
69
73
  ~~~~
70
74
 
71
75
  ### URL validation
@@ -75,7 +79,9 @@ import { option } from "@optique/core/primitives";
75
79
  import { zod } from "@optique/zod";
76
80
  import { z } from "zod";
77
81
 
78
- const url = option("--url", zod(z.string().url()));
82
+ const url = option("--url",
83
+ zod(z.string().url(), { placeholder: "" }),
84
+ );
79
85
  ~~~~
80
86
 
81
87
  ### Port numbers with range validation
@@ -90,7 +96,7 @@ import { zod } from "@optique/zod";
90
96
  import { z } from "zod";
91
97
 
92
98
  const port = option("-p", "--port",
93
- zod(z.coerce.number().int().min(1024).max(65535))
99
+ zod(z.coerce.number().int().min(1024).max(65535), { placeholder: 1024 }),
94
100
  );
95
101
  ~~~~
96
102
 
@@ -102,7 +108,7 @@ import { zod } from "@optique/zod";
102
108
  import { z } from "zod";
103
109
 
104
110
  const logLevel = option("--log-level",
105
- zod(z.enum(["debug", "info", "warn", "error"]))
111
+ zod(z.enum(["debug", "info", "warn", "error"]), { placeholder: "debug" }),
106
112
  );
107
113
  ~~~~
108
114
 
@@ -114,7 +120,7 @@ import { zod } from "@optique/zod";
114
120
  import { z } from "zod";
115
121
 
116
122
  const startDate = argument(
117
- zod(z.string().transform((s) => new Date(s)))
123
+ zod(z.string().transform((s) => new Date(s)), { placeholder: new Date(0) }),
118
124
  );
119
125
  ~~~~
120
126
 
@@ -131,6 +137,7 @@ import { message } from "@optique/core/message";
131
137
  import { z } from "zod";
132
138
 
133
139
  const email = option("--email", zod(z.string().email(), {
140
+ placeholder: "",
134
141
  metavar: "EMAIL",
135
142
  errors: {
136
143
  zodError: (error, input) =>
@@ -154,7 +161,7 @@ import { zod } from "@optique/zod";
154
161
  import { z } from "zod";
155
162
 
156
163
  // ✅ Correct
157
- const port = option("-p", zod(z.coerce.number()));
164
+ const port = option("-p", zod(z.coerce.number(), { placeholder: 0 }));
158
165
 
159
166
  // ❌ Won't work (CLI arguments are always strings)
160
167
  // const port = option("-p", zod(z.number()));
@@ -172,7 +179,8 @@ import { z } from "zod";
172
179
 
173
180
  // ❌ Not supported
174
181
  const email = option("--email",
175
- zod(z.string().refine(async (val) => await checkDB(val)))
182
+ zod(z.string().refine(async (val) => await checkDB(val)),
183
+ { placeholder: "" }),
176
184
  );
177
185
  ~~~~
178
186
 
package/dist/index.cjs CHANGED
@@ -302,7 +302,8 @@ function inferChoices(schema) {
302
302
  *
303
303
  * @template T The output type of the Zod schema.
304
304
  * @param schema A Zod schema to validate input against.
305
- * @param options Optional configuration for the parser.
305
+ * @param options Configuration for the parser, including a required
306
+ * `placeholder` value used during deferred prompt resolution.
306
307
  * @returns A value parser that validates inputs using the provided schema.
307
308
  *
308
309
  * @example Basic string validation
@@ -311,7 +312,9 @@ function inferChoices(schema) {
311
312
  * import { zod } from "@optique/zod";
312
313
  * import { option } from "@optique/core/primitives";
313
314
  *
314
- * const email = option("--email", zod(z.string().email()));
315
+ * const email = option("--email",
316
+ * zod(z.string().email(), { placeholder: "" }),
317
+ * );
315
318
  * ```
316
319
  *
317
320
  * @example Number validation with coercion
@@ -322,7 +325,7 @@ function inferChoices(schema) {
322
325
  *
323
326
  * // Use z.coerce for non-string types since CLI args are always strings
324
327
  * const port = option("-p", "--port",
325
- * zod(z.coerce.number().int().min(1024).max(65535))
328
+ * zod(z.coerce.number().int().min(1024).max(65535), { placeholder: 1024 }),
326
329
  * );
327
330
  * ```
328
331
  *
@@ -333,7 +336,7 @@ function inferChoices(schema) {
333
336
  * import { option } from "@optique/core/primitives";
334
337
  *
335
338
  * const logLevel = option("--log-level",
336
- * zod(z.enum(["debug", "info", "warn", "error"]))
339
+ * zod(z.enum(["debug", "info", "warn", "error"]), { placeholder: "debug" }),
337
340
  * );
338
341
  * ```
339
342
  *
@@ -344,21 +347,28 @@ function inferChoices(schema) {
344
347
  * import { message } from "@optique/core/message";
345
348
  * import { option } from "@optique/core/primitives";
346
349
  *
347
- * const email = option("--email", zod(z.string().email(), {
348
- * metavar: "EMAIL",
349
- * errors: {
350
- * zodError: (error, input) =>
351
- * message`Please provide a valid email address, got ${input}.`
352
- * }
353
- * }));
350
+ * const email = option("--email",
351
+ * zod(z.string().email(), {
352
+ * placeholder: "",
353
+ * metavar: "EMAIL",
354
+ * errors: {
355
+ * zodError: (error, input) =>
356
+ * message`Please provide a valid email address, got ${input}.`
357
+ * },
358
+ * }),
359
+ * );
354
360
  * ```
355
361
  *
362
+ * @throws {TypeError} If `options` is missing, not an object, or does not
363
+ * include `placeholder`.
356
364
  * @throws {TypeError} If the resolved `metavar` is an empty string.
357
365
  * @throws {TypeError} If the schema contains async refinements or other async
358
366
  * operations that cannot be executed synchronously.
359
367
  * @since 0.7.0
360
368
  */
361
- function zod$1(schema, options = {}) {
369
+ function zod$1(schema, options) {
370
+ if (options == null || typeof options !== "object") throw new TypeError("zod() requires an options object with a placeholder property.");
371
+ if (!("placeholder" in options)) throw new TypeError("zod() options must include a placeholder property.");
362
372
  const choices = inferChoices(schema);
363
373
  const boolInfo = analyzeBooleanSchema(schema);
364
374
  const metavar = options.metavar ?? (boolInfo.isBoolean ? "BOOLEAN" : inferMetavar(schema));
@@ -427,6 +437,7 @@ function zod$1(schema, options = {}) {
427
437
  const parser = {
428
438
  $mode: "sync",
429
439
  metavar,
440
+ placeholder: options.placeholder,
430
441
  ...boolInfo.exposeChoices ? {
431
442
  choices: Object.freeze([true, false]),
432
443
  suggest(prefix) {
package/dist/index.d.cts CHANGED
@@ -16,6 +16,13 @@ interface ZodParserOptions<T = unknown> {
16
16
  * @default `"VALUE"`
17
17
  */
18
18
  readonly metavar?: NonEmptyString;
19
+ /**
20
+ * A phase-one stand-in value of type `T` used during deferred prompt
21
+ * resolution. Because the output type of a Zod schema cannot be
22
+ * inferred to a concrete default, callers must provide this explicitly.
23
+ * @since 1.0.0
24
+ */
25
+ readonly placeholder: T;
19
26
  /**
20
27
  * Custom formatter for displaying parsed values in help messages.
21
28
  * When not provided, the default formatter is used: primitives use
@@ -58,7 +65,8 @@ interface ZodParserOptions<T = unknown> {
58
65
  *
59
66
  * @template T The output type of the Zod schema.
60
67
  * @param schema A Zod schema to validate input against.
61
- * @param options Optional configuration for the parser.
68
+ * @param options Configuration for the parser, including a required
69
+ * `placeholder` value used during deferred prompt resolution.
62
70
  * @returns A value parser that validates inputs using the provided schema.
63
71
  *
64
72
  * @example Basic string validation
@@ -67,7 +75,9 @@ interface ZodParserOptions<T = unknown> {
67
75
  * import { zod } from "@optique/zod";
68
76
  * import { option } from "@optique/core/primitives";
69
77
  *
70
- * const email = option("--email", zod(z.string().email()));
78
+ * const email = option("--email",
79
+ * zod(z.string().email(), { placeholder: "" }),
80
+ * );
71
81
  * ```
72
82
  *
73
83
  * @example Number validation with coercion
@@ -78,7 +88,7 @@ interface ZodParserOptions<T = unknown> {
78
88
  *
79
89
  * // Use z.coerce for non-string types since CLI args are always strings
80
90
  * const port = option("-p", "--port",
81
- * zod(z.coerce.number().int().min(1024).max(65535))
91
+ * zod(z.coerce.number().int().min(1024).max(65535), { placeholder: 1024 }),
82
92
  * );
83
93
  * ```
84
94
  *
@@ -89,7 +99,7 @@ interface ZodParserOptions<T = unknown> {
89
99
  * import { option } from "@optique/core/primitives";
90
100
  *
91
101
  * const logLevel = option("--log-level",
92
- * zod(z.enum(["debug", "info", "warn", "error"]))
102
+ * zod(z.enum(["debug", "info", "warn", "error"]), { placeholder: "debug" }),
93
103
  * );
94
104
  * ```
95
105
  *
@@ -100,20 +110,25 @@ interface ZodParserOptions<T = unknown> {
100
110
  * import { message } from "@optique/core/message";
101
111
  * import { option } from "@optique/core/primitives";
102
112
  *
103
- * const email = option("--email", zod(z.string().email(), {
104
- * metavar: "EMAIL",
105
- * errors: {
106
- * zodError: (error, input) =>
107
- * message`Please provide a valid email address, got ${input}.`
108
- * }
109
- * }));
113
+ * const email = option("--email",
114
+ * zod(z.string().email(), {
115
+ * placeholder: "",
116
+ * metavar: "EMAIL",
117
+ * errors: {
118
+ * zodError: (error, input) =>
119
+ * message`Please provide a valid email address, got ${input}.`
120
+ * },
121
+ * }),
122
+ * );
110
123
  * ```
111
124
  *
125
+ * @throws {TypeError} If `options` is missing, not an object, or does not
126
+ * include `placeholder`.
112
127
  * @throws {TypeError} If the resolved `metavar` is an empty string.
113
128
  * @throws {TypeError} If the schema contains async refinements or other async
114
129
  * operations that cannot be executed synchronously.
115
130
  * @since 0.7.0
116
131
  */
117
- declare function zod<T>(schema: z.Schema<T>, options?: ZodParserOptions<T>): ValueParser<"sync", T>;
132
+ declare function zod<T>(schema: z.Schema<T>, options: ZodParserOptions<T>): ValueParser<"sync", T>;
118
133
  //#endregion
119
134
  export { ZodParserOptions, zod };
package/dist/index.d.ts CHANGED
@@ -16,6 +16,13 @@ interface ZodParserOptions<T = unknown> {
16
16
  * @default `"VALUE"`
17
17
  */
18
18
  readonly metavar?: NonEmptyString;
19
+ /**
20
+ * A phase-one stand-in value of type `T` used during deferred prompt
21
+ * resolution. Because the output type of a Zod schema cannot be
22
+ * inferred to a concrete default, callers must provide this explicitly.
23
+ * @since 1.0.0
24
+ */
25
+ readonly placeholder: T;
19
26
  /**
20
27
  * Custom formatter for displaying parsed values in help messages.
21
28
  * When not provided, the default formatter is used: primitives use
@@ -58,7 +65,8 @@ interface ZodParserOptions<T = unknown> {
58
65
  *
59
66
  * @template T The output type of the Zod schema.
60
67
  * @param schema A Zod schema to validate input against.
61
- * @param options Optional configuration for the parser.
68
+ * @param options Configuration for the parser, including a required
69
+ * `placeholder` value used during deferred prompt resolution.
62
70
  * @returns A value parser that validates inputs using the provided schema.
63
71
  *
64
72
  * @example Basic string validation
@@ -67,7 +75,9 @@ interface ZodParserOptions<T = unknown> {
67
75
  * import { zod } from "@optique/zod";
68
76
  * import { option } from "@optique/core/primitives";
69
77
  *
70
- * const email = option("--email", zod(z.string().email()));
78
+ * const email = option("--email",
79
+ * zod(z.string().email(), { placeholder: "" }),
80
+ * );
71
81
  * ```
72
82
  *
73
83
  * @example Number validation with coercion
@@ -78,7 +88,7 @@ interface ZodParserOptions<T = unknown> {
78
88
  *
79
89
  * // Use z.coerce for non-string types since CLI args are always strings
80
90
  * const port = option("-p", "--port",
81
- * zod(z.coerce.number().int().min(1024).max(65535))
91
+ * zod(z.coerce.number().int().min(1024).max(65535), { placeholder: 1024 }),
82
92
  * );
83
93
  * ```
84
94
  *
@@ -89,7 +99,7 @@ interface ZodParserOptions<T = unknown> {
89
99
  * import { option } from "@optique/core/primitives";
90
100
  *
91
101
  * const logLevel = option("--log-level",
92
- * zod(z.enum(["debug", "info", "warn", "error"]))
102
+ * zod(z.enum(["debug", "info", "warn", "error"]), { placeholder: "debug" }),
93
103
  * );
94
104
  * ```
95
105
  *
@@ -100,20 +110,25 @@ interface ZodParserOptions<T = unknown> {
100
110
  * import { message } from "@optique/core/message";
101
111
  * import { option } from "@optique/core/primitives";
102
112
  *
103
- * const email = option("--email", zod(z.string().email(), {
104
- * metavar: "EMAIL",
105
- * errors: {
106
- * zodError: (error, input) =>
107
- * message`Please provide a valid email address, got ${input}.`
108
- * }
109
- * }));
113
+ * const email = option("--email",
114
+ * zod(z.string().email(), {
115
+ * placeholder: "",
116
+ * metavar: "EMAIL",
117
+ * errors: {
118
+ * zodError: (error, input) =>
119
+ * message`Please provide a valid email address, got ${input}.`
120
+ * },
121
+ * }),
122
+ * );
110
123
  * ```
111
124
  *
125
+ * @throws {TypeError} If `options` is missing, not an object, or does not
126
+ * include `placeholder`.
112
127
  * @throws {TypeError} If the resolved `metavar` is an empty string.
113
128
  * @throws {TypeError} If the schema contains async refinements or other async
114
129
  * operations that cannot be executed synchronously.
115
130
  * @since 0.7.0
116
131
  */
117
- declare function zod<T>(schema: z.Schema<T>, options?: ZodParserOptions<T>): ValueParser<"sync", T>;
132
+ declare function zod<T>(schema: z.Schema<T>, options: ZodParserOptions<T>): ValueParser<"sync", T>;
118
133
  //#endregion
119
134
  export { ZodParserOptions, zod };
package/dist/index.js CHANGED
@@ -279,7 +279,8 @@ function inferChoices(schema) {
279
279
  *
280
280
  * @template T The output type of the Zod schema.
281
281
  * @param schema A Zod schema to validate input against.
282
- * @param options Optional configuration for the parser.
282
+ * @param options Configuration for the parser, including a required
283
+ * `placeholder` value used during deferred prompt resolution.
283
284
  * @returns A value parser that validates inputs using the provided schema.
284
285
  *
285
286
  * @example Basic string validation
@@ -288,7 +289,9 @@ function inferChoices(schema) {
288
289
  * import { zod } from "@optique/zod";
289
290
  * import { option } from "@optique/core/primitives";
290
291
  *
291
- * const email = option("--email", zod(z.string().email()));
292
+ * const email = option("--email",
293
+ * zod(z.string().email(), { placeholder: "" }),
294
+ * );
292
295
  * ```
293
296
  *
294
297
  * @example Number validation with coercion
@@ -299,7 +302,7 @@ function inferChoices(schema) {
299
302
  *
300
303
  * // Use z.coerce for non-string types since CLI args are always strings
301
304
  * const port = option("-p", "--port",
302
- * zod(z.coerce.number().int().min(1024).max(65535))
305
+ * zod(z.coerce.number().int().min(1024).max(65535), { placeholder: 1024 }),
303
306
  * );
304
307
  * ```
305
308
  *
@@ -310,7 +313,7 @@ function inferChoices(schema) {
310
313
  * import { option } from "@optique/core/primitives";
311
314
  *
312
315
  * const logLevel = option("--log-level",
313
- * zod(z.enum(["debug", "info", "warn", "error"]))
316
+ * zod(z.enum(["debug", "info", "warn", "error"]), { placeholder: "debug" }),
314
317
  * );
315
318
  * ```
316
319
  *
@@ -321,21 +324,28 @@ function inferChoices(schema) {
321
324
  * import { message } from "@optique/core/message";
322
325
  * import { option } from "@optique/core/primitives";
323
326
  *
324
- * const email = option("--email", zod(z.string().email(), {
325
- * metavar: "EMAIL",
326
- * errors: {
327
- * zodError: (error, input) =>
328
- * message`Please provide a valid email address, got ${input}.`
329
- * }
330
- * }));
327
+ * const email = option("--email",
328
+ * zod(z.string().email(), {
329
+ * placeholder: "",
330
+ * metavar: "EMAIL",
331
+ * errors: {
332
+ * zodError: (error, input) =>
333
+ * message`Please provide a valid email address, got ${input}.`
334
+ * },
335
+ * }),
336
+ * );
331
337
  * ```
332
338
  *
339
+ * @throws {TypeError} If `options` is missing, not an object, or does not
340
+ * include `placeholder`.
333
341
  * @throws {TypeError} If the resolved `metavar` is an empty string.
334
342
  * @throws {TypeError} If the schema contains async refinements or other async
335
343
  * operations that cannot be executed synchronously.
336
344
  * @since 0.7.0
337
345
  */
338
- function zod(schema, options = {}) {
346
+ function zod(schema, options) {
347
+ if (options == null || typeof options !== "object") throw new TypeError("zod() requires an options object with a placeholder property.");
348
+ if (!("placeholder" in options)) throw new TypeError("zod() options must include a placeholder property.");
339
349
  const choices = inferChoices(schema);
340
350
  const boolInfo = analyzeBooleanSchema(schema);
341
351
  const metavar = options.metavar ?? (boolInfo.isBoolean ? "BOOLEAN" : inferMetavar(schema));
@@ -404,6 +414,7 @@ function zod(schema, options = {}) {
404
414
  const parser = {
405
415
  $mode: "sync",
406
416
  metavar,
417
+ placeholder: options.placeholder,
407
418
  ...boolInfo.exposeChoices ? {
408
419
  choices: Object.freeze([true, false]),
409
420
  suggest(prefix) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optique/zod",
3
- "version": "1.0.0-dev.1495+f6fe8a79",
3
+ "version": "1.0.0-dev.1500+dc0650e5",
4
4
  "description": "Zod value parsers for Optique",
5
5
  "keywords": [
6
6
  "CLI",
@@ -57,7 +57,7 @@
57
57
  "zod": "^3.25.0 || ^4.0.0"
58
58
  },
59
59
  "dependencies": {
60
- "@optique/core": "1.0.0-dev.1495+f6fe8a79"
60
+ "@optique/core": "1.0.0-dev.1500+dc0650e5"
61
61
  },
62
62
  "devDependencies": {
63
63
  "@types/node": "^20.19.9",