@effect-app/infra 1.14.4 → 1.16.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 CHANGED
@@ -1,5 +1,31 @@
1
1
  # @effect-app/infra
2
2
 
3
+ ## 1.16.0
4
+
5
+ ### Minor Changes
6
+
7
+ - feat: add new router support
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies
12
+ - effect-app@1.15.0
13
+ - @effect-app/infra-adapters@1.10.1
14
+
15
+ ## 1.15.0
16
+
17
+ ### Minor Changes
18
+
19
+ - b3d9a3e: update packages
20
+
21
+ ### Patch Changes
22
+
23
+ - Updated dependencies [b3d9a3e]
24
+ - @effect-app/infra-adapters@1.10.0
25
+ - effect-app@1.14.0
26
+ - @effect-app/schema@1.11.0
27
+ - @effect-app/core@1.9.0
28
+
3
29
  ## 1.14.4
4
30
 
5
31
  ### Patch Changes
@@ -0,0 +1,150 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.makeRouter = void 0;
7
+ var _Effect = require("@effect-app/core/Effect");
8
+ var _utils = require("@effect-app/core/utils");
9
+ var _routing = require("@effect-app/infra/api/routing");
10
+ var _effectApp = require("effect-app");
11
+ var _http = require("effect-app/http");
12
+ var _schema = require("effect-app/schema");
13
+ // TODO: support FLIP
14
+ const makeRouter = (handleRequestEnv /* Middleware */) => {
15
+ function match(requestHandler, errorHandler, middleware) {
16
+ let middlewareLayer = undefined;
17
+ if (middleware) {
18
+ const {
19
+ handler,
20
+ makeRequestLayer
21
+ } = middleware(requestHandler);
22
+ requestHandler = handler; // todo
23
+ middlewareLayer = makeRequestLayer;
24
+ }
25
+ // const rdesc = yield* RouteDescriptors.flatMap((_) => _.get)
26
+ const handler = (0, _routing.makeRequestHandler)(requestHandler,
27
+ // one argument if no middleware, 2 if has middleware. TODO: clean this shit up
28
+ errorHandler, middlewareLayer);
29
+ const route = _http.HttpRouter.makeRoute(requestHandler.Request.method, requestHandler.Request.path, handler);
30
+ // TODO
31
+ // rdesc.push(makeRouteDescriptor(
32
+ // requestHandler.Request.path,
33
+ // requestHandler.Request.method,
34
+ // requestHandler
35
+ // ))
36
+ return route;
37
+ }
38
+ function handle(_, name, adaptResponse) {
39
+ const Request = _effectApp.S.REST.extractRequest(_);
40
+ const Response = _effectApp.S.REST.extractResponse(_);
41
+ return h => ({
42
+ adaptResponse,
43
+ h: h.handler,
44
+ name,
45
+ Request,
46
+ Response,
47
+ ResponseOpenApi: _.ResponseOpenApi ?? Response,
48
+ Context: null,
49
+ CTX: null,
50
+ rt: h._tag
51
+ });
52
+ }
53
+ function matchFor(rsc) {
54
+ const filtered = (0, _utils.typedKeysOf)(rsc).reduce((acc, cur) => {
55
+ if (_effectApp.Predicate.isObject(rsc[cur]) && rsc[cur].Request) {
56
+ acc[cur] = rsc[cur];
57
+ }
58
+ return acc;
59
+ }, {});
60
+ const matchWithServices = action => {
61
+ return (services, f) => (req, ctx) => _effectApp.Effect.andThen((0, _Effect.allLower)(services), svc2 => f(req, {
62
+ ...ctx,
63
+ ...svc2,
64
+ Response: rsc[action].Response
65
+ }));
66
+ };
67
+ const controllers = controllers => {
68
+ const handlers = (0, _utils.typedKeysOf)(filtered).reduce((acc, cur) => {
69
+ if (cur === "meta") return acc;
70
+ const m = rsc.meta;
71
+ if (!m) throw new Error("Resource has no meta specified");
72
+ acc[cur] = handle(rsc[cur], m.moduleName + "." + cur)(controllers[cur]);
73
+ return acc;
74
+ }, {});
75
+ const mapped = (0, _utils.typedKeysOf)(handlers).reduce((acc, cur) => {
76
+ const handler = handlers[cur];
77
+ const req = handler.Request;
78
+ class Request extends req {
79
+ static path = "/" + handler.name + (req.path === "/" ? "" : req.path);
80
+ static method = req.method === "AUTO" ? _schema.REST.determineMethod(handler.name.split(".")[1], req) : req.method;
81
+ }
82
+ if (req.method === "AUTO") {
83
+ Object.assign(Request, {
84
+ [Request.method === "GET" || Request.method === "DELETE" ? "Query" : "Body"]: req.Auto
85
+ });
86
+ }
87
+ Object.assign(handler, {
88
+ Request
89
+ });
90
+ acc[cur] = match(handler, errorHandler(req), handleRequestEnv // TODO
91
+ );
92
+ return acc;
93
+ }, {});
94
+ return _http.HttpRouter.fromIterable(Object.values(mapped));
95
+ };
96
+ const r = {
97
+ controllers,
98
+ ...(0, _utils.typedKeysOf)(filtered).reduce((prev, cur) => {
99
+ ;
100
+ prev[cur] = (svcOrFnOrEffect, fnOrNone) => _effectApp.Effect.isEffect(svcOrFnOrEffect) ? class {
101
+ static _tag = "d";
102
+ static handler = () => svcOrFnOrEffect;
103
+ } : typeof svcOrFnOrEffect === "function" ? class {
104
+ static _tag = "d";
105
+ static handler = (req, ctx) => svcOrFnOrEffect(req, {
106
+ ...ctx,
107
+ Response: rsc[cur].Response
108
+ });
109
+ } : class {
110
+ static _tag = "d";
111
+ static handler = matchWithServices(cur)(svcOrFnOrEffect, fnOrNone);
112
+ };
113
+ prev[cur + "Raw"] = (svcOrFnOrEffect, fnOrNone) => _effectApp.Effect.isEffect(svcOrFnOrEffect) ? class {
114
+ static _tag = "raw";
115
+ static handler = () => svcOrFnOrEffect;
116
+ } : typeof svcOrFnOrEffect === "function" ? class {
117
+ static _tag = "raw";
118
+ static handler = (req, ctx) => svcOrFnOrEffect(req, {
119
+ ...ctx,
120
+ Response: rsc[cur].Response
121
+ });
122
+ } : class {
123
+ static _tag = "raw";
124
+ static handler = matchWithServices(cur)(svcOrFnOrEffect, fnOrNone);
125
+ };
126
+ return prev;
127
+ }, {})
128
+ };
129
+ return r;
130
+ }
131
+ const errorHandler = resourceRequest => {
132
+ return (req, res, r2) => (0, _routing.defaultErrorHandler)(req, res, _effectApp.Effect.catchTag(r2, "ParseError", _ => _effectApp.Effect.die(_)), resourceRequest.failure);
133
+ };
134
+ /**
135
+ * Gather all handlers of a module and attach them to the Server.
136
+ * If no `allowAnonymous` flag is on the Request, will require a valid authenticated user.
137
+ */
138
+ function matchAll(handlers) {
139
+ const r = (0, _utils.typedKeysOf)(handlers).reduce((acc, cur) => {
140
+ return _http.HttpRouter.concat(acc, handlers[cur]);
141
+ }, _http.HttpRouter.empty);
142
+ return r;
143
+ }
144
+ return {
145
+ matchFor,
146
+ matchAll
147
+ };
148
+ };
149
+ exports.makeRouter = makeRouter;
150
+ //# sourceMappingURL=router.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.cjs","names":["_Effect","require","_utils","_routing","_effectApp","_http","_schema","makeRouter","handleRequestEnv","match","requestHandler","errorHandler","middleware","middlewareLayer","undefined","handler","makeRequestLayer","makeRequestHandler","route","HttpRouter","makeRoute","Request","method","path","handle","_","name","adaptResponse","S","REST","extractRequest","Response","extractResponse","h","ResponseOpenApi","Context","CTX","rt","_tag","matchFor","rsc","filtered","typedKeysOf","reduce","acc","cur","Predicate","isObject","matchWithServices","action","services","f","req","ctx","Effect","andThen","allLower","svc2","controllers","handlers","m","meta","Error","moduleName","mapped","determineMethod","split","Object","assign","Auto","fromIterable","values","r","prev","svcOrFnOrEffect","fnOrNone","isEffect","resourceRequest","res","r2","defaultErrorHandler","catchTag","die","failure","matchAll","concat","empty","exports"],"sources":["../src/router.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
@@ -8,5 +8,5 @@ import type { HttpServerRequest, HttpServerResponse } from "effect-app/http";
8
8
  import type { RequestHandler } from "./base.js";
9
9
  import type { Middleware } from "./makeRequestHandler.js";
10
10
  export declare const RouteDescriptors: Context.Tag<Ref<RouteDescriptorAny[]>, Ref<RouteDescriptorAny[]>>;
11
- export declare function match<R, M, PathA extends Struct.Fields, CookieA extends Struct.Fields, QueryA extends Struct.Fields, BodyA extends Struct.Fields, HeaderA extends Struct.Fields, ReqA extends PathA & QueryA & BodyA, ResA extends Struct.Fields, ResE, MiddlewareE, PPath extends `/${string}`, R2, PR, RErr, CTX, Context, Config>(requestHandler: RequestHandler<R, M, PathA, CookieA, QueryA, BodyA, HeaderA, ReqA, ResA, ResE, PPath, CTX, Context, Config>, errorHandler: <R>(req: HttpServerRequest.HttpServerRequest, res: HttpServerResponse.HttpServerResponse, r2: Effect<HttpServerResponse.HttpServerResponse, ValidationError | MiddlewareE | ResE, R>) => Effect<HttpServerResponse.HttpServerResponse, never, Exclude<RErr | R, HttpServerRequest.HttpServerRequest | HttpRouter.RouteContext | Scope>>, middleware?: Middleware<R, M, PathA, CookieA, QueryA, BodyA, HeaderA, ReqA, ResA, ResE, MiddlewareE, PPath, R2, PR, CTX, Context, Config>): Effect.Effect<HttpRouter.Route<import("@effect/platform/HttpServerError").RequestError, import("../../services/RequestContextContainer.js").RequestContextContainer | import("@effect-app/infra-adapters/RequestFiberSet").RequestFiberSet | import("../../services/Store/ContextMapContainer.js").ContextMapContainer | Exclude<R2, HttpRouter.HttpRouter.Provided> | Exclude<RErr, HttpRouter.HttpRouter.Provided> | Exclude<Exclude<Exclude<R, import("effect-app/utils").EnforceNonEmptyRecord<M>>, PR>, HttpRouter.HttpRouter.Provided>>, never, never>;
11
+ export declare function match<R, M, PathA extends Struct.Fields, CookieA extends Struct.Fields, QueryA extends Struct.Fields, BodyA extends Struct.Fields, HeaderA extends Struct.Fields, ReqA extends PathA & QueryA & BodyA, ResA extends Struct.Fields, ResE, MiddlewareE, PPath extends `/${string}`, R2, PR, RErr, CTX, Context, Config>(requestHandler: RequestHandler<R, M, PathA, CookieA, QueryA, BodyA, HeaderA, ReqA, ResA, ResE, PPath, CTX, Context, Config>, errorHandler: <R>(req: HttpServerRequest.HttpServerRequest, res: HttpServerResponse.HttpServerResponse, r2: Effect<HttpServerResponse.HttpServerResponse, ValidationError | MiddlewareE | ResE, R>) => Effect<HttpServerResponse.HttpServerResponse, never, Exclude<RErr | R, HttpServerRequest.HttpServerRequest | HttpRouter.RouteContext | Scope>>, middleware?: Middleware<R, M, PathA, CookieA, QueryA, BodyA, HeaderA, ReqA, ResA, ResE, MiddlewareE, PPath, R2, PR, CTX, Context, Config>): Effect.Effect<HttpRouter.Route<import("@effect/platform/HttpServerError").RequestError, import("../../services/RequestContextContainer.js").RequestContextContainer | import("../../services/Store/ContextMapContainer.js").ContextMapContainer | import("@effect-app/infra-adapters/RequestFiberSet").RequestFiberSet | Exclude<R2, HttpRouter.HttpRouter.Provided> | Exclude<RErr, HttpRouter.HttpRouter.Provided> | Exclude<Exclude<Exclude<R, import("effect-app/utils").EnforceNonEmptyRecord<M>>, PR>, HttpRouter.HttpRouter.Provided>>, never, never>;
12
12
  //# sourceMappingURL=match.d.ts.map
@@ -0,0 +1,121 @@
1
+ import type { EffectUnunified, LowerServices } from "@effect-app/core/Effect";
2
+ import type { EnforceNonEmptyRecord } from "@effect-app/core/utils";
3
+ import type { _R, EffectDeps, Extr, ReqFromSchema } from "@effect-app/infra/api/routing";
4
+ import type { Types } from "effect-app";
5
+ import { Effect, S } from "effect-app";
6
+ import type { ValidationError } from "effect-app/client/errors";
7
+ import { HttpRouter } from "effect-app/http";
8
+ import { REST } from "effect-app/schema";
9
+ export type RouteMatch<R, M, PR = never> = HttpRouter.Route<never, Exclude<Exclude<R, EnforceNonEmptyRecord<M>>, PR>>;
10
+ export interface Hint<Err extends string> {
11
+ Err: Err;
12
+ }
13
+ export declare const makeRouter: <CTX, CTXMap extends Record<string, [string, any, boolean]>>(handleRequestEnv: any) => {
14
+ matchFor: <Rsc extends Record<string, any>>(rsc: Rsc) => {
15
+ controllers: <THandlers extends { [K in keyof { [K_1 in keyof Rsc as Rsc[K_1] extends {
16
+ Response: any;
17
+ } ? K_1 : never]: Rsc[K_1] extends {
18
+ Response: any;
19
+ } ? Rsc[K_1] : never; }]: {
20
+ new (): {};
21
+ _tag: "raw";
22
+ handler: (req: S.Schema.Type<REST.GetRequest<Rsc[K]>>, ctx: CTX & { [key in keyof CTXMap as key extends keyof REST.GetRequest<Rsc[K]> ? REST.GetRequest<Rsc[K]>[key] extends true ? CTXMap[key][0] : never : never]?: CTXMap[key][1]; } & { [key_1 in keyof CTXMap as key_1 extends keyof REST.GetRequest<Rsc[K]> ? REST.GetRequest<Rsc[K]>[key_1] extends false ? CTXMap[key_1][0] : never : CTXMap[key_1][0]]: CTXMap[key_1][1]; }) => Effect<S.Schema.Encoded<Extr<REST.GetResponse<Rsc[K]>>>, import("effect-app/client/errors").OptimisticConcurrencyException | S.ParseResult.ParseError | ValidationError | import("effect-app/client/errors").InvalidStateError | import("effect-app/client/errors").NotFoundError<ItemType> | import("effect-app/client/errors").NotLoggedInError | import("effect-app/client/errors").LoginError | import("effect-app/client/errors").UnauthorizedError | import("effect-app/client/errors").ServiceUnavailableError | S.Schema.Type<REST.GetRequest<Rsc[K]>["failure"]>, any>;
23
+ } | {
24
+ new (): {};
25
+ _tag: "d";
26
+ handler: (req: S.Schema.Type<REST.GetRequest<Rsc[K]>>, ctx: CTX & { [key in keyof CTXMap as key extends keyof REST.GetRequest<Rsc[K]> ? REST.GetRequest<Rsc[K]>[key] extends true ? CTXMap[key][0] : never : never]?: CTXMap[key][1]; } & { [key_1 in keyof CTXMap as key_1 extends keyof REST.GetRequest<Rsc[K]> ? REST.GetRequest<Rsc[K]>[key_1] extends false ? CTXMap[key_1][0] : never : CTXMap[key_1][0]]: CTXMap[key_1][1]; }) => Effect<S.Schema.Type<Extr<REST.GetResponse<Rsc[K]>>>, import("effect-app/client/errors").OptimisticConcurrencyException | S.ParseResult.ParseError | ValidationError | import("effect-app/client/errors").InvalidStateError | import("effect-app/client/errors").NotFoundError<ItemType> | import("effect-app/client/errors").NotLoggedInError | import("effect-app/client/errors").LoginError | import("effect-app/client/errors").UnauthorizedError | import("effect-app/client/errors").ServiceUnavailableError | S.Schema.Type<REST.GetRequest<Rsc[K]>["failure"]>, any>;
27
+ }; }>(controllers: THandlers) => HttpRouter.HttpRouter<[(keyof { [K_1 in keyof Rsc as Rsc[K_1] extends {
28
+ Response: any;
29
+ } ? K_1 : never]: Rsc[K_1] extends {
30
+ Response: any;
31
+ } ? Rsc[K_1] : never; } extends infer T extends keyof { [K_1 in keyof Rsc as Rsc[K_1] extends {
32
+ Response: any;
33
+ } ? K_1 : never]: Rsc[K_1] extends {
34
+ Response: any;
35
+ } ? Rsc[K_1] : never; } ? { [K in T]: RouteMatch<_R<ReturnType<THandlers[K]["handler"]>>, ReqFromSchema<REST.GetRequest<Rsc[K]>>, { [key in keyof CTXMap as key extends keyof REST.GetRequest<Rsc[K]> ? REST.GetRequest<Rsc[K]>[key] extends true ? never : CTXMap[key][0] : CTXMap[key][0]]: CTXMap[key][1]; }[keyof { [key in keyof CTXMap as key extends keyof REST.GetRequest<Rsc[K]> ? REST.GetRequest<Rsc[K]>[key] extends true ? never : CTXMap[key][0] : CTXMap[key][0]]: CTXMap[key][1]; }]>; } : never)[keyof { [K_1 in keyof Rsc as Rsc[K_1] extends {
36
+ Response: any;
37
+ } ? K_1 : never]: Rsc[K_1] extends {
38
+ Response: any;
39
+ } ? Rsc[K_1] : never; }]] extends [HttpRouter.Route<infer E, any>] ? E : never, [(keyof { [K_1 in keyof Rsc as Rsc[K_1] extends {
40
+ Response: any;
41
+ } ? K_1 : never]: Rsc[K_1] extends {
42
+ Response: any;
43
+ } ? Rsc[K_1] : never; } extends infer T extends keyof { [K_1 in keyof Rsc as Rsc[K_1] extends {
44
+ Response: any;
45
+ } ? K_1 : never]: Rsc[K_1] extends {
46
+ Response: any;
47
+ } ? Rsc[K_1] : never; } ? { [K in T]: RouteMatch<_R<ReturnType<THandlers[K]["handler"]>>, ReqFromSchema<REST.GetRequest<Rsc[K]>>, { [key in keyof CTXMap as key extends keyof REST.GetRequest<Rsc[K]> ? REST.GetRequest<Rsc[K]>[key] extends true ? never : CTXMap[key][0] : CTXMap[key][0]]: CTXMap[key][1]; }[keyof { [key in keyof CTXMap as key extends keyof REST.GetRequest<Rsc[K]> ? REST.GetRequest<Rsc[K]>[key] extends true ? never : CTXMap[key][0] : CTXMap[key][0]]: CTXMap[key][1]; }]>; } : never)[keyof { [K_1 in keyof Rsc as Rsc[K_1] extends {
48
+ Response: any;
49
+ } ? K_1 : never]: Rsc[K_1] extends {
50
+ Response: any;
51
+ } ? Rsc[K_1] : never; }]] extends [HttpRouter.Route<any, infer R>] ? R : never>;
52
+ } & { [Key in keyof { [K_1 in keyof Rsc as Rsc[K_1] extends {
53
+ Response: any;
54
+ } ? K_1 : never]: Rsc[K_1] extends {
55
+ Response: any;
56
+ } ? Rsc[K_1] : never; }]: {
57
+ <R2, E, A>(f: Effect<A, E, R2>): S.Schema.Type<REST.GetResponse<Rsc[Key]>> extends infer T ? T extends S.Schema.Type<REST.GetResponse<Rsc[Key]>> ? T extends void ? A extends void ? {
58
+ new (): {};
59
+ _tag: "d";
60
+ handler: (req: S.Schema.Type<REST.GetRequest<Rsc[Key]>>, ctx: Types.Simplify<CTX & { [key in keyof CTXMap as key extends keyof REST.GetRequest<Rsc[Key]> ? REST.GetRequest<Rsc[Key]>[key] extends true ? CTXMap[key][0] : never : never]?: CTXMap[key][1]; } & { [key_1 in keyof CTXMap as key_1 extends keyof REST.GetRequest<Rsc[Key]> ? REST.GetRequest<Rsc[Key]>[key_1] extends false ? CTXMap[key_1][0] : never : CTXMap[key_1][0]]: CTXMap[key_1][1]; }>) => Effect<A, E, R2>;
61
+ } : Hint<"You're returning non void for a void Response, please fix"> : {
62
+ new (): {};
63
+ _tag: "d";
64
+ handler: (req: S.Schema.Type<REST.GetRequest<Rsc[Key]>>, ctx: Types.Simplify<CTX & { [key in keyof CTXMap as key extends keyof REST.GetRequest<Rsc[Key]> ? REST.GetRequest<Rsc[Key]>[key] extends true ? CTXMap[key][0] : never : never]?: CTXMap[key][1]; } & { [key_1 in keyof CTXMap as key_1 extends keyof REST.GetRequest<Rsc[Key]> ? REST.GetRequest<Rsc[Key]>[key_1] extends false ? CTXMap[key_1][0] : never : CTXMap[key_1][0]]: CTXMap[key_1][1]; }>) => Effect<A, E, R2>;
65
+ } : never : never;
66
+ <R2, E_1, A_1>(f: (req: S.Schema.Type<REST.GetRequest<Rsc[Key]>>, ctx: CTX & { [key in keyof CTXMap as key extends keyof REST.GetRequest<Rsc[Key]> ? REST.GetRequest<Rsc[Key]>[key] extends true ? CTXMap[key][0] : never : never]?: CTXMap[key][1]; } & { [key_1 in keyof CTXMap as key_1 extends keyof REST.GetRequest<Rsc[Key]> ? REST.GetRequest<Rsc[Key]>[key_1] extends false ? CTXMap[key_1][0] : never : CTXMap[key_1][0]]: CTXMap[key_1][1]; } & Pick<Rsc[Key], "Response">) => Effect<A_1, E_1, R2>): S.Schema.Type<REST.GetResponse<Rsc[Key]>> extends infer T ? T extends S.Schema.Type<REST.GetResponse<Rsc[Key]>> ? T extends void ? A_1 extends void ? {
67
+ new (): {};
68
+ _tag: "d";
69
+ handler: (req: S.Schema.Type<REST.GetRequest<Rsc[Key]>>, ctx: Types.Simplify<CTX & { [key in keyof CTXMap as key extends keyof REST.GetRequest<Rsc[Key]> ? REST.GetRequest<Rsc[Key]>[key] extends true ? CTXMap[key][0] : never : never]?: CTXMap[key][1]; } & { [key_1 in keyof CTXMap as key_1 extends keyof REST.GetRequest<Rsc[Key]> ? REST.GetRequest<Rsc[Key]>[key_1] extends false ? CTXMap[key_1][0] : never : CTXMap[key_1][0]]: CTXMap[key_1][1]; }>) => Effect<A_1, E_1, R2>;
70
+ } : Hint<"You're returning non void for a void Response, please fix"> : {
71
+ new (): {};
72
+ _tag: "d";
73
+ handler: (req: S.Schema.Type<REST.GetRequest<Rsc[Key]>>, ctx: Types.Simplify<CTX & { [key in keyof CTXMap as key extends keyof REST.GetRequest<Rsc[Key]> ? REST.GetRequest<Rsc[Key]>[key] extends true ? CTXMap[key][0] : never : never]?: CTXMap[key][1]; } & { [key_1 in keyof CTXMap as key_1 extends keyof REST.GetRequest<Rsc[Key]> ? REST.GetRequest<Rsc[Key]>[key_1] extends false ? CTXMap[key_1][0] : never : CTXMap[key_1][0]]: CTXMap[key_1][1]; }>) => Effect<A_1, E_1, R2>;
74
+ } : never : never;
75
+ <SVC extends Record<string, EffectUnunified<any, any, any>>, R2, E_2, A_2>(services: SVC, f: (req: S.Schema.Type<REST.GetRequest<Rsc[Key]>>, ctx: import("@effect-app/core/utils").ComputeFlat<LowerServices<EffectDeps<SVC>> & CTX & { [key in keyof CTXMap as key extends keyof REST.GetRequest<Rsc[Key]> ? REST.GetRequest<Rsc[Key]>[key] extends true ? CTXMap[key][0] : never : never]?: CTXMap[key][1]; } & { [key_1 in keyof CTXMap as key_1 extends keyof REST.GetRequest<Rsc[Key]> ? REST.GetRequest<Rsc[Key]>[key_1] extends false ? CTXMap[key_1][0] : never : CTXMap[key_1][0]]: CTXMap[key_1][1]; } & Pick<Rsc[Key], "Response">>) => Effect<A_2, E_2, R2>): S.Schema.Type<REST.GetResponse<Rsc[Key]>> extends infer T ? T extends S.Schema.Type<REST.GetResponse<Rsc[Key]>> ? T extends void ? A_2 extends void ? {
76
+ new (): {};
77
+ _tag: "d";
78
+ handler: (req: S.Schema.Type<REST.GetRequest<Rsc[Key]>>, ctx: Types.Simplify<CTX & { [key in keyof CTXMap as key extends keyof REST.GetRequest<Rsc[Key]> ? REST.GetRequest<Rsc[Key]>[key] extends true ? CTXMap[key][0] : never : never]?: CTXMap[key][1]; } & { [key_1 in keyof CTXMap as key_1 extends keyof REST.GetRequest<Rsc[Key]> ? REST.GetRequest<Rsc[Key]>[key_1] extends false ? CTXMap[key_1][0] : never : CTXMap[key_1][0]]: CTXMap[key_1][1]; }>) => Effect<A_2, E_2, R2>;
79
+ } : Hint<"You're returning non void for a void Response, please fix"> : {
80
+ new (): {};
81
+ _tag: "d";
82
+ handler: (req: S.Schema.Type<REST.GetRequest<Rsc[Key]>>, ctx: Types.Simplify<CTX & { [key in keyof CTXMap as key extends keyof REST.GetRequest<Rsc[Key]> ? REST.GetRequest<Rsc[Key]>[key] extends true ? CTXMap[key][0] : never : never]?: CTXMap[key][1]; } & { [key_1 in keyof CTXMap as key_1 extends keyof REST.GetRequest<Rsc[Key]> ? REST.GetRequest<Rsc[Key]>[key_1] extends false ? CTXMap[key_1][0] : never : CTXMap[key_1][0]]: CTXMap[key_1][1]; }>) => Effect<A_2, E_2, R2>;
83
+ } : never : never;
84
+ }; } & { [Key_1 in keyof { [K_1 in keyof Rsc as Rsc[K_1] extends {
85
+ Response: any;
86
+ } ? K_1 : never]: Rsc[K_1] extends {
87
+ Response: any;
88
+ } ? Rsc[K_1] : never; } as Key_1 extends string ? `${Key_1}Raw` : never]: {
89
+ <R2_1, E, A>(f: Effect<A, E, R2_1>): S.Schema.Type<REST.GetResponse<Rsc[Key_1]>> extends infer T ? T extends S.Schema.Type<REST.GetResponse<Rsc[Key_1]>> ? T extends void ? A extends void ? {
90
+ new (): {};
91
+ _tag: "raw";
92
+ handler: (req: S.Schema.Type<REST.GetRequest<Rsc[Key_1]>>, ctx: Types.Simplify<CTX & { [key in keyof CTXMap as key extends keyof REST.GetRequest<Rsc[Key_1]> ? REST.GetRequest<Rsc[Key_1]>[key] extends true ? CTXMap[key][0] : never : never]?: CTXMap[key][1]; } & { [key_1 in keyof CTXMap as key_1 extends keyof REST.GetRequest<Rsc[Key_1]> ? REST.GetRequest<Rsc[Key_1]>[key_1] extends false ? CTXMap[key_1][0] : never : CTXMap[key_1][0]]: CTXMap[key_1][1]; }>) => Effect<A, E, R2_1>;
93
+ } : Hint<"You're returning non void for a void Response, please fix"> : {
94
+ new (): {};
95
+ _tag: "raw";
96
+ handler: (req: S.Schema.Type<REST.GetRequest<Rsc[Key_1]>>, ctx: Types.Simplify<CTX & { [key in keyof CTXMap as key extends keyof REST.GetRequest<Rsc[Key_1]> ? REST.GetRequest<Rsc[Key_1]>[key] extends true ? CTXMap[key][0] : never : never]?: CTXMap[key][1]; } & { [key_1 in keyof CTXMap as key_1 extends keyof REST.GetRequest<Rsc[Key_1]> ? REST.GetRequest<Rsc[Key_1]>[key_1] extends false ? CTXMap[key_1][0] : never : CTXMap[key_1][0]]: CTXMap[key_1][1]; }>) => Effect<A, E, R2_1>;
97
+ } : never : never;
98
+ <R2_1, E_1, A_1>(f: (req: S.Schema.Type<REST.GetRequest<Rsc[Key_1]>>, ctx: CTX & { [key in keyof CTXMap as key extends keyof REST.GetRequest<Rsc[Key_1]> ? REST.GetRequest<Rsc[Key_1]>[key] extends true ? CTXMap[key][0] : never : never]?: CTXMap[key][1]; } & { [key_1 in keyof CTXMap as key_1 extends keyof REST.GetRequest<Rsc[Key_1]> ? REST.GetRequest<Rsc[Key_1]>[key_1] extends false ? CTXMap[key_1][0] : never : CTXMap[key_1][0]]: CTXMap[key_1][1]; } & Pick<Rsc[Key_1], "Response">) => Effect<A_1, E_1, R2_1>): S.Schema.Type<REST.GetResponse<Rsc[Key_1]>> extends infer T ? T extends S.Schema.Type<REST.GetResponse<Rsc[Key_1]>> ? T extends void ? A_1 extends void ? {
99
+ new (): {};
100
+ _tag: "raw";
101
+ handler: (req: S.Schema.Type<REST.GetRequest<Rsc[Key_1]>>, ctx: Types.Simplify<CTX & { [key in keyof CTXMap as key extends keyof REST.GetRequest<Rsc[Key_1]> ? REST.GetRequest<Rsc[Key_1]>[key] extends true ? CTXMap[key][0] : never : never]?: CTXMap[key][1]; } & { [key_1 in keyof CTXMap as key_1 extends keyof REST.GetRequest<Rsc[Key_1]> ? REST.GetRequest<Rsc[Key_1]>[key_1] extends false ? CTXMap[key_1][0] : never : CTXMap[key_1][0]]: CTXMap[key_1][1]; }>) => Effect<A_1, E_1, R2_1>;
102
+ } : Hint<"You're returning non void for a void Response, please fix"> : {
103
+ new (): {};
104
+ _tag: "raw";
105
+ handler: (req: S.Schema.Type<REST.GetRequest<Rsc[Key_1]>>, ctx: Types.Simplify<CTX & { [key in keyof CTXMap as key extends keyof REST.GetRequest<Rsc[Key_1]> ? REST.GetRequest<Rsc[Key_1]>[key] extends true ? CTXMap[key][0] : never : never]?: CTXMap[key][1]; } & { [key_1 in keyof CTXMap as key_1 extends keyof REST.GetRequest<Rsc[Key_1]> ? REST.GetRequest<Rsc[Key_1]>[key_1] extends false ? CTXMap[key_1][0] : never : CTXMap[key_1][0]]: CTXMap[key_1][1]; }>) => Effect<A_1, E_1, R2_1>;
106
+ } : never : never;
107
+ <SVC extends Record<string, EffectUnunified<any, any, any>>, R2, E_2, A_2>(services: SVC, f: (req: S.Schema.Type<REST.GetRequest<Rsc[Key_1]>>, ctx: import("@effect-app/core/utils").ComputeFlat<LowerServices<EffectDeps<SVC>> & CTX & { [key in keyof CTXMap as key extends keyof REST.GetRequest<Rsc[Key_1]> ? REST.GetRequest<Rsc[Key_1]>[key] extends true ? CTXMap[key][0] : never : never]?: CTXMap[key][1]; } & { [key_1 in keyof CTXMap as key_1 extends keyof REST.GetRequest<Rsc[Key_1]> ? REST.GetRequest<Rsc[Key_1]>[key_1] extends false ? CTXMap[key_1][0] : never : CTXMap[key_1][0]]: CTXMap[key_1][1]; } & Pick<Rsc[Key_1], "Response">>) => Effect<A_2, E_2, R2>): S.Schema.Type<REST.GetResponse<Rsc[Key_1]>> extends infer T ? T extends S.Schema.Type<REST.GetResponse<Rsc[Key_1]>> ? T extends void ? A_2 extends void ? {
108
+ new (): {};
109
+ _tag: "raw";
110
+ handler: (req: S.Schema.Type<REST.GetRequest<Rsc[Key_1]>>, ctx: Types.Simplify<CTX & { [key in keyof CTXMap as key extends keyof REST.GetRequest<Rsc[Key_1]> ? REST.GetRequest<Rsc[Key_1]>[key] extends true ? CTXMap[key][0] : never : never]?: CTXMap[key][1]; } & { [key_1 in keyof CTXMap as key_1 extends keyof REST.GetRequest<Rsc[Key_1]> ? REST.GetRequest<Rsc[Key_1]>[key_1] extends false ? CTXMap[key_1][0] : never : CTXMap[key_1][0]]: CTXMap[key_1][1]; }>) => Effect<A_2, E_2, R2>;
111
+ } : Hint<"You're returning non void for a void Response, please fix"> : {
112
+ new (): {};
113
+ _tag: "raw";
114
+ handler: (req: S.Schema.Type<REST.GetRequest<Rsc[Key_1]>>, ctx: Types.Simplify<CTX & { [key in keyof CTXMap as key extends keyof REST.GetRequest<Rsc[Key_1]> ? REST.GetRequest<Rsc[Key_1]>[key] extends true ? CTXMap[key][0] : never : never]?: CTXMap[key][1]; } & { [key_1 in keyof CTXMap as key_1 extends keyof REST.GetRequest<Rsc[Key_1]> ? REST.GetRequest<Rsc[Key_1]>[key_1] extends false ? CTXMap[key_1][0] : never : CTXMap[key_1][0]]: CTXMap[key_1][1]; }>) => Effect<A_2, E_2, R2>;
115
+ } : never : never;
116
+ }; };
117
+ matchAll: <T extends {
118
+ [key: string]: HttpRouter.HttpRouter<any, any>;
119
+ }>(handlers: T) => HttpRouter.HttpRouter<[T[keyof T]] extends [HttpRouter.HttpRouter<infer R, any>] ? R : never, [T[keyof T]] extends [HttpRouter.HttpRouter<any, infer E_3>] ? E_3 : never>;
120
+ };
121
+ //# sourceMappingURL=router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"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"}
package/dist/router.js ADDED
@@ -0,0 +1,136 @@
1
+ import { allLower } from "@effect-app/core/Effect";
2
+ import { typedKeysOf } from "@effect-app/core/utils";
3
+ import { defaultErrorHandler, makeRequestHandler } from "@effect-app/infra/api/routing";
4
+ import { Effect, Predicate, S } from "effect-app";
5
+ import { HttpRouter } from "effect-app/http";
6
+ import { REST } from "effect-app/schema";
7
+ // TODO: support FLIP
8
+ export const makeRouter = (handleRequestEnv /* Middleware */) => {
9
+ function match(requestHandler, errorHandler, middleware) {
10
+ let middlewareLayer = undefined;
11
+ if (middleware) {
12
+ const { handler, makeRequestLayer } = middleware(requestHandler);
13
+ requestHandler = handler; // todo
14
+ middlewareLayer = makeRequestLayer;
15
+ }
16
+ // const rdesc = yield* RouteDescriptors.flatMap((_) => _.get)
17
+ const handler = makeRequestHandler(requestHandler, // one argument if no middleware, 2 if has middleware. TODO: clean this shit up
18
+ errorHandler, middlewareLayer);
19
+ const route = HttpRouter.makeRoute(requestHandler.Request.method, requestHandler.Request.path, handler);
20
+ // TODO
21
+ // rdesc.push(makeRouteDescriptor(
22
+ // requestHandler.Request.path,
23
+ // requestHandler.Request.method,
24
+ // requestHandler
25
+ // ))
26
+ return route;
27
+ }
28
+ function handle(_, name, adaptResponse) {
29
+ const Request = S.REST.extractRequest(_);
30
+ const Response = S.REST.extractResponse(_);
31
+ return (h) => ({
32
+ adaptResponse,
33
+ h: h.handler,
34
+ name,
35
+ Request,
36
+ Response,
37
+ ResponseOpenApi: _.ResponseOpenApi ?? Response,
38
+ Context: null,
39
+ CTX: null,
40
+ rt: h._tag
41
+ });
42
+ }
43
+ function matchFor(rsc) {
44
+ const filtered = typedKeysOf(rsc).reduce((acc, cur) => {
45
+ if (Predicate.isObject(rsc[cur]) && rsc[cur].Request) {
46
+ acc[cur] = rsc[cur];
47
+ }
48
+ return acc;
49
+ }, {});
50
+ const matchWithServices = (action) => {
51
+ return (services, f) => (req, ctx) => Effect.andThen(allLower(services), (svc2) => f(req, { ...ctx, ...svc2, Response: rsc[action].Response }));
52
+ };
53
+ const controllers = (controllers) => {
54
+ const handlers = typedKeysOf(filtered).reduce((acc, cur) => {
55
+ if (cur === "meta")
56
+ return acc;
57
+ const m = rsc.meta;
58
+ if (!m)
59
+ throw new Error("Resource has no meta specified");
60
+ acc[cur] = handle(rsc[cur], m.moduleName + "." + cur)(controllers[cur]);
61
+ return acc;
62
+ }, {});
63
+ const mapped = typedKeysOf(handlers).reduce((acc, cur) => {
64
+ const handler = handlers[cur];
65
+ const req = handler.Request;
66
+ class Request extends req {
67
+ static path = "/" + handler.name + (req.path === "/" ? "" : req.path);
68
+ static method = req.method === "AUTO"
69
+ ? REST.determineMethod(handler.name.split(".")[1], req)
70
+ : req.method;
71
+ }
72
+ if (req.method === "AUTO") {
73
+ Object.assign(Request, {
74
+ [Request.method === "GET" || Request.method === "DELETE" ? "Query" : "Body"]: req.Auto
75
+ });
76
+ }
77
+ Object.assign(handler, { Request });
78
+ acc[cur] = match(handler, errorHandler(req), handleRequestEnv // TODO
79
+ );
80
+ return acc;
81
+ }, {});
82
+ return HttpRouter.fromIterable(Object.values(mapped));
83
+ };
84
+ const r = {
85
+ controllers,
86
+ ...typedKeysOf(filtered).reduce((prev, cur) => {
87
+ ;
88
+ prev[cur] = (svcOrFnOrEffect, fnOrNone) => Effect.isEffect(svcOrFnOrEffect)
89
+ ? class {
90
+ static _tag = "d";
91
+ static handler = () => svcOrFnOrEffect;
92
+ }
93
+ : typeof svcOrFnOrEffect === "function"
94
+ ? class {
95
+ static _tag = "d";
96
+ static handler = (req, ctx) => svcOrFnOrEffect(req, { ...ctx, Response: rsc[cur].Response });
97
+ }
98
+ : class {
99
+ static _tag = "d";
100
+ static handler = matchWithServices(cur)(svcOrFnOrEffect, fnOrNone);
101
+ };
102
+ prev[cur + "Raw"] = (svcOrFnOrEffect, fnOrNone) => Effect.isEffect(svcOrFnOrEffect)
103
+ ? class {
104
+ static _tag = "raw";
105
+ static handler = () => svcOrFnOrEffect;
106
+ }
107
+ : typeof svcOrFnOrEffect === "function"
108
+ ? class {
109
+ static _tag = "raw";
110
+ static handler = (req, ctx) => svcOrFnOrEffect(req, { ...ctx, Response: rsc[cur].Response });
111
+ }
112
+ : class {
113
+ static _tag = "raw";
114
+ static handler = matchWithServices(cur)(svcOrFnOrEffect, fnOrNone);
115
+ };
116
+ return prev;
117
+ }, {})
118
+ };
119
+ return r;
120
+ }
121
+ const errorHandler = (resourceRequest) => {
122
+ return (req, res, r2) => defaultErrorHandler(req, res, Effect.catchTag(r2, "ParseError", (_) => Effect.die(_)), resourceRequest.failure);
123
+ };
124
+ /**
125
+ * Gather all handlers of a module and attach them to the Server.
126
+ * If no `allowAnonymous` flag is on the Request, will require a valid authenticated user.
127
+ */
128
+ function matchAll(handlers) {
129
+ const r = typedKeysOf(handlers).reduce((acc, cur) => {
130
+ return HttpRouter.concat(acc, handlers[cur]);
131
+ }, HttpRouter.empty);
132
+ return r;
133
+ }
134
+ return { matchFor, matchAll };
135
+ };
136
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3JvdXRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFHQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0seUJBQXlCLENBQUE7QUFDbEQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHdCQUF3QixDQUFBO0FBY3BELE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxrQkFBa0IsRUFBRSxNQUFNLCtCQUErQixDQUFBO0FBRXZGLE9BQU8sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLENBQUMsRUFBRSxNQUFNLFlBQVksQ0FBQTtBQUVqRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0saUJBQWlCLENBQUE7QUFHNUMsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLG1CQUFtQixDQUFBO0FBZ0J4QyxxQkFBcUI7QUFDckIsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHLENBQ3hCLGdCQUFxQixDQUFDLGdCQUFnQixFQUN0QyxFQUFFO0lBb0JGLFNBQVMsS0FBSyxDQW9CWixjQWVDLEVBQ0QsWUFRQyxFQUNELFVBa0JDO1FBRUQsSUFBSSxlQUFlLEdBQTJDLFNBQVMsQ0FBQTtRQUN2RSxJQUFJLFVBQVUsRUFBRSxDQUFDO1lBQ2YsTUFBTSxFQUFFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxHQUFHLFVBQVUsQ0FBQyxjQUFjLENBQUMsQ0FBQTtZQUNoRSxjQUFjLEdBQUcsT0FBYyxDQUFBLENBQUMsT0FBTztZQUN2QyxlQUFlLEdBQUcsZ0JBQWdCLENBQUE7UUFDcEMsQ0FBQztRQUNELDhEQUE4RDtRQUU5RCxNQUFNLE9BQU8sR0FBRyxrQkFBa0IsQ0FrQmhDLGNBQXFCLEVBQUUsK0VBQStFO1FBQ3RHLFlBQVksRUFDWixlQUFlLENBQ2hCLENBQUE7UUFFRCxNQUFNLEtBQUssR0FBRyxVQUFVLENBQUMsU0FBUyxDQUNoQyxjQUFjLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFDN0IsY0FBYyxDQUFDLE9B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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effect-app/infra",
3
- "version": "1.14.4",
3
+ "version": "1.16.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "dependencies": {
@@ -18,10 +18,10 @@
18
18
  "proper-lockfile": "^4.1.2",
19
19
  "pure-rand": "6.1.0",
20
20
  "redlock": "^4.2.0",
21
- "@effect-app/core": "1.8.1",
22
- "effect-app": "1.13.4",
23
- "@effect-app/schema": "1.10.1",
24
- "@effect-app/infra-adapters": "1.9.4"
21
+ "@effect-app/core": "1.9.0",
22
+ "effect-app": "1.15.0",
23
+ "@effect-app/schema": "1.11.0",
24
+ "@effect-app/infra-adapters": "1.10.1"
25
25
  },
26
26
  "devDependencies": {
27
27
  "@babel/cli": "^7.25.6",
@@ -42,9 +42,9 @@
42
42
  },
43
43
  "peerDependencies": {
44
44
  "express": "^4.21.0",
45
- "@effect/platform": "^0.65.2",
46
- "@effect/schema": "^0.73.1",
47
- "effect": "^3.8.1"
45
+ "@effect/platform": "^0.65.5",
46
+ "@effect/schema": "^0.73.4",
47
+ "effect": "^3.8.3"
48
48
  },
49
49
  "typesVersions": {
50
50
  "*": {
@@ -334,6 +334,16 @@
334
334
  "default": "./_cjs/rateLimit.cjs"
335
335
  }
336
336
  },
337
+ "./router": {
338
+ "import": {
339
+ "types": "./dist/router.d.ts",
340
+ "default": "./dist/router.js"
341
+ },
342
+ "require": {
343
+ "types": "./dist/router.d.ts",
344
+ "default": "./_cjs/router.cjs"
345
+ }
346
+ },
337
347
  "./services/Emailer": {
338
348
  "import": {
339
349
  "types": "./dist/services/Emailer.d.ts",
package/src/router.ts ADDED
@@ -0,0 +1,547 @@
1
+ /* eslint-disable @typescript-eslint/no-empty-object-type */
2
+ /* eslint-disable @typescript-eslint/no-explicit-any */
3
+ import type { EffectUnunified, LowerServices } from "@effect-app/core/Effect"
4
+ import { allLower } from "@effect-app/core/Effect"
5
+ import { typedKeysOf } from "@effect-app/core/utils"
6
+ import type { Compute, EnforceNonEmptyRecord } from "@effect-app/core/utils"
7
+ import type {
8
+ _E,
9
+ _R,
10
+ EffectDeps,
11
+ Extr,
12
+ JWTError,
13
+ Middleware,
14
+ ReqFromSchema,
15
+ ReqHandler,
16
+ RequestHandler,
17
+ ResFromSchema
18
+ } from "@effect-app/infra/api/routing"
19
+ import { defaultErrorHandler, makeRequestHandler } from "@effect-app/infra/api/routing"
20
+ import type { Layer, Scope, Types } from "effect-app"
21
+ import { Effect, Predicate, S } from "effect-app"
22
+ import type { SupportedErrors, ValidationError } from "effect-app/client/errors"
23
+ import { HttpRouter } from "effect-app/http"
24
+ import type { HttpServerRequest, HttpServerResponse } from "effect-app/http"
25
+ import type { Struct } from "effect-app/schema"
26
+ import { REST } from "effect-app/schema"
27
+ import type {} from "@effect/schema/ParseResult"
28
+
29
+ export type RouteMatch<
30
+ R,
31
+ M,
32
+ // TODO: specific errors
33
+ // Err extends SupportedErrors | S.ParseResult.ParseError,
34
+ PR = never
35
+ > // RErr = never,
36
+ = HttpRouter.Route<never, Exclude<Exclude<R, EnforceNonEmptyRecord<M>>, PR>>
37
+
38
+ export interface Hint<Err extends string> {
39
+ Err: Err
40
+ }
41
+
42
+ // TODO: support FLIP
43
+ export const makeRouter = <CTX, CTXMap extends Record<string, [string, any, boolean]>>(
44
+ handleRequestEnv: any /* Middleware */
45
+ ) => {
46
+ type GetCTX<T> =
47
+ & CTX
48
+ & {
49
+ [key in keyof CTXMap as key extends keyof T ? T[key] extends true ? CTXMap[key][0] : never : never]?:
50
+ CTXMap[key][1]
51
+ }
52
+ & {
53
+ [key in keyof CTXMap as key extends keyof T ? T[key] extends false ? CTXMap[key][0] : never : CTXMap[key][0]]:
54
+ CTXMap[key][1]
55
+ }
56
+
57
+ type Values<T extends Record<any, any>> = T[keyof T]
58
+
59
+ type GetContext<T> = Values<
60
+ {
61
+ [key in keyof CTXMap as key extends keyof T ? T[key] extends true ? never : CTXMap[key][0] : CTXMap[key][0]]: // TODO: or as an Optional available?
62
+ CTXMap[key][1]
63
+ }
64
+ >
65
+ function match<
66
+ R,
67
+ M,
68
+ PathA extends Struct.Fields,
69
+ CookieA extends Struct.Fields,
70
+ QueryA extends Struct.Fields,
71
+ BodyA extends Struct.Fields,
72
+ HeaderA extends Struct.Fields,
73
+ ReqA extends PathA & QueryA & BodyA,
74
+ ResA extends Struct.Fields,
75
+ ResE,
76
+ MiddlewareE,
77
+ PPath extends `/${string}`,
78
+ R2,
79
+ PR,
80
+ RErr,
81
+ CTX,
82
+ Context,
83
+ Config
84
+ >(
85
+ requestHandler: RequestHandler<
86
+ R,
87
+ M,
88
+ PathA,
89
+ CookieA,
90
+ QueryA,
91
+ BodyA,
92
+ HeaderA,
93
+ ReqA,
94
+ ResA,
95
+ ResE,
96
+ PPath,
97
+ CTX,
98
+ Context,
99
+ Config
100
+ >,
101
+ errorHandler: <R>(
102
+ req: HttpServerRequest.HttpServerRequest,
103
+ res: HttpServerResponse.HttpServerResponse,
104
+ r2: Effect<HttpServerResponse.HttpServerResponse, ValidationError | MiddlewareE | ResE, R>
105
+ ) => Effect<
106
+ HttpServerResponse.HttpServerResponse,
107
+ never,
108
+ Exclude<RErr | R, HttpServerRequest.HttpServerRequest | HttpRouter.RouteContext | Scope>
109
+ >,
110
+ middleware?: Middleware<
111
+ R,
112
+ M,
113
+ PathA,
114
+ CookieA,
115
+ QueryA,
116
+ BodyA,
117
+ HeaderA,
118
+ ReqA,
119
+ ResA,
120
+ ResE,
121
+ MiddlewareE,
122
+ PPath,
123
+ R2,
124
+ PR,
125
+ CTX,
126
+ Context,
127
+ Config
128
+ >
129
+ ) {
130
+ let middlewareLayer: Layer<PR, MiddlewareE, R2> | undefined = undefined
131
+ if (middleware) {
132
+ const { handler, makeRequestLayer } = middleware(requestHandler)
133
+ requestHandler = handler as any // todo
134
+ middlewareLayer = makeRequestLayer
135
+ }
136
+ // const rdesc = yield* RouteDescriptors.flatMap((_) => _.get)
137
+
138
+ const handler = makeRequestHandler<
139
+ R,
140
+ M,
141
+ PathA,
142
+ CookieA,
143
+ QueryA,
144
+ BodyA,
145
+ HeaderA,
146
+ ReqA,
147
+ ResA,
148
+ ResE,
149
+ MiddlewareE,
150
+ R2,
151
+ PR,
152
+ RErr,
153
+ PPath,
154
+ Config
155
+ >(
156
+ requestHandler as any, // one argument if no middleware, 2 if has middleware. TODO: clean this shit up
157
+ errorHandler,
158
+ middlewareLayer
159
+ )
160
+
161
+ const route = HttpRouter.makeRoute(
162
+ requestHandler.Request.method,
163
+ requestHandler.Request.path,
164
+ handler
165
+ )
166
+ // TODO
167
+ // rdesc.push(makeRouteDescriptor(
168
+ // requestHandler.Request.path,
169
+ // requestHandler.Request.method,
170
+ // requestHandler
171
+ // ))
172
+ return route
173
+ }
174
+
175
+ function handle<
176
+ TModule extends Record<
177
+ string,
178
+ any
179
+ >
180
+ >(
181
+ _: TModule & { ResponseOpenApi?: any },
182
+ name: string,
183
+ adaptResponse?: any
184
+ ) {
185
+ const Request = S.REST.extractRequest(_)
186
+ const Response = S.REST.extractResponse(_)
187
+
188
+ type ReqSchema = S.REST.GetRequest<TModule>
189
+ type ResSchema = S.REST.GetResponse<TModule>
190
+ type Req = InstanceType<
191
+ ReqSchema extends { new(...args: any[]): any } ? ReqSchema
192
+ : never
193
+ >
194
+ type Res = S.Schema.Type<Extr<ResSchema>>
195
+
196
+ return <R, E>(
197
+ h: { _tag: "raw" | "d"; handler: (r: Req) => Effect<Res, E, R> }
198
+ ) => ({
199
+ adaptResponse,
200
+ h: h.handler,
201
+ name,
202
+ Request,
203
+ Response,
204
+ ResponseOpenApi: _.ResponseOpenApi ?? Response,
205
+ Context: null as any,
206
+ CTX: null as any,
207
+ rt: h._tag
208
+ } as ReqHandler<
209
+ Req,
210
+ R,
211
+ E,
212
+ Res,
213
+ ReqSchema,
214
+ ResSchema,
215
+ GetCTX<Req>,
216
+ GetContext<Req>
217
+ >)
218
+ }
219
+
220
+ type HandleVoid<Expected, Actual, Result> = Expected extends void
221
+ ? Actual extends void ? Result : Hint<"You're returning non void for a void Response, please fix">
222
+ : Result
223
+
224
+ function matchFor<Rsc extends Record<string, any>>(
225
+ rsc: Rsc
226
+ ) {
227
+ type Filtered = {
228
+ [K in keyof Rsc as Rsc[K] extends { Response: any } ? K : never]: Rsc[K] extends { Response: any } ? Rsc[K]
229
+ : never
230
+ }
231
+ const filtered = typedKeysOf(rsc).reduce((acc, cur) => {
232
+ if (Predicate.isObject(rsc[cur]) && rsc[cur].Request) {
233
+ acc[cur as keyof Filtered] = rsc[cur]
234
+ }
235
+ return acc
236
+ }, {} as Filtered)
237
+
238
+ const matchWithServices = <Key extends keyof Filtered>(action: Key) => {
239
+ type Req = ReqFromSchema<REST.GetRequest<Rsc[Key]>>
240
+ return <
241
+ SVC extends Record<
242
+ string,
243
+ Effect<any, any, any>
244
+ >,
245
+ R2,
246
+ E,
247
+ A
248
+ >(
249
+ services: SVC,
250
+ f: (
251
+ req: Req,
252
+ ctx: Compute<
253
+ LowerServices<EffectDeps<SVC>> & GetCTX<Req>,
254
+ "flat"
255
+ >
256
+ ) => Effect<A, E, R2>
257
+ ) =>
258
+ (req: any, ctx: any) =>
259
+ Effect.andThen(allLower(services), (svc2) => f(req, { ...ctx, ...svc2 as any, Response: rsc[action].Response }))
260
+ }
261
+
262
+ type MatchWithServicesNew<RT extends "raw" | "d", Key extends keyof Rsc> = {
263
+ <R2, E, A>(
264
+ f: Effect<A, E, R2>
265
+ ): HandleVoid<
266
+ S.Schema.Type<REST.GetResponse<Rsc[Key]>>,
267
+ A,
268
+ Handler<
269
+ ReqFromSchema<REST.GetRequest<Rsc[Key]>>,
270
+ Types.Simplify<GetCTX<REST.GetRequest<Rsc[Key]>>>,
271
+ RT,
272
+ A,
273
+ E,
274
+ R2
275
+ >
276
+ >
277
+ <R2, E, A>(
278
+ f: (
279
+ req: ReqFromSchema<REST.GetRequest<Rsc[Key]>>,
280
+ ctx: GetCTX<REST.GetRequest<Rsc[Key]>> & Pick<Rsc[Key], "Response">
281
+ ) => Effect<A, E, R2>
282
+ ): HandleVoid<
283
+ S.Schema.Type<REST.GetResponse<Rsc[Key]>>,
284
+ A,
285
+ Handler<
286
+ ReqFromSchema<REST.GetRequest<Rsc[Key]>>,
287
+ Types.Simplify<GetCTX<REST.GetRequest<Rsc[Key]>>>,
288
+ RT,
289
+ A,
290
+ E,
291
+ R2
292
+ >
293
+ >
294
+
295
+ <
296
+ SVC extends Record<
297
+ string,
298
+ EffectUnunified<any, any, any>
299
+ >,
300
+ R2,
301
+ E,
302
+ A
303
+ >(
304
+ services: SVC,
305
+ f: (
306
+ req: ReqFromSchema<REST.GetRequest<Rsc[Key]>>,
307
+ ctx: Compute<
308
+ LowerServices<EffectDeps<SVC>> & GetCTX<REST.GetRequest<Rsc[Key]>> & Pick<Rsc[Key], "Response">,
309
+ "flat"
310
+ >
311
+ ) => Effect<A, E, R2>
312
+ ): HandleVoid<
313
+ S.Schema.Type<REST.GetResponse<Rsc[Key]>>,
314
+ A,
315
+ Handler<
316
+ ReqFromSchema<REST.GetRequest<Rsc[Key]>>,
317
+ Types.Simplify<GetCTX<REST.GetRequest<Rsc[Key]>>>,
318
+ RT,
319
+ A,
320
+ E,
321
+ R2
322
+ >
323
+ >
324
+ }
325
+
326
+ type Keys = keyof Filtered
327
+ type Handler<Req, Context, RT extends "raw" | "d", A, E, R> = {
328
+ new(): {}
329
+ _tag: RT
330
+ handler: (
331
+ req: Req,
332
+ ctx: Context
333
+ ) => Effect<
334
+ A,
335
+ E,
336
+ R
337
+ >
338
+ }
339
+
340
+ type AHandler<Action extends Record<string, any>> =
341
+ | Handler<
342
+ ReqFromSchema<REST.GetRequest<Action>>,
343
+ GetCTX<REST.GetRequest<Action>>,
344
+ "raw",
345
+ ResRawFromSchema<REST.GetResponse<Action>>,
346
+ SupportedErrors | S.ParseResult.ParseError | S.Schema.Type<REST.GetRequest<Action>["failure"]>,
347
+ any
348
+ >
349
+ | Handler<
350
+ ReqFromSchema<REST.GetRequest<Action>>,
351
+ GetCTX<REST.GetRequest<Action>>,
352
+ "d",
353
+ ResFromSchema<REST.GetResponse<Action>>,
354
+ SupportedErrors | S.ParseResult.ParseError | S.Schema.Type<REST.GetRequest<Action>["failure"]>,
355
+ any
356
+ >
357
+
358
+ const controllers = <
359
+ THandlers extends {
360
+ // import to keep them separate via | for type checking!!
361
+ [K in Keys]: AHandler<Rsc[K]>
362
+ }
363
+ >(
364
+ controllers: THandlers
365
+ ) => {
366
+ const handlers = typedKeysOf(filtered).reduce(
367
+ (acc, cur) => {
368
+ if (cur === "meta") return acc
369
+ const m = (rsc as any).meta as { moduleName: string }
370
+ if (!m) throw new Error("Resource has no meta specified")
371
+ ;(acc as any)[cur] = handle(
372
+ rsc[cur],
373
+ m.moduleName + "." + (cur as string)
374
+ )(controllers[cur as keyof typeof controllers] as any)
375
+ return acc
376
+ },
377
+ {} as {
378
+ [K in Keys]: ReqHandler<
379
+ ReqFromSchema<REST.GetRequest<Rsc[K]>>,
380
+ _R<ReturnType<THandlers[K]["handler"]>>,
381
+ _E<ReturnType<THandlers[K]["handler"]>>,
382
+ ResFromSchema<REST.GetResponse<Rsc[K]>>,
383
+ REST.GetRequest<Rsc[K]>,
384
+ REST.GetResponse<Rsc[K]>,
385
+ GetCTX<REST.GetRequest<Rsc[K]>>,
386
+ GetContext<REST.GetRequest<Rsc[K]>>
387
+ >
388
+ }
389
+ )
390
+
391
+ const mapped = typedKeysOf(handlers).reduce((acc, cur) => {
392
+ const handler = handlers[cur]
393
+ const req = handler.Request
394
+
395
+ class Request extends (req as any) {
396
+ static path = "/" + handler.name + (req.path === "/" ? "" : req.path)
397
+ static method = req.method === "AUTO"
398
+ ? REST.determineMethod(handler.name.split(".")[1]!, req)
399
+ : req.method
400
+ }
401
+ if (req.method === "AUTO") {
402
+ Object.assign(Request, {
403
+ [Request.method === "GET" || Request.method === "DELETE" ? "Query" : "Body"]: req.Auto
404
+ })
405
+ }
406
+ Object.assign(handler, { Request })
407
+ acc[cur] = match(
408
+ handler as any,
409
+ errorHandler(req),
410
+ handleRequestEnv // TODO
411
+ )
412
+ return acc
413
+ }, {} as any) as {
414
+ [K in Keys]: RouteMatch<
415
+ _R<ReturnType<THandlers[K]["handler"]>>,
416
+ ReqFromSchema<REST.GetRequest<Rsc[K]>>,
417
+ // _E<ReturnType<THandlers[K]["handler"]>>,
418
+ GetContext<REST.GetRequest<Rsc[K]>>
419
+ >
420
+ }
421
+
422
+ type _RRoute<T extends HttpRouter.Route<any, any>> = [T] extends [
423
+ HttpRouter.Route<any, infer R>
424
+ ] ? R
425
+ : never
426
+
427
+ type _ERoute<T extends HttpRouter.Route<any, any>> = [T] extends [
428
+ HttpRouter.Route<infer E, any>
429
+ ] ? E
430
+ : never
431
+
432
+ return HttpRouter.fromIterable(Object.values(mapped)) as HttpRouter.HttpRouter<
433
+ _ERoute<typeof mapped[keyof typeof mapped]>,
434
+ _RRoute<typeof mapped[keyof typeof mapped]>
435
+ >
436
+ }
437
+
438
+ type ResRawFromSchema<ResSchema> = S.Schema.Encoded<Extr<ResSchema>>
439
+
440
+ const r = {
441
+ controllers,
442
+ ...typedKeysOf(filtered).reduce(
443
+ (prev, cur) => {
444
+ ;(prev as any)[cur] = (svcOrFnOrEffect: any, fnOrNone: any) =>
445
+ Effect.isEffect(svcOrFnOrEffect)
446
+ ? class {
447
+ static _tag = "d"
448
+ static handler = () => svcOrFnOrEffect
449
+ }
450
+ : typeof svcOrFnOrEffect === "function"
451
+ ? class {
452
+ static _tag = "d"
453
+ static handler = (req: any, ctx: any) => svcOrFnOrEffect(req, { ...ctx, Response: rsc[cur].Response })
454
+ }
455
+ : class {
456
+ static _tag = "d"
457
+ static handler = matchWithServices(cur)(svcOrFnOrEffect, fnOrNone)
458
+ }
459
+ ;(prev as any)[(cur as any) + "Raw"] = (svcOrFnOrEffect: any, fnOrNone: any) =>
460
+ Effect.isEffect(svcOrFnOrEffect)
461
+ ? class {
462
+ static _tag = "raw"
463
+ static handler = () => svcOrFnOrEffect
464
+ }
465
+ : typeof svcOrFnOrEffect === "function"
466
+ ? class {
467
+ static _tag = "raw"
468
+ static handler = (req: any, ctx: any) => svcOrFnOrEffect(req, { ...ctx, Response: rsc[cur].Response })
469
+ }
470
+ : class {
471
+ static _tag = "raw"
472
+ static handler = matchWithServices(cur)(svcOrFnOrEffect, fnOrNone)
473
+ }
474
+ return prev
475
+ },
476
+ {} as
477
+ & {
478
+ // use Rsc as Key over using Keys, so that the Go To on X.Action remain in tact in Controllers files
479
+ [Key in keyof Filtered]: MatchWithServicesNew<"d", Key>
480
+ }
481
+ & {
482
+ // use Rsc as Key over using Keys, so that the Go To on X.Action remain in tact in Controllers files
483
+ [Key in keyof Filtered as Key extends string ? `${Key}Raw` : never]: MatchWithServicesNew<"raw", Key>
484
+ }
485
+ )
486
+ }
487
+ return r
488
+ }
489
+
490
+ const errorHandler = (resourceRequest: { failure?: S.Schema.AnyNoContext }) => {
491
+ return <R>(
492
+ req: HttpServerRequest.HttpServerRequest,
493
+ res: HttpServerResponse.HttpServerResponse,
494
+ r2: Effect<HttpServerResponse.HttpServerResponse, SupportedErrors | JWTError | S.ParseResult.ParseError, R>
495
+ ) => defaultErrorHandler(req, res, Effect.catchTag(r2, "ParseError", (_) => Effect.die(_)), resourceRequest.failure)
496
+ }
497
+
498
+ /**
499
+ * Gather all handlers of a module and attach them to the Server.
500
+ * If no `allowAnonymous` flag is on the Request, will require a valid authenticated user.
501
+ */
502
+
503
+ function matchAll<T extends RequestHandlersTest>(handlers: T) {
504
+ const r = typedKeysOf(handlers).reduce((acc, cur) => {
505
+ return HttpRouter.concat(acc, handlers[cur] as any)
506
+ }, HttpRouter.empty)
507
+
508
+ type _RRouter<T extends HttpRouter.HttpRouter<any, any>> = [T] extends [
509
+ HttpRouter.HttpRouter<infer R, any>
510
+ ] ? R
511
+ : never
512
+
513
+ type _ERouter<T extends HttpRouter.HttpRouter<any, any>> = [T] extends [
514
+ HttpRouter.HttpRouter<any, infer E>
515
+ ] ? E
516
+ : never
517
+
518
+ return r as HttpRouter.HttpRouter<
519
+ _RRouter<typeof handlers[keyof typeof handlers]>,
520
+ _ERouter<typeof handlers[keyof typeof handlers]>
521
+ >
522
+ }
523
+
524
+ // type SupportedRequestHandler = RequestHandler<
525
+ // any,
526
+ // any,
527
+ // any,
528
+ // any,
529
+ // any,
530
+ // any,
531
+ // any,
532
+ // any,
533
+ // any,
534
+ // SupportedErrors | S.ParseResult.ParseError,
535
+ // any,
536
+ // any,
537
+ // any,
538
+ // any
539
+ // >
540
+
541
+ // type RequestHandlers = { [key: string]: SupportedRequestHandler }
542
+ type RequestHandlersTest = {
543
+ [key: string]: HttpRouter.HttpRouter<any, any>
544
+ }
545
+
546
+ return { matchFor, matchAll }
547
+ }
@@ -0,0 +1,37 @@
1
+ // packages/infra/vitest.config.ts
2
+ import { defineConfig } from "file:///Users/patrickroza/pj/effect-app/libs/node_modules/.pnpm/vite@5.2.6_@types+node@20.11.30/node_modules/vite/dist/node/index.js";
3
+
4
+ // vite.config.base.ts
5
+ import path from "path";
6
+ import fs from "fs";
7
+ var __vite_injected_original_dirname = "/Users/patrickroza/pj/effect-app/libs";
8
+ function makeConfig(dirName) {
9
+ const prefix = path.resolve(__vite_injected_original_dirname, "packages");
10
+ const packages = fs.readdirSync(prefix).map((f) => prefix + "/" + f).filter((f) => fs.lstatSync(f).isDirectory());
11
+ const cfg = {
12
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
13
+ //plugins: [autoImport],
14
+ test: {
15
+ include: ["./test/**/*.test.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"],
16
+ reporters: "verbose",
17
+ globals: true
18
+ },
19
+ resolve: {
20
+ alias: packages.reduce((acc, cur) => {
21
+ acc[JSON.parse(fs.readFileSync(cur + "/package.json", "utf-8")).name] = path.resolve(cur, cur.endsWith("core") ? "dist" : "src");
22
+ return acc;
23
+ }, {})
24
+ // "@effect-app/core/Prelude": path.join(__dirname, "packages/core/src/Prelude.code.ts")
25
+ }
26
+ };
27
+ console.log(cfg);
28
+ return cfg;
29
+ }
30
+
31
+ // packages/infra/vitest.config.ts
32
+ var __vite_injected_original_dirname2 = "/Users/patrickroza/pj/effect-app/libs/packages/infra";
33
+ var vitest_config_default = defineConfig(makeConfig(__vite_injected_original_dirname2));
34
+ export {
35
+ vitest_config_default as default
36
+ };
37
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsicGFja2FnZXMvaW5mcmEvdml0ZXN0LmNvbmZpZy50cyIsICJ2aXRlLmNvbmZpZy5iYXNlLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZGlybmFtZSA9IFwiL1VzZXJzL3BhdHJpY2tyb3phL3BqL2VmZmVjdC1hcHAvbGlicy9wYWNrYWdlcy9pbmZyYVwiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9maWxlbmFtZSA9IFwiL1VzZXJzL3BhdHJpY2tyb3phL3BqL2VmZmVjdC1hcHAvbGlicy9wYWNrYWdlcy9pbmZyYS92aXRlc3QuY29uZmlnLnRzXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ltcG9ydF9tZXRhX3VybCA9IFwiZmlsZTovLy9Vc2Vycy9wYXRyaWNrcm96YS9wai9lZmZlY3QtYXBwL2xpYnMvcGFja2FnZXMvaW5mcmEvdml0ZXN0LmNvbmZpZy50c1wiOy8vLyA8cmVmZXJlbmNlIHR5cGVzPVwidml0ZXN0XCIgLz5cbmltcG9ydCB7IGRlZmluZUNvbmZpZyB9IGZyb20gXCJ2aXRlXCJcbmltcG9ydCBtYWtlQ29uZmlnIGZyb20gXCIuLi8uLi92aXRlLmNvbmZpZy5iYXNlXCJcblxuZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKG1ha2VDb25maWcoX19kaXJuYW1lKSlcbiIsICJjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZGlybmFtZSA9IFwiL1VzZXJzL3BhdHJpY2tyb3phL3BqL2VmZmVjdC1hcHAvbGlic1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9maWxlbmFtZSA9IFwiL1VzZXJzL3BhdHJpY2tyb3phL3BqL2VmZmVjdC1hcHAvbGlicy92aXRlLmNvbmZpZy5iYXNlLnRzXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ltcG9ydF9tZXRhX3VybCA9IFwiZmlsZTovLy9Vc2Vycy9wYXRyaWNrcm96YS9wai9lZmZlY3QtYXBwL2xpYnMvdml0ZS5jb25maWcuYmFzZS50c1wiOy8vLyA8cmVmZXJlbmNlIHR5cGVzPVwidml0ZXN0XCIgLz5cbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCJcbmltcG9ydCBmcyBmcm9tIFwiZnNcIlxuaW1wb3J0IEF1dG9JbXBvcnQgZnJvbSBcInVucGx1Z2luLWF1dG8taW1wb3J0L3ZpdGVcIlxuaW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSBcInZpdGVzdC9jb25maWdcIlxuXG4vLyBjb25zdCBhdXRvSW1wb3J0ID0gQXV0b0ltcG9ydCh7XG4vLyAgIGR0czogXCIuL3Rlc3QvYXV0by1pbXBvcnRzLmQudHNcIixcbi8vICAgLy8gaW5jbHVkZTogW1xuLy8gICAvLyAgIC9cXC50ZXN0XFwuW3RqXXN4PyQvIC8vIC50cywgLnRzeCwgLmpzLCAuanN4XG4vLyAgIC8vIF0sXG4vLyAgIGltcG9ydHM6IFtcbi8vICAgICBcInZpdGVzdFwiXG4vLyAgIF1cbi8vIH0pXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIG1ha2VDb25maWcoZGlyTmFtZT86IHN0cmluZykge1xuICBjb25zdCBwcmVmaXggPSBwYXRoLnJlc29sdmUoX19kaXJuYW1lLCBcInBhY2thZ2VzXCIpXG4gIGNvbnN0IHBhY2thZ2VzID0gZnMucmVhZGRpclN5bmMocHJlZml4KS5tYXAoZiA9PiBwcmVmaXggKyBcIi9cIiArIGYpLmZpbHRlcihmID0+IGZzLmxzdGF0U3luYyhmKS5pc0RpcmVjdG9yeSgpIClcbiAgY29uc3QgY2ZnID0ge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdmFyLXJlcXVpcmVzXG4gICAgLy9wbHVnaW5zOiBbYXV0b0ltcG9ydF0sXG4gICAgdGVzdDoge1xuICAgICAgaW5jbHVkZTogIFtcIi4vdGVzdC8qKi8qLnRlc3Que2pzLG1qcyxjanMsdHMsbXRzLGN0cyxqc3gsdHN4fVwiXSxcbiAgICAgIHJlcG9ydGVyczogXCJ2ZXJib3NlXCIsXG4gICAgICBnbG9iYWxzOiB0cnVlXG4gICAgfSxcbiAgICByZXNvbHZlOiB7XG4gICAgICBhbGlhczogcGFja2FnZXMucmVkdWNlKChhY2MsIGN1cikgPT4geyAvLyB3b3JrYXJvdW5kIGZvciAvUHJlbHVkZSBpc3N1ZVxuICAgICAgYWNjW0pTT04ucGFyc2UoZnMucmVhZEZpbGVTeW5jKGN1ciArIFwiL3BhY2thZ2UuanNvblwiLCBcInV0Zi04XCIpKS5uYW1lXSA9IHBhdGgucmVzb2x2ZShjdXIsIGN1ci5lbmRzV2l0aChcImNvcmVcIikgPyBcImRpc3RcIiA6IFwic3JjXCIpXG4gICAgICByZXR1cm4gYWNjXG4gICAgfSwgeyB9KSAvLyBcIkBlZmZlY3QtYXBwL2NvcmUvUHJlbHVkZVwiOiBwYXRoLmpvaW4oX19kaXJuYW1lLCBcInBhY2thZ2VzL2NvcmUvc3JjL1ByZWx1ZGUuY29kZS50c1wiKVxuICB9XG4gIH1cbiAgY29uc29sZS5sb2coY2ZnKVxuICByZXR1cm4gY2ZnXG59XG4iXSwKICAibWFwcGluZ3MiOiAiO0FBQ0EsU0FBUyxvQkFBb0I7OztBQ0E3QixPQUFPLFVBQVU7QUFDakIsT0FBTyxRQUFRO0FBRmYsSUFBTSxtQ0FBbUM7QUFnQjFCLFNBQVIsV0FBNEIsU0FBa0I7QUFDbkQsUUFBTSxTQUFTLEtBQUssUUFBUSxrQ0FBVyxVQUFVO0FBQ2pELFFBQU0sV0FBVyxHQUFHLFlBQVksTUFBTSxFQUFFLElBQUksT0FBSyxTQUFTLE1BQU0sQ0FBQyxFQUFFLE9BQU8sT0FBSyxHQUFHLFVBQVUsQ0FBQyxFQUFFLFlBQVksQ0FBRTtBQUM3RyxRQUFNLE1BQU07QUFBQTtBQUFBO0FBQUEsSUFHVixNQUFNO0FBQUEsTUFDSixTQUFVLENBQUMsa0RBQWtEO0FBQUEsTUFDN0QsV0FBVztBQUFBLE1BQ1gsU0FBUztBQUFBLElBQ1g7QUFBQSxJQUNBLFNBQVM7QUFBQSxNQUNQLE9BQU8sU0FBUyxPQUFPLENBQUMsS0FBSyxRQUFRO0FBQ3JDLFlBQUksS0FBSyxNQUFNLEdBQUcsYUFBYSxNQUFNLGlCQUFpQixPQUFPLENBQUMsRUFBRSxJQUFJLElBQUksS0FBSyxRQUFRLEtBQUssSUFBSSxTQUFTLE1BQU0sSUFBSSxTQUFTLEtBQUs7QUFDL0gsZUFBTztBQUFBLE1BQ1QsR0FBRyxDQUFFLENBQUM7QUFBQTtBQUFBLElBQ1I7QUFBQSxFQUNBO0FBQ0EsVUFBUSxJQUFJLEdBQUc7QUFDZixTQUFPO0FBQ1Q7OztBRHBDQSxJQUFNQSxvQ0FBbUM7QUFJekMsSUFBTyx3QkFBUSxhQUFhLFdBQVdDLGlDQUFTLENBQUM7IiwKICAibmFtZXMiOiBbIl9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lIiwgIl9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lIl0KfQo=