@suss/ir-core 0.34.0 → 0.35.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/dist/{chunk-WOXA5GBL.js → chunk-A46EUIKC.js} +301 -35
- package/dist/index.cjs +333 -43
- package/dist/index.d.cts +63 -11
- package/dist/index.d.ts +63 -11
- package/dist/index.js +30 -7
- 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);
|
|
@@ -1681,7 +1964,9 @@ var EffectRelationSchema = RelationSchema.exclude(["provides"]);
|
|
|
1681
1964
|
var import_zod15 = require("zod");
|
|
1682
1965
|
var SuppressionSideSchema = import_zod15.z.object({
|
|
1683
1966
|
summary: import_zod15.z.string().optional(),
|
|
1684
|
-
transitionId: import_zod15.z.string().optional()
|
|
1967
|
+
transitionId: import_zod15.z.string().optional(),
|
|
1968
|
+
/** The field on that side, for a finding about one field and no transition. */
|
|
1969
|
+
field: import_zod15.z.string().optional()
|
|
1685
1970
|
}).optional();
|
|
1686
1971
|
var SuppressionRuleSchema = import_zod15.z.object({
|
|
1687
1972
|
/**
|
|
@@ -1968,7 +2253,9 @@ function restBinding(opts) {
|
|
|
1968
2253
|
name: "rest",
|
|
1969
2254
|
method: method === null ? null : method.toUpperCase(),
|
|
1970
2255
|
path: namedOrNull(opts.path, "rest path"),
|
|
1971
|
-
...opts.declaredResponses !== void 0 ? { declaredResponses: opts.declaredResponses } : {}
|
|
2256
|
+
...opts.declaredResponses !== void 0 ? { declaredResponses: opts.declaredResponses } : {},
|
|
2257
|
+
...opts.host !== void 0 && opts.host !== "" ? { host: opts.host } : {},
|
|
2258
|
+
...opts.optionalFormat === true ? { optionalFormat: true } : {}
|
|
1972
2259
|
},
|
|
1973
2260
|
recognition: opts.recognition
|
|
1974
2261
|
};
|
|
@@ -2127,7 +2414,6 @@ function ioBinding(opts) {
|
|
|
2127
2414
|
boundaryKey,
|
|
2128
2415
|
boundaryLabel,
|
|
2129
2416
|
boundaryNameString,
|
|
2130
|
-
bucketRank,
|
|
2131
2417
|
bucketsMeet,
|
|
2132
2418
|
busIdentityKey,
|
|
2133
2419
|
busesAgree,
|
|
@@ -2151,6 +2437,7 @@ function ioBinding(opts) {
|
|
|
2151
2437
|
groundBinding,
|
|
2152
2438
|
groundedPairingKey,
|
|
2153
2439
|
hasNameHole,
|
|
2440
|
+
hostCanBeOwn,
|
|
2154
2441
|
ioBinding,
|
|
2155
2442
|
ioIdentityKey,
|
|
2156
2443
|
isGraphqlOperationBinding,
|
|
@@ -2171,7 +2458,9 @@ function ioBinding(opts) {
|
|
|
2171
2458
|
namesNothing,
|
|
2172
2459
|
normalizePath,
|
|
2173
2460
|
normalizeRuleBoundary,
|
|
2461
|
+
operationKey,
|
|
2174
2462
|
packageExportBinding,
|
|
2463
|
+
pairRank,
|
|
2175
2464
|
pairingKey,
|
|
2176
2465
|
parseBoundaryName,
|
|
2177
2466
|
parseChannel,
|
|
@@ -2208,5 +2497,6 @@ function ioBinding(opts) {
|
|
|
2208
2497
|
validateRule,
|
|
2209
2498
|
withDefinitionsInlined,
|
|
2210
2499
|
withRewrittenPaths,
|
|
2211
|
-
withinScope
|
|
2500
|
+
withinScope,
|
|
2501
|
+
withoutOwnHost
|
|
2212
2502
|
});
|