@json-schema-engine/core 0.0.1

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 (143) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +50 -0
  3. package/dist/coverage.d.ts +30 -0
  4. package/dist/coverage.d.ts.map +1 -0
  5. package/dist/coverage.js +81 -0
  6. package/dist/coverage.js.map +1 -0
  7. package/dist/cursor.d.ts +16 -0
  8. package/dist/cursor.d.ts.map +1 -0
  9. package/dist/cursor.js +28 -0
  10. package/dist/cursor.js.map +1 -0
  11. package/dist/dialect.d.ts +316 -0
  12. package/dist/dialect.d.ts.map +1 -0
  13. package/dist/dialect.js +135 -0
  14. package/dist/dialect.js.map +1 -0
  15. package/dist/engine.d.ts +203 -0
  16. package/dist/engine.d.ts.map +1 -0
  17. package/dist/engine.js +493 -0
  18. package/dist/engine.js.map +1 -0
  19. package/dist/index.d.ts +182 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +370 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/json.d.ts +49 -0
  24. package/dist/json.d.ts.map +1 -0
  25. package/dist/json.js +128 -0
  26. package/dist/json.js.map +1 -0
  27. package/dist/keywords/applicator.d.ts +57 -0
  28. package/dist/keywords/applicator.d.ts.map +1 -0
  29. package/dist/keywords/applicator.js +789 -0
  30. package/dist/keywords/applicator.js.map +1 -0
  31. package/dist/keywords/core.d.ts +42 -0
  32. package/dist/keywords/core.d.ts.map +1 -0
  33. package/dist/keywords/core.js +139 -0
  34. package/dist/keywords/core.js.map +1 -0
  35. package/dist/keywords/format.d.ts +43 -0
  36. package/dist/keywords/format.d.ts.map +1 -0
  37. package/dist/keywords/format.js +101 -0
  38. package/dist/keywords/format.js.map +1 -0
  39. package/dist/keywords/metaschemas2019.d.ts +3 -0
  40. package/dist/keywords/metaschemas2019.d.ts.map +1 -0
  41. package/dist/keywords/metaschemas2019.js +406 -0
  42. package/dist/keywords/metaschemas2019.js.map +1 -0
  43. package/dist/keywords/metaschemas2020.d.ts +3 -0
  44. package/dist/keywords/metaschemas2020.d.ts.map +1 -0
  45. package/dist/keywords/metaschemas2020.js +441 -0
  46. package/dist/keywords/metaschemas2020.js.map +1 -0
  47. package/dist/keywords/metaschemas6.d.ts +3 -0
  48. package/dist/keywords/metaschemas6.d.ts.map +1 -0
  49. package/dist/keywords/metaschemas6.js +221 -0
  50. package/dist/keywords/metaschemas6.js.map +1 -0
  51. package/dist/keywords/metaschemas7.d.ts +3 -0
  52. package/dist/keywords/metaschemas7.d.ts.map +1 -0
  53. package/dist/keywords/metaschemas7.js +248 -0
  54. package/dist/keywords/metaschemas7.js.map +1 -0
  55. package/dist/keywords/unevaluated.d.ts +14 -0
  56. package/dist/keywords/unevaluated.d.ts.map +1 -0
  57. package/dist/keywords/unevaluated.js +296 -0
  58. package/dist/keywords/unevaluated.js.map +1 -0
  59. package/dist/keywords/validation.d.ts +21 -0
  60. package/dist/keywords/validation.d.ts.map +1 -0
  61. package/dist/keywords/validation.js +332 -0
  62. package/dist/keywords/validation.js.map +1 -0
  63. package/dist/keywords/vocab2019.d.ts +36 -0
  64. package/dist/keywords/vocab2019.d.ts.map +1 -0
  65. package/dist/keywords/vocab2019.js +585 -0
  66. package/dist/keywords/vocab2019.js.map +1 -0
  67. package/dist/keywords/vocab2020.d.ts +20 -0
  68. package/dist/keywords/vocab2020.d.ts.map +1 -0
  69. package/dist/keywords/vocab2020.js +55 -0
  70. package/dist/keywords/vocab2020.js.map +1 -0
  71. package/dist/keywords/vocab7.d.ts +46 -0
  72. package/dist/keywords/vocab7.d.ts.map +1 -0
  73. package/dist/keywords/vocab7.js +305 -0
  74. package/dist/keywords/vocab7.js.map +1 -0
  75. package/dist/loader.d.ts +41 -0
  76. package/dist/loader.d.ts.map +1 -0
  77. package/dist/loader.js +13 -0
  78. package/dist/loader.js.map +1 -0
  79. package/dist/lowering.d.ts +371 -0
  80. package/dist/lowering.d.ts.map +1 -0
  81. package/dist/lowering.js +59 -0
  82. package/dist/lowering.js.map +1 -0
  83. package/dist/output.d.ts +251 -0
  84. package/dist/output.d.ts.map +1 -0
  85. package/dist/output.js +357 -0
  86. package/dist/output.js.map +1 -0
  87. package/dist/records.d.ts +71 -0
  88. package/dist/records.d.ts.map +1 -0
  89. package/dist/records.js +150 -0
  90. package/dist/records.js.map +1 -0
  91. package/dist/ref.d.ts +10 -0
  92. package/dist/ref.d.ts.map +1 -0
  93. package/dist/ref.js +5 -0
  94. package/dist/ref.js.map +1 -0
  95. package/dist/regex.d.ts +45 -0
  96. package/dist/regex.d.ts.map +1 -0
  97. package/dist/regex.js +163 -0
  98. package/dist/regex.js.map +1 -0
  99. package/dist/registry.d.ts +141 -0
  100. package/dist/registry.d.ts.map +1 -0
  101. package/dist/registry.js +407 -0
  102. package/dist/registry.js.map +1 -0
  103. package/dist/result.d.ts +109 -0
  104. package/dist/result.d.ts.map +1 -0
  105. package/dist/result.js +112 -0
  106. package/dist/result.js.map +1 -0
  107. package/dist/uri.d.ts +18 -0
  108. package/dist/uri.d.ts.map +1 -0
  109. package/dist/uri.js +27 -0
  110. package/dist/uri.js.map +1 -0
  111. package/dist/walk.d.ts +25 -0
  112. package/dist/walk.d.ts.map +1 -0
  113. package/dist/walk.js +65 -0
  114. package/dist/walk.js.map +1 -0
  115. package/package.json +32 -0
  116. package/src/coverage.ts +88 -0
  117. package/src/cursor.ts +42 -0
  118. package/src/dialect.ts +428 -0
  119. package/src/engine.ts +741 -0
  120. package/src/index.ts +699 -0
  121. package/src/json.ts +137 -0
  122. package/src/keywords/applicator.ts +895 -0
  123. package/src/keywords/core.ts +168 -0
  124. package/src/keywords/format.ts +143 -0
  125. package/src/keywords/metaschemas2019.ts +410 -0
  126. package/src/keywords/metaschemas2020.ts +443 -0
  127. package/src/keywords/metaschemas6.ts +226 -0
  128. package/src/keywords/metaschemas7.ts +253 -0
  129. package/src/keywords/unevaluated.ts +329 -0
  130. package/src/keywords/validation.ts +627 -0
  131. package/src/keywords/vocab2019.ts +676 -0
  132. package/src/keywords/vocab2020.ts +82 -0
  133. package/src/keywords/vocab7.ts +393 -0
  134. package/src/loader.ts +60 -0
  135. package/src/lowering.ts +414 -0
  136. package/src/output.ts +651 -0
  137. package/src/records.ts +226 -0
  138. package/src/ref.ts +14 -0
  139. package/src/regex.ts +171 -0
  140. package/src/registry.ts +481 -0
  141. package/src/result.ts +252 -0
  142. package/src/uri.ts +35 -0
  143. package/src/walk.ts +88 -0
@@ -0,0 +1,71 @@
1
+ import { AnnotationRecord, ErrorRecord, KeywordTrace, PathNode, TraceNode } from "./engine.js";
2
+ import { type AnnotationSelection, type AnnotationUnit, type ErrorUnit, type RenderInput, type RenderNode } from "./output.js";
3
+ /** The two fields of a schema reference that locate it; `node` is not needed. */
4
+ export interface LocationRef {
5
+ baseUri: string;
6
+ pointer: string;
7
+ }
8
+ /** Canonical schema location of a schema object, or of one of its keywords. */
9
+ export declare const schemaLocationOf: (ref: LocationRef, keywordName: string | null) => string;
10
+ /** Renders one error record into its native unit. */
11
+ export declare function renderError(record: ErrorRecord, includeParams?: boolean): ErrorUnit;
12
+ /** Renders one annotation record into its native unit. */
13
+ export declare function renderAnnotation(record: AnnotationRecord): AnnotationUnit;
14
+ /**
15
+ * Selects and renders annotation records in one pass: each candidate is
16
+ * rendered once and `keep` sees that unit. The survivors' records stay
17
+ * positionally paired with their units so {@link toRenderInput} can index
18
+ * them.
19
+ */
20
+ export declare function renderSelected(records: readonly AnnotationRecord[], selection: boolean | AnnotationSelection): {
21
+ records: AnnotationRecord[];
22
+ units: AnnotationUnit[];
23
+ };
24
+ /** The record arrays the flat surface was rendered from, positionally paired with {@link UnitSets}. */
25
+ export interface RecordSets {
26
+ errors: readonly ErrorRecord[];
27
+ droppedErrors: readonly ErrorRecord[];
28
+ annotations: readonly AnnotationRecord[];
29
+ droppedAnnotations: readonly AnnotationRecord[];
30
+ }
31
+ /** The flat surface's unit arrays, positionally paired with {@link RecordSets}. */
32
+ export interface UnitSets {
33
+ errors: readonly ErrorUnit[];
34
+ droppedErrors: readonly ErrorUnit[];
35
+ annotations: readonly AnnotationUnit[];
36
+ droppedAnnotations: readonly AnnotationUnit[];
37
+ }
38
+ /**
39
+ * Adapts the interpreter's trace into the located tree, materializing every
40
+ * location once per application; the index lists point into the unit
41
+ * arrays paired with `records`.
42
+ */
43
+ export declare function toRenderNode(root: TraceNode, records: RecordSets): RenderNode;
44
+ /**
45
+ * A {@link RenderNode} still being filled by its producer: the index lists
46
+ * grow as records are attributed, `valid` is settled when the application
47
+ * ends. Assignable to `RenderNode` once complete.
48
+ */
49
+ export interface MutableRenderNode extends RenderNode {
50
+ valid: boolean;
51
+ keywords: KeywordTrace[];
52
+ errors: number[];
53
+ droppedErrors: number[];
54
+ annotations: number[];
55
+ droppedAnnotations: number[];
56
+ children: MutableRenderNode[];
57
+ }
58
+ /**
59
+ * Converts a traced fragment into producer-side nodes. The evaluation path
60
+ * comes from the fragment's path chain (a compiled caller seeds it with its
61
+ * own prefix), the input location gets the caller's prefix, and `at` maps
62
+ * each path node to the nodes sharing it so the caller can attribute the
63
+ * fragment's records to their owners the way the interpreter's adapter does.
64
+ */
65
+ export declare function traceToRenderNodes(root: TraceNode, inputPrefix: string): {
66
+ root: MutableRenderNode;
67
+ at: Map<PathNode | null, MutableRenderNode[]>;
68
+ };
69
+ /** The located tree with its paired unit arrays: the renderers' input. */
70
+ export declare function toRenderInput(root: TraceNode, records: RecordSets, units: UnitSets): RenderInput;
71
+ //# sourceMappingURL=records.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"records.d.ts","sourceRoot":"","sources":["../src/records.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,gBAAgB,EAChB,WAAW,EACX,YAAY,EACZ,QAAQ,EACR,SAAS,EAEV,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,UAAU,EAGhB,MAAM,aAAa,CAAC;AAErB,iFAAiF;AACjF,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAUD,+EAA+E;AAC/E,eAAO,MAAM,gBAAgB,GAC3B,KAAK,WAAW,EAChB,aAAa,MAAM,GAAG,IAAI,KACzB,MAAsE,CAAC;AAE1E,qDAAqD;AACrD,wBAAgB,WAAW,CACzB,MAAM,EAAE,WAAW,EACnB,aAAa,UAAQ,GACpB,SAAS,CAaX;AAED,0DAA0D;AAC1D,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,GAAG,cAAc,CAWzE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,SAAS,gBAAgB,EAAE,EACpC,SAAS,EAAE,OAAO,GAAG,mBAAmB,GACvC;IAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAAC,KAAK,EAAE,cAAc,EAAE,CAAA;CAAE,CAe1D;AAED,uGAAuG;AACvG,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,SAAS,WAAW,EAAE,CAAC;IAC/B,aAAa,EAAE,SAAS,WAAW,EAAE,CAAC;IACtC,WAAW,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACzC,kBAAkB,EAAE,SAAS,gBAAgB,EAAE,CAAC;CACjD;AAED,mFAAmF;AACnF,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,SAAS,SAAS,EAAE,CAAC;IAC7B,aAAa,EAAE,SAAS,SAAS,EAAE,CAAC;IACpC,WAAW,EAAE,SAAS,cAAc,EAAE,CAAC;IACvC,kBAAkB,EAAE,SAAS,cAAc,EAAE,CAAC;CAC/C;AAmBD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,GAAG,UAAU,CAkB7E;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAkB,SAAQ,UAAU;IACnD,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,SAAS,EACf,WAAW,EAAE,MAAM,GAClB;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,EAAE,EAAE,GAAG,CAAC,QAAQ,GAAG,IAAI,EAAE,iBAAiB,EAAE,CAAC,CAAA;CAAE,CAsB5E;AAED,0EAA0E;AAC1E,wBAAgB,aAAa,CAC3B,IAAI,EAAE,SAAS,EACf,OAAO,EAAE,UAAU,EACnB,KAAK,EAAE,QAAQ,GACd,WAAW,CAQb"}
@@ -0,0 +1,150 @@
1
+ // Interpreter-side rendering: the engine's evaluation records (path-node
2
+ // chains, schema refs, cursors) become the string-located units of the flat
3
+ // surface here, and its trace becomes the located tree the document
4
+ // renderers in output.ts consume — so those renderers stay free of engine
5
+ // internals and serve any producer of a RenderInput.
6
+ import { escapeSegment } from "./json.js";
7
+ import { instancePointer } from "./cursor.js";
8
+ import { materializePath, } from "./engine.js";
9
+ import { NO_INDEXES, makeRecordPredicate, } from "./output.js";
10
+ const keywordSuffix = (name) => name === null ? "" : "/" + escapeSegment(name);
11
+ const evaluationPathOf = (pathNode, keywordName) => materializePath(pathNode) + keywordSuffix(keywordName);
12
+ /** Canonical schema location of a schema object, or of one of its keywords. */
13
+ export const schemaLocationOf = (ref, keywordName) => `${ref.baseUri}#${ref.pointer}${keywordSuffix(keywordName)}`;
14
+ /** Renders one error record into its native unit. */
15
+ export function renderError(record, includeParams = false) {
16
+ const unit = {
17
+ evaluationPath: evaluationPathOf(record.pathNode, record.keywordName),
18
+ schemaLocation: schemaLocationOf(record.schemaRef, record.keywordName),
19
+ inputLocation: instancePointer(record.cursor),
20
+ error: record.message,
21
+ };
22
+ if (includeParams) {
23
+ if (record.keywordName !== null)
24
+ unit.keyword = record.keywordName;
25
+ if (record.vocabularyUri !== null)
26
+ unit.vocabulary = record.vocabularyUri;
27
+ unit.params = record.params ?? {};
28
+ }
29
+ return unit;
30
+ }
31
+ /** Renders one annotation record into its native unit. */
32
+ export function renderAnnotation(record) {
33
+ return {
34
+ keyword: record.keywordName,
35
+ ...(record.vocabularyUri === null
36
+ ? {}
37
+ : { vocabulary: record.vocabularyUri }),
38
+ evaluationPath: evaluationPathOf(record.pathNode, record.keywordName),
39
+ schemaLocation: schemaLocationOf(record.schemaRef, record.keywordName),
40
+ inputLocation: instancePointer(record.cursor),
41
+ annotation: record.value,
42
+ };
43
+ }
44
+ /**
45
+ * Selects and renders annotation records in one pass: each candidate is
46
+ * rendered once and `keep` sees that unit. The survivors' records stay
47
+ * positionally paired with their units so {@link toRenderInput} can index
48
+ * them.
49
+ */
50
+ export function renderSelected(records, selection) {
51
+ const byLists = makeRecordPredicate(selection);
52
+ const keep = typeof selection === "object" ? selection.keep : undefined;
53
+ const kept = [];
54
+ const units = [];
55
+ for (const record of records) {
56
+ if (!byLists(record.behaviorId, record.keywordName, record.vocabularyUri)) {
57
+ continue;
58
+ }
59
+ const unit = renderAnnotation(record);
60
+ if (keep !== undefined && !keep(unit))
61
+ continue;
62
+ kept.push(record);
63
+ units.push(unit);
64
+ }
65
+ return { records: kept, units };
66
+ }
67
+ // Records attach to applications by path-node identity: every application
68
+ // mints its own PathNode, so identity is finer than the evaluation-path
69
+ // string (repeated applications of one keyword share the string). A custom
70
+ // keyword applying with no segment of its own shares its parent's node and
71
+ // therefore its parent's record group.
72
+ function indexByPath(records) {
73
+ const at = new Map();
74
+ records.forEach((r, i) => {
75
+ const list = at.get(r.pathNode);
76
+ if (list)
77
+ list.push(i);
78
+ else
79
+ at.set(r.pathNode, [i]);
80
+ });
81
+ return at;
82
+ }
83
+ /**
84
+ * Adapts the interpreter's trace into the located tree, materializing every
85
+ * location once per application; the index lists point into the unit
86
+ * arrays paired with `records`.
87
+ */
88
+ export function toRenderNode(root, records) {
89
+ const errorsAt = indexByPath(records.errors);
90
+ const droppedErrorsAt = indexByPath(records.droppedErrors);
91
+ const annotationsAt = indexByPath(records.annotations);
92
+ const droppedAnnotationsAt = indexByPath(records.droppedAnnotations);
93
+ const toNode = (node) => ({
94
+ evaluationPath: materializePath(node.pathNode),
95
+ schemaLocation: schemaLocationOf(node.schemaRef, null),
96
+ inputLocation: instancePointer(node.cursor),
97
+ valid: node.valid,
98
+ keywords: node.keywords,
99
+ errors: errorsAt.get(node.pathNode) ?? NO_INDEXES,
100
+ droppedErrors: droppedErrorsAt.get(node.pathNode) ?? NO_INDEXES,
101
+ annotations: annotationsAt.get(node.pathNode) ?? NO_INDEXES,
102
+ droppedAnnotations: droppedAnnotationsAt.get(node.pathNode) ?? NO_INDEXES,
103
+ children: node.children.map(toNode),
104
+ });
105
+ return toNode(root);
106
+ }
107
+ /**
108
+ * Converts a traced fragment into producer-side nodes. The evaluation path
109
+ * comes from the fragment's path chain (a compiled caller seeds it with its
110
+ * own prefix), the input location gets the caller's prefix, and `at` maps
111
+ * each path node to the nodes sharing it so the caller can attribute the
112
+ * fragment's records to their owners the way the interpreter's adapter does.
113
+ */
114
+ export function traceToRenderNodes(root, inputPrefix) {
115
+ const at = new Map();
116
+ const toNode = (node) => {
117
+ const out = {
118
+ evaluationPath: materializePath(node.pathNode),
119
+ schemaLocation: schemaLocationOf(node.schemaRef, null),
120
+ inputLocation: inputPrefix + instancePointer(node.cursor),
121
+ valid: node.valid,
122
+ keywords: node.keywords,
123
+ errors: [],
124
+ droppedErrors: [],
125
+ annotations: [],
126
+ droppedAnnotations: [],
127
+ children: [],
128
+ };
129
+ const sharing = at.get(node.pathNode);
130
+ if (sharing)
131
+ sharing.push(out);
132
+ else
133
+ at.set(node.pathNode, [out]);
134
+ for (const child of node.children)
135
+ out.children.push(toNode(child));
136
+ return out;
137
+ };
138
+ return { root: toNode(root), at };
139
+ }
140
+ /** The located tree with its paired unit arrays: the renderers' input. */
141
+ export function toRenderInput(root, records, units) {
142
+ return {
143
+ errors: units.errors,
144
+ droppedErrors: units.droppedErrors,
145
+ annotations: units.annotations,
146
+ droppedAnnotations: units.droppedAnnotations,
147
+ root: toRenderNode(root, records),
148
+ };
149
+ }
150
+ //# sourceMappingURL=records.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"records.js","sourceRoot":"","sources":["../src/records.ts"],"names":[],"mappings":"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"}
package/dist/ref.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ import { JsonValue } from "./json.js";
2
+ /** A schema node plus its canonical location. */
3
+ export interface SchemaRef {
4
+ node: JsonValue;
5
+ /** Canonical base URI, no fragment. */
6
+ baseUri: string;
7
+ /** JSON Pointer from the base's root schema. */
8
+ pointer: string;
9
+ }
10
+ //# sourceMappingURL=ref.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ref.d.ts","sourceRoot":"","sources":["../src/ref.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,iDAAiD;AACjD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,SAAS,CAAC;IAChB,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAC;CACjB"}
package/dist/ref.js ADDED
@@ -0,0 +1,5 @@
1
+ // A schema position: the node plus its canonical location (lexical base URI
2
+ // and JSON Pointer from that base's root schema). Kept dependency-free; both
3
+ // the dialect layer and the registry build on it.
4
+ export {};
5
+ //# sourceMappingURL=ref.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ref.js","sourceRoot":"","sources":["../src/ref.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,6EAA6E;AAC7E,kDAAkD"}
@@ -0,0 +1,45 @@
1
+ /** A compiled pattern: only membership testing is needed. */
2
+ export interface CompiledRegex {
3
+ test(input: string): boolean;
4
+ }
5
+ /** Compiles a JSON Schema `pattern` string into a {@link CompiledRegex}. */
6
+ export interface RegexEngine {
7
+ compile(pattern: string): CompiledRegex;
8
+ }
9
+ /**
10
+ * The built-in engine: ECMA-262 semantics via the native `RegExp` (unicode
11
+ * mode where valid). Fast, but subject to catastrophic backtracking on
12
+ * adversarial patterns — see {@link RegexEngine} for the linear-time opt-out.
13
+ */
14
+ export declare const defaultRegexEngine: RegexEngine;
15
+ /**
16
+ * Compiles patterns through a {@link RegexEngine}, caching by pattern string.
17
+ * One cache lives per {@link Engine}, so a pattern that appears in many
18
+ * schemas — or is tested against many instances — compiles once even when the
19
+ * engine's own compilation is expensive.
20
+ */
21
+ export declare class RegexCache {
22
+ private engine;
23
+ private cache;
24
+ constructor(engine?: RegexEngine);
25
+ compile(pattern: string): CompiledRegex;
26
+ }
27
+ /** A pattern was rejected by {@link EngineOptions.rejectUnsafeRegex}. */
28
+ export declare class UnsafeRegexError extends Error {
29
+ }
30
+ /**
31
+ * Flags regular expressions whose structure admits exponential-time
32
+ * backtracking (ReDoS). The test is star height: a repetition applied to a
33
+ * subexpression that itself contains an unbounded repetition — `(a+)+`,
34
+ * `(a*)*`, `(.*)+` — is the classic exponential shape.
35
+ *
36
+ * This is a conservative heuristic, not a proof. It targets nested unbounded
37
+ * quantifiers; it does not catch every dangerous pattern (e.g. overlapping
38
+ * alternation such as `(a|a)*`), and a linear-time engine remains the only
39
+ * hard guarantee. Safe by default when the pattern cannot be parsed.
40
+ */
41
+ export declare function detectUnsafeRegex(pattern: string): {
42
+ safe: boolean;
43
+ reason?: string;
44
+ };
45
+ //# sourceMappingURL=regex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"regex.d.ts","sourceRoot":"","sources":["../src/regex.ts"],"names":[],"mappings":"AAaA,6DAA6D;AAC7D,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;CAC9B;AAED,4EAA4E;AAC5E,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,CAAC;CACzC;AAED;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,WAEhC,CAAC;AAEF;;;;;GAKG;AACH,qBAAa,UAAU;IAGT,OAAO,CAAC,MAAM;IAF1B,OAAO,CAAC,KAAK,CAAoC;gBAE7B,MAAM,GAAE,WAAgC;IAE5D,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa;CAQxC;AAED,yEAAyE;AACzE,qBAAa,gBAAiB,SAAQ,KAAK;CAAG;AAE9C;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG;IAClD,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAoGA"}
package/dist/regex.js ADDED
@@ -0,0 +1,163 @@
1
+ // Regular-expression handling for `pattern`/`patternProperties`: a pluggable
2
+ // compile hook, a per-engine compiled-pattern cache, and a conservative
3
+ // static detector for exponential-backtracking (ReDoS) shapes.
4
+ //
5
+ // `pattern`/`patternProperties` compile untrusted regex from the schema and
6
+ // run it against untrusted instance strings. The native RegExp engine is
7
+ // vulnerable to catastrophic backtracking; callers who evaluate untrusted
8
+ // schemas can inject a linear-time engine (e.g. RE2) through `regexEngine`,
9
+ // and/or reject unsafe patterns at registration with `rejectUnsafeRegex`
10
+ // (backed by {@link detectUnsafeRegex}). See docs/guide/security.md.
11
+ import { schemaRegExp } from "./json.js";
12
+ /**
13
+ * The built-in engine: ECMA-262 semantics via the native `RegExp` (unicode
14
+ * mode where valid). Fast, but subject to catastrophic backtracking on
15
+ * adversarial patterns — see {@link RegexEngine} for the linear-time opt-out.
16
+ */
17
+ export const defaultRegexEngine = {
18
+ compile: (pattern) => schemaRegExp(pattern),
19
+ };
20
+ /**
21
+ * Compiles patterns through a {@link RegexEngine}, caching by pattern string.
22
+ * One cache lives per {@link Engine}, so a pattern that appears in many
23
+ * schemas — or is tested against many instances — compiles once even when the
24
+ * engine's own compilation is expensive.
25
+ */
26
+ export class RegexCache {
27
+ engine;
28
+ cache = new Map();
29
+ constructor(engine = defaultRegexEngine) {
30
+ this.engine = engine;
31
+ }
32
+ compile(pattern) {
33
+ let compiled = this.cache.get(pattern);
34
+ if (compiled === undefined) {
35
+ compiled = this.engine.compile(pattern);
36
+ this.cache.set(pattern, compiled);
37
+ }
38
+ return compiled;
39
+ }
40
+ }
41
+ /** A pattern was rejected by {@link EngineOptions.rejectUnsafeRegex}. */
42
+ export class UnsafeRegexError extends Error {
43
+ }
44
+ /**
45
+ * Flags regular expressions whose structure admits exponential-time
46
+ * backtracking (ReDoS). The test is star height: a repetition applied to a
47
+ * subexpression that itself contains an unbounded repetition — `(a+)+`,
48
+ * `(a*)*`, `(.*)+` — is the classic exponential shape.
49
+ *
50
+ * This is a conservative heuristic, not a proof. It targets nested unbounded
51
+ * quantifiers; it does not catch every dangerous pattern (e.g. overlapping
52
+ * alternation such as `(a|a)*`), and a linear-time engine remains the only
53
+ * hard guarantee. Safe by default when the pattern cannot be parsed.
54
+ */
55
+ export function detectUnsafeRegex(pattern) {
56
+ let i = 0;
57
+ // Parses a sequence (alternation of concatenations) up to a closing `)` or
58
+ // end of input, returning its star height.
59
+ const parseSeq = () => {
60
+ let maxHeight = 0;
61
+ while (i < pattern.length) {
62
+ const c = pattern[i];
63
+ if (c === "|") {
64
+ i++;
65
+ continue;
66
+ }
67
+ if (c === ")")
68
+ break;
69
+ let atomHeight = 0;
70
+ if (c === "\\") {
71
+ i += 2; // escaped atom
72
+ }
73
+ else if (c === "[") {
74
+ skipCharClass();
75
+ }
76
+ else if (c === "(") {
77
+ i++;
78
+ skipGroupPrefix();
79
+ atomHeight = parseSeq();
80
+ if (pattern[i] === ")")
81
+ i++;
82
+ }
83
+ else {
84
+ i++; // literal
85
+ }
86
+ const height = atomHeight + (consumeQuantifier() ? 1 : 0);
87
+ if (height > maxHeight)
88
+ maxHeight = height;
89
+ }
90
+ return maxHeight;
91
+ };
92
+ // Consumes a trailing quantifier if present; returns whether it was
93
+ // unbounded (`*`, `+`, `{n,}`). Bounded quantifiers (`?`, `{n}`, `{n,m}`)
94
+ // do not raise star height.
95
+ const consumeQuantifier = () => {
96
+ let unbounded = false;
97
+ const q = pattern[i];
98
+ if (q === "*" || q === "+") {
99
+ unbounded = true;
100
+ i++;
101
+ }
102
+ else if (q === "?") {
103
+ i++;
104
+ }
105
+ else if (q === "{") {
106
+ const close = pattern.indexOf("}", i);
107
+ if (close !== -1) {
108
+ const body = pattern.slice(i + 1, close);
109
+ i = close + 1;
110
+ unbounded = /^\s*\d+\s*,\s*$/.test(body);
111
+ }
112
+ }
113
+ // Lazy/possessive suffix does not change star height.
114
+ if (pattern[i] === "?" || pattern[i] === "+")
115
+ i++;
116
+ return unbounded;
117
+ };
118
+ const skipCharClass = () => {
119
+ i++; // opening [
120
+ if (pattern[i] === "^")
121
+ i++;
122
+ if (pattern[i] === "]")
123
+ i++; // a leading ] is literal
124
+ while (i < pattern.length && pattern[i] !== "]") {
125
+ if (pattern[i] === "\\")
126
+ i++;
127
+ i++;
128
+ }
129
+ i++; // closing ]
130
+ };
131
+ // Skips `(?:`, `(?=`, `(?!`, `(?<=`, `(?<!`, `(?<name>` prefixes.
132
+ const skipGroupPrefix = () => {
133
+ if (pattern[i] !== "?")
134
+ return;
135
+ i++;
136
+ if (pattern[i] === "<" &&
137
+ pattern[i + 1] !== "=" &&
138
+ pattern[i + 1] !== "!") {
139
+ const close = pattern.indexOf(">", i);
140
+ if (close !== -1)
141
+ i = close + 1;
142
+ return;
143
+ }
144
+ // ?:, ?=, ?!, ?<=, ?<!
145
+ i++;
146
+ if (pattern[i] === "=" || pattern[i] === "!")
147
+ i++;
148
+ };
149
+ let height;
150
+ try {
151
+ height = parseSeq();
152
+ }
153
+ catch {
154
+ return { safe: true };
155
+ }
156
+ return height >= 2
157
+ ? {
158
+ safe: false,
159
+ reason: `nested unbounded quantifier (star height ${height})`,
160
+ }
161
+ : { safe: true };
162
+ }
163
+ //# sourceMappingURL=regex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"regex.js","sourceRoot":"","sources":["../src/regex.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,wEAAwE;AACxE,+DAA+D;AAC/D,EAAE;AACF,4EAA4E;AAC5E,yEAAyE;AACzE,0EAA0E;AAC1E,4EAA4E;AAC5E,yEAAyE;AACzE,qEAAqE;AAErE,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAYzC;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAgB;IAC7C,OAAO,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC;CAC5C,CAAC;AAEF;;;;;GAKG;AACH,MAAM,OAAO,UAAU;IAGD;IAFZ,KAAK,GAAG,IAAI,GAAG,EAAyB,CAAC;IAEjD,YAAoB,SAAsB,kBAAkB;QAAxC,WAAM,GAAN,MAAM,CAAkC;IAAG,CAAC;IAEhE,OAAO,CAAC,OAAe;QACrB,IAAI,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACvC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACxC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACpC,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF;AAED,yEAAyE;AACzE,MAAM,OAAO,gBAAiB,SAAQ,KAAK;CAAG;AAE9C;;;;;;;;;;GAUG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAI/C,IAAI,CAAC,GAAG,CAAC,CAAC;IAEV,2EAA2E;IAC3E,2CAA2C;IAC3C,MAAM,QAAQ,GAAG,GAAW,EAAE;QAC5B,IAAI,SAAS,GAAG,CAAC,CAAC;QAClB,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;YAC1B,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YACrB,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;gBACd,CAAC,EAAE,CAAC;gBACJ,SAAS;YACX,CAAC;YACD,IAAI,CAAC,KAAK,GAAG;gBAAE,MAAM;YAErB,IAAI,UAAU,GAAG,CAAC,CAAC;YACnB,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;gBACf,CAAC,IAAI,CAAC,CAAC,CAAC,eAAe;YACzB,CAAC;iBAAM,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;gBACrB,aAAa,EAAE,CAAC;YAClB,CAAC;iBAAM,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;gBACrB,CAAC,EAAE,CAAC;gBACJ,eAAe,EAAE,CAAC;gBAClB,UAAU,GAAG,QAAQ,EAAE,CAAC;gBACxB,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG;oBAAE,CAAC,EAAE,CAAC;YAC9B,CAAC;iBAAM,CAAC;gBACN,CAAC,EAAE,CAAC,CAAC,UAAU;YACjB,CAAC;YAED,MAAM,MAAM,GAAG,UAAU,GAAG,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1D,IAAI,MAAM,GAAG,SAAS;gBAAE,SAAS,GAAG,MAAM,CAAC;QAC7C,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC;IAEF,oEAAoE;IACpE,0EAA0E;IAC1E,4BAA4B;IAC5B,MAAM,iBAAiB,GAAG,GAAY,EAAE;QACtC,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QACrB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;YAC3B,SAAS,GAAG,IAAI,CAAC;YACjB,CAAC,EAAE,CAAC;QACN,CAAC;aAAM,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;YACrB,CAAC,EAAE,CAAC;QACN,CAAC;aAAM,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;YACrB,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YACtC,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;gBACjB,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;gBACzC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;gBACd,SAAS,GAAG,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC;QACD,sDAAsD;QACtD,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG;YAAE,CAAC,EAAE,CAAC;QAClD,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC;IAEF,MAAM,aAAa,GAAG,GAAS,EAAE;QAC/B,CAAC,EAAE,CAAC,CAAC,YAAY;QACjB,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG;YAAE,CAAC,EAAE,CAAC;QAC5B,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG;YAAE,CAAC,EAAE,CAAC,CAAC,yBAAyB;QACtD,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YAChD,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI;gBAAE,CAAC,EAAE,CAAC;YAC7B,CAAC,EAAE,CAAC;QACN,CAAC;QACD,CAAC,EAAE,CAAC,CAAC,YAAY;IACnB,CAAC,CAAC;IAEF,kEAAkE;IAClE,MAAM,eAAe,GAAG,GAAS,EAAE;QACjC,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG;YAAE,OAAO;QAC/B,CAAC,EAAE,CAAC;QACJ,IACE,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG;YAClB,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG;YACtB,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EACtB,CAAC;YACD,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YACtC,IAAI,KAAK,KAAK,CAAC,CAAC;gBAAE,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;YAChC,OAAO;QACT,CAAC;QACD,uBAAuB;QACvB,CAAC,EAAE,CAAC;QACJ,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG;YAAE,CAAC,EAAE,CAAC;IACpD,CAAC,CAAC;IAEF,IAAI,MAAc,CAAC;IACnB,IAAI,CAAC;QACH,MAAM,GAAG,QAAQ,EAAE,CAAC;IACtB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACxB,CAAC;IACD,OAAO,MAAM,IAAI,CAAC;QAChB,CAAC,CAAC;YACE,IAAI,EAAE,KAAK;YACX,MAAM,EAAE,4CAA4C,MAAM,GAAG;SAC9D;QACH,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AACrB,CAAC"}
@@ -0,0 +1,141 @@
1
+ import { JsonValue } from "./json.js";
2
+ import { SchemaRef } from "./ref.js";
3
+ import { Dialect, DialectRegistry } from "./dialect.js";
4
+ import { SourceRange } from "./loader.js";
5
+ /**
6
+ * Where a schema resource physically lives: the registered document
7
+ * containing it and the JSON Pointer from that document's root to the
8
+ * resource's root (D17 bridge; see loader.ts).
9
+ */
10
+ export interface DocumentLocation {
11
+ documentUri: string;
12
+ pointer: string;
13
+ }
14
+ /**
15
+ * A value that is not a schema (neither an object nor a boolean) was found
16
+ * where a schema is required (D19): in a keyword-claimed schema position at
17
+ * registration, or applied as a schema during evaluation. Keyword-value
18
+ * validity beyond schema shape is not checked here — that is metaschema
19
+ * validation's job ({@link EngineOptions.validateSchemas}).
20
+ *
21
+ * When thrown during registration, the document may be partially indexed;
22
+ * re-register a corrected document under the same URI, or discard the
23
+ * engine.
24
+ */
25
+ export declare class InvalidSchemaError extends Error {
26
+ }
27
+ /**
28
+ * Schema nesting (at registration) or schema-application nesting (at
29
+ * evaluation) exceeded {@link EngineOptions.maxDepth}. A bounded, catchable
30
+ * failure that replaces the native stack overflow deep input would otherwise
31
+ * cause; the engine remains usable afterward (each evaluation runs in fresh
32
+ * state). Raise `maxDepth` for legitimately deep documents, within what the
33
+ * runtime's own stack allows.
34
+ */
35
+ export declare class MaxDepthExceededError extends Error {
36
+ }
37
+ /**
38
+ * Default schema/application nesting bound. Chosen below the native
39
+ * call-stack ceiling so the typed {@link MaxDepthExceededError} fires before
40
+ * a `RangeError`, while staying generous for real-world documents.
41
+ */
42
+ export declare const DEFAULT_MAX_DEPTH = 512;
43
+ /** One-line description of a non-schema value for error messages. */
44
+ export declare function describeNonSchema(node: JsonValue): string;
45
+ /** Schema registration, identifier indexing, and reference resolution. */
46
+ export declare class SchemaRegistry {
47
+ private dialectRegistry;
48
+ private defaultDialectUri;
49
+ private maxDepth;
50
+ private documents;
51
+ private anchors;
52
+ private dynamicAnchors;
53
+ private recursiveRoots;
54
+ private producedBehaviorIds;
55
+ private consumedBehaviorIds;
56
+ private coverageProducerIds;
57
+ private coverageConsumedIds;
58
+ private documentDialects;
59
+ private resourceLocations;
60
+ private aliases;
61
+ private pendingResources;
62
+ private documentRanges;
63
+ /**
64
+ * Called for each `pattern`/`patternProperties` regex during a
65
+ * registration walk, when set. The Engine installs this (after registering
66
+ * its trusted metaschemas) to enforce `rejectUnsafeRegex`.
67
+ */
68
+ onRegex?: (pattern: string, location: string) => void;
69
+ private shared;
70
+ private readOnly;
71
+ constructor(dialectRegistry: DialectRegistry, defaultDialectUri: string, maxDepth?: number);
72
+ /**
73
+ * A read-only view of the registry's current contents, over a view of the
74
+ * dialect registry. Later registrations on this registry are invisible to
75
+ * the view, and registering into the view throws
76
+ * {@link ReadOnlyRegistryError}. A compiled artifact binds to one so that
77
+ * a compilation boundary cannot change reference resolution (E1).
78
+ */
79
+ snapshot(): SchemaRegistry;
80
+ private mutable;
81
+ /**
82
+ * Register a schema document. The dialect comes from `$schema` when present
83
+ * (and must already be registered), else `dialectUri`, else the default.
84
+ * Returns the document's canonical base URI.
85
+ */
86
+ register(schema: JsonValue, retrievalUri: string, dialectUri?: string, getRange?: (pointer: string) => SourceRange | undefined): string;
87
+ private walk;
88
+ /**
89
+ * The registered document containing a schema resource, and the resource
90
+ * root's pointer from that document's root (D17 bridge; see loader.ts).
91
+ * Undefined for resources the registration walk never saw (e.g. an `$id`
92
+ * inside an unknown keyword reached only by pointer navigation).
93
+ */
94
+ documentLocation(resourceUri: string): DocumentLocation | undefined;
95
+ /** Source range for a document-rooted pointer, when the loader supplied one (D17). */
96
+ range(documentUri: string, pointer: string): SourceRange | undefined;
97
+ /** True if a resource is registered, directly or via a retrieval-URI alias. */
98
+ has(resourceUri: string): boolean;
99
+ /** The schema node at a resource's root, if registered. */
100
+ document(resourceUri: string): JsonValue | undefined;
101
+ /** External resources referenced but not yet registered; drained per call. */
102
+ takeUnresolved(): string[];
103
+ /** The `$dynamicAnchor` target for a name in a resource, if one was registered (D8). */
104
+ dynamicAnchor(resourceUri: string, name: string): SchemaRef | undefined;
105
+ /** True if a resource's root carries 2019-09 `$recursiveAnchor: true`. */
106
+ hasRecursiveRoot(resourceUri: string): boolean;
107
+ /** Behavior ids some registered keyword declares it produces dependency data under. */
108
+ producedIds(): ReadonlySet<string>;
109
+ /** Behavior ids some registered keyword declares it consumes. */
110
+ consumedIds(): ReadonlySet<string>;
111
+ /** The consumed subset of {@link consumedIds} whose producer declares evaluated coverage: what the coverage channel carries. */
112
+ coverageIds(): ReadonlySet<string>;
113
+ private canonical;
114
+ /**
115
+ * The dialect URI a resource was registered under.
116
+ * @throws UnresolvableRefError if the resource is not registered.
117
+ */
118
+ dialectUriFor(baseUri: string): string;
119
+ /**
120
+ * The dialect a resource was registered under.
121
+ * @throws UnresolvableRefError if the resource is not registered.
122
+ */
123
+ dialectFor(baseUri: string): Dialect;
124
+ /**
125
+ * Resolves a URI to its resource's root schema.
126
+ * @throws UnresolvableRefError if the resource is not registered.
127
+ */
128
+ rootRef(uri: string): SchemaRef;
129
+ /**
130
+ * Resolves a reference value against the referring schema's base URI.
131
+ * @throws UnresolvableRefError if the resource, anchor, or pointer target
132
+ * does not exist.
133
+ */
134
+ resolveRef(ref: string, currentBase: string): SchemaRef;
135
+ /**
136
+ * Descend from a schema position into keyword/index children, maintaining
137
+ * canonical location and lexical base.
138
+ */
139
+ child(ref: SchemaRef, segments: readonly (string | number)[]): SchemaRef;
140
+ }
141
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}