@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
package/dist/cli.js
ADDED
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @runa-cmd/core — defineCLI() + runCLI()
|
|
3
|
+
*
|
|
4
|
+
* The main CLI orchestrator. Wires together:
|
|
5
|
+
* - Command resolution (including subcommands)
|
|
6
|
+
* - Parsing pipeline (schema-walker → parseArgs-bridge → util.parseArgs → resolve)
|
|
7
|
+
* - Lifecycle hooks (7-hook pipeline)
|
|
8
|
+
* - Plugin loading (topological sort, setup/cleanup)
|
|
9
|
+
* - Middleware execution (Koa/Hono onion model)
|
|
10
|
+
* - Config loading
|
|
11
|
+
* - Error handling
|
|
12
|
+
*/
|
|
13
|
+
import { parseArgs } from 'node:util';
|
|
14
|
+
import { loadAndMergeConfig } from './config/merge.js';
|
|
15
|
+
import { CommandNotFoundError, RunaError } from './errors.js';
|
|
16
|
+
import { getSchema } from './introspect.js';
|
|
17
|
+
import { createHookRegistry } from './lifecycle.js';
|
|
18
|
+
import { buildParseArgsConfig } from './parse/parseargs-bridge.js';
|
|
19
|
+
import { resolveValues } from './parse/resolve.js';
|
|
20
|
+
import { walkSchema } from './parse/schema-walker.js';
|
|
21
|
+
import { resolvePlugins, runPluginCleanup, runPluginSetup, topologicalSort } from './plugin.js';
|
|
22
|
+
/**
|
|
23
|
+
* Check if a value is a Command (branded object).
|
|
24
|
+
*/
|
|
25
|
+
function isCommand(value) {
|
|
26
|
+
return '_type' in value && value._type === 'runa:command';
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Levenshtein distance for "did you mean" suggestions.
|
|
30
|
+
*/
|
|
31
|
+
function levenshtein(a, b) {
|
|
32
|
+
const rows = b.length + 1;
|
|
33
|
+
const cols = a.length + 1;
|
|
34
|
+
// Use a flat array for guaranteed index access without non-null assertions
|
|
35
|
+
const matrix = new Array(rows * cols).fill(0);
|
|
36
|
+
const at = (i, j) => matrix[i * cols + j] ?? 0;
|
|
37
|
+
const set = (i, j, v) => {
|
|
38
|
+
matrix[i * cols + j] = v;
|
|
39
|
+
};
|
|
40
|
+
for (let i = 0; i < rows; i++)
|
|
41
|
+
set(i, 0, i);
|
|
42
|
+
for (let j = 0; j < cols; j++)
|
|
43
|
+
set(0, j, j);
|
|
44
|
+
for (let i = 1; i < rows; i++) {
|
|
45
|
+
for (let j = 1; j < cols; j++) {
|
|
46
|
+
if (b[i - 1] === a[j - 1]) {
|
|
47
|
+
set(i, j, at(i - 1, j - 1));
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
set(i, j, Math.min(at(i - 1, j - 1) + 1, // substitution
|
|
51
|
+
at(i, j - 1) + 1, // insertion
|
|
52
|
+
at(i - 1, j) + 1));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return at(b.length, a.length);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Find the best suggestion for a misspelled command name.
|
|
60
|
+
* Returns undefined if no close match exists (distance > 3).
|
|
61
|
+
*/
|
|
62
|
+
function findSuggestion(input, candidates) {
|
|
63
|
+
let best;
|
|
64
|
+
let bestDist = Infinity;
|
|
65
|
+
for (const candidate of candidates) {
|
|
66
|
+
const dist = levenshtein(input, candidate);
|
|
67
|
+
if (dist < bestDist) {
|
|
68
|
+
bestDist = dist;
|
|
69
|
+
best = candidate;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// Only suggest if reasonably close
|
|
73
|
+
return bestDist <= 3 ? best : undefined;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Resolve a command from the command tree by walking argv tokens.
|
|
77
|
+
* Supports nested subcommands.
|
|
78
|
+
*/
|
|
79
|
+
function resolveCommand(commands, tokens) {
|
|
80
|
+
let current = commands;
|
|
81
|
+
let consumed = 0;
|
|
82
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
83
|
+
const token = tokens[i];
|
|
84
|
+
if (token === undefined)
|
|
85
|
+
break;
|
|
86
|
+
// Stop at flags — they're not command names
|
|
87
|
+
if (token.startsWith('-'))
|
|
88
|
+
break;
|
|
89
|
+
const entry = current[token];
|
|
90
|
+
if (!entry)
|
|
91
|
+
break;
|
|
92
|
+
consumed++;
|
|
93
|
+
if (isCommand(entry)) {
|
|
94
|
+
return {
|
|
95
|
+
command: entry,
|
|
96
|
+
remainingArgv: tokens.slice(consumed),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
// It's a subtree — continue walking
|
|
100
|
+
current = entry;
|
|
101
|
+
}
|
|
102
|
+
// If we're in a subtree and haven't found a command, check for a default/index command
|
|
103
|
+
// For now, throw CommandNotFoundError
|
|
104
|
+
const commandName = tokens[consumed] ?? tokens[consumed - 1] ?? '';
|
|
105
|
+
const candidates = Object.keys(current);
|
|
106
|
+
const suggestion = commandName ? findSuggestion(commandName, candidates) : undefined;
|
|
107
|
+
if (!commandName && consumed === 0) {
|
|
108
|
+
throw new CommandNotFoundError('(no command specified)', undefined);
|
|
109
|
+
}
|
|
110
|
+
throw new CommandNotFoundError(tokens.slice(0, consumed + 1).join(' '), suggestion);
|
|
111
|
+
}
|
|
112
|
+
// ─── Middleware Composition ─────────────────────────────────
|
|
113
|
+
/**
|
|
114
|
+
* Compose middleware into a nested chain.
|
|
115
|
+
* Outermost middleware is first in the array.
|
|
116
|
+
* Innermost next() calls the command execution function.
|
|
117
|
+
*/
|
|
118
|
+
function composeMiddleware(middlewareList, globalOptions, innerFn) {
|
|
119
|
+
// Build the chain from inside out
|
|
120
|
+
let chain = innerFn;
|
|
121
|
+
for (let i = middlewareList.length - 1; i >= 0; i--) {
|
|
122
|
+
const mw = middlewareList[i];
|
|
123
|
+
if (!mw)
|
|
124
|
+
continue;
|
|
125
|
+
const next = chain;
|
|
126
|
+
chain = () => {
|
|
127
|
+
const ctx = {
|
|
128
|
+
next: async () => {
|
|
129
|
+
await next();
|
|
130
|
+
},
|
|
131
|
+
globalOptions,
|
|
132
|
+
};
|
|
133
|
+
return mw.handler(ctx);
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
return chain;
|
|
137
|
+
}
|
|
138
|
+
// ─── CLI Execution Engine ───────────────────────────────────
|
|
139
|
+
/**
|
|
140
|
+
* Run the full CLI lifecycle.
|
|
141
|
+
*/
|
|
142
|
+
async function runCLILifecycle(config, argv) {
|
|
143
|
+
// ─── State ─────────────────────────────────────────
|
|
144
|
+
const hookRegistry = createHookRegistry();
|
|
145
|
+
const mutableCommands = { ...config.commands };
|
|
146
|
+
const mutableGlobalOptions = { ...(config.globalOptions ?? {}) };
|
|
147
|
+
const mutableGlobalMeta = {
|
|
148
|
+
options: { ...(config.globalMeta?.options ?? {}) },
|
|
149
|
+
};
|
|
150
|
+
const mutableMiddleware = [...(config.middleware ?? [])];
|
|
151
|
+
let sortedPlugins = [];
|
|
152
|
+
// Hook context that grows as we progress through the lifecycle
|
|
153
|
+
const hookCtx = {
|
|
154
|
+
cli: config.meta,
|
|
155
|
+
rawArgs: argv,
|
|
156
|
+
};
|
|
157
|
+
let lifecycleError;
|
|
158
|
+
let commandResult;
|
|
159
|
+
try {
|
|
160
|
+
// ─── Plugin resolution ────────────────────────────
|
|
161
|
+
if (config.plugins && config.plugins.length > 0) {
|
|
162
|
+
const resolvedPlugins = await resolvePlugins(config.plugins);
|
|
163
|
+
sortedPlugins = topologicalSort(resolvedPlugins);
|
|
164
|
+
// Create plugin host refs
|
|
165
|
+
const pluginRefs = {
|
|
166
|
+
commands: mutableCommands,
|
|
167
|
+
globalOptions: mutableGlobalOptions,
|
|
168
|
+
globalMeta: mutableGlobalMeta,
|
|
169
|
+
middleware: mutableMiddleware,
|
|
170
|
+
hookRegister: (name, handler) => hookRegistry.register(name, handler),
|
|
171
|
+
getSchema: () => getSchema({ ...config, commands: mutableCommands }, mutableGlobalOptions, mutableGlobalMeta.options),
|
|
172
|
+
};
|
|
173
|
+
await runPluginSetup(sortedPlugins, pluginRefs);
|
|
174
|
+
}
|
|
175
|
+
// ─── beforeParse ──────────────────────────────────
|
|
176
|
+
await hookRegistry.emit('beforeParse', hookCtx);
|
|
177
|
+
// Handlers may have mutated hookCtx.rawArgs
|
|
178
|
+
const currentArgv = hookCtx.rawArgs;
|
|
179
|
+
// ─── Parse global options ─────────────────────────
|
|
180
|
+
let parsedGlobalOptions = {};
|
|
181
|
+
if (Object.keys(mutableGlobalOptions).length > 0) {
|
|
182
|
+
const globalMetadata = walkSchema(mutableGlobalOptions);
|
|
183
|
+
const { parseArgsConfig, longAliasMap } = buildParseArgsConfig(globalMetadata, mutableGlobalMeta.options, true);
|
|
184
|
+
// Build lookup maps for global options:
|
|
185
|
+
// longNames: '--verbose' → 'verbose' (canonical name)
|
|
186
|
+
// shortNames: '-V' → 'verbose' (canonical name)
|
|
187
|
+
// booleanGlobals: set of canonical names that are boolean type
|
|
188
|
+
const longNames = new Map();
|
|
189
|
+
const shortNames = new Map();
|
|
190
|
+
const booleanGlobals = new Set();
|
|
191
|
+
const registeredOptions = parseArgsConfig.options ?? {};
|
|
192
|
+
for (const [name, opt] of Object.entries(registeredOptions)) {
|
|
193
|
+
const canonical = longAliasMap[name] ?? name;
|
|
194
|
+
longNames.set(`--${name}`, canonical);
|
|
195
|
+
// --no-* negation for booleans
|
|
196
|
+
if (opt?.type === 'boolean') {
|
|
197
|
+
booleanGlobals.add(canonical);
|
|
198
|
+
longNames.set(`--no-${name}`, canonical);
|
|
199
|
+
}
|
|
200
|
+
if (opt && 'short' in opt && opt.short) {
|
|
201
|
+
shortNames.set(`-${opt.short}`, canonical);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
// Long aliases
|
|
205
|
+
for (const [alias, canonical] of Object.entries(longAliasMap)) {
|
|
206
|
+
longNames.set(`--${alias}`, canonical);
|
|
207
|
+
}
|
|
208
|
+
// Manual argv split: extract global option tokens, leave the rest
|
|
209
|
+
const globalArgv = [];
|
|
210
|
+
const commandArgv = [];
|
|
211
|
+
let i = 0;
|
|
212
|
+
while (i < currentArgv.length) {
|
|
213
|
+
const token = currentArgv[i] ?? '';
|
|
214
|
+
// Handle --opt=val form
|
|
215
|
+
const eqIdx = token.indexOf('=');
|
|
216
|
+
const tokenKey = eqIdx > 0 ? token.slice(0, eqIdx) : token;
|
|
217
|
+
if (longNames.has(tokenKey) || shortNames.has(tokenKey)) {
|
|
218
|
+
const canonical = longNames.get(tokenKey) ?? shortNames.get(tokenKey) ?? '';
|
|
219
|
+
const isBool = booleanGlobals.has(canonical);
|
|
220
|
+
if (eqIdx > 0) {
|
|
221
|
+
// --opt=val — single token, always extract
|
|
222
|
+
globalArgv.push(token);
|
|
223
|
+
i++;
|
|
224
|
+
}
|
|
225
|
+
else if (isBool) {
|
|
226
|
+
// --verbose or --no-verbose — boolean, no value token
|
|
227
|
+
globalArgv.push(token);
|
|
228
|
+
i++;
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
// --opt val — string option, extract both tokens
|
|
232
|
+
globalArgv.push(token);
|
|
233
|
+
i++;
|
|
234
|
+
if (i < currentArgv.length) {
|
|
235
|
+
globalArgv.push(currentArgv[i] ?? '');
|
|
236
|
+
i++;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
commandArgv.push(token);
|
|
242
|
+
i++;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
// Now parse ONLY the extracted global tokens with parseArgs
|
|
246
|
+
const globalParseResult = parseArgs({
|
|
247
|
+
...parseArgsConfig,
|
|
248
|
+
args: globalArgv,
|
|
249
|
+
});
|
|
250
|
+
const { parsedOptions } = resolveValues({
|
|
251
|
+
parseArgsResult: {
|
|
252
|
+
values: globalParseResult.values,
|
|
253
|
+
positionals: [],
|
|
254
|
+
},
|
|
255
|
+
longAliasMap,
|
|
256
|
+
schemas: { options: mutableGlobalOptions },
|
|
257
|
+
meta: { options: mutableGlobalMeta.options },
|
|
258
|
+
});
|
|
259
|
+
parsedGlobalOptions = parsedOptions;
|
|
260
|
+
// Pass remaining argv (command tokens only) to command parsing
|
|
261
|
+
hookCtx.rawArgs = commandArgv;
|
|
262
|
+
}
|
|
263
|
+
hookCtx.globalOptions = parsedGlobalOptions;
|
|
264
|
+
// ─── onGlobalFlags ────────────────────────────────
|
|
265
|
+
const globalFlagsResult = await hookRegistry.emit('onGlobalFlags', hookCtx);
|
|
266
|
+
if (globalFlagsResult.shortCircuited) {
|
|
267
|
+
// Short-circuit: skip command resolution and execution, go to cleanup
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
// ─── Resolve command ──────────────────────────────
|
|
271
|
+
const commandArgv = hookCtx.rawArgs;
|
|
272
|
+
const { command, remainingArgv } = resolveCommandFromTree(mutableCommands, commandArgv, config);
|
|
273
|
+
hookCtx.command = command.meta;
|
|
274
|
+
// ─── Parse command args + options ──────────────────
|
|
275
|
+
const optionMetadata = command.options ? walkSchema(command.options) : [];
|
|
276
|
+
const { parseArgsConfig, longAliasMap } = buildParseArgsConfig(optionMetadata, command.meta.options, !!command.args);
|
|
277
|
+
const cmdParseResult = parseArgs({
|
|
278
|
+
...parseArgsConfig,
|
|
279
|
+
args: remainingArgv,
|
|
280
|
+
});
|
|
281
|
+
// Load config values if configured
|
|
282
|
+
let configValues;
|
|
283
|
+
if (config.config) {
|
|
284
|
+
configValues = await loadAndMergeConfig(config.config);
|
|
285
|
+
}
|
|
286
|
+
const { parsedArgs, parsedOptions } = resolveValues({
|
|
287
|
+
parseArgsResult: {
|
|
288
|
+
values: cmdParseResult.values,
|
|
289
|
+
positionals: cmdParseResult.positionals,
|
|
290
|
+
},
|
|
291
|
+
longAliasMap,
|
|
292
|
+
schemas: {
|
|
293
|
+
args: command.args,
|
|
294
|
+
options: command.options,
|
|
295
|
+
},
|
|
296
|
+
meta: { options: command.meta.options },
|
|
297
|
+
configValues,
|
|
298
|
+
});
|
|
299
|
+
hookCtx.args = parsedArgs;
|
|
300
|
+
hookCtx.options = parsedOptions;
|
|
301
|
+
// ─── afterParse ───────────────────────────────────
|
|
302
|
+
await hookRegistry.emit('afterParse', hookCtx);
|
|
303
|
+
// ─── beforeRun ────────────────────────────────────
|
|
304
|
+
await hookRegistry.emit('beforeRun', hookCtx);
|
|
305
|
+
// ─── Middleware chain + command execution ──────────
|
|
306
|
+
const runContext = {
|
|
307
|
+
args: parsedArgs,
|
|
308
|
+
options: parsedOptions,
|
|
309
|
+
globalOptions: parsedGlobalOptions,
|
|
310
|
+
command: command.meta,
|
|
311
|
+
rawArgs: argv,
|
|
312
|
+
};
|
|
313
|
+
const innerFn = async () => {
|
|
314
|
+
commandResult = await command.run(runContext);
|
|
315
|
+
// Validate output schema if present
|
|
316
|
+
if (command.output) {
|
|
317
|
+
command.output.parse(commandResult);
|
|
318
|
+
}
|
|
319
|
+
};
|
|
320
|
+
const chain = composeMiddleware(mutableMiddleware, parsedGlobalOptions, innerFn);
|
|
321
|
+
await chain();
|
|
322
|
+
// ─── afterRun ─────────────────────────────────────
|
|
323
|
+
await hookRegistry.emit('afterRun', hookCtx);
|
|
324
|
+
}
|
|
325
|
+
catch (err) {
|
|
326
|
+
lifecycleError = err instanceof Error ? err : new Error(String(err));
|
|
327
|
+
// ─── onError ──────────────────────────────────────
|
|
328
|
+
hookCtx.error = lifecycleError;
|
|
329
|
+
try {
|
|
330
|
+
await hookRegistry.emit('onError', hookCtx);
|
|
331
|
+
}
|
|
332
|
+
catch {
|
|
333
|
+
// onError handler threw — swallow it, cleanup still needs to run
|
|
334
|
+
}
|
|
335
|
+
// If error was not handled, fall back to default behavior
|
|
336
|
+
if (!hookCtx.handled) {
|
|
337
|
+
const exitCode = lifecycleError instanceof RunaError ? lifecycleError.exitCode : 1;
|
|
338
|
+
console.error(lifecycleError.message);
|
|
339
|
+
process.exit(exitCode);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
finally {
|
|
343
|
+
// ─── cleanup (ALWAYS runs) ────────────────────────
|
|
344
|
+
try {
|
|
345
|
+
await hookRegistry.emit('cleanup', hookCtx);
|
|
346
|
+
}
|
|
347
|
+
catch {
|
|
348
|
+
// Cleanup hook errors are swallowed
|
|
349
|
+
}
|
|
350
|
+
// Plugin cleanup in reverse topological order
|
|
351
|
+
if (sortedPlugins.length > 0) {
|
|
352
|
+
const cleanupErrors = await runPluginCleanup(sortedPlugins);
|
|
353
|
+
if (cleanupErrors.length > 0) {
|
|
354
|
+
for (const err of cleanupErrors) {
|
|
355
|
+
console.error(`Plugin cleanup error: ${err.message}`);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Resolve command with single-command mode support.
|
|
363
|
+
* If there's exactly one command, route directly without requiring
|
|
364
|
+
* the command name in argv.
|
|
365
|
+
*/
|
|
366
|
+
function resolveCommandFromTree(commands, argv, _config) {
|
|
367
|
+
const commandEntries = Object.entries(commands);
|
|
368
|
+
// Single-command mode: if exactly one command and first token doesn't match it,
|
|
369
|
+
// route directly to that command
|
|
370
|
+
if (commandEntries.length === 1) {
|
|
371
|
+
const firstEntry = commandEntries[0];
|
|
372
|
+
if (firstEntry) {
|
|
373
|
+
const [name, entry] = firstEntry;
|
|
374
|
+
if (isCommand(entry)) {
|
|
375
|
+
// If argv is empty or first token doesn't match the command name
|
|
376
|
+
if (argv.length === 0 || argv[0] !== name) {
|
|
377
|
+
return { command: entry, remainingArgv: argv };
|
|
378
|
+
}
|
|
379
|
+
// First token matches — consume it
|
|
380
|
+
return { command: entry, remainingArgv: argv.slice(1) };
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
// Multi-command mode: resolve from tree
|
|
385
|
+
return resolveCommand(commands, argv);
|
|
386
|
+
}
|
|
387
|
+
// ─── Public API ─────────────────────────────────────────────
|
|
388
|
+
/**
|
|
389
|
+
* Create a CLI from a configuration.
|
|
390
|
+
* Returns a branded CLI object with a .run() method.
|
|
391
|
+
*/
|
|
392
|
+
export function defineCLI(config) {
|
|
393
|
+
return {
|
|
394
|
+
_type: 'runa:cli',
|
|
395
|
+
config,
|
|
396
|
+
async run(argv) {
|
|
397
|
+
const effectiveArgv = argv ?? process.argv.slice(2);
|
|
398
|
+
await runCLILifecycle(config, effectiveArgv);
|
|
399
|
+
},
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Single-command shorthand.
|
|
404
|
+
* Wraps a command in defineCLI() and runs it.
|
|
405
|
+
*/
|
|
406
|
+
export async function runCLI(command, argv) {
|
|
407
|
+
const cli = defineCLI({
|
|
408
|
+
meta: { name: command.meta.name, description: command.meta.description },
|
|
409
|
+
commands: { [command.meta.name]: command },
|
|
410
|
+
});
|
|
411
|
+
await cli.run(argv);
|
|
412
|
+
}
|
|
413
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEtD,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAoBhG;;GAEG;AACH,SAAS,SAAS,CAAC,KAA4B;IAC9C,OAAO,OAAO,IAAI,KAAK,IAAI,KAAK,CAAC,KAAK,KAAK,cAAc,CAAC;AAC3D,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAAC,CAAS,EAAE,CAAS;IACxC,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IAC1B,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IAE1B,2EAA2E;IAC3E,MAAM,MAAM,GAAG,IAAI,KAAK,CAAS,IAAI,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACtD,MAAM,EAAE,GAAG,CAAC,CAAS,EAAE,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;IAC/D,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,EAAE;QAC/C,MAAM,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC,CAAC;IAEF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE;QAAE,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE;QAAE,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAE5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;YAC/B,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;gBAC3B,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAC7B,CAAC;iBAAM,CAAC;gBACP,GAAG,CACF,CAAC,EACD,CAAC,EACD,IAAI,CAAC,GAAG,CACP,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,eAAe;gBACrC,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,YAAY;gBAC9B,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAChB,CACD,CAAC;YACH,CAAC;QACF,CAAC;IACF,CAAC;IAED,OAAO,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC;AAED;;;GAGG;AACH,SAAS,cAAc,CAAC,KAAa,EAAE,UAAoB;IAC1D,IAAI,IAAwB,CAAC;IAC7B,IAAI,QAAQ,GAAG,QAAQ,CAAC;IAExB,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACpC,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAC3C,IAAI,IAAI,GAAG,QAAQ,EAAE,CAAC;YACrB,QAAQ,GAAG,IAAI,CAAC;YAChB,IAAI,GAAG,SAAS,CAAC;QAClB,CAAC;IACF,CAAC;IAED,mCAAmC;IACnC,OAAO,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;AACzC,CAAC;AAED;;;GAGG;AACH,SAAS,cAAc,CAAC,QAAqB,EAAE,MAAgB;IAC9D,IAAI,OAAO,GAAgB,QAAQ,CAAC;IACpC,IAAI,QAAQ,GAAG,CAAC,CAAC;IAEjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACxB,IAAI,KAAK,KAAK,SAAS;YAAE,MAAM;QAE/B,4CAA4C;QAC5C,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,MAAM;QAEjC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;QAC7B,IAAI,CAAC,KAAK;YAAE,MAAM;QAElB,QAAQ,EAAE,CAAC;QAEX,IAAI,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO;gBACN,OAAO,EAAE,KAAK;gBACd,aAAa,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC;aACrC,CAAC;QACH,CAAC;QAED,oCAAoC;QACpC,OAAO,GAAG,KAAK,CAAC;IACjB,CAAC;IAED,uFAAuF;IACvF,sCAAsC;IAEtC,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACnE,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC,cAAc,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAErF,IAAI,CAAC,WAAW,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,oBAAoB,CAAC,wBAAwB,EAAE,SAAS,CAAC,CAAC;IACrE,CAAC;IAED,MAAM,IAAI,oBAAoB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,UAAU,CAAC,CAAC;AACrF,CAAC;AAED,+DAA+D;AAE/D;;;;GAIG;AACH,SAAS,iBAAiB,CACzB,cAA4B,EAC5B,aAAsC,EACtC,OAA4B;IAE5B,kCAAkC;IAClC,IAAI,KAAK,GAAG,OAAO,CAAC;IAEpB,KAAK,IAAI,CAAC,GAAG,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACrD,MAAM,EAAE,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;QAC7B,IAAI,CAAC,EAAE;YAAE,SAAS;QAClB,MAAM,IAAI,GAAG,KAAK,CAAC;QACnB,KAAK,GAAG,GAAG,EAAE;YACZ,MAAM,GAAG,GAAsB;gBAC9B,IAAI,EAAE,KAAK,IAAI,EAAE;oBAChB,MAAM,IAAI,EAAE,CAAC;gBACd,CAAC;gBACD,aAAa;aACb,CAAC;YACF,OAAO,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACxB,CAAC,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACd,CAAC;AAED,+DAA+D;AAE/D;;GAEG;AACH,KAAK,UAAU,eAAe,CAAC,MAAiB,EAAE,IAAc;IAC/D,sDAAsD;IACtD,MAAM,YAAY,GAAG,kBAAkB,EAAE,CAAC;IAC1C,MAAM,eAAe,GAAgB,EAAE,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;IAC5D,MAAM,oBAAoB,GAA4B,EAAE,GAAG,CAAC,MAAM,CAAC,aAAa,IAAI,EAAE,CAAC,EAAE,CAAC;IAC1F,MAAM,iBAAiB,GAA4C;QAClE,OAAO,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,IAAI,EAAE,CAAC,EAAE;KAClD,CAAC;IACF,MAAM,iBAAiB,GAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,CAAC;IACvE,IAAI,aAAa,GAAmB,EAAE,CAAC;IAEvC,+DAA+D;IAC/D,MAAM,OAAO,GAAgB;QAC5B,GAAG,EAAE,MAAM,CAAC,IAAI;QAChB,OAAO,EAAE,IAAI;KACb,CAAC;IAEF,IAAI,cAAiC,CAAC;IACtC,IAAI,aAAsB,CAAC;IAE3B,IAAI,CAAC;QACJ,qDAAqD;QACrD,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjD,MAAM,eAAe,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAC7D,aAAa,GAAG,eAAe,CAAC,eAAe,CAAC,CAAC;YAEjD,0BAA0B;YAC1B,MAAM,UAAU,GAAmB;gBAClC,QAAQ,EAAE,eAAe;gBACzB,aAAa,EAAE,oBAAoB;gBACnC,UAAU,EAAE,iBAAiB;gBAC7B,UAAU,EAAE,iBAAiB;gBAC7B,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;gBACrE,SAAS,EAAE,GAAG,EAAE,CACf,SAAS,CACR,EAAE,GAAG,MAAM,EAAE,QAAQ,EAAE,eAAe,EAAE,EACxC,oBAAoB,EACpB,iBAAiB,CAAC,OAAO,CACzB;aACF,CAAC;YAEF,MAAM,cAAc,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;QACjD,CAAC;QAED,qDAAqD;QACrD,MAAM,YAAY,CAAC,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;QAChD,4CAA4C;QAC5C,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;QAEpC,qDAAqD;QACrD,IAAI,mBAAmB,GAA4B,EAAE,CAAC;QAEtD,IAAI,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClD,MAAM,cAAc,GAAG,UAAU,CAAC,oBAAoB,CAAC,CAAC;YACxD,MAAM,EAAE,eAAe,EAAE,YAAY,EAAE,GAAG,oBAAoB,CAC7D,cAAc,EACd,iBAAiB,CAAC,OAAO,EACzB,IAAI,CACJ,CAAC;YAEF,wCAAwC;YACxC,sDAAsD;YACtD,gDAAgD;YAChD,+DAA+D;YAC/D,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;YAC5C,MAAM,UAAU,GAAG,IAAI,GAAG,EAAkB,CAAC;YAC7C,MAAM,cAAc,GAAG,IAAI,GAAG,EAAU,CAAC;YAEzC,MAAM,iBAAiB,GAAG,eAAe,CAAC,OAAO,IAAI,EAAE,CAAC;YACxD,KAAK,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,CAAC;gBAC7D,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;gBAC7C,SAAS,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,EAAE,SAAS,CAAC,CAAC;gBACtC,+BAA+B;gBAC/B,IAAI,GAAG,EAAE,IAAI,KAAK,SAAS,EAAE,CAAC;oBAC7B,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;oBAC9B,SAAS,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,EAAE,SAAS,CAAC,CAAC;gBAC1C,CAAC;gBACD,IAAI,GAAG,IAAI,OAAO,IAAI,GAAG,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;oBACxC,UAAU,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,KAAK,EAAE,EAAE,SAAS,CAAC,CAAC;gBAC5C,CAAC;YACF,CAAC;YACD,eAAe;YACf,KAAK,MAAM,CAAC,KAAK,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;gBAC/D,SAAS,CAAC,GAAG,CAAC,KAAK,KAAK,EAAE,EAAE,SAAS,CAAC,CAAC;YACxC,CAAC;YAED,kEAAkE;YAClE,MAAM,UAAU,GAAa,EAAE,CAAC;YAChC,MAAM,WAAW,GAAa,EAAE,CAAC;YACjC,IAAI,CAAC,GAAG,CAAC,CAAC;YAEV,OAAO,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC;gBAC/B,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBAEnC,wBAAwB;gBACxB,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;gBACjC,MAAM,QAAQ,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;gBAE3D,IAAI,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;oBACzD,MAAM,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;oBAC5E,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;oBAE7C,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;wBACf,2CAA2C;wBAC3C,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;wBACvB,CAAC,EAAE,CAAC;oBACL,CAAC;yBAAM,IAAI,MAAM,EAAE,CAAC;wBACnB,sDAAsD;wBACtD,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;wBACvB,CAAC,EAAE,CAAC;oBACL,CAAC;yBAAM,CAAC;wBACP,iDAAiD;wBACjD,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;wBACvB,CAAC,EAAE,CAAC;wBACJ,IAAI,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC;4BAC5B,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;4BACtC,CAAC,EAAE,CAAC;wBACL,CAAC;oBACF,CAAC;gBACF,CAAC;qBAAM,CAAC;oBACP,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;oBACxB,CAAC,EAAE,CAAC;gBACL,CAAC;YACF,CAAC;YAED,4DAA4D;YAC5D,MAAM,iBAAiB,GAAG,SAAS,CAAC;gBACnC,GAAG,eAAe;gBAClB,IAAI,EAAE,UAAU;aAChB,CAAC,CAAC;YAEH,MAAM,EAAE,aAAa,EAAE,GAAG,aAAa,CAAC;gBACvC,eAAe,EAAE;oBAChB,MAAM,EAAE,iBAAiB,CAAC,MAAiC;oBAC3D,WAAW,EAAE,EAAE;iBACf;gBACD,YAAY;gBACZ,OAAO,EAAE,EAAE,OAAO,EAAE,oBAAoB,EAAE;gBAC1C,IAAI,EAAE,EAAE,OAAO,EAAE,iBAAiB,CAAC,OAAO,EAAE;aAC5C,CAAC,CAAC;YACH,mBAAmB,GAAG,aAAa,CAAC;YAEpC,+DAA+D;YAC/D,OAAO,CAAC,OAAO,GAAG,WAAW,CAAC;QAC/B,CAAC;QAED,OAAO,CAAC,aAAa,GAAG,mBAAmB,CAAC;QAE5C,qDAAqD;QACrD,MAAM,iBAAiB,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;QAC5E,IAAI,iBAAiB,CAAC,cAAc,EAAE,CAAC;YACtC,sEAAsE;YACtE,OAAO;QACR,CAAC;QAED,qDAAqD;QACrD,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;QACpC,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,sBAAsB,CAAC,eAAe,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;QAEhG,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;QAE/B,sDAAsD;QACtD,MAAM,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAE1E,MAAM,EAAE,eAAe,EAAE,YAAY,EAAE,GAAG,oBAAoB,CAC7D,cAAc,EACd,OAAO,CAAC,IAAI,CAAC,OAAiD,EAC9D,CAAC,CAAC,OAAO,CAAC,IAAI,CACd,CAAC;QAEF,MAAM,cAAc,GAAG,SAAS,CAAC;YAChC,GAAG,eAAe;YAClB,IAAI,EAAE,aAAa;SACnB,CAAC,CAAC;QAEH,mCAAmC;QACnC,IAAI,YAAiD,CAAC;QACtD,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YACnB,YAAY,GAAG,MAAM,kBAAkB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACxD,CAAC;QAED,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,GAAG,aAAa,CAAC;YACnD,eAAe,EAAE;gBAChB,MAAM,EAAE,cAAc,CAAC,MAAiC;gBACxD,WAAW,EAAE,cAAc,CAAC,WAAW;aACvC;YACD,YAAY;YACZ,OAAO,EAAE;gBACR,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,OAAO,EAAE,OAAO,CAAC,OAAO;aACxB;YACD,IAAI,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,OAAiD,EAAE;YACjF,YAAY;SACZ,CAAC,CAAC;QAEH,OAAO,CAAC,IAAI,GAAG,UAAU,CAAC;QAC1B,OAAO,CAAC,OAAO,GAAG,aAAa,CAAC;QAEhC,qDAAqD;QACrD,MAAM,YAAY,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QAE/C,qDAAqD;QACrD,MAAM,YAAY,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAE9C,sDAAsD;QACtD,MAAM,UAAU,GAAG;YAClB,IAAI,EAAE,UAAU;YAChB,OAAO,EAAE,aAAa;YACtB,aAAa,EAAE,mBAAmB;YAClC,OAAO,EAAE,OAAO,CAAC,IAAI;YACrB,OAAO,EAAE,IAAI;SACb,CAAC;QAEF,MAAM,OAAO,GAAG,KAAK,IAAI,EAAE;YAC1B,aAAa,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAE9C,oCAAoC;YACpC,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;gBACpB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;YACrC,CAAC;QACF,CAAC,CAAC;QAEF,MAAM,KAAK,GAAG,iBAAiB,CAAC,iBAAiB,EAAE,mBAAmB,EAAE,OAAO,CAAC,CAAC;QAEjF,MAAM,KAAK,EAAE,CAAC;QAEd,qDAAqD;QACrD,MAAM,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,cAAc,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAErE,qDAAqD;QACrD,OAAO,CAAC,KAAK,GAAG,cAAc,CAAC;QAE/B,IAAI,CAAC;YACJ,MAAM,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAC7C,CAAC;QAAC,MAAM,CAAC;YACR,iEAAiE;QAClE,CAAC;QAED,0DAA0D;QAC1D,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YACtB,MAAM,QAAQ,GAAG,cAAc,YAAY,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;YACnF,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;YACtC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxB,CAAC;IACF,CAAC;YAAS,CAAC;QACV,qDAAqD;QACrD,IAAI,CAAC;YACJ,MAAM,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAC7C,CAAC;QAAC,MAAM,CAAC;YACR,oCAAoC;QACrC,CAAC;QAED,8CAA8C;QAC9C,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,MAAM,aAAa,GAAG,MAAM,gBAAgB,CAAC,aAAa,CAAC,CAAC;YAC5D,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC9B,KAAK,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;oBACjC,OAAO,CAAC,KAAK,CAAC,yBAAyB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;gBACvD,CAAC;YACF,CAAC;QACF,CAAC;IACF,CAAC;AACF,CAAC;AAED;;;;GAIG;AACH,SAAS,sBAAsB,CAC9B,QAAqB,EACrB,IAAc,EACd,OAAkB;IAElB,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAEhD,gFAAgF;IAChF,iCAAiC;IACjC,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjC,MAAM,UAAU,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;QACrC,IAAI,UAAU,EAAE,CAAC;YAChB,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,UAAU,CAAC;YACjC,IAAI,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;gBACtB,iEAAiE;gBACjE,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;oBAC3C,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;gBAChD,CAAC;gBACD,mCAAmC;gBACnC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YACzD,CAAC;QACF,CAAC;IACF,CAAC;IAED,wCAAwC;IACxC,OAAO,cAAc,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AACvC,CAAC;AAED,+DAA+D;AAE/D;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,MAAiB;IAC1C,OAAO;QACN,KAAK,EAAE,UAAmB;QAC1B,MAAM;QACN,KAAK,CAAC,GAAG,CAAC,IAAe;YACxB,MAAM,aAAa,GAAG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACpD,MAAM,eAAe,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;QAC9C,CAAC;KACD,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,OAAgB,EAAE,IAAe;IAC7D,MAAM,GAAG,GAAG,SAAS,CAAC;QACrB,IAAI,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE;QACxE,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE;KAC1C,CAAC,CAAC;IACH,MAAM,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @runa-cmd/core — defineCommand()
|
|
3
|
+
*
|
|
4
|
+
* Builder function that creates a typed, branded Command object from
|
|
5
|
+
* a CommandConfig. Validates variadic args and meta.options keys at
|
|
6
|
+
* definition time.
|
|
7
|
+
*/
|
|
8
|
+
import type { ZodType } from 'zod';
|
|
9
|
+
import type { Command, CommandConfig } from './types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Create a typed Command from a CommandConfig.
|
|
12
|
+
*
|
|
13
|
+
* Validates at definition time:
|
|
14
|
+
* - Variadic args (z.array()) must be the last positional arg
|
|
15
|
+
* - meta.options keys must be a subset of options keys
|
|
16
|
+
*
|
|
17
|
+
* Returns a branded Command object with full generic inference preserved.
|
|
18
|
+
*/
|
|
19
|
+
export declare function defineCommand<TArgs extends Record<string, ZodType> = Record<string, ZodType>, TOptions extends Record<string, ZodType> = Record<string, ZodType>, TOutput extends ZodType | undefined = undefined>(config: CommandConfig<TArgs, TOptions, TOutput>): Command;
|
|
20
|
+
//# sourceMappingURL=command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAGnC,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAA2B,MAAM,YAAY,CAAC;AA6BlF;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC5B,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/D,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClE,OAAO,SAAS,OAAO,GAAG,SAAS,GAAG,SAAS,EAC9C,MAAM,EAAE,aAAa,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,GAAG,OAAO,CAkB1D"}
|
package/dist/command.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { RunaError } from './errors.js';
|
|
2
|
+
import { validateVariadicArgs } from './parse/variadic.js';
|
|
3
|
+
// ─── Definition-time validation ─────────────────────────────
|
|
4
|
+
/**
|
|
5
|
+
* Validate that keys in meta.options are a subset of the options schema keys.
|
|
6
|
+
* This is a runtime complement to TypeScript's compile-time constraint.
|
|
7
|
+
*/
|
|
8
|
+
function validateMetaOptionsKeys(meta, options) {
|
|
9
|
+
if (!meta.options)
|
|
10
|
+
return;
|
|
11
|
+
const optionKeys = options ? new Set(Object.keys(options)) : new Set();
|
|
12
|
+
for (const key of Object.keys(meta.options)) {
|
|
13
|
+
if (!optionKeys.has(key)) {
|
|
14
|
+
throw new RunaError(`meta.options contains key '${key}' that is not defined in options. ` +
|
|
15
|
+
`Available keys: ${optionKeys.size > 0 ? [...optionKeys].map((k) => `'${k}'`).join(', ') : '(none)'}.`, { code: 'INVALID_META_OPTIONS', exitCode: 1 });
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
// ─── Public API ─────────────────────────────────────────────
|
|
20
|
+
/**
|
|
21
|
+
* Create a typed Command from a CommandConfig.
|
|
22
|
+
*
|
|
23
|
+
* Validates at definition time:
|
|
24
|
+
* - Variadic args (z.array()) must be the last positional arg
|
|
25
|
+
* - meta.options keys must be a subset of options keys
|
|
26
|
+
*
|
|
27
|
+
* Returns a branded Command object with full generic inference preserved.
|
|
28
|
+
*/
|
|
29
|
+
export function defineCommand(config) {
|
|
30
|
+
// Validate variadic args at definition time
|
|
31
|
+
if (config.args) {
|
|
32
|
+
validateVariadicArgs(config.args);
|
|
33
|
+
}
|
|
34
|
+
// Validate meta.options keys match options keys
|
|
35
|
+
validateMetaOptionsKeys(config.meta, config.options);
|
|
36
|
+
// Construct branded Command object
|
|
37
|
+
return {
|
|
38
|
+
_type: 'runa:command',
|
|
39
|
+
meta: config.meta,
|
|
40
|
+
args: config.args,
|
|
41
|
+
options: config.options,
|
|
42
|
+
output: config.output,
|
|
43
|
+
run: config.run,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.js","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAG3D,+DAA+D;AAE/D;;;GAGG;AACH,SAAS,uBAAuB,CAC/B,IAA2B,EAC3B,OAAkB;IAElB,IAAI,CAAC,IAAI,CAAC,OAAO;QAAE,OAAO;IAE1B,MAAM,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAU,CAAC;IAE/E,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7C,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,SAAS,CAClB,8BAA8B,GAAG,oCAAoC;gBACpE,mBAAmB,UAAU,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,EACvG,EAAE,IAAI,EAAE,sBAAsB,EAAE,QAAQ,EAAE,CAAC,EAAE,CAC7C,CAAC;QACH,CAAC;IACF,CAAC;AACF,CAAC;AAED,+DAA+D;AAE/D;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAI3B,MAA+C;IAChD,4CAA4C;IAC5C,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QACjB,oBAAoB,CAAC,MAAM,CAAC,IAA+B,CAAC,CAAC;IAC9D,CAAC;IAED,gDAAgD;IAChD,uBAAuB,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAErD,mCAAmC;IACnC,OAAO;QACN,KAAK,EAAE,cAAuB;QAC9B,IAAI,EAAE,MAAM,CAAC,IAAmB;QAChC,IAAI,EAAE,MAAM,CAAC,IAA2C;QACxD,OAAO,EAAE,MAAM,CAAC,OAA8C;QAC9D,MAAM,EAAE,MAAM,CAAC,MAA6B;QAC5C,GAAG,EAAE,MAAM,CAAC,GAAmC;KAC/C,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ConfigLoader } from '../types.js';
|
|
2
|
+
export type { ConfigLoader } from '../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Built-in JSON config file loader.
|
|
5
|
+
* Reads the file and parses it with JSON.parse().
|
|
6
|
+
* Wraps parse errors with a descriptive message including file path.
|
|
7
|
+
*/
|
|
8
|
+
export declare function jsonLoader(): ConfigLoader;
|
|
9
|
+
//# sourceMappingURL=loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAIhD;;;;GAIG;AACH,wBAAgB,UAAU,IAAI,YAAY,CAsBzC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @runa-cmd/core — Config file loader
|
|
3
|
+
*
|
|
4
|
+
* ConfigLoader interface + built-in JSON loader.
|
|
5
|
+
* Uses node:fs/promises for zero runtime dependencies.
|
|
6
|
+
*/
|
|
7
|
+
import { readFile } from 'node:fs/promises';
|
|
8
|
+
// ─── Public API ─────────────────────────────────────────────
|
|
9
|
+
/**
|
|
10
|
+
* Built-in JSON config file loader.
|
|
11
|
+
* Reads the file and parses it with JSON.parse().
|
|
12
|
+
* Wraps parse errors with a descriptive message including file path.
|
|
13
|
+
*/
|
|
14
|
+
export function jsonLoader() {
|
|
15
|
+
return {
|
|
16
|
+
extensions: ['.json'],
|
|
17
|
+
async load(filePath) {
|
|
18
|
+
let content;
|
|
19
|
+
try {
|
|
20
|
+
content = await readFile(filePath, 'utf-8');
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
throw new Error(`Failed to read config file '${filePath}': ${err instanceof Error ? err.message : String(err)}`);
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
return JSON.parse(content);
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
throw new Error(`Invalid JSON in config file '${filePath}': ${err instanceof Error ? err.message : String(err)}`);
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAM5C,+DAA+D;AAE/D;;;;GAIG;AACH,MAAM,UAAU,UAAU;IACzB,OAAO;QACN,UAAU,EAAE,CAAC,OAAO,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC,QAAgB;YAC1B,IAAI,OAAe,CAAC;YACpB,IAAI,CAAC;gBACJ,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC7C,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACd,MAAM,IAAI,KAAK,CACd,+BAA+B,QAAQ,MAAM,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAC/F,CAAC;YACH,CAAC;YAED,IAAI,CAAC;gBACJ,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAY,CAAC;YACvC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACd,MAAM,IAAI,KAAK,CACd,gCAAgC,QAAQ,MAAM,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAChG,CAAC;YACH,CAAC;QACF,CAAC;KACD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @runa-cmd/core — Config loading orchestration
|
|
3
|
+
*
|
|
4
|
+
* Searches for a config file using registered loaders, loads it,
|
|
5
|
+
* and returns the raw config values. The actual merge priority
|
|
6
|
+
* (CLI > env > config > defaults) is handled in resolve.ts.
|
|
7
|
+
*/
|
|
8
|
+
import type { CLIConfigOptions } from '../types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Load config values from a config file, if found.
|
|
11
|
+
*
|
|
12
|
+
* 1. Combines built-in JSON loader with any additional loaders
|
|
13
|
+
* 2. Searches configured paths for matching config files
|
|
14
|
+
* 3. Loads and returns the parsed config
|
|
15
|
+
* 4. Returns undefined if no config file found
|
|
16
|
+
*/
|
|
17
|
+
export declare function loadAndMergeConfig(configOptions: CLIConfigOptions): Promise<Record<string, unknown> | undefined>;
|
|
18
|
+
//# sourceMappingURL=merge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../src/config/merge.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAMpD;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CACvC,aAAa,EAAE,gBAAgB,GAC7B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,CA0B9C"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsonLoader } from './loader.js';
|
|
2
|
+
import { searchConfig } from './search.js';
|
|
3
|
+
// ─── Public API ─────────────────────────────────────────────
|
|
4
|
+
/**
|
|
5
|
+
* Load config values from a config file, if found.
|
|
6
|
+
*
|
|
7
|
+
* 1. Combines built-in JSON loader with any additional loaders
|
|
8
|
+
* 2. Searches configured paths for matching config files
|
|
9
|
+
* 3. Loads and returns the parsed config
|
|
10
|
+
* 4. Returns undefined if no config file found
|
|
11
|
+
*/
|
|
12
|
+
export async function loadAndMergeConfig(configOptions) {
|
|
13
|
+
// Combine built-in JSON loader with additional loaders
|
|
14
|
+
const builtInLoader = jsonLoader();
|
|
15
|
+
const allLoaders = [builtInLoader, ...(configOptions.loaders ?? [])];
|
|
16
|
+
// Default search paths: current dir, then home dir
|
|
17
|
+
const searchPaths = configOptions.searchPaths ?? ['.', '~'];
|
|
18
|
+
// Search for config file
|
|
19
|
+
const result = await searchConfig(configOptions.name, allLoaders, searchPaths);
|
|
20
|
+
if (!result) {
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
// Load and return config values
|
|
24
|
+
const config = await result.loader.load(result.filePath);
|
|
25
|
+
// Config files should return plain objects
|
|
26
|
+
if (config === null || typeof config !== 'object' || Array.isArray(config)) {
|
|
27
|
+
throw new Error(`Config file '${result.filePath}' must export a plain object, got ${Array.isArray(config) ? 'array' : typeof config}.`);
|
|
28
|
+
}
|
|
29
|
+
return config;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=merge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge.js","sourceRoot":"","sources":["../../src/config/merge.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,+DAA+D;AAE/D;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACvC,aAA+B;IAE/B,uDAAuD;IACvD,MAAM,aAAa,GAAG,UAAU,EAAE,CAAC;IACnC,MAAM,UAAU,GAAG,CAAC,aAAa,EAAE,GAAG,CAAC,aAAa,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC;IAErE,mDAAmD;IACnD,MAAM,WAAW,GAAG,aAAa,CAAC,WAAW,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAE5D,yBAAyB;IACzB,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,aAAa,CAAC,IAAI,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;IAE/E,IAAI,CAAC,MAAM,EAAE,CAAC;QACb,OAAO,SAAS,CAAC;IAClB,CAAC;IAED,gCAAgC;IAChC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAEzD,2CAA2C;IAC3C,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5E,MAAM,IAAI,KAAK,CACd,gBAAgB,MAAM,CAAC,QAAQ,qCAAqC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,MAAM,GAAG,CACtH,CAAC;IACH,CAAC;IAED,OAAO,MAAiC,CAAC;AAC1C,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ConfigLoader } from '../types.js';
|
|
2
|
+
export interface SearchResult {
|
|
3
|
+
filePath: string;
|
|
4
|
+
loader: ConfigLoader;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Search for a config file in the given paths.
|
|
8
|
+
*
|
|
9
|
+
* For each search path, for each loader, checks if
|
|
10
|
+
* `{path}/{name}.config{ext}` exists.
|
|
11
|
+
*
|
|
12
|
+
* Search paths are checked in order; first match wins.
|
|
13
|
+
* '~' is resolved to os.homedir().
|
|
14
|
+
*
|
|
15
|
+
* Returns null if no config file is found (not an error).
|
|
16
|
+
*/
|
|
17
|
+
export declare function searchConfig(name: string, loaders: ConfigLoader[], searchPaths: string[]): Promise<SearchResult | null>;
|
|
18
|
+
//# sourceMappingURL=search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/config/search.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAIhD,MAAM,WAAW,YAAY;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,YAAY,CAAC;CACrB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,YAAY,CACjC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,YAAY,EAAE,EACvB,WAAW,EAAE,MAAM,EAAE,GACnB,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAmB9B"}
|