schemair 0.2.0 → 0.4.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
1
  const require_definition = require('./definition-BLLBpLKv.cjs');
2
- const require_relations = require('./relations-Cymx4iTc.cjs');
2
+ const require_schema_ref_key = require('./schema-ref-key-BHVFVfj1.cjs');
3
+ const require_relations = require('./relations-NUVJkAG8.cjs');
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 require_relations.checkSchemaRelationAsync(source, target, context.relation);
982
- if (source.kind === "record" && target.kind === "record") return require_relations.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 require_relations.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 = require_definition.validateSchemaNodeDefinition(source);
1048
- const targetSchema = require_definition.validateSchemaNodeDefinition(target);
1049
- if (sourceSchema.ok && targetSchema.ok) return require_relations.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 = require_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 = require_schema_ref_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" || !require_definition.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: require_schema_ref_key.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 = require_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" || !require_definition.expressionKinds.has(kind)) return { value };
1463
- const shape = require_definition.expressionFields[kind];
1464
- if (Object.keys(value).some((key) => !shape.allowed.includes(key)) || shape.required.some((key) => !(key in value))) return { value };
1465
- if (require_definition.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 (!require_definition.validateSchemaTypeTermDefinition(constraint.source).ok || !require_definition.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
1433
  Object.defineProperty(exports, 'checkTypeTermRelation', {
@@ -1659,45 +1436,21 @@ Object.defineProperty(exports, 'checkTypeTermRelation', {
1659
1436
  return checkTypeTermRelation;
1660
1437
  }
1661
1438
  });
1662
- Object.defineProperty(exports, 'checkTypeTermRelationAsync', {
1663
- enumerable: true,
1664
- get: function () {
1665
- return checkTypeTermRelationAsync;
1666
- }
1667
- });
1668
1439
  Object.defineProperty(exports, 'evaluateExpression', {
1669
1440
  enumerable: true,
1670
1441
  get: function () {
1671
1442
  return evaluateExpression;
1672
1443
  }
1673
1444
  });
1674
- Object.defineProperty(exports, 'evaluateExpressionAsync', {
1675
- enumerable: true,
1676
- get: function () {
1677
- return evaluateExpressionAsync;
1678
- }
1679
- });
1680
1445
  Object.defineProperty(exports, 'evaluateSchemaTypeTerm', {
1681
1446
  enumerable: true,
1682
1447
  get: function () {
1683
1448
  return evaluateSchemaTypeTerm;
1684
1449
  }
1685
1450
  });
1686
- Object.defineProperty(exports, 'evaluateSchemaTypeTermAsync', {
1687
- enumerable: true,
1688
- get: function () {
1689
- return evaluateSchemaTypeTermAsync;
1690
- }
1691
- });
1692
1451
  Object.defineProperty(exports, 'solveTypeVariables', {
1693
1452
  enumerable: true,
1694
1453
  get: function () {
1695
1454
  return solveTypeVariables;
1696
1455
  }
1697
- });
1698
- Object.defineProperty(exports, 'solveTypeVariablesAsync', {
1699
- enumerable: true,
1700
- get: function () {
1701
- return solveTypeVariablesAsync;
1702
- }
1703
1456
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "schemair",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "TypeScript wire bindings and authoring tools for SchemaIR",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://github.com/schemair/schemair#readme",
@@ -70,6 +70,16 @@
70
70
  "default": "./dist/relations/index.cjs"
71
71
  }
72
72
  },
73
+ "./compatibility": {
74
+ "import": {
75
+ "types": "./dist/compatibility/index.d.ts",
76
+ "default": "./dist/compatibility/index.js"
77
+ },
78
+ "require": {
79
+ "types": "./dist/compatibility/index.d.cts",
80
+ "default": "./dist/compatibility/index.cjs"
81
+ }
82
+ },
73
83
  "./type-interpreter": {
74
84
  "import": {
75
85
  "types": "./dist/type-interpreter/index.d.ts",
@@ -80,6 +90,16 @@
80
90
  "default": "./dist/type-interpreter/index.cjs"
81
91
  }
82
92
  },
93
+ "./resolve": {
94
+ "import": {
95
+ "types": "./dist/resolve/index.d.ts",
96
+ "default": "./dist/resolve/index.js"
97
+ },
98
+ "require": {
99
+ "types": "./dist/resolve/index.d.cts",
100
+ "default": "./dist/resolve/index.cjs"
101
+ }
102
+ },
83
103
  "./authoring": {
84
104
  "import": {
85
105
  "types": "./dist/authoring/index.d.ts",
@@ -129,8 +149,8 @@
129
149
  "prepack": "pnpm build"
130
150
  },
131
151
  "devDependencies": {
132
- "@types/node": "^22.10.0",
133
- "tsdown": "^0.18.2",
152
+ "@types/node": "^26.6.4",
153
+ "tsdown": "^0.23.0",
134
154
  "tsx": "^4.20.0",
135
155
  "typescript": "^5.7.2"
136
156
  },
@@ -1,56 +0,0 @@
1
- import { ct as SchemaNode } from "./index-4aMF0cTE.js";
2
-
3
- //#region src/payload/validator.d.ts
4
- type PayloadPath = readonly (string | number)[];
5
- interface PayloadValidationDiagnostic {
6
- readonly code: string;
7
- readonly path: PayloadPath;
8
- readonly message: string;
9
- }
10
- type PayloadValidationResult = {
11
- readonly status: 'accepted';
12
- readonly issues: readonly [];
13
- } | {
14
- readonly status: 'rejected' | 'unknown';
15
- readonly issues: readonly PayloadValidationDiagnostic[];
16
- };
17
- type PayloadProviderDecision = boolean | {
18
- readonly status: 'accepted' | 'rejected' | 'unknown' | 'unsupported';
19
- readonly message?: string;
20
- };
21
- interface PayloadProviderContext {
22
- readonly path: PayloadPath;
23
- readonly schema: SchemaNode;
24
- readonly rootSchema: SchemaNode;
25
- }
26
- interface PayloadResolutionContext extends PayloadProviderContext {
27
- readonly refPath: readonly string[];
28
- }
29
- type PayloadResolution = SchemaNode | {
30
- readonly status: 'resolved';
31
- readonly schema: SchemaNode;
32
- } | {
33
- readonly status: 'unknown' | 'unsupported';
34
- readonly message?: string;
35
- } | undefined;
36
- type SemanticProvider = (semanticPath: readonly string[], value: unknown, context: PayloadProviderContext) => PayloadProviderDecision | Promise<PayloadProviderDecision | undefined> | undefined;
37
- type ConstraintProvider = (constraintPath: readonly string[], args: unknown, value: unknown, context: PayloadProviderContext) => PayloadProviderDecision | Promise<PayloadProviderDecision | undefined> | undefined;
38
- type SyncSemanticProvider = (semanticPath: readonly string[], value: unknown, context: PayloadProviderContext) => PayloadProviderDecision | undefined;
39
- type SyncConstraintProvider = (constraintPath: readonly string[], args: unknown, value: unknown, context: PayloadProviderContext) => PayloadProviderDecision | undefined;
40
- type SyncPayloadResolution = PayloadResolution;
41
- interface SyncPayloadValidationContext {
42
- readonly resolveRef?: (refPath: readonly string[], context: PayloadResolutionContext) => SyncPayloadResolution;
43
- readonly semanticProvider?: SyncSemanticProvider;
44
- readonly constraintProvider?: SyncConstraintProvider;
45
- }
46
- interface PayloadValidationContext {
47
- readonly resolveRef?: (refPath: readonly string[], context: PayloadResolutionContext) => PayloadResolution | Promise<PayloadResolution>;
48
- readonly semanticProvider?: SemanticProvider;
49
- readonly constraintProvider?: ConstraintProvider;
50
- }
51
- /** Context accepted by the asynchronous payload validation entry point. */
52
- type AsyncPayloadValidationContext = PayloadValidationContext;
53
- declare function validatePayload(value: unknown, schema: SchemaNode, context?: SyncPayloadValidationContext): PayloadValidationResult;
54
- declare function validatePayloadAsync(value: unknown, schema: SchemaNode, context?: AsyncPayloadValidationContext): Promise<PayloadValidationResult>;
55
- //#endregion
56
- export { validatePayloadAsync as _, PayloadProviderDecision as a, PayloadValidationContext as c, SemanticProvider as d, SyncConstraintProvider as f, validatePayload as g, SyncSemanticProvider as h, PayloadProviderContext as i, PayloadValidationDiagnostic as l, SyncPayloadValidationContext as m, ConstraintProvider as n, PayloadResolution as o, SyncPayloadResolution as p, PayloadPath as r, PayloadResolutionContext as s, AsyncPayloadValidationContext as t, PayloadValidationResult as u };
@@ -1,56 +0,0 @@
1
- import { ct as SchemaNode } from "./index-DDMwVy2I.cjs";
2
-
3
- //#region src/payload/validator.d.ts
4
- type PayloadPath = readonly (string | number)[];
5
- interface PayloadValidationDiagnostic {
6
- readonly code: string;
7
- readonly path: PayloadPath;
8
- readonly message: string;
9
- }
10
- type PayloadValidationResult = {
11
- readonly status: 'accepted';
12
- readonly issues: readonly [];
13
- } | {
14
- readonly status: 'rejected' | 'unknown';
15
- readonly issues: readonly PayloadValidationDiagnostic[];
16
- };
17
- type PayloadProviderDecision = boolean | {
18
- readonly status: 'accepted' | 'rejected' | 'unknown' | 'unsupported';
19
- readonly message?: string;
20
- };
21
- interface PayloadProviderContext {
22
- readonly path: PayloadPath;
23
- readonly schema: SchemaNode;
24
- readonly rootSchema: SchemaNode;
25
- }
26
- interface PayloadResolutionContext extends PayloadProviderContext {
27
- readonly refPath: readonly string[];
28
- }
29
- type PayloadResolution = SchemaNode | {
30
- readonly status: 'resolved';
31
- readonly schema: SchemaNode;
32
- } | {
33
- readonly status: 'unknown' | 'unsupported';
34
- readonly message?: string;
35
- } | undefined;
36
- type SemanticProvider = (semanticPath: readonly string[], value: unknown, context: PayloadProviderContext) => PayloadProviderDecision | Promise<PayloadProviderDecision | undefined> | undefined;
37
- type ConstraintProvider = (constraintPath: readonly string[], args: unknown, value: unknown, context: PayloadProviderContext) => PayloadProviderDecision | Promise<PayloadProviderDecision | undefined> | undefined;
38
- type SyncSemanticProvider = (semanticPath: readonly string[], value: unknown, context: PayloadProviderContext) => PayloadProviderDecision | undefined;
39
- type SyncConstraintProvider = (constraintPath: readonly string[], args: unknown, value: unknown, context: PayloadProviderContext) => PayloadProviderDecision | undefined;
40
- type SyncPayloadResolution = PayloadResolution;
41
- interface SyncPayloadValidationContext {
42
- readonly resolveRef?: (refPath: readonly string[], context: PayloadResolutionContext) => SyncPayloadResolution;
43
- readonly semanticProvider?: SyncSemanticProvider;
44
- readonly constraintProvider?: SyncConstraintProvider;
45
- }
46
- interface PayloadValidationContext {
47
- readonly resolveRef?: (refPath: readonly string[], context: PayloadResolutionContext) => PayloadResolution | Promise<PayloadResolution>;
48
- readonly semanticProvider?: SemanticProvider;
49
- readonly constraintProvider?: ConstraintProvider;
50
- }
51
- /** Context accepted by the asynchronous payload validation entry point. */
52
- type AsyncPayloadValidationContext = PayloadValidationContext;
53
- declare function validatePayload(value: unknown, schema: SchemaNode, context?: SyncPayloadValidationContext): PayloadValidationResult;
54
- declare function validatePayloadAsync(value: unknown, schema: SchemaNode, context?: AsyncPayloadValidationContext): Promise<PayloadValidationResult>;
55
- //#endregion
56
- export { validatePayloadAsync as _, PayloadProviderDecision as a, PayloadValidationContext as c, SemanticProvider as d, SyncConstraintProvider as f, validatePayload as g, SyncSemanticProvider as h, PayloadProviderContext as i, PayloadValidationDiagnostic as l, SyncPayloadValidationContext as m, ConstraintProvider as n, PayloadResolution as o, SyncPayloadResolution as p, PayloadPath as r, PayloadResolutionContext as s, AsyncPayloadValidationContext as t, PayloadValidationResult as u };
File without changes