padrone 1.5.0 → 1.7.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/CHANGELOG.md +44 -0
- package/README.md +15 -11
- package/dist/{args-D5PNDyNu.mjs → args-Cnq0nwSM.mjs} +91 -41
- package/dist/args-Cnq0nwSM.mjs.map +1 -0
- package/dist/codegen/index.mjs +4 -4
- package/dist/codegen/index.mjs.map +1 -1
- package/dist/commands-B_gufyR9.mjs +514 -0
- package/dist/commands-B_gufyR9.mjs.map +1 -0
- package/dist/{completion.mjs → completion-BEuflbDO.mjs} +12 -82
- package/dist/completion-BEuflbDO.mjs.map +1 -0
- package/dist/docs/index.d.mts +4 -4
- package/dist/docs/index.d.mts.map +1 -1
- package/dist/docs/index.mjs +10 -12
- package/dist/docs/index.mjs.map +1 -1
- package/dist/{errors-BiVrBgi6.mjs → errors-DA4KzK1M.mjs} +26 -3
- package/dist/errors-DA4KzK1M.mjs.map +1 -0
- package/dist/{formatter-DtHzbP22.d.mts → formatter-DrvhDMrq.d.mts} +3 -3
- package/dist/formatter-DrvhDMrq.d.mts.map +1 -0
- package/dist/{help-bbmu9-qd.mjs → help-BtxLgrF_.mjs} +190 -43
- package/dist/help-BtxLgrF_.mjs.map +1 -0
- package/dist/{types-Ch8Mk6Qb.d.mts → index-D6-7dz0l.d.mts} +634 -745
- package/dist/index-D6-7dz0l.d.mts.map +1 -0
- package/dist/index.d.mts +869 -36
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +3884 -1699
- package/dist/index.mjs.map +1 -1
- package/dist/{mcp-mLWIdUIu.mjs → mcp-6-Jw4Bpq.mjs} +13 -15
- package/dist/mcp-6-Jw4Bpq.mjs.map +1 -0
- package/dist/{serve-B0u43DK7.mjs → serve-YVTPzBCl.mjs} +12 -14
- package/dist/serve-YVTPzBCl.mjs.map +1 -0
- package/dist/{stream-BcC146Ud.mjs → stream-DC4H8YTx.mjs} +24 -3
- package/dist/stream-DC4H8YTx.mjs.map +1 -0
- package/dist/test.d.mts +5 -8
- package/dist/test.d.mts.map +1 -1
- package/dist/test.mjs +2 -13
- package/dist/test.mjs.map +1 -1
- package/dist/{update-check-CFX1FV3v.mjs → update-check-CZ2VqjnV.mjs} +16 -17
- package/dist/update-check-CZ2VqjnV.mjs.map +1 -0
- package/dist/zod.d.mts +2 -2
- package/dist/zod.d.mts.map +1 -1
- package/dist/zod.mjs +2 -2
- package/dist/zod.mjs.map +1 -1
- package/package.json +15 -12
- package/src/cli/completions.ts +14 -11
- package/src/cli/docs.ts +13 -10
- package/src/cli/doctor.ts +22 -18
- package/src/cli/index.ts +28 -82
- package/src/cli/init.ts +10 -7
- package/src/cli/link.ts +20 -16
- package/src/cli/wrap.ts +14 -11
- package/src/codegen/schema-to-code.ts +2 -2
- package/src/{args.ts → core/args.ts} +32 -225
- package/src/core/commands.ts +373 -0
- package/src/core/create.ts +301 -0
- package/src/core/default-runtime.ts +239 -0
- package/src/{errors.ts → core/errors.ts} +22 -0
- package/src/core/exec.ts +259 -0
- package/src/core/interceptors.ts +302 -0
- package/src/{parse.ts → core/parse.ts} +36 -89
- package/src/core/program-methods.ts +301 -0
- package/src/core/results.ts +229 -0
- package/src/core/runtime.ts +246 -0
- package/src/core/validate.ts +247 -0
- package/src/docs/index.ts +12 -13
- package/src/extension/auto-output.ts +146 -0
- package/src/extension/color.ts +38 -0
- package/src/extension/completion.ts +49 -0
- package/src/extension/config.ts +262 -0
- package/src/extension/env.ts +101 -0
- package/src/extension/help.ts +192 -0
- package/src/extension/index.ts +44 -0
- package/src/extension/ink.ts +93 -0
- package/src/extension/interactive.ts +106 -0
- package/src/extension/logger.ts +262 -0
- package/src/extension/man.ts +51 -0
- package/src/extension/mcp.ts +52 -0
- package/src/extension/progress-renderer.ts +338 -0
- package/src/extension/progress.ts +299 -0
- package/src/extension/repl.ts +94 -0
- package/src/extension/serve.ts +48 -0
- package/src/extension/signal.ts +87 -0
- package/src/extension/stdin.ts +62 -0
- package/src/extension/suggestions.ts +114 -0
- package/src/extension/timing.ts +81 -0
- package/src/extension/tracing.ts +175 -0
- package/src/extension/update-check.ts +77 -0
- package/src/extension/utils.ts +51 -0
- package/src/extension/version.ts +63 -0
- package/src/{completion.ts → feature/completion.ts} +12 -12
- package/src/{interactive.ts → feature/interactive.ts} +4 -4
- package/src/{mcp.ts → feature/mcp.ts} +12 -15
- package/src/{repl-loop.ts → feature/repl-loop.ts} +10 -13
- package/src/{serve.ts → feature/serve.ts} +11 -15
- package/src/feature/test.ts +262 -0
- package/src/{update-check.ts → feature/update-check.ts} +16 -16
- package/src/{wrap.ts → feature/wrap.ts} +10 -8
- package/src/index.ts +115 -30
- package/src/{formatter.ts → output/formatter.ts} +124 -176
- package/src/{help.ts → output/help.ts} +22 -8
- package/src/output/output-indicator.ts +87 -0
- package/src/output/primitives.ts +335 -0
- package/src/output/styling.ts +221 -0
- package/src/{zod.d.ts → schema/zod.d.ts} +1 -1
- package/src/schema/zod.ts +50 -0
- package/src/test.ts +2 -276
- package/src/types/args-meta.ts +151 -0
- package/src/types/builder.ts +718 -0
- package/src/types/command.ts +157 -0
- package/src/types/index.ts +60 -0
- package/src/types/interceptor.ts +296 -0
- package/src/types/preferences.ts +83 -0
- package/src/types/result.ts +71 -0
- package/src/types/schema.ts +19 -0
- package/src/util/dotenv.ts +244 -0
- package/src/{shell-utils.ts → util/shell-utils.ts} +26 -9
- package/src/{stream.ts → util/stream.ts} +27 -1
- package/src/{type-helpers.ts → util/type-helpers.ts} +23 -16
- package/src/{type-utils.ts → util/type-utils.ts} +71 -33
- package/src/util/utils.ts +51 -0
- package/src/zod.ts +1 -50
- package/dist/args-D5PNDyNu.mjs.map +0 -1
- package/dist/chunk-CjcI7cDX.mjs +0 -15
- package/dist/command-utils-B1D-HqCd.mjs +0 -1117
- package/dist/command-utils-B1D-HqCd.mjs.map +0 -1
- package/dist/completion.d.mts +0 -64
- package/dist/completion.d.mts.map +0 -1
- package/dist/completion.mjs.map +0 -1
- package/dist/errors-BiVrBgi6.mjs.map +0 -1
- package/dist/formatter-DtHzbP22.d.mts.map +0 -1
- package/dist/help-bbmu9-qd.mjs.map +0 -1
- package/dist/mcp-mLWIdUIu.mjs.map +0 -1
- package/dist/serve-B0u43DK7.mjs.map +0 -1
- package/dist/stream-BcC146Ud.mjs.map +0 -1
- package/dist/types-Ch8Mk6Qb.d.mts.map +0 -1
- package/dist/update-check-CFX1FV3v.mjs.map +0 -1
- package/src/command-utils.ts +0 -882
- package/src/create.ts +0 -1829
- package/src/runtime.ts +0 -497
- package/src/types.ts +0 -1291
- package/src/utils.ts +0 -140
- /package/src/{colorizer.ts → output/colorizer.ts} +0 -0
|
@@ -1,181 +1,22 @@
|
|
|
1
1
|
import type { StandardJSONSchemaV1, StandardSchemaV1 } from '@standard-schema/spec';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
| 'j'
|
|
15
|
-
| 'k'
|
|
16
|
-
| 'l'
|
|
17
|
-
| 'm'
|
|
18
|
-
| 'n'
|
|
19
|
-
| 'o'
|
|
20
|
-
| 'p'
|
|
21
|
-
| 'q'
|
|
22
|
-
| 'r'
|
|
23
|
-
| 's'
|
|
24
|
-
| 't'
|
|
25
|
-
| 'u'
|
|
26
|
-
| 'v'
|
|
27
|
-
| 'w'
|
|
28
|
-
| 'x'
|
|
29
|
-
| 'y'
|
|
30
|
-
| 'z';
|
|
31
|
-
|
|
32
|
-
/** A single letter character, valid as a short CLI flag (e.g. `'v'`, `'n'`, `'V'`). */
|
|
33
|
-
export type SingleChar = Letter | Uppercase<Letter>;
|
|
34
|
-
|
|
35
|
-
export interface PadroneFieldMeta {
|
|
36
|
-
description?: string;
|
|
37
|
-
/** Single-character short flags (stackable: `-abc` = `-a -b -c`). Used with single dash. */
|
|
38
|
-
flags?: readonly SingleChar[] | SingleChar;
|
|
39
|
-
/** Multi-character alternative long names. Used with double dash (e.g. `--dry-run` for `--dryRun`). */
|
|
40
|
-
alias?: readonly string[] | string;
|
|
41
|
-
deprecated?: boolean | string;
|
|
42
|
-
hidden?: boolean;
|
|
43
|
-
examples?: readonly unknown[];
|
|
44
|
-
/** Group name for organizing this option under a labeled section in help output. */
|
|
45
|
-
group?: string;
|
|
2
|
+
import type { PadroneFieldMeta } from '../types/args-meta.ts';
|
|
3
|
+
import { camelToKebab } from '../util/shell-utils.ts';
|
|
4
|
+
import { asyncStreamRegistry } from '../util/stream.ts';
|
|
5
|
+
|
|
6
|
+
export type { PadroneArgsSchemaMeta, PadroneFieldMeta, SingleChar, StdinConfig } from '../types/args-meta.ts';
|
|
7
|
+
|
|
8
|
+
/** Extract the JSON schema from a Standard Schema, returning it as a plain record. */
|
|
9
|
+
export function getJsonSchema(schema: StandardJSONSchemaV1): Record<string, any> {
|
|
10
|
+
return schema['~standard'].jsonSchema.input({
|
|
11
|
+
target: 'draft-2020-12',
|
|
12
|
+
libraryOptions: { unrepresentable: 'any' },
|
|
13
|
+
}) as Record<string, any>;
|
|
46
14
|
}
|
|
47
15
|
|
|
48
|
-
type PositionalArgs<TObj> =
|
|
49
|
-
TObj extends Record<string, any>
|
|
50
|
-
? {
|
|
51
|
-
[K in keyof TObj]: NonNullable<TObj[K]> extends Array<any> ? `...${K & string}` | (K & string) : K & string;
|
|
52
|
-
}[keyof TObj]
|
|
53
|
-
: string;
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Meta configuration for arguments, including positional arguments.
|
|
57
|
-
* The `positional` array defines which arguments are positional and their order.
|
|
58
|
-
* Use '...name' prefix to indicate variadic (rest) arguments, matching JS/TS rest syntax.
|
|
59
|
-
*
|
|
60
|
-
* @example
|
|
61
|
-
* ```ts
|
|
62
|
-
* .arguments(schema, {
|
|
63
|
-
* positional: ['source', '...files', 'dest'], // '...files' is variadic
|
|
64
|
-
* })
|
|
65
|
-
* ```
|
|
66
|
-
*/
|
|
67
|
-
/**
|
|
68
|
-
* Configuration for reading from stdin and mapping it to an argument field.
|
|
69
|
-
* Simply specify the field name — the read mode is inferred from the schema:
|
|
70
|
-
* - `string` field → reads all stdin as text
|
|
71
|
-
* - `string[]` field → reads stdin line-by-line
|
|
72
|
-
*/
|
|
73
|
-
export type StdinConfig<TObj = Record<string, any>> = keyof TObj & string;
|
|
74
|
-
|
|
75
|
-
export interface PadroneArgsSchemaMeta<TObj = Record<string, any>> {
|
|
76
|
-
/**
|
|
77
|
-
* Array of argument names that should be treated as positional arguments.
|
|
78
|
-
* Order in array determines position. Use '...name' prefix for variadic args.
|
|
79
|
-
* @example ['source', '...files', 'dest'] - 'files' captures multiple values
|
|
80
|
-
*/
|
|
81
|
-
positional?: readonly PositionalArgs<TObj>[];
|
|
82
|
-
/**
|
|
83
|
-
* Per-argument metadata.
|
|
84
|
-
*/
|
|
85
|
-
fields?: { [K in keyof TObj]?: PadroneFieldMeta };
|
|
86
|
-
/**
|
|
87
|
-
* Automatically generate kebab-case aliases for camelCase option names.
|
|
88
|
-
* For example, `dryRun` automatically gets `--dry-run` as an alias.
|
|
89
|
-
* Defaults to `true`. Set to `false` to disable.
|
|
90
|
-
*
|
|
91
|
-
* @default true
|
|
92
|
-
* @example
|
|
93
|
-
* ```ts
|
|
94
|
-
* // Auto-aliases enabled (default): --dry-run → dryRun
|
|
95
|
-
* .arguments(z.object({ dryRun: z.boolean() }))
|
|
96
|
-
*
|
|
97
|
-
* // Disable auto-aliases
|
|
98
|
-
* .arguments(z.object({ dryRun: z.boolean() }), { autoAlias: false })
|
|
99
|
-
* ```
|
|
100
|
-
*/
|
|
101
|
-
autoAlias?: boolean;
|
|
102
|
-
/**
|
|
103
|
-
* Read from stdin and inject the data into the specified argument field.
|
|
104
|
-
* Only reads when stdin is piped (not a TTY) and the field wasn't already provided via CLI flags.
|
|
105
|
-
*
|
|
106
|
-
* The read mode is inferred from the schema type of the target field:
|
|
107
|
-
* - `string` field → reads all stdin as a single string
|
|
108
|
-
* - `string[]` field → reads stdin line-by-line into an array
|
|
109
|
-
*
|
|
110
|
-
* Precedence: CLI flags > stdin > env vars > config file > schema defaults.
|
|
111
|
-
*
|
|
112
|
-
* @example
|
|
113
|
-
* ```ts
|
|
114
|
-
* // Read all stdin as text into 'data' field
|
|
115
|
-
* .arguments(z.object({ data: z.string() }), { stdin: 'data' })
|
|
116
|
-
*
|
|
117
|
-
* // Read stdin lines into 'lines' field (inferred from array schema)
|
|
118
|
-
* .arguments(z.object({ lines: z.string().array() }), { stdin: 'lines' })
|
|
119
|
-
* ```
|
|
120
|
-
*/
|
|
121
|
-
stdin?: StdinConfig<TObj>;
|
|
122
|
-
/**
|
|
123
|
-
* Fields to interactively prompt for when their values are missing after CLI/env/config resolution.
|
|
124
|
-
* - `true`: prompt for all required fields that are missing.
|
|
125
|
-
* - `string[]`: prompt for these specific fields if missing.
|
|
126
|
-
*
|
|
127
|
-
* Interactive prompting only occurs in `cli()` when the runtime has `interactive: true`.
|
|
128
|
-
* Setting this makes `parse()` and `cli()` return Promises.
|
|
129
|
-
*
|
|
130
|
-
* @example
|
|
131
|
-
* ```ts
|
|
132
|
-
* .arguments(schema, {
|
|
133
|
-
* interactive: true, // prompt all missing required fields
|
|
134
|
-
* interactive: ['name', 'template'], // prompt only these fields
|
|
135
|
-
* })
|
|
136
|
-
* ```
|
|
137
|
-
*/
|
|
138
|
-
interactive?: true | readonly (keyof TObj & string)[];
|
|
139
|
-
/**
|
|
140
|
-
* Optional fields offered after required interactive prompts.
|
|
141
|
-
* Users are shown a multi-select to choose which of these fields to configure.
|
|
142
|
-
* - `true`: offer all optional fields that are missing.
|
|
143
|
-
* - `string[]`: offer these specific fields.
|
|
144
|
-
*
|
|
145
|
-
* @example
|
|
146
|
-
* ```ts
|
|
147
|
-
* .arguments(schema, {
|
|
148
|
-
* interactive: ['name'],
|
|
149
|
-
* optionalInteractive: ['typescript', 'eslint', 'prettier'],
|
|
150
|
-
* })
|
|
151
|
-
* ```
|
|
152
|
-
*/
|
|
153
|
-
optionalInteractive?: true | readonly (keyof TObj & string)[];
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Convert a camelCase string to kebab-case.
|
|
158
|
-
* Returns null if the string has no uppercase letters (no conversion needed).
|
|
159
|
-
*/
|
|
160
|
-
export function camelToKebab(str: string): string | null {
|
|
161
|
-
if (!/[A-Z]/.test(str)) return null;
|
|
162
|
-
return str.replace(/[A-Z]/g, (ch) => `-${ch.toLowerCase()}`);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Returns the stdin field name from the config.
|
|
167
|
-
*/
|
|
168
|
-
export function parseStdinConfig(stdin: StdinConfig): string {
|
|
169
|
-
return stdin;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/** Options passed to `jsonSchema.input()` to handle unrepresentable types like `z.custom()`. */
|
|
173
|
-
export const JSON_SCHEMA_OPTS = { target: 'draft-2020-12', libraryOptions: { unrepresentable: 'any' } } as const;
|
|
174
|
-
|
|
175
16
|
function getFieldJsonSchema(schema: StandardJSONSchemaV1 | undefined, field: string): Record<string, any> | undefined {
|
|
176
17
|
if (!schema) return undefined;
|
|
177
18
|
try {
|
|
178
|
-
const jsonSchema = schema
|
|
19
|
+
const jsonSchema = getJsonSchema(schema);
|
|
179
20
|
if (jsonSchema.type === 'object' && jsonSchema.properties) return jsonSchema.properties[field];
|
|
180
21
|
} catch {}
|
|
181
22
|
return undefined;
|
|
@@ -208,9 +49,9 @@ export function isAsyncStreamField(schema: StandardJSONSchemaV1 | undefined, fie
|
|
|
208
49
|
*/
|
|
209
50
|
export function parsePositionalConfig(positional: readonly string[]): { name: string; variadic: boolean }[] {
|
|
210
51
|
return positional.map((p) => {
|
|
211
|
-
const
|
|
212
|
-
const name =
|
|
213
|
-
return { name, variadic
|
|
52
|
+
const variadic = p.startsWith('...');
|
|
53
|
+
const name = variadic ? p.slice(3) : p;
|
|
54
|
+
return { name, variadic };
|
|
214
55
|
});
|
|
215
56
|
}
|
|
216
57
|
|
|
@@ -262,7 +103,7 @@ export function extractSchemaMetadata(
|
|
|
262
103
|
|
|
263
104
|
// Extract from JSON schema properties
|
|
264
105
|
try {
|
|
265
|
-
const jsonSchema = schema
|
|
106
|
+
const jsonSchema = getJsonSchema(schema) as Record<string, any>;
|
|
266
107
|
if (jsonSchema.type === 'object' && jsonSchema.properties) {
|
|
267
108
|
for (const [propertyName, propertySchema] of Object.entries(jsonSchema.properties as Record<string, any>)) {
|
|
268
109
|
if (!propertySchema) continue;
|
|
@@ -313,23 +154,14 @@ function preprocessMappings(data: Record<string, unknown>, mappings: Record<stri
|
|
|
313
154
|
return result;
|
|
314
155
|
}
|
|
315
156
|
|
|
316
|
-
interface ParseArgsContext {
|
|
317
|
-
flags?: Record<string, string>;
|
|
318
|
-
aliases?: Record<string, string>;
|
|
319
|
-
stdinData?: Record<string, unknown>;
|
|
320
|
-
envData?: Record<string, unknown>;
|
|
321
|
-
configData?: Record<string, unknown>;
|
|
322
|
-
}
|
|
323
|
-
|
|
324
157
|
/**
|
|
325
|
-
* Apply values
|
|
326
|
-
*
|
|
158
|
+
* Apply values to arguments using "set if not present" semantics.
|
|
159
|
+
* Existing values take precedence — only fills in undefined or missing keys.
|
|
327
160
|
*/
|
|
328
|
-
function applyValues(data: Record<string, unknown>, values: Record<string, unknown>): Record<string, unknown> {
|
|
161
|
+
export function applyValues(data: Record<string, unknown>, values: Record<string, unknown>): Record<string, unknown> {
|
|
329
162
|
const result = { ...data };
|
|
330
163
|
|
|
331
164
|
for (const [key, value] of Object.entries(values)) {
|
|
332
|
-
// Only apply value if arg wasn't already set
|
|
333
165
|
if (key in result && result[key] !== undefined) continue;
|
|
334
166
|
if (value !== undefined) {
|
|
335
167
|
result[key] = value;
|
|
@@ -339,14 +171,13 @@ function applyValues(data: Record<string, unknown>, values: Record<string, unkno
|
|
|
339
171
|
return result;
|
|
340
172
|
}
|
|
341
173
|
|
|
342
|
-
/**
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
174
|
+
/** Applies flag and alias mappings to raw arguments. */
|
|
175
|
+
export function preprocessArgs(
|
|
176
|
+
data: Record<string, unknown>,
|
|
177
|
+
ctx: { flags?: Record<string, string>; aliases?: Record<string, string> },
|
|
178
|
+
): Record<string, unknown> {
|
|
347
179
|
let result = { ...data };
|
|
348
180
|
|
|
349
|
-
// 1. Apply flags and aliases first
|
|
350
181
|
if (ctx.flags && Object.keys(ctx.flags).length > 0) {
|
|
351
182
|
result = preprocessMappings(result, ctx.flags);
|
|
352
183
|
}
|
|
@@ -354,24 +185,6 @@ export function preprocessArgs(data: Record<string, unknown>, ctx: ParseArgsCont
|
|
|
354
185
|
result = preprocessMappings(result, ctx.aliases);
|
|
355
186
|
}
|
|
356
187
|
|
|
357
|
-
// 2. Apply stdin data (higher precedence than env)
|
|
358
|
-
// Only applies if CLI didn't set the arg
|
|
359
|
-
if (ctx.stdinData) {
|
|
360
|
-
result = applyValues(result, ctx.stdinData);
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
// 3. Apply environment variables (higher precedence than config)
|
|
364
|
-
// These only apply if CLI/stdin didn't set the arg
|
|
365
|
-
if (ctx.envData) {
|
|
366
|
-
result = applyValues(result, ctx.envData);
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
// 4. Apply config file values (lowest precedence)
|
|
370
|
-
// These only apply if neither CLI, stdin, nor env set the arg
|
|
371
|
-
if (ctx.configData) {
|
|
372
|
-
result = applyValues(result, ctx.configData);
|
|
373
|
-
}
|
|
374
|
-
|
|
375
188
|
return result;
|
|
376
189
|
}
|
|
377
190
|
|
|
@@ -383,7 +196,7 @@ export function preprocessArgs(data: Record<string, unknown>, ctx: ParseArgsCont
|
|
|
383
196
|
export function coerceArgs(data: Record<string, unknown>, schema: StandardJSONSchemaV1): Record<string, unknown> {
|
|
384
197
|
let properties: Record<string, any>;
|
|
385
198
|
try {
|
|
386
|
-
const jsonSchema = schema
|
|
199
|
+
const jsonSchema = getJsonSchema(schema) as Record<string, any>;
|
|
387
200
|
if (jsonSchema.type !== 'object' || !jsonSchema.properties) return data;
|
|
388
201
|
properties = jsonSchema.properties;
|
|
389
202
|
} catch {
|
|
@@ -439,12 +252,9 @@ export function coerceArgs(data: Record<string, unknown>, schema: StandardJSONSc
|
|
|
439
252
|
return result;
|
|
440
253
|
}
|
|
441
254
|
|
|
442
|
-
/** Keys consumed by the CLI framework that are not user-defined args. */
|
|
443
|
-
const frameworkReservedKeys = new Set(['config', 'c']);
|
|
444
|
-
|
|
445
255
|
/**
|
|
446
256
|
* Detect unknown keys in the args that don't match any schema property.
|
|
447
|
-
* Returns an array of { key
|
|
257
|
+
* Returns an array of { key } for each unknown key.
|
|
448
258
|
* Framework-reserved keys (--config, -c) are always allowed.
|
|
449
259
|
*/
|
|
450
260
|
export function detectUnknownArgs(
|
|
@@ -452,12 +262,11 @@ export function detectUnknownArgs(
|
|
|
452
262
|
schema: StandardJSONSchemaV1,
|
|
453
263
|
flags: Record<string, string>,
|
|
454
264
|
aliases: Record<string, string>,
|
|
455
|
-
|
|
456
|
-
): { key: string; suggestion: string }[] {
|
|
265
|
+
): { key: string }[] {
|
|
457
266
|
let properties: Record<string, any>;
|
|
458
267
|
let isLoose = false;
|
|
459
268
|
try {
|
|
460
|
-
const jsonSchema = schema
|
|
269
|
+
const jsonSchema = getJsonSchema(schema) as Record<string, any>;
|
|
461
270
|
if (jsonSchema.type !== 'object' || !jsonSchema.properties) return [];
|
|
462
271
|
properties = jsonSchema.properties;
|
|
463
272
|
// If additionalProperties is set (true, {}, or a schema), the schema allows extra keys
|
|
@@ -475,13 +284,11 @@ export function detectUnknownArgs(
|
|
|
475
284
|
...Object.keys(aliases),
|
|
476
285
|
...Object.values(aliases),
|
|
477
286
|
]);
|
|
478
|
-
const
|
|
479
|
-
const unknowns: { key: string; suggestion: string }[] = [];
|
|
287
|
+
const unknowns: { key: string }[] = [];
|
|
480
288
|
|
|
481
289
|
for (const key of Object.keys(data)) {
|
|
482
|
-
if (!knownKeys.has(key)
|
|
483
|
-
|
|
484
|
-
unknowns.push({ key, suggestion });
|
|
290
|
+
if (!knownKeys.has(key)) {
|
|
291
|
+
unknowns.push({ key });
|
|
485
292
|
}
|
|
486
293
|
}
|
|
487
294
|
|