@effect-app/infra 2.94.0 → 3.0.1

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 (52) hide show
  1. package/CHANGELOG.md +19 -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/QueueMaker/errors.d.ts +1 -1
  6. package/dist/QueueMaker/errors.d.ts.map +1 -1
  7. package/dist/RequestFiberSet.d.ts +1 -1
  8. package/dist/Store/service.d.ts +2 -2
  9. package/dist/adapters/SQL/Model.d.ts +6 -6
  10. package/dist/adapters/ServiceBus.d.ts +2 -2
  11. package/dist/adapters/ServiceBus.d.ts.map +1 -1
  12. package/dist/adapters/ServiceBus.js +13 -10
  13. package/dist/adapters/memQueue.d.ts +1 -1
  14. package/dist/api/routing/middleware/RouterMiddleware.d.ts +7 -7
  15. package/dist/api/routing/middleware/RouterMiddleware.d.ts.map +1 -1
  16. package/dist/api/routing/middleware/middleware.d.ts +6 -27
  17. package/dist/api/routing/middleware/middleware.d.ts.map +1 -1
  18. package/dist/api/routing/middleware/middleware.js +72 -88
  19. package/dist/api/routing/middleware.d.ts +0 -3
  20. package/dist/api/routing/middleware.d.ts.map +1 -1
  21. package/dist/api/routing/middleware.js +1 -4
  22. package/dist/api/routing.d.ts +1 -2
  23. package/dist/api/routing.d.ts.map +1 -1
  24. package/dist/api/routing.js +2 -8
  25. package/package.json +3 -15
  26. package/src/adapters/ServiceBus.ts +7 -5
  27. package/src/api/routing/middleware/RouterMiddleware.ts +10 -9
  28. package/src/api/routing/middleware/middleware.ts +35 -40
  29. package/src/api/routing/middleware.ts +0 -3
  30. package/src/api/routing.ts +3 -9
  31. package/test/controller.test.ts +33 -9
  32. package/test/dist/controller.test.d.ts.map +1 -1
  33. package/test/dist/fixtures.d.ts +48 -32
  34. package/test/dist/fixtures.d.ts.map +1 -1
  35. package/test/dist/fixtures.js +76 -47
  36. package/test/dist/requires.test.d.ts.map +1 -1
  37. package/test/dist/rpc-multi-middleware.test.d.ts.map +1 -0
  38. package/test/fixtures.ts +70 -16
  39. package/test/requires.test.ts +16 -51
  40. package/test/rpc-multi-middleware.test.ts +134 -0
  41. package/dist/api/routing/middleware/RpcMiddleware.d.ts +0 -199
  42. package/dist/api/routing/middleware/RpcMiddleware.d.ts.map +0 -1
  43. package/dist/api/routing/middleware/RpcMiddleware.js +0 -14
  44. package/dist/api/routing/middleware/generic-middleware.d.ts +0 -41
  45. package/dist/api/routing/middleware/generic-middleware.d.ts.map +0 -1
  46. package/dist/api/routing/middleware/generic-middleware.js +0 -70
  47. package/dist/api/routing/middleware/middleware-api.d.ts +0 -88
  48. package/dist/api/routing/middleware/middleware-api.d.ts.map +0 -1
  49. package/dist/api/routing/middleware/middleware-api.js +0 -58
  50. package/src/api/routing/middleware/RpcMiddleware.ts +0 -301
  51. package/src/api/routing/middleware/generic-middleware.ts +0 -163
  52. package/src/api/routing/middleware/middleware-api.ts +0 -226
@@ -1,58 +0,0 @@
1
- import { Context, S } from "effect-app";
2
- import { middlewareMaker } from "./generic-middleware.js";
3
- import { Tag } from "./RpcMiddleware.js";
4
- /** Adapter used when setting the dynamic prop on a middleware implementation */
5
- export const contextMap = (rcm, key) => ({
6
- key,
7
- settings: { service: rcm[key]["service"] }
8
- });
9
- /** Retrieves RequestContextConfig out of the RPC annotations */
10
- export const getConfig = () => (rpc) => {
11
- return Context.unsafeGet(rpc.annotations, Context.GenericTag("RequestContextConfig"));
12
- };
13
- export const makeMiddleware = (rcm) => {
14
- let allMiddleware = [];
15
- const it = {
16
- middleware: (...middlewares) => {
17
- for (const mw of middlewares) {
18
- // recall that we run middlewares in reverse order
19
- allMiddleware = [mw, ...allMiddleware];
20
- }
21
- return allMiddleware.filter((m) => !!m.dynamic).length !== Object.keys(rcm).length
22
- // for sure, until all the dynamic middlewares are provided it's non sensical to call makeMiddlewareBasic
23
- ? it
24
- // actually, we don't know yet if MiddlewareR is never, but we can't easily check it at runtime
25
- : Object.assign(makeMiddlewareBasic(rcm, ...allMiddleware), it);
26
- }
27
- };
28
- return it;
29
- };
30
- const makeMiddlewareBasic =
31
- // by setting RequestContextMap beforehand, execute contextual typing does not fuck up itself to anys
32
- (_rcm, ...make) => {
33
- // reverse middlewares and wrap one after the other
34
- const middleware = middlewareMaker(make);
35
- const failures = make.map((_) => _.failure).filter(Boolean);
36
- const provides = make.flatMap((_) => !_.provides ? [] : Array.isArray(_.provides) ? _.provides : [_.provides]);
37
- const requires = make
38
- .flatMap((_) => !_.requires ? [] : Array.isArray(_.requires) ? _.requires : [_.requires])
39
- .filter((_) => !provides.includes(_));
40
- const MiddlewareMaker = Tag()("MiddlewareMaker", {
41
- failure: (failures.length > 0
42
- ? S.Union(...failures)
43
- : S.Never),
44
- requires: (requires.length > 0
45
- ? requires
46
- : undefined),
47
- provides: (provides.length > 0
48
- ? provides
49
- : undefined),
50
- wrap: true
51
- })(middleware);
52
- // add to the tag a default implementation
53
- return Object.assign(MiddlewareMaker, {
54
- // tag to be used to retrieve the RequestContextConfig from RPC annotations
55
- requestContext: Context.GenericTag("RequestContextConfig")
56
- });
57
- };
58
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWlkZGxld2FyZS1hcGkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvYXBpL3JvdXRpbmcvbWlkZGxld2FyZS9taWRkbGV3YXJlLWFwaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLEVBQUUsT0FBTyxFQUErRCxDQUFDLEVBQUUsTUFBTSxZQUFZLENBQUE7QUFHcEcsT0FBTyxFQUF3QixlQUFlLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQTtBQUMvRSxPQUFPLEVBQW9DLEdBQUcsRUFBb0IsTUFBTSxvQkFBb0IsQ0FBQTtBQUU1RixnRkFBZ0Y7QUFDaEYsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHLENBR3hCLEdBQXNCLEVBQUUsR0FBUSxFQUEyQyxFQUFFLENBQUMsQ0FBQztJQUMvRSxHQUFHO0lBQ0gsUUFBUSxFQUFFLEVBQUUsT0FBTyxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUUsQ0FBQyxTQUFTLENBQUMsRUFBNEI7Q0FDdEUsQ0FBQyxDQUFBO0FBRUYsZ0VBQWdFO0FBQ2hFLE1BQU0sQ0FBQyxNQUFNLFNBQVMsR0FBRyxHQUVyQixFQUFFLENBQ04sQ0FBQyxHQUFpQixFQUF1QyxFQUFFO0lBQ3pELE9BQU8sT0FBTyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFLE9BQU8sQ0FBQyxVQUFVLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFBO0FBQ3ZGLENBQUMsQ0FBQTtBQWtIRCxNQUFNLENBQUMsTUFBTSxjQUFjLEdBRTBDLENBQUMsR0FBRyxFQUFFLEVBQUU7SUFDM0UsSUFBSSxhQUFhLEdBQXNCLEVBQUUsQ0FBQTtJQUN6QyxNQUFNLEVBQUUsR0FBRztRQUNULFVBQVUsRUFBRSxDQUFDLEdBQUcsV0FBa0IsRUFBRSxFQUFFO1lBQ3BDLEtBQUssTUFBTSxFQUFFLElBQUksV0FBVyxFQUFFLENBQUM7Z0JBQzdCLGtEQUFrRDtnQkFDbEQsYUFBYSxHQUFHLENBQUMsRUFBRSxFQUFFLEdB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
@@ -1,301 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-unsafe-assignment */
2
- /* eslint-disable @typescript-eslint/no-unsafe-return */
3
- /* eslint-disable @typescript-eslint/no-explicit-any */
4
- import { type Rpc, RpcMiddleware } from "@effect/rpc"
5
- import { type SuccessValue, type TypeId } from "@effect/rpc/RpcMiddleware"
6
- import { type Context, type Effect, Layer, type NonEmptyReadonlyArray, type Option, type S, type Schema, type Scope, Unify } from "effect-app"
7
- import type { AnyService, ContextTagArray, RPCContextMap } from "effect-app/client/req"
8
- import { type HttpHeaders } from "effect-app/http"
9
- import { type TagUnify, type TagUnifyIgnore } from "effect/Context"
10
- import { type Service } from "effect/Effect"
11
-
12
- // updated to support Scope.Scope and Requires
13
- export interface RpcMiddleware<Provides, E, Requires> {
14
- (options: {
15
- readonly clientId: number
16
- readonly rpc: Rpc.AnyWithProps
17
- readonly payload: unknown
18
- readonly headers: HttpHeaders.Headers
19
- }): Effect.Effect<Provides, E, Scope.Scope | Requires>
20
- }
21
- export interface RpcMiddlewareWrap<Provides, E, Requires> {
22
- (options: {
23
- readonly clientId: number
24
- readonly rpc: Rpc.AnyWithProps
25
- readonly payload: unknown
26
- readonly headers: HttpHeaders.Headers
27
- readonly next: Effect.Effect<SuccessValue, E, Provides | Scope.Scope | Requires>
28
- }): Effect.Effect<SuccessValue, E, Scope.Scope | Requires>
29
- }
30
-
31
- type RpcOptionsOriginal = {
32
- readonly wrap?: boolean
33
- readonly optional?: boolean
34
- readonly failure?: Schema.Schema.All
35
- readonly provides?: AnyService
36
- readonly requiredForClient?: boolean
37
- }
38
-
39
- export type RpcDynamic<Key extends string, A extends RPCContextMap.Any> = {
40
- key: Key
41
- settings: A
42
- }
43
-
44
- export type AnyDynamic = { dynamic: RpcDynamic<any, any> }
45
-
46
- export type DependsOn = {
47
- readonly dependsOn: NonEmptyReadonlyArray<AnyDynamic> | undefined
48
- }
49
-
50
- interface RpcOptionsDynamic<Key extends string, A extends RPCContextMap.Any> extends RpcOptionsOriginal {
51
- readonly dynamic: RpcDynamic<Key, A>
52
- readonly dependsOn?: NonEmptyReadonlyArray<AnyDynamic> | undefined
53
- }
54
-
55
- export type Dynamic<Options> = Options extends RpcOptionsDynamic<any, any> ? true : false
56
-
57
- export interface RpcMiddlewareDynamicWrap<E, R, _Config> {
58
- (options: {
59
- readonly next: Effect.Effect<SuccessValue, E, Scope.Scope | R>
60
- readonly clientId: number
61
- readonly rpc: Rpc.AnyWithProps // TODO & { annotations: Context.Context<RequestContextMap<Config>> }
62
- readonly payload: unknown
63
- readonly headers: HttpHeaders.Headers
64
- }): Effect.Effect<
65
- SuccessValue,
66
- E,
67
- Scope.Scope | R
68
- >
69
- }
70
-
71
- export interface RpcMiddlewareDynamicNormal<A, E, R, _Config> {
72
- (options: {
73
- readonly clientId: number
74
- readonly rpc: Rpc.AnyWithProps // TODO & { annotations: Context.Context<RequestContextMap<Config>> }
75
- readonly payload: unknown
76
- readonly headers: HttpHeaders.Headers
77
- }): Effect.Effect<
78
- Option.Option<A>,
79
- E,
80
- Scope.Scope | R
81
- >
82
- }
83
-
84
- export interface TagClassAny extends Context.Tag<any, any> {
85
- readonly [TypeId]: TypeId
86
- readonly optional: boolean
87
- readonly provides?: Context.Tag<any, any> | ContextTagArray | undefined
88
- readonly requires?: Context.Tag<any, any> | ContextTagArray | undefined
89
- readonly failure: Schema.Schema.All
90
- readonly requiredForClient: boolean
91
- readonly wrap: boolean
92
- readonly dynamic?: RpcDynamic<any, any> | undefined
93
- readonly dependsOn?: NonEmptyReadonlyArray<AnyDynamic> | undefined
94
- }
95
-
96
- export declare namespace TagClass {
97
- /**
98
- * @since 1.0.0
99
- * @category models
100
- */
101
- export type Provides<Options> = Options extends {
102
- readonly provides: Context.Tag<any, any>
103
- readonly optional?: false
104
- } ? Context.Tag.Identifier<Options["provides"]>
105
- : Options extends {
106
- readonly provides: ContextTagArray
107
- readonly optional?: false
108
- } ? ContextTagArray.Identifier<Options["provides"]>
109
- : never
110
-
111
- /**
112
- * @since 1.0.0
113
- * @category models
114
- */
115
- export type Requires<Options> = Options extends {
116
- readonly requires: Context.Tag<any, any>
117
- } ? Context.Tag.Identifier<Options["requires"]>
118
- : Options extends {
119
- readonly requires: ContextTagArray
120
- } ? ContextTagArray.Identifier<Options["requires"]>
121
- : never
122
-
123
- /**
124
- * @since 1.0.0
125
- * @category models
126
- */
127
- export type Service<Options> = Options extends { readonly provides: Context.Tag<any, any> }
128
- ? Context.Tag.Service<Options["provides"]>
129
- : Options extends { readonly dynamic: RpcDynamic<any, infer A> }
130
- ? Options extends { wrap: true } ? void : AnyService.Bla<A["service"]>
131
- : Options extends { readonly provides: ContextTagArray }
132
- ? Context.Context<ContextTagArray.Identifier<Options["provides"]>>
133
- : void
134
-
135
- /**
136
- * @since 1.0.0
137
- * @category models
138
- */
139
- export type FailureSchema<Options> = Options extends
140
- { readonly failure: Schema.Schema.All; readonly optional?: false } ? Options["failure"]
141
- // actually not, the Failure depends on Dynamic Middleware Configuration!
142
- // : Options extends { readonly dynamic: RpcDynamic<any, infer A> } ? A["error"]
143
- : typeof Schema.Never
144
-
145
- /**
146
- * @since 1.0.0
147
- * @category models
148
- */
149
- export type Failure<Options> = Options extends
150
- { readonly failure: Schema.Schema<infer _A, infer _I, infer _R>; readonly optional?: false } ? _A
151
- // actually not, the Failure depends on Dynamic Middleware Configuration!
152
- : Options extends { readonly dynamic: RpcDynamic<any, infer A> } ? S.Schema.Type<A["error"]>
153
- : never
154
-
155
- /**
156
- * @since 1.0.0
157
- * @category models
158
- */
159
- export type FailureContext<Options> = Schema.Schema.Context<FailureSchema<Options>>
160
-
161
- /**
162
- * @since 1.0.0
163
- * @category models
164
- */
165
- export type FailureService<Options> = Optional<Options> extends true ? unknown : Failure<Options>
166
-
167
- /**
168
- * @since 1.0.0
169
- * @category models
170
- */
171
- export type Optional<Options> = Options extends { readonly optional: true } ? true : false
172
-
173
- /**
174
- * @since 1.0.0
175
- * @category models
176
- */
177
- export type RequiredForClient<Options> = Options extends { readonly requiredForClient: true } ? true : false
178
-
179
- /**
180
- * @since 1.0.0
181
- * @category models
182
- */
183
- export type Wrap<Options> = Options extends { readonly wrap: true } ? true : false
184
-
185
- /**
186
- * @since 1.0.0
187
- * @category models
188
- */
189
- export interface Base<Self, Name extends string, Options, Service> extends Context.Tag<Self, Service> {
190
- new(_: never): Context.TagClassShape<Name, Service>
191
- readonly [TypeId]: TypeId
192
- readonly optional: Optional<Options>
193
- readonly failure: FailureSchema<Options>
194
- readonly provides: Options extends { readonly provides: Context.Tag<any, any> } ? Options["provides"]
195
- : Options extends { readonly provides: ContextTagArray } ? Options["provides"]
196
- : undefined
197
- readonly requires: Options extends { readonly requires: Context.Tag<any, any> } ? Options["requires"]
198
- : Options extends { readonly requires: ContextTagArray } ? Options["requires"]
199
- : undefined
200
- readonly dynamic: Options extends RpcOptionsDynamic<any, any> ? Options["dynamic"]
201
- : undefined
202
- readonly dependsOn: Options extends DependsOn ? Options["dependsOn"] : undefined
203
- readonly requiredForClient: RequiredForClient<Options>
204
- readonly wrap: Wrap<Options>
205
- }
206
- }
207
-
208
- export interface TagClass<
209
- Self,
210
- Name extends string,
211
- Options
212
- > extends
213
- TagClass.Base<
214
- Self,
215
- Name,
216
- Options,
217
- Options extends RpcOptionsDynamic<any, any> ? TagClass.Wrap<Options> extends true ? RpcMiddlewareDynamicWrap<
218
- TagClass.FailureService<Options>,
219
- TagClass.Requires<Options>,
220
- { [K in Options["dynamic"]["key"]]?: Options["dynamic"]["settings"]["contextActivation"] }
221
- >
222
- : RpcMiddlewareDynamicNormal<
223
- TagClass.Service<Options>,
224
- TagClass.FailureService<Options>,
225
- TagClass.Requires<Options>,
226
- { [K in Options["dynamic"]["key"]]?: Options["dynamic"]["settings"]["contextActivation"] }
227
- >
228
- : TagClass.Wrap<Options> extends true ? RpcMiddlewareWrap<
229
- TagClass.Provides<Options>,
230
- TagClass.Failure<Options>,
231
- TagClass.Requires<Options>
232
- >
233
- : RpcMiddleware<
234
- TagClass.Service<Options>,
235
- TagClass.FailureService<Options>,
236
- TagClass.Requires<Options>
237
- >
238
- >
239
- {}
240
-
241
- export const Tag = <Self>() =>
242
- <
243
- const Name extends string,
244
- const Options extends RpcOptionsOriginal | RpcOptionsDynamic<any, any>
245
- >(
246
- id: Name,
247
- options?: Options | undefined
248
- ) =>
249
- <
250
- LayerOpts extends {
251
- effect: Effect.Effect<
252
- Options extends RpcOptionsDynamic<any, any> ? TagClass.Wrap<Options> extends true ? RpcMiddlewareDynamicWrap<
253
- TagClass.FailureService<Options>,
254
- TagClass.Requires<Options>,
255
- { [K in Options["dynamic"]["key"]]?: Options["dynamic"]["settings"]["contextActivation"] }
256
- >
257
- : RpcMiddlewareDynamicNormal<
258
- TagClass.Service<Options>,
259
- TagClass.FailureService<Options>,
260
- TagClass.Requires<Options>,
261
- { [K in Options["dynamic"]["key"]]?: Options["dynamic"]["settings"]["contextActivation"] }
262
- >
263
- : TagClass.Wrap<Options> extends true ? RpcMiddlewareWrap<
264
- TagClass.Provides<Options>,
265
- TagClass.Failure<Options>,
266
- TagClass.Requires<Options>
267
- >
268
- : RpcMiddleware<
269
- TagClass.Service<Options>,
270
- TagClass.FailureService<Options>,
271
- TagClass.Requires<Options>
272
- >,
273
- any,
274
- any
275
- >
276
- // TODO: we really should only support NonEmtyReadonlyArray because ReadonlyArray fucks up once you have a Layer.empty in the list, as the whole thing resolves to never
277
- dependencies?: NonEmptyReadonlyArray<Layer.Layer.Any> | ReadonlyArray<Layer.Layer.Any>
278
- }
279
- >(opts: LayerOpts): TagClass<Self, Name, Options> & {
280
- Default: Layer.Layer<
281
- Self,
282
- | (LayerOpts extends { effect: Effect<infer _A, infer _E, infer _R> } ? _E
283
- : never)
284
- | Service.MakeDepsE<LayerOpts>,
285
- | Exclude<
286
- LayerOpts extends { effect: Effect<infer _A, infer _E, infer _R> } ? _R : never,
287
- Service.MakeDepsOut<LayerOpts>
288
- >
289
- | Service.MakeDepsIn<LayerOpts>
290
- >
291
- } =>
292
- class extends RpcMiddleware.Tag<Self>()(id, options as any) {
293
- static readonly dynamic = options && "dynamic" in options ? options.dynamic : undefined
294
- static readonly dependsOn = options && "dependsOn" in options ? options.dependsOn : undefined
295
- static readonly Default = Layer.scoped(this, opts.effect as any).pipe(
296
- Layer.provide([Layer.empty, ...opts.dependencies ?? []])
297
- )
298
- static override [Unify.typeSymbol]?: unknown
299
- static override [Unify.unifySymbol]?: TagUnify<typeof this>
300
- static override [Unify.ignoreSymbol]?: TagUnifyIgnore
301
- } as any
@@ -1,163 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import { type RpcMiddleware } from "@effect/rpc"
3
- import { Context, Effect, type Layer, type NonEmptyReadonlyArray, Option, type S, type Scope } from "effect-app"
4
- import { type ContextTagArray } from "effect-app/client"
5
- import { InfraLogger } from "../../../logger.js"
6
- import { type RpcMiddlewareWrap, type TagClassAny } from "./RpcMiddleware.js"
7
-
8
- // Effect rpc middleware does not support changing payload or headers, but we do..
9
-
10
- export type MiddlewareMaker = TagClassAny & { Default: Layer.Layer.Any } // todo; and Layer..
11
-
12
- export namespace MiddlewareMaker {
13
- export type ApplyServices<A extends TagClassAny, R> = Exclude<R, Provided<A>> | Required<A>
14
-
15
- export type ApplyManyServices<A extends NonEmptyReadonlyArray<TagClassAny>, R> =
16
- | Exclude<R, { [K in keyof A]: Provided<A[K]> }[number]>
17
- | { [K in keyof A]: Required<A[K]> }[number]
18
-
19
- export type ManyProvided<A extends ReadonlyArray<TagClassAny>> = A extends NonEmptyReadonlyArray<TagClassAny>
20
- ? { [K in keyof A]: Provided<A[K]> }[number]
21
- : Provided<A[number]>
22
- export type ManyRequired<A extends ReadonlyArray<TagClassAny>> = A extends NonEmptyReadonlyArray<TagClassAny>
23
- ? { [K in keyof A]: Required<A[K]> }[number]
24
- : Required<A[number]>
25
- export type ManyErrors<A extends ReadonlyArray<TagClassAny>> = A extends NonEmptyReadonlyArray<TagClassAny>
26
- ? { [K in keyof A]: Errors<A[K]> }[number]
27
- : Errors<A[number]>
28
-
29
- export type Provided<T> = T extends TagClassAny
30
- ? T extends { provides: Context.Tag<any, any> } ? Context.Tag.Identifier<T["provides"]>
31
- : T extends { provides: ContextTagArray } ? ContextTagArray.Identifier<T["provides"]>
32
- : never
33
- : never
34
-
35
- export type Errors<T> = T extends TagClassAny ? T extends { failure: S.Schema.Any } ? S.Schema.Type<T["failure"]>
36
- : never
37
- : never
38
-
39
- export type Required<T> = T extends TagClassAny
40
- ? T extends { requires: Context.Tag<any, any> } ? Context.Tag.Identifier<T["requires"]>
41
- : T extends { requires: ContextTagArray } ? ContextTagArray.Identifier<T["requires"]>
42
- : never
43
- : never
44
- }
45
-
46
- export const middlewareMaker = <
47
- MiddlewareProviders extends ReadonlyArray<MiddlewareMaker>
48
- >(middlewares: MiddlewareProviders): {
49
- dependencies: { [K in keyof MiddlewareProviders]: MiddlewareProviders[K]["Default"] }
50
- effect: Effect.Effect<
51
- RpcMiddlewareWrap<
52
- MiddlewareMaker.ManyProvided<MiddlewareProviders>,
53
- MiddlewareMaker.ManyErrors<MiddlewareProviders>,
54
- Exclude<
55
- MiddlewareMaker.ManyRequired<MiddlewareProviders>,
56
- MiddlewareMaker.ManyProvided<MiddlewareProviders>
57
- > extends never ? never
58
- : Exclude<MiddlewareMaker.ManyRequired<MiddlewareProviders>, MiddlewareMaker.ManyProvided<MiddlewareProviders>>
59
- >
60
- >
61
- } => {
62
- // we want to run them in reverse order because latter middlewares will provide context to former ones
63
- middlewares = middlewares.toReversed() as any
64
-
65
- return {
66
- dependencies: middlewares.map((_) => _.Default),
67
- effect: Effect.gen(function*() {
68
- const context = yield* Effect.context()
69
-
70
- // returns a Effect/RpcMiddlewareWrap with Scope in requirements
71
- return (
72
- options: Parameters<
73
- RpcMiddlewareWrap<
74
- MiddlewareMaker.ManyProvided<MiddlewareProviders>,
75
- never,
76
- Scope.Scope
77
- >
78
- >[0]
79
- ) => {
80
- // we start with the actual handler
81
- let handler = options.next
82
-
83
- // inspired from Effect/RpcMiddleware
84
- for (const tag of middlewares) {
85
- if (tag.wrap) {
86
- // use the tag to get the middleware from context
87
- const middleware = Context.unsafeGet(context, tag)
88
-
89
- // wrap the current handler, allowing the middleware to run before and after it
90
- handler = InfraLogger.logDebug("Applying middleware wrap " + tag.key).pipe(
91
- Effect.zipRight(middleware({ ...options, next: handler }))
92
- ) as any
93
- } else if (tag.optional) {
94
- // use the tag to get the middleware from context
95
- // if the middleware fails to run, we will ignore the error
96
- const middleware = Context.unsafeGet(context, tag) as RpcMiddleware.RpcMiddleware<any, any>
97
-
98
- const previous = handler
99
-
100
- // set the previous handler to run after the middleware
101
- // if the middleware is not present, we just return the previous handler
102
- // otherwise the middleware will provide some context to be provided to the previous handler
103
- handler = InfraLogger.logDebug("Applying middleware optional " + tag.key).pipe(
104
- Effect.zipRight(Effect.matchEffect(middleware(options), {
105
- onFailure: () => previous,
106
- onSuccess: tag.provides !== undefined
107
- ? (value) =>
108
- Context.isContext(value)
109
- ? Effect.provide(previous, value)
110
- : Effect.provideService(previous, tag.provides as any, value)
111
- : (_) => previous
112
- }))
113
- )
114
- } else if (tag.dynamic) {
115
- // use the tag to get the middleware from context
116
- const middleware = Context.unsafeGet(context, tag) as RpcMiddleware.RpcMiddleware<any, any>
117
-
118
- const previous = handler
119
-
120
- // set the previous handler to run after the middleware
121
- // we do expect the middleware to be present, but the context might not be available
122
- // if it is, we provide it to the previous handler
123
- handler = InfraLogger.logDebug("Applying middleware dynamic " + tag.key, tag.dynamic).pipe(
124
- Effect.zipRight(
125
- middleware(options).pipe(
126
- Effect.flatMap((o) =>
127
- Option.isSome(o)
128
- ? Context.isContext(o.value)
129
- ? Effect.provide(previous, o.value)
130
- : Effect.provideService(previous, tag.dynamic!.settings.service!, /* TODO */ o.value)
131
- : previous
132
- )
133
- )
134
- )
135
- ) as any
136
- } else {
137
- // use the tag to get the middleware from context
138
- const middleware = Context.unsafeGet(context, tag) as RpcMiddleware.RpcMiddleware<any, any>
139
-
140
- const previous = handler
141
-
142
- // set the previous handler to run after the middleware
143
- // we do expect both the middleware and the context to be present
144
- handler = InfraLogger.logDebug("Applying middleware " + tag.key).pipe(
145
- Effect.zipRight(
146
- tag.provides !== undefined
147
- ? middleware(options).pipe(
148
- Effect.flatMap((value) =>
149
- Context.isContext(value)
150
- ? Effect.provide(previous, value)
151
- : Effect.provideService(previous, tag.provides as any, value)
152
- )
153
- )
154
- : Effect.zipRight(middleware(options), previous)
155
- )
156
- ) as any
157
- }
158
- }
159
- return handler
160
- }
161
- })
162
- } as any
163
- }