@shell-shock/core 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. package/README.md +1 -1
  2. package/dist/api.cjs +15 -3
  3. package/dist/api.cjs.map +1 -0
  4. package/dist/api.d.cts +9 -1
  5. package/dist/api.d.cts.map +1 -0
  6. package/dist/api.d.mts +9 -1
  7. package/dist/api.d.mts.map +1 -0
  8. package/dist/api.mjs +14 -3
  9. package/dist/api.mjs.map +1 -0
  10. package/dist/components/docs.cjs +105 -0
  11. package/dist/components/docs.cjs.map +1 -0
  12. package/dist/components/docs.d.cts +56 -0
  13. package/dist/components/docs.d.cts.map +1 -0
  14. package/dist/components/docs.d.mts +56 -0
  15. package/dist/components/docs.d.mts.map +1 -0
  16. package/dist/components/docs.mjs +102 -0
  17. package/dist/components/docs.mjs.map +1 -0
  18. package/dist/components/index.cjs +4 -6
  19. package/dist/components/index.d.cts +2 -2
  20. package/dist/components/index.d.mts +2 -2
  21. package/dist/components/index.mjs +2 -2
  22. package/dist/config.cjs +2 -1
  23. package/dist/config.cjs.map +1 -0
  24. package/dist/config.d.cts +2 -1
  25. package/dist/config.d.cts.map +1 -0
  26. package/dist/config.d.mts +2 -1
  27. package/dist/config.d.mts.map +1 -0
  28. package/dist/config.mjs +2 -1
  29. package/dist/config.mjs.map +1 -0
  30. package/dist/contexts/command.cjs +21 -0
  31. package/dist/contexts/command.cjs.map +1 -0
  32. package/dist/contexts/command.d.cts +18 -0
  33. package/dist/contexts/command.d.cts.map +1 -0
  34. package/dist/contexts/command.d.mts +18 -0
  35. package/dist/contexts/command.d.mts.map +1 -0
  36. package/dist/contexts/command.mjs +19 -0
  37. package/dist/contexts/command.mjs.map +1 -0
  38. package/dist/contexts/index.cjs +4 -0
  39. package/dist/contexts/index.d.cts +2 -0
  40. package/dist/contexts/index.d.mts +2 -0
  41. package/dist/contexts/index.mjs +3 -0
  42. package/dist/helpers/docs-helpers.cjs +17 -0
  43. package/dist/helpers/docs-helpers.cjs.map +1 -0
  44. package/dist/helpers/docs-helpers.mjs +16 -0
  45. package/dist/helpers/docs-helpers.mjs.map +1 -0
  46. package/dist/helpers/persistence.cjs +2 -1
  47. package/dist/helpers/persistence.cjs.map +1 -0
  48. package/dist/helpers/persistence.mjs +2 -1
  49. package/dist/helpers/persistence.mjs.map +1 -0
  50. package/dist/helpers/resolve-command.cjs +118 -33
  51. package/dist/helpers/resolve-command.cjs.map +1 -0
  52. package/dist/helpers/resolve-command.mjs +116 -32
  53. package/dist/helpers/resolve-command.mjs.map +1 -0
  54. package/dist/helpers/update-package-json.cjs +18 -10
  55. package/dist/helpers/update-package-json.cjs.map +1 -0
  56. package/dist/helpers/update-package-json.mjs +17 -10
  57. package/dist/helpers/update-package-json.mjs.map +1 -0
  58. package/dist/helpers/utilities.cjs +30 -30
  59. package/dist/helpers/utilities.cjs.map +1 -0
  60. package/dist/helpers/utilities.mjs +29 -28
  61. package/dist/helpers/utilities.mjs.map +1 -0
  62. package/dist/helpers/validations.cjs +97 -0
  63. package/dist/helpers/validations.cjs.map +1 -0
  64. package/dist/helpers/validations.mjs +97 -0
  65. package/dist/helpers/validations.mjs.map +1 -0
  66. package/dist/index.cjs +5 -13
  67. package/dist/index.cjs.map +1 -0
  68. package/dist/index.d.cts +6 -17
  69. package/dist/index.d.mts +6 -17
  70. package/dist/index.mjs +4 -13
  71. package/dist/index.mjs.map +1 -0
  72. package/dist/plugin-utils/context-helpers.cjs +86 -0
  73. package/dist/plugin-utils/context-helpers.cjs.map +1 -0
  74. package/dist/plugin-utils/context-helpers.d.cts +58 -0
  75. package/dist/plugin-utils/context-helpers.d.cts.map +1 -0
  76. package/dist/plugin-utils/context-helpers.d.mts +58 -0
  77. package/dist/plugin-utils/context-helpers.d.mts.map +1 -0
  78. package/dist/plugin-utils/context-helpers.mjs +79 -0
  79. package/dist/plugin-utils/context-helpers.mjs.map +1 -0
  80. package/dist/plugin-utils/get-command-tree.cjs +4 -2
  81. package/dist/plugin-utils/get-command-tree.cjs.map +1 -0
  82. package/dist/plugin-utils/get-command-tree.d.cts +2 -1
  83. package/dist/plugin-utils/get-command-tree.d.cts.map +1 -0
  84. package/dist/plugin-utils/get-command-tree.d.mts +2 -1
  85. package/dist/plugin-utils/get-command-tree.d.mts.map +1 -0
  86. package/dist/plugin-utils/get-command-tree.mjs +5 -2
  87. package/dist/plugin-utils/get-command-tree.mjs.map +1 -0
  88. package/dist/plugin-utils/index.cjs +14 -1
  89. package/dist/plugin-utils/index.d.cts +4 -1
  90. package/dist/plugin-utils/index.d.mts +4 -1
  91. package/dist/plugin-utils/index.mjs +4 -1
  92. package/dist/plugin-utils/reflect.cjs +25 -0
  93. package/dist/plugin-utils/reflect.cjs.map +1 -0
  94. package/dist/plugin-utils/reflect.d.cts +14 -0
  95. package/dist/plugin-utils/reflect.d.cts.map +1 -0
  96. package/dist/plugin-utils/reflect.d.mts +14 -0
  97. package/dist/plugin-utils/reflect.d.mts.map +1 -0
  98. package/dist/plugin-utils/reflect.mjs +24 -0
  99. package/dist/plugin-utils/reflect.mjs.map +1 -0
  100. package/dist/plugin-utils/traverse-command-tree.cjs +33 -0
  101. package/dist/plugin-utils/traverse-command-tree.cjs.map +1 -0
  102. package/dist/plugin-utils/traverse-command-tree.d.cts +23 -0
  103. package/dist/plugin-utils/traverse-command-tree.d.cts.map +1 -0
  104. package/dist/plugin-utils/traverse-command-tree.d.mts +23 -0
  105. package/dist/plugin-utils/traverse-command-tree.d.mts.map +1 -0
  106. package/dist/plugin-utils/traverse-command-tree.mjs +31 -0
  107. package/dist/plugin-utils/traverse-command-tree.mjs.map +1 -0
  108. package/dist/plugin.cjs +267 -0
  109. package/dist/plugin.cjs.map +1 -0
  110. package/dist/plugin.d.cts +13 -0
  111. package/dist/plugin.d.cts.map +1 -0
  112. package/dist/plugin.d.mts +13 -0
  113. package/dist/plugin.d.mts.map +1 -0
  114. package/dist/plugin.mjs +261 -0
  115. package/dist/plugin.mjs.map +1 -0
  116. package/dist/types/command.d.cts +13 -4
  117. package/dist/types/command.d.cts.map +1 -0
  118. package/dist/types/command.d.mts +13 -4
  119. package/dist/types/command.d.mts.map +1 -0
  120. package/dist/types/config.d.cts +73 -10
  121. package/dist/types/config.d.cts.map +1 -0
  122. package/dist/types/config.d.mts +73 -10
  123. package/dist/types/config.d.mts.map +1 -0
  124. package/dist/types/context.d.cts +7 -4
  125. package/dist/types/context.d.cts.map +1 -0
  126. package/dist/types/context.d.mts +7 -4
  127. package/dist/types/context.d.mts.map +1 -0
  128. package/dist/types/index.d.cts +4 -4
  129. package/dist/types/index.d.mts +4 -4
  130. package/dist/types/internal.cjs +0 -0
  131. package/dist/types/internal.d.cts +24 -0
  132. package/dist/types/internal.d.cts.map +1 -0
  133. package/dist/types/internal.d.mts +24 -0
  134. package/dist/types/internal.d.mts.map +1 -0
  135. package/dist/types/internal.mjs +1 -0
  136. package/dist/types/options.d.cts +2 -1
  137. package/dist/types/options.d.cts.map +1 -0
  138. package/dist/types/options.d.mts +2 -1
  139. package/dist/types/options.d.mts.map +1 -0
  140. package/package.json +207 -92
  141. package/dist/components/utils-builtin.cjs +0 -453
  142. package/dist/components/utils-builtin.d.cts +0 -27
  143. package/dist/components/utils-builtin.d.mts +0 -27
  144. package/dist/components/utils-builtin.mjs +0 -447
  145. package/dist/powerlines.cjs +0 -172
  146. package/dist/powerlines.d.cts +0 -12
  147. package/dist/powerlines.d.mts +0 -12
  148. package/dist/powerlines.mjs +0 -168
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command.cjs","names":["createNamedContext","useContext","CommandContext","useCommand"],"sources":["../../src/contexts/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 type { ComponentContext } from \"@alloy-js/core\";\nimport { createNamedContext, useContext } from \"@alloy-js/core\";\nimport type { CommandTree } from \"../types/command\";\n\n/**\n * The reflection parameter context used in template rendering.\n */\nexport const CommandContext: ComponentContext<CommandTree | undefined> =\n createNamedContext<CommandTree | undefined>(\"Command\");\n\n/**\n * Hook to access the Command context.\n *\n * @returns A reactive version of the current reflection.\n */\nexport function useCommand() {\n return useContext<CommandTree | undefined>(CommandContext)!;\n}\n"],"mappings":";;;;;;;AAyBA,MAAaE,yDACiC,UAAU;;;;;;AAOxD,SAAgBC,aAAa;AAC3B,wCAA2CD,eAAe"}
@@ -0,0 +1,18 @@
1
+ import { CommandTree } from "../types/command.cjs";
2
+ import { ComponentContext } from "@alloy-js/core";
3
+
4
+ //#region src/contexts/command.d.ts
5
+
6
+ /**
7
+ * The reflection parameter context used in template rendering.
8
+ */
9
+ declare const CommandContext: ComponentContext<CommandTree | undefined>;
10
+ /**
11
+ * Hook to access the Command context.
12
+ *
13
+ * @returns A reactive version of the current reflection.
14
+ */
15
+ declare function useCommand(): CommandTree;
16
+ //#endregion
17
+ export { CommandContext, useCommand };
18
+ //# sourceMappingURL=command.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command.d.cts","names":[],"sources":["../../src/contexts/command.ts"],"sourcesContent":[],"mappings":";;;;;;;AAyBA;AAQgB,cARH,cAQa,EARG,gBAQH,CARoB,WAQpB,GAAA,SAAA,CAAA;;;;;;iBAAV,UAAA,CAAA,GAAU"}
@@ -0,0 +1,18 @@
1
+ import { CommandTree } from "../types/command.mjs";
2
+ import { ComponentContext } from "@alloy-js/core";
3
+
4
+ //#region src/contexts/command.d.ts
5
+
6
+ /**
7
+ * The reflection parameter context used in template rendering.
8
+ */
9
+ declare const CommandContext: ComponentContext<CommandTree | undefined>;
10
+ /**
11
+ * Hook to access the Command context.
12
+ *
13
+ * @returns A reactive version of the current reflection.
14
+ */
15
+ declare function useCommand(): CommandTree;
16
+ //#endregion
17
+ export { CommandContext, useCommand };
18
+ //# sourceMappingURL=command.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command.d.mts","names":[],"sources":["../../src/contexts/command.ts"],"sourcesContent":[],"mappings":";;;;;;;AAyBA;AAQgB,cARH,cAQa,EARG,gBAQH,CARoB,WAQpB,GAAA,SAAA,CAAA;;;;;;iBAAV,UAAA,CAAA,GAAU"}
@@ -0,0 +1,19 @@
1
+ import { createNamedContext, useContext } from "@alloy-js/core";
2
+
3
+ //#region src/contexts/command.ts
4
+ /**
5
+ * The reflection parameter context used in template rendering.
6
+ */
7
+ const CommandContext = createNamedContext("Command");
8
+ /**
9
+ * Hook to access the Command context.
10
+ *
11
+ * @returns A reactive version of the current reflection.
12
+ */
13
+ function useCommand() {
14
+ return useContext(CommandContext);
15
+ }
16
+
17
+ //#endregion
18
+ export { CommandContext, useCommand };
19
+ //# sourceMappingURL=command.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command.mjs","names":["createNamedContext","useContext","CommandContext","useCommand"],"sources":["../../src/contexts/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 type { ComponentContext } from \"@alloy-js/core\";\nimport { createNamedContext, useContext } from \"@alloy-js/core\";\nimport type { CommandTree } from \"../types/command\";\n\n/**\n * The reflection parameter context used in template rendering.\n */\nexport const CommandContext: ComponentContext<CommandTree | undefined> =\n createNamedContext<CommandTree | undefined>(\"Command\");\n\n/**\n * Hook to access the Command context.\n *\n * @returns A reactive version of the current reflection.\n */\nexport function useCommand() {\n return useContext<CommandTree | undefined>(CommandContext)!;\n}\n"],"mappings":";;;;;;AAyBA,MAAaE,iBACXF,mBAA4C,UAAU;;;;;;AAOxD,SAAgBG,aAAa;AAC3B,QAAOF,WAAoCC,eAAe"}
@@ -0,0 +1,4 @@
1
+ const require_contexts_command = require('./command.cjs');
2
+
3
+ exports.CommandContext = require_contexts_command.CommandContext;
4
+ exports.useCommand = require_contexts_command.useCommand;
@@ -0,0 +1,2 @@
1
+ import { CommandContext, useCommand } from "./command.cjs";
2
+ export { CommandContext, useCommand };
@@ -0,0 +1,2 @@
1
+ import { CommandContext, useCommand } from "./command.mjs";
2
+ export { CommandContext, useCommand };
@@ -0,0 +1,3 @@
1
+ import { CommandContext, useCommand } from "./command.mjs";
2
+
3
+ export { CommandContext, useCommand };
@@ -0,0 +1,17 @@
1
+ const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
2
+ let __stryke_path_join = require("@stryke/path/join");
3
+
4
+ //#region src/helpers/docs-helpers.ts
5
+ /**
6
+ * Gets the output path for the generated documentation.
7
+ *
8
+ * @param context - The Shell Shock context.
9
+ * @returns The output path for the generated documentation.
10
+ */
11
+ function getDocsOutputPath(context) {
12
+ return (0, __stryke_path_join.joinPaths)(context.config.projectRoot, "docs", "generated");
13
+ }
14
+
15
+ //#endregion
16
+ exports.getDocsOutputPath = getDocsOutputPath;
17
+ //# sourceMappingURL=docs-helpers.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docs-helpers.cjs","names":["joinPaths","getDocsOutputPath","context","config","projectRoot"],"sources":["../../src/helpers/docs-helpers.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 { joinPaths } from \"@stryke/path/join\";\nimport type { Context } from \"../types/context\";\n\n/**\n * Gets the output path for the generated documentation.\n *\n * @param context - The Shell Shock context.\n * @returns The output path for the generated documentation.\n */\nexport function getDocsOutputPath(context: Context): string {\n return joinPaths(context.config.projectRoot, \"docs\", \"generated\");\n}\n"],"mappings":";;;;;;;;;;AA2BA,SAAgBC,kBAAkBC,SAA0B;AAC1D,0CAAiBA,QAAQC,OAAOC,aAAa,QAAQ,YAAY"}
@@ -0,0 +1,16 @@
1
+ import { joinPaths } from "@stryke/path/join";
2
+
3
+ //#region src/helpers/docs-helpers.ts
4
+ /**
5
+ * Gets the output path for the generated documentation.
6
+ *
7
+ * @param context - The Shell Shock context.
8
+ * @returns The output path for the generated documentation.
9
+ */
10
+ function getDocsOutputPath(context) {
11
+ return joinPaths(context.config.projectRoot, "docs", "generated");
12
+ }
13
+
14
+ //#endregion
15
+ export { getDocsOutputPath };
16
+ //# sourceMappingURL=docs-helpers.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docs-helpers.mjs","names":["joinPaths","getDocsOutputPath","context","config","projectRoot"],"sources":["../../src/helpers/docs-helpers.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 { joinPaths } from \"@stryke/path/join\";\nimport type { Context } from \"../types/context\";\n\n/**\n * Gets the output path for the generated documentation.\n *\n * @param context - The Shell Shock context.\n * @returns The output path for the generated documentation.\n */\nexport function getDocsOutputPath(context: Context): string {\n return joinPaths(context.config.projectRoot, \"docs\", \"generated\");\n}\n"],"mappings":";;;;;;;;;AA2BA,SAAgBC,kBAAkBC,SAA0B;AAC1D,QAAOF,UAAUE,QAAQC,OAAOC,aAAa,QAAQ,YAAY"}
@@ -46,4 +46,5 @@ async function writeCommandsPersistence(context) {
46
46
  //#endregion
47
47
  exports.getCommandsPersistencePath = getCommandsPersistencePath;
48
48
  exports.readCommandsPersistence = readCommandsPersistence;
49
- exports.writeCommandsPersistence = writeCommandsPersistence;
49
+ exports.writeCommandsPersistence = writeCommandsPersistence;
50
+ //# sourceMappingURL=persistence.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"persistence.cjs","names":["joinPaths","getCommandsPersistencePath","context","dataPath","serializedCommandTree","commands","serialize","node","parent","serializedNode","children","key","child","Object","entries","id","result","deserializeCommandTree","serializedCommands","deserialize","deserializedNode","readCommandsPersistence","reflections","fs","read","length","Error","JSON","parse","writeCommandsPersistence","filePath","write","stringify","config","mode"],"sources":["../../src/helpers/persistence.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 { joinPaths } from \"@stryke/path/join-paths\";\nimport type { CommandTree, SerializedCommandTree } from \"../types\";\nimport type { Context } from \"../types/context\";\n\nexport function getCommandsPersistencePath(context: Context): string {\n return joinPaths(context.dataPath, `commands.json`);\n}\n\nfunction serializedCommandTree(\n commands: Record<string, CommandTree>\n): Record<string, SerializedCommandTree> {\n const serialize = (\n node: CommandTree,\n parent: string | null = null\n ): SerializedCommandTree => {\n const serializedNode: SerializedCommandTree = {\n ...node,\n parent,\n children: {}\n };\n\n for (const [key, child] of Object.entries(node.children || {})) {\n serializedNode.children[key] = serialize(child, node.id);\n }\n\n return serializedNode;\n };\n\n const result: Record<string, SerializedCommandTree> = {};\n for (const [key, child] of Object.entries(commands)) {\n result[key] = serialize(child, null);\n }\n\n return result;\n}\n\nfunction deserializeCommandTree(\n serializedCommands: Record<string, SerializedCommandTree>\n): Record<string, CommandTree> {\n const deserialize = (\n node: SerializedCommandTree,\n parent: CommandTree | null = null\n ): CommandTree => {\n const deserializedNode: CommandTree = {\n ...node,\n parent,\n children: {}\n };\n\n for (const [key, child] of Object.entries(node.children || {})) {\n deserializedNode.children[key] = deserialize(child, deserializedNode);\n }\n\n return deserializedNode;\n };\n\n const result: Record<string, CommandTree> = {};\n for (const [key, child] of Object.entries(serializedCommands)) {\n result[key] = deserialize(child, null);\n }\n\n return result;\n}\n\nexport async function readCommandsPersistence(context: Context) {\n const reflections = await context.fs.read(\n getCommandsPersistencePath(context)\n );\n if (!reflections || !reflections.length) {\n throw new Error(\n `CLI Command reflection file ${getCommandsPersistencePath(context)} is empty`\n );\n }\n\n context.commands = deserializeCommandTree(JSON.parse(reflections));\n}\n\nexport async function writeCommandsPersistence(context: Context) {\n const filePath = getCommandsPersistencePath(context);\n\n await context.fs.write(\n filePath,\n JSON.stringify(\n serializedCommandTree(context.commands),\n null,\n context.config.mode === \"development\" ? 2 : 0\n )\n );\n}\n"],"mappings":";;;;AAsBA,SAAgBC,2BAA2BC,SAA0B;AACnE,gDAAiBA,QAAQC,UAAU,gBAAgB;;AAGrD,SAASC,sBACPC,UACuC;CACvC,MAAMC,aACJC,MACAC,SAAwB,SACE;EAC1B,MAAMC,iBAAwC;GAC5C,GAAGF;GACHC;GACAE,UAAU,EAAC;GACZ;AAED,OAAK,MAAM,CAACC,KAAKC,UAAUC,OAAOC,QAAQP,KAAKG,YAAY,EAAE,CAAC,CAC5DD,gBAAeC,SAASC,OAAOL,UAAUM,OAAOL,KAAKQ,GAAG;AAG1D,SAAON;;CAGT,MAAMO,SAAgD,EAAE;AACxD,MAAK,MAAM,CAACL,KAAKC,UAAUC,OAAOC,QAAQT,SAAS,CACjDW,QAAOL,OAAOL,UAAUM,OAAO,KAAK;AAGtC,QAAOI;;AAGT,SAASC,uBACPC,oBAC6B;CAC7B,MAAMC,eACJZ,MACAC,SAA6B,SACb;EAChB,MAAMY,mBAAgC;GACpC,GAAGb;GACHC;GACAE,UAAU,EAAC;GACZ;AAED,OAAK,MAAM,CAACC,KAAKC,UAAUC,OAAOC,QAAQP,KAAKG,YAAY,EAAE,CAAC,CAC5DU,kBAAiBV,SAASC,OAAOQ,YAAYP,OAAOQ,iBAAiB;AAGvE,SAAOA;;CAGT,MAAMJ,SAAsC,EAAE;AAC9C,MAAK,MAAM,CAACL,KAAKC,UAAUC,OAAOC,QAAQI,mBAAmB,CAC3DF,QAAOL,OAAOQ,YAAYP,OAAO,KAAK;AAGxC,QAAOI;;AAGT,eAAsBK,wBAAwBnB,SAAkB;CAC9D,MAAMoB,cAAc,MAAMpB,QAAQqB,GAAGC,KACnCvB,2BAA2BC,QAC7B,CAAC;AACD,KAAI,CAACoB,eAAe,CAACA,YAAYG,OAC/B,OAAM,IAAIC,MACR,+BAA+BzB,2BAA2BC,QAAQ,CAAA,WACnE;AAGHA,SAAQG,WAAWY,uBAAuBU,KAAKC,MAAMN,YAAY,CAAC;;AAGpE,eAAsBO,yBAAyB3B,SAAkB;CAC/D,MAAM4B,WAAW7B,2BAA2BC,QAAQ;AAEpD,OAAMA,QAAQqB,GAAGQ,MACfD,UACAH,KAAKK,UACH5B,sBAAsBF,QAAQG,SAAS,EACvC,MACAH,QAAQ+B,OAAOC,SAAS,gBAAgB,IAAI,EAEhD,CAAC"}
@@ -43,4 +43,5 @@ async function writeCommandsPersistence(context) {
43
43
  }
44
44
 
45
45
  //#endregion
46
- export { getCommandsPersistencePath, readCommandsPersistence, writeCommandsPersistence };
46
+ export { getCommandsPersistencePath, readCommandsPersistence, writeCommandsPersistence };
47
+ //# sourceMappingURL=persistence.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"persistence.mjs","names":["joinPaths","getCommandsPersistencePath","context","dataPath","serializedCommandTree","commands","serialize","node","parent","serializedNode","children","key","child","Object","entries","id","result","deserializeCommandTree","serializedCommands","deserialize","deserializedNode","readCommandsPersistence","reflections","fs","read","length","Error","JSON","parse","writeCommandsPersistence","filePath","write","stringify","config","mode"],"sources":["../../src/helpers/persistence.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 { joinPaths } from \"@stryke/path/join-paths\";\nimport type { CommandTree, SerializedCommandTree } from \"../types\";\nimport type { Context } from \"../types/context\";\n\nexport function getCommandsPersistencePath(context: Context): string {\n return joinPaths(context.dataPath, `commands.json`);\n}\n\nfunction serializedCommandTree(\n commands: Record<string, CommandTree>\n): Record<string, SerializedCommandTree> {\n const serialize = (\n node: CommandTree,\n parent: string | null = null\n ): SerializedCommandTree => {\n const serializedNode: SerializedCommandTree = {\n ...node,\n parent,\n children: {}\n };\n\n for (const [key, child] of Object.entries(node.children || {})) {\n serializedNode.children[key] = serialize(child, node.id);\n }\n\n return serializedNode;\n };\n\n const result: Record<string, SerializedCommandTree> = {};\n for (const [key, child] of Object.entries(commands)) {\n result[key] = serialize(child, null);\n }\n\n return result;\n}\n\nfunction deserializeCommandTree(\n serializedCommands: Record<string, SerializedCommandTree>\n): Record<string, CommandTree> {\n const deserialize = (\n node: SerializedCommandTree,\n parent: CommandTree | null = null\n ): CommandTree => {\n const deserializedNode: CommandTree = {\n ...node,\n parent,\n children: {}\n };\n\n for (const [key, child] of Object.entries(node.children || {})) {\n deserializedNode.children[key] = deserialize(child, deserializedNode);\n }\n\n return deserializedNode;\n };\n\n const result: Record<string, CommandTree> = {};\n for (const [key, child] of Object.entries(serializedCommands)) {\n result[key] = deserialize(child, null);\n }\n\n return result;\n}\n\nexport async function readCommandsPersistence(context: Context) {\n const reflections = await context.fs.read(\n getCommandsPersistencePath(context)\n );\n if (!reflections || !reflections.length) {\n throw new Error(\n `CLI Command reflection file ${getCommandsPersistencePath(context)} is empty`\n );\n }\n\n context.commands = deserializeCommandTree(JSON.parse(reflections));\n}\n\nexport async function writeCommandsPersistence(context: Context) {\n const filePath = getCommandsPersistencePath(context);\n\n await context.fs.write(\n filePath,\n JSON.stringify(\n serializedCommandTree(context.commands),\n null,\n context.config.mode === \"development\" ? 2 : 0\n )\n );\n}\n"],"mappings":";;;AAsBA,SAAgBC,2BAA2BC,SAA0B;AACnE,QAAOF,UAAUE,QAAQC,UAAU,gBAAgB;;AAGrD,SAASC,sBACPC,UACuC;CACvC,MAAMC,aACJC,MACAC,SAAwB,SACE;EAC1B,MAAMC,iBAAwC;GAC5C,GAAGF;GACHC;GACAE,UAAU,EAAC;GACZ;AAED,OAAK,MAAM,CAACC,KAAKC,UAAUC,OAAOC,QAAQP,KAAKG,YAAY,EAAE,CAAC,CAC5DD,gBAAeC,SAASC,OAAOL,UAAUM,OAAOL,KAAKQ,GAAG;AAG1D,SAAON;;CAGT,MAAMO,SAAgD,EAAE;AACxD,MAAK,MAAM,CAACL,KAAKC,UAAUC,OAAOC,QAAQT,SAAS,CACjDW,QAAOL,OAAOL,UAAUM,OAAO,KAAK;AAGtC,QAAOI;;AAGT,SAASC,uBACPC,oBAC6B;CAC7B,MAAMC,eACJZ,MACAC,SAA6B,SACb;EAChB,MAAMY,mBAAgC;GACpC,GAAGb;GACHC;GACAE,UAAU,EAAC;GACZ;AAED,OAAK,MAAM,CAACC,KAAKC,UAAUC,OAAOC,QAAQP,KAAKG,YAAY,EAAE,CAAC,CAC5DU,kBAAiBV,SAASC,OAAOQ,YAAYP,OAAOQ,iBAAiB;AAGvE,SAAOA;;CAGT,MAAMJ,SAAsC,EAAE;AAC9C,MAAK,MAAM,CAACL,KAAKC,UAAUC,OAAOC,QAAQI,mBAAmB,CAC3DF,QAAOL,OAAOQ,YAAYP,OAAO,KAAK;AAGxC,QAAOI;;AAGT,eAAsBK,wBAAwBnB,SAAkB;CAC9D,MAAMoB,cAAc,MAAMpB,QAAQqB,GAAGC,KACnCvB,2BAA2BC,QAC7B,CAAC;AACD,KAAI,CAACoB,eAAe,CAACA,YAAYG,OAC/B,OAAM,IAAIC,MACR,+BAA+BzB,2BAA2BC,QAAQ,CAAA,WACnE;AAGHA,SAAQG,WAAWY,uBAAuBU,KAAKC,MAAMN,YAAY,CAAC;;AAGpE,eAAsBO,yBAAyB3B,SAAkB;CAC/D,MAAM4B,WAAW7B,2BAA2BC,QAAQ;AAEpD,OAAMA,QAAQqB,GAAGQ,MACfD,UACAH,KAAKK,UACH5B,sBAAsBF,QAAQG,SAAS,EACvC,MACAH,QAAQ+B,OAAOC,SAAS,gBAAgB,IAAI,EAEhD,CAAC"}
@@ -1,19 +1,47 @@
1
1
  const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
2
- let __stryke_helpers_get_unique = require("@stryke/helpers/get-unique");
2
+ const require_plugin_utils_context_helpers = require('../plugin-utils/context-helpers.cjs');
3
+ const require_utilities = require('./utilities.cjs');
3
4
  let __stryke_path_append = require("@stryke/path/append");
4
5
  let __stryke_path_file_path_fns = require("@stryke/path/file-path-fns");
5
6
  let __stryke_path_replace = require("@stryke/path/replace");
6
7
  let __stryke_path_resolve_parent_path = require("@stryke/path/resolve-parent-path");
7
- let __stryke_string_format_title_case = require("@stryke/string-format/title-case");
8
- let __stryke_type_checks_is_function = require("@stryke/type-checks/is-function");
8
+ let __stryke_string_format_constant_case = require("@stryke/string-format/constant-case");
9
9
  let __stryke_type_checks_is_set_object = require("@stryke/type-checks/is-set-object");
10
- let __powerlines_deepkit_reflect_type = require("@powerlines/deepkit/reflect-type");
10
+ let __stryke_type_checks_is_set_string = require("@stryke/type-checks/is-set-string");
11
+ let __stryke_string_format_title_case = require("@stryke/string-format/title-case");
11
12
  let __powerlines_deepkit_vendor_type = require("@powerlines/deepkit/vendor/type");
13
+ let __powerlines_deepkit_reflect_type = require("@powerlines/deepkit/reflect-type");
12
14
  let __stryke_path_common = require("@stryke/path/common");
13
15
  let __stryke_path_normalize = require("@stryke/path/normalize");
14
- let __stryke_type_checks_is_set_string = require("@stryke/type-checks/is-set-string");
15
16
 
16
17
  //#region src/helpers/resolve-command.ts
18
+ /**
19
+ * Resolves the description for a command option based on its reflection.
20
+ *
21
+ * @param propertyReflection - The reflection property of the command option.
22
+ * @returns The resolved description for the command option.
23
+ */
24
+ function resolveCommandDescription(propertyReflection) {
25
+ return propertyReflection.getDescription()?.trim() || `A${propertyReflection.isOptional() && !propertyReflection.getDefaultValue() ? "n optional" : ""} ${propertyReflection.getType().kind === __powerlines_deepkit_vendor_type.ReflectionKind.boolean ? "flag provided via the command-line" : "command-line option"} that allows the user to ${propertyReflection.getType().kind === __powerlines_deepkit_vendor_type.ReflectionKind.boolean ? "set the" : propertyReflection.getType().kind === __powerlines_deepkit_vendor_type.ReflectionKind.array ? "specify custom" : "specify a custom"} ${propertyReflection.getTags().title?.trim() || (0, __stryke_string_format_title_case.titleCase)(propertyReflection.getNameAsString())} ${propertyReflection.getType().kind === __powerlines_deepkit_vendor_type.ReflectionKind.boolean ? "indicator" : `${propertyReflection.getType().kind === __powerlines_deepkit_vendor_type.ReflectionKind.number ? "numeric" : "string"} value${propertyReflection.getType().kind === __powerlines_deepkit_vendor_type.ReflectionKind.array ? "s" : ""}`} that will be used in the application.`;
26
+ }
27
+ function resolveCommandId(context, file) {
28
+ return (0, __stryke_path_replace.replacePath)((0, __stryke_path_file_path_fns.findFilePath)(file), context.commandsPath).split("/").filter((p) => Boolean(p) && !require_plugin_utils_context_helpers.isVariableCommandPath(p)).join("/").replaceAll(/^\/+/g, "").replaceAll(/\/+$/g, "").replaceAll("/", "-");
29
+ }
30
+ /**
31
+ * Finds the command name from the given file path.
32
+ *
33
+ * @param file - The file path to extract the command name from.
34
+ * @returns The command name.
35
+ */
36
+ function resolveCommandName(file) {
37
+ let path = (0, __stryke_path_file_path_fns.findFilePath)(file);
38
+ let name = (0, __stryke_path_file_path_fns.findFolderName)(file, { requireExtension: true });
39
+ while (require_plugin_utils_context_helpers.isVariableCommandPath(name)) {
40
+ path = (0, __stryke_path_resolve_parent_path.resolveParentPath)(path);
41
+ name = (0, __stryke_path_file_path_fns.findFolderName)(path, { requireExtension: true });
42
+ }
43
+ return name;
44
+ }
17
45
  function resolveCommandPath(context, file) {
18
46
  return (0, __stryke_path_replace.replacePath)((0, __stryke_path_file_path_fns.findFilePath)(file), context.commandsPath).replaceAll(/^\/+/g, "").replaceAll(/\/+$/g, "");
19
47
  }
@@ -24,35 +52,46 @@ function findCommandsRoot(context) {
24
52
  return (0, __stryke_path_append.appendPath)(context.config.sourceRoot || context.config.projectRoot, context.workspaceConfig.workspaceRoot);
25
53
  }
26
54
  /**
27
- * Finds the command name from the given file path.
55
+ * Extracts command parameter information from a type parameter reflection.
28
56
  *
29
- * @param file - The file path to extract the command name from.
30
- * @returns The command name.
57
+ * @param param - The type parameter reflection to extract information from.
58
+ * @returns The extracted command parameter information.
31
59
  */
32
- function findCommandName(file) {
33
- let name = (0, __stryke_path_file_path_fns.findFolderName)(file);
34
- let count = 1;
35
- while (name.startsWith("[") && name.endsWith("]")) name = (0, __stryke_path_file_path_fns.findFolderName)((0, __stryke_path_resolve_parent_path.resolveParentPath)(file, count++));
36
- return name;
60
+ function extractCommandParameters(param) {
61
+ return {
62
+ name: param.name,
63
+ description: param.description,
64
+ optional: !!param.optional,
65
+ variadic: param.type.kind === __powerlines_deepkit_vendor_type.ReflectionKind.array,
66
+ default: param.default
67
+ };
37
68
  }
69
+ /**
70
+ * Reflects the command tree for a given command input.
71
+ *
72
+ * @param context - The context in which the command is being reflected.
73
+ * @param command - The command input to reflect.
74
+ * @param parent - The parent command tree, if any.
75
+ * @returns The reflected command tree.
76
+ */
38
77
  async function reflectCommandTree(context, command, parent) {
39
- const title = command.title || `${parent?.title ? `${parent.title} - ` : ""}${(0, __stryke_string_format_title_case.titleCase)(command.name)}`;
40
- const commandTree = {
78
+ const title = command.title || `${parent?.title ? `${parent.title} - ` : ""}${(0, __stryke_string_format_title_case.titleCase)(command.name)}${command.isVirtual ? " Commands" : ""}`;
79
+ const tree = {
41
80
  ...command,
42
81
  title,
43
- description: command.description || `The ${title} ${parent ? "sub-" : ""}command.`,
44
- options: {},
82
+ description: command.description || (command.isVirtual ? `A collection of available ${command.title || (0, __stryke_string_format_title_case.titleCase)(command.name)} commands that are included in the ${require_plugin_utils_context_helpers.getAppTitle(context)} command-line application.` : `The ${title} executable command-line interface.`),
83
+ path: {
84
+ ...command.path,
85
+ variables: {}
86
+ },
87
+ options: require_utilities.getDefaultOptions(context, command),
45
88
  params: [],
46
89
  parent: parent ?? null,
47
90
  children: {}
48
91
  };
49
- if (context.config.defaultOptions === false) commandTree.options = {};
50
- else if (Array.isArray(context.config.defaultOptions)) commandTree.options = Object.fromEntries((0, __stryke_helpers_get_unique.getUniqueBy)(context.config.defaultOptions, (item) => item.name).map((option) => [option.name, option]));
51
- else if ((0, __stryke_type_checks_is_function.isFunction)(context.config.defaultOptions)) commandTree.options = Object.fromEntries((0, __stryke_helpers_get_unique.getUniqueBy)(context.config.defaultOptions(context, command), (item) => item.name).map((option) => [option.name, option]));
52
- if (command.isVirtual) context.trace(`Adding reflection for virtual command: ${command.id}`);
53
- else {
92
+ if (!command.isVirtual) {
54
93
  if (!command.entry.input?.file || !context.fs.existsSync(command.entry.input.file)) throw new Error(`${!command.entry.input?.file ? "Missing" : "Non-existent"} command entry file for "${command.name}"`);
55
- context.trace(`Adding reflection for user-defined command: ${command.id} (file: ${command.entry.input.file})`);
94
+ context.debug(`Adding reflection for user-defined command: ${command.id} (file: ${command.entry.input.file})`);
56
95
  const type = await (0, __powerlines_deepkit_reflect_type.reflectType)(context, command.entry.input);
57
96
  if (type.kind !== __powerlines_deepkit_vendor_type.ReflectionKind.function) throw new Error(`The command entry file "${command.entry.input.file}" does not export a valid function.`);
58
97
  if (type.parameters.length > 0 && type.parameters[0]) {
@@ -61,32 +100,78 @@ async function reflectCommandTree(context, command, parent) {
61
100
  const optionsReflection = __powerlines_deepkit_vendor_type.ReflectionClass.from(firstParam.type);
62
101
  for (const propertyReflection of optionsReflection.getProperties()) {
63
102
  const propertyType = propertyReflection.getType();
64
- commandTree.options[propertyReflection.getNameAsString()] = {
103
+ tree.options[propertyReflection.getNameAsString()] = {
65
104
  name: propertyReflection.getNameAsString(),
66
105
  alias: propertyReflection.getTags().alias ?? [],
67
- title: propertyReflection.getTags().title || (0, __stryke_string_format_title_case.titleCase)(propertyReflection.getNameAsString()),
68
- description: propertyReflection.getDescription(),
106
+ title: propertyReflection.getTags().title?.trim() || (0, __stryke_string_format_title_case.titleCase)(propertyReflection.getNameAsString()),
107
+ description: resolveCommandDescription(propertyReflection),
108
+ env: (0, __stryke_string_format_constant_case.constantCase)(propertyReflection.getNameAsString()),
69
109
  kind: propertyType.kind,
70
110
  optional: propertyReflection.isOptional(),
71
111
  default: propertyReflection.getDefaultValue(),
72
112
  variadic: false
73
113
  };
74
- commandTree.options[propertyReflection.getNameAsString()].description ??= `The ${commandTree.options[propertyReflection.getNameAsString()].title} option.`;
75
114
  if (propertyType.kind === __powerlines_deepkit_vendor_type.ReflectionKind.array) if (propertyType.type.kind === __powerlines_deepkit_vendor_type.ReflectionKind.string || propertyType.type.kind === __powerlines_deepkit_vendor_type.ReflectionKind.number) {
76
- commandTree.options[propertyReflection.getNameAsString()].variadic = true;
77
- commandTree.options[propertyReflection.getNameAsString()].kind = propertyType.type.kind;
115
+ tree.options[propertyReflection.getNameAsString()].variadic = true;
116
+ tree.options[propertyReflection.getNameAsString()].kind = propertyType.type.kind;
78
117
  } else throw new Error(`Unsupported array type for option "${propertyReflection.getNameAsString()}" in command "${command.name}". Only string[] and number[] are supported.`);
79
118
  else if (propertyType.kind !== __powerlines_deepkit_vendor_type.ReflectionKind.boolean && propertyType.kind !== __powerlines_deepkit_vendor_type.ReflectionKind.string && propertyType.kind !== __powerlines_deepkit_vendor_type.ReflectionKind.number) throw new Error(`Unsupported type for option "${propertyReflection.getNameAsString()}" in command "${command.name}". Only string, number, boolean, string[] and number[] are supported, received ${(0, __powerlines_deepkit_vendor_type.stringifyType)(propertyType).trim().replaceAll(" | ", ", or ")}.`);
80
119
  }
81
120
  }
121
+ tree.path.variables = tree.path.segments.filter((segment) => require_plugin_utils_context_helpers.isVariableCommandPath(segment)).reduce((obj, segment, index) => {
122
+ if (type.parameters.length < index + 2 || !type.parameters[index + 1]) return obj;
123
+ const paramName = require_plugin_utils_context_helpers.getVariableCommandPathName(segment);
124
+ obj[paramName] = extractCommandParameters(type.parameters[index + 1]);
125
+ obj[paramName].description = obj[paramName].description || `The ${paramName} variable for the ${command.name} command.`;
126
+ return obj;
127
+ }, {});
128
+ if (type.parameters.length > 1) type.parameters.slice(tree.path.segments.filter((segment) => require_plugin_utils_context_helpers.isVariableCommandPath(segment)).length + 1).forEach((param) => {
129
+ tree.params.push(extractCommandParameters(param));
130
+ });
82
131
  }
83
132
  }
84
- for (const input of context.inputs.filter((input$1) => input$1.path.length === command.path.length + 1 && input$1.path.slice(0, command.path.length).every((value, index) => value === command.path[index]))) commandTree.children[input.name] = await reflectCommandTree(context, input, commandTree);
85
- return commandTree;
133
+ if (context.env) {
134
+ if ((0, __stryke_type_checks_is_set_object.isSetObject)(tree.options)) Object.values(tree.options).filter((option) => option.env !== false).forEach((option) => {
135
+ context.env.types.env.addProperty({
136
+ name: option.env,
137
+ optional: option.optional ? true : void 0,
138
+ description: option.description,
139
+ visibility: __powerlines_deepkit_vendor_type.ReflectionVisibility.public,
140
+ type: option.kind === __powerlines_deepkit_vendor_type.ReflectionKind.string || option.kind === __powerlines_deepkit_vendor_type.ReflectionKind.number ? option.variadic ? {
141
+ kind: __powerlines_deepkit_vendor_type.ReflectionKind.array,
142
+ type: { kind: option.kind }
143
+ } : { kind: option.kind } : { kind: __powerlines_deepkit_vendor_type.ReflectionKind.boolean },
144
+ default: option.default,
145
+ tags: {
146
+ title: option.title,
147
+ alias: option.alias.filter((alias) => alias.length > 0).map((alias) => (0, __stryke_string_format_constant_case.constantCase)(alias)),
148
+ domain: "cli"
149
+ }
150
+ });
151
+ });
152
+ if (tree.params) tree.params.forEach((param) => {
153
+ context.env.types.env.addProperty({
154
+ name: (0, __stryke_string_format_constant_case.constantCase)(param.name),
155
+ optional: param.optional ? true : void 0,
156
+ description: param.description,
157
+ visibility: __powerlines_deepkit_vendor_type.ReflectionVisibility.public,
158
+ type: param.variadic ? {
159
+ kind: __powerlines_deepkit_vendor_type.ReflectionKind.array,
160
+ type: { kind: __powerlines_deepkit_vendor_type.ReflectionKind.string }
161
+ } : { kind: __powerlines_deepkit_vendor_type.ReflectionKind.string },
162
+ default: param.default,
163
+ tags: { domain: "cli" }
164
+ });
165
+ });
166
+ }
167
+ for (const input of context.inputs.filter((input$1) => input$1.path.segments.filter((segment) => !require_plugin_utils_context_helpers.isVariableCommandPath(segment)).length === command.path.segments.filter((segment) => !require_plugin_utils_context_helpers.isVariableCommandPath(segment)).length + 1 && input$1.path.segments.slice(0, command.path.segments.length).every((value, index) => value === command.path.segments[index]))) tree.children[input.name] = await reflectCommandTree(context, input, tree);
168
+ return tree;
86
169
  }
87
170
 
88
171
  //#endregion
89
- exports.findCommandName = findCommandName;
90
172
  exports.findCommandsRoot = findCommandsRoot;
91
173
  exports.reflectCommandTree = reflectCommandTree;
92
- exports.resolveCommandPath = resolveCommandPath;
174
+ exports.resolveCommandId = resolveCommandId;
175
+ exports.resolveCommandName = resolveCommandName;
176
+ exports.resolveCommandPath = resolveCommandPath;
177
+ //# sourceMappingURL=resolve-command.cjs.map
@@ -0,0 +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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"}