json-schema-library 11.5.1 → 11.6.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "json-schema-library",
3
- "version": "11.5.1",
3
+ "version": "11.6.1",
4
4
  "description": "Customizable and hackable json-validator and json-schema utilities for traversal, data generation and validation",
5
5
  "types": "./dist/index.d.cts",
6
6
  "exports": {
package/src/SchemaNode.ts CHANGED
@@ -551,7 +551,7 @@ export const SchemaNodeMethods = {
551
551
  schema.$id = resolveUri(schema.$id || url);
552
552
  }
553
553
 
554
- const node = this as SchemaNode;
554
+ const node = this as SchemaNode & { schemaErrors?: JsonError[]; schemaAnnotations: JsonAnnotation[] };
555
555
  const { context } = node;
556
556
  const schemaId = isJsonSchema(schema) ? (node.context.draft ?? schema.$schema) : undefined;
557
557
  const draft = getDraft(context.drafts, schemaId ?? context.rootNode.schema?.$schema);
@@ -576,7 +576,22 @@ export const SchemaNodeMethods = {
576
576
 
577
577
  remoteNode.context.rootNode = remoteNode;
578
578
  remoteNode.context.remotes[resolveUri(url)] = remoteNode;
579
- addKeywords(remoteNode);
579
+
580
+ // parse and validate schema
581
+ // @todo this is a duplicated to compileSchema
582
+ let schemaValidation = addKeywords(remoteNode).filter((err) => err != null);
583
+ schemaValidation = sanitizeErrors(schemaValidation);
584
+ const schemaErrors: JsonError[] = [];
585
+ const schemaAnnotations: JsonAnnotation[] = [];
586
+ schemaValidation.forEach((error) => {
587
+ if (isJsonError(error)) {
588
+ schemaErrors.push(error);
589
+ } else if (isJsonAnnotation(error)) {
590
+ schemaAnnotations.push(error);
591
+ }
592
+ });
593
+ node.schemaErrors = schemaErrors;
594
+ node.schemaAnnotations = schemaAnnotations;
580
595
 
581
596
  return node;
582
597
  },
@@ -631,6 +646,7 @@ export function addKeywords(node: SchemaNode) {
631
646
  ).forEach((keyword) => {
632
647
  errors.push(
633
648
  node.createAnnotation("unknown-keyword-warning", {
649
+ $id: node.$id,
634
650
  pointer: `${node.schemaLocation}/${keyword}`,
635
651
  schema: node.schema,
636
652
  value: keyword,
@@ -1,7 +1,6 @@
1
1
  import { compileSchema } from "./compileSchema";
2
2
  import { strict as assert } from "assert";
3
- import { draftEditor } from "./draftEditor";
4
- import { SchemaNode } from "./SchemaNode";
3
+ import { isSchemaNode, SchemaNode } from "./SchemaNode";
5
4
  import { draft04 } from "./draft04";
6
5
  import { draft07 } from "./draft07";
7
6
  import { draft2020 } from "./draft2020";
@@ -106,6 +105,42 @@ describe("compileSchema remotes", () => {
106
105
  const data = node.getData();
107
106
  assert.deepEqual(data, { string: "a", number: 9 });
108
107
  });
108
+
109
+ it("should resolve definition of remote schema", () => {
110
+ const node = compileSchema(
111
+ {
112
+ type: "object",
113
+ required: ["value"],
114
+ properties: {
115
+ value: { $ref: "https://remote.com/definitions.json#/$defs/property" }
116
+ }
117
+ },
118
+ {
119
+ drafts: [draft2020],
120
+ remotes: [
121
+ {
122
+ $id: "https://remote.com/definitions.json",
123
+ $defs: {
124
+ property: {
125
+ title: "remote boolean definition",
126
+ type: "boolean"
127
+ }
128
+ }
129
+ }
130
+ ]
131
+ }
132
+ );
133
+
134
+ const data = node.getData();
135
+ assert.deepEqual(data, { value: false });
136
+
137
+ const { node: valueNode } = node.getNode("#/value");
138
+ assert(isSchemaNode(valueNode), "expected returned node to be a valid SchemaNode");
139
+ assert.deepEqual(valueNode.schema, {
140
+ title: "remote boolean definition",
141
+ type: "boolean"
142
+ });
143
+ });
109
144
  });
110
145
 
111
146
  describe("compileSchema vocabulary", () => {
@@ -250,17 +285,3 @@ describe("compileSchema `schemaLocation`", () => {
250
285
  assert.deepEqual(node?.schemaLocation, "#");
251
286
  });
252
287
  });
253
-
254
- describe("compileSchema `errors`", () => {
255
- it("draftEditor come with custom minLengthOneError", () => {
256
- const { errors } = compileSchema(
257
- {
258
- type: "string",
259
- minLength: 1
260
- },
261
- { drafts: [draftEditor] }
262
- ).validate("");
263
- assert.equal(errors.length, 1);
264
- assert.deepEqual(errors[0].code, "min-length-one-error");
265
- });
266
- });
@@ -66,7 +66,7 @@ export type CompileOptions = {
66
66
  /**
67
67
  * Set node and its remote schemata as remote schemata for this node and schema to resolve $ref
68
68
  */
69
- remote?: SchemaNode;
69
+ remote?: SchemaNode & { schemaErrors?: JsonError[]; schemaAnnotations: JsonAnnotation[] };
70
70
  /**
71
71
  * a list of remotes to add, requires a unique $id for each schema. Will be ignored if `remote` is set
72
72
  */
@@ -180,11 +180,19 @@ export function compileSchema(schema: JsonSchema | BooleanSchema, options: Compi
180
180
  const schemaAnnotations: JsonAnnotation[] = [];
181
181
  schemaValidation.forEach((error) => {
182
182
  if (isJsonError(error)) {
183
+ error.data.schemaId = node.context.rootNode.$id ?? "#";
183
184
  schemaErrors.push(error);
184
185
  } else if (isJsonAnnotation(error)) {
186
+ error.data.schemaId = node.context.rootNode.$id ?? "#";
185
187
  schemaAnnotations.push(error);
186
188
  }
187
189
  });
190
+ if (Array.isArray(remote?.schemaErrors)) {
191
+ schemaErrors.push(...remote.schemaErrors);
192
+ }
193
+ if (Array.isArray(remote?.schemaAnnotations)) {
194
+ schemaAnnotations.push(...remote.schemaAnnotations);
195
+ }
188
196
 
189
197
  if (options.throwOnInvalidSchema && schemaErrors.length > 0) {
190
198
  const error = new Error("Invalid schema passed to compileSchema");