@shell-shock/core 0.17.16 → 0.17.18

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, "docs" | "types" | "prepare" | "create" | "clean" | "lint" | "test" | "build" | "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, "docs" | "types" | "prepare" | "create" | "clean" | "lint" | "test" | "build" | "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
@@ -13,6 +13,7 @@ let _powerlines_plugin_alloy_core_contexts_context = require("@powerlines/plugin
13
13
  let _powerlines_plugin_alloy_markdown_components_markdown_file = require("@powerlines/plugin-alloy/markdown/components/markdown-file");
14
14
  let _powerlines_plugin_alloy_markdown_components_markdown_table = require("@powerlines/plugin-alloy/markdown/components/markdown-table");
15
15
  let _stryke_path_join = require("@stryke/path/join");
16
+ let _stryke_type_checks_is_undefined = require("@stryke/type-checks/is-undefined");
16
17
 
17
18
  //#region src/components/docs.tsx
18
19
  const __ΩRequired = [
@@ -43,18 +44,20 @@ function CommandOptionsDocs(props) {
43
44
  const { command } = props;
44
45
  if (Object.keys(command.options).length === 0) return _alloy_js_core.code`This command does not have any options.`;
45
46
  return (0, _alloy_js_core_jsx_runtime.createComponent)(_powerlines_plugin_alloy_markdown_components_markdown_table.MarkdownTable, { get data() {
46
- return require_reflect.sortOptions(Object.values(command.options)).map(__assignType((option) => {
47
- return {
47
+ return require_reflect.sortOptions(Object.values(command.options)).reduce(__assignType((ret, option) => {
48
+ ret.push({
48
49
  name: option.name.trim(),
49
50
  description: option.description.trim(),
50
- defaultValue: option.default ? String(option.default)?.includes("\"") ? option.default : `\`${Array.isArray(option.default) ? option.default.join(", ") : option.default}\`` : "",
51
+ defaultValue: (0, _stryke_type_checks_is_undefined.isUndefined)(option.default) ? "" : JSON.stringify(option.default),
51
52
  required: !option.required || option.default ? "" : "✔"
52
- };
53
+ });
54
+ return ret;
53
55
  }, [
56
+ "ret",
54
57
  "option",
55
58
  "",
56
- "P\"2!\"/\""
57
- ]));
59
+ "P\"2!\"2\"\"/#"
60
+ ]), []);
58
61
  } });
59
62
  }
60
63
  CommandOptionsDocs.__type = [
@@ -75,18 +78,26 @@ const __ΩCommandDocsUsageExampleProps = [
75
78
  "CommandTree",
76
79
  "command",
77
80
  "The command to generate the usage example for.",
81
+ "expand",
82
+ true,
83
+ "Whether to add expand/collapse details tags around the usage example. This is useful for hiding long usage examples by default.",
78
84
  "CommandDocsUsageExampleProps",
79
- "PP.!.\".#.$J4%8>&?'\"w(4)?*Mw+y"
85
+ "PP.!.\".#.$J4%8>&?'\"w(4)?*)4+8>,?-Mw.y"
80
86
  ];
81
87
  /**
82
88
  * Generates the markdown documentation for a command.
83
89
  */
84
90
  function CommandDocsUsageExample(props) {
85
- const { packageManager = "npm", command } = props;
91
+ const { packageManager = "npm", command, expand = true } = props;
86
92
  const context = (_powerlines_plugin_alloy_core_contexts_context.usePowerlines.Ω = [["Context", "\"w!"]], (0, _powerlines_plugin_alloy_core_contexts_context.usePowerlines)());
87
93
  return [
88
- (0, _alloy_js_core_jsx_runtime.createIntrinsic)("hbr", {}),
89
- _alloy_js_core.code`\`\`\`bash `,
94
+ (0, _alloy_js_core_jsx_runtime.createComponent)(_alloy_js_core.Show, {
95
+ when: expand,
96
+ fallback: _alloy_js_core.code`\`\`\`bash `,
97
+ children: _alloy_js_core.code`<details>
98
+ <summary>Using ${packageManager}</summary>
99
+ \`\`\`bash `
100
+ }),
90
101
  (0, _alloy_js_core_jsx_runtime.createIntrinsic)("hbr", {}),
91
102
  (0, _alloy_js_core_jsx_runtime.createComponent)(require_components_usage.Usage, {
92
103
  command,
@@ -96,7 +107,12 @@ function CommandDocsUsageExample(props) {
96
107
  packageManager
97
108
  }),
98
109
  (0, _alloy_js_core_jsx_runtime.createIntrinsic)("hbr", {}),
99
- _alloy_js_core.code`\`\`\``,
110
+ (0, _alloy_js_core_jsx_runtime.createComponent)(_alloy_js_core.Show, {
111
+ when: expand,
112
+ fallback: _alloy_js_core.code`\`\`\` `,
113
+ children: _alloy_js_core.code`\`\`\`
114
+ </details> `
115
+ }),
100
116
  (0, _alloy_js_core_jsx_runtime.createIntrinsic)("hbr", {})
101
117
  ];
102
118
  }
@@ -26,6 +26,12 @@ interface CommandDocsUsageExampleProps {
26
26
  * The command to generate the usage example for.
27
27
  */
28
28
  command: CommandTree;
29
+ /**
30
+ * Whether to add expand/collapse details tags around the usage example. This is useful for hiding long usage examples by default.
31
+ *
32
+ * @defaultValue true
33
+ */
34
+ expand?: boolean;
29
35
  }
30
36
  /**
31
37
  * Generates the markdown documentation for a command.
@@ -1 +1 @@
1
- {"version":3,"file":"docs.d.cts","names":[],"sources":["../../src/components/docs.tsx"],"mappings":";;;;UAmCiB,uBAAA;;AAAjB;;EAIE,OAAA,EAAS,WAAW;AAAA;AAAA;AAMtB;;AANsB,iBAMN,kBAAA,CAAmB,KAAA,EAAO,uBAAuB,4BAAA,QAAA;AAAA,UA4BhD,4BAAA;EA5ByB;;;;AAAuB;AA4BjE;;;EASE,cAAA;EAAA;;;EAKA,OAAA,EAAS,WAAW;AAAA;AAMtB;;;AAAA,iBAAgB,uBAAA,CAAwB,KAAA,EAAO,4BAA4B,4BAAA,QAAA;AAAA,UAsB1D,gBAAA;EAtBuB;;;AAAmC;AAsB3E;;;;EASE,WAAA;EAYgB;;;EAPhB,OAAA,EAAS,WAAA;EAAT;;;;;EAOA,aAAA,GAAgB,QAAA,CAAS,4BAAA;AAAA;AAM3B;;;AAAA,iBAAgB,WAAA,CAAY,KAAA,EAAO,gBAAgB,4BAAA,QAAA;AAAA,UAwClC,oBAAA,SAA6B,OAAA,CAAQ,iBAAA;EAxC1B;;;AAAuB;AAwCnD;;;;EASE,WAAA;EAT4C;;;EAc5C,OAAA,EAAS,WAAA;AAAA;;;;iBAMK,eAAA,CAAgB,KAAA,EAAO,oBAAoB,4BAAA,QAAA"}
1
+ {"version":3,"file":"docs.d.cts","names":[],"sources":["../../src/components/docs.tsx"],"mappings":";;;;UAoCiB,uBAAA;;AAAjB;;EAIE,OAAA,EAAS,WAAW;AAAA;AAAA;AAMtB;;AANsB,iBAMN,kBAAA,CAAmB,KAAA,EAAO,uBAAuB,4BAAA,QAAA;AAAA,UAgChD,4BAAA;EAhCyB;;;;AAAuB;AAgCjE;;;EASE,cAAA;EAAA;;;EAKA,OAAA,EAAS,WAAW;EAOd;AAAA;AAMR;;;EANE,MAAA;AAAA;;;;iBAMc,uBAAA,CAAwB,KAAA,EAAO,4BAA4B,4BAAA,QAAA;AAAA,UA4B1D,gBAAA;EAAgB;;;;;;;;EAS/B,WAAA;EAKS;;;EAAT,OAAA,EAAS,WAAA;EAO4C;AAAA;AAMvD;;;EANE,aAAA,GAAgB,QAAA,CAAS,4BAAA;AAAA;;;;iBAMX,WAAA,CAAY,KAAA,EAAO,gBAAgB,4BAAA,QAAA;AAAA,UAwClC,oBAAA,SAA6B,OAAA,CAAQ,iBAAA;EAAhB;;;;;;;;EASpC,WAAA;EAAA;;;EAKA,OAAA,EAAS,WAAA;AAAA;AAMX;;;AAAA,iBAAgB,eAAA,CAAgB,KAAA,EAAO,oBAAoB,4BAAA,QAAA"}
@@ -26,6 +26,12 @@ interface CommandDocsUsageExampleProps {
26
26
  * The command to generate the usage example for.
27
27
  */
28
28
  command: CommandTree;
29
+ /**
30
+ * Whether to add expand/collapse details tags around the usage example. This is useful for hiding long usage examples by default.
31
+ *
32
+ * @defaultValue true
33
+ */
34
+ expand?: boolean;
29
35
  }
30
36
  /**
31
37
  * Generates the markdown documentation for a command.
@@ -12,6 +12,7 @@ import { usePowerlines } from "@powerlines/plugin-alloy/core/contexts/context";
12
12
  import { MarkdownFile } from "@powerlines/plugin-alloy/markdown/components/markdown-file";
13
13
  import { MarkdownTable } from "@powerlines/plugin-alloy/markdown/components/markdown-table";
14
14
  import { joinPaths } from "@stryke/path/join";
15
+ import { isUndefined } from "@stryke/type-checks/is-undefined";
15
16
 
16
17
  //#region src/components/docs.tsx
17
18
  const __ΩRequired = [
@@ -42,18 +43,20 @@ function CommandOptionsDocs(props) {
42
43
  const { command } = props;
43
44
  if (Object.keys(command.options).length === 0) return code`This command does not have any options.`;
44
45
  return createComponent(MarkdownTable, { get data() {
45
- return sortOptions(Object.values(command.options)).map(__assignType((option) => {
46
- return {
46
+ return sortOptions(Object.values(command.options)).reduce(__assignType((ret, option) => {
47
+ ret.push({
47
48
  name: option.name.trim(),
48
49
  description: option.description.trim(),
49
- defaultValue: option.default ? String(option.default)?.includes("\"") ? option.default : `\`${Array.isArray(option.default) ? option.default.join(", ") : option.default}\`` : "",
50
+ defaultValue: isUndefined(option.default) ? "" : JSON.stringify(option.default),
50
51
  required: !option.required || option.default ? "" : "✔"
51
- };
52
+ });
53
+ return ret;
52
54
  }, [
55
+ "ret",
53
56
  "option",
54
57
  "",
55
- "P\"2!\"/\""
56
- ]));
58
+ "P\"2!\"2\"\"/#"
59
+ ]), []);
57
60
  } });
58
61
  }
59
62
  CommandOptionsDocs.__type = [
@@ -74,18 +77,26 @@ const __ΩCommandDocsUsageExampleProps = [
74
77
  "CommandTree",
75
78
  "command",
76
79
  "The command to generate the usage example for.",
80
+ "expand",
81
+ true,
82
+ "Whether to add expand/collapse details tags around the usage example. This is useful for hiding long usage examples by default.",
77
83
  "CommandDocsUsageExampleProps",
78
- "PP.!.\".#.$J4%8>&?'\"w(4)?*Mw+y"
84
+ "PP.!.\".#.$J4%8>&?'\"w(4)?*)4+8>,?-Mw.y"
79
85
  ];
80
86
  /**
81
87
  * Generates the markdown documentation for a command.
82
88
  */
83
89
  function CommandDocsUsageExample(props) {
84
- const { packageManager = "npm", command } = props;
90
+ const { packageManager = "npm", command, expand = true } = props;
85
91
  const context = (usePowerlines.Ω = [["Context", "\"w!"]], usePowerlines());
86
92
  return [
87
- createIntrinsic("hbr", {}),
88
- code`\`\`\`bash `,
93
+ createComponent(Show, {
94
+ when: expand,
95
+ fallback: code`\`\`\`bash `,
96
+ children: code`<details>
97
+ <summary>Using ${packageManager}</summary>
98
+ \`\`\`bash `
99
+ }),
89
100
  createIntrinsic("hbr", {}),
90
101
  createComponent(Usage, {
91
102
  command,
@@ -95,7 +106,12 @@ function CommandDocsUsageExample(props) {
95
106
  packageManager
96
107
  }),
97
108
  createIntrinsic("hbr", {}),
98
- code`\`\`\``,
109
+ createComponent(Show, {
110
+ when: expand,
111
+ fallback: code`\`\`\` `,
112
+ children: code`\`\`\`
113
+ </details> `
114
+ }),
99
115
  createIntrinsic("hbr", {})
100
116
  ];
101
117
  }
@@ -54,11 +54,11 @@ function Usage(props) {
54
54
  "segment",
55
55
  "",
56
56
  "P\"2!\"/\""
57
- ])).join(" ")}` : ""}${Object.values(command.children).length > 0 ? " [commands]" : ""}${command.args.length > 0 ? ` ${command.args.map(__assignType((param) => `<${(0, _stryke_string_format_snake_case.snakeCase)(param.name)}${(param.type === "string" || param.type === "number") && param.variadic ? "..." : ""}>`, [
57
+ ])).join(" ")}` : ""}${Object.values(command.children).length > 0 ? " <commands>" : ""}${command.args.length > 0 ? command.args.map(__assignType((param) => `<${(0, _stryke_string_format_snake_case.snakeCase)(param.name)}${(param.type === "string" || param.type === "number") && param.variadic ? "..." : ""}>`, [
58
58
  "param",
59
59
  "",
60
60
  "P\"2!\"/\""
61
- ])).join(" ")}` : ""} [options]`),
61
+ ])).join(" ") : ""} [options]`),
62
62
  (0, _alloy_js_core_jsx_runtime.createComponent)(_alloy_js_core.Show, {
63
63
  get when() {
64
64
  return command.args.length > 0;
@@ -66,7 +66,9 @@ function Usage(props) {
66
66
  get children() {
67
67
  return [
68
68
  (0, _alloy_js_core_jsx_runtime.createIntrinsic)("hbr", {}),
69
- _alloy_js_core.code`$ `,
69
+ (0, _alloy_js_core_jsx_runtime.createIntrinsic)("hbr", {}),
70
+ _alloy_js_core.code`# or with options before arguments: `,
71
+ (0, _alloy_js_core_jsx_runtime.createIntrinsic)("hbr", {}),
70
72
  (0, _alloy_js_core_jsx_runtime.createComponent)(_alloy_js_core.Switch, { get children() {
71
73
  return [
72
74
  (0, _alloy_js_core_jsx_runtime.createComponent)(_alloy_js_core.Match, {
@@ -91,11 +93,11 @@ function Usage(props) {
91
93
  "segment",
92
94
  "",
93
95
  "P\"2!\"/\""
94
- ])).join(" ")}` : ""}${Object.values(command.children).length > 0 ? " [commands]" : ""} [options] ${command.args.length > 0 ? ` ${command.args.map(__assignType((param) => `<${(0, _stryke_string_format_snake_case.snakeCase)(param.name)}${(param.type === "string" || param.type === "number") && param.variadic ? "..." : ""}>`, [
96
+ ])).join(" ")}` : ""}${Object.values(command.children).length > 0 ? " <commands>" : ""} [options] ${command.args.length > 0 ? command.args.map(__assignType((param) => `<${(0, _stryke_string_format_snake_case.snakeCase)(param.name)}${(param.type === "string" || param.type === "number") && param.variadic ? "..." : ""}>`, [
95
97
  "param",
96
98
  "",
97
99
  "P\"2!\"/\""
98
- ])).join(" ")}` : ""}`)
100
+ ])).join(" ") : ""}`)
99
101
  ];
100
102
  }
101
103
  })
@@ -53,11 +53,11 @@ function Usage(props) {
53
53
  "segment",
54
54
  "",
55
55
  "P\"2!\"/\""
56
- ])).join(" ")}` : ""}${Object.values(command.children).length > 0 ? " [commands]" : ""}${command.args.length > 0 ? ` ${command.args.map(__assignType((param) => `<${snakeCase(param.name)}${(param.type === "string" || param.type === "number") && param.variadic ? "..." : ""}>`, [
56
+ ])).join(" ")}` : ""}${Object.values(command.children).length > 0 ? " <commands>" : ""}${command.args.length > 0 ? command.args.map(__assignType((param) => `<${snakeCase(param.name)}${(param.type === "string" || param.type === "number") && param.variadic ? "..." : ""}>`, [
57
57
  "param",
58
58
  "",
59
59
  "P\"2!\"/\""
60
- ])).join(" ")}` : ""} [options]`),
60
+ ])).join(" ") : ""} [options]`),
61
61
  createComponent(Show, {
62
62
  get when() {
63
63
  return command.args.length > 0;
@@ -65,7 +65,9 @@ function Usage(props) {
65
65
  get children() {
66
66
  return [
67
67
  createIntrinsic("hbr", {}),
68
- code`$ `,
68
+ createIntrinsic("hbr", {}),
69
+ code`# or with options before arguments: `,
70
+ createIntrinsic("hbr", {}),
69
71
  createComponent(Switch, { get children() {
70
72
  return [
71
73
  createComponent(Match, {
@@ -90,11 +92,11 @@ function Usage(props) {
90
92
  "segment",
91
93
  "",
92
94
  "P\"2!\"/\""
93
- ])).join(" ")}` : ""}${Object.values(command.children).length > 0 ? " [commands]" : ""} [options] ${command.args.length > 0 ? ` ${command.args.map(__assignType((param) => `<${snakeCase(param.name)}${(param.type === "string" || param.type === "number") && param.variadic ? "..." : ""}>`, [
95
+ ])).join(" ")}` : ""}${Object.values(command.children).length > 0 ? " <commands>" : ""} [options] ${command.args.length > 0 ? command.args.map(__assignType((param) => `<${snakeCase(param.name)}${(param.type === "string" || param.type === "number") && param.variadic ? "..." : ""}>`, [
94
96
  "param",
95
97
  "",
96
98
  "P\"2!\"/\""
97
- ])).join(" ")}` : ""}`)
99
+ ])).join(" ") : ""}`)
98
100
  ];
99
101
  }
100
102
  })
package/dist/package.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
 
2
2
  //#region package.json
3
- var version = "0.17.15";
3
+ var version = "0.17.17";
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.15";
2
+ var version = "0.17.17";
3
3
 
4
4
  //#endregion
5
5
  export { version };
@@ -8,11 +8,12 @@ function __assignType(fn, args) {
8
8
  * Sort command options alphabetically by name, placing boolean options with negatives appropriately.
9
9
  *
10
10
  * @param options - The array of command options to sort.
11
+ * @param skipNegatives - Whether to skip negative options when sorting (default: true).
11
12
  * @returns A new array of sorted command options.
12
13
  */
13
- function sortOptions(options) {
14
+ function sortOptions(options, skipNegatives = true) {
14
15
  if (!options || options.length === 0) return [];
15
- return options.filter(__assignType((arg) => arg.type !== "boolean" || arg.variadic || !arg.isNegativeOf, [
16
+ return options.filter(__assignType((arg) => arg.type !== "boolean" || arg.variadic || !skipNegatives || !arg.isNegativeOf, [
16
17
  "arg",
17
18
  "",
18
19
  "P\"2!\"/\""
@@ -42,9 +43,10 @@ function sortOptions(options) {
42
43
  sortOptions.__type = [
43
44
  "CommandOption",
44
45
  "options",
46
+ "skipNegatives",
45
47
  "sortOptions",
46
48
  "Sort command options alphabetically by name, placing boolean options with negatives appropriately.",
47
- "P\"w!F2\"\"w!F/#?$"
49
+ "P\"w!F2\"\"2#\"w!F/$?%"
48
50
  ];
49
51
 
50
52
  //#endregion
@@ -5,9 +5,10 @@ import { CommandOption } from "../types/command.cjs";
5
5
  * Sort command options alphabetically by name, placing boolean options with negatives appropriately.
6
6
  *
7
7
  * @param options - The array of command options to sort.
8
+ * @param skipNegatives - Whether to skip negative options when sorting (default: true).
8
9
  * @returns A new array of sorted command options.
9
10
  */
10
- declare function sortOptions(options: CommandOption[]): CommandOption[];
11
+ declare function sortOptions(options: CommandOption[], skipNegatives?: boolean): CommandOption[];
11
12
  //#endregion
12
13
  export { sortOptions };
13
14
  //# sourceMappingURL=reflect.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"reflect.d.cts","names":[],"sources":["../../src/plugin-utils/reflect.ts"],"mappings":";;;;;AA0BA;;;;iBAAgB,WAAA,CAAY,OAAA,EAAS,aAAA,KAAkB,aAAa"}
1
+ {"version":3,"file":"reflect.d.cts","names":[],"sources":["../../src/plugin-utils/reflect.ts"],"mappings":";;;;;AA2BA;;;;;iBAAgB,WAAA,CACd,OAAA,EAAS,aAAA,IACT,aAAA,aACC,aAAa"}
@@ -5,9 +5,10 @@ import { CommandOption } from "../types/command.mjs";
5
5
  * Sort command options alphabetically by name, placing boolean options with negatives appropriately.
6
6
  *
7
7
  * @param options - The array of command options to sort.
8
+ * @param skipNegatives - Whether to skip negative options when sorting (default: true).
8
9
  * @returns A new array of sorted command options.
9
10
  */
10
- declare function sortOptions(options: CommandOption[]): CommandOption[];
11
+ declare function sortOptions(options: CommandOption[], skipNegatives?: boolean): CommandOption[];
11
12
  //#endregion
12
13
  export { sortOptions };
13
14
  //# sourceMappingURL=reflect.d.mts.map
@@ -7,11 +7,12 @@ function __assignType(fn, args) {
7
7
  * Sort command options alphabetically by name, placing boolean options with negatives appropriately.
8
8
  *
9
9
  * @param options - The array of command options to sort.
10
+ * @param skipNegatives - Whether to skip negative options when sorting (default: true).
10
11
  * @returns A new array of sorted command options.
11
12
  */
12
- function sortOptions(options) {
13
+ function sortOptions(options, skipNegatives = true) {
13
14
  if (!options || options.length === 0) return [];
14
- return options.filter(__assignType((arg) => arg.type !== "boolean" || arg.variadic || !arg.isNegativeOf, [
15
+ return options.filter(__assignType((arg) => arg.type !== "boolean" || arg.variadic || !skipNegatives || !arg.isNegativeOf, [
15
16
  "arg",
16
17
  "",
17
18
  "P\"2!\"/\""
@@ -41,9 +42,10 @@ function sortOptions(options) {
41
42
  sortOptions.__type = [
42
43
  "CommandOption",
43
44
  "options",
45
+ "skipNegatives",
44
46
  "sortOptions",
45
47
  "Sort command options alphabetically by name, placing boolean options with negatives appropriately.",
46
- "P\"w!F2\"\"w!F/#?$"
48
+ "P\"w!F2\"\"2#\"w!F/$?%"
47
49
  ];
48
50
 
49
51
  //#endregion
@@ -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.16",
3
+ "version": "0.17.18",
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": "fb690df8ec51cb881e90d3bb9b347f7f15b06e07"
410
+ "gitHead": "4ca0ac0ff9ada03aea6667c89a04b54dc73ff40b"
411
411
  }