politty 0.8.0 → 0.9.0
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/cli.js +1 -1
- package/dist/docs/index.js +1 -1
- package/dist/index.js +1 -1
- package/dist/{runner-D43SkHt5.js → runner-APRZYXUS.js} +74 -3
- package/package.json +20 -65
- package/dist/arg-registry-DDJpsUea.d.cts +0 -942
- package/dist/arg-registry-DDJpsUea.d.cts.map +0 -1
- package/dist/arg-registry-DDJpsUea.d.ts.map +0 -1
- package/dist/augment.cjs +0 -0
- package/dist/augment.d.cts +0 -17
- package/dist/augment.d.cts.map +0 -1
- package/dist/augment.d.ts.map +0 -1
- package/dist/cli.cjs +0 -54
- package/dist/cli.cjs.map +0 -1
- package/dist/cli.d.cts +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/completion/index.cjs +0 -23
- package/dist/completion/index.d.cts +0 -3
- package/dist/completion-CLHO3Xaz.cjs +0 -5769
- package/dist/completion-CLHO3Xaz.cjs.map +0 -1
- package/dist/completion-DHnVx9Zk.js.map +0 -1
- package/dist/docs/index.cjs +0 -3127
- package/dist/docs/index.cjs.map +0 -1
- package/dist/docs/index.d.cts +0 -752
- package/dist/docs/index.d.cts.map +0 -1
- package/dist/docs/index.d.ts.map +0 -1
- package/dist/docs/index.js.map +0 -1
- package/dist/index-DKGn3lIl.d.ts.map +0 -1
- package/dist/index-WyViqW59.d.cts +0 -663
- package/dist/index-WyViqW59.d.cts.map +0 -1
- package/dist/index.cjs +0 -45
- package/dist/index.d.cts +0 -685
- package/dist/index.d.cts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/log-collector-DK32-73m.js.map +0 -1
- package/dist/log-collector-DUqC427m.cjs +0 -185
- package/dist/log-collector-DUqC427m.cjs.map +0 -1
- package/dist/prompt/clack/index.cjs +0 -33
- package/dist/prompt/clack/index.cjs.map +0 -1
- package/dist/prompt/clack/index.d.cts +0 -18
- package/dist/prompt/clack/index.d.cts.map +0 -1
- package/dist/prompt/clack/index.d.ts.map +0 -1
- package/dist/prompt/clack/index.js.map +0 -1
- package/dist/prompt/index.cjs +0 -7
- package/dist/prompt/index.d.cts +0 -108
- package/dist/prompt/index.d.cts.map +0 -1
- package/dist/prompt/index.d.ts.map +0 -1
- package/dist/prompt/inquirer/index.cjs +0 -48
- package/dist/prompt/inquirer/index.cjs.map +0 -1
- package/dist/prompt/inquirer/index.d.cts +0 -18
- package/dist/prompt/inquirer/index.d.cts.map +0 -1
- package/dist/prompt/inquirer/index.d.ts.map +0 -1
- package/dist/prompt/inquirer/index.js.map +0 -1
- package/dist/prompt-Bs9e-Em3.cjs +0 -196
- package/dist/prompt-Bs9e-Em3.cjs.map +0 -1
- package/dist/prompt-Cc8Tfmdv.js.map +0 -1
- package/dist/runner-D43SkHt5.js.map +0 -1
- package/dist/runner-DvFvokV6.cjs +0 -2865
- package/dist/runner-DvFvokV6.cjs.map +0 -1
- package/dist/schema-extractor-BxSRwLrx.cjs +0 -710
- package/dist/schema-extractor-BxSRwLrx.cjs.map +0 -1
- package/dist/schema-extractor-Dqe7_kyQ.js.map +0 -1
|
@@ -1,710 +0,0 @@
|
|
|
1
|
-
let zod = require("zod");
|
|
2
|
-
|
|
3
|
-
//#region src/core/arg-registry.ts
|
|
4
|
-
/**
|
|
5
|
-
* Custom registry for politty argument metadata
|
|
6
|
-
* This avoids polluting Zod's GlobalMeta
|
|
7
|
-
*/
|
|
8
|
-
const argRegistry = zod.z.registry();
|
|
9
|
-
function arg(schema, meta) {
|
|
10
|
-
if (meta) argRegistry.add(schema, meta);
|
|
11
|
-
return schema;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Get metadata for a schema from the registry
|
|
15
|
-
*
|
|
16
|
-
* @param schema - The Zod schema
|
|
17
|
-
* @returns The metadata if registered, undefined otherwise
|
|
18
|
-
*/
|
|
19
|
-
function getArgMeta$1(schema) {
|
|
20
|
-
return argRegistry.get(schema);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
//#endregion
|
|
24
|
-
//#region src/lazy.ts
|
|
25
|
-
/**
|
|
26
|
-
* Marker property for LazyCommand identification
|
|
27
|
-
*/
|
|
28
|
-
const LAZY_BRAND = "__politty_lazy__";
|
|
29
|
-
/**
|
|
30
|
-
* Type guard: check if a value is a LazyCommand
|
|
31
|
-
*/
|
|
32
|
-
function isLazyCommand(value) {
|
|
33
|
-
return typeof value === "object" && value !== null && LAZY_BRAND in value && value[LAZY_BRAND] === true;
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Create a lazily-loaded subcommand with synchronous metadata.
|
|
37
|
-
*
|
|
38
|
-
* The `meta` command provides names, descriptions, and args schema
|
|
39
|
-
* for static analysis (completion scripts, help text) without loading
|
|
40
|
-
* the full command module.
|
|
41
|
-
*
|
|
42
|
-
* The `load` function is called only at execution time.
|
|
43
|
-
*
|
|
44
|
-
* @example
|
|
45
|
-
* ```ts
|
|
46
|
-
* import { lazy, defineCommand } from "politty";
|
|
47
|
-
*
|
|
48
|
-
* const cli = defineCommand({
|
|
49
|
-
* name: "mycli",
|
|
50
|
-
* subCommands: {
|
|
51
|
-
* deploy: lazy(
|
|
52
|
-
* defineCommand({
|
|
53
|
-
* name: "deploy",
|
|
54
|
-
* description: "Deploy the application",
|
|
55
|
-
* args: z.object({ env: arg(z.string()) }),
|
|
56
|
-
* }),
|
|
57
|
-
* () => import("./deploy.js").then((m) => m.deployCommand),
|
|
58
|
-
* ),
|
|
59
|
-
* },
|
|
60
|
-
* });
|
|
61
|
-
* ```
|
|
62
|
-
*/
|
|
63
|
-
function lazy(meta, load) {
|
|
64
|
-
return {
|
|
65
|
-
[LAZY_BRAND]: true,
|
|
66
|
-
meta,
|
|
67
|
-
load
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Resolve synchronous metadata from a SubCommandValue.
|
|
72
|
-
* Returns null for legacy async subcommands whose metadata is unavailable.
|
|
73
|
-
*/
|
|
74
|
-
function resolveSubCommandMeta(subCmd) {
|
|
75
|
-
if (isLazyCommand(subCmd)) return subCmd.meta;
|
|
76
|
-
if (typeof subCmd === "function") return null;
|
|
77
|
-
return subCmd;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
//#endregion
|
|
81
|
-
//#region src/executor/subcommand-router.ts
|
|
82
|
-
/**
|
|
83
|
-
* Resolve a lazy-loaded command (sync or async)
|
|
84
|
-
*
|
|
85
|
-
* @param cmd - The command or lazy loader function
|
|
86
|
-
* @returns The resolved command
|
|
87
|
-
*/
|
|
88
|
-
async function resolveLazyCommand(cmd) {
|
|
89
|
-
if (isLazyCommand(cmd)) return await cmd.load();
|
|
90
|
-
if (typeof cmd === "function") return await cmd();
|
|
91
|
-
return cmd;
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Resolve a subcommand by name (including alias lookup) and return both the
|
|
95
|
-
* resolved command and the canonical name if accessed via alias.
|
|
96
|
-
*
|
|
97
|
-
* This avoids a redundant alias scan when the caller needs both pieces of info.
|
|
98
|
-
*/
|
|
99
|
-
async function resolveSubcommandWithAlias(command, name) {
|
|
100
|
-
if (!command.subCommands) return;
|
|
101
|
-
const subCmd = command.subCommands[name];
|
|
102
|
-
if (subCmd) return {
|
|
103
|
-
command: await resolveLazyCommand(subCmd),
|
|
104
|
-
aliasFor: void 0
|
|
105
|
-
};
|
|
106
|
-
const canonicalName = resolveSubCommandAlias(command, name);
|
|
107
|
-
if (canonicalName) return {
|
|
108
|
-
command: await resolveLazyCommand(command.subCommands[canonicalName]),
|
|
109
|
-
aliasFor: canonicalName
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* Resolve an alias to the canonical subcommand name.
|
|
114
|
-
* Returns the canonical name if the given name is an alias, or undefined.
|
|
115
|
-
*
|
|
116
|
-
* Note: Aliases are only recognized for eagerly-defined commands and
|
|
117
|
-
* `lazy()` commands (which carry synchronous metadata). Pure async
|
|
118
|
-
* subcommand functions do not expose metadata synchronously, so their
|
|
119
|
-
* aliases cannot be resolved without loading the module.
|
|
120
|
-
*
|
|
121
|
-
* @param command - The parent command
|
|
122
|
-
* @param alias - The alias to look up
|
|
123
|
-
* @returns The canonical subcommand name, or undefined
|
|
124
|
-
*/
|
|
125
|
-
function resolveSubCommandAlias(command, alias) {
|
|
126
|
-
if (!command.subCommands) return void 0;
|
|
127
|
-
for (const [name, subCmd] of Object.entries(command.subCommands)) if (resolveSubCommandMeta(subCmd)?.aliases?.includes(alias)) return name;
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Build a set of all recognized subcommand names including aliases.
|
|
131
|
-
*
|
|
132
|
-
* @param command - The parent command
|
|
133
|
-
* @returns Set of all names (canonical + aliases)
|
|
134
|
-
*/
|
|
135
|
-
function listSubCommandNamesWithAliases(command) {
|
|
136
|
-
const names = /* @__PURE__ */ new Set();
|
|
137
|
-
if (!command.subCommands) return names;
|
|
138
|
-
for (const [name, subCmd] of Object.entries(command.subCommands)) {
|
|
139
|
-
names.add(name);
|
|
140
|
-
const meta = resolveSubCommandMeta(subCmd);
|
|
141
|
-
if (meta?.aliases) for (const alias of meta.aliases) names.add(alias);
|
|
142
|
-
}
|
|
143
|
-
return names;
|
|
144
|
-
}
|
|
145
|
-
/**
|
|
146
|
-
* List all subcommand names for a command
|
|
147
|
-
*
|
|
148
|
-
* @param command - The parent command
|
|
149
|
-
* @returns Array of subcommand names
|
|
150
|
-
*/
|
|
151
|
-
function listSubCommands(command) {
|
|
152
|
-
if (!command.subCommands) return [];
|
|
153
|
-
return Object.keys(command.subCommands);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
//#endregion
|
|
157
|
-
//#region src/core/schema-extractor.ts
|
|
158
|
-
/**
|
|
159
|
-
* Get ArgMeta from both the custom registry and Zod's _def
|
|
160
|
-
* Priority: custom registry > _def.argMeta
|
|
161
|
-
*/
|
|
162
|
-
function getArgMeta(schema) {
|
|
163
|
-
const fromRegistry = getArgMeta$1(schema);
|
|
164
|
-
if (fromRegistry) return fromRegistry;
|
|
165
|
-
if (typeof schema.meta === "function") {
|
|
166
|
-
const meta = schema.meta();
|
|
167
|
-
if (meta && typeof meta === "object") return meta;
|
|
168
|
-
}
|
|
169
|
-
const def = schema._def;
|
|
170
|
-
if (def?.argMeta) return def.argMeta;
|
|
171
|
-
if (def?.meta) return def.meta;
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* Long flag names reserved for built-in handling (parseArgs / scanForSubcommand
|
|
175
|
-
* intercept these before option parsing), so custom negation names must avoid them.
|
|
176
|
-
*/
|
|
177
|
-
const RESERVED_NEGATION_NAMES = new Set([
|
|
178
|
-
"help",
|
|
179
|
-
"help-all",
|
|
180
|
-
"version"
|
|
181
|
-
]);
|
|
182
|
-
/**
|
|
183
|
-
* Get the type name from a zod schema (v4 compatible)
|
|
184
|
-
*/
|
|
185
|
-
function getTypeName(schema) {
|
|
186
|
-
const s = schema;
|
|
187
|
-
return s.def?.type ?? s._def?.type ?? s.type;
|
|
188
|
-
}
|
|
189
|
-
/**
|
|
190
|
-
* Detect unknown keys handling mode from a Zod object schema
|
|
191
|
-
*
|
|
192
|
-
* In Zod v4:
|
|
193
|
-
* - Default (strip): _def.catchall is undefined
|
|
194
|
-
* - strict: _def.catchall is ZodNever (type = "never")
|
|
195
|
-
* - passthrough: _def.catchall is ZodUnknown (type = "unknown")
|
|
196
|
-
*/
|
|
197
|
-
function getUnknownKeysMode(schema) {
|
|
198
|
-
const s = schema;
|
|
199
|
-
const catchall = (s.def ?? s._def)?.catchall;
|
|
200
|
-
if (!catchall) return "strip";
|
|
201
|
-
const catchallType = getTypeName(catchall);
|
|
202
|
-
if (catchallType === "never") return "strict";
|
|
203
|
-
if (catchallType === "unknown" || catchallType === "any") return "passthrough";
|
|
204
|
-
return "strip";
|
|
205
|
-
}
|
|
206
|
-
/**
|
|
207
|
-
* Get the inner schema, unwrapping optional, nullable, default, etc.
|
|
208
|
-
*/
|
|
209
|
-
function unwrapSchema(schema) {
|
|
210
|
-
const typeName = getTypeName(schema);
|
|
211
|
-
const s = schema;
|
|
212
|
-
const def = s.def ?? s._def;
|
|
213
|
-
if (typeName === "optional" || typeName === "nullable" || typeName === "default") {
|
|
214
|
-
const innerSchema = def?.innerType;
|
|
215
|
-
if (innerSchema) return unwrapSchema(innerSchema);
|
|
216
|
-
}
|
|
217
|
-
if (typeName === "pipe") {
|
|
218
|
-
const innerSchema = def?.in ?? def?.schema;
|
|
219
|
-
if (innerSchema) return unwrapSchema(innerSchema);
|
|
220
|
-
}
|
|
221
|
-
return schema;
|
|
222
|
-
}
|
|
223
|
-
/**
|
|
224
|
-
* Detect the base type of a schema
|
|
225
|
-
*/
|
|
226
|
-
function detectType(schema) {
|
|
227
|
-
switch (getTypeName(unwrapSchema(schema))) {
|
|
228
|
-
case "string":
|
|
229
|
-
case "enum": return "string";
|
|
230
|
-
case "number":
|
|
231
|
-
case "int": return "number";
|
|
232
|
-
case "boolean": return "boolean";
|
|
233
|
-
case "array": return "array";
|
|
234
|
-
default: return "unknown";
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
/**
|
|
238
|
-
* Extract enum values from a schema if it's an enum type
|
|
239
|
-
*
|
|
240
|
-
* @param schema - The Zod schema to extract enum values from
|
|
241
|
-
* @returns Array of enum values if schema is an enum, undefined otherwise
|
|
242
|
-
*/
|
|
243
|
-
function extractEnumValues(schema) {
|
|
244
|
-
const innerSchema = unwrapSchema(schema);
|
|
245
|
-
const typeName = getTypeName(innerSchema);
|
|
246
|
-
const s = innerSchema;
|
|
247
|
-
const def = s.def ?? s._def;
|
|
248
|
-
if (typeName === "enum") {
|
|
249
|
-
const entries = def?.entries;
|
|
250
|
-
if (entries && typeof entries === "object") return Object.values(entries);
|
|
251
|
-
const values = def?.values;
|
|
252
|
-
if (Array.isArray(values)) return values;
|
|
253
|
-
const options = s.options;
|
|
254
|
-
if (Array.isArray(options)) return options;
|
|
255
|
-
}
|
|
256
|
-
if (typeName === "array") {
|
|
257
|
-
const element = def?.element;
|
|
258
|
-
if (element) return extractEnumValues(element);
|
|
259
|
-
}
|
|
260
|
-
if (typeName === "union") {
|
|
261
|
-
const options = def?.options;
|
|
262
|
-
if (Array.isArray(options)) {
|
|
263
|
-
const literalValues = [];
|
|
264
|
-
for (const option of options) if (getTypeName(option) === "literal") {
|
|
265
|
-
const optionDef = option.def ?? option._def;
|
|
266
|
-
const value = optionDef?.value;
|
|
267
|
-
const values = optionDef?.values;
|
|
268
|
-
const literalValue = value ?? values?.[0];
|
|
269
|
-
if (typeof literalValue === "string") literalValues.push(literalValue);
|
|
270
|
-
}
|
|
271
|
-
if (literalValues.length === options.length && literalValues.length > 0) return literalValues;
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
/**
|
|
276
|
-
* Convert camelCase to kebab-case
|
|
277
|
-
* @example toKebabCase("dryRun") => "dry-run"
|
|
278
|
-
* @example toKebabCase("outputDir") => "output-dir"
|
|
279
|
-
* @example toKebabCase("XMLParser") => "xml-parser"
|
|
280
|
-
*/
|
|
281
|
-
function toKebabCase(str) {
|
|
282
|
-
return str.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1-$2").toLowerCase();
|
|
283
|
-
}
|
|
284
|
-
/**
|
|
285
|
-
* Convert hyphen-separated sequences to camelCase.
|
|
286
|
-
*
|
|
287
|
-
* Replaces `-x` (hyphen followed by a lowercase letter) with the uppercase
|
|
288
|
-
* variant. Non-hyphenated input (e.g., already camelCase) is returned as-is.
|
|
289
|
-
*
|
|
290
|
-
* @param str - A string that may contain hyphens
|
|
291
|
-
* @example toCamelCase("dry-run") => "dryRun"
|
|
292
|
-
* @example toCamelCase("output-dir") => "outputDir"
|
|
293
|
-
* @example toCamelCase("dryRun") => "dryRun"
|
|
294
|
-
*/
|
|
295
|
-
function toCamelCase(str) {
|
|
296
|
-
return str.replace(/-([a-z])/g, (_, char) => char.toUpperCase());
|
|
297
|
-
}
|
|
298
|
-
/**
|
|
299
|
-
* Check if a schema is required (not optional or has default)
|
|
300
|
-
*
|
|
301
|
-
* Note: We only check isOptional(), not isNullable(), because CLI arguments
|
|
302
|
-
* are either present (string value) or absent (undefined), never null.
|
|
303
|
-
* Also, some coerce types incorrectly report isNullable()=true.
|
|
304
|
-
*/
|
|
305
|
-
function isRequired(schema) {
|
|
306
|
-
return !schema.isOptional();
|
|
307
|
-
}
|
|
308
|
-
/**
|
|
309
|
-
* Extract default value from schema if present
|
|
310
|
-
*/
|
|
311
|
-
function extractDefaultValue(schema) {
|
|
312
|
-
const typeName = getTypeName(schema);
|
|
313
|
-
const s = schema;
|
|
314
|
-
const def = s.def ?? s._def;
|
|
315
|
-
if (typeName === "default") {
|
|
316
|
-
const defaultValue = def?.defaultValue;
|
|
317
|
-
if (typeof defaultValue === "function") return defaultValue();
|
|
318
|
-
return defaultValue;
|
|
319
|
-
}
|
|
320
|
-
if (typeName === "optional" || typeName === "nullable") {
|
|
321
|
-
const innerSchema = def?.innerType;
|
|
322
|
-
if (innerSchema) return extractDefaultValue(innerSchema);
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
/**
|
|
326
|
-
* Extract description from schema
|
|
327
|
-
*/
|
|
328
|
-
function extractDescription(schema) {
|
|
329
|
-
if (schema.description) return schema.description;
|
|
330
|
-
const typeName = getTypeName(schema);
|
|
331
|
-
const s = schema;
|
|
332
|
-
const def = s.def ?? s._def;
|
|
333
|
-
if (typeName === "optional" || typeName === "nullable" || typeName === "default") {
|
|
334
|
-
const innerSchema = def?.innerType;
|
|
335
|
-
if (innerSchema) return extractDescription(innerSchema);
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
/**
|
|
339
|
-
* Resolve field metadata from schema and argRegistry
|
|
340
|
-
*/
|
|
341
|
-
function resolveFieldMeta(name, schema) {
|
|
342
|
-
const argMeta = getArgMeta(schema) ?? getArgMeta(unwrapSchema(schema));
|
|
343
|
-
const description = argMeta?.description ?? extractDescription(schema);
|
|
344
|
-
const cliName = toKebabCase(name);
|
|
345
|
-
const enumValues = extractEnumValues(schema);
|
|
346
|
-
const aliasPattern = /^[A-Za-z0-9][A-Za-z0-9-]*$/;
|
|
347
|
-
const normalizeAliasList = (input, metaKey) => {
|
|
348
|
-
if (input == null) return void 0;
|
|
349
|
-
const normalized = (Array.isArray(input) ? input : [input]).map((a) => {
|
|
350
|
-
if (typeof a !== "string") throw new Error(`Invalid ${metaKey} for field "${name}": expected string or string[], received ${typeof a}.`);
|
|
351
|
-
const candidate = a.trim().replace(/^-+/, "");
|
|
352
|
-
if (candidate.length === 0 || !aliasPattern.test(candidate)) throw new Error(`Invalid ${metaKey} "${a}" for field "${name}": aliases must match ${aliasPattern}.`);
|
|
353
|
-
return candidate;
|
|
354
|
-
});
|
|
355
|
-
const result = Array.from(new Set(normalized));
|
|
356
|
-
return result.length > 0 ? result : void 0;
|
|
357
|
-
};
|
|
358
|
-
const alias = normalizeAliasList(argMeta?.alias, "alias");
|
|
359
|
-
const visibleSet = new Set(alias ?? []);
|
|
360
|
-
const hiddenAlias = normalizeAliasList(argMeta?.hiddenAlias, "hiddenAlias")?.filter((a) => !visibleSet.has(a));
|
|
361
|
-
const hiddenAliasFinal = hiddenAlias && hiddenAlias.length > 0 ? hiddenAlias : void 0;
|
|
362
|
-
const fieldType = detectType(schema);
|
|
363
|
-
const rawNegation = argMeta?.negation;
|
|
364
|
-
let negation;
|
|
365
|
-
if (rawNegation !== void 0 && rawNegation !== null) if (typeof rawNegation === "boolean") {
|
|
366
|
-
if (fieldType !== "boolean") throw new Error(`Invalid negation for field "${name}": negation can only be used on boolean fields.`);
|
|
367
|
-
negation = rawNegation;
|
|
368
|
-
} else {
|
|
369
|
-
if (typeof rawNegation !== "string") throw new Error(`Invalid negation for field "${name}": expected string or boolean, received ${typeof rawNegation}.`);
|
|
370
|
-
const candidate = rawNegation.trim().replace(/^-+/, "");
|
|
371
|
-
if (candidate.length === 0 || !aliasPattern.test(candidate)) throw new Error(`Invalid negation "${rawNegation}" for field "${name}": negation names must match ${aliasPattern}.`);
|
|
372
|
-
if (RESERVED_NEGATION_NAMES.has(candidate)) throw new Error(`Invalid negation "${rawNegation}" for field "${name}": negation cannot use reserved built-in flag names (${[...RESERVED_NEGATION_NAMES].map((n) => `--${n}`).join(", ")}).`);
|
|
373
|
-
if (fieldType !== "boolean") throw new Error(`Invalid negation for field "${name}": negation can only be used on boolean fields.`);
|
|
374
|
-
negation = candidate;
|
|
375
|
-
}
|
|
376
|
-
const rawNegationDescription = argMeta?.negationDescription;
|
|
377
|
-
let negationDescription;
|
|
378
|
-
if (rawNegationDescription !== void 0 && rawNegationDescription !== null) {
|
|
379
|
-
if (typeof rawNegationDescription !== "string") throw new Error(`Invalid negationDescription for field "${name}": expected string, received ${typeof rawNegationDescription}.`);
|
|
380
|
-
if (negation === false) throw new Error(`Invalid negationDescription for field "${name}": negationDescription cannot be used when negation is false.`);
|
|
381
|
-
if (negation === void 0) throw new Error(`Invalid negationDescription for field "${name}": negationDescription requires \`negation\` to be set (string or true).`);
|
|
382
|
-
const trimmed = rawNegationDescription.trim();
|
|
383
|
-
if (trimmed.length === 0) throw new Error(`Invalid negationDescription for field "${name}": negationDescription must be a non-empty string.`);
|
|
384
|
-
negationDescription = trimmed;
|
|
385
|
-
}
|
|
386
|
-
const negationDisplay = typeof negation === "string" ? negation : negation === true ? `no-${cliName}` : void 0;
|
|
387
|
-
const meta = {
|
|
388
|
-
name,
|
|
389
|
-
cliName,
|
|
390
|
-
alias,
|
|
391
|
-
hiddenAlias: hiddenAliasFinal,
|
|
392
|
-
description,
|
|
393
|
-
positional: argMeta?.positional ?? false,
|
|
394
|
-
placeholder: argMeta?.placeholder,
|
|
395
|
-
env: argMeta?.env,
|
|
396
|
-
required: isRequired(schema),
|
|
397
|
-
defaultValue: extractDefaultValue(schema),
|
|
398
|
-
type: fieldType,
|
|
399
|
-
schema,
|
|
400
|
-
enumValues,
|
|
401
|
-
completion: argMeta?.completion,
|
|
402
|
-
prompt: argMeta?.prompt,
|
|
403
|
-
negation,
|
|
404
|
-
negationDisplay,
|
|
405
|
-
negationDescription,
|
|
406
|
-
effect: argMeta?.effect
|
|
407
|
-
};
|
|
408
|
-
if (argMeta && "overrideBuiltinAlias" in argMeta && argMeta.overrideBuiltinAlias === true) meta.overrideBuiltinAlias = true;
|
|
409
|
-
return meta;
|
|
410
|
-
}
|
|
411
|
-
/**
|
|
412
|
-
* Get the combined list of visible + hidden aliases for a field.
|
|
413
|
-
* Used by the parser and validators which treat both equally,
|
|
414
|
-
* while help/docs/completion rely on `field.alias` only.
|
|
415
|
-
*/
|
|
416
|
-
function getAllAliases(field) {
|
|
417
|
-
if (!field.alias && !field.hiddenAlias) return [];
|
|
418
|
-
return [...field.alias ?? [], ...field.hiddenAlias ?? []];
|
|
419
|
-
}
|
|
420
|
-
/**
|
|
421
|
-
* Get shape from a ZodObject
|
|
422
|
-
*/
|
|
423
|
-
function getObjectShape(schema) {
|
|
424
|
-
const s = schema;
|
|
425
|
-
return (s.def ?? s._def)?.shape ?? s.shape ?? {};
|
|
426
|
-
}
|
|
427
|
-
/**
|
|
428
|
-
* Extract fields from a ZodObject
|
|
429
|
-
*/
|
|
430
|
-
function extractFromObject(schema) {
|
|
431
|
-
const shape = getObjectShape(schema);
|
|
432
|
-
return Object.entries(shape).map(([name, fieldSchema]) => resolveFieldMeta(name, fieldSchema));
|
|
433
|
-
}
|
|
434
|
-
/**
|
|
435
|
-
* Extract fields from a discriminated union
|
|
436
|
-
*/
|
|
437
|
-
function extractFromDiscriminatedUnion(schema) {
|
|
438
|
-
const s = schema;
|
|
439
|
-
const def = s.def ?? s._def;
|
|
440
|
-
const discriminator = def?.discriminator ?? "";
|
|
441
|
-
const options = def?.options ?? [];
|
|
442
|
-
const allFieldsMap = /* @__PURE__ */ new Map();
|
|
443
|
-
const variants = [];
|
|
444
|
-
for (const option of options) {
|
|
445
|
-
const shape = getObjectShape(option);
|
|
446
|
-
const variantFields = [];
|
|
447
|
-
let discriminatorValue = "";
|
|
448
|
-
const discriminatorSchema = shape[discriminator];
|
|
449
|
-
if (discriminatorSchema) {
|
|
450
|
-
const typeName = getTypeName(discriminatorSchema);
|
|
451
|
-
if (typeName === "literal") {
|
|
452
|
-
const litDef = discriminatorSchema.def ?? discriminatorSchema._def;
|
|
453
|
-
const value = litDef?.value;
|
|
454
|
-
const values = litDef?.values;
|
|
455
|
-
discriminatorValue = String(value ?? values?.[0] ?? "");
|
|
456
|
-
} else if (typeName === "enum") {
|
|
457
|
-
const enumValues = extractEnumValues(discriminatorSchema);
|
|
458
|
-
if (enumValues && enumValues.length === 1) discriminatorValue = enumValues[0];
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
for (const [name, fieldSchema] of Object.entries(shape)) {
|
|
462
|
-
const fieldMeta = resolveFieldMeta(name, fieldSchema);
|
|
463
|
-
variantFields.push(fieldMeta);
|
|
464
|
-
if (!allFieldsMap.has(name)) allFieldsMap.set(name, fieldMeta);
|
|
465
|
-
}
|
|
466
|
-
const variantDescription = extractDescription(option);
|
|
467
|
-
variants.push({
|
|
468
|
-
discriminatorValue,
|
|
469
|
-
fields: variantFields,
|
|
470
|
-
...variantDescription ? { description: variantDescription } : {}
|
|
471
|
-
});
|
|
472
|
-
}
|
|
473
|
-
const description = extractDescription(schema);
|
|
474
|
-
return {
|
|
475
|
-
fields: Array.from(allFieldsMap.values()),
|
|
476
|
-
schema,
|
|
477
|
-
schemaType: "discriminatedUnion",
|
|
478
|
-
unknownKeysMode: getUnknownKeysMode(schema),
|
|
479
|
-
discriminator,
|
|
480
|
-
variants,
|
|
481
|
-
...description ? { description } : {}
|
|
482
|
-
};
|
|
483
|
-
}
|
|
484
|
-
/**
|
|
485
|
-
* Extract fields from a union-like schema (union or xor)
|
|
486
|
-
*/
|
|
487
|
-
function extractFromUnionLike(schema, schemaType) {
|
|
488
|
-
const s = schema;
|
|
489
|
-
const options = (s.def ?? s._def)?.options ?? [];
|
|
490
|
-
const allFieldsMap = /* @__PURE__ */ new Map();
|
|
491
|
-
const unionOptions = [];
|
|
492
|
-
for (const option of options) {
|
|
493
|
-
const extracted = extractFields(option);
|
|
494
|
-
unionOptions.push(extracted);
|
|
495
|
-
for (const field of extracted.fields) if (!allFieldsMap.has(field.name)) allFieldsMap.set(field.name, field);
|
|
496
|
-
}
|
|
497
|
-
const description = extractDescription(schema);
|
|
498
|
-
return {
|
|
499
|
-
fields: Array.from(allFieldsMap.values()),
|
|
500
|
-
schema,
|
|
501
|
-
schemaType,
|
|
502
|
-
unknownKeysMode: getUnknownKeysMode(schema),
|
|
503
|
-
unionOptions,
|
|
504
|
-
...description ? { description } : {}
|
|
505
|
-
};
|
|
506
|
-
}
|
|
507
|
-
/**
|
|
508
|
-
* Extract fields from an intersection
|
|
509
|
-
*/
|
|
510
|
-
function extractFromIntersection(schema) {
|
|
511
|
-
const s = schema;
|
|
512
|
-
const def = s.def ?? s._def;
|
|
513
|
-
const left = def?.left;
|
|
514
|
-
const right = def?.right;
|
|
515
|
-
const allFieldsMap = /* @__PURE__ */ new Map();
|
|
516
|
-
const extractSubFields = (subSchema) => {
|
|
517
|
-
if (!subSchema) return;
|
|
518
|
-
const extracted = extractFields(subSchema);
|
|
519
|
-
for (const field of extracted.fields) if (!allFieldsMap.has(field.name)) allFieldsMap.set(field.name, field);
|
|
520
|
-
};
|
|
521
|
-
extractSubFields(left);
|
|
522
|
-
extractSubFields(right);
|
|
523
|
-
const description = extractDescription(schema);
|
|
524
|
-
return {
|
|
525
|
-
fields: Array.from(allFieldsMap.values()),
|
|
526
|
-
schema,
|
|
527
|
-
schemaType: "intersection",
|
|
528
|
-
unknownKeysMode: getUnknownKeysMode(schema),
|
|
529
|
-
...description ? { description } : {}
|
|
530
|
-
};
|
|
531
|
-
}
|
|
532
|
-
/**
|
|
533
|
-
* Cache for extractFields results to avoid redundant schema extraction
|
|
534
|
-
*/
|
|
535
|
-
const extractFieldsCache = /* @__PURE__ */ new WeakMap();
|
|
536
|
-
/**
|
|
537
|
-
* Extract all fields from a schema
|
|
538
|
-
*
|
|
539
|
-
* @param schema - The args schema (ZodObject, ZodDiscriminatedUnion, etc.)
|
|
540
|
-
* @returns Extracted field information
|
|
541
|
-
*/
|
|
542
|
-
function extractFields(schema) {
|
|
543
|
-
const cached = extractFieldsCache.get(schema);
|
|
544
|
-
if (cached) return cached;
|
|
545
|
-
let result;
|
|
546
|
-
const typeName = getTypeName(schema);
|
|
547
|
-
const s = schema;
|
|
548
|
-
const def = s.def ?? s._def;
|
|
549
|
-
switch (typeName) {
|
|
550
|
-
case "object": {
|
|
551
|
-
const description = extractDescription(schema);
|
|
552
|
-
result = {
|
|
553
|
-
fields: extractFromObject(schema),
|
|
554
|
-
schema,
|
|
555
|
-
schemaType: "object",
|
|
556
|
-
unknownKeysMode: getUnknownKeysMode(schema),
|
|
557
|
-
...description ? { description } : {}
|
|
558
|
-
};
|
|
559
|
-
break;
|
|
560
|
-
}
|
|
561
|
-
case "union":
|
|
562
|
-
if (def?.discriminator) result = extractFromDiscriminatedUnion(schema);
|
|
563
|
-
else result = extractFromUnionLike(schema, "union");
|
|
564
|
-
break;
|
|
565
|
-
case "xor":
|
|
566
|
-
result = extractFromUnionLike(schema, "xor");
|
|
567
|
-
break;
|
|
568
|
-
case "intersection":
|
|
569
|
-
result = extractFromIntersection(schema);
|
|
570
|
-
break;
|
|
571
|
-
case "pipe": {
|
|
572
|
-
const pipeInner = def?.in ?? def?.schema;
|
|
573
|
-
if (pipeInner) {
|
|
574
|
-
const innerResult = extractFields(pipeInner);
|
|
575
|
-
const pipeDescription = extractDescription(schema);
|
|
576
|
-
result = {
|
|
577
|
-
...innerResult,
|
|
578
|
-
schema,
|
|
579
|
-
...pipeDescription ? { description: pipeDescription } : {}
|
|
580
|
-
};
|
|
581
|
-
break;
|
|
582
|
-
}
|
|
583
|
-
const pipeDescription = extractDescription(schema);
|
|
584
|
-
result = {
|
|
585
|
-
fields: [],
|
|
586
|
-
schema,
|
|
587
|
-
schemaType: "object",
|
|
588
|
-
unknownKeysMode: getUnknownKeysMode(schema),
|
|
589
|
-
...pipeDescription ? { description: pipeDescription } : {}
|
|
590
|
-
};
|
|
591
|
-
break;
|
|
592
|
-
}
|
|
593
|
-
default: {
|
|
594
|
-
const description = extractDescription(schema);
|
|
595
|
-
result = {
|
|
596
|
-
fields: [],
|
|
597
|
-
schema,
|
|
598
|
-
schemaType: "object",
|
|
599
|
-
unknownKeysMode: getUnknownKeysMode(schema),
|
|
600
|
-
...description ? { description } : {}
|
|
601
|
-
};
|
|
602
|
-
break;
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
extractFieldsCache.set(schema, result);
|
|
606
|
-
return result;
|
|
607
|
-
}
|
|
608
|
-
/**
|
|
609
|
-
* Get extracted fields from a command
|
|
610
|
-
*
|
|
611
|
-
* @param command - The command to extract fields from
|
|
612
|
-
* @returns Extracted field information, or null if command has no args schema
|
|
613
|
-
*/
|
|
614
|
-
function getExtractedFields(command) {
|
|
615
|
-
if (!command.args) return null;
|
|
616
|
-
return extractFields(command.args);
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
//#endregion
|
|
620
|
-
Object.defineProperty(exports, 'arg', {
|
|
621
|
-
enumerable: true,
|
|
622
|
-
get: function () {
|
|
623
|
-
return arg;
|
|
624
|
-
}
|
|
625
|
-
});
|
|
626
|
-
Object.defineProperty(exports, 'extractFields', {
|
|
627
|
-
enumerable: true,
|
|
628
|
-
get: function () {
|
|
629
|
-
return extractFields;
|
|
630
|
-
}
|
|
631
|
-
});
|
|
632
|
-
Object.defineProperty(exports, 'getAllAliases', {
|
|
633
|
-
enumerable: true,
|
|
634
|
-
get: function () {
|
|
635
|
-
return getAllAliases;
|
|
636
|
-
}
|
|
637
|
-
});
|
|
638
|
-
Object.defineProperty(exports, 'getExtractedFields', {
|
|
639
|
-
enumerable: true,
|
|
640
|
-
get: function () {
|
|
641
|
-
return getExtractedFields;
|
|
642
|
-
}
|
|
643
|
-
});
|
|
644
|
-
Object.defineProperty(exports, 'getUnknownKeysMode', {
|
|
645
|
-
enumerable: true,
|
|
646
|
-
get: function () {
|
|
647
|
-
return getUnknownKeysMode;
|
|
648
|
-
}
|
|
649
|
-
});
|
|
650
|
-
Object.defineProperty(exports, 'isLazyCommand', {
|
|
651
|
-
enumerable: true,
|
|
652
|
-
get: function () {
|
|
653
|
-
return isLazyCommand;
|
|
654
|
-
}
|
|
655
|
-
});
|
|
656
|
-
Object.defineProperty(exports, 'lazy', {
|
|
657
|
-
enumerable: true,
|
|
658
|
-
get: function () {
|
|
659
|
-
return lazy;
|
|
660
|
-
}
|
|
661
|
-
});
|
|
662
|
-
Object.defineProperty(exports, 'listSubCommandNamesWithAliases', {
|
|
663
|
-
enumerable: true,
|
|
664
|
-
get: function () {
|
|
665
|
-
return listSubCommandNamesWithAliases;
|
|
666
|
-
}
|
|
667
|
-
});
|
|
668
|
-
Object.defineProperty(exports, 'listSubCommands', {
|
|
669
|
-
enumerable: true,
|
|
670
|
-
get: function () {
|
|
671
|
-
return listSubCommands;
|
|
672
|
-
}
|
|
673
|
-
});
|
|
674
|
-
Object.defineProperty(exports, 'resolveLazyCommand', {
|
|
675
|
-
enumerable: true,
|
|
676
|
-
get: function () {
|
|
677
|
-
return resolveLazyCommand;
|
|
678
|
-
}
|
|
679
|
-
});
|
|
680
|
-
Object.defineProperty(exports, 'resolveSubCommandAlias', {
|
|
681
|
-
enumerable: true,
|
|
682
|
-
get: function () {
|
|
683
|
-
return resolveSubCommandAlias;
|
|
684
|
-
}
|
|
685
|
-
});
|
|
686
|
-
Object.defineProperty(exports, 'resolveSubCommandMeta', {
|
|
687
|
-
enumerable: true,
|
|
688
|
-
get: function () {
|
|
689
|
-
return resolveSubCommandMeta;
|
|
690
|
-
}
|
|
691
|
-
});
|
|
692
|
-
Object.defineProperty(exports, 'resolveSubcommandWithAlias', {
|
|
693
|
-
enumerable: true,
|
|
694
|
-
get: function () {
|
|
695
|
-
return resolveSubcommandWithAlias;
|
|
696
|
-
}
|
|
697
|
-
});
|
|
698
|
-
Object.defineProperty(exports, 'toCamelCase', {
|
|
699
|
-
enumerable: true,
|
|
700
|
-
get: function () {
|
|
701
|
-
return toCamelCase;
|
|
702
|
-
}
|
|
703
|
-
});
|
|
704
|
-
Object.defineProperty(exports, 'toKebabCase', {
|
|
705
|
-
enumerable: true,
|
|
706
|
-
get: function () {
|
|
707
|
-
return toKebabCase;
|
|
708
|
-
}
|
|
709
|
-
});
|
|
710
|
-
//# sourceMappingURL=schema-extractor-BxSRwLrx.cjs.map
|