@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.
- package/CHANGELOG.md +13 -1
- package/dist/api/routing/middleware/RouterMiddleware.d.ts +4 -22
- package/dist/api/routing/middleware/RouterMiddleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/RouterMiddleware.js +1 -1
- package/dist/api/routing/middleware/RpcMiddleware.d.ts +13 -13
- package/dist/api/routing/middleware/RpcMiddleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/RpcMiddleware.js +1 -1
- package/dist/api/routing/middleware/dynamic-middleware.d.ts +1 -9
- package/dist/api/routing/middleware/dynamic-middleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/generic-middleware.d.ts +8 -8
- package/dist/api/routing/middleware/generic-middleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/generic-middleware.js +23 -7
- package/dist/api/routing/middleware/middleware-api.d.ts +59 -30
- package/dist/api/routing/middleware/middleware-api.d.ts.map +1 -1
- package/dist/api/routing/middleware/middleware-api.js +44 -35
- package/dist/api/routing/middleware/middleware.d.ts +7 -7
- package/dist/api/routing/middleware/middleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/middleware.js +5 -5
- package/package.json +2 -2
- package/src/api/routing/middleware/RouterMiddleware.ts +8 -86
- package/src/api/routing/middleware/RpcMiddleware.ts +13 -12
- package/src/api/routing/middleware/dynamic-middleware.ts +0 -47
- package/src/api/routing/middleware/generic-middleware.ts +45 -14
- package/src/api/routing/middleware/middleware-api.ts +147 -101
- package/src/api/routing/middleware/middleware.ts +5 -5
- package/test/contextProvider.test.ts +27 -24
- package/test/controller.test.ts +44 -9
- package/test/dist/contextProvider.test.d.ts.map +1 -1
- package/test/dist/controller.test.d.ts.map +1 -1
- package/test/dist/fixtures.d.ts +39 -45
- package/test/dist/fixtures.d.ts.map +1 -1
- package/test/dist/fixtures.js +21 -9
- package/test/dist/requires.test.d.ts.map +1 -1
- package/test/fixtures.ts +22 -13
- package/test/layerUtils.test.ts +1 -2
- package/test/requires.test.ts +119 -97
package/test/dist/fixtures.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Context, Effect, S, Scope } from "effect-app";
|
|
2
|
-
import { NotLoggedInError,
|
|
2
|
+
import { NotLoggedInError, RPCContextMap, UnauthorizedError } from "effect-app/client";
|
|
3
3
|
import { Middleware } from "../src/api/routing.js";
|
|
4
4
|
declare const UserProfile_base: S.EnhancedClass<UserProfile, {
|
|
5
5
|
id: typeof S.String;
|
|
@@ -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,
|
|
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
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
70
|
+
declare const SomeService_base: (abstract new (service: {
|
|
71
|
+
a: number;
|
|
72
|
+
}) => Readonly<{
|
|
73
|
+
a: number;
|
|
74
|
+
}> & Context.TagClassShape<"SomeService", {
|
|
75
|
+
a: number;
|
|
76
|
+
}>) & {
|
|
77
|
+
toLayer: {
|
|
78
|
+
(): import("effect/Layer").Layer<SomeService, never, never>;
|
|
79
|
+
<E_1, R_1>(eff: Effect.Effect<Omit<SomeService, keyof Context.TagClassShape<any, any>>, E_1, R_1>): import("effect/Layer").Layer<SomeService, E_1, R_1>;
|
|
80
|
+
};
|
|
81
|
+
toLayerScoped: {
|
|
82
|
+
(): import("effect/Layer").Layer<SomeService, never, never>;
|
|
83
|
+
<E_1, R_2>(eff: Effect.Effect<Context.TagClassShape<any, any>, E_1, R_2>): import("effect/Layer").Layer<SomeService, E_1, Exclude<R_2, Scope.Scope>>;
|
|
84
|
+
};
|
|
85
|
+
of: (service: Context.TagClassShape<any, any>) => SomeService;
|
|
86
|
+
make: Effect.Effect<SomeService, never, never>;
|
|
87
|
+
} & Context.Tag<SomeService, SomeService> & {
|
|
88
|
+
a: Effect.Effect<number, never, SomeService>;
|
|
89
|
+
} & {
|
|
90
|
+
use: <X>(body: (_: {
|
|
91
|
+
a: number;
|
|
92
|
+
}) => X) => X extends Effect.Effect<infer A, infer E_1, infer R_3> ? Effect.Effect<A, E_1, R_3 | SomeService> : Effect.Effect<X, never, SomeService>;
|
|
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,
|
|
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,
|
|
1
|
+
{"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../fixtures.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAU,CAAC,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAC9D,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAEtF,OAAO,EAAc,UAAU,EAAE,MAAM,uBAAuB,CAAA;;;;;;;;;;;;;AAE9D,qBAAa,WAAY,SAAQ,gBAKhC;CACA;;;;;;;;;;;;;;;;;;;;;;;;;AAED,qBAAa,IAAK,SAAQ,SAA2D;CAAG;;;;;;;;;;;;;;;;;;;;;;;;;AACxF,qBAAa,QAAS,SAAQ,aAAmE;CAAG;;;;;;;;;;;;;;;;;;;;;;;;;AAEpG,qBAAa,WAAY,SAAQ,gBAAgE;CAAG;AAOpG,eAAO,MAAM,iBAAiB;;;;CAIpB,CAAA;AAEV,KAAK,kBAAkB,GAAG,OAAO,iBAAiB,CAAA;AAClD,MAAM,WAAW,iBAAkB,SAAQ,kBAAkB;CAAG;;;;;;;AAEhE,qBAAa,cAAe,SAAQ,mBA4BlC;CACD;;;;;;;;AAID,qBAAa,YAAa,SAAQ,iBA6BhC;CACD;;;;;;;AAGD,qBAAa,IAAK,SAAQ,SASxB;CAAG;;;;AAEL,qBAAa,YAAa,SAAQ,iBAAmD;CAAG;;;;AACxF,qBAAa,YAAa,SAAQ,iBAAmD;CAAG"}
|
package/test/dist/fixtures.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Context, Effect, Option, S, Scope } from "effect-app";
|
|
2
|
-
import { NotLoggedInError, UnauthorizedError } from "effect-app/client";
|
|
2
|
+
import { NotLoggedInError, RPCContextMap, UnauthorizedError } from "effect-app/client";
|
|
3
3
|
import { TaggedError } from "effect-app/Schema";
|
|
4
4
|
import { contextMap, Middleware } from "../src/api/routing.js";
|
|
5
5
|
export class UserProfile extends Context.assignTag("UserProfile")(S.Class("UserProfile")({
|
|
@@ -11,8 +11,21 @@ export class Some extends Context.TagMakeId("Some", Effect.succeed({ a: 1 }))()
|
|
|
11
11
|
}
|
|
12
12
|
export class SomeElse extends Context.TagMakeId("SomeElse", Effect.succeed({ b: 2 }))() {
|
|
13
13
|
}
|
|
14
|
+
const MakeSomeService = Effect.succeed({ a: 1 });
|
|
15
|
+
export class SomeService extends Context.TagMakeId("SomeService", MakeSomeService)() {
|
|
16
|
+
}
|
|
17
|
+
// TODO: null as never sucks
|
|
18
|
+
// why [UserProfile] is needed? AllowAnonymous triggers an error if just UserProfile without []
|
|
19
|
+
// [] requires return Context, non [] requires return the Service instance
|
|
20
|
+
//
|
|
21
|
+
// consider if we want to support Context of one Service
|
|
22
|
+
export const RequestContextMap = {
|
|
23
|
+
allowAnonymous: RPCContextMap.makeInverted([UserProfile], NotLoggedInError),
|
|
24
|
+
requireRoles: RPCContextMap.makeCustom(null, UnauthorizedError, Array()),
|
|
25
|
+
test: RPCContextMap.make(null, S.Never)
|
|
26
|
+
};
|
|
14
27
|
export class AllowAnonymous extends Middleware.Tag()("AllowAnonymous", {
|
|
15
|
-
dynamic: contextMap(
|
|
28
|
+
dynamic: contextMap(RequestContextMap, "allowAnonymous"),
|
|
16
29
|
requires: SomeElse
|
|
17
30
|
})({
|
|
18
31
|
effect: Effect.gen(function* () {
|
|
@@ -34,9 +47,10 @@ export class AllowAnonymous extends Middleware.Tag()("AllowAnonymous", {
|
|
|
34
47
|
})
|
|
35
48
|
}) {
|
|
36
49
|
}
|
|
50
|
+
// TODO: don't expect service when it's wrap
|
|
37
51
|
// @effect-diagnostics-next-line missingEffectServiceDependency:off
|
|
38
52
|
export class RequireRoles extends Middleware.Tag()("RequireRoles", {
|
|
39
|
-
dynamic: contextMap(
|
|
53
|
+
dynamic: contextMap(RequestContextMap, "requireRoles"),
|
|
40
54
|
wrap: true,
|
|
41
55
|
// wrap: true,
|
|
42
56
|
// had to move this in here, because once you put it manually as a readonly static property on the class,
|
|
@@ -44,7 +58,7 @@ export class RequireRoles extends Middleware.Tag()("RequireRoles", {
|
|
|
44
58
|
dependsOn: [AllowAnonymous]
|
|
45
59
|
})({
|
|
46
60
|
effect: Effect.gen(function* () {
|
|
47
|
-
yield*
|
|
61
|
+
yield* SomeService;
|
|
48
62
|
return Effect.fnUntraced(function* ({ config, next }) {
|
|
49
63
|
// we don't know if the service will be provided or not, so we use option..
|
|
50
64
|
const userProfile = yield* Effect.serviceOption(UserProfile);
|
|
@@ -61,9 +75,10 @@ export class RequireRoles extends Middleware.Tag()("RequireRoles", {
|
|
|
61
75
|
})
|
|
62
76
|
}) {
|
|
63
77
|
}
|
|
78
|
+
// TODO: don't expect service when it's wrap
|
|
64
79
|
export class Test extends Middleware.Tag()("Test", {
|
|
65
80
|
wrap: true,
|
|
66
|
-
dynamic: contextMap(
|
|
81
|
+
dynamic: contextMap(RequestContextMap, "test")
|
|
67
82
|
})({
|
|
68
83
|
effect: Effect.gen(function* () {
|
|
69
84
|
return Effect.fn(function* ({ next }) {
|
|
@@ -76,7 +91,4 @@ export class CustomError1 extends TaggedError()("CustomError1", {}) {
|
|
|
76
91
|
}
|
|
77
92
|
export class CustomError2 extends TaggedError()("CustomError1", {}) {
|
|
78
93
|
}
|
|
79
|
-
|
|
80
|
-
export class SomeService extends Context.TagMakeId("SomeService", MakeSomeService)() {
|
|
81
|
-
}
|
|
82
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZml4dHVyZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9maXh0dXJlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxNQUFNLFlBQVksQ0FBQTtBQUM5RCxPQUFPLEVBQUUsZ0JBQWdCLEVBQXNCLGlCQUFpQixFQUFFLE1BQU0sbUJBQW1CLENBQUE7QUFDM0YsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLG1CQUFtQixDQUFBO0FBQy9DLE9BQU8sRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLE1BQU0sdUJBQXVCLENBQUE7QUFFOUQsTUFBTSxPQUFPLFdBQVksU0FBUSxPQUFPLENBQUMsU0FBUyxDQUEyQixhQUFhLENBQUMsQ0FDekYsQ0FBQyxDQUFDLEtBQUssQ0FBYyxhQUFhLENBQUMsQ0FBQztJQUNsQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLE1BQU07SUFDWixLQUFLLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDO0NBQ3pCLENBQUMsQ0FDSDtDQUNBO0FBRUQsTUFBTSxPQUFPLElBQUssU0FBUSxPQUFPLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBUTtDQUFHO0FBQ3hGLE1BQU0sT0FBTyxRQUFTLFNBQVEsT0FBTyxDQUFDLFNBQVMsQ0FBQyxVQUFVLEVBQUUsTUFBTSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQVk7Q0FBRztBQVFwRyxNQUFNLE9BQU8sY0FBZSxTQUFRLFVBQVUsQ0FBQyxHQUFHLEVBQWtCLENBQUMsZ0JBQWdCLEVBQUU7SUFDckYsT0FBTyxFQUFFLFVBQVUsRUFBcUIsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLFdBQVcs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
|
|
94
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZml4dHVyZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9maXh0dXJlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxNQUFNLFlBQVksQ0FBQTtBQUM5RCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsYUFBYSxFQUFFLGlCQUFpQixFQUFFLE1BQU0sbUJBQW1CLENBQUE7QUFDdEYsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLG1CQUFtQixDQUFBO0FBQy9DLE9BQU8sRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLE1BQU0sdUJBQXVCLENBQUE7QUFFOUQsTUFBTSxPQUFPLFdBQVksU0FBUSxPQUFPLENBQUMsU0FBUyxDQUEyQixhQUFhLENBQUMsQ0FDekYsQ0FBQyxDQUFDLEtBQUssQ0FBYyxhQUFhLENBQUMsQ0FBQztJQUNsQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLE1BQU07SUFDWixLQUFLLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDO0NBQ3pCLENBQUMsQ0FDSDtDQUNBO0FBRUQsTUFBTSxPQUFPLElBQUssU0FBUSxPQUFPLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBUTtDQUFHO0FBQ3hGLE1BQU0sT0FBTyxRQUFTLFNBQVEsT0FBTyxDQUFDLFNBQVMsQ0FBQyxVQUFVLEVBQUUsTUFBTSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQVk7Q0FBRztBQUNwRyxNQUFNLGVBQWUsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUE7QUFDaEQsTUFBTSxPQUFPLFdBQVksU0FBUSxPQUFPLENB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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"requires.test.d.ts","sourceRoot":"","sources":["../requires.test.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,KAAK,EAAK,MAAM,YAAY,CAAA;AAErD,OAAO,EAAkB,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAClE,OAAO,
|
|
1
|
+
{"version":3,"file":"requires.test.d.ts","sourceRoot":"","sources":["../requires.test.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,KAAK,EAAK,MAAM,YAAY,CAAA;AAErD,OAAO,EAAkB,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAClE,OAAO,EAAmD,IAAI,EAAE,QAAQ,EAAqB,MAAM,eAAe,CAAA;;;;;;AAElH,qBAAa,cAAe,SAAQ,mBAUlC;CACD;;;;;;;AAGD,qBAAa,kBAAmB,SAAQ,uBAQtC;CACD;;;;;;;AAED,qBAAa,kBAAmB,SAAQ,uBAYtC;CACD;;;;;;;AAED,qBAAa,sBAAuB,SAAQ,2BAa1C;CACD"}
|
package/test/fixtures.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Context, Effect, Option, S, Scope } from "effect-app"
|
|
2
|
-
import { NotLoggedInError,
|
|
2
|
+
import { NotLoggedInError, RPCContextMap, UnauthorizedError } from "effect-app/client"
|
|
3
3
|
import { TaggedError } from "effect-app/Schema"
|
|
4
4
|
import { contextMap, Middleware } from "../src/api/routing.js"
|
|
5
5
|
|
|
@@ -13,15 +13,25 @@ export class UserProfile extends Context.assignTag<UserProfile, UserProfile>("Us
|
|
|
13
13
|
|
|
14
14
|
export class Some extends Context.TagMakeId("Some", Effect.succeed({ a: 1 }))<Some>() {}
|
|
15
15
|
export class SomeElse extends Context.TagMakeId("SomeElse", Effect.succeed({ b: 2 }))<SomeElse>() {}
|
|
16
|
+
const MakeSomeService = Effect.succeed({ a: 1 })
|
|
17
|
+
export class SomeService extends Context.TagMakeId("SomeService", MakeSomeService)<SomeService>() {}
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
// TODO: null as never sucks
|
|
20
|
+
// why [UserProfile] is needed? AllowAnonymous triggers an error if just UserProfile without []
|
|
21
|
+
// [] requires return Context, non [] requires return the Service instance
|
|
22
|
+
//
|
|
23
|
+
// consider if we want to support Context of one Service
|
|
24
|
+
export const RequestContextMap = {
|
|
25
|
+
allowAnonymous: RPCContextMap.makeInverted([UserProfile], NotLoggedInError),
|
|
26
|
+
requireRoles: RPCContextMap.makeCustom(null as never, UnauthorizedError, Array<string>()),
|
|
27
|
+
test: RPCContextMap.make(null as never, S.Never)
|
|
28
|
+
} as const
|
|
29
|
+
|
|
30
|
+
type _RequestContextMap = typeof RequestContextMap
|
|
31
|
+
export interface RequestContextMap extends _RequestContextMap {}
|
|
22
32
|
|
|
23
33
|
export class AllowAnonymous extends Middleware.Tag<AllowAnonymous>()("AllowAnonymous", {
|
|
24
|
-
dynamic: contextMap
|
|
34
|
+
dynamic: contextMap(RequestContextMap, "allowAnonymous"),
|
|
25
35
|
requires: SomeElse
|
|
26
36
|
})({
|
|
27
37
|
effect: Effect.gen(function*() {
|
|
@@ -51,9 +61,10 @@ export class AllowAnonymous extends Middleware.Tag<AllowAnonymous>()("AllowAnony
|
|
|
51
61
|
}) {
|
|
52
62
|
}
|
|
53
63
|
|
|
64
|
+
// TODO: don't expect service when it's wrap
|
|
54
65
|
// @effect-diagnostics-next-line missingEffectServiceDependency:off
|
|
55
66
|
export class RequireRoles extends Middleware.Tag<RequireRoles>()("RequireRoles", {
|
|
56
|
-
dynamic: contextMap
|
|
67
|
+
dynamic: contextMap(RequestContextMap, "requireRoles"),
|
|
57
68
|
wrap: true,
|
|
58
69
|
// wrap: true,
|
|
59
70
|
// had to move this in here, because once you put it manually as a readonly static property on the class,
|
|
@@ -61,7 +72,7 @@ export class RequireRoles extends Middleware.Tag<RequireRoles>()("RequireRoles",
|
|
|
61
72
|
dependsOn: [AllowAnonymous]
|
|
62
73
|
})({
|
|
63
74
|
effect: Effect.gen(function*() {
|
|
64
|
-
yield*
|
|
75
|
+
yield* SomeService
|
|
65
76
|
return Effect.fnUntraced(
|
|
66
77
|
function*({ config, next }) {
|
|
67
78
|
// we don't know if the service will be provided or not, so we use option..
|
|
@@ -84,9 +95,10 @@ export class RequireRoles extends Middleware.Tag<RequireRoles>()("RequireRoles",
|
|
|
84
95
|
}) {
|
|
85
96
|
}
|
|
86
97
|
|
|
98
|
+
// TODO: don't expect service when it's wrap
|
|
87
99
|
export class Test extends Middleware.Tag<Test>()("Test", {
|
|
88
100
|
wrap: true,
|
|
89
|
-
dynamic: contextMap
|
|
101
|
+
dynamic: contextMap(RequestContextMap, "test")
|
|
90
102
|
})({
|
|
91
103
|
effect: Effect.gen(function*() {
|
|
92
104
|
return Effect.fn(function*({ next }) {
|
|
@@ -97,6 +109,3 @@ export class Test extends Middleware.Tag<Test>()("Test", {
|
|
|
97
109
|
|
|
98
110
|
export class CustomError1 extends TaggedError<NotLoggedInError>()("CustomError1", {}) {}
|
|
99
111
|
export class CustomError2 extends TaggedError<NotLoggedInError>()("CustomError1", {}) {}
|
|
100
|
-
|
|
101
|
-
const MakeSomeService = Effect.succeed({ a: 1 })
|
|
102
|
-
export class SomeService extends Context.TagMakeId("SomeService", MakeSomeService)<SomeService>() {}
|
package/test/layerUtils.test.ts
CHANGED
package/test/requires.test.ts
CHANGED
|
@@ -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,
|
|
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
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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
|
-
|
|
70
|
+
const _middlewareSideways = makeMiddleware(RequestContextMap)
|
|
71
|
+
.middleware(RequiresSomeMiddleware)
|
|
72
|
+
.middleware(SomeMiddleware)
|
|
73
|
+
.middleware(RequireRoles, AllowAnonymous, Test)
|
|
74
|
+
.middleware(SomeElseMiddleware)
|
|
60
75
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
expectTypeOf({} as LayerContext).toEqualTypeOf<Some>()
|
|
76
|
+
const _middlewareSidewaysFully = makeMiddleware(RequestContextMap)
|
|
77
|
+
.middleware(RequiresSomeMiddleware, SomeMiddleware, RequireRoles, AllowAnonymous, Test, SomeElseMiddleware)
|
|
64
78
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
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
|
-
|
|
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
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
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
|
-
|
|
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
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
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
|
-
|
|
170
|
+
.toEqual(Either.left(new UnauthorizedError({ message: "don't have the right roles" })))
|
|
147
171
|
})
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
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)
|