@sundaysf/cli-v2 1.0.5 → 1.0.6

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/bin/index.js CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import{Command}from"commander";import inquirer from"inquirer";import{generateController,generateRouter}from"./generators/class.js";import fs from"fs-extra";import path from"path";import{fileURLToPath}from"url";import{exec}from"child_process";import ora from"ora";import{generateBasePostman,getItemFormatted}from"./generators/postman.js";const __dirname=path.dirname(fileURLToPath(import.meta.url)),pkg=fs.readJsonSync(path.join(__dirname,"../../package.json")),program=new Command;program.version(pkg.version,"-v, --version").option("--init","Initialize a new project").option("--backend","Initialize with backend template").option("--module","Initialize with module template").option("--db-sql","Initialize with db-sql template").option("--backend-db-sql","Initialize with backend + database template (separate db module)").option("--backend-embedded-db-sql","Initialize with backend + embedded database template (single project)").option("--frontend-nextjs","Initialize with Next.js frontend template (shadcn/ui + Tailwind)").option("--create-controller","Create a controller and its associated route"),program.parse(process.argv);const options=program.opts();function runFormatter(e="."){return new Promise(((t,r)=>{const s=exec("npm run format",{cwd:e});s.stdout.on("data",(e=>process.stdout.write(e))),s.stderr.on("data",(e=>process.stderr.write(e))),s.on("close",(e=>{0===e?t():r(new Error(`npm format exited with code ${e}`))}))}))}function runNpmInstall(e){return new Promise(((t,r)=>{const s=exec("npm install",{cwd:e});s.stdout.on("data",(e=>process.stdout.write(e))),s.stderr.on("data",(e=>process.stderr.write(e))),s.on("close",(e=>{0===e?t():r(new Error(`npm install exited with code ${e}`))}))}))}function initGitRepo(e){return new Promise(((t,r)=>{const s=exec("git init",{cwd:e});s.stdout.on("data",(e=>process.stdout.write(e))),s.stderr.on("data",(e=>process.stderr.write(e))),s.on("close",(e=>{0===e?t():r(new Error(`Git init exited with code ${e}`))}))}))}options.init&&(options.backend||options.module||options.dbSql||options.backendDbSql||options.backendEmbeddedDbSql||options.frontendNextjs)?(console.log("Hello! I'm Paul Sundays, your backend architect. Let's craft an awesome backend together!"),inquirer.prompt([{type:"input",name:"projectName",message:"Name of the project:",validate:e=>!!e||"The name of the project can not be empty"}]).then((async({projectName:e})=>{const t=options.backend?"backend":options.backendEmbeddedDbSql?"backend-embedded-db-sql":options.backendDbSql?"backend-db-sql":options.frontendNextjs?"frontend-nextjs":options.module?"module":"db-sql",r=path.join(__dirname,`../templates/${t}`);let s,n,i;"."===e?(s=path.resolve("."),n=path.basename(s),fs.existsSync(path.join(s,"package.json"))&&(console.error("A package.json already exists in the current directory."),process.exit(1))):(n=e.toLowerCase().replace(/\s+/g,"-"),s=path.resolve(n),fs.existsSync(s)&&(console.error(`Directory "${n}" already exists.`),process.exit(1)),await fs.mkdir(s,{recursive:!0}));try{await fs.copy(r,s,{overwrite:!1,errorOnExist:!0,filter:(e,t)=>!0}),console.log("Template files copied successfully")}catch(e){console.error("Error copying the files:",e),process.exit(1)}if(i="db-sql"===t?{name:n,version:"0.0.1",description:"Knex Module",main:"dist/index.js",scripts:{test:"jest",format:"prettier --write .",build:"tsc",clean:"rimraf dist && npm run format && npm run build","npm:publish":"npm run clean && npm publish","migrate:create":"knex migrate:make migration -x ts","migrate:deploy":"knex migrate:latest","seed:create":"knex seed:make seed -x ts","seed:run":"knex seed:run"},repository:{type:"git",url:""},author:"",license:"MIT",bugs:{url:""},homepage:"",devDependencies:{"@eslint/js":"^9.23.0","@types/node":"^22.13.13",eslint:"^9.23.0",globals:"^16.0.0",prettier:"^3.5.3",rimraf:"^6.0.1","ts-node":"^10.9.2",typescript:"^5.8.2","typescript-eslint":"^8.28.0"},dependencies:{dotenv:"^16.4.7",knex:"^3.1.0",lodash:"^4.17.21",pg:"^8.14.1",uuid:"^11.1.0"}}:"backend"===t?{name:n,version:"1.0.0",description:"Backend project generated with Sundays Framework",main:"dist/server.js",scripts:{test:"jest",start:"node dist/server.js",build:"tsc","start:dev":"nodemon src/server.ts",format:"prettier --write .","create:controller":"sundaysf --create-controller"},dependencies:{morgan:"^1.10.0",cors:"^2.8.5",dotenv:"^16.4.7",express:"^4.18.2"},devDependencies:{"@types/morgan":"^1.9.9","@types/cors":"^2.8.17","@types/express":"^4.17.21",nodemon:"^3.0.2",prettier:"^3.5.3","ts-node":"^10.9.2",typescript:"^5.8.2","@eslint/js":"^9.23.0",eslint:"^9.23.0","typescript-eslint":"^8.28.0"},author:"",license:"MIT"}:"backend-db-sql"===t?{name:n,version:"1.0.0",description:"Backend project with database module generated with Sundays Framework",main:"dist/server.js",scripts:{test:"jest",start:"node dist/server.js",build:"tsc","start:dev":"nodemon src/server.ts",format:"prettier --write .","create:controller":"sundaysf --create-controller","migrate:create":"knex migrate:make migration -x ts --knexfile db/knexfile.ts","migrate:deploy":"knex migrate:latest --knexfile db/knexfile.ts","seed:create":"knex seed:make seed -x ts --knexfile db/knexfile.ts","seed:run":"knex seed:run --knexfile db/knexfile.ts","db:build":"tsc -p db/tsconfig.json","db:publish":"cd db && npm publish"},dependencies:{morgan:"^1.10.0",cors:"^2.8.5",dotenv:"^16.4.7",express:"^4.18.2",knex:"^3.1.0",lodash:"^4.17.21",pg:"^8.14.1",uuid:"^11.1.0"},devDependencies:{"@types/morgan":"^1.9.9","@types/cors":"^2.8.17","@types/express":"^4.17.21","@types/lodash":"^4.17.16","@types/node":"^22.13.13",nodemon:"^3.0.2",prettier:"^3.5.3",rimraf:"^6.0.1","ts-node":"^10.9.2",typescript:"^5.8.2","@eslint/js":"^9.23.0",eslint:"^9.23.0",globals:"^16.0.0","typescript-eslint":"^8.28.0"},author:"",license:"MIT"}:"backend-embedded-db-sql"===t?{name:n,version:"1.0.0",description:"Backend project with embedded database generated with Sundays Framework",main:"dist/server.js",scripts:{test:"jest",start:"node dist/server.js",build:"tsc","start:dev":"nodemon src/server.ts",format:"prettier --write .","create:controller":"sundaysf --create-controller","db:migrate":"npx knex migrate:latest --knexfile knexfile.ts","db:rollback":"npx knex migrate:rollback --knexfile knexfile.ts","db:seed":"npx knex seed:run --knexfile knexfile.ts","db:make-migration":"npx knex migrate:make --knexfile knexfile.ts -x ts"},dependencies:{morgan:"^1.10.0",cors:"^2.8.5",dotenv:"^16.4.7",express:"^4.18.2",knex:"^3.1.0",lodash:"^4.17.21",pg:"^8.14.1",uuid:"^11.1.0"},devDependencies:{"@types/morgan":"^1.9.9","@types/cors":"^2.8.17","@types/express":"^4.17.21","@types/lodash":"^4.17.16","@types/node":"^22.13.13",nodemon:"^3.0.2",prettier:"^3.5.3",rimraf:"^6.0.1","ts-node":"^10.9.2",typescript:"^5.8.2","@eslint/js":"^9.23.0",eslint:"^9.23.0",globals:"^16.0.0","typescript-eslint":"^8.28.0"},author:"",license:"MIT"}:"frontend-nextjs"===t?{name:n,version:"0.1.0",private:!0,scripts:{dev:"next dev",build:"next build",start:"next start",lint:"eslint ."},dependencies:{"@hookform/resolvers":"^3.9.1","@radix-ui/react-accordion":"1.2.12","@radix-ui/react-alert-dialog":"1.1.15","@radix-ui/react-aspect-ratio":"1.1.8","@radix-ui/react-avatar":"1.1.11","@radix-ui/react-checkbox":"1.3.3","@radix-ui/react-collapsible":"1.1.12","@radix-ui/react-context-menu":"2.2.16","@radix-ui/react-dialog":"1.1.15","@radix-ui/react-dropdown-menu":"2.1.16","@radix-ui/react-hover-card":"1.1.15","@radix-ui/react-label":"2.1.8","@radix-ui/react-menubar":"1.1.16","@radix-ui/react-navigation-menu":"1.2.14","@radix-ui/react-popover":"1.1.15","@radix-ui/react-progress":"1.1.8","@radix-ui/react-radio-group":"1.3.8","@radix-ui/react-scroll-area":"1.2.10","@radix-ui/react-select":"2.2.6","@radix-ui/react-separator":"1.1.8","@radix-ui/react-slider":"1.3.6","@radix-ui/react-slot":"1.2.4","@radix-ui/react-switch":"1.2.6","@radix-ui/react-tabs":"1.1.13","@radix-ui/react-toast":"1.2.15","@radix-ui/react-toggle":"1.1.10","@radix-ui/react-toggle-group":"1.1.11","@radix-ui/react-tooltip":"1.2.8",autoprefixer:"^10.4.20","class-variance-authority":"^0.7.1",clsx:"^2.1.1",cmdk:"1.1.1","date-fns":"4.1.0","embla-carousel-react":"8.6.0","framer-motion":"^12.38.0","input-otp":"1.4.2","lucide-react":"^0.564.0",next:"16.1.6","next-themes":"^0.4.6",react:"19.2.4","react-day-picker":"9.13.2","react-dom":"19.2.4","react-hook-form":"^7.54.1","react-resizable-panels":"^2.1.7",recharts:"2.15.0",sonner:"^1.7.1","tailwind-merge":"^3.3.1",vaul:"^1.1.2",zod:"^3.24.1"},devDependencies:{"@tailwindcss/postcss":"^4.2.0","@types/node":"^22","@types/react":"19.2.14","@types/react-dom":"19.2.3",postcss:"^8.5",tailwindcss:"^4.2.0","tw-animate-css":"1.3.3",typescript:"5.7.3"}}:{name:n,version:"1.0.0",description:"Module generated with Sundays Framework",main:"dist/index.js",types:"dist/index.d.ts",scripts:{test:"jest",build:"tsc",format:"prettier --write .",clean:"rimraf dist && npm run build"},dependencies:{},devDependencies:{prettier:"^3.5.3",rimraf:"^6.0.1",typescript:"^5.8.2"},author:"",license:"MIT"},await fs.writeJson(path.join(s,"package.json"),i,{spaces:2}),["backend","backend-db-sql","backend-embedded-db-sql"].includes(t)){const t=generateBasePostman(e);await fs.writeJson(path.join(s,"postman.json"),t,{spaces:2})}if("backend-db-sql"===t){const e={name:`${n}-db`,version:"0.0.1",description:"Database module",main:"dist/index.js",types:"dist/index.d.ts",scripts:{build:"tsc",clean:"rimraf dist && npm run build",format:"prettier --write .","npm:publish":"npm run clean && npm publish","migrate:create":"knex migrate:make migration -x ts","migrate:deploy":"knex migrate:latest","seed:create":"knex seed:make seed -x ts","seed:run":"knex seed:run"},dependencies:{dotenv:"^16.4.7",knex:"^3.1.0",lodash:"^4.17.21",pg:"^8.14.1",uuid:"^11.1.0"},devDependencies:{typescript:"^5.8.2","ts-node":"^10.9.2",rimraf:"^6.0.1",prettier:"^3.5.3","@types/node":"^22.13.13"}};await fs.writeJson(path.join(s,"db/package.json"),e,{spaces:2})}const a=ora("Git init...").start();await initGitRepo(s),a.succeed("Git initialized");const o=ora("Installing dependencies...").start();await runNpmInstall(s),o.succeed("Dependencies installed"),await runFormatter(s);const d="."===e?"Project created successfully in current directory":`Project '${e}' created successfully in ./${n}`;console.log(d)}))):options.createController?(fs.existsSync("./src/controllers")&&fs.existsSync("./postman.json")||(console.error("This command must be run inside a Sundays backend project."),console.error("Expected ./src/controllers/ and ./postman.json to exist."),process.exit(1)),inquirer.prompt([{type:"input",name:"controllerName",message:"Controller name:",validate:e=>e?!!/^[a-zA-Z][a-zA-Z0-9]*$/.test(e)||"Name must start with a letter and contain only letters and numbers":"The controller name is empty"}]).then((async({controllerName:e})=>{try{const t=e.charAt(0).toLowerCase()+e.slice(1),r=e.charAt(0).toUpperCase()+e.slice(1),s=`${r}Controller`,n=`${t}.controller.ts`,i=`${t}`,a=`${r}Router`,o=`${t}.router.ts`,d=`${t}`,c=`./src/controllers/${i}`,p=`./src/routes/${d}`;fs.existsSync(c)&&(console.error(`Controller directory "${c}" already exists.`),process.exit(1));const l=generateController(s),m=generateRouter(a,s,i),u=`${c}/${n}`,x=`${p}/${o}`;await fs.mkdir(c,{recursive:!0}),await fs.mkdir(p,{recursive:!0}),await fs.writeFile(u,l),await fs.writeFile(x,m);const b=await fs.readFile("./postman.json","utf-8"),f=JSON.parse(b),k=getItemFormatted(d,f.info.name);f.item.push(k),await fs.writeJson(path.join(".","postman.json"),f,{spaces:2}),await runFormatter("."),console.log(`Created ${s} in ${i}/${n} and ${a} in ${d}/${o}`)}catch(e){console.error("Error generating controller:",e.message),process.exit(1)}}))):program.help();
2
+ import{Command}from"commander";import inquirer from"inquirer";import{generateController,generateRouter}from"./generators/class.js";import fs from"fs-extra";import path from"path";import{fileURLToPath}from"url";import{exec}from"child_process";import ora from"ora";import{generateBasePostman,getItemFormatted}from"./generators/postman.js";const __dirname=path.dirname(fileURLToPath(import.meta.url)),pkg=fs.readJsonSync(path.join(__dirname,"../../package.json")),program=new Command;program.version(pkg.version,"-v, --version").option("--init","Initialize a new project").option("--backend","Initialize with backend template").option("--module","Initialize with module template").option("--db-sql","Initialize with db-sql template").option("--backend-db-sql","Initialize with backend + database template (separate db module)").option("--backend-embedded-db-sql","Initialize with backend + embedded database template (single project)").option("--frontend-nextjs","Initialize with Next.js frontend template (shadcn/ui + Tailwind)").option("--create-controller","Create a controller and its associated route"),program.parse(process.argv);const options=program.opts();function runFormatter(e="."){return new Promise(((t,r)=>{const s=exec("npm run format",{cwd:e});s.stdout.on("data",(e=>process.stdout.write(e))),s.stderr.on("data",(e=>process.stderr.write(e))),s.on("close",(e=>{0===e?t():r(new Error(`npm format exited with code ${e}`))}))}))}function runNpmInstall(e){return new Promise(((t,r)=>{const s=exec("npm install",{cwd:e});s.stdout.on("data",(e=>process.stdout.write(e))),s.stderr.on("data",(e=>process.stderr.write(e))),s.on("close",(e=>{0===e?t():r(new Error(`npm install exited with code ${e}`))}))}))}function initGitRepo(e){return new Promise(((t,r)=>{const s=exec("git init",{cwd:e});s.stdout.on("data",(e=>process.stdout.write(e))),s.stderr.on("data",(e=>process.stderr.write(e))),s.on("close",(e=>{0===e?t():r(new Error(`Git init exited with code ${e}`))}))}))}options.init&&(options.backend||options.module||options.dbSql||options.backendDbSql||options.backendEmbeddedDbSql||options.frontendNextjs)?(console.log("Hello! I'm Paul Sundays, your backend architect. Let's craft an awesome backend together!"),inquirer.prompt([{type:"input",name:"projectName",message:"Name of the project:",validate:e=>!!e||"The name of the project can not be empty"}]).then((async({projectName:e})=>{const t=options.backend?"backend":options.backendEmbeddedDbSql?"backend-embedded-db-sql":options.backendDbSql?"backend-db-sql":options.frontendNextjs?"frontend-nextjs":options.module?"module":"db-sql",r=path.join(__dirname,`../templates/${t}`);let s,n,i;"."===e?(s=path.resolve("."),n=path.basename(s),fs.existsSync(path.join(s,"package.json"))&&(console.error("A package.json already exists in the current directory."),process.exit(1))):(n=e.toLowerCase().replace(/\s+/g,"-"),s=path.resolve(n),fs.existsSync(s)&&(console.error(`Directory "${n}" already exists.`),process.exit(1)),await fs.mkdir(s,{recursive:!0}));try{await fs.copy(r,s,{overwrite:!1,errorOnExist:!0,filter:(e,t)=>!0});const e=path.join(s,"gitignore"),t=path.join(s,".gitignore");await fs.pathExists(e)&&!await fs.pathExists(t)&&await fs.rename(e,t),console.log("Template files copied successfully")}catch(e){console.error("Error copying the files:",e),process.exit(1)}if(i="db-sql"===t?{name:n,version:"0.0.1",description:"Knex Module",main:"dist/index.js",scripts:{test:"jest",format:"prettier --write .",build:"tsc",clean:"rimraf dist && npm run format && npm run build","npm:publish":"npm run clean && npm publish","migrate:create":"knex migrate:make migration -x ts","migrate:deploy":"knex migrate:latest","seed:create":"knex seed:make seed -x ts","seed:run":"knex seed:run"},repository:{type:"git",url:""},author:"",license:"MIT",bugs:{url:""},homepage:"",devDependencies:{"@eslint/js":"^9.23.0","@types/node":"^22.13.13",eslint:"^9.23.0",globals:"^16.0.0",prettier:"^3.5.3",rimraf:"^6.0.1","ts-node":"^10.9.2",typescript:"^5.8.2","typescript-eslint":"^8.28.0"},dependencies:{dotenv:"^16.4.7",knex:"^3.1.0",lodash:"^4.17.21",pg:"^8.14.1",uuid:"^11.1.0"}}:"backend"===t?{name:n,version:"1.0.0",description:"Backend project generated with Sundays Framework",main:"dist/server.js",scripts:{test:"jest",start:"node dist/server.js",build:"tsc","start:dev":"nodemon src/server.ts",format:"prettier --write .","create:controller":"sundaysf --create-controller"},dependencies:{morgan:"^1.10.0",cors:"^2.8.5",dotenv:"^16.4.7",express:"^4.18.2"},devDependencies:{"@types/morgan":"^1.9.9","@types/cors":"^2.8.17","@types/express":"^4.17.21",nodemon:"^3.0.2",prettier:"^3.5.3","ts-node":"^10.9.2",typescript:"^5.8.2","@eslint/js":"^9.23.0",eslint:"^9.23.0","typescript-eslint":"^8.28.0"},author:"",license:"MIT"}:"backend-db-sql"===t?{name:n,version:"1.0.0",description:"Backend project with database module generated with Sundays Framework",main:"dist/server.js",scripts:{test:"jest",start:"node dist/server.js",build:"tsc","start:dev":"nodemon src/server.ts",format:"prettier --write .","create:controller":"sundaysf --create-controller","migrate:create":"knex migrate:make migration -x ts --knexfile db/knexfile.ts","migrate:deploy":"knex migrate:latest --knexfile db/knexfile.ts","seed:create":"knex seed:make seed -x ts --knexfile db/knexfile.ts","seed:run":"knex seed:run --knexfile db/knexfile.ts","db:build":"tsc -p db/tsconfig.json","db:publish":"cd db && npm publish"},dependencies:{morgan:"^1.10.0",cors:"^2.8.5",dotenv:"^16.4.7",express:"^4.18.2",knex:"^3.1.0",lodash:"^4.17.21",pg:"^8.14.1",uuid:"^11.1.0"},devDependencies:{"@types/morgan":"^1.9.9","@types/cors":"^2.8.17","@types/express":"^4.17.21","@types/lodash":"^4.17.16","@types/node":"^22.13.13",nodemon:"^3.0.2",prettier:"^3.5.3",rimraf:"^6.0.1","ts-node":"^10.9.2",typescript:"^5.8.2","@eslint/js":"^9.23.0",eslint:"^9.23.0",globals:"^16.0.0","typescript-eslint":"^8.28.0"},author:"",license:"MIT"}:"backend-embedded-db-sql"===t?{name:n,version:"1.0.0",description:"Backend project with embedded database generated with Sundays Framework",main:"dist/server.js",scripts:{test:"jest",start:"node dist/server.js",build:"tsc","start:dev":"nodemon src/server.ts",format:"prettier --write .","create:controller":"sundaysf --create-controller","db:migrate":"npx knex migrate:latest --knexfile knexfile.ts","db:rollback":"npx knex migrate:rollback --knexfile knexfile.ts","db:seed":"npx knex seed:run --knexfile knexfile.ts","db:make-migration":"npx knex migrate:make --knexfile knexfile.ts -x ts"},dependencies:{morgan:"^1.10.0",cors:"^2.8.5",dotenv:"^16.4.7",express:"^4.18.2",knex:"^3.1.0",lodash:"^4.17.21",pg:"^8.14.1",uuid:"^11.1.0"},devDependencies:{"@types/morgan":"^1.9.9","@types/cors":"^2.8.17","@types/express":"^4.17.21","@types/lodash":"^4.17.16","@types/node":"^22.13.13",nodemon:"^3.0.2",prettier:"^3.5.3",rimraf:"^6.0.1","ts-node":"^10.9.2",typescript:"^5.8.2","@eslint/js":"^9.23.0",eslint:"^9.23.0",globals:"^16.0.0","typescript-eslint":"^8.28.0"},author:"",license:"MIT"}:"frontend-nextjs"===t?{name:n,version:"0.1.0",private:!0,scripts:{dev:"next dev",build:"next build",start:"next start",lint:"eslint ."},dependencies:{"@hookform/resolvers":"^3.9.1","@radix-ui/react-accordion":"1.2.12","@radix-ui/react-alert-dialog":"1.1.15","@radix-ui/react-aspect-ratio":"1.1.8","@radix-ui/react-avatar":"1.1.11","@radix-ui/react-checkbox":"1.3.3","@radix-ui/react-collapsible":"1.1.12","@radix-ui/react-context-menu":"2.2.16","@radix-ui/react-dialog":"1.1.15","@radix-ui/react-dropdown-menu":"2.1.16","@radix-ui/react-hover-card":"1.1.15","@radix-ui/react-label":"2.1.8","@radix-ui/react-menubar":"1.1.16","@radix-ui/react-navigation-menu":"1.2.14","@radix-ui/react-popover":"1.1.15","@radix-ui/react-progress":"1.1.8","@radix-ui/react-radio-group":"1.3.8","@radix-ui/react-scroll-area":"1.2.10","@radix-ui/react-select":"2.2.6","@radix-ui/react-separator":"1.1.8","@radix-ui/react-slider":"1.3.6","@radix-ui/react-slot":"1.2.4","@radix-ui/react-switch":"1.2.6","@radix-ui/react-tabs":"1.1.13","@radix-ui/react-toast":"1.2.15","@radix-ui/react-toggle":"1.1.10","@radix-ui/react-toggle-group":"1.1.11","@radix-ui/react-tooltip":"1.2.8",autoprefixer:"^10.4.20","class-variance-authority":"^0.7.1",clsx:"^2.1.1",cmdk:"1.1.1","date-fns":"4.1.0","embla-carousel-react":"8.6.0","framer-motion":"^12.38.0","input-otp":"1.4.2","lucide-react":"^0.564.0",next:"16.1.6","next-themes":"^0.4.6",react:"19.2.4","react-day-picker":"9.13.2","react-dom":"19.2.4","react-hook-form":"^7.54.1","react-resizable-panels":"^2.1.7",recharts:"2.15.0",sonner:"^1.7.1","tailwind-merge":"^3.3.1",vaul:"^1.1.2",zod:"^3.24.1"},devDependencies:{"@tailwindcss/postcss":"^4.2.0","@types/node":"^22","@types/react":"19.2.14","@types/react-dom":"19.2.3",postcss:"^8.5",tailwindcss:"^4.2.0","tw-animate-css":"1.3.3",typescript:"5.7.3"}}:{name:n,version:"1.0.0",description:"Module generated with Sundays Framework",main:"dist/index.js",types:"dist/index.d.ts",scripts:{test:"jest",build:"tsc",format:"prettier --write .",clean:"rimraf dist && npm run build"},dependencies:{},devDependencies:{prettier:"^3.5.3",rimraf:"^6.0.1",typescript:"^5.8.2"},author:"",license:"MIT"},await fs.writeJson(path.join(s,"package.json"),i,{spaces:2}),["backend","backend-db-sql","backend-embedded-db-sql"].includes(t)){const t=generateBasePostman(e);await fs.writeJson(path.join(s,"postman.json"),t,{spaces:2})}if("backend-db-sql"===t){const e={name:`${n}-db`,version:"0.0.1",description:"Database module",main:"dist/index.js",types:"dist/index.d.ts",scripts:{build:"tsc",clean:"rimraf dist && npm run build",format:"prettier --write .","npm:publish":"npm run clean && npm publish","migrate:create":"knex migrate:make migration -x ts","migrate:deploy":"knex migrate:latest","seed:create":"knex seed:make seed -x ts","seed:run":"knex seed:run"},dependencies:{dotenv:"^16.4.7",knex:"^3.1.0",lodash:"^4.17.21",pg:"^8.14.1",uuid:"^11.1.0"},devDependencies:{typescript:"^5.8.2","ts-node":"^10.9.2",rimraf:"^6.0.1",prettier:"^3.5.3","@types/node":"^22.13.13"}};await fs.writeJson(path.join(s,"db/package.json"),e,{spaces:2})}const a=ora("Git init...").start();await initGitRepo(s),a.succeed("Git initialized");const o=ora("Installing dependencies...").start();await runNpmInstall(s),o.succeed("Dependencies installed"),await runFormatter(s);const d="."===e?"Project created successfully in current directory":`Project '${e}' created successfully in ./${n}`;console.log(d)}))):options.createController?(fs.existsSync("./src/controllers")&&fs.existsSync("./postman.json")||(console.error("This command must be run inside a Sundays backend project."),console.error("Expected ./src/controllers/ and ./postman.json to exist."),process.exit(1)),inquirer.prompt([{type:"input",name:"controllerName",message:"Controller name:",validate:e=>e?!!/^[a-zA-Z][a-zA-Z0-9]*$/.test(e)||"Name must start with a letter and contain only letters and numbers":"The controller name is empty"}]).then((async({controllerName:e})=>{try{const t=e.charAt(0).toLowerCase()+e.slice(1),r=e.charAt(0).toUpperCase()+e.slice(1),s=`${r}Controller`,n=`${t}.controller.ts`,i=`${t}`,a=`${r}Router`,o=`${t}.router.ts`,d=`${t}`,c=`./src/controllers/${i}`,p=`./src/routes/${d}`;fs.existsSync(c)&&(console.error(`Controller directory "${c}" already exists.`),process.exit(1));const l=generateController(s),m=generateRouter(a,s,i),u=`${c}/${n}`,x=`${p}/${o}`;await fs.mkdir(c,{recursive:!0}),await fs.mkdir(p,{recursive:!0}),await fs.writeFile(u,l),await fs.writeFile(x,m);const b=await fs.readFile("./postman.json","utf-8"),f=JSON.parse(b),g=getItemFormatted(d,f.info.name);f.item.push(g),await fs.writeJson(path.join(".","postman.json"),f,{spaces:2}),await runFormatter("."),console.log(`Created ${s} in ${i}/${n} and ${a} in ${d}/${o}`)}catch(e){console.error("Error generating controller:",e.message),process.exit(1)}}))):program.help();
3
3
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["Command","inquirer","generateController","generateRouter","fs","path","fileURLToPath","exec","ora","generateBasePostman","getItemFormatted","__dirname","dirname","url","pkg","readJsonSync","join","program","version","option","parse","process","argv","options","opts","runFormatter","cwd","Promise","resolve","reject","formatProcess","stdout","on","data","write","stderr","code","Error","runNpmInstall","destDir","installProcess","initGitRepo","gitProcess","init","backend","module","dbSql","backendDbSql","backendEmbeddedDbSql","frontendNextjs","console","log","prompt","type","name","message","validate","input","then","async","projectName","templateType","srcDir","dirName","packageJson","basename","existsSync","error","exit","toLowerCase","replace","mkdir","recursive","copy","overwrite","errorOnExist","filter","src","dest","err","description","main","scripts","test","format","build","clean","repository","author","license","bugs","homepage","devDependencies","eslint","globals","prettier","rimraf","typescript","dependencies","dotenv","knex","lodash","pg","uuid","start","morgan","cors","express","nodemon","private","dev","lint","autoprefixer","clsx","cmdk","next","react","recharts","sonner","vaul","zod","postcss","tailwindcss","types","writeJson","spaces","includes","postmanBaseData","dbPackageJson","spinnerGit","succeed","spinner","outputMsg","createController","controllerName","nonCapitalized","charAt","slice","capitalized","toUpperCase","controllerClassName","controllerFileName","controllerDirectoryName","routerClassName","routerFileName","routerDirectoryName","controllerDir","routerDir","classControllerContentGenerator","classRouterContentGenerator","controllerPath","routerPath","writeFile","readFile","leanData","JSON","itemToPush","info","item","push","help"],"sources":["bin/index.js"],"mappings":"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","ignoreList":[],"sourcesContent":["#!/usr/bin/env node\r\n\r\nimport { Command } from 'commander';\r\nimport inquirer from 'inquirer';\r\nimport { generateController, generateRouter } from './generators/class.js';\r\nimport fs from 'fs-extra';\r\nimport path from 'path';\r\nimport { fileURLToPath } from 'url';\r\nimport { exec } from 'child_process';\r\nimport ora from 'ora';\r\nimport { generateBasePostman, getItemFormatted } from './generators/postman.js';\r\n\r\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\r\nconst pkg = fs.readJsonSync(path.join(__dirname, '../../package.json'));\r\n\r\nconst program = new Command();\r\n\r\nprogram\r\n .version(pkg.version, '-v, --version')\r\n .option('--init', 'Initialize a new project')\r\n .option('--backend', 'Initialize with backend template')\r\n .option('--module', 'Initialize with module template')\r\n .option('--db-sql', 'Initialize with db-sql template')\r\n .option('--backend-db-sql', 'Initialize with backend + database template (separate db module)')\r\n .option('--backend-embedded-db-sql', 'Initialize with backend + embedded database template (single project)')\r\n .option('--frontend-nextjs', 'Initialize with Next.js frontend template (shadcn/ui + Tailwind)')\r\n .option('--create-controller', 'Create a controller and its associated route');\r\n\r\nprogram.parse(process.argv);\r\n\r\nconst options = program.opts();\r\n\r\nif (options.init && (options.backend || options.module || options.dbSql || options.backendDbSql || options.backendEmbeddedDbSql || options.frontendNextjs)) {\r\n console.log(\"Hello! I'm Paul Sundays, your backend architect. Let's craft an awesome backend together!\");\r\n inquirer.prompt([\r\n {\r\n type: 'input',\r\n name: 'projectName',\r\n message: 'Name of the project:',\r\n validate: input => input ? true : 'The name of the project can not be empty'\r\n }\r\n ]).then(async ({ projectName }) => {\r\n const templateType = options.backend ? 'backend' : options.backendEmbeddedDbSql ? 'backend-embedded-db-sql' : options.backendDbSql ? 'backend-db-sql' : options.frontendNextjs ? 'frontend-nextjs' : options.module ? 'module' : 'db-sql';\r\n const srcDir = path.join(__dirname, `../templates/${templateType}`);\r\n\r\n let destDir;\r\n let dirName;\r\n if (projectName === '.') {\r\n destDir = path.resolve('.');\r\n dirName = path.basename(destDir);\r\n if (fs.existsSync(path.join(destDir, 'package.json'))) {\r\n console.error('A package.json already exists in the current directory.');\r\n process.exit(1);\r\n }\r\n } else {\r\n dirName = projectName.toLowerCase().replace(/\\s+/g, '-');\r\n destDir = path.resolve(dirName);\r\n if (fs.existsSync(destDir)) {\r\n console.error(`Directory \"${dirName}\" already exists.`);\r\n process.exit(1);\r\n }\r\n await fs.mkdir(destDir, { recursive: true });\r\n }\r\n\r\n try {\r\n await fs.copy(srcDir, destDir, {\r\n overwrite: false,\r\n errorOnExist: true,\r\n filter: (src, dest) => {\r\n return true;\r\n }\r\n });\r\n console.log('Template files copied successfully');\r\n } catch (err) {\r\n console.error('Error copying the files:', err);\r\n process.exit(1);\r\n }\r\n\r\n let packageJson;\r\n if (templateType === 'db-sql') {\r\n packageJson = {\r\n name: dirName,\r\n version: \"0.0.1\",\r\n description: \"Knex Module\",\r\n main: \"dist/index.js\",\r\n scripts: {\r\n test: \"jest\",\r\n format: \"prettier --write .\",\r\n build: \"tsc\",\r\n clean: \"rimraf dist && npm run format && npm run build\",\r\n \"npm:publish\": \"npm run clean && npm publish\",\r\n \"migrate:create\": \"knex migrate:make migration -x ts\",\r\n \"migrate:deploy\": \"knex migrate:latest\",\r\n \"seed:create\": \"knex seed:make seed -x ts\",\r\n \"seed:run\": \"knex seed:run\"\r\n },\r\n repository: {\r\n type: \"git\",\r\n url: \"\"\r\n },\r\n author: \"\",\r\n license: \"MIT\",\r\n bugs: {\r\n url: \"\"\r\n },\r\n homepage: \"\",\r\n devDependencies: {\r\n \"@eslint/js\": \"^9.23.0\",\r\n \"@types/node\": \"^22.13.13\",\r\n eslint: \"^9.23.0\",\r\n globals: \"^16.0.0\",\r\n prettier: \"^3.5.3\",\r\n rimraf: \"^6.0.1\",\r\n \"ts-node\": \"^10.9.2\",\r\n typescript: \"^5.8.2\",\r\n \"typescript-eslint\": \"^8.28.0\"\r\n },\r\n dependencies: {\r\n dotenv: \"^16.4.7\",\r\n knex: \"^3.1.0\",\r\n lodash: \"^4.17.21\",\r\n pg: \"^8.14.1\",\r\n uuid: \"^11.1.0\"\r\n }\r\n };\r\n } else if (templateType === 'backend') {\r\n packageJson = {\r\n name: dirName,\r\n version: \"1.0.0\",\r\n description: `Backend project generated with Sundays Framework`,\r\n main: \"dist/server.js\",\r\n scripts: {\r\n \"test\": \"jest\",\r\n \"start\": \"node dist/server.js\",\r\n \"build\": \"tsc\",\r\n \"start:dev\": \"nodemon src/server.ts\",\r\n \"format\": \"prettier --write .\",\r\n \"create:controller\": \"sundaysf --create-controller\"\r\n },\r\n dependencies: {\r\n \"morgan\": \"^1.10.0\",\r\n \"cors\": \"^2.8.5\",\r\n \"dotenv\": \"^16.4.7\",\r\n \"express\": \"^4.18.2\"\r\n },\r\n devDependencies: {\r\n \"@types/morgan\": \"^1.9.9\",\r\n \"@types/cors\": \"^2.8.17\",\r\n \"@types/express\": \"^4.17.21\",\r\n \"nodemon\": \"^3.0.2\",\r\n \"prettier\": \"^3.5.3\",\r\n \"ts-node\": \"^10.9.2\",\r\n \"typescript\": \"^5.8.2\",\r\n \"@eslint/js\": \"^9.23.0\",\r\n \"eslint\": \"^9.23.0\",\r\n \"typescript-eslint\": \"^8.28.0\"\r\n },\r\n author: \"\",\r\n license: \"MIT\"\r\n };\r\n } else if (templateType === 'backend-db-sql') {\r\n packageJson = {\r\n name: dirName,\r\n version: \"1.0.0\",\r\n description: `Backend project with database module generated with Sundays Framework`,\r\n main: \"dist/server.js\",\r\n scripts: {\r\n \"test\": \"jest\",\r\n \"start\": \"node dist/server.js\",\r\n \"build\": \"tsc\",\r\n \"start:dev\": \"nodemon src/server.ts\",\r\n \"format\": \"prettier --write .\",\r\n \"create:controller\": \"sundaysf --create-controller\",\r\n \"migrate:create\": \"knex migrate:make migration -x ts --knexfile db/knexfile.ts\",\r\n \"migrate:deploy\": \"knex migrate:latest --knexfile db/knexfile.ts\",\r\n \"seed:create\": \"knex seed:make seed -x ts --knexfile db/knexfile.ts\",\r\n \"seed:run\": \"knex seed:run --knexfile db/knexfile.ts\",\r\n \"db:build\": \"tsc -p db/tsconfig.json\",\r\n \"db:publish\": \"cd db && npm publish\"\r\n },\r\n dependencies: {\r\n \"morgan\": \"^1.10.0\",\r\n \"cors\": \"^2.8.5\",\r\n \"dotenv\": \"^16.4.7\",\r\n \"express\": \"^4.18.2\",\r\n \"knex\": \"^3.1.0\",\r\n \"lodash\": \"^4.17.21\",\r\n \"pg\": \"^8.14.1\",\r\n \"uuid\": \"^11.1.0\"\r\n },\r\n devDependencies: {\r\n \"@types/morgan\": \"^1.9.9\",\r\n \"@types/cors\": \"^2.8.17\",\r\n \"@types/express\": \"^4.17.21\",\r\n \"@types/lodash\": \"^4.17.16\",\r\n \"@types/node\": \"^22.13.13\",\r\n \"nodemon\": \"^3.0.2\",\r\n \"prettier\": \"^3.5.3\",\r\n \"rimraf\": \"^6.0.1\",\r\n \"ts-node\": \"^10.9.2\",\r\n \"typescript\": \"^5.8.2\",\r\n \"@eslint/js\": \"^9.23.0\",\r\n \"eslint\": \"^9.23.0\",\r\n \"globals\": \"^16.0.0\",\r\n \"typescript-eslint\": \"^8.28.0\"\r\n },\r\n author: \"\",\r\n license: \"MIT\"\r\n };\r\n } else if (templateType === 'backend-embedded-db-sql') {\r\n packageJson = {\r\n name: dirName,\r\n version: \"1.0.0\",\r\n description: `Backend project with embedded database generated with Sundays Framework`,\r\n main: \"dist/server.js\",\r\n scripts: {\r\n \"test\": \"jest\",\r\n \"start\": \"node dist/server.js\",\r\n \"build\": \"tsc\",\r\n \"start:dev\": \"nodemon src/server.ts\",\r\n \"format\": \"prettier --write .\",\r\n \"create:controller\": \"sundaysf --create-controller\",\r\n \"db:migrate\": \"npx knex migrate:latest --knexfile knexfile.ts\",\r\n \"db:rollback\": \"npx knex migrate:rollback --knexfile knexfile.ts\",\r\n \"db:seed\": \"npx knex seed:run --knexfile knexfile.ts\",\r\n \"db:make-migration\": \"npx knex migrate:make --knexfile knexfile.ts -x ts\"\r\n },\r\n dependencies: {\r\n \"morgan\": \"^1.10.0\",\r\n \"cors\": \"^2.8.5\",\r\n \"dotenv\": \"^16.4.7\",\r\n \"express\": \"^4.18.2\",\r\n \"knex\": \"^3.1.0\",\r\n \"lodash\": \"^4.17.21\",\r\n \"pg\": \"^8.14.1\",\r\n \"uuid\": \"^11.1.0\"\r\n },\r\n devDependencies: {\r\n \"@types/morgan\": \"^1.9.9\",\r\n \"@types/cors\": \"^2.8.17\",\r\n \"@types/express\": \"^4.17.21\",\r\n \"@types/lodash\": \"^4.17.16\",\r\n \"@types/node\": \"^22.13.13\",\r\n \"nodemon\": \"^3.0.2\",\r\n \"prettier\": \"^3.5.3\",\r\n \"rimraf\": \"^6.0.1\",\r\n \"ts-node\": \"^10.9.2\",\r\n \"typescript\": \"^5.8.2\",\r\n \"@eslint/js\": \"^9.23.0\",\r\n \"eslint\": \"^9.23.0\",\r\n \"globals\": \"^16.0.0\",\r\n \"typescript-eslint\": \"^8.28.0\"\r\n },\r\n author: \"\",\r\n license: \"MIT\"\r\n };\r\n } else if (templateType === 'frontend-nextjs') {\r\n packageJson = {\r\n name: dirName,\r\n version: \"0.1.0\",\r\n private: true,\r\n scripts: {\r\n \"dev\": \"next dev\",\r\n \"build\": \"next build\",\r\n \"start\": \"next start\",\r\n \"lint\": \"eslint .\"\r\n },\r\n dependencies: {\r\n \"@hookform/resolvers\": \"^3.9.1\",\r\n \"@radix-ui/react-accordion\": \"1.2.12\",\r\n \"@radix-ui/react-alert-dialog\": \"1.1.15\",\r\n \"@radix-ui/react-aspect-ratio\": \"1.1.8\",\r\n \"@radix-ui/react-avatar\": \"1.1.11\",\r\n \"@radix-ui/react-checkbox\": \"1.3.3\",\r\n \"@radix-ui/react-collapsible\": \"1.1.12\",\r\n \"@radix-ui/react-context-menu\": \"2.2.16\",\r\n \"@radix-ui/react-dialog\": \"1.1.15\",\r\n \"@radix-ui/react-dropdown-menu\": \"2.1.16\",\r\n \"@radix-ui/react-hover-card\": \"1.1.15\",\r\n \"@radix-ui/react-label\": \"2.1.8\",\r\n \"@radix-ui/react-menubar\": \"1.1.16\",\r\n \"@radix-ui/react-navigation-menu\": \"1.2.14\",\r\n \"@radix-ui/react-popover\": \"1.1.15\",\r\n \"@radix-ui/react-progress\": \"1.1.8\",\r\n \"@radix-ui/react-radio-group\": \"1.3.8\",\r\n \"@radix-ui/react-scroll-area\": \"1.2.10\",\r\n \"@radix-ui/react-select\": \"2.2.6\",\r\n \"@radix-ui/react-separator\": \"1.1.8\",\r\n \"@radix-ui/react-slider\": \"1.3.6\",\r\n \"@radix-ui/react-slot\": \"1.2.4\",\r\n \"@radix-ui/react-switch\": \"1.2.6\",\r\n \"@radix-ui/react-tabs\": \"1.1.13\",\r\n \"@radix-ui/react-toast\": \"1.2.15\",\r\n \"@radix-ui/react-toggle\": \"1.1.10\",\r\n \"@radix-ui/react-toggle-group\": \"1.1.11\",\r\n \"@radix-ui/react-tooltip\": \"1.2.8\",\r\n \"autoprefixer\": \"^10.4.20\",\r\n \"class-variance-authority\": \"^0.7.1\",\r\n \"clsx\": \"^2.1.1\",\r\n \"cmdk\": \"1.1.1\",\r\n \"date-fns\": \"4.1.0\",\r\n \"embla-carousel-react\": \"8.6.0\",\r\n \"framer-motion\": \"^12.38.0\",\r\n \"input-otp\": \"1.4.2\",\r\n \"lucide-react\": \"^0.564.0\",\r\n \"next\": \"16.1.6\",\r\n \"next-themes\": \"^0.4.6\",\r\n \"react\": \"19.2.4\",\r\n \"react-day-picker\": \"9.13.2\",\r\n \"react-dom\": \"19.2.4\",\r\n \"react-hook-form\": \"^7.54.1\",\r\n \"react-resizable-panels\": \"^2.1.7\",\r\n \"recharts\": \"2.15.0\",\r\n \"sonner\": \"^1.7.1\",\r\n \"tailwind-merge\": \"^3.3.1\",\r\n \"vaul\": \"^1.1.2\",\r\n \"zod\": \"^3.24.1\"\r\n },\r\n devDependencies: {\r\n \"@tailwindcss/postcss\": \"^4.2.0\",\r\n \"@types/node\": \"^22\",\r\n \"@types/react\": \"19.2.14\",\r\n \"@types/react-dom\": \"19.2.3\",\r\n \"postcss\": \"^8.5\",\r\n \"tailwindcss\": \"^4.2.0\",\r\n \"tw-animate-css\": \"1.3.3\",\r\n \"typescript\": \"5.7.3\"\r\n }\r\n };\r\n } else {\r\n // module\r\n packageJson = {\r\n name: dirName,\r\n version: \"1.0.0\",\r\n description: `Module generated with Sundays Framework`,\r\n main: \"dist/index.js\",\r\n types: \"dist/index.d.ts\",\r\n scripts: {\r\n \"test\": \"jest\",\r\n \"build\": \"tsc\",\r\n \"format\": \"prettier --write .\",\r\n \"clean\": \"rimraf dist && npm run build\"\r\n },\r\n dependencies: {},\r\n devDependencies: {\r\n \"prettier\": \"^3.5.3\",\r\n \"rimraf\": \"^6.0.1\",\r\n \"typescript\": \"^5.8.2\"\r\n },\r\n author: \"\",\r\n license: \"MIT\"\r\n };\r\n }\r\n\r\n await fs.writeJson(path.join(destDir, 'package.json'), packageJson, { spaces: 2 });\r\n\r\n if (['backend', 'backend-db-sql', 'backend-embedded-db-sql'].includes(templateType)) {\r\n const postmanBaseData = generateBasePostman(projectName);\r\n await fs.writeJson(path.join(destDir, 'postman.json'), postmanBaseData, { spaces: 2 });\r\n }\r\n\r\n if (templateType === 'backend-db-sql') {\r\n const dbPackageJson = {\r\n name: `${dirName}-db`,\r\n version: \"0.0.1\",\r\n description: \"Database module\",\r\n main: \"dist/index.js\",\r\n types: \"dist/index.d.ts\",\r\n scripts: {\r\n build: \"tsc\",\r\n clean: \"rimraf dist && npm run build\",\r\n format: \"prettier --write .\",\r\n \"npm:publish\": \"npm run clean && npm publish\",\r\n \"migrate:create\": \"knex migrate:make migration -x ts\",\r\n \"migrate:deploy\": \"knex migrate:latest\",\r\n \"seed:create\": \"knex seed:make seed -x ts\",\r\n \"seed:run\": \"knex seed:run\"\r\n },\r\n dependencies: {\r\n dotenv: \"^16.4.7\",\r\n knex: \"^3.1.0\",\r\n lodash: \"^4.17.21\",\r\n pg: \"^8.14.1\",\r\n uuid: \"^11.1.0\"\r\n },\r\n devDependencies: {\r\n typescript: \"^5.8.2\",\r\n \"ts-node\": \"^10.9.2\",\r\n rimraf: \"^6.0.1\",\r\n prettier: \"^3.5.3\",\r\n \"@types/node\": \"^22.13.13\"\r\n }\r\n };\r\n await fs.writeJson(path.join(destDir, 'db/package.json'), dbPackageJson, { spaces: 2 });\r\n }\r\n\r\n const spinnerGit = ora('Git init...').start();\r\n await initGitRepo(destDir);\r\n spinnerGit.succeed('Git initialized');\r\n\r\n const spinner = ora('Installing dependencies...').start();\r\n await runNpmInstall(destDir);\r\n spinner.succeed('Dependencies installed');\r\n\r\n await runFormatter(destDir);\r\n const outputMsg = projectName === '.' ? `Project created successfully in current directory` : `Project '${projectName}' created successfully in ./${dirName}`;\r\n console.log(outputMsg);\r\n });\r\n} else if (options.createController) {\r\n // Verify we're inside a backend project\r\n if (!fs.existsSync('./src/controllers') || !fs.existsSync('./postman.json')) {\r\n console.error('This command must be run inside a Sundays backend project.');\r\n console.error('Expected ./src/controllers/ and ./postman.json to exist.');\r\n process.exit(1);\r\n }\r\n\r\n inquirer.prompt([\r\n {\r\n type: 'input',\r\n name: 'controllerName',\r\n message: 'Controller name:',\r\n validate: input => {\r\n if (!input) return 'The controller name is empty';\r\n if (!/^[a-zA-Z][a-zA-Z0-9]*$/.test(input)) {\r\n return 'Name must start with a letter and contain only letters and numbers';\r\n }\r\n return true;\r\n }\r\n }\r\n ]).then(async ({ controllerName }) => {\r\n try {\r\n const nonCapitalized = controllerName.charAt(0).toLowerCase() + controllerName.slice(1);\r\n const capitalized = controllerName.charAt(0).toUpperCase() + controllerName.slice(1);\r\n const controllerClassName = `${capitalized}Controller`;\r\n const controllerFileName = `${nonCapitalized}.controller.ts`;\r\n const controllerDirectoryName = `${nonCapitalized}`;\r\n const routerClassName = `${capitalized}Router`;\r\n const routerFileName = `${nonCapitalized}.router.ts`;\r\n const routerDirectoryName = `${nonCapitalized}`;\r\n\r\n const controllerDir = `./src/controllers/${controllerDirectoryName}`;\r\n const routerDir = `./src/routes/${routerDirectoryName}`;\r\n\r\n if (fs.existsSync(controllerDir)) {\r\n console.error(`Controller directory \"${controllerDir}\" already exists.`);\r\n process.exit(1);\r\n }\r\n\r\n const classControllerContentGenerator = generateController(controllerClassName);\r\n const classRouterContentGenerator = generateRouter(routerClassName, controllerClassName, controllerDirectoryName);\r\n const controllerPath = `${controllerDir}/${controllerFileName}`;\r\n const routerPath = `${routerDir}/${routerFileName}`;\r\n\r\n await fs.mkdir(controllerDir, { recursive: true });\r\n await fs.mkdir(routerDir, { recursive: true });\r\n await fs.writeFile(controllerPath, classControllerContentGenerator);\r\n await fs.writeFile(routerPath, classRouterContentGenerator);\r\n\r\n const postmanBaseData = await fs.readFile('./postman.json', 'utf-8');\r\n const leanData = JSON.parse(postmanBaseData);\r\n const itemToPush = getItemFormatted(routerDirectoryName, leanData.info.name);\r\n leanData.item.push(itemToPush);\r\n await fs.writeJson(path.join('.', 'postman.json'), leanData, { spaces: 2 });\r\n\r\n await runFormatter('.');\r\n console.log(`Created ${controllerClassName} in ${controllerDirectoryName}/${controllerFileName} and ${routerClassName} in ${routerDirectoryName}/${routerFileName}`);\r\n } catch (err) {\r\n console.error('Error generating controller:', err.message);\r\n process.exit(1);\r\n }\r\n });\r\n} else {\r\n program.help();\r\n}\r\n\r\n\r\nfunction runFormatter(cwd = '.') {\r\n return new Promise((resolve, reject) => {\r\n const formatProcess = exec('npm run format', { cwd });\r\n\r\n formatProcess.stdout.on('data', data => process.stdout.write(data));\r\n formatProcess.stderr.on('data', data => process.stderr.write(data));\r\n\r\n formatProcess.on('close', code => {\r\n if (code === 0) {\r\n resolve();\r\n } else {\r\n reject(new Error(`npm format exited with code ${code}`));\r\n }\r\n });\r\n });\r\n}\r\n\r\n\r\nfunction runNpmInstall(destDir) {\r\n return new Promise((resolve, reject) => {\r\n const installProcess = exec('npm install', { cwd: destDir });\r\n\r\n installProcess.stdout.on('data', data => process.stdout.write(data));\r\n installProcess.stderr.on('data', data => process.stderr.write(data));\r\n\r\n installProcess.on('close', code => {\r\n if (code === 0) {\r\n resolve();\r\n } else {\r\n reject(new Error(`npm install exited with code ${code}`));\r\n }\r\n });\r\n });\r\n}\r\n\r\nfunction initGitRepo(destDir) {\r\n return new Promise((resolve, reject) => {\r\n const gitProcess = exec('git init', { cwd: destDir });\r\n\r\n gitProcess.stdout.on('data', data => process.stdout.write(data));\r\n gitProcess.stderr.on('data', data => process.stderr.write(data));\r\n\r\n gitProcess.on('close', code => {\r\n if (code === 0) {\r\n resolve();\r\n } else {\r\n reject(new Error(`Git init exited with code ${code}`));\r\n }\r\n });\r\n });\r\n}\r\n"]}
1
+ {"version":3,"file":"index.js","names":["Command","inquirer","generateController","generateRouter","fs","path","fileURLToPath","exec","ora","generateBasePostman","getItemFormatted","__dirname","dirname","url","pkg","readJsonSync","join","program","version","option","parse","process","argv","options","opts","runFormatter","cwd","Promise","resolve","reject","formatProcess","stdout","on","data","write","stderr","code","Error","runNpmInstall","destDir","installProcess","initGitRepo","gitProcess","init","backend","module","dbSql","backendDbSql","backendEmbeddedDbSql","frontendNextjs","console","log","prompt","type","name","message","validate","input","then","async","projectName","templateType","srcDir","dirName","packageJson","basename","existsSync","error","exit","toLowerCase","replace","mkdir","recursive","copy","overwrite","errorOnExist","filter","src","dest","gitignorePath","dotGitignorePath","pathExists","rename","err","description","main","scripts","test","format","build","clean","repository","author","license","bugs","homepage","devDependencies","eslint","globals","prettier","rimraf","typescript","dependencies","dotenv","knex","lodash","pg","uuid","start","morgan","cors","express","nodemon","private","dev","lint","autoprefixer","clsx","cmdk","next","react","recharts","sonner","vaul","zod","postcss","tailwindcss","types","writeJson","spaces","includes","postmanBaseData","dbPackageJson","spinnerGit","succeed","spinner","outputMsg","createController","controllerName","nonCapitalized","charAt","slice","capitalized","toUpperCase","controllerClassName","controllerFileName","controllerDirectoryName","routerClassName","routerFileName","routerDirectoryName","controllerDir","routerDir","classControllerContentGenerator","classRouterContentGenerator","controllerPath","routerPath","writeFile","readFile","leanData","JSON","itemToPush","info","item","push","help"],"sources":["bin/index.js"],"mappings":"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","ignoreList":[],"sourcesContent":["#!/usr/bin/env node\r\n\r\nimport { Command } from 'commander';\r\nimport inquirer from 'inquirer';\r\nimport { generateController, generateRouter } from './generators/class.js';\r\nimport fs from 'fs-extra';\r\nimport path from 'path';\r\nimport { fileURLToPath } from 'url';\r\nimport { exec } from 'child_process';\r\nimport ora from 'ora';\r\nimport { generateBasePostman, getItemFormatted } from './generators/postman.js';\r\n\r\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\r\nconst pkg = fs.readJsonSync(path.join(__dirname, '../../package.json'));\r\n\r\nconst program = new Command();\r\n\r\nprogram\r\n .version(pkg.version, '-v, --version')\r\n .option('--init', 'Initialize a new project')\r\n .option('--backend', 'Initialize with backend template')\r\n .option('--module', 'Initialize with module template')\r\n .option('--db-sql', 'Initialize with db-sql template')\r\n .option('--backend-db-sql', 'Initialize with backend + database template (separate db module)')\r\n .option('--backend-embedded-db-sql', 'Initialize with backend + embedded database template (single project)')\r\n .option('--frontend-nextjs', 'Initialize with Next.js frontend template (shadcn/ui + Tailwind)')\r\n .option('--create-controller', 'Create a controller and its associated route');\r\n\r\nprogram.parse(process.argv);\r\n\r\nconst options = program.opts();\r\n\r\nif (options.init && (options.backend || options.module || options.dbSql || options.backendDbSql || options.backendEmbeddedDbSql || options.frontendNextjs)) {\r\n console.log(\"Hello! I'm Paul Sundays, your backend architect. Let's craft an awesome backend together!\");\r\n inquirer.prompt([\r\n {\r\n type: 'input',\r\n name: 'projectName',\r\n message: 'Name of the project:',\r\n validate: input => input ? true : 'The name of the project can not be empty'\r\n }\r\n ]).then(async ({ projectName }) => {\r\n const templateType = options.backend ? 'backend' : options.backendEmbeddedDbSql ? 'backend-embedded-db-sql' : options.backendDbSql ? 'backend-db-sql' : options.frontendNextjs ? 'frontend-nextjs' : options.module ? 'module' : 'db-sql';\r\n const srcDir = path.join(__dirname, `../templates/${templateType}`);\r\n\r\n let destDir;\r\n let dirName;\r\n if (projectName === '.') {\r\n destDir = path.resolve('.');\r\n dirName = path.basename(destDir);\r\n if (fs.existsSync(path.join(destDir, 'package.json'))) {\r\n console.error('A package.json already exists in the current directory.');\r\n process.exit(1);\r\n }\r\n } else {\r\n dirName = projectName.toLowerCase().replace(/\\s+/g, '-');\r\n destDir = path.resolve(dirName);\r\n if (fs.existsSync(destDir)) {\r\n console.error(`Directory \"${dirName}\" already exists.`);\r\n process.exit(1);\r\n }\r\n await fs.mkdir(destDir, { recursive: true });\r\n }\r\n\r\n try {\r\n await fs.copy(srcDir, destDir, {\r\n overwrite: false,\r\n errorOnExist: true,\r\n filter: (src, dest) => {\r\n return true;\r\n }\r\n });\r\n // Rename gitignore to .gitignore (npm strips dotfiles from published packages)\r\n const gitignorePath = path.join(destDir, 'gitignore');\r\n const dotGitignorePath = path.join(destDir, '.gitignore');\r\n if (await fs.pathExists(gitignorePath) && !await fs.pathExists(dotGitignorePath)) {\r\n await fs.rename(gitignorePath, dotGitignorePath);\r\n }\r\n console.log('Template files copied successfully');\r\n } catch (err) {\r\n console.error('Error copying the files:', err);\r\n process.exit(1);\r\n }\r\n\r\n let packageJson;\r\n if (templateType === 'db-sql') {\r\n packageJson = {\r\n name: dirName,\r\n version: \"0.0.1\",\r\n description: \"Knex Module\",\r\n main: \"dist/index.js\",\r\n scripts: {\r\n test: \"jest\",\r\n format: \"prettier --write .\",\r\n build: \"tsc\",\r\n clean: \"rimraf dist && npm run format && npm run build\",\r\n \"npm:publish\": \"npm run clean && npm publish\",\r\n \"migrate:create\": \"knex migrate:make migration -x ts\",\r\n \"migrate:deploy\": \"knex migrate:latest\",\r\n \"seed:create\": \"knex seed:make seed -x ts\",\r\n \"seed:run\": \"knex seed:run\"\r\n },\r\n repository: {\r\n type: \"git\",\r\n url: \"\"\r\n },\r\n author: \"\",\r\n license: \"MIT\",\r\n bugs: {\r\n url: \"\"\r\n },\r\n homepage: \"\",\r\n devDependencies: {\r\n \"@eslint/js\": \"^9.23.0\",\r\n \"@types/node\": \"^22.13.13\",\r\n eslint: \"^9.23.0\",\r\n globals: \"^16.0.0\",\r\n prettier: \"^3.5.3\",\r\n rimraf: \"^6.0.1\",\r\n \"ts-node\": \"^10.9.2\",\r\n typescript: \"^5.8.2\",\r\n \"typescript-eslint\": \"^8.28.0\"\r\n },\r\n dependencies: {\r\n dotenv: \"^16.4.7\",\r\n knex: \"^3.1.0\",\r\n lodash: \"^4.17.21\",\r\n pg: \"^8.14.1\",\r\n uuid: \"^11.1.0\"\r\n }\r\n };\r\n } else if (templateType === 'backend') {\r\n packageJson = {\r\n name: dirName,\r\n version: \"1.0.0\",\r\n description: `Backend project generated with Sundays Framework`,\r\n main: \"dist/server.js\",\r\n scripts: {\r\n \"test\": \"jest\",\r\n \"start\": \"node dist/server.js\",\r\n \"build\": \"tsc\",\r\n \"start:dev\": \"nodemon src/server.ts\",\r\n \"format\": \"prettier --write .\",\r\n \"create:controller\": \"sundaysf --create-controller\"\r\n },\r\n dependencies: {\r\n \"morgan\": \"^1.10.0\",\r\n \"cors\": \"^2.8.5\",\r\n \"dotenv\": \"^16.4.7\",\r\n \"express\": \"^4.18.2\"\r\n },\r\n devDependencies: {\r\n \"@types/morgan\": \"^1.9.9\",\r\n \"@types/cors\": \"^2.8.17\",\r\n \"@types/express\": \"^4.17.21\",\r\n \"nodemon\": \"^3.0.2\",\r\n \"prettier\": \"^3.5.3\",\r\n \"ts-node\": \"^10.9.2\",\r\n \"typescript\": \"^5.8.2\",\r\n \"@eslint/js\": \"^9.23.0\",\r\n \"eslint\": \"^9.23.0\",\r\n \"typescript-eslint\": \"^8.28.0\"\r\n },\r\n author: \"\",\r\n license: \"MIT\"\r\n };\r\n } else if (templateType === 'backend-db-sql') {\r\n packageJson = {\r\n name: dirName,\r\n version: \"1.0.0\",\r\n description: `Backend project with database module generated with Sundays Framework`,\r\n main: \"dist/server.js\",\r\n scripts: {\r\n \"test\": \"jest\",\r\n \"start\": \"node dist/server.js\",\r\n \"build\": \"tsc\",\r\n \"start:dev\": \"nodemon src/server.ts\",\r\n \"format\": \"prettier --write .\",\r\n \"create:controller\": \"sundaysf --create-controller\",\r\n \"migrate:create\": \"knex migrate:make migration -x ts --knexfile db/knexfile.ts\",\r\n \"migrate:deploy\": \"knex migrate:latest --knexfile db/knexfile.ts\",\r\n \"seed:create\": \"knex seed:make seed -x ts --knexfile db/knexfile.ts\",\r\n \"seed:run\": \"knex seed:run --knexfile db/knexfile.ts\",\r\n \"db:build\": \"tsc -p db/tsconfig.json\",\r\n \"db:publish\": \"cd db && npm publish\"\r\n },\r\n dependencies: {\r\n \"morgan\": \"^1.10.0\",\r\n \"cors\": \"^2.8.5\",\r\n \"dotenv\": \"^16.4.7\",\r\n \"express\": \"^4.18.2\",\r\n \"knex\": \"^3.1.0\",\r\n \"lodash\": \"^4.17.21\",\r\n \"pg\": \"^8.14.1\",\r\n \"uuid\": \"^11.1.0\"\r\n },\r\n devDependencies: {\r\n \"@types/morgan\": \"^1.9.9\",\r\n \"@types/cors\": \"^2.8.17\",\r\n \"@types/express\": \"^4.17.21\",\r\n \"@types/lodash\": \"^4.17.16\",\r\n \"@types/node\": \"^22.13.13\",\r\n \"nodemon\": \"^3.0.2\",\r\n \"prettier\": \"^3.5.3\",\r\n \"rimraf\": \"^6.0.1\",\r\n \"ts-node\": \"^10.9.2\",\r\n \"typescript\": \"^5.8.2\",\r\n \"@eslint/js\": \"^9.23.0\",\r\n \"eslint\": \"^9.23.0\",\r\n \"globals\": \"^16.0.0\",\r\n \"typescript-eslint\": \"^8.28.0\"\r\n },\r\n author: \"\",\r\n license: \"MIT\"\r\n };\r\n } else if (templateType === 'backend-embedded-db-sql') {\r\n packageJson = {\r\n name: dirName,\r\n version: \"1.0.0\",\r\n description: `Backend project with embedded database generated with Sundays Framework`,\r\n main: \"dist/server.js\",\r\n scripts: {\r\n \"test\": \"jest\",\r\n \"start\": \"node dist/server.js\",\r\n \"build\": \"tsc\",\r\n \"start:dev\": \"nodemon src/server.ts\",\r\n \"format\": \"prettier --write .\",\r\n \"create:controller\": \"sundaysf --create-controller\",\r\n \"db:migrate\": \"npx knex migrate:latest --knexfile knexfile.ts\",\r\n \"db:rollback\": \"npx knex migrate:rollback --knexfile knexfile.ts\",\r\n \"db:seed\": \"npx knex seed:run --knexfile knexfile.ts\",\r\n \"db:make-migration\": \"npx knex migrate:make --knexfile knexfile.ts -x ts\"\r\n },\r\n dependencies: {\r\n \"morgan\": \"^1.10.0\",\r\n \"cors\": \"^2.8.5\",\r\n \"dotenv\": \"^16.4.7\",\r\n \"express\": \"^4.18.2\",\r\n \"knex\": \"^3.1.0\",\r\n \"lodash\": \"^4.17.21\",\r\n \"pg\": \"^8.14.1\",\r\n \"uuid\": \"^11.1.0\"\r\n },\r\n devDependencies: {\r\n \"@types/morgan\": \"^1.9.9\",\r\n \"@types/cors\": \"^2.8.17\",\r\n \"@types/express\": \"^4.17.21\",\r\n \"@types/lodash\": \"^4.17.16\",\r\n \"@types/node\": \"^22.13.13\",\r\n \"nodemon\": \"^3.0.2\",\r\n \"prettier\": \"^3.5.3\",\r\n \"rimraf\": \"^6.0.1\",\r\n \"ts-node\": \"^10.9.2\",\r\n \"typescript\": \"^5.8.2\",\r\n \"@eslint/js\": \"^9.23.0\",\r\n \"eslint\": \"^9.23.0\",\r\n \"globals\": \"^16.0.0\",\r\n \"typescript-eslint\": \"^8.28.0\"\r\n },\r\n author: \"\",\r\n license: \"MIT\"\r\n };\r\n } else if (templateType === 'frontend-nextjs') {\r\n packageJson = {\r\n name: dirName,\r\n version: \"0.1.0\",\r\n private: true,\r\n scripts: {\r\n \"dev\": \"next dev\",\r\n \"build\": \"next build\",\r\n \"start\": \"next start\",\r\n \"lint\": \"eslint .\"\r\n },\r\n dependencies: {\r\n \"@hookform/resolvers\": \"^3.9.1\",\r\n \"@radix-ui/react-accordion\": \"1.2.12\",\r\n \"@radix-ui/react-alert-dialog\": \"1.1.15\",\r\n \"@radix-ui/react-aspect-ratio\": \"1.1.8\",\r\n \"@radix-ui/react-avatar\": \"1.1.11\",\r\n \"@radix-ui/react-checkbox\": \"1.3.3\",\r\n \"@radix-ui/react-collapsible\": \"1.1.12\",\r\n \"@radix-ui/react-context-menu\": \"2.2.16\",\r\n \"@radix-ui/react-dialog\": \"1.1.15\",\r\n \"@radix-ui/react-dropdown-menu\": \"2.1.16\",\r\n \"@radix-ui/react-hover-card\": \"1.1.15\",\r\n \"@radix-ui/react-label\": \"2.1.8\",\r\n \"@radix-ui/react-menubar\": \"1.1.16\",\r\n \"@radix-ui/react-navigation-menu\": \"1.2.14\",\r\n \"@radix-ui/react-popover\": \"1.1.15\",\r\n \"@radix-ui/react-progress\": \"1.1.8\",\r\n \"@radix-ui/react-radio-group\": \"1.3.8\",\r\n \"@radix-ui/react-scroll-area\": \"1.2.10\",\r\n \"@radix-ui/react-select\": \"2.2.6\",\r\n \"@radix-ui/react-separator\": \"1.1.8\",\r\n \"@radix-ui/react-slider\": \"1.3.6\",\r\n \"@radix-ui/react-slot\": \"1.2.4\",\r\n \"@radix-ui/react-switch\": \"1.2.6\",\r\n \"@radix-ui/react-tabs\": \"1.1.13\",\r\n \"@radix-ui/react-toast\": \"1.2.15\",\r\n \"@radix-ui/react-toggle\": \"1.1.10\",\r\n \"@radix-ui/react-toggle-group\": \"1.1.11\",\r\n \"@radix-ui/react-tooltip\": \"1.2.8\",\r\n \"autoprefixer\": \"^10.4.20\",\r\n \"class-variance-authority\": \"^0.7.1\",\r\n \"clsx\": \"^2.1.1\",\r\n \"cmdk\": \"1.1.1\",\r\n \"date-fns\": \"4.1.0\",\r\n \"embla-carousel-react\": \"8.6.0\",\r\n \"framer-motion\": \"^12.38.0\",\r\n \"input-otp\": \"1.4.2\",\r\n \"lucide-react\": \"^0.564.0\",\r\n \"next\": \"16.1.6\",\r\n \"next-themes\": \"^0.4.6\",\r\n \"react\": \"19.2.4\",\r\n \"react-day-picker\": \"9.13.2\",\r\n \"react-dom\": \"19.2.4\",\r\n \"react-hook-form\": \"^7.54.1\",\r\n \"react-resizable-panels\": \"^2.1.7\",\r\n \"recharts\": \"2.15.0\",\r\n \"sonner\": \"^1.7.1\",\r\n \"tailwind-merge\": \"^3.3.1\",\r\n \"vaul\": \"^1.1.2\",\r\n \"zod\": \"^3.24.1\"\r\n },\r\n devDependencies: {\r\n \"@tailwindcss/postcss\": \"^4.2.0\",\r\n \"@types/node\": \"^22\",\r\n \"@types/react\": \"19.2.14\",\r\n \"@types/react-dom\": \"19.2.3\",\r\n \"postcss\": \"^8.5\",\r\n \"tailwindcss\": \"^4.2.0\",\r\n \"tw-animate-css\": \"1.3.3\",\r\n \"typescript\": \"5.7.3\"\r\n }\r\n };\r\n } else {\r\n // module\r\n packageJson = {\r\n name: dirName,\r\n version: \"1.0.0\",\r\n description: `Module generated with Sundays Framework`,\r\n main: \"dist/index.js\",\r\n types: \"dist/index.d.ts\",\r\n scripts: {\r\n \"test\": \"jest\",\r\n \"build\": \"tsc\",\r\n \"format\": \"prettier --write .\",\r\n \"clean\": \"rimraf dist && npm run build\"\r\n },\r\n dependencies: {},\r\n devDependencies: {\r\n \"prettier\": \"^3.5.3\",\r\n \"rimraf\": \"^6.0.1\",\r\n \"typescript\": \"^5.8.2\"\r\n },\r\n author: \"\",\r\n license: \"MIT\"\r\n };\r\n }\r\n\r\n await fs.writeJson(path.join(destDir, 'package.json'), packageJson, { spaces: 2 });\r\n\r\n if (['backend', 'backend-db-sql', 'backend-embedded-db-sql'].includes(templateType)) {\r\n const postmanBaseData = generateBasePostman(projectName);\r\n await fs.writeJson(path.join(destDir, 'postman.json'), postmanBaseData, { spaces: 2 });\r\n }\r\n\r\n if (templateType === 'backend-db-sql') {\r\n const dbPackageJson = {\r\n name: `${dirName}-db`,\r\n version: \"0.0.1\",\r\n description: \"Database module\",\r\n main: \"dist/index.js\",\r\n types: \"dist/index.d.ts\",\r\n scripts: {\r\n build: \"tsc\",\r\n clean: \"rimraf dist && npm run build\",\r\n format: \"prettier --write .\",\r\n \"npm:publish\": \"npm run clean && npm publish\",\r\n \"migrate:create\": \"knex migrate:make migration -x ts\",\r\n \"migrate:deploy\": \"knex migrate:latest\",\r\n \"seed:create\": \"knex seed:make seed -x ts\",\r\n \"seed:run\": \"knex seed:run\"\r\n },\r\n dependencies: {\r\n dotenv: \"^16.4.7\",\r\n knex: \"^3.1.0\",\r\n lodash: \"^4.17.21\",\r\n pg: \"^8.14.1\",\r\n uuid: \"^11.1.0\"\r\n },\r\n devDependencies: {\r\n typescript: \"^5.8.2\",\r\n \"ts-node\": \"^10.9.2\",\r\n rimraf: \"^6.0.1\",\r\n prettier: \"^3.5.3\",\r\n \"@types/node\": \"^22.13.13\"\r\n }\r\n };\r\n await fs.writeJson(path.join(destDir, 'db/package.json'), dbPackageJson, { spaces: 2 });\r\n }\r\n\r\n const spinnerGit = ora('Git init...').start();\r\n await initGitRepo(destDir);\r\n spinnerGit.succeed('Git initialized');\r\n\r\n const spinner = ora('Installing dependencies...').start();\r\n await runNpmInstall(destDir);\r\n spinner.succeed('Dependencies installed');\r\n\r\n await runFormatter(destDir);\r\n const outputMsg = projectName === '.' ? `Project created successfully in current directory` : `Project '${projectName}' created successfully in ./${dirName}`;\r\n console.log(outputMsg);\r\n });\r\n} else if (options.createController) {\r\n // Verify we're inside a backend project\r\n if (!fs.existsSync('./src/controllers') || !fs.existsSync('./postman.json')) {\r\n console.error('This command must be run inside a Sundays backend project.');\r\n console.error('Expected ./src/controllers/ and ./postman.json to exist.');\r\n process.exit(1);\r\n }\r\n\r\n inquirer.prompt([\r\n {\r\n type: 'input',\r\n name: 'controllerName',\r\n message: 'Controller name:',\r\n validate: input => {\r\n if (!input) return 'The controller name is empty';\r\n if (!/^[a-zA-Z][a-zA-Z0-9]*$/.test(input)) {\r\n return 'Name must start with a letter and contain only letters and numbers';\r\n }\r\n return true;\r\n }\r\n }\r\n ]).then(async ({ controllerName }) => {\r\n try {\r\n const nonCapitalized = controllerName.charAt(0).toLowerCase() + controllerName.slice(1);\r\n const capitalized = controllerName.charAt(0).toUpperCase() + controllerName.slice(1);\r\n const controllerClassName = `${capitalized}Controller`;\r\n const controllerFileName = `${nonCapitalized}.controller.ts`;\r\n const controllerDirectoryName = `${nonCapitalized}`;\r\n const routerClassName = `${capitalized}Router`;\r\n const routerFileName = `${nonCapitalized}.router.ts`;\r\n const routerDirectoryName = `${nonCapitalized}`;\r\n\r\n const controllerDir = `./src/controllers/${controllerDirectoryName}`;\r\n const routerDir = `./src/routes/${routerDirectoryName}`;\r\n\r\n if (fs.existsSync(controllerDir)) {\r\n console.error(`Controller directory \"${controllerDir}\" already exists.`);\r\n process.exit(1);\r\n }\r\n\r\n const classControllerContentGenerator = generateController(controllerClassName);\r\n const classRouterContentGenerator = generateRouter(routerClassName, controllerClassName, controllerDirectoryName);\r\n const controllerPath = `${controllerDir}/${controllerFileName}`;\r\n const routerPath = `${routerDir}/${routerFileName}`;\r\n\r\n await fs.mkdir(controllerDir, { recursive: true });\r\n await fs.mkdir(routerDir, { recursive: true });\r\n await fs.writeFile(controllerPath, classControllerContentGenerator);\r\n await fs.writeFile(routerPath, classRouterContentGenerator);\r\n\r\n const postmanBaseData = await fs.readFile('./postman.json', 'utf-8');\r\n const leanData = JSON.parse(postmanBaseData);\r\n const itemToPush = getItemFormatted(routerDirectoryName, leanData.info.name);\r\n leanData.item.push(itemToPush);\r\n await fs.writeJson(path.join('.', 'postman.json'), leanData, { spaces: 2 });\r\n\r\n await runFormatter('.');\r\n console.log(`Created ${controllerClassName} in ${controllerDirectoryName}/${controllerFileName} and ${routerClassName} in ${routerDirectoryName}/${routerFileName}`);\r\n } catch (err) {\r\n console.error('Error generating controller:', err.message);\r\n process.exit(1);\r\n }\r\n });\r\n} else {\r\n program.help();\r\n}\r\n\r\n\r\nfunction runFormatter(cwd = '.') {\r\n return new Promise((resolve, reject) => {\r\n const formatProcess = exec('npm run format', { cwd });\r\n\r\n formatProcess.stdout.on('data', data => process.stdout.write(data));\r\n formatProcess.stderr.on('data', data => process.stderr.write(data));\r\n\r\n formatProcess.on('close', code => {\r\n if (code === 0) {\r\n resolve();\r\n } else {\r\n reject(new Error(`npm format exited with code ${code}`));\r\n }\r\n });\r\n });\r\n}\r\n\r\n\r\nfunction runNpmInstall(destDir) {\r\n return new Promise((resolve, reject) => {\r\n const installProcess = exec('npm install', { cwd: destDir });\r\n\r\n installProcess.stdout.on('data', data => process.stdout.write(data));\r\n installProcess.stderr.on('data', data => process.stderr.write(data));\r\n\r\n installProcess.on('close', code => {\r\n if (code === 0) {\r\n resolve();\r\n } else {\r\n reject(new Error(`npm install exited with code ${code}`));\r\n }\r\n });\r\n });\r\n}\r\n\r\nfunction initGitRepo(destDir) {\r\n return new Promise((resolve, reject) => {\r\n const gitProcess = exec('git init', { cwd: destDir });\r\n\r\n gitProcess.stdout.on('data', data => process.stdout.write(data));\r\n gitProcess.stderr.on('data', data => process.stderr.write(data));\r\n\r\n gitProcess.on('close', code => {\r\n if (code === 0) {\r\n resolve();\r\n } else {\r\n reject(new Error(`Git init exited with code ${code}`));\r\n }\r\n });\r\n });\r\n}\r\n"]}
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"mappings":"","sources":["templates/backend/eslint.config.js"],"sourcesContent":["const eslint = require('@eslint/js');\r\nconst tseslint = require('typescript-eslint');\r\n\r\nmodule.exports = tseslint.config(\r\n eslint.configs.recommended,\r\n ...tseslint.configs.recommended,\r\n {\r\n languageOptions: {\r\n parserOptions: {\r\n project: './tsconfig.json',\r\n },\r\n },\r\n rules: {},\r\n },\r\n {\r\n ignores: ['dist/', 'node_modules/'],\r\n }\r\n);\r\n"],"file":"eslint.config.js"}
@@ -0,0 +1,52 @@
1
+ # Dependencies
2
+ node_modules/
3
+ package-lock.json
4
+ yarn.lock
5
+
6
+ # Build output
7
+ dist/
8
+ build/
9
+ *.js.map
10
+ *.tsbuildinfo
11
+
12
+ # Environment files
13
+ .env
14
+ .env.local
15
+ .env.development
16
+ .env.test
17
+ .env.production
18
+
19
+ # IDE
20
+ .vscode/
21
+ .idea/
22
+ *.swp
23
+ *.swo
24
+ *~
25
+
26
+ # OS
27
+ .DS_Store
28
+ Thumbs.db
29
+
30
+ # Logs
31
+ logs/
32
+ *.log
33
+ npm-debug.log*
34
+ yarn-debug.log*
35
+ yarn-error.log*
36
+ lerna-debug.log*
37
+
38
+ # Testing
39
+ coverage/
40
+ .nyc_output/
41
+
42
+ # Temporary files
43
+ tmp/
44
+ temp/
45
+ *.tmp
46
+ .cache/
47
+
48
+ # Package files
49
+ *.tgz
50
+
51
+ # Postman collection (auto-generated)
52
+ postman.json
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"mappings":"","sources":["templates/backend-db-sql/eslint.config.js"],"sourcesContent":["const eslint = require('@eslint/js');\r\nconst tseslint = require('typescript-eslint');\r\n\r\nmodule.exports = tseslint.config(\r\n eslint.configs.recommended,\r\n ...tseslint.configs.recommended,\r\n {\r\n languageOptions: {\r\n parserOptions: {\r\n project: './tsconfig.json',\r\n },\r\n },\r\n rules: {},\r\n },\r\n {\r\n ignores: ['dist/', 'node_modules/'],\r\n }\r\n);\r\n"],"file":"eslint.config.js"}
@@ -0,0 +1,65 @@
1
+ # Dependencies
2
+ node_modules/
3
+ package-lock.json
4
+ yarn.lock
5
+
6
+ # Build output
7
+ dist/
8
+ build/
9
+ *.js.map
10
+ *.d.ts.map
11
+ *.tsbuildinfo
12
+
13
+ # Environment files
14
+ .env
15
+ .env.local
16
+ .env.development
17
+ .env.test
18
+ .env.production
19
+
20
+ # IDE
21
+ .vscode/
22
+ .idea/
23
+ *.swp
24
+ *.swo
25
+ *~
26
+
27
+ # OS
28
+ .DS_Store
29
+ Thumbs.db
30
+
31
+ # Logs
32
+ logs/
33
+ *.log
34
+ npm-debug.log*
35
+ yarn-debug.log*
36
+ yarn-error.log*
37
+ lerna-debug.log*
38
+
39
+ # Testing
40
+ coverage/
41
+ .nyc_output/
42
+
43
+ # Temporary files
44
+ tmp/
45
+ temp/
46
+ *.tmp
47
+ .cache/
48
+
49
+ # Package files
50
+ *.tgz
51
+
52
+ # Postman collection (auto-generated)
53
+ postman.json
54
+
55
+ # Database
56
+ *.sqlite
57
+ *.sqlite3
58
+ *.db
59
+
60
+ # Keep migrations and seeds folders but ignore their compiled JS
61
+ db/migrations/*.js
62
+ !db/migrations/.gitkeep
63
+ db/seeds/*.js
64
+ !db/seeds/.gitkeep
65
+ db/dist/
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"mappings":"","sources":["templates/backend-embedded-db-sql/eslint.config.js"],"sourcesContent":["const eslint = require('@eslint/js');\nconst tseslint = require('typescript-eslint');\n\nmodule.exports = tseslint.config(\n eslint.configs.recommended,\n ...tseslint.configs.recommended,\n {\n languageOptions: {\n parserOptions: {\n project: './tsconfig.json',\n },\n },\n rules: {},\n },\n {\n ignores: ['dist/', 'node_modules/'],\n }\n);\n"],"file":"eslint.config.js"}
@@ -0,0 +1,64 @@
1
+ # Dependencies
2
+ node_modules/
3
+ package-lock.json
4
+ yarn.lock
5
+
6
+ # Build output
7
+ dist/
8
+ build/
9
+ *.js.map
10
+ *.d.ts.map
11
+ *.tsbuildinfo
12
+
13
+ # Environment files
14
+ .env
15
+ .env.local
16
+ .env.development
17
+ .env.test
18
+ .env.production
19
+
20
+ # IDE
21
+ .vscode/
22
+ .idea/
23
+ *.swp
24
+ *.swo
25
+ *~
26
+
27
+ # OS
28
+ .DS_Store
29
+ Thumbs.db
30
+
31
+ # Logs
32
+ logs/
33
+ *.log
34
+ npm-debug.log*
35
+ yarn-debug.log*
36
+ yarn-error.log*
37
+ lerna-debug.log*
38
+
39
+ # Testing
40
+ coverage/
41
+ .nyc_output/
42
+
43
+ # Temporary files
44
+ tmp/
45
+ temp/
46
+ *.tmp
47
+ .cache/
48
+
49
+ # Package files
50
+ *.tgz
51
+
52
+ # Postman collection (auto-generated)
53
+ postman.json
54
+
55
+ # Database
56
+ *.sqlite
57
+ *.sqlite3
58
+ *.db
59
+
60
+ # Keep migrations and seeds folders but ignore their compiled JS
61
+ migrations/*.js
62
+ !migrations/.gitkeep
63
+ seeds/*.js
64
+ !seeds/.gitkeep
@@ -0,0 +1,17 @@
1
+ # v0 sandbox internal files
2
+ __v0_runtime_loader.js
3
+ __v0_devtools.tsx
4
+ __v0_jsx-dev-runtime.ts
5
+ .npmrc
6
+ .snowflake/
7
+ .v0-trash/
8
+ .vercel/
9
+ next.user-config.*
10
+
11
+ # Environment variables
12
+ .env*.local
13
+
14
+ # Common ignores
15
+ node_modules/
16
+ .next/
17
+ .DS_Store
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sundaysf/cli-v2",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "description": "Sundays Framework CLI - Project scaffolding and CRUD code generation",
5
5
  "main": "./dist/bin/index.js",
6
6
  "scripts": {