@shell-shock/core 0.17.5 → 0.17.6
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/components/command-validation-logic.cjs +214 -152
- package/dist/components/command-validation-logic.mjs +213 -152
- package/dist/components/command-validation-logic.mjs.map +1 -1
- package/dist/components/docs.cjs +113 -9
- package/dist/components/docs.mjs +109 -9
- package/dist/components/docs.mjs.map +1 -1
- package/dist/components/exec-builtin.cjs +36 -1
- package/dist/components/exec-builtin.d.cts.map +1 -1
- package/dist/components/exec-builtin.d.mts.map +1 -1
- package/dist/components/exec-builtin.mjs +35 -1
- package/dist/components/exec-builtin.mjs.map +1 -1
- package/dist/components/helpers.cjs +51 -2
- package/dist/components/helpers.mjs +50 -2
- package/dist/components/helpers.mjs.map +1 -1
- package/dist/components/index.cjs +17 -1
- package/dist/components/index.mjs +9 -9
- package/dist/components/options-parser-logic.cjs +411 -174
- package/dist/components/options-parser-logic.d.cts.map +1 -1
- package/dist/components/options-parser-logic.d.mts.map +1 -1
- package/dist/components/options-parser-logic.mjs +405 -174
- package/dist/components/options-parser-logic.mjs.map +1 -1
- package/dist/components/state-builtin.cjs +61 -5
- package/dist/components/state-builtin.mjs +60 -5
- package/dist/components/state-builtin.mjs.map +1 -1
- package/dist/components/usage.cjs +46 -3
- package/dist/components/usage.mjs +45 -3
- package/dist/components/usage.mjs.map +1 -1
- package/dist/components/utils-builtin.cjs +68 -3
- package/dist/components/utils-builtin.mjs +67 -3
- package/dist/components/utils-builtin.mjs.map +1 -1
- package/dist/helpers/automd.cjs +28 -13
- package/dist/helpers/automd.mjs +28 -13
- package/dist/helpers/automd.mjs.map +1 -1
- package/dist/index.cjs +11 -0
- package/dist/index.d.cts +2 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +2 -2
- package/dist/plugin-utils/compute-bin.cjs +50 -0
- package/dist/plugin-utils/compute-bin.d.cts +13 -0
- package/dist/plugin-utils/compute-bin.d.cts.map +1 -0
- package/dist/plugin-utils/compute-bin.d.mts +13 -0
- package/dist/plugin-utils/compute-bin.d.mts.map +1 -0
- package/dist/plugin-utils/compute-bin.mjs +50 -0
- package/dist/plugin-utils/compute-bin.mjs.map +1 -0
- package/dist/plugin-utils/get-command-tree.cjs +50 -0
- package/dist/plugin-utils/get-command-tree.d.cts +15 -1
- package/dist/plugin-utils/get-command-tree.d.cts.map +1 -1
- package/dist/plugin-utils/get-command-tree.d.mts +15 -1
- package/dist/plugin-utils/get-command-tree.d.mts.map +1 -1
- package/dist/plugin-utils/get-command-tree.mjs +49 -1
- package/dist/plugin-utils/get-command-tree.mjs.map +1 -1
- package/dist/plugin-utils/index.cjs +4 -0
- package/dist/plugin-utils/index.d.cts +3 -2
- package/dist/plugin-utils/index.d.mts +3 -2
- package/dist/plugin-utils/index.mjs +3 -2
- package/dist/plugin.cjs +170 -52
- package/dist/plugin.mjs +170 -52
- package/dist/plugin.mjs.map +1 -1
- package/dist/resolver/deepkit.cjs +1 -1
- package/dist/resolver/deepkit.mjs +1 -1
- package/dist/resolver/deepkit.mjs.map +1 -1
- package/dist/types/command.cjs +120 -10
- package/dist/types/command.d.cts +95 -8
- package/dist/types/command.d.cts.map +1 -1
- package/dist/types/command.d.mts +95 -8
- package/dist/types/command.d.mts.map +1 -1
- package/dist/types/command.mjs +109 -10
- package/dist/types/command.mjs.map +1 -1
- package/dist/types/index.cjs +12 -1
- package/dist/types/index.d.cts +2 -2
- package/dist/types/index.d.mts +2 -2
- package/dist/types/index.mjs +2 -2
- package/package.json +10 -10
package/dist/plugin.mjs
CHANGED
|
@@ -35,17 +35,21 @@ import { defu } from "defu";
|
|
|
35
35
|
import { resolveInputs } from "powerlines/utils";
|
|
36
36
|
|
|
37
37
|
//#region src/plugin.tsx
|
|
38
|
+
function __assignType(fn, args) {
|
|
39
|
+
fn.__type = args;
|
|
40
|
+
return fn;
|
|
41
|
+
}
|
|
38
42
|
const MAX_DEPTH = 50;
|
|
39
43
|
/**
|
|
40
44
|
* The core Powerlines plugin to build Shell Shock projects.
|
|
41
45
|
*/
|
|
42
|
-
const plugin = (options = {}) => {
|
|
46
|
+
const plugin = __assignType((options = {}) => {
|
|
43
47
|
return [
|
|
44
|
-
tsdown(),
|
|
45
|
-
automd(),
|
|
48
|
+
(tsdown.Ω = [["Context", "\"w!"]], tsdown()),
|
|
49
|
+
(automd.Ω = [["Context", "\"w!"]], automd()),
|
|
46
50
|
{
|
|
47
51
|
name: "shell-shock:config",
|
|
48
|
-
async config() {
|
|
52
|
+
config: __assignType(async function config() {
|
|
49
53
|
this.debug("Resolving the Shell Shock configuration.");
|
|
50
54
|
await updatePackageJsonBinary(this);
|
|
51
55
|
return defu({ output: { path: joinPaths(this.config.root, "dist") } }, options, {
|
|
@@ -71,7 +75,7 @@ const plugin = (options = {}) => {
|
|
|
71
75
|
unbundle: false
|
|
72
76
|
}
|
|
73
77
|
});
|
|
74
|
-
},
|
|
78
|
+
}, ["config", "P\"/!"]),
|
|
75
79
|
configResolved: {
|
|
76
80
|
order: "pre",
|
|
77
81
|
async handler() {
|
|
@@ -100,19 +104,23 @@ const plugin = (options = {}) => {
|
|
|
100
104
|
alias: [],
|
|
101
105
|
isVirtual: false
|
|
102
106
|
}));
|
|
103
|
-
this.options = this.options.map((option) => ({
|
|
107
|
+
this.options = this.options.map(__assignType((option) => ({
|
|
104
108
|
...option,
|
|
105
109
|
name: camelCase(option.name),
|
|
106
110
|
alias: option.alias ?? [],
|
|
107
111
|
optional: option.optional ?? false
|
|
108
|
-
})
|
|
112
|
+
}), [
|
|
113
|
+
"option",
|
|
114
|
+
"",
|
|
115
|
+
"P\"2!\"/\""
|
|
116
|
+
]));
|
|
109
117
|
}
|
|
110
118
|
}
|
|
111
119
|
},
|
|
112
|
-
...nodejs(defu(options ?? {}, { env: {
|
|
120
|
+
...(nodejs.Ω = [["Context", "\"w!"]], nodejs(defu(options ?? {}, { env: {
|
|
113
121
|
types: "@shell-shock/core/types/env#ShellShockEnv",
|
|
114
122
|
validate: false
|
|
115
|
-
} })),
|
|
123
|
+
} }))),
|
|
116
124
|
{
|
|
117
125
|
name: "shell-shock:inputs",
|
|
118
126
|
async configResolved() {
|
|
@@ -122,17 +130,34 @@ const plugin = (options = {}) => {
|
|
|
122
130
|
this.debug(`Resolved commands root path: ${this.commandsPath}`);
|
|
123
131
|
const inputs = await resolveInputs(this, this.config.input);
|
|
124
132
|
this.debug(`Found ${inputs.length} entry points specified in the configuration options.`);
|
|
125
|
-
this.inputs = inputs.reduce((ret, entry) => {
|
|
133
|
+
this.inputs = inputs.reduce(__assignType((ret, entry) => {
|
|
126
134
|
if (entry.file !== this.commandsPath && !isParentPath(entry.file, this.commandsPath)) throw new Error(`Command entry point "${entry.file}" is not located within the commands root "${this.commandsPath}". Please ensure that all command entry points are located within the current project.`);
|
|
127
135
|
const id = resolveCommandId(this, entry.file);
|
|
128
|
-
if (!ret.some((existing) => existing.id === id
|
|
136
|
+
if (!ret.some(__assignType((existing) => existing.id === id, [
|
|
137
|
+
"existing",
|
|
138
|
+
"",
|
|
139
|
+
"P\"2!\"/\""
|
|
140
|
+
]))) {
|
|
129
141
|
const name = resolveCommandName(entry.file);
|
|
130
142
|
let segments = resolveCommandPath(this, entry.file).split("/").filter(Boolean);
|
|
131
|
-
segments = segments.map((segment, index) => {
|
|
132
|
-
const found = segments.findIndex((existing) => existing === segment
|
|
133
|
-
|
|
143
|
+
segments = segments.map(__assignType((segment, index) => {
|
|
144
|
+
const found = segments.findIndex(__assignType((existing) => existing === segment, [
|
|
145
|
+
"existing",
|
|
146
|
+
"",
|
|
147
|
+
"P\"2!\"/\""
|
|
148
|
+
]));
|
|
149
|
+
if (found !== -1 && found !== index) segment += `_${segments.filter(__assignType((segment) => isDynamicPathSegment(segment) && getDynamicPathSegmentName(segment).replace(/_\d+$/, "") === segment, [
|
|
150
|
+
"segment",
|
|
151
|
+
"",
|
|
152
|
+
"P\"2!\"/\""
|
|
153
|
+
])).length}`;
|
|
134
154
|
return segment;
|
|
135
|
-
}
|
|
155
|
+
}, [
|
|
156
|
+
"segment",
|
|
157
|
+
"index",
|
|
158
|
+
"",
|
|
159
|
+
"P\"2!\"2\"\"/#"
|
|
160
|
+
]));
|
|
136
161
|
ret.push({
|
|
137
162
|
id,
|
|
138
163
|
path: segments.join("/"),
|
|
@@ -154,17 +179,26 @@ const plugin = (options = {}) => {
|
|
|
154
179
|
});
|
|
155
180
|
}
|
|
156
181
|
return ret;
|
|
157
|
-
},
|
|
158
|
-
|
|
182
|
+
}, [
|
|
183
|
+
"ret",
|
|
184
|
+
"entry",
|
|
185
|
+
"",
|
|
186
|
+
"P\"2!\"2\"\"/#"
|
|
187
|
+
]), this.inputs);
|
|
188
|
+
this.debug(`Shell Shock will process ${this.inputs.length} command entry files: \n${this.inputs.map(__assignType((command) => ` - ${command.id}: ${replacePath(command.entry.file, this.commandsPath)}`, [
|
|
189
|
+
"command",
|
|
190
|
+
"",
|
|
191
|
+
"P\"2!\"/\""
|
|
192
|
+
])).join("\n")}`);
|
|
159
193
|
},
|
|
160
|
-
async prepare() {
|
|
194
|
+
prepare: __assignType(async function prepare() {
|
|
161
195
|
this.debug("Rendering base built-in modules for the Shell Shock application.");
|
|
162
196
|
return render(this, [
|
|
163
197
|
createComponent(StateBuiltin, {}),
|
|
164
198
|
createComponent(UtilsBuiltin, {}),
|
|
165
199
|
createComponent(ExecBuiltin, {})
|
|
166
200
|
]);
|
|
167
|
-
}
|
|
201
|
+
}, ["prepare", "P\"/!"])
|
|
168
202
|
},
|
|
169
203
|
{
|
|
170
204
|
name: "shell-shock:virtual-inputs",
|
|
@@ -174,22 +208,43 @@ const plugin = (options = {}) => {
|
|
|
174
208
|
if (this.inputs.length === 0) this.warn("No commands were found in the project. Please ensure at least one command exists.");
|
|
175
209
|
else {
|
|
176
210
|
this.debug("Finding and adding virtual command inputs for each command previously found.");
|
|
177
|
-
this.inputs = this.inputs.reduce((ret, command) => {
|
|
211
|
+
this.inputs = this.inputs.reduce(__assignType((ret, command) => {
|
|
178
212
|
let depth = 0;
|
|
179
213
|
let parentPath = resolveParentPath(findFilePath(command.entry.file));
|
|
180
214
|
if (isParentPath(parentPath, this.commandsPath)) while (parentPath !== this.commandsPath) {
|
|
181
215
|
if (depth++ > MAX_DEPTH) throw new Error(`Unable to process virtual commands for ${command.name} \n\nPlease ensure ${command.entry.file} is a valid command entry file and does not have an invalid path.`);
|
|
182
|
-
if (!ret.some((existing) => findFilePath(existing.entry.file) === parentPath
|
|
216
|
+
if (!ret.some(__assignType((existing) => findFilePath(existing.entry.file) === parentPath, [
|
|
217
|
+
"existing",
|
|
218
|
+
"",
|
|
219
|
+
"P\"2!\"/\""
|
|
220
|
+
]))) {
|
|
183
221
|
const file = joinPaths(parentPath, "command.ts");
|
|
184
222
|
const id = resolveCommandId(this, file);
|
|
185
|
-
if (!ret.some((existing) => existing.id === id
|
|
223
|
+
if (!ret.some(__assignType((existing) => existing.id === id, [
|
|
224
|
+
"existing",
|
|
225
|
+
"",
|
|
226
|
+
"P\"2!\"/\""
|
|
227
|
+
]))) {
|
|
186
228
|
const name = resolveCommandName(file);
|
|
187
229
|
let segments = resolveCommandPath(this, file).split("/").filter(Boolean);
|
|
188
|
-
segments = segments.map((segment, index) => {
|
|
189
|
-
const found = segments.findIndex((existing) => existing === segment
|
|
190
|
-
|
|
230
|
+
segments = segments.map(__assignType((segment, index) => {
|
|
231
|
+
const found = segments.findIndex(__assignType((existing) => existing === segment, [
|
|
232
|
+
"existing",
|
|
233
|
+
"",
|
|
234
|
+
"P\"2!\"/\""
|
|
235
|
+
]));
|
|
236
|
+
if (found !== -1 && found !== index) segment += `_${segments.filter(__assignType((segment) => isDynamicPathSegment(segment) && getDynamicPathSegmentName(segment).replace(/_\d+$/, "") === segment, [
|
|
237
|
+
"segment",
|
|
238
|
+
"",
|
|
239
|
+
"P\"2!\"/\""
|
|
240
|
+
])).length}`;
|
|
191
241
|
return segment;
|
|
192
|
-
}
|
|
242
|
+
}, [
|
|
243
|
+
"segment",
|
|
244
|
+
"index",
|
|
245
|
+
"",
|
|
246
|
+
"P\"2!\"2\"\"/#"
|
|
247
|
+
]));
|
|
193
248
|
ret.push({
|
|
194
249
|
id,
|
|
195
250
|
path: segments.join("/"),
|
|
@@ -206,8 +261,22 @@ const plugin = (options = {}) => {
|
|
|
206
261
|
parentPath = resolveParentPath(parentPath);
|
|
207
262
|
}
|
|
208
263
|
return ret;
|
|
209
|
-
},
|
|
210
|
-
|
|
264
|
+
}, [
|
|
265
|
+
"ret",
|
|
266
|
+
"command",
|
|
267
|
+
"",
|
|
268
|
+
"P\"2!\"2\"\"/#"
|
|
269
|
+
]), this.inputs).sort(__assignType((a, b) => a.segments.length - b.segments.length, [
|
|
270
|
+
"a",
|
|
271
|
+
"b",
|
|
272
|
+
"",
|
|
273
|
+
"P\"2!\"2\"\"/#"
|
|
274
|
+
]));
|
|
275
|
+
this.debug(`Final command input list: \n${this.inputs.map(__assignType((command) => ` - ${command.id}${command.isVirtual ? " (virtual)" : ""}: ${command.source === "file" ? replacePath(command.entry.file, this.commandsPath) : `added by ${command.source}`}`, [
|
|
276
|
+
"command",
|
|
277
|
+
"",
|
|
278
|
+
"P\"2!\"/\""
|
|
279
|
+
])).join("\n")}`);
|
|
211
280
|
}
|
|
212
281
|
}
|
|
213
282
|
}
|
|
@@ -223,30 +292,54 @@ const plugin = (options = {}) => {
|
|
|
223
292
|
this.debug(`Skipping command resolution as the meta checksum has not changed.`);
|
|
224
293
|
await readCommandsPersistence(this);
|
|
225
294
|
} else {
|
|
226
|
-
for (const input of this.inputs.filter((input) => input.segments.filter((segment) => !isDynamicPathSegment(segment) && !isPathSegmentGroup(segment)
|
|
295
|
+
for (const input of this.inputs.filter(__assignType((input) => input.segments.filter(__assignType((segment) => !isDynamicPathSegment(segment) && !isPathSegmentGroup(segment), [
|
|
296
|
+
"segment",
|
|
297
|
+
"",
|
|
298
|
+
"P\"2!\"/\""
|
|
299
|
+
])).length === 1, [
|
|
300
|
+
"input",
|
|
301
|
+
"",
|
|
302
|
+
"P\"2!\"/\""
|
|
303
|
+
]))) this.commands[input.name] = await resolve({
|
|
227
304
|
context: this,
|
|
228
305
|
command: input
|
|
229
306
|
});
|
|
230
307
|
this.debug("Post-processing commands to ensure proper reflection.");
|
|
231
|
-
await traverseCommands(this, (command) => {
|
|
232
|
-
command.options = Object.fromEntries(Object.entries(command.options).map(([name, option]) => [camelCase(name), {
|
|
308
|
+
await traverseCommands(this, __assignType((command) => {
|
|
309
|
+
command.options = Object.fromEntries(Object.entries(command.options).map(__assignType(([name, option]) => [camelCase(name), {
|
|
233
310
|
...option,
|
|
234
311
|
name: camelCase(name),
|
|
235
312
|
alias: option.alias ?? [],
|
|
236
313
|
optional: option.optional ?? false
|
|
237
|
-
}]
|
|
238
|
-
|
|
314
|
+
}], [
|
|
315
|
+
"param0",
|
|
316
|
+
"",
|
|
317
|
+
"P\"2!\"/\""
|
|
318
|
+
])));
|
|
319
|
+
}, [
|
|
320
|
+
"command",
|
|
321
|
+
"",
|
|
322
|
+
"P\"2!\"/\""
|
|
323
|
+
]));
|
|
239
324
|
await writeCommandsPersistence(this);
|
|
240
325
|
}
|
|
241
326
|
this.debug("Validating the CLI applications command tree.");
|
|
242
327
|
let isValid = true;
|
|
243
|
-
await traverseCommands(this, (command) => {
|
|
328
|
+
await traverseCommands(this, __assignType((command) => {
|
|
244
329
|
const failures = validateCommand(command);
|
|
245
330
|
if (failures.length > 0) {
|
|
246
|
-
this.error(`Found ${failures.length} issue${failures.length > 1 ? "s" : ""} with the ${command.title} command: \n${failures.map((failure) => ` - ${failure.code}: ${failure.details}
|
|
331
|
+
this.error(`Found ${failures.length} issue${failures.length > 1 ? "s" : ""} with the ${command.title} command: \n${failures.map(__assignType((failure) => ` - ${failure.code}: ${failure.details}`, [
|
|
332
|
+
"failure",
|
|
333
|
+
"",
|
|
334
|
+
"P\"2!\"/\""
|
|
335
|
+
])).join("\n")}\n`);
|
|
247
336
|
isValid = false;
|
|
248
337
|
}
|
|
249
|
-
}
|
|
338
|
+
}, [
|
|
339
|
+
"command",
|
|
340
|
+
"",
|
|
341
|
+
"P\"2!\"/\""
|
|
342
|
+
]));
|
|
250
343
|
if (!isValid) throw new Error(`One or more commands in the command tree are invalid. Please review the errors above and correct them before proceeding.`);
|
|
251
344
|
this.info(`\nCreating an application with the following command tree: \n${formatCommandTree(this)}\n`);
|
|
252
345
|
}
|
|
@@ -256,8 +349,8 @@ const plugin = (options = {}) => {
|
|
|
256
349
|
name: "shell-shock:chmod+x",
|
|
257
350
|
configResolved() {
|
|
258
351
|
this.config.tsdown.hooks ??= {};
|
|
259
|
-
this.config.tsdown.hooks["build:done"] = async (_) => {
|
|
260
|
-
await Promise.all(Object.values(this.config.bin).map(async (bin) => {
|
|
352
|
+
this.config.tsdown.hooks["build:done"] = __assignType(async (_) => {
|
|
353
|
+
await Promise.all(Object.values(this.config.bin).map(__assignType(async (bin) => {
|
|
261
354
|
const path = appendPath(bin, joinPaths(this.workspaceConfig.workspaceRoot, this.config.root));
|
|
262
355
|
if (this.fs.existsSync(path)) {
|
|
263
356
|
this.debug(`Adding hashbang to binary executable output file: ${path}`);
|
|
@@ -266,40 +359,65 @@ const plugin = (options = {}) => {
|
|
|
266
359
|
this.debug(`Adding executable permissions (chmod+x) to binary executable output file: ${path}`);
|
|
267
360
|
await chmodX(path);
|
|
268
361
|
} else this.warn(`Expected binary output file not found at path: ${path}. Skipping adding hashbang and executable permissions (chmod+x).`);
|
|
269
|
-
}
|
|
270
|
-
|
|
362
|
+
}, [
|
|
363
|
+
"bin",
|
|
364
|
+
"",
|
|
365
|
+
"P\"2!\"/\""
|
|
366
|
+
])));
|
|
367
|
+
}, [
|
|
368
|
+
"chunks",
|
|
369
|
+
"_",
|
|
370
|
+
"",
|
|
371
|
+
"PP!P!F4!MK2\"\"/#"
|
|
372
|
+
]);
|
|
271
373
|
}
|
|
272
374
|
},
|
|
273
375
|
{
|
|
274
376
|
name: "shell-shock:docs",
|
|
275
|
-
configResolved() {
|
|
377
|
+
configResolved: __assignType(function configResolved() {
|
|
276
378
|
this.config.automd ??= {};
|
|
277
379
|
this.config.automd.generators = {
|
|
278
380
|
...this.config.automd.generators ?? {},
|
|
279
381
|
commands: commands(this)
|
|
280
382
|
};
|
|
281
|
-
},
|
|
383
|
+
}, ["configResolved", "P\"/!"]),
|
|
282
384
|
async docs() {
|
|
283
385
|
this.debug("Rendering entrypoint modules for the Shell Shock `script` preset.");
|
|
284
|
-
const commands = this.inputs.map((input) => getCommandTree(this, input.segments)
|
|
386
|
+
const commands = this.inputs.map(__assignType((input) => getCommandTree(this, input.segments), [
|
|
387
|
+
"input",
|
|
388
|
+
"",
|
|
389
|
+
"P\"2!\"/\""
|
|
390
|
+
])).filter(Boolean);
|
|
285
391
|
return render(this, createComponent(For, {
|
|
286
392
|
get each() {
|
|
287
393
|
return Object.values(commands);
|
|
288
394
|
},
|
|
289
395
|
doubleHardline: true,
|
|
290
|
-
children
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
396
|
+
get children() {
|
|
397
|
+
return __assignType((child) => createComponent(Show, {
|
|
398
|
+
get when() {
|
|
399
|
+
return !child.isVirtual;
|
|
400
|
+
},
|
|
401
|
+
get children() {
|
|
402
|
+
return createComponent(CommandDocsFile, { command: child });
|
|
403
|
+
}
|
|
404
|
+
}), [
|
|
405
|
+
"child",
|
|
406
|
+
"",
|
|
407
|
+
"P\"2!\"/\""
|
|
408
|
+
]);
|
|
409
|
+
}
|
|
298
410
|
}));
|
|
299
411
|
}
|
|
300
412
|
}
|
|
301
413
|
];
|
|
302
|
-
}
|
|
414
|
+
}, [
|
|
415
|
+
"Options",
|
|
416
|
+
"options",
|
|
417
|
+
() => ({}),
|
|
418
|
+
"",
|
|
419
|
+
"P\"w!2\">#!F/$"
|
|
420
|
+
]);
|
|
303
421
|
|
|
304
422
|
//#endregion
|
|
305
423
|
export { plugin as default, plugin };
|
package/dist/plugin.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.mjs","names":[],"sources":["../src/plugin.tsx"],"sourcesContent":["/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Shell Shock\n\n This code was released as part of the Shell Shock project. Shell Shock\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/shell-shock.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/shell-shock\n Documentation: https://docs.stormsoftware.com/projects/shell-shock\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport { For, Show } from \"@alloy-js/core/components\";\nimport { render } from \"@powerlines/plugin-alloy/render\";\nimport automd from \"@powerlines/plugin-automd\";\nimport nodejs from \"@powerlines/plugin-nodejs\";\nimport tsdown from \"@powerlines/plugin-tsdown\";\nimport { toArray } from \"@stryke/convert/to-array\";\nimport { chmodX } from \"@stryke/fs/chmod-x\";\nimport { appendPath } from \"@stryke/path/append\";\nimport { findFilePath } from \"@stryke/path/file-path-fns\";\nimport { isParentPath } from \"@stryke/path/is-parent-path\";\nimport { joinPaths } from \"@stryke/path/join-paths\";\nimport { replacePath } from \"@stryke/path/replace\";\nimport { resolveParentPath } from \"@stryke/path/resolve-parent-path\";\nimport { camelCase } from \"@stryke/string-format/camel-case\";\nimport { constantCase } from \"@stryke/string-format/constant-case\";\nimport { kebabCase } from \"@stryke/string-format/kebab-case\";\nimport { isObject } from \"@stryke/type-checks/is-object\";\nimport { isSetString } from \"@stryke/type-checks/is-set-string\";\nimport { defu } from \"defu\";\nimport type { Plugin } from \"powerlines\";\nimport { resolveInputs } from \"powerlines/utils\";\nimport type { BuildContext, RolldownChunk, TsdownHooks } from \"tsdown\";\nimport { CommandDocsFile } from \"./components/docs\";\nimport { ExecBuiltin } from \"./components/exec-builtin\";\nimport { StateBuiltin } from \"./components/state-builtin\";\nimport { UtilsBuiltin } from \"./components/utils-builtin\";\nimport { commands } from \"./helpers/automd\";\nimport {\n findCommandsRoot,\n resolveCommandId,\n resolveCommandName,\n resolveCommandPath\n} from \"./helpers/paths\";\nimport {\n getCommandsPersistencePath,\n readCommandsPersistence,\n writeCommandsPersistence\n} from \"./helpers/persistence\";\nimport {\n formatBinaryPath,\n updatePackageJsonBinary\n} from \"./helpers/update-package-json\";\nimport { formatCommandTree, getGlobalOptions } from \"./helpers/utilities\";\nimport { validateCommand } from \"./helpers/validations\";\nimport {\n getAppDescription,\n getAppName,\n getAppTitle,\n getDynamicPathSegmentName,\n isDynamicPathSegment,\n isPathSegmentGroup\n} from \"./plugin-utils/context-helpers\";\nimport { getCommandTree } from \"./plugin-utils/get-command-tree\";\nimport { traverseCommands } from \"./plugin-utils/traverse-command-tree\";\nimport { resolve } from \"./resolver/resolve\";\nimport type { CommandOption, CommandTree } from \"./types/command\";\nimport type { Options } from \"./types/config\";\nimport type { Context } from \"./types/context\";\n\nconst MAX_DEPTH = 50;\n\n/**\n * The core Powerlines plugin to build Shell Shock projects.\n */\nexport const plugin = <TContext extends Context = Context>(\n options: Options = {}\n): Plugin<TContext>[] => {\n return [\n tsdown<TContext>(),\n automd<TContext>(),\n {\n name: \"shell-shock:config\",\n async config() {\n this.debug(\"Resolving the Shell Shock configuration.\");\n\n await updatePackageJsonBinary(this);\n\n const result = defu(\n {\n output: {\n path: joinPaths(this.config.root, \"dist\")\n }\n },\n options,\n {\n name: getAppName(this),\n title: getAppTitle(this),\n description: getAppDescription(this),\n platform: \"node\",\n projectType: \"application\",\n framework: \"shell-shock\",\n isCaseSensitive: false,\n output: {\n format: \"esm\",\n dts: false\n },\n input:\n !this.config.input ||\n (Array.isArray(this.config.input) &&\n this.config.input.length === 0) ||\n (isObject(this.config.input) &&\n Object.keys(this.config.input).length === 0)\n ? [\n joinPaths(this.config.root, \"src/**/command.ts\"),\n joinPaths(this.config.root, \"src/**/command.tsx\")\n ]\n : undefined,\n resolve: {\n external: [\"@powerlines/deepkit\"],\n skipNodeModulesBundle: true\n },\n tsdown: {\n dts: false,\n nodeProtocol: true,\n unbundle: false\n }\n }\n );\n\n return result;\n },\n configResolved: {\n order: \"pre\",\n async handler() {\n this.debug(\"Shell Shock configuration has been resolved.\");\n\n this.config.appSpecificEnvPrefix = isSetString(\n this.config.autoAssignEnv\n )\n ? this.config.autoAssignEnv\n : constantCase(getAppName(this));\n if (\n !this.config.env.prefix ||\n !Array.isArray(this.config.env.prefix)\n ) {\n this.config.env.prefix = toArray(this.config.env.prefix);\n }\n\n if (\n !this.config.env.prefix.includes(this.config.appSpecificEnvPrefix)\n ) {\n this.config.env.prefix.push(this.config.appSpecificEnvPrefix);\n }\n\n this.config.bin = (isSetString(this.packageJson.bin)\n ? { [kebabCase(this.config.name)]: this.packageJson.bin }\n : this.packageJson.bin) ?? {\n [kebabCase(this.config.name)]: formatBinaryPath(\n this.config.output.format\n )\n };\n\n if (isSetString(this.config.reference)) {\n if (this.config.reference.includes(\"{command}\")) {\n this.config.reference = {\n app: this.config.reference\n .substring(0, this.config.reference.indexOf(\"{command}\"))\n .replace(/\\/?$/, \"/\"),\n commands: this.config.reference\n };\n } else if (this.config.reference.includes(\"{commands}\")) {\n this.config.reference = {\n app: this.config.reference\n .substring(0, this.config.reference.indexOf(\"{commands}\"))\n .replace(/\\/?$/, \"/\"),\n commands: this.config.reference\n };\n } else {\n this.config.reference = {\n app: this.config.reference\n };\n }\n }\n\n this.inputs ??= [];\n this.options = Object.values(\n getGlobalOptions(this, {\n id: null,\n name: this.config.name,\n path: null,\n segments: [],\n title: this.config.title,\n description: this.config.description,\n alias: [],\n isVirtual: false\n })\n );\n\n this.options = this.options.map(\n option =>\n ({\n ...option,\n name: camelCase(option.name),\n alias: option.alias ?? [],\n optional: option.optional ?? false\n }) as CommandOption\n );\n }\n }\n },\n ...nodejs<TContext>(\n defu(options ?? {}, {\n env: {\n types: \"@shell-shock/core/types/env#ShellShockEnv\",\n validate: false\n }\n })\n ),\n {\n name: \"shell-shock:inputs\",\n async configResolved() {\n this.debug(\"Finding command entry point files.\");\n\n this.debug(\n `Checking for commands using input: ${JSON.stringify(this.config.input)}`\n );\n\n this.commandsPath = await findCommandsRoot(this);\n this.debug(`Resolved commands root path: ${this.commandsPath}`);\n\n const inputs = await resolveInputs(this, this.config.input);\n\n this.debug(\n `Found ${\n inputs.length\n } entry points specified in the configuration options.`\n );\n\n this.inputs = inputs.reduce((ret, entry) => {\n if (\n entry.file !== this.commandsPath &&\n !isParentPath(entry.file, this.commandsPath)\n ) {\n throw new Error(\n `Command entry point \"${\n entry.file\n }\" is not located within the commands root \"${\n this.commandsPath\n }\". Please ensure that all command entry points are located within the current project.`\n );\n }\n\n const id = resolveCommandId(this, entry.file);\n if (!ret.some(existing => existing.id === id)) {\n const name = resolveCommandName(entry.file);\n let segments = resolveCommandPath(this, entry.file)\n .split(\"/\")\n .filter(Boolean);\n\n // Ensure unique segment names by appending an index suffix to duplicates\n segments = segments.map((segment, index) => {\n const found = segments.findIndex(\n existing => existing === segment\n );\n if (found !== -1 && found !== index) {\n segment += `_${\n segments.filter(\n segment =>\n isDynamicPathSegment(segment) &&\n getDynamicPathSegmentName(segment).replace(\n /_\\d+$/,\n \"\"\n ) === segment\n ).length\n }`;\n }\n\n return segment;\n });\n\n ret.push({\n id,\n path: segments.join(\"/\"),\n segments,\n name,\n alias: [],\n tags: [],\n isVirtual: false,\n source: \"file\",\n entry: {\n ...entry,\n file: entry.file,\n input: {\n file: entry.file,\n name: entry.name\n },\n output: name\n }\n });\n }\n\n return ret;\n }, this.inputs);\n\n this.debug(\n `Shell Shock will process ${\n this.inputs.length\n } command entry files: \\n${this.inputs\n .map(\n command =>\n ` - ${command.id}: ${replacePath(\n command.entry.file,\n this.commandsPath\n )}`\n )\n .join(\"\\n\")}`\n );\n },\n async prepare() {\n this.debug(\n \"Rendering base built-in modules for the Shell Shock application.\"\n );\n\n return render(\n this,\n <>\n <StateBuiltin />\n <UtilsBuiltin />\n <ExecBuiltin />\n </>\n );\n }\n },\n {\n name: \"shell-shock:virtual-inputs\",\n configResolved: {\n order: \"post\",\n async handler() {\n if (this.inputs.length === 0) {\n this.warn(\n \"No commands were found in the project. Please ensure at least one command exists.\"\n );\n } else {\n this.debug(\n \"Finding and adding virtual command inputs for each command previously found.\"\n );\n\n this.inputs = this.inputs\n .reduce((ret, command) => {\n let depth = 0;\n\n let parentPath = resolveParentPath(\n findFilePath(command.entry.file)\n );\n if (isParentPath(parentPath, this.commandsPath)) {\n while (parentPath !== this.commandsPath) {\n if (depth++ > MAX_DEPTH) {\n throw new Error(\n `Unable to process virtual commands for ${\n command.name\n } \\n\\nPlease ensure ${\n command.entry.file\n } is a valid command entry file and does not have an invalid path.`\n );\n }\n\n if (\n !ret.some(\n existing =>\n findFilePath(existing.entry.file) === parentPath\n )\n ) {\n const file = joinPaths(parentPath, \"command.ts\");\n const id = resolveCommandId(this, file);\n if (!ret.some(existing => existing.id === id)) {\n const name = resolveCommandName(file);\n\n let segments = resolveCommandPath(this, file)\n .split(\"/\")\n .filter(Boolean);\n\n // Ensure unique segment names by appending an index suffix to duplicates\n segments = segments.map((segment, index) => {\n const found = segments.findIndex(\n existing => existing === segment\n );\n if (found !== -1 && found !== index) {\n segment += `_${\n segments.filter(\n segment =>\n isDynamicPathSegment(segment) &&\n getDynamicPathSegmentName(segment).replace(\n /_\\d+$/,\n \"\"\n ) === segment\n ).length\n }`;\n }\n\n return segment;\n });\n\n ret.push({\n id,\n path: segments.join(\"/\"),\n segments,\n name,\n alias: [],\n tags: [],\n isVirtual: true,\n entry: {\n file\n },\n source: \"file\"\n });\n }\n }\n\n parentPath = resolveParentPath(parentPath);\n }\n }\n\n return ret;\n }, this.inputs)\n .sort((a, b) => a.segments.length - b.segments.length);\n\n this.debug(\n `Final command input list: \\n${this.inputs\n .map(\n command =>\n ` - ${command.id}${command.isVirtual ? \" (virtual)\" : \"\"}: ${\n command.source === \"file\"\n ? replacePath(command.entry.file, this.commandsPath)\n : `added by ${command.source}`\n }`\n )\n .join(\"\\n\")}`\n );\n }\n }\n }\n },\n {\n name: \"shell-shock:resolve-commands\",\n prepare: {\n order: \"post\",\n async handler() {\n this.debug(\"Initializing the CLI application's command tree.\");\n\n this.commands = {};\n if (\n this.config.command !== \"prepare\" &&\n this.config.skipCache !== true &&\n this.persistedMeta?.checksum === this.meta.checksum &&\n this.fs.existsSync(getCommandsPersistencePath(this))\n ) {\n this.debug(\n `Skipping command resolution as the meta checksum has not changed.`\n );\n\n await readCommandsPersistence(this);\n } else {\n for (const input of this.inputs.filter(\n input =>\n input.segments.filter(\n segment =>\n !isDynamicPathSegment(segment) &&\n !isPathSegmentGroup(segment)\n ).length === 1\n )) {\n this.commands[input.name] = await resolve({\n context: this,\n command: input\n });\n }\n\n this.debug(\"Post-processing commands to ensure proper reflection.\");\n\n await traverseCommands(this, command => {\n command.options = Object.fromEntries(\n Object.entries(command.options).map(([name, option]) => [\n camelCase(name),\n {\n ...option,\n name: camelCase(name),\n alias: option.alias ?? [],\n optional: option.optional ?? false\n } as CommandOption\n ])\n );\n });\n\n await writeCommandsPersistence(this);\n }\n\n this.debug(\"Validating the CLI applications command tree.\");\n\n let isValid = true;\n await traverseCommands(this, command => {\n const failures = validateCommand(command);\n if (failures.length > 0) {\n this.error(\n `Found ${failures.length} issue${failures.length > 1 ? \"s\" : \"\"} with the ${\n command.title\n } command: \\n${failures\n .map(failure => ` - ${failure.code}: ${failure.details}`)\n .join(\"\\n\")}\\n`\n );\n isValid = false;\n }\n });\n if (!isValid) {\n throw new Error(\n `One or more commands in the command tree are invalid. Please review the errors above and correct them before proceeding.`\n );\n }\n\n this.info(\n `\\nCreating an application with the following command tree: \\n${formatCommandTree(\n this\n )}\\n`\n );\n }\n }\n },\n {\n name: \"shell-shock:chmod+x\",\n configResolved() {\n this.config.tsdown.hooks ??= {} as TsdownHooks;\n (this.config.tsdown.hooks as TsdownHooks)[\"build:done\"] = async (\n _: BuildContext & {\n chunks: RolldownChunk[];\n }\n ) => {\n await Promise.all(\n Object.values(this.config.bin).map(async bin => {\n const path = appendPath(\n bin,\n joinPaths(this.workspaceConfig.workspaceRoot, this.config.root)\n );\n if (this.fs.existsSync(path)) {\n this.debug(\n `Adding hashbang to binary executable output file: ${path}`\n );\n\n const content = await this.fs.read(path);\n if (content && !content.startsWith(\"#!\")) {\n await this.fs.write(\n path,\n `#!/usr/bin/env ${\n this.config.mode === \"development\"\n ? \"-S NODE_OPTIONS=--enable-source-maps\"\n : \"\"\n } node\\n\\n${content}`\n );\n }\n\n this.debug(\n `Adding executable permissions (chmod+x) to binary executable output file: ${\n path\n }`\n );\n\n await chmodX(path);\n } else {\n this.warn(\n `Expected binary output file not found at path: ${\n path\n }. Skipping adding hashbang and executable permissions (chmod+x).`\n );\n }\n })\n );\n };\n }\n },\n {\n name: \"shell-shock:docs\",\n configResolved() {\n this.config.automd ??= {};\n this.config.automd.generators = {\n ...(this.config.automd.generators ?? {}),\n commands: commands(this)\n };\n },\n async docs() {\n this.debug(\n \"Rendering entrypoint modules for the Shell Shock `script` preset.\"\n );\n\n const commands = this.inputs\n .map(input => getCommandTree(this, input.segments))\n .filter(Boolean) as CommandTree[];\n\n return render(\n this,\n <For each={Object.values(commands)} doubleHardline>\n {child => (\n <Show when={!child.isVirtual}>\n <CommandDocsFile command={child} />\n </Show>\n )}\n </For>\n );\n }\n }\n ];\n};\n\nexport default plugin;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"plugin.mjs","names":[],"sources":["../src/plugin.tsx"],"sourcesContent":["/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Shell Shock\n\n This code was released as part of the Shell Shock project. Shell Shock\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/shell-shock.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/shell-shock\n Documentation: https://docs.stormsoftware.com/projects/shell-shock\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport { For, Show } from \"@alloy-js/core/components\";\nimport { render } from \"@powerlines/plugin-alloy/render\";\nimport automd from \"@powerlines/plugin-automd\";\nimport nodejs from \"@powerlines/plugin-nodejs\";\nimport tsdown from \"@powerlines/plugin-tsdown\";\nimport { toArray } from \"@stryke/convert/to-array\";\nimport { chmodX } from \"@stryke/fs/chmod-x\";\nimport { appendPath } from \"@stryke/path/append\";\nimport { findFilePath } from \"@stryke/path/file-path-fns\";\nimport { isParentPath } from \"@stryke/path/is-parent-path\";\nimport { joinPaths } from \"@stryke/path/join-paths\";\nimport { replacePath } from \"@stryke/path/replace\";\nimport { resolveParentPath } from \"@stryke/path/resolve-parent-path\";\nimport { camelCase } from \"@stryke/string-format/camel-case\";\nimport { constantCase } from \"@stryke/string-format/constant-case\";\nimport { kebabCase } from \"@stryke/string-format/kebab-case\";\nimport { isObject } from \"@stryke/type-checks/is-object\";\nimport { isSetString } from \"@stryke/type-checks/is-set-string\";\nimport { defu } from \"defu\";\nimport type { Plugin } from \"powerlines\";\nimport { resolveInputs } from \"powerlines/utils\";\nimport type { BuildContext, RolldownChunk, TsdownHooks } from \"tsdown\";\nimport { CommandDocsFile } from \"./components/docs\";\nimport { ExecBuiltin } from \"./components/exec-builtin\";\nimport { StateBuiltin } from \"./components/state-builtin\";\nimport { UtilsBuiltin } from \"./components/utils-builtin\";\nimport { commands } from \"./helpers/automd\";\nimport {\n findCommandsRoot,\n resolveCommandId,\n resolveCommandName,\n resolveCommandPath\n} from \"./helpers/paths\";\nimport {\n getCommandsPersistencePath,\n readCommandsPersistence,\n writeCommandsPersistence\n} from \"./helpers/persistence\";\nimport {\n formatBinaryPath,\n updatePackageJsonBinary\n} from \"./helpers/update-package-json\";\nimport { formatCommandTree, getGlobalOptions } from \"./helpers/utilities\";\nimport { validateCommand } from \"./helpers/validations\";\nimport {\n getAppDescription,\n getAppName,\n getAppTitle,\n getDynamicPathSegmentName,\n isDynamicPathSegment,\n isPathSegmentGroup\n} from \"./plugin-utils/context-helpers\";\nimport { getCommandTree } from \"./plugin-utils/get-command-tree\";\nimport { traverseCommands } from \"./plugin-utils/traverse-command-tree\";\nimport { resolve } from \"./resolver/resolve\";\nimport type { CommandOption, CommandTree } from \"./types/command\";\nimport type { Options } from \"./types/config\";\nimport type { Context } from \"./types/context\";\n\nconst MAX_DEPTH = 50;\n\n/**\n * The core Powerlines plugin to build Shell Shock projects.\n */\nexport const plugin = <TContext extends Context = Context>(\n options: Options = {}\n): Plugin<TContext>[] => {\n return [\n tsdown<TContext>(),\n automd<TContext>(),\n {\n name: \"shell-shock:config\",\n async config() {\n this.debug(\"Resolving the Shell Shock configuration.\");\n\n await updatePackageJsonBinary(this);\n\n const result = defu(\n {\n output: {\n path: joinPaths(this.config.root, \"dist\")\n }\n },\n options,\n {\n name: getAppName(this),\n title: getAppTitle(this),\n description: getAppDescription(this),\n platform: \"node\",\n projectType: \"application\",\n framework: \"shell-shock\",\n isCaseSensitive: false,\n output: {\n format: \"esm\",\n dts: false\n },\n input:\n !this.config.input ||\n (Array.isArray(this.config.input) &&\n this.config.input.length === 0) ||\n (isObject(this.config.input) &&\n Object.keys(this.config.input).length === 0)\n ? [\n joinPaths(this.config.root, \"src/**/command.ts\"),\n joinPaths(this.config.root, \"src/**/command.tsx\")\n ]\n : undefined,\n resolve: {\n external: [\"@powerlines/deepkit\"],\n skipNodeModulesBundle: true\n },\n tsdown: {\n dts: false,\n nodeProtocol: true,\n unbundle: false\n }\n }\n );\n\n return result;\n },\n configResolved: {\n order: \"pre\",\n async handler() {\n this.debug(\"Shell Shock configuration has been resolved.\");\n\n this.config.appSpecificEnvPrefix = isSetString(\n this.config.autoAssignEnv\n )\n ? this.config.autoAssignEnv\n : constantCase(getAppName(this));\n if (\n !this.config.env.prefix ||\n !Array.isArray(this.config.env.prefix)\n ) {\n this.config.env.prefix = toArray(this.config.env.prefix);\n }\n\n if (\n !this.config.env.prefix.includes(this.config.appSpecificEnvPrefix)\n ) {\n this.config.env.prefix.push(this.config.appSpecificEnvPrefix);\n }\n\n this.config.bin = (isSetString(this.packageJson.bin)\n ? { [kebabCase(this.config.name)]: this.packageJson.bin }\n : this.packageJson.bin) ?? {\n [kebabCase(this.config.name)]: formatBinaryPath(\n this.config.output.format\n )\n };\n\n if (isSetString(this.config.reference)) {\n if (this.config.reference.includes(\"{command}\")) {\n this.config.reference = {\n app: this.config.reference\n .substring(0, this.config.reference.indexOf(\"{command}\"))\n .replace(/\\/?$/, \"/\"),\n commands: this.config.reference\n };\n } else if (this.config.reference.includes(\"{commands}\")) {\n this.config.reference = {\n app: this.config.reference\n .substring(0, this.config.reference.indexOf(\"{commands}\"))\n .replace(/\\/?$/, \"/\"),\n commands: this.config.reference\n };\n } else {\n this.config.reference = {\n app: this.config.reference\n };\n }\n }\n\n this.inputs ??= [];\n this.options = Object.values(\n getGlobalOptions(this, {\n id: null,\n name: this.config.name,\n path: null,\n segments: [],\n title: this.config.title,\n description: this.config.description,\n alias: [],\n isVirtual: false\n })\n );\n\n this.options = this.options.map(\n option =>\n ({\n ...option,\n name: camelCase(option.name),\n alias: option.alias ?? [],\n optional: option.optional ?? false\n }) as CommandOption\n );\n }\n }\n },\n ...nodejs<TContext>(\n defu(options ?? {}, {\n env: {\n types: \"@shell-shock/core/types/env#ShellShockEnv\",\n validate: false\n }\n })\n ),\n {\n name: \"shell-shock:inputs\",\n async configResolved() {\n this.debug(\"Finding command entry point files.\");\n\n this.debug(\n `Checking for commands using input: ${JSON.stringify(this.config.input)}`\n );\n\n this.commandsPath = await findCommandsRoot(this);\n this.debug(`Resolved commands root path: ${this.commandsPath}`);\n\n const inputs = await resolveInputs(this, this.config.input);\n\n this.debug(\n `Found ${\n inputs.length\n } entry points specified in the configuration options.`\n );\n\n this.inputs = inputs.reduce((ret, entry) => {\n if (\n entry.file !== this.commandsPath &&\n !isParentPath(entry.file, this.commandsPath)\n ) {\n throw new Error(\n `Command entry point \"${\n entry.file\n }\" is not located within the commands root \"${\n this.commandsPath\n }\". Please ensure that all command entry points are located within the current project.`\n );\n }\n\n const id = resolveCommandId(this, entry.file);\n if (!ret.some(existing => existing.id === id)) {\n const name = resolveCommandName(entry.file);\n let segments = resolveCommandPath(this, entry.file)\n .split(\"/\")\n .filter(Boolean);\n\n // Ensure unique segment names by appending an index suffix to duplicates\n segments = segments.map((segment, index) => {\n const found = segments.findIndex(\n existing => existing === segment\n );\n if (found !== -1 && found !== index) {\n segment += `_${\n segments.filter(\n segment =>\n isDynamicPathSegment(segment) &&\n getDynamicPathSegmentName(segment).replace(\n /_\\d+$/,\n \"\"\n ) === segment\n ).length\n }`;\n }\n\n return segment;\n });\n\n ret.push({\n id,\n path: segments.join(\"/\"),\n segments,\n name,\n alias: [],\n tags: [],\n isVirtual: false,\n source: \"file\",\n entry: {\n ...entry,\n file: entry.file,\n input: {\n file: entry.file,\n name: entry.name\n },\n output: name\n }\n });\n }\n\n return ret;\n }, this.inputs);\n\n this.debug(\n `Shell Shock will process ${\n this.inputs.length\n } command entry files: \\n${this.inputs\n .map(\n command =>\n ` - ${command.id}: ${replacePath(\n command.entry.file,\n this.commandsPath\n )}`\n )\n .join(\"\\n\")}`\n );\n },\n async prepare() {\n this.debug(\n \"Rendering base built-in modules for the Shell Shock application.\"\n );\n\n return render(\n this,\n <>\n <StateBuiltin />\n <UtilsBuiltin />\n <ExecBuiltin />\n </>\n );\n }\n },\n {\n name: \"shell-shock:virtual-inputs\",\n configResolved: {\n order: \"post\",\n async handler() {\n if (this.inputs.length === 0) {\n this.warn(\n \"No commands were found in the project. Please ensure at least one command exists.\"\n );\n } else {\n this.debug(\n \"Finding and adding virtual command inputs for each command previously found.\"\n );\n\n this.inputs = this.inputs\n .reduce((ret, command) => {\n let depth = 0;\n\n let parentPath = resolveParentPath(\n findFilePath(command.entry.file)\n );\n if (isParentPath(parentPath, this.commandsPath)) {\n while (parentPath !== this.commandsPath) {\n if (depth++ > MAX_DEPTH) {\n throw new Error(\n `Unable to process virtual commands for ${\n command.name\n } \\n\\nPlease ensure ${\n command.entry.file\n } is a valid command entry file and does not have an invalid path.`\n );\n }\n\n if (\n !ret.some(\n existing =>\n findFilePath(existing.entry.file) === parentPath\n )\n ) {\n const file = joinPaths(parentPath, \"command.ts\");\n const id = resolveCommandId(this, file);\n if (!ret.some(existing => existing.id === id)) {\n const name = resolveCommandName(file);\n\n let segments = resolveCommandPath(this, file)\n .split(\"/\")\n .filter(Boolean);\n\n // Ensure unique segment names by appending an index suffix to duplicates\n segments = segments.map((segment, index) => {\n const found = segments.findIndex(\n existing => existing === segment\n );\n if (found !== -1 && found !== index) {\n segment += `_${\n segments.filter(\n segment =>\n isDynamicPathSegment(segment) &&\n getDynamicPathSegmentName(segment).replace(\n /_\\d+$/,\n \"\"\n ) === segment\n ).length\n }`;\n }\n\n return segment;\n });\n\n ret.push({\n id,\n path: segments.join(\"/\"),\n segments,\n name,\n alias: [],\n tags: [],\n isVirtual: true,\n entry: {\n file\n },\n source: \"file\"\n });\n }\n }\n\n parentPath = resolveParentPath(parentPath);\n }\n }\n\n return ret;\n }, this.inputs)\n .sort((a, b) => a.segments.length - b.segments.length);\n\n this.debug(\n `Final command input list: \\n${this.inputs\n .map(\n command =>\n ` - ${command.id}${command.isVirtual ? \" (virtual)\" : \"\"}: ${\n command.source === \"file\"\n ? replacePath(command.entry.file, this.commandsPath)\n : `added by ${command.source}`\n }`\n )\n .join(\"\\n\")}`\n );\n }\n }\n }\n },\n {\n name: \"shell-shock:resolve-commands\",\n prepare: {\n order: \"post\",\n async handler() {\n this.debug(\"Initializing the CLI application's command tree.\");\n\n this.commands = {};\n if (\n this.config.command !== \"prepare\" &&\n this.config.skipCache !== true &&\n this.persistedMeta?.checksum === this.meta.checksum &&\n this.fs.existsSync(getCommandsPersistencePath(this))\n ) {\n this.debug(\n `Skipping command resolution as the meta checksum has not changed.`\n );\n\n await readCommandsPersistence(this);\n } else {\n for (const input of this.inputs.filter(\n input =>\n input.segments.filter(\n segment =>\n !isDynamicPathSegment(segment) &&\n !isPathSegmentGroup(segment)\n ).length === 1\n )) {\n this.commands[input.name] = await resolve({\n context: this,\n command: input\n });\n }\n\n this.debug(\"Post-processing commands to ensure proper reflection.\");\n\n await traverseCommands(this, command => {\n command.options = Object.fromEntries(\n Object.entries(command.options).map(([name, option]) => [\n camelCase(name),\n {\n ...option,\n name: camelCase(name),\n alias: option.alias ?? [],\n optional: option.optional ?? false\n } as CommandOption\n ])\n );\n });\n\n await writeCommandsPersistence(this);\n }\n\n this.debug(\"Validating the CLI applications command tree.\");\n\n let isValid = true;\n await traverseCommands(this, command => {\n const failures = validateCommand(command);\n if (failures.length > 0) {\n this.error(\n `Found ${failures.length} issue${failures.length > 1 ? \"s\" : \"\"} with the ${\n command.title\n } command: \\n${failures\n .map(failure => ` - ${failure.code}: ${failure.details}`)\n .join(\"\\n\")}\\n`\n );\n isValid = false;\n }\n });\n if (!isValid) {\n throw new Error(\n `One or more commands in the command tree are invalid. Please review the errors above and correct them before proceeding.`\n );\n }\n\n this.info(\n `\\nCreating an application with the following command tree: \\n${formatCommandTree(\n this\n )}\\n`\n );\n }\n }\n },\n {\n name: \"shell-shock:chmod+x\",\n configResolved() {\n this.config.tsdown.hooks ??= {} as TsdownHooks;\n (this.config.tsdown.hooks as TsdownHooks)[\"build:done\"] = async (\n _: BuildContext & {\n chunks: RolldownChunk[];\n }\n ) => {\n await Promise.all(\n Object.values(this.config.bin).map(async bin => {\n const path = appendPath(\n bin,\n joinPaths(this.workspaceConfig.workspaceRoot, this.config.root)\n );\n if (this.fs.existsSync(path)) {\n this.debug(\n `Adding hashbang to binary executable output file: ${path}`\n );\n\n const content = await this.fs.read(path);\n if (content && !content.startsWith(\"#!\")) {\n await this.fs.write(\n path,\n `#!/usr/bin/env ${\n this.config.mode === \"development\"\n ? \"-S NODE_OPTIONS=--enable-source-maps\"\n : \"\"\n } node\\n\\n${content}`\n );\n }\n\n this.debug(\n `Adding executable permissions (chmod+x) to binary executable output file: ${\n path\n }`\n );\n\n await chmodX(path);\n } else {\n this.warn(\n `Expected binary output file not found at path: ${\n path\n }. Skipping adding hashbang and executable permissions (chmod+x).`\n );\n }\n })\n );\n };\n }\n },\n {\n name: \"shell-shock:docs\",\n configResolved() {\n this.config.automd ??= {};\n this.config.automd.generators = {\n ...(this.config.automd.generators ?? {}),\n commands: commands(this)\n };\n },\n async docs() {\n this.debug(\n \"Rendering entrypoint modules for the Shell Shock `script` preset.\"\n );\n\n const commands = this.inputs\n .map(input => getCommandTree(this, input.segments))\n .filter(Boolean) as CommandTree[];\n\n return render(\n this,\n <For each={Object.values(commands)} doubleHardline>\n {child => (\n <Show when={!child.isVirtual}>\n <CommandDocsFile command={child} />\n </Show>\n )}\n </For>\n );\n }\n }\n ];\n};\n\nexport default plugin;\n"],"mappings":"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"}
|
|
@@ -73,7 +73,7 @@ function resolveCommandArgument(ctx, index, reflection) {
|
|
|
73
73
|
title: reflection.getTitle() || reflection.parameter.tags?.title,
|
|
74
74
|
description: reflection.parameter.description,
|
|
75
75
|
optional: reflection.isOptional(),
|
|
76
|
-
default: reflection.getDefaultValue()
|
|
76
|
+
default: reflection.getDefaultValue() || reflection.parameter.default
|
|
77
77
|
};
|
|
78
78
|
if (type.kind === _powerlines_deepkit_vendor_type.ReflectionKind.array) if (type.type.kind === _powerlines_deepkit_vendor_type.ReflectionKind.string || type.type.kind === _powerlines_deepkit_vendor_type.ReflectionKind.number) {
|
|
79
79
|
argument.variadic = true;
|
|
@@ -72,7 +72,7 @@ function resolveCommandArgument(ctx, index, reflection) {
|
|
|
72
72
|
title: reflection.getTitle() || reflection.parameter.tags?.title,
|
|
73
73
|
description: reflection.parameter.description,
|
|
74
74
|
optional: reflection.isOptional(),
|
|
75
|
-
default: reflection.getDefaultValue()
|
|
75
|
+
default: reflection.getDefaultValue() || reflection.parameter.default
|
|
76
76
|
};
|
|
77
77
|
if (type.kind === ReflectionKind.array) if (type.type.kind === ReflectionKind.string || type.type.kind === ReflectionKind.number) {
|
|
78
78
|
argument.variadic = true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deepkit.mjs","names":[],"sources":["../../src/resolver/deepkit.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Shell Shock\n\n This code was released as part of the Shell Shock project. Shell Shock\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/shell-shock.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/shell-shock\n Documentation: https://docs.stormsoftware.com/projects/shell-shock\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport type {\n ReflectionParameter,\n ReflectionProperty,\n Type,\n TypeArray\n} from \"@powerlines/deepkit/vendor/type\";\nimport {\n reflect,\n ReflectionClass,\n ReflectionFunction,\n ReflectionKind,\n stringifyType\n} from \"@powerlines/deepkit/vendor/type\";\nimport { isBigInt } from \"@stryke/type-checks/is-bigint\";\nimport { isNumber } from \"@stryke/type-checks/is-number\";\nimport { isRegExp } from \"@stryke/type-checks/is-regexp\";\nimport { isSetObject } from \"@stryke/type-checks/is-set-object\";\nimport type {\n CommandArgument,\n CommandOption,\n CommandParameterKind,\n Context,\n NumberCommandParameter,\n StringCommandParameter\n} from \"../types\";\nimport { CommandParameterKinds } from \"../types\";\nimport { mergeCommandParameter } from \"./helpers\";\nimport type { ResolverContext } from \"./types\";\n\nfunction extractCommandParameterKind(\n type: Type | ReflectionKind\n): CommandParameterKind {\n const isKind = !(isSetObject(type) && \"kind\" in type);\n const kind = !isKind ? type.kind : type;\n if (kind === ReflectionKind.string) {\n return CommandParameterKinds.string;\n } else if (\n kind === ReflectionKind.number ||\n kind === ReflectionKind.bigint ||\n (!isKind &&\n type.kind === ReflectionKind.literal &&\n (isNumber(type.literal) || isBigInt(type.literal)))\n ) {\n return CommandParameterKinds.number;\n } else if (kind === ReflectionKind.boolean) {\n return CommandParameterKinds.boolean;\n } else {\n return CommandParameterKinds.string;\n }\n}\n\nfunction resolveCommandOption(\n ctx: ResolverContext,\n reflection: ReflectionProperty\n): CommandOption {\n const type = reflection.getType();\n const existing = (ctx.output.options[reflection.getNameAsString()] ??\n {}) as Partial<CommandOption>;\n\n const option = {\n name: reflection.getNameAsString(),\n alias: reflection.getTags().alias ?? [],\n title: reflection.getTags().title?.trim(),\n description: reflection.getDescription(),\n kind: extractCommandParameterKind(type),\n optional: reflection.isOptional(),\n default: reflection.getDefaultValue(),\n variadic: reflection.isArray()\n };\n\n if (option.variadic) {\n option.kind = extractCommandParameterKind((type as TypeArray).type.kind);\n } else if (type.kind === ReflectionKind.union) {\n option.kind = type.types.every(\n t =>\n t.kind === ReflectionKind.number ||\n (t.kind === ReflectionKind.literal &&\n (isNumber(t.literal) || isBigInt(t.literal)))\n )\n ? CommandParameterKinds.number\n : CommandParameterKinds.string;\n\n (option as StringCommandParameter | NumberCommandParameter).choices =\n type.types\n .map(t =>\n t.kind === ReflectionKind.literal\n ? isNumber(t.literal)\n ? t.literal\n : isBigInt(t.literal)\n ? Number(t.literal)\n : isRegExp(t.literal)\n ? t.literal.source\n : String(t.literal)\n : null\n )\n .filter(Boolean) as string[] | number[];\n } else if (type.kind === ReflectionKind.literal) {\n (option as StringCommandParameter | NumberCommandParameter).choices = [\n isNumber(type.literal)\n ? type.literal\n : isBigInt(type.literal)\n ? Number(type.literal)\n : isRegExp(type.literal)\n ? type.literal.source\n : String(type.literal)\n ].filter(Boolean) as string[] | number[];\n } else if (\n !existing.kind &&\n type.kind !== ReflectionKind.boolean &&\n type.kind !== ReflectionKind.string &&\n type.kind !== ReflectionKind.number\n ) {\n throw new Error(\n `Unsupported type for option \"${reflection.getNameAsString()}\" in command \"${\n ctx.input.command.name\n }\". Only string, number, boolean, string[], number[], or literal[] are supported, received ${stringifyType(\n type\n )\n .trim()\n .replaceAll(\" | \", \", or \")}.`\n );\n }\n\n return mergeCommandParameter(existing, option) as CommandOption;\n}\n\nfunction resolveCommandArgument(\n ctx: ResolverContext,\n index: number,\n reflection: ReflectionParameter\n): CommandArgument {\n const type = reflection.getType();\n const existing = (\n ctx.output.args.length > index ? ctx.output.args[index] : {}\n ) as Partial<CommandArgument>;\n\n const argument = {\n name: reflection.getName() || reflection.parameter.name,\n alias: reflection.getAlias(),\n kind: extractCommandParameterKind(type.kind),\n title: reflection.getTitle() || reflection.parameter.tags?.title,\n description: reflection.parameter.description,\n optional: reflection.isOptional(),\n default: reflection.getDefaultValue()\n };\n\n if (type.kind === ReflectionKind.array) {\n if (\n type.type.kind === ReflectionKind.string ||\n type.type.kind === ReflectionKind.number\n ) {\n (argument as StringCommandParameter | NumberCommandParameter).variadic =\n true;\n (argument as StringCommandParameter | NumberCommandParameter).kind =\n extractCommandParameterKind(type.type.kind) as \"string\" | \"number\";\n } else {\n throw new Error(\n `Unsupported array type for positional argument \"${argument.name}\" in command \"${\n ctx.input.command.name\n }\". Only string[], number[], or literal[] are supported, received ${stringifyType(\n type\n )\n .trim()\n .replaceAll(\" | \", \", or \")}.`\n );\n }\n } else if (type.kind === ReflectionKind.union) {\n argument.kind = type.types.every(\n t =>\n t.kind === ReflectionKind.number ||\n (t.kind === ReflectionKind.literal &&\n (isNumber(t.literal) || isBigInt(t.literal)))\n )\n ? CommandParameterKinds.number\n : CommandParameterKinds.string;\n\n (argument as StringCommandParameter | NumberCommandParameter).choices =\n type.types\n .map(t =>\n t.kind === ReflectionKind.literal\n ? isNumber(t.literal)\n ? t.literal\n : isBigInt(t.literal)\n ? Number(t.literal)\n : isRegExp(t.literal)\n ? t.literal.source\n : String(t.literal)\n : null\n )\n .filter(Boolean) as string[] | number[];\n } else if (type.kind === ReflectionKind.literal) {\n (argument as StringCommandParameter | NumberCommandParameter).choices = [\n isNumber(type.literal)\n ? type.literal\n : isBigInt(type.literal)\n ? Number(type.literal)\n : isRegExp(type.literal)\n ? type.literal.source\n : String(type.literal)\n ].filter(Boolean) as string[] | number[];\n } else if (\n !ctx.output.args?.length &&\n type.kind !== ReflectionKind.boolean &&\n type.kind !== ReflectionKind.string &&\n type.kind !== ReflectionKind.number\n ) {\n throw new Error(\n `Unsupported type for positional argument \"${argument.name}\" in command \"${\n ctx.input.command.name\n }\". Only string, number, boolean, string[], number[], or literal[] are supported, received ${stringifyType(\n type\n )\n .trim()\n .replaceAll(\" | \", \", or \")}.`\n );\n }\n\n return mergeCommandParameter(existing, argument, {\n name: `arg${index}`\n }) as CommandArgument;\n}\n\nexport function resolveFromBytecode<TContext extends Context = Context>(\n ctx: ResolverContext<TContext>\n) {\n const { input, module } = ctx;\n\n const type = reflect(module);\n if (type.kind !== ReflectionKind.function) {\n throw new Error(\n `The command entry file \"${\n input.command.entry.input?.file || input.command.path\n }\" does not export a valid function.`\n );\n }\n\n const reflection = new ReflectionFunction(type);\n\n ctx.output.description ??= (ctx.input.command.description ||\n reflection.getDescription() ||\n type.description)!;\n\n const parameters = reflection.getParameters();\n if (parameters.length > 0) {\n const hasOptions =\n parameters[0] &&\n (parameters[0].type.kind === ReflectionKind.objectLiteral ||\n parameters[0].type.kind === ReflectionKind.class);\n if (hasOptions) {\n const optionsReflection = ReflectionClass.from(parameters[0]?.type);\n for (const propertyReflection of optionsReflection.getProperties()) {\n ctx.output.options[propertyReflection.getNameAsString()] =\n resolveCommandOption(ctx, propertyReflection);\n }\n }\n\n ctx.output.args = (hasOptions ? parameters.slice(1) : parameters).map(\n (arg, index) => resolveCommandArgument(ctx, index, arg)\n );\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"deepkit.mjs","names":[],"sources":["../../src/resolver/deepkit.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Shell Shock\n\n This code was released as part of the Shell Shock project. Shell Shock\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/shell-shock.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/shell-shock\n Documentation: https://docs.stormsoftware.com/projects/shell-shock\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport type {\n ReflectionParameter,\n ReflectionProperty,\n Type,\n TypeArray\n} from \"@powerlines/deepkit/vendor/type\";\nimport {\n reflect,\n ReflectionClass,\n ReflectionFunction,\n ReflectionKind,\n stringifyType\n} from \"@powerlines/deepkit/vendor/type\";\nimport { isBigInt } from \"@stryke/type-checks/is-bigint\";\nimport { isNumber } from \"@stryke/type-checks/is-number\";\nimport { isRegExp } from \"@stryke/type-checks/is-regexp\";\nimport { isSetObject } from \"@stryke/type-checks/is-set-object\";\nimport type {\n CommandArgument,\n CommandOption,\n CommandParameterKind,\n Context,\n NumberCommandParameter,\n StringCommandParameter\n} from \"../types\";\nimport { CommandParameterKinds } from \"../types\";\nimport { mergeCommandParameter } from \"./helpers\";\nimport type { ResolverContext } from \"./types\";\n\nfunction extractCommandParameterKind(\n type: Type | ReflectionKind\n): CommandParameterKind {\n const isKind = !(isSetObject(type) && \"kind\" in type);\n const kind = !isKind ? type.kind : type;\n if (kind === ReflectionKind.string) {\n return CommandParameterKinds.string;\n } else if (\n kind === ReflectionKind.number ||\n kind === ReflectionKind.bigint ||\n (!isKind &&\n type.kind === ReflectionKind.literal &&\n (isNumber(type.literal) || isBigInt(type.literal)))\n ) {\n return CommandParameterKinds.number;\n } else if (kind === ReflectionKind.boolean) {\n return CommandParameterKinds.boolean;\n } else {\n return CommandParameterKinds.string;\n }\n}\n\nfunction resolveCommandOption(\n ctx: ResolverContext,\n reflection: ReflectionProperty\n): CommandOption {\n const type = reflection.getType();\n const existing = (ctx.output.options[reflection.getNameAsString()] ??\n {}) as Partial<CommandOption>;\n\n const option = {\n name: reflection.getNameAsString(),\n alias: reflection.getTags().alias ?? [],\n title: reflection.getTags().title?.trim(),\n description: reflection.getDescription(),\n kind: extractCommandParameterKind(type),\n optional: reflection.isOptional(),\n default: reflection.getDefaultValue(),\n variadic: reflection.isArray()\n };\n\n if (option.variadic) {\n option.kind = extractCommandParameterKind((type as TypeArray).type.kind);\n } else if (type.kind === ReflectionKind.union) {\n option.kind = type.types.every(\n t =>\n t.kind === ReflectionKind.number ||\n (t.kind === ReflectionKind.literal &&\n (isNumber(t.literal) || isBigInt(t.literal)))\n )\n ? CommandParameterKinds.number\n : CommandParameterKinds.string;\n\n (option as StringCommandParameter | NumberCommandParameter).choices =\n type.types\n .map(t =>\n t.kind === ReflectionKind.literal\n ? isNumber(t.literal)\n ? t.literal\n : isBigInt(t.literal)\n ? Number(t.literal)\n : isRegExp(t.literal)\n ? t.literal.source\n : String(t.literal)\n : null\n )\n .filter(Boolean) as string[] | number[];\n } else if (type.kind === ReflectionKind.literal) {\n (option as StringCommandParameter | NumberCommandParameter).choices = [\n isNumber(type.literal)\n ? type.literal\n : isBigInt(type.literal)\n ? Number(type.literal)\n : isRegExp(type.literal)\n ? type.literal.source\n : String(type.literal)\n ].filter(Boolean) as string[] | number[];\n } else if (\n !existing.kind &&\n type.kind !== ReflectionKind.boolean &&\n type.kind !== ReflectionKind.string &&\n type.kind !== ReflectionKind.number\n ) {\n throw new Error(\n `Unsupported type for option \"${reflection.getNameAsString()}\" in command \"${\n ctx.input.command.name\n }\". Only string, number, boolean, string[], number[], or literal[] are supported, received ${stringifyType(\n type\n )\n .trim()\n .replaceAll(\" | \", \", or \")}.`\n );\n }\n\n return mergeCommandParameter(existing, option) as CommandOption;\n}\n\nfunction resolveCommandArgument(\n ctx: ResolverContext,\n index: number,\n reflection: ReflectionParameter\n): CommandArgument {\n const type = reflection.getType();\n const existing = (\n ctx.output.args.length > index ? ctx.output.args[index] : {}\n ) as Partial<CommandArgument>;\n\n const argument = {\n name: reflection.getName() || reflection.parameter.name,\n alias: reflection.getAlias(),\n kind: extractCommandParameterKind(type.kind),\n title: reflection.getTitle() || reflection.parameter.tags?.title,\n description: reflection.parameter.description,\n optional: reflection.isOptional(),\n default: reflection.getDefaultValue() || reflection.parameter.default\n };\n\n if (type.kind === ReflectionKind.array) {\n if (\n type.type.kind === ReflectionKind.string ||\n type.type.kind === ReflectionKind.number\n ) {\n (argument as StringCommandParameter | NumberCommandParameter).variadic =\n true;\n (argument as StringCommandParameter | NumberCommandParameter).kind =\n extractCommandParameterKind(type.type.kind) as \"string\" | \"number\";\n } else {\n throw new Error(\n `Unsupported array type for positional argument \"${argument.name}\" in command \"${\n ctx.input.command.name\n }\". Only string[], number[], or literal[] are supported, received ${stringifyType(\n type\n )\n .trim()\n .replaceAll(\" | \", \", or \")}.`\n );\n }\n } else if (type.kind === ReflectionKind.union) {\n argument.kind = type.types.every(\n t =>\n t.kind === ReflectionKind.number ||\n (t.kind === ReflectionKind.literal &&\n (isNumber(t.literal) || isBigInt(t.literal)))\n )\n ? CommandParameterKinds.number\n : CommandParameterKinds.string;\n\n (argument as StringCommandParameter | NumberCommandParameter).choices =\n type.types\n .map(t =>\n t.kind === ReflectionKind.literal\n ? isNumber(t.literal)\n ? t.literal\n : isBigInt(t.literal)\n ? Number(t.literal)\n : isRegExp(t.literal)\n ? t.literal.source\n : String(t.literal)\n : null\n )\n .filter(Boolean) as string[] | number[];\n } else if (type.kind === ReflectionKind.literal) {\n (argument as StringCommandParameter | NumberCommandParameter).choices = [\n isNumber(type.literal)\n ? type.literal\n : isBigInt(type.literal)\n ? Number(type.literal)\n : isRegExp(type.literal)\n ? type.literal.source\n : String(type.literal)\n ].filter(Boolean) as string[] | number[];\n } else if (\n !ctx.output.args?.length &&\n type.kind !== ReflectionKind.boolean &&\n type.kind !== ReflectionKind.string &&\n type.kind !== ReflectionKind.number\n ) {\n throw new Error(\n `Unsupported type for positional argument \"${argument.name}\" in command \"${\n ctx.input.command.name\n }\". Only string, number, boolean, string[], number[], or literal[] are supported, received ${stringifyType(\n type\n )\n .trim()\n .replaceAll(\" | \", \", or \")}.`\n );\n }\n\n return mergeCommandParameter(existing, argument, {\n name: `arg${index}`\n }) as CommandArgument;\n}\n\nexport function resolveFromBytecode<TContext extends Context = Context>(\n ctx: ResolverContext<TContext>\n) {\n const { input, module } = ctx;\n\n const type = reflect(module);\n if (type.kind !== ReflectionKind.function) {\n throw new Error(\n `The command entry file \"${\n input.command.entry.input?.file || input.command.path\n }\" does not export a valid function.`\n );\n }\n\n const reflection = new ReflectionFunction(type);\n\n ctx.output.description ??= (ctx.input.command.description ||\n reflection.getDescription() ||\n type.description)!;\n\n const parameters = reflection.getParameters();\n if (parameters.length > 0) {\n const hasOptions =\n parameters[0] &&\n (parameters[0].type.kind === ReflectionKind.objectLiteral ||\n parameters[0].type.kind === ReflectionKind.class);\n if (hasOptions) {\n const optionsReflection = ReflectionClass.from(parameters[0]?.type);\n for (const propertyReflection of optionsReflection.getProperties()) {\n ctx.output.options[propertyReflection.getNameAsString()] =\n resolveCommandOption(ctx, propertyReflection);\n }\n }\n\n ctx.output.args = (hasOptions ? parameters.slice(1) : parameters).map(\n (arg, index) => resolveCommandArgument(ctx, index, arg)\n );\n }\n}\n"],"mappings":";;;;;;;;;AAAA,SAAS,aAAa,IAAI,MAAM;;AAE5B,QAAO;;AASX,SAAC,4BAAkC,MAAK;CACvC,MAAS,SAAS,EAAE,YAAY,KAAE,IAAA,UAAiB;;AAEnD,KAAK,SAAQ,eAAa;4CAIpB,SAAK,eAAA,UACV,CAAA,UACA,KAAA,SAAkB,eAAA,YACd,SAAA,KAAA,QAAA,IAAA,SAAA,KAAA,QAAA,EACJ,QAAA,sBAAA;UAEK,SAAA,eAAA,QACL,QAAO,sBAAA;KAGP,QAAA,sBAAc;;AAGhB,4BAA2B,SAAO;CAAI;CAAQ;CAAU;CAAA;CAAA;AACxD,SAAS,qBAAkB,KAAO,YAAY;CAC9C,MAAS,OAAQ,WAAU,SAAO;CAClC,MAAS,WAAa,IAAC,OAAO,QAAW,WAAW,iBAAW,KACxD,EAAA;CACL,MAAA,SAAe;EACf,MAAA,WAAa,iBAAA;EACb,OAAA,WAAoB,SAAA,CAAA,SAAA,EAAA;EACpB,OAAO,WAAA,SAAA,CAAA,OAAA,MAAA;EACP,aAAA,WAAsB,gBAAA;EACtB,MAAA,4BAAA,KAAA;EACM,UAAS,WAAA,YAAA;EACT,SAAC,WAAA,iBAAiC;EAClC,UAAC,WAAA,SAA6B;EACtC;qBAEQ,QAAC,OAAA,4BAA2B,KAAA,KAAA,KAAA;UAEjC,KAAA,SAAqB,eAAA,OAAA;AAChB,SAAO,OAAI,KAAA,MAAY,MAAQ,cAAW,MAAK,EAAA,SAAA,eAAA,UAC1C,EAAE,SAAS,eAAa,YACtB,SAAA,EAAA,QAAqB,IAAE,SAAA,EAAA,QAAA,GAAA;GAAA;GAAA;GAAA;GAAA,CAAA,CAAA,GAC3B,sBAAsB,SACrB,sBAAA;AACJ,SAAK,UACD,KAAC,MACC,IAAA,cAAA,MAAA,EAAA,SAAA,eAAA,UACI,SAAE,EAAA,QAAe,GACd,EAAA,UACjB,SAAA,EAAA,QAAA,GACO,OAAsB,EAAA,QAAM,GACjB,SAAA,EAAe,QAAQ,GAClC,EAAqB,QAAQ,SAC/B,OAAA,EAAA,QAAA,GACE,MAAA;GAAA;GAAA;GAAsB;GAAM,CAAA,CAAA,CACrC,OAAA,QAAA;iDAGM,QAAC,UAAA,CACF,SAAA,KAAe,QAAA,GACR,KAAA,UACG,SAAA,KAAA,QAAA,GACF,OAAW,KAAQ,QAAC,GACf,SAAW,KAAA,QAAQ,GACpB,KAAA,QAAc,8BAEzB,CAAA,OAAS,QAAA;UAEN,CAAA,SAAW,QAClB,KAAO,SAAW,eAAe,WACjC,KAAA,SAAa,eAAW,UACpB,KAAE,SAAA,eAA2B,OACjC,OAAU,IAAA,MAAU,gCAAa,WAAA,iBAAA,CAAA,gBAAA,IAAA,MAAA,QAAA,KAAA,4FAAA,cAAA,KAAA,CACxB,MAAA,CACA,WAAW,OAAC,QAAQ,CAAA,GAAA;;;AAIjC,qBAAkB,SAAA;CAAA;CAA6B;CAAQ;CAAgB;CAAK;CAAA;CAAA;AAC5E,SAAS,uBAAkB,KAAA,OAAe,YAAO;CAC7C,MAAM,OAAO,WAAW,SAAM;CAC9B,MAAK,WAAA,IAAA,OAAA,KAAA,SAAA,QAAA,IAAA,OAAA,KAAA,SAAA,EAAA;CACL,MAAM,WAAS;EACX,MAAG,WAAS,SAAc,IAAC,WAAS,UAAA;EACpC,OAAG,WAAW,UAAY;EAC9B,MAAA,4BAAA,KAAA,KAAA;EACI,OAAA,WAAA,UAAsB,IAAA,WAAA,UAAA,MAAA;EACtB,aAAA,WAAsB,UAAM;;EAE/B,SAAU,WAAA,iBAAyB,IAAA,WAAA,UAAwB;EAC3D;AACD,KAAI,KAAK,SAAG,eAAA,MACR,KAAI,KAAK,KAAI,SAAA,eAAe,UACxB,KAAE,KAAQ,SAAG,eAAO,QAAA;AACpB,WAAM,WACF;AACJ,WAAM,OACF,4BAAoB,KAAA,KAAA,KAAA;OAGxB,OAAE,IAAA,MAAA,mDAAA,SAAA,KAAA,gBAAA,IAAA,MAAA,QAAA,KAAA,mEAAA,cAAA,KAAA,CACN,MAAA,CACQ,WAAY,OAAO,QAAI,CAAA,GAAQ;UAGzC,KAAS,SAAY,eAAA,OAAA;AACnB,WAAO,OAAA,KAAA,MAAA,MAAA,cAAA,MAAA,EAAA,SAAA,eAAA,UACL,EAAA,SAAc,eAAO,YACnB,SAAY,EAAA,QAAO,IAAA,SAAA,EAAA,QAAA,GAAA;GAAA;GAAA;GAAA;GAAA,CAAA,CAAA,GACnB,sBAAqB,SACnB,sBAAa;AACnB,WAAM,UACF,KAAC,MACD,IAAA,cAAA,MAAA,EAAA,SAAA,eAAA,UACM,SAAE,EAAA,QAAA,GACF,EAAA,UACA,SAAA,EAAe,QAAQ,GACvB,OAAe,EAAA,QAAA,GAC7B,SAAA,EAAA,QAAA,GACe,EAAA,QAAA,SACS,OAAS,EAAC,QAAA,GACpB,MAAA;GAAO;GAAC;GAAA;GAAA,CAAA,CAAA,CACX,OAAQ,QAAQ;YAEzB,KAAA,SAAA,eAAA,QACE,UAAM,UAAA,CACL,SAAY,KAAK,QAAQ,GAC7B,KAAA,UACH,SAAA,KAAA,QAAA,0BAEO,SAAsB,KAAA,QAAU,GACzC,KAAA,QAAA,8BAES,CAAA,OAAA,QAAA;UAEA,CAAA,IAAM,OAAA,MAAA,UACb,KAAW,SAAC,eAAA,WACX,KAAA,SAAgB,eAAA,UACX,KAAK,SAAE,eAAoB,OAC3B,OAAA,IAAU,MAAC,6CAAA,SAAA,KAAA,gBAAA,IAAA,MAAA,QAAA,KAAA,4FAAA,cAAA,KAAA,CACX,MAAW,CACZ,WAAQ,OAAgB,QAAA,CAAA,GAAA;AAE7B,QAAM,sBAAW,UAAA,UAAA,EACX,MAAE,MAAU,SAChB,CAAA;;AAEJ,uBAAsB,SAAU;CAAC;CAAc;CAAU;CAAW;CAAA;CAAA;CAAA;CAAA;AACpE,SAAgB,oBAAY,KAAU;CAClC,MAAA,EAAQ,OAAE,WAAW;CACrB,MAAA,OAAS,QAAW,OAAA;AACrB,KAAA,KAAA,SAAA,eAAA;CAGC,MAAG,aAAA,IAAA,mBAAA,KAAA;AACH,KAAE,OAAS,gBAAU,IAAA,MAAe,QAAQ,eAC1C,WAAU,gBAAS,IACnB,KAAA;CACF,MAAG,aAAY,WAAA,eAAyB;AACxC,KAAI,WAAI,SAAA,GAAA;EACL,MAAA,aAAY,WAAA,OACX,WAAA,GAAA,KAAA,SAAiC,eAAe,iBAC7C,WAAA,GAAA,KAAA,SAAA,eAAA;AACL,MAAM,YAAS;GACZ,MAAA,oBAA2B,gBAAW,KAAY,WAAS,IAAM,KAAI;AACpE,QAAI,MAAM,sBAAQ,kBAAA,eAAA,CACZ,KAAC,OAAU,QAAQ,mBAAmB,iBAAW,IACvD,qBAAA,KAAA,mBAAA;;AAGF,MAAG,OAAA,QAAgB,aAAY,WAAA,MAAA,EAAA,GAAA,YAAA,IAAA,cAAA,KAAA,UAAA,uBAAA,KAAA,OAAA,IAAA,EAAA;GAAA;GAAA;GAAA;GAAA;GAAA,CAAA,CAAA;;;AAGvC,oBAAkB,SAAS;CAAA;CAAsB;CAAA;CAAA;CAAA"}
|