@suss/ir-core 0.34.0 → 0.34.1
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/dist/{chunk-WOXA5GBL.js → chunk-A46EUIKC.js} +301 -35
- package/dist/index.cjs +330 -42
- package/dist/index.d.cts +59 -11
- package/dist/index.d.ts +59 -11
- package/dist/index.js +27 -6
- package/dist/{schemas-CghZNwSE.d.cts → schemas-lfg8kvak.d.cts} +6 -0
- package/dist/{schemas-CghZNwSE.d.ts → schemas-lfg8kvak.d.ts} +6 -0
- package/dist/schemas.cjs +299 -37
- package/dist/schemas.d.cts +1 -1
- package/dist/schemas.d.ts +1 -1
- package/dist/schemas.js +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -54,7 +54,6 @@ __export(index_exports, {
|
|
|
54
54
|
boundaryKey: () => boundaryKey,
|
|
55
55
|
boundaryLabel: () => boundaryLabel,
|
|
56
56
|
boundaryNameString: () => boundaryNameString,
|
|
57
|
-
bucketRank: () => bucketRank,
|
|
58
57
|
bucketsMeet: () => bucketsMeet,
|
|
59
58
|
busIdentityKey: () => busIdentityKey,
|
|
60
59
|
busesAgree: () => busesAgree,
|
|
@@ -78,6 +77,7 @@ __export(index_exports, {
|
|
|
78
77
|
groundBinding: () => groundBinding,
|
|
79
78
|
groundedPairingKey: () => groundedPairingKey,
|
|
80
79
|
hasNameHole: () => hasNameHole,
|
|
80
|
+
hostCanBeOwn: () => hostCanBeOwn,
|
|
81
81
|
ioBinding: () => ioBinding,
|
|
82
82
|
ioIdentityKey: () => ioIdentityKey,
|
|
83
83
|
isGraphqlOperationBinding: () => isGraphqlOperationBinding,
|
|
@@ -98,7 +98,9 @@ __export(index_exports, {
|
|
|
98
98
|
namesNothing: () => namesNothing,
|
|
99
99
|
normalizePath: () => normalizePath,
|
|
100
100
|
normalizeRuleBoundary: () => normalizeRuleBoundary,
|
|
101
|
+
operationKey: () => operationKey,
|
|
101
102
|
packageExportBinding: () => packageExportBinding,
|
|
103
|
+
pairRank: () => pairRank,
|
|
102
104
|
pairingKey: () => pairingKey,
|
|
103
105
|
parseBoundaryName: () => parseBoundaryName,
|
|
104
106
|
parseChannel: () => parseChannel,
|
|
@@ -135,7 +137,8 @@ __export(index_exports, {
|
|
|
135
137
|
validateRule: () => validateRule,
|
|
136
138
|
withDefinitionsInlined: () => withDefinitionsInlined,
|
|
137
139
|
withRewrittenPaths: () => withRewrittenPaths,
|
|
138
|
-
withinScope: () => withinScope
|
|
140
|
+
withinScope: () => withinScope,
|
|
141
|
+
withoutOwnHost: () => withoutOwnHost
|
|
139
142
|
});
|
|
140
143
|
module.exports = __toCommonJS(index_exports);
|
|
141
144
|
|
|
@@ -655,6 +658,38 @@ function pathAfterOrigin(text) {
|
|
|
655
658
|
function statesAnOrigin(text) {
|
|
656
659
|
return SCHEME_ORIGIN.test(text) || PROTOCOL_RELATIVE_ORIGIN.test(text);
|
|
657
660
|
}
|
|
661
|
+
var PRIVATE_SUFFIXES = [
|
|
662
|
+
"local",
|
|
663
|
+
"internal",
|
|
664
|
+
"localhost",
|
|
665
|
+
"lan",
|
|
666
|
+
"home.arpa",
|
|
667
|
+
"svc",
|
|
668
|
+
"test",
|
|
669
|
+
"example",
|
|
670
|
+
"invalid",
|
|
671
|
+
"example.com",
|
|
672
|
+
"example.net",
|
|
673
|
+
"example.org"
|
|
674
|
+
];
|
|
675
|
+
var PRIVATE_IPV4 = /^(?:127\.|10\.|192\.168\.|169\.254\.|172\.(?:1[6-9]|2\d|3[01])\.|0\.0\.0\.0$)/;
|
|
676
|
+
function hostnameOf(host) {
|
|
677
|
+
const lower = host.toLowerCase();
|
|
678
|
+
const name = lower.startsWith("[") ? lower.slice(0, lower.indexOf("]") + 1) : lower.split(":")[0] ?? lower;
|
|
679
|
+
return name.replace(/\.$/, "");
|
|
680
|
+
}
|
|
681
|
+
function hostCanBeOwn(host) {
|
|
682
|
+
const name = hostnameOf(host);
|
|
683
|
+
if (name === "[::1]" || /^\[f[cd]/.test(name) || PRIVATE_IPV4.test(name)) {
|
|
684
|
+
return true;
|
|
685
|
+
}
|
|
686
|
+
if (!name.includes(".")) {
|
|
687
|
+
return true;
|
|
688
|
+
}
|
|
689
|
+
return PRIVATE_SUFFIXES.some(
|
|
690
|
+
(suffix) => name === suffix || name.endsWith(`.${suffix}`)
|
|
691
|
+
);
|
|
692
|
+
}
|
|
658
693
|
|
|
659
694
|
// src/semantics/pathPattern.ts
|
|
660
695
|
var HOLE_RANGE_SUFFIX = {
|
|
@@ -721,14 +756,18 @@ function shapedItem(segment) {
|
|
|
721
756
|
return ".*";
|
|
722
757
|
}
|
|
723
758
|
if (part.startsWith("{")) {
|
|
724
|
-
return "[^/]+";
|
|
759
|
+
return /[?*]\}$/.test(part) ? "[^/]*" : "[^/]+";
|
|
725
760
|
}
|
|
726
761
|
return escapedForRegex(part);
|
|
727
762
|
}).join("");
|
|
763
|
+
const holes = segment.match(/\{[^}]*\}|\*/g) ?? [];
|
|
764
|
+
const text = segment.replace(/\{[^}]*\}|\*/g, "");
|
|
728
765
|
return {
|
|
729
766
|
kind: "shaped",
|
|
730
767
|
shape: segment.replace(/\{[^}]*\}/g, "{}"),
|
|
731
|
-
test: new RegExp(`^${source}$`)
|
|
768
|
+
test: new RegExp(`^${source}$`),
|
|
769
|
+
bare: holes.every((hole) => hole === "*" || /[?*]\}$/.test(hole)) ? text : null,
|
|
770
|
+
textLength: text.length
|
|
732
771
|
};
|
|
733
772
|
}
|
|
734
773
|
function itemsOf(segment) {
|
|
@@ -748,10 +787,35 @@ function segmentsOf(alternative) {
|
|
|
748
787
|
const trimmed = alternative.startsWith("/") ? alternative.slice(1) : alternative;
|
|
749
788
|
return trimmed === "" ? [] : trimmed.split("/");
|
|
750
789
|
}
|
|
790
|
+
function patternSegmentsOf(alternative) {
|
|
791
|
+
const segments = segmentsOf(alternative);
|
|
792
|
+
const first = segments[0];
|
|
793
|
+
const opensWithBaseUrl = !alternative.startsWith("/") && first !== void 0 && HOLE_SEGMENT.test(first);
|
|
794
|
+
return opensWithBaseUrl ? segments.slice(1) : segments;
|
|
795
|
+
}
|
|
796
|
+
function pathAfterBaseUrl(path) {
|
|
797
|
+
const segments = segmentsOf(path);
|
|
798
|
+
const first = segments[0];
|
|
799
|
+
if (path.startsWith("/") || first === void 0 || segments.length < 2 || !HOLE_SEGMENT.test(first)) {
|
|
800
|
+
return path;
|
|
801
|
+
}
|
|
802
|
+
return `/${segments.slice(1).join("/")}`;
|
|
803
|
+
}
|
|
804
|
+
var PATTERNS = /* @__PURE__ */ new Map();
|
|
805
|
+
var PATTERN_CACHE_LIMIT = 5e4;
|
|
751
806
|
function patternOf(path) {
|
|
752
|
-
|
|
753
|
-
|
|
807
|
+
const known = PATTERNS.get(path);
|
|
808
|
+
if (known !== void 0) {
|
|
809
|
+
return known;
|
|
810
|
+
}
|
|
811
|
+
const pattern = alternativesOf(path).map(
|
|
812
|
+
(alternative) => patternSegmentsOf(alternative).flatMap(itemsOf)
|
|
754
813
|
);
|
|
814
|
+
if (PATTERNS.size >= PATTERN_CACHE_LIMIT) {
|
|
815
|
+
PATTERNS.clear();
|
|
816
|
+
}
|
|
817
|
+
PATTERNS.set(path, pattern);
|
|
818
|
+
return pattern;
|
|
755
819
|
}
|
|
756
820
|
function literalItemsOf(path) {
|
|
757
821
|
return segmentsOf(path).map((text) => ({ kind: "text", text }));
|
|
@@ -830,17 +894,104 @@ function pathSpansShapes(path) {
|
|
|
830
894
|
function countOf(items, kinds) {
|
|
831
895
|
return items.filter((item) => kinds.includes(item.kind)).length;
|
|
832
896
|
}
|
|
833
|
-
function
|
|
834
|
-
|
|
835
|
-
const ranks = alternatives.map((items) => [
|
|
897
|
+
function readingSpecificity(items) {
|
|
898
|
+
return [
|
|
836
899
|
countOf(items, ["text"]),
|
|
837
900
|
countOf(items, ["shaped"]),
|
|
838
901
|
-countOf(items, ["optional", "star"])
|
|
839
|
-
]
|
|
840
|
-
|
|
841
|
-
|
|
902
|
+
];
|
|
903
|
+
}
|
|
904
|
+
function segmentFit(route, request) {
|
|
905
|
+
if (!meetOnOneSegment(route, request)) {
|
|
906
|
+
return "apart";
|
|
907
|
+
}
|
|
908
|
+
if (request.kind === "text") {
|
|
909
|
+
if (route.kind === "text") {
|
|
910
|
+
return "stated";
|
|
911
|
+
}
|
|
912
|
+
return route.kind === "shaped" ? "shaped" : "free";
|
|
913
|
+
}
|
|
914
|
+
if (absorbsAnything(route)) {
|
|
915
|
+
return "free";
|
|
916
|
+
}
|
|
917
|
+
if (request.kind !== "shaped") {
|
|
918
|
+
return "guess";
|
|
919
|
+
}
|
|
920
|
+
if (route.kind === "shaped") {
|
|
921
|
+
return "free";
|
|
922
|
+
}
|
|
923
|
+
return route.kind === "text" && request.bare === route.text ? "stated" : "guess";
|
|
924
|
+
}
|
|
925
|
+
function shapedText(item) {
|
|
926
|
+
return item.kind === "shaped" ? item.textLength : 0;
|
|
927
|
+
}
|
|
928
|
+
function betterFit(a, b) {
|
|
929
|
+
return a === void 0 || compareRanks(b, a) > 0;
|
|
930
|
+
}
|
|
931
|
+
function bestFit(route, request) {
|
|
932
|
+
const width = request.length + 1;
|
|
933
|
+
const best = new Array((route.length + 1) * width);
|
|
934
|
+
best[0] = [0, 0];
|
|
935
|
+
const offer = (i, j, fit) => {
|
|
936
|
+
const at = i * width + j;
|
|
937
|
+
if (betterFit(best[at], fit)) {
|
|
938
|
+
best[at] = fit;
|
|
939
|
+
}
|
|
940
|
+
};
|
|
941
|
+
for (let reached = 0; reached <= route.length + request.length; reached += 1) {
|
|
942
|
+
for (let i = Math.max(0, reached - request.length); i <= Math.min(route.length, reached); i += 1) {
|
|
943
|
+
const j = reached - i;
|
|
944
|
+
const fit = best[i * width + j];
|
|
945
|
+
if (fit === void 0) {
|
|
946
|
+
continue;
|
|
947
|
+
}
|
|
948
|
+
const left = route[i];
|
|
949
|
+
const right = request[j];
|
|
950
|
+
if (left !== void 0 && skippable(left)) {
|
|
951
|
+
offer(i + 1, j, fit);
|
|
952
|
+
}
|
|
953
|
+
if (right !== void 0 && skippable(right)) {
|
|
954
|
+
offer(i, j + 1, fit);
|
|
955
|
+
}
|
|
956
|
+
if (left === void 0 || right === void 0) {
|
|
957
|
+
continue;
|
|
958
|
+
}
|
|
959
|
+
if (left.kind === "star" && right.kind === "star") {
|
|
960
|
+
continue;
|
|
961
|
+
}
|
|
962
|
+
const kind = segmentFit(left, right);
|
|
963
|
+
if (kind === "apart" || kind === "guess") {
|
|
964
|
+
continue;
|
|
965
|
+
}
|
|
966
|
+
offer(
|
|
967
|
+
left.kind === "star" ? i : i + 1,
|
|
968
|
+
right.kind === "star" ? j : j + 1,
|
|
969
|
+
[
|
|
970
|
+
fit[0] + (kind === "stated" ? 1 : 0),
|
|
971
|
+
fit[1] + (kind === "shaped" ? shapedText(left) : 0)
|
|
972
|
+
]
|
|
973
|
+
);
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
return best[route.length * width + request.length] ?? null;
|
|
977
|
+
}
|
|
978
|
+
function requestRank(route, request) {
|
|
979
|
+
let found = null;
|
|
980
|
+
for (const routeItems of patternOf(route)) {
|
|
981
|
+
for (const requestItems of patternOf(request)) {
|
|
982
|
+
const fit = bestFit(routeItems, requestItems);
|
|
983
|
+
const rank = fit === null ? null : [...fit, ...readingSpecificity(routeItems)];
|
|
984
|
+
if (rank !== null && (found === null || compareRanks(rank, found) > 0)) {
|
|
985
|
+
found = rank;
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
return found;
|
|
990
|
+
}
|
|
991
|
+
function isCatchAll(route) {
|
|
992
|
+
return patternOf(route).some(
|
|
993
|
+
(items) => items.length > 0 && items.every(absorbsAnything) && items.some((item) => item.kind === "star")
|
|
842
994
|
);
|
|
843
|
-
return [...loosest, 1 - alternatives.length];
|
|
844
995
|
}
|
|
845
996
|
function compareRanks(a, b) {
|
|
846
997
|
const length = Math.max(a.length, b.length);
|
|
@@ -870,7 +1021,18 @@ var RestSemanticsSchema = import_zod7.z.object({
|
|
|
870
1021
|
* here so the pairing layer can see them without unwrapping any
|
|
871
1022
|
* metadata. Absent or empty for an inferred source.
|
|
872
1023
|
*/
|
|
873
|
-
declaredResponses: import_zod7.z.array(import_zod7.z.number()).optional()
|
|
1024
|
+
declaredResponses: import_zod7.z.array(import_zod7.z.number()).optional(),
|
|
1025
|
+
/**
|
|
1026
|
+
* The host a client wrote in an absolute URL, with its port
|
|
1027
|
+
* (`api.example.com:8443`). A piece suss could not read is written
|
|
1028
|
+
* `{name}`. Absent for a relative URL and for a route.
|
|
1029
|
+
*/
|
|
1030
|
+
host: import_zod7.z.string().min(1).optional(),
|
|
1031
|
+
/**
|
|
1032
|
+
* True for a route the framework also serves with `.{format}` after
|
|
1033
|
+
* its path, the way Rails serves `/search.json` from `get "search"`.
|
|
1034
|
+
*/
|
|
1035
|
+
optionalFormat: import_zod7.z.boolean().optional()
|
|
874
1036
|
});
|
|
875
1037
|
var OPENING_HOLE = /^\{([^{}]+)\}(.*)$/;
|
|
876
1038
|
function baseUrlReference(semantics) {
|
|
@@ -878,7 +1040,10 @@ function baseUrlReference(semantics) {
|
|
|
878
1040
|
return label === void 0 ? null : referenceFromName(patternHole(label));
|
|
879
1041
|
}
|
|
880
1042
|
function normalizePath(path) {
|
|
881
|
-
let normalized = path.replace(
|
|
1043
|
+
let normalized = withoutParameterConstraints(path).replace(
|
|
1044
|
+
/:([a-zA-Z_]\w*)([?+*]?)/g,
|
|
1045
|
+
"{$1$2}"
|
|
1046
|
+
);
|
|
882
1047
|
if (normalized.length > 1 && normalized.endsWith("/")) {
|
|
883
1048
|
normalized = normalized.slice(0, -1);
|
|
884
1049
|
}
|
|
@@ -888,6 +1053,46 @@ function normalizePath(path) {
|
|
|
888
1053
|
);
|
|
889
1054
|
return normalized;
|
|
890
1055
|
}
|
|
1056
|
+
function withoutParameterConstraints(path) {
|
|
1057
|
+
let out = "";
|
|
1058
|
+
let i = 0;
|
|
1059
|
+
while (i < path.length) {
|
|
1060
|
+
const name = /^:[a-zA-Z_]\w*\(/.exec(path.slice(i));
|
|
1061
|
+
if (name === null) {
|
|
1062
|
+
out += path[i];
|
|
1063
|
+
i += 1;
|
|
1064
|
+
continue;
|
|
1065
|
+
}
|
|
1066
|
+
const open = i + name[0].length - 1;
|
|
1067
|
+
const close = closingParenthesis(path, open);
|
|
1068
|
+
if (close === -1) {
|
|
1069
|
+
return out + path.slice(i);
|
|
1070
|
+
}
|
|
1071
|
+
out += path.slice(i, open);
|
|
1072
|
+
i = close + 1;
|
|
1073
|
+
}
|
|
1074
|
+
return out;
|
|
1075
|
+
}
|
|
1076
|
+
function closingParenthesis(text, open) {
|
|
1077
|
+
let depth = 0;
|
|
1078
|
+
for (let i = open; i < text.length; i += 1) {
|
|
1079
|
+
const char = text[i];
|
|
1080
|
+
if (char === "\\") {
|
|
1081
|
+
i += 1;
|
|
1082
|
+
continue;
|
|
1083
|
+
}
|
|
1084
|
+
if (char === "(") {
|
|
1085
|
+
depth += 1;
|
|
1086
|
+
}
|
|
1087
|
+
if (char === ")") {
|
|
1088
|
+
depth -= 1;
|
|
1089
|
+
if (depth === 0) {
|
|
1090
|
+
return i;
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
return -1;
|
|
1095
|
+
}
|
|
891
1096
|
function pathShape(path) {
|
|
892
1097
|
return normalizePath(path).replace(/\{[^{}]*?([?+*]?)\}/g, "{$1}");
|
|
893
1098
|
}
|
|
@@ -903,6 +1108,40 @@ function routePathAdmits(declaredPath, requestPath) {
|
|
|
903
1108
|
function routePathsMeet(a, b) {
|
|
904
1109
|
return pathsMeet(normalizePath(a), normalizePath(b));
|
|
905
1110
|
}
|
|
1111
|
+
function readHost(semantics) {
|
|
1112
|
+
const host = semantics.host;
|
|
1113
|
+
return host === void 0 || /[{(]/.test(host) ? void 0 : host;
|
|
1114
|
+
}
|
|
1115
|
+
function hostsAgree(a, b) {
|
|
1116
|
+
return readHost(a) === readHost(b);
|
|
1117
|
+
}
|
|
1118
|
+
function hostUnread(semantics) {
|
|
1119
|
+
if (semantics.host !== void 0) {
|
|
1120
|
+
return readHost(semantics) === void 0;
|
|
1121
|
+
}
|
|
1122
|
+
return baseUrlReference(semantics) !== null;
|
|
1123
|
+
}
|
|
1124
|
+
function servedPath(semantics, path) {
|
|
1125
|
+
const normalized = normalizePath(path);
|
|
1126
|
+
return semantics.optionalFormat === true ? `${normalized}(|.{format})` : normalized;
|
|
1127
|
+
}
|
|
1128
|
+
function withoutHost(semantics) {
|
|
1129
|
+
const { host: _host, ...rest } = semantics;
|
|
1130
|
+
return rest;
|
|
1131
|
+
}
|
|
1132
|
+
function groundedBaseUrl(semantics, deployment) {
|
|
1133
|
+
const reference = baseUrlReference(semantics);
|
|
1134
|
+
if (reference === null) {
|
|
1135
|
+
return null;
|
|
1136
|
+
}
|
|
1137
|
+
const base = deployment.setTo(reference);
|
|
1138
|
+
if (base === null) {
|
|
1139
|
+
return null;
|
|
1140
|
+
}
|
|
1141
|
+
const rest = OPENING_HOLE.exec(semantics.path ?? "")?.[2] ?? "";
|
|
1142
|
+
const grounded = pathAfterOrigin(`${base}${rest}`);
|
|
1143
|
+
return { ...semantics, path: grounded === "" ? "/" : grounded };
|
|
1144
|
+
}
|
|
906
1145
|
var restSemantics = defineBoundarySemantics({
|
|
907
1146
|
name: "rest",
|
|
908
1147
|
schema: RestSemanticsSchema,
|
|
@@ -941,19 +1180,46 @@ var restSemantics = defineBoundarySemantics({
|
|
|
941
1180
|
if (semantics.method === null || semantics.path === null) {
|
|
942
1181
|
return null;
|
|
943
1182
|
}
|
|
944
|
-
|
|
1183
|
+
const shape = pathShape(pathAfterBaseUrl(normalizePath(semantics.path)));
|
|
1184
|
+
const host = readHost(semantics);
|
|
1185
|
+
return host === void 0 ? `rest ${shape}` : `rest //${host}${shape}`;
|
|
1186
|
+
},
|
|
1187
|
+
/**
|
|
1188
|
+
* A spec writes `/teams/{team_id}` where the route that serves it
|
|
1189
|
+
* writes `/teams/:id`. The method stays in, so a `"*"` handler is
|
|
1190
|
+
* never compared with the document for one method.
|
|
1191
|
+
*/
|
|
1192
|
+
operationKey(semantics) {
|
|
1193
|
+
if (semantics.method === null || semantics.path === null) {
|
|
1194
|
+
return null;
|
|
1195
|
+
}
|
|
1196
|
+
return `${semantics.method.toUpperCase()} ${pathShape(semantics.path)}`;
|
|
945
1197
|
},
|
|
946
1198
|
sidesAgree(a, b) {
|
|
947
|
-
return methodsAgree(a.method, b.method);
|
|
1199
|
+
return methodsAgree(a.method, b.method) && hostsAgree(a, b);
|
|
948
1200
|
},
|
|
949
1201
|
spansBuckets(semantics) {
|
|
950
|
-
return semantics.path !== null && pathSpansShapes(normalizePath(semantics.path));
|
|
1202
|
+
return semantics.path !== null && (semantics.optionalFormat === true || pathSpansShapes(normalizePath(semantics.path)));
|
|
951
1203
|
},
|
|
952
1204
|
bucketsMeet(a, b) {
|
|
953
|
-
return a.path !== null && b.path !== null &&
|
|
1205
|
+
return a.path !== null && b.path !== null && hostsAgree(a, b) && pathsMeet(servedPath(a, a.path), servedPath(b, b.path));
|
|
954
1206
|
},
|
|
955
|
-
|
|
956
|
-
|
|
1207
|
+
/**
|
|
1208
|
+
* A catch-all route never takes a call whose host suss could not
|
|
1209
|
+
* read, since nothing else ties that call to this app.
|
|
1210
|
+
*/
|
|
1211
|
+
pairRank(provider, consumer) {
|
|
1212
|
+
if (provider.path === null || consumer.path === null) {
|
|
1213
|
+
return [];
|
|
1214
|
+
}
|
|
1215
|
+
const route = normalizePath(provider.path);
|
|
1216
|
+
if (hostUnread(consumer) && isCatchAll(route)) {
|
|
1217
|
+
return null;
|
|
1218
|
+
}
|
|
1219
|
+
return requestRank(
|
|
1220
|
+
servedPath(provider, provider.path),
|
|
1221
|
+
normalizePath(consumer.path)
|
|
1222
|
+
);
|
|
957
1223
|
},
|
|
958
1224
|
/**
|
|
959
1225
|
* The identity key, with a missing half still readable: `ANY` when
|
|
@@ -994,27 +1260,29 @@ var restSemantics = defineBoundarySemantics({
|
|
|
994
1260
|
},
|
|
995
1261
|
/**
|
|
996
1262
|
* A call whose base URL the deployment fills in, resolved to the
|
|
997
|
-
* path it reaches
|
|
1263
|
+
* path it reaches, and a call to a host that can be the project's
|
|
1264
|
+
* own, with the host left out so it meets the route.
|
|
998
1265
|
*
|
|
999
|
-
* The source cannot settle
|
|
1000
|
-
* the hole in. `API_BASE` could be `http://backend.internal`,
|
|
1001
|
-
* then the path is `/orders`. It could equally be `/api/v2`, and
|
|
1266
|
+
* The source cannot settle a base URL on its own, so the adapter
|
|
1267
|
+
* leaves the hole in. `API_BASE` could be `http://backend.internal`,
|
|
1268
|
+
* and then the path is `/orders`. It could equally be `/api/v2`, and
|
|
1002
1269
|
* then the path is `/api/v2/orders`. Filling in the deployed value
|
|
1003
|
-
* and reading the path back out gets the right one either way
|
|
1004
|
-
*
|
|
1270
|
+
* and reading the path back out gets the right one either way, and
|
|
1271
|
+
* a base the deployment sets counts as the app's own.
|
|
1005
1272
|
*/
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
}
|
|
1011
|
-
const base = deployment.setTo(reference);
|
|
1012
|
-
if (base === null) {
|
|
1273
|
+
/** A listed host matches with or without the port the call gives. */
|
|
1274
|
+
withoutOwnHost(semantics, ownHosts) {
|
|
1275
|
+
const host = semantics.host?.toLowerCase();
|
|
1276
|
+
if (host === void 0) {
|
|
1013
1277
|
return null;
|
|
1014
1278
|
}
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1279
|
+
return ownHosts.has(host) || ownHosts.has(host.replace(/:\d+$/, "")) ? withoutHost(semantics) : null;
|
|
1280
|
+
},
|
|
1281
|
+
groundName(semantics, deployment) {
|
|
1282
|
+
const based = groundedBaseUrl(semantics, deployment);
|
|
1283
|
+
const grounded = based ?? semantics;
|
|
1284
|
+
const host = readHost(grounded);
|
|
1285
|
+
return host !== void 0 && hostCanBeOwn(host) ? withoutHost(grounded) : based;
|
|
1018
1286
|
},
|
|
1019
1287
|
nameReference: baseUrlReference,
|
|
1020
1288
|
ruleBoundary: {
|
|
@@ -1460,6 +1728,13 @@ function withRewrittenPaths(binding, rewrite) {
|
|
|
1460
1728
|
semantics: behavior.rewritePaths(binding.semantics, rewrite)
|
|
1461
1729
|
};
|
|
1462
1730
|
}
|
|
1731
|
+
function withoutOwnHost(binding, ownHosts) {
|
|
1732
|
+
const semantics = behaviorOf(binding.semantics).withoutOwnHost?.(
|
|
1733
|
+
binding.semantics,
|
|
1734
|
+
ownHosts
|
|
1735
|
+
);
|
|
1736
|
+
return semantics === void 0 || semantics === null ? binding : { ...binding, semantics };
|
|
1737
|
+
}
|
|
1463
1738
|
function groundedPairingKey(binding, deployment) {
|
|
1464
1739
|
return pairingKey(groundBinding(binding, deployment));
|
|
1465
1740
|
}
|
|
@@ -1475,6 +1750,10 @@ function pairingKey(binding) {
|
|
|
1475
1750
|
const behavior = behaviorOf(binding.semantics);
|
|
1476
1751
|
return (behavior.pairingKey ?? behavior.identityKey)(binding.semantics);
|
|
1477
1752
|
}
|
|
1753
|
+
function operationKey(binding) {
|
|
1754
|
+
const behavior = behaviorOf(binding.semantics);
|
|
1755
|
+
return (behavior.operationKey ?? behavior.identityKey)(binding.semantics);
|
|
1756
|
+
}
|
|
1478
1757
|
function semanticsAgree(a, b) {
|
|
1479
1758
|
if (a.name !== b.name) {
|
|
1480
1759
|
return false;
|
|
@@ -1492,8 +1771,12 @@ function bucketsMeet(a, b) {
|
|
|
1492
1771
|
const meet = behaviorOf(a.semantics).bucketsMeet;
|
|
1493
1772
|
return meet !== void 0 && meet(a.semantics, b.semantics);
|
|
1494
1773
|
}
|
|
1495
|
-
function
|
|
1496
|
-
|
|
1774
|
+
function pairRank(provider, consumer) {
|
|
1775
|
+
if (provider.semantics.name !== consumer.semantics.name) {
|
|
1776
|
+
return null;
|
|
1777
|
+
}
|
|
1778
|
+
const rank = behaviorOf(provider.semantics).pairRank;
|
|
1779
|
+
return rank === void 0 ? [] : rank(provider.semantics, consumer.semantics);
|
|
1497
1780
|
}
|
|
1498
1781
|
function boundaryLabel(binding) {
|
|
1499
1782
|
const behavior = behaviorOf(binding.semantics);
|
|
@@ -1968,7 +2251,9 @@ function restBinding(opts) {
|
|
|
1968
2251
|
name: "rest",
|
|
1969
2252
|
method: method === null ? null : method.toUpperCase(),
|
|
1970
2253
|
path: namedOrNull(opts.path, "rest path"),
|
|
1971
|
-
...opts.declaredResponses !== void 0 ? { declaredResponses: opts.declaredResponses } : {}
|
|
2254
|
+
...opts.declaredResponses !== void 0 ? { declaredResponses: opts.declaredResponses } : {},
|
|
2255
|
+
...opts.host !== void 0 && opts.host !== "" ? { host: opts.host } : {},
|
|
2256
|
+
...opts.optionalFormat === true ? { optionalFormat: true } : {}
|
|
1972
2257
|
},
|
|
1973
2258
|
recognition: opts.recognition
|
|
1974
2259
|
};
|
|
@@ -2127,7 +2412,6 @@ function ioBinding(opts) {
|
|
|
2127
2412
|
boundaryKey,
|
|
2128
2413
|
boundaryLabel,
|
|
2129
2414
|
boundaryNameString,
|
|
2130
|
-
bucketRank,
|
|
2131
2415
|
bucketsMeet,
|
|
2132
2416
|
busIdentityKey,
|
|
2133
2417
|
busesAgree,
|
|
@@ -2151,6 +2435,7 @@ function ioBinding(opts) {
|
|
|
2151
2435
|
groundBinding,
|
|
2152
2436
|
groundedPairingKey,
|
|
2153
2437
|
hasNameHole,
|
|
2438
|
+
hostCanBeOwn,
|
|
2154
2439
|
ioBinding,
|
|
2155
2440
|
ioIdentityKey,
|
|
2156
2441
|
isGraphqlOperationBinding,
|
|
@@ -2171,7 +2456,9 @@ function ioBinding(opts) {
|
|
|
2171
2456
|
namesNothing,
|
|
2172
2457
|
normalizePath,
|
|
2173
2458
|
normalizeRuleBoundary,
|
|
2459
|
+
operationKey,
|
|
2174
2460
|
packageExportBinding,
|
|
2461
|
+
pairRank,
|
|
2175
2462
|
pairingKey,
|
|
2176
2463
|
parseBoundaryName,
|
|
2177
2464
|
parseChannel,
|
|
@@ -2208,5 +2495,6 @@ function ioBinding(opts) {
|
|
|
2208
2495
|
validateRule,
|
|
2209
2496
|
withDefinitionsInlined,
|
|
2210
2497
|
withRewrittenPaths,
|
|
2211
|
-
withinScope
|
|
2498
|
+
withinScope,
|
|
2499
|
+
withoutOwnHost
|
|
2212
2500
|
});
|