@scalar/oas-utils 0.2.140 → 0.2.142
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 +18 -0
- package/dist/entities/cookie/cookie.js +14 -13
- package/dist/entities/cookie/cookie.js.map +7 -0
- package/dist/entities/cookie/index.d.ts +1 -1
- package/dist/entities/cookie/index.d.ts.map +1 -1
- package/dist/entities/cookie/index.js +5 -1
- package/dist/entities/cookie/index.js.map +7 -0
- package/dist/entities/environment/environment.js +10 -9
- package/dist/entities/environment/environment.js.map +7 -0
- package/dist/entities/environment/index.d.ts +1 -1
- package/dist/entities/environment/index.d.ts.map +1 -1
- package/dist/entities/environment/index.js +5 -1
- package/dist/entities/environment/index.js.map +7 -0
- package/dist/entities/hotkeys/hotkeys.js +109 -116
- package/dist/entities/hotkeys/hotkeys.js.map +7 -0
- package/dist/entities/hotkeys/index.d.ts +1 -1
- package/dist/entities/hotkeys/index.d.ts.map +1 -1
- package/dist/entities/hotkeys/index.js +6 -1
- package/dist/entities/hotkeys/index.js.map +7 -0
- package/dist/entities/shared/index.d.ts +1 -1
- package/dist/entities/shared/index.d.ts.map +1 -1
- package/dist/entities/shared/index.js +7 -1
- package/dist/entities/shared/index.js.map +7 -0
- package/dist/entities/shared/utility.js +9 -12
- package/dist/entities/shared/utility.js.map +7 -0
- package/dist/entities/spec/collection.d.ts.map +1 -1
- package/dist/entities/spec/collection.js +91 -94
- package/dist/entities/spec/collection.js.map +7 -0
- package/dist/entities/spec/index.d.ts +8 -8
- package/dist/entities/spec/index.d.ts.map +1 -1
- package/dist/entities/spec/index.js +59 -9
- package/dist/entities/spec/index.js.map +7 -0
- package/dist/entities/spec/operation.d.ts +1 -1
- package/dist/entities/spec/operation.d.ts.map +1 -1
- package/dist/entities/spec/operation.js +5 -8
- package/dist/entities/spec/operation.js.map +7 -0
- package/dist/entities/spec/operation.test.js +43 -0
- package/dist/entities/spec/operation.test.js.map +7 -0
- package/dist/entities/spec/parameters.d.ts +1 -1
- package/dist/entities/spec/parameters.d.ts.map +1 -1
- package/dist/entities/spec/parameters.js +40 -38
- package/dist/entities/spec/parameters.js.map +7 -0
- package/dist/entities/spec/parameters.test.js +71 -0
- package/dist/entities/spec/parameters.test.js.map +7 -0
- package/dist/entities/spec/request-example.test.js +637 -0
- package/dist/entities/spec/request-example.test.js.map +7 -0
- package/dist/entities/spec/request-examples.d.ts +3 -3
- package/dist/entities/spec/request-examples.d.ts.map +1 -1
- package/dist/entities/spec/request-examples.js +323 -338
- package/dist/entities/spec/request-examples.js.map +7 -0
- package/dist/entities/spec/requests.d.ts +6 -8
- package/dist/entities/spec/requests.d.ts.map +1 -1
- package/dist/entities/spec/requests.js +80 -101
- package/dist/entities/spec/requests.js.map +7 -0
- package/dist/entities/spec/server.js +47 -63
- package/dist/entities/spec/server.js.map +7 -0
- package/dist/entities/spec/server.test.js +120 -0
- package/dist/entities/spec/server.test.js.map +7 -0
- package/dist/entities/spec/spec-objects.d.ts.map +1 -1
- package/dist/entities/spec/spec-objects.js +77 -121
- package/dist/entities/spec/spec-objects.js.map +7 -0
- package/dist/entities/spec/spec-objects.test.js +205 -0
- package/dist/entities/spec/spec-objects.test.js.map +7 -0
- package/dist/entities/spec/x-scalar-environments.js +21 -18
- package/dist/entities/spec/x-scalar-environments.js.map +7 -0
- package/dist/entities/spec/x-scalar-environments.test.js +11 -0
- package/dist/entities/spec/x-scalar-environments.test.js.map +7 -0
- package/dist/entities/spec/x-scalar-secrets.js +8 -6
- package/dist/entities/spec/x-scalar-secrets.js.map +7 -0
- package/dist/entities/spec/x-scalar-secrets.test.js +11 -0
- package/dist/entities/spec/x-scalar-secrets.test.js.map +7 -0
- package/dist/entities/workspace/index.d.ts +1 -1
- package/dist/entities/workspace/index.d.ts.map +1 -1
- package/dist/entities/workspace/index.js +7 -1
- package/dist/entities/workspace/index.js.map +7 -0
- package/dist/entities/workspace/workspace.js +46 -50
- package/dist/entities/workspace/workspace.js.map +7 -0
- package/dist/helpers/create-hash.js +15 -18
- package/dist/helpers/create-hash.js.map +7 -0
- package/dist/helpers/ensure-protocol.js +9 -10
- package/dist/helpers/ensure-protocol.js.map +7 -0
- package/dist/helpers/ensure-protocol.test.js +70 -0
- package/dist/helpers/ensure-protocol.test.js.map +7 -0
- package/dist/helpers/fetch-document.js +24 -32
- package/dist/helpers/fetch-document.js.map +7 -0
- package/dist/helpers/fetch-document.test.js +63 -0
- package/dist/helpers/fetch-document.test.js.map +7 -0
- package/dist/helpers/fetch-with-proxy-fallback.js +20 -28
- package/dist/helpers/fetch-with-proxy-fallback.js.map +7 -0
- package/dist/helpers/find-variables.d.ts +1 -1
- package/dist/helpers/find-variables.d.ts.map +1 -1
- package/dist/helpers/find-variables.js +6 -8
- package/dist/helpers/find-variables.js.map +7 -0
- package/dist/helpers/find-variables.test.js +20 -0
- package/dist/helpers/find-variables.test.js.map +7 -0
- package/dist/helpers/http-methods.d.ts +1 -1
- package/dist/helpers/http-methods.d.ts.map +1 -1
- package/dist/helpers/http-methods.js +60 -66
- package/dist/helpers/http-methods.js.map +7 -0
- package/dist/helpers/http-status-codes.js +319 -317
- package/dist/helpers/http-status-codes.js.map +7 -0
- package/dist/helpers/index.d.ts +27 -27
- package/dist/helpers/index.d.ts.map +1 -1
- package/dist/helpers/index.js +73 -27
- package/dist/helpers/index.js.map +7 -0
- package/dist/helpers/is-defined.js +5 -14
- package/dist/helpers/is-defined.js.map +7 -0
- package/dist/helpers/is-defined.test.js +37 -0
- package/dist/helpers/is-defined.test.js.map +7 -0
- package/dist/helpers/is-local-url.js +11 -16
- package/dist/helpers/is-local-url.js.map +7 -0
- package/dist/helpers/is-local-url.test.js +40 -0
- package/dist/helpers/is-local-url.test.js.map +7 -0
- package/dist/helpers/is-valid-url.js +9 -18
- package/dist/helpers/is-valid-url.js.map +7 -0
- package/dist/helpers/is-valid-url.test.js +17 -0
- package/dist/helpers/is-valid-url.test.js.map +7 -0
- package/dist/helpers/iterate-title.js +11 -15
- package/dist/helpers/iterate-title.js.map +7 -0
- package/dist/helpers/json2xml.js +40 -47
- package/dist/helpers/json2xml.js.map +7 -0
- package/dist/helpers/json2xml.test.js +19 -0
- package/dist/helpers/json2xml.test.js.map +7 -0
- package/dist/helpers/local-storage.js +13 -15
- package/dist/helpers/local-storage.js.map +7 -0
- package/dist/helpers/make-url-absolute.js +11 -17
- package/dist/helpers/make-url-absolute.js.map +7 -0
- package/dist/helpers/make-url-absolute.test.js +61 -0
- package/dist/helpers/make-url-absolute.test.js.map +7 -0
- package/dist/helpers/merge-urls.js +50 -75
- package/dist/helpers/merge-urls.js.map +7 -0
- package/dist/helpers/merge-urls.test.js +339 -0
- package/dist/helpers/merge-urls.test.js.map +7 -0
- package/dist/helpers/normalize-mime-type-object.js +21 -31
- package/dist/helpers/normalize-mime-type-object.js.map +7 -0
- package/dist/helpers/normalize-mime-type-object.test.js +53 -0
- package/dist/helpers/normalize-mime-type-object.test.js.map +7 -0
- package/dist/helpers/normalize-mime-type.js +8 -18
- package/dist/helpers/normalize-mime-type.js.map +7 -0
- package/dist/helpers/normalize-mime-type.test.js +33 -0
- package/dist/helpers/normalize-mime-type.test.js.map +7 -0
- package/dist/helpers/object.js +12 -18
- package/dist/helpers/object.js.map +7 -0
- package/dist/helpers/omit-undefined-values.js +17 -19
- package/dist/helpers/omit-undefined-values.js.map +7 -0
- package/dist/helpers/omit-undefined-values.test.js +89 -0
- package/dist/helpers/omit-undefined-values.test.js.map +7 -0
- package/dist/helpers/parse.js +71 -83
- package/dist/helpers/parse.js.map +7 -0
- package/dist/helpers/parse.test.js +45 -0
- package/dist/helpers/parse.test.js.map +7 -0
- package/dist/helpers/pretty-print-json.js +31 -35
- package/dist/helpers/pretty-print-json.js.map +7 -0
- package/dist/helpers/pretty-print-json.test.js +28 -0
- package/dist/helpers/pretty-print-json.test.js.map +7 -0
- package/dist/helpers/redirect-to-proxy.js +46 -83
- package/dist/helpers/redirect-to-proxy.js.map +7 -0
- package/dist/helpers/redirect-to-proxy.test.js +54 -0
- package/dist/helpers/redirect-to-proxy.test.js.map +7 -0
- package/dist/helpers/regex-helpers.js +11 -9
- package/dist/helpers/regex-helpers.js.map +7 -0
- package/dist/helpers/regex-helpers.test.js +154 -0
- package/dist/helpers/regex-helpers.test.js.map +7 -0
- package/dist/helpers/replace-variables.js +13 -16
- package/dist/helpers/replace-variables.js.map +7 -0
- package/dist/helpers/replace-variables.test.js +30 -0
- package/dist/helpers/replace-variables.test.js.map +7 -0
- package/dist/helpers/schema-model.js +15 -14
- package/dist/helpers/schema-model.js.map +7 -0
- package/dist/helpers/security/get-schemes.d.ts +1 -1
- package/dist/helpers/security/get-schemes.d.ts.map +1 -1
- package/dist/helpers/security/get-schemes.js +7 -9
- package/dist/helpers/security/get-schemes.js.map +7 -0
- package/dist/helpers/security/get-schemes.test.js +71 -0
- package/dist/helpers/security/get-schemes.test.js.map +7 -0
- package/dist/helpers/security/has-token.js +18 -19
- package/dist/helpers/security/has-token.js.map +7 -0
- package/dist/helpers/security/has-token.test.js +157 -0
- package/dist/helpers/security/has-token.test.js.map +7 -0
- package/dist/helpers/security/index.d.ts +2 -2
- package/dist/helpers/security/index.d.ts.map +1 -1
- package/dist/helpers/security/index.js +7 -2
- package/dist/helpers/security/index.js.map +7 -0
- package/dist/helpers/should-ignore-entity.d.ts +2 -2
- package/dist/helpers/should-ignore-entity.d.ts.map +1 -1
- package/dist/helpers/should-ignore-entity.js +5 -6
- package/dist/helpers/should-ignore-entity.js.map +7 -0
- package/dist/helpers/ssr-state.js +6 -6
- package/dist/helpers/ssr-state.js.map +7 -0
- package/dist/helpers/string.js +6 -18
- package/dist/helpers/string.js.map +7 -0
- package/dist/migrations/data-version.js +7 -17
- package/dist/migrations/data-version.js.map +7 -0
- package/dist/migrations/generate-types.js +56 -0
- package/dist/migrations/generate-types.js.map +7 -0
- package/dist/migrations/index.d.ts +3 -3
- package/dist/migrations/index.d.ts.map +1 -1
- package/dist/migrations/index.js +10 -3
- package/dist/migrations/index.js.map +7 -0
- package/dist/migrations/local-storage.d.ts +1 -1
- package/dist/migrations/local-storage.d.ts.map +1 -1
- package/dist/migrations/local-storage.js +27 -32
- package/dist/migrations/local-storage.js.map +7 -0
- package/dist/migrations/migrator.d.ts +1 -1
- package/dist/migrations/migrator.d.ts.map +1 -1
- package/dist/migrations/migrator.js +51 -58
- package/dist/migrations/migrator.js.map +7 -0
- package/dist/migrations/semver.js +23 -25
- package/dist/migrations/semver.js.map +7 -0
- package/dist/migrations/semver.test.js +21 -0
- package/dist/migrations/semver.test.js.map +7 -0
- package/dist/migrations/v-0.0.0/types.generated.js +1 -0
- package/dist/migrations/v-0.0.0/types.generated.js.map +7 -0
- package/dist/migrations/v-2.1.0/migration.d.ts +2 -2
- package/dist/migrations/v-2.1.0/migration.d.ts.map +1 -1
- package/dist/migrations/v-2.1.0/migration.js +256 -273
- package/dist/migrations/v-2.1.0/migration.js.map +7 -0
- package/dist/migrations/v-2.1.0/types.generated.js +1 -0
- package/dist/migrations/v-2.1.0/types.generated.js.map +7 -0
- package/dist/migrations/v-2.2.0/migration.d.ts +2 -2
- package/dist/migrations/v-2.2.0/migration.d.ts.map +1 -1
- package/dist/migrations/v-2.2.0/migration.js +95 -100
- package/dist/migrations/v-2.2.0/migration.js.map +7 -0
- package/dist/migrations/v-2.2.0/types.generated.js +1 -0
- package/dist/migrations/v-2.2.0/types.generated.js.map +7 -0
- package/dist/migrations/v-2.3.0/migration.d.ts +2 -2
- package/dist/migrations/v-2.3.0/migration.d.ts.map +1 -1
- package/dist/migrations/v-2.3.0/migration.js +47 -46
- package/dist/migrations/v-2.3.0/migration.js.map +7 -0
- package/dist/migrations/v-2.3.0/types.generated.js +1 -0
- package/dist/migrations/v-2.3.0/types.generated.js.map +7 -0
- package/dist/migrations/v-2.4.0/migration.d.ts +2 -2
- package/dist/migrations/v-2.4.0/migration.d.ts.map +1 -1
- package/dist/migrations/v-2.4.0/migration.js +24 -26
- package/dist/migrations/v-2.4.0/migration.js.map +7 -0
- package/dist/migrations/v-2.4.0/migration.test.js +90 -0
- package/dist/migrations/v-2.4.0/migration.test.js.map +7 -0
- package/dist/migrations/v-2.4.0/types.generated.js +1 -0
- package/dist/migrations/v-2.4.0/types.generated.js.map +7 -0
- package/dist/migrations/v-2.5.0/migration.d.ts +2 -2
- package/dist/migrations/v-2.5.0/migration.d.ts.map +1 -1
- package/dist/migrations/v-2.5.0/migration.js +135 -119
- package/dist/migrations/v-2.5.0/migration.js.map +7 -0
- package/dist/migrations/v-2.5.0/migration.test.js +108 -0
- package/dist/migrations/v-2.5.0/migration.test.js.map +7 -0
- package/dist/migrations/v-2.5.0/types.generated.d.ts +8 -8
- package/dist/migrations/v-2.5.0/types.generated.d.ts.map +1 -1
- package/dist/migrations/v-2.5.0/types.generated.js +1 -0
- package/dist/migrations/v-2.5.0/types.generated.js.map +7 -0
- package/dist/spec-getters/get-example-from-schema.js +206 -268
- package/dist/spec-getters/get-example-from-schema.js.map +7 -0
- package/dist/spec-getters/get-example-from-schema.test.js +1092 -0
- package/dist/spec-getters/get-example-from-schema.test.js.map +7 -0
- package/dist/spec-getters/get-parameters-from-operation.js +22 -42
- package/dist/spec-getters/get-parameters-from-operation.js.map +7 -0
- package/dist/spec-getters/get-parameters-from-operation.test.js +178 -0
- package/dist/spec-getters/get-parameters-from-operation.test.js.map +7 -0
- package/dist/spec-getters/get-request-body-from-operation.js +110 -162
- package/dist/spec-getters/get-request-body-from-operation.js.map +7 -0
- package/dist/spec-getters/get-request-body-from-operation.test.js +289 -0
- package/dist/spec-getters/get-request-body-from-operation.test.js.map +7 -0
- package/dist/spec-getters/get-server-variable-examples.d.ts +1 -1
- package/dist/spec-getters/get-server-variable-examples.d.ts.map +1 -1
- package/dist/spec-getters/get-server-variable-examples.js +12 -11
- package/dist/spec-getters/get-server-variable-examples.js.map +7 -0
- package/dist/spec-getters/index.d.ts +4 -4
- package/dist/spec-getters/index.d.ts.map +1 -1
- package/dist/spec-getters/index.js +11 -4
- package/dist/spec-getters/index.js.map +7 -0
- package/dist/transforms/import-spec.d.ts +6 -6
- package/dist/transforms/import-spec.d.ts.map +1 -1
- package/dist/transforms/import-spec.js +313 -425
- package/dist/transforms/import-spec.js.map +7 -0
- package/dist/transforms/import-spec.test.js +1124 -0
- package/dist/transforms/import-spec.test.js.map +7 -0
- package/dist/transforms/index.d.ts +1 -1
- package/dist/transforms/index.d.ts.map +1 -1
- package/dist/transforms/index.js +13 -1
- package/dist/transforms/index.js.map +7 -0
- package/package.json +10 -11
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { combineUrlAndPath, mergeSearchParams, mergeUrls } from "./merge-urls.js";
|
|
3
|
+
describe("mergeSearchParams", () => {
|
|
4
|
+
it("merges basic params from different sources", () => {
|
|
5
|
+
const base = new URLSearchParams("a=1&b=2");
|
|
6
|
+
const path = new URLSearchParams("c=3");
|
|
7
|
+
const url = new URLSearchParams("d=4");
|
|
8
|
+
const result = mergeSearchParams(base, path, url);
|
|
9
|
+
expect(result.toString()).toBe("a=1&b=2&c=3&d=4");
|
|
10
|
+
});
|
|
11
|
+
it("later sources overwrite earlier ones completely", () => {
|
|
12
|
+
const base = new URLSearchParams("a=1&b=2");
|
|
13
|
+
const path = new URLSearchParams("b=3");
|
|
14
|
+
const url = new URLSearchParams("b=4");
|
|
15
|
+
const result = mergeSearchParams(base, path, url);
|
|
16
|
+
expect(result.toString()).toBe("a=1&b=4");
|
|
17
|
+
});
|
|
18
|
+
it("preserves multiple values from the same source", () => {
|
|
19
|
+
const base = new URLSearchParams("a=1&a=2");
|
|
20
|
+
const path = new URLSearchParams("b=3&b=4");
|
|
21
|
+
const url = new URLSearchParams("c=5&c=6");
|
|
22
|
+
const result = mergeSearchParams(base, path, url);
|
|
23
|
+
expect(result.toString()).toBe("a=1&a=2&b=3&b=4&c=5&c=6");
|
|
24
|
+
});
|
|
25
|
+
it("overwrites multiple values from earlier sources", () => {
|
|
26
|
+
const base = new URLSearchParams("a=1&a=2");
|
|
27
|
+
const path = new URLSearchParams("a=3&a=4");
|
|
28
|
+
const url = new URLSearchParams();
|
|
29
|
+
const result = mergeSearchParams(base, path, url);
|
|
30
|
+
expect(result.toString()).toBe("a=3&a=4");
|
|
31
|
+
});
|
|
32
|
+
it("handles empty params", () => {
|
|
33
|
+
const base = new URLSearchParams();
|
|
34
|
+
const path = new URLSearchParams("a=1");
|
|
35
|
+
const url = new URLSearchParams();
|
|
36
|
+
const result = mergeSearchParams(base, path, url);
|
|
37
|
+
expect(result.toString()).toBe("a=1");
|
|
38
|
+
});
|
|
39
|
+
it("handles special characters correctly", () => {
|
|
40
|
+
const base = new URLSearchParams("q=hello world");
|
|
41
|
+
const path = new URLSearchParams("filter=type:123");
|
|
42
|
+
const url = new URLSearchParams("special=@#$%");
|
|
43
|
+
const result = mergeSearchParams(base, path, url);
|
|
44
|
+
expect(decodeURIComponent(result.toString())).toBe("q=hello+world&filter=type:123&special=@#$%");
|
|
45
|
+
});
|
|
46
|
+
it("handles complex overwriting scenarios", () => {
|
|
47
|
+
const base = new URLSearchParams("a=1&a=2&b=1&c=1");
|
|
48
|
+
const path = new URLSearchParams("b=2&b=3&c=2");
|
|
49
|
+
const url = new URLSearchParams("c=3&c=4");
|
|
50
|
+
const result = mergeSearchParams(base, path, url);
|
|
51
|
+
expect(result.toString()).toBe("a=1&a=2&b=2&b=3&c=3&c=4");
|
|
52
|
+
});
|
|
53
|
+
it("maintains order of parameters", () => {
|
|
54
|
+
const base = new URLSearchParams("first=1&second=2");
|
|
55
|
+
const path = new URLSearchParams("third=3");
|
|
56
|
+
const url = new URLSearchParams("fourth=4");
|
|
57
|
+
const result = mergeSearchParams(base, path, url);
|
|
58
|
+
expect(result.toString()).toBe("first=1&second=2&third=3&fourth=4");
|
|
59
|
+
});
|
|
60
|
+
it("handles boolean and numeric values", () => {
|
|
61
|
+
const base = new URLSearchParams("bool=true&num=123");
|
|
62
|
+
const path = new URLSearchParams("bool=false");
|
|
63
|
+
const url = new URLSearchParams("num=456");
|
|
64
|
+
const result = mergeSearchParams(base, path, url);
|
|
65
|
+
expect(result.toString()).toBe("bool=false&num=456");
|
|
66
|
+
});
|
|
67
|
+
it("handles null and undefined values", () => {
|
|
68
|
+
const base = new URLSearchParams("a=null&b=undefined");
|
|
69
|
+
const path = new URLSearchParams("a=value");
|
|
70
|
+
const url = new URLSearchParams();
|
|
71
|
+
const result = mergeSearchParams(base, path, url);
|
|
72
|
+
expect(result.toString()).toBe("a=value&b=undefined");
|
|
73
|
+
});
|
|
74
|
+
it("handles empty string values", () => {
|
|
75
|
+
const base = new URLSearchParams("a=&b=value");
|
|
76
|
+
const path = new URLSearchParams("b=");
|
|
77
|
+
const url = new URLSearchParams();
|
|
78
|
+
const result = mergeSearchParams(base, path, url);
|
|
79
|
+
expect(result.toString()).toBe("a=&b=");
|
|
80
|
+
});
|
|
81
|
+
describe("edge cases", () => {
|
|
82
|
+
it("handles all empty params", () => {
|
|
83
|
+
const result = mergeSearchParams(new URLSearchParams(), new URLSearchParams(), new URLSearchParams());
|
|
84
|
+
expect(result.toString()).toBe("");
|
|
85
|
+
});
|
|
86
|
+
it("handles repeated overwrites", () => {
|
|
87
|
+
const base = new URLSearchParams("a=1&a=2");
|
|
88
|
+
const path = new URLSearchParams("a=3");
|
|
89
|
+
const url = new URLSearchParams("a=4&a=5");
|
|
90
|
+
const result = mergeSearchParams(base, path, url);
|
|
91
|
+
expect(result.toString()).toBe("a=4&a=5");
|
|
92
|
+
});
|
|
93
|
+
it("preserves plus signs in values", () => {
|
|
94
|
+
const base = new URLSearchParams("q=c++");
|
|
95
|
+
const result = mergeSearchParams(base, new URLSearchParams(), new URLSearchParams());
|
|
96
|
+
expect(result.toString()).toBe("q=c++");
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
describe("mergeUrls", () => {
|
|
101
|
+
it("combines simple URL and path", () => {
|
|
102
|
+
const result = mergeUrls("https://api.example.com", "/users");
|
|
103
|
+
expect(result).toBe("https://api.example.com/users");
|
|
104
|
+
});
|
|
105
|
+
it("handles query parameters from base URL", () => {
|
|
106
|
+
const result = mergeUrls("https://api.example.com?version=1", "/users");
|
|
107
|
+
expect(result).toBe("https://api.example.com/users?version=1");
|
|
108
|
+
});
|
|
109
|
+
it("handles query parameters from path", () => {
|
|
110
|
+
const result = mergeUrls("https://api.example.com", "/users?role=admin");
|
|
111
|
+
expect(result).toBe("https://api.example.com/users?role=admin");
|
|
112
|
+
});
|
|
113
|
+
it("handles query parameters from urlParams", () => {
|
|
114
|
+
const params = new URLSearchParams("token=123");
|
|
115
|
+
const result = mergeUrls("https://api.example.com", "/users", params);
|
|
116
|
+
expect(result).toBe("https://api.example.com/users?token=123");
|
|
117
|
+
});
|
|
118
|
+
it("merges query parameters from all sources", () => {
|
|
119
|
+
const params = new URLSearchParams("token=123");
|
|
120
|
+
const result = mergeUrls("https://api.example.com?version=1", "/users?role=admin", params);
|
|
121
|
+
expect(result).toBe("https://api.example.com/users?version=1&role=admin&token=123");
|
|
122
|
+
});
|
|
123
|
+
it("handles multiple values for same parameter", () => {
|
|
124
|
+
const params = new URLSearchParams([
|
|
125
|
+
["filter", "active"],
|
|
126
|
+
["filter", "verified"]
|
|
127
|
+
]);
|
|
128
|
+
const result = mergeUrls("https://api.example.com", "/users", params);
|
|
129
|
+
expect(result).toBe("https://api.example.com/users?filter=active&filter=verified");
|
|
130
|
+
});
|
|
131
|
+
it("later sources overwrite earlier ones", () => {
|
|
132
|
+
const params = new URLSearchParams("version=3");
|
|
133
|
+
const result = mergeUrls("https://api.example.com?version=1", "/users?version=2", params);
|
|
134
|
+
expect(result).toBe("https://api.example.com/users?version=3");
|
|
135
|
+
});
|
|
136
|
+
it("handles URLs with template variables", () => {
|
|
137
|
+
const result = mergeUrls("{protocol}://api.example.com", "/users");
|
|
138
|
+
expect(result).toBe("http://localhost:3000/{protocol}://api.example.com/users");
|
|
139
|
+
});
|
|
140
|
+
it("handles URLs with template variables and disableOriginPrefix", () => {
|
|
141
|
+
const result = mergeUrls("{protocol}://api.example.com", "/users", void 0, true);
|
|
142
|
+
expect(result).toBe("{protocol}://api.example.com/users");
|
|
143
|
+
});
|
|
144
|
+
it("handles relative URLs", () => {
|
|
145
|
+
const result = mergeUrls("/api", "/users");
|
|
146
|
+
expect(result).toBe("http://localhost:3000/api/users");
|
|
147
|
+
});
|
|
148
|
+
it("handles relative URLs with disableOriginPrefix", () => {
|
|
149
|
+
const result = mergeUrls("/api", "/users", void 0, true);
|
|
150
|
+
expect(result).toBe("/api/users");
|
|
151
|
+
});
|
|
152
|
+
describe("path handling", () => {
|
|
153
|
+
it("handles trailing slashes in base URL", () => {
|
|
154
|
+
const result = mergeUrls("https://api.example.com/", "/users");
|
|
155
|
+
expect(result).toBe("https://api.example.com/users");
|
|
156
|
+
});
|
|
157
|
+
it("handles leading slashes in path", () => {
|
|
158
|
+
const result = mergeUrls("https://api.example.com", "users");
|
|
159
|
+
expect(result).toBe("https://api.example.com/users");
|
|
160
|
+
});
|
|
161
|
+
it("handles both trailing and leading slashes", () => {
|
|
162
|
+
const result = mergeUrls("https://api.example.com/", "/users/");
|
|
163
|
+
expect(result).toBe("https://api.example.com/users/");
|
|
164
|
+
});
|
|
165
|
+
it("handles empty path", () => {
|
|
166
|
+
const result = mergeUrls("https://api.example.com", "");
|
|
167
|
+
expect(result).toBe("https://api.example.com");
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
describe("query parameter handling", () => {
|
|
171
|
+
it("preserves parameter order", () => {
|
|
172
|
+
const params = new URLSearchParams([
|
|
173
|
+
["c", "3"],
|
|
174
|
+
["d", "4"]
|
|
175
|
+
]);
|
|
176
|
+
const result = mergeUrls("https://api.example.com?a=1", "/users?b=2", params);
|
|
177
|
+
expect(result).toBe("https://api.example.com/users?a=1&b=2&c=3&d=4");
|
|
178
|
+
});
|
|
179
|
+
it("handles special characters in parameters", () => {
|
|
180
|
+
const params = new URLSearchParams([["q", "hello world&special=true"]]);
|
|
181
|
+
const result = mergeUrls("https://api.example.com", "/search", params);
|
|
182
|
+
expect(result).toBe("https://api.example.com/search?q=hello+world%26special%3Dtrue");
|
|
183
|
+
});
|
|
184
|
+
it("handles empty parameters", () => {
|
|
185
|
+
const params = new URLSearchParams("empty=");
|
|
186
|
+
const result = mergeUrls("https://api.example.com", "/users", params);
|
|
187
|
+
expect(result).toBe("https://api.example.com/users?empty=");
|
|
188
|
+
});
|
|
189
|
+
it("handles null or undefined parameters", () => {
|
|
190
|
+
const params = new URLSearchParams([
|
|
191
|
+
["null", "null"],
|
|
192
|
+
["undefined", "undefined"]
|
|
193
|
+
]);
|
|
194
|
+
const result = mergeUrls("https://api.example.com", "/users", params);
|
|
195
|
+
expect(result).toBe("https://api.example.com/users?null=null&undefined=undefined");
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
describe("edge cases", () => {
|
|
199
|
+
it("handles invalid URLs gracefully", () => {
|
|
200
|
+
const result = mergeUrls("not-a-url", "/path");
|
|
201
|
+
expect(result).toBe("http://localhost:3000/not-a-url/path");
|
|
202
|
+
});
|
|
203
|
+
it("handles invalid URLs with disableOriginPrefix", () => {
|
|
204
|
+
const result = mergeUrls("not-a-url", "/path", void 0, true);
|
|
205
|
+
expect(result).toBe("not-a-url/path");
|
|
206
|
+
});
|
|
207
|
+
it("handles URLs with authentication", () => {
|
|
208
|
+
const result = mergeUrls("https://user:pass@api.example.com", "/users");
|
|
209
|
+
expect(result).toBe("https://user:pass@api.example.com/users");
|
|
210
|
+
});
|
|
211
|
+
it("handles URLs with ports", () => {
|
|
212
|
+
const result = mergeUrls("https://api.example.com:8080", "/users");
|
|
213
|
+
expect(result).toBe("https://api.example.com:8080/users");
|
|
214
|
+
});
|
|
215
|
+
it("handles complex URLs", () => {
|
|
216
|
+
const params = new URLSearchParams("token=123");
|
|
217
|
+
const result = mergeUrls("https://user:pass@api.example.com:8080?version=1", "/users?role=admin", params);
|
|
218
|
+
expect(result).toBe("https://user:pass@api.example.com:8080/users?version=1&role=admin&token=123");
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
describe("error handling", () => {
|
|
222
|
+
it("handles empty base url", () => {
|
|
223
|
+
const result = mergeUrls("", "/users");
|
|
224
|
+
expect(result).toBe("/users");
|
|
225
|
+
});
|
|
226
|
+
it("handles undefined urlParams", () => {
|
|
227
|
+
const result = mergeUrls("https://api.example.com", "/users", void 0);
|
|
228
|
+
expect(result).toBe("https://api.example.com/users");
|
|
229
|
+
});
|
|
230
|
+
it("handles malformed URLs gracefully", () => {
|
|
231
|
+
const result = mergeUrls("http://{bad-url}", "/users");
|
|
232
|
+
expect(result).toBe("http://{bad-url}/users");
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
describe("combineUrlAndPath", () => {
|
|
237
|
+
describe("basic path joining", () => {
|
|
238
|
+
it("combines base and path with single slash", () => {
|
|
239
|
+
expect(combineUrlAndPath("http://example.com", "api")).toBe("http://example.com/api");
|
|
240
|
+
});
|
|
241
|
+
it("returns base when paths are identical", () => {
|
|
242
|
+
expect(combineUrlAndPath("http://example.com", "http://example.com")).toBe("http://example.com");
|
|
243
|
+
});
|
|
244
|
+
it("returns base when path is empty", () => {
|
|
245
|
+
expect(combineUrlAndPath("http://example.com", "")).toBe("http://example.com");
|
|
246
|
+
});
|
|
247
|
+
it("returns base when path is undefined", () => {
|
|
248
|
+
expect(combineUrlAndPath("http://example.com", void 0)).toBe("http://example.com");
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
describe("slash handling", () => {
|
|
252
|
+
it("removes trailing slash from base", () => {
|
|
253
|
+
expect(combineUrlAndPath("http://example.com/", "api")).toBe("http://example.com/api");
|
|
254
|
+
});
|
|
255
|
+
it("removes leading slash from path", () => {
|
|
256
|
+
expect(combineUrlAndPath("http://example.com", "/api")).toBe("http://example.com/api");
|
|
257
|
+
});
|
|
258
|
+
it("handles both trailing and leading slashes", () => {
|
|
259
|
+
expect(combineUrlAndPath("http://example.com/", "/api")).toBe("http://example.com/api");
|
|
260
|
+
});
|
|
261
|
+
it("removes multiple trailing slashes", () => {
|
|
262
|
+
expect(combineUrlAndPath("http://example.com///", "api")).toBe("http://example.com/api");
|
|
263
|
+
});
|
|
264
|
+
it("removes multiple leading slashes", () => {
|
|
265
|
+
expect(combineUrlAndPath("http://example.com", "///api")).toBe("http://example.com/api");
|
|
266
|
+
});
|
|
267
|
+
it("handles multiple slashes in both base and path", () => {
|
|
268
|
+
expect(combineUrlAndPath("http://example.com///", "///api")).toBe("http://example.com/api");
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
describe("path segments", () => {
|
|
272
|
+
it("preserves multiple path segments", () => {
|
|
273
|
+
expect(combineUrlAndPath("http://example.com", "api/v1/users")).toBe("http://example.com/api/v1/users");
|
|
274
|
+
});
|
|
275
|
+
it("preserves query parameters in base", () => {
|
|
276
|
+
expect(combineUrlAndPath("http://example.com?version=1", "api")).toBe("http://example.com?version=1/api");
|
|
277
|
+
});
|
|
278
|
+
it("preserves query parameters in path", () => {
|
|
279
|
+
expect(combineUrlAndPath("http://example.com", "api?version=1")).toBe("http://example.com/api?version=1");
|
|
280
|
+
});
|
|
281
|
+
it("preserves hash fragments", () => {
|
|
282
|
+
expect(combineUrlAndPath("http://example.com#section", "api")).toBe("http://example.com#section/api");
|
|
283
|
+
});
|
|
284
|
+
});
|
|
285
|
+
describe("special cases", () => {
|
|
286
|
+
it("handles relative base paths", () => {
|
|
287
|
+
expect(combineUrlAndPath("./base", "api")).toBe("./base/api");
|
|
288
|
+
});
|
|
289
|
+
it("handles parent directory references", () => {
|
|
290
|
+
expect(combineUrlAndPath("../base", "api")).toBe("../base/api");
|
|
291
|
+
});
|
|
292
|
+
it("handles absolute paths", () => {
|
|
293
|
+
expect(combineUrlAndPath("/base", "api")).toBe("/base/api");
|
|
294
|
+
});
|
|
295
|
+
it("removes extra spaces", () => {
|
|
296
|
+
expect(combineUrlAndPath("http://example.com ", " api ")).toBe("http://example.com/api");
|
|
297
|
+
});
|
|
298
|
+
it("handles URLs with ports", () => {
|
|
299
|
+
expect(combineUrlAndPath("http://example.com:8080", "api")).toBe("http://example.com:8080/api");
|
|
300
|
+
});
|
|
301
|
+
it("handles URLs with authentication", () => {
|
|
302
|
+
expect(combineUrlAndPath("http://user:pass@example.com", "api")).toBe("http://user:pass@example.com/api");
|
|
303
|
+
});
|
|
304
|
+
});
|
|
305
|
+
describe("template variables", () => {
|
|
306
|
+
it("preserves variables in base", () => {
|
|
307
|
+
expect(combineUrlAndPath("{protocol}://example.com", "api")).toBe("{protocol}://example.com/api");
|
|
308
|
+
});
|
|
309
|
+
it("preserves variables in path", () => {
|
|
310
|
+
expect(combineUrlAndPath("http://example.com", "{version}/api")).toBe("http://example.com/{version}/api");
|
|
311
|
+
});
|
|
312
|
+
it("preserves variables in both", () => {
|
|
313
|
+
expect(combineUrlAndPath("{host}/base", "{version}/api")).toBe("{host}/base/{version}/api");
|
|
314
|
+
});
|
|
315
|
+
});
|
|
316
|
+
describe("edge cases", () => {
|
|
317
|
+
it("handles empty base", () => {
|
|
318
|
+
expect(combineUrlAndPath("", "api")).toBe("api");
|
|
319
|
+
});
|
|
320
|
+
it("handles no base url", () => {
|
|
321
|
+
expect(combineUrlAndPath("", "https://example.com/api")).toBe("https://example.com/api");
|
|
322
|
+
});
|
|
323
|
+
it("handles both empty strings", () => {
|
|
324
|
+
expect(combineUrlAndPath("", "")).toBe("");
|
|
325
|
+
});
|
|
326
|
+
it("handles root paths", () => {
|
|
327
|
+
expect(combineUrlAndPath("http://example.com", "/")).toBe("http://example.com/");
|
|
328
|
+
});
|
|
329
|
+
it("handles special characters in paths", () => {
|
|
330
|
+
expect(combineUrlAndPath("http://example.com", "path with spaces")).toBe("http://example.com/path with spaces");
|
|
331
|
+
});
|
|
332
|
+
it("preserves URL encoded characters", () => {
|
|
333
|
+
expect(combineUrlAndPath("http://example.com", "path%20with%20spaces")).toBe(
|
|
334
|
+
"http://example.com/path%20with%20spaces"
|
|
335
|
+
);
|
|
336
|
+
});
|
|
337
|
+
});
|
|
338
|
+
});
|
|
339
|
+
//# sourceMappingURL=merge-urls.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/helpers/merge-urls.test.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * @vitest-environment jsdom\n */\nimport { describe, expect, it } from 'vitest'\n\nimport { combineUrlAndPath, mergeSearchParams, mergeUrls } from './merge-urls'\n\ndescribe('mergeSearchParams', () => {\n it('merges basic params from different sources', () => {\n const base = new URLSearchParams('a=1&b=2')\n const path = new URLSearchParams('c=3')\n const url = new URLSearchParams('d=4')\n\n const result = mergeSearchParams(base, path, url)\n expect(result.toString()).toBe('a=1&b=2&c=3&d=4')\n })\n\n it('later sources overwrite earlier ones completely', () => {\n const base = new URLSearchParams('a=1&b=2')\n const path = new URLSearchParams('b=3')\n const url = new URLSearchParams('b=4')\n\n const result = mergeSearchParams(base, path, url)\n expect(result.toString()).toBe('a=1&b=4')\n })\n\n it('preserves multiple values from the same source', () => {\n const base = new URLSearchParams('a=1&a=2')\n const path = new URLSearchParams('b=3&b=4')\n const url = new URLSearchParams('c=5&c=6')\n\n const result = mergeSearchParams(base, path, url)\n expect(result.toString()).toBe('a=1&a=2&b=3&b=4&c=5&c=6')\n })\n\n it('overwrites multiple values from earlier sources', () => {\n const base = new URLSearchParams('a=1&a=2')\n const path = new URLSearchParams('a=3&a=4')\n const url = new URLSearchParams()\n\n const result = mergeSearchParams(base, path, url)\n expect(result.toString()).toBe('a=3&a=4')\n })\n\n it('handles empty params', () => {\n const base = new URLSearchParams()\n const path = new URLSearchParams('a=1')\n const url = new URLSearchParams()\n\n const result = mergeSearchParams(base, path, url)\n expect(result.toString()).toBe('a=1')\n })\n\n it('handles special characters correctly', () => {\n const base = new URLSearchParams('q=hello world')\n const path = new URLSearchParams('filter=type:123')\n const url = new URLSearchParams('special=@#$%')\n\n const result = mergeSearchParams(base, path, url)\n expect(decodeURIComponent(result.toString())).toBe('q=hello+world&filter=type:123&special=@#$%')\n })\n\n it('handles complex overwriting scenarios', () => {\n const base = new URLSearchParams('a=1&a=2&b=1&c=1')\n const path = new URLSearchParams('b=2&b=3&c=2')\n const url = new URLSearchParams('c=3&c=4')\n\n const result = mergeSearchParams(base, path, url)\n expect(result.toString()).toBe('a=1&a=2&b=2&b=3&c=3&c=4')\n })\n\n it('maintains order of parameters', () => {\n const base = new URLSearchParams('first=1&second=2')\n const path = new URLSearchParams('third=3')\n const url = new URLSearchParams('fourth=4')\n\n const result = mergeSearchParams(base, path, url)\n expect(result.toString()).toBe('first=1&second=2&third=3&fourth=4')\n })\n\n it('handles boolean and numeric values', () => {\n const base = new URLSearchParams('bool=true&num=123')\n const path = new URLSearchParams('bool=false')\n const url = new URLSearchParams('num=456')\n\n const result = mergeSearchParams(base, path, url)\n expect(result.toString()).toBe('bool=false&num=456')\n })\n\n it('handles null and undefined values', () => {\n const base = new URLSearchParams('a=null&b=undefined')\n const path = new URLSearchParams('a=value')\n const url = new URLSearchParams()\n\n const result = mergeSearchParams(base, path, url)\n expect(result.toString()).toBe('a=value&b=undefined')\n })\n\n it('handles empty string values', () => {\n const base = new URLSearchParams('a=&b=value')\n const path = new URLSearchParams('b=')\n const url = new URLSearchParams()\n\n const result = mergeSearchParams(base, path, url)\n expect(result.toString()).toBe('a=&b=')\n })\n\n describe('edge cases', () => {\n it('handles all empty params', () => {\n const result = mergeSearchParams(new URLSearchParams(), new URLSearchParams(), new URLSearchParams())\n expect(result.toString()).toBe('')\n })\n\n it('handles repeated overwrites', () => {\n const base = new URLSearchParams('a=1&a=2')\n const path = new URLSearchParams('a=3')\n const url = new URLSearchParams('a=4&a=5')\n\n const result = mergeSearchParams(base, path, url)\n expect(result.toString()).toBe('a=4&a=5')\n })\n\n it('preserves plus signs in values', () => {\n const base = new URLSearchParams('q=c++')\n const result = mergeSearchParams(base, new URLSearchParams(), new URLSearchParams())\n expect(result.toString()).toBe('q=c++')\n })\n })\n})\n\ndescribe('mergeUrls', () => {\n it('combines simple URL and path', () => {\n const result = mergeUrls('https://api.example.com', '/users')\n expect(result).toBe('https://api.example.com/users')\n })\n\n it('handles query parameters from base URL', () => {\n const result = mergeUrls('https://api.example.com?version=1', '/users')\n expect(result).toBe('https://api.example.com/users?version=1')\n })\n\n it('handles query parameters from path', () => {\n const result = mergeUrls('https://api.example.com', '/users?role=admin')\n expect(result).toBe('https://api.example.com/users?role=admin')\n })\n\n it('handles query parameters from urlParams', () => {\n const params = new URLSearchParams('token=123')\n const result = mergeUrls('https://api.example.com', '/users', params)\n expect(result).toBe('https://api.example.com/users?token=123')\n })\n\n it('merges query parameters from all sources', () => {\n const params = new URLSearchParams('token=123')\n const result = mergeUrls('https://api.example.com?version=1', '/users?role=admin', params)\n expect(result).toBe('https://api.example.com/users?version=1&role=admin&token=123')\n })\n\n it('handles multiple values for same parameter', () => {\n const params = new URLSearchParams([\n ['filter', 'active'],\n ['filter', 'verified'],\n ])\n const result = mergeUrls('https://api.example.com', '/users', params)\n expect(result).toBe('https://api.example.com/users?filter=active&filter=verified')\n })\n\n it('later sources overwrite earlier ones', () => {\n const params = new URLSearchParams('version=3')\n const result = mergeUrls('https://api.example.com?version=1', '/users?version=2', params)\n expect(result).toBe('https://api.example.com/users?version=3')\n })\n\n it('handles URLs with template variables', () => {\n const result = mergeUrls('{protocol}://api.example.com', '/users')\n expect(result).toBe('http://localhost:3000/{protocol}://api.example.com/users')\n })\n\n it('handles URLs with template variables and disableOriginPrefix', () => {\n const result = mergeUrls('{protocol}://api.example.com', '/users', undefined, true)\n expect(result).toBe('{protocol}://api.example.com/users')\n })\n\n it('handles relative URLs', () => {\n const result = mergeUrls('/api', '/users')\n expect(result).toBe('http://localhost:3000/api/users')\n })\n it('handles relative URLs with disableOriginPrefix', () => {\n const result = mergeUrls('/api', '/users', undefined, true)\n expect(result).toBe('/api/users')\n })\n\n describe('path handling', () => {\n it('handles trailing slashes in base URL', () => {\n const result = mergeUrls('https://api.example.com/', '/users')\n expect(result).toBe('https://api.example.com/users')\n })\n\n it('handles leading slashes in path', () => {\n const result = mergeUrls('https://api.example.com', 'users')\n expect(result).toBe('https://api.example.com/users')\n })\n\n it('handles both trailing and leading slashes', () => {\n const result = mergeUrls('https://api.example.com/', '/users/')\n expect(result).toBe('https://api.example.com/users/')\n })\n\n it('handles empty path', () => {\n const result = mergeUrls('https://api.example.com', '')\n expect(result).toBe('https://api.example.com')\n })\n })\n\n describe('query parameter handling', () => {\n it('preserves parameter order', () => {\n const params = new URLSearchParams([\n ['c', '3'],\n ['d', '4'],\n ])\n const result = mergeUrls('https://api.example.com?a=1', '/users?b=2', params)\n expect(result).toBe('https://api.example.com/users?a=1&b=2&c=3&d=4')\n })\n\n it('handles special characters in parameters', () => {\n const params = new URLSearchParams([['q', 'hello world&special=true']])\n const result = mergeUrls('https://api.example.com', '/search', params)\n expect(result).toBe('https://api.example.com/search?q=hello+world%26special%3Dtrue')\n })\n\n it('handles empty parameters', () => {\n const params = new URLSearchParams('empty=')\n const result = mergeUrls('https://api.example.com', '/users', params)\n expect(result).toBe('https://api.example.com/users?empty=')\n })\n\n it('handles null or undefined parameters', () => {\n const params = new URLSearchParams([\n ['null', 'null'],\n ['undefined', 'undefined'],\n ])\n const result = mergeUrls('https://api.example.com', '/users', params)\n expect(result).toBe('https://api.example.com/users?null=null&undefined=undefined')\n })\n })\n\n describe('edge cases', () => {\n it('handles invalid URLs gracefully', () => {\n const result = mergeUrls('not-a-url', '/path')\n expect(result).toBe('http://localhost:3000/not-a-url/path')\n })\n\n it('handles invalid URLs with disableOriginPrefix', () => {\n const result = mergeUrls('not-a-url', '/path', undefined, true)\n expect(result).toBe('not-a-url/path')\n })\n\n it('handles URLs with authentication', () => {\n const result = mergeUrls('https://user:pass@api.example.com', '/users')\n expect(result).toBe('https://user:pass@api.example.com/users')\n })\n\n it('handles URLs with ports', () => {\n const result = mergeUrls('https://api.example.com:8080', '/users')\n expect(result).toBe('https://api.example.com:8080/users')\n })\n\n it('handles complex URLs', () => {\n const params = new URLSearchParams('token=123')\n const result = mergeUrls('https://user:pass@api.example.com:8080?version=1', '/users?role=admin', params)\n expect(result).toBe('https://user:pass@api.example.com:8080/users?version=1&role=admin&token=123')\n })\n })\n\n describe('error handling', () => {\n it('handles empty base url', () => {\n const result = mergeUrls('', '/users')\n expect(result).toBe('/users')\n })\n\n it('handles undefined urlParams', () => {\n const result = mergeUrls('https://api.example.com', '/users', undefined)\n expect(result).toBe('https://api.example.com/users')\n })\n\n it('handles malformed URLs gracefully', () => {\n const result = mergeUrls('http://{bad-url}', '/users')\n expect(result).toBe('http://{bad-url}/users')\n })\n })\n})\n\ndescribe('combineUrlAndPath', () => {\n describe('basic path joining', () => {\n it('combines base and path with single slash', () => {\n expect(combineUrlAndPath('http://example.com', 'api')).toBe('http://example.com/api')\n })\n\n it('returns base when paths are identical', () => {\n expect(combineUrlAndPath('http://example.com', 'http://example.com')).toBe('http://example.com')\n })\n\n it('returns base when path is empty', () => {\n expect(combineUrlAndPath('http://example.com', '')).toBe('http://example.com')\n })\n\n it('returns base when path is undefined', () => {\n expect(combineUrlAndPath('http://example.com', undefined as unknown as string)).toBe('http://example.com')\n })\n })\n\n describe('slash handling', () => {\n it('removes trailing slash from base', () => {\n expect(combineUrlAndPath('http://example.com/', 'api')).toBe('http://example.com/api')\n })\n\n it('removes leading slash from path', () => {\n expect(combineUrlAndPath('http://example.com', '/api')).toBe('http://example.com/api')\n })\n\n it('handles both trailing and leading slashes', () => {\n expect(combineUrlAndPath('http://example.com/', '/api')).toBe('http://example.com/api')\n })\n\n it('removes multiple trailing slashes', () => {\n expect(combineUrlAndPath('http://example.com///', 'api')).toBe('http://example.com/api')\n })\n\n it('removes multiple leading slashes', () => {\n expect(combineUrlAndPath('http://example.com', '///api')).toBe('http://example.com/api')\n })\n\n it('handles multiple slashes in both base and path', () => {\n expect(combineUrlAndPath('http://example.com///', '///api')).toBe('http://example.com/api')\n })\n })\n\n describe('path segments', () => {\n it('preserves multiple path segments', () => {\n expect(combineUrlAndPath('http://example.com', 'api/v1/users')).toBe('http://example.com/api/v1/users')\n })\n\n it('preserves query parameters in base', () => {\n expect(combineUrlAndPath('http://example.com?version=1', 'api')).toBe('http://example.com?version=1/api')\n })\n\n it('preserves query parameters in path', () => {\n expect(combineUrlAndPath('http://example.com', 'api?version=1')).toBe('http://example.com/api?version=1')\n })\n\n it('preserves hash fragments', () => {\n expect(combineUrlAndPath('http://example.com#section', 'api')).toBe('http://example.com#section/api')\n })\n })\n\n describe('special cases', () => {\n it('handles relative base paths', () => {\n expect(combineUrlAndPath('./base', 'api')).toBe('./base/api')\n })\n\n it('handles parent directory references', () => {\n expect(combineUrlAndPath('../base', 'api')).toBe('../base/api')\n })\n\n it('handles absolute paths', () => {\n expect(combineUrlAndPath('/base', 'api')).toBe('/base/api')\n })\n\n it('removes extra spaces', () => {\n expect(combineUrlAndPath('http://example.com ', ' api ')).toBe('http://example.com/api')\n })\n\n it('handles URLs with ports', () => {\n expect(combineUrlAndPath('http://example.com:8080', 'api')).toBe('http://example.com:8080/api')\n })\n\n it('handles URLs with authentication', () => {\n expect(combineUrlAndPath('http://user:pass@example.com', 'api')).toBe('http://user:pass@example.com/api')\n })\n })\n\n describe('template variables', () => {\n it('preserves variables in base', () => {\n expect(combineUrlAndPath('{protocol}://example.com', 'api')).toBe('{protocol}://example.com/api')\n })\n\n it('preserves variables in path', () => {\n expect(combineUrlAndPath('http://example.com', '{version}/api')).toBe('http://example.com/{version}/api')\n })\n\n it('preserves variables in both', () => {\n expect(combineUrlAndPath('{host}/base', '{version}/api')).toBe('{host}/base/{version}/api')\n })\n })\n\n describe('edge cases', () => {\n it('handles empty base', () => {\n expect(combineUrlAndPath('', 'api')).toBe('api')\n })\n\n it('handles no base url', () => {\n expect(combineUrlAndPath('', 'https://example.com/api')).toBe('https://example.com/api')\n })\n\n it('handles both empty strings', () => {\n expect(combineUrlAndPath('', '')).toBe('')\n })\n\n it('handles root paths', () => {\n expect(combineUrlAndPath('http://example.com', '/')).toBe('http://example.com/')\n })\n\n it('handles special characters in paths', () => {\n expect(combineUrlAndPath('http://example.com', 'path with spaces')).toBe('http://example.com/path with spaces')\n })\n\n it('preserves URL encoded characters', () => {\n expect(combineUrlAndPath('http://example.com', 'path%20with%20spaces')).toBe(\n 'http://example.com/path%20with%20spaces',\n )\n })\n })\n})\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,34 +1,24 @@
|
|
|
1
|
-
import { normalizeMimeType } from
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Remove charset from content types
|
|
5
|
-
*
|
|
6
|
-
* Example: `application/json; charset=utf-8` -> `application/json`
|
|
7
|
-
*/
|
|
1
|
+
import { normalizeMimeType } from "./normalize-mime-type.js";
|
|
8
2
|
function normalizeMimeTypeObject(content) {
|
|
9
|
-
|
|
10
|
-
|
|
3
|
+
if (!content) {
|
|
4
|
+
return content;
|
|
5
|
+
}
|
|
6
|
+
const newContent = {
|
|
7
|
+
...content
|
|
8
|
+
};
|
|
9
|
+
Object.keys(newContent).forEach((key) => {
|
|
10
|
+
const newKey = normalizeMimeType(key);
|
|
11
|
+
if (newKey === void 0) {
|
|
12
|
+
return;
|
|
11
13
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
// Output: 'application/json'
|
|
19
|
-
const newKey = normalizeMimeType(key);
|
|
20
|
-
// We need a new key to replace the old one
|
|
21
|
-
if (newKey === undefined) {
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
// Move the content
|
|
25
|
-
newContent[newKey] = newContent[key];
|
|
26
|
-
// Remove the old key
|
|
27
|
-
if (key !== newKey) {
|
|
28
|
-
delete newContent[key];
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
return newContent;
|
|
14
|
+
newContent[newKey] = newContent[key];
|
|
15
|
+
if (key !== newKey) {
|
|
16
|
+
delete newContent[key];
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
return newContent;
|
|
32
20
|
}
|
|
33
|
-
|
|
34
|
-
|
|
21
|
+
export {
|
|
22
|
+
normalizeMimeTypeObject
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=normalize-mime-type-object.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/helpers/normalize-mime-type-object.ts"],
|
|
4
|
+
"sourcesContent": ["import type { ContentType } from '@scalar/types/legacy'\n\nimport { normalizeMimeType } from './normalize-mime-type'\n\n/**\n * Remove charset from content types\n *\n * Example: `application/json; charset=utf-8` -> `application/json`\n */\nexport function normalizeMimeTypeObject(content?: Record<ContentType, any>) {\n if (!content) {\n return content\n }\n\n // Clone the object\n const newContent = {\n ...content,\n }\n\n Object.keys(newContent).forEach((key) => {\n // Input: 'application/problem+json; charset=utf-8'\n // Output: 'application/json'\n const newKey = normalizeMimeType(key)\n\n // We need a new key to replace the old one\n if (newKey === undefined) {\n return\n }\n\n // Move the content\n newContent[newKey] = newContent[key as ContentType]\n\n // Remove the old key\n if (key !== newKey) {\n delete newContent[key as ContentType]\n }\n })\n\n return newContent\n}\n"],
|
|
5
|
+
"mappings": "AAEA,SAAS,yBAAyB;AAO3B,SAAS,wBAAwB,SAAoC;AAC1E,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AAGA,QAAM,aAAa;AAAA,IACjB,GAAG;AAAA,EACL;AAEA,SAAO,KAAK,UAAU,EAAE,QAAQ,CAAC,QAAQ;AAGvC,UAAM,SAAS,kBAAkB,GAAG;AAGpC,QAAI,WAAW,QAAW;AACxB;AAAA,IACF;AAGA,eAAW,MAAM,IAAI,WAAW,GAAkB;AAGlD,QAAI,QAAQ,QAAQ;AAClB,aAAO,WAAW,GAAkB;AAAA,IACtC;AAAA,EACF,CAAC;AAED,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { normalizeMimeTypeObject } from "./normalize-mime-type-object.js";
|
|
3
|
+
describe("normalizeMimeTypeObject", () => {
|
|
4
|
+
it("removes charset", async () => {
|
|
5
|
+
const content = {
|
|
6
|
+
"application/json; charset=utf-8": {}
|
|
7
|
+
};
|
|
8
|
+
expect(normalizeMimeTypeObject(content)).toMatchObject({
|
|
9
|
+
"application/json": {}
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
it("removes semicolon", async () => {
|
|
13
|
+
const content = {
|
|
14
|
+
"application/json;": {}
|
|
15
|
+
};
|
|
16
|
+
expect(normalizeMimeTypeObject(content)).toMatchObject({
|
|
17
|
+
"application/json": {}
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
it("removes whitespace", async () => {
|
|
21
|
+
const content = {
|
|
22
|
+
" application/json ": {}
|
|
23
|
+
};
|
|
24
|
+
expect(normalizeMimeTypeObject(content)).toMatchObject({
|
|
25
|
+
"application/json": {}
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
it("removes mimetype variants", async () => {
|
|
29
|
+
const content = {
|
|
30
|
+
"application/problem+json": {}
|
|
31
|
+
};
|
|
32
|
+
expect(normalizeMimeTypeObject(content)).toMatchObject({
|
|
33
|
+
"application/json": {}
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
it("removes mimetype variants with special characters", async () => {
|
|
37
|
+
const content = {
|
|
38
|
+
"application/problem+json": {}
|
|
39
|
+
};
|
|
40
|
+
expect(normalizeMimeTypeObject(content)).toMatchObject({
|
|
41
|
+
"application/json": {}
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
it("removes all the clutter", async () => {
|
|
45
|
+
const content = {
|
|
46
|
+
"application/problem-foobar+json; charset=utf-8": {}
|
|
47
|
+
};
|
|
48
|
+
expect(normalizeMimeTypeObject(content)).toMatchObject({
|
|
49
|
+
"application/json": {}
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
//# sourceMappingURL=normalize-mime-type-object.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/helpers/normalize-mime-type-object.test.ts"],
|
|
4
|
+
"sourcesContent": ["import { describe, expect, it } from 'vitest'\n\nimport { normalizeMimeTypeObject } from './normalize-mime-type-object'\n\ndescribe('normalizeMimeTypeObject', () => {\n it('removes charset', async () => {\n const content = {\n 'application/json; charset=utf-8': {},\n }\n\n expect(normalizeMimeTypeObject(content)).toMatchObject({\n 'application/json': {},\n })\n })\n\n it('removes semicolon', async () => {\n const content = {\n 'application/json;': {},\n }\n\n expect(normalizeMimeTypeObject(content)).toMatchObject({\n 'application/json': {},\n })\n })\n\n it('removes whitespace', async () => {\n const content = {\n ' application/json ': {},\n }\n\n expect(normalizeMimeTypeObject(content)).toMatchObject({\n 'application/json': {},\n })\n })\n\n it('removes mimetype variants', async () => {\n const content = {\n 'application/problem+json': {},\n }\n\n expect(normalizeMimeTypeObject(content)).toMatchObject({\n 'application/json': {},\n })\n })\n\n it('removes mimetype variants with special characters', async () => {\n const content = {\n 'application/problem+json': {},\n }\n\n expect(normalizeMimeTypeObject(content)).toMatchObject({\n 'application/json': {},\n })\n })\n\n it('removes all the clutter', async () => {\n const content = {\n 'application/problem-foobar+json; charset=utf-8': {},\n }\n\n expect(normalizeMimeTypeObject(content)).toMatchObject({\n 'application/json': {},\n })\n })\n})\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,UAAU,QAAQ,UAAU;AAErC,SAAS,+BAA+B;AAExC,SAAS,2BAA2B,MAAM;AACxC,KAAG,mBAAmB,YAAY;AAChC,UAAM,UAAU;AAAA,MACd,mCAAmC,CAAC;AAAA,IACtC;AAEA,WAAO,wBAAwB,OAAO,CAAC,EAAE,cAAc;AAAA,MACrD,oBAAoB,CAAC;AAAA,IACvB,CAAC;AAAA,EACH,CAAC;AAED,KAAG,qBAAqB,YAAY;AAClC,UAAM,UAAU;AAAA,MACd,qBAAqB,CAAC;AAAA,IACxB;AAEA,WAAO,wBAAwB,OAAO,CAAC,EAAE,cAAc;AAAA,MACrD,oBAAoB,CAAC;AAAA,IACvB,CAAC;AAAA,EACH,CAAC;AAED,KAAG,sBAAsB,YAAY;AACnC,UAAM,UAAU;AAAA,MACd,sBAAsB,CAAC;AAAA,IACzB;AAEA,WAAO,wBAAwB,OAAO,CAAC,EAAE,cAAc;AAAA,MACrD,oBAAoB,CAAC;AAAA,IACvB,CAAC;AAAA,EACH,CAAC;AAED,KAAG,6BAA6B,YAAY;AAC1C,UAAM,UAAU;AAAA,MACd,4BAA4B,CAAC;AAAA,IAC/B;AAEA,WAAO,wBAAwB,OAAO,CAAC,EAAE,cAAc;AAAA,MACrD,oBAAoB,CAAC;AAAA,IACvB,CAAC;AAAA,EACH,CAAC;AAED,KAAG,qDAAqD,YAAY;AAClE,UAAM,UAAU;AAAA,MACd,4BAA4B,CAAC;AAAA,IAC/B;AAEA,WAAO,wBAAwB,OAAO,CAAC,EAAE,cAAc;AAAA,MACrD,oBAAoB,CAAC;AAAA,IACvB,CAAC;AAAA,EACH,CAAC;AAED,KAAG,2BAA2B,YAAY;AACxC,UAAM,UAAU;AAAA,MACd,kDAAkD,CAAC;AAAA,IACrD;AAEA,WAAO,wBAAwB,OAAO,CAAC,EAAE,cAAc;AAAA,MACrD,oBAAoB,CAAC;AAAA,IACvB,CAAC;AAAA,EACH,CAAC;AACH,CAAC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,20 +1,10 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Normalizes a MIME type to a standard format.
|
|
3
|
-
*
|
|
4
|
-
* Input: application/problem+json; charset=utf-8
|
|
5
|
-
* Output: application/json
|
|
6
|
-
*/
|
|
7
1
|
function normalizeMimeType(contentType) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
// Remove '; charset=utf-8'
|
|
13
|
-
.replace(/;.*$/, '')
|
|
14
|
-
// Remove 'problem+' but keep vendor-specific vnd and fhir mime types
|
|
15
|
-
.replace(/\/(?!.*vnd\.|fhir\+).*\+/, '/')
|
|
16
|
-
// Remove whitespace
|
|
17
|
-
.trim();
|
|
2
|
+
if (typeof contentType !== "string") {
|
|
3
|
+
return void 0;
|
|
4
|
+
}
|
|
5
|
+
return contentType.replace(/;.*$/, "").replace(/\/(?!.*vnd\.|fhir\+).*\+/, "/").trim();
|
|
18
6
|
}
|
|
19
|
-
|
|
20
|
-
|
|
7
|
+
export {
|
|
8
|
+
normalizeMimeType
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=normalize-mime-type.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/helpers/normalize-mime-type.ts"],
|
|
4
|
+
"sourcesContent": ["import type { ContentType } from '@scalar/types/legacy'\n\n/**\n * Normalizes a MIME type to a standard format.\n *\n * Input: application/problem+json; charset=utf-8\n * Output: application/json\n */\nexport function normalizeMimeType(contentType?: string) {\n if (typeof contentType !== 'string') {\n return undefined\n }\n\n return (\n contentType\n // Remove '; charset=utf-8'\n .replace(/;.*$/, '')\n // Remove 'problem+' but keep vendor-specific vnd and fhir mime types\n .replace(/\\/(?!.*vnd\\.|fhir\\+).*\\+/, '/')\n // Remove whitespace\n .trim() as ContentType\n )\n}\n"],
|
|
5
|
+
"mappings": "AAQO,SAAS,kBAAkB,aAAsB;AACtD,MAAI,OAAO,gBAAgB,UAAU;AACnC,WAAO;AAAA,EACT;AAEA,SACE,YAEG,QAAQ,QAAQ,EAAE,EAElB,QAAQ,4BAA4B,GAAG,EAEvC,KAAK;AAEZ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { normalizeMimeType } from "./normalize-mime-type.js";
|
|
3
|
+
describe("normalizeMimeType", () => {
|
|
4
|
+
it("removes charset", async () => {
|
|
5
|
+
const content = "application/json; charset=utf-8";
|
|
6
|
+
expect(normalizeMimeType(content)).toBe("application/json");
|
|
7
|
+
});
|
|
8
|
+
it("removes semicolon", async () => {
|
|
9
|
+
const content = "application/json;";
|
|
10
|
+
expect(normalizeMimeType(content)).toBe("application/json");
|
|
11
|
+
});
|
|
12
|
+
it("removes whitespace", async () => {
|
|
13
|
+
const content = " application/json ";
|
|
14
|
+
expect(normalizeMimeType(content)).toBe("application/json");
|
|
15
|
+
});
|
|
16
|
+
it("removes unsupported mimetype variants", async () => {
|
|
17
|
+
const content = "application/problem+json";
|
|
18
|
+
expect(normalizeMimeType(content)).toBe("application/json");
|
|
19
|
+
});
|
|
20
|
+
it("removes all the clutter", async () => {
|
|
21
|
+
const content = "application/problem-foobar+json; charset=utf-8";
|
|
22
|
+
expect(normalizeMimeType(content)).toBe("application/json");
|
|
23
|
+
});
|
|
24
|
+
it("keeps vendor specific mimetypes", async () => {
|
|
25
|
+
const content = "application/vnd.api+json";
|
|
26
|
+
expect(normalizeMimeType(content)).toBe("application/vnd.api+json");
|
|
27
|
+
});
|
|
28
|
+
it("removes all the clutter but keeps vendor specific part", async () => {
|
|
29
|
+
const content = "application/fhir+json; charset=utf-8";
|
|
30
|
+
expect(normalizeMimeType(content)).toBe("application/fhir+json");
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
//# sourceMappingURL=normalize-mime-type.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/helpers/normalize-mime-type.test.ts"],
|
|
4
|
+
"sourcesContent": ["import { describe, expect, it } from 'vitest'\n\nimport { normalizeMimeType } from './normalize-mime-type'\n\ndescribe('normalizeMimeType', () => {\n it('removes charset', async () => {\n const content = 'application/json; charset=utf-8'\n\n expect(normalizeMimeType(content)).toBe('application/json')\n })\n\n it('removes semicolon', async () => {\n const content = 'application/json;'\n\n expect(normalizeMimeType(content)).toBe('application/json')\n })\n\n it('removes whitespace', async () => {\n const content = ' application/json '\n\n expect(normalizeMimeType(content)).toBe('application/json')\n })\n\n it('removes unsupported mimetype variants', async () => {\n const content = 'application/problem+json'\n\n expect(normalizeMimeType(content)).toBe('application/json')\n })\n\n it('removes all the clutter', async () => {\n const content = 'application/problem-foobar+json; charset=utf-8'\n\n expect(normalizeMimeType(content)).toBe('application/json')\n })\n\n it('keeps vendor specific mimetypes', async () => {\n const content = 'application/vnd.api+json'\n\n expect(normalizeMimeType(content)).toBe('application/vnd.api+json')\n })\n\n it('removes all the clutter but keeps vendor specific part', async () => {\n const content = 'application/fhir+json; charset=utf-8'\n\n expect(normalizeMimeType(content)).toBe('application/fhir+json')\n })\n})\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,UAAU,QAAQ,UAAU;AAErC,SAAS,yBAAyB;AAElC,SAAS,qBAAqB,MAAM;AAClC,KAAG,mBAAmB,YAAY;AAChC,UAAM,UAAU;AAEhB,WAAO,kBAAkB,OAAO,CAAC,EAAE,KAAK,kBAAkB;AAAA,EAC5D,CAAC;AAED,KAAG,qBAAqB,YAAY;AAClC,UAAM,UAAU;AAEhB,WAAO,kBAAkB,OAAO,CAAC,EAAE,KAAK,kBAAkB;AAAA,EAC5D,CAAC;AAED,KAAG,sBAAsB,YAAY;AACnC,UAAM,UAAU;AAEhB,WAAO,kBAAkB,OAAO,CAAC,EAAE,KAAK,kBAAkB;AAAA,EAC5D,CAAC;AAED,KAAG,yCAAyC,YAAY;AACtD,UAAM,UAAU;AAEhB,WAAO,kBAAkB,OAAO,CAAC,EAAE,KAAK,kBAAkB;AAAA,EAC5D,CAAC;AAED,KAAG,2BAA2B,YAAY;AACxC,UAAM,UAAU;AAEhB,WAAO,kBAAkB,OAAO,CAAC,EAAE,KAAK,kBAAkB;AAAA,EAC5D,CAAC;AAED,KAAG,mCAAmC,YAAY;AAChD,UAAM,UAAU;AAEhB,WAAO,kBAAkB,OAAO,CAAC,EAAE,KAAK,0BAA0B;AAAA,EACpE,CAAC;AAED,KAAG,0DAA0D,YAAY;AACvE,UAAM,UAAU;AAEhB,WAAO,kBAAkB,OAAO,CAAC,EAAE,KAAK,uBAAuB;AAAA,EACjE,CAAC;AACH,CAAC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|