@shell-shock/core 0.16.2 → 0.17.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/dist/components/command-validation-logic.cjs +1 -1
  2. package/dist/components/command-validation-logic.cjs.map +1 -1
  3. package/dist/components/command-validation-logic.mjs +1 -1
  4. package/dist/components/command-validation-logic.mjs.map +1 -1
  5. package/dist/components/{spawn-builtin.cjs → exec-builtin.cjs} +140 -75
  6. package/dist/components/exec-builtin.cjs.map +1 -0
  7. package/dist/components/exec-builtin.d.cts +12 -0
  8. package/dist/components/exec-builtin.d.cts.map +1 -0
  9. package/dist/components/exec-builtin.d.mts +12 -0
  10. package/dist/components/exec-builtin.d.mts.map +1 -0
  11. package/dist/components/{spawn-builtin.mjs → exec-builtin.mjs} +140 -75
  12. package/dist/components/exec-builtin.mjs.map +1 -0
  13. package/dist/components/index.cjs +3 -2
  14. package/dist/components/index.d.cts +3 -3
  15. package/dist/components/index.d.mts +3 -3
  16. package/dist/components/index.mjs +3 -3
  17. package/dist/components/options-parser-logic.cjs +14 -6
  18. package/dist/components/options-parser-logic.cjs.map +1 -1
  19. package/dist/components/options-parser-logic.d.cts +2 -5
  20. package/dist/components/options-parser-logic.d.cts.map +1 -1
  21. package/dist/components/options-parser-logic.d.mts +2 -5
  22. package/dist/components/options-parser-logic.d.mts.map +1 -1
  23. package/dist/components/options-parser-logic.mjs +14 -6
  24. package/dist/components/options-parser-logic.mjs.map +1 -1
  25. package/dist/components/state-builtin.cjs +43 -8
  26. package/dist/components/state-builtin.cjs.map +1 -1
  27. package/dist/components/state-builtin.d.cts.map +1 -1
  28. package/dist/components/state-builtin.d.mts.map +1 -1
  29. package/dist/components/state-builtin.mjs +44 -9
  30. package/dist/components/state-builtin.mjs.map +1 -1
  31. package/dist/components/utils-builtin.cjs +154 -0
  32. package/dist/components/utils-builtin.cjs.map +1 -1
  33. package/dist/components/utils-builtin.d.cts +5 -1
  34. package/dist/components/utils-builtin.d.cts.map +1 -1
  35. package/dist/components/utils-builtin.d.mts +5 -1
  36. package/dist/components/utils-builtin.d.mts.map +1 -1
  37. package/dist/components/utils-builtin.mjs +155 -2
  38. package/dist/components/utils-builtin.mjs.map +1 -1
  39. package/dist/plugin.cjs +2 -2
  40. package/dist/plugin.cjs.map +1 -1
  41. package/dist/plugin.mjs +2 -2
  42. package/dist/plugin.mjs.map +1 -1
  43. package/dist/resolver/resolve.cjs +1 -1
  44. package/dist/resolver/resolve.cjs.map +1 -1
  45. package/dist/resolver/resolve.mjs +1 -1
  46. package/dist/resolver/resolve.mjs.map +1 -1
  47. package/dist/types/env.cjs +1 -1
  48. package/dist/types/env.cjs.map +1 -1
  49. package/dist/types/env.d.cts +7 -1
  50. package/dist/types/env.d.cts.map +1 -1
  51. package/dist/types/env.d.mts +7 -1
  52. package/dist/types/env.d.mts.map +1 -1
  53. package/dist/types/env.mjs +1 -1
  54. package/dist/types/env.mjs.map +1 -1
  55. package/package.json +16 -16
  56. package/dist/components/spawn-builtin.cjs.map +0 -1
  57. package/dist/components/spawn-builtin.d.cts +0 -12
  58. package/dist/components/spawn-builtin.d.cts.map +0 -1
  59. package/dist/components/spawn-builtin.d.mts +0 -12
  60. package/dist/components/spawn-builtin.d.mts.map +0 -1
  61. package/dist/components/spawn-builtin.mjs.map +0 -1
@@ -95,7 +95,7 @@ function CommandValidationLogic(props) {
95
95
  get children() {
96
96
  return (0, _alloy_js_core_jsx_runtime.createComponent)(_alloy_js_core.Show, {
97
97
  get when() {
98
- return (option.kind === require_types_command.CommandParameterKinds.string || option.kind === require_types_command.CommandParameterKinds.number) && option.variadic;
98
+ return !option.variadic;
99
99
  },
100
100
  get fallback() {
101
101
  return (0, _alloy_js_core_jsx_runtime.createComponent)(_alloy_js_typescript.ElseIfClause, {
@@ -1 +1 @@
1
- {"version":3,"file":"command-validation-logic.cjs","names":[],"sources":["../../src/components/command-validation-logic.tsx"],"sourcesContent":["/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Shell Shock\n\n This code was released as part of the Shell Shock project. Shell Shock\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/shell-shock.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/shell-shock\n Documentation: https://docs.stormsoftware.com/projects/shell-shock\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport { code, For, Show } from \"@alloy-js/core\";\nimport {\n ElseIfClause,\n IfStatement,\n VarDeclaration\n} from \"@alloy-js/typescript\";\nimport { Spacing } from \"@powerlines/plugin-alloy/core/components/spacing\";\nimport { camelCase } from \"@stryke/string-format/camel-case\";\nimport { list } from \"@stryke/string-format/list\";\nimport type {\n CommandTree,\n NumberCommandParameter,\n StringCommandParameter\n} from \"../types\";\nimport { CommandParameterKinds } from \"../types\";\n\nexport interface CommandValidationLogicProps {\n command: CommandTree;\n}\n\n/**\n * A component that generates command validation logic for required options and arguments.\n */\nexport function CommandValidationLogic(props: CommandValidationLogicProps) {\n const { command } = props;\n\n return (\n <>\n <VarDeclaration name=\"failures\" type=\"string[]\" initializer={code`[];`} />\n <hbr />\n <For each={Object.values(command.options ?? {})} doubleHardline>\n {option => (\n <>\n <Show when={!option.optional}>\n <IfStatement\n condition={code`!options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n }`}>\n {code`failures.push(\"Missing required ${option.name} option\");`}\n </IfStatement>\n <Show\n when={\n (option.kind === CommandParameterKinds.string ||\n option.kind === CommandParameterKinds.number) &&\n option.variadic\n }>\n <ElseIfClause\n condition={code`options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n }.length === 0`}>\n {code`failures.push(\"No values were provided to the required ${\n option.name\n } array option\");`}\n </ElseIfClause>\n </Show>\n </Show>\n <Show when={option.kind === CommandParameterKinds.number}>\n <Show\n when={(option as NumberCommandParameter).variadic}\n fallback={\n <IfStatement\n condition={code`options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n } && Number.isNaN(options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n })`}>\n {code`failures.push(\"Invalid numeric value provided for the ${\n option.name\n } option\");`}\n </IfStatement>\n }>\n <IfStatement\n condition={code`options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n }.some(value => Number.isNaN(value))`}>\n {code`failures.push(\"Invalid numeric value provided in the ${\n option.name\n } array option\");`}\n </IfStatement>\n </Show>\n </Show>\n <Show\n when={\n (option.kind === CommandParameterKinds.string ||\n option.kind === CommandParameterKinds.number) &&\n option.choices &&\n option.choices.length > 0\n }>\n <Show\n when={\n (option.kind === CommandParameterKinds.string ||\n option.kind === CommandParameterKinds.number) &&\n option.variadic\n }\n fallback={\n <ElseIfClause\n condition={code`!options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n }.every(value => [${(\n option as StringCommandParameter | NumberCommandParameter\n ).choices\n ?.map(choice =>\n option.kind === CommandParameterKinds.string\n ? `\"${choice}\"`\n : choice\n )\n .join(\", \")}].includes(value))`}>\n {code`failures.push(\\`Invalid value provided for the ${\n option.name\n } option - valid values include: ${list(\n (\n option as\n | StringCommandParameter\n | NumberCommandParameter\n )?.choices?.map(choice => String(choice)) ?? []\n )}; provided: \\${options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n }}\\`);`}\n </ElseIfClause>\n }>\n <ElseIfClause\n condition={code`![${(\n option as StringCommandParameter | NumberCommandParameter\n ).choices\n ?.map(choice =>\n option.kind === CommandParameterKinds.string\n ? `\"${choice}\"`\n : choice\n )\n .join(\", \")}].includes(options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n })`}>\n {code`failures.push(\\`Invalid value provided for the ${\n option.name\n } option - valid values include: ${list(\n (\n option as StringCommandParameter | NumberCommandParameter\n )?.choices?.map(choice => String(choice)) ?? []\n )}; provided: \\${options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n }}\\`);`}\n </ElseIfClause>\n </Show>\n </Show>\n </>\n )}\n </For>\n <Spacing />\n <For each={command.args} doubleHardline>\n {argument => (\n <>\n <Show when={!argument.optional}>\n <IfStatement condition={code`!${camelCase(argument.name)}`}>\n {code`failures.push(\"Missing required \\\\\"${\n argument.name\n }\\\\\" positional argument\");`}\n </IfStatement>\n <Show\n when={\n (argument.kind === CommandParameterKinds.string ||\n argument.kind === CommandParameterKinds.number) &&\n argument.variadic\n }>\n <ElseIfClause\n condition={code`${camelCase(argument.name)}.length === 0`}>\n {code`failures.push(\"No values were provided to the required ${\n argument.name\n } array positional argument\");`}\n </ElseIfClause>\n </Show>\n </Show>\n <Show when={argument.kind === CommandParameterKinds.number}>\n <Show\n when={(argument as NumberCommandParameter).variadic}\n fallback={\n <IfStatement\n condition={code`${camelCase(\n argument.name\n )} && Number.isNaN(${camelCase(argument.name)})`}>\n {code`failures.push(\"Invalid numeric value provided for the ${\n argument.name\n } positional argument\");`}\n </IfStatement>\n }>\n <IfStatement\n condition={code`${camelCase(argument.name)}.some(value => Number.isNaN(value))`}>\n {code`failures.push(\"Invalid numeric value provided in the ${\n argument.name\n } array positional argument\");`}\n </IfStatement>\n </Show>\n </Show>\n </>\n )}\n </For>\n </>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"command-validation-logic.cjs","names":[],"sources":["../../src/components/command-validation-logic.tsx"],"sourcesContent":["/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Shell Shock\n\n This code was released as part of the Shell Shock project. Shell Shock\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/shell-shock.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/shell-shock\n Documentation: https://docs.stormsoftware.com/projects/shell-shock\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport { code, For, Show } from \"@alloy-js/core\";\nimport {\n ElseIfClause,\n IfStatement,\n VarDeclaration\n} from \"@alloy-js/typescript\";\nimport { Spacing } from \"@powerlines/plugin-alloy/core/components/spacing\";\nimport { camelCase } from \"@stryke/string-format/camel-case\";\nimport { list } from \"@stryke/string-format/list\";\nimport type {\n CommandTree,\n NumberCommandParameter,\n StringCommandParameter\n} from \"../types\";\nimport { CommandParameterKinds } from \"../types\";\n\nexport interface CommandValidationLogicProps {\n command: CommandTree;\n}\n\n/**\n * A component that generates command validation logic for required options and arguments.\n */\nexport function CommandValidationLogic(props: CommandValidationLogicProps) {\n const { command } = props;\n\n return (\n <>\n <VarDeclaration name=\"failures\" type=\"string[]\" initializer={code`[];`} />\n <hbr />\n <For each={Object.values(command.options ?? {})} doubleHardline>\n {option => (\n <>\n <Show when={!option.optional}>\n <IfStatement\n condition={code`!options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n }`}>\n {code`failures.push(\"Missing required ${option.name} option\");`}\n </IfStatement>\n <Show\n when={\n (option.kind === CommandParameterKinds.string ||\n option.kind === CommandParameterKinds.number) &&\n option.variadic\n }>\n <ElseIfClause\n condition={code`options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n }.length === 0`}>\n {code`failures.push(\"No values were provided to the required ${\n option.name\n } array option\");`}\n </ElseIfClause>\n </Show>\n </Show>\n <Show when={option.kind === CommandParameterKinds.number}>\n <Show\n when={(option as NumberCommandParameter).variadic}\n fallback={\n <IfStatement\n condition={code`options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n } && Number.isNaN(options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n })`}>\n {code`failures.push(\"Invalid numeric value provided for the ${\n option.name\n } option\");`}\n </IfStatement>\n }>\n <IfStatement\n condition={code`options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n }.some(value => Number.isNaN(value))`}>\n {code`failures.push(\"Invalid numeric value provided in the ${\n option.name\n } array option\");`}\n </IfStatement>\n </Show>\n </Show>\n <Show\n when={\n (option.kind === CommandParameterKinds.string ||\n option.kind === CommandParameterKinds.number) &&\n option.choices &&\n option.choices.length > 0\n }>\n <Show\n when={!option.variadic}\n fallback={\n <ElseIfClause\n condition={code`!options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n }.every(value => [${(\n option as StringCommandParameter | NumberCommandParameter\n ).choices\n ?.map(choice =>\n option.kind === CommandParameterKinds.string\n ? `\"${choice}\"`\n : choice\n )\n .join(\", \")}].includes(value))`}>\n {code`failures.push(\\`Invalid value provided for the ${\n option.name\n } option - valid values include: ${list(\n (\n option as\n | StringCommandParameter\n | NumberCommandParameter\n )?.choices?.map(choice => String(choice)) ?? []\n )}; provided: \\${options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n }}\\`);`}\n </ElseIfClause>\n }>\n <ElseIfClause\n condition={code`![${(\n option as StringCommandParameter | NumberCommandParameter\n ).choices\n ?.map(choice =>\n option.kind === CommandParameterKinds.string\n ? `\"${choice}\"`\n : choice\n )\n .join(\", \")}].includes(options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n })`}>\n {code`failures.push(\\`Invalid value provided for the ${\n option.name\n } option - valid values include: ${list(\n (\n option as StringCommandParameter | NumberCommandParameter\n )?.choices?.map(choice => String(choice)) ?? []\n )}; provided: \\${options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n }}\\`);`}\n </ElseIfClause>\n </Show>\n </Show>\n </>\n )}\n </For>\n <Spacing />\n <For each={command.args} doubleHardline>\n {argument => (\n <>\n <Show when={!argument.optional}>\n <IfStatement condition={code`!${camelCase(argument.name)}`}>\n {code`failures.push(\"Missing required \\\\\"${\n argument.name\n }\\\\\" positional argument\");`}\n </IfStatement>\n <Show\n when={\n (argument.kind === CommandParameterKinds.string ||\n argument.kind === CommandParameterKinds.number) &&\n argument.variadic\n }>\n <ElseIfClause\n condition={code`${camelCase(argument.name)}.length === 0`}>\n {code`failures.push(\"No values were provided to the required ${\n argument.name\n } array positional argument\");`}\n </ElseIfClause>\n </Show>\n </Show>\n <Show when={argument.kind === CommandParameterKinds.number}>\n <Show\n when={(argument as NumberCommandParameter).variadic}\n fallback={\n <IfStatement\n condition={code`${camelCase(\n argument.name\n )} && Number.isNaN(${camelCase(argument.name)})`}>\n {code`failures.push(\"Invalid numeric value provided for the ${\n argument.name\n } positional argument\");`}\n </IfStatement>\n }>\n <IfStatement\n condition={code`${camelCase(argument.name)}.some(value => Number.isNaN(value))`}>\n {code`failures.push(\"Invalid numeric value provided in the ${\n argument.name\n } array positional argument\");`}\n </IfStatement>\n </Show>\n </Show>\n </>\n )}\n </For>\n </>\n );\n}\n"],"mappings":"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"}
@@ -93,7 +93,7 @@ function CommandValidationLogic(props) {
93
93
  get children() {
94
94
  return createComponent(Show, {
95
95
  get when() {
96
- return (option.kind === CommandParameterKinds.string || option.kind === CommandParameterKinds.number) && option.variadic;
96
+ return !option.variadic;
97
97
  },
98
98
  get fallback() {
99
99
  return createComponent(ElseIfClause, {
@@ -1 +1 @@
1
- {"version":3,"file":"command-validation-logic.mjs","names":[],"sources":["../../src/components/command-validation-logic.tsx"],"sourcesContent":["/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Shell Shock\n\n This code was released as part of the Shell Shock project. Shell Shock\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/shell-shock.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/shell-shock\n Documentation: https://docs.stormsoftware.com/projects/shell-shock\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport { code, For, Show } from \"@alloy-js/core\";\nimport {\n ElseIfClause,\n IfStatement,\n VarDeclaration\n} from \"@alloy-js/typescript\";\nimport { Spacing } from \"@powerlines/plugin-alloy/core/components/spacing\";\nimport { camelCase } from \"@stryke/string-format/camel-case\";\nimport { list } from \"@stryke/string-format/list\";\nimport type {\n CommandTree,\n NumberCommandParameter,\n StringCommandParameter\n} from \"../types\";\nimport { CommandParameterKinds } from \"../types\";\n\nexport interface CommandValidationLogicProps {\n command: CommandTree;\n}\n\n/**\n * A component that generates command validation logic for required options and arguments.\n */\nexport function CommandValidationLogic(props: CommandValidationLogicProps) {\n const { command } = props;\n\n return (\n <>\n <VarDeclaration name=\"failures\" type=\"string[]\" initializer={code`[];`} />\n <hbr />\n <For each={Object.values(command.options ?? {})} doubleHardline>\n {option => (\n <>\n <Show when={!option.optional}>\n <IfStatement\n condition={code`!options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n }`}>\n {code`failures.push(\"Missing required ${option.name} option\");`}\n </IfStatement>\n <Show\n when={\n (option.kind === CommandParameterKinds.string ||\n option.kind === CommandParameterKinds.number) &&\n option.variadic\n }>\n <ElseIfClause\n condition={code`options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n }.length === 0`}>\n {code`failures.push(\"No values were provided to the required ${\n option.name\n } array option\");`}\n </ElseIfClause>\n </Show>\n </Show>\n <Show when={option.kind === CommandParameterKinds.number}>\n <Show\n when={(option as NumberCommandParameter).variadic}\n fallback={\n <IfStatement\n condition={code`options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n } && Number.isNaN(options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n })`}>\n {code`failures.push(\"Invalid numeric value provided for the ${\n option.name\n } option\");`}\n </IfStatement>\n }>\n <IfStatement\n condition={code`options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n }.some(value => Number.isNaN(value))`}>\n {code`failures.push(\"Invalid numeric value provided in the ${\n option.name\n } array option\");`}\n </IfStatement>\n </Show>\n </Show>\n <Show\n when={\n (option.kind === CommandParameterKinds.string ||\n option.kind === CommandParameterKinds.number) &&\n option.choices &&\n option.choices.length > 0\n }>\n <Show\n when={\n (option.kind === CommandParameterKinds.string ||\n option.kind === CommandParameterKinds.number) &&\n option.variadic\n }\n fallback={\n <ElseIfClause\n condition={code`!options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n }.every(value => [${(\n option as StringCommandParameter | NumberCommandParameter\n ).choices\n ?.map(choice =>\n option.kind === CommandParameterKinds.string\n ? `\"${choice}\"`\n : choice\n )\n .join(\", \")}].includes(value))`}>\n {code`failures.push(\\`Invalid value provided for the ${\n option.name\n } option - valid values include: ${list(\n (\n option as\n | StringCommandParameter\n | NumberCommandParameter\n )?.choices?.map(choice => String(choice)) ?? []\n )}; provided: \\${options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n }}\\`);`}\n </ElseIfClause>\n }>\n <ElseIfClause\n condition={code`![${(\n option as StringCommandParameter | NumberCommandParameter\n ).choices\n ?.map(choice =>\n option.kind === CommandParameterKinds.string\n ? `\"${choice}\"`\n : choice\n )\n .join(\", \")}].includes(options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n })`}>\n {code`failures.push(\\`Invalid value provided for the ${\n option.name\n } option - valid values include: ${list(\n (\n option as StringCommandParameter | NumberCommandParameter\n )?.choices?.map(choice => String(choice)) ?? []\n )}; provided: \\${options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n }}\\`);`}\n </ElseIfClause>\n </Show>\n </Show>\n </>\n )}\n </For>\n <Spacing />\n <For each={command.args} doubleHardline>\n {argument => (\n <>\n <Show when={!argument.optional}>\n <IfStatement condition={code`!${camelCase(argument.name)}`}>\n {code`failures.push(\"Missing required \\\\\"${\n argument.name\n }\\\\\" positional argument\");`}\n </IfStatement>\n <Show\n when={\n (argument.kind === CommandParameterKinds.string ||\n argument.kind === CommandParameterKinds.number) &&\n argument.variadic\n }>\n <ElseIfClause\n condition={code`${camelCase(argument.name)}.length === 0`}>\n {code`failures.push(\"No values were provided to the required ${\n argument.name\n } array positional argument\");`}\n </ElseIfClause>\n </Show>\n </Show>\n <Show when={argument.kind === CommandParameterKinds.number}>\n <Show\n when={(argument as NumberCommandParameter).variadic}\n fallback={\n <IfStatement\n condition={code`${camelCase(\n argument.name\n )} && Number.isNaN(${camelCase(argument.name)})`}>\n {code`failures.push(\"Invalid numeric value provided for the ${\n argument.name\n } positional argument\");`}\n </IfStatement>\n }>\n <IfStatement\n condition={code`${camelCase(argument.name)}.some(value => Number.isNaN(value))`}>\n {code`failures.push(\"Invalid numeric value provided in the ${\n argument.name\n } array positional argument\");`}\n </IfStatement>\n </Show>\n </Show>\n </>\n )}\n </For>\n </>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"command-validation-logic.mjs","names":[],"sources":["../../src/components/command-validation-logic.tsx"],"sourcesContent":["/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Shell Shock\n\n This code was released as part of the Shell Shock project. Shell Shock\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/shell-shock.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/shell-shock\n Documentation: https://docs.stormsoftware.com/projects/shell-shock\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport { code, For, Show } from \"@alloy-js/core\";\nimport {\n ElseIfClause,\n IfStatement,\n VarDeclaration\n} from \"@alloy-js/typescript\";\nimport { Spacing } from \"@powerlines/plugin-alloy/core/components/spacing\";\nimport { camelCase } from \"@stryke/string-format/camel-case\";\nimport { list } from \"@stryke/string-format/list\";\nimport type {\n CommandTree,\n NumberCommandParameter,\n StringCommandParameter\n} from \"../types\";\nimport { CommandParameterKinds } from \"../types\";\n\nexport interface CommandValidationLogicProps {\n command: CommandTree;\n}\n\n/**\n * A component that generates command validation logic for required options and arguments.\n */\nexport function CommandValidationLogic(props: CommandValidationLogicProps) {\n const { command } = props;\n\n return (\n <>\n <VarDeclaration name=\"failures\" type=\"string[]\" initializer={code`[];`} />\n <hbr />\n <For each={Object.values(command.options ?? {})} doubleHardline>\n {option => (\n <>\n <Show when={!option.optional}>\n <IfStatement\n condition={code`!options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n }`}>\n {code`failures.push(\"Missing required ${option.name} option\");`}\n </IfStatement>\n <Show\n when={\n (option.kind === CommandParameterKinds.string ||\n option.kind === CommandParameterKinds.number) &&\n option.variadic\n }>\n <ElseIfClause\n condition={code`options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n }.length === 0`}>\n {code`failures.push(\"No values were provided to the required ${\n option.name\n } array option\");`}\n </ElseIfClause>\n </Show>\n </Show>\n <Show when={option.kind === CommandParameterKinds.number}>\n <Show\n when={(option as NumberCommandParameter).variadic}\n fallback={\n <IfStatement\n condition={code`options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n } && Number.isNaN(options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n })`}>\n {code`failures.push(\"Invalid numeric value provided for the ${\n option.name\n } option\");`}\n </IfStatement>\n }>\n <IfStatement\n condition={code`options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n }.some(value => Number.isNaN(value))`}>\n {code`failures.push(\"Invalid numeric value provided in the ${\n option.name\n } array option\");`}\n </IfStatement>\n </Show>\n </Show>\n <Show\n when={\n (option.kind === CommandParameterKinds.string ||\n option.kind === CommandParameterKinds.number) &&\n option.choices &&\n option.choices.length > 0\n }>\n <Show\n when={!option.variadic}\n fallback={\n <ElseIfClause\n condition={code`!options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n }.every(value => [${(\n option as StringCommandParameter | NumberCommandParameter\n ).choices\n ?.map(choice =>\n option.kind === CommandParameterKinds.string\n ? `\"${choice}\"`\n : choice\n )\n .join(\", \")}].includes(value))`}>\n {code`failures.push(\\`Invalid value provided for the ${\n option.name\n } option - valid values include: ${list(\n (\n option as\n | StringCommandParameter\n | NumberCommandParameter\n )?.choices?.map(choice => String(choice)) ?? []\n )}; provided: \\${options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n }}\\`);`}\n </ElseIfClause>\n }>\n <ElseIfClause\n condition={code`![${(\n option as StringCommandParameter | NumberCommandParameter\n ).choices\n ?.map(choice =>\n option.kind === CommandParameterKinds.string\n ? `\"${choice}\"`\n : choice\n )\n .join(\", \")}].includes(options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n })`}>\n {code`failures.push(\\`Invalid value provided for the ${\n option.name\n } option - valid values include: ${list(\n (\n option as StringCommandParameter | NumberCommandParameter\n )?.choices?.map(choice => String(choice)) ?? []\n )}; provided: \\${options${\n option.name.includes(\"?\")\n ? `[\"${option.name}\"]`\n : `.${camelCase(option.name)}`\n }}\\`);`}\n </ElseIfClause>\n </Show>\n </Show>\n </>\n )}\n </For>\n <Spacing />\n <For each={command.args} doubleHardline>\n {argument => (\n <>\n <Show when={!argument.optional}>\n <IfStatement condition={code`!${camelCase(argument.name)}`}>\n {code`failures.push(\"Missing required \\\\\"${\n argument.name\n }\\\\\" positional argument\");`}\n </IfStatement>\n <Show\n when={\n (argument.kind === CommandParameterKinds.string ||\n argument.kind === CommandParameterKinds.number) &&\n argument.variadic\n }>\n <ElseIfClause\n condition={code`${camelCase(argument.name)}.length === 0`}>\n {code`failures.push(\"No values were provided to the required ${\n argument.name\n } array positional argument\");`}\n </ElseIfClause>\n </Show>\n </Show>\n <Show when={argument.kind === CommandParameterKinds.number}>\n <Show\n when={(argument as NumberCommandParameter).variadic}\n fallback={\n <IfStatement\n condition={code`${camelCase(\n argument.name\n )} && Number.isNaN(${camelCase(argument.name)})`}>\n {code`failures.push(\"Invalid numeric value provided for the ${\n argument.name\n } positional argument\");`}\n </IfStatement>\n }>\n <IfStatement\n condition={code`${camelCase(argument.name)}.some(value => Number.isNaN(value))`}>\n {code`failures.push(\"Invalid numeric value provided in the ${\n argument.name\n } array positional argument\");`}\n </IfStatement>\n </Show>\n </Show>\n </>\n )}\n </For>\n </>\n );\n}\n"],"mappings":"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"}
@@ -10,15 +10,15 @@ let _powerlines_deepkit_vendor_type = require("@powerlines/deepkit/vendor/type")
10
10
  let _powerlines_plugin_alloy_typescript_components_builtin_file = require("@powerlines/plugin-alloy/typescript/components/builtin-file");
11
11
  let _powerlines_plugin_alloy_typescript_components_tsdoc = require("@powerlines/plugin-alloy/typescript/components/tsdoc");
12
12
 
13
- //#region src/components/spawn-builtin.tsx
13
+ //#region src/components/exec-builtin.tsx
14
14
  /**
15
- * A built-in module for handling child process spawning in Shell Shock.
15
+ * A built-in module for handling command execution in Shell Shock.
16
16
  */
17
- function SpawnBuiltin(props) {
17
+ function ExecBuiltin(props) {
18
18
  const [{ children }, rest] = (0, _alloy_js_core.splitProps)(props, ["children"]);
19
19
  return (0, _alloy_js_core_jsx_runtime.createComponent)(_powerlines_plugin_alloy_typescript_components_builtin_file.BuiltinFile, (0, _alloy_js_core_jsx_runtime.mergeProps)({
20
- id: "spawn",
21
- description: "A module to handle spawning child processes."
20
+ id: "exec",
21
+ description: "A module to handle command execution in a Shell Shock application."
22
22
  }, rest, {
23
23
  get imports() {
24
24
  return (0, defu.default)(rest.imports ?? {}, {
@@ -32,7 +32,7 @@ function SpawnBuiltin(props) {
32
32
  "node:child_process": [{
33
33
  name: "spawn",
34
34
  alias: "_spawn"
35
- }],
35
+ }, "execFileSync"],
36
36
  "node:stream": [{
37
37
  name: "Stream",
38
38
  default: true,
@@ -41,7 +41,14 @@ function SpawnBuiltin(props) {
41
41
  });
42
42
  },
43
43
  get builtinImports() {
44
- return (0, defu.default)(rest.builtinImports ?? {}, { env: ["isWindows"] });
44
+ return (0, defu.default)(rest.builtinImports ?? {}, { env: [
45
+ "isWindows",
46
+ "env",
47
+ {
48
+ name: "Env",
49
+ type: true
50
+ }
51
+ ] });
45
52
  },
46
53
  get children() {
47
54
  return [
@@ -49,11 +56,10 @@ function SpawnBuiltin(props) {
49
56
  name: "resolveCommandEnv",
50
57
  parameters: [{
51
58
  name: "params",
52
- type: "{ argv: string[]; env?: NodeJS.ProcessEnv; baseEnv?: NodeJS.ProcessEnv; }"
59
+ type: "{ argv: string[]; env?: NodeJS.ProcessEnv; }"
53
60
  }],
54
61
  returnType: "NodeJS.ProcessEnv",
55
- children: _alloy_js_core.code`const baseEnv = params.baseEnv ?? process.env;
56
- const argv = params.argv;
62
+ children: _alloy_js_core.code`const argv = params.argv;
57
63
  const shouldSuppressNpmFund = (() => {
58
64
  const cmd = basename(argv[0] ?? "");
59
65
  if (cmd === "npm" || cmd === "npm.cmd" || cmd === "npm.exe") {
@@ -67,17 +73,19 @@ const shouldSuppressNpmFund = (() => {
67
73
  return false;
68
74
  })();
69
75
 
70
- const mergedEnv = params.env ? { ...baseEnv, ...params.env } : { ...baseEnv };
71
- const resolvedEnv = Object.fromEntries(
72
- Object.entries(mergedEnv)
73
- .filter(([, value]) => value !== undefined)
74
- .map(([key, value]) => [key, String(value)])
76
+ const result = Object.fromEntries(
77
+ Object.entries({
78
+ ...env,
79
+ ...(params.env ?? {})
80
+ })
81
+ .filter(([, value]) => value !== undefined)
82
+ .map(([key, value]) => [key, String(value)])
75
83
  );
76
84
  if (shouldSuppressNpmFund) {
77
- resolvedEnv.NPM_CONFIG_FUND ??= "false";
78
- resolvedEnv.npm_config_fund ??= "false";
85
+ result.NPM_CONFIG_FUND ??= "false";
86
+ result.npm_config_fund ??= "false";
79
87
  }
80
- return resolvedEnv;`
88
+ return result; `
81
89
  }),
82
90
  (0, _alloy_js_core_jsx_runtime.createComponent)(_powerlines_plugin_alloy_core_components_spacing.Spacing, {}),
83
91
  (0, _alloy_js_core_jsx_runtime.createComponent)(_alloy_js_typescript.FunctionDeclaration, {
@@ -195,45 +203,6 @@ return command;`
195
203
  : "pipe";
196
204
 
197
205
  return [stdin, "pipe", "pipe"];`
198
- }),
199
- (0, _alloy_js_core_jsx_runtime.createComponent)(_powerlines_plugin_alloy_core_components_spacing.Spacing, {}),
200
- (0, _alloy_js_core_jsx_runtime.createComponent)(_alloy_js_typescript.FunctionDeclaration, {
201
- name: "resolveChildProcessInvocation",
202
- parameters: [{
203
- name: "params",
204
- type: "{ argv: string[]; windowsVerbatimArguments?: boolean; }"
205
- }],
206
- returnType: "{ args: string[]; command: string; usesWindowsExitCodeShim: boolean; windowsHide: true; windowsVerbatimArguments?: boolean; }",
207
- children: _alloy_js_core.code`const finalArgv =
208
- isWindows
209
- ? (resolveNpmArgvForWindows(params.argv) ?? params.argv)
210
- : params.argv;
211
- const resolvedCommand =
212
- finalArgv !== params.argv
213
- ? (finalArgv[0] ?? "")
214
- : resolveCommand(params.argv[0] ?? "");
215
- const useCmdWrapper = isWindowsBatchCommand(resolvedCommand);
216
-
217
- return {
218
- command: useCmdWrapper
219
- ? (process.env.ComSpec ?? "cmd.exe")
220
- : resolvedCommand,
221
- args: useCmdWrapper
222
- ? [
223
- "/d",
224
- "/s",
225
- "/c",
226
- buildCmdExeCommandLine(resolvedCommand, finalArgv.slice(1))
227
- ]
228
- : finalArgv.slice(1),
229
- usesWindowsExitCodeShim:
230
- isWindows &&
231
- (useCmdWrapper || finalArgv !== params.argv),
232
- windowsHide: true,
233
- windowsVerbatimArguments: useCmdWrapper
234
- ? true
235
- : params.windowsVerbatimArguments
236
- };`
237
206
  }),
238
207
  (0, _alloy_js_core_jsx_runtime.createComponent)(_powerlines_plugin_alloy_core_components_spacing.Spacing, {}),
239
208
  (0, _alloy_js_core_jsx_runtime.createComponent)(_alloy_js_typescript.FunctionDeclaration, {
@@ -350,6 +319,7 @@ return false;`
350
319
  }),
351
320
  (0, _alloy_js_core_jsx_runtime.createComponent)(_alloy_js_typescript.InterfaceMember, {
352
321
  name: "timeoutMs",
322
+ optional: true,
353
323
  type: "number"
354
324
  }),
355
325
  (0, _alloy_js_core_jsx_runtime.createComponent)(_powerlines_plugin_alloy_core_components_spacing.Spacing, {}),
@@ -436,23 +406,41 @@ return false;`
436
406
  typeof optionsOrTimeoutMs === "number"
437
407
  ? { timeoutMs: optionsOrTimeoutMs }
438
408
  : optionsOrTimeoutMs;
439
- const { timeoutMs, cwd, input, env, noOutputTimeoutMs } = options;
440
- const hasInput = input !== undefined;
441
- const resolvedEnv = resolveCommandEnv({ argv, env });
442
- const stdio = resolveCommandStdio({ hasInput, preferInherit: true });
443
- const invocation = resolveChildProcessInvocation({
444
- argv,
445
- windowsVerbatimArguments: options.windowsVerbatimArguments
446
- });
409
+ const { timeoutMs = 300000, cwd, input, noOutputTimeoutMs } = options;
410
+
411
+ const resolvedArgv =
412
+ isWindows
413
+ ? (resolveNpmArgvForWindows(argv) ?? argv)
414
+ : argv;
415
+ const resolvedCommand =
416
+ resolvedArgv !== argv
417
+ ? (resolvedArgv[0] ?? "")
418
+ : resolveCommand(argv[0] ?? "");
419
+ const useCmdWrapper = isWindowsBatchCommand(resolvedCommand);
447
420
 
448
- const child = _spawn(invocation.command, invocation.args, {
449
- stdio,
421
+ const child = _spawn(
422
+ useCmdWrapper
423
+ ? (env.COMSPEC ?? "cmd.exe")
424
+ : resolvedCommand,
425
+ useCmdWrapper
426
+ ? [
427
+ "/d",
428
+ "/s",
429
+ "/c",
430
+ buildCmdExeCommandLine(resolvedCommand, resolvedArgv.slice(1))
431
+ ]
432
+ : resolvedArgv.slice(1), {
433
+ stdio: resolveCommandStdio({ hasInput: input !== undefined, preferInherit: true }),
450
434
  cwd,
451
- env: resolvedEnv,
452
- windowsHide: invocation.windowsHide,
453
- windowsVerbatimArguments: invocation.windowsVerbatimArguments,
435
+ env: resolveCommandEnv({ argv, env: options.env }),
436
+ windowsHide: true,
437
+ windowsVerbatimArguments: useCmdWrapper
438
+ ? true
439
+ : options.windowsVerbatimArguments,
454
440
  ...(shouldSpawnWithShell({
455
- resolvedCommand: invocation.command,
441
+ resolvedCommand: useCmdWrapper
442
+ ? (env.COMSPEC ?? "cmd.exe")
443
+ : resolvedCommand,
456
444
  platform: process.platform
457
445
  })
458
446
  ? { shell: true }
@@ -521,7 +509,7 @@ return new Promise((resolve, reject) => {
521
509
  }, timeoutMs >= 0 ? timeoutMs : Number.POSITIVE_INFINITY);
522
510
  armNoOutputTimer();
523
511
 
524
- if (hasInput && child.stdin) {
512
+ if (input !== undefined && child.stdin) {
525
513
  child.stdin.write(input ?? "");
526
514
  child.stdin.end();
527
515
  }
@@ -574,7 +562,7 @@ return new Promise((resolve, reject) => {
574
562
  explicitCode: childExitState?.code ?? code,
575
563
  childExitCode: child.exitCode,
576
564
  resolvedSignal,
577
- usesWindowsExitCodeShim: invocation.usesWindowsExitCodeShim,
565
+ usesWindowsExitCodeShim: isWindows && (useCmdWrapper || resolvedArgv !== argv),
578
566
  timedOut,
579
567
  noOutputTimedOut,
580
568
  killIssuedByTimeout
@@ -638,6 +626,83 @@ return new Promise((resolve, reject) => {
638
626
  waitForExitState();
639
627
  });
640
628
  });`
629
+ }),
630
+ (0, _alloy_js_core_jsx_runtime.createComponent)(_powerlines_plugin_alloy_core_components_spacing.Spacing, {}),
631
+ (0, _alloy_js_core_jsx_runtime.createComponent)(_powerlines_plugin_alloy_typescript_components_tsdoc.TSDoc, {
632
+ heading: "A helper function that executes a command and returns its stdout.",
633
+ get children() {
634
+ return [
635
+ (0, _alloy_js_core_jsx_runtime.createComponent)(_powerlines_plugin_alloy_typescript_components_tsdoc.TSDocParam, {
636
+ name: "argv",
637
+ children: `The command and its arguments to spawn. This is passed directly to the spawn function. Remember that on Windows, commands like \`npm\` or \`pnpm\` will be resolved to their .cmd shims, so you can just pass \`npm\` without worrying about the extension.`
638
+ }),
639
+ (0, _alloy_js_core_jsx_runtime.createComponent)(_powerlines_plugin_alloy_typescript_components_tsdoc.TSDocParam, {
640
+ name: "optionsOrTimeoutMs",
641
+ children: `The options for spawning the command, or a number representing the timeout in milliseconds. This is passed directly to the spawn function. Providing \`-1\` will disable the timeout. If no options or timeout are provided, a default timeout of 5 minutes will be used.`
642
+ }),
643
+ (0, _alloy_js_core_jsx_runtime.createComponent)(_powerlines_plugin_alloy_typescript_components_tsdoc.TSDocReturns, { children: "A promise that resolves with the result of the spawn operation if the command exits with code 0, or rejects with an error if the command exits with a non-zero code or if there is a problem spawning the process." })
644
+ ];
645
+ }
646
+ }),
647
+ (0, _alloy_js_core_jsx_runtime.createComponent)(_alloy_js_typescript.FunctionDeclaration, {
648
+ "export": true,
649
+ async: true,
650
+ name: "exec",
651
+ parameters: [{
652
+ name: "argv",
653
+ type: "string[]"
654
+ }, {
655
+ name: "optionsOrTimeoutMs",
656
+ type: "number | SpawnOptions",
657
+ default: "300000"
658
+ }],
659
+ returnType: "Promise<string>",
660
+ children: _alloy_js_core.code`const spawnResult = await spawn(argv, optionsOrTimeoutMs);
661
+ if (spawnResult.code !== 0) {
662
+ throw Object.assign(new Error(
663
+ \`Command "\${argv.join(" ")}" exited with code \${spawnResult.code} and signal \${spawnResult.signal}\`
664
+ ), spawnResult);
665
+ }
666
+
667
+ return spawnResult.stdout.trim(); `
668
+ }),
669
+ (0, _alloy_js_core_jsx_runtime.createComponent)(_powerlines_plugin_alloy_core_components_spacing.Spacing, {}),
670
+ (0, _alloy_js_core_jsx_runtime.createComponent)(_powerlines_plugin_alloy_typescript_components_tsdoc.TSDoc, {
671
+ heading: "A helper function that executes a command synchronously and returns its stdout. This is a thin wrapper around \\`child_process.execFileSync\\` with some added Windows compatibility handling.",
672
+ get children() {
673
+ return [
674
+ (0, _alloy_js_core_jsx_runtime.createComponent)(_powerlines_plugin_alloy_typescript_components_tsdoc.TSDocParam, {
675
+ name: "argv",
676
+ children: `The command and its arguments to spawn. This is passed directly to \`execFileSync\` after Windows-specific resolution. Remember that on Windows, commands like \`npm\` or \`pnpm\` will be resolved to their .cmd shims, so you can just pass \`npm\` without worrying about the extension.`
677
+ }),
678
+ (0, _alloy_js_core_jsx_runtime.createComponent)(_powerlines_plugin_alloy_typescript_components_tsdoc.TSDocParam, {
679
+ name: "options",
680
+ children: `The options for spawning the command. This is passed directly to \`execFileSync\` after some processing. The timeout option is supported, but note that it will throw an error if the process runs longer than the specified timeout. If no options are provided, a default timeout of 5 minutes will be used.`
681
+ }),
682
+ (0, _alloy_js_core_jsx_runtime.createComponent)(_powerlines_plugin_alloy_typescript_components_tsdoc.TSDocReturns, { children: "The standard output produced by the command if it exits with code 0. If the command exits with a non-zero code or if there is a problem spawning the process, an error will be thrown." })
683
+ ];
684
+ }
685
+ }),
686
+ (0, _alloy_js_core_jsx_runtime.createComponent)(_alloy_js_typescript.FunctionDeclaration, {
687
+ "export": true,
688
+ name: "execSync",
689
+ parameters: [{
690
+ name: "argv",
691
+ type: "string[]"
692
+ }, {
693
+ name: "options",
694
+ type: "SpawnOptions",
695
+ default: "{}"
696
+ }],
697
+ returnType: "string",
698
+ children: _alloy_js_core.code`return execFileSync(argv.length > 0 ? argv[0] : "", argv.slice(1), {
699
+ encoding: "utf8",
700
+ stdio: ["ignore", "pipe", "ignore"],
701
+ timeout: options.timeoutMs ?? 300000,
702
+ env: resolveCommandEnv({ argv, env: options.env }),
703
+ cwd: options.cwd || process.cwd(),
704
+ windowsHide: true
705
+ }).trim(); `
641
706
  }),
642
707
  (0, _alloy_js_core_jsx_runtime.createComponent)(_powerlines_plugin_alloy_core_components_spacing.Spacing, {}),
643
708
  (0, _alloy_js_core_jsx_runtime.createComponent)(_alloy_js_core.Show, {
@@ -652,5 +717,5 @@ return new Promise((resolve, reject) => {
652
717
  }
653
718
 
654
719
  //#endregion
655
- exports.SpawnBuiltin = SpawnBuiltin;
656
- //# sourceMappingURL=spawn-builtin.cjs.map
720
+ exports.ExecBuiltin = ExecBuiltin;
721
+ //# sourceMappingURL=exec-builtin.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exec-builtin.cjs","names":[],"sources":["../../src/components/exec-builtin.tsx"],"sourcesContent":["/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Shell Shock\n\n This code was released as part of the Shell Shock project. Shell Shock\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/shell-shock.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/shell-shock\n Documentation: https://docs.stormsoftware.com/projects/shell-shock\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport { code, Show, splitProps } from \"@alloy-js/core\";\nimport {\n FunctionDeclaration,\n InterfaceDeclaration,\n InterfaceMember,\n VarDeclaration\n} from \"@alloy-js/typescript\";\nimport { ReflectionKind } from \"@powerlines/deepkit/vendor/type\";\n\nimport { Spacing } from \"@powerlines/plugin-alloy/core/components/spacing\";\nimport type { BuiltinFileProps } from \"@powerlines/plugin-alloy/typescript/components/builtin-file\";\nimport { BuiltinFile } from \"@powerlines/plugin-alloy/typescript/components/builtin-file\";\nimport {\n TSDoc,\n TSDocDefaultValue,\n TSDocParam,\n TSDocReturns\n} from \"@powerlines/plugin-alloy/typescript/components/tsdoc\";\nimport defu from \"defu\";\n\nexport interface ExecBuiltinProps extends Omit<\n BuiltinFileProps,\n \"id\" | \"description\"\n> {}\n\n/**\n * A built-in module for handling command execution in Shell Shock.\n */\nexport function ExecBuiltin(props: ExecBuiltinProps) {\n const [{ children }, rest] = splitProps(props, [\"children\"]);\n\n return (\n <BuiltinFile\n id=\"exec\"\n description=\"A module to handle command execution in a Shell Shock application.\"\n {...rest}\n imports={defu(rest.imports ?? {}, {\n \"node:path\": [\"basename\", \"extname\", \"dirname\", \"join\"],\n \"node:fs\": [\"existsSync\"],\n \"node:child_process\": [\n { name: \"spawn\", alias: \"_spawn\" },\n \"execFileSync\"\n ],\n \"node:stream\": [{ name: \"Stream\", default: true, type: true }]\n })}\n builtinImports={defu(rest.builtinImports ?? {}, {\n env: [\"isWindows\", \"env\", { name: \"Env\", type: true }]\n })}>\n <FunctionDeclaration\n name=\"resolveCommandEnv\"\n parameters={[\n {\n name: \"params\",\n type: \"{ argv: string[]; env?: NodeJS.ProcessEnv; }\"\n }\n ]}\n returnType=\"NodeJS.ProcessEnv\">\n {code`const argv = params.argv;\nconst shouldSuppressNpmFund = (() => {\n const cmd = basename(argv[0] ?? \"\");\n if (cmd === \"npm\" || cmd === \"npm.cmd\" || cmd === \"npm.exe\") {\n return true;\n }\n if (cmd === \"node\" || cmd === \"node.exe\") {\n const script = argv[1] ?? \"\";\n\n return script.includes(\"npm-cli.js\");\n }\n return false;\n})();\n\nconst result = Object.fromEntries(\n Object.entries({\n ...env,\n ...(params.env ?? {})\n})\n .filter(([, value]) => value !== undefined)\n .map(([key, value]) => [key, String(value)])\n);\nif (shouldSuppressNpmFund) {\n result.NPM_CONFIG_FUND ??= \"false\";\n result.npm_config_fund ??= \"false\";\n}\nreturn result; `}\n </FunctionDeclaration>\n <Spacing />\n <FunctionDeclaration\n name=\"isWindowsBatchCommand\"\n parameters={[{ name: \"resolvedCommand\", type: \"string\" }]}\n returnType=\"boolean\">\n {code`if (!isWindows) {\n return false;\n}\nconst ext = extname(resolvedCommand).toLowerCase();\n\nreturn ext === \".cmd\" || ext === \".bat\";`}\n </FunctionDeclaration>\n <Spacing />\n <FunctionDeclaration\n name=\"escapeForCmdExe\"\n parameters={[{ name: \"arg\", type: \"string\" }]}\n returnType=\"string\">\n {code`if (/[&|<>^%\\\\\\\\r\\\\\\\\n]/.test(arg)) {\n throw new Error(\n \\`Unsafe Windows cmd.exe argument detected: \\${JSON.stringify(arg)}. \\` +\n \"Pass an explicit shell-wrapper argv at the call site instead.\"\n );\n}\nif (!arg.includes(\" \") && !arg.includes('\"')) {\n return arg;\n}\nreturn \\`\"\\${arg.replace(/\"/g, '\"\"')}\"\\`;`}\n </FunctionDeclaration>\n <Spacing />\n <FunctionDeclaration\n name=\"buildCmdExeCommandLine\"\n parameters={[\n { name: \"resolvedCommand\", type: \"string\" },\n { name: \"args\", type: \"string[]\" }\n ]}\n returnType=\"string\">\n {code`return [escapeForCmdExe(resolvedCommand), ...args.map(escapeForCmdExe)].join(\n \" \"\n);`}\n </FunctionDeclaration>\n <Spacing />\n <FunctionDeclaration\n name=\"resolveNpmArgvForWindows\"\n doc=\"On Windows, Node 18.20.2+ (CVE-2024-27980) rejects spawning .cmd/.bat directly without shell, causing EINVAL. Resolve npm/npx to node + cli script so we spawn node.exe instead of npm.cmd.\"\n parameters={[{ name: \"argv\", type: \"string[]\" }]}\n returnType=\"string[] | null\">\n {code`if (!isWindows || argv.length === 0) {\n return null;\n}\nconst base = basename(argv[0] ?? \"\")\n .toLowerCase()\n .replace(/\\.(?:cmd|exe|bat)$/, \"\");\nconst cliName =\n base === \"npx\" ? \"npx-cli.js\" : base === \"npm\" ? \"npm-cli.js\" : null;\nif (!cliName) {\n return null;\n}\nconst nodeDir = dirname(process.execPath);\nconst cliPath = join(nodeDir, \"node_modules\", \"npm\", \"bin\", cliName);\nif (!existsSync(cliPath)) {\n const command = argv[0] ?? \"\";\n const ext = extname(command).toLowerCase();\n const shimmedCommand = ext ? command : \\`\\${command}.cmd\\`;\n\n return [shimmedCommand, ...argv.slice(1)];\n}\nreturn [process.execPath, cliPath, ...argv.slice(1)];`}\n </FunctionDeclaration>\n <Spacing />\n <FunctionDeclaration\n name=\"resolveCommand\"\n doc=\"Resolves a command for Windows compatibility. On Windows, non-.exe commands (like pnpm, yarn) are resolved to .cmd; npm/npx are handled by resolveNpmArgvForWindows to avoid spawn EINVAL (no direct .cmd).\"\n parameters={[{ name: \"command\", type: \"string\" }]}\n returnType=\"string\">\n {code`if (!isWindows) {\n return command;\n}\nconst base = basename(command).toLowerCase();\nif (extname(base)) {\n return command;\n}\nif ([\"pnpm\", \"yarn\"].includes(base)) {\n return \\`\\${command}.cmd\\`;\n}\nreturn command;`}\n </FunctionDeclaration>\n <Spacing />\n <FunctionDeclaration\n name=\"resolveCommandStdio\"\n parameters={[\n {\n name: \"params\",\n type: \"{ hasInput: boolean; preferInherit: boolean; }\"\n }\n ]}\n returnType='[\"pipe\" | \"inherit\" | \"ignore\", \"pipe\", \"pipe\"]'>\n {code`const stdin = params.hasInput\n ? \"pipe\"\n : params.preferInherit\n ? \"inherit\"\n : \"pipe\";\n\nreturn [stdin, \"pipe\", \"pipe\"];`}\n </FunctionDeclaration>\n <Spacing />\n <FunctionDeclaration\n name=\"resolveProcessExitCode\"\n parameters={[\n {\n name: \"params\",\n type: \"{ explicitCode: number | null | undefined; childExitCode: number | null | undefined; resolvedSignal: NodeJS.Signals | null; usesWindowsExitCodeShim: boolean; timedOut: boolean; noOutputTimedOut: boolean; killIssuedByTimeout: boolean; }\"\n }\n ]}\n returnType=\"number | null\">\n {code`return (\n params.explicitCode ??\n params.childExitCode ??\n (params.usesWindowsExitCodeShim &&\n params.resolvedSignal == null &&\n !params.timedOut &&\n !params.noOutputTimedOut &&\n !params.killIssuedByTimeout\n ? 0\n : null)\n);`}\n </FunctionDeclaration>\n <Spacing />\n <FunctionDeclaration\n name=\"shouldSpawnWithShell\"\n parameters={[\n {\n name: \"params\",\n type: \"{ resolvedCommand: string; platform: NodeJS.Platform; }\"\n }\n ]}\n returnType=\"boolean\">\n {code`// SECURITY: never enable \\`shell\\` for argv-based execution.\n// \\`shell\\` routes through cmd.exe on Windows, which turns untrusted argv values\n// (like chat prompts passed as CLI args) into command-injection primitives.\n// If you need a shell, use an explicit shell-wrapper argv (e.g. \\`cmd.exe /c ...\\`)\n// and validate/escape at the call site.\nvoid params;\nreturn false;`}\n </FunctionDeclaration>\n <Spacing />\n <TSDoc heading=\"The result of a spawn operation.\" />\n <InterfaceDeclaration export name=\"SpawnResult\">\n <TSDoc heading=\"The PID of the spawned child process, if available.\" />\n <InterfaceMember name=\"pid\" optional type=\"number\" />\n <Spacing />\n <TSDoc heading=\"The standard output produced by the child process.\" />\n <InterfaceMember name=\"stdout\" type=\"string\" />\n <Spacing />\n <TSDoc heading=\"The standard error produced by the child process.\" />\n <InterfaceMember name=\"stderr\" type=\"string\" />\n <Spacing />\n <TSDoc heading=\"The exit code of the child process, if available.\" />\n <InterfaceMember name=\"code\" type=\"number | null\" />\n <Spacing />\n <TSDoc heading=\"The signal that caused the child process to terminate, if it was killed by a signal.\" />\n <InterfaceMember name=\"signal\" type=\"NodeJS.Signals | null\" />\n <Spacing />\n <TSDoc heading=\"Whether the child process was killed.\" />\n <InterfaceMember name=\"killed\" type=\"boolean\" />\n <Spacing />\n <TSDoc heading=\"The reason for the child process termination.\" />\n <InterfaceMember\n name=\"termination\"\n type={code`\"exit\" | \"timeout\" | \"no-output-timeout\" | \"signal\"`}\n />\n <Spacing />\n <TSDoc heading=\"Whether the child process timed out due to no output.\" />\n <InterfaceMember name=\"noOutputTimedOut\" optional type=\"boolean\" />\n </InterfaceDeclaration>\n <Spacing />\n <TSDoc heading=\"Options for spawning a child process.\" />\n <InterfaceDeclaration export name=\"SpawnOptions\">\n <TSDoc heading=\"The timeout in milliseconds for the spawn operation. If the process runs longer than this, it will be killed and the spawn promise will reject. This can also be provided as a number directly to the spawn function for convenience. Providing \\`-1\\` will disable the timeout.\">\n <TSDocDefaultValue\n type={ReflectionKind.number}\n defaultValue=\"300000\"\n />\n </TSDoc>\n <InterfaceMember name=\"timeoutMs\" optional type=\"number\" />\n <Spacing />\n <TSDoc heading=\"The current working directory of the child process.\" />\n <InterfaceMember name=\"cwd\" optional type=\"string\" />\n <Spacing />\n <TSDoc heading=\"The input to be passed to the child process.\" />\n <InterfaceMember name=\"input\" optional type=\"string\" />\n <Spacing />\n <TSDoc heading=\"The environment variables for the child process.\" />\n <InterfaceMember name=\"env\" optional type=\"NodeJS.ProcessEnv\" />\n <Spacing />\n <TSDoc heading=\"Whether to pass arguments to the child process verbatim on Windows.\" />\n <InterfaceMember\n name=\"windowsVerbatimArguments\"\n optional\n type=\"boolean\"\n />\n <Spacing />\n <TSDoc heading=\"The timeout in milliseconds for the child process to produce output on stdout or stderr. If the process produces no output for this duration, it will be killed and the spawn promise will reject with a no-output-timeout termination reason.\" />\n <InterfaceMember name=\"noOutputTimeoutMs\" optional type=\"number\" />\n </InterfaceDeclaration>\n <Spacing />\n <VarDeclaration\n const\n name=\"WINDOWS_CLOSE_STATE_SETTLE_TIMEOUT_MS\"\n initializer={code`250`}\n />\n <Spacing />\n <VarDeclaration\n const\n name=\"WINDOWS_CLOSE_STATE_POLL_MS\"\n initializer={code`10`}\n />\n <Spacing />\n <TSDoc heading=\"Spawns a child process with the given arguments and options, returning a promise that resolves with the result of the spawn operation.\">\n <TSDocParam name=\"argv\">\n {\"The command and its arguments to spawn.\"}\n </TSDocParam>\n <TSDocParam name=\"optionsOrTimeoutMs\">\n {`The options for spawning the command, or a number representing the timeout in milliseconds. This allows for a convenient shorthand when only a timeout is needed. Providing \\`-1\\` will disable the timeout. If no options or timeout are provided, a default timeout of 5 minutes will be used.`}\n </TSDocParam>\n <TSDocReturns>\n {\n \"A promise that resolves with the result of the spawn operation, including stdout, stderr, exit code, signal, and termination reason.\"\n }\n </TSDocReturns>\n </TSDoc>\n <FunctionDeclaration\n export\n async\n name=\"spawn\"\n parameters={[\n { name: \"argv\", type: \"string[]\" },\n {\n name: \"optionsOrTimeoutMs\",\n type: \"number | SpawnOptions\",\n default: \"300000\"\n }\n ]}\n returnType=\"Promise<SpawnResult>\">\n {code`const options: SpawnOptions =\n typeof optionsOrTimeoutMs === \"number\"\n ? { timeoutMs: optionsOrTimeoutMs }\n : optionsOrTimeoutMs;\nconst { timeoutMs = 300000, cwd, input, noOutputTimeoutMs } = options;\n\nconst resolvedArgv =\n isWindows\n ? (resolveNpmArgvForWindows(argv) ?? argv)\n : argv;\nconst resolvedCommand =\n resolvedArgv !== argv\n ? (resolvedArgv[0] ?? \"\")\n : resolveCommand(argv[0] ?? \"\");\nconst useCmdWrapper = isWindowsBatchCommand(resolvedCommand);\n\nconst child = _spawn(\n useCmdWrapper\n ? (env.COMSPEC ?? \"cmd.exe\")\n : resolvedCommand,\n useCmdWrapper\n ? [\n \"/d\",\n \"/s\",\n \"/c\",\n buildCmdExeCommandLine(resolvedCommand, resolvedArgv.slice(1))\n ]\n : resolvedArgv.slice(1), {\n stdio: resolveCommandStdio({ hasInput: input !== undefined, preferInherit: true }),\n cwd,\n env: resolveCommandEnv({ argv, env: options.env }),\n windowsHide: true,\n windowsVerbatimArguments: useCmdWrapper\n ? true\n : options.windowsVerbatimArguments,\n ...(shouldSpawnWithShell({\n resolvedCommand: useCmdWrapper\n ? (env.COMSPEC ?? \"cmd.exe\")\n : resolvedCommand,\n platform: process.platform\n })\n ? { shell: true }\n : {})\n});\n\nreturn new Promise((resolve, reject) => {\n let stdout = \"\";\n let stderr = \"\";\n let settled = false;\n let timedOut = false;\n let noOutputTimedOut = false;\n let killIssuedByTimeout = false;\n let childExitState: {\n code: number | null;\n signal: NodeJS.Signals | null;\n } | null = null;\n let closeFallbackTimer: NodeJS.Timeout | null = null;\n let noOutputTimer: NodeJS.Timeout | null = null;\n const shouldTrackOutputTimeout =\n typeof noOutputTimeoutMs === \"number\" &&\n Number.isFinite(noOutputTimeoutMs) &&\n noOutputTimeoutMs > 0;\n\n const clearNoOutputTimer = () => {\n if (!noOutputTimer) {\n return;\n }\n clearTimeout(noOutputTimer);\n noOutputTimer = null;\n };\n\n const clearCloseFallbackTimer = () => {\n if (!closeFallbackTimer) {\n return;\n }\n clearTimeout(closeFallbackTimer);\n closeFallbackTimer = null;\n };\n\n const killChild = () => {\n if (settled || typeof child?.kill !== \"function\") {\n return;\n }\n killIssuedByTimeout = true;\n child.kill(\"SIGKILL\");\n };\n\n const armNoOutputTimer = () => {\n if (!shouldTrackOutputTimeout || settled) {\n return;\n }\n clearNoOutputTimer();\n noOutputTimer = setTimeout(() => {\n if (settled) {\n return;\n }\n noOutputTimedOut = true;\n killChild();\n }, Math.floor(noOutputTimeoutMs));\n };\n\n const timer = setTimeout(() => {\n timedOut = true;\n killChild();\n }, timeoutMs >= 0 ? timeoutMs : Number.POSITIVE_INFINITY);\n armNoOutputTimer();\n\n if (input !== undefined && child.stdin) {\n child.stdin.write(input ?? \"\");\n child.stdin.end();\n }\n\n child.stdout?.on(\"data\", (d: Stream) => {\n stdout += d.toString();\n armNoOutputTimer();\n });\n child.stderr?.on(\"data\", (d: Stream) => {\n stderr += d.toString();\n armNoOutputTimer();\n });\n child.on(\"error\", err => {\n if (settled) {\n return;\n }\n settled = true;\n clearTimeout(timer);\n clearNoOutputTimer();\n clearCloseFallbackTimer();\n reject(err);\n });\n child.on(\"exit\", (code, signal) => {\n childExitState = { code, signal };\n if (settled || closeFallbackTimer) {\n return;\n }\n closeFallbackTimer = setTimeout(() => {\n if (settled) {\n return;\n }\n child.stdout?.destroy();\n child.stderr?.destroy();\n }, 250);\n });\n const resolveFromClose = (\n code: number | null,\n signal: NodeJS.Signals | null\n ) => {\n if (settled) {\n return;\n }\n settled = true;\n clearTimeout(timer);\n clearNoOutputTimer();\n clearCloseFallbackTimer();\n const resolvedSignal =\n childExitState?.signal ?? signal ?? child.signalCode ?? null;\n const resolvedCode = resolveProcessExitCode({\n explicitCode: childExitState?.code ?? code,\n childExitCode: child.exitCode,\n resolvedSignal,\n usesWindowsExitCodeShim: isWindows && (useCmdWrapper || resolvedArgv !== argv),\n timedOut,\n noOutputTimedOut,\n killIssuedByTimeout\n });\n const termination = noOutputTimedOut\n ? \"no-output-timeout\"\n : timedOut\n ? \"timeout\"\n : resolvedSignal != null\n ? \"signal\"\n : \"exit\";\n const normalizedCode =\n termination === \"timeout\" || termination === \"no-output-timeout\"\n ? resolvedCode === 0\n ? 124\n : resolvedCode\n : resolvedCode;\n resolve({\n pid: child.pid ?? undefined,\n stdout,\n stderr,\n code: normalizedCode,\n signal: resolvedSignal,\n killed: child.killed,\n termination,\n noOutputTimedOut\n });\n };\n child.on(\"close\", (code, signal) => {\n if (\n !isWindows ||\n childExitState != null ||\n code != null ||\n signal != null ||\n child.exitCode != null ||\n child.signalCode != null\n ) {\n resolveFromClose(code, signal);\n return;\n }\n\n const startedAt = Date.now();\n const waitForExitState = () => {\n if (settled) {\n return;\n }\n if (\n childExitState != null ||\n child.exitCode != null ||\n child.signalCode != null\n ) {\n resolveFromClose(code, signal);\n return;\n }\n if (Date.now() - startedAt >= WINDOWS_CLOSE_STATE_SETTLE_TIMEOUT_MS) {\n resolveFromClose(code, signal);\n return;\n }\n setTimeout(waitForExitState, WINDOWS_CLOSE_STATE_POLL_MS);\n };\n waitForExitState();\n });\n});`}\n </FunctionDeclaration>\n <Spacing />\n <TSDoc heading=\"A helper function that executes a command and returns its stdout.\">\n <TSDocParam name=\"argv\">\n {`The command and its arguments to spawn. This is passed directly to the spawn function. Remember that on Windows, commands like \\`npm\\` or \\`pnpm\\` will be resolved to their .cmd shims, so you can just pass \\`npm\\` without worrying about the extension.`}\n </TSDocParam>\n <TSDocParam name=\"optionsOrTimeoutMs\">\n {`The options for spawning the command, or a number representing the timeout in milliseconds. This is passed directly to the spawn function. Providing \\`-1\\` will disable the timeout. If no options or timeout are provided, a default timeout of 5 minutes will be used.`}\n </TSDocParam>\n <TSDocReturns>\n {\n \"A promise that resolves with the result of the spawn operation if the command exits with code 0, or rejects with an error if the command exits with a non-zero code or if there is a problem spawning the process.\"\n }\n </TSDocReturns>\n </TSDoc>\n <FunctionDeclaration\n export\n async\n name=\"exec\"\n parameters={[\n { name: \"argv\", type: \"string[]\" },\n {\n name: \"optionsOrTimeoutMs\",\n type: \"number | SpawnOptions\",\n default: \"300000\"\n }\n ]}\n returnType=\"Promise<string>\">\n {code`const spawnResult = await spawn(argv, optionsOrTimeoutMs);\n if (spawnResult.code !== 0) {\n throw Object.assign(new Error(\n \\`Command \"\\${argv.join(\" \")}\" exited with code \\${spawnResult.code} and signal \\${spawnResult.signal}\\`\n ), spawnResult);\n }\n\n return spawnResult.stdout.trim(); `}\n </FunctionDeclaration>\n <Spacing />\n <TSDoc heading=\"A helper function that executes a command synchronously and returns its stdout. This is a thin wrapper around \\`child_process.execFileSync\\` with some added Windows compatibility handling.\">\n <TSDocParam name=\"argv\">\n {`The command and its arguments to spawn. This is passed directly to \\`execFileSync\\` after Windows-specific resolution. Remember that on Windows, commands like \\`npm\\` or \\`pnpm\\` will be resolved to their .cmd shims, so you can just pass \\`npm\\` without worrying about the extension.`}\n </TSDocParam>\n <TSDocParam name=\"options\">\n {`The options for spawning the command. This is passed directly to \\`execFileSync\\` after some processing. The timeout option is supported, but note that it will throw an error if the process runs longer than the specified timeout. If no options are provided, a default timeout of 5 minutes will be used.`}\n </TSDocParam>\n <TSDocReturns>\n {\n \"The standard output produced by the command if it exits with code 0. If the command exits with a non-zero code or if there is a problem spawning the process, an error will be thrown.\"\n }\n </TSDocReturns>\n </TSDoc>\n <FunctionDeclaration\n export\n name=\"execSync\"\n parameters={[\n { name: \"argv\", type: \"string[]\" },\n { name: \"options\", type: \"SpawnOptions\", default: \"{}\" }\n ]}\n returnType=\"string\">\n {code`return execFileSync(argv.length > 0 ? argv[0] : \"\", argv.slice(1), {\n encoding: \"utf8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n timeout: options.timeoutMs ?? 300000,\n env: resolveCommandEnv({ argv, env: options.env }),\n cwd: options.cwd || process.cwd(),\n windowsHide: true\n }).trim(); `}\n </FunctionDeclaration>\n <Spacing />\n\n <Show when={Boolean(children)}>{children}</Show>\n </BuiltinFile>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAgCA,SAAE,YAAiB,OAAA;CACjB,MAAA,CAAA,EACA,YACA,uCAAkB,OAAO,CAAK,WAAW,CAAC;AAC5C,wDAAuB,oHAAA;;EAEvB,aAAiB;EACf,EAAA,MAAA;EACC,IAAK,UAAE;AACP,4BAAA,KAAA,WAAA,EAAA,EAAA;;;;;;;IAED,WAAA,CAAA,aAAA;IACG,sBAAoB,CAAA;KACvB,MAAA;KACK,OAAS;KACP,EAAE,eAAY;;KAEd,MAAA;KACJ,SAAA;KACK,MAAI;KACR,CAAA;IACC,CAAC;;EAEJ,IAAI,iBAAe;AACjB,4BAAY,KAAG,kBAAY,EAAA,EAAA,EACzB,KAAK;IAAC;IAAa;IAAG;KACpB,MAAM;KACN,MAAC;KACF;IAAA,EACF,CAAC;;EAEJ,IAAE,WAAA;AACA,UAAO;oDAAmB,0CAAqB;KAC7C,MAAC;KACF,YAAA,CAAA;MACC,MAAM;MACN,MAAA;MACC,CAAC;KACF,YAAW;KACX,UAAU,mBAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;KA2BnB,CAAM;oDAAoB,0DAAQ,EAAA,CAAA;oDAAA,0CAAA;KAC5B,MAAC;KACT,YAAA,CAAA;MACO,MAAS;MACR,MAAA;MACD,CAAA;KACA,YAAA;KACC,UAAM,mBAAA;;;;;;KAMR,CAAA;oDAAc,0DAAiB,EAAA,CAAA;oDAAa,0CAAA;;KAE3C,YAAa,CAAC;MACb,MAAA;MACD,MAAS;MACT,CAAA;KACC,YAAM;KACN,UAAU,mBAAI;;;;;;;;;;KAUtB,CAAA;oDAAA,0DAAA,EAAA,CAAA;oDAAA,0CAAA;KACQ,MAAK;KACL,YAAA,CAAA;MACD,MAAS;MACT,MAAA;MACC,EAAA;MACA,MAAA;MACE,MAAM;MACP,CAAC;KACF,YAAC;KACD,UAAU,mBAAE;;;KAGjB,CAAA;oDAAA,0DAAA,EAAA,CAAA;oDAAA,0CAAA;KACK,MAAA;KACD,KAAA;KACA,YAAA,CAAA;MACC,MAAM;MACN,MAAQ;MACR,CAAA;KACA,YAAY;KACZ,UAAU,mBAAC;;;;;;;;;;;;;;;;;;;;;KAqBZ,CAAC;oDAAmB,0DAAA,EAAA,CAAA;oDAAA,0CAAA;KACpB,MAAO;KACP,KAAA;KACC,YAAM,CAAA;MACN,MAAK;MACL,MAAA;MACA,CAAA;KACA,YAAW;KACX,UAAQ,mBAAA;;;;;;;;;;;KAWT,CAAA;oDAAS,0DAAA,EAAA,CAAA;oDAAA,0CAAA;KACT,MAAA;KACC,YAAM,CAAA;MACN,MAAA;MACE,MAAA;MACD,CAAC;KACF,YAAY;KACZ,UAAE,mBAAA;;;;;;;KAOH,CAAA;oDAAK,0DAAA,EAAA,CAAA;oDAAA,0CAAA;;KAEJ,YAAY,CAAC;MACb,MAAA;MACD,MAAS;MACT,CAAA;KACC,YAAM;KACN,UAAU,mBAAE;;;;;;;;;;;KAWlB,CAAM;oDAAmB,0DAAM,EAAA,CAAA;oDAAA,0CAAA;KAC9B,MAAO;KACP,YAAO,CAAA;MACA,MAAA;MACJ,MAAA;MACA,CAAI;KACP,YAAA;KACK,UAAA,mBAAA;;;;;;;KAOD,CAAC;oDAAa,0DAAgB,EAAC,CAAA;oDAAkB,4DAAO,EACvD,SAAE,oCACH,CAAC;oDAAC,2CAAA;KACD,UAAU;KACV,MAAM;KACT,IAAO,WAAQ;AACX,aAAK;uDAAsB,4DAAM,EAChC,SAAO,uDACV,CAAA;uDAAuB,sCAAS;QAC5B,MAAA;QACC,UAAE;QACN,MAAA;QACD,CAAA;uDAAS,0DAAA,EAAA,CAAA;uDAAA,4DAAA,EACJ,SAAS,sDACd,CAAA;uDAAqB,sCAAa;QAChC,MAAM;QACN,MAAA;QACA,CAAA;uDAAS,0DAAA,EAAA,CAAA;uDAAA,4DAAA,EACT,SAAM,qDACN,CAAA;uDAAsB,sCAAc;QACpC,MAAS;QACT,MAAM;QACN,CAAA;uDAAsB,0DAAQ,EAAI,CAAC;uDAAU,4DAAA,EAC7C,SAAS,qDACT,CAAA;uDAAuB,sCAAa;QACpC,MAAA;QACA,MAAS;QACT,CAAA;uDAAmB,0DAAY,EAAA,CAAA;uDAAwB,4DAAI,EAC3D,SAAA,wFACA,CAAA;uDAAS,sCAAA;QACT,MAAM;QACN,MAAA;QACA,CAAA;uDAAS,0DAAA,EAAA,CAAA;uDAAA,4DAAA,EACT,SAAM,yCACN,CAAA;uDAAA,sCAAA;QACC,MAAM;QACN,MAAM;QACP,CAAA;uDAAA,0DAAA,EAAA,CAAA;uDAAA,4DAAA,EACA,SAAS,iDACT,CAAA;uDAAuB,sCAAiB;QACxC,MAAA;QACD,MAAA,mBAAA;QACD,CAAA;uDAAS,0DAAA,EAAA,CAAA;uDAAA,4DAAA,EACJ,SAAS,yDACd,CAAA;uDAAqB,sCAAa;QAChC,MAAM;QACJ,UAAA;QACC,MAAM;QACP,CAAC;OAAA;;KAEL,CAAC;oDAAO,0DAAA,EAAA,CAAA;oDAAA,4DAAA,EACP,SAAC,yCACF,CAAC;oDAAU,2CAAA;KACV,UAAO;KACP,MAAC;KACD,IAAC,WAAS;AACT,aAAM;uDAAqB,4DAAI;QAC/B,SAAA;QACA,IAAO,WAAE;AACJ,gEAAyB,wEAAmB;UACjD,IAAA,OAAgB;AACP,kBAAA,+CAAA;;UAET,cAAA;UACM,CAAC;;QAEN,CAAA;uDAAa,sCAAA;QACd,MAAA;QACA,UAAS;QACT,MAAM;QACN,CAAA;uDAAsB,0DAAA,EAAA,CAAA;uDAAiC,4DAAO,EAC/D,SAAA,uDACD,CAAA;uDAAS,sCAAA;QACT,MAAA;QACC,UAAA;QACI,MAAE;QACN,CAAA;uDAAsB,0DAAA,EAAA,CAAA;uDAAA,4DAAA,EACvB,SAAA,gDACA,CAAA;uDAAS,sCAAA;QACT,MAAA;QACC,UAAA;QACI,MAAE;QACN,CAAA;uDAAqB,0DAAA,EAAA,CAAA;uDAAA,4DAAA,EACtB,SAAA,oDACA,CAAA;uDAAS,sCAAA;QACJ,MAAC;QACJ,UAAW;QACR,MAAI;QACN,CAAA;uDAAU,0DAAA,EAAA,CAAA;uDAAA,4DAAA,EACX,SAAW,uEACT,CAAC;uDAAgB,sCAAqB;QACvC,MAAA;QACD,UAAY;QACX,MAAA;QACC,CAAC;uDAAgB,0DAAa,EAAC,CAAA;uDAAkB,4DAAM,EACxD,SAAA,kPACA,CAAA;uDAAY,sCAAA;QACd,MAAK;QACN,UAAA;QACC,MAAA;QACA,CAAA;OAAA;;KAED,CAAC;oDAAY,0DAAA,EAAA,CAAA;oDAAA,qCAAA;KACZ,SAAS;KACT,MAAE;KACF,aAAW,mBAAA;KACZ,CAAC;oDAAoB,0DAAA,EAAA,CAAY;oDAAC,qCAAA;KACjC,SAAI;KACJ,MAAE;KACF,aAAC,mBAAA;KACF,CAAC;oDAAoB,0DAAA,EAAW,CAAC;oDAAC,4DAAA;KACjC,SAAM;KACN,IAAC,WAAA;AACD,aAAS;uDAAE,iEAAmB;QAChC,MAAA;QACE,UAAY;;;QAEd,MAAY;QAChB,UAAA;QACK,CAAA;uDAAyB,mEAAa,EACnC,UAAA,wIACJ,CAAA;OAAA;;KAEC,CAAA;oDAAqB,0CAAA;KACtB,UAAA;KACA,OAAA;;KAEA,YAAc,CAAA;MAClB,MAAA;MACQ,MAAC;MACL,EAAA;MACJ,MAAA;MACI,MAAA;MACI,SAAE;MACH,CAAC;KACF,YAAI;KACJ,UAAA,mBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAgOD,CAAC;oDAAE,0DAAA,EAAA,CAAA;oDAAA,4DAAA;KACF,SAAC;KACD,IAAA,WAAY;AACX,aAAK;uDAAoB,iEAAY;QAClC,MAAE;QACF,UAAM;QACP,CAAC;uDAAoB,iEAAY;QAChC,MAAG;QACL,UAAA;;4HAEA,UAAO,sNACT,CAAA;OAAA;;KAED,CAAA;oDAAiB,0CAAqB;KACrC,UAAC;KACD,OAAO;KACP,MAAE;KACF,YAAY,CAAA;MACV,MAAM;MACN,MAAA;MACD,EAAA;MACC,MAAA;MACA,MAAM;MACN,SAAA;MACD,CAAC;KACF,YAAK;KACN,UAAA,mBAAA;;;;;;;;KAQA,CAAC;oDAAa,0DAAa,EAAK,CAAA;oDAAqB,4DAAM;KAC1D,SAAE;KACF,IAAE,WAAS;AACT,aAAO;uDAAmB,iEAAU;QACpC,MAAK;QACL,UAAY;QACZ,CAAA;uDAAa,iEAAA;QACZ,MAAO;QACV,UAAA;QACD,CAAA;uDAAS,mEAAA,sMAEL,CAAC;OAAA;;KAET,CAAA;oDAAA,0CAAA;KACH,UAAA"}
@@ -0,0 +1,12 @@
1
+ import * as _$_alloy_js_core0 from "@alloy-js/core";
2
+ import { BuiltinFileProps } from "@powerlines/plugin-alloy/typescript/components/builtin-file";
3
+
4
+ //#region src/components/exec-builtin.d.ts
5
+ interface ExecBuiltinProps extends Omit<BuiltinFileProps, "id" | "description"> {}
6
+ /**
7
+ * A built-in module for handling command execution in Shell Shock.
8
+ */
9
+ declare function ExecBuiltin(props: ExecBuiltinProps): _$_alloy_js_core0.Children;
10
+ //#endregion
11
+ export { ExecBuiltin, ExecBuiltinProps };
12
+ //# sourceMappingURL=exec-builtin.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exec-builtin.d.cts","names":[],"sources":["../../src/components/exec-builtin.tsx"],"mappings":";;;;UAsCiB,gBAAA,SAAyB,IAAA,CACxC,gBAAA;;AADF;;iBAQgB,WAAA,CAAY,KAAA,EAAO,gBAAA,GAAgB,iBAAA,CAAA,QAAA"}
@@ -0,0 +1,12 @@
1
+ import * as _$_alloy_js_core0 from "@alloy-js/core";
2
+ import { BuiltinFileProps } from "@powerlines/plugin-alloy/typescript/components/builtin-file";
3
+
4
+ //#region src/components/exec-builtin.d.ts
5
+ interface ExecBuiltinProps extends Omit<BuiltinFileProps, "id" | "description"> {}
6
+ /**
7
+ * A built-in module for handling command execution in Shell Shock.
8
+ */
9
+ declare function ExecBuiltin(props: ExecBuiltinProps): _$_alloy_js_core0.Children;
10
+ //#endregion
11
+ export { ExecBuiltin, ExecBuiltinProps };
12
+ //# sourceMappingURL=exec-builtin.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exec-builtin.d.mts","names":[],"sources":["../../src/components/exec-builtin.tsx"],"mappings":";;;;UAsCiB,gBAAA,SAAyB,IAAA,CACxC,gBAAA;;AADF;;iBAQgB,WAAA,CAAY,KAAA,EAAO,gBAAA,GAAgB,iBAAA,CAAA,QAAA"}