@shakil-dev/shakil-stack 2.2.2 → 2.2.4

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.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/dist/index.js +23 -22
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -10,7 +10,7 @@
10
10
 
11
11
  ## 🌟 Key Features
12
12
 
13
- ### 🛡️ Backend Excellence (EchoNet Style)
13
+ ### 🛡️ Backend Excellence (Professional Coding Style)
14
14
  - **Modular Architecture**: Clean, scalable `src/app/module` pattern.
15
15
  - **Prisma 7+**: Next-gen database ORM with pre-configured PostgreSQL adapters.
16
16
  - **Better Auth Integration**: Pre-built authentication schemas (User, Session, Account).
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{Command as ae}from"commander";import Q from"fs-extra";import w from"path";import{fileURLToPath as ie}from"url";import o from"fs-extra";import s from"path";import n from"chalk";import ee from"ora";import M from"inquirer";import{execSync as X}from"child_process";import ue from"fs-extra";var i=(e,r=process.cwd())=>{try{return X(e,{stdio:"inherit",cwd:r}),!0}catch{return!1}},f=()=>{let e=process.env.npm_config_user_agent||"";return e.includes("pnpm")?"pnpm":e.includes("yarn")?"yarn":"npm"};var j=e=>`import { Server } from 'http';
2
+ import{Command as ie}from"commander";import Q from"fs-extra";import w from"path";import{fileURLToPath as pe}from"url";import o from"fs-extra";import s from"path";import a from"chalk";import te from"ora";import M from"inquirer";import{execSync as Z}from"child_process";import ge from"fs-extra";var i=(e,r=process.cwd())=>{try{return Z(e,{stdio:"inherit",cwd:r}),!0}catch{return!1}},h=()=>{let e=process.env.npm_config_user_agent||"";return e.includes("pnpm")?"pnpm":e.includes("yarn")?"yarn":"npm"};var j=e=>`import { Server } from 'http';
3
3
  import app from './app.js';
4
4
  import config from './app/config/index.js';
5
5
 
@@ -76,7 +76,7 @@ export default {
76
76
  database_url: process.env.DATABASE_URL,
77
77
  jwt_secret: process.env.JWT_SECRET,
78
78
  };
79
- `,R=`import "dotenv/config";
79
+ `,v=`import "dotenv/config";
80
80
  import { PrismaClient } from "@prisma/client";
81
81
  import pkg from 'pg';
82
82
  import { PrismaPg } from '@prisma/adapter-pg';
@@ -90,7 +90,7 @@ const prisma = new PrismaClient({ adapter });
90
90
 
91
91
  export default prisma;
92
92
  export { prisma };
93
- `,v=`import { betterAuth } from "better-auth";
93
+ `,R=`import { betterAuth } from "better-auth";
94
94
  import { prismaAdapter } from "better-auth/adapters/prisma";
95
95
  import config from "../config/index.js";
96
96
  import { prisma } from "./prisma.js";
@@ -132,7 +132,7 @@ const notFound = (req: Request, res: Response, next: NextFunction) => {
132
132
  };
133
133
 
134
134
  export default notFound;
135
- `,P=`import { NextFunction, Request, RequestHandler, Response } from 'express';
135
+ `,$=`import { NextFunction, Request, RequestHandler, Response } from 'express';
136
136
 
137
137
  const catchAsync = (fn: RequestHandler) => {
138
138
  return async (req: Request, res: Response, next: NextFunction) => {
@@ -145,7 +145,7 @@ const catchAsync = (fn: RequestHandler) => {
145
145
  };
146
146
 
147
147
  export default catchAsync;
148
- `,$=`class ApiError extends Error {
148
+ `,P=`class ApiError extends Error {
149
149
  statusCode: number;
150
150
  constructor(statusCode: number, message: string | undefined, stack = '') {
151
151
  super(message);
@@ -170,7 +170,7 @@ export const sanitize = (data: any): any => {
170
170
  }
171
171
  return data;
172
172
  };
173
- `,E=`import { Request, Response, NextFunction } from 'express';
173
+ `,C=`import { Request, Response, NextFunction } from 'express';
174
174
  import { sanitize } from '../utils/sanitizer.js';
175
175
 
176
176
  export const sanitizeRequest = (req: Request, res: Response, next: NextFunction) => {
@@ -179,7 +179,7 @@ export const sanitizeRequest = (req: Request, res: Response, next: NextFunction)
179
179
  if (req.params) sanitize(req.params);
180
180
  next();
181
181
  };
182
- `,C=`import { Response } from 'express';
182
+ `,E=`import { Response } from 'express';
183
183
 
184
184
  type IResponse<T> = {
185
185
  statusCode: number;
@@ -206,6 +206,7 @@ export default sendResponse;
206
206
  `,z=`generator client {
207
207
  provider = "prisma-client-js"
208
208
  previewFeatures = ["prismaSchemaFolder"]
209
+ output = "../../generated/prisma"
209
210
  }
210
211
 
211
212
  datasource db {
@@ -276,19 +277,19 @@ export default defineConfig({
276
277
  "include": ["src/**/*"],
277
278
  "exclude": ["node_modules", "dist"]
278
279
  }
279
- `;var b=async e=>{let r=e;r||(r=(await M.prompt([{type:"input",name:"projectName",message:"What is your project name?",default:"shakil-stack-app"}])).projectName),r||(console.log(n.red("\u274C Error: Project name is required.")),process.exit(1));let{packageManager:a,useShadcn:g,installDeps:c}=await M.prompt([{type:"list",name:"packageManager",message:"Which package manager do you want to use?",choices:["pnpm","npm","yarn"],default:f()},{type:"confirm",name:"useShadcn",message:"Would you like to use shadcn/ui?",default:!0},{type:"confirm",name:"installDeps",message:"Do you want to install dependencies automatically?",default:!0}]),t=s.join(process.cwd(),r);o.existsSync(t)&&(console.log(n.red(`\u274C Error: Directory ${r} already exists.`)),process.exit(1)),console.log(n.cyan(`
280
- \u{1F680} Initializing ${n.bold(r)}...
281
- `));let m=ee("\u{1F6E0}\uFE0F Creating project structure...").start();try{await o.ensureDir(t),await o.ensureDir(s.join(t,"backend","src","app","config")),await o.ensureDir(s.join(t,"backend","src","app","lib")),await o.ensureDir(s.join(t,"backend","src","app","module")),await o.ensureDir(s.join(t,"backend","src","app","routes")),await o.ensureDir(s.join(t,"backend","src","app","middleware")),await o.ensureDir(s.join(t,"backend","src","app","utils")),await o.ensureDir(s.join(t,"backend","src","app","errorHelpers")),await o.ensureDir(s.join(t,"backend","prisma","schema")),console.log(n.cyan(`
282
- \u{1F5BC}\uFE0F Scaffolding Next.js frontend...`)),i(`npx create-next-app@latest frontend --ts --tailwind --eslint --app --src-dir --import-alias "@/*" --use-${a}`,t);let d=["config","hooks","lib","services","types"];for(let y of d)await o.ensureDir(s.join(t,"frontend","src",y));if(g){console.log(n.cyan(`
283
- \u{1F3A8} Setting up shadcn/ui...`));try{i("npx shadcn@latest init -d",s.join(t,"frontend")),console.log(n.cyan("\u{1F4E6} Adding common shadcn/ui components...")),i(`npx shadcn@latest add ${["button","card","input","label","textarea","dialog","dropdown-menu","table","tabs","checkbox"].join(" ")} -y`,s.join(t,"frontend")),console.log(n.green("\u2705 shadcn/ui and common components initialized successfully!\u2728"))}catch{console.log(n.yellow(`
284
- \u26A0\uFE0F Warning: Failed to automate shadcn/ui init. You can run "npx shadcn@latest init" in the frontend folder.`))}}await o.outputFile(s.join(t,"backend","src","server.ts"),j(r)),await o.outputFile(s.join(t,"backend","src","app.ts"),T(r)),await o.outputFile(s.join(t,"backend","src","app","config","index.ts"),S),await o.outputFile(s.join(t,"backend","src","app","lib","prisma.ts"),R),await o.outputFile(s.join(t,"backend","src","app","lib","auth.ts"),v),await o.outputFile(s.join(t,"backend","src","app","routes","index.ts"),D),await o.outputFile(s.join(t,"backend","src","app","middleware","globalErrorHandler.ts"),A),await o.outputFile(s.join(t,"backend","src","app","middleware","notFound.ts"),F),await o.outputFile(s.join(t,"backend","src","app","middleware","sanitizeRequest.ts"),E),await o.outputFile(s.join(t,"backend","src","app","utils","catchAsync.ts"),P),await o.outputFile(s.join(t,"backend","src","app","utils","sendResponse.ts"),C),await o.outputFile(s.join(t,"backend","src","app","utils","sanitizer.ts"),q),await o.outputFile(s.join(t,"backend","src","app","errorHelpers","ApiError.ts"),$),await o.outputFile(s.join(t,"backend","prisma","schema","base.prisma"),z),await o.outputFile(s.join(t,"backend","prisma","schema","user.prisma"),I),await o.outputFile(s.join(t,"backend","prisma.config.ts"),O),await o.outputFile(s.join(t,"backend","tsconfig.json"),_),await o.outputFile(s.join(t,"backend",".gitignore"),`node_modules
280
+ `;var b=async e=>{let r=e;r||(r=(await M.prompt([{type:"input",name:"projectName",message:"What is your project name?",default:"shakil-stack-app"}])).projectName),r||(console.log(a.red("\u274C Error: Project name is required.")),process.exit(1));let{packageManager:n,useShadcn:g,installDeps:c}=await M.prompt([{type:"list",name:"packageManager",message:"Which package manager do you want to use?",choices:["pnpm","npm","yarn"],default:h()},{type:"confirm",name:"useShadcn",message:"Would you like to use shadcn/ui?",default:!0},{type:"confirm",name:"installDeps",message:"Do you want to install dependencies automatically?",default:!0}]),t=s.join(process.cwd(),r);o.existsSync(t)&&(console.log(a.red(`\u274C Error: Directory ${r} already exists.`)),process.exit(1)),console.log(a.cyan(`
281
+ \u{1F680} Initializing ${a.bold(r)}...
282
+ `));let m=te("\u{1F6E0}\uFE0F Creating project structure...").start();try{await o.ensureDir(t),await o.ensureDir(s.join(t,"backend","src","app","config")),await o.ensureDir(s.join(t,"backend","src","app","lib")),await o.ensureDir(s.join(t,"backend","src","app","module")),await o.ensureDir(s.join(t,"backend","src","app","routes")),await o.ensureDir(s.join(t,"backend","src","app","middleware")),await o.ensureDir(s.join(t,"backend","src","app","utils")),await o.ensureDir(s.join(t,"backend","src","app","errorHelpers")),await o.ensureDir(s.join(t,"backend","prisma","schema")),console.log(a.cyan(`
283
+ \u{1F5BC}\uFE0F Scaffolding Next.js frontend...`)),i(`npx create-next-app@latest frontend --ts --tailwind --eslint --app --src-dir --import-alias "@/*" --use-${n}`,t);let d=["config","hooks","lib","services","types"];for(let f of d)await o.ensureDir(s.join(t,"frontend","src",f));if(g){console.log(a.cyan(`
284
+ \u{1F3A8} Setting up shadcn/ui...`));try{i("npx shadcn@latest init -d",s.join(t,"frontend")),console.log(a.cyan("\u{1F4E6} Adding common shadcn/ui components...")),i(`npx shadcn@latest add ${["button","card","input","label","textarea","dialog","dropdown-menu","table","tabs","checkbox"].join(" ")} -y`,s.join(t,"frontend")),console.log(a.green("\u2705 shadcn/ui and common components initialized successfully!\u2728"))}catch{console.log(a.yellow(`
285
+ \u26A0\uFE0F Warning: Failed to automate shadcn/ui init. You can run "npx shadcn@latest init" in the frontend folder.`))}}await o.outputFile(s.join(t,"backend","src","server.ts"),j(r)),await o.outputFile(s.join(t,"backend","src","app.ts"),T(r)),await o.outputFile(s.join(t,"backend","src","app","config","index.ts"),S),await o.outputFile(s.join(t,"backend","src","app","lib","prisma.ts"),v),await o.outputFile(s.join(t,"backend","src","app","lib","auth.ts"),R),await o.outputFile(s.join(t,"backend","src","app","routes","index.ts"),D),await o.outputFile(s.join(t,"backend","src","app","middleware","globalErrorHandler.ts"),A),await o.outputFile(s.join(t,"backend","src","app","middleware","notFound.ts"),F),await o.outputFile(s.join(t,"backend","src","app","middleware","sanitizeRequest.ts"),C),await o.outputFile(s.join(t,"backend","src","app","utils","catchAsync.ts"),$),await o.outputFile(s.join(t,"backend","src","app","utils","sendResponse.ts"),E),await o.outputFile(s.join(t,"backend","src","app","utils","sanitizer.ts"),q),await o.outputFile(s.join(t,"backend","src","app","errorHelpers","ApiError.ts"),P),await o.outputFile(s.join(t,"backend","prisma","schema","schema.prisma"),z),await o.outputFile(s.join(t,"backend","prisma","schema","auth.prisma"),I);let y=["meal.prisma","order.prisma","provider.prisma","review.prisma"];for(let f of y)await o.outputFile(s.join(t,"backend","prisma","schema",f),"// ${schema.split('.')[0].charAt(0).toUpperCase() + schema.split('.')[0].slice(1)} model\n");await o.outputFile(s.join(t,"backend","prisma.config.ts"),O),await o.outputFile(s.join(t,"backend","tsconfig.json"),_),await o.outputFile(s.join(t,"backend",".gitignore"),`node_modules
285
286
  dist
286
287
  .env`),await o.outputFile(s.join(t,"backend",".env"),`DATABASE_URL="postgresql://user:password@localhost:5432/mydb"
287
- JWT_SECRET="your-secret-key"`);let h={name:`${r}-backend`,version:"1.0.0",type:"module",scripts:{test:'echo "Error: no test specified" && exit 1',dev:"nodemon --exec tsx src/server.ts",build:"prisma generate && tsup src/server.ts --format esm --platform node --target node20 --outDir dist --external pg-native",postinstall:"prisma generate",start:"node dist/server.js","prisma:generate":"prisma generate","prisma:migrate":"prisma migrate dev","prisma:studio":"prisma studio",seed:"tsx prisma/seed.ts",setup:"pnpm install && pnpm add @prisma/adapter-pg pg && pnpm add -D @types/pg && pnpm prisma:generate",predev:"pnpm run prisma:generate",init:"pnpm run prisma:generate && pnpm run prisma:migrate --name init",lint:"eslint src/**/*.ts","lint:fix":"eslint src/**/*.ts --fix",format:"prettier --write .",push:"prisma db push",pull:"prisma db pull"},dependencies:{"@prisma/adapter-pg":"^7.5.0","@prisma/client":"^7.5.0","better-auth":"^1.5.6","cookie-parser":"^1.4.7",cors:"^2.8.6",dompurify:"^3.3.3",dotenv:"^17.3.1",express:"^5.2.1","express-rate-limit":"^8.3.1",helmet:"^8.1.0","http-status":"^2.1.0",jsdom:"^29.0.1",jsonwebtoken:"^9.0.3",morgan:"^1.10.1",pg:"^8.20.0",winston:"^3.19.0",zod:"^4.3.6"},devDependencies:{"@types/cookie-parser":"^1.4.10","@types/cors":"^2.8.19","@types/express":"^5.0.6","@types/node":"^20.19.37","@types/pg":"^8.20.0","@types/morgan":"^1.9.10","@types/jsdom":"^21.1.7",prisma:"^7.5.0",tsx:"^4.21.0",nodemon:"^3.1.14",tsup:"^8.5.1",typescript:"^5.9.3",eslint:"^9.21.0",prettier:"^3.5.2"}};await o.writeJson(s.join(t,"backend","package.json"),h,{spaces:2}),m.succeed(n.green("\u2705 Project structure created! \u2728")),c&&(console.log(n.yellow(`
288
- \u{1F4E6} Finalizing dependencies with ${a}...
289
- `)),i(`${a} install`,s.join(t,"backend"))),console.log(n.cyan("To get started:")),console.log(n.white(` cd ${r}`)),console.log(n.white(` cd backend && ${a} dev
290
- `)),console.log(n.white(` cd frontend && ${a} dev
291
- `))}catch(d){m.fail(n.red("\u274C Failed to initialize project.")),console.error(d),process.exit(1)}};import l from"fs-extra";import x from"path";import p from"chalk";import re from"ora";var H=(e,r)=>`import { Request, Response } from 'express';
288
+ JWT_SECRET="your-secret-key"`);let X={name:`${r}-backend`,version:"1.0.0",type:"module",scripts:{test:'echo "Error: no test specified" && exit 1',dev:"nodemon --exec tsx src/server.ts",build:"prisma generate && tsup src/server.ts --format esm --platform node --target node20 --outDir dist --external pg-native",postinstall:"prisma generate",start:"node dist/server.js","prisma:generate":"prisma generate","prisma:migrate":"prisma migrate dev","prisma:studio":"prisma studio",seed:"tsx prisma/seed.ts",setup:"pnpm install && pnpm add @prisma/adapter-pg pg && pnpm add -D @types/pg && pnpm prisma:generate",predev:"pnpm run prisma:generate",init:"pnpm run prisma:generate && pnpm run prisma:migrate --name init",lint:"eslint src/**/*.ts","lint:fix":"eslint src/**/*.ts --fix",format:"prettier --write .",push:"prisma db push",pull:"prisma db pull"},dependencies:{"@prisma/adapter-pg":"^7.5.0","@prisma/client":"^7.5.0","better-auth":"^1.5.6","cookie-parser":"^1.4.7",cors:"^2.8.6",dompurify:"^3.3.3",dotenv:"^17.3.1",express:"^5.2.1","express-rate-limit":"^8.3.1",helmet:"^8.1.0","http-status":"^2.1.0",jsdom:"^29.0.1",jsonwebtoken:"^9.0.3",morgan:"^1.10.1",pg:"^8.20.0",winston:"^3.19.0",zod:"^4.3.6"},devDependencies:{"@types/cookie-parser":"^1.4.10","@types/cors":"^2.8.19","@types/express":"^5.0.6","@types/node":"^20.19.37","@types/pg":"^8.20.0","@types/morgan":"^1.9.10","@types/jsdom":"^21.1.7",prisma:"^7.5.0",tsx:"^4.21.0",nodemon:"^3.1.14",tsup:"^8.5.1",typescript:"^5.9.3",eslint:"^9.21.0",prettier:"^3.5.2"}};await o.writeJson(s.join(t,"backend","package.json"),X,{spaces:2}),m.succeed(a.green("\u2705 Project structure created! \u2728")),c&&(console.log(a.yellow(`
289
+ \u{1F4E6} Finalizing dependencies with ${n}...
290
+ `)),i(`${n} install`,s.join(t,"backend"))),console.log(a.cyan("To get started:")),console.log(a.white(` cd ${r}`)),console.log(a.white(` cd backend && ${n} dev
291
+ `)),console.log(a.white(` cd frontend && ${n} dev
292
+ `))}catch(d){m.fail(a.red("\u274C Failed to initialize project.")),console.error(d),process.exit(1)}};import l from"fs-extra";import x from"path";import p from"chalk";import se from"ora";var H=(e,r)=>`import { Request, Response } from 'express';
292
293
  import httpStatus from 'http-status';
293
294
  import catchAsync from '../../utils/catchAsync.js';
294
295
  import sendResponse from '../../utils/sendResponse.js';
@@ -307,7 +308,7 @@ const create${e} = catchAsync(async (req: Request, res: Response) => {
307
308
  export const ${e}Controller = {
308
309
  create${e},
309
310
  };
310
- `,L=(e,r)=>`import { ${e} } from '@prisma/client';
311
+ `,U=(e,r)=>`import { ${e} } from '@prisma/client';
311
312
  import prisma from '../../lib/prisma.js';
312
313
 
313
314
  const create${e}IntoDB = async (payload: any) => {
@@ -318,7 +319,7 @@ const create${e}IntoDB = async (payload: any) => {
318
319
  export const ${e}Service = {
319
320
  create${e}IntoDB,
320
321
  };
321
- `,N=(e,r)=>`import { Router } from 'express';
322
+ `,L=(e,r)=>`import { Router } from 'express';
322
323
  import { ${e}Controller } from './${r}.controller.js';
323
324
 
324
325
  const router = Router();
@@ -326,7 +327,7 @@ const router = Router();
326
327
  router.post('/create-${r}', ${e}Controller.create${e});
327
328
 
328
329
  export const ${e}Routes = router;
329
- `,U=e=>`export type I${e} = {
330
+ `,N=e=>`export type I${e} = {
330
331
  // Define interface
331
332
  };
332
333
  `,B=e=>`import { z } from 'zod';
@@ -347,4 +348,4 @@ export const ${e}Validations = {
347
348
  createdAt DateTime @default(now())
348
349
  updatedAt DateTime @updatedAt
349
350
  }
350
- `;var V=async e=>{e||(console.log(p.red("\u274C Error: Module name is required.")),process.exit(1));let r=e.charAt(0).toUpperCase()+e.slice(1),a=e.toLowerCase(),g=l.existsSync("backend")?"backend":".",c=x.join(g,"src","app","module",r);l.existsSync(x.join(g,"src","app","module"))||(console.log(p.red("\u274C Error: This command must be run inside your shakil-stack project root or backend directory.")),process.exit(1)),l.existsSync(c)&&(console.log(p.red(`\u274C Error: Module ${r} already exists.`)),process.exit(1));let t=re(`\u{1F6E0}\uFE0F Generating module: ${p.cyan(r)}...`).start();try{await l.ensureDir(c);let m={"controller.ts":H(r,a),"service.ts":L(r,a),"route.ts":N(r,a),"interface.ts":U(r),"validation.ts":B(r),"constant.ts":J(r)};await l.outputFile(x.join(g,"prisma","schema",`${a}.prisma`),W(r));for(let[d,h]of Object.entries(m))await l.outputFile(x.join(c,`${a}.${d}`),h);t.succeed(p.green(`\u2705 Module ${r} generated successfully! \u2728`)),console.log(p.gray(`Created at: ${c}`))}catch(m){t.fail(p.red("\u274C Failed to generate module.")),console.error(m)}};import se from"fs-extra";import oe from"chalk";var G=async()=>{let e=f(),r=se.existsSync("backend")?"backend":".";console.log(oe.cyan(`\u{1F3D7}\uFE0F Building backend with ${e}...`)),i(`${e} run build`,r)};import ne from"fs-extra";import k from"chalk";var K=async e=>{let r=ne.existsSync("backend")?"backend":".";e==="generate"?(console.log(k.cyan("\u{1F504} Generating Prisma client...")),i("npx prisma generate",r)):e==="migrate"?(console.log(k.cyan("\u{1F680} Running Prisma migrations...")),i("npx prisma migrate dev",r)):console.log(k.red(`\u274C Error: Unknown prisma subcommand: ${e}`))};var pe=ie(import.meta.url),Y=w.dirname(pe),ce=w.resolve(Y,Q.existsSync(w.resolve(Y,"../../package.json"))?"../../package.json":"../package.json"),me=Q.readJsonSync(ce),u=new ae;u.name("shakil-stack").description("Full-stack EchoNet-style project generator CLI").version(me.version);u.command("init").description("Initialize a new full-stack project").argument("[projectName]","Name of the project").action(e=>{b(e)});u.command("generate").alias("g").description("Generate a new module").argument("<type>","Type of generation (module)").argument("<name>","Name of the module").action((e,r)=>{e==="module"?V(r):console.log(`\u274C Error: Unknown generation type: ${e}`)});u.command("build").description("Build the backend for production").action(()=>{G()});u.command("prisma").description("Prisma utilities").argument("<subcommand>","generate | migrate").action(e=>{K(e)});process.argv.slice(2).length?u.parse(process.argv):b();
351
+ `;var V=async e=>{e||(console.log(p.red("\u274C Error: Module name is required.")),process.exit(1));let r=e.charAt(0).toUpperCase()+e.slice(1),n=e.toLowerCase(),g=l.existsSync("backend")?"backend":".",c=x.join(g,"src","app","module",r);l.existsSync(x.join(g,"src","app","module"))||(console.log(p.red("\u274C Error: This command must be run inside your shakil-stack project root or backend directory.")),process.exit(1)),l.existsSync(c)&&(console.log(p.red(`\u274C Error: Module ${r} already exists.`)),process.exit(1));let t=se(`\u{1F6E0}\uFE0F Generating module: ${p.cyan(r)}...`).start();try{await l.ensureDir(c);let m={"controller.ts":H(r,n),"service.ts":U(r,n),"route.ts":L(r,n),"interface.ts":N(r),"validation.ts":B(r),"constant.ts":J(r)};await l.outputFile(x.join(g,"prisma","schema",`${n}.prisma`),W(r));for(let[d,y]of Object.entries(m))await l.outputFile(x.join(c,`${n}.${d}`),y);t.succeed(p.green(`\u2705 Module ${r} generated successfully! \u2728`)),console.log(p.gray(`Created at: ${c}`))}catch(m){t.fail(p.red("\u274C Failed to generate module.")),console.error(m)}};import oe from"fs-extra";import ae from"chalk";var G=async()=>{let e=h(),r=oe.existsSync("backend")?"backend":".";console.log(ae.cyan(`\u{1F3D7}\uFE0F Building backend with ${e}...`)),i(`${e} run build`,r)};import ne from"fs-extra";import k from"chalk";var K=async e=>{let r=ne.existsSync("backend")?"backend":".";e==="generate"?(console.log(k.cyan("\u{1F504} Generating Prisma client...")),i("npx prisma generate",r)):e==="migrate"?(console.log(k.cyan("\u{1F680} Running Prisma migrations...")),i("npx prisma migrate dev",r)):console.log(k.red(`\u274C Error: Unknown prisma subcommand: ${e}`))};var ce=pe(import.meta.url),Y=w.dirname(ce),me=w.resolve(Y,Q.existsSync(w.resolve(Y,"../../package.json"))?"../../package.json":"../package.json"),de=Q.readJsonSync(me),u=new ie;u.name("shakil-stack").description("Full-stack EchoNet-style project generator CLI").version(de.version);u.command("init").description("Initialize a new full-stack project").argument("[projectName]","Name of the project").action(e=>{b(e)});u.command("generate").alias("g").description("Generate a new module").argument("<type>","Type of generation (module)").argument("<name>","Name of the module").action((e,r)=>{e==="module"?V(r):console.log(`\u274C Error: Unknown generation type: ${e}`)});u.command("build").description("Build the backend for production").action(()=>{G()});u.command("prisma").description("Prisma utilities").argument("<subcommand>","generate | migrate").action(e=>{K(e)});process.argv.slice(2).length?u.parse(process.argv):b();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shakil-dev/shakil-stack",
3
- "version": "2.2.2",
3
+ "version": "2.2.4",
4
4
  "description": "Full-stack EchoNet-style project generator CLI",
5
5
  "keywords": [
6
6
  "shakil-stack",