schemair 0.2.0 → 0.3.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.
Files changed (73) hide show
  1. package/README.md +140 -39
  2. package/dist/authoring/index.d.cts +1 -1
  3. package/dist/authoring/index.d.ts +1 -1
  4. package/dist/authoring/index.js +1 -1
  5. package/dist/{authoring-D3V0iyTe.js → authoring-DyJNYs5o.js} +1 -1
  6. package/dist/compatibility/index.cjs +43 -0
  7. package/dist/compatibility/index.d.cts +2 -0
  8. package/dist/compatibility/index.d.ts +2 -0
  9. package/dist/compatibility/index.js +42 -0
  10. package/dist/definition/index.d.cts +2 -2
  11. package/dist/definition/index.d.ts +2 -2
  12. package/dist/definition/index.js +1 -1
  13. package/dist/{index-DDMwVy2I.d.cts → index-1sDuqu05.d.ts} +6 -1
  14. package/dist/index-BFSMT_2d.d.ts +53 -0
  15. package/dist/{index-DM5DSLLL.d.ts → index-BGz7L_Fq.d.cts} +4 -30
  16. package/dist/{index-bQy-C-1l.d.ts → index-BTtdqi_M.d.ts} +9 -9
  17. package/dist/index-BfbClf6R.d.cts +20 -0
  18. package/dist/{index-CQynt7ft.d.cts → index-CK7Is7vy.d.cts} +9 -9
  19. package/dist/index-CUGhtuwA.d.cts +53 -0
  20. package/dist/{index-DXWoNYFB.d.ts → index-CV8EZQy8.d.ts} +1 -1
  21. package/dist/index-CzNxjqVg.d.cts +47 -0
  22. package/dist/{index-CIim1dG7.d.cts → index-DGHMUZ5m.d.cts} +1 -1
  23. package/dist/{index-CBbd4hXJ.d.ts → index-DxvfPmw6.d.ts} +4 -11
  24. package/dist/index-T6nFhvGQ.d.ts +20 -0
  25. package/dist/{index-CNjYUKvu.d.cts → index-ba_52Yu9.d.cts} +4 -11
  26. package/dist/index-hrcM9oJe.d.ts +47 -0
  27. package/dist/{index-4aMF0cTE.d.ts → index-i7Au-FQ6.d.cts} +6 -1
  28. package/dist/{index-DhmHCGpT.d.cts → index-mu1znI1F.d.ts} +4 -30
  29. package/dist/index.cjs +10 -10
  30. package/dist/index.d.cts +9 -7
  31. package/dist/index.d.ts +9 -7
  32. package/dist/index.js +9 -7
  33. package/dist/integrations/json-schema/index.d.cts +1 -1
  34. package/dist/integrations/json-schema/index.d.ts +1 -1
  35. package/dist/integrations/json-schema/index.js +1 -1
  36. package/dist/integrations/standard-schema/index.cjs +4 -4
  37. package/dist/integrations/standard-schema/index.d.cts +5 -5
  38. package/dist/integrations/standard-schema/index.d.ts +5 -5
  39. package/dist/integrations/standard-schema/index.js +5 -5
  40. package/dist/payload/index.cjs +44 -81
  41. package/dist/payload/index.d.cts +2 -2
  42. package/dist/payload/index.d.ts +2 -2
  43. package/dist/payload/index.js +45 -81
  44. package/dist/relations/index.cjs +2 -5
  45. package/dist/relations/index.d.cts +2 -2
  46. package/dist/relations/index.d.ts +2 -2
  47. package/dist/relations/index.js +2 -2
  48. package/dist/{relations-Cymx4iTc.cjs → relations-NUVJkAG8.cjs} +11 -232
  49. package/dist/{relations-ysXDmi-Z.js → relations-QtnCRW9x.js} +13 -216
  50. package/dist/resolve/index.cjs +308 -0
  51. package/dist/resolve/index.d.cts +2 -0
  52. package/dist/resolve/index.d.ts +2 -0
  53. package/dist/resolve/index.js +305 -0
  54. package/dist/schema-ref-key-BHVFVfj1.cjs +26 -0
  55. package/dist/schema-ref-key-DR__tPr-.js +14 -0
  56. package/dist/spec/index.d.cts +2 -2
  57. package/dist/spec/index.d.ts +2 -2
  58. package/dist/spec/index.js +1 -1
  59. package/dist/standard/index.d.cts +2 -2
  60. package/dist/standard/index.d.ts +2 -2
  61. package/dist/standard/index.js +2 -2
  62. package/dist/type-interpreter/index.cjs +2 -6
  63. package/dist/type-interpreter/index.d.cts +2 -2
  64. package/dist/type-interpreter/index.d.ts +2 -2
  65. package/dist/type-interpreter/index.js +2 -2
  66. package/dist/{type-interpreter-DnrId8aM.js → type-interpreter-BA8gcLUU.js} +57 -280
  67. package/dist/{type-interpreter-OLt2W2yd.cjs → type-interpreter-D8xETgq1.cjs} +55 -302
  68. package/package.json +23 -3
  69. package/dist/index-BqfGAU1K.d.ts +0 -56
  70. package/dist/index-D3mfwaSO.d.cts +0 -56
  71. /package/dist/{chunk-BgLxgFZR.js → chunk-bFfwrPtJ.js} +0 -0
  72. /package/dist/{definition-DmYnDmQO.js → definition-BH_LzXGc.js} +0 -0
  73. /package/dist/{standard-DhKsxu9U.js → standard-BGMgbbEQ.js} +0 -0
@@ -1,5 +1,6 @@
1
- import { a as expressionShapeIssue, f as validateSchemaNodeDefinition, i as expressionKinds, r as expressionFields } from "./definition-DmYnDmQO.js";
2
- import { a as checkSchemaRelation, o as checkSchemaRelationAsync } from "./relations-ysXDmi-Z.js";
1
+ import { a as expressionShapeIssue, f as validateSchemaNodeDefinition, i as expressionKinds, n as validateSchemaTypeTermDefinition, r as expressionFields } from "./definition-BH_LzXGc.js";
2
+ import { n as schemaRefKey, t as indexSchemaRefs } from "./schema-ref-key-DR__tPr-.js";
3
+ import { r as checkSchemaRelation } from "./relations-QtnCRW9x.js";
3
4
 
4
5
  //#region src/type-interpreter/materializer.ts
5
6
  function isRecord(value) {
@@ -861,6 +862,18 @@ function compareTerms(source, target, context) {
861
862
  message: "source does not provide a required field"
862
863
  }]
863
864
  };
865
+ if (!sourceField && source.additionalFields !== void 0) {
866
+ if (source.additionalFields === true) return {
867
+ status: "unknown",
868
+ issues: [{
869
+ code: "relation.unknown.additionalField",
870
+ path: ["fields", field.key],
871
+ message: "unconstrained source residual values do not prove compatibility with the target field"
872
+ }]
873
+ };
874
+ const residual = compareTerms(source.additionalFields, field.value, context);
875
+ if (residual.status !== "assignable") return residual;
876
+ }
864
877
  if (sourceField) {
865
878
  if (field.required === true && sourceField.required !== true) return {
866
879
  status: "incompatible",
@@ -935,125 +948,11 @@ function unknownTermRelation() {
935
948
  }]
936
949
  };
937
950
  }
938
- async function compareTermsAsync(source, target, context) {
939
- if (source.kind === "never") return {
940
- status: "assignable",
941
- issues: []
942
- };
943
- if (source.kind === "absent") return target.kind === "absent" || target.kind === "maybeAbsent" ? {
944
- status: "assignable",
945
- issues: []
946
- } : incompatiblePresence("absent");
947
- if (target.kind === "never" || target.kind === "absent") return incompatiblePresence(target.kind);
948
- if (source.kind === "maybeAbsent" && target.kind !== "maybeAbsent") return incompatiblePresence("maybeAbsent");
949
- if (target.kind === "unknown") return {
950
- status: "assignable",
951
- issues: []
952
- };
953
- if (source.kind === "unknown") return unknownTermRelation();
954
- if (source.kind === "opaqueHostType" && target.kind === "opaqueHostType") {
955
- if (samePath(source.hostPath, target.hostPath)) return {
956
- status: "assignable",
957
- issues: []
958
- };
959
- if (!context.hostTypeRelation) return {
960
- status: "incompatible",
961
- issues: [{
962
- code: "relation.incompatible.opaqueHostType",
963
- path: [],
964
- message: "different opaque host types require an explicit relation provider"
965
- }]
966
- };
967
- return hostDecision(await context.hostTypeRelation(source.hostPath, target.hostPath), "opaque host type relation provider rejected the relation");
968
- }
969
- if (source.kind === "arrayOf" && target.kind === "arrayOf") {
970
- if (!sameData(source.constraints, target.constraints)) return unknownMetadata();
971
- return compareTermsAsync(source.element, target.element, context);
972
- }
973
- if (source.kind === "maybeAbsent" || target.kind === "maybeAbsent") {
974
- if (source.kind !== "maybeAbsent") {
975
- if (target.kind === "maybeAbsent") return compareTermsAsync(source, target.value, context);
976
- return unreachableRelation();
977
- }
978
- if (target.kind !== "maybeAbsent") return incompatiblePresence("maybeAbsent");
979
- return compareTermsAsync(source.value, target.value, context);
980
- }
981
- if (source.kind === "array" && target.kind === "array") return checkSchemaRelationAsync(source, target, context.relation);
982
- if (source.kind === "record" && target.kind === "record") return checkSchemaRelationAsync(source, target, context.relation);
983
- if (source.kind === "tupleOf" && target.kind === "tupleOf") {
984
- if (source.elements.length !== target.elements.length) return {
985
- status: "incompatible",
986
- issues: [{
987
- code: "relation.incompatible.tuple.length",
988
- path: [],
989
- message: "tuple lengths are different"
990
- }]
991
- };
992
- for (let index = 0; index < source.elements.length; index += 1) {
993
- const result$1 = await compareTermsAsync(source.elements[index], target.elements[index], context);
994
- if (result$1.status !== "assignable") return result$1;
995
- }
996
- return {
997
- status: "assignable",
998
- issues: []
999
- };
1000
- }
1001
- if (source.kind === "tuple" && target.kind === "tuple") return checkSchemaRelationAsync(source, target, context.relation);
1002
- if (source.kind === "recordOf" && target.kind === "recordOf") {
1003
- if (!sameData(source.constraints, target.constraints) || !sameData(source.additionalFields, target.additionalFields)) return unknownMetadata();
1004
- const sourceFields = new Map(source.fields.map((field) => [field.key, field]));
1005
- for (const field of target.fields) {
1006
- const sourceField = sourceFields.get(field.key);
1007
- if (!sourceField && field.required === true) return {
1008
- status: "incompatible",
1009
- issues: [{
1010
- code: "relation.incompatible.required",
1011
- path: ["fields", field.key],
1012
- message: "source does not provide a required field"
1013
- }]
1014
- };
1015
- if (sourceField) {
1016
- if (field.required === true && sourceField.required !== true) return {
1017
- status: "incompatible",
1018
- issues: [{
1019
- code: "relation.incompatible.required",
1020
- path: ["fields", field.key],
1021
- message: "source field may be absent"
1022
- }]
1023
- };
1024
- const result$1 = await compareTermsAsync(sourceField.value, field.value, context);
1025
- if (result$1.status !== "assignable") return result$1;
1026
- }
1027
- }
1028
- for (const field of source.fields) if (!target.fields.some((candidate) => candidate.key === field.key)) {
1029
- if (target.additionalFields === void 0) return {
1030
- status: "incompatible",
1031
- issues: [{
1032
- code: "relation.incompatible.additionalField",
1033
- path: ["fields", field.key],
1034
- message: "target record does not allow this source field"
1035
- }]
1036
- };
1037
- if (target.additionalFields !== true) {
1038
- const relation = await compareTermsAsync(field.value, target.additionalFields, context);
1039
- if (relation.status !== "assignable") return relation;
1040
- }
1041
- }
1042
- return {
1043
- status: "assignable",
1044
- issues: []
1045
- };
1046
- }
1047
- const sourceSchema = validateSchemaNodeDefinition(source);
1048
- const targetSchema = validateSchemaNodeDefinition(target);
1049
- if (sourceSchema.ok && targetSchema.ok) return checkSchemaRelationAsync(sourceSchema.node, targetSchema.node, context.relation);
951
+ function relationWithInterpreterRefs(relation, interpreter) {
952
+ if (interpreter?.refs === void 0) return relation ?? {};
1050
953
  return {
1051
- status: "unknown",
1052
- issues: [{
1053
- code: "relation.unknown.term",
1054
- path: [],
1055
- message: "async relation requires normalized term comparison"
1056
- }]
954
+ ...relation ?? {},
955
+ refs: [...relation?.refs ?? [], ...interpreter.refs]
1057
956
  };
1058
957
  }
1059
958
  function diagnostics(result$1, status) {
@@ -1077,12 +976,8 @@ function compareEvaluated(source, target, relation = {}, hostTypeRelation) {
1077
976
  } : { relation });
1078
977
  }
1079
978
  function checkTypeTermRelation(source, target, context = {}) {
1080
- return compareEvaluated(evaluateExpression(source, context.interpreter), evaluateExpression(target, context.interpreter), context.relation, context.hostTypeRelation);
1081
- }
1082
- async function checkTypeTermRelationAsync(source, target, context = {}) {
1083
- const [sourceResult, targetResult] = await Promise.all([evaluateExpressionAsync(source, context.interpreter), evaluateExpressionAsync(target, context.interpreter)]);
1084
- if (sourceResult.status !== "evaluated" || targetResult.status !== "evaluated") return compareEvaluated(sourceResult, targetResult);
1085
- return compareTermsAsync(sourceResult.term, targetResult.term, context);
979
+ const relation = relationWithInterpreterRefs(context.relation, context.interpreter);
980
+ return compareEvaluated(evaluateExpression(source, context.interpreter), evaluateExpression(target, context.interpreter), relation, context.hostTypeRelation);
1086
981
  }
1087
982
 
1088
983
  //#endregion
@@ -1152,9 +1047,13 @@ function replaceChild(expression, path, value) {
1152
1047
  expression[key] = value;
1153
1048
  return;
1154
1049
  }
1155
- const items = expression[key];
1050
+ const items = [...expression[key]];
1051
+ expression[key] = items;
1156
1052
  const index = Number(indexText);
1157
- if (subkey) items[index][subkey] = value;
1053
+ if (subkey) items[index] = {
1054
+ ...items[index],
1055
+ [subkey]: value
1056
+ };
1158
1057
  else items[index] = value;
1159
1058
  }
1160
1059
  function projectNormalized(expression) {
@@ -1263,33 +1162,32 @@ function operandKindIssue(expression) {
1263
1162
  function normalize(term, state, depth = 0) {
1264
1163
  state.steps += 1;
1265
1164
  if (state.steps > (state.context.maxSteps ?? 2e3) || depth > (state.context.maxDepth ?? 64)) return failure("incomplete", "budget", "type interpretation work budget exceeded");
1165
+ const definition = validateSchemaTypeTermDefinition(term);
1166
+ if (!definition.ok) {
1167
+ const status = definition.issues.every((issue$1) => issue$1.code === "expression.cycle" || issue$1.code === "expression.budget") ? "incomplete" : "rejected";
1168
+ return {
1169
+ status,
1170
+ issues: definition.issues.map((issue$1) => ({
1171
+ ...issue$1,
1172
+ code: `interpreter.${status}.${issue$1.code}`
1173
+ }))
1174
+ };
1175
+ }
1266
1176
  if (!isObject(term)) return failure("rejected", "term.object", "type term must be an object");
1267
1177
  if (schemaTerm(term)) {
1268
1178
  if (term.kind !== "ref") return result(term);
1269
- if (!state.context.resolveRef) return failure("incomplete", "ref.resolver", "refPath requires an explicit resolver");
1270
- const key = term.refPath.join("\0");
1271
- if (state.refs.has(key)) return failure("incomplete", "cycle.ref", "refPath resolution cycle could not be determined");
1272
- state.refs.add(key);
1273
- let resolved;
1274
- try {
1275
- resolved = state.context.resolveRef(term.refPath);
1276
- } catch (error) {
1277
- state.refs.delete(key);
1278
- return failure("incomplete", "ref.error", `refPath resolver failed: ${error instanceof Error ? error.message : String(error)}`);
1279
- }
1280
- if (!resolved) {
1281
- state.refs.delete(key);
1282
- return failure("incomplete", "ref.unresolved", "refPath resolver returned no schema");
1283
- }
1284
- if (typeof resolved === "object" && "status" in resolved && resolved.status !== "resolved") {
1285
- state.refs.delete(key);
1286
- return failure("incomplete", `ref.${resolved.status}`, resolved.message ?? "refPath resolver could not determine this path");
1287
- }
1288
- try {
1289
- return normalize(typeof resolved === "object" && "status" in resolved ? resolved.schema : resolved, state, depth + 1);
1290
- } finally {
1291
- state.refs.delete(key);
1179
+ const key = schemaRefKey(term.refPath);
1180
+ const materialized = state.refIndex.get(key);
1181
+ if (materialized !== void 0) {
1182
+ if (state.refs.has(key)) return failure("incomplete", "cycle.ref", "refPath resolution encountered a recursive reference");
1183
+ state.refs.add(key);
1184
+ try {
1185
+ return normalize(materialized, state, depth + 1);
1186
+ } finally {
1187
+ state.refs.delete(key);
1188
+ }
1292
1189
  }
1190
+ return failure("incomplete", state.context.refs === void 0 ? "ref.environment" : "ref.unresolved", state.context.refs === void 0 ? "refPath requires a preloaded refs environment" : "refPath is not present in the preloaded refs environment");
1293
1191
  }
1294
1192
  const kind = term.kind;
1295
1193
  if (typeof kind !== "string" || !expressionKinds.has(kind)) return failure("rejected", "expression.kind", "term is neither a valid SchemaNode nor a supported expression");
@@ -1326,7 +1224,7 @@ function normalize(term, state, depth = 0) {
1326
1224
  if (evaluated.status === "evaluated" && upper !== void 0) {
1327
1225
  const upperResult = result(upper);
1328
1226
  if (evaluated.unresolvedTypeVars?.length || upperResult.status === "evaluated" && upperResult.unresolvedTypeVars?.length) return failure("incomplete", "typeVar.bound", "type variable upper bound could not be established");
1329
- const relation = checkTypeTermRelation(evaluated.term, upper);
1227
+ const relation = checkTypeTermRelation(evaluated.term, upper, { interpreter: state.context });
1330
1228
  if (relation.status !== "assignable") return failure(relation.status === "incompatible" || relation.status === "rejected" ? "rejected" : "incomplete", "typeVar.bound", `binding for '${term.name}' does not satisfy its upper bound: ${relation.issues[0]?.message ?? relation.status}`);
1331
1229
  }
1332
1230
  return evaluated;
@@ -1392,97 +1290,14 @@ function normalize(term, state, depth = 0) {
1392
1290
  function evaluateExpression(term, context = {}) {
1393
1291
  return normalize(term, {
1394
1292
  context,
1293
+ refIndex: indexSchemaRefs(context.refs),
1395
1294
  active: /* @__PURE__ */ new Set(),
1396
1295
  variables: /* @__PURE__ */ new Set(),
1397
1296
  refs: /* @__PURE__ */ new Set(),
1398
1297
  steps: 0
1399
1298
  });
1400
1299
  }
1401
- async function evaluateExpressionAsync(term, context = {}) {
1402
- const activeRefs = /* @__PURE__ */ new Set();
1403
- const activeVars = /* @__PURE__ */ new Set();
1404
- const activeObjects = /* @__PURE__ */ new Set();
1405
- let steps = 0;
1406
- const resolveTree = async (value, depth = 0) => {
1407
- steps += 1;
1408
- if (steps > (context.maxSteps ?? 2e3) || depth > (context.maxDepth ?? 64)) return { failure: failure("incomplete", "budget", "type interpretation work budget exceeded") };
1409
- if (!isObject(value)) return { value };
1410
- if (activeObjects.has(value)) return { failure: failure("incomplete", "cycle.expression", "expression cycle could not be determined") };
1411
- activeObjects.add(value);
1412
- try {
1413
- const definition = validateSchemaNodeDefinition(value);
1414
- if (definition.ok && definition.node.kind === "ref") {
1415
- if (!context.resolveRef) return { failure: failure("incomplete", "ref.resolver", "refPath requires an explicit resolver") };
1416
- const key = definition.node.refPath.join("\0");
1417
- if (activeRefs.has(key)) return { failure: failure("incomplete", "cycle.ref", "refPath resolution cycle could not be determined") };
1418
- activeRefs.add(key);
1419
- try {
1420
- let resolution;
1421
- try {
1422
- resolution = await context.resolveRef(definition.node.refPath);
1423
- } catch (error) {
1424
- return { failure: failure("incomplete", "ref.error", `refPath resolver failed: ${error instanceof Error ? error.message : String(error)}`) };
1425
- }
1426
- if (!resolution) return { failure: failure("incomplete", "ref.unresolved", "refPath resolver returned no schema") };
1427
- if (typeof resolution === "object" && "status" in resolution && resolution.status !== "resolved") return { failure: failure("incomplete", `ref.${resolution.status}`, resolution.message ?? "refPath resolver could not determine this path") };
1428
- return await resolveTree(typeof resolution === "object" && "status" in resolution ? resolution.schema : resolution, depth + 1);
1429
- } finally {
1430
- activeRefs.delete(key);
1431
- }
1432
- }
1433
- if (value.kind === "typeVar") {
1434
- if (typeof value.name !== "string" || !value.name.trim()) return { value };
1435
- const bound = context.typeVars?.[value.name];
1436
- if (bound === void 0) {
1437
- if (value.extends === void 0) return { value };
1438
- const upper = await resolveTree(value.extends, depth + 1);
1439
- return upper.failure ? upper : { value: {
1440
- ...value,
1441
- extends: upper.value
1442
- } };
1443
- }
1444
- if (activeVars.has(value.name)) return { failure: failure("incomplete", "cycle.typeVar", "typeVar resolution cycle could not be determined") };
1445
- activeVars.add(value.name);
1446
- try {
1447
- const resolved$1 = await resolveTree(bound, depth + 1);
1448
- if (resolved$1.failure || value.extends === void 0) return resolved$1;
1449
- const upper = await resolveTree(value.extends, depth + 1);
1450
- if (upper.failure) return upper;
1451
- const source = evaluateExpression(resolved$1.value);
1452
- const target = evaluateExpression(upper.value);
1453
- if (source.status !== "evaluated" || target.status !== "evaluated" || source.unresolvedTypeVars?.length || target.unresolvedTypeVars?.length) return { failure: failure("incomplete", "typeVar.bound", "type variable upper bound could not be established") };
1454
- const relation = checkTypeTermRelation(source.term, target.term);
1455
- if (relation.status !== "assignable") return { failure: failure(relation.status === "incompatible" || relation.status === "rejected" ? "rejected" : "incomplete", "typeVar.bound", `binding for '${value.name}' does not satisfy its upper bound: ${relation.issues[0]?.message ?? relation.status}`) };
1456
- return resolved$1;
1457
- } finally {
1458
- activeVars.delete(value.name);
1459
- }
1460
- }
1461
- const kind = value.kind;
1462
- if (typeof kind !== "string" || !expressionKinds.has(kind)) return { value };
1463
- const shape = expressionFields[kind];
1464
- if (Object.keys(value).some((key) => !shape.allowed.includes(key)) || shape.required.some((key) => !(key in value))) return { value };
1465
- if (expressionShapeIssue(value)) return { value };
1466
- const copy = { ...value };
1467
- for (const [path, child] of childTerms(value)) {
1468
- const resolved$1 = await resolveTree(child, depth + 1);
1469
- if (resolved$1.failure) return resolved$1;
1470
- replaceChild(copy, path, resolved$1.value);
1471
- }
1472
- return { value: copy };
1473
- } finally {
1474
- activeObjects.delete(value);
1475
- }
1476
- };
1477
- const resolved = await resolveTree(term);
1478
- if (resolved.failure) return resolved.failure;
1479
- return evaluateExpression(resolved.value, {
1480
- maxDepth: Number.MAX_SAFE_INTEGER,
1481
- maxSteps: Number.MAX_SAFE_INTEGER
1482
- });
1483
- }
1484
1300
  const evaluateSchemaTypeTerm = evaluateExpression;
1485
- const evaluateSchemaTypeTermAsync = evaluateExpressionAsync;
1486
1301
 
1487
1302
  //#endregion
1488
1303
  //#region src/type-interpreter/type-variable-solver.ts
@@ -1541,6 +1356,11 @@ function initial(input, context) {
1541
1356
  code: "solver.rejected.variable.prebound",
1542
1357
  message: "a variable declared for solving is already bound in the interpreter context"
1543
1358
  }]);
1359
+ for (const [index, constraint] of input.constraints.entries()) if (!validateSchemaTypeTermDefinition(constraint.source).ok || !validateSchemaTypeTermDefinition(constraint.target).ok) return makeResult("rejected", {}, names, [{
1360
+ code: "solver.rejected.input",
1361
+ constraint: index,
1362
+ message: "constraint terms must be well formed"
1363
+ }]);
1544
1364
  }
1545
1365
  function interpreterContext(context, bindings) {
1546
1366
  return {
@@ -1608,49 +1428,6 @@ function solveTypeVariables(input, context = {}) {
1608
1428
  }
1609
1429
  return makeResult("solved", bindings, input.variables, []);
1610
1430
  }
1611
- async function solveTypeVariablesAsync(input, context = {}) {
1612
- const invalid = initial(input, context);
1613
- if (invalid) return invalid;
1614
- const bindings = Object.create(null);
1615
- const names = new Set(input.variables);
1616
- for (let pass = 0; pass <= input.variables.length; pass += 1) {
1617
- let changed = false;
1618
- for (const [index, constraint] of input.constraints.entries()) {
1619
- const actual = await evaluateExpressionAsync(constraint.source, interpreterContext(context.interpreter, bindings));
1620
- if (actual.status === "evaluated" && actual.unresolvedTypeVars?.length) continue;
1621
- if (actual.status !== "evaluated") return makeResult(actual.status === "incomplete" ? "unknown" : actual.status, bindings, input.variables, [issue(actual.status, index, actual.issues[0]?.message ?? "source could not be evaluated")]);
1622
- const found = [];
1623
- if (candidates(actual.term, constraint.target, found)) return makeResult("incompatible", bindings, input.variables, [issue("incompatible.shape", index, "source and target container shapes differ")]);
1624
- for (const candidate of found) {
1625
- if (context.interpreter?.typeVars?.[candidate.name] !== void 0 && !names.has(candidate.name)) continue;
1626
- if (!names.has(candidate.name)) return makeResult("rejected", bindings, input.variables, [issue("rejected.variable.undeclared", index, "target uses an undeclared type variable", candidate.name)]);
1627
- const previous = bindings[candidate.name];
1628
- if (!previous) {
1629
- bindings[candidate.name] = candidate.term;
1630
- changed = true;
1631
- continue;
1632
- }
1633
- if ((await checkTypeTermRelationAsync(candidate.term, previous, relationContext(context, bindings))).status === "assignable") continue;
1634
- if ((await checkTypeTermRelationAsync(previous, candidate.term, relationContext(context, bindings))).status === "assignable") {
1635
- bindings[candidate.name] = candidate.term;
1636
- changed = true;
1637
- continue;
1638
- }
1639
- return makeResult("unknown", bindings, input.variables, [issue("unknown.variable.join", index, "no supported unique common supertype for variable candidates", candidate.name)]);
1640
- }
1641
- }
1642
- if (!changed) break;
1643
- }
1644
- if (input.variables.some((name) => !Object.hasOwn(bindings, name))) return makeResult("unknown", bindings, input.variables, [{
1645
- code: "solver.unknown.variable.unresolved",
1646
- message: "one or more declared type variables could not be inferred"
1647
- }]);
1648
- for (const [index, constraint] of input.constraints.entries()) {
1649
- const relation = await checkTypeTermRelationAsync(constraint.source, constraint.target, relationContext(context, bindings));
1650
- if (relation.status !== "assignable") return makeResult(relation.status, bindings, input.variables, [issue(relation.status, index, relation.issues[0]?.message ?? "type relation could not be established")]);
1651
- }
1652
- return makeResult("solved", bindings, input.variables, []);
1653
- }
1654
1431
 
1655
1432
  //#endregion
1656
- export { evaluateSchemaTypeTerm as a, checkTypeTermRelationAsync as c, evaluateExpressionAsync as i, solveTypeVariablesAsync as n, evaluateSchemaTypeTermAsync as o, evaluateExpression as r, checkTypeTermRelation as s, solveTypeVariables as t };
1433
+ export { checkTypeTermRelation as i, evaluateExpression as n, evaluateSchemaTypeTerm as r, solveTypeVariables as t };