@aerogel/cli 0.0.0-next.7e89f52eb37d9154f4879a5ccd058d27d476dada → 0.0.0-next.980a397d575dcb5ff8c5a0bff769d09f938ea03c
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/aerogel-cli.cjs.js +1 -1
- package/dist/aerogel-cli.cjs.js.map +1 -1
- package/dist/aerogel-cli.esm.js +1 -1
- package/dist/aerogel-cli.esm.js.map +1 -1
- package/package.json +10 -4
- package/src/commands/Command.ts +15 -7
- package/src/commands/create.test.ts +21 -4
- package/src/commands/create.ts +10 -7
- package/src/commands/generate-component.test.ts +59 -6
- package/src/commands/generate-component.ts +49 -14
- package/src/commands/generate-model.test.ts +11 -3
- package/src/commands/generate-model.ts +7 -8
- package/src/commands/generate-service.test.ts +10 -2
- package/src/commands/generate-service.ts +5 -6
- package/src/commands/install.test.ts +36 -5
- package/src/commands/install.ts +6 -5
- package/src/lib/Editor.ts +16 -9
- package/src/lib/Shell.mock.ts +1 -1
- package/src/lib/Template.ts +5 -1
- package/src/lib/utils/app.ts +1 -1
- package/src/lib/utils/paths.ts +1 -1
- package/src/plugins/Histoire.ts +105 -0
- package/src/plugins/Plugin.ts +57 -4
- package/src/plugins/Solid.ts +47 -34
- package/src/plugins/Soukai.ts +1 -1
- package/src/testing/stubs/ProgramStub.ts +35 -0
- package/src/testing/utils.ts +14 -0
- package/templates/app/.github/workflows/ci.yml +14 -2
- package/templates/app/README.md +3 -0
- package/templates/app/{cypress.config.ts → cypress/cypress.config.ts} +4 -0
- package/templates/app/index.html +3 -2
- package/templates/app/package.json +14 -2
- package/templates/app/src/App.vue +2 -2
- package/templates/app/src/assets/public/robots.txt +2 -0
- package/templates/app/src/main.ts +1 -1
- package/templates/app/tsconfig.json +1 -0
- package/templates/app/vite.config.ts +10 -4
- package/templates/component-button/[component.name].vue +32 -0
- package/templates/component-button-story/[component.name].story.vue +71 -0
- package/templates/component-input/[component.name].vue +16 -0
- package/templates/component-input-story/[component.name].story.vue +63 -0
- package/templates/histoire/histoire.config.ts +7 -0
- package/templates/histoire/patches/histoire+0.17.6.patch +13 -0
- package/templates/histoire/src/main.histoire.ts +8 -0
- package/templates/postcss-pseudo-classes/postcss.config.js +15 -0
- package/.eslintrc.js +0 -7
- package/noeldemartin.config.js +0 -14
- package/src/lib/utils/format.test.ts +0 -33
- package/src/lib/utils/format.ts +0 -38
- package/templates/app/.eslintrc.js +0 -3
- package/templates/app/prettier.config.js +0 -5
- /package/bin/{ag → gel} +0 -0
- /package/templates/app/src/assets/{styles.css → css/styles.css} +0 -0
package/dist/aerogel-cli.cjs.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("commander"),t=require("@babel/runtime/helpers/defineProperty");require("core-js/modules/esnext.async-iterator.reduce.js"),require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.reduce.js");var i=require("@noeldemartin/utils"),s=require("fs"),n=require("path");require("core-js/modules/esnext.async-iterator.for-each.js"),require("core-js/modules/esnext.iterator.for-each.js"),require("core-js/modules/esnext.async-iterator.find.js"),require("core-js/modules/esnext.iterator.find.js"),require("core-js/modules/esnext.async-iterator.map.js"),require("core-js/modules/esnext.iterator.map.js");var r=require("chalk"),a=require("readline"),o=require("mustache");require("core-js/modules/esnext.set.add-all.js"),require("core-js/modules/esnext.set.delete-all.js"),require("core-js/modules/esnext.set.difference.js"),require("core-js/modules/esnext.set.every.js"),require("core-js/modules/esnext.set.filter.js"),require("core-js/modules/esnext.set.find.js"),require("core-js/modules/esnext.set.intersection.js"),require("core-js/modules/esnext.set.is-disjoint-from.js"),require("core-js/modules/esnext.set.is-subset-of.js"),require("core-js/modules/esnext.set.is-superset-of.js"),require("core-js/modules/esnext.set.join.js"),require("core-js/modules/esnext.set.map.js"),require("core-js/modules/esnext.set.reduce.js"),require("core-js/modules/esnext.set.some.js"),require("core-js/modules/esnext.set.symmetric-difference.js"),require("core-js/modules/esnext.set.union.js");var l=require("ts-morph"),c=require("child_process");function d(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}require("core-js/modules/esnext.async-iterator.some.js"),require("core-js/modules/esnext.iterator.some.js");var u=d(t);var p=i.facade(new class{contains(e,t){return!!this.read(e)?.includes(t)}exists(e){return s.existsSync(e)}isSymlink(e){return s.lstatSync(e).isSymbolicLink()}read(e){return this.isFile(e)?s.readFileSync(e).toString():null}getFiles(e){const t=s.readdirSync(e,{withFileTypes:!0}),i=[];for(const s of t){const t=n.resolve(e,s.name);s.isDirectory()?i.push(...this.getFiles(t)):i.push(t)}return i}isDirectory(e){return this.exists(e)&&s.lstatSync(e).isDirectory()}isFile(e){return this.exists(e)&&s.lstatSync(e).isFile()}isEmptyDirectory(e){return!!this.isDirectory(e)&&0===this.getFiles(e).length}makeDirectory(e){s.mkdirSync(e,{recursive:!0})}write(e,t){s.existsSync(n.dirname(e))||s.mkdirSync(n.dirname(e),{recursive:!0}),s.writeFileSync(e,t)}});var m=i.facade(new class{constructor(){u.default(this,"renderInfo",r.hex("#00ffff")),u.default(this,"renderSuccess",r.hex("#00ff00")),u.default(this,"renderError",r.hex("#ff0000"))}async animate(e,t){var i=this;const s=function(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",s=arguments.length>1&&void 0!==arguments[1]&&arguments[1];const r=i.renderInfo(i.renderMarkdown(e)+(s?"...":".".repeat(n%4)))+t;i.stdout(r)};let n=0;s();const r=setInterval((()=>(n++,s())),1e3),a=await t();return clearInterval(r),s("\n",!0),a}info(e){this.log(this.renderMarkdown(e),this.renderInfo)}error(e){this.log(this.renderMarkdown(e),this.renderError)}fail(e){this.error(e),process.exit(1)}success(e){this.log(this.renderMarkdown(e),this.renderSuccess)}renderMarkdown(e){const t=i.stringMatchAll(e,/\*\*(.*)\*\*/g);for(const i of t)e=e.replace(i[0],r.bold(i[1]));return e}log(e,t){this.formatMessage(e).forEach((e=>{this.logLine(t?t(e):e)}))}formatMessage(e){if("\n"===e[0]){const t=(e=e.slice(1).trimEnd()).split("\n"),i=e.trim()[0]??"",s=t.find((e=>e.trim().length>0))?.indexOf(i)??0;return t.map((e=>e.slice(s)))}return[e]}logLine(e){console.log(e)}stdout(e){a.cursorTo(process.stdout,0),a.clearLine(process.stdout,0),process.stdout.write(e)}});class g{static instantiate(e,t,i){return new g(e).instantiate(t,i)}constructor(e){u.default(this,"path",void 0),this.path=e}instantiate(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const i=this.getFilenameReplacements(t),n=[];e=`${e}/`.replace(/\/\//,"/");for(const r of p.getFiles(this.path)){const a=Object.entries(i).reduce(((e,t)=>{let[i,s]=t;return e.replaceAll(i,s)}),r.substring(this.path.length+1)),l=s.readFileSync(r).toString(),c=e+(a.endsWith(".template")?a.slice(0,-9):a);p.write(c,o.render(l,t,void 0,["<%","%>"])),n.push(c)}return n}getFilenameReplacements(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return Object.entries(e).reduce(((e,s)=>{let[n,r]=s;return"object"==typeof r?Object.assign(e,this.getFilenameReplacements(r,`${n}.`)):e[`[${t}${n}]`]=i.toString(r),e}),{})}}function f(e){return m.fail(`Could not find ${e} pack file, did you run 'npm pack'?`)}function h(e){return p.getFiles(y(e)).find((e=>e.endsWith(".tgz")))??null}function y(e){return function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";if(p.contains(n.resolve(__dirname,"../../../package.json"),'"name": "aerogel"'))return n.resolve(__dirname,"../",e);const t=p.read(n.resolve(__dirname,"../../../../package.json")),s=i.stringMatch(t??"",/"@aerogel\/cli": "file:(.*)\/aerogel-cli-[\d.]*\.tgz"/),r=s?.[1]??m.fail("Could not determine base path");return n.resolve(r,e)}(`../${e}`)}function v(e){return n.resolve(__dirname,`../templates/${e}`)}var w=i.facade(new class{constructor(){u.default(this,"cwd",null)}setWorkingDirectory(e){this.cwd=e}async run(e){await new Promise(((t,i)=>{c.exec(e,{cwd:this.cwd??void 0},(e=>{e?i(e):t()}))}))}});class x{constructor(){u.default(this,"project",void 0),u.default(this,"modifiedFiles",void 0),this.project=new l.Project({tsConfigFilePath:"tsconfig.json"}),this.modifiedFiles=new Set,this.project.addSourceFilesAtPaths("src/**/*.ts"),this.project.addSourceFilesAtPaths("tailwind.config.js"),this.project.addSourceFilesAtPaths("vite.config.ts")}addSourceFile(e){this.project.addSourceFilesAtPaths(e)}requireSourceFile(e){return this.project.getSourceFileOrThrow(e)}async format(){await m.animate("Formatting modified files",(async()=>{const e=p.exists("prettier.config.js"),t=p.exists(".eslintrc.js");await Promise.all(i.arrayFrom(this.modifiedFiles).map((async i=>{e&&await w.run(`npx prettier ${i} --write`),t&&await w.run(`npx eslint ${i} --fix`)})))}))}async save(e){await e.save(),this.modifiedFiles.add(e.getFilePath())}}class j{constructor(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};u.default(this,"name",void 0),u.default(this,"options",void 0),this.name=e,this.options=t}create(e){!p.exists(e)||p.isDirectory(e)&&p.isEmptyDirectory(e)||m.fail(`Folder at '${e}' already exists!`),g.instantiate(v("app"),e,{app:{name:this.name,slug:i.stringToSlug(this.name)},dependencies:this.getDependencies(),contentPath:this.options.linkedLocal?`${y("core")}/dist/**/*.js`:"./node_modules/@aerogel/core/dist/**/*.js"})}edit(){return new x}getDependencies(){const e=e=>Object.entries(e).reduce(((e,t)=>{let[i,s]=t;return Object.assign(e,{[i]:`file:${s}`})}),{});return this.options.linkedLocal?e({aerogelCli:y("cli"),aerogelCore:y("core"),aerogelCypress:y("cypress"),aerogelPluginI18n:y("plugin-i18n"),aerogelPluginSoukai:y("plugin-soukai"),aerogelVite:y("vite")}):this.options.local?e({aerogelCli:h("cli")??f("cli"),aerogelCore:h("core")??f("core"),aerogelCypress:h("cypress")??f("cypress"),aerogelPluginI18n:h("plugin-i18n")??f("plugin-i18n"),aerogelPluginSoukai:h("plugin-soukai")??f("plugin-soukai"),aerogelVite:h("vite")??f("vite")}):{aerogelCli:"next",aerogelCore:"next",aerogelCypress:"next",aerogelPluginI18n:"next",aerogelPluginSoukai:"next",aerogelVite:"next"}}}class S{static define(e){var t=this;e=e.command(this.command).description(this.description);for(const[t,i]of this.parameters)e=e.argument(`<${t}>`,i);for(const[t,i]of Object.entries(this.options)){const s="string"==typeof i?i:i.description,n="string"==typeof i?"string":i.type??"string";e=e.option("boolean"===n?`--${t}`:`--${t} <${n}>`,s)}e=e.action((function(){for(var e=arguments.length,i=new Array(e),s=0;s<e;s++)i[s]=arguments[s];return t.run.call(t,...i)}))}static async run(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];const s=new this(...t);await s.run()}async run(){}assertAerogelOrDirectory(e){const t=p.read("package.json");if(t?.includes("@aerogel/core"))return;if(e&&p.isDirectory(e))return;const i=e?`${e} folder does not exist.`:"package.json does not contain @aerogel/core.";m.fail(`${i} Are you sure this is an Aerogel app?`)}}u.default(S,"command",""),u.default(S,"description",""),u.default(S,"parameters",[]),u.default(S,"options",{});class $ extends S{constructor(e,t){super(),u.default(this,"path",void 0),u.default(this,"options",void 0),this.path=e,this.options=t}async run(){const e=this.path,t=this.options.name??"Aerogel App";w.setWorkingDirectory(e),await this.createApp(t,e),await this.installDependencies(),await this.initializeGit(),m.success(`\n\n That's it! You can start working on **${t}** doing the following:\n\n cd ${e}\n npm run dev\n\n Have fun!\n `)}async createApp(e,t){m.info(`Creating **${e}**...`),new j(e,{local:this.options.local,linkedLocal:this.options.local&&!this.options.copy}).create(t)}async installDependencies(){await m.animate("Installing dependencies",(async()=>{await w.run("npm install")}))}async initializeGit(){await m.animate("Initializing git",(async()=>{await w.run("git init"),await w.run("git add ."),await w.run('git commit -m "Start"')}))}}function k(){return new j("")}function C(){return p.isSymlink("node_modules/@aerogel/core")}function A(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!e)return;const s=t.guard??(()=>!0),n=t.validate??(()=>!0),r=i.arrayFrom(t.skip??[]);return e.forEachDescendant(((e,t)=>{if(s(e)&&n(e))return e;const i=e.getKind();r.includes(i)&&t.skip()}))}function F(e,t){if(e&&t(e))return e}u.default($,"command","create"),u.default($,"description","Create AerogelJS app"),u.default($,"parameters",[["path","Application path"]]),u.default($,"options",{name:"Application name",local:{type:"boolean",description:"Whether to create an app using local Aerogel packages (used for core development)"},copy:{type:"boolean",description:"Whether to create an app linked to local Aerogel packages (used in CI)"}});class q extends S{constructor(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(),u.default(this,"path",void 0),u.default(this,"options",void 0),this.path=e,this.options=t}async run(){this.assertAerogelOrDirectory("src/components"),this.assertHistoireInstalled();const e=new Set,[t,s]=this.parsePathComponents();await this.createComponent(t,s,e),await this.createStory(s,e),await this.declareComponents();const n=i.arrayFrom(e).map((e=>`- ${e}`)).join("\n");m.info(`${s} component created successfully! The following files were created:\n\n${n}`)}assertHistoireInstalled(){this.options.story&&(p.exists("src/main.histoire.ts")||m.fail("Histoire is not installed yet!"))}async createComponent(e,t,i){await m.animate("Creating component",(async()=>{p.exists(`src/components/${this.path}.vue`)&&m.fail(`${this.path} component already exists!`);g.instantiate(v("component"),`src/components/${e}`,{component:{name:t}}).forEach((e=>i.add(e)))}))}async createStory(e,t){this.options.story&&await m.animate("Creating story",(async()=>{g.instantiate(v("component-story"),"src/components",{component:{name:e}}).forEach((e=>t.add(e)))}))}async declareComponents(){const e=k().edit(),t=e.requireSourceFile("vite.config.ts"),i=this.getComponentDirsArray(t);if(!i)return m.fail("Could not find component dirs declaration in vite config!");i.getDescendantsOfKind(l.SyntaxKind.StringLiteral).some((e=>"'src/components'"===e.getText()))||(await m.animate("Updating vite config",(async()=>{i.addElement("'src/components'"),await e.save(t)})),await e.format())}getComponentDirsArray(e){const t=A(e,{guard:l.Node.isCallExpression,validate:e=>e.getText().startsWith("Components("),skip:l.SyntaxKind.ImportDeclaration});if(!t)return null;const i=A(t,{guard:l.Node.isPropertyAssignment,validate:e=>"dirs"===e.getName()}),s=i?.getInitializer();return l.Node.isArrayLiteralExpression(s)?s:this.declareComponentDirsArray(t)}declareComponentDirsArray(e){const t=A(e,{guard:l.Node.isObjectLiteralExpression}),i=t?.addPropertyAssignment({name:"dirs",initializer:"[]"});return i?.getInitializer()??null}parsePathComponents(){const e=this.path.lastIndexOf("/");return-1===e?["",this.path]:[this.path.substring(0,e),this.path.substring(e+1)]}}function D(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const i=e.split("\n"),s=t.indent??0;let n=0,r="";for(const e of i){const t=e.trim(),i=0===t.length;if(0===r.length){if(i)continue;n=e.indexOf(t[0]??""),r+=`${" ".repeat(s)}${t}\n`;continue}if(i){r+="\n";continue}const a=e.indexOf(t[0]??"");r+=`${" ".repeat(s+a-n)}${t}\n`}return r.trimEnd()}u.default(q,"command","generate:component"),u.default(q,"description","Generate an AerogelJS Component"),u.default(q,"parameters",[["path","Component path (relative to components folder; extension not necessary)"]]),u.default(q,"options",{story:{description:"Create component story using Histoire",type:"boolean"}});class I extends S{constructor(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(),u.default(this,"name",void 0),u.default(this,"options",void 0),this.name=e,this.options=t}async run(){this.assertAerogelOrDirectory("src/models"),p.exists(`src/models/${this.name}.ts`)&&m.fail(`${this.name} model already exists!`),this.assertSoukaiInstalled();const e=await m.animate("Creating model",(async()=>g.instantiate(v("model"),"src/models",{model:{name:this.name,fieldsDefinition:this.getFieldsDefinition()},soukaiImports:this.options.fields?"FieldType, defineModelSchema":"defineModelSchema"}).map((e=>`- ${e}`)).join("\n")));m.info(`${this.name} model created successfully! The following files were created:\n\n${e}`)}getFieldsDefinition(){if(!this.options.fields)return" //";const e=this.options.fields.split(",").map((e=>{const[t,s,n]=e.split(":");return{name:t,type:i.stringToStudlyCase(s??"string"),required:"required"===n}})).reduce(((e,t)=>e+`\n${t.required?D(`\n ${t.name}: {\n type: FieldType.${t.type},\n required: true,\n }\n `):`${t.name}: FieldType.${t.type}`},`),"");return D(e,{indent:8})}assertSoukaiInstalled(){p.contains("package.json",'"soukai"')||p.contains("package.json",'"@aerogel/plugin-soukai"')||m.fail("\n Soukai is not installed yet! You can install it running:\n npx ag install soukai\n ")}}u.default(I,"command","generate:model"),u.default(I,"description","Generate an AerogelJS Model"),u.default(I,"parameters",[["name","Model name"]]),u.default(I,"options",{fields:"Create model with the given fields"});class P extends S{constructor(e){super(),u.default(this,"name",void 0),this.name=e}async run(){this.assertAerogelOrDirectory("src/services");const e=new Set,t=k().edit();await this.createService(e),await this.registerService(t),await t.format();const s=i.arrayFrom(e).map((e=>`- ${e}`)).join("\n");m.info(`${this.name} service created successfully! The following files were created:\n\n${s}`)}async createService(e){await m.animate("Creating service",(async()=>{p.exists(`src/services/${this.name}.ts`)&&m.fail(`${this.name} service already exists!`);g.instantiate(v("service"),"src/services",{service:{name:this.name}}).forEach((t=>e.add(t)))}))}async registerService(e){await m.animate("Registering service",(async()=>{p.exists("src/services/index.ts")||await this.createServicesIndex(e);const t=e.requireSourceFile("src/services/index.ts"),s=this.getServicesObject(t);if(!s)return m.fail("Could not find services object in services config, please add it manually.");t.addImportDeclaration({defaultImport:this.name,moduleSpecifier:`./${this.name}`}),s.addPropertyAssignment({name:`$${i.stringToCamelCase(this.name)}`,initializer:this.name}),await e.save(t)}))}async createServicesIndex(e){p.write("src/services/index.ts",D("\n export const services = {};\n\n export type AppServices = typeof services;\n\n declare module '@vue/runtime-core' {\n interface ComponentCustomProperties extends AppServices {}\n }\n ")),e.addSourceFile("src/services/index.ts");const t=e.requireSourceFile("src/main.ts"),i=this.getBootstrapOptions(t);if(!i)return m.fail("Could not find options object in bootstrap config, please add the services manually.");i.insertShorthandPropertyAssignment(0,{name:"services"}),t.addImportDeclaration({namedImports:["services"],moduleSpecifier:"./services"}),await e.save(t)}getBootstrapOptions(e){const t=A(e,{guard:l.Node.isCallExpression,validate:e=>"bootstrapApplication"===e.getExpression().getText(),skip:l.SyntaxKind.ImportDeclaration}),i=t?.getArguments()[1];return l.Node.isObjectLiteralExpression(i)?i:null}getServicesObject(e){const t=A(e,{guard:l.Node.isVariableDeclaration,validate:e=>"services"===e.getName()}),i=t?.getInitializer();return l.Node.isObjectLiteralExpression(i)?i:null}}u.default(P,"command","generate:service"),u.default(P,"description","Generate an AerogelJS Service"),u.default(P,"parameters",[["name","Service name"]]);class b{constructor(e){u.default(this,"name",void 0),this.name=e}async install(){this.assertNotInstalled(),await this.installDependencies();{const e=k().edit();await this.updateFiles(e),await e.format()}m.info(`Plugin ${this.name} installed!`)}assertNotInstalled(){p.contains("package.json",`"${this.getNpmPackageName()}"`)&&m.fail(`${this.name} is already installed!`)}async installDependencies(){await m.animate("Installing plugin dependencies",(async()=>{await this.installNpmDependencies()}))}async updateFiles(e){await this.updateBootstrapConfig(e)}async installNpmDependencies(){if(C())await w.run(`npm install file:${y(this.getLocalPackageName())}`);else if(p.contains("package.json","file")){const e=h(this.getLocalPackageName())??f(this.getLocalPackageName());await w.run(`npm install file:${e}`)}else await w.run(`npm install ${this.getNpmPackageName()}@next`)}async updateBootstrapConfig(e){await m.animate("Injecting plugin in bootstrap configuration",(async()=>{const t=e.requireSourceFile("src/main.ts"),i=this.getBootstrapPluginsDeclaration(t);if(!i)return m.fail(`\n Could not find plugins array in bootstrap config, please add the following manually:\n\n ${this.getBootstrapConfig()}\n `);t.addImportDeclaration(this.getBootstrapImport()),i.addElement(this.getBootstrapConfig()),await e.save(t)}))}getBootstrapPluginsDeclaration(e){const t=A(e,{guard:l.Node.isCallExpression,validate:e=>"bootstrapApplication"===e.getExpression().getText(),skip:l.SyntaxKind.ImportDeclaration}),i=t?.getArguments()[1],s=F(i,l.Node.isObjectLiteralExpression)?.getProperty("plugins"),n=F(s,l.Node.isPropertyAssignment)?.getInitializer();return l.Node.isArrayLiteralExpression(n)?n:null}getBootstrapImport(){return{defaultImport:this.name,moduleSpecifier:`@aerogel/plugin-${this.name}`}}getNpmPackageName(){return`@aerogel/${this.getLocalPackageName()}`}getLocalPackageName(){return`plugin-${this.name}`}getBootstrapConfig(){return`${this.name}()`}}const N=[new class extends b{constructor(){super("soukai")}async installNpmDependencies(){await w.run("npm install soukai@next"),await super.installNpmDependencies()}getBootstrapConfig(){return"soukai({ models: import.meta.glob('@/models/*', { eager: true }) })"}},new class extends b{constructor(){super("solid")}async updateFiles(e){await this.updateTailwindConfig(e),await super.updateFiles(e)}async installNpmDependencies(){await w.run("npm install soukai-solid@next"),await super.installNpmDependencies()}async updateTailwindConfig(e){await m.animate("Updating tailwind configuration",(async()=>{const t=e.requireSourceFile("tailwind.config.js"),i=this.getTailwindContentArray(t),s=C()?`'${y("plugin-solid")}/dist/**/*.js'`:"'./node_modules/@aerogel/plugin-solid/dist/**/*.js'";if(!i)return m.fail(`\n Could not find content array in tailwind config, please add the following manually:\n\n ${s}\n `);i.addElement(s),await e.save(t)}))}getTailwindContentArray(e){const t=A(e,{guard:l.Node.isPropertyAssignment,validate:e=>"content"===e.getName(),skip:l.SyntaxKind.JSDoc}),i=t?.getInitializer();return l.Node.isArrayLiteralExpression(i)?i:null}}].reduce(((e,t)=>Object.assign(e,{[t.name]:t})),{});class O extends S{constructor(e){super(),u.default(this,"plugin",void 0),this.plugin=N[e]??m.fail(`Plugin '${e}' doesn't exist. Available plugins: ${Object.keys(N).join(", ")}`)}async run(){await this.plugin.install()}}u.default(O,"command","install"),u.default(O,"description","Install an AerogelJS plugin"),u.default(O,"parameters",[["plugin","Plugin to install"]]);var E=i.facade(new class{run(t){const i=new e.Command;i.name("ag").description("AerogelJS CLI").version("0.0.0"),$.define(i),q.define(i),I.define(i),P.define(i),O.define(i),i.parse(t)}});exports.CLI=E;
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("commander"),t=require("@babel/runtime/helpers/defineProperty"),s=require("path"),i=require("@noeldemartin/utils");require("core-js/modules/esnext.async-iterator.reduce.js"),require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.reduce.js");var n=require("fs");require("core-js/modules/esnext.async-iterator.for-each.js"),require("core-js/modules/esnext.iterator.for-each.js"),require("core-js/modules/esnext.async-iterator.find.js"),require("core-js/modules/esnext.iterator.find.js"),require("core-js/modules/esnext.async-iterator.map.js"),require("core-js/modules/esnext.iterator.map.js");var a=require("chalk"),r=require("readline"),o=require("mustache");require("core-js/modules/esnext.set.add-all.js"),require("core-js/modules/esnext.set.delete-all.js"),require("core-js/modules/esnext.set.difference.js"),require("core-js/modules/esnext.set.every.js"),require("core-js/modules/esnext.set.filter.js"),require("core-js/modules/esnext.set.find.js"),require("core-js/modules/esnext.set.intersection.js"),require("core-js/modules/esnext.set.is-disjoint-from.js"),require("core-js/modules/esnext.set.is-subset-of.js"),require("core-js/modules/esnext.set.is-superset-of.js"),require("core-js/modules/esnext.set.join.js"),require("core-js/modules/esnext.set.map.js"),require("core-js/modules/esnext.set.reduce.js"),require("core-js/modules/esnext.set.some.js"),require("core-js/modules/esnext.set.symmetric-difference.js"),require("core-js/modules/esnext.set.union.js");var l=require("ts-morph"),c=require("child_process");function d(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}require("core-js/modules/esnext.async-iterator.some.js"),require("core-js/modules/esnext.iterator.some.js");var p=d(t);var u=i.facade(new class{contains(e,t){return!!this.read(e)?.includes(t)}exists(e){return n.existsSync(e)}isSymlink(e){return n.lstatSync(e).isSymbolicLink()}read(e){return this.isFile(e)?n.readFileSync(e).toString():null}getFiles(e){const t=n.readdirSync(e,{withFileTypes:!0}),i=[];for(const n of t){const t=s.resolve(e,n.name);n.isDirectory()?i.push(...this.getFiles(t)):i.push(t)}return i}isDirectory(e){return this.exists(e)&&n.lstatSync(e).isDirectory()}isFile(e){return this.exists(e)&&n.lstatSync(e).isFile()}isEmptyDirectory(e){return!!this.isDirectory(e)&&0===this.getFiles(e).length}makeDirectory(e){n.mkdirSync(e,{recursive:!0})}write(e,t){n.existsSync(s.dirname(e))||n.mkdirSync(s.dirname(e),{recursive:!0}),n.writeFileSync(e,t)}});var m=i.facade(new class{constructor(){p.default(this,"renderInfo",a.hex("#00ffff")),p.default(this,"renderSuccess",a.hex("#00ff00")),p.default(this,"renderError",a.hex("#ff0000"))}async animate(e,t){var s=this;const i=function(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",i=arguments.length>1&&void 0!==arguments[1]&&arguments[1];const a=s.renderInfo(s.renderMarkdown(e)+(i?"...":".".repeat(n%4)))+t;s.stdout(a)};let n=0;i();const a=setInterval((()=>(n++,i())),1e3),r=await t();return clearInterval(a),i("\n",!0),r}info(e){this.log(this.renderMarkdown(e),this.renderInfo)}error(e){this.log(this.renderMarkdown(e),this.renderError)}fail(e){this.error(e),process.exit(1)}success(e){this.log(this.renderMarkdown(e),this.renderSuccess)}renderMarkdown(e){const t=i.stringMatchAll(e,/\*\*(.*)\*\*/g);for(const s of t)e=e.replace(s[0],a.bold(s[1]));return e}log(e,t){this.formatMessage(e).forEach((e=>{this.logLine(t?t(e):e)}))}formatMessage(e){if("\n"===e[0]){const t=(e=e.slice(1).trimEnd()).split("\n"),s=e.trim()[0]??"",i=t.find((e=>e.trim().length>0))?.indexOf(s)??0;return t.map((e=>e.slice(i)))}return[e]}logLine(e){console.log(e)}stdout(e){r.cursorTo(process.stdout,0),r.clearLine(process.stdout,0),process.stdout.write(e)}});class g{static instantiate(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"./",s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return new g(e).instantiate(t,s)}constructor(e){p.default(this,"path",void 0),this.path=e}instantiate(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const s=this.getFilenameReplacements(t),i=[];e=`${e}/`.replace(/\/\//,"/");for(const a of u.getFiles(this.path)){const r=Object.entries(s).reduce(((e,t)=>{let[s,i]=t;return e.replaceAll(s,i)}),a.substring(this.path.length+1)),l=n.readFileSync(a).toString(),c=e+(r.endsWith(".template")?r.slice(0,-9):r);u.write(c,o.render(l,t,void 0,["<%","%>"])),i.push(c)}return i}getFilenameReplacements(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return Object.entries(e).reduce(((e,s)=>{let[n,a]=s;return"object"==typeof a?Object.assign(e,this.getFilenameReplacements(a,`${n}.`)):e[`[${t}${n}]`]=i.toString(a),e}),{})}}function h(e){return m.fail(`Could not find ${e} pack file, did you run 'npm pack'?`)}function f(e){return u.getFiles(y(e)).find((e=>e.endsWith(".tgz")))??null}function y(e){return function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";if(u.contains(s.resolve(__dirname,"../../../package.json"),'"name": "aerogel"'))return s.resolve(__dirname,"../",e);const t=u.read(s.resolve(__dirname,"../../../../package.json")),n=i.stringMatch(t??"",/"@aerogel\/core": "file:(.*)\/aerogel-core-[\d.]*\.tgz"/),a=n?.[1]??m.fail("Could not determine base path");return s.resolve(a,e)}(`../${e}`)}function v(e){return s.resolve(__dirname,`../templates/${e}`)}var w=i.facade(new class{constructor(){p.default(this,"cwd",null)}setWorkingDirectory(e){this.cwd=e}async run(e){await new Promise(((t,s)=>{c.exec(e,{cwd:this.cwd??void 0},(e=>{e?s(e):t()}))}))}});class j{constructor(){p.default(this,"project",void 0),p.default(this,"modifiedFiles",void 0),this.project=new l.Project({tsConfigFilePath:"tsconfig.json"}),this.modifiedFiles=new Set,this.project.addSourceFilesAtPaths("src/**/*.ts"),this.project.addSourceFilesAtPaths("tailwind.config.js"),this.project.addSourceFilesAtPaths("vite.config.ts"),this.project.addSourceFilesAtPaths("package.json")}addSourceFile(e){this.project.addSourceFilesAtPaths(e)}requireSourceFile(e){return this.project.getSourceFileOrThrow(e)}async format(){await m.animate("Formatting modified files",(async()=>{const e=u.exists("prettier.config.js")||u.contains("package.json",'"prettier": {'),t=u.exists(".eslintrc.js")||u.contains("package.json",'"eslintConfig"'),s=u.contains("package.json",'"prettier-eslint-cli"')?e=>w.run(`npx prettier-eslint ${e} --write`):async s=>{e&&await w.run(`npx prettier ${s} --write`),s.match(/\.(ts|js|vue)$/)&&t&&await w.run(`npx eslint ${s} --fix`)};await Promise.all(i.arrayFrom(this.modifiedFiles).map((async e=>s(e))))}))}async save(e){await e.save(),this.addModifiedFile(e.getFilePath())}addModifiedFile(e){this.modifiedFiles.add(e)}}class x{constructor(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};p.default(this,"name",void 0),p.default(this,"options",void 0),this.name=e,this.options=t}create(e){!u.exists(e)||u.isDirectory(e)&&u.isEmptyDirectory(e)||m.fail(`Folder at '${e}' already exists!`),g.instantiate(v("app"),e,{app:{name:this.name,slug:i.stringToSlug(this.name)},dependencies:this.getDependencies(),contentPath:this.options.linkedLocal?`${y("core")}/dist/**/*.js`:"./node_modules/@aerogel/core/dist/**/*.js"})}edit(){return new j}getDependencies(){const e=e=>Object.entries(e).reduce(((e,t)=>{let[s,i]=t;return Object.assign(e,{[s]:`file:${i}`})}),{});return this.options.linkedLocal?e({aerogelCli:y("cli"),aerogelCore:y("core"),aerogelCypress:y("cypress"),aerogelPluginI18n:y("plugin-i18n"),aerogelPluginSoukai:y("plugin-soukai"),aerogelVite:y("vite")}):this.options.local?e({aerogelCli:f("cli")??h("cli"),aerogelCore:f("core")??h("core"),aerogelCypress:f("cypress")??h("cypress"),aerogelPluginI18n:f("plugin-i18n")??h("plugin-i18n"),aerogelPluginSoukai:f("plugin-soukai")??h("plugin-soukai"),aerogelVite:f("vite")??h("vite")}):{aerogelCli:"next",aerogelCore:"next",aerogelCypress:"next",aerogelPluginI18n:"next",aerogelPluginSoukai:"next",aerogelVite:"next"}}}class k{static define(e){var t=this;e=e.command(this.command).description(this.description);for(const[t,s]of this.parameters)e=e.argument(`<${t}>`,s);for(const[t,s]of Object.entries(this.options)){const i="string"==typeof s?s:s.description,n="string"==typeof s?"string":s.type??"string";e=e.option("boolean"===n?`--${t}`:`--${t} <${n}>`,i)}e=e.action((function(){for(var e=arguments.length,s=new Array(e),i=0;i<e;i++)s[i]=arguments[i];return t.run.call(t,...s)}))}static async run(){for(var e=arguments.length,t=new Array(e),s=0;s<e;s++)t[s]=arguments[s];const i=new this(...t);await i.validate(),await i.run()}async validate(){}async run(){}assertAerogelOrDirectory(e){const t=u.read("package.json");if(t?.includes("@aerogel/core"))return;if(e&&u.isDirectory(e))return;const s=e?`${e} folder does not exist.`:"package.json does not contain @aerogel/core.";m.fail(`${s} Are you sure this is an Aerogel app?`)}}p.default(k,"command",""),p.default(k,"description",""),p.default(k,"parameters",[]),p.default(k,"options",{});class S extends k{constructor(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(),p.default(this,"path",void 0),p.default(this,"options",void 0),this.path=e,this.options=t}async run(){const e=this.path,t=this.options.name??i.stringToTitleCase(s.basename(e));w.setWorkingDirectory(e),await this.createApp(t,e),await this.installDependencies(),await this.initializeGit(),m.success(`\n\n That's it! You can start working on **${t}** doing the following:\n\n cd ${e}\n npm run dev\n\n Have fun!\n `)}async createApp(e,t){m.info(`Creating **${e}**...`),new x(e,{local:this.options.local,linkedLocal:this.options.local&&!this.options.copy}).create(t)}async installDependencies(){await m.animate("Installing dependencies",(async()=>{await w.run("npm install")}))}async initializeGit(){await m.animate("Initializing git",(async()=>{await w.run("git init"),await w.run("git add ."),await w.run('git commit -m "Start"')}))}}function C(){return new x("")}function $(){return u.isSymlink("node_modules/@aerogel/core")}function F(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!e)return;const s=t.guard??(()=>!0),n=t.validate??(()=>!0),a=i.arrayFrom(t.skip??[]);return e.forEachDescendant(((e,t)=>{if(s(e)&&n(e))return e;const i=e.getKind();a.includes(i)&&t.skip()}))}function P(e,t){if(e&&t(e))return e}p.default(S,"command","create"),p.default(S,"description","Create AerogelJS app"),p.default(S,"parameters",[["path","Application path"]]),p.default(S,"options",{name:"Application name",local:{type:"boolean",description:"Whether to create an app using local Aerogel packages (used for core development)"},copy:{type:"boolean",description:"Whether to create an app linked to local Aerogel packages (used in CI)"}});class b extends k{constructor(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(),p.default(this,"path",void 0),p.default(this,"options",void 0),this.path=e,this.options=t}async validate(){this.options.button&&this.options.input&&m.fail("Cannot use both 'button' and 'input' flags!")}async run(){this.assertAerogelOrDirectory("src/components"),this.assertHistoireInstalled();const e=new Set,[t,s]=this.parsePathComponents();await this.createComponent(t,s,e),await this.createStory(t,s,e),await this.declareComponents();const n=i.arrayFrom(e).map((e=>`- ${e}`)).join("\n");m.info(`${s} component created successfully! The following files were created:\n\n${n}`)}assertHistoireInstalled(){this.options.story&&(u.contains("package.json",'"histoire"')||u.contains("package.json",'"@aerogel/histoire"')||m.fail("\n Histoire is not installed yet! You can install it running:\n npx gel install histoire\n "))}async createComponent(e,t,s){await m.animate("Creating component",(async()=>{u.exists(`src/components/${this.path}.vue`)&&m.fail(`${this.path} component already exists!`);const n=this.options.input?"component-input":this.options.button?"component-button":"component";g.instantiate(v(n),`src/components/${e}`,{component:{name:t,slug:i.stringToSlug(t)}}).forEach((e=>s.add(e)))}))}async createStory(e,t,s){this.options.story&&await m.animate("Creating story",(async()=>{const n=this.options.input?"component-input-story":this.options.button?"component-button-story":"component-story";g.instantiate(v(n),`src/components/${e}`,{component:{name:t,slug:i.stringToSlug(t)}}).forEach((e=>s.add(e)))}))}async declareComponents(){const e=C().edit(),t=e.requireSourceFile("vite.config.ts"),s=this.getComponentDirsArray(t);if(!s)return m.fail("Could not find component dirs declaration in vite config!");s.getDescendantsOfKind(l.SyntaxKind.StringLiteral).some((e=>"'src/components'"===e.getText()))||(await m.animate("Updating vite config",(async()=>{s.addElement("'src/components'"),await e.save(t)})),await e.format())}getComponentDirsArray(e){const t=F(e,{guard:l.Node.isCallExpression,validate:e=>e.getText().startsWith("Components("),skip:l.SyntaxKind.ImportDeclaration});if(!t)return null;const s=F(t,{guard:l.Node.isPropertyAssignment,validate:e=>"dirs"===e.getName()}),i=s?.getInitializer();return l.Node.isArrayLiteralExpression(i)?i:this.declareComponentDirsArray(t)}declareComponentDirsArray(e){const t=F(e,{guard:l.Node.isObjectLiteralExpression}),s=t?.addPropertyAssignment({name:"dirs",initializer:"[]"});return s?.getInitializer()??null}parsePathComponents(){const e=this.path.lastIndexOf("/");return-1===e?["",this.path]:[this.path.substring(0,e),this.path.substring(e+1)]}}p.default(b,"command","generate:component"),p.default(b,"description","Generate an AerogelJS Component"),p.default(b,"parameters",[["path","Component path (relative to components folder; extension not necessary)"]]),p.default(b,"options",{button:{description:"Create a custom button",type:"boolean"},input:{description:"Create a custom input",type:"boolean"},story:{description:"Create component story using Histoire",type:"boolean"}});class D extends k{constructor(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(),p.default(this,"name",void 0),p.default(this,"options",void 0),this.name=e,this.options=t}async run(){this.assertAerogelOrDirectory("src/models"),u.exists(`src/models/${this.name}.ts`)&&m.fail(`${this.name} model already exists!`),this.assertSoukaiInstalled();const e=await m.animate("Creating model",(async()=>g.instantiate(v("model"),"src/models",{model:{name:this.name,fieldsDefinition:this.getFieldsDefinition()},soukaiImports:this.options.fields?"FieldType, defineModelSchema":"defineModelSchema"}).map((e=>`- ${e}`)).join("\n")));m.info(`${this.name} model created successfully! The following files were created:\n\n${e}`)}getFieldsDefinition(){if(!this.options.fields)return" //";const e=this.options.fields.split(",").map((e=>{const[t,s,n]=e.split(":");return{name:t,type:i.stringToStudlyCase(s??"string"),required:"required"===n}})).reduce(((e,t)=>e+`\n${t.required?i.formatCodeBlock(`\n ${t.name}: {\n type: FieldType.${t.type},\n required: true,\n }\n `):`${t.name}: FieldType.${t.type}`},`),"");return i.formatCodeBlock(e,{indent:8})}assertSoukaiInstalled(){u.contains("package.json",'"soukai"')||u.contains("package.json",'"@aerogel/plugin-soukai"')||m.fail("\n Soukai is not installed yet! You can install it running:\n npx gel install soukai\n ")}}p.default(D,"command","generate:model"),p.default(D,"description","Generate an AerogelJS Model"),p.default(D,"parameters",[["name","Model name"]]),p.default(D,"options",{fields:"Create model with the given fields"});class I extends k{constructor(e){super(),p.default(this,"name",void 0),this.name=e}async run(){this.assertAerogelOrDirectory("src/services");const e=new Set,t=C().edit();await this.createService(e),await this.registerService(t),await t.format();const s=i.arrayFrom(e).map((e=>`- ${e}`)).join("\n");m.info(`${this.name} service created successfully! The following files were created:\n\n${s}`)}async createService(e){await m.animate("Creating service",(async()=>{u.exists(`src/services/${this.name}.ts`)&&m.fail(`${this.name} service already exists!`);g.instantiate(v("service"),"src/services",{service:{name:this.name}}).forEach((t=>e.add(t)))}))}async registerService(e){await m.animate("Registering service",(async()=>{u.exists("src/services/index.ts")||await this.createServicesIndex(e);const t=e.requireSourceFile("src/services/index.ts"),s=this.getServicesObject(t);if(!s)return m.fail("Could not find services object in services config, please add it manually.");t.addImportDeclaration({defaultImport:this.name,moduleSpecifier:`./${this.name}`}),s.addPropertyAssignment({name:`$${i.stringToCamelCase(this.name)}`,initializer:this.name}),await e.save(t)}))}async createServicesIndex(e){u.write("src/services/index.ts",i.formatCodeBlock("\n export const services = {};\n\n export type AppServices = typeof services;\n\n declare module '@vue/runtime-core' {\n interface ComponentCustomProperties extends AppServices {}\n }\n ")),e.addSourceFile("src/services/index.ts");const t=e.requireSourceFile("src/main.ts"),s=this.getBootstrapOptions(t);if(!s)return m.fail("Could not find options object in bootstrap config, please add the services manually.");s.insertShorthandPropertyAssignment(0,{name:"services"}),t.addImportDeclaration({namedImports:["services"],moduleSpecifier:"./services"}),await e.save(t)}getBootstrapOptions(e){const t=F(e,{guard:l.Node.isCallExpression,validate:e=>"bootstrapApplication"===e.getExpression().getText(),skip:l.SyntaxKind.ImportDeclaration}),s=t?.getArguments()[1];return l.Node.isObjectLiteralExpression(s)?s:null}getServicesObject(e){const t=F(e,{guard:l.Node.isVariableDeclaration,validate:e=>"services"===e.getName()}),s=t?.getInitializer();return l.Node.isObjectLiteralExpression(s)?s:null}}p.default(I,"command","generate:service"),p.default(I,"description","Generate an AerogelJS Service"),p.default(I,"parameters",[["name","Service name"]]);class A{constructor(e){p.default(this,"name",void 0),this.name=e}async install(){this.assertNotInstalled(),await this.beforeInstall(),await this.installDependencies();{const e=C().edit();await this.updateFiles(e),await e.format()}await this.afterInstall(),m.info(`Plugin ${this.name} installed!`)}assertNotInstalled(){u.contains("package.json",`"${this.getNpmPackageName()}"`)&&m.fail(`${this.name} is already installed!`)}async beforeInstall(){}async afterInstall(){}async installDependencies(){await m.animate("Installing plugin dependencies",(async()=>{await this.installNpmDependencies()}))}async updateFiles(e){this.isForDevelopment()||await this.updateBootstrapConfig(e)}async installNpmDependencies(){const e=this.isForDevelopment()?"--save-dev":"";if($())await w.run(`npm install file:${y(this.getLocalPackageName())} ${e}`);else if(u.contains("package.json",'"@aerogel/core": "file:')){const t=f(this.getLocalPackageName())??h(this.getLocalPackageName());await w.run(`npm install file:${t} ${e}`)}else await w.run(`npm install ${this.getNpmPackageName()}@next --save-exact ${e}`)}async updateBootstrapConfig(e){await m.animate("Injecting plugin in bootstrap configuration",(async()=>{const t=e.requireSourceFile("src/main.ts"),s=this.getBootstrapPluginsDeclaration(t);if(!s)return m.fail(`\n Could not find plugins array in bootstrap config, please add the following manually:\n\n ${this.getBootstrapConfig()}\n `);t.addImportDeclaration(this.getBootstrapImport()),s.addElement(this.getBootstrapConfig()),await e.save(t)}))}async updateTailwindConfig(e,t){await m.animate("Updating tailwind configuration",(async()=>{const s=e.requireSourceFile("tailwind.config.js"),i=this.getTailwindContentArray(s);if(!i)return m.fail(`\n Could not find content array in tailwind config, please add the following manually:\n\n ${t.content}\n `);i.addElement(t.content),await e.save(s)}))}getBootstrapPluginsDeclaration(e){const t=F(e,{guard:l.Node.isCallExpression,validate:e=>"bootstrapApplication"===e.getExpression().getText(),skip:l.SyntaxKind.ImportDeclaration}),s=t?.getArguments()[1],i=P(s,l.Node.isObjectLiteralExpression)?.getProperty("plugins"),n=P(i,l.Node.isPropertyAssignment)?.getInitializer();return l.Node.isArrayLiteralExpression(n)?n:null}getTailwindContentArray(e){const t=F(e,{guard:l.Node.isPropertyAssignment,validate:e=>"content"===e.getName(),skip:l.SyntaxKind.JSDoc}),s=t?.getInitializer();return l.Node.isArrayLiteralExpression(s)?s:null}getBootstrapImport(){return{defaultImport:this.name,moduleSpecifier:`@aerogel/plugin-${this.name}`}}getNpmPackageName(){return`@aerogel/${this.getLocalPackageName()}`}getLocalPackageName(){return`plugin-${this.name}`}isForDevelopment(){return!1}getBootstrapConfig(){return`${this.name}()`}}const q=[new class extends A{constructor(){super("soukai")}async installNpmDependencies(){await w.run("npm install soukai@next --save-exact"),await super.installNpmDependencies()}getBootstrapConfig(){return"soukai({ models: import.meta.glob('@/models/*', { eager: true }) })"}},new class extends A{constructor(){super("solid")}async updateFiles(e){await this.updateTailwindConfig(e,{content:$()?`'${y("plugin-solid")}/dist/**/*.js'`:"'./node_modules/@aerogel/plugin-solid/dist/**/*.js'"}),await this.updateNpmScripts(e),await this.updateGitIgnore(),await super.updateFiles(e)}async installNpmDependencies(){await w.run("npm install soukai-solid@next --save-exact"),await w.run("npm install @solid/community-server@7 --save"),await super.installNpmDependencies()}async updateNpmScripts(e){m.info("Updating npm scripts...");const t=u.read("package.json");if(!t)return m.fail("Could not find package.json file");u.write("package.json",t.replace('"cy:dev": "concurrently --kill-others \\"npm run test:serve-app\\" \\"npm run cy:open\\"",','"cy:dev": "concurrently --kill-others \\"npm run test:serve-app\\" \\"npm run test:serve-pod\\" \\"npm run cy:open\\"",').replace('"cy:test": "start-server-and-test test:serve-app http-get://localhost:5001 cy:run",','"cy:test": "start-server-and-test test:serve-app http-get://localhost:5001 test:serve-pod http-get://localhost:4000 cy:run",').replace('"dev": "vite",','"dev": "vite",\n"dev:serve-pod": "community-solid-server -c @css:config/file.json -p 4000 -f ./solid-data",').replace('"test:serve-app": "vite --port 5001"','"test:serve-app": "vite --port 5001",\n"test:serve-pod": "community-solid-server -p 4000 -l warn"')),e.addModifiedFile("package.json")}async updateGitIgnore(){m.info("Updating .gitignore");const e=u.read(".gitignore")??"";u.write(".gitignore",`${e}/solid-data\n`)}},new class extends A{constructor(){super("histoire"),p.default(this,"installedPatchPackage",!1),p.default(this,"installedPostCSSPseudoClasses",!1)}async beforeInstall(){this.installedPatchPackage=!1,this.installedPostCSSPseudoClasses=!1}async afterInstall(){this.installedPatchPackage&&await m.animate("Patching dependencies",(async()=>{await w.run("npx patch-package")}))}async updateFiles(e){await this.updateTailwindConfig(e,{content:$()?`'${y("histoire")}/dist/**/*.js'`:"'./node_modules/@aerogel/histoire/dist/**/*.js'"}),await this.updateNpmScripts(e),await this.createConfigFiles(),await super.updateFiles(e)}async installNpmDependencies(){await w.run("npm install histoire@0.17.6 --save-dev"),u.contains("package.json",'"patch-package"')||(await w.run("npm install patch-package --save-dev"),this.installedPatchPackage=!0),u.contains("package.json",'"postcss-pseudo-classes"')||(await w.run("npm install postcss-pseudo-classes --save-dev"),this.installedPostCSSPseudoClasses=!0),await super.installNpmDependencies()}getLocalPackageName(){return this.name}async updateNpmScripts(e){m.info("Updating npm scripts...");const t=u.read("package.json");if(!t)return m.fail("Could not find package.json file");u.write("package.json",t.replace('"lint": "noeldemartin-lint src",',this.installedPatchPackage?'"histoire": "histoire dev", "lint": "noeldemartin-lint src", "postinstall": "patch-package",':'"histoire": "histoire dev", "lint": "noeldemartin-lint src",')),e.addModifiedFile("package.json")}async createConfigFiles(){m.info("Creating config files..."),g.instantiate(v("histoire")),this.installedPostCSSPseudoClasses&&g.instantiate(v("postcss-pseudo-classes"))}isForDevelopment(){return!0}}].reduce(((e,t)=>Object.assign(e,{[t.name]:t})),{});class N extends k{constructor(e){super(),p.default(this,"plugin",void 0),this.plugin=q[e]??m.fail(`Plugin '${e}' doesn't exist. Available plugins: ${Object.keys(q).join(", ")}`)}async run(){await this.plugin.install()}}p.default(N,"command","install"),p.default(N,"description","Install an AerogelJS plugin"),p.default(N,"parameters",[["plugin","Plugin to install"]]);var T=i.facade(new class{run(t){const s=new e.Command;s.name("ag").description("AerogelJS CLI").version("0.0.0"),S.define(s),b.define(s),D.define(s),I.define(s),N.define(s),s.parse(t)}});exports.CLI=T;
|
|
2
2
|
//# sourceMappingURL=aerogel-cli.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aerogel-cli.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"aerogel-cli.cjs.js","sources":["../src/lib/File.ts","../src/lib/Log.ts","../src/lib/Template.ts","../src/lib/utils/paths.ts","../src/lib/Shell.ts","../src/lib/Editor.ts","../src/lib/App.ts","../src/commands/Command.ts","../src/commands/create.ts","../src/lib/utils/app.ts","../src/lib/utils/edit.ts","../src/commands/generate-component.ts","../src/commands/generate-model.ts","../src/commands/generate-service.ts","../src/plugins/Plugin.ts","../src/commands/install.ts","../src/plugins/Soukai.ts","../src/plugins/Solid.ts","../src/plugins/Histoire.ts","../src/cli.ts"],"sourcesContent":["import { existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from 'fs';\nimport { facade } from '@noeldemartin/utils';\nimport { dirname, resolve } from 'path';\n\nexport class FileService {\n\n public contains(path: string, contents: string): boolean {\n return !!this.read(path)?.includes(contents);\n }\n\n public exists(path: string): boolean {\n return existsSync(path);\n }\n\n public isSymlink(path: string): boolean {\n const stats = lstatSync(path);\n\n return stats.isSymbolicLink();\n }\n\n public read(path: string): string | null {\n if (!this.isFile(path)) {\n return null;\n }\n\n return readFileSync(path).toString();\n }\n\n public getFiles(directoryPath: string): string[] {\n const children = readdirSync(directoryPath, { withFileTypes: true });\n const files: string[] = [];\n\n for (const child of children) {\n const path = resolve(directoryPath, child.name);\n\n if (child.isDirectory()) {\n files.push(...this.getFiles(path));\n } else {\n files.push(path);\n }\n }\n\n return files;\n }\n\n public isDirectory(path: string): boolean {\n return this.exists(path) && lstatSync(path).isDirectory();\n }\n\n public isFile(path: string): boolean {\n return this.exists(path) && lstatSync(path).isFile();\n }\n\n public isEmptyDirectory(path: string): boolean {\n if (!this.isDirectory(path)) {\n return false;\n }\n\n return this.getFiles(path).length === 0;\n }\n\n public makeDirectory(path: string): void {\n mkdirSync(path, { recursive: true });\n }\n\n public write(path: string, contents: string): void {\n if (!existsSync(dirname(path))) {\n mkdirSync(dirname(path), { recursive: true });\n }\n\n writeFileSync(path, contents);\n }\n\n}\n\nexport default facade(new FileService());\n","import { facade, stringMatchAll } from '@noeldemartin/utils';\nimport { bold, hex } from 'chalk';\nimport { clearLine, cursorTo } from 'readline';\n\nexport class LogService {\n\n protected renderInfo = hex('#00ffff');\n protected renderSuccess = hex('#00ff00');\n protected renderError = hex('#ff0000');\n\n public async animate<T>(message: string, operation: () => Promise<T>): Promise<T> {\n const updateStdout = (end: string = '', done: boolean = false) => {\n const progress =\n this.renderInfo(this.renderMarkdown(message) + (done ? '...' : '.'.repeat(frame % 4))) + end;\n\n this.stdout(progress);\n };\n\n let frame = 0;\n\n updateStdout();\n\n const interval = setInterval(() => (frame++, updateStdout()), 1000);\n const result = await operation();\n\n clearInterval(interval);\n updateStdout('\\n', true);\n\n return result;\n }\n\n public info(message: string): void {\n this.log(this.renderMarkdown(message), this.renderInfo);\n }\n\n public error(message: string): void {\n this.log(this.renderMarkdown(message), this.renderError);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public fail<T = any>(message: string): T {\n this.error(message);\n\n process.exit(1);\n }\n\n public success(message: string): void {\n this.log(this.renderMarkdown(message), this.renderSuccess);\n }\n\n protected renderMarkdown(message: string): string {\n const matches = stringMatchAll<2>(message, /\\*\\*(.*)\\*\\*/g);\n\n for (const match of matches) {\n message = message.replace(match[0], bold(match[1]));\n }\n\n return message;\n }\n\n protected log(message: string, formatMessage?: (message: string) => string): void {\n this.formatMessage(message).forEach((line) => {\n this.logLine(formatMessage ? formatMessage(line) : line);\n });\n }\n\n protected formatMessage(message: string): string[] {\n if (message[0] === '\\n') {\n message = message.slice(1).trimEnd();\n\n const lines = message.split('\\n');\n const firstLetter = message.trim()[0] ?? '';\n const indentation = lines.find((line) => line.trim().length > 0)?.indexOf(firstLetter) ?? 0;\n\n return lines.map((line) => line.slice(indentation));\n }\n\n return [message];\n }\n\n protected logLine(line: string): void {\n // eslint-disable-next-line no-console\n console.log(line);\n }\n\n protected stdout(message: string): void {\n cursorTo(process.stdout, 0);\n clearLine(process.stdout, 0);\n\n process.stdout.write(message);\n }\n\n}\n\nexport default facade(new LogService());\n","import { readFileSync } from 'fs';\nimport { render } from 'mustache';\nimport { toString } from '@noeldemartin/utils';\n\nimport File from '@/lib/File';\n\nexport default class Template {\n\n public static instantiate(\n path: string,\n destination: string = './',\n replacements: Record<string, unknown> = {},\n ): string[] {\n const template = new Template(path);\n\n return template.instantiate(destination, replacements);\n }\n\n constructor(public path: string) {}\n\n public instantiate(destination: string, replacements: Record<string, unknown> = {}): string[] {\n const filenameReplacements = this.getFilenameReplacements(replacements);\n const files: string[] = [];\n destination = `${destination}/`.replace(/\\/\\//, '/');\n\n for (const file of File.getFiles(this.path)) {\n const relativePath = Object.entries(filenameReplacements).reduce(\n (path, [match, replacement]) => path.replaceAll(match, replacement),\n file.substring(this.path.length + 1),\n );\n const fileContents = readFileSync(file).toString();\n const filePath =\n destination + (relativePath.endsWith('.template') ? relativePath.slice(0, -9) : relativePath);\n\n File.write(filePath, render(fileContents, replacements, undefined, ['<%', '%>']));\n files.push(filePath);\n }\n\n return files;\n }\n\n protected getFilenameReplacements(\n replacements: Record<string, unknown>,\n prefix: string = '',\n ): Record<string, string> {\n return Object.entries(replacements).reduce((filenameReplacements, [key, value]) => {\n if (typeof value === 'object') {\n Object.assign(\n filenameReplacements,\n this.getFilenameReplacements(value as Record<string, unknown>, `${key}.`),\n );\n } else {\n filenameReplacements[`[${prefix}${key}]`] = toString(value);\n }\n\n return filenameReplacements;\n }, {} as Record<string, string>);\n }\n\n}\n","import { resolve } from 'path';\nimport { stringMatch } from '@noeldemartin/utils';\n\nimport File from '@/lib/File';\nimport Log from '@/lib/Log';\n\nexport function basePath(path: string = ''): string {\n if (File.contains(resolve(__dirname, '../../../package.json'), '\"name\": \"aerogel\"')) {\n return resolve(__dirname, '../', path);\n }\n\n const packageJson = File.read(resolve(__dirname, '../../../../package.json'));\n const matches = stringMatch<2>(packageJson ?? '', /\"@aerogel\\/core\": \"file:(.*)\\/aerogel-core-[\\d.]*\\.tgz\"/);\n const cliPath = matches?.[1] ?? Log.fail<string>('Could not determine base path');\n\n return resolve(cliPath, path);\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function packNotFound(packageName: string): any {\n return Log.fail(`Could not find ${packageName} pack file, did you run 'npm pack'?`);\n}\n\nexport function packagePackPath(packageName: string): string | null {\n return File.getFiles(packagePath(packageName)).find((file) => file.endsWith('.tgz')) ?? null;\n}\n\nexport function packagePath(packageName: string): string {\n return basePath(`../${packageName}`);\n}\n\nexport function templatePath(name: string): string {\n return resolve(__dirname, `../templates/${name}`);\n}\n","import { exec } from 'child_process';\nimport { facade } from '@noeldemartin/utils';\n\nexport class ShellService {\n\n private cwd: string | null = null;\n\n public setWorkingDirectory(cwd: string): void {\n this.cwd = cwd;\n }\n\n public async run(command: string): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n exec(command, { cwd: this.cwd ?? undefined }, (error) => {\n if (error) {\n reject(error);\n\n return;\n }\n\n resolve();\n });\n });\n }\n\n}\n\nexport default facade(new ShellService());\n","import { arrayFrom } from '@noeldemartin/utils';\nimport { Project } from 'ts-morph';\nimport type { SourceFile } from 'ts-morph';\n\nimport File from '@/lib/File';\nimport Log from '@/lib/Log';\nimport Shell from '@/lib/Shell';\n\nexport class Editor {\n\n private project: Project;\n private modifiedFiles: Set<string>;\n\n constructor() {\n this.project = new Project({ tsConfigFilePath: 'tsconfig.json' });\n this.modifiedFiles = new Set();\n\n this.project.addSourceFilesAtPaths('src/**/*.ts');\n this.project.addSourceFilesAtPaths('tailwind.config.js');\n this.project.addSourceFilesAtPaths('vite.config.ts');\n this.project.addSourceFilesAtPaths('package.json');\n }\n\n public addSourceFile(path: string): void {\n this.project.addSourceFilesAtPaths(path);\n }\n\n public requireSourceFile(path: string): SourceFile {\n return this.project.getSourceFileOrThrow(path);\n }\n\n public async format(): Promise<void> {\n await Log.animate('Formatting modified files', async () => {\n const usingPrettier = File.exists('prettier.config.js') || File.contains('package.json', '\"prettier\": {');\n const usingESLint = File.exists('.eslintrc.js') || File.contains('package.json', '\"eslintConfig\"');\n const usingPrettierESLint = File.contains('package.json', '\"prettier-eslint-cli\"');\n const formatFile = usingPrettierESLint\n ? (file: string) => Shell.run(`npx prettier-eslint ${file} --write`)\n : async (file: string) => {\n usingPrettier && (await Shell.run(`npx prettier ${file} --write`));\n file.match(/\\.(ts|js|vue)$/) && usingESLint && (await Shell.run(`npx eslint ${file} --fix`));\n };\n\n await Promise.all(arrayFrom(this.modifiedFiles).map(async (file) => formatFile(file)));\n });\n }\n\n public async save(file: SourceFile): Promise<void> {\n await file.save();\n\n this.addModifiedFile(file.getFilePath());\n }\n\n public addModifiedFile(path: string): void {\n this.modifiedFiles.add(path);\n }\n\n}\n","import { stringToSlug } from '@noeldemartin/utils';\n\nimport File from '@/lib/File';\nimport Log from '@/lib/Log';\nimport Template from '@/lib/Template';\nimport { packNotFound, packagePackPath, packagePath, templatePath } from '@/lib/utils/paths';\nimport { Editor } from '@/lib/Editor';\n\ninterface Dependencies {\n aerogelCli: string;\n aerogelCore: string;\n aerogelCypress: string;\n aerogelPluginI18n: string;\n aerogelPluginSoukai: string;\n aerogelVite: string;\n}\n\nexport interface Options {\n local?: boolean;\n linkedLocal?: boolean;\n}\n\nexport default class App {\n\n constructor(protected name: string, protected options: Options = {}) {}\n\n public create(path: string): void {\n if (File.exists(path) && (!File.isDirectory(path) || !File.isEmptyDirectory(path))) {\n Log.fail(`Folder at '${path}' already exists!`);\n }\n\n Template.instantiate(templatePath('app'), path, {\n app: {\n name: this.name,\n slug: stringToSlug(this.name),\n },\n dependencies: this.getDependencies(),\n contentPath: this.options.linkedLocal\n ? `${packagePath('core')}/dist/**/*.js`\n : './node_modules/@aerogel/core/dist/**/*.js',\n });\n }\n\n public edit(): Editor {\n return new Editor();\n }\n\n protected getDependencies(): Dependencies {\n const withFilePrefix = <T extends Record<string, string>>(paths: T) =>\n Object.entries(paths).reduce(\n (pathsWithFile, [name, path]) => Object.assign(pathsWithFile, { [name]: `file:${path}` }) as T,\n {} as T,\n );\n\n if (this.options.linkedLocal) {\n return withFilePrefix({\n aerogelCli: packagePath('cli'),\n aerogelCore: packagePath('core'),\n aerogelCypress: packagePath('cypress'),\n aerogelPluginI18n: packagePath('plugin-i18n'),\n aerogelPluginSoukai: packagePath('plugin-soukai'),\n aerogelVite: packagePath('vite'),\n });\n }\n\n if (this.options.local) {\n return withFilePrefix({\n aerogelCli: packagePackPath('cli') ?? packNotFound('cli'),\n aerogelCore: packagePackPath('core') ?? packNotFound('core'),\n aerogelCypress: packagePackPath('cypress') ?? packNotFound('cypress'),\n aerogelPluginI18n: packagePackPath('plugin-i18n') ?? packNotFound('plugin-i18n'),\n aerogelPluginSoukai: packagePackPath('plugin-soukai') ?? packNotFound('plugin-soukai'),\n aerogelVite: packagePackPath('vite') ?? packNotFound('vite'),\n });\n }\n\n return {\n aerogelCli: 'next',\n aerogelCore: 'next',\n aerogelCypress: 'next',\n aerogelPluginI18n: 'next',\n aerogelPluginSoukai: 'next',\n aerogelVite: 'next',\n };\n }\n\n}\n","import File from '@/lib/File';\nimport Log from '@/lib/Log';\nimport type { Constructor } from '@noeldemartin/utils';\nimport type { Command as CommanderCommand } from 'commander';\n\nexport type CommandConstructor<T extends Command = Command> = Constructor<T>;\nexport type CommandOptions = Record<string, string | { description: string; type?: string }>;\n\nexport default class Command {\n\n protected static command: string = '';\n protected static description: string = '';\n protected static parameters: [string, string][] = [];\n protected static options: CommandOptions = {};\n\n public static define(program: CommanderCommand): void {\n program = program.command(this.command).description(this.description);\n\n for (const [name, description] of this.parameters) {\n program = program.argument(`<${name}>`, description);\n }\n\n for (const [name, definition] of Object.entries(this.options)) {\n const description = typeof definition === 'string' ? definition : definition.description;\n const type = typeof definition === 'string' ? 'string' : definition.type ?? 'string';\n\n program = program.option(type === 'boolean' ? `--${name}` : `--${name} <${type}>`, description);\n }\n\n program = program.action((...args) => this.run.call(this, ...args));\n }\n\n protected static async run<T extends CommandConstructor>(\n this: T,\n ...args: ConstructorParameters<T>\n ): Promise<void> {\n const instance = new this(...args);\n\n await instance.validate();\n await instance.run();\n }\n\n protected async validate(): Promise<void> {\n // Placeholder for overrides, don't place any functionality here.\n }\n\n protected async run(): Promise<void> {\n // Placeholder for overrides, don't place any functionality here.\n }\n\n protected assertAerogelOrDirectory(path?: string): void {\n const packageJson = File.read('package.json');\n\n if (packageJson?.includes('@aerogel/core')) {\n return;\n }\n\n if (path && File.isDirectory(path)) {\n return;\n }\n\n const message = path ? `${path} folder does not exist.` : 'package.json does not contain @aerogel/core.';\n\n Log.fail(`${message} Are you sure this is an Aerogel app?`);\n }\n\n}\n","import { basename } from 'path';\nimport { stringToTitleCase } from '@noeldemartin/utils';\n\nimport App from '@/lib/App';\nimport Command from '@/commands/Command';\nimport Log from '@/lib/Log';\nimport Shell from '@/lib/Shell';\nimport type { CommandOptions } from '@/commands/Command';\n\nexport interface Options {\n name?: string;\n local?: boolean;\n copy?: boolean;\n}\n\nexport class CreateCommand extends Command {\n\n protected static command: string = 'create';\n protected static description: string = 'Create AerogelJS app';\n protected static parameters: [string, string][] = [['path', 'Application path']];\n protected static options: CommandOptions = {\n name: 'Application name',\n local: {\n type: 'boolean',\n description: 'Whether to create an app using local Aerogel packages (used for core development)',\n },\n copy: {\n type: 'boolean',\n description: 'Whether to create an app linked to local Aerogel packages (used in CI)',\n },\n };\n\n private path: string;\n private options: Options;\n\n constructor(path: string, options: Options = {}) {\n super();\n\n this.path = path;\n this.options = options;\n }\n\n protected async run(): Promise<void> {\n const path = this.path;\n const name = this.options.name ?? stringToTitleCase(basename(path));\n\n Shell.setWorkingDirectory(path);\n\n await this.createApp(name, path);\n await this.installDependencies();\n await this.initializeGit();\n\n Log.success(`\n\n That's it! You can start working on **${name}** doing the following:\n\n cd ${path}\n npm run dev\n\n Have fun!\n `);\n }\n\n protected async createApp(name: string, path: string): Promise<void> {\n Log.info(`Creating **${name}**...`);\n\n new App(name, {\n local: this.options.local,\n linkedLocal: this.options.local && !this.options.copy,\n }).create(path);\n }\n\n protected async installDependencies(): Promise<void> {\n await Log.animate('Installing dependencies', async () => {\n await Shell.run('npm install');\n });\n }\n\n protected async initializeGit(): Promise<void> {\n await Log.animate('Initializing git', async () => {\n await Shell.run('git init');\n await Shell.run('git add .');\n await Shell.run('git commit -m \"Start\"');\n });\n }\n\n}\n","import App from '@/lib/App';\nimport File from '@/lib/File';\n\nexport function app(): App {\n // TODO parse app name\n return new App('');\n}\n\nexport function isLocalApp(): boolean {\n return File.contains('package.json', '\"@aerogel/core\": \"file:');\n}\n\nexport function isLinkedLocalApp(): boolean {\n return File.isSymlink('node_modules/@aerogel/core');\n}\n","import { arrayFrom } from '@noeldemartin/utils';\nimport type { Node, SyntaxKind } from 'ts-morph';\n\nexport function editFiles(): boolean {\n // TODO mock editor instead of relying on this for unit tests\n return true;\n}\n\nexport function findDescendant<T extends Node>(\n node: Node | undefined,\n options: {\n guard?: (node: Node | undefined) => node is T;\n validate?: (node: T) => boolean;\n skip?: SyntaxKind | SyntaxKind[];\n } = {},\n): T | undefined {\n if (!node) {\n return;\n }\n\n const guard = options.guard ?? (() => true);\n const validate = options.validate ?? (() => true);\n const skipKinds = arrayFrom(options.skip ?? []);\n\n return node.forEachDescendant((descendant, traversal) => {\n if (guard(descendant) && validate(descendant)) {\n return descendant;\n }\n\n const descendantKind = descendant.getKind();\n\n if (skipKinds.includes(descendantKind)) {\n traversal.skip();\n }\n });\n}\n\nexport function when<T extends Node>(node: Node | undefined, assertion: (node: Node) => node is T): T | undefined {\n if (!node || !assertion(node)) {\n return;\n }\n\n return node as T;\n}\n","import { arrayFrom, stringToSlug } from '@noeldemartin/utils';\nimport { Node, SyntaxKind } from 'ts-morph';\nimport type { ArrayLiteralExpression, CallExpression, SourceFile } from 'ts-morph';\n\nimport Command from '@/commands/Command';\nimport File from '@/lib/File';\nimport Log from '@/lib/Log';\nimport Template from '@/lib/Template';\nimport { app } from '@/lib/utils/app';\nimport { editFiles, findDescendant } from '@/lib/utils/edit';\nimport { templatePath } from '@/lib/utils/paths';\nimport type { CommandOptions } from '@/commands/Command';\n\nexport interface Options {\n button?: boolean;\n input?: boolean;\n story?: boolean;\n}\n\nexport class GenerateComponentCommand extends Command {\n\n protected static command: string = 'generate:component';\n protected static description: string = 'Generate an AerogelJS Component';\n protected static parameters: [string, string][] = [\n ['path', 'Component path (relative to components folder; extension not necessary)'],\n ];\n\n protected static options: CommandOptions = {\n button: {\n description: 'Create a custom button',\n type: 'boolean',\n },\n input: {\n description: 'Create a custom input',\n type: 'boolean',\n },\n story: {\n description: 'Create component story using Histoire',\n type: 'boolean',\n },\n };\n\n private path: string;\n private options: Options;\n\n constructor(path: string, options: Options = {}) {\n super();\n\n this.path = path;\n this.options = options;\n }\n\n protected async validate(): Promise<void> {\n if (this.options.button && this.options.input) {\n Log.fail('Cannot use both \\'button\\' and \\'input\\' flags!');\n }\n }\n\n protected async run(): Promise<void> {\n this.assertAerogelOrDirectory('src/components');\n this.assertHistoireInstalled();\n\n const files = new Set<string>();\n const [directoryName, componentName] = this.parsePathComponents();\n\n await this.createComponent(directoryName, componentName, files);\n await this.createStory(directoryName, componentName, files);\n await this.declareComponents();\n\n const filesList = arrayFrom(files)\n .map((file) => `- ${file}`)\n .join('\\n');\n\n Log.info(`${componentName} component created successfully! The following files were created:\\n\\n${filesList}`);\n }\n\n protected assertHistoireInstalled(): void {\n if (!this.options.story) {\n return;\n }\n\n if (!File.contains('package.json', '\"histoire\"') && !File.contains('package.json', '\"@aerogel/histoire\"')) {\n Log.fail(`\n Histoire is not installed yet! You can install it running:\n npx gel install histoire\n `);\n }\n }\n\n protected async createComponent(directoryName: string, componentName: string, files: Set<string>): Promise<void> {\n await Log.animate('Creating component', async () => {\n if (File.exists(`src/components/${this.path}.vue`)) {\n Log.fail(`${this.path} component already exists!`);\n }\n\n const templateName = this.options.input\n ? 'component-input'\n : this.options.button\n ? 'component-button'\n : 'component';\n const componentFiles = Template.instantiate(templatePath(templateName), `src/components/${directoryName}`, {\n component: {\n name: componentName,\n slug: stringToSlug(componentName),\n },\n });\n\n componentFiles.forEach((file) => files.add(file));\n });\n }\n\n protected async createStory(directoryName: string, componentName: string, files: Set<string>): Promise<void> {\n if (!this.options.story) {\n return;\n }\n\n await Log.animate('Creating story', async () => {\n const templateName = this.options.input\n ? 'component-input-story'\n : this.options.button\n ? 'component-button-story'\n : 'component-story';\n const storyFiles = Template.instantiate(templatePath(templateName), `src/components/${directoryName}`, {\n component: {\n name: componentName,\n slug: stringToSlug(componentName),\n },\n });\n\n storyFiles.forEach((file) => files.add(file));\n });\n }\n\n protected async declareComponents(): Promise<void> {\n if (!editFiles()) {\n return;\n }\n\n const editor = app().edit();\n const viteConfig = editor.requireSourceFile('vite.config.ts');\n const componentDirsArray = this.getComponentDirsArray(viteConfig);\n\n if (!componentDirsArray) {\n return Log.fail('Could not find component dirs declaration in vite config!');\n }\n\n if (\n componentDirsArray\n .getDescendantsOfKind(SyntaxKind.StringLiteral)\n .some((literal) => literal.getText() === '\\'src/components\\'')\n ) {\n return;\n }\n\n await Log.animate('Updating vite config', async () => {\n componentDirsArray.addElement('\\'src/components\\'');\n\n await editor.save(viteConfig);\n });\n\n await editor.format();\n }\n\n protected getComponentDirsArray(viteConfig: SourceFile): ArrayLiteralExpression | null {\n const pluginCall = findDescendant(viteConfig, {\n guard: Node.isCallExpression,\n validate: (callExpression) => callExpression.getText().startsWith('Components('),\n skip: SyntaxKind.ImportDeclaration,\n });\n\n if (!pluginCall) {\n return null;\n }\n\n const dirsAssignment = findDescendant(pluginCall, {\n guard: Node.isPropertyAssignment,\n validate: (propertyAssignment) => propertyAssignment.getName() === 'dirs',\n });\n\n const dirsArray = dirsAssignment?.getInitializer();\n\n if (!Node.isArrayLiteralExpression(dirsArray)) {\n return this.declareComponentDirsArray(pluginCall);\n }\n\n return dirsArray;\n }\n\n protected declareComponentDirsArray(pluginCall: CallExpression): ArrayLiteralExpression | null {\n const pluginOptions = findDescendant(pluginCall, { guard: Node.isObjectLiteralExpression });\n const dirsAssignment = pluginOptions?.addPropertyAssignment({\n name: 'dirs',\n initializer: '[]',\n });\n\n return (dirsAssignment?.getInitializer() as ArrayLiteralExpression) ?? null;\n }\n\n protected parsePathComponents(): [string, string] {\n const lastSlashIndex = this.path.lastIndexOf('/');\n\n return lastSlashIndex === -1\n ? ['', this.path]\n : [this.path.substring(0, lastSlashIndex), this.path.substring(lastSlashIndex + 1)];\n }\n\n}\n","import { formatCodeBlock, stringToStudlyCase } from '@noeldemartin/utils';\n\nimport Command from '@/commands/Command';\nimport File from '@/lib/File';\nimport Log from '@/lib/Log';\nimport Template from '@/lib/Template';\nimport { templatePath } from '@/lib/utils/paths';\nimport type { CommandOptions } from '@/commands/Command';\n\ninterface Options {\n fields?: string;\n}\n\nexport class GenerateModelCommand extends Command {\n\n protected static command: string = 'generate:model';\n protected static description: string = 'Generate an AerogelJS Model';\n protected static parameters: [string, string][] = [['name', 'Model name']];\n protected static options: CommandOptions = {\n fields: 'Create model with the given fields',\n };\n\n private name: string;\n private options: Options;\n\n constructor(name: string, options: Options = {}) {\n super();\n\n this.name = name;\n this.options = options;\n }\n\n protected async run(): Promise<void> {\n this.assertAerogelOrDirectory('src/models');\n\n if (File.exists(`src/models/${this.name}.ts`)) {\n Log.fail(`${this.name} model already exists!`);\n }\n\n this.assertSoukaiInstalled();\n\n const filesList = await Log.animate('Creating model', async () => {\n const files = Template.instantiate(templatePath('model'), 'src/models', {\n model: {\n name: this.name,\n fieldsDefinition: this.getFieldsDefinition(),\n },\n soukaiImports: this.options.fields ? 'FieldType, defineModelSchema' : 'defineModelSchema',\n });\n\n return files.map((file) => `- ${file}`).join('\\n');\n });\n\n Log.info(`${this.name} model created successfully! The following files were created:\\n\\n${filesList}`);\n }\n\n protected getFieldsDefinition(): string {\n if (!this.options.fields) {\n return ' //';\n }\n\n const code = this.options.fields\n .split(',')\n .map((field) => {\n const [name, type, rules] = field.split(':');\n\n return {\n name,\n type: stringToStudlyCase(type ?? 'string'),\n required: rules === 'required',\n };\n })\n .reduce((definition, field) => {\n const fieldDefinition = field.required\n ? formatCodeBlock(`\n ${field.name}: {\n type: FieldType.${field.type},\n required: true,\n }\n `)\n : `${field.name}: FieldType.${field.type}`;\n\n return definition + `\\n${fieldDefinition},`;\n }, '');\n\n return formatCodeBlock(code, { indent: 8 });\n }\n\n protected assertSoukaiInstalled(): void {\n if (!File.contains('package.json', '\"soukai\"') && !File.contains('package.json', '\"@aerogel/plugin-soukai\"')) {\n Log.fail(`\n Soukai is not installed yet! You can install it running:\n npx gel install soukai\n `);\n }\n }\n\n}\n","import { arrayFrom, formatCodeBlock, stringToCamelCase } from '@noeldemartin/utils';\nimport { Node, SyntaxKind } from 'ts-morph';\nimport type { ObjectLiteralExpression, SourceFile } from 'ts-morph';\n\nimport Command from '@/commands/Command';\nimport File from '@/lib/File';\nimport Log from '@/lib/Log';\nimport Template from '@/lib/Template';\nimport { app } from '@/lib/utils/app';\nimport { templatePath } from '@/lib/utils/paths';\nimport { editFiles, findDescendant } from '@/lib/utils/edit';\nimport type { Editor } from '@/lib/Editor';\n\nexport class GenerateServiceCommand extends Command {\n\n protected static command: string = 'generate:service';\n protected static description: string = 'Generate an AerogelJS Service';\n protected static parameters: [string, string][] = [['name', 'Service name']];\n\n private name: string;\n\n constructor(name: string) {\n super();\n\n this.name = name;\n }\n\n protected async run(): Promise<void> {\n this.assertAerogelOrDirectory('src/services');\n\n const files = new Set<string>();\n const editor = app().edit();\n\n await this.createService(files);\n\n if (editFiles()) {\n await this.registerService(editor);\n await editor.format();\n }\n\n const filesList = arrayFrom(files)\n .map((file) => `- ${file}`)\n .join('\\n');\n\n Log.info(`${this.name} service created successfully! The following files were created:\\n\\n${filesList}`);\n }\n\n protected async createService(files: Set<string>): Promise<void> {\n await Log.animate('Creating service', async () => {\n if (File.exists(`src/services/${this.name}.ts`)) {\n Log.fail(`${this.name} service already exists!`);\n }\n\n const serviceFiles = Template.instantiate(templatePath('service'), 'src/services', {\n service: {\n name: this.name,\n },\n });\n\n serviceFiles.forEach((file) => files.add(file));\n });\n }\n\n protected async registerService(editor: Editor): Promise<void> {\n await Log.animate('Registering service', async () => {\n if (!File.exists('src/services/index.ts')) {\n await this.createServicesIndex(editor);\n }\n\n const servicesIndex = editor.requireSourceFile('src/services/index.ts');\n const servicesObject = this.getServicesObject(servicesIndex);\n\n if (!servicesObject) {\n return Log.fail('Could not find services object in services config, please add it manually.');\n }\n\n servicesIndex.addImportDeclaration({\n defaultImport: this.name,\n moduleSpecifier: `./${this.name}`,\n });\n servicesObject.addPropertyAssignment({\n name: `$${stringToCamelCase(this.name)}`,\n initializer: this.name,\n });\n\n await editor.save(servicesIndex);\n });\n }\n\n protected async createServicesIndex(editor: Editor): Promise<void> {\n File.write(\n 'src/services/index.ts',\n formatCodeBlock(`\n export const services = {};\n\n export type AppServices = typeof services;\n\n declare module '@vue/runtime-core' {\n interface ComponentCustomProperties extends AppServices {}\n }\n `),\n );\n\n editor.addSourceFile('src/services/index.ts');\n\n const mainConfig = editor.requireSourceFile('src/main.ts');\n const bootstrapOptions = this.getBootstrapOptions(mainConfig);\n\n if (!bootstrapOptions) {\n return Log.fail('Could not find options object in bootstrap config, please add the services manually.');\n }\n\n bootstrapOptions.insertShorthandPropertyAssignment(0, { name: 'services' });\n mainConfig.addImportDeclaration({\n namedImports: ['services'],\n moduleSpecifier: './services',\n });\n\n await editor.save(mainConfig);\n }\n\n protected getBootstrapOptions(mainConfig: SourceFile): ObjectLiteralExpression | null {\n const bootstrapAppCall = findDescendant(mainConfig, {\n guard: Node.isCallExpression,\n validate: (callExpression) => callExpression.getExpression().getText() === 'bootstrapApplication',\n skip: SyntaxKind.ImportDeclaration,\n });\n const bootstrapOptions = bootstrapAppCall?.getArguments()[1];\n\n if (!Node.isObjectLiteralExpression(bootstrapOptions)) {\n return null;\n }\n\n return bootstrapOptions;\n }\n\n protected getServicesObject(servicesIndex: SourceFile): ObjectLiteralExpression | null {\n const servicesDeclaration = findDescendant(servicesIndex, {\n guard: Node.isVariableDeclaration,\n validate: (variableDeclaration) => variableDeclaration.getName() === 'services',\n });\n const servicesObject = servicesDeclaration?.getInitializer();\n\n if (!Node.isObjectLiteralExpression(servicesObject)) {\n return null;\n }\n\n return servicesObject;\n }\n\n}\n","import { Node, SyntaxKind } from 'ts-morph';\nimport type { ArrayLiteralExpression, ImportDeclarationStructure, OptionalKind, SourceFile } from 'ts-morph';\n\nimport Log from '@/lib/Log';\nimport Shell from '@/lib/Shell';\nimport File from '@/lib/File';\nimport { app, isLinkedLocalApp, isLocalApp } from '@/lib/utils/app';\nimport { editFiles, findDescendant, when } from '@/lib/utils/edit';\nimport { packNotFound, packagePackPath, packagePath } from '@/lib/utils/paths';\nimport type { Editor } from '@/lib/Editor';\n\nexport default abstract class Plugin {\n\n public readonly name: string;\n\n constructor(name: string) {\n this.name = name;\n }\n\n public async install(): Promise<void> {\n this.assertNotInstalled();\n\n await this.beforeInstall();\n await this.installDependencies();\n\n if (editFiles()) {\n const editor = app().edit();\n\n await this.updateFiles(editor);\n await editor.format();\n }\n\n await this.afterInstall();\n\n Log.info(`Plugin ${this.name} installed!`);\n }\n\n protected assertNotInstalled(): void {\n if (File.contains('package.json', `\"${this.getNpmPackageName()}\"`)) {\n Log.fail(`${this.name} is already installed!`);\n }\n }\n\n protected async beforeInstall(): Promise<void> {\n // Placeholder for overrides, don't place any functionality here.\n }\n\n protected async afterInstall(): Promise<void> {\n // Placeholder for overrides, don't place any functionality here.\n }\n\n protected async installDependencies(): Promise<void> {\n await Log.animate('Installing plugin dependencies', async () => {\n await this.installNpmDependencies();\n });\n }\n\n protected async updateFiles(editor: Editor): Promise<void> {\n if (!this.isForDevelopment()) {\n await this.updateBootstrapConfig(editor);\n }\n }\n\n protected async installNpmDependencies(): Promise<void> {\n const flags = this.isForDevelopment() ? '--save-dev' : '';\n\n if (isLinkedLocalApp()) {\n await Shell.run(`npm install file:${packagePath(this.getLocalPackageName())} ${flags}`);\n\n return;\n }\n\n if (isLocalApp()) {\n const packPath = packagePackPath(this.getLocalPackageName()) ?? packNotFound(this.getLocalPackageName());\n\n await Shell.run(`npm install file:${packPath} ${flags}`);\n\n return;\n }\n\n await Shell.run(`npm install ${this.getNpmPackageName()}@next --save-exact ${flags}`);\n }\n\n protected async updateBootstrapConfig(editor: Editor): Promise<void> {\n await Log.animate('Injecting plugin in bootstrap configuration', async () => {\n const mainConfig = editor.requireSourceFile('src/main.ts');\n const pluginsArray = this.getBootstrapPluginsDeclaration(mainConfig);\n\n if (!pluginsArray) {\n return Log.fail(`\n Could not find plugins array in bootstrap config, please add the following manually:\n\n ${this.getBootstrapConfig()}\n `);\n }\n\n mainConfig.addImportDeclaration(this.getBootstrapImport());\n pluginsArray.addElement(this.getBootstrapConfig());\n\n await editor.save(mainConfig);\n });\n }\n\n protected async updateTailwindConfig(editor: Editor, options: { content: string }): Promise<void> {\n await Log.animate('Updating tailwind configuration', async () => {\n const tailwindConfig = editor.requireSourceFile('tailwind.config.js');\n const contentArray = this.getTailwindContentArray(tailwindConfig);\n\n if (!contentArray) {\n return Log.fail(`\n Could not find content array in tailwind config, please add the following manually:\n\n ${options.content}\n `);\n }\n\n contentArray.addElement(options.content);\n\n await editor.save(tailwindConfig);\n });\n }\n\n protected getBootstrapPluginsDeclaration(mainConfig: SourceFile): ArrayLiteralExpression | null {\n const bootstrapAppCall = findDescendant(mainConfig, {\n guard: Node.isCallExpression,\n validate: (callExpression) => callExpression.getExpression().getText() === 'bootstrapApplication',\n skip: SyntaxKind.ImportDeclaration,\n });\n const bootstrapOptions = bootstrapAppCall?.getArguments()[1];\n const pluginsOption = when(bootstrapOptions, Node.isObjectLiteralExpression)?.getProperty('plugins');\n const pluginsArray = when(pluginsOption, Node.isPropertyAssignment)?.getInitializer();\n\n if (!Node.isArrayLiteralExpression(pluginsArray)) {\n return null;\n }\n\n return pluginsArray;\n }\n\n protected getTailwindContentArray(tailwindConfig: SourceFile): ArrayLiteralExpression | null {\n const contentAssignment = findDescendant(tailwindConfig, {\n guard: Node.isPropertyAssignment,\n validate: (propertyAssignment) => propertyAssignment.getName() === 'content',\n skip: SyntaxKind.JSDoc,\n });\n const contentArray = contentAssignment?.getInitializer();\n\n if (!Node.isArrayLiteralExpression(contentArray)) {\n return null;\n }\n\n return contentArray;\n }\n\n protected getBootstrapImport(): OptionalKind<ImportDeclarationStructure> {\n return {\n defaultImport: this.name,\n moduleSpecifier: `@aerogel/plugin-${this.name}`,\n };\n }\n\n protected getNpmPackageName(): string {\n return `@aerogel/${this.getLocalPackageName()}`;\n }\n\n protected getLocalPackageName(): string {\n return `plugin-${this.name}`;\n }\n\n protected isForDevelopment(): boolean {\n return false;\n }\n\n protected getBootstrapConfig(): string {\n return `${this.name}()`;\n }\n\n}\n","import Command from '@/commands/Command';\nimport Log from '@/lib/Log';\nimport { Histoire } from '@/plugins/Histoire';\nimport { Solid } from '@/plugins/Solid';\nimport { Soukai } from '@/plugins/Soukai';\nimport type Plugin from '@/plugins/Plugin';\n\nconst plugins = [new Soukai(), new Solid(), new Histoire()].reduce(\n (pluginsObject, plugin) => Object.assign(pluginsObject, { [plugin.name]: plugin }),\n {} as Record<string, Plugin>,\n);\n\nexport class InstallCommand extends Command {\n\n protected static command: string = 'install';\n protected static description: string = 'Install an AerogelJS plugin';\n protected static parameters: [string, string][] = [['plugin', 'Plugin to install']];\n\n private plugin: Plugin;\n\n constructor(plugin: string) {\n super();\n\n this.plugin =\n plugins[plugin] ??\n Log.fail(`Plugin '${plugin}' doesn't exist. Available plugins: ${Object.keys(plugins).join(', ')}`);\n }\n\n protected async run(): Promise<void> {\n await this.plugin.install();\n }\n\n}\n","import Plugin from '@/plugins/Plugin';\nimport Shell from '@/lib/Shell';\n\nexport class Soukai extends Plugin {\n\n constructor() {\n super('soukai');\n }\n\n protected async installNpmDependencies(): Promise<void> {\n await Shell.run('npm install soukai@next --save-exact');\n await super.installNpmDependencies();\n }\n\n protected getBootstrapConfig(): string {\n return 'soukai({ models: import.meta.glob(\\'@/models/*\\', { eager: true }) })';\n }\n\n}\n","import File from '@/lib/File';\nimport Log from '@/lib/Log';\nimport Plugin from '@/plugins/Plugin';\nimport Shell from '@/lib/Shell';\nimport { isLinkedLocalApp } from '@/lib/utils/app';\nimport { packagePath } from '@/lib/utils/paths';\nimport type { Editor } from '@/lib/Editor';\n\nexport class Solid extends Plugin {\n\n constructor() {\n super('solid');\n }\n\n protected async updateFiles(editor: Editor): Promise<void> {\n await this.updateTailwindConfig(editor, {\n content: isLinkedLocalApp()\n ? `'${packagePath('plugin-solid')}/dist/**/*.js'`\n : '\\'./node_modules/@aerogel/plugin-solid/dist/**/*.js\\'',\n });\n\n await this.updateNpmScripts(editor);\n await this.updateGitIgnore();\n await super.updateFiles(editor);\n }\n\n protected async installNpmDependencies(): Promise<void> {\n await Shell.run('npm install soukai-solid@next --save-exact');\n await Shell.run('npm install @solid/community-server@7 --save');\n await super.installNpmDependencies();\n }\n\n protected async updateNpmScripts(editor: Editor): Promise<void> {\n Log.info('Updating npm scripts...');\n\n const packageJson = File.read('package.json');\n\n if (!packageJson) {\n return Log.fail('Could not find package.json file');\n }\n\n File.write(\n 'package.json',\n packageJson\n .replace(\n '\"cy:dev\": \"concurrently --kill-others \\\\\"npm run test:serve-app\\\\\" \\\\\"npm run cy:open\\\\\"\",',\n '\"cy:dev\": \"concurrently --kill-others ' +\n '\\\\\"npm run test:serve-app\\\\\" \\\\\"npm run test:serve-pod\\\\\" \\\\\"npm run cy:open\\\\\"\",',\n )\n .replace(\n '\"cy:test\": \"start-server-and-test test:serve-app http-get://localhost:5001 cy:run\",',\n '\"cy:test\": \"start-server-and-test ' +\n 'test:serve-app http-get://localhost:5001 test:serve-pod http-get://localhost:4000 cy:run\",',\n )\n .replace(\n '\"dev\": \"vite\",',\n '\"dev\": \"vite\",\\n' +\n '\"dev:serve-pod\": \"community-solid-server -c @css:config/file.json -p 4000 -f ./solid-data\",',\n )\n .replace(\n '\"test:serve-app\": \"vite --port 5001\"',\n '\"test:serve-app\": \"vite --port 5001\",\\n' +\n '\"test:serve-pod\": \"community-solid-server -p 4000 -l warn\"',\n ),\n );\n\n editor.addModifiedFile('package.json');\n }\n\n protected async updateGitIgnore(): Promise<void> {\n Log.info('Updating .gitignore');\n\n const gitignore = File.read('.gitignore') ?? '';\n\n File.write('.gitignore', `${gitignore}/solid-data\\n`);\n }\n\n}\n","import File from '@/lib/File';\nimport Log from '@/lib/Log';\nimport Plugin from '@/plugins/Plugin';\nimport Shell from '@/lib/Shell';\nimport Template from '@/lib/Template';\nimport { isLinkedLocalApp } from '@/lib/utils/app';\nimport { packagePath, templatePath } from '@/lib/utils/paths';\nimport type { Editor } from '@/lib/Editor';\n\nexport class Histoire extends Plugin {\n\n private installedPatchPackage: boolean = false;\n private installedPostCSSPseudoClasses: boolean = false;\n\n constructor() {\n super('histoire');\n }\n\n public async beforeInstall(): Promise<void> {\n this.installedPatchPackage = false;\n this.installedPostCSSPseudoClasses = false;\n }\n\n protected async afterInstall(): Promise<void> {\n if (!this.installedPatchPackage) {\n return;\n }\n\n await Log.animate('Patching dependencies', async () => {\n await Shell.run('npx patch-package');\n });\n }\n\n protected async updateFiles(editor: Editor): Promise<void> {\n await this.updateTailwindConfig(editor, {\n content: isLinkedLocalApp()\n ? `'${packagePath('histoire')}/dist/**/*.js'`\n : '\\'./node_modules/@aerogel/histoire/dist/**/*.js\\'',\n });\n\n await this.updateNpmScripts(editor);\n await this.createConfigFiles();\n await super.updateFiles(editor);\n }\n\n protected async installNpmDependencies(): Promise<void> {\n // We need this specific version because we're patching it using patch-package\n await Shell.run('npm install histoire@0.17.6 --save-dev');\n\n if (!File.contains('package.json', '\"patch-package\"')) {\n await Shell.run('npm install patch-package --save-dev');\n\n this.installedPatchPackage = true;\n }\n\n if (!File.contains('package.json', '\"postcss-pseudo-classes\"')) {\n await Shell.run('npm install postcss-pseudo-classes --save-dev');\n\n this.installedPostCSSPseudoClasses = true;\n }\n\n await super.installNpmDependencies();\n }\n\n protected getLocalPackageName(): string {\n return this.name;\n }\n\n protected async updateNpmScripts(editor: Editor): Promise<void> {\n Log.info('Updating npm scripts...');\n\n const packageJson = File.read('package.json');\n\n if (!packageJson) {\n return Log.fail('Could not find package.json file');\n }\n\n File.write(\n 'package.json',\n packageJson.replace(\n '\"lint\": \"noeldemartin-lint src\",',\n this.installedPatchPackage\n ? '\"histoire\": \"histoire dev\", \"lint\": \"noeldemartin-lint src\", \"postinstall\": \"patch-package\",'\n : '\"histoire\": \"histoire dev\", \"lint\": \"noeldemartin-lint src\",',\n ),\n );\n\n editor.addModifiedFile('package.json');\n }\n\n protected async createConfigFiles(): Promise<void> {\n Log.info('Creating config files...');\n\n Template.instantiate(templatePath('histoire'));\n\n if (this.installedPostCSSPseudoClasses) {\n Template.instantiate(templatePath('postcss-pseudo-classes'));\n }\n }\n\n protected isForDevelopment(): boolean {\n return true;\n }\n\n}\n","import { Command } from 'commander';\nimport { CreateCommand } from '@/commands/create';\nimport { facade } from '@noeldemartin/utils';\nimport { GenerateComponentCommand } from '@/commands/generate-component';\nimport { GenerateModelCommand } from '@/commands/generate-model';\nimport { GenerateServiceCommand } from '@/commands/generate-service';\nimport { InstallCommand } from '@/commands/install';\n\nexport class CLIService {\n\n public run(argv?: string[]): void {\n const program = new Command();\n\n program.name('ag').description('AerogelJS CLI').version('0.0.0');\n\n CreateCommand.define(program);\n GenerateComponentCommand.define(program);\n GenerateModelCommand.define(program);\n GenerateServiceCommand.define(program);\n InstallCommand.define(program);\n\n program.parse(argv);\n }\n\n}\n\nexport default facade(new CLIService());\n"],"names":["File","facade","contains","path","contents","this","read","includes","exists","existsSync","isSymlink","lstatSync","isSymbolicLink","isFile","readFileSync","toString","getFiles","directoryPath","children","readdirSync","withFileTypes","files","child","resolve","name","isDirectory","push","isEmptyDirectory","length","makeDirectory","mkdirSync","recursive","write","dirname","writeFileSync","Log","constructor","_defineProperty","hex","animate","message","operation","_this","updateStdout","end","arguments","undefined","done","progress","renderInfo","renderMarkdown","repeat","frame","stdout","interval","setInterval","result","clearInterval","info","log","error","renderError","fail","process","exit","success","renderSuccess","matches","stringMatchAll","match","replace","bold","formatMessage","forEach","line","logLine","lines","slice","trimEnd","split","firstLetter","trim","indentation","find","indexOf","map","console","cursorTo","clearLine","Template","instantiate","destination","replacements","filenameReplacements","getFilenameReplacements","file","relativePath","Object","entries","reduce","_ref","replacement","replaceAll","substring","fileContents","filePath","endsWith","render","prefix","_ref2","key","value","assign","packNotFound","packageName","packagePackPath","packagePath","__dirname","packageJson","stringMatch","cliPath","basePath","templatePath","Shell","setWorkingDirectory","cwd","run","command","Promise","reject","exec","Editor","project","Project","tsConfigFilePath","modifiedFiles","Set","addSourceFilesAtPaths","addSourceFile","requireSourceFile","getSourceFileOrThrow","format","async","usingPrettier","usingESLint","formatFile","all","arrayFrom","save","addModifiedFile","getFilePath","add","App","options","create","app","slug","stringToSlug","dependencies","getDependencies","contentPath","linkedLocal","edit","withFilePrefix","paths","pathsWithFile","aerogelCli","aerogelCore","aerogelCypress","aerogelPluginI18n","aerogelPluginSoukai","aerogelVite","local","Command","define","program","description","parameters","argument","definition","type","option","action","_len","args","Array","_key","call","_len2","_key2","instance","validate","assertAerogelOrDirectory","CreateCommand","super","stringToTitleCase","basename","createApp","installDependencies","initializeGit","copy","isLinkedLocalApp","findDescendant","node","guard","skipKinds","skip","forEachDescendant","descendant","traversal","descendantKind","getKind","when","assertion","GenerateComponentCommand","button","input","assertHistoireInstalled","directoryName","componentName","parsePathComponents","createComponent","createStory","declareComponents","filesList","join","story","templateName","component","editor","viteConfig","componentDirsArray","getComponentDirsArray","getDescendantsOfKind","SyntaxKind","StringLiteral","some","literal","getText","addElement","pluginCall","Node","isCallExpression","callExpression","startsWith","ImportDeclaration","dirsAssignment","isPropertyAssignment","propertyAssignment","getName","dirsArray","getInitializer","isArrayLiteralExpression","declareComponentDirsArray","pluginOptions","isObjectLiteralExpression","addPropertyAssignment","initializer","lastSlashIndex","lastIndexOf","GenerateModelCommand","assertSoukaiInstalled","model","fieldsDefinition","getFieldsDefinition","soukaiImports","fields","code","field","rules","stringToStudlyCase","required","formatCodeBlock","indent","GenerateServiceCommand","createService","registerService","service","createServicesIndex","servicesIndex","servicesObject","getServicesObject","addImportDeclaration","defaultImport","moduleSpecifier","stringToCamelCase","mainConfig","bootstrapOptions","getBootstrapOptions","insertShorthandPropertyAssignment","namedImports","bootstrapAppCall","getExpression","getArguments","servicesDeclaration","isVariableDeclaration","variableDeclaration","Plugin","install","assertNotInstalled","beforeInstall","updateFiles","afterInstall","getNpmPackageName","installNpmDependencies","isForDevelopment","updateBootstrapConfig","flags","getLocalPackageName","packPath","pluginsArray","getBootstrapPluginsDeclaration","getBootstrapConfig","getBootstrapImport","updateTailwindConfig","tailwindConfig","contentArray","getTailwindContentArray","content","pluginsOption","getProperty","contentAssignment","JSDoc","plugins","updateNpmScripts","updateGitIgnore","gitignore","installedPatchPackage","installedPostCSSPseudoClasses","createConfigFiles","pluginsObject","plugin","InstallCommand","keys","cli","argv","version","parse"],"mappings":"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"}
|
package/dist/aerogel-cli.esm.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{Command as e}from"commander";import t from"@babel/runtime/helpers/esm/defineProperty";import"core-js/modules/esnext.async-iterator.reduce.js";import"core-js/modules/esnext.iterator.constructor.js";import"core-js/modules/esnext.iterator.reduce.js";import{facade as i,stringMatchAll as s,toString as n,stringMatch as r,arrayFrom as a,stringToSlug as o,stringToStudlyCase as c,stringToCamelCase as l}from"@noeldemartin/utils";import{existsSync as d,lstatSync as p,readFileSync as m,readdirSync as u,mkdirSync as g,writeFileSync as h}from"fs";import{resolve as f,dirname as y}from"path";import"core-js/modules/esnext.async-iterator.for-each.js";import"core-js/modules/esnext.iterator.for-each.js";import"core-js/modules/esnext.async-iterator.find.js";import"core-js/modules/esnext.iterator.find.js";import"core-js/modules/esnext.async-iterator.map.js";import"core-js/modules/esnext.iterator.map.js";import{hex as w,bold as v}from"chalk";import{cursorTo as j,clearLine as x}from"readline";import{render as $}from"mustache";import"core-js/modules/esnext.set.add-all.js";import"core-js/modules/esnext.set.delete-all.js";import"core-js/modules/esnext.set.difference.js";import"core-js/modules/esnext.set.every.js";import"core-js/modules/esnext.set.filter.js";import"core-js/modules/esnext.set.find.js";import"core-js/modules/esnext.set.intersection.js";import"core-js/modules/esnext.set.is-disjoint-from.js";import"core-js/modules/esnext.set.is-subset-of.js";import"core-js/modules/esnext.set.is-superset-of.js";import"core-js/modules/esnext.set.join.js";import"core-js/modules/esnext.set.map.js";import"core-js/modules/esnext.set.reduce.js";import"core-js/modules/esnext.set.some.js";import"core-js/modules/esnext.set.symmetric-difference.js";import"core-js/modules/esnext.set.union.js";import{Project as k,SyntaxKind as S,Node as C}from"ts-morph";import{exec as A}from"child_process";import"core-js/modules/esnext.async-iterator.some.js";import"core-js/modules/esnext.iterator.some.js";var D=i(new class{contains(e,t){return!!this.read(e)?.includes(t)}exists(e){return d(e)}isSymlink(e){return p(e).isSymbolicLink()}read(e){return this.isFile(e)?m(e).toString():null}getFiles(e){const t=u(e,{withFileTypes:!0}),i=[];for(const s of t){const t=f(e,s.name);s.isDirectory()?i.push(...this.getFiles(t)):i.push(t)}return i}isDirectory(e){return this.exists(e)&&p(e).isDirectory()}isFile(e){return this.exists(e)&&p(e).isFile()}isEmptyDirectory(e){return!!this.isDirectory(e)&&0===this.getFiles(e).length}makeDirectory(e){g(e,{recursive:!0})}write(e,t){d(y(e))||g(y(e),{recursive:!0}),h(e,t)}});var F=i(new class{constructor(){t(this,"renderInfo",w("#00ffff")),t(this,"renderSuccess",w("#00ff00")),t(this,"renderError",w("#ff0000"))}async animate(e,t){var i=this;const s=function(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",s=arguments.length>1&&void 0!==arguments[1]&&arguments[1];const r=i.renderInfo(i.renderMarkdown(e)+(s?"...":".".repeat(n%4)))+t;i.stdout(r)};let n=0;s();const r=setInterval((()=>(n++,s())),1e3),a=await t();return clearInterval(r),s("\n",!0),a}info(e){this.log(this.renderMarkdown(e),this.renderInfo)}error(e){this.log(this.renderMarkdown(e),this.renderError)}fail(e){this.error(e),process.exit(1)}success(e){this.log(this.renderMarkdown(e),this.renderSuccess)}renderMarkdown(e){const t=s(e,/\*\*(.*)\*\*/g);for(const i of t)e=e.replace(i[0],v(i[1]));return e}log(e,t){this.formatMessage(e).forEach((e=>{this.logLine(t?t(e):e)}))}formatMessage(e){if("\n"===e[0]){const t=(e=e.slice(1).trimEnd()).split("\n"),i=e.trim()[0]??"",s=t.find((e=>e.trim().length>0))?.indexOf(i)??0;return t.map((e=>e.slice(s)))}return[e]}logLine(e){console.log(e)}stdout(e){j(process.stdout,0),x(process.stdout,0),process.stdout.write(e)}});class I{static instantiate(e,t,i){return new I(e).instantiate(t,i)}constructor(e){t(this,"path",void 0),this.path=e}instantiate(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const i=this.getFilenameReplacements(t),s=[];e=`${e}/`.replace(/\/\//,"/");for(const n of D.getFiles(this.path)){const r=Object.entries(i).reduce(((e,t)=>{let[i,s]=t;return e.replaceAll(i,s)}),n.substring(this.path.length+1)),a=m(n).toString(),o=e+(r.endsWith(".template")?r.slice(0,-9):r);D.write(o,$(a,t,void 0,["<%","%>"])),s.push(o)}return s}getFilenameReplacements(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return Object.entries(e).reduce(((e,i)=>{let[s,r]=i;return"object"==typeof r?Object.assign(e,this.getFilenameReplacements(r,`${s}.`)):e[`[${t}${s}]`]=n(r),e}),{})}}function P(e){return F.fail(`Could not find ${e} pack file, did you run 'npm pack'?`)}function b(e){return D.getFiles(E(e)).find((e=>e.endsWith(".tgz")))??null}function E(e){return function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";if(D.contains(f(__dirname,"../../../package.json"),'"name": "aerogel"'))return f(__dirname,"../",e);const t=D.read(f(__dirname,"../../../../package.json")),i=r(t??"",/"@aerogel\/cli": "file:(.*)\/aerogel-cli-[\d.]*\.tgz"/),s=i?.[1]??F.fail("Could not determine base path");return f(s,e)}(`../${e}`)}function O(e){return f(__dirname,`../templates/${e}`)}var N=i(new class{constructor(){t(this,"cwd",null)}setWorkingDirectory(e){this.cwd=e}async run(e){await new Promise(((t,i)=>{A(e,{cwd:this.cwd??void 0},(e=>{e?i(e):t()}))}))}});class L{constructor(){t(this,"project",void 0),t(this,"modifiedFiles",void 0),this.project=new k({tsConfigFilePath:"tsconfig.json"}),this.modifiedFiles=new Set,this.project.addSourceFilesAtPaths("src/**/*.ts"),this.project.addSourceFilesAtPaths("tailwind.config.js"),this.project.addSourceFilesAtPaths("vite.config.ts")}addSourceFile(e){this.project.addSourceFilesAtPaths(e)}requireSourceFile(e){return this.project.getSourceFileOrThrow(e)}async format(){await F.animate("Formatting modified files",(async()=>{const e=D.exists("prettier.config.js"),t=D.exists(".eslintrc.js");await Promise.all(a(this.modifiedFiles).map((async i=>{e&&await N.run(`npx prettier ${i} --write`),t&&await N.run(`npx eslint ${i} --fix`)})))}))}async save(e){await e.save(),this.modifiedFiles.add(e.getFilePath())}}class T{constructor(e){let i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};t(this,"name",void 0),t(this,"options",void 0),this.name=e,this.options=i}create(e){!D.exists(e)||D.isDirectory(e)&&D.isEmptyDirectory(e)||F.fail(`Folder at '${e}' already exists!`),I.instantiate(O("app"),e,{app:{name:this.name,slug:o(this.name)},dependencies:this.getDependencies(),contentPath:this.options.linkedLocal?`${E("core")}/dist/**/*.js`:"./node_modules/@aerogel/core/dist/**/*.js"})}edit(){return new L}getDependencies(){const e=e=>Object.entries(e).reduce(((e,t)=>{let[i,s]=t;return Object.assign(e,{[i]:`file:${s}`})}),{});return this.options.linkedLocal?e({aerogelCli:E("cli"),aerogelCore:E("core"),aerogelCypress:E("cypress"),aerogelPluginI18n:E("plugin-i18n"),aerogelPluginSoukai:E("plugin-soukai"),aerogelVite:E("vite")}):this.options.local?e({aerogelCli:b("cli")??P("cli"),aerogelCore:b("core")??P("core"),aerogelCypress:b("cypress")??P("cypress"),aerogelPluginI18n:b("plugin-i18n")??P("plugin-i18n"),aerogelPluginSoukai:b("plugin-soukai")??P("plugin-soukai"),aerogelVite:b("vite")??P("vite")}):{aerogelCli:"next",aerogelCore:"next",aerogelCypress:"next",aerogelPluginI18n:"next",aerogelPluginSoukai:"next",aerogelVite:"next"}}}class z{static define(e){var t=this;e=e.command(this.command).description(this.description);for(const[t,i]of this.parameters)e=e.argument(`<${t}>`,i);for(const[t,i]of Object.entries(this.options)){const s="string"==typeof i?i:i.description,n="string"==typeof i?"string":i.type??"string";e=e.option("boolean"===n?`--${t}`:`--${t} <${n}>`,s)}e=e.action((function(){for(var e=arguments.length,i=new Array(e),s=0;s<e;s++)i[s]=arguments[s];return t.run.call(t,...i)}))}static async run(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];const s=new this(...t);await s.run()}async run(){}assertAerogelOrDirectory(e){const t=D.read("package.json");if(t?.includes("@aerogel/core"))return;if(e&&D.isDirectory(e))return;const i=e?`${e} folder does not exist.`:"package.json does not contain @aerogel/core.";F.fail(`${i} Are you sure this is an Aerogel app?`)}}t(z,"command",""),t(z,"description",""),t(z,"parameters",[]),t(z,"options",{});class B extends z{constructor(e,i){super(),t(this,"path",void 0),t(this,"options",void 0),this.path=e,this.options=i}async run(){const e=this.path,t=this.options.name??"Aerogel App";N.setWorkingDirectory(e),await this.createApp(t,e),await this.installDependencies(),await this.initializeGit(),F.success(`\n\n That's it! You can start working on **${t}** doing the following:\n\n cd ${e}\n npm run dev\n\n Have fun!\n `)}async createApp(e,t){F.info(`Creating **${e}**...`),new T(e,{local:this.options.local,linkedLocal:this.options.local&&!this.options.copy}).create(t)}async installDependencies(){await F.animate("Installing dependencies",(async()=>{await N.run("npm install")}))}async initializeGit(){await F.animate("Initializing git",(async()=>{await N.run("git init"),await N.run("git add ."),await N.run('git commit -m "Start"')}))}}function _(){return new T("")}function M(){return D.isSymlink("node_modules/@aerogel/core")}function q(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!e)return;const i=t.guard??(()=>!0),s=t.validate??(()=>!0),n=a(t.skip??[]);return e.forEachDescendant(((e,t)=>{if(i(e)&&s(e))return e;const r=e.getKind();n.includes(r)&&t.skip()}))}function J(e,t){if(e&&t(e))return e}t(B,"command","create"),t(B,"description","Create AerogelJS app"),t(B,"parameters",[["path","Application path"]]),t(B,"options",{name:"Application name",local:{type:"boolean",description:"Whether to create an app using local Aerogel packages (used for core development)"},copy:{type:"boolean",description:"Whether to create an app linked to local Aerogel packages (used in CI)"}});class W extends z{constructor(e){let i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(),t(this,"path",void 0),t(this,"options",void 0),this.path=e,this.options=i}async run(){this.assertAerogelOrDirectory("src/components"),this.assertHistoireInstalled();const e=new Set,[t,i]=this.parsePathComponents();await this.createComponent(t,i,e),await this.createStory(i,e),await this.declareComponents();const s=a(e).map((e=>`- ${e}`)).join("\n");F.info(`${i} component created successfully! The following files were created:\n\n${s}`)}assertHistoireInstalled(){this.options.story&&(D.exists("src/main.histoire.ts")||F.fail("Histoire is not installed yet!"))}async createComponent(e,t,i){await F.animate("Creating component",(async()=>{D.exists(`src/components/${this.path}.vue`)&&F.fail(`${this.path} component already exists!`);I.instantiate(O("component"),`src/components/${e}`,{component:{name:t}}).forEach((e=>i.add(e)))}))}async createStory(e,t){this.options.story&&await F.animate("Creating story",(async()=>{I.instantiate(O("component-story"),"src/components",{component:{name:e}}).forEach((e=>t.add(e)))}))}async declareComponents(){const e=_().edit(),t=e.requireSourceFile("vite.config.ts"),i=this.getComponentDirsArray(t);if(!i)return F.fail("Could not find component dirs declaration in vite config!");i.getDescendantsOfKind(S.StringLiteral).some((e=>"'src/components'"===e.getText()))||(await F.animate("Updating vite config",(async()=>{i.addElement("'src/components'"),await e.save(t)})),await e.format())}getComponentDirsArray(e){const t=q(e,{guard:C.isCallExpression,validate:e=>e.getText().startsWith("Components("),skip:S.ImportDeclaration});if(!t)return null;const i=q(t,{guard:C.isPropertyAssignment,validate:e=>"dirs"===e.getName()}),s=i?.getInitializer();return C.isArrayLiteralExpression(s)?s:this.declareComponentDirsArray(t)}declareComponentDirsArray(e){const t=q(e,{guard:C.isObjectLiteralExpression}),i=t?.addPropertyAssignment({name:"dirs",initializer:"[]"});return i?.getInitializer()??null}parsePathComponents(){const e=this.path.lastIndexOf("/");return-1===e?["",this.path]:[this.path.substring(0,e),this.path.substring(e+1)]}}function G(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const i=e.split("\n"),s=t.indent??0;let n=0,r="";for(const e of i){const t=e.trim(),i=0===t.length;if(0===r.length){if(i)continue;n=e.indexOf(t[0]??""),r+=`${" ".repeat(s)}${t}\n`;continue}if(i){r+="\n";continue}const a=e.indexOf(t[0]??"");r+=`${" ".repeat(s+a-n)}${t}\n`}return r.trimEnd()}t(W,"command","generate:component"),t(W,"description","Generate an AerogelJS Component"),t(W,"parameters",[["path","Component path (relative to components folder; extension not necessary)"]]),t(W,"options",{story:{description:"Create component story using Histoire",type:"boolean"}});class H extends z{constructor(e){let i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(),t(this,"name",void 0),t(this,"options",void 0),this.name=e,this.options=i}async run(){this.assertAerogelOrDirectory("src/models"),D.exists(`src/models/${this.name}.ts`)&&F.fail(`${this.name} model already exists!`),this.assertSoukaiInstalled();const e=await F.animate("Creating model",(async()=>I.instantiate(O("model"),"src/models",{model:{name:this.name,fieldsDefinition:this.getFieldsDefinition()},soukaiImports:this.options.fields?"FieldType, defineModelSchema":"defineModelSchema"}).map((e=>`- ${e}`)).join("\n")));F.info(`${this.name} model created successfully! The following files were created:\n\n${e}`)}getFieldsDefinition(){if(!this.options.fields)return" //";const e=this.options.fields.split(",").map((e=>{const[t,i,s]=e.split(":");return{name:t,type:c(i??"string"),required:"required"===s}})).reduce(((e,t)=>e+`\n${t.required?G(`\n ${t.name}: {\n type: FieldType.${t.type},\n required: true,\n }\n `):`${t.name}: FieldType.${t.type}`},`),"");return G(e,{indent:8})}assertSoukaiInstalled(){D.contains("package.json",'"soukai"')||D.contains("package.json",'"@aerogel/plugin-soukai"')||F.fail("\n Soukai is not installed yet! You can install it running:\n npx ag install soukai\n ")}}t(H,"command","generate:model"),t(H,"description","Generate an AerogelJS Model"),t(H,"parameters",[["name","Model name"]]),t(H,"options",{fields:"Create model with the given fields"});class R extends z{constructor(e){super(),t(this,"name",void 0),this.name=e}async run(){this.assertAerogelOrDirectory("src/services");const e=new Set,t=_().edit();await this.createService(e),await this.registerService(t),await t.format();const i=a(e).map((e=>`- ${e}`)).join("\n");F.info(`${this.name} service created successfully! The following files were created:\n\n${i}`)}async createService(e){await F.animate("Creating service",(async()=>{D.exists(`src/services/${this.name}.ts`)&&F.fail(`${this.name} service already exists!`);I.instantiate(O("service"),"src/services",{service:{name:this.name}}).forEach((t=>e.add(t)))}))}async registerService(e){await F.animate("Registering service",(async()=>{D.exists("src/services/index.ts")||await this.createServicesIndex(e);const t=e.requireSourceFile("src/services/index.ts"),i=this.getServicesObject(t);if(!i)return F.fail("Could not find services object in services config, please add it manually.");t.addImportDeclaration({defaultImport:this.name,moduleSpecifier:`./${this.name}`}),i.addPropertyAssignment({name:`$${l(this.name)}`,initializer:this.name}),await e.save(t)}))}async createServicesIndex(e){D.write("src/services/index.ts",G("\n export const services = {};\n\n export type AppServices = typeof services;\n\n declare module '@vue/runtime-core' {\n interface ComponentCustomProperties extends AppServices {}\n }\n ")),e.addSourceFile("src/services/index.ts");const t=e.requireSourceFile("src/main.ts"),i=this.getBootstrapOptions(t);if(!i)return F.fail("Could not find options object in bootstrap config, please add the services manually.");i.insertShorthandPropertyAssignment(0,{name:"services"}),t.addImportDeclaration({namedImports:["services"],moduleSpecifier:"./services"}),await e.save(t)}getBootstrapOptions(e){const t=q(e,{guard:C.isCallExpression,validate:e=>"bootstrapApplication"===e.getExpression().getText(),skip:S.ImportDeclaration}),i=t?.getArguments()[1];return C.isObjectLiteralExpression(i)?i:null}getServicesObject(e){const t=q(e,{guard:C.isVariableDeclaration,validate:e=>"services"===e.getName()}),i=t?.getInitializer();return C.isObjectLiteralExpression(i)?i:null}}t(R,"command","generate:service"),t(R,"description","Generate an AerogelJS Service"),t(R,"parameters",[["name","Service name"]]);class V{constructor(e){t(this,"name",void 0),this.name=e}async install(){this.assertNotInstalled(),await this.installDependencies();{const e=_().edit();await this.updateFiles(e),await e.format()}F.info(`Plugin ${this.name} installed!`)}assertNotInstalled(){D.contains("package.json",`"${this.getNpmPackageName()}"`)&&F.fail(`${this.name} is already installed!`)}async installDependencies(){await F.animate("Installing plugin dependencies",(async()=>{await this.installNpmDependencies()}))}async updateFiles(e){await this.updateBootstrapConfig(e)}async installNpmDependencies(){if(M())await N.run(`npm install file:${E(this.getLocalPackageName())}`);else if(D.contains("package.json","file")){const e=b(this.getLocalPackageName())??P(this.getLocalPackageName());await N.run(`npm install file:${e}`)}else await N.run(`npm install ${this.getNpmPackageName()}@next`)}async updateBootstrapConfig(e){await F.animate("Injecting plugin in bootstrap configuration",(async()=>{const t=e.requireSourceFile("src/main.ts"),i=this.getBootstrapPluginsDeclaration(t);if(!i)return F.fail(`\n Could not find plugins array in bootstrap config, please add the following manually:\n\n ${this.getBootstrapConfig()}\n `);t.addImportDeclaration(this.getBootstrapImport()),i.addElement(this.getBootstrapConfig()),await e.save(t)}))}getBootstrapPluginsDeclaration(e){const t=q(e,{guard:C.isCallExpression,validate:e=>"bootstrapApplication"===e.getExpression().getText(),skip:S.ImportDeclaration}),i=t?.getArguments()[1],s=J(i,C.isObjectLiteralExpression)?.getProperty("plugins"),n=J(s,C.isPropertyAssignment)?.getInitializer();return C.isArrayLiteralExpression(n)?n:null}getBootstrapImport(){return{defaultImport:this.name,moduleSpecifier:`@aerogel/plugin-${this.name}`}}getNpmPackageName(){return`@aerogel/${this.getLocalPackageName()}`}getLocalPackageName(){return`plugin-${this.name}`}getBootstrapConfig(){return`${this.name}()`}}const K=[new class extends V{constructor(){super("soukai")}async installNpmDependencies(){await N.run("npm install soukai@next"),await super.installNpmDependencies()}getBootstrapConfig(){return"soukai({ models: import.meta.glob('@/models/*', { eager: true }) })"}},new class extends V{constructor(){super("solid")}async updateFiles(e){await this.updateTailwindConfig(e),await super.updateFiles(e)}async installNpmDependencies(){await N.run("npm install soukai-solid@next"),await super.installNpmDependencies()}async updateTailwindConfig(e){await F.animate("Updating tailwind configuration",(async()=>{const t=e.requireSourceFile("tailwind.config.js"),i=this.getTailwindContentArray(t),s=M()?`'${E("plugin-solid")}/dist/**/*.js'`:"'./node_modules/@aerogel/plugin-solid/dist/**/*.js'";if(!i)return F.fail(`\n Could not find content array in tailwind config, please add the following manually:\n\n ${s}\n `);i.addElement(s),await e.save(t)}))}getTailwindContentArray(e){const t=q(e,{guard:C.isPropertyAssignment,validate:e=>"content"===e.getName(),skip:S.JSDoc}),i=t?.getInitializer();return C.isArrayLiteralExpression(i)?i:null}}].reduce(((e,t)=>Object.assign(e,{[t.name]:t})),{});class U extends z{constructor(e){super(),t(this,"plugin",void 0),this.plugin=K[e]??F.fail(`Plugin '${e}' doesn't exist. Available plugins: ${Object.keys(K).join(", ")}`)}async run(){await this.plugin.install()}}t(U,"command","install"),t(U,"description","Install an AerogelJS plugin"),t(U,"parameters",[["plugin","Plugin to install"]]);var Y=i(new class{run(t){const i=new e;i.name("ag").description("AerogelJS CLI").version("0.0.0"),B.define(i),W.define(i),H.define(i),R.define(i),U.define(i),i.parse(t)}});export{Y as CLI};
|
|
1
|
+
import{Command as e}from"commander";import t from"@babel/runtime/helpers/esm/defineProperty";import{resolve as s,dirname as i,basename as n}from"path";import{facade as a,stringMatchAll as o,toString as r,stringMatch as c,arrayFrom as l,stringToSlug as p,stringToTitleCase as d,stringToStudlyCase as u,formatCodeBlock as m,stringToCamelCase as g}from"@noeldemartin/utils";import"core-js/modules/esnext.async-iterator.reduce.js";import"core-js/modules/esnext.iterator.constructor.js";import"core-js/modules/esnext.iterator.reduce.js";import{existsSync as h,lstatSync as f,readFileSync as y,readdirSync as v,mkdirSync as w,writeFileSync as j}from"fs";import"core-js/modules/esnext.async-iterator.for-each.js";import"core-js/modules/esnext.iterator.for-each.js";import"core-js/modules/esnext.async-iterator.find.js";import"core-js/modules/esnext.iterator.find.js";import"core-js/modules/esnext.async-iterator.map.js";import"core-js/modules/esnext.iterator.map.js";import{hex as x,bold as k}from"chalk";import{cursorTo as C,clearLine as S}from"readline";import{render as $}from"mustache";import"core-js/modules/esnext.set.add-all.js";import"core-js/modules/esnext.set.delete-all.js";import"core-js/modules/esnext.set.difference.js";import"core-js/modules/esnext.set.every.js";import"core-js/modules/esnext.set.filter.js";import"core-js/modules/esnext.set.find.js";import"core-js/modules/esnext.set.intersection.js";import"core-js/modules/esnext.set.is-disjoint-from.js";import"core-js/modules/esnext.set.is-subset-of.js";import"core-js/modules/esnext.set.is-superset-of.js";import"core-js/modules/esnext.set.join.js";import"core-js/modules/esnext.set.map.js";import"core-js/modules/esnext.set.reduce.js";import"core-js/modules/esnext.set.some.js";import"core-js/modules/esnext.set.symmetric-difference.js";import"core-js/modules/esnext.set.union.js";import{Project as P,SyntaxKind as F,Node as D}from"ts-morph";import{exec as b}from"child_process";import"core-js/modules/esnext.async-iterator.some.js";import"core-js/modules/esnext.iterator.some.js";var I=a(new class{contains(e,t){return!!this.read(e)?.includes(t)}exists(e){return h(e)}isSymlink(e){return f(e).isSymbolicLink()}read(e){return this.isFile(e)?y(e).toString():null}getFiles(e){const t=v(e,{withFileTypes:!0}),i=[];for(const n of t){const t=s(e,n.name);n.isDirectory()?i.push(...this.getFiles(t)):i.push(t)}return i}isDirectory(e){return this.exists(e)&&f(e).isDirectory()}isFile(e){return this.exists(e)&&f(e).isFile()}isEmptyDirectory(e){return!!this.isDirectory(e)&&0===this.getFiles(e).length}makeDirectory(e){w(e,{recursive:!0})}write(e,t){h(i(e))||w(i(e),{recursive:!0}),j(e,t)}});var A=a(new class{constructor(){t(this,"renderInfo",x("#00ffff")),t(this,"renderSuccess",x("#00ff00")),t(this,"renderError",x("#ff0000"))}async animate(e,t){var s=this;const i=function(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",i=arguments.length>1&&void 0!==arguments[1]&&arguments[1];const a=s.renderInfo(s.renderMarkdown(e)+(i?"...":".".repeat(n%4)))+t;s.stdout(a)};let n=0;i();const a=setInterval((()=>(n++,i())),1e3),o=await t();return clearInterval(a),i("\n",!0),o}info(e){this.log(this.renderMarkdown(e),this.renderInfo)}error(e){this.log(this.renderMarkdown(e),this.renderError)}fail(e){this.error(e),process.exit(1)}success(e){this.log(this.renderMarkdown(e),this.renderSuccess)}renderMarkdown(e){const t=o(e,/\*\*(.*)\*\*/g);for(const s of t)e=e.replace(s[0],k(s[1]));return e}log(e,t){this.formatMessage(e).forEach((e=>{this.logLine(t?t(e):e)}))}formatMessage(e){if("\n"===e[0]){const t=(e=e.slice(1).trimEnd()).split("\n"),s=e.trim()[0]??"",i=t.find((e=>e.trim().length>0))?.indexOf(s)??0;return t.map((e=>e.slice(i)))}return[e]}logLine(e){console.log(e)}stdout(e){C(process.stdout,0),S(process.stdout,0),process.stdout.write(e)}});class N{static instantiate(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"./",s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return new N(e).instantiate(t,s)}constructor(e){t(this,"path",void 0),this.path=e}instantiate(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const s=this.getFilenameReplacements(t),i=[];e=`${e}/`.replace(/\/\//,"/");for(const n of I.getFiles(this.path)){const a=Object.entries(s).reduce(((e,t)=>{let[s,i]=t;return e.replaceAll(s,i)}),n.substring(this.path.length+1)),o=y(n).toString(),r=e+(a.endsWith(".template")?a.slice(0,-9):a);I.write(r,$(o,t,void 0,["<%","%>"])),i.push(r)}return i}getFilenameReplacements(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return Object.entries(e).reduce(((e,s)=>{let[i,n]=s;return"object"==typeof n?Object.assign(e,this.getFilenameReplacements(n,`${i}.`)):e[`[${t}${i}]`]=r(n),e}),{})}}function E(e){return A.fail(`Could not find ${e} pack file, did you run 'npm pack'?`)}function O(e){return I.getFiles(L(e)).find((e=>e.endsWith(".tgz")))??null}function L(e){return function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";if(I.contains(s(__dirname,"../../../package.json"),'"name": "aerogel"'))return s(__dirname,"../",e);const t=I.read(s(__dirname,"../../../../package.json")),i=c(t??"",/"@aerogel\/core": "file:(.*)\/aerogel-core-[\d.]*\.tgz"/),n=i?.[1]??A.fail("Could not determine base path");return s(n,e)}(`../${e}`)}function T(e){return s(__dirname,`../templates/${e}`)}var M=a(new class{constructor(){t(this,"cwd",null)}setWorkingDirectory(e){this.cwd=e}async run(e){await new Promise(((t,s)=>{b(e,{cwd:this.cwd??void 0},(e=>{e?s(e):t()}))}))}});class _{constructor(){t(this,"project",void 0),t(this,"modifiedFiles",void 0),this.project=new P({tsConfigFilePath:"tsconfig.json"}),this.modifiedFiles=new Set,this.project.addSourceFilesAtPaths("src/**/*.ts"),this.project.addSourceFilesAtPaths("tailwind.config.js"),this.project.addSourceFilesAtPaths("vite.config.ts"),this.project.addSourceFilesAtPaths("package.json")}addSourceFile(e){this.project.addSourceFilesAtPaths(e)}requireSourceFile(e){return this.project.getSourceFileOrThrow(e)}async format(){await A.animate("Formatting modified files",(async()=>{const e=I.exists("prettier.config.js")||I.contains("package.json",'"prettier": {'),t=I.exists(".eslintrc.js")||I.contains("package.json",'"eslintConfig"'),s=I.contains("package.json",'"prettier-eslint-cli"')?e=>M.run(`npx prettier-eslint ${e} --write`):async s=>{e&&await M.run(`npx prettier ${s} --write`),s.match(/\.(ts|js|vue)$/)&&t&&await M.run(`npx eslint ${s} --fix`)};await Promise.all(l(this.modifiedFiles).map((async e=>s(e))))}))}async save(e){await e.save(),this.addModifiedFile(e.getFilePath())}addModifiedFile(e){this.modifiedFiles.add(e)}}class z{constructor(e){let s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};t(this,"name",void 0),t(this,"options",void 0),this.name=e,this.options=s}create(e){!I.exists(e)||I.isDirectory(e)&&I.isEmptyDirectory(e)||A.fail(`Folder at '${e}' already exists!`),N.instantiate(T("app"),e,{app:{name:this.name,slug:p(this.name)},dependencies:this.getDependencies(),contentPath:this.options.linkedLocal?`${L("core")}/dist/**/*.js`:"./node_modules/@aerogel/core/dist/**/*.js"})}edit(){return new _}getDependencies(){const e=e=>Object.entries(e).reduce(((e,t)=>{let[s,i]=t;return Object.assign(e,{[s]:`file:${i}`})}),{});return this.options.linkedLocal?e({aerogelCli:L("cli"),aerogelCore:L("core"),aerogelCypress:L("cypress"),aerogelPluginI18n:L("plugin-i18n"),aerogelPluginSoukai:L("plugin-soukai"),aerogelVite:L("vite")}):this.options.local?e({aerogelCli:O("cli")??E("cli"),aerogelCore:O("core")??E("core"),aerogelCypress:O("cypress")??E("cypress"),aerogelPluginI18n:O("plugin-i18n")??E("plugin-i18n"),aerogelPluginSoukai:O("plugin-soukai")??E("plugin-soukai"),aerogelVite:O("vite")??E("vite")}):{aerogelCli:"next",aerogelCore:"next",aerogelCypress:"next",aerogelPluginI18n:"next",aerogelPluginSoukai:"next",aerogelVite:"next"}}}class B{static define(e){var t=this;e=e.command(this.command).description(this.description);for(const[t,s]of this.parameters)e=e.argument(`<${t}>`,s);for(const[t,s]of Object.entries(this.options)){const i="string"==typeof s?s:s.description,n="string"==typeof s?"string":s.type??"string";e=e.option("boolean"===n?`--${t}`:`--${t} <${n}>`,i)}e=e.action((function(){for(var e=arguments.length,s=new Array(e),i=0;i<e;i++)s[i]=arguments[i];return t.run.call(t,...s)}))}static async run(){for(var e=arguments.length,t=new Array(e),s=0;s<e;s++)t[s]=arguments[s];const i=new this(...t);await i.validate(),await i.run()}async validate(){}async run(){}assertAerogelOrDirectory(e){const t=I.read("package.json");if(t?.includes("@aerogel/core"))return;if(e&&I.isDirectory(e))return;const s=e?`${e} folder does not exist.`:"package.json does not contain @aerogel/core.";A.fail(`${s} Are you sure this is an Aerogel app?`)}}t(B,"command",""),t(B,"description",""),t(B,"parameters",[]),t(B,"options",{});class q extends B{constructor(e){let s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(),t(this,"path",void 0),t(this,"options",void 0),this.path=e,this.options=s}async run(){const e=this.path,t=this.options.name??d(n(e));M.setWorkingDirectory(e),await this.createApp(t,e),await this.installDependencies(),await this.initializeGit(),A.success(`\n\n That's it! You can start working on **${t}** doing the following:\n\n cd ${e}\n npm run dev\n\n Have fun!\n `)}async createApp(e,t){A.info(`Creating **${e}**...`),new z(e,{local:this.options.local,linkedLocal:this.options.local&&!this.options.copy}).create(t)}async installDependencies(){await A.animate("Installing dependencies",(async()=>{await M.run("npm install")}))}async initializeGit(){await A.animate("Initializing git",(async()=>{await M.run("git init"),await M.run("git add ."),await M.run('git commit -m "Start"')}))}}function G(){return new z("")}function J(){return I.isSymlink("node_modules/@aerogel/core")}function W(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!e)return;const s=t.guard??(()=>!0),i=t.validate??(()=>!0),n=l(t.skip??[]);return e.forEachDescendant(((e,t)=>{if(s(e)&&i(e))return e;const a=e.getKind();n.includes(a)&&t.skip()}))}function H(e,t){if(e&&t(e))return e}t(q,"command","create"),t(q,"description","Create AerogelJS app"),t(q,"parameters",[["path","Application path"]]),t(q,"options",{name:"Application name",local:{type:"boolean",description:"Whether to create an app using local Aerogel packages (used for core development)"},copy:{type:"boolean",description:"Whether to create an app linked to local Aerogel packages (used in CI)"}});class U extends B{constructor(e){let s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(),t(this,"path",void 0),t(this,"options",void 0),this.path=e,this.options=s}async validate(){this.options.button&&this.options.input&&A.fail("Cannot use both 'button' and 'input' flags!")}async run(){this.assertAerogelOrDirectory("src/components"),this.assertHistoireInstalled();const e=new Set,[t,s]=this.parsePathComponents();await this.createComponent(t,s,e),await this.createStory(t,s,e),await this.declareComponents();const i=l(e).map((e=>`- ${e}`)).join("\n");A.info(`${s} component created successfully! The following files were created:\n\n${i}`)}assertHistoireInstalled(){this.options.story&&(I.contains("package.json",'"histoire"')||I.contains("package.json",'"@aerogel/histoire"')||A.fail("\n Histoire is not installed yet! You can install it running:\n npx gel install histoire\n "))}async createComponent(e,t,s){await A.animate("Creating component",(async()=>{I.exists(`src/components/${this.path}.vue`)&&A.fail(`${this.path} component already exists!`);const i=this.options.input?"component-input":this.options.button?"component-button":"component";N.instantiate(T(i),`src/components/${e}`,{component:{name:t,slug:p(t)}}).forEach((e=>s.add(e)))}))}async createStory(e,t,s){this.options.story&&await A.animate("Creating story",(async()=>{const i=this.options.input?"component-input-story":this.options.button?"component-button-story":"component-story";N.instantiate(T(i),`src/components/${e}`,{component:{name:t,slug:p(t)}}).forEach((e=>s.add(e)))}))}async declareComponents(){const e=G().edit(),t=e.requireSourceFile("vite.config.ts"),s=this.getComponentDirsArray(t);if(!s)return A.fail("Could not find component dirs declaration in vite config!");s.getDescendantsOfKind(F.StringLiteral).some((e=>"'src/components'"===e.getText()))||(await A.animate("Updating vite config",(async()=>{s.addElement("'src/components'"),await e.save(t)})),await e.format())}getComponentDirsArray(e){const t=W(e,{guard:D.isCallExpression,validate:e=>e.getText().startsWith("Components("),skip:F.ImportDeclaration});if(!t)return null;const s=W(t,{guard:D.isPropertyAssignment,validate:e=>"dirs"===e.getName()}),i=s?.getInitializer();return D.isArrayLiteralExpression(i)?i:this.declareComponentDirsArray(t)}declareComponentDirsArray(e){const t=W(e,{guard:D.isObjectLiteralExpression}),s=t?.addPropertyAssignment({name:"dirs",initializer:"[]"});return s?.getInitializer()??null}parsePathComponents(){const e=this.path.lastIndexOf("/");return-1===e?["",this.path]:[this.path.substring(0,e),this.path.substring(e+1)]}}t(U,"command","generate:component"),t(U,"description","Generate an AerogelJS Component"),t(U,"parameters",[["path","Component path (relative to components folder; extension not necessary)"]]),t(U,"options",{button:{description:"Create a custom button",type:"boolean"},input:{description:"Create a custom input",type:"boolean"},story:{description:"Create component story using Histoire",type:"boolean"}});class R extends B{constructor(e){let s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(),t(this,"name",void 0),t(this,"options",void 0),this.name=e,this.options=s}async run(){this.assertAerogelOrDirectory("src/models"),I.exists(`src/models/${this.name}.ts`)&&A.fail(`${this.name} model already exists!`),this.assertSoukaiInstalled();const e=await A.animate("Creating model",(async()=>N.instantiate(T("model"),"src/models",{model:{name:this.name,fieldsDefinition:this.getFieldsDefinition()},soukaiImports:this.options.fields?"FieldType, defineModelSchema":"defineModelSchema"}).map((e=>`- ${e}`)).join("\n")));A.info(`${this.name} model created successfully! The following files were created:\n\n${e}`)}getFieldsDefinition(){if(!this.options.fields)return" //";const e=this.options.fields.split(",").map((e=>{const[t,s,i]=e.split(":");return{name:t,type:u(s??"string"),required:"required"===i}})).reduce(((e,t)=>e+`\n${t.required?m(`\n ${t.name}: {\n type: FieldType.${t.type},\n required: true,\n }\n `):`${t.name}: FieldType.${t.type}`},`),"");return m(e,{indent:8})}assertSoukaiInstalled(){I.contains("package.json",'"soukai"')||I.contains("package.json",'"@aerogel/plugin-soukai"')||A.fail("\n Soukai is not installed yet! You can install it running:\n npx gel install soukai\n ")}}t(R,"command","generate:model"),t(R,"description","Generate an AerogelJS Model"),t(R,"parameters",[["name","Model name"]]),t(R,"options",{fields:"Create model with the given fields"});class V extends B{constructor(e){super(),t(this,"name",void 0),this.name=e}async run(){this.assertAerogelOrDirectory("src/services");const e=new Set,t=G().edit();await this.createService(e),await this.registerService(t),await t.format();const s=l(e).map((e=>`- ${e}`)).join("\n");A.info(`${this.name} service created successfully! The following files were created:\n\n${s}`)}async createService(e){await A.animate("Creating service",(async()=>{I.exists(`src/services/${this.name}.ts`)&&A.fail(`${this.name} service already exists!`);N.instantiate(T("service"),"src/services",{service:{name:this.name}}).forEach((t=>e.add(t)))}))}async registerService(e){await A.animate("Registering service",(async()=>{I.exists("src/services/index.ts")||await this.createServicesIndex(e);const t=e.requireSourceFile("src/services/index.ts"),s=this.getServicesObject(t);if(!s)return A.fail("Could not find services object in services config, please add it manually.");t.addImportDeclaration({defaultImport:this.name,moduleSpecifier:`./${this.name}`}),s.addPropertyAssignment({name:`$${g(this.name)}`,initializer:this.name}),await e.save(t)}))}async createServicesIndex(e){I.write("src/services/index.ts",m("\n export const services = {};\n\n export type AppServices = typeof services;\n\n declare module '@vue/runtime-core' {\n interface ComponentCustomProperties extends AppServices {}\n }\n ")),e.addSourceFile("src/services/index.ts");const t=e.requireSourceFile("src/main.ts"),s=this.getBootstrapOptions(t);if(!s)return A.fail("Could not find options object in bootstrap config, please add the services manually.");s.insertShorthandPropertyAssignment(0,{name:"services"}),t.addImportDeclaration({namedImports:["services"],moduleSpecifier:"./services"}),await e.save(t)}getBootstrapOptions(e){const t=W(e,{guard:D.isCallExpression,validate:e=>"bootstrapApplication"===e.getExpression().getText(),skip:F.ImportDeclaration}),s=t?.getArguments()[1];return D.isObjectLiteralExpression(s)?s:null}getServicesObject(e){const t=W(e,{guard:D.isVariableDeclaration,validate:e=>"services"===e.getName()}),s=t?.getInitializer();return D.isObjectLiteralExpression(s)?s:null}}t(V,"command","generate:service"),t(V,"description","Generate an AerogelJS Service"),t(V,"parameters",[["name","Service name"]]);class Y{constructor(e){t(this,"name",void 0),this.name=e}async install(){this.assertNotInstalled(),await this.beforeInstall(),await this.installDependencies();{const e=G().edit();await this.updateFiles(e),await e.format()}await this.afterInstall(),A.info(`Plugin ${this.name} installed!`)}assertNotInstalled(){I.contains("package.json",`"${this.getNpmPackageName()}"`)&&A.fail(`${this.name} is already installed!`)}async beforeInstall(){}async afterInstall(){}async installDependencies(){await A.animate("Installing plugin dependencies",(async()=>{await this.installNpmDependencies()}))}async updateFiles(e){this.isForDevelopment()||await this.updateBootstrapConfig(e)}async installNpmDependencies(){const e=this.isForDevelopment()?"--save-dev":"";if(J())await M.run(`npm install file:${L(this.getLocalPackageName())} ${e}`);else if(I.contains("package.json",'"@aerogel/core": "file:')){const t=O(this.getLocalPackageName())??E(this.getLocalPackageName());await M.run(`npm install file:${t} ${e}`)}else await M.run(`npm install ${this.getNpmPackageName()}@next --save-exact ${e}`)}async updateBootstrapConfig(e){await A.animate("Injecting plugin in bootstrap configuration",(async()=>{const t=e.requireSourceFile("src/main.ts"),s=this.getBootstrapPluginsDeclaration(t);if(!s)return A.fail(`\n Could not find plugins array in bootstrap config, please add the following manually:\n\n ${this.getBootstrapConfig()}\n `);t.addImportDeclaration(this.getBootstrapImport()),s.addElement(this.getBootstrapConfig()),await e.save(t)}))}async updateTailwindConfig(e,t){await A.animate("Updating tailwind configuration",(async()=>{const s=e.requireSourceFile("tailwind.config.js"),i=this.getTailwindContentArray(s);if(!i)return A.fail(`\n Could not find content array in tailwind config, please add the following manually:\n\n ${t.content}\n `);i.addElement(t.content),await e.save(s)}))}getBootstrapPluginsDeclaration(e){const t=W(e,{guard:D.isCallExpression,validate:e=>"bootstrapApplication"===e.getExpression().getText(),skip:F.ImportDeclaration}),s=t?.getArguments()[1],i=H(s,D.isObjectLiteralExpression)?.getProperty("plugins"),n=H(i,D.isPropertyAssignment)?.getInitializer();return D.isArrayLiteralExpression(n)?n:null}getTailwindContentArray(e){const t=W(e,{guard:D.isPropertyAssignment,validate:e=>"content"===e.getName(),skip:F.JSDoc}),s=t?.getInitializer();return D.isArrayLiteralExpression(s)?s:null}getBootstrapImport(){return{defaultImport:this.name,moduleSpecifier:`@aerogel/plugin-${this.name}`}}getNpmPackageName(){return`@aerogel/${this.getLocalPackageName()}`}getLocalPackageName(){return`plugin-${this.name}`}isForDevelopment(){return!1}getBootstrapConfig(){return`${this.name}()`}}const K=[new class extends Y{constructor(){super("soukai")}async installNpmDependencies(){await M.run("npm install soukai@next --save-exact"),await super.installNpmDependencies()}getBootstrapConfig(){return"soukai({ models: import.meta.glob('@/models/*', { eager: true }) })"}},new class extends Y{constructor(){super("solid")}async updateFiles(e){await this.updateTailwindConfig(e,{content:J()?`'${L("plugin-solid")}/dist/**/*.js'`:"'./node_modules/@aerogel/plugin-solid/dist/**/*.js'"}),await this.updateNpmScripts(e),await this.updateGitIgnore(),await super.updateFiles(e)}async installNpmDependencies(){await M.run("npm install soukai-solid@next --save-exact"),await M.run("npm install @solid/community-server@7 --save"),await super.installNpmDependencies()}async updateNpmScripts(e){A.info("Updating npm scripts...");const t=I.read("package.json");if(!t)return A.fail("Could not find package.json file");I.write("package.json",t.replace('"cy:dev": "concurrently --kill-others \\"npm run test:serve-app\\" \\"npm run cy:open\\"",','"cy:dev": "concurrently --kill-others \\"npm run test:serve-app\\" \\"npm run test:serve-pod\\" \\"npm run cy:open\\"",').replace('"cy:test": "start-server-and-test test:serve-app http-get://localhost:5001 cy:run",','"cy:test": "start-server-and-test test:serve-app http-get://localhost:5001 test:serve-pod http-get://localhost:4000 cy:run",').replace('"dev": "vite",','"dev": "vite",\n"dev:serve-pod": "community-solid-server -c @css:config/file.json -p 4000 -f ./solid-data",').replace('"test:serve-app": "vite --port 5001"','"test:serve-app": "vite --port 5001",\n"test:serve-pod": "community-solid-server -p 4000 -l warn"')),e.addModifiedFile("package.json")}async updateGitIgnore(){A.info("Updating .gitignore");const e=I.read(".gitignore")??"";I.write(".gitignore",`${e}/solid-data\n`)}},new class extends Y{constructor(){super("histoire"),t(this,"installedPatchPackage",!1),t(this,"installedPostCSSPseudoClasses",!1)}async beforeInstall(){this.installedPatchPackage=!1,this.installedPostCSSPseudoClasses=!1}async afterInstall(){this.installedPatchPackage&&await A.animate("Patching dependencies",(async()=>{await M.run("npx patch-package")}))}async updateFiles(e){await this.updateTailwindConfig(e,{content:J()?`'${L("histoire")}/dist/**/*.js'`:"'./node_modules/@aerogel/histoire/dist/**/*.js'"}),await this.updateNpmScripts(e),await this.createConfigFiles(),await super.updateFiles(e)}async installNpmDependencies(){await M.run("npm install histoire@0.17.6 --save-dev"),I.contains("package.json",'"patch-package"')||(await M.run("npm install patch-package --save-dev"),this.installedPatchPackage=!0),I.contains("package.json",'"postcss-pseudo-classes"')||(await M.run("npm install postcss-pseudo-classes --save-dev"),this.installedPostCSSPseudoClasses=!0),await super.installNpmDependencies()}getLocalPackageName(){return this.name}async updateNpmScripts(e){A.info("Updating npm scripts...");const t=I.read("package.json");if(!t)return A.fail("Could not find package.json file");I.write("package.json",t.replace('"lint": "noeldemartin-lint src",',this.installedPatchPackage?'"histoire": "histoire dev", "lint": "noeldemartin-lint src", "postinstall": "patch-package",':'"histoire": "histoire dev", "lint": "noeldemartin-lint src",')),e.addModifiedFile("package.json")}async createConfigFiles(){A.info("Creating config files..."),N.instantiate(T("histoire")),this.installedPostCSSPseudoClasses&&N.instantiate(T("postcss-pseudo-classes"))}isForDevelopment(){return!0}}].reduce(((e,t)=>Object.assign(e,{[t.name]:t})),{});class Q extends B{constructor(e){super(),t(this,"plugin",void 0),this.plugin=K[e]??A.fail(`Plugin '${e}' doesn't exist. Available plugins: ${Object.keys(K).join(", ")}`)}async run(){await this.plugin.install()}}t(Q,"command","install"),t(Q,"description","Install an AerogelJS plugin"),t(Q,"parameters",[["plugin","Plugin to install"]]);var X=a(new class{run(t){const s=new e;s.name("ag").description("AerogelJS CLI").version("0.0.0"),q.define(s),U.define(s),R.define(s),V.define(s),Q.define(s),s.parse(t)}});export{X as CLI};
|
|
2
2
|
//# sourceMappingURL=aerogel-cli.esm.js.map
|