@effect-app/infra 2.87.2 → 2.89.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 (50) hide show
  1. package/CHANGELOG.md +24 -1
  2. package/dist/api/{routing/middleware/ContextProvider.d.ts → ContextProvider.d.ts} +1 -1
  3. package/dist/api/ContextProvider.d.ts.map +1 -0
  4. package/dist/api/ContextProvider.js +38 -0
  5. package/dist/api/routing/middleware/RouterMiddleware.d.ts +15 -28
  6. package/dist/api/routing/middleware/RouterMiddleware.d.ts.map +1 -1
  7. package/dist/api/routing/middleware/RouterMiddleware.js +2 -5
  8. package/dist/api/routing/middleware/RpcMiddleware.d.ts +19 -23
  9. package/dist/api/routing/middleware/RpcMiddleware.d.ts.map +1 -1
  10. package/dist/api/routing/middleware/RpcMiddleware.js +1 -1
  11. package/dist/api/routing/middleware/dynamic-middleware.d.ts +1 -9
  12. package/dist/api/routing/middleware/dynamic-middleware.d.ts.map +1 -1
  13. package/dist/api/routing/middleware/generic-middleware.d.ts +24 -22
  14. package/dist/api/routing/middleware/generic-middleware.d.ts.map +1 -1
  15. package/dist/api/routing/middleware/generic-middleware.js +24 -8
  16. package/dist/api/routing/middleware/middleware-api.d.ts +68 -36
  17. package/dist/api/routing/middleware/middleware-api.d.ts.map +1 -1
  18. package/dist/api/routing/middleware/middleware-api.js +45 -45
  19. package/dist/api/routing/middleware/middleware.d.ts +7 -7
  20. package/dist/api/routing/middleware/middleware.d.ts.map +1 -1
  21. package/dist/api/routing/middleware/middleware.js +5 -5
  22. package/dist/api/routing/middleware.d.ts +0 -1
  23. package/dist/api/routing/middleware.d.ts.map +1 -1
  24. package/dist/api/routing/middleware.js +1 -2
  25. package/dist/api/routing.d.ts +1 -1
  26. package/dist/api/routing.d.ts.map +1 -1
  27. package/dist/api/routing.js +12 -10
  28. package/package.json +6 -6
  29. package/src/api/{routing/middleware/ContextProvider.ts → ContextProvider.ts} +1 -1
  30. package/src/api/routing/middleware/RouterMiddleware.ts +22 -134
  31. package/src/api/routing/middleware/RpcMiddleware.ts +28 -23
  32. package/src/api/routing/middleware/dynamic-middleware.ts +0 -47
  33. package/src/api/routing/middleware/generic-middleware.ts +84 -35
  34. package/src/api/routing/middleware/middleware-api.ts +190 -159
  35. package/src/api/routing/middleware/middleware.ts +5 -5
  36. package/src/api/routing/middleware.ts +0 -1
  37. package/src/api/routing.ts +22 -20
  38. package/test/contextProvider.test.ts +28 -25
  39. package/test/controller.test.ts +44 -9
  40. package/test/dist/contextProvider.test.d.ts.map +1 -1
  41. package/test/dist/controller.test.d.ts.map +1 -1
  42. package/test/dist/fixtures.d.ts +39 -45
  43. package/test/dist/fixtures.d.ts.map +1 -1
  44. package/test/dist/fixtures.js +27 -14
  45. package/test/dist/requires.test.d.ts.map +1 -1
  46. package/test/fixtures.ts +29 -18
  47. package/test/layerUtils.test.ts +1 -2
  48. package/test/requires.test.ts +146 -103
  49. package/dist/api/routing/middleware/ContextProvider.d.ts.map +0 -1
  50. package/dist/api/routing/middleware/ContextProvider.js +0 -38
@@ -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>()
@@ -307,7 +342,7 @@ const router2 = r2.Router(Something)({
307
342
 
308
343
  // eslint-disable-next-line unused-imports/no-unused-vars
309
344
  const matched2 = matchAll({ router: router2 })
310
- expectTypeOf({} as Layer.Context<typeof matched2>).toEqualTypeOf<Some | SomeService | "str">()
345
+ expectTypeOf({} as Layer.Context<typeof matched2>).toEqualTypeOf<SomeService | "str">()
311
346
 
312
347
  type makeContext2 = MakeContext<typeof router2.make>
313
348
  expectTypeOf({} as MakeErrors<typeof router2.make>).toEqualTypeOf<InvalidStateError>()
@@ -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;
@@ -37,7 +37,7 @@ declare const Some_base: (abstract new (service: {
37
37
  } & {
38
38
  use: <X>(body: (_: {
39
39
  a: number;
40
- }) => X) => X extends Effect.Effect<infer A, infer E_1, infer R_3> ? Effect.Effect<A, E_1, R_3 | Some> : Effect.Effect<X, never, Some>;
40
+ }) => X) => X extends Effect.Effect<infer A, infer E_1, infer R_3> ? Effect.Effect<A, E_1, Some | R_3> : Effect.Effect<X, never, Some>;
41
41
  };
42
42
  export declare class Some extends Some_base {
43
43
  }
@@ -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>;
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>;
74
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, SomeService | R_3> : 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,EAAyB,UAAU,EAAE,MAAM,uBAAuB,CAAA;;;;;;;;;;;;;AAEzE,qBAAa,WAAY,SAAQ,gBAKhC;CACA;;;;;;;;;;;;;;;;;;;;;;;;;AAED,qBAAa,IAAK,SAAQ,SAA2D;CAAG;;;;;;;;;;;;;;;;;;;;;;;;;AACxF,qBAAa,QAAS,SAAQ,aAAmE;CAAG;;;;;;;;;;;;;;;;;;;;;;;;;AAEpG,qBAAa,WAAY,SAAQ,gBAAgE;CAAG;AASpG,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,7 +1,7 @@
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
- import { contextMap, Middleware } from "../src/api/routing.js";
4
+ import { contextMap, getConfig, Middleware } from "../src/api/routing.js";
5
5
  export class UserProfile extends Context.assignTag("UserProfile")(S.Class("UserProfile")({
6
6
  id: S.String,
7
7
  roles: S.Array(S.String)
@@ -11,17 +11,31 @@ 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
+ const requestConfig = getConfig();
18
+ // TODO: null as never sucks
19
+ // why [UserProfile] is needed? AllowAnonymous triggers an error if just UserProfile without []
20
+ // [] requires return Context, non [] requires return the Service instance
21
+ //
22
+ // consider if we want to support Context of one Service
23
+ export const RequestContextMap = {
24
+ allowAnonymous: RPCContextMap.makeInverted([UserProfile], NotLoggedInError),
25
+ requireRoles: RPCContextMap.makeCustom(null, UnauthorizedError, Array()),
26
+ test: RPCContextMap.make(null, S.Never)
27
+ };
14
28
  export class AllowAnonymous extends Middleware.Tag()("AllowAnonymous", {
15
- dynamic: contextMap()("allowAnonymous", [UserProfile]),
29
+ dynamic: contextMap(RequestContextMap, "allowAnonymous"),
16
30
  requires: SomeElse
17
31
  })({
18
32
  effect: Effect.gen(function* () {
19
- return Effect.fnUntraced(function* ({ config, headers }) {
33
+ return Effect.fnUntraced(function* ({ headers, rpc }) {
20
34
  yield* SomeElse;
21
35
  yield* Scope.Scope; // provided by HttpRouter.HttpRouter.Provided
22
36
  const isLoggedIn = !!headers["x-user"];
23
37
  if (!isLoggedIn) {
24
- if (!config.allowAnonymous) {
38
+ if (!requestConfig(rpc).allowAnonymous) {
25
39
  return yield* new NotLoggedInError({ message: "Not logged in" });
26
40
  }
27
41
  return Option.none();
@@ -34,9 +48,10 @@ export class AllowAnonymous extends Middleware.Tag()("AllowAnonymous", {
34
48
  })
35
49
  }) {
36
50
  }
51
+ // TODO: don't expect service when it's wrap
37
52
  // @effect-diagnostics-next-line missingEffectServiceDependency:off
38
53
  export class RequireRoles extends Middleware.Tag()("RequireRoles", {
39
- dynamic: contextMap()("requireRoles", null), // TODO
54
+ dynamic: contextMap(RequestContextMap, "requireRoles"),
40
55
  wrap: true,
41
56
  // wrap: true,
42
57
  // had to move this in here, because once you put it manually as a readonly static property on the class,
@@ -44,11 +59,11 @@ export class RequireRoles extends Middleware.Tag()("RequireRoles", {
44
59
  dependsOn: [AllowAnonymous]
45
60
  })({
46
61
  effect: Effect.gen(function* () {
47
- yield* Some;
48
- return Effect.fnUntraced(function* ({ config, next }) {
62
+ yield* SomeService;
63
+ return Effect.fnUntraced(function* ({ next, rpc }) {
49
64
  // we don't know if the service will be provided or not, so we use option..
50
65
  const userProfile = yield* Effect.serviceOption(UserProfile);
51
- const { requireRoles } = config;
66
+ const { requireRoles } = requestConfig(rpc);
52
67
  console.dir({
53
68
  userProfile,
54
69
  requireRoles
@@ -61,9 +76,10 @@ export class RequireRoles extends Middleware.Tag()("RequireRoles", {
61
76
  })
62
77
  }) {
63
78
  }
79
+ // TODO: don't expect service when it's wrap
64
80
  export class Test extends Middleware.Tag()("Test", {
65
81
  wrap: true,
66
- dynamic: contextMap()("test", null) // TODO
82
+ dynamic: contextMap(RequestContextMap, "test")
67
83
  })({
68
84
  effect: Effect.gen(function* () {
69
85
  return Effect.fn(function* ({ next }) {
@@ -76,7 +92,4 @@ export class CustomError1 extends TaggedError()("CustomError1", {}) {
76
92
  }
77
93
  export class CustomError2 extends TaggedError()("CustomError1", {}) {
78
94
  }
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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
95
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZml4dHVyZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9maXh0dXJlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxNQUFNLFlBQVksQ0FBQTtBQUM5RCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsYUFBYSxFQUFFLGlCQUFpQixFQUFFLE1BQU0sbUJBQW1CLENBQUE7QUFDdEYsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLG1CQUFtQixDQUFBO0FBQy9DLE9BQU8sRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxNQUFNLHVCQUF1QixDQUFBO0FBRXpFLE1BQU0sT0FBTyxXQUFZLFNBQVEsT0FBTyxDQUFDLFNBQVMsQ0FBMkIsYUFBYSxDQUFDLENBQ3pGLENBQUMsQ0FBQyxLQUFLLENBQWMsYUFBYSxDQUFDLENBQUM7SUFDbEMsRUFBRSxFQUFFLENBQUMsQ0FBQyxNQUFNO0lBQ1osS0FBSyxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztDQUN6QixDQUFDLENBQ0g7Q0FDQTtBQUVELE1BQU0sT0FBTyxJQUFLLFNBQVEsT0FBTyxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQVE7Q0FBRztBQUN4RixNQUFNLE9BQU8sUUFBUyxTQUFRLE9BQU8sQ0FBQyxTQUFTLENBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFZO0NBQUc7QUFDcEcsTUFBTSxlQUFlLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFBO0FBQ2hELE1BQU0sT0FBTyxXQUFZLFNB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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":"AAGA,OAAO,EAA2B,KAAK,EAAK,MAAM,YAAY,CAAA;AAG9D,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,7 +1,7 @@
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
- import { contextMap, Middleware } from "../src/api/routing.js"
4
+ import { contextMap, getConfig, Middleware } from "../src/api/routing.js"
5
5
 
6
6
  export class UserProfile extends Context.assignTag<UserProfile, UserProfile>("UserProfile")(
7
7
  S.Class<UserProfile>("UserProfile")({
@@ -13,25 +13,37 @@ 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
+ const requestConfig = getConfig<RequestContextMap>()
20
+
21
+ // TODO: null as never sucks
22
+ // why [UserProfile] is needed? AllowAnonymous triggers an error if just UserProfile without []
23
+ // [] requires return Context, non [] requires return the Service instance
24
+ //
25
+ // consider if we want to support Context of one Service
26
+ export const RequestContextMap = {
27
+ allowAnonymous: RPCContextMap.makeInverted([UserProfile], NotLoggedInError),
28
+ requireRoles: RPCContextMap.makeCustom(null as never, UnauthorizedError, Array<string>()),
29
+ test: RPCContextMap.make(null as never, S.Never)
30
+ } as const
31
+
32
+ type _RequestContextMap = typeof RequestContextMap
33
+ export interface RequestContextMap extends _RequestContextMap {}
22
34
 
23
35
  export class AllowAnonymous extends Middleware.Tag<AllowAnonymous>()("AllowAnonymous", {
24
- dynamic: contextMap<RequestContextMap>()("allowAnonymous", [UserProfile]),
36
+ dynamic: contextMap(RequestContextMap, "allowAnonymous"),
25
37
  requires: SomeElse
26
38
  })({
27
39
  effect: Effect.gen(function*() {
28
40
  return Effect.fnUntraced(
29
- function*({ config, headers }) {
41
+ function*({ headers, rpc }) {
30
42
  yield* SomeElse
31
43
  yield* Scope.Scope // provided by HttpRouter.HttpRouter.Provided
32
44
  const isLoggedIn = !!headers["x-user"]
33
45
  if (!isLoggedIn) {
34
- if (!config.allowAnonymous) {
46
+ if (!requestConfig(rpc).allowAnonymous) {
35
47
  return yield* new NotLoggedInError({ message: "Not logged in" })
36
48
  }
37
49
  return Option.none()
@@ -51,9 +63,10 @@ export class AllowAnonymous extends Middleware.Tag<AllowAnonymous>()("AllowAnony
51
63
  }) {
52
64
  }
53
65
 
66
+ // TODO: don't expect service when it's wrap
54
67
  // @effect-diagnostics-next-line missingEffectServiceDependency:off
55
68
  export class RequireRoles extends Middleware.Tag<RequireRoles>()("RequireRoles", {
56
- dynamic: contextMap<RequestContextMap>()("requireRoles", null as never), // TODO
69
+ dynamic: contextMap(RequestContextMap, "requireRoles"),
57
70
  wrap: true,
58
71
  // wrap: true,
59
72
  // had to move this in here, because once you put it manually as a readonly static property on the class,
@@ -61,12 +74,12 @@ export class RequireRoles extends Middleware.Tag<RequireRoles>()("RequireRoles",
61
74
  dependsOn: [AllowAnonymous]
62
75
  })({
63
76
  effect: Effect.gen(function*() {
64
- yield* Some
77
+ yield* SomeService
65
78
  return Effect.fnUntraced(
66
- function*({ config, next }) {
79
+ function*({ next, rpc }) {
67
80
  // we don't know if the service will be provided or not, so we use option..
68
81
  const userProfile = yield* Effect.serviceOption(UserProfile)
69
- const { requireRoles } = config
82
+ const { requireRoles } = requestConfig(rpc)
70
83
  console.dir(
71
84
  {
72
85
  userProfile,
@@ -84,9 +97,10 @@ export class RequireRoles extends Middleware.Tag<RequireRoles>()("RequireRoles",
84
97
  }) {
85
98
  }
86
99
 
100
+ // TODO: don't expect service when it's wrap
87
101
  export class Test extends Middleware.Tag<Test>()("Test", {
88
102
  wrap: true,
89
- dynamic: contextMap<RequestContextMap>()("test", null as never) // TODO
103
+ dynamic: contextMap(RequestContextMap, "test")
90
104
  })({
91
105
  effect: Effect.gen(function*() {
92
106
  return Effect.fn(function*({ next }) {
@@ -97,6 +111,3 @@ export class Test extends Middleware.Tag<Test>()("Test", {
97
111
 
98
112
  export class CustomError1 extends TaggedError<NotLoggedInError>()("CustomError1", {}) {}
99
113
  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,6 +1,5 @@
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", () => {