@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.
Files changed (40) hide show
  1. package/CHANGELOG.md +19 -1
  2. package/dist/api/routing/middleware/RouterMiddleware.d.ts +4 -22
  3. package/dist/api/routing/middleware/RouterMiddleware.d.ts.map +1 -1
  4. package/dist/api/routing/middleware/RouterMiddleware.js +1 -1
  5. package/dist/api/routing/middleware/RpcMiddleware.d.ts +13 -13
  6. package/dist/api/routing/middleware/RpcMiddleware.d.ts.map +1 -1
  7. package/dist/api/routing/middleware/RpcMiddleware.js +1 -1
  8. package/dist/api/routing/middleware/dynamic-middleware.d.ts +1 -9
  9. package/dist/api/routing/middleware/dynamic-middleware.d.ts.map +1 -1
  10. package/dist/api/routing/middleware/generic-middleware.d.ts +8 -8
  11. package/dist/api/routing/middleware/generic-middleware.d.ts.map +1 -1
  12. package/dist/api/routing/middleware/generic-middleware.js +23 -7
  13. package/dist/api/routing/middleware/middleware-api.d.ts +59 -30
  14. package/dist/api/routing/middleware/middleware-api.d.ts.map +1 -1
  15. package/dist/api/routing/middleware/middleware-api.js +44 -35
  16. package/dist/api/routing/middleware/middleware.d.ts +7 -7
  17. package/dist/api/routing/middleware/middleware.d.ts.map +1 -1
  18. package/dist/api/routing/middleware/middleware.js +5 -5
  19. package/dist/api/routing.d.ts +28 -22
  20. package/dist/api/routing.d.ts.map +1 -1
  21. package/dist/api/routing.js +1 -1
  22. package/package.json +2 -2
  23. package/src/api/routing/middleware/RouterMiddleware.ts +8 -86
  24. package/src/api/routing/middleware/RpcMiddleware.ts +13 -12
  25. package/src/api/routing/middleware/dynamic-middleware.ts +0 -47
  26. package/src/api/routing/middleware/generic-middleware.ts +45 -14
  27. package/src/api/routing/middleware/middleware-api.ts +147 -101
  28. package/src/api/routing/middleware/middleware.ts +5 -5
  29. package/src/api/routing.ts +50 -35
  30. package/test/contextProvider.test.ts +27 -24
  31. package/test/controller.test.ts +45 -23
  32. package/test/dist/contextProvider.test.d.ts.map +1 -1
  33. package/test/dist/controller.test.d.ts.map +1 -1
  34. package/test/dist/fixtures.d.ts +38 -44
  35. package/test/dist/fixtures.d.ts.map +1 -1
  36. package/test/dist/fixtures.js +21 -9
  37. package/test/dist/requires.test.d.ts.map +1 -1
  38. package/test/fixtures.ts +22 -13
  39. package/test/layerUtils.test.ts +4 -2
  40. 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
- const merged = mergeContextProviders(MyContextProvider)
125
- const mergedGen = mergeContextProviders(MyContextProviderGen)
123
+ it("works", () => {
124
+ expectTypeOf(someContextProvider).toEqualTypeOf<typeof someContextProviderGen>()
126
125
 
127
- export const contextProvider2 = ContextProvider(merged)
128
- export const contextProvider3 = MergedContextProvider(MyContextProvider)
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
- export const contextProvider2Gen = ContextProvider(mergedGen)
133
- export const contextProvider3Gen = MergedContextProvider(MyContextProviderGen)
134
- expectTypeOf(contextProvider2Gen).toEqualTypeOf<typeof someContextProvider>()
135
- expectTypeOf(contextProvider3Gen).toEqualTypeOf<typeof contextProvider2Gen>()
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
- expectTypeOf(contextProvider2Gen).toEqualTypeOf<typeof contextProvider2>()
138
- expectTypeOf(contextProvider3Gen).toEqualTypeOf<typeof contextProvider3>()
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
- const merged2 = mergeContextProviders(MyContextProvider, MyContextProvider2)
141
- export const contextProvider22 = ContextProvider(merged2)
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 merged2Gen = mergeContextProviders(MyContextProviderGen, MyContextProvider2Gen)
146
- export const contextProvider22Gen = ContextProvider(merged2Gen)
147
- export const contextProvider23Gen = MergedContextProvider(MyContextProviderGen, MyContextProvider2Gen)
148
- expectTypeOf(contextProvider23Gen).toEqualTypeOf<typeof contextProvider22Gen>()
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
- expectTypeOf(contextProvider22Gen).toEqualTypeOf<typeof contextProvider22>()
151
- expectTypeOf(contextProvider23Gen).toEqualTypeOf<typeof contextProvider23>()
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
+ })
@@ -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, type RequestContextMap, RequireRoles, Some, SomeElse, SomeService, Test } from "./fixtures.js"
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.pipe(Effect.provideService(SomeService, null as any))
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 middleware2 = makeMiddleware<RequestContextMap>()
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 | Some | "str">()
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<Some | SomeService | "str">()
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,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AA8EzE,eAAO,MAAM,mBAAmB;;CAkB9B,CAAA;AACF,eAAO,MAAM,sBAAsB;;CAkBjC,CAAA;AAMF,eAAO,MAAM,gBAAgB;;CAA0B,CAAA;AACvD,eAAO,MAAM,gBAAgB,kMAA2C,CAAA;AAIxE,eAAO,MAAM,mBAAmB;;CAA6B,CAAA;AAC7D,eAAO,MAAM,mBAAmB,kMAA8C,CAAA;AAQ9E,eAAO,MAAM,iBAAiB;;CAA2B,CAAA;AACzD,eAAO,MAAM,iBAAiB,6MAA+D,CAAA;AAI7F,eAAO,MAAM,oBAAoB;;CAA8B,CAAA;AAC/D,eAAO,MAAM,oBAAoB,6MAAqE,CAAA"}
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,KAAK,iBAAiB,EAAE,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;;;;;;AAgCrI,cAAM,kBAAmB,SAAQ,uBAU/B;CAAG;;;;;;;AAML,qBAAa,eAAgB,SAAQ,oBAanC;CACD;AAwBD,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"}
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"}
@@ -1,5 +1,5 @@
1
1
  import { Context, Effect, S, Scope } from "effect-app";
2
- import { NotLoggedInError, type RPCContextMap, UnauthorizedError } from "effect-app/client";
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
- export type RequestContextMap = {
71
- allowAnonymous: RPCContextMap.Inverted<[typeof UserProfile], typeof NotLoggedInError>;
72
- requireRoles: RPCContextMap.Custom<never, typeof UnauthorizedError, Array<string>>;
73
- test: RPCContextMap<never, typeof S.Never>;
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, Some>;
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,KAAK,aAAa,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAE3F,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,MAAM,MAAM,iBAAiB,GAAG;IAC9B,cAAc,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC,OAAO,WAAW,CAAC,EAAE,OAAO,gBAAgB,CAAC,CAAA;IACrF,YAAY,EAAE,aAAa,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,iBAAiB,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAA;IAClF,IAAI,EAAE,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAA;CAC3C,CAAA;;;;;;;;;;AAED,qBAAa,cAAe,SAAQ,mBA4BlC;CACD;;;;;;;;;;;AAGD,qBAAa,YAAa,SAAQ,iBA6BhC;CACD;;;;;;;;;;AAED,qBAAa,IAAK,SAAQ,SASxB;CAAG;;;;AAEL,qBAAa,YAAa,SAAQ,iBAAmD;CAAG;;;;AACxF,qBAAa,YAAa,SAAQ,iBAAmD;CAAG;;;;;;;;;;;;;;;;;;;;;;;;;AAGxF,qBAAa,WAAY,SAAQ,gBAAgE;CAAG"}
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"}
@@ -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()("allowAnonymous", [UserProfile]),
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()("requireRoles", null), // TODO
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* Some;
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()("test", null) // TODO
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
- const MakeSomeService = Effect.succeed({ a: 1 });
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,EAAwD,IAAI,EAAE,QAAQ,EAAQ,MAAM,eAAe,CAAA;;;;;;AAE1G,qBAAa,cAAe,SAAQ,mBAUlC;CACD;;;;;;;AAED,qBAAa,kBAAmB,SAAQ,uBAYtC;CACD;;;;;;;AAED,qBAAa,sBAAuB,SAAQ,2BAa1C;CACD"}
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, type RPCContextMap, 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
 
@@ -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
- export type RequestContextMap = {
18
- allowAnonymous: RPCContextMap.Inverted<[typeof UserProfile], typeof NotLoggedInError>
19
- requireRoles: RPCContextMap.Custom<never, typeof UnauthorizedError, Array<string>>
20
- test: RPCContextMap<never, typeof S.Never>
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<RequestContextMap>()("allowAnonymous", [UserProfile]),
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<RequestContextMap>()("requireRoles", null as never), // TODO
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* Some
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<RequestContextMap>()("test", null as never) // TODO
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>() {}
@@ -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>