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.
- package/README.md +140 -39
- package/dist/authoring/index.d.cts +1 -1
- package/dist/authoring/index.d.ts +1 -1
- package/dist/authoring/index.js +1 -1
- package/dist/{authoring-D3V0iyTe.js → authoring-DyJNYs5o.js} +1 -1
- package/dist/compatibility/index.cjs +43 -0
- package/dist/compatibility/index.d.cts +2 -0
- package/dist/compatibility/index.d.ts +2 -0
- package/dist/compatibility/index.js +42 -0
- package/dist/definition/index.d.cts +2 -2
- package/dist/definition/index.d.ts +2 -2
- package/dist/definition/index.js +1 -1
- package/dist/{index-DDMwVy2I.d.cts → index-1sDuqu05.d.ts} +6 -1
- package/dist/index-BFSMT_2d.d.ts +53 -0
- package/dist/{index-DM5DSLLL.d.ts → index-BGz7L_Fq.d.cts} +4 -30
- package/dist/{index-bQy-C-1l.d.ts → index-BTtdqi_M.d.ts} +9 -9
- package/dist/index-BfbClf6R.d.cts +20 -0
- package/dist/{index-CQynt7ft.d.cts → index-CK7Is7vy.d.cts} +9 -9
- package/dist/index-CUGhtuwA.d.cts +53 -0
- package/dist/{index-DXWoNYFB.d.ts → index-CV8EZQy8.d.ts} +1 -1
- package/dist/index-CzNxjqVg.d.cts +47 -0
- package/dist/{index-CIim1dG7.d.cts → index-DGHMUZ5m.d.cts} +1 -1
- package/dist/{index-CBbd4hXJ.d.ts → index-DxvfPmw6.d.ts} +4 -11
- package/dist/index-T6nFhvGQ.d.ts +20 -0
- package/dist/{index-CNjYUKvu.d.cts → index-ba_52Yu9.d.cts} +4 -11
- package/dist/index-hrcM9oJe.d.ts +47 -0
- package/dist/{index-4aMF0cTE.d.ts → index-i7Au-FQ6.d.cts} +6 -1
- package/dist/{index-DhmHCGpT.d.cts → index-mu1znI1F.d.ts} +4 -30
- package/dist/index.cjs +10 -10
- package/dist/index.d.cts +9 -7
- package/dist/index.d.ts +9 -7
- package/dist/index.js +9 -7
- package/dist/integrations/json-schema/index.d.cts +1 -1
- package/dist/integrations/json-schema/index.d.ts +1 -1
- package/dist/integrations/json-schema/index.js +1 -1
- package/dist/integrations/standard-schema/index.cjs +4 -4
- package/dist/integrations/standard-schema/index.d.cts +5 -5
- package/dist/integrations/standard-schema/index.d.ts +5 -5
- package/dist/integrations/standard-schema/index.js +5 -5
- package/dist/payload/index.cjs +44 -81
- package/dist/payload/index.d.cts +2 -2
- package/dist/payload/index.d.ts +2 -2
- package/dist/payload/index.js +45 -81
- package/dist/relations/index.cjs +2 -5
- package/dist/relations/index.d.cts +2 -2
- package/dist/relations/index.d.ts +2 -2
- package/dist/relations/index.js +2 -2
- package/dist/{relations-Cymx4iTc.cjs → relations-NUVJkAG8.cjs} +11 -232
- package/dist/{relations-ysXDmi-Z.js → relations-QtnCRW9x.js} +13 -216
- package/dist/resolve/index.cjs +308 -0
- package/dist/resolve/index.d.cts +2 -0
- package/dist/resolve/index.d.ts +2 -0
- package/dist/resolve/index.js +305 -0
- package/dist/schema-ref-key-BHVFVfj1.cjs +26 -0
- package/dist/schema-ref-key-DR__tPr-.js +14 -0
- package/dist/spec/index.d.cts +2 -2
- package/dist/spec/index.d.ts +2 -2
- package/dist/spec/index.js +1 -1
- package/dist/standard/index.d.cts +2 -2
- package/dist/standard/index.d.ts +2 -2
- package/dist/standard/index.js +2 -2
- package/dist/type-interpreter/index.cjs +2 -6
- package/dist/type-interpreter/index.d.cts +2 -2
- package/dist/type-interpreter/index.d.ts +2 -2
- package/dist/type-interpreter/index.js +2 -2
- package/dist/{type-interpreter-DnrId8aM.js → type-interpreter-BA8gcLUU.js} +57 -280
- package/dist/{type-interpreter-OLt2W2yd.cjs → type-interpreter-D8xETgq1.cjs} +55 -302
- package/package.json +23 -3
- package/dist/index-BqfGAU1K.d.ts +0 -56
- package/dist/index-D3mfwaSO.d.cts +0 -56
- /package/dist/{chunk-BgLxgFZR.js → chunk-bFfwrPtJ.js} +0 -0
- /package/dist/{definition-DmYnDmQO.js → definition-BH_LzXGc.js} +0 -0
- /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
|
|
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
|
-
|
|
939
|
-
if (
|
|
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
|
-
|
|
1052
|
-
|
|
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
|
-
|
|
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]
|
|
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
|
-
|
|
1270
|
-
const
|
|
1271
|
-
if (
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
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.
|
|
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": "^
|
|
133
|
-
"tsdown": "^0.
|
|
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
|
},
|
package/dist/index-BqfGAU1K.d.ts
DELETED
|
@@ -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
|
|
File without changes
|
|
File without changes
|