@lenne.tech/nest-server 11.8.0 → 11.10.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.
- package/dist/config.env.js +5 -0
- package/dist/config.env.js.map +1 -1
- package/dist/core/common/helpers/logging.helper.d.ts +6 -0
- package/dist/core/common/helpers/logging.helper.js +55 -0
- package/dist/core/common/helpers/logging.helper.js.map +1 -0
- package/dist/core/common/interfaces/server-options.interface.d.ts +50 -19
- package/dist/core/modules/auth/guards/roles.guard.js +37 -5
- package/dist/core/modules/auth/guards/roles.guard.js.map +1 -1
- package/dist/core/modules/auth/services/core-auth.service.d.ts +5 -5
- package/dist/core/modules/auth/services/core-auth.service.js +9 -8
- package/dist/core/modules/auth/services/core-auth.service.js.map +1 -1
- package/dist/core/modules/auth/tokens.decorator.d.ts +1 -1
- package/dist/core/modules/better-auth/better-auth.config.js +32 -10
- package/dist/core/modules/better-auth/better-auth.config.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth.resolver.d.ts +16 -16
- package/dist/core/modules/better-auth/better-auth.resolver.js +34 -34
- package/dist/core/modules/better-auth/better-auth.resolver.js.map +1 -1
- package/dist/core/modules/better-auth/better-auth.types.d.ts +2 -1
- package/dist/core/modules/better-auth/better-auth.types.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth-api.middleware.d.ts +10 -0
- package/dist/core/modules/better-auth/core-better-auth-api.middleware.js +91 -0
- package/dist/core/modules/better-auth/core-better-auth-api.middleware.js.map +1 -0
- package/dist/core/modules/better-auth/core-better-auth-auth.model.d.ts +9 -0
- package/dist/core/modules/better-auth/{better-auth-auth.model.js → core-better-auth-auth.model.js} +17 -17
- package/dist/core/modules/better-auth/core-better-auth-auth.model.js.map +1 -0
- package/dist/core/modules/better-auth/{better-auth-migration-status.model.d.ts → core-better-auth-migration-status.model.d.ts} +1 -1
- package/dist/core/modules/better-auth/{better-auth-migration-status.model.js → core-better-auth-migration-status.model.js} +14 -14
- package/dist/core/modules/better-auth/core-better-auth-migration-status.model.js.map +1 -0
- package/dist/core/modules/better-auth/{better-auth-models.d.ts → core-better-auth-models.d.ts} +8 -8
- package/dist/core/modules/better-auth/{better-auth-models.js → core-better-auth-models.js} +61 -61
- package/dist/core/modules/better-auth/core-better-auth-models.js.map +1 -0
- package/dist/core/modules/better-auth/core-better-auth-rate-limit.middleware.d.ts +12 -0
- package/dist/core/modules/better-auth/{better-auth-rate-limit.middleware.js → core-better-auth-rate-limit.middleware.js} +10 -10
- package/dist/core/modules/better-auth/core-better-auth-rate-limit.middleware.js.map +1 -0
- package/dist/core/modules/better-auth/{better-auth-rate-limiter.service.d.ts → core-better-auth-rate-limiter.service.d.ts} +1 -1
- package/dist/core/modules/better-auth/{better-auth-rate-limiter.service.js → core-better-auth-rate-limiter.service.js} +8 -8
- package/dist/core/modules/better-auth/core-better-auth-rate-limiter.service.js.map +1 -0
- package/dist/core/modules/better-auth/{better-auth-user.mapper.d.ts → core-better-auth-user.mapper.d.ts} +1 -1
- package/dist/core/modules/better-auth/{better-auth-user.mapper.js → core-better-auth-user.mapper.js} +10 -9
- package/dist/core/modules/better-auth/core-better-auth-user.mapper.js.map +1 -0
- package/dist/core/modules/better-auth/core-better-auth-web.helper.d.ts +19 -0
- package/dist/core/modules/better-auth/core-better-auth-web.helper.js +152 -0
- package/dist/core/modules/better-auth/core-better-auth-web.helper.js.map +1 -0
- package/dist/core/modules/better-auth/core-better-auth.controller.d.ts +23 -32
- package/dist/core/modules/better-auth/core-better-auth.controller.js +184 -201
- package/dist/core/modules/better-auth/core-better-auth.controller.js.map +1 -1
- package/dist/core/modules/better-auth/core-better-auth.middleware.d.ts +22 -0
- package/dist/core/modules/better-auth/{better-auth.middleware.js → core-better-auth.middleware.js} +45 -18
- package/dist/core/modules/better-auth/core-better-auth.middleware.js.map +1 -0
- package/dist/core/modules/better-auth/{better-auth.module.d.ts → core-better-auth.module.d.ts} +6 -6
- package/dist/core/modules/better-auth/{better-auth.module.js → core-better-auth.module.js} +65 -60
- package/dist/core/modules/better-auth/core-better-auth.module.js.map +1 -0
- package/dist/core/modules/better-auth/core-better-auth.resolver.d.ts +19 -19
- package/dist/core/modules/better-auth/core-better-auth.resolver.js +18 -18
- package/dist/core/modules/better-auth/core-better-auth.resolver.js.map +1 -1
- package/dist/core/modules/better-auth/{better-auth.service.d.ts → core-better-auth.service.d.ts} +3 -2
- package/dist/core/modules/better-auth/{better-auth.service.js → core-better-auth.service.js} +75 -35
- package/dist/core/modules/better-auth/core-better-auth.service.js.map +1 -0
- package/dist/core/modules/better-auth/index.d.ts +11 -9
- package/dist/core/modules/better-auth/index.js +11 -9
- package/dist/core/modules/better-auth/index.js.map +1 -1
- package/dist/core/modules/error-code/core-error-code.controller.d.ts +7 -0
- package/dist/core/modules/error-code/core-error-code.controller.js +45 -0
- package/dist/core/modules/error-code/core-error-code.controller.js.map +1 -0
- package/dist/core/modules/error-code/core-error-code.service.d.ts +16 -0
- package/dist/core/modules/error-code/core-error-code.service.js +65 -0
- package/dist/core/modules/error-code/core-error-code.service.js.map +1 -0
- package/dist/core/modules/error-code/error-code.module.d.ts +7 -0
- package/dist/core/modules/error-code/error-code.module.js +64 -0
- package/dist/core/modules/error-code/error-code.module.js.map +1 -0
- package/dist/core/modules/error-code/error-codes.d.ts +219 -0
- package/dist/core/modules/error-code/error-codes.js +204 -0
- package/dist/core/modules/error-code/error-codes.js.map +1 -0
- package/dist/core/modules/error-code/index.d.ts +5 -0
- package/dist/core/modules/error-code/index.js +22 -0
- package/dist/core/modules/error-code/index.js.map +1 -0
- package/dist/core/modules/error-code/interfaces/error-code.interfaces.d.ts +12 -0
- package/dist/core/modules/error-code/interfaces/error-code.interfaces.js +3 -0
- package/dist/core/modules/error-code/interfaces/error-code.interfaces.js.map +1 -0
- package/dist/core/modules/user/interfaces/core-user-service-options.interface.d.ts +2 -2
- package/dist/core.module.js +14 -6
- package/dist/core.module.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/server/modules/better-auth/better-auth.controller.d.ts +5 -5
- package/dist/server/modules/better-auth/better-auth.controller.js +4 -4
- package/dist/server/modules/better-auth/better-auth.controller.js.map +1 -1
- package/dist/server/modules/better-auth/better-auth.module.js +3 -3
- package/dist/server/modules/better-auth/better-auth.module.js.map +1 -1
- package/dist/server/modules/better-auth/better-auth.resolver.d.ts +17 -17
- package/dist/server/modules/better-auth/better-auth.resolver.js +18 -18
- package/dist/server/modules/better-auth/better-auth.resolver.js.map +1 -1
- package/dist/server/modules/error-code/error-code.controller.d.ts +8 -0
- package/dist/server/modules/error-code/error-code.controller.js +55 -0
- package/dist/server/modules/error-code/error-code.controller.js.map +1 -0
- package/dist/server/modules/error-code/error-code.service.d.ts +4 -0
- package/dist/server/modules/error-code/error-code.service.js +27 -0
- package/dist/server/modules/error-code/error-code.service.js.map +1 -0
- package/dist/server/modules/error-code/error-codes.d.ts +45 -0
- package/dist/server/modules/error-code/error-codes.js +24 -0
- package/dist/server/modules/error-code/error-codes.js.map +1 -0
- package/dist/server/modules/error-code/index.d.ts +3 -0
- package/dist/server/modules/error-code/index.js +20 -0
- package/dist/server/modules/error-code/index.js.map +1 -0
- package/dist/server/modules/user/user.service.d.ts +2 -2
- package/dist/server/modules/user/user.service.js +2 -2
- package/dist/server/modules/user/user.service.js.map +1 -1
- package/dist/server/server.module.js +7 -0
- package/dist/server/server.module.js.map +1 -1
- package/dist/test/test.helper.d.ts +1 -0
- package/dist/test/test.helper.js +5 -1
- package/dist/test/test.helper.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +6 -4
- package/src/config.env.ts +19 -0
- package/src/core/common/helpers/logging.helper.ts +134 -0
- package/src/core/common/interfaces/server-options.interface.ts +511 -237
- package/src/core/modules/auth/guards/roles.guard.ts +49 -7
- package/src/core/modules/auth/services/core-auth.service.ts +9 -8
- package/src/core/modules/better-auth/ARCHITECTURE.md +102 -0
- package/src/core/modules/better-auth/INTEGRATION-CHECKLIST.md +277 -8
- package/src/core/modules/better-auth/README.md +97 -53
- package/src/core/modules/better-auth/better-auth.config.ts +66 -18
- package/src/core/modules/better-auth/better-auth.resolver.ts +32 -32
- package/src/core/modules/better-auth/better-auth.types.ts +3 -2
- package/src/core/modules/better-auth/core-better-auth-api.middleware.ts +134 -0
- package/src/core/modules/better-auth/{better-auth-auth.model.ts → core-better-auth-auth.model.ts} +6 -6
- package/src/core/modules/better-auth/{better-auth-migration-status.model.ts → core-better-auth-migration-status.model.ts} +1 -1
- package/src/core/modules/better-auth/{better-auth-models.ts → core-better-auth-models.ts} +9 -9
- package/src/core/modules/better-auth/{better-auth-rate-limit.middleware.ts → core-better-auth-rate-limit.middleware.ts} +5 -5
- package/src/core/modules/better-auth/{better-auth-rate-limiter.service.ts → core-better-auth-rate-limiter.service.ts} +2 -2
- package/src/core/modules/better-auth/{better-auth-user.mapper.ts → core-better-auth-user.mapper.ts} +4 -3
- package/src/core/modules/better-auth/core-better-auth-web.helper.ts +272 -0
- package/src/core/modules/better-auth/core-better-auth.controller.ts +386 -230
- package/src/core/modules/better-auth/{better-auth.middleware.ts → core-better-auth.middleware.ts} +57 -17
- package/src/core/modules/better-auth/{better-auth.module.ts → core-better-auth.module.ts} +77 -66
- package/src/core/modules/better-auth/core-better-auth.resolver.ts +42 -42
- package/src/core/modules/better-auth/{better-auth.service.ts → core-better-auth.service.ts} +86 -40
- package/src/core/modules/better-auth/index.ts +18 -11
- package/src/core/modules/error-code/INTEGRATION-CHECKLIST.md +291 -0
- package/src/core/modules/error-code/core-error-code.controller.ts +55 -0
- package/src/core/modules/error-code/core-error-code.service.ts +135 -0
- package/src/core/modules/error-code/error-code.module.ts +119 -0
- package/src/core/modules/error-code/error-codes.ts +405 -0
- package/src/core/modules/error-code/index.ts +14 -0
- package/src/core/modules/error-code/interfaces/error-code.interfaces.ts +99 -0
- package/src/core/modules/user/interfaces/core-user-service-options.interface.ts +3 -3
- package/src/core.module.ts +28 -12
- package/src/index.ts +7 -0
- package/src/server/modules/better-auth/better-auth.controller.ts +4 -4
- package/src/server/modules/better-auth/better-auth.module.ts +1 -1
- package/src/server/modules/better-auth/better-auth.resolver.ts +31 -31
- package/src/server/modules/error-code/README.md +131 -0
- package/src/server/modules/error-code/error-code.controller.ts +91 -0
- package/src/server/modules/error-code/error-code.service.ts +42 -0
- package/src/server/modules/error-code/error-codes.ts +65 -0
- package/src/server/modules/error-code/index.ts +8 -0
- package/src/server/modules/user/user.service.ts +2 -2
- package/src/server/server.module.ts +10 -0
- package/src/test/test.helper.ts +13 -1
- package/dist/core/modules/better-auth/better-auth-auth.model.d.ts +0 -9
- package/dist/core/modules/better-auth/better-auth-auth.model.js.map +0 -1
- package/dist/core/modules/better-auth/better-auth-migration-status.model.js.map +0 -1
- package/dist/core/modules/better-auth/better-auth-models.js.map +0 -1
- package/dist/core/modules/better-auth/better-auth-rate-limit.middleware.d.ts +0 -12
- package/dist/core/modules/better-auth/better-auth-rate-limit.middleware.js.map +0 -1
- package/dist/core/modules/better-auth/better-auth-rate-limiter.service.js.map +0 -1
- package/dist/core/modules/better-auth/better-auth-user.mapper.js.map +0 -1
- package/dist/core/modules/better-auth/better-auth.middleware.d.ts +0 -21
- package/dist/core/modules/better-auth/better-auth.middleware.js.map +0 -1
- package/dist/core/modules/better-auth/better-auth.module.js.map +0 -1
- package/dist/core/modules/better-auth/better-auth.service.js.map +0 -1
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
# ErrorCode Integration Checklist
|
|
2
|
+
|
|
3
|
+
**For integrating custom error codes into projects using `@lenne.tech/nest-server`.**
|
|
4
|
+
|
|
5
|
+
> **Estimated time:** 5-10 minutes
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Choose Your Scenario
|
|
10
|
+
|
|
11
|
+
| Scenario | Use When | Configuration | Complexity |
|
|
12
|
+
|----------|----------|---------------|------------|
|
|
13
|
+
| **A. additionalErrorRegistry** | Simple error code addition | Config in `config.env.ts` | Minimal |
|
|
14
|
+
| **B. Custom Service** | Need custom locales or logic | Service inheritance | Low |
|
|
15
|
+
| **C. Custom Controller** | Need custom controller/routes | Service + Controller | Medium |
|
|
16
|
+
|
|
17
|
+
**Recommendation:** Start with **Scenario A**. Only use B or C if you need customization beyond adding error codes.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Reference Implementation
|
|
22
|
+
|
|
23
|
+
All files are available as reference in the package:
|
|
24
|
+
|
|
25
|
+
**Local (in your node_modules):**
|
|
26
|
+
```
|
|
27
|
+
node_modules/@lenne.tech/nest-server/src/server/modules/error-code/
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**GitHub:**
|
|
31
|
+
https://github.com/lenneTech/nest-server/tree/develop/src/server/modules/error-code
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Scenario A: additionalErrorRegistry (Simplest)
|
|
36
|
+
|
|
37
|
+
Use this when you just want to add project-specific error codes.
|
|
38
|
+
|
|
39
|
+
### 1. Define Error Codes
|
|
40
|
+
|
|
41
|
+
**Create:** `src/server/common/errors/project-errors.ts`
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
import { IErrorRegistry, mergeErrorCodes } from '@lenne.tech/nest-server';
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Project-specific error codes
|
|
48
|
+
*
|
|
49
|
+
* Format: PREFIX_XXXX (e.g., PROJ_0001, APP_0001)
|
|
50
|
+
* Use a unique prefix to avoid collisions with LTNS_* core errors.
|
|
51
|
+
*/
|
|
52
|
+
export const ProjectErrors = {
|
|
53
|
+
ORDER_NOT_FOUND: {
|
|
54
|
+
code: 'PROJ_0001',
|
|
55
|
+
message: 'Order not found',
|
|
56
|
+
translations: {
|
|
57
|
+
de: 'Bestellung mit ID {orderId} wurde nicht gefunden.',
|
|
58
|
+
en: 'Order with ID {orderId} was not found.',
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
PAYMENT_FAILED: {
|
|
62
|
+
code: 'PROJ_0002',
|
|
63
|
+
message: 'Payment processing failed',
|
|
64
|
+
translations: {
|
|
65
|
+
de: 'Die Zahlung konnte nicht verarbeitet werden: {reason}',
|
|
66
|
+
en: 'Payment processing failed: {reason}',
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
} as const satisfies IErrorRegistry;
|
|
70
|
+
|
|
71
|
+
// Merged error codes for type-safe factory functions
|
|
72
|
+
export const ErrorCode = mergeErrorCodes(ProjectErrors);
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### 2. Add to config.env.ts
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
import { ProjectErrors } from './server/common/errors/project-errors';
|
|
79
|
+
|
|
80
|
+
const config = {
|
|
81
|
+
// ... other config ...
|
|
82
|
+
errorCode: {
|
|
83
|
+
additionalErrorRegistry: ProjectErrors,
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Done!** Your project errors are now available via `/api/i18n/errors/:locale`.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Scenario B: Custom Service (For Custom Locales)
|
|
93
|
+
|
|
94
|
+
Use this when you need:
|
|
95
|
+
- Additional locales (e.g., French, Spanish)
|
|
96
|
+
- Custom logic in the service
|
|
97
|
+
|
|
98
|
+
### 1. Define Error Codes
|
|
99
|
+
|
|
100
|
+
Same as Scenario A, Step 1.
|
|
101
|
+
|
|
102
|
+
### 2. Create Custom Service
|
|
103
|
+
|
|
104
|
+
**Create:** `src/server/modules/error-code/error-code.service.ts`
|
|
105
|
+
**Copy from:** `node_modules/@lenne.tech/nest-server/src/server/modules/error-code/error-code.service.ts`
|
|
106
|
+
|
|
107
|
+
**Optional customization - add locales:**
|
|
108
|
+
```typescript
|
|
109
|
+
@Injectable()
|
|
110
|
+
export class ErrorCodeService extends CoreErrorCodeService {
|
|
111
|
+
// Override to add more locales
|
|
112
|
+
protected override supportedLocales = ['de', 'en', 'fr', 'es'] as const;
|
|
113
|
+
|
|
114
|
+
constructor() {
|
|
115
|
+
super();
|
|
116
|
+
this.registerErrorRegistry(ProjectErrors);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### 3. Disable Auto-Registration
|
|
122
|
+
|
|
123
|
+
**Update:** `src/config.env.ts`
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
const config = {
|
|
127
|
+
// ... other config ...
|
|
128
|
+
errorCode: {
|
|
129
|
+
autoRegister: false, // Required! Prevents CoreModule from registering its own
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**WHY is `autoRegister: false` required?**
|
|
135
|
+
NestJS @Global() modules use "first wins" for provider registration. Without this, CoreModule's ErrorCodeModule loads first and your custom service is ignored.
|
|
136
|
+
|
|
137
|
+
### 4. Register in ServerModule
|
|
138
|
+
|
|
139
|
+
**Update:** `src/server/server.module.ts`
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
import { ErrorCodeModule as CoreErrorCodeModule } from '@lenne.tech/nest-server';
|
|
143
|
+
import { ErrorCodeService } from './modules/error-code/error-code.service';
|
|
144
|
+
|
|
145
|
+
@Module({
|
|
146
|
+
imports: [
|
|
147
|
+
CoreModule.forRoot(...),
|
|
148
|
+
// Register with custom service
|
|
149
|
+
CoreErrorCodeModule.forRoot({
|
|
150
|
+
service: ErrorCodeService,
|
|
151
|
+
}),
|
|
152
|
+
// ... other modules
|
|
153
|
+
],
|
|
154
|
+
})
|
|
155
|
+
export class ServerModule {}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Scenario C: Custom Controller (For Custom Routes)
|
|
161
|
+
|
|
162
|
+
Use this when you need:
|
|
163
|
+
- Custom controller endpoints (e.g., `/codes` listing)
|
|
164
|
+
- Different route paths
|
|
165
|
+
- Additional REST endpoints
|
|
166
|
+
|
|
167
|
+
**No custom module needed!** Use Core `ErrorCodeModule.forRoot()` with your custom controller and service.
|
|
168
|
+
|
|
169
|
+
### 1. Create Files
|
|
170
|
+
|
|
171
|
+
**Copy from:** `node_modules/@lenne.tech/nest-server/src/server/modules/error-code/`
|
|
172
|
+
|
|
173
|
+
Files needed:
|
|
174
|
+
- `error-codes.ts` - Your error definitions
|
|
175
|
+
- `error-code.service.ts` - Service extending CoreErrorCodeService
|
|
176
|
+
- `error-code.controller.ts` - Controller (**standalone**, not extending)
|
|
177
|
+
- `index.ts` - Exports
|
|
178
|
+
|
|
179
|
+
**No `error-code.module.ts` needed!**
|
|
180
|
+
|
|
181
|
+
### 2. Disable Auto-Registration
|
|
182
|
+
|
|
183
|
+
Same as Scenario B, Step 3.
|
|
184
|
+
|
|
185
|
+
### 3. Register via Core ErrorCodeModule
|
|
186
|
+
|
|
187
|
+
**Update:** `src/server/server.module.ts`
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
import { ErrorCodeModule } from '@lenne.tech/nest-server';
|
|
191
|
+
import { ErrorCodeController } from './modules/error-code/error-code.controller';
|
|
192
|
+
import { ErrorCodeService } from './modules/error-code/error-code.service';
|
|
193
|
+
|
|
194
|
+
@Module({
|
|
195
|
+
imports: [
|
|
196
|
+
CoreModule.forRoot(...),
|
|
197
|
+
// Use Core ErrorCodeModule with custom service and controller
|
|
198
|
+
ErrorCodeModule.forRoot({
|
|
199
|
+
controller: ErrorCodeController,
|
|
200
|
+
service: ErrorCodeService,
|
|
201
|
+
}),
|
|
202
|
+
// ... other modules
|
|
203
|
+
],
|
|
204
|
+
})
|
|
205
|
+
export class ServerModule {}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
**WHY standalone controller instead of extending?**
|
|
209
|
+
NestJS registers routes from parent classes first, regardless of method order in child classes. This causes `:locale` to intercept `/codes`. A standalone controller ensures correct route order: static routes (`/codes`) first, then parameterized routes (`:locale`).
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## Verification Checklist
|
|
214
|
+
|
|
215
|
+
After integration, verify:
|
|
216
|
+
|
|
217
|
+
- [ ] `npm run build` succeeds without errors
|
|
218
|
+
- [ ] `npm test` passes
|
|
219
|
+
- [ ] `GET /api/i18n/errors/de` returns your project error codes
|
|
220
|
+
- [ ] `GET /api/i18n/errors/en` returns English translations
|
|
221
|
+
- [ ] Error codes follow format `PREFIX_XXXX` (e.g., `PROJ_0001`)
|
|
222
|
+
- [ ] Translations include placeholders where needed (`{param}`)
|
|
223
|
+
|
|
224
|
+
### For Scenario C only:
|
|
225
|
+
- [ ] `GET /api/i18n/errors/codes` returns all error codes (if implemented)
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## Common Mistakes
|
|
230
|
+
|
|
231
|
+
| Mistake | Symptom | Fix |
|
|
232
|
+
|---------|---------|-----|
|
|
233
|
+
| Forgot `autoRegister: false` | Project errors not appearing | Add `errorCode: { autoRegister: false }` to config |
|
|
234
|
+
| Wrong error code format | Validation errors | Use `PREFIX_XXXX` format (4 digits) |
|
|
235
|
+
| Missing translations | Runtime errors | Ensure all locales have translations |
|
|
236
|
+
| Controller extends CoreErrorCodeController | `/codes` returns 404 | Use standalone controller |
|
|
237
|
+
| Duplicate error codes | Unpredictable behavior | Ensure unique codes across all registries |
|
|
238
|
+
| Forgot to import module | No error translations | Import ErrorCodeModule in ServerModule |
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## Using Error Codes in Code
|
|
243
|
+
|
|
244
|
+
```typescript
|
|
245
|
+
import { ErrorCode, Errors } from '@lenne.tech/nest-server';
|
|
246
|
+
|
|
247
|
+
// Type-safe error code access
|
|
248
|
+
const code = ErrorCode.userNotFound; // Returns '#LTNS_0001: User not found'
|
|
249
|
+
|
|
250
|
+
// Factory functions with parameters
|
|
251
|
+
throw new BadRequestException(Errors.userNotFound({ email: 'test@example.com' }));
|
|
252
|
+
// Throws: '#LTNS_0001: User with email test@example.com was not found.'
|
|
253
|
+
|
|
254
|
+
// Project-specific errors (after registration)
|
|
255
|
+
import { ErrorCode as ProjectErrorCode } from './common/errors/project-errors';
|
|
256
|
+
|
|
257
|
+
const orderCode = ProjectErrorCode.ORDER_NOT_FOUND; // '#PROJ_0001: Order not found'
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## API Reference
|
|
263
|
+
|
|
264
|
+
### REST Endpoints
|
|
265
|
+
|
|
266
|
+
| Endpoint | Method | Description |
|
|
267
|
+
|----------|--------|-------------|
|
|
268
|
+
| `/api/i18n/errors/:locale` | GET | Get translations for locale (de, en, ...) |
|
|
269
|
+
| `/api/i18n/errors/codes` | GET | Get all error codes (Scenario C only) |
|
|
270
|
+
|
|
271
|
+
### Response Format (Nuxt i18n compatible)
|
|
272
|
+
|
|
273
|
+
```json
|
|
274
|
+
{
|
|
275
|
+
"errors": {
|
|
276
|
+
"LTNS_0001": "Benutzer wurde nicht gefunden.",
|
|
277
|
+
"LTNS_0100": "Sie sind nicht angemeldet.",
|
|
278
|
+
"PROJ_0001": "Bestellung mit ID {orderId} wurde nicht gefunden."
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
> **Note:** Core LTNS_* translations are user-friendly messages without placeholders. Project-specific errors (PROJ_*) may include placeholders like `{orderId}` if defined in your `ProjectErrors` registry.
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
## Detailed Documentation
|
|
288
|
+
|
|
289
|
+
For complete API reference and advanced topics:
|
|
290
|
+
- **Core Error Codes:** `node_modules/@lenne.tech/nest-server/src/core/modules/error-code/error-codes.ts`
|
|
291
|
+
- **Interfaces:** `node_modules/@lenne.tech/nest-server/src/core/modules/error-code/interfaces/error-code.interfaces.ts`
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Controller, Get, NotFoundException, Param } from '@nestjs/common';
|
|
2
|
+
|
|
3
|
+
import { Roles } from '../../common/decorators/roles.decorator';
|
|
4
|
+
import { RoleEnum } from '../../common/enums/role.enum';
|
|
5
|
+
import { CoreErrorCodeService } from './core-error-code.service';
|
|
6
|
+
import { IErrorTranslationResponse, SupportedLocale } from './interfaces/error-code.interfaces';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Core Error Code Controller
|
|
10
|
+
*
|
|
11
|
+
* Provides REST endpoints for error translations.
|
|
12
|
+
* This controller is publicly accessible (no authentication required).
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* GET /api/i18n/errors/de - Get German translations
|
|
16
|
+
* GET /api/i18n/errors/en - Get English translations
|
|
17
|
+
*/
|
|
18
|
+
@Controller('api/i18n/errors')
|
|
19
|
+
export class CoreErrorCodeController {
|
|
20
|
+
constructor(protected readonly errorCodeService: CoreErrorCodeService) {}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Get error translations for a specific locale
|
|
24
|
+
*
|
|
25
|
+
* Returns all error codes with their translations in Nuxt i18n compatible format.
|
|
26
|
+
*
|
|
27
|
+
* @param locale - Locale code (e.g., 'de', 'en')
|
|
28
|
+
* @returns Translations object
|
|
29
|
+
* @throws NotFoundException if locale is not supported
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* Response:
|
|
33
|
+
* ```json
|
|
34
|
+
* {
|
|
35
|
+
* "errors": {
|
|
36
|
+
* "LTNS_0001": "Benutzer wurde nicht gefunden.",
|
|
37
|
+
* "LTNS_0002": "Das eingegebene Passwort ist ungültig.",
|
|
38
|
+
* "LTNS_0100": "Sie sind nicht angemeldet."
|
|
39
|
+
* }
|
|
40
|
+
* }
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
@Get(':locale')
|
|
44
|
+
@Roles(RoleEnum.S_EVERYONE)
|
|
45
|
+
getTranslations(@Param('locale') locale: string): IErrorTranslationResponse {
|
|
46
|
+
if (!this.errorCodeService.isLocaleSupported(locale)) {
|
|
47
|
+
throw new NotFoundException(
|
|
48
|
+
`Locale "${locale}" is not supported. ` +
|
|
49
|
+
`Supported locales: ${this.errorCodeService.getSupportedLocales().join(', ')}`,
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return this.errorCodeService.getTranslations(locale as SupportedLocale);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
|
|
3
|
+
import { getAllErrorDefinitions, IErrorRegistry } from './error-codes';
|
|
4
|
+
import { SupportedLocale } from './interfaces/error-code.interfaces';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Core Error Code Service
|
|
8
|
+
*
|
|
9
|
+
* Serves error code translations from the structured ErrorRegistry.
|
|
10
|
+
* Translations are defined in error-codes.ts as Single Source of Truth.
|
|
11
|
+
*
|
|
12
|
+
* Projects can extend this service to add custom error registries.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* // In consuming project:
|
|
17
|
+
* import { CoreErrorCodeService, IErrorRegistry } from '@lenne.tech/nest-server';
|
|
18
|
+
*
|
|
19
|
+
* const ProjectErrors = {
|
|
20
|
+
* ORDER_NOT_FOUND: {
|
|
21
|
+
* code: 'PROJ_0001',
|
|
22
|
+
* message: 'Order not found',
|
|
23
|
+
* translations: { de: 'Bestellung nicht gefunden.', en: 'Order not found.' }
|
|
24
|
+
* }
|
|
25
|
+
* } as const satisfies IErrorRegistry;
|
|
26
|
+
*
|
|
27
|
+
* @Injectable()
|
|
28
|
+
* export class ErrorCodeService extends CoreErrorCodeService {
|
|
29
|
+
* constructor() {
|
|
30
|
+
* super();
|
|
31
|
+
* this.registerErrorRegistry(ProjectErrors);
|
|
32
|
+
* }
|
|
33
|
+
* }
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
@Injectable()
|
|
37
|
+
export class CoreErrorCodeService {
|
|
38
|
+
/**
|
|
39
|
+
* Supported locales
|
|
40
|
+
*/
|
|
41
|
+
protected supportedLocales: SupportedLocale[] = ['de', 'en'];
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Cached translations per locale
|
|
45
|
+
*/
|
|
46
|
+
protected translations: Map<SupportedLocale, Record<string, string>> = new Map();
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Registered error registries
|
|
50
|
+
*/
|
|
51
|
+
protected registries: IErrorRegistry[] = [];
|
|
52
|
+
|
|
53
|
+
constructor() {
|
|
54
|
+
// Initialize with core errors
|
|
55
|
+
this.registerErrorRegistry(getAllErrorDefinitions());
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Register an error registry and generate translations
|
|
60
|
+
*
|
|
61
|
+
* @param registry - Error registry to register
|
|
62
|
+
*/
|
|
63
|
+
registerErrorRegistry(registry: IErrorRegistry): void {
|
|
64
|
+
this.registries.push(registry);
|
|
65
|
+
this.generateTranslationsFromRegistry(registry);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Generate translations from error registry
|
|
70
|
+
*
|
|
71
|
+
* @param registry - Error registry to extract translations from
|
|
72
|
+
*/
|
|
73
|
+
protected generateTranslationsFromRegistry(registry: IErrorRegistry): void {
|
|
74
|
+
for (const [, definition] of Object.entries(registry)) {
|
|
75
|
+
const { code, translations: defTranslations } = definition;
|
|
76
|
+
|
|
77
|
+
for (const locale of this.supportedLocales) {
|
|
78
|
+
const translation = defTranslations[locale];
|
|
79
|
+
if (translation) {
|
|
80
|
+
const existing = this.translations.get(locale) || {};
|
|
81
|
+
this.translations.set(locale, { ...existing, [code]: translation });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Check if a locale is supported
|
|
89
|
+
*
|
|
90
|
+
* @param locale - Locale to check
|
|
91
|
+
* @returns True if locale is supported
|
|
92
|
+
*/
|
|
93
|
+
isLocaleSupported(locale: string): locale is SupportedLocale {
|
|
94
|
+
return this.supportedLocales.includes(locale as SupportedLocale);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Get supported locales
|
|
99
|
+
*
|
|
100
|
+
* @returns Array of supported locales
|
|
101
|
+
*/
|
|
102
|
+
getSupportedLocales(): SupportedLocale[] {
|
|
103
|
+
return [...this.supportedLocales];
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Get all translations for a locale
|
|
108
|
+
*
|
|
109
|
+
* @param locale - Locale code (e.g., 'de', 'en')
|
|
110
|
+
* @returns Translations object wrapped in { errors: ... } for Nuxt i18n compatibility
|
|
111
|
+
* @throws Error if locale is not supported
|
|
112
|
+
*/
|
|
113
|
+
getTranslations(locale: SupportedLocale): { errors: Record<string, string> } {
|
|
114
|
+
if (!this.isLocaleSupported(locale)) {
|
|
115
|
+
throw new Error(`Locale "${locale}" is not supported. Supported: ${this.supportedLocales.join(', ')}`);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return { errors: this.translations.get(locale) || {} };
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Get all error codes
|
|
123
|
+
*
|
|
124
|
+
* @returns Array of error codes from all registries
|
|
125
|
+
*/
|
|
126
|
+
getErrorCodes(): string[] {
|
|
127
|
+
const codes = new Set<string>();
|
|
128
|
+
for (const translations of this.translations.values()) {
|
|
129
|
+
for (const code of Object.keys(translations)) {
|
|
130
|
+
codes.add(code);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return Array.from(codes).sort();
|
|
134
|
+
}
|
|
135
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { DynamicModule, Global, Module, Type } from '@nestjs/common';
|
|
2
|
+
|
|
3
|
+
import { CoreErrorCodeController } from './core-error-code.controller';
|
|
4
|
+
import { CoreErrorCodeService } from './core-error-code.service';
|
|
5
|
+
import { IErrorCodeModuleConfig } from './interfaces/error-code.interfaces';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Error Code Module
|
|
9
|
+
*
|
|
10
|
+
* Provides error code translations via REST endpoint.
|
|
11
|
+
* Translations are defined in the error registry (Single Source of Truth).
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* // Basic usage (auto-register in CoreModule)
|
|
16
|
+
* // No explicit import needed - included in CoreModule
|
|
17
|
+
*
|
|
18
|
+
* // Extended usage (with custom error registry - RECOMMENDED)
|
|
19
|
+
* const ProjectErrors = {
|
|
20
|
+
* ORDER_NOT_FOUND: {
|
|
21
|
+
* code: 'PROJ_0001',
|
|
22
|
+
* message: 'Order not found',
|
|
23
|
+
* translations: { de: 'Bestellung nicht gefunden.', en: 'Order not found.' }
|
|
24
|
+
* }
|
|
25
|
+
* } as const satisfies IErrorRegistry;
|
|
26
|
+
*
|
|
27
|
+
* ErrorCodeModule.forRoot({ additionalErrorRegistry: ProjectErrors })
|
|
28
|
+
*
|
|
29
|
+
* // Extended usage (with custom controller and service)
|
|
30
|
+
* ErrorCodeModule.forRoot({
|
|
31
|
+
* additionalErrorRegistry: ProjectErrors,
|
|
32
|
+
* controller: ErrorCodeController,
|
|
33
|
+
* service: ErrorCodeService,
|
|
34
|
+
* })
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
@Global()
|
|
38
|
+
@Module({
|
|
39
|
+
// IMPORTANT: Controllers are NOT registered here - they are registered via forRoot()
|
|
40
|
+
// This prevents duplicate controller registration when using custom controllers,
|
|
41
|
+
// which would cause route conflicts (e.g., :locale intercepting /codes)
|
|
42
|
+
exports: [CoreErrorCodeService],
|
|
43
|
+
providers: [CoreErrorCodeService],
|
|
44
|
+
})
|
|
45
|
+
export class ErrorCodeModule {
|
|
46
|
+
/**
|
|
47
|
+
* Gets the controller class to use (custom or default)
|
|
48
|
+
*/
|
|
49
|
+
private static getControllerClass(config?: IErrorCodeModuleConfig): Type<any> {
|
|
50
|
+
return config?.controller || CoreErrorCodeController;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Gets the service class to use (custom or default)
|
|
55
|
+
*/
|
|
56
|
+
private static getServiceClass(config?: IErrorCodeModuleConfig): Type<CoreErrorCodeService> {
|
|
57
|
+
return config?.service || CoreErrorCodeService;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Register the module with configuration
|
|
62
|
+
*
|
|
63
|
+
* Supports the following patterns:
|
|
64
|
+
* 1. **No config**: Uses CoreErrorCodeService and CoreErrorCodeController with core errors only
|
|
65
|
+
* 2. **additionalErrorRegistry only**: Adds project errors to core errors
|
|
66
|
+
* 3. **service only**: Uses custom service class (should register its own errors in constructor)
|
|
67
|
+
* 4. **controller only**: Uses custom controller class with CoreErrorCodeService
|
|
68
|
+
* 5. **Full config**: Uses custom service and controller
|
|
69
|
+
*
|
|
70
|
+
* @param config - Module configuration
|
|
71
|
+
* @returns Dynamic module
|
|
72
|
+
*/
|
|
73
|
+
static forRoot(config?: IErrorCodeModuleConfig): DynamicModule {
|
|
74
|
+
const ControllerClass = this.getControllerClass(config);
|
|
75
|
+
const ServiceClass = this.getServiceClass(config);
|
|
76
|
+
|
|
77
|
+
// Build providers array
|
|
78
|
+
const providers: any[] = [];
|
|
79
|
+
|
|
80
|
+
if (config?.service) {
|
|
81
|
+
// If a custom service is provided, register it under both tokens:
|
|
82
|
+
// 1. Its own class (for direct injection in custom controllers)
|
|
83
|
+
// 2. CoreErrorCodeService (for backward compatibility)
|
|
84
|
+
providers.push(ServiceClass);
|
|
85
|
+
providers.push({
|
|
86
|
+
provide: CoreErrorCodeService,
|
|
87
|
+
useExisting: ServiceClass,
|
|
88
|
+
});
|
|
89
|
+
} else {
|
|
90
|
+
// Use factory to register additional errors
|
|
91
|
+
providers.push({
|
|
92
|
+
provide: CoreErrorCodeService,
|
|
93
|
+
useFactory: () => {
|
|
94
|
+
const service = new CoreErrorCodeService();
|
|
95
|
+
|
|
96
|
+
// Add additional error registry
|
|
97
|
+
if (config?.additionalErrorRegistry) {
|
|
98
|
+
service.registerErrorRegistry(config.additionalErrorRegistry);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return service;
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Export both the base class and custom service class (if provided)
|
|
107
|
+
const exports: any[] = [CoreErrorCodeService];
|
|
108
|
+
if (config?.service && ServiceClass !== CoreErrorCodeService) {
|
|
109
|
+
exports.push(ServiceClass);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return {
|
|
113
|
+
controllers: [ControllerClass],
|
|
114
|
+
exports,
|
|
115
|
+
module: ErrorCodeModule,
|
|
116
|
+
providers,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
}
|