@lenne.tech/nest-server 11.21.3 → 11.22.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/.claude/rules/architecture.md +79 -0
- package/.claude/rules/better-auth.md +262 -0
- package/.claude/rules/configurable-features.md +308 -0
- package/.claude/rules/core-modules.md +205 -0
- package/.claude/rules/migration-guides.md +149 -0
- package/.claude/rules/module-deprecation.md +214 -0
- package/.claude/rules/module-inheritance.md +97 -0
- package/.claude/rules/package-management.md +112 -0
- package/.claude/rules/role-system.md +146 -0
- package/.claude/rules/testing.md +120 -0
- package/.claude/rules/versioning.md +53 -0
- package/CLAUDE.md +172 -0
- package/dist/core/common/interfaces/server-options.interface.d.ts +10 -0
- package/dist/core/modules/error-code/error-code.module.js.map +1 -1
- package/dist/core.module.d.ts +3 -3
- package/dist/core.module.js +17 -4
- package/dist/core.module.js.map +1 -1
- package/dist/server/server.module.js +6 -6
- package/dist/server/server.module.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/docs/REQUEST-LIFECYCLE.md +1256 -0
- package/docs/error-codes.md +446 -0
- package/migration-guides/11.10.x-to-11.11.x.md +266 -0
- package/migration-guides/11.11.x-to-11.12.x.md +323 -0
- package/migration-guides/11.12.x-to-11.13.0.md +612 -0
- package/migration-guides/11.13.x-to-11.14.0.md +348 -0
- package/migration-guides/11.14.x-to-11.15.0.md +262 -0
- package/migration-guides/11.15.0-to-11.15.3.md +118 -0
- package/migration-guides/11.15.x-to-11.16.0.md +497 -0
- package/migration-guides/11.16.x-to-11.17.0.md +130 -0
- package/migration-guides/11.17.x-to-11.18.0.md +393 -0
- package/migration-guides/11.18.x-to-11.19.0.md +151 -0
- package/migration-guides/11.19.x-to-11.20.0.md +170 -0
- package/migration-guides/11.20.x-to-11.21.0.md +216 -0
- package/migration-guides/11.21.0-to-11.21.1.md +194 -0
- package/migration-guides/11.21.1-to-11.21.2.md +114 -0
- package/migration-guides/11.21.2-to-11.21.3.md +175 -0
- package/migration-guides/11.21.x-to-11.22.0.md +224 -0
- package/migration-guides/11.3.x-to-11.4.x.md +233 -0
- package/migration-guides/11.6.x-to-11.7.x.md +394 -0
- package/migration-guides/11.7.x-to-11.8.x.md +318 -0
- package/migration-guides/11.8.x-to-11.9.x.md +322 -0
- package/migration-guides/11.9.x-to-11.10.x.md +571 -0
- package/migration-guides/TEMPLATE.md +113 -0
- package/package.json +8 -3
- package/src/core/common/interfaces/server-options.interface.ts +83 -16
- package/src/core/modules/better-auth/CUSTOMIZATION.md +24 -17
- package/src/core/modules/better-auth/INTEGRATION-CHECKLIST.md +5 -5
- package/src/core/modules/error-code/INTEGRATION-CHECKLIST.md +42 -12
- package/src/core/modules/error-code/error-code.module.ts +4 -9
- package/src/core.module.ts +52 -10
- package/src/server/server.module.ts +7 -9
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lenne.tech/nest-server",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.22.0",
|
|
4
4
|
"description": "Modern, fast, powerful Node.js web framework in TypeScript based on Nest with a GraphQL API and a connection to MongoDB (or other databases).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"node",
|
|
@@ -168,7 +168,11 @@
|
|
|
168
168
|
"files": [
|
|
169
169
|
"dist/**/*",
|
|
170
170
|
"src/**/*",
|
|
171
|
-
"bin/**/*"
|
|
171
|
+
"bin/**/*",
|
|
172
|
+
"CLAUDE.md",
|
|
173
|
+
".claude/rules/**/*",
|
|
174
|
+
"docs/**/*",
|
|
175
|
+
"migration-guides/**/*"
|
|
172
176
|
],
|
|
173
177
|
"watch": {
|
|
174
178
|
"build:dev": "src"
|
|
@@ -191,7 +195,8 @@
|
|
|
191
195
|
"picomatch@>=4.0.0 <4.0.4": "4.0.4",
|
|
192
196
|
"path-to-regexp@>=8.0.0 <8.4.0": "8.4.1",
|
|
193
197
|
"kysely@>=0.26.0 <0.28.15": "0.28.15",
|
|
194
|
-
"lodash@>=4.0.0 <4.18.0": "4.18.1"
|
|
198
|
+
"lodash@>=4.0.0 <4.18.0": "4.18.1",
|
|
199
|
+
"defu@<=6.1.4": "6.1.6"
|
|
195
200
|
},
|
|
196
201
|
"onlyBuiltDependencies": [
|
|
197
202
|
"bcrypt",
|
|
@@ -2117,16 +2117,12 @@ interface IBetterAuthBase {
|
|
|
2117
2117
|
* Custom controller class to use instead of the default CoreBetterAuthController.
|
|
2118
2118
|
* The class should extend CoreBetterAuthController.
|
|
2119
2119
|
*
|
|
2120
|
-
*
|
|
2121
|
-
* a separate module. Use this with CoreModule.forRoot(envConfig) (IAM-only mode).
|
|
2122
|
-
*
|
|
2123
|
-
* @example
|
|
2120
|
+
* @deprecated Since 11.22.0 — Use the `overrides` parameter on `CoreModule.forRoot()` instead:
|
|
2124
2121
|
* ```typescript
|
|
2125
|
-
*
|
|
2126
|
-
* betterAuth: {
|
|
2127
|
-
* controller: IamController,
|
|
2128
|
-
* }
|
|
2122
|
+
* CoreModule.forRoot(envConfig, { betterAuth: { controller: IamController } })
|
|
2129
2123
|
* ```
|
|
2124
|
+
* This separates class references from environment configuration. The config field
|
|
2125
|
+
* still works for backward compatibility but `overrides` takes precedence.
|
|
2130
2126
|
*
|
|
2131
2127
|
* @since 11.14.0
|
|
2132
2128
|
*/
|
|
@@ -2342,16 +2338,12 @@ interface IBetterAuthBase {
|
|
|
2342
2338
|
* Custom resolver class to use instead of the default DefaultBetterAuthResolver.
|
|
2343
2339
|
* The class should extend CoreBetterAuthResolver.
|
|
2344
2340
|
*
|
|
2345
|
-
*
|
|
2346
|
-
* a separate module. Use this with CoreModule.forRoot(envConfig) (IAM-only mode).
|
|
2347
|
-
*
|
|
2348
|
-
* @example
|
|
2341
|
+
* @deprecated Since 11.22.0 — Use the `overrides` parameter on `CoreModule.forRoot()` instead:
|
|
2349
2342
|
* ```typescript
|
|
2350
|
-
*
|
|
2351
|
-
* betterAuth: {
|
|
2352
|
-
* resolver: IamResolver,
|
|
2353
|
-
* }
|
|
2343
|
+
* CoreModule.forRoot(envConfig, { betterAuth: { resolver: IamResolver } })
|
|
2354
2344
|
* ```
|
|
2345
|
+
* This separates class references from environment configuration. The config field
|
|
2346
|
+
* still works for backward compatibility but `overrides` takes precedence.
|
|
2355
2347
|
*
|
|
2356
2348
|
* @since 11.14.0
|
|
2357
2349
|
*/
|
|
@@ -2663,3 +2655,78 @@ interface IBetterAuthWithPasskey extends IBetterAuthBase {
|
|
|
2663
2655
|
*/
|
|
2664
2656
|
trustedOrigins: string[];
|
|
2665
2657
|
}
|
|
2658
|
+
|
|
2659
|
+
/**
|
|
2660
|
+
* Override default implementations of core module components.
|
|
2661
|
+
*
|
|
2662
|
+
* Use this as the second parameter of `CoreModule.forRoot()` to replace
|
|
2663
|
+
* default controllers, resolvers, or services with project-specific implementations.
|
|
2664
|
+
*
|
|
2665
|
+
* This keeps class references (code) separate from environment configuration (strings/numbers)
|
|
2666
|
+
* and ensures each module's `forRoot()` is called exactly once — preventing duplicate
|
|
2667
|
+
* controller registration.
|
|
2668
|
+
*
|
|
2669
|
+
* Each core module that supports customization has a typed entry here.
|
|
2670
|
+
* Only specified components are overridden — unset fields use defaults.
|
|
2671
|
+
*
|
|
2672
|
+
* @example
|
|
2673
|
+
* ```typescript
|
|
2674
|
+
* // IAM-only mode with overrides
|
|
2675
|
+
* CoreModule.forRoot(envConfig, {
|
|
2676
|
+
* errorCode: { controller: ErrorCodeController, service: ErrorCodeService },
|
|
2677
|
+
* betterAuth: { resolver: BetterAuthResolver },
|
|
2678
|
+
* })
|
|
2679
|
+
*
|
|
2680
|
+
* // Legacy mode with overrides
|
|
2681
|
+
* CoreModule.forRoot(CoreAuthService, AuthModule.forRoot(envConfig.jwt), envConfig, {
|
|
2682
|
+
* errorCode: { controller: ErrorCodeController, service: ErrorCodeService },
|
|
2683
|
+
* betterAuth: { controller: BetterAuthController, resolver: BetterAuthResolver },
|
|
2684
|
+
* })
|
|
2685
|
+
* ```
|
|
2686
|
+
*
|
|
2687
|
+
* @since 11.22.0
|
|
2688
|
+
*/
|
|
2689
|
+
export interface ICoreModuleOverrides {
|
|
2690
|
+
/**
|
|
2691
|
+
* Override BetterAuth controller and/or resolver.
|
|
2692
|
+
*
|
|
2693
|
+
* The custom controller must extend `CoreBetterAuthController`.
|
|
2694
|
+
* The custom resolver must extend `CoreBetterAuthResolver` and re-declare
|
|
2695
|
+
* all GraphQL decorators (`@Mutation`, `@Query`, `@Roles`).
|
|
2696
|
+
*
|
|
2697
|
+
* @example
|
|
2698
|
+
* ```typescript
|
|
2699
|
+
* {
|
|
2700
|
+
* betterAuth: {
|
|
2701
|
+
* controller: BetterAuthController,
|
|
2702
|
+
* resolver: BetterAuthResolver,
|
|
2703
|
+
* },
|
|
2704
|
+
* }
|
|
2705
|
+
* ```
|
|
2706
|
+
*/
|
|
2707
|
+
betterAuth?: {
|
|
2708
|
+
controller?: Type<any>;
|
|
2709
|
+
resolver?: Type<any>;
|
|
2710
|
+
};
|
|
2711
|
+
|
|
2712
|
+
/**
|
|
2713
|
+
* Override ErrorCode controller and/or service.
|
|
2714
|
+
*
|
|
2715
|
+
* The custom controller can be standalone (recommended) or extend `CoreErrorCodeController`.
|
|
2716
|
+
* The custom service must extend `CoreErrorCodeService`.
|
|
2717
|
+
*
|
|
2718
|
+
* @example
|
|
2719
|
+
* ```typescript
|
|
2720
|
+
* {
|
|
2721
|
+
* errorCode: {
|
|
2722
|
+
* controller: ErrorCodeController,
|
|
2723
|
+
* service: ErrorCodeService,
|
|
2724
|
+
* },
|
|
2725
|
+
* }
|
|
2726
|
+
* ```
|
|
2727
|
+
*/
|
|
2728
|
+
errorCode?: {
|
|
2729
|
+
controller?: Type<any>;
|
|
2730
|
+
service?: Type<any>;
|
|
2731
|
+
};
|
|
2732
|
+
}
|
|
@@ -41,29 +41,23 @@ export class ServerModule {}
|
|
|
41
41
|
- Default `CoreBetterAuthController` and `DefaultBetterAuthResolver` are registered
|
|
42
42
|
- No additional configuration needed
|
|
43
43
|
|
|
44
|
-
### Pattern 2:
|
|
44
|
+
### Pattern 2: Overrides Parameter (Recommended for Customization)
|
|
45
45
|
|
|
46
46
|
**Use when:** Need custom Controller or Resolver, but don't need a separate module.
|
|
47
47
|
|
|
48
|
-
```typescript
|
|
49
|
-
// config.env.ts
|
|
50
|
-
import { IamController } from './server/modules/iam/iam.controller';
|
|
51
|
-
import { IamResolver } from './server/modules/iam/iam.resolver';
|
|
52
|
-
|
|
53
|
-
const config = {
|
|
54
|
-
betterAuth: {
|
|
55
|
-
controller: IamController, // Custom controller class
|
|
56
|
-
resolver: IamResolver, // Custom resolver class
|
|
57
|
-
// ... other betterAuth config
|
|
58
|
-
},
|
|
59
|
-
};
|
|
60
|
-
```
|
|
61
|
-
|
|
62
48
|
```typescript
|
|
63
49
|
// server.module.ts
|
|
50
|
+
import { IamController } from './modules/iam/iam.controller';
|
|
51
|
+
import { IamResolver } from './modules/iam/iam.resolver';
|
|
52
|
+
|
|
64
53
|
@Module({
|
|
65
54
|
imports: [
|
|
66
|
-
CoreModule.forRoot(envConfig
|
|
55
|
+
CoreModule.forRoot(envConfig, {
|
|
56
|
+
betterAuth: {
|
|
57
|
+
controller: IamController,
|
|
58
|
+
resolver: IamResolver,
|
|
59
|
+
},
|
|
60
|
+
}),
|
|
67
61
|
],
|
|
68
62
|
})
|
|
69
63
|
export class ServerModule {}
|
|
@@ -71,9 +65,22 @@ export class ServerModule {}
|
|
|
71
65
|
|
|
72
66
|
**What happens:**
|
|
73
67
|
|
|
74
|
-
- CoreModule passes
|
|
68
|
+
- CoreModule passes overrides to `CoreBetterAuthModule.forRoot()`
|
|
75
69
|
- Your custom classes are registered instead of defaults
|
|
76
70
|
- Single registration point, no duplicate imports
|
|
71
|
+
- Class references stay separate from environment config
|
|
72
|
+
|
|
73
|
+
**Alternative:** Set `controller`/`resolver` directly in config (backward compatible):
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
// config.env.ts — still works but overrides parameter is preferred
|
|
77
|
+
const config = {
|
|
78
|
+
betterAuth: {
|
|
79
|
+
controller: IamController,
|
|
80
|
+
resolver: IamResolver,
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
```
|
|
77
84
|
|
|
78
85
|
### Pattern 3: Separate Module (autoRegister: false)
|
|
79
86
|
|
|
@@ -23,11 +23,11 @@
|
|
|
23
23
|
|
|
24
24
|
### Registration Patterns (Quick Reference)
|
|
25
25
|
|
|
26
|
-
| Pattern
|
|
27
|
-
|
|
|
28
|
-
| **Zero-Config**
|
|
29
|
-
| **
|
|
30
|
-
| **Separate Module**
|
|
26
|
+
| Pattern | Use When | Configuration |
|
|
27
|
+
| --------------------------- | ---------------------------------- | --------------------------------------------------------------------------------------------- |
|
|
28
|
+
| **Zero-Config** | No customization needed | Just use `CoreModule.forRoot(envConfig)` |
|
|
29
|
+
| **Overrides** (recommended) | Custom Controller/Resolver | Pass `overrides` to `CoreModule.forRoot(envConfig, { betterAuth: { controller, resolver } })` |
|
|
30
|
+
| **Separate Module** | Full control, additional providers | Set `autoRegister: false` in config |
|
|
31
31
|
|
|
32
32
|
**Details:** See [CUSTOMIZATION.md](./CUSTOMIZATION.md#module-registration-patterns)
|
|
33
33
|
|
|
@@ -141,16 +141,15 @@ NestJS @Global() modules use "first wins" for provider registration. Without thi
|
|
|
141
141
|
|
|
142
142
|
**Update:** `src/server/server.module.ts`
|
|
143
143
|
|
|
144
|
+
Use the `overrides` parameter of `CoreModule.forRoot()` (recommended since v11.22.0):
|
|
145
|
+
|
|
144
146
|
```typescript
|
|
145
|
-
import { ErrorCodeModule as CoreErrorCodeModule } from '@lenne.tech/nest-server';
|
|
146
147
|
import { ErrorCodeService } from './modules/error-code/error-code.service';
|
|
147
148
|
|
|
148
149
|
@Module({
|
|
149
150
|
imports: [
|
|
150
|
-
CoreModule.forRoot(
|
|
151
|
-
|
|
152
|
-
CoreErrorCodeModule.forRoot({
|
|
153
|
-
service: ErrorCodeService,
|
|
151
|
+
CoreModule.forRoot(envConfig, {
|
|
152
|
+
errorCode: { service: ErrorCodeService },
|
|
154
153
|
}),
|
|
155
154
|
// ... other modules
|
|
156
155
|
],
|
|
@@ -158,6 +157,22 @@ import { ErrorCodeService } from './modules/error-code/error-code.service';
|
|
|
158
157
|
export class ServerModule {}
|
|
159
158
|
```
|
|
160
159
|
|
|
160
|
+
**Alternative** (for complex setups): disable auto-registration and import separately:
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
import { ErrorCodeModule as CoreErrorCodeModule } from '@lenne.tech/nest-server';
|
|
164
|
+
import { ErrorCodeService } from './modules/error-code/error-code.service';
|
|
165
|
+
|
|
166
|
+
@Module({
|
|
167
|
+
imports: [
|
|
168
|
+
CoreModule.forRoot({ ...envConfig, errorCode: { autoRegister: false } }),
|
|
169
|
+
CoreErrorCodeModule.forRoot({ service: ErrorCodeService }),
|
|
170
|
+
// ... other modules
|
|
171
|
+
],
|
|
172
|
+
})
|
|
173
|
+
export class ServerModule {}
|
|
174
|
+
```
|
|
175
|
+
|
|
161
176
|
---
|
|
162
177
|
|
|
163
178
|
## Scenario C: Custom Controller (For Custom Routes)
|
|
@@ -168,7 +183,7 @@ Use this when you need:
|
|
|
168
183
|
- Different route paths
|
|
169
184
|
- Additional REST endpoints
|
|
170
185
|
|
|
171
|
-
**No custom module needed!** Use
|
|
186
|
+
**No custom module needed!** Use the `overrides` parameter of `CoreModule.forRoot()`.
|
|
172
187
|
|
|
173
188
|
### 1. Create Files
|
|
174
189
|
|
|
@@ -183,13 +198,29 @@ Files needed:
|
|
|
183
198
|
|
|
184
199
|
**No `error-code.module.ts` needed!**
|
|
185
200
|
|
|
186
|
-
### 2.
|
|
201
|
+
### 2. Register via CoreModule.forRoot() Overrides (Recommended)
|
|
187
202
|
|
|
188
|
-
|
|
203
|
+
**Update:** `src/server/server.module.ts`
|
|
189
204
|
|
|
190
|
-
|
|
205
|
+
```typescript
|
|
206
|
+
import { ErrorCodeController } from './modules/error-code/error-code.controller';
|
|
207
|
+
import { ErrorCodeService } from './modules/error-code/error-code.service';
|
|
191
208
|
|
|
192
|
-
|
|
209
|
+
@Module({
|
|
210
|
+
imports: [
|
|
211
|
+
CoreModule.forRoot(envConfig, {
|
|
212
|
+
errorCode: {
|
|
213
|
+
controller: ErrorCodeController,
|
|
214
|
+
service: ErrorCodeService,
|
|
215
|
+
},
|
|
216
|
+
}),
|
|
217
|
+
// ... other modules
|
|
218
|
+
],
|
|
219
|
+
})
|
|
220
|
+
export class ServerModule {}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
**Alternative** (for complex setups): disable auto-registration and import separately:
|
|
193
224
|
|
|
194
225
|
```typescript
|
|
195
226
|
import { ErrorCodeModule } from '@lenne.tech/nest-server';
|
|
@@ -198,8 +229,7 @@ import { ErrorCodeService } from './modules/error-code/error-code.service';
|
|
|
198
229
|
|
|
199
230
|
@Module({
|
|
200
231
|
imports: [
|
|
201
|
-
CoreModule.forRoot(...),
|
|
202
|
-
// Use Core ErrorCodeModule with custom service and controller
|
|
232
|
+
CoreModule.forRoot({ ...envConfig, errorCode: { autoRegister: false } }),
|
|
203
233
|
ErrorCodeModule.forRoot({
|
|
204
234
|
controller: ErrorCodeController,
|
|
205
235
|
service: ErrorCodeService,
|
|
@@ -12,8 +12,10 @@ import { IErrorCodeModuleConfig } from './interfaces/error-code.interfaces';
|
|
|
12
12
|
*
|
|
13
13
|
* @example
|
|
14
14
|
* ```typescript
|
|
15
|
-
* // Basic usage (auto-register in CoreModule)
|
|
16
|
-
*
|
|
15
|
+
* // Basic usage (auto-register in CoreModule via overrides)
|
|
16
|
+
* CoreModule.forRoot(envConfig, {
|
|
17
|
+
* errorCode: { controller: ErrorCodeController, service: ErrorCodeService },
|
|
18
|
+
* })
|
|
17
19
|
*
|
|
18
20
|
* // Extended usage (with custom error registry - RECOMMENDED)
|
|
19
21
|
* const ProjectErrors = {
|
|
@@ -25,13 +27,6 @@ import { IErrorCodeModuleConfig } from './interfaces/error-code.interfaces';
|
|
|
25
27
|
* } as const satisfies IErrorRegistry;
|
|
26
28
|
*
|
|
27
29
|
* 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
30
|
* ```
|
|
36
31
|
*/
|
|
37
32
|
@Global()
|
package/src/core.module.ts
CHANGED
|
@@ -12,7 +12,7 @@ import { CheckResponseInterceptor } from './core/common/interceptors/check-respo
|
|
|
12
12
|
import { CheckSecurityInterceptor } from './core/common/interceptors/check-security.interceptor';
|
|
13
13
|
import { ResponseModelInterceptor } from './core/common/interceptors/response-model.interceptor';
|
|
14
14
|
import { TranslateResponseInterceptor } from './core/common/interceptors/translate-response.interceptor';
|
|
15
|
-
import { IServerOptions } from './core/common/interfaces/server-options.interface';
|
|
15
|
+
import { ICoreModuleOverrides, IServerOptions } from './core/common/interfaces/server-options.interface';
|
|
16
16
|
import { RequestContextMiddleware } from './core/common/middleware/request-context.middleware';
|
|
17
17
|
import { MapAndValidatePipe } from './core/common/pipes/map-and-validate.pipe';
|
|
18
18
|
import { ComplexityPlugin } from './core/common/plugins/complexity.plugin';
|
|
@@ -95,6 +95,12 @@ export class CoreModule implements NestModule {
|
|
|
95
95
|
*
|
|
96
96
|
* ```typescript
|
|
97
97
|
* CoreModule.forRoot(envConfig)
|
|
98
|
+
*
|
|
99
|
+
* // With module overrides (custom controllers/resolvers/services)
|
|
100
|
+
* CoreModule.forRoot(envConfig, {
|
|
101
|
+
* errorCode: { controller: ErrorCodeController, service: ErrorCodeService },
|
|
102
|
+
* betterAuth: { resolver: BetterAuthResolver },
|
|
103
|
+
* })
|
|
98
104
|
* ```
|
|
99
105
|
*
|
|
100
106
|
* Use this for new projects that only use BetterAuth (IAM) for authentication.
|
|
@@ -109,6 +115,11 @@ export class CoreModule implements NestModule {
|
|
|
109
115
|
*
|
|
110
116
|
* ```typescript
|
|
111
117
|
* CoreModule.forRoot(CoreAuthService, AuthModule.forRoot(envConfig.jwt), envConfig)
|
|
118
|
+
*
|
|
119
|
+
* // With module overrides
|
|
120
|
+
* CoreModule.forRoot(CoreAuthService, AuthModule.forRoot(envConfig.jwt), envConfig, {
|
|
121
|
+
* errorCode: { controller: ErrorCodeController, service: ErrorCodeService },
|
|
122
|
+
* })
|
|
112
123
|
* ```
|
|
113
124
|
*
|
|
114
125
|
* @deprecated This 3-parameter signature is deprecated for new projects.
|
|
@@ -127,22 +138,36 @@ export class CoreModule implements NestModule {
|
|
|
127
138
|
*
|
|
128
139
|
* @see https://github.com/lenneTech/nest-server/blob/develop/.claude/rules/module-deprecation.md
|
|
129
140
|
*/
|
|
130
|
-
static forRoot(options: Partial<IServerOptions
|
|
141
|
+
static forRoot(options: Partial<IServerOptions>, overrides?: ICoreModuleOverrides): DynamicModule;
|
|
131
142
|
/**
|
|
132
143
|
* @deprecated Use the single-parameter signature `CoreModule.forRoot(envConfig)` for new projects.
|
|
133
144
|
* This 3-parameter signature is for existing projects during migration to IAM.
|
|
134
145
|
*/
|
|
135
|
-
static forRoot(
|
|
146
|
+
static forRoot(
|
|
147
|
+
AuthService: any,
|
|
148
|
+
AuthModule: any,
|
|
149
|
+
options: Partial<IServerOptions>,
|
|
150
|
+
overrides?: ICoreModuleOverrides,
|
|
151
|
+
): DynamicModule;
|
|
136
152
|
static forRoot(
|
|
137
153
|
authServiceOrOptions: any,
|
|
138
154
|
authModuleOrUndefined?: any,
|
|
139
155
|
optionsOrUndefined?: Partial<IServerOptions>,
|
|
156
|
+
overridesOrUndefined?: ICoreModuleOverrides,
|
|
140
157
|
): DynamicModule {
|
|
141
|
-
// Detect which signature was used
|
|
142
|
-
|
|
158
|
+
// Detect which signature was used:
|
|
159
|
+
// IAM-only: forRoot(config, overrides?) — first arg is a plain object (config)
|
|
160
|
+
// Legacy: forRoot(AuthService, AuthModule, config, overrides?) — first arg is a class (function)
|
|
161
|
+
const isIamOnlyMode = typeof authServiceOrOptions !== 'function';
|
|
143
162
|
const AuthService = isIamOnlyMode ? null : authServiceOrOptions;
|
|
144
163
|
const AuthModule = isIamOnlyMode ? null : authModuleOrUndefined;
|
|
145
164
|
const options: Partial<IServerOptions> = isIamOnlyMode ? authServiceOrOptions : optionsOrUndefined;
|
|
165
|
+
// For IAM-only mode: overrides is the 2nd param; for legacy mode: it's the 4th param.
|
|
166
|
+
// The cast is safe: the public overloads guarantee the 2nd arg is ICoreModuleOverrides | undefined
|
|
167
|
+
// in IAM-only mode (typeof first arg !== 'function'), never a DynamicModule (AuthModule).
|
|
168
|
+
const overrides: ICoreModuleOverrides | undefined = isIamOnlyMode
|
|
169
|
+
? (authModuleOrUndefined as ICoreModuleOverrides | undefined)
|
|
170
|
+
: overridesOrUndefined;
|
|
146
171
|
|
|
147
172
|
// Process config
|
|
148
173
|
let cors = {};
|
|
@@ -316,11 +341,21 @@ export class CoreModule implements NestModule {
|
|
|
316
341
|
const errorCodeConfig = config.errorCode;
|
|
317
342
|
const isErrorCodeAutoRegister = errorCodeConfig?.autoRegister !== false;
|
|
318
343
|
|
|
344
|
+
if (!isErrorCodeAutoRegister && (overrides?.errorCode?.controller || overrides?.errorCode?.service)) {
|
|
345
|
+
console.warn(
|
|
346
|
+
'CoreModule: errorCode overrides are ignored because errorCode.autoRegister is false. ' +
|
|
347
|
+
'Either remove autoRegister: false or pass controller/service to your own ErrorCodeModule.forRoot() call.',
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
|
|
319
351
|
if (isErrorCodeAutoRegister) {
|
|
320
352
|
// Always use forRoot() - it registers the controller and handles configuration
|
|
353
|
+
// Overrides take precedence over config for controller/service
|
|
321
354
|
imports.push(
|
|
322
355
|
ErrorCodeModule.forRoot({
|
|
323
356
|
additionalErrorRegistry: errorCodeConfig?.additionalErrorRegistry,
|
|
357
|
+
controller: overrides?.errorCode?.controller,
|
|
358
|
+
service: overrides?.errorCode?.service,
|
|
324
359
|
}),
|
|
325
360
|
);
|
|
326
361
|
}
|
|
@@ -357,24 +392,31 @@ export class CoreModule implements NestModule {
|
|
|
357
392
|
// autoRegister: false means the project imports its own BetterAuthModule separately
|
|
358
393
|
const isAutoRegisterDisabled = typeof betterAuthConfig === 'object' && betterAuthConfig?.autoRegister === false;
|
|
359
394
|
|
|
360
|
-
// Extract custom controller/resolver
|
|
395
|
+
// Extract custom controller/resolver: overrides take precedence over config fields
|
|
361
396
|
const configController = typeof betterAuthConfig === 'object' ? betterAuthConfig?.controller : undefined;
|
|
362
397
|
const configResolver = typeof betterAuthConfig === 'object' ? betterAuthConfig?.resolver : undefined;
|
|
363
398
|
|
|
399
|
+
if (isAutoRegisterDisabled && (overrides?.betterAuth?.controller || overrides?.betterAuth?.resolver)) {
|
|
400
|
+
console.warn(
|
|
401
|
+
'CoreModule: betterAuth overrides are ignored because betterAuth.autoRegister is false. ' +
|
|
402
|
+
'Either remove autoRegister: false or pass controller/resolver to your own BetterAuthModule.forRoot() call.',
|
|
403
|
+
);
|
|
404
|
+
}
|
|
405
|
+
|
|
364
406
|
if (isBetterAuthEnabled) {
|
|
365
407
|
if ((isIamOnlyMode && !isAutoRegisterDisabled) || isAutoRegister) {
|
|
366
408
|
imports.push(
|
|
367
409
|
CoreBetterAuthModule.forRoot({
|
|
368
410
|
config: betterAuthConfig === true ? {} : betterAuthConfig || {},
|
|
369
|
-
//
|
|
370
|
-
controller: configController,
|
|
411
|
+
// Overrides take precedence over config fields (backward compatible)
|
|
412
|
+
controller: overrides?.betterAuth?.controller || configController,
|
|
371
413
|
// Pass JWT secrets for backwards compatibility fallback
|
|
372
414
|
fallbackSecrets: [config.jwt?.secret, config.jwt?.refresh?.secret],
|
|
373
415
|
// In IAM-only mode, register RolesGuard globally to enforce @Roles() decorators
|
|
374
416
|
// In Legacy mode (autoRegister), RolesGuard is already registered via CoreAuthModule
|
|
375
417
|
registerRolesGuardGlobally: isIamOnlyMode,
|
|
376
|
-
//
|
|
377
|
-
resolver: configResolver,
|
|
418
|
+
// Overrides take precedence over config fields (backward compatible)
|
|
419
|
+
resolver: overrides?.betterAuth?.resolver || configResolver,
|
|
378
420
|
// Pass server-level URLs for Passkey auto-detection
|
|
379
421
|
// When env: 'local', defaults are: baseUrl=localhost:3000, appUrl=localhost:3001
|
|
380
422
|
serverAppUrl: config.appUrl,
|
|
@@ -7,7 +7,6 @@ import { Any } from '../core/common/scalars/any.scalar';
|
|
|
7
7
|
import { DateScalar } from '../core/common/scalars/date.scalar';
|
|
8
8
|
import { JSON } from '../core/common/scalars/json.scalar';
|
|
9
9
|
import { CoreAuthService } from '../core/modules/auth/services/core-auth.service';
|
|
10
|
-
import { ErrorCodeModule } from '../core/modules/error-code/error-code.module';
|
|
11
10
|
import { TusModule } from '../core/modules/tus';
|
|
12
11
|
import { CronJobs } from './common/services/cron-jobs.service';
|
|
13
12
|
import { AuthController } from './modules/auth/auth.controller';
|
|
@@ -35,7 +34,13 @@ import { ServerController } from './server.controller';
|
|
|
35
34
|
imports: [
|
|
36
35
|
// Include CoreModule for standard processes
|
|
37
36
|
// Note: BetterAuthModule is imported manually below (autoRegister defaults to false)
|
|
38
|
-
CoreModule
|
|
37
|
+
// ErrorCodeModule is auto-registered by CoreModule with overrides for custom controller/service
|
|
38
|
+
CoreModule.forRoot(CoreAuthService, AuthModule.forRoot(envConfig.jwt), envConfig, {
|
|
39
|
+
errorCode: {
|
|
40
|
+
controller: ErrorCodeController,
|
|
41
|
+
service: ErrorCodeService,
|
|
42
|
+
},
|
|
43
|
+
}),
|
|
39
44
|
|
|
40
45
|
// Include cron job handling
|
|
41
46
|
ScheduleModule.forRoot(),
|
|
@@ -49,13 +54,6 @@ import { ServerController } from './server.controller';
|
|
|
49
54
|
// This allows project-specific customization via BetterAuthResolver
|
|
50
55
|
BetterAuthModule.forRoot({}),
|
|
51
56
|
|
|
52
|
-
// Include ErrorCodeModule with project-specific error codes
|
|
53
|
-
// Uses Core ErrorCodeModule.forRoot() with custom service and controller
|
|
54
|
-
ErrorCodeModule.forRoot({
|
|
55
|
-
controller: ErrorCodeController,
|
|
56
|
-
service: ErrorCodeService,
|
|
57
|
-
}),
|
|
58
|
-
|
|
59
57
|
// Include FileModule for file handling
|
|
60
58
|
FileModule,
|
|
61
59
|
|