@hyperjump/json-schema 1.9.9 → 1.10.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/README.md CHANGED
@@ -201,6 +201,9 @@ Schema, such as `@hyperjump/json-schema/draft-2020-12`.
201
201
  * **unregisterSchema**: (uri: string) => void
202
202
 
203
203
  Remove a schema from the local schema registry.
204
+ * **hasSchema**: (uri: string) => boolean
205
+
206
+ Check if a schema with the given URI is already registered.
204
207
  * _(deprecated)_ **addSchema**: (schema: object, retrievalUri?: string, defaultDialectId?: string) => void
205
208
 
206
209
  Load a schema manually rather than fetching it from the filesystem or over
package/lib/common.js CHANGED
@@ -19,9 +19,10 @@ export const jsonTypeOf = (value) => {
19
19
  } else if (Object.getPrototypeOf(value) === Object.prototype) {
20
20
  return "object";
21
21
  }
22
- default:
22
+ default: {
23
23
  const type = jsType === "object" ? Object.getPrototypeOf(value).constructor.name || "anonymous" : jsType;
24
24
  throw Error(`Not a JSON compatible type: ${type}`);
25
+ }
25
26
  }
26
27
  };
27
28
 
@@ -59,8 +59,8 @@ export const getKeywordName: (dialectId: string, keywordId: string) => string;
59
59
  export const getKeyword: <A>(id: string) => Keyword<A>;
60
60
  export const getKeywordByName: <A>(keywordName: string, dialectId: string) => Keyword<A>;
61
61
  export const getKeywordId: (keywordName: string, dialectId: string) => string;
62
- export const defineVocabulary: (id: string, keywords: { [keyword: string]: string }) => void;
63
- export const loadDialect: (dialectId: string, dialect: { [vocabularyId: string]: boolean }, allowUnknownKeywords?: boolean) => void;
62
+ export const defineVocabulary: (id: string, keywords: Record<string, string>) => void;
63
+ export const loadDialect: (dialectId: string, dialect: Record<string, boolean>, allowUnknownKeywords?: boolean) => void;
64
64
  export const unloadDialect: (dialectId: string) => void;
65
65
  export const hasDialect: (dialectId: string) => boolean;
66
66
 
package/lib/index.d.ts CHANGED
@@ -2,12 +2,13 @@ import type { Json } from "@hyperjump/json-pointer";
2
2
 
3
3
 
4
4
  export type SchemaFragment = string | number | boolean | null | SchemaObject | SchemaFragment[];
5
- export type SchemaObject = {
5
+ export type SchemaObject = { // eslint-disable-line @typescript-eslint/consistent-indexed-object-style
6
6
  [keyword: string]: SchemaFragment;
7
7
  };
8
8
 
9
9
  export const registerSchema: (schema: SchemaObject | boolean, retrievalUri?: string, contextDialectId?: string) => void;
10
10
  export const unregisterSchema: (retrievalUri: string) => void;
11
+ export const hasSchema: (uri: string) => boolean;
11
12
 
12
13
  /**
13
14
  * @deprecated since 1.7.0. Use registerSchema instead.
package/lib/index.js CHANGED
@@ -130,7 +130,7 @@ addKeyword(vocabulary);
130
130
  addKeyword(writeOnly);
131
131
 
132
132
  export { addSchema, unregisterSchema, validate, FLAG } from "./core.js";
133
- export { registerSchema } from "./schema.js";
133
+ export { registerSchema, hasSchema } from "./schema.js";
134
134
  export {
135
135
  getMetaSchemaOutputFormat,
136
136
  setMetaSchemaOutputFormat,
package/lib/instance.js CHANGED
@@ -34,9 +34,10 @@ export const fromJs = (value, uri = "", pointer = "", parent = undefined) => {
34
34
  } else if (value instanceof Reference) {
35
35
  return fromJs(value.toJSON(), uri, pointer, parent);
36
36
  }
37
- default:
37
+ default: {
38
38
  const type = jsType === "object" ? Object.getPrototypeOf(value).constructor.name || "anonymous" : jsType;
39
39
  throw Error(`Not a JSON compatible type: ${type}`);
40
+ }
40
41
  }
41
42
  };
42
43
 
@@ -77,14 +78,16 @@ export const has = (key, node) => key in node.value;
77
78
 
78
79
  export const step = (key, node) => {
79
80
  switch (node.type) {
80
- case "object":
81
+ case "object": {
81
82
  const property = node.children.find((propertyNode) => {
82
83
  return value(propertyNode.children[0]) === key;
83
84
  });
84
85
  return property?.children[1];
85
- case "array":
86
+ }
87
+ case "array": {
86
88
  const index = parseInt(key, 10);
87
89
  return node.children[index];
90
+ }
88
91
  default:
89
92
  return;
90
93
  }
package/lib/keywords.js CHANGED
@@ -36,6 +36,7 @@ export const defineVocabulary = (id, keywords) => {
36
36
 
37
37
  const _dialects = {};
38
38
  const _allowUnknownKeywords = {};
39
+ const _persistentDialects = {};
39
40
 
40
41
  export const getKeywordId = (keyword, dialectId) => getDialect(dialectId)?.[keyword]
41
42
  || (_allowUnknownKeywords[dialectId] || keyword.startsWith("x-"))
@@ -60,8 +61,9 @@ const getDialect = (dialectId) => {
60
61
 
61
62
  export const hasDialect = (dialectId) => dialectId in _dialects;
62
63
 
63
- export const loadDialect = (dialectId, dialect, allowUnknownKeywords = false) => {
64
+ export const loadDialect = (dialectId, dialect, allowUnknownKeywords = false, isPersistent = true) => {
64
65
  _allowUnknownKeywords[dialectId] = allowUnknownKeywords;
66
+ _persistentDialects[dialectId] = _persistentDialects[dialectId] || isPersistent;
65
67
 
66
68
  _dialects[dialectId] = {};
67
69
  Object.entries(dialect)
@@ -77,12 +79,16 @@ export const loadDialect = (dialectId, dialect, allowUnknownKeywords = false) =>
77
79
  });
78
80
  } else if (!allowUnknownKeywords || isRequired) {
79
81
  delete _dialects[dialectId];
82
+ delete _allowUnknownKeywords[dialectId];
83
+ delete _persistentDialects[dialectId];
80
84
  throw Error(`Unrecognized vocabulary: ${vocabularyId}. You can define this vocabulary with the 'defineVocabulary' function.`);
81
85
  }
82
86
  });
83
87
  };
84
88
 
85
89
  export const unloadDialect = (dialectId) => {
86
- delete _allowUnknownKeywords[dialectId];
87
- delete _dialects[dialectId];
90
+ if (!_persistentDialects[dialectId]) {
91
+ delete _allowUnknownKeywords[dialectId];
92
+ delete _dialects[dialectId];
93
+ }
88
94
  };
package/lib/schema.js CHANGED
@@ -14,7 +14,7 @@ export const schemaPlugin = {
14
14
 
15
15
  return buildSchemaDocument(await response.json(), response.url, contextDialectId);
16
16
  },
17
- fileMatcher: (path) => /(\.|\/)schema\.json$/.test(path)
17
+ fileMatcher: async (path) => /(\.|\/)schema\.json$/.test(path)
18
18
  };
19
19
 
20
20
  const schemaRegistry = {};
@@ -59,6 +59,8 @@ export const unregisterSchema = (uri) => {
59
59
  delete schemaRegistry[normalizedUri];
60
60
  };
61
61
 
62
+ export const hasSchema = (uri) => uri in schemaRegistry;
63
+
62
64
  export const buildSchemaDocument = (schema, id, dialectId, embedded = {}) => {
63
65
  // Dialect / JSON Schema Version
64
66
  if (typeof schema.$schema === "string") {
@@ -91,7 +93,7 @@ export const buildSchemaDocument = (schema, id, dialectId, embedded = {}) => {
91
93
  const allowUnknownKeywords = schema[vocabularyToken]["https://json-schema.org/draft/2019-09/vocab/core"]
92
94
  || schema[vocabularyToken]["https://json-schema.org/draft/2020-12/vocab/core"];
93
95
 
94
- loadDialect(id, schema[vocabularyToken], allowUnknownKeywords);
96
+ loadDialect(id, schema[vocabularyToken], allowUnknownKeywords, false);
95
97
  delete schema[vocabularyToken];
96
98
  }
97
99
 
@@ -69,7 +69,7 @@ type OpenApi = {
69
69
  };
70
70
 
71
71
  type Reference = {
72
- $ref: "string"
72
+ $ref: "string";
73
73
  };
74
74
 
75
75
  type Info = {
@@ -86,11 +86,11 @@ type Xml = {
86
86
  };
87
87
 
88
88
  export type OpenApi = {
89
- openapi: string
89
+ openapi: string;
90
90
  info: Info;
91
91
  jsonSchemaDialect?: string;
92
92
  servers?: Server[];
93
- security?: SecurityRequirement[]
93
+ security?: SecurityRequirement[];
94
94
  tags?: Tag[];
95
95
  externalDocs?: ExternalDocumentation;
96
96
  paths?: Record<string, PathItem>;
@@ -227,7 +227,7 @@ type Callbacks = Record<string, PathItem | Reference>;
227
227
  type Example = {
228
228
  summary?: string;
229
229
  description?: string;
230
- value?: Json,
230
+ value?: Json;
231
231
  externalValue?: string;
232
232
  };
233
233
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyperjump/json-schema",
3
- "version": "1.9.9",
3
+ "version": "1.10.1",
4
4
  "description": "A JSON Schema validator with support for custom keywords, vocabularies, and dialects",
5
5
  "type": "module",
6
6
  "main": "./stable/index.js",
@@ -50,19 +50,16 @@
50
50
  "url": "https://github.com/sponsors/jdesrosiers"
51
51
  },
52
52
  "devDependencies": {
53
+ "@stylistic/eslint-plugin": "*",
53
54
  "@types/content-type": "*",
54
55
  "@types/node": "*",
55
56
  "@types/uuid": "*",
56
- "@typescript-eslint/eslint-plugin": "*",
57
- "@typescript-eslint/parser": "*",
58
57
  "@vitest/coverage-v8": "*",
59
- "eslint": "*",
60
- "eslint-import-resolver-exports": "*",
61
- "eslint-import-resolver-node": "*",
62
58
  "eslint-import-resolver-typescript": "*",
63
59
  "eslint-plugin-import": "*",
64
60
  "json-schema-test-suite": "github:json-schema-org/JSON-Schema-Test-Suite",
65
61
  "typescript": "*",
62
+ "typescript-eslint": "*",
66
63
  "undici": "*",
67
64
  "vitest": "*",
68
65
  "yaml": "*"