@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 CHANGED
@@ -1,6 +1,7 @@
1
1
  # @wyrly/express
2
2
 
3
- Wyrly DI adapter for Express one request scope per HTTP request via `diMiddleware`.
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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"}
@@ -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
- for (const d of np.deps) {
262
- resolveDep(d);
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
- * Explicit DI for modern TypeScript typed tokens, standard decorators, and request scopes.
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
@@ -1 +1 @@
1
- {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../src/core/mod.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;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"}
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
- * Explicit DI for modern TypeScript typed tokens, standard decorators, and request scopes.
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
@@ -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?: InjectionToken<unknown>[];
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,6CAA6C;IAC7C,UAAU,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,CAAC,CAAC;IAChC,+CAA+C;IAC/C,IAAI,CAAC,EAAE,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC;IACjC,uCAAuC;IACvC,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED,wCAAwC;AACxC,MAAM,WAAW,gBAAgB,CAAC,CAAC;IACjC,gCAAgC;IAChC,WAAW,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;IAC/B,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED,uDAAuD;AACvD,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,GAAG,UAAU,CAAC;AAEtE,yEAAyE;AACzE,MAAM,WAAW,kBAAkB,CAAC,CAAC,GAAG,OAAO;IAC7C,qCAAqC;IACrC,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;IAClC,yCAAyC;IACzC,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IACpC,kCAAkC;IAClC,QAAQ,CAAC,IAAI,EAAE,SAAS,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC;IAClD,0BAA0B;IAC1B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,uCAAuC;IACvC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,4CAA4C;IAC5C,QAAQ,CAAC,QAAQ,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;IAClC,4CAA4C;IAC5C,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACtB,8CAA8C;IAC9C,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,CAAC,CAAC;IAC1C,+CAA+C;IAC/C,QAAQ,CAAC,WAAW,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;CAC1C;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,EACxB,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,GACpB,kBAAkB,CAAC,CAAC,CAAC,CAwDvB;AAED,wBAAgB,sBAAsB,CAAC,CAAC,EACtC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,GACnB,kBAAkB,CAAC,CAAC,CAAC,CAYvB"}
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/core/provider.ts"],"names":[],"mappings":"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"}
@@ -17,7 +17,7 @@ export function normalizeProvider(token, provider) {
17
17
  };
18
18
  }
19
19
  if ("useFactory" in provider) {
20
- const deps = provider.deps ?? [];
20
+ const deps = provider.deps;
21
21
  const lifetime = provider.lifetime ?? "singleton";
22
22
  return {
23
23
  token,
@@ -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;AAIhD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,cAAc,CAejE"}
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
- void scope.dispose();
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);
@@ -1,5 +1,8 @@
1
1
  /**
2
- * Express adapter for Wyrly DI one scope per HTTP request via `diMiddleware`.
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
@@ -1 +1 @@
1
- {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../src/express/mod.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;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,EAAE,sBAAsB,EAAE,KAAK,oBAAoB,EAAE,MAAM,YAAY,CAAC"}
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"}
@@ -1,3 +1,3 @@
1
1
  export { diMiddleware } from "./middleware.js";
2
2
  export { ExpressRequestToken, ExpressResponseToken } from "./tokens.js";
3
- export { asExpressRequestWithDI } from "./types.js";
3
+ export { asExpressRequestWithDI, } from "./types.js";
@@ -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;AACvC,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,oGAAoG;AACpG,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG,oBAAoB,CAEzE"}
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": "1.0.5",
4
- "description": "Wyrly DI adapter for Express request scope via diMiddleware",
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": "^1.0.5"
46
+ "@wyrly/core": "^2.0.0"
38
47
  },
39
48
  "peerDependencies": {
40
49
  "express": "^5.0.0"