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