@maroonedog/luq 2.5.0 → 2.7.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 +35 -8
- package/dist/chain/slot-type-guard.js +20 -6
- package/dist/chain/slot-type-guard.mjs +20 -6
- package/dist/compile/resolve-presence.js +36 -5
- package/dist/compile/resolve-presence.mjs +36 -5
- package/dist/json-schema/assert-supported-dialect.d.ts +37 -0
- package/dist/json-schema/assert-supported-dialect.js +113 -0
- package/dist/json-schema/assert-supported-dialect.mjs +109 -0
- package/dist/json-schema/build-from-schema.d.ts +22 -3
- package/dist/json-schema/build-from-schema.js +27 -5
- package/dist/json-schema/build-from-schema.mjs +27 -5
- package/dist/json-schema/declare-value-keywords.d.ts +0 -2
- package/dist/json-schema/declare-value-keywords.js +7 -10
- package/dist/json-schema/declare-value-keywords.mjs +7 -9
- package/dist/json-schema/extensions/json-schema/index.d.ts +2 -2
- package/dist/json-schema/extensions/json-schema/index.js +3 -1
- package/dist/json-schema/extensions/json-schema/index.mjs +1 -1
- package/dist/json-schema/extensions/json-schema/json-schema.d.ts +2 -2
- package/dist/json-schema/extensions/json-schema/json-schema.js +3 -0
- package/dist/json-schema/extensions/json-schema/json-schema.mjs +4 -1
- package/dist/json-schema/extensions/json-schema-full-feature/bundle-coverage.js +6 -1
- package/dist/json-schema/extensions/json-schema-full-feature/bundle-coverage.mjs +6 -1
- package/dist/json-schema/extensions/json-schema-full-feature/index.d.ts +3 -1
- package/dist/json-schema/extensions/json-schema-full-feature/index.js +18 -1
- package/dist/json-schema/extensions/json-schema-full-feature/index.mjs +11 -0
- package/dist/json-schema/extensions/json-schema-full-feature/json-schema-full-feature.d.ts +9 -1
- package/dist/json-schema/extensions/json-schema-full-feature/json-schema-full-feature.js +9 -2
- package/dist/json-schema/extensions/json-schema-full-feature/json-schema-full-feature.mjs +9 -2
- package/dist/json-schema/index.d.ts +3 -0
- package/dist/json-schema/index.js +7 -1
- package/dist/json-schema/index.mjs +2 -0
- package/dist/json-schema/keyword-map-core.js +3 -1
- package/dist/json-schema/keyword-map-core.mjs +3 -1
- package/dist/json-schema/keyword-map.js +3 -0
- package/dist/json-schema/keyword-map.mjs +3 -0
- package/dist/json-schema/schema-to-declarations.js +1 -4
- package/dist/json-schema/schema-to-declarations.mjs +2 -5
- package/dist/json-schema/unsupported-dialect-error.d.ts +21 -0
- package/dist/json-schema/unsupported-dialect-error.js +58 -0
- package/dist/json-schema/unsupported-dialect-error.mjs +54 -0
- package/dist/runtime/create-issue.d.ts +9 -0
- package/dist/runtime/create-issue.js +9 -2
- package/dist/runtime/create-issue.mjs +9 -2
- package/dist/runtime/run-field.js +1 -0
- package/dist/runtime/run-field.mjs +1 -0
- package/dist/types/index.d.ts +12 -0
- package/package.json +20 -8
|
@@ -6,6 +6,7 @@ exports.buildFromSchema = buildFromSchema;
|
|
|
6
6
|
exports.fromJsonSchema = fromJsonSchema;
|
|
7
7
|
const create_field_builder_1 = require("../builder/create-field-builder");
|
|
8
8
|
const type_erasure_1 = require("../core/type-erasure");
|
|
9
|
+
const assert_supported_dialect_1 = require("./assert-supported-dialect");
|
|
9
10
|
const create_structural_context_1 = require("./create-structural-context");
|
|
10
11
|
const declare_presence_1 = require("./declare-presence");
|
|
11
12
|
const ref_scope_1 = require("./ref-scope");
|
|
@@ -35,9 +36,12 @@ function collectDeclaredRules(declaration, bag, root, chain) {
|
|
|
35
36
|
]);
|
|
36
37
|
}
|
|
37
38
|
/** One pending `.v()` per declared path, with its callback still unrun. */
|
|
38
|
-
function buildFieldEntries(bag, schema) {
|
|
39
|
+
function buildFieldEntries(bag, schema, options = {}) {
|
|
39
40
|
if (!(0, draft07_types_1.isDraft07Schema)(schema))
|
|
40
41
|
throw new NotASchemaError(schema);
|
|
42
|
+
// Before any keyword is read: what the document's keywords MEAN depends on
|
|
43
|
+
// the dialect it declares, and Luq reads every one of them as Draft-07.
|
|
44
|
+
(0, assert_supported_dialect_1.assertSupportedDialect)(schema, options);
|
|
41
45
|
return (0, flatten_schema_1.flattenSchema)(schema, schema_to_declarations_1.readChildSchemas).map((declaration) => ({
|
|
42
46
|
path: declaration.path,
|
|
43
47
|
defaultOf: null,
|
|
@@ -53,10 +57,28 @@ function buildFieldEntries(bag, schema) {
|
|
|
53
57
|
}));
|
|
54
58
|
}
|
|
55
59
|
/** The erased front door: the declarations, with nothing compiled yet. */
|
|
56
|
-
function buildFromSchema(bag, schema, config) {
|
|
57
|
-
return (0, create_field_builder_1.createFieldBuilderSurface)(bag, config, buildFieldEntries(bag, schema));
|
|
60
|
+
function buildFromSchema(bag, schema, config, options) {
|
|
61
|
+
return (0, create_field_builder_1.createFieldBuilderSurface)(bag, config, buildFieldEntries(bag, schema, options));
|
|
58
62
|
}
|
|
59
63
|
/**
|
|
64
|
+
* Converts a JSON Schema document into a validator.
|
|
65
|
+
*
|
|
66
|
+
* THE INPUT LIMIT IS DRAFT-07, and it is a limit on what may be handed in, not
|
|
67
|
+
* only a statement of how much of Draft-07 is covered. A document declaring
|
|
68
|
+
* 2019-09 or 2020-12 in its root `$schema` is REFUSED with an
|
|
69
|
+
* `UnsupportedDialectError` rather than read as Draft-07, because the two
|
|
70
|
+
* dialects disagree about what an unchanged keyword means: from 2019-09 on
|
|
71
|
+
* `$ref` is an ordinary applicator whose siblings are applied, while Draft-07
|
|
72
|
+
* §8.3 replaces the node, so `{"$ref": "#/$defs/name", "minLength": 5}` read as
|
|
73
|
+
* Draft-07 loses the `minLength` and accepts a value the document forbids. A
|
|
74
|
+
* document with NO `$schema` is read as Draft-07 and always has been. Pass
|
|
75
|
+
* `{ assumeDraft07: true }` as the fourth argument to read a newer-dialect
|
|
76
|
+
* document under Draft-07 rules deliberately, with that reading's consequences.
|
|
77
|
+
*
|
|
78
|
+
* `T` defaults to `Record<string, unknown>`, never `any`; under the default NO
|
|
79
|
+
* declared path is checked. See the header of this file, which owns that
|
|
80
|
+
* escape hatch.
|
|
81
|
+
*
|
|
60
82
|
* The declared type is put back on by `eraseSchemaValidator`, the fourth
|
|
61
83
|
* function in src/core/type-erasure.ts — the one file the code standard allows
|
|
62
84
|
* to assert. Step 25 expressed this as an OVERLOAD PAIR instead, because
|
|
@@ -64,7 +86,7 @@ function buildFromSchema(bag, schema, config) {
|
|
|
64
86
|
* TypeScript on lenient compatibility rules and so was never audited anywhere.
|
|
65
87
|
* The call below is, in the file where every escape hatch is reviewed together.
|
|
66
88
|
*/
|
|
67
|
-
function fromJsonSchema(bag, schema, config) {
|
|
68
|
-
const planBacked = buildFromSchema(bag, schema, config).build();
|
|
89
|
+
function fromJsonSchema(bag, schema, config, options) {
|
|
90
|
+
const planBacked = buildFromSchema(bag, schema, config, options).build();
|
|
69
91
|
return (0, type_erasure_1.eraseSchemaValidator)(planBacked);
|
|
70
92
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createFieldBuilderSurface } from "../builder/create-field-builder.mjs";
|
|
2
2
|
import { eraseSchemaValidator } from "../core/type-erasure.mjs";
|
|
3
|
+
import { assertSupportedDialect } from "./assert-supported-dialect.mjs";
|
|
3
4
|
import { createStructuralContext } from "./create-structural-context.mjs";
|
|
4
5
|
import { declarePresenceRules } from "./declare-presence.mjs";
|
|
5
6
|
import { createLocalScope } from "./ref-scope.mjs";
|
|
@@ -28,9 +29,12 @@ function collectDeclaredRules(declaration, bag, root, chain) {
|
|
|
28
29
|
]);
|
|
29
30
|
}
|
|
30
31
|
/** One pending `.v()` per declared path, with its callback still unrun. */
|
|
31
|
-
export function buildFieldEntries(bag, schema) {
|
|
32
|
+
export function buildFieldEntries(bag, schema, options = {}) {
|
|
32
33
|
if (!isDraft07Schema(schema))
|
|
33
34
|
throw new NotASchemaError(schema);
|
|
35
|
+
// Before any keyword is read: what the document's keywords MEAN depends on
|
|
36
|
+
// the dialect it declares, and Luq reads every one of them as Draft-07.
|
|
37
|
+
assertSupportedDialect(schema, options);
|
|
34
38
|
return flattenSchema(schema, readChildSchemas).map((declaration) => ({
|
|
35
39
|
path: declaration.path,
|
|
36
40
|
defaultOf: null,
|
|
@@ -46,10 +50,28 @@ export function buildFieldEntries(bag, schema) {
|
|
|
46
50
|
}));
|
|
47
51
|
}
|
|
48
52
|
/** The erased front door: the declarations, with nothing compiled yet. */
|
|
49
|
-
export function buildFromSchema(bag, schema, config) {
|
|
50
|
-
return createFieldBuilderSurface(bag, config, buildFieldEntries(bag, schema));
|
|
53
|
+
export function buildFromSchema(bag, schema, config, options) {
|
|
54
|
+
return createFieldBuilderSurface(bag, config, buildFieldEntries(bag, schema, options));
|
|
51
55
|
}
|
|
52
56
|
/**
|
|
57
|
+
* Converts a JSON Schema document into a validator.
|
|
58
|
+
*
|
|
59
|
+
* THE INPUT LIMIT IS DRAFT-07, and it is a limit on what may be handed in, not
|
|
60
|
+
* only a statement of how much of Draft-07 is covered. A document declaring
|
|
61
|
+
* 2019-09 or 2020-12 in its root `$schema` is REFUSED with an
|
|
62
|
+
* `UnsupportedDialectError` rather than read as Draft-07, because the two
|
|
63
|
+
* dialects disagree about what an unchanged keyword means: from 2019-09 on
|
|
64
|
+
* `$ref` is an ordinary applicator whose siblings are applied, while Draft-07
|
|
65
|
+
* §8.3 replaces the node, so `{"$ref": "#/$defs/name", "minLength": 5}` read as
|
|
66
|
+
* Draft-07 loses the `minLength` and accepts a value the document forbids. A
|
|
67
|
+
* document with NO `$schema` is read as Draft-07 and always has been. Pass
|
|
68
|
+
* `{ assumeDraft07: true }` as the fourth argument to read a newer-dialect
|
|
69
|
+
* document under Draft-07 rules deliberately, with that reading's consequences.
|
|
70
|
+
*
|
|
71
|
+
* `T` defaults to `Record<string, unknown>`, never `any`; under the default NO
|
|
72
|
+
* declared path is checked. See the header of this file, which owns that
|
|
73
|
+
* escape hatch.
|
|
74
|
+
*
|
|
53
75
|
* The declared type is put back on by `eraseSchemaValidator`, the fourth
|
|
54
76
|
* function in src/core/type-erasure.ts — the one file the code standard allows
|
|
55
77
|
* to assert. Step 25 expressed this as an OVERLOAD PAIR instead, because
|
|
@@ -57,7 +79,7 @@ export function buildFromSchema(bag, schema, config) {
|
|
|
57
79
|
* TypeScript on lenient compatibility rules and so was never audited anywhere.
|
|
58
80
|
* The call below is, in the file where every escape hatch is reviewed together.
|
|
59
81
|
*/
|
|
60
|
-
export function fromJsonSchema(bag, schema, config) {
|
|
61
|
-
const planBacked = buildFromSchema(bag, schema, config).build();
|
|
82
|
+
export function fromJsonSchema(bag, schema, config, options) {
|
|
83
|
+
const planBacked = buildFromSchema(bag, schema, config, options).build();
|
|
62
84
|
return eraseSchemaValidator(planBacked);
|
|
63
85
|
}
|
|
@@ -20,8 +20,6 @@ export declare function permitsNull(schema: Draft07SchemaObject): boolean;
|
|
|
20
20
|
* that fails all of them.
|
|
21
21
|
*/
|
|
22
22
|
export declare function declareTypeRules(schema: Draft07SchemaObject, context: StructuralContext): readonly Rule[];
|
|
23
|
-
/** `type: "integer"` is the only `type` member that adds a chain method. */
|
|
24
|
-
export declare function declareIntegerRules(schema: Draft07SchemaObject, context: StructuralContext): readonly Rule[];
|
|
25
23
|
export declare function declareConstRules(schema: Draft07SchemaObject, context: StructuralContext): readonly Rule[];
|
|
26
24
|
/**
|
|
27
25
|
* `enum` drives the `.oneOf()` METHOD, which is a different thing from the
|
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.readDeclaredTypes = readDeclaredTypes;
|
|
4
4
|
exports.permitsNull = permitsNull;
|
|
5
5
|
exports.declareTypeRules = declareTypeRules;
|
|
6
|
-
exports.declareIntegerRules = declareIntegerRules;
|
|
7
6
|
exports.declareConstRules = declareConstRules;
|
|
8
7
|
exports.declareEnumRules = declareEnumRules;
|
|
9
8
|
// ===========================================================================
|
|
@@ -41,6 +40,13 @@ const NO_RULES = Object.freeze([]);
|
|
|
41
40
|
const JSON_TYPE_TESTS = {
|
|
42
41
|
string: types_1.isString,
|
|
43
42
|
number: (value) => typeof value === "number",
|
|
43
|
+
// The whole of `type: "integer"`. A second rule built from the numberInteger
|
|
44
|
+
// plugin used to run beside this one with its code overridden to `type`,
|
|
45
|
+
// which put two issues coded `type` at one path for one value — and (path,
|
|
46
|
+
// code) is the pair a machine consumer de-duplicates on, so one of them
|
|
47
|
+
// disappeared without trace. This test is the same predicate the plugin
|
|
48
|
+
// applies, so removing the second rule changed no verdict: the conformance
|
|
49
|
+
// corpus stayed at 929 / 929.
|
|
44
50
|
integer: (value) => typeof value === "number" && Number.isInteger(value),
|
|
45
51
|
boolean: (value) => typeof value === "boolean",
|
|
46
52
|
array: types_1.isArray,
|
|
@@ -126,15 +132,6 @@ function declareTypeRules(schema, context) {
|
|
|
126
132
|
}),
|
|
127
133
|
]);
|
|
128
134
|
}
|
|
129
|
-
/** `type: "integer"` is the only `type` member that adds a chain method. */
|
|
130
|
-
function declareIntegerRules(schema, context) {
|
|
131
|
-
if (!readDeclaredTypes(schema).includes("integer"))
|
|
132
|
-
return NO_RULES;
|
|
133
|
-
const plugin = context.bag.numberInteger;
|
|
134
|
-
return Object.freeze([
|
|
135
|
-
plugin.build(context.ruleContextFor(plugin.name, "type")),
|
|
136
|
-
]);
|
|
137
|
-
}
|
|
138
135
|
function declareConstRules(schema, context) {
|
|
139
136
|
if (!Object.prototype.hasOwnProperty.call(schema, "const"))
|
|
140
137
|
return NO_RULES;
|
|
@@ -33,6 +33,13 @@ const NO_RULES = Object.freeze([]);
|
|
|
33
33
|
const JSON_TYPE_TESTS = {
|
|
34
34
|
string: isString,
|
|
35
35
|
number: (value) => typeof value === "number",
|
|
36
|
+
// The whole of `type: "integer"`. A second rule built from the numberInteger
|
|
37
|
+
// plugin used to run beside this one with its code overridden to `type`,
|
|
38
|
+
// which put two issues coded `type` at one path for one value — and (path,
|
|
39
|
+
// code) is the pair a machine consumer de-duplicates on, so one of them
|
|
40
|
+
// disappeared without trace. This test is the same predicate the plugin
|
|
41
|
+
// applies, so removing the second rule changed no verdict: the conformance
|
|
42
|
+
// corpus stayed at 929 / 929.
|
|
36
43
|
integer: (value) => typeof value === "number" && Number.isInteger(value),
|
|
37
44
|
boolean: (value) => typeof value === "boolean",
|
|
38
45
|
array: isArray,
|
|
@@ -118,15 +125,6 @@ export function declareTypeRules(schema, context) {
|
|
|
118
125
|
}),
|
|
119
126
|
]);
|
|
120
127
|
}
|
|
121
|
-
/** `type: "integer"` is the only `type` member that adds a chain method. */
|
|
122
|
-
export function declareIntegerRules(schema, context) {
|
|
123
|
-
if (!readDeclaredTypes(schema).includes("integer"))
|
|
124
|
-
return NO_RULES;
|
|
125
|
-
const plugin = context.bag.numberInteger;
|
|
126
|
-
return Object.freeze([
|
|
127
|
-
plugin.build(context.ruleContextFor(plugin.name, "type")),
|
|
128
|
-
]);
|
|
129
|
-
}
|
|
130
128
|
export function declareConstRules(schema, context) {
|
|
131
129
|
if (!Object.prototype.hasOwnProperty.call(schema, "const"))
|
|
132
130
|
return NO_RULES;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { SCHEMA_BRANCH_LABEL, collectDocumentRules, jsonSchemaPlugin, } from "./json-schema";
|
|
2
2
|
export type { JsonSchemaOptions } from "./json-schema";
|
|
3
|
-
export { MalformedSchemaError, NotASchemaError, UnsupportedKeywordError, RefResolutionError, buildFieldEntries, buildFromSchema, fromJsonSchema, isDraft07Schema, listBoundPluginNames, listDraft07Keywords, listFormatNames, } from "../../index";
|
|
4
|
-
export type { Draft07Schema, Draft07SchemaObject, JsonSchemaBag, } from "../../index";
|
|
3
|
+
export { DRAFT07_DIALECT_URI, MalformedSchemaError, NotASchemaError, UnsupportedDialectError, UnsupportedKeywordError, RefResolutionError, buildFieldEntries, buildFromSchema, fromJsonSchema, isDraft07Schema, listBoundPluginNames, listDraft07Keywords, listFormatNames, } from "../../index";
|
|
4
|
+
export type { DialectOptions, Draft07Schema, Draft07SchemaObject, JsonSchemaBag, } from "../../index";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.listFormatNames = exports.listDraft07Keywords = exports.listBoundPluginNames = exports.isDraft07Schema = exports.fromJsonSchema = exports.buildFromSchema = exports.buildFieldEntries = exports.RefResolutionError = exports.UnsupportedKeywordError = exports.NotASchemaError = exports.MalformedSchemaError = exports.jsonSchemaPlugin = exports.collectDocumentRules = exports.SCHEMA_BRANCH_LABEL = void 0;
|
|
3
|
+
exports.listFormatNames = exports.listDraft07Keywords = exports.listBoundPluginNames = exports.isDraft07Schema = exports.fromJsonSchema = exports.buildFromSchema = exports.buildFieldEntries = exports.RefResolutionError = exports.UnsupportedKeywordError = exports.UnsupportedDialectError = exports.NotASchemaError = exports.MalformedSchemaError = exports.DRAFT07_DIALECT_URI = exports.jsonSchemaPlugin = exports.collectDocumentRules = exports.SCHEMA_BRANCH_LABEL = void 0;
|
|
4
4
|
// ===========================================================================
|
|
5
5
|
// The public subpath `@maroonedog/luq/plugins/jsonSchema`. Re-exports only.
|
|
6
6
|
//
|
|
@@ -15,8 +15,10 @@ Object.defineProperty(exports, "SCHEMA_BRANCH_LABEL", { enumerable: true, get: f
|
|
|
15
15
|
Object.defineProperty(exports, "collectDocumentRules", { enumerable: true, get: function () { return json_schema_1.collectDocumentRules; } });
|
|
16
16
|
Object.defineProperty(exports, "jsonSchemaPlugin", { enumerable: true, get: function () { return json_schema_1.jsonSchemaPlugin; } });
|
|
17
17
|
var index_1 = require("../../index");
|
|
18
|
+
Object.defineProperty(exports, "DRAFT07_DIALECT_URI", { enumerable: true, get: function () { return index_1.DRAFT07_DIALECT_URI; } });
|
|
18
19
|
Object.defineProperty(exports, "MalformedSchemaError", { enumerable: true, get: function () { return index_1.MalformedSchemaError; } });
|
|
19
20
|
Object.defineProperty(exports, "NotASchemaError", { enumerable: true, get: function () { return index_1.NotASchemaError; } });
|
|
21
|
+
Object.defineProperty(exports, "UnsupportedDialectError", { enumerable: true, get: function () { return index_1.UnsupportedDialectError; } });
|
|
20
22
|
Object.defineProperty(exports, "UnsupportedKeywordError", { enumerable: true, get: function () { return index_1.UnsupportedKeywordError; } });
|
|
21
23
|
Object.defineProperty(exports, "RefResolutionError", { enumerable: true, get: function () { return index_1.RefResolutionError; } });
|
|
22
24
|
Object.defineProperty(exports, "buildFieldEntries", { enumerable: true, get: function () { return index_1.buildFieldEntries; } });
|
|
@@ -8,4 +8,4 @@
|
|
|
8
8
|
// a consumer of this subpath pays only for the plugins they import themselves.
|
|
9
9
|
// ===========================================================================
|
|
10
10
|
export { SCHEMA_BRANCH_LABEL, collectDocumentRules, jsonSchemaPlugin, } from "./json-schema.mjs";
|
|
11
|
-
export { MalformedSchemaError, NotASchemaError, UnsupportedKeywordError, RefResolutionError, buildFieldEntries, buildFromSchema, fromJsonSchema, isDraft07Schema, listBoundPluginNames, listDraft07Keywords, listFormatNames, } from "../../index.mjs";
|
|
11
|
+
export { DRAFT07_DIALECT_URI, MalformedSchemaError, NotASchemaError, UnsupportedDialectError, UnsupportedKeywordError, RefResolutionError, buildFieldEntries, buildFromSchema, fromJsonSchema, isDraft07Schema, listBoundPluginNames, listDraft07Keywords, listFormatNames, } from "../../index.mjs";
|
|
@@ -2,7 +2,7 @@ import type { Rule } from "../../../plugin-kit/compiled-rule";
|
|
|
2
2
|
import { type MessageContextExtra, type TypeName } from "../../../types";
|
|
3
3
|
import type { RuleBuildContext } from "../../../plugin-kit/rule-build-context";
|
|
4
4
|
import type { Unchanged } from "../../../plugin-kit/marker.types";
|
|
5
|
-
import { type JsonSchemaBag } from "../../index";
|
|
5
|
+
import { type DialectOptions, type JsonSchemaBag } from "../../index";
|
|
6
6
|
/** The label the whole document carries inside the composite it becomes. */
|
|
7
7
|
export declare const SCHEMA_BRANCH_LABEL = "schema";
|
|
8
8
|
/**
|
|
@@ -17,7 +17,7 @@ export declare const SCHEMA_BRANCH_LABEL = "schema";
|
|
|
17
17
|
* The caller fetches, reads from disk, or bundles — whichever is right for
|
|
18
18
|
* their deployment — and hands over what they already have.
|
|
19
19
|
*/
|
|
20
|
-
export interface JsonSchemaOptions {
|
|
20
|
+
export interface JsonSchemaOptions extends DialectOptions {
|
|
21
21
|
readonly externalDocuments?: Readonly<Record<string, unknown>> | undefined;
|
|
22
22
|
}
|
|
23
23
|
/**
|
|
@@ -66,6 +66,9 @@ const NO_EXTERNAL_DOCUMENTS = Object.freeze({});
|
|
|
66
66
|
function collectDocumentRules(ctx, document, bag, options = {}) {
|
|
67
67
|
if (!(0, index_1.isDraft07Schema)(document))
|
|
68
68
|
throw new index_1.NotASchemaError(document);
|
|
69
|
+
// Before any keyword is read, and in the same place the function front door
|
|
70
|
+
// reads it: the dialect decides what the keywords below MEAN.
|
|
71
|
+
(0, index_1.assertSupportedDialect)(document, options);
|
|
69
72
|
const root = document;
|
|
70
73
|
const scope = (0, index_1.createDocumentScope)(root, options.externalDocuments ?? NO_EXTERNAL_DOCUMENTS);
|
|
71
74
|
// The seed's `chain` is a ChainBuildContext, whose three members a
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
import { branch, composite } from "../../../plugin-kit/create-rule.mjs";
|
|
39
39
|
import { definePlugin } from "../../../plugin-kit/plugin-definition.mjs";
|
|
40
40
|
import { PASS } from "../../../types/index.mjs";
|
|
41
|
-
import { NotASchemaError, collectSubSchemaRules, createStructuralContext, createDocumentScope, isDraft07Schema, resolveSchemaNodeInScope, } from "../../index.mjs";
|
|
41
|
+
import { NotASchemaError, assertSupportedDialect, collectSubSchemaRules, createStructuralContext, createDocumentScope, isDraft07Schema, resolveSchemaNodeInScope, } from "../../index.mjs";
|
|
42
42
|
/** Every slot: a JSON Schema document constrains a value of any shape. */
|
|
43
43
|
const SCHEMA_SLOTS = [
|
|
44
44
|
"string",
|
|
@@ -62,6 +62,9 @@ const NO_EXTERNAL_DOCUMENTS = Object.freeze({});
|
|
|
62
62
|
export function collectDocumentRules(ctx, document, bag, options = {}) {
|
|
63
63
|
if (!isDraft07Schema(document))
|
|
64
64
|
throw new NotASchemaError(document);
|
|
65
|
+
// Before any keyword is read, and in the same place the function front door
|
|
66
|
+
// reads it: the dialect decides what the keywords below MEAN.
|
|
67
|
+
assertSupportedDialect(document, options);
|
|
65
68
|
const root = document;
|
|
66
69
|
const scope = createDocumentScope(root, options.externalDocuments ?? NO_EXTERNAL_DOCUMENTS);
|
|
67
70
|
// The seed's `chain` is a ChainBuildContext, whose three members a
|
|
@@ -44,7 +44,6 @@ exports.UNBOUND_BUNDLED_PLUGIN_NAMES = Object.freeze([
|
|
|
44
44
|
"arrayContains",
|
|
45
45
|
"arrayEach",
|
|
46
46
|
"conditionalSchema",
|
|
47
|
-
"numberInteger",
|
|
48
47
|
"objectAdditionalPropertiesSchema",
|
|
49
48
|
"objectDependentRequired",
|
|
50
49
|
"objectDependentSchemas",
|
|
@@ -53,6 +52,12 @@ exports.UNBOUND_BUNDLED_PLUGIN_NAMES = Object.freeze([
|
|
|
53
52
|
"oneOf",
|
|
54
53
|
// Reachable only from a hand-written chain; the converter never calls them.
|
|
55
54
|
"compareField",
|
|
55
|
+
// numberInteger moved into this group when the converter stopped building a
|
|
56
|
+
// second rule from it for `type: "integer"`: the type table's own predicate
|
|
57
|
+
// is `Number.isInteger`, so the plugin's rule only ever duplicated it. It
|
|
58
|
+
// stays in the bag because `.integer()` is still a method a hand-written
|
|
59
|
+
// chain can call.
|
|
60
|
+
"numberInteger",
|
|
56
61
|
"nullable",
|
|
57
62
|
"optional",
|
|
58
63
|
"tupleBuilder",
|
|
@@ -37,7 +37,6 @@ export const UNBOUND_BUNDLED_PLUGIN_NAMES = Object.freeze([
|
|
|
37
37
|
"arrayContains",
|
|
38
38
|
"arrayEach",
|
|
39
39
|
"conditionalSchema",
|
|
40
|
-
"numberInteger",
|
|
41
40
|
"objectAdditionalPropertiesSchema",
|
|
42
41
|
"objectDependentRequired",
|
|
43
42
|
"objectDependentSchemas",
|
|
@@ -46,6 +45,12 @@ export const UNBOUND_BUNDLED_PLUGIN_NAMES = Object.freeze([
|
|
|
46
45
|
"oneOf",
|
|
47
46
|
// Reachable only from a hand-written chain; the converter never calls them.
|
|
48
47
|
"compareField",
|
|
48
|
+
// numberInteger moved into this group when the converter stopped building a
|
|
49
|
+
// second rule from it for `type: "integer"`: the type table's own predicate
|
|
50
|
+
// is `Number.isInteger`, so the plugin's rule only ever duplicated it. It
|
|
51
|
+
// stays in the bag because `.integer()` is still a method a hand-written
|
|
52
|
+
// chain can call.
|
|
53
|
+
"numberInteger",
|
|
49
54
|
"nullable",
|
|
50
55
|
"optional",
|
|
51
56
|
"tupleBuilder",
|
|
@@ -2,4 +2,6 @@ export { fromJsonSchema, jsonSchemaFullFeaturePlugin, } from "./json-schema-full
|
|
|
2
2
|
export { jsonSchemaBag } from "./bundled-plugins";
|
|
3
3
|
export { UNBOUND_BUNDLED_PLUGIN_NAMES, findStaleUnboundDeclarations, findUnbundledBoundPlugins, findUnexplainedBundledPlugins, listBundledPluginNames, } from "./bundle-coverage";
|
|
4
4
|
export type { JsonSchemaOptions } from "../json-schema";
|
|
5
|
-
export
|
|
5
|
+
export { DRAFT07_DIALECT_URI, UnsupportedDialectError, } from "../../unsupported-dialect-error";
|
|
6
|
+
export { MalformedSchemaError, NotASchemaError, RefResolutionError, UnsupportedKeywordError, } from "../../index";
|
|
7
|
+
export type { DialectOptions, JsonSchemaBag } from "../../index";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.listBundledPluginNames = exports.findUnexplainedBundledPlugins = exports.findUnbundledBoundPlugins = exports.findStaleUnboundDeclarations = exports.UNBOUND_BUNDLED_PLUGIN_NAMES = exports.jsonSchemaBag = exports.jsonSchemaFullFeaturePlugin = exports.fromJsonSchema = void 0;
|
|
3
|
+
exports.UnsupportedKeywordError = exports.RefResolutionError = exports.NotASchemaError = exports.MalformedSchemaError = exports.UnsupportedDialectError = exports.DRAFT07_DIALECT_URI = exports.listBundledPluginNames = exports.findUnexplainedBundledPlugins = exports.findUnbundledBoundPlugins = exports.findStaleUnboundDeclarations = exports.UNBOUND_BUNDLED_PLUGIN_NAMES = exports.jsonSchemaBag = exports.jsonSchemaFullFeaturePlugin = exports.fromJsonSchema = void 0;
|
|
4
4
|
// ===========================================================================
|
|
5
5
|
// The public subpath `@maroonedog/luq/plugins/jsonSchemaFullFeature`.
|
|
6
6
|
// Re-exports only.
|
|
@@ -23,3 +23,20 @@ Object.defineProperty(exports, "findStaleUnboundDeclarations", { enumerable: tru
|
|
|
23
23
|
Object.defineProperty(exports, "findUnbundledBoundPlugins", { enumerable: true, get: function () { return bundle_coverage_1.findUnbundledBoundPlugins; } });
|
|
24
24
|
Object.defineProperty(exports, "findUnexplainedBundledPlugins", { enumerable: true, get: function () { return bundle_coverage_1.findUnexplainedBundledPlugins; } });
|
|
25
25
|
Object.defineProperty(exports, "listBundledPluginNames", { enumerable: true, get: function () { return bundle_coverage_1.listBundledPluginNames; } });
|
|
26
|
+
// Every error `fromJsonSchema` can throw, so a caller can tell them apart by
|
|
27
|
+
// class rather than by reading the message.
|
|
28
|
+
//
|
|
29
|
+
// This subpath is the one-import route and the one the documentation points at,
|
|
30
|
+
// which made it the worst place to be missing them: a document that is not
|
|
31
|
+
// Draft-07 at all, one the meta-schema forbids, one carrying a keyword Luq
|
|
32
|
+
// cannot honour and one that is not a schema are four different things to do
|
|
33
|
+
// about it, and a caller who can only match on message text has to re-derive
|
|
34
|
+
// that distinction from prose that is free to change.
|
|
35
|
+
var unsupported_dialect_error_1 = require("../../unsupported-dialect-error");
|
|
36
|
+
Object.defineProperty(exports, "DRAFT07_DIALECT_URI", { enumerable: true, get: function () { return unsupported_dialect_error_1.DRAFT07_DIALECT_URI; } });
|
|
37
|
+
Object.defineProperty(exports, "UnsupportedDialectError", { enumerable: true, get: function () { return unsupported_dialect_error_1.UnsupportedDialectError; } });
|
|
38
|
+
var index_1 = require("../../index");
|
|
39
|
+
Object.defineProperty(exports, "MalformedSchemaError", { enumerable: true, get: function () { return index_1.MalformedSchemaError; } });
|
|
40
|
+
Object.defineProperty(exports, "NotASchemaError", { enumerable: true, get: function () { return index_1.NotASchemaError; } });
|
|
41
|
+
Object.defineProperty(exports, "RefResolutionError", { enumerable: true, get: function () { return index_1.RefResolutionError; } });
|
|
42
|
+
Object.defineProperty(exports, "UnsupportedKeywordError", { enumerable: true, get: function () { return index_1.UnsupportedKeywordError; } });
|
|
@@ -12,3 +12,14 @@
|
|
|
12
12
|
export { fromJsonSchema, jsonSchemaFullFeaturePlugin, } from "./json-schema-full-feature.mjs";
|
|
13
13
|
export { jsonSchemaBag } from "./bundled-plugins.mjs";
|
|
14
14
|
export { UNBOUND_BUNDLED_PLUGIN_NAMES, findStaleUnboundDeclarations, findUnbundledBoundPlugins, findUnexplainedBundledPlugins, listBundledPluginNames, } from "./bundle-coverage.mjs";
|
|
15
|
+
// Every error `fromJsonSchema` can throw, so a caller can tell them apart by
|
|
16
|
+
// class rather than by reading the message.
|
|
17
|
+
//
|
|
18
|
+
// This subpath is the one-import route and the one the documentation points at,
|
|
19
|
+
// which made it the worst place to be missing them: a document that is not
|
|
20
|
+
// Draft-07 at all, one the meta-schema forbids, one carrying a keyword Luq
|
|
21
|
+
// cannot honour and one that is not a schema are four different things to do
|
|
22
|
+
// about it, and a caller who can only match on message text has to re-derive
|
|
23
|
+
// that distinction from prose that is free to change.
|
|
24
|
+
export { DRAFT07_DIALECT_URI, UnsupportedDialectError, } from "../../unsupported-dialect-error.mjs";
|
|
25
|
+
export { MalformedSchemaError, NotASchemaError, RefResolutionError, UnsupportedKeywordError, } from "../../index.mjs";
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { MessageContextExtra, TypeName } from "../../../types";
|
|
2
2
|
import type { Unchanged } from "../../../plugin-kit/marker.types";
|
|
3
3
|
import type { JsonSchemaOptions } from "../json-schema";
|
|
4
|
+
import type { DialectOptions } from "../../index";
|
|
4
5
|
import type { GlobalConfig } from "../../../types/global-config";
|
|
5
6
|
export declare const jsonSchemaFullFeaturePlugin: import("../../../plugin-kit/plugin-definition").PluginDefinition<"jsonSchemaFullFeature", "jsonSchemaFullFeature", readonly TypeName[], {
|
|
6
7
|
args: readonly [document: unknown, options?: JsonSchemaOptions];
|
|
@@ -17,8 +18,15 @@ export declare const jsonSchemaFullFeaturePlugin: import("../../../plugin-kit/pl
|
|
|
17
18
|
* NO declared path is checked — see build-from-schema.ts, which owns that
|
|
18
19
|
* escape hatch and its single overload.
|
|
19
20
|
*
|
|
21
|
+
* THE INPUT LIMIT IS DRAFT-07. A document whose root `$schema` names 2019-09 or
|
|
22
|
+
* 2020-12 is refused with an `UnsupportedDialectError` rather than read as
|
|
23
|
+
* Draft-07, because the dialects disagree about what unchanged keywords mean;
|
|
24
|
+
* a document with no `$schema` is read as Draft-07 as before. Pass
|
|
25
|
+
* `{ assumeDraft07: true }` as the third argument to take the Draft-07 reading
|
|
26
|
+
* deliberately. build-from-schema.ts states the divergence in full.
|
|
27
|
+
*
|
|
20
28
|
* The return type is INFERRED rather than written: naming `Validator<T>` would
|
|
21
29
|
* mean importing src/builder, which tier `extension` forbids. The inferred type
|
|
22
30
|
* is that same `Validator<T>` and the type test asserts it.
|
|
23
31
|
*/
|
|
24
|
-
export declare function fromJsonSchema<T extends object = Record<string, unknown>>(schema: unknown, config?: GlobalConfig): import("../../..").Validator<T, T>;
|
|
32
|
+
export declare function fromJsonSchema<T extends object = Record<string, unknown>>(schema: unknown, config?: GlobalConfig, options?: DialectOptions): import("../../..").Validator<T, T>;
|
|
@@ -57,10 +57,17 @@ exports.jsonSchemaFullFeaturePlugin = (0, plugin_definition_1.definePlugin)()({
|
|
|
57
57
|
* NO declared path is checked — see build-from-schema.ts, which owns that
|
|
58
58
|
* escape hatch and its single overload.
|
|
59
59
|
*
|
|
60
|
+
* THE INPUT LIMIT IS DRAFT-07. A document whose root `$schema` names 2019-09 or
|
|
61
|
+
* 2020-12 is refused with an `UnsupportedDialectError` rather than read as
|
|
62
|
+
* Draft-07, because the dialects disagree about what unchanged keywords mean;
|
|
63
|
+
* a document with no `$schema` is read as Draft-07 as before. Pass
|
|
64
|
+
* `{ assumeDraft07: true }` as the third argument to take the Draft-07 reading
|
|
65
|
+
* deliberately. build-from-schema.ts states the divergence in full.
|
|
66
|
+
*
|
|
60
67
|
* The return type is INFERRED rather than written: naming `Validator<T>` would
|
|
61
68
|
* mean importing src/builder, which tier `extension` forbids. The inferred type
|
|
62
69
|
* is that same `Validator<T>` and the type test asserts it.
|
|
63
70
|
*/
|
|
64
|
-
function fromJsonSchema(schema, config) {
|
|
65
|
-
return (0, index_1.fromJsonSchema)(bundled_plugins_1.jsonSchemaBag, schema, config);
|
|
71
|
+
function fromJsonSchema(schema, config, options) {
|
|
72
|
+
return (0, index_1.fromJsonSchema)(bundled_plugins_1.jsonSchemaBag, schema, config, options);
|
|
66
73
|
}
|
|
@@ -53,10 +53,17 @@ export const jsonSchemaFullFeaturePlugin = /*#__PURE__*/ definePlugin()({
|
|
|
53
53
|
* NO declared path is checked — see build-from-schema.ts, which owns that
|
|
54
54
|
* escape hatch and its single overload.
|
|
55
55
|
*
|
|
56
|
+
* THE INPUT LIMIT IS DRAFT-07. A document whose root `$schema` names 2019-09 or
|
|
57
|
+
* 2020-12 is refused with an `UnsupportedDialectError` rather than read as
|
|
58
|
+
* Draft-07, because the dialects disagree about what unchanged keywords mean;
|
|
59
|
+
* a document with no `$schema` is read as Draft-07 as before. Pass
|
|
60
|
+
* `{ assumeDraft07: true }` as the third argument to take the Draft-07 reading
|
|
61
|
+
* deliberately. build-from-schema.ts states the divergence in full.
|
|
62
|
+
*
|
|
56
63
|
* The return type is INFERRED rather than written: naming `Validator<T>` would
|
|
57
64
|
* mean importing src/builder, which tier `extension` forbids. The inferred type
|
|
58
65
|
* is that same `Validator<T>` and the type test asserts it.
|
|
59
66
|
*/
|
|
60
|
-
export function fromJsonSchema(schema, config) {
|
|
61
|
-
return convertWithBag(jsonSchemaBag, schema, config);
|
|
67
|
+
export function fromJsonSchema(schema, config, options) {
|
|
68
|
+
return convertWithBag(jsonSchemaBag, schema, config, options);
|
|
62
69
|
}
|
|
@@ -18,6 +18,9 @@ export type { SchemaRegistry } from "./schema-registry";
|
|
|
18
18
|
export { createSchemaRegistry } from "./schema-registry";
|
|
19
19
|
export { UnsupportedKeywordError } from "./unsupported-keyword-error";
|
|
20
20
|
export { MalformedSchemaError } from "./malformed-schema-error";
|
|
21
|
+
export { DRAFT07_DIALECT_URI, UnsupportedDialectError, } from "./unsupported-dialect-error";
|
|
22
|
+
export { NON_DRAFT07_DIALECTS, assertSupportedDialect, } from "./assert-supported-dialect";
|
|
23
|
+
export type { DialectOptions } from "./assert-supported-dialect";
|
|
21
24
|
export { isDraft07Schema, isSchemaObject } from "./draft07.types";
|
|
22
25
|
export type { Draft07Schema, Draft07SchemaObject, Draft07TypeKeyword, } from "./draft07.types";
|
|
23
26
|
export { assertKeywordSupported, countKeywordHandlings, findKeywordHandling, isDraft07Keyword, listBoundPluginNames, listDraft07Keywords, } from "./keyword-map";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.listFormatNames = exports.findFormatHandling = exports.listDraft07Keywords = exports.listBoundPluginNames = exports.isDraft07Keyword = exports.findKeywordHandling = exports.countKeywordHandlings = exports.assertKeywordSupported = exports.isSchemaObject = exports.isDraft07Schema = exports.MalformedSchemaError = exports.UnsupportedKeywordError = exports.createSchemaRegistry = exports.createLocalScope = exports.createDocumentScope = exports.resolveRefInScope = exports.resolveRef = exports.isResolvableRef = exports.RefResolutionError = exports.declarePresenceRules = exports.declareRequiredProperties = exports.createStructuralContext = exports.toSchemaBranch = exports.collectSubSchemaRules = exports.readChildSchemas = exports.isStructuralKeyword = exports.expandSchemaRules = exports.STRUCTURAL_EXPANSIONS = exports.joinDeclaredPath = exports.flattenSchema = exports.toSchemaObject = exports.resolveSchemaNodeInScope = exports.resolveSchemaNode = exports.readRefPointer = exports.isDefinitionContainer = exports.collectDefinitionNames = exports.DEFINITION_CONTAINERS = exports.fromJsonSchema = exports.buildFromSchema = exports.buildFieldEntries = exports.NotASchemaError = void 0;
|
|
3
|
+
exports.listFormatNames = exports.findFormatHandling = exports.listDraft07Keywords = exports.listBoundPluginNames = exports.isDraft07Keyword = exports.findKeywordHandling = exports.countKeywordHandlings = exports.assertKeywordSupported = exports.isSchemaObject = exports.isDraft07Schema = exports.assertSupportedDialect = exports.NON_DRAFT07_DIALECTS = exports.UnsupportedDialectError = exports.DRAFT07_DIALECT_URI = exports.MalformedSchemaError = exports.UnsupportedKeywordError = exports.createSchemaRegistry = exports.createLocalScope = exports.createDocumentScope = exports.resolveRefInScope = exports.resolveRef = exports.isResolvableRef = exports.RefResolutionError = exports.declarePresenceRules = exports.declareRequiredProperties = exports.createStructuralContext = exports.toSchemaBranch = exports.collectSubSchemaRules = exports.readChildSchemas = exports.isStructuralKeyword = exports.expandSchemaRules = exports.STRUCTURAL_EXPANSIONS = exports.joinDeclaredPath = exports.flattenSchema = exports.toSchemaObject = exports.resolveSchemaNodeInScope = exports.resolveSchemaNode = exports.readRefPointer = exports.isDefinitionContainer = exports.collectDefinitionNames = exports.DEFINITION_CONTAINERS = exports.fromJsonSchema = exports.buildFromSchema = exports.buildFieldEntries = exports.NotASchemaError = void 0;
|
|
4
4
|
// ===========================================================================
|
|
5
5
|
// L8 src/json-schema/index.ts — re-exports only. Nothing is defined here.
|
|
6
6
|
//
|
|
@@ -52,6 +52,12 @@ var unsupported_keyword_error_1 = require("./unsupported-keyword-error");
|
|
|
52
52
|
Object.defineProperty(exports, "UnsupportedKeywordError", { enumerable: true, get: function () { return unsupported_keyword_error_1.UnsupportedKeywordError; } });
|
|
53
53
|
var malformed_schema_error_1 = require("./malformed-schema-error");
|
|
54
54
|
Object.defineProperty(exports, "MalformedSchemaError", { enumerable: true, get: function () { return malformed_schema_error_1.MalformedSchemaError; } });
|
|
55
|
+
var unsupported_dialect_error_1 = require("./unsupported-dialect-error");
|
|
56
|
+
Object.defineProperty(exports, "DRAFT07_DIALECT_URI", { enumerable: true, get: function () { return unsupported_dialect_error_1.DRAFT07_DIALECT_URI; } });
|
|
57
|
+
Object.defineProperty(exports, "UnsupportedDialectError", { enumerable: true, get: function () { return unsupported_dialect_error_1.UnsupportedDialectError; } });
|
|
58
|
+
var assert_supported_dialect_1 = require("./assert-supported-dialect");
|
|
59
|
+
Object.defineProperty(exports, "NON_DRAFT07_DIALECTS", { enumerable: true, get: function () { return assert_supported_dialect_1.NON_DRAFT07_DIALECTS; } });
|
|
60
|
+
Object.defineProperty(exports, "assertSupportedDialect", { enumerable: true, get: function () { return assert_supported_dialect_1.assertSupportedDialect; } });
|
|
55
61
|
var draft07_types_1 = require("./draft07.types");
|
|
56
62
|
Object.defineProperty(exports, "isDraft07Schema", { enumerable: true, get: function () { return draft07_types_1.isDraft07Schema; } });
|
|
57
63
|
Object.defineProperty(exports, "isSchemaObject", { enumerable: true, get: function () { return draft07_types_1.isSchemaObject; } });
|
|
@@ -18,6 +18,8 @@ export { createDocumentScope, createLocalScope } from "./ref-scope.mjs";
|
|
|
18
18
|
export { createSchemaRegistry } from "./schema-registry.mjs";
|
|
19
19
|
export { UnsupportedKeywordError } from "./unsupported-keyword-error.mjs";
|
|
20
20
|
export { MalformedSchemaError } from "./malformed-schema-error.mjs";
|
|
21
|
+
export { DRAFT07_DIALECT_URI, UnsupportedDialectError, } from "./unsupported-dialect-error.mjs";
|
|
22
|
+
export { NON_DRAFT07_DIALECTS, assertSupportedDialect, } from "./assert-supported-dialect.mjs";
|
|
21
23
|
export { isDraft07Schema, isSchemaObject } from "./draft07.types.mjs";
|
|
22
24
|
export { assertKeywordSupported, countKeywordHandlings, findKeywordHandling, isDraft07Keyword, listBoundPluginNames, listDraft07Keywords, } from "./keyword-map.mjs";
|
|
23
25
|
export { findFormatHandling, listFormatNames } from "./format-map.mjs";
|
|
@@ -25,7 +25,9 @@ const ANNOTATION_ONLY = "an annotation with no validation effect in Draft-07";
|
|
|
25
25
|
*/
|
|
26
26
|
exports.constBinding = (0, bind_keyword_1.bindKeyword)("any", "literal", literal_1.literalPlugin, (v) => [v]);
|
|
27
27
|
exports.coreKeywordMap = {
|
|
28
|
-
$schema: (0, bind_keyword_1.unsupported)("read
|
|
28
|
+
$schema: (0, bind_keyword_1.unsupported)("read at the document ROOT by assert-supported-dialect and then " +
|
|
29
|
+
"discarded: Luq implements Draft-07 and never switches dialect, so a " +
|
|
30
|
+
"root `$schema` naming another one is refused rather than ignored"),
|
|
29
31
|
$id: (0, bind_keyword_1.unsupported)("no base-URI resolution; resolve-ref accepts local $ref only"),
|
|
30
32
|
$comment: (0, bind_keyword_1.unsupported)(ANNOTATION_ONLY),
|
|
31
33
|
$ref: (0, bind_keyword_1.structural)("resolved by resolve-ref before any keyword is read"),
|
|
@@ -22,7 +22,9 @@ const ANNOTATION_ONLY = "an annotation with no validation effect in Draft-07";
|
|
|
22
22
|
*/
|
|
23
23
|
export const constBinding = bindKeyword("any", "literal", literalPlugin, (v) => [v]);
|
|
24
24
|
export const coreKeywordMap = {
|
|
25
|
-
$schema: unsupported("read
|
|
25
|
+
$schema: unsupported("read at the document ROOT by assert-supported-dialect and then " +
|
|
26
|
+
"discarded: Luq implements Draft-07 and never switches dialect, so a " +
|
|
27
|
+
"root `$schema` naming another one is refused rather than ignored"),
|
|
26
28
|
$id: unsupported("no base-URI resolution; resolve-ref accepts local $ref only"),
|
|
27
29
|
$comment: unsupported(ANNOTATION_ONLY),
|
|
28
30
|
$ref: structural("resolved by resolve-ref before any keyword is read"),
|
|
@@ -32,7 +32,10 @@ exports.NON_DRAFT07_KEYWORDS = {
|
|
|
32
32
|
$defs: "2019-09 spelling of `definitions`; resolve-ref follows it anyway",
|
|
33
33
|
$anchor: "2019-09 anchors; resolve-ref resolves JSON Pointers only",
|
|
34
34
|
$dynamicRef: "2020-12 dynamic references",
|
|
35
|
+
$dynamicAnchor: "2020-12 dynamic anchors; the target half of $dynamicRef",
|
|
35
36
|
$recursiveRef: "2019-09 recursive references",
|
|
37
|
+
$recursiveAnchor: "2019-09 recursive anchors; the target half of $recursiveRef",
|
|
38
|
+
$vocabulary: "2019-09 vocabulary declaration; Luq has one fixed vocabulary",
|
|
36
39
|
dependentRequired: "2019-09 split of `dependencies`; use `dependencies`",
|
|
37
40
|
dependentSchemas: "2019-09 split of `dependencies`; use `dependencies`",
|
|
38
41
|
minContains: "2019-09 bound on `contains`; Draft-07's is fixed at one",
|
|
@@ -23,7 +23,10 @@ export const NON_DRAFT07_KEYWORDS = {
|
|
|
23
23
|
$defs: "2019-09 spelling of `definitions`; resolve-ref follows it anyway",
|
|
24
24
|
$anchor: "2019-09 anchors; resolve-ref resolves JSON Pointers only",
|
|
25
25
|
$dynamicRef: "2020-12 dynamic references",
|
|
26
|
+
$dynamicAnchor: "2020-12 dynamic anchors; the target half of $dynamicRef",
|
|
26
27
|
$recursiveRef: "2019-09 recursive references",
|
|
28
|
+
$recursiveAnchor: "2019-09 recursive anchors; the target half of $recursiveRef",
|
|
29
|
+
$vocabulary: "2019-09 vocabulary declaration; Luq has one fixed vocabulary",
|
|
27
30
|
dependentRequired: "2019-09 split of `dependencies`; use `dependencies`",
|
|
28
31
|
dependentSchemas: "2019-09 split of `dependencies`; use `dependencies`",
|
|
29
32
|
minContains: "2019-09 bound on `contains`; Draft-07's is fixed at one",
|
|
@@ -30,10 +30,7 @@ exports.STRUCTURAL_EXPANSIONS = {
|
|
|
30
30
|
},
|
|
31
31
|
type: {
|
|
32
32
|
expandsTo: "rules",
|
|
33
|
-
toRules:
|
|
34
|
-
...(0, declare_value_keywords_1.declareTypeRules)(schema, context),
|
|
35
|
-
...(0, declare_value_keywords_1.declareIntegerRules)(schema, context),
|
|
36
|
-
],
|
|
33
|
+
toRules: declare_value_keywords_1.declareTypeRules,
|
|
37
34
|
},
|
|
38
35
|
enum: { expandsTo: "rules", toRules: declare_value_keywords_1.declareEnumRules },
|
|
39
36
|
allOf: { expandsTo: "rules", toRules: compose_keyword_1.composeAllOf },
|
|
@@ -5,7 +5,7 @@ import { declareAdditionalPropertiesSchema } from "./declare-additional-properti
|
|
|
5
5
|
import { declareDependencies, declareObjectRules, declarePatternProperties, declarePropertyNames, readPropertyChildren, } from "./declare-object-keywords.mjs";
|
|
6
6
|
import { declareRequiredProperties } from "./declare-required-properties.mjs";
|
|
7
7
|
import { declareFormatRules, declareNumberRules, declareStringRules, } from "./declare-scalar-keywords.mjs";
|
|
8
|
-
import { declareConstRules, declareEnumRules,
|
|
8
|
+
import { declareConstRules, declareEnumRules, declareTypeRules, } from "./declare-value-keywords.mjs";
|
|
9
9
|
import { composeContains, composeTupleItems, declareArrayRules, readItemChildren, } from "./flatten-array-schema.mjs";
|
|
10
10
|
import { NON_DRAFT07_KEYWORDS, findKeywordHandling } from "./keyword-map.mjs";
|
|
11
11
|
import { readChildExpansion, readRuleExpansion, } from "./structural-expansion.types.mjs";
|
|
@@ -24,10 +24,7 @@ export const STRUCTURAL_EXPANSIONS = {
|
|
|
24
24
|
},
|
|
25
25
|
type: {
|
|
26
26
|
expandsTo: "rules",
|
|
27
|
-
toRules:
|
|
28
|
-
...declareTypeRules(schema, context),
|
|
29
|
-
...declareIntegerRules(schema, context),
|
|
30
|
-
],
|
|
27
|
+
toRules: declareTypeRules,
|
|
31
28
|
},
|
|
32
29
|
enum: { expandsTo: "rules", toRules: declareEnumRules },
|
|
33
30
|
allOf: { expandsTo: "rules", toRules: composeAllOf },
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** The dialect this library implements, in the spelling the draft publishes. */
|
|
2
|
+
export declare const DRAFT07_DIALECT_URI = "http://json-schema.org/draft-07/schema#";
|
|
3
|
+
/**
|
|
4
|
+
* Raised when a document's root `$schema` names a dialect Luq does not
|
|
5
|
+
* implement. Thrown at build time, before a validator that would read the
|
|
6
|
+
* document under the wrong dialect's rules can exist.
|
|
7
|
+
*
|
|
8
|
+
* `reason` follows the convention the other two refusals use: a sentence
|
|
9
|
+
* fragment with no terminal punctuation, saying what the dialect does that
|
|
10
|
+
* Draft-07 does not, so that two refusals from two different dialects read as
|
|
11
|
+
* one library rather than as two unrelated messages.
|
|
12
|
+
*/
|
|
13
|
+
export declare class UnsupportedDialectError extends Error {
|
|
14
|
+
/** The `$schema` value the document wrote, verbatim. */
|
|
15
|
+
readonly declared: string;
|
|
16
|
+
/** The dialect Luq reads every document under. */
|
|
17
|
+
readonly implemented: string;
|
|
18
|
+
/** What that dialect does differently, or that it is unrecognised. */
|
|
19
|
+
readonly reason: string;
|
|
20
|
+
constructor(declared: string, reason: string);
|
|
21
|
+
}
|