@effect-app/infra 2.9.0 → 2.9.2
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 +12 -0
- package/_cjs/Store/utils.cjs +3 -3
- package/_cjs/Store/utils.cjs.map +1 -1
- package/_cjs/api/routing4.cjs +190 -0
- package/_cjs/api/routing4.cjs.map +1 -0
- package/dist/Store/utils.d.ts.map +1 -1
- package/dist/Store/utils.js +4 -3
- package/dist/api/routing4.d.ts +104 -0
- package/dist/api/routing4.d.ts.map +1 -0
- package/dist/api/routing4.js +207 -0
- package/package.json +11 -2
- package/src/Store/utils.ts +8 -5
- package/src/api/routing4.ts +510 -0
- package/types/modules.d.ts +0 -1
package/CHANGELOG.md
CHANGED
package/_cjs/Store/utils.cjs
CHANGED
|
@@ -10,16 +10,16 @@ exports.lowerThan = lowerThan;
|
|
|
10
10
|
exports.lowerThanExclusive = lowerThanExclusive;
|
|
11
11
|
exports.lowercaseIfString = lowercaseIfString;
|
|
12
12
|
exports.makeUpdateETag = exports.makeETag = void 0;
|
|
13
|
+
var _crypto = require("crypto");
|
|
13
14
|
var _effectApp = require("effect-app");
|
|
14
|
-
var _objectHash = _interopRequireDefault(require("object-hash"));
|
|
15
15
|
var _errors = require("../errors.cjs");
|
|
16
|
-
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
17
16
|
const makeETag = ({
|
|
18
17
|
_etag,
|
|
19
18
|
...e
|
|
20
19
|
}) => ({
|
|
21
20
|
...e,
|
|
22
|
-
|
|
21
|
+
// we have to hash the JSON, as hashing the object might contain elements that won't be serialized anyway
|
|
22
|
+
_etag: (0, _crypto.createHash)("sha256").update(JSON.stringify(e)).digest("hex")
|
|
23
23
|
});
|
|
24
24
|
exports.makeETag = makeETag;
|
|
25
25
|
const makeUpdateETag = type => (e, current) => _effectApp.Effect.gen(function* () {
|
package/_cjs/Store/utils.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.cjs","names":["
|
|
1
|
+
{"version":3,"file":"utils.cjs","names":["_crypto","require","_effectApp","_errors","makeETag","_etag","e","createHash","update","JSON","stringify","digest","exports","makeUpdateETag","type","current","Effect","gen","mapError","OptimisticConcurrencyException","id","found","Option","isSome","value","newE","lowercaseIfString","val","toLowerCase","compare","valA","valB","lowerThan","lowerThanExclusive","greaterThan","greaterThanExclusive"],"sources":["../../src/Store/utils.ts"],"sourcesContent":[null],"mappings":";;;;;;;;;;;;AAAA,IAAAA,OAAA,GAAAC,OAAA;AACA,IAAAC,UAAA,GAAAD,OAAA;AACA,IAAAE,OAAA,GAAAF,OAAA;AAGO,MAAMG,QAAQ,GAAGA,CACtB;EAAEC,KAAK;EAAE,GAAGC;AAAC,CAAK,MAEjB;EACC,GAAGA,CAAC;EACJ;EACAD,KAAK,EAAE,IAAAE,kBAAU,EAAC,QAAQ,CAAC,CAACC,MAAM,CAACC,IAAI,CAACC,SAAS,CAACJ,CAAC,CAAC,CAAC,CAACK,MAAM,CAAC,KAAK;CACnE,CAAQ;AAAAC,OAAA,CAAAR,QAAA,GAAAA,QAAA;AAEJ,MAAMS,cAAc,GACxBC,IAAY,IAAK,CAAiDR,CAAI,EAAES,OAAkB,KACzFC,iBAAM,CAACC,GAAG,CAAC,aAAS;EAClB,IAAIX,CAAC,CAACD,KAAK,EAAE;IACX,OAAOW,iBAAM,CAACE,QAAQ,CACpBH,OAAO,EACP,MAAM,IAAII,sCAA8B,CAAC;MAAEL,IAAI;MAAEM,EAAE,EAAEd,CAAC,CAACc,EAAE;MAAEL,OAAO,EAAE,EAAE;MAAEM,KAAK,EAAEf,CAAC,CAACD;IAAK,CAAE,CAAC,CAC1F;EACH;EACA,IAAIiB,iBAAM,CAACC,MAAM,CAACR,OAAO,CAAC,IAAIA,OAAO,CAACS,KAAK,CAACnB,KAAK,KAAKC,CAAC,CAACD,KAAK,EAAE;IAC7D,OAAO,OAAO,IAAIc,sCAA8B,CAAC;MAC/CL,IAAI;MACJM,EAAE,EAAEL,OAAO,CAACS,KAAK,CAACJ,EAAE;MACpBL,OAAO,EAAEA,OAAO,CAACS,KAAK,CAACnB,KAAK;MAC5BgB,KAAK,EAAEf,CAAC,CAACD;KACV,CAAC;EACJ;EACA,MAAMoB,IAAI,GAAGrB,QAAQ,CAACE,CAAC,CAAC;EACxB,OAAOmB,IAAI;AACb,CAAC,CAAC;AAAAb,OAAA,CAAAC,cAAA,GAAAA,cAAA;AAEA,SAAUa,iBAAiBA,CAAIC,GAAM;EACzC,IAAI,OAAOA,GAAG,KAAK,QAAQ,EAAE;IAC3B,OAAOA,GAAG,CAACC,WAAW,EAAE;EAC1B;EACA,OAAOD,GAAG;AACZ;AAEM,SAAUE,OAAOA,CAACC,IAAa,EAAEC,IAAa;EAClD,OAAOD,IAAI,KAAKC,IAAI;AACtB;AAEM,SAAUC,SAASA,CAACF,IAAsB,EAAEC,IAAsB;EACtE,OAAOD,IAAI,GAAGC,IAAI;AACpB;AAEM,SAAUE,kBAAkBA,CAACH,IAAsB,EAAEC,IAAsB;EAC/E,OAAOD,IAAI,IAAIC,IAAI;AACrB;AAEM,SAAUG,WAAWA,CAACJ,IAAsB,EAAEC,IAAsB;EACxE,OAAOD,IAAI,GAAGC,IAAI;AACpB;AAEM,SAAUI,oBAAoBA,CAACL,IAAsB,EAAEC,IAAsB;EACjF,OAAOD,IAAI,IAAIC,IAAI;AACrB","ignoreList":[]}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.toHttpApp = exports.makeRouter = exports.makeMiddleware = exports.RouterSymbol = void 0;
|
|
7
|
+
var _rpc = require("@effect/rpc");
|
|
8
|
+
var _effectApp = require("effect-app");
|
|
9
|
+
var _http = require("effect-app/http");
|
|
10
|
+
var _utils = require("effect-app/utils");
|
|
11
|
+
var _errorReporter = require("../errorReporter.cjs");
|
|
12
|
+
var _logger = require("../logger.cjs");
|
|
13
|
+
var _DynamicMiddleware = require("./routing/DynamicMiddleware.cjs");
|
|
14
|
+
const logRequestError = (0, _errorReporter.logError)("Request");
|
|
15
|
+
const reportRequestError = (0, _errorReporter.reportError)("Request");
|
|
16
|
+
/**
|
|
17
|
+
* Plain jane JSON version
|
|
18
|
+
* @deprecated use HttpRpcRouterNoStream.toHttpApp once support options
|
|
19
|
+
*/
|
|
20
|
+
const toHttpApp = (self, options) => {
|
|
21
|
+
const handler = _rpc.RpcRouter.toHandler(self, options);
|
|
22
|
+
return _effectApp.Effect.withFiberRuntime(fiber => {
|
|
23
|
+
const context = fiber.getFiberRef(_effectApp.FiberRef.currentContext);
|
|
24
|
+
const request = _effectApp.Context.unsafeGet(context, _http.HttpServerRequest.HttpServerRequest);
|
|
25
|
+
return _effectApp.Effect.flatMap(request.json, _ => handler(_).pipe(_effectApp.Stream.provideContext(context), _effectApp.Stream.runCollect, _effectApp.Effect.map(_ => _effectApp.Chunk.toReadonlyArray(_)), _effectApp.Effect.andThen(_ => {
|
|
26
|
+
let status = 200;
|
|
27
|
+
for (const r of _.flat()) {
|
|
28
|
+
if (typeof r === "number") continue;
|
|
29
|
+
const results = Array.isArray(r) ? r : [r];
|
|
30
|
+
if (results.some(_ => _._tag === "Failure" && _.cause._tag === "Die")) {
|
|
31
|
+
status = 500;
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
if (results.some(_ => _._tag === "Failure" && _.cause._tag === "Fail")) {
|
|
35
|
+
status = 422; // 418
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return _http.HttpServerResponse.json(_, {
|
|
40
|
+
status
|
|
41
|
+
});
|
|
42
|
+
}), _effectApp.Effect.orDie, _effectApp.Effect.tapDefect((0, _errorReporter.reportError)("RPCHttpApp"))));
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
exports.toHttpApp = toHttpApp;
|
|
46
|
+
const RouterSymbol = exports.RouterSymbol = Symbol();
|
|
47
|
+
// export interface RouteMatcher<
|
|
48
|
+
// Filtered extends Record<string, any>,
|
|
49
|
+
// CTXMap extends Record<string, any>,
|
|
50
|
+
// Rsc extends Filtered
|
|
51
|
+
// > extends RouteMatcherInt<Filtered, CTXMap, Rsc> {}
|
|
52
|
+
const makeMiddleware = content => content;
|
|
53
|
+
exports.makeMiddleware = makeMiddleware;
|
|
54
|
+
const makeRouter = (middleware, devMode) => {
|
|
55
|
+
function matchFor(rsc) {
|
|
56
|
+
const meta = rsc.meta;
|
|
57
|
+
const filtered = (0, _utils.typedKeysOf)(rsc).reduce((acc, cur) => {
|
|
58
|
+
if (_effectApp.Predicate.isObject(rsc[cur]) && rsc[cur]["success"]) {
|
|
59
|
+
acc[cur] = rsc[cur];
|
|
60
|
+
}
|
|
61
|
+
return acc;
|
|
62
|
+
}, {});
|
|
63
|
+
const items = (0, _utils.typedKeysOf)(filtered).reduce((prev, cur) => {
|
|
64
|
+
;
|
|
65
|
+
prev[cur] = Object.assign(fnOrEffect => {
|
|
66
|
+
const stack = new Error().stack?.split("\n").slice(2).join("\n");
|
|
67
|
+
return _effectApp.Effect.isEffect(fnOrEffect) ? class {
|
|
68
|
+
static stack = stack;
|
|
69
|
+
static _tag = "d";
|
|
70
|
+
static handler = () => fnOrEffect;
|
|
71
|
+
} : class {
|
|
72
|
+
static stack = stack;
|
|
73
|
+
static _tag = "d";
|
|
74
|
+
static handler = fnOrEffect;
|
|
75
|
+
};
|
|
76
|
+
}, {
|
|
77
|
+
success: rsc[cur].success,
|
|
78
|
+
successRaw: _effectApp.S.encodedSchema(rsc[cur].success),
|
|
79
|
+
failure: rsc[cur].failure,
|
|
80
|
+
raw:
|
|
81
|
+
// "Raw" variations are for when you don't want to decode just to encode it again on the response
|
|
82
|
+
// e.g for direct projection from DB
|
|
83
|
+
// but more importantly, to skip Effectful decoders, like to resolve relationships from the database or remote client.
|
|
84
|
+
fnOrEffect => {
|
|
85
|
+
const stack = new Error().stack?.split("\n").slice(2).join("\n");
|
|
86
|
+
return _effectApp.Effect.isEffect(fnOrEffect) ? class {
|
|
87
|
+
static stack = stack;
|
|
88
|
+
static _tag = "raw";
|
|
89
|
+
static handler = () => fnOrEffect;
|
|
90
|
+
} : class {
|
|
91
|
+
static stack = stack;
|
|
92
|
+
static _tag = "raw";
|
|
93
|
+
static handler = (req, ctx) => fnOrEffect(req, {
|
|
94
|
+
...ctx,
|
|
95
|
+
Response: rsc[cur].success
|
|
96
|
+
});
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
return prev;
|
|
101
|
+
}, {});
|
|
102
|
+
const effect = (layers, make) => {
|
|
103
|
+
const r = class Router extends _http.HttpRouter.Tag(`${meta.moduleName}Router`)() {};
|
|
104
|
+
const layer = r.use(router => _effectApp.Effect.gen(function* () {
|
|
105
|
+
const controllers = yield* make(items);
|
|
106
|
+
const rpc = yield* (0, _DynamicMiddleware.makeRpc)(middleware);
|
|
107
|
+
// return make.pipe(Effect.map((c) => controllers(c, layers)))
|
|
108
|
+
const mapped = (0, _utils.typedKeysOf)(filtered).reduce((acc, cur) => {
|
|
109
|
+
const handler = controllers[cur];
|
|
110
|
+
const req = rsc[cur];
|
|
111
|
+
acc[cur] = rpc.effect(handler._tag === "raw" ? class extends req {
|
|
112
|
+
static success = _effectApp.S.encodedSchema(req.success);
|
|
113
|
+
get [_effectApp.Schema.symbolSerializable]() {
|
|
114
|
+
return this.constructor;
|
|
115
|
+
}
|
|
116
|
+
get [_effectApp.Schema.symbolWithResult]() {
|
|
117
|
+
return {
|
|
118
|
+
failure: req.failure,
|
|
119
|
+
success: _effectApp.S.encodedSchema(req.success)
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
} : req, req => _effectApp.Effect.annotateCurrentSpan("requestInput", Object.entries(req).reduce((prev, [key, value]) => {
|
|
123
|
+
prev[key] = key === "password" ? "<redacted>" : typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? typeof value === "string" && value.length > 256 ? value.substring(0, 253) + "..." : value : Array.isArray(value) ? `Array[${value.length}]` : value === null || value === undefined ? `${value}` : typeof value === "object" && value ? `Object[${Object.keys(value).length}]` : typeof value;
|
|
124
|
+
return prev;
|
|
125
|
+
}, {})).pipe(
|
|
126
|
+
// can't use andThen due to some being a function and effect
|
|
127
|
+
_effectApp.Effect.zipRight(handler.handler(req)), _effectApp.Effect.tapErrorCause(cause => _effectApp.Cause.isFailure(cause) ? logRequestError(cause) : _effectApp.Effect.void), _effectApp.Effect.tapDefect(cause => _effectApp.Effect.all([reportRequestError(cause, {
|
|
128
|
+
action: `${meta.moduleName}.${req._tag}`
|
|
129
|
+
}), _rpc.Rpc.currentHeaders.pipe(_effectApp.Effect.andThen(headers => {
|
|
130
|
+
return _logger.InfraLogger.logError("Finished request", cause).pipe(_effectApp.Effect.annotateLogs({
|
|
131
|
+
action: `${meta.moduleName}.${req._tag}`,
|
|
132
|
+
req: (0, _utils.pretty)(req),
|
|
133
|
+
headers: (0, _utils.pretty)(headers)
|
|
134
|
+
// resHeaders: pretty(
|
|
135
|
+
// Object
|
|
136
|
+
// .entries(headers)
|
|
137
|
+
// .reduce((prev, [key, value]) => {
|
|
138
|
+
// prev[key] = value && typeof value === "string" ? snipString(value) : value
|
|
139
|
+
// return prev
|
|
140
|
+
// }, {} as Record<string, any>)
|
|
141
|
+
// )
|
|
142
|
+
}));
|
|
143
|
+
}))])), devMode ? _ => _ : _effectApp.Effect.catchAllDefect(() => _effectApp.Effect.die("Internal Server Error")), _effectApp.Effect.withSpan("Request." + meta.moduleName + "." + req._tag, {
|
|
144
|
+
captureStackTrace: () => handler.stack
|
|
145
|
+
})), meta.moduleName); // TODO
|
|
146
|
+
return acc;
|
|
147
|
+
}, {});
|
|
148
|
+
const rpcRouter = _rpc.RpcRouter.make(...Object.values(mapped));
|
|
149
|
+
const httpApp = toHttpApp(rpcRouter, {
|
|
150
|
+
spanPrefix: rsc.meta.moduleName + "."
|
|
151
|
+
});
|
|
152
|
+
yield* router.all("/", httpApp,
|
|
153
|
+
// TODO: not queries.
|
|
154
|
+
{
|
|
155
|
+
uninterruptible: true
|
|
156
|
+
});
|
|
157
|
+
}));
|
|
158
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
159
|
+
const routes = layer.pipe(_effectApp.Layer.provideMerge(r.Live), layers ? _effectApp.Layer.provide(layers) : _ => _,
|
|
160
|
+
// TODO: only provide to the middleware?
|
|
161
|
+
middleware.dependencies ? _effectApp.Layer.provide(middleware.dependencies) : _ => _);
|
|
162
|
+
// Effect.Effect<HttpRouter.HttpRouter<unknown, HttpRouter.HttpRouter.DefaultServices>, never, UserRouter>
|
|
163
|
+
return {
|
|
164
|
+
moduleName: meta.moduleName,
|
|
165
|
+
Router: r,
|
|
166
|
+
routes
|
|
167
|
+
};
|
|
168
|
+
};
|
|
169
|
+
return effect;
|
|
170
|
+
}
|
|
171
|
+
function matchAll(handlers, requestLayer) {
|
|
172
|
+
const routers = (0, _utils.typedValuesOf)(handlers);
|
|
173
|
+
const rootRouter = class extends _http.HttpRouter.Tag("RootRouter")() {};
|
|
174
|
+
const r = rootRouter.use(router => _effectApp.Effect.gen(function* () {
|
|
175
|
+
for (const route of routers) {
|
|
176
|
+
yield* router.mount("/rpc/" + route.moduleName, yield* route.Router.router.pipe(_effectApp.Effect.map(_http.HttpRouter.use((0, _effectApp.flow)(_effectApp.Effect.provide(requestLayer))))));
|
|
177
|
+
}
|
|
178
|
+
})).pipe(_effectApp.Layer.provide(routers.map(r => r.routes).flat()));
|
|
179
|
+
return {
|
|
180
|
+
layer: r,
|
|
181
|
+
Router: rootRouter
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
return {
|
|
185
|
+
matchAll,
|
|
186
|
+
matchFor
|
|
187
|
+
};
|
|
188
|
+
};
|
|
189
|
+
exports.makeRouter = makeRouter;
|
|
190
|
+
//# sourceMappingURL=routing4.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routing4.cjs","names":["_rpc","require","_effectApp","_http","_utils","_errorReporter","_logger","_DynamicMiddleware","logRequestError","logError","reportRequestError","reportError","toHttpApp","self","options","handler","RpcRouter","toHandler","Effect","withFiberRuntime","fiber","context","getFiberRef","FiberRef","currentContext","request","Context","unsafeGet","HttpServerRequest","flatMap","json","_","pipe","Stream","provideContext","runCollect","map","Chunk","toReadonlyArray","andThen","status","r","flat","results","Array","isArray","some","_tag","cause","HttpServerResponse","orDie","tapDefect","exports","RouterSymbol","Symbol","makeMiddleware","content","makeRouter","middleware","devMode","matchFor","rsc","meta","filtered","typedKeysOf","reduce","acc","cur","Predicate","isObject","items","prev","Object","assign","fnOrEffect","stack","Error","split","slice","join","isEffect","success","successRaw","S","encodedSchema","failure","raw","req","ctx","Response","effect","layers","make","Router","HttpRouter","Tag","moduleName","layer","use","router","gen","controllers","rpc","makeRpc","mapped","Schema","symbolSerializable","constructor","symbolWithResult","annotateCurrentSpan","entries","key","value","length","substring","undefined","keys","zipRight","tapErrorCause","Cause","isFailure","void","all","action","Rpc","currentHeaders","headers","InfraLogger","annotateLogs","pretty","catchAllDefect","die","withSpan","captureStackTrace","rpcRouter","values","httpApp","spanPrefix","uninterruptible","routes","Layer","provideMerge","Live","provide","dependencies","matchAll","handlers","requestLayer","routers","typedValuesOf","rootRouter","route","mount","flow"],"sources":["../../src/api/routing4.ts"],"sourcesContent":[null],"mappings":";;;;;;AAQA,IAAAA,IAAA,GAAAC,OAAA;AAEA,IAAAC,UAAA,GAAAD,OAAA;AAGA,IAAAE,KAAA,GAAAF,OAAA;AACA,IAAAG,MAAA,GAAAH,OAAA;AACA,IAAAI,cAAA,GAAAJ,OAAA;AACA,IAAAK,OAAA,GAAAL,OAAA;AAEA,IAAAM,kBAAA,GAAAN,OAAA;AAEA,MAAMO,eAAe,GAAG,IAAAC,uBAAQ,EAAC,SAAS,CAAC;AAC3C,MAAMC,kBAAkB,GAAG,IAAAC,0BAAW,EAAC,SAAS,CAAC;AAejD;;;;AAIO,MAAMC,SAAS,GAAGA,CAA0CC,IAAO,EAAEC,OAE3E,KAGG;EACF,MAAMC,OAAO,GAAGC,cAAS,CAACC,SAAS,CAACJ,IAAI,EAAEC,OAAO,CAAC;EAClD,OAAOI,iBAAM,CAACC,gBAAgB,CAAEC,KAAK,IAAI;IACvC,MAAMC,OAAO,GAAGD,KAAK,CAACE,WAAW,CAACC,mBAAQ,CAACC,cAAc,CAAC;IAC1D,MAAMC,OAAO,GAAGC,kBAAO,CAACC,SAAS,CAACN,OAAO,EAAEO,uBAAiB,CAACA,iBAAiB,CAAC;IAC/E,OAAOV,iBAAM,CAACW,OAAO,CACnBJ,OAAO,CAACK,IAAI,EACXC,CAAC,IACAhB,OAAO,CAACgB,CAAC,CAAC,CAACC,IAAI,CACbC,iBAAM,CAACC,cAAc,CAACb,OAAO,CAAC,EAC9BY,iBAAM,CAACE,UAAU,EACjBjB,iBAAM,CAACkB,GAAG,CAAEL,CAAC,IAAKM,gBAAK,CAACC,eAAe,CAACP,CAAC,CAAC,CAAC,EAC3Cb,iBAAM,CAACqB,OAAO,CAAER,CAAC,IAAI;MACnB,IAAIS,MAAM,GAAG,GAAG;MAChB,KAAK,MAAMC,CAAC,IAAIV,CAAC,CAACW,IAAI,EAAE,EAAE;QACxB,IAAI,OAAOD,CAAC,KAAK,QAAQ,EAAE;QAC3B,MAAME,OAAO,GAAGC,KAAK,CAACC,OAAO,CAACJ,CAAC,CAAC,GAAGA,CAAC,GAAG,CAACA,CAAC,CAAC;QAC1C,IAAIE,OAAO,CAACG,IAAI,CAAEf,CAA+B,IAAKA,CAAC,CAACgB,IAAI,KAAK,SAAS,IAAIhB,CAAC,CAACiB,KAAK,CAACD,IAAI,KAAK,KAAK,CAAC,EAAE;UACrGP,MAAM,GAAG,GAAG;UACZ;QACF;QACA,IAAIG,OAAO,CAACG,IAAI,CAAEf,CAA+B,IAAKA,CAAC,CAACgB,IAAI,KAAK,SAAS,IAAIhB,CAAC,CAACiB,KAAK,CAACD,IAAI,KAAK,MAAM,CAAC,EAAE;UACtGP,MAAM,GAAG,GAAG,EAAC;UACb;QACF;MACF;MACA,OAAOS,wBAAkB,CAACnB,IAAI,CAACC,CAAC,EAAE;QAAES;MAAM,CAAE,CAAC;IAC/C,CAAC,CAAC,EACFtB,iBAAM,CAACgC,KAAK,EACZhC,iBAAM,CAACiC,SAAS,CAAC,IAAAxC,0BAAW,EAAC,YAAY,CAAC,CAAC,CAC5C,CACJ;EACH,CAAC,CAAC;AACJ,CAAC;AAAAyC,OAAA,CAAAxC,SAAA,GAAAA,SAAA;AAqDM,MAAMyC,YAAY,GAAAD,OAAA,CAAAC,YAAA,GAAGC,MAAM,EAAE;AA6EpC;AACA;AACA;AACA;AACA;AAEO,MAAMC,cAAc,GAKzBC,OAAiD,IAA+CA,OAAO;AAAAJ,OAAA,CAAAG,cAAA,GAAAA,cAAA;AAElG,MAAME,UAAU,GAAGA,CAMxBC,UAAoD,EACpDC,OAAgB,KACd;EACF,SAASC,QAAQA,CAIfC,GAA+C;IAE/C,MAAMC,IAAI,GAAGD,GAAG,CAACC,IAAI;IAErB,MAAMC,QAAQ,GAAG,IAAAC,kBAAW,EAACH,GAAG,CAAC,CAACI,MAAM,CAAC,CAACC,GAAG,EAAEC,GAAG,KAAI;MACpD,IAAIC,oBAAS,CAACC,QAAQ,CAACR,GAAG,CAACM,GAAG,CAAC,CAAC,IAAIN,GAAG,CAACM,GAAG,CAAC,CAAC,SAAS,CAAC,EAAE;QACvDD,GAAG,CAACC,GAAqB,CAAC,GAAGN,GAAG,CAACM,GAAG,CAAC;MACvC;MACA,OAAOD,GAAG;IACZ,CAAC,EAAE,EAAc,CAAC;IAElB,MAAMI,KAAK,GAAG,IAAAN,kBAAW,EAACD,QAAQ,CAAC,CAACE,MAAM,CACxC,CAACM,IAAI,EAAEJ,GAAG,KAAI;MACZ;MAAEI,IAAY,CAACJ,GAAG,CAAC,GAAGK,MAAM,CAACC,MAAM,CAAEC,UAAe,IAAI;QACtD,MAAMC,KAAK,GAAG,IAAIC,KAAK,EAAE,CAACD,KAAK,EAAEE,KAAK,CAAC,IAAI,CAAC,CAACC,KAAK,CAAC,CAAC,CAAC,CAACC,IAAI,CAAC,IAAI,CAAC;QAChE,OAAO7D,iBAAM,CAAC8D,QAAQ,CAACN,UAAU,CAAC,GAC9B;UACA,OAAOC,KAAK,GAAGA,KAAK;UACpB,OAAO5B,IAAI,GAAG,GAAG;UACjB,OAAOhC,OAAO,GAAGA,CAAA,KAAM2D,UAAU;SAClC,GACC;UACA,OAAOC,KAAK,GAAGA,KAAK;UACpB,OAAO5B,IAAI,GAAG,GAAG;UACjB,OAAOhC,OAAO,GAAG2D,UAAU;SAC5B;MACL,CAAC,EAAE;QACDO,OAAO,EAAEpB,GAAG,CAACM,GAAG,CAAC,CAACc,OAAO;QACzBC,UAAU,EAAEC,YAAC,CAACC,aAAa,CAACvB,GAAG,CAACM,GAAG,CAAC,CAACc,OAAO,CAAC;QAC7CI,OAAO,EAAExB,GAAG,CAACM,GAAG,CAAC,CAACkB,OAAO;QACzBC,GAAG;QAAE;QACH;QACA;QACCZ,UAAe,IAAI;UAClB,MAAMC,KAAK,GAAG,IAAIC,KAAK,EAAE,CAACD,KAAK,EAAEE,KAAK,CAAC,IAAI,CAAC,CAACC,KAAK,CAAC,CAAC,CAAC,CAACC,IAAI,CAAC,IAAI,CAAC;UAChE,OAAO7D,iBAAM,CAAC8D,QAAQ,CAACN,UAAU,CAAC,GAC9B;YACA,OAAOC,KAAK,GAAGA,KAAK;YACpB,OAAO5B,IAAI,GAAG,KAAK;YACnB,OAAOhC,OAAO,GAAGA,CAAA,KAAM2D,UAAU;WAClC,GACC;YACA,OAAOC,KAAK,GAAGA,KAAK;YACpB,OAAO5B,IAAI,GAAG,KAAK;YACnB,OAAOhC,OAAO,GAAGA,CAACwE,GAAQ,EAAEC,GAAQ,KAAKd,UAAU,CAACa,GAAG,EAAE;cAAE,GAAGC,GAAG;cAAEC,QAAQ,EAAE5B,GAAG,CAACM,GAAG,CAAC,CAACc;YAAO,CAAE,CAAC;WACjG;QACL;OACH,CAAC;MACF,OAAOV,IAAI;IACb,CAAC,EACD,EAAwC,CACzC;IAID,MAAMmB,MAAM,GAAGA,CASbC,MAAe,EACfC,IAAyD,KACvD;MAKF,MAAMnD,CAAC,GAWF,MAAMoD,MAAO,SAAQC,gBAAU,CAACC,GAAG,CAAC,GAAGjC,IAAI,CAACkC,UAAU,QAAQ,CAAC,EAAU,GAAW;MAEzF,MAAMC,KAAK,GAAGxD,CAAC,CAACyD,GAAG,CAAEC,MAAM,IACzBjF,iBAAM,CAACkF,GAAG,CAAC,aAAS;QAClB,MAAMC,WAAW,GAAG,OAAOT,IAAI,CAACtB,KAAK,CAAC;QACtC,MAAMgC,GAAG,GAAG,OAAO,IAAAC,0BAAO,EAAC7C,UAAU,CAAC;QAEtC;QACA,MAAM8C,MAAM,GAAG,IAAAxC,kBAAW,EAACD,QAAQ,CAAC,CAACE,MAAM,CAAC,CAACC,GAAG,EAAEC,GAAG,KAAI;UACvD,MAAMpD,OAAO,GAAGsF,WAAW,CAAClC,GAA+B,CAAC;UAC5D,MAAMoB,GAAG,GAAG1B,GAAG,CAACM,GAAG,CAAC;UAEpBD,GAAG,CAACC,GAAG,CAAC,GAAGmC,GAAG,CAACZ,MAAM,CACnB3E,OAAO,CAACgC,IAAI,KAAK,KAAK,GAClB,cAAewC,GAAW;YAC1B,OAAON,OAAO,GAAGE,YAAC,CAACC,aAAa,CAACG,GAAG,CAACN,OAAO,CAAC;YAC7C,KAAKwB,iBAAM,CAACC,kBAAkB,IAAC;cAC7B,OAAO,IAAI,CAACC,WAAW;YACzB;YACA,KAAKF,iBAAM,CAACG,gBAAgB,IAAC;cAC3B,OAAO;gBACLvB,OAAO,EAAEE,GAAG,CAACF,OAAO;gBACpBJ,OAAO,EAAEE,YAAC,CAACC,aAAa,CAACG,GAAG,CAACN,OAAO;eACrC;YACH;WACM,GACNM,GAAG,EACNA,GAAG,IACFrE,iBAAM,CACH2F,mBAAmB,CAClB,cAAc,EACdrC,MAAM,CAACsC,OAAO,CAACvB,GAAG,CAAC,CAACtB,MAAM,CAAC,CAACM,IAAI,EAAE,CAACwC,GAAG,EAAEC,KAAK,CAAoB,KAAI;YACnEzC,IAAI,CAACwC,GAAG,CAAC,GAAGA,GAAG,KAAK,UAAU,GAC1B,YAAY,GACZ,OAAOC,KAAK,KAAK,QAAQ,IAAI,OAAOA,KAAK,KAAK,QAAQ,IAAI,OAAOA,KAAK,KAAK,SAAS,GACpF,OAAOA,KAAK,KAAK,QAAQ,IAAIA,KAAK,CAACC,MAAM,GAAG,GAAG,GAC5CD,KAAK,CAACE,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,KAAK,GAChCF,KAAK,GACPpE,KAAK,CAACC,OAAO,CAACmE,KAAK,CAAC,GACpB,SAASA,KAAK,CAACC,MAAM,GAAG,GACxBD,KAAK,KAAK,IAAI,IAAIA,KAAK,KAAKG,SAAS,GACrC,GAAGH,KAAK,EAAE,GACV,OAAOA,KAAK,KAAK,QAAQ,IAAIA,KAAK,GAClC,UAAUxC,MAAM,CAAC4C,IAAI,CAACJ,KAAK,CAAC,CAACC,MAAM,GAAG,GACtC,OAAOD,KAAK;YAChB,OAAOzC,IAAI;UACb,CAAC,EAAE,EAA+C,CAAC,CACpD,CACAvC,IAAI;UACH;UACAd,iBAAM,CAACmG,QAAQ,CAACtG,OAAO,CAACA,OAAO,CAACwE,GAAU,CAAQ,CAAC,EACnDrE,iBAAM,CAACoG,aAAa,CAAEtE,KAAK,IAAKuE,gBAAK,CAACC,SAAS,CAACxE,KAAK,CAAC,GAAGxC,eAAe,CAACwC,KAAK,CAAC,GAAG9B,iBAAM,CAACuG,IAAI,CAAC,EAC9FvG,iBAAM,CAACiC,SAAS,CAAEH,KAAK,IACrB9B,iBAAM,CACHwG,GAAG,CAAC,CACHhH,kBAAkB,CAACsC,KAAK,EAAE;YACxB2E,MAAM,EAAE,GAAG7D,IAAI,CAACkC,UAAU,IAAIT,GAAG,CAACxC,IAAI;WACvC,CAAC,EACF6E,QAAG,CAACC,cAAc,CAAC7F,IAAI,CAACd,iBAAM,CAACqB,OAAO,CAAEuF,OAAO,IAAI;YACjD,OAAOC,mBAAW,CACftH,QAAQ,CAAC,kBAAkB,EAAEuC,KAAK,CAAC,CACnChB,IAAI,CAACd,iBAAM,CAAC8G,YAAY,CAAC;cACxBL,MAAM,EAAE,GAAG7D,IAAI,CAACkC,UAAU,IAAIT,GAAG,CAACxC,IAAI,EAAE;cACxCwC,GAAG,EAAE,IAAA0C,aAAM,EAAC1C,GAAG,CAAC;cAChBuC,OAAO,EAAE,IAAAG,aAAM,EAACH,OAAO;cACvB;cACA;cACA;cACA;cACA;cACA;cACA;cACA;aACD,CAAC,CAAC;UACP,CAAC,CAAC,CAAC,CACJ,CAAC,CACL,EACDnE,OAAO,GAAI5B,CAAC,IAAKA,CAAC,GAAGb,iBAAM,CAACgH,cAAc,CAAC,MAAMhH,iBAAM,CAACiH,GAAG,CAAC,uBAAuB,CAAC,CAAC,EACrFjH,iBAAM,CAACkH,QAAQ,CAAC,UAAU,GAAGtE,IAAI,CAACkC,UAAU,GAAG,GAAG,GAAGT,GAAG,CAACxC,IAAI,EAAE;YAC7DsF,iBAAiB,EAAEA,CAAA,KAAMtH,OAAO,CAAC4D;WAClC,CAAC,CACH,EACLb,IAAI,CAACkC,UAAU,CAChB,EAAC;UACF,OAAO9B,GAAG;QACZ,CAAC,EAAE,EAAS,CAKX;QAED,MAAMoE,SAAS,GAAGtH,cAAS,CAAC4E,IAAI,CAAC,GAAGpB,MAAM,CAAC+D,MAAM,CAAC/B,MAAM,CAAQ,CAG/D;QACD,MAAMgC,OAAO,GAAG5H,SAAS,CAAC0H,SAAS,EAAE;UACnCG,UAAU,EAAE5E,GAAG,CACZC,IAAI,CACJkC,UAAU,GAAG;SACjB,CAAC;QACF,OAAOG,MAAM,CACVuB,GAAG,CACF,GAAG,EACHc,OAAc;QACd;QACA;UAAEE,eAAe,EAAE;QAAI,CAAE,CAC1B;MACL,CAAC,CAAC,CACH;MAED;MACA,MAAMC,MAAM,GAAG1C,KAAK,CAACjE,IAAI,CACvB4G,gBAAK,CAACC,YAAY,CAACpG,CAAC,CAACqG,IAAI,CAAC,EAC1BnD,MAAM,GAAGiD,gBAAK,CAACG,OAAO,CAACpD,MAAM,CAAQ,GAAI5D,CAAC,IAAKA,CAAC;MAChD;MACA2B,UAAU,CAACsF,YAAY,GAAGJ,gBAAK,CAACG,OAAO,CAACrF,UAAU,CAACsF,YAAmB,CAAC,GAAIjH,CAAC,IAAKA,CAAC,CASnF;MAED;MAEA,OAAO;QACLiE,UAAU,EAAElC,IAAI,CAACkC,UAAU;QAC3BH,MAAM,EAAEpD,CAAC;QACTkG;OACD;IACH,CAAC;IAED,OAAOjD,MAAM;EACf;EAYA,SAASuD,QAAQA,CACfC,QAAW,EACXC,YAAkC;IAElC,MAAMC,OAAO,GAAG,IAAAC,oBAAa,EAACH,QAAQ,CAAC;IAEvC,MAAMI,UAAU,GAAG,cAAcxD,gBAAU,CAACC,GAAG,CAAC,YAAY,CAAC,EAI1D,GAAG;IAEN,MAAMtD,CAAC,GAAG6G,UAAU,CACjBpD,GAAG,CAAEC,MAAM,IACVjF,iBAAM,CAACkF,GAAG,CAAC,aAAS;MAClB,KAAK,MAAMmD,KAAK,IAAIH,OAAO,EAAE;QAC3B,OAAOjD,MAAM,CAACqD,KAAK,CAChB,OAAO,GAAGD,KAAK,CAACvD,UAAU,EAC3B,OAAOuD,KAAK,CACT1D,MAAM,CACNM,MAAM,CACNnE,IAAI,CAACd,iBAAM,CAACkB,GAAG,CAAC0D,gBAAU,CAACI,GAAG,CAAC,IAAAuD,eAAI,EAACvI,iBAAM,CAAC6H,OAAO,CAACI,YAAY,CAAC,CAAC,CAAC,CAAC,CAAQ,CAC/E;MACH;IACF,CAAC,CAAC,CACH,CACAnH,IAAI,CAAC4G,gBAAK,CAACG,OAAO,CAACK,OAAO,CAAChH,GAAG,CAAEK,CAAC,IAAKA,CAAC,CAACkG,MAAM,CAAC,CAACjG,IAAI,EAA+C,CAAC,CAAC;IAExG,OAAO;MACLuD,KAAK,EAAExD,CAIN;MACDoD,MAAM,EAAEyD;KAMT;EACH;EAEA,OAAO;IAAEL,QAAQ;IAAErF;EAAQ,CAAE;AAC/B,CAAC;AAAAR,OAAA,CAAAK,UAAA,GAAAA,UAAA","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/Store/utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/Store/utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAC3C,OAAO,EAAE,8BAA8B,EAAE,MAAM,cAAc,CAAA;AAC7D,OAAO,KAAK,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAE1E,eAAO,MAAM,QAAQ,GAAI,CAAC,SAAS,oBAAoB,CAAC,EAAE,CAAC,mBACxC,CAAC,KACjB,CAKQ,CAAA;AAEX,eAAO,MAAM,cAAc,SAClB,MAAM,MAAM,CAAC,SAAS,oBAAoB,CAAC;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,KAAK,CAAC,WAAW,MAAM,CAAC,CAAC,CAAC,4DAkBvF,CAAA;AAEN,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,cAK1C;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,WAEnD;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,gBAAgB,WAEvE;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,gBAAgB,WAEhF;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,gBAAgB,WAEzE;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,gBAAgB,WAElF"}
|
package/dist/Store/utils.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import { createHash } from "crypto";
|
|
1
2
|
import { Effect, Option } from "effect-app";
|
|
2
|
-
import objectHash from "object-hash";
|
|
3
3
|
import { OptimisticConcurrencyException } from "../errors.js";
|
|
4
4
|
export const makeETag = ({ _etag, ...e }) => ({
|
|
5
5
|
...e,
|
|
6
|
-
|
|
6
|
+
// we have to hash the JSON, as hashing the object might contain elements that won't be serialized anyway
|
|
7
|
+
_etag: createHash("sha256").update(JSON.stringify(e)).digest("hex")
|
|
7
8
|
});
|
|
8
9
|
export const makeUpdateETag = (type) => (e, current) => Effect.gen(function* () {
|
|
9
10
|
if (e._etag) {
|
|
@@ -41,4 +42,4 @@ export function greaterThan(valA, valB) {
|
|
|
41
42
|
export function greaterThanExclusive(valA, valB) {
|
|
42
43
|
return valA >= valB;
|
|
43
44
|
}
|
|
44
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
45
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvU3RvcmUvdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLFFBQVEsQ0FBQTtBQUNuQyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLFlBQVksQ0FBQTtBQUMzQyxPQUFPLEVBQUUsOEJBQThCLEVBQUUsTUFBTSxjQUFjLENBQUE7QUFHN0QsTUFBTSxDQUFDLE1BQU0sUUFBUSxHQUFHLENBQ3RCLEVBQUUsS0FBSyxFQUFFLEdBQUcsQ0FBQyxFQUFLLEVBQ2YsRUFBRSxDQUNMLENBQUM7SUFDQyxHQUFHLENBQUM7SUFDSix5R0FBeUc7SUFDekcsS0FBSyxFQUFFLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUM7Q0FDcEUsQ0FBUSxDQUFBO0FBRVgsTUFBTSxDQUFDLE1BQU0sY0FBYyxHQUN6QixDQUFDLElBQVksRUFBRSxFQUFFLENBQUMsQ0FBaUQsQ0FBSSxFQUFFLE9BQWtCLEVBQUUsRUFBRSxDQUM3RixNQUFNLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQztJQUNsQixJQUFJLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNaLEtBQUssQ0FBQyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQ3BCLE9BQU8sRUFDUCxHQUFHLEVBQUUsQ0FBQyxJQUFJLDhCQUE4QixDQUFDLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLE9BQU8sRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUMxRixDQUFBO0lBQ0gsQ0FBQztJQUNELElBQUksTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssS0FBSyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDOUQsT0FBTyxLQUFLLENBQUMsQ0FBQyxJQUFJLDhCQUE4QixDQUFDO1lBQy9DLElBQUk7WUFDSixFQUFFLEVBQUUsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFO1lBQ3BCLE9BQU8sRUFBRSxPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUs7WUFDNUIsS0FBSyxFQUFFLENBQUMsQ0FBQyxLQUFLO1NBQ2YsQ0FBQyxDQUFBO0lBQ0osQ0FBQztJQUNELE1BQU0sSUFBSSxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUN4QixPQUFPLElBQUksQ0FBQTtBQUNiLENBQUMsQ0FBQyxDQUFBO0FBRU4sTUFBTSxVQUFVLGlCQUFpQixDQUFJLEdBQU07SUFDekMsSUFBSSxPQUFPLEdBQUcsS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUM1QixPQUFPLEdBQUcsQ0FBQyxXQUFXLEVBQUUsQ0FBQTtJQUMxQixDQUFDO0lBQ0QsT0FBTyxHQUFHLENBQUE7QUFDWixDQUFDO0FBRUQsTUFBTSxVQUFVLE9BQU8sQ0FBQyxJQUFhLEVBQUUsSUFBYTtJQUNsRCxPQUFPLElBQUksS0FBSyxJQUFJLENBQUE7QUFDdEIsQ0FBQztBQUVELE1BQU0sVUFBVSxTQUFTLENBQUMsSUFBc0IsRUFBRSxJQUFzQjtJQUN0RSxPQUFPLElBQUksR0FBRyxJQUFJLENBQUE7QUFDcEIsQ0FBQztBQUVELE1BQU0sVUFBVSxrQkFBa0IsQ0FBQyxJQUFzQixFQUFFLElBQXNCO0lBQy9FLE9BQU8sSUFBSSxJQUFJLElBQUksQ0FBQTtBQUNyQixDQUFDO0FBRUQsTUFBTSxVQUFVLFdBQVcsQ0FBQyxJQUFzQixFQUFFLElBQXNCO0lBQ3hFLE9BQU8sSUFBSSxHQUFHLElBQUksQ0FBQTtBQUNwQixDQUFDO0FBRUQsTUFBTSxVQUFVLG9CQUFvQixDQUFDLElBQXNCLEVBQUUsSUFBc0I7SUFDakYsT0FBTyxJQUFJLElBQUksSUFBSSxDQUFBO0FBQ3JCLENBQUMifQ==
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import type * as HttpApp from "@effect/platform/HttpApp";
|
|
2
|
+
import { Rpc, RpcRouter } from "@effect/rpc";
|
|
3
|
+
import type { NonEmptyArray } from "effect-app";
|
|
4
|
+
import { Effect, Layer, S } from "effect-app";
|
|
5
|
+
import type { GetEffectContext, RPCContextMap } from "effect-app/client/req";
|
|
6
|
+
import type { HttpServerError } from "effect-app/http";
|
|
7
|
+
import { HttpRouter } from "effect-app/http";
|
|
8
|
+
import type { Middleware } from "./routing/DynamicMiddleware.js";
|
|
9
|
+
export type _R<T extends Effect<any, any, any>> = [T] extends [
|
|
10
|
+
Effect<any, any, infer R>
|
|
11
|
+
] ? R : never;
|
|
12
|
+
export type _E<T extends Effect<any, any, any>> = [T] extends [
|
|
13
|
+
Effect<any, infer E, any>
|
|
14
|
+
] ? E : never;
|
|
15
|
+
export type EffectDeps<A> = {
|
|
16
|
+
[K in keyof A as A[K] extends Effect<any, any, any> ? K : never]: A[K] extends Effect<any, any, any> ? A[K] : never;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Plain jane JSON version
|
|
20
|
+
* @deprecated use HttpRpcRouterNoStream.toHttpApp once support options
|
|
21
|
+
*/
|
|
22
|
+
export declare const toHttpApp: <R extends RpcRouter.RpcRouter<any, any>>(self: R, options?: {
|
|
23
|
+
readonly spanPrefix?: string;
|
|
24
|
+
}) => HttpApp.Default<HttpServerError.RequestError, RpcRouter.RpcRouter.Context<R>>;
|
|
25
|
+
export interface Hint<Err extends string> {
|
|
26
|
+
Err: Err;
|
|
27
|
+
}
|
|
28
|
+
type HandleVoid<Expected, Actual, Result> = [Expected] extends [void] ? [Actual] extends [void] ? Result : Hint<"You're returning non void for a void Response, please fix"> : Result;
|
|
29
|
+
type AnyRequestModule = S.Schema.Any & {
|
|
30
|
+
success?: S.Schema.Any;
|
|
31
|
+
failure?: S.Schema.Any;
|
|
32
|
+
};
|
|
33
|
+
type GetSuccess<T> = T extends {
|
|
34
|
+
success: S.Schema.Any;
|
|
35
|
+
} ? T["success"] : typeof S.Void;
|
|
36
|
+
type GetSuccessShape<Action extends {
|
|
37
|
+
success?: S.Schema.Any;
|
|
38
|
+
}, RT extends "d" | "raw"> = RT extends "raw" ? S.Schema.Encoded<GetSuccess<Action>> : S.Schema.Type<GetSuccess<Action>>;
|
|
39
|
+
type GetFailure<T extends {
|
|
40
|
+
failure?: S.Schema.Any;
|
|
41
|
+
}> = T["failure"] extends never ? typeof S.Never : T["failure"];
|
|
42
|
+
type HandlerFull<Action extends AnyRequestModule, RT extends "raw" | "d", A, E, R> = {
|
|
43
|
+
new (): {};
|
|
44
|
+
_tag: RT;
|
|
45
|
+
stack: string;
|
|
46
|
+
handler: (req: S.Schema.Type<Action>) => Effect<A, E, R>;
|
|
47
|
+
};
|
|
48
|
+
export interface Handler<Action extends AnyRequestModule, RT extends "raw" | "d", R> extends HandlerFull<Action, RT, GetSuccessShape<Action, RT>, S.Schema.Type<GetFailure<Action>> | S.ParseResult.ParseError, R> {
|
|
49
|
+
}
|
|
50
|
+
type AHandler<Action extends AnyRequestModule> = Handler<Action, any, any>;
|
|
51
|
+
type Filter<T> = {
|
|
52
|
+
[K in keyof T as T[K] extends S.Schema.All & {
|
|
53
|
+
success: S.Schema.Any;
|
|
54
|
+
failure: S.Schema.Any;
|
|
55
|
+
} ? K : never]: T[K];
|
|
56
|
+
};
|
|
57
|
+
export declare const RouterSymbol: unique symbol;
|
|
58
|
+
export interface RouterShape<Rsc> {
|
|
59
|
+
[RouterSymbol]: Rsc;
|
|
60
|
+
}
|
|
61
|
+
type RPCRouteR<T extends Rpc.Rpc<any, any>> = [T] extends [
|
|
62
|
+
Rpc.Rpc<any, infer R>
|
|
63
|
+
] ? R : never;
|
|
64
|
+
type Match<Rsc extends Record<string, any>, CTXMap extends Record<string, any>, RT extends "raw" | "d", Key extends keyof Rsc, Context> = {
|
|
65
|
+
<A extends GetSuccessShape<Rsc[Key], RT>, R2 = never, E = never>(f: Effect<A, E, R2>): HandleVoid<GetSuccessShape<Rsc[Key], RT>, A, Handler<Rsc[Key], RT, Exclude<Context | Exclude<R2, GetEffectContext<CTXMap, Rsc[Key]["config"]>>, HttpRouter.HttpRouter.Provided>>>;
|
|
66
|
+
<A extends GetSuccessShape<Rsc[Key], RT>, R2 = never, E = never>(f: (req: S.Schema.Type<Rsc[Key]>) => Effect<A, E, R2>): HandleVoid<GetSuccessShape<Rsc[Key], RT>, A, Handler<Rsc[Key], RT, Exclude<Context | Exclude<R2, GetEffectContext<CTXMap, Rsc[Key]["config"]>>, HttpRouter.HttpRouter.Provided>>>;
|
|
67
|
+
};
|
|
68
|
+
export type RouteMatcher<CTXMap extends Record<string, any>, Rsc extends Record<string, any>, Context> = {
|
|
69
|
+
[Key in keyof Filter<Rsc>]: Match<Rsc, CTXMap, "d", Key, Context> & {
|
|
70
|
+
success: Rsc[Key]["success"];
|
|
71
|
+
successRaw: S.SchemaClass<S.Schema.Encoded<Rsc[Key]["success"]>>;
|
|
72
|
+
failure: Rsc[Key]["failure"];
|
|
73
|
+
/**
|
|
74
|
+
* Requires the Encoded shape (e.g directly undecoded from DB, so that we don't do multiple Decode/Encode)
|
|
75
|
+
*/
|
|
76
|
+
raw: Match<Rsc, CTXMap, "raw", Key, Context>;
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
export declare const makeMiddleware: <Context, CTXMap extends Record<string, RPCContextMap.Any>, RMW, Layers extends Array<Layer.Layer.Any>>(content: Middleware<Context, CTXMap, RMW, Layers>) => Middleware<Context, CTXMap, RMW, Layers>;
|
|
80
|
+
export declare const makeRouter: <Context, CTXMap extends Record<string, RPCContextMap.Any>, RMW, Layers extends Array<Layer.Layer.Any>>(middleware: Middleware<Context, CTXMap, RMW, Layers>, devMode: boolean) => {
|
|
81
|
+
matchAll: <T extends {
|
|
82
|
+
[key: string]: {
|
|
83
|
+
Router: {
|
|
84
|
+
router: Effect<HttpRouter.HttpRouter<any, any>, any, any>;
|
|
85
|
+
};
|
|
86
|
+
routes: Layer.Layer<any, any, any>;
|
|
87
|
+
moduleName: string;
|
|
88
|
+
};
|
|
89
|
+
}, A, E, R>(handlers: T, requestLayer: Layer.Layer<A, E, R>) => {
|
|
90
|
+
layer: Layer.Layer<never, Layer.Layer.Error<(typeof handlers)[keyof typeof handlers]["routes"]>, Layer.Layer.Context<(typeof handlers)[keyof typeof handlers]["routes"]>>;
|
|
91
|
+
Router: HttpRouter.HttpRouter.TagClass<"RootRouter", "RootRouter", Effect.Effect.Success<T[keyof T]["Router"]["router"]> extends infer T_1 ? T_1 extends Effect.Effect.Success<T[keyof T]["Router"]["router"]> ? T_1 extends HttpRouter.HttpRouter<infer E_1, any> ? E_1 : never : never : never, R | Exclude<Effect.Effect.Success<T[keyof T]["Router"]["router"]> extends infer T_2 ? T_2 extends Effect.Effect.Success<T[keyof T]["Router"]["router"]> ? T_2 extends HttpRouter.HttpRouter<any, infer R_1> ? R_1 : never : never : never, A>>;
|
|
92
|
+
};
|
|
93
|
+
matchFor: <const ModuleName extends string, const Rsc extends Record<string, any>>(rsc: Rsc & {
|
|
94
|
+
meta: {
|
|
95
|
+
moduleName: ModuleName;
|
|
96
|
+
};
|
|
97
|
+
}) => <E_1, R_1, THandlers extends { [K in keyof Filter<Rsc>]: AHandler<Rsc[K]>; }, TLayers extends NonEmptyArray<Layer.Layer.Any>>(layers: TLayers, make: (requests: RouteMatcher<CTXMap, Rsc, Context>) => Effect<THandlers, E_1, R_1>) => {
|
|
98
|
+
moduleName: ModuleName;
|
|
99
|
+
Router: HttpRouter.HttpRouter.TagClass<RouterShape<Rsc>, `${ModuleName}Router`, never, Exclude<Context, HttpRouter.HttpRouter.Provided> | Exclude<RPCRouteR<{ [K in keyof Filter<Rsc>]: Rpc.Rpc<Rsc[K], _R<ReturnType<THandlers[K]["handler"]>>>; }[keyof Filter<Rsc>]>, HttpRouter.HttpRouter.Provided>>;
|
|
100
|
+
routes: Layer.Layer<RouterShape<Rsc>, E_1 | { [k in keyof TLayers]: Layer.Layer.Error<TLayers[k]>; }[number], { [k_1 in keyof TLayers]: Layer.Layer.Context<TLayers[k_1]>; }[number] | Exclude<RMW, { [k_2 in keyof Layers]: Layer.Layer.Success<Layers[k_2]>; }[number] | { [k_3 in keyof TLayers]: Layer.Layer.Success<TLayers[k_3]>; }[number]> | Exclude<R_1, { [k_2 in keyof Layers]: Layer.Layer.Success<Layers[k_2]>; }[number] | { [k_3 in keyof TLayers]: Layer.Layer.Success<TLayers[k_3]>; }[number]>>;
|
|
101
|
+
};
|
|
102
|
+
};
|
|
103
|
+
export {};
|
|
104
|
+
//# sourceMappingURL=routing4.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routing4.d.ts","sourceRoot":"","sources":["../../src/api/routing4.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { Rpc, RpcRouter } from "@effect/rpc";
|
|
2
|
+
import { Cause, Chunk, Context, Effect, FiberRef, flow, Layer, Predicate, S, Schema, Stream } from "effect-app";
|
|
3
|
+
import { HttpRouter, HttpServerRequest, HttpServerResponse } from "effect-app/http";
|
|
4
|
+
import { pretty, typedKeysOf, typedValuesOf } from "effect-app/utils";
|
|
5
|
+
import { logError, reportError } from "../errorReporter.js";
|
|
6
|
+
import { InfraLogger } from "../logger.js";
|
|
7
|
+
import { makeRpc } from "./routing/DynamicMiddleware.js";
|
|
8
|
+
const logRequestError = logError("Request");
|
|
9
|
+
const reportRequestError = reportError("Request");
|
|
10
|
+
/**
|
|
11
|
+
* Plain jane JSON version
|
|
12
|
+
* @deprecated use HttpRpcRouterNoStream.toHttpApp once support options
|
|
13
|
+
*/
|
|
14
|
+
export const toHttpApp = (self, options) => {
|
|
15
|
+
const handler = RpcRouter.toHandler(self, options);
|
|
16
|
+
return Effect.withFiberRuntime((fiber) => {
|
|
17
|
+
const context = fiber.getFiberRef(FiberRef.currentContext);
|
|
18
|
+
const request = Context.unsafeGet(context, HttpServerRequest.HttpServerRequest);
|
|
19
|
+
return Effect.flatMap(request.json, (_) => handler(_).pipe(Stream.provideContext(context), Stream.runCollect, Effect.map((_) => Chunk.toReadonlyArray(_)), Effect.andThen((_) => {
|
|
20
|
+
let status = 200;
|
|
21
|
+
for (const r of _.flat()) {
|
|
22
|
+
if (typeof r === "number")
|
|
23
|
+
continue;
|
|
24
|
+
const results = Array.isArray(r) ? r : [r];
|
|
25
|
+
if (results.some((_) => _._tag === "Failure" && _.cause._tag === "Die")) {
|
|
26
|
+
status = 500;
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
if (results.some((_) => _._tag === "Failure" && _.cause._tag === "Fail")) {
|
|
30
|
+
status = 422; // 418
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return HttpServerResponse.json(_, { status });
|
|
35
|
+
}), Effect.orDie, Effect.tapDefect(reportError("RPCHttpApp"))));
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
export const RouterSymbol = Symbol();
|
|
39
|
+
// export interface RouteMatcher<
|
|
40
|
+
// Filtered extends Record<string, any>,
|
|
41
|
+
// CTXMap extends Record<string, any>,
|
|
42
|
+
// Rsc extends Filtered
|
|
43
|
+
// > extends RouteMatcherInt<Filtered, CTXMap, Rsc> {}
|
|
44
|
+
export const makeMiddleware = (content) => content;
|
|
45
|
+
export const makeRouter = (middleware, devMode) => {
|
|
46
|
+
function matchFor(rsc) {
|
|
47
|
+
const meta = rsc.meta;
|
|
48
|
+
const filtered = typedKeysOf(rsc).reduce((acc, cur) => {
|
|
49
|
+
if (Predicate.isObject(rsc[cur]) && rsc[cur]["success"]) {
|
|
50
|
+
acc[cur] = rsc[cur];
|
|
51
|
+
}
|
|
52
|
+
return acc;
|
|
53
|
+
}, {});
|
|
54
|
+
const items = typedKeysOf(filtered).reduce((prev, cur) => {
|
|
55
|
+
;
|
|
56
|
+
prev[cur] = Object.assign((fnOrEffect) => {
|
|
57
|
+
const stack = new Error().stack?.split("\n").slice(2).join("\n");
|
|
58
|
+
return Effect.isEffect(fnOrEffect)
|
|
59
|
+
? class {
|
|
60
|
+
static stack = stack;
|
|
61
|
+
static _tag = "d";
|
|
62
|
+
static handler = () => fnOrEffect;
|
|
63
|
+
}
|
|
64
|
+
: class {
|
|
65
|
+
static stack = stack;
|
|
66
|
+
static _tag = "d";
|
|
67
|
+
static handler = fnOrEffect;
|
|
68
|
+
};
|
|
69
|
+
}, {
|
|
70
|
+
success: rsc[cur].success,
|
|
71
|
+
successRaw: S.encodedSchema(rsc[cur].success),
|
|
72
|
+
failure: rsc[cur].failure,
|
|
73
|
+
raw: // "Raw" variations are for when you don't want to decode just to encode it again on the response
|
|
74
|
+
// e.g for direct projection from DB
|
|
75
|
+
// but more importantly, to skip Effectful decoders, like to resolve relationships from the database or remote client.
|
|
76
|
+
(fnOrEffect) => {
|
|
77
|
+
const stack = new Error().stack?.split("\n").slice(2).join("\n");
|
|
78
|
+
return Effect.isEffect(fnOrEffect)
|
|
79
|
+
? class {
|
|
80
|
+
static stack = stack;
|
|
81
|
+
static _tag = "raw";
|
|
82
|
+
static handler = () => fnOrEffect;
|
|
83
|
+
}
|
|
84
|
+
: class {
|
|
85
|
+
static stack = stack;
|
|
86
|
+
static _tag = "raw";
|
|
87
|
+
static handler = (req, ctx) => fnOrEffect(req, { ...ctx, Response: rsc[cur].success });
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
return prev;
|
|
92
|
+
}, {});
|
|
93
|
+
const effect = (layers, make) => {
|
|
94
|
+
const r = (class Router extends HttpRouter.Tag(`${meta.moduleName}Router`)() {
|
|
95
|
+
});
|
|
96
|
+
const layer = r.use((router) => Effect.gen(function* () {
|
|
97
|
+
const controllers = yield* make(items);
|
|
98
|
+
const rpc = yield* makeRpc(middleware);
|
|
99
|
+
// return make.pipe(Effect.map((c) => controllers(c, layers)))
|
|
100
|
+
const mapped = typedKeysOf(filtered).reduce((acc, cur) => {
|
|
101
|
+
const handler = controllers[cur];
|
|
102
|
+
const req = rsc[cur];
|
|
103
|
+
acc[cur] = rpc.effect(handler._tag === "raw"
|
|
104
|
+
? class extends req {
|
|
105
|
+
static success = S.encodedSchema(req.success);
|
|
106
|
+
get [Schema.symbolSerializable]() {
|
|
107
|
+
return this.constructor;
|
|
108
|
+
}
|
|
109
|
+
get [Schema.symbolWithResult]() {
|
|
110
|
+
return {
|
|
111
|
+
failure: req.failure,
|
|
112
|
+
success: S.encodedSchema(req.success)
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
: req, (req) => Effect
|
|
117
|
+
.annotateCurrentSpan("requestInput", Object.entries(req).reduce((prev, [key, value]) => {
|
|
118
|
+
prev[key] = key === "password"
|
|
119
|
+
? "<redacted>"
|
|
120
|
+
: typeof value === "string" || typeof value === "number" || typeof value === "boolean"
|
|
121
|
+
? typeof value === "string" && value.length > 256
|
|
122
|
+
? (value.substring(0, 253) + "...")
|
|
123
|
+
: value
|
|
124
|
+
: Array.isArray(value)
|
|
125
|
+
? `Array[${value.length}]`
|
|
126
|
+
: value === null || value === undefined
|
|
127
|
+
? `${value}`
|
|
128
|
+
: typeof value === "object" && value
|
|
129
|
+
? `Object[${Object.keys(value).length}]`
|
|
130
|
+
: typeof value;
|
|
131
|
+
return prev;
|
|
132
|
+
}, {}))
|
|
133
|
+
.pipe(
|
|
134
|
+
// can't use andThen due to some being a function and effect
|
|
135
|
+
Effect.zipRight(handler.handler(req)), Effect.tapErrorCause((cause) => Cause.isFailure(cause) ? logRequestError(cause) : Effect.void), Effect.tapDefect((cause) => Effect
|
|
136
|
+
.all([
|
|
137
|
+
reportRequestError(cause, {
|
|
138
|
+
action: `${meta.moduleName}.${req._tag}`
|
|
139
|
+
}),
|
|
140
|
+
Rpc.currentHeaders.pipe(Effect.andThen((headers) => {
|
|
141
|
+
return InfraLogger
|
|
142
|
+
.logError("Finished request", cause)
|
|
143
|
+
.pipe(Effect.annotateLogs({
|
|
144
|
+
action: `${meta.moduleName}.${req._tag}`,
|
|
145
|
+
req: pretty(req),
|
|
146
|
+
headers: pretty(headers)
|
|
147
|
+
// resHeaders: pretty(
|
|
148
|
+
// Object
|
|
149
|
+
// .entries(headers)
|
|
150
|
+
// .reduce((prev, [key, value]) => {
|
|
151
|
+
// prev[key] = value && typeof value === "string" ? snipString(value) : value
|
|
152
|
+
// return prev
|
|
153
|
+
// }, {} as Record<string, any>)
|
|
154
|
+
// )
|
|
155
|
+
}));
|
|
156
|
+
}))
|
|
157
|
+
])), devMode ? (_) => _ : Effect.catchAllDefect(() => Effect.die("Internal Server Error")), Effect.withSpan("Request." + meta.moduleName + "." + req._tag, {
|
|
158
|
+
captureStackTrace: () => handler.stack
|
|
159
|
+
})), meta.moduleName); // TODO
|
|
160
|
+
return acc;
|
|
161
|
+
}, {});
|
|
162
|
+
const rpcRouter = RpcRouter.make(...Object.values(mapped));
|
|
163
|
+
const httpApp = toHttpApp(rpcRouter, {
|
|
164
|
+
spanPrefix: rsc
|
|
165
|
+
.meta
|
|
166
|
+
.moduleName + "."
|
|
167
|
+
});
|
|
168
|
+
yield* router
|
|
169
|
+
.all("/", httpApp,
|
|
170
|
+
// TODO: not queries.
|
|
171
|
+
{ uninterruptible: true });
|
|
172
|
+
}));
|
|
173
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
174
|
+
const routes = layer.pipe(Layer.provideMerge(r.Live), layers ? Layer.provide(layers) : (_) => _,
|
|
175
|
+
// TODO: only provide to the middleware?
|
|
176
|
+
middleware.dependencies ? Layer.provide(middleware.dependencies) : (_) => _);
|
|
177
|
+
// Effect.Effect<HttpRouter.HttpRouter<unknown, HttpRouter.HttpRouter.DefaultServices>, never, UserRouter>
|
|
178
|
+
return {
|
|
179
|
+
moduleName: meta.moduleName,
|
|
180
|
+
Router: r,
|
|
181
|
+
routes
|
|
182
|
+
};
|
|
183
|
+
};
|
|
184
|
+
return effect;
|
|
185
|
+
}
|
|
186
|
+
function matchAll(handlers, requestLayer) {
|
|
187
|
+
const routers = typedValuesOf(handlers);
|
|
188
|
+
const rootRouter = class extends HttpRouter.Tag("RootRouter")() {
|
|
189
|
+
};
|
|
190
|
+
const r = rootRouter
|
|
191
|
+
.use((router) => Effect.gen(function* () {
|
|
192
|
+
for (const route of routers) {
|
|
193
|
+
yield* router.mount(("/rpc/" + route.moduleName), yield* route
|
|
194
|
+
.Router
|
|
195
|
+
.router
|
|
196
|
+
.pipe(Effect.map(HttpRouter.use(flow(Effect.provide(requestLayer))))));
|
|
197
|
+
}
|
|
198
|
+
}))
|
|
199
|
+
.pipe(Layer.provide(routers.map((r) => r.routes).flat()));
|
|
200
|
+
return {
|
|
201
|
+
layer: r,
|
|
202
|
+
Router: rootRouter
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
return { matchAll, matchFor };
|
|
206
|
+
};
|
|
207
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGluZzQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL3JvdXRpbmc0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQVFBLE9BQU8sRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLE1BQU0sYUFBYSxDQUFBO0FBRTVDLE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sWUFBWSxDQUFBO0FBRy9HLE9BQU8sRUFBRSxVQUFVLEVBQUUsaUJBQWlCLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQTtBQUNuRixPQUFPLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBRSxhQUFhLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQTtBQUNyRSxPQUFPLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxNQUFNLHFCQUFxQixDQUFBO0FBQzNELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxjQUFjLENBQUE7QUFFMUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGdDQUFnQyxDQUFBO0FBRXhELE1BQU0sZUFBZSxHQUFHLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQTtBQUMzQyxNQUFNLGtCQUFrQixHQUFHLFdBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQTtBQWVqRDs7O0dBR0c7QUFDSCxNQUFNLENBQUMsTUFBTSxTQUFTLEdBQUcsQ0FBMEMsSUFBTyxFQUFFLE9BRTNFLEVBR0MsRUFBRTtJQUNGLE1BQU0sT0FBTyxHQUFHLFNBQVMsQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFBO0lBQ2xELE9BQU8sTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUU7UUFDdkMsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLFdBQVcsQ0FBQyxR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
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effect-app/infra",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.2",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"dependencies": {
|
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
"cross-fetch": "^4.0.0",
|
|
10
10
|
"express-oauth2-jwt-bearer": "^1.6.0",
|
|
11
11
|
"fast-check": "~3.22.0",
|
|
12
|
-
"object-hash": "^3.0.0",
|
|
13
12
|
"path-parser": "^6.1.0",
|
|
14
13
|
"proper-lockfile": "^4.1.2",
|
|
15
14
|
"pure-rand": "6.1.0",
|
|
@@ -660,6 +659,16 @@
|
|
|
660
659
|
"default": "./_cjs/api/routing/schema/jwt.cjs"
|
|
661
660
|
}
|
|
662
661
|
},
|
|
662
|
+
"./api/routing4": {
|
|
663
|
+
"import": {
|
|
664
|
+
"types": "./dist/api/routing4.d.ts",
|
|
665
|
+
"default": "./dist/api/routing4.js"
|
|
666
|
+
},
|
|
667
|
+
"require": {
|
|
668
|
+
"types": "./dist/api/routing4.d.ts",
|
|
669
|
+
"default": "./_cjs/api/routing4.cjs"
|
|
670
|
+
}
|
|
671
|
+
},
|
|
663
672
|
"./api/setupRequest": {
|
|
664
673
|
"import": {
|
|
665
674
|
"types": "./dist/api/setupRequest.d.ts",
|
package/src/Store/utils.ts
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
|
+
import { createHash } from "crypto"
|
|
1
2
|
import { Effect, Option } from "effect-app"
|
|
2
|
-
import objectHash from "object-hash"
|
|
3
3
|
import { OptimisticConcurrencyException } from "../errors.js"
|
|
4
4
|
import type { PersistenceModelType, SupportedValues2 } from "./service.js"
|
|
5
5
|
|
|
6
6
|
export const makeETag = <E extends PersistenceModelType<{}>>(
|
|
7
7
|
{ _etag, ...e }: E
|
|
8
|
-
): E =>
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
): E =>
|
|
9
|
+
({
|
|
10
|
+
...e,
|
|
11
|
+
// we have to hash the JSON, as hashing the object might contain elements that won't be serialized anyway
|
|
12
|
+
_etag: createHash("sha256").update(JSON.stringify(e)).digest("hex")
|
|
13
|
+
}) as any
|
|
14
|
+
|
|
12
15
|
export const makeUpdateETag =
|
|
13
16
|
(type: string) => <E extends PersistenceModelType<{ id: string }>>(e: E, current: Option<E>) =>
|
|
14
17
|
Effect.gen(function*() {
|
|
@@ -0,0 +1,510 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-empty-object-type */
|
|
3
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
4
|
+
/*
|
|
5
|
+
TODO: Effect.retry(r2, optimisticConcurrencySchedule) / was for PATCH only
|
|
6
|
+
TODO: uninteruptible commands! was for All except GET.
|
|
7
|
+
*/
|
|
8
|
+
import type * as HttpApp from "@effect/platform/HttpApp"
|
|
9
|
+
import { Rpc, RpcRouter } from "@effect/rpc"
|
|
10
|
+
import type { NonEmptyArray } from "effect-app"
|
|
11
|
+
import { Cause, Chunk, Context, Effect, FiberRef, flow, Layer, Predicate, S, Schema, Stream } from "effect-app"
|
|
12
|
+
import type { GetEffectContext, RPCContextMap } from "effect-app/client/req"
|
|
13
|
+
import type { HttpServerError } from "effect-app/http"
|
|
14
|
+
import { HttpRouter, HttpServerRequest, HttpServerResponse } from "effect-app/http"
|
|
15
|
+
import { pretty, typedKeysOf, typedValuesOf } from "effect-app/utils"
|
|
16
|
+
import { logError, reportError } from "../errorReporter.js"
|
|
17
|
+
import { InfraLogger } from "../logger.js"
|
|
18
|
+
import type { Middleware } from "./routing/DynamicMiddleware.js"
|
|
19
|
+
import { makeRpc } from "./routing/DynamicMiddleware.js"
|
|
20
|
+
|
|
21
|
+
const logRequestError = logError("Request")
|
|
22
|
+
const reportRequestError = reportError("Request")
|
|
23
|
+
|
|
24
|
+
export type _R<T extends Effect<any, any, any>> = [T] extends [
|
|
25
|
+
Effect<any, any, infer R>
|
|
26
|
+
] ? R
|
|
27
|
+
: never
|
|
28
|
+
|
|
29
|
+
export type _E<T extends Effect<any, any, any>> = [T] extends [
|
|
30
|
+
Effect<any, infer E, any>
|
|
31
|
+
] ? E
|
|
32
|
+
: never
|
|
33
|
+
|
|
34
|
+
export type EffectDeps<A> = {
|
|
35
|
+
[K in keyof A as A[K] extends Effect<any, any, any> ? K : never]: A[K] extends Effect<any, any, any> ? A[K] : never
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Plain jane JSON version
|
|
39
|
+
* @deprecated use HttpRpcRouterNoStream.toHttpApp once support options
|
|
40
|
+
*/
|
|
41
|
+
export const toHttpApp = <R extends RpcRouter.RpcRouter<any, any>>(self: R, options?: {
|
|
42
|
+
readonly spanPrefix?: string
|
|
43
|
+
}): HttpApp.Default<
|
|
44
|
+
HttpServerError.RequestError,
|
|
45
|
+
RpcRouter.RpcRouter.Context<R>
|
|
46
|
+
> => {
|
|
47
|
+
const handler = RpcRouter.toHandler(self, options)
|
|
48
|
+
return Effect.withFiberRuntime((fiber) => {
|
|
49
|
+
const context = fiber.getFiberRef(FiberRef.currentContext)
|
|
50
|
+
const request = Context.unsafeGet(context, HttpServerRequest.HttpServerRequest)
|
|
51
|
+
return Effect.flatMap(
|
|
52
|
+
request.json,
|
|
53
|
+
(_) =>
|
|
54
|
+
handler(_).pipe(
|
|
55
|
+
Stream.provideContext(context),
|
|
56
|
+
Stream.runCollect,
|
|
57
|
+
Effect.map((_) => Chunk.toReadonlyArray(_)),
|
|
58
|
+
Effect.andThen((_) => {
|
|
59
|
+
let status = 200
|
|
60
|
+
for (const r of _.flat()) {
|
|
61
|
+
if (typeof r === "number") continue
|
|
62
|
+
const results = Array.isArray(r) ? r : [r]
|
|
63
|
+
if (results.some((_: S.ExitEncoded<any, any, any>) => _._tag === "Failure" && _.cause._tag === "Die")) {
|
|
64
|
+
status = 500
|
|
65
|
+
break
|
|
66
|
+
}
|
|
67
|
+
if (results.some((_: S.ExitEncoded<any, any, any>) => _._tag === "Failure" && _.cause._tag === "Fail")) {
|
|
68
|
+
status = 422 // 418
|
|
69
|
+
break
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return HttpServerResponse.json(_, { status })
|
|
73
|
+
}),
|
|
74
|
+
Effect.orDie,
|
|
75
|
+
Effect.tapDefect(reportError("RPCHttpApp"))
|
|
76
|
+
)
|
|
77
|
+
)
|
|
78
|
+
})
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface Hint<Err extends string> {
|
|
82
|
+
Err: Err
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
type HandleVoid<Expected, Actual, Result> = [Expected] extends [void]
|
|
86
|
+
? [Actual] extends [void] ? Result : Hint<"You're returning non void for a void Response, please fix">
|
|
87
|
+
: Result
|
|
88
|
+
|
|
89
|
+
type AnyRequestModule = S.Schema.Any & { success?: S.Schema.Any; failure?: S.Schema.Any }
|
|
90
|
+
|
|
91
|
+
type GetSuccess<T> = T extends { success: S.Schema.Any } ? T["success"] : typeof S.Void
|
|
92
|
+
|
|
93
|
+
type GetSuccessShape<Action extends { success?: S.Schema.Any }, RT extends "d" | "raw"> = RT extends "raw"
|
|
94
|
+
? S.Schema.Encoded<GetSuccess<Action>>
|
|
95
|
+
: S.Schema.Type<GetSuccess<Action>>
|
|
96
|
+
type GetFailure<T extends { failure?: S.Schema.Any }> = T["failure"] extends never ? typeof S.Never : T["failure"]
|
|
97
|
+
|
|
98
|
+
type HandlerFull<Action extends AnyRequestModule, RT extends "raw" | "d", A, E, R> = {
|
|
99
|
+
new(): {}
|
|
100
|
+
_tag: RT
|
|
101
|
+
stack: string
|
|
102
|
+
handler: (
|
|
103
|
+
req: S.Schema.Type<Action>
|
|
104
|
+
) => Effect<
|
|
105
|
+
A,
|
|
106
|
+
E,
|
|
107
|
+
R
|
|
108
|
+
>
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export interface Handler<Action extends AnyRequestModule, RT extends "raw" | "d", R> extends
|
|
112
|
+
HandlerFull<
|
|
113
|
+
Action,
|
|
114
|
+
RT,
|
|
115
|
+
GetSuccessShape<Action, RT>,
|
|
116
|
+
S.Schema.Type<GetFailure<Action>> | S.ParseResult.ParseError,
|
|
117
|
+
R
|
|
118
|
+
>
|
|
119
|
+
{
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
type AHandler<Action extends AnyRequestModule> = Handler<
|
|
123
|
+
Action,
|
|
124
|
+
any,
|
|
125
|
+
any
|
|
126
|
+
>
|
|
127
|
+
|
|
128
|
+
type Filter<T> = {
|
|
129
|
+
[K in keyof T as T[K] extends S.Schema.All & { success: S.Schema.Any; failure: S.Schema.Any } ? K : never]: T[K]
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export const RouterSymbol = Symbol()
|
|
133
|
+
export interface RouterShape<Rsc> {
|
|
134
|
+
[RouterSymbol]: Rsc
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
type RPCRouteR<T extends Rpc.Rpc<any, any>> = [T] extends [
|
|
138
|
+
Rpc.Rpc<any, infer R>
|
|
139
|
+
] ? R
|
|
140
|
+
: never
|
|
141
|
+
|
|
142
|
+
type RPCRouteReq<T extends Rpc.Rpc<any, any>> = [T] extends [
|
|
143
|
+
Rpc.Rpc<infer Req, any>
|
|
144
|
+
] ? Req
|
|
145
|
+
: never
|
|
146
|
+
|
|
147
|
+
type Match<
|
|
148
|
+
Rsc extends Record<string, any>,
|
|
149
|
+
CTXMap extends Record<string, any>,
|
|
150
|
+
RT extends "raw" | "d",
|
|
151
|
+
Key extends keyof Rsc,
|
|
152
|
+
Context
|
|
153
|
+
> = {
|
|
154
|
+
// TODO: deal with HandleVoid and ability to extends from GetSuccessShape...
|
|
155
|
+
// aka we want to make sure that the return type is void if the success is void,
|
|
156
|
+
// and make sure A is the actual expected type
|
|
157
|
+
|
|
158
|
+
// note: the defaults of = never prevent the whole router to error
|
|
159
|
+
<A extends GetSuccessShape<Rsc[Key], RT>, R2 = never, E = never>(
|
|
160
|
+
f: Effect<A, E, R2>
|
|
161
|
+
): HandleVoid<
|
|
162
|
+
GetSuccessShape<Rsc[Key], RT>,
|
|
163
|
+
A,
|
|
164
|
+
Handler<
|
|
165
|
+
Rsc[Key],
|
|
166
|
+
RT,
|
|
167
|
+
Exclude<
|
|
168
|
+
Context | Exclude<R2, GetEffectContext<CTXMap, Rsc[Key]["config"]>>,
|
|
169
|
+
HttpRouter.HttpRouter.Provided
|
|
170
|
+
>
|
|
171
|
+
>
|
|
172
|
+
>
|
|
173
|
+
|
|
174
|
+
<A extends GetSuccessShape<Rsc[Key], RT>, R2 = never, E = never>(
|
|
175
|
+
f: (req: S.Schema.Type<Rsc[Key]>) => Effect<A, E, R2>
|
|
176
|
+
): HandleVoid<
|
|
177
|
+
GetSuccessShape<Rsc[Key], RT>,
|
|
178
|
+
A,
|
|
179
|
+
Handler<
|
|
180
|
+
Rsc[Key],
|
|
181
|
+
RT,
|
|
182
|
+
Exclude<
|
|
183
|
+
Context | Exclude<R2, GetEffectContext<CTXMap, Rsc[Key]["config"]>>,
|
|
184
|
+
HttpRouter.HttpRouter.Provided
|
|
185
|
+
>
|
|
186
|
+
>
|
|
187
|
+
>
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export type RouteMatcher<
|
|
191
|
+
CTXMap extends Record<string, any>,
|
|
192
|
+
Rsc extends Record<string, any>,
|
|
193
|
+
Context
|
|
194
|
+
> = {
|
|
195
|
+
// use Rsc as Key over using Keys, so that the Go To on X.Action remain in tact in Controllers files
|
|
196
|
+
/**
|
|
197
|
+
* Requires the Type shape
|
|
198
|
+
*/
|
|
199
|
+
[Key in keyof Filter<Rsc>]: Match<Rsc, CTXMap, "d", Key, Context> & {
|
|
200
|
+
success: Rsc[Key]["success"]
|
|
201
|
+
successRaw: S.SchemaClass<S.Schema.Encoded<Rsc[Key]["success"]>>
|
|
202
|
+
failure: Rsc[Key]["failure"]
|
|
203
|
+
/**
|
|
204
|
+
* Requires the Encoded shape (e.g directly undecoded from DB, so that we don't do multiple Decode/Encode)
|
|
205
|
+
*/
|
|
206
|
+
raw: Match<Rsc, CTXMap, "raw", Key, Context>
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
// export interface RouteMatcher<
|
|
210
|
+
// Filtered extends Record<string, any>,
|
|
211
|
+
// CTXMap extends Record<string, any>,
|
|
212
|
+
// Rsc extends Filtered
|
|
213
|
+
// > extends RouteMatcherInt<Filtered, CTXMap, Rsc> {}
|
|
214
|
+
|
|
215
|
+
export const makeMiddleware = <
|
|
216
|
+
Context,
|
|
217
|
+
CTXMap extends Record<string, RPCContextMap.Any>,
|
|
218
|
+
RMW,
|
|
219
|
+
Layers extends Array<Layer.Layer.Any>
|
|
220
|
+
>(content: Middleware<Context, CTXMap, RMW, Layers>): Middleware<Context, CTXMap, RMW, Layers> => content
|
|
221
|
+
|
|
222
|
+
export const makeRouter = <
|
|
223
|
+
Context,
|
|
224
|
+
CTXMap extends Record<string, RPCContextMap.Any>,
|
|
225
|
+
RMW,
|
|
226
|
+
Layers extends Array<Layer.Layer.Any>
|
|
227
|
+
>(
|
|
228
|
+
middleware: Middleware<Context, CTXMap, RMW, Layers>,
|
|
229
|
+
devMode: boolean
|
|
230
|
+
) => {
|
|
231
|
+
function matchFor<
|
|
232
|
+
const ModuleName extends string,
|
|
233
|
+
const Rsc extends Record<string, any>
|
|
234
|
+
>(
|
|
235
|
+
rsc: Rsc & { meta: { moduleName: ModuleName } }
|
|
236
|
+
) {
|
|
237
|
+
const meta = rsc.meta
|
|
238
|
+
type Filtered = Filter<Rsc>
|
|
239
|
+
const filtered = typedKeysOf(rsc).reduce((acc, cur) => {
|
|
240
|
+
if (Predicate.isObject(rsc[cur]) && rsc[cur]["success"]) {
|
|
241
|
+
acc[cur as keyof Filtered] = rsc[cur]
|
|
242
|
+
}
|
|
243
|
+
return acc
|
|
244
|
+
}, {} as Filtered)
|
|
245
|
+
|
|
246
|
+
const items = typedKeysOf(filtered).reduce(
|
|
247
|
+
(prev, cur) => {
|
|
248
|
+
;(prev as any)[cur] = Object.assign((fnOrEffect: any) => {
|
|
249
|
+
const stack = new Error().stack?.split("\n").slice(2).join("\n")
|
|
250
|
+
return Effect.isEffect(fnOrEffect)
|
|
251
|
+
? class {
|
|
252
|
+
static stack = stack
|
|
253
|
+
static _tag = "d"
|
|
254
|
+
static handler = () => fnOrEffect
|
|
255
|
+
}
|
|
256
|
+
: class {
|
|
257
|
+
static stack = stack
|
|
258
|
+
static _tag = "d"
|
|
259
|
+
static handler = fnOrEffect
|
|
260
|
+
}
|
|
261
|
+
}, {
|
|
262
|
+
success: rsc[cur].success,
|
|
263
|
+
successRaw: S.encodedSchema(rsc[cur].success),
|
|
264
|
+
failure: rsc[cur].failure,
|
|
265
|
+
raw: // "Raw" variations are for when you don't want to decode just to encode it again on the response
|
|
266
|
+
// e.g for direct projection from DB
|
|
267
|
+
// but more importantly, to skip Effectful decoders, like to resolve relationships from the database or remote client.
|
|
268
|
+
(fnOrEffect: any) => {
|
|
269
|
+
const stack = new Error().stack?.split("\n").slice(2).join("\n")
|
|
270
|
+
return Effect.isEffect(fnOrEffect)
|
|
271
|
+
? class {
|
|
272
|
+
static stack = stack
|
|
273
|
+
static _tag = "raw"
|
|
274
|
+
static handler = () => fnOrEffect
|
|
275
|
+
}
|
|
276
|
+
: class {
|
|
277
|
+
static stack = stack
|
|
278
|
+
static _tag = "raw"
|
|
279
|
+
static handler = (req: any, ctx: any) => fnOrEffect(req, { ...ctx, Response: rsc[cur].success })
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
})
|
|
283
|
+
return prev
|
|
284
|
+
},
|
|
285
|
+
{} as RouteMatcher<CTXMap, Rsc, Context>
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
type Keys = keyof Filtered
|
|
289
|
+
|
|
290
|
+
const effect = <
|
|
291
|
+
E,
|
|
292
|
+
R,
|
|
293
|
+
THandlers extends {
|
|
294
|
+
// import to keep them separate via | for type checking!!
|
|
295
|
+
[K in Keys]: AHandler<Rsc[K]>
|
|
296
|
+
},
|
|
297
|
+
TLayers extends NonEmptyArray<Layer.Layer.Any>
|
|
298
|
+
>(
|
|
299
|
+
layers: TLayers,
|
|
300
|
+
make: (requests: typeof items) => Effect<THandlers, E, R>
|
|
301
|
+
) => {
|
|
302
|
+
type ProvidedLayers =
|
|
303
|
+
| { [k in keyof Layers]: Layer.Layer.Success<Layers[k]> }[number]
|
|
304
|
+
| { [k in keyof TLayers]: Layer.Layer.Success<TLayers[k]> }[number]
|
|
305
|
+
type Router = RouterShape<Rsc>
|
|
306
|
+
const r: HttpRouter.HttpRouter.TagClass<
|
|
307
|
+
Router,
|
|
308
|
+
`${typeof meta.moduleName}Router`,
|
|
309
|
+
never,
|
|
310
|
+
Exclude<
|
|
311
|
+
| Context
|
|
312
|
+
| RPCRouteR<
|
|
313
|
+
{ [K in keyof Filter<Rsc>]: Rpc.Rpc<Rsc[K], _R<ReturnType<THandlers[K]["handler"]>>> }[keyof Filter<Rsc>]
|
|
314
|
+
>,
|
|
315
|
+
HttpRouter.HttpRouter.Provided
|
|
316
|
+
>
|
|
317
|
+
> = (class Router extends HttpRouter.Tag(`${meta.moduleName}Router`)<Router>() {}) as any
|
|
318
|
+
|
|
319
|
+
const layer = r.use((router) =>
|
|
320
|
+
Effect.gen(function*() {
|
|
321
|
+
const controllers = yield* make(items)
|
|
322
|
+
const rpc = yield* makeRpc(middleware)
|
|
323
|
+
|
|
324
|
+
// return make.pipe(Effect.map((c) => controllers(c, layers)))
|
|
325
|
+
const mapped = typedKeysOf(filtered).reduce((acc, cur) => {
|
|
326
|
+
const handler = controllers[cur as keyof typeof controllers]
|
|
327
|
+
const req = rsc[cur]
|
|
328
|
+
|
|
329
|
+
acc[cur] = rpc.effect(
|
|
330
|
+
handler._tag === "raw"
|
|
331
|
+
? class extends (req as any) {
|
|
332
|
+
static success = S.encodedSchema(req.success)
|
|
333
|
+
get [Schema.symbolSerializable]() {
|
|
334
|
+
return this.constructor
|
|
335
|
+
}
|
|
336
|
+
get [Schema.symbolWithResult]() {
|
|
337
|
+
return {
|
|
338
|
+
failure: req.failure,
|
|
339
|
+
success: S.encodedSchema(req.success)
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
} as any
|
|
343
|
+
: req,
|
|
344
|
+
(req) =>
|
|
345
|
+
Effect
|
|
346
|
+
.annotateCurrentSpan(
|
|
347
|
+
"requestInput",
|
|
348
|
+
Object.entries(req).reduce((prev, [key, value]: [string, unknown]) => {
|
|
349
|
+
prev[key] = key === "password"
|
|
350
|
+
? "<redacted>"
|
|
351
|
+
: typeof value === "string" || typeof value === "number" || typeof value === "boolean"
|
|
352
|
+
? typeof value === "string" && value.length > 256
|
|
353
|
+
? (value.substring(0, 253) + "...")
|
|
354
|
+
: value
|
|
355
|
+
: Array.isArray(value)
|
|
356
|
+
? `Array[${value.length}]`
|
|
357
|
+
: value === null || value === undefined
|
|
358
|
+
? `${value}`
|
|
359
|
+
: typeof value === "object" && value
|
|
360
|
+
? `Object[${Object.keys(value).length}]`
|
|
361
|
+
: typeof value
|
|
362
|
+
return prev
|
|
363
|
+
}, {} as Record<string, string | number | boolean>)
|
|
364
|
+
)
|
|
365
|
+
.pipe(
|
|
366
|
+
// can't use andThen due to some being a function and effect
|
|
367
|
+
Effect.zipRight(handler.handler(req as any) as any),
|
|
368
|
+
Effect.tapErrorCause((cause) => Cause.isFailure(cause) ? logRequestError(cause) : Effect.void),
|
|
369
|
+
Effect.tapDefect((cause) =>
|
|
370
|
+
Effect
|
|
371
|
+
.all([
|
|
372
|
+
reportRequestError(cause, {
|
|
373
|
+
action: `${meta.moduleName}.${req._tag}`
|
|
374
|
+
}),
|
|
375
|
+
Rpc.currentHeaders.pipe(Effect.andThen((headers) => {
|
|
376
|
+
return InfraLogger
|
|
377
|
+
.logError("Finished request", cause)
|
|
378
|
+
.pipe(Effect.annotateLogs({
|
|
379
|
+
action: `${meta.moduleName}.${req._tag}`,
|
|
380
|
+
req: pretty(req),
|
|
381
|
+
headers: pretty(headers)
|
|
382
|
+
// resHeaders: pretty(
|
|
383
|
+
// Object
|
|
384
|
+
// .entries(headers)
|
|
385
|
+
// .reduce((prev, [key, value]) => {
|
|
386
|
+
// prev[key] = value && typeof value === "string" ? snipString(value) : value
|
|
387
|
+
// return prev
|
|
388
|
+
// }, {} as Record<string, any>)
|
|
389
|
+
// )
|
|
390
|
+
}))
|
|
391
|
+
}))
|
|
392
|
+
])
|
|
393
|
+
),
|
|
394
|
+
devMode ? (_) => _ : Effect.catchAllDefect(() => Effect.die("Internal Server Error")),
|
|
395
|
+
Effect.withSpan("Request." + meta.moduleName + "." + req._tag, {
|
|
396
|
+
captureStackTrace: () => handler.stack
|
|
397
|
+
})
|
|
398
|
+
),
|
|
399
|
+
meta.moduleName
|
|
400
|
+
) // TODO
|
|
401
|
+
return acc
|
|
402
|
+
}, {} as any) as {
|
|
403
|
+
[K in Keys]: Rpc.Rpc<
|
|
404
|
+
Rsc[K],
|
|
405
|
+
Context | _R<ReturnType<THandlers[K]["handler"]>>
|
|
406
|
+
>
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
const rpcRouter = RpcRouter.make(...Object.values(mapped) as any) as RpcRouter.RpcRouter<
|
|
410
|
+
RPCRouteReq<typeof mapped[keyof typeof mapped]>,
|
|
411
|
+
RPCRouteR<typeof mapped[keyof typeof mapped]>
|
|
412
|
+
>
|
|
413
|
+
const httpApp = toHttpApp(rpcRouter, {
|
|
414
|
+
spanPrefix: rsc
|
|
415
|
+
.meta
|
|
416
|
+
.moduleName + "."
|
|
417
|
+
})
|
|
418
|
+
yield* router
|
|
419
|
+
.all(
|
|
420
|
+
"/",
|
|
421
|
+
httpApp as any,
|
|
422
|
+
// TODO: not queries.
|
|
423
|
+
{ uninterruptible: true }
|
|
424
|
+
)
|
|
425
|
+
})
|
|
426
|
+
)
|
|
427
|
+
|
|
428
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
429
|
+
const routes = layer.pipe(
|
|
430
|
+
Layer.provideMerge(r.Live),
|
|
431
|
+
layers ? Layer.provide(layers) as any : (_) => _,
|
|
432
|
+
// TODO: only provide to the middleware?
|
|
433
|
+
middleware.dependencies ? Layer.provide(middleware.dependencies as any) : (_) => _
|
|
434
|
+
) as Layer.Layer<
|
|
435
|
+
Router,
|
|
436
|
+
{ [k in keyof TLayers]: Layer.Layer.Error<TLayers[k]> }[number] | E,
|
|
437
|
+
| { [k in keyof TLayers]: Layer.Layer.Context<TLayers[k]> }[number]
|
|
438
|
+
| Exclude<
|
|
439
|
+
RMW | R,
|
|
440
|
+
ProvidedLayers
|
|
441
|
+
>
|
|
442
|
+
>
|
|
443
|
+
|
|
444
|
+
// Effect.Effect<HttpRouter.HttpRouter<unknown, HttpRouter.HttpRouter.DefaultServices>, never, UserRouter>
|
|
445
|
+
|
|
446
|
+
return {
|
|
447
|
+
moduleName: meta.moduleName,
|
|
448
|
+
Router: r,
|
|
449
|
+
routes
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
return effect
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
type HR<T> = T extends HttpRouter.HttpRouter<any, infer R> ? R : never
|
|
457
|
+
type HE<T> = T extends HttpRouter.HttpRouter<infer E, any> ? E : never
|
|
458
|
+
|
|
459
|
+
type RequestHandlersTest = {
|
|
460
|
+
[key: string]: {
|
|
461
|
+
Router: { router: Effect<HttpRouter.HttpRouter<any, any>, any, any> }
|
|
462
|
+
routes: Layer.Layer<any, any, any>
|
|
463
|
+
moduleName: string
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
function matchAll<T extends RequestHandlersTest, A, E, R>(
|
|
467
|
+
handlers: T,
|
|
468
|
+
requestLayer: Layer.Layer<A, E, R>
|
|
469
|
+
) {
|
|
470
|
+
const routers = typedValuesOf(handlers)
|
|
471
|
+
|
|
472
|
+
const rootRouter = class extends HttpRouter.Tag("RootRouter")<
|
|
473
|
+
"RootRouter",
|
|
474
|
+
HR<Effect.Success<typeof handlers[keyof typeof handlers]["Router"]["router"]>>,
|
|
475
|
+
HE<Effect.Success<typeof handlers[keyof typeof handlers]["Router"]["router"]>>
|
|
476
|
+
>() {}
|
|
477
|
+
|
|
478
|
+
const r = rootRouter
|
|
479
|
+
.use((router) =>
|
|
480
|
+
Effect.gen(function*() {
|
|
481
|
+
for (const route of routers) {
|
|
482
|
+
yield* router.mount(
|
|
483
|
+
("/rpc/" + route.moduleName) as any,
|
|
484
|
+
yield* route
|
|
485
|
+
.Router
|
|
486
|
+
.router
|
|
487
|
+
.pipe(Effect.map(HttpRouter.use(flow(Effect.provide(requestLayer))))) as any
|
|
488
|
+
)
|
|
489
|
+
}
|
|
490
|
+
})
|
|
491
|
+
)
|
|
492
|
+
.pipe(Layer.provide(routers.map((r) => r.routes).flat() as unknown as NonEmptyArray<Layer.Layer.Any>))
|
|
493
|
+
|
|
494
|
+
return {
|
|
495
|
+
layer: r as Layer.Layer<
|
|
496
|
+
never,
|
|
497
|
+
Layer.Layer.Error<typeof handlers[keyof typeof handlers]["routes"]>,
|
|
498
|
+
Layer.Layer.Context<typeof handlers[keyof typeof handlers]["routes"]>
|
|
499
|
+
>,
|
|
500
|
+
Router: rootRouter as any as HttpRouter.HttpRouter.TagClass<
|
|
501
|
+
"RootRouter",
|
|
502
|
+
"RootRouter",
|
|
503
|
+
HE<Effect.Success<typeof handlers[keyof typeof handlers]["Router"]["router"]>>,
|
|
504
|
+
R | Exclude<HR<Effect.Success<typeof handlers[keyof typeof handlers]["Router"]["router"]>>, A>
|
|
505
|
+
>
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
return { matchAll, matchFor }
|
|
510
|
+
}
|
package/types/modules.d.ts
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
declare module 'object-hash';
|