@effect-app/infra 2.93.0 → 3.0.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 +22 -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 +2 -2
- package/dist/adapters/ServiceBus.d.ts.map +1 -1
- package/dist/adapters/ServiceBus.js +13 -10
- package/dist/adapters/memQueue.d.ts +1 -1
- package/dist/api/ContextProvider.d.ts +3 -3
- package/dist/api/ContextProvider.d.ts.map +1 -1
- package/dist/api/ContextProvider.js +1 -1
- package/dist/api/routing/middleware/RouterMiddleware.d.ts +6 -6
- package/dist/api/routing/middleware/RouterMiddleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/RpcMiddleware.d.ts +4 -15
- package/dist/api/routing/middleware/RpcMiddleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/RpcMiddleware.js +3 -4
- package/dist/api/routing/middleware/RpcMiddlewareX.d.ts +18 -0
- package/dist/api/routing/middleware/RpcMiddlewareX.d.ts.map +1 -0
- package/dist/api/routing/middleware/RpcMiddlewareX.js +16 -0
- package/dist/api/routing/middleware/generic-middleware.d.ts +22 -8
- package/dist/api/routing/middleware/generic-middleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/generic-middleware.js +59 -62
- package/dist/api/routing/middleware/middleware-api.d.ts +51 -32
- package/dist/api/routing/middleware/middleware-api.d.ts.map +1 -1
- package/dist/api/routing/middleware/middleware-api.js +54 -24
- package/dist/api/routing/middleware/middleware-native.d.ts +23 -0
- package/dist/api/routing/middleware/middleware-native.d.ts.map +1 -0
- package/dist/api/routing/middleware/middleware-native.js +19 -0
- package/dist/api/routing/middleware/middleware.d.ts +7 -27
- package/dist/api/routing/middleware/middleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/middleware.js +73 -88
- package/dist/api/routing/middleware.d.ts +1 -0
- package/dist/api/routing/middleware.d.ts.map +1 -1
- package/dist/api/routing/middleware.js +2 -1
- package/dist/api/routing.d.ts +1 -4
- package/dist/api/routing.d.ts.map +1 -1
- package/dist/api/routing.js +8 -8
- package/package.json +11 -3
- package/src/adapters/ServiceBus.ts +7 -5
- package/src/api/ContextProvider.ts +9 -7
- package/src/api/routing/middleware/RouterMiddleware.ts +9 -8
- package/src/api/routing/middleware/RpcMiddleware.ts +4 -51
- package/src/api/routing/middleware/RpcMiddlewareX.ts +70 -0
- package/src/api/routing/middleware/generic-middleware.ts +142 -107
- package/src/api/routing/middleware/middleware-api.ts +239 -61
- package/src/api/routing/middleware/middleware-native.ts +23 -0
- package/src/api/routing/middleware/middleware.ts +37 -40
- package/src/api/routing/middleware.ts +1 -0
- package/src/api/routing.ts +7 -13
- package/test/contextProvider.test.ts +4 -4
- package/test/controller.test.ts +41 -16
- package/test/dist/controller.test.d.ts.map +1 -1
- package/test/dist/fixtures.d.ts +48 -32
- package/test/dist/fixtures.d.ts.map +1 -1
- package/test/dist/fixtures.js +76 -47
- package/test/dist/requires.test.d.ts.map +1 -1
- package/test/dist/rpc-multi-middleware.test.d.ts.map +1 -0
- package/test/fixtures.ts +71 -17
- package/test/requires.test.ts +15 -50
- package/test/rpc-multi-middleware.test.ts +134 -0
package/test/requires.test.ts
CHANGED
|
@@ -5,49 +5,9 @@ import { Context, Effect, Either, Layer, S } from "effect-app"
|
|
|
5
5
|
import { NotLoggedInError, UnauthorizedError } from "effect-app/client"
|
|
6
6
|
import { HttpHeaders } from "effect-app/http"
|
|
7
7
|
import { makeMiddleware, Middleware } from "../src/api/routing.js"
|
|
8
|
-
import { AllowAnonymous, RequestContextMap, RequireRoles, Some,
|
|
8
|
+
import { AllowAnonymous, AllowAnonymousLive, RequestContextMap, RequireRoles, RequireRolesLive, Some, SomeElseMiddleware, SomeElseMiddlewareLive, SomeMiddleware, SomeMiddlewareLive, SomeMiddlewareWrap, SomeService, Test, TestLive } from "./fixtures.js"
|
|
9
9
|
|
|
10
|
-
export class
|
|
11
|
-
provides: Some
|
|
12
|
-
})({
|
|
13
|
-
effect: Effect.gen(function*() {
|
|
14
|
-
// yield* Effect.context<"test-dep">()
|
|
15
|
-
return () =>
|
|
16
|
-
Effect.gen(function*() {
|
|
17
|
-
return new Some({ a: 1 })
|
|
18
|
-
})
|
|
19
|
-
})
|
|
20
|
-
}) {
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// functionally equivalent to the one above
|
|
24
|
-
export class SomeMiddlewareWrap extends Middleware.Tag<SomeMiddlewareWrap>()("SomeMiddlewareWrap", {
|
|
25
|
-
provides: Some,
|
|
26
|
-
wrap: true
|
|
27
|
-
})({
|
|
28
|
-
effect: Effect.gen(function*() {
|
|
29
|
-
// yield* Effect.context<"test-dep">()
|
|
30
|
-
return ({ next }) => next.pipe(Effect.provideService(Some, new Some({ a: 1 })))
|
|
31
|
-
})
|
|
32
|
-
}) {
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export class SomeElseMiddleware extends Middleware.Tag<SomeElseMiddleware>()("SomeElseMiddleware", {
|
|
36
|
-
provides: SomeElse,
|
|
37
|
-
wrap: true
|
|
38
|
-
})({
|
|
39
|
-
effect: Effect.gen(function*() {
|
|
40
|
-
// yield* Effect.context<"test-dep">()
|
|
41
|
-
return ({ next }) =>
|
|
42
|
-
Effect.gen(function*() {
|
|
43
|
-
// yield* Effect.context<"test-dep2">()
|
|
44
|
-
return yield* next.pipe(Effect.provideService(SomeElse, new SomeElse({ b: 2 })))
|
|
45
|
-
})
|
|
46
|
-
})
|
|
47
|
-
}) {
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export class RequiresSomeMiddleware extends Middleware.Tag<RequiresSomeMiddleware>()("RequiresSomeMiddleware", {
|
|
10
|
+
export class RequiresSomeMiddleware extends Middleware.TagService<RequiresSomeMiddleware>()("RequiresSomeMiddleware", {
|
|
51
11
|
requires: [Some],
|
|
52
12
|
wrap: true
|
|
53
13
|
})({
|
|
@@ -79,7 +39,7 @@ const _middlewareSideways = makeMiddleware(RequestContextMap)
|
|
|
79
39
|
const _middlewareSidewaysFully = makeMiddleware(RequestContextMap)
|
|
80
40
|
.middleware(RequiresSomeMiddleware, SomeMiddleware, RequireRoles, AllowAnonymous, Test, SomeElseMiddleware)
|
|
81
41
|
|
|
82
|
-
const _middleware3Bis = makeMiddleware(RequestContextMap)
|
|
42
|
+
export const _middleware3Bis = makeMiddleware(RequestContextMap)
|
|
83
43
|
.middleware(RequiresSomeMiddleware)
|
|
84
44
|
.middleware(SomeMiddlewareWrap)
|
|
85
45
|
.middleware(RequireRoles)
|
|
@@ -88,11 +48,7 @@ const _middleware3Bis = makeMiddleware(RequestContextMap)
|
|
|
88
48
|
|
|
89
49
|
expectTypeOf(_middlewareSideways).toEqualTypeOf<typeof middleware3>()
|
|
90
50
|
expectTypeOf(_middlewareSidewaysFully).toEqualTypeOf<typeof _middlewareSideways>()
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
type Default = typeof middleware3["Default"]
|
|
94
|
-
type LayerContext = Layer.Layer.Context<Default>
|
|
95
|
-
expectTypeOf({} as LayerContext).toEqualTypeOf<SomeService>()
|
|
51
|
+
expectTypeOf(_middleware3Bis).not.toEqualTypeOf<typeof middleware3>() // is not the same because SomeMiddlewareWrap is not SomeMiddleware
|
|
96
52
|
|
|
97
53
|
class TestRequest extends S.TaggedRequest<Test>("Test")("Test", {
|
|
98
54
|
payload: {},
|
|
@@ -112,7 +68,16 @@ const testSuite = (_mw: typeof middleware3) =>
|
|
|
112
68
|
rpc: { ...Rpc.fromTaggedRequest(TestRequest), annotations: Context.make(_mw.requestContext, {}) },
|
|
113
69
|
next: Effect.void as unknown as Effect<SuccessValue, never, any>
|
|
114
70
|
}
|
|
115
|
-
const layer = _mw.
|
|
71
|
+
const layer = _mw.layer.pipe(
|
|
72
|
+
Layer.provide([
|
|
73
|
+
RequiresSomeMiddleware.Default,
|
|
74
|
+
SomeMiddlewareLive,
|
|
75
|
+
RequireRolesLive.pipe(Layer.provide(SomeService.toLayer())),
|
|
76
|
+
AllowAnonymousLive,
|
|
77
|
+
TestLive,
|
|
78
|
+
SomeElseMiddlewareLive
|
|
79
|
+
])
|
|
80
|
+
)
|
|
116
81
|
yield* Effect
|
|
117
82
|
.gen(function*() {
|
|
118
83
|
const mw = yield* _mw
|
|
@@ -194,6 +159,6 @@ const testSuite = (_mw: typeof middleware3) =>
|
|
|
194
159
|
})
|
|
195
160
|
|
|
196
161
|
testSuite(middleware3)
|
|
197
|
-
testSuite(_middleware3Bis)
|
|
162
|
+
// testSuite(_middleware3Bis)
|
|
198
163
|
testSuite(_middlewareSideways)
|
|
199
164
|
testSuite(_middlewareSidewaysFully)
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { FetchHttpClient } from "@effect/platform"
|
|
2
|
+
import { NodeHttpServer } from "@effect/platform-node"
|
|
3
|
+
import { RpcClient, RpcGroup, RpcSerialization, RpcServer, RpcTest } from "@effect/rpc"
|
|
4
|
+
import { expect, expectTypeOf, it } from "@effect/vitest"
|
|
5
|
+
import { Console, Effect, Either, Layer } from "effect"
|
|
6
|
+
import { S } from "effect-app"
|
|
7
|
+
import { NotLoggedInError } from "effect-app/client"
|
|
8
|
+
import { HttpLayerRouter } from "effect-app/http"
|
|
9
|
+
import { createServer } from "http"
|
|
10
|
+
import { DefaultGenericMiddlewaresLive, makeMiddleware, middlewareGroup } from "../src/api/routing.js"
|
|
11
|
+
import { DefaultGenericMiddlewares } from "../src/api/routing/middleware/middleware-native.js"
|
|
12
|
+
import { AllowAnonymous, AllowAnonymousLive, RequestContextMap, RequireRoles, RequireRolesLive, Some, SomeElseMiddleware, SomeElseMiddlewareLive, SomeMiddlewareWrap, SomeMiddlewareWrapLive, SomeService, Test, TestLive, UserProfile } from "./fixtures.js"
|
|
13
|
+
|
|
14
|
+
const middleware = makeMiddleware(RequestContextMap)
|
|
15
|
+
.middleware(RequireRoles)
|
|
16
|
+
.middleware(AllowAnonymous, Test)
|
|
17
|
+
.middleware(SomeElseMiddleware, SomeMiddlewareWrap)
|
|
18
|
+
.middleware(...DefaultGenericMiddlewares)
|
|
19
|
+
|
|
20
|
+
const UserRpcs = middlewareGroup(middleware)(RpcGroup
|
|
21
|
+
.make(
|
|
22
|
+
middleware.rpc("getUser", {
|
|
23
|
+
success: S.Literal("awesome")
|
|
24
|
+
}),
|
|
25
|
+
middleware.rpc("doSomething", {
|
|
26
|
+
success: S.Literal("also-awesome"),
|
|
27
|
+
config: { allowAnonymous: true }
|
|
28
|
+
})
|
|
29
|
+
))
|
|
30
|
+
|
|
31
|
+
const impl = Effect
|
|
32
|
+
.gen(function*() {
|
|
33
|
+
const impl = UserRpcs
|
|
34
|
+
.toLayerDynamic({
|
|
35
|
+
getUser: Effect.fn(function*(_payload, _headers) {
|
|
36
|
+
yield* Some
|
|
37
|
+
yield* UserProfile // we only access it while protected by allowAnonymous: false
|
|
38
|
+
return "awesome" as const
|
|
39
|
+
}),
|
|
40
|
+
doSomething: Effect.fn(function*() {
|
|
41
|
+
console.log(yield* Effect.serviceOption(UserProfile)) // we access it optionally, while allowAnonymous: true
|
|
42
|
+
return "also-awesome" as const
|
|
43
|
+
})
|
|
44
|
+
})
|
|
45
|
+
return impl
|
|
46
|
+
})
|
|
47
|
+
.pipe(Layer.unwrapEffect)
|
|
48
|
+
|
|
49
|
+
expectTypeOf<Layer.Layer.Context<typeof impl>>().toEqualTypeOf<never>()
|
|
50
|
+
|
|
51
|
+
const UserRpcsBad = middlewareGroup(middleware)(RpcGroup
|
|
52
|
+
.make(
|
|
53
|
+
middleware.rpc("doSomethingElse", {
|
|
54
|
+
success: S.Literal("also-awesome2"),
|
|
55
|
+
config: { allowAnonymous: true }
|
|
56
|
+
})
|
|
57
|
+
))
|
|
58
|
+
export const badImpl = Effect
|
|
59
|
+
.gen(function*() {
|
|
60
|
+
const impl = UserRpcsBad
|
|
61
|
+
.toLayerDynamic({
|
|
62
|
+
doSomethingElse: Effect.fn(function*() {
|
|
63
|
+
console.log(yield* UserProfile) // bad boy! allowAnonymous: false, so `UserProfile` must fall through to the Layer R.
|
|
64
|
+
return "also-awesome2" as const
|
|
65
|
+
})
|
|
66
|
+
})
|
|
67
|
+
return impl
|
|
68
|
+
})
|
|
69
|
+
.pipe(Layer.unwrapEffect)
|
|
70
|
+
|
|
71
|
+
expectTypeOf<Layer.Layer.Context<typeof badImpl>>().toEqualTypeOf<UserProfile>()
|
|
72
|
+
|
|
73
|
+
const middlwareLayer = middleware
|
|
74
|
+
.layer
|
|
75
|
+
.pipe(
|
|
76
|
+
Layer.provide([
|
|
77
|
+
DefaultGenericMiddlewaresLive,
|
|
78
|
+
SomeElseMiddlewareLive,
|
|
79
|
+
SomeMiddlewareWrapLive,
|
|
80
|
+
TestLive,
|
|
81
|
+
RequireRolesLive.pipe(Layer.provide(SomeService.toLayer())),
|
|
82
|
+
AllowAnonymousLive
|
|
83
|
+
])
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
export const RpcTestLayer = Layer
|
|
87
|
+
.mergeAll(
|
|
88
|
+
impl,
|
|
89
|
+
middlwareLayer
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
export const RpcRealLayer = Layer
|
|
93
|
+
.mergeAll(
|
|
94
|
+
HttpLayerRouter
|
|
95
|
+
.serve(
|
|
96
|
+
RpcServer
|
|
97
|
+
.layerHttpRouter({ group: UserRpcs, path: "/rpc", protocol: "http" })
|
|
98
|
+
.pipe(Layer.provide(impl))
|
|
99
|
+
.pipe(Layer.provide(middlwareLayer))
|
|
100
|
+
)
|
|
101
|
+
.pipe(Layer.provide(NodeHttpServer.layer(() => createServer(), { port: 5918 }))),
|
|
102
|
+
RpcClient
|
|
103
|
+
.layerProtocolHttp({ url: "http://localhost:5918/rpc" })
|
|
104
|
+
.pipe(
|
|
105
|
+
Layer.provide(FetchHttpClient.layer)
|
|
106
|
+
)
|
|
107
|
+
)
|
|
108
|
+
.pipe(Layer.provide(RpcSerialization.layerJson))
|
|
109
|
+
|
|
110
|
+
it.scopedLive(
|
|
111
|
+
"require login",
|
|
112
|
+
Effect.fnUntraced(
|
|
113
|
+
function*() {
|
|
114
|
+
const userClient = yield* RpcTest.makeClient(UserRpcs) // RpcTest.makeClient(UserRpcs) // RpcClient.make(UserRpcs)
|
|
115
|
+
|
|
116
|
+
const user = yield* Effect.either(userClient.getUser().pipe(Effect.onExit((_) => Console.dir(_, { depth: 10 }))))
|
|
117
|
+
expect(user).toStrictEqual(Either.left(new NotLoggedInError("Not logged in")))
|
|
118
|
+
},
|
|
119
|
+
Effect.provide(RpcTestLayer)
|
|
120
|
+
)
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
it.scopedLive(
|
|
124
|
+
"allow anonymous, optional UserProfile",
|
|
125
|
+
Effect.fnUntraced(
|
|
126
|
+
function*() {
|
|
127
|
+
const userClient = yield* RpcTest.makeClient(UserRpcs) // RpcTest.makeClient(UserRpcs) // RpcClient.make(UserRpcs)
|
|
128
|
+
|
|
129
|
+
const user = yield* userClient.doSomething().pipe(Effect.onExit((_) => Console.dir(_, { depth: 10 })))
|
|
130
|
+
expect(user).toBe("also-awesome")
|
|
131
|
+
},
|
|
132
|
+
Effect.provide(RpcTestLayer)
|
|
133
|
+
)
|
|
134
|
+
)
|