@pixpilot/scaffoldfy 0.57.0 → 0.58.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/cli.cjs +2 -2
- package/dist/cli.js +2 -2
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +15 -1
- package/dist/index.d.ts +15 -1
- package/dist/index.js +1 -1
- package/dist/{run-configuration-sequentially-DvhESKyi.cjs → run-configuration-sequentially-CJCntxv9.cjs} +2 -2
- package/dist/run-configuration-sequentially-Cj1kYWTZ.js +4 -0
- package/dist/{src-C8x8K2Wl.cjs → src-CJxBSFwf.cjs} +1 -1
- package/dist/{src-DeP5BHt6.js → src-Clk5H1_d.js} +1 -1
- package/dist/{tasks-CoJIuLRc.js → tasks-D-wcmZrW.js} +7 -6
- package/dist/{tasks-sQUUhxhX.cjs → tasks-shq57X_d.cjs} +9 -8
- package/package.json +4 -4
- package/schema/scaffoldfy.schema.json +14 -0
- package/dist/run-configuration-sequentially-QttHwxn_.js +0 -4
package/dist/cli.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const e=require(`./configurations-iSmGgORy.cjs`);require(`./initial-config-CESipc-c.cjs`);const t=require(`./tasks-
|
|
2
|
+
const e=require(`./configurations-iSmGgORy.cjs`);require(`./initial-config-CESipc-c.cjs`);const t=require(`./tasks-shq57X_d.cjs`),n=require(`./validate-scaffoldfy-json-DgRRmNSc.cjs`);require(`./scaffoldfy-config-validator-BvNnGMO1.cjs`);const r=require(`./src-CJxBSFwf.cjs`);let i=require(`node:process`);i=e.z(i);let a=require(`node:fs`);a=e.z(a);let o=require(`node:path`);o=e.z(o);let s=require(`commander`);s=e.z(s);const c=1,l=`
|
|
3
3
|
Prompt answers:
|
|
4
4
|
Any prompt in the configuration, including prompts from extended configurations,
|
|
5
5
|
can be answered with a flag named after its id (camelCase or kebab-case):
|
|
@@ -9,7 +9,7 @@ Prompt answers:
|
|
|
9
9
|
--no-keep-example-packages answer a yes/no prompt with no
|
|
10
10
|
--project-name my-app answer any other prompt (or --project-name=my-app)
|
|
11
11
|
|
|
12
|
-
Run with --config <path> --help to list the prompts of a configuration.`;function u(e,t=[]){return[...t,e]}function d(){let e=o.default.join(__dirname,`..`,`package.json`);try{return JSON.parse(a.default.readFileSync(e,`utf-8`)).version??`0.0.0`}catch{return`0.0.0`}}async function f(n,r){r.outputHelp();let s=n.config??``,c=e.C(s),l=c?s:o.default.resolve(i.default.cwd(),s),u=r.getOptionValueSource(`config`)===`cli`;if(!(s===``||l.endsWith(`.ts`)||l.endsWith(`.mts`))){if(!c&&!a.default.existsSync(l)){if(!u)return;e.j(`Config file not found: ${s}`,`error`),i.default.exit(1)}try{let{configs:n=[]}=await e.n(l,{sequential:!0});i.default.stdout.write(`\n${t.p(n)}\n`)}catch(t){e.j(`Could not list the prompts of ${s}`,`error`),t instanceof Error&&e.j(` Error: ${t.message}`,`error`),i.default.exit(1)}}}async function p(s,c){if(s.debug===!0&&e.M(!0),s.help===!0){await f(s,c);return}try{let l=t.m(c.args),u=(s.set??[]).map(t.d),d=n=>{try{t.f(t.g(l,u,n))}catch(t){e.j(t instanceof Error?t.message:String(t),`error`),i.default.exit(1)}},f=[],p,m,h,g,_;if(s.config!=null&&s.config!==``){let t=e.C(s.config),r=t?s.config:o.default.resolve(i.default.cwd(),s.config);if(t||a.default.existsSync(r))if(_=r,r.endsWith(`.ts`)||r.endsWith(`.mts`)){t&&(e.j(`❌ Remote TypeScript config files are not supported`,`error`),e.j(`Only JSON config files can be loaded from a URL`,`info`),i.default.exit(1)),e.j(`Loading tasks from TypeScript file: ${s.config}`,`info`);try{let t=await import(r);f=t.default??t.tasks??[],(!Array.isArray(f)||f.length===0)&&(e.j(`⚠️ No tasks found in TypeScript file or invalid format`,`warn`),e.j(`Expected default export or named export "tasks" with TaskDefinition[]`,`info`))}catch(t){e.j(`Failed to load TypeScript config file: ${s.config}`,`error`),t instanceof Error&&e.j(` Error: ${t.message}`,`error`),i.default.exit(1)}}else try{s.validate!==!1&&(e.O(`Validating task configuration against schema...`),n.r(e.y(await e.u(r)),{silent:!1}).valid||(e.j(``,`error`),e.j(`💡 You can skip validation with --no-validate flag, but this is not recommended.`,`info`),i.default.exit(1)),e.j(`Configuration validated`,`success`));let t=e.g(`Loading config`),a;try{a=await e.n(r,{sequential:!0})}finally{e._(t)}if(a.configs!=null&&a.configs.length>0){let{runConfigurationSequentially:e}=await Promise.resolve().then(()=>require(`./run-configuration-sequentially-
|
|
12
|
+
Run with --config <path> --help to list the prompts of a configuration.`;function u(e,t=[]){return[...t,e]}function d(){let e=o.default.join(__dirname,`..`,`package.json`);try{return JSON.parse(a.default.readFileSync(e,`utf-8`)).version??`0.0.0`}catch{return`0.0.0`}}async function f(n,r){r.outputHelp();let s=n.config??``,c=e.C(s),l=c?s:o.default.resolve(i.default.cwd(),s),u=r.getOptionValueSource(`config`)===`cli`;if(!(s===``||l.endsWith(`.ts`)||l.endsWith(`.mts`))){if(!c&&!a.default.existsSync(l)){if(!u)return;e.j(`Config file not found: ${s}`,`error`),i.default.exit(1)}try{let{configs:n=[]}=await e.n(l,{sequential:!0});i.default.stdout.write(`\n${t.p(n)}\n`)}catch(t){e.j(`Could not list the prompts of ${s}`,`error`),t instanceof Error&&e.j(` Error: ${t.message}`,`error`),i.default.exit(1)}}}async function p(s,c){if(s.debug===!0&&e.M(!0),s.help===!0){await f(s,c);return}try{let l=t.m(c.args),u=(s.set??[]).map(t.d),d=(n,r=[])=>{try{t.f({...t.g(r,n),...t._(l,u,n)})}catch(t){e.j(t instanceof Error?t.message:String(t),`error`),i.default.exit(1)}},f=[],p,m,h,g,_;if(s.config!=null&&s.config!==``){let t=e.C(s.config),r=t?s.config:o.default.resolve(i.default.cwd(),s.config);if(t||a.default.existsSync(r))if(_=r,r.endsWith(`.ts`)||r.endsWith(`.mts`)){t&&(e.j(`❌ Remote TypeScript config files are not supported`,`error`),e.j(`Only JSON config files can be loaded from a URL`,`info`),i.default.exit(1)),e.j(`Loading tasks from TypeScript file: ${s.config}`,`info`);try{let t=await import(r);f=t.default??t.tasks??[],(!Array.isArray(f)||f.length===0)&&(e.j(`⚠️ No tasks found in TypeScript file or invalid format`,`warn`),e.j(`Expected default export or named export "tasks" with TaskDefinition[]`,`info`))}catch(t){e.j(`Failed to load TypeScript config file: ${s.config}`,`error`),t instanceof Error&&e.j(` Error: ${t.message}`,`error`),i.default.exit(1)}}else try{s.validate!==!1&&(e.O(`Validating task configuration against schema...`),n.r(e.y(await e.u(r)),{silent:!1}).valid||(e.j(``,`error`),e.j(`💡 You can skip validation with --no-validate flag, but this is not recommended.`,`info`),i.default.exit(1)),e.j(`Configuration validated`,`success`));let t=e.g(`Loading config`),a;try{a=await e.n(r,{sequential:!0})}finally{e._(t)}if(a.configs!=null&&a.configs.length>0){let{runConfigurationSequentially:e}=await Promise.resolve().then(()=>require(`./run-configuration-sequentially-CJCntxv9.cjs`)),{createInitialConfig:t}=await Promise.resolve().then(()=>require(`./initial-config-CbzFPdT_.cjs`));d(a.configs.flatMap(e=>e.prompts??[]),a.configs),await e(a.configs,{dryRun:s.dryRun??!1,force:s.force??!1,configFilePath:r},t()),i.default.exit(0)}f=a.tasks,p=a.variables,m=a.prompts,h=a.enabled,g=a.transformers,Array.isArray(f)||(e.j(`❌ Invalid config file format`,`error`),e.j(`Expected JSON with { "tasks": [...] } structure`,`info`),i.default.exit(1))}catch(t){e.j(`Failed to load JSON config file: ${s.config}`,`error`),t instanceof Error&&e.j(` Error: ${t.message}`,`error`),i.default.exit(1)}else e.j(`Config file not found: ${s.config}`,`warn`)}let v=m!=null&&m.length>0||p!=null&&p.length>0;f.length===0&&!v&&(e.j(`❌ No tasks defined`,`error`),e.j(`Please provide tasks using one of these methods:`,`info`),e.j(` 1. Create a template-tasks.json file in the current directory`,`info`),e.j(` 2. Create a template-tasks.ts file in the current directory`,`info`),e.j(` 3. Use --config option to specify a different config file`,`info`),e.j(`Example JSON structure:`,`info`),console.log(JSON.stringify({tasks:[{id:`update-package`,name:`Update package.json`,description:`Update package.json with repository information`,required:!0,enabled:!0,type:`update-json`,prompts:[{id:`projectName`,type:`input`,message:`What is your project name?`,default:`my-project`,required:!0},{id:`includeTests`,type:`confirm`,message:`Include test files?`,default:!0}],config:{file:`package.json`,updates:{name:`{{projectName}}`,author:`{{author}}`}}}]},null,2)),i.default.exit(1)),f.length===0?e.j(`Loaded template with 0 tasks (template may only provide prompts/variables for extending)`,`info`):e.j(`Loaded ${f.length} task(s)`,`success`),d(m??[]),await r.t(f,{dryRun:s.dryRun,force:s.force,configFilePath:_,variables:p,prompts:m,configEnabled:h,transformers:g})}catch(t){if(e.j(`❌ CLI execution failed`,`error`),t instanceof Error){e.j(`Error: ${t.message}`,`error`);let n=i.default.env.DEBUG;n!=null&&n!==``&&console.error(t.stack)}else console.error(t);i.default.exit(1)}}function m(){return new s.Command().name(`scaffoldfy`).description(`Automate project setup and configuration with customizable tasks`).version(d()).helpOption(!1).option(`-h, --help`,`Display help; with --config, also list the prompts of that configuration`).option(`--dry-run`,`Run in dry mode without making any changes`).option(`--force`,`Force execution even if checks fail`).option(`--config <path>`,`Path or URL to task configuration file (JSON, JSONC, or TypeScript)`,`./scaffoldfy.json`).option(`--no-validate`,`Skip schema validation of task configuration (validation is enabled by default)`).option(`--debug`,`Enable debug logging for verbose output`).option(`--set <key=value>`,`Answer a prompt up front instead of being asked (repeatable)`,u).allowUnknownOption().allowExcessArguments().addHelpText(`after`,`
|
|
13
13
|
Prompt answers:
|
|
14
14
|
Any prompt in the configuration, including prompts from extended configurations,
|
|
15
15
|
can be answered with a flag named after its id (camelCase or kebab-case):
|
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{C as e,M as t,O as n,_ as r,g as i,j as a,n as o,u as s,y as c}from"./configurations-sRFCjZJV.js";import"./initial-config-Dt0jw4Vs.js";import{
|
|
2
|
+
import{C as e,M as t,O as n,_ as r,g as i,j as a,n as o,u as s,y as c}from"./configurations-sRFCjZJV.js";import"./initial-config-Dt0jw4Vs.js";import{_ as l,d as u,f as d,g as f,m as p,p as m}from"./tasks-D-wcmZrW.js";import{r as h}from"./validate-scaffoldfy-json-DZ1arWdk.js";import"./scaffoldfy-config-validator-D1iJBnRE.js";import{t as g}from"./src-Clk5H1_d.js";import _ from"node:process";import v from"node:path";import{fileURLToPath as y}from"node:url";import b from"node:fs";import{Command as x}from"commander";const S=()=>y(import.meta.url),C=(()=>v.dirname(S()))();function w(e,t=[]){return[...t,e]}function T(){let e=v.join(C,`..`,`package.json`);try{return JSON.parse(b.readFileSync(e,`utf-8`)).version??`0.0.0`}catch{return`0.0.0`}}async function E(t,n){n.outputHelp();let r=t.config??``,i=e(r),s=i?r:v.resolve(_.cwd(),r),c=n.getOptionValueSource(`config`)===`cli`;if(!(r===``||s.endsWith(`.ts`)||s.endsWith(`.mts`))){if(!i&&!b.existsSync(s)){if(!c)return;a(`Config file not found: ${r}`,`error`),_.exit(1)}try{let{configs:e=[]}=await o(s,{sequential:!0});_.stdout.write(`\n${m(e)}\n`)}catch(e){a(`Could not list the prompts of ${r}`,`error`),e instanceof Error&&a(` Error: ${e.message}`,`error`),_.exit(1)}}}async function D(m,y){if(m.debug===!0&&t(!0),m.help===!0){await E(m,y);return}try{let t=p(y.args),x=(m.set??[]).map(u),S=(e,n=[])=>{try{d({...f(n,e),...l(t,x,e)})}catch(e){a(e instanceof Error?e.message:String(e),`error`),_.exit(1)}},C=[],w,T,E,D,O;if(m.config!=null&&m.config!==``){let t=e(m.config),l=t?m.config:v.resolve(_.cwd(),m.config);if(t||b.existsSync(l))if(O=l,l.endsWith(`.ts`)||l.endsWith(`.mts`)){t&&(a(`❌ Remote TypeScript config files are not supported`,`error`),a(`Only JSON config files can be loaded from a URL`,`info`),_.exit(1)),a(`Loading tasks from TypeScript file: ${m.config}`,`info`);try{let e=await import(l);C=e.default??e.tasks??[],(!Array.isArray(C)||C.length===0)&&(a(`⚠️ No tasks found in TypeScript file or invalid format`,`warn`),a(`Expected default export or named export "tasks" with TaskDefinition[]`,`info`))}catch(e){a(`Failed to load TypeScript config file: ${m.config}`,`error`),e instanceof Error&&a(` Error: ${e.message}`,`error`),_.exit(1)}}else try{m.validate!==!1&&(n(`Validating task configuration against schema...`),h(c(await s(l)),{silent:!1}).valid||(a(``,`error`),a(`💡 You can skip validation with --no-validate flag, but this is not recommended.`,`info`),_.exit(1)),a(`Configuration validated`,`success`));let e=i(`Loading config`),t;try{t=await o(l,{sequential:!0})}finally{r(e)}if(t.configs!=null&&t.configs.length>0){let{runConfigurationSequentially:e}=await import(`./run-configuration-sequentially-Cj1kYWTZ.js`),{createInitialConfig:n}=await import(`./initial-config-V9mm6hls.js`);S(t.configs.flatMap(e=>e.prompts??[]),t.configs),await e(t.configs,{dryRun:m.dryRun??!1,force:m.force??!1,configFilePath:l},n()),_.exit(0)}C=t.tasks,w=t.variables,T=t.prompts,E=t.enabled,D=t.transformers,Array.isArray(C)||(a(`❌ Invalid config file format`,`error`),a(`Expected JSON with { "tasks": [...] } structure`,`info`),_.exit(1))}catch(e){a(`Failed to load JSON config file: ${m.config}`,`error`),e instanceof Error&&a(` Error: ${e.message}`,`error`),_.exit(1)}else a(`Config file not found: ${m.config}`,`warn`)}let k=T!=null&&T.length>0||w!=null&&w.length>0;C.length===0&&!k&&(a(`❌ No tasks defined`,`error`),a(`Please provide tasks using one of these methods:`,`info`),a(` 1. Create a template-tasks.json file in the current directory`,`info`),a(` 2. Create a template-tasks.ts file in the current directory`,`info`),a(` 3. Use --config option to specify a different config file`,`info`),a(`Example JSON structure:`,`info`),console.log(JSON.stringify({tasks:[{id:`update-package`,name:`Update package.json`,description:`Update package.json with repository information`,required:!0,enabled:!0,type:`update-json`,prompts:[{id:`projectName`,type:`input`,message:`What is your project name?`,default:`my-project`,required:!0},{id:`includeTests`,type:`confirm`,message:`Include test files?`,default:!0}],config:{file:`package.json`,updates:{name:`{{projectName}}`,author:`{{author}}`}}}]},null,2)),_.exit(1)),C.length===0?a(`Loaded template with 0 tasks (template may only provide prompts/variables for extending)`,`info`):a(`Loaded ${C.length} task(s)`,`success`),S(T??[]),await g(C,{dryRun:m.dryRun,force:m.force,configFilePath:O,variables:w,prompts:T,configEnabled:E,transformers:D})}catch(e){if(a(`❌ CLI execution failed`,`error`),e instanceof Error){a(`Error: ${e.message}`,`error`);let t=_.env.DEBUG;t!=null&&t!==``&&console.error(e.stack)}else console.error(e);_.exit(1)}}function O(){return new x().name(`scaffoldfy`).description(`Automate project setup and configuration with customizable tasks`).version(T()).helpOption(!1).option(`-h, --help`,`Display help; with --config, also list the prompts of that configuration`).option(`--dry-run`,`Run in dry mode without making any changes`).option(`--force`,`Force execution even if checks fail`).option(`--config <path>`,`Path or URL to task configuration file (JSON, JSONC, or TypeScript)`,`./scaffoldfy.json`).option(`--no-validate`,`Skip schema validation of task configuration (validation is enabled by default)`).option(`--debug`,`Enable debug logging for verbose output`).option(`--set <key=value>`,`Answer a prompt up front instead of being asked (repeatable)`,w).allowUnknownOption().allowExcessArguments().addHelpText(`after`,`
|
|
3
3
|
Prompt answers:
|
|
4
4
|
Any prompt in the configuration, including prompts from extended configurations,
|
|
5
5
|
can be answered with a flag named after its id (camelCase or kebab-case):
|
|
@@ -9,4 +9,4 @@ Prompt answers:
|
|
|
9
9
|
--no-keep-example-packages answer a yes/no prompt with no
|
|
10
10
|
--project-name my-app answer any other prompt (or --project-name=my-app)
|
|
11
11
|
|
|
12
|
-
Run with --config <path> --help to list the prompts of a configuration.`).action(
|
|
12
|
+
Run with --config <path> --help to list the prompts of a configuration.`).action(D)}O().parse(_.argv);export{};
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const e=require(`./configurations-iSmGgORy.cjs`);require(`./initial-config-CESipc-c.cjs`);const t=require(`./tasks-
|
|
1
|
+
const e=require(`./configurations-iSmGgORy.cjs`);require(`./initial-config-CESipc-c.cjs`);const t=require(`./tasks-shq57X_d.cjs`),n=require(`./validate-scaffoldfy-json-DgRRmNSc.cjs`);require(`./scaffoldfy-config-validator-BvNnGMO1.cjs`);const r=require(`./src-CJxBSFwf.cjs`);exports.clearConfigurationCache=e.l,exports.clearPlugins=t.S,exports.createTaskPlugin=t.v,exports.displayTasksDiff=t.k,exports.executePluginTask=t.y,exports.getDeleteDiff=t.N,exports.getExecDiff=t.j,exports.getGitInitDiff=t.M,exports.getPlugin=t.C,exports.getPluginForTaskType=t.b,exports.getRegexReplaceDiff=t.F,exports.getRenameDiff=t.P,exports.getReplaceInFileDiff=t.I,exports.getTaskDiff=t.A,exports.getUpdateJsonDiff=t.L,exports.isPluginTaskType=t.x,exports.listPlugins=t.w,exports.loadAndMergeConfiguration=e.t,exports.loadConfiguration=e.c,exports.loadTasksWithInheritance=e.n,exports.mergeConfigurations=e.r,exports.parseAnswerFlags=t.m,exports.registerHooks=t.O,exports.registerPlugin=t.T,exports.resolveAnswerFlags=t.h,exports.resolveConfigAnswers=t.g,exports.runWithTasks=r.t,exports.unregisterPlugin=t.E,exports.validateScaffoldfyJsonFile=n.n;
|
package/dist/index.d.cts
CHANGED
|
@@ -371,8 +371,14 @@ interface ScaffoldfyConfiguration {
|
|
|
371
371
|
transformers?: Transformer[];
|
|
372
372
|
variables?: VariableDefinition[];
|
|
373
373
|
prompts?: PromptDefinition[];
|
|
374
|
+
answers?: Record<string, PromptAnswerValue>;
|
|
374
375
|
tasks?: TaskDefinition[];
|
|
375
376
|
}
|
|
377
|
+
/**
|
|
378
|
+
* Value of a pre-set prompt answer in a configuration's `answers`
|
|
379
|
+
* (checkbox prompts take an array of choice values)
|
|
380
|
+
*/
|
|
381
|
+
type PromptAnswerValue = string | number | boolean | Array<string | number | boolean>;
|
|
376
382
|
/**
|
|
377
383
|
* Plugin interface for custom task types
|
|
378
384
|
*/
|
|
@@ -598,6 +604,14 @@ declare function parseAnswerFlags(args: readonly string[]): AnswerFlag[];
|
|
|
598
604
|
* @throws Error listing every flag that matches no prompt or is missing a value
|
|
599
605
|
*/
|
|
600
606
|
declare function resolveAnswerFlags(flags: readonly AnswerFlag[], prompts: readonly PromptDefinition[]): Record<string, string>;
|
|
607
|
+
/**
|
|
608
|
+
* Resolve the `answers` of every configuration into raw answers keyed by prompt id.
|
|
609
|
+
* Configurations are read in load order (extended configurations first), so the config
|
|
610
|
+
* passed to the CLI overrides the answers of the configs it extends.
|
|
611
|
+
* Keys use the same id matching as answer flags.
|
|
612
|
+
* @throws Error listing answers that match no prompt or have an unsupported value
|
|
613
|
+
*/
|
|
614
|
+
declare function resolveConfigAnswers(configs: readonly ScaffoldfyConfiguration[], prompts?: readonly PromptDefinition[]): Record<string, string>;
|
|
601
615
|
//#endregion
|
|
602
616
|
//#region src/index.d.ts
|
|
603
617
|
/**
|
|
@@ -622,4 +636,4 @@ declare function runWithTasks(customTasks: TaskDefinition[], options?: {
|
|
|
622
636
|
transformers?: Transformer[] | undefined;
|
|
623
637
|
}): Promise<void>;
|
|
624
638
|
//#endregion
|
|
625
|
-
export { type AnswerFlag, type AppendConfig, BasePrompt, CheckboxPrompt, ConditionExpression, ConditionalConfig, ConditionalDefaultConfig, ConfirmPrompt, type CopyConfig, type CreateConfig, CurrentConfigurationContext, DefaultValue, DefaultValueConfig, DefaultValueType, type DeleteConfig, DynamicBooleanValue, EnabledValue, type ExecConfig, ExecFileRuntime, ExecFileValueConfig, ExecutableConfig, type GitInitConfig, InputPrompt, MergeStrategy, type MkdirConfig, type MoveConfig, NumberPrompt, PluginHooks, PromptDefinition, PromptType, type RegexReplaceConfig, type RenameConfig, type ReplaceInFileConfig, RollbackConfig, ScaffoldfyConfiguration, SelectPrompt, TaskDefinition, TaskPlugin, TaskType, type UpdateJsonConfig, VariableDefinition, type WriteConfig, clearConfigurationCache, clearPlugins, createTaskPlugin, displayTasksDiff, executePluginTask, getDeleteDiff, getExecDiff, getGitInitDiff, getPlugin, getPluginForTaskType, getRegexReplaceDiff, getRenameDiff, getReplaceInFileDiff, getTaskDiff, getUpdateJsonDiff, isPluginTaskType, listPlugins, loadAndMergeConfiguration, loadConfiguration, loadTasksWithInheritance, mergeConfigurations, parseAnswerFlags, registerHooks, registerPlugin, resolveAnswerFlags, runWithTasks, unregisterPlugin, validateScaffoldfyJsonFile };
|
|
639
|
+
export { type AnswerFlag, type AppendConfig, BasePrompt, CheckboxPrompt, ConditionExpression, ConditionalConfig, ConditionalDefaultConfig, ConfirmPrompt, type CopyConfig, type CreateConfig, CurrentConfigurationContext, DefaultValue, DefaultValueConfig, DefaultValueType, type DeleteConfig, DynamicBooleanValue, EnabledValue, type ExecConfig, ExecFileRuntime, ExecFileValueConfig, ExecutableConfig, type GitInitConfig, InputPrompt, MergeStrategy, type MkdirConfig, type MoveConfig, NumberPrompt, PluginHooks, PromptAnswerValue, PromptDefinition, PromptType, type RegexReplaceConfig, type RenameConfig, type ReplaceInFileConfig, RollbackConfig, ScaffoldfyConfiguration, SelectPrompt, TaskDefinition, TaskPlugin, TaskType, type UpdateJsonConfig, VariableDefinition, type WriteConfig, clearConfigurationCache, clearPlugins, createTaskPlugin, displayTasksDiff, executePluginTask, getDeleteDiff, getExecDiff, getGitInitDiff, getPlugin, getPluginForTaskType, getRegexReplaceDiff, getRenameDiff, getReplaceInFileDiff, getTaskDiff, getUpdateJsonDiff, isPluginTaskType, listPlugins, loadAndMergeConfiguration, loadConfiguration, loadTasksWithInheritance, mergeConfigurations, parseAnswerFlags, registerHooks, registerPlugin, resolveAnswerFlags, resolveConfigAnswers, runWithTasks, unregisterPlugin, validateScaffoldfyJsonFile };
|
package/dist/index.d.ts
CHANGED
|
@@ -371,8 +371,14 @@ interface ScaffoldfyConfiguration {
|
|
|
371
371
|
transformers?: Transformer[];
|
|
372
372
|
variables?: VariableDefinition[];
|
|
373
373
|
prompts?: PromptDefinition[];
|
|
374
|
+
answers?: Record<string, PromptAnswerValue>;
|
|
374
375
|
tasks?: TaskDefinition[];
|
|
375
376
|
}
|
|
377
|
+
/**
|
|
378
|
+
* Value of a pre-set prompt answer in a configuration's `answers`
|
|
379
|
+
* (checkbox prompts take an array of choice values)
|
|
380
|
+
*/
|
|
381
|
+
type PromptAnswerValue = string | number | boolean | Array<string | number | boolean>;
|
|
376
382
|
/**
|
|
377
383
|
* Plugin interface for custom task types
|
|
378
384
|
*/
|
|
@@ -598,6 +604,14 @@ declare function parseAnswerFlags(args: readonly string[]): AnswerFlag[];
|
|
|
598
604
|
* @throws Error listing every flag that matches no prompt or is missing a value
|
|
599
605
|
*/
|
|
600
606
|
declare function resolveAnswerFlags(flags: readonly AnswerFlag[], prompts: readonly PromptDefinition[]): Record<string, string>;
|
|
607
|
+
/**
|
|
608
|
+
* Resolve the `answers` of every configuration into raw answers keyed by prompt id.
|
|
609
|
+
* Configurations are read in load order (extended configurations first), so the config
|
|
610
|
+
* passed to the CLI overrides the answers of the configs it extends.
|
|
611
|
+
* Keys use the same id matching as answer flags.
|
|
612
|
+
* @throws Error listing answers that match no prompt or have an unsupported value
|
|
613
|
+
*/
|
|
614
|
+
declare function resolveConfigAnswers(configs: readonly ScaffoldfyConfiguration[], prompts?: readonly PromptDefinition[]): Record<string, string>;
|
|
601
615
|
//#endregion
|
|
602
616
|
//#region src/index.d.ts
|
|
603
617
|
/**
|
|
@@ -622,4 +636,4 @@ declare function runWithTasks(customTasks: TaskDefinition[], options?: {
|
|
|
622
636
|
transformers?: Transformer[] | undefined;
|
|
623
637
|
}): Promise<void>;
|
|
624
638
|
//#endregion
|
|
625
|
-
export { type AnswerFlag, type AppendConfig, BasePrompt, CheckboxPrompt, ConditionExpression, ConditionalConfig, ConditionalDefaultConfig, ConfirmPrompt, type CopyConfig, type CreateConfig, CurrentConfigurationContext, DefaultValue, DefaultValueConfig, DefaultValueType, type DeleteConfig, DynamicBooleanValue, EnabledValue, type ExecConfig, ExecFileRuntime, ExecFileValueConfig, ExecutableConfig, type GitInitConfig, InputPrompt, MergeStrategy, type MkdirConfig, type MoveConfig, NumberPrompt, PluginHooks, PromptDefinition, PromptType, type RegexReplaceConfig, type RenameConfig, type ReplaceInFileConfig, RollbackConfig, ScaffoldfyConfiguration, SelectPrompt, TaskDefinition, TaskPlugin, TaskType, type UpdateJsonConfig, VariableDefinition, type WriteConfig, clearConfigurationCache, clearPlugins, createTaskPlugin, displayTasksDiff, executePluginTask, getDeleteDiff, getExecDiff, getGitInitDiff, getPlugin, getPluginForTaskType, getRegexReplaceDiff, getRenameDiff, getReplaceInFileDiff, getTaskDiff, getUpdateJsonDiff, isPluginTaskType, listPlugins, loadAndMergeConfiguration, loadConfiguration, loadTasksWithInheritance, mergeConfigurations, parseAnswerFlags, registerHooks, registerPlugin, resolveAnswerFlags, runWithTasks, unregisterPlugin, validateScaffoldfyJsonFile };
|
|
639
|
+
export { type AnswerFlag, type AppendConfig, BasePrompt, CheckboxPrompt, ConditionExpression, ConditionalConfig, ConditionalDefaultConfig, ConfirmPrompt, type CopyConfig, type CreateConfig, CurrentConfigurationContext, DefaultValue, DefaultValueConfig, DefaultValueType, type DeleteConfig, DynamicBooleanValue, EnabledValue, type ExecConfig, ExecFileRuntime, ExecFileValueConfig, ExecutableConfig, type GitInitConfig, InputPrompt, MergeStrategy, type MkdirConfig, type MoveConfig, NumberPrompt, PluginHooks, PromptAnswerValue, PromptDefinition, PromptType, type RegexReplaceConfig, type RenameConfig, type ReplaceInFileConfig, RollbackConfig, ScaffoldfyConfiguration, SelectPrompt, TaskDefinition, TaskPlugin, TaskType, type UpdateJsonConfig, VariableDefinition, type WriteConfig, clearConfigurationCache, clearPlugins, createTaskPlugin, displayTasksDiff, executePluginTask, getDeleteDiff, getExecDiff, getGitInitDiff, getPlugin, getPluginForTaskType, getRegexReplaceDiff, getRenameDiff, getReplaceInFileDiff, getTaskDiff, getUpdateJsonDiff, isPluginTaskType, listPlugins, loadAndMergeConfiguration, loadConfiguration, loadTasksWithInheritance, mergeConfigurations, parseAnswerFlags, registerHooks, registerPlugin, resolveAnswerFlags, resolveConfigAnswers, runWithTasks, unregisterPlugin, validateScaffoldfyJsonFile };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c as e,l as t,n,r,t as i}from"./configurations-sRFCjZJV.js";import"./initial-config-Dt0jw4Vs.js";import{A as a,C as o,
|
|
1
|
+
import{c as e,l as t,n,r,t as i}from"./configurations-sRFCjZJV.js";import"./initial-config-Dt0jw4Vs.js";import{A as a,C as o,E as s,F as c,I as l,L as u,M as d,N as f,O as p,P as m,S as h,T as g,b as _,g as v,h as y,j as b,k as x,m as S,v as C,w,x as T,y as E}from"./tasks-D-wcmZrW.js";import{n as D}from"./validate-scaffoldfy-json-DZ1arWdk.js";import"./scaffoldfy-config-validator-D1iJBnRE.js";import{t as O}from"./src-Clk5H1_d.js";export{t as clearConfigurationCache,h as clearPlugins,C as createTaskPlugin,x as displayTasksDiff,E as executePluginTask,f as getDeleteDiff,b as getExecDiff,d as getGitInitDiff,o as getPlugin,_ as getPluginForTaskType,c as getRegexReplaceDiff,m as getRenameDiff,l as getReplaceInFileDiff,a as getTaskDiff,u as getUpdateJsonDiff,T as isPluginTaskType,w as listPlugins,i as loadAndMergeConfiguration,e as loadConfiguration,n as loadTasksWithInheritance,r as mergeConfigurations,S as parseAnswerFlags,p as registerHooks,g as registerPlugin,y as resolveAnswerFlags,v as resolveConfigAnswers,O as runWithTasks,s as unregisterPlugin,D as validateScaffoldfyJsonFile};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const e=require(`./configurations-iSmGgORy.cjs`),t=require(`./tasks-
|
|
1
|
+
const e=require(`./configurations-iSmGgORy.cjs`),t=require(`./tasks-shq57X_d.cjs`);let n=require(`node:process`);n=e.z(n);async function r(e,r){let i=e.prompts??[];if(i.length>0){let e=t.c(i);e.length>0&&(console.error(`❌ Prompt validation errors:`),e.forEach(e=>console.error(` - ${e}`)),n.default.exit(1));let a=await t.u(i,await t.l(i,r),r);Object.assign(r,a)}}async function i(t,r){let i=t.variables??[];if(i.length>0){let o=e.i(i);o.length>0&&(console.error(`❌ Variable validation errors:`),o.forEach(e=>console.error(` - ${e}`)),n.default.exit(1));let s=await e.o(i,await e.a(i,r,{skipConditional:!0}),r);Object.assign(r,s),await a(t,r)}}async function a(t,n){let r=t.variables??[];if(r.length===0)return;let i=r.filter(e=>typeof e.value==`object`&&e.value!==null&&!Array.isArray(e.value)?e.value.type===`conditional`:!1);if(i.length>0){let t=await e.o(i,await e.a(i,n),n);Object.assign(n,t)}}async function o(t,n){return await e.E(t.enabled,n)?(await i(t,n),await r(t,n),await a(t,n),await e.E(t.enabled,n)?!0:(e.A(`⊘ Config "${t.name}" became disabled after variable/prompt resolution - skipping tasks`),!1)):(e.A(`⊘ Config "${t.name}" is disabled - skipping`),!1)}async function s(n,r,i={}){e.O(`Running configs with sequential variable/prompt resolution...`),e.O(`Total configs to process: ${n.length}`),e.O(`Registering built-in plugins...`),t.o();let a=[];console.log(``),e.A(`📋 Collecting input...`),console.log(``);for(let t=0;t<n.length;t++){let r=n[t];if(r==null)continue;let s=`=`.repeat(60);if(e.O(`\n${s}`),e.O(`Processing config ${t+1}/${n.length}: "${r.name}"`),e.O(s),e.O(`Current config keys: ${Object.keys(i).join(`, `)}`),await o(r,i)){let t=r.tasks??[];t.length>0&&(e.O(`Found ${t.length} task(s) in config "${r.name}" (will execute later)`),a.push(...t))}}if(e.O(`
|
|
2
2
|
🔧 Validating and filtering all collected tasks...`),a.length===0){e.j(`No tasks found in any config`,`info`);return}console.log(``),e.j(`🛠️ Preparing tasks...`,`info`);let s=await t.r(a,i);if(console.log(``),e.j(`Found ${a.length} tasks (${s.length} enabled)`,`info`),e.j(`All tasks validated successfully`,`success`),s.length===0){e.j(`No enabled tasks to execute`,`info`);return}let c=t.n(s);if(r.dryRun){e.j(`
|
|
3
|
-
🔍 Dry run - showing task changes...`,`info`),await t.
|
|
3
|
+
🔍 Dry run - showing task changes...`,`info`),await t.k(c,i),e.j(`
|
|
4
4
|
🔍 Dry run completed - no changes were made`,`info`),e.j(`Run without --dry-run to apply changes`,`info`);return}console.log(``),e.A(`⚙️ Executing tasks...`),console.log(``),await t.a(c,i,r)}exports.runConfigurationSequentially=s;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{A as e,E as t,O as n,a as r,i,j as a,o}from"./configurations-sRFCjZJV.js";import{a as s,c,k as l,l as u,n as d,o as f,r as p,u as m}from"./tasks-D-wcmZrW.js";import h from"node:process";async function g(e,t){let n=e.prompts??[];if(n.length>0){let e=c(n);e.length>0&&(console.error(`❌ Prompt validation errors:`),e.forEach(e=>console.error(` - ${e}`)),h.exit(1));let r=await m(n,await u(n,t),t);Object.assign(t,r)}}async function _(e,t){let n=e.variables??[];if(n.length>0){let a=i(n);a.length>0&&(console.error(`❌ Variable validation errors:`),a.forEach(e=>console.error(` - ${e}`)),h.exit(1));let s=await o(n,await r(n,t,{skipConditional:!0}),t);Object.assign(t,s),await v(e,t)}}async function v(e,t){let n=e.variables??[];if(n.length===0)return;let i=n.filter(e=>typeof e.value==`object`&&e.value!==null&&!Array.isArray(e.value)?e.value.type===`conditional`:!1);if(i.length>0){let e=await o(i,await r(i,t),t);Object.assign(t,e)}}async function y(n,r){return await t(n.enabled,r)?(await _(n,r),await g(n,r),await v(n,r),await t(n.enabled,r)?!0:(e(`⊘ Config "${n.name}" became disabled after variable/prompt resolution - skipping tasks`),!1)):(e(`⊘ Config "${n.name}" is disabled - skipping`),!1)}async function b(t,r,i={}){n(`Running configs with sequential variable/prompt resolution...`),n(`Total configs to process: ${t.length}`),n(`Registering built-in plugins...`),f();let o=[];console.log(``),e(`📋 Collecting input...`),console.log(``);for(let e=0;e<t.length;e++){let r=t[e];if(r==null)continue;let a=`=`.repeat(60);if(n(`\n${a}`),n(`Processing config ${e+1}/${t.length}: "${r.name}"`),n(a),n(`Current config keys: ${Object.keys(i).join(`, `)}`),await y(r,i)){let e=r.tasks??[];e.length>0&&(n(`Found ${e.length} task(s) in config "${r.name}" (will execute later)`),o.push(...e))}}if(n(`
|
|
2
|
+
🔧 Validating and filtering all collected tasks...`),o.length===0){a(`No tasks found in any config`,`info`);return}console.log(``),a(`🛠️ Preparing tasks...`,`info`);let c=await p(o,i);if(console.log(``),a(`Found ${o.length} tasks (${c.length} enabled)`,`info`),a(`All tasks validated successfully`,`success`),c.length===0){a(`No enabled tasks to execute`,`info`);return}let u=d(c);if(r.dryRun){a(`
|
|
3
|
+
🔍 Dry run - showing task changes...`,`info`),await l(u,i),a(`
|
|
4
|
+
🔍 Dry run completed - no changes were made`,`info`),a(`Run without --dry-run to apply changes`,`info`);return}console.log(``),e(`⚙️ Executing tasks...`),console.log(``),await s(u,i,r)}export{b as runConfigurationSequentially};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const e=require(`./configurations-iSmGgORy.cjs`),t=require(`./initial-config-CESipc-c.cjs`),n=require(`./tasks-
|
|
1
|
+
const e=require(`./configurations-iSmGgORy.cjs`),t=require(`./initial-config-CESipc-c.cjs`),n=require(`./tasks-shq57X_d.cjs`),r=require(`./validate-scaffoldfy-json-DgRRmNSc.cjs`);let i=require(`node:process`);i=e.z(i);async function a(a,o){let s=t.t();if(!await e.E(o.configEnabled,s,{lazy:!0})){e.A(`⊘ Template is disabled - skipping all execution`);return}o.transformers!==void 0&&o.transformers.length>0&&(e.O(`Registering ${o.transformers.length} transformer(s)...`),e.s.registerAll(o.transformers)),e.O(`Registering built-in plugins...`),n.o(),e.O(`Validating task configurations...`);let c=n.t(a);c.length>0&&(r.t(c),i.default.exit(1)),e.O(`All tasks validated successfully`);let l=a.filter(n=>e.T(n.enabled,t.t(),{lazy:!0}));e.O(`Resolving task dependencies...`);let u=n.i(l);e.O(`Sorted ${u.length} task(s) by dependencies`),e.A(`Welcome! Let's execute your tasks.`),o.dryRun&&e.P(`🔍 DRY RUN MODE - No changes will be made`),e.A(`This will execute your project tasks based on the defined configuration.`);let d=s,f=[...o.variables??[]];if(f.length>0){let t=e.i(f);t.length>0&&(e.j(`❌ Variable validation errors:`,`error`),t.forEach(t=>e.j(` - ${t}`,`error`)),i.default.exit(1)),e.O(`Resolving variable values...`);let n=await e.o(f,await e.a(f,d,{skipConditional:!0}),d);Object.assign(d,n),Object.keys(n).length>0&&(e.O(`Resolved ${Object.keys(n).length} variable(s)`),e.O(`Variable values: ${JSON.stringify(n)}`))}let p=o.prompts??[],m=[...p];if(m.length>0){let t=n.c(m);t.length>0&&(e.j(`❌ Prompt validation errors:`,`error`),t.forEach(t=>e.j(` - ${t}`,`error`)),i.default.exit(1)),e.O(`Resolving prompt default values...`);let r=await n.l(m,d);if(p.length>0){e.A(`📋 Collecting prompts (available to all tasks):`);let t=await n.u(p,r,d);Object.assign(d,t)}}if(f.length>0){let t=f.filter(e=>typeof e.value==`object`&&e.value!==null&&!Array.isArray(e.value)?e.value.type===`conditional`:!1);if(t.length>0){e.O(`Re-resolving conditional variables with prompt values...`);let n=await e.o(t,await e.a(t,d),d);Object.assign(d,n),Object.keys(n).length>0&&e.O(`Resolved ${Object.keys(n).length} conditional variable(s)`)}}if(!await e.E(o.configEnabled,d)){e.A(`⊘ Template is disabled after variable resolution - skipping all execution`);return}let h=[];for(let t of u)t.$configEnabled!=null&&!await e.E(t.$configEnabled,d)||await e.E(t.enabled,d)&&h.push(t);if(e.j(`${h.length} of ${u.length} task(s) enabled for execution`,`info`),o.dryRun){await n.k(h,d),e.A(`🔍 Dry run completed - no changes were made`),e.A(`Run without --dry-run to apply changes`);return}e.O(`Calling beforeAll hook...`),await n.D(`beforeAll`,d);let g=h.length,_=0,v=0,y=[],b=[];for(let t=0;t<h.length;t++){let r=h[t];r!=null&&(e.O(`Calling beforeTask hook for task: ${r.name}`),await n.D(`beforeTask`,r,d),await n.s(r,d,t+1,g,o.dryRun)?(_++,y.push(r.id),e.O(`Calling afterTask hook for task: ${r.name}`),await n.D(`afterTask`,r,d)):(await e.w(r.required,d)&&(v++,b.push(r.name)),e.O(`Calling onError hook for task: ${r.name}`),await n.D(`onError`,Error(`Task ${r.name} failed`),r),e.P(`⚠️ Task "${r.name}" failed, continuing with remaining tasks...`)))}v>0&&(e.j(`\n❌ Task execution completed with ${v} error(s)`,`error`),e.j(`Completed: ${_}/${g} tasks`,`info`),e.j(`Failed tasks: ${b.join(`, `)}`,`error`),i.default.exit(1)),e.O(`Calling afterAll hook...`),await n.D(`afterAll`,d),e.N(`✅ All tasks completed successfully!`),e.N(` Completed: ${_}/${g} tasks`)}const o=i.default.argv.includes(`--dry-run`),s=i.default.argv.includes(`--force`);async function c(t,n){try{await a(t,{dryRun:n?.dryRun??o,force:n?.force??s,configFilePath:n?.configFilePath??void 0,...n?.variables!=null&&{variables:n.variables},...n?.prompts!=null&&{prompts:n.prompts},...n?.configEnabled!=null&&{configEnabled:n.configEnabled},...n?.transformers!=null&&{transformers:n.transformers}})}catch(t){e.j(`❌ Task execution failed`,`error`),t instanceof Error?(e.j(`Error: ${t.message}`,`error`),i.default.env.DEBUG!=null&&console.error(t.stack)):console.error(t),i.default.exit(1)}}Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return c}});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{A as e,E as t,N as n,O as r,P as i,T as a,a as o,i as s,j as c,o as l,s as u,w as d}from"./configurations-sRFCjZJV.js";import{t as f}from"./initial-config-Dt0jw4Vs.js";import{
|
|
1
|
+
import{A as e,E as t,N as n,O as r,P as i,T as a,a as o,i as s,j as c,o as l,s as u,w as d}from"./configurations-sRFCjZJV.js";import{t as f}from"./initial-config-Dt0jw4Vs.js";import{D as p,c as m,i as h,k as g,l as _,o as v,s as y,t as b,u as x}from"./tasks-D-wcmZrW.js";import{t as S}from"./validate-scaffoldfy-json-DZ1arWdk.js";import C from"node:process";async function w(w,T){let E=f();if(!await t(T.configEnabled,E,{lazy:!0})){e(`⊘ Template is disabled - skipping all execution`);return}T.transformers!==void 0&&T.transformers.length>0&&(r(`Registering ${T.transformers.length} transformer(s)...`),u.registerAll(T.transformers)),r(`Registering built-in plugins...`),v(),r(`Validating task configurations...`);let D=b(w);D.length>0&&(S(D),C.exit(1)),r(`All tasks validated successfully`);let O=w.filter(e=>a(e.enabled,f(),{lazy:!0}));r(`Resolving task dependencies...`);let k=h(O);r(`Sorted ${k.length} task(s) by dependencies`),e(`Welcome! Let's execute your tasks.`),T.dryRun&&i(`🔍 DRY RUN MODE - No changes will be made`),e(`This will execute your project tasks based on the defined configuration.`);let A=E,j=[...T.variables??[]];if(j.length>0){let e=s(j);e.length>0&&(c(`❌ Variable validation errors:`,`error`),e.forEach(e=>c(` - ${e}`,`error`)),C.exit(1)),r(`Resolving variable values...`);let t=await l(j,await o(j,A,{skipConditional:!0}),A);Object.assign(A,t),Object.keys(t).length>0&&(r(`Resolved ${Object.keys(t).length} variable(s)`),r(`Variable values: ${JSON.stringify(t)}`))}let M=T.prompts??[],N=[...M];if(N.length>0){let t=m(N);t.length>0&&(c(`❌ Prompt validation errors:`,`error`),t.forEach(e=>c(` - ${e}`,`error`)),C.exit(1)),r(`Resolving prompt default values...`);let n=await _(N,A);if(M.length>0){e(`📋 Collecting prompts (available to all tasks):`);let t=await x(M,n,A);Object.assign(A,t)}}if(j.length>0){let e=j.filter(e=>typeof e.value==`object`&&e.value!==null&&!Array.isArray(e.value)?e.value.type===`conditional`:!1);if(e.length>0){r(`Re-resolving conditional variables with prompt values...`);let t=await l(e,await o(e,A),A);Object.assign(A,t),Object.keys(t).length>0&&r(`Resolved ${Object.keys(t).length} conditional variable(s)`)}}if(!await t(T.configEnabled,A)){e(`⊘ Template is disabled after variable resolution - skipping all execution`);return}let P=[];for(let e of k)e.$configEnabled!=null&&!await t(e.$configEnabled,A)||await t(e.enabled,A)&&P.push(e);if(c(`${P.length} of ${k.length} task(s) enabled for execution`,`info`),T.dryRun){await g(P,A),e(`🔍 Dry run completed - no changes were made`),e(`Run without --dry-run to apply changes`);return}r(`Calling beforeAll hook...`),await p(`beforeAll`,A);let F=P.length,I=0,L=0,R=[],z=[];for(let e=0;e<P.length;e++){let t=P[e];t!=null&&(r(`Calling beforeTask hook for task: ${t.name}`),await p(`beforeTask`,t,A),await y(t,A,e+1,F,T.dryRun)?(I++,R.push(t.id),r(`Calling afterTask hook for task: ${t.name}`),await p(`afterTask`,t,A)):(await d(t.required,A)&&(L++,z.push(t.name)),r(`Calling onError hook for task: ${t.name}`),await p(`onError`,Error(`Task ${t.name} failed`),t),i(`⚠️ Task "${t.name}" failed, continuing with remaining tasks...`)))}L>0&&(c(`\n❌ Task execution completed with ${L} error(s)`,`error`),c(`Completed: ${I}/${F} tasks`,`info`),c(`Failed tasks: ${z.join(`, `)}`,`error`),C.exit(1)),r(`Calling afterAll hook...`),await p(`afterAll`,A),n(`✅ All tasks completed successfully!`),n(` Completed: ${I}/${F} tasks`)}const T=C.argv.includes(`--dry-run`),E=C.argv.includes(`--force`);async function D(e,t){try{await w(e,{dryRun:t?.dryRun??T,force:t?.force??E,configFilePath:t?.configFilePath??void 0,...t?.variables!=null&&{variables:t.variables},...t?.prompts!=null&&{prompts:t.prompts},...t?.configEnabled!=null&&{configEnabled:t.configEnabled},...t?.transformers!=null&&{transformers:t.transformers}})}catch(e){c(`❌ Task execution failed`,`error`),e instanceof Error?(c(`Error: ${e.message}`,`error`),C.env.DEBUG!=null&&console.error(e.stack)):console.error(e),C.exit(1)}}export{D as t};
|
|
@@ -18,9 +18,10 @@ import{D as e,E as t,F as n,I as r,L as i,O as a,P as o,R as s,d as c,f as l,j a
|
|
|
18
18
|
`).length>10;return C(i)?`${b.blue}File: ${t.file}${b.reset}\n${b.green}+ Would append content${b.reset}\n${b.gray}Content preview:${b.reset}\n${o}${s?`
|
|
19
19
|
...`:``}`:`${b.blue}File: ${t.file}${b.reset}\n${b.green}+ New file would be created with content${b.reset}\n${b.gray}Content preview:${b.reset}\n${o}${s?`
|
|
20
20
|
...`:``}`}catch(e){return`${b.red}✗ Error: ${e instanceof Error?e.message:String(e)}${b.reset}`}}function M(t,n){if(t.condition!=null&&t.condition!==``&&!e(t.condition,n))return`${b.yellow}⊘ Condition not met - task would be skipped${b.reset}`;let r=t.paths.map(e=>c(e,n)).filter(e=>C(e));return r.length===0?`${b.cyan}→ No files/directories to delete${b.reset}`:`${b.red}Would delete:${b.reset}\n${r.map(e=>`${b.red} - ${e}${b.reset}`).join(`
|
|
21
|
-
`)}`}function
|
|
22
|
-
`)}function F(t,n){if(t.condition!=null&&t.condition!==``&&!e(t.condition,n))return`${b.yellow}⊘ Condition not met - task would be skipped${b.reset}`;let r=
|
|
23
|
-
`));return i}function ke(e,t,n){let r=n.map(e=>e.id),i=q(e,n);for(let[e,n]of t)i[K(e,r)??e]=n;return i}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
`)&&(f=t.newline!==!1)}catch{}d&&f?await X(a,`\n${l}`):await X(a,l),u(`Appended content to ${t.file}`,`success`)}const Ke={name:`append`,version:`1.0.0`,taskTypes:[`append`],execute:async(e,t,n)=>{n.dryRun||await Ge(e.config,t,e)}},Z=v(_.copyFile),qe=v(_.stat),Q=v(_.mkdir),Je=v(_.readdir);async function $(e,t){await Q(t,{recursive:!0});let n=await Je(e,{withFileTypes:!0});await Promise.all(n.map(async n=>{let r=g.join(e,n.name),i=g.join(t,n.name);n.isDirectory()?await $(r,i):await Z(r,i)}))}async function Ye(t,n){if(t.condition!=null&&t.condition!==``&&!e(t.condition,n)){u(`Condition not met, skipping copy task`,`info`);return}let r=g.join(h.cwd(),c(t.from,n)),i=g.join(h.cwd(),c(t.to,n)),a;try{a=await qe(r)}catch{u(`Source path does not exist: ${r}`,`warn`);return}await Q(g.dirname(i),{recursive:!0}),a.isDirectory()?(await $(r,i),u(`Copied directory ${t.from} to ${t.to}`,`success`)):(await Z(r,i),u(`Copied file ${t.from} to ${t.to}`,`success`))}const Xe={name:`copy`,version:`1.0.0`,taskTypes:[`copy`],execute:async(e,t,n)=>{n.dryRun||await Ye(e.config,t)}},Ze=v(_.writeFile);async function Qe(t,r,i){if(t.condition!=null&&t.condition!==``&&!e(t.condition,r)){u(`Condition not met, skipping create task`,`info`);return}let a=c(t.file,r),o=g.join(h.cwd(),a);if(_.existsSync(o)){u(`File already exists, skipping: ${a}`,`info`);return}let s=A(t);if(!s.isValid)throw s.error?.includes(`cannot have both`)?n.createHasBothTemplateAndFile():n.createMissingTemplateOrFile();let l=await j(t,r,i),d=g.dirname(o);_.existsSync(d)||_.mkdirSync(d,{recursive:!0}),await Ze(o,l),u(`Created file: ${a}`,`success`)}const $e={name:`create`,version:`1.0.0`,taskTypes:[`create`],execute:async(e,t,n)=>{n.dryRun||await Qe(e.config,t,e)}};async function et(t,n){let{paths:r,condition:i}=t;if(i!=null&&i!==``){if(!n){u(`Condition specified but no config provided, skipping deletion`,`warn`);return}if(!e(i,n)){u(`Condition not met, skipping deletion`,`info`);return}}for(let e of r){let t=n==null?e:c(e,n),r=g.join(h.cwd(),t);_.existsSync(r)&&_.rmSync(r,{recursive:!0,force:!0})}}const tt={name:`delete`,version:`1.0.0`,taskTypes:[`delete`],execute:async(e,t,n)=>{n.dryRun||await et(e.config,t)}};async function nt(t,n,r){t.condition!=null&&t.condition!==``&&!e(t.condition,n)||await d({file:t.file,...t.runtime&&{runtime:t.runtime},...t.args&&{args:t.args},...t.parameters&&{parameters:t.parameters},...t.cwd!=null&&t.cwd.trim()!==``&&{cwd:t.cwd},...r?.$sourceUrl!=null&&r.$sourceUrl.trim()!==``&&{sourceUrl:r.$sourceUrl},captureOutput:!1},n)}const rt={name:`exec-file`,version:`1.0.0`,taskTypes:[`exec-file`],execute:async(e,t,n)=>{n.dryRun||await nt(e.config,t,e)}};async function it(t,n){if(t.condition!=null&&t.condition!==``){if(!n){u(`Condition specified but no config provided, skipping exec`,`warn`);return}if(!e(t.condition,n)){u(`Condition not met, skipping exec task`,`info`);return}}let r=e=>n==null?e:c(e,n),i=N(r(t.command),t.args?.map(r)),o=t.cwd==null?h.cwd():g.join(h.cwd(),r(t.cwd));a(`Executing: ${i}`),y(i,{cwd:o,stdio:`inherit`})}const at={name:`exec`,version:`1.0.0`,taskTypes:[`exec`],execute:async(e,t,n)=>{n.dryRun||await it(e.config,t)}};async function ot(t,n){if(t.condition!=null&&t.condition!==``){if(!n){u(`Condition specified but no config provided, skipping git-init`,`warn`);return}if(!e(t.condition,n)){u(`Condition not met, skipping git-init task`,`info`);return}}if(t.removeExisting){let e=g.join(h.cwd(),`.git`);_.existsSync(e)&&_.rmSync(e,{recursive:!0,force:!0})}if(y(`git init`,{stdio:`inherit`}),t.initialCommit){let e=t.message??`Initial commit`;y(`git add .`,{stdio:`inherit`}),y(`git commit -m "${e}"`,{stdio:`inherit`})}}const st={name:`git-init`,version:`1.0.0`,taskTypes:[`git-init`],execute:async(e,t,n)=>{n.dryRun||await ot(e.config,t)}},ct=v(_.mkdir);async function lt(t,n){if(t.condition!=null&&t.condition!==``&&!e(t.condition,n)){u(`Condition not met, skipping mkdir task`,`info`);return}await ct(g.join(h.cwd(),c(t.path,n)),{recursive:!0}),u(`Created directory: ${t.path}`,`success`)}const ut={name:`mkdir`,version:`1.0.0`,taskTypes:[`mkdir`],execute:async(e,t,n)=>{n.dryRun||await lt(e.config,t)}},dt=v(_.rename),ft=v(_.stat),pt=v(_.mkdir);async function mt(t,n){if(t.condition!=null&&t.condition!==``&&!e(t.condition,n)){u(`Condition not met, skipping move task`,`info`);return}let r=g.join(h.cwd(),c(t.from,n)),i=g.join(h.cwd(),c(t.to,n));try{await ft(r)}catch{u(`Source path does not exist: ${r}`,`warn`);return}await pt(g.dirname(i),{recursive:!0}),await dt(r,i),u(`Moved ${t.from} to ${t.to}`,`success`)}const ht={name:`move`,version:`1.0.0`,taskTypes:[`move`],execute:async(e,t,n)=>{n.dryRun||await mt(e.config,t)}},gt=v(_.readFile),_t=v(_.writeFile);async function vt(t,n){if(t.condition!=null&&t.condition!==``&&!e(t.condition,n)){u(`Condition not met, skipping regex-replace task`,`info`);return}let r=g.join(h.cwd(),c(t.file,n)),{pattern:i}=t,a=t.flags??``,o=t.replacement||``,s=await gt(r,`utf-8`),l=new RegExp(i,a);s=s.replace(l,c(o,n)),await _t(r,s)}const yt={name:`regex-replace`,version:`1.0.0`,taskTypes:[`regex-replace`],execute:async(e,t,n)=>{n.dryRun||await vt(e.config,t)}},bt=v(_.rename);async function xt(t,n){if(t.condition!=null&&t.condition!==``&&!e(t.condition,n)){u(`Condition not met, skipping rename task`,`info`);return}let r=g.join(h.cwd(),c(t.from,n)),i=g.join(h.cwd(),c(t.to,n));if(!_.existsSync(r)){u(`Source path does not exist: ${r}`,`warn`);return}await bt(r,i)}const St={name:`rename`,version:`1.0.0`,taskTypes:[`rename`],execute:async(e,t,n)=>{n.dryRun||await xt(e.config,t)}},Ct=v(_.readFile),wt=v(_.writeFile);async function Tt(t,n){if(t.condition!=null&&t.condition!==``&&!e(t.condition,n)){u(`Condition not met, skipping replace-in-file task`,`info`);return}let r=g.join(h.cwd(),c(t.file,n)),{replacements:i}=t;if(!_.existsSync(r)){u(`File not found: ${r}, skipping`,`warn`);return}let a=await Ct(r,`utf-8`);for(let{find:e,replace:t}of i){let r=c(t,n);a=a.replace(new RegExp(e,`gu`),r)}await wt(r,a)}const Et={name:`replace-in-file`,version:`1.0.0`,taskTypes:[`replace-in-file`],execute:async(e,t,n)=>{n.dryRun||await Tt(e.config,t)}},Dt=v(_.readFile),Ot=v(_.writeFile);async function kt(t,n){if(t.condition!=null&&t.condition!==``&&!e(t.condition,n)){u(`Condition not met, skipping update-json task`,`info`);return}let r=g.join(h.cwd(),c(t.file,n)),{updates:i}=t,a=ne(await Dt(r,`utf-8`));function o(e){if(typeof e==`string`)return c(e,n);if(Array.isArray(e))return e.map(e=>o(e));if(typeof e==`object`&&e){let t={};for(let[n,r]of Object.entries(e))t[n]=o(r);return t}return e}for(let[e,t]of Object.entries(i)){let n=o(t);e.includes(`.`)?m(a,e,n):a[e]=n}await Ot(r,`${JSON.stringify(a,null,2)}\n`)}const At={name:`update-json`,version:`1.0.0`,taskTypes:[`update-json`],execute:async(e,t,n)=>{n.dryRun||await kt(e.config,t)}},jt=v(_.writeFile);async function Mt(t,r,i){let{allowCreate:a=!0}=t;if(t.condition!=null&&t.condition!==``&&!e(t.condition,r)){u(`Condition not met, skipping write task`,`info`);return}let o=c(t.file,r),s=g.join(h.cwd(),o);if(!_.existsSync(s)){if(a===!1)throw Error(`Write task failed: file does not exist (${o})`);u(`File not found, creating new file: ${o}`,`info`)}let l=A(t);if(!l.isValid)throw l.error?.includes(`cannot have both`)?n.templateHasBothTemplateAndFile():n.templateMissingTemplateOrFile();let d=await j(t,r,i),f=g.dirname(s);_.existsSync(f)||_.mkdirSync(f,{recursive:!0}),await jt(s,d)}const Nt={name:`write`,version:`1.0.0`,taskTypes:[`write`],execute:async(e,t,n)=>{n.dryRun||await Mt(e.config,t,e)}};function Pt(){U(`update-json`)||(V(At),V(Nt),V($e),V(yt),V(Et),V(tt),V(St),V(st),V(at),V(rt),V(ht),V(Xe),V(Ke),V(ut))}async function Ft(e,t,n=!1){if(Pt(),n){u(`[DRY RUN] Would execute: ${e.name}`,`info`);return}if(U(e.type)){await W(e,t,{dryRun:n});return}throw TypeError(`Unknown task type: ${e.type}`)}async function It(e,t,n,r,i=!1){try{return u(`[${n}/${r}] Running: ${e.name}...`,`info`),await Ft(e,t,i),u(`[${n}/${r}] Completed: ${e.name}...`,`success`),!0}catch(t){return u(`Failed: ${e.name}`,`error`),t instanceof Error&&(u(` Reason: ${t.message}`,`error`),t.stack!=null&&h.env.DEBUG!=null&&console.error(t.stack)),!1}}async function Lt(e,t,n){await B(`beforeAll`,t);let r=0,i=0,a=[];for(let s=0;s<e.length;s++){let c=e[s];c!=null&&(await B(`beforeTask`,c,t),await It(c,t,s+1,e.length,n.dryRun)?(r++,await B(`afterTask`,c,t)):(await p(c.required,t)&&(i++,a.push(c.name)),await B(`onError`,Error(`Task ${c.name} failed`),c),o(`⚠️ Task "${c.name}" failed, continuing with remaining tasks...`)))}await B(`afterAll`,t),i>0&&(u(`\n❌ Task execution completed with ${i} error(s)`,`error`),u(`Completed: ${r}/${e.length} tasks`,`info`),u(`Failed tasks: ${a.join(`, `)}`,`error`),h.exit(1)),u(`Completed: ${r}/${e.length} tasks`,`success`)}function Rt(e){let t=[],n=new Set,r=new Set,a=new Map(e.map(e=>[e.id,e]));function o(e){if(n.has(e))return;if(r.has(e))throw s.forTaskDependency(e);r.add(e);let c=a.get(e);if(!c)throw i.forId(e);if(c.dependencies)for(let e of c.dependencies)o(e);r.delete(e),n.add(e),t.push(c)}for(let t of e)n.has(t.id)||o(t.id);return t}function zt(e){let t=[],n=e.config,r=typeof n.template==`string`?n.template:void 0,i=typeof n.templateFile==`string`?n.templateFile:void 0,a=A({...r!==void 0&&{template:r},...i!==void 0&&{templateFile:i}});return!a.isValid&&a.error!=null&&a.error!==``&&t.push(`Task "${e.id}" (${e.name}): ${a.error}`),(n.file==null||n.file===``)&&t.push(`Task "${e.id}" (${e.name}): Write task requires "file" property to specify the output file path`),t}async function Bt(e,n){let r=Ht(e);r.length>0&&(console.error(`❌ Task validation errors:`),r.forEach(e=>console.error(` - ${e}`)),h.exit(1));let i=[];for(let r of e)await t(r.enabled,n)&&i.push(r);return i}function Vt(e){return Rt(e)}function Ht(e){let t=[];for(let n of e)if(!U(n.type))t.push(`Task "${n.id}" (${n.name}): Unknown task type "${n.type}"`);else if(n.type===`write`){let e=zt(n);t.push(...e)}return t}export{F as A,Te as C,Se as D,B as E,D as F,T as I,M,he as N,xe as O,E as P,we as S,Ce as T,De as _,Lt as a,U as b,He as c,Re as d,Ie as f,ke as g,q as h,Rt as i,P as j,I as k,Ve as l,Oe as m,Vt as n,Pt as o,Ne as p,Bt as r,It as s,Ht as t,Be as u,W as v,V as w,Ee as x,H as y};
|
|
21
|
+
`)}`}function N(t,n){if(t.condition!=null&&t.condition!==``&&!e(t.condition,n))return`${b.yellow}⊘ Condition not met - task would be skipped${b.reset}`;let r=c(t.from,n),i=c(t.to,n);return C(r)?C(i)?`${b.yellow}⚠ Destination already exists: ${i}${b.reset}\n${b.cyan}Would rename: ${r} → ${i}${b.reset}`:`${b.cyan}Would rename: ${r} → ${i}${b.reset}`:`${b.red}✗ Source not found: ${r}${b.reset}`}function he(t,n){if(t.condition!=null&&t.condition!==``&&!e(t.condition,n))return`${b.yellow}⊘ Condition not met - task would be skipped${b.reset}`;let r=c(t.from,n),i=c(t.to,n);return C(r)?C(i)?`${b.yellow}⚠ Destination already exists: ${i}${b.reset}\n${b.cyan}Would move: ${r} → ${i}${b.reset}`:`${b.cyan}Would move: ${r} → ${i}${b.reset}`:`${b.red}✗ Source not found: ${r}${b.reset}`}function ge(t,n){if(t.condition!=null&&t.condition!==``&&!e(t.condition,n))return`${b.yellow}⊘ Condition not met - task would be skipped${b.reset}`;let r=c(t.from,n),i=c(t.to,n);if(!C(r))return`${b.red}✗ Source not found: ${r}${b.reset}`;let a=`file`;return C(i)?`${b.yellow}⚠ Destination already exists: ${i}${b.reset}\n${b.cyan}Would copy ${a}: ${r} → ${i}${b.reset}`:`${b.cyan}Would copy ${a}: ${r} → ${i}${b.reset}`}function _e(t,n){if(t.condition!=null&&t.condition!==``&&!e(t.condition,n))return`${b.yellow}⊘ Condition not met - task would be skipped${b.reset}`;let r=c(t.path,n);return C(r)?`${b.cyan}→ Directory already exists: ${r}${b.reset}`:`${b.green}+ Would create directory: ${r}${b.reset}`}const ve=/^[\w+,./:=@-]+$/u;function ye(e){return ve.test(e)?e:h.platform===`win32`?`"${e.replace(/(?<slashes>\\*)"/gu,`$<slashes>$<slashes>\\"`).replace(/(?<slashes>\\+)$/u,`$<slashes>$<slashes>`)}"`:`'${e.replace(/'/gu,String.raw`'\''`)}'`}function be(e,t){let n=(t??[]).filter(e=>e!==``).map(ye);return n.length>0?`${e} ${n.join(` `)}`:e}function P(e){if(e.condition!=null&&e.condition!==``)return`${b.yellow}⊘ Condition check skipped in dry-run${b.reset}`;let t=C(`.git`),n=[];if(e.removeExisting&&t&&n.push(`${b.red}Would remove existing .git directory${b.reset}`),n.push(`${b.green}Would initialize git repository${b.reset}`),e.initialCommit){let t=e.message??`Initial commit`;n.push(`${b.green}Would create initial commit: "${t}"${b.reset}`)}return n.join(`
|
|
22
|
+
`)}function F(t,n){if(t.condition!=null&&t.condition!==``&&!e(t.condition,n))return`${b.yellow}⊘ Condition not met - task would be skipped${b.reset}`;let r=be(c(t.command,n),t.args?.map(e=>c(e,n))),i=t.cwd==null?h.cwd():c(t.cwd,n);return`${b.yellow}Would execute:${b.reset}\n${b.cyan} Command: ${r}${b.reset}\n${b.cyan} Working directory: ${i}${b.reset}`}async function I(e,t){try{switch(e.type){case`update-json`:return await T(e.config,t);case`write`:return await fe(e.config,t);case`create`:return await pe(e.config,t,e);case`regex-replace`:return await E(e.config,t);case`replace-in-file`:return await D(e.config,t);case`delete`:return M(e.config,t);case`rename`:return N(e.config,t);case`move`:return he(e.config,t);case`copy`:return ge(e.config,t);case`append`:return await me(e.config,t,e);case`mkdir`:return _e(e.config,t);case`git-init`:return P(e.config);case`exec`:return F(e.config,t);case`exec-file`:return F(e.config,t);default:{let t=e.type;return`${b.yellow}⚠ Diff not available for task type: ${t}${b.reset}`}}}catch(e){return`${b.red}✗ Error generating diff: ${e instanceof Error?e.message:String(e)}${b.reset}`}}async function xe(e,t){console.log(`${b.blue}═══════════════════════════════════════════════════════${b.reset}`),console.log(`${b.blue} DRY RUN - Preview of changes${b.reset}`),console.log(`${b.blue}═══════════════════════════════════════════════════════${b.reset}`);for(let n of e){console.log(`${b.cyan}▶ Task: ${n.name}${b.reset}`),n.description!=null&&n.description!==``&&console.log(`${b.gray} ${n.description}${b.reset}`);let e=await I(n,t);console.log(e),console.log(`${b.gray}${`─`.repeat(55)}${b.reset}`)}console.log(`${b.blue}═══════════════════════════════════════════════════════${b.reset}`),console.log(`${b.yellow} No changes were applied (dry-run mode)${b.reset}`),console.log(`${b.blue}═══════════════════════════════════════════════════════${b.reset}`)}const L=new Map,R={},z=new Map;function Se(e){e.beforeAll!=null&&(R.beforeAll=e.beforeAll),e.afterAll!=null&&(R.afterAll=e.afterAll),e.beforeTask!=null&&(R.beforeTask=e.beforeTask),e.afterTask!=null&&(R.afterTask=e.afterTask),e.onError!=null&&(R.onError=e.onError)}async function B(e,...t){let n=R[e];if(n!=null)try{e===`beforeAll`||e===`afterAll`?await n(t[0]):(e===`beforeTask`||e===`afterTask`||e===`onError`)&&await n(t[0],t[1])}catch(t){u(`Error in ${e} hook: ${t instanceof Error?t.message:String(t)}`,`error`)}}function V(e){if(e.name==null||e.name===``)throw TypeError(`Plugin name is required`);if(!Array.isArray(e.taskTypes)||e.taskTypes.length===0)throw TypeError(`Plugin ${e.name} must define at least one task type`);if(typeof e.execute!=`function`)throw TypeError(`Plugin ${e.name} must provide an execute function`);if(L.has(e.name))throw TypeError(`Plugin ${e.name} is already registered`);for(let t of e.taskTypes)if(z.has(t)){let e=z.get(t);throw TypeError(`Task type "${t}" is already registered by plugin "${e}"`)}L.set(e.name,e);for(let t of e.taskTypes)z.set(t,e.name);a(`Registered plugin: ${e.name}${e.version==null?``:` v${e.version}`}`)}function Ce(e){let t=L.get(e);if(t!=null){for(let e of t.taskTypes)z.delete(e);L.delete(e)}}function we(e){return L.get(e)}function Te(){return Array.from(L.keys())}function Ee(){L.clear(),z.clear()}function H(e){let t=z.get(e);if(t!=null)return L.get(t)}function U(e){return z.has(e)}async function W(e,t,n){let r=H(e.type);if(r==null)throw TypeError(`No plugin found for task type: ${e.type}`);await r.execute(e,t,n)}function De(e,t,n,r){return{name:e,...r?.version!=null&&{version:r.version},taskTypes:[t],execute:n,...r?.getDiff!=null&&{getDiff:r.getDiff},...r?.validate!=null&&{validate:r.validate}}}function G(e){return e.replace(/[-_]/gu,``).toLowerCase()}function K(e,t){if(t.includes(e))return e;let n=G(e);return t.find(e=>G(e)===n)}function Oe(e){let t=[];for(let n=0;n<e.length;n++){let r=e[n]??``;if(!r.startsWith(`--`)||r.length===2)throw Error(r.startsWith(`-`)?`Unknown option "${r}"`:`Unexpected argument "${r}". Prompt answers are passed as --<promptId> <value>`);let i=r.indexOf(`=`),a=i===-1?r:r.slice(0,i),o=a.slice(2);if(o===``)throw Error(`Unknown option "${r}"`);let s;if(i!==-1)s=r.slice(i+1);else{let t=e[n+1];t!=null&&!t.startsWith(`-`)&&(s=t,n++)}t.push({flag:a,name:o,value:s})}return t}function q(e,t){let n=t.map(e=>e.id),r=new Map(t.map(e=>[e.id,e.type])),i={},a=[],o=[];for(let{flag:t,name:s,value:c}of e){let e=K(s,n);if(e!=null){c===void 0?r.get(e)===`confirm`?i[e]=`true`:o.push(`Option ${t} needs a value, e.g. ${t}=<value>`):i[e]=c;continue}let l=c===void 0&&s.startsWith(`no-`)?K(s.slice(3),n):void 0;l==null?a.push(t):r.get(l)===`confirm`?i[l]=`false`:o.push(`Option ${t} only works for yes/no (confirm) prompts`)}if(a.length>0&&o.unshift(`Unknown option(s) ${a.join(`, `)}: no prompt with a matching id. ${n.length>0?`Prompts in this configuration: ${n.join(`, `)}`:`This configuration has no prompts`}`),o.length>0)throw Error(o.join(`
|
|
23
|
+
`));return i}function ke(e,t,n){let r=n.map(e=>e.id),i=q(e,n);for(let[e,n]of t)i[K(e,r)??e]=n;return i}function Ae(e){if(Array.isArray(e))return e.map(String).join(`,`);if([`string`,`number`,`boolean`].includes(typeof e))return String(e)}function J(e,t){let n={},r=[];for(let i of e)for(let[e,a]of Object.entries(i.answers??{})){let o=K(e,t),s=Ae(a);o==null?r.push(`Answer "${e}" in config "${i.name}" matches no prompt`):s===void 0?r.push(`Answer "${e}" in config "${i.name}" must be a string, number, boolean or array`):n[o]=s}return{answers:n,problems:r}}function je(e,t=e.flatMap(e=>e.prompts??[])){let n=t.map(e=>e.id),{answers:r,problems:i}=J(e,n);if(i.length>0)throw i.push(n.length>0?`Prompts in this configuration: ${n.join(`, `)}`:`This configuration has no prompts`),Error(i.join(`
|
|
24
|
+
`));return r}const Me={input:`<value>`,password:`<value>`,select:`<value>`,number:`<number>`,checkbox:`<values>`};function Ne(e){return e.type===`confirm`?`--[no-]${e.id}`:`--${e.id} ${Me[e.type]}`}function Pe(e,t){let n=[];(e.type===`select`||e.type===`checkbox`)&&n.push(`choices: ${e.choices.map(e=>String(e.value)).join(`, `)}`);let r=e.default;return([`string`,`number`,`boolean`].includes(typeof r)||Array.isArray(r))&&n.push(`default: ${String(r)}`),e.required===!0&&n.push(`required`),typeof e.enabled==`object`?n.push(e.enabled.type===`condition`?`when: ${e.enabled.value}`:`conditional`):e.enabled===!1&&n.push(`disabled`),t!==void 0&&n.push(`answered in config: ${t}`),n.length>0?`${e.message} [${n.join(`; `)}]`:e.message}function Fe(e){let{answers:t}=J(e,e.flatMap(e=>(e.prompts??[]).map(e=>e.id))),n=e.map(e=>({name:e.name,items:(e.prompts??[]).map(e=>({flag:Ne(e),description:Pe(e,t[e.id])}))})).filter(e=>e.items.length>0);if(n.length===0)return`Prompts:
|
|
25
|
+
This configuration has no prompts.`;let r=Math.min(40,Math.max(...n.flatMap(e=>e.items.map(e=>e.flag.length)))),i=[`Prompts (answer with a flag instead of being asked; kebab-case ids work too):`];for(let e of n){i.push(``,` ${e.name}:`);for(let t of e.items)i.push(` ${t.flag.padEnd(r)} ${t.description}`)}return i.join(`
|
|
26
|
+
`)}const Ie=new Set([`true`,`1`,`yes`,`y`]),Le=new Set([`false`,`0`,`no`,`n`]);let Y=new Map;function Re(e){Y=new Map(Object.entries(e))}function ze(e){return Y.get(e)}function Be(e){let t=e.indexOf(`=`);if(t<=0)throw Error(`Invalid --set value "${e}". Expected format: key=value`);return[e.slice(0,t).trim(),e.slice(t+1)]}function Ve(e,t){switch(e.type){case`confirm`:{let n=t.trim().toLowerCase();if(Ie.has(n))return!0;if(Le.has(n))return!1;throw r.invalidValue(e.id,t,`expected true or false`)}case`number`:{let n=Number(t);if(t.trim()===``||Number.isNaN(n))throw r.invalidValue(e.id,t,`expected a number`);return n}case`select`:{let n=e.choices.find(e=>String(e.value)===t);if(n==null)throw r.invalidValue(e.id,t,`expected one of ${e.choices.map(e=>String(e.value)).join(`, `)}`);return n.value}case`checkbox`:return t.split(`,`).map(e=>e.trim()).filter(e=>e!==``).map(t=>{let n=e.choices.find(e=>String(e.value)===t);if(n==null)throw r.invalidValue(e.id,t,`expected one of ${e.choices.map(e=>String(e.value)).join(`, `)}`);return n.value});case`input`:case`password`:return t;default:throw r.unknownType(e.type)}}async function X(e,t,n,r){if(e!==void 0)return l(e,{id:t,contextType:`Prompt`,...n!=null&&{context:n},...r?.$sourceUrl!=null&&{sourceUrl:r.$sourceUrl}})}async function He(e,n=new Map,i={}){let a={};if(e.length===0)return a;for(let o of e){if(o.$configEnabled!=null&&!await t(o.$configEnabled,{...i,...a}))continue;let e={...i,...a};if(!await t(o.enabled,e)){a[o.id]=void 0;continue}let s=ze(o.id);if(s!==void 0){let t=Ve(o,s);if(typeof t==`string`&&t.trim()===``&&await p(o.required,e)===!0)throw r.required(o.id);o.transformers!==void 0&&(t=await f.apply(o.transformers,t,e)),u(`${o.message}: ${String(t)} (preset)`,`info`),a[o.id]=t;continue}try{let t,i=n.get(o.id);switch(o.default!==void 0&&(i=await X(o.default,o.id,e,o)),i!==void 0&&o.transformers!==void 0&&(i=await f.apply(o.transformers,i,e)),o.type){case`input`:{let n={message:o.message};i!==void 0&&(n.default=String(i));let a=await p(o.required,e);if(a!==void 0&&(n.required=a),t=await ae(n),a&&(t==null||typeof t==`string`&&t.trim()===``))throw u(`${o.message} is required`,`error`),r.required(o.id);break}case`password`:if(t=await se({message:o.message,mask:`*`}),await p(o.required,e)&&(t==null||typeof t==`string`&&t.trim()===``))throw u(`${o.message} is required`,`error`),r.required(o.id);break;case`number`:{let n={message:o.message};i!==void 0&&(n.default=Number(i));let a=await p(o.required,e);if(a!==void 0&&(n.required=a),o.min!==void 0&&(n.min=o.min),o.max!==void 0&&(n.max=o.max),t=await oe(n),a&&t==null)throw u(`${o.message} is required`,`error`),r.required(o.id);break}case`select`:{let e={message:o.message,choices:o.choices.map(e=>({name:e.name,value:e.value}))};i!==void 0&&(e.default=i),t=await ce(e);break}case`checkbox`:{let n={message:o.message,choices:o.choices.map(e=>({name:e.name,value:e.value}))};i!==void 0&&(n.default=i);let r=await p(o.required,e);r!==void 0&&(n.required=r),t=await re(n);break}case`confirm`:{let e=i===void 0?!1:!!i;t=await ie({message:o.message,default:e});break}default:throw u(`Unknown prompt type: ${o.type}`,`error`),r.unknownType(o.type)}o.transformers!==void 0&&(i!==void 0&&(t===i||String(t)===String(i))||(t=await f.apply(o.transformers,t,{...e,...a}))),a[o.id]=t}catch(e){throw e instanceof Error&&u(`Failed to collect prompt "${o.id}": ${e.message}`,`error`),e}}return a}async function Ue(e,t){let n=new Map,r=e.map(async e=>{if(e.default!==void 0){let r=await X(e.default,e.id,t,e);r!==void 0&&n.set(e.id,r)}});return await Promise.all(r),n}function We(e){let t=[],n=new Set;for(let r of e){if(n.has(r.id)&&t.push(`Duplicate prompt ID: ${r.id}`),n.add(r.id),/^[a-zA-Z_$][a-zA-Z0-9_$]*$/u.test(r.id)||t.push(`Invalid prompt ID "${r.id}": must be a valid JavaScript identifier (start with letter, underscore, or $, followed by letters, digits, underscores, or $)`),(!r.message||r.message.trim()===``)&&t.push(`Prompt "${r.id}" must have a non-empty message`),r.type===`select`||r.type===`checkbox`){r.choices.length===0&&t.push(`${r.type===`select`?`Select`:`Checkbox`} prompt "${r.id}" must have at least one choice`);for(let e of r.choices)(!e.name||e.name.trim()===``)&&t.push(`${r.type===`select`?`Select`:`Checkbox`} prompt "${r.id}" has a choice with empty name`),e.value===void 0&&t.push(`${r.type===`select`?`Select`:`Checkbox`} prompt "${r.id}" has a choice with undefined value`)}r.type===`number`&&r.min!==void 0&&r.max!==void 0&&r.min>r.max&&t.push(`Number prompt "${r.id}" has min greater than max`)}return t}const Z=v(_.appendFile),Ge=v(_.readFile),Ke=v(_.stat);async function qe(t,r,i){if(t.condition!=null&&t.condition!==``&&!e(t.condition,r)){u(`Condition not met, skipping append task`,`info`);return}let a=g.join(h.cwd(),c(t.file,r)),o={};t.content==null?t.template!=null&&(o.template=t.template):o.template=t.content,t.templateFile!=null&&(o.templateFile=t.templateFile);let s=A(o);if(!s.isValid)throw s.error?.includes(`cannot have both`)?n.templateHasBothTemplateAndFile():n.templateMissingTemplateOrFile();let l=await j(o,r,i),d=!1,f=!1;try{await Ke(a),d=!0;let e=await Ge(a,`utf-8`);e.length>0&&!e.endsWith(`
|
|
27
|
+
`)&&(f=t.newline!==!1)}catch{}d&&f?await Z(a,`\n${l}`):await Z(a,l),u(`Appended content to ${t.file}`,`success`)}const Je={name:`append`,version:`1.0.0`,taskTypes:[`append`],execute:async(e,t,n)=>{n.dryRun||await qe(e.config,t,e)}},Q=v(_.copyFile),Ye=v(_.stat),$=v(_.mkdir),Xe=v(_.readdir);async function Ze(e,t){await $(t,{recursive:!0});let n=await Xe(e,{withFileTypes:!0});await Promise.all(n.map(async n=>{let r=g.join(e,n.name),i=g.join(t,n.name);n.isDirectory()?await Ze(r,i):await Q(r,i)}))}async function Qe(t,n){if(t.condition!=null&&t.condition!==``&&!e(t.condition,n)){u(`Condition not met, skipping copy task`,`info`);return}let r=g.join(h.cwd(),c(t.from,n)),i=g.join(h.cwd(),c(t.to,n)),a;try{a=await Ye(r)}catch{u(`Source path does not exist: ${r}`,`warn`);return}await $(g.dirname(i),{recursive:!0}),a.isDirectory()?(await Ze(r,i),u(`Copied directory ${t.from} to ${t.to}`,`success`)):(await Q(r,i),u(`Copied file ${t.from} to ${t.to}`,`success`))}const $e={name:`copy`,version:`1.0.0`,taskTypes:[`copy`],execute:async(e,t,n)=>{n.dryRun||await Qe(e.config,t)}},et=v(_.writeFile);async function tt(t,r,i){if(t.condition!=null&&t.condition!==``&&!e(t.condition,r)){u(`Condition not met, skipping create task`,`info`);return}let a=c(t.file,r),o=g.join(h.cwd(),a);if(_.existsSync(o)){u(`File already exists, skipping: ${a}`,`info`);return}let s=A(t);if(!s.isValid)throw s.error?.includes(`cannot have both`)?n.createHasBothTemplateAndFile():n.createMissingTemplateOrFile();let l=await j(t,r,i),d=g.dirname(o);_.existsSync(d)||_.mkdirSync(d,{recursive:!0}),await et(o,l),u(`Created file: ${a}`,`success`)}const nt={name:`create`,version:`1.0.0`,taskTypes:[`create`],execute:async(e,t,n)=>{n.dryRun||await tt(e.config,t,e)}};async function rt(t,n){let{paths:r,condition:i}=t;if(i!=null&&i!==``){if(!n){u(`Condition specified but no config provided, skipping deletion`,`warn`);return}if(!e(i,n)){u(`Condition not met, skipping deletion`,`info`);return}}for(let e of r){let t=n==null?e:c(e,n),r=g.join(h.cwd(),t);_.existsSync(r)&&_.rmSync(r,{recursive:!0,force:!0})}}const it={name:`delete`,version:`1.0.0`,taskTypes:[`delete`],execute:async(e,t,n)=>{n.dryRun||await rt(e.config,t)}};async function at(t,n,r){t.condition!=null&&t.condition!==``&&!e(t.condition,n)||await d({file:t.file,...t.runtime&&{runtime:t.runtime},...t.args&&{args:t.args},...t.parameters&&{parameters:t.parameters},...t.cwd!=null&&t.cwd.trim()!==``&&{cwd:t.cwd},...r?.$sourceUrl!=null&&r.$sourceUrl.trim()!==``&&{sourceUrl:r.$sourceUrl},captureOutput:!1},n)}const ot={name:`exec-file`,version:`1.0.0`,taskTypes:[`exec-file`],execute:async(e,t,n)=>{n.dryRun||await at(e.config,t,e)}};async function st(t,n){if(t.condition!=null&&t.condition!==``){if(!n){u(`Condition specified but no config provided, skipping exec`,`warn`);return}if(!e(t.condition,n)){u(`Condition not met, skipping exec task`,`info`);return}}let r=e=>n==null?e:c(e,n),i=be(r(t.command),t.args?.map(r)),o=t.cwd==null?h.cwd():g.join(h.cwd(),r(t.cwd));a(`Executing: ${i}`),y(i,{cwd:o,stdio:`inherit`})}const ct={name:`exec`,version:`1.0.0`,taskTypes:[`exec`],execute:async(e,t,n)=>{n.dryRun||await st(e.config,t)}};async function lt(t,n){if(t.condition!=null&&t.condition!==``){if(!n){u(`Condition specified but no config provided, skipping git-init`,`warn`);return}if(!e(t.condition,n)){u(`Condition not met, skipping git-init task`,`info`);return}}if(t.removeExisting){let e=g.join(h.cwd(),`.git`);_.existsSync(e)&&_.rmSync(e,{recursive:!0,force:!0})}if(y(`git init`,{stdio:`inherit`}),t.initialCommit){let e=t.message??`Initial commit`;y(`git add .`,{stdio:`inherit`}),y(`git commit -m "${e}"`,{stdio:`inherit`})}}const ut={name:`git-init`,version:`1.0.0`,taskTypes:[`git-init`],execute:async(e,t,n)=>{n.dryRun||await lt(e.config,t)}},dt=v(_.mkdir);async function ft(t,n){if(t.condition!=null&&t.condition!==``&&!e(t.condition,n)){u(`Condition not met, skipping mkdir task`,`info`);return}await dt(g.join(h.cwd(),c(t.path,n)),{recursive:!0}),u(`Created directory: ${t.path}`,`success`)}const pt={name:`mkdir`,version:`1.0.0`,taskTypes:[`mkdir`],execute:async(e,t,n)=>{n.dryRun||await ft(e.config,t)}},mt=v(_.rename),ht=v(_.stat),gt=v(_.mkdir);async function _t(t,n){if(t.condition!=null&&t.condition!==``&&!e(t.condition,n)){u(`Condition not met, skipping move task`,`info`);return}let r=g.join(h.cwd(),c(t.from,n)),i=g.join(h.cwd(),c(t.to,n));try{await ht(r)}catch{u(`Source path does not exist: ${r}`,`warn`);return}await gt(g.dirname(i),{recursive:!0}),await mt(r,i),u(`Moved ${t.from} to ${t.to}`,`success`)}const vt={name:`move`,version:`1.0.0`,taskTypes:[`move`],execute:async(e,t,n)=>{n.dryRun||await _t(e.config,t)}},yt=v(_.readFile),bt=v(_.writeFile);async function xt(t,n){if(t.condition!=null&&t.condition!==``&&!e(t.condition,n)){u(`Condition not met, skipping regex-replace task`,`info`);return}let r=g.join(h.cwd(),c(t.file,n)),{pattern:i}=t,a=t.flags??``,o=t.replacement||``,s=await yt(r,`utf-8`),l=new RegExp(i,a);s=s.replace(l,c(o,n)),await bt(r,s)}const St={name:`regex-replace`,version:`1.0.0`,taskTypes:[`regex-replace`],execute:async(e,t,n)=>{n.dryRun||await xt(e.config,t)}},Ct=v(_.rename);async function wt(t,n){if(t.condition!=null&&t.condition!==``&&!e(t.condition,n)){u(`Condition not met, skipping rename task`,`info`);return}let r=g.join(h.cwd(),c(t.from,n)),i=g.join(h.cwd(),c(t.to,n));if(!_.existsSync(r)){u(`Source path does not exist: ${r}`,`warn`);return}await Ct(r,i)}const Tt={name:`rename`,version:`1.0.0`,taskTypes:[`rename`],execute:async(e,t,n)=>{n.dryRun||await wt(e.config,t)}},Et=v(_.readFile),Dt=v(_.writeFile);async function Ot(t,n){if(t.condition!=null&&t.condition!==``&&!e(t.condition,n)){u(`Condition not met, skipping replace-in-file task`,`info`);return}let r=g.join(h.cwd(),c(t.file,n)),{replacements:i}=t;if(!_.existsSync(r)){u(`File not found: ${r}, skipping`,`warn`);return}let a=await Et(r,`utf-8`);for(let{find:e,replace:t}of i){let r=c(t,n);a=a.replace(new RegExp(e,`gu`),r)}await Dt(r,a)}const kt={name:`replace-in-file`,version:`1.0.0`,taskTypes:[`replace-in-file`],execute:async(e,t,n)=>{n.dryRun||await Ot(e.config,t)}},At=v(_.readFile),jt=v(_.writeFile);async function Mt(t,n){if(t.condition!=null&&t.condition!==``&&!e(t.condition,n)){u(`Condition not met, skipping update-json task`,`info`);return}let r=g.join(h.cwd(),c(t.file,n)),{updates:i}=t,a=ne(await At(r,`utf-8`));function o(e){if(typeof e==`string`)return c(e,n);if(Array.isArray(e))return e.map(e=>o(e));if(typeof e==`object`&&e){let t={};for(let[n,r]of Object.entries(e))t[n]=o(r);return t}return e}for(let[e,t]of Object.entries(i)){let n=o(t);e.includes(`.`)?m(a,e,n):a[e]=n}await jt(r,`${JSON.stringify(a,null,2)}\n`)}const Nt={name:`update-json`,version:`1.0.0`,taskTypes:[`update-json`],execute:async(e,t,n)=>{n.dryRun||await Mt(e.config,t)}},Pt=v(_.writeFile);async function Ft(t,r,i){let{allowCreate:a=!0}=t;if(t.condition!=null&&t.condition!==``&&!e(t.condition,r)){u(`Condition not met, skipping write task`,`info`);return}let o=c(t.file,r),s=g.join(h.cwd(),o);if(!_.existsSync(s)){if(a===!1)throw Error(`Write task failed: file does not exist (${o})`);u(`File not found, creating new file: ${o}`,`info`)}let l=A(t);if(!l.isValid)throw l.error?.includes(`cannot have both`)?n.templateHasBothTemplateAndFile():n.templateMissingTemplateOrFile();let d=await j(t,r,i),f=g.dirname(s);_.existsSync(f)||_.mkdirSync(f,{recursive:!0}),await Pt(s,d)}const It={name:`write`,version:`1.0.0`,taskTypes:[`write`],execute:async(e,t,n)=>{n.dryRun||await Ft(e.config,t,e)}};function Lt(){U(`update-json`)||(V(Nt),V(It),V(nt),V(St),V(kt),V(it),V(Tt),V(ut),V(ct),V(ot),V(vt),V($e),V(Je),V(pt))}async function Rt(e,t,n=!1){if(Lt(),n){u(`[DRY RUN] Would execute: ${e.name}`,`info`);return}if(U(e.type)){await W(e,t,{dryRun:n});return}throw TypeError(`Unknown task type: ${e.type}`)}async function zt(e,t,n,r,i=!1){try{return u(`[${n}/${r}] Running: ${e.name}...`,`info`),await Rt(e,t,i),u(`[${n}/${r}] Completed: ${e.name}...`,`success`),!0}catch(t){return u(`Failed: ${e.name}`,`error`),t instanceof Error&&(u(` Reason: ${t.message}`,`error`),t.stack!=null&&h.env.DEBUG!=null&&console.error(t.stack)),!1}}async function Bt(e,t,n){await B(`beforeAll`,t);let r=0,i=0,a=[];for(let s=0;s<e.length;s++){let c=e[s];c!=null&&(await B(`beforeTask`,c,t),await zt(c,t,s+1,e.length,n.dryRun)?(r++,await B(`afterTask`,c,t)):(await p(c.required,t)&&(i++,a.push(c.name)),await B(`onError`,Error(`Task ${c.name} failed`),c),o(`⚠️ Task "${c.name}" failed, continuing with remaining tasks...`)))}await B(`afterAll`,t),i>0&&(u(`\n❌ Task execution completed with ${i} error(s)`,`error`),u(`Completed: ${r}/${e.length} tasks`,`info`),u(`Failed tasks: ${a.join(`, `)}`,`error`),h.exit(1)),u(`Completed: ${r}/${e.length} tasks`,`success`)}function Vt(e){let t=[],n=new Set,r=new Set,a=new Map(e.map(e=>[e.id,e]));function o(e){if(n.has(e))return;if(r.has(e))throw s.forTaskDependency(e);r.add(e);let c=a.get(e);if(!c)throw i.forId(e);if(c.dependencies)for(let e of c.dependencies)o(e);r.delete(e),n.add(e),t.push(c)}for(let t of e)n.has(t.id)||o(t.id);return t}function Ht(e){let t=[],n=e.config,r=typeof n.template==`string`?n.template:void 0,i=typeof n.templateFile==`string`?n.templateFile:void 0,a=A({...r!==void 0&&{template:r},...i!==void 0&&{templateFile:i}});return!a.isValid&&a.error!=null&&a.error!==``&&t.push(`Task "${e.id}" (${e.name}): ${a.error}`),(n.file==null||n.file===``)&&t.push(`Task "${e.id}" (${e.name}): Write task requires "file" property to specify the output file path`),t}async function Ut(e,n){let r=Gt(e);r.length>0&&(console.error(`❌ Task validation errors:`),r.forEach(e=>console.error(` - ${e}`)),h.exit(1));let i=[];for(let r of e)await t(r.enabled,n)&&i.push(r);return i}function Wt(e){return Vt(e)}function Gt(e){let t=[];for(let n of e)if(!U(n.type))t.push(`Task "${n.id}" (${n.name}): Unknown task type "${n.type}"`);else if(n.type===`write`){let e=Ht(n);t.push(...e)}return t}export{I as A,we as C,B as D,Ce as E,E as F,D as I,T as L,P as M,M as N,Se as O,N as P,Ee as S,V as T,ke as _,Bt as a,H as b,We as c,Be as d,Re as f,je as g,q as h,Vt as i,F as j,xe as k,Ue as l,Oe as m,Wt as n,Lt as o,Fe as p,Ut as r,zt as s,Gt as t,He as u,De as v,Te as w,U as x,W as y};
|
|
@@ -12,15 +12,16 @@ const e=require(`./configurations-iSmGgORy.cjs`);let t=require(`node:process`);t
|
|
|
12
12
|
`).slice(0,10).join(`
|
|
13
13
|
`),a=e.split(`
|
|
14
14
|
`).length>10;return`${d.blue}File: ${t.file}${d.reset}\n${d.green}+ New file would be created${d.reset}\n${d.gray}Content preview:${d.reset}\n${i}${a?`
|
|
15
|
-
...`:``}`}let e=te(t);return`${d.blue}File: ${t.file}${d.reset}\n${d.green}+ New file would be created from ${e}${d.reset}`}catch(e){return`${d.red}✗ Error: ${e instanceof Error?e.message:String(e)}${d.reset}`}}async function
|
|
15
|
+
...`:``}`}let e=te(t);return`${d.blue}File: ${t.file}${d.reset}\n${d.green}+ New file would be created from ${e}${d.reset}`}catch(e){return`${d.red}✗ Error: ${e instanceof Error?e.message:String(e)}${d.reset}`}}async function C(t,n,r){if(t.condition!=null&&t.condition!==``&&!e.D(t.condition,n))return`${d.yellow}⊘ Condition not met - task would be skipped${d.reset}`;let i=t.file,a={};t.content==null?t.template!=null&&(a.template=t.template):a.template=t.content,t.templateFile!=null&&(a.templateFile=t.templateFile);try{let e=await S(a,n,r),o=e.split(`
|
|
16
16
|
`).slice(0,10).join(`
|
|
17
17
|
`),s=e.split(`
|
|
18
18
|
`).length>10;return m(i)?`${d.blue}File: ${t.file}${d.reset}\n${d.green}+ Would append content${d.reset}\n${d.gray}Content preview:${d.reset}\n${o}${s?`
|
|
19
19
|
...`:``}`:`${d.blue}File: ${t.file}${d.reset}\n${d.green}+ New file would be created with content${d.reset}\n${d.gray}Content preview:${d.reset}\n${o}${s?`
|
|
20
|
-
...`:``}`}catch(e){return`${d.red}✗ Error: ${e instanceof Error?e.message:String(e)}${d.reset}`}}function
|
|
21
|
-
`)}`}function
|
|
22
|
-
`)}function O(n,r){if(n.condition!=null&&n.condition!==``&&!e.D(n.condition,r))return`${d.yellow}⊘ Condition not met - task would be skipped${d.reset}`;let i=E(e.d(n.command,r),n.args?.map(t=>e.d(t,r))),a=n.cwd==null?t.default.cwd():e.d(n.cwd,r);return`${d.yellow}Would execute:${d.reset}\n${d.cyan} Command: ${i}${d.reset}\n${d.cyan} Working directory: ${a}${d.reset}`}async function k(e,t){try{switch(e.type){case`update-json`:return await g(e.config,t);case`write`:return await ne(e.config,t);case`create`:return await re(e.config,t,e);case`regex-replace`:return await _(e.config,t);case`replace-in-file`:return await v(e.config,t);case`delete`:return
|
|
23
|
-
`));return i}function
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
`)&&(d=n.newline!==!1)}catch{}u&&d?await G(o,`\n${l}`):await G(o,l),e.j(`Appended content to ${n.file}`,`success`)}const Fe={name:`append`,version:`1.0.0`,taskTypes:[`append`],execute:async(e,t,n)=>{n.dryRun||await Pe(e.config,t,e)}},K=(0,i.promisify)(n.default.copyFile),Ie=(0,i.promisify)(n.default.stat),q=(0,i.promisify)(n.default.mkdir),Le=(0,i.promisify)(n.default.readdir);async function J(e,t){await q(t,{recursive:!0});let n=await Le(e,{withFileTypes:!0});await Promise.all(n.map(async n=>{let i=r.default.join(e,n.name),a=r.default.join(t,n.name);n.isDirectory()?await J(i,a):await K(i,a)}))}async function Re(n,i){if(n.condition!=null&&n.condition!==``&&!e.D(n.condition,i)){e.j(`Condition not met, skipping copy task`,`info`);return}let a=r.default.join(t.default.cwd(),e.d(n.from,i)),o=r.default.join(t.default.cwd(),e.d(n.to,i)),s;try{s=await Ie(a)}catch{e.j(`Source path does not exist: ${a}`,`warn`);return}await q(r.default.dirname(o),{recursive:!0}),s.isDirectory()?(await J(a,o),e.j(`Copied directory ${n.from} to ${n.to}`,`success`)):(await K(a,o),e.j(`Copied file ${n.from} to ${n.to}`,`success`))}const ze={name:`copy`,version:`1.0.0`,taskTypes:[`copy`],execute:async(e,t,n)=>{n.dryRun||await Re(e.config,t)}},Be=(0,i.promisify)(n.default.writeFile);async function Ve(i,a,o){if(i.condition!=null&&i.condition!==``&&!e.D(i.condition,a)){e.j(`Condition not met, skipping create task`,`info`);return}let s=e.d(i.file,a),c=r.default.join(t.default.cwd(),s);if(n.default.existsSync(c)){e.j(`File already exists, skipping: ${s}`,`info`);return}let l=x(i);if(!l.isValid)throw l.error?.includes(`cannot have both`)?e.F.createHasBothTemplateAndFile():e.F.createMissingTemplateOrFile();let u=await S(i,a,o),d=r.default.dirname(c);n.default.existsSync(d)||n.default.mkdirSync(d,{recursive:!0}),await Be(c,u),e.j(`Created file: ${s}`,`success`)}const He={name:`create`,version:`1.0.0`,taskTypes:[`create`],execute:async(e,t,n)=>{n.dryRun||await Ve(e.config,t,e)}};async function Ue(i,a){let{paths:o,condition:s}=i;if(s!=null&&s!==``){if(!a){e.j(`Condition specified but no config provided, skipping deletion`,`warn`);return}if(!e.D(s,a)){e.j(`Condition not met, skipping deletion`,`info`);return}}for(let i of o){let o=a==null?i:e.d(i,a),s=r.default.join(t.default.cwd(),o);n.default.existsSync(s)&&n.default.rmSync(s,{recursive:!0,force:!0})}}const We={name:`delete`,version:`1.0.0`,taskTypes:[`delete`],execute:async(e,t,n)=>{n.dryRun||await Ue(e.config,t)}};async function Ge(t,n,r){t.condition!=null&&t.condition!==``&&!e.D(t.condition,n)||await e.p({file:t.file,...t.runtime&&{runtime:t.runtime},...t.args&&{args:t.args},...t.parameters&&{parameters:t.parameters},...t.cwd!=null&&t.cwd.trim()!==``&&{cwd:t.cwd},...r?.$sourceUrl!=null&&r.$sourceUrl.trim()!==``&&{sourceUrl:r.$sourceUrl},captureOutput:!1},n)}const Ke={name:`exec-file`,version:`1.0.0`,taskTypes:[`exec-file`],execute:async(e,t,n)=>{n.dryRun||await Ge(e.config,t,e)}};async function qe(n,i){if(n.condition!=null&&n.condition!==``){if(!i){e.j(`Condition specified but no config provided, skipping exec`,`warn`);return}if(!e.D(n.condition,i)){e.j(`Condition not met, skipping exec task`,`info`);return}}let o=t=>i==null?t:e.d(t,i),s=E(o(n.command),n.args?.map(o)),c=n.cwd==null?t.default.cwd():r.default.join(t.default.cwd(),o(n.cwd));e.O(`Executing: ${s}`),(0,a.execSync)(s,{cwd:c,stdio:`inherit`})}const Je={name:`exec`,version:`1.0.0`,taskTypes:[`exec`],execute:async(e,t,n)=>{n.dryRun||await qe(e.config,t)}};async function Ye(i,o){if(i.condition!=null&&i.condition!==``){if(!o){e.j(`Condition specified but no config provided, skipping git-init`,`warn`);return}if(!e.D(i.condition,o)){e.j(`Condition not met, skipping git-init task`,`info`);return}}if(i.removeExisting){let e=r.default.join(t.default.cwd(),`.git`);n.default.existsSync(e)&&n.default.rmSync(e,{recursive:!0,force:!0})}if((0,a.execSync)(`git init`,{stdio:`inherit`}),i.initialCommit){let e=i.message??`Initial commit`;(0,a.execSync)(`git add .`,{stdio:`inherit`}),(0,a.execSync)(`git commit -m "${e}"`,{stdio:`inherit`})}}const Xe={name:`git-init`,version:`1.0.0`,taskTypes:[`git-init`],execute:async(e,t,n)=>{n.dryRun||await Ye(e.config,t)}},Ze=(0,i.promisify)(n.default.mkdir);async function Qe(n,i){if(n.condition!=null&&n.condition!==``&&!e.D(n.condition,i)){e.j(`Condition not met, skipping mkdir task`,`info`);return}await Ze(r.default.join(t.default.cwd(),e.d(n.path,i)),{recursive:!0}),e.j(`Created directory: ${n.path}`,`success`)}const $e={name:`mkdir`,version:`1.0.0`,taskTypes:[`mkdir`],execute:async(e,t,n)=>{n.dryRun||await Qe(e.config,t)}},et=(0,i.promisify)(n.default.rename),tt=(0,i.promisify)(n.default.stat),nt=(0,i.promisify)(n.default.mkdir);async function rt(n,i){if(n.condition!=null&&n.condition!==``&&!e.D(n.condition,i)){e.j(`Condition not met, skipping move task`,`info`);return}let a=r.default.join(t.default.cwd(),e.d(n.from,i)),o=r.default.join(t.default.cwd(),e.d(n.to,i));try{await tt(a)}catch{e.j(`Source path does not exist: ${a}`,`warn`);return}await nt(r.default.dirname(o),{recursive:!0}),await et(a,o),e.j(`Moved ${n.from} to ${n.to}`,`success`)}const it={name:`move`,version:`1.0.0`,taskTypes:[`move`],execute:async(e,t,n)=>{n.dryRun||await rt(e.config,t)}},at=(0,i.promisify)(n.default.readFile),ot=(0,i.promisify)(n.default.writeFile);async function st(n,i){if(n.condition!=null&&n.condition!==``&&!e.D(n.condition,i)){e.j(`Condition not met, skipping regex-replace task`,`info`);return}let a=r.default.join(t.default.cwd(),e.d(n.file,i)),{pattern:o}=n,s=n.flags??``,c=n.replacement||``,l=await at(a,`utf-8`),u=new RegExp(o,s);l=l.replace(u,e.d(c,i)),await ot(a,l)}const ct={name:`regex-replace`,version:`1.0.0`,taskTypes:[`regex-replace`],execute:async(e,t,n)=>{n.dryRun||await st(e.config,t)}},lt=(0,i.promisify)(n.default.rename);async function ut(i,a){if(i.condition!=null&&i.condition!==``&&!e.D(i.condition,a)){e.j(`Condition not met, skipping rename task`,`info`);return}let o=r.default.join(t.default.cwd(),e.d(i.from,a)),s=r.default.join(t.default.cwd(),e.d(i.to,a));if(!n.default.existsSync(o)){e.j(`Source path does not exist: ${o}`,`warn`);return}await lt(o,s)}const dt={name:`rename`,version:`1.0.0`,taskTypes:[`rename`],execute:async(e,t,n)=>{n.dryRun||await ut(e.config,t)}},ft=(0,i.promisify)(n.default.readFile),pt=(0,i.promisify)(n.default.writeFile);async function mt(i,a){if(i.condition!=null&&i.condition!==``&&!e.D(i.condition,a)){e.j(`Condition not met, skipping replace-in-file task`,`info`);return}let o=r.default.join(t.default.cwd(),e.d(i.file,a)),{replacements:s}=i;if(!n.default.existsSync(o)){e.j(`File not found: ${o}, skipping`,`warn`);return}let c=await ft(o,`utf-8`);for(let{find:t,replace:n}of s){let r=e.d(n,a);c=c.replace(new RegExp(t,`gu`),r)}await pt(o,c)}const ht={name:`replace-in-file`,version:`1.0.0`,taskTypes:[`replace-in-file`],execute:async(e,t,n)=>{n.dryRun||await mt(e.config,t)}},gt=(0,i.promisify)(n.default.readFile),_t=(0,i.promisify)(n.default.writeFile),vt=2;async function yt(n,i){if(n.condition!=null&&n.condition!==``&&!e.D(n.condition,i)){e.j(`Condition not met, skipping update-json task`,`info`);return}let a=r.default.join(t.default.cwd(),e.d(n.file,i)),{updates:o}=n,s=e.y(await gt(a,`utf-8`));function c(t){if(typeof t==`string`)return e.d(t,i);if(Array.isArray(t))return t.map(e=>c(e));if(typeof t==`object`&&t){let e={};for(let[n,r]of Object.entries(t))e[n]=c(r);return e}return t}for(let[t,n]of Object.entries(o)){let r=c(n);t.includes(`.`)?e.x(s,t,r):s[t]=r}await _t(a,`${JSON.stringify(s,null,2)}\n`)}const bt={name:`update-json`,version:`1.0.0`,taskTypes:[`update-json`],execute:async(e,t,n)=>{n.dryRun||await yt(e.config,t)}},Y=(0,i.promisify)(n.default.writeFile);async function xt(i,a,o){let{allowCreate:s=!0}=i;if(i.condition!=null&&i.condition!==``&&!e.D(i.condition,a)){e.j(`Condition not met, skipping write task`,`info`);return}let c=e.d(i.file,a),l=r.default.join(t.default.cwd(),c);if(!n.default.existsSync(l)){if(s===!1)throw Error(`Write task failed: file does not exist (${c})`);e.j(`File not found, creating new file: ${c}`,`info`)}let u=x(i);if(!u.isValid)throw u.error?.includes(`cannot have both`)?e.F.templateHasBothTemplateAndFile():e.F.templateMissingTemplateOrFile();let d=await S(i,a,o),f=r.default.dirname(l);n.default.existsSync(f)||n.default.mkdirSync(f,{recursive:!0}),await Y(l,d)}const St={name:`write`,version:`1.0.0`,taskTypes:[`write`],execute:async(e,t,n)=>{n.dryRun||await xt(e.config,t,e)}};function X(){L(`update-json`)||(F(bt),F(St),F(He),F(ct),F(ht),F(We),F(dt),F(Xe),F(Je),F(Ke),F(it),F(ze),F(Fe),F($e))}async function Ct(t,n,r=!1){if(X(),r){e.j(`[DRY RUN] Would execute: ${t.name}`,`info`);return}if(L(t.type)){await R(t,n,{dryRun:r});return}throw TypeError(`Unknown task type: ${t.type}`)}async function Z(n,r,i,a,o=!1){try{return e.j(`[${i}/${a}] Running: ${n.name}...`,`info`),await Ct(n,r,o),e.j(`[${i}/${a}] Completed: ${n.name}...`,`success`),!0}catch(r){return e.j(`Failed: ${n.name}`,`error`),r instanceof Error&&(e.j(` Reason: ${r.message}`,`error`),r.stack!=null&&t.default.env.DEBUG!=null&&console.error(r.stack)),!1}}async function wt(n,r,i){await P(`beforeAll`,r);let a=0,o=0,s=[];for(let t=0;t<n.length;t++){let c=n[t];c!=null&&(await P(`beforeTask`,c,r),await Z(c,r,t+1,n.length,i.dryRun)?(a++,await P(`afterTask`,c,r)):(await e.w(c.required,r)&&(o++,s.push(c.name)),await P(`onError`,Error(`Task ${c.name} failed`),c),e.P(`⚠️ Task "${c.name}" failed, continuing with remaining tasks...`)))}await P(`afterAll`,r),o>0&&(e.j(`\n❌ Task execution completed with ${o} error(s)`,`error`),e.j(`Completed: ${a}/${n.length} tasks`,`info`),e.j(`Failed tasks: ${s.join(`, `)}`,`error`),t.default.exit(1)),e.j(`Completed: ${a}/${n.length} tasks`,`success`)}function Q(t){let n=[],r=new Set,i=new Set,a=new Map(t.map(e=>[e.id,e]));function o(t){if(r.has(t))return;if(i.has(t))throw e.R.forTaskDependency(t);i.add(t);let s=a.get(t);if(!s)throw e.L.forId(t);if(s.dependencies)for(let e of s.dependencies)o(e);i.delete(t),r.add(t),n.push(s)}for(let e of t)r.has(e.id)||o(e.id);return n}function Tt(e){let t=[],n=e.config,r=typeof n.template==`string`?n.template:void 0,i=typeof n.templateFile==`string`?n.templateFile:void 0,a=x({...r!==void 0&&{template:r},...i!==void 0&&{templateFile:i}});return!a.isValid&&a.error!=null&&a.error!==``&&t.push(`Task "${e.id}" (${e.name}): ${a.error}`),(n.file==null||n.file===``)&&t.push(`Task "${e.id}" (${e.name}): Write task requires "file" property to specify the output file path`),t}async function Et(n,r){let i=$(n);i.length>0&&(console.error(`❌ Task validation errors:`),i.forEach(e=>console.error(` - ${e}`)),t.default.exit(1));let a=[];for(let t of n)await e.E(t.enabled,r)&&a.push(t);return a}function Dt(e){return Q(e)}function $(e){let t=[];for(let n of e)if(!L(n.type))t.push(`Task "${n.id}" (${n.name}): Unknown task type "${n.type}"`);else if(n.type===`write`){let e=Tt(n);t.push(...e)}return t}Object.defineProperty(exports,`A`,{enumerable:!0,get:function(){return O}}),Object.defineProperty(exports,`C`,{enumerable:!0,get:function(){return fe}}),Object.defineProperty(exports,`D`,{enumerable:!0,get:function(){return le}}),Object.defineProperty(exports,`E`,{enumerable:!0,get:function(){return P}}),Object.defineProperty(exports,`F`,{enumerable:!0,get:function(){return v}}),Object.defineProperty(exports,`I`,{enumerable:!0,get:function(){return g}}),Object.defineProperty(exports,`M`,{enumerable:!0,get:function(){return C}}),Object.defineProperty(exports,`N`,{enumerable:!0,get:function(){return w}}),Object.defineProperty(exports,`O`,{enumerable:!0,get:function(){return A}}),Object.defineProperty(exports,`P`,{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,`S`,{enumerable:!0,get:function(){return de}}),Object.defineProperty(exports,`T`,{enumerable:!0,get:function(){return ue}}),Object.defineProperty(exports,`_`,{enumerable:!0,get:function(){return z}}),Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return wt}}),Object.defineProperty(exports,`b`,{enumerable:!0,get:function(){return L}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return je}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return De}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return Te}}),Object.defineProperty(exports,`g`,{enumerable:!0,get:function(){return _e}}),Object.defineProperty(exports,`h`,{enumerable:!0,get:function(){return H}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return Q}}),Object.defineProperty(exports,`j`,{enumerable:!0,get:function(){return D}}),Object.defineProperty(exports,`k`,{enumerable:!0,get:function(){return k}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return Ae}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return ge}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return Dt}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return X}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return Se}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return Et}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return Z}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return $}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return ke}}),Object.defineProperty(exports,`v`,{enumerable:!0,get:function(){return R}}),Object.defineProperty(exports,`w`,{enumerable:!0,get:function(){return F}}),Object.defineProperty(exports,`x`,{enumerable:!0,get:function(){return pe}}),Object.defineProperty(exports,`y`,{enumerable:!0,get:function(){return I}});
|
|
20
|
+
...`:``}`}catch(e){return`${d.red}✗ Error: ${e instanceof Error?e.message:String(e)}${d.reset}`}}function w(t,n){if(t.condition!=null&&t.condition!==``&&!e.D(t.condition,n))return`${d.yellow}⊘ Condition not met - task would be skipped${d.reset}`;let r=t.paths.map(t=>e.d(t,n)).filter(e=>m(e));return r.length===0?`${d.cyan}→ No files/directories to delete${d.reset}`:`${d.red}Would delete:${d.reset}\n${r.map(e=>`${d.red} - ${e}${d.reset}`).join(`
|
|
21
|
+
`)}`}function T(t,n){if(t.condition!=null&&t.condition!==``&&!e.D(t.condition,n))return`${d.yellow}⊘ Condition not met - task would be skipped${d.reset}`;let r=e.d(t.from,n),i=e.d(t.to,n);return m(r)?m(i)?`${d.yellow}⚠ Destination already exists: ${i}${d.reset}\n${d.cyan}Would rename: ${r} → ${i}${d.reset}`:`${d.cyan}Would rename: ${r} → ${i}${d.reset}`:`${d.red}✗ Source not found: ${r}${d.reset}`}function ie(t,n){if(t.condition!=null&&t.condition!==``&&!e.D(t.condition,n))return`${d.yellow}⊘ Condition not met - task would be skipped${d.reset}`;let r=e.d(t.from,n),i=e.d(t.to,n);return m(r)?m(i)?`${d.yellow}⚠ Destination already exists: ${i}${d.reset}\n${d.cyan}Would move: ${r} → ${i}${d.reset}`:`${d.cyan}Would move: ${r} → ${i}${d.reset}`:`${d.red}✗ Source not found: ${r}${d.reset}`}function ae(t,n){if(t.condition!=null&&t.condition!==``&&!e.D(t.condition,n))return`${d.yellow}⊘ Condition not met - task would be skipped${d.reset}`;let r=e.d(t.from,n),i=e.d(t.to,n);if(!m(r))return`${d.red}✗ Source not found: ${r}${d.reset}`;let a=`file`;return m(i)?`${d.yellow}⚠ Destination already exists: ${i}${d.reset}\n${d.cyan}Would copy ${a}: ${r} → ${i}${d.reset}`:`${d.cyan}Would copy ${a}: ${r} → ${i}${d.reset}`}function oe(t,n){if(t.condition!=null&&t.condition!==``&&!e.D(t.condition,n))return`${d.yellow}⊘ Condition not met - task would be skipped${d.reset}`;let r=e.d(t.path,n);return m(r)?`${d.cyan}→ Directory already exists: ${r}${d.reset}`:`${d.green}+ Would create directory: ${r}${d.reset}`}const se=/^[\w+,./:=@-]+$/u;function ce(e){return se.test(e)?e:t.default.platform===`win32`?`"${e.replace(/(?<slashes>\\*)"/gu,`$<slashes>$<slashes>\\"`).replace(/(?<slashes>\\+)$/u,`$<slashes>$<slashes>`)}"`:`'${e.replace(/'/gu,String.raw`'\''`)}'`}function E(e,t){let n=(t??[]).filter(e=>e!==``).map(ce);return n.length>0?`${e} ${n.join(` `)}`:e}function D(e){if(e.condition!=null&&e.condition!==``)return`${d.yellow}⊘ Condition check skipped in dry-run${d.reset}`;let t=m(`.git`),n=[];if(e.removeExisting&&t&&n.push(`${d.red}Would remove existing .git directory${d.reset}`),n.push(`${d.green}Would initialize git repository${d.reset}`),e.initialCommit){let t=e.message??`Initial commit`;n.push(`${d.green}Would create initial commit: "${t}"${d.reset}`)}return n.join(`
|
|
22
|
+
`)}function O(n,r){if(n.condition!=null&&n.condition!==``&&!e.D(n.condition,r))return`${d.yellow}⊘ Condition not met - task would be skipped${d.reset}`;let i=E(e.d(n.command,r),n.args?.map(t=>e.d(t,r))),a=n.cwd==null?t.default.cwd():e.d(n.cwd,r);return`${d.yellow}Would execute:${d.reset}\n${d.cyan} Command: ${i}${d.reset}\n${d.cyan} Working directory: ${a}${d.reset}`}async function k(e,t){try{switch(e.type){case`update-json`:return await g(e.config,t);case`write`:return await ne(e.config,t);case`create`:return await re(e.config,t,e);case`regex-replace`:return await _(e.config,t);case`replace-in-file`:return await v(e.config,t);case`delete`:return w(e.config,t);case`rename`:return T(e.config,t);case`move`:return ie(e.config,t);case`copy`:return ae(e.config,t);case`append`:return await C(e.config,t,e);case`mkdir`:return oe(e.config,t);case`git-init`:return D(e.config);case`exec`:return O(e.config,t);case`exec-file`:return O(e.config,t);default:{let t=e.type;return`${d.yellow}⚠ Diff not available for task type: ${t}${d.reset}`}}}catch(e){return`${d.red}✗ Error generating diff: ${e instanceof Error?e.message:String(e)}${d.reset}`}}async function le(e,t){console.log(`${d.blue}═══════════════════════════════════════════════════════${d.reset}`),console.log(`${d.blue} DRY RUN - Preview of changes${d.reset}`),console.log(`${d.blue}═══════════════════════════════════════════════════════${d.reset}`);for(let n of e){console.log(`${d.cyan}▶ Task: ${n.name}${d.reset}`),n.description!=null&&n.description!==``&&console.log(`${d.gray} ${n.description}${d.reset}`);let e=await k(n,t);console.log(e),console.log(`${d.gray}${`─`.repeat(55)}${d.reset}`)}console.log(`${d.blue}═══════════════════════════════════════════════════════${d.reset}`),console.log(`${d.yellow} No changes were applied (dry-run mode)${d.reset}`),console.log(`${d.blue}═══════════════════════════════════════════════════════${d.reset}`)}const A=new Map,j={},M=new Map;function ue(e){e.beforeAll!=null&&(j.beforeAll=e.beforeAll),e.afterAll!=null&&(j.afterAll=e.afterAll),e.beforeTask!=null&&(j.beforeTask=e.beforeTask),e.afterTask!=null&&(j.afterTask=e.afterTask),e.onError!=null&&(j.onError=e.onError)}async function N(t,...n){let r=j[t];if(r!=null)try{t===`beforeAll`||t===`afterAll`?await r(n[0]):(t===`beforeTask`||t===`afterTask`||t===`onError`)&&await r(n[0],n[1])}catch(n){e.j(`Error in ${t} hook: ${n instanceof Error?n.message:String(n)}`,`error`)}}function P(t){if(t.name==null||t.name===``)throw TypeError(`Plugin name is required`);if(!Array.isArray(t.taskTypes)||t.taskTypes.length===0)throw TypeError(`Plugin ${t.name} must define at least one task type`);if(typeof t.execute!=`function`)throw TypeError(`Plugin ${t.name} must provide an execute function`);if(A.has(t.name))throw TypeError(`Plugin ${t.name} is already registered`);for(let e of t.taskTypes)if(M.has(e)){let t=M.get(e);throw TypeError(`Task type "${e}" is already registered by plugin "${t}"`)}A.set(t.name,t);for(let e of t.taskTypes)M.set(e,t.name);e.O(`Registered plugin: ${t.name}${t.version==null?``:` v${t.version}`}`)}function de(e){let t=A.get(e);if(t!=null){for(let e of t.taskTypes)M.delete(e);A.delete(e)}}function fe(e){return A.get(e)}function pe(){return Array.from(A.keys())}function me(){A.clear(),M.clear()}function F(e){let t=M.get(e);if(t!=null)return A.get(t)}function I(e){return M.has(e)}async function L(e,t,n){let r=F(e.type);if(r==null)throw TypeError(`No plugin found for task type: ${e.type}`);await r.execute(e,t,n)}function R(e,t,n,r){return{name:e,...r?.version!=null&&{version:r.version},taskTypes:[t],execute:n,...r?.getDiff!=null&&{getDiff:r.getDiff},...r?.validate!=null&&{validate:r.validate}}}const he=`--`,ge=`no-`;function z(e){return e.replace(/[-_]/gu,``).toLowerCase()}function B(e,t){if(t.includes(e))return e;let n=z(e);return t.find(e=>z(e)===n)}function _e(e){let t=[];for(let n=0;n<e.length;n++){let r=e[n]??``;if(!r.startsWith(`--`)||r.length===2)throw Error(r.startsWith(`-`)?`Unknown option "${r}"`:`Unexpected argument "${r}". Prompt answers are passed as --<promptId> <value>`);let i=r.indexOf(`=`),a=i===-1?r:r.slice(0,i),o=a.slice(2);if(o===``)throw Error(`Unknown option "${r}"`);let s;if(i!==-1)s=r.slice(i+1);else{let t=e[n+1];t!=null&&!t.startsWith(`-`)&&(s=t,n++)}t.push({flag:a,name:o,value:s})}return t}function V(e,t){let n=t.map(e=>e.id),r=new Map(t.map(e=>[e.id,e.type])),i={},a=[],o=[];for(let{flag:t,name:s,value:c}of e){let e=B(s,n);if(e!=null){c===void 0?r.get(e)===`confirm`?i[e]=`true`:o.push(`Option ${t} needs a value, e.g. ${t}=<value>`):i[e]=c;continue}let l=c===void 0&&s.startsWith(`no-`)?B(s.slice(3),n):void 0;l==null?a.push(t):r.get(l)===`confirm`?i[l]=`false`:o.push(`Option ${t} only works for yes/no (confirm) prompts`)}if(a.length>0&&o.unshift(`Unknown option(s) ${a.join(`, `)}: no prompt with a matching id. ${n.length>0?`Prompts in this configuration: ${n.join(`, `)}`:`This configuration has no prompts`}`),o.length>0)throw Error(o.join(`
|
|
23
|
+
`));return i}function ve(e,t,n){let r=n.map(e=>e.id),i=V(e,n);for(let[e,n]of t)i[B(e,r)??e]=n;return i}function ye(e){if(Array.isArray(e))return e.map(String).join(`,`);if([`string`,`number`,`boolean`].includes(typeof e))return String(e)}function H(e,t){let n={},r=[];for(let i of e)for(let[e,a]of Object.entries(i.answers??{})){let o=B(e,t),s=ye(a);o==null?r.push(`Answer "${e}" in config "${i.name}" matches no prompt`):s===void 0?r.push(`Answer "${e}" in config "${i.name}" must be a string, number, boolean or array`):n[o]=s}return{answers:n,problems:r}}function be(e,t=e.flatMap(e=>e.prompts??[])){let n=t.map(e=>e.id),{answers:r,problems:i}=H(e,n);if(i.length>0)throw i.push(n.length>0?`Prompts in this configuration: ${n.join(`, `)}`:`This configuration has no prompts`),Error(i.join(`
|
|
24
|
+
`));return r}const xe=40,Se={input:`<value>`,password:`<value>`,select:`<value>`,number:`<number>`,checkbox:`<values>`};function Ce(e){return e.type===`confirm`?`--[no-]${e.id}`:`--${e.id} ${Se[e.type]}`}function we(e,t){let n=[];(e.type===`select`||e.type===`checkbox`)&&n.push(`choices: ${e.choices.map(e=>String(e.value)).join(`, `)}`);let r=e.default;return([`string`,`number`,`boolean`].includes(typeof r)||Array.isArray(r))&&n.push(`default: ${String(r)}`),e.required===!0&&n.push(`required`),typeof e.enabled==`object`?n.push(e.enabled.type===`condition`?`when: ${e.enabled.value}`:`conditional`):e.enabled===!1&&n.push(`disabled`),t!==void 0&&n.push(`answered in config: ${t}`),n.length>0?`${e.message} [${n.join(`; `)}]`:e.message}function Te(e){let{answers:t}=H(e,e.flatMap(e=>(e.prompts??[]).map(e=>e.id))),n=e.map(e=>({name:e.name,items:(e.prompts??[]).map(e=>({flag:Ce(e),description:we(e,t[e.id])}))})).filter(e=>e.items.length>0);if(n.length===0)return`Prompts:
|
|
25
|
+
This configuration has no prompts.`;let r=Math.min(40,Math.max(...n.flatMap(e=>e.items.map(e=>e.flag.length)))),i=[`Prompts (answer with a flag instead of being asked; kebab-case ids work too):`];for(let e of n){i.push(``,` ${e.name}:`);for(let t of e.items)i.push(` ${t.flag.padEnd(r)} ${t.description}`)}return i.join(`
|
|
26
|
+
`)}const Ee=new Set([`true`,`1`,`yes`,`y`]),De=new Set([`false`,`0`,`no`,`n`]);let U=new Map;function Oe(e){U=new Map(Object.entries(e))}function ke(e){return U.get(e)}function Ae(e){let t=e.indexOf(`=`);if(t<=0)throw Error(`Invalid --set value "${e}". Expected format: key=value`);return[e.slice(0,t).trim(),e.slice(t+1)]}function je(t,n){switch(t.type){case`confirm`:{let r=n.trim().toLowerCase();if(Ee.has(r))return!0;if(De.has(r))return!1;throw e.I.invalidValue(t.id,n,`expected true or false`)}case`number`:{let r=Number(n);if(n.trim()===``||Number.isNaN(r))throw e.I.invalidValue(t.id,n,`expected a number`);return r}case`select`:{let r=t.choices.find(e=>String(e.value)===n);if(r==null)throw e.I.invalidValue(t.id,n,`expected one of ${t.choices.map(e=>String(e.value)).join(`, `)}`);return r.value}case`checkbox`:return n.split(`,`).map(e=>e.trim()).filter(e=>e!==``).map(n=>{let r=t.choices.find(e=>String(e.value)===n);if(r==null)throw e.I.invalidValue(t.id,n,`expected one of ${t.choices.map(e=>String(e.value)).join(`, `)}`);return r.value});case`input`:case`password`:return n;default:throw e.I.unknownType(t.type)}}async function W(t,n,r,i){if(t!==void 0)return e.f(t,{id:n,contextType:`Prompt`,...r!=null&&{context:r},...i?.$sourceUrl!=null&&{sourceUrl:i.$sourceUrl}})}async function Me(t,n=new Map,r={}){let i={};if(t.length===0)return i;for(let a of t){if(a.$configEnabled!=null&&!await e.E(a.$configEnabled,{...r,...i}))continue;let t={...r,...i};if(!await e.E(a.enabled,t)){i[a.id]=void 0;continue}let s=ke(a.id);if(s!==void 0){let n=je(a,s);if(typeof n==`string`&&n.trim()===``&&await e.w(a.required,t)===!0)throw e.I.required(a.id);a.transformers!==void 0&&(n=await e.s.apply(a.transformers,n,t)),e.j(`${a.message}: ${String(n)} (preset)`,`info`),i[a.id]=n;continue}try{let r,s=n.get(a.id);switch(a.default!==void 0&&(s=await W(a.default,a.id,t,a)),s!==void 0&&a.transformers!==void 0&&(s=await e.s.apply(a.transformers,s,t)),a.type){case`input`:{let n={message:a.message};s!==void 0&&(n.default=String(s));let i=await e.w(a.required,t);if(i!==void 0&&(n.required=i),r=await(0,o.input)(n),i&&(r==null||typeof r==`string`&&r.trim()===``))throw e.j(`${a.message} is required`,`error`),e.I.required(a.id);break}case`password`:if(r=await(0,o.password)({message:a.message,mask:`*`}),await e.w(a.required,t)&&(r==null||typeof r==`string`&&r.trim()===``))throw e.j(`${a.message} is required`,`error`),e.I.required(a.id);break;case`number`:{let n={message:a.message};s!==void 0&&(n.default=Number(s));let i=await e.w(a.required,t);if(i!==void 0&&(n.required=i),a.min!==void 0&&(n.min=a.min),a.max!==void 0&&(n.max=a.max),r=await(0,o.number)(n),i&&r==null)throw e.j(`${a.message} is required`,`error`),e.I.required(a.id);break}case`select`:{let e={message:a.message,choices:a.choices.map(e=>({name:e.name,value:e.value}))};s!==void 0&&(e.default=s),r=await(0,o.select)(e);break}case`checkbox`:{let n={message:a.message,choices:a.choices.map(e=>({name:e.name,value:e.value}))};s!==void 0&&(n.default=s);let i=await e.w(a.required,t);i!==void 0&&(n.required=i),r=await(0,o.checkbox)(n);break}case`confirm`:{let e=s===void 0?!1:!!s;r=await(0,o.confirm)({message:a.message,default:e});break}default:throw e.j(`Unknown prompt type: ${a.type}`,`error`),e.I.unknownType(a.type)}a.transformers!==void 0&&(s!==void 0&&(r===s||String(r)===String(s))||(r=await e.s.apply(a.transformers,r,{...t,...i}))),i[a.id]=r}catch(t){throw t instanceof Error&&e.j(`Failed to collect prompt "${a.id}": ${t.message}`,`error`),t}}return i}async function Ne(e,t){let n=new Map,r=e.map(async e=>{if(e.default!==void 0){let r=await W(e.default,e.id,t,e);r!==void 0&&n.set(e.id,r)}});return await Promise.all(r),n}function Pe(e){let t=[],n=new Set;for(let r of e){if(n.has(r.id)&&t.push(`Duplicate prompt ID: ${r.id}`),n.add(r.id),/^[a-zA-Z_$][a-zA-Z0-9_$]*$/u.test(r.id)||t.push(`Invalid prompt ID "${r.id}": must be a valid JavaScript identifier (start with letter, underscore, or $, followed by letters, digits, underscores, or $)`),(!r.message||r.message.trim()===``)&&t.push(`Prompt "${r.id}" must have a non-empty message`),r.type===`select`||r.type===`checkbox`){r.choices.length===0&&t.push(`${r.type===`select`?`Select`:`Checkbox`} prompt "${r.id}" must have at least one choice`);for(let e of r.choices)(!e.name||e.name.trim()===``)&&t.push(`${r.type===`select`?`Select`:`Checkbox`} prompt "${r.id}" has a choice with empty name`),e.value===void 0&&t.push(`${r.type===`select`?`Select`:`Checkbox`} prompt "${r.id}" has a choice with undefined value`)}r.type===`number`&&r.min!==void 0&&r.max!==void 0&&r.min>r.max&&t.push(`Number prompt "${r.id}" has min greater than max`)}return t}const G=(0,i.promisify)(n.default.appendFile),Fe=(0,i.promisify)(n.default.readFile),Ie=(0,i.promisify)(n.default.stat);async function Le(n,i,a){if(n.condition!=null&&n.condition!==``&&!e.D(n.condition,i)){e.j(`Condition not met, skipping append task`,`info`);return}let o=r.default.join(t.default.cwd(),e.d(n.file,i)),s={};n.content==null?n.template!=null&&(s.template=n.template):s.template=n.content,n.templateFile!=null&&(s.templateFile=n.templateFile);let c=x(s);if(!c.isValid)throw c.error?.includes(`cannot have both`)?e.F.templateHasBothTemplateAndFile():e.F.templateMissingTemplateOrFile();let l=await S(s,i,a),u=!1,d=!1;try{await Ie(o),u=!0;let e=await Fe(o,`utf-8`);e.length>0&&!e.endsWith(`
|
|
27
|
+
`)&&(d=n.newline!==!1)}catch{}u&&d?await G(o,`\n${l}`):await G(o,l),e.j(`Appended content to ${n.file}`,`success`)}const Re={name:`append`,version:`1.0.0`,taskTypes:[`append`],execute:async(e,t,n)=>{n.dryRun||await Le(e.config,t,e)}},K=(0,i.promisify)(n.default.copyFile),ze=(0,i.promisify)(n.default.stat),q=(0,i.promisify)(n.default.mkdir),Be=(0,i.promisify)(n.default.readdir);async function J(e,t){await q(t,{recursive:!0});let n=await Be(e,{withFileTypes:!0});await Promise.all(n.map(async n=>{let i=r.default.join(e,n.name),a=r.default.join(t,n.name);n.isDirectory()?await J(i,a):await K(i,a)}))}async function Ve(n,i){if(n.condition!=null&&n.condition!==``&&!e.D(n.condition,i)){e.j(`Condition not met, skipping copy task`,`info`);return}let a=r.default.join(t.default.cwd(),e.d(n.from,i)),o=r.default.join(t.default.cwd(),e.d(n.to,i)),s;try{s=await ze(a)}catch{e.j(`Source path does not exist: ${a}`,`warn`);return}await q(r.default.dirname(o),{recursive:!0}),s.isDirectory()?(await J(a,o),e.j(`Copied directory ${n.from} to ${n.to}`,`success`)):(await K(a,o),e.j(`Copied file ${n.from} to ${n.to}`,`success`))}const He={name:`copy`,version:`1.0.0`,taskTypes:[`copy`],execute:async(e,t,n)=>{n.dryRun||await Ve(e.config,t)}},Ue=(0,i.promisify)(n.default.writeFile);async function We(i,a,o){if(i.condition!=null&&i.condition!==``&&!e.D(i.condition,a)){e.j(`Condition not met, skipping create task`,`info`);return}let s=e.d(i.file,a),c=r.default.join(t.default.cwd(),s);if(n.default.existsSync(c)){e.j(`File already exists, skipping: ${s}`,`info`);return}let l=x(i);if(!l.isValid)throw l.error?.includes(`cannot have both`)?e.F.createHasBothTemplateAndFile():e.F.createMissingTemplateOrFile();let u=await S(i,a,o),d=r.default.dirname(c);n.default.existsSync(d)||n.default.mkdirSync(d,{recursive:!0}),await Ue(c,u),e.j(`Created file: ${s}`,`success`)}const Ge={name:`create`,version:`1.0.0`,taskTypes:[`create`],execute:async(e,t,n)=>{n.dryRun||await We(e.config,t,e)}};async function Ke(i,a){let{paths:o,condition:s}=i;if(s!=null&&s!==``){if(!a){e.j(`Condition specified but no config provided, skipping deletion`,`warn`);return}if(!e.D(s,a)){e.j(`Condition not met, skipping deletion`,`info`);return}}for(let i of o){let o=a==null?i:e.d(i,a),s=r.default.join(t.default.cwd(),o);n.default.existsSync(s)&&n.default.rmSync(s,{recursive:!0,force:!0})}}const qe={name:`delete`,version:`1.0.0`,taskTypes:[`delete`],execute:async(e,t,n)=>{n.dryRun||await Ke(e.config,t)}};async function Je(t,n,r){t.condition!=null&&t.condition!==``&&!e.D(t.condition,n)||await e.p({file:t.file,...t.runtime&&{runtime:t.runtime},...t.args&&{args:t.args},...t.parameters&&{parameters:t.parameters},...t.cwd!=null&&t.cwd.trim()!==``&&{cwd:t.cwd},...r?.$sourceUrl!=null&&r.$sourceUrl.trim()!==``&&{sourceUrl:r.$sourceUrl},captureOutput:!1},n)}const Ye={name:`exec-file`,version:`1.0.0`,taskTypes:[`exec-file`],execute:async(e,t,n)=>{n.dryRun||await Je(e.config,t,e)}};async function Xe(n,i){if(n.condition!=null&&n.condition!==``){if(!i){e.j(`Condition specified but no config provided, skipping exec`,`warn`);return}if(!e.D(n.condition,i)){e.j(`Condition not met, skipping exec task`,`info`);return}}let o=t=>i==null?t:e.d(t,i),s=E(o(n.command),n.args?.map(o)),c=n.cwd==null?t.default.cwd():r.default.join(t.default.cwd(),o(n.cwd));e.O(`Executing: ${s}`),(0,a.execSync)(s,{cwd:c,stdio:`inherit`})}const Ze={name:`exec`,version:`1.0.0`,taskTypes:[`exec`],execute:async(e,t,n)=>{n.dryRun||await Xe(e.config,t)}};async function Qe(i,o){if(i.condition!=null&&i.condition!==``){if(!o){e.j(`Condition specified but no config provided, skipping git-init`,`warn`);return}if(!e.D(i.condition,o)){e.j(`Condition not met, skipping git-init task`,`info`);return}}if(i.removeExisting){let e=r.default.join(t.default.cwd(),`.git`);n.default.existsSync(e)&&n.default.rmSync(e,{recursive:!0,force:!0})}if((0,a.execSync)(`git init`,{stdio:`inherit`}),i.initialCommit){let e=i.message??`Initial commit`;(0,a.execSync)(`git add .`,{stdio:`inherit`}),(0,a.execSync)(`git commit -m "${e}"`,{stdio:`inherit`})}}const $e={name:`git-init`,version:`1.0.0`,taskTypes:[`git-init`],execute:async(e,t,n)=>{n.dryRun||await Qe(e.config,t)}},et=(0,i.promisify)(n.default.mkdir);async function tt(n,i){if(n.condition!=null&&n.condition!==``&&!e.D(n.condition,i)){e.j(`Condition not met, skipping mkdir task`,`info`);return}await et(r.default.join(t.default.cwd(),e.d(n.path,i)),{recursive:!0}),e.j(`Created directory: ${n.path}`,`success`)}const nt={name:`mkdir`,version:`1.0.0`,taskTypes:[`mkdir`],execute:async(e,t,n)=>{n.dryRun||await tt(e.config,t)}},rt=(0,i.promisify)(n.default.rename),it=(0,i.promisify)(n.default.stat),at=(0,i.promisify)(n.default.mkdir);async function ot(n,i){if(n.condition!=null&&n.condition!==``&&!e.D(n.condition,i)){e.j(`Condition not met, skipping move task`,`info`);return}let a=r.default.join(t.default.cwd(),e.d(n.from,i)),o=r.default.join(t.default.cwd(),e.d(n.to,i));try{await it(a)}catch{e.j(`Source path does not exist: ${a}`,`warn`);return}await at(r.default.dirname(o),{recursive:!0}),await rt(a,o),e.j(`Moved ${n.from} to ${n.to}`,`success`)}const st={name:`move`,version:`1.0.0`,taskTypes:[`move`],execute:async(e,t,n)=>{n.dryRun||await ot(e.config,t)}},ct=(0,i.promisify)(n.default.readFile),lt=(0,i.promisify)(n.default.writeFile);async function ut(n,i){if(n.condition!=null&&n.condition!==``&&!e.D(n.condition,i)){e.j(`Condition not met, skipping regex-replace task`,`info`);return}let a=r.default.join(t.default.cwd(),e.d(n.file,i)),{pattern:o}=n,s=n.flags??``,c=n.replacement||``,l=await ct(a,`utf-8`),u=new RegExp(o,s);l=l.replace(u,e.d(c,i)),await lt(a,l)}const dt={name:`regex-replace`,version:`1.0.0`,taskTypes:[`regex-replace`],execute:async(e,t,n)=>{n.dryRun||await ut(e.config,t)}},ft=(0,i.promisify)(n.default.rename);async function pt(i,a){if(i.condition!=null&&i.condition!==``&&!e.D(i.condition,a)){e.j(`Condition not met, skipping rename task`,`info`);return}let o=r.default.join(t.default.cwd(),e.d(i.from,a)),s=r.default.join(t.default.cwd(),e.d(i.to,a));if(!n.default.existsSync(o)){e.j(`Source path does not exist: ${o}`,`warn`);return}await ft(o,s)}const mt={name:`rename`,version:`1.0.0`,taskTypes:[`rename`],execute:async(e,t,n)=>{n.dryRun||await pt(e.config,t)}},ht=(0,i.promisify)(n.default.readFile),gt=(0,i.promisify)(n.default.writeFile);async function _t(i,a){if(i.condition!=null&&i.condition!==``&&!e.D(i.condition,a)){e.j(`Condition not met, skipping replace-in-file task`,`info`);return}let o=r.default.join(t.default.cwd(),e.d(i.file,a)),{replacements:s}=i;if(!n.default.existsSync(o)){e.j(`File not found: ${o}, skipping`,`warn`);return}let c=await ht(o,`utf-8`);for(let{find:t,replace:n}of s){let r=e.d(n,a);c=c.replace(new RegExp(t,`gu`),r)}await gt(o,c)}const vt={name:`replace-in-file`,version:`1.0.0`,taskTypes:[`replace-in-file`],execute:async(e,t,n)=>{n.dryRun||await _t(e.config,t)}},yt=(0,i.promisify)(n.default.readFile),bt=(0,i.promisify)(n.default.writeFile),xt=2;async function St(n,i){if(n.condition!=null&&n.condition!==``&&!e.D(n.condition,i)){e.j(`Condition not met, skipping update-json task`,`info`);return}let a=r.default.join(t.default.cwd(),e.d(n.file,i)),{updates:o}=n,s=e.y(await yt(a,`utf-8`));function c(t){if(typeof t==`string`)return e.d(t,i);if(Array.isArray(t))return t.map(e=>c(e));if(typeof t==`object`&&t){let e={};for(let[n,r]of Object.entries(t))e[n]=c(r);return e}return t}for(let[t,n]of Object.entries(o)){let r=c(n);t.includes(`.`)?e.x(s,t,r):s[t]=r}await bt(a,`${JSON.stringify(s,null,2)}\n`)}const Ct={name:`update-json`,version:`1.0.0`,taskTypes:[`update-json`],execute:async(e,t,n)=>{n.dryRun||await St(e.config,t)}},Y=(0,i.promisify)(n.default.writeFile);async function wt(i,a,o){let{allowCreate:s=!0}=i;if(i.condition!=null&&i.condition!==``&&!e.D(i.condition,a)){e.j(`Condition not met, skipping write task`,`info`);return}let c=e.d(i.file,a),l=r.default.join(t.default.cwd(),c);if(!n.default.existsSync(l)){if(s===!1)throw Error(`Write task failed: file does not exist (${c})`);e.j(`File not found, creating new file: ${c}`,`info`)}let u=x(i);if(!u.isValid)throw u.error?.includes(`cannot have both`)?e.F.templateHasBothTemplateAndFile():e.F.templateMissingTemplateOrFile();let d=await S(i,a,o),f=r.default.dirname(l);n.default.existsSync(f)||n.default.mkdirSync(f,{recursive:!0}),await Y(l,d)}const Tt={name:`write`,version:`1.0.0`,taskTypes:[`write`],execute:async(e,t,n)=>{n.dryRun||await wt(e.config,t,e)}};function X(){I(`update-json`)||(P(Ct),P(Tt),P(Ge),P(dt),P(vt),P(qe),P(mt),P($e),P(Ze),P(Ye),P(st),P(He),P(Re),P(nt))}async function Et(t,n,r=!1){if(X(),r){e.j(`[DRY RUN] Would execute: ${t.name}`,`info`);return}if(I(t.type)){await L(t,n,{dryRun:r});return}throw TypeError(`Unknown task type: ${t.type}`)}async function Z(n,r,i,a,o=!1){try{return e.j(`[${i}/${a}] Running: ${n.name}...`,`info`),await Et(n,r,o),e.j(`[${i}/${a}] Completed: ${n.name}...`,`success`),!0}catch(r){return e.j(`Failed: ${n.name}`,`error`),r instanceof Error&&(e.j(` Reason: ${r.message}`,`error`),r.stack!=null&&t.default.env.DEBUG!=null&&console.error(r.stack)),!1}}async function Dt(n,r,i){await N(`beforeAll`,r);let a=0,o=0,s=[];for(let t=0;t<n.length;t++){let c=n[t];c!=null&&(await N(`beforeTask`,c,r),await Z(c,r,t+1,n.length,i.dryRun)?(a++,await N(`afterTask`,c,r)):(await e.w(c.required,r)&&(o++,s.push(c.name)),await N(`onError`,Error(`Task ${c.name} failed`),c),e.P(`⚠️ Task "${c.name}" failed, continuing with remaining tasks...`)))}await N(`afterAll`,r),o>0&&(e.j(`\n❌ Task execution completed with ${o} error(s)`,`error`),e.j(`Completed: ${a}/${n.length} tasks`,`info`),e.j(`Failed tasks: ${s.join(`, `)}`,`error`),t.default.exit(1)),e.j(`Completed: ${a}/${n.length} tasks`,`success`)}function Q(t){let n=[],r=new Set,i=new Set,a=new Map(t.map(e=>[e.id,e]));function o(t){if(r.has(t))return;if(i.has(t))throw e.R.forTaskDependency(t);i.add(t);let s=a.get(t);if(!s)throw e.L.forId(t);if(s.dependencies)for(let e of s.dependencies)o(e);i.delete(t),r.add(t),n.push(s)}for(let e of t)r.has(e.id)||o(e.id);return n}function Ot(e){let t=[],n=e.config,r=typeof n.template==`string`?n.template:void 0,i=typeof n.templateFile==`string`?n.templateFile:void 0,a=x({...r!==void 0&&{template:r},...i!==void 0&&{templateFile:i}});return!a.isValid&&a.error!=null&&a.error!==``&&t.push(`Task "${e.id}" (${e.name}): ${a.error}`),(n.file==null||n.file===``)&&t.push(`Task "${e.id}" (${e.name}): Write task requires "file" property to specify the output file path`),t}async function kt(n,r){let i=$(n);i.length>0&&(console.error(`❌ Task validation errors:`),i.forEach(e=>console.error(` - ${e}`)),t.default.exit(1));let a=[];for(let t of n)await e.E(t.enabled,r)&&a.push(t);return a}function At(e){return Q(e)}function $(e){let t=[];for(let n of e)if(!I(n.type))t.push(`Task "${n.id}" (${n.name}): Unknown task type "${n.type}"`);else if(n.type===`write`){let e=Ot(n);t.push(...e)}return t}Object.defineProperty(exports,`A`,{enumerable:!0,get:function(){return k}}),Object.defineProperty(exports,`C`,{enumerable:!0,get:function(){return fe}}),Object.defineProperty(exports,`D`,{enumerable:!0,get:function(){return N}}),Object.defineProperty(exports,`E`,{enumerable:!0,get:function(){return de}}),Object.defineProperty(exports,`F`,{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,`I`,{enumerable:!0,get:function(){return v}}),Object.defineProperty(exports,`L`,{enumerable:!0,get:function(){return g}}),Object.defineProperty(exports,`M`,{enumerable:!0,get:function(){return D}}),Object.defineProperty(exports,`N`,{enumerable:!0,get:function(){return w}}),Object.defineProperty(exports,`O`,{enumerable:!0,get:function(){return ue}}),Object.defineProperty(exports,`P`,{enumerable:!0,get:function(){return T}}),Object.defineProperty(exports,`S`,{enumerable:!0,get:function(){return me}}),Object.defineProperty(exports,`T`,{enumerable:!0,get:function(){return P}}),Object.defineProperty(exports,`_`,{enumerable:!0,get:function(){return ve}}),Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return Dt}}),Object.defineProperty(exports,`b`,{enumerable:!0,get:function(){return F}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return Pe}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return Ae}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return Oe}}),Object.defineProperty(exports,`g`,{enumerable:!0,get:function(){return be}}),Object.defineProperty(exports,`h`,{enumerable:!0,get:function(){return V}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return Q}}),Object.defineProperty(exports,`j`,{enumerable:!0,get:function(){return O}}),Object.defineProperty(exports,`k`,{enumerable:!0,get:function(){return le}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return Ne}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return _e}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return At}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return X}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return Te}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return kt}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return Z}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return $}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return Me}}),Object.defineProperty(exports,`v`,{enumerable:!0,get:function(){return R}}),Object.defineProperty(exports,`w`,{enumerable:!0,get:function(){return pe}}),Object.defineProperty(exports,`x`,{enumerable:!0,get:function(){return I}}),Object.defineProperty(exports,`y`,{enumerable:!0,get:function(){return L}});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pixpilot/scaffoldfy",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.58.0",
|
|
5
5
|
"author": "PixPilot <m.doaie@hotmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
@@ -52,11 +52,11 @@
|
|
|
52
52
|
"eslint": "^9.38.0",
|
|
53
53
|
"tsdown": "^0.15.10",
|
|
54
54
|
"typescript": "^5.9.3",
|
|
55
|
-
"@internal/eslint-config": "0.3.0",
|
|
56
55
|
"@internal/prettier-config": "0.0.1",
|
|
57
56
|
"@internal/tsconfig": "0.1.0",
|
|
58
|
-
"@internal/
|
|
59
|
-
"@internal/tsdown-config": "0.1.0"
|
|
57
|
+
"@internal/eslint-config": "0.3.0",
|
|
58
|
+
"@internal/tsdown-config": "0.1.0",
|
|
59
|
+
"@internal/vitest-config": "0.1.0"
|
|
60
60
|
},
|
|
61
61
|
"prettier": "@internal/prettier-config",
|
|
62
62
|
"scripts": {
|
|
@@ -58,6 +58,20 @@
|
|
|
58
58
|
"description": "Top-level global prompts collected once upfront and available to all tasks.",
|
|
59
59
|
"items": { "$ref": "#/$defs/promptItem" }
|
|
60
60
|
},
|
|
61
|
+
"answers": {
|
|
62
|
+
"type": "object",
|
|
63
|
+
"description": "Pre-set prompt answers keyed by prompt id, including prompts from extended configs. Answered prompts are not asked. CLI answer flags and --set override these answers.",
|
|
64
|
+
"additionalProperties": {
|
|
65
|
+
"anyOf": [
|
|
66
|
+
{ "type": ["string", "number", "boolean"] },
|
|
67
|
+
{
|
|
68
|
+
"type": "array",
|
|
69
|
+
"description": "Choice values for a checkbox prompt",
|
|
70
|
+
"items": { "type": ["string", "number", "boolean"] }
|
|
71
|
+
}
|
|
72
|
+
]
|
|
73
|
+
}
|
|
74
|
+
},
|
|
61
75
|
"tasks": {
|
|
62
76
|
"type": "array",
|
|
63
77
|
"items": {
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import{A as e,E as t,O as n,a as r,i,j as a,o}from"./configurations-sRFCjZJV.js";import{O as s,a as c,c as l,l as u,n as d,o as f,r as p,u as m}from"./tasks-CoJIuLRc.js";import h from"node:process";async function g(e,t){let n=e.prompts??[];if(n.length>0){let e=l(n);e.length>0&&(console.error(`❌ Prompt validation errors:`),e.forEach(e=>console.error(` - ${e}`)),h.exit(1));let r=await m(n,await u(n,t),t);Object.assign(t,r)}}async function _(e,t){let n=e.variables??[];if(n.length>0){let a=i(n);a.length>0&&(console.error(`❌ Variable validation errors:`),a.forEach(e=>console.error(` - ${e}`)),h.exit(1));let s=await o(n,await r(n,t,{skipConditional:!0}),t);Object.assign(t,s),await v(e,t)}}async function v(e,t){let n=e.variables??[];if(n.length===0)return;let i=n.filter(e=>typeof e.value==`object`&&e.value!==null&&!Array.isArray(e.value)?e.value.type===`conditional`:!1);if(i.length>0){let e=await o(i,await r(i,t),t);Object.assign(t,e)}}async function y(n,r){return await t(n.enabled,r)?(await _(n,r),await g(n,r),await v(n,r),await t(n.enabled,r)?!0:(e(`⊘ Config "${n.name}" became disabled after variable/prompt resolution - skipping tasks`),!1)):(e(`⊘ Config "${n.name}" is disabled - skipping`),!1)}async function b(t,r,i={}){n(`Running configs with sequential variable/prompt resolution...`),n(`Total configs to process: ${t.length}`),n(`Registering built-in plugins...`),f();let o=[];console.log(``),e(`📋 Collecting input...`),console.log(``);for(let e=0;e<t.length;e++){let r=t[e];if(r==null)continue;let a=`=`.repeat(60);if(n(`\n${a}`),n(`Processing config ${e+1}/${t.length}: "${r.name}"`),n(a),n(`Current config keys: ${Object.keys(i).join(`, `)}`),await y(r,i)){let e=r.tasks??[];e.length>0&&(n(`Found ${e.length} task(s) in config "${r.name}" (will execute later)`),o.push(...e))}}if(n(`
|
|
2
|
-
🔧 Validating and filtering all collected tasks...`),o.length===0){a(`No tasks found in any config`,`info`);return}console.log(``),a(`🛠️ Preparing tasks...`,`info`);let l=await p(o,i);if(console.log(``),a(`Found ${o.length} tasks (${l.length} enabled)`,`info`),a(`All tasks validated successfully`,`success`),l.length===0){a(`No enabled tasks to execute`,`info`);return}let u=d(l);if(r.dryRun){a(`
|
|
3
|
-
🔍 Dry run - showing task changes...`,`info`),await s(u,i),a(`
|
|
4
|
-
🔍 Dry run completed - no changes were made`,`info`),a(`Run without --dry-run to apply changes`,`info`);return}console.log(``),e(`⚙️ Executing tasks...`),console.log(``),await c(u,i,r)}export{b as runConfigurationSequentially};
|