@noxfly/noxus 3.0.0-dev.0 → 3.0.0-dev.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +132 -16
- package/dist/child.d.mts +118 -4
- package/dist/child.d.ts +118 -4
- package/dist/child.js +402 -859
- package/dist/child.js.map +1 -0
- package/dist/child.mjs +389 -847
- package/dist/child.mjs.map +1 -0
- package/dist/main.d.mts +517 -25
- package/dist/main.d.ts +517 -25
- package/dist/main.js +1088 -988
- package/dist/main.js.map +1 -0
- package/dist/main.mjs +983 -884
- package/dist/main.mjs.map +1 -0
- package/dist/preload.d.mts +28 -0
- package/dist/preload.d.ts +28 -0
- package/dist/preload.js +95 -0
- package/dist/preload.js.map +1 -0
- package/dist/preload.mjs +70 -0
- package/dist/preload.mjs.map +1 -0
- package/dist/renderer.d.mts +186 -23
- package/dist/renderer.d.ts +186 -23
- package/dist/renderer.js +170 -170
- package/dist/renderer.js.map +1 -0
- package/dist/renderer.mjs +159 -157
- package/dist/renderer.mjs.map +1 -0
- package/package.json +35 -21
- package/.editorconfig +0 -16
- package/.github/copilot-instructions.md +0 -32
- package/.vscode/settings.json +0 -3
- package/eslint.config.js +0 -109
- package/scripts/postbuild.js +0 -31
- package/src/DI/app-injector.ts +0 -151
- package/src/DI/injector-explorer.ts +0 -143
- package/src/DI/token.ts +0 -53
- package/src/app.ts +0 -217
- package/src/bootstrap.ts +0 -108
- package/src/decorators/controller.decorator.ts +0 -58
- package/src/decorators/guards.decorator.ts +0 -15
- package/src/decorators/injectable.decorator.ts +0 -81
- package/src/decorators/method.decorator.ts +0 -66
- package/src/decorators/middleware.decorator.ts +0 -15
- package/src/exceptions.ts +0 -57
- package/src/index.ts +0 -13
- package/src/main.ts +0 -26
- package/src/non-electron-process.ts +0 -22
- package/src/preload-bridge.ts +0 -75
- package/src/renderer-client.ts +0 -338
- package/src/renderer-events.ts +0 -110
- package/src/request.ts +0 -97
- package/src/router.ts +0 -353
- package/src/routes.ts +0 -78
- package/src/socket.ts +0 -73
- package/src/utils/forward-ref.ts +0 -31
- package/src/utils/logger.ts +0 -430
- package/src/utils/radix-tree.ts +0 -210
- package/src/utils/types.ts +0 -21
- package/src/window/window-manager.ts +0 -255
- package/tsconfig.json +0 -29
- package/tsup.config.ts +0 -34
package/README.md
CHANGED
|
@@ -120,19 +120,30 @@ export class AppService implements IApp {
|
|
|
120
120
|
}
|
|
121
121
|
```
|
|
122
122
|
|
|
123
|
-
### 4.
|
|
123
|
+
### 4. Define routes
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
// routes.ts
|
|
127
|
+
import { defineRoutes } from '@noxfly/noxus/main';
|
|
128
|
+
|
|
129
|
+
export const routes = defineRoutes([
|
|
130
|
+
{ path: 'users', load: () => import('./controllers/user.controller.js') },
|
|
131
|
+
{ path: 'orders', load: () => import('./controllers/order.controller.js') },
|
|
132
|
+
]);
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### 5. Bootstrap the application
|
|
124
136
|
|
|
125
137
|
```ts
|
|
126
138
|
// main.ts
|
|
127
139
|
import { bootstrapApplication } from '@noxfly/noxus/main';
|
|
128
140
|
import { AppService } from './app.service';
|
|
141
|
+
import { routes } from './routes';
|
|
129
142
|
|
|
130
|
-
const noxApp = await bootstrapApplication();
|
|
143
|
+
const noxApp = await bootstrapApplication({ routes });
|
|
131
144
|
|
|
132
145
|
noxApp
|
|
133
146
|
.configure(AppService)
|
|
134
|
-
.lazy('users', () => import('./controllers/user.controller.js'))
|
|
135
|
-
.lazy('orders', () => import('./controllers/order.controller.js'))
|
|
136
147
|
.start();
|
|
137
148
|
```
|
|
138
149
|
|
|
@@ -195,6 +206,9 @@ import { inject } from '@noxfly/noxus/main';
|
|
|
195
206
|
const userService = inject(UserService);
|
|
196
207
|
```
|
|
197
208
|
|
|
209
|
+
When you decide to inject manually with `inject()`, you may not duplicate the dependency in the `deps` array of `@Injectable`.
|
|
210
|
+
The resolve dependency in deps will be ignored in the constructor and will be re-solved at runtime by `inject()`.
|
|
211
|
+
|
|
198
212
|
Useful outside a constructor — in callbacks, factories, etc.
|
|
199
213
|
|
|
200
214
|
### `forwardRef()` — Circular dependencies
|
|
@@ -238,6 +252,21 @@ getProduct(req: Request) {
|
|
|
238
252
|
}
|
|
239
253
|
```
|
|
240
254
|
|
|
255
|
+
### Query parameters
|
|
256
|
+
|
|
257
|
+
```ts
|
|
258
|
+
// Renderer side:
|
|
259
|
+
await client.request({ method: 'GET', path: 'users/list', query: { role: 'admin', page: '1' } });
|
|
260
|
+
|
|
261
|
+
// Controller side:
|
|
262
|
+
@Get('list')
|
|
263
|
+
list(req: Request) {
|
|
264
|
+
const role = req.query['role']; // 'admin'
|
|
265
|
+
const page = req.query['page']; // '1'
|
|
266
|
+
return this.svc.findAll({ role, page: parseInt(page!) });
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
241
270
|
### Request body
|
|
242
271
|
|
|
243
272
|
```ts
|
|
@@ -261,10 +290,43 @@ create(req: Request, res: IResponse) {
|
|
|
261
290
|
|
|
262
291
|
---
|
|
263
292
|
|
|
293
|
+
## Route definitions (`defineRoutes`)
|
|
294
|
+
|
|
295
|
+
`defineRoutes` is the single source of truth for your routing table. It validates prefixes, detects duplicates and overlapping paths, and supports nested routes:
|
|
296
|
+
|
|
297
|
+
```ts
|
|
298
|
+
import { defineRoutes } from '@noxfly/noxus/main';
|
|
299
|
+
|
|
300
|
+
export const routes = defineRoutes([
|
|
301
|
+
{ path: 'users', load: () => import('./modules/users/users.controller.js'), guards: [authGuard] },
|
|
302
|
+
{ path: 'orders', load: () => import('./modules/orders/orders.controller.js') },
|
|
303
|
+
]);
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### Nested routes
|
|
307
|
+
|
|
308
|
+
Parent routes can omit `load` and only serve as a shared prefix with inherited guards/middlewares:
|
|
309
|
+
|
|
310
|
+
```ts
|
|
311
|
+
export const routes = defineRoutes([
|
|
312
|
+
{
|
|
313
|
+
path: 'admin',
|
|
314
|
+
guards: [authGuard, adminGuard],
|
|
315
|
+
children: [
|
|
316
|
+
{ path: 'users', load: () => import('./admin/users.controller.js') },
|
|
317
|
+
{ path: 'products', load: () => import('./admin/products.controller.js') },
|
|
318
|
+
],
|
|
319
|
+
},
|
|
320
|
+
]);
|
|
321
|
+
// Produces flat routes: admin/users and admin/products, both inheriting authGuard + adminGuard.
|
|
322
|
+
```
|
|
323
|
+
|
|
264
324
|
## Lazy loading
|
|
265
325
|
|
|
266
326
|
This is the core mechanism for keeping startup fast. A lazy controller is never imported until an IPC request targets its prefix.
|
|
267
327
|
|
|
328
|
+
Routes declared via `defineRoutes` are lazy by default. You can also register lazy routes manually:
|
|
329
|
+
|
|
268
330
|
```ts
|
|
269
331
|
noxApp
|
|
270
332
|
.lazy('users', () => import('./modules/users/users.controller.js'))
|
|
@@ -451,26 +513,35 @@ class UserRepository {
|
|
|
451
513
|
|
|
452
514
|
```ts
|
|
453
515
|
// preload.ts
|
|
454
|
-
import {
|
|
516
|
+
import { exposeNoxusBridge } from '@noxfly/noxus/preload';
|
|
455
517
|
|
|
456
|
-
|
|
518
|
+
exposeNoxusBridge(); // exposes window.__noxus__ to the renderer
|
|
457
519
|
```
|
|
458
520
|
|
|
459
521
|
### IPC client
|
|
460
522
|
|
|
461
523
|
```ts
|
|
462
524
|
// In the renderer (Angular, React, Vue, Vanilla...)
|
|
463
|
-
import {
|
|
525
|
+
import { NoxRendererClient } from '@noxfly/noxus';
|
|
464
526
|
|
|
465
|
-
const client = new
|
|
466
|
-
|
|
527
|
+
const client = new NoxRendererClient({
|
|
528
|
+
requestTimeout: 10_000, // 10s (default). Set to 0 to disable.
|
|
529
|
+
});
|
|
530
|
+
await client.setup(); // requests the MessagePort from main
|
|
467
531
|
|
|
468
532
|
// Requests
|
|
469
|
-
const users
|
|
470
|
-
const user
|
|
471
|
-
await client.
|
|
472
|
-
await client.
|
|
473
|
-
await client.
|
|
533
|
+
const users = await client.request<User[]>({ method: 'GET', path: 'users/list' });
|
|
534
|
+
const user = await client.request<User> ({ method: 'GET', path: 'users/42' });
|
|
535
|
+
await client.request({ method: 'GET', path: 'users/list', query: { role: 'admin' } });
|
|
536
|
+
await client.request({ method: 'POST', path: 'users/create', body: { name: 'Bob' } });
|
|
537
|
+
await client.request({ method: 'PUT', path: 'users/42', body: { name: 'Bob Updated' } });
|
|
538
|
+
await client.request({ method: 'DELETE', path: 'users/42' });
|
|
539
|
+
|
|
540
|
+
// Per-request timeout override (takes precedence over the global requestTimeout)
|
|
541
|
+
const report = await client.request<Report>(
|
|
542
|
+
{ method: 'GET', path: 'reports/heavy' },
|
|
543
|
+
{ timeout: 60_000 }, // 60s for this specific request
|
|
544
|
+
);
|
|
474
545
|
```
|
|
475
546
|
|
|
476
547
|
### Push events (main → renderer)
|
|
@@ -495,9 +566,12 @@ class NotificationService {
|
|
|
495
566
|
On the renderer side:
|
|
496
567
|
|
|
497
568
|
```ts
|
|
498
|
-
client.
|
|
569
|
+
const sub = client.events.subscribe<INotification>('notification', (payload) => {
|
|
499
570
|
console.log(payload.message);
|
|
500
571
|
});
|
|
572
|
+
|
|
573
|
+
// Unsubscribe when done
|
|
574
|
+
sub.unsubscribe();
|
|
501
575
|
```
|
|
502
576
|
|
|
503
577
|
---
|
|
@@ -508,7 +582,7 @@ Multiple IPC requests in a single round-trip:
|
|
|
508
582
|
|
|
509
583
|
```ts
|
|
510
584
|
const results = await client.batch([
|
|
511
|
-
{ method: 'GET', path: 'users/list' },
|
|
585
|
+
{ method: 'GET', path: 'users/list', query: { role: 'admin' } },
|
|
512
586
|
{ method: 'GET', path: 'products/list' },
|
|
513
587
|
{ method: 'POST', path: 'orders/create', body: { ... } },
|
|
514
588
|
]);
|
|
@@ -568,3 +642,45 @@ src/
|
|
|
568
642
|
```
|
|
569
643
|
|
|
570
644
|
Each `module/` folder is **self-contained** — the controller imports its own services directly, with no central declaration. `main.ts` only knows the lazy loading paths.
|
|
645
|
+
|
|
646
|
+
---
|
|
647
|
+
|
|
648
|
+
## Log level
|
|
649
|
+
|
|
650
|
+
By default, all framework logs are enabled (`debug` level). Control verbosity via `bootstrapApplication`:
|
|
651
|
+
|
|
652
|
+
```ts
|
|
653
|
+
const noxApp = await bootstrapApplication({
|
|
654
|
+
logLevel: 'none', // 'debug' | 'info' | 'none'
|
|
655
|
+
});
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
You can also pass an array of specific levels:
|
|
659
|
+
|
|
660
|
+
```ts
|
|
661
|
+
bootstrapApplication({ logLevel: ['warn', 'error', 'critical'] });
|
|
662
|
+
```
|
|
663
|
+
|
|
664
|
+
Or change it at runtime:
|
|
665
|
+
|
|
666
|
+
```ts
|
|
667
|
+
import { Logger } from '@noxfly/noxus/main';
|
|
668
|
+
|
|
669
|
+
Logger.setLogLevel('info');
|
|
670
|
+
```
|
|
671
|
+
|
|
672
|
+
---
|
|
673
|
+
|
|
674
|
+
## Testing
|
|
675
|
+
|
|
676
|
+
To reset the DI container between tests (avoids leaking singletons across test suites):
|
|
677
|
+
|
|
678
|
+
```ts
|
|
679
|
+
import { resetRootInjector } from '@noxfly/noxus/main';
|
|
680
|
+
|
|
681
|
+
afterEach(() => {
|
|
682
|
+
resetRootInjector();
|
|
683
|
+
});
|
|
684
|
+
```
|
|
685
|
+
|
|
686
|
+
This clears all bindings, singletons, and scoped instances from the root injector.
|
package/dist/child.d.mts
CHANGED
|
@@ -1,11 +1,125 @@
|
|
|
1
|
-
import { L as Lifetime, a as TokenKey } from './app-injector-Bz3Upc0y.mjs';
|
|
2
|
-
export { A as AppInjector, F as ForwardRefFn, b as ForwardReference, I as IBinding, M as MaybeAsync, R as RootInjector, c as Token, T as Type, f as forwardRef, i as inject } from './app-injector-Bz3Upc0y.mjs';
|
|
3
|
-
|
|
4
1
|
/**
|
|
5
2
|
* @copyright 2025 NoxFly
|
|
6
3
|
* @license MIT
|
|
7
4
|
* @author NoxFly
|
|
8
5
|
*/
|
|
6
|
+
interface Type<T> extends Function {
|
|
7
|
+
new (...args: any[]): T;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Represents a generic type that can be either a value or a promise resolving to that value.
|
|
11
|
+
*/
|
|
12
|
+
type MaybeAsync<T> = T | Promise<T>;
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* A function that returns a type.
|
|
17
|
+
* Used for forward references to types that are not yet defined.
|
|
18
|
+
*/
|
|
19
|
+
interface ForwardRefFn<T = any> {
|
|
20
|
+
(): Type<T>;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* A wrapper class for forward referenced types.
|
|
24
|
+
*/
|
|
25
|
+
declare class ForwardReference<T = any> {
|
|
26
|
+
readonly forwardRefFn: ForwardRefFn<T>;
|
|
27
|
+
constructor(forwardRefFn: ForwardRefFn<T>);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Creates a forward reference to a type.
|
|
31
|
+
* @param fn A function that returns the type.
|
|
32
|
+
* @returns A ForwardReference instance.
|
|
33
|
+
*/
|
|
34
|
+
declare function forwardRef<T = any>(fn: ForwardRefFn<T>): ForwardReference<T>;
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* A DI token uniquely identifies a dependency.
|
|
39
|
+
* It can wrap a class (Type<T>) or be a named symbol token.
|
|
40
|
+
*
|
|
41
|
+
* Using tokens instead of reflect-metadata means dependencies are
|
|
42
|
+
* declared explicitly — no magic type inference, no emitDecoratorMetadata.
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* // Class token (most common)
|
|
46
|
+
* const MY_SERVICE = token(MyService);
|
|
47
|
+
*
|
|
48
|
+
* // Named symbol token (for interfaces or non-class values)
|
|
49
|
+
* const DB_URL = token<string>('DB_URL');
|
|
50
|
+
*/
|
|
51
|
+
declare class Token<T> {
|
|
52
|
+
readonly target: Type<T> | string;
|
|
53
|
+
readonly description: string;
|
|
54
|
+
constructor(target: Type<T> | string);
|
|
55
|
+
toString(): string;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* The key used to look up a class token in the registry.
|
|
59
|
+
* For class tokens, the key is the class constructor itself.
|
|
60
|
+
* For named tokens, the key is the Token instance.
|
|
61
|
+
*/
|
|
62
|
+
type TokenKey<T = unknown> = Type<T> | Token<T>;
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Lifetime of a binding in the DI container.
|
|
67
|
+
* - singleton: created once, shared for the lifetime of the app.
|
|
68
|
+
* - scope: created once per request scope.
|
|
69
|
+
* - transient: new instance every time it is resolved.
|
|
70
|
+
*/
|
|
71
|
+
type Lifetime = 'singleton' | 'scope' | 'transient';
|
|
72
|
+
/**
|
|
73
|
+
* Internal representation of a registered binding.
|
|
74
|
+
*/
|
|
75
|
+
interface IBinding<T = unknown> {
|
|
76
|
+
lifetime: Lifetime;
|
|
77
|
+
implementation: Type<T>;
|
|
78
|
+
/** Explicit constructor dependencies, declared by the class itself. */
|
|
79
|
+
deps: ReadonlyArray<TokenKey>;
|
|
80
|
+
instance?: T;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* AppInjector is the core DI container.
|
|
84
|
+
* It no longer uses reflect-metadata — all dependency information
|
|
85
|
+
* comes from explicitly declared `deps` arrays on each binding.
|
|
86
|
+
*/
|
|
87
|
+
declare class AppInjector {
|
|
88
|
+
readonly name: string | null;
|
|
89
|
+
readonly bindings: Map<Type<unknown> | Token<unknown>, IBinding<unknown>>;
|
|
90
|
+
readonly singletons: Map<Type<unknown> | Token<unknown>, unknown>;
|
|
91
|
+
readonly scoped: Map<Type<unknown> | Token<unknown>, unknown>;
|
|
92
|
+
constructor(name?: string | null);
|
|
93
|
+
/**
|
|
94
|
+
* Creates a child scope for per-request lifetime resolution.
|
|
95
|
+
*/
|
|
96
|
+
createScope(): AppInjector;
|
|
97
|
+
/**
|
|
98
|
+
* Registers a binding explicitly.
|
|
99
|
+
*/
|
|
100
|
+
register<T>(key: TokenKey<T>, implementation: Type<T>, lifetime: Lifetime, deps?: ReadonlyArray<TokenKey>): void;
|
|
101
|
+
/**
|
|
102
|
+
* Resolves a dependency by token or class reference.
|
|
103
|
+
*/
|
|
104
|
+
resolve<T>(target: TokenKey<T> | ForwardReference<T>): T;
|
|
105
|
+
private _resolveForwardRef;
|
|
106
|
+
private _instantiate;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* The global root injector. All singletons live here.
|
|
110
|
+
*/
|
|
111
|
+
declare const RootInjector: AppInjector;
|
|
112
|
+
/**
|
|
113
|
+
* Resets the root injector to a clean state.
|
|
114
|
+
* **Intended for testing only** — clears all bindings, singletons, and scoped instances
|
|
115
|
+
* so that each test can start from a fresh DI container without restarting the process.
|
|
116
|
+
*/
|
|
117
|
+
declare function resetRootInjector(): void;
|
|
118
|
+
/**
|
|
119
|
+
* Convenience function: resolve a token from the root injector.
|
|
120
|
+
*/
|
|
121
|
+
declare function inject<T>(t: TokenKey<T> | ForwardReference<T>): T;
|
|
122
|
+
|
|
9
123
|
declare class ResponseException extends Error {
|
|
10
124
|
readonly status: number;
|
|
11
125
|
constructor(message?: string);
|
|
@@ -232,4 +346,4 @@ declare namespace Logger {
|
|
|
232
346
|
};
|
|
233
347
|
}
|
|
234
348
|
|
|
235
|
-
export { BadGatewayException, BadRequestException, ConflictException, ForbiddenException, GatewayTimeoutException, HttpVersionNotSupportedException, Injectable, type InjectableOptions, InsufficientStorageException, InternalServerException, Lifetime, type LogLevel, Logger, LoopDetectedException, MethodNotAllowedException, NetworkAuthenticationRequiredException, NetworkConnectTimeoutException, NotAcceptableException, NotExtendedException, NotFoundException, NotImplementedException, PaymentRequiredException, RequestTimeoutException, ResponseException, ServiceUnavailableException, TokenKey, TooManyRequestsException, UnauthorizedException, UpgradeRequiredException, VariantAlsoNegotiatesException };
|
|
349
|
+
export { AppInjector, BadGatewayException, BadRequestException, ConflictException, ForbiddenException, type ForwardRefFn, ForwardReference, GatewayTimeoutException, HttpVersionNotSupportedException, type IBinding, Injectable, type InjectableOptions, InsufficientStorageException, InternalServerException, type Lifetime, type LogLevel, Logger, LoopDetectedException, type MaybeAsync, MethodNotAllowedException, NetworkAuthenticationRequiredException, NetworkConnectTimeoutException, NotAcceptableException, NotExtendedException, NotFoundException, NotImplementedException, PaymentRequiredException, RequestTimeoutException, ResponseException, RootInjector, ServiceUnavailableException, Token, type TokenKey, TooManyRequestsException, type Type, UnauthorizedException, UpgradeRequiredException, VariantAlsoNegotiatesException, forwardRef, inject, resetRootInjector };
|
package/dist/child.d.ts
CHANGED
|
@@ -1,11 +1,125 @@
|
|
|
1
|
-
import { L as Lifetime, a as TokenKey } from './app-injector-Bz3Upc0y.js';
|
|
2
|
-
export { A as AppInjector, F as ForwardRefFn, b as ForwardReference, I as IBinding, M as MaybeAsync, R as RootInjector, c as Token, T as Type, f as forwardRef, i as inject } from './app-injector-Bz3Upc0y.js';
|
|
3
|
-
|
|
4
1
|
/**
|
|
5
2
|
* @copyright 2025 NoxFly
|
|
6
3
|
* @license MIT
|
|
7
4
|
* @author NoxFly
|
|
8
5
|
*/
|
|
6
|
+
interface Type<T> extends Function {
|
|
7
|
+
new (...args: any[]): T;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Represents a generic type that can be either a value or a promise resolving to that value.
|
|
11
|
+
*/
|
|
12
|
+
type MaybeAsync<T> = T | Promise<T>;
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* A function that returns a type.
|
|
17
|
+
* Used for forward references to types that are not yet defined.
|
|
18
|
+
*/
|
|
19
|
+
interface ForwardRefFn<T = any> {
|
|
20
|
+
(): Type<T>;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* A wrapper class for forward referenced types.
|
|
24
|
+
*/
|
|
25
|
+
declare class ForwardReference<T = any> {
|
|
26
|
+
readonly forwardRefFn: ForwardRefFn<T>;
|
|
27
|
+
constructor(forwardRefFn: ForwardRefFn<T>);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Creates a forward reference to a type.
|
|
31
|
+
* @param fn A function that returns the type.
|
|
32
|
+
* @returns A ForwardReference instance.
|
|
33
|
+
*/
|
|
34
|
+
declare function forwardRef<T = any>(fn: ForwardRefFn<T>): ForwardReference<T>;
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* A DI token uniquely identifies a dependency.
|
|
39
|
+
* It can wrap a class (Type<T>) or be a named symbol token.
|
|
40
|
+
*
|
|
41
|
+
* Using tokens instead of reflect-metadata means dependencies are
|
|
42
|
+
* declared explicitly — no magic type inference, no emitDecoratorMetadata.
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* // Class token (most common)
|
|
46
|
+
* const MY_SERVICE = token(MyService);
|
|
47
|
+
*
|
|
48
|
+
* // Named symbol token (for interfaces or non-class values)
|
|
49
|
+
* const DB_URL = token<string>('DB_URL');
|
|
50
|
+
*/
|
|
51
|
+
declare class Token<T> {
|
|
52
|
+
readonly target: Type<T> | string;
|
|
53
|
+
readonly description: string;
|
|
54
|
+
constructor(target: Type<T> | string);
|
|
55
|
+
toString(): string;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* The key used to look up a class token in the registry.
|
|
59
|
+
* For class tokens, the key is the class constructor itself.
|
|
60
|
+
* For named tokens, the key is the Token instance.
|
|
61
|
+
*/
|
|
62
|
+
type TokenKey<T = unknown> = Type<T> | Token<T>;
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Lifetime of a binding in the DI container.
|
|
67
|
+
* - singleton: created once, shared for the lifetime of the app.
|
|
68
|
+
* - scope: created once per request scope.
|
|
69
|
+
* - transient: new instance every time it is resolved.
|
|
70
|
+
*/
|
|
71
|
+
type Lifetime = 'singleton' | 'scope' | 'transient';
|
|
72
|
+
/**
|
|
73
|
+
* Internal representation of a registered binding.
|
|
74
|
+
*/
|
|
75
|
+
interface IBinding<T = unknown> {
|
|
76
|
+
lifetime: Lifetime;
|
|
77
|
+
implementation: Type<T>;
|
|
78
|
+
/** Explicit constructor dependencies, declared by the class itself. */
|
|
79
|
+
deps: ReadonlyArray<TokenKey>;
|
|
80
|
+
instance?: T;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* AppInjector is the core DI container.
|
|
84
|
+
* It no longer uses reflect-metadata — all dependency information
|
|
85
|
+
* comes from explicitly declared `deps` arrays on each binding.
|
|
86
|
+
*/
|
|
87
|
+
declare class AppInjector {
|
|
88
|
+
readonly name: string | null;
|
|
89
|
+
readonly bindings: Map<Type<unknown> | Token<unknown>, IBinding<unknown>>;
|
|
90
|
+
readonly singletons: Map<Type<unknown> | Token<unknown>, unknown>;
|
|
91
|
+
readonly scoped: Map<Type<unknown> | Token<unknown>, unknown>;
|
|
92
|
+
constructor(name?: string | null);
|
|
93
|
+
/**
|
|
94
|
+
* Creates a child scope for per-request lifetime resolution.
|
|
95
|
+
*/
|
|
96
|
+
createScope(): AppInjector;
|
|
97
|
+
/**
|
|
98
|
+
* Registers a binding explicitly.
|
|
99
|
+
*/
|
|
100
|
+
register<T>(key: TokenKey<T>, implementation: Type<T>, lifetime: Lifetime, deps?: ReadonlyArray<TokenKey>): void;
|
|
101
|
+
/**
|
|
102
|
+
* Resolves a dependency by token or class reference.
|
|
103
|
+
*/
|
|
104
|
+
resolve<T>(target: TokenKey<T> | ForwardReference<T>): T;
|
|
105
|
+
private _resolveForwardRef;
|
|
106
|
+
private _instantiate;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* The global root injector. All singletons live here.
|
|
110
|
+
*/
|
|
111
|
+
declare const RootInjector: AppInjector;
|
|
112
|
+
/**
|
|
113
|
+
* Resets the root injector to a clean state.
|
|
114
|
+
* **Intended for testing only** — clears all bindings, singletons, and scoped instances
|
|
115
|
+
* so that each test can start from a fresh DI container without restarting the process.
|
|
116
|
+
*/
|
|
117
|
+
declare function resetRootInjector(): void;
|
|
118
|
+
/**
|
|
119
|
+
* Convenience function: resolve a token from the root injector.
|
|
120
|
+
*/
|
|
121
|
+
declare function inject<T>(t: TokenKey<T> | ForwardReference<T>): T;
|
|
122
|
+
|
|
9
123
|
declare class ResponseException extends Error {
|
|
10
124
|
readonly status: number;
|
|
11
125
|
constructor(message?: string);
|
|
@@ -232,4 +346,4 @@ declare namespace Logger {
|
|
|
232
346
|
};
|
|
233
347
|
}
|
|
234
348
|
|
|
235
|
-
export { BadGatewayException, BadRequestException, ConflictException, ForbiddenException, GatewayTimeoutException, HttpVersionNotSupportedException, Injectable, type InjectableOptions, InsufficientStorageException, InternalServerException, Lifetime, type LogLevel, Logger, LoopDetectedException, MethodNotAllowedException, NetworkAuthenticationRequiredException, NetworkConnectTimeoutException, NotAcceptableException, NotExtendedException, NotFoundException, NotImplementedException, PaymentRequiredException, RequestTimeoutException, ResponseException, ServiceUnavailableException, TokenKey, TooManyRequestsException, UnauthorizedException, UpgradeRequiredException, VariantAlsoNegotiatesException };
|
|
349
|
+
export { AppInjector, BadGatewayException, BadRequestException, ConflictException, ForbiddenException, type ForwardRefFn, ForwardReference, GatewayTimeoutException, HttpVersionNotSupportedException, type IBinding, Injectable, type InjectableOptions, InsufficientStorageException, InternalServerException, type Lifetime, type LogLevel, Logger, LoopDetectedException, type MaybeAsync, MethodNotAllowedException, NetworkAuthenticationRequiredException, NetworkConnectTimeoutException, NotAcceptableException, NotExtendedException, NotFoundException, NotImplementedException, PaymentRequiredException, RequestTimeoutException, ResponseException, RootInjector, ServiceUnavailableException, Token, type TokenKey, TooManyRequestsException, type Type, UnauthorizedException, UpgradeRequiredException, VariantAlsoNegotiatesException, forwardRef, inject, resetRootInjector };
|