@effect-app/infra 2.76.0 → 2.78.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 +18 -0
- package/dist/Emailer/service.d.ts +1 -1
- package/dist/MainFiberSet.d.ts +1 -1
- package/dist/Operations.d.ts +1 -1
- package/dist/RequestFiberSet.d.ts +1 -1
- package/dist/Store/service.d.ts +2 -2
- package/dist/adapters/SQL/Model.d.ts +6 -6
- package/dist/adapters/ServiceBus.d.ts +1 -1
- package/dist/adapters/memQueue.d.ts +1 -1
- package/dist/api/layerUtils.d.ts +10 -2
- package/dist/api/layerUtils.d.ts.map +1 -1
- package/dist/api/layerUtils.js +25 -2
- package/dist/api/routing/middleware/ContextProvider.d.ts.map +1 -1
- package/dist/api/routing/middleware/ContextProvider.js +3 -2
- package/dist/api/routing/middleware/DynamicMiddleware.d.ts +4 -4
- package/dist/api/routing/middleware/DynamicMiddleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/DynamicMiddleware.js +18 -12
- 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/dynamic-middleware.js +4 -25
- package/dist/api/routing/middleware/generic-middleware.d.ts +10 -1
- package/dist/api/routing/middleware/generic-middleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/generic-middleware.js +8 -9
- package/dist/api/routing/middleware/middleware.d.ts +4 -10
- package/dist/api/routing/middleware/middleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/middleware.js +36 -48
- package/package.json +5 -5
- package/src/api/layerUtils.ts +39 -2
- package/src/api/routing/middleware/ContextProvider.ts +2 -2
- package/src/api/routing/middleware/DynamicMiddleware.ts +36 -30
- package/src/api/routing/middleware/dynamic-middleware.ts +3 -39
- package/src/api/routing/middleware/generic-middleware.ts +19 -12
- package/src/api/routing/middleware/middleware.ts +55 -86
- package/test/controller.test.ts +5 -9
- package/test/dist/controller.test.d.ts.map +1 -1
|
@@ -1,80 +1,49 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
1
2
|
import { Cause, Context, Effect, ParseResult } from "effect-app"
|
|
2
|
-
import { HttpHeaders, type HttpRouter, 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 { RequestCacheLayers } from "../../routing.js"
|
|
6
|
+
import { genericMiddleware, RequestCacheLayers } from "../../routing.js"
|
|
7
7
|
|
|
8
8
|
const logRequestError = logError("Request")
|
|
9
9
|
const reportRequestError = reportError("Request")
|
|
10
10
|
|
|
11
11
|
export class DevMode extends Context.Reference<DevMode>()("DevMode", { defaultValue: () => false }) {}
|
|
12
|
-
|
|
12
|
+
// Effect Rpc Middleware: Wrap
|
|
13
13
|
export class RequestCacheMiddleware extends Effect.Service<RequestCacheMiddleware>()("RequestCacheMiddleware", {
|
|
14
14
|
effect: Effect.gen(function*() {
|
|
15
|
-
return
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
) =>
|
|
19
|
-
Effect.fnUntraced(function*(input: any, headers: HttpHeaders.Headers) {
|
|
20
|
-
return yield* handle(input, headers).pipe(Effect.provide(RequestCacheLayers))
|
|
21
|
-
})
|
|
15
|
+
return genericMiddleware(Effect.fnUntraced(function*(options) {
|
|
16
|
+
return yield* options.next.pipe(Effect.provide(RequestCacheLayers))
|
|
17
|
+
}))
|
|
22
18
|
})
|
|
23
19
|
}) {}
|
|
24
20
|
|
|
21
|
+
// Effect Rpc Middleware: Wrap
|
|
25
22
|
export class ConfigureInterruptibility extends Effect.Service<ConfigureInterruptibility>()(
|
|
26
23
|
"ConfigureInterruptibility",
|
|
27
24
|
{
|
|
28
25
|
effect: Effect.gen(function*() {
|
|
29
|
-
return
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
// TODO: make this depend on query/command, and consider if middleware also should be affected. right now it's not.
|
|
36
|
-
Effect.uninterruptible
|
|
37
|
-
)
|
|
38
|
-
})
|
|
26
|
+
return genericMiddleware(Effect.fnUntraced(function*(options) {
|
|
27
|
+
return yield* options.next.pipe(
|
|
28
|
+
// TODO: make this depend on query/command, and consider if middleware also should be affected. right now it's not.
|
|
29
|
+
Effect.uninterruptible
|
|
30
|
+
)
|
|
31
|
+
}))
|
|
39
32
|
})
|
|
40
33
|
}
|
|
41
34
|
) {}
|
|
42
35
|
|
|
43
|
-
|
|
44
|
-
extends Effect.Service<CaptureHttpHeadersAsRpcHeaders>()("CaptureHttpHeadersAsRpcHeaders", {
|
|
45
|
-
effect: Effect.gen(function*() {
|
|
46
|
-
return <A, E>(
|
|
47
|
-
handle: (input: any, headers: HttpHeaders.Headers) => Effect.Effect<A, E, HttpRouter.HttpRouter.Provided>,
|
|
48
|
-
_moduleName: string
|
|
49
|
-
) =>
|
|
50
|
-
Effect.fnUntraced(function*(input: any, rpcHeaders: HttpHeaders.Headers) {
|
|
51
|
-
// merge in the request headers
|
|
52
|
-
// we should consider if we should merge them into rpc headers on the Protocol layer instead.
|
|
53
|
-
const httpReq = yield* HttpServerRequest.HttpServerRequest
|
|
54
|
-
const headers = HttpHeaders.merge(httpReq.headers, rpcHeaders)
|
|
55
|
-
return yield* handle(input, headers)
|
|
56
|
-
})
|
|
57
|
-
})
|
|
58
|
-
})
|
|
59
|
-
{}
|
|
60
|
-
|
|
36
|
+
// Effect Rpc Middleware: Wrap
|
|
61
37
|
export class MiddlewareLogger extends Effect.Service<MiddlewareLogger>()("MiddlewareLogger", {
|
|
62
38
|
effect: Effect.gen(function*() {
|
|
63
|
-
return
|
|
64
|
-
|
|
65
|
-
moduleName: string
|
|
66
|
-
) =>
|
|
67
|
-
Effect.fnUntraced(function*(input: any, rpcHeaders: HttpHeaders.Headers) {
|
|
68
|
-
const devMode = yield* DevMode
|
|
69
|
-
// merge in the request headers
|
|
70
|
-
// we should consider if we should merge them into rpc headers on the Protocol layer instead.
|
|
71
|
-
const httpReq = yield* HttpServerRequest.HttpServerRequest
|
|
72
|
-
const headers = HttpHeaders.merge(httpReq.headers, rpcHeaders)
|
|
39
|
+
return genericMiddleware(Effect.fnUntraced(function*({ headers, next, payload, rpc }) {
|
|
40
|
+
const devMode = yield* DevMode
|
|
73
41
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
42
|
+
return yield* Effect
|
|
43
|
+
.annotateCurrentSpan(
|
|
44
|
+
"requestInput",
|
|
45
|
+
typeof payload === "object" && payload !== null
|
|
46
|
+
? Object.entries(payload).reduce((prev, [key, value]: [string, unknown]) => {
|
|
78
47
|
prev[key] = key === "password"
|
|
79
48
|
? "<redacted>"
|
|
80
49
|
: typeof value === "string" || typeof value === "number" || typeof value === "boolean"
|
|
@@ -90,45 +59,45 @@ export class MiddlewareLogger extends Effect.Service<MiddlewareLogger>()("Middle
|
|
|
90
59
|
: typeof value
|
|
91
60
|
return prev
|
|
92
61
|
}, {} as Record<string, string | number | boolean>)
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
)
|
|
125
|
-
|
|
62
|
+
: payload
|
|
63
|
+
)
|
|
64
|
+
.pipe(
|
|
65
|
+
// can't use andThen due to some being a function and effect
|
|
66
|
+
Effect.zipRight(next),
|
|
67
|
+
// TODO: support ParseResult if the error channel of the request allows it.. but who would want that?
|
|
68
|
+
Effect.catchAll((_) => ParseResult.isParseError(_) ? Effect.die(_) : Effect.fail(_)),
|
|
69
|
+
Effect.tapErrorCause((cause) => Cause.isFailure(cause) ? logRequestError(cause) : Effect.void),
|
|
70
|
+
Effect.tapDefect((cause) =>
|
|
71
|
+
Effect
|
|
72
|
+
.all([
|
|
73
|
+
reportRequestError(cause, {
|
|
74
|
+
action: rpc._tag
|
|
75
|
+
}),
|
|
76
|
+
InfraLogger
|
|
77
|
+
.logError("Finished request", cause)
|
|
78
|
+
.pipe(Effect.annotateLogs({
|
|
79
|
+
action: rpc._tag,
|
|
80
|
+
req: pretty(payload),
|
|
81
|
+
headers: pretty(headers)
|
|
82
|
+
// resHeaders: pretty(
|
|
83
|
+
// Object
|
|
84
|
+
// .entries(headers)
|
|
85
|
+
// .reduce((prev, [key, value]) => {
|
|
86
|
+
// prev[key] = value && typeof value === "string" ? snipString(value) : value
|
|
87
|
+
// return prev
|
|
88
|
+
// }, {} as Record<string, any>)
|
|
89
|
+
// )
|
|
90
|
+
}))
|
|
91
|
+
])
|
|
92
|
+
),
|
|
93
|
+
devMode ? (_) => _ : Effect.catchAllDefect(() => Effect.die("Internal Server Error"))
|
|
94
|
+
)
|
|
95
|
+
}))
|
|
126
96
|
})
|
|
127
97
|
}) {}
|
|
128
98
|
|
|
129
99
|
export const DefaultGenericMiddlewares = [
|
|
130
100
|
RequestCacheMiddleware,
|
|
131
101
|
ConfigureInterruptibility,
|
|
132
|
-
CaptureHttpHeadersAsRpcHeaders,
|
|
133
102
|
MiddlewareLogger
|
|
134
103
|
] as const
|
package/test/controller.test.ts
CHANGED
|
@@ -5,9 +5,9 @@ import type { RequestContext } from "@effect-app/infra/RequestContext"
|
|
|
5
5
|
import { expect, expectTypeOf, it } from "@effect/vitest"
|
|
6
6
|
import { type Array, Context, Effect, Layer, Option, S } from "effect-app"
|
|
7
7
|
import { InvalidStateError, makeRpcClient, type RPCContextMap, UnauthorizedError } from "effect-app/client"
|
|
8
|
-
import {
|
|
8
|
+
import { HttpServerRequest } from "effect-app/http"
|
|
9
9
|
import { Class, TaggedError } from "effect-app/Schema"
|
|
10
|
-
import { ContextProvider, DefaultGenericMiddlewares, implementMiddleware, makeMiddleware, mergeContextProviders, MergedContextProvider } from "../src/api/routing/middleware.js"
|
|
10
|
+
import { ContextProvider, DefaultGenericMiddlewares, genericMiddleware, implementMiddleware, makeMiddleware, mergeContextProviders, MergedContextProvider } from "../src/api/routing/middleware.js"
|
|
11
11
|
import { sort } from "../src/api/routing/tsort.js"
|
|
12
12
|
import { SomeService } from "./query.test.js"
|
|
13
13
|
|
|
@@ -171,13 +171,9 @@ class Test extends Effect.Service<Test>()("Test", {
|
|
|
171
171
|
|
|
172
172
|
export class BogusMiddleware extends Effect.Service<BogusMiddleware>()("BogusMiddleware", {
|
|
173
173
|
effect: Effect.gen(function*() {
|
|
174
|
-
return
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
) =>
|
|
178
|
-
Effect.fnUntraced(function*(input: any, headers: HttpHeaders.Headers) {
|
|
179
|
-
return yield* handle(input, headers)
|
|
180
|
-
})
|
|
174
|
+
return genericMiddleware(Effect.fnUntraced(function*(options) {
|
|
175
|
+
return yield* options.next
|
|
176
|
+
}))
|
|
181
177
|
})
|
|
182
178
|
}) {}
|
|
183
179
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controller.test.d.ts","sourceRoot":"","sources":["../controller.test.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAc,MAAM,+BAA+B,CAAA;AAC7F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAA;AAEtE,OAAO,EAAE,KAAK,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,YAAY,CAAA;AAC1E,OAAO,EAAoC,KAAK,aAAa,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAC3G,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"controller.test.d.ts","sourceRoot":"","sources":["../controller.test.ts"],"names":[],"mappings":"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"}
|