@effect-app/infra 2.87.2 → 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 (36) hide show
  1. package/CHANGELOG.md +13 -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/package.json +2 -2
  20. package/src/api/routing/middleware/RouterMiddleware.ts +8 -86
  21. package/src/api/routing/middleware/RpcMiddleware.ts +13 -12
  22. package/src/api/routing/middleware/dynamic-middleware.ts +0 -47
  23. package/src/api/routing/middleware/generic-middleware.ts +45 -14
  24. package/src/api/routing/middleware/middleware-api.ts +147 -101
  25. package/src/api/routing/middleware/middleware.ts +5 -5
  26. package/test/contextProvider.test.ts +27 -24
  27. package/test/controller.test.ts +44 -9
  28. package/test/dist/contextProvider.test.d.ts.map +1 -1
  29. package/test/dist/controller.test.d.ts.map +1 -1
  30. package/test/dist/fixtures.d.ts +39 -45
  31. package/test/dist/fixtures.d.ts.map +1 -1
  32. package/test/dist/fixtures.js +21 -9
  33. package/test/dist/requires.test.d.ts.map +1 -1
  34. package/test/fixtures.ts +22 -13
  35. package/test/layerUtils.test.ts +1 -2
  36. package/test/requires.test.ts +119 -97
@@ -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,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,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", () => {
@@ -1,8 +1,8 @@
1
- import { expect, expectTypeOf, it } from "@effect/vitest"
1
+ import { describe, expect, expectTypeOf, it } from "@effect/vitest"
2
2
  import { Effect, Either, Layer, S } from "effect-app"
3
3
  import { NotLoggedInError, UnauthorizedError } from "effect-app/client"
4
4
  import { makeMiddleware, Middleware } from "../src/api/routing.js"
5
- import { AllowAnonymous, type RequestContextMap, RequireRoles, Some, SomeElse, Test } from "./fixtures.js"
5
+ import { AllowAnonymous, RequestContextMap, RequireRoles, Some, SomeElse, SomeService, Test } from "./fixtures.js"
6
6
 
7
7
  export class SomeMiddleware extends Middleware.Tag<SomeMiddleware>()("SomeMiddleware", {
8
8
  provides: Some
@@ -17,6 +17,18 @@ export class SomeMiddleware extends Middleware.Tag<SomeMiddleware>()("SomeMiddle
17
17
  }) {
18
18
  }
19
19
 
20
+ // functionally equivalent to the one above
21
+ export class SomeMiddlewareWrap extends Middleware.Tag<SomeMiddlewareWrap>()("SomeMiddlewareWrap", {
22
+ provides: Some,
23
+ wrap: true
24
+ })({
25
+ effect: Effect.gen(function*() {
26
+ // yield* Effect.context<"test-dep">()
27
+ return ({ next }) => next.pipe(Effect.provideService(Some, new Some({ a: 1 })))
28
+ })
29
+ }) {
30
+ }
31
+
20
32
  export class SomeElseMiddleware extends Middleware.Tag<SomeElseMiddleware>()("SomeElseMiddleware", {
21
33
  provides: SomeElse,
22
34
  wrap: true
@@ -48,109 +60,119 @@ export class RequiresSomeMiddleware extends Middleware.Tag<RequiresSomeMiddlewar
48
60
  }) {
49
61
  }
50
62
 
51
- it("requires gets enforced", async () => {
52
- const middleware3 = makeMiddleware<RequestContextMap>()
53
- .middleware(RequiresSomeMiddleware)
54
- .middleware(SomeMiddleware)
55
- .middleware(RequireRoles)
56
- .middleware(AllowAnonymous, Test)
57
- .middleware(SomeElseMiddleware)
63
+ const middleware3 = makeMiddleware(RequestContextMap)
64
+ .middleware(RequiresSomeMiddleware)
65
+ .middleware(SomeMiddleware)
66
+ .middleware(RequireRoles)
67
+ .middleware(AllowAnonymous, Test)
68
+ .middleware(SomeElseMiddleware)
58
69
 
59
- const layer = middleware3.Default.pipe(Layer.provide(Layer.succeed(Some, new Some({ a: 1 }))))
70
+ const _middlewareSideways = makeMiddleware(RequestContextMap)
71
+ .middleware(RequiresSomeMiddleware)
72
+ .middleware(SomeMiddleware)
73
+ .middleware(RequireRoles, AllowAnonymous, Test)
74
+ .middleware(SomeElseMiddleware)
60
75
 
61
- type Default = typeof middleware3["Default"]
62
- type LayerContext = Layer.Layer.Context<Default>
63
- expectTypeOf({} as LayerContext).toEqualTypeOf<Some>()
76
+ const _middlewareSidewaysFully = makeMiddleware(RequestContextMap)
77
+ .middleware(RequiresSomeMiddleware, SomeMiddleware, RequireRoles, AllowAnonymous, Test, SomeElseMiddleware)
64
78
 
65
- await Effect
66
- .gen(function*() {
67
- const mw = yield* middleware3
68
- const mwM = mw.effect(
69
- Object.assign({}, S.Any, { config: { requireRoles: ["manager"] } }),
70
- (_req) => Effect.void,
71
- "some-module"
72
- )
73
- yield* mwM({}, { "x-user": "test-user", "x-is-manager": "true" })
74
- })
75
- .pipe(
76
- Effect.scoped,
77
- Effect.provide(layer),
78
- Effect.runPromise
79
- )
79
+ const _middleware3Bis = makeMiddleware(RequestContextMap)
80
+ .middleware(RequiresSomeMiddleware)
81
+ .middleware(SomeMiddlewareWrap)
82
+ .middleware(RequireRoles)
83
+ .middleware(AllowAnonymous, Test)
84
+ .middleware(SomeElseMiddleware)
80
85
 
81
- await Effect
82
- .gen(function*() {
83
- const mw = yield* middleware3
84
- const mwM = mw.effect(
85
- Object.assign({}, S.Any, { config: { allowAnonymous: true } }),
86
- (_req) => Effect.void,
87
- "some-module"
88
- )
89
- yield* mwM({}, {})
90
- })
91
- .pipe(
92
- Effect.scoped,
93
- Effect.provide(layer),
94
- Effect.runPromise
95
- )
86
+ expectTypeOf(_middlewareSideways).toEqualTypeOf<typeof middleware3>()
87
+ expectTypeOf(_middlewareSidewaysFully).toEqualTypeOf<typeof _middlewareSideways>()
88
+ expectTypeOf(_middleware3Bis).toEqualTypeOf<typeof middleware3>()
89
+
90
+ type Default = typeof middleware3["Default"]
91
+ type LayerContext = Layer.Layer.Context<Default>
92
+ expectTypeOf({} as LayerContext).toEqualTypeOf<SomeService>()
96
93
 
97
- expect(
98
- await Effect
99
- .gen(function*() {
100
- const mw = yield* middleware3
101
- const mwM = mw.effect(
102
- Object.assign({}, S.Any, { config: {} }),
103
- (_req) => Effect.void,
104
- "some-module"
94
+ const testSuite = (_mw: typeof middleware3) =>
95
+ describe("middleware" + _mw, () => {
96
+ it.effect(
97
+ "works",
98
+ Effect.fn(function*() {
99
+ const layer = _mw.Default.pipe(Layer.provide(SomeService.toLayer()))
100
+ yield* Effect
101
+ .gen(function*() {
102
+ const mw = yield* _mw
103
+ const mwM = mw.effect(
104
+ Object.assign({}, S.Any, { config: { requireRoles: ["manager"] } }),
105
+ (_req) => Effect.void,
106
+ "some-module"
107
+ )
108
+ yield* mwM({}, { "x-user": "test-user", "x-is-manager": "true" })
109
+ })
110
+ .pipe(
111
+ Effect.scoped,
112
+ Effect.provide(layer)
113
+ )
114
+
115
+ expect(
116
+ yield* Effect
117
+ .gen(function*() {
118
+ const mw = yield* _mw
119
+ const mwM = mw.effect(
120
+ Object.assign({}, S.Any, { config: {} }),
121
+ (_req) => Effect.void,
122
+ "some-module"
123
+ )
124
+ yield* mwM({}, {})
125
+ })
126
+ .pipe(
127
+ Effect.scoped,
128
+ Effect.provide(layer),
129
+ Effect.either
130
+ )
105
131
  )
106
- yield* mwM({}, {})
107
- })
108
- .pipe(
109
- Effect.scoped,
110
- Effect.provide(layer),
111
- Effect.either,
112
- Effect.runPromise
113
- )
114
- )
115
- .toEqual(Either.left(new NotLoggedInError()))
132
+ .toEqual(Either.left(new NotLoggedInError()))
116
133
 
117
- expect(
118
- await Effect
119
- .gen(function*() {
120
- const mw = yield* middleware3
121
- const mwM = mw.effect(
122
- Object.assign({}, S.Any, { config: { requireRoles: ["manager"] } }),
123
- (_req) => Effect.void,
124
- "some-module"
134
+ expect(
135
+ yield* Effect
136
+ .gen(function*() {
137
+ const mw = yield* _mw
138
+ const mwM = mw.effect(
139
+ Object.assign({}, S.Any, { config: { requireRoles: ["manager"] } }),
140
+ (_req) => Effect.void,
141
+ "some-module"
142
+ )
143
+ yield* mwM({}, {})
144
+ })
145
+ .pipe(
146
+ Effect.scoped,
147
+ Effect.provide(layer),
148
+ Effect.either
149
+ )
125
150
  )
126
- yield* mwM({}, {})
127
- })
128
- .pipe(
129
- Effect.scoped,
130
- Effect.provide(layer),
131
- Effect.either,
132
- Effect.runPromise
133
- )
134
- )
135
- .toEqual(Either.left(new NotLoggedInError()))
151
+ .toEqual(Either.left(new NotLoggedInError()))
136
152
 
137
- expect(
138
- await Effect
139
- .gen(function*() {
140
- const mw = yield* middleware3
141
- const mwM = mw.effect(
142
- Object.assign({}, S.Any, { config: { requireRoles: ["manager"] } }),
143
- (_req) => Effect.void,
144
- "some-module"
153
+ expect(
154
+ yield* Effect
155
+ .gen(function*() {
156
+ const mw = yield* _mw
157
+ const mwM = mw.effect(
158
+ Object.assign({}, S.Any, { config: { requireRoles: ["manager"] } }),
159
+ (_req) => Effect.void,
160
+ "some-module"
161
+ )
162
+ yield* mwM({}, { "x-user": "test-user" })
163
+ })
164
+ .pipe(
165
+ Effect.scoped,
166
+ Effect.provide(layer),
167
+ Effect.either
168
+ )
145
169
  )
146
- yield* mwM({}, { "x-user": "test-user" })
170
+ .toEqual(Either.left(new UnauthorizedError({ message: "don't have the right roles" })))
147
171
  })
148
- .pipe(
149
- Effect.scoped,
150
- Effect.provide(layer),
151
- Effect.either,
152
- Effect.runPromise
153
- )
154
- )
155
- .toEqual(Either.left(new UnauthorizedError({ message: "don't have the right roles" })))
156
- })
172
+ )
173
+ })
174
+
175
+ testSuite(middleware3)
176
+ testSuite(_middleware3Bis)
177
+ testSuite(_middlewareSideways)
178
+ testSuite(_middlewareSidewaysFully)