lapeh 1.0.1 ā 1.0.3
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/.env.example +16 -16
- package/bin/index.js +105 -105
- package/framework.md +105 -0
- package/nodemon.json +6 -0
- package/package.json +73 -70
- package/prisma/base.prisma +8 -8
- package/prisma/migrations/20251225163737_init/migration.sql +236 -236
- package/prisma/migrations/migration_lock.toml +3 -3
- package/prisma/schema.prisma +0 -7
- package/prisma.config.ts +15 -15
- package/readme.md +126 -120
- package/scripts/generate-jwt-secret.js +38 -38
- package/scripts/init-project.js +71 -0
- package/scripts/make-model.js +42 -42
- package/scripts/make-module.js +158 -158
- package/src/controllers/rbacController.ts +353 -353
- package/src/middleware/auth.ts +56 -56
- package/src/middleware/error.ts +7 -7
- package/src/middleware/visitor.ts +180 -180
- package/src/models/schema.prisma +159 -159
- package/src/routes/rbac.ts +55 -55
- package/src/schema/auth-schema.ts +62 -62
- package/src/utils/pagination.ts +56 -56
package/readme.md
CHANGED
|
@@ -1,120 +1,126 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
**
|
|
4
|
-
|
|
5
|
-
## š Fitur Utama
|
|
6
|
-
|
|
7
|
-
- **Struktur Modular**: Terorganisir rapi dengan Controllers, Services, Routes, dan Middleware.
|
|
8
|
-
- **TypeScript Ready**: Full TypeScript support untuk type-safety.
|
|
9
|
-
- **Prisma ORM**: Integrasi database yang modern dan type-safe.
|
|
10
|
-
- **Schema Terpisah**: Mendukung pemisahan schema Prisma per model (mirip Eloquent).
|
|
11
|
-
- **Generator Tools**: CLI commands untuk generate Module dan Model dengan cepat.
|
|
12
|
-
- **Security Best Practices**: Dilengkapi dengan Helmet, Rate Limiting, CORS, dan JWT Authentication.
|
|
13
|
-
- **Validasi Data**: Menggunakan Zod untuk validasi request yang kuat.
|
|
14
|
-
|
|
15
|
-
## š¦ Instalasi & Penggunaan
|
|
16
|
-
|
|
17
|
-
Buat project baru cukup dengan satu perintah:
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
npx lapeh
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
### Apa yang terjadi otomatis?
|
|
24
|
-
|
|
25
|
-
1. Struktur project dibuat.
|
|
26
|
-
2. Dependencies diinstall.
|
|
27
|
-
3. Environment variable (`.env`) disiapkan.
|
|
28
|
-
4. **JWT Secret** di-generate otomatis.
|
|
29
|
-
|
|
30
|
-
Masuk ke folder project dan jalankan:
|
|
31
|
-
|
|
32
|
-
```bash
|
|
33
|
-
cd nama-project-anda
|
|
34
|
-
npm run dev
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
Server akan berjalan di `http://localhost:4000`.
|
|
38
|
-
|
|
39
|
-
---
|
|
40
|
-
|
|
41
|
-
## š Development Tools
|
|
42
|
-
|
|
43
|
-
API Lapeh menyediakan tools untuk mempercepat development, mirip dengan `artisan` di Laravel.
|
|
44
|
-
|
|
45
|
-
### 1. Membuat Module (Resource)
|
|
46
|
-
|
|
47
|
-
Membuat Controller, Service, dan Route sekaligus.
|
|
48
|
-
|
|
49
|
-
```bash
|
|
50
|
-
npm run make:module NamaResource
|
|
51
|
-
# Contoh: npm run make:module Product
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
Command ini akan membuat:
|
|
55
|
-
|
|
56
|
-
- `src/controllers/product.controller.ts`
|
|
57
|
-
- `src/services/product.service.ts`
|
|
58
|
-
- `src/routes/product.route.ts` (dan otomatis didaftarkan di `src/routes/index.ts` jika memungkinkan)
|
|
59
|
-
|
|
60
|
-
### 2. Membuat Model Database
|
|
61
|
-
|
|
62
|
-
Membuat file model Prisma baru di dalam folder `src/models/` (atau `prisma/models` tergantung konfigurasi).
|
|
63
|
-
|
|
64
|
-
```bash
|
|
65
|
-
npm run make:model NamaModel
|
|
66
|
-
# Contoh: npm run make:model User
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
Ini akan membuat file `src/models/User.prisma`.
|
|
70
|
-
|
|
71
|
-
### 3. Workflow Database (Prisma)
|
|
72
|
-
|
|
73
|
-
Karena framework ini menggunakan **Schema Terpisah** (split schema), Anda **TIDAK BOLEH** mengedit `prisma/schema.prisma` secara manual.
|
|
74
|
-
|
|
75
|
-
- **Edit Models**: Lakukan perubahan di `src/models/*.prisma`.
|
|
76
|
-
- **Apply Changes**: Jalankan perintah migrasi standar, sistem akan otomatis menggabungkan (compile) schema Anda.
|
|
77
|
-
|
|
78
|
-
```bash
|
|
79
|
-
# Generate Prisma Client (setiap ada perubahan model)
|
|
80
|
-
npm run prisma:generate
|
|
81
|
-
|
|
82
|
-
# Migrasi Database (Development)
|
|
83
|
-
npm run prisma:migrate
|
|
84
|
-
|
|
85
|
-
#
|
|
86
|
-
npm run
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
āāā
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
āāā
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
1
|
+
# Lapeh Framework
|
|
2
|
+
|
|
3
|
+
**Lapeh** adalah framework berbasis Express.js yang terstandarisasi, dirancang untuk mempercepat pengembangan REST API dengan struktur yang solid, aman, dan scalable. Terinspirasi oleh struktur Laravel dan NestJS, namun tetap menjaga kesederhanaan Express.
|
|
4
|
+
|
|
5
|
+
## š Fitur Utama
|
|
6
|
+
|
|
7
|
+
- **Struktur Modular**: Terorganisir rapi dengan Controllers, Services, Routes, dan Middleware.
|
|
8
|
+
- **TypeScript Ready**: Full TypeScript support untuk type-safety.
|
|
9
|
+
- **Prisma ORM**: Integrasi database yang modern dan type-safe.
|
|
10
|
+
- **Schema Terpisah**: Mendukung pemisahan schema Prisma per model (mirip Eloquent).
|
|
11
|
+
- **Generator Tools**: CLI commands untuk generate Module dan Model dengan cepat.
|
|
12
|
+
- **Security Best Practices**: Dilengkapi dengan Helmet, Rate Limiting, CORS, dan JWT Authentication.
|
|
13
|
+
- **Validasi Data**: Menggunakan Zod untuk validasi request yang kuat.
|
|
14
|
+
|
|
15
|
+
## š¦ Instalasi & Penggunaan
|
|
16
|
+
|
|
17
|
+
Buat project baru cukup dengan satu perintah:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npx lapeh nama-project-anda
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Apa yang terjadi otomatis?
|
|
24
|
+
|
|
25
|
+
1. Struktur project dibuat.
|
|
26
|
+
2. Dependencies diinstall.
|
|
27
|
+
3. Environment variable (`.env`) disiapkan.
|
|
28
|
+
4. **JWT Secret** di-generate otomatis.
|
|
29
|
+
|
|
30
|
+
Masuk ke folder project dan jalankan:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
cd nama-project-anda
|
|
34
|
+
npm run dev
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Server akan berjalan di `http://localhost:4000`.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## š Development Tools
|
|
42
|
+
|
|
43
|
+
API Lapeh menyediakan tools untuk mempercepat development, mirip dengan `artisan` di Laravel.
|
|
44
|
+
|
|
45
|
+
### 1. Membuat Module (Resource)
|
|
46
|
+
|
|
47
|
+
Membuat Controller, Service, dan Route sekaligus.
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
npm run make:module NamaResource
|
|
51
|
+
# Contoh: npm run make:module Product
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Command ini akan membuat:
|
|
55
|
+
|
|
56
|
+
- `src/controllers/product.controller.ts`
|
|
57
|
+
- `src/services/product.service.ts`
|
|
58
|
+
- `src/routes/product.route.ts` (dan otomatis didaftarkan di `src/routes/index.ts` jika memungkinkan)
|
|
59
|
+
|
|
60
|
+
### 2. Membuat Model Database
|
|
61
|
+
|
|
62
|
+
Membuat file model Prisma baru di dalam folder `src/models/` (atau `prisma/models` tergantung konfigurasi).
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
npm run make:model NamaModel
|
|
66
|
+
# Contoh: npm run make:model User
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Ini akan membuat file `src/models/User.prisma`.
|
|
70
|
+
|
|
71
|
+
### 3. Workflow Database (Prisma)
|
|
72
|
+
|
|
73
|
+
Karena framework ini menggunakan **Schema Terpisah** (split schema), Anda **TIDAK BOLEH** mengedit `prisma/schema.prisma` secara manual.
|
|
74
|
+
|
|
75
|
+
- **Edit Models**: Lakukan perubahan di `src/models/*.prisma`.
|
|
76
|
+
- **Apply Changes**: Jalankan perintah migrasi standar, sistem akan otomatis menggabungkan (compile) schema Anda.
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# Generate Prisma Client (setiap ada perubahan model)
|
|
80
|
+
npm run prisma:generate
|
|
81
|
+
|
|
82
|
+
# Migrasi Database (Development)
|
|
83
|
+
npm run prisma:migrate
|
|
84
|
+
|
|
85
|
+
# Membuka GUI Database (Prisma Studio)
|
|
86
|
+
npm run db:studio
|
|
87
|
+
|
|
88
|
+
# Migrasi Database Dan Seed (Development - Reset Total default option for development)
|
|
89
|
+
npm run db:reset
|
|
90
|
+
|
|
91
|
+
# Deploy ke Production
|
|
92
|
+
npm run prisma:deploy
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
> **Catatan:** Script `compile-schema.js` akan otomatis berjalan sebelum perintah prisma di atas dieksekusi.
|
|
96
|
+
|
|
97
|
+
### 4. Generate JWT Secret
|
|
98
|
+
|
|
99
|
+
Jika Anda perlu me-refresh secret key JWT:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
npm run generate:jwt
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## š Struktur Folder
|
|
108
|
+
|
|
109
|
+
```text
|
|
110
|
+
src/
|
|
111
|
+
āāā controllers/ # Logika Request & Response
|
|
112
|
+
āāā services/ # Business Logic
|
|
113
|
+
āāā routes/ # Definisi Route API
|
|
114
|
+
āāā models/ # Definisi Schema Prisma per Model
|
|
115
|
+
āāā middleware/ # Auth, Validation, Error Handling
|
|
116
|
+
āāā schema/ # Zod Validation Schemas
|
|
117
|
+
āāā utils/ # Helper Functions
|
|
118
|
+
āāā index.ts # App Entry Point
|
|
119
|
+
prisma/
|
|
120
|
+
āāā schema.prisma # [GENERATED] Jangan edit file ini
|
|
121
|
+
āāā base.prisma # Konfigurasi Datasource & Generator
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## š Lisensi
|
|
125
|
+
|
|
126
|
+
MIT
|
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
const crypto = require('crypto');
|
|
4
|
-
|
|
5
|
-
const envPath = path.join(__dirname, '..', '.env');
|
|
6
|
-
|
|
7
|
-
function generateSecret() {
|
|
8
|
-
return crypto.randomBytes(64).toString('hex');
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
try {
|
|
12
|
-
const secret = generateSecret();
|
|
13
|
-
let envContent = '';
|
|
14
|
-
|
|
15
|
-
if (fs.existsSync(envPath)) {
|
|
16
|
-
envContent = fs.readFileSync(envPath, 'utf8');
|
|
17
|
-
} else {
|
|
18
|
-
console.log('.env file not found, creating one...');
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// Check if JWT_SECRET exists
|
|
22
|
-
if (envContent.match(/^JWT_SECRET=/m)) {
|
|
23
|
-
envContent = envContent.replace(/^JWT_SECRET=.*/m, `JWT_SECRET="${secret}"`);
|
|
24
|
-
} else {
|
|
25
|
-
// Ensure there is a newline before appending if the file is not empty
|
|
26
|
-
if (envContent && !envContent.endsWith('\n')) {
|
|
27
|
-
envContent += '\n';
|
|
28
|
-
}
|
|
29
|
-
envContent += `JWT_SECRET="${secret}"\n`;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
fs.writeFileSync(envPath, envContent);
|
|
33
|
-
console.log('ā
JWT Secret generated and updated in .env file.');
|
|
34
|
-
console.log('š New Secret has been set.');
|
|
35
|
-
} catch (error) {
|
|
36
|
-
console.error('ā Error updating .env file:', error);
|
|
37
|
-
process.exit(1);
|
|
38
|
-
}
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const crypto = require('crypto');
|
|
4
|
+
|
|
5
|
+
const envPath = path.join(__dirname, '..', '.env');
|
|
6
|
+
|
|
7
|
+
function generateSecret() {
|
|
8
|
+
return crypto.randomBytes(64).toString('hex');
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
try {
|
|
12
|
+
const secret = generateSecret();
|
|
13
|
+
let envContent = '';
|
|
14
|
+
|
|
15
|
+
if (fs.existsSync(envPath)) {
|
|
16
|
+
envContent = fs.readFileSync(envPath, 'utf8');
|
|
17
|
+
} else {
|
|
18
|
+
console.log('.env file not found, creating one...');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Check if JWT_SECRET exists
|
|
22
|
+
if (envContent.match(/^JWT_SECRET=/m)) {
|
|
23
|
+
envContent = envContent.replace(/^JWT_SECRET=.*/m, `JWT_SECRET="${secret}"`);
|
|
24
|
+
} else {
|
|
25
|
+
// Ensure there is a newline before appending if the file is not empty
|
|
26
|
+
if (envContent && !envContent.endsWith('\n')) {
|
|
27
|
+
envContent += '\n';
|
|
28
|
+
}
|
|
29
|
+
envContent += `JWT_SECRET="${secret}"\n`;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
fs.writeFileSync(envPath, envContent);
|
|
33
|
+
console.log('ā
JWT Secret generated and updated in .env file.');
|
|
34
|
+
console.log('š New Secret has been set.');
|
|
35
|
+
} catch (error) {
|
|
36
|
+
console.error('ā Error updating .env file:', error);
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
const { execSync } = require("child_process");
|
|
4
|
+
|
|
5
|
+
const rootDir = path.join(__dirname, "..");
|
|
6
|
+
const envExample = path.join(rootDir, ".env.example");
|
|
7
|
+
const envFile = path.join(rootDir, ".env");
|
|
8
|
+
|
|
9
|
+
console.log("š Starting project initialization...");
|
|
10
|
+
|
|
11
|
+
try {
|
|
12
|
+
// 1. Copy .env
|
|
13
|
+
if (!fs.existsSync(envFile)) {
|
|
14
|
+
console.log("š Copying .env.example to .env...");
|
|
15
|
+
fs.copyFileSync(envExample, envFile);
|
|
16
|
+
} else {
|
|
17
|
+
console.log("ā ļø .env already exists, skipping copy.");
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// 2. Install dependencies
|
|
21
|
+
console.log("š¦ Installing dependencies...");
|
|
22
|
+
execSync("npm install", { stdio: "inherit", cwd: rootDir });
|
|
23
|
+
|
|
24
|
+
// 3. Generate JWT Secret
|
|
25
|
+
console.log("š Generating JWT Secret...");
|
|
26
|
+
execSync("node scripts/generate-jwt-secret.js", {
|
|
27
|
+
stdio: "inherit",
|
|
28
|
+
cwd: rootDir,
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// 4. Setup Database (Migrate)
|
|
32
|
+
console.log("šļø Setting up database...");
|
|
33
|
+
// We skip the interactive prompt by providing a name if needed,
|
|
34
|
+
// or just let it run. However, if it prompts, the script might hang or fail if not interactive.
|
|
35
|
+
// 'prisma migrate dev' asks for name if there are changes.
|
|
36
|
+
// We try to run it. If it fails, we inform the user.
|
|
37
|
+
// We use npx to ensure we use the local binary.
|
|
38
|
+
try {
|
|
39
|
+
// We use the script defined in package.json but add --name init to avoid prompt for new migration
|
|
40
|
+
// However, if migrations already exist, --name might create a new one.
|
|
41
|
+
// If it's a fresh clone, 'prisma migrate dev' checks existing migrations.
|
|
42
|
+
// Let's just run the compile-schema first, then migrate.
|
|
43
|
+
execSync('node scripts/compile-schema.js', { stdio: 'inherit', cwd: rootDir });
|
|
44
|
+
|
|
45
|
+
// Explicitly generate Prisma Client before migration to ensure it exists
|
|
46
|
+
console.log('āļø Generating Prisma Client...');
|
|
47
|
+
execSync('npx prisma generate', { stdio: 'inherit', cwd: rootDir });
|
|
48
|
+
|
|
49
|
+
execSync('npx prisma migrate dev --name init_setup', { stdio: 'inherit', cwd: rootDir });
|
|
50
|
+
} catch (error) {
|
|
51
|
+
console.warn(
|
|
52
|
+
'ā ļø Database migration had an issue. Please check your database connection in .env and run "npm run prisma:migrate" manually.'
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// 5. Seed Database
|
|
57
|
+
console.log("š± Seeding database...");
|
|
58
|
+
try {
|
|
59
|
+
execSync("npm run db:seed", { stdio: "inherit", cwd: rootDir });
|
|
60
|
+
} catch (error) {
|
|
61
|
+
console.warn(
|
|
62
|
+
'ā ļø Database seeding had an issue. You might need to run "npm run db:seed" manually.'
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
console.log("\nā
Setup complete! You can now run:");
|
|
67
|
+
console.log(" npm run dev");
|
|
68
|
+
} catch (error) {
|
|
69
|
+
console.error("ā Setup failed:", error.message);
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
package/scripts/make-model.js
CHANGED
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
|
|
4
|
-
const modelName = process.argv[2];
|
|
5
|
-
|
|
6
|
-
if (!modelName) {
|
|
7
|
-
console.error('ā Please specify the model name.');
|
|
8
|
-
console.error(' Usage: npm run make:model <ModelName>');
|
|
9
|
-
console.error(' Example: npm run make:model Product');
|
|
10
|
-
process.exit(1);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const PascalCaseName = modelName.charAt(0).toUpperCase() + modelName.slice(1);
|
|
14
|
-
const tableName = modelName.toLowerCase() + 's'; // simple pluralization
|
|
15
|
-
|
|
16
|
-
const modelsDir = path.join(__dirname, '..', 'src', 'models');
|
|
17
|
-
const modelPath = path.join(modelsDir, `${PascalCaseName}.prisma`);
|
|
18
|
-
|
|
19
|
-
if (fs.existsSync(modelPath)) {
|
|
20
|
-
console.error(`ā Model ${PascalCaseName} already exists at ${modelPath}`);
|
|
21
|
-
process.exit(1);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// Ensure models directory exists
|
|
25
|
-
if (!fs.existsSync(modelsDir)) {
|
|
26
|
-
fs.mkdirSync(modelsDir, { recursive: true });
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const content = `model ${tableName} {
|
|
30
|
-
id BigInt @id @default(autoincrement())
|
|
31
|
-
name String @db.VarChar(255)
|
|
32
|
-
createdAt DateTime? @default(now()) @db.Timestamp(0)
|
|
33
|
-
updatedAt DateTime? @updatedAt @db.Timestamp(0)
|
|
34
|
-
}
|
|
35
|
-
`;
|
|
36
|
-
|
|
37
|
-
fs.writeFileSync(modelPath, content);
|
|
38
|
-
|
|
39
|
-
console.log(`ā
Model created: src/models/${PascalCaseName}.prisma`);
|
|
40
|
-
console.log(`\nNext steps:`);
|
|
41
|
-
console.log(`1. Edit the model file.`);
|
|
42
|
-
console.log(`2. Run 'npm run prisma:migrate' to update the database.`);
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
const modelName = process.argv[2];
|
|
5
|
+
|
|
6
|
+
if (!modelName) {
|
|
7
|
+
console.error('ā Please specify the model name.');
|
|
8
|
+
console.error(' Usage: npm run make:model <ModelName>');
|
|
9
|
+
console.error(' Example: npm run make:model Product');
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const PascalCaseName = modelName.charAt(0).toUpperCase() + modelName.slice(1);
|
|
14
|
+
const tableName = modelName.toLowerCase() + 's'; // simple pluralization
|
|
15
|
+
|
|
16
|
+
const modelsDir = path.join(__dirname, '..', 'src', 'models');
|
|
17
|
+
const modelPath = path.join(modelsDir, `${PascalCaseName}.prisma`);
|
|
18
|
+
|
|
19
|
+
if (fs.existsSync(modelPath)) {
|
|
20
|
+
console.error(`ā Model ${PascalCaseName} already exists at ${modelPath}`);
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Ensure models directory exists
|
|
25
|
+
if (!fs.existsSync(modelsDir)) {
|
|
26
|
+
fs.mkdirSync(modelsDir, { recursive: true });
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const content = `model ${tableName} {
|
|
30
|
+
id BigInt @id @default(autoincrement())
|
|
31
|
+
name String @db.VarChar(255)
|
|
32
|
+
createdAt DateTime? @default(now()) @db.Timestamp(0)
|
|
33
|
+
updatedAt DateTime? @updatedAt @db.Timestamp(0)
|
|
34
|
+
}
|
|
35
|
+
`;
|
|
36
|
+
|
|
37
|
+
fs.writeFileSync(modelPath, content);
|
|
38
|
+
|
|
39
|
+
console.log(`ā
Model created: src/models/${PascalCaseName}.prisma`);
|
|
40
|
+
console.log(`\nNext steps:`);
|
|
41
|
+
console.log(`1. Edit the model file.`);
|
|
42
|
+
console.log(`2. Run 'npm run prisma:migrate' to update the database.`);
|