@shell-shock/core 0.15.1 → 0.16.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.
- package/dist/api.cjs +10 -7
- package/dist/api.cjs.map +1 -1
- package/dist/api.d.cts +1 -1
- package/dist/api.d.cts.map +1 -1
- package/dist/api.d.mts +1 -1
- package/dist/api.d.mts.map +1 -1
- package/dist/api.mjs +11 -8
- package/dist/api.mjs.map +1 -1
- package/dist/components/helpers.cjs +1 -1
- package/dist/components/helpers.cjs.map +1 -1
- package/dist/components/helpers.mjs +1 -1
- package/dist/components/helpers.mjs.map +1 -1
- package/dist/components/index.cjs +8 -4
- package/dist/components/index.d.cts +4 -2
- package/dist/components/index.d.mts +4 -2
- package/dist/components/index.mjs +4 -2
- package/dist/components/options-parser-logic.cjs +68 -48
- package/dist/components/options-parser-logic.cjs.map +1 -1
- package/dist/components/options-parser-logic.d.cts.map +1 -1
- package/dist/components/options-parser-logic.d.mts.map +1 -1
- package/dist/components/options-parser-logic.mjs +68 -48
- package/dist/components/options-parser-logic.mjs.map +1 -1
- package/dist/components/spawn-builtin.cjs +656 -0
- package/dist/components/spawn-builtin.cjs.map +1 -0
- package/dist/components/spawn-builtin.d.cts +12 -0
- package/dist/components/spawn-builtin.d.cts.map +1 -0
- package/dist/components/spawn-builtin.d.mts +12 -0
- package/dist/components/spawn-builtin.d.mts.map +1 -0
- package/dist/components/spawn-builtin.mjs +653 -0
- package/dist/components/spawn-builtin.mjs.map +1 -0
- package/dist/components/state-builtin.cjs +545 -0
- package/dist/components/state-builtin.cjs.map +1 -0
- package/dist/components/state-builtin.d.cts +18 -0
- package/dist/components/state-builtin.d.cts.map +1 -0
- package/dist/components/state-builtin.d.mts +18 -0
- package/dist/components/state-builtin.d.mts.map +1 -0
- package/dist/components/state-builtin.mjs +539 -0
- package/dist/components/state-builtin.mjs.map +1 -0
- package/dist/components/utils-builtin.cjs +15 -509
- package/dist/components/utils-builtin.cjs.map +1 -1
- package/dist/components/utils-builtin.d.cts +1 -10
- package/dist/components/utils-builtin.d.cts.map +1 -1
- package/dist/components/utils-builtin.d.mts +1 -10
- package/dist/components/utils-builtin.d.mts.map +1 -1
- package/dist/components/utils-builtin.mjs +17 -508
- package/dist/components/utils-builtin.mjs.map +1 -1
- package/dist/config.cjs.map +1 -1
- package/dist/config.mjs.map +1 -1
- package/dist/contexts/options.cjs +9 -9
- package/dist/contexts/options.cjs.map +1 -1
- package/dist/contexts/options.d.cts +2 -2
- package/dist/contexts/options.d.cts.map +1 -1
- package/dist/contexts/options.d.mts +2 -2
- package/dist/contexts/options.d.mts.map +1 -1
- package/dist/contexts/options.mjs +9 -9
- package/dist/contexts/options.mjs.map +1 -1
- package/dist/index.cjs +2 -10
- package/dist/index.d.cts +1 -2
- package/dist/index.d.mts +1 -2
- package/dist/index.mjs +1 -7
- package/dist/plugin.cjs +17 -32
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.cts +1 -1
- package/dist/plugin.d.cts.map +1 -1
- package/dist/plugin.d.mts +1 -1
- package/dist/plugin.d.mts.map +1 -1
- package/dist/plugin.mjs +16 -30
- package/dist/plugin.mjs.map +1 -1
- package/dist/resolver/resolve.cjs +1 -1
- package/dist/resolver/resolve.cjs.map +1 -1
- package/dist/resolver/resolve.mjs +1 -1
- package/dist/resolver/resolve.mjs.map +1 -1
- package/dist/types/config.cjs +3 -1
- package/dist/types/config.cjs.map +1 -1
- package/dist/types/config.d.cts +1 -1
- package/dist/types/config.d.cts.map +1 -1
- package/dist/types/config.d.mts +1 -1
- package/dist/types/config.d.mts.map +1 -1
- package/dist/types/config.mjs +3 -1
- package/dist/types/config.mjs.map +1 -1
- package/dist/types/env.cjs +2 -1
- package/dist/types/env.cjs.map +1 -1
- package/dist/types/env.d.cts +15 -0
- package/dist/types/env.d.cts.map +1 -1
- package/dist/types/env.d.mts +15 -0
- package/dist/types/env.d.mts.map +1 -1
- package/dist/types/env.mjs +2 -1
- package/dist/types/env.mjs.map +1 -1
- package/dist/types/index.cjs +0 -2
- package/dist/types/index.d.cts +1 -2
- package/dist/types/index.d.mts +1 -2
- package/dist/types/index.mjs +1 -2
- package/package.json +49 -35
- package/dist/index.cjs.map +0 -1
- package/dist/index.mjs.map +0 -1
- package/dist/types/runtime.cjs +0 -13
- package/dist/types/runtime.cjs.map +0 -1
- package/dist/types/runtime.d.cts +0 -14
- package/dist/types/runtime.d.cts.map +0 -1
- package/dist/types/runtime.d.mts +0 -14
- package/dist/types/runtime.d.mts.map +0 -1
- package/dist/types/runtime.mjs +0 -11
- package/dist/types/runtime.mjs.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,15 +1,10 @@
|
|
|
1
|
-
Object.
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
const require_types_command = require('./types/command.cjs');
|
|
3
3
|
const require_types_config = require('./types/config.cjs');
|
|
4
4
|
const require_types_context = require('./types/context.cjs');
|
|
5
5
|
const require_types_options = require('./types/options.cjs');
|
|
6
|
-
const require_types_runtime = require('./types/runtime.cjs');
|
|
7
6
|
const require_api = require('./api.cjs');
|
|
8
7
|
|
|
9
|
-
//#region src/index.ts
|
|
10
|
-
var src_default = require_api.ShellShockAPI;
|
|
11
|
-
|
|
12
|
-
//#endregion
|
|
13
8
|
exports.CommandParameterKinds = require_types_command.CommandParameterKinds;
|
|
14
9
|
exports.ShellShockAPI = require_api.ShellShockAPI;
|
|
15
10
|
exports.__ΩAsCommandParameterConfig = require_types_command.__ΩAsCommandParameterConfig;
|
|
@@ -22,7 +17,6 @@ exports.__ΩCommandArgument = require_types_command.__ΩCommandArgument;
|
|
|
22
17
|
exports.__ΩCommandArgumentConfig = require_types_command.__ΩCommandArgumentConfig;
|
|
23
18
|
exports.__ΩCommandBase = require_types_command.__ΩCommandBase;
|
|
24
19
|
exports.__ΩCommandConfig = require_types_command.__ΩCommandConfig;
|
|
25
|
-
exports.__ΩCommandContext = require_types_runtime.__ΩCommandContext;
|
|
26
20
|
exports.__ΩCommandMetadata = require_types_command.__ΩCommandMetadata;
|
|
27
21
|
exports.__ΩCommandModule = require_types_command.__ΩCommandModule;
|
|
28
22
|
exports.__ΩCommandOption = require_types_command.__ΩCommandOption;
|
|
@@ -44,6 +38,4 @@ exports.__ΩStringCommandParameter = require_types_command.__ΩStringCommandPara
|
|
|
44
38
|
exports.__ΩStringCommandParameterConfig = require_types_command.__ΩStringCommandParameterConfig;
|
|
45
39
|
exports.__ΩUnresolvedContext = require_types_context.__ΩUnresolvedContext;
|
|
46
40
|
exports.__ΩUserConfig = require_types_config.__ΩUserConfig;
|
|
47
|
-
exports.createShellShock = require_api.createShellShock;
|
|
48
|
-
exports.default = src_default;
|
|
49
|
-
//# sourceMappingURL=index.cjs.map
|
|
41
|
+
exports.createShellShock = require_api.createShellShock;
|
package/dist/index.d.cts
CHANGED
|
@@ -3,5 +3,4 @@ import { Context, UnresolvedContext } from "./types/context.cjs";
|
|
|
3
3
|
import { Options, OutputConfig, ReferenceOptions, ResolvedConfig, UserConfig } from "./types/config.cjs";
|
|
4
4
|
import { ShellShockAPI, createShellShock } from "./api.cjs";
|
|
5
5
|
import { BaseCommandOptions } from "./types/options.cjs";
|
|
6
|
-
|
|
7
|
-
export { AsCommandParameterConfig, BaseCommandOptions, BaseCommandParameter, BooleanCommandOption, BooleanCommandParameter, BooleanCommandParameterConfig, CommandArgument, CommandArgumentConfig, CommandBase, CommandConfig, CommandContext, CommandMetadata, CommandModule, CommandOption, CommandOptionConfig, CommandParameter, CommandParameterConfig, CommandParameterKind, CommandParameterKinds, CommandParameterType, CommandTree, Context, NumberCommandParameter, NumberCommandParameterConfig, Options, OutputConfig, ReferenceOptions, ResolvedConfig, SerializedCommandTree, ShellShockAPI, ShellShockAPI as default, StringCommandParameter, StringCommandParameterConfig, UnresolvedContext, UserConfig, createShellShock };
|
|
6
|
+
export { AsCommandParameterConfig, BaseCommandOptions, BaseCommandParameter, BooleanCommandOption, BooleanCommandParameter, BooleanCommandParameterConfig, CommandArgument, CommandArgumentConfig, CommandBase, CommandConfig, CommandMetadata, CommandModule, CommandOption, CommandOptionConfig, CommandParameter, CommandParameterConfig, CommandParameterKind, CommandParameterKinds, CommandParameterType, CommandTree, Context, NumberCommandParameter, NumberCommandParameterConfig, Options, OutputConfig, ReferenceOptions, ResolvedConfig, SerializedCommandTree, ShellShockAPI, StringCommandParameter, StringCommandParameterConfig, UnresolvedContext, UserConfig, createShellShock };
|
package/dist/index.d.mts
CHANGED
|
@@ -3,5 +3,4 @@ import { Context, UnresolvedContext } from "./types/context.mjs";
|
|
|
3
3
|
import { Options, OutputConfig, ReferenceOptions, ResolvedConfig, UserConfig } from "./types/config.mjs";
|
|
4
4
|
import { ShellShockAPI, createShellShock } from "./api.mjs";
|
|
5
5
|
import { BaseCommandOptions } from "./types/options.mjs";
|
|
6
|
-
|
|
7
|
-
export { AsCommandParameterConfig, BaseCommandOptions, BaseCommandParameter, BooleanCommandOption, BooleanCommandParameter, BooleanCommandParameterConfig, CommandArgument, CommandArgumentConfig, CommandBase, CommandConfig, CommandContext, CommandMetadata, CommandModule, CommandOption, CommandOptionConfig, CommandParameter, CommandParameterConfig, CommandParameterKind, CommandParameterKinds, CommandParameterType, CommandTree, Context, NumberCommandParameter, NumberCommandParameterConfig, Options, OutputConfig, ReferenceOptions, ResolvedConfig, SerializedCommandTree, ShellShockAPI, ShellShockAPI as default, StringCommandParameter, StringCommandParameterConfig, UnresolvedContext, UserConfig, createShellShock };
|
|
6
|
+
export { AsCommandParameterConfig, BaseCommandOptions, BaseCommandParameter, BooleanCommandOption, BooleanCommandParameter, BooleanCommandParameterConfig, CommandArgument, CommandArgumentConfig, CommandBase, CommandConfig, CommandMetadata, CommandModule, CommandOption, CommandOptionConfig, CommandParameter, CommandParameterConfig, CommandParameterKind, CommandParameterKinds, CommandParameterType, CommandTree, Context, NumberCommandParameter, NumberCommandParameterConfig, Options, OutputConfig, ReferenceOptions, ResolvedConfig, SerializedCommandTree, ShellShockAPI, StringCommandParameter, StringCommandParameterConfig, UnresolvedContext, UserConfig, createShellShock };
|
package/dist/index.mjs
CHANGED
|
@@ -2,12 +2,6 @@ import { CommandParameterKinds, __ΩAsCommandParameterConfig, __ΩBaseCommandPar
|
|
|
2
2
|
import { __ΩOptions, __ΩOutputConfig, __ΩReferenceOptions, __ΩResolvedConfig, __ΩUserConfig } from "./types/config.mjs";
|
|
3
3
|
import { __ΩContext, __ΩUnresolvedContext } from "./types/context.mjs";
|
|
4
4
|
import { __ΩBaseCommandOptions } from "./types/options.mjs";
|
|
5
|
-
import { __ΩCommandContext } from "./types/runtime.mjs";
|
|
6
5
|
import { ShellShockAPI, createShellShock } from "./api.mjs";
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
var src_default = ShellShockAPI;
|
|
10
|
-
|
|
11
|
-
//#endregion
|
|
12
|
-
export { CommandParameterKinds, ShellShockAPI, __ΩAsCommandParameterConfig, __ΩBaseCommandOptions, __ΩBaseCommandParameter, __ΩBooleanCommandOption, __ΩBooleanCommandParameter, __ΩBooleanCommandParameterConfig, __ΩCommandArgument, __ΩCommandArgumentConfig, __ΩCommandBase, __ΩCommandConfig, __ΩCommandContext, __ΩCommandMetadata, __ΩCommandModule, __ΩCommandOption, __ΩCommandOptionConfig, __ΩCommandParameter, __ΩCommandParameterConfig, __ΩCommandParameterKind, __ΩCommandParameterType, __ΩCommandTree, __ΩContext, __ΩNumberCommandParameter, __ΩNumberCommandParameterConfig, __ΩOptions, __ΩOutputConfig, __ΩReferenceOptions, __ΩResolvedConfig, __ΩSerializedCommandTree, __ΩStringCommandParameter, __ΩStringCommandParameterConfig, __ΩUnresolvedContext, __ΩUserConfig, createShellShock, src_default as default };
|
|
13
|
-
//# sourceMappingURL=index.mjs.map
|
|
7
|
+
export { CommandParameterKinds, ShellShockAPI, __ΩAsCommandParameterConfig, __ΩBaseCommandOptions, __ΩBaseCommandParameter, __ΩBooleanCommandOption, __ΩBooleanCommandParameter, __ΩBooleanCommandParameterConfig, __ΩCommandArgument, __ΩCommandArgumentConfig, __ΩCommandBase, __ΩCommandConfig, __ΩCommandMetadata, __ΩCommandModule, __ΩCommandOption, __ΩCommandOptionConfig, __ΩCommandParameter, __ΩCommandParameterConfig, __ΩCommandParameterKind, __ΩCommandParameterType, __ΩCommandTree, __ΩContext, __ΩNumberCommandParameter, __ΩNumberCommandParameterConfig, __ΩOptions, __ΩOutputConfig, __ΩReferenceOptions, __ΩResolvedConfig, __ΩSerializedCommandTree, __ΩStringCommandParameter, __ΩStringCommandParameterConfig, __ΩUnresolvedContext, __ΩUserConfig, createShellShock };
|
package/dist/plugin.cjs
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
|
|
2
2
|
const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
|
|
3
3
|
const require_context_helpers = require('./plugin-utils/context-helpers.cjs');
|
|
4
|
-
const require_types_command = require('./types/command.cjs');
|
|
5
4
|
const require_components_docs = require('./components/docs.cjs');
|
|
6
|
-
const
|
|
5
|
+
const require_components_spawn_builtin = require('./components/spawn-builtin.cjs');
|
|
7
6
|
const require_traverse_command_tree = require('./plugin-utils/traverse-command-tree.cjs');
|
|
8
7
|
const require_get_command_tree = require('./plugin-utils/get-command-tree.cjs');
|
|
8
|
+
const require_components_state_builtin = require('./components/state-builtin.cjs');
|
|
9
|
+
const require_components_utils_builtin = require('./components/utils-builtin.cjs');
|
|
9
10
|
const require_automd = require('./helpers/automd.cjs');
|
|
10
11
|
const require_paths = require('./helpers/paths.cjs');
|
|
11
12
|
const require_persistence = require('./helpers/persistence.cjs');
|
|
@@ -18,10 +19,10 @@ let _alloy_js_core_components = require("@alloy-js/core/components");
|
|
|
18
19
|
let _powerlines_plugin_alloy_render = require("@powerlines/plugin-alloy/render");
|
|
19
20
|
let _powerlines_plugin_automd = require("@powerlines/plugin-automd");
|
|
20
21
|
_powerlines_plugin_automd = require_runtime.__toESM(_powerlines_plugin_automd);
|
|
21
|
-
let _powerlines_plugin_deepkit = require("@powerlines/plugin-deepkit");
|
|
22
|
-
_powerlines_plugin_deepkit = require_runtime.__toESM(_powerlines_plugin_deepkit);
|
|
23
22
|
let _powerlines_plugin_nodejs = require("@powerlines/plugin-nodejs");
|
|
24
23
|
_powerlines_plugin_nodejs = require_runtime.__toESM(_powerlines_plugin_nodejs);
|
|
24
|
+
let _powerlines_plugin_tsdown = require("@powerlines/plugin-tsdown");
|
|
25
|
+
_powerlines_plugin_tsdown = require_runtime.__toESM(_powerlines_plugin_tsdown);
|
|
25
26
|
let _stryke_convert_to_array = require("@stryke/convert/to-array");
|
|
26
27
|
let _stryke_fs_chmod_x = require("@stryke/fs/chmod-x");
|
|
27
28
|
let _stryke_path_append = require("@stryke/path/append");
|
|
@@ -36,7 +37,6 @@ let _stryke_string_format_kebab_case = require("@stryke/string-format/kebab-case
|
|
|
36
37
|
let _stryke_type_checks_is_object = require("@stryke/type-checks/is-object");
|
|
37
38
|
let _stryke_type_checks_is_set_string = require("@stryke/type-checks/is-set-string");
|
|
38
39
|
let defu = require("defu");
|
|
39
|
-
let powerlines_tsdown = require("powerlines/tsdown");
|
|
40
40
|
let powerlines_utils = require("powerlines/utils");
|
|
41
41
|
|
|
42
42
|
//#region src/plugin.tsx
|
|
@@ -46,8 +46,7 @@ const MAX_DEPTH = 50;
|
|
|
46
46
|
*/
|
|
47
47
|
const plugin = (options = {}) => {
|
|
48
48
|
return [
|
|
49
|
-
(0,
|
|
50
|
-
(0, _powerlines_plugin_deepkit.default)(),
|
|
49
|
+
(0, _powerlines_plugin_tsdown.default)(),
|
|
51
50
|
(0, _powerlines_plugin_automd.default)(),
|
|
52
51
|
{
|
|
53
52
|
name: "shell-shock:config",
|
|
@@ -106,6 +105,12 @@ const plugin = (options = {}) => {
|
|
|
106
105
|
alias: [],
|
|
107
106
|
isVirtual: false
|
|
108
107
|
}));
|
|
108
|
+
this.options = this.options.map((option) => ({
|
|
109
|
+
...option,
|
|
110
|
+
name: (0, _stryke_string_format_camel_case.camelCase)(option.name),
|
|
111
|
+
alias: option.alias ?? [],
|
|
112
|
+
optional: option.optional ?? false
|
|
113
|
+
}));
|
|
109
114
|
}
|
|
110
115
|
}
|
|
111
116
|
},
|
|
@@ -156,26 +161,13 @@ const plugin = (options = {}) => {
|
|
|
156
161
|
}, this.inputs);
|
|
157
162
|
this.debug(`Shell Shock will process ${this.inputs.length} command entry files: \n${this.inputs.map((command) => ` - ${command.id}: ${(0, _stryke_path_replace.replacePath)(command.entry.file, this.commandsPath)}`).join("\n")}`);
|
|
158
163
|
},
|
|
159
|
-
types() {
|
|
160
|
-
this.debug("Generating type definitions for the Shell Shock application.");
|
|
161
|
-
return `
|
|
162
|
-
/**
|
|
163
|
-
* The global options available for every command in the ${require_context_helpers.getAppTitle(this, true)} command-line application.
|
|
164
|
-
*/
|
|
165
|
-
export interface GlobalOptions {
|
|
166
|
-
${this.options.map((option) => `${option.description ? `
|
|
167
|
-
/**
|
|
168
|
-
* ${option.description}${option.default ? `
|
|
169
|
-
*
|
|
170
|
-
* @defaultValue ${option.kind === require_types_command.CommandParameterKinds.string ? `"${option.default}"` : option.default}` : ""}
|
|
171
|
-
*/
|
|
172
|
-
` : ""}${option.name}${option.optional ? "?" : ""}: ${option.kind === require_types_command.CommandParameterKinds.boolean ? "boolean" : `${option.variadic ? "(" : ""}${option.choices ? option.choices.map((choice) => option.kind === require_types_command.CommandParameterKinds.number ? `${choice}` : `"${choice}"`).join(" | ") : option.kind === require_types_command.CommandParameterKinds.number ? "number" : "string"}${option.variadic ? ")[]" : ""}`};${option.alias && option.alias.length > 0 ? option.alias.map((alias) => `${alias}${option.optional ? "?" : ""}: ${option.kind === require_types_command.CommandParameterKinds.boolean ? "boolean" : `${option.variadic ? "(" : ""}${option.choices ? option.choices.map((choice) => option.kind === require_types_command.CommandParameterKinds.number ? `${choice}` : `"${choice}"`).join(" | ") : option.kind === require_types_command.CommandParameterKinds.number ? "number" : "string"}${option.variadic ? ")[]" : ""}`};`).join("\n\n") : ""}`).join("\n\n")}
|
|
173
|
-
}
|
|
174
|
-
`;
|
|
175
|
-
},
|
|
176
164
|
async prepare() {
|
|
177
165
|
this.debug("Rendering base built-in modules for the Shell Shock application.");
|
|
178
|
-
return (0, _powerlines_plugin_alloy_render.render)(this, [
|
|
166
|
+
return (0, _powerlines_plugin_alloy_render.render)(this, [
|
|
167
|
+
(0, _alloy_js_core_jsx_runtime.createComponent)(require_components_state_builtin.StateBuiltin, {}),
|
|
168
|
+
(0, _alloy_js_core_jsx_runtime.createComponent)(require_components_utils_builtin.UtilsBuiltin, {}),
|
|
169
|
+
(0, _alloy_js_core_jsx_runtime.createComponent)(require_components_spawn_builtin.SpawnBuiltin, {})
|
|
170
|
+
]);
|
|
179
171
|
}
|
|
180
172
|
},
|
|
181
173
|
{
|
|
@@ -240,12 +232,6 @@ export interface GlobalOptions {
|
|
|
240
232
|
command: input
|
|
241
233
|
});
|
|
242
234
|
this.debug("Post-processing commands to ensure proper reflection.");
|
|
243
|
-
this.options = this.options.map((option) => ({
|
|
244
|
-
...option,
|
|
245
|
-
name: (0, _stryke_string_format_camel_case.camelCase)(option.name),
|
|
246
|
-
alias: option.alias ?? [],
|
|
247
|
-
optional: option.optional ?? false
|
|
248
|
-
}));
|
|
249
235
|
await require_traverse_command_tree.traverseCommands(this, (command) => {
|
|
250
236
|
command.options = Object.fromEntries(Object.entries(command.options).map(([name, option]) => [(0, _stryke_string_format_camel_case.camelCase)(name), {
|
|
251
237
|
...option,
|
|
@@ -322,5 +308,4 @@ export interface GlobalOptions {
|
|
|
322
308
|
//#endregion
|
|
323
309
|
exports.default = plugin;
|
|
324
310
|
exports.plugin = plugin;
|
|
325
|
-
exports.shellShock = plugin;
|
|
326
311
|
//# sourceMappingURL=plugin.cjs.map
|
package/dist/plugin.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.cjs","names":[],"sources":["../src/plugin.tsx"],"sourcesContent":["/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Shell Shock\n\n This code was released as part of the Shell Shock project. Shell Shock\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/shell-shock.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/shell-shock\n Documentation: https://docs.stormsoftware.com/projects/shell-shock\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport { For, Show } from \"@alloy-js/core/components\";\nimport { render } from \"@powerlines/plugin-alloy/render\";\nimport automd from \"@powerlines/plugin-automd\";\nimport deepkit from \"@powerlines/plugin-deepkit\";\nimport nodejs from \"@powerlines/plugin-nodejs\";\nimport { toArray } from \"@stryke/convert/to-array\";\nimport { chmodX } from \"@stryke/fs/chmod-x\";\nimport { appendPath } from \"@stryke/path/append\";\nimport { findFilePath, relativePath } from \"@stryke/path/file-path-fns\";\nimport { isParentPath } from \"@stryke/path/is-parent-path\";\nimport { joinPaths } from \"@stryke/path/join-paths\";\nimport { replacePath } from \"@stryke/path/replace\";\nimport { resolveParentPath } from \"@stryke/path/resolve-parent-path\";\nimport { camelCase } from \"@stryke/string-format/camel-case\";\nimport { constantCase } from \"@stryke/string-format/constant-case\";\nimport { kebabCase } from \"@stryke/string-format/kebab-case\";\nimport { isObject } from \"@stryke/type-checks/is-object\";\nimport { isSetString } from \"@stryke/type-checks/is-set-string\";\nimport { defu } from \"defu\";\nimport type { Plugin } from \"powerlines\";\nimport { tsdown } from \"powerlines/tsdown\";\nimport { resolveInputs } from \"powerlines/utils\";\nimport type { BuildContext, RolldownChunk, TsdownHooks } from \"tsdown\";\nimport { CommandDocsFile } from \"./components/docs\";\nimport { UtilsBuiltin } from \"./components/utils-builtin\";\nimport { commands } from \"./helpers/automd\";\nimport {\n findCommandsRoot,\n resolveCommandId,\n resolveCommandName,\n resolveCommandPath\n} from \"./helpers/paths\";\nimport {\n getCommandsPersistencePath,\n readCommandsPersistence,\n writeCommandsPersistence\n} from \"./helpers/persistence\";\nimport {\n formatBinaryPath,\n updatePackageJsonBinary\n} from \"./helpers/update-package-json\";\nimport { formatCommandTree, getGlobalOptions } from \"./helpers/utilities\";\nimport { validateCommand } from \"./helpers/validations\";\nimport {\n getAppDescription,\n getAppName,\n getAppTitle,\n getDynamicPathSegmentName,\n isDynamicPathSegment,\n isPathSegmentGroup\n} from \"./plugin-utils/context-helpers\";\nimport { getCommandTree } from \"./plugin-utils/get-command-tree\";\nimport { traverseCommands } from \"./plugin-utils/traverse-command-tree\";\nimport { resolve } from \"./resolver/resolve\";\nimport type { CommandOption, CommandTree } from \"./types/command\";\nimport { CommandParameterKinds } from \"./types/command\";\nimport type { Options } from \"./types/config\";\nimport type { Context } from \"./types/context\";\n\nconst MAX_DEPTH = 50;\n\n/**\n * The core Powerlines plugin to build Shell Shock projects.\n */\nexport const plugin = <TContext extends Context = Context>(\n options: Options = {}\n) => {\n return [\n tsdown(),\n deepkit(),\n automd(),\n {\n name: \"shell-shock:config\",\n async config() {\n this.debug(\"Resolving the Shell Shock configuration.\");\n\n await updatePackageJsonBinary(this);\n\n const result = defu(\n {\n output: {\n path: joinPaths(this.config.root, \"dist\")\n }\n },\n options,\n {\n name: getAppName(this),\n title: getAppTitle(this),\n description: getAppDescription(this),\n platform: \"node\",\n projectType: \"application\",\n framework: \"shell-shock\",\n isCaseSensitive: false,\n output: {\n format: \"esm\",\n dts: false\n },\n input:\n !this.config.input ||\n (Array.isArray(this.config.input) &&\n this.config.input.length === 0) ||\n (isObject(this.config.input) &&\n Object.keys(this.config.input).length === 0)\n ? [\n joinPaths(this.config.root, \"src/**/command.ts\"),\n joinPaths(this.config.root, \"src/**/command.tsx\")\n ]\n : undefined,\n resolve: {\n external: [\"@powerlines/deepkit\"],\n skipNodeModulesBundle: true\n },\n tsdown: {\n dts: false,\n nodeProtocol: true,\n unbundle: false\n }\n }\n );\n\n return result;\n },\n configResolved: {\n order: \"pre\",\n async handler() {\n this.debug(\"Shell Shock configuration has been resolved.\");\n\n this.config.appSpecificEnvPrefix = isSetString(\n this.config.autoAssignEnv\n )\n ? this.config.autoAssignEnv\n : constantCase(getAppName(this));\n if (\n !this.config.env.prefix ||\n !Array.isArray(this.config.env.prefix)\n ) {\n this.config.env.prefix = toArray(this.config.env.prefix);\n }\n\n if (\n !this.config.env.prefix.includes(this.config.appSpecificEnvPrefix)\n ) {\n this.config.env.prefix.push(this.config.appSpecificEnvPrefix);\n }\n\n this.config.bin = (isSetString(this.packageJson.bin)\n ? { [kebabCase(this.config.name)]: this.packageJson.bin }\n : this.packageJson.bin) ?? {\n [kebabCase(this.config.name)]: formatBinaryPath(\n this.config.output.format\n )\n };\n\n if (isSetString(this.config.reference)) {\n if (this.config.reference.includes(\"{command}\")) {\n this.config.reference = {\n app: this.config.reference\n .substring(0, this.config.reference.indexOf(\"{command}\"))\n .replace(/\\/?$/, \"/\"),\n commands: this.config.reference\n };\n } else if (this.config.reference.includes(\"{commands}\")) {\n this.config.reference = {\n app: this.config.reference\n .substring(0, this.config.reference.indexOf(\"{commands}\"))\n .replace(/\\/?$/, \"/\"),\n commands: this.config.reference\n };\n } else {\n this.config.reference = {\n app: this.config.reference\n };\n }\n }\n\n this.inputs ??= [];\n this.options = Object.values(\n getGlobalOptions(this, {\n id: null,\n name: this.config.name,\n path: null,\n segments: [],\n title: this.config.title,\n description: this.config.description,\n alias: [],\n isVirtual: false\n })\n );\n }\n }\n },\n ...nodejs<TContext>(\n defu(options ?? {}, {\n env: {\n types: \"@shell-shock/core/types/env#ShellShockEnv\",\n validate: false\n }\n })\n ),\n {\n name: \"shell-shock:inputs\",\n async configResolved() {\n this.debug(\"Finding command entry point files.\");\n\n this.debug(\n `Checking for commands using input: ${JSON.stringify(this.config.input)}`\n );\n\n this.commandsPath = await findCommandsRoot(this);\n this.debug(`Resolved commands root path: ${this.commandsPath}`);\n\n const inputs = await resolveInputs(this, this.config.input);\n\n this.debug(\n `Found ${\n inputs.length\n } entry points specified in the configuration options.`\n );\n\n this.inputs = inputs.reduce((ret, entry) => {\n if (\n entry.file !== this.commandsPath &&\n !isParentPath(entry.file, this.commandsPath)\n ) {\n throw new Error(\n `Command entry point \"${\n entry.file\n }\" is not located within the commands root \"${\n this.commandsPath\n }\". Please ensure that all command entry points are located within the current project.`\n );\n }\n\n const id = resolveCommandId(this, entry.file);\n if (!ret.some(existing => existing.id === id)) {\n const name = resolveCommandName(entry.file);\n let segments = resolveCommandPath(this, entry.file)\n .split(\"/\")\n .filter(Boolean);\n\n // Ensure unique segment names by appending an index suffix to duplicates\n segments = segments.map((segment, index) => {\n const found = segments.findIndex(\n existing => existing === segment\n );\n if (found !== -1 && found !== index) {\n segment += `_${\n segments.filter(\n segment =>\n isDynamicPathSegment(segment) &&\n getDynamicPathSegmentName(segment).replace(\n /_\\d+$/,\n \"\"\n ) === segment\n ).length\n }`;\n }\n\n return segment;\n });\n\n ret.push({\n id,\n path: segments.join(\"/\"),\n segments,\n name,\n alias: [],\n tags: [],\n isVirtual: false,\n entry: {\n ...entry,\n file: entry.file,\n input: {\n file: entry.file,\n name: entry.name\n },\n output: name\n }\n });\n }\n\n return ret;\n }, this.inputs);\n\n this.debug(\n `Shell Shock will process ${\n this.inputs.length\n } command entry files: \\n${this.inputs\n .map(\n command =>\n ` - ${command.id}: ${replacePath(\n command.entry.file,\n this.commandsPath\n )}`\n )\n .join(\"\\n\")}`\n );\n },\n types() {\n this.debug(\n \"Generating type definitions for the Shell Shock application.\"\n );\n\n return `\n/**\n * The global options available for every command in the ${getAppTitle(\n this,\n true\n )} command-line application.\n */\nexport interface GlobalOptions {\n ${this.options\n .map(\n option =>\n `${\n option.description\n ? `\n/**\n * ${option.description}${\n option.default\n ? `\n *\n * @defaultValue ${\n option.kind === CommandParameterKinds.string\n ? `\"${option.default}\"`\n : option.default\n }`\n : \"\"\n }\n */\n`\n : \"\"\n }${option.name}${option.optional ? \"?\" : \"\"}: ${\n option.kind === CommandParameterKinds.boolean\n ? \"boolean\"\n : `${option.variadic ? \"(\" : \"\"}${\n option.choices\n ? option.choices\n .map(choice =>\n option.kind === CommandParameterKinds.number\n ? `${choice}`\n : `\"${choice}\"`\n )\n .join(\" | \")\n : option.kind === CommandParameterKinds.number\n ? \"number\"\n : \"string\"\n }${option.variadic ? \")[]\" : \"\"}`\n };${\n option.alias && option.alias.length > 0\n ? option.alias\n .map(\n alias =>\n `${alias}${option.optional ? \"?\" : \"\"}: ${\n option.kind === CommandParameterKinds.boolean\n ? \"boolean\"\n : `${option.variadic ? \"(\" : \"\"}${\n option.choices\n ? option.choices\n .map(choice =>\n option.kind === CommandParameterKinds.number\n ? `${choice}`\n : `\"${choice}\"`\n )\n .join(\" | \")\n : option.kind === CommandParameterKinds.number\n ? \"number\"\n : \"string\"\n }${option.variadic ? \")[]\" : \"\"}`\n };`\n )\n .join(\"\\n\\n\")\n : \"\"\n }`\n )\n .join(\"\\n\\n\")}\n}\n`;\n },\n async prepare() {\n this.debug(\n \"Rendering base built-in modules for the Shell Shock application.\"\n );\n\n return render(\n this,\n <>\n <UtilsBuiltin />\n </>\n );\n }\n },\n {\n name: \"shell-shock:virtual-inputs\",\n configResolved: {\n order: \"post\",\n async handler() {\n if (this.inputs.length === 0) {\n this.warn(\n \"No commands were found in the project. Please ensure at least one command exists.\"\n );\n } else {\n this.debug(\n `Shell Shock will create an application with the following commands: \\n${this.inputs\n .filter(cmd => !cmd.isVirtual)\n .map(\n command =>\n ` - ${command.id}: ${\n isParentPath(command.entry.file, this.commandsPath)\n ? replacePath(command.entry.file, this.commandsPath)\n : relativePath(command.entry.file, this.commandsPath)\n }${command.isVirtual ? \" (virtual)\" : \"\"}`\n )\n .join(\"\\n\")}`\n );\n\n this.debug(\n \"Finding and adding virtual command inputs for each command previously found.\"\n );\n\n this.inputs = this.inputs\n .reduce((ret, command) => {\n let depth = 0;\n\n let parentPath = resolveParentPath(\n findFilePath(command.entry.file)\n );\n if (isParentPath(parentPath, this.commandsPath)) {\n while (parentPath !== this.commandsPath) {\n if (depth++ > MAX_DEPTH) {\n throw new Error(\n `Unable to process virtual commands for ${command.name} \\n\\nPlease ensure ${command.entry.file} is a valid command entry file and does not have an invalid path.`\n );\n }\n\n if (\n !ret.some(\n existing =>\n findFilePath(existing.entry.file) === parentPath\n )\n ) {\n const file = joinPaths(parentPath, \"command.ts\");\n const id = resolveCommandId(this, file);\n if (!ret.some(existing => existing.id === id)) {\n const name = resolveCommandName(file);\n\n let segments = resolveCommandPath(this, file)\n .split(\"/\")\n .filter(Boolean);\n\n // Ensure unique segment names by appending an index suffix to duplicates\n segments = segments.map((segment, index) => {\n const found = segments.findIndex(\n existing => existing === segment\n );\n if (found !== -1 && found !== index) {\n segment += `_${\n segments.filter(\n segment =>\n isDynamicPathSegment(segment) &&\n getDynamicPathSegmentName(segment).replace(\n /_\\d+$/,\n \"\"\n ) === segment\n ).length\n }`;\n }\n\n return segment;\n });\n\n ret.push({\n id,\n path: segments.join(\"/\"),\n segments,\n name,\n alias: [],\n tags: [],\n isVirtual: true,\n entry: {\n file\n }\n });\n }\n }\n\n parentPath = resolveParentPath(parentPath);\n }\n }\n\n return ret;\n }, this.inputs)\n .sort((a, b) => a.segments.length - b.segments.length);\n\n this.debug(\n `Final command input list: \\n${this.inputs\n .map(\n command =>\n ` - ${command.id}: ${\n isParentPath(command.entry.file, this.commandsPath)\n ? replacePath(command.entry.file, this.commandsPath)\n : replacePath(command.entry.file, this.config.root)\n }${command.isVirtual ? \" (virtual)\" : \"\"}`\n )\n .join(\"\\n\")}`\n );\n }\n }\n }\n },\n {\n name: \"shell-shock:resolve-commands\",\n prepare: {\n order: \"post\",\n async handler() {\n this.debug(\"Initializing the CLI application's command tree.\");\n\n this.commands = {};\n if (\n this.config.command !== \"prepare\" &&\n this.config.skipCache !== true &&\n this.persistedMeta?.checksum === this.meta.checksum &&\n this.fs.existsSync(getCommandsPersistencePath(this))\n ) {\n this.debug(\n `Skipping command resolution as the meta checksum has not changed.`\n );\n\n await readCommandsPersistence(this);\n } else {\n for (const input of this.inputs.filter(\n input =>\n input.segments.filter(\n segment =>\n !isDynamicPathSegment(segment) &&\n !isPathSegmentGroup(segment)\n ).length === 1\n )) {\n this.commands[input.name] = await resolve({\n context: this,\n command: input\n });\n }\n\n this.debug(\"Post-processing commands to ensure proper reflection.\");\n\n this.options = this.options.map(\n option =>\n ({\n ...option,\n name: camelCase(option.name),\n alias: option.alias ?? [],\n optional: option.optional ?? false\n }) as CommandOption\n );\n\n await traverseCommands(this, command => {\n command.options = Object.fromEntries(\n Object.entries(command.options).map(([name, option]) => [\n camelCase(name),\n {\n ...option,\n name: camelCase(name),\n alias: option.alias ?? [],\n optional: option.optional ?? false\n } as CommandOption\n ])\n );\n });\n\n await writeCommandsPersistence(this);\n }\n\n this.debug(\"Validating the CLI applications command tree.\");\n\n let isValid = true;\n await traverseCommands(this, command => {\n const failures = validateCommand(command);\n if (failures.length > 0) {\n this.error(\n `Found ${failures.length} issue${failures.length > 1 ? \"s\" : \"\"} with the ${\n command.title\n } command: \\n${failures\n .map(failure => ` - ${failure.code}: ${failure.details}`)\n .join(\"\\n\")}\\n`\n );\n isValid = false;\n }\n });\n if (!isValid) {\n throw new Error(\n `One or more commands in the command tree are invalid. Please review the errors above and correct them before proceeding.`\n );\n }\n\n this.info(\n `\\nCreating an application with the following command tree: \\n${formatCommandTree(\n this\n )}\\n`\n );\n }\n }\n },\n {\n name: \"shell-shock:chmod+x\",\n configResolved() {\n this.config.tsdown.hooks ??= {} as TsdownHooks;\n (this.config.tsdown.hooks as TsdownHooks)[\"build:done\"] = async (\n _: BuildContext & {\n chunks: RolldownChunk[];\n }\n ) => {\n await Promise.all(\n Object.values(this.config.bin).map(async bin => {\n const path = appendPath(\n bin,\n joinPaths(this.workspaceConfig.workspaceRoot, this.config.root)\n );\n if (this.fs.existsSync(path)) {\n this.debug(\n `Adding hashbang to binary executable output file: ${path}`\n );\n\n const content = await this.fs.read(path);\n if (content && !content.startsWith(\"#!\")) {\n await this.fs.write(\n path,\n `#!/usr/bin/env ${\n this.config.mode === \"development\"\n ? \"-S NODE_OPTIONS=--enable-source-maps\"\n : \"\"\n } node\\n\\n${content}`\n );\n }\n\n this.debug(\n `Adding executable permissions (chmod+x) to binary executable output file: ${\n path\n }`\n );\n\n await chmodX(path);\n } else {\n this.warn(\n `Expected binary output file not found at path: ${\n path\n }. Skipping adding hashbang and executable permissions (chmod+x).`\n );\n }\n })\n );\n };\n }\n },\n {\n name: \"shell-shock:docs\",\n configResolved() {\n this.config.automd ??= {};\n this.config.automd.generators = {\n ...(this.config.automd.generators ?? {}),\n commands: commands(this)\n };\n },\n async docs() {\n this.debug(\n \"Rendering entrypoint modules for the Shell Shock `script` preset.\"\n );\n\n const commands = this.inputs\n .map(input => getCommandTree(this, input.segments))\n .filter(Boolean) as CommandTree[];\n\n return render(\n this,\n <For each={Object.values(commands)} doubleHardline>\n {child => (\n <Show when={!child.isVirtual}>\n <CommandDocsFile command={child} />\n </Show>\n )}\n </For>\n );\n }\n }\n ] as Plugin<TContext>[];\n};\n\nexport { plugin as shellShock };\nexport default plugin;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"plugin.cjs","names":[],"sources":["../src/plugin.tsx"],"sourcesContent":["/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Shell Shock\n\n This code was released as part of the Shell Shock project. Shell Shock\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/shell-shock.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/shell-shock\n Documentation: https://docs.stormsoftware.com/projects/shell-shock\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport { For, Show } from \"@alloy-js/core/components\";\nimport { render } from \"@powerlines/plugin-alloy/render\";\nimport automd from \"@powerlines/plugin-automd\";\nimport nodejs from \"@powerlines/plugin-nodejs\";\nimport tsdown from \"@powerlines/plugin-tsdown\";\nimport { toArray } from \"@stryke/convert/to-array\";\nimport { chmodX } from \"@stryke/fs/chmod-x\";\nimport { appendPath } from \"@stryke/path/append\";\nimport { findFilePath, relativePath } from \"@stryke/path/file-path-fns\";\nimport { isParentPath } from \"@stryke/path/is-parent-path\";\nimport { joinPaths } from \"@stryke/path/join-paths\";\nimport { replacePath } from \"@stryke/path/replace\";\nimport { resolveParentPath } from \"@stryke/path/resolve-parent-path\";\nimport { camelCase } from \"@stryke/string-format/camel-case\";\nimport { constantCase } from \"@stryke/string-format/constant-case\";\nimport { kebabCase } from \"@stryke/string-format/kebab-case\";\nimport { isObject } from \"@stryke/type-checks/is-object\";\nimport { isSetString } from \"@stryke/type-checks/is-set-string\";\nimport { defu } from \"defu\";\nimport type { Plugin } from \"powerlines\";\nimport { resolveInputs } from \"powerlines/utils\";\nimport type { BuildContext, RolldownChunk, TsdownHooks } from \"tsdown\";\nimport { CommandDocsFile } from \"./components/docs\";\nimport { SpawnBuiltin } from \"./components/spawn-builtin\";\nimport { StateBuiltin } from \"./components/state-builtin\";\nimport { UtilsBuiltin } from \"./components/utils-builtin\";\nimport { commands } from \"./helpers/automd\";\nimport {\n findCommandsRoot,\n resolveCommandId,\n resolveCommandName,\n resolveCommandPath\n} from \"./helpers/paths\";\nimport {\n getCommandsPersistencePath,\n readCommandsPersistence,\n writeCommandsPersistence\n} from \"./helpers/persistence\";\nimport {\n formatBinaryPath,\n updatePackageJsonBinary\n} from \"./helpers/update-package-json\";\nimport { formatCommandTree, getGlobalOptions } from \"./helpers/utilities\";\nimport { validateCommand } from \"./helpers/validations\";\nimport {\n getAppDescription,\n getAppName,\n getAppTitle,\n getDynamicPathSegmentName,\n isDynamicPathSegment,\n isPathSegmentGroup\n} from \"./plugin-utils/context-helpers\";\nimport { getCommandTree } from \"./plugin-utils/get-command-tree\";\nimport { traverseCommands } from \"./plugin-utils/traverse-command-tree\";\nimport { resolve } from \"./resolver/resolve\";\nimport type { CommandOption, CommandTree } from \"./types/command\";\nimport type { Options } from \"./types/config\";\nimport type { Context } from \"./types/context\";\n\nconst MAX_DEPTH = 50;\n\n/**\n * The core Powerlines plugin to build Shell Shock projects.\n */\nexport const plugin = <TContext extends Context = Context>(\n options: Options = {}\n): Plugin<TContext>[] => {\n return [\n tsdown<TContext>(),\n automd<TContext>(),\n {\n name: \"shell-shock:config\",\n async config() {\n this.debug(\"Resolving the Shell Shock configuration.\");\n\n await updatePackageJsonBinary(this);\n\n const result = defu(\n {\n output: {\n path: joinPaths(this.config.root, \"dist\")\n }\n },\n options,\n {\n name: getAppName(this),\n title: getAppTitle(this),\n description: getAppDescription(this),\n platform: \"node\",\n projectType: \"application\",\n framework: \"shell-shock\",\n isCaseSensitive: false,\n output: {\n format: \"esm\",\n dts: false\n },\n input:\n !this.config.input ||\n (Array.isArray(this.config.input) &&\n this.config.input.length === 0) ||\n (isObject(this.config.input) &&\n Object.keys(this.config.input).length === 0)\n ? [\n joinPaths(this.config.root, \"src/**/command.ts\"),\n joinPaths(this.config.root, \"src/**/command.tsx\")\n ]\n : undefined,\n resolve: {\n external: [\"@powerlines/deepkit\"],\n skipNodeModulesBundle: true\n },\n tsdown: {\n dts: false,\n nodeProtocol: true,\n unbundle: false\n }\n }\n );\n\n return result;\n },\n configResolved: {\n order: \"pre\",\n async handler() {\n this.debug(\"Shell Shock configuration has been resolved.\");\n\n this.config.appSpecificEnvPrefix = isSetString(\n this.config.autoAssignEnv\n )\n ? this.config.autoAssignEnv\n : constantCase(getAppName(this));\n if (\n !this.config.env.prefix ||\n !Array.isArray(this.config.env.prefix)\n ) {\n this.config.env.prefix = toArray(this.config.env.prefix);\n }\n\n if (\n !this.config.env.prefix.includes(this.config.appSpecificEnvPrefix)\n ) {\n this.config.env.prefix.push(this.config.appSpecificEnvPrefix);\n }\n\n this.config.bin = (isSetString(this.packageJson.bin)\n ? { [kebabCase(this.config.name)]: this.packageJson.bin }\n : this.packageJson.bin) ?? {\n [kebabCase(this.config.name)]: formatBinaryPath(\n this.config.output.format\n )\n };\n\n if (isSetString(this.config.reference)) {\n if (this.config.reference.includes(\"{command}\")) {\n this.config.reference = {\n app: this.config.reference\n .substring(0, this.config.reference.indexOf(\"{command}\"))\n .replace(/\\/?$/, \"/\"),\n commands: this.config.reference\n };\n } else if (this.config.reference.includes(\"{commands}\")) {\n this.config.reference = {\n app: this.config.reference\n .substring(0, this.config.reference.indexOf(\"{commands}\"))\n .replace(/\\/?$/, \"/\"),\n commands: this.config.reference\n };\n } else {\n this.config.reference = {\n app: this.config.reference\n };\n }\n }\n\n this.inputs ??= [];\n this.options = Object.values(\n getGlobalOptions(this, {\n id: null,\n name: this.config.name,\n path: null,\n segments: [],\n title: this.config.title,\n description: this.config.description,\n alias: [],\n isVirtual: false\n })\n );\n\n this.options = this.options.map(\n option =>\n ({\n ...option,\n name: camelCase(option.name),\n alias: option.alias ?? [],\n optional: option.optional ?? false\n }) as CommandOption\n );\n }\n }\n },\n ...nodejs<TContext>(\n defu(options ?? {}, {\n env: {\n types: \"@shell-shock/core/types/env#ShellShockEnv\",\n validate: false\n }\n })\n ),\n {\n name: \"shell-shock:inputs\",\n async configResolved() {\n this.debug(\"Finding command entry point files.\");\n\n this.debug(\n `Checking for commands using input: ${JSON.stringify(this.config.input)}`\n );\n\n this.commandsPath = await findCommandsRoot(this);\n this.debug(`Resolved commands root path: ${this.commandsPath}`);\n\n const inputs = await resolveInputs(this, this.config.input);\n\n this.debug(\n `Found ${\n inputs.length\n } entry points specified in the configuration options.`\n );\n\n this.inputs = inputs.reduce((ret, entry) => {\n if (\n entry.file !== this.commandsPath &&\n !isParentPath(entry.file, this.commandsPath)\n ) {\n throw new Error(\n `Command entry point \"${\n entry.file\n }\" is not located within the commands root \"${\n this.commandsPath\n }\". Please ensure that all command entry points are located within the current project.`\n );\n }\n\n const id = resolveCommandId(this, entry.file);\n if (!ret.some(existing => existing.id === id)) {\n const name = resolveCommandName(entry.file);\n let segments = resolveCommandPath(this, entry.file)\n .split(\"/\")\n .filter(Boolean);\n\n // Ensure unique segment names by appending an index suffix to duplicates\n segments = segments.map((segment, index) => {\n const found = segments.findIndex(\n existing => existing === segment\n );\n if (found !== -1 && found !== index) {\n segment += `_${\n segments.filter(\n segment =>\n isDynamicPathSegment(segment) &&\n getDynamicPathSegmentName(segment).replace(\n /_\\d+$/,\n \"\"\n ) === segment\n ).length\n }`;\n }\n\n return segment;\n });\n\n ret.push({\n id,\n path: segments.join(\"/\"),\n segments,\n name,\n alias: [],\n tags: [],\n isVirtual: false,\n entry: {\n ...entry,\n file: entry.file,\n input: {\n file: entry.file,\n name: entry.name\n },\n output: name\n }\n });\n }\n\n return ret;\n }, this.inputs);\n\n this.debug(\n `Shell Shock will process ${\n this.inputs.length\n } command entry files: \\n${this.inputs\n .map(\n command =>\n ` - ${command.id}: ${replacePath(\n command.entry.file,\n this.commandsPath\n )}`\n )\n .join(\"\\n\")}`\n );\n },\n async prepare() {\n this.debug(\n \"Rendering base built-in modules for the Shell Shock application.\"\n );\n\n return render(\n this,\n <>\n <StateBuiltin />\n <UtilsBuiltin />\n <SpawnBuiltin />\n </>\n );\n }\n },\n {\n name: \"shell-shock:virtual-inputs\",\n configResolved: {\n order: \"post\",\n async handler() {\n if (this.inputs.length === 0) {\n this.warn(\n \"No commands were found in the project. Please ensure at least one command exists.\"\n );\n } else {\n this.debug(\n `Shell Shock will create an application with the following commands: \\n${this.inputs\n .filter(cmd => !cmd.isVirtual)\n .map(\n command =>\n ` - ${command.id}: ${\n isParentPath(command.entry.file, this.commandsPath)\n ? replacePath(command.entry.file, this.commandsPath)\n : relativePath(command.entry.file, this.commandsPath)\n }${command.isVirtual ? \" (virtual)\" : \"\"}`\n )\n .join(\"\\n\")}`\n );\n\n this.debug(\n \"Finding and adding virtual command inputs for each command previously found.\"\n );\n\n this.inputs = this.inputs\n .reduce((ret, command) => {\n let depth = 0;\n\n let parentPath = resolveParentPath(\n findFilePath(command.entry.file)\n );\n if (isParentPath(parentPath, this.commandsPath)) {\n while (parentPath !== this.commandsPath) {\n if (depth++ > MAX_DEPTH) {\n throw new Error(\n `Unable to process virtual commands for ${\n command.name\n } \\n\\nPlease ensure ${\n command.entry.file\n } is a valid command entry file and does not have an invalid path.`\n );\n }\n\n if (\n !ret.some(\n existing =>\n findFilePath(existing.entry.file) === parentPath\n )\n ) {\n const file = joinPaths(parentPath, \"command.ts\");\n const id = resolveCommandId(this, file);\n if (!ret.some(existing => existing.id === id)) {\n const name = resolveCommandName(file);\n\n let segments = resolveCommandPath(this, file)\n .split(\"/\")\n .filter(Boolean);\n\n // Ensure unique segment names by appending an index suffix to duplicates\n segments = segments.map((segment, index) => {\n const found = segments.findIndex(\n existing => existing === segment\n );\n if (found !== -1 && found !== index) {\n segment += `_${\n segments.filter(\n segment =>\n isDynamicPathSegment(segment) &&\n getDynamicPathSegmentName(segment).replace(\n /_\\d+$/,\n \"\"\n ) === segment\n ).length\n }`;\n }\n\n return segment;\n });\n\n ret.push({\n id,\n path: segments.join(\"/\"),\n segments,\n name,\n alias: [],\n tags: [],\n isVirtual: true,\n entry: {\n file\n }\n });\n }\n }\n\n parentPath = resolveParentPath(parentPath);\n }\n }\n\n return ret;\n }, this.inputs)\n .sort((a, b) => a.segments.length - b.segments.length);\n\n this.debug(\n `Final command input list: \\n${this.inputs\n .map(\n command =>\n ` - ${command.id}: ${\n isParentPath(command.entry.file, this.commandsPath)\n ? replacePath(command.entry.file, this.commandsPath)\n : replacePath(command.entry.file, this.config.root)\n }${command.isVirtual ? \" (virtual)\" : \"\"}`\n )\n .join(\"\\n\")}`\n );\n }\n }\n }\n },\n {\n name: \"shell-shock:resolve-commands\",\n prepare: {\n order: \"post\",\n async handler() {\n this.debug(\"Initializing the CLI application's command tree.\");\n\n this.commands = {};\n if (\n this.config.command !== \"prepare\" &&\n this.config.skipCache !== true &&\n this.persistedMeta?.checksum === this.meta.checksum &&\n this.fs.existsSync(getCommandsPersistencePath(this))\n ) {\n this.debug(\n `Skipping command resolution as the meta checksum has not changed.`\n );\n\n await readCommandsPersistence(this);\n } else {\n for (const input of this.inputs.filter(\n input =>\n input.segments.filter(\n segment =>\n !isDynamicPathSegment(segment) &&\n !isPathSegmentGroup(segment)\n ).length === 1\n )) {\n this.commands[input.name] = await resolve({\n context: this,\n command: input\n });\n }\n\n this.debug(\"Post-processing commands to ensure proper reflection.\");\n\n await traverseCommands(this, command => {\n command.options = Object.fromEntries(\n Object.entries(command.options).map(([name, option]) => [\n camelCase(name),\n {\n ...option,\n name: camelCase(name),\n alias: option.alias ?? [],\n optional: option.optional ?? false\n } as CommandOption\n ])\n );\n });\n\n await writeCommandsPersistence(this);\n }\n\n this.debug(\"Validating the CLI applications command tree.\");\n\n let isValid = true;\n await traverseCommands(this, command => {\n const failures = validateCommand(command);\n if (failures.length > 0) {\n this.error(\n `Found ${failures.length} issue${failures.length > 1 ? \"s\" : \"\"} with the ${\n command.title\n } command: \\n${failures\n .map(failure => ` - ${failure.code}: ${failure.details}`)\n .join(\"\\n\")}\\n`\n );\n isValid = false;\n }\n });\n if (!isValid) {\n throw new Error(\n `One or more commands in the command tree are invalid. Please review the errors above and correct them before proceeding.`\n );\n }\n\n this.info(\n `\\nCreating an application with the following command tree: \\n${formatCommandTree(\n this\n )}\\n`\n );\n }\n }\n },\n {\n name: \"shell-shock:chmod+x\",\n configResolved() {\n this.config.tsdown.hooks ??= {} as TsdownHooks;\n (this.config.tsdown.hooks as TsdownHooks)[\"build:done\"] = async (\n _: BuildContext & {\n chunks: RolldownChunk[];\n }\n ) => {\n await Promise.all(\n Object.values(this.config.bin).map(async bin => {\n const path = appendPath(\n bin,\n joinPaths(this.workspaceConfig.workspaceRoot, this.config.root)\n );\n if (this.fs.existsSync(path)) {\n this.debug(\n `Adding hashbang to binary executable output file: ${path}`\n );\n\n const content = await this.fs.read(path);\n if (content && !content.startsWith(\"#!\")) {\n await this.fs.write(\n path,\n `#!/usr/bin/env ${\n this.config.mode === \"development\"\n ? \"-S NODE_OPTIONS=--enable-source-maps\"\n : \"\"\n } node\\n\\n${content}`\n );\n }\n\n this.debug(\n `Adding executable permissions (chmod+x) to binary executable output file: ${\n path\n }`\n );\n\n await chmodX(path);\n } else {\n this.warn(\n `Expected binary output file not found at path: ${\n path\n }. Skipping adding hashbang and executable permissions (chmod+x).`\n );\n }\n })\n );\n };\n }\n },\n {\n name: \"shell-shock:docs\",\n configResolved() {\n this.config.automd ??= {};\n this.config.automd.generators = {\n ...(this.config.automd.generators ?? {}),\n commands: commands(this)\n };\n },\n async docs() {\n this.debug(\n \"Rendering entrypoint modules for the Shell Shock `script` preset.\"\n );\n\n const commands = this.inputs\n .map(input => getCommandTree(this, input.segments))\n .filter(Boolean) as CommandTree[];\n\n return render(\n this,\n <For each={Object.values(commands)} doubleHardline>\n {child => (\n <Show when={!child.isVirtual}>\n <CommandDocsFile command={child} />\n </Show>\n )}\n </For>\n );\n }\n }\n ];\n};\n\nexport default plugin;\n"],"mappings":"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"}
|
package/dist/plugin.d.cts
CHANGED
|
@@ -8,5 +8,5 @@ import { Plugin } from "powerlines";
|
|
|
8
8
|
*/
|
|
9
9
|
declare const plugin: <TContext extends Context = Context>(options?: Options) => Plugin<TContext>[];
|
|
10
10
|
//#endregion
|
|
11
|
-
export { plugin as default, plugin
|
|
11
|
+
export { plugin as default, plugin };
|
|
12
12
|
//# sourceMappingURL=plugin.d.cts.map
|
package/dist/plugin.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.cts","names":[],"sources":["../src/plugin.tsx"],"mappings":";;;;;;;AAkFA;cAAa,MAAA,oBAA2B,OAAA,GAAU,OAAA,EAChD,OAAA,GAAS,OAAA,
|
|
1
|
+
{"version":3,"file":"plugin.d.cts","names":[],"sources":["../src/plugin.tsx"],"mappings":";;;;;;;AAkFA;cAAa,MAAA,oBAA2B,OAAA,GAAU,OAAA,EAChD,OAAA,GAAS,OAAA,KACR,MAAA,CAAO,QAAA"}
|
package/dist/plugin.d.mts
CHANGED
|
@@ -8,5 +8,5 @@ import { Plugin } from "powerlines";
|
|
|
8
8
|
*/
|
|
9
9
|
declare const plugin: <TContext extends Context = Context>(options?: Options) => Plugin<TContext>[];
|
|
10
10
|
//#endregion
|
|
11
|
-
export { plugin as default, plugin
|
|
11
|
+
export { plugin as default, plugin };
|
|
12
12
|
//# sourceMappingURL=plugin.d.mts.map
|
package/dist/plugin.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.mts","names":[],"sources":["../src/plugin.tsx"],"mappings":";;;;;;;AAkFA;cAAa,MAAA,oBAA2B,OAAA,GAAU,OAAA,EAChD,OAAA,GAAS,OAAA,
|
|
1
|
+
{"version":3,"file":"plugin.d.mts","names":[],"sources":["../src/plugin.tsx"],"mappings":";;;;;;;AAkFA;cAAa,MAAA,oBAA2B,OAAA,GAAU,OAAA,EAChD,OAAA,GAAS,OAAA,KACR,MAAA,CAAO,QAAA"}
|
package/dist/plugin.mjs
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { getAppDescription, getAppName, getAppTitle, getDynamicPathSegmentName, isDynamicPathSegment, isPathSegmentGroup } from "./plugin-utils/context-helpers.mjs";
|
|
2
|
-
import { CommandParameterKinds } from "./types/command.mjs";
|
|
3
2
|
import { CommandDocsFile } from "./components/docs.mjs";
|
|
4
|
-
import {
|
|
3
|
+
import { SpawnBuiltin } from "./components/spawn-builtin.mjs";
|
|
5
4
|
import { traverseCommands } from "./plugin-utils/traverse-command-tree.mjs";
|
|
6
5
|
import { getCommandTree } from "./plugin-utils/get-command-tree.mjs";
|
|
6
|
+
import { StateBuiltin } from "./components/state-builtin.mjs";
|
|
7
|
+
import { UtilsBuiltin } from "./components/utils-builtin.mjs";
|
|
7
8
|
import { commands } from "./helpers/automd.mjs";
|
|
8
9
|
import { findCommandsRoot, resolveCommandId, resolveCommandName, resolveCommandPath } from "./helpers/paths.mjs";
|
|
9
10
|
import { getCommandsPersistencePath, readCommandsPersistence, writeCommandsPersistence } from "./helpers/persistence.mjs";
|
|
@@ -15,8 +16,8 @@ import { createComponent } from "@alloy-js/core/jsx-runtime";
|
|
|
15
16
|
import { For, Show } from "@alloy-js/core/components";
|
|
16
17
|
import { render } from "@powerlines/plugin-alloy/render";
|
|
17
18
|
import automd from "@powerlines/plugin-automd";
|
|
18
|
-
import deepkit from "@powerlines/plugin-deepkit";
|
|
19
19
|
import nodejs from "@powerlines/plugin-nodejs";
|
|
20
|
+
import tsdown from "@powerlines/plugin-tsdown";
|
|
20
21
|
import { toArray } from "@stryke/convert/to-array";
|
|
21
22
|
import { chmodX } from "@stryke/fs/chmod-x";
|
|
22
23
|
import { appendPath } from "@stryke/path/append";
|
|
@@ -31,7 +32,6 @@ import { kebabCase } from "@stryke/string-format/kebab-case";
|
|
|
31
32
|
import { isObject } from "@stryke/type-checks/is-object";
|
|
32
33
|
import { isSetString } from "@stryke/type-checks/is-set-string";
|
|
33
34
|
import { defu } from "defu";
|
|
34
|
-
import { tsdown } from "powerlines/tsdown";
|
|
35
35
|
import { resolveInputs } from "powerlines/utils";
|
|
36
36
|
|
|
37
37
|
//#region src/plugin.tsx
|
|
@@ -42,7 +42,6 @@ const MAX_DEPTH = 50;
|
|
|
42
42
|
const plugin = (options = {}) => {
|
|
43
43
|
return [
|
|
44
44
|
tsdown(),
|
|
45
|
-
deepkit(),
|
|
46
45
|
automd(),
|
|
47
46
|
{
|
|
48
47
|
name: "shell-shock:config",
|
|
@@ -101,6 +100,12 @@ const plugin = (options = {}) => {
|
|
|
101
100
|
alias: [],
|
|
102
101
|
isVirtual: false
|
|
103
102
|
}));
|
|
103
|
+
this.options = this.options.map((option) => ({
|
|
104
|
+
...option,
|
|
105
|
+
name: camelCase(option.name),
|
|
106
|
+
alias: option.alias ?? [],
|
|
107
|
+
optional: option.optional ?? false
|
|
108
|
+
}));
|
|
104
109
|
}
|
|
105
110
|
}
|
|
106
111
|
},
|
|
@@ -151,26 +156,13 @@ const plugin = (options = {}) => {
|
|
|
151
156
|
}, this.inputs);
|
|
152
157
|
this.debug(`Shell Shock will process ${this.inputs.length} command entry files: \n${this.inputs.map((command) => ` - ${command.id}: ${replacePath(command.entry.file, this.commandsPath)}`).join("\n")}`);
|
|
153
158
|
},
|
|
154
|
-
types() {
|
|
155
|
-
this.debug("Generating type definitions for the Shell Shock application.");
|
|
156
|
-
return `
|
|
157
|
-
/**
|
|
158
|
-
* The global options available for every command in the ${getAppTitle(this, true)} command-line application.
|
|
159
|
-
*/
|
|
160
|
-
export interface GlobalOptions {
|
|
161
|
-
${this.options.map((option) => `${option.description ? `
|
|
162
|
-
/**
|
|
163
|
-
* ${option.description}${option.default ? `
|
|
164
|
-
*
|
|
165
|
-
* @defaultValue ${option.kind === CommandParameterKinds.string ? `"${option.default}"` : option.default}` : ""}
|
|
166
|
-
*/
|
|
167
|
-
` : ""}${option.name}${option.optional ? "?" : ""}: ${option.kind === CommandParameterKinds.boolean ? "boolean" : `${option.variadic ? "(" : ""}${option.choices ? option.choices.map((choice) => option.kind === CommandParameterKinds.number ? `${choice}` : `"${choice}"`).join(" | ") : option.kind === CommandParameterKinds.number ? "number" : "string"}${option.variadic ? ")[]" : ""}`};${option.alias && option.alias.length > 0 ? option.alias.map((alias) => `${alias}${option.optional ? "?" : ""}: ${option.kind === CommandParameterKinds.boolean ? "boolean" : `${option.variadic ? "(" : ""}${option.choices ? option.choices.map((choice) => option.kind === CommandParameterKinds.number ? `${choice}` : `"${choice}"`).join(" | ") : option.kind === CommandParameterKinds.number ? "number" : "string"}${option.variadic ? ")[]" : ""}`};`).join("\n\n") : ""}`).join("\n\n")}
|
|
168
|
-
}
|
|
169
|
-
`;
|
|
170
|
-
},
|
|
171
159
|
async prepare() {
|
|
172
160
|
this.debug("Rendering base built-in modules for the Shell Shock application.");
|
|
173
|
-
return render(this, [
|
|
161
|
+
return render(this, [
|
|
162
|
+
createComponent(StateBuiltin, {}),
|
|
163
|
+
createComponent(UtilsBuiltin, {}),
|
|
164
|
+
createComponent(SpawnBuiltin, {})
|
|
165
|
+
]);
|
|
174
166
|
}
|
|
175
167
|
},
|
|
176
168
|
{
|
|
@@ -235,12 +227,6 @@ export interface GlobalOptions {
|
|
|
235
227
|
command: input
|
|
236
228
|
});
|
|
237
229
|
this.debug("Post-processing commands to ensure proper reflection.");
|
|
238
|
-
this.options = this.options.map((option) => ({
|
|
239
|
-
...option,
|
|
240
|
-
name: camelCase(option.name),
|
|
241
|
-
alias: option.alias ?? [],
|
|
242
|
-
optional: option.optional ?? false
|
|
243
|
-
}));
|
|
244
230
|
await traverseCommands(this, (command) => {
|
|
245
231
|
command.options = Object.fromEntries(Object.entries(command.options).map(([name, option]) => [camelCase(name), {
|
|
246
232
|
...option,
|
|
@@ -315,5 +301,5 @@ export interface GlobalOptions {
|
|
|
315
301
|
};
|
|
316
302
|
|
|
317
303
|
//#endregion
|
|
318
|
-
export { plugin as default, plugin
|
|
304
|
+
export { plugin as default, plugin };
|
|
319
305
|
//# sourceMappingURL=plugin.mjs.map
|
package/dist/plugin.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.mjs","names":[],"sources":["../src/plugin.tsx"],"sourcesContent":["/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Shell Shock\n\n This code was released as part of the Shell Shock project. Shell Shock\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/shell-shock.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/shell-shock\n Documentation: https://docs.stormsoftware.com/projects/shell-shock\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport { For, Show } from \"@alloy-js/core/components\";\nimport { render } from \"@powerlines/plugin-alloy/render\";\nimport automd from \"@powerlines/plugin-automd\";\nimport deepkit from \"@powerlines/plugin-deepkit\";\nimport nodejs from \"@powerlines/plugin-nodejs\";\nimport { toArray } from \"@stryke/convert/to-array\";\nimport { chmodX } from \"@stryke/fs/chmod-x\";\nimport { appendPath } from \"@stryke/path/append\";\nimport { findFilePath, relativePath } from \"@stryke/path/file-path-fns\";\nimport { isParentPath } from \"@stryke/path/is-parent-path\";\nimport { joinPaths } from \"@stryke/path/join-paths\";\nimport { replacePath } from \"@stryke/path/replace\";\nimport { resolveParentPath } from \"@stryke/path/resolve-parent-path\";\nimport { camelCase } from \"@stryke/string-format/camel-case\";\nimport { constantCase } from \"@stryke/string-format/constant-case\";\nimport { kebabCase } from \"@stryke/string-format/kebab-case\";\nimport { isObject } from \"@stryke/type-checks/is-object\";\nimport { isSetString } from \"@stryke/type-checks/is-set-string\";\nimport { defu } from \"defu\";\nimport type { Plugin } from \"powerlines\";\nimport { tsdown } from \"powerlines/tsdown\";\nimport { resolveInputs } from \"powerlines/utils\";\nimport type { BuildContext, RolldownChunk, TsdownHooks } from \"tsdown\";\nimport { CommandDocsFile } from \"./components/docs\";\nimport { UtilsBuiltin } from \"./components/utils-builtin\";\nimport { commands } from \"./helpers/automd\";\nimport {\n findCommandsRoot,\n resolveCommandId,\n resolveCommandName,\n resolveCommandPath\n} from \"./helpers/paths\";\nimport {\n getCommandsPersistencePath,\n readCommandsPersistence,\n writeCommandsPersistence\n} from \"./helpers/persistence\";\nimport {\n formatBinaryPath,\n updatePackageJsonBinary\n} from \"./helpers/update-package-json\";\nimport { formatCommandTree, getGlobalOptions } from \"./helpers/utilities\";\nimport { validateCommand } from \"./helpers/validations\";\nimport {\n getAppDescription,\n getAppName,\n getAppTitle,\n getDynamicPathSegmentName,\n isDynamicPathSegment,\n isPathSegmentGroup\n} from \"./plugin-utils/context-helpers\";\nimport { getCommandTree } from \"./plugin-utils/get-command-tree\";\nimport { traverseCommands } from \"./plugin-utils/traverse-command-tree\";\nimport { resolve } from \"./resolver/resolve\";\nimport type { CommandOption, CommandTree } from \"./types/command\";\nimport { CommandParameterKinds } from \"./types/command\";\nimport type { Options } from \"./types/config\";\nimport type { Context } from \"./types/context\";\n\nconst MAX_DEPTH = 50;\n\n/**\n * The core Powerlines plugin to build Shell Shock projects.\n */\nexport const plugin = <TContext extends Context = Context>(\n options: Options = {}\n) => {\n return [\n tsdown(),\n deepkit(),\n automd(),\n {\n name: \"shell-shock:config\",\n async config() {\n this.debug(\"Resolving the Shell Shock configuration.\");\n\n await updatePackageJsonBinary(this);\n\n const result = defu(\n {\n output: {\n path: joinPaths(this.config.root, \"dist\")\n }\n },\n options,\n {\n name: getAppName(this),\n title: getAppTitle(this),\n description: getAppDescription(this),\n platform: \"node\",\n projectType: \"application\",\n framework: \"shell-shock\",\n isCaseSensitive: false,\n output: {\n format: \"esm\",\n dts: false\n },\n input:\n !this.config.input ||\n (Array.isArray(this.config.input) &&\n this.config.input.length === 0) ||\n (isObject(this.config.input) &&\n Object.keys(this.config.input).length === 0)\n ? [\n joinPaths(this.config.root, \"src/**/command.ts\"),\n joinPaths(this.config.root, \"src/**/command.tsx\")\n ]\n : undefined,\n resolve: {\n external: [\"@powerlines/deepkit\"],\n skipNodeModulesBundle: true\n },\n tsdown: {\n dts: false,\n nodeProtocol: true,\n unbundle: false\n }\n }\n );\n\n return result;\n },\n configResolved: {\n order: \"pre\",\n async handler() {\n this.debug(\"Shell Shock configuration has been resolved.\");\n\n this.config.appSpecificEnvPrefix = isSetString(\n this.config.autoAssignEnv\n )\n ? this.config.autoAssignEnv\n : constantCase(getAppName(this));\n if (\n !this.config.env.prefix ||\n !Array.isArray(this.config.env.prefix)\n ) {\n this.config.env.prefix = toArray(this.config.env.prefix);\n }\n\n if (\n !this.config.env.prefix.includes(this.config.appSpecificEnvPrefix)\n ) {\n this.config.env.prefix.push(this.config.appSpecificEnvPrefix);\n }\n\n this.config.bin = (isSetString(this.packageJson.bin)\n ? { [kebabCase(this.config.name)]: this.packageJson.bin }\n : this.packageJson.bin) ?? {\n [kebabCase(this.config.name)]: formatBinaryPath(\n this.config.output.format\n )\n };\n\n if (isSetString(this.config.reference)) {\n if (this.config.reference.includes(\"{command}\")) {\n this.config.reference = {\n app: this.config.reference\n .substring(0, this.config.reference.indexOf(\"{command}\"))\n .replace(/\\/?$/, \"/\"),\n commands: this.config.reference\n };\n } else if (this.config.reference.includes(\"{commands}\")) {\n this.config.reference = {\n app: this.config.reference\n .substring(0, this.config.reference.indexOf(\"{commands}\"))\n .replace(/\\/?$/, \"/\"),\n commands: this.config.reference\n };\n } else {\n this.config.reference = {\n app: this.config.reference\n };\n }\n }\n\n this.inputs ??= [];\n this.options = Object.values(\n getGlobalOptions(this, {\n id: null,\n name: this.config.name,\n path: null,\n segments: [],\n title: this.config.title,\n description: this.config.description,\n alias: [],\n isVirtual: false\n })\n );\n }\n }\n },\n ...nodejs<TContext>(\n defu(options ?? {}, {\n env: {\n types: \"@shell-shock/core/types/env#ShellShockEnv\",\n validate: false\n }\n })\n ),\n {\n name: \"shell-shock:inputs\",\n async configResolved() {\n this.debug(\"Finding command entry point files.\");\n\n this.debug(\n `Checking for commands using input: ${JSON.stringify(this.config.input)}`\n );\n\n this.commandsPath = await findCommandsRoot(this);\n this.debug(`Resolved commands root path: ${this.commandsPath}`);\n\n const inputs = await resolveInputs(this, this.config.input);\n\n this.debug(\n `Found ${\n inputs.length\n } entry points specified in the configuration options.`\n );\n\n this.inputs = inputs.reduce((ret, entry) => {\n if (\n entry.file !== this.commandsPath &&\n !isParentPath(entry.file, this.commandsPath)\n ) {\n throw new Error(\n `Command entry point \"${\n entry.file\n }\" is not located within the commands root \"${\n this.commandsPath\n }\". Please ensure that all command entry points are located within the current project.`\n );\n }\n\n const id = resolveCommandId(this, entry.file);\n if (!ret.some(existing => existing.id === id)) {\n const name = resolveCommandName(entry.file);\n let segments = resolveCommandPath(this, entry.file)\n .split(\"/\")\n .filter(Boolean);\n\n // Ensure unique segment names by appending an index suffix to duplicates\n segments = segments.map((segment, index) => {\n const found = segments.findIndex(\n existing => existing === segment\n );\n if (found !== -1 && found !== index) {\n segment += `_${\n segments.filter(\n segment =>\n isDynamicPathSegment(segment) &&\n getDynamicPathSegmentName(segment).replace(\n /_\\d+$/,\n \"\"\n ) === segment\n ).length\n }`;\n }\n\n return segment;\n });\n\n ret.push({\n id,\n path: segments.join(\"/\"),\n segments,\n name,\n alias: [],\n tags: [],\n isVirtual: false,\n entry: {\n ...entry,\n file: entry.file,\n input: {\n file: entry.file,\n name: entry.name\n },\n output: name\n }\n });\n }\n\n return ret;\n }, this.inputs);\n\n this.debug(\n `Shell Shock will process ${\n this.inputs.length\n } command entry files: \\n${this.inputs\n .map(\n command =>\n ` - ${command.id}: ${replacePath(\n command.entry.file,\n this.commandsPath\n )}`\n )\n .join(\"\\n\")}`\n );\n },\n types() {\n this.debug(\n \"Generating type definitions for the Shell Shock application.\"\n );\n\n return `\n/**\n * The global options available for every command in the ${getAppTitle(\n this,\n true\n )} command-line application.\n */\nexport interface GlobalOptions {\n ${this.options\n .map(\n option =>\n `${\n option.description\n ? `\n/**\n * ${option.description}${\n option.default\n ? `\n *\n * @defaultValue ${\n option.kind === CommandParameterKinds.string\n ? `\"${option.default}\"`\n : option.default\n }`\n : \"\"\n }\n */\n`\n : \"\"\n }${option.name}${option.optional ? \"?\" : \"\"}: ${\n option.kind === CommandParameterKinds.boolean\n ? \"boolean\"\n : `${option.variadic ? \"(\" : \"\"}${\n option.choices\n ? option.choices\n .map(choice =>\n option.kind === CommandParameterKinds.number\n ? `${choice}`\n : `\"${choice}\"`\n )\n .join(\" | \")\n : option.kind === CommandParameterKinds.number\n ? \"number\"\n : \"string\"\n }${option.variadic ? \")[]\" : \"\"}`\n };${\n option.alias && option.alias.length > 0\n ? option.alias\n .map(\n alias =>\n `${alias}${option.optional ? \"?\" : \"\"}: ${\n option.kind === CommandParameterKinds.boolean\n ? \"boolean\"\n : `${option.variadic ? \"(\" : \"\"}${\n option.choices\n ? option.choices\n .map(choice =>\n option.kind === CommandParameterKinds.number\n ? `${choice}`\n : `\"${choice}\"`\n )\n .join(\" | \")\n : option.kind === CommandParameterKinds.number\n ? \"number\"\n : \"string\"\n }${option.variadic ? \")[]\" : \"\"}`\n };`\n )\n .join(\"\\n\\n\")\n : \"\"\n }`\n )\n .join(\"\\n\\n\")}\n}\n`;\n },\n async prepare() {\n this.debug(\n \"Rendering base built-in modules for the Shell Shock application.\"\n );\n\n return render(\n this,\n <>\n <UtilsBuiltin />\n </>\n );\n }\n },\n {\n name: \"shell-shock:virtual-inputs\",\n configResolved: {\n order: \"post\",\n async handler() {\n if (this.inputs.length === 0) {\n this.warn(\n \"No commands were found in the project. Please ensure at least one command exists.\"\n );\n } else {\n this.debug(\n `Shell Shock will create an application with the following commands: \\n${this.inputs\n .filter(cmd => !cmd.isVirtual)\n .map(\n command =>\n ` - ${command.id}: ${\n isParentPath(command.entry.file, this.commandsPath)\n ? replacePath(command.entry.file, this.commandsPath)\n : relativePath(command.entry.file, this.commandsPath)\n }${command.isVirtual ? \" (virtual)\" : \"\"}`\n )\n .join(\"\\n\")}`\n );\n\n this.debug(\n \"Finding and adding virtual command inputs for each command previously found.\"\n );\n\n this.inputs = this.inputs\n .reduce((ret, command) => {\n let depth = 0;\n\n let parentPath = resolveParentPath(\n findFilePath(command.entry.file)\n );\n if (isParentPath(parentPath, this.commandsPath)) {\n while (parentPath !== this.commandsPath) {\n if (depth++ > MAX_DEPTH) {\n throw new Error(\n `Unable to process virtual commands for ${command.name} \\n\\nPlease ensure ${command.entry.file} is a valid command entry file and does not have an invalid path.`\n );\n }\n\n if (\n !ret.some(\n existing =>\n findFilePath(existing.entry.file) === parentPath\n )\n ) {\n const file = joinPaths(parentPath, \"command.ts\");\n const id = resolveCommandId(this, file);\n if (!ret.some(existing => existing.id === id)) {\n const name = resolveCommandName(file);\n\n let segments = resolveCommandPath(this, file)\n .split(\"/\")\n .filter(Boolean);\n\n // Ensure unique segment names by appending an index suffix to duplicates\n segments = segments.map((segment, index) => {\n const found = segments.findIndex(\n existing => existing === segment\n );\n if (found !== -1 && found !== index) {\n segment += `_${\n segments.filter(\n segment =>\n isDynamicPathSegment(segment) &&\n getDynamicPathSegmentName(segment).replace(\n /_\\d+$/,\n \"\"\n ) === segment\n ).length\n }`;\n }\n\n return segment;\n });\n\n ret.push({\n id,\n path: segments.join(\"/\"),\n segments,\n name,\n alias: [],\n tags: [],\n isVirtual: true,\n entry: {\n file\n }\n });\n }\n }\n\n parentPath = resolveParentPath(parentPath);\n }\n }\n\n return ret;\n }, this.inputs)\n .sort((a, b) => a.segments.length - b.segments.length);\n\n this.debug(\n `Final command input list: \\n${this.inputs\n .map(\n command =>\n ` - ${command.id}: ${\n isParentPath(command.entry.file, this.commandsPath)\n ? replacePath(command.entry.file, this.commandsPath)\n : replacePath(command.entry.file, this.config.root)\n }${command.isVirtual ? \" (virtual)\" : \"\"}`\n )\n .join(\"\\n\")}`\n );\n }\n }\n }\n },\n {\n name: \"shell-shock:resolve-commands\",\n prepare: {\n order: \"post\",\n async handler() {\n this.debug(\"Initializing the CLI application's command tree.\");\n\n this.commands = {};\n if (\n this.config.command !== \"prepare\" &&\n this.config.skipCache !== true &&\n this.persistedMeta?.checksum === this.meta.checksum &&\n this.fs.existsSync(getCommandsPersistencePath(this))\n ) {\n this.debug(\n `Skipping command resolution as the meta checksum has not changed.`\n );\n\n await readCommandsPersistence(this);\n } else {\n for (const input of this.inputs.filter(\n input =>\n input.segments.filter(\n segment =>\n !isDynamicPathSegment(segment) &&\n !isPathSegmentGroup(segment)\n ).length === 1\n )) {\n this.commands[input.name] = await resolve({\n context: this,\n command: input\n });\n }\n\n this.debug(\"Post-processing commands to ensure proper reflection.\");\n\n this.options = this.options.map(\n option =>\n ({\n ...option,\n name: camelCase(option.name),\n alias: option.alias ?? [],\n optional: option.optional ?? false\n }) as CommandOption\n );\n\n await traverseCommands(this, command => {\n command.options = Object.fromEntries(\n Object.entries(command.options).map(([name, option]) => [\n camelCase(name),\n {\n ...option,\n name: camelCase(name),\n alias: option.alias ?? [],\n optional: option.optional ?? false\n } as CommandOption\n ])\n );\n });\n\n await writeCommandsPersistence(this);\n }\n\n this.debug(\"Validating the CLI applications command tree.\");\n\n let isValid = true;\n await traverseCommands(this, command => {\n const failures = validateCommand(command);\n if (failures.length > 0) {\n this.error(\n `Found ${failures.length} issue${failures.length > 1 ? \"s\" : \"\"} with the ${\n command.title\n } command: \\n${failures\n .map(failure => ` - ${failure.code}: ${failure.details}`)\n .join(\"\\n\")}\\n`\n );\n isValid = false;\n }\n });\n if (!isValid) {\n throw new Error(\n `One or more commands in the command tree are invalid. Please review the errors above and correct them before proceeding.`\n );\n }\n\n this.info(\n `\\nCreating an application with the following command tree: \\n${formatCommandTree(\n this\n )}\\n`\n );\n }\n }\n },\n {\n name: \"shell-shock:chmod+x\",\n configResolved() {\n this.config.tsdown.hooks ??= {} as TsdownHooks;\n (this.config.tsdown.hooks as TsdownHooks)[\"build:done\"] = async (\n _: BuildContext & {\n chunks: RolldownChunk[];\n }\n ) => {\n await Promise.all(\n Object.values(this.config.bin).map(async bin => {\n const path = appendPath(\n bin,\n joinPaths(this.workspaceConfig.workspaceRoot, this.config.root)\n );\n if (this.fs.existsSync(path)) {\n this.debug(\n `Adding hashbang to binary executable output file: ${path}`\n );\n\n const content = await this.fs.read(path);\n if (content && !content.startsWith(\"#!\")) {\n await this.fs.write(\n path,\n `#!/usr/bin/env ${\n this.config.mode === \"development\"\n ? \"-S NODE_OPTIONS=--enable-source-maps\"\n : \"\"\n } node\\n\\n${content}`\n );\n }\n\n this.debug(\n `Adding executable permissions (chmod+x) to binary executable output file: ${\n path\n }`\n );\n\n await chmodX(path);\n } else {\n this.warn(\n `Expected binary output file not found at path: ${\n path\n }. Skipping adding hashbang and executable permissions (chmod+x).`\n );\n }\n })\n );\n };\n }\n },\n {\n name: \"shell-shock:docs\",\n configResolved() {\n this.config.automd ??= {};\n this.config.automd.generators = {\n ...(this.config.automd.generators ?? {}),\n commands: commands(this)\n };\n },\n async docs() {\n this.debug(\n \"Rendering entrypoint modules for the Shell Shock `script` preset.\"\n );\n\n const commands = this.inputs\n .map(input => getCommandTree(this, input.segments))\n .filter(Boolean) as CommandTree[];\n\n return render(\n this,\n <For each={Object.values(commands)} doubleHardline>\n {child => (\n <Show when={!child.isVirtual}>\n <CommandDocsFile command={child} />\n </Show>\n )}\n </For>\n );\n }\n }\n ] as Plugin<TContext>[];\n};\n\nexport { plugin as shellShock };\nexport default plugin;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"plugin.mjs","names":[],"sources":["../src/plugin.tsx"],"sourcesContent":["/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Shell Shock\n\n This code was released as part of the Shell Shock project. Shell Shock\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/shell-shock.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/shell-shock\n Documentation: https://docs.stormsoftware.com/projects/shell-shock\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport { For, Show } from \"@alloy-js/core/components\";\nimport { render } from \"@powerlines/plugin-alloy/render\";\nimport automd from \"@powerlines/plugin-automd\";\nimport nodejs from \"@powerlines/plugin-nodejs\";\nimport tsdown from \"@powerlines/plugin-tsdown\";\nimport { toArray } from \"@stryke/convert/to-array\";\nimport { chmodX } from \"@stryke/fs/chmod-x\";\nimport { appendPath } from \"@stryke/path/append\";\nimport { findFilePath, relativePath } from \"@stryke/path/file-path-fns\";\nimport { isParentPath } from \"@stryke/path/is-parent-path\";\nimport { joinPaths } from \"@stryke/path/join-paths\";\nimport { replacePath } from \"@stryke/path/replace\";\nimport { resolveParentPath } from \"@stryke/path/resolve-parent-path\";\nimport { camelCase } from \"@stryke/string-format/camel-case\";\nimport { constantCase } from \"@stryke/string-format/constant-case\";\nimport { kebabCase } from \"@stryke/string-format/kebab-case\";\nimport { isObject } from \"@stryke/type-checks/is-object\";\nimport { isSetString } from \"@stryke/type-checks/is-set-string\";\nimport { defu } from \"defu\";\nimport type { Plugin } from \"powerlines\";\nimport { resolveInputs } from \"powerlines/utils\";\nimport type { BuildContext, RolldownChunk, TsdownHooks } from \"tsdown\";\nimport { CommandDocsFile } from \"./components/docs\";\nimport { SpawnBuiltin } from \"./components/spawn-builtin\";\nimport { StateBuiltin } from \"./components/state-builtin\";\nimport { UtilsBuiltin } from \"./components/utils-builtin\";\nimport { commands } from \"./helpers/automd\";\nimport {\n findCommandsRoot,\n resolveCommandId,\n resolveCommandName,\n resolveCommandPath\n} from \"./helpers/paths\";\nimport {\n getCommandsPersistencePath,\n readCommandsPersistence,\n writeCommandsPersistence\n} from \"./helpers/persistence\";\nimport {\n formatBinaryPath,\n updatePackageJsonBinary\n} from \"./helpers/update-package-json\";\nimport { formatCommandTree, getGlobalOptions } from \"./helpers/utilities\";\nimport { validateCommand } from \"./helpers/validations\";\nimport {\n getAppDescription,\n getAppName,\n getAppTitle,\n getDynamicPathSegmentName,\n isDynamicPathSegment,\n isPathSegmentGroup\n} from \"./plugin-utils/context-helpers\";\nimport { getCommandTree } from \"./plugin-utils/get-command-tree\";\nimport { traverseCommands } from \"./plugin-utils/traverse-command-tree\";\nimport { resolve } from \"./resolver/resolve\";\nimport type { CommandOption, CommandTree } from \"./types/command\";\nimport type { Options } from \"./types/config\";\nimport type { Context } from \"./types/context\";\n\nconst MAX_DEPTH = 50;\n\n/**\n * The core Powerlines plugin to build Shell Shock projects.\n */\nexport const plugin = <TContext extends Context = Context>(\n options: Options = {}\n): Plugin<TContext>[] => {\n return [\n tsdown<TContext>(),\n automd<TContext>(),\n {\n name: \"shell-shock:config\",\n async config() {\n this.debug(\"Resolving the Shell Shock configuration.\");\n\n await updatePackageJsonBinary(this);\n\n const result = defu(\n {\n output: {\n path: joinPaths(this.config.root, \"dist\")\n }\n },\n options,\n {\n name: getAppName(this),\n title: getAppTitle(this),\n description: getAppDescription(this),\n platform: \"node\",\n projectType: \"application\",\n framework: \"shell-shock\",\n isCaseSensitive: false,\n output: {\n format: \"esm\",\n dts: false\n },\n input:\n !this.config.input ||\n (Array.isArray(this.config.input) &&\n this.config.input.length === 0) ||\n (isObject(this.config.input) &&\n Object.keys(this.config.input).length === 0)\n ? [\n joinPaths(this.config.root, \"src/**/command.ts\"),\n joinPaths(this.config.root, \"src/**/command.tsx\")\n ]\n : undefined,\n resolve: {\n external: [\"@powerlines/deepkit\"],\n skipNodeModulesBundle: true\n },\n tsdown: {\n dts: false,\n nodeProtocol: true,\n unbundle: false\n }\n }\n );\n\n return result;\n },\n configResolved: {\n order: \"pre\",\n async handler() {\n this.debug(\"Shell Shock configuration has been resolved.\");\n\n this.config.appSpecificEnvPrefix = isSetString(\n this.config.autoAssignEnv\n )\n ? this.config.autoAssignEnv\n : constantCase(getAppName(this));\n if (\n !this.config.env.prefix ||\n !Array.isArray(this.config.env.prefix)\n ) {\n this.config.env.prefix = toArray(this.config.env.prefix);\n }\n\n if (\n !this.config.env.prefix.includes(this.config.appSpecificEnvPrefix)\n ) {\n this.config.env.prefix.push(this.config.appSpecificEnvPrefix);\n }\n\n this.config.bin = (isSetString(this.packageJson.bin)\n ? { [kebabCase(this.config.name)]: this.packageJson.bin }\n : this.packageJson.bin) ?? {\n [kebabCase(this.config.name)]: formatBinaryPath(\n this.config.output.format\n )\n };\n\n if (isSetString(this.config.reference)) {\n if (this.config.reference.includes(\"{command}\")) {\n this.config.reference = {\n app: this.config.reference\n .substring(0, this.config.reference.indexOf(\"{command}\"))\n .replace(/\\/?$/, \"/\"),\n commands: this.config.reference\n };\n } else if (this.config.reference.includes(\"{commands}\")) {\n this.config.reference = {\n app: this.config.reference\n .substring(0, this.config.reference.indexOf(\"{commands}\"))\n .replace(/\\/?$/, \"/\"),\n commands: this.config.reference\n };\n } else {\n this.config.reference = {\n app: this.config.reference\n };\n }\n }\n\n this.inputs ??= [];\n this.options = Object.values(\n getGlobalOptions(this, {\n id: null,\n name: this.config.name,\n path: null,\n segments: [],\n title: this.config.title,\n description: this.config.description,\n alias: [],\n isVirtual: false\n })\n );\n\n this.options = this.options.map(\n option =>\n ({\n ...option,\n name: camelCase(option.name),\n alias: option.alias ?? [],\n optional: option.optional ?? false\n }) as CommandOption\n );\n }\n }\n },\n ...nodejs<TContext>(\n defu(options ?? {}, {\n env: {\n types: \"@shell-shock/core/types/env#ShellShockEnv\",\n validate: false\n }\n })\n ),\n {\n name: \"shell-shock:inputs\",\n async configResolved() {\n this.debug(\"Finding command entry point files.\");\n\n this.debug(\n `Checking for commands using input: ${JSON.stringify(this.config.input)}`\n );\n\n this.commandsPath = await findCommandsRoot(this);\n this.debug(`Resolved commands root path: ${this.commandsPath}`);\n\n const inputs = await resolveInputs(this, this.config.input);\n\n this.debug(\n `Found ${\n inputs.length\n } entry points specified in the configuration options.`\n );\n\n this.inputs = inputs.reduce((ret, entry) => {\n if (\n entry.file !== this.commandsPath &&\n !isParentPath(entry.file, this.commandsPath)\n ) {\n throw new Error(\n `Command entry point \"${\n entry.file\n }\" is not located within the commands root \"${\n this.commandsPath\n }\". Please ensure that all command entry points are located within the current project.`\n );\n }\n\n const id = resolveCommandId(this, entry.file);\n if (!ret.some(existing => existing.id === id)) {\n const name = resolveCommandName(entry.file);\n let segments = resolveCommandPath(this, entry.file)\n .split(\"/\")\n .filter(Boolean);\n\n // Ensure unique segment names by appending an index suffix to duplicates\n segments = segments.map((segment, index) => {\n const found = segments.findIndex(\n existing => existing === segment\n );\n if (found !== -1 && found !== index) {\n segment += `_${\n segments.filter(\n segment =>\n isDynamicPathSegment(segment) &&\n getDynamicPathSegmentName(segment).replace(\n /_\\d+$/,\n \"\"\n ) === segment\n ).length\n }`;\n }\n\n return segment;\n });\n\n ret.push({\n id,\n path: segments.join(\"/\"),\n segments,\n name,\n alias: [],\n tags: [],\n isVirtual: false,\n entry: {\n ...entry,\n file: entry.file,\n input: {\n file: entry.file,\n name: entry.name\n },\n output: name\n }\n });\n }\n\n return ret;\n }, this.inputs);\n\n this.debug(\n `Shell Shock will process ${\n this.inputs.length\n } command entry files: \\n${this.inputs\n .map(\n command =>\n ` - ${command.id}: ${replacePath(\n command.entry.file,\n this.commandsPath\n )}`\n )\n .join(\"\\n\")}`\n );\n },\n async prepare() {\n this.debug(\n \"Rendering base built-in modules for the Shell Shock application.\"\n );\n\n return render(\n this,\n <>\n <StateBuiltin />\n <UtilsBuiltin />\n <SpawnBuiltin />\n </>\n );\n }\n },\n {\n name: \"shell-shock:virtual-inputs\",\n configResolved: {\n order: \"post\",\n async handler() {\n if (this.inputs.length === 0) {\n this.warn(\n \"No commands were found in the project. Please ensure at least one command exists.\"\n );\n } else {\n this.debug(\n `Shell Shock will create an application with the following commands: \\n${this.inputs\n .filter(cmd => !cmd.isVirtual)\n .map(\n command =>\n ` - ${command.id}: ${\n isParentPath(command.entry.file, this.commandsPath)\n ? replacePath(command.entry.file, this.commandsPath)\n : relativePath(command.entry.file, this.commandsPath)\n }${command.isVirtual ? \" (virtual)\" : \"\"}`\n )\n .join(\"\\n\")}`\n );\n\n this.debug(\n \"Finding and adding virtual command inputs for each command previously found.\"\n );\n\n this.inputs = this.inputs\n .reduce((ret, command) => {\n let depth = 0;\n\n let parentPath = resolveParentPath(\n findFilePath(command.entry.file)\n );\n if (isParentPath(parentPath, this.commandsPath)) {\n while (parentPath !== this.commandsPath) {\n if (depth++ > MAX_DEPTH) {\n throw new Error(\n `Unable to process virtual commands for ${\n command.name\n } \\n\\nPlease ensure ${\n command.entry.file\n } is a valid command entry file and does not have an invalid path.`\n );\n }\n\n if (\n !ret.some(\n existing =>\n findFilePath(existing.entry.file) === parentPath\n )\n ) {\n const file = joinPaths(parentPath, \"command.ts\");\n const id = resolveCommandId(this, file);\n if (!ret.some(existing => existing.id === id)) {\n const name = resolveCommandName(file);\n\n let segments = resolveCommandPath(this, file)\n .split(\"/\")\n .filter(Boolean);\n\n // Ensure unique segment names by appending an index suffix to duplicates\n segments = segments.map((segment, index) => {\n const found = segments.findIndex(\n existing => existing === segment\n );\n if (found !== -1 && found !== index) {\n segment += `_${\n segments.filter(\n segment =>\n isDynamicPathSegment(segment) &&\n getDynamicPathSegmentName(segment).replace(\n /_\\d+$/,\n \"\"\n ) === segment\n ).length\n }`;\n }\n\n return segment;\n });\n\n ret.push({\n id,\n path: segments.join(\"/\"),\n segments,\n name,\n alias: [],\n tags: [],\n isVirtual: true,\n entry: {\n file\n }\n });\n }\n }\n\n parentPath = resolveParentPath(parentPath);\n }\n }\n\n return ret;\n }, this.inputs)\n .sort((a, b) => a.segments.length - b.segments.length);\n\n this.debug(\n `Final command input list: \\n${this.inputs\n .map(\n command =>\n ` - ${command.id}: ${\n isParentPath(command.entry.file, this.commandsPath)\n ? replacePath(command.entry.file, this.commandsPath)\n : replacePath(command.entry.file, this.config.root)\n }${command.isVirtual ? \" (virtual)\" : \"\"}`\n )\n .join(\"\\n\")}`\n );\n }\n }\n }\n },\n {\n name: \"shell-shock:resolve-commands\",\n prepare: {\n order: \"post\",\n async handler() {\n this.debug(\"Initializing the CLI application's command tree.\");\n\n this.commands = {};\n if (\n this.config.command !== \"prepare\" &&\n this.config.skipCache !== true &&\n this.persistedMeta?.checksum === this.meta.checksum &&\n this.fs.existsSync(getCommandsPersistencePath(this))\n ) {\n this.debug(\n `Skipping command resolution as the meta checksum has not changed.`\n );\n\n await readCommandsPersistence(this);\n } else {\n for (const input of this.inputs.filter(\n input =>\n input.segments.filter(\n segment =>\n !isDynamicPathSegment(segment) &&\n !isPathSegmentGroup(segment)\n ).length === 1\n )) {\n this.commands[input.name] = await resolve({\n context: this,\n command: input\n });\n }\n\n this.debug(\"Post-processing commands to ensure proper reflection.\");\n\n await traverseCommands(this, command => {\n command.options = Object.fromEntries(\n Object.entries(command.options).map(([name, option]) => [\n camelCase(name),\n {\n ...option,\n name: camelCase(name),\n alias: option.alias ?? [],\n optional: option.optional ?? false\n } as CommandOption\n ])\n );\n });\n\n await writeCommandsPersistence(this);\n }\n\n this.debug(\"Validating the CLI applications command tree.\");\n\n let isValid = true;\n await traverseCommands(this, command => {\n const failures = validateCommand(command);\n if (failures.length > 0) {\n this.error(\n `Found ${failures.length} issue${failures.length > 1 ? \"s\" : \"\"} with the ${\n command.title\n } command: \\n${failures\n .map(failure => ` - ${failure.code}: ${failure.details}`)\n .join(\"\\n\")}\\n`\n );\n isValid = false;\n }\n });\n if (!isValid) {\n throw new Error(\n `One or more commands in the command tree are invalid. Please review the errors above and correct them before proceeding.`\n );\n }\n\n this.info(\n `\\nCreating an application with the following command tree: \\n${formatCommandTree(\n this\n )}\\n`\n );\n }\n }\n },\n {\n name: \"shell-shock:chmod+x\",\n configResolved() {\n this.config.tsdown.hooks ??= {} as TsdownHooks;\n (this.config.tsdown.hooks as TsdownHooks)[\"build:done\"] = async (\n _: BuildContext & {\n chunks: RolldownChunk[];\n }\n ) => {\n await Promise.all(\n Object.values(this.config.bin).map(async bin => {\n const path = appendPath(\n bin,\n joinPaths(this.workspaceConfig.workspaceRoot, this.config.root)\n );\n if (this.fs.existsSync(path)) {\n this.debug(\n `Adding hashbang to binary executable output file: ${path}`\n );\n\n const content = await this.fs.read(path);\n if (content && !content.startsWith(\"#!\")) {\n await this.fs.write(\n path,\n `#!/usr/bin/env ${\n this.config.mode === \"development\"\n ? \"-S NODE_OPTIONS=--enable-source-maps\"\n : \"\"\n } node\\n\\n${content}`\n );\n }\n\n this.debug(\n `Adding executable permissions (chmod+x) to binary executable output file: ${\n path\n }`\n );\n\n await chmodX(path);\n } else {\n this.warn(\n `Expected binary output file not found at path: ${\n path\n }. Skipping adding hashbang and executable permissions (chmod+x).`\n );\n }\n })\n );\n };\n }\n },\n {\n name: \"shell-shock:docs\",\n configResolved() {\n this.config.automd ??= {};\n this.config.automd.generators = {\n ...(this.config.automd.generators ?? {}),\n commands: commands(this)\n };\n },\n async docs() {\n this.debug(\n \"Rendering entrypoint modules for the Shell Shock `script` preset.\"\n );\n\n const commands = this.inputs\n .map(input => getCommandTree(this, input.segments))\n .filter(Boolean) as CommandTree[];\n\n return render(\n this,\n <For each={Object.values(commands)} doubleHardline>\n {child => (\n <Show when={!child.isVirtual}>\n <CommandDocsFile command={child} />\n </Show>\n )}\n </For>\n );\n }\n }\n ];\n};\n\nexport default plugin;\n"],"mappings":"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"}
|