@effect-app/infra 3.10.0 → 4.0.0-beta.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 +11 -0
- package/_check.sh +3 -0
- package/dist/CUPS.d.ts +22 -12
- package/dist/CUPS.d.ts.map +1 -1
- package/dist/CUPS.js +28 -29
- package/dist/Emailer/Sendgrid.js +13 -12
- package/dist/Emailer/service.d.ts +3 -13
- package/dist/Emailer/service.d.ts.map +1 -1
- package/dist/Emailer/service.js +3 -3
- package/dist/MainFiberSet.d.ts +18 -41
- package/dist/MainFiberSet.d.ts.map +1 -1
- package/dist/MainFiberSet.js +10 -10
- package/dist/Model/Repository/ext.d.ts.map +1 -1
- package/dist/Model/Repository/ext.js +13 -10
- package/dist/Model/Repository/internal/internal.d.ts +5 -5
- package/dist/Model/Repository/internal/internal.d.ts.map +1 -1
- package/dist/Model/Repository/internal/internal.js +52 -42
- package/dist/Model/Repository/legacy.d.ts +9 -9
- package/dist/Model/Repository/legacy.d.ts.map +1 -1
- package/dist/Model/Repository/makeRepo.d.ts +4 -4
- package/dist/Model/Repository/makeRepo.d.ts.map +1 -1
- package/dist/Model/Repository/makeRepo.js +1 -1
- package/dist/Model/Repository/service.d.ts +11 -11
- package/dist/Model/Repository/service.d.ts.map +1 -1
- package/dist/Model/Repository/validation.d.ts +17 -47
- package/dist/Model/Repository/validation.d.ts.map +1 -1
- package/dist/Model/Repository/validation.js +2 -2
- package/dist/Model/query/dsl.d.ts +22 -22
- package/dist/Model/query/dsl.d.ts.map +1 -1
- package/dist/Model/query/dsl.js +1 -1
- package/dist/Model/query/new-kid-interpreter.d.ts +1 -1
- package/dist/Model/query/new-kid-interpreter.js +7 -7
- package/dist/Operations.d.ts +22 -63
- package/dist/Operations.d.ts.map +1 -1
- package/dist/Operations.js +14 -14
- package/dist/OperationsRepo.d.ts +23 -7
- package/dist/OperationsRepo.d.ts.map +1 -1
- package/dist/OperationsRepo.js +4 -5
- package/dist/QueueMaker/SQLQueue.d.ts +6 -8
- package/dist/QueueMaker/SQLQueue.d.ts.map +1 -1
- package/dist/QueueMaker/SQLQueue.js +20 -24
- package/dist/QueueMaker/errors.js +1 -1
- package/dist/QueueMaker/memQueue.d.ts +2 -5
- package/dist/QueueMaker/memQueue.d.ts.map +1 -1
- package/dist/QueueMaker/memQueue.js +22 -26
- package/dist/QueueMaker/sbqueue.d.ts +2 -5
- package/dist/QueueMaker/sbqueue.d.ts.map +1 -1
- package/dist/QueueMaker/sbqueue.js +24 -28
- package/dist/RequestContext.d.ts +28 -41
- package/dist/RequestContext.d.ts.map +1 -1
- package/dist/RequestContext.js +4 -4
- package/dist/RequestFiberSet.d.ts +23 -50
- package/dist/RequestFiberSet.d.ts.map +1 -1
- package/dist/RequestFiberSet.js +14 -14
- package/dist/Store/ContextMapContainer.d.ts +4 -4
- package/dist/Store/ContextMapContainer.d.ts.map +1 -1
- package/dist/Store/ContextMapContainer.js +5 -5
- package/dist/Store/Cosmos.d.ts.map +1 -1
- package/dist/Store/Cosmos.js +21 -28
- package/dist/Store/Disk.d.ts.map +1 -1
- package/dist/Store/Disk.js +12 -16
- package/dist/Store/Memory.d.ts +2 -2
- package/dist/Store/Memory.d.ts.map +1 -1
- package/dist/Store/Memory.js +25 -33
- package/dist/Store/index.js +2 -2
- package/dist/Store/service.d.ts +9 -34
- package/dist/Store/service.d.ts.map +1 -1
- package/dist/Store/service.js +4 -4
- package/dist/Store/utils.d.ts.map +1 -1
- package/dist/Store/utils.js +10 -2
- package/dist/adapters/SQL/Model.d.ts +106 -162
- package/dist/adapters/SQL/Model.d.ts.map +1 -1
- package/dist/adapters/SQL/Model.js +92 -130
- package/dist/adapters/ServiceBus.d.ts +13 -44
- package/dist/adapters/ServiceBus.d.ts.map +1 -1
- package/dist/adapters/ServiceBus.js +13 -15
- package/dist/adapters/cosmos-client.d.ts +7 -3
- package/dist/adapters/cosmos-client.d.ts.map +1 -1
- package/dist/adapters/cosmos-client.js +5 -4
- package/dist/adapters/logger.d.ts +1 -1
- package/dist/adapters/logger.d.ts.map +1 -1
- package/dist/adapters/memQueue.d.ts +8 -21
- package/dist/adapters/memQueue.d.ts.map +1 -1
- package/dist/adapters/memQueue.js +4 -4
- package/dist/adapters/mongo-client.d.ts +6 -6
- package/dist/adapters/mongo-client.d.ts.map +1 -1
- package/dist/adapters/mongo-client.js +5 -4
- package/dist/adapters/redis-client.d.ts +14 -4
- package/dist/adapters/redis-client.d.ts.map +1 -1
- package/dist/adapters/redis-client.js +19 -18
- package/dist/api/ContextProvider.d.ts +10 -15
- package/dist/api/ContextProvider.d.ts.map +1 -1
- package/dist/api/ContextProvider.js +8 -8
- package/dist/api/codec.d.ts +1 -1
- package/dist/api/codec.d.ts.map +1 -1
- package/dist/api/codec.js +1 -1
- package/dist/api/internal/RequestContextMiddleware.d.ts +1 -1
- package/dist/api/internal/RequestContextMiddleware.d.ts.map +1 -1
- package/dist/api/internal/auth.d.ts +3 -3
- package/dist/api/internal/auth.d.ts.map +1 -1
- package/dist/api/internal/auth.js +8 -8
- package/dist/api/internal/events.d.ts +2 -2
- package/dist/api/internal/events.d.ts.map +1 -1
- package/dist/api/internal/events.js +9 -9
- package/dist/api/internal/health.d.ts +1 -1
- package/dist/api/internal/health.d.ts.map +1 -1
- package/dist/api/internal/health.js +2 -2
- package/dist/api/layerUtils.d.ts +14 -14
- package/dist/api/layerUtils.d.ts.map +1 -1
- package/dist/api/layerUtils.js +5 -5
- package/dist/api/middlewares.d.ts +0 -75
- package/dist/api/middlewares.d.ts.map +1 -1
- package/dist/api/middlewares.js +6 -51
- package/dist/api/reportError.js +4 -4
- package/dist/api/routing/middleware/RouterMiddleware.d.ts +4 -4
- package/dist/api/routing/middleware/RouterMiddleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/middleware.d.ts +6 -7
- package/dist/api/routing/middleware/middleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/middleware.js +9 -13
- package/dist/api/routing/schema/jwt.d.ts +1 -1
- package/dist/api/routing/schema/jwt.d.ts.map +1 -1
- package/dist/api/routing/schema/jwt.js +5 -4
- package/dist/api/routing/utils.d.ts +2 -2
- package/dist/api/routing/utils.d.ts.map +1 -1
- package/dist/api/routing/utils.js +10 -8
- package/dist/api/routing.d.ts +39 -37
- package/dist/api/routing.d.ts.map +1 -1
- package/dist/api/routing.js +17 -21
- package/dist/api/setupRequest.d.ts +4 -6
- package/dist/api/setupRequest.d.ts.map +1 -1
- package/dist/api/setupRequest.js +10 -9
- package/dist/arbs.d.ts +3 -3
- package/dist/arbs.d.ts.map +1 -1
- package/dist/arbs.js +2 -2
- package/dist/errorReporter.d.ts +1 -1
- package/dist/errorReporter.d.ts.map +1 -1
- package/dist/errorReporter.js +12 -12
- package/dist/fileUtil.d.ts +6 -6
- package/dist/fileUtil.d.ts.map +1 -1
- package/dist/logger/jsonLogger.d.ts.map +1 -1
- package/dist/logger/jsonLogger.js +19 -18
- package/dist/logger/logFmtLogger.d.ts.map +1 -1
- package/dist/logger/logFmtLogger.js +11 -13
- package/dist/logger/shared.d.ts +2 -2
- package/dist/logger/shared.d.ts.map +1 -1
- package/dist/logger/shared.js +7 -9
- package/dist/logger.d.ts +1 -1
- package/dist/logger.d.ts.map +1 -1
- package/dist/rateLimit.d.ts +2 -2
- package/dist/rateLimit.d.ts.map +1 -1
- package/dist/rateLimit.js +5 -5
- package/dist/test.d.ts +2 -2
- package/dist/test.d.ts.map +1 -1
- package/dist/test.js +6 -24
- package/package.json +19 -22
- package/src/CUPS.ts +15 -14
- package/src/Emailer/Sendgrid.ts +15 -13
- package/src/Emailer/service.ts +3 -3
- package/src/MainFiberSet.ts +16 -12
- package/src/Model/Repository/ext.ts +18 -16
- package/src/Model/Repository/internal/internal.ts +80 -69
- package/src/Model/Repository/legacy.ts +9 -9
- package/src/Model/Repository/makeRepo.ts +5 -5
- package/src/Model/Repository/service.ts +12 -12
- package/src/Model/Repository/validation.ts +1 -1
- package/src/Model/query/dsl.ts +13 -13
- package/src/Model/query/new-kid-interpreter.ts +8 -8
- package/src/Operations.ts +17 -14
- package/src/OperationsRepo.ts +3 -4
- package/src/QueueMaker/SQLQueue.ts +86 -89
- package/src/QueueMaker/errors.ts +1 -1
- package/src/QueueMaker/memQueue.ts +90 -91
- package/src/QueueMaker/sbqueue.ts +90 -92
- package/src/RequestContext.ts +3 -3
- package/src/RequestFiberSet.ts +17 -15
- package/src/Store/ContextMapContainer.ts +4 -4
- package/src/Store/Cosmos.ts +20 -27
- package/src/Store/Disk.ts +13 -17
- package/src/Store/Memory.ts +28 -34
- package/src/Store/index.ts +1 -1
- package/src/Store/service.ts +4 -4
- package/src/Store/utils.ts +9 -5
- package/src/adapters/SQL/Model.ts +255 -268
- package/src/adapters/ServiceBus.ts +17 -20
- package/src/adapters/cosmos-client.ts +5 -5
- package/src/adapters/memQueue.ts +3 -3
- package/src/adapters/mongo-client.ts +5 -5
- package/src/adapters/redis-client.ts +25 -19
- package/src/api/ContextProvider.ts +24 -34
- package/src/api/codec.ts +1 -1
- package/src/api/internal/auth.ts +11 -13
- package/src/api/internal/events.ts +11 -11
- package/src/api/internal/health.ts +1 -1
- package/src/api/layerUtils.ts +20 -20
- package/src/api/middlewares.ts +0 -97
- package/src/api/reportError.ts +3 -3
- package/src/api/routing/middleware/RouterMiddleware.ts +5 -6
- package/src/api/routing/middleware/middleware.ts +13 -25
- package/src/api/routing/schema/jwt.ts +9 -7
- package/src/api/routing/utils.ts +12 -10
- package/src/api/routing.ts +77 -79
- package/src/api/setupRequest.ts +9 -8
- package/src/arbs.ts +3 -3
- package/src/errorReporter.ts +12 -12
- package/src/logger/jsonLogger.ts +18 -17
- package/src/logger/logFmtLogger.ts +10 -12
- package/src/logger/shared.ts +6 -8
- package/src/rateLimit.ts +7 -7
- package/src/test.ts +7 -29
- package/test/contextProvider.test.ts +77 -70
- package/test/controller.test.ts +51 -39
- 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 +33 -81
- package/test/dist/fixtures.d.ts.map +1 -1
- package/test/dist/fixtures.js +9 -8
- package/test/dist/query.test.d.ts.map +1 -1
- package/test/dist/rawQuery.test.d.ts.map +1 -1
- package/test/dist/requires.test.d.ts.map +1 -1
- package/test/dist/rpc-multi-middleware.test.d.ts.map +1 -1
- package/test/fixtures.ts +9 -7
- package/test/query.test.ts +49 -41
- package/test/rawQuery.test.ts +44 -40
- package/test/requires.test.ts +40 -31
- package/test/rpc-multi-middleware.test.ts +13 -14
- package/test/validateSample.test.ts +2 -2
- package/tsconfig.json +1 -27
- package/dist/api/internal/middlewares.d.ts +0 -15
- package/dist/api/internal/middlewares.d.ts.map +0 -1
- package/dist/api/internal/middlewares.js +0 -168
- package/src/api/internal/middlewares.ts +0 -279
package/src/api/middlewares.ts
CHANGED
|
@@ -3,105 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @since 1.0.0
|
|
5
5
|
*/
|
|
6
|
-
import type * as App from "@effect/platform/HttpApp"
|
|
7
|
-
import type { Effect } from "effect-app"
|
|
8
|
-
import type { NotLoggedInError } from "../errors.js"
|
|
9
|
-
import * as internal from "./internal/middlewares.js"
|
|
10
6
|
|
|
11
7
|
export * from "./internal/auth.js"
|
|
12
8
|
export * from "./internal/events.js"
|
|
13
9
|
export * from "./internal/health.js"
|
|
14
10
|
export * from "./internal/RequestContextMiddleware.js"
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Add access logs for handled requests. The log runs before each request.
|
|
18
|
-
* Optionally configure log level using the first argument. The default log level
|
|
19
|
-
* is `Debug`.
|
|
20
|
-
*
|
|
21
|
-
* @category logging
|
|
22
|
-
* @since 1.0.0
|
|
23
|
-
*/
|
|
24
|
-
export const accessLog: (
|
|
25
|
-
level?: "Info" | "Warning" | "Debug"
|
|
26
|
-
) => <R, E>(app: App.Default<R, E>) => App.Default<R, E> = internal.accessLog
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Annotate request logs using generated UUID. The default annotation key is `requestId`.
|
|
30
|
-
* The annotation key is configurable using the first argument.
|
|
31
|
-
*
|
|
32
|
-
* Note that in order to apply the annotation also for access logging, you should
|
|
33
|
-
* make sure the `accessLog` middleware is plugged after the `uuidLogAnnotation`.
|
|
34
|
-
*
|
|
35
|
-
* @category logging
|
|
36
|
-
* @since 1.0.0
|
|
37
|
-
*/
|
|
38
|
-
export const uuidLogAnnotation: (
|
|
39
|
-
logAnnotationKey?: string
|
|
40
|
-
) => <R, E>(app: App.Default<R, E>) => App.Default<R, E> = internal.uuidLogAnnotation
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Measure how many times each endpoint was called in a
|
|
44
|
-
* `server.endpoint_calls` counter metrics.
|
|
45
|
-
*
|
|
46
|
-
* @category metrics
|
|
47
|
-
* @since 1.0.0
|
|
48
|
-
*/
|
|
49
|
-
export const endpointCallsMetric: () => <R, E>(
|
|
50
|
-
app: App.Default<R, E>
|
|
51
|
-
) => App.Default<R, E> = internal.endpointCallsMetric
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Logs out a handler failure.
|
|
55
|
-
*
|
|
56
|
-
* @category logging
|
|
57
|
-
* @since 1.0.0
|
|
58
|
-
*/
|
|
59
|
-
export const errorLog: <R, E>(app: App.Default<R, E>) => App.Default<R, E> = internal.errorLog
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* @category models
|
|
63
|
-
* @since 1.0.0
|
|
64
|
-
*/
|
|
65
|
-
export interface BasicAuthCredentials {
|
|
66
|
-
user: string
|
|
67
|
-
password: string
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Basic auth middleware.
|
|
72
|
-
*
|
|
73
|
-
* @category authorization
|
|
74
|
-
* @since 1.0.0
|
|
75
|
-
*/
|
|
76
|
-
export const basicAuth: <R2, _>(
|
|
77
|
-
checkCredentials: (
|
|
78
|
-
credentials: BasicAuthCredentials
|
|
79
|
-
) => Effect.Effect<_, NotLoggedInError, R2>,
|
|
80
|
-
options?: Partial<{
|
|
81
|
-
headerName: string
|
|
82
|
-
skipPaths: readonly string[]
|
|
83
|
-
}>
|
|
84
|
-
) => <R1, E>(app: App.Default<E, R1>) => App.Default<E, R1 | R2> = internal.basicAuth
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* @category models
|
|
88
|
-
* @since 1.0.0
|
|
89
|
-
*/
|
|
90
|
-
export interface CorsOptions {
|
|
91
|
-
allowedOrigins: readonly string[]
|
|
92
|
-
allowedMethods: readonly string[]
|
|
93
|
-
allowedHeaders: readonly string[]
|
|
94
|
-
exposedHeaders: readonly string[]
|
|
95
|
-
maxAge: number
|
|
96
|
-
credentials: boolean
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Basic auth middleware.
|
|
101
|
-
*
|
|
102
|
-
* @category authorization
|
|
103
|
-
* @since 1.0.0
|
|
104
|
-
*/
|
|
105
|
-
export const cors: (
|
|
106
|
-
options?: Partial<CorsOptions>
|
|
107
|
-
) => <R, E>(app: App.Default<R, E>) => App.Default<R, E> = internal.cors
|
package/src/api/reportError.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { logError, reportError } from "../errorReporter.js"
|
|
|
8
8
|
// Effect.onExit(self, (exit) =>
|
|
9
9
|
// Exit.isFailure(exit)
|
|
10
10
|
// ? unknownOnly
|
|
11
|
-
// ? Cause.
|
|
11
|
+
// ? Cause.hasInterruptsOnly(exit.cause) || Cause.isDie(exit.cause)
|
|
12
12
|
// ? report(exit.cause)
|
|
13
13
|
// : log(exit.cause)
|
|
14
14
|
// : report(exit.cause)
|
|
@@ -18,9 +18,9 @@ const tapErrorCause = (name: string, unknownOnly?: boolean) => {
|
|
|
18
18
|
const report = reportError(name)
|
|
19
19
|
const log = logError(name)
|
|
20
20
|
return <A, E, R>(self: Effect.Effect<A, E, R>) =>
|
|
21
|
-
Effect.
|
|
21
|
+
Effect.tapCause(self, (cause) =>
|
|
22
22
|
unknownOnly
|
|
23
|
-
? Cause.
|
|
23
|
+
? Cause.hasFails(cause)
|
|
24
24
|
? log(cause)
|
|
25
25
|
: report(cause)
|
|
26
26
|
: report(cause))
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
3
3
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
4
|
-
import { type
|
|
5
|
-
import { type Context, type Effect, type Layer } from "effect-app"
|
|
4
|
+
import { type Layer, type ServiceMap } from "effect-app"
|
|
6
5
|
import { type GetContextConfig, type RpcContextMap } from "effect-app/rpc/RpcContextMap"
|
|
6
|
+
import { type RpcMiddlewareV4 } from "effect-app/rpc/RpcMiddleware"
|
|
7
7
|
// module:
|
|
8
8
|
//
|
|
9
9
|
|
|
10
|
+
// v4: middleware tags are ServiceMap.Service (not Effect) — they carry the RpcMiddlewareV4 as their service Shape
|
|
10
11
|
export type RouterMiddleware<
|
|
11
12
|
Self,
|
|
12
13
|
RequestContextMap extends Record<string, RpcContextMap.Any>, // what services will the middlware provide dynamically to the next, or raise errors.
|
|
@@ -17,11 +18,9 @@ export type RouterMiddleware<
|
|
|
17
18
|
_ContextProviderR, // what the context provider requires
|
|
18
19
|
RequestContextId
|
|
19
20
|
> =
|
|
20
|
-
&
|
|
21
|
-
// makes error because of TagUnify :/
|
|
22
|
-
// Context.Tag<Self, RpcMiddlewareWrap<ContextProviderA, ContextProviderE>>
|
|
21
|
+
& ServiceMap.Service<Self, RpcMiddlewareV4<ContextProviderA, ContextProviderE, never>>
|
|
23
22
|
& {
|
|
24
23
|
readonly Default: Layer.Layer<Self, MakeMiddlewareE, MakeMiddlewareR>
|
|
25
|
-
readonly requestContext:
|
|
24
|
+
readonly requestContext: ServiceMap.Service<RequestContextId, GetContextConfig<RequestContextMap>>
|
|
26
25
|
readonly requestContextMap: RequestContextMap
|
|
27
26
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
import { Cause, Config,
|
|
2
|
+
import { Cause, Config, Effect, Layer, Schema } from "effect"
|
|
3
3
|
import { ConfigureInterruptibilityMiddleware, DevMode, DevModeMiddleware, LoggerMiddleware, RequestCacheMiddleware } from "effect-app/middleware"
|
|
4
4
|
import { pretty } from "effect-app/utils"
|
|
5
5
|
import { logError, reportError } from "../../../errorReporter.js"
|
|
@@ -18,29 +18,19 @@ export const DevModeLive = Layer.effect(
|
|
|
18
18
|
})
|
|
19
19
|
)
|
|
20
20
|
|
|
21
|
-
export const RequestCacheLayers = Layer.mergeAll(
|
|
22
|
-
Layer.setRequestCache(
|
|
23
|
-
Request.makeCache({ capacity: 500, timeToLive: Duration.hours(8) })
|
|
24
|
-
),
|
|
25
|
-
Layer.setRequestCaching(true),
|
|
26
|
-
Layer.setRequestBatching(true)
|
|
27
|
-
)
|
|
28
|
-
|
|
29
21
|
export const RequestCacheMiddlewareLive = Layer.succeed(
|
|
30
22
|
RequestCacheMiddleware,
|
|
31
|
-
(effect) => effect
|
|
23
|
+
(effect) => effect
|
|
32
24
|
)
|
|
33
25
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
Schedule.intersect(Schedule.recurWhile<any>((a) => a?._tag === "OptimisticConcurrencyException"))
|
|
37
|
-
)
|
|
26
|
+
const isOptimisticConcurrencyException = (input: unknown) =>
|
|
27
|
+
typeof input === "object" && input !== null && "_tag" in input && input._tag === "OptimisticConcurrencyException"
|
|
38
28
|
|
|
39
29
|
export const ConfigureInterruptibilityMiddlewareLive = Layer.effect(
|
|
40
30
|
ConfigureInterruptibilityMiddleware,
|
|
41
31
|
Effect.gen(function*() {
|
|
42
32
|
const cache = new Map()
|
|
43
|
-
const getCached = (key: string, schema: Schema.
|
|
33
|
+
const getCached = (key: string, schema: Schema.Top) => {
|
|
44
34
|
const existing = cache.get(key)
|
|
45
35
|
if (existing) return existing
|
|
46
36
|
const n = determineMethod(key, schema)
|
|
@@ -51,7 +41,7 @@ export const ConfigureInterruptibilityMiddlewareLive = Layer.effect(
|
|
|
51
41
|
const method = getCached(rpc._tag, rpc.payloadSchema)
|
|
52
42
|
|
|
53
43
|
effect = isCommand(method)
|
|
54
|
-
? Effect.retry(Effect.uninterruptible(effect),
|
|
44
|
+
? Effect.retry(Effect.uninterruptible(effect), { times: 1, while: isOptimisticConcurrencyException })
|
|
55
45
|
: Effect.interruptible(effect)
|
|
56
46
|
|
|
57
47
|
return effect
|
|
@@ -88,12 +78,11 @@ export const LoggerMiddlewareLive = Layer
|
|
|
88
78
|
: payload
|
|
89
79
|
})
|
|
90
80
|
.pipe(
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
Effect.
|
|
95
|
-
Effect.
|
|
96
|
-
Effect.tapDefect((cause) =>
|
|
81
|
+
Effect.andThen(effect),
|
|
82
|
+
// TODO: support SchemaError if the error channel of the request allows it.. but who would want that?
|
|
83
|
+
Effect.catch((_) => Schema.isSchemaError(_) ? Effect.die(_) : Effect.fail(_)),
|
|
84
|
+
Effect.tapCause((cause) => Cause.hasFails(cause) ? logRequestError(cause) : Effect.void),
|
|
85
|
+
Effect.tapCauseIf(Cause.hasDies, (cause) =>
|
|
97
86
|
Effect
|
|
98
87
|
.all([
|
|
99
88
|
reportRequestError(cause, {
|
|
@@ -114,9 +103,8 @@ export const LoggerMiddlewareLive = Layer
|
|
|
114
103
|
// }, {} as Record<string, any>)
|
|
115
104
|
// )
|
|
116
105
|
}))
|
|
117
|
-
])
|
|
118
|
-
)
|
|
119
|
-
devMode ? (_) => _ : Effect.catchAllDefect(() => Effect.die("Internal Server Error"))
|
|
106
|
+
])),
|
|
107
|
+
devMode ? (_) => _ : Effect.catchDefect(() => Effect.die("Internal Server Error"))
|
|
120
108
|
)
|
|
121
109
|
})
|
|
122
110
|
)
|
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
3
|
+
import { Effect, Option } from "effect"
|
|
3
4
|
import * as S from "effect-app/Schema"
|
|
4
5
|
import { jwtDecode, type JwtDecodeOptions } from "jwt-decode"
|
|
5
6
|
|
|
6
|
-
export const parseJwt = <
|
|
7
|
-
schema:
|
|
7
|
+
export const parseJwt = <Sch extends S.Top>(
|
|
8
|
+
schema: Sch,
|
|
8
9
|
options?: JwtDecodeOptions
|
|
9
|
-
)
|
|
10
|
+
) =>
|
|
10
11
|
S
|
|
11
12
|
.transformToOrFail(
|
|
12
13
|
S.String,
|
|
13
14
|
S.Unknown,
|
|
14
|
-
(s,
|
|
15
|
-
|
|
15
|
+
(s, _options) =>
|
|
16
|
+
Effect.try({
|
|
16
17
|
try: () => jwtDecode(s, options),
|
|
17
|
-
catch: (e: any) =>
|
|
18
|
+
catch: (e: any) =>
|
|
19
|
+
new S.SchemaIssue.InvalidValue(Option.some(s), { message: e?.message })
|
|
18
20
|
})
|
|
19
21
|
)
|
|
20
|
-
.pipe(S.
|
|
22
|
+
.pipe(S.decodeTo(schema) as any) as any as S.decodeTo<Sch, S.String>
|
package/src/api/routing/utils.ts
CHANGED
|
@@ -1,34 +1,36 @@
|
|
|
1
|
-
import { S } from "effect-app"
|
|
2
|
-
import type { AST
|
|
1
|
+
import { S, SchemaAST } from "effect-app"
|
|
2
|
+
import type { AST } from "effect-app/Schema"
|
|
3
3
|
|
|
4
4
|
const get = ["Get", "Index", "List", "All", "Find", "Search"]
|
|
5
5
|
const del = ["Delete", "Remove", "Destroy"]
|
|
6
6
|
const patch = ["Patch", "Update", "Edit"]
|
|
7
7
|
|
|
8
8
|
const astAssignableToString = (ast: AST.AST): boolean => {
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
// In v4, refined strings (e.g. NonEmptyString) are String nodes with checks — no Refinement wrapper.
|
|
10
|
+
// Transformations are stored as encoding on nodes — no Transformation wrapper.
|
|
11
|
+
// So we check the encoded form to see if the wire format is a string.
|
|
12
|
+
const encoded = SchemaAST.toEncoded(ast)
|
|
13
|
+
if (encoded._tag === "String") return true
|
|
14
|
+
if (encoded._tag === "Union" && encoded.types.every(astAssignableToString)) {
|
|
11
15
|
return true
|
|
12
16
|
}
|
|
13
|
-
if (ast._tag === "Refinement" || ast._tag === "Transformation") {
|
|
14
|
-
return astAssignableToString(ast.from)
|
|
15
|
-
}
|
|
16
17
|
|
|
17
18
|
return false
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
const onlyStringsAst = (ast: AST.AST): boolean => {
|
|
21
22
|
if (ast._tag === "Union") return ast.types.every(onlyStringsAst)
|
|
22
|
-
|
|
23
|
+
// v4: TypeLiteral is now Objects
|
|
24
|
+
if (ast._tag !== "Objects") return false
|
|
23
25
|
return ast.propertySignatures.every((_) => astAssignableToString(_.type))
|
|
24
26
|
}
|
|
25
27
|
|
|
26
|
-
const onlyStrings = (schema:
|
|
28
|
+
const onlyStrings = (schema: S.Top & { fields?: S.Struct.Fields }): boolean => {
|
|
27
29
|
if ("fields" in schema && schema.fields) return onlyStringsAst(S.Struct(schema.fields).ast) // only one level..
|
|
28
30
|
return onlyStringsAst(schema.ast)
|
|
29
31
|
}
|
|
30
32
|
|
|
31
|
-
export const determineMethod = (fullName: string, schema:
|
|
33
|
+
export const determineMethod = (fullName: string, schema: S.Top) => {
|
|
32
34
|
const bits = fullName.split(".")
|
|
33
35
|
const actionName = bits[bits.length - 1]!
|
|
34
36
|
|