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,4 +1,5 @@
|
|
|
1
|
-
import { f as validateSchemaNodeDefinition, l as validateOperationDefinition } from "./definition-
|
|
1
|
+
import { f as validateSchemaNodeDefinition, l as validateOperationDefinition } from "./definition-BH_LzXGc.js";
|
|
2
|
+
import { n as schemaRefKey, t as indexSchemaRefs } from "./schema-ref-key-DR__tPr-.js";
|
|
2
3
|
|
|
3
4
|
//#region src/relations/validator.ts
|
|
4
5
|
function equalLiteral(left, right) {
|
|
@@ -17,11 +18,13 @@ var RelationChecker = class {
|
|
|
17
18
|
activePairs = /* @__PURE__ */ new Set();
|
|
18
19
|
activeRefs = /* @__PURE__ */ new Set();
|
|
19
20
|
ids = /* @__PURE__ */ new WeakMap();
|
|
21
|
+
refIndex;
|
|
20
22
|
nextId = 1;
|
|
21
23
|
constructor(context, rootSourceSchema, rootTargetSchema) {
|
|
22
24
|
this.context = context;
|
|
23
25
|
this.rootSourceSchema = rootSourceSchema;
|
|
24
26
|
this.rootTargetSchema = rootTargetSchema;
|
|
27
|
+
this.refIndex = indexSchemaRefs(context.refs);
|
|
25
28
|
}
|
|
26
29
|
run() {
|
|
27
30
|
const result = this.compare(this.rootSourceSchema, this.rootTargetSchema, [], this.rootSourceSchema, this.rootTargetSchema);
|
|
@@ -251,8 +254,14 @@ var RelationChecker = class {
|
|
|
251
254
|
}
|
|
252
255
|
}
|
|
253
256
|
compareRef(ref, other, path, rootSource, rootTarget, side) {
|
|
254
|
-
|
|
255
|
-
|
|
257
|
+
const materialized = this.refIndex.get(schemaRefKey(ref.refPath));
|
|
258
|
+
if (materialized !== void 0) {
|
|
259
|
+
const definition$1 = validateSchemaNodeDefinition(materialized);
|
|
260
|
+
if (!definition$1.ok) return this.rejected(path, "ref.schema", "resolved ref environment contains an invalid schema");
|
|
261
|
+
return side === "source" ? this.compare(definition$1.node, other, path, rootSource, rootTarget) : this.compare(other, definition$1.node, path, rootSource, rootTarget);
|
|
262
|
+
}
|
|
263
|
+
if (!this.context.resolveRef) return this.context.refs === void 0 ? this.unknown(path, "ref.resolver", "refPath relation requires an explicit resolver") : this.unknown(path, "ref.unresolved", "refPath is not present in the resolved environment");
|
|
264
|
+
const key = `${side}:${schemaRefKey(ref.refPath)}`;
|
|
256
265
|
if (this.activeRefs.has(key)) return this.unknown(path, "ref.cycle", "refPath relation cycle could not be determined");
|
|
257
266
|
this.activeRefs.add(key);
|
|
258
267
|
let resolved;
|
|
@@ -364,210 +373,6 @@ function checkSchemaRelation(source, target, context = {}) {
|
|
|
364
373
|
return new RelationChecker(context, validSource, validTarget).run();
|
|
365
374
|
}
|
|
366
375
|
const checkSchemaAssignability = checkSchemaRelation;
|
|
367
|
-
async function resolveAsyncSchema(schema, context, active, path, side, rootSourceSchema, rootTargetSchema) {
|
|
368
|
-
if (schema.kind === "ref" && context.resolveRef) {
|
|
369
|
-
const key = schema.refPath.join("\0");
|
|
370
|
-
if (active.has(key)) return schema;
|
|
371
|
-
active.add(key);
|
|
372
|
-
let resolved;
|
|
373
|
-
try {
|
|
374
|
-
resolved = await context.resolveRef(schema.refPath, {
|
|
375
|
-
path,
|
|
376
|
-
side,
|
|
377
|
-
sourceSchema: side === "source" ? schema : rootSourceSchema,
|
|
378
|
-
targetSchema: side === "source" ? rootTargetSchema : schema,
|
|
379
|
-
rootSourceSchema,
|
|
380
|
-
rootTargetSchema,
|
|
381
|
-
refPath: schema.refPath
|
|
382
|
-
});
|
|
383
|
-
} catch {
|
|
384
|
-
return schema;
|
|
385
|
-
} finally {
|
|
386
|
-
active.delete(key);
|
|
387
|
-
}
|
|
388
|
-
if (resolved && !(typeof resolved === "object" && "status" in resolved && resolved.status !== "resolved")) {
|
|
389
|
-
const definition = validateSchemaNodeDefinition(typeof resolved === "object" && "status" in resolved ? resolved.schema : resolved);
|
|
390
|
-
if (definition.ok) return resolveAsyncSchema(definition.node, context, new Set(active), path, side, rootSourceSchema, rootTargetSchema);
|
|
391
|
-
}
|
|
392
|
-
return schema;
|
|
393
|
-
}
|
|
394
|
-
switch (schema.kind) {
|
|
395
|
-
case "record": return {
|
|
396
|
-
...schema,
|
|
397
|
-
fields: await Promise.all(schema.fields.map(async (field) => ({
|
|
398
|
-
...field,
|
|
399
|
-
schema: await resolveAsyncSchema(field.schema, context, new Set(active), [
|
|
400
|
-
...path,
|
|
401
|
-
"fields",
|
|
402
|
-
field.key
|
|
403
|
-
], side, rootSourceSchema, rootTargetSchema)
|
|
404
|
-
}))),
|
|
405
|
-
...schema.additionalFields && schema.additionalFields !== true ? { additionalFields: await resolveAsyncSchema(schema.additionalFields, context, new Set(active), [...path, "additionalFields"], side, rootSourceSchema, rootTargetSchema) } : {}
|
|
406
|
-
};
|
|
407
|
-
case "array": return {
|
|
408
|
-
...schema,
|
|
409
|
-
elementSchema: await resolveAsyncSchema(schema.elementSchema, context, new Set(active), [...path, "elementSchema"], side, rootSourceSchema, rootTargetSchema)
|
|
410
|
-
};
|
|
411
|
-
case "tuple": return {
|
|
412
|
-
...schema,
|
|
413
|
-
elementSchemas: await Promise.all(schema.elementSchemas.map((item, index) => resolveAsyncSchema(item, context, new Set(active), [
|
|
414
|
-
...path,
|
|
415
|
-
"elementSchemas",
|
|
416
|
-
index
|
|
417
|
-
], side, rootSourceSchema, rootTargetSchema)))
|
|
418
|
-
};
|
|
419
|
-
case "nullable": return {
|
|
420
|
-
...schema,
|
|
421
|
-
value: await resolveAsyncSchema(schema.value, context, new Set(active), path, side, rootSourceSchema, rootTargetSchema)
|
|
422
|
-
};
|
|
423
|
-
case "taggedUnion": return {
|
|
424
|
-
...schema,
|
|
425
|
-
variants: await Promise.all(schema.variants.map(async (variant) => ({
|
|
426
|
-
...variant,
|
|
427
|
-
schema: await resolveAsyncSchema(variant.schema, context, new Set(active), [
|
|
428
|
-
...path,
|
|
429
|
-
"variants",
|
|
430
|
-
variant.key
|
|
431
|
-
], side, rootSourceSchema, rootTargetSchema)
|
|
432
|
-
})))
|
|
433
|
-
};
|
|
434
|
-
default: return schema;
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
function collectRelationPairs(source, target, path = [], result = [], seen = /* @__PURE__ */ new Set()) {
|
|
438
|
-
const key = `${JSON.stringify(path)}:${JSON.stringify(source)}:${JSON.stringify(target)}`;
|
|
439
|
-
if (seen.has(key)) return result;
|
|
440
|
-
seen.add(key);
|
|
441
|
-
result.push({
|
|
442
|
-
source,
|
|
443
|
-
target,
|
|
444
|
-
path
|
|
445
|
-
});
|
|
446
|
-
if (source.kind === "record" && target.kind === "record") {
|
|
447
|
-
const targetFields = new Map(target.fields.map((field) => [field.key, field]));
|
|
448
|
-
for (const field of source.fields) {
|
|
449
|
-
const targetField = targetFields.get(field.key);
|
|
450
|
-
if (targetField) collectRelationPairs(field.schema, targetField.schema, [
|
|
451
|
-
...path,
|
|
452
|
-
"fields",
|
|
453
|
-
field.key
|
|
454
|
-
], result, seen);
|
|
455
|
-
}
|
|
456
|
-
} else if (source.kind === "array" && target.kind === "array") collectRelationPairs(source.elementSchema, target.elementSchema, [...path, "elementSchema"], result, seen);
|
|
457
|
-
else if (source.kind === "tuple" && target.kind === "tuple") for (let index = 0; index < Math.min(source.elementSchemas.length, target.elementSchemas.length); index += 1) collectRelationPairs(source.elementSchemas[index], target.elementSchemas[index], [
|
|
458
|
-
...path,
|
|
459
|
-
"elementSchemas",
|
|
460
|
-
index
|
|
461
|
-
], result, seen);
|
|
462
|
-
else if (source.kind === "nullable" && target.kind === "nullable") collectRelationPairs(source.value, target.value, path, result, seen);
|
|
463
|
-
else if (source.kind === "taggedUnion" && target.kind === "taggedUnion" && source.discriminator === target.discriminator) {
|
|
464
|
-
const targetVariants = new Map(target.variants.map((variant) => [variant.key, variant]));
|
|
465
|
-
for (const variant of source.variants) {
|
|
466
|
-
const targetVariant = targetVariants.get(variant.key);
|
|
467
|
-
if (targetVariant) collectRelationPairs(variant.schema, targetVariant.schema, [
|
|
468
|
-
...path,
|
|
469
|
-
"variants",
|
|
470
|
-
variant.key
|
|
471
|
-
], result, seen);
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
return result;
|
|
475
|
-
}
|
|
476
|
-
async function checkSchemaRelationAsync(source, target, context = {}) {
|
|
477
|
-
try {
|
|
478
|
-
const validSource = validateSchema(source, "source");
|
|
479
|
-
if ("status" in validSource) return validSource;
|
|
480
|
-
const validTarget = validateSchema(target, "target");
|
|
481
|
-
if ("status" in validTarget) return validTarget;
|
|
482
|
-
const resolvedSource = await resolveAsyncSchema(validSource, context, /* @__PURE__ */ new Set(), [], "source", validSource, validTarget);
|
|
483
|
-
const resolvedTarget = await resolveAsyncSchema(validTarget, context, /* @__PURE__ */ new Set(), [], "target", validSource, validTarget);
|
|
484
|
-
const pairs = collectRelationPairs(resolvedSource, resolvedTarget);
|
|
485
|
-
const semanticCache = /* @__PURE__ */ new Map();
|
|
486
|
-
const constraintCache = /* @__PURE__ */ new Map();
|
|
487
|
-
if (context.semanticProvider) for (const pair of pairs) {
|
|
488
|
-
const { source: left, target: right } = pair;
|
|
489
|
-
const sourceSemantic = left.kind === "primitive" && (left.name === "string" || left.name === "number") ? left.semanticPath : void 0;
|
|
490
|
-
const targetSemantic = right.kind === "primitive" && (right.name === "string" || right.name === "number") ? right.semanticPath : void 0;
|
|
491
|
-
if (right.kind !== "primitive" || right.name !== "string" && right.name !== "number" || sourceSemantic === void 0 && targetSemantic === void 0) continue;
|
|
492
|
-
const providerContext = {
|
|
493
|
-
path: pair.path,
|
|
494
|
-
side: "source",
|
|
495
|
-
sourceSchema: left,
|
|
496
|
-
targetSchema: right,
|
|
497
|
-
rootSourceSchema: resolvedSource,
|
|
498
|
-
rootTargetSchema: resolvedTarget
|
|
499
|
-
};
|
|
500
|
-
let decision;
|
|
501
|
-
try {
|
|
502
|
-
decision = await context.semanticProvider(sourceSemantic, targetSemantic, providerContext);
|
|
503
|
-
} catch (error) {
|
|
504
|
-
decision = {
|
|
505
|
-
status: "unknown",
|
|
506
|
-
message: `semantic provider failed: ${error instanceof Error ? error.message : String(error)}`
|
|
507
|
-
};
|
|
508
|
-
}
|
|
509
|
-
semanticCache.set(JSON.stringify([
|
|
510
|
-
pair.path,
|
|
511
|
-
sourceSemantic,
|
|
512
|
-
targetSemantic
|
|
513
|
-
]), decision);
|
|
514
|
-
}
|
|
515
|
-
if (context.constraintProvider) for (const pair of pairs) {
|
|
516
|
-
const { source: left, target: right } = pair;
|
|
517
|
-
if (left.kind === "primitive" || left.kind === "array" || left.kind === "record" || left.kind === "literal" || left.kind === "literalUnion") {
|
|
518
|
-
const literalToPrimitive = (left.kind === "literal" || left.kind === "literalUnion") && right.kind === "primitive";
|
|
519
|
-
if (right.kind !== left.kind && !literalToPrimitive) continue;
|
|
520
|
-
const sourceConstraints = "constraints" in left ? left.constraints : void 0;
|
|
521
|
-
const targetConstraints = "constraints" in right ? right.constraints : void 0;
|
|
522
|
-
if (sourceConstraints === void 0 && targetConstraints === void 0) continue;
|
|
523
|
-
const providerContext = {
|
|
524
|
-
path: pair.path,
|
|
525
|
-
side: "source",
|
|
526
|
-
sourceSchema: left,
|
|
527
|
-
targetSchema: right,
|
|
528
|
-
rootSourceSchema: resolvedSource,
|
|
529
|
-
rootTargetSchema: resolvedTarget
|
|
530
|
-
};
|
|
531
|
-
let decision;
|
|
532
|
-
try {
|
|
533
|
-
decision = await context.constraintProvider(sourceConstraints, targetConstraints, providerContext);
|
|
534
|
-
} catch (error) {
|
|
535
|
-
decision = {
|
|
536
|
-
status: "unknown",
|
|
537
|
-
message: `constraint provider failed: ${error instanceof Error ? error.message : String(error)}`
|
|
538
|
-
};
|
|
539
|
-
}
|
|
540
|
-
constraintCache.set(JSON.stringify([
|
|
541
|
-
pair.path,
|
|
542
|
-
sourceConstraints,
|
|
543
|
-
targetConstraints
|
|
544
|
-
]), decision);
|
|
545
|
-
}
|
|
546
|
-
}
|
|
547
|
-
return checkSchemaRelation(resolvedSource, resolvedTarget, {
|
|
548
|
-
semanticProvider: (sourcePath, targetPath, providerContext) => semanticCache.get(JSON.stringify([
|
|
549
|
-
providerContext.path,
|
|
550
|
-
sourcePath,
|
|
551
|
-
targetPath
|
|
552
|
-
])) ?? { status: "unknown" },
|
|
553
|
-
constraintProvider: (sourceConstraints, targetConstraints, providerContext) => constraintCache.get(JSON.stringify([
|
|
554
|
-
providerContext.path,
|
|
555
|
-
sourceConstraints,
|
|
556
|
-
targetConstraints
|
|
557
|
-
])) ?? { status: "unknown" }
|
|
558
|
-
});
|
|
559
|
-
} catch (error) {
|
|
560
|
-
return {
|
|
561
|
-
status: "unknown",
|
|
562
|
-
issues: [{
|
|
563
|
-
code: "relation.unknown.async",
|
|
564
|
-
path: [],
|
|
565
|
-
message: `async relation provider failed: ${error instanceof Error ? error.message : String(error)}`
|
|
566
|
-
}]
|
|
567
|
-
};
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
const checkSchemaAssignabilityAsync = checkSchemaRelationAsync;
|
|
571
376
|
|
|
572
377
|
//#endregion
|
|
573
378
|
//#region src/relations/operation.ts
|
|
@@ -701,14 +506,6 @@ function checkOperationRelation(source, target, context = {}) {
|
|
|
701
506
|
if (!Array.isArray(work)) return work;
|
|
702
507
|
return combine(work.map((item) => "result" in item ? item.result : prefix(checkSchemaRelation(item.source, item.target, context), item.path)));
|
|
703
508
|
}
|
|
704
|
-
/** Async companion with the same substitution rules and schema-local providers. */
|
|
705
|
-
async function checkOperationRelationAsync(source, target, context = {}) {
|
|
706
|
-
const work = prepare(source, target);
|
|
707
|
-
if (!Array.isArray(work)) return work;
|
|
708
|
-
const results = [];
|
|
709
|
-
for (const item of work) results.push("result" in item ? item.result : prefix(await checkSchemaRelationAsync(item.source, item.target, context), item.path));
|
|
710
|
-
return combine(results);
|
|
711
|
-
}
|
|
712
509
|
|
|
713
510
|
//#endregion
|
|
714
|
-
export {
|
|
511
|
+
export { checkSchemaAssignability as n, checkSchemaRelation as r, checkOperationRelation as t };
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
const require_definition = require('../definition-BLLBpLKv.cjs');
|
|
2
|
+
const require_schema_ref_key = require('../schema-ref-key-BHVFVfj1.cjs');
|
|
3
|
+
|
|
4
|
+
//#region src/resolve/schema-closure.ts
|
|
5
|
+
var AsyncResolverError = class extends Error {};
|
|
6
|
+
function isObject(value) {
|
|
7
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8
|
+
}
|
|
9
|
+
function refNode(value) {
|
|
10
|
+
if (!isObject(value) || value.kind !== "ref" || !Array.isArray(value.refPath) || value.refPath.some((part) => typeof part !== "string")) return void 0;
|
|
11
|
+
return value;
|
|
12
|
+
}
|
|
13
|
+
function issue(status, code, path, message) {
|
|
14
|
+
return {
|
|
15
|
+
code: `closure.${status}.${code}`,
|
|
16
|
+
path,
|
|
17
|
+
message
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function children(value, basePath) {
|
|
21
|
+
if (Array.isArray(value)) return value.map((child, index) => ({
|
|
22
|
+
value: child,
|
|
23
|
+
path: basePath.length === 0 && index === 0 ? [] : [index]
|
|
24
|
+
}));
|
|
25
|
+
if (!isObject(value)) return [];
|
|
26
|
+
if (value.kind === "record" && Array.isArray(value.fields)) {
|
|
27
|
+
const fields = value.fields.flatMap((field) => {
|
|
28
|
+
if (!isObject(field) || typeof field.key !== "string" || !("schema" in field)) return [];
|
|
29
|
+
return [{
|
|
30
|
+
value: field.schema,
|
|
31
|
+
path: ["fields", field.key]
|
|
32
|
+
}];
|
|
33
|
+
});
|
|
34
|
+
if (value.additionalFields !== void 0 && value.additionalFields !== true) fields.push({
|
|
35
|
+
value: value.additionalFields,
|
|
36
|
+
path: ["additionalFields"]
|
|
37
|
+
});
|
|
38
|
+
return fields;
|
|
39
|
+
}
|
|
40
|
+
if (value.kind === "recordOf" && Array.isArray(value.fields)) {
|
|
41
|
+
const fields = value.fields.flatMap((field) => {
|
|
42
|
+
if (!isObject(field) || typeof field.key !== "string" || !("value" in field)) return [];
|
|
43
|
+
return [{
|
|
44
|
+
value: field.value,
|
|
45
|
+
path: ["fields", field.key]
|
|
46
|
+
}];
|
|
47
|
+
});
|
|
48
|
+
if (value.additionalFields !== void 0 && value.additionalFields !== true) fields.push({
|
|
49
|
+
value: value.additionalFields,
|
|
50
|
+
path: ["additionalFields"]
|
|
51
|
+
});
|
|
52
|
+
return fields;
|
|
53
|
+
}
|
|
54
|
+
if ((value.kind === "taggedUnion" || value.kind === "taggedUnionOf") && Array.isArray(value.variants)) {
|
|
55
|
+
const member = value.kind === "taggedUnion" ? "schema" : "value";
|
|
56
|
+
return value.variants.flatMap((variant) => {
|
|
57
|
+
if (!isObject(variant) || typeof variant.key !== "string" || !(member in variant)) return [];
|
|
58
|
+
return [{
|
|
59
|
+
value: variant[member],
|
|
60
|
+
path: ["variants", variant.key]
|
|
61
|
+
}];
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
const members = {
|
|
65
|
+
array: ["elementSchema"],
|
|
66
|
+
tuple: ["elementSchemas"],
|
|
67
|
+
nullable: ["value"],
|
|
68
|
+
arrayOf: ["element"],
|
|
69
|
+
tupleOf: ["elements"],
|
|
70
|
+
nullableOf: ["value"],
|
|
71
|
+
maybeAbsent: ["value"],
|
|
72
|
+
typeVar: ["extends"],
|
|
73
|
+
mergeRecords: ["sources"],
|
|
74
|
+
intersect: ["sources"],
|
|
75
|
+
elementOf: ["source"],
|
|
76
|
+
valueOf: ["source"],
|
|
77
|
+
elementAt: ["source"],
|
|
78
|
+
fieldOf: ["source"],
|
|
79
|
+
keyOf: ["source"],
|
|
80
|
+
fieldsOf: ["source"],
|
|
81
|
+
pickFields: ["source"],
|
|
82
|
+
omitFields: ["source"],
|
|
83
|
+
partialFields: ["source"],
|
|
84
|
+
requiredFields: ["source"],
|
|
85
|
+
excludeVariants: ["source"],
|
|
86
|
+
extractVariants: ["source"],
|
|
87
|
+
structured: ["schema"]
|
|
88
|
+
};
|
|
89
|
+
if (typeof value.kind === "string") {
|
|
90
|
+
const edges$1 = (Object.hasOwn(members, value.kind) ? members[value.kind] : []).filter((key) => key in value).map((key) => ({
|
|
91
|
+
value: value[key],
|
|
92
|
+
path: [key]
|
|
93
|
+
}));
|
|
94
|
+
if (value.kind === "refine") {
|
|
95
|
+
edges$1.push({
|
|
96
|
+
value: value.source,
|
|
97
|
+
path: ["source"]
|
|
98
|
+
});
|
|
99
|
+
if (Array.isArray(value.fields)) value.fields.forEach((field, index) => {
|
|
100
|
+
if (isObject(field) && "intersectWith" in field) edges$1.push({
|
|
101
|
+
value: field.intersectWith,
|
|
102
|
+
path: [
|
|
103
|
+
"fields",
|
|
104
|
+
index,
|
|
105
|
+
"intersectWith"
|
|
106
|
+
]
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
return edges$1;
|
|
111
|
+
}
|
|
112
|
+
const edges = [];
|
|
113
|
+
for (const key of [
|
|
114
|
+
"input",
|
|
115
|
+
"output",
|
|
116
|
+
"data"
|
|
117
|
+
]) if (key in value) edges.push({
|
|
118
|
+
value: value[key],
|
|
119
|
+
path: [key]
|
|
120
|
+
});
|
|
121
|
+
for (const key of [
|
|
122
|
+
"errors",
|
|
123
|
+
"emits",
|
|
124
|
+
"operations",
|
|
125
|
+
"containers"
|
|
126
|
+
]) if (isObject(value[key])) for (const [name, child] of Object.entries(value[key])) edges.push({
|
|
127
|
+
value: child,
|
|
128
|
+
path: [key, name]
|
|
129
|
+
});
|
|
130
|
+
return edges;
|
|
131
|
+
}
|
|
132
|
+
/** Recursively load all external schema references reachable from an entry,
|
|
133
|
+
* preserving reference paths and recording cycles rather than inlining refs.
|
|
134
|
+
* Yielding host requests lets both execution modes use identical traversal state. */
|
|
135
|
+
function* loadReferences(entry, context) {
|
|
136
|
+
const refs = /* @__PURE__ */ new Map();
|
|
137
|
+
for (const ref of context.refs ?? []) refs.set(require_schema_ref_key.schemaRefKey(ref.refPath), {
|
|
138
|
+
refPath: [...ref.refPath],
|
|
139
|
+
schema: ref.schema
|
|
140
|
+
});
|
|
141
|
+
const active = /* @__PURE__ */ new Set();
|
|
142
|
+
const visited = /* @__PURE__ */ new Set();
|
|
143
|
+
const objects = /* @__PURE__ */ new Set();
|
|
144
|
+
const cycles = /* @__PURE__ */ new Map();
|
|
145
|
+
const issues = [];
|
|
146
|
+
let steps = 0;
|
|
147
|
+
let nodes = 0;
|
|
148
|
+
let rejected = false;
|
|
149
|
+
let incomplete = false;
|
|
150
|
+
function* walk(value, path, depth) {
|
|
151
|
+
steps += 1;
|
|
152
|
+
if (steps > (context.maxSteps ?? 1e4) || depth > (context.maxDepth ?? 64)) {
|
|
153
|
+
incomplete = true;
|
|
154
|
+
issues.push(issue("incomplete", "budget", path, "schema closure work budget exceeded"));
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
if (isObject(value) && value.kind === "ref" && !require_definition.validateSchemaNodeDefinition(value).ok) {
|
|
158
|
+
rejected = true;
|
|
159
|
+
issues.push(issue("rejected", "schema", path, "reference must be a valid SchemaNode"));
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const ref = refNode(value);
|
|
163
|
+
if (ref) {
|
|
164
|
+
const key = require_schema_ref_key.schemaRefKey(ref.refPath);
|
|
165
|
+
if (active.has(key)) {
|
|
166
|
+
cycles.set(key, [...ref.refPath]);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
if (visited.has(key)) return;
|
|
170
|
+
active.add(key);
|
|
171
|
+
try {
|
|
172
|
+
const preloaded = refs.get(key);
|
|
173
|
+
if (preloaded !== void 0) {
|
|
174
|
+
if (!require_definition.validateSchemaNodeDefinition(preloaded.schema).ok) {
|
|
175
|
+
rejected = true;
|
|
176
|
+
issues.push(issue("rejected", "schema", path, "preloaded ref did not contain a valid SchemaNode"));
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
visited.add(key);
|
|
180
|
+
yield* walk(preloaded.schema, path, depth + 1);
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
if (nodes >= (context.maxNodes ?? 1e4)) {
|
|
184
|
+
incomplete = true;
|
|
185
|
+
issues.push(issue("incomplete", "nodes", path, "schema closure node budget exceeded"));
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
let resolution;
|
|
189
|
+
if (!context.resolveRef) {
|
|
190
|
+
incomplete = true;
|
|
191
|
+
issues.push(issue("incomplete", "unresolved", path, "refPath is not present in the resolved environment"));
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
try {
|
|
195
|
+
resolution = yield {
|
|
196
|
+
refPath: ref.refPath,
|
|
197
|
+
context: {
|
|
198
|
+
path,
|
|
199
|
+
refPath: ref.refPath,
|
|
200
|
+
ref,
|
|
201
|
+
depth
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
} catch (error) {
|
|
205
|
+
incomplete = true;
|
|
206
|
+
issues.push(issue("incomplete", error instanceof AsyncResolverError ? "resolver.async" : "resolver", path, `refPath resolver failed: ${error instanceof Error ? error.message : String(error)}`));
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
if (!resolution) {
|
|
210
|
+
incomplete = true;
|
|
211
|
+
issues.push(issue("incomplete", "unresolved", path, "refPath resolver returned no schema"));
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
if (typeof resolution === "object" && "status" in resolution && resolution.status !== "resolved") {
|
|
215
|
+
incomplete = true;
|
|
216
|
+
issues.push(issue("incomplete", `ref.${resolution.status}`, path, resolution.message ?? "refPath resolver could not determine this path"));
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
const definition = require_definition.validateSchemaNodeDefinition(typeof resolution === "object" && "status" in resolution ? resolution.schema : resolution);
|
|
220
|
+
if (!definition.ok) {
|
|
221
|
+
rejected = true;
|
|
222
|
+
issues.push(issue("rejected", "schema", path, "resolved ref did not contain a valid SchemaNode"));
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
refs.set(key, {
|
|
226
|
+
refPath: [...ref.refPath],
|
|
227
|
+
schema: definition.node
|
|
228
|
+
});
|
|
229
|
+
nodes += 1;
|
|
230
|
+
visited.add(key);
|
|
231
|
+
yield* walk(definition.node, path, depth + 1);
|
|
232
|
+
} finally {
|
|
233
|
+
active.delete(key);
|
|
234
|
+
}
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
if (!isObject(value) && !Array.isArray(value)) return;
|
|
238
|
+
if (objects.has(value)) {
|
|
239
|
+
incomplete = true;
|
|
240
|
+
issues.push(issue("incomplete", "cycle.data", path, "input contains an object cycle"));
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
objects.add(value);
|
|
244
|
+
try {
|
|
245
|
+
for (const child of children(value, path)) yield* walk(child.value, [...path, ...child.path], depth + 1);
|
|
246
|
+
} finally {
|
|
247
|
+
objects.delete(value);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
yield* walk(entry, [], 0);
|
|
251
|
+
return {
|
|
252
|
+
status: rejected ? "rejected" : incomplete ? "incomplete" : "resolved",
|
|
253
|
+
graph: {
|
|
254
|
+
refs: [...refs.values()],
|
|
255
|
+
cycles: [...cycles.values()].sort((left, right) => require_schema_ref_key.schemaRefKey(left).localeCompare(require_schema_ref_key.schemaRefKey(right)))
|
|
256
|
+
},
|
|
257
|
+
issues
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
/** Load references using a synchronous host resolver. */
|
|
261
|
+
function resolveSchemaReferences(entry, context = {}) {
|
|
262
|
+
const traversal = loadReferences(entry, context);
|
|
263
|
+
let step = traversal.next();
|
|
264
|
+
while (!step.done) {
|
|
265
|
+
let resolution;
|
|
266
|
+
try {
|
|
267
|
+
resolution = context.resolveRef(step.value.refPath, step.value.context);
|
|
268
|
+
if (resolution && typeof resolution === "object" && "then" in resolution && typeof resolution.then === "function") {
|
|
269
|
+
if (resolution instanceof Promise) resolution.catch(() => {});
|
|
270
|
+
throw new AsyncResolverError("reference loading requires a synchronous resolver; use resolveSchemaReferencesAsync");
|
|
271
|
+
}
|
|
272
|
+
} catch (error) {
|
|
273
|
+
step = traversal.throw(error);
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
step = traversal.next(resolution);
|
|
277
|
+
}
|
|
278
|
+
return step.value;
|
|
279
|
+
}
|
|
280
|
+
/** Load references using a synchronous or asynchronous host resolver. */
|
|
281
|
+
async function resolveSchemaReferencesAsync(entry, context = {}) {
|
|
282
|
+
const traversal = loadReferences(entry, context);
|
|
283
|
+
let step = traversal.next();
|
|
284
|
+
while (!step.done) {
|
|
285
|
+
let resolution;
|
|
286
|
+
try {
|
|
287
|
+
resolution = await context.resolveRef(step.value.refPath, step.value.context);
|
|
288
|
+
} catch (error) {
|
|
289
|
+
step = traversal.throw(error);
|
|
290
|
+
continue;
|
|
291
|
+
}
|
|
292
|
+
step = traversal.next(resolution);
|
|
293
|
+
}
|
|
294
|
+
return step.value;
|
|
295
|
+
}
|
|
296
|
+
/** Resolve all external schema refs reachable from an operation declaration. */
|
|
297
|
+
function resolveOperationClosure(entry, context = {}) {
|
|
298
|
+
return resolveSchemaReferences(entry, context);
|
|
299
|
+
}
|
|
300
|
+
async function resolveOperationClosureAsync(entry, context = {}) {
|
|
301
|
+
return resolveSchemaReferencesAsync(entry, context);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
//#endregion
|
|
305
|
+
exports.resolveOperationClosure = resolveOperationClosure;
|
|
306
|
+
exports.resolveOperationClosureAsync = resolveOperationClosureAsync;
|
|
307
|
+
exports.resolveSchemaReferences = resolveSchemaReferences;
|
|
308
|
+
exports.resolveSchemaReferencesAsync = resolveSchemaReferencesAsync;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as SchemaClosureResolutionContext, c as SchemaRefResolution, d as resolveSchemaReferences, f as resolveSchemaReferencesAsync, i as SchemaClosureDiagnostic, l as resolveOperationClosure, n as ResolvedSchemaGraph, o as SchemaClosureResult, r as SchemaClosureContext, s as SchemaClosureStatus, t as AsyncSchemaClosureContext, u as resolveOperationClosureAsync } from "../index-CUGhtuwA.cjs";
|
|
2
|
+
export { AsyncSchemaClosureContext, ResolvedSchemaGraph, SchemaClosureContext, SchemaClosureDiagnostic, SchemaClosureResolutionContext, SchemaClosureResult, SchemaClosureStatus, SchemaRefResolution, resolveOperationClosure, resolveOperationClosureAsync, resolveSchemaReferences, resolveSchemaReferencesAsync };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as SchemaClosureResolutionContext, c as SchemaRefResolution, d as resolveSchemaReferences, f as resolveSchemaReferencesAsync, i as SchemaClosureDiagnostic, l as resolveOperationClosure, n as ResolvedSchemaGraph, o as SchemaClosureResult, r as SchemaClosureContext, s as SchemaClosureStatus, t as AsyncSchemaClosureContext, u as resolveOperationClosureAsync } from "../index-BFSMT_2d.js";
|
|
2
|
+
export { AsyncSchemaClosureContext, ResolvedSchemaGraph, SchemaClosureContext, SchemaClosureDiagnostic, SchemaClosureResolutionContext, SchemaClosureResult, SchemaClosureStatus, SchemaRefResolution, resolveOperationClosure, resolveOperationClosureAsync, resolveSchemaReferences, resolveSchemaReferencesAsync };
|