@pixpilot/scaffoldfy 0.19.3 → 0.21.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/README.md CHANGED
@@ -4,7 +4,7 @@ A flexible and powerful task automation utility for project setup, cleanup, and
4
4
 
5
5
  ## Features
6
6
 
7
- - 🔄 **9 Task Types** - update-json, template, regex-replace, replace-in-file, delete, conditional-delete, rename, git-init, exec
7
+ - 🔄 **9 Task Types** - update-json, write, regex-replace, replace-in-file, delete, conditional-delete, rename, git-init, exec
8
8
  - 🧩 **Template Inheritance** - Extend base templates for code reuse
9
9
  - 🔍 **Dry-Run Mode with Diff** - Preview exact changes before applying
10
10
  - 🔌 **Plugin System** - Create custom task types and lifecycle hooks
package/dist/cli.cjs CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- const e=require(`./utils-BeLs5aXN.cjs`),t=require(`./src-BWFVB-OE.cjs`);let n=require(`node:fs`);n=e.v(n);let r=require(`node:path`);r=e.v(r);let i=require(`node:process`);i=e.v(i);let a=require(`commander`);a=e.v(a);let o=require(`node:url`);o=e.v(o);let s=require(`ajv`);s=e.v(s);const c=1,l=(0,o.fileURLToPath)(require(`url`).pathToFileURL(__filename).href),u=r.default.dirname(l);function d(){return new s.default({allErrors:!0,verbose:!0,strict:!1,discriminator:!0})}function f(){let e=r.default.join(u,`..`,`schema`,`tasks.schema.json`);try{let t=n.default.readFileSync(e,`utf-8`);return JSON.parse(t)}catch(t){throw Error(`Failed to load tasks schema from ${e}: ${t instanceof Error?t.message:String(t)}`)}}function p(e){return e.filter(t=>{if(t.keyword===`oneOf`){let e=t.params;if(e.passingSchemas&&e.passingSchemas.length>0)return!1}if(t.keyword===`required`){let n=e.find(e=>e.keyword===`oneOf`&&e.instancePath===t.instancePath);if(n){let e=n.params;if(e.passingSchemas&&e.passingSchemas.length>0)return!1}}return!0}).map(e=>{let t=e.instancePath||`root`,n=e.message??`Unknown error`;switch(e.keyword){case`required`:return`${t}: Missing required property "${String(e.params.missingProperty??`unknown`)}"`;case`type`:return`${t}: Expected type "${String(e.params.type??`unknown`)}", received "${typeof e.data}"`;case`enum`:{let r=e.params.allowedValues;return`${t}: ${n}. Allowed values: ${Array.isArray(r)?r.join(`, `):String(r)}`}case`pattern`:{let{pattern:r}=e.params;return`${t}: ${n}. Value must match pattern: ${String(r)}`}case`oneOf`:return`${t}: ${n}. Configuration must match exactly one of the allowed schemas`;case`additionalProperties`:return`${t}: ${n}. Unknown property: "${String(e.params.additionalProperty??`unknown`)}"`;default:return`${t}: ${n}`}})}function m(t,n={}){try{let e=d(),r=f(),i=e.compile(r);if(!i(t)&&i.errors){let e=p(i.errors);return e.length===0?{valid:!0,errors:[]}:(n.silent||h(e),{valid:!1,errors:e})}return{valid:!0,errors:[]}}catch(t){let r=t instanceof Error?t.message:`Unknown error occurred during schema validation`;return n.silent||(e.o(`❌ Schema validation error:`,`error`),e.o(` ${r}`,`error`)),{valid:!1,errors:[r]}}}function h(t){e.o(`❌ Schema validation failed:`,`error`),e.o(``,`error`),e.o(`The following validation errors were found:`,`error`),e.o(``,`error`);for(let n of t)e.o(` • ${n}`,`error`);e.o(``,`error`),e.o(`Please fix these errors in your template configuration file.`,`error`),e.o(``,`error`),e.o(`For schema documentation, see: https://github.com/pixpilot/scaffoldfy/tree/main/packages/scaffoldfy/schema`,`info`)}const g=new a.Command,_=r.default.join(__dirname,`..`,`package.json`);let v=`0.0.0`;try{v=JSON.parse(n.default.readFileSync(_,`utf-8`)).version??`0.0.0`}catch{}g.name(`scaffoldfy`).description(`Automate project setup and configuration with customizable tasks`).version(v),g.option(`--dry-run`,`Run in dry mode without making any changes`).option(`--force`,`Force execution even if checks fail`).option(`--tasks-file <path>`,`Path to JSON file containing task definitions`,`./template-tasks.json`).option(`--tasks-ts <path>`,`Path to TypeScript file exporting tasks`,`./template-tasks.ts`).option(`--no-validate`,`Skip schema validation of task configuration (validation is enabled by default)`).action(async a=>{try{let o=[],s,c,l;if(a.tasksTs!=null&&a.tasksTs!==``){let t=r.default.resolve(i.default.cwd(),a.tasksTs);if(n.default.existsSync(t)){e.o(`Loading tasks from TypeScript file: ${a.tasksTs}`,`info`),l=t;try{let n=await import(t);o=n.default??n.tasks??[],(!Array.isArray(o)||o.length===0)&&(e.o(`⚠️ No tasks found in TypeScript file or invalid format`,`warn`),e.o(`Expected default export or named export "tasks" with TaskDefinition[]`,`info`))}catch(t){e.o(`Failed to load TypeScript tasks file: ${a.tasksTs}`,`error`),t instanceof Error&&e.o(` Error: ${t.message}`,`error`),i.default.exit(1)}}}if(o.length===0&&a.tasksFile!=null&&a.tasksFile!==``){let u=r.default.resolve(i.default.cwd(),a.tasksFile);if(n.default.existsSync(u)){l=u;try{if(a.validate!==!1){e.o(`Validating task configuration against schema...`,`info`);let t=n.default.readFileSync(u,`utf-8`);m(JSON.parse(t),{silent:!1}).valid||(e.o(``,`error`),e.o(`💡 You can skip validation with --no-validate flag, but this is not recommended.`,`info`),i.default.exit(1)),e.o(`✓ Schema validation passed`,`success`)}let r=await t.p(u);o=r.tasks,s=r.variables,c=r.prompts,Array.isArray(o)||(e.o(`❌ Invalid tasks file format`,`error`),e.o(`Expected JSON with { "tasks": [...] } structure`,`info`),i.default.exit(1))}catch(t){e.o(`Failed to load JSON tasks file: ${a.tasksFile}`,`error`),t instanceof Error&&e.o(` Error: ${t.message}`,`error`),i.default.exit(1)}}else e.o(`Tasks file not found: ${a.tasksFile}`,`warn`)}let u=c!=null&&c.length>0||s!=null&&s.length>0;o.length===0&&!u&&(e.o(`❌ No tasks defined`,`error`),e.o(`Please provide tasks using one of these methods:`,`info`),e.o(` 1. Create a template-tasks.json file in the current directory`,`info`),e.o(` 2. Create a template-tasks.ts file in the current directory`,`info`),e.o(` 3. Use --tasks-file option to specify a different JSON file`,`info`),e.o(` 4. Use --tasks-ts option to specify a different TypeScript file`,`info`),e.o(`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)),o.length===0?e.o(`Loaded template with 0 tasks (template may only provide prompts/variables for extending)`,`info`):e.o(`Loaded ${o.length} task(s)`,`success`),await t.n(o,{dryRun:a.dryRun,force:a.force,tasksFilePath:l,globalVariables:s,globalPrompts:c})}catch(t){if(e.o(`❌ CLI execution failed`,`error`),t instanceof Error){e.o(`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)}}),g.parse(i.default.argv);
2
+ const e=require(`./utils-CdfjwUZm.cjs`),t=require(`./src-yawjKD-O.cjs`);let n=require(`node:fs`);n=e._(n);let r=require(`node:path`);r=e._(r);let i=require(`node:process`);i=e._(i);let a=require(`commander`);a=e._(a);let o=require(`node:url`);o=e._(o);let s=require(`ajv`);s=e._(s);const c=1,l=(0,o.fileURLToPath)(require(`url`).pathToFileURL(__filename).href),u=r.default.dirname(l);function d(){return new s.default({allErrors:!0,verbose:!0,strict:!1,discriminator:!0})}function f(){let e=r.default.join(u,`..`,`schema`,`tasks.schema.json`);try{let t=n.default.readFileSync(e,`utf-8`);return JSON.parse(t)}catch(t){throw Error(`Failed to load tasks schema from ${e}: ${t instanceof Error?t.message:String(t)}`)}}function p(e){return e.filter(t=>{if(t.keyword===`oneOf`){let e=t.params;if(e.passingSchemas&&e.passingSchemas.length>0)return!1}if(t.keyword===`required`){let n=e.find(e=>e.keyword===`oneOf`&&e.instancePath===t.instancePath);if(n){let e=n.params;if(e.passingSchemas&&e.passingSchemas.length>0)return!1}}return!0}).map(e=>{let t=e.instancePath||`root`,n=e.message??`Unknown error`;switch(e.keyword){case`required`:return`${t}: Missing required property "${String(e.params.missingProperty??`unknown`)}"`;case`type`:return`${t}: Expected type "${String(e.params.type??`unknown`)}", received "${typeof e.data}"`;case`enum`:{let r=e.params.allowedValues;return`${t}: ${n}. Allowed values: ${Array.isArray(r)?r.join(`, `):String(r)}`}case`pattern`:{let{pattern:r}=e.params;return`${t}: ${n}. Value must match pattern: ${String(r)}`}case`oneOf`:return`${t}: ${n}. Configuration must match exactly one of the allowed schemas`;case`additionalProperties`:return`${t}: ${n}. Unknown property: "${String(e.params.additionalProperty??`unknown`)}"`;default:return`${t}: ${n}`}})}function m(t,n={}){try{let e=d(),r=f(),i=e.compile(r);if(!i(t)&&i.errors){let e=p(i.errors);return e.length===0?{valid:!0,errors:[]}:(n.silent||h(e),{valid:!1,errors:e})}return{valid:!0,errors:[]}}catch(t){let r=t instanceof Error?t.message:`Unknown error occurred during schema validation`;return n.silent||(e.i(`❌ Schema validation error:`,`error`),e.i(` ${r}`,`error`)),{valid:!1,errors:[r]}}}function h(t){e.i(`❌ Schema validation failed:`,`error`),e.i(``,`error`),e.i(`The following validation errors were found:`,`error`),e.i(``,`error`);for(let n of t)e.i(` • ${n}`,`error`);e.i(``,`error`),e.i(`Please fix these errors in your template configuration file.`,`error`),e.i(``,`error`),e.i(`For schema documentation, see: https://github.com/pixpilot/scaffoldfy/tree/main/packages/scaffoldfy/schema`,`info`)}const g=new a.Command,_=r.default.join(__dirname,`..`,`package.json`);let v=`0.0.0`;try{v=JSON.parse(n.default.readFileSync(_,`utf-8`)).version??`0.0.0`}catch{}g.name(`scaffoldfy`).description(`Automate project setup and configuration with customizable tasks`).version(v),g.option(`--dry-run`,`Run in dry mode without making any changes`).option(`--force`,`Force execution even if checks fail`).option(`--tasks-file <path>`,`Path to JSON file containing task definitions`,`./template-tasks.json`).option(`--tasks-ts <path>`,`Path to TypeScript file exporting tasks`,`./template-tasks.ts`).option(`--no-validate`,`Skip schema validation of task configuration (validation is enabled by default)`).action(async a=>{try{let o=[],s,c,l,u;if(a.tasksTs!=null&&a.tasksTs!==``){let t=r.default.resolve(i.default.cwd(),a.tasksTs);if(n.default.existsSync(t)){e.i(`Loading tasks from TypeScript file: ${a.tasksTs}`,`info`),u=t;try{let n=await import(t);o=n.default??n.tasks??[],(!Array.isArray(o)||o.length===0)&&(e.i(`⚠️ No tasks found in TypeScript file or invalid format`,`warn`),e.i(`Expected default export or named export "tasks" with TaskDefinition[]`,`info`))}catch(t){e.i(`Failed to load TypeScript tasks file: ${a.tasksTs}`,`error`),t instanceof Error&&e.i(` Error: ${t.message}`,`error`),i.default.exit(1)}}}if(o.length===0&&a.tasksFile!=null&&a.tasksFile!==``){let d=r.default.resolve(i.default.cwd(),a.tasksFile);if(n.default.existsSync(d)){u=d;try{if(a.validate!==!1){e.i(`Validating task configuration against schema...`,`info`);let t=n.default.readFileSync(d,`utf-8`);m(JSON.parse(t),{silent:!1}).valid||(e.i(``,`error`),e.i(`💡 You can skip validation with --no-validate flag, but this is not recommended.`,`info`),i.default.exit(1)),e.i(`✓ Schema validation passed`,`success`)}let r=await t.q(d);o=r.tasks,s=r.variables,c=r.prompts,l=r.enabled,Array.isArray(o)||(e.i(`❌ Invalid tasks file format`,`error`),e.i(`Expected JSON with { "tasks": [...] } structure`,`info`),i.default.exit(1))}catch(t){e.i(`Failed to load JSON tasks file: ${a.tasksFile}`,`error`),t instanceof Error&&e.i(` Error: ${t.message}`,`error`),i.default.exit(1)}}else e.i(`Tasks file not found: ${a.tasksFile}`,`warn`)}let d=c!=null&&c.length>0||s!=null&&s.length>0;o.length===0&&!d&&(e.i(`❌ No tasks defined`,`error`),e.i(`Please provide tasks using one of these methods:`,`info`),e.i(` 1. Create a template-tasks.json file in the current directory`,`info`),e.i(` 2. Create a template-tasks.ts file in the current directory`,`info`),e.i(` 3. Use --tasks-file option to specify a different JSON file`,`info`),e.i(` 4. Use --tasks-ts option to specify a different TypeScript file`,`info`),e.i(`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)),o.length===0?e.i(`Loaded template with 0 tasks (template may only provide prompts/variables for extending)`,`info`):e.i(`Loaded ${o.length} task(s)`,`success`),await t.n(o,{dryRun:a.dryRun,force:a.force,tasksFilePath:u,globalVariables:s,globalPrompts:c,templateEnabled:l})}catch(t){if(e.i(`❌ CLI execution failed`,`error`),t instanceof Error){e.i(`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)}}),g.parse(i.default.argv);
package/dist/cli.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{n as e,p as t}from"./src-DYtpmv9N.js";import{o as n}from"./utils-ii_k_uXl.js";import r from"node:path";import{fileURLToPath as i}from"node:url";import a from"node:fs";import o from"node:process";import{Command as s}from"commander";import c from"ajv";const l=()=>i(import.meta.url),u=(()=>r.dirname(l()))(),d=i(import.meta.url),f=r.dirname(d);function p(){return new c({allErrors:!0,verbose:!0,strict:!1,discriminator:!0})}function m(){let e=r.join(f,`..`,`schema`,`tasks.schema.json`);try{let t=a.readFileSync(e,`utf-8`);return JSON.parse(t)}catch(t){throw Error(`Failed to load tasks schema from ${e}: ${t instanceof Error?t.message:String(t)}`)}}function h(e){return e.filter(t=>{if(t.keyword===`oneOf`){let e=t.params;if(e.passingSchemas&&e.passingSchemas.length>0)return!1}if(t.keyword===`required`){let n=e.find(e=>e.keyword===`oneOf`&&e.instancePath===t.instancePath);if(n){let e=n.params;if(e.passingSchemas&&e.passingSchemas.length>0)return!1}}return!0}).map(e=>{let t=e.instancePath||`root`,n=e.message??`Unknown error`;switch(e.keyword){case`required`:return`${t}: Missing required property "${String(e.params.missingProperty??`unknown`)}"`;case`type`:return`${t}: Expected type "${String(e.params.type??`unknown`)}", received "${typeof e.data}"`;case`enum`:{let r=e.params.allowedValues;return`${t}: ${n}. Allowed values: ${Array.isArray(r)?r.join(`, `):String(r)}`}case`pattern`:{let{pattern:r}=e.params;return`${t}: ${n}. Value must match pattern: ${String(r)}`}case`oneOf`:return`${t}: ${n}. Configuration must match exactly one of the allowed schemas`;case`additionalProperties`:return`${t}: ${n}. Unknown property: "${String(e.params.additionalProperty??`unknown`)}"`;default:return`${t}: ${n}`}})}function g(e,t={}){try{let n=p(),r=m(),i=n.compile(r);if(!i(e)&&i.errors){let e=h(i.errors);return e.length===0?{valid:!0,errors:[]}:(t.silent||_(e),{valid:!1,errors:e})}return{valid:!0,errors:[]}}catch(e){let r=e instanceof Error?e.message:`Unknown error occurred during schema validation`;return t.silent||(n(`❌ Schema validation error:`,`error`),n(` ${r}`,`error`)),{valid:!1,errors:[r]}}}function _(e){n(`❌ Schema validation failed:`,`error`),n(``,`error`),n(`The following validation errors were found:`,`error`),n(``,`error`);for(let t of e)n(` • ${t}`,`error`);n(``,`error`),n(`Please fix these errors in your template configuration file.`,`error`),n(``,`error`),n(`For schema documentation, see: https://github.com/pixpilot/scaffoldfy/tree/main/packages/scaffoldfy/schema`,`info`)}const v=new s,y=r.join(u,`..`,`package.json`);let b=`0.0.0`;try{b=JSON.parse(a.readFileSync(y,`utf-8`)).version??`0.0.0`}catch{}v.name(`scaffoldfy`).description(`Automate project setup and configuration with customizable tasks`).version(b),v.option(`--dry-run`,`Run in dry mode without making any changes`).option(`--force`,`Force execution even if checks fail`).option(`--tasks-file <path>`,`Path to JSON file containing task definitions`,`./template-tasks.json`).option(`--tasks-ts <path>`,`Path to TypeScript file exporting tasks`,`./template-tasks.ts`).option(`--no-validate`,`Skip schema validation of task configuration (validation is enabled by default)`).action(async i=>{try{let s=[],c,l,u;if(i.tasksTs!=null&&i.tasksTs!==``){let e=r.resolve(o.cwd(),i.tasksTs);if(a.existsSync(e)){n(`Loading tasks from TypeScript file: ${i.tasksTs}`,`info`),u=e;try{let t=await import(e);s=t.default??t.tasks??[],(!Array.isArray(s)||s.length===0)&&(n(`⚠️ No tasks found in TypeScript file or invalid format`,`warn`),n(`Expected default export or named export "tasks" with TaskDefinition[]`,`info`))}catch(e){n(`Failed to load TypeScript tasks file: ${i.tasksTs}`,`error`),e instanceof Error&&n(` Error: ${e.message}`,`error`),o.exit(1)}}}if(s.length===0&&i.tasksFile!=null&&i.tasksFile!==``){let e=r.resolve(o.cwd(),i.tasksFile);if(a.existsSync(e)){u=e;try{if(i.validate!==!1){n(`Validating task configuration against schema...`,`info`);let t=a.readFileSync(e,`utf-8`);g(JSON.parse(t),{silent:!1}).valid||(n(``,`error`),n(`💡 You can skip validation with --no-validate flag, but this is not recommended.`,`info`),o.exit(1)),n(`✓ Schema validation passed`,`success`)}let r=await t(e);s=r.tasks,c=r.variables,l=r.prompts,Array.isArray(s)||(n(`❌ Invalid tasks file format`,`error`),n(`Expected JSON with { "tasks": [...] } structure`,`info`),o.exit(1))}catch(e){n(`Failed to load JSON tasks file: ${i.tasksFile}`,`error`),e instanceof Error&&n(` Error: ${e.message}`,`error`),o.exit(1)}}else n(`Tasks file not found: ${i.tasksFile}`,`warn`)}let d=l!=null&&l.length>0||c!=null&&c.length>0;s.length===0&&!d&&(n(`❌ No tasks defined`,`error`),n(`Please provide tasks using one of these methods:`,`info`),n(` 1. Create a template-tasks.json file in the current directory`,`info`),n(` 2. Create a template-tasks.ts file in the current directory`,`info`),n(` 3. Use --tasks-file option to specify a different JSON file`,`info`),n(` 4. Use --tasks-ts option to specify a different TypeScript file`,`info`),n(`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)),o.exit(1)),s.length===0?n(`Loaded template with 0 tasks (template may only provide prompts/variables for extending)`,`info`):n(`Loaded ${s.length} task(s)`,`success`),await e(s,{dryRun:i.dryRun,force:i.force,tasksFilePath:u,globalVariables:c,globalPrompts:l})}catch(e){if(n(`❌ CLI execution failed`,`error`),e instanceof Error){n(`Error: ${e.message}`,`error`);let t=o.env.DEBUG;t!=null&&t!==``&&console.error(e.stack)}else console.error(e);o.exit(1)}}),v.parse(o.argv);export{};
2
+ import{n as e,q as t}from"./src-DIM5YRco.js";import{i as n}from"./utils-DfD7I1u2.js";import r from"node:path";import{fileURLToPath as i}from"node:url";import a from"node:fs";import o from"node:process";import{Command as s}from"commander";import c from"ajv";const l=()=>i(import.meta.url),u=(()=>r.dirname(l()))(),d=i(import.meta.url),f=r.dirname(d);function p(){return new c({allErrors:!0,verbose:!0,strict:!1,discriminator:!0})}function m(){let e=r.join(f,`..`,`schema`,`tasks.schema.json`);try{let t=a.readFileSync(e,`utf-8`);return JSON.parse(t)}catch(t){throw Error(`Failed to load tasks schema from ${e}: ${t instanceof Error?t.message:String(t)}`)}}function h(e){return e.filter(t=>{if(t.keyword===`oneOf`){let e=t.params;if(e.passingSchemas&&e.passingSchemas.length>0)return!1}if(t.keyword===`required`){let n=e.find(e=>e.keyword===`oneOf`&&e.instancePath===t.instancePath);if(n){let e=n.params;if(e.passingSchemas&&e.passingSchemas.length>0)return!1}}return!0}).map(e=>{let t=e.instancePath||`root`,n=e.message??`Unknown error`;switch(e.keyword){case`required`:return`${t}: Missing required property "${String(e.params.missingProperty??`unknown`)}"`;case`type`:return`${t}: Expected type "${String(e.params.type??`unknown`)}", received "${typeof e.data}"`;case`enum`:{let r=e.params.allowedValues;return`${t}: ${n}. Allowed values: ${Array.isArray(r)?r.join(`, `):String(r)}`}case`pattern`:{let{pattern:r}=e.params;return`${t}: ${n}. Value must match pattern: ${String(r)}`}case`oneOf`:return`${t}: ${n}. Configuration must match exactly one of the allowed schemas`;case`additionalProperties`:return`${t}: ${n}. Unknown property: "${String(e.params.additionalProperty??`unknown`)}"`;default:return`${t}: ${n}`}})}function g(e,t={}){try{let n=p(),r=m(),i=n.compile(r);if(!i(e)&&i.errors){let e=h(i.errors);return e.length===0?{valid:!0,errors:[]}:(t.silent||_(e),{valid:!1,errors:e})}return{valid:!0,errors:[]}}catch(e){let r=e instanceof Error?e.message:`Unknown error occurred during schema validation`;return t.silent||(n(`❌ Schema validation error:`,`error`),n(` ${r}`,`error`)),{valid:!1,errors:[r]}}}function _(e){n(`❌ Schema validation failed:`,`error`),n(``,`error`),n(`The following validation errors were found:`,`error`),n(``,`error`);for(let t of e)n(` • ${t}`,`error`);n(``,`error`),n(`Please fix these errors in your template configuration file.`,`error`),n(``,`error`),n(`For schema documentation, see: https://github.com/pixpilot/scaffoldfy/tree/main/packages/scaffoldfy/schema`,`info`)}const v=new s,y=r.join(u,`..`,`package.json`);let b=`0.0.0`;try{b=JSON.parse(a.readFileSync(y,`utf-8`)).version??`0.0.0`}catch{}v.name(`scaffoldfy`).description(`Automate project setup and configuration with customizable tasks`).version(b),v.option(`--dry-run`,`Run in dry mode without making any changes`).option(`--force`,`Force execution even if checks fail`).option(`--tasks-file <path>`,`Path to JSON file containing task definitions`,`./template-tasks.json`).option(`--tasks-ts <path>`,`Path to TypeScript file exporting tasks`,`./template-tasks.ts`).option(`--no-validate`,`Skip schema validation of task configuration (validation is enabled by default)`).action(async i=>{try{let s=[],c,l,u,d;if(i.tasksTs!=null&&i.tasksTs!==``){let e=r.resolve(o.cwd(),i.tasksTs);if(a.existsSync(e)){n(`Loading tasks from TypeScript file: ${i.tasksTs}`,`info`),d=e;try{let t=await import(e);s=t.default??t.tasks??[],(!Array.isArray(s)||s.length===0)&&(n(`⚠️ No tasks found in TypeScript file or invalid format`,`warn`),n(`Expected default export or named export "tasks" with TaskDefinition[]`,`info`))}catch(e){n(`Failed to load TypeScript tasks file: ${i.tasksTs}`,`error`),e instanceof Error&&n(` Error: ${e.message}`,`error`),o.exit(1)}}}if(s.length===0&&i.tasksFile!=null&&i.tasksFile!==``){let e=r.resolve(o.cwd(),i.tasksFile);if(a.existsSync(e)){d=e;try{if(i.validate!==!1){n(`Validating task configuration against schema...`,`info`);let t=a.readFileSync(e,`utf-8`);g(JSON.parse(t),{silent:!1}).valid||(n(``,`error`),n(`💡 You can skip validation with --no-validate flag, but this is not recommended.`,`info`),o.exit(1)),n(`✓ Schema validation passed`,`success`)}let r=await t(e);s=r.tasks,c=r.variables,l=r.prompts,u=r.enabled,Array.isArray(s)||(n(`❌ Invalid tasks file format`,`error`),n(`Expected JSON with { "tasks": [...] } structure`,`info`),o.exit(1))}catch(e){n(`Failed to load JSON tasks file: ${i.tasksFile}`,`error`),e instanceof Error&&n(` Error: ${e.message}`,`error`),o.exit(1)}}else n(`Tasks file not found: ${i.tasksFile}`,`warn`)}let f=l!=null&&l.length>0||c!=null&&c.length>0;s.length===0&&!f&&(n(`❌ No tasks defined`,`error`),n(`Please provide tasks using one of these methods:`,`info`),n(` 1. Create a template-tasks.json file in the current directory`,`info`),n(` 2. Create a template-tasks.ts file in the current directory`,`info`),n(` 3. Use --tasks-file option to specify a different JSON file`,`info`),n(` 4. Use --tasks-ts option to specify a different TypeScript file`,`info`),n(`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)),o.exit(1)),s.length===0?n(`Loaded template with 0 tasks (template may only provide prompts/variables for extending)`,`info`):n(`Loaded ${s.length} task(s)`,`success`),await e(s,{dryRun:i.dryRun,force:i.force,tasksFilePath:d,globalVariables:c,globalPrompts:l,templateEnabled:u})}catch(e){if(n(`❌ CLI execution failed`,`error`),e instanceof Error){n(`Error: ${e.message}`,`error`);let t=o.env.DEBUG;t!=null&&t!==``&&console.error(e.stack)}else console.error(e);o.exit(1)}}),v.parse(o.argv);export{};
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- const e=require(`./utils-BeLs5aXN.cjs`),t=require(`./src-BWFVB-OE.cjs`);exports.callHook=t.b,exports.clearPlugins=t.x,exports.clearTemplateCache=t.d,exports.collectPrompts=t.v,exports.collectVariables=t.o,exports.createPlugin=t.S,exports.displayTasksDiff=t.N,exports.evaluateCondition=e.r,exports.executePluginTask=t.C,exports.executeTask=t.c,exports.getDeleteDiff=t.P,exports.getExecDiff=t.F,exports.getGitInitDiff=t.I,exports.getGitRepoInfo=e.i,exports.getPlugin=t.w,exports.getPluginForTaskType=t.T,exports.getPluginTaskDiff=t.E,exports.getRegexReplaceDiff=t.L,exports.getRenameDiff=t.R,exports.getReplaceInFileDiff=t.z,exports.getTaskDiff=t.B,exports.getTemplateDiff=t.V,exports.getUpdateJsonDiff=t.H,exports.interpolateTemplate=e.a,exports.isPluginTaskType=t.D,exports.listPlugins=t.O,exports.loadAndMergeTemplate=t.f,exports.loadTasksWithInheritance=t.p,exports.loadTemplate=t.m,exports.log=e.o,exports.main=t.t,exports.mergeTemplates=t.h,exports.prompt=e.s,exports.promptYesNo=e.c,exports.registerBuiltInPlugins=t.l,exports.registerHooks=t.k,exports.registerPlugin=t.A,exports.resolveAllDefaultValues=t._,exports.resolveAllVariableValues=t.i,exports.resolveDefaultValue=t.y,exports.resolveVariableValue=t.a,exports.runTask=t.u,exports.runWithTasks=t.n,exports.setNestedProperty=e.l,exports.topologicalSort=t.s,exports.unregisterPlugin=t.j,exports.validatePluginTask=t.M,exports.validatePrompts=t.g,exports.validateVariables=t.r;
1
+ const e=require(`./utils-CdfjwUZm.cjs`),t=require(`./src-yawjKD-O.cjs`);exports.callHook=t.h,exports.clearPlugins=t.g,exports.clearTemplateCache=t.G,exports.collectPrompts=t.p,exports.collectVariables=t.o,exports.createPlugin=t._,exports.displayTasksDiff=t.O,exports.evaluateCondition=e.t,exports.executePluginTask=t.v,exports.executeTask=t.c,exports.getCreateDiff=t.k,exports.getDeleteDiff=t.A,exports.getExecDiff=t.j,exports.getGitInitDiff=t.M,exports.getGitRepoInfo=e.n,exports.getPlugin=t.y,exports.getPluginForTaskType=t.b,exports.getPluginTaskDiff=t.x,exports.getRegexReplaceDiff=t.N,exports.getRenameDiff=t.P,exports.getReplaceInFileDiff=t.F,exports.getTaskDiff=t.I,exports.getTemplateSourceDescription=t.z,exports.getUpdateJsonDiff=t.L,exports.getWriteDiff=t.R,exports.hasInlineTemplate=t.B,exports.hasTemplateFile=t.V,exports.interpolateTemplate=e.r,exports.isPluginTaskType=t.S,exports.listPlugins=t.C,exports.loadAndMergeTemplate=t.K,exports.loadTasksWithInheritance=t.q,exports.loadTemplate=t.J,exports.log=e.i,exports.main=t.t,exports.mergeTemplates=t.Y,exports.processTemplate=t.H,exports.prompt=e.a,exports.promptYesNo=e.o,exports.registerBuiltInPlugins=t.l,exports.registerHooks=t.w,exports.registerPlugin=t.T,exports.resolveAllDefaultValues=t.f,exports.resolveAllVariableValues=t.i,exports.resolveDefaultValue=t.m,exports.resolveVariableValue=t.a,exports.runTask=t.u,exports.runWithTasks=t.n,exports.setNestedProperty=e.s,exports.shouldUseHandlebars=t.U,exports.topologicalSort=t.s,exports.unregisterPlugin=t.E,exports.validatePluginTask=t.D,exports.validatePrompts=t.d,exports.validateTemplateConfig=t.W,exports.validateVariables=t.r;
package/dist/index.d.cts CHANGED
@@ -1,5 +1,22 @@
1
- //#region src/plugins/create/types.d.ts
1
+ //#region src/plugins/append/types.d.ts
2
2
 
3
+ interface AppendConfig {
4
+ file: string;
5
+ content?: string;
6
+ template?: string;
7
+ templateFile?: string;
8
+ newline?: boolean;
9
+ condition?: ConditionExpression;
10
+ }
11
+ //#endregion
12
+ //#region src/plugins/copy/types.d.ts
13
+ interface CopyConfig {
14
+ from: string;
15
+ to: string;
16
+ condition?: ConditionExpression;
17
+ }
18
+ //#endregion
19
+ //#region src/plugins/create/types.d.ts
3
20
  interface CreateConfig {
4
21
  file: string;
5
22
  template?: string;
@@ -28,6 +45,19 @@ interface GitInitConfig {
28
45
  condition?: ConditionExpression;
29
46
  }
30
47
  //#endregion
48
+ //#region src/plugins/mkdir/types.d.ts
49
+ interface MkdirConfig {
50
+ path: string;
51
+ condition?: ConditionExpression;
52
+ }
53
+ //#endregion
54
+ //#region src/plugins/move/types.d.ts
55
+ interface MoveConfig {
56
+ from: string;
57
+ to: string;
58
+ condition?: ConditionExpression;
59
+ }
60
+ //#endregion
31
61
  //#region src/plugins/regex-replace/types.d.ts
32
62
  interface RegexReplaceConfig {
33
63
  file: string;
@@ -54,18 +84,18 @@ interface ReplaceInFileConfig {
54
84
  condition?: ConditionExpression;
55
85
  }
56
86
  //#endregion
57
- //#region src/plugins/template/types.d.ts
58
- interface TemplateConfig {
87
+ //#region src/plugins/update-json/types.d.ts
88
+ interface UpdateJsonConfig {
59
89
  file: string;
60
- template?: string;
61
- templateFile?: string;
90
+ updates: Record<string, unknown>;
62
91
  condition?: ConditionExpression;
63
92
  }
64
93
  //#endregion
65
- //#region src/plugins/update-json/types.d.ts
66
- interface UpdateJsonConfig {
94
+ //#region src/plugins/write/types.d.ts
95
+ interface WriteConfig {
67
96
  file: string;
68
- updates: Record<string, unknown>;
97
+ template?: string;
98
+ templateFile?: string;
69
99
  condition?: ConditionExpression;
70
100
  }
71
101
  //#endregion
@@ -117,12 +147,21 @@ interface ConditionalEnabled {
117
147
  condition: ConditionExpression;
118
148
  }
119
149
  /**
120
- * Type for enabled field that can be boolean, string condition, or conditional object
150
+ * Executable enabled configuration
151
+ * Determines enabled state by executing a shell command
152
+ */
153
+ interface ExecutableEnabled {
154
+ type: 'exec';
155
+ value: string;
156
+ }
157
+ /**
158
+ * Type for enabled field that can be boolean, string condition, conditional object, or executable
121
159
  * - boolean: Simple true/false
122
160
  * - string: JavaScript expression to evaluate (shorthand for { condition: "..." })
123
161
  * - ConditionalEnabled: Object with condition property
162
+ * - ExecutableEnabled: Object with type='exec' and value=command
124
163
  */
125
- type EnabledValue = boolean | string | ConditionalEnabled;
164
+ type EnabledValue = boolean | string | ConditionalEnabled | ExecutableEnabled;
126
165
  interface BasePrompt {
127
166
  id: string;
128
167
  type: PromptType;
@@ -174,7 +213,7 @@ interface VariableDefinition {
174
213
  * @example "packageManager === 'pnpm'"
175
214
  */
176
215
  type ConditionExpression = string;
177
- type TaskType = 'update-json' | 'template' | 'create' | 'regex-replace' | 'replace-in-file' | 'delete' | 'rename' | 'git-init' | 'exec';
216
+ type TaskType = 'update-json' | 'write' | 'create' | 'regex-replace' | 'replace-in-file' | 'delete' | 'rename' | 'git-init' | 'exec' | 'move' | 'copy' | 'append' | 'mkdir';
178
217
  interface RollbackConfig {
179
218
  type: TaskType;
180
219
  config: unknown;
@@ -192,7 +231,7 @@ interface TaskDefinition {
192
231
  required?: boolean;
193
232
  enabled?: EnabledValue;
194
233
  type: TaskType;
195
- config: UpdateJsonConfig | TemplateConfig | CreateConfig | RegexReplaceConfig | ReplaceInFileConfig | DeleteConfig | RenameConfig | GitInitConfig | ExecConfig | Record<string, unknown>;
234
+ config: UpdateJsonConfig | WriteConfig | CreateConfig | RegexReplaceConfig | ReplaceInFileConfig | DeleteConfig | RenameConfig | GitInitConfig | ExecConfig | MoveConfig | CopyConfig | AppendConfig | MkdirConfig | Record<string, unknown>;
196
235
  dependencies?: string[];
197
236
  rollback?: RollbackConfig;
198
237
  prompts?: PromptDefinition[];
@@ -206,6 +245,7 @@ interface TaskDefinition {
206
245
  interface TasksConfiguration {
207
246
  name: string;
208
247
  description?: string;
248
+ enabled?: EnabledValue;
209
249
  dependencies?: string[];
210
250
  extends?: string | string[];
211
251
  variables?: VariableDefinition[];
@@ -242,9 +282,13 @@ interface PluginHooks {
242
282
  */
243
283
  declare function getUpdateJsonDiff(config: UpdateJsonConfig, initConfig: InitConfig): Promise<string>;
244
284
  /**
245
- * Get diff for template task
285
+ * Get diff for write task
246
286
  */
247
- declare function getTemplateDiff(config: TemplateConfig, initConfig: InitConfig): Promise<string>;
287
+ declare function getWriteDiff(config: WriteConfig, initConfig: InitConfig): Promise<string>;
288
+ /**
289
+ * Get diff for create task
290
+ */
291
+ declare function getCreateDiff(config: CreateConfig, initConfig: InitConfig, task?: TaskDefinition): Promise<string>;
248
292
  /**
249
293
  * Get diff for regex-replace task
250
294
  */
@@ -474,8 +518,75 @@ declare function loadTasksWithInheritance(tasksFilePath: string): Promise<{
474
518
  tasks: TaskDefinition[];
475
519
  variables?: VariableDefinition[];
476
520
  prompts?: PromptDefinition[];
521
+ enabled?: EnabledValue;
477
522
  }>;
478
523
  //#endregion
524
+ //#region src/template-utils.d.ts
525
+ /**
526
+ * Configuration for template/templateFile properties
527
+ */
528
+ interface TemplateSource {
529
+ template?: string;
530
+ templateFile?: string;
531
+ }
532
+ /**
533
+ * Result of template validation
534
+ */
535
+ interface TemplateValidationResult {
536
+ isValid: boolean;
537
+ hasInlineTemplate: boolean;
538
+ hasTemplateFile: boolean;
539
+ error?: string;
540
+ }
541
+ /**
542
+ * Options for processing templates
543
+ */
544
+ interface ProcessTemplateOptions {
545
+ /** Enable Handlebars compilation for .hbs files */
546
+ enableHandlebars?: boolean;
547
+ /** Source URL for resolving relative template paths */
548
+ sourceUrl?: string;
549
+ }
550
+ /**
551
+ * Check if a config has an inline template
552
+ * @param config - Configuration object with potential template property
553
+ * @returns True if inline template is present and non-empty
554
+ */
555
+ declare function hasInlineTemplate(config: TemplateSource): boolean;
556
+ /**
557
+ * Check if a config has a template file reference
558
+ * @param config - Configuration object with potential templateFile property
559
+ * @returns True if templateFile is present and non-empty
560
+ */
561
+ declare function hasTemplateFile(config: TemplateSource): boolean;
562
+ /**
563
+ * Check if a template file should be processed with Handlebars
564
+ * @param templateFile - Path to the template file
565
+ * @returns True if the file has .hbs extension
566
+ */
567
+ declare function shouldUseHandlebars(templateFile: string): boolean;
568
+ /**
569
+ * Validate template configuration
570
+ * @param config - Configuration object to validate
571
+ * @returns Validation result with details
572
+ */
573
+ declare function validateTemplateConfig(config: TemplateSource): TemplateValidationResult;
574
+ /**
575
+ * Process a template and return the rendered content
576
+ * @param config - Template configuration
577
+ * @param initConfig - Initialization config with variable values
578
+ * @param task - Optional task definition for $sourceUrl resolution
579
+ * @param options - Processing options
580
+ * @returns Processed template content
581
+ */
582
+ declare function processTemplate(config: TemplateSource, initConfig: InitConfig, task?: TaskDefinition, options?: ProcessTemplateOptions): Promise<string>;
583
+ /**
584
+ * Get a description of the template source for display purposes
585
+ * @param config - Template configuration
586
+ * @returns Human-readable description of the template source
587
+ */
588
+ declare function getTemplateSourceDescription(config: TemplateSource): string;
589
+ //#endregion
479
590
  //#region src/utils.d.ts
480
591
  /**
481
592
  * Get Git repository information from the current directory
@@ -571,6 +682,7 @@ declare function main(customTasks?: TaskDefinition[]): Promise<void>;
571
682
  * @param options.tasksFilePath - Path to the tasks file
572
683
  * @param options.globalVariables - Optional top-level global variables
573
684
  * @param options.globalPrompts - Optional top-level global prompts
685
+ * @param options.templateEnabled - Optional template-level enabled condition
574
686
  */
575
687
  declare function runWithTasks(customTasks: TaskDefinition[], options?: {
576
688
  dryRun?: boolean | undefined;
@@ -578,6 +690,7 @@ declare function runWithTasks(customTasks: TaskDefinition[], options?: {
578
690
  tasksFilePath?: string | undefined;
579
691
  globalVariables?: VariableDefinition[] | undefined;
580
692
  globalPrompts?: PromptDefinition[] | undefined;
693
+ templateEnabled?: EnabledValue | undefined;
581
694
  }): Promise<void>;
582
695
  //#endregion
583
- export { BasePrompt, ConditionExpression, ConditionalDefaultConfig, ConditionalEnabled, ConfirmPrompt, type CreateConfig, DefaultValue, DefaultValueConfig, DefaultValueType, type DeleteConfig, EnabledValue, type ExecConfig, type GitInitConfig, InitConfig, InputPrompt, MergeStrategy, NumberPrompt, PluginHooks, PromptDefinition, PromptType, type RegexReplaceConfig, type RenameConfig, type ReplaceInFileConfig, RollbackConfig, SelectPrompt, TaskDefinition, TaskPlugin, TaskType, TasksConfiguration, type TemplateConfig, type UpdateJsonConfig, VariableDefinition, callHook, clearPlugins, clearTemplateCache, collectPrompts, collectVariables, createPlugin, displayTasksDiff, evaluateCondition, executePluginTask, executeTask, getDeleteDiff, getExecDiff, getGitInitDiff, getGitRepoInfo, getPlugin, getPluginForTaskType, getPluginTaskDiff, getRegexReplaceDiff, getRenameDiff, getReplaceInFileDiff, getTaskDiff, getTemplateDiff, getUpdateJsonDiff, interpolateTemplate, isPluginTaskType, listPlugins, loadAndMergeTemplate, loadTasksWithInheritance, loadTemplate, log, main, mergeTemplates, prompt, promptYesNo, registerBuiltInPlugins, registerHooks, registerPlugin, resolveAllDefaultValues, resolveAllVariableValues, resolveDefaultValue, resolveVariableValue, runTask, runWithTasks, setNestedProperty, topologicalSort, unregisterPlugin, validatePluginTask, validatePrompts, validateVariables };
696
+ export { type AppendConfig, BasePrompt, ConditionExpression, ConditionalDefaultConfig, ConditionalEnabled, ConfirmPrompt, type CopyConfig, type CreateConfig, DefaultValue, DefaultValueConfig, DefaultValueType, type DeleteConfig, EnabledValue, type ExecConfig, ExecutableEnabled, type GitInitConfig, InitConfig, InputPrompt, MergeStrategy, type MkdirConfig, type MoveConfig, NumberPrompt, PluginHooks, PromptDefinition, PromptType, type RegexReplaceConfig, type RenameConfig, type ReplaceInFileConfig, RollbackConfig, SelectPrompt, TaskDefinition, TaskPlugin, TaskType, TasksConfiguration, type UpdateJsonConfig, VariableDefinition, type WriteConfig, callHook, clearPlugins, clearTemplateCache, collectPrompts, collectVariables, createPlugin, displayTasksDiff, evaluateCondition, executePluginTask, executeTask, getCreateDiff, getDeleteDiff, getExecDiff, getGitInitDiff, getGitRepoInfo, getPlugin, getPluginForTaskType, getPluginTaskDiff, getRegexReplaceDiff, getRenameDiff, getReplaceInFileDiff, getTaskDiff, getTemplateSourceDescription, getUpdateJsonDiff, getWriteDiff, hasInlineTemplate, hasTemplateFile, interpolateTemplate, isPluginTaskType, listPlugins, loadAndMergeTemplate, loadTasksWithInheritance, loadTemplate, log, main, mergeTemplates, processTemplate, prompt, promptYesNo, registerBuiltInPlugins, registerHooks, registerPlugin, resolveAllDefaultValues, resolveAllVariableValues, resolveDefaultValue, resolveVariableValue, runTask, runWithTasks, setNestedProperty, shouldUseHandlebars, topologicalSort, unregisterPlugin, validatePluginTask, validatePrompts, validateTemplateConfig, validateVariables };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,22 @@
1
- //#region src/plugins/create/types.d.ts
1
+ //#region src/plugins/append/types.d.ts
2
2
 
3
+ interface AppendConfig {
4
+ file: string;
5
+ content?: string;
6
+ template?: string;
7
+ templateFile?: string;
8
+ newline?: boolean;
9
+ condition?: ConditionExpression;
10
+ }
11
+ //#endregion
12
+ //#region src/plugins/copy/types.d.ts
13
+ interface CopyConfig {
14
+ from: string;
15
+ to: string;
16
+ condition?: ConditionExpression;
17
+ }
18
+ //#endregion
19
+ //#region src/plugins/create/types.d.ts
3
20
  interface CreateConfig {
4
21
  file: string;
5
22
  template?: string;
@@ -28,6 +45,19 @@ interface GitInitConfig {
28
45
  condition?: ConditionExpression;
29
46
  }
30
47
  //#endregion
48
+ //#region src/plugins/mkdir/types.d.ts
49
+ interface MkdirConfig {
50
+ path: string;
51
+ condition?: ConditionExpression;
52
+ }
53
+ //#endregion
54
+ //#region src/plugins/move/types.d.ts
55
+ interface MoveConfig {
56
+ from: string;
57
+ to: string;
58
+ condition?: ConditionExpression;
59
+ }
60
+ //#endregion
31
61
  //#region src/plugins/regex-replace/types.d.ts
32
62
  interface RegexReplaceConfig {
33
63
  file: string;
@@ -54,18 +84,18 @@ interface ReplaceInFileConfig {
54
84
  condition?: ConditionExpression;
55
85
  }
56
86
  //#endregion
57
- //#region src/plugins/template/types.d.ts
58
- interface TemplateConfig {
87
+ //#region src/plugins/update-json/types.d.ts
88
+ interface UpdateJsonConfig {
59
89
  file: string;
60
- template?: string;
61
- templateFile?: string;
90
+ updates: Record<string, unknown>;
62
91
  condition?: ConditionExpression;
63
92
  }
64
93
  //#endregion
65
- //#region src/plugins/update-json/types.d.ts
66
- interface UpdateJsonConfig {
94
+ //#region src/plugins/write/types.d.ts
95
+ interface WriteConfig {
67
96
  file: string;
68
- updates: Record<string, unknown>;
97
+ template?: string;
98
+ templateFile?: string;
69
99
  condition?: ConditionExpression;
70
100
  }
71
101
  //#endregion
@@ -117,12 +147,21 @@ interface ConditionalEnabled {
117
147
  condition: ConditionExpression;
118
148
  }
119
149
  /**
120
- * Type for enabled field that can be boolean, string condition, or conditional object
150
+ * Executable enabled configuration
151
+ * Determines enabled state by executing a shell command
152
+ */
153
+ interface ExecutableEnabled {
154
+ type: 'exec';
155
+ value: string;
156
+ }
157
+ /**
158
+ * Type for enabled field that can be boolean, string condition, conditional object, or executable
121
159
  * - boolean: Simple true/false
122
160
  * - string: JavaScript expression to evaluate (shorthand for { condition: "..." })
123
161
  * - ConditionalEnabled: Object with condition property
162
+ * - ExecutableEnabled: Object with type='exec' and value=command
124
163
  */
125
- type EnabledValue = boolean | string | ConditionalEnabled;
164
+ type EnabledValue = boolean | string | ConditionalEnabled | ExecutableEnabled;
126
165
  interface BasePrompt {
127
166
  id: string;
128
167
  type: PromptType;
@@ -174,7 +213,7 @@ interface VariableDefinition {
174
213
  * @example "packageManager === 'pnpm'"
175
214
  */
176
215
  type ConditionExpression = string;
177
- type TaskType = 'update-json' | 'template' | 'create' | 'regex-replace' | 'replace-in-file' | 'delete' | 'rename' | 'git-init' | 'exec';
216
+ type TaskType = 'update-json' | 'write' | 'create' | 'regex-replace' | 'replace-in-file' | 'delete' | 'rename' | 'git-init' | 'exec' | 'move' | 'copy' | 'append' | 'mkdir';
178
217
  interface RollbackConfig {
179
218
  type: TaskType;
180
219
  config: unknown;
@@ -192,7 +231,7 @@ interface TaskDefinition {
192
231
  required?: boolean;
193
232
  enabled?: EnabledValue;
194
233
  type: TaskType;
195
- config: UpdateJsonConfig | TemplateConfig | CreateConfig | RegexReplaceConfig | ReplaceInFileConfig | DeleteConfig | RenameConfig | GitInitConfig | ExecConfig | Record<string, unknown>;
234
+ config: UpdateJsonConfig | WriteConfig | CreateConfig | RegexReplaceConfig | ReplaceInFileConfig | DeleteConfig | RenameConfig | GitInitConfig | ExecConfig | MoveConfig | CopyConfig | AppendConfig | MkdirConfig | Record<string, unknown>;
196
235
  dependencies?: string[];
197
236
  rollback?: RollbackConfig;
198
237
  prompts?: PromptDefinition[];
@@ -206,6 +245,7 @@ interface TaskDefinition {
206
245
  interface TasksConfiguration {
207
246
  name: string;
208
247
  description?: string;
248
+ enabled?: EnabledValue;
209
249
  dependencies?: string[];
210
250
  extends?: string | string[];
211
251
  variables?: VariableDefinition[];
@@ -242,9 +282,13 @@ interface PluginHooks {
242
282
  */
243
283
  declare function getUpdateJsonDiff(config: UpdateJsonConfig, initConfig: InitConfig): Promise<string>;
244
284
  /**
245
- * Get diff for template task
285
+ * Get diff for write task
246
286
  */
247
- declare function getTemplateDiff(config: TemplateConfig, initConfig: InitConfig): Promise<string>;
287
+ declare function getWriteDiff(config: WriteConfig, initConfig: InitConfig): Promise<string>;
288
+ /**
289
+ * Get diff for create task
290
+ */
291
+ declare function getCreateDiff(config: CreateConfig, initConfig: InitConfig, task?: TaskDefinition): Promise<string>;
248
292
  /**
249
293
  * Get diff for regex-replace task
250
294
  */
@@ -474,8 +518,75 @@ declare function loadTasksWithInheritance(tasksFilePath: string): Promise<{
474
518
  tasks: TaskDefinition[];
475
519
  variables?: VariableDefinition[];
476
520
  prompts?: PromptDefinition[];
521
+ enabled?: EnabledValue;
477
522
  }>;
478
523
  //#endregion
524
+ //#region src/template-utils.d.ts
525
+ /**
526
+ * Configuration for template/templateFile properties
527
+ */
528
+ interface TemplateSource {
529
+ template?: string;
530
+ templateFile?: string;
531
+ }
532
+ /**
533
+ * Result of template validation
534
+ */
535
+ interface TemplateValidationResult {
536
+ isValid: boolean;
537
+ hasInlineTemplate: boolean;
538
+ hasTemplateFile: boolean;
539
+ error?: string;
540
+ }
541
+ /**
542
+ * Options for processing templates
543
+ */
544
+ interface ProcessTemplateOptions {
545
+ /** Enable Handlebars compilation for .hbs files */
546
+ enableHandlebars?: boolean;
547
+ /** Source URL for resolving relative template paths */
548
+ sourceUrl?: string;
549
+ }
550
+ /**
551
+ * Check if a config has an inline template
552
+ * @param config - Configuration object with potential template property
553
+ * @returns True if inline template is present and non-empty
554
+ */
555
+ declare function hasInlineTemplate(config: TemplateSource): boolean;
556
+ /**
557
+ * Check if a config has a template file reference
558
+ * @param config - Configuration object with potential templateFile property
559
+ * @returns True if templateFile is present and non-empty
560
+ */
561
+ declare function hasTemplateFile(config: TemplateSource): boolean;
562
+ /**
563
+ * Check if a template file should be processed with Handlebars
564
+ * @param templateFile - Path to the template file
565
+ * @returns True if the file has .hbs extension
566
+ */
567
+ declare function shouldUseHandlebars(templateFile: string): boolean;
568
+ /**
569
+ * Validate template configuration
570
+ * @param config - Configuration object to validate
571
+ * @returns Validation result with details
572
+ */
573
+ declare function validateTemplateConfig(config: TemplateSource): TemplateValidationResult;
574
+ /**
575
+ * Process a template and return the rendered content
576
+ * @param config - Template configuration
577
+ * @param initConfig - Initialization config with variable values
578
+ * @param task - Optional task definition for $sourceUrl resolution
579
+ * @param options - Processing options
580
+ * @returns Processed template content
581
+ */
582
+ declare function processTemplate(config: TemplateSource, initConfig: InitConfig, task?: TaskDefinition, options?: ProcessTemplateOptions): Promise<string>;
583
+ /**
584
+ * Get a description of the template source for display purposes
585
+ * @param config - Template configuration
586
+ * @returns Human-readable description of the template source
587
+ */
588
+ declare function getTemplateSourceDescription(config: TemplateSource): string;
589
+ //#endregion
479
590
  //#region src/utils.d.ts
480
591
  /**
481
592
  * Get Git repository information from the current directory
@@ -571,6 +682,7 @@ declare function main(customTasks?: TaskDefinition[]): Promise<void>;
571
682
  * @param options.tasksFilePath - Path to the tasks file
572
683
  * @param options.globalVariables - Optional top-level global variables
573
684
  * @param options.globalPrompts - Optional top-level global prompts
685
+ * @param options.templateEnabled - Optional template-level enabled condition
574
686
  */
575
687
  declare function runWithTasks(customTasks: TaskDefinition[], options?: {
576
688
  dryRun?: boolean | undefined;
@@ -578,6 +690,7 @@ declare function runWithTasks(customTasks: TaskDefinition[], options?: {
578
690
  tasksFilePath?: string | undefined;
579
691
  globalVariables?: VariableDefinition[] | undefined;
580
692
  globalPrompts?: PromptDefinition[] | undefined;
693
+ templateEnabled?: EnabledValue | undefined;
581
694
  }): Promise<void>;
582
695
  //#endregion
583
- export { BasePrompt, ConditionExpression, ConditionalDefaultConfig, ConditionalEnabled, ConfirmPrompt, type CreateConfig, DefaultValue, DefaultValueConfig, DefaultValueType, type DeleteConfig, EnabledValue, type ExecConfig, type GitInitConfig, InitConfig, InputPrompt, MergeStrategy, NumberPrompt, PluginHooks, PromptDefinition, PromptType, type RegexReplaceConfig, type RenameConfig, type ReplaceInFileConfig, RollbackConfig, SelectPrompt, TaskDefinition, TaskPlugin, TaskType, TasksConfiguration, type TemplateConfig, type UpdateJsonConfig, VariableDefinition, callHook, clearPlugins, clearTemplateCache, collectPrompts, collectVariables, createPlugin, displayTasksDiff, evaluateCondition, executePluginTask, executeTask, getDeleteDiff, getExecDiff, getGitInitDiff, getGitRepoInfo, getPlugin, getPluginForTaskType, getPluginTaskDiff, getRegexReplaceDiff, getRenameDiff, getReplaceInFileDiff, getTaskDiff, getTemplateDiff, getUpdateJsonDiff, interpolateTemplate, isPluginTaskType, listPlugins, loadAndMergeTemplate, loadTasksWithInheritance, loadTemplate, log, main, mergeTemplates, prompt, promptYesNo, registerBuiltInPlugins, registerHooks, registerPlugin, resolveAllDefaultValues, resolveAllVariableValues, resolveDefaultValue, resolveVariableValue, runTask, runWithTasks, setNestedProperty, topologicalSort, unregisterPlugin, validatePluginTask, validatePrompts, validateVariables };
696
+ export { type AppendConfig, BasePrompt, ConditionExpression, ConditionalDefaultConfig, ConditionalEnabled, ConfirmPrompt, type CopyConfig, type CreateConfig, DefaultValue, DefaultValueConfig, DefaultValueType, type DeleteConfig, EnabledValue, type ExecConfig, ExecutableEnabled, type GitInitConfig, InitConfig, InputPrompt, MergeStrategy, type MkdirConfig, type MoveConfig, NumberPrompt, PluginHooks, PromptDefinition, PromptType, type RegexReplaceConfig, type RenameConfig, type ReplaceInFileConfig, RollbackConfig, SelectPrompt, TaskDefinition, TaskPlugin, TaskType, TasksConfiguration, type UpdateJsonConfig, VariableDefinition, type WriteConfig, callHook, clearPlugins, clearTemplateCache, collectPrompts, collectVariables, createPlugin, displayTasksDiff, evaluateCondition, executePluginTask, executeTask, getCreateDiff, getDeleteDiff, getExecDiff, getGitInitDiff, getGitRepoInfo, getPlugin, getPluginForTaskType, getPluginTaskDiff, getRegexReplaceDiff, getRenameDiff, getReplaceInFileDiff, getTaskDiff, getTemplateSourceDescription, getUpdateJsonDiff, getWriteDiff, hasInlineTemplate, hasTemplateFile, interpolateTemplate, isPluginTaskType, listPlugins, loadAndMergeTemplate, loadTasksWithInheritance, loadTemplate, log, main, mergeTemplates, processTemplate, prompt, promptYesNo, registerBuiltInPlugins, registerHooks, registerPlugin, resolveAllDefaultValues, resolveAllVariableValues, resolveDefaultValue, resolveVariableValue, runTask, runWithTasks, setNestedProperty, shouldUseHandlebars, topologicalSort, unregisterPlugin, validatePluginTask, validatePrompts, validateTemplateConfig, validateVariables };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{A as e,B as t,C as n,D as r,E as i,F as a,H as o,I as s,L as c,M as l,N as u,O as d,P as f,R as p,S as m,T as h,V as g,_,a as v,b as y,c as b,d as x,f as S,g as C,h as w,i as T,j as E,k as D,l as O,m as k,n as A,o as j,p as M,r as N,s as P,t as F,u as I,v as L,w as R,x as z,y as B,z as V}from"./src-DYtpmv9N.js";import{a as H,c as U,i as W,l as G,o as K,r as q,s as J}from"./utils-ii_k_uXl.js";export{y as callHook,z as clearPlugins,x as clearTemplateCache,L as collectPrompts,j as collectVariables,m as createPlugin,u as displayTasksDiff,q as evaluateCondition,n as executePluginTask,b as executeTask,f as getDeleteDiff,a as getExecDiff,s as getGitInitDiff,W as getGitRepoInfo,R as getPlugin,h as getPluginForTaskType,i as getPluginTaskDiff,c as getRegexReplaceDiff,p as getRenameDiff,V as getReplaceInFileDiff,t as getTaskDiff,g as getTemplateDiff,o as getUpdateJsonDiff,H as interpolateTemplate,r as isPluginTaskType,d as listPlugins,S as loadAndMergeTemplate,M as loadTasksWithInheritance,k as loadTemplate,K as log,F as main,w as mergeTemplates,J as prompt,U as promptYesNo,O as registerBuiltInPlugins,D as registerHooks,e as registerPlugin,_ as resolveAllDefaultValues,T as resolveAllVariableValues,B as resolveDefaultValue,v as resolveVariableValue,I as runTask,A as runWithTasks,G as setNestedProperty,P as topologicalSort,E as unregisterPlugin,l as validatePluginTask,C as validatePrompts,N as validateVariables};
1
+ import{A as e,B as t,C as n,D as r,E as i,F as a,G as o,H as s,I as c,J as l,K as u,L as d,M as f,N as p,O as m,P as h,R as g,S as _,T as v,U as y,V as b,W as x,Y as S,_ as C,a as w,b as T,c as E,d as D,f as O,g as k,h as A,i as j,j as M,k as N,l as P,m as F,n as I,o as L,p as R,q as z,r as B,s as V,t as H,u as U,v as W,w as G,x as K,y as q,z as J}from"./src-DIM5YRco.js";import{a as Y,i as X,n as Z,o as Q,r as $,s as ee,t as te}from"./utils-DfD7I1u2.js";export{A as callHook,k as clearPlugins,o as clearTemplateCache,R as collectPrompts,L as collectVariables,C as createPlugin,m as displayTasksDiff,te as evaluateCondition,W as executePluginTask,E as executeTask,N as getCreateDiff,e as getDeleteDiff,M as getExecDiff,f as getGitInitDiff,Z as getGitRepoInfo,q as getPlugin,T as getPluginForTaskType,K as getPluginTaskDiff,p as getRegexReplaceDiff,h as getRenameDiff,a as getReplaceInFileDiff,c as getTaskDiff,J as getTemplateSourceDescription,d as getUpdateJsonDiff,g as getWriteDiff,t as hasInlineTemplate,b as hasTemplateFile,$ as interpolateTemplate,_ as isPluginTaskType,n as listPlugins,u as loadAndMergeTemplate,z as loadTasksWithInheritance,l as loadTemplate,X as log,H as main,S as mergeTemplates,s as processTemplate,Y as prompt,Q as promptYesNo,P as registerBuiltInPlugins,G as registerHooks,v as registerPlugin,O as resolveAllDefaultValues,j as resolveAllVariableValues,F as resolveDefaultValue,w as resolveVariableValue,U as runTask,I as runWithTasks,ee as setNestedProperty,y as shouldUseHandlebars,V as topologicalSort,i as unregisterPlugin,r as validatePluginTask,D as validatePrompts,x as validateTemplateConfig,B as validateVariables};