lapeeh 1.0.0

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 (76) hide show
  1. package/.env.example +14 -0
  2. package/LICENSE +21 -0
  3. package/bin/index.js +934 -0
  4. package/doc/en/ARCHITECTURE_GUIDE.md +79 -0
  5. package/doc/en/CHANGELOG.md +203 -0
  6. package/doc/en/CHEATSHEET.md +90 -0
  7. package/doc/en/CLI.md +111 -0
  8. package/doc/en/CONTRIBUTING.md +119 -0
  9. package/doc/en/DEPLOYMENT.md +171 -0
  10. package/doc/en/FAQ.md +69 -0
  11. package/doc/en/FEATURES.md +99 -0
  12. package/doc/en/GETTING_STARTED.md +84 -0
  13. package/doc/en/INTRODUCTION.md +62 -0
  14. package/doc/en/PACKAGES.md +63 -0
  15. package/doc/en/PERFORMANCE.md +98 -0
  16. package/doc/en/ROADMAP.md +104 -0
  17. package/doc/en/SECURITY.md +95 -0
  18. package/doc/en/STRUCTURE.md +79 -0
  19. package/doc/en/TUTORIAL.md +145 -0
  20. package/doc/id/ARCHITECTURE_GUIDE.md +76 -0
  21. package/doc/id/CHANGELOG.md +203 -0
  22. package/doc/id/CHEATSHEET.md +90 -0
  23. package/doc/id/CLI.md +139 -0
  24. package/doc/id/CONTRIBUTING.md +119 -0
  25. package/doc/id/DEPLOYMENT.md +171 -0
  26. package/doc/id/FAQ.md +69 -0
  27. package/doc/id/FEATURES.md +169 -0
  28. package/doc/id/GETTING_STARTED.md +91 -0
  29. package/doc/id/INTRODUCTION.md +62 -0
  30. package/doc/id/PACKAGES.md +63 -0
  31. package/doc/id/PERFORMANCE.md +100 -0
  32. package/doc/id/ROADMAP.md +107 -0
  33. package/doc/id/SECURITY.md +94 -0
  34. package/doc/id/STRUCTURE.md +79 -0
  35. package/doc/id/TUTORIAL.md +145 -0
  36. package/docker-compose.yml +24 -0
  37. package/ecosystem.config.js +17 -0
  38. package/eslint.config.mjs +26 -0
  39. package/gitignore.template +30 -0
  40. package/lib/bootstrap.ts +210 -0
  41. package/lib/core/realtime.ts +34 -0
  42. package/lib/core/redis.ts +139 -0
  43. package/lib/core/serializer.ts +63 -0
  44. package/lib/core/server.ts +70 -0
  45. package/lib/core/store.ts +116 -0
  46. package/lib/middleware/auth.ts +63 -0
  47. package/lib/middleware/error.ts +50 -0
  48. package/lib/middleware/multipart.ts +13 -0
  49. package/lib/middleware/rateLimit.ts +14 -0
  50. package/lib/middleware/requestLogger.ts +27 -0
  51. package/lib/middleware/visitor.ts +178 -0
  52. package/lib/utils/logger.ts +100 -0
  53. package/lib/utils/pagination.ts +56 -0
  54. package/lib/utils/response.ts +88 -0
  55. package/lib/utils/validator.ts +394 -0
  56. package/nodemon.json +6 -0
  57. package/package.json +126 -0
  58. package/readme.md +357 -0
  59. package/scripts/check-update.js +92 -0
  60. package/scripts/config-clear.js +45 -0
  61. package/scripts/generate-jwt-secret.js +38 -0
  62. package/scripts/init-project.js +84 -0
  63. package/scripts/make-module.js +89 -0
  64. package/scripts/release.js +494 -0
  65. package/scripts/seed-json.js +158 -0
  66. package/scripts/verify-rbac-functional.js +187 -0
  67. package/src/config/app.ts +9 -0
  68. package/src/config/cors.ts +5 -0
  69. package/src/modules/Auth/auth.controller.ts +519 -0
  70. package/src/modules/Rbac/rbac.controller.ts +533 -0
  71. package/src/routes/auth.ts +74 -0
  72. package/src/routes/index.ts +7 -0
  73. package/src/routes/rbac.ts +42 -0
  74. package/storage/logs/.gitkeep +0 -0
  75. package/tsconfig.build.json +12 -0
  76. package/tsconfig.json +30 -0
package/readme.md ADDED
@@ -0,0 +1,357 @@
1
+ # lapeeh Framework - Modern Node.js & TypeScript API Framework
2
+
3
+ **lapeeh** adalah framework **Node.js** berbasis **Express** dan **TypeScript** yang dirancang untuk kecepatan dan skalabilitas. Menggabungkan fleksibilitas Express dengan struktur solid ala **Laravel** dan **NestJS**, lapeeh memberikan pengalaman development **REST API** yang cepat, terstandarisasi, dan siap produksi.
4
+
5
+ Cocok untuk developer yang mencari **Express boilerplate** dengan fitur lengkap: Authentication, 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
+ - **Database Agnostic**: Bebas pilih database dan ORM pilihan Anda.
12
+ - **Standardized Structure**: Controller, Service, dan Route yang terpisah rapi.
13
+ - **Auto CLI Generator**: Buat modul 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
+ lapeeh 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
+ lapeeh 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:
61
+
62
+ ```bash
63
+ npx lapeeh@latest nama-project-anda
64
+ ```
65
+
66
+ Perintah di atas akan membuat proyek **bersih** (clean slate):
67
+
68
+ - Struktur folder dibuat.
69
+ - Dependensi diinstall.
70
+ - Folder `bin` dan `lib` framework tersembunyi di `node_modules` agar root proyek Anda tetap rapi.
71
+
72
+ ### Apa yang terjadi otomatis?
73
+
74
+ 1. Struktur project dibuat (Core framework tersembunyi sebagai dependency).
75
+ 2. Dependencies diinstall.
76
+ 3. **JWT Secret** di-generate otomatis.
77
+
78
+ Masuk ke folder project dan jalankan:
79
+
80
+ ```bash
81
+ cd nama-project-anda
82
+ npm run dev
83
+ ```
84
+
85
+ > **Catatan**: Perintah `npm run dev` sekarang menggunakan CLI internal framework (`lapeeh dev`), memberikan pengalaman development yang lebih stabil dan terstandarisasi. Core framework (`bin` dan `lib`) tidak lagi memenuhi root folder Anda, tetapi tersimpan aman sebagai dependency.
86
+
87
+ Server akan berjalan di `http://localhost:8000`.
88
+
89
+ ### šŸ›”ļø Keamanan & Pembaruan
90
+
91
+ Framework ini didesain dengan memprioritaskan keamanan:
92
+
93
+ - **Zero-Vulnerability Policy**: Kami secara rutin melakukan audit dependensi (`npm audit`) untuk memastikan tidak ada celah keamanan.
94
+ - **Framework-as-Dependency**: Dengan menyembunyikan core logic di `node_modules`, pembaruan framework menjadi lebih mudah (cukup update versi `@lapeeh/lapeeh` di `package.json`) tanpa merusak kode aplikasi Anda.
95
+
96
+ ---
97
+
98
+ ## šŸ”„ Upgrade Project
99
+
100
+ Jika Anda memiliki project lama yang dibuat dengan versi lapeeh sebelumnya dan ingin memperbarui struktur, scripts, dan konfigurasi ke standar terbaru (termasuk keamanan Redis baru), Anda tidak perlu membuat project ulang.
101
+
102
+ Cukup jalankan perintah ini di dalam folder project Anda:
103
+
104
+ ```bash
105
+ npx lapeeh@latest upgrade
106
+ ```
107
+
108
+ Perintah ini akan secara otomatis:
109
+
110
+ 1. Mengupdate `scripts/` (termasuk generator controller baru).
111
+ 2. Mengupdate `docker-compose.yml` (keamanan Redis).
112
+ 3. Mengupdate dependencies di `package.json`.
113
+ 4. Menambahkan konfigurasi `.vscode` dan `tsconfig` terbaru.
114
+
115
+ > **Catatan:** File `.env` Anda **tidak akan ditimpa**, namun kami akan mengupdate `.env.example` sebagai referensi konfigurasi terbaru.
116
+
117
+ ## 🧠 Zero-Config Redis
118
+
119
+ lapeeh otomatis mendeteksi ketersediaan Redis.
120
+
121
+ 1. **Auto-Discovery**: Mencoba terhubung ke Redis URL di `.env` (`REDIS_URL`).
122
+ 2. **Smart Fallback**: Jika Redis tidak tersedia atau koneksi gagal, otomatis beralih ke **In-Memory Mock**.
123
+ - Tidak perlu install Redis di local development.
124
+ - Fitur rate-limiting dan caching tetap berjalan (namun data hilang saat restart).
125
+ 3. **Production Safety**: Memberikan peringatan log jika berjalan di Production menggunakan Mock.
126
+
127
+ **Force Mock Mode:**
128
+ Anda bisa memaksa menggunakan mock (misal untuk testing) dengan menambahkan env variable:
129
+
130
+ ```env
131
+ NO_REDIS=true
132
+ ```
133
+
134
+ ### Optional: Menggunakan Real Redis dengan Docker
135
+
136
+ Jika Anda ingin menggunakan Redis yang sebenarnya di local environment, kami telah menyertakan konfigurasi `docker-compose.yml` yang aman (menggunakan ACL).
137
+
138
+ 1. Jalankan Redis container:
139
+
140
+ ```bash
141
+ docker-compose up -d
142
+ ```
143
+
144
+ 2. Uncomment konfigurasi Redis di file `.env` Anda:
145
+
146
+ ```env
147
+ REDIS_URL="redis://lapeeh:12341234@localhost:6379"
148
+ ```
149
+
150
+ > **Credential Default:**
151
+ >
152
+ > - User: `lapeeh`
153
+ > - Password: `12341234`
154
+
155
+ ## šŸ›  Development Tools
156
+
157
+ API lapeeh menyediakan tools untuk mempercepat development, mirip dengan `artisan` di Laravel.
158
+
159
+ ### 1. Membuat Module (Resource)
160
+
161
+ Membuat Controller, Service, dan Route sekaligus.
162
+
163
+ ```bash
164
+ npm run make:module NamaResource
165
+ # Contoh: npm run make:module Product
166
+ ```
167
+
168
+ Command ini akan membuat:
169
+
170
+ - `src/controllers/product.controller.ts`
171
+ - `src/services/product.service.ts`
172
+ - `src/routes/product.route.ts` (dan otomatis didaftarkan di `src/routes/index.ts` jika memungkinkan)
173
+
174
+ ### 2. Membuat Controller
175
+
176
+ Membuat file Controller baru. Gunakan flag `-r` untuk membuat controller lengkap dengan method CRUD (index, show, store, update, destroy).
177
+
178
+ ```bash
179
+ npm run make:controller NamaController
180
+ # Contoh Basic: npm run make:controller PaymentController
181
+
182
+ # Contoh Resource (CRUD Lengkap):
183
+ npm run make:controller PaymentController -r
184
+ ```
185
+
186
+ ### 3. Database (No-ORM)
187
+
188
+ Since v3.0.0, lapeeh Framework **does not include a default ORM** (like Prisma). We believe in giving you full control over your database stack.
189
+
190
+ You can freely choose to use:
191
+
192
+ - **Prisma** (Manual installation)
193
+ - **TypeORM**
194
+ - **Drizzle ORM**
195
+ - **Mongoose**
196
+ - **Raw SQL** (pg, mysql2)
197
+
198
+ The framework provides a `Validator` class for request validation and a `Serializer` for response formatting, but data persistence is up to you.
199
+
200
+ ### 4. Generate JWT Secret
201
+
202
+ Jika Anda perlu me-refresh secret key JWT:
203
+
204
+ ```bash
205
+ npm run generate:jwt
206
+ ```
207
+
208
+ ### 5. Maintenance (Clear Config)
209
+
210
+ Membersihkan cache framework, NPM, build artifacts, dan temporary files (sangat berguna jika mengalami isu cache aneh atau ingin reset environment development).
211
+
212
+ ```bash
213
+ npm run config:clear
214
+ ```
215
+
216
+ - Menghapus `node_modules/.cache`
217
+ - Menghapus `dist/`
218
+ - Menghapus `dump.rdb` (Redis Persistence)
219
+ - Membersihkan `npm cache`
220
+
221
+ ---
222
+
223
+ ## šŸ“‚ Struktur Folder
224
+
225
+ ```text
226
+ src/
227
+ ā”œā”€ā”€ controllers/ # Logika Request & Response
228
+ ā”œā”€ā”€ services/ # Business Logic
229
+ ā”œā”€ā”€ routes/ # Definisi Route API
230
+ ā”œā”€ā”€ middleware/ # Auth, Validation, Error Handling
231
+ ā”œā”€ā”€ schema/ # Zod Validation Schemas
232
+ ā”œā”€ā”€ utils/ # Helper Functions
233
+ └── index.ts # App Entry Point
234
+ ```
235
+
236
+ ## šŸ“ Lisensi
237
+
238
+ MIT
239
+
240
+ ---
241
+
242
+ ## šŸš€ Deployment Guide
243
+
244
+ ### 1) Build
245
+
246
+ - Build: `npm run build`
247
+ - Start (dev): `npm run start`
248
+ - Start (prod): `npm run start:prod`
249
+
250
+ ### 2) Production Environment
251
+
252
+ - Pastikan `.env` berisi kredensial production:
253
+ - `JWT_SECRET` (gunakan `npm run generate:jwt` untuk mengganti)
254
+ - Database credentials (sesuai pilihan ORM/DB Anda)
255
+
256
+ ### 3) Menjalankan dengan PM2
257
+
258
+ - Install PM2:
259
+
260
+ ```bash
261
+ npm i -g pm2
262
+ ```
263
+
264
+ - Jalankan aplikasi:
265
+
266
+ ```bash
267
+ pm2 start dist/src/index.js --name lapeeh-api --time
268
+ ```
269
+
270
+ - Simpan proses agar auto-start saat reboot:
271
+
272
+ ```bash
273
+ pm2 save
274
+ pm2 startup
275
+ ```
276
+
277
+ - Monitoring:
278
+
279
+ ```bash
280
+ pm2 status
281
+ pm2 logs lapeeh-api
282
+ pm2 restart lapeeh-api
283
+ ```
284
+
285
+ ### 4) Nginx Reverse Proxy (Recommended)
286
+
287
+ - Buat server block `/etc/nginx/sites-available/lapeeh`:
288
+
289
+ ```nginx
290
+ server {
291
+ listen 80;
292
+ server_name example.com;
293
+
294
+ location / {
295
+ proxy_set_header Host $host;
296
+ proxy_set_header X-Real-IP $remote_addr;
297
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
298
+ proxy_set_header X-Forwarded-Proto $scheme;
299
+ proxy_pass http://127.0.0.1:8000;
300
+ }
301
+ }
302
+ ```
303
+
304
+ - Aktifkan:
305
+
306
+ ```bash
307
+ sudo ln -s /etc/nginx/sites-available/lapeeh /etc/nginx/sites-enabled/lapeeh
308
+ sudo nginx -t
309
+ sudo systemctl reload nginx
310
+ ```
311
+
312
+ - SSL (opsional, Certbot):
313
+
314
+ ```bash
315
+ sudo apt install certbot python3-certbot-nginx -y
316
+ sudo certbot --nginx -d example.com
317
+ ```
318
+
319
+ ### 5) Apache 2 Reverse Proxy (Alternatif)
320
+
321
+ - Enable modul proxy:
322
+
323
+ ```bash
324
+ sudo a2enmod proxy proxy_http headers
325
+ sudo systemctl reload apache2
326
+ ```
327
+
328
+ - Buat vhost `/etc/apache2/sites-available/lapeeh.conf`:
329
+
330
+ ```apache
331
+ <VirtualHost *:80>
332
+ ServerName example.com
333
+ ProxyPreserveHost On
334
+ ProxyRequests Off
335
+ <Proxy *>
336
+ Require all granted
337
+ </Proxy>
338
+ ProxyPass / http://127.0.0.1:8000/
339
+ ProxyPassReverse / http://127.0.0.1:8000/
340
+ ErrorLog ${APACHE_LOG_DIR}/lapeeh-error.log
341
+ CustomLog ${APACHE_LOG_DIR}/lapeeh-access.log combined
342
+ </VirtualHost>
343
+ ```
344
+
345
+ - Aktifkan:
346
+
347
+ ```bash
348
+ sudo a2ensite lapeeh.conf
349
+ sudo apachectl configtest
350
+ sudo systemctl reload apache2
351
+ ```
352
+
353
+ ### 6) Checklist Produksi
354
+
355
+ - `pm2 status` menunjukkan proses hidup
356
+ - Proxy (Nginx/Apache) menuju port aplikasi (default 8000)
357
+ - `.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/lapeeh/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 "lapeeh" di dependencies (project user)
14
+ // Jika tidak ada, fallback ke version package.json (mungkin ini repo framework itu sendiri)
15
+ const currentVersion = packageJson.dependencies?.['lapeeh'] || 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 lapeeh@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,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
+ }
@@ -0,0 +1,84 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+ const { execSync } = require("child_process");
4
+ const readline = require("readline");
5
+
6
+ const rootDir = path.join(__dirname, "..");
7
+ const envExample = path.join(rootDir, ".env.example");
8
+ const envFile = path.join(rootDir, ".env");
9
+
10
+ const rl = readline.createInterface({
11
+ input: process.stdin,
12
+ output: process.stdout,
13
+ });
14
+
15
+ const ask = (query, defaultVal) => {
16
+ return new Promise((resolve) => {
17
+ rl.question(`${query} ${defaultVal ? `[${defaultVal}]` : ""}: `, (answer) => {
18
+ resolve(answer.trim() || defaultVal);
19
+ });
20
+ });
21
+ };
22
+
23
+ const selectOption = async (query, options) => {
24
+ console.log(query);
25
+ options.forEach((opt, idx) => {
26
+ console.log(` [${opt.key}] ${opt.label}`);
27
+ });
28
+
29
+ while (true) {
30
+ const answer = await ask(">", options[0].key); // Default to first option
31
+ const selected = options.find(o => o.key.toLowerCase() === answer.toLowerCase());
32
+ if (selected) return selected;
33
+
34
+ // Check if user entered the full name or label
35
+ const byLabel = options.find(o => o.label.toLowerCase().includes(answer.toLowerCase()));
36
+ if (byLabel) return byLabel;
37
+
38
+ console.log("Pilihan tidak valid. Silakan coba lagi.");
39
+ }
40
+ };
41
+
42
+ (async () => {
43
+ console.log("šŸš€ Starting project initialization...");
44
+
45
+ try {
46
+ // Close readline as we are done with input
47
+ rl.close();
48
+
49
+ // 1. Setup .env
50
+ console.log("\nšŸ“„ Setting up .env...");
51
+ let envContent = "";
52
+ if (fs.existsSync(envExample)) {
53
+ envContent = fs.readFileSync(envExample, "utf8");
54
+ } else {
55
+ // Fallback minimal env if example missing
56
+ envContent = `PORT=8000\nJWT_SECRET="replace_this"\n`;
57
+ }
58
+
59
+ fs.writeFileSync(envFile, envContent);
60
+ console.log("āœ… .env created.");
61
+
62
+ // 3. Install dependencies
63
+ console.log("\nšŸ“¦ Installing dependencies...");
64
+ execSync("npm install", { stdio: "inherit", cwd: rootDir });
65
+
66
+ // 5. Generate JWT Secret
67
+ console.log("\nšŸ”‘ Generating JWT Secret...");
68
+ try {
69
+ execSync("node scripts/generate-jwt-secret.js", {
70
+ stdio: "inherit",
71
+ cwd: rootDir,
72
+ });
73
+ } catch (e) {
74
+ console.warn("āš ļø Failed to generate JWT secret automatically.");
75
+ }
76
+
77
+ console.log("\nāœ… Setup complete! You can now run:");
78
+ console.log(" npm run dev");
79
+
80
+ } catch (error) {
81
+ console.error("\nāŒ Setup failed:", error.message);
82
+ process.exit(1);
83
+ }
84
+ })();