@effect-app/infra 2.87.1 → 2.88.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 +19 -1
- package/dist/api/routing/middleware/RouterMiddleware.d.ts +4 -22
- package/dist/api/routing/middleware/RouterMiddleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/RouterMiddleware.js +1 -1
- package/dist/api/routing/middleware/RpcMiddleware.d.ts +13 -13
- 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 +8 -8
- package/dist/api/routing/middleware/generic-middleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/generic-middleware.js +23 -7
- package/dist/api/routing/middleware/middleware-api.d.ts +59 -30
- package/dist/api/routing/middleware/middleware-api.d.ts.map +1 -1
- package/dist/api/routing/middleware/middleware-api.js +44 -35
- 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.d.ts +28 -22
- package/dist/api/routing.d.ts.map +1 -1
- package/dist/api/routing.js +1 -1
- package/package.json +2 -2
- package/src/api/routing/middleware/RouterMiddleware.ts +8 -86
- package/src/api/routing/middleware/RpcMiddleware.ts +13 -12
- package/src/api/routing/middleware/dynamic-middleware.ts +0 -47
- package/src/api/routing/middleware/generic-middleware.ts +45 -14
- package/src/api/routing/middleware/middleware-api.ts +147 -101
- package/src/api/routing/middleware/middleware.ts +5 -5
- package/src/api/routing.ts +50 -35
- package/test/contextProvider.test.ts +27 -24
- package/test/controller.test.ts +45 -23
- 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 +38 -44
- package/test/dist/fixtures.d.ts.map +1 -1
- package/test/dist/fixtures.js +21 -9
- package/test/dist/requires.test.d.ts.map +1 -1
- package/test/fixtures.ts +22 -13
- package/test/layerUtils.test.ts +4 -2
- package/test/requires.test.ts +119 -97
|
@@ -1,6 +1,6 @@
|
|
|
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
5
|
import { ContextProvider, mergeContextProviders, MergedContextProvider } from "../src/api/routing.js"
|
|
6
6
|
import { CustomError1, Some, SomeElse, SomeService } from "./fixtures.js"
|
|
@@ -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
|
+
})
|
package/test/controller.test.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { Context, Effect, type Layer, S, Scope } from "effect-app"
|
|
|
6
6
|
import { InvalidStateError, makeRpcClient, NotLoggedInError, UnauthorizedError } from "effect-app/client"
|
|
7
7
|
import { DefaultGenericMiddlewares, makeMiddleware, Middleware, Tag } from "../src/api/routing/middleware.js"
|
|
8
8
|
import { sort } from "../src/api/routing/tsort.js"
|
|
9
|
-
import { AllowAnonymous, CustomError1,
|
|
9
|
+
import { AllowAnonymous, CustomError1, RequestContextMap, RequireRoles, Some, SomeElse, SomeService, Test } from "./fixtures.js"
|
|
10
10
|
|
|
11
11
|
// @effect-diagnostics-next-line missingEffectServiceDependency:off
|
|
12
12
|
class MyContextProvider extends Middleware.Tag<MyContextProvider>()("MyContextProvider", {
|
|
@@ -55,7 +55,6 @@ class MyContextProvider2 extends Middleware.Tag<MyContextProvider2>()("MyContext
|
|
|
55
55
|
const Str = Context.GenericTag<"str", "str">("str")
|
|
56
56
|
|
|
57
57
|
export class BogusMiddleware extends Tag<BogusMiddleware>()("BogusMiddleware", {
|
|
58
|
-
provides: SomeService,
|
|
59
58
|
wrap: true
|
|
60
59
|
})({
|
|
61
60
|
effect: Effect.gen(function*() {
|
|
@@ -64,7 +63,7 @@ export class BogusMiddleware extends Tag<BogusMiddleware>()("BogusMiddleware", {
|
|
|
64
63
|
return ({ next }) =>
|
|
65
64
|
Effect.gen(function*() {
|
|
66
65
|
// yield* Effect.context<"test-dep2">()
|
|
67
|
-
return yield* next
|
|
66
|
+
return yield* next
|
|
68
67
|
})
|
|
69
68
|
})
|
|
70
69
|
}) {
|
|
@@ -76,23 +75,59 @@ const genericMiddlewares = [
|
|
|
76
75
|
MyContextProvider2
|
|
77
76
|
] as const
|
|
78
77
|
|
|
79
|
-
const middleware = makeMiddleware<RequestContextMap>()
|
|
78
|
+
const middleware = makeMiddleware<RequestContextMap>(RequestContextMap)
|
|
80
79
|
.middleware(MyContextProvider)
|
|
81
80
|
.middleware(
|
|
82
81
|
RequireRoles,
|
|
83
82
|
Test
|
|
84
83
|
)
|
|
84
|
+
// AllowAnonymous provided after RequireRoles so that RequireRoles can access what AllowAnonymous provides
|
|
85
85
|
.middleware(AllowAnonymous)
|
|
86
86
|
.middleware(...genericMiddlewares)
|
|
87
|
-
// dependencies: [Layer.effect(Str2, Str)],
|
|
88
87
|
|
|
89
|
-
const
|
|
88
|
+
const middlewareBis = makeMiddleware<RequestContextMap>(RequestContextMap)
|
|
89
|
+
.middleware(MyContextProvider)
|
|
90
|
+
.middleware(
|
|
91
|
+
RequireRoles,
|
|
92
|
+
Test
|
|
93
|
+
)
|
|
94
|
+
// testing sideways elimination
|
|
95
|
+
.middleware(AllowAnonymous, ...genericMiddlewares)
|
|
96
|
+
|
|
97
|
+
expectTypeOf(middleware).toEqualTypeOf<typeof middlewareBis>()
|
|
98
|
+
|
|
99
|
+
const middlewareTrisWip = makeMiddleware<RequestContextMap>(RequestContextMap)
|
|
100
|
+
.middleware(
|
|
101
|
+
MyContextProvider,
|
|
102
|
+
RequireRoles,
|
|
103
|
+
Test
|
|
104
|
+
)
|
|
105
|
+
.missing
|
|
106
|
+
|
|
107
|
+
expectTypeOf(middlewareTrisWip).toEqualTypeOf<{
|
|
108
|
+
missingDynamicMiddlewares: "allowAnonymous"
|
|
109
|
+
missingContext: SomeElse
|
|
110
|
+
}>()
|
|
111
|
+
|
|
112
|
+
// testing more sideways elimination]
|
|
113
|
+
const middlewareQuater = makeMiddleware<RequestContextMap>(RequestContextMap)
|
|
114
|
+
.middleware(
|
|
115
|
+
MyContextProvider,
|
|
116
|
+
RequireRoles,
|
|
117
|
+
Test,
|
|
118
|
+
AllowAnonymous,
|
|
119
|
+
...genericMiddlewares
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
expectTypeOf(middleware).toEqualTypeOf<typeof middlewareQuater>()
|
|
123
|
+
|
|
124
|
+
const middleware2 = makeMiddleware<RequestContextMap>(RequestContextMap)
|
|
90
125
|
.middleware(MyContextProvider)
|
|
91
126
|
.middleware(RequireRoles, Test)
|
|
92
127
|
.middleware(AllowAnonymous)
|
|
93
128
|
.middleware(...DefaultGenericMiddlewares, BogusMiddleware, MyContextProvider2)
|
|
94
129
|
|
|
95
|
-
export const middleware3 = makeMiddleware<RequestContextMap>()
|
|
130
|
+
export const middleware3 = makeMiddleware<RequestContextMap>(RequestContextMap)
|
|
96
131
|
.middleware(...genericMiddlewares)
|
|
97
132
|
.middleware(AllowAnonymous, RequireRoles)
|
|
98
133
|
.middleware(Test)
|
|
@@ -246,7 +281,7 @@ it("sorts based on requirements", () => {
|
|
|
246
281
|
|
|
247
282
|
// eslint-disable-next-line unused-imports/no-unused-vars
|
|
248
283
|
const matched = matchAll({ router })
|
|
249
|
-
expectTypeOf({} as Layer.Context<typeof matched>).toEqualTypeOf<SomeService |
|
|
284
|
+
expectTypeOf({} as Layer.Context<typeof matched>).toEqualTypeOf<SomeService | "str">()
|
|
250
285
|
|
|
251
286
|
type makeContext = MakeContext<typeof router.make>
|
|
252
287
|
expectTypeOf({} as MakeErrors<typeof router.make>).toEqualTypeOf<InvalidStateError>()
|
|
@@ -255,23 +290,12 @@ expectTypeOf({} as makeContext).toEqualTypeOf<
|
|
|
255
290
|
>()
|
|
256
291
|
|
|
257
292
|
const router2 = r2.Router(Something)({
|
|
258
|
-
dependencies: [
|
|
259
|
-
SomethingRepo.Default,
|
|
260
|
-
SomethingService.Default,
|
|
261
|
-
SomethingService2.Default
|
|
262
|
-
],
|
|
263
293
|
*effect(match) {
|
|
264
|
-
const repo = yield* SomethingRepo
|
|
265
|
-
const smth = yield* SomethingService
|
|
266
|
-
const smth2 = yield* SomethingService2
|
|
267
|
-
|
|
268
294
|
// this gets catched in 'routes' type
|
|
269
295
|
if (Math.random() > 0.5) {
|
|
270
296
|
return yield* new InvalidStateError("ciao")
|
|
271
297
|
}
|
|
272
298
|
|
|
273
|
-
console.log({ repo, smth, smth2 })
|
|
274
|
-
|
|
275
299
|
return match({
|
|
276
300
|
Eff: () =>
|
|
277
301
|
Effect
|
|
@@ -318,10 +342,8 @@ const router2 = r2.Router(Something)({
|
|
|
318
342
|
|
|
319
343
|
// eslint-disable-next-line unused-imports/no-unused-vars
|
|
320
344
|
const matched2 = matchAll({ router: router2 })
|
|
321
|
-
expectTypeOf({} as Layer.Context<typeof matched2>).toEqualTypeOf<
|
|
345
|
+
expectTypeOf({} as Layer.Context<typeof matched2>).toEqualTypeOf<SomeService | "str">()
|
|
322
346
|
|
|
323
347
|
type makeContext2 = MakeContext<typeof router2.make>
|
|
324
348
|
expectTypeOf({} as MakeErrors<typeof router2.make>).toEqualTypeOf<InvalidStateError>()
|
|
325
|
-
expectTypeOf({} as makeContext2).toEqualTypeOf<
|
|
326
|
-
SomethingService | SomethingRepo | SomethingService2
|
|
327
|
-
>()
|
|
349
|
+
expectTypeOf({} as makeContext2).toEqualTypeOf<never>()
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contextProvider.test.d.ts","sourceRoot":"","sources":["../contextProvider.test.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAEnD,OAAO,EAAE,YAAY,EAAE,IAAI,
|
|
1
|
+
{"version":3,"file":"contextProvider.test.d.ts","sourceRoot":"","sources":["../contextProvider.test.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAEnD,OAAO,EAAE,YAAY,EAAE,IAAI,EAAY,WAAW,EAAE,MAAM,eAAe,CAAA;AA8EzE,eAAO,MAAM,mBAAmB;;CAkB9B,CAAA;AACF,eAAO,MAAM,sBAAsB;;CAkBjC,CAAA"}
|
|
@@ -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;AAE7F,OAAO,EAAW,MAAM,EAAE,KAAK,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAElE,OAAO,EAA6C,UAAU,EAAO,MAAM,kCAAkC,CAAA;AAE7G,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,
|
|
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;AAE7F,OAAO,EAAW,MAAM,EAAE,KAAK,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAElE,OAAO,EAA6C,UAAU,EAAO,MAAM,kCAAkC,CAAA;AAE7G,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;;;;;;AAgChI,cAAM,kBAAmB,SAAQ,uBAU/B;CAAG;;;;;;AAML,qBAAa,eAAgB,SAAQ,oBAYnC;CACD;AA4DD,eAAO,MAAM,WAAW;;;;;;YAIM,CAAA;AAE9B,MAAM,MAAM,aAAa,GAAG;IAC1B,yCAAyC;IACzC,cAAc,CAAC,EAAE,IAAI,CAAA;IACrB,iEAAiE;IACjE,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAC/B,CAAA;AACD,eAAO,MAAuB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAI/B,CAAA;;;;;;;;;;AAEF,qBAAa,GAAI,SAAQ,QAA0C;CAAG;;;;;;;;;;AACtE,qBAAa,GAAI,SAAQ,QAA0C;CAAG;;;;;;;;;;;;AAEtE,qBAAa,WAAY,SAAQ,gBAEV;CAAG;;;;;;;;;;;;AAgB1B,qBAAa,YAAa,SAAQ,iBAET;CAAG;;;;;;;;;;;;AAE5B,qBAAa,aAAc,SAAQ,kBAEA;CAAG;;;;;AAItC,qBAAa,gBAAiB,SAAQ,qBAKpC;CAAG;;;;;AASL,qBAAa,aAAc,SAAQ,kBAOjC;CAAG;;;;;AAEL,qBAAa,iBAAkB,SAAQ,sBAKrC;CAAG;AAEL,eAAO,MAAQ,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAAE,QAAQ;;;;;2HAAE,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uCAAiC,CAAA;AAE1E,eAAO,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAgC,CAAA"}
|
package/test/dist/fixtures.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Context, Effect, S, Scope } from "effect-app";
|
|
2
|
-
import { NotLoggedInError,
|
|
2
|
+
import { NotLoggedInError, RPCContextMap, UnauthorizedError } from "effect-app/client";
|
|
3
3
|
import { Middleware } from "../src/api/routing.js";
|
|
4
4
|
declare const UserProfile_base: S.EnhancedClass<UserProfile, {
|
|
5
5
|
id: typeof S.String;
|
|
@@ -67,16 +67,42 @@ declare const SomeElse_base: (abstract new (service: {
|
|
|
67
67
|
};
|
|
68
68
|
export declare class SomeElse extends SomeElse_base {
|
|
69
69
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
70
|
+
declare const SomeService_base: (abstract new (service: {
|
|
71
|
+
a: number;
|
|
72
|
+
}) => Readonly<{
|
|
73
|
+
a: number;
|
|
74
|
+
}> & Context.TagClassShape<"SomeService", {
|
|
75
|
+
a: number;
|
|
76
|
+
}>) & {
|
|
77
|
+
toLayer: {
|
|
78
|
+
(): import("effect/Layer").Layer<SomeService, never, never>;
|
|
79
|
+
<E_1, R_1>(eff: Effect.Effect<Omit<SomeService, keyof Context.TagClassShape<any, any>>, E_1, R_1>): import("effect/Layer").Layer<SomeService, E_1, R_1>;
|
|
80
|
+
};
|
|
81
|
+
toLayerScoped: {
|
|
82
|
+
(): import("effect/Layer").Layer<SomeService, never, never>;
|
|
83
|
+
<E_1, R_2>(eff: Effect.Effect<Context.TagClassShape<any, any>, E_1, R_2>): import("effect/Layer").Layer<SomeService, E_1, Exclude<R_2, Scope.Scope>>;
|
|
84
|
+
};
|
|
85
|
+
of: (service: Context.TagClassShape<any, any>) => SomeService;
|
|
86
|
+
make: Effect.Effect<SomeService, never, never>;
|
|
87
|
+
} & Context.Tag<SomeService, SomeService> & {
|
|
88
|
+
a: Effect.Effect<number, never, SomeService>;
|
|
89
|
+
} & {
|
|
90
|
+
use: <X>(body: (_: {
|
|
91
|
+
a: number;
|
|
92
|
+
}) => X) => X extends Effect.Effect<infer A, infer E_1, infer R_3> ? Effect.Effect<A, E_1, R_3 | SomeService> : Effect.Effect<X, never, SomeService>;
|
|
74
93
|
};
|
|
94
|
+
export declare class SomeService extends SomeService_base {
|
|
95
|
+
}
|
|
96
|
+
export declare const RequestContextMap: {
|
|
97
|
+
readonly allowAnonymous: RPCContextMap.Inverted<[typeof UserProfile], typeof NotLoggedInError>;
|
|
98
|
+
readonly requireRoles: RPCContextMap.Custom<never, typeof UnauthorizedError, string[]>;
|
|
99
|
+
readonly test: RPCContextMap.RPCContextMap<never, typeof S.Never>;
|
|
100
|
+
};
|
|
101
|
+
type _RequestContextMap = typeof RequestContextMap;
|
|
102
|
+
export interface RequestContextMap extends _RequestContextMap {
|
|
103
|
+
}
|
|
75
104
|
declare const AllowAnonymous_base: Middleware.TagClass<AllowAnonymous, "AllowAnonymous", {
|
|
76
|
-
readonly dynamic:
|
|
77
|
-
key: "allowAnonymous";
|
|
78
|
-
settings: RPCContextMap.Inverted<[typeof UserProfile], typeof NotLoggedInError>;
|
|
79
|
-
};
|
|
105
|
+
readonly dynamic: Middleware.RpcDynamic<"allowAnonymous", RPCContextMap.Inverted<[typeof UserProfile], typeof NotLoggedInError>>;
|
|
80
106
|
readonly requires: typeof SomeElse;
|
|
81
107
|
}> & {
|
|
82
108
|
Default: import("effect/Layer").Layer<AllowAnonymous, never, never>;
|
|
@@ -84,23 +110,17 @@ declare const AllowAnonymous_base: Middleware.TagClass<AllowAnonymous, "AllowAno
|
|
|
84
110
|
export declare class AllowAnonymous extends AllowAnonymous_base {
|
|
85
111
|
}
|
|
86
112
|
declare const RequireRoles_base: Middleware.TagClass<RequireRoles, "RequireRoles", {
|
|
87
|
-
readonly dynamic:
|
|
88
|
-
key: "requireRoles";
|
|
89
|
-
settings: RPCContextMap.Custom<never, typeof UnauthorizedError, string[]>;
|
|
90
|
-
};
|
|
113
|
+
readonly dynamic: Middleware.RpcDynamic<"requireRoles", RPCContextMap.Custom<never, typeof UnauthorizedError, string[]>>;
|
|
91
114
|
readonly wrap: true;
|
|
92
115
|
readonly dependsOn: readonly [typeof AllowAnonymous];
|
|
93
116
|
}> & {
|
|
94
|
-
Default: import("effect/Layer").Layer<RequireRoles, never,
|
|
117
|
+
Default: import("effect/Layer").Layer<RequireRoles, never, SomeService>;
|
|
95
118
|
};
|
|
96
119
|
export declare class RequireRoles extends RequireRoles_base {
|
|
97
120
|
}
|
|
98
121
|
declare const Test_base: Middleware.TagClass<Test, "Test", {
|
|
99
122
|
readonly wrap: true;
|
|
100
|
-
readonly dynamic:
|
|
101
|
-
key: "test";
|
|
102
|
-
settings: RPCContextMap<never, typeof S.Never>;
|
|
103
|
-
};
|
|
123
|
+
readonly dynamic: Middleware.RpcDynamic<"test", RPCContextMap.RPCContextMap<never, typeof S.Never>>;
|
|
104
124
|
}> & {
|
|
105
125
|
Default: import("effect/Layer").Layer<Test, never, never>;
|
|
106
126
|
};
|
|
@@ -116,31 +136,5 @@ declare const CustomError2_base: S.TaggedErrorClass<NotLoggedInError, "CustomErr
|
|
|
116
136
|
}>;
|
|
117
137
|
export declare class CustomError2 extends CustomError2_base {
|
|
118
138
|
}
|
|
119
|
-
declare const SomeService_base: (abstract new (service: {
|
|
120
|
-
a: number;
|
|
121
|
-
}) => Readonly<{
|
|
122
|
-
a: number;
|
|
123
|
-
}> & Context.TagClassShape<"SomeService", {
|
|
124
|
-
a: number;
|
|
125
|
-
}>) & {
|
|
126
|
-
toLayer: {
|
|
127
|
-
(): import("effect/Layer").Layer<SomeService, never, never>;
|
|
128
|
-
<E_1, R_1>(eff: Effect.Effect<Omit<SomeService, keyof Context.TagClassShape<any, any>>, E_1, R_1>): import("effect/Layer").Layer<SomeService, E_1, R_1>;
|
|
129
|
-
};
|
|
130
|
-
toLayerScoped: {
|
|
131
|
-
(): import("effect/Layer").Layer<SomeService, never, never>;
|
|
132
|
-
<E_1, R_2>(eff: Effect.Effect<Context.TagClassShape<any, any>, E_1, R_2>): import("effect/Layer").Layer<SomeService, E_1, Exclude<R_2, Scope.Scope>>;
|
|
133
|
-
};
|
|
134
|
-
of: (service: Context.TagClassShape<any, any>) => SomeService;
|
|
135
|
-
make: Effect.Effect<SomeService, never, never>;
|
|
136
|
-
} & Context.Tag<SomeService, SomeService> & {
|
|
137
|
-
a: Effect.Effect<number, never, SomeService>;
|
|
138
|
-
} & {
|
|
139
|
-
use: <X>(body: (_: {
|
|
140
|
-
a: number;
|
|
141
|
-
}) => X) => X extends Effect.Effect<infer A, infer E_1, infer R_3> ? Effect.Effect<A, E_1, R_3 | SomeService> : Effect.Effect<X, never, SomeService>;
|
|
142
|
-
};
|
|
143
|
-
export declare class SomeService extends SomeService_base {
|
|
144
|
-
}
|
|
145
139
|
export {};
|
|
146
140
|
//# sourceMappingURL=fixtures.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../fixtures.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAU,CAAC,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAC9D,OAAO,EAAE,gBAAgB,EAAE,
|
|
1
|
+
{"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../fixtures.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAU,CAAC,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAC9D,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAEtF,OAAO,EAAc,UAAU,EAAE,MAAM,uBAAuB,CAAA;;;;;;;;;;;;;AAE9D,qBAAa,WAAY,SAAQ,gBAKhC;CACA;;;;;;;;;;;;;;;;;;;;;;;;;AAED,qBAAa,IAAK,SAAQ,SAA2D;CAAG;;;;;;;;;;;;;;;;;;;;;;;;;AACxF,qBAAa,QAAS,SAAQ,aAAmE;CAAG;;;;;;;;;;;;;;;;;;;;;;;;;AAEpG,qBAAa,WAAY,SAAQ,gBAAgE;CAAG;AAOpG,eAAO,MAAM,iBAAiB;;;;CAIpB,CAAA;AAEV,KAAK,kBAAkB,GAAG,OAAO,iBAAiB,CAAA;AAClD,MAAM,WAAW,iBAAkB,SAAQ,kBAAkB;CAAG;;;;;;;AAEhE,qBAAa,cAAe,SAAQ,mBA4BlC;CACD;;;;;;;;AAID,qBAAa,YAAa,SAAQ,iBA6BhC;CACD;;;;;;;AAGD,qBAAa,IAAK,SAAQ,SASxB;CAAG;;;;AAEL,qBAAa,YAAa,SAAQ,iBAAmD;CAAG;;;;AACxF,qBAAa,YAAa,SAAQ,iBAAmD;CAAG"}
|
package/test/dist/fixtures.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Context, Effect, Option, S, Scope } from "effect-app";
|
|
2
|
-
import { NotLoggedInError, UnauthorizedError } from "effect-app/client";
|
|
2
|
+
import { NotLoggedInError, RPCContextMap, UnauthorizedError } from "effect-app/client";
|
|
3
3
|
import { TaggedError } from "effect-app/Schema";
|
|
4
4
|
import { contextMap, Middleware } from "../src/api/routing.js";
|
|
5
5
|
export class UserProfile extends Context.assignTag("UserProfile")(S.Class("UserProfile")({
|
|
@@ -11,8 +11,21 @@ export class Some extends Context.TagMakeId("Some", Effect.succeed({ a: 1 }))()
|
|
|
11
11
|
}
|
|
12
12
|
export class SomeElse extends Context.TagMakeId("SomeElse", Effect.succeed({ b: 2 }))() {
|
|
13
13
|
}
|
|
14
|
+
const MakeSomeService = Effect.succeed({ a: 1 });
|
|
15
|
+
export class SomeService extends Context.TagMakeId("SomeService", MakeSomeService)() {
|
|
16
|
+
}
|
|
17
|
+
// TODO: null as never sucks
|
|
18
|
+
// why [UserProfile] is needed? AllowAnonymous triggers an error if just UserProfile without []
|
|
19
|
+
// [] requires return Context, non [] requires return the Service instance
|
|
20
|
+
//
|
|
21
|
+
// consider if we want to support Context of one Service
|
|
22
|
+
export const RequestContextMap = {
|
|
23
|
+
allowAnonymous: RPCContextMap.makeInverted([UserProfile], NotLoggedInError),
|
|
24
|
+
requireRoles: RPCContextMap.makeCustom(null, UnauthorizedError, Array()),
|
|
25
|
+
test: RPCContextMap.make(null, S.Never)
|
|
26
|
+
};
|
|
14
27
|
export class AllowAnonymous extends Middleware.Tag()("AllowAnonymous", {
|
|
15
|
-
dynamic: contextMap(
|
|
28
|
+
dynamic: contextMap(RequestContextMap, "allowAnonymous"),
|
|
16
29
|
requires: SomeElse
|
|
17
30
|
})({
|
|
18
31
|
effect: Effect.gen(function* () {
|
|
@@ -34,9 +47,10 @@ export class AllowAnonymous extends Middleware.Tag()("AllowAnonymous", {
|
|
|
34
47
|
})
|
|
35
48
|
}) {
|
|
36
49
|
}
|
|
50
|
+
// TODO: don't expect service when it's wrap
|
|
37
51
|
// @effect-diagnostics-next-line missingEffectServiceDependency:off
|
|
38
52
|
export class RequireRoles extends Middleware.Tag()("RequireRoles", {
|
|
39
|
-
dynamic: contextMap(
|
|
53
|
+
dynamic: contextMap(RequestContextMap, "requireRoles"),
|
|
40
54
|
wrap: true,
|
|
41
55
|
// wrap: true,
|
|
42
56
|
// had to move this in here, because once you put it manually as a readonly static property on the class,
|
|
@@ -44,7 +58,7 @@ export class RequireRoles extends Middleware.Tag()("RequireRoles", {
|
|
|
44
58
|
dependsOn: [AllowAnonymous]
|
|
45
59
|
})({
|
|
46
60
|
effect: Effect.gen(function* () {
|
|
47
|
-
yield*
|
|
61
|
+
yield* SomeService;
|
|
48
62
|
return Effect.fnUntraced(function* ({ config, next }) {
|
|
49
63
|
// we don't know if the service will be provided or not, so we use option..
|
|
50
64
|
const userProfile = yield* Effect.serviceOption(UserProfile);
|
|
@@ -61,9 +75,10 @@ export class RequireRoles extends Middleware.Tag()("RequireRoles", {
|
|
|
61
75
|
})
|
|
62
76
|
}) {
|
|
63
77
|
}
|
|
78
|
+
// TODO: don't expect service when it's wrap
|
|
64
79
|
export class Test extends Middleware.Tag()("Test", {
|
|
65
80
|
wrap: true,
|
|
66
|
-
dynamic: contextMap(
|
|
81
|
+
dynamic: contextMap(RequestContextMap, "test")
|
|
67
82
|
})({
|
|
68
83
|
effect: Effect.gen(function* () {
|
|
69
84
|
return Effect.fn(function* ({ next }) {
|
|
@@ -76,7 +91,4 @@ export class CustomError1 extends TaggedError()("CustomError1", {}) {
|
|
|
76
91
|
}
|
|
77
92
|
export class CustomError2 extends TaggedError()("CustomError1", {}) {
|
|
78
93
|
}
|
|
79
|
-
|
|
80
|
-
export class SomeService extends Context.TagMakeId("SomeService", MakeSomeService)() {
|
|
81
|
-
}
|
|
82
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZml4dHVyZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9maXh0dXJlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxNQUFNLFlBQVksQ0FBQTtBQUM5RCxPQUFPLEVBQUUsZ0JBQWdCLEVBQXNCLGlCQUFpQixFQUFFLE1BQU0sbUJBQW1CLENBQUE7QUFDM0YsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLG1CQUFtQixDQUFBO0FBQy9DLE9BQU8sRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLE1BQU0sdUJBQXVCLENBQUE7QUFFOUQsTUFBTSxPQUFPLFdBQVksU0FBUSxPQUFPLENBQUMsU0FBUyxDQUEyQixhQUFhLENBQUMsQ0FDekYsQ0FBQyxDQUFDLEtBQUssQ0FBYyxhQUFhLENBQUMsQ0FBQztJQUNsQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLE1BQU07SUFDWixLQUFLLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDO0NBQ3pCLENBQUMsQ0FDSDtDQUNBO0FBRUQsTUFBTSxPQUFPLElBQUssU0FBUSxPQUFPLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBUTtDQUFHO0FBQ3hGLE1BQU0sT0FBTyxRQUFTLFNBQVEsT0FBTyxDQUFDLFNBQVMsQ0FBQyxVQUFVLEVBQUUsTUFBTSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQVk7Q0FBRztBQVFwRyxNQUFNLE9BQU8sY0FBZSxTQUFRLFVBQVUsQ0FBQyxHQUFHLEVBQWtCLENBQUMsZ0JBQWdCLEVBQUU7SUFDckYsT0FBTyxFQUFFLFVBQVUsRUFBcUIsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLFdBQVcs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
|
|
94
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZml4dHVyZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9maXh0dXJlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxNQUFNLFlBQVksQ0FBQTtBQUM5RCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsYUFBYSxFQUFFLGlCQUFpQixFQUFFLE1BQU0sbUJBQW1CLENBQUE7QUFDdEYsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLG1CQUFtQixDQUFBO0FBQy9DLE9BQU8sRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLE1BQU0sdUJBQXVCLENBQUE7QUFFOUQsTUFBTSxPQUFPLFdBQVksU0FBUSxPQUFPLENBQUMsU0FBUyxDQUEyQixhQUFhLENBQUMsQ0FDekYsQ0FBQyxDQUFDLEtBQUssQ0FBYyxhQUFhLENBQUMsQ0FBQztJQUNsQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLE1BQU07SUFDWixLQUFLLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDO0NBQ3pCLENBQUMsQ0FDSDtDQUNBO0FBRUQsTUFBTSxPQUFPLElBQUssU0FBUSxPQUFPLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBUTtDQUFHO0FBQ3hGLE1BQU0sT0FBTyxRQUFTLFNBQVEsT0FBTyxDQUFDLFNBQVMsQ0FBQyxVQUFVLEVBQUUsTUFBTSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQVk7Q0FBRztBQUNwRyxNQUFNLGVBQWUsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUE7QUFDaEQsTUFBTSxPQUFPLFdBQVksU0FBUSxPQUFPLENB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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"requires.test.d.ts","sourceRoot":"","sources":["../requires.test.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,KAAK,EAAK,MAAM,YAAY,CAAA;AAErD,OAAO,EAAkB,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAClE,OAAO,
|
|
1
|
+
{"version":3,"file":"requires.test.d.ts","sourceRoot":"","sources":["../requires.test.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,KAAK,EAAK,MAAM,YAAY,CAAA;AAErD,OAAO,EAAkB,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAClE,OAAO,EAAmD,IAAI,EAAE,QAAQ,EAAqB,MAAM,eAAe,CAAA;;;;;;AAElH,qBAAa,cAAe,SAAQ,mBAUlC;CACD;;;;;;;AAGD,qBAAa,kBAAmB,SAAQ,uBAQtC;CACD;;;;;;;AAED,qBAAa,kBAAmB,SAAQ,uBAYtC;CACD;;;;;;;AAED,qBAAa,sBAAuB,SAAQ,2BAa1C;CACD"}
|
package/test/fixtures.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Context, Effect, Option, S, Scope } from "effect-app"
|
|
2
|
-
import { NotLoggedInError,
|
|
2
|
+
import { NotLoggedInError, RPCContextMap, UnauthorizedError } from "effect-app/client"
|
|
3
3
|
import { TaggedError } from "effect-app/Schema"
|
|
4
4
|
import { contextMap, Middleware } from "../src/api/routing.js"
|
|
5
5
|
|
|
@@ -13,15 +13,25 @@ export class UserProfile extends Context.assignTag<UserProfile, UserProfile>("Us
|
|
|
13
13
|
|
|
14
14
|
export class Some extends Context.TagMakeId("Some", Effect.succeed({ a: 1 }))<Some>() {}
|
|
15
15
|
export class SomeElse extends Context.TagMakeId("SomeElse", Effect.succeed({ b: 2 }))<SomeElse>() {}
|
|
16
|
+
const MakeSomeService = Effect.succeed({ a: 1 })
|
|
17
|
+
export class SomeService extends Context.TagMakeId("SomeService", MakeSomeService)<SomeService>() {}
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
// TODO: null as never sucks
|
|
20
|
+
// why [UserProfile] is needed? AllowAnonymous triggers an error if just UserProfile without []
|
|
21
|
+
// [] requires return Context, non [] requires return the Service instance
|
|
22
|
+
//
|
|
23
|
+
// consider if we want to support Context of one Service
|
|
24
|
+
export const RequestContextMap = {
|
|
25
|
+
allowAnonymous: RPCContextMap.makeInverted([UserProfile], NotLoggedInError),
|
|
26
|
+
requireRoles: RPCContextMap.makeCustom(null as never, UnauthorizedError, Array<string>()),
|
|
27
|
+
test: RPCContextMap.make(null as never, S.Never)
|
|
28
|
+
} as const
|
|
29
|
+
|
|
30
|
+
type _RequestContextMap = typeof RequestContextMap
|
|
31
|
+
export interface RequestContextMap extends _RequestContextMap {}
|
|
22
32
|
|
|
23
33
|
export class AllowAnonymous extends Middleware.Tag<AllowAnonymous>()("AllowAnonymous", {
|
|
24
|
-
dynamic: contextMap
|
|
34
|
+
dynamic: contextMap(RequestContextMap, "allowAnonymous"),
|
|
25
35
|
requires: SomeElse
|
|
26
36
|
})({
|
|
27
37
|
effect: Effect.gen(function*() {
|
|
@@ -51,9 +61,10 @@ export class AllowAnonymous extends Middleware.Tag<AllowAnonymous>()("AllowAnony
|
|
|
51
61
|
}) {
|
|
52
62
|
}
|
|
53
63
|
|
|
64
|
+
// TODO: don't expect service when it's wrap
|
|
54
65
|
// @effect-diagnostics-next-line missingEffectServiceDependency:off
|
|
55
66
|
export class RequireRoles extends Middleware.Tag<RequireRoles>()("RequireRoles", {
|
|
56
|
-
dynamic: contextMap
|
|
67
|
+
dynamic: contextMap(RequestContextMap, "requireRoles"),
|
|
57
68
|
wrap: true,
|
|
58
69
|
// wrap: true,
|
|
59
70
|
// had to move this in here, because once you put it manually as a readonly static property on the class,
|
|
@@ -61,7 +72,7 @@ export class RequireRoles extends Middleware.Tag<RequireRoles>()("RequireRoles",
|
|
|
61
72
|
dependsOn: [AllowAnonymous]
|
|
62
73
|
})({
|
|
63
74
|
effect: Effect.gen(function*() {
|
|
64
|
-
yield*
|
|
75
|
+
yield* SomeService
|
|
65
76
|
return Effect.fnUntraced(
|
|
66
77
|
function*({ config, next }) {
|
|
67
78
|
// we don't know if the service will be provided or not, so we use option..
|
|
@@ -84,9 +95,10 @@ export class RequireRoles extends Middleware.Tag<RequireRoles>()("RequireRoles",
|
|
|
84
95
|
}) {
|
|
85
96
|
}
|
|
86
97
|
|
|
98
|
+
// TODO: don't expect service when it's wrap
|
|
87
99
|
export class Test extends Middleware.Tag<Test>()("Test", {
|
|
88
100
|
wrap: true,
|
|
89
|
-
dynamic: contextMap
|
|
101
|
+
dynamic: contextMap(RequestContextMap, "test")
|
|
90
102
|
})({
|
|
91
103
|
effect: Effect.gen(function*() {
|
|
92
104
|
return Effect.fn(function*({ next }) {
|
|
@@ -97,6 +109,3 @@ export class Test extends Middleware.Tag<Test>()("Test", {
|
|
|
97
109
|
|
|
98
110
|
export class CustomError1 extends TaggedError<NotLoggedInError>()("CustomError1", {}) {}
|
|
99
111
|
export class CustomError2 extends TaggedError<NotLoggedInError>()("CustomError1", {}) {}
|
|
100
|
-
|
|
101
|
-
const MakeSomeService = Effect.succeed({ a: 1 })
|
|
102
|
-
export class SomeService extends Context.TagMakeId("SomeService", MakeSomeService)<SomeService>() {}
|
package/test/layerUtils.test.ts
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
import { it } from "@effect/vitest"
|
|
1
|
+
import { expectTypeOf, it } from "@effect/vitest"
|
|
2
2
|
import { type Layer } from "effect"
|
|
3
|
-
import { expectTypeOf } from "vitest/index.cjs"
|
|
4
3
|
import { type LayerUtils } from "../src/api/layerUtils.js"
|
|
5
4
|
|
|
6
5
|
it("works", () => {
|
|
6
|
+
// not supported atm, resolves to unknown!
|
|
7
|
+
// type None = LayerUtils.GetLayersContext<any[]>
|
|
7
8
|
type B = (Layer.Layer<void, "error-a", "a"> | Layer.Layer<void, "error-b", "b">)[]
|
|
8
9
|
type C = LayerUtils.GetLayersContext<B>
|
|
9
10
|
type CE = LayerUtils.GetLayersError<B>
|
|
10
11
|
|
|
11
12
|
expectTypeOf({} as C).toEqualTypeOf<"a" | "b">()
|
|
12
13
|
expectTypeOf({} as CE).toEqualTypeOf<"error-a" | "error-b">()
|
|
14
|
+
// expectTypeOf({} as None).toEqualTypeOf<never>()
|
|
13
15
|
|
|
14
16
|
type B2 = [Layer.Layer<void, "error-a", "a">, Layer.Layer<void, "error-b", "b"> | Layer.Layer<void, "error-c", "c">]
|
|
15
17
|
type C2 = LayerUtils.GetLayersContext<B2>
|