crypt-express-app 1.3.20
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 +329 -0
- package/dist/generate-module.js +658 -0
- package/dist/index.js +121 -0
- package/dist/scripts/generate-app.js +198 -0
- package/dist/scripts/generate-locales.js +25 -0
- package/dist/scripts/generate-middleware.js +167 -0
- package/dist/scripts/generate-module.js +739 -0
- package/dist/scripts/generate-root-files.js +759 -0
- package/dist/scripts/generate-utils.js +1002 -0
- package/dist/scripts/middleware.js +165 -0
- package/dist/scripts/setup-prisma.js +25 -0
- package/package.json +28 -0
|
@@ -0,0 +1,759 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
export function generateRootFiles(projectDir, projectName) {
|
|
4
|
+
const tsconfig = {
|
|
5
|
+
compilerOptions: {
|
|
6
|
+
module: "nodenext",
|
|
7
|
+
moduleResolution: "nodenext",
|
|
8
|
+
resolvePackageJsonExports: true,
|
|
9
|
+
esModuleInterop: true,
|
|
10
|
+
isolatedModules: true,
|
|
11
|
+
declaration: true,
|
|
12
|
+
removeComments: true,
|
|
13
|
+
emitDecoratorMetadata: true,
|
|
14
|
+
experimentalDecorators: true,
|
|
15
|
+
allowSyntheticDefaultImports: true,
|
|
16
|
+
target: "ES2023",
|
|
17
|
+
sourceMap: true,
|
|
18
|
+
rootDir: ".",
|
|
19
|
+
outDir: "./dist",
|
|
20
|
+
types: ["node"],
|
|
21
|
+
incremental: true,
|
|
22
|
+
skipLibCheck: true,
|
|
23
|
+
strictNullChecks: true,
|
|
24
|
+
forceConsistentCasingInFileNames: true,
|
|
25
|
+
noImplicitAny: false,
|
|
26
|
+
strictBindCallApply: false,
|
|
27
|
+
noFallthroughCasesInSwitch: false,
|
|
28
|
+
},
|
|
29
|
+
include: ["src", "server.ts", "prisma.config.ts"],
|
|
30
|
+
exclude: ["node_modules"],
|
|
31
|
+
};
|
|
32
|
+
fs.writeFileSync(path.join(projectDir, "tsconfig.json"), JSON.stringify(tsconfig, null, 2));
|
|
33
|
+
const packageJson = {
|
|
34
|
+
name: projectName.toLowerCase().replace(/\s+/g, "-"),
|
|
35
|
+
"version": "1.0.0",
|
|
36
|
+
"description": "Cryptdox generated expressJS backend.",
|
|
37
|
+
"keywords": [
|
|
38
|
+
"ts"
|
|
39
|
+
],
|
|
40
|
+
"homepage": "https://github.com/..#readme",
|
|
41
|
+
"bugs": {
|
|
42
|
+
"url": "https://github.com/../issues"
|
|
43
|
+
},
|
|
44
|
+
"repository": {
|
|
45
|
+
"type": "git",
|
|
46
|
+
"url": "git+https://github.com/...git"
|
|
47
|
+
},
|
|
48
|
+
"license": "ISC",
|
|
49
|
+
"author": "abir-hosen",
|
|
50
|
+
"main": "server.ts",
|
|
51
|
+
"scripts": {
|
|
52
|
+
"copy-locales": "cpx \"src/locales/**/*\" dist/src/locales",
|
|
53
|
+
"dev": "nodemon --watch 'src/**/*.ts' --exec 'ts-node' server.ts",
|
|
54
|
+
"build": "tsc && npm run copy-locales",
|
|
55
|
+
"start": "node dist/server.js",
|
|
56
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
57
|
+
"generate-module": "ts-node scripts/generate-module.ts"
|
|
58
|
+
},
|
|
59
|
+
"dependencies": {
|
|
60
|
+
"@prisma/adapter-pg": "^7.3.0",
|
|
61
|
+
"@prisma/client": "^7.3.0",
|
|
62
|
+
"acorn": "^8.15.0",
|
|
63
|
+
"acorn-walk": "^8.3.4",
|
|
64
|
+
"arg": "^4.1.3",
|
|
65
|
+
"bcrypt": "^6.0.0",
|
|
66
|
+
"cors": "^2.8.6",
|
|
67
|
+
"create-require": "^1.1.1",
|
|
68
|
+
"diff": "^4.0.4",
|
|
69
|
+
"dotenv": "^17.2.3",
|
|
70
|
+
"express": "^5.2.1",
|
|
71
|
+
"i18next": "^25.8.4",
|
|
72
|
+
"i18next-fs-backend": "^2.6.1",
|
|
73
|
+
"i18next-http-middleware": "^3.9.2",
|
|
74
|
+
"jsonwebtoken": "^9.0.3",
|
|
75
|
+
"make-error": "^1.3.6",
|
|
76
|
+
"morgan": "^1.10.1",
|
|
77
|
+
"pg": "^8.18.0",
|
|
78
|
+
"redis": "^5.11.0",
|
|
79
|
+
"swagger-jsdoc": "^6.2.8",
|
|
80
|
+
"swagger-ui-express": "^5.0.1",
|
|
81
|
+
"undici-types": "^7.16.0",
|
|
82
|
+
"v8-compile-cache-lib": "^3.0.1",
|
|
83
|
+
"winston": "^3.19.0",
|
|
84
|
+
"yn": "^3.1.1",
|
|
85
|
+
"zod": "^4.3.6"
|
|
86
|
+
},
|
|
87
|
+
"devDependencies": {
|
|
88
|
+
"@types/bcrypt": "^6.0.0",
|
|
89
|
+
"@types/cors": "^2.8.19",
|
|
90
|
+
"@types/express": "^5.0.6",
|
|
91
|
+
"@types/i18next": "^12.1.0",
|
|
92
|
+
"@types/jsonwebtoken": "^9.0.10",
|
|
93
|
+
"@types/morgan": "^1.9.10",
|
|
94
|
+
"@types/node": "^25.1.0",
|
|
95
|
+
"@types/swagger-jsdoc": "^6.0.4",
|
|
96
|
+
"@types/swagger-ui-express": "^4.1.8",
|
|
97
|
+
"cpx": "^1.5.0",
|
|
98
|
+
"nodemon": "^3.1.11",
|
|
99
|
+
"prisma": "^7.3.0",
|
|
100
|
+
"ts-node": "^10.9.2",
|
|
101
|
+
"typescript": "^5.9.3"
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
fs.writeFileSync(path.join(projectDir, "package.json"), JSON.stringify(packageJson, null, 2));
|
|
105
|
+
const nodemon = {
|
|
106
|
+
watch: ["src"],
|
|
107
|
+
ext: "ts",
|
|
108
|
+
ignore: ["dist"],
|
|
109
|
+
exec: "ts-node server.ts",
|
|
110
|
+
};
|
|
111
|
+
fs.writeFileSync(path.join(projectDir, "nodemon.json"), JSON.stringify(nodemon, null, 2));
|
|
112
|
+
const gitignore = `
|
|
113
|
+
node_modules
|
|
114
|
+
.env
|
|
115
|
+
dist
|
|
116
|
+
package-lock.json
|
|
117
|
+
pnpm-lock.yaml
|
|
118
|
+
`;
|
|
119
|
+
fs.writeFileSync(path.join(projectDir, ".gitignore"), gitignore.trim());
|
|
120
|
+
generatePrisma(projectDir);
|
|
121
|
+
generatePrismaConfig(projectDir);
|
|
122
|
+
generateEnvironmentAndDocker(projectDir);
|
|
123
|
+
generateReadme(projectDir, projectName);
|
|
124
|
+
console.log(`โ
root config files generated for project: ${projectName}`);
|
|
125
|
+
}
|
|
126
|
+
/* ================= PRISMA ================= */
|
|
127
|
+
function generatePrisma(projectDir) {
|
|
128
|
+
const prismaDir = path.join(projectDir, "prisma");
|
|
129
|
+
if (!fs.existsSync(prismaDir))
|
|
130
|
+
fs.mkdirSync(prismaDir, { recursive: true });
|
|
131
|
+
const schema = `
|
|
132
|
+
// This is your Prisma schema file,
|
|
133
|
+
// learn more about it in the docs: https://pris.ly/d/prisma-schema
|
|
134
|
+
|
|
135
|
+
// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
|
|
136
|
+
// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init
|
|
137
|
+
|
|
138
|
+
generator client {
|
|
139
|
+
provider = "prisma-client-js"
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
datasource db {
|
|
143
|
+
provider = "postgresql"
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
model Common {
|
|
147
|
+
commonId String @id @default(uuid())
|
|
148
|
+
name String @unique
|
|
149
|
+
}
|
|
150
|
+
`;
|
|
151
|
+
fs.writeFileSync(path.join(prismaDir, "schema.prisma"), schema.trim());
|
|
152
|
+
}
|
|
153
|
+
/* ================= PRISMA CONFIG ================= */
|
|
154
|
+
function generatePrismaConfig(projectDir) {
|
|
155
|
+
const config = `
|
|
156
|
+
// This file was generated by Prisma, and assumes you have installed the following:
|
|
157
|
+
// npm install --save-dev prisma dotenv
|
|
158
|
+
|
|
159
|
+
import "dotenv/config";
|
|
160
|
+
import { defineConfig } from "prisma/config";
|
|
161
|
+
|
|
162
|
+
export default defineConfig({
|
|
163
|
+
schema: "prisma/schema.prisma",
|
|
164
|
+
migrations: { path: "prisma/migrations" },
|
|
165
|
+
datasource: { url: process.env["DATABASE_URL"] },
|
|
166
|
+
});
|
|
167
|
+
`;
|
|
168
|
+
fs.writeFileSync(path.join(projectDir, "prisma.config.ts"), config.trim());
|
|
169
|
+
}
|
|
170
|
+
/* ================= ENV & DOCKER CONFIG ================= */
|
|
171
|
+
function generateEnvironmentAndDocker(projectDir) {
|
|
172
|
+
/* ================= ENV FILES ================= */
|
|
173
|
+
const baseEnv = `
|
|
174
|
+
PORT=3000
|
|
175
|
+
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/app_db?pgbouncer=true
|
|
176
|
+
IAM_REDIS_URL=redis://localhost:6380
|
|
177
|
+
`.trim();
|
|
178
|
+
const envDev = `
|
|
179
|
+
PORT=3000
|
|
180
|
+
DATABASE_URL=postgresql://postgres:postgres@postgres:5433/app_db?pgbouncer=true
|
|
181
|
+
IAM_REDIS_URL=redis://redis:6380
|
|
182
|
+
`.trim();
|
|
183
|
+
const envProd = `
|
|
184
|
+
PORT=3000
|
|
185
|
+
DATABASE_URL=postgresql://postgres:strongpassword@postgres:5433/app_db?pgbouncer=true
|
|
186
|
+
IAM_REDIS_URL=redis://redis:6380
|
|
187
|
+
`.trim();
|
|
188
|
+
const exampleEnv = `
|
|
189
|
+
PORT=
|
|
190
|
+
DATABASE_URL=
|
|
191
|
+
IAM_REDIS_URL=
|
|
192
|
+
`.trim();
|
|
193
|
+
fs.writeFileSync(path.join(projectDir, ".env"), baseEnv);
|
|
194
|
+
fs.writeFileSync(path.join(projectDir, ".env.local"), baseEnv);
|
|
195
|
+
fs.writeFileSync(path.join(projectDir, ".env.dev"), envDev);
|
|
196
|
+
fs.writeFileSync(path.join(projectDir, ".env.prod"), envProd);
|
|
197
|
+
fs.writeFileSync(path.join(projectDir, "example.env"), exampleEnv);
|
|
198
|
+
/* ================= DOCKERFILE ================= */
|
|
199
|
+
const dockerfile = `
|
|
200
|
+
FROM node:20-alpine
|
|
201
|
+
|
|
202
|
+
WORKDIR /app
|
|
203
|
+
|
|
204
|
+
COPY package.json pnpm-lock.yaml* ./
|
|
205
|
+
|
|
206
|
+
RUN npm install -g pnpm
|
|
207
|
+
RUN pnpm install
|
|
208
|
+
|
|
209
|
+
COPY . .
|
|
210
|
+
|
|
211
|
+
RUN pnpm build
|
|
212
|
+
|
|
213
|
+
EXPOSE 3000
|
|
214
|
+
|
|
215
|
+
CMD ["node", "dist/server.js"]
|
|
216
|
+
`.trim();
|
|
217
|
+
fs.writeFileSync(path.join(projectDir, "Dockerfile"), dockerfile);
|
|
218
|
+
/* ================= DOCKER COMPOSE ================= */
|
|
219
|
+
const dockerCompose = `
|
|
220
|
+
version: "3.9"
|
|
221
|
+
|
|
222
|
+
services:
|
|
223
|
+
app:
|
|
224
|
+
build: .
|
|
225
|
+
container_name: express_app
|
|
226
|
+
ports:
|
|
227
|
+
- "3001:3000"
|
|
228
|
+
env_file:
|
|
229
|
+
- .env.dev
|
|
230
|
+
depends_on:
|
|
231
|
+
- postgres
|
|
232
|
+
- redis
|
|
233
|
+
restart: always
|
|
234
|
+
|
|
235
|
+
postgres:
|
|
236
|
+
image: postgres:16
|
|
237
|
+
container_name: postgres_db
|
|
238
|
+
environment:
|
|
239
|
+
POSTGRES_USER: postgres
|
|
240
|
+
POSTGRES_PASSWORD: postgres
|
|
241
|
+
POSTGRES_DB: app_db
|
|
242
|
+
ports:
|
|
243
|
+
- "5433:5432"
|
|
244
|
+
volumes:
|
|
245
|
+
- pgdata:/var/lib/postgresql/data
|
|
246
|
+
restart: always
|
|
247
|
+
|
|
248
|
+
redis:
|
|
249
|
+
image: redis:7
|
|
250
|
+
container_name: redis_cache
|
|
251
|
+
ports:
|
|
252
|
+
- "6380:6379"
|
|
253
|
+
restart: always
|
|
254
|
+
|
|
255
|
+
iam:
|
|
256
|
+
image: abir71hosen/crypt-iam:latest
|
|
257
|
+
container_name: crypt_iam
|
|
258
|
+
depends_on:
|
|
259
|
+
- postgres
|
|
260
|
+
- redis
|
|
261
|
+
environment:
|
|
262
|
+
DATABASE_URL: postgres://postgres:postgres@postgres:5432/iam_db
|
|
263
|
+
IAM_REDIS_URL: redis://redis:6379
|
|
264
|
+
JWT_SECRET: supersecret
|
|
265
|
+
EXPOSE_PORT: 5000
|
|
266
|
+
ports:
|
|
267
|
+
- "5000:3000"
|
|
268
|
+
|
|
269
|
+
volumes:
|
|
270
|
+
pgdata:
|
|
271
|
+
`.trim();
|
|
272
|
+
fs.writeFileSync(path.join(projectDir, "docker-compose.yml"), dockerCompose);
|
|
273
|
+
console.log("โ
ENV and Docker files generated");
|
|
274
|
+
}
|
|
275
|
+
/* ================= README.MD ================= */
|
|
276
|
+
function generateReadme(projectDir, projectName) {
|
|
277
|
+
const readmeContent = `
|
|
278
|
+
> โ
This ${projectName.toUpperCase()} project was generated using \`crypt-express-app\`
|
|
279
|
+
> โ
It includes Express + TypeScript + Prisma + Redis + Swagger + Docker + IAM
|
|
280
|
+
> โ
It explains how to run THIS generated app
|
|
281
|
+
|
|
282
|
+
You can directly place this inside:
|
|
283
|
+
|
|
284
|
+
\`\`\`
|
|
285
|
+
${projectName}/README.md
|
|
286
|
+
\`\`\`
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
# ${projectName.toUpperCase()}
|
|
292
|
+
|
|
293
|
+
๐ Scalable Express + TypeScript Backend Application
|
|
294
|
+
Generated using **crypt-express-app**
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
## ๐ About This Project
|
|
299
|
+
|
|
300
|
+
This is a production-ready backend application scaffolded using the \`crypt-express-app\` CLI.
|
|
301
|
+
|
|
302
|
+
It provides a clean, modular, and scalable architecture with:
|
|
303
|
+
|
|
304
|
+
- Express + TypeScript
|
|
305
|
+
- Prisma ORM
|
|
306
|
+
- PostgreSQL
|
|
307
|
+
- Redis
|
|
308
|
+
- Swagger API documentation
|
|
309
|
+
- Internationalization (i18n)
|
|
310
|
+
- Docker support
|
|
311
|
+
- IAM integration
|
|
312
|
+
- Structured logging
|
|
313
|
+
- Global error handling
|
|
314
|
+
|
|
315
|
+
This project is designed to help you start building business logic immediately without worrying about boilerplate setup.
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
# ๐ Architecture Overview
|
|
320
|
+
|
|
321
|
+
This project follows a modular and scalable architecture.
|
|
322
|
+
|
|
323
|
+
\`\`\`
|
|
324
|
+
|
|
325
|
+
${projectName}\/
|
|
326
|
+
โ
|
|
327
|
+
โโโ src\/
|
|
328
|
+
โ โโโ app.ts
|
|
329
|
+
โ โโโ routes.ts
|
|
330
|
+
โ โโโ prisma\/
|
|
331
|
+
โ โ โโโ client.ts
|
|
332
|
+
โ โโโ modules\/
|
|
333
|
+
โ โโโ middlewares\/
|
|
334
|
+
โ โโโ utils\/
|
|
335
|
+
โ โโโ locales\/
|
|
336
|
+
โ
|
|
337
|
+
โโโ prisma\/
|
|
338
|
+
โ โโโ schema.prisma
|
|
339
|
+
โ
|
|
340
|
+
โโโ server.ts
|
|
341
|
+
โโโ docker-compose.yml
|
|
342
|
+
โโโ Dockerfile
|
|
343
|
+
โโโ .env
|
|
344
|
+
โโโ .env.dev
|
|
345
|
+
โโโ .env.prod
|
|
346
|
+
โโโ package.json
|
|
347
|
+
\`\`\`
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
---
|
|
352
|
+
|
|
353
|
+
## ๐ Folder Explanation
|
|
354
|
+
|
|
355
|
+
### \`src\/app.ts\`
|
|
356
|
+
Initializes Express app:
|
|
357
|
+
- Middleware registration
|
|
358
|
+
- Swagger setup
|
|
359
|
+
- i18n initialization
|
|
360
|
+
- Global error handling
|
|
361
|
+
|
|
362
|
+
### \`src\/routes.ts\`
|
|
363
|
+
Registers all feature module routes.
|
|
364
|
+
|
|
365
|
+
### \`src\/modules\/\`
|
|
366
|
+
Feature-based module structure.
|
|
367
|
+
Each module should contain:
|
|
368
|
+
- route
|
|
369
|
+
- controller
|
|
370
|
+
- service
|
|
371
|
+
- validation (optional)
|
|
372
|
+
|
|
373
|
+
### \`src\/prisma\/\`
|
|
374
|
+
Prisma client initialization layer.
|
|
375
|
+
|
|
376
|
+
### \`prisma\/schema.prisma\`
|
|
377
|
+
Database schema definition.
|
|
378
|
+
|
|
379
|
+
### \`src\/middlewares\/\`
|
|
380
|
+
- Logger middleware
|
|
381
|
+
- Error handler middleware
|
|
382
|
+
|
|
383
|
+
### \`src\/locales\/\`
|
|
384
|
+
Translation JSON files for:
|
|
385
|
+
- English
|
|
386
|
+
- Bengali
|
|
387
|
+
|
|
388
|
+
---
|
|
389
|
+
|
|
390
|
+
# ๐ How To Run This Project
|
|
391
|
+
|
|
392
|
+
---
|
|
393
|
+
|
|
394
|
+
# ๐ง Important: First-Time IAM Setup
|
|
395
|
+
|
|
396
|
+
If using IAM service, after running docker compose:
|
|
397
|
+
|
|
398
|
+
You must run the IAM setup command ONE TIME:
|
|
399
|
+
|
|
400
|
+
\`\`\`bash
|
|
401
|
+
docker compose up -d postgres
|
|
402
|
+
|
|
403
|
+
docker exec -it postgres_db createdb -U postgres iam_db || true
|
|
404
|
+
\`\`\`
|
|
405
|
+
|
|
406
|
+
This initializes:
|
|
407
|
+
|
|
408
|
+
* IAM database
|
|
409
|
+
* Default configuration
|
|
410
|
+
* Required internal tables
|
|
411
|
+
|
|
412
|
+
You only need to run this once.
|
|
413
|
+
|
|
414
|
+
---
|
|
415
|
+
|
|
416
|
+
# ๐ณ Option 1: Run Using Docker (Recommended)
|
|
417
|
+
|
|
418
|
+
## Step 1: Start Infrastructure
|
|
419
|
+
|
|
420
|
+
\`\`\`bash
|
|
421
|
+
docker compose up -d
|
|
422
|
+
\`\`\`\`
|
|
423
|
+
|
|
424
|
+
---
|
|
425
|
+
|
|
426
|
+
## Services Included
|
|
427
|
+
|
|
428
|
+
| Service | Description |
|
|
429
|
+
| -------- | -------------------------- |
|
|
430
|
+
| app | Express backend |
|
|
431
|
+
| postgres | PostgreSQL database |
|
|
432
|
+
| redis | Redis cache |
|
|
433
|
+
| iam | IAM authentication service |
|
|
434
|
+
|
|
435
|
+
---
|
|
436
|
+
|
|
437
|
+
## Port Mapping
|
|
438
|
+
|
|
439
|
+
| Service | Host Port | Container Port |
|
|
440
|
+
| ---------- | --------- | -------------- |
|
|
441
|
+
| App | 3001 | 3000 |
|
|
442
|
+
| PostgreSQL | 5433 | 5432 |
|
|
443
|
+
| Redis | 6380 | 6379 |
|
|
444
|
+
| IAM | 5000 | 3000 |
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
If running via Docker:
|
|
448
|
+
|
|
449
|
+
\`\`\`
|
|
450
|
+
http://localhost:3001
|
|
451
|
+
\`\`\`
|
|
452
|
+
|
|
453
|
+
---
|
|
454
|
+
|
|
455
|
+
# ๐ป Option 2: Run App Locally (Recommended for Development)
|
|
456
|
+
|
|
457
|
+
### 1๏ธโฃ Start Database & Redis
|
|
458
|
+
|
|
459
|
+
\`\`\`bash
|
|
460
|
+
docker compose up -d postgres redis iam
|
|
461
|
+
\`\`\`
|
|
462
|
+
|
|
463
|
+
---
|
|
464
|
+
|
|
465
|
+
### 2๏ธโฃ Install Dependencies
|
|
466
|
+
|
|
467
|
+
\`\`\`bash
|
|
468
|
+
pnpm install
|
|
469
|
+
\`\`\`
|
|
470
|
+
|
|
471
|
+
or
|
|
472
|
+
|
|
473
|
+
\`\`\`bash
|
|
474
|
+
npm install
|
|
475
|
+
\`\`\`
|
|
476
|
+
|
|
477
|
+
---
|
|
478
|
+
|
|
479
|
+
### 3๏ธโฃ Generate Prisma Client
|
|
480
|
+
|
|
481
|
+
\`\`\`bash
|
|
482
|
+
npx prisma generate
|
|
483
|
+
\`\`\`
|
|
484
|
+
|
|
485
|
+
---
|
|
486
|
+
|
|
487
|
+
### 4๏ธโฃ Run Migrations (First Time Only)
|
|
488
|
+
|
|
489
|
+
\`\`\`bash
|
|
490
|
+
npx prisma db push
|
|
491
|
+
\`\`\`
|
|
492
|
+
|
|
493
|
+
---
|
|
494
|
+
|
|
495
|
+
### 5๏ธโฃ Start Development Server
|
|
496
|
+
|
|
497
|
+
\`\`\`bash
|
|
498
|
+
pnpm dev
|
|
499
|
+
\`\`\`
|
|
500
|
+
|
|
501
|
+
or
|
|
502
|
+
|
|
503
|
+
\`\`\`bash
|
|
504
|
+
npm run dev
|
|
505
|
+
\`\`\`
|
|
506
|
+
|
|
507
|
+
---
|
|
508
|
+
|
|
509
|
+
Server will run at:
|
|
510
|
+
|
|
511
|
+
\`\`\`
|
|
512
|
+
http://localhost:3000
|
|
513
|
+
\`\`\`
|
|
514
|
+
|
|
515
|
+
---
|
|
516
|
+
|
|
517
|
+
# ๐ Swagger API Documentation
|
|
518
|
+
|
|
519
|
+
Access App Swagger UI at:
|
|
520
|
+
|
|
521
|
+
\`\`\`
|
|
522
|
+
http://localhost:3000/api/docs
|
|
523
|
+
\`\`\`
|
|
524
|
+
|
|
525
|
+
or Docker:
|
|
526
|
+
|
|
527
|
+
\`\`\`
|
|
528
|
+
http://localhost:3001/api/docs
|
|
529
|
+
\`\`\`
|
|
530
|
+
|
|
531
|
+
|
|
532
|
+
Access IAM Swagger UI at:
|
|
533
|
+
|
|
534
|
+
\`\`\`
|
|
535
|
+
http://localhost:5000/api/docs
|
|
536
|
+
\`\`\`
|
|
537
|
+
|
|
538
|
+
|
|
539
|
+
Get IAM master realm id to login:
|
|
540
|
+
|
|
541
|
+
\`\`\`
|
|
542
|
+
docker exec -it postgres_db psql -U postgres -d iam_db
|
|
543
|
+
SELECT * FROM realm;
|
|
544
|
+
q
|
|
545
|
+
\\q
|
|
546
|
+
\`\`\`
|
|
547
|
+
|
|
548
|
+
|
|
549
|
+
Features:
|
|
550
|
+
|
|
551
|
+
* Interactive API testing
|
|
552
|
+
* Bearer token authentication
|
|
553
|
+
* Request/response schema
|
|
554
|
+
* Try-it-out functionality
|
|
555
|
+
|
|
556
|
+
---
|
|
557
|
+
|
|
558
|
+
# ๐ Internationalization (i18n)
|
|
559
|
+
|
|
560
|
+
Supported languages:
|
|
561
|
+
|
|
562
|
+
* English
|
|
563
|
+
* Bengali
|
|
564
|
+
|
|
565
|
+
Translation files located in:
|
|
566
|
+
|
|
567
|
+
\`\`\`
|
|
568
|
+
src\/locales\/
|
|
569
|
+
\`\`\`
|
|
570
|
+
|
|
571
|
+
Language is detected automatically via request headers.
|
|
572
|
+
|
|
573
|
+
---
|
|
574
|
+
|
|
575
|
+
# ๐ง Environment Configuration
|
|
576
|
+
|
|
577
|
+
## \`.env\` (Local)
|
|
578
|
+
|
|
579
|
+
\`\`\`
|
|
580
|
+
PORT=3000
|
|
581
|
+
DATABASE_URL=postgresql:\/\/postgres:postgres@localhost:5432\/app_db?pgbouncer=true
|
|
582
|
+
IAM_REDIS_URL=redis:\/\/localhost:6379
|
|
583
|
+
\`\`\`
|
|
584
|
+
|
|
585
|
+
---
|
|
586
|
+
|
|
587
|
+
# ๐ Database Configuration
|
|
588
|
+
|
|
589
|
+
Database: PostgreSQL
|
|
590
|
+
ORM: Prisma
|
|
591
|
+
|
|
592
|
+
Schema file:
|
|
593
|
+
|
|
594
|
+
\`\`\`
|
|
595
|
+
prisma\/schema.prisma
|
|
596
|
+
\`\`\`
|
|
597
|
+
|
|
598
|
+
After updating schema:
|
|
599
|
+
|
|
600
|
+
\`\`\`bash
|
|
601
|
+
npx prisma migrate dev
|
|
602
|
+
npx prisma generate
|
|
603
|
+
\`\`\`
|
|
604
|
+
|
|
605
|
+
---
|
|
606
|
+
|
|
607
|
+
# โก Redis Cache
|
|
608
|
+
|
|
609
|
+
Redis is used for:
|
|
610
|
+
|
|
611
|
+
* Caching
|
|
612
|
+
* Performance optimization
|
|
613
|
+
* Session storage (optional)
|
|
614
|
+
* Token storage (optional)
|
|
615
|
+
|
|
616
|
+
Redis URL is configured via:
|
|
617
|
+
|
|
618
|
+
\`\`\`
|
|
619
|
+
IAM_REDIS_URL
|
|
620
|
+
\`\`\`
|
|
621
|
+
|
|
622
|
+
---
|
|
623
|
+
|
|
624
|
+
# ๐ IAM Integration
|
|
625
|
+
|
|
626
|
+
This project includes optional IAM service:
|
|
627
|
+
|
|
628
|
+
* Authentication
|
|
629
|
+
* Authorization
|
|
630
|
+
* JWT management
|
|
631
|
+
* Token validation
|
|
632
|
+
|
|
633
|
+
IAM runs on:
|
|
634
|
+
|
|
635
|
+
\`\`\`
|
|
636
|
+
http:\/\/localhost:5000
|
|
637
|
+
\`\`\`
|
|
638
|
+
|
|
639
|
+
Make sure IAM setup is completed before using protected endpoints.
|
|
640
|
+
|
|
641
|
+
---
|
|
642
|
+
|
|
643
|
+
# ๐งฑ Adding New Module
|
|
644
|
+
|
|
645
|
+
From root run:
|
|
646
|
+
|
|
647
|
+
\`\`\`
|
|
648
|
+
pnpm generate-module example
|
|
649
|
+
\`\`\`
|
|
650
|
+
|
|
651
|
+
Inside:
|
|
652
|
+
|
|
653
|
+
\`\`\`
|
|
654
|
+
src\/modules\/
|
|
655
|
+
\`\`\`
|
|
656
|
+
|
|
657
|
+
Create:
|
|
658
|
+
|
|
659
|
+
\`\`\`
|
|
660
|
+
example\/
|
|
661
|
+
example.route.ts
|
|
662
|
+
example.controller.ts
|
|
663
|
+
example.service.ts
|
|
664
|
+
example.middleware.ts
|
|
665
|
+
example.dto.ts
|
|
666
|
+
\`\`\`
|
|
667
|
+
|
|
668
|
+
Register route in:
|
|
669
|
+
|
|
670
|
+
\`\`\`
|
|
671
|
+
routes.ts
|
|
672
|
+
\`\`\`
|
|
673
|
+
|
|
674
|
+
Follow clean separation:
|
|
675
|
+
|
|
676
|
+
* Controller handles request\/response
|
|
677
|
+
* Service handles business logic
|
|
678
|
+
|
|
679
|
+
---
|
|
680
|
+
|
|
681
|
+
# ๐ Available Scripts
|
|
682
|
+
|
|
683
|
+
\`\`\`
|
|
684
|
+
pnpm dev
|
|
685
|
+
pnpm build
|
|
686
|
+
pnpm start
|
|
687
|
+
\`\`\`
|
|
688
|
+
|
|
689
|
+
| Script | Purpose |
|
|
690
|
+
| ------ | -------------------- |
|
|
691
|
+
| dev | Development mode |
|
|
692
|
+
| build | Compile TypeScript |
|
|
693
|
+
| start | Run production build |
|
|
694
|
+
|
|
695
|
+
---
|
|
696
|
+
|
|
697
|
+
# ๐ Production Deployment
|
|
698
|
+
|
|
699
|
+
Recommended:
|
|
700
|
+
|
|
701
|
+
* Use \`.env.\`
|
|
702
|
+
* Secure database credentials
|
|
703
|
+
* Use reverse proxy (NGINX)
|
|
704
|
+
* Enable SSL
|
|
705
|
+
* Use Docker Compose
|
|
706
|
+
* Monitor logs
|
|
707
|
+
|
|
708
|
+
---
|
|
709
|
+
|
|
710
|
+
# ๐งช Best Practices
|
|
711
|
+
|
|
712
|
+
* Keep modules small
|
|
713
|
+
* Avoid business logic in controllers
|
|
714
|
+
* Use service layer properly
|
|
715
|
+
* Validate inputs
|
|
716
|
+
* Handle errors centrally
|
|
717
|
+
* Use environment-based config
|
|
718
|
+
|
|
719
|
+
---
|
|
720
|
+
|
|
721
|
+
# ๐ License
|
|
722
|
+
|
|
723
|
+
ISC
|
|
724
|
+
|
|
725
|
+
---
|
|
726
|
+
|
|
727
|
+
# ๐จโ๐ป Generated With
|
|
728
|
+
|
|
729
|
+
This project was generated using:
|
|
730
|
+
|
|
731
|
+
crypt-express-app
|
|
732
|
+
|
|
733
|
+
Production-ready Express backend scaffolding CLI.
|
|
734
|
+
|
|
735
|
+
---
|
|
736
|
+
|
|
737
|
+
# ๐ Now What?
|
|
738
|
+
|
|
739
|
+
You can now:
|
|
740
|
+
|
|
741
|
+
* Add business logic
|
|
742
|
+
* Build APIs
|
|
743
|
+
* Connect frontend
|
|
744
|
+
* Implement module authorization
|
|
745
|
+
* Deploy to production
|
|
746
|
+
|
|
747
|
+
Happy coding ๐
|
|
748
|
+
|
|
749
|
+
## ๐ Links
|
|
750
|
+
|
|
751
|
+
- ๐ Website: [Cryptdox](https://cryptdox.com)
|
|
752
|
+
- ๐ฆ NPM Package: [crypt-express-app](https://www.npmjs.com/package/crypt-express-app)
|
|
753
|
+
- ๐ค Portfolio: [abir.cryptdox.com](http://abir.cryptdox.com)
|
|
754
|
+
- ๐ง Email: abir71.hosen@gmail.com
|
|
755
|
+
|
|
756
|
+
`.trim();
|
|
757
|
+
fs.writeFileSync(path.join(projectDir, "README.md"), readmeContent);
|
|
758
|
+
console.log("โ
Readme.md file generated");
|
|
759
|
+
}
|