nestjs-prisma-cli 1.0.2 → 1.0.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.
package/README.md CHANGED
@@ -8,8 +8,6 @@ A CLI tool to quickly scaffold a **NestJS + Prisma** project with pre-configured
8
8
 
9
9
  ## 📦 NestJS Prisma Generator CLI
10
10
 
11
- **`create-nestjs-prisma`**
12
-
13
11
  A CLI tool to quickly scaffold a **NestJS + Prisma** project with built-in support for:
14
12
 
15
13
  - 🔧 Prisma ORM with migrations and seeding
@@ -23,9 +21,46 @@ Compatible with **Node.js >=18** and **NestJS v10+**.
23
21
 
24
22
  ## 📥 Installation
25
23
 
26
- ### Using `npx` (recommended)
24
+ ## Quick Start Guide
25
+
26
+ Once the CLI is installed, you can use the following commands:
27
+
28
+ ### 1️⃣ Install CLI globally
27
29
 
28
30
  ```bash
31
+
29
32
  npm install -g nestjs-prisma-cli
30
33
 
31
34
  ```
35
+
36
+ ### 2️⃣ Check CLI version
37
+ ```bash
38
+
39
+ nestgen -v
40
+ # or
41
+ nestgen --version
42
+
43
+ ```
44
+
45
+ ### 3️⃣ Generate a new project
46
+ ```bash
47
+
48
+ nestgen
49
+
50
+ Step 1 : ? Enter your project name: my-app
51
+
52
+ Step 2 : ? Select your database: (Use arrow keys)
53
+ PostgreSQL
54
+ MySQL
55
+ SQLite
56
+ MongoDB
57
+ CockroachDB
58
+ SQLServer
59
+ Step 3 : 🎉 Project ready! Next steps:
60
+ cd my-app
61
+ Check .env
62
+ npm run start:dev
63
+ npm run prisma:migrate
64
+ npm run seed
65
+
66
+ ```
package/bin/index.cjs ADDED
@@ -0,0 +1,189 @@
1
+ #!/usr/bin/env node
2
+ const inquirer = require("inquirer");
3
+ const chalk = require("chalk");
4
+ const fs = require("fs-extra");
5
+ const path = require("path");
6
+ const { execa } = require("execa");
7
+ const { readFileSync } = require("fs");
8
+
9
+ const packageJson = JSON.parse(readFileSync(path.join(__dirname, "../package.json"), "utf-8"));
10
+
11
+ if (process.argv.includes("-v") || process.argv.includes("--version")) {
12
+ console.log(`nestgen ${packageJson.version}`);
13
+ process.exit(0);
14
+ }
15
+
16
+ if (process.argv.includes("-h") || process.argv.includes("--help")) {
17
+ console.log(`
18
+ Usage: nestgen [options]
19
+
20
+ Options:
21
+ -v, --version Show version
22
+ -h, --help Show help
23
+ `);
24
+ process.exit(0);
25
+ }
26
+
27
+ const detectPackageManager = () => {
28
+ try {
29
+ fs.accessSync(path.join(process.cwd(), "yarn.lock"));
30
+ return "yarn";
31
+ } catch {
32
+ return "npm";
33
+ }
34
+ };
35
+
36
+ async function main() {
37
+ console.log(chalk.blue("🚀 Welcome to NestJS + Prisma Project Generator!"));
38
+
39
+ const { projectName } = await inquirer.prompt([
40
+ { type: "input", name: "projectName", message: "Enter your project name:" }
41
+ ]);
42
+ const dbSafeName = projectName.replace(/-/g, "_") + "_db";
43
+ const projectPath = path.join(process.cwd(), projectName);
44
+
45
+ if (fs.existsSync(projectPath)) {
46
+ console.log(chalk.red(`❌ Folder "${projectName}" already exists!`));
47
+ process.exit(1);
48
+ }
49
+
50
+ const { database } = await inquirer.prompt([
51
+ {
52
+ type: "list",
53
+ name: "database",
54
+ message: "Select your database:",
55
+ choices: ["MySQL", "PostgreSQL", "SQLite", "MongoDB", "CockroachDB", "SQLServer"]
56
+ }
57
+ ]);
58
+
59
+ console.log(chalk.green(`📦 Creating NestJS project "${projectName}"...`));
60
+ await execa("npx", ["@nestjs/cli", "new", projectName, "--skip-install"], { stdio: "inherit" });
61
+
62
+ const pkgManager = detectPackageManager();
63
+ const coreDeps = [
64
+ "argon2",
65
+ "@nestjs/config",
66
+ "@nestjs/swagger",
67
+ "class-validator",
68
+ "class-transformer",
69
+ "winston",
70
+ "winston-daily-rotate-file",
71
+ "@nestjs/jwt",
72
+ "passport-jwt",
73
+ "@nestjs/passport",
74
+ "@aws-sdk/client-s3",
75
+ "@aws-sdk/s3-request-presigner",
76
+ "moment"
77
+ ];
78
+ await execa(pkgManager, ["install", ...coreDeps], { cwd: projectPath, stdio: "inherit" });
79
+ console.log(chalk.green("✅ Core dependencies installed!"));
80
+
81
+ await execa(pkgManager, ["install", "@prisma/client"], { cwd: projectPath, stdio: "inherit" });
82
+ await execa(pkgManager, ["install", "-D", "prisma"], { cwd: projectPath, stdio: "inherit" });
83
+ console.log(chalk.green("✅ Prisma and @prisma/client installed!"));
84
+
85
+ const templatePath = path.resolve(__dirname, "./template");
86
+ const projectPrismaPath = path.join(projectPath, "prisma/schema.prisma");
87
+
88
+ const providerMap = {
89
+ postgresql: "postgresql",
90
+ mysql: "mysql",
91
+ sqlite: "sqlite",
92
+ mongodb: "mongodb",
93
+ cockroachdb: "postgresql",
94
+ sqlserver: "sqlserver"
95
+ };
96
+ const selectedProvider = providerMap[database.toLowerCase()] || "mysql";
97
+
98
+ let prismaContent = "";
99
+ if (fs.existsSync(templatePath)) {
100
+ await fs.copy(templatePath, projectPath, { overwrite: true });
101
+ const templatePrismaPath = path.join(templatePath, "prisma/schema.prisma");
102
+ if (fs.existsSync(templatePrismaPath)) {
103
+ prismaContent = await fs.readFile(templatePrismaPath, "utf-8");
104
+ prismaContent = prismaContent.replace(
105
+ /datasource\s+db\s*{[^}]*provider\s*=\s*".*"/,
106
+ `datasource db {\n provider = "${selectedProvider}"`
107
+ );
108
+ }
109
+ }
110
+
111
+ if (!prismaContent) {
112
+ prismaContent = `generator client {
113
+ provider = "prisma-client-js"
114
+ }
115
+
116
+ datasource db {
117
+ provider = "${selectedProvider}"
118
+ url = env("DATABASE_URL")
119
+ }
120
+
121
+ model User {
122
+ id Int @id @default(autoincrement())
123
+ userId String @unique
124
+ name String?
125
+ email String
126
+ password String
127
+ isActive Boolean @default(true)
128
+ createdAt DateTime @default(now())
129
+ updatedAt DateTime @updatedAt
130
+ @@map("tbl_user")
131
+ }
132
+ `;
133
+ }
134
+
135
+ await fs.outputFile(projectPrismaPath, prismaContent);
136
+
137
+ const defaultUrlMap = {
138
+ postgresql: `postgresql://postgres:password@localhost:5432/${dbSafeName}?schema=public`,
139
+ mysql: `mysql://root:password@localhost:3306/${dbSafeName}?schema=public`,
140
+ sqlite: `file:./dev.db`,
141
+ mongodb: `mongodb://localhost:27017/${dbSafeName}`,
142
+ cockroachdb: `postgresql://root:password@localhost:26257/${dbSafeName}?sslmode=disable`,
143
+ sqlserver: `sqlserver://localhost:1433;database=${dbSafeName};user=sa;password=your_password;encrypt=false`
144
+ };
145
+
146
+ const envContent = `DATABASE_URL="${defaultUrlMap[database.toLowerCase()]}"
147
+
148
+ JWT_ACCESS_SECRET="JWT_ACCESS_SECRET"
149
+ JWT_REFRESH_SECRET="JWT_REFRESH_SECRET"
150
+ JWT_ACCESS_EXPIRATION_TIME="1d"
151
+ JWT_REFRESH_EXPIRATION_TIME="30d"
152
+
153
+ AWS_ACCESS_KEY_ID="AWS_ACCESS_KEY_ID"
154
+ AWS_SECRET_ACCESS_KEY="AWS_SECRET_ACCESS_KEY"
155
+ AWS_REGION=ap-southeast-1
156
+ S3_BUCKET="S3_BUCKET"
157
+
158
+ NODE_ENV=dev
159
+ PROJECT_NAME=${dbSafeName}
160
+ PORT=3000
161
+ `;
162
+
163
+ await fs.outputFile(path.join(projectPath, ".env"), envContent);
164
+ console.log(chalk.yellow("🎉 Project ready! Next steps:"));
165
+ console.log(chalk.cyan(`cd ${projectName}`));
166
+
167
+ console.log(chalk.green("✅ .env created! Please update DATABASE_URL if necessary before running seed."));
168
+
169
+ console.log(chalk.green("📦 Prisma installed!"));
170
+
171
+ console.log(chalk.yellow("🔧 Next steps (run manually):"));
172
+ console.log(chalk.cyan(`1. Generate Prisma Client:`));
173
+ console.log(chalk.cyan(` npx prisma generate`));
174
+
175
+ console.log(chalk.cyan(`2. Apply Prisma Migrations:`));
176
+ console.log(chalk.cyan(` npx prisma migrate dev --name init`));
177
+
178
+ console.log(chalk.cyan(`3. Run Seed Script:`));
179
+ console.log(chalk.cyan(` npx ts-node prisma/seed.ts`));
180
+
181
+ console.log(chalk.yellow("⚠️ Make sure your .env DATABASE_URL is correct before running the above commands!"));
182
+
183
+ console.log(chalk.cyan(`${pkgManager} run start:dev`));
184
+ }
185
+
186
+ main().catch(err => {
187
+ console.error(chalk.red("❌ Error:"), err);
188
+ process.exit(1);
189
+ });
@@ -17,7 +17,7 @@ async function main() {
17
17
  },
18
18
  });
19
19
 
20
- console.log("Seeded user successfully.");
20
+ console.log("Seeded Successfully.");
21
21
  }
22
22
 
23
23
  main()
@@ -2,7 +2,7 @@ import { ApiProperty } from '@nestjs/swagger';
2
2
  import { IsString } from 'class-validator';
3
3
 
4
4
  export class LoginDto {
5
- @ApiProperty({ example: 'USER-20250815001' })
5
+ @ApiProperty({ example: 'USER_20250815001' })
6
6
  @IsString()
7
7
  userId: string;
8
8
 
@@ -2,7 +2,7 @@ import { IsString, IsOptional, IsEmail } from 'class-validator';
2
2
  import { ApiProperty } from '@nestjs/swagger';
3
3
 
4
4
  export class CreateUserDto {
5
- @ApiProperty({ example: 'USER-20250815001' })
5
+ @ApiProperty({ example: 'USER_20250815001' })
6
6
  @IsString()
7
7
  userId: string;
8
8
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nestjs-prisma-cli",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "A CLI to generate NestJS + Prisma project boilerplate with Swagger, Auth, and AWS S3 setup",
5
5
  "main": "bin/index.js",
6
6
  "type": "module",
@@ -9,7 +9,7 @@
9
9
  "template/"
10
10
  ],
11
11
  "bin": {
12
- "nestgen": "./bin/index.js"
12
+ "nestgen": "./bin/index.cjs"
13
13
  },
14
14
  "scripts": {
15
15
  "start": "node ./bin/index.js",
package/bin/index.js DELETED
@@ -1,193 +0,0 @@
1
- import inquirer from "inquirer";
2
- import chalk from "chalk";
3
- import fs from "fs-extra";
4
- import path from "path";
5
- import { execa } from "execa";
6
- import { fileURLToPath } from "url";
7
-
8
- const __filename = fileURLToPath(import.meta.url);
9
- const __dirname = path.dirname(__filename);
10
-
11
- async function main() {
12
- console.log(chalk.blue("🚀 Welcome to NestJS + Prisma Project Generator!"));
13
-
14
- const { projectName } = await inquirer.prompt([
15
- { type: "input", name: "projectName", message: "Enter your project name:" }
16
- ]);
17
-
18
- const dbSafeName = projectName.replace(/-/g, "_") + "_db";
19
- const projectPath = path.join(process.cwd(), projectName);
20
-
21
- if (fs.existsSync(projectPath)) {
22
- console.log(chalk.red(`❌ Folder "${projectName}" already exists!`));
23
- process.exit(1);
24
- }
25
-
26
- const { database } = await inquirer.prompt([
27
- {
28
- type: "list",
29
- name: "database",
30
- message: "Select your database:",
31
- choices: ["PostgreSQL", "MySQL", "SQLite", "MongoDB", "CockroachDB", "SQLServer"]
32
- }
33
- ]);
34
-
35
- console.log(chalk.green(`📦 Creating NestJS project "${projectName}"...`));
36
- await execa("npx", ["@nestjs/cli", "new", projectName, "--skip-install"], { stdio: "inherit" });
37
-
38
- console.log(chalk.green("📥 Installing dependencies..."));
39
- await execa("npm", ["install"], { cwd: projectPath, stdio: "inherit" });
40
-
41
- await execa("npm", [
42
- "install",
43
- "--save",
44
- "@aws-sdk/client-s3",
45
- "@aws-sdk/s3-request-presigner",
46
- "@nestjs/config",
47
- "@nestjs/jwt",
48
- "@nestjs/passport",
49
- "@nestjs/swagger",
50
- "argon2",
51
- "class-transformer",
52
- "class-validator",
53
- "moment",
54
- "multer",
55
- "passport",
56
- "passport-jwt",
57
- "prisma",
58
- "@prisma/client",
59
- "reflect-metadata",
60
- "rxjs",
61
- "swagger-ui-express",
62
- "winston",
63
- "winston-daily-rotate-file"
64
- ], { cwd: projectPath, stdio: "inherit" });
65
-
66
- await execa("npm", [
67
- "install",
68
- "--save-dev",
69
- "@eslint/eslintrc",
70
- "@eslint/js",
71
- "@nestjs/cli",
72
- "@nestjs/schematics",
73
- "@nestjs/testing",
74
- "@swc/cli",
75
- "@swc/core",
76
- "@types/express",
77
- "@types/jest",
78
- "@types/multer",
79
- "@types/node",
80
- "@types/supertest",
81
- "eslint",
82
- "eslint-config-prettier",
83
- "eslint-plugin-prettier",
84
- "globals",
85
- "jest",
86
- "prettier",
87
- "source-map-support",
88
- "supertest",
89
- "ts-jest",
90
- "ts-loader",
91
- "ts-node",
92
- "tsconfig-paths",
93
- "typescript",
94
- "typescript-eslint"
95
- ], { cwd: projectPath, stdio: "inherit" });
96
-
97
- console.log(chalk.green("✅ Dependencies installed!"));
98
-
99
- const provider = database.toLowerCase() === "sqlserver" ? "sqlserver" : database.toLowerCase();
100
- const prismaSchema = `generator client {
101
- provider = "prisma-client-js"
102
- }
103
-
104
- datasource db {
105
- provider = "${provider}"
106
- url = env("DATABASE_URL")
107
- }
108
-
109
- model User {
110
- id Int @id @default(autoincrement())
111
- userId String @unique
112
- name String?
113
- email String
114
- password String
115
- isActive Boolean @default(true)
116
- createdAt DateTime @default(now())
117
- updatedAt DateTime @updatedAt
118
-
119
- @@map("tbl_user")
120
- }
121
- `;
122
- await fs.outputFile(path.join(projectPath, "prisma/schema.prisma"), prismaSchema);
123
-
124
- const defaultUrlMap = {
125
- postgresql: `postgresql://root:password@localhost:5432/${dbSafeName}?schema=public`,
126
- mysql: `mysql://root:password@localhost:3306/${dbSafeName}?schema=public`,
127
- sqlite: `file:./dev.db`,
128
- mongodb: `mongodb://localhost:27017/${dbSafeName}`,
129
- cockroachdb: `postgresql://root:password@localhost:26257/${dbSafeName}?sslmode=disable`,
130
- sqlserver: `sqlserver://localhost:1433;database=${dbSafeName};user=sa;password=your_password;encrypt=false`
131
- };
132
-
133
- const envContent = `DATABASE_URL="${defaultUrlMap[provider]}"
134
-
135
- JWT_ACCESS_SECRET="JWT_ACCESS_SECRET"
136
- JWT_REFRESH_SECRET="JWT_REFRESH_SECRET"
137
- JWT_ACCESS_EXPIRATION_TIME="1d"
138
- JWT_REFRESH_EXPIRATION_TIME="30d"
139
-
140
- AWS_ACCESS_KEY_ID="AWS_ACCESS_KEY_ID"
141
- AWS_SECRET_ACCESS_KEY="AWS_SECRET_ACCESS_KEY"
142
- AWS_REGION=ap-southeast-1
143
- S3_BUCKET="S3_BUCKET"
144
-
145
- NODE_ENV=dev
146
- PROJECT_NAME=${dbSafeName}
147
- PORT=3000
148
- `;
149
-
150
- await fs.outputFile(path.join(projectPath, ".env"), envContent);
151
- console.log(chalk.green("✅ Prisma schema + .env created!"));
152
-
153
- await execa("npx", ["prisma", "generate"], { cwd: projectPath, stdio: "inherit" });
154
- console.log(chalk.green("✅ Prisma client generated!"));
155
-
156
- const templatePath = path.join(__dirname, "template");
157
- if (!fs.existsSync(templatePath)) {
158
- console.log(chalk.red("❌ Template folder not found!"));
159
- process.exit(1);
160
- }
161
- await fs.copy(templatePath, projectPath, { overwrite: true });
162
- console.log(chalk.green("✅ Template files copied successfully!"));
163
-
164
- const packageJsonPath = path.join(projectPath, "package.json");
165
- const packageJson = await fs.readJSON(packageJsonPath);
166
- packageJson.scripts = {
167
- ...packageJson.scripts,
168
- "prisma:migrate": "prisma migrate dev --name init",
169
- "prisma:generate": "prisma generate",
170
- "prisma:deploy": "prisma migrate deploy",
171
- "prisma:studio": "prisma studio",
172
- "prisma:reset": "prisma migrate reset --force",
173
- "postinstall": "prisma generate",
174
- "migrate:dev": "dotenv -e .env -- prisma migrate dev",
175
- "migrate:staging": "dotenv -e .env -- prisma migrate deploy",
176
- "migrate:prod": "dotenv -e .env -- prisma migrate deploy",
177
- "seed": "ts-node prisma/seed.ts"
178
- };
179
- await fs.writeJSON(packageJsonPath, packageJson, { spaces: 2 });
180
- console.log(chalk.green("✅ package.json scripts updated successfully!"));
181
-
182
- console.log(chalk.yellow("🎉 Project is ready! Next steps:"));
183
- console.log(chalk.cyan(`cd ${projectName}`));
184
- console.log(chalk.cyan("Check .env"));
185
- console.log(chalk.cyan("npm run prisma:migrate"));
186
- console.log(chalk.cyan("npm run seed"));
187
- console.log(chalk.cyan("npm run start:dev"));
188
- }
189
-
190
- main().catch(err => {
191
- console.error(chalk.red("❌ Error:"), err);
192
- process.exit(1);
193
- });