@optique/zod 1.0.0-dev.1288 → 1.0.0-dev.1291

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 CHANGED
@@ -47,7 +47,7 @@ const __optique_core_message = __toESM(require("@optique/core/message"));
47
47
  function inferMetavar(schema) {
48
48
  const def = schema._def;
49
49
  if (!def) return "VALUE";
50
- const typeName = def.typeName || def.type;
50
+ const typeName = def.typeName ?? def.type;
51
51
  if (typeName === "ZodString" || typeName === "string") {
52
52
  if (Array.isArray(def.checks)) for (const check of def.checks) {
53
53
  const kind = check.kind || check.format;
@@ -76,8 +76,15 @@ function inferMetavar(schema) {
76
76
  }
77
77
  if (typeName === "ZodBoolean" || typeName === "boolean") return "BOOLEAN";
78
78
  if (typeName === "ZodDate" || typeName === "date") return "DATE";
79
- if (typeName === "ZodEnum" || typeName === "enum" || typeName === "ZodNativeEnum" || typeName === "nativeEnum") return "CHOICE";
80
- if (typeName === "ZodUnion" || typeName === "union" || typeName === "ZodLiteral" || typeName === "literal") return "VALUE";
79
+ if (typeName === "ZodEnum" || typeName === "enum" || typeName === "ZodNativeEnum" || typeName === "nativeEnum") return inferChoices(schema) != null ? "CHOICE" : "VALUE";
80
+ if (typeName === "ZodLiteral" || typeName === "literal") {
81
+ if (inferChoices(schema) != null) return "CHOICE";
82
+ return "VALUE";
83
+ }
84
+ if (typeName === "ZodUnion" || typeName === "union") {
85
+ if (inferChoices(schema) != null) return "CHOICE";
86
+ return "VALUE";
87
+ }
81
88
  if (typeName === "ZodOptional" || typeName === "optional" || typeName === "ZodNullable" || typeName === "nullable") {
82
89
  const innerType = def.innerType;
83
90
  if (innerType != null) return inferMetavar(innerType);
@@ -91,6 +98,70 @@ function inferMetavar(schema) {
91
98
  return "VALUE";
92
99
  }
93
100
  /**
101
+ * Extracts valid choices from a Zod schema that represents a fixed set of
102
+ * values (enum, literal, or union of literals).
103
+ *
104
+ * @param schema A Zod schema to analyze.
105
+ * @returns An array of string representations of valid choices, or `undefined`
106
+ * if the schema does not represent a fixed set of values.
107
+ */
108
+ function inferChoices(schema) {
109
+ const def = schema._def;
110
+ if (!def) return void 0;
111
+ const typeName = def.typeName ?? def.type;
112
+ if (typeName === "ZodEnum" || typeName === "enum") {
113
+ const values = def.values;
114
+ if (Array.isArray(values)) return values.map(String);
115
+ const entries = def.entries;
116
+ if (entries != null && typeof entries === "object") {
117
+ const result = /* @__PURE__ */ new Set();
118
+ for (const val of Object.values(entries)) if (typeof val === "string") result.add(val);
119
+ else return void 0;
120
+ return result.size > 0 ? [...result] : void 0;
121
+ }
122
+ return void 0;
123
+ }
124
+ if (typeName === "ZodNativeEnum" || typeName === "nativeEnum") {
125
+ const values = def.values;
126
+ if (values != null && typeof values === "object" && !Array.isArray(values)) {
127
+ const result = /* @__PURE__ */ new Set();
128
+ for (const val of Object.values(values)) if (typeof val === "string") result.add(val);
129
+ else return void 0;
130
+ return result.size > 0 ? [...result] : void 0;
131
+ }
132
+ return void 0;
133
+ }
134
+ if (typeName === "ZodLiteral" || typeName === "literal") {
135
+ const value = def.value;
136
+ if (typeof value === "string") return [value];
137
+ const values = def.values;
138
+ if (Array.isArray(values)) {
139
+ const result = [];
140
+ for (const v of values) if (typeof v === "string") result.push(v);
141
+ else return void 0;
142
+ return result.length > 0 ? result : void 0;
143
+ }
144
+ return void 0;
145
+ }
146
+ if (typeName === "ZodUnion" || typeName === "union") {
147
+ const options = def.options;
148
+ if (!Array.isArray(options)) return void 0;
149
+ const allChoices = /* @__PURE__ */ new Set();
150
+ for (const opt of options) {
151
+ const sub = inferChoices(opt);
152
+ if (sub == null) return void 0;
153
+ for (const choice of sub) allChoices.add(choice);
154
+ }
155
+ return allChoices.size > 0 ? [...allChoices] : void 0;
156
+ }
157
+ if (typeName === "ZodOptional" || typeName === "optional" || typeName === "ZodNullable" || typeName === "nullable" || typeName === "ZodDefault" || typeName === "default") {
158
+ const innerType = def.innerType;
159
+ if (innerType != null) return inferChoices(innerType);
160
+ return void 0;
161
+ }
162
+ return void 0;
163
+ }
164
+ /**
94
165
  * Creates a value parser from a Zod schema.
95
166
  *
96
167
  * This parser validates CLI argument strings using Zod schemas, enabling
@@ -161,9 +232,19 @@ function inferMetavar(schema) {
161
232
  * @since 0.7.0
162
233
  */
163
234
  function zod(schema, options = {}) {
164
- return {
235
+ const choices = inferChoices(schema);
236
+ const parser = {
165
237
  $mode: "sync",
166
238
  metavar: options.metavar ?? inferMetavar(schema),
239
+ ...choices != null && choices.length > 0 ? {
240
+ choices: Object.freeze(choices),
241
+ *suggest(prefix) {
242
+ for (const c of choices) if (c.startsWith(prefix)) yield {
243
+ kind: "literal",
244
+ text: c
245
+ };
246
+ }
247
+ } : {},
167
248
  parse(input) {
168
249
  const result = schema.safeParse(input);
169
250
  if (result.success) return {
@@ -192,6 +273,7 @@ function zod(schema, options = {}) {
192
273
  return String(value);
193
274
  }
194
275
  };
276
+ return parser;
195
277
  }
196
278
 
197
279
  //#endregion
package/dist/index.js CHANGED
@@ -24,7 +24,7 @@ import { message } from "@optique/core/message";
24
24
  function inferMetavar(schema) {
25
25
  const def = schema._def;
26
26
  if (!def) return "VALUE";
27
- const typeName = def.typeName || def.type;
27
+ const typeName = def.typeName ?? def.type;
28
28
  if (typeName === "ZodString" || typeName === "string") {
29
29
  if (Array.isArray(def.checks)) for (const check of def.checks) {
30
30
  const kind = check.kind || check.format;
@@ -53,8 +53,15 @@ function inferMetavar(schema) {
53
53
  }
54
54
  if (typeName === "ZodBoolean" || typeName === "boolean") return "BOOLEAN";
55
55
  if (typeName === "ZodDate" || typeName === "date") return "DATE";
56
- if (typeName === "ZodEnum" || typeName === "enum" || typeName === "ZodNativeEnum" || typeName === "nativeEnum") return "CHOICE";
57
- if (typeName === "ZodUnion" || typeName === "union" || typeName === "ZodLiteral" || typeName === "literal") return "VALUE";
56
+ if (typeName === "ZodEnum" || typeName === "enum" || typeName === "ZodNativeEnum" || typeName === "nativeEnum") return inferChoices(schema) != null ? "CHOICE" : "VALUE";
57
+ if (typeName === "ZodLiteral" || typeName === "literal") {
58
+ if (inferChoices(schema) != null) return "CHOICE";
59
+ return "VALUE";
60
+ }
61
+ if (typeName === "ZodUnion" || typeName === "union") {
62
+ if (inferChoices(schema) != null) return "CHOICE";
63
+ return "VALUE";
64
+ }
58
65
  if (typeName === "ZodOptional" || typeName === "optional" || typeName === "ZodNullable" || typeName === "nullable") {
59
66
  const innerType = def.innerType;
60
67
  if (innerType != null) return inferMetavar(innerType);
@@ -68,6 +75,70 @@ function inferMetavar(schema) {
68
75
  return "VALUE";
69
76
  }
70
77
  /**
78
+ * Extracts valid choices from a Zod schema that represents a fixed set of
79
+ * values (enum, literal, or union of literals).
80
+ *
81
+ * @param schema A Zod schema to analyze.
82
+ * @returns An array of string representations of valid choices, or `undefined`
83
+ * if the schema does not represent a fixed set of values.
84
+ */
85
+ function inferChoices(schema) {
86
+ const def = schema._def;
87
+ if (!def) return void 0;
88
+ const typeName = def.typeName ?? def.type;
89
+ if (typeName === "ZodEnum" || typeName === "enum") {
90
+ const values = def.values;
91
+ if (Array.isArray(values)) return values.map(String);
92
+ const entries = def.entries;
93
+ if (entries != null && typeof entries === "object") {
94
+ const result = /* @__PURE__ */ new Set();
95
+ for (const val of Object.values(entries)) if (typeof val === "string") result.add(val);
96
+ else return void 0;
97
+ return result.size > 0 ? [...result] : void 0;
98
+ }
99
+ return void 0;
100
+ }
101
+ if (typeName === "ZodNativeEnum" || typeName === "nativeEnum") {
102
+ const values = def.values;
103
+ if (values != null && typeof values === "object" && !Array.isArray(values)) {
104
+ const result = /* @__PURE__ */ new Set();
105
+ for (const val of Object.values(values)) if (typeof val === "string") result.add(val);
106
+ else return void 0;
107
+ return result.size > 0 ? [...result] : void 0;
108
+ }
109
+ return void 0;
110
+ }
111
+ if (typeName === "ZodLiteral" || typeName === "literal") {
112
+ const value = def.value;
113
+ if (typeof value === "string") return [value];
114
+ const values = def.values;
115
+ if (Array.isArray(values)) {
116
+ const result = [];
117
+ for (const v of values) if (typeof v === "string") result.push(v);
118
+ else return void 0;
119
+ return result.length > 0 ? result : void 0;
120
+ }
121
+ return void 0;
122
+ }
123
+ if (typeName === "ZodUnion" || typeName === "union") {
124
+ const options = def.options;
125
+ if (!Array.isArray(options)) return void 0;
126
+ const allChoices = /* @__PURE__ */ new Set();
127
+ for (const opt of options) {
128
+ const sub = inferChoices(opt);
129
+ if (sub == null) return void 0;
130
+ for (const choice of sub) allChoices.add(choice);
131
+ }
132
+ return allChoices.size > 0 ? [...allChoices] : void 0;
133
+ }
134
+ if (typeName === "ZodOptional" || typeName === "optional" || typeName === "ZodNullable" || typeName === "nullable" || typeName === "ZodDefault" || typeName === "default") {
135
+ const innerType = def.innerType;
136
+ if (innerType != null) return inferChoices(innerType);
137
+ return void 0;
138
+ }
139
+ return void 0;
140
+ }
141
+ /**
71
142
  * Creates a value parser from a Zod schema.
72
143
  *
73
144
  * This parser validates CLI argument strings using Zod schemas, enabling
@@ -138,9 +209,19 @@ function inferMetavar(schema) {
138
209
  * @since 0.7.0
139
210
  */
140
211
  function zod(schema, options = {}) {
141
- return {
212
+ const choices = inferChoices(schema);
213
+ const parser = {
142
214
  $mode: "sync",
143
215
  metavar: options.metavar ?? inferMetavar(schema),
216
+ ...choices != null && choices.length > 0 ? {
217
+ choices: Object.freeze(choices),
218
+ *suggest(prefix) {
219
+ for (const c of choices) if (c.startsWith(prefix)) yield {
220
+ kind: "literal",
221
+ text: c
222
+ };
223
+ }
224
+ } : {},
144
225
  parse(input) {
145
226
  const result = schema.safeParse(input);
146
227
  if (result.success) return {
@@ -169,6 +250,7 @@ function zod(schema, options = {}) {
169
250
  return String(value);
170
251
  }
171
252
  };
253
+ return parser;
172
254
  }
173
255
 
174
256
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optique/zod",
3
- "version": "1.0.0-dev.1288+e8d1d8b0",
3
+ "version": "1.0.0-dev.1291+36a7f4c9",
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.1288+e8d1d8b0"
60
+ "@optique/core": "1.0.0-dev.1291+36a7f4c9"
61
61
  },
62
62
  "devDependencies": {
63
63
  "@types/node": "^20.19.9",