@effect-app/infra 2.75.0 → 2.77.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.
Files changed (36) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/Emailer/service.d.ts +1 -1
  3. package/dist/MainFiberSet.d.ts +1 -1
  4. package/dist/Operations.d.ts +1 -1
  5. package/dist/RequestFiberSet.d.ts +1 -1
  6. package/dist/Store/service.d.ts +2 -2
  7. package/dist/adapters/SQL/Model.d.ts +6 -6
  8. package/dist/adapters/ServiceBus.d.ts +1 -1
  9. package/dist/adapters/memQueue.d.ts +1 -1
  10. package/dist/api/layerUtils.d.ts +10 -2
  11. package/dist/api/layerUtils.d.ts.map +1 -1
  12. package/dist/api/layerUtils.js +25 -2
  13. package/dist/api/routing/middleware/ContextProvider.d.ts +14 -14
  14. package/dist/api/routing/middleware/ContextProvider.d.ts.map +1 -1
  15. package/dist/api/routing/middleware/ContextProvider.js +3 -2
  16. package/dist/api/routing/middleware/DynamicMiddleware.d.ts +4 -4
  17. package/dist/api/routing/middleware/DynamicMiddleware.d.ts.map +1 -1
  18. package/dist/api/routing/middleware/DynamicMiddleware.js +24 -12
  19. package/dist/api/routing/middleware/dynamic-middleware.d.ts +6 -15
  20. package/dist/api/routing/middleware/dynamic-middleware.d.ts.map +1 -1
  21. package/dist/api/routing/middleware/dynamic-middleware.js +4 -25
  22. package/dist/api/routing/middleware/generic-middleware.d.ts +10 -1
  23. package/dist/api/routing/middleware/generic-middleware.d.ts.map +1 -1
  24. package/dist/api/routing/middleware/generic-middleware.js +8 -9
  25. package/dist/api/routing/middleware/middleware.d.ts +8 -9
  26. package/dist/api/routing/middleware/middleware.d.ts.map +1 -1
  27. package/dist/api/routing/middleware/middleware.js +41 -43
  28. package/package.json +5 -5
  29. package/src/api/layerUtils.ts +39 -3
  30. package/src/api/routing/middleware/ContextProvider.ts +39 -51
  31. package/src/api/routing/middleware/DynamicMiddleware.ts +42 -31
  32. package/src/api/routing/middleware/dynamic-middleware.ts +31 -105
  33. package/src/api/routing/middleware/generic-middleware.ts +19 -12
  34. package/src/api/routing/middleware/middleware.ts +60 -77
  35. package/test/controller.test.ts +38 -20
  36. package/test/dist/controller.test.d.ts.map +1 -1
@@ -1,20 +1,19 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
2
  import { Effect } from "effect-app";
3
+ export const genericMiddleware = (i) => i;
3
4
  export const genericMiddlewareMaker = (...middlewares) => {
4
5
  return {
5
6
  dependencies: middlewares.map((_) => _.Default),
6
7
  effect: Effect.gen(function* () {
7
8
  const middlewaresInstances = yield* Effect.all(middlewares);
8
- return (handle, moduleName) => {
9
- return (input, headers) => {
10
- let effect = handle;
11
- for (const middleware of middlewaresInstances.toReversed()) {
12
- effect = middleware(effect, moduleName);
13
- }
14
- return effect(input, headers);
15
- };
9
+ return (options) => {
10
+ let next = options.next;
11
+ for (const middleware of middlewaresInstances.toReversed()) {
12
+ next = middleware({ ...options, next });
13
+ }
14
+ return next;
16
15
  };
17
16
  })
18
17
  };
19
18
  };
20
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJpYy1taWRkbGV3YXJlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2FwaS9yb3V0aW5nL21pZGRsZXdhcmUvZ2VuZXJpYy1taWRkbGV3YXJlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHVEQUF1RDtBQUN2RCxPQUFPLEVBQWMsTUFBTSxFQUFFLE1BQU0sWUFBWSxDQUFBO0FBUy9DLE1BQU0sQ0FBQyxNQUFNLHNCQUFzQixHQUFHLENBSXBDLEdBQUcsV0FBYyxFQUdqQixFQUFFO0lBQ0YsT0FBTztRQUNMLFlBQVksRUFBRSxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDO1FBQy9DLE1BQU0sRUFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQztZQUMxQixNQUFNLG9CQUFvQixHQUFHLEtBQUssQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUE7WUFFM0QsT0FBTyxDQUNMLE1BQTRFLEVBQzVFLFVBQWtCLEVBQ2xCLEVBQUU7Z0JBQ0YsT0FBTyxDQUFDLEtBQVUsRUFBRSxPQUE0QixFQUFFLEVBQUU7b0JBQ2xELElBQUksTUFBTSxHQUFHLE1BQU0sQ0FBQTtvQkFDbkIsS0FBSyxNQUFNLFVBQVUsSUFBSyxvQkFBOEIsQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDO3dCQUN0RSxNQUFNLEdBQUcsVUFBVSxDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsQ0FBQTtvQkFDekMsQ0FBQztvQkFDRCxPQUFPLE1BQU0sQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUE7Z0JBQy9CLENBQUMsQ0FBQTtZQUNILENBQUMsQ0FBQTtRQUNILENBQUMsQ0FBQztLQUNJLENBQUE7QUFDVixDQUFDLENBQUEifQ==
19
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJpYy1taWRkbGV3YXJlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2FwaS9yb3V0aW5nL21pZGRsZXdhcmUvZ2VuZXJpYy1taWRkbGV3YXJlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHVEQUF1RDtBQUN2RCxPQUFPLEVBQWMsTUFBTSxFQUFFLE1BQU0sWUFBWSxDQUFBO0FBaUIvQyxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBRyxDQUFDLENBQXlCLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQTtBQUVqRSxNQUFNLENBQUMsTUFBTSxzQkFBc0IsR0FBRyxDQUlwQyxHQUFHLFdBQWMsRUFHakIsRUFBRTtJQUNGLE9BQU87UUFDTCxZQUFZLEVBQUUsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQztRQUMvQyxNQUFNLEVBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUM7WUFDMUIsTUFBTSxvQkFBb0IsR0FBRyxLQUFLLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFBO1lBRTNELE9BQU8sQ0FDTCxPQUF1QyxFQUN2QyxFQUFFO2dCQUNGLElBQUksSUFBSSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUE7Z0JBQ3ZCLEtBQUssTUFBTSxVQUFVLElBQUssb0JBQThCLENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQztvQkFDdEUsSUFBSSxHQUFHLFVBQVUsQ0FBQyxFQUFFLEdBQUcsT0FBTyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUE7Z0JBQ3pDLENBQUM7Z0JBQ0QsT0FBTyxJQUFJLENBQUE7WUFDYixDQUFDLENBQUE7UUFDSCxDQUFDLENBQUM7S0FDSSxDQUFBO0FBQ1YsQ0FBQyxDQUFBIn0=
@@ -1,23 +1,22 @@
1
1
  import { Context, Effect } from "effect-app";
2
- import { HttpHeaders, type HttpRouter } from "effect-app/http";
3
2
  declare const DevMode_base: Context.ReferenceClass<DevMode, "DevMode", boolean>;
4
3
  export declare class DevMode extends DevMode_base {
5
4
  }
6
- declare const ConfigureInterruptibility_base: Effect.Service.Class<ConfigureInterruptibility, "ConfigureInterruptibility", {
7
- readonly effect: Effect.Effect<(<A, E>(handle: (input: any, headers: HttpHeaders.Headers) => Effect.Effect<A, E, HttpRouter.HttpRouter.Provided>, _moduleName: string) => (input: any, headers: HttpHeaders.Headers) => Effect.Effect<A, E, HttpRouter.HttpRouter.Provided>), never, never>;
5
+ declare const RequestCacheMiddleware_base: Effect.Service.Class<RequestCacheMiddleware, "RequestCacheMiddleware", {
6
+ readonly effect: Effect.Effect<import("./generic-middleware.js").GenericMiddlewareMaker, never, never>;
8
7
  }>;
9
- export declare class ConfigureInterruptibility extends ConfigureInterruptibility_base {
8
+ export declare class RequestCacheMiddleware extends RequestCacheMiddleware_base {
10
9
  }
11
- declare const CaptureHttpHeadersAsRpcHeaders_base: Effect.Service.Class<CaptureHttpHeadersAsRpcHeaders, "CaptureHttpHeadersAsRpcHeaders", {
12
- readonly effect: Effect.Effect<(<A, E>(handle: (input: any, headers: HttpHeaders.Headers) => Effect.Effect<A, E, HttpRouter.HttpRouter.Provided>, _moduleName: string) => (input: any, rpcHeaders: HttpHeaders.Headers) => Effect.Effect<A, E, HttpRouter.HttpRouter.Provided>), never, never>;
10
+ declare const ConfigureInterruptibility_base: Effect.Service.Class<ConfigureInterruptibility, "ConfigureInterruptibility", {
11
+ readonly effect: Effect.Effect<import("./generic-middleware.js").GenericMiddlewareMaker, never, never>;
13
12
  }>;
14
- export declare class CaptureHttpHeadersAsRpcHeaders extends CaptureHttpHeadersAsRpcHeaders_base {
13
+ export declare class ConfigureInterruptibility extends ConfigureInterruptibility_base {
15
14
  }
16
15
  declare const MiddlewareLogger_base: Effect.Service.Class<MiddlewareLogger, "MiddlewareLogger", {
17
- readonly effect: Effect.Effect<(<A, E>(handle: (input: any, headers: HttpHeaders.Headers) => Effect.Effect<A, E, HttpRouter.HttpRouter.Provided>, moduleName: string) => (input: any, rpcHeaders: HttpHeaders.Headers) => Effect.Effect<A, E, HttpRouter.HttpRouter.Provided>), never, never>;
16
+ readonly effect: Effect.Effect<import("./generic-middleware.js").GenericMiddlewareMaker, never, never>;
18
17
  }>;
19
18
  export declare class MiddlewareLogger extends MiddlewareLogger_base {
20
19
  }
21
- export declare const DefaultGenericMiddlewares: readonly [typeof ConfigureInterruptibility, typeof CaptureHttpHeadersAsRpcHeaders, typeof MiddlewareLogger];
20
+ export declare const DefaultGenericMiddlewares: readonly [typeof RequestCacheMiddleware, typeof ConfigureInterruptibility, typeof MiddlewareLogger];
22
21
  export {};
23
22
  //# sourceMappingURL=middleware.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../../../src/api/routing/middleware/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,OAAO,EAAE,MAAM,EAAe,MAAM,YAAY,CAAA;AAChE,OAAO,EAAE,WAAW,EAAE,KAAK,UAAU,EAAqB,MAAM,iBAAiB,CAAA;;AAQjF,qBAAa,OAAQ,SAAQ,YAAsE;CAAG;;qCAMxF,CAAC,EAAE,CAAC,UACF,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,WAAW,CAAC,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,UAAU,CAAC,UAAU,CAAC,QAAQ,CAAC,eAC5F,MAAM;;AAN3B,qBAAa,yBAA0B,SAAQ,8BAgB9C;CAAG;;qCAKU,CAAC,EAAE,CAAC,UACF,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,WAAW,CAAC,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,UAAU,CAAC,UAAU,CAAC,QAAQ,CAAC,eAC5F,MAAM;;AAL3B,qBAAa,8BACX,SAAQ,mCAcN;CACF;;qCAIU,CAAC,EAAE,CAAC,UACF,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,WAAW,CAAC,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,UAAU,CAAC,UAAU,CAAC,QAAQ,CAAC,cAC7F,MAAM;;AAJxB,qBAAa,gBAAiB,SAAQ,qBAkEpC;CAAG;AAEL,eAAO,MAAM,yBAAyB,6GAI5B,CAAA"}
1
+ {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../../../src/api/routing/middleware/middleware.ts"],"names":[],"mappings":"AACA,OAAO,EAAS,OAAO,EAAE,MAAM,EAAe,MAAM,YAAY,CAAA;;AAShE,qBAAa,OAAQ,SAAQ,YAAsE;CAAG;;;;AAEtG,qBAAa,sBAAuB,SAAQ,2BAM1C;CAAG;;;;AAGL,qBAAa,yBAA0B,SAAQ,8BAY9C;CAAG;;;;AAGJ,qBAAa,gBAAiB,SAAQ,qBA4DpC;CAAG;AAEL,eAAO,MAAM,yBAAyB,qGAI5B,CAAA"}
@@ -1,73 +1,71 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
1
2
  import { Cause, Context, Effect, ParseResult } from "effect-app";
2
- import { HttpHeaders, HttpServerRequest } from "effect-app/http";
3
3
  import { pretty } from "effect-app/utils";
4
4
  import { logError, reportError } from "../../../errorReporter.js";
5
5
  import { InfraLogger } from "../../../logger.js";
6
+ import { genericMiddleware, RequestCacheLayers } from "../../routing.js";
6
7
  const logRequestError = logError("Request");
7
8
  const reportRequestError = reportError("Request");
8
9
  export class DevMode extends Context.Reference()("DevMode", { defaultValue: () => false }) {
9
10
  }
10
- export class ConfigureInterruptibility extends Effect.Service()("ConfigureInterruptibility", {
11
+ // Effect Rpc Middleware: Wrap
12
+ export class RequestCacheMiddleware extends Effect.Service()("RequestCacheMiddleware", {
11
13
  effect: Effect.gen(function* () {
12
- return (handle, _moduleName) => Effect.fnUntraced(function* (input, headers) {
13
- return yield* handle(input, headers).pipe(
14
- // TODO: make this depend on query/command, and consider if middleware also should be affected. right now it's not.
15
- Effect.uninterruptible);
16
- });
14
+ return genericMiddleware(Effect.fnUntraced(function* (options) {
15
+ return yield* options.next.pipe(Effect.provide(RequestCacheLayers));
16
+ }));
17
17
  })
18
18
  }) {
19
19
  }
20
- export class CaptureHttpHeadersAsRpcHeaders extends Effect.Service()("CaptureHttpHeadersAsRpcHeaders", {
20
+ // Effect Rpc Middleware: Wrap
21
+ export class ConfigureInterruptibility extends Effect.Service()("ConfigureInterruptibility", {
21
22
  effect: Effect.gen(function* () {
22
- return (handle, _moduleName) => Effect.fnUntraced(function* (input, rpcHeaders) {
23
- // merge in the request headers
24
- // we should consider if we should merge them into rpc headers on the Protocol layer instead.
25
- const httpReq = yield* HttpServerRequest.HttpServerRequest;
26
- const headers = HttpHeaders.merge(httpReq.headers, rpcHeaders);
27
- return yield* handle(input, headers);
28
- });
23
+ return genericMiddleware(Effect.fnUntraced(function* (options) {
24
+ return yield* options.next.pipe(
25
+ // TODO: make this depend on query/command, and consider if middleware also should be affected. right now it's not.
26
+ Effect.uninterruptible);
27
+ }));
29
28
  })
30
29
  }) {
31
30
  }
31
+ // Effect Rpc Middleware: Wrap
32
32
  export class MiddlewareLogger extends Effect.Service()("MiddlewareLogger", {
33
33
  effect: Effect.gen(function* () {
34
- return (handle, moduleName) => Effect.fnUntraced(function* (input, rpcHeaders) {
34
+ return genericMiddleware(Effect.fnUntraced(function* ({ headers, next, payload, rpc }) {
35
35
  const devMode = yield* DevMode;
36
- // merge in the request headers
37
- // we should consider if we should merge them into rpc headers on the Protocol layer instead.
38
- const httpReq = yield* HttpServerRequest.HttpServerRequest;
39
- const headers = HttpHeaders.merge(httpReq.headers, rpcHeaders);
40
36
  return yield* Effect
41
- .annotateCurrentSpan("requestInput", Object.entries(input).reduce((prev, [key, value]) => {
42
- prev[key] = key === "password"
43
- ? "<redacted>"
44
- : typeof value === "string" || typeof value === "number" || typeof value === "boolean"
45
- ? typeof value === "string" && value.length > 256
46
- ? (value.substring(0, 253) + "...")
47
- : value
48
- : Array.isArray(value)
49
- ? `Array[${value.length}]`
50
- : value === null || value === undefined
51
- ? `${value}`
52
- : typeof value === "object" && value
53
- ? `Object[${Object.keys(value).length}]`
54
- : typeof value;
55
- return prev;
56
- }, {}))
37
+ .annotateCurrentSpan("requestInput", typeof payload === "object" && payload !== null
38
+ ? Object.entries(payload).reduce((prev, [key, value]) => {
39
+ prev[key] = key === "password"
40
+ ? "<redacted>"
41
+ : typeof value === "string" || typeof value === "number" || typeof value === "boolean"
42
+ ? typeof value === "string" && value.length > 256
43
+ ? (value.substring(0, 253) + "...")
44
+ : value
45
+ : Array.isArray(value)
46
+ ? `Array[${value.length}]`
47
+ : value === null || value === undefined
48
+ ? `${value}`
49
+ : typeof value === "object" && value
50
+ ? `Object[${Object.keys(value).length}]`
51
+ : typeof value;
52
+ return prev;
53
+ }, {})
54
+ : payload)
57
55
  .pipe(
58
56
  // can't use andThen due to some being a function and effect
59
- Effect.zipRight(handle(input, headers)),
57
+ Effect.zipRight(next),
60
58
  // TODO: support ParseResult if the error channel of the request allows it.. but who would want that?
61
59
  Effect.catchAll((_) => ParseResult.isParseError(_) ? Effect.die(_) : Effect.fail(_)), Effect.tapErrorCause((cause) => Cause.isFailure(cause) ? logRequestError(cause) : Effect.void), Effect.tapDefect((cause) => Effect
62
60
  .all([
63
61
  reportRequestError(cause, {
64
- action: `${moduleName}.${input._tag}`
62
+ action: rpc._tag
65
63
  }),
66
64
  InfraLogger
67
65
  .logError("Finished request", cause)
68
66
  .pipe(Effect.annotateLogs({
69
- action: `${moduleName}.${input._tag}`,
70
- req: pretty(input),
67
+ action: rpc._tag,
68
+ req: pretty(payload),
71
69
  headers: pretty(headers)
72
70
  // resHeaders: pretty(
73
71
  // Object
@@ -79,13 +77,13 @@ export class MiddlewareLogger extends Effect.Service()("MiddlewareLogger", {
79
77
  // )
80
78
  }))
81
79
  ])), devMode ? (_) => _ : Effect.catchAllDefect(() => Effect.die("Internal Server Error")));
82
- });
80
+ }));
83
81
  })
84
82
  }) {
85
83
  }
86
84
  export const DefaultGenericMiddlewares = [
85
+ RequestCacheMiddleware,
87
86
  ConfigureInterruptibility,
88
- CaptureHttpHeadersAsRpcHeaders,
89
87
  MiddlewareLogger
90
88
  ];
91
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWlkZGxld2FyZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9hcGkvcm91dGluZy9taWRkbGV3YXJlL21pZGRsZXdhcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBRSxNQUFNLFlBQVksQ0FBQTtBQUNoRSxPQUFPLEVBQUUsV0FBVyxFQUFtQixpQkFBaUIsRUFBRSxNQUFNLGlCQUFpQixDQUFBO0FBQ2pGLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQTtBQUN6QyxPQUFPLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxNQUFNLDJCQUEyQixDQUFBO0FBQ2pFLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQTtBQUVoRCxNQUFNLGVBQWUsR0FBRyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUE7QUFDM0MsTUFBTSxrQkFBa0IsR0FBRyxXQUFXLENBQUMsU0FBUyxDQUFDLENBQUE7QUFFakQsTUFBTSxPQUFPLE9BQVEsU0FBUSxPQUFPLENBQUMsU0FBUyxFQUFXLENBQUMsU0FBUyxFQUFFLEVBQUUsWUFBWSxFQUFFLEdBQUcsRUFBRSxDQUFDLEtBQUssRUFBRSxDQUFDO0NBQUc7QUFFdEcsTUFBTSxPQUFPLHlCQUEwQixTQUFRLE1BQU0sQ0FBQyxPQUFPLEVBQTZCLENBQ3hGLDJCQUEyQixFQUMzQjtJQUNFLE1BQU0sRUFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQztRQUMxQixPQUFPLENBQ0wsTUFBeUcsRUFDekcsV0FBbUIsRUFDbkIsRUFBRSxDQUNGLE1BQU0sQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLEVBQUMsS0FBVSxFQUFFLE9BQTRCO1lBQ2xFLE9BQU8sS0FBSyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQyxJQUFJO1lBQ3ZDLG1I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
89
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWlkZGxld2FyZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9hcGkvcm91dGluZy9taWRkbGV3YXJlL21pZGRsZXdhcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsdURBQXVEO0FBQ3ZELE9BQU8sRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUsTUFBTSxZQUFZLENBQUE7QUFDaEUsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGtCQUFrQixDQUFBO0FBQ3pDLE9BQU8sRUFBRSxRQUFRLEVBQUUsV0FBVyxFQUFFLE1BQU0sMkJBQTJCLENBQUE7QUFDakUsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLG9CQUFvQixDQUFBO0FBQ2hELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGtCQUFrQixDQUFBO0FBRXhFLE1BQU0sZUFBZSxHQUFHLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQTtBQUMzQyxNQUFNLGtCQUFrQixHQUFHLFdBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQTtBQUVqRCxNQUFNLE9BQU8sT0FBUSxTQUFRLE9BQU8sQ0FBQyxTQUFTLEVBQVcsQ0FBQyxTQUFTLEVBQUUsRUFBRSxZQUFZLEVBQUUsR0FBRyxFQUFFLENBQUMsS0FBSyxFQUFFLENBQUM7Q0FBRztBQUN0Ryw4QkFBOEI7QUFDOUIsTUFBTSxPQUFPLHNCQUF1QixTQUFRLE1BQU0sQ0FBQyxPQUFPLEVBQTBCLENBQUMsd0JBQXdCLEVBQUU7SUFDN0csTUFBTSxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDO1FBQzFCLE9BQU8saUJBQWlCLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsRUFBQyxPQUFPO1lBQzFELE9BQU8sS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxrQkFBa0IsQ0FB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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effect-app/infra",
3
- "version": "2.75.0",
3
+ "version": "2.77.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "dependencies": {
@@ -13,7 +13,7 @@
13
13
  "proper-lockfile": "^4.1.2",
14
14
  "pure-rand": "7.0.1",
15
15
  "query-string": "^9.2.2",
16
- "effect-app": "2.49.0"
16
+ "effect-app": "2.50.0"
17
17
  },
18
18
  "devDependencies": {
19
19
  "@azure/cosmos": "^4.5.0",
@@ -38,10 +38,10 @@
38
38
  "peerDependencies": {
39
39
  "@azure/cosmos": "^4.5.0",
40
40
  "@azure/service-bus": "^7.9.5",
41
- "@effect/experimental": "^0.54.1",
41
+ "@effect/experimental": "^0.54.3",
42
42
  "@effect/platform": "^0.90.0",
43
43
  "@effect/rpc-http": "^0.52.4",
44
- "@effect/rpc": "^0.68.0",
44
+ "@effect/rpc": "^0.68.1",
45
45
  "@effect/sql": "^0.44.0",
46
46
  "@effect/vitest": "^0.25.0",
47
47
  "@sendgrid/helpers": "^8.0.0",
@@ -51,7 +51,7 @@
51
51
  "jwt-decode": "^4.0.0",
52
52
  "redis": "^3.1.2",
53
53
  "redlock": "^4.2.0",
54
- "effect": "^3.17.2",
54
+ "effect": "^3.17.4",
55
55
  "express": "^5.1.0"
56
56
  },
57
57
  "typesVersions": {
@@ -1,4 +1,5 @@
1
- import { type Context, type Layer, type NonEmptyReadonlyArray } from "effect-app"
1
+ import { Context, Effect, type Layer, type NonEmptyReadonlyArray, Option } from "effect-app"
2
+ import { InfraLogger } from "../logger.js"
2
3
 
3
4
  export namespace LayerUtils {
4
5
  export type GetLayersSuccess<Layers extends ReadonlyArray<Layer.Layer.Any>> = Layers extends
@@ -24,11 +25,46 @@ export type ContextTagWithDefault<Id, A, LayerE, LayerR, Tag = unknown> =
24
25
  & (Tag extends string ? Context.Tag<Id, { _tag: Tag } & A> : Context.Tag<Id, A>)
25
26
  & {
26
27
  Default: Layer.Layer<Id, LayerE, LayerR>
27
- // new(a: A): Id
28
28
  }
29
29
 
30
30
  export namespace ContextTagWithDefault {
31
- export type Base<A> = ContextTagWithDefault<any, any, A, any, any>
31
+ export type Base<A> = ContextTagWithDefault<any, A, any, any, any>
32
32
  }
33
33
 
34
34
  export type GetContext<T> = T extends Context.Context<infer Y> ? Y : never
35
+
36
+ export const mergeContexts = Effect.fnUntraced(
37
+ function*<T extends readonly { maker: any; handle: Effect<Context<any>> }[]>(makers: T) {
38
+ let context = Context.empty()
39
+ for (const mw of makers) {
40
+ yield* InfraLogger.logDebug("Building context for middleware", mw.maker.key ?? mw.maker)
41
+ const moreContext = yield* mw.handle.pipe(Effect.provide(context))
42
+ yield* InfraLogger.logDebug(
43
+ "Built context for middleware",
44
+ mw.maker.key ?? mw.maker,
45
+ (moreContext as any).toJSON().services
46
+ )
47
+ context = Context.merge(context, moreContext)
48
+ }
49
+ return context as Context.Context<Effect.Success<T[number]["handle"]>>
50
+ }
51
+ )
52
+
53
+ export const mergeOptionContexts = Effect.fnUntraced(
54
+ function*<T extends readonly { maker: any; handle: Effect<Option<Context<any>>> }[]>(makers: T) {
55
+ let context = Context.empty()
56
+ for (const mw of makers) {
57
+ yield* InfraLogger.logDebug("Building context for middleware", mw.maker.key ?? mw.maker)
58
+ const moreContext = yield* mw.handle.pipe(Effect.provide(context))
59
+ yield* InfraLogger.logDebug(
60
+ "Built context for middleware",
61
+ mw.maker.key ?? mw.maker,
62
+ Option.map(moreContext, (c) => (c as any).toJSON().services)
63
+ )
64
+ if (moreContext.value) {
65
+ context = Context.merge(context, moreContext.value)
66
+ }
67
+ }
68
+ return context
69
+ }
70
+ )
@@ -1,7 +1,7 @@
1
1
  import { type Array, Context, Effect, Layer, type NonEmptyArray, pipe, type Scope } from "effect-app"
2
2
  import { type HttpRouter } from "effect-app/http"
3
- import { type ContextTagWithDefault, type GetContext, type LayerUtils } from "../../layerUtils.js"
4
- import { mergeContexts } from "./dynamic-middleware.js"
3
+ import { type Tag } from "effect/Context"
4
+ import { type ContextTagWithDefault, type GetContext, type LayerUtils, mergeContexts } from "../../layerUtils.js"
5
5
 
6
6
  // the context provider provides additional stuff
7
7
  export type ContextProviderShape<ContextProviderA, ContextProviderR extends HttpRouter.HttpRouter.Provided> = Effect<
@@ -14,38 +14,44 @@ export interface ContextProviderId {
14
14
  _tag: "ContextProvider"
15
15
  }
16
16
 
17
+ /**
18
+ * TDeps is an array of services with Default implementation
19
+ * each service is an effect which builds some context for each request
20
+ */
21
+ type TDepsArr = Array.NonEmptyReadonlyArray<
22
+ & (
23
+ // E = never => the context provided cannot trigger errors
24
+ // can't put HttpRouter.HttpRouter.Provided as R here because of variance
25
+ // (TDeps is an input type parameter so it's contravariant therefore Effect's R becomes contravariant too)
26
+ | Context.Tag<any, Effect<Context.Context<any>, never, any> & { _tag: any }>
27
+ | Context.Tag<any, Effect<Context.Context<any>, never, never> & { _tag: any }>
28
+ )
29
+ & {
30
+ Default: Layer.Layer<Effect<Context.Context<any>> & { _tag: any }, any, any>
31
+ }
32
+ >
33
+
34
+ type ConstrainDeps<TDeps extends TDepsArr> = {
35
+ [K in keyof TDeps]: TDeps[K]["Service"] extends Effect<Context.Context<any>, never, HttpRouter.HttpRouter.Provided>
36
+ ? TDeps[K]
37
+ : `HttpRouter.HttpRouter.Provided are the only requirements ${TDeps[K]["Service"][
38
+ "_tag"
39
+ ]}'s returned effect can have`
40
+ }
41
+
17
42
  // Note: the type here must be aligned with MergedContextProvider
18
43
  export const mergeContextProviders = <
19
- // TDeps is an array of services whit Default implementation
20
- // each service is an effect which builds some context for each request
21
- TDeps extends Array.NonEmptyReadonlyArray<
22
- & (
23
- // E = never => the context provided cannot trigger errors
24
- // can't put HttpRouter.HttpRouter.Provided as R here because of variance
25
- // (TDeps is an input type parameter so it's contravariant therefore Effect's R becomes contravariant too)
26
- | Context.Tag<any, Effect<Context.Context<any>, never, any> & { _tag: any }>
27
- | Context.Tag<any, Effect<Context.Context<any>, never, never> & { _tag: any }>
28
- )
29
- & {
30
- new(...args: any[]): any
31
- Default: Layer.Layer<Effect<Context.Context<any>> & { _tag: any }, any, any>
32
- }
33
- >
44
+ TDeps extends TDepsArr
34
45
  >(
35
- ...deps: {
36
- [K in keyof TDeps]: TDeps[K]["Service"] extends Effect<Context.Context<any>, never, HttpRouter.HttpRouter.Provided>
37
- ? TDeps[K]
38
- : `HttpRouter.HttpRouter.Provided are the only requirements ${TDeps[K]["Service"][
39
- "_tag"
40
- ]}'s returned effect can have`
41
- }
46
+ ...deps: ConstrainDeps<TDeps>
42
47
  ): {
43
48
  dependencies: { [K in keyof TDeps]: TDeps[K]["Default"] }
44
49
  effect: Effect.Effect<
45
50
  Effect.Effect<
46
- Context.Context<GetContext<Effect.Success<InstanceType<TDeps[number]>>>>,
51
+ // we need to merge all contexts into one
52
+ Context.Context<GetContext<Effect.Success<Tag.Service<TDeps[number]>>>>,
47
53
  never,
48
- Effect.Context<InstanceType<TDeps[number]>>
54
+ Effect.Context<Tag.Service<TDeps[number]>>
49
55
  >,
50
56
  LayerUtils.GetLayersError<{ [K in keyof TDeps]: TDeps[K]["Default"] }>,
51
57
  LayerUtils.GetLayersSuccess<{ [K in keyof TDeps]: TDeps[K]["Default"] }>
@@ -64,6 +70,7 @@ export const mergeContextProviders = <
64
70
  }) as any
65
71
  })
66
72
 
73
+ // Effect Rpc Middleware: for single tag providing, we could use Provides, for providing Context or Layer (bad boy) we could use Wrap..
67
74
  export const ContextProvider = <
68
75
  ContextProviderA,
69
76
  MakeContextProviderE,
@@ -102,29 +109,9 @@ export const ContextProvider = <
102
109
 
103
110
  // Note: the type here must be aligned with mergeContextProviders
104
111
  export const MergedContextProvider = <
105
- // TDeps is an array of services whit Default implementation
106
- // each service is an effect which builds some context for each request
107
- TDeps extends Array.NonEmptyReadonlyArray<
108
- & (
109
- // E = never => the context provided cannot trigger errors
110
- // can't put HttpRouter.HttpRouter.Provided as R here because of variance
111
- // (TDeps is an input type parameter so it's contravariant therefore Effect's R becomes contravariant too)
112
- | Context.Tag<any, Effect<Context.Context<any>, never, any> & { _tag: any }>
113
- | Context.Tag<any, Effect<Context.Context<any>, never, never> & { _tag: any }>
114
- )
115
- & {
116
- new(...args: any[]): any
117
- Default: Layer.Layer<Effect<Context.Context<any>> & { _tag: any }, any, any>
118
- }
119
- >
112
+ TDeps extends TDepsArr
120
113
  >(
121
- ...deps: {
122
- [K in keyof TDeps]: TDeps[K]["Service"] extends Effect<Context.Context<any>, never, HttpRouter.HttpRouter.Provided>
123
- ? TDeps[K]
124
- : `HttpRouter.HttpRouter.Provided are the only requirements ${TDeps[K]["Service"][
125
- "_tag"
126
- ]}'s returned effect can have`
127
- }
114
+ ...deps: ConstrainDeps<TDeps>
128
115
  ) =>
129
116
  pipe(
130
117
  deps as [Parameters<typeof mergeContextProviders>[0]],
@@ -133,13 +120,14 @@ export const MergedContextProvider = <
133
120
  ) as unknown as ContextTagWithDefault<
134
121
  ContextProviderId,
135
122
  Effect.Effect<
136
- Context.Context<GetContext<Effect.Success<InstanceType<TDeps[number]>>>>,
123
+ // we need to merge all contexts into one
124
+ Context.Context<GetContext<Effect.Success<Tag.Service<TDeps[number]>>>>,
137
125
  never,
138
- Effect.Context<InstanceType<TDeps[number]>>
126
+ Effect.Context<Tag.Service<TDeps[number]>>
139
127
  >,
140
128
  LayerUtils.GetLayersError<{ [K in keyof TDeps]: TDeps[K]["Default"] }>,
141
129
  | Exclude<
142
- InstanceType<TDeps[number]>,
130
+ Tag.Service<TDeps[number]>,
143
131
  LayerUtils.GetLayersSuccess<{ [K in keyof TDeps]: TDeps[K]["Default"] }>
144
132
  >
145
133
  | LayerUtils.GetLayersContext<{ [K in keyof TDeps]: TDeps[K]["Default"] }>
@@ -3,7 +3,7 @@
3
3
  /* eslint-disable @typescript-eslint/no-explicit-any */
4
4
  import { Context, Effect, Layer, type NonEmptyArray, type Request, type S, type Scope } from "effect-app"
5
5
  import type { GetEffectContext, RPCContextMap } from "effect-app/client/req"
6
- import { type HttpRouter } from "effect-app/http"
6
+ import { HttpHeaders, type HttpRouter, HttpServerRequest } from "effect-app/http"
7
7
  import type * as EffectRequest from "effect/Request"
8
8
  import { type ContextTagWithDefault, type LayerUtils } from "../../layerUtils.js"
9
9
  import { type ContextProviderId, type ContextProviderShape } from "./ContextProvider.js"
@@ -23,7 +23,7 @@ export type MakeRPCHandlerFactory<
23
23
  HandlerR
24
24
  >(
25
25
  schema: T & S.Schema<Req, any, never>,
26
- handler: (
26
+ next: (
27
27
  request: Req,
28
28
  headers: any
29
29
  ) => Effect.Effect<
@@ -56,7 +56,7 @@ export type RPCHandlerFactory<
56
56
  HandlerR
57
57
  >(
58
58
  schema: T & S.Schema<Req, any, never>,
59
- handler: (
59
+ next: (
60
60
  request: Req,
61
61
  headers: any
62
62
  ) => Effect.Effect<
@@ -76,7 +76,7 @@ export type RPCHandlerFactory<
76
76
  // the middleware will remove from HandlerR the dynamic context
77
77
  // & S.Schema<Req, any, never> is useless here but useful when creating the middleware
78
78
  Exclude<HandlerR, GetEffectContext<RequestContextMap, (T & S.Schema<Req, any, never>)["config"]>>,
79
- // the context provider provides additional stuff both to the middleware and the handler
79
+ // the context provider provides additional stuff both to the middleware and the next
80
80
  ContextProviderA
81
81
  >
82
82
  >
@@ -90,7 +90,7 @@ type RequestContextMapProvider<RequestContextMap extends Record<string, RPCConte
90
90
  }
91
91
 
92
92
  export interface MiddlewareMake<
93
- RequestContextMap extends Record<string, RPCContextMap.Any>, // what services will the middleware provide dynamically to the handler, or raise errors.
93
+ RequestContextMap extends Record<string, RPCContextMap.Any>, // what services will the middleware provide dynamically to the next, or raise errors.
94
94
  //
95
95
  // ContextProvider is a service that builds additional context for each request.
96
96
  ContextProviderA, // what the context provider provides
@@ -117,9 +117,9 @@ export interface MiddlewareMake<
117
117
  MakeContextProviderR
118
118
  >
119
119
 
120
- /* dependencies for the main middleware running just before the handler is called */
120
+ /* dependencies for the main middleware running just before the next is called */
121
121
  dependencies?: MiddlewareDependencies
122
- // this actually builds "the middleware", i.e. returns the augmented handler factory when yielded...
122
+ // this actually builds "the middleware", i.e. returns the augmented next factory when yielded...
123
123
  execute?: (
124
124
  maker: (
125
125
  // MiddlewareR is set to ContextProviderA | HttpRouter.HttpRouter.Provided because that's what, at most
@@ -138,7 +138,7 @@ export interface MiddlewareMakerId {
138
138
  }
139
139
 
140
140
  export type Middleware<
141
- RequestContextMap extends Record<string, RPCContextMap.Any>, // what services will the middlware provide dynamically to the handler, or raise errors.
141
+ RequestContextMap extends Record<string, RPCContextMap.Any>, // what services will the middlware provide dynamically to the next, or raise errors.
142
142
  MakeMiddlewareE, // what the middleware construction can fail with
143
143
  MakeMiddlewareR, // what the middlware requires to be constructed
144
144
  ContextProviderA // what the context provider provides
@@ -190,7 +190,6 @@ export const makeMiddleware =
190
190
  MiddlewareDependencies
191
191
  >
192
192
  ) => {
193
- // type Id = MiddlewareMakerId &
194
193
  const MiddlewareMaker = Context.GenericTag<
195
194
  MiddlewareMakerId,
196
195
  {
@@ -216,35 +215,47 @@ export const makeMiddleware =
216
215
  ) => cb)
217
216
  : Effect.succeed<
218
217
  MakeRPCHandlerFactory<RequestContextMap, ContextProviderA | HttpRouter.HttpRouter.Provided>
219
- >((_schema, handle) => (req, headers) => handle(req, headers)),
218
+ >((_schema, next) => (payload, headers) => next(payload, headers)),
220
219
  contextProvider: make.contextProvider // uses the middleware.contextProvider tag to get the context provider service
221
220
  })
222
221
  .pipe(
223
222
  Effect.map(({ contextProvider, dynamicMiddlewares, generic, middleware }) => ({
224
223
  _tag: "MiddlewareMaker" as const,
225
224
  effect: makeRpcEffect<RequestContextMap, ContextProviderA>()(
226
- (schema, handler, moduleName) => {
227
- const h = middleware(schema, handler as any, moduleName)
228
- return generic(
229
- Effect.fnUntraced(function*(req, headers) {
230
- yield* Effect.annotateCurrentSpan(
231
- "request.name",
232
- moduleName ? `${moduleName}.${req._tag}` : req._tag
233
- )
225
+ (schema, next, moduleName) => {
226
+ const h = middleware(schema, next as any, moduleName)
227
+ return (payload, rpcHeaders) =>
228
+ Effect.gen(function*() {
229
+ // TODO: perhaps this should be part of Protocol instead.
230
+ // the alternative is that UserProfile handling is part of Http Middleware instead of Rpc Middleware..
231
+ // the Rpc Middleware then just needs to confirm if it's there..
232
+ const req = yield* HttpServerRequest.HttpServerRequest
233
+ const headers = HttpHeaders.merge(req.headers, rpcHeaders)
234
+ return yield* generic({
235
+ payload,
236
+ headers,
237
+ rpc: { _tag: `${moduleName}.${payload._tag}` }, // todo: make moduleName part of the tag on S.Req creation.
238
+ next: Effect.gen(function*() {
239
+ yield* Effect.annotateCurrentSpan(
240
+ "request.name",
241
+ moduleName ? `${moduleName}.${payload._tag}` : payload._tag
242
+ )
234
243
 
235
- // the contextProvider is an Effect that builds the context for the request
236
- return yield* contextProvider.pipe(
237
- Effect.flatMap((contextProviderContext) =>
238
- // the dynamicMiddlewares is an Effect that builds the dynamiuc context for the request
239
- dynamicMiddlewares(schema.config ?? {}, headers).pipe(
240
- Effect.flatMap((dynamicContext) => h(req, headers).pipe(Effect.provide(dynamicContext))),
241
- Effect.provide(contextProviderContext)
244
+ // the contextProvider is an Effect that builds the context for the request
245
+ return yield* contextProvider.pipe(
246
+ Effect.flatMap((contextProviderContext) =>
247
+ // the dynamicMiddlewares is an Effect that builds the dynamiuc context for the request
248
+ dynamicMiddlewares(schema.config ?? {}, headers).pipe(
249
+ Effect.flatMap((dynamicContext) =>
250
+ h(payload, headers).pipe(Effect.provide(dynamicContext))
251
+ ),
252
+ Effect.provide(contextProviderContext)
253
+ )
254
+ )
242
255
  )
243
- )
244
- )
245
- }) as any,
246
- moduleName
247
- )
256
+ }) as any
257
+ })
258
+ }) as any // why?
248
259
  }
249
260
  )
250
261
  }))
@@ -291,7 +302,7 @@ function makeRpcEffect<
291
302
  HandlerR
292
303
  >(
293
304
  schema: T & S.Schema<Req, any, never>,
294
- handler: (
305
+ next: (
295
306
  request: Req,
296
307
  headers: any
297
308
  ) => Effect.Effect<