@runa-cmd/core 0.1.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/LICENSE +21 -0
- package/README.md +351 -0
- package/dist/cli.d.ts +12 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +413 -0
- package/dist/cli.js.map +1 -0
- package/dist/command.d.ts +20 -0
- package/dist/command.d.ts.map +1 -0
- package/dist/command.js +46 -0
- package/dist/command.js.map +1 -0
- package/dist/config/loader.d.ts +9 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +34 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/merge.d.ts +18 -0
- package/dist/config/merge.d.ts.map +1 -0
- package/dist/config/merge.js +31 -0
- package/dist/config/merge.js.map +1 -0
- package/dist/config/search.d.ts +18 -0
- package/dist/config/search.d.ts.map +1 -0
- package/dist/config/search.js +40 -0
- package/dist/config/search.js.map +1 -0
- package/dist/errors.d.ts +32 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +65 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/introspect.d.ts +16 -0
- package/dist/introspect.d.ts.map +1 -0
- package/dist/introspect.js +128 -0
- package/dist/introspect.js.map +1 -0
- package/dist/lifecycle.d.ts +27 -0
- package/dist/lifecycle.d.ts.map +1 -0
- package/dist/lifecycle.js +62 -0
- package/dist/lifecycle.js.map +1 -0
- package/dist/middleware.d.ts +16 -0
- package/dist/middleware.d.ts.map +1 -0
- package/dist/middleware.js +15 -0
- package/dist/middleware.js.map +1 -0
- package/dist/parse/parseargs-bridge.d.ts +22 -0
- package/dist/parse/parseargs-bridge.d.ts.map +1 -0
- package/dist/parse/parseargs-bridge.js +54 -0
- package/dist/parse/parseargs-bridge.js.map +1 -0
- package/dist/parse/resolve.d.ts +48 -0
- package/dist/parse/resolve.d.ts.map +1 -0
- package/dist/parse/resolve.js +240 -0
- package/dist/parse/resolve.js.map +1 -0
- package/dist/parse/schema-walker.d.ts +21 -0
- package/dist/parse/schema-walker.d.ts.map +1 -0
- package/dist/parse/schema-walker.js +121 -0
- package/dist/parse/schema-walker.js.map +1 -0
- package/dist/parse/variadic.d.ts +22 -0
- package/dist/parse/variadic.d.ts.map +1 -0
- package/dist/parse/variadic.js +71 -0
- package/dist/parse/variadic.js.map +1 -0
- package/dist/plugin.d.ts +53 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +194 -0
- package/dist/plugin.js.map +1 -0
- package/dist/types.d.ts +225 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +19 -0
- package/dist/types.js.map +1 -0
- package/dist/zod.d.ts +8 -0
- package/dist/zod.d.ts.map +1 -0
- package/dist/zod.js +8 -0
- package/dist/zod.js.map +1 -0
- package/package.json +66 -0
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @runa-cmd/core — Value resolution pipeline
|
|
3
|
+
*
|
|
4
|
+
* Merge priority: CLI args > env vars > config file > Zod defaults.
|
|
5
|
+
* Maps positionals to args by insertion order.
|
|
6
|
+
* Pre-coerces number strings before Zod .parse().
|
|
7
|
+
*/
|
|
8
|
+
import { ZodError, z } from 'zod';
|
|
9
|
+
import { ValidationError } from '../errors.js';
|
|
10
|
+
import { walkSchema } from './schema-walker.js';
|
|
11
|
+
import { isVariadic } from './variadic.js';
|
|
12
|
+
// ─── Positional Mapping ─────────────────────────────────────
|
|
13
|
+
function mapPositionals(positionals, argsSchemas) {
|
|
14
|
+
const keys = Object.keys(argsSchemas);
|
|
15
|
+
const result = {};
|
|
16
|
+
if (keys.length === 0) {
|
|
17
|
+
// No args defined but positionals provided
|
|
18
|
+
if (positionals.length > 0) {
|
|
19
|
+
throw new ValidationError([
|
|
20
|
+
{
|
|
21
|
+
code: 'custom',
|
|
22
|
+
message: `Unexpected positional argument: '${positionals[0]}'`,
|
|
23
|
+
path: [],
|
|
24
|
+
},
|
|
25
|
+
]);
|
|
26
|
+
}
|
|
27
|
+
return result;
|
|
28
|
+
}
|
|
29
|
+
// Check if last arg is variadic
|
|
30
|
+
const lastKey = keys[keys.length - 1];
|
|
31
|
+
if (!lastKey)
|
|
32
|
+
return result;
|
|
33
|
+
const lastSchema = argsSchemas[lastKey];
|
|
34
|
+
const lastIsVariadic = lastSchema ? isVariadic(lastSchema) : false;
|
|
35
|
+
const fixedCount = lastIsVariadic ? keys.length - 1 : keys.length;
|
|
36
|
+
// Check for extra positionals without variadic
|
|
37
|
+
if (!lastIsVariadic && positionals.length > keys.length) {
|
|
38
|
+
throw new ValidationError([
|
|
39
|
+
{
|
|
40
|
+
code: 'custom',
|
|
41
|
+
message: `Unexpected positional argument: '${positionals[keys.length]}'`,
|
|
42
|
+
path: [],
|
|
43
|
+
},
|
|
44
|
+
]);
|
|
45
|
+
}
|
|
46
|
+
// Map fixed positionals
|
|
47
|
+
for (let i = 0; i < fixedCount; i++) {
|
|
48
|
+
const key = keys[i];
|
|
49
|
+
if (!key)
|
|
50
|
+
continue;
|
|
51
|
+
if (i < positionals.length) {
|
|
52
|
+
result[key] = positionals[i];
|
|
53
|
+
}
|
|
54
|
+
// If not provided, omit — let Zod handle required/optional validation
|
|
55
|
+
}
|
|
56
|
+
// Map variadic (remaining positionals go to last key as array)
|
|
57
|
+
if (lastIsVariadic) {
|
|
58
|
+
result[lastKey] = positionals.slice(fixedCount);
|
|
59
|
+
}
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
// ─── Value Resolution ───────────────────────────────────────
|
|
63
|
+
function resolveOptionValues(parseArgsValues, longAliasMap, optionsSchemas, optionsMeta, configValues, env, optionsMetadata) {
|
|
64
|
+
const resolved = {};
|
|
65
|
+
// Build a set of number fields for pre-coercion
|
|
66
|
+
const numberFields = new Set();
|
|
67
|
+
for (const meta of optionsMetadata) {
|
|
68
|
+
if (meta.zodType === 'number') {
|
|
69
|
+
numberFields.add(meta.name);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// First, apply long alias mappings to parseArgs values
|
|
73
|
+
const normalizedValues = { ...parseArgsValues };
|
|
74
|
+
for (const [alias, canonical] of Object.entries(longAliasMap)) {
|
|
75
|
+
if (alias in normalizedValues && !(canonical in normalizedValues)) {
|
|
76
|
+
normalizedValues[canonical] = normalizedValues[alias];
|
|
77
|
+
delete normalizedValues[alias];
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
for (const key of Object.keys(optionsSchemas)) {
|
|
81
|
+
// Priority 1: CLI arg
|
|
82
|
+
if (key in normalizedValues && normalizedValues[key] !== undefined) {
|
|
83
|
+
let value = normalizedValues[key];
|
|
84
|
+
// Pre-coerce numbers from string
|
|
85
|
+
if (numberFields.has(key) && typeof value === 'string') {
|
|
86
|
+
const num = Number(value);
|
|
87
|
+
if (!Number.isNaN(num)) {
|
|
88
|
+
value = num;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
resolved[key] = value;
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
// Priority 2: Environment variable
|
|
95
|
+
const envName = optionsMeta?.[key]?.env;
|
|
96
|
+
if (envName && envName in env && env[envName] !== undefined) {
|
|
97
|
+
let value = env[envName];
|
|
98
|
+
// Pre-coerce numbers from string
|
|
99
|
+
if (numberFields.has(key) && typeof value === 'string') {
|
|
100
|
+
const num = Number(value);
|
|
101
|
+
if (!Number.isNaN(num)) {
|
|
102
|
+
value = num;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
resolved[key] = value;
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
// Priority 3: Config file value
|
|
109
|
+
if (configValues && key in configValues && configValues[key] !== undefined) {
|
|
110
|
+
let value = configValues[key];
|
|
111
|
+
// Pre-coerce numbers from string (config values are usually already typed,
|
|
112
|
+
// but defensive handling)
|
|
113
|
+
if (numberFields.has(key) && typeof value === 'string') {
|
|
114
|
+
const num = Number(value);
|
|
115
|
+
if (!Number.isNaN(num)) {
|
|
116
|
+
value = num;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
resolved[key] = value;
|
|
120
|
+
}
|
|
121
|
+
// Priority 4: Omit — let Zod .default() handle it
|
|
122
|
+
}
|
|
123
|
+
return resolved;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Rewrite Zod issues into user-friendly CLI error messages.
|
|
127
|
+
* Handles common cases: missing required args/options, invalid enums, wrong types.
|
|
128
|
+
*/
|
|
129
|
+
function humanizeArgIssues(issues, argsSchemas) {
|
|
130
|
+
const metadata = walkSchema(argsSchemas);
|
|
131
|
+
const metaByName = new Map(metadata.map((m) => [m.name, m]));
|
|
132
|
+
return issues.map((issue) => {
|
|
133
|
+
const name = issue.path[0];
|
|
134
|
+
if (typeof name !== 'string')
|
|
135
|
+
return issue;
|
|
136
|
+
const param = metaByName.get(name);
|
|
137
|
+
// Missing required arg: Zod v4 produces "Invalid input: expected X, received undefined"
|
|
138
|
+
if (issue.code === 'invalid_type' && issue.message.includes('received undefined')) {
|
|
139
|
+
return {
|
|
140
|
+
code: 'custom',
|
|
141
|
+
message: `Missing required argument: <${name}>${param?.description ? ` — ${param.description}` : ''}`,
|
|
142
|
+
path: issue.path,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
// Invalid enum value (Zod v4 uses 'invalid_value' for enums)
|
|
146
|
+
if (issue.code === 'invalid_value' && param?.enumValues) {
|
|
147
|
+
return {
|
|
148
|
+
code: 'custom',
|
|
149
|
+
message: `Invalid value for <${name}>. Expected one of: ${param.enumValues.join(', ')}`,
|
|
150
|
+
path: issue.path,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
return issue;
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
function humanizeOptionIssues(issues, optionsSchemas) {
|
|
157
|
+
const metadata = walkSchema(optionsSchemas);
|
|
158
|
+
const metaByName = new Map(metadata.map((m) => [m.name, m]));
|
|
159
|
+
return issues.map((issue) => {
|
|
160
|
+
const name = issue.path[0];
|
|
161
|
+
if (typeof name !== 'string')
|
|
162
|
+
return issue;
|
|
163
|
+
const param = metaByName.get(name);
|
|
164
|
+
// Missing required option
|
|
165
|
+
if (issue.code === 'invalid_type' && issue.message.includes('received undefined')) {
|
|
166
|
+
return {
|
|
167
|
+
code: 'custom',
|
|
168
|
+
message: `Missing required option: --${name}${param?.description ? ` — ${param.description}` : ''}`,
|
|
169
|
+
path: issue.path,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
// Invalid enum value
|
|
173
|
+
if (issue.code === 'invalid_value' && param?.enumValues) {
|
|
174
|
+
return {
|
|
175
|
+
code: 'custom',
|
|
176
|
+
message: `Invalid value for --${name}. Expected one of: ${param.enumValues.join(', ')}`,
|
|
177
|
+
path: issue.path,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
// Wrong type (e.g. expected number, got string)
|
|
181
|
+
if (issue.code === 'invalid_type') {
|
|
182
|
+
const expected = issue.expected;
|
|
183
|
+
return {
|
|
184
|
+
code: 'custom',
|
|
185
|
+
message: `Invalid value for --${name}: expected ${String(expected)}`,
|
|
186
|
+
path: issue.path,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
return issue;
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
// ─── Public API ─────────────────────────────────────────────
|
|
193
|
+
/**
|
|
194
|
+
* Resolve values from all sources and validate through Zod.
|
|
195
|
+
*
|
|
196
|
+
* Pipeline:
|
|
197
|
+
* 1. Map positionals to args by insertion order
|
|
198
|
+
* 2. Merge option values (CLI > env > config)
|
|
199
|
+
* 3. Pre-coerce number strings
|
|
200
|
+
* 4. Validate through Zod schemas
|
|
201
|
+
* 5. Return typed results or throw ValidationError
|
|
202
|
+
*/
|
|
203
|
+
export function resolveValues(input) {
|
|
204
|
+
const { parseArgsResult, longAliasMap = {}, schemas, meta, configValues, env = process.env, } = input;
|
|
205
|
+
// ─── Args resolution ─────────────────────────────────
|
|
206
|
+
let parsedArgs = {};
|
|
207
|
+
if (schemas.args && Object.keys(schemas.args).length > 0) {
|
|
208
|
+
const rawArgs = mapPositionals(parseArgsResult.positionals, schemas.args);
|
|
209
|
+
// Build Zod object schema for args and validate
|
|
210
|
+
const argsZodSchema = z.object(schemas.args);
|
|
211
|
+
try {
|
|
212
|
+
parsedArgs = argsZodSchema.parse(rawArgs);
|
|
213
|
+
}
|
|
214
|
+
catch (err) {
|
|
215
|
+
if (err instanceof ZodError) {
|
|
216
|
+
throw new ValidationError(humanizeArgIssues(err.issues, schemas.args));
|
|
217
|
+
}
|
|
218
|
+
throw err;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
// ─── Options resolution ──────────────────────────────
|
|
222
|
+
let parsedOptions = {};
|
|
223
|
+
if (schemas.options && Object.keys(schemas.options).length > 0) {
|
|
224
|
+
const optionsMetadata = walkSchema(schemas.options);
|
|
225
|
+
const rawOptions = resolveOptionValues(parseArgsResult.values, longAliasMap, schemas.options, meta?.options, configValues, env, optionsMetadata);
|
|
226
|
+
// Build Zod object schema for options and validate
|
|
227
|
+
const optionsZodSchema = z.object(schemas.options);
|
|
228
|
+
try {
|
|
229
|
+
parsedOptions = optionsZodSchema.parse(rawOptions);
|
|
230
|
+
}
|
|
231
|
+
catch (err) {
|
|
232
|
+
if (err instanceof ZodError) {
|
|
233
|
+
throw new ValidationError(humanizeOptionIssues(err.issues, schemas.options));
|
|
234
|
+
}
|
|
235
|
+
throw err;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return { parsedArgs, parsedOptions };
|
|
239
|
+
}
|
|
240
|
+
//# sourceMappingURL=resolve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/parse/resolve.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @runa-cmd/core — Zod Schema Walker
|
|
3
|
+
*
|
|
4
|
+
* Walks Zod schemas to extract parameter metadata (type, default, required,
|
|
5
|
+
* description, enum values, variadic). This is the ONLY module that accesses
|
|
6
|
+
* Zod v4 internal `._zod.def` — if Zod changes internals, only this file
|
|
7
|
+
* needs updating.
|
|
8
|
+
*/
|
|
9
|
+
import type { ZodType } from 'zod';
|
|
10
|
+
import type { ParamMetadata } from '../types.js';
|
|
11
|
+
/**
|
|
12
|
+
* Walk a record of Zod schemas and extract parameter metadata for each key.
|
|
13
|
+
* Keys are returned in insertion order (Object.entries preserves it).
|
|
14
|
+
*/
|
|
15
|
+
export declare function walkSchema(schemas: Record<string, ZodType>): ParamMetadata[];
|
|
16
|
+
/**
|
|
17
|
+
* Walk a single Zod schema and extract its metadata.
|
|
18
|
+
* Used by other modules that need to inspect individual schemas.
|
|
19
|
+
*/
|
|
20
|
+
export declare function walkSingleSchema(name: string, schema: ZodType): ParamMetadata;
|
|
21
|
+
//# sourceMappingURL=schema-walker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-walker.d.ts","sourceRoot":"","sources":["../../src/parse/schema-walker.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AACnC,OAAO,KAAK,EAAE,aAAa,EAAa,MAAM,aAAa,CAAC;AA6I5D;;;GAGG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,aAAa,EAAE,CAmB5E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,aAAa,CAa7E"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
// ─── Helper: access ._zod.def safely ───────────────────────
|
|
2
|
+
function getZodDef(schema) {
|
|
3
|
+
const s = schema;
|
|
4
|
+
if (!s._zod?.def) {
|
|
5
|
+
throw new Error('Cannot introspect Zod schema: ._zod.def is missing. Ensure you are using Zod v4.');
|
|
6
|
+
}
|
|
7
|
+
return s._zod.def;
|
|
8
|
+
}
|
|
9
|
+
function getDescription(schema) {
|
|
10
|
+
const s = schema;
|
|
11
|
+
return s.description;
|
|
12
|
+
}
|
|
13
|
+
function unwrapSchema(schema) {
|
|
14
|
+
let isOptional = false;
|
|
15
|
+
let defaultValue;
|
|
16
|
+
let hasDefault = false;
|
|
17
|
+
let description = getDescription(schema);
|
|
18
|
+
let current = schema;
|
|
19
|
+
// Iteratively unwrap layers
|
|
20
|
+
const maxDepth = 10; // safety limit
|
|
21
|
+
for (let i = 0; i < maxDepth; i++) {
|
|
22
|
+
const def = getZodDef(current);
|
|
23
|
+
if (def.type === 'optional') {
|
|
24
|
+
isOptional = true;
|
|
25
|
+
current = def.innerType;
|
|
26
|
+
if (!description)
|
|
27
|
+
description = getDescription(current);
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
if (def.type === 'default') {
|
|
31
|
+
isOptional = true; // defaults make the field optional from the user's perspective
|
|
32
|
+
hasDefault = true;
|
|
33
|
+
defaultValue = def.defaultValue;
|
|
34
|
+
current = def.innerType;
|
|
35
|
+
if (!description)
|
|
36
|
+
description = getDescription(current);
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
if (def.type === 'nullable') {
|
|
40
|
+
current = def.innerType;
|
|
41
|
+
if (!description)
|
|
42
|
+
description = getDescription(current);
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
// Base type reached
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
// If we found a default via the wrapper, keep it.
|
|
49
|
+
// If not, defaultValue stays undefined.
|
|
50
|
+
return {
|
|
51
|
+
baseSchema: current,
|
|
52
|
+
baseDef: getZodDef(current),
|
|
53
|
+
isOptional,
|
|
54
|
+
defaultValue: hasDefault ? defaultValue : undefined,
|
|
55
|
+
description,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
// ─── Detect base type ───────────────────────────────────────
|
|
59
|
+
function detectParamType(def) {
|
|
60
|
+
switch (def.type) {
|
|
61
|
+
case 'string':
|
|
62
|
+
return { zodType: 'string' };
|
|
63
|
+
case 'number':
|
|
64
|
+
case 'int':
|
|
65
|
+
return { zodType: 'number' };
|
|
66
|
+
case 'boolean':
|
|
67
|
+
return { zodType: 'boolean' };
|
|
68
|
+
case 'enum': {
|
|
69
|
+
// Zod v4 uses `entries` (object { staging: 'staging', prod: 'prod' })
|
|
70
|
+
// not `values` (array). Extract the values from the entries object.
|
|
71
|
+
const entries = def.entries;
|
|
72
|
+
const values = entries ? Object.values(entries) : undefined;
|
|
73
|
+
return { zodType: 'enum', enumValues: values };
|
|
74
|
+
}
|
|
75
|
+
case 'array':
|
|
76
|
+
return { zodType: 'array' };
|
|
77
|
+
default:
|
|
78
|
+
// Fallback: treat unknown types as string
|
|
79
|
+
return { zodType: 'string' };
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// ─── Public API ─────────────────────────────────────────────
|
|
83
|
+
/**
|
|
84
|
+
* Walk a record of Zod schemas and extract parameter metadata for each key.
|
|
85
|
+
* Keys are returned in insertion order (Object.entries preserves it).
|
|
86
|
+
*/
|
|
87
|
+
export function walkSchema(schemas) {
|
|
88
|
+
const result = [];
|
|
89
|
+
for (const [name, schema] of Object.entries(schemas)) {
|
|
90
|
+
const { baseDef, isOptional, defaultValue, description } = unwrapSchema(schema);
|
|
91
|
+
const { zodType, enumValues } = detectParamType(baseDef);
|
|
92
|
+
result.push({
|
|
93
|
+
name,
|
|
94
|
+
zodType,
|
|
95
|
+
isOptional,
|
|
96
|
+
defaultValue,
|
|
97
|
+
isArray: zodType === 'array',
|
|
98
|
+
enumValues,
|
|
99
|
+
description,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
return result;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Walk a single Zod schema and extract its metadata.
|
|
106
|
+
* Used by other modules that need to inspect individual schemas.
|
|
107
|
+
*/
|
|
108
|
+
export function walkSingleSchema(name, schema) {
|
|
109
|
+
const { baseDef, isOptional, defaultValue, description } = unwrapSchema(schema);
|
|
110
|
+
const { zodType, enumValues } = detectParamType(baseDef);
|
|
111
|
+
return {
|
|
112
|
+
name,
|
|
113
|
+
zodType,
|
|
114
|
+
isOptional,
|
|
115
|
+
defaultValue,
|
|
116
|
+
isArray: zodType === 'array',
|
|
117
|
+
enumValues,
|
|
118
|
+
description,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=schema-walker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-walker.js","sourceRoot":"","sources":["../../src/parse/schema-walker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @runa-cmd/core — Variadic arg validation
|
|
3
|
+
*
|
|
4
|
+
* Validates that z.array() positional args appear only as the last arg
|
|
5
|
+
* and that at most one variadic arg exists per command.
|
|
6
|
+
* These checks run at definition time (when defineCommand() is called).
|
|
7
|
+
*/
|
|
8
|
+
import type { ZodType } from 'zod';
|
|
9
|
+
/**
|
|
10
|
+
* Check if a Zod schema is a z.array() type.
|
|
11
|
+
* Unwraps optional/default/nullable wrappers to find the base type.
|
|
12
|
+
*/
|
|
13
|
+
export declare function isVariadic(schema: ZodType): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Validate variadic arg constraints:
|
|
16
|
+
* 1. z.array() is only allowed as the LAST positional arg
|
|
17
|
+
* 2. At most one z.array() per command
|
|
18
|
+
*
|
|
19
|
+
* Throws RunaError at definition time if constraints are violated.
|
|
20
|
+
*/
|
|
21
|
+
export declare function validateVariadicArgs(args: Record<string, ZodType>): void;
|
|
22
|
+
//# sourceMappingURL=variadic.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"variadic.d.ts","sourceRoot":"","sources":["../../src/parse/variadic.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAsBnC;;;GAGG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAyBnD;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAsCxE"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { RunaError } from '../errors.js';
|
|
2
|
+
function getDefType(schema) {
|
|
3
|
+
const s = schema;
|
|
4
|
+
return s._zod?.def?.type ?? 'unknown';
|
|
5
|
+
}
|
|
6
|
+
// ─── Public API ─────────────────────────────────────────────
|
|
7
|
+
/**
|
|
8
|
+
* Check if a Zod schema is a z.array() type.
|
|
9
|
+
* Unwraps optional/default/nullable wrappers to find the base type.
|
|
10
|
+
*/
|
|
11
|
+
export function isVariadic(schema) {
|
|
12
|
+
let current = schema;
|
|
13
|
+
const maxDepth = 10;
|
|
14
|
+
for (let i = 0; i < maxDepth; i++) {
|
|
15
|
+
const defType = getDefType(current);
|
|
16
|
+
if (defType === 'array') {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
// Unwrap wrappers
|
|
20
|
+
if (defType === 'optional' || defType === 'default' || defType === 'nullable') {
|
|
21
|
+
const s = current;
|
|
22
|
+
const inner = s._zod?.def?.innerType;
|
|
23
|
+
if (inner) {
|
|
24
|
+
current = inner;
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Validate variadic arg constraints:
|
|
34
|
+
* 1. z.array() is only allowed as the LAST positional arg
|
|
35
|
+
* 2. At most one z.array() per command
|
|
36
|
+
*
|
|
37
|
+
* Throws RunaError at definition time if constraints are violated.
|
|
38
|
+
*/
|
|
39
|
+
export function validateVariadicArgs(args) {
|
|
40
|
+
const keys = Object.keys(args);
|
|
41
|
+
const arrayIndices = [];
|
|
42
|
+
for (let i = 0; i < keys.length; i++) {
|
|
43
|
+
const key = keys[i];
|
|
44
|
+
if (!key)
|
|
45
|
+
continue;
|
|
46
|
+
const schema = args[key];
|
|
47
|
+
if (schema && isVariadic(schema)) {
|
|
48
|
+
arrayIndices.push({ name: key, index: i });
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// No arrays → valid
|
|
52
|
+
if (arrayIndices.length === 0) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
// Multiple arrays → invalid
|
|
56
|
+
if (arrayIndices.length > 1) {
|
|
57
|
+
const names = arrayIndices.map((a) => `'${a.name}'`).join(', ');
|
|
58
|
+
throw new RunaError(`Only one variadic arg is allowed per command. Found: ${names}.`, {
|
|
59
|
+
code: 'INVALID_VARIADIC_ARGS',
|
|
60
|
+
exitCode: 1,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
// Single array but not in last position → invalid
|
|
64
|
+
const arrayEntry = arrayIndices[0];
|
|
65
|
+
if (arrayEntry && arrayEntry.index !== keys.length - 1) {
|
|
66
|
+
throw new RunaError(`Variadic arg '${arrayEntry.name}' must be the last positional argument. ` +
|
|
67
|
+
`Found at position ${arrayEntry.index} of ${keys.length}.`, { code: 'INVALID_VARIADIC_POSITION', exitCode: 1 });
|
|
68
|
+
}
|
|
69
|
+
// Single array in last position → valid
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=variadic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"variadic.js","sourceRoot":"","sources":["../../src/parse/variadic.ts"],"names":[],"mappings":"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"}
|
package/dist/plugin.d.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @runa-cmd/core — Plugin system
|
|
3
|
+
*
|
|
4
|
+
* definePlugin() — validate and return plugin config
|
|
5
|
+
* Plugin host — resolve lazy imports, topological sort, setup/cleanup orchestration
|
|
6
|
+
* Capability validation via PluginAPI proxy
|
|
7
|
+
*/
|
|
8
|
+
import type { ZodType } from 'zod';
|
|
9
|
+
import type { CLISchema, CommandTree, HookHandler, HookName, Middleware, OptionMeta, PluginAPI, PluginCapabilities, PluginConfig } from './types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Validate and return a PluginConfig.
|
|
12
|
+
* Passthrough with shape validation — ensures required fields exist.
|
|
13
|
+
*/
|
|
14
|
+
export declare function definePlugin(config: PluginConfig): PluginConfig;
|
|
15
|
+
type PluginInput = PluginConfig | (() => Promise<{
|
|
16
|
+
default: PluginConfig;
|
|
17
|
+
}>);
|
|
18
|
+
/**
|
|
19
|
+
* Resolve a list of plugin inputs (direct configs or lazy imports)
|
|
20
|
+
* into resolved PluginConfig objects.
|
|
21
|
+
*/
|
|
22
|
+
export declare function resolvePlugins(plugins: PluginInput[]): Promise<PluginConfig[]>;
|
|
23
|
+
/**
|
|
24
|
+
* Sort plugins in dependency order using Kahn's algorithm.
|
|
25
|
+
* Detects circular dependencies and missing dependencies.
|
|
26
|
+
*/
|
|
27
|
+
export declare function topologicalSort(plugins: PluginConfig[]): PluginConfig[];
|
|
28
|
+
export interface PluginHostRefs {
|
|
29
|
+
commands: CommandTree;
|
|
30
|
+
globalOptions: Record<string, ZodType>;
|
|
31
|
+
globalMeta: {
|
|
32
|
+
options: Record<string, OptionMeta>;
|
|
33
|
+
};
|
|
34
|
+
middleware: Middleware[];
|
|
35
|
+
hookRegister: (name: HookName, handler: HookHandler) => void;
|
|
36
|
+
getSchema: () => CLISchema;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Create a PluginAPI for a specific plugin, enforcing capability checks.
|
|
40
|
+
*/
|
|
41
|
+
export declare function createPluginAPI(pluginName: string, capabilities: PluginCapabilities | undefined, refs: PluginHostRefs): PluginAPI;
|
|
42
|
+
/**
|
|
43
|
+
* Call setup(api) for each plugin in topological order.
|
|
44
|
+
*/
|
|
45
|
+
export declare function runPluginSetup(plugins: PluginConfig[], refs: PluginHostRefs): Promise<void>;
|
|
46
|
+
/**
|
|
47
|
+
* Call cleanup() for each plugin in REVERSE topological order.
|
|
48
|
+
* Each cleanup is wrapped in try/catch — failures don't prevent others from running.
|
|
49
|
+
* Returns collected errors.
|
|
50
|
+
*/
|
|
51
|
+
export declare function runPluginCleanup(plugins: PluginConfig[]): Promise<Error[]>;
|
|
52
|
+
export {};
|
|
53
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAEnC,OAAO,KAAK,EACX,SAAS,EAET,WAAW,EACX,WAAW,EACX,QAAQ,EACR,UAAU,EACV,UAAU,EACV,SAAS,EACT,kBAAkB,EAClB,YAAY,EACZ,MAAM,YAAY,CAAC;AAIpB;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,YAAY,CAc/D;AAID,KAAK,WAAW,GAAG,YAAY,GAAG,CAAC,MAAM,OAAO,CAAC;IAAE,OAAO,EAAE,YAAY,CAAA;CAAE,CAAC,CAAC,CAAC;AAE7E;;;GAGG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CA2BpF;AAID;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,YAAY,EAAE,CAmEvE;AAID,MAAM,WAAW,cAAc;IAC9B,QAAQ,EAAE,WAAW,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,UAAU,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;KAAE,CAAC;IACpD,UAAU,EAAE,UAAU,EAAE,CAAC;IACzB,YAAY,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;IAC7D,SAAS,EAAE,MAAM,SAAS,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC9B,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,kBAAkB,GAAG,SAAS,EAC5C,IAAI,EAAE,cAAc,GAClB,SAAS,CAkDX;AAID;;GAEG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAKjG;AAID;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,CAiBhF"}
|