lapeh 2.2.6 โ 2.2.7
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/api-testing-sepuluh/.env.example +19 -0
- package/api-testing-sepuluh/doc/ARCHITECTURE_GUIDE.md +73 -0
- package/api-testing-sepuluh/doc/CHANGELOG.md +77 -0
- package/api-testing-sepuluh/doc/CHEATSHEET.md +94 -0
- package/api-testing-sepuluh/doc/CLI.md +106 -0
- package/api-testing-sepuluh/doc/CONTRIBUTING.md +105 -0
- package/api-testing-sepuluh/doc/DEPLOYMENT.md +122 -0
- package/api-testing-sepuluh/doc/FAQ.md +81 -0
- package/api-testing-sepuluh/doc/FEATURES.md +165 -0
- package/api-testing-sepuluh/doc/GETTING_STARTED.md +108 -0
- package/api-testing-sepuluh/doc/INTRODUCTION.md +60 -0
- package/api-testing-sepuluh/doc/PACKAGES.md +66 -0
- package/api-testing-sepuluh/doc/PERFORMANCE.md +91 -0
- package/api-testing-sepuluh/doc/ROADMAP.md +93 -0
- package/api-testing-sepuluh/doc/SECURITY.md +93 -0
- package/api-testing-sepuluh/doc/STRUCTURE.md +90 -0
- package/api-testing-sepuluh/doc/TUTORIAL.md +192 -0
- package/api-testing-sepuluh/docker-compose.yml +24 -0
- package/api-testing-sepuluh/eslint.config.mjs +26 -0
- package/api-testing-sepuluh/framework.md +168 -0
- package/api-testing-sepuluh/nodemon.json +6 -0
- package/api-testing-sepuluh/package-lock.json +5539 -0
- package/api-testing-sepuluh/package.json +103 -0
- package/api-testing-sepuluh/prisma/base.prisma.template +7 -0
- package/api-testing-sepuluh/prisma/migrations/20251227034737_init_setup/migration.sql +248 -0
- package/api-testing-sepuluh/prisma/migrations/migration_lock.toml +3 -0
- package/api-testing-sepuluh/prisma/schema.prisma +183 -0
- package/api-testing-sepuluh/prisma/seed.ts +411 -0
- package/api-testing-sepuluh/prisma.config.ts +15 -0
- package/api-testing-sepuluh/readme.md +414 -0
- package/api-testing-sepuluh/scripts/check-update.js +92 -0
- package/api-testing-sepuluh/scripts/compile-schema.js +29 -0
- package/api-testing-sepuluh/scripts/config-clear.js +45 -0
- package/api-testing-sepuluh/scripts/generate-jwt-secret.js +38 -0
- package/api-testing-sepuluh/scripts/init-project.js +178 -0
- package/api-testing-sepuluh/scripts/make-controller.js +205 -0
- package/api-testing-sepuluh/scripts/make-model.js +42 -0
- package/api-testing-sepuluh/scripts/make-module.js +158 -0
- package/api-testing-sepuluh/scripts/verify-rbac-functional.js +187 -0
- package/api-testing-sepuluh/src/controllers/authController.ts +469 -0
- package/api-testing-sepuluh/src/controllers/petController.ts +194 -0
- package/api-testing-sepuluh/src/controllers/rbacController.ts +478 -0
- package/api-testing-sepuluh/src/models/core.prisma +163 -0
- package/api-testing-sepuluh/src/models/pets.prisma +9 -0
- package/api-testing-sepuluh/src/routes/auth.ts +74 -0
- package/api-testing-sepuluh/src/routes/index.ts +10 -0
- package/api-testing-sepuluh/src/routes/pets.ts +13 -0
- package/api-testing-sepuluh/src/routes/rbac.ts +42 -0
- package/api-testing-sepuluh/storage/logs/.gitkeep +0 -0
- package/api-testing-sepuluh/tsconfig.json +39 -0
- package/bin/index.js +68 -13
- package/package.json +1 -1
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
# Lapeh Framework - Modern Node.js & TypeScript API Framework
|
|
2
|
+
|
|
3
|
+
**Lapeh** adalah framework **Node.js** berbasis **Express** dan **TypeScript** yang dirancang untuk kecepatan dan skalabilitas. Menggabungkan fleksibilitas Express dengan struktur solid ala **Laravel** dan **NestJS**, Lapeh memberikan pengalaman development **REST API** yang cepat, terstandarisasi, dan siap produksi.
|
|
4
|
+
|
|
5
|
+
Cocok untuk developer yang mencari **Express boilerplate** dengan fitur lengkap: Prisma ORM, Authentication, RBAC, dan Zero-Config Redis.
|
|
6
|
+
|
|
7
|
+
## ๐ Fitur Utama
|
|
8
|
+
|
|
9
|
+
- **Production Ready**: Struktur folder modular (MVC) yang mudah dikembangkan.
|
|
10
|
+
- **TypeScript First**: Full type-safety untuk mengurangi runtime error.
|
|
11
|
+
- **Prisma ORM Integration**: Database modern dengan dukungan PostgreSQL dan MySQL.
|
|
12
|
+
- **Laravel-style Structure**: Controller, Service, dan Route yang terpisah rapi.
|
|
13
|
+
- **Auto CLI Generator**: Buat modul, model, dan controller dengan satu perintah.
|
|
14
|
+
- **Smart Caching**: Otomatis menggunakan Redis jika tersedia, fallback ke in-memory jika tidak.
|
|
15
|
+
- **Secure by Default**: Dilengkapi Helmet, Rate Limiting, CORS, dan JWT Auth.
|
|
16
|
+
- **Robust Validation**: Validasi request otomatis menggunakan Zod.
|
|
17
|
+
- **High Performance**: Mendukung Fast-Serialization (Fastify-style) untuk response JSON super cepat.
|
|
18
|
+
- **Scalable**: Siap untuk deployment Cluster/Load Balancer dengan Redis Store.
|
|
19
|
+
|
|
20
|
+
## ๐ฎ Roadmap (Rencana Masa Depan)
|
|
21
|
+
|
|
22
|
+
Lapeh Framework akan terus berkembang menjadi solusi Enterprise yang lengkap. Kami memiliki rencana besar untuk fitur-fitur seperti **Job Queues**, **Storage Abstraction (S3)**, **Mailer**, dan **OpenAPI Generator**.
|
|
23
|
+
|
|
24
|
+
Lihat detail rencana pengembangan di **[ROADMAP.md](doc/ROADMAP.md)**.
|
|
25
|
+
|
|
26
|
+
## ๐ค Berkontribusi (Open Source)
|
|
27
|
+
|
|
28
|
+
Lapeh adalah proyek Open Source dan kami sangat terbuka untuk kontribusi dari komunitas! Baik itu perbaikan bug, penambahan fitur, atau perbaikan dokumentasi.
|
|
29
|
+
|
|
30
|
+
Ingin ikut berkontribusi? Silakan baca **[Panduan Kontribusi (CONTRIBUTING.md)](doc/CONTRIBUTING.md)** untuk memulai.
|
|
31
|
+
|
|
32
|
+
## ๐ Dokumentasi Lengkap
|
|
33
|
+
|
|
34
|
+
Kami menyusun "Learning Path" agar Anda bisa memahami framework ini dari nol hingga mahir.
|
|
35
|
+
|
|
36
|
+
### ๐ฃ Level 1: Pemula (Wajib Baca)
|
|
37
|
+
|
|
38
|
+
- **[Pengenalan Framework](doc/INTRODUCTION.md)**: Mengapa framework ini ada? Apa bedanya dengan yang lain?
|
|
39
|
+
- **[Getting Started](doc/GETTING_STARTED.md)**: Instalasi dan setup awal.
|
|
40
|
+
- **[Bedah Struktur Folder](doc/STRUCTURE.md)**: Pahami fungsi setiap file dan direktori.
|
|
41
|
+
- **[Referensi Package](doc/PACKAGES.md)**: Penjelasan kegunaan setiap library yang terinstall.
|
|
42
|
+
- **[Cheatsheet (Contekan)](doc/CHEATSHEET.md)**: Daftar perintah & kode cepat.
|
|
43
|
+
|
|
44
|
+
### ๐จ Level 2: Membangun Aplikasi
|
|
45
|
+
|
|
46
|
+
- **[CLI Tools](doc/CLI.md)**: Percepat kerja dengan generator kode (`make:module`, dll).
|
|
47
|
+
- **[Tutorial Studi Kasus](doc/TUTORIAL.md)**: Bikin API "Perpustakaan" dari nol sampai jadi.
|
|
48
|
+
- **[Fitur & Konsep Inti](doc/FEATURES.md)**: Validasi, Auth, RBAC, dan Serializer.
|
|
49
|
+
|
|
50
|
+
### ๐ Level 3: Mahir & Production
|
|
51
|
+
|
|
52
|
+
- **[Performance Guide](doc/PERFORMANCE.md)**: Tips optimasi high-scale app.
|
|
53
|
+
- **[Security Best Practices](doc/SECURITY.md)**: Panduan mengamankan aplikasi.
|
|
54
|
+
- **[Deployment Guide](doc/DEPLOYMENT.md)**: Cara deploy ke VPS, Docker, atau Cloud.
|
|
55
|
+
- **[FAQ & Troubleshooting](doc/FAQ.md)**: Solusi masalah umum.
|
|
56
|
+
- **[Changelog](doc/CHANGELOG.md)**: Riwayat versi.
|
|
57
|
+
|
|
58
|
+
## ๐ฆ Instalasi & Penggunaan
|
|
59
|
+
|
|
60
|
+
Anda dapat menginstall framework ini menggunakan versi terbaru atau versi spesifik agar lebih fleksibel:
|
|
61
|
+
|
|
62
|
+
### 1. Menggunakan Versi Terbaru (Recommended)
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
npx lapeh@latest nama-project-anda
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Atau gunakan flag `--full` untuk setup lengkap (termasuk seeding data default user & roles):
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
npx lapeh@latest nama-project-anda --full
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 2. Menggunakan Versi Spesifik
|
|
75
|
+
|
|
76
|
+
Jika Anda membutuhkan versi tertentu (misalnya untuk kompatibilitas):
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
npx lapeh@1.0.8 nama-project-anda
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Atau dengan setup lengkap:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
npx lapeh@1.0.8 nama-project-anda --full
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Apa yang terjadi otomatis?
|
|
89
|
+
|
|
90
|
+
1. Struktur project dibuat.
|
|
91
|
+
2. Dependencies diinstall.
|
|
92
|
+
3. Database dipilih & dikonfigurasi secara interaktif.
|
|
93
|
+
4. **Database** dibuat dan dimigrasi otomatis.
|
|
94
|
+
5. **JWT Secret** di-generate otomatis.
|
|
95
|
+
6. **Seeding Data** (jika menggunakan `--full`).
|
|
96
|
+
|
|
97
|
+
Masuk ke folder project dan jalankan:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
cd nama-project-anda
|
|
101
|
+
npm run dev
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Server akan berjalan di `http://localhost:4000`.
|
|
105
|
+
|
|
106
|
+
### ๐ Akun Default (Jika menggunakan `--full` atau `npm run db:seed`)
|
|
107
|
+
|
|
108
|
+
Jika Anda melakukan setup dengan flag `--full`, database akan terisi dengan akun default berikut:
|
|
109
|
+
|
|
110
|
+
| Role | Email | Password |
|
|
111
|
+
| :-------------- | :---------- | :------- |
|
|
112
|
+
| **Super Admin** | `sa@sa.com` | `string` |
|
|
113
|
+
| **Admin** | `a@a.com` | `string` |
|
|
114
|
+
| **User** | `u@u.com` | `string` |
|
|
115
|
+
|
|
116
|
+
> **Catatan:** Segera ubah password akun-akun ini jika Anda mendeploy ke production!
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## ๐ Upgrade Project
|
|
121
|
+
|
|
122
|
+
Jika Anda memiliki project lama yang dibuat dengan versi Lapeh sebelumnya dan ingin memperbarui struktur, scripts, dan konfigurasi ke standar terbaru (termasuk keamanan Redis baru), Anda tidak perlu membuat project ulang.
|
|
123
|
+
|
|
124
|
+
Cukup jalankan perintah ini di dalam folder project Anda:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
npx lapeh@latest upgrade
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Perintah ini akan secara otomatis:
|
|
131
|
+
|
|
132
|
+
1. Mengupdate `scripts/` (termasuk generator controller baru).
|
|
133
|
+
2. Mengupdate `docker-compose.yml` (keamanan Redis).
|
|
134
|
+
3. Mengupdate dependencies di `package.json`.
|
|
135
|
+
4. Menambahkan konfigurasi `.vscode` dan `tsconfig` terbaru.
|
|
136
|
+
|
|
137
|
+
> **Catatan:** File `.env` Anda **tidak akan ditimpa**, namun kami akan mengupdate `.env.example` sebagai referensi konfigurasi terbaru.
|
|
138
|
+
|
|
139
|
+
## ๐ง Zero-Config Redis
|
|
140
|
+
|
|
141
|
+
Lapeh otomatis mendeteksi ketersediaan Redis.
|
|
142
|
+
|
|
143
|
+
1. **Auto-Discovery**: Mencoba terhubung ke Redis URL di `.env` (`REDIS_URL`).
|
|
144
|
+
2. **Smart Fallback**: Jika Redis tidak tersedia atau koneksi gagal, otomatis beralih ke **In-Memory Mock**.
|
|
145
|
+
- Tidak perlu install Redis di local development.
|
|
146
|
+
- Fitur rate-limiting dan caching tetap berjalan (namun data hilang saat restart).
|
|
147
|
+
3. **Production Safety**: Memberikan peringatan log jika berjalan di Production menggunakan Mock.
|
|
148
|
+
|
|
149
|
+
**Force Mock Mode:**
|
|
150
|
+
Anda bisa memaksa menggunakan mock (misal untuk testing) dengan menambahkan env variable:
|
|
151
|
+
|
|
152
|
+
```env
|
|
153
|
+
NO_REDIS=true
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Optional: Menggunakan Real Redis dengan Docker
|
|
157
|
+
|
|
158
|
+
Jika Anda ingin menggunakan Redis yang sebenarnya di local environment, kami telah menyertakan konfigurasi `docker-compose.yml` yang aman (menggunakan ACL).
|
|
159
|
+
|
|
160
|
+
1. Jalankan Redis container:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
docker-compose up -d
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
2. Uncomment konfigurasi Redis di file `.env` Anda:
|
|
167
|
+
|
|
168
|
+
```env
|
|
169
|
+
REDIS_URL="redis://lapeh:12341234@localhost:6379"
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
> **Credential Default:**
|
|
173
|
+
>
|
|
174
|
+
> - User: `lapeh`
|
|
175
|
+
> - Password: `12341234`
|
|
176
|
+
|
|
177
|
+
## ๐ Development Tools
|
|
178
|
+
|
|
179
|
+
API Lapeh menyediakan tools untuk mempercepat development, mirip dengan `artisan` di Laravel.
|
|
180
|
+
|
|
181
|
+
### 1. Membuat Module (Resource)
|
|
182
|
+
|
|
183
|
+
Membuat Controller, Service, dan Route sekaligus.
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
npm run make:module NamaResource
|
|
187
|
+
# Contoh: npm run make:module Product
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Command ini akan membuat:
|
|
191
|
+
|
|
192
|
+
- `src/controllers/product.controller.ts`
|
|
193
|
+
- `src/services/product.service.ts`
|
|
194
|
+
- `src/routes/product.route.ts` (dan otomatis didaftarkan di `src/routes/index.ts` jika memungkinkan)
|
|
195
|
+
|
|
196
|
+
### 2. Membuat Model Database
|
|
197
|
+
|
|
198
|
+
Membuat file model Prisma baru di dalam folder `src/models/` (atau `prisma/models` tergantung konfigurasi).
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
npm run make:model NamaModel
|
|
202
|
+
# Contoh: npm run make:model User
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Ini akan membuat file `src/models/User.prisma`.
|
|
206
|
+
|
|
207
|
+
### 3. Membuat Controller
|
|
208
|
+
|
|
209
|
+
Membuat file Controller baru. Gunakan flag `-r` untuk membuat controller lengkap dengan method CRUD (index, show, store, update, destroy).
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
npm run make:controller NamaController
|
|
213
|
+
# Contoh Basic: npm run make:controller PaymentController
|
|
214
|
+
|
|
215
|
+
# Contoh Resource (CRUD Lengkap):
|
|
216
|
+
npm run make:controller PaymentController -r
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### 4. Workflow Database (Prisma)
|
|
220
|
+
|
|
221
|
+
Karena framework ini menggunakan **Schema Terpisah** (split schema), Anda **TIDAK BOLEH** mengedit `prisma/schema.prisma` secara manual.
|
|
222
|
+
|
|
223
|
+
- **Edit Models**: Lakukan perubahan di `src/models/*.prisma`.
|
|
224
|
+
- **Apply Changes**: Jalankan perintah migrasi standar, sistem akan otomatis menggabungkan (compile) schema Anda.
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
# Generate Prisma Client (setiap ada perubahan model)
|
|
228
|
+
npm run prisma:generate
|
|
229
|
+
|
|
230
|
+
# Migrasi Database (Development)
|
|
231
|
+
npm run prisma:migrate
|
|
232
|
+
|
|
233
|
+
# Membuka GUI Database (Prisma Studio)
|
|
234
|
+
npm run db:studio
|
|
235
|
+
|
|
236
|
+
# Migrasi Database Dan Seed (Development - Reset Total default option for development)
|
|
237
|
+
npm run db:reset
|
|
238
|
+
|
|
239
|
+
# Deploy ke Production
|
|
240
|
+
npm run prisma:deploy
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
> **Catatan:** Script `compile-schema.js` akan otomatis berjalan sebelum perintah prisma di atas dieksekusi.
|
|
244
|
+
|
|
245
|
+
### 5. Generate JWT Secret
|
|
246
|
+
|
|
247
|
+
Jika Anda perlu me-refresh secret key JWT:
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
npm run generate:jwt
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### 6. Maintenance (Clear Config)
|
|
254
|
+
|
|
255
|
+
Membersihkan cache framework, NPM, build artifacts, dan temporary files (sangat berguna jika mengalami isu cache aneh atau ingin reset environment development).
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
npm run config:clear
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
- Menghapus `node_modules/.cache`
|
|
262
|
+
- Menghapus `dist/`
|
|
263
|
+
- Menghapus `dump.rdb` (Redis Persistence)
|
|
264
|
+
- Membersihkan `npm cache`
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
## ๐ Struktur Folder
|
|
269
|
+
|
|
270
|
+
```text
|
|
271
|
+
src/
|
|
272
|
+
โโโ controllers/ # Logika Request & Response
|
|
273
|
+
โโโ services/ # Business Logic
|
|
274
|
+
โโโ routes/ # Definisi Route API
|
|
275
|
+
โโโ models/ # Definisi Schema Prisma per Model
|
|
276
|
+
โโโ middleware/ # Auth, Validation, Error Handling
|
|
277
|
+
โโโ schema/ # Zod Validation Schemas
|
|
278
|
+
โโโ utils/ # Helper Functions
|
|
279
|
+
โโโ index.ts # App Entry Point
|
|
280
|
+
prisma/
|
|
281
|
+
โโโ schema.prisma # [GENERATED] Jangan edit file ini
|
|
282
|
+
โโโ base.prisma.template # Konfigurasi Datasource & Generator
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
## ๐ Lisensi
|
|
286
|
+
|
|
287
|
+
MIT
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
## ๐ Deployment Guide
|
|
292
|
+
|
|
293
|
+
### 1) Build & Generate Prisma Client (Otomatis)
|
|
294
|
+
|
|
295
|
+
- Build: `npm run build`
|
|
296
|
+
- Start (dev): `npm run start`
|
|
297
|
+
- Start (prod): `npm run start:prod`
|
|
298
|
+
- Hooks otomatis:
|
|
299
|
+
- `prebuild`, `prestart`, dan `prestart:prod` akan memanggil `npm run prisma:generate` sehingga Prisma Client selalu tersedia tanpa error.
|
|
300
|
+
|
|
301
|
+
### 2) Production Environment
|
|
302
|
+
|
|
303
|
+
- Pastikan `.env` berisi kredensial production:
|
|
304
|
+
- `DATABASE_URL` dan `DATABASE_PROVIDER` (mysql/postgresql)
|
|
305
|
+
- `JWT_SECRET` (gunakan `npm run generate:jwt` untuk mengganti)
|
|
306
|
+
- Terapkan migrasi production (tanpa reset data):
|
|
307
|
+
|
|
308
|
+
```bash
|
|
309
|
+
npm run prisma:deploy
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### 3) Menjalankan dengan PM2
|
|
313
|
+
|
|
314
|
+
- Install PM2:
|
|
315
|
+
|
|
316
|
+
```bash
|
|
317
|
+
npm i -g pm2
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
- Jalankan aplikasi:
|
|
321
|
+
|
|
322
|
+
```bash
|
|
323
|
+
pm2 start dist/src/index.js --name lapeh-api --time
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
- Simpan proses agar auto-start saat reboot:
|
|
327
|
+
|
|
328
|
+
```bash
|
|
329
|
+
pm2 save
|
|
330
|
+
pm2 startup
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
- Monitoring:
|
|
334
|
+
|
|
335
|
+
```bash
|
|
336
|
+
pm2 status
|
|
337
|
+
pm2 logs lapeh-api
|
|
338
|
+
pm2 restart lapeh-api
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
### 4) Nginx Reverse Proxy (Recommended)
|
|
342
|
+
|
|
343
|
+
- Buat server block `/etc/nginx/sites-available/lapeh`:
|
|
344
|
+
|
|
345
|
+
```nginx
|
|
346
|
+
server {
|
|
347
|
+
listen 80;
|
|
348
|
+
server_name example.com;
|
|
349
|
+
|
|
350
|
+
location / {
|
|
351
|
+
proxy_set_header Host $host;
|
|
352
|
+
proxy_set_header X-Real-IP $remote_addr;
|
|
353
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
354
|
+
proxy_set_header X-Forwarded-Proto $scheme;
|
|
355
|
+
proxy_pass http://127.0.0.1:4000;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
- Aktifkan:
|
|
361
|
+
|
|
362
|
+
```bash
|
|
363
|
+
sudo ln -s /etc/nginx/sites-available/lapeh /etc/nginx/sites-enabled/lapeh
|
|
364
|
+
sudo nginx -t
|
|
365
|
+
sudo systemctl reload nginx
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
- SSL (opsional, Certbot):
|
|
369
|
+
|
|
370
|
+
```bash
|
|
371
|
+
sudo apt install certbot python3-certbot-nginx -y
|
|
372
|
+
sudo certbot --nginx -d example.com
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
### 5) Apache 2 Reverse Proxy (Alternatif)
|
|
376
|
+
|
|
377
|
+
- Enable modul proxy:
|
|
378
|
+
|
|
379
|
+
```bash
|
|
380
|
+
sudo a2enmod proxy proxy_http headers
|
|
381
|
+
sudo systemctl reload apache2
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
- Buat vhost `/etc/apache2/sites-available/lapeh.conf`:
|
|
385
|
+
|
|
386
|
+
```apache
|
|
387
|
+
<VirtualHost *:80>
|
|
388
|
+
ServerName example.com
|
|
389
|
+
ProxyPreserveHost On
|
|
390
|
+
ProxyRequests Off
|
|
391
|
+
<Proxy *>
|
|
392
|
+
Require all granted
|
|
393
|
+
</Proxy>
|
|
394
|
+
ProxyPass / http://127.0.0.1:4000/
|
|
395
|
+
ProxyPassReverse / http://127.0.0.1:4000/
|
|
396
|
+
ErrorLog ${APACHE_LOG_DIR}/lapeh-error.log
|
|
397
|
+
CustomLog ${APACHE_LOG_DIR}/lapeh-access.log combined
|
|
398
|
+
</VirtualHost>
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
- Aktifkan:
|
|
402
|
+
|
|
403
|
+
```bash
|
|
404
|
+
sudo a2ensite lapeh.conf
|
|
405
|
+
sudo apachectl configtest
|
|
406
|
+
sudo systemctl reload apache2
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
### 6) Checklist Produksi
|
|
410
|
+
|
|
411
|
+
- `npm run prisma:deploy` sukses dan tabel terbentuk
|
|
412
|
+
- `pm2 status` menunjukkan proses hidup
|
|
413
|
+
- Proxy (Nginx/Apache) menuju port aplikasi (default 4000)
|
|
414
|
+
- `.env` aman dan tidak di-commit ke repository
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
const https = require('https');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
|
|
5
|
+
// --- KONFIGURASI ---
|
|
6
|
+
// Ganti URL ini dengan URL raw package.json dari repository GitHub/GitLab Anda
|
|
7
|
+
// Contoh: 'https://raw.githubusercontent.com/username/project-name/main/package.json'
|
|
8
|
+
// Jika package dipublish ke NPM, Anda bisa menggunakan registry NPM.
|
|
9
|
+
const REPO_VERSION_URL = 'https://registry.npmjs.org/lapeh/latest';
|
|
10
|
+
const TIMEOUT = 2000; // Timeout 2 detik agar tidak terlalu lama menunggu
|
|
11
|
+
|
|
12
|
+
const packageJson = require('../package.json');
|
|
13
|
+
// Cek apakah ada key "lapeh" di dependencies (project user)
|
|
14
|
+
// Jika tidak ada, fallback ke version package.json (mungkin ini repo framework itu sendiri)
|
|
15
|
+
const currentVersion = packageJson.dependencies?.['lapeh'] || packageJson.version;
|
|
16
|
+
|
|
17
|
+
function checkForUpdates() {
|
|
18
|
+
if (!REPO_VERSION_URL) return;
|
|
19
|
+
|
|
20
|
+
const req = https.get(REPO_VERSION_URL, {
|
|
21
|
+
headers: { 'User-Agent': 'NodeJS Update Checker' },
|
|
22
|
+
timeout: TIMEOUT
|
|
23
|
+
}, (res) => {
|
|
24
|
+
let data = '';
|
|
25
|
+
|
|
26
|
+
if (res.statusCode !== 200) {
|
|
27
|
+
// Silent fail jika URL tidak bisa diakses
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
res.on('data', (chunk) => {
|
|
32
|
+
data += chunk;
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
res.on('end', () => {
|
|
36
|
+
try {
|
|
37
|
+
const remoteJson = JSON.parse(data);
|
|
38
|
+
// Jika cek ke NPM, version ada di root object atau 'version'
|
|
39
|
+
// Jika cek ke raw github, structure sama dengan package.json
|
|
40
|
+
const latestVersion = remoteJson.version || remoteJson['dist-tags']?.latest;
|
|
41
|
+
|
|
42
|
+
if (latestVersion && isNewer(latestVersion, currentVersion)) {
|
|
43
|
+
showUpdateMessage(latestVersion, currentVersion);
|
|
44
|
+
}
|
|
45
|
+
} catch (e) {
|
|
46
|
+
// Ignore parsing errors
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
req.on('error', (e) => {
|
|
52
|
+
// Ignore network errors
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
req.end();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function isNewer(latest, current) {
|
|
59
|
+
const lParts = latest.split('.').map(Number);
|
|
60
|
+
const cParts = current.split('.').map(Number);
|
|
61
|
+
|
|
62
|
+
for (let i = 0; i < 3; i++) {
|
|
63
|
+
if (lParts[i] > cParts[i]) return true;
|
|
64
|
+
if (lParts[i] < cParts[i]) return false;
|
|
65
|
+
}
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function showUpdateMessage(latest, current) {
|
|
70
|
+
const reset = "\x1b[0m";
|
|
71
|
+
const bright = "\x1b[1m";
|
|
72
|
+
const fgYellow = "\x1b[33m";
|
|
73
|
+
const fgCyan = "\x1b[36m";
|
|
74
|
+
|
|
75
|
+
console.log('\n');
|
|
76
|
+
console.log(`${fgYellow}โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ${reset}`);
|
|
77
|
+
console.log(`${fgYellow}โ โ${reset}`);
|
|
78
|
+
console.log(`${fgYellow}โ ${bright}UPDATE FRAMEWORK TERSEDIA!${reset}${fgYellow} โ${reset}`);
|
|
79
|
+
console.log(`${fgYellow}โ โ${reset}`);
|
|
80
|
+
console.log(`${fgYellow}โ Versi Lokal : ${fgCyan}${current}${reset}${fgYellow} โ${reset}`);
|
|
81
|
+
console.log(`${fgYellow}โ Versi Terbaru : ${fgCyan}${latest}${reset}${fgYellow} โ${reset}`);
|
|
82
|
+
console.log(`${fgYellow}โ โ${reset}`);
|
|
83
|
+
console.log(`${fgYellow}โ Silakan cek repository untuk melihat perubahan terbaru. โ${reset}`);
|
|
84
|
+
console.log(`${fgYellow}โ โ${reset}`);
|
|
85
|
+
console.log(`${fgYellow}โ Untuk upgrade jalankan: โ${reset}`);
|
|
86
|
+
console.log(`${fgYellow}โ ${fgCyan}npm install lapeh@latest${reset}${fgYellow} โ${reset}`);
|
|
87
|
+
console.log(`${fgYellow}โ โ${reset}`);
|
|
88
|
+
console.log(`${fgYellow}โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ${reset}`);
|
|
89
|
+
console.log('\n');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
checkForUpdates();
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
const prismaDir = path.join(__dirname, '..', 'prisma');
|
|
5
|
+
const modelsDir = path.join(__dirname, '..', 'src', 'models');
|
|
6
|
+
const schemaFile = path.join(prismaDir, 'schema.prisma');
|
|
7
|
+
const baseFile = path.join(prismaDir, 'base.prisma.template');
|
|
8
|
+
|
|
9
|
+
// Ensure models directory exists
|
|
10
|
+
if (!fs.existsSync(modelsDir)) {
|
|
11
|
+
fs.mkdirSync(modelsDir, { recursive: true });
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Read base schema (datasource & generator)
|
|
15
|
+
let schemaContent = fs.readFileSync(baseFile, 'utf8');
|
|
16
|
+
|
|
17
|
+
// Read all .prisma files in src/models
|
|
18
|
+
const modelFiles = fs.readdirSync(modelsDir).filter(file => file.endsWith('.prisma'));
|
|
19
|
+
|
|
20
|
+
modelFiles.forEach(file => {
|
|
21
|
+
const content = fs.readFileSync(path.join(modelsDir, file), 'utf8');
|
|
22
|
+
schemaContent += '\n\n' + content;
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// Write concatenated content to prisma/schema.prisma
|
|
26
|
+
fs.writeFileSync(schemaFile, schemaContent);
|
|
27
|
+
|
|
28
|
+
console.log('โ
Prisma schema compiled successfully!');
|
|
29
|
+
console.log(` Merged ${modelFiles.length} model files from src/models/ into prisma/schema.prisma`);
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { execSync } = require('child_process');
|
|
4
|
+
|
|
5
|
+
const rootDir = path.join(__dirname, '..');
|
|
6
|
+
|
|
7
|
+
console.log('๐งน Starting cleanup process...');
|
|
8
|
+
|
|
9
|
+
// 1. Remove dist folder (Build artifacts)
|
|
10
|
+
const distDir = path.join(rootDir, 'dist');
|
|
11
|
+
if (fs.existsSync(distDir)) {
|
|
12
|
+
console.log('๐๏ธ Removing dist/ folder...');
|
|
13
|
+
fs.rmSync(distDir, { recursive: true, force: true });
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// 2. Remove node_modules/.cache (Framework caches: ts-node, eslint, etc)
|
|
17
|
+
const nmCacheDir = path.join(rootDir, 'node_modules', '.cache');
|
|
18
|
+
if (fs.existsSync(nmCacheDir)) {
|
|
19
|
+
console.log('๐๏ธ Removing node_modules/.cache...');
|
|
20
|
+
fs.rmSync(nmCacheDir, { recursive: true, force: true });
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// 3. Remove Redis local persistence file (dump.rdb)
|
|
24
|
+
const dumpRdb = path.join(rootDir, 'dump.rdb');
|
|
25
|
+
if (fs.existsSync(dumpRdb)) {
|
|
26
|
+
console.log('๐๏ธ Removing dump.rdb (Redis persistence)...');
|
|
27
|
+
fs.unlinkSync(dumpRdb);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// 4. Remove Coverage folder (if exists)
|
|
31
|
+
const coverageDir = path.join(rootDir, 'coverage');
|
|
32
|
+
if (fs.existsSync(coverageDir)) {
|
|
33
|
+
console.log('๐๏ธ Removing coverage/ folder...');
|
|
34
|
+
fs.rmSync(coverageDir, { recursive: true, force: true });
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// 5. Clear NPM Cache
|
|
38
|
+
try {
|
|
39
|
+
console.log('๐ฆ Clearing NPM cache...');
|
|
40
|
+
execSync('npm cache clean --force', { stdio: 'inherit' });
|
|
41
|
+
} catch (error) {
|
|
42
|
+
console.warn('โ ๏ธ Warning: Could not clear NPM cache. You might need admin privileges.');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
console.log('โจ Cleanup complete! Project is fresh.');
|
|
@@ -0,0 +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
|
+
}
|