@effect-app/infra 2.94.0 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/dist/Emailer/service.d.ts +1 -1
- package/dist/MainFiberSet.d.ts +1 -1
- package/dist/Operations.d.ts +1 -1
- package/dist/QueueMaker/errors.d.ts +1 -1
- package/dist/QueueMaker/errors.d.ts.map +1 -1
- package/dist/RequestFiberSet.d.ts +1 -1
- package/dist/Store/service.d.ts +2 -2
- package/dist/adapters/SQL/Model.d.ts +6 -6
- package/dist/adapters/ServiceBus.d.ts +2 -2
- package/dist/adapters/ServiceBus.d.ts.map +1 -1
- package/dist/adapters/ServiceBus.js +13 -10
- package/dist/adapters/memQueue.d.ts +1 -1
- package/dist/api/routing/middleware/RouterMiddleware.d.ts +7 -7
- package/dist/api/routing/middleware/RouterMiddleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/middleware.d.ts +6 -27
- package/dist/api/routing/middleware/middleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/middleware.js +72 -88
- package/dist/api/routing/middleware.d.ts +0 -3
- package/dist/api/routing/middleware.d.ts.map +1 -1
- package/dist/api/routing/middleware.js +1 -4
- package/dist/api/routing.d.ts +1 -2
- package/dist/api/routing.d.ts.map +1 -1
- package/dist/api/routing.js +2 -8
- package/package.json +3 -15
- package/src/adapters/ServiceBus.ts +7 -5
- package/src/api/routing/middleware/RouterMiddleware.ts +10 -9
- package/src/api/routing/middleware/middleware.ts +35 -40
- package/src/api/routing/middleware.ts +0 -3
- package/src/api/routing.ts +3 -9
- package/test/controller.test.ts +33 -9
- package/test/dist/controller.test.d.ts.map +1 -1
- package/test/dist/fixtures.d.ts +48 -32
- package/test/dist/fixtures.d.ts.map +1 -1
- package/test/dist/fixtures.js +76 -47
- package/test/dist/requires.test.d.ts.map +1 -1
- package/test/dist/rpc-multi-middleware.test.d.ts.map +1 -0
- package/test/fixtures.ts +70 -16
- package/test/requires.test.ts +16 -51
- package/test/rpc-multi-middleware.test.ts +134 -0
- package/dist/api/routing/middleware/RpcMiddleware.d.ts +0 -199
- package/dist/api/routing/middleware/RpcMiddleware.d.ts.map +0 -1
- package/dist/api/routing/middleware/RpcMiddleware.js +0 -14
- package/dist/api/routing/middleware/generic-middleware.d.ts +0 -41
- package/dist/api/routing/middleware/generic-middleware.d.ts.map +0 -1
- package/dist/api/routing/middleware/generic-middleware.js +0 -70
- package/dist/api/routing/middleware/middleware-api.d.ts +0 -88
- package/dist/api/routing/middleware/middleware-api.d.ts.map +0 -1
- package/dist/api/routing/middleware/middleware-api.js +0 -58
- package/src/api/routing/middleware/RpcMiddleware.ts +0 -301
- package/src/api/routing/middleware/generic-middleware.ts +0 -163
- package/src/api/routing/middleware/middleware-api.ts +0 -226
package/test/dist/fixtures.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { Context, Effect, S, Scope } from "effect-app";
|
|
1
|
+
import { Context, Effect, Layer, S, Scope } from "effect-app";
|
|
2
2
|
import { NotLoggedInError, RPCContextMap, UnauthorizedError } from "effect-app/client";
|
|
3
|
-
import { Middleware } from "../src/api/routing.js";
|
|
4
3
|
declare const UserProfile_base: S.EnhancedClass<UserProfile, {
|
|
5
4
|
id: typeof S.String;
|
|
6
5
|
roles: S.Array$<typeof S.String> & {
|
|
@@ -23,12 +22,12 @@ declare const Some_base: (abstract new (service: {
|
|
|
23
22
|
a: number;
|
|
24
23
|
}>) & {
|
|
25
24
|
toLayer: {
|
|
26
|
-
():
|
|
27
|
-
<E_1, R_1>(eff: Effect.Effect<Omit<Some, keyof Context.TagClassShape<any, any>>, E_1, R_1>):
|
|
25
|
+
(): Layer.Layer<Some, never, never>;
|
|
26
|
+
<E_1, R_1>(eff: Effect.Effect<Omit<Some, keyof Context.TagClassShape<any, any>>, E_1, R_1>): Layer.Layer<Some, E_1, R_1>;
|
|
28
27
|
};
|
|
29
28
|
toLayerScoped: {
|
|
30
|
-
():
|
|
31
|
-
<E_1, R_2>(eff: Effect.Effect<Omit<Some, keyof Context.TagClassShape<any, any>>, E_1, R_2>):
|
|
29
|
+
(): Layer.Layer<Some, never, never>;
|
|
30
|
+
<E_1, R_2>(eff: Effect.Effect<Omit<Some, keyof Context.TagClassShape<any, any>>, E_1, R_2>): Layer.Layer<Some, E_1, Exclude<R_2, Scope.Scope>>;
|
|
32
31
|
};
|
|
33
32
|
of: (service: Context.TagClassShape<any, any>) => Some;
|
|
34
33
|
make: Effect.Effect<Some, never, never>;
|
|
@@ -37,7 +36,7 @@ declare const Some_base: (abstract new (service: {
|
|
|
37
36
|
} & {
|
|
38
37
|
use: <X>(body: (_: {
|
|
39
38
|
a: number;
|
|
40
|
-
}) => X) => X extends Effect.Effect<infer
|
|
39
|
+
}) => X) => X extends Effect.Effect<infer A_1, infer E_2, infer R_4> ? Effect.Effect<A_1, E_2, Some | R_4> : Effect.Effect<X, never, Some>;
|
|
41
40
|
};
|
|
42
41
|
export declare class Some extends Some_base {
|
|
43
42
|
}
|
|
@@ -49,12 +48,12 @@ declare const SomeElse_base: (abstract new (service: {
|
|
|
49
48
|
b: number;
|
|
50
49
|
}>) & {
|
|
51
50
|
toLayer: {
|
|
52
|
-
():
|
|
53
|
-
<E_1, R_1>(eff: Effect.Effect<Omit<SomeElse, keyof Context.TagClassShape<any, any>>, E_1, R_1>):
|
|
51
|
+
(): Layer.Layer<SomeElse, never, never>;
|
|
52
|
+
<E_1, R_1>(eff: Effect.Effect<Omit<SomeElse, keyof Context.TagClassShape<any, any>>, E_1, R_1>): Layer.Layer<SomeElse, E_1, R_1>;
|
|
54
53
|
};
|
|
55
54
|
toLayerScoped: {
|
|
56
|
-
():
|
|
57
|
-
<E_1, R_2>(eff: Effect.Effect<Omit<SomeElse, keyof Context.TagClassShape<any, any>>, E_1, R_2>):
|
|
55
|
+
(): Layer.Layer<SomeElse, never, never>;
|
|
56
|
+
<E_1, R_2>(eff: Effect.Effect<Omit<SomeElse, keyof Context.TagClassShape<any, any>>, E_1, R_2>): Layer.Layer<SomeElse, E_1, Exclude<R_2, Scope.Scope>>;
|
|
58
57
|
};
|
|
59
58
|
of: (service: Context.TagClassShape<any, any>) => SomeElse;
|
|
60
59
|
make: Effect.Effect<SomeElse, never, never>;
|
|
@@ -63,7 +62,7 @@ declare const SomeElse_base: (abstract new (service: {
|
|
|
63
62
|
} & {
|
|
64
63
|
use: <X>(body: (_: {
|
|
65
64
|
b: number;
|
|
66
|
-
}) => X) => X extends Effect.Effect<infer
|
|
65
|
+
}) => X) => X extends Effect.Effect<infer A_1, infer E_2, infer R_4> ? Effect.Effect<A_1, E_2, R_4 | SomeElse> : Effect.Effect<X, never, SomeElse>;
|
|
67
66
|
};
|
|
68
67
|
export declare class SomeElse extends SomeElse_base {
|
|
69
68
|
}
|
|
@@ -75,12 +74,12 @@ declare const SomeService_base: (abstract new (service: {
|
|
|
75
74
|
a: number;
|
|
76
75
|
}>) & {
|
|
77
76
|
toLayer: {
|
|
78
|
-
():
|
|
79
|
-
<E_1, R_1>(eff: Effect.Effect<Omit<SomeService, keyof Context.TagClassShape<any, any>>, E_1, R_1>):
|
|
77
|
+
(): Layer.Layer<SomeService, never, never>;
|
|
78
|
+
<E_1, R_1>(eff: Effect.Effect<Omit<SomeService, keyof Context.TagClassShape<any, any>>, E_1, R_1>): Layer.Layer<SomeService, E_1, R_1>;
|
|
80
79
|
};
|
|
81
80
|
toLayerScoped: {
|
|
82
|
-
():
|
|
83
|
-
<E_1, R_2>(eff: Effect.Effect<Omit<SomeService, keyof Context.TagClassShape<any, any>>, E_1, R_2>):
|
|
81
|
+
(): Layer.Layer<SomeService, never, never>;
|
|
82
|
+
<E_1, R_2>(eff: Effect.Effect<Omit<SomeService, keyof Context.TagClassShape<any, any>>, E_1, R_2>): Layer.Layer<SomeService, E_1, Exclude<R_2, Scope.Scope>>;
|
|
84
83
|
};
|
|
85
84
|
of: (service: Context.TagClassShape<any, any>) => SomeService;
|
|
86
85
|
make: Effect.Effect<SomeService, never, never>;
|
|
@@ -89,10 +88,30 @@ declare const SomeService_base: (abstract new (service: {
|
|
|
89
88
|
} & {
|
|
90
89
|
use: <X>(body: (_: {
|
|
91
90
|
a: number;
|
|
92
|
-
}) => X) => X extends Effect.Effect<infer
|
|
91
|
+
}) => X) => X extends Effect.Effect<infer A_1, infer E_2, infer R_4> ? Effect.Effect<A_1, E_2, R_4 | SomeService> : Effect.Effect<X, never, SomeService>;
|
|
93
92
|
};
|
|
94
93
|
export declare class SomeService extends SomeService_base {
|
|
95
94
|
}
|
|
95
|
+
declare const SomeMiddleware_base: import("effect-app/rpc").TagClass<SomeMiddleware, "SomeMiddleware", {
|
|
96
|
+
readonly provides: typeof Some;
|
|
97
|
+
}>;
|
|
98
|
+
export declare class SomeMiddleware extends SomeMiddleware_base {
|
|
99
|
+
}
|
|
100
|
+
export declare const SomeMiddlewareLive: Layer.Layer<SomeMiddleware, never, never>;
|
|
101
|
+
declare const SomeMiddlewareWrap_base: import("effect-app/rpc").TagClass<SomeMiddlewareWrap, "SomeMiddlewareWrap", {
|
|
102
|
+
readonly provides: typeof Some;
|
|
103
|
+
readonly wrap: true;
|
|
104
|
+
}>;
|
|
105
|
+
export declare class SomeMiddlewareWrap extends SomeMiddlewareWrap_base {
|
|
106
|
+
}
|
|
107
|
+
export declare const SomeMiddlewareWrapLive: Layer.Layer<SomeMiddlewareWrap, never, never>;
|
|
108
|
+
declare const SomeElseMiddleware_base: import("effect-app/rpc").TagClass<SomeElseMiddleware, "SomeElseMiddleware", {
|
|
109
|
+
readonly provides: typeof SomeElse;
|
|
110
|
+
readonly wrap: true;
|
|
111
|
+
}>;
|
|
112
|
+
export declare class SomeElseMiddleware extends SomeElseMiddleware_base {
|
|
113
|
+
}
|
|
114
|
+
export declare const SomeElseMiddlewareLive: Layer.Layer<SomeElseMiddleware, never, never>;
|
|
96
115
|
export declare const RequestContextMap: {
|
|
97
116
|
readonly allowAnonymous: RPCContextMap.Inverted<[typeof UserProfile], typeof NotLoggedInError>;
|
|
98
117
|
readonly requireRoles: RPCContextMap.Custom<never, typeof UnauthorizedError, string[]>;
|
|
@@ -101,31 +120,28 @@ export declare const RequestContextMap: {
|
|
|
101
120
|
type _RequestContextMap = typeof RequestContextMap;
|
|
102
121
|
export interface RequestContextMap extends _RequestContextMap {
|
|
103
122
|
}
|
|
104
|
-
declare const AllowAnonymous_base:
|
|
105
|
-
readonly dynamic:
|
|
123
|
+
declare const AllowAnonymous_base: import("effect-app/rpc").TagClass<AllowAnonymous, "AllowAnonymous", {
|
|
124
|
+
readonly dynamic: import("effect-app/rpc").RpcDynamic<"allowAnonymous", RPCContextMap.Inverted<[typeof UserProfile], typeof NotLoggedInError>>;
|
|
106
125
|
readonly requires: typeof SomeElse;
|
|
107
|
-
}
|
|
108
|
-
Default: import("effect/Layer").Layer<AllowAnonymous, never, never>;
|
|
109
|
-
};
|
|
126
|
+
}>;
|
|
110
127
|
export declare class AllowAnonymous extends AllowAnonymous_base {
|
|
111
128
|
}
|
|
112
|
-
declare const
|
|
113
|
-
|
|
129
|
+
export declare const AllowAnonymousLive: Layer.Layer<AllowAnonymous, never, never>;
|
|
130
|
+
declare const RequireRoles_base: import("effect-app/rpc").TagClass<RequireRoles, "RequireRoles", {
|
|
131
|
+
readonly dynamic: import("effect-app/rpc").RpcDynamic<"requireRoles", RPCContextMap.Custom<never, typeof UnauthorizedError, string[]>>;
|
|
114
132
|
readonly wrap: true;
|
|
115
133
|
readonly dependsOn: readonly [typeof AllowAnonymous];
|
|
116
|
-
}
|
|
117
|
-
Default: import("effect/Layer").Layer<RequireRoles, never, SomeService>;
|
|
118
|
-
};
|
|
134
|
+
}>;
|
|
119
135
|
export declare class RequireRoles extends RequireRoles_base {
|
|
120
136
|
}
|
|
121
|
-
declare const
|
|
137
|
+
export declare const RequireRolesLive: Layer.Layer<RequireRoles, never, SomeService>;
|
|
138
|
+
declare const Test_base: import("effect-app/rpc").TagClass<Test, "Test", {
|
|
122
139
|
readonly wrap: true;
|
|
123
|
-
readonly dynamic:
|
|
124
|
-
}
|
|
125
|
-
Default: import("effect/Layer").Layer<Test, never, never>;
|
|
126
|
-
};
|
|
140
|
+
readonly dynamic: import("effect-app/rpc").RpcDynamic<"test", RPCContextMap.RPCContextMap<never, typeof S.Never>>;
|
|
141
|
+
}>;
|
|
127
142
|
export declare class Test extends Test_base {
|
|
128
143
|
}
|
|
144
|
+
export declare const TestLive: Layer.Layer<Test, never, never>;
|
|
129
145
|
declare const CustomError1_base: S.TaggedErrorClass<NotLoggedInError, "CustomError1", {
|
|
130
146
|
readonly _tag: S.tag<"CustomError1">;
|
|
131
147
|
}>;
|
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../fixtures.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAU,CAAC,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AACrE,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;;;;;;;;;;;;;AAItF,qBAAa,WAAY,SAAQ,gBAKhC;CACA;;;;;;;;;;;;;;;;;;;;;;;;;AAED,qBAAa,IAAK,SAAQ,SAA2D;CAAG;;;;;;;;;;;;;;;;;;;;;;;;;AACxF,qBAAa,QAAS,SAAQ,aAAmE;CAAG;;;;;;;;;;;;;;;;;;;;;;;;;AAEpG,qBAAa,WAAY,SAAQ,gBAAgE;CAAG;;;;AAEpG,qBAAa,cAAe,SAAQ,mBAElC;CAAG;AAEL,eAAO,MAAM,kBAAkB,2CAS9B,CAAA;;;;;AAGD,qBAAa,kBAAmB,SAAQ,uBAGtC;CACD;AAED,eAAO,MAAM,sBAAsB,+CAMlC,CAAA;;;;;AAED,qBAAa,kBAAmB,SAAQ,uBAGtC;CAAG;AAEL,eAAO,MAAM,sBAAsB,+CAUlC,CAAA;AASD,eAAO,MAAM,iBAAiB;;;;CAIpB,CAAA;AAEV,KAAK,kBAAkB,GAAG,OAAO,iBAAiB,CAAA;AAClD,MAAM,WAAW,iBAAkB,SAAQ,kBAAkB;CAAG;;;;;AAEhE,qBAAa,cAAe,SAAQ,mBAGlC;CAAG;AAEL,eAAO,MAAM,kBAAkB,2CA0B9B,CAAA;;;;;;AAID,qBAAa,YAAa,SAAQ,iBAOhC;CAAG;AAEL,eAAO,MAAM,gBAAgB,+CAuB5B,CAAA;;;;;AAGD,qBAAa,IAAK,SAAQ,SAGxB;CAAG;AAEL,eAAO,MAAM,QAAQ,iCAOpB,CAAA;;;;AAED,qBAAa,YAAa,SAAQ,iBAAmD;CAAG;;;;AACxF,qBAAa,YAAa,SAAQ,iBAAmD;CAAG"}
|
package/test/dist/fixtures.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Context, Effect, Option, S, Scope } from "effect-app";
|
|
1
|
+
import { Context, Effect, Layer, Option, S, Scope } from "effect-app";
|
|
2
2
|
import { NotLoggedInError, RPCContextMap, UnauthorizedError } from "effect-app/client";
|
|
3
|
+
import { contextMap, getConfig, Tag } from "effect-app/rpc";
|
|
3
4
|
import { TaggedError } from "effect-app/Schema";
|
|
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)
|
|
@@ -14,6 +14,38 @@ export class SomeElse extends Context.TagMakeId("SomeElse", Effect.succeed({ b:
|
|
|
14
14
|
const MakeSomeService = Effect.succeed({ a: 1 });
|
|
15
15
|
export class SomeService extends Context.TagMakeId("SomeService", MakeSomeService)() {
|
|
16
16
|
}
|
|
17
|
+
export class SomeMiddleware extends Tag()("SomeMiddleware", {
|
|
18
|
+
provides: Some
|
|
19
|
+
}) {
|
|
20
|
+
}
|
|
21
|
+
export const SomeMiddlewareLive = Layer.effect(SomeMiddleware, Effect.gen(function* () {
|
|
22
|
+
// yield* Effect.context<"test-dep">()
|
|
23
|
+
return () => Effect.gen(function* () {
|
|
24
|
+
return new Some({ a: 1 });
|
|
25
|
+
});
|
|
26
|
+
}));
|
|
27
|
+
// functionally equivalent to the one above
|
|
28
|
+
export class SomeMiddlewareWrap extends Tag()("SomeMiddlewareWrap", {
|
|
29
|
+
provides: Some,
|
|
30
|
+
wrap: true
|
|
31
|
+
}) {
|
|
32
|
+
}
|
|
33
|
+
export const SomeMiddlewareWrapLive = Layer.effect(SomeMiddlewareWrap, Effect.gen(function* () {
|
|
34
|
+
// yield* Effect.context<"test-dep">()
|
|
35
|
+
return ({ next }) => next.pipe(Effect.provideService(Some, new Some({ a: 1 })));
|
|
36
|
+
}));
|
|
37
|
+
export class SomeElseMiddleware extends Tag()("SomeElseMiddleware", {
|
|
38
|
+
provides: SomeElse,
|
|
39
|
+
wrap: true
|
|
40
|
+
}) {
|
|
41
|
+
}
|
|
42
|
+
export const SomeElseMiddlewareLive = Layer.effect(SomeElseMiddleware, Effect.gen(function* () {
|
|
43
|
+
// yield* Effect.context<"test-dep">()
|
|
44
|
+
return ({ next }) => Effect.gen(function* () {
|
|
45
|
+
// yield* Effect.context<"test-dep2">()
|
|
46
|
+
return yield* next.pipe(Effect.provideService(SomeElse, new SomeElse({ b: 2 })));
|
|
47
|
+
});
|
|
48
|
+
}));
|
|
17
49
|
const requestConfig = getConfig();
|
|
18
50
|
// TODO: null as never sucks
|
|
19
51
|
// why [UserProfile] is needed? AllowAnonymous triggers an error if just UserProfile without []
|
|
@@ -25,71 +57,68 @@ export const RequestContextMap = {
|
|
|
25
57
|
requireRoles: RPCContextMap.makeCustom(null, UnauthorizedError, Array()),
|
|
26
58
|
test: RPCContextMap.make(null, S.Never)
|
|
27
59
|
};
|
|
28
|
-
export class AllowAnonymous extends
|
|
60
|
+
export class AllowAnonymous extends Tag()("AllowAnonymous", {
|
|
29
61
|
dynamic: contextMap(RequestContextMap, "allowAnonymous"),
|
|
30
62
|
requires: SomeElse
|
|
31
|
-
})({
|
|
32
|
-
effect: Effect.gen(function* () {
|
|
33
|
-
return Effect.fnUntraced(function* ({ headers, rpc }) {
|
|
34
|
-
yield* SomeElse;
|
|
35
|
-
yield* Scope.Scope; // provided by HttpLayerRouter.Provided
|
|
36
|
-
const isLoggedIn = !!headers["x-user"];
|
|
37
|
-
if (!isLoggedIn) {
|
|
38
|
-
if (!requestConfig(rpc).allowAnonymous) {
|
|
39
|
-
return yield* new NotLoggedInError({ message: "Not logged in" });
|
|
40
|
-
}
|
|
41
|
-
return Option.none();
|
|
42
|
-
}
|
|
43
|
-
return Option.some(Context.make(UserProfile, new UserProfile({
|
|
44
|
-
id: "whatever",
|
|
45
|
-
roles: ["user", ...headers["x-is-manager"] === "true" ? ["manager"] : []]
|
|
46
|
-
})));
|
|
47
|
-
});
|
|
48
|
-
})
|
|
49
63
|
}) {
|
|
50
64
|
}
|
|
65
|
+
export const AllowAnonymousLive = Layer.effect(AllowAnonymous, Effect.gen(function* () {
|
|
66
|
+
return Effect.fnUntraced(function* ({ headers, rpc }) {
|
|
67
|
+
yield* SomeElse;
|
|
68
|
+
yield* Scope.Scope; // provided by HttpLayerRouter.Provided
|
|
69
|
+
const isLoggedIn = !!headers["x-user"];
|
|
70
|
+
if (!isLoggedIn) {
|
|
71
|
+
if (!requestConfig(rpc).allowAnonymous) {
|
|
72
|
+
return yield* new NotLoggedInError({ message: "Not logged in" });
|
|
73
|
+
}
|
|
74
|
+
return Option.none();
|
|
75
|
+
}
|
|
76
|
+
return Option.some(Context.make(UserProfile, new UserProfile({
|
|
77
|
+
id: "whatever",
|
|
78
|
+
roles: ["user", ...headers["x-is-manager"] === "true" ? ["manager"] : []]
|
|
79
|
+
})));
|
|
80
|
+
});
|
|
81
|
+
}));
|
|
51
82
|
// TODO: don't expect service when it's wrap
|
|
52
83
|
// @effect-diagnostics-next-line missingEffectServiceDependency:off
|
|
53
|
-
export class RequireRoles extends
|
|
84
|
+
export class RequireRoles extends Tag()("RequireRoles", {
|
|
54
85
|
dynamic: contextMap(RequestContextMap, "requireRoles"),
|
|
55
86
|
wrap: true,
|
|
56
87
|
// wrap: true,
|
|
57
88
|
// had to move this in here, because once you put it manually as a readonly static property on the class,
|
|
58
89
|
// there's a weird issue where the fluent api stops behaving properly after adding this middleware via `addDynamicMiddleware`
|
|
59
90
|
dependsOn: [AllowAnonymous]
|
|
60
|
-
})({
|
|
61
|
-
effect: Effect.gen(function* () {
|
|
62
|
-
yield* SomeService;
|
|
63
|
-
return Effect.fnUntraced(function* ({ next, rpc }) {
|
|
64
|
-
// we don't know if the service will be provided or not, so we use option..
|
|
65
|
-
const userProfile = yield* Effect.serviceOption(UserProfile);
|
|
66
|
-
const { requireRoles } = requestConfig(rpc);
|
|
67
|
-
console.dir({
|
|
68
|
-
userProfile,
|
|
69
|
-
requireRoles
|
|
70
|
-
}, { depth: 5 });
|
|
71
|
-
if (requireRoles && !userProfile.value?.roles?.some((role) => requireRoles.includes(role))) {
|
|
72
|
-
return yield* new UnauthorizedError({ message: "don't have the right roles" });
|
|
73
|
-
}
|
|
74
|
-
return yield* next;
|
|
75
|
-
});
|
|
76
|
-
})
|
|
77
91
|
}) {
|
|
78
92
|
}
|
|
93
|
+
export const RequireRolesLive = Layer.effect(RequireRoles, Effect.gen(function* () {
|
|
94
|
+
yield* SomeService;
|
|
95
|
+
return Effect.fnUntraced(function* ({ next, rpc }) {
|
|
96
|
+
// we don't know if the service will be provided or not, so we use option..
|
|
97
|
+
const userProfile = yield* Effect.serviceOption(UserProfile);
|
|
98
|
+
const { requireRoles } = requestConfig(rpc);
|
|
99
|
+
console.dir({
|
|
100
|
+
userProfile,
|
|
101
|
+
requireRoles
|
|
102
|
+
}, { depth: 5 });
|
|
103
|
+
if (requireRoles && !userProfile.value?.roles?.some((role) => requireRoles.includes(role))) {
|
|
104
|
+
return yield* new UnauthorizedError({ message: "don't have the right roles" });
|
|
105
|
+
}
|
|
106
|
+
return yield* next;
|
|
107
|
+
});
|
|
108
|
+
}));
|
|
79
109
|
// TODO: don't expect service when it's wrap
|
|
80
|
-
export class Test extends
|
|
110
|
+
export class Test extends Tag()("Test", {
|
|
81
111
|
wrap: true,
|
|
82
112
|
dynamic: contextMap(RequestContextMap, "test")
|
|
83
|
-
})({
|
|
84
|
-
effect: Effect.gen(function* () {
|
|
85
|
-
return Effect.fn(function* ({ next }) {
|
|
86
|
-
return yield* next;
|
|
87
|
-
});
|
|
88
|
-
})
|
|
89
113
|
}) {
|
|
90
114
|
}
|
|
115
|
+
export const TestLive = Layer.effect(Test, Effect.gen(function* () {
|
|
116
|
+
return Effect.fn(function* ({ next }) {
|
|
117
|
+
return yield* next;
|
|
118
|
+
});
|
|
119
|
+
}));
|
|
91
120
|
export class CustomError1 extends TaggedError()("CustomError1", {}) {
|
|
92
121
|
}
|
|
93
122
|
export class CustomError2 extends TaggedError()("CustomError1", {}) {
|
|
94
123
|
}
|
|
95
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
124
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZml4dHVyZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9maXh0dXJlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsTUFBTSxZQUFZLENBQUE7QUFDckUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLGFBQWEsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG1CQUFtQixDQUFBO0FBQ3RGLE9BQU8sRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFBO0FBQzNELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQTtBQUUvQyxNQUFNLE9BQU8sV0FBWSxTQUFRLE9BQU8sQ0FBQyxTQUFTLENBQTJCLGFBQWEsQ0FBQyxDQUN6RixDQUFDLENBQUMsS0FBSyxDQUFjLGFBQWEsQ0FBQyxDQUFDO0lBQ2xDLEVBQUUsRUFBRSxDQUFDLENBQUMsTUFBTTtJQUNaLEtBQUssRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7Q0FDekIsQ0FBQyxDQUNIO0NBQ0E7QUFFRCxNQUFNLE9BQU8sSUFBSyxTQUFRLE9BQU8sQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFRO0NBQUc7QUFDeEYsTUFBTSxPQUFPLFFBQVMsU0FBUSxPQUFPLENBQUMsU0FBUyxDQUFDLFVBQVUsRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBWTtDQUFHO0FBQ3BHLE1BQU0sZUFBZSxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQTtBQUNoRCxNQUFNLE9B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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"requires.test.d.ts","sourceRoot":"","sources":["../requires.test.ts"],"names":[],"mappings":"AAGA,OAAO,EAA2B,KAAK,
|
|
1
|
+
{"version":3,"file":"requires.test.d.ts","sourceRoot":"","sources":["../requires.test.ts"],"names":[],"mappings":"AAGA,OAAO,EAA2B,KAAK,EAAE,CAAC,EAAE,MAAM,YAAY,CAAA;AAC9D,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAGvE,OAAO,EAAE,cAAc,EAAyC,YAAY,EAAoB,IAAI,EAAE,kBAAkB,EAA8D,kBAAkB,EAAe,IAAI,EAAY,MAAM,eAAe,CAAA;;;;;;;AAE5P,qBAAa,sBAAuB,SAAQ,2BAa1C;CACD;AAkBD,eAAO,MAAM,eAAe;;;;;;;;;;SAKK,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpc-multi-middleware.test.d.ts","sourceRoot":"","sources":["../rpc-multi-middleware.test.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAkD,MAAM,aAAa,CAAA;AAEvF,OAAO,EAA2B,KAAK,EAAE,MAAM,QAAQ,CAAA;AAOvD,OAAO,EAAoN,WAAW,EAAE,MAAM,eAAe,CAAA;AA8C7P,eAAO,MAAM,OAAO,uFAWO,CAAA;AAiB3B,eAAO,MAAM,YAAY,yKAItB,CAAA;AAEH,eAAO,MAAM,YAAY,+FAgByB,CAAA"}
|
package/test/fixtures.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Context, Effect, Option, S, Scope } from "effect-app"
|
|
1
|
+
import { Context, Effect, Layer, Option, S, Scope } from "effect-app"
|
|
2
2
|
import { NotLoggedInError, RPCContextMap, UnauthorizedError } from "effect-app/client"
|
|
3
|
+
import { contextMap, getConfig, Tag } from "effect-app/rpc"
|
|
3
4
|
import { TaggedError } from "effect-app/Schema"
|
|
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")({
|
|
@@ -16,6 +16,53 @@ export class SomeElse extends Context.TagMakeId("SomeElse", Effect.succeed({ b:
|
|
|
16
16
|
const MakeSomeService = Effect.succeed({ a: 1 })
|
|
17
17
|
export class SomeService extends Context.TagMakeId("SomeService", MakeSomeService)<SomeService>() {}
|
|
18
18
|
|
|
19
|
+
export class SomeMiddleware extends Tag<SomeMiddleware>()("SomeMiddleware", {
|
|
20
|
+
provides: Some
|
|
21
|
+
}) {}
|
|
22
|
+
|
|
23
|
+
export const SomeMiddlewareLive = Layer.effect(
|
|
24
|
+
SomeMiddleware,
|
|
25
|
+
Effect.gen(function*() {
|
|
26
|
+
// yield* Effect.context<"test-dep">()
|
|
27
|
+
return () =>
|
|
28
|
+
Effect.gen(function*() {
|
|
29
|
+
return new Some({ a: 1 })
|
|
30
|
+
})
|
|
31
|
+
})
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
// functionally equivalent to the one above
|
|
35
|
+
export class SomeMiddlewareWrap extends Tag<SomeMiddlewareWrap>()("SomeMiddlewareWrap", {
|
|
36
|
+
provides: Some,
|
|
37
|
+
wrap: true
|
|
38
|
+
}) {
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export const SomeMiddlewareWrapLive = Layer.effect(
|
|
42
|
+
SomeMiddlewareWrap,
|
|
43
|
+
Effect.gen(function*() {
|
|
44
|
+
// yield* Effect.context<"test-dep">()
|
|
45
|
+
return ({ next }) => next.pipe(Effect.provideService(Some, new Some({ a: 1 })))
|
|
46
|
+
})
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
export class SomeElseMiddleware extends Tag<SomeElseMiddleware>()("SomeElseMiddleware", {
|
|
50
|
+
provides: SomeElse,
|
|
51
|
+
wrap: true
|
|
52
|
+
}) {}
|
|
53
|
+
|
|
54
|
+
export const SomeElseMiddlewareLive = Layer.effect(
|
|
55
|
+
SomeElseMiddleware,
|
|
56
|
+
Effect.gen(function*() {
|
|
57
|
+
// yield* Effect.context<"test-dep">()
|
|
58
|
+
return ({ next }) =>
|
|
59
|
+
Effect.gen(function*() {
|
|
60
|
+
// yield* Effect.context<"test-dep2">()
|
|
61
|
+
return yield* next.pipe(Effect.provideService(SomeElse, new SomeElse({ b: 2 })))
|
|
62
|
+
})
|
|
63
|
+
})
|
|
64
|
+
)
|
|
65
|
+
|
|
19
66
|
const requestConfig = getConfig<RequestContextMap>()
|
|
20
67
|
|
|
21
68
|
// TODO: null as never sucks
|
|
@@ -32,11 +79,14 @@ export const RequestContextMap = {
|
|
|
32
79
|
type _RequestContextMap = typeof RequestContextMap
|
|
33
80
|
export interface RequestContextMap extends _RequestContextMap {}
|
|
34
81
|
|
|
35
|
-
export class AllowAnonymous extends
|
|
82
|
+
export class AllowAnonymous extends Tag<AllowAnonymous>()("AllowAnonymous", {
|
|
36
83
|
dynamic: contextMap(RequestContextMap, "allowAnonymous"),
|
|
37
84
|
requires: SomeElse
|
|
38
|
-
})
|
|
39
|
-
|
|
85
|
+
}) {}
|
|
86
|
+
|
|
87
|
+
export const AllowAnonymousLive = Layer.effect(
|
|
88
|
+
AllowAnonymous,
|
|
89
|
+
Effect.gen(function*() {
|
|
40
90
|
return Effect.fnUntraced(
|
|
41
91
|
function*({ headers, rpc }) {
|
|
42
92
|
yield* SomeElse
|
|
@@ -60,20 +110,22 @@ export class AllowAnonymous extends Middleware.Tag<AllowAnonymous>()("AllowAnony
|
|
|
60
110
|
}
|
|
61
111
|
)
|
|
62
112
|
})
|
|
63
|
-
|
|
64
|
-
}
|
|
113
|
+
)
|
|
65
114
|
|
|
66
115
|
// TODO: don't expect service when it's wrap
|
|
67
116
|
// @effect-diagnostics-next-line missingEffectServiceDependency:off
|
|
68
|
-
export class RequireRoles extends
|
|
117
|
+
export class RequireRoles extends Tag<RequireRoles>()("RequireRoles", {
|
|
69
118
|
dynamic: contextMap(RequestContextMap, "requireRoles"),
|
|
70
119
|
wrap: true,
|
|
71
120
|
// wrap: true,
|
|
72
121
|
// had to move this in here, because once you put it manually as a readonly static property on the class,
|
|
73
122
|
// there's a weird issue where the fluent api stops behaving properly after adding this middleware via `addDynamicMiddleware`
|
|
74
123
|
dependsOn: [AllowAnonymous]
|
|
75
|
-
})
|
|
76
|
-
|
|
124
|
+
}) {}
|
|
125
|
+
|
|
126
|
+
export const RequireRolesLive = Layer.effect(
|
|
127
|
+
RequireRoles,
|
|
128
|
+
Effect.gen(function*() {
|
|
77
129
|
yield* SomeService
|
|
78
130
|
return Effect.fnUntraced(
|
|
79
131
|
function*({ next, rpc }) {
|
|
@@ -94,20 +146,22 @@ export class RequireRoles extends Middleware.Tag<RequireRoles>()("RequireRoles",
|
|
|
94
146
|
}
|
|
95
147
|
)
|
|
96
148
|
})
|
|
97
|
-
|
|
98
|
-
}
|
|
149
|
+
)
|
|
99
150
|
|
|
100
151
|
// TODO: don't expect service when it's wrap
|
|
101
|
-
export class Test extends
|
|
152
|
+
export class Test extends Tag<Test>()("Test", {
|
|
102
153
|
wrap: true,
|
|
103
154
|
dynamic: contextMap(RequestContextMap, "test")
|
|
104
|
-
})
|
|
105
|
-
|
|
155
|
+
}) {}
|
|
156
|
+
|
|
157
|
+
export const TestLive = Layer.effect(
|
|
158
|
+
Test,
|
|
159
|
+
Effect.gen(function*() {
|
|
106
160
|
return Effect.fn(function*({ next }) {
|
|
107
161
|
return yield* next
|
|
108
162
|
})
|
|
109
163
|
})
|
|
110
|
-
|
|
164
|
+
)
|
|
111
165
|
|
|
112
166
|
export class CustomError1 extends TaggedError<NotLoggedInError>()("CustomError1", {}) {}
|
|
113
167
|
export class CustomError2 extends TaggedError<NotLoggedInError>()("CustomError1", {}) {}
|
package/test/requires.test.ts
CHANGED
|
@@ -4,50 +4,10 @@ import { describe, expect, expectTypeOf, it } from "@effect/vitest"
|
|
|
4
4
|
import { Context, Effect, Either, Layer, S } from "effect-app"
|
|
5
5
|
import { NotLoggedInError, UnauthorizedError } from "effect-app/client"
|
|
6
6
|
import { HttpHeaders } from "effect-app/http"
|
|
7
|
-
import { makeMiddleware,
|
|
8
|
-
import { AllowAnonymous, RequestContextMap, RequireRoles, Some,
|
|
7
|
+
import { makeMiddleware, TagService } from "effect-app/rpc"
|
|
8
|
+
import { AllowAnonymous, AllowAnonymousLive, RequestContextMap, RequireRoles, RequireRolesLive, Some, SomeElseMiddleware, SomeElseMiddlewareLive, SomeMiddleware, SomeMiddlewareLive, SomeMiddlewareWrap, SomeService, Test, TestLive } from "./fixtures.js"
|
|
9
9
|
|
|
10
|
-
export class
|
|
11
|
-
provides: Some
|
|
12
|
-
})({
|
|
13
|
-
effect: Effect.gen(function*() {
|
|
14
|
-
// yield* Effect.context<"test-dep">()
|
|
15
|
-
return () =>
|
|
16
|
-
Effect.gen(function*() {
|
|
17
|
-
return new Some({ a: 1 })
|
|
18
|
-
})
|
|
19
|
-
})
|
|
20
|
-
}) {
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// functionally equivalent to the one above
|
|
24
|
-
export class SomeMiddlewareWrap extends Middleware.Tag<SomeMiddlewareWrap>()("SomeMiddlewareWrap", {
|
|
25
|
-
provides: Some,
|
|
26
|
-
wrap: true
|
|
27
|
-
})({
|
|
28
|
-
effect: Effect.gen(function*() {
|
|
29
|
-
// yield* Effect.context<"test-dep">()
|
|
30
|
-
return ({ next }) => next.pipe(Effect.provideService(Some, new Some({ a: 1 })))
|
|
31
|
-
})
|
|
32
|
-
}) {
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export class SomeElseMiddleware extends Middleware.Tag<SomeElseMiddleware>()("SomeElseMiddleware", {
|
|
36
|
-
provides: SomeElse,
|
|
37
|
-
wrap: true
|
|
38
|
-
})({
|
|
39
|
-
effect: Effect.gen(function*() {
|
|
40
|
-
// yield* Effect.context<"test-dep">()
|
|
41
|
-
return ({ next }) =>
|
|
42
|
-
Effect.gen(function*() {
|
|
43
|
-
// yield* Effect.context<"test-dep2">()
|
|
44
|
-
return yield* next.pipe(Effect.provideService(SomeElse, new SomeElse({ b: 2 })))
|
|
45
|
-
})
|
|
46
|
-
})
|
|
47
|
-
}) {
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export class RequiresSomeMiddleware extends Middleware.Tag<RequiresSomeMiddleware>()("RequiresSomeMiddleware", {
|
|
10
|
+
export class RequiresSomeMiddleware extends TagService<RequiresSomeMiddleware>()("RequiresSomeMiddleware", {
|
|
51
11
|
requires: [Some],
|
|
52
12
|
wrap: true
|
|
53
13
|
})({
|
|
@@ -79,7 +39,7 @@ const _middlewareSideways = makeMiddleware(RequestContextMap)
|
|
|
79
39
|
const _middlewareSidewaysFully = makeMiddleware(RequestContextMap)
|
|
80
40
|
.middleware(RequiresSomeMiddleware, SomeMiddleware, RequireRoles, AllowAnonymous, Test, SomeElseMiddleware)
|
|
81
41
|
|
|
82
|
-
const _middleware3Bis = makeMiddleware(RequestContextMap)
|
|
42
|
+
export const _middleware3Bis = makeMiddleware(RequestContextMap)
|
|
83
43
|
.middleware(RequiresSomeMiddleware)
|
|
84
44
|
.middleware(SomeMiddlewareWrap)
|
|
85
45
|
.middleware(RequireRoles)
|
|
@@ -88,11 +48,7 @@ const _middleware3Bis = makeMiddleware(RequestContextMap)
|
|
|
88
48
|
|
|
89
49
|
expectTypeOf(_middlewareSideways).toEqualTypeOf<typeof middleware3>()
|
|
90
50
|
expectTypeOf(_middlewareSidewaysFully).toEqualTypeOf<typeof _middlewareSideways>()
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
type Default = typeof middleware3["Default"]
|
|
94
|
-
type LayerContext = Layer.Layer.Context<Default>
|
|
95
|
-
expectTypeOf({} as LayerContext).toEqualTypeOf<SomeService>()
|
|
51
|
+
expectTypeOf(_middleware3Bis).not.toEqualTypeOf<typeof middleware3>() // is not the same because SomeMiddlewareWrap is not SomeMiddleware
|
|
96
52
|
|
|
97
53
|
class TestRequest extends S.TaggedRequest<Test>("Test")("Test", {
|
|
98
54
|
payload: {},
|
|
@@ -112,7 +68,16 @@ const testSuite = (_mw: typeof middleware3) =>
|
|
|
112
68
|
rpc: { ...Rpc.fromTaggedRequest(TestRequest), annotations: Context.make(_mw.requestContext, {}) },
|
|
113
69
|
next: Effect.void as unknown as Effect<SuccessValue, never, any>
|
|
114
70
|
}
|
|
115
|
-
const layer = _mw.
|
|
71
|
+
const layer = _mw.layer.pipe(
|
|
72
|
+
Layer.provide([
|
|
73
|
+
RequiresSomeMiddleware.Default,
|
|
74
|
+
SomeMiddlewareLive,
|
|
75
|
+
RequireRolesLive.pipe(Layer.provide(SomeService.toLayer())),
|
|
76
|
+
AllowAnonymousLive,
|
|
77
|
+
TestLive,
|
|
78
|
+
SomeElseMiddlewareLive
|
|
79
|
+
])
|
|
80
|
+
)
|
|
116
81
|
yield* Effect
|
|
117
82
|
.gen(function*() {
|
|
118
83
|
const mw = yield* _mw
|
|
@@ -194,6 +159,6 @@ const testSuite = (_mw: typeof middleware3) =>
|
|
|
194
159
|
})
|
|
195
160
|
|
|
196
161
|
testSuite(middleware3)
|
|
197
|
-
testSuite(_middleware3Bis)
|
|
162
|
+
// testSuite(_middleware3Bis)
|
|
198
163
|
testSuite(_middlewareSideways)
|
|
199
164
|
testSuite(_middlewareSidewaysFully)
|