@rune-cli/rune 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +43 -27
- package/dist/dist-Bcn0FpHi.mjs +400 -0
- package/dist/index-BF5_G9J2.d.mts +286 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +1 -1
- package/dist/runtime.d.mts +1 -1
- package/dist/runtime.mjs +1 -1
- package/dist/test.d.mts +1 -1
- package/dist/test.mjs +1 -1
- package/dist/{write-result-C0wgFsjj.mjs → write-result-qylmqXvG.mjs} +1 -1
- package/package.json +4 -5
package/dist/cli.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { i as successResult, n as runManifestCommand, r as failureResult, t as writeCommandExecutionResult } from "./write-result-
|
|
2
|
+
import { i as successResult, n as runManifestCommand, r as failureResult, t as writeCommandExecutionResult } from "./write-result-qylmqXvG.mjs";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
import { build } from "esbuild";
|
|
5
5
|
import { cp, mkdir, readFile, readdir, rm, stat, writeFile } from "node:fs/promises";
|
|
@@ -313,6 +313,21 @@ async function writeBuiltRuntimeFiles(distDirectory, manifest) {
|
|
|
313
313
|
await mkdir(distDirectory, { recursive: true });
|
|
314
314
|
await writeFile(path.join(distDirectory, BUILD_MANIFEST_FILENAME), serializeCommandManifest(manifest));
|
|
315
315
|
}
|
|
316
|
+
function renderRuneBuildHelp() {
|
|
317
|
+
return `\
|
|
318
|
+
Build a Rune project into a distributable CLI.
|
|
319
|
+
|
|
320
|
+
Usage: rune build [options]
|
|
321
|
+
|
|
322
|
+
Options:
|
|
323
|
+
--project <path> Path to the Rune project root (default: current directory)
|
|
324
|
+
-h, --help Show this help message
|
|
325
|
+
|
|
326
|
+
Examples:
|
|
327
|
+
rune build
|
|
328
|
+
rune build --project ./my-app
|
|
329
|
+
`;
|
|
330
|
+
}
|
|
316
331
|
async function runBuildCommand(options) {
|
|
317
332
|
let projectRoot = "";
|
|
318
333
|
try {
|
|
@@ -340,14 +355,6 @@ async function runBuildCommand(options) {
|
|
|
340
355
|
return failureResult(error instanceof Error ? error.message : "Failed to run rune build");
|
|
341
356
|
}
|
|
342
357
|
}
|
|
343
|
-
function renderRuneBuildHelp() {
|
|
344
|
-
return [
|
|
345
|
-
"Usage: rune build [--project <path>]",
|
|
346
|
-
"",
|
|
347
|
-
"Build a Rune project into a distributable CLI.",
|
|
348
|
-
""
|
|
349
|
-
].join("\n");
|
|
350
|
-
}
|
|
351
358
|
//#endregion
|
|
352
359
|
//#region src/cli/dev-command.ts
|
|
353
360
|
const DEV_MANIFEST_DIRECTORY_PATH = ".rune";
|
|
@@ -358,6 +365,21 @@ async function writeDevManifest(projectRoot, manifestContents) {
|
|
|
358
365
|
await mkdir(manifestDirectory, { recursive: true });
|
|
359
366
|
await writeFile(manifestPath, manifestContents);
|
|
360
367
|
}
|
|
368
|
+
function renderRuneDevHelp() {
|
|
369
|
+
return `\
|
|
370
|
+
Run a Rune project in development mode.
|
|
371
|
+
|
|
372
|
+
Usage: rune dev [options] [command...]
|
|
373
|
+
|
|
374
|
+
Options:
|
|
375
|
+
--project <path> Path to the Rune project root (default: current directory)
|
|
376
|
+
-h, --help Show this help message
|
|
377
|
+
|
|
378
|
+
Examples:
|
|
379
|
+
rune dev hello
|
|
380
|
+
rune dev --project ./my-app hello
|
|
381
|
+
`;
|
|
382
|
+
}
|
|
361
383
|
async function runDevCommand(options) {
|
|
362
384
|
try {
|
|
363
385
|
const projectRoot = resolveProjectPath(options);
|
|
@@ -375,24 +397,6 @@ async function runDevCommand(options) {
|
|
|
375
397
|
return failureResult(error instanceof Error ? error.message : "Failed to run rune dev");
|
|
376
398
|
}
|
|
377
399
|
}
|
|
378
|
-
function renderRuneDevHelp() {
|
|
379
|
-
return [
|
|
380
|
-
"Usage: rune dev [--project <path>] [--] [command...]",
|
|
381
|
-
"",
|
|
382
|
-
"Run a Rune project in development mode.",
|
|
383
|
-
""
|
|
384
|
-
].join("\n");
|
|
385
|
-
}
|
|
386
|
-
function renderRuneCliHelp() {
|
|
387
|
-
return [
|
|
388
|
-
"Usage: rune <command>",
|
|
389
|
-
"",
|
|
390
|
-
"Commands:",
|
|
391
|
-
" build Build a Rune project into a distributable CLI",
|
|
392
|
-
" dev Run a Rune project in development mode",
|
|
393
|
-
""
|
|
394
|
-
].join("\n");
|
|
395
|
-
}
|
|
396
400
|
//#endregion
|
|
397
401
|
//#region src/cli/rune-cli.ts
|
|
398
402
|
function tryParseProjectOption(argv, index) {
|
|
@@ -460,6 +464,18 @@ function parseBuildArgs(argv) {
|
|
|
460
464
|
}
|
|
461
465
|
return { projectPath };
|
|
462
466
|
}
|
|
467
|
+
function renderRuneCliHelp() {
|
|
468
|
+
return `\
|
|
469
|
+
Usage: rune <command>
|
|
470
|
+
|
|
471
|
+
Commands:
|
|
472
|
+
build Build a Rune project into a distributable CLI
|
|
473
|
+
dev Run a Rune project in development mode
|
|
474
|
+
|
|
475
|
+
Options:
|
|
476
|
+
-h, --help Show this help message
|
|
477
|
+
`;
|
|
478
|
+
}
|
|
463
479
|
async function runRuneCli(options) {
|
|
464
480
|
const [subcommand, ...restArgs] = options.argv;
|
|
465
481
|
if (!subcommand || isHelpFlag(subcommand)) return successResult(renderRuneCliHelp());
|
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
import { format, parseArgs } from "node:util";
|
|
2
|
+
//#region ../core/dist/index.mjs
|
|
3
|
+
function isSchemaField(field) {
|
|
4
|
+
return "schema" in field && field.schema !== void 0;
|
|
5
|
+
}
|
|
6
|
+
const EMPTY_FIELDS = [];
|
|
7
|
+
function isOptionalArg(field) {
|
|
8
|
+
if (isSchemaField(field)) return;
|
|
9
|
+
return field.required !== true || field.default !== void 0;
|
|
10
|
+
}
|
|
11
|
+
function validateArgOrdering(args) {
|
|
12
|
+
let firstOptionalName;
|
|
13
|
+
for (const field of args) {
|
|
14
|
+
const optional = isOptionalArg(field);
|
|
15
|
+
if (optional === void 0) continue;
|
|
16
|
+
if (optional) firstOptionalName ??= field.name;
|
|
17
|
+
else if (firstOptionalName !== void 0) throw new Error(`Required argument "${field.name}" cannot follow optional argument "${firstOptionalName}"`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Defines a CLI command with a description, positional arguments, options,
|
|
22
|
+
* and a function to execute when the command is invoked.
|
|
23
|
+
*
|
|
24
|
+
* The command module's default export should be the return value of this function.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* export default defineCommand({
|
|
29
|
+
* description: "Greet someone",
|
|
30
|
+
* args: [
|
|
31
|
+
* { name: "name", type: "string", required: true },
|
|
32
|
+
* ],
|
|
33
|
+
* options: [
|
|
34
|
+
* { name: "loud", type: "boolean", alias: "l" },
|
|
35
|
+
* ],
|
|
36
|
+
* run(ctx) {
|
|
37
|
+
* const greeting = `Hello, ${ctx.args.name}!`;
|
|
38
|
+
* console.log(ctx.options.loud ? greeting.toUpperCase() : greeting);
|
|
39
|
+
* },
|
|
40
|
+
* });
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* Required positional arguments must precede optional ones. This ordering is
|
|
44
|
+
* enforced at the type level for concrete schema types and at runtime for
|
|
45
|
+
* primitive fields:
|
|
46
|
+
*
|
|
47
|
+
* ```ts
|
|
48
|
+
* // Type error — required arg after optional arg
|
|
49
|
+
* defineCommand({
|
|
50
|
+
* args: [
|
|
51
|
+
* { name: "source", type: "string" },
|
|
52
|
+
* { name: "target", type: "string", required: true },
|
|
53
|
+
* ],
|
|
54
|
+
* run() {},
|
|
55
|
+
* });
|
|
56
|
+
*
|
|
57
|
+
* // Type error — required primitive arg after optional schema arg
|
|
58
|
+
* defineCommand({
|
|
59
|
+
* args: [
|
|
60
|
+
* { name: "mode", schema: z.string().optional() },
|
|
61
|
+
* { name: "target", type: "string", required: true },
|
|
62
|
+
* ],
|
|
63
|
+
* run() {},
|
|
64
|
+
* });
|
|
65
|
+
* ```
|
|
66
|
+
*
|
|
67
|
+
* When a schema type is widened to plain `StandardSchemaV1` (e.g. stored in
|
|
68
|
+
* a variable without a concrete type), optionality information is lost and
|
|
69
|
+
* the ordering check is skipped for that field.
|
|
70
|
+
*/
|
|
71
|
+
function defineCommand(input) {
|
|
72
|
+
if (input.args) validateArgOrdering(input.args);
|
|
73
|
+
return {
|
|
74
|
+
description: input.description,
|
|
75
|
+
args: input.args ?? EMPTY_FIELDS,
|
|
76
|
+
options: input.options ?? EMPTY_FIELDS,
|
|
77
|
+
run: input.run
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function formatExecutionError(error) {
|
|
81
|
+
if (error instanceof Error) return error.message === "" ? "" : error.message || error.name || "Unknown error";
|
|
82
|
+
if (typeof error === "string") return error;
|
|
83
|
+
return "Unknown error";
|
|
84
|
+
}
|
|
85
|
+
async function captureProcessOutput(action) {
|
|
86
|
+
const stdoutChunks = [];
|
|
87
|
+
const stderrChunks = [];
|
|
88
|
+
const originalStdoutWrite = process.stdout.write.bind(process.stdout);
|
|
89
|
+
const originalStderrWrite = process.stderr.write.bind(process.stderr);
|
|
90
|
+
const originalConsoleMethods = {
|
|
91
|
+
log: console.log,
|
|
92
|
+
info: console.info,
|
|
93
|
+
debug: console.debug,
|
|
94
|
+
warn: console.warn,
|
|
95
|
+
error: console.error
|
|
96
|
+
};
|
|
97
|
+
const captureChunk = (chunks, chunk, encoding) => {
|
|
98
|
+
if (typeof chunk === "string") {
|
|
99
|
+
chunks.push(chunk);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
chunks.push(Buffer.from(chunk).toString(encoding));
|
|
103
|
+
};
|
|
104
|
+
const captureConsole = (chunks, args) => {
|
|
105
|
+
chunks.push(`${format(...args)}\n`);
|
|
106
|
+
};
|
|
107
|
+
const createWriteCapture = (chunks) => ((chunk, encoding, cb) => {
|
|
108
|
+
captureChunk(chunks, chunk, typeof encoding === "string" ? encoding : void 0);
|
|
109
|
+
if (typeof encoding === "function") encoding(null);
|
|
110
|
+
else cb?.(null);
|
|
111
|
+
return true;
|
|
112
|
+
});
|
|
113
|
+
process.stdout.write = createWriteCapture(stdoutChunks);
|
|
114
|
+
process.stderr.write = createWriteCapture(stderrChunks);
|
|
115
|
+
for (const method of [
|
|
116
|
+
"log",
|
|
117
|
+
"info",
|
|
118
|
+
"debug"
|
|
119
|
+
]) console[method] = (...args) => captureConsole(stdoutChunks, args);
|
|
120
|
+
for (const method of ["warn", "error"]) console[method] = (...args) => captureConsole(stderrChunks, args);
|
|
121
|
+
try {
|
|
122
|
+
const value = await action();
|
|
123
|
+
return {
|
|
124
|
+
stdout: stdoutChunks.join(""),
|
|
125
|
+
stderr: stderrChunks.join(""),
|
|
126
|
+
value
|
|
127
|
+
};
|
|
128
|
+
} catch (error) {
|
|
129
|
+
return {
|
|
130
|
+
stdout: stdoutChunks.join(""),
|
|
131
|
+
stderr: stderrChunks.join(""),
|
|
132
|
+
error
|
|
133
|
+
};
|
|
134
|
+
} finally {
|
|
135
|
+
process.stdout.write = originalStdoutWrite;
|
|
136
|
+
process.stderr.write = originalStderrWrite;
|
|
137
|
+
Object.assign(console, originalConsoleMethods);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
const EMPTY_ARGS = [];
|
|
141
|
+
async function executeCommand(command, input = {}) {
|
|
142
|
+
const result = await captureProcessOutput(async () => {
|
|
143
|
+
await command.run({
|
|
144
|
+
options: input.options ?? {},
|
|
145
|
+
args: input.args ?? {},
|
|
146
|
+
cwd: input.cwd ?? process.cwd(),
|
|
147
|
+
rawArgs: input.rawArgs ?? EMPTY_ARGS
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
if (result.error === void 0) return {
|
|
151
|
+
exitCode: 0,
|
|
152
|
+
stdout: result.stdout,
|
|
153
|
+
stderr: result.stderr
|
|
154
|
+
};
|
|
155
|
+
const message = formatExecutionError(result.error);
|
|
156
|
+
return {
|
|
157
|
+
exitCode: 1,
|
|
158
|
+
stdout: result.stdout,
|
|
159
|
+
stderr: `${result.stderr}${message ? `${message}\n` : ""}`
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
function formatFieldTypeHint(field) {
|
|
163
|
+
if (isSchemaField(field)) return "";
|
|
164
|
+
return ` <${field.type}>`;
|
|
165
|
+
}
|
|
166
|
+
function formatOptionLabel(field) {
|
|
167
|
+
return `--${field.name}${formatFieldTypeHint(field)}`;
|
|
168
|
+
}
|
|
169
|
+
function formatArgumentLabel(field) {
|
|
170
|
+
return field.name;
|
|
171
|
+
}
|
|
172
|
+
function missingRequiredOption(field) {
|
|
173
|
+
return {
|
|
174
|
+
ok: false,
|
|
175
|
+
error: { message: `Missing required option:\n\n ${formatOptionLabel(field)}` }
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
function missingRequiredArgument(field) {
|
|
179
|
+
return {
|
|
180
|
+
ok: false,
|
|
181
|
+
error: { message: `Missing required argument:\n\n ${formatArgumentLabel(field)}` }
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
function invalidOptionValue(field, messages) {
|
|
185
|
+
return {
|
|
186
|
+
ok: false,
|
|
187
|
+
error: { message: `Invalid value for option ${formatOptionLabel(field)}:\n\n ${messages.join("\n ")}` }
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
function invalidArgumentValue(field, messages) {
|
|
191
|
+
return {
|
|
192
|
+
ok: false,
|
|
193
|
+
error: { message: `Invalid value for argument ${formatArgumentLabel(field)}:\n\n ${messages.join("\n ")}` }
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
function unknownOption(token) {
|
|
197
|
+
return {
|
|
198
|
+
ok: false,
|
|
199
|
+
error: { message: `Unknown option "${token}"` }
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
function duplicateOption(field) {
|
|
203
|
+
return {
|
|
204
|
+
ok: false,
|
|
205
|
+
error: { message: `Duplicate option "${formatOptionLabel(field)}" is not supported` }
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
function unexpectedArgument(token) {
|
|
209
|
+
return {
|
|
210
|
+
ok: false,
|
|
211
|
+
error: { message: `Unexpected argument "${token}"` }
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
function normalizeParseArgsError(error) {
|
|
215
|
+
if (!(error instanceof Error)) return {
|
|
216
|
+
ok: false,
|
|
217
|
+
error: { message: "Argument parsing failed" }
|
|
218
|
+
};
|
|
219
|
+
const unknownMatch = error.message.match(/Unknown option '([^']+)'/);
|
|
220
|
+
if (unknownMatch) return unknownOption(unknownMatch[1]);
|
|
221
|
+
return {
|
|
222
|
+
ok: false,
|
|
223
|
+
error: { message: error.message }
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
function parsePrimitiveValue(field, rawValue) {
|
|
227
|
+
if (isSchemaField(field)) throw new Error("Schema fields must be handled separately");
|
|
228
|
+
switch (field.type) {
|
|
229
|
+
case "string": return {
|
|
230
|
+
ok: true,
|
|
231
|
+
value: String(rawValue)
|
|
232
|
+
};
|
|
233
|
+
case "number": {
|
|
234
|
+
if (typeof rawValue !== "string") return {
|
|
235
|
+
ok: false,
|
|
236
|
+
error: { message: `Expected number, received ${JSON.stringify(rawValue)}` }
|
|
237
|
+
};
|
|
238
|
+
const value = Number(rawValue);
|
|
239
|
+
if (!Number.isFinite(value)) return {
|
|
240
|
+
ok: false,
|
|
241
|
+
error: { message: `Expected number, received ${JSON.stringify(rawValue)}` }
|
|
242
|
+
};
|
|
243
|
+
return {
|
|
244
|
+
ok: true,
|
|
245
|
+
value
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
case "boolean":
|
|
249
|
+
if (typeof rawValue === "boolean") return {
|
|
250
|
+
ok: true,
|
|
251
|
+
value: rawValue
|
|
252
|
+
};
|
|
253
|
+
if (rawValue === "true") return {
|
|
254
|
+
ok: true,
|
|
255
|
+
value: true
|
|
256
|
+
};
|
|
257
|
+
if (rawValue === "false") return {
|
|
258
|
+
ok: true,
|
|
259
|
+
value: false
|
|
260
|
+
};
|
|
261
|
+
return {
|
|
262
|
+
ok: false,
|
|
263
|
+
error: { message: `Expected boolean, received ${JSON.stringify(rawValue)}` }
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
async function validateSchemaValue(schema, rawValue) {
|
|
268
|
+
const result = await schema["~standard"].validate(rawValue);
|
|
269
|
+
if ("value" in result) return {
|
|
270
|
+
ok: true,
|
|
271
|
+
value: result.value
|
|
272
|
+
};
|
|
273
|
+
if (result.issues?.length) return {
|
|
274
|
+
ok: false,
|
|
275
|
+
error: { message: result.issues.map((issue) => issue.message).join("\n") }
|
|
276
|
+
};
|
|
277
|
+
return {
|
|
278
|
+
ok: false,
|
|
279
|
+
error: { message: "Schema validation failed" }
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
async function parseProvidedField(field, rawValue) {
|
|
283
|
+
if (isSchemaField(field)) return validateSchemaValue(field.schema, rawValue);
|
|
284
|
+
return parsePrimitiveValue(field, rawValue);
|
|
285
|
+
}
|
|
286
|
+
async function resolveMissingField(field, missingRequired) {
|
|
287
|
+
if (!isSchemaField(field)) {
|
|
288
|
+
if (field.default !== void 0) return {
|
|
289
|
+
ok: true,
|
|
290
|
+
present: true,
|
|
291
|
+
value: field.default
|
|
292
|
+
};
|
|
293
|
+
if (field.required) return missingRequired();
|
|
294
|
+
return {
|
|
295
|
+
ok: true,
|
|
296
|
+
present: false
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
const omittedResult = await validateSchemaValue(field.schema, void 0);
|
|
300
|
+
if (!omittedResult.ok) return missingRequired();
|
|
301
|
+
if (omittedResult.value === void 0) return {
|
|
302
|
+
ok: true,
|
|
303
|
+
present: false
|
|
304
|
+
};
|
|
305
|
+
return {
|
|
306
|
+
ok: true,
|
|
307
|
+
present: true,
|
|
308
|
+
value: omittedResult.value
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
async function parseArgumentField(field, rawValue) {
|
|
312
|
+
if (rawValue === void 0) return resolveMissingField(field, () => missingRequiredArgument(field));
|
|
313
|
+
const result = await parseProvidedField(field, rawValue);
|
|
314
|
+
if (!result.ok) return invalidArgumentValue(field, result.error.message.split("\n"));
|
|
315
|
+
return {
|
|
316
|
+
ok: true,
|
|
317
|
+
present: true,
|
|
318
|
+
value: result.value
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
async function parseOptionField(field, rawValue) {
|
|
322
|
+
const result = await parseProvidedField(field, rawValue);
|
|
323
|
+
if (!result.ok) return invalidOptionValue(field, result.error.message.split("\n"));
|
|
324
|
+
return {
|
|
325
|
+
ok: true,
|
|
326
|
+
present: true,
|
|
327
|
+
value: result.value
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
function getOptionParseType(field) {
|
|
331
|
+
if (isSchemaField(field)) return field.flag ? "boolean" : "string";
|
|
332
|
+
return field.type === "boolean" ? "boolean" : "string";
|
|
333
|
+
}
|
|
334
|
+
function buildParseArgsOptions(options) {
|
|
335
|
+
const config = {};
|
|
336
|
+
for (const field of options) config[field.name] = field.alias ? {
|
|
337
|
+
type: getOptionParseType(field),
|
|
338
|
+
short: field.alias
|
|
339
|
+
} : { type: getOptionParseType(field) };
|
|
340
|
+
return config;
|
|
341
|
+
}
|
|
342
|
+
function detectDuplicateOption(options, tokens) {
|
|
343
|
+
const counts = /* @__PURE__ */ new Map();
|
|
344
|
+
for (const token of tokens) {
|
|
345
|
+
if (token.kind !== "option" || !token.name) continue;
|
|
346
|
+
const nextCount = (counts.get(token.name) ?? 0) + 1;
|
|
347
|
+
counts.set(token.name, nextCount);
|
|
348
|
+
if (nextCount > 1) {
|
|
349
|
+
const field = options.find((option) => option.name === token.name);
|
|
350
|
+
if (field) return duplicateOption(field);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
async function parseCommand(command, rawArgs) {
|
|
355
|
+
let parsed;
|
|
356
|
+
try {
|
|
357
|
+
parsed = parseArgs({
|
|
358
|
+
args: [...rawArgs],
|
|
359
|
+
allowPositionals: true,
|
|
360
|
+
strict: true,
|
|
361
|
+
tokens: true,
|
|
362
|
+
options: buildParseArgsOptions(command.options)
|
|
363
|
+
});
|
|
364
|
+
} catch (error) {
|
|
365
|
+
return normalizeParseArgsError(error);
|
|
366
|
+
}
|
|
367
|
+
const duplicateError = detectDuplicateOption(command.options, parsed.tokens);
|
|
368
|
+
if (duplicateError) return duplicateError;
|
|
369
|
+
const parsedArgs = {};
|
|
370
|
+
const parsedOptions = {};
|
|
371
|
+
for (let index = 0; index < command.args.length; index += 1) {
|
|
372
|
+
const field = command.args[index];
|
|
373
|
+
const result = await parseArgumentField(field, parsed.positionals[index]);
|
|
374
|
+
if (!result.ok) return result;
|
|
375
|
+
if (result.present) parsedArgs[field.name] = result.value;
|
|
376
|
+
}
|
|
377
|
+
if (parsed.positionals.length > command.args.length) return unexpectedArgument(parsed.positionals[command.args.length]);
|
|
378
|
+
for (const field of command.options) {
|
|
379
|
+
const rawValue = parsed.values[field.name];
|
|
380
|
+
if (rawValue !== void 0) {
|
|
381
|
+
const result = await parseOptionField(field, rawValue);
|
|
382
|
+
if (!result.ok) return result;
|
|
383
|
+
if (result.present) parsedOptions[field.name] = result.value;
|
|
384
|
+
continue;
|
|
385
|
+
}
|
|
386
|
+
const result = await resolveMissingField(field, () => missingRequiredOption(field));
|
|
387
|
+
if (!result.ok) return result;
|
|
388
|
+
if (result.present) parsedOptions[field.name] = result.value;
|
|
389
|
+
}
|
|
390
|
+
return {
|
|
391
|
+
ok: true,
|
|
392
|
+
value: {
|
|
393
|
+
options: parsedOptions,
|
|
394
|
+
args: parsedArgs,
|
|
395
|
+
rawArgs
|
|
396
|
+
}
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
//#endregion
|
|
400
|
+
export { parseCommand as a, isSchemaField as i, executeCommand as n, formatFieldTypeHint as r, defineCommand as t };
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
//#region ../core/dist/index.d.mts
|
|
2
|
+
//#region ../../node_modules/.pnpm/@standard-schema+spec@1.1.0/node_modules/@standard-schema/spec/dist/index.d.ts
|
|
3
|
+
/** The Standard Typed interface. This is a base type extended by other specs. */
|
|
4
|
+
interface StandardTypedV1<Input = unknown, Output = Input> {
|
|
5
|
+
/** The Standard properties. */
|
|
6
|
+
readonly "~standard": StandardTypedV1.Props<Input, Output>;
|
|
7
|
+
}
|
|
8
|
+
declare namespace StandardTypedV1 {
|
|
9
|
+
/** The Standard Typed properties interface. */
|
|
10
|
+
interface Props<Input = unknown, Output = Input> {
|
|
11
|
+
/** The version number of the standard. */
|
|
12
|
+
readonly version: 1;
|
|
13
|
+
/** The vendor name of the schema library. */
|
|
14
|
+
readonly vendor: string;
|
|
15
|
+
/** Inferred types associated with the schema. */
|
|
16
|
+
readonly types?: Types<Input, Output> | undefined;
|
|
17
|
+
}
|
|
18
|
+
/** The Standard Typed types interface. */
|
|
19
|
+
interface Types<Input = unknown, Output = Input> {
|
|
20
|
+
/** The input type of the schema. */
|
|
21
|
+
readonly input: Input;
|
|
22
|
+
/** The output type of the schema. */
|
|
23
|
+
readonly output: Output;
|
|
24
|
+
}
|
|
25
|
+
/** Infers the input type of a Standard Typed. */
|
|
26
|
+
type InferInput<Schema extends StandardTypedV1> = NonNullable<Schema["~standard"]["types"]>["input"];
|
|
27
|
+
/** Infers the output type of a Standard Typed. */
|
|
28
|
+
type InferOutput<Schema extends StandardTypedV1> = NonNullable<Schema["~standard"]["types"]>["output"];
|
|
29
|
+
}
|
|
30
|
+
/** The Standard Schema interface. */
|
|
31
|
+
interface StandardSchemaV1<Input = unknown, Output = Input> {
|
|
32
|
+
/** The Standard Schema properties. */
|
|
33
|
+
readonly "~standard": StandardSchemaV1.Props<Input, Output>;
|
|
34
|
+
}
|
|
35
|
+
declare namespace StandardSchemaV1 {
|
|
36
|
+
/** The Standard Schema properties interface. */
|
|
37
|
+
interface Props<Input = unknown, Output = Input> extends StandardTypedV1.Props<Input, Output> {
|
|
38
|
+
/** Validates unknown input values. */
|
|
39
|
+
readonly validate: (value: unknown, options?: StandardSchemaV1.Options | undefined) => Result<Output> | Promise<Result<Output>>;
|
|
40
|
+
}
|
|
41
|
+
/** The result interface of the validate function. */
|
|
42
|
+
type Result<Output> = SuccessResult<Output> | FailureResult;
|
|
43
|
+
/** The result interface if validation succeeds. */
|
|
44
|
+
interface SuccessResult<Output> {
|
|
45
|
+
/** The typed output value. */
|
|
46
|
+
readonly value: Output;
|
|
47
|
+
/** A falsy value for `issues` indicates success. */
|
|
48
|
+
readonly issues?: undefined;
|
|
49
|
+
}
|
|
50
|
+
interface Options {
|
|
51
|
+
/** Explicit support for additional vendor-specific parameters, if needed. */
|
|
52
|
+
readonly libraryOptions?: Record<string, unknown> | undefined;
|
|
53
|
+
}
|
|
54
|
+
/** The result interface if validation fails. */
|
|
55
|
+
interface FailureResult {
|
|
56
|
+
/** The issues of failed validation. */
|
|
57
|
+
readonly issues: ReadonlyArray<Issue>;
|
|
58
|
+
}
|
|
59
|
+
/** The issue interface of the failure output. */
|
|
60
|
+
interface Issue {
|
|
61
|
+
/** The error message of the issue. */
|
|
62
|
+
readonly message: string;
|
|
63
|
+
/** The path of the issue, if any. */
|
|
64
|
+
readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined;
|
|
65
|
+
}
|
|
66
|
+
/** The path segment interface of the issue. */
|
|
67
|
+
interface PathSegment {
|
|
68
|
+
/** The key representing a path segment. */
|
|
69
|
+
readonly key: PropertyKey;
|
|
70
|
+
}
|
|
71
|
+
/** The Standard types interface. */
|
|
72
|
+
interface Types<Input = unknown, Output = Input> extends StandardTypedV1.Types<Input, Output> {}
|
|
73
|
+
/** Infers the input type of a Standard. */
|
|
74
|
+
type InferInput<Schema extends StandardTypedV1> = StandardTypedV1.InferInput<Schema>;
|
|
75
|
+
/** Infers the output type of a Standard. */
|
|
76
|
+
type InferOutput<Schema extends StandardTypedV1> = StandardTypedV1.InferOutput<Schema>;
|
|
77
|
+
}
|
|
78
|
+
/** The Standard JSON Schema interface. */
|
|
79
|
+
//#endregion
|
|
80
|
+
//#region src/command-types.d.ts
|
|
81
|
+
type PrimitiveFieldType = "string" | "number" | "boolean";
|
|
82
|
+
type PrimitiveFieldValue<TType extends PrimitiveFieldType> = TType extends "string" ? string : TType extends "number" ? number : boolean;
|
|
83
|
+
interface NamedField<TName extends string = string> {
|
|
84
|
+
/** Identifier used as the key in `ctx.args` / `ctx.options` and as the CLI flag name for options. */
|
|
85
|
+
readonly name: TName;
|
|
86
|
+
/** One-line help text shown in `--help` output. */
|
|
87
|
+
readonly description?: string | undefined;
|
|
88
|
+
}
|
|
89
|
+
interface PrimitiveFieldBase<TName extends string, TType extends PrimitiveFieldType> extends NamedField<TName> {
|
|
90
|
+
/** Primitive type that Rune parses the raw CLI token into (`"string"`, `"number"`, or `"boolean"`). */
|
|
91
|
+
readonly type: TType;
|
|
92
|
+
/**
|
|
93
|
+
* When `true`, the field must be provided by the user.
|
|
94
|
+
* Omitted or `false` makes the field optional (absent fields are `undefined` in `ctx`).
|
|
95
|
+
*/
|
|
96
|
+
readonly required?: boolean | undefined;
|
|
97
|
+
/** Value used when the user does not provide this field. Makes the field always present in `ctx`. */
|
|
98
|
+
readonly default?: PrimitiveFieldValue<TType> | undefined;
|
|
99
|
+
readonly schema?: never;
|
|
100
|
+
}
|
|
101
|
+
interface SchemaFieldBase<TName extends string, TSchema extends StandardSchemaV1 = StandardSchemaV1> extends NamedField<TName> {
|
|
102
|
+
/**
|
|
103
|
+
* A Standard Schema object (e.g. `z.string()`, `v.number()`) used to
|
|
104
|
+
* validate and transform the raw CLI token. Required/optional and default
|
|
105
|
+
* semantics are derived from the schema itself.
|
|
106
|
+
*/
|
|
107
|
+
readonly schema: TSchema;
|
|
108
|
+
readonly type?: never;
|
|
109
|
+
readonly required?: never;
|
|
110
|
+
readonly default?: never;
|
|
111
|
+
}
|
|
112
|
+
interface PrimitiveArgField<TName extends string = string, TType extends PrimitiveFieldType = PrimitiveFieldType> extends PrimitiveFieldBase<TName, TType> {
|
|
113
|
+
readonly alias?: never;
|
|
114
|
+
readonly flag?: never;
|
|
115
|
+
}
|
|
116
|
+
interface SchemaArgField<TName extends string = string, TSchema extends StandardSchemaV1 = StandardSchemaV1> extends SchemaFieldBase<TName, TSchema> {
|
|
117
|
+
readonly alias?: never;
|
|
118
|
+
readonly flag?: never;
|
|
119
|
+
}
|
|
120
|
+
interface PrimitiveOptionField<TName extends string = string, TType extends PrimitiveFieldType = PrimitiveFieldType> extends PrimitiveFieldBase<TName, TType> {
|
|
121
|
+
/** Single-character shorthand (e.g. `"v"` for `--verbose` → `-v`). */
|
|
122
|
+
readonly alias?: string | undefined;
|
|
123
|
+
readonly flag?: never;
|
|
124
|
+
}
|
|
125
|
+
interface SchemaOptionField<TName extends string = string, TSchema extends StandardSchemaV1 = StandardSchemaV1> extends SchemaFieldBase<TName, TSchema> {
|
|
126
|
+
/** Single-character shorthand (e.g. `"v"` for `--verbose` → `-v`). */
|
|
127
|
+
readonly alias?: string | undefined;
|
|
128
|
+
/**
|
|
129
|
+
* When `true`, the option is parsed as a boolean flag (no value expected).
|
|
130
|
+
* The schema receives `true` when the flag is present, `undefined` when absent.
|
|
131
|
+
*/
|
|
132
|
+
readonly flag?: true | undefined;
|
|
133
|
+
}
|
|
134
|
+
type CommandArgField = PrimitiveArgField | SchemaArgField;
|
|
135
|
+
type CommandOptionField = PrimitiveOptionField | SchemaOptionField;
|
|
136
|
+
type NormalizeFields<TFields extends readonly TField[] | undefined, TField> = TFields extends readonly TField[] ? TFields : readonly [];
|
|
137
|
+
type FieldName<TField> = TField extends {
|
|
138
|
+
readonly name: infer TName extends string;
|
|
139
|
+
} ? TName : never;
|
|
140
|
+
type InferSchemaOutput<TSchema> = TSchema extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<TSchema> : never;
|
|
141
|
+
type InferSchemaInput<TSchema> = TSchema extends StandardSchemaV1 ? StandardSchemaV1.InferInput<TSchema> : never;
|
|
142
|
+
type IsOptionalSchemaOutput<TValue> = undefined extends TValue ? true : false;
|
|
143
|
+
type FieldValue<TField> = TField extends {
|
|
144
|
+
readonly schema: infer TSchema;
|
|
145
|
+
} ? Exclude<InferSchemaOutput<TSchema>, undefined> : TField extends {
|
|
146
|
+
readonly type: infer TType extends PrimitiveFieldType;
|
|
147
|
+
} ? PrimitiveFieldValue<TType> : never;
|
|
148
|
+
type FieldInputValue<TField> = TField extends {
|
|
149
|
+
readonly schema: infer TSchema;
|
|
150
|
+
} ? InferSchemaInput<TSchema> : TField extends {
|
|
151
|
+
readonly type: infer TType extends PrimitiveFieldType;
|
|
152
|
+
} ? PrimitiveFieldValue<TType> : never;
|
|
153
|
+
type HasDefaultValue<TField> = TField extends {
|
|
154
|
+
readonly default: infer TDefault;
|
|
155
|
+
} ? [TDefault] extends [undefined] ? false : true : false;
|
|
156
|
+
type IsRequiredField<TField> = TField extends {
|
|
157
|
+
readonly schema: infer TSchema;
|
|
158
|
+
} ? IsOptionalSchemaOutput<InferSchemaOutput<TSchema>> extends true ? false : true : HasDefaultValue<TField> extends true ? true : TField extends {
|
|
159
|
+
readonly required: true;
|
|
160
|
+
} ? true : false;
|
|
161
|
+
type IsArgOptional<TField> = TField extends {
|
|
162
|
+
readonly schema: infer TSchema;
|
|
163
|
+
} ? unknown extends InferSchemaInput<TSchema> ? false : undefined extends InferSchemaInput<TSchema> ? true : false : TField extends {
|
|
164
|
+
readonly type: PrimitiveFieldType;
|
|
165
|
+
} ? HasDefaultValue<TField> extends true ? true : TField extends {
|
|
166
|
+
readonly required: true;
|
|
167
|
+
} ? false : true : false;
|
|
168
|
+
type IsValidArgOrder<TArgs extends readonly any[], TSeenOptional extends boolean = false> = TArgs extends readonly [infer THead, ...infer TTail] ? IsArgOptional<THead> extends true ? IsValidArgOrder<TTail, true> : TSeenOptional extends true ? false : IsValidArgOrder<TTail, false> : true;
|
|
169
|
+
type ValidateArgOrder<TArgs> = TArgs extends readonly CommandArgField[] ? IsValidArgOrder<TArgs> extends false ? {
|
|
170
|
+
readonly args: never;
|
|
171
|
+
} : unknown : unknown;
|
|
172
|
+
type Simplify<TValue> = { [TKey in keyof TValue]: TValue[TKey] };
|
|
173
|
+
type InferNamedFields<TFields extends readonly NamedField[]> = Simplify<{ [TField in TFields[number] as IsRequiredField<TField> extends true ? FieldName<TField> : never]: FieldValue<TField> } & { [TField in TFields[number] as IsRequiredField<TField> extends true ? never : FieldName<TField>]?: FieldValue<TField> }>;
|
|
174
|
+
type InferExecutionFields<TFields extends readonly NamedField[]> = Simplify<{ [TField in TFields[number] as FieldName<TField>]?: FieldInputValue<TField> }>;
|
|
175
|
+
/** Runtime data passed into a command's `run` function. */
|
|
176
|
+
interface CommandContext<TOptions, TArgs> {
|
|
177
|
+
/** Parsed and validated positional argument values keyed by field name. */
|
|
178
|
+
readonly args: TArgs;
|
|
179
|
+
/** Parsed and validated option values keyed by field name. */
|
|
180
|
+
readonly options: TOptions;
|
|
181
|
+
/** Working directory the CLI was invoked from. */
|
|
182
|
+
readonly cwd: string;
|
|
183
|
+
/**
|
|
184
|
+
* Unparsed argv tokens passed to this command, before Rune splits them
|
|
185
|
+
* into `args` and `options`. Useful for forwarding to child processes.
|
|
186
|
+
*/
|
|
187
|
+
readonly rawArgs: readonly string[];
|
|
188
|
+
}
|
|
189
|
+
/** The command definition object accepted by {@link defineCommand}. */
|
|
190
|
+
interface DefineCommandInput<TArgsFields extends readonly CommandArgField[] | undefined = undefined, TOptionsFields extends readonly CommandOptionField[] | undefined = undefined> {
|
|
191
|
+
/** One-line summary shown in `--help` output. */
|
|
192
|
+
readonly description?: string | undefined;
|
|
193
|
+
/**
|
|
194
|
+
* Positional arguments declared in the order they appear on the command line.
|
|
195
|
+
* Required arguments must come before optional ones.
|
|
196
|
+
*
|
|
197
|
+
* Each entry is either a primitive field (`{ name, type }`) or a schema
|
|
198
|
+
* field (`{ name, schema }`).
|
|
199
|
+
*/
|
|
200
|
+
readonly args?: TArgsFields;
|
|
201
|
+
/**
|
|
202
|
+
* Options declared as `--name` flags, with optional single-character aliases.
|
|
203
|
+
*
|
|
204
|
+
* Each entry is either a primitive field (`{ name, type }`) or a schema
|
|
205
|
+
* field (`{ name, schema }`).
|
|
206
|
+
*/
|
|
207
|
+
readonly options?: TOptionsFields;
|
|
208
|
+
/**
|
|
209
|
+
* The function executed when this command is invoked.
|
|
210
|
+
* Receives a {@link CommandContext} with fully parsed `args` and `options`.
|
|
211
|
+
*/
|
|
212
|
+
readonly run: (ctx: CommandContext<InferNamedFields<NormalizeFields<TOptionsFields, CommandOptionField>>, InferNamedFields<NormalizeFields<TArgsFields, CommandArgField>>>) => void | Promise<void>;
|
|
213
|
+
}
|
|
214
|
+
interface DefinedCommand<TArgsFields extends readonly CommandArgField[] = readonly [], TOptionsFields extends readonly CommandOptionField[] = readonly []> {
|
|
215
|
+
readonly description?: string | undefined;
|
|
216
|
+
readonly args: TArgsFields;
|
|
217
|
+
readonly options: TOptionsFields;
|
|
218
|
+
readonly run: (ctx: CommandContext<InferNamedFields<TOptionsFields>, InferNamedFields<TArgsFields>>) => void | Promise<void>;
|
|
219
|
+
} //#endregion
|
|
220
|
+
//#region src/define-command.d.ts
|
|
221
|
+
/**
|
|
222
|
+
* Defines a CLI command with a description, positional arguments, options,
|
|
223
|
+
* and a function to execute when the command is invoked.
|
|
224
|
+
*
|
|
225
|
+
* The command module's default export should be the return value of this function.
|
|
226
|
+
*
|
|
227
|
+
* @example
|
|
228
|
+
* ```ts
|
|
229
|
+
* export default defineCommand({
|
|
230
|
+
* description: "Greet someone",
|
|
231
|
+
* args: [
|
|
232
|
+
* { name: "name", type: "string", required: true },
|
|
233
|
+
* ],
|
|
234
|
+
* options: [
|
|
235
|
+
* { name: "loud", type: "boolean", alias: "l" },
|
|
236
|
+
* ],
|
|
237
|
+
* run(ctx) {
|
|
238
|
+
* const greeting = `Hello, ${ctx.args.name}!`;
|
|
239
|
+
* console.log(ctx.options.loud ? greeting.toUpperCase() : greeting);
|
|
240
|
+
* },
|
|
241
|
+
* });
|
|
242
|
+
* ```
|
|
243
|
+
*
|
|
244
|
+
* Required positional arguments must precede optional ones. This ordering is
|
|
245
|
+
* enforced at the type level for concrete schema types and at runtime for
|
|
246
|
+
* primitive fields:
|
|
247
|
+
*
|
|
248
|
+
* ```ts
|
|
249
|
+
* // Type error — required arg after optional arg
|
|
250
|
+
* defineCommand({
|
|
251
|
+
* args: [
|
|
252
|
+
* { name: "source", type: "string" },
|
|
253
|
+
* { name: "target", type: "string", required: true },
|
|
254
|
+
* ],
|
|
255
|
+
* run() {},
|
|
256
|
+
* });
|
|
257
|
+
*
|
|
258
|
+
* // Type error — required primitive arg after optional schema arg
|
|
259
|
+
* defineCommand({
|
|
260
|
+
* args: [
|
|
261
|
+
* { name: "mode", schema: z.string().optional() },
|
|
262
|
+
* { name: "target", type: "string", required: true },
|
|
263
|
+
* ],
|
|
264
|
+
* run() {},
|
|
265
|
+
* });
|
|
266
|
+
* ```
|
|
267
|
+
*
|
|
268
|
+
* When a schema type is widened to plain `StandardSchemaV1` (e.g. stored in
|
|
269
|
+
* a variable without a concrete type), optionality information is lost and
|
|
270
|
+
* the ordering check is skipped for that field.
|
|
271
|
+
*/
|
|
272
|
+
declare function defineCommand<const TArgsFields extends readonly CommandArgField[] | undefined = undefined, const TOptionsFields extends readonly CommandOptionField[] | undefined = undefined>(input: DefineCommandInput<TArgsFields, TOptionsFields> & ValidateArgOrder<TArgsFields>): DefinedCommand<NormalizeFields<TArgsFields, CommandArgField>, NormalizeFields<TOptionsFields, CommandOptionField>>; //#endregion
|
|
273
|
+
//#region src/execute-command.d.ts
|
|
274
|
+
interface ExecuteCommandInput<TOptions, TArgs> {
|
|
275
|
+
readonly options?: TOptions | undefined;
|
|
276
|
+
readonly args?: TArgs | undefined;
|
|
277
|
+
readonly cwd?: string | undefined;
|
|
278
|
+
readonly rawArgs?: readonly string[] | undefined;
|
|
279
|
+
}
|
|
280
|
+
interface CommandExecutionResult {
|
|
281
|
+
readonly exitCode: number;
|
|
282
|
+
readonly stdout: string;
|
|
283
|
+
readonly stderr: string;
|
|
284
|
+
}
|
|
285
|
+
//#endregion
|
|
286
|
+
export { DefinedCommand as a, PrimitiveArgField as c, SchemaArgField as d, SchemaOptionField as f, CommandOptionField as i, PrimitiveFieldType as l, CommandContext as n, ExecuteCommandInput as o, defineCommand as p, CommandExecutionResult as r, InferExecutionFields as s, CommandArgField as t, PrimitiveOptionField as u };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { defineCommand } from "
|
|
2
|
-
export { defineCommand };
|
|
1
|
+
import { a as DefinedCommand, c as PrimitiveArgField, d as SchemaArgField, f as SchemaOptionField, i as CommandOptionField, l as PrimitiveFieldType, n as CommandContext, o as ExecuteCommandInput, p as defineCommand, r as CommandExecutionResult, s as InferExecutionFields, t as CommandArgField, u as PrimitiveOptionField } from "./index-BF5_G9J2.mjs";
|
|
2
|
+
export { type CommandArgField, type CommandContext, type CommandExecutionResult, type CommandOptionField, type DefinedCommand, type ExecuteCommandInput, type InferExecutionFields, type PrimitiveArgField, type PrimitiveFieldType, type PrimitiveOptionField, type SchemaArgField, type SchemaOptionField, defineCommand };
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { defineCommand } from "
|
|
1
|
+
import { t as defineCommand } from "./dist-Bcn0FpHi.mjs";
|
|
2
2
|
export { defineCommand };
|
package/dist/runtime.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as DefinedCommand, i as CommandOptionField, r as CommandExecutionResult, t as CommandArgField } from "./index-BF5_G9J2.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/manifest/manifest-types.d.ts
|
|
4
4
|
type CommandManifestPath = readonly string[];
|
package/dist/runtime.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as runManifestCommand, t as writeCommandExecutionResult } from "./write-result-
|
|
1
|
+
import { n as runManifestCommand, t as writeCommandExecutionResult } from "./write-result-qylmqXvG.mjs";
|
|
2
2
|
export { runManifestCommand, writeCommandExecutionResult };
|
package/dist/test.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as DefinedCommand, i as CommandOptionField, o as ExecuteCommandInput, r as CommandExecutionResult, s as InferExecutionFields, t as CommandArgField } from "./index-BF5_G9J2.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/test.d.ts
|
|
4
4
|
type RunCommandOptions<TOptions, TArgs> = ExecuteCommandInput<TOptions, TArgs>;
|
package/dist/test.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as parseCommand, i as isSchemaField, n as executeCommand, r as formatFieldTypeHint } from "./dist-Bcn0FpHi.mjs";
|
|
2
2
|
import { pathToFileURL } from "node:url";
|
|
3
3
|
//#region src/cli/result.ts
|
|
4
4
|
function successResult(stdout) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rune-cli/rune",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "Rune is a CLI framework built around the concept of file-based command routing.",
|
|
5
5
|
"homepage": "https://github.com/morinokami/rune#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -39,15 +39,14 @@
|
|
|
39
39
|
"access": "public"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"esbuild": "0.27.4"
|
|
43
|
-
"@rune-cli/core": "0.0.0"
|
|
42
|
+
"esbuild": "0.27.4"
|
|
44
43
|
},
|
|
45
44
|
"devDependencies": {
|
|
46
45
|
"@types/node": "24.12.0",
|
|
47
46
|
"@typescript/native-preview": "7.0.0-dev.20260317.1",
|
|
48
|
-
"bumpp": "11.0.1",
|
|
49
47
|
"typescript": "5.9.3",
|
|
50
|
-
"vite-plus": "v0.1.13"
|
|
48
|
+
"vite-plus": "v0.1.13",
|
|
49
|
+
"@rune-cli/core": "0.0.0"
|
|
51
50
|
},
|
|
52
51
|
"peerDependencies": {
|
|
53
52
|
"typescript": ">=5.0.0"
|