@shell-shock/core 0.17.4 → 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.
Files changed (82) hide show
  1. package/dist/components/command-validation-logic.cjs +214 -152
  2. package/dist/components/command-validation-logic.mjs +213 -152
  3. package/dist/components/command-validation-logic.mjs.map +1 -1
  4. package/dist/components/docs.cjs +113 -9
  5. package/dist/components/docs.mjs +109 -9
  6. package/dist/components/docs.mjs.map +1 -1
  7. package/dist/components/exec-builtin.cjs +36 -1
  8. package/dist/components/exec-builtin.d.cts.map +1 -1
  9. package/dist/components/exec-builtin.d.mts.map +1 -1
  10. package/dist/components/exec-builtin.mjs +35 -1
  11. package/dist/components/exec-builtin.mjs.map +1 -1
  12. package/dist/components/helpers.cjs +51 -2
  13. package/dist/components/helpers.mjs +50 -2
  14. package/dist/components/helpers.mjs.map +1 -1
  15. package/dist/components/index.cjs +17 -1
  16. package/dist/components/index.mjs +9 -9
  17. package/dist/components/options-parser-logic.cjs +411 -174
  18. package/dist/components/options-parser-logic.d.cts.map +1 -1
  19. package/dist/components/options-parser-logic.d.mts.map +1 -1
  20. package/dist/components/options-parser-logic.mjs +405 -174
  21. package/dist/components/options-parser-logic.mjs.map +1 -1
  22. package/dist/components/state-builtin.cjs +61 -5
  23. package/dist/components/state-builtin.mjs +60 -5
  24. package/dist/components/state-builtin.mjs.map +1 -1
  25. package/dist/components/usage.cjs +46 -3
  26. package/dist/components/usage.mjs +45 -3
  27. package/dist/components/usage.mjs.map +1 -1
  28. package/dist/components/utils-builtin.cjs +68 -3
  29. package/dist/components/utils-builtin.mjs +67 -3
  30. package/dist/components/utils-builtin.mjs.map +1 -1
  31. package/dist/helpers/automd.cjs +28 -13
  32. package/dist/helpers/automd.mjs +28 -13
  33. package/dist/helpers/automd.mjs.map +1 -1
  34. package/dist/index.cjs +11 -0
  35. package/dist/index.d.cts +2 -2
  36. package/dist/index.d.mts +2 -2
  37. package/dist/index.mjs +2 -2
  38. package/dist/plugin-utils/compute-bin.cjs +50 -0
  39. package/dist/plugin-utils/compute-bin.d.cts +13 -0
  40. package/dist/plugin-utils/compute-bin.d.cts.map +1 -0
  41. package/dist/plugin-utils/compute-bin.d.mts +13 -0
  42. package/dist/plugin-utils/compute-bin.d.mts.map +1 -0
  43. package/dist/plugin-utils/compute-bin.mjs +50 -0
  44. package/dist/plugin-utils/compute-bin.mjs.map +1 -0
  45. package/dist/plugin-utils/get-command-tree.cjs +50 -0
  46. package/dist/plugin-utils/get-command-tree.d.cts +15 -1
  47. package/dist/plugin-utils/get-command-tree.d.cts.map +1 -1
  48. package/dist/plugin-utils/get-command-tree.d.mts +15 -1
  49. package/dist/plugin-utils/get-command-tree.d.mts.map +1 -1
  50. package/dist/plugin-utils/get-command-tree.mjs +49 -1
  51. package/dist/plugin-utils/get-command-tree.mjs.map +1 -1
  52. package/dist/plugin-utils/index.cjs +4 -0
  53. package/dist/plugin-utils/index.d.cts +3 -2
  54. package/dist/plugin-utils/index.d.mts +3 -2
  55. package/dist/plugin-utils/index.mjs +3 -2
  56. package/dist/plugin.cjs +170 -55
  57. package/dist/plugin.d.cts.map +1 -1
  58. package/dist/plugin.d.mts.map +1 -1
  59. package/dist/plugin.mjs +170 -54
  60. package/dist/plugin.mjs.map +1 -1
  61. package/dist/resolver/deepkit.cjs +1 -1
  62. package/dist/resolver/deepkit.mjs +1 -1
  63. package/dist/resolver/deepkit.mjs.map +1 -1
  64. package/dist/types/command.cjs +120 -10
  65. package/dist/types/command.d.cts +95 -8
  66. package/dist/types/command.d.cts.map +1 -1
  67. package/dist/types/command.d.mts +95 -8
  68. package/dist/types/command.d.mts.map +1 -1
  69. package/dist/types/command.mjs +109 -10
  70. package/dist/types/command.mjs.map +1 -1
  71. package/dist/types/config.cjs +2 -3
  72. package/dist/types/config.d.cts +2 -3
  73. package/dist/types/config.d.cts.map +1 -1
  74. package/dist/types/config.d.mts +2 -3
  75. package/dist/types/config.d.mts.map +1 -1
  76. package/dist/types/config.mjs +2 -3
  77. package/dist/types/config.mjs.map +1 -1
  78. package/dist/types/index.cjs +12 -1
  79. package/dist/types/index.d.cts +2 -2
  80. package/dist/types/index.d.mts +2 -2
  81. package/dist/types/index.mjs +2 -2
  82. package/package.json +10 -10
package/dist/plugin.mjs CHANGED
@@ -16,7 +16,6 @@ import { createComponent } from "@alloy-js/core/jsx-runtime";
16
16
  import { For, Show } from "@alloy-js/core/components";
17
17
  import { render } from "@powerlines/plugin-alloy/render";
18
18
  import automd from "@powerlines/plugin-automd";
19
- import deepkit from "@powerlines/plugin-deepkit";
20
19
  import nodejs from "@powerlines/plugin-nodejs";
21
20
  import tsdown from "@powerlines/plugin-tsdown";
22
21
  import { toArray } from "@stryke/convert/to-array";
@@ -36,18 +35,21 @@ import { defu } from "defu";
36
35
  import { resolveInputs } from "powerlines/utils";
37
36
 
38
37
  //#region src/plugin.tsx
38
+ function __assignType(fn, args) {
39
+ fn.__type = args;
40
+ return fn;
41
+ }
39
42
  const MAX_DEPTH = 50;
40
43
  /**
41
44
  * The core Powerlines plugin to build Shell Shock projects.
42
45
  */
43
- const plugin = (options = {}) => {
46
+ const plugin = __assignType((options = {}) => {
44
47
  return [
45
- ...deepkit(),
46
- tsdown(),
47
- automd(),
48
+ (tsdown.Ω = [["Context", "\"w!"]], tsdown()),
49
+ (automd.Ω = [["Context", "\"w!"]], automd()),
48
50
  {
49
51
  name: "shell-shock:config",
50
- async config() {
52
+ config: __assignType(async function config() {
51
53
  this.debug("Resolving the Shell Shock configuration.");
52
54
  await updatePackageJsonBinary(this);
53
55
  return defu({ output: { path: joinPaths(this.config.root, "dist") } }, options, {
@@ -73,7 +75,7 @@ const plugin = (options = {}) => {
73
75
  unbundle: false
74
76
  }
75
77
  });
76
- },
78
+ }, ["config", "P\"/!"]),
77
79
  configResolved: {
78
80
  order: "pre",
79
81
  async handler() {
@@ -102,19 +104,23 @@ const plugin = (options = {}) => {
102
104
  alias: [],
103
105
  isVirtual: false
104
106
  }));
105
- this.options = this.options.map((option) => ({
107
+ this.options = this.options.map(__assignType((option) => ({
106
108
  ...option,
107
109
  name: camelCase(option.name),
108
110
  alias: option.alias ?? [],
109
111
  optional: option.optional ?? false
110
- }));
112
+ }), [
113
+ "option",
114
+ "",
115
+ "P\"2!\"/\""
116
+ ]));
111
117
  }
112
118
  }
113
119
  },
114
- ...nodejs(defu(options ?? {}, { env: {
120
+ ...(nodejs.Ω = [["Context", "\"w!"]], nodejs(defu(options ?? {}, { env: {
115
121
  types: "@shell-shock/core/types/env#ShellShockEnv",
116
122
  validate: false
117
- } })),
123
+ } }))),
118
124
  {
119
125
  name: "shell-shock:inputs",
120
126
  async configResolved() {
@@ -124,17 +130,34 @@ const plugin = (options = {}) => {
124
130
  this.debug(`Resolved commands root path: ${this.commandsPath}`);
125
131
  const inputs = await resolveInputs(this, this.config.input);
126
132
  this.debug(`Found ${inputs.length} entry points specified in the configuration options.`);
127
- this.inputs = inputs.reduce((ret, entry) => {
133
+ this.inputs = inputs.reduce(__assignType((ret, entry) => {
128
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.`);
129
135
  const id = resolveCommandId(this, entry.file);
130
- if (!ret.some((existing) => existing.id === id)) {
136
+ if (!ret.some(__assignType((existing) => existing.id === id, [
137
+ "existing",
138
+ "",
139
+ "P\"2!\"/\""
140
+ ]))) {
131
141
  const name = resolveCommandName(entry.file);
132
142
  let segments = resolveCommandPath(this, entry.file).split("/").filter(Boolean);
133
- segments = segments.map((segment, index) => {
134
- const found = segments.findIndex((existing) => existing === segment);
135
- if (found !== -1 && found !== index) segment += `_${segments.filter((segment) => isDynamicPathSegment(segment) && getDynamicPathSegmentName(segment).replace(/_\d+$/, "") === segment).length}`;
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}`;
136
154
  return segment;
137
- });
155
+ }, [
156
+ "segment",
157
+ "index",
158
+ "",
159
+ "P\"2!\"2\"\"/#"
160
+ ]));
138
161
  ret.push({
139
162
  id,
140
163
  path: segments.join("/"),
@@ -156,17 +179,26 @@ const plugin = (options = {}) => {
156
179
  });
157
180
  }
158
181
  return ret;
159
- }, this.inputs);
160
- this.debug(`Shell Shock will process ${this.inputs.length} command entry files: \n${this.inputs.map((command) => ` - ${command.id}: ${replacePath(command.entry.file, this.commandsPath)}`).join("\n")}`);
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")}`);
161
193
  },
162
- async prepare() {
194
+ prepare: __assignType(async function prepare() {
163
195
  this.debug("Rendering base built-in modules for the Shell Shock application.");
164
196
  return render(this, [
165
197
  createComponent(StateBuiltin, {}),
166
198
  createComponent(UtilsBuiltin, {}),
167
199
  createComponent(ExecBuiltin, {})
168
200
  ]);
169
- }
201
+ }, ["prepare", "P\"/!"])
170
202
  },
171
203
  {
172
204
  name: "shell-shock:virtual-inputs",
@@ -176,22 +208,43 @@ const plugin = (options = {}) => {
176
208
  if (this.inputs.length === 0) this.warn("No commands were found in the project. Please ensure at least one command exists.");
177
209
  else {
178
210
  this.debug("Finding and adding virtual command inputs for each command previously found.");
179
- this.inputs = this.inputs.reduce((ret, command) => {
211
+ this.inputs = this.inputs.reduce(__assignType((ret, command) => {
180
212
  let depth = 0;
181
213
  let parentPath = resolveParentPath(findFilePath(command.entry.file));
182
214
  if (isParentPath(parentPath, this.commandsPath)) while (parentPath !== this.commandsPath) {
183
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.`);
184
- 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
+ ]))) {
185
221
  const file = joinPaths(parentPath, "command.ts");
186
222
  const id = resolveCommandId(this, file);
187
- if (!ret.some((existing) => existing.id === id)) {
223
+ if (!ret.some(__assignType((existing) => existing.id === id, [
224
+ "existing",
225
+ "",
226
+ "P\"2!\"/\""
227
+ ]))) {
188
228
  const name = resolveCommandName(file);
189
229
  let segments = resolveCommandPath(this, file).split("/").filter(Boolean);
190
- segments = segments.map((segment, index) => {
191
- const found = segments.findIndex((existing) => existing === segment);
192
- if (found !== -1 && found !== index) segment += `_${segments.filter((segment) => isDynamicPathSegment(segment) && getDynamicPathSegmentName(segment).replace(/_\d+$/, "") === segment).length}`;
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}`;
193
241
  return segment;
194
- });
242
+ }, [
243
+ "segment",
244
+ "index",
245
+ "",
246
+ "P\"2!\"2\"\"/#"
247
+ ]));
195
248
  ret.push({
196
249
  id,
197
250
  path: segments.join("/"),
@@ -208,8 +261,22 @@ const plugin = (options = {}) => {
208
261
  parentPath = resolveParentPath(parentPath);
209
262
  }
210
263
  return ret;
211
- }, this.inputs).sort((a, b) => a.segments.length - b.segments.length);
212
- this.debug(`Final command input list: \n${this.inputs.map((command) => ` - ${command.id}${command.isVirtual ? " (virtual)" : ""}: ${command.source === "file" ? replacePath(command.entry.file, this.commandsPath) : `added by ${command.source}`}`).join("\n")}`);
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")}`);
213
280
  }
214
281
  }
215
282
  }
@@ -225,30 +292,54 @@ const plugin = (options = {}) => {
225
292
  this.debug(`Skipping command resolution as the meta checksum has not changed.`);
226
293
  await readCommandsPersistence(this);
227
294
  } else {
228
- for (const input of this.inputs.filter((input) => input.segments.filter((segment) => !isDynamicPathSegment(segment) && !isPathSegmentGroup(segment)).length === 1)) this.commands[input.name] = await resolve({
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({
229
304
  context: this,
230
305
  command: input
231
306
  });
232
307
  this.debug("Post-processing commands to ensure proper reflection.");
233
- await traverseCommands(this, (command) => {
234
- 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), {
235
310
  ...option,
236
311
  name: camelCase(name),
237
312
  alias: option.alias ?? [],
238
313
  optional: option.optional ?? false
239
- }]));
240
- });
314
+ }], [
315
+ "param0",
316
+ "",
317
+ "P\"2!\"/\""
318
+ ])));
319
+ }, [
320
+ "command",
321
+ "",
322
+ "P\"2!\"/\""
323
+ ]));
241
324
  await writeCommandsPersistence(this);
242
325
  }
243
326
  this.debug("Validating the CLI applications command tree.");
244
327
  let isValid = true;
245
- await traverseCommands(this, (command) => {
328
+ await traverseCommands(this, __assignType((command) => {
246
329
  const failures = validateCommand(command);
247
330
  if (failures.length > 0) {
248
- this.error(`Found ${failures.length} issue${failures.length > 1 ? "s" : ""} with the ${command.title} command: \n${failures.map((failure) => ` - ${failure.code}: ${failure.details}`).join("\n")}\n`);
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`);
249
336
  isValid = false;
250
337
  }
251
- });
338
+ }, [
339
+ "command",
340
+ "",
341
+ "P\"2!\"/\""
342
+ ]));
252
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.`);
253
344
  this.info(`\nCreating an application with the following command tree: \n${formatCommandTree(this)}\n`);
254
345
  }
@@ -258,8 +349,8 @@ const plugin = (options = {}) => {
258
349
  name: "shell-shock:chmod+x",
259
350
  configResolved() {
260
351
  this.config.tsdown.hooks ??= {};
261
- this.config.tsdown.hooks["build:done"] = async (_) => {
262
- 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) => {
263
354
  const path = appendPath(bin, joinPaths(this.workspaceConfig.workspaceRoot, this.config.root));
264
355
  if (this.fs.existsSync(path)) {
265
356
  this.debug(`Adding hashbang to binary executable output file: ${path}`);
@@ -268,40 +359,65 @@ const plugin = (options = {}) => {
268
359
  this.debug(`Adding executable permissions (chmod+x) to binary executable output file: ${path}`);
269
360
  await chmodX(path);
270
361
  } else this.warn(`Expected binary output file not found at path: ${path}. Skipping adding hashbang and executable permissions (chmod+x).`);
271
- }));
272
- };
362
+ }, [
363
+ "bin",
364
+ "",
365
+ "P\"2!\"/\""
366
+ ])));
367
+ }, [
368
+ "chunks",
369
+ "_",
370
+ "",
371
+ "PP!P!F4!MK2\"\"/#"
372
+ ]);
273
373
  }
274
374
  },
275
375
  {
276
376
  name: "shell-shock:docs",
277
- configResolved() {
377
+ configResolved: __assignType(function configResolved() {
278
378
  this.config.automd ??= {};
279
379
  this.config.automd.generators = {
280
380
  ...this.config.automd.generators ?? {},
281
381
  commands: commands(this)
282
382
  };
283
- },
383
+ }, ["configResolved", "P\"/!"]),
284
384
  async docs() {
285
385
  this.debug("Rendering entrypoint modules for the Shell Shock `script` preset.");
286
- const commands = this.inputs.map((input) => getCommandTree(this, input.segments)).filter(Boolean);
386
+ const commands = this.inputs.map(__assignType((input) => getCommandTree(this, input.segments), [
387
+ "input",
388
+ "",
389
+ "P\"2!\"/\""
390
+ ])).filter(Boolean);
287
391
  return render(this, createComponent(For, {
288
392
  get each() {
289
393
  return Object.values(commands);
290
394
  },
291
395
  doubleHardline: true,
292
- children: (child) => createComponent(Show, {
293
- get when() {
294
- return !child.isVirtual;
295
- },
296
- get children() {
297
- return createComponent(CommandDocsFile, { command: child });
298
- }
299
- })
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
+ }
300
410
  }));
301
411
  }
302
412
  }
303
413
  ];
304
- };
414
+ }, [
415
+ "Options",
416
+ "options",
417
+ () => ({}),
418
+ "",
419
+ "P\"w!2\">#!F/$"
420
+ ]);
305
421
 
306
422
  //#endregion
307
423
  export { plugin as default, plugin };
@@ -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 deepkit from \"@powerlines/plugin-deepkit\";\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 ...deepkit<TContext>(),\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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2DA,MAAE,YAAA;;;;AAKF,MAAE,UAAiB,UAAA,EAAA,KAAA;AACjB,QAAA;EAAA,GAAU,SAAA;EAAA,QAAA;EAAA,QAAA;EAAA;GACV,MAAA;GACA,MAAA,SAAA;AACA,SAAA,MAAA,2CAAoB;AACpB,UAAA,wBAAA,KAAA;AA4BI,WA3BW,KAAM,EACf,QAAC,EACA,MAAA,UAAiB,KAAE,OAAQ,MAAO,OAAM,EACxC,EACF,EAAA,SAAO;KACP,MAAO,WAAU,KAAM;KACvB,OAAO,YAAU,KAAQ;;KAE1B,UAAY;;KAEhB,WAAA;KACK,iBAAgB;KACrB,QAAA;MACK,QAAM;MACH,KAAC;MACF;KACD,OAAC,CAAA,KAAA,OAAA,SAAA,MAAA,QAAA,KAAA,OAAA,MAAA,IAAA,KAAA,OAAA,MAAA,WAAA,KAAA,SAAA,KAAA,OAAA,MAAA,IAAA,OAAA,KAAA,KAAA,OAAA,MAAA,CAAA,WAAA,IAAA,CAAA,UAAA,KAAA,OAAA,MAAA,oBAAA,EAAA,UAAA,KAAA,OAAA,MAAA,qBAAA,CAAA,GAAA;KACF,SAAQ;MACL,UAAU,CAAC,sBAAC;MACZ,uBAAY;MAClB;KACE,QAAO;MACP,KAAM;MACJ,cAAY;;MAEZ;;;GAIJ,gBAAgB;IACd,OAAO;IACP,MAAM,UAAA;AACJ,UAAG,MAAA,+CAAA;AACH,UAAE,OAAO,uBAAA,YAAA,KAAA,OAAA,cAAA,GAAA,KAAA,OAAA,gBAAA,aAAA,WAAA,KAAA,CAAA;AACT,SAAE,CAAA,KAAA,OAAA,IAAA,UAAA,CAAA,MAAA,QAAA,KAAA,OAAA,IAAA,OAAA,CACA,MAAE,OAAM,IAAA,SAAgB,QAAA,KAAA,OAAA,IAAA,OAAA;AAE1B,SAAI,CAAA,KAAA,OAAa,IAAA,OAAA,SAAkB,KAAK,OAAA,qBAAA,CACtC,MAAE,OAAU,IAAC,OAAK,KAAA,KAAA,OAAA,qBAAA;AAEpB,UAAI,OAAA,OAAY,YAAY,KAAA,YAAA,IAAA,GAAA,GACzB,UAAC,KAAA,OAAiB,KAAK,GAAA,KAAA,YAAA,KACzB,GAAG,KAAA,YAAQ,QAAA,GACT,UAAU,KAAK,OAAC,KAAA,GAAA,iBAAA,KAAA,OAAA,OAAA,OAAA,EAClB;AACD,SAAI,YAAC,KAAA,OAAA,UAAA,CACH,KAAE,KAAK,OAAA,UAAA,SAAA,YAAA,CACL,MAAG,OAAK,YAAc;MACpB,KAAC,KAAM,OAAQ,UAAY,UAAQ,GAAA,KAAA,OAAA,UAAA,QAAA,YAAA,CAAA,CAAA,QAAA,QAAA,IAAA;MACnC,UAAO,KAAO,OAAM;MACrB;cACG,KAAO,OAAU,UAAO,SAAO,aAAY,CAC/C,MAAK,OAAC,YAAA;MACJ,KAAK,KAAC,OAAU,UAAW,UAAQ,GAAK,KAAE,OAAU,UAAE,QAAA,aAAA,CAAA,CAAA,QAAA,QAAA,IAAA;MACtD,UAAM,KAAS,OAAM;MACtB;SAED,MAAA,OAAS,YAAA,EACP,KAAA,KAAU,OAAG,WACd;AAGL,UAAK,WAAW,EAAA;AAChB,UAAK,UAAC,OAAc,OAAI,iBAAA,MAAA;MACtB,IAAI;MACJ,MAAE,KAAA,OAAA;MACF,MAAA;MACD,UAAA,EAAA;;MAED,aAAa,KAAA,OAAA;MACd,OAAA,EAAA;MACD,WAAe;MACb,CAAA,CAAA;AACA,UAAK,UAAU,KAAC,QAAA,KAAA,YAAA;MACd,GAAA;;MAEA,OAAK,OAAO,SAAA,EAAA;MACZ,UAAO,OAAO,YAAA;MACf,EAAC;;IAEL;GACF;EAAE,GAAG,OAAK,KAAA,WAAA,EAAA,EAAA,EACT,KAAK;GACH,OAAO;GACP,UAAM;GACP,EACF,CAAC,CAAC;EAAE;;GAEH,MAAM,iBAAG;AACP,SAAK,MAAM,qCAAiC;AAC5C,SAAK,MAAC,sCAAA,KAAA,UAAA,KAAA,OAAA,MAAA,GAAA;AACN,SAAK,eAAa,MAAI,iBAAiB,KAAO;AAC9C,SAAI,MAAA,gCAAA,KAAA,eAAA;;AAEJ,SAAI,MAAK,SAAW,OAAG,OAAW,uDAAqB;AACvD,SAAK,SAAM,OAAU,QAAK,KAAO,UAAQ;AACvC,SAAI,MAAM,SAAC,KAAY,gBAAQ,CAAA,aAAA,MAAA,MAAA,KAAA,aAAA,CAC7B,OAAG,IAAA,MAAU,wBAAoB,MAAA,KAAgB,6CAAA,KAAA,aAAA,wFAAA;KAEnD,MAAI,KAAA,iBAAA,MAAA,MAAA,KAAA;AACJ,SAAG,CAAA,IAAA,MAAA,aAAA,SAAA,OAAA,GAAA,EAAA;;MAED,IAAI,WAAW,mBAAa,MAAY,MAAA,KAAA,CAAA,MAAA,IAAA,CAAA,OAAA,QAAA;AAGxC,iBAAW,SAAK,KAAO,SAAA,UAAA;OACrB,MAAM,QAAC,SAAa,WAAY,aAAU,aAAU,QAAU;AAC9D,WAAI,UAAU,MAAM,UAAO,MACzB,YAAW,IAAC,SAAY,QAAA,YAAA,qBAAA,QAAA,IAAA,0BAAA,QAAA,CAAA,QAAA,SAAA,GAAA,KAAA,QAAA,CAAA;AAE1B,cAAO;QACP;AACF,UAAI,KAAK;OACP;OACA,MAAM,SAAS,KAAK,IAAI;OACxB;OACA;OACA,OAAO,EAAA;OACP,MAAM,EAAC;OACP,WAAS;OACT,QAAG;OACH,OAAA;QACF,GAAA;;QAEI,OAAO;SACN,MAAO,MAAG;SACb,MAAA,MAAgB;SACd;QACA,QAAM;QACP;OACF,CAAC;;AAEJ,YAAM;OACL,KAAK,OAAO;AACf,SAAK,MAAG,4BAAW,KAAA,OAAA,OAAA,0BAAA,KAAA,OAAA,KAAA,YAAA,MAAA,QAAA,GAAA,IAAA,YAAA,QAAA,MAAA,MAAA,KAAA,aAAA,GAAA,CAAA,KAAA,KAAA,GAAA;;GAErB,MAAM,UAAC;;AAEL,WAAI,OAAK,MAAU;KAAA,gBAAgB,cAAA,EAAA,CAAA;KAAA,gBAAA,cAAA,EAAA,CAAA;KAAA,gBAAA,aAAA,EAAA,CAAA;KAAA,CAAA;;GAEtC;EAAE;GACD,MAAM;GACN,gBAAgB;IACd,OAAO;IACP,MAAM,UAAI;AACR,SAAI,KAAK,OAAG,WAAA,EACV,MAAC,KAAA,oFAAA;UACH;AACF,WAAA,MAAA,+EAAA;AACD,WAAA,SAAA,KAAA,OAAA,QAAA,KAAA,YAAA;OACE,IAAO,QAAS;OACZ,IAAA,aAAe,kBAAA,aAAA,QAAA,MAAA,KAAA,CAAA;AACd,WAAC,aAAA,YAAA,KAAA,aAAA,CACH,QAAS,eAAiB,KAAK,cAAK;AACpC,YAAU,UAAA,UACZ,OAAA,IAAA,MAAA,0CAAA,QAAA,KAAA,qBAAA,QAAA,MAAA,KAAA,mEAAA;AAEH,YAAA,CAAA,IAAA,MAAA,aAAA,aAAA,SAAA,MAAA,KAAA,KAAA,WAAA,EAAA;SACD,MAAA,OAAA,UAAA,YAAA,aAAA;SACc,MAAM,KAAC,iBAAO,MAAA,KAAA;AACpB,aAAA,CAAA,IAAe,MAAE,aAAA,SAAA,OAAA,GAAA,EAAA;UACT,MAAA,OAAQ,mBAAoB,KAAQ;;AAI/C,qBAAA,SAAA,KAAA,SAAA,UAAA;;AAEI,eAAa,UAAQ,MAAA,UAAiB,MAC/B,YAAS,IAAS,SAAU,QAAO,YAAC,qBAAe,QAAA,IAAA,0BAAA,QAAA,CAAA,QAAA,SAAA,GAAA,KAAA,QAAA,CAAA;AAEjD,kBAAO;;AAEX,cAAA,KAAA;WACA;WACC,MAAA,SAAA,KAAA,IAAA;WACD;WACT;;WAEa,MAAM,EAAC;WAChB,WAAA;WACS,OAAK,EACd,MACD;WACU,QAAK;WACZ,CAAO;;;AAGN,qBAAK,kBAAA,WAAA;;AAGX,cAAA;;AAEA,WAAK,MAAM,+BAA6B,KAAK,OAAA,KAAA,YAAA,MAAA,QAAA,KAAA,QAAA,YAAA,eAAA,GAAA,IAAA,QAAA,WAAA,SAAA,YAAA,QAAA,MAAA,MAAA,KAAA,aAAA,GAAA,YAAA,QAAA,WAAA,CAAA,KAAA,KAAA,GAAA;;;IAGlD;GACF;EAAE;GACD,MAAM;;IAEJ,OAAO;IACP,MAAM,UAAU;AACd,UAAK,MAAM,mDAA2B;AACtC,UAAK,WAAW,EAAE;AAClB,SAAI,KAAG,OAAA,YAAA,aAAA,KAAA,OAAA,cAAA,QAAA,KAAA,eAAA,aAAA,KAAA,KAAA,YAAA,KAAA,GAAA,WAAA,2BAAA,KAAA,CAAA,EAAA;AACL,WAAI,MAAI,oEAAiC;AACzC,YAAM,wBAAc,KAAA;YACf;AACL,WAAK,MAAK,SAAS,KAAA,OAAA,QAAA,UAAA,MAAA,SAAA,QAAA,YAAA,CAAA,qBAAA,QAAA,IAAA,CAAA,mBAAA,QAAA,CAAA,CAAA,WAAA,EAAA,CACjB,MAAK,SAAK,MAAA,QAAA,MAAqB,QAAU;OACvC,SAAQ;OACR,SAAS;OACV,CAAC;AAEJ,WAAK,MAAK,wDAAA;AACV,YAAM,iBAAE,OAAA,YAAA;AACN,eAAE,UAAA,OAAA,YAAA,OAAA,QAAA,QAAA,QAAA,CAAA,KAAA,CAAA,MAAA,YAAA,CAAA,UAAA,KAAA,EAAA;;QAEA,MAAM,UAAQ,KAAA;QACd,OAAA,OAAA,SAAA,EAAA;;QAEF,CAAS,CAAA,CAAA;QACT;AACF,YAAI,yBAAwB,KAAA;;AAE9B,UAAK,MAAK,gDAAA;KACV,IAAI,UAAU;AACd,WAAM,iBAAQ,OAAA,YAAA;MACZ,MAAI,WAAW,gBAAK,QAAA;AACpB,UAAI,SAAS,SAAK,GAAA;AAChB,YAAE,MAAO,SAAA,SAAA,OAAA,QAAA,SAAA,SAAA,IAAA,MAAA,GAAA,YAAA,QAAA,MAAA,cAAA,SAAA,KAAA,YAAA,MAAA,QAAA,KAAA,IAAA,QAAA,UAAA,CAAA,KAAA,KAAA,CAAA,IAAA;AACT,iBAAO;;OAET;AACF,SAAI,CAAC,QACH,OAAM,IAAE,MAAM,2HAAM;AAEtB,UAAK,KAAG,gEAAQ,kBAAA,KAAA,CAAA,IAAA;;IAEnB;GACF;EAAE;;GAED,iBAAgB;AACd,SAAK,OAAK,OAAO,UAAA,EAAA;0DAGZ;AACH,WAAI,QAAK,IAAO,OAAA,OAAA,KAAA,OAAA,IAAA,CAAA,IAAA,OAAA,QAAA;MACd,MAAE,OAAQ,WAAc,KAAG,UAAK,KAAA,gBAAA,eAAA,KAAA,OAAA,KAAA,CAAA;AAChC,UAAG,KAAG,GAAA,WAAA,KAAA,EAAA;AACJ,YAAE,MAAS,qDAAA,OAAA;OACX,MAAM,UAAI,MAAY,KAAG,GAAA,KAAA,KAAW;AACpC,WAAI,WAAU,CAAA,QAAU,WAAA,KAAA,CACtB,OAAI,KAAK,GAAA,MAAA,MAAA,kBAAA,KAAA,OAAA,SAAA,gBAAA,yCAAA,GAAA,WAAA,UAAA;AAEX,YAAA,MAAA,6EAAA,OAAA;AACA,aAAM,OAAM,KAAA;YAEjB,MAAA,KAAA,kDAAA,KAAA,kEAAA;OAEC,CAAA;;;;;GAIJ,MAAI;GACJ,iBAAU;AACR,SAAK,OAAA,WAAA,EAAA;AACL,SAAK,OAAE,OAAY,aAAE;KACnB,GAAI,KAAC,OAAA,OAAc,cAAA,EAAA;KACnB,UAAK,SAAa,KAAA;KACnB;;GAEH,MAAE,OAAA;AACD,SAAA,MAAA,oEAAA;IACD,MAAA,WAAA,KAAA,OAAA,KAAA,UAAA,eAAA,MAAA,MAAA,SAAA,CAAA,CAAA,OAAA,QAAA;AACE,WAAO,OAAM,MAAM,gBAAe,KAAA;KAClC,IAAA,OAAA;AACE,aAAQ,OAAK,OAAA,SAAA;;KAEb,gBAAW;KACX,WAAS,UAAI,gBAAA,MAAA;MACX,IAAI,OAAI;AACN,cAAC,CAAA,MAAA;;MAEH,IAAE,WAAU;AACV,cAAG,gBAAmB,iBAAgB,EACrC,SAAA;;MAGJ,CAAC;KACH,CAAC,CAAC;;GAEN;EAAC"}
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"}