@shell-shock/core 0.17.15 → 0.17.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/api.d.cts CHANGED
@@ -1,4 +1,4 @@
1
1
  //#region src/api.d.ts
2
- declare const _default: (params: import("@powerlines/engine").ExecutionApiParams<import("powerlines").ExecutionOptions, "types" | "prepare" | "create" | "clean" | "lint" | "test" | "build" | "docs" | "deploy">) => Promise<void>;
2
+ declare const _default: (params: import("@powerlines/engine").ExecutionApiParams<import("powerlines").ExecutionOptions, "types" | "docs" | "create" | "clean" | "prepare" | "lint" | "test" | "build" | "deploy">) => Promise<void>;
3
3
  export = _default;
4
4
  //# sourceMappingURL=api.d.cts.map
package/dist/api.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region src/api.d.ts
2
- declare const _default: (params: import("@powerlines/engine").ExecutionApiParams<import("powerlines").ExecutionOptions, "types" | "prepare" | "create" | "clean" | "lint" | "test" | "build" | "docs" | "deploy">) => Promise<void>;
2
+ declare const _default: (params: import("@powerlines/engine").ExecutionApiParams<import("powerlines").ExecutionOptions, "types" | "docs" | "create" | "clean" | "prepare" | "lint" | "test" | "build" | "deploy">) => Promise<void>;
3
3
  //#endregion
4
4
  export { _default as default };
5
5
  //# sourceMappingURL=api.d.mts.map
package/dist/package.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
 
2
2
  //#region package.json
3
- var version = "0.17.14";
3
+ var version = "0.17.16";
4
4
 
5
5
  //#endregion
6
6
  Object.defineProperty(exports, 'version', {
package/dist/package.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region package.json
2
- var version = "0.17.14";
2
+ var version = "0.17.16";
3
3
 
4
4
  //#endregion
5
5
  export { version };
@@ -0,0 +1,110 @@
1
+ const require_helpers = require('./helpers.cjs');
2
+ let _stryke_type_checks_is_set_object = require("@stryke/type-checks/is-set-object");
3
+ let _powerlines_deepkit_vendor_type = require("@powerlines/deepkit/vendor/type");
4
+ let _stryke_type_checks_is_bigint = require("@stryke/type-checks/is-bigint");
5
+ let _stryke_type_checks_is_number = require("@stryke/type-checks/is-number");
6
+ let _stryke_type_checks_is_regexp = require("@stryke/type-checks/is-regexp");
7
+
8
+ //#region src/resolver/deepkit.ts
9
+ function __assignType(fn, args) {
10
+ fn.__type = args;
11
+ return fn;
12
+ }
13
+ function resolveCommandParameterType(type) {
14
+ const isKind = !((0, _stryke_type_checks_is_set_object.isSetObject)(type) && "kind" in type);
15
+ const kind = !isKind ? type.kind : type;
16
+ if (kind === _powerlines_deepkit_vendor_type.ReflectionKind.string) return "string";
17
+ else if (kind === _powerlines_deepkit_vendor_type.ReflectionKind.number || kind === _powerlines_deepkit_vendor_type.ReflectionKind.bigint || !isKind && type.kind === _powerlines_deepkit_vendor_type.ReflectionKind.literal && ((0, _stryke_type_checks_is_number.isNumber)(type.literal) || (0, _stryke_type_checks_is_bigint.isBigInt)(type.literal))) return "number";
18
+ else if (kind === _powerlines_deepkit_vendor_type.ReflectionKind.boolean) return "boolean";
19
+ else return "string";
20
+ }
21
+ resolveCommandParameterType.__type = [
22
+ "type",
23
+ "string",
24
+ "number",
25
+ "boolean",
26
+ "resolveCommandParameterType",
27
+ "PP!!J2!P.\".#.$J/%"
28
+ ];
29
+ function resolveCommandOption(ctx, reflection) {
30
+ const type = reflection.getType();
31
+ const existing = ctx.output.options[reflection.getNameAsString()] ?? {};
32
+ const option = {
33
+ name: reflection.getNameAsString(),
34
+ alias: reflection.getTags().alias ?? [],
35
+ title: reflection.getTags().title?.trim(),
36
+ description: reflection.getDescription(),
37
+ type: resolveCommandParameterType(type),
38
+ required: !reflection.isOptional(),
39
+ default: reflection.getDefaultValue(),
40
+ variadic: reflection.isArray()
41
+ };
42
+ if (option.variadic) option.type = resolveCommandParameterType(type.type.kind);
43
+ else if (type.kind === _powerlines_deepkit_vendor_type.ReflectionKind.union) {
44
+ option.type = type.types.every(__assignType((t) => t.kind === _powerlines_deepkit_vendor_type.ReflectionKind.number || t.kind === _powerlines_deepkit_vendor_type.ReflectionKind.literal && ((0, _stryke_type_checks_is_number.isNumber)(t.literal) || (0, _stryke_type_checks_is_bigint.isBigInt)(t.literal)), [
45
+ "t",
46
+ "",
47
+ "P\"2!\"/\""
48
+ ])) ? "number" : "string";
49
+ option.choices = type.types.map(__assignType((t) => t.kind === _powerlines_deepkit_vendor_type.ReflectionKind.literal ? (0, _stryke_type_checks_is_number.isNumber)(t.literal) ? t.literal : (0, _stryke_type_checks_is_bigint.isBigInt)(t.literal) ? Number(t.literal) : (0, _stryke_type_checks_is_regexp.isRegExp)(t.literal) ? t.literal.source : String(t.literal) : null, [
50
+ "t",
51
+ "",
52
+ "P\"2!\"/\""
53
+ ])).filter(Boolean);
54
+ } else if (type.kind === _powerlines_deepkit_vendor_type.ReflectionKind.literal) option.choices = [(0, _stryke_type_checks_is_number.isNumber)(type.literal) ? type.literal : (0, _stryke_type_checks_is_bigint.isBigInt)(type.literal) ? Number(type.literal) : (0, _stryke_type_checks_is_regexp.isRegExp)(type.literal) ? type.literal.source : String(type.literal)].filter(Boolean);
55
+ else if (!existing.type && type.kind !== _powerlines_deepkit_vendor_type.ReflectionKind.boolean && type.kind !== _powerlines_deepkit_vendor_type.ReflectionKind.string && type.kind !== _powerlines_deepkit_vendor_type.ReflectionKind.number) throw new Error(`Unsupported type for option "${reflection.getNameAsString()}" in command "${ctx.input.command.name}". Only string, number, boolean, string[], number[], or literal[] are supported, received ${(0, _powerlines_deepkit_vendor_type.stringifyType)(type).trim().replaceAll(" | ", ", or ")}.`);
56
+ return require_helpers.mergeCommandParameter(existing, option);
57
+ }
58
+ resolveCommandOption.__type = [
59
+ "ResolverContext",
60
+ "ctx",
61
+ "reflection",
62
+ "CommandOption",
63
+ "resolveCommandOption",
64
+ "P\"w!2\"!2#\"w$/%"
65
+ ];
66
+ function resolveCommandArgument(ctx, index, reflection) {
67
+ const type = reflection.getType();
68
+ const existing = ctx.output.args.length > index ? ctx.output.args[index] : {};
69
+ const argument = {
70
+ name: reflection.getName() || reflection.parameter.name,
71
+ alias: reflection.getAlias(),
72
+ type: resolveCommandParameterType(type.kind),
73
+ title: reflection.getTitle() || reflection.parameter.tags?.title,
74
+ description: reflection.parameter.description,
75
+ required: !reflection.isOptional(),
76
+ default: reflection.getDefaultValue()
77
+ };
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
+ argument.variadic = true;
80
+ argument.type = resolveCommandParameterType(type.type.kind);
81
+ } else throw new Error(`Unsupported array type for positional argument "${argument.name}" in command "${ctx.input.command.name}". Only string[], number[], or literal[] are supported, received ${(0, _powerlines_deepkit_vendor_type.stringifyType)(type).trim().replaceAll(" | ", ", or ")}.`);
82
+ else if (type.kind === _powerlines_deepkit_vendor_type.ReflectionKind.union) {
83
+ argument.type = type.types.every(__assignType((t) => t.kind === _powerlines_deepkit_vendor_type.ReflectionKind.number || t.kind === _powerlines_deepkit_vendor_type.ReflectionKind.literal && ((0, _stryke_type_checks_is_number.isNumber)(t.literal) || (0, _stryke_type_checks_is_bigint.isBigInt)(t.literal)), [
84
+ "t",
85
+ "",
86
+ "P\"2!\"/\""
87
+ ])) ? "number" : "string";
88
+ argument.choices = type.types.map(__assignType((t) => t.kind === _powerlines_deepkit_vendor_type.ReflectionKind.literal ? (0, _stryke_type_checks_is_number.isNumber)(t.literal) ? t.literal : (0, _stryke_type_checks_is_bigint.isBigInt)(t.literal) ? Number(t.literal) : (0, _stryke_type_checks_is_regexp.isRegExp)(t.literal) ? t.literal.source : String(t.literal) : null, [
89
+ "t",
90
+ "",
91
+ "P\"2!\"/\""
92
+ ])).filter(Boolean);
93
+ } else if (type.kind === _powerlines_deepkit_vendor_type.ReflectionKind.literal) argument.choices = [(0, _stryke_type_checks_is_number.isNumber)(type.literal) ? type.literal : (0, _stryke_type_checks_is_bigint.isBigInt)(type.literal) ? Number(type.literal) : (0, _stryke_type_checks_is_regexp.isRegExp)(type.literal) ? type.literal.source : String(type.literal)].filter(Boolean);
94
+ else if (!ctx.output.args?.length && type.kind !== _powerlines_deepkit_vendor_type.ReflectionKind.boolean && type.kind !== _powerlines_deepkit_vendor_type.ReflectionKind.string && type.kind !== _powerlines_deepkit_vendor_type.ReflectionKind.number) throw new Error(`Unsupported type for positional argument "${argument.name}" in command "${ctx.input.command.name}". Only string, number, boolean, string[], number[], or literal[] are supported, received ${(0, _powerlines_deepkit_vendor_type.stringifyType)(type).trim().replaceAll(" | ", ", or ")}.`);
95
+ return require_helpers.mergeCommandParameter(existing, argument, { name: `arg${index}` });
96
+ }
97
+ resolveCommandArgument.__type = [
98
+ "ResolverContext",
99
+ "ctx",
100
+ "index",
101
+ "reflection",
102
+ "CommandArgument",
103
+ "resolveCommandArgument",
104
+ "P\"w!2\"'2#!2$\"w%/&"
105
+ ];
106
+
107
+ //#endregion
108
+ exports.resolveCommandArgument = resolveCommandArgument;
109
+ exports.resolveCommandOption = resolveCommandOption;
110
+ //# sourceMappingURL=deepkit.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deepkit.cjs","names":[],"sources":[],"mappings":""}
@@ -0,0 +1,109 @@
1
+ import { mergeCommandParameter } from "./helpers.mjs";
2
+ import { isSetObject } from "@stryke/type-checks/is-set-object";
3
+ import { ReflectionKind, stringifyType } from "@powerlines/deepkit/vendor/type";
4
+ import { isBigInt } from "@stryke/type-checks/is-bigint";
5
+ import { isNumber } from "@stryke/type-checks/is-number";
6
+ import { isRegExp } from "@stryke/type-checks/is-regexp";
7
+
8
+ //#region src/resolver/deepkit.ts
9
+ function __assignType(fn, args) {
10
+ fn.__type = args;
11
+ return fn;
12
+ }
13
+ function resolveCommandParameterType(type) {
14
+ const isKind = !(isSetObject(type) && "kind" in type);
15
+ const kind = !isKind ? type.kind : type;
16
+ if (kind === ReflectionKind.string) return "string";
17
+ else if (kind === ReflectionKind.number || kind === ReflectionKind.bigint || !isKind && type.kind === ReflectionKind.literal && (isNumber(type.literal) || isBigInt(type.literal))) return "number";
18
+ else if (kind === ReflectionKind.boolean) return "boolean";
19
+ else return "string";
20
+ }
21
+ resolveCommandParameterType.__type = [
22
+ "type",
23
+ "string",
24
+ "number",
25
+ "boolean",
26
+ "resolveCommandParameterType",
27
+ "PP!!J2!P.\".#.$J/%"
28
+ ];
29
+ function resolveCommandOption(ctx, reflection) {
30
+ const type = reflection.getType();
31
+ const existing = ctx.output.options[reflection.getNameAsString()] ?? {};
32
+ const option = {
33
+ name: reflection.getNameAsString(),
34
+ alias: reflection.getTags().alias ?? [],
35
+ title: reflection.getTags().title?.trim(),
36
+ description: reflection.getDescription(),
37
+ type: resolveCommandParameterType(type),
38
+ required: !reflection.isOptional(),
39
+ default: reflection.getDefaultValue(),
40
+ variadic: reflection.isArray()
41
+ };
42
+ if (option.variadic) option.type = resolveCommandParameterType(type.type.kind);
43
+ else if (type.kind === ReflectionKind.union) {
44
+ option.type = type.types.every(__assignType((t) => t.kind === ReflectionKind.number || t.kind === ReflectionKind.literal && (isNumber(t.literal) || isBigInt(t.literal)), [
45
+ "t",
46
+ "",
47
+ "P\"2!\"/\""
48
+ ])) ? "number" : "string";
49
+ option.choices = type.types.map(__assignType((t) => t.kind === ReflectionKind.literal ? isNumber(t.literal) ? t.literal : isBigInt(t.literal) ? Number(t.literal) : isRegExp(t.literal) ? t.literal.source : String(t.literal) : null, [
50
+ "t",
51
+ "",
52
+ "P\"2!\"/\""
53
+ ])).filter(Boolean);
54
+ } else if (type.kind === ReflectionKind.literal) option.choices = [isNumber(type.literal) ? type.literal : isBigInt(type.literal) ? Number(type.literal) : isRegExp(type.literal) ? type.literal.source : String(type.literal)].filter(Boolean);
55
+ else if (!existing.type && type.kind !== ReflectionKind.boolean && type.kind !== ReflectionKind.string && type.kind !== ReflectionKind.number) throw new Error(`Unsupported type for option "${reflection.getNameAsString()}" in command "${ctx.input.command.name}". Only string, number, boolean, string[], number[], or literal[] are supported, received ${stringifyType(type).trim().replaceAll(" | ", ", or ")}.`);
56
+ return mergeCommandParameter(existing, option);
57
+ }
58
+ resolveCommandOption.__type = [
59
+ "ResolverContext",
60
+ "ctx",
61
+ "reflection",
62
+ "CommandOption",
63
+ "resolveCommandOption",
64
+ "P\"w!2\"!2#\"w$/%"
65
+ ];
66
+ function resolveCommandArgument(ctx, index, reflection) {
67
+ const type = reflection.getType();
68
+ const existing = ctx.output.args.length > index ? ctx.output.args[index] : {};
69
+ const argument = {
70
+ name: reflection.getName() || reflection.parameter.name,
71
+ alias: reflection.getAlias(),
72
+ type: resolveCommandParameterType(type.kind),
73
+ title: reflection.getTitle() || reflection.parameter.tags?.title,
74
+ description: reflection.parameter.description,
75
+ required: !reflection.isOptional(),
76
+ default: reflection.getDefaultValue()
77
+ };
78
+ if (type.kind === ReflectionKind.array) if (type.type.kind === ReflectionKind.string || type.type.kind === ReflectionKind.number) {
79
+ argument.variadic = true;
80
+ argument.type = resolveCommandParameterType(type.type.kind);
81
+ } else throw new Error(`Unsupported array type for positional argument "${argument.name}" in command "${ctx.input.command.name}". Only string[], number[], or literal[] are supported, received ${stringifyType(type).trim().replaceAll(" | ", ", or ")}.`);
82
+ else if (type.kind === ReflectionKind.union) {
83
+ argument.type = type.types.every(__assignType((t) => t.kind === ReflectionKind.number || t.kind === ReflectionKind.literal && (isNumber(t.literal) || isBigInt(t.literal)), [
84
+ "t",
85
+ "",
86
+ "P\"2!\"/\""
87
+ ])) ? "number" : "string";
88
+ argument.choices = type.types.map(__assignType((t) => t.kind === ReflectionKind.literal ? isNumber(t.literal) ? t.literal : isBigInt(t.literal) ? Number(t.literal) : isRegExp(t.literal) ? t.literal.source : String(t.literal) : null, [
89
+ "t",
90
+ "",
91
+ "P\"2!\"/\""
92
+ ])).filter(Boolean);
93
+ } else if (type.kind === ReflectionKind.literal) argument.choices = [isNumber(type.literal) ? type.literal : isBigInt(type.literal) ? Number(type.literal) : isRegExp(type.literal) ? type.literal.source : String(type.literal)].filter(Boolean);
94
+ else if (!ctx.output.args?.length && type.kind !== ReflectionKind.boolean && type.kind !== ReflectionKind.string && type.kind !== ReflectionKind.number) throw new Error(`Unsupported type for positional argument "${argument.name}" in command "${ctx.input.command.name}". Only string, number, boolean, string[], number[], or literal[] are supported, received ${stringifyType(type).trim().replaceAll(" | ", ", or ")}.`);
95
+ return mergeCommandParameter(existing, argument, { name: `arg${index}` });
96
+ }
97
+ resolveCommandArgument.__type = [
98
+ "ResolverContext",
99
+ "ctx",
100
+ "index",
101
+ "reflection",
102
+ "CommandArgument",
103
+ "resolveCommandArgument",
104
+ "P\"w!2\"'2#!2$\"w%/&"
105
+ ];
106
+
107
+ //#endregion
108
+ export { resolveCommandArgument, resolveCommandOption };
109
+ //# sourceMappingURL=deepkit.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deepkit.mjs","names":[],"sources":[],"mappings":""}
@@ -179,5 +179,6 @@ const mergeCommandParameter = (0, defu.createDefu)(__assignType((obj, key, value
179
179
  exports.applyArgsDefaults = applyArgsDefaults;
180
180
  exports.applyDefaults = applyDefaults;
181
181
  exports.applyOptionsDefaults = applyOptionsDefaults;
182
+ exports.mergeCommandParameter = mergeCommandParameter;
182
183
  exports.resolveVirtualCommand = resolveVirtualCommand;
183
184
  //# sourceMappingURL=helpers.cjs.map
@@ -176,5 +176,5 @@ const mergeCommandParameter = createDefu(__assignType((obj, key, value) => {
176
176
  ]));
177
177
 
178
178
  //#endregion
179
- export { applyArgsDefaults, applyDefaults, applyOptionsDefaults, resolveVirtualCommand };
179
+ export { applyArgsDefaults, applyDefaults, applyOptionsDefaults, mergeCommandParameter, resolveVirtualCommand };
180
180
  //# sourceMappingURL=helpers.mjs.map
@@ -1,6 +1,7 @@
1
1
  const require_context_helpers = require('../plugin-utils/context-helpers.cjs');
2
2
  const require_utilities = require('../helpers/utilities.cjs');
3
3
  const require_helpers = require('./helpers.cjs');
4
+ const require_deepkit = require('./deepkit.cjs');
4
5
  let _powerlines_schema = require("@powerlines/schema");
5
6
  let _stryke_convert_to_array = require("@stryke/convert/to-array");
6
7
  let _stryke_path_replace = require("@stryke/path/replace");
@@ -8,8 +9,10 @@ let _stryke_string_format_constant_case = require("@stryke/string-format/constan
8
9
  let _stryke_type_checks_is_set_object = require("@stryke/type-checks/is-set-object");
9
10
  let _stryke_type_checks_is_set_string = require("@stryke/type-checks/is-set-string");
10
11
  let _stryke_string_format_title_case = require("@stryke/string-format/title-case");
12
+ let _powerlines_deepkit_vendor_type = require("@powerlines/deepkit/vendor/type");
11
13
  let _stryke_type_checks_is_boolean = require("@stryke/type-checks/is-boolean");
12
14
  let _stryke_helpers_get_unique = require("@stryke/helpers/get-unique");
15
+ let _stryke_type_checks_is_function = require("@stryke/type-checks/is-function");
13
16
  let _powerlines_deepkit_esbuild_plugin = require("@powerlines/deepkit/esbuild-plugin");
14
17
  let _stryke_json = require("@stryke/json");
15
18
 
@@ -223,44 +226,6 @@ resolveCommandParameter.__type = [
223
226
  "resolveCommandParameter",
224
227
  "P#2!P)4\")4#M2$P\"w%\"w&J/'"
225
228
  ];
226
- /**
227
- * Resolves a command option from the given schema.
228
- *
229
- * @param schema - The command option schema, which can be a command option configuration or a JSON schema input.
230
- * @returns The resolved command option definition.
231
- */
232
- function resolveCommandOption(schema) {
233
- return resolveCommandParameter(schema, {
234
- fallbackRequired: false,
235
- includeBooleanOptionFields: true
236
- });
237
- }
238
- resolveCommandOption.__type = [
239
- "schema",
240
- "CommandOption",
241
- "resolveCommandOption",
242
- "Resolves a command option from the given schema.",
243
- "P#2!\"w\"/#?$"
244
- ];
245
- /**
246
- * Resolves a command argument from the given schema.
247
- *
248
- * @param schema - The command argument schema, which can be a command argument configuration or a JSON schema input.
249
- * @returns The resolved command argument definition.
250
- */
251
- function resolveCommandArgument(schema) {
252
- return resolveCommandParameter(schema, {
253
- fallbackRequired: true,
254
- includeBooleanOptionFields: false
255
- });
256
- }
257
- resolveCommandArgument.__type = [
258
- "schema",
259
- "CommandArgument",
260
- "resolveCommandArgument",
261
- "Resolves a command argument from the given schema.",
262
- "P#2!\"w\"/#?$"
263
- ];
264
229
  async function preprocess(input) {
265
230
  const { context, command, parent } = input;
266
231
  const title = command.title || `${parent?.title ? `${parent.virtual ? parent.title.replace(/(?:c|C)ommands?$/, "").trim() : parent.title} - ` : ""}${(0, _stryke_string_format_title_case.titleCase)(command.name)}${command.virtual ? " Commands" : ""}`;
@@ -270,7 +235,6 @@ async function preprocess(input) {
270
235
  alias: [],
271
236
  icon: parent?.icon,
272
237
  tags: parent?.tags ?? [],
273
- source: "file",
274
238
  ...command,
275
239
  title,
276
240
  options: parent === null ? require_utilities.getGlobalOptions(context, command) : {},
@@ -291,6 +255,12 @@ async function preprocess(input) {
291
255
  resolve: { skipNodeModulesBundle: true }
292
256
  }));
293
257
  }
258
+ if (!command.virtual) {
259
+ if (!result.module?.default) throw new Error(`The command entry file "${input.command.entry.input?.file || input.command.path}" does not include a handler function as its default export - this is required for command resolution and execution.`);
260
+ const type = (0, _powerlines_deepkit_vendor_type.reflect)(result.module.default);
261
+ if (type.kind !== _powerlines_deepkit_vendor_type.ReflectionKind.function) throw new Error(`The command entry file "${input.command.entry.input?.file || input.command.path}" does not have a valid function as its default export - this is required for command resolution and execution.`);
262
+ result.reflection = new _powerlines_deepkit_vendor_type.ReflectionFunction(type);
263
+ }
294
264
  return result;
295
265
  }
296
266
  preprocess.__type = [
@@ -441,11 +411,15 @@ async function resolve(input) {
441
411
  if ((0, _stryke_type_checks_is_set_string.isSetString)(metadata.alias) || Array.isArray(metadata.alias) && metadata.alias.length > 0) ctx.output.alias = (0, _stryke_convert_to_array.toArray)(metadata.alias);
442
412
  if ((0, _stryke_type_checks_is_set_string.isSetString)(metadata.icon)) ctx.output.icon = metadata.icon;
443
413
  if ((0, _stryke_type_checks_is_set_string.isSetString)(metadata.tags)) ctx.output.tags = (0, _stryke_helpers_get_unique.getUnique)(ctx.output.tags.concat((0, _stryke_convert_to_array.toArray)(metadata.tags)));
444
- if ((0, _stryke_type_checks_is_set_object.isSetObject)(ctx.module.options)) {
414
+ ctx.output.description ??= ctx.input.command.description || (0, _stryke_type_checks_is_function.isFunction)(ctx.reflection?.getDescription) ? ctx.reflection?.getDescription() : ctx.reflection?.description;
415
+ if (ctx.module.options) {
445
416
  const options = await (0, _powerlines_schema.extract)(ctx.input.context, ctx.module.options);
446
417
  if (!(0, _stryke_type_checks_is_set_object.isSetObject)(options) || !(0, _stryke_json.isJsonSchemaObjectType)(options.schema)) throw new TypeError(`Command options for command at path "${ctx.input.command.path}" must resolve to an object.`);
447
418
  ctx.output.options = (0, _powerlines_schema.getPropertiesList)(options).reduce(__assignType((ret, property) => {
448
- ret[property.name] = resolveCommandOption(property);
419
+ ret[property.name] = resolveCommandParameter(property, {
420
+ fallbackRequired: false,
421
+ includeBooleanOptionFields: true
422
+ });
449
423
  return ret;
450
424
  }, [
451
425
  "ret",
@@ -454,13 +428,32 @@ async function resolve(input) {
454
428
  "P\"2!\"2\"\"/#"
455
429
  ]), {});
456
430
  }
457
- if (ctx.module.args && Array.isArray(ctx.module.args)) {
431
+ if (ctx.module.args) {
458
432
  const args = await (0, _powerlines_schema.extract)(ctx.input.context, ctx.module.args);
459
- if (!(0, _stryke_type_checks_is_set_object.isSetObject)(args) || !(0, _stryke_json.isJsonSchemaTupleType)(args.schema)) throw new TypeError(`Command arguments for command at path "${ctx.input.command.path}" must resolve to a tuple.`);
460
- ctx.output.args = args.schema.items.map(__assignType((item) => resolveCommandArgument(item), [
461
- "item",
433
+ if ((0, _stryke_type_checks_is_set_object.isSetObject)(args)) {
434
+ if (!(0, _stryke_json.isJsonSchemaTupleType)(args.schema) && !(0, _powerlines_schema.isJsonSchemaArray)(args.schema)) throw new TypeError(`Command arguments for command at path "${ctx.input.command.path}" must resolve to a tuple${args?.schema?.type ? `, instead received ${JSON.stringify(args.schema.type)}` : ""}.`);
435
+ if (Array.isArray(args.schema.items)) ctx.output.args = args.schema.items.map(__assignType((item) => resolveCommandParameter(item, {
436
+ fallbackRequired: true,
437
+ includeBooleanOptionFields: false
438
+ }), [
439
+ "item",
440
+ "",
441
+ "P\"2!\"/\""
442
+ ]));
443
+ }
444
+ }
445
+ const parameters = ctx.reflection?.getParameters() ?? [];
446
+ if (parameters.length > 0) {
447
+ const hasOptions = parameters[0] && (parameters[0].type.kind === _powerlines_deepkit_vendor_type.ReflectionKind.objectLiteral || parameters[0].type.kind === _powerlines_deepkit_vendor_type.ReflectionKind.class);
448
+ if (hasOptions && !ctx.module.options) {
449
+ const optionsReflection = _powerlines_deepkit_vendor_type.ReflectionClass.from(parameters[0]?.type);
450
+ for (const property of optionsReflection.getProperties()) ctx.output.options[property.getNameAsString()] = require_deepkit.resolveCommandOption(ctx, property);
451
+ }
452
+ if (!ctx.module.args) ctx.output.args = (hasOptions ? parameters.slice(1) : parameters).map(__assignType((arg, index) => require_deepkit.resolveCommandArgument(ctx, index, arg), [
453
+ "arg",
454
+ "index",
462
455
  "",
463
- "P\"2!\"/\""
456
+ "P\"2!\"2\"\"/#"
464
457
  ]));
465
458
  }
466
459
  } else require_helpers.resolveVirtualCommand(ctx);
@@ -1,15 +1,18 @@
1
1
  import { getDynamicPathSegmentName, isDynamicPathSegment } from "../plugin-utils/context-helpers.mjs";
2
2
  import { getGlobalOptions } from "../helpers/utilities.mjs";
3
3
  import { applyArgsDefaults, applyDefaults, applyOptionsDefaults, resolveVirtualCommand } from "./helpers.mjs";
4
- import { addProperty, extract, getPropertiesList, resolveModule } from "@powerlines/schema";
4
+ import { resolveCommandArgument, resolveCommandOption } from "./deepkit.mjs";
5
+ import { addProperty, extract, getPropertiesList, isJsonSchemaArray, resolveModule } from "@powerlines/schema";
5
6
  import { toArray } from "@stryke/convert/to-array";
6
7
  import { replacePath } from "@stryke/path/replace";
7
8
  import { constantCase } from "@stryke/string-format/constant-case";
8
9
  import { isSetObject } from "@stryke/type-checks/is-set-object";
9
10
  import { isSetString } from "@stryke/type-checks/is-set-string";
10
11
  import { titleCase } from "@stryke/string-format/title-case";
12
+ import { ReflectionClass, ReflectionFunction, ReflectionKind, reflect } from "@powerlines/deepkit/vendor/type";
11
13
  import { isBoolean } from "@stryke/type-checks/is-boolean";
12
14
  import { getUnique } from "@stryke/helpers/get-unique";
15
+ import { isFunction } from "@stryke/type-checks/is-function";
13
16
  import { esbuildPlugin } from "@powerlines/deepkit/esbuild-plugin";
14
17
  import { isJsonSchemaObjectType, isJsonSchemaTupleType } from "@stryke/json";
15
18
 
@@ -223,44 +226,6 @@ resolveCommandParameter.__type = [
223
226
  "resolveCommandParameter",
224
227
  "P#2!P)4\")4#M2$P\"w%\"w&J/'"
225
228
  ];
226
- /**
227
- * Resolves a command option from the given schema.
228
- *
229
- * @param schema - The command option schema, which can be a command option configuration or a JSON schema input.
230
- * @returns The resolved command option definition.
231
- */
232
- function resolveCommandOption(schema) {
233
- return resolveCommandParameter(schema, {
234
- fallbackRequired: false,
235
- includeBooleanOptionFields: true
236
- });
237
- }
238
- resolveCommandOption.__type = [
239
- "schema",
240
- "CommandOption",
241
- "resolveCommandOption",
242
- "Resolves a command option from the given schema.",
243
- "P#2!\"w\"/#?$"
244
- ];
245
- /**
246
- * Resolves a command argument from the given schema.
247
- *
248
- * @param schema - The command argument schema, which can be a command argument configuration or a JSON schema input.
249
- * @returns The resolved command argument definition.
250
- */
251
- function resolveCommandArgument(schema) {
252
- return resolveCommandParameter(schema, {
253
- fallbackRequired: true,
254
- includeBooleanOptionFields: false
255
- });
256
- }
257
- resolveCommandArgument.__type = [
258
- "schema",
259
- "CommandArgument",
260
- "resolveCommandArgument",
261
- "Resolves a command argument from the given schema.",
262
- "P#2!\"w\"/#?$"
263
- ];
264
229
  async function preprocess(input) {
265
230
  const { context, command, parent } = input;
266
231
  const title = command.title || `${parent?.title ? `${parent.virtual ? parent.title.replace(/(?:c|C)ommands?$/, "").trim() : parent.title} - ` : ""}${titleCase(command.name)}${command.virtual ? " Commands" : ""}`;
@@ -270,7 +235,6 @@ async function preprocess(input) {
270
235
  alias: [],
271
236
  icon: parent?.icon,
272
237
  tags: parent?.tags ?? [],
273
- source: "file",
274
238
  ...command,
275
239
  title,
276
240
  options: parent === null ? getGlobalOptions(context, command) : {},
@@ -291,6 +255,12 @@ async function preprocess(input) {
291
255
  resolve: { skipNodeModulesBundle: true }
292
256
  }));
293
257
  }
258
+ if (!command.virtual) {
259
+ if (!result.module?.default) throw new Error(`The command entry file "${input.command.entry.input?.file || input.command.path}" does not include a handler function as its default export - this is required for command resolution and execution.`);
260
+ const type = reflect(result.module.default);
261
+ if (type.kind !== ReflectionKind.function) throw new Error(`The command entry file "${input.command.entry.input?.file || input.command.path}" does not have a valid function as its default export - this is required for command resolution and execution.`);
262
+ result.reflection = new ReflectionFunction(type);
263
+ }
294
264
  return result;
295
265
  }
296
266
  preprocess.__type = [
@@ -441,11 +411,15 @@ async function resolve(input) {
441
411
  if (isSetString(metadata.alias) || Array.isArray(metadata.alias) && metadata.alias.length > 0) ctx.output.alias = toArray(metadata.alias);
442
412
  if (isSetString(metadata.icon)) ctx.output.icon = metadata.icon;
443
413
  if (isSetString(metadata.tags)) ctx.output.tags = getUnique(ctx.output.tags.concat(toArray(metadata.tags)));
444
- if (isSetObject(ctx.module.options)) {
414
+ ctx.output.description ??= ctx.input.command.description || isFunction(ctx.reflection?.getDescription) ? ctx.reflection?.getDescription() : ctx.reflection?.description;
415
+ if (ctx.module.options) {
445
416
  const options = await extract(ctx.input.context, ctx.module.options);
446
417
  if (!isSetObject(options) || !isJsonSchemaObjectType(options.schema)) throw new TypeError(`Command options for command at path "${ctx.input.command.path}" must resolve to an object.`);
447
418
  ctx.output.options = getPropertiesList(options).reduce(__assignType((ret, property) => {
448
- ret[property.name] = resolveCommandOption(property);
419
+ ret[property.name] = resolveCommandParameter(property, {
420
+ fallbackRequired: false,
421
+ includeBooleanOptionFields: true
422
+ });
449
423
  return ret;
450
424
  }, [
451
425
  "ret",
@@ -454,13 +428,32 @@ async function resolve(input) {
454
428
  "P\"2!\"2\"\"/#"
455
429
  ]), {});
456
430
  }
457
- if (ctx.module.args && Array.isArray(ctx.module.args)) {
431
+ if (ctx.module.args) {
458
432
  const args = await extract(ctx.input.context, ctx.module.args);
459
- if (!isSetObject(args) || !isJsonSchemaTupleType(args.schema)) throw new TypeError(`Command arguments for command at path "${ctx.input.command.path}" must resolve to a tuple.`);
460
- ctx.output.args = args.schema.items.map(__assignType((item) => resolveCommandArgument(item), [
461
- "item",
433
+ if (isSetObject(args)) {
434
+ if (!isJsonSchemaTupleType(args.schema) && !isJsonSchemaArray(args.schema)) throw new TypeError(`Command arguments for command at path "${ctx.input.command.path}" must resolve to a tuple${args?.schema?.type ? `, instead received ${JSON.stringify(args.schema.type)}` : ""}.`);
435
+ if (Array.isArray(args.schema.items)) ctx.output.args = args.schema.items.map(__assignType((item) => resolveCommandParameter(item, {
436
+ fallbackRequired: true,
437
+ includeBooleanOptionFields: false
438
+ }), [
439
+ "item",
440
+ "",
441
+ "P\"2!\"/\""
442
+ ]));
443
+ }
444
+ }
445
+ const parameters = ctx.reflection?.getParameters() ?? [];
446
+ if (parameters.length > 0) {
447
+ const hasOptions = parameters[0] && (parameters[0].type.kind === ReflectionKind.objectLiteral || parameters[0].type.kind === ReflectionKind.class);
448
+ if (hasOptions && !ctx.module.options) {
449
+ const optionsReflection = ReflectionClass.from(parameters[0]?.type);
450
+ for (const property of optionsReflection.getProperties()) ctx.output.options[property.getNameAsString()] = resolveCommandOption(ctx, property);
451
+ }
452
+ if (!ctx.module.args) ctx.output.args = (hasOptions ? parameters.slice(1) : parameters).map(__assignType((arg, index) => resolveCommandArgument(ctx, index, arg), [
453
+ "arg",
454
+ "index",
462
455
  "",
463
- "P\"2!\"/\""
456
+ "P\"2!\"2\"\"/#"
464
457
  ]));
465
458
  }
466
459
  } else resolveVirtualCommand(ctx);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shell-shock/core",
3
- "version": "0.17.15",
3
+ "version": "0.17.17",
4
4
  "private": false,
5
5
  "description": "A package containing the core Shell Shock functionality used to build and manage a command-line application.",
6
6
  "keywords": ["shell-shock", "powerlines", "storm-software"],
@@ -407,5 +407,5 @@
407
407
  "typescript": "^6.0.3"
408
408
  },
409
409
  "publishConfig": { "access": "public" },
410
- "gitHead": "302eeb47bc029bb0105ec572faecfe398a30d3c1"
410
+ "gitHead": "8c9f000d243ed0b6ac67b2be112429ddeccd0617"
411
411
  }