@shell-shock/preset-cli 0.1.6 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/README.md +1 -1
  2. package/dist/components/banner-function-declaration.d.cts +2 -2
  3. package/dist/components/banner-function-declaration.d.mts +2 -2
  4. package/dist/components/banner-function-declaration.mjs +1 -1
  5. package/dist/components/command-entry.cjs +221 -129
  6. package/dist/components/command-entry.d.cts +2 -2
  7. package/dist/components/command-entry.d.cts.map +1 -1
  8. package/dist/components/command-entry.d.mts +2 -2
  9. package/dist/components/command-entry.d.mts.map +1 -1
  10. package/dist/components/command-entry.mjs +225 -133
  11. package/dist/components/command-entry.mjs.map +1 -1
  12. package/dist/components/command-router.cjs +87 -0
  13. package/dist/components/command-router.d.cts +16 -0
  14. package/dist/components/command-router.d.cts.map +1 -0
  15. package/dist/components/command-router.d.mts +16 -0
  16. package/dist/components/command-router.d.mts.map +1 -0
  17. package/dist/components/command-router.mjs +86 -0
  18. package/dist/components/command-router.mjs.map +1 -0
  19. package/dist/components/virtual-command-entry.cjs +28 -4
  20. package/dist/components/virtual-command-entry.d.cts +2 -2
  21. package/dist/components/virtual-command-entry.d.cts.map +1 -1
  22. package/dist/components/virtual-command-entry.d.mts.map +1 -1
  23. package/dist/components/virtual-command-entry.mjs +28 -4
  24. package/dist/components/virtual-command-entry.mjs.map +1 -1
  25. package/dist/helpers/get-default-options.cjs +1 -1
  26. package/dist/helpers/get-default-options.mjs +1 -1
  27. package/dist/helpers/get-default-options.mjs.map +1 -1
  28. package/dist/index.cjs +37 -8
  29. package/dist/index.d.cts.map +1 -1
  30. package/dist/index.d.mts.map +1 -1
  31. package/dist/index.mjs +37 -8
  32. package/dist/index.mjs.map +1 -1
  33. package/package.json +22 -8
@@ -1,13 +1,13 @@
1
1
  import { BannerFunctionDeclaration } from "./banner-function-declaration.mjs";
2
2
  import { VirtualCommandEntry } from "./virtual-command-entry.mjs";
3
- import { createComponent, createIntrinsic, mergeProps } from "@alloy-js/core/jsx-runtime";
4
- import { For, Show, code, computed } from "@alloy-js/core";
5
- import { ElseIfClause, IfStatement, VarDeclaration } from "@alloy-js/typescript";
3
+ import { createComponent, createIntrinsic, memo, mergeProps } from "@alloy-js/core/jsx-runtime";
4
+ import { For, Match, Show, Switch, code, computed } from "@alloy-js/core";
5
+ import { ElseIfClause, IfStatement } from "@alloy-js/typescript";
6
6
  import { usePowerlines } from "@powerlines/plugin-alloy/core/contexts/context";
7
7
  import { isDynamicPathSegment } from "@shell-shock/core/plugin-utils/context-helpers";
8
8
  import { ReflectionKind } from "@powerlines/deepkit/vendor/type";
9
9
  import { EntryFile } from "@powerlines/plugin-alloy/typescript/components/entry-file";
10
- import { CommandHandlerDeclaration } from "@shell-shock/preset-script/components/command-entry";
10
+ import { CommandHandlerDeclaration, CommandValidationLogic } from "@shell-shock/preset-script/components/command-entry";
11
11
  import { findFilePath, relativePath } from "@stryke/path/find";
12
12
  import { joinPaths } from "@stryke/path/join";
13
13
  import { replaceExtension } from "@stryke/path/replace";
@@ -36,13 +36,15 @@ function CommandEntry(props) {
36
36
  return typeDefinition.value;
37
37
  },
38
38
  get imports() {
39
- return defu(imports ?? {}, { [commandSourcePath.value]: `handle${pascalCase(command.name)}` });
39
+ return defu(imports ?? {}, {
40
+ [commandSourcePath.value]: `handle${pascalCase(command.name)}`,
41
+ prompts: "prompts"
42
+ });
40
43
  },
41
44
  get builtinImports() {
42
45
  return defu(builtinImports ?? {}, {
43
46
  env: [
44
47
  "env",
45
- "isCI",
46
48
  "isDevelopment",
47
49
  "isDebug"
48
50
  ],
@@ -54,12 +56,20 @@ function CommandEntry(props) {
54
56
  "colors",
55
57
  "stripAnsi",
56
58
  "writeLine",
57
- "splitText"
59
+ "splitText",
60
+ "text",
61
+ "confirm",
62
+ "isCancel",
63
+ "intro",
64
+ "outro"
58
65
  ],
59
66
  utils: [
60
- "getArgs",
67
+ "useApp",
68
+ "useArgs",
61
69
  "hasFlag",
62
70
  "isMinimal",
71
+ "isInteractive",
72
+ "isHelp",
63
73
  "isUnicodeSupported",
64
74
  "internal_commandContext"
65
75
  ]
@@ -73,153 +83,235 @@ function CommandEntry(props) {
73
83
  createComponent(CommandHandlerDeclaration, {
74
84
  command,
75
85
  get children() {
76
- return [
77
- createComponent(VarDeclaration, {
78
- name: "failures",
79
- type: "string[]",
80
- initializer: code`[];`
81
- }),
82
- createIntrinsic("hbr", {}),
83
- createComponent(For, {
84
- get each() {
85
- return Object.values(command.options ?? {});
86
- },
87
- doubleHardline: true,
88
- children: (option) => [createComponent(Show, {
89
- get when() {
90
- return !option.optional;
91
- },
92
- get children() {
93
- return [createComponent(IfStatement, {
94
- get condition() {
95
- return code`!options${option.name.includes("?") ? `["${option.name}"]` : `.${camelCase(option.name)}`}`;
96
- },
97
- get children() {
98
- return code`failures.push("Missing required \\"${option.name}\\" option");`;
99
- }
100
- }), createComponent(Show, {
86
+ return [createComponent(IfStatement, {
87
+ condition: code`!isInteractive`,
88
+ get children() {
89
+ return createComponent(CommandValidationLogic, { command });
90
+ }
91
+ }), createComponent(ElseIfClause, {
92
+ get condition() {
93
+ return code`!isHelp && (${Object.values(command.options ?? {}).filter((option) => !option.optional).map((option) => (option.kind === ReflectionKind.string || option.kind === ReflectionKind.number) && option.variadic ? `(!options${option.name.includes("?") ? `["${option.name}"]` : `.${camelCase(option.name)}`} || options${option.name.includes("?") ? `["${option.name}"]` : `.${camelCase(option.name)}`}.length === 0)` : `options${option.name.includes("?") ? `["${option.name}"]` : `.${camelCase(option.name)}`} === undefined`).join(" || ")}${Object.values(command.options ?? {}).filter((option) => !option.optional).length > 0 && Object.values(command.arguments ?? {}).filter((argument) => !argument.optional).length > 0 ? " || " : ""}${Object.values(command.arguments ?? {}).filter((argument) => !argument.optional).map((argument) => (argument.kind === ReflectionKind.string || argument.kind === ReflectionKind.number) && argument.variadic ? `(!${camelCase(argument.name)} || ${camelCase(argument.name)}.length === 0)` : `${camelCase(argument.name)} === undefined`).join(" || ")}) `;
94
+ },
95
+ get children() {
96
+ return [
97
+ code`writeLine("");
98
+
99
+ intro("Select required input parameters"); `,
100
+ createIntrinsic("hbr", {}),
101
+ createIntrinsic("hbr", {}),
102
+ createComponent(For, {
103
+ get each() {
104
+ return Object.values(command.options ?? {});
105
+ },
106
+ doubleHardline: true,
107
+ children: (option) => [createComponent(Show, {
101
108
  get when() {
102
- return (option.kind === ReflectionKind.string || option.kind === ReflectionKind.number) && option.variadic;
109
+ return !option.optional;
103
110
  },
104
111
  get children() {
105
- return createComponent(ElseIfClause, {
112
+ return [createComponent(IfStatement, {
106
113
  get condition() {
107
- return code`options${option.name.includes("?") ? `["${option.name}"]` : `.${camelCase(option.name)}`}.length === 0`;
114
+ return code`!options${option.name.includes("?") ? `["${option.name}"]` : `.${camelCase(option.name)}`}`;
108
115
  },
109
116
  get children() {
110
- return code`failures.push("No values were provided to the required \\"${option.name}\\" array option");`;
111
- }
112
- });
113
- }
114
- })];
115
- }
116
- }), createComponent(Show, {
117
- get when() {
118
- return option.kind === ReflectionKind.number;
119
- },
120
- get children() {
121
- return createComponent(Show, {
122
- get when() {
123
- return option.variadic;
124
- },
125
- get fallback() {
126
- return createComponent(IfStatement, {
127
- get condition() {
128
- return code`options${option.name.includes("?") ? `["${option.name}"]` : `.${camelCase(option.name)}`} && Number.isNaN(options${option.name.includes("?") ? `["${option.name}"]` : `.${camelCase(option.name)}`})`;
129
- },
130
- get children() {
131
- return code`failures.push("Invalid numeric value provided for the \\"${option.name}\\" option");`;
117
+ return createComponent(Switch, { get children() {
118
+ return [createComponent(Match, {
119
+ get when() {
120
+ return option.kind === ReflectionKind.string || option.kind === ReflectionKind.number;
121
+ },
122
+ get children() {
123
+ return code`
124
+ const value = await text({
125
+ message: 'Please provide a value for the ${option.title} option:',
126
+ validate(value) {
127
+ if (isCancel(value)) {
128
+ return true;
129
+ }
130
+ if (!value || value.trim() === "") {
131
+ return "A value is required for this option";
132
+ }
133
+ ${option.kind === ReflectionKind.number ? `if (Number.isNaN(Number(value))) {
134
+ return "The value provided must be a valid number";
135
+ }` : ""}
136
+ return undefined;
137
+ }
138
+ });
139
+ if (isCancel(value)) {
140
+ return;
141
+ }
142
+
143
+ options${option.name.includes("?") ? `["${option.name}"]` : `.${camelCase(option.name)}`} = ${option.kind === ReflectionKind.number ? `Number(value)` : "value"};
144
+ `;
145
+ }
146
+ }), createComponent(Match, {
147
+ get when() {
148
+ return option.kind === ReflectionKind.boolean;
149
+ },
150
+ get children() {
151
+ return code`
152
+ options${option.name.includes("?") ? `["${option.name}"]` : `.${camelCase(option.name)}`} = await confirm({
153
+ message: 'Please select a value for the ${option.title} option:'
154
+ });
155
+ `;
156
+ }
157
+ })];
158
+ } });
132
159
  }
133
- });
134
- },
135
- get children() {
136
- return createComponent(IfStatement, {
137
- get condition() {
138
- return code`options${option.name.includes("?") ? `["${option.name}"]` : `.${camelCase(option.name)}`}.some(value => Number.isNaN(value))`;
160
+ }), createComponent(Show, {
161
+ get when() {
162
+ return (option.kind === ReflectionKind.string || option.kind === ReflectionKind.number) && option.variadic;
139
163
  },
140
164
  get children() {
141
- return code`failures.push("Invalid numeric value provided in the \\"${option.name}\\" array option");`;
165
+ return createComponent(ElseIfClause, {
166
+ get condition() {
167
+ return code`options${option.name.includes("?") ? `["${option.name}"]` : `.${camelCase(option.name)}`}.length === 0`;
168
+ },
169
+ get children() {
170
+ return code`
171
+ const value = await text({
172
+ message: 'Please provide one or more values for the ${option.title} option (values are separated by a "," character):',
173
+ validate(value) {
174
+ if (isCancel(value)) {
175
+ return true;
176
+ }
177
+ if (!value || value.trim() === "") {
178
+ return "A value is required for this option";
179
+ }
180
+ if (value.split(",").map(value => value.trim()).filter(Boolean).length === 0) {
181
+ return "At least one value is required for this option";
182
+ }
183
+ ${option.kind === ReflectionKind.number ? `const invalidIndex = value.split(",").map(value => value.trim()).filter(Boolean).findIndex(value => Number.isNaN(Number(value));
184
+ if (invalidIndex !== -1) {
185
+ return \`Invalid numeric value provided for item #\${invalidIndex + 1} - all provided items must be a valid number\`;
186
+ } ` : ""}
187
+ return undefined;
188
+ }
189
+ });
190
+ if (isCancel(value)) {
191
+ return;
192
+ }
193
+
194
+ options${option.name.includes("?") ? `["${option.name}"]` : `.${camelCase(option.name)}`} = value.split(",").map(value => value.trim()).filter(Boolean)${option.kind === ReflectionKind.number ? `.map(Number)` : ""} ;
195
+ `;
196
+ }
197
+ });
142
198
  }
143
- });
199
+ })];
144
200
  }
145
- });
146
- }
147
- })]
148
- }),
149
- createIntrinsic("hbr", {}),
150
- createIntrinsic("hbr", {}),
151
- createComponent(For, {
152
- get each() {
153
- return command.arguments;
154
- },
155
- doubleHardline: true,
156
- children: (argument) => [createComponent(Show, {
157
- get when() {
158
- return !argument.optional;
159
- },
160
- get children() {
161
- return [createComponent(IfStatement, {
162
- get condition() {
163
- return code`!${camelCase(argument.name)}`;
164
- },
165
- get children() {
166
- return code`failures.push("Missing required \\"${argument.name}\\" positional argument");`;
167
- }
168
- }), createComponent(Show, {
201
+ })]
202
+ }),
203
+ createIntrinsic("hbr", {}),
204
+ createIntrinsic("hbr", {}),
205
+ createComponent(For, {
206
+ get each() {
207
+ return command.arguments;
208
+ },
209
+ doubleHardline: true,
210
+ children: (argument) => [createComponent(Show, {
169
211
  get when() {
170
- return (argument.kind === ReflectionKind.string || argument.kind === ReflectionKind.number) && argument.variadic;
212
+ return !argument.optional;
171
213
  },
172
214
  get children() {
173
- return createComponent(ElseIfClause, {
215
+ return [createComponent(IfStatement, {
174
216
  get condition() {
175
- return code`${camelCase(argument.name)}.length === 0`;
217
+ return code`!${camelCase(argument.name)}`;
176
218
  },
177
219
  get children() {
178
- return code`failures.push("No values were provided to the required \\"${argument.name}\\" array positional argument");`;
179
- }
180
- });
181
- }
182
- })];
183
- }
184
- }), createComponent(Show, {
185
- get when() {
186
- return argument.kind === ReflectionKind.number;
187
- },
188
- get children() {
189
- return createComponent(Show, {
190
- get when() {
191
- return argument.variadic;
192
- },
193
- get fallback() {
194
- return createComponent(IfStatement, {
195
- get condition() {
196
- return code`${camelCase(argument.name)} && Number.isNaN(${camelCase(argument.name)})`;
197
- },
198
- get children() {
199
- return code`failures.push("Invalid numeric value provided for the \\"${argument.name}\\" positional argument");`;
220
+ return createComponent(Switch, { get children() {
221
+ return [createComponent(Match, {
222
+ get when() {
223
+ return argument.kind === ReflectionKind.string || argument.kind === ReflectionKind.number;
224
+ },
225
+ get children() {
226
+ return code`
227
+ const value = await text({
228
+ message: 'Please provide a value for the ${argument.title} positional argument:',
229
+ validate(value) {
230
+ if (isCancel(value)) {
231
+ return true;
232
+ }
233
+ if (!value || value.trim() === "") {
234
+ return "A value is required for this positional argument";
235
+ }
236
+ ${argument.kind === ReflectionKind.number ? `if (Number.isNaN(Number(value))) {
237
+ return "The value provided must be a valid number";
238
+ }` : ""}
239
+ return undefined;
240
+ }
241
+ });
242
+ if (isCancel(value)) {
243
+ return;
244
+ }
245
+
246
+ ${camelCase(argument.name)} = ${argument.kind === ReflectionKind.number ? `Number(value)` : "value"};
247
+ `;
248
+ }
249
+ }), createComponent(Match, {
250
+ get when() {
251
+ return argument.kind === ReflectionKind.boolean;
252
+ },
253
+ get children() {
254
+ return code`
255
+ ${camelCase(argument.name)} = await confirm({
256
+ message: 'Please select a value for the ${argument.title} positional argument:'
257
+ });
258
+ `;
259
+ }
260
+ })];
261
+ } });
200
262
  }
201
- });
202
- },
203
- get children() {
204
- return createComponent(IfStatement, {
205
- get condition() {
206
- return code`${camelCase(argument.name)}.some(value => Number.isNaN(value))`;
263
+ }), createComponent(Show, {
264
+ get when() {
265
+ return (argument.kind === ReflectionKind.string || argument.kind === ReflectionKind.number) && argument.variadic;
207
266
  },
208
267
  get children() {
209
- return code`failures.push("Invalid numeric value provided in the \\"${argument.name}\\" array positional argument");`;
268
+ return createComponent(ElseIfClause, {
269
+ get condition() {
270
+ return code`${camelCase(argument.name)}.length === 0`;
271
+ },
272
+ get children() {
273
+ return code`
274
+ const value = await text({
275
+ message: 'Please provide one or more values for the ${argument.title} option (values are separated by a "," character):',
276
+ validate(value) {
277
+ if (isCancel(value)) {
278
+ return true;
279
+ }
280
+ if (!value || value.trim() === "") {
281
+ return "A value is required for this option";
282
+ }
283
+ if (value.split(",").map(value => value.trim()).filter(Boolean).length === 0) {
284
+ return "At least one value is required for this option";
285
+ }
286
+ ${argument.kind === ReflectionKind.number ? `const invalidIndex = value.split(",").map(value => value.trim()).filter(Boolean).findIndex(value => Number.isNaN(Number(value));
287
+ if (invalidIndex !== -1) {
288
+ return \`Invalid numeric value provided for item #\${invalidIndex + 1} - all provided items must be a valid number\`;
289
+ } ` : ""}
290
+
291
+ return undefined;
292
+ }
293
+ });
294
+ if (isCancel(value)) {
295
+ return;
296
+ }
297
+
298
+ ${camelCase(argument.name)} = value.split(",").map(value => value.trim()).filter(Boolean)${argument.kind === ReflectionKind.number ? `.map(Number)` : ""} ;
299
+ `;
300
+ }
301
+ });
210
302
  }
211
- });
303
+ })];
212
304
  }
213
- });
214
- }
215
- })]
216
- }),
217
- createComponent(IfStatement, {
218
- condition: code`failures.length > 0`,
219
- children: code`error(colors.text.message.description.error("The following validation failures were found while processing the user provided input, and must be corrected before the command line process can be executed: \\n\\n") + failures.map(failure => colors.text.body.secondary(" - " + failure)).join("\\n"));
220
- options.help = true; `
221
- })
222
- ];
305
+ })]
306
+ }),
307
+ code`outro("Completed providing all required input parameters");
308
+
309
+ writeLine(""); `,
310
+ createIntrinsic("hbr", {}),
311
+ createIntrinsic("hbr", {})
312
+ ];
313
+ }
314
+ })];
223
315
  }
224
316
  })
225
317
  ];
@@ -1 +1 @@
1
- {"version":3,"file":"command-entry.mjs","names":["code","computed","For","Show","ElseIfClause","IfStatement","VarDeclaration","ReflectionKind","usePowerlines","EntryFile","isDynamicPathSegment","CommandHandlerDeclaration","findFilePath","relativePath","joinPaths","replaceExtension","camelCase","pascalCase","defu","BannerFunctionDeclaration","VirtualCommandEntry","CommandEntry","props","command","imports","builtinImports","rest","context","filePath","segments","filter","segment","join","commandSourcePath","entryPath","value","entry","input","file","typeDefinition","output","id","_$createComponent","_$mergeProps","path","name","env","console","utils","children","_$createIntrinsic","type","initializer","each","Object","values","options","doubleHardline","option","when","optional","condition","includes","kind","string","number","variadic","fallback","arguments","argument","child","isVirtual"],"sources":["../../src/components/command-entry.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 { code, computed, For, Show } from \"@alloy-js/core\";\nimport {\n ElseIfClause,\n IfStatement,\n VarDeclaration\n} from \"@alloy-js/typescript\";\nimport { ReflectionKind } from \"@powerlines/deepkit/vendor/type\";\nimport { usePowerlines } from \"@powerlines/plugin-alloy/core/contexts/context\";\nimport type { EntryFileProps } from \"@powerlines/plugin-alloy/typescript/components/entry-file\";\nimport { EntryFile } from \"@powerlines/plugin-alloy/typescript/components/entry-file\";\nimport { isDynamicPathSegment } from \"@shell-shock/core/plugin-utils/context-helpers\";\nimport type {\n CommandTree,\n NumberCommandArgument,\n NumberCommandOption\n} from \"@shell-shock/core/types/command\";\nimport { CommandHandlerDeclaration } from \"@shell-shock/preset-script/components/command-entry\";\nimport { findFilePath, relativePath } from \"@stryke/path/find\";\nimport { joinPaths } from \"@stryke/path/join\";\nimport { replaceExtension } from \"@stryke/path/replace\";\nimport { camelCase } from \"@stryke/string-format/camel-case\";\nimport { pascalCase } from \"@stryke/string-format/pascal-case\";\nimport defu from \"defu\";\nimport type { CLIPresetContext } from \"../types/plugin\";\nimport { BannerFunctionDeclaration } from \"./banner-function-declaration\";\nimport { VirtualCommandEntry } from \"./virtual-command-entry\";\n\nexport interface CommandEntryProps extends Omit<\n EntryFileProps,\n \"path\" | \"typeDefinition\"\n> {\n command: CommandTree;\n}\n\n/**\n * The command entry point for the Shell Shock project.\n */\nexport function CommandEntry(props: CommandEntryProps) {\n const { command, imports, builtinImports, ...rest } = props;\n\n const context = usePowerlines<CLIPresetContext>();\n const filePath = computed(() =>\n joinPaths(\n command.segments\n .filter(segment => !isDynamicPathSegment(segment))\n .join(\"/\"),\n \"index.ts\"\n )\n );\n const commandSourcePath = computed(() =>\n replaceExtension(\n relativePath(\n joinPaths(context.entryPath, findFilePath(filePath.value)),\n command.entry.input?.file || command.entry.file\n )\n )\n );\n const typeDefinition = computed(() => ({\n ...command.entry,\n output: command.id\n }));\n\n return (\n <>\n <EntryFile\n {...rest}\n path={filePath.value}\n typeDefinition={typeDefinition.value}\n imports={defu(imports ?? {}, {\n [commandSourcePath.value]: `handle${pascalCase(command.name)}`\n })}\n builtinImports={defu(builtinImports ?? {}, {\n env: [\"env\", \"isCI\", \"isDevelopment\", \"isDebug\"],\n console: [\n \"debug\",\n \"warn\",\n \"error\",\n \"table\",\n \"colors\",\n \"stripAnsi\",\n \"writeLine\",\n \"splitText\"\n ],\n utils: [\n \"getArgs\",\n \"hasFlag\",\n \"isMinimal\",\n \"isUnicodeSupported\",\n \"internal_commandContext\"\n ]\n })}>\n <BannerFunctionDeclaration command={command} />\n <hbr />\n <hbr />\n <CommandHandlerDeclaration command={command}>\n <VarDeclaration\n name=\"failures\"\n type=\"string[]\"\n initializer={code`[];`}\n />\n <hbr />\n <For each={Object.values(command.options ?? {})} doubleHardline>\n {option => (\n <>\n <Show when={!option.optional}>\n <IfStatement\n condition={code`!options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n }`}>\n {code`failures.push(\"Missing required \\\\\"${option.name}\\\\\" option\");`}\n </IfStatement>\n <Show\n when={\n (option.kind === ReflectionKind.string ||\n option.kind === ReflectionKind.number) &&\n option.variadic\n }>\n <ElseIfClause\n condition={code`options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n }.length === 0`}>\n {code`failures.push(\"No values were provided to the required \\\\\"${\n option.name\n }\\\\\" array option\");`}\n </ElseIfClause>\n </Show>\n </Show>\n <Show when={option.kind === ReflectionKind.number}>\n <Show\n when={(option as NumberCommandOption).variadic}\n fallback={\n <IfStatement\n condition={code`options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n } && Number.isNaN(options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n })`}>\n {code`failures.push(\"Invalid numeric value provided for the \\\\\"${\n option.name\n }\\\\\" option\");`}\n </IfStatement>\n }>\n <IfStatement\n condition={code`options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n }.some(value => Number.isNaN(value))`}>\n {code`failures.push(\"Invalid numeric value provided in the \\\\\"${\n option.name\n }\\\\\" array option\");`}\n </IfStatement>\n </Show>\n </Show>\n </>\n )}\n </For>\n <hbr />\n <hbr />\n <For each={command.arguments} doubleHardline>\n {argument => (\n <>\n <Show when={!argument.optional}>\n <IfStatement condition={code`!${camelCase(argument.name)}`}>\n {code`failures.push(\"Missing required \\\\\"${\n argument.name\n }\\\\\" positional argument\");`}\n </IfStatement>\n <Show\n when={\n (argument.kind === ReflectionKind.string ||\n argument.kind === ReflectionKind.number) &&\n argument.variadic\n }>\n <ElseIfClause\n condition={code`${camelCase(argument.name)}.length === 0`}>\n {code`failures.push(\"No values were provided to the required \\\\\"${\n argument.name\n }\\\\\" array positional argument\");`}\n </ElseIfClause>\n </Show>\n </Show>\n <Show when={argument.kind === ReflectionKind.number}>\n <Show\n when={(argument as NumberCommandArgument).variadic}\n fallback={\n <IfStatement\n condition={code`${camelCase(\n argument.name\n )} && Number.isNaN(${camelCase(argument.name)})`}>\n {code`failures.push(\"Invalid numeric value provided for the \\\\\"${\n argument.name\n }\\\\\" positional argument\");`}\n </IfStatement>\n }>\n <IfStatement\n condition={code`${camelCase(argument.name)}.some(value => Number.isNaN(value))`}>\n {code`failures.push(\"Invalid numeric value provided in the \\\\\"${\n argument.name\n }\\\\\" array positional argument\");`}\n </IfStatement>\n </Show>\n </Show>\n </>\n )}\n </For>\n <IfStatement condition={code`failures.length > 0`}>\n {code`error(colors.text.message.description.error(\"The following validation failures were found while processing the user provided input, and must be corrected before the command line process can be executed: \\\\n\\\\n\") + failures.map(failure => colors.text.body.secondary(\" - \" + failure)).join(\"\\\\n\"));\n options.help = true; `}\n </IfStatement>\n </CommandHandlerDeclaration>\n </EntryFile>\n <For each={Object.values(command.children)}>\n {child => (\n <Show\n when={child.isVirtual}\n fallback={<CommandEntry command={child} />}>\n <VirtualCommandEntry command={child} />\n </Show>\n )}\n </For>\n </>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAuDA,SAAgBqB,aAAaC,OAA0B;CACrD,MAAM,EAAEC,SAASC,SAASC,gBAAgB,GAAGC,SAASJ;CAEtD,MAAMK,UAAUnB,eAAiC;CACjD,MAAMoB,WAAW3B,eACfa,UACES,QAAQM,SACLC,QAAOC,YAAW,CAACrB,qBAAqBqB,QAAQ,CAAC,CACjDC,KAAK,IAAI,EACZ,WAEJ,CAAC;CACD,MAAMC,oBAAoBhC,eACxBc,iBACEF,aACEC,UAAUa,QAAQO,WAAWtB,aAAagB,SAASO,MAAM,CAAC,EAC1DZ,QAAQa,MAAMC,OAAOC,QAAQf,QAAQa,MAAME,KAE/C,CACF,CAAC;CACD,MAAMC,iBAAiBtC,gBAAgB;EACrC,GAAGsB,QAAQa;EACXI,QAAQjB,QAAQkB;EACjB,EAAE;AAEH,QAAA,CAAAC,gBAEKjC,WAASkC,WACJjB,MAAI;EAAA,IACRkB,OAAI;AAAA,UAAEhB,SAASO;;EAAK,IACpBI,iBAAc;AAAA,UAAEA,eAAeJ;;EAAK,IACpCX,UAAO;AAAA,UAAEN,KAAKM,WAAW,EAAE,EAAE,GAC1BS,kBAAkBE,QAAQ,SAASlB,WAAWM,QAAQsB,KAAK,IAC7D,CAAC;;EAAA,IACFpB,iBAAc;AAAA,UAAEP,KAAKO,kBAAkB,EAAE,EAAE;IACzCqB,KAAK;KAAC;KAAO;KAAQ;KAAiB;KAAU;IAChDC,SAAS;KACP;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACD;IACDC,OAAO;KACL;KACA;KACA;KACA;KACA;KAAyB;IAE5B,CAAC;;EAAA,IAAAC,WAAA;AAAA,UAAA;IAAAP,gBACDvB,2BAAyB,EAAUI,SAAO,CAAA;IAAA2B,gBAAA,OAAA,EAAA,CAAA;IAAAA,gBAAA,OAAA,EAAA,CAAA;IAAAR,gBAG1C/B,2BAAyB;KAAUY;KAAO,IAAA0B,WAAA;AAAA,aAAA;OAAAP,gBACxCpC,gBAAc;QACbuC,MAAI;QACJM,MAAI;QACJC,aAAapD,IAAI;QAAK,CAAA;OAAAkD,gBAAA,OAAA,EAAA,CAAA;OAAAR,gBAGvBxC,KAAG;QAAA,IAACmD,OAAI;AAAA,gBAAEC,OAAOC,OAAOhC,QAAQiC,WAAW,EAAE,CAAC;;QAAEC,gBAAc;QAAAR,WAC5DS,WAAM,CAAAhB,gBAEFvC,MAAI;SAAA,IAACwD,OAAI;AAAA,iBAAE,CAACD,OAAOE;;SAAQ,IAAAX,WAAA;AAAA,iBAAA,CAAAP,gBACzBrC,aAAW;WAAA,IACVwD,YAAS;AAAA,mBAAE7D,IAAI,WACb0D,OAAOb,KAAKiB,SAAS,IAAI,GACrB,KAAKJ,OAAOb,KAAI,MAChB,IAAI7B,UAAU0C,OAAOb,KAAK;;WAC9B,IAAAI,WAAA;AAAA,mBACDjD,IAAI,sCAAsC0D,OAAOb,KAAI;;WAAe,CAAA,EAAAH,gBAEtEvC,MAAI;WAAA,IACHwD,OAAI;AAAA,oBACDD,OAAOK,SAASxD,eAAeyD,UAC9BN,OAAOK,SAASxD,eAAe0D,WACjCP,OAAOQ;;WAAQ,IAAAjB,WAAA;AAAA,mBAAAP,gBAEhBtC,cAAY;aAAA,IACXyD,YAAS;AAAA,qBAAE7D,IAAI,UACb0D,OAAOb,KAAKiB,SAAS,IAAI,GACrB,KAAKJ,OAAOb,KAAI,MAChB,IAAI7B,UAAU0C,OAAOb,KAAK,GAAE;;aACnB,IAAAI,WAAA;AAAA,qBACdjD,IAAI,6DACH0D,OAAOb,KAAI;;aACQ,CAAA;;WAAA,CAAA,CAAA;;SAAA,CAAA,EAAAH,gBAI1BvC,MAAI;SAAA,IAACwD,OAAI;AAAA,iBAAED,OAAOK,SAASxD,eAAe0D;;SAAM,IAAAhB,WAAA;AAAA,iBAAAP,gBAC9CvC,MAAI;WAAA,IACHwD,OAAI;AAAA,mBAAGD,OAA+BQ;;WAAQ,IAC9CC,WAAQ;AAAA,mBAAAzB,gBACLrC,aAAW;aAAA,IACVwD,YAAS;AAAA,qBAAE7D,IAAI,UACb0D,OAAOb,KAAKiB,SAAS,IAAI,GACrB,KAAKJ,OAAOb,KAAI,MAChB,IAAI7B,UAAU0C,OAAOb,KAAK,GAAE,0BAEhCa,OAAOb,KAAKiB,SAAS,IAAI,GACrB,KAAKJ,OAAOb,KAAI,MAChB,IAAI7B,UAAU0C,OAAOb,KAAK,GAAE;;aAC/B,IAAAI,WAAA;AAAA,qBACFjD,IAAI,4DACH0D,OAAOb,KAAI;;aACE,CAAA;;WAAA,IAAAI,WAAA;AAAA,mBAAAP,gBAGlBrC,aAAW;aAAA,IACVwD,YAAS;AAAA,qBAAE7D,IAAI,UACb0D,OAAOb,KAAKiB,SAAS,IAAI,GACrB,KAAKJ,OAAOb,KAAI,MAChB,IAAI7B,UAAU0C,OAAOb,KAAK,GAAE;;aACG,IAAAI,WAAA;AAAA,qBACpCjD,IAAI,2DACH0D,OAAOb,KAAI;;aACQ,CAAA;;WAAA,CAAA;;SAAA,CAAA,CAAA;QAK9B,CAAA;OAAAK,gBAAA,OAAA,EAAA,CAAA;OAAAA,gBAAA,OAAA,EAAA,CAAA;OAAAR,gBAIFxC,KAAG;QAAA,IAACmD,OAAI;AAAA,gBAAE9B,QAAQ6C;;QAAWX,gBAAc;QAAAR,WACzCoB,aAAQ,CAAA3B,gBAEJvC,MAAI;SAAA,IAACwD,OAAI;AAAA,iBAAE,CAACU,SAAST;;SAAQ,IAAAX,WAAA;AAAA,iBAAA,CAAAP,gBAC3BrC,aAAW;WAAA,IAACwD,YAAS;AAAA,mBAAE7D,IAAI,IAAIgB,UAAUqD,SAASxB,KAAK;;WAAE,IAAAI,WAAA;AAAA,mBACvDjD,IAAI,sCACHqE,SAASxB,KAAI;;WACa,CAAA,EAAAH,gBAE7BvC,MAAI;WAAA,IACHwD,OAAI;AAAA,oBACDU,SAASN,SAASxD,eAAeyD,UAChCK,SAASN,SAASxD,eAAe0D,WACnCI,SAASH;;WAAQ,IAAAjB,WAAA;AAAA,mBAAAP,gBAElBtC,cAAY;aAAA,IACXyD,YAAS;AAAA,qBAAE7D,IAAI,GAAGgB,UAAUqD,SAASxB,KAAK,CAAA;;aAAe,IAAAI,WAAA;AAAA,qBACxDjD,IAAI,6DACHqE,SAASxB,KAAI;;aACmB,CAAA;;WAAA,CAAA,CAAA;;SAAA,CAAA,EAAAH,gBAIvCvC,MAAI;SAAA,IAACwD,OAAI;AAAA,iBAAEU,SAASN,SAASxD,eAAe0D;;SAAM,IAAAhB,WAAA;AAAA,iBAAAP,gBAChDvC,MAAI;WAAA,IACHwD,OAAI;AAAA,mBAAGU,SAAmCH;;WAAQ,IAClDC,WAAQ;AAAA,mBAAAzB,gBACLrC,aAAW;aAAA,IACVwD,YAAS;AAAA,qBAAE7D,IAAI,GAAGgB,UAChBqD,SAASxB,KACV,CAAA,mBAAoB7B,UAAUqD,SAASxB,KAAK,CAAA;;aAAG,IAAAI,WAAA;AAAA,qBAC/CjD,IAAI,4DACHqE,SAASxB,KAAI;;aACa,CAAA;;WAAA,IAAAI,WAAA;AAAA,mBAAAP,gBAG/BrC,aAAW;aAAA,IACVwD,YAAS;AAAA,qBAAE7D,IAAI,GAAGgB,UAAUqD,SAASxB,KAAK,CAAA;;aAAqC,IAAAI,WAAA;AAAA,qBAC9EjD,IAAI,2DACHqE,SAASxB,KAAI;;aACmB,CAAA;;WAAA,CAAA;;SAAA,CAAA,CAAA;QAK3C,CAAA;OAAAH,gBAEFrC,aAAW;QAACwD,WAAW7D,IAAI;QAAqBiD,UAC9CjD,IAAI;;QACiB,CAAA;OAAA;;KAAA,CAAA;IAAA;;EAAA,CAAA,CAAA,EAAA0C,gBAI3BxC,KAAG;EAAA,IAACmD,OAAI;AAAA,UAAEC,OAAOC,OAAOhC,QAAQ0B,SAAS;;EAAAA,WACvCqB,UAAK5B,gBACHvC,MAAI;GAAA,IACHwD,OAAI;AAAA,WAAEW,MAAMC;;GAAS,IACrBJ,WAAQ;AAAA,WAAAzB,gBAAGrB,cAAY,EAACE,SAAS+C,OAAK,CAAA;;GAAA,IAAArB,WAAA;AAAA,WAAAP,gBACrCtB,qBAAmB,EAACG,SAAS+C,OAAK,CAAA;;GAAA,CAAA;EAEtC,CAAA,CAAA"}
1
+ {"version":3,"file":"command-entry.mjs","names":["code","computed","For","Match","Show","Switch","ElseIfClause","IfStatement","ReflectionKind","usePowerlines","EntryFile","isDynamicPathSegment","CommandHandlerDeclaration","CommandValidationLogic","findFilePath","relativePath","joinPaths","replaceExtension","camelCase","pascalCase","defu","BannerFunctionDeclaration","VirtualCommandEntry","CommandEntry","props","command","imports","builtinImports","rest","context","filePath","segments","filter","segment","join","commandSourcePath","entryPath","value","entry","input","file","typeDefinition","output","id","_$createComponent","_$mergeProps","path","name","prompts","env","console","utils","children","_$createIntrinsic","condition","Object","values","options","option","optional","map","kind","string","number","variadic","includes","length","arguments","argument","each","doubleHardline","when","title","boolean","child","isVirtual","fallback"],"sources":["../../src/components/command-entry.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 { code, computed, For, Match, Show, Switch } from \"@alloy-js/core\";\nimport { ElseIfClause, IfStatement } from \"@alloy-js/typescript\";\nimport { ReflectionKind } from \"@powerlines/deepkit/vendor/type\";\nimport { usePowerlines } from \"@powerlines/plugin-alloy/core/contexts/context\";\nimport type { EntryFileProps } from \"@powerlines/plugin-alloy/typescript/components/entry-file\";\nimport { EntryFile } from \"@powerlines/plugin-alloy/typescript/components/entry-file\";\nimport { isDynamicPathSegment } from \"@shell-shock/core/plugin-utils/context-helpers\";\nimport type { CommandTree } from \"@shell-shock/core/types/command\";\nimport {\n CommandHandlerDeclaration,\n CommandValidationLogic\n} from \"@shell-shock/preset-script/components/command-entry\";\nimport { findFilePath, relativePath } from \"@stryke/path/find\";\nimport { joinPaths } from \"@stryke/path/join\";\nimport { replaceExtension } from \"@stryke/path/replace\";\nimport { camelCase } from \"@stryke/string-format/camel-case\";\nimport { pascalCase } from \"@stryke/string-format/pascal-case\";\nimport defu from \"defu\";\nimport type { CLIPresetContext } from \"../types/plugin\";\nimport { BannerFunctionDeclaration } from \"./banner-function-declaration\";\nimport { VirtualCommandEntry } from \"./virtual-command-entry\";\n\nexport interface CommandEntryProps extends Omit<\n EntryFileProps,\n \"path\" | \"typeDefinition\"\n> {\n command: CommandTree;\n}\n\n/**\n * The command entry point for the Shell Shock project.\n */\nexport function CommandEntry(props: CommandEntryProps) {\n const { command, imports, builtinImports, ...rest } = props;\n\n const context = usePowerlines<CLIPresetContext>();\n const filePath = computed(() =>\n joinPaths(\n command.segments\n .filter(segment => !isDynamicPathSegment(segment))\n .join(\"/\"),\n \"index.ts\"\n )\n );\n const commandSourcePath = computed(() =>\n replaceExtension(\n relativePath(\n joinPaths(context.entryPath, findFilePath(filePath.value)),\n command.entry.input?.file || command.entry.file\n )\n )\n );\n const typeDefinition = computed(() => ({\n ...command.entry,\n output: command.id\n }));\n\n return (\n <>\n <EntryFile\n {...rest}\n path={filePath.value}\n typeDefinition={typeDefinition.value}\n imports={defu(imports ?? {}, {\n [commandSourcePath.value]: `handle${pascalCase(command.name)}`,\n prompts: \"prompts\"\n })}\n builtinImports={defu(builtinImports ?? {}, {\n env: [\"env\", \"isDevelopment\", \"isDebug\"],\n console: [\n \"debug\",\n \"warn\",\n \"error\",\n \"table\",\n \"colors\",\n \"stripAnsi\",\n \"writeLine\",\n \"splitText\",\n \"text\",\n \"confirm\",\n \"isCancel\",\n \"intro\",\n \"outro\"\n ],\n utils: [\n \"useApp\",\n \"useArgs\",\n \"hasFlag\",\n \"isMinimal\",\n \"isInteractive\",\n \"isHelp\",\n \"isUnicodeSupported\",\n \"internal_commandContext\"\n ]\n })}>\n <BannerFunctionDeclaration command={command} />\n <hbr />\n <hbr />\n <CommandHandlerDeclaration command={command}>\n <IfStatement condition={code`!isInteractive`}>\n <CommandValidationLogic command={command} />\n </IfStatement>\n <ElseIfClause\n condition={code`!isHelp && (${Object.values(command.options ?? {})\n .filter(option => !option.optional)\n .map(option =>\n (option.kind === ReflectionKind.string ||\n option.kind === ReflectionKind.number) &&\n option.variadic\n ? `(!options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n } || options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n }.length === 0)`\n : `options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n } === undefined`\n )\n .join(\" || \")}${\n Object.values(command.options ?? {}).filter(\n option => !option.optional\n ).length > 0 &&\n Object.values(command.arguments ?? {}).filter(\n argument => !argument.optional\n ).length > 0\n ? \" || \"\n : \"\"\n }${Object.values(command.arguments ?? {})\n .filter(argument => !argument.optional)\n .map(argument =>\n (argument.kind === ReflectionKind.string ||\n argument.kind === ReflectionKind.number) &&\n argument.variadic\n ? `(!${camelCase(\n argument.name\n )} || ${camelCase(argument.name)}.length === 0)`\n : `${camelCase(argument.name)} === undefined`\n )\n .join(\" || \")}) `}>\n {code`writeLine(\"\");\n\n intro(\"Select required input parameters\"); `}\n <hbr />\n <hbr />\n <For each={Object.values(command.options ?? {})} doubleHardline>\n {option => (\n <>\n <Show when={!option.optional}>\n <IfStatement\n condition={code`!options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n }`}>\n <Switch>\n <Match\n when={\n option.kind === ReflectionKind.string ||\n option.kind === ReflectionKind.number\n }>{code`\n const value = await text({\n message: 'Please provide a value for the ${\n option.title\n } option:',\n validate(value) {\n if (isCancel(value)) {\n return true;\n }\n if (!value || value.trim() === \"\") {\n return \"A value is required for this option\";\n }\n ${\n option.kind === ReflectionKind.number\n ? `if (Number.isNaN(Number(value))) {\n return \"The value provided must be a valid number\";\n }`\n : \"\"\n }\n return undefined;\n }\n });\n if (isCancel(value)) {\n return;\n }\n\n options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n } = ${\n option.kind === ReflectionKind.number\n ? `Number(value)`\n : \"value\"\n };\n `}</Match>\n <Match\n when={option.kind === ReflectionKind.boolean}>{code`\n options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n } = await confirm({\n message: 'Please select a value for the ${option.title} option:'\n });\n `}</Match>\n </Switch>\n </IfStatement>\n <Show\n when={\n (option.kind === ReflectionKind.string ||\n option.kind === ReflectionKind.number) &&\n option.variadic\n }>\n <ElseIfClause\n condition={code`options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n }.length === 0`}>\n {code`\n const value = await text({\n message: 'Please provide one or more values for the ${\n option.title\n } option (values are separated by a \",\" character):',\n validate(value) {\n if (isCancel(value)) {\n return true;\n }\n if (!value || value.trim() === \"\") {\n return \"A value is required for this option\";\n }\n if (value.split(\",\").map(value => value.trim()).filter(Boolean).length === 0) {\n return \"At least one value is required for this option\";\n }\n ${\n option.kind === ReflectionKind.number\n ? `const invalidIndex = value.split(\",\").map(value => value.trim()).filter(Boolean).findIndex(value => Number.isNaN(Number(value));\n if (invalidIndex !== -1) {\n return \\`Invalid numeric value provided for item #\\${invalidIndex + 1} - all provided items must be a valid number\\`;\n } `\n : \"\"\n }\n return undefined;\n }\n });\n if (isCancel(value)) {\n return;\n }\n\n options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n } = value.split(\",\").map(value => value.trim()).filter(Boolean)${\n option.kind === ReflectionKind.number\n ? `.map(Number)`\n : \"\"\n } ;\n `}\n </ElseIfClause>\n </Show>\n </Show>\n </>\n )}\n </For>\n <hbr />\n <hbr />\n <For each={command.arguments} doubleHardline>\n {argument => (\n <>\n <Show when={!argument.optional}>\n <IfStatement condition={code`!${camelCase(argument.name)}`}>\n <Switch>\n <Match\n when={\n argument.kind === ReflectionKind.string ||\n argument.kind === ReflectionKind.number\n }>{code`\n const value = await text({\n message: 'Please provide a value for the ${argument.title} positional argument:',\n validate(value) {\n if (isCancel(value)) {\n return true;\n }\n if (!value || value.trim() === \"\") {\n return \"A value is required for this positional argument\";\n }\n ${\n argument.kind === ReflectionKind.number\n ? `if (Number.isNaN(Number(value))) {\n return \"The value provided must be a valid number\";\n }`\n : \"\"\n }\n return undefined;\n }\n });\n if (isCancel(value)) {\n return;\n }\n\n ${camelCase(argument.name)} = ${\n argument.kind === ReflectionKind.number\n ? `Number(value)`\n : \"value\"\n };\n `}</Match>\n <Match\n when={argument.kind === ReflectionKind.boolean}>{code`\n ${camelCase(argument.name)} = await confirm({\n message: 'Please select a value for the ${argument.title} positional argument:'\n });\n `}</Match>\n </Switch>\n </IfStatement>\n <Show\n when={\n (argument.kind === ReflectionKind.string ||\n argument.kind === ReflectionKind.number) &&\n argument.variadic\n }>\n <ElseIfClause\n condition={code`${camelCase(argument.name)}.length === 0`}>\n {code`\n const value = await text({\n message: 'Please provide one or more values for the ${\n argument.title\n } option (values are separated by a \",\" character):',\n validate(value) {\n if (isCancel(value)) {\n return true;\n }\n if (!value || value.trim() === \"\") {\n return \"A value is required for this option\";\n }\n if (value.split(\",\").map(value => value.trim()).filter(Boolean).length === 0) {\n return \"At least one value is required for this option\";\n }\n ${\n argument.kind === ReflectionKind.number\n ? `const invalidIndex = value.split(\",\").map(value => value.trim()).filter(Boolean).findIndex(value => Number.isNaN(Number(value));\n if (invalidIndex !== -1) {\n return \\`Invalid numeric value provided for item #\\${invalidIndex + 1} - all provided items must be a valid number\\`;\n } `\n : \"\"\n }\n\n return undefined;\n }\n });\n if (isCancel(value)) {\n return;\n }\n\n ${camelCase(argument.name)} = value.split(\",\").map(value => value.trim()).filter(Boolean)${\n argument.kind === ReflectionKind.number\n ? `.map(Number)`\n : \"\"\n } ;\n `}\n </ElseIfClause>\n </Show>\n </Show>\n </>\n )}\n </For>\n {code`outro(\"Completed providing all required input parameters\");\n\n writeLine(\"\"); `}\n <hbr />\n <hbr />\n </ElseIfClause>\n </CommandHandlerDeclaration>\n </EntryFile>\n <For each={Object.values(command.children)}>\n {child => (\n <Show\n when={child.isVirtual}\n fallback={<CommandEntry command={child} />}>\n <VirtualCommandEntry command={child} />\n </Show>\n )}\n </For>\n </>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
2
+ let __alloy_js_core_jsx_runtime = require("@alloy-js/core/jsx-runtime");
3
+ let __alloy_js_core = require("@alloy-js/core");
4
+ let __alloy_js_typescript = require("@alloy-js/typescript");
5
+ let __shell_shock_preset_script_components_command_router = require("@shell-shock/preset-script/components/command-router");
6
+
7
+ //#region src/components/command-router.tsx
8
+ function CommandRouterSelectOptions(props) {
9
+ const { commands } = props;
10
+ return (0, __alloy_js_core_jsx_runtime.createComponent)(__alloy_js_core.For, {
11
+ get each() {
12
+ return Object.values(commands ?? {});
13
+ },
14
+ joiner: ",",
15
+ hardline: true,
16
+ children: (command) => command.isVirtual ? (0, __alloy_js_core_jsx_runtime.createComponent)(CommandRouterSelectOptions, { get commands() {
17
+ return command.children ?? {};
18
+ } }) : __alloy_js_core.code`{ value: [${command.segments.map((segment) => `"${segment}"`).join(", ")}], label: "${command.icon ? `${command.icon} ` : ""}${command.title}", hint: "${command.description}" }`
19
+ });
20
+ }
21
+ /**
22
+ * A component that renders a command router interface, allowing users to select and execute commands from a provided list of commands and segments. This component serves as a wrapper around the base CommandRouter, adding additional UI elements and logic for command selection.
23
+ */
24
+ function CommandRouter(props) {
25
+ const { segments, commands } = props;
26
+ return [
27
+ (0, __alloy_js_core_jsx_runtime.createComponent)(__shell_shock_preset_script_components_command_router.CommandRouter, (0, __alloy_js_core_jsx_runtime.mergeProps)(props, {
28
+ segments,
29
+ commands
30
+ })),
31
+ (0, __alloy_js_core_jsx_runtime.createIntrinsic)("hbr", {}),
32
+ (0, __alloy_js_core_jsx_runtime.createIntrinsic)("hbr", {}),
33
+ (0, __alloy_js_core_jsx_runtime.createComponent)(__alloy_js_typescript.IfStatement, {
34
+ condition: __alloy_js_core.code`isInteractive && !isHelp`,
35
+ get children() {
36
+ return [
37
+ __alloy_js_core.code`
38
+ banner();
39
+ writeLine("");
40
+
41
+ intro("Command selection");
42
+
43
+ let segments = await select({
44
+ message: "Please select a command to execute:",
45
+ options: [ `,
46
+ (0, __alloy_js_core_jsx_runtime.createComponent)(CommandRouterSelectOptions, { commands }),
47
+ (0, __alloy_js_core_jsx_runtime.memo)(() => ` ],
48
+ });
49
+ if (isCancel(segments)) {
50
+ return;
51
+ }
52
+
53
+ let dynamics = {} as Record<string, string>;
54
+ for (const dynamic of segments.filter(segment => segment.startsWith("[") && segment.endsWith("]"))) {
55
+ const value = await text({
56
+ message: \`Please provide a value for \${dynamic.replace(/^\[+/, "").replace(/\]+$/, "")}:\`,
57
+ });
58
+ if (isCancel(value)) {
59
+ return;
60
+ }
61
+ dynamics[dynamic] = value;
62
+ }
63
+
64
+ segments = segments.map(segment => dynamics[segment] || segment);
65
+ const context = useApp();
66
+ context.set("args", [args[0], ...segments, ...args.slice(${segments.length + 2})]);
67
+
68
+ outro(\`Executing \${segments.join(" ")} command\`);
69
+
70
+ command = segments[0];
71
+ args = context.get("args");
72
+ `),
73
+ (0, __alloy_js_core_jsx_runtime.createComponent)(__shell_shock_preset_script_components_command_router.CommandRouterBody, (0, __alloy_js_core_jsx_runtime.mergeProps)(props, {
74
+ segments,
75
+ commands
76
+ }))
77
+ ];
78
+ }
79
+ }),
80
+ (0, __alloy_js_core_jsx_runtime.createIntrinsic)("hbr", {}),
81
+ (0, __alloy_js_core_jsx_runtime.createIntrinsic)("hbr", {})
82
+ ];
83
+ }
84
+
85
+ //#endregion
86
+ exports.CommandRouter = CommandRouter;
87
+ exports.CommandRouterSelectOptions = CommandRouterSelectOptions;
@@ -0,0 +1,16 @@
1
+ import * as _alloy_js_core0 from "@alloy-js/core";
2
+ import { CommandTree } from "@shell-shock/core/types/command";
3
+ import { CommandRouterProps } from "@shell-shock/preset-script/components/command-router";
4
+
5
+ //#region src/components/command-router.d.ts
6
+ interface CommandRouterSelectOptionsProps {
7
+ commands?: Record<string, CommandTree>;
8
+ }
9
+ declare function CommandRouterSelectOptions(props: CommandRouterSelectOptionsProps): _alloy_js_core0.Children;
10
+ /**
11
+ * A component that renders a command router interface, allowing users to select and execute commands from a provided list of commands and segments. This component serves as a wrapper around the base CommandRouter, adding additional UI elements and logic for command selection.
12
+ */
13
+ declare function CommandRouter(props: CommandRouterProps): _alloy_js_core0.Children;
14
+ //#endregion
15
+ export { CommandRouter, CommandRouterSelectOptions, CommandRouterSelectOptionsProps };
16
+ //# sourceMappingURL=command-router.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-router.d.cts","names":[],"sources":["../../src/components/command-router.tsx"],"sourcesContent":[],"mappings":";;;;;UA2BiB,+BAAA;aACJ,eAAe;;AADX,iBAID,0BAAA,CAHY,KAAA,EAInB,+BAJU,CAAA,EAIqB,eAAA,CAAA,QAJrB;AAGnB;AA2BA;;iBAAgB,aAAA,QAAqB,qBAAkB,eAAA,CAAA"}