@effect-app/infra 3.0.12 → 3.0.13
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 +8 -0
- package/package.json +2 -2
- package/test/controller.test.ts +3 -8
- package/test/dist/controller.test.d.ts.map +1 -1
- package/test/dist/fixtures.d.ts +27 -11
- package/test/dist/fixtures.d.ts.map +1 -1
- package/test/dist/fixtures.js +13 -21
- package/test/dist/rpc-multi-middleware.test.d.ts.map +1 -1
- package/test/fixtures.ts +11 -24
- package/test/rpc-multi-middleware.test.ts +8 -0
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effect-app/infra",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.13",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"dependencies": {
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"proper-lockfile": "^4.1.2",
|
|
14
14
|
"pure-rand": "7.0.1",
|
|
15
15
|
"query-string": "^9.2.2",
|
|
16
|
-
"effect-app": "3.0.
|
|
16
|
+
"effect-app": "3.0.9"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
19
|
"@azure/cosmos": "^4.5.0",
|
package/test/controller.test.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { type MakeContext, type MakeErrors, makeRouter } from "@effect-app/infra
|
|
|
4
4
|
import { type RpcSerialization } from "@effect/rpc"
|
|
5
5
|
import { expect, expectTypeOf, it } from "@effect/vitest"
|
|
6
6
|
import { Context, Effect, Layer, S, Scope } from "effect-app"
|
|
7
|
-
import { InvalidStateError, makeRpcClient,
|
|
7
|
+
import { InvalidStateError, makeRpcClient, UnauthorizedError } from "effect-app/client"
|
|
8
8
|
import { DefaultGenericMiddlewares } from "effect-app/middleware"
|
|
9
9
|
import * as RpcX from "effect-app/rpc"
|
|
10
10
|
import { MiddlewareMaker } from "effect-app/rpc"
|
|
@@ -205,17 +205,12 @@ export const middleware3 = MiddlewareMaker
|
|
|
205
205
|
.middleware(Test)
|
|
206
206
|
.middleware(BogusMiddleware)
|
|
207
207
|
|
|
208
|
-
export
|
|
208
|
+
export const { TaggedRequest: Req } = makeRpcClient(RequestContextMap)<{
|
|
209
209
|
/** Disable authentication requirement */
|
|
210
210
|
allowAnonymous?: true
|
|
211
211
|
/** Control the roles that are required to access the resource */
|
|
212
212
|
allowRoles?: readonly string[]
|
|
213
|
-
}
|
|
214
|
-
export const { TaggedRequest: Req } = makeRpcClient<RequestConfig, RequestContextMap>({
|
|
215
|
-
allowAnonymous: NotLoggedInError,
|
|
216
|
-
requireRoles: UnauthorizedError,
|
|
217
|
-
test: S.Never
|
|
218
|
-
})
|
|
213
|
+
}>()
|
|
219
214
|
|
|
220
215
|
export class Eff extends Req<Eff>()("Eff", {}, { success: S.Void }) {}
|
|
221
216
|
export class Gen extends Req<Gen>()("Gen", {}, { success: S.Void }) {}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controller.test.d.ts","sourceRoot":"","sources":["../controller.test.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAc,MAAM,+BAA+B,CAAA;AAC7F,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAEnD,OAAO,EAAW,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAC7D,OAAO,EAAoC,
|
|
1
|
+
{"version":3,"file":"controller.test.d.ts","sourceRoot":"","sources":["../controller.test.ts"],"names":[],"mappings":"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"}
|
package/test/dist/fixtures.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Context, Effect, Layer, S, Scope } from "effect-app";
|
|
2
2
|
import { NotLoggedInError, UnauthorizedError } from "effect-app/client";
|
|
3
|
-
import { RpcX } from "effect-app/rpc";
|
|
4
|
-
import { RpcContextMap } from "effect-app/rpc/RpcContextMap";
|
|
3
|
+
import { RpcContextMap, RpcX } from "effect-app/rpc";
|
|
5
4
|
declare const UserProfile_base: S.EnhancedClass<UserProfile, {
|
|
6
5
|
id: typeof S.String;
|
|
7
6
|
roles: S.Array$<typeof S.String> & {
|
|
@@ -64,7 +63,7 @@ declare const SomeElse_base: (abstract new (service: {
|
|
|
64
63
|
} & {
|
|
65
64
|
use: <X>(body: (_: {
|
|
66
65
|
b: number;
|
|
67
|
-
}) => X) => X extends Effect.Effect<infer A, infer E_1, infer R_3> ? Effect.Effect<A, E_1,
|
|
66
|
+
}) => X) => X extends Effect.Effect<infer A, infer E_1, infer R_3> ? Effect.Effect<A, E_1, SomeElse | R_3> : Effect.Effect<X, never, SomeElse>;
|
|
68
67
|
};
|
|
69
68
|
export declare class SomeElse extends SomeElse_base {
|
|
70
69
|
}
|
|
@@ -106,16 +105,33 @@ declare const SomeElseMiddleware_base: RpcX.RpcMiddleware.TagClass<SomeElseMiddl
|
|
|
106
105
|
export declare class SomeElseMiddleware extends SomeElseMiddleware_base {
|
|
107
106
|
}
|
|
108
107
|
export declare const SomeElseMiddlewareLive: Layer.Layer<SomeElseMiddleware, never, never>;
|
|
109
|
-
|
|
110
|
-
readonly
|
|
111
|
-
|
|
112
|
-
|
|
108
|
+
declare const RequestContextMap_base: (new () => {
|
|
109
|
+
readonly config: {
|
|
110
|
+
readonly allowAnonymous: RpcContextMap.RpcContextMap.Inverted<UserProfile, typeof NotLoggedInError>;
|
|
111
|
+
readonly requireRoles: RpcContextMap.RpcContextMap.Custom<never, typeof UnauthorizedError, string[]>;
|
|
112
|
+
readonly test: RpcContextMap.RpcContextMap<never, typeof S.Never>;
|
|
113
|
+
};
|
|
114
|
+
}) & {
|
|
115
|
+
config: {
|
|
116
|
+
readonly allowAnonymous: RpcContextMap.RpcContextMap.Inverted<UserProfile, typeof NotLoggedInError>;
|
|
117
|
+
readonly requireRoles: RpcContextMap.RpcContextMap.Custom<never, typeof UnauthorizedError, string[]>;
|
|
118
|
+
readonly test: RpcContextMap.RpcContextMap<never, typeof S.Never>;
|
|
119
|
+
};
|
|
120
|
+
getConfig: (rpc: import("@effect/rpc/Rpc").AnyWithProps) => RpcContextMap.GetContextConfig<{
|
|
121
|
+
readonly allowAnonymous: RpcContextMap.RpcContextMap.Inverted<UserProfile, typeof NotLoggedInError>;
|
|
122
|
+
readonly requireRoles: RpcContextMap.RpcContextMap.Custom<never, typeof UnauthorizedError, string[]>;
|
|
123
|
+
readonly test: RpcContextMap.RpcContextMap<never, typeof S.Never>;
|
|
124
|
+
}>;
|
|
125
|
+
get: <Key extends "allowAnonymous" | "requireRoles" | "test">(key: Key) => RpcX.RpcMiddleware.RpcDynamic<Key, {
|
|
126
|
+
readonly allowAnonymous: RpcContextMap.RpcContextMap.Inverted<UserProfile, typeof NotLoggedInError>;
|
|
127
|
+
readonly requireRoles: RpcContextMap.RpcContextMap.Custom<never, typeof UnauthorizedError, string[]>;
|
|
128
|
+
readonly test: RpcContextMap.RpcContextMap<never, typeof S.Never>;
|
|
129
|
+
}[Key]>;
|
|
113
130
|
};
|
|
114
|
-
|
|
115
|
-
export interface RequestContextMap extends _RequestContextMap {
|
|
131
|
+
export declare class RequestContextMap extends RequestContextMap_base {
|
|
116
132
|
}
|
|
117
133
|
declare const AllowAnonymous_base: RpcX.RpcMiddleware.TagClass<AllowAnonymous, "AllowAnonymous", {
|
|
118
|
-
readonly dynamic: RpcX.RpcMiddleware.RpcDynamic<"allowAnonymous", RpcContextMap.Inverted<
|
|
134
|
+
readonly dynamic: RpcX.RpcMiddleware.RpcDynamic<"allowAnonymous", RpcContextMap.RpcContextMap.Inverted<UserProfile, typeof NotLoggedInError>>;
|
|
119
135
|
}, {
|
|
120
136
|
requires: SomeElse;
|
|
121
137
|
}>;
|
|
@@ -123,7 +139,7 @@ export declare class AllowAnonymous extends AllowAnonymous_base {
|
|
|
123
139
|
}
|
|
124
140
|
export declare const AllowAnonymousLive: Layer.Layer<AllowAnonymous, never, never>;
|
|
125
141
|
declare const RequireRoles_base: RpcX.RpcMiddleware.TagClass<RequireRoles, "RequireRoles", {
|
|
126
|
-
readonly dynamic: RpcX.RpcMiddleware.RpcDynamic<"requireRoles", RpcContextMap.Custom<never, typeof UnauthorizedError, string[]>>;
|
|
142
|
+
readonly dynamic: RpcX.RpcMiddleware.RpcDynamic<"requireRoles", RpcContextMap.RpcContextMap.Custom<never, typeof UnauthorizedError, string[]>>;
|
|
127
143
|
readonly dependsOn: readonly [typeof AllowAnonymous];
|
|
128
144
|
}, {
|
|
129
145
|
requires: never;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../fixtures.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAC7D,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AACvE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../fixtures.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAC7D,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AACvE,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAA;;;;;;;;;;;;;AAGpD,qBAAa,WAAY,SAAQ,gBAKhC;CACA;;;;;;;;;;;;;;;;;;;;;;;;;AAED,qBAAa,IAAK,SAAQ,SAA2D;CAAG;;;;;;;;;;;;;;;;;;;;;;;;;AACxF,qBAAa,QAAS,SAAQ,aAAmE;CAAG;;;;;;;;;;;;;;;;;;;;;;;;;AAEpG,qBAAa,WAAY,SAAQ,gBAAgE;CAAG;;cAGb,IAAI;;AAA3F,qBAAa,cAAe,SAAQ,mBAA8E;CACjH;AAED,eAAO,MAAM,kBAAkB,2CAM9B,CAAA;;cAGgE,QAAQ;;AADzE,qBAAa,kBACX,SAAQ,uBAA0F;CAClG;AAEF,eAAO,MAAM,sBAAsB,+CAUlC,CAAA;;;;;;;;;;;;;;;;;;;;;;;;AAED,qBAAa,iBAAkB,SAAQ,sBAIrC;CAAG;;;;cAEkF,QAAQ;;AAA/F,qBAAa,cAAe,SAAQ,mBAElC;CAAG;AAEL,eAAO,MAAM,kBAAkB,2CAyB9B,CAAA;;;;;;;;AAGD,qBAAa,YAAa,SAAQ,iBAKhC;CAAG;AAEL,eAAO,MAAM,gBAAgB,+CAuB5B,CAAA;;;;;;;AAED,qBAAa,IAAK,SAAQ,SAExB;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,6 @@
|
|
|
1
1
|
import { Context, Effect, Layer, S, Scope } from "effect-app";
|
|
2
2
|
import { NotLoggedInError, UnauthorizedError } from "effect-app/client";
|
|
3
|
-
import { RpcX } from "effect-app/rpc";
|
|
4
|
-
import { contextMap, getConfig, RpcContextMap } from "effect-app/rpc/RpcContextMap";
|
|
3
|
+
import { RpcContextMap, RpcX } from "effect-app/rpc";
|
|
5
4
|
import { TaggedError } from "effect-app/Schema";
|
|
6
5
|
export class UserProfile extends Context.assignTag("UserProfile")(S.Class("UserProfile")({
|
|
7
6
|
id: S.String,
|
|
@@ -31,19 +30,14 @@ export const SomeElseMiddlewareLive = Layer.effect(SomeElseMiddleware, Effect.ge
|
|
|
31
30
|
return yield* effect.pipe(Effect.provideService(SomeElse, new SomeElse({ b: 2 })));
|
|
32
31
|
});
|
|
33
32
|
}));
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
export const RequestContextMap = {
|
|
41
|
-
allowAnonymous: RpcContextMap.makeInverted([UserProfile], NotLoggedInError),
|
|
42
|
-
requireRoles: RpcContextMap.makeCustom(null, UnauthorizedError, Array()),
|
|
43
|
-
test: RpcContextMap.make(null, S.Never)
|
|
44
|
-
};
|
|
33
|
+
export class RequestContextMap extends RpcContextMap.makeMap({
|
|
34
|
+
allowAnonymous: RpcContextMap.makeInverted()(NotLoggedInError),
|
|
35
|
+
requireRoles: RpcContextMap.makeCustom()(UnauthorizedError, Array()),
|
|
36
|
+
test: RpcContextMap.make()(S.Never)
|
|
37
|
+
}) {
|
|
38
|
+
}
|
|
45
39
|
export class AllowAnonymous extends RpcX.RpcMiddleware.Tag()("AllowAnonymous", {
|
|
46
|
-
dynamic:
|
|
40
|
+
dynamic: RequestContextMap.get("allowAnonymous")
|
|
47
41
|
}) {
|
|
48
42
|
}
|
|
49
43
|
export const AllowAnonymousLive = Layer.effect(AllowAnonymous, Effect.gen(function* () {
|
|
@@ -52,7 +46,7 @@ export const AllowAnonymousLive = Layer.effect(AllowAnonymous, Effect.gen(functi
|
|
|
52
46
|
yield* Scope.Scope; // provided by HttpLayerRouter.Provided
|
|
53
47
|
const isLoggedIn = !!headers["x-user"];
|
|
54
48
|
if (!isLoggedIn) {
|
|
55
|
-
if (!
|
|
49
|
+
if (!RequestContextMap.getConfig(rpc).allowAnonymous) {
|
|
56
50
|
return yield* new NotLoggedInError({ message: "Not logged in" });
|
|
57
51
|
}
|
|
58
52
|
return yield* effect;
|
|
@@ -63,10 +57,9 @@ export const AllowAnonymousLive = Layer.effect(AllowAnonymous, Effect.gen(functi
|
|
|
63
57
|
}));
|
|
64
58
|
});
|
|
65
59
|
}));
|
|
66
|
-
// TODO: don't expect service when it's wrap
|
|
67
60
|
// @effect-diagnostics-next-line missingEffectServiceDependency:off
|
|
68
61
|
export class RequireRoles extends RpcX.RpcMiddleware.Tag()("RequireRoles", {
|
|
69
|
-
dynamic:
|
|
62
|
+
dynamic: RequestContextMap.get("requireRoles"),
|
|
70
63
|
// had to move this in here, because once you put it manually as a readonly static property on the class,
|
|
71
64
|
// there's a weird issue where the fluent api stops behaving properly after adding this middleware via `addDynamicMiddleware`
|
|
72
65
|
dependsOn: [AllowAnonymous]
|
|
@@ -77,7 +70,7 @@ export const RequireRolesLive = Layer.effect(RequireRoles, Effect.gen(function*
|
|
|
77
70
|
return Effect.fnUntraced(function* (effect, { rpc }) {
|
|
78
71
|
// we don't know if the service will be provided or not, so we use option..
|
|
79
72
|
const userProfile = yield* Effect.serviceOption(UserProfile);
|
|
80
|
-
const { requireRoles } =
|
|
73
|
+
const { requireRoles } = RequestContextMap.getConfig(rpc);
|
|
81
74
|
console.dir({
|
|
82
75
|
userProfile,
|
|
83
76
|
requireRoles
|
|
@@ -88,9 +81,8 @@ export const RequireRolesLive = Layer.effect(RequireRoles, Effect.gen(function*
|
|
|
88
81
|
return yield* effect;
|
|
89
82
|
});
|
|
90
83
|
}));
|
|
91
|
-
// TODO: don't expect service when it's wrap
|
|
92
84
|
export class Test extends RpcX.RpcMiddleware.Tag()("Test", {
|
|
93
|
-
dynamic:
|
|
85
|
+
dynamic: RequestContextMap.get("test")
|
|
94
86
|
}) {
|
|
95
87
|
}
|
|
96
88
|
export const TestLive = Layer.effect(Test, Effect.gen(function* () {
|
|
@@ -102,4 +94,4 @@ export class CustomError1 extends TaggedError()("CustomError1", {}) {
|
|
|
102
94
|
}
|
|
103
95
|
export class CustomError2 extends TaggedError()("CustomError1", {}) {
|
|
104
96
|
}
|
|
105
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
97
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZml4dHVyZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9maXh0dXJlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxNQUFNLFlBQVksQ0FBQTtBQUM3RCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQTtBQUN2RSxPQUFPLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxNQUFNLGdCQUFnQixDQUFBO0FBQ3BELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQTtBQUUvQyxNQUFNLE9BQU8sV0FBWSxTQUFRLE9BQU8sQ0FBQyxTQUFTLENBQTJCLGFBQWEsQ0FBQyxDQUN6RixDQUFDLENBQUMsS0FBSyxDQUFjLGFBQWEsQ0FBQyxDQUFDO0lBQ2xDLEVBQUUsRUFBRSxDQUFDLENBQUMsTUFBTTtJQUNaLEtBQUssRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7Q0FDekIsQ0FBQyxDQUNIO0NBQ0E7QUFFRCxNQUFNLE9BQU8sSUFBSyxTQUFRLE9BQU8sQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFRO0NBQUc7QUFDeEYsTUFBTSxPQUFPLFFBQVMsU0FBUSxPQUFPLENBQUMsU0FBUyxDQUFDLFVBQVUsRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBWTtDQUFHO0FBQ3BHLE1BQU0sZUFBZSxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQTtBQUNoRCxNQUFNLE9BQU8sV0FBWSxTQUFRLE9BQU8sQ0FBQyxTQUFTLENB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
|
|
@@ -1 +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;AACvD,OAAO,EAAE,CAAC,EAAE,MAAM,YAAY,CAAA;AAC9B,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAGpD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAIhD,OAAO,EAAE,cAAc,EAAyC,YAAY,EAA0B,kBAAkB,EAA0B,cAAc,EAAmC,IAAI,EAAY,WAAW,EAAE,MAAM,eAAe,CAAA
|
|
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;AACvD,OAAO,EAAE,CAAC,EAAE,MAAM,YAAY,CAAA;AAC9B,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAGpD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAIhD,OAAO,EAAE,cAAc,EAAyC,YAAY,EAA0B,kBAAkB,EAA0B,cAAc,EAAmC,IAAI,EAAY,WAAW,EAAE,MAAM,eAAe,CAAA;AAErP,QAAA,MAAM,UAAU;;;;;;;;;;oCAGmB,CAAA;AAGnC,qBAAa,oBAAqB,SAAQ,UAAU;CAAG;;;;;;;;;;;;AAEvD,cAAM,UAAW,SAAQ,eAKkB;CACzC;AAsCF,eAAO,MAAM,OAAO,uFAMhB,CAAA;AAiBJ,eAAO,MAAM,YAAY,4KAItB,CAAA;AAEH,eAAO,MAAM,YAAY,0IAgByB,CAAA"}
|
package/test/fixtures.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Context, Effect, Layer, S, Scope } from "effect-app"
|
|
2
2
|
import { NotLoggedInError, UnauthorizedError } from "effect-app/client"
|
|
3
|
-
import { RpcX } from "effect-app/rpc"
|
|
4
|
-
import { contextMap, getConfig, RpcContextMap } from "effect-app/rpc/RpcContextMap"
|
|
3
|
+
import { RpcContextMap, RpcX } from "effect-app/rpc"
|
|
5
4
|
import { TaggedError } from "effect-app/Schema"
|
|
6
5
|
|
|
7
6
|
export class UserProfile extends Context.assignTag<UserProfile, UserProfile>("UserProfile")(
|
|
@@ -45,24 +44,14 @@ export const SomeElseMiddlewareLive = Layer.effect(
|
|
|
45
44
|
})
|
|
46
45
|
)
|
|
47
46
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
//
|
|
54
|
-
// consider if we want to support Context of one Service
|
|
55
|
-
export const RequestContextMap = {
|
|
56
|
-
allowAnonymous: RpcContextMap.makeInverted([UserProfile], NotLoggedInError),
|
|
57
|
-
requireRoles: RpcContextMap.makeCustom(null as never, UnauthorizedError, Array<string>()),
|
|
58
|
-
test: RpcContextMap.make(null as never, S.Never)
|
|
59
|
-
} as const
|
|
60
|
-
|
|
61
|
-
type _RequestContextMap = typeof RequestContextMap
|
|
62
|
-
export interface RequestContextMap extends _RequestContextMap {}
|
|
47
|
+
export class RequestContextMap extends RpcContextMap.makeMap({
|
|
48
|
+
allowAnonymous: RpcContextMap.makeInverted<UserProfile>()(NotLoggedInError),
|
|
49
|
+
requireRoles: RpcContextMap.makeCustom()(UnauthorizedError, Array<string>()),
|
|
50
|
+
test: RpcContextMap.make()(S.Never)
|
|
51
|
+
}) {}
|
|
63
52
|
|
|
64
53
|
export class AllowAnonymous extends RpcX.RpcMiddleware.Tag<AllowAnonymous, { requires: SomeElse }>()("AllowAnonymous", {
|
|
65
|
-
dynamic:
|
|
54
|
+
dynamic: RequestContextMap.get("allowAnonymous")
|
|
66
55
|
}) {}
|
|
67
56
|
|
|
68
57
|
export const AllowAnonymousLive = Layer.effect(
|
|
@@ -74,7 +63,7 @@ export const AllowAnonymousLive = Layer.effect(
|
|
|
74
63
|
yield* Scope.Scope // provided by HttpLayerRouter.Provided
|
|
75
64
|
const isLoggedIn = !!headers["x-user"]
|
|
76
65
|
if (!isLoggedIn) {
|
|
77
|
-
if (!
|
|
66
|
+
if (!RequestContextMap.getConfig(rpc).allowAnonymous) {
|
|
78
67
|
return yield* new NotLoggedInError({ message: "Not logged in" })
|
|
79
68
|
}
|
|
80
69
|
return yield* effect
|
|
@@ -92,10 +81,9 @@ export const AllowAnonymousLive = Layer.effect(
|
|
|
92
81
|
})
|
|
93
82
|
)
|
|
94
83
|
|
|
95
|
-
// TODO: don't expect service when it's wrap
|
|
96
84
|
// @effect-diagnostics-next-line missingEffectServiceDependency:off
|
|
97
85
|
export class RequireRoles extends RpcX.RpcMiddleware.Tag<RequireRoles>()("RequireRoles", {
|
|
98
|
-
dynamic:
|
|
86
|
+
dynamic: RequestContextMap.get("requireRoles"),
|
|
99
87
|
// had to move this in here, because once you put it manually as a readonly static property on the class,
|
|
100
88
|
// there's a weird issue where the fluent api stops behaving properly after adding this middleware via `addDynamicMiddleware`
|
|
101
89
|
dependsOn: [AllowAnonymous]
|
|
@@ -109,7 +97,7 @@ export const RequireRolesLive = Layer.effect(
|
|
|
109
97
|
function*(effect, { rpc }) {
|
|
110
98
|
// we don't know if the service will be provided or not, so we use option..
|
|
111
99
|
const userProfile = yield* Effect.serviceOption(UserProfile)
|
|
112
|
-
const { requireRoles } =
|
|
100
|
+
const { requireRoles } = RequestContextMap.getConfig(rpc)
|
|
113
101
|
console.dir(
|
|
114
102
|
{
|
|
115
103
|
userProfile,
|
|
@@ -126,9 +114,8 @@ export const RequireRolesLive = Layer.effect(
|
|
|
126
114
|
})
|
|
127
115
|
)
|
|
128
116
|
|
|
129
|
-
// TODO: don't expect service when it's wrap
|
|
130
117
|
export class Test extends RpcX.RpcMiddleware.Tag<Test>()("Test", {
|
|
131
|
-
dynamic:
|
|
118
|
+
dynamic: RequestContextMap.get("test")
|
|
132
119
|
}) {}
|
|
133
120
|
|
|
134
121
|
export const TestLive = Layer.effect(
|
|
@@ -13,6 +13,14 @@ import { createServer } from "http"
|
|
|
13
13
|
import { DefaultGenericMiddlewaresLive } from "../src/api/routing.js"
|
|
14
14
|
import { AllowAnonymous, AllowAnonymousLive, RequestContextMap, RequireRoles, RequireRolesLive, Some, SomeElseMiddleware, SomeElseMiddlewareLive, SomeMiddleware, SomeMiddlewareLive, SomeService, Test, TestLive, UserProfile } from "./fixtures.js"
|
|
15
15
|
|
|
16
|
+
const incomplete = MiddlewareMaker
|
|
17
|
+
.Tag<middleware>()("MiddlewareMaker", RequestContextMap)
|
|
18
|
+
.middleware(RequireRoles)
|
|
19
|
+
.middleware(AllowAnonymous, Test)
|
|
20
|
+
|
|
21
|
+
// this extension is allowed otherwise the error is quite obscure
|
|
22
|
+
export class incompleteMiddleware extends incomplete {}
|
|
23
|
+
|
|
16
24
|
class middleware extends MiddlewareMaker
|
|
17
25
|
.Tag<middleware>()("MiddlewareMaker", RequestContextMap)
|
|
18
26
|
.middleware(RequireRoles)
|