@effect-app/infra 2.87.2 → 2.89.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 +24 -1
- package/dist/api/{routing/middleware/ContextProvider.d.ts → ContextProvider.d.ts} +1 -1
- package/dist/api/ContextProvider.d.ts.map +1 -0
- package/dist/api/ContextProvider.js +38 -0
- package/dist/api/routing/middleware/RouterMiddleware.d.ts +15 -28
- package/dist/api/routing/middleware/RouterMiddleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/RouterMiddleware.js +2 -5
- package/dist/api/routing/middleware/RpcMiddleware.d.ts +19 -23
- package/dist/api/routing/middleware/RpcMiddleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/RpcMiddleware.js +1 -1
- package/dist/api/routing/middleware/dynamic-middleware.d.ts +1 -9
- package/dist/api/routing/middleware/dynamic-middleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/generic-middleware.d.ts +24 -22
- package/dist/api/routing/middleware/generic-middleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/generic-middleware.js +24 -8
- package/dist/api/routing/middleware/middleware-api.d.ts +68 -36
- package/dist/api/routing/middleware/middleware-api.d.ts.map +1 -1
- package/dist/api/routing/middleware/middleware-api.js +45 -45
- package/dist/api/routing/middleware/middleware.d.ts +7 -7
- package/dist/api/routing/middleware/middleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/middleware.js +5 -5
- package/dist/api/routing/middleware.d.ts +0 -1
- package/dist/api/routing/middleware.d.ts.map +1 -1
- package/dist/api/routing/middleware.js +1 -2
- package/dist/api/routing.d.ts +1 -1
- package/dist/api/routing.d.ts.map +1 -1
- package/dist/api/routing.js +12 -10
- package/package.json +6 -6
- package/src/api/{routing/middleware/ContextProvider.ts → ContextProvider.ts} +1 -1
- package/src/api/routing/middleware/RouterMiddleware.ts +22 -134
- package/src/api/routing/middleware/RpcMiddleware.ts +28 -23
- package/src/api/routing/middleware/dynamic-middleware.ts +0 -47
- package/src/api/routing/middleware/generic-middleware.ts +84 -35
- package/src/api/routing/middleware/middleware-api.ts +190 -159
- package/src/api/routing/middleware/middleware.ts +5 -5
- package/src/api/routing/middleware.ts +0 -1
- package/src/api/routing.ts +22 -20
- package/test/contextProvider.test.ts +28 -25
- package/test/controller.test.ts +44 -9
- 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 +39 -45
- package/test/dist/fixtures.d.ts.map +1 -1
- package/test/dist/fixtures.js +27 -14
- package/test/dist/requires.test.d.ts.map +1 -1
- package/test/fixtures.ts +29 -18
- package/test/layerUtils.test.ts +1 -2
- package/test/requires.test.ts +146 -103
- package/dist/api/routing/middleware/ContextProvider.d.ts.map +0 -1
- package/dist/api/routing/middleware/ContextProvider.js +0 -38
|
@@ -1,199 +1,230 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import { type
|
|
4
|
-
import { type
|
|
5
|
-
import { type
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
export
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
// out MiddlewareR = never
|
|
24
|
-
MiddlewareR = never
|
|
25
|
-
> {
|
|
26
|
-
middleware<MW extends NonEmptyArray<GenericMiddlewareMaker>>(
|
|
27
|
-
...mw: MW
|
|
28
|
-
): DynamicMiddlewareMakerrsss<
|
|
29
|
-
RequestContext,
|
|
30
|
-
Provided,
|
|
31
|
-
[...Middlewares, ...MW],
|
|
32
|
-
DynamicMiddlewareProviders,
|
|
33
|
-
GenericMiddlewareMaker.ApplyManyServices<MW, MiddlewareR>
|
|
34
|
-
>
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import { type AnyWithProps } from "@effect/rpc/Rpc"
|
|
3
|
+
import { Context, type Effect, type NonEmptyArray, type NonEmptyReadonlyArray, S } from "effect-app"
|
|
4
|
+
import { type GetContextConfig, type RPCContextMap } from "effect-app/client"
|
|
5
|
+
import { type MiddlewareMaker, middlewareMaker } from "./generic-middleware.js"
|
|
6
|
+
import { type AnyDynamic, type RpcDynamic, Tag, type TagClassAny } from "./RpcMiddleware.js"
|
|
7
|
+
|
|
8
|
+
/** Adapter used when setting the dynamic prop on a middleware implementation */
|
|
9
|
+
export const contextMap = <
|
|
10
|
+
RequestContextMap extends Record<string, RPCContextMap.Any>,
|
|
11
|
+
Key extends (keyof RequestContextMap) & string
|
|
12
|
+
>(rcm: RequestContextMap, key: Key): RpcDynamic<Key, RequestContextMap[Key]> => ({
|
|
13
|
+
key,
|
|
14
|
+
settings: { service: rcm[key]!["service"] } as RequestContextMap[Key]
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
/** Retrieves RequestContextConfig out of the RPC annotations */
|
|
18
|
+
export const getConfig = <
|
|
19
|
+
RequestContextMap extends Record<string, RPCContextMap.Any>
|
|
20
|
+
>() =>
|
|
21
|
+
(rpc: AnyWithProps): GetContextConfig<RequestContextMap> => {
|
|
22
|
+
return Context.unsafeGet(rpc.annotations, Context.GenericTag("RequestContextConfig"))
|
|
35
23
|
}
|
|
36
24
|
|
|
37
|
-
|
|
38
|
-
|
|
25
|
+
// the following implements sort of builder pattern
|
|
26
|
+
// we support both sideways and upwards elimination of dependencies
|
|
27
|
+
|
|
28
|
+
// it's for dynamic middlewares
|
|
29
|
+
type GetDependsOnKeys<MW extends MiddlewareMaker> = MW extends { dependsOn: NonEmptyReadonlyArray<TagClassAny> } ? {
|
|
39
30
|
[K in keyof MW["dependsOn"]]: MW["dependsOn"][K] extends AnyDynamic ? MW["dependsOn"][K]["dynamic"]["key"]
|
|
40
31
|
: never
|
|
41
32
|
}[keyof MW["dependsOn"]]
|
|
42
33
|
: never
|
|
43
34
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
35
|
+
type FilterInDynamicMiddlewares<
|
|
36
|
+
MWs extends ReadonlyArray<MiddlewareMaker>,
|
|
37
|
+
RequestContextMap extends Record<string, RPCContextMap.Any>
|
|
38
|
+
> = {
|
|
39
|
+
[K in keyof MWs]: MWs[K] extends { dynamic: RpcDynamic<any, RequestContextMap[keyof RequestContextMap]> } ? MWs[K]
|
|
40
|
+
: never
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
type RecursiveHandleMWsSideways<
|
|
44
|
+
MWs,
|
|
45
|
+
R extends {
|
|
46
|
+
rcm: Record<string, RPCContextMap.Any>
|
|
47
|
+
provided: keyof R["rcm"] // that's fine
|
|
48
|
+
middlewares: ReadonlyArray<MiddlewareMaker>
|
|
49
|
+
dmp: any
|
|
50
|
+
middlewareR: any
|
|
51
|
+
}
|
|
52
|
+
> = MWs extends [
|
|
53
|
+
infer F extends MiddlewareMaker,
|
|
54
|
+
...infer Rest extends ReadonlyArray<MiddlewareMaker>
|
|
55
|
+
] ? RecursiveHandleMWsSideways<Rest, {
|
|
56
|
+
rcm: R["rcm"]
|
|
57
|
+
// when one dynamic middleware depends on another, subtract the key to enforce the dependency to be provided after
|
|
58
|
+
// (if already provided, it would have to be re-provided anyway, so better to provide it after)
|
|
59
|
+
provided: Exclude<
|
|
60
|
+
R["provided"] | FilterInDynamicMiddlewares<[F], R["rcm"]>[number]["dynamic"]["key"],
|
|
61
|
+
// F is fine here because only dynamic middlewares will have 'dependsOn' prop
|
|
62
|
+
GetDependsOnKeys<F>
|
|
63
|
+
>
|
|
64
|
+
middlewares: [...R["middlewares"], F]
|
|
65
|
+
dmp: [FilterInDynamicMiddlewares<[F], R["rcm"]>[number]] extends [never] ? R["dmp"]
|
|
66
|
+
:
|
|
67
|
+
& R["dmp"]
|
|
68
|
+
& {
|
|
69
|
+
[U in FilterInDynamicMiddlewares<[F], R["rcm"]>[number] as U["dynamic"]["key"]]: U
|
|
70
|
+
}
|
|
71
|
+
middlewareR: MiddlewareMaker.ApplyManyServices<[F], R["middlewareR"]>
|
|
72
|
+
}>
|
|
73
|
+
: R
|
|
74
|
+
|
|
75
|
+
export interface BuildingMiddleware<
|
|
76
|
+
RequestContextMap extends Record<string, RPCContextMap.Any>,
|
|
77
|
+
Provided extends keyof RequestContextMap,
|
|
78
|
+
Middlewares extends ReadonlyArray<MiddlewareMaker>,
|
|
48
79
|
DynamicMiddlewareProviders,
|
|
49
|
-
out MiddlewareR
|
|
80
|
+
out MiddlewareR extends { _tag: string } = never
|
|
50
81
|
> {
|
|
51
|
-
middleware<
|
|
52
|
-
...mw:
|
|
53
|
-
):
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
[...Middlewares, ...MW],
|
|
72
|
-
DynamicMiddlewareProviders,
|
|
73
|
-
GenericMiddlewareMaker.ApplyManyServices<MW, MiddlewareR>
|
|
82
|
+
middleware<MWs extends NonEmptyArray<MiddlewareMaker>>(
|
|
83
|
+
...mw: MWs
|
|
84
|
+
): RecursiveHandleMWsSideways<MWs, {
|
|
85
|
+
rcm: RequestContextMap
|
|
86
|
+
provided: Provided
|
|
87
|
+
middlewares: Middlewares
|
|
88
|
+
dmp: DynamicMiddlewareProviders
|
|
89
|
+
middlewareR: MiddlewareR
|
|
90
|
+
}> extends infer Res extends {
|
|
91
|
+
rcm: RequestContextMap
|
|
92
|
+
provided: keyof RequestContextMap
|
|
93
|
+
middlewares: ReadonlyArray<MiddlewareMaker>
|
|
94
|
+
dmp: any
|
|
95
|
+
middlewareR: any
|
|
96
|
+
} ? MiddlewaresBuilder<
|
|
97
|
+
Res["rcm"],
|
|
98
|
+
Res["provided"],
|
|
99
|
+
Res["middlewares"],
|
|
100
|
+
Res["dmp"],
|
|
101
|
+
Res["middlewareR"]
|
|
74
102
|
>
|
|
103
|
+
: never
|
|
104
|
+
|
|
105
|
+
// helps debugging what are the missing requirements (type only)
|
|
106
|
+
missing: {
|
|
107
|
+
missingDynamicMiddlewares: Exclude<keyof RequestContextMap, Provided>
|
|
108
|
+
missingContext: MiddlewareR
|
|
109
|
+
}
|
|
75
110
|
}
|
|
76
111
|
|
|
77
|
-
type
|
|
78
|
-
|
|
79
|
-
Provided extends keyof
|
|
80
|
-
Middlewares extends ReadonlyArray<
|
|
112
|
+
export type MiddlewaresBuilder<
|
|
113
|
+
RequestContextMap extends Record<string, RPCContextMap.Any>,
|
|
114
|
+
Provided extends keyof RequestContextMap = never,
|
|
115
|
+
Middlewares extends ReadonlyArray<MiddlewareMaker> = [],
|
|
81
116
|
DynamicMiddlewareProviders = unknown,
|
|
82
|
-
MiddlewareR = never
|
|
83
|
-
> =
|
|
84
|
-
|
|
117
|
+
MiddlewareR extends { _tag: string } = never
|
|
118
|
+
> =
|
|
119
|
+
// keyof Omit<RequestContextMap, Provided> extends never is true when all the dynamic middlewares are provided
|
|
120
|
+
// MiddlewareR is never when all the required services from generic & dynamic middlewares are provided
|
|
121
|
+
keyof Omit<RequestContextMap, Provided> extends never ? [MiddlewareR] extends [never] ? ReturnType<
|
|
85
122
|
typeof makeMiddlewareBasic<
|
|
86
|
-
|
|
123
|
+
RequestContextMap,
|
|
87
124
|
Middlewares
|
|
88
125
|
>
|
|
89
126
|
>
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
: MiddlewareDynamic<
|
|
105
|
-
RequestContext,
|
|
106
|
-
Provided,
|
|
107
|
-
Middlewares,
|
|
108
|
-
DynamicMiddlewareProviders,
|
|
109
|
-
MiddlewareR
|
|
110
|
-
>
|
|
127
|
+
: BuildingMiddleware<
|
|
128
|
+
RequestContextMap,
|
|
129
|
+
Provided,
|
|
130
|
+
Middlewares,
|
|
131
|
+
DynamicMiddlewareProviders,
|
|
132
|
+
MiddlewareR
|
|
133
|
+
>
|
|
134
|
+
: BuildingMiddleware<
|
|
135
|
+
RequestContextMap,
|
|
136
|
+
Provided,
|
|
137
|
+
Middlewares,
|
|
138
|
+
DynamicMiddlewareProviders,
|
|
139
|
+
MiddlewareR
|
|
140
|
+
>
|
|
111
141
|
|
|
112
142
|
export const makeMiddleware: <
|
|
113
143
|
RequestContextMap extends Record<string, RPCContextMap.Any>
|
|
114
|
-
>() =>
|
|
115
|
-
let allMiddleware:
|
|
144
|
+
>(rcm: RequestContextMap) => MiddlewaresBuilder<RequestContextMap> = (rcm) => {
|
|
145
|
+
let allMiddleware: MiddlewareMaker[] = []
|
|
116
146
|
const it = {
|
|
117
147
|
middleware: (...middlewares: any[]) => {
|
|
118
148
|
for (const mw of middlewares) {
|
|
149
|
+
// recall that we run middlewares in reverse order
|
|
119
150
|
allMiddleware = [mw, ...allMiddleware]
|
|
120
151
|
}
|
|
121
|
-
|
|
122
|
-
|
|
152
|
+
return allMiddleware.filter((m) => !!m.dynamic).length !== Object.keys(rcm).length
|
|
153
|
+
// for sure, until all the dynamic middlewares are provided it's non sensical to call makeMiddlewareBasic
|
|
154
|
+
? it
|
|
155
|
+
// actually, we don't know yet if MiddlewareR is never, but we can't easily check it at runtime
|
|
156
|
+
: Object.assign(makeMiddlewareBasic<any, any>(rcm, ...allMiddleware), it)
|
|
123
157
|
}
|
|
124
158
|
}
|
|
125
159
|
return it as any
|
|
126
160
|
}
|
|
127
161
|
|
|
128
|
-
|
|
162
|
+
//
|
|
163
|
+
export interface MiddlewareMakerId {
|
|
164
|
+
readonly _id: unique symbol
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// TODO: actually end up with [Tag<A, A>, Tag<B, B>, ...]
|
|
168
|
+
type MakeTags<A> = Context.Tag<A, A>
|
|
169
|
+
|
|
170
|
+
const makeMiddlewareBasic =
|
|
129
171
|
// by setting RequestContextMap beforehand, execute contextual typing does not fuck up itself to anys
|
|
130
172
|
<
|
|
131
173
|
RequestContextMap extends Record<string, RPCContextMap.Any>,
|
|
132
|
-
|
|
133
|
-
GenericMiddlewareProviders extends ReadonlyArray<GenericMiddlewareMaker>
|
|
174
|
+
MiddlewareProviders extends ReadonlyArray<MiddlewareMaker>
|
|
134
175
|
>(
|
|
135
|
-
|
|
176
|
+
_rcm: RequestContextMap,
|
|
177
|
+
...make: MiddlewareProviders
|
|
136
178
|
) => {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
179
|
+
// reverse middlewares and wrap one after the other
|
|
180
|
+
const middleware = middlewareMaker(make)
|
|
181
|
+
|
|
182
|
+
const failures = make.map((_) => _.failure).filter(Boolean)
|
|
183
|
+
const provides = make.flatMap((_) => !_.provides ? [] : Array.isArray(_.provides) ? _.provides : [_.provides])
|
|
184
|
+
const requires = make
|
|
185
|
+
.flatMap((_) => !_.requires ? [] : Array.isArray(_.requires) ? _.requires : [_.requires])
|
|
186
|
+
.filter((_) => !provides.includes(_))
|
|
187
|
+
|
|
188
|
+
const MiddlewareMaker = Tag<MiddlewareMakerId>()("MiddlewareMaker", {
|
|
189
|
+
failure: (failures.length > 0
|
|
190
|
+
? S.Union(...failures)
|
|
191
|
+
: S.Never) as unknown as MiddlewareMaker.ManyErrors<MiddlewareProviders> extends never ? never
|
|
192
|
+
: S.Schema<MiddlewareMaker.ManyErrors<MiddlewareProviders>>,
|
|
193
|
+
requires: (requires.length > 0
|
|
194
|
+
? requires
|
|
195
|
+
: undefined) as unknown as Exclude<
|
|
196
|
+
MiddlewareMaker.ManyRequired<MiddlewareProviders>,
|
|
197
|
+
MiddlewareMaker.ManyProvided<MiddlewareProviders>
|
|
198
|
+
> extends never ? never : [
|
|
199
|
+
MakeTags<
|
|
200
|
+
Exclude<
|
|
201
|
+
MiddlewareMaker.ManyRequired<MiddlewareProviders>,
|
|
202
|
+
MiddlewareMaker.ManyProvided<MiddlewareProviders>
|
|
203
|
+
>
|
|
204
|
+
>
|
|
205
|
+
],
|
|
206
|
+
provides: (provides.length > 0
|
|
207
|
+
? provides
|
|
208
|
+
: undefined) as unknown as MiddlewareMaker.ManyProvided<MiddlewareProviders> extends never ? never : [
|
|
209
|
+
MakeTags<MiddlewareMaker.ManyProvided<MiddlewareProviders>>
|
|
210
|
+
],
|
|
211
|
+
wrap: true
|
|
212
|
+
})(
|
|
213
|
+
middleware as {
|
|
214
|
+
dependencies: typeof middleware["dependencies"]
|
|
215
|
+
effect: Effect<
|
|
216
|
+
any, // TODO: why ?
|
|
217
|
+
Effect.Error<typeof middleware["effect"]>,
|
|
218
|
+
Effect.Context<typeof middleware["effect"]>
|
|
143
219
|
>
|
|
144
|
-
_tag: "MiddlewareMaker"
|
|
145
220
|
}
|
|
146
|
-
>(
|
|
147
|
-
"MiddlewareMaker"
|
|
148
221
|
)
|
|
149
222
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
Effect.map((generic) => ({
|
|
158
|
-
_tag: "MiddlewareMaker" as const,
|
|
159
|
-
effect: makeRpcEffect<
|
|
160
|
-
RequestContextMap,
|
|
161
|
-
GenericMiddlewareMaker.Provided<GenericMiddlewareProviders[number]>
|
|
162
|
-
>()(
|
|
163
|
-
(schema, next, moduleName) => {
|
|
164
|
-
return (payload, headers) =>
|
|
165
|
-
Effect
|
|
166
|
-
.gen(function*() {
|
|
167
|
-
const basic = {
|
|
168
|
-
config: schema.config ?? {},
|
|
169
|
-
payload,
|
|
170
|
-
headers,
|
|
171
|
-
clientId: 0, // TODO: get the clientId from the request context
|
|
172
|
-
rpc: {
|
|
173
|
-
...Rpc.fromTaggedRequest(schema as any),
|
|
174
|
-
key: `${moduleName}.${payload._tag}`,
|
|
175
|
-
_tag: `${moduleName}.${payload._tag}`
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
return yield* generic({
|
|
179
|
-
...basic,
|
|
180
|
-
next: next(payload, headers) as any
|
|
181
|
-
})
|
|
182
|
-
}) as any // why?
|
|
183
|
-
}
|
|
184
|
-
)
|
|
185
|
-
}))
|
|
186
|
-
)
|
|
187
|
-
)
|
|
188
|
-
|
|
189
|
-
const middlewareLayer = l
|
|
190
|
-
.pipe(
|
|
191
|
-
Layer.provide(middlewares.dependencies as any)
|
|
192
|
-
) as Layer.Layer<
|
|
193
|
-
MiddlewareMakerId,
|
|
194
|
-
LayerUtils.GetLayersError<typeof middlewares.dependencies>, // what could go wrong when building the dynamic middleware provider
|
|
195
|
-
LayerUtils.GetLayersContext<typeof middlewares.dependencies>
|
|
196
|
-
>
|
|
197
|
-
|
|
198
|
-
return Object.assign(MiddlewareMaker, { Default: middlewareLayer })
|
|
223
|
+
// add to the tag a default implementation
|
|
224
|
+
return Object.assign(MiddlewareMaker, {
|
|
225
|
+
// tag to be used to retrieve the RequestContextConfig from RPC annotations
|
|
226
|
+
requestContext: Context.GenericTag<"RequestContextConfig", GetContextConfig<RequestContextMap>>(
|
|
227
|
+
"RequestContextConfig"
|
|
228
|
+
)
|
|
229
|
+
})
|
|
199
230
|
}
|
|
@@ -23,8 +23,8 @@ export class RequestCacheMiddleware extends Tag<RequestCacheMiddleware>()("Reque
|
|
|
23
23
|
}) {
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
export class
|
|
27
|
-
extends Tag<
|
|
26
|
+
export class ConfigureInterruptibilityMiddleware
|
|
27
|
+
extends Tag<ConfigureInterruptibilityMiddleware>()("ConfigureInterruptibilityMiddleware", { wrap: true })({
|
|
28
28
|
effect: Effect.succeed(({ next }) =>
|
|
29
29
|
next.pipe(
|
|
30
30
|
// TODO: make this depend on query/command, and consider if middleware also should be affected. right now it's not.
|
|
@@ -35,7 +35,7 @@ export class ConfigureInterruptibility
|
|
|
35
35
|
{
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
export class
|
|
38
|
+
export class LoggerMiddleware extends Tag<LoggerMiddleware>()("LoggerMiddleware", { wrap: true })({
|
|
39
39
|
effect: Effect.gen(function*() {
|
|
40
40
|
const devMode = yield* DevMode
|
|
41
41
|
return ({ headers, next, payload, rpc }) =>
|
|
@@ -98,6 +98,6 @@ export class MiddlewareLogger extends Tag<MiddlewareLogger>()("MiddlewareLogger"
|
|
|
98
98
|
|
|
99
99
|
export const DefaultGenericMiddlewares = [
|
|
100
100
|
RequestCacheMiddleware,
|
|
101
|
-
|
|
102
|
-
|
|
101
|
+
ConfigureInterruptibilityMiddleware,
|
|
102
|
+
LoggerMiddleware
|
|
103
103
|
] as const
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
// codegen:start {preset: barrel, include: ./middleware/*.ts, nodir: false }
|
|
2
|
-
export * from "./middleware/ContextProvider.js"
|
|
3
2
|
export * from "./middleware/dynamic-middleware.js"
|
|
4
3
|
export * from "./middleware/generic-middleware.js"
|
|
5
4
|
export * from "./middleware/middleware-api.js"
|
package/src/api/routing.ts
CHANGED
|
@@ -167,13 +167,17 @@ export const makeRouter = <
|
|
|
167
167
|
RequestContextMap extends Record<string, RPCContextMap.Any>,
|
|
168
168
|
MakeMiddlewareE,
|
|
169
169
|
MakeMiddlewareR,
|
|
170
|
-
ContextProviderA
|
|
170
|
+
ContextProviderA,
|
|
171
|
+
ContextProviderE,
|
|
172
|
+
ContextProviderR
|
|
171
173
|
>(
|
|
172
174
|
middleware: RouterMiddleware<
|
|
173
175
|
RequestContextMap,
|
|
174
176
|
MakeMiddlewareE,
|
|
175
177
|
MakeMiddlewareR,
|
|
176
|
-
ContextProviderA
|
|
178
|
+
ContextProviderA,
|
|
179
|
+
ContextProviderE,
|
|
180
|
+
ContextProviderR
|
|
177
181
|
>,
|
|
178
182
|
devMode: boolean
|
|
179
183
|
) => {
|
|
@@ -370,7 +374,6 @@ export const makeRouter = <
|
|
|
370
374
|
: make
|
|
371
375
|
|
|
372
376
|
const controllers = yield* make
|
|
373
|
-
const rpc = yield* middleware
|
|
374
377
|
|
|
375
378
|
// return make.pipe(Effect.map((c) => controllers(c, dependencies)))
|
|
376
379
|
const mapped = typedKeysOf(requestModules).reduce((acc, cur) => {
|
|
@@ -400,16 +403,12 @@ export const makeRouter = <
|
|
|
400
403
|
}
|
|
401
404
|
} as any
|
|
402
405
|
: resource,
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
})
|
|
410
|
-
),
|
|
411
|
-
meta.moduleName
|
|
412
|
-
),
|
|
406
|
+
(payload: any, headers: any) =>
|
|
407
|
+
handle(payload, headers).pipe(
|
|
408
|
+
Effect.withSpan("Request." + resource._tag, {
|
|
409
|
+
captureStackTrace: () => handler.stack // capturing the handler stack is the main reason why we are doing the span here
|
|
410
|
+
})
|
|
411
|
+
),
|
|
413
412
|
meta.moduleName
|
|
414
413
|
] as const
|
|
415
414
|
return acc
|
|
@@ -431,16 +430,19 @@ export const makeRouter = <
|
|
|
431
430
|
]
|
|
432
431
|
}
|
|
433
432
|
|
|
434
|
-
const rpcs = RpcGroup
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
433
|
+
const rpcs = RpcGroup
|
|
434
|
+
.make(
|
|
435
|
+
...typedValuesOf(mapped).map(([resource]) => {
|
|
436
|
+
return Rpc.fromTaggedRequest(resource).annotate(middleware.requestContext, resource.config ?? {})
|
|
437
|
+
})
|
|
438
|
+
)
|
|
439
|
+
.prefix(`${meta.moduleName}.`)
|
|
440
|
+
.middleware(middleware as any)
|
|
439
441
|
const rpcLayer = rpcs.toLayer(Effect.gen(function*() {
|
|
440
442
|
return typedValuesOf(mapped).reduce((acc, [resource, handler]) => {
|
|
441
|
-
acc[resource._tag] = handler
|
|
443
|
+
acc[`${meta.moduleName}.${resource._tag}`] = handler
|
|
442
444
|
return acc
|
|
443
|
-
}, {} as Record<string, any>)
|
|
445
|
+
}, {} as Record<string, any>) as any // TODO
|
|
444
446
|
})) as unknown as Layer<
|
|
445
447
|
{ [K in keyof RequestModules]: Rpc.Handler<K> },
|
|
446
448
|
| Layer.Error<typeof middleware.Default>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
3
|
-
import { expectTypeOf } from "@effect/vitest"
|
|
3
|
+
import { expectTypeOf, it } from "@effect/vitest"
|
|
4
4
|
import { Context, Effect, Scope } from "effect-app"
|
|
5
|
-
import { ContextProvider, mergeContextProviders, MergedContextProvider } from "../src/api/
|
|
5
|
+
import { ContextProvider, mergeContextProviders, MergedContextProvider } from "../src/api/ContextProvider.js"
|
|
6
6
|
import { CustomError1, Some, SomeElse, SomeService } from "./fixtures.js"
|
|
7
7
|
|
|
8
8
|
// @effect-diagnostics-next-line missingEffectServiceDependency:off
|
|
@@ -119,33 +119,36 @@ export const someContextProviderGen = ContextProvider({
|
|
|
119
119
|
}
|
|
120
120
|
})
|
|
121
121
|
})
|
|
122
|
-
expectTypeOf(someContextProvider).toEqualTypeOf<typeof someContextProviderGen>()
|
|
123
122
|
|
|
124
|
-
|
|
125
|
-
|
|
123
|
+
it("works", () => {
|
|
124
|
+
expectTypeOf(someContextProvider).toEqualTypeOf<typeof someContextProviderGen>()
|
|
126
125
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
expectTypeOf(contextProvider2).toEqualTypeOf<typeof someContextProvider>()
|
|
130
|
-
expectTypeOf(contextProvider3).toEqualTypeOf<typeof contextProvider2>()
|
|
126
|
+
const merged = mergeContextProviders(MyContextProvider)
|
|
127
|
+
const mergedGen = mergeContextProviders(MyContextProviderGen)
|
|
131
128
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
expectTypeOf(
|
|
135
|
-
expectTypeOf(
|
|
129
|
+
const contextProvider2 = ContextProvider(merged)
|
|
130
|
+
const contextProvider3 = MergedContextProvider(MyContextProvider)
|
|
131
|
+
expectTypeOf(contextProvider2).toEqualTypeOf<typeof someContextProvider>()
|
|
132
|
+
expectTypeOf(contextProvider3).toEqualTypeOf<typeof contextProvider2>()
|
|
136
133
|
|
|
137
|
-
|
|
138
|
-
|
|
134
|
+
const contextProvider2Gen = ContextProvider(mergedGen)
|
|
135
|
+
const contextProvider3Gen = MergedContextProvider(MyContextProviderGen)
|
|
136
|
+
expectTypeOf(contextProvider2Gen).toEqualTypeOf<typeof someContextProvider>()
|
|
137
|
+
expectTypeOf(contextProvider3Gen).toEqualTypeOf<typeof contextProvider2Gen>()
|
|
139
138
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
export const contextProvider23 = MergedContextProvider(MyContextProvider, MyContextProvider2)
|
|
143
|
-
expectTypeOf(contextProvider23).toEqualTypeOf<typeof contextProvider22>()
|
|
139
|
+
expectTypeOf(contextProvider2Gen).toEqualTypeOf<typeof contextProvider2>()
|
|
140
|
+
expectTypeOf(contextProvider3Gen).toEqualTypeOf<typeof contextProvider3>()
|
|
144
141
|
|
|
145
|
-
const
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
expectTypeOf(
|
|
142
|
+
const merged2 = mergeContextProviders(MyContextProvider, MyContextProvider2)
|
|
143
|
+
const contextProvider22 = ContextProvider(merged2)
|
|
144
|
+
const contextProvider23 = MergedContextProvider(MyContextProvider, MyContextProvider2)
|
|
145
|
+
expectTypeOf(contextProvider23).toEqualTypeOf<typeof contextProvider22>()
|
|
149
146
|
|
|
150
|
-
|
|
151
|
-
|
|
147
|
+
const merged2Gen = mergeContextProviders(MyContextProviderGen, MyContextProvider2Gen)
|
|
148
|
+
const contextProvider22Gen = ContextProvider(merged2Gen)
|
|
149
|
+
const contextProvider23Gen = MergedContextProvider(MyContextProviderGen, MyContextProvider2Gen)
|
|
150
|
+
expectTypeOf(contextProvider23Gen).toEqualTypeOf<typeof contextProvider22Gen>()
|
|
151
|
+
|
|
152
|
+
expectTypeOf(contextProvider22Gen).toEqualTypeOf<typeof contextProvider22>()
|
|
153
|
+
expectTypeOf(contextProvider23Gen).toEqualTypeOf<typeof contextProvider23>()
|
|
154
|
+
})
|