@effect-app/infra 0.71.1 → 0.72.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/.cache/effect/095519d034161945a8d2616a506d3e7f35a9b3d868814f44c747429c60fc4e7f.hash +1 -1
- package/.cache/effect/134218688132dfbdea493cbe1f26e73449f2759121df35ddd5448346b59c9a8d.content +24 -6
- package/.cache/effect/134218688132dfbdea493cbe1f26e73449f2759121df35ddd5448346b59c9a8d.hash +1 -1
- package/.cache/effect/14eb9da4ca6d22162888c7fdb7f39ab772d2a2dc6625db6031ecdb32ac89158f.content +75 -40
- package/.cache/effect/14eb9da4ca6d22162888c7fdb7f39ab772d2a2dc6625db6031ecdb32ac89158f.hash +1 -1
- package/.cache/effect/49c1bd9ec26e6df78b994d8df0bfe21b119803fa4aa46349bf4679fd0f1e7cda.hash +1 -1
- package/.cache/effect/58d4ccde8bd2db7829706db5bebd01b99900ee83f0f6a8413b53d17cbd69f510.hash +1 -1
- package/.cache/effect/72a5a16a6b62b63cd71719c833091128207d7e6c823cb32293549b3dd58c451b.hash +1 -1
- package/.cache/effect/f38adf43700dab905456a534a0690eaf882cff2cd576c731f23d6d14a3c3d659.hash +1 -1
- package/CHANGELOG.md +14 -0
- package/_cjs/api/express/makeJsonSchema.cjs +81 -54
- package/_cjs/api/express/makeJsonSchema.cjs.map +1 -1
- package/_cjs/api/express/makeJsonSchema.test.cjs +28 -4
- package/_cjs/api/express/makeJsonSchema.test.cjs.map +1 -1
- package/_src/api/express/makeJsonSchema.test.ts +34 -8
- package/_src/api/express/makeJsonSchema.ts +101 -45
- package/dist/api/express/makeJsonSchema.d.ts +2 -3
- package/dist/api/express/makeJsonSchema.d.ts.map +1 -1
- package/dist/api/express/makeJsonSchema.js +73 -42
- package/dist/api/express/makeOpenApiSpecs.d.ts +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
3fdb756675565f3f5e5cdb6e2680f07a60ced261a3790df2cdfc23a21d160956
|
package/.cache/effect/134218688132dfbdea493cbe1f26e73449f2759121df35ddd5448346b59c9a8d.content
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import * as tsplus_module_1 from "@effect/io/Effect";
|
|
2
|
+
import * as tsplus_module_2 from "@effect/data/Either";
|
|
3
|
+
import * as tsplus_module_3 from "@effect/io/Logger";
|
|
2
4
|
import { InvalidStateError } from "../../errors.js";
|
|
3
|
-
import {
|
|
5
|
+
import { checkPaths } from "./makeJsonSchema.js";
|
|
4
6
|
const path = { path: "/securities/:id/search/:id2", method: "get" };
|
|
5
7
|
const equalPaths = [
|
|
6
8
|
"/securities/:idt/search/:id2",
|
|
@@ -9,8 +11,9 @@ const equalPaths = [
|
|
|
9
11
|
]
|
|
10
12
|
.map((path) => ({ path, method: "get" }));
|
|
11
13
|
const differentPaths = [
|
|
12
|
-
"/securities/:id/search/",
|
|
13
14
|
"/securities/search/:id2",
|
|
15
|
+
"/securities/:id/search/",
|
|
16
|
+
"/securities/:id/search/:id2",
|
|
14
17
|
"/securities/:id/:id2/search/:id3"
|
|
15
18
|
]
|
|
16
19
|
.map((path) => ({ path, method: "get" }))
|
|
@@ -18,8 +21,23 @@ const differentPaths = [
|
|
|
18
21
|
"/securities/:idt/search/:id2"
|
|
19
22
|
]
|
|
20
23
|
.map((path) => ({ path, method: "post" })));
|
|
21
|
-
test("works", () => {
|
|
22
|
-
expect(
|
|
23
|
-
|
|
24
|
+
test("works", async () => {
|
|
25
|
+
expect(await tsplus_module_1.runPromise((checkPaths(differentPaths)))).toStrictEqual(differentPaths);
|
|
26
|
+
for (const p of equalPaths) {
|
|
27
|
+
expect(await tsplus_module_1.runPromiseEither(checkPaths([path, p]))).toStrictEqual(tsplus_module_2.left(new InvalidStateError(`Duplicate method ${p.method} for path ${p.path}`)));
|
|
28
|
+
}
|
|
29
|
+
expect(await tsplus_module_1.runPromiseEither(checkPaths(["a/:p1/c/:p2", "a/b"].map((path) => ({ path, method: "get" })))))
|
|
30
|
+
.toStrictEqual(tsplus_module_2.left(new InvalidStateError(`Path /a/b/ is shadowed by /a/:p1/`)));
|
|
31
|
+
expect(await tsplus_module_1.runPromiseEither(checkPaths(["a/:p1/c/:p2", "a/:p111/c/d"].map((path) => ({ path, method: "get" })))))
|
|
32
|
+
.toStrictEqual(tsplus_module_2.left(new InvalidStateError(`Path /a/:p1/c/d/ is shadowed by /a/:p1/c/:p2/`)));
|
|
33
|
+
});
|
|
34
|
+
test("log shadowing", async () => {
|
|
35
|
+
const arr = [];
|
|
36
|
+
const paths = ["a/b", "a/:p"].map((path) => ({ path, method: "get" }));
|
|
37
|
+
const CustomLogger = tsplus_module_3.make((_, __, message) => {
|
|
38
|
+
arr.push(message);
|
|
39
|
+
});
|
|
40
|
+
await tsplus_module_1.runPromise(tsplus_module_1.provideLayer(checkPaths(paths), tsplus_module_3.replace(tsplus_module_3.defaultLogger, CustomLogger)));
|
|
41
|
+
expect(arr).toStrictEqual([`Path /a/:p/ is partially shadowed by /a/b/`]);
|
|
24
42
|
});
|
|
25
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
43
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFrZUpzb25TY2hlbWEudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL19zcmMvYXBpL2V4cHJlc3MvbWFrZUpzb25TY2hlbWEudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQTtBQUNuRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0scUJBQXFCLENBQUE7QUFFaEQsTUFBTSxJQUFJLEdBQUcsRUFBRSxJQUFJLEVBQUUsNkJBQTZCLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxDQUFBO0FBRW5FLE1BQU0sVUFBVSxHQUFHO0lBQ2pCLDhCQUE4QjtJQUM5Qiw4QkFBOEI7SUFDOUIsK0JBQStCO0NBQ2hDO0tBQ0UsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUE7QUFFM0MsTUFBTSxjQUFjLEdBR2Q7SUFDSix5QkFBeUI7SUFDekIseUJBQXlCO0lBQ3pCLDZCQUE2QjtJQUM3QixrQ0FBa0M7Q0FDbkM7S0FDRSxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7S0FDeEMsTUFBTSxDQUFDO0lBQ04sOEJBQThCO0NBQy9CO0tBQ0UsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQTtBQUUvQyxJQUFJLENBQUMsT0FBTyxFQUFFLEtBQUssSUFBSSxFQUFFO0lBQ3ZCLE1BQU0sQ0FBQyxpQ0FBTSxDQUFDLFVBQVUsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFXLENBQUMsQ0FBQyxhQUFhLENBQUMsY0FBYyxDQUFDLENBQUE7SUFFbkYsS0FBSyxNQUFNLENBQUMsSUFBSSxVQUFVLEVBQUU7UUFDMUIsTUFBTSxDQUFDLHVDQUFNLFVBQVUsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFpQixDQUFDLENBQUMsYUFBYSxDQUNoRSxxQkFBWSxJQUFJLGlCQUFpQixDQUFDLG9CQUFvQixDQUFDLENBQUMsTUFBTSxhQUFhLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQ3RGLENBQUE7S0FDRjtJQUVELE1BQU0sQ0FBQyx1Q0FBTSxVQUFVLENBQUMsQ0FBQyxhQUFhLEVBQUUsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBaUIsQ0FBQztTQUN2RyxhQUFhLENBQ1oscUJBQVksSUFBSSxpQkFBaUIsQ0FBQyxtQ0FBbUMsQ0FBQyxDQUFDLENBQ3hFLENBQUE7SUFFSCxNQUFNLENBQUMsdUNBQU0sVUFBVSxDQUFDLENBQUMsYUFBYSxFQUFFLGFBQWEsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQWlCLENBQUM7U0FDL0csYUFBYSxDQUNaLHFCQUFZLElBQUksaUJBQWlCLENBQUMsK0NBQStDLENBQUMsQ0FBQyxDQUNwRixDQUFBO0FBQ0wsQ0FBQyxDQUFDLENBQUE7QUFFRixJQUFJLENBQUMsZUFBZSxFQUFFLEtBQUssSUFBSSxFQUFFO0lBQy9CLE1BQU0sR0FBRyxHQUFhLEVBQUUsQ0FBQTtJQUN4QixNQUFNLEtBQUssR0FBRyxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQTtJQUV0RSxNQUFNLFlBQVksR0FBRyxxQkFBMEIsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLE9BQU8sRUFBRSxFQUFFO1FBQ2hFLEdBQUcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUE7SUFDbkIsQ0FBQyxDQUFDLENBQUE7SUFFRixpQ0FBTSw2QkFBQSxVQUFVLENBQUMsS0FBSyxDQUFDLEVBQ1AsdURBQXFDLFlBQVksQ0FBQyxDQUFDLENBQ3RELENBQUE7SUFFYixNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsYUFBYSxDQUFDLENBQUMsNENBQTRDLENBQUMsQ0FBQyxDQUFBO0FBQzNFLENBQUMsQ0FBQyxDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW52YWxpZFN0YXRlRXJyb3IgfSBmcm9tIFwiLi4vLi4vZXJyb3JzLmpzXCJcbmltcG9ydCB7IGNoZWNrUGF0aHMgfSBmcm9tIFwiLi9tYWtlSnNvblNjaGVtYS5qc1wiXG5cbmNvbnN0IHBhdGggPSB7IHBhdGg6IFwiL3NlY3VyaXRpZXMvOmlkL3NlYXJjaC86aWQyXCIsIG1ldGhvZDogXCJnZXRcIiB9XG5cbmNvbnN0IGVxdWFsUGF0aHMgPSBbXG4gIFwiL3NlY3VyaXRpZXMvOmlkdC9zZWFyY2gvOmlkMlwiLFxuICBcIi9zZWN1cml0aWVzLzppZC9zZWFyY2gvOmlkMnRcIixcbiAgXCIvc2VjdXJpdGllcy86aWR0L3NlYXJjaC86aWQydFwiXG5dXG4gIC5tYXAoKHBhdGgpID0+ICh7IHBhdGgsIG1ldGhvZDogXCJnZXRcIiB9KSlcblxuY29uc3QgZGlmZmVyZW50UGF0aHM6IHtcbiAgcGF0aDogc3RyaW5nXG4gIG1ldGhvZDogc3RyaW5nXG59W10gPSBbXG4gIFwiL3NlY3VyaXRpZXMvc2VhcmNoLzppZDJcIixcbiAgXCIvc2VjdXJpdGllcy86aWQvc2VhcmNoL1wiLFxuICBcIi9zZWN1cml0aWVzLzppZC9zZWFyY2gvOmlkMlwiLFxuICBcIi9zZWN1cml0aWVzLzppZC86aWQyL3NlYXJjaC86aWQzXCJcbl1cbiAgLm1hcCgocGF0aCkgPT4gKHsgcGF0aCwgbWV0aG9kOiBcImdldFwiIH0pKVxuICAuY29uY2F0KFtcbiAgICBcIi9zZWN1cml0aWVzLzppZHQvc2VhcmNoLzppZDJcIlxuICBdXG4gICAgLm1hcCgocGF0aCkgPT4gKHsgcGF0aCwgbWV0aG9kOiBcInBvc3RcIiB9KSkpXG5cbnRlc3QoXCJ3b3Jrc1wiLCBhc3luYyAoKSA9PiB7XG4gIGV4cGVjdChhd2FpdCAoY2hlY2tQYXRocyhkaWZmZXJlbnRQYXRocykpLnJ1blByb21pc2UpLnRvU3RyaWN0RXF1YWwoZGlmZmVyZW50UGF0aHMpXG5cbiAgZm9yIChjb25zdCBwIG9mIGVxdWFsUGF0aHMpIHtcbiAgICBleHBlY3QoYXdhaXQgY2hlY2tQYXRocyhbcGF0aCwgcF0pLnJ1blByb21pc2VFaXRoZXIpLnRvU3RyaWN0RXF1YWwoXG4gICAgICBFaXRoZXIubGVmdChuZXcgSW52YWxpZFN0YXRlRXJyb3IoYER1cGxpY2F0ZSBtZXRob2QgJHtwLm1ldGhvZH0gZm9yIHBhdGggJHtwLnBhdGh9YCkpXG4gICAgKVxuICB9XG5cbiAgZXhwZWN0KGF3YWl0IGNoZWNrUGF0aHMoW1wiYS86cDEvYy86cDJcIiwgXCJhL2JcIl0ubWFwKChwYXRoKSA9PiAoeyBwYXRoLCBtZXRob2Q6IFwiZ2V0XCIgfSkpKS5ydW5Qcm9taXNlRWl0aGVyKVxuICAgIC50b1N0cmljdEVxdWFsKFxuICAgICAgRWl0aGVyLmxlZnQobmV3IEludmFsaWRTdGF0ZUVycm9yKGBQYXRoIC9hL2IvIGlzIHNoYWRvd2VkIGJ5IC9hLzpwMS9gKSlcbiAgICApXG5cbiAgZXhwZWN0KGF3YWl0IGNoZWNrUGF0aHMoW1wiYS86cDEvYy86cDJcIiwgXCJhLzpwMTExL2MvZFwiXS5tYXAoKHBhdGgpID0+ICh7IHBhdGgsIG1ldGhvZDogXCJnZXRcIiB9KSkpLnJ1blByb21pc2VFaXRoZXIpXG4gICAgLnRvU3RyaWN0RXF1YWwoXG4gICAgICBFaXRoZXIubGVmdChuZXcgSW52YWxpZFN0YXRlRXJyb3IoYFBhdGggL2EvOnAxL2MvZC8gaXMgc2hhZG93ZWQgYnkgL2EvOnAxL2MvOnAyL2ApKVxuICAgIClcbn0pXG5cbnRlc3QoXCJsb2cgc2hhZG93aW5nXCIsIGFzeW5jICgpID0+IHtcbiAgY29uc3QgYXJyOiBzdHJpbmdbXSA9IFtdXG4gIGNvbnN0IHBhdGhzID0gW1wiYS9iXCIsIFwiYS86cFwiXS5tYXAoKHBhdGgpID0+ICh7IHBhdGgsIG1ldGhvZDogXCJnZXRcIiB9KSlcblxuICBjb25zdCBDdXN0b21Mb2dnZXIgPSBMb2dnZXIubWFrZTxzdHJpbmcsIHZvaWQ+KChfLCBfXywgbWVzc2FnZSkgPT4ge1xuICAgIGFyci5wdXNoKG1lc3NhZ2UpXG4gIH0pXG5cbiAgYXdhaXQgY2hlY2tQYXRocyhwYXRocylcbiAgICAucHJvdmlkZUxheWVyKExvZ2dlci5yZXBsYWNlKExvZ2dlci5kZWZhdWx0TG9nZ2VyLCBDdXN0b21Mb2dnZXIpKVxuICAgIC5ydW5Qcm9taXNlXG5cbiAgZXhwZWN0KGFycikudG9TdHJpY3RFcXVhbChbYFBhdGggL2EvOnAvIGlzIHBhcnRpYWxseSBzaGFkb3dlZCBieSAvYS9iL2BdKVxufSlcbiJdfQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
227326c96d8f8db11aa5dd8162cb906e55a27b00a9069640a822be51cb025b58
|
package/.cache/effect/14eb9da4ca6d22162888c7fdb7f39ab772d2a2dc6625db6031ecdb32ac89158f.content
CHANGED
|
@@ -5,57 +5,92 @@ import * as tsplus_module_3 from "@effect-app/core/_ext/Iterable";
|
|
|
5
5
|
import { InvalidStateError } from "../../errors.js";
|
|
6
6
|
import * as RS from "./schema/routing.js";
|
|
7
7
|
const rx = /:(\w+)/g;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
i++;
|
|
28
|
-
break;
|
|
8
|
+
class PathsTree {
|
|
9
|
+
methods;
|
|
10
|
+
params;
|
|
11
|
+
subpaths;
|
|
12
|
+
path;
|
|
13
|
+
constructor(path) {
|
|
14
|
+
this.methods = [];
|
|
15
|
+
this.params = {};
|
|
16
|
+
this.subpaths = {};
|
|
17
|
+
this.path = path;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function checkShadowing(pathNavigator, match) {
|
|
21
|
+
return tsplus_module_1.gen(function* ($) {
|
|
22
|
+
switch (match._tag) {
|
|
23
|
+
case "resource": {
|
|
24
|
+
// check shadowing: if 'a/:param' comes before 'a/b', then 'a/b' is shadowed
|
|
25
|
+
if (pathNavigator.params[1]) {
|
|
26
|
+
return yield* $(tsplus_module_1.fail(new InvalidStateError(`Path ${pathNavigator.path}${match.value}/ is shadowed by ${pathNavigator.params[1].path}`)));
|
|
29
27
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
case "param": {
|
|
31
|
+
// check shadowing: if 'a/b' comes before 'a/:param', then 'a/"param' is partially shadowed
|
|
32
|
+
const subpaths = Object.getOwnPropertyNames(pathNavigator.subpaths);
|
|
33
|
+
if (subpaths.length > 0) {
|
|
34
|
+
yield* $(tsplus_module_1.all(subpaths.map((s) => tsplus_module_1.logInfo(`Path ${pathNavigator.path}:${match.value}/ is partially shadowed by ${pathNavigator.subpaths[s].path}`))));
|
|
35
|
+
}
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
export function checkPaths(paths) {
|
|
42
|
+
return tsplus_module_1.gen(function* ($) {
|
|
43
|
+
const pathMethods = new PathsTree("/");
|
|
44
|
+
const regex = /(?:^|\/)([^/:\n]+)|:(\w+)/g;
|
|
45
|
+
for (const path of paths) {
|
|
46
|
+
const matches = [...path.path.matchAll(regex)]
|
|
47
|
+
.map((match) => match[1]
|
|
48
|
+
? { _tag: "resource", value: match[1] }
|
|
49
|
+
: { _tag: "param", value: match[2] });
|
|
50
|
+
let pathNavigator = pathMethods;
|
|
51
|
+
for (let i = 0; i < matches.length;) {
|
|
52
|
+
const match = matches[i];
|
|
53
|
+
yield* $(checkShadowing(pathNavigator, match));
|
|
54
|
+
switch (match._tag) {
|
|
55
|
+
case "resource": {
|
|
56
|
+
if (!(match.value in pathNavigator.subpaths)) {
|
|
57
|
+
pathNavigator.subpaths[match.value] = new PathsTree(`${pathNavigator.path}${match.value}/`);
|
|
58
|
+
}
|
|
59
|
+
pathNavigator = pathNavigator.subpaths[match.value];
|
|
34
60
|
i++;
|
|
61
|
+
break;
|
|
35
62
|
}
|
|
36
|
-
|
|
37
|
-
;
|
|
38
|
-
|
|
63
|
+
case "param": {
|
|
64
|
+
const paramsNames = [match.value];
|
|
65
|
+
let numberOfParams = 1;
|
|
66
|
+
while (i < matches.length && matches[i + 1]?._tag === "param") {
|
|
67
|
+
numberOfParams++;
|
|
68
|
+
i++;
|
|
69
|
+
paramsNames.push(match.value);
|
|
70
|
+
}
|
|
71
|
+
if (!(numberOfParams in pathNavigator.params)) {
|
|
72
|
+
pathNavigator.params[numberOfParams] = new PathsTree(`${pathNavigator.path}:${paramsNames.join("/:")}/`);
|
|
73
|
+
}
|
|
74
|
+
pathNavigator = pathNavigator.params[numberOfParams];
|
|
75
|
+
i++;
|
|
76
|
+
break;
|
|
39
77
|
}
|
|
40
|
-
pathNavigator = (pathNavigator)[numberOfParams];
|
|
41
|
-
i++;
|
|
42
|
-
break;
|
|
43
78
|
}
|
|
44
79
|
}
|
|
80
|
+
if (pathNavigator.methods.includes(path.method)) {
|
|
81
|
+
// throw duplicate path-method error
|
|
82
|
+
return yield* $(tsplus_module_1.fail(new InvalidStateError(`Duplicate method ${path.method} for path ${path.path}`)));
|
|
83
|
+
}
|
|
84
|
+
pathNavigator.methods.push(path.method);
|
|
45
85
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
return tsplus_module_1.fail(new InvalidStateError(`Duplicate method ${path.method} for path ${path.path}`));
|
|
49
|
-
}
|
|
50
|
-
pathNavigator[methods].push(path.method);
|
|
51
|
-
}
|
|
52
|
-
return tsplus_module_1.succeed(paths);
|
|
86
|
+
return paths;
|
|
87
|
+
});
|
|
53
88
|
}
|
|
54
89
|
/**
|
|
55
90
|
* Work in progress JSONSchema generator.
|
|
56
91
|
*/
|
|
57
92
|
export function makeJsonSchema(r) {
|
|
58
|
-
return tsplus_module_1.map(tsplus_module_1.flatMap(tsplus_module_3.ext_forEach(tsplus_module_2.fromIterable(r), RS.makeFromSchema),
|
|
93
|
+
return tsplus_module_1.map(tsplus_module_1.flatMap(tsplus_module_3.ext_forEach(tsplus_module_2.fromIterable(r), RS.makeFromSchema), checkPaths), (e) => {
|
|
59
94
|
const map = ({ method, path, responses, ...rest }) => ({
|
|
60
95
|
[method]: {
|
|
61
96
|
...rest,
|
|
@@ -84,4 +119,4 @@ class Response {
|
|
|
84
119
|
this.type = type;
|
|
85
120
|
}
|
|
86
121
|
}
|
|
87
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFrZUpzb25TY2hlbWEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9fc3JjL2FwaS9leHByZXNzL21ha2VKc29uU2NoZW1hLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHVEQUF1RDtBQUV2RCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQTtBQUNuRCxPQUFPLEtBQUssRUFBRSxNQUFNLHFCQUFxQixDQUFBO0FBSXpDLE1BQU0sRUFBRSxHQUFHLFNBQVMsQ0FBQTtBQUlwQixNQUFNLFVBQVUsbUJBQW1CLENBQ2pDLEtBQW1CO0lBRW5CLE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQTtJQUtqQyxNQUFNLFdBQVcsR0FBZ0IsRUFBRSxDQUFDLE9BQU8sQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFBO0lBQ2xELE1BQU0sS0FBSyxHQUFHLDRCQUE0QixDQUFBO0lBRTFDLEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxFQUFFO1FBQ3hCLE1BQU0sT0FBTyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQzthQUMzQyxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUNiLEtBQUssQ0FBQyxDQUFDLENBQUM7WUFDTixDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQVc7WUFDaEQsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBRSxFQUFXLENBQ2pELENBQUE7UUFFSCxJQUFJLGFBQWEsR0FBMkIsV0FBVyxDQUFBO1FBQ3ZELEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxPQUFPLENBQUMsTUFBTSxHQUFHO1lBQ25DLE1BQU0sS0FBSyxHQUFHLE9BQU8s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R0FBRyxDQUFDLENBQUE7WUFDbEUsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHO2dCQUNYLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQztnQkFDYixHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQVE7YUFDakIsQ0FBQTtZQUNELE9BQU8sSUFBSSxDQUFBO1FBQ2IsQ0FBQyxFQUNELEVBQTZELENBQzlELENBQUE7SUFDSCxDQUFDLENBQUMsQ0FBQTtBQUNOLENBQUM7QUFFRCxNQUFNLFFBQVE7SUFFTTtJQUNBO0lBRmxCLFlBQ2tCLFVBQWtCLEVBQ2xCLElBQVMsQ0FBQyxrQ0FBa0M7O1FBRDVDLGVBQVUsR0FBVixVQUFVLENBQVE7UUFDbEIsU0FBSSxHQUFKLElBQUksQ0FBSztJQUN4QixDQUFDO0NBQ0wiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55ICovXG5cbmltcG9ydCB7IEludmFsaWRTdGF0ZUVycm9yIH0gZnJvbSBcIi4uLy4uL2Vycm9ycy5qc1wiXG5pbXBvcnQgKiBhcyBSUyBmcm9tIFwiLi9zY2hlbWEvcm91dGluZy5qc1wiXG5cbnR5cGUgTWV0aG9kcyA9IFwiR0VUXCIgfCBcIlBVVFwiIHwgXCJQT1NUXCIgfCBcIlBBVENIXCIgfCBcIkRFTEVURVwiXG5cbmNvbnN0IHJ4ID0gLzooXFx3KykvZ1xuXG50eXBlIF9BPEM+ID0gQyBleHRlbmRzIFJlYWRvbmx5QXJyYXk8aW5mZXIgQT4gPyBBIDogbmV2ZXJcblxuZXhwb3J0IGZ1bmN0aW9uIGNoZWNrRHVwbGljYXRlUGF0aHM8VCBleHRlbmRzIHsgcGF0aDogc3RyaW5nOyBtZXRob2Q6IHN0cmluZyB9PihcbiAgcGF0aHM6IHJlYWRvbmx5IFRbXVxuKTogRWZmZWN0PG5ldmVyLCBJbnZhbGlkU3RhdGVFcnJvciwgcmVhZG9ubHkgVFtdPiB7XG4gIGNvbnN0IG1ldGhvZHMgPSBTeW1ib2woXCJtZXRob2RzXCIpXG4gIGludGVyZmFjZSBQYXRoTWV0aG9kcyB7XG4gICAgW2tleTogc3RyaW5nIHwgbnVtYmVyXTogdGhpcyB8IHVuZGVmaW5lZFxuICAgIFttZXRob2RzXTogc3RyaW5nW11cbiAgfVxuICBjb25zdCBwYXRoTWV0aG9kczogUGF0aE1ldGhvZHMgPSB7IFttZXRob2RzXTogW10gfVxuICBjb25zdCByZWdleCA9IC8oPzpefFxcLykoW14vOlxcbl0rKXw6KFxcdyspL2dcblxuICBmb3IgKGNvbnN0IHBhdGggb2YgcGF0aHMpIHtcbiAgICBjb25zdCBtYXRjaGVzID0gWy4uLnBhdGgucGF0aC5tYXRjaEFsbChyZWdleCldXG4gICAgICAubWFwKChtYXRjaCkgPT5cbiAgICAgICAgbWF0Y2hbMV1cbiAgICAgICAgICA/IHsgX3RhZzogXCJyZXNvdXJjZVwiLCB2YWx1ZTogbWF0Y2hbMV0gfSBhcyBjb25zdFxuICAgICAgICAgIDogeyBfdGFnOiBcInBhcmFtXCIsIHZhbHVlOiBtYXRjaFsyXSEgfSBhcyBjb25zdFxuICAgICAgKVxuXG4gICAgbGV0IHBhdGhOYXZpZ2F0b3I6IFBhdGhNZXRob2RzIHwgc3RyaW5nW10gPSBwYXRoTWV0aG9kc1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbWF0Y2hlcy5sZW5ndGg7KSB7XG4gICAgICBjb25zdCBtYXRjaCA9IG1hdGNoZXNbaV0hXG4gICAgICBzd2l0Y2ggKG1hdGNoLl90YWcpIHtcbiAgICAgICAgY2FzZSBcInJlc291cmNlXCI6IHtcbiAgICAgICAgICBpZiAoIShtYXRjaC52YWx1ZSBpbiAocGF0aE5hdmlnYXRvcikpKSB7XG4gICAgICAgICAgICA7KHBhdGhOYXZpZ2F0b3IpW21hdGNoLnZhbHVlXSA9IHsgW21ldGhvZHNdOiBbXSB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHBhdGhOYXZpZ2F0b3IgPSAocGF0aE5hdmlnYXRvcilbbWF0Y2gudmFsdWVdIVxuICAgICAgICAgIGkrK1xuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgICAgY2FzZSBcInBhcmFtXCI6IHtcbiAgICAgICAgICBsZXQgbnVtYmVyT2ZQYXJhbXMgPSAxXG4gICAgICAgICAgd2hpbGUgKGkgPCBtYXRjaGVzLmxlbmd0aCAmJiBtYXRjaGVzW2kgKyAxXT8uX3RhZyA9PT0gXCJwYXJhbVwiKSB7XG4gICAgICAgICAgICBudW1iZXJPZlBhcmFtcysrXG4gICAgICAgICAgICBpKytcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoIShudW1iZXJPZlBhcmFtcyBpbiBwYXRoTmF2aWdhdG9yKSkge1xuICAgICAgICAgICAgOyhwYXRoTmF2aWdhdG9yKVtudW1iZXJPZlBhcmFtc10gPSB7IFttZXRob2RzXTogW10gfVxuICAgICAgICAgIH1cbiAgICAgICAgICBwYXRoTmF2aWdhdG9yID0gKHBhdGhOYXZpZ2F0b3IpW251bWJlck9mUGFyYW1zXSFcbiAgICAgICAgICBpKytcbiAgICAgICAgICBicmVha1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHBhdGhOYXZpZ2F0b3JbbWV0aG9kc10uaW5jbHVkZXMocGF0aC5tZXRob2QpKSB7XG4gICAgICAvLyB0aHJvdyBkdXBsaWNhdGUgcGF0aC1tZXRob2QgZXJyb3JcbiAgICAgIHJldHVybiBFZmZlY3QuZmFpbChuZXcgSW52YWxpZFN0YXRlRXJyb3IoYER1cGxpY2F0ZSBtZXRob2QgJHtwYXRoLm1ldGhvZH0gZm9yIHBhdGggJHtwYXRoLnBhdGh9YCkpXG4gICAgfVxuICAgIHBhdGhOYXZpZ2F0b3JbbWV0aG9kc10ucHVzaChwYXRoLm1ldGhvZClcbiAgfVxuXG4gIHJldHVybiBFZmZlY3Quc3VjY2VlZChwYXRocylcbn1cblxuLyoqXG4gKiBXb3JrIGluIHByb2dyZXNzIEpTT05TY2hlbWEgZ2VuZXJhdG9yLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbWFrZUpzb25TY2hlbWEocjogSXRlcmFibGU8UlMuUm91dGVEZXNjcmlwdG9yQW55Pikge1xuICByZXR1cm4gQ2h1bmtcbiAgICAuZnJvbUl0ZXJhYmxlKHIpXG4gICAgLmZvckVhY2hFZmZlY3QoUlMubWFrZUZyb21TY2hlbWEpXG4gICAgLmZsYXRNYXAoY2hlY2tEdXBsaWNhdGVQYXRocylcbiAgICAubWFwKChlKSA9PiB7XG4gICAgICBjb25zdCBtYXAgPSAoeyBtZXRob2QsIHBhdGgsIHJlc3BvbnNlcywgLi4ucmVzdCB9OiBfQTx0eXBlb2YgZT4pID0+ICh7XG4gICAgICAgIFttZXRob2RdOiB7XG4gICAgICAgICAgLi4ucmVzdCxcbiAgICAgICAgICByZXNwb25zZXM6IChyZXNwb25zZXMgYXMgQXJyYXk8YW55PikucmVkdWNlKFxuICAgICAgICAgICAgKHByZXYsIGN1cikgPT4ge1xuICAgICAgICAgICAgICBwcmV2W2N1ci5zdGF0dXNDb2RlXSA9IGN1ci50eXBlXG4gICAgICAgICAgICAgIHJldHVybiBwcmV2XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge30gYXMgUmVjb3JkPFJlc3BvbnNlW1wic3RhdHVzQ29kZVwiXSwgUmVzcG9uc2VbXCJ0eXBlXCJdPlxuICAgICAgICAgIClcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICAgIHJldHVybiBlLnJlZHVjZShcbiAgICAgICAgKHByZXYsIGUpID0+IHtcbiAgICAgICAgICBjb25zdCBwYXRoID0gZS5wYXRoLnNwbGl0KFwiP1wiKVswXS5yZXBsYWNlKHJ4LCAoX2EsIGIpID0+IGB7JHtifX1gKVxuICAgICAgICAgIHByZXZbcGF0aF0gPSB7XG4gICAgICAgICAgICAuLi5wcmV2W3BhdGhdLFxuICAgICAgICAgICAgLi4ubWFwKGUpIGFzIGFueVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gcHJldlxuICAgICAgICB9LFxuICAgICAgICB7fSBhcyBSZWNvcmQ8c3RyaW5nLCBSZWNvcmQ8TWV0aG9kcywgUmV0dXJuVHlwZTx0eXBlb2YgbWFwPj4+XG4gICAgICApXG4gICAgfSlcbn1cblxuY2xhc3MgUmVzcG9uc2Uge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgcmVhZG9ubHkgc3RhdHVzQ29kZTogbnVtYmVyLFxuICAgIHB1YmxpYyByZWFkb25seSB0eXBlOiBhbnkgLy8gc3RyaW5nIHwgSlNPTlNjaGVtYSB8IFN1YlNjaGVtYVxuICApIHt9XG59XG4iXX0=
|
|
122
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFrZUpzb25TY2hlbWEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9fc3JjL2FwaS9leHByZXNzL21ha2VKc29uU2NoZW1hLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHVEQUF1RDtBQUV2RCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQTtBQUNuRCxPQUFPLEtBQUssRUFBRSxNQUFNLHFCQUFxQixDQUFBO0FBSXpDLE1BQU0sRUFBRSxHQUFHLFNBQVMsQ0FBQTtBQUlwQixNQUFNLFNBQVM7SUFDRyxPQUFPLENBQVU7SUFDakIsTUFBTSxDQUEwQztJQUNoRCxRQUFRLENBQTBDO0lBQ2xELElBQUksQ0FBUTtJQUU1QixZQUFZLElBQVk7UUFDdEIsSUFBSSxDQUFDLE9BQU8sR0FBRyxFQUFFLENBQUE7UUFDakIsSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFFLENBQUE7UUFDaEIsSUFBSSxDQUFDLFFBQVEsR0FBRyxFQUFFLENBQUE7UUFDbEIsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUE7SUFDbEIsQ0FBQztDQUNGO0FBT0QsU0FBUyxjQUFjLENBQ3JCLGFBQXdCLEVBQ3hCLEtBQVk7SUFFWixPQUFPLG9CQUFXLFFBQVEsQ0FBQyxFQUFDLENBQUM7UUFDM0IsUUFBUSxLQUFLLENBQUMsSUFBSSxFQUFFO1lBQ2xCLEtBQUssVUFBVSxDQUFDLENBQUM7Z0JBQ2YsNEVBQTRFO2dCQUM1RSxJQUFJLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUU7b0JBQzNCLE9BQU8sS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLHFCQUNkLElBQUksaUJBQWlCLENBQ25CLFFBQVEsYUFBYSxDQUFDLElBQUksR0FBRyxLQUFLLENBQUMsS0FBSyxvQkFBb0IsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FDM0YsQ0FDRixDQUFDLENBQUE7aUJBQ0g7Z0JBQ0QsTUFBSzthQUNOO1lBQ0QsS0FBSyxPQUFPLENBQUMsQ0FBQztnQkFDWiwyRkFBMkY7Z0JBQzNGLE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUE7Z0JBQ25FLElBQUksUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7b0JBQ3ZCLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxvQkFBVyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FDckMsd0JBQ0UsUUFBUSxhQUFhLENBQUMsSUFBSSxJQUFJLEtBQUssQ0FBQyxLQUFLLDhCQUE4QixhQUFhLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBRSxDQUFDLElBQUksRUFBRSxDQUN6RyxDQUNGLENBQUMsQ0FBQyxDQUFBO2lCQUNKO2dCQUNELE1BQUs7YUFDTjtTQUNGO0lBQ0gsQ0FBQyxDQUFDLENBQUE7QUFDSixDQUFDO0FBRUQsTUFBTSxVQUFVLFVBQVUsQ0FDeEIsS0FBbUI7SUFFbkIsT0FBTyxvQkFBVyxRQUFRLENBQUMsRUFBQyxDQUFDO1FBQzNCLE1BQU0sV0FBVyxHQUFjLElBQUksU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFBO1FBQ2pELE1BQU0sS0FBSyxHQUFHLDRCQUE0QixDQUFBO1FBQzFDLEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxFQUFFO1lBQ3hCLE1BQU0sT0FBTyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztpQkFDM0MsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FDYixLQUFLLENBQUMsQ0FBQyxDQUFDO2dCQUNOLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBVztnQkFDaEQsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBRSxFQUFXLENBQ2pELENBQUE7WUFFSCxJQUFJLGFBQWEsR0FBRyxXQUFXLENBQUE7WUFDL0IsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxNQUFNLEdBQUc7Z0JBQ25DLE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUUsQ0FBQTtnQkFFekIsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxhQUFhLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQTtnQkFFOUMsUUFBUSxLQUFLLENBQUMsSUFBSSxFQUFFO29CQUNsQixLQUFLLFVBQVUsQ0FBQyxDQUFDO3dCQUNmLElBQUksQ0FBQyxDQUFDLEtBQUssQ0FBQyxLQUFLLElBQUksYUFBYSxDQUFDLFFBQVEsQ0FBQyxFQUFFOzRCQUM1QyxhQUFhLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxJQUFJLFNBQVMsQ0FBQyxHQUFHLGFBQWEsQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUE7eUJBQzVGO3dCQUVELGFBQWEsR0FBRyxhQUFhLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUUsQ0FBQTt3QkFDcEQsQ0FBQyxFQUFFLENBQUE7d0JBQ0gsTUFBSztxQkFDTjtvQkFDRCxLQUFLLE9BQU8sQ0FBQyxDQUFDO3dCQUNaLE1BQU0sV0FBVyxHQUFHLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFBO3dCQUNqQyxJQUFJLGNBQWMsR0FBRyxDQUFDLENBQUE7d0JBQ3RCLE9BQU8sQ0FBQyxHQUFHLE9BQU8sQ0FBQyxNQUFNLElBQUksT0FBTyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLEtBQUssT0FBTyxFQUFFOzRCQUM3RCxjQUFjLEVBQUUsQ0FBQTs0QkFDaEIsQ0FBQyxFQUFFLENBQUE7NEJBQ0gsV0FBVyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUE7eUJBQzlCO3dCQUVELElBQUksQ0FBQyxDQUFDLGNBQWMsSUFBSSxhQUFhLENBQUMsTUFBTSxDQUFDLEVBQUU7NEJBQzdDLGFBQWEsQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDLEdBQUcsSUFBSSxTQUFTLENBQ2xELEdBQUcsYUFBYSxDQUFDLElBQUksSUFBSSxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQ25ELENBQUE7eUJBQ0Y7d0JBQ0QsYUFBYSxHQUFHLGFBQWEsQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFFLENBQUE7d0JBQ3JELENBQUMsRUFBRSxDQUFBO3dCQUNILE1BQUs7cUJBQ047aUJBQ0Y7YUFDRjtZQUVELElBQUksYUFBYSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFO2dCQUMvQyxvQ0FBb0M7Z0JBQ3BDLE9BQU8sS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLHFCQUFZLElBQUksaUJBQWlCLENBQUMsb0JBQW9CLElBQUksQ0FBQyxNQUFNLGFBQWEsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFBO2FBQzdHO1lBQ0QsYUFBYSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFBO1NBQ3hDO1FBRUQsT0FBTyxLQUFLLENBQUE7SUFDZCxDQUFDLENBQUMsQ0FBQTtBQUNKLENBQUM7QUFFRDs7R0FFRztBQUNILE1BQU0sVUFBVSxjQUFjLENBQUMsQ0FBa0M7SUFDL0QsT0FBTyxvQkFBQSx3QkFBQSw0QkFBQSw2QkFDUyxDQUFDLENBQUMsRUFDRCxFQUFFLENBQUMsY0FBYyxDQUFDLEVBQ3hCLFVBQVUsQ0FBQyxFQUNmLENBQUMsQ0FBQyxFQUFFLEVBQUU7UUFDVCxNQUFNLEdBQUcsR0FBRyxDQUFDLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsR0FBRyxJQUFJLEVBQWdCLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDbkUsQ0FBQyxNQUFNLENBQUMsRUFBRTtnQkFDUixHQUFHLElBQUk7Z0JBQ1AsU0FBUyxFQUFHLFNBQXdCLENBQUMsTUFBTSxDQUN6QyxDQUFDLElBQUksRUFBRSxHQUFHLEVBQUUsRUFBRTtvQkFDWixJQUFJLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUE7b0JBQy9CLE9BQU8sSUFBSSxDQUFBO2dCQUNiLENBQUMsRUFDRCxFQUFzRCxDQUN2RDthQUNGO1NBQ0YsQ0FBQyxDQUFBO1FBQ0YsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUNiLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQ1YsTUFBTSxJQUFJLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQTtZQUNsRSxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUc7Z0JBQ1gsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO2dCQUNiLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBUTthQUNqQixDQUFBO1lBQ0QsT0FBTyxJQUFJLENBQUE7UUFDYixDQUFDLEVBQ0QsRUFBNkQsQ0FDOUQsQ0FBQTtJQUNILENBQUMsQ0FBQyxDQUFBO0FBQ04sQ0FBQztBQUVELE1BQU0sUUFBUTtJQUVNO0lBQ0E7SUFGbEIsWUFDa0IsVUFBa0IsRUFDbEIsSUFBUyxDQUFDLGtDQUFrQzs7UUFENUMsZUFBVSxHQUFWLFVBQVUsQ0FBUTtRQUNsQixTQUFJLEdBQUosSUFBSSxDQUFLO0lBQ3hCLENBQUM7Q0FDTCIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnkgKi9cblxuaW1wb3J0IHsgSW52YWxpZFN0YXRlRXJyb3IgfSBmcm9tIFwiLi4vLi4vZXJyb3JzLmpzXCJcbmltcG9ydCAqIGFzIFJTIGZyb20gXCIuL3NjaGVtYS9yb3V0aW5nLmpzXCJcblxudHlwZSBNZXRob2RzID0gXCJHRVRcIiB8IFwiUFVUXCIgfCBcIlBPU1RcIiB8IFwiUEFUQ0hcIiB8IFwiREVMRVRFXCJcblxuY29uc3QgcnggPSAvOihcXHcrKS9nXG5cbnR5cGUgX0E8Qz4gPSBDIGV4dGVuZHMgUmVhZG9ubHlBcnJheTxpbmZlciBBPiA/IEEgOiBuZXZlclxuXG5jbGFzcyBQYXRoc1RyZWUge1xuICBwdWJsaWMgcmVhZG9ubHkgbWV0aG9kczogc3RyaW5nW11cbiAgcHVibGljIHJlYWRvbmx5IHBhcmFtczogeyBba2V5OiBudW1iZXJdOiBQYXRoc1RyZWUgfCB1bmRlZmluZWQgfVxuICBwdWJsaWMgcmVhZG9ubHkgc3VicGF0aHM6IHsgW2tleTogc3RyaW5nXTogUGF0aHNUcmVlIHwgdW5kZWZpbmVkIH1cbiAgcHVibGljIHJlYWRvbmx5IHBhdGg6IHN0cmluZ1xuXG4gIGNvbnN0cnVjdG9yKHBhdGg6IHN0cmluZykge1xuICAgIHRoaXMubWV0aG9kcyA9IFtdXG4gICAgdGhpcy5wYXJhbXMgPSB7fVxuICAgIHRoaXMuc3VicGF0aHMgPSB7fVxuICAgIHRoaXMucGF0aCA9IHBhdGhcbiAgfVxufVxuXG5pbnRlcmZhY2UgTWF0Y2gge1xuICBfdGFnOiBcInJlc291cmNlXCIgfCBcInBhcmFtXCJcbiAgdmFsdWU6IHN0cmluZ1xufVxuXG5mdW5jdGlvbiBjaGVja1NoYWRvd2luZyhcbiAgcGF0aE5hdmlnYXRvcjogUGF0aHNUcmVlLFxuICBtYXRjaDogTWF0Y2hcbikge1xuICByZXR1cm4gRWZmZWN0LmdlbihmdW5jdGlvbiooJCkge1xuICAgIHN3aXRjaCAobWF0Y2guX3RhZykge1xuICAgICAgY2FzZSBcInJlc291cmNlXCI6IHtcbiAgICAgICAgLy8gY2hlY2sgc2hhZG93aW5nOiBpZiAnYS86cGFyYW0nIGNvbWVzIGJlZm9yZSAnYS9iJywgdGhlbiAnYS9iJyBpcyBzaGFkb3dlZFxuICAgICAgICBpZiAocGF0aE5hdmlnYXRvci5wYXJhbXNbMV0pIHtcbiAgICAgICAgICByZXR1cm4geWllbGQqICQoRWZmZWN0LmZhaWwoXG4gICAgICAgICAgICBuZXcgSW52YWxpZFN0YXRlRXJyb3IoXG4gICAgICAgICAgICAgIGBQYXRoICR7cGF0aE5hdmlnYXRvci5wYXRofSR7bWF0Y2gudmFsdWV9LyBpcyBzaGFkb3dlZCBieSAke3BhdGhOYXZpZ2F0b3IucGFyYW1zWzFdLnBhdGh9YFxuICAgICAgICAgICAgKVxuICAgICAgICAgICkpXG4gICAgICAgIH1cbiAgICAgICAgYnJlYWtcbiAgICAgIH1cbiAgICAgIGNhc2UgXCJwYXJhbVwiOiB7XG4gICAgICAgIC8vIGNoZWNrIHNoYWRvd2luZzogaWYgJ2EvYicgY29tZXMgYmVmb3JlICdhLzpwYXJhbScsIHRoZW4gJ2EvXCJwYXJhbScgaXMgcGFydGlhbGx5IHNoYWRvd2VkXG4gICAgICAgIGNvbnN0IHN1YnBhdGhzID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMocGF0aE5hdmlnYXRvci5zdWJwYXRocylcbiAgICAgICAgaWYgKHN1YnBhdGhzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICB5aWVsZCogJChFZmZlY3QuYWxsKHN1YnBhdGhzLm1hcCgocykgPT5cbiAgICAgICAgICAgIEVmZmVjdC5sb2dJbmZvKFxuICAgICAgICAgICAgICBgUGF0aCAke3BhdGhOYXZpZ2F0b3IucGF0aH06JHttYXRjaC52YWx1ZX0vIGlzIHBhcnRpYWxseSBzaGFkb3dlZCBieSAke3BhdGhOYXZpZ2F0b3Iuc3VicGF0aHNbc10hLnBhdGh9YFxuICAgICAgICAgICAgKVxuICAgICAgICAgICkpKVxuICAgICAgICB9XG4gICAgICAgIGJyZWFrXG4gICAgICB9XG4gICAgfVxuICB9KVxufVxuXG5leHBvcnQgZnVuY3Rpb24gY2hlY2tQYXRoczxUIGV4dGVuZHMgeyBwYXRoOiBzdHJpbmc7IG1ldGhvZDogc3RyaW5nIH0+KFxuICBwYXRoczogcmVhZG9ubHkgVFtdXG4pIHtcbiAgcmV0dXJuIEVmZmVjdC5nZW4oZnVuY3Rpb24qKCQpIHtcbiAgICBjb25zdCBwYXRoTWV0aG9kczogUGF0aHNUcmVlID0gbmV3IFBhdGhzVHJlZShcIi9cIilcbiAgICBjb25zdCByZWdleCA9IC8oPzpefFxcLykoW14vOlxcbl0rKXw6KFxcdyspL2dcbiAgICBmb3IgKGNvbnN0IHBhdGggb2YgcGF0aHMpIHtcbiAgICAgIGNvbnN0IG1hdGNoZXMgPSBbLi4ucGF0aC5wYXRoLm1hdGNoQWxsKHJlZ2V4KV1cbiAgICAgICAgLm1hcCgobWF0Y2gpID0+XG4gICAgICAgICAgbWF0Y2hbMV1cbiAgICAgICAgICAgID8geyBfdGFnOiBcInJlc291cmNlXCIsIHZhbHVlOiBtYXRjaFsxXSB9IGFzIGNvbnN0XG4gICAgICAgICAgICA6IHsgX3RhZzogXCJwYXJhbVwiLCB2YWx1ZTogbWF0Y2hbMl0hIH0gYXMgY29uc3RcbiAgICAgICAgKVxuXG4gICAgICBsZXQgcGF0aE5hdmlnYXRvciA9IHBhdGhNZXRob2RzXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG1hdGNoZXMubGVuZ3RoOykge1xuICAgICAgICBjb25zdCBtYXRjaCA9IG1hdGNoZXNbaV0hXG5cbiAgICAgICAgeWllbGQqICQoY2hlY2tTaGFkb3dpbmcocGF0aE5hdmlnYXRvciwgbWF0Y2gpKVxuXG4gICAgICAgIHN3aXRjaCAobWF0Y2guX3RhZykge1xuICAgICAgICAgIGNhc2UgXCJyZXNvdXJjZVwiOiB7XG4gICAgICAgICAgICBpZiAoIShtYXRjaC52YWx1ZSBpbiBwYXRoTmF2aWdhdG9yLnN1YnBhdGhzKSkge1xuICAgICAgICAgICAgICBwYXRoTmF2aWdhdG9yLnN1YnBhdGhzW21hdGNoLnZhbHVlXSA9IG5ldyBQYXRoc1RyZWUoYCR7cGF0aE5hdmlnYXRvci5wYXRofSR7bWF0Y2gudmFsdWV9L2ApXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHBhdGhOYXZpZ2F0b3IgPSBwYXRoTmF2aWdhdG9yLnN1YnBhdGhzW21hdGNoLnZhbHVlXSFcbiAgICAgICAgICAgIGkrK1xuICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSBcInBhcmFtXCI6IHtcbiAgICAgICAgICAgIGNvbnN0IHBhcmFtc05hbWVzID0gW21hdGNoLnZhbHVlXVxuICAgICAgICAgICAgbGV0IG51bWJlck9mUGFyYW1zID0gMVxuICAgICAgICAgICAgd2hpbGUgKGkgPCBtYXRjaGVzLmxlbmd0aCAmJiBtYXRjaGVzW2kgKyAxXT8uX3RhZyA9PT0gXCJwYXJhbVwiKSB7XG4gICAgICAgICAgICAgIG51bWJlck9mUGFyYW1zKytcbiAgICAgICAgICAgICAgaSsrXG4gICAgICAgICAgICAgIHBhcmFtc05hbWVzLnB1c2gobWF0Y2gudmFsdWUpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghKG51bWJlck9mUGFyYW1zIGluIHBhdGhOYXZpZ2F0b3IucGFyYW1zKSkge1xuICAgICAgICAgICAgICBwYXRoTmF2aWdhdG9yLnBhcmFtc1tudW1iZXJPZlBhcmFtc10gPSBuZXcgUGF0aHNUcmVlKFxuICAgICAgICAgICAgICAgIGAke3BhdGhOYXZpZ2F0b3IucGF0aH06JHtwYXJhbXNOYW1lcy5qb2luKFwiLzpcIil9L2BcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcGF0aE5hdmlnYXRvciA9IHBhdGhOYXZpZ2F0b3IucGFyYW1zW251bWJlck9mUGFyYW1zXSFcbiAgICAgICAgICAgIGkrK1xuICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHBhdGhOYXZpZ2F0b3IubWV0aG9kcy5pbmNsdWRlcyhwYXRoLm1ldGhvZCkpIHtcbiAgICAgICAgLy8gdGhyb3cgZHVwbGljYXRlIHBhdGgtbWV0aG9kIGVycm9yXG4gICAgICAgIHJldHVybiB5aWVsZCogJChFZmZlY3QuZmFpbChuZXcgSW52YWxpZFN0YXRlRXJyb3IoYER1cGxpY2F0ZSBtZXRob2QgJHtwYXRoLm1ldGhvZH0gZm9yIHBhdGggJHtwYXRoLnBhdGh9YCkpKVxuICAgICAgfVxuICAgICAgcGF0aE5hdmlnYXRvci5tZXRob2RzLnB1c2gocGF0aC5tZXRob2QpXG4gICAgfVxuXG4gICAgcmV0dXJuIHBhdGhzXG4gIH0pXG59XG5cbi8qKlxuICogV29yayBpbiBwcm9ncmVzcyBKU09OU2NoZW1hIGdlbmVyYXRvci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1ha2VKc29uU2NoZW1hKHI6IEl0ZXJhYmxlPFJTLlJvdXRlRGVzY3JpcHRvckFueT4pIHtcbiAgcmV0dXJuIENodW5rXG4gICAgLmZyb21JdGVyYWJsZShyKVxuICAgIC5mb3JFYWNoRWZmZWN0KFJTLm1ha2VGcm9tU2NoZW1hKVxuICAgIC5mbGF0TWFwKGNoZWNrUGF0aHMpXG4gICAgLm1hcCgoZSkgPT4ge1xuICAgICAgY29uc3QgbWFwID0gKHsgbWV0aG9kLCBwYXRoLCByZXNwb25zZXMsIC4uLnJlc3QgfTogX0E8dHlwZW9mIGU+KSA9PiAoe1xuICAgICAgICBbbWV0aG9kXToge1xuICAgICAgICAgIC4uLnJlc3QsXG4gICAgICAgICAgcmVzcG9uc2VzOiAocmVzcG9uc2VzIGFzIEFycmF5PGFueT4pLnJlZHVjZShcbiAgICAgICAgICAgIChwcmV2LCBjdXIpID0+IHtcbiAgICAgICAgICAgICAgcHJldltjdXIuc3RhdHVzQ29kZV0gPSBjdXIudHlwZVxuICAgICAgICAgICAgICByZXR1cm4gcHJldlxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHt9IGFzIFJlY29yZDxSZXNwb25zZVtcInN0YXR1c0NvZGVcIl0sIFJlc3BvbnNlW1widHlwZVwiXT5cbiAgICAgICAgICApXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICByZXR1cm4gZS5yZWR1Y2UoXG4gICAgICAgIChwcmV2LCBlKSA9PiB7XG4gICAgICAgICAgY29uc3QgcGF0aCA9IGUucGF0aC5zcGxpdChcIj9cIilbMF0ucmVwbGFjZShyeCwgKF9hLCBiKSA9PiBgeyR7Yn19YClcbiAgICAgICAgICBwcmV2W3BhdGhdID0ge1xuICAgICAgICAgICAgLi4ucHJldltwYXRoXSxcbiAgICAgICAgICAgIC4uLm1hcChlKSBhcyBhbnlcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHByZXZcbiAgICAgICAgfSxcbiAgICAgICAge30gYXMgUmVjb3JkPHN0cmluZywgUmVjb3JkPE1ldGhvZHMsIFJldHVyblR5cGU8dHlwZW9mIG1hcD4+PlxuICAgICAgKVxuICAgIH0pXG59XG5cbmNsYXNzIFJlc3BvbnNlIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIHJlYWRvbmx5IHN0YXR1c0NvZGU6IG51bWJlcixcbiAgICBwdWJsaWMgcmVhZG9ubHkgdHlwZTogYW55IC8vIHN0cmluZyB8IEpTT05TY2hlbWEgfCBTdWJTY2hlbWFcbiAgKSB7fVxufVxuIl19
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
b8406b30e5dc86e8886d361354e8ded840ddf37986c569803276d119c900733c
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
cc2e90554066973e1b31534d5490d33b59233503ebcbafddd5483cecb7c817dd
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
6c73d6a53dba8e2732209764f5233c88f81e895dc2e244202cf05253b7fe38f0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
b4b12945fbdaa4d1e98b8a2095ca4363f267e0909cdb70da478a35926e8fbba5
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
86abfcd3894752fc7211a2479161a1f24bc7df3ef89aaa7c2ff967fc7b5c673b
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @effect-app/infra
|
|
2
2
|
|
|
3
|
+
## 0.72.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- b6af4d2f: enhance shadowing paths check
|
|
8
|
+
|
|
9
|
+
## 0.71.2
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Updated dependencies
|
|
14
|
+
- @effect-app/prelude@0.58.2
|
|
15
|
+
- @effect-app/infra-adapters@0.49.2
|
|
16
|
+
|
|
3
17
|
## 0.71.1
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.checkPaths = checkPaths;
|
|
7
7
|
exports.makeJsonSchema = makeJsonSchema;
|
|
8
8
|
var tsplus_module_1 = _interopRequireWildcard(require("@effect/io/Effect"));
|
|
9
|
-
var tsplus_module_2 = _interopRequireWildcard(require("@effect/
|
|
10
|
-
var tsplus_module_3 = _interopRequireWildcard(require("@effect
|
|
9
|
+
var tsplus_module_2 = _interopRequireWildcard(require("@effect-app/core/_ext/Iterable"));
|
|
10
|
+
var tsplus_module_3 = _interopRequireWildcard(require("@effect/data/Chunk"));
|
|
11
11
|
var _errors = require("../../errors.cjs");
|
|
12
12
|
var RS = _interopRequireWildcard(require("./schema/routing.cjs"));
|
|
13
13
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
@@ -15,68 +15,95 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
|
|
|
15
15
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
16
16
|
|
|
17
17
|
const rx = /:(\w+)/g;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const match = matches[i];
|
|
35
|
-
switch (match._tag) {
|
|
36
|
-
case "resource":
|
|
37
|
-
{
|
|
38
|
-
if (!(match.value in pathNavigator)) {
|
|
39
|
-
;
|
|
40
|
-
pathNavigator[match.value] = {
|
|
41
|
-
[methods]: []
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
pathNavigator = pathNavigator[match.value];
|
|
45
|
-
i++;
|
|
46
|
-
break;
|
|
18
|
+
class PathsTree {
|
|
19
|
+
constructor(path) {
|
|
20
|
+
this.methods = [];
|
|
21
|
+
this.params = {};
|
|
22
|
+
this.subpaths = {};
|
|
23
|
+
this.path = path;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function checkShadowing(pathNavigator, match) {
|
|
27
|
+
return tsplus_module_1.gen(function* ($) {
|
|
28
|
+
switch (match._tag) {
|
|
29
|
+
case "resource":
|
|
30
|
+
{
|
|
31
|
+
// check shadowing: if 'a/:param' comes before 'a/b', then 'a/b' is shadowed
|
|
32
|
+
if (pathNavigator.params[1]) {
|
|
33
|
+
return yield* $(tsplus_module_1.fail(new _errors.InvalidStateError(`Path ${pathNavigator.path}${match.value}/ is shadowed by ${pathNavigator.params[1].path}`)));
|
|
47
34
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
case "param":
|
|
38
|
+
{
|
|
39
|
+
// check shadowing: if 'a/b' comes before 'a/:param', then 'a/"param' is partially shadowed
|
|
40
|
+
const subpaths = Object.getOwnPropertyNames(pathNavigator.subpaths);
|
|
41
|
+
if (subpaths.length > 0) {
|
|
42
|
+
yield* $(tsplus_module_2.ext_forEach(subpaths, s => tsplus_module_1.logInfo(`Path ${pathNavigator.path}:${match.value}/ is partially shadowed by ${pathNavigator.subpaths[s].path}`)));
|
|
43
|
+
}
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
function checkPaths(paths) {
|
|
50
|
+
return tsplus_module_1.gen(function* ($) {
|
|
51
|
+
const pathMethods = new PathsTree("/");
|
|
52
|
+
const regex = /(?:^|\/)([^/:\n]+)|:(\w+)/g;
|
|
53
|
+
for (const path of paths) {
|
|
54
|
+
const matches = [...path.path.matchAll(regex)].map(match => match[1] ? {
|
|
55
|
+
_tag: "resource",
|
|
56
|
+
value: match[1]
|
|
57
|
+
} : {
|
|
58
|
+
_tag: "param",
|
|
59
|
+
value: match[2]
|
|
60
|
+
});
|
|
61
|
+
let pathNavigator = pathMethods;
|
|
62
|
+
for (let i = 0; i < matches.length;) {
|
|
63
|
+
const match = matches[i];
|
|
64
|
+
yield* $(checkShadowing(pathNavigator, match));
|
|
65
|
+
switch (match._tag) {
|
|
66
|
+
case "resource":
|
|
67
|
+
{
|
|
68
|
+
if (!(match.value in pathNavigator.subpaths)) {
|
|
69
|
+
pathNavigator.subpaths[match.value] = new PathsTree(`${pathNavigator.path}${match.value}/`);
|
|
70
|
+
}
|
|
71
|
+
pathNavigator = pathNavigator.subpaths[match.value];
|
|
53
72
|
i++;
|
|
73
|
+
break;
|
|
54
74
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
75
|
+
case "param":
|
|
76
|
+
{
|
|
77
|
+
const paramsNames = [match.value];
|
|
78
|
+
let numberOfParams = 1;
|
|
79
|
+
while (i < matches.length && matches[i + 1]?._tag === "param") {
|
|
80
|
+
numberOfParams++;
|
|
81
|
+
i++;
|
|
82
|
+
paramsNames.push(matches[i].value);
|
|
83
|
+
}
|
|
84
|
+
if (!(numberOfParams in pathNavigator.params)) {
|
|
85
|
+
pathNavigator.params[numberOfParams] = new PathsTree(`${pathNavigator.path}:${paramsNames.join("/:")}/`);
|
|
86
|
+
}
|
|
87
|
+
pathNavigator = pathNavigator.params[numberOfParams];
|
|
88
|
+
i++;
|
|
89
|
+
break;
|
|
60
90
|
}
|
|
61
|
-
|
|
62
|
-
i++;
|
|
63
|
-
break;
|
|
64
|
-
}
|
|
91
|
+
}
|
|
65
92
|
}
|
|
93
|
+
if (pathNavigator.methods.includes(path.method)) {
|
|
94
|
+
// throw duplicate path-method error
|
|
95
|
+
return yield* $(tsplus_module_1.fail(new _errors.InvalidStateError(`Duplicate method ${path.method} for path ${path.path}`)));
|
|
96
|
+
}
|
|
97
|
+
pathNavigator.methods.push(path.method);
|
|
66
98
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
return tsplus_module_1.fail(new _errors.InvalidStateError(`Duplicate method ${path.method} for path ${path.path}`));
|
|
70
|
-
}
|
|
71
|
-
pathNavigator[methods].push(path.method);
|
|
72
|
-
}
|
|
73
|
-
return tsplus_module_1.succeed(paths);
|
|
99
|
+
return paths;
|
|
100
|
+
});
|
|
74
101
|
}
|
|
75
102
|
/**
|
|
76
103
|
* Work in progress JSONSchema generator.
|
|
77
104
|
*/
|
|
78
105
|
function makeJsonSchema(r) {
|
|
79
|
-
return tsplus_module_1.map(tsplus_module_1.flatMap(
|
|
106
|
+
return tsplus_module_1.map(tsplus_module_1.flatMap(tsplus_module_2.ext_forEach(tsplus_module_3.fromIterable(r), RS.makeFromSchema), checkPaths), e => {
|
|
80
107
|
const map = ({
|
|
81
108
|
method,
|
|
82
109
|
path,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"makeJsonSchema.cjs","names":["_errors","require","RS","_interopRequireWildcard","_getRequireWildcardCache","nodeInterop","WeakMap","cacheBabelInterop","cacheNodeInterop","obj","__esModule","default","cache","has","get","newObj","hasPropertyDescriptor","Object","defineProperty","getOwnPropertyDescriptor","key","prototype","hasOwnProperty","call","desc","set","rx","
|
|
1
|
+
{"version":3,"file":"makeJsonSchema.cjs","names":["_errors","require","RS","_interopRequireWildcard","_getRequireWildcardCache","nodeInterop","WeakMap","cacheBabelInterop","cacheNodeInterop","obj","__esModule","default","cache","has","get","newObj","hasPropertyDescriptor","Object","defineProperty","getOwnPropertyDescriptor","key","prototype","hasOwnProperty","call","desc","set","rx","PathsTree","constructor","path","methods","params","subpaths","checkShadowing","pathNavigator","match","tsplus_module_1","gen","$","_tag","fail","InvalidStateError","value","getOwnPropertyNames","length","tsplus_module_2","ext_forEach","s","logInfo","checkPaths","paths","pathMethods","regex","matches","matchAll","map","i","paramsNames","numberOfParams","push","join","includes","method","makeJsonSchema","r","flatMap","tsplus_module_3","fromIterable","makeFromSchema","e","responses","rest","reduce","prev","cur","statusCode","type","split","replace","_a","b","Response"],"sources":["../../../_src/api/express/makeJsonSchema.ts"],"sourcesContent":[null],"mappings":"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"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
var tsplus_module_1 = _interopRequireWildcard(require("@effect/io/Effect"));
|
|
4
|
+
var tsplus_module_2 = _interopRequireWildcard(require("@effect/data/Either"));
|
|
5
|
+
var tsplus_module_3 = _interopRequireWildcard(require("@effect/io/Logger"));
|
|
4
6
|
var _errors = require("../../errors.cjs");
|
|
5
7
|
var _makeJsonSchema = require("./makeJsonSchema.cjs");
|
|
6
8
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
@@ -13,15 +15,37 @@ const equalPaths = ["/securities/:idt/search/:id2", "/securities/:id/search/:id2
|
|
|
13
15
|
path,
|
|
14
16
|
method: "get"
|
|
15
17
|
}));
|
|
16
|
-
const differentPaths = ["/securities/:id/search/", "/securities/search/:id2", "/securities/:id/:id2/search/:id3"].map(path => ({
|
|
18
|
+
const differentPaths = ["/securities/search/:id2", "/securities/:id/search/", "/securities/:id/search/:id2", "/securities/:id/:id2/search/:id3"].map(path => ({
|
|
17
19
|
path,
|
|
18
20
|
method: "get"
|
|
19
21
|
})).concat(["/securities/:idt/search/:id2"].map(path => ({
|
|
20
22
|
path,
|
|
21
23
|
method: "post"
|
|
22
24
|
})));
|
|
23
|
-
test("works", () => {
|
|
24
|
-
expect((0, _makeJsonSchema.
|
|
25
|
-
|
|
25
|
+
test("works", async () => {
|
|
26
|
+
expect(await tsplus_module_1.runPromise((0, _makeJsonSchema.checkPaths)(differentPaths))).toStrictEqual(differentPaths);
|
|
27
|
+
for (const p of equalPaths) {
|
|
28
|
+
expect(await tsplus_module_1.runPromiseEither((0, _makeJsonSchema.checkPaths)([path, p]))).toStrictEqual(tsplus_module_2.left(new _errors.InvalidStateError(`Duplicate method ${p.method} for path ${p.path}`)));
|
|
29
|
+
}
|
|
30
|
+
expect(await tsplus_module_1.runPromiseEither((0, _makeJsonSchema.checkPaths)(["a/:p1/c/:p2", "a/b"].map(path => ({
|
|
31
|
+
path,
|
|
32
|
+
method: "get"
|
|
33
|
+
}))))).toStrictEqual(tsplus_module_2.left(new _errors.InvalidStateError(`Path /a/b/ is shadowed by /a/:p1/`)));
|
|
34
|
+
expect(await tsplus_module_1.runPromiseEither((0, _makeJsonSchema.checkPaths)(["a/:p1/c/:p2", "a/:p111/c/d"].map(path => ({
|
|
35
|
+
path,
|
|
36
|
+
method: "get"
|
|
37
|
+
}))))).toStrictEqual(tsplus_module_2.left(new _errors.InvalidStateError(`Path /a/:p1/c/d/ is shadowed by /a/:p1/c/:p2/`)));
|
|
38
|
+
});
|
|
39
|
+
test("log shadowing", async () => {
|
|
40
|
+
const arr = [];
|
|
41
|
+
const paths = ["a/b", "a/:p"].map(path => ({
|
|
42
|
+
path,
|
|
43
|
+
method: "get"
|
|
44
|
+
}));
|
|
45
|
+
const CustomLogger = tsplus_module_3.make((_, __, message) => {
|
|
46
|
+
arr.push(message);
|
|
47
|
+
});
|
|
48
|
+
await tsplus_module_1.runPromise(tsplus_module_1.provideLayer((0, _makeJsonSchema.checkPaths)(paths), tsplus_module_3.replace(tsplus_module_3.defaultLogger, CustomLogger)));
|
|
49
|
+
expect(arr).toStrictEqual([`Path /a/:p/ is partially shadowed by /a/b/`]);
|
|
26
50
|
});
|
|
27
51
|
//# sourceMappingURL=makeJsonSchema.test.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"makeJsonSchema.test.cjs","names":["_errors","require","_makeJsonSchema","_getRequireWildcardCache","nodeInterop","WeakMap","cacheBabelInterop","cacheNodeInterop","_interopRequireWildcard","obj","__esModule","default","cache","has","get","newObj","hasPropertyDescriptor","Object","defineProperty","getOwnPropertyDescriptor","key","prototype","hasOwnProperty","call","desc","set","path","method","equalPaths","map","differentPaths","concat","test","expect","
|
|
1
|
+
{"version":3,"file":"makeJsonSchema.test.cjs","names":["_errors","require","_makeJsonSchema","_getRequireWildcardCache","nodeInterop","WeakMap","cacheBabelInterop","cacheNodeInterop","_interopRequireWildcard","obj","__esModule","default","cache","has","get","newObj","hasPropertyDescriptor","Object","defineProperty","getOwnPropertyDescriptor","key","prototype","hasOwnProperty","call","desc","set","path","method","equalPaths","map","differentPaths","concat","test","expect","tsplus_module_1","runPromise","checkPaths","toStrictEqual","p","runPromiseEither","tsplus_module_2","left","InvalidStateError","arr","paths","CustomLogger","tsplus_module_3","make","_","__","message","push","provideLayer","replace","defaultLogger"],"sources":["../../../_src/api/express/makeJsonSchema.test.ts"],"sourcesContent":[null],"mappings":";;;;;AAAA,IAAAA,OAAA,GAAAC,OAAA;AACA,IAAAC,eAAA,GAAAD,OAAA;AAAgD,SAAAE,yBAAAC,WAAA,eAAAC,OAAA,kCAAAC,iBAAA,OAAAD,OAAA,QAAAE,gBAAA,OAAAF,OAAA,YAAAF,wBAAA,YAAAA,CAAAC,WAAA,WAAAA,WAAA,GAAAG,gBAAA,GAAAD,iBAAA,KAAAF,WAAA;AAAA,SAAAI,wBAAAC,GAAA,EAAAL,WAAA,SAAAA,WAAA,IAAAK,GAAA,IAAAA,GAAA,CAAAC,UAAA,WAAAD,GAAA,QAAAA,GAAA,oBAAAA,GAAA,wBAAAA,GAAA,4BAAAE,OAAA,EAAAF,GAAA,UAAAG,KAAA,GAAAT,wBAAA,CAAAC,WAAA,OAAAQ,KAAA,IAAAA,KAAA,CAAAC,GAAA,CAAAJ,GAAA,YAAAG,KAAA,CAAAE,GAAA,CAAAL,GAAA,SAAAM,MAAA,WAAAC,qBAAA,GAAAC,MAAA,CAAAC,cAAA,IAAAD,MAAA,CAAAE,wBAAA,WAAAC,GAAA,IAAAX,GAAA,QAAAW,GAAA,kBAAAH,MAAA,CAAAI,SAAA,CAAAC,cAAA,CAAAC,IAAA,CAAAd,GAAA,EAAAW,GAAA,SAAAI,IAAA,GAAAR,qBAAA,GAAAC,MAAA,CAAAE,wBAAA,CAAAV,GAAA,EAAAW,GAAA,cAAAI,IAAA,KAAAA,IAAA,CAAAV,GAAA,IAAAU,IAAA,CAAAC,GAAA,KAAAR,MAAA,CAAAC,cAAA,CAAAH,MAAA,EAAAK,GAAA,EAAAI,IAAA,YAAAT,MAAA,CAAAK,GAAA,IAAAX,GAAA,CAAAW,GAAA,SAAAL,MAAA,CAAAJ,OAAA,GAAAF,GAAA,MAAAG,KAAA,IAAAA,KAAA,CAAAa,GAAA,CAAAhB,GAAA,EAAAM,MAAA,YAAAA,MAAA;AAEhD,MAAMW,IAAI,GAAG;EAAEA,IAAI,EAAE,6BAA6B;EAAEC,MAAM,EAAE;AAAK,CAAE;AAEnE,MAAMC,UAAU,GAAG,CACjB,8BAA8B,EAC9B,8BAA8B,EAC9B,+BAA+B,CAChC,CACEC,GAAG,CAAEH,IAAI,KAAM;EAAEA,IAAI;EAAEC,MAAM,EAAE;AAAK,CAAE,CAAC,CAAC;AAE3C,MAAMG,cAAc,GAGd,CACJ,yBAAyB,EACzB,yBAAyB,EACzB,6BAA6B,EAC7B,kCAAkC,CACnC,CACED,GAAG,CAAEH,IAAI,KAAM;EAAEA,IAAI;EAAEC,MAAM,EAAE;AAAK,CAAE,CAAC,CAAC,CACxCI,MAAM,CAAC,CACN,8BAA8B,CAC/B,CACEF,GAAG,CAAEH,IAAI,KAAM;EAAEA,IAAI;EAAEC,MAAM,EAAE;AAAM,CAAE,CAAC,CAAC,CAAC;AAE/CK,IAAI,CAAC,OAAO,EAAE,YAAW;EACvBC,MAAM,CAAC,MAAAC,eAAA,CAAAC,UAAA,CAAO,IAAAC,0BAAU,EAACN,cAAc,CAAE,CAAW,CAAC,CAACO,aAAa,CAACP,cAAc,CAAC;EAEnF,KAAK,MAAMQ,CAAC,IAAIV,UAAU,EAAE;IAC1BK,MAAM,CAAC,MAAAC,eAAA,CAAAK,gBAAA,CAAM,IAAAH,0BAAU,EAAC,CAACV,IAAI,EAAEY,CAAC,CAAC,CAAC,CAAiB,CAAC,CAACD,aAAa,CAChEG,eAAA,CAAAC,IAAA,CAAY,IAAIC,yBAAiB,CAAC,oBAAoBJ,CAAC,CAACX,MAAM,aAAaW,CAAC,CAACZ,IAAI,EAAE,CAAC,CAAC,CACtF;;EAGHO,MAAM,CAAC,MAAAC,eAAA,CAAAK,gBAAA,CAAM,IAAAH,0BAAU,EAAC,CAAC,aAAa,EAAE,KAAK,CAAC,CAACP,GAAG,CAAEH,IAAI,KAAM;IAAEA,IAAI;IAAEC,MAAM,EAAE;EAAK,CAAE,CAAC,CAAC,CAAC,CAAiB,CAAC,CACvGU,aAAa,CACZG,eAAA,CAAAC,IAAA,CAAY,IAAIC,yBAAiB,CAAC,mCAAmC,CAAC,CAAC,CACxE;EAEHT,MAAM,CAAC,MAAAC,eAAA,CAAAK,gBAAA,CAAM,IAAAH,0BAAU,EAAC,CAAC,aAAa,EAAE,aAAa,CAAC,CAACP,GAAG,CAAEH,IAAI,KAAM;IAAEA,IAAI;IAAEC,MAAM,EAAE;EAAK,CAAE,CAAC,CAAC,CAAC,CAAiB,CAAC,CAC/GU,aAAa,CACZG,eAAA,CAAAC,IAAA,CAAY,IAAIC,yBAAiB,CAAC,+CAA+C,CAAC,CAAC,CACpF;AACL,CAAC,CAAC;AAEFV,IAAI,CAAC,eAAe,EAAE,YAAW;EAC/B,MAAMW,GAAG,GAAa,EAAE;EACxB,MAAMC,KAAK,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAACf,GAAG,CAAEH,IAAI,KAAM;IAAEA,IAAI;IAAEC,MAAM,EAAE;EAAK,CAAE,CAAC,CAAC;EAEtE,MAAMkB,YAAY,GAAGC,eAAA,CAAAC,IAAA,CAA0B,CAACC,CAAC,EAAEC,EAAE,EAAEC,OAAO,KAAI;IAChEP,GAAG,CAACQ,IAAI,CAACD,OAAO,CAAC;EACnB,CAAC,CAAC;EAEF,MAAAhB,eAAA,CAAAC,UAAA,CAAMD,eAAA,CAAAkB,YAAA,KAAAhB,0BAAU,EAACQ,KAAK,CAAC,EACPE,eAAA,CAAAO,OAAA,CAAAP,eAAA,CAAAQ,aAAA,EAAqCT,YAAY,CAAC,CAAC,CACtD;EAEbZ,MAAM,CAACU,GAAG,CAAC,CAACN,aAAa,CAAC,CAAC,4CAA4C,CAAC,CAAC;AAC3E,CAAC,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { InvalidStateError } from "../../errors.js"
|
|
2
|
-
import {
|
|
2
|
+
import { checkPaths } from "./makeJsonSchema.js"
|
|
3
3
|
|
|
4
4
|
const path = { path: "/securities/:id/search/:id2", method: "get" }
|
|
5
5
|
|
|
@@ -14,8 +14,9 @@ const differentPaths: {
|
|
|
14
14
|
path: string
|
|
15
15
|
method: string
|
|
16
16
|
}[] = [
|
|
17
|
-
"/securities/:id/search/",
|
|
18
17
|
"/securities/search/:id2",
|
|
18
|
+
"/securities/:id/search/",
|
|
19
|
+
"/securities/:id/search/:id2",
|
|
19
20
|
"/securities/:id/:id2/search/:id3"
|
|
20
21
|
]
|
|
21
22
|
.map((path) => ({ path, method: "get" }))
|
|
@@ -24,12 +25,37 @@ const differentPaths: {
|
|
|
24
25
|
]
|
|
25
26
|
.map((path) => ({ path, method: "post" })))
|
|
26
27
|
|
|
27
|
-
test("works", () => {
|
|
28
|
-
expect(
|
|
28
|
+
test("works", async () => {
|
|
29
|
+
expect(await (checkPaths(differentPaths)).runPromise).toStrictEqual(differentPaths)
|
|
30
|
+
|
|
31
|
+
for (const p of equalPaths) {
|
|
32
|
+
expect(await checkPaths([path, p]).runPromiseEither).toStrictEqual(
|
|
33
|
+
Either.left(new InvalidStateError(`Duplicate method ${p.method} for path ${p.path}`))
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
expect(await checkPaths(["a/:p1/c/:p2", "a/b"].map((path) => ({ path, method: "get" }))).runPromiseEither)
|
|
38
|
+
.toStrictEqual(
|
|
39
|
+
Either.left(new InvalidStateError(`Path /a/b/ is shadowed by /a/:p1/`))
|
|
40
|
+
)
|
|
29
41
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
42
|
+
expect(await checkPaths(["a/:p1/c/:p2", "a/:p111/c/d"].map((path) => ({ path, method: "get" }))).runPromiseEither)
|
|
43
|
+
.toStrictEqual(
|
|
44
|
+
Either.left(new InvalidStateError(`Path /a/:p1/c/d/ is shadowed by /a/:p1/c/:p2/`))
|
|
33
45
|
)
|
|
34
|
-
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
test("log shadowing", async () => {
|
|
49
|
+
const arr: string[] = []
|
|
50
|
+
const paths = ["a/b", "a/:p"].map((path) => ({ path, method: "get" }))
|
|
51
|
+
|
|
52
|
+
const CustomLogger = Logger.make<string, void>((_, __, message) => {
|
|
53
|
+
arr.push(message)
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
await checkPaths(paths)
|
|
57
|
+
.provideLayer(Logger.replace(Logger.defaultLogger, CustomLogger))
|
|
58
|
+
.runPromise
|
|
59
|
+
|
|
60
|
+
expect(arr).toStrictEqual([`Path /a/:p/ is partially shadowed by /a/b/`])
|
|
35
61
|
})
|
|
@@ -9,62 +9,118 @@ const rx = /:(\w+)/g
|
|
|
9
9
|
|
|
10
10
|
type _A<C> = C extends ReadonlyArray<infer A> ? A : never
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
class PathsTree {
|
|
13
|
+
public readonly methods: string[]
|
|
14
|
+
public readonly params: { [key: number]: PathsTree | undefined }
|
|
15
|
+
public readonly subpaths: { [key: string]: PathsTree | undefined }
|
|
16
|
+
public readonly path: string
|
|
17
|
+
|
|
18
|
+
constructor(path: string) {
|
|
19
|
+
this.methods = []
|
|
20
|
+
this.params = {}
|
|
21
|
+
this.subpaths = {}
|
|
22
|
+
this.path = path
|
|
19
23
|
}
|
|
20
|
-
|
|
21
|
-
const regex = /(?:^|\/)([^/:\n]+)|:(\w+)/g
|
|
22
|
-
|
|
23
|
-
for (const path of paths) {
|
|
24
|
-
const matches = [...path.path.matchAll(regex)]
|
|
25
|
-
.map((match) =>
|
|
26
|
-
match[1]
|
|
27
|
-
? { _tag: "resource", value: match[1] } as const
|
|
28
|
-
: { _tag: "param", value: match[2]! } as const
|
|
29
|
-
)
|
|
24
|
+
}
|
|
30
25
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
26
|
+
interface Match {
|
|
27
|
+
_tag: "resource" | "param"
|
|
28
|
+
value: string
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function checkShadowing(
|
|
32
|
+
pathNavigator: PathsTree,
|
|
33
|
+
match: Match
|
|
34
|
+
) {
|
|
35
|
+
return Effect.gen(function*($) {
|
|
36
|
+
switch (match._tag) {
|
|
37
|
+
case "resource": {
|
|
38
|
+
// check shadowing: if 'a/:param' comes before 'a/b', then 'a/b' is shadowed
|
|
39
|
+
if (pathNavigator.params[1]) {
|
|
40
|
+
return yield* $(Effect.fail(
|
|
41
|
+
new InvalidStateError(
|
|
42
|
+
`Path ${pathNavigator.path}${match.value}/ is shadowed by ${pathNavigator.params[1].path}`
|
|
43
|
+
)
|
|
44
|
+
))
|
|
45
|
+
}
|
|
46
|
+
break
|
|
47
|
+
}
|
|
48
|
+
case "param": {
|
|
49
|
+
// check shadowing: if 'a/b' comes before 'a/:param', then 'a/"param' is partially shadowed
|
|
50
|
+
const subpaths = Object.getOwnPropertyNames(pathNavigator.subpaths)
|
|
51
|
+
if (subpaths.length > 0) {
|
|
52
|
+
yield* $(subpaths.forEachEffect((s) =>
|
|
53
|
+
Effect.logInfo(
|
|
54
|
+
`Path ${pathNavigator.path}:${match.value}/ is partially shadowed by ${pathNavigator.subpaths[s]!.path}`
|
|
55
|
+
)
|
|
56
|
+
))
|
|
42
57
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
58
|
+
break
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
})
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function checkPaths<T extends { path: string; method: string }>(
|
|
65
|
+
paths: readonly T[]
|
|
66
|
+
) {
|
|
67
|
+
return Effect.gen(function*($) {
|
|
68
|
+
const pathMethods: PathsTree = new PathsTree("/")
|
|
69
|
+
const regex = /(?:^|\/)([^/:\n]+)|:(\w+)/g
|
|
70
|
+
for (const path of paths) {
|
|
71
|
+
const matches = [...path.path.matchAll(regex)]
|
|
72
|
+
.map((match) =>
|
|
73
|
+
match[1]
|
|
74
|
+
? { _tag: "resource", value: match[1] } as const
|
|
75
|
+
: { _tag: "param", value: match[2]! } as const
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
let pathNavigator = pathMethods
|
|
79
|
+
for (let i = 0; i < matches.length;) {
|
|
80
|
+
const match = matches[i]!
|
|
81
|
+
|
|
82
|
+
yield* $(checkShadowing(pathNavigator, match))
|
|
83
|
+
|
|
84
|
+
switch (match._tag) {
|
|
85
|
+
case "resource": {
|
|
86
|
+
if (!(match.value in pathNavigator.subpaths)) {
|
|
87
|
+
pathNavigator.subpaths[match.value] = new PathsTree(`${pathNavigator.path}${match.value}/`)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
pathNavigator = pathNavigator.subpaths[match.value]!
|
|
47
91
|
i++
|
|
92
|
+
break
|
|
48
93
|
}
|
|
94
|
+
case "param": {
|
|
95
|
+
const paramsNames = [match.value]
|
|
96
|
+
let numberOfParams = 1
|
|
97
|
+
while (i < matches.length && matches[i + 1]?._tag === "param") {
|
|
98
|
+
numberOfParams++
|
|
99
|
+
i++
|
|
100
|
+
paramsNames.push(matches[i]!.value)
|
|
101
|
+
}
|
|
49
102
|
|
|
50
|
-
|
|
51
|
-
|
|
103
|
+
if (!(numberOfParams in pathNavigator.params)) {
|
|
104
|
+
pathNavigator.params[numberOfParams] = new PathsTree(
|
|
105
|
+
`${pathNavigator.path}:${paramsNames.join("/:")}/`
|
|
106
|
+
)
|
|
107
|
+
}
|
|
108
|
+
pathNavigator = pathNavigator.params[numberOfParams]!
|
|
109
|
+
i++
|
|
110
|
+
break
|
|
52
111
|
}
|
|
53
|
-
pathNavigator = (pathNavigator)[numberOfParams]!
|
|
54
|
-
i++
|
|
55
|
-
break
|
|
56
112
|
}
|
|
57
113
|
}
|
|
58
|
-
}
|
|
59
114
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
115
|
+
if (pathNavigator.methods.includes(path.method)) {
|
|
116
|
+
// throw duplicate path-method error
|
|
117
|
+
return yield* $(Effect.fail(new InvalidStateError(`Duplicate method ${path.method} for path ${path.path}`)))
|
|
118
|
+
}
|
|
119
|
+
pathNavigator.methods.push(path.method)
|
|
63
120
|
}
|
|
64
|
-
pathNavigator[methods].push(path.method)
|
|
65
|
-
}
|
|
66
121
|
|
|
67
|
-
|
|
122
|
+
return paths
|
|
123
|
+
})
|
|
68
124
|
}
|
|
69
125
|
|
|
70
126
|
/**
|
|
@@ -74,7 +130,7 @@ export function makeJsonSchema(r: Iterable<RS.RouteDescriptorAny>) {
|
|
|
74
130
|
return Chunk
|
|
75
131
|
.fromIterable(r)
|
|
76
132
|
.forEachEffect(RS.makeFromSchema)
|
|
77
|
-
.flatMap(
|
|
133
|
+
.flatMap(checkPaths)
|
|
78
134
|
.map((e) => {
|
|
79
135
|
const map = ({ method, path, responses, ...rest }: _A<typeof e>) => ({
|
|
80
136
|
[method]: {
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { Effect } from "@effect/io/Effect";
|
|
2
1
|
import { InvalidStateError } from "../../errors.js";
|
|
3
2
|
import * as RS from "./schema/routing.js";
|
|
4
3
|
type Methods = "GET" | "PUT" | "POST" | "PATCH" | "DELETE";
|
|
5
|
-
export declare function
|
|
4
|
+
export declare function checkPaths<T extends {
|
|
6
5
|
path: string;
|
|
7
6
|
method: string;
|
|
8
|
-
}>(paths: readonly T[]): Effect<never, InvalidStateError, readonly T[]>;
|
|
7
|
+
}>(paths: readonly T[]): import("@effect/io/Effect").Effect<never, InvalidStateError, readonly T[]>;
|
|
9
8
|
/**
|
|
10
9
|
* Work in progress JSONSchema generator.
|
|
11
10
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"makeJsonSchema.d.ts","sourceRoot":"","sources":["../../../_src/api/express/makeJsonSchema.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"makeJsonSchema.d.ts","sourceRoot":"","sources":["../../../_src/api/express/makeJsonSchema.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AACnD,OAAO,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAEzC,KAAK,OAAO,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAA;AA0D1D,wBAAgB,UAAU,CAAC,CAAC,SAAS;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EACnE,KAAK,EAAE,SAAS,CAAC,EAAE,8EA2DpB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,QAAQ,CAAC,EAAE,CAAC,kBAAkB,CAAC;;;;;;;;;;;;;;;;;;;;;KA8BhE"}
|
|
@@ -1,61 +1,92 @@
|
|
|
1
1
|
import * as tsplus_module_1 from "@effect/io/Effect";
|
|
2
|
-
import * as tsplus_module_2 from "@effect/
|
|
3
|
-
import * as tsplus_module_3 from "@effect
|
|
2
|
+
import * as tsplus_module_2 from "@effect-app/core/_ext/Iterable";
|
|
3
|
+
import * as tsplus_module_3 from "@effect/data/Chunk";
|
|
4
4
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
5
5
|
import { InvalidStateError } from "../../errors.js";
|
|
6
6
|
import * as RS from "./schema/routing.js";
|
|
7
7
|
const rx = /:(\w+)/g;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
;
|
|
24
|
-
(pathNavigator)[match.value] = { [methods]: [] };
|
|
25
|
-
}
|
|
26
|
-
pathNavigator = (pathNavigator)[match.value];
|
|
27
|
-
i++;
|
|
28
|
-
break;
|
|
8
|
+
class PathsTree {
|
|
9
|
+
constructor(path) {
|
|
10
|
+
this.methods = [];
|
|
11
|
+
this.params = {};
|
|
12
|
+
this.subpaths = {};
|
|
13
|
+
this.path = path;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function checkShadowing(pathNavigator, match) {
|
|
17
|
+
return tsplus_module_1.gen(function* ($) {
|
|
18
|
+
switch (match._tag) {
|
|
19
|
+
case "resource": {
|
|
20
|
+
// check shadowing: if 'a/:param' comes before 'a/b', then 'a/b' is shadowed
|
|
21
|
+
if (pathNavigator.params[1]) {
|
|
22
|
+
return yield* $(tsplus_module_1.fail(new InvalidStateError(`Path ${pathNavigator.path}${match.value}/ is shadowed by ${pathNavigator.params[1].path}`)));
|
|
29
23
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
24
|
+
break;
|
|
25
|
+
}
|
|
26
|
+
case "param": {
|
|
27
|
+
// check shadowing: if 'a/b' comes before 'a/:param', then 'a/"param' is partially shadowed
|
|
28
|
+
const subpaths = Object.getOwnPropertyNames(pathNavigator.subpaths);
|
|
29
|
+
if (subpaths.length > 0) {
|
|
30
|
+
yield* $(tsplus_module_2.ext_forEach(subpaths, (s) => tsplus_module_1.logInfo(`Path ${pathNavigator.path}:${match.value}/ is partially shadowed by ${pathNavigator.subpaths[s].path}`)));
|
|
31
|
+
}
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
export function checkPaths(paths) {
|
|
38
|
+
return tsplus_module_1.gen(function* ($) {
|
|
39
|
+
const pathMethods = new PathsTree("/");
|
|
40
|
+
const regex = /(?:^|\/)([^/:\n]+)|:(\w+)/g;
|
|
41
|
+
for (const path of paths) {
|
|
42
|
+
const matches = [...path.path.matchAll(regex)]
|
|
43
|
+
.map((match) => match[1]
|
|
44
|
+
? { _tag: "resource", value: match[1] }
|
|
45
|
+
: { _tag: "param", value: match[2] });
|
|
46
|
+
let pathNavigator = pathMethods;
|
|
47
|
+
for (let i = 0; i < matches.length;) {
|
|
48
|
+
const match = matches[i];
|
|
49
|
+
yield* $(checkShadowing(pathNavigator, match));
|
|
50
|
+
switch (match._tag) {
|
|
51
|
+
case "resource": {
|
|
52
|
+
if (!(match.value in pathNavigator.subpaths)) {
|
|
53
|
+
pathNavigator.subpaths[match.value] = new PathsTree(`${pathNavigator.path}${match.value}/`);
|
|
54
|
+
}
|
|
55
|
+
pathNavigator = pathNavigator.subpaths[match.value];
|
|
34
56
|
i++;
|
|
57
|
+
break;
|
|
35
58
|
}
|
|
36
|
-
|
|
37
|
-
;
|
|
38
|
-
|
|
59
|
+
case "param": {
|
|
60
|
+
const paramsNames = [match.value];
|
|
61
|
+
let numberOfParams = 1;
|
|
62
|
+
while (i < matches.length && matches[i + 1]?._tag === "param") {
|
|
63
|
+
numberOfParams++;
|
|
64
|
+
i++;
|
|
65
|
+
paramsNames.push(matches[i].value);
|
|
66
|
+
}
|
|
67
|
+
if (!(numberOfParams in pathNavigator.params)) {
|
|
68
|
+
pathNavigator.params[numberOfParams] = new PathsTree(`${pathNavigator.path}:${paramsNames.join("/:")}/`);
|
|
69
|
+
}
|
|
70
|
+
pathNavigator = pathNavigator.params[numberOfParams];
|
|
71
|
+
i++;
|
|
72
|
+
break;
|
|
39
73
|
}
|
|
40
|
-
pathNavigator = (pathNavigator)[numberOfParams];
|
|
41
|
-
i++;
|
|
42
|
-
break;
|
|
43
74
|
}
|
|
44
75
|
}
|
|
76
|
+
if (pathNavigator.methods.includes(path.method)) {
|
|
77
|
+
// throw duplicate path-method error
|
|
78
|
+
return yield* $(tsplus_module_1.fail(new InvalidStateError(`Duplicate method ${path.method} for path ${path.path}`)));
|
|
79
|
+
}
|
|
80
|
+
pathNavigator.methods.push(path.method);
|
|
45
81
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
return tsplus_module_1.fail(new InvalidStateError(`Duplicate method ${path.method} for path ${path.path}`));
|
|
49
|
-
}
|
|
50
|
-
pathNavigator[methods].push(path.method);
|
|
51
|
-
}
|
|
52
|
-
return tsplus_module_1.succeed(paths);
|
|
82
|
+
return paths;
|
|
83
|
+
});
|
|
53
84
|
}
|
|
54
85
|
/**
|
|
55
86
|
* Work in progress JSONSchema generator.
|
|
56
87
|
*/
|
|
57
88
|
export function makeJsonSchema(r) {
|
|
58
|
-
return tsplus_module_1.map(tsplus_module_1.flatMap(
|
|
89
|
+
return tsplus_module_1.map(tsplus_module_1.flatMap(tsplus_module_2.ext_forEach(tsplus_module_3.fromIterable(r), RS.makeFromSchema), checkPaths), (e) => {
|
|
59
90
|
const map = ({ method, path, responses, ...rest }) => ({
|
|
60
91
|
[method]: {
|
|
61
92
|
...rest,
|
|
@@ -82,4 +113,4 @@ class Response {
|
|
|
82
113
|
this.type = type;
|
|
83
114
|
}
|
|
84
115
|
}
|
|
85
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
116
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFrZUpzb25TY2hlbWEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9fc3JjL2FwaS9leHByZXNzL21ha2VKc29uU2NoZW1hLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHVEQUF1RDtBQUV2RCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQTtBQUNuRCxPQUFPLEtBQUssRUFBRSxNQUFNLHFCQUFxQixDQUFBO0FBSXpDLE1BQU0sRUFBRSxHQUFHLFNBQVMsQ0FBQTtBQUlwQixNQUFNLFNBQVM7SUFNYixZQUFZLElBQVk7UUFDdEIsSUFBSSxDQUFDLE9BQU8sR0FBRyxFQUFFLENBQUE7UUFDakIsSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFFLENBQUE7UUFDaEIsSUFBSSxDQUFDLFFBQVEsR0FBRyxFQUFFLENBQUE7UUFDbEIsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUE7SUFDbEIsQ0FBQztDQUNGO0FBT0QsU0FBUyxjQUFjLENBQ3JCLGFBQXdCLEVBQ3hCLEtBQVk7SUFFWixPQUFPLG9CQUFXLFFBQVEsQ0FBQyxFQUFDLENBQUM7UUFDM0IsUUFBUSxLQUFLLENBQUMsSUFBSSxFQUFFO1lBQ2xCLEtBQUssVUFBVSxDQUFDLENBQUM7Z0JBQ2YsNEVBQTRFO2dCQUM1RSxJQUFJLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUU7b0JBQzNCLE9BQU8sS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLHFCQUNkLElBQUksaUJBQWlCLENBQ25CLFFBQVEsYUFBYSxDQUFDLElBQUksR0FBRyxLQUFLLENBQUMsS0FBSyxvQkFBb0IsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FDM0YsQ0FDRixDQUFDLENBQUE7aUJBQ0g7Z0JBQ0QsTUFBSzthQUNOO1lBQ0QsS0FBSyxPQUFPLENBQUMsQ0FBQztnQkFDWiwyRkFBMkY7Z0JBQzNGLE1BQU0sUUFBUSxH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
|
|
@@ -18,7 +18,7 @@ export declare function makeOpenApiSpecs(rdescs: Iterable<RouteDescriptorAny>, i
|
|
|
18
18
|
version: string;
|
|
19
19
|
};
|
|
20
20
|
tags: never[];
|
|
21
|
-
paths: Record<string, Record<"
|
|
21
|
+
paths: Record<string, Record<"GET" | "PUT" | "POST" | "PATCH" | "DELETE", {
|
|
22
22
|
[x: string]: {
|
|
23
23
|
responses: any;
|
|
24
24
|
tags: readonly string[] | undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effect-app/infra",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.72.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"dependencies": {
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
"pure-rand": "^6.0.2",
|
|
21
21
|
"redlock": "^4.2.0",
|
|
22
22
|
"@effect-app/core": "0.56.1",
|
|
23
|
-
"@effect-app/
|
|
24
|
-
"@effect-app/
|
|
23
|
+
"@effect-app/infra-adapters": "0.49.2",
|
|
24
|
+
"@effect-app/prelude": "0.58.2",
|
|
25
25
|
"@effect-app/schema": "0.50.1"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|