@wyrly/express 1.0.5 → 2.0.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/README.md +13 -1
- package/esm/core/container.d.ts.map +1 -1
- package/esm/core/container.js +2 -4
- package/esm/core/mod.d.ts +4 -1
- package/esm/core/mod.d.ts.map +1 -1
- package/esm/core/mod.js +4 -1
- package/esm/core/provider.d.ts +5 -5
- package/esm/core/provider.d.ts.map +1 -1
- package/esm/core/provider.js +1 -1
- package/esm/express/middleware.d.ts +2 -1
- package/esm/express/middleware.d.ts.map +1 -1
- package/esm/express/middleware.js +12 -2
- package/esm/express/mod.d.ts +5 -2
- package/esm/express/mod.d.ts.map +1 -1
- package/esm/express/mod.js +1 -1
- package/esm/express/types.d.ts +6 -1
- package/esm/express/types.d.ts.map +1 -1
- package/package.json +12 -3
package/README.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# @wyrly/express
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Request-scoped dependency injection for Express and modern TypeScript without `reflect-metadata` —
|
|
4
|
+
one scope per HTTP request via `diMiddleware`.
|
|
4
5
|
|
|
5
6
|
Japanese: [README.ja.md](./README.ja.md)
|
|
6
7
|
|
|
@@ -34,11 +35,22 @@ app.get("/users/:id", (req, res) => {
|
|
|
34
35
|
});
|
|
35
36
|
```
|
|
36
37
|
|
|
38
|
+
Use `onDisposeError` when scoped resources need observable asynchronous cleanup:
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
app.use(diMiddleware(container, {
|
|
42
|
+
onDisposeError(error, req) {
|
|
43
|
+
console.error("Failed to dispose request scope", req.path, error);
|
|
44
|
+
},
|
|
45
|
+
}));
|
|
46
|
+
```
|
|
47
|
+
|
|
37
48
|
## Documentation
|
|
38
49
|
|
|
39
50
|
- [@wyrly/core](../core/README.md)
|
|
40
51
|
- [API reference](https://github.com/valid-lab/wyrly/blob/main/API.md)
|
|
41
52
|
- [Monorepo README](https://github.com/valid-lab/wyrly/blob/main/README.md)
|
|
53
|
+
- [Express DDD example](https://github.com/valid-lab/wyrly/tree/main/examples/express-api)
|
|
42
54
|
|
|
43
55
|
## Related packages
|
|
44
56
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../../src/core/container.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../../src/core/container.ts"],"names":[],"mappings":"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"}
|
package/esm/core/container.js
CHANGED
|
@@ -258,10 +258,8 @@ _ContainerImpl_registry = new WeakMap(), _ContainerImpl_singletonCache = new Wea
|
|
|
258
258
|
return this.resolveFromScope(scope, ex, np.lifetime, pathIds);
|
|
259
259
|
}
|
|
260
260
|
case "factory": {
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
}
|
|
264
|
-
return np.useFactory(scope);
|
|
261
|
+
const args = np.deps.map((d) => resolveDep(d));
|
|
262
|
+
return np.useFactory(scope, ...args);
|
|
265
263
|
}
|
|
266
264
|
case "class": {
|
|
267
265
|
const Ctor = np.useClass;
|
package/esm/core/mod.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Type-safe dependency injection for modern TypeScript without `reflect-metadata`.
|
|
3
|
+
*
|
|
4
|
+
* Wyrly DI uses typed tokens, explicit dependencies, standard decorators, request scopes, and an
|
|
5
|
+
* inspectable graph instead of legacy decorator metadata or parameter decorators.
|
|
3
6
|
*
|
|
4
7
|
* @example
|
|
5
8
|
* ```ts
|
package/esm/core/mod.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../src/core/mod.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../src/core/mod.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,cAAc,EAAE,KAAK,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACrF,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,YAAY,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACxD,YAAY,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,KAAK,SAAS,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjE,YAAY,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,YAAY,EACV,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,kBAAkB,EAClB,QAAQ,EACR,YAAY,EACZ,aAAa,GACd,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAClF,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC5E,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACxF,OAAO,EAAE,2BAA2B,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EACL,cAAc,EACd,YAAY,EACZ,KAAK,gBAAgB,EACrB,qBAAqB,EACrB,KAAK,MAAM,EACX,kBAAkB,EAClB,oBAAoB,EACpB,aAAa,EACb,iBAAiB,EACjB,KAAK,qBAAqB,GAC3B,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,uBAAuB,EACvB,sBAAsB,EACtB,KAAK,kBAAkB,EACvB,oBAAoB,EACpB,sBAAsB,EACtB,qBAAqB,EACrB,KAAK,cAAc,EACnB,kBAAkB,GACnB,MAAM,aAAa,CAAC"}
|
package/esm/core/mod.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Type-safe dependency injection for modern TypeScript without `reflect-metadata`.
|
|
3
|
+
*
|
|
4
|
+
* Wyrly DI uses typed tokens, explicit dependencies, standard decorators, request scopes, and an
|
|
5
|
+
* inspectable graph instead of legacy decorator metadata or parameter decorators.
|
|
3
6
|
*
|
|
4
7
|
* @example
|
|
5
8
|
* ```ts
|
package/esm/core/provider.d.ts
CHANGED
|
@@ -25,10 +25,10 @@ export interface ValueProvider<T> {
|
|
|
25
25
|
* `Promise<T>` is planned for a future `resolveAsync`.
|
|
26
26
|
*/
|
|
27
27
|
export interface FactoryProvider<T> {
|
|
28
|
-
/** Factory invoked with the active scope. */
|
|
29
|
-
useFactory: (scope: Scope) => T;
|
|
30
|
-
/** Tokens resolved before the factory runs
|
|
31
|
-
deps
|
|
28
|
+
/** Factory invoked with the active scope and resolved dependency values. */
|
|
29
|
+
useFactory: (scope: Scope, ...deps: unknown[]) => T;
|
|
30
|
+
/** Tokens resolved before the factory runs and passed to `useFactory`. */
|
|
31
|
+
deps: InjectionToken<unknown>[];
|
|
32
32
|
/** Lifetime for the factory result. */
|
|
33
33
|
lifetime?: Lifetime;
|
|
34
34
|
}
|
|
@@ -58,7 +58,7 @@ export interface NormalizedProvider<T = unknown> {
|
|
|
58
58
|
/** Set when `providerType` is `"value"`. */
|
|
59
59
|
readonly useValue?: T;
|
|
60
60
|
/** Set when `providerType` is `"factory"`. */
|
|
61
|
-
readonly useFactory?: (scope: Scope) => T;
|
|
61
|
+
readonly useFactory?: (scope: Scope, ...deps: unknown[]) => T;
|
|
62
62
|
/** Set when `providerType` is `"existing"`. */
|
|
63
63
|
readonly useExisting?: InjectionToken<T>;
|
|
64
64
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/core/provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAK9C,iEAAiE;AACjE,MAAM,MAAM,QAAQ,CAAC,CAAC,IAClB,aAAa,CAAC,CAAC,CAAC,GAChB,aAAa,CAAC,CAAC,CAAC,GAChB,eAAe,CAAC,CAAC,CAAC,GAClB,gBAAgB,CAAC,CAAC,CAAC,CAAC;AAExB,2DAA2D;AAC3D,MAAM,WAAW,aAAa,CAAC,CAAC;IAC9B,4BAA4B;IAC5B,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;IACxB,4EAA4E;IAC5E,IAAI,CAAC,EAAE,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC;IACjC,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED,mDAAmD;AACnD,MAAM,WAAW,aAAa,CAAC,CAAC;IAC9B,0BAA0B;IAC1B,QAAQ,EAAE,CAAC,CAAC;IACZ,sCAAsC;IACtC,QAAQ,CAAC,EAAE,WAAW,CAAC;CACxB;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/core/provider.ts"],"names":[],"mappings":"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"}
|
package/esm/core/provider.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { RequestHandler } from "express";
|
|
2
2
|
import type { Container } from "../core/mod.js";
|
|
3
|
+
import { type ExpressDIOptions } from "./types.js";
|
|
3
4
|
/**
|
|
4
5
|
* Creates a DI scope per request and attaches it to `req.di`.
|
|
5
6
|
* Disposes the scope on response `finish` / `close`.
|
|
@@ -7,5 +8,5 @@ import type { Container } from "../core/mod.js";
|
|
|
7
8
|
* In the domain layer, avoid injecting `ExpressRequestToken` directly;
|
|
8
9
|
* map it to port tokens (e.g. `CurrentUser`) in the composition root instead.
|
|
9
10
|
*/
|
|
10
|
-
export declare function diMiddleware(container: Container): RequestHandler;
|
|
11
|
+
export declare function diMiddleware(container: Container, options?: ExpressDIOptions): RequestHandler;
|
|
11
12
|
//# sourceMappingURL=middleware.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/express/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAyB,cAAc,EAAY,MAAM,SAAS,CAAC;AAC/E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/express/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAyB,cAAc,EAAY,MAAM,SAAS,CAAC;AAC/E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,OAAO,EAA0B,KAAK,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE3E;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,GAAE,gBAAqB,GAAG,cAAc,CAuBjG"}
|
|
@@ -7,14 +7,24 @@ import { asExpressRequestWithDI } from "./types.js";
|
|
|
7
7
|
* In the domain layer, avoid injecting `ExpressRequestToken` directly;
|
|
8
8
|
* map it to port tokens (e.g. `CurrentUser`) in the composition root instead.
|
|
9
9
|
*/
|
|
10
|
-
export function diMiddleware(container) {
|
|
10
|
+
export function diMiddleware(container, options = {}) {
|
|
11
11
|
return (req, res, next) => {
|
|
12
12
|
const scope = container.createScope();
|
|
13
13
|
scope.set(ExpressRequestToken, req);
|
|
14
14
|
scope.set(ExpressResponseToken, res);
|
|
15
15
|
asExpressRequestWithDI(req).di = scope;
|
|
16
|
+
let disposeStarted = false;
|
|
16
17
|
const disposeScope = () => {
|
|
17
|
-
|
|
18
|
+
if (disposeStarted)
|
|
19
|
+
return;
|
|
20
|
+
disposeStarted = true;
|
|
21
|
+
void scope.dispose().catch((error) => {
|
|
22
|
+
if (!options.onDisposeError)
|
|
23
|
+
return;
|
|
24
|
+
void Promise.resolve(options.onDisposeError(error, req, res)).catch(() => {
|
|
25
|
+
// Disposal happens after the response lifecycle; avoid unhandled rejections here.
|
|
26
|
+
});
|
|
27
|
+
});
|
|
18
28
|
};
|
|
19
29
|
res.once("finish", disposeScope);
|
|
20
30
|
res.once("close", disposeScope);
|
package/esm/express/mod.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Request-scoped dependency injection for Express and modern TypeScript.
|
|
3
|
+
*
|
|
4
|
+
* Use `diMiddleware` to create one explicit Wyrly DI scope per HTTP request without
|
|
5
|
+
* `reflect-metadata` or parameter decorators.
|
|
3
6
|
*
|
|
4
7
|
* @example
|
|
5
8
|
* ```ts
|
|
@@ -22,5 +25,5 @@
|
|
|
22
25
|
export type { ClassProvider, ClassToken, Container, DependencyEdge, DependencyGraph, DependencyNode, ExistingProvider, FactoryProvider, InjectionToken, Lifetime, Locale, Provider, ProviderType, Scope, Token, ValidateOptions, ValidationIssue, ValidationResult, ValueProvider, } from "../core/mod.js";
|
|
23
26
|
export { diMiddleware } from "./middleware.js";
|
|
24
27
|
export { ExpressRequestToken, ExpressResponseToken } from "./tokens.js";
|
|
25
|
-
export { asExpressRequestWithDI, type ExpressRequestWithDI } from "./types.js";
|
|
28
|
+
export { asExpressRequestWithDI, type ExpressDIOptions, type ExpressRequestWithDI, } from "./types.js";
|
|
26
29
|
//# sourceMappingURL=mod.d.ts.map
|
package/esm/express/mod.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../src/express/mod.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../src/express/mod.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,YAAY,EACV,aAAa,EACb,UAAU,EACV,SAAS,EACT,cAAc,EACd,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,YAAY,EACZ,KAAK,EACL,KAAK,EACL,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,aAAa,GACd,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EACL,sBAAsB,EACtB,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,GAC1B,MAAM,YAAY,CAAC"}
|
package/esm/express/mod.js
CHANGED
package/esm/express/types.d.ts
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
import type { Request } from "express";
|
|
1
|
+
import type { Request, Response } from "express";
|
|
2
2
|
import type { Scope } from "../core/mod.js";
|
|
3
3
|
/** Express `Request` with the DI scope attached by `diMiddleware`. */
|
|
4
4
|
export type ExpressRequestWithDI = Request & {
|
|
5
5
|
di: Scope;
|
|
6
6
|
};
|
|
7
|
+
/** Options for {@link diMiddleware}. */
|
|
8
|
+
export interface ExpressDIOptions {
|
|
9
|
+
/** Called when request-scope disposal rejects after the response lifecycle ends. */
|
|
10
|
+
onDisposeError?: (error: unknown, req: Request, res: Response) => void | Promise<void>;
|
|
11
|
+
}
|
|
7
12
|
/** Narrow `req` after `diMiddleware` (use instead of casting when route generics block overlap). */
|
|
8
13
|
export declare function asExpressRequestWithDI(req: Request): ExpressRequestWithDI;
|
|
9
14
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/express/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/express/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAE5C,sEAAsE;AACtE,MAAM,MAAM,oBAAoB,GAAG,OAAO,GAAG;IAAE,EAAE,EAAE,KAAK,CAAA;CAAE,CAAC;AAE3D,wCAAwC;AACxC,MAAM,WAAW,gBAAgB;IAC/B,oFAAoF;IACpF,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACxF;AAED,oGAAoG;AACpG,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG,oBAAoB,CAEzE"}
|
package/package.json
CHANGED
|
@@ -1,17 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wyrly/express",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "Request-scoped dependency injection adapter for Express and TypeScript",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"wyrly",
|
|
7
7
|
"dependency-injection",
|
|
8
8
|
"di",
|
|
9
9
|
"typescript",
|
|
10
|
+
"standard-decorators",
|
|
11
|
+
"decorators",
|
|
12
|
+
"reflect-metadata",
|
|
13
|
+
"no-reflect-metadata",
|
|
14
|
+
"request-scope",
|
|
15
|
+
"scoped",
|
|
16
|
+
"clean-architecture",
|
|
17
|
+
"ddd",
|
|
10
18
|
"inversion-of-control",
|
|
11
19
|
"ioc",
|
|
12
20
|
"express",
|
|
13
21
|
"middleware",
|
|
14
22
|
"node",
|
|
23
|
+
"nodejs",
|
|
15
24
|
"http"
|
|
16
25
|
],
|
|
17
26
|
"homepage": "https://github.com/valid-lab/wyrly/tree/main/packages/express",
|
|
@@ -34,7 +43,7 @@
|
|
|
34
43
|
"sideEffects": false,
|
|
35
44
|
"dependencies": {
|
|
36
45
|
"express": "5",
|
|
37
|
-
"@wyrly/core": "^
|
|
46
|
+
"@wyrly/core": "^2.0.0"
|
|
38
47
|
},
|
|
39
48
|
"peerDependencies": {
|
|
40
49
|
"express": "^5.0.0"
|