@effect-app/infra 2.85.0 → 2.87.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/CHANGELOG.md +17 -0
- package/dist/api/layerUtils.d.ts +4 -8
- package/dist/api/layerUtils.d.ts.map +1 -1
- package/dist/api/layerUtils.js +3 -11
- package/dist/api/routing/middleware/ContextProvider.d.ts +2 -2
- package/dist/api/routing/middleware/ContextProvider.d.ts.map +1 -1
- package/dist/api/routing/middleware/RouterMiddleware.d.ts +33 -0
- package/dist/api/routing/middleware/RouterMiddleware.d.ts.map +1 -0
- package/dist/api/routing/middleware/RouterMiddleware.js +5 -0
- package/dist/api/routing/middleware/RpcMiddleware.d.ts +199 -0
- package/dist/api/routing/middleware/RpcMiddleware.d.ts.map +1 -0
- package/dist/api/routing/middleware/RpcMiddleware.js +14 -0
- package/dist/api/routing/middleware/dynamic-middleware.d.ts +3 -13
- package/dist/api/routing/middleware/dynamic-middleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/dynamic-middleware.js +2 -18
- package/dist/api/routing/middleware/generic-middleware.d.ts +15 -22
- package/dist/api/routing/middleware/generic-middleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/generic-middleware.js +13 -9
- package/dist/api/routing/middleware/middleware-api.d.ts +55 -8
- package/dist/api/routing/middleware/middleware-api.d.ts.map +1 -1
- package/dist/api/routing/middleware/middleware-api.js +50 -14
- package/dist/api/routing/middleware/middleware.d.ts +8 -7
- package/dist/api/routing/middleware/middleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/middleware.js +6 -5
- package/dist/api/routing/middleware.d.ts +2 -1
- package/dist/api/routing/middleware.d.ts.map +1 -1
- package/dist/api/routing/middleware.js +3 -2
- package/dist/api/routing/tsort.d.ts +2 -2
- package/dist/api/routing/tsort.d.ts.map +1 -1
- package/dist/api/routing/tsort.js +1 -1
- package/dist/api/routing.d.ts +0 -1
- package/dist/api/routing.d.ts.map +1 -1
- package/dist/api/routing.js +2 -3
- package/package.json +9 -5
- package/src/api/layerUtils.ts +7 -21
- package/src/api/routing/middleware/ContextProvider.ts +5 -5
- package/src/api/routing/middleware/RouterMiddleware.ts +149 -0
- package/src/api/routing/middleware/RpcMiddleware.ts +287 -0
- package/src/api/routing/middleware/dynamic-middleware.ts +9 -54
- package/src/api/routing/middleware/generic-middleware.ts +33 -33
- package/src/api/routing/middleware/middleware-api.ts +202 -32
- package/src/api/routing/middleware/middleware.ts +13 -5
- package/src/api/routing/middleware.ts +2 -1
- package/src/api/routing/tsort.ts +2 -2
- package/src/api/routing.ts +1 -9
- package/test/contextProvider.test.ts +1 -2
- package/test/controller.test.ts +35 -155
- package/test/dist/contextProvider.test.d.ts.map +1 -1
- package/test/dist/controller.test.d.ts.map +1 -1
- package/test/dist/fixtures.d.ts +146 -0
- package/test/dist/fixtures.d.ts.map +1 -0
- package/test/dist/fixtures.js +82 -0
- package/test/dist/layerUtils.test.d.ts.map +1 -0
- package/test/dist/query.test.d.ts.map +1 -1
- package/test/dist/requires.d.ts +21 -0
- package/test/dist/requires.d.ts.map +1 -0
- package/test/dist/requires.js +27 -0
- package/test/dist/requires.test.d.ts.map +1 -0
- package/test/fixtures.ts +102 -0
- package/test/layerUtils.test.ts +19 -0
- package/test/query.test.ts +2 -4
- package/test/requires.test.ts +156 -0
- package/dist/api/routing/middleware/DynamicMiddleware.d.ts +0 -215
- package/dist/api/routing/middleware/DynamicMiddleware.d.ts.map +0 -1
- package/dist/api/routing/middleware/DynamicMiddleware.js +0 -168
- package/src/api/routing/middleware/DynamicMiddleware.ts +0 -693
|
@@ -1,693 +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 { Rpc, RpcMiddleware } from "@effect/rpc"
|
|
5
|
-
import { type SuccessValue, type TypeId } from "@effect/rpc/RpcMiddleware"
|
|
6
|
-
import { Context, Effect, Layer, type NonEmptyReadonlyArray, type Option, type Request, type S, type Schema, type Scope, Unify } from "effect-app"
|
|
7
|
-
import type { GetEffectContext, 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 * as EffectRequest from "effect/Request"
|
|
11
|
-
import { type ContextTagWithDefault, type LayerUtils } from "../../layerUtils.js"
|
|
12
|
-
import { type ContextWithLayer, implementMiddleware } from "./dynamic-middleware.js"
|
|
13
|
-
import { type ContextRepr, type GenericMiddlewareMaker, genericMiddlewareMaker } from "./generic-middleware.js"
|
|
14
|
-
|
|
15
|
-
// module:
|
|
16
|
-
//
|
|
17
|
-
export type MakeRPCHandlerFactory<
|
|
18
|
-
RequestContextMap extends Record<string, RPCContextMap.Any>,
|
|
19
|
-
MiddlewareR
|
|
20
|
-
> = <
|
|
21
|
-
T extends {
|
|
22
|
-
config?: Partial<Record<keyof RequestContextMap, any>>
|
|
23
|
-
},
|
|
24
|
-
Req extends S.TaggedRequest.All,
|
|
25
|
-
HandlerR
|
|
26
|
-
>(
|
|
27
|
-
schema: T & S.Schema<Req, any, never>,
|
|
28
|
-
next: (
|
|
29
|
-
request: Req,
|
|
30
|
-
headers: any
|
|
31
|
-
) => Effect.Effect<
|
|
32
|
-
EffectRequest.Request.Success<Req>,
|
|
33
|
-
EffectRequest.Request.Error<Req>,
|
|
34
|
-
// dynamic middlewares removes the dynamic context from HandlerR
|
|
35
|
-
Exclude<HandlerR, GetEffectContext<RequestContextMap, (T & S.Schema<Req, any, never>)["config"]>>
|
|
36
|
-
>,
|
|
37
|
-
moduleName: string
|
|
38
|
-
) => (
|
|
39
|
-
req: Req,
|
|
40
|
-
headers: any
|
|
41
|
-
) => Effect.Effect<
|
|
42
|
-
Request.Request.Success<Req>,
|
|
43
|
-
Request.Request.Error<Req> | RequestContextMapErrors<RequestContextMap>,
|
|
44
|
-
// the middleware will remove from HandlerR the dynamic context, but will also add some requirements
|
|
45
|
-
| MiddlewareR
|
|
46
|
-
// & S.Schema<Req, any, never> is useless here but useful when creating the middleware
|
|
47
|
-
| Exclude<HandlerR, GetEffectContext<RequestContextMap, (T & S.Schema<Req, any, never>)["config"]>>
|
|
48
|
-
>
|
|
49
|
-
|
|
50
|
-
export type RPCHandlerFactory<
|
|
51
|
-
RequestContextMap extends Record<string, RPCContextMap.Any>,
|
|
52
|
-
ContextProviderA
|
|
53
|
-
> = <
|
|
54
|
-
T extends {
|
|
55
|
-
config?: Partial<Record<keyof RequestContextMap, any>>
|
|
56
|
-
},
|
|
57
|
-
Req extends S.TaggedRequest.All,
|
|
58
|
-
HandlerR
|
|
59
|
-
>(
|
|
60
|
-
schema: T & S.Schema<Req, any, never>,
|
|
61
|
-
next: (
|
|
62
|
-
request: Req,
|
|
63
|
-
headers: any
|
|
64
|
-
) => Effect.Effect<
|
|
65
|
-
EffectRequest.Request.Success<Req>,
|
|
66
|
-
EffectRequest.Request.Error<Req>,
|
|
67
|
-
HandlerR
|
|
68
|
-
>,
|
|
69
|
-
moduleName: string
|
|
70
|
-
) => (
|
|
71
|
-
req: Req,
|
|
72
|
-
headers: any
|
|
73
|
-
) => Effect.Effect<
|
|
74
|
-
Request.Request.Success<Req>,
|
|
75
|
-
Request.Request.Error<Req> | RequestContextMapErrors<RequestContextMap>,
|
|
76
|
-
| Scope.Scope // because of the context provider and the middleware (Middleware)
|
|
77
|
-
| Exclude<
|
|
78
|
-
// the middleware will remove from HandlerR the dynamic context
|
|
79
|
-
// & S.Schema<Req, any, never> is useless here but useful when creating the middleware
|
|
80
|
-
Exclude<HandlerR, GetEffectContext<RequestContextMap, (T & S.Schema<Req, any, never>)["config"]>>,
|
|
81
|
-
// the context provider provides additional stuff both to the middleware and the next
|
|
82
|
-
ContextProviderA
|
|
83
|
-
>
|
|
84
|
-
>
|
|
85
|
-
|
|
86
|
-
export type RequestContextMapProvider<RequestContextMap extends Record<string, RPCContextMap.Any>> = {
|
|
87
|
-
[K in keyof RequestContextMap]: ContextWithLayer.Base<
|
|
88
|
-
{ [K in keyof RequestContextMap]?: RequestContextMap[K]["contextActivation"] },
|
|
89
|
-
RequestContextMap[K]["service"],
|
|
90
|
-
S.Schema.Type<RequestContextMap[K]["error"]>
|
|
91
|
-
>
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
export interface MiddlewareMake<
|
|
95
|
-
RequestContextMap extends Record<string, RPCContextMap.Any>, // what services will the middleware provide dynamically to the next, or raise errors.
|
|
96
|
-
DynamicMiddlewareProviders extends RequestContextMapProvider<RequestContextMap>, // how to resolve the dynamic middleware
|
|
97
|
-
GenericMiddlewareProviders extends NonEmptyReadonlyArray<GenericMiddlewareMaker>,
|
|
98
|
-
MakeMiddlewareE, // what the middleware construction can fail with
|
|
99
|
-
MakeMiddlewareR, // what the middleware requires to be constructed
|
|
100
|
-
MiddlewareDependencies extends NonEmptyReadonlyArray<Layer.Layer.Any> // layers provided for the middleware to be constructed
|
|
101
|
-
> {
|
|
102
|
-
/* dynamic middlewares to be applied based on Request Configuration */
|
|
103
|
-
dynamicMiddlewares: DynamicMiddlewareProviders
|
|
104
|
-
/** generic middlewares are those which follow the (next) => (input, headers) => pattern */
|
|
105
|
-
genericMiddlewares: GenericMiddlewareProviders
|
|
106
|
-
|
|
107
|
-
/* dependencies for the main middleware running just before the next is called */
|
|
108
|
-
dependencies?: MiddlewareDependencies
|
|
109
|
-
// this actually builds "the middleware", i.e. returns the augmented next factory when yielded...
|
|
110
|
-
execute?: (
|
|
111
|
-
maker: (
|
|
112
|
-
// MiddlewareR is set to GenericMiddlewareProviders | Scope.Scope because that's what, at most
|
|
113
|
-
// a middleware can additionally require to get executed
|
|
114
|
-
cb: MakeRPCHandlerFactory<
|
|
115
|
-
RequestContextMap,
|
|
116
|
-
| GenericMiddlewareMaker.Provided<GenericMiddlewareProviders[number]>
|
|
117
|
-
| Scope.Scope
|
|
118
|
-
>
|
|
119
|
-
) => MakeRPCHandlerFactory<
|
|
120
|
-
RequestContextMap,
|
|
121
|
-
| GenericMiddlewareMaker.Provided<GenericMiddlewareProviders[number]>
|
|
122
|
-
| Scope.Scope
|
|
123
|
-
>
|
|
124
|
-
) => Effect<
|
|
125
|
-
MakeRPCHandlerFactory<
|
|
126
|
-
RequestContextMap,
|
|
127
|
-
| GenericMiddlewareMaker.Provided<GenericMiddlewareProviders[number]>
|
|
128
|
-
| Scope.Scope
|
|
129
|
-
>,
|
|
130
|
-
MakeMiddlewareE,
|
|
131
|
-
MakeMiddlewareR | Scope // ...that's why MakeMiddlewareR is here
|
|
132
|
-
>
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
export interface MiddlewareMakerId {
|
|
136
|
-
_tag: "MiddlewareMaker"
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
export type RouterMiddleware<
|
|
140
|
-
RequestContextMap extends Record<string, RPCContextMap.Any>, // what services will the middlware provide dynamically to the next, or raise errors.
|
|
141
|
-
MakeMiddlewareE, // what the middleware construction can fail with
|
|
142
|
-
MakeMiddlewareR, // what the middlware requires to be constructed
|
|
143
|
-
ContextProviderA // what the context provider provides
|
|
144
|
-
> = ContextTagWithDefault<
|
|
145
|
-
MiddlewareMakerId,
|
|
146
|
-
{
|
|
147
|
-
_tag: "MiddlewareMaker"
|
|
148
|
-
effect: RPCHandlerFactory<RequestContextMap, ContextProviderA>
|
|
149
|
-
},
|
|
150
|
-
MakeMiddlewareE,
|
|
151
|
-
MakeMiddlewareR
|
|
152
|
-
>
|
|
153
|
-
|
|
154
|
-
export type RequestContextMapErrors<RequestContextMap extends Record<string, RPCContextMap.Any>> = S.Schema.Type<
|
|
155
|
-
RequestContextMap[keyof RequestContextMap]["error"]
|
|
156
|
-
>
|
|
157
|
-
|
|
158
|
-
/*:
|
|
159
|
-
& Context.Tag<MiddlewareMakerId, {
|
|
160
|
-
effect: RPCHandlerFactory<RequestContextMap, GenericMiddlewareMaker.Provided<GenericMiddlewareProviders[number]>>
|
|
161
|
-
_tag: "MiddlewareMaker"
|
|
162
|
-
}>
|
|
163
|
-
& { Default: "abc" } */
|
|
164
|
-
|
|
165
|
-
// factory for middlewares
|
|
166
|
-
export const makeMiddleware =
|
|
167
|
-
// by setting RequestContextMap beforehand, execute contextual typing does not fuck up itself to anys
|
|
168
|
-
<
|
|
169
|
-
RequestContextMap extends Record<string, RPCContextMap.Any>
|
|
170
|
-
>() =>
|
|
171
|
-
<
|
|
172
|
-
RequestContextProviders extends RequestContextMapProvider<RequestContextMap>, // how to resolve the dynamic middleware
|
|
173
|
-
GenericMiddlewareProviders extends NonEmptyReadonlyArray<GenericMiddlewareMaker>,
|
|
174
|
-
MiddlewareDependencies extends NonEmptyReadonlyArray<Layer.Layer.Any>, // layers provided for the middlware to be constructed
|
|
175
|
-
MakeMiddlewareE = never, // what the middleware construction can fail with
|
|
176
|
-
MakeMiddlewareR = never // what the middlware requires to be constructed
|
|
177
|
-
>(
|
|
178
|
-
make: MiddlewareMake<
|
|
179
|
-
RequestContextMap,
|
|
180
|
-
RequestContextProviders,
|
|
181
|
-
GenericMiddlewareProviders,
|
|
182
|
-
MakeMiddlewareE,
|
|
183
|
-
MakeMiddlewareR,
|
|
184
|
-
MiddlewareDependencies
|
|
185
|
-
>
|
|
186
|
-
) => {
|
|
187
|
-
const MiddlewareMaker = Context.GenericTag<
|
|
188
|
-
MiddlewareMakerId,
|
|
189
|
-
{
|
|
190
|
-
effect: RPCHandlerFactory<
|
|
191
|
-
RequestContextMap,
|
|
192
|
-
GenericMiddlewareMaker.Provided<GenericMiddlewareProviders[number]>
|
|
193
|
-
>
|
|
194
|
-
_tag: "MiddlewareMaker"
|
|
195
|
-
}
|
|
196
|
-
>(
|
|
197
|
-
"MiddlewareMaker"
|
|
198
|
-
)
|
|
199
|
-
|
|
200
|
-
const dynamicMiddlewares = implementMiddleware<RequestContextMap>()(make.dynamicMiddlewares)
|
|
201
|
-
const middlewares = genericMiddlewareMaker(...make.genericMiddlewares)
|
|
202
|
-
|
|
203
|
-
const l = Layer.scoped(
|
|
204
|
-
MiddlewareMaker,
|
|
205
|
-
Effect
|
|
206
|
-
.all({
|
|
207
|
-
dynamicMiddlewares: dynamicMiddlewares.effect,
|
|
208
|
-
generic: middlewares.effect,
|
|
209
|
-
middleware: make.execute
|
|
210
|
-
? make.execute((
|
|
211
|
-
cb: MakeRPCHandlerFactory<
|
|
212
|
-
RequestContextMap,
|
|
213
|
-
Scope.Scope | GenericMiddlewareMaker.Provided<GenericMiddlewareProviders[number]>
|
|
214
|
-
>
|
|
215
|
-
) => cb)
|
|
216
|
-
: Effect.succeed<
|
|
217
|
-
MakeRPCHandlerFactory<
|
|
218
|
-
RequestContextMap,
|
|
219
|
-
Scope.Scope | GenericMiddlewareMaker.Provided<GenericMiddlewareProviders[number]>
|
|
220
|
-
>
|
|
221
|
-
>((_schema, next) => (payload, headers) => next(payload, headers))
|
|
222
|
-
})
|
|
223
|
-
.pipe(
|
|
224
|
-
Effect.map(({ dynamicMiddlewares, generic, middleware }) => ({
|
|
225
|
-
_tag: "MiddlewareMaker" as const,
|
|
226
|
-
effect: makeRpcEffect<
|
|
227
|
-
RequestContextMap,
|
|
228
|
-
GenericMiddlewareMaker.Provided<GenericMiddlewareProviders[number]>
|
|
229
|
-
>()(
|
|
230
|
-
(schema, next, moduleName) => {
|
|
231
|
-
const h = middleware(schema, next as any, moduleName)
|
|
232
|
-
return (payload, headers) => {
|
|
233
|
-
const basic = {
|
|
234
|
-
config: schema.config ?? {},
|
|
235
|
-
payload,
|
|
236
|
-
headers,
|
|
237
|
-
clientId: 0, // TODO: get the clientId from the request context
|
|
238
|
-
rpc: {
|
|
239
|
-
...Rpc.fromTaggedRequest(schema as any),
|
|
240
|
-
// middlewares ? // todo: get from actual middleware flow?
|
|
241
|
-
annotations: Context.empty(), // TODO //Annotations(schema as any),
|
|
242
|
-
// successSchema: schema.success ?? Schema.Void,
|
|
243
|
-
// errorSchema: schema.failure ?? Schema.Never,
|
|
244
|
-
payloadSchema: schema,
|
|
245
|
-
_tag: `${moduleName}.${payload._tag}`,
|
|
246
|
-
key: `${moduleName}.${payload._tag}` /* ? */
|
|
247
|
-
// clientId: 0 as number /* ? */
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
return Effect
|
|
251
|
-
.gen(function*() {
|
|
252
|
-
const gen = generic({
|
|
253
|
-
...basic,
|
|
254
|
-
next:
|
|
255
|
-
// the contextProvider is an Effect that builds the context for the request
|
|
256
|
-
// the dynamicMiddlewares is an Effect that builds the dynamiuc context for the request
|
|
257
|
-
dynamicMiddlewares(basic).pipe(
|
|
258
|
-
Effect.flatMap((dynamicContext) => h(payload, headers).pipe(Effect.provide(dynamicContext)))
|
|
259
|
-
) as any
|
|
260
|
-
})
|
|
261
|
-
|
|
262
|
-
return yield* gen
|
|
263
|
-
}) as any // why?
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
)
|
|
267
|
-
}))
|
|
268
|
-
)
|
|
269
|
-
)
|
|
270
|
-
|
|
271
|
-
const dependencies = [
|
|
272
|
-
...(make.dependencies ? make.dependencies : []),
|
|
273
|
-
...(dynamicMiddlewares.dependencies as any),
|
|
274
|
-
...middlewares.dependencies
|
|
275
|
-
]
|
|
276
|
-
const middlewareLayer = l
|
|
277
|
-
.pipe(
|
|
278
|
-
Layer.provide(dependencies as any)
|
|
279
|
-
) as Layer.Layer<
|
|
280
|
-
MiddlewareMakerId,
|
|
281
|
-
| MakeMiddlewareE // what the middleware construction can fail with
|
|
282
|
-
| LayerUtils.GetLayersError<typeof dynamicMiddlewares.dependencies>
|
|
283
|
-
| LayerUtils.GetLayersError<typeof middlewares.dependencies>, // what could go wrong when building the dynamic middleware provider
|
|
284
|
-
| LayerUtils.GetLayersContext<MiddlewareDependencies> // what's needed to build layers
|
|
285
|
-
| LayerUtils.GetLayersContext<typeof middlewares.dependencies>
|
|
286
|
-
| LayerUtils.GetLayersContext<typeof dynamicMiddlewares.dependencies> // what's needed to build dynamic middleware layers
|
|
287
|
-
| Exclude<MakeMiddlewareR, LayerUtils.GetLayersSuccess<MiddlewareDependencies>> // what layers provides
|
|
288
|
-
>
|
|
289
|
-
|
|
290
|
-
return Object.assign(MiddlewareMaker, { Default: middlewareLayer })
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
export const makeMiddlewareBasic =
|
|
294
|
-
// by setting RequestContextMap beforehand, execute contextual typing does not fuck up itself to anys
|
|
295
|
-
<
|
|
296
|
-
RequestContextMap extends Record<string, RPCContextMap.Any>,
|
|
297
|
-
RequestContextProviders extends RequestContextMapProvider<RequestContextMap>, // how to resolve the dynamic middleware
|
|
298
|
-
GenericMiddlewareProviders extends NonEmptyReadonlyArray<GenericMiddlewareMaker>
|
|
299
|
-
>(
|
|
300
|
-
make: MiddlewareMake<
|
|
301
|
-
RequestContextMap,
|
|
302
|
-
RequestContextProviders,
|
|
303
|
-
GenericMiddlewareProviders,
|
|
304
|
-
never,
|
|
305
|
-
never,
|
|
306
|
-
never
|
|
307
|
-
>
|
|
308
|
-
) => {
|
|
309
|
-
const MiddlewareMaker = Context.GenericTag<
|
|
310
|
-
MiddlewareMakerId,
|
|
311
|
-
{
|
|
312
|
-
effect: RPCHandlerFactory<
|
|
313
|
-
RequestContextMap,
|
|
314
|
-
GenericMiddlewareMaker.Provided<GenericMiddlewareProviders[number]>
|
|
315
|
-
>
|
|
316
|
-
_tag: "MiddlewareMaker"
|
|
317
|
-
}
|
|
318
|
-
>(
|
|
319
|
-
"MiddlewareMaker"
|
|
320
|
-
)
|
|
321
|
-
|
|
322
|
-
const dynamicMiddlewares = implementMiddleware<RequestContextMap>()(make.dynamicMiddlewares)
|
|
323
|
-
const middlewares = genericMiddlewareMaker(...make.genericMiddlewares)
|
|
324
|
-
|
|
325
|
-
const l = Layer.scoped(
|
|
326
|
-
MiddlewareMaker,
|
|
327
|
-
Effect
|
|
328
|
-
.all({
|
|
329
|
-
dynamicMiddlewares: dynamicMiddlewares.effect,
|
|
330
|
-
generic: middlewares.effect,
|
|
331
|
-
middleware: make.execute
|
|
332
|
-
? make.execute((
|
|
333
|
-
cb: MakeRPCHandlerFactory<
|
|
334
|
-
RequestContextMap,
|
|
335
|
-
Scope.Scope | GenericMiddlewareMaker.Provided<GenericMiddlewareProviders[number]>
|
|
336
|
-
>
|
|
337
|
-
) => cb)
|
|
338
|
-
: Effect.succeed<
|
|
339
|
-
MakeRPCHandlerFactory<
|
|
340
|
-
RequestContextMap,
|
|
341
|
-
Scope.Scope | GenericMiddlewareMaker.Provided<GenericMiddlewareProviders[number]>
|
|
342
|
-
>
|
|
343
|
-
>((_schema, next) => (payload, headers) => next(payload, headers))
|
|
344
|
-
})
|
|
345
|
-
.pipe(
|
|
346
|
-
Effect.map(({ dynamicMiddlewares, generic, middleware }) => ({
|
|
347
|
-
_tag: "MiddlewareMaker" as const,
|
|
348
|
-
effect: makeRpcEffect<
|
|
349
|
-
RequestContextMap,
|
|
350
|
-
GenericMiddlewareMaker.Provided<GenericMiddlewareProviders[number]>
|
|
351
|
-
>()(
|
|
352
|
-
(schema, next, moduleName) => {
|
|
353
|
-
const h = middleware(schema, next as any, moduleName)
|
|
354
|
-
return (payload, headers) =>
|
|
355
|
-
Effect
|
|
356
|
-
.gen(function*() {
|
|
357
|
-
const basic = {
|
|
358
|
-
config: schema.config ?? {},
|
|
359
|
-
payload,
|
|
360
|
-
headers,
|
|
361
|
-
clientId: 0, // TODO: get the clientId from the request context
|
|
362
|
-
rpc: {
|
|
363
|
-
...Rpc.fromTaggedRequest(schema as any),
|
|
364
|
-
// middlewares ? // todo: get from actual middleware flow?
|
|
365
|
-
annotations: Context.empty(), // TODO //Annotations(schema as any),
|
|
366
|
-
// successSchema: schema.success ?? Schema.Void,
|
|
367
|
-
// errorSchema: schema.failure ?? Schema.Never,
|
|
368
|
-
payloadSchema: schema,
|
|
369
|
-
_tag: `${moduleName}.${payload._tag}`,
|
|
370
|
-
key: `${moduleName}.${payload._tag}` /* ? */
|
|
371
|
-
// clientId: 0 as number /* ? */
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
return yield* generic({
|
|
375
|
-
...basic,
|
|
376
|
-
next:
|
|
377
|
-
// the contextProvider is an Effect that builds the context for the request
|
|
378
|
-
// the dynamicMiddlewares is an Effect that builds the dynamiuc context for the request
|
|
379
|
-
dynamicMiddlewares(basic).pipe(
|
|
380
|
-
Effect.flatMap((dynamicContext) => h(payload, headers).pipe(Effect.provide(dynamicContext)))
|
|
381
|
-
) as any
|
|
382
|
-
})
|
|
383
|
-
}) as any // why?
|
|
384
|
-
}
|
|
385
|
-
)
|
|
386
|
-
}))
|
|
387
|
-
)
|
|
388
|
-
)
|
|
389
|
-
|
|
390
|
-
const dependencies = [
|
|
391
|
-
...(make.dependencies ? make.dependencies : []),
|
|
392
|
-
...(dynamicMiddlewares.dependencies),
|
|
393
|
-
...middlewares.dependencies
|
|
394
|
-
]
|
|
395
|
-
const middlewareLayer = l
|
|
396
|
-
.pipe(
|
|
397
|
-
Layer.provide(dependencies as any)
|
|
398
|
-
) as Layer.Layer<
|
|
399
|
-
MiddlewareMakerId,
|
|
400
|
-
| LayerUtils.GetLayersError<typeof dynamicMiddlewares.dependencies>
|
|
401
|
-
| LayerUtils.GetLayersError<typeof middlewares.dependencies>, // what could go wrong when building the dynamic middleware provider
|
|
402
|
-
| LayerUtils.GetLayersContext<typeof middlewares.dependencies>
|
|
403
|
-
| LayerUtils.GetLayersContext<typeof dynamicMiddlewares.dependencies> // what's needed to build dynamic middleware layers
|
|
404
|
-
>
|
|
405
|
-
|
|
406
|
-
return Object.assign(MiddlewareMaker, { Default: middlewareLayer })
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
// it just provides the right types without cluttering the implementation with them
|
|
410
|
-
function makeRpcEffect<
|
|
411
|
-
RequestContextMap extends Record<string, RPCContextMap.Any>,
|
|
412
|
-
ContextProviderA
|
|
413
|
-
>() {
|
|
414
|
-
return (
|
|
415
|
-
cb: <
|
|
416
|
-
T extends {
|
|
417
|
-
config?: Partial<Record<keyof RequestContextMap, any>>
|
|
418
|
-
},
|
|
419
|
-
Req extends S.TaggedRequest.All,
|
|
420
|
-
HandlerR
|
|
421
|
-
>(
|
|
422
|
-
schema: T & S.Schema<Req, any, never>,
|
|
423
|
-
next: (
|
|
424
|
-
request: Req,
|
|
425
|
-
headers: any
|
|
426
|
-
) => Effect.Effect<
|
|
427
|
-
EffectRequest.Request.Success<Req>,
|
|
428
|
-
EffectRequest.Request.Error<Req>,
|
|
429
|
-
HandlerR
|
|
430
|
-
>,
|
|
431
|
-
moduleName: string
|
|
432
|
-
) => (
|
|
433
|
-
req: Req,
|
|
434
|
-
headers: any
|
|
435
|
-
) => Effect.Effect<
|
|
436
|
-
Request.Request.Success<Req>,
|
|
437
|
-
Request.Request.Error<Req> | RequestContextMapErrors<RequestContextMap>,
|
|
438
|
-
| Scope.Scope // the context provider may require Scope to run
|
|
439
|
-
| Exclude<
|
|
440
|
-
// it can also be removed from HandlerR
|
|
441
|
-
Exclude<HandlerR, GetEffectContext<RequestContextMap, (T & S.Schema<Req, any, never>)["config"]>>,
|
|
442
|
-
ContextProviderA
|
|
443
|
-
>
|
|
444
|
-
>
|
|
445
|
-
) => cb
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
// updated to support Scope.Scope
|
|
449
|
-
export interface RpcMiddleware<Provides, E> {
|
|
450
|
-
(options: {
|
|
451
|
-
readonly clientId: number
|
|
452
|
-
readonly rpc: Rpc.AnyWithProps
|
|
453
|
-
readonly payload: unknown
|
|
454
|
-
readonly headers: HttpHeaders.Headers
|
|
455
|
-
}): Effect.Effect<Provides, E, Scope.Scope>
|
|
456
|
-
}
|
|
457
|
-
export interface RpcMiddlewareWrap<Provides, E> {
|
|
458
|
-
(options: {
|
|
459
|
-
readonly clientId: number
|
|
460
|
-
readonly rpc: Rpc.AnyWithProps
|
|
461
|
-
readonly payload: unknown
|
|
462
|
-
readonly headers: HttpHeaders.Headers
|
|
463
|
-
readonly next: Effect.Effect<SuccessValue, E, Provides | Scope.Scope>
|
|
464
|
-
}): Effect.Effect<SuccessValue, E, Scope.Scope>
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
type RpcOptionsOriginal = {
|
|
468
|
-
readonly wrap?: boolean
|
|
469
|
-
readonly optional?: boolean
|
|
470
|
-
readonly failure?: Schema.Schema.All
|
|
471
|
-
readonly provides?: Context.Tag<any, any> | ContextRepr
|
|
472
|
-
readonly requiredForClient?: boolean
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
type RpcDynamic<Key extends string, A extends RPCContextMap.Any> = {
|
|
476
|
-
key: Key
|
|
477
|
-
settings: A
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
type RpcOptionsDynamic<Key extends string, A extends RPCContextMap.Any> = RpcOptionsOriginal & {
|
|
481
|
-
readonly dynamic: RpcDynamic<Key, A>
|
|
482
|
-
readonly dependsOn?: NonEmptyReadonlyArray<TagClassDynamicAny<any>>
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
export type Dynamic<Options> = Options extends RpcOptionsDynamic<any, any> ? true : false
|
|
486
|
-
|
|
487
|
-
export interface RpcMiddlewareDynamic<A, E, Config> {
|
|
488
|
-
(options: {
|
|
489
|
-
readonly config: Config // todo
|
|
490
|
-
readonly clientId: number
|
|
491
|
-
readonly rpc: Rpc.AnyWithProps
|
|
492
|
-
readonly payload: unknown
|
|
493
|
-
readonly headers: HttpHeaders.Headers
|
|
494
|
-
}): Effect.Effect<Option.Option<Context.Context<A>>, E, Scope.Scope>
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
export interface TagClassDynamicAny<RequestContext extends Record<string, RPCContextMap.Any>>
|
|
498
|
-
extends Context.Tag<any, any>
|
|
499
|
-
{
|
|
500
|
-
readonly [RpcMiddleware.TypeId]: RpcMiddleware.TypeId
|
|
501
|
-
readonly optional: boolean
|
|
502
|
-
readonly provides?: Context.Tag<any, any> | undefined
|
|
503
|
-
readonly failure: Schema.Schema.All
|
|
504
|
-
readonly requiredForClient: boolean
|
|
505
|
-
readonly dynamic: RpcDynamic<any, RequestContext[keyof RequestContext]>
|
|
506
|
-
readonly wrap: boolean
|
|
507
|
-
readonly dependsOn?: any
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
export declare namespace TagClass {
|
|
511
|
-
/**
|
|
512
|
-
* @since 1.0.0
|
|
513
|
-
* @category models
|
|
514
|
-
*/
|
|
515
|
-
export type Provides<Options> = Options extends {
|
|
516
|
-
readonly provides: Context.Tag<any, any>
|
|
517
|
-
readonly optional?: false
|
|
518
|
-
} ? Context.Tag.Identifier<Options["provides"]>
|
|
519
|
-
: Options extends {
|
|
520
|
-
readonly provides: ContextRepr
|
|
521
|
-
readonly optional?: false
|
|
522
|
-
} ? ContextRepr.Identifier<Options["provides"]>
|
|
523
|
-
: never
|
|
524
|
-
|
|
525
|
-
/**
|
|
526
|
-
* @since 1.0.0
|
|
527
|
-
* @category models
|
|
528
|
-
*/
|
|
529
|
-
export type Service<Options> = Options extends { readonly provides: Context.Tag<any, any> }
|
|
530
|
-
? Context.Tag.Service<Options["provides"]>
|
|
531
|
-
: Options extends { readonly dynamic: RpcDynamic<any, infer A> } ? A["service"]
|
|
532
|
-
: Options extends { readonly provides: ContextRepr } ? Context.Context<ContextRepr.Identifier<Options["provides"]>>
|
|
533
|
-
: void
|
|
534
|
-
|
|
535
|
-
/**
|
|
536
|
-
* @since 1.0.0
|
|
537
|
-
* @category models
|
|
538
|
-
*/
|
|
539
|
-
export type FailureSchema<Options> = Options extends
|
|
540
|
-
{ readonly failure: Schema.Schema.All; readonly optional?: false } ? Options["failure"]
|
|
541
|
-
: Options extends { readonly dynamic: RpcDynamic<any, infer A> } ? A["error"]
|
|
542
|
-
: typeof Schema.Never
|
|
543
|
-
|
|
544
|
-
/**
|
|
545
|
-
* @since 1.0.0
|
|
546
|
-
* @category models
|
|
547
|
-
*/
|
|
548
|
-
export type Failure<Options> = Options extends
|
|
549
|
-
{ readonly failure: Schema.Schema<infer _A, infer _I, infer _R>; readonly optional?: false } ? _A
|
|
550
|
-
: Options extends { readonly dynamic: RpcDynamic<any, infer A> } ? S.Schema.Type<A["error"]>
|
|
551
|
-
: never
|
|
552
|
-
|
|
553
|
-
/**
|
|
554
|
-
* @since 1.0.0
|
|
555
|
-
* @category models
|
|
556
|
-
*/
|
|
557
|
-
export type FailureContext<Options> = Schema.Schema.Context<FailureSchema<Options>>
|
|
558
|
-
|
|
559
|
-
/**
|
|
560
|
-
* @since 1.0.0
|
|
561
|
-
* @category models
|
|
562
|
-
*/
|
|
563
|
-
export type FailureService<Options> = Optional<Options> extends true ? unknown : Failure<Options>
|
|
564
|
-
|
|
565
|
-
/**
|
|
566
|
-
* @since 1.0.0
|
|
567
|
-
* @category models
|
|
568
|
-
*/
|
|
569
|
-
export type Optional<Options> = Options extends { readonly optional: true } ? true : false
|
|
570
|
-
|
|
571
|
-
/**
|
|
572
|
-
* @since 1.0.0
|
|
573
|
-
* @category models
|
|
574
|
-
*/
|
|
575
|
-
export type RequiredForClient<Options> = Options extends { readonly requiredForClient: true } ? true : false
|
|
576
|
-
|
|
577
|
-
/**
|
|
578
|
-
* @since 1.0.0
|
|
579
|
-
* @category models
|
|
580
|
-
*/
|
|
581
|
-
export type Wrap<Options> = Options extends { readonly wrap: true } ? true : false
|
|
582
|
-
|
|
583
|
-
/**
|
|
584
|
-
* @since 1.0.0
|
|
585
|
-
* @category models
|
|
586
|
-
*/
|
|
587
|
-
export interface Base<Self, Name extends string, Options, Service> extends Context.Tag<Self, Service> {
|
|
588
|
-
new(_: never): Context.TagClassShape<Name, Service>
|
|
589
|
-
readonly [TypeId]: TypeId
|
|
590
|
-
readonly optional: Optional<Options>
|
|
591
|
-
readonly failure: FailureSchema<Options>
|
|
592
|
-
readonly provides: Options extends { readonly provides: Context.Tag<any, any> } ? Options["provides"]
|
|
593
|
-
: Options extends { readonly provides: ContextRepr } ? Options["provides"]
|
|
594
|
-
: undefined
|
|
595
|
-
readonly dynamic: Options extends RpcOptionsDynamic<any, any> ? Options["dynamic"]
|
|
596
|
-
: undefined
|
|
597
|
-
readonly requiredForClient: RequiredForClient<Options>
|
|
598
|
-
readonly wrap: Wrap<Options>
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
export interface TagClass<
|
|
603
|
-
Self,
|
|
604
|
-
Name extends string,
|
|
605
|
-
Options
|
|
606
|
-
> extends
|
|
607
|
-
TagClass.Base<
|
|
608
|
-
Self,
|
|
609
|
-
Name,
|
|
610
|
-
Options,
|
|
611
|
-
TagClass.Wrap<Options> extends true ? RpcMiddlewareWrap<
|
|
612
|
-
TagClass.Provides<Options>,
|
|
613
|
-
TagClass.Failure<Options>
|
|
614
|
-
>
|
|
615
|
-
: Options extends RpcOptionsDynamic<any, any> ? RpcMiddlewareDynamic<
|
|
616
|
-
TagClass.Service<Options>,
|
|
617
|
-
TagClass.FailureService<Options>,
|
|
618
|
-
{ [K in Options["dynamic"]["key"]]?: Options["dynamic"]["settings"]["contextActivation"] }
|
|
619
|
-
>
|
|
620
|
-
: RpcMiddleware<
|
|
621
|
-
TagClass.Service<Options>,
|
|
622
|
-
TagClass.FailureService<Options>
|
|
623
|
-
>
|
|
624
|
-
>
|
|
625
|
-
{}
|
|
626
|
-
|
|
627
|
-
export const Tag = <Self>() =>
|
|
628
|
-
<
|
|
629
|
-
const Name extends string,
|
|
630
|
-
const Options extends RpcOptionsOriginal | RpcOptionsDynamic<any, any>
|
|
631
|
-
>(
|
|
632
|
-
id: Name,
|
|
633
|
-
options?: Options | undefined
|
|
634
|
-
) =>
|
|
635
|
-
<E, R, L extends NonEmptyReadonlyArray<Layer.Layer.Any>>(opts: {
|
|
636
|
-
effect: Effect.Effect<
|
|
637
|
-
TagClass.Wrap<Options> extends true ? RpcMiddlewareWrap<
|
|
638
|
-
TagClass.Provides<Options>,
|
|
639
|
-
TagClass.Failure<Options>
|
|
640
|
-
>
|
|
641
|
-
: Options extends RpcOptionsDynamic<any, any> ? RpcMiddlewareDynamic<
|
|
642
|
-
TagClass.Service<Options>,
|
|
643
|
-
TagClass.FailureService<Options>,
|
|
644
|
-
{ [K in Options["dynamic"]["key"]]?: Options["dynamic"]["settings"]["contextActivation"] }
|
|
645
|
-
>
|
|
646
|
-
: RpcMiddleware<
|
|
647
|
-
TagClass.Service<Options>,
|
|
648
|
-
TagClass.FailureService<Options>
|
|
649
|
-
>,
|
|
650
|
-
E,
|
|
651
|
-
R
|
|
652
|
-
>
|
|
653
|
-
dependencies?: L
|
|
654
|
-
}): TagClass<Self, Name, Options> & {
|
|
655
|
-
Default: Layer.Layer<Self, E | LayerUtils.GetLayersError<L>, Exclude<R, LayerUtils.GetLayersSuccess<L>>>
|
|
656
|
-
} =>
|
|
657
|
-
class extends RpcMiddleware.Tag<Self>()(id, options as any) {
|
|
658
|
-
// TODO: move to TagClass.
|
|
659
|
-
static readonly dynamic = options && "dynamic" in options ? options.dynamic : undefined
|
|
660
|
-
static readonly dependsOn = options && "dependsOn" in options ? options.dependsOn : undefined
|
|
661
|
-
static readonly Default = Layer.scoped(this, opts.effect as any).pipe(
|
|
662
|
-
Layer.provide([Layer.empty, ...opts.dependencies ?? []])
|
|
663
|
-
)
|
|
664
|
-
static override [Unify.typeSymbol]?: unknown
|
|
665
|
-
static override [Unify.unifySymbol]?: TagUnify<typeof this>
|
|
666
|
-
static override [Unify.ignoreSymbol]?: TagUnifyIgnore
|
|
667
|
-
} as any
|
|
668
|
-
|
|
669
|
-
// export const Tag = <Self>() =>
|
|
670
|
-
// <
|
|
671
|
-
// const Name extends string,
|
|
672
|
-
// const Options extends Omit<RpcOptionsOriginal, "wrap">
|
|
673
|
-
// >(
|
|
674
|
-
// id: Name,
|
|
675
|
-
// options?: Options | undefined
|
|
676
|
-
// ) =>
|
|
677
|
-
// OurTag<Self>()(id, { ...options, wrap: true } as Options & { wrap: true }) as <
|
|
678
|
-
// E,
|
|
679
|
-
// R,
|
|
680
|
-
// L extends NonEmptyReadonlyArray<Layer.Layer.Any>
|
|
681
|
-
// >(opts: {
|
|
682
|
-
// effect: Effect.Effect<
|
|
683
|
-
// RpcMiddlewareWrap<
|
|
684
|
-
// RpcMiddleware.TagClass.Provides<Options>,
|
|
685
|
-
// RpcMiddleware.TagClass.Failure<Options>
|
|
686
|
-
// >,
|
|
687
|
-
// E,
|
|
688
|
-
// R
|
|
689
|
-
// >
|
|
690
|
-
// dependencies?: L
|
|
691
|
-
// }) => RpcMiddleware.TagClass<Self, Name, Options> & {
|
|
692
|
-
// Default: Layer.Layer<Self, E | LayerUtils.GetLayersError<L>, Exclude<R, LayerUtils.GetLayersSuccess<L>>>
|
|
693
|
-
// }
|