@shell-shock/core 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/api.cjs.map +1 -1
  2. package/dist/api.d.cts.map +1 -1
  3. package/dist/api.d.mts.map +1 -1
  4. package/dist/api.mjs.map +1 -1
  5. package/dist/components/docs.cjs +87 -17
  6. package/dist/components/docs.cjs.map +1 -1
  7. package/dist/components/docs.d.cts +26 -1
  8. package/dist/components/docs.d.cts.map +1 -1
  9. package/dist/components/docs.d.mts +26 -1
  10. package/dist/components/docs.d.mts.map +1 -1
  11. package/dist/components/docs.mjs +88 -19
  12. package/dist/components/docs.mjs.map +1 -1
  13. package/dist/components/index.cjs +1 -0
  14. package/dist/components/index.d.cts +2 -2
  15. package/dist/components/index.d.mts +2 -2
  16. package/dist/components/index.mjs +2 -2
  17. package/dist/helpers/automd.cjs +59 -0
  18. package/dist/helpers/automd.cjs.map +1 -0
  19. package/dist/helpers/automd.mjs +58 -0
  20. package/dist/helpers/automd.mjs.map +1 -0
  21. package/dist/helpers/resolve-command.cjs +1 -1
  22. package/dist/helpers/resolve-command.cjs.map +1 -1
  23. package/dist/helpers/resolve-command.mjs +1 -1
  24. package/dist/helpers/resolve-command.mjs.map +1 -1
  25. package/dist/plugin.cjs +23 -6
  26. package/dist/plugin.cjs.map +1 -1
  27. package/dist/plugin.d.cts.map +1 -1
  28. package/dist/plugin.d.mts.map +1 -1
  29. package/dist/plugin.mjs +21 -6
  30. package/dist/plugin.mjs.map +1 -1
  31. package/dist/types/command.d.cts +1 -0
  32. package/dist/types/command.d.cts.map +1 -1
  33. package/dist/types/command.d.mts +1 -0
  34. package/dist/types/command.d.mts.map +1 -1
  35. package/dist/types/config.d.cts +3 -2
  36. package/dist/types/config.d.cts.map +1 -1
  37. package/dist/types/config.d.mts +3 -2
  38. package/dist/types/config.d.mts.map +1 -1
  39. package/dist/types/runtime.cjs +0 -0
  40. package/dist/types/runtime.d.cts +24 -0
  41. package/dist/types/runtime.d.cts.map +1 -0
  42. package/dist/types/runtime.d.mts +24 -0
  43. package/dist/types/runtime.d.mts.map +1 -0
  44. package/dist/types/runtime.mjs +1 -0
  45. package/package.json +27 -10
@@ -0,0 +1,59 @@
1
+ const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
2
+ const require_plugin_utils_context_helpers = require('../plugin-utils/context-helpers.cjs');
3
+ const require_components_docs = require('../components/docs.cjs');
4
+ require('../plugin-utils/index.cjs');
5
+ let __alloy_js_core_jsx_runtime = require("@alloy-js/core/jsx-runtime");
6
+ let __alloy_js_core_components = require("@alloy-js/core/components");
7
+ let __powerlines_plugin_alloy_render = require("@powerlines/plugin-alloy/render");
8
+ let __alloy_js_core = require("@alloy-js/core");
9
+ let __alloy_js_markdown = require("@alloy-js/markdown");
10
+ let automd = require("automd");
11
+
12
+ //#region src/helpers/automd.tsx
13
+ /**
14
+ * AutoMD generator to generate CLI command documentation
15
+ *
16
+ * @see https://automd.unjs.io/
17
+ *
18
+ * @param context - The generator context.
19
+ * @returns The generated documentation content.
20
+ */
21
+ const commands = (context) => (0, automd.defineGenerator)({
22
+ name: "commands",
23
+ async generate() {
24
+ return { contents: (0, __powerlines_plugin_alloy_render.renderString)(context, [
25
+ (0, __alloy_js_core_jsx_runtime.createComponent)(__alloy_js_markdown.Heading, {
26
+ level: 2,
27
+ children: "Commands"
28
+ }),
29
+ (0, __alloy_js_core_jsx_runtime.createIntrinsic)("hbr", {}),
30
+ (0, __alloy_js_core_jsx_runtime.createIntrinsic)("hbr", {}),
31
+ (0, __alloy_js_core_jsx_runtime.memo)(() => __alloy_js_core.code`The following commands are available in the ${require_plugin_utils_context_helpers.getAppTitle(context)} CLI application:`),
32
+ (0, __alloy_js_core_jsx_runtime.createIntrinsic)("hbr", {}),
33
+ (0, __alloy_js_core_jsx_runtime.createIntrinsic)("hbr", {}),
34
+ (0, __alloy_js_core_jsx_runtime.createComponent)(__alloy_js_core_components.For, {
35
+ get each() {
36
+ return Object.values(context.commands);
37
+ },
38
+ doubleHardline: true,
39
+ children: (child) => (0, __alloy_js_core_jsx_runtime.createComponent)(__alloy_js_core_components.Show, {
40
+ get when() {
41
+ return !child.isVirtual;
42
+ },
43
+ get children() {
44
+ return (0, __alloy_js_core_jsx_runtime.createComponent)(require_components_docs.CommandDocs, {
45
+ command: child,
46
+ levelOffset: 2
47
+ });
48
+ }
49
+ })
50
+ }),
51
+ (0, __alloy_js_core_jsx_runtime.createIntrinsic)("hbr", {}),
52
+ (0, __alloy_js_core_jsx_runtime.createIntrinsic)("hbr", {})
53
+ ]) };
54
+ }
55
+ });
56
+
57
+ //#endregion
58
+ exports.commands = commands;
59
+ //# sourceMappingURL=automd.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"automd.cjs","names":["code","For","Show","Heading","renderString","defineGenerator","CommandDocs","getAppTitle","commands","context","name","generate","contents","_$createComponent","level","children","_$createIntrinsic","_$memo","each","Object","values","doubleHardline","child","when","isVirtual","command","levelOffset"],"sources":["../../src/helpers/automd.tsx"],"sourcesContent":["/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Shell Shock\n\n This code was released as part of the Shell Shock project. Shell Shock\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/shell-shock.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/shell-shock\n Documentation: https://docs.stormsoftware.com/projects/shell-shock\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport { code } from \"@alloy-js/core\";\nimport { For, Show } from \"@alloy-js/core/components\";\nimport { Heading } from \"@alloy-js/markdown\";\nimport { renderString } from \"@powerlines/plugin-alloy/render\";\nimport { defineGenerator } from \"automd\";\nimport { CommandDocs } from \"../components/docs\";\nimport { getAppTitle } from \"../plugin-utils\";\nimport type { Context } from \"../types/context\";\n\n/**\n * AutoMD generator to generate CLI command documentation\n *\n * @see https://automd.unjs.io/\n *\n * @param context - The generator context.\n * @returns The generated documentation content.\n */\nexport const commands = (context: Context) =>\n defineGenerator({\n name: \"commands\",\n async generate() {\n return {\n contents: renderString(\n context,\n <>\n <Heading level={2}>Commands</Heading>\n <hbr />\n <hbr />\n {code`The following commands are available in the ${getAppTitle(\n context\n )} CLI application:`}\n <hbr />\n <hbr />\n <For each={Object.values(context.commands)} doubleHardline>\n {child => (\n <Show when={!child.isVirtual}>\n <CommandDocs command={child} levelOffset={2} />\n </Show>\n )}\n </For>\n <hbr />\n <hbr />\n </>\n )\n };\n }\n });\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAmCA,MAAaQ,YAAYC,wCACP;CACdC,MAAM;CACN,MAAMC,WAAW;AACf,SAAO,EACLC,6DACEH,SAAO;oDAEJN,6BAAO;IAACW,OAAO;IAACC,UAAA;IAAA,CAAA;oDAAA,OAAA,EAAA,CAAA;oDAAA,OAAA,EAAA,CAAA;+CAGhBf,oBAAI,+CAA+CO,iDAClDE,QACD,CAAA,mBAAmB;oDAAA,OAAA,EAAA,CAAA;oDAAA,OAAA,EAAA,CAAA;oDAGnBR,gCAAG;IAAA,IAACiB,OAAI;AAAA,YAAEC,OAAOC,OAAOX,QAAQD,SAAS;;IAAEa,gBAAc;IAAAN,WACvDO,2DACEpB,iCAAI;KAAA,IAACqB,OAAI;AAAA,aAAE,CAACD,MAAME;;KAAS,IAAAT,WAAA;AAAA,8DACzBT,qCAAW;OAACmB,SAASH;OAAOI,aAAa;OAAC,CAAA;;KAAA,CAAA;IAE9C,CAAA;oDAAA,OAAA,EAAA,CAAA;oDAAA,OAAA,EAAA,CAAA;GAKP,CAAA,EACD;;CAEJ,CAAC"}
@@ -0,0 +1,58 @@
1
+ import { getAppTitle } from "../plugin-utils/context-helpers.mjs";
2
+ import { CommandDocs } from "../components/docs.mjs";
3
+ import "../plugin-utils/index.mjs";
4
+ import { createComponent, createIntrinsic, memo } from "@alloy-js/core/jsx-runtime";
5
+ import { For, Show } from "@alloy-js/core/components";
6
+ import { renderString } from "@powerlines/plugin-alloy/render";
7
+ import { code } from "@alloy-js/core";
8
+ import { Heading } from "@alloy-js/markdown";
9
+ import { defineGenerator } from "automd";
10
+
11
+ //#region src/helpers/automd.tsx
12
+ /**
13
+ * AutoMD generator to generate CLI command documentation
14
+ *
15
+ * @see https://automd.unjs.io/
16
+ *
17
+ * @param context - The generator context.
18
+ * @returns The generated documentation content.
19
+ */
20
+ const commands = (context) => defineGenerator({
21
+ name: "commands",
22
+ async generate() {
23
+ return { contents: renderString(context, [
24
+ createComponent(Heading, {
25
+ level: 2,
26
+ children: "Commands"
27
+ }),
28
+ createIntrinsic("hbr", {}),
29
+ createIntrinsic("hbr", {}),
30
+ memo(() => code`The following commands are available in the ${getAppTitle(context)} CLI application:`),
31
+ createIntrinsic("hbr", {}),
32
+ createIntrinsic("hbr", {}),
33
+ createComponent(For, {
34
+ get each() {
35
+ return Object.values(context.commands);
36
+ },
37
+ doubleHardline: true,
38
+ children: (child) => createComponent(Show, {
39
+ get when() {
40
+ return !child.isVirtual;
41
+ },
42
+ get children() {
43
+ return createComponent(CommandDocs, {
44
+ command: child,
45
+ levelOffset: 2
46
+ });
47
+ }
48
+ })
49
+ }),
50
+ createIntrinsic("hbr", {}),
51
+ createIntrinsic("hbr", {})
52
+ ]) };
53
+ }
54
+ });
55
+
56
+ //#endregion
57
+ export { commands };
58
+ //# sourceMappingURL=automd.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"automd.mjs","names":["code","For","Show","Heading","renderString","defineGenerator","CommandDocs","getAppTitle","commands","context","name","generate","contents","_$createComponent","level","children","_$createIntrinsic","_$memo","each","Object","values","doubleHardline","child","when","isVirtual","command","levelOffset"],"sources":["../../src/helpers/automd.tsx"],"sourcesContent":["/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Shell Shock\n\n This code was released as part of the Shell Shock project. Shell Shock\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/shell-shock.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/shell-shock\n Documentation: https://docs.stormsoftware.com/projects/shell-shock\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport { code } from \"@alloy-js/core\";\nimport { For, Show } from \"@alloy-js/core/components\";\nimport { Heading } from \"@alloy-js/markdown\";\nimport { renderString } from \"@powerlines/plugin-alloy/render\";\nimport { defineGenerator } from \"automd\";\nimport { CommandDocs } from \"../components/docs\";\nimport { getAppTitle } from \"../plugin-utils\";\nimport type { Context } from \"../types/context\";\n\n/**\n * AutoMD generator to generate CLI command documentation\n *\n * @see https://automd.unjs.io/\n *\n * @param context - The generator context.\n * @returns The generated documentation content.\n */\nexport const commands = (context: Context) =>\n defineGenerator({\n name: \"commands\",\n async generate() {\n return {\n contents: renderString(\n context,\n <>\n <Heading level={2}>Commands</Heading>\n <hbr />\n <hbr />\n {code`The following commands are available in the ${getAppTitle(\n context\n )} CLI application:`}\n <hbr />\n <hbr />\n <For each={Object.values(context.commands)} doubleHardline>\n {child => (\n <Show when={!child.isVirtual}>\n <CommandDocs command={child} levelOffset={2} />\n </Show>\n )}\n </For>\n <hbr />\n <hbr />\n </>\n )\n };\n }\n });\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAmCA,MAAaQ,YAAYC,YACvBJ,gBAAgB;CACdK,MAAM;CACN,MAAMC,WAAW;AACf,SAAO,EACLC,UAAUR,aACRK,SAAO;GAAAI,gBAEJV,SAAO;IAACW,OAAO;IAACC,UAAA;IAAA,CAAA;GAAAC,gBAAA,OAAA,EAAA,CAAA;GAAAA,gBAAA,OAAA,EAAA,CAAA;GAAAC,WAGhBjB,IAAI,+CAA+CO,YAClDE,QACD,CAAA,mBAAmB;GAAAO,gBAAA,OAAA,EAAA,CAAA;GAAAA,gBAAA,OAAA,EAAA,CAAA;GAAAH,gBAGnBZ,KAAG;IAAA,IAACiB,OAAI;AAAA,YAAEC,OAAOC,OAAOX,QAAQD,SAAS;;IAAEa,gBAAc;IAAAN,WACvDO,UAAKT,gBACHX,MAAI;KAAA,IAACqB,OAAI;AAAA,aAAE,CAACD,MAAME;;KAAS,IAAAT,WAAA;AAAA,aAAAF,gBACzBP,aAAW;OAACmB,SAASH;OAAOI,aAAa;OAAC,CAAA;;KAAA,CAAA;IAE9C,CAAA;GAAAV,gBAAA,OAAA,EAAA,CAAA;GAAAA,gBAAA,OAAA,EAAA,CAAA;GAKP,CAAA,EACD;;CAEJ,CAAC"}
@@ -75,7 +75,7 @@ function extractCommandParameters(param) {
75
75
  * @returns The reflected command tree.
76
76
  */
77
77
  async function reflectCommandTree(context, command, parent) {
78
- const title = command.title || `${parent?.title ? `${parent.title} - ` : ""}${(0, __stryke_string_format_title_case.titleCase)(command.name)}${command.isVirtual ? " Commands" : ""}`;
78
+ const title = command.title || `${parent?.title ? `${parent.isVirtual ? parent.title.replace(/ Commands$/, "") : parent.title} - ` : ""}${(0, __stryke_string_format_title_case.titleCase)(command.name)}${command.isVirtual ? " Commands" : ""}`;
79
79
  const tree = {
80
80
  ...command,
81
81
  title,
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-command.cjs","names":["reflectType","ReflectionClass","ReflectionKind","ReflectionVisibility","stringifyType","appendPath","commonPath","findFilePath","findFolderName","stripStars","replacePath","resolveParentPath","constantCase","titleCase","isSetObject","isSetString","getAppTitle","getVariableCommandPathName","isVariableCommandPath","getDefaultOptions","resolveCommandDescription","propertyReflection","getDescription","trim","isOptional","getDefaultValue","getType","kind","boolean","array","getTags","title","getNameAsString","number","resolveCommandId","context","file","commandsPath","split","filter","p","Boolean","join","replaceAll","resolveCommandName","path","name","requireExtension","resolveCommandPath","resolveCommandParams","map","findCommandsRoot","config","entry","projectRoot","workspaceConfig","workspaceRoot","Array","isArray","length","sourceRoot","extractCommandParameters","param","description","optional","variadic","type","default","reflectCommandTree","command","parent","isVirtual","tree","variables","options","params","children","input","fs","existsSync","Error","debug","id","function","parameters","firstParam","objectLiteral","class","optionsReflection","from","getProperties","propertyType","alias","env","string","segments","segment","reduce","obj","index","paramName","slice","forEach","push","Object","values","option","types","addProperty","undefined","visibility","public","tags","domain","inputs","every","value"],"sources":["../../src/helpers/resolve-command.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 { reflectType } from \"@powerlines/deepkit/reflect-type\";\nimport type {\n ReflectionProperty,\n TypeParameter\n} from \"@powerlines/deepkit/vendor/type\";\nimport {\n ReflectionClass,\n ReflectionKind,\n ReflectionVisibility,\n stringifyType\n} from \"@powerlines/deepkit/vendor/type\";\nimport { appendPath } from \"@stryke/path/append\";\nimport { commonPath } from \"@stryke/path/common\";\nimport { findFilePath, findFolderName } from \"@stryke/path/file-path-fns\";\nimport { stripStars } from \"@stryke/path/normalize\";\nimport { replacePath } from \"@stryke/path/replace\";\nimport { resolveParentPath } from \"@stryke/path/resolve-parent-path\";\nimport { constantCase } from \"@stryke/string-format/constant-case\";\nimport { titleCase } from \"@stryke/string-format/title-case\";\nimport { isSetObject } from \"@stryke/type-checks/is-set-object\";\nimport { isSetString } from \"@stryke/type-checks/is-set-string\";\nimport {\n getAppTitle,\n getVariableCommandPathName,\n isVariableCommandPath\n} from \"../plugin-utils/context-helpers\";\nimport type {\n CommandInput,\n CommandParam,\n CommandTree,\n NumberCommandOption,\n StringCommandOption\n} from \"../types/command\";\nimport type { Context } from \"../types/context\";\nimport { getDefaultOptions } from \"./utilities\";\n\n/**\n * Resolves the description for a command option based on its reflection.\n *\n * @param propertyReflection - The reflection property of the command option.\n * @returns The resolved description for the command option.\n */\nexport function resolveCommandDescription(\n propertyReflection: ReflectionProperty\n): string {\n return (\n propertyReflection.getDescription()?.trim() ||\n `A${\n propertyReflection.isOptional() && !propertyReflection.getDefaultValue()\n ? \"n optional\"\n : \"\"\n } ${\n propertyReflection.getType().kind === ReflectionKind.boolean\n ? \"flag provided via the command-line\"\n : \"command-line option\"\n } that allows the user to ${\n propertyReflection.getType().kind === ReflectionKind.boolean\n ? \"set the\"\n : propertyReflection.getType().kind === ReflectionKind.array\n ? \"specify custom\"\n : \"specify a custom\"\n } ${\n propertyReflection.getTags().title?.trim() ||\n titleCase(propertyReflection.getNameAsString())\n } ${\n propertyReflection.getType().kind === ReflectionKind.boolean\n ? \"indicator\"\n : `${propertyReflection.getType().kind === ReflectionKind.number ? \"numeric\" : \"string\"} value${\n propertyReflection.getType().kind === ReflectionKind.array\n ? \"s\"\n : \"\"\n }`\n } that will be used in the application.`\n );\n}\n\nexport function resolveCommandId(context: Context, file: string): string {\n return replacePath(findFilePath(file), context.commandsPath)\n .split(\"/\")\n .filter(p => Boolean(p) && !isVariableCommandPath(p))\n .join(\"/\")\n .replaceAll(/^\\/+/g, \"\")\n .replaceAll(/\\/+$/g, \"\")\n .replaceAll(\"/\", \"-\");\n}\n\n/**\n * Finds the command name from the given file path.\n *\n * @param file - The file path to extract the command name from.\n * @returns The command name.\n */\nexport function resolveCommandName(file: string) {\n let path = findFilePath(file);\n let name = findFolderName(file, {\n requireExtension: true\n });\n\n while (isVariableCommandPath(name)) {\n path = resolveParentPath(path);\n name = findFolderName(path, {\n requireExtension: true\n });\n }\n\n return name;\n}\n\nexport function resolveCommandPath(context: Context, file: string): string {\n return replacePath(findFilePath(file), context.commandsPath)\n .replaceAll(/^\\/+/g, \"\")\n .replaceAll(/\\/+$/g, \"\");\n}\n\nexport function resolveCommandParams(context: Context, file: string): string[] {\n return replacePath(findFilePath(file), context.commandsPath)\n .split(\"/\")\n .filter(p => Boolean(p) && isVariableCommandPath(p))\n .map(p => p.replaceAll(/^\\[+/g, \"\").replaceAll(/\\]+$/g, \"\"));\n}\n\nexport function findCommandsRoot(context: Context): string {\n if (isSetString(context.config.entry)) {\n return appendPath(\n appendPath(stripStars(context.config.entry), context.config.projectRoot),\n context.workspaceConfig.workspaceRoot\n );\n } else if (\n isSetObject(context.config.entry) &&\n \"file\" in context.config.entry\n ) {\n return appendPath(\n appendPath(\n stripStars(context.config.entry.file),\n context.config.projectRoot\n ),\n context.workspaceConfig.workspaceRoot\n );\n } else if (\n Array.isArray(context.config.entry) &&\n context.config.entry.length > 0\n ) {\n return commonPath(\n context.config.entry.map(entry =>\n appendPath(\n appendPath(\n stripStars(isSetString(entry) ? entry : entry.file),\n context.config.projectRoot\n ),\n context.workspaceConfig.workspaceRoot\n )\n )\n );\n }\n\n return appendPath(\n context.config.sourceRoot || context.config.projectRoot,\n context.workspaceConfig.workspaceRoot\n );\n}\n\n/**\n * Extracts command parameter information from a type parameter reflection.\n *\n * @param param - The type parameter reflection to extract information from.\n * @returns The extracted command parameter information.\n */\nexport function extractCommandParameters(param: TypeParameter): CommandParam {\n return {\n name: param.name,\n description: param.description,\n optional: !!param.optional,\n variadic: param.type.kind === ReflectionKind.array,\n default: param.default\n } as CommandParam;\n}\n\n/**\n * Reflects the command tree for a given command input.\n *\n * @param context - The context in which the command is being reflected.\n * @param command - The command input to reflect.\n * @param parent - The parent command tree, if any.\n * @returns The reflected command tree.\n */\nexport async function reflectCommandTree<TContext extends Context = Context>(\n context: TContext,\n command: CommandInput,\n parent?: CommandTree\n): Promise<CommandTree> {\n const title =\n command.title ||\n `${parent?.title ? `${parent.title} - ` : \"\"}${titleCase(command.name)}${\n command.isVirtual ? \" Commands\" : \"\"\n }`;\n\n const tree = {\n ...command,\n title,\n description:\n command.description ||\n (command.isVirtual\n ? `A collection of available ${command.title || titleCase(command.name)} commands that are included in the ${getAppTitle(\n context\n )} command-line application.`\n : `The ${title} executable command-line interface.`),\n path: {\n ...command.path,\n variables: {}\n },\n options: getDefaultOptions(context, command),\n params: [],\n parent: parent ?? null,\n children: {}\n } as CommandTree;\n\n if (!command.isVirtual) {\n if (\n !command.entry.input?.file ||\n !context.fs.existsSync(command.entry.input.file)\n ) {\n throw new Error(\n `${\n !command.entry.input?.file ? \"Missing\" : \"Non-existent\"\n } command entry file for \"${command.name}\"`\n );\n }\n\n context.debug(\n `Adding reflection for user-defined command: ${command.id} (file: ${\n command.entry.input.file\n })`\n );\n\n const type = await reflectType<TContext>(context, command.entry.input);\n if (type.kind !== ReflectionKind.function) {\n throw new Error(\n `The command entry file \"${command.entry.input.file}\" does not export a valid function.`\n );\n }\n\n if (type.parameters.length > 0 && type.parameters[0]) {\n const firstParam = type.parameters[0];\n if (\n firstParam.type.kind === ReflectionKind.objectLiteral ||\n firstParam.type.kind === ReflectionKind.class\n ) {\n const optionsReflection = ReflectionClass.from(firstParam.type);\n for (const propertyReflection of optionsReflection.getProperties()) {\n const propertyType = propertyReflection.getType();\n\n tree.options[propertyReflection.getNameAsString()] = {\n name: propertyReflection.getNameAsString(),\n alias: propertyReflection.getTags().alias ?? [],\n title:\n propertyReflection.getTags().title?.trim() ||\n titleCase(propertyReflection.getNameAsString()),\n description: resolveCommandDescription(propertyReflection),\n env: constantCase(propertyReflection.getNameAsString()),\n kind: propertyType.kind as\n | ReflectionKind.string\n | ReflectionKind.number\n | ReflectionKind.boolean,\n optional: propertyReflection.isOptional(),\n default: propertyReflection.getDefaultValue(),\n variadic: false\n };\n if (propertyType.kind === ReflectionKind.array) {\n if (\n propertyType.type.kind === ReflectionKind.string ||\n propertyType.type.kind === ReflectionKind.number\n ) {\n (\n tree.options[propertyReflection.getNameAsString()] as\n | StringCommandOption\n | NumberCommandOption\n ).variadic = true;\n (\n tree.options[propertyReflection.getNameAsString()] as\n | StringCommandOption\n | NumberCommandOption\n ).kind = propertyType.type.kind;\n } else {\n throw new Error(\n `Unsupported array type for option \"${propertyReflection.getNameAsString()}\" in command \"${\n command.name\n }\". Only string[] and number[] are supported.`\n );\n }\n } else if (\n propertyType.kind !== ReflectionKind.boolean &&\n propertyType.kind !== ReflectionKind.string &&\n propertyType.kind !== ReflectionKind.number\n ) {\n throw new Error(\n `Unsupported type for option \"${propertyReflection.getNameAsString()}\" in command \"${\n command.name\n }\". Only string, number, boolean, string[] and number[] are supported, received ${stringifyType(\n propertyType\n )\n .trim()\n .replaceAll(\" | \", \", or \")}.`\n );\n }\n }\n }\n\n tree.path.variables = tree.path.segments\n .filter(segment => isVariableCommandPath(segment))\n .reduce(\n (obj, segment, index) => {\n if (\n type.parameters.length < index + 2 ||\n !type.parameters[index + 1]\n ) {\n return obj;\n }\n\n const paramName = getVariableCommandPathName(segment);\n obj[paramName] = extractCommandParameters(\n type.parameters[index + 1]!\n );\n obj[paramName].description =\n obj[paramName].description ||\n `The ${paramName} variable for the ${command.name} command.`;\n\n return obj;\n },\n {} as Record<string, CommandParam>\n );\n\n if (type.parameters.length > 1) {\n type.parameters\n .slice(\n tree.path.segments.filter(segment => isVariableCommandPath(segment))\n .length + 1\n )\n .forEach(param => {\n tree.params.push(extractCommandParameters(param));\n });\n }\n }\n }\n\n if (context.env) {\n if (isSetObject(tree.options)) {\n Object.values(tree.options)\n .filter(option => option.env !== false)\n .forEach(option => {\n context.env.types.env.addProperty({\n name: option.env as string,\n optional: option.optional ? true : undefined,\n description: option.description,\n visibility: ReflectionVisibility.public,\n type:\n option.kind === ReflectionKind.string ||\n option.kind === ReflectionKind.number\n ? option.variadic\n ? { kind: ReflectionKind.array, type: { kind: option.kind } }\n : { kind: option.kind }\n : { kind: ReflectionKind.boolean },\n default: option.default,\n tags: {\n title: option.title,\n alias: option.alias\n .filter(alias => alias.length > 0)\n .map(alias => constantCase(alias)),\n domain: \"cli\"\n }\n });\n });\n }\n\n if (tree.params) {\n tree.params.forEach(param => {\n context.env.types.env.addProperty({\n name: constantCase(param.name),\n optional: param.optional ? true : undefined,\n description: param.description,\n visibility: ReflectionVisibility.public,\n type: param.variadic\n ? {\n kind: ReflectionKind.array,\n type: { kind: ReflectionKind.string }\n }\n : { kind: ReflectionKind.string },\n default: param.default,\n tags: {\n domain: \"cli\"\n }\n });\n });\n }\n }\n\n for (const input of context.inputs.filter(\n input =>\n input.path.segments.filter(segment => !isVariableCommandPath(segment))\n .length ===\n command.path.segments.filter(segment => !isVariableCommandPath(segment))\n .length +\n 1 &&\n input.path.segments\n .slice(0, command.path.segments.length)\n .every((value, index) => value === command.path.segments[index])\n )) {\n tree.children[input.name] = await reflectCommandTree(context, input, tree);\n }\n\n return tree;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"resolve-command.cjs","names":["reflectType","ReflectionClass","ReflectionKind","ReflectionVisibility","stringifyType","appendPath","commonPath","findFilePath","findFolderName","stripStars","replacePath","resolveParentPath","constantCase","titleCase","isSetObject","isSetString","getAppTitle","getVariableCommandPathName","isVariableCommandPath","getDefaultOptions","resolveCommandDescription","propertyReflection","getDescription","trim","isOptional","getDefaultValue","getType","kind","boolean","array","getTags","title","getNameAsString","number","resolveCommandId","context","file","commandsPath","split","filter","p","Boolean","join","replaceAll","resolveCommandName","path","name","requireExtension","resolveCommandPath","resolveCommandParams","map","findCommandsRoot","config","entry","projectRoot","workspaceConfig","workspaceRoot","Array","isArray","length","sourceRoot","extractCommandParameters","param","description","optional","variadic","type","default","reflectCommandTree","command","parent","isVirtual","replace","tree","variables","options","params","children","input","fs","existsSync","Error","debug","id","function","parameters","firstParam","objectLiteral","class","optionsReflection","from","getProperties","propertyType","alias","env","string","segments","segment","reduce","obj","index","paramName","slice","forEach","push","Object","values","option","types","addProperty","undefined","visibility","public","tags","domain","inputs","every","value"],"sources":["../../src/helpers/resolve-command.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 { reflectType } from \"@powerlines/deepkit/reflect-type\";\nimport type {\n ReflectionProperty,\n TypeParameter\n} from \"@powerlines/deepkit/vendor/type\";\nimport {\n ReflectionClass,\n ReflectionKind,\n ReflectionVisibility,\n stringifyType\n} from \"@powerlines/deepkit/vendor/type\";\nimport { appendPath } from \"@stryke/path/append\";\nimport { commonPath } from \"@stryke/path/common\";\nimport { findFilePath, findFolderName } from \"@stryke/path/file-path-fns\";\nimport { stripStars } from \"@stryke/path/normalize\";\nimport { replacePath } from \"@stryke/path/replace\";\nimport { resolveParentPath } from \"@stryke/path/resolve-parent-path\";\nimport { constantCase } from \"@stryke/string-format/constant-case\";\nimport { titleCase } from \"@stryke/string-format/title-case\";\nimport { isSetObject } from \"@stryke/type-checks/is-set-object\";\nimport { isSetString } from \"@stryke/type-checks/is-set-string\";\nimport {\n getAppTitle,\n getVariableCommandPathName,\n isVariableCommandPath\n} from \"../plugin-utils/context-helpers\";\nimport type {\n CommandInput,\n CommandParam,\n CommandTree,\n NumberCommandOption,\n StringCommandOption\n} from \"../types/command\";\nimport type { Context } from \"../types/context\";\nimport { getDefaultOptions } from \"./utilities\";\n\n/**\n * Resolves the description for a command option based on its reflection.\n *\n * @param propertyReflection - The reflection property of the command option.\n * @returns The resolved description for the command option.\n */\nexport function resolveCommandDescription(\n propertyReflection: ReflectionProperty\n): string {\n return (\n propertyReflection.getDescription()?.trim() ||\n `A${\n propertyReflection.isOptional() && !propertyReflection.getDefaultValue()\n ? \"n optional\"\n : \"\"\n } ${\n propertyReflection.getType().kind === ReflectionKind.boolean\n ? \"flag provided via the command-line\"\n : \"command-line option\"\n } that allows the user to ${\n propertyReflection.getType().kind === ReflectionKind.boolean\n ? \"set the\"\n : propertyReflection.getType().kind === ReflectionKind.array\n ? \"specify custom\"\n : \"specify a custom\"\n } ${\n propertyReflection.getTags().title?.trim() ||\n titleCase(propertyReflection.getNameAsString())\n } ${\n propertyReflection.getType().kind === ReflectionKind.boolean\n ? \"indicator\"\n : `${propertyReflection.getType().kind === ReflectionKind.number ? \"numeric\" : \"string\"} value${\n propertyReflection.getType().kind === ReflectionKind.array\n ? \"s\"\n : \"\"\n }`\n } that will be used in the application.`\n );\n}\n\nexport function resolveCommandId(context: Context, file: string): string {\n return replacePath(findFilePath(file), context.commandsPath)\n .split(\"/\")\n .filter(p => Boolean(p) && !isVariableCommandPath(p))\n .join(\"/\")\n .replaceAll(/^\\/+/g, \"\")\n .replaceAll(/\\/+$/g, \"\")\n .replaceAll(\"/\", \"-\");\n}\n\n/**\n * Finds the command name from the given file path.\n *\n * @param file - The file path to extract the command name from.\n * @returns The command name.\n */\nexport function resolveCommandName(file: string) {\n let path = findFilePath(file);\n let name = findFolderName(file, {\n requireExtension: true\n });\n\n while (isVariableCommandPath(name)) {\n path = resolveParentPath(path);\n name = findFolderName(path, {\n requireExtension: true\n });\n }\n\n return name;\n}\n\nexport function resolveCommandPath(context: Context, file: string): string {\n return replacePath(findFilePath(file), context.commandsPath)\n .replaceAll(/^\\/+/g, \"\")\n .replaceAll(/\\/+$/g, \"\");\n}\n\nexport function resolveCommandParams(context: Context, file: string): string[] {\n return replacePath(findFilePath(file), context.commandsPath)\n .split(\"/\")\n .filter(p => Boolean(p) && isVariableCommandPath(p))\n .map(p => p.replaceAll(/^\\[+/g, \"\").replaceAll(/\\]+$/g, \"\"));\n}\n\nexport function findCommandsRoot(context: Context): string {\n if (isSetString(context.config.entry)) {\n return appendPath(\n appendPath(stripStars(context.config.entry), context.config.projectRoot),\n context.workspaceConfig.workspaceRoot\n );\n } else if (\n isSetObject(context.config.entry) &&\n \"file\" in context.config.entry\n ) {\n return appendPath(\n appendPath(\n stripStars(context.config.entry.file),\n context.config.projectRoot\n ),\n context.workspaceConfig.workspaceRoot\n );\n } else if (\n Array.isArray(context.config.entry) &&\n context.config.entry.length > 0\n ) {\n return commonPath(\n context.config.entry.map(entry =>\n appendPath(\n appendPath(\n stripStars(isSetString(entry) ? entry : entry.file),\n context.config.projectRoot\n ),\n context.workspaceConfig.workspaceRoot\n )\n )\n );\n }\n\n return appendPath(\n context.config.sourceRoot || context.config.projectRoot,\n context.workspaceConfig.workspaceRoot\n );\n}\n\n/**\n * Extracts command parameter information from a type parameter reflection.\n *\n * @param param - The type parameter reflection to extract information from.\n * @returns The extracted command parameter information.\n */\nexport function extractCommandParameters(param: TypeParameter): CommandParam {\n return {\n name: param.name,\n description: param.description,\n optional: !!param.optional,\n variadic: param.type.kind === ReflectionKind.array,\n default: param.default\n } as CommandParam;\n}\n\n/**\n * Reflects the command tree for a given command input.\n *\n * @param context - The context in which the command is being reflected.\n * @param command - The command input to reflect.\n * @param parent - The parent command tree, if any.\n * @returns The reflected command tree.\n */\nexport async function reflectCommandTree<TContext extends Context = Context>(\n context: TContext,\n command: CommandInput,\n parent?: CommandTree\n): Promise<CommandTree> {\n const title =\n command.title ||\n `${parent?.title ? `${parent.isVirtual ? parent.title.replace(/ Commands$/, \"\") : parent.title} - ` : \"\"}${titleCase(command.name)}${\n command.isVirtual ? \" Commands\" : \"\"\n }`;\n\n const tree = {\n ...command,\n title,\n description:\n command.description ||\n (command.isVirtual\n ? `A collection of available ${command.title || titleCase(command.name)} commands that are included in the ${getAppTitle(\n context\n )} command-line application.`\n : `The ${title} executable command-line interface.`),\n path: {\n ...command.path,\n variables: {}\n },\n options: getDefaultOptions(context, command),\n params: [],\n parent: parent ?? null,\n children: {}\n } as CommandTree;\n\n if (!command.isVirtual) {\n if (\n !command.entry.input?.file ||\n !context.fs.existsSync(command.entry.input.file)\n ) {\n throw new Error(\n `${\n !command.entry.input?.file ? \"Missing\" : \"Non-existent\"\n } command entry file for \"${command.name}\"`\n );\n }\n\n context.debug(\n `Adding reflection for user-defined command: ${command.id} (file: ${\n command.entry.input.file\n })`\n );\n\n const type = await reflectType<TContext>(context, command.entry.input);\n if (type.kind !== ReflectionKind.function) {\n throw new Error(\n `The command entry file \"${command.entry.input.file}\" does not export a valid function.`\n );\n }\n\n if (type.parameters.length > 0 && type.parameters[0]) {\n const firstParam = type.parameters[0];\n if (\n firstParam.type.kind === ReflectionKind.objectLiteral ||\n firstParam.type.kind === ReflectionKind.class\n ) {\n const optionsReflection = ReflectionClass.from(firstParam.type);\n for (const propertyReflection of optionsReflection.getProperties()) {\n const propertyType = propertyReflection.getType();\n\n tree.options[propertyReflection.getNameAsString()] = {\n name: propertyReflection.getNameAsString(),\n alias: propertyReflection.getTags().alias ?? [],\n title:\n propertyReflection.getTags().title?.trim() ||\n titleCase(propertyReflection.getNameAsString()),\n description: resolveCommandDescription(propertyReflection),\n env: constantCase(propertyReflection.getNameAsString()),\n kind: propertyType.kind as\n | ReflectionKind.string\n | ReflectionKind.number\n | ReflectionKind.boolean,\n optional: propertyReflection.isOptional(),\n default: propertyReflection.getDefaultValue(),\n variadic: false\n };\n if (propertyType.kind === ReflectionKind.array) {\n if (\n propertyType.type.kind === ReflectionKind.string ||\n propertyType.type.kind === ReflectionKind.number\n ) {\n (\n tree.options[propertyReflection.getNameAsString()] as\n | StringCommandOption\n | NumberCommandOption\n ).variadic = true;\n (\n tree.options[propertyReflection.getNameAsString()] as\n | StringCommandOption\n | NumberCommandOption\n ).kind = propertyType.type.kind;\n } else {\n throw new Error(\n `Unsupported array type for option \"${propertyReflection.getNameAsString()}\" in command \"${\n command.name\n }\". Only string[] and number[] are supported.`\n );\n }\n } else if (\n propertyType.kind !== ReflectionKind.boolean &&\n propertyType.kind !== ReflectionKind.string &&\n propertyType.kind !== ReflectionKind.number\n ) {\n throw new Error(\n `Unsupported type for option \"${propertyReflection.getNameAsString()}\" in command \"${\n command.name\n }\". Only string, number, boolean, string[] and number[] are supported, received ${stringifyType(\n propertyType\n )\n .trim()\n .replaceAll(\" | \", \", or \")}.`\n );\n }\n }\n }\n\n tree.path.variables = tree.path.segments\n .filter(segment => isVariableCommandPath(segment))\n .reduce(\n (obj, segment, index) => {\n if (\n type.parameters.length < index + 2 ||\n !type.parameters[index + 1]\n ) {\n return obj;\n }\n\n const paramName = getVariableCommandPathName(segment);\n obj[paramName] = extractCommandParameters(\n type.parameters[index + 1]!\n );\n obj[paramName].description =\n obj[paramName].description ||\n `The ${paramName} variable for the ${command.name} command.`;\n\n return obj;\n },\n {} as Record<string, CommandParam>\n );\n\n if (type.parameters.length > 1) {\n type.parameters\n .slice(\n tree.path.segments.filter(segment => isVariableCommandPath(segment))\n .length + 1\n )\n .forEach(param => {\n tree.params.push(extractCommandParameters(param));\n });\n }\n }\n }\n\n if (context.env) {\n if (isSetObject(tree.options)) {\n Object.values(tree.options)\n .filter(option => option.env !== false)\n .forEach(option => {\n context.env.types.env.addProperty({\n name: option.env as string,\n optional: option.optional ? true : undefined,\n description: option.description,\n visibility: ReflectionVisibility.public,\n type:\n option.kind === ReflectionKind.string ||\n option.kind === ReflectionKind.number\n ? option.variadic\n ? { kind: ReflectionKind.array, type: { kind: option.kind } }\n : { kind: option.kind }\n : { kind: ReflectionKind.boolean },\n default: option.default,\n tags: {\n title: option.title,\n alias: option.alias\n .filter(alias => alias.length > 0)\n .map(alias => constantCase(alias)),\n domain: \"cli\"\n }\n });\n });\n }\n\n if (tree.params) {\n tree.params.forEach(param => {\n context.env.types.env.addProperty({\n name: constantCase(param.name),\n optional: param.optional ? true : undefined,\n description: param.description,\n visibility: ReflectionVisibility.public,\n type: param.variadic\n ? {\n kind: ReflectionKind.array,\n type: { kind: ReflectionKind.string }\n }\n : { kind: ReflectionKind.string },\n default: param.default,\n tags: {\n domain: \"cli\"\n }\n });\n });\n }\n }\n\n for (const input of context.inputs.filter(\n input =>\n input.path.segments.filter(segment => !isVariableCommandPath(segment))\n .length ===\n command.path.segments.filter(segment => !isVariableCommandPath(segment))\n .length +\n 1 &&\n input.path.segments\n .slice(0, command.path.segments.length)\n .every((value, index) => value === command.path.segments[index])\n )) {\n tree.children[input.name] = await reflectCommandTree(context, input, tree);\n }\n\n return tree;\n}\n"],"mappings":"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"}
@@ -74,7 +74,7 @@ function extractCommandParameters(param) {
74
74
  * @returns The reflected command tree.
75
75
  */
76
76
  async function reflectCommandTree(context, command, parent) {
77
- const title = command.title || `${parent?.title ? `${parent.title} - ` : ""}${titleCase(command.name)}${command.isVirtual ? " Commands" : ""}`;
77
+ const title = command.title || `${parent?.title ? `${parent.isVirtual ? parent.title.replace(/ Commands$/, "") : parent.title} - ` : ""}${titleCase(command.name)}${command.isVirtual ? " Commands" : ""}`;
78
78
  const tree = {
79
79
  ...command,
80
80
  title,
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-command.mjs","names":["reflectType","ReflectionClass","ReflectionKind","ReflectionVisibility","stringifyType","appendPath","commonPath","findFilePath","findFolderName","stripStars","replacePath","resolveParentPath","constantCase","titleCase","isSetObject","isSetString","getAppTitle","getVariableCommandPathName","isVariableCommandPath","getDefaultOptions","resolveCommandDescription","propertyReflection","getDescription","trim","isOptional","getDefaultValue","getType","kind","boolean","array","getTags","title","getNameAsString","number","resolveCommandId","context","file","commandsPath","split","filter","p","Boolean","join","replaceAll","resolveCommandName","path","name","requireExtension","resolveCommandPath","resolveCommandParams","map","findCommandsRoot","config","entry","projectRoot","workspaceConfig","workspaceRoot","Array","isArray","length","sourceRoot","extractCommandParameters","param","description","optional","variadic","type","default","reflectCommandTree","command","parent","isVirtual","tree","variables","options","params","children","input","fs","existsSync","Error","debug","id","function","parameters","firstParam","objectLiteral","class","optionsReflection","from","getProperties","propertyType","alias","env","string","segments","segment","reduce","obj","index","paramName","slice","forEach","push","Object","values","option","types","addProperty","undefined","visibility","public","tags","domain","inputs","every","value"],"sources":["../../src/helpers/resolve-command.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 { reflectType } from \"@powerlines/deepkit/reflect-type\";\nimport type {\n ReflectionProperty,\n TypeParameter\n} from \"@powerlines/deepkit/vendor/type\";\nimport {\n ReflectionClass,\n ReflectionKind,\n ReflectionVisibility,\n stringifyType\n} from \"@powerlines/deepkit/vendor/type\";\nimport { appendPath } from \"@stryke/path/append\";\nimport { commonPath } from \"@stryke/path/common\";\nimport { findFilePath, findFolderName } from \"@stryke/path/file-path-fns\";\nimport { stripStars } from \"@stryke/path/normalize\";\nimport { replacePath } from \"@stryke/path/replace\";\nimport { resolveParentPath } from \"@stryke/path/resolve-parent-path\";\nimport { constantCase } from \"@stryke/string-format/constant-case\";\nimport { titleCase } from \"@stryke/string-format/title-case\";\nimport { isSetObject } from \"@stryke/type-checks/is-set-object\";\nimport { isSetString } from \"@stryke/type-checks/is-set-string\";\nimport {\n getAppTitle,\n getVariableCommandPathName,\n isVariableCommandPath\n} from \"../plugin-utils/context-helpers\";\nimport type {\n CommandInput,\n CommandParam,\n CommandTree,\n NumberCommandOption,\n StringCommandOption\n} from \"../types/command\";\nimport type { Context } from \"../types/context\";\nimport { getDefaultOptions } from \"./utilities\";\n\n/**\n * Resolves the description for a command option based on its reflection.\n *\n * @param propertyReflection - The reflection property of the command option.\n * @returns The resolved description for the command option.\n */\nexport function resolveCommandDescription(\n propertyReflection: ReflectionProperty\n): string {\n return (\n propertyReflection.getDescription()?.trim() ||\n `A${\n propertyReflection.isOptional() && !propertyReflection.getDefaultValue()\n ? \"n optional\"\n : \"\"\n } ${\n propertyReflection.getType().kind === ReflectionKind.boolean\n ? \"flag provided via the command-line\"\n : \"command-line option\"\n } that allows the user to ${\n propertyReflection.getType().kind === ReflectionKind.boolean\n ? \"set the\"\n : propertyReflection.getType().kind === ReflectionKind.array\n ? \"specify custom\"\n : \"specify a custom\"\n } ${\n propertyReflection.getTags().title?.trim() ||\n titleCase(propertyReflection.getNameAsString())\n } ${\n propertyReflection.getType().kind === ReflectionKind.boolean\n ? \"indicator\"\n : `${propertyReflection.getType().kind === ReflectionKind.number ? \"numeric\" : \"string\"} value${\n propertyReflection.getType().kind === ReflectionKind.array\n ? \"s\"\n : \"\"\n }`\n } that will be used in the application.`\n );\n}\n\nexport function resolveCommandId(context: Context, file: string): string {\n return replacePath(findFilePath(file), context.commandsPath)\n .split(\"/\")\n .filter(p => Boolean(p) && !isVariableCommandPath(p))\n .join(\"/\")\n .replaceAll(/^\\/+/g, \"\")\n .replaceAll(/\\/+$/g, \"\")\n .replaceAll(\"/\", \"-\");\n}\n\n/**\n * Finds the command name from the given file path.\n *\n * @param file - The file path to extract the command name from.\n * @returns The command name.\n */\nexport function resolveCommandName(file: string) {\n let path = findFilePath(file);\n let name = findFolderName(file, {\n requireExtension: true\n });\n\n while (isVariableCommandPath(name)) {\n path = resolveParentPath(path);\n name = findFolderName(path, {\n requireExtension: true\n });\n }\n\n return name;\n}\n\nexport function resolveCommandPath(context: Context, file: string): string {\n return replacePath(findFilePath(file), context.commandsPath)\n .replaceAll(/^\\/+/g, \"\")\n .replaceAll(/\\/+$/g, \"\");\n}\n\nexport function resolveCommandParams(context: Context, file: string): string[] {\n return replacePath(findFilePath(file), context.commandsPath)\n .split(\"/\")\n .filter(p => Boolean(p) && isVariableCommandPath(p))\n .map(p => p.replaceAll(/^\\[+/g, \"\").replaceAll(/\\]+$/g, \"\"));\n}\n\nexport function findCommandsRoot(context: Context): string {\n if (isSetString(context.config.entry)) {\n return appendPath(\n appendPath(stripStars(context.config.entry), context.config.projectRoot),\n context.workspaceConfig.workspaceRoot\n );\n } else if (\n isSetObject(context.config.entry) &&\n \"file\" in context.config.entry\n ) {\n return appendPath(\n appendPath(\n stripStars(context.config.entry.file),\n context.config.projectRoot\n ),\n context.workspaceConfig.workspaceRoot\n );\n } else if (\n Array.isArray(context.config.entry) &&\n context.config.entry.length > 0\n ) {\n return commonPath(\n context.config.entry.map(entry =>\n appendPath(\n appendPath(\n stripStars(isSetString(entry) ? entry : entry.file),\n context.config.projectRoot\n ),\n context.workspaceConfig.workspaceRoot\n )\n )\n );\n }\n\n return appendPath(\n context.config.sourceRoot || context.config.projectRoot,\n context.workspaceConfig.workspaceRoot\n );\n}\n\n/**\n * Extracts command parameter information from a type parameter reflection.\n *\n * @param param - The type parameter reflection to extract information from.\n * @returns The extracted command parameter information.\n */\nexport function extractCommandParameters(param: TypeParameter): CommandParam {\n return {\n name: param.name,\n description: param.description,\n optional: !!param.optional,\n variadic: param.type.kind === ReflectionKind.array,\n default: param.default\n } as CommandParam;\n}\n\n/**\n * Reflects the command tree for a given command input.\n *\n * @param context - The context in which the command is being reflected.\n * @param command - The command input to reflect.\n * @param parent - The parent command tree, if any.\n * @returns The reflected command tree.\n */\nexport async function reflectCommandTree<TContext extends Context = Context>(\n context: TContext,\n command: CommandInput,\n parent?: CommandTree\n): Promise<CommandTree> {\n const title =\n command.title ||\n `${parent?.title ? `${parent.title} - ` : \"\"}${titleCase(command.name)}${\n command.isVirtual ? \" Commands\" : \"\"\n }`;\n\n const tree = {\n ...command,\n title,\n description:\n command.description ||\n (command.isVirtual\n ? `A collection of available ${command.title || titleCase(command.name)} commands that are included in the ${getAppTitle(\n context\n )} command-line application.`\n : `The ${title} executable command-line interface.`),\n path: {\n ...command.path,\n variables: {}\n },\n options: getDefaultOptions(context, command),\n params: [],\n parent: parent ?? null,\n children: {}\n } as CommandTree;\n\n if (!command.isVirtual) {\n if (\n !command.entry.input?.file ||\n !context.fs.existsSync(command.entry.input.file)\n ) {\n throw new Error(\n `${\n !command.entry.input?.file ? \"Missing\" : \"Non-existent\"\n } command entry file for \"${command.name}\"`\n );\n }\n\n context.debug(\n `Adding reflection for user-defined command: ${command.id} (file: ${\n command.entry.input.file\n })`\n );\n\n const type = await reflectType<TContext>(context, command.entry.input);\n if (type.kind !== ReflectionKind.function) {\n throw new Error(\n `The command entry file \"${command.entry.input.file}\" does not export a valid function.`\n );\n }\n\n if (type.parameters.length > 0 && type.parameters[0]) {\n const firstParam = type.parameters[0];\n if (\n firstParam.type.kind === ReflectionKind.objectLiteral ||\n firstParam.type.kind === ReflectionKind.class\n ) {\n const optionsReflection = ReflectionClass.from(firstParam.type);\n for (const propertyReflection of optionsReflection.getProperties()) {\n const propertyType = propertyReflection.getType();\n\n tree.options[propertyReflection.getNameAsString()] = {\n name: propertyReflection.getNameAsString(),\n alias: propertyReflection.getTags().alias ?? [],\n title:\n propertyReflection.getTags().title?.trim() ||\n titleCase(propertyReflection.getNameAsString()),\n description: resolveCommandDescription(propertyReflection),\n env: constantCase(propertyReflection.getNameAsString()),\n kind: propertyType.kind as\n | ReflectionKind.string\n | ReflectionKind.number\n | ReflectionKind.boolean,\n optional: propertyReflection.isOptional(),\n default: propertyReflection.getDefaultValue(),\n variadic: false\n };\n if (propertyType.kind === ReflectionKind.array) {\n if (\n propertyType.type.kind === ReflectionKind.string ||\n propertyType.type.kind === ReflectionKind.number\n ) {\n (\n tree.options[propertyReflection.getNameAsString()] as\n | StringCommandOption\n | NumberCommandOption\n ).variadic = true;\n (\n tree.options[propertyReflection.getNameAsString()] as\n | StringCommandOption\n | NumberCommandOption\n ).kind = propertyType.type.kind;\n } else {\n throw new Error(\n `Unsupported array type for option \"${propertyReflection.getNameAsString()}\" in command \"${\n command.name\n }\". Only string[] and number[] are supported.`\n );\n }\n } else if (\n propertyType.kind !== ReflectionKind.boolean &&\n propertyType.kind !== ReflectionKind.string &&\n propertyType.kind !== ReflectionKind.number\n ) {\n throw new Error(\n `Unsupported type for option \"${propertyReflection.getNameAsString()}\" in command \"${\n command.name\n }\". Only string, number, boolean, string[] and number[] are supported, received ${stringifyType(\n propertyType\n )\n .trim()\n .replaceAll(\" | \", \", or \")}.`\n );\n }\n }\n }\n\n tree.path.variables = tree.path.segments\n .filter(segment => isVariableCommandPath(segment))\n .reduce(\n (obj, segment, index) => {\n if (\n type.parameters.length < index + 2 ||\n !type.parameters[index + 1]\n ) {\n return obj;\n }\n\n const paramName = getVariableCommandPathName(segment);\n obj[paramName] = extractCommandParameters(\n type.parameters[index + 1]!\n );\n obj[paramName].description =\n obj[paramName].description ||\n `The ${paramName} variable for the ${command.name} command.`;\n\n return obj;\n },\n {} as Record<string, CommandParam>\n );\n\n if (type.parameters.length > 1) {\n type.parameters\n .slice(\n tree.path.segments.filter(segment => isVariableCommandPath(segment))\n .length + 1\n )\n .forEach(param => {\n tree.params.push(extractCommandParameters(param));\n });\n }\n }\n }\n\n if (context.env) {\n if (isSetObject(tree.options)) {\n Object.values(tree.options)\n .filter(option => option.env !== false)\n .forEach(option => {\n context.env.types.env.addProperty({\n name: option.env as string,\n optional: option.optional ? true : undefined,\n description: option.description,\n visibility: ReflectionVisibility.public,\n type:\n option.kind === ReflectionKind.string ||\n option.kind === ReflectionKind.number\n ? option.variadic\n ? { kind: ReflectionKind.array, type: { kind: option.kind } }\n : { kind: option.kind }\n : { kind: ReflectionKind.boolean },\n default: option.default,\n tags: {\n title: option.title,\n alias: option.alias\n .filter(alias => alias.length > 0)\n .map(alias => constantCase(alias)),\n domain: \"cli\"\n }\n });\n });\n }\n\n if (tree.params) {\n tree.params.forEach(param => {\n context.env.types.env.addProperty({\n name: constantCase(param.name),\n optional: param.optional ? true : undefined,\n description: param.description,\n visibility: ReflectionVisibility.public,\n type: param.variadic\n ? {\n kind: ReflectionKind.array,\n type: { kind: ReflectionKind.string }\n }\n : { kind: ReflectionKind.string },\n default: param.default,\n tags: {\n domain: \"cli\"\n }\n });\n });\n }\n }\n\n for (const input of context.inputs.filter(\n input =>\n input.path.segments.filter(segment => !isVariableCommandPath(segment))\n .length ===\n command.path.segments.filter(segment => !isVariableCommandPath(segment))\n .length +\n 1 &&\n input.path.segments\n .slice(0, command.path.segments.length)\n .every((value, index) => value === command.path.segments[index])\n )) {\n tree.children[input.name] = await reflectCommandTree(context, input, tree);\n }\n\n return tree;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"resolve-command.mjs","names":["reflectType","ReflectionClass","ReflectionKind","ReflectionVisibility","stringifyType","appendPath","commonPath","findFilePath","findFolderName","stripStars","replacePath","resolveParentPath","constantCase","titleCase","isSetObject","isSetString","getAppTitle","getVariableCommandPathName","isVariableCommandPath","getDefaultOptions","resolveCommandDescription","propertyReflection","getDescription","trim","isOptional","getDefaultValue","getType","kind","boolean","array","getTags","title","getNameAsString","number","resolveCommandId","context","file","commandsPath","split","filter","p","Boolean","join","replaceAll","resolveCommandName","path","name","requireExtension","resolveCommandPath","resolveCommandParams","map","findCommandsRoot","config","entry","projectRoot","workspaceConfig","workspaceRoot","Array","isArray","length","sourceRoot","extractCommandParameters","param","description","optional","variadic","type","default","reflectCommandTree","command","parent","isVirtual","replace","tree","variables","options","params","children","input","fs","existsSync","Error","debug","id","function","parameters","firstParam","objectLiteral","class","optionsReflection","from","getProperties","propertyType","alias","env","string","segments","segment","reduce","obj","index","paramName","slice","forEach","push","Object","values","option","types","addProperty","undefined","visibility","public","tags","domain","inputs","every","value"],"sources":["../../src/helpers/resolve-command.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 { reflectType } from \"@powerlines/deepkit/reflect-type\";\nimport type {\n ReflectionProperty,\n TypeParameter\n} from \"@powerlines/deepkit/vendor/type\";\nimport {\n ReflectionClass,\n ReflectionKind,\n ReflectionVisibility,\n stringifyType\n} from \"@powerlines/deepkit/vendor/type\";\nimport { appendPath } from \"@stryke/path/append\";\nimport { commonPath } from \"@stryke/path/common\";\nimport { findFilePath, findFolderName } from \"@stryke/path/file-path-fns\";\nimport { stripStars } from \"@stryke/path/normalize\";\nimport { replacePath } from \"@stryke/path/replace\";\nimport { resolveParentPath } from \"@stryke/path/resolve-parent-path\";\nimport { constantCase } from \"@stryke/string-format/constant-case\";\nimport { titleCase } from \"@stryke/string-format/title-case\";\nimport { isSetObject } from \"@stryke/type-checks/is-set-object\";\nimport { isSetString } from \"@stryke/type-checks/is-set-string\";\nimport {\n getAppTitle,\n getVariableCommandPathName,\n isVariableCommandPath\n} from \"../plugin-utils/context-helpers\";\nimport type {\n CommandInput,\n CommandParam,\n CommandTree,\n NumberCommandOption,\n StringCommandOption\n} from \"../types/command\";\nimport type { Context } from \"../types/context\";\nimport { getDefaultOptions } from \"./utilities\";\n\n/**\n * Resolves the description for a command option based on its reflection.\n *\n * @param propertyReflection - The reflection property of the command option.\n * @returns The resolved description for the command option.\n */\nexport function resolveCommandDescription(\n propertyReflection: ReflectionProperty\n): string {\n return (\n propertyReflection.getDescription()?.trim() ||\n `A${\n propertyReflection.isOptional() && !propertyReflection.getDefaultValue()\n ? \"n optional\"\n : \"\"\n } ${\n propertyReflection.getType().kind === ReflectionKind.boolean\n ? \"flag provided via the command-line\"\n : \"command-line option\"\n } that allows the user to ${\n propertyReflection.getType().kind === ReflectionKind.boolean\n ? \"set the\"\n : propertyReflection.getType().kind === ReflectionKind.array\n ? \"specify custom\"\n : \"specify a custom\"\n } ${\n propertyReflection.getTags().title?.trim() ||\n titleCase(propertyReflection.getNameAsString())\n } ${\n propertyReflection.getType().kind === ReflectionKind.boolean\n ? \"indicator\"\n : `${propertyReflection.getType().kind === ReflectionKind.number ? \"numeric\" : \"string\"} value${\n propertyReflection.getType().kind === ReflectionKind.array\n ? \"s\"\n : \"\"\n }`\n } that will be used in the application.`\n );\n}\n\nexport function resolveCommandId(context: Context, file: string): string {\n return replacePath(findFilePath(file), context.commandsPath)\n .split(\"/\")\n .filter(p => Boolean(p) && !isVariableCommandPath(p))\n .join(\"/\")\n .replaceAll(/^\\/+/g, \"\")\n .replaceAll(/\\/+$/g, \"\")\n .replaceAll(\"/\", \"-\");\n}\n\n/**\n * Finds the command name from the given file path.\n *\n * @param file - The file path to extract the command name from.\n * @returns The command name.\n */\nexport function resolveCommandName(file: string) {\n let path = findFilePath(file);\n let name = findFolderName(file, {\n requireExtension: true\n });\n\n while (isVariableCommandPath(name)) {\n path = resolveParentPath(path);\n name = findFolderName(path, {\n requireExtension: true\n });\n }\n\n return name;\n}\n\nexport function resolveCommandPath(context: Context, file: string): string {\n return replacePath(findFilePath(file), context.commandsPath)\n .replaceAll(/^\\/+/g, \"\")\n .replaceAll(/\\/+$/g, \"\");\n}\n\nexport function resolveCommandParams(context: Context, file: string): string[] {\n return replacePath(findFilePath(file), context.commandsPath)\n .split(\"/\")\n .filter(p => Boolean(p) && isVariableCommandPath(p))\n .map(p => p.replaceAll(/^\\[+/g, \"\").replaceAll(/\\]+$/g, \"\"));\n}\n\nexport function findCommandsRoot(context: Context): string {\n if (isSetString(context.config.entry)) {\n return appendPath(\n appendPath(stripStars(context.config.entry), context.config.projectRoot),\n context.workspaceConfig.workspaceRoot\n );\n } else if (\n isSetObject(context.config.entry) &&\n \"file\" in context.config.entry\n ) {\n return appendPath(\n appendPath(\n stripStars(context.config.entry.file),\n context.config.projectRoot\n ),\n context.workspaceConfig.workspaceRoot\n );\n } else if (\n Array.isArray(context.config.entry) &&\n context.config.entry.length > 0\n ) {\n return commonPath(\n context.config.entry.map(entry =>\n appendPath(\n appendPath(\n stripStars(isSetString(entry) ? entry : entry.file),\n context.config.projectRoot\n ),\n context.workspaceConfig.workspaceRoot\n )\n )\n );\n }\n\n return appendPath(\n context.config.sourceRoot || context.config.projectRoot,\n context.workspaceConfig.workspaceRoot\n );\n}\n\n/**\n * Extracts command parameter information from a type parameter reflection.\n *\n * @param param - The type parameter reflection to extract information from.\n * @returns The extracted command parameter information.\n */\nexport function extractCommandParameters(param: TypeParameter): CommandParam {\n return {\n name: param.name,\n description: param.description,\n optional: !!param.optional,\n variadic: param.type.kind === ReflectionKind.array,\n default: param.default\n } as CommandParam;\n}\n\n/**\n * Reflects the command tree for a given command input.\n *\n * @param context - The context in which the command is being reflected.\n * @param command - The command input to reflect.\n * @param parent - The parent command tree, if any.\n * @returns The reflected command tree.\n */\nexport async function reflectCommandTree<TContext extends Context = Context>(\n context: TContext,\n command: CommandInput,\n parent?: CommandTree\n): Promise<CommandTree> {\n const title =\n command.title ||\n `${parent?.title ? `${parent.isVirtual ? parent.title.replace(/ Commands$/, \"\") : parent.title} - ` : \"\"}${titleCase(command.name)}${\n command.isVirtual ? \" Commands\" : \"\"\n }`;\n\n const tree = {\n ...command,\n title,\n description:\n command.description ||\n (command.isVirtual\n ? `A collection of available ${command.title || titleCase(command.name)} commands that are included in the ${getAppTitle(\n context\n )} command-line application.`\n : `The ${title} executable command-line interface.`),\n path: {\n ...command.path,\n variables: {}\n },\n options: getDefaultOptions(context, command),\n params: [],\n parent: parent ?? null,\n children: {}\n } as CommandTree;\n\n if (!command.isVirtual) {\n if (\n !command.entry.input?.file ||\n !context.fs.existsSync(command.entry.input.file)\n ) {\n throw new Error(\n `${\n !command.entry.input?.file ? \"Missing\" : \"Non-existent\"\n } command entry file for \"${command.name}\"`\n );\n }\n\n context.debug(\n `Adding reflection for user-defined command: ${command.id} (file: ${\n command.entry.input.file\n })`\n );\n\n const type = await reflectType<TContext>(context, command.entry.input);\n if (type.kind !== ReflectionKind.function) {\n throw new Error(\n `The command entry file \"${command.entry.input.file}\" does not export a valid function.`\n );\n }\n\n if (type.parameters.length > 0 && type.parameters[0]) {\n const firstParam = type.parameters[0];\n if (\n firstParam.type.kind === ReflectionKind.objectLiteral ||\n firstParam.type.kind === ReflectionKind.class\n ) {\n const optionsReflection = ReflectionClass.from(firstParam.type);\n for (const propertyReflection of optionsReflection.getProperties()) {\n const propertyType = propertyReflection.getType();\n\n tree.options[propertyReflection.getNameAsString()] = {\n name: propertyReflection.getNameAsString(),\n alias: propertyReflection.getTags().alias ?? [],\n title:\n propertyReflection.getTags().title?.trim() ||\n titleCase(propertyReflection.getNameAsString()),\n description: resolveCommandDescription(propertyReflection),\n env: constantCase(propertyReflection.getNameAsString()),\n kind: propertyType.kind as\n | ReflectionKind.string\n | ReflectionKind.number\n | ReflectionKind.boolean,\n optional: propertyReflection.isOptional(),\n default: propertyReflection.getDefaultValue(),\n variadic: false\n };\n if (propertyType.kind === ReflectionKind.array) {\n if (\n propertyType.type.kind === ReflectionKind.string ||\n propertyType.type.kind === ReflectionKind.number\n ) {\n (\n tree.options[propertyReflection.getNameAsString()] as\n | StringCommandOption\n | NumberCommandOption\n ).variadic = true;\n (\n tree.options[propertyReflection.getNameAsString()] as\n | StringCommandOption\n | NumberCommandOption\n ).kind = propertyType.type.kind;\n } else {\n throw new Error(\n `Unsupported array type for option \"${propertyReflection.getNameAsString()}\" in command \"${\n command.name\n }\". Only string[] and number[] are supported.`\n );\n }\n } else if (\n propertyType.kind !== ReflectionKind.boolean &&\n propertyType.kind !== ReflectionKind.string &&\n propertyType.kind !== ReflectionKind.number\n ) {\n throw new Error(\n `Unsupported type for option \"${propertyReflection.getNameAsString()}\" in command \"${\n command.name\n }\". Only string, number, boolean, string[] and number[] are supported, received ${stringifyType(\n propertyType\n )\n .trim()\n .replaceAll(\" | \", \", or \")}.`\n );\n }\n }\n }\n\n tree.path.variables = tree.path.segments\n .filter(segment => isVariableCommandPath(segment))\n .reduce(\n (obj, segment, index) => {\n if (\n type.parameters.length < index + 2 ||\n !type.parameters[index + 1]\n ) {\n return obj;\n }\n\n const paramName = getVariableCommandPathName(segment);\n obj[paramName] = extractCommandParameters(\n type.parameters[index + 1]!\n );\n obj[paramName].description =\n obj[paramName].description ||\n `The ${paramName} variable for the ${command.name} command.`;\n\n return obj;\n },\n {} as Record<string, CommandParam>\n );\n\n if (type.parameters.length > 1) {\n type.parameters\n .slice(\n tree.path.segments.filter(segment => isVariableCommandPath(segment))\n .length + 1\n )\n .forEach(param => {\n tree.params.push(extractCommandParameters(param));\n });\n }\n }\n }\n\n if (context.env) {\n if (isSetObject(tree.options)) {\n Object.values(tree.options)\n .filter(option => option.env !== false)\n .forEach(option => {\n context.env.types.env.addProperty({\n name: option.env as string,\n optional: option.optional ? true : undefined,\n description: option.description,\n visibility: ReflectionVisibility.public,\n type:\n option.kind === ReflectionKind.string ||\n option.kind === ReflectionKind.number\n ? option.variadic\n ? { kind: ReflectionKind.array, type: { kind: option.kind } }\n : { kind: option.kind }\n : { kind: ReflectionKind.boolean },\n default: option.default,\n tags: {\n title: option.title,\n alias: option.alias\n .filter(alias => alias.length > 0)\n .map(alias => constantCase(alias)),\n domain: \"cli\"\n }\n });\n });\n }\n\n if (tree.params) {\n tree.params.forEach(param => {\n context.env.types.env.addProperty({\n name: constantCase(param.name),\n optional: param.optional ? true : undefined,\n description: param.description,\n visibility: ReflectionVisibility.public,\n type: param.variadic\n ? {\n kind: ReflectionKind.array,\n type: { kind: ReflectionKind.string }\n }\n : { kind: ReflectionKind.string },\n default: param.default,\n tags: {\n domain: \"cli\"\n }\n });\n });\n }\n }\n\n for (const input of context.inputs.filter(\n input =>\n input.path.segments.filter(segment => !isVariableCommandPath(segment))\n .length ===\n command.path.segments.filter(segment => !isVariableCommandPath(segment))\n .length +\n 1 &&\n input.path.segments\n .slice(0, command.path.segments.length)\n .every((value, index) => value === command.path.segments[index])\n )) {\n tree.children[input.name] = await reflectCommandTree(context, input, tree);\n }\n\n return tree;\n}\n"],"mappings":"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"}
package/dist/plugin.cjs CHANGED
@@ -2,16 +2,21 @@ Object.defineProperty(exports, '__esModule', { value: true });
2
2
  const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
3
3
  const require_plugin_utils_context_helpers = require('./plugin-utils/context-helpers.cjs');
4
4
  const require_components_docs = require('./components/docs.cjs');
5
+ const require_plugin_utils_get_command_tree = require('./plugin-utils/get-command-tree.cjs');
6
+ const require_plugin_utils_traverse_command_tree = require('./plugin-utils/traverse-command-tree.cjs');
7
+ const require_automd = require('./helpers/automd.cjs');
5
8
  const require_persistence = require('./helpers/persistence.cjs');
6
9
  const require_utilities = require('./helpers/utilities.cjs');
7
10
  const require_resolve_command = require('./helpers/resolve-command.cjs');
8
11
  const require_update_package_json = require('./helpers/update-package-json.cjs');
9
12
  const require_validations = require('./helpers/validations.cjs');
10
- const require_plugin_utils_get_command_tree = require('./plugin-utils/get-command-tree.cjs');
11
- const require_plugin_utils_traverse_command_tree = require('./plugin-utils/traverse-command-tree.cjs');
12
13
  let __alloy_js_core_jsx_runtime = require("@alloy-js/core/jsx-runtime");
13
14
  let __alloy_js_core_components = require("@alloy-js/core/components");
14
15
  let __powerlines_plugin_alloy_render = require("@powerlines/plugin-alloy/render");
16
+ let __powerlines_plugin_automd = require("@powerlines/plugin-automd");
17
+ __powerlines_plugin_automd = require_rolldown_runtime.__toESM(__powerlines_plugin_automd);
18
+ let __powerlines_plugin_deepkit = require("@powerlines/plugin-deepkit");
19
+ __powerlines_plugin_deepkit = require_rolldown_runtime.__toESM(__powerlines_plugin_deepkit);
15
20
  let __powerlines_plugin_nodejs = require("@powerlines/plugin-nodejs");
16
21
  __powerlines_plugin_nodejs = require_rolldown_runtime.__toESM(__powerlines_plugin_nodejs);
17
22
  let __powerlines_plugin_tsdown = require("@powerlines/plugin-tsdown");
@@ -40,6 +45,8 @@ const MAX_DEPTH = 50;
40
45
  const plugin = (options = {}) => {
41
46
  return [
42
47
  (0, __powerlines_plugin_tsdown.default)(),
48
+ (0, __powerlines_plugin_deepkit.default)(),
49
+ (0, __powerlines_plugin_automd.default)(),
43
50
  {
44
51
  name: "shell-shock:config",
45
52
  async config() {
@@ -51,7 +58,6 @@ const plugin = (options = {}) => {
51
58
  description: require_plugin_utils_context_helpers.getAppDescription(this),
52
59
  envPrefix: (0, __stryke_string_format_constant_case.constantCase)(require_plugin_utils_context_helpers.getAppName(this)),
53
60
  env: { prefix: [] },
54
- automd: { generators: {} },
55
61
  isCaseSensitive: false,
56
62
  output: {
57
63
  format: "esm",
@@ -62,7 +68,8 @@ const plugin = (options = {}) => {
62
68
  dts: false,
63
69
  platform: "node",
64
70
  nodeProtocol: true,
65
- unbundle: false
71
+ unbundle: false,
72
+ noExternal: ["@powerlines/deepkit"]
66
73
  },
67
74
  type: "application",
68
75
  framework: "shell-shock"
@@ -81,6 +88,7 @@ const plugin = (options = {}) => {
81
88
  name: this.config.name,
82
89
  title: this.config.title,
83
90
  description: this.config.description,
91
+ alias: [],
84
92
  path: {
85
93
  value: null,
86
94
  segments: []
@@ -111,6 +119,7 @@ const plugin = (options = {}) => {
111
119
  segments: path.split("/").filter(Boolean)
112
120
  },
113
121
  name,
122
+ alias: [],
114
123
  isVirtual: false,
115
124
  entry: {
116
125
  ...entry,
@@ -155,6 +164,7 @@ const plugin = (options = {}) => {
155
164
  segments: path.split("/").filter(Boolean)
156
165
  },
157
166
  name,
167
+ alias: [],
158
168
  isVirtual: true,
159
169
  entry: { file }
160
170
  });
@@ -237,12 +247,19 @@ const plugin = (options = {}) => {
237
247
  },
238
248
  {
239
249
  name: "shell-shock:docs",
250
+ configResolved() {
251
+ this.config.automd ??= {};
252
+ this.config.automd.generators = {
253
+ ...this.config.automd.generators ?? {},
254
+ commands: require_automd.commands(this)
255
+ };
256
+ },
240
257
  async docs() {
241
258
  this.debug("Rendering entrypoint modules for the Shell Shock `script` preset.");
242
- const commands = this.inputs.map((input) => require_plugin_utils_get_command_tree.getCommandTree(this, input.path.segments)).filter(Boolean);
259
+ const commands$1 = this.inputs.map((input) => require_plugin_utils_get_command_tree.getCommandTree(this, input.path.segments)).filter(Boolean);
243
260
  return (0, __powerlines_plugin_alloy_render.render)(this, (0, __alloy_js_core_jsx_runtime.createComponent)(__alloy_js_core_components.For, {
244
261
  get each() {
245
- return Object.values(commands);
262
+ return Object.values(commands$1);
246
263
  },
247
264
  doubleHardline: true,
248
265
  children: (child) => (0, __alloy_js_core_jsx_runtime.createComponent)(__alloy_js_core_components.Show, {