UNPKG

clingon

Version:

Multipurpose generator CLI based on local config and templates

3 lines (2 loc) 36.1 kB
#!/usr/bin/env node import{Command as e}from"commander";import t,{join as s}from"node:path";import n from"node:fs";import{fileURLToPath as a}from"node:url";import{input as o,confirm as r,select as i}from"@inquirer/prompts";import{parse as c}from"yaml";function l(e){return n.readFileSync(e,"utf8")}function u(e,t){try{return n.writeFileSync(e,t,"utf8"),!0}catch(e){return!1}}function p(e){try{return n.accessSync(e,n.constants.F_OK),!0}catch{return!1}}function m(...e){let t;return e.forEach(((e,s)=>t=0===s?e():e(t))),t}function f(){const e=a(import.meta.url),s=t.dirname(e);return s?.replace("/utils","")}function d(e){let s=process.cwd();for(const a of e)if(s=t.join(s,a),!n.existsSync(s)||!n.statSync(s).isDirectory())return!1;return!0}function v(e){try{return n.mkdirSync(e,{recursive:!0}),!0}catch(e){return console.error(e),!1}}const h=process.cwd(),y=".clingon",w="presets";function g(){if(!d([y,w])){if(function(){let e,t;return d([y])||(e=v(s(h,y))),d([y,w])||(t=v(s(h,y,w))),!(!e||!t)}())return g()}const e=function(e){const s=e??process.cwd();try{return n.readdirSync(s).map((e=>t.join(s,e)))}catch(e){throw new Error(`Error reading files: ${e}`)}}(s(h,y,w)).map((e=>{const t=e.split("/");return t[t.length-1]}));return e}function _(e){const t=l(s(h,y,w,e));return"string"==typeof t?JSON.parse(t):t}function j(e){return e.map((e=>({name:e.split(".")[0],fileName:e})))}function k(e,t){const n=s(y,w,e+".json");return{success:u(n,JSON.stringify(t,null,2)),path:n}}function C(e){return e.map((e=>({name:e.name,value:e.fileName})))}const x=[{folder:"templates/core/functions",target:"functions",files:["AsyncFunction.ts","AsyncFunction.spec.ts"]},{folder:"templates/core/markdown",target:"docs",files:["HookDoc.md"]},{folder:"templates/core/react-component",target:"components/react-component",files:["index.tsx","Component.tsx","Component.test.tsx","Component.styles.css","Component.stories.tsx"]},{folder:"templates/core",target:"",files:["meta.yaml","SCAFFOLD_GUIDE.md"]}],P=[{folder:"templates/core",target:"",files:["PRESETS_GUIDE.md","function-preset.json"]}],b=[{folder:"templates/core",target:"",files:["clingon.config.json"]}];function S(e){return e?.includes("/")?e.split("/"):[e]}function T(e){return e?"Yes":"No"}function $(e,t){switch(e){case"PascalCase":return function(e){return e.replace(/[-_](.)/g,((e,t)=>t.toUpperCase())).replace(/^\w/,(e=>e.toUpperCase()))}(t);case"camelCase":return function(e){let t=e.split(/[-_]/);if(1===t.length)return e.charAt(0).toLowerCase()+e.slice(1);for(let e=1;e<t.length;e++)t[e]=t[e].charAt(0).toUpperCase()+t[e].slice(1);return t.join("")}(t);case"snake_case":return function(e){return e.replace(/([a-z])([A-Z])/g,"$1_$2").replace(/[-\s]/g,"_").toLowerCase()}(t);case"kebab-case":return function(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/[_\s]/g,"-").toLowerCase()}(t);case"UPPERCASE":return function(e){return e.toUpperCase()}(t);case"lowercase":return function(e){return e.toLowerCase()}(t);default:throw new Error("Invalid target pattern.")}}function F(e,t="first_letter",s){if("all"===t){return e.split(new RegExp(s)).map((e=>F(e))).join(s)}return e.charAt(0).toUpperCase()+e.slice(1)}function W({examples:e,fullPath:t}){if(t)return console.info("\n✅ You already have config at: ",t),t;return J(b,process.cwd())?console.info("🌎 Global config file created at: ",s(process.cwd(),"clingon.config.json")):console.error("❌ Error: Cannot create global config file, try again."),{fullPath:t,examples:e}}const O="presets",N=".clingon",E=s(process.cwd(),N,O);function L({exists:e,examples:t}){if(e&&!t)return console.info("\n✅ You already have presets folder at: ",E),{exists:e,examples:t};if(e=v(E)){const e=t?"Presets examples created at: ":"Presets created at: ";console.info(`\n🎛️ ${e}`,E)}else console.error("\n❌ Error: cannot create presets dir, try again.");return{exists:e,examples:t}}function I({examples:e,exists:t}){if(e)try{if(!t)throw new Error("Cannot create folder to place files");J(P,E)}catch(e){console.error(e)}}const R="templates",M=s(process.cwd(),N,R);function V({examples:e,exists:t}){if(t&&!e)return console.info("\n✅ You already have templates folder at: ",M),{examples:e,exists:t};if(t=v(M)){const t=e?"Templates examples created at:":"Templates created at:";console.info(`\n📂 ${t} `,M)}else console.error("\n❌ Error: cannot create templates dir, try again");return{examples:e,exists:t}}function D({examples:e,exists:t}){if(e)try{if(!t)throw new Error("Cannot create folder to place files");J(x,M)}catch(e){console.error(e)}}function J(e,t){try{const n=f();return e.forEach((e=>{let a=s(t,e.target);d(S(a))||v(a),e.files.forEach((t=>u(s(a,t),l(s(n,e.folder,t)))))})),!0}catch(e){console.error(e)}}const A="vue",U="react",Y="vitest",q="css_modules",G="no_style",z={react:{js:{component:{functional:{no_style:"templates/react/js/component/Functional.jsx",css_modules:"templates/react/js/component/CssModulesFunctional.jsx",scss:"templates/react/js/component/FunctionalWithScss.jsx",css_vanilla:"templates/react/js/component/FunctionalWithStyle.jsx",tailwind_inline:"templates/react/js/component/TailwindInlineFunctional.jsx",tailwind_file:"templates/react/js/component/TailwindFunctional.jsx"}}},ts:{component:{functional:{no_style:"templates/react/ts/component/Functional.tsx",css_modules:"templates/react/ts/component/CssModulesFunctional.tsx",scss:"templates/react/ts/component/FunctionalWithScss.tsx",css_vanilla:"templates/react/ts/component/FunctionalWithStyle.tsx",tailwind_inline:"templates/react/ts/component/TailwindInlineFunctional.tsx",tailwind_file:"templates/react/ts/component/TailwindFunctional.tsx"}}}},vue:{2:{js:{component:{options:{css_modules:"templates/vue/2/js/component/CssModulesOptions.vue",scss:"templates/vue/2/js/component/ScssOptions.vue",no_style:"templates/vue/2/js/component/Options.vue",css_vanilla:"templates/vue/2/js/component/OptionsWithStyle.vue",tailwind_inline:"templates/vue/2/js/component/TailwindInlineOptions.vue",tailwind_file:"templates/vue/2/js/component/TailwindOptions.vue"}},page:{options:{css_modules:"templates/vue/2/js/page/CssModulesOptions.vue",scss:"templates/vue/2/js/page/ScssOptions.vue",no_style:"templates/vue/2/js/page/Options.vue",css_vanilla:"templates/vue/2/js/page/OptionsWithStyle.vue",tailwind_inline:"templates/vue/2/js/page/TailwindInlineOptions.vue",tailwind_file:"templates/vue/2/js/page/TailwindOptions.vue"}}},ts:{component:{options:{css_modules:"templates/vue/2/ts/component/CssModulesOptions.vue",scss:"templates/vue/2/ts/component/ScssOptions.vue",no_style:"templates/vue/2/ts/component/Options.vue",css_vanilla:"templates/vue/2/ts/component/OptionsWithStyle.vue",tailwind_inline:"templates/vue/2/ts/component/TailwindInlineOptions.vue",tailwind_file:"templates/vue/2/ts/component/TailwindOptions.vue"}},page:{options:{css_modules:"templates/vue/2/ts/page/CssModulesOptions.vue",scss:"templates/vue/2/ts/page/ScssOptions.vue",no_style:"templates/vue/2/ts/page/Options.vue",css_vanilla:"templates/vue/2/ts/page/OptionsWithStyle.vue",tailwind_inline:"templates/vue/2/ts/page/TailwindInlineOptions.vue",tailwind_file:"templates/vue/2/ts/page/TailwindOptions.vue"}}}},3:{js:{component:{options:{css_modules:"templates/vue/3/js/component/CssModulesOptions.vue",scss:"templates/vue/3/js/component/ScssOptions.vue",no_style:"templates/vue/3/js/component/Options.vue",css_vanilla:"templates/vue/3/js/component/OptionsWithStyle.vue",tailwind_inline:"templates/vue/3/js/component/TailwindInlineOptions.vue",tailwind_file:"templates/vue/3/js/component/TailwindOptions.vue"},setup:{css_modules:"templates/vue/3/js/component/CssModulesSetup.vue",scss:"templates/vue/3/js/component/ScssSetup.vue",no_style:"templates/vue/3/js/component/Setup.vue",css_vanilla:"templates/vue/3/js/component/SetupWithStyle.vue",tailwind_inline:"templates/vue/3/js/component/TailwindInlineSetup.vue",tailwind_file:"templates/vue/3/js/component/TailwindSetup.vue"}},page:{options:{css_modules:"templates/vue/3/js/page/CssModulesOptions.vue",scss:"templates/vue/3/js/page/ScssOptions.vue",no_style:"templates/vue/3/js/page/Options.vue",css_vanilla:"templates/vue/3/js/page/OptionsWithStyle.vue",tailwind_inline:"templates/vue/3/js/page/TailwindInlineOptions.vue",tailwind_file:"templates/vue/3/js/page/TailwindOptions.vue"},setup:{css_modules:"templates/vue/3/js/page/CssModulesSetup.vue",scss:"templates/vue/3/js/page/ScssSetup.vue",no_style:"templates/vue/3/js/page/Setup.vue",css_vanilla:"templates/vue/3/js/page/SetupWithStyle.vue",tailwind_inline:"templates/vue/3/js/page/TailwindInlineSetup.vue",tailwind_file:"templates/vue/3/js/page/TailwindSetup.vue"}}},ts:{component:{options:{css_modules:"templates/vue/3/ts/component/CssModulesOptions.vue",scss:"templates/vue/3/ts/component/ScssOptions.vue",no_style:"templates/vue/3/ts/component/Options.vue",css_vanilla:"templates/vue/3/ts/component/OptionsWithStyle.vue",tailwind_file:"templates/vue/3/ts/component/TailwindOptions.vue",tailwind_inline:"templates/vue/3/ts/component/TailwindInlineOptions.vue"},setup:{css_modules:"templates/vue/3/ts/component/CssModulesSetup.vue",scss:"templates/vue/3/ts/component/ScssSetup.vue",no_style:"templates/vue/3/ts/component/Setup.vue",css_vanilla:"templates/vue/3/ts/component/SetupWithStyle.vue",tailwind_file:"templates/vue/3/ts/component/TailwindSetup.vue",tailwind_inline:"templates/vue/3/ts/component/TailwindInlineSetup.vue"}},page:{options:{css_modules:"templates/vue/3/ts/page/CssModulesOptions.vue",scss:"templates/vue/3/ts/page/ScssOptions.vue",no_style:"templates/vue/3/ts/page/Options.vue",css_vanilla:"templates/vue/3/ts/page/OptionsWithStyle.vue",tailwind_file:"templates/vue/3/ts/page/TailwindOptions.vue",tailwind_inline:"templates/vue/3/ts/page/TailwindInlineOptions.vue"},setup:{css_modules:"templates/vue/3/ts/page/CssModulesSetup.vue",scss:"templates/vue/3/ts/page/ScssSetup.vue",no_style:"templates/vue/3/ts/page/Setup.vue",css_vanilla:"templates/vue/3/ts/page/SetupWithStyle.vue",tailwind_file:"templates/vue/3/ts/page/TailwindSetup.vue",tailwind_inline:"templates/vue/3/ts/page/TailwindInlineSetup.vue"}}}}}},Z={react:{js:{jest:"templates/unit-test/react/js/Jest.js",jestTestingLibrary:"templates/unit-test/react/js/JestTestingLibrary.js",vitest:"templates/unit-test/react/js/Vitest.js",vitestTestingLibrary:"templates/unit-test/react/js/VitestTestingLibrary.js"},ts:{jest:"templates/unit-test/react/ts/Jest.ts",jestTestingLibrary:"templates/unit-test/react/ts/JestTestingLibrary.ts",vitest:"templates/unit-test/react/ts/Vitest.ts",vitestTestingLibrary:"templates/unit-test/react/ts/VitestTestingLibrary.ts"}},vue:{js:{jest:"templates/unit-test/vue/ts/Jest.ts",jestTestingLibrary:"templates/unit-test/vue/ts/JestTestingLibrary.ts",vitest:"templates/unit-test/vue/ts/Vitest.ts",vitestTestingLibrary:"templates/unit-test/vue/ts/VitestTestingLibrary.ts"},ts:{jest:"templates/unit-test/vue/ts/Jest.ts",jestTestingLibrary:"templates/unit-test/vue/ts/JestTestingLibrary.ts",vitest:"templates/unit-test/vue/ts/Vitest.ts",vitestTestingLibrary:"templates/unit-test/vue/ts/VitestTestingLibrary.ts"}},function:{js:{jest:"templates/unit-test/function/js/Jest.js",vitest:"templates/unit-test/function/js/Vitest.js"},ts:{jest:"templates/unit-test/function/ts/Jest.ts",vitest:"templates/unit-test/function/ts/Vitest.ts"}}},H={storybook:{vue:{3:{js:{component:"templates/storybook/vue/3/js/Component.js"},ts:{component:"templates/storybook/vue/3/ts/Component.ts"}}},react:{js:{component:"templates/storybook/react/js/Component.jsx"},ts:{component:"templates/storybook/react/ts/Component.tsx"}}}},K={js:"templates/function/js/function.js",ts:"templates/function/ts/function.ts"},B={scss:"templates/styles/Default.scss",css_modules:"templates/styles/Default.css",css_vanilla:"templates/styles/Default.css",tailwind_file:"templates/styles/Tailwind.css"},Q={resource:{react:{js:"jsx",ts:"tsx"},vue:{js:"vue",ts:"vue"},vanilla:{js:"js",ts:"ts"}},style:{css_modules:"css",tailwind_file:"css",css_vanilla:"css",scss:"scss"}};function X({framework:e,cssFramework:t,language:s,postfix:n,target:a}){let o="";return o="style"===a?Q.style[t]:Q.resource[e][s],n?`${n}.${o}`:o}function ee(e){return e.replace(/\.(stories|spec|test)?\.(jsx?|tsx?|ts|vue)|\.(jsx?|tsx?|vue)$/,"")}function te(e){const{success:t,path:s}=m((n=e,()=>{let e="";const t=n.typescript?"ts":"js",s=n.version,a={2:"options",3:"setup"}[s];switch(n.framework){case U:e=z.react[t].component.functional[n.cssFramework];break;case A:e=z.vue[s][t].component[a][n.cssFramework];break;default:console.error("Framework is required to get a template")}return{...n,templatePath:e}}),se,ne,ae,oe,re);var n;t?console.info("\nComponent created successfully: "+s):console.error("Error on create component, try again")}function se(e){const s=l(t.join(rt,e.templatePath));return{...e,fileContent:s}}function ne(e){e.name=$("PascalCase",e.name);const t=s(e.resourcePath,e.name),n=d(S(t));if(e.folderWrapper&&!n){v(t)||console.error("Error: cannot create folder wrapper.")}return{...e,folderWrapperPath:t}}function ae(e){const t=X({language:e.typescript?"ts":"js",target:"resource",framework:e.framework}),s=e.folderWrapper?`${e.name}/${e.name}.${t}`:`${e.name}.${t}`,n=`${e.path}/${s}`;return{...e,extension:t,fileName:s,pathWithFileName:n}}function oe(e){switch(e.framework){case U:return e.folderWrapper||it?.exportDefault&&(e.fileContent=e.fileContent.replace(/export function/g,"export default function")),e.fileContent=e.fileContent.replace(/ResourceName/g,e.name),e;case A:return e.cssFramework===q?e.fileContent=e.fileContent.replace(/component/g,$("camelCase",e.name)):e.fileContent=e.fileContent.replace(/component/g,$("kebab-case",e.name)),e;default:return e}}function re(e){const t=e.pathWithFileName,n=u(e.pathWithFileName,e.fileContent);if(e.folderWrapper){const t=s(e.resourcePath,e.name,"index."+e.extension);u(t,it?.exportDefault?`import { ${e.name} } from './${e.name}'\n\nexport * from './${e.name}'\nexport default ${e.name}\n`:`export * from './${e.name}'`)}return{success:n,path:t}}function ie(e){const{success:t,path:s}=m((n=e,()=>{let e="";const t=n.typescript?"ts":"js";if(["function"].includes(n.type)&&(e=Z.function[t][n.testFramework]),["component","page"].includes(n.type))switch(n.framework){case U:"jest"===n.testFramework&&(e=n.withTestingLibrary?Z.react[t].jestTestingLibrary:Z.react[t].jest),"vitest"===n.testFramework&&(e=n.withTestingLibrary?Z.react[t].vitestTestingLibrary:Z.react[t].vitest);break;case A:"jest"===n.testFramework&&(e=n.withTestingLibrary?Z.vue[t].jestTestingLibrary:Z.vue[t].jest),"vitest"===n.testFramework&&(e=n.withTestingLibrary?Z.vue[t].vitestTestingLibrary:Z.vue[t].vitest);break;default:console.error("Error: Framework is required to get a template")}return{...n,templatePath:e}}),ce,le,ue,pe);var n;t?console.info(F(e.testPostfix)+" created successfully: "+s):console.error(`Error on create ${e.testPostfix}, try again`)}function ce(e){const s=l(t.join(rt,e.templatePath));return{...e,fileContent:s}}function le(e){["function"].includes(e.type)&&(e.name=$("kebab-case",e.name)),["component","page"].includes(e.type)&&(e.name=$("PascalCase",e.name));const t=X({language:e.typescript?"ts":"js",framework:"react"===e.framework?e.framework:"vanilla",target:"resource",postfix:e.testPostfix}),s=e.folderWrapper&&["component","page"].includes(e.type)?`${e.name}/${e.name}.${t}`:`${e.name}.${t}`,n=`${e.path}/${s}`,a=`${e.resourcePath}/${e.name}.${t}`;return{...e,extension:t,fileName:s,pathWithFileName:n,resourcePathWithFileName:a}}function ue(e){if(it?.exportDefault){const t=new RegExp("import { ResourceName } from");e.fileContent=e.fileContent.replace(t,"import ResourceName from")}return["function"].includes(e.type)&&(e.name=$("camelCase",e.name)),["component","page"].includes(e.type)&&(e.name=$("PascalCase",e.name)),e.fileContent=e.fileContent.replace(/ResourceName/g,e.name),e.fileContent=e.fileContent.replace(/FunctionName/g,e.name),["function"].includes(e.type)&&(e.fileContent=e.fileContent.replace(/functionPath/g,ee(e.resourcePathWithFileName))),["component","page"].includes(e.type)&&(e.framework===A&&(e.fileContent=e.fileContent.replace(/resourcePath/g,ee(e.resourcePathWithFileName))),e.framework===U&&(e.fileContent=e.fileContent.replace(/resourcePath/g,ee(e.resourcePathWithFileName)))),it?.alias?.src&&(e.fileContent=e.fileContent.replace(/src/g,it.alias.src)),e}function pe(e){const t=e.pathWithFileName;return{success:u(e.pathWithFileName,e.fileContent),path:t}}function me(e){const{success:t,error:s,path:n}=m((a=e,()=>{let e="";const t=a.typescript?"ts":"js";return e=K[t],{...a,templatePath:e}}),fe,de,ve);var a;t?console.info("Function created successfully: "+n):console.error("Error on create component, try again")}function fe(e){const s=l(t.join(rt,e.templatePath));return{...e,fileContent:s}}function de(e){return e.folderWrapper||it?.exportDefault&&(e.fileContent=e.fileContent.replace(/export function/g,"export default function")),e.name=$("camelCase",e.name),e.fileContent=e.fileContent.replace("FunctionName",e.name),e}function ve(e){const t=X({language:e.typescript?"ts":"js",target:"resource",framework:"vanilla"}),s=e.folderWrapper&&["component","page"].includes(e.type)?`${$("kebab-case",e.name)}/${$("kebab-case",e.name)}.${t}`:`${$("kebab-case",e.name)}.${t}`,n=`${e.path}/${s}`,a=u(n,e.fileContent);return{success:a,error:!a,path:n}}function he(e){const{success:t,path:s}=m((n=e,()=>{let e="";const t=n.typescript?"ts":"js";switch(n.framework){case U:e=H.storybook.react[t].component;break;case A:e=H.storybook.vue[3][t].component;break;default:console.error("Framework is required to get a template")}return{...n,templatePath:e}}),ye,we,ge,_e);var n;t?console.info("Story created successfully: "+s):console.error("Error on create Story, try again")}function ye(e){const s=l(t.join(rt,e.templatePath));return{...e,fileContent:s}}function we(e){e.name=$("PascalCase",e.name);const t=X({language:e.typescript?"ts":"js",framework:"react"===e.framework?e.framework:"vanilla",target:"resource",postfix:e.storyPostfix}),s=e.folderWrapper&&["component","page"].includes(e.type)?`${e.name}/${e.name}.${t}`:`${e.name}.${t}`,n=`${e.path}/${s}`,a=`${e.resourcePath}/${e.name}.${t}`;return{...e,extension:t,fileName:s,pathWithFileName:n,resourcePathWithFileName:a}}function ge(e){if(it?.exportDefault){const t=new RegExp("import { ResourceName } from");e.fileContent=e.fileContent.replace(t,"import ResourceName from")}if(e.fileContent=e.fileContent.replace(/ResourceName/g,e.name),e.framework===A){const t=ee(e.resourcePathWithFileName);e.fileContent=e.fileContent.replace(/resourcePath/g,t)}if(e.framework===U){const t=ee(e.resourcePathWithFileName);e.fileContent=e.fileContent.replace(/resourcePath/g,t)}return it?.alias?.src&&(e.fileContent=e.fileContent.replace(/src/g,it.alias.src)),e}function _e(e){const t=e.pathWithFileName;return{success:u(e.pathWithFileName,e.fileContent),path:t}}const je="module",ke="style";function Ce(e){const{success:t,path:s}=m((n=e,()=>{let e=B[n.cssFramework];return{...n,templatePath:e}}),xe,Pe,be);var n;t?console.info("Style created successfully: "+s):console.error("Error on create style, try again")}function xe(e){const s=l(t.join(rt,e.templatePath));return{...e,fileContent:s}}function Pe(e){return e.name=$("PascalCase",e.name),e.fileContent=e.fileContent.replace("component",$("kebab-case",e.name)),e}function be(e){const t=X({postfix:"css_modules"===e.cssFramework?je:ke,target:"style",cssFramework:e.cssFramework}),s=e.folderWrapper&&["component","page"].includes(e.type)?`${e.name}/${e.name}.${t}`:`${e.name}.${t}`,n=`${e.path}/${s}`,a=u(n,e.fileContent);return{success:a,error:!a,path:n}}async function Se(e){await Te(e.resourcePath,(async t=>{switch(e.type){case"page":case"component":te({...e,path:t}),e.framework===U&&await async function(e,t){if(["no_style","tailwind_inline"].includes(e.cssFramework))return;if(e.storyPath===e.resourcePath)return Ce({...e,path:t});return await Te(e.storyPath,(s=>Ce({...e,path:s,resourcePath:t})),"style")}(e,t);break;case"function":me({...e,path:t})}await async function(e,t){if(!e.withTest)return;if(e.testPath===e.resourcePath)return ie({...e,path:t});return await Te(e.testPath,(s=>ie({...e,path:s,resourcePath:t})),e.testPostfix)}(e,t),await async function(e,t){if(!e.withStory)return;if(e.storyPath===e.resourcePath)return he({...e,path:t});return await Te(e.storyPath,(s=>he({...e,path:s,resourcePath:t})),e.storyPostfix)}(e,t)}),e.type)}async function Te(e,t,s){if(d(S(e)))return await t(e);{const e=await o({message:`The ${s} path not exist's. Provide the correct path:`});await Te(e,t,s)}}const $e="page",Fe="component",We="function",Oe={css_vanilla:"CSS Vanilla",css_modules:"CSS Modules",no_style:"None",scss:"Sass/Scss",tailwind_file:"Tailwind (css file w/ @apply)",tailwind_inline:"Tailwind (inline w/ class attr)"},Ne=[{name:"Page",value:$e},{name:"Component",value:Fe},{name:"Function",value:We}],Ee=[{name:"Page",value:$e},{name:"Component",value:Fe},{name:"Function",value:We}],Le=[{name:"Jest",value:"jest"},{name:"Vitest",value:Y}],Ie=[{name:"Vue",value:A},{name:"React",value:U}],Re=[{name:Oe.no_style,value:G},{name:Oe.css_vanilla,value:"css_vanilla"},{name:Oe.tailwind_inline,value:"tailwind_inline"},{name:Oe.tailwind_file,value:"tailwind_file"},{name:Oe.css_modules,value:q},{name:Oe.scss,value:"scss"}],Me=[{name:"3",value:3},{name:"2",value:2}],Ve=[{name:".spec",value:"spec"},{name:".test",value:"test"}],De=[{name:"Type my path",value:"type-path"}],Je={page:[{name:"src/pages",value:"src/pages"},{name:"src/views",value:"src/views"}],component:[{name:"components",value:"components"},{name:"src/components",value:"src/components"}],function:[{name:"functions",value:"functions"},{name:"src/functions",value:"src/functions"},{name:"utils",value:"utils"},{name:"src/utils",value:"src/utils"},{name:"helpers",value:"helpers"},{name:"src/helpers",value:"src/helpers"}],type:[{name:"@types",value:"@types"},{name:"types",value:"types"},{name:"src/types",value:"src/types"},{name:"src/@types",value:"src/@types"}],model:[{name:"src/models",value:"src/models"}],enum:[{name:"src/enums",value:"src/enums"},{name:"src/models",value:"src/models"}],test:{page:[{name:"src/__tests__",value:"src/__tests__"},{name:"src/pages",value:"src/pages"},{name:"src/pages/__tests__",value:"src/pages/__tests__"},{name:"src/views",value:"src/views"},{name:"src/views/__tests__",value:"src/views/__tests__"}],component:[{name:"src/tests",value:"src/tests"},{name:"src/__tests__",value:"src/__tests__"},{name:"src/components",value:"src/components"},{name:"src/components/__tests__",value:"src/components/__tests__"}],function:[{name:"src/tests",value:"src/tests"},{name:"src/__tests__",value:"src/__tests__"},{name:"src/utils",value:"src/utils"},{name:"src/utils/__tests__",value:"src/utils/__tests__"},{name:"src/helpers",value:"src/helpers"},{name:"src/helpers/__tests__",value:"src/helpers/__tests__"},{name:"src/functions",value:"src/functions"},{name:"src/functions/__tests__",value:"src/functions/__tests__"},{name:"src/core",value:"src/core"},{name:"src/core/__tests__",value:"src/core/__tests__"},{name:"src/shared",value:"src/shared"},{name:"src/shared/__tests__",value:"src/shared/__tests__"}]},cypress_spec:[{name:"e2e",value:"e2e"},{name:"src/e2e",value:"src/e2e"},{name:"cypress",value:"cypress"},{name:"src/cypress",value:"src/cypress"}],storybook_story:{page:[{name:"storybook",value:"storybook"},{name:"stories",value:"stories"},{name:"src/storybook",value:"src/storybook"},{name:"src/stories",value:"src/stories"},{name:"src/__stories__",value:"src/__stories__"},{name:"src/pages/__stories__",value:"src/pages/__stories__"}],component:[{name:"storybook",value:"storybook"},{name:"stories",value:"stories"},{name:"src/storybook",value:"src/storybook"},{name:"src/stories",value:"src/stories"},{name:"src/__stories__",value:"src/__stories__"},{name:"src/components/__stories__",value:"src/components/__stories__"}]}};function Ae({type:e,target:t}){return"test"===t?Je.test[e]:"story"===t?Je.storybook_story[e]:Je[e]}function Ue(e){return e?Oe[e]:null}function Ye(e){return!!e||'Enter an existing path. For root dir, use "."'}async function qe(){return await o({message:"Name: ",validate:e=>!!e||"Invalid. Please enter name!"})}async function Ge(){return await o({message:"Preset name: ",validate:e=>!!e||"Invalid. Please enter preset name!"})}async function ze(e){let t=!1,s=!1,n=!1,a=null,c=null,l=null,u=null,p=null,m=null,f="css_vanilla",d=null,v=!1;const h=await r({message:"Do you use TypeScript?"}),y=await i({message:"What do you want to create?",choices:h?Ne:Ee});["component","page"].includes(y)&&(c=await i({message:"Select your framework/lib",choices:Ie})),v=await r({message:"Put the files in a folder with the same name as the resource?"}),c===A&&(d=await i({message:"What is your Vue version?",choices:Me})),["component","page"].includes(y)&&(f=await i({message:"Would you like to select the CSS styles?",choices:Re,default:G}));const w=Ae({type:y});if(w&&(m=await i({message:`What is the folder path that I should create your ${y} in?`,choices:[...De,...w]})),w&&"type-path"!==m||(m=await o({message:`What is the folder path that I should create your ${y} in? e.g. src/folder/here`,validate:Ye})),["component","function","page"].includes(y)&&(t=await r({message:"Would you like to add unit tests?"})),t){const e=Ae({type:y,target:"test"});e&&(u=await i({message:"What is the folder path that I should create your tests in?",choices:[{name:`Same as your ${y}: ${m}`,value:m},...De,...e]})),e&&"type-path"!==u||(u=await o({message:"What is the folder path that I should create your tests in? e.g. folder/here",validate:Ye})),l=await i({message:"What is your test framework?",choices:Le}),["component","page"].includes(y)&&(n=await r({message:"Do you use Testing Library in your tests?"})),a=await i({message:"What postfix do you use in your test file?",choices:Ve})}const g=c===A&&2===d&&h;if(["component"].includes(y)&&!g&&(s=await r({message:"Would you like to add storybook story?"})),s){const e=Ae({type:y,target:"story"});e&&(p=await i({message:"What is the folder path that I should create your story in?",choices:[{name:`Same as your ${y}: ${m}`,value:m},...De,...e]})),e&&"type-path"!==p||(p=await o({message:"What is the folder path that I should create your story in? e.g. folder/here",validate:Ye}))}let _=null;_=e||await qe();return{framework:c,cssFramework:f,testFramework:l,version:d,name:_,resourcePath:m,testPath:u,storyPath:p,testPostfix:a,storyPostfix:"stories",type:y,typescript:h,withStory:s,withTest:t,withTestingLibrary:n,folderWrapper:v}}function Ze(e,t,s=!1){const n=[];if("object"!=typeof e||null===e)return n.push("The provided value is not an object or this identifier does not exist inside your meta file."),n;for(const a in t){const o=t[a],r=e[a];if(void 0!==r)if("array"===o.type){if(!Array.isArray(r)){n.push(`Expected an array for key '${a}', but got type '${typeof r}'.`);continue}r.forEach(((e,t)=>{const r=Ze(e,o.items,s);r.length>0&&n.push(...r.map((e=>`${a}[${t}].${e}`)))}))}else if("object"==typeof o&&null!==o){const e=Ze(r,o,s);e.length>0&&n.push(...e.map((e=>`${a}.${e}`)))}else typeof r!==o&&n.push(`Expected type '${o}' for key '${a}', but got type '${typeof r}'.`);else s||n.push(`Missing required key: ${a}`)}return n}const He={identifier:"string",folderWrapper:"boolean",resources:{type:"array",items:{path:"string",template:"string"}}};function Ke(e){try{const{path:t,type:n}=function(){const e=s(process.cwd(),".clingon","templates");try{const t=s(e,"meta.yaml");if(p(t))return{path:t,type:"yaml"};const n=s(e,"meta.json");if(p(n))return{path:n,type:"json"};throw new Error("Meta file is not defined, run `npx clingon init --template`")}catch(e){throw new Error(e)}}(),a=l(t);let o=null;switch(n){case"json":o=JSON.parse(a);case"yaml":o=c(a)}return o.find((t=>t.identifier===e))}catch(e){console.error(e)}}function Be(e){return Ze(e,He,!0)}function Qe(e){const t=Xe(e,"/");return{fileName:t,extension:Xe(t,/^[^.]*\./)}}function Xe(e,t){const s=e.split(t);return s[s.length-1]}function et(e,t,n){const a=t.replace(/ResourceName/g,e);a&&(t=a);const{extension:o}=Qe(n.resource.template);return t=function(e,t){const s=ee(e),n=t.replace(/resourcePath/g,s);n&&(t=n);return t}(s(n.resource.path,`${e}.${o}`),t),t}function tt(e,t){const{extension:n}=Qe(t.resource.template),a=t.resource.template.includes("index")?`index.${n}`:`${e}.${n}`;return s(t.resource.path,a)}function st(e,t){return()=>{const n=t?.folderWrapper?s(t?.resource?.path,e):t?.resource?.path,a=S(n);let o="";return a&&(o=d(a)),o?.resource||(o=v(function(e){return s(process.cwd(),e)}(n))),{name:e,template:t,target:o}}}function nt({name:e,template:t,target:n}){if(!n)return;let a="";try{return a=l(function(e){return s(process.cwd(),".clingon","templates",e)}(t?.resource?.template)),{name:e,template:t,templateContent:a,target:n}}catch(e){console.error(e)}}function at({name:e,template:t,templateContent:s,target:n}){return{name:e=$(t.case??"PascalCase",e),template:t,templateContent:s=et(e,s,t),target:n}}function ot({name:e,target:t,template:n,templateContent:a}){let o;if(t){n.folderWrapper&&(n.resource.path=s(n.resource?.path,e));const t=function(e){const t=e.resource.template.split("/");return t[t.length-1].split(".")[0]}(n),r=n.keepTemplateName?tt(t,n):tt(e,n);u(r,a)&&(o=r)}return o}const rt=f(),{globalConfig:it}=await async function(){const e=s(process.cwd(),"clingon.config.json"),t={globalConfig:void 0};try{if(!p(e))return{globalConfig:null};const s=l(e),n=JSON.parse(s);t.globalConfig=n}catch(e){console.error(e)}return t}(),ct=new e;ct.name("clingon").description("CLI to generate files based on templates").version("1.0.0","-v, --version","Current version"),ct.command("gen").argument("[name]","Resource name").action((async function e(t){let s,n=!1;const a=g();if(a&&a.length>0){const e=C(j(a));n=await i({message:"You already have some presets saved. Want to use some?",choices:[{name:"No, create a new one",value:!1},...e]})}if(n?(s=_(n),s.name=t??await qe()):s=await ze(t),s&&function(e){const t={"Framework/Lib":e.framework,"Framework/Lib Version":e.version,"Resource Type":e.type,"Resource Name":e.name,"With TypeScript":T(e.typescript),"CSS approach":Ue(e.cssFramework),"With Story":T(e.withStory),"With Unit Test":T(e.withTest),"With Testing Library":T(e.withTestingLibrary),"My Test Postfix":e.testPostfix,"My Test Framework":e.testFramework,"Resource Path":e.resourcePath,"Test Path":e.testPath,"Story Path":e.storyPath},s=Object.fromEntries(Object.entries(t).filter((([e,t])=>null!==t)));console.table(s)}(s),!n){if(await r({message:"Do you want to save the answers as a preset to use later?"})){const e=await Ge(),{success:t,path:n}=k(e,s);t?console.info("Preset saved with success on: "+n):console.error("Error on create preset file, try again")}}if(await r({message:"Confirm this is what you want to create?"}))await Se(s);else{await r({message:"Do you want to restart the generator?"})&&e()}})).description("Start a guided flow to generate resources (components, functions, pages, etc)"),ct.command("scaffold").argument("<name>","Resource name").option("-t, --template <template>","Template name").action((async function(e,t){const n=s(process.cwd(),".clingon","templates"),a=Ke(t.template),o=Be(a);if(o.length>0){console.error(`\n⎡ Template has many errors, review your meta file at: \n⎪\n⎣ → ${n}`),console.error("\n⎡ Validation errors: \n⎪");const e=o.length-1;return void o.forEach(((t,s)=>console.error(`${e===s?"⎣":"⎪"}${t}`)))}const r=await async function(e,t){let s=[];for(let n of t.resources){const a=m(st(e,{identifier:t.identifier,folderWrapper:t.folderWrapper,keepTemplateName:t.keepTemplateName,case:t.case,resource:n}),nt,at,ot);s.push(a)}return s}(e,a);r&&function(e){console.info("⎧ 💿 Files successfully created at:\n⎪"),e.forEach((e=>console.info("⎪⎯→ "+e)))}(r)})).description("Generate resources based on a local template config inside meta.yaml or meta.json"),ct.command("create").argument("<name>","Resource name").option("-p, --preset [preset]","Preset name").option("-t, --type [resourceType]",'Resource type: "function" | "page" | "component"').option("-vv, --vue-version [vueVersion]",'Vue version: "2" | "3" (default: 3))',"3").option("-f, --framework [frameworkName]","Framework name for default preset: vue or react").option("-cs, --css-framework [cssFramework]",'Style approach: "css_modules" | "tailwind_inline" | "tailwind_file" | "css_vanilla" | "scss" (default: no_style)',"no_style").option("-tf, --test-framework [testFrameworkName]","Test framework: jest or vitest (default: vitest)",Y).option("-rp, --path [resourcePath]",'Path to resource, use dot (".") to current dir where command is executed').option("-tp, --test-path [testPath]",'Path to test, use dot (".") to current dir where command is executed, if ommited, and --spec is present, will use the same path to resource').option("-sp, --story-path [storyPath]",'Path to story, use dot (".") to current dir where command is executed, if ommited, and --spec is present, will use the same path to resource').option("-ts, --typescript","With TypeScript (default: false)",!1).option("-tl, --testing-library","With Testing Library (default: false)",!1).option("--test","Add test file (default: false)",!1).option("--spec","Add spec file (default: false)",!1).option("--story","Add story file (default: false)",!1).option("-fw, --folder-wrapper","Creates a folder with the name of the resource, with the files inside it",!1).action((async function(e,t){let s,n=t.preset;if(!n&&t.framework){if(!t.type||!t.framework||!t.path)throw new Error("You did not pass any of the mandatory parameters for Options Mode");let n=t.path,a=t.story,o=t.path,r="spec",i=t.test||t.spec;t.story&&(n=t.storyPath??t.path),(t.test||t.spec)&&(o=t.testPath??t.path,r=t.test?"test":t.spec?"spec":void 0),s={name:e,framework:t.framework,testFramework:t.testFramework,cssFramework:t.cssFramework,typescript:t.typescript,type:t.type,resourcePath:t.path,withTestingLibrary:t.testingLibrary,version:t.vueVersion,folderWrapper:t.folderWrapper,keepTemplateName:t.keepTemplateName,storyPostfix:"stories",testPath:o,storyPath:n,testPostfix:r,withStory:a,withTest:i}}if(!t.framework&&n)s=_(n+".json"),s.name=e??await qe();else if(!t.framework){const e=g();if(e&&e.length>0){const t=C(j(e));n=await async function(e){return await i({message:"It appears that there is no template with that name, select an existing template from the list below: ",choices:[{name:"No, create a new one",value:!1},...e]})}(t)}if(!e||!n){console.info("\nYou don't have presets yet, let's follow the creation flow and at the end you can save as a preset.\n"),s=await ze();const e=await r({message:"Do you want to save the answers as a preset to use later?"}),t=await Ge();if(e){const{success:e,path:n}=k(t,s);e?console.info("Preset saved with success on: "+n):console.error("Error on create preset file, try again")}}}s?await Se(s):console.error("Error: an error has ocurred when retrieve answers, try again")})).usage("create <resourceName> --preset <presetName>").usage("create <resourceName> --type (component | page | function) --framework <framework> (--test | --spec) --typescript --folder-wrapper --story --test-framework (vitest | jest)").description("Creates the resources with a local preset in non-verbose mode (preview and ask to confirm are not shown, resources will be created immediately), if the preset folder is empty, it will call the guided flow (the same as the `gen` command executes)"),ct.command("init").action((async function(e={examples:!1}){var t;m((t=e?.examples,()=>{const e=s(process.cwd(),"clingon.config.json");return p(e)?{fullPath:e,examples:t}:{fullPath:void 0,examples:t}}),W),m(function(e){const t=d([N,O]);return()=>({exists:t,examples:e})}(e?.examples),L,I),m(function(e){const t=d([N,R]);return()=>({exists:t,examples:e})}(e?.examples),V,D)})).option("-e, --examples [examples]","Generate folders with examples",!1).description("Init all needed setup, generate files and create folders to store assets."),ct.parse();export{it as globalConfig,rt as localDirname};