mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 21:01:08 +02:00
🔧 chore: create @manacore/shared-nestjs-setup and migrate 8 backends
- Create shared package with bootstrapApp(), configureCors(), configureValidation() - Migrate: chat, calendar, contacts, zitare, clock, planta, presi, nutriphi - Skip complex backends: manadeck, picture, todo, skilltree, questions, storage Savings: ~280 LOC (8 backends × 35 LOC each)
This commit is contained in:
parent
840f6d7ff3
commit
fbd315eac0
21 changed files with 280 additions and 314 deletions
|
|
@ -24,6 +24,7 @@
|
|||
"@calendar/shared": "workspace:*",
|
||||
"@manacore/shared-nestjs-auth": "workspace:*",
|
||||
"@manacore/shared-nestjs-metrics": "workspace:*",
|
||||
"@manacore/shared-nestjs-setup": "workspace:*",
|
||||
"@nestjs/common": "^10.4.15",
|
||||
"@nestjs/config": "^3.3.0",
|
||||
"@nestjs/core": "^10.4.15",
|
||||
|
|
|
|||
|
|
@ -1,42 +1,8 @@
|
|||
import { NestFactory } from '@nestjs/core';
|
||||
import { ValidationPipe } from '@nestjs/common';
|
||||
import { bootstrapApp } from '@manacore/shared-nestjs-setup';
|
||||
import { AppModule } from './app.module';
|
||||
|
||||
async function bootstrap() {
|
||||
const app = await NestFactory.create(AppModule);
|
||||
|
||||
// Enable CORS for mobile and web apps
|
||||
const corsOrigins = process.env.CORS_ORIGINS?.split(',').map((origin) => origin.trim()) || [
|
||||
'http://localhost:3000',
|
||||
'http://localhost:5173',
|
||||
'http://localhost:5179',
|
||||
'http://localhost:8081',
|
||||
'exp://localhost:8081',
|
||||
'http://localhost:3001',
|
||||
];
|
||||
|
||||
app.enableCors({
|
||||
origin: corsOrigins,
|
||||
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
|
||||
credentials: true,
|
||||
});
|
||||
|
||||
// Enable validation
|
||||
app.useGlobalPipes(
|
||||
new ValidationPipe({
|
||||
whitelist: true,
|
||||
transform: true,
|
||||
forbidNonWhitelisted: true,
|
||||
})
|
||||
);
|
||||
|
||||
// Set global prefix for API routes (exclude metrics endpoint)
|
||||
app.setGlobalPrefix('api/v1', {
|
||||
exclude: ['metrics', 'health'],
|
||||
});
|
||||
|
||||
const port = process.env.PORT || 3014;
|
||||
await app.listen(port);
|
||||
console.log(`Calendar backend running on http://localhost:${port}`);
|
||||
}
|
||||
bootstrap();
|
||||
bootstrapApp(AppModule, {
|
||||
defaultPort: 3014,
|
||||
serviceName: 'Calendar',
|
||||
additionalCorsOrigins: ['http://localhost:5179'],
|
||||
});
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
"@manacore/shared-errors": "workspace:*",
|
||||
"@manacore/shared-nestjs-auth": "workspace:*",
|
||||
"@manacore/shared-nestjs-metrics": "workspace:*",
|
||||
"@manacore/shared-nestjs-setup": "workspace:*",
|
||||
"@nestjs/common": "^10.4.15",
|
||||
"@nestjs/config": "^3.3.0",
|
||||
"@nestjs/core": "^10.4.15",
|
||||
|
|
|
|||
|
|
@ -1,43 +1,8 @@
|
|||
import { NestFactory } from '@nestjs/core';
|
||||
import { ValidationPipe } from '@nestjs/common';
|
||||
import { bootstrapApp } from '@manacore/shared-nestjs-setup';
|
||||
import { AppModule } from './app.module';
|
||||
|
||||
async function bootstrap() {
|
||||
const app = await NestFactory.create(AppModule);
|
||||
|
||||
// Enable CORS for mobile and web apps
|
||||
const corsOrigins = process.env.CORS_ORIGINS?.split(',').map((origin) => origin.trim()) || [
|
||||
'http://localhost:3000',
|
||||
'http://localhost:5173',
|
||||
'http://localhost:5174',
|
||||
'http://localhost:5178',
|
||||
'http://localhost:8081',
|
||||
'exp://localhost:8081',
|
||||
'http://localhost:3001',
|
||||
];
|
||||
|
||||
app.enableCors({
|
||||
origin: corsOrigins,
|
||||
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
|
||||
credentials: true,
|
||||
});
|
||||
|
||||
// Enable validation
|
||||
app.useGlobalPipes(
|
||||
new ValidationPipe({
|
||||
whitelist: true,
|
||||
transform: true,
|
||||
forbidNonWhitelisted: true,
|
||||
})
|
||||
);
|
||||
|
||||
// Set global prefix for API routes (exclude metrics endpoint)
|
||||
app.setGlobalPrefix('api/v1', {
|
||||
exclude: ['metrics', 'health'],
|
||||
});
|
||||
|
||||
const port = process.env.PORT || 3002;
|
||||
await app.listen(port);
|
||||
console.log(`Chat backend running on http://localhost:${port}`);
|
||||
}
|
||||
bootstrap();
|
||||
bootstrapApp(AppModule, {
|
||||
defaultPort: 3002,
|
||||
serviceName: 'Chat',
|
||||
additionalCorsOrigins: ['http://localhost:5174', 'http://localhost:5178'],
|
||||
});
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
"@clock/shared": "workspace:*",
|
||||
"@manacore/shared-nestjs-auth": "workspace:*",
|
||||
"@manacore/shared-nestjs-metrics": "workspace:*",
|
||||
"@manacore/shared-nestjs-setup": "workspace:*",
|
||||
"@nestjs/common": "^10.4.15",
|
||||
"@nestjs/config": "^3.3.0",
|
||||
"@nestjs/core": "^10.4.15",
|
||||
|
|
|
|||
|
|
@ -1,42 +1,8 @@
|
|||
import { NestFactory } from '@nestjs/core';
|
||||
import { ValidationPipe } from '@nestjs/common';
|
||||
import { bootstrapApp } from '@manacore/shared-nestjs-setup';
|
||||
import { AppModule } from './app.module';
|
||||
|
||||
async function bootstrap() {
|
||||
const app = await NestFactory.create(AppModule);
|
||||
|
||||
// Enable CORS for mobile and web apps
|
||||
const corsOrigins = process.env.CORS_ORIGINS?.split(',').map((origin) => origin.trim()) || [
|
||||
'http://localhost:3000',
|
||||
'http://localhost:5173',
|
||||
'http://localhost:5186',
|
||||
'http://localhost:8081',
|
||||
'exp://localhost:8081',
|
||||
'http://localhost:3001',
|
||||
];
|
||||
|
||||
app.enableCors({
|
||||
origin: corsOrigins,
|
||||
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
|
||||
credentials: true,
|
||||
});
|
||||
|
||||
// Enable validation
|
||||
app.useGlobalPipes(
|
||||
new ValidationPipe({
|
||||
whitelist: true,
|
||||
transform: true,
|
||||
forbidNonWhitelisted: true,
|
||||
})
|
||||
);
|
||||
|
||||
// Set global prefix for API routes (exclude metrics endpoint)
|
||||
app.setGlobalPrefix('api/v1', {
|
||||
exclude: ['metrics', 'health'],
|
||||
});
|
||||
|
||||
const port = process.env.PORT || 3017;
|
||||
await app.listen(port);
|
||||
console.log(`Clock backend running on http://localhost:${port}`);
|
||||
}
|
||||
bootstrap();
|
||||
bootstrapApp(AppModule, {
|
||||
defaultPort: 3017,
|
||||
serviceName: 'Clock',
|
||||
additionalCorsOrigins: ['http://localhost:5186'],
|
||||
});
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
"dependencies": {
|
||||
"@manacore/shared-nestjs-auth": "workspace:*",
|
||||
"@manacore/shared-nestjs-metrics": "workspace:*",
|
||||
"@manacore/shared-nestjs-setup": "workspace:*",
|
||||
"@manacore/shared-storage": "workspace:*",
|
||||
"@nestjs/common": "^10.4.15",
|
||||
"@nestjs/config": "^3.3.0",
|
||||
|
|
|
|||
|
|
@ -1,42 +1,8 @@
|
|||
import { NestFactory } from '@nestjs/core';
|
||||
import { ValidationPipe } from '@nestjs/common';
|
||||
import { bootstrapApp } from '@manacore/shared-nestjs-setup';
|
||||
import { AppModule } from './app.module';
|
||||
|
||||
async function bootstrap() {
|
||||
const app = await NestFactory.create(AppModule);
|
||||
|
||||
// Enable CORS for mobile and web apps
|
||||
const corsOrigins = process.env.CORS_ORIGINS?.split(',').map((origin) => origin.trim()) || [
|
||||
'http://localhost:3000',
|
||||
'http://localhost:5173',
|
||||
'http://localhost:5184',
|
||||
'http://localhost:8081',
|
||||
'exp://localhost:8081',
|
||||
'http://localhost:3001',
|
||||
];
|
||||
|
||||
app.enableCors({
|
||||
origin: corsOrigins,
|
||||
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
|
||||
credentials: true,
|
||||
});
|
||||
|
||||
// Enable validation
|
||||
app.useGlobalPipes(
|
||||
new ValidationPipe({
|
||||
whitelist: true,
|
||||
transform: true,
|
||||
forbidNonWhitelisted: true,
|
||||
})
|
||||
);
|
||||
|
||||
// Set global prefix for API routes (exclude metrics endpoint)
|
||||
app.setGlobalPrefix('api/v1', {
|
||||
exclude: ['metrics', 'health'],
|
||||
});
|
||||
|
||||
const port = process.env.PORT || 3015;
|
||||
await app.listen(port);
|
||||
console.log(`Contacts backend running on http://localhost:${port}`);
|
||||
}
|
||||
bootstrap();
|
||||
bootstrapApp(AppModule, {
|
||||
defaultPort: 3015,
|
||||
serviceName: 'Contacts',
|
||||
additionalCorsOrigins: ['http://localhost:5184'],
|
||||
});
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
"dependencies": {
|
||||
"@nutriphi/shared": "workspace:*",
|
||||
"@manacore/shared-nestjs-auth": "workspace:*",
|
||||
"@manacore/shared-nestjs-setup": "workspace:*",
|
||||
"@google/generative-ai": "^0.21.0",
|
||||
"@nestjs/common": "^10.4.15",
|
||||
"@nestjs/config": "^3.3.0",
|
||||
|
|
|
|||
|
|
@ -1,35 +1,9 @@
|
|||
import { NestFactory } from '@nestjs/core';
|
||||
import { ValidationPipe } from '@nestjs/common';
|
||||
import { bootstrapApp } from '@manacore/shared-nestjs-setup';
|
||||
import { AppModule } from './app.module';
|
||||
|
||||
async function bootstrap() {
|
||||
const app = await NestFactory.create(AppModule);
|
||||
|
||||
// Enable CORS
|
||||
app.enableCors({
|
||||
origin: process.env.CORS_ORIGINS?.split(',') || [
|
||||
'http://localhost:5180',
|
||||
'http://localhost:4323',
|
||||
'http://localhost:3001',
|
||||
],
|
||||
credentials: true,
|
||||
});
|
||||
|
||||
// Global validation pipe
|
||||
app.useGlobalPipes(
|
||||
new ValidationPipe({
|
||||
whitelist: true,
|
||||
transform: true,
|
||||
forbidNonWhitelisted: true,
|
||||
})
|
||||
);
|
||||
|
||||
// Global prefix
|
||||
app.setGlobalPrefix('api/v1');
|
||||
|
||||
const port = process.env.PORT || 3023;
|
||||
await app.listen(port);
|
||||
console.log(`NutriPhi Backend running on http://localhost:${port}`);
|
||||
}
|
||||
|
||||
bootstrap();
|
||||
bootstrapApp(AppModule, {
|
||||
defaultPort: 3023,
|
||||
serviceName: 'NutriPhi',
|
||||
additionalCorsOrigins: ['http://localhost:5180', 'http://localhost:4323'],
|
||||
excludeFromPrefix: [], // no exclusions
|
||||
});
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
"dependencies": {
|
||||
"@google/generative-ai": "^0.21.0",
|
||||
"@manacore/shared-nestjs-auth": "workspace:*",
|
||||
"@manacore/shared-nestjs-setup": "workspace:*",
|
||||
"@manacore/shared-storage": "workspace:*",
|
||||
"@nestjs/common": "^10.4.15",
|
||||
"@nestjs/config": "^3.3.0",
|
||||
|
|
|
|||
|
|
@ -1,38 +1,9 @@
|
|||
import { NestFactory } from '@nestjs/core';
|
||||
import { ValidationPipe } from '@nestjs/common';
|
||||
import { bootstrapApp } from '@manacore/shared-nestjs-setup';
|
||||
import { AppModule } from './app.module';
|
||||
|
||||
async function bootstrap() {
|
||||
const app = await NestFactory.create(AppModule);
|
||||
|
||||
// Enable CORS for web app
|
||||
const corsOrigins = process.env.CORS_ORIGINS?.split(',').map((origin) => origin.trim()) || [
|
||||
'http://localhost:3000',
|
||||
'http://localhost:5173',
|
||||
'http://localhost:5191',
|
||||
'http://localhost:3001',
|
||||
];
|
||||
|
||||
app.enableCors({
|
||||
origin: corsOrigins,
|
||||
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
|
||||
credentials: true,
|
||||
});
|
||||
|
||||
// Enable validation
|
||||
app.useGlobalPipes(
|
||||
new ValidationPipe({
|
||||
whitelist: true,
|
||||
transform: true,
|
||||
forbidNonWhitelisted: true,
|
||||
})
|
||||
);
|
||||
|
||||
// Set global prefix for API routes
|
||||
app.setGlobalPrefix('api/v1');
|
||||
|
||||
const port = process.env.PORT || 3022;
|
||||
await app.listen(port);
|
||||
console.log(`Planta backend running on http://localhost:${port}`);
|
||||
}
|
||||
bootstrap();
|
||||
bootstrapApp(AppModule, {
|
||||
defaultPort: 3022,
|
||||
serviceName: 'Planta',
|
||||
additionalCorsOrigins: ['http://localhost:5191'],
|
||||
excludeFromPrefix: [], // no exclusions
|
||||
});
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@manacore/shared-nestjs-auth": "workspace:*",
|
||||
"@manacore/shared-nestjs-setup": "workspace:*",
|
||||
"@nestjs/common": "^10.4.15",
|
||||
"@nestjs/config": "^3.3.0",
|
||||
"@nestjs/core": "^10.4.15",
|
||||
|
|
|
|||
|
|
@ -1,41 +1,9 @@
|
|||
import { NestFactory } from '@nestjs/core';
|
||||
import { ValidationPipe } from '@nestjs/common';
|
||||
import { bootstrapApp } from '@manacore/shared-nestjs-setup';
|
||||
import { AppModule } from './app.module';
|
||||
|
||||
async function bootstrap() {
|
||||
const app = await NestFactory.create(AppModule);
|
||||
|
||||
// Enable CORS for mobile and web apps
|
||||
const corsOrigins = process.env.CORS_ORIGINS?.split(',').map((origin) => origin.trim()) || [
|
||||
'http://localhost:3000',
|
||||
'http://localhost:5173',
|
||||
'http://localhost:5177',
|
||||
'http://localhost:5178',
|
||||
'http://localhost:8081',
|
||||
'exp://localhost:8081',
|
||||
'http://localhost:3001',
|
||||
];
|
||||
|
||||
app.enableCors({
|
||||
origin: corsOrigins,
|
||||
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
|
||||
credentials: true,
|
||||
});
|
||||
|
||||
// Enable validation
|
||||
app.useGlobalPipes(
|
||||
new ValidationPipe({
|
||||
whitelist: true,
|
||||
transform: true,
|
||||
forbidNonWhitelisted: true,
|
||||
})
|
||||
);
|
||||
|
||||
// Set global prefix for API routes
|
||||
app.setGlobalPrefix('api/v1');
|
||||
|
||||
const port = process.env.PORT || 3008;
|
||||
await app.listen(port);
|
||||
console.log(`Presi backend running on http://localhost:${port}`);
|
||||
}
|
||||
bootstrap();
|
||||
bootstrapApp(AppModule, {
|
||||
defaultPort: 3008,
|
||||
serviceName: 'Presi',
|
||||
additionalCorsOrigins: ['http://localhost:5177', 'http://localhost:5178'],
|
||||
excludeFromPrefix: [], // no exclusions
|
||||
});
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@manacore/shared-nestjs-auth": "workspace:*",
|
||||
"@manacore/shared-nestjs-setup": "workspace:*",
|
||||
"@nestjs/common": "^10.4.15",
|
||||
"@nestjs/config": "^3.3.0",
|
||||
"@nestjs/core": "^10.4.15",
|
||||
|
|
|
|||
|
|
@ -1,40 +1,8 @@
|
|||
import { NestFactory } from '@nestjs/core';
|
||||
import { ValidationPipe } from '@nestjs/common';
|
||||
import { bootstrapApp } from '@manacore/shared-nestjs-setup';
|
||||
import { AppModule } from './app.module';
|
||||
|
||||
async function bootstrap() {
|
||||
const app = await NestFactory.create(AppModule);
|
||||
|
||||
// Enable CORS for mobile and web apps
|
||||
const corsOrigins = process.env.CORS_ORIGINS?.split(',').map((origin) => origin.trim()) || [
|
||||
'http://localhost:3000',
|
||||
'http://localhost:5173',
|
||||
'http://localhost:5177',
|
||||
'http://localhost:8081',
|
||||
'exp://localhost:8081',
|
||||
'http://localhost:3001',
|
||||
];
|
||||
|
||||
app.enableCors({
|
||||
origin: corsOrigins,
|
||||
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
|
||||
credentials: true,
|
||||
});
|
||||
|
||||
// Enable validation
|
||||
app.useGlobalPipes(
|
||||
new ValidationPipe({
|
||||
whitelist: true,
|
||||
transform: true,
|
||||
forbidNonWhitelisted: true,
|
||||
})
|
||||
);
|
||||
|
||||
// Set global prefix for API routes
|
||||
app.setGlobalPrefix('api/v1');
|
||||
|
||||
const port = process.env.PORT || 3007;
|
||||
await app.listen(port);
|
||||
console.log(`Quote backend running on http://localhost:${port}`);
|
||||
}
|
||||
bootstrap();
|
||||
bootstrapApp(AppModule, {
|
||||
defaultPort: 3007,
|
||||
serviceName: 'Quote',
|
||||
additionalCorsOrigins: ['http://localhost:5177'],
|
||||
});
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
| ~~**KRITISCH**~~ | ~~Backend Metrics Migration~~ | ~~350 LOC~~ ✅ **709 LOC entfernt** | ~~Niedrig~~ |
|
||||
| **HOCH** | Skeleton Components | 800-1.000 LOC | Mittel |
|
||||
| ~~**HOCH**~~ | ~~App Settings Stores~~ | ~~600-700 LOC~~ ✅ **323 LOC entfernt** | ~~Mittel~~ |
|
||||
| **HOCH** | Main.ts/CORS Patterns | 1.800 LOC | Mittel |
|
||||
| ~~**HOCH**~~ | ~~Main.ts/CORS Patterns~~ | ~~1.800 LOC~~ ✅ **~280 LOC entfernt** | ~~Mittel~~ |
|
||||
| ~~**MITTEL**~~ | ~~TypeScript Configs~~ | ~~400 LOC~~ ✅ **~280 LOC entfernt** | ~~Niedrig~~ |
|
||||
| ~~**MITTEL**~~ | ~~UI Component Cleanup~~ | ~~400 LOC~~ ✅ **~74 LOC entfernt** | ~~Niedrig~~ |
|
||||
| ~~**MITTEL**~~ | ~~Vite Configs~~ | ~~300 LOC~~ ✅ **~350 LOC entfernt** | ~~Niedrig~~ |
|
||||
|
|
@ -51,11 +51,23 @@ import { MetricsModule } from '@manacore/shared-nestjs-metrics';
|
|||
|
||||
---
|
||||
|
||||
### 1.2 HOCH: Main.ts/CORS Setup (1.800 LOC)
|
||||
### ~~1.2 HOCH: Main.ts/CORS Setup~~ ✅ TEILWEISE ERLEDIGT (~280 LOC gespart)
|
||||
|
||||
**Problem:** 14 Backends haben fast identische `main.ts` mit CORS, ValidationPipe, GlobalPrefix.
|
||||
**Status:** `@manacore/shared-nestjs-setup` Package erstellt und 8 Backends migriert (29.01.2026)
|
||||
|
||||
**Empfehlung:** Erstelle `@manacore/shared-nestjs-setup`
|
||||
**Migrierte Backends (8 von 14):**
|
||||
- ✅ chat (3002), calendar (3014), contacts (3015), zitare (3007)
|
||||
- ✅ clock (3017), planta (3022), presi (3008), nutriphi (3023)
|
||||
|
||||
**Nicht migriert (komplexe Anforderungen):**
|
||||
- ⏭️ manadeck - ConfigService, AppExceptionFilter
|
||||
- ⏭️ picture - NestExpressApplication, Static Assets
|
||||
- ⏭️ todo, skilltree - CORS Callback mit Logger
|
||||
- ⏭️ questions, storage - ConfigService
|
||||
|
||||
**Einsparung:** 8 Backends × ~35 LOC = ~280 LOC
|
||||
|
||||
**Empfehlung für komplexe Backends:** Erstelle `@manacore/shared-nestjs-setup`
|
||||
|
||||
```typescript
|
||||
// packages/shared-nestjs-setup/src/bootstrap.ts
|
||||
|
|
@ -445,9 +457,9 @@ export default createDrizzleConfig({ dbName: 'chat' });
|
|||
|
||||
### Phase 3: Backend Setup (5-7 Tage, ~2.000 LOC)
|
||||
|
||||
| Aufgabe | LOC | Aufwand |
|
||||
|---------|-----|---------|
|
||||
| `@manacore/shared-nestjs-setup` erstellen | 1.800 | Mittel | Offen |
|
||||
| Aufgabe | LOC | Aufwand | Status |
|
||||
|---------|-----|---------|--------|
|
||||
| ~~`@manacore/shared-nestjs-setup` erstellen~~ | ~~1.800~~ → **280** | ~~Mittel~~ | ✅ 8 Backends migriert |
|
||||
| `@manacore/shared-nestjs-health` erstellen | 170 | Niedrig | Offen |
|
||||
| ~~Drizzle Config Factory erstellen~~ | ~~200~~ → **160** | ~~Niedrig~~ | ✅ Erledigt |
|
||||
|
||||
|
|
|
|||
25
packages/shared-nestjs-setup/package.json
Normal file
25
packages/shared-nestjs-setup/package.json
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"name": "@manacore/shared-nestjs-setup",
|
||||
"version": "1.0.0",
|
||||
"description": "Shared NestJS bootstrap utilities for ManaCore backends",
|
||||
"main": "./src/index.ts",
|
||||
"types": "./src/index.ts",
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"type-check": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nestjs/common": "^10.0.0 || ^11.0.0",
|
||||
"@nestjs/core": "^10.0.0 || ^11.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@nestjs/common": "^10.0.0 || ^11.0.0",
|
||||
"@nestjs/core": "^10.0.0 || ^11.0.0"
|
||||
}
|
||||
}
|
||||
137
packages/shared-nestjs-setup/src/index.ts
Normal file
137
packages/shared-nestjs-setup/src/index.ts
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
/**
|
||||
* Shared NestJS Bootstrap Utilities for ManaCore Backends
|
||||
*
|
||||
* Provides a consistent setup for CORS, validation, and global prefix
|
||||
* across all backend applications.
|
||||
*/
|
||||
|
||||
import { INestApplication, ValidationPipe, Type } from '@nestjs/common';
|
||||
import { NestFactory } from '@nestjs/core';
|
||||
|
||||
/**
|
||||
* Default CORS origins for local development
|
||||
* These ports cover most common dev scenarios
|
||||
*/
|
||||
export const DEFAULT_CORS_ORIGINS = [
|
||||
'http://localhost:3000', // Common web dev port
|
||||
'http://localhost:3001', // Mana-core-auth
|
||||
'http://localhost:5173', // Vite default
|
||||
'http://localhost:8081', // Expo
|
||||
'exp://localhost:8081', // Expo native
|
||||
];
|
||||
|
||||
/**
|
||||
* Configuration options for the bootstrap utility
|
||||
*/
|
||||
export interface BootstrapOptions {
|
||||
/** Default port if PORT env is not set */
|
||||
defaultPort: number;
|
||||
/** Service name for console log message */
|
||||
serviceName: string;
|
||||
/** Additional CORS origins beyond defaults (app-specific web port) */
|
||||
additionalCorsOrigins?: string[];
|
||||
/** API prefix (default: 'api/v1') */
|
||||
apiPrefix?: string;
|
||||
/** Routes to exclude from global prefix (default: ['metrics', 'health']) */
|
||||
excludeFromPrefix?: string[];
|
||||
/** HTTP methods for CORS (default: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS']) */
|
||||
corsMethods?: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse CORS origins from environment or use defaults
|
||||
*/
|
||||
function getCorsOrigins(additionalOrigins: string[] = []): string[] {
|
||||
const envOrigins = process.env.CORS_ORIGINS?.split(',').map((origin) => origin.trim());
|
||||
if (envOrigins && envOrigins.length > 0) {
|
||||
return envOrigins;
|
||||
}
|
||||
return [...DEFAULT_CORS_ORIGINS, ...additionalOrigins];
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure standard CORS settings for the application
|
||||
*/
|
||||
export function configureCors(
|
||||
app: INestApplication,
|
||||
options: { additionalOrigins?: string[]; methods?: string[] } = {}
|
||||
): void {
|
||||
const corsOrigins = getCorsOrigins(options.additionalOrigins);
|
||||
const methods = options.methods || ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'];
|
||||
|
||||
app.enableCors({
|
||||
origin: corsOrigins,
|
||||
methods,
|
||||
credentials: true,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure standard validation pipe settings
|
||||
*/
|
||||
export function configureValidation(app: INestApplication): void {
|
||||
app.useGlobalPipes(
|
||||
new ValidationPipe({
|
||||
whitelist: true,
|
||||
transform: true,
|
||||
forbidNonWhitelisted: true,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure global API prefix with standard exclusions
|
||||
*/
|
||||
export function configurePrefix(
|
||||
app: INestApplication,
|
||||
prefix = 'api/v1',
|
||||
exclude: string[] = ['metrics', 'health']
|
||||
): void {
|
||||
app.setGlobalPrefix(prefix, { exclude });
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstrap a NestJS application with standard configuration
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* import { bootstrapApp } from '@manacore/shared-nestjs-setup';
|
||||
* import { AppModule } from './app.module';
|
||||
*
|
||||
* bootstrapApp(AppModule, {
|
||||
* defaultPort: 3002,
|
||||
* serviceName: 'Chat',
|
||||
* additionalCorsOrigins: ['http://localhost:5178'],
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
export async function bootstrapApp(
|
||||
AppModule: Type<unknown>,
|
||||
options: BootstrapOptions
|
||||
): Promise<INestApplication> {
|
||||
const app = await NestFactory.create(AppModule);
|
||||
|
||||
// Configure CORS
|
||||
configureCors(app, {
|
||||
additionalOrigins: options.additionalCorsOrigins,
|
||||
methods: options.corsMethods,
|
||||
});
|
||||
|
||||
// Configure validation
|
||||
configureValidation(app);
|
||||
|
||||
// Configure global prefix
|
||||
configurePrefix(
|
||||
app,
|
||||
options.apiPrefix ?? 'api/v1',
|
||||
options.excludeFromPrefix ?? ['metrics', 'health']
|
||||
);
|
||||
|
||||
// Start listening
|
||||
const port = process.env.PORT || options.defaultPort;
|
||||
await app.listen(port);
|
||||
|
||||
console.log(`${options.serviceName} backend running on http://localhost:${port}`);
|
||||
|
||||
return app;
|
||||
}
|
||||
3
packages/shared-nestjs-setup/tsconfig.json
Normal file
3
packages/shared-nestjs-setup/tsconfig.json
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"extends": "@manacore/shared-tsconfig/nestjs"
|
||||
}
|
||||
37
pnpm-lock.yaml
generated
37
pnpm-lock.yaml
generated
|
|
@ -71,6 +71,9 @@ importers:
|
|||
'@manacore/shared-nestjs-metrics':
|
||||
specifier: workspace:*
|
||||
version: link:../../../../packages/shared-nestjs-metrics
|
||||
'@manacore/shared-nestjs-setup':
|
||||
specifier: workspace:*
|
||||
version: link:../../../../packages/shared-nestjs-setup
|
||||
'@nestjs/common':
|
||||
specifier: ^10.4.15
|
||||
version: 10.4.20(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||
|
|
@ -388,6 +391,9 @@ importers:
|
|||
'@manacore/shared-nestjs-metrics':
|
||||
specifier: workspace:*
|
||||
version: link:../../../../packages/shared-nestjs-metrics
|
||||
'@manacore/shared-nestjs-setup':
|
||||
specifier: workspace:*
|
||||
version: link:../../../../packages/shared-nestjs-setup
|
||||
'@nestjs/common':
|
||||
specifier: ^10.4.15
|
||||
version: 10.4.20(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||
|
|
@ -727,6 +733,9 @@ importers:
|
|||
'@manacore/shared-nestjs-metrics':
|
||||
specifier: workspace:*
|
||||
version: link:../../../../packages/shared-nestjs-metrics
|
||||
'@manacore/shared-nestjs-setup':
|
||||
specifier: workspace:*
|
||||
version: link:../../../../packages/shared-nestjs-setup
|
||||
'@nestjs/common':
|
||||
specifier: ^10.4.15
|
||||
version: 10.4.20(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||
|
|
@ -994,6 +1003,9 @@ importers:
|
|||
'@manacore/shared-nestjs-metrics':
|
||||
specifier: workspace:*
|
||||
version: link:../../../../packages/shared-nestjs-metrics
|
||||
'@manacore/shared-nestjs-setup':
|
||||
specifier: workspace:*
|
||||
version: link:../../../../packages/shared-nestjs-setup
|
||||
'@manacore/shared-storage':
|
||||
specifier: workspace:*
|
||||
version: link:../../../../packages/shared-storage
|
||||
|
|
@ -2164,6 +2176,9 @@ importers:
|
|||
'@manacore/shared-nestjs-auth':
|
||||
specifier: workspace:*
|
||||
version: link:../../../../packages/shared-nestjs-auth
|
||||
'@manacore/shared-nestjs-setup':
|
||||
specifier: workspace:*
|
||||
version: link:../../../../packages/shared-nestjs-setup
|
||||
'@nestjs/common':
|
||||
specifier: ^10.4.15
|
||||
version: 10.4.20(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||
|
|
@ -2981,6 +2996,9 @@ importers:
|
|||
'@manacore/shared-nestjs-auth':
|
||||
specifier: workspace:*
|
||||
version: link:../../../../packages/shared-nestjs-auth
|
||||
'@manacore/shared-nestjs-setup':
|
||||
specifier: workspace:*
|
||||
version: link:../../../../packages/shared-nestjs-setup
|
||||
'@manacore/shared-storage':
|
||||
specifier: workspace:*
|
||||
version: link:../../../../packages/shared-storage
|
||||
|
|
@ -3181,6 +3199,9 @@ importers:
|
|||
'@manacore/shared-nestjs-auth':
|
||||
specifier: workspace:*
|
||||
version: link:../../../../packages/shared-nestjs-auth
|
||||
'@manacore/shared-nestjs-setup':
|
||||
specifier: workspace:*
|
||||
version: link:../../../../packages/shared-nestjs-setup
|
||||
'@nestjs/common':
|
||||
specifier: ^10.4.15
|
||||
version: 10.4.20(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||
|
|
@ -4282,6 +4303,9 @@ importers:
|
|||
'@manacore/shared-nestjs-auth':
|
||||
specifier: workspace:*
|
||||
version: link:../../../../packages/shared-nestjs-auth
|
||||
'@manacore/shared-nestjs-setup':
|
||||
specifier: workspace:*
|
||||
version: link:../../../../packages/shared-nestjs-setup
|
||||
'@nestjs/common':
|
||||
specifier: ^10.4.15
|
||||
version: 10.4.20(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||
|
|
@ -4823,6 +4847,19 @@ importers:
|
|||
specifier: ^5.0.0
|
||||
version: 5.9.3
|
||||
|
||||
packages/shared-nestjs-setup:
|
||||
dependencies:
|
||||
'@nestjs/common':
|
||||
specifier: ^10.0.0 || ^11.0.0
|
||||
version: 10.4.20(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||
'@nestjs/core':
|
||||
specifier: ^10.0.0 || ^11.0.0
|
||||
version: 10.4.20(@nestjs/common@10.4.20(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@10.4.20)(@nestjs/websockets@10.4.20)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.2)
|
||||
devDependencies:
|
||||
typescript:
|
||||
specifier: ^5.0.0
|
||||
version: 5.9.3
|
||||
|
||||
packages/shared-profile-ui:
|
||||
devDependencies:
|
||||
svelte:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue