Support checked keyed relationships across portable operations and queries

This commit is contained in:
Timothy J. Aveni
2026-09-25 12:02:05 -07:00
parent e0e8563224
commit 1bc3c69de3
23 changed files with 1203 additions and 949 deletions
+30 -3
View File
@@ -439,7 +439,19 @@ export const edgePrimitiveSignature = (
case "disconnect":
return {
mode: "call",
inputType: targetType,
inputType:
primitive === "connect" && projection.endpoint.keyType
? {
kind: "record",
fields: {
mapKey: {
kind: "scalar",
name: projection.endpoint.keyType === "boolean" ? "bool" : projection.endpoint.keyType,
},
target: targetType,
},
}
: targetType,
outputType: valueType.unit,
};
case "watch-start":
@@ -1398,6 +1410,13 @@ const validateBoundDependencies = (
);
break;
}
if (projection.target.keyType && requirement.primitives.includes("connect"))
issue(
issues,
"invalid-dependency-binding",
path,
"Connect through the keyed projection so the caller supplies a map key",
);
const traversal = edgeBinding.via
? validateTraversal(
issues,
@@ -1434,13 +1453,14 @@ const validateBoundDependencies = (
requirement.target,
params.indexes.conformances,
) ||
requirement.cardinality !== projection.endpoint.cardinality
requirement.cardinality !== projection.endpoint.cardinality ||
requirement.keyType !== projection.endpoint.keyType
) {
issue(
issues,
"invalid-dependency-binding",
`${path}.binding`,
`Edge port target or cardinality does not match projection ${edgeBinding.projectionId}`,
`Edge port target, cardinality or key type does not match projection ${edgeBinding.projectionId}`,
);
}
break;
@@ -1822,6 +1842,13 @@ const validateConformances = (
continue;
}
const projection = edgeProjection(attachment.attachment, binding.projectionId);
if (projection?.target.keyType && binding.primitive === "connect")
issue(
issues,
"invalid-edge-binding",
bindingPath,
"Connect through the keyed projection so the caller supplies a map key",
);
// An owned endpoint may explicitly export read-only traversal, including
// a native inverse relationship view. This never exports mutation rights.
if (!(binding.primitive === "resolve" && projection?.endpoint.publicTraversal)) {