@amritk/generate-parsers 0.24.0 → 0.25.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 +37 -463
- package/dist/index.d.ts +22 -2
- package/dist/index.js +18 -1
- package/package.json +15 -40
- package/AI.md +0 -52
- package/dist/generators/assert-supported-keywords.d.ts +0 -30
- package/dist/generators/assert-supported-keywords.js +0 -87
- package/dist/generators/build-schema.d.ts +0 -111
- package/dist/generators/build-schema.js +0 -74
- package/dist/generators/generate-deep-equal-check.d.ts +0 -24
- package/dist/generators/generate-deep-equal-check.js +0 -35
- package/dist/generators/generate-default-from-pattern.d.ts +0 -26
- package/dist/generators/generate-default-from-pattern.js +0 -223
- package/dist/generators/generate-discriminated-union-validation.d.ts +0 -15
- package/dist/generators/generate-discriminated-union-validation.js +0 -28
- package/dist/generators/generate-enum-check.d.ts +0 -35
- package/dist/generators/generate-enum-check.js +0 -31
- package/dist/generators/generate-files.d.ts +0 -138
- package/dist/generators/generate-files.js +0 -89
- package/dist/generators/generate-non-discriminated-union-validation.d.ts +0 -6
- package/dist/generators/generate-non-discriminated-union-validation.js +0 -26
- package/dist/generators/generate-parser-function.d.ts +0 -120
- package/dist/generators/generate-parser-function.js +0 -1973
- package/dist/generators/generate-schema-checks.d.ts +0 -5
- package/dist/generators/generate-schema-checks.js +0 -260
- package/dist/generators/generate-strict-assertion.d.ts +0 -155
- package/dist/generators/generate-strict-assertion.js +0 -759
- package/dist/generators/generate-type-checks.d.ts +0 -148
- package/dist/generators/generate-type-checks.js +0 -454
- package/dist/generators/generate-unique-items-check.d.ts +0 -16
- package/dist/generators/generate-unique-items-check.js +0 -32
- package/dist/generators/generate-validation-expression.d.ts +0 -79
- package/dist/generators/generate-validation-expression.js +0 -416
- package/dist/generators/subschema-match.d.ts +0 -48
- package/dist/generators/subschema-match.js +0 -485
- package/dist/generators/unevaluated-match.d.ts +0 -19
- package/dist/generators/unevaluated-match.js +0 -206
- package/dist/helpers/apply-schema-extensions.d.ts +0 -35
- package/dist/helpers/apply-schema-extensions.js +0 -20
- package/dist/helpers/collect-helpers.d.ts +0 -15
- package/dist/helpers/collect-helpers.js +0 -64
- package/dist/helpers/collect-imports.d.ts +0 -104
- package/dist/helpers/collect-imports.js +0 -227
- package/dist/helpers/find-discriminator.d.ts +0 -6
- package/dist/helpers/find-discriminator.js +0 -27
- package/dist/helpers/get-default-value.d.ts +0 -7
- package/dist/helpers/get-default-value.js +0 -155
- package/dist/helpers/get-discriminator-value.d.ts +0 -6
- package/dist/helpers/get-discriminator-value.js +0 -18
- package/dist/types/schema-extensions.d.ts +0 -34
- package/dist/types/schema-extensions.js +0 -0
|
@@ -1,260 +0,0 @@
|
|
|
1
|
-
import { regexLiteral } from "@amritk/helpers/escape-regex-pattern";
|
|
2
|
-
import { getMjstInstanceOf, getMjstPrimitive } from "@amritk/helpers/mjst-extension";
|
|
3
|
-
import { multipleOfPassExpr } from "@amritk/helpers/multiple-of-check";
|
|
4
|
-
import { boundPassExpr } from "@amritk/helpers/numeric-bound-check";
|
|
5
|
-
import { hasOwnCheck } from "@amritk/helpers/safe-accessor";
|
|
6
|
-
import { hasAdditionalProperties, hasConst, hasEnum, hasExclusiveMaximum, hasExclusiveMinimum, hasMaxItems, hasMaximum, hasMaxLength, hasMaxProperties, hasMinItems, hasMinimum, hasMinLength, hasMinProperties, hasMultipleOf, hasPattern, hasProperties, hasRequired, hasType, hasUniqueItems, isSchemaObject } from "@amritk/helpers/schema-guards";
|
|
7
|
-
import { maxLengthPassExpr, minLengthPassExpr } from "@amritk/helpers/string-length-check";
|
|
8
|
-
import { generateDeepEqualCheck } from "./generate-deep-equal-check.js";
|
|
9
|
-
import { generateEnumCheck } from "./generate-enum-check.js";
|
|
10
|
-
import { generateUniqueItemsCheck } from "./generate-unique-items-check.js";
|
|
11
|
-
const OBJECT_KEYWORDS = [
|
|
12
|
-
"properties",
|
|
13
|
-
"required",
|
|
14
|
-
"minProperties",
|
|
15
|
-
"maxProperties",
|
|
16
|
-
"additionalProperties",
|
|
17
|
-
"patternProperties",
|
|
18
|
-
"dependentRequired",
|
|
19
|
-
"propertyNames"
|
|
20
|
-
];
|
|
21
|
-
const ARRAY_KEYWORDS = ["items", "prefixItems", "minItems", "maxItems", "uniqueItems", "contains"];
|
|
22
|
-
const STRING_KEYWORDS = ["minLength", "maxLength", "pattern", "format"];
|
|
23
|
-
const NUMBER_KEYWORDS = ["minimum", "maximum", "exclusiveMinimum", "exclusiveMaximum", "multipleOf"];
|
|
24
|
-
const countKeywords = (schema, keywords) => keywords.reduce((total, keyword) => keyword in schema ? total + 1 : total, 0);
|
|
25
|
-
const typeOfLiteral = (value) => {
|
|
26
|
-
if (value === null)
|
|
27
|
-
return "null";
|
|
28
|
-
if (Array.isArray(value))
|
|
29
|
-
return "array";
|
|
30
|
-
const type = typeof value;
|
|
31
|
-
if (type === "boolean")
|
|
32
|
-
return "boolean";
|
|
33
|
-
if (type === "number" || type === "bigint")
|
|
34
|
-
return "number";
|
|
35
|
-
if (type === "string")
|
|
36
|
-
return "string";
|
|
37
|
-
return "object";
|
|
38
|
-
};
|
|
39
|
-
const inferSchemaType = (schema) => {
|
|
40
|
-
if (!isSchemaObject(schema))
|
|
41
|
-
return void 0;
|
|
42
|
-
if (hasConst(schema)) {
|
|
43
|
-
return typeOfLiteral(schema.const);
|
|
44
|
-
}
|
|
45
|
-
if (hasEnum(schema) && schema.enum.length > 0 && schema.enum.every((value) => value === null)) {
|
|
46
|
-
return "null";
|
|
47
|
-
}
|
|
48
|
-
const scores = {
|
|
49
|
-
object: countKeywords(schema, OBJECT_KEYWORDS),
|
|
50
|
-
array: countKeywords(schema, ARRAY_KEYWORDS),
|
|
51
|
-
string: countKeywords(schema, STRING_KEYWORDS),
|
|
52
|
-
number: countKeywords(schema, NUMBER_KEYWORDS)
|
|
53
|
-
};
|
|
54
|
-
let best;
|
|
55
|
-
for (const type of ["object", "array", "string", "number"]) {
|
|
56
|
-
if (scores[type] > 0 && (best === void 0 || scores[type] > scores[best])) {
|
|
57
|
-
best = type;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
return best;
|
|
61
|
-
};
|
|
62
|
-
const generateInferredChecks = (accessor, schema, type) => {
|
|
63
|
-
const checks = [];
|
|
64
|
-
switch (type) {
|
|
65
|
-
case "object":
|
|
66
|
-
checks.push(`typeof ${accessor} === "object" && ${accessor} !== null && !Array.isArray(${accessor})`);
|
|
67
|
-
if (hasRequired(schema) && schema.required.length > 0) {
|
|
68
|
-
for (const requiredKey of schema.required) {
|
|
69
|
-
checks.push(hasOwnCheck(accessor, requiredKey));
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
if (hasMinProperties(schema)) {
|
|
73
|
-
checks.push(`Object.keys(${accessor}).length >= ${schema.minProperties}`);
|
|
74
|
-
}
|
|
75
|
-
if (hasMaxProperties(schema)) {
|
|
76
|
-
checks.push(`Object.keys(${accessor}).length <= ${schema.maxProperties}`);
|
|
77
|
-
}
|
|
78
|
-
if (hasAdditionalProperties(schema) && schema.additionalProperties === false && hasProperties(schema)) {
|
|
79
|
-
const allowedKeysStr = JSON.stringify(Object.keys(schema.properties));
|
|
80
|
-
checks.push(`Object.keys(${accessor}).every(k => ${allowedKeysStr}.includes(k))`);
|
|
81
|
-
}
|
|
82
|
-
break;
|
|
83
|
-
case "array":
|
|
84
|
-
checks.push(`Array.isArray(${accessor})`);
|
|
85
|
-
if (hasMinItems(schema)) {
|
|
86
|
-
checks.push(`${accessor}.length >= ${schema.minItems}`);
|
|
87
|
-
}
|
|
88
|
-
if (hasMaxItems(schema)) {
|
|
89
|
-
checks.push(`${accessor}.length <= ${schema.maxItems}`);
|
|
90
|
-
}
|
|
91
|
-
if (hasUniqueItems(schema) && schema.uniqueItems === true) {
|
|
92
|
-
checks.push(generateUniqueItemsCheck(accessor, schema));
|
|
93
|
-
}
|
|
94
|
-
break;
|
|
95
|
-
case "string":
|
|
96
|
-
checks.push(`typeof ${accessor} === "string"`);
|
|
97
|
-
if (hasPattern(schema)) {
|
|
98
|
-
checks.push(`${regexLiteral(schema.pattern)}.test(${accessor})`);
|
|
99
|
-
}
|
|
100
|
-
if (hasMinLength(schema)) {
|
|
101
|
-
checks.push(minLengthPassExpr(accessor, schema.minLength));
|
|
102
|
-
}
|
|
103
|
-
if (hasMaxLength(schema)) {
|
|
104
|
-
checks.push(maxLengthPassExpr(accessor, schema.maxLength));
|
|
105
|
-
}
|
|
106
|
-
break;
|
|
107
|
-
case "number":
|
|
108
|
-
checks.push(`typeof ${accessor} === "number"`);
|
|
109
|
-
if (hasMinimum(schema)) {
|
|
110
|
-
checks.push(boundPassExpr(accessor, "minimum", schema.minimum));
|
|
111
|
-
}
|
|
112
|
-
if (hasMaximum(schema)) {
|
|
113
|
-
checks.push(boundPassExpr(accessor, "maximum", schema.maximum));
|
|
114
|
-
}
|
|
115
|
-
if (hasExclusiveMinimum(schema)) {
|
|
116
|
-
checks.push(boundPassExpr(accessor, "minimum", schema.exclusiveMinimum, true));
|
|
117
|
-
}
|
|
118
|
-
if (hasExclusiveMaximum(schema)) {
|
|
119
|
-
checks.push(boundPassExpr(accessor, "maximum", schema.exclusiveMaximum, true));
|
|
120
|
-
}
|
|
121
|
-
if (hasMultipleOf(schema)) {
|
|
122
|
-
checks.push(`${accessor} % ${schema.multipleOf} === 0`);
|
|
123
|
-
}
|
|
124
|
-
break;
|
|
125
|
-
case "boolean":
|
|
126
|
-
checks.push(`typeof ${accessor} === "boolean"`);
|
|
127
|
-
break;
|
|
128
|
-
case "null":
|
|
129
|
-
if (hasConst(schema)) {
|
|
130
|
-
checks.push(`${accessor} === null`);
|
|
131
|
-
}
|
|
132
|
-
break;
|
|
133
|
-
}
|
|
134
|
-
return checks;
|
|
135
|
-
};
|
|
136
|
-
const generateSchemaChecks = (accessor, schema) => {
|
|
137
|
-
const checks = [];
|
|
138
|
-
const instanceOf = getMjstInstanceOf(schema);
|
|
139
|
-
if (instanceOf) {
|
|
140
|
-
return [`${accessor} instanceof ${instanceOf}`];
|
|
141
|
-
}
|
|
142
|
-
const primitive = getMjstPrimitive(schema);
|
|
143
|
-
if (primitive) {
|
|
144
|
-
return [`typeof ${accessor} === "${primitive}"`];
|
|
145
|
-
}
|
|
146
|
-
if (hasConst(schema)) {
|
|
147
|
-
return [generateDeepEqualCheck(accessor, schema.const)];
|
|
148
|
-
}
|
|
149
|
-
if (isSchemaObject(schema) && Array.isArray(schema.type)) {
|
|
150
|
-
const branches = [];
|
|
151
|
-
for (const type of schema.type) {
|
|
152
|
-
if (typeof type !== "string")
|
|
153
|
-
continue;
|
|
154
|
-
const branch = generateSchemaChecks(accessor, { ...schema, type });
|
|
155
|
-
if (branch.length === 0)
|
|
156
|
-
continue;
|
|
157
|
-
branches.push(branch.length === 1 ? branch[0] : `(${branch.join(" && ")})`);
|
|
158
|
-
}
|
|
159
|
-
if (branches.length === 0)
|
|
160
|
-
return checks;
|
|
161
|
-
return [branches.length === 1 ? branches[0] : `(${branches.join(" || ")})`];
|
|
162
|
-
}
|
|
163
|
-
if (!hasType(schema)) {
|
|
164
|
-
const inferred = inferSchemaType(schema);
|
|
165
|
-
if (!inferred) {
|
|
166
|
-
return checks;
|
|
167
|
-
}
|
|
168
|
-
checks.push(...generateInferredChecks(accessor, schema, inferred));
|
|
169
|
-
if (hasEnum(schema) && schema.enum.length > 0) {
|
|
170
|
-
checks.push(generateEnumCheck(accessor, schema.enum));
|
|
171
|
-
}
|
|
172
|
-
return checks;
|
|
173
|
-
}
|
|
174
|
-
switch (schema.type) {
|
|
175
|
-
case "string": {
|
|
176
|
-
checks.push(`typeof ${accessor} === "string"`);
|
|
177
|
-
if (hasPattern(schema)) {
|
|
178
|
-
checks.push(`${regexLiteral(schema.pattern)}.test(${accessor})`);
|
|
179
|
-
}
|
|
180
|
-
if (hasMinLength(schema)) {
|
|
181
|
-
checks.push(minLengthPassExpr(accessor, schema.minLength));
|
|
182
|
-
}
|
|
183
|
-
if (hasMaxLength(schema)) {
|
|
184
|
-
checks.push(maxLengthPassExpr(accessor, schema.maxLength));
|
|
185
|
-
}
|
|
186
|
-
break;
|
|
187
|
-
}
|
|
188
|
-
case "number":
|
|
189
|
-
case "integer":
|
|
190
|
-
checks.push(`typeof ${accessor} === "number"`);
|
|
191
|
-
if (schema.type === "integer") {
|
|
192
|
-
checks.push(`Number.isInteger(${accessor})`);
|
|
193
|
-
}
|
|
194
|
-
if (hasMinimum(schema)) {
|
|
195
|
-
checks.push(boundPassExpr(accessor, "minimum", schema.minimum));
|
|
196
|
-
}
|
|
197
|
-
if (hasMaximum(schema)) {
|
|
198
|
-
checks.push(boundPassExpr(accessor, "maximum", schema.maximum));
|
|
199
|
-
}
|
|
200
|
-
if (hasExclusiveMinimum(schema)) {
|
|
201
|
-
checks.push(boundPassExpr(accessor, "minimum", schema.exclusiveMinimum, true));
|
|
202
|
-
}
|
|
203
|
-
if (hasExclusiveMaximum(schema)) {
|
|
204
|
-
checks.push(boundPassExpr(accessor, "maximum", schema.exclusiveMaximum, true));
|
|
205
|
-
}
|
|
206
|
-
if (hasMultipleOf(schema)) {
|
|
207
|
-
checks.push(multipleOfPassExpr(accessor, schema.multipleOf));
|
|
208
|
-
}
|
|
209
|
-
break;
|
|
210
|
-
case "boolean":
|
|
211
|
-
checks.push(`typeof ${accessor} === "boolean"`);
|
|
212
|
-
break;
|
|
213
|
-
// Without this the `null` branch of a union produced NO check, which reads
|
|
214
|
-
// as "this branch matches nothing": `{ anyOf: [{ type: 'string' },
|
|
215
|
-
// { type: 'null' }] }` rejected `null` — the one value the branch exists to
|
|
216
|
-
// admit — and the coercing build dropped the property instead of keeping it.
|
|
217
|
-
case "null":
|
|
218
|
-
checks.push(`${accessor} === null`);
|
|
219
|
-
break;
|
|
220
|
-
case "array":
|
|
221
|
-
checks.push(`Array.isArray(${accessor})`);
|
|
222
|
-
if (hasMinItems(schema)) {
|
|
223
|
-
checks.push(`${accessor}.length >= ${schema.minItems}`);
|
|
224
|
-
}
|
|
225
|
-
if (hasMaxItems(schema)) {
|
|
226
|
-
checks.push(`${accessor}.length <= ${schema.maxItems}`);
|
|
227
|
-
}
|
|
228
|
-
if (hasUniqueItems(schema) && schema.uniqueItems === true) {
|
|
229
|
-
checks.push(generateUniqueItemsCheck(accessor, schema));
|
|
230
|
-
}
|
|
231
|
-
break;
|
|
232
|
-
case "object": {
|
|
233
|
-
checks.push(`typeof ${accessor} === "object" && ${accessor} !== null && !Array.isArray(${accessor})`);
|
|
234
|
-
if (hasRequired(schema) && schema.required.length > 0) {
|
|
235
|
-
for (const requiredKey of schema.required) {
|
|
236
|
-
checks.push(hasOwnCheck(accessor, requiredKey));
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
if (hasMinProperties(schema)) {
|
|
240
|
-
checks.push(`Object.keys(${accessor}).length >= ${schema.minProperties}`);
|
|
241
|
-
}
|
|
242
|
-
if (hasMaxProperties(schema)) {
|
|
243
|
-
checks.push(`Object.keys(${accessor}).length <= ${schema.maxProperties}`);
|
|
244
|
-
}
|
|
245
|
-
if (hasAdditionalProperties(schema) && schema.additionalProperties === false && hasProperties(schema)) {
|
|
246
|
-
const allowedKeys = Object.keys(schema.properties);
|
|
247
|
-
const allowedKeysStr = JSON.stringify(allowedKeys);
|
|
248
|
-
checks.push(`Object.keys(${accessor}).every(k => ${allowedKeysStr}.includes(k))`);
|
|
249
|
-
}
|
|
250
|
-
break;
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
if (hasEnum(schema) && schema.enum.length > 0) {
|
|
254
|
-
checks.push(generateEnumCheck(accessor, schema.enum));
|
|
255
|
-
}
|
|
256
|
-
return checks;
|
|
257
|
-
};
|
|
258
|
-
export {
|
|
259
|
-
generateSchemaChecks
|
|
260
|
-
};
|
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
import type { UnknownKeysStrategy } from '@amritk/helpers/unknown-keys-strategy';
|
|
2
|
-
import type { JSONSchema } from 'json-schema-typed/draft-2020-12';
|
|
3
|
-
/**
|
|
4
|
-
* Context for assertions that reach beyond the property's own schema: union
|
|
5
|
-
* membership checks may call imported `validate{X}Shape` predicates ($ref
|
|
6
|
-
* branches), which requires knowing the ref-import mode, the type-name suffix,
|
|
7
|
-
* and the root document (to prove those validators are real — see
|
|
8
|
-
* canEnforceUnion). `stripUnknown` disables union enforcement entirely, since
|
|
9
|
-
* shape validators then treat undeclared keys as a mismatch while the
|
|
10
|
-
* stripUnknown contract is to drop them.
|
|
11
|
-
*/
|
|
12
|
-
export type StrictAssertionContext = {
|
|
13
|
-
readonly useRefImports?: boolean;
|
|
14
|
-
readonly suffix?: string;
|
|
15
|
-
readonly rootSchema?: Record<string, unknown>;
|
|
16
|
-
readonly stripUnknown?: boolean;
|
|
17
|
-
/**
|
|
18
|
-
* The parser's `unknownKeys` option, carried so every object parser one of
|
|
19
|
-
* these contexts reaches counts keys on its fast path the same way.
|
|
20
|
-
*/
|
|
21
|
-
readonly unknownKeys?: UnknownKeysStrategy;
|
|
22
|
-
/**
|
|
23
|
-
* Whether the parser these assertions run inside also emits the private
|
|
24
|
-
* sub-parsers for its inline object properties (and inline-object array
|
|
25
|
-
* items). `generateObjectParser` does, so the shape of such a property is
|
|
26
|
-
* proven by the call it delegates to and asserting it here would be
|
|
27
|
-
* redundant. The pattern-property parsers do NOT — they build their result
|
|
28
|
-
* with a copy loop — so a nested object property there is proven by nobody
|
|
29
|
-
* unless these assertions prove it. Defaults to true, the historical
|
|
30
|
-
* assumption.
|
|
31
|
-
*/
|
|
32
|
-
readonly subParsers?: boolean;
|
|
33
|
-
};
|
|
34
|
-
/**
|
|
35
|
-
* Why a node needs the whole-schema backstop, or `null` when the specialized
|
|
36
|
-
* assertions above already cover it. Each reason is a keyword whose enforcement
|
|
37
|
-
* no per-property / per-type check can express:
|
|
38
|
-
*
|
|
39
|
-
* - `unevaluated*` depends on which *other* keywords evaluated which keys, so it
|
|
40
|
-
* can only be answered against the whole node at once.
|
|
41
|
-
* - a `$ref` is normally enforced by the parser generated for its target, but
|
|
42
|
-
* that delegation covers neither an inlined build (no ref imports) nor the
|
|
43
|
-
* 2020-12 rule that a `$ref`'s *siblings* still apply.
|
|
44
|
-
* - `items: false` (with no tuple positions) admits only the empty array, and
|
|
45
|
-
* the item-check builder reads `items` through a guard that a boolean fails.
|
|
46
|
-
* - a constraint keyword with no `type` never reaches the typed constraint pass.
|
|
47
|
-
*/
|
|
48
|
-
export declare const backstopReason: (schema: JSONSchema, context: StrictAssertionContext) => string | null;
|
|
49
|
-
/**
|
|
50
|
-
* The slice of a node the backstop actually has to prove.
|
|
51
|
-
*
|
|
52
|
-
* `unevaluated*` and `$ref` need the node whole — the first because its answer
|
|
53
|
-
* depends on what every sibling keyword evaluated, the second because a ref's
|
|
54
|
-
* siblings apply alongside its target. A bare constraint needs only itself, and
|
|
55
|
-
* proving it in isolation is what keeps an ordinary
|
|
56
|
-
* `{ allOf: [{…}, { $ref: … }], required: ['role'] }` — the OpenAPI idiom —
|
|
57
|
-
* generating: the `required` is provable even when the surrounding `allOf`
|
|
58
|
-
* member is too deep (or too unresolvable) to inline, and that member has its
|
|
59
|
-
* own enforcement anyway.
|
|
60
|
-
*
|
|
61
|
-
* `properties` rides along, flattened to `true` schemas, only because
|
|
62
|
-
* `additionalProperties` needs the declared key names to know which keys it
|
|
63
|
-
* owns. Their values are irrelevant to that question and are asserted
|
|
64
|
-
* per-property elsewhere.
|
|
65
|
-
*/
|
|
66
|
-
export declare const backstopSchema: (schema: JSONSchema, reason: string) => JSONSchema;
|
|
67
|
-
/**
|
|
68
|
-
* The strict-mode backstop: a single whole-node match, emitted only for the
|
|
69
|
-
* keywords {@link backstopReason} identifies as unreachable by the specialized
|
|
70
|
-
* assertions. It is the same exact matcher `contains` and `propertyNames` use, so
|
|
71
|
-
* a `true` verdict means valid and a `false` one means invalid — which is what
|
|
72
|
-
* lets it stand alone as the enforcement for those keywords.
|
|
73
|
-
*
|
|
74
|
-
* Emitting nothing here is only safe because `assertNoUnsupportedKeywords`
|
|
75
|
-
* refuses generation for any node that needs a backstop the matcher cannot
|
|
76
|
-
* build.
|
|
77
|
-
*/
|
|
78
|
-
export declare const generateBackstopAssertion: (acc: string, schema: JSONSchema, label: string, context: StrictAssertionContext, optional?: boolean) => string[];
|
|
79
|
-
/**
|
|
80
|
-
* Strict-mode `minProperties` / `maxProperties`. Both were read by the coercing
|
|
81
|
-
* expression builder and the subschema matcher but by nothing on the strict
|
|
82
|
-
* path, so a strict parser accepted `{}` against `{ minProperties: 2 }` — at the
|
|
83
|
-
* root, on a property, and inside the empty-object/record parsers alike. `guard`
|
|
84
|
-
* wraps the comparison in a runtime `isObject` for accessors whose type is
|
|
85
|
-
* reported separately; callers that have already proven an object pass `false`.
|
|
86
|
-
*/
|
|
87
|
-
export declare const generateObjectSizeChecks: (acc: string, schema: JSONSchema, label: string, guard: boolean) => string[];
|
|
88
|
-
/**
|
|
89
|
-
* Strict-mode value checks for keys the schema constrains by *pattern* rather
|
|
90
|
-
* than by name: `patternProperties` (every key matching the regex) and a
|
|
91
|
-
* schema-valued `additionalProperties` (every key matched by neither
|
|
92
|
-
* `properties` nor a pattern). Both were read only by the *building* code paths
|
|
93
|
-
* — which coerce or copy — so a strict parser accepted `{ s_a: 1 }` against
|
|
94
|
-
* `patternProperties: { '^s_': { type: 'string' } }`.
|
|
95
|
-
*
|
|
96
|
-
* One `Object.keys` walk covers both, and a term is emitted only when
|
|
97
|
-
* {@link subschemaMatchExpr} proves its subschema exactly. `additionalProperties:
|
|
98
|
-
* false` is not handled here — that is the unknown-key rejection the parsers
|
|
99
|
-
* already emit.
|
|
100
|
-
*/
|
|
101
|
-
export declare const generateKeyedValueChecks: (obj: string, schema: JSONSchema, label: string, context?: StrictAssertionContext) => string[];
|
|
102
|
-
/**
|
|
103
|
-
* Strict-mode `contains` / `minContains` / `maxContains`: at least `minContains`
|
|
104
|
-
* (default 1) and at most `maxContains` (default ∞) items of the array must
|
|
105
|
-
* match the `contains` subschema. Runtime-gated on `Array.isArray` so a
|
|
106
|
-
* non-array value is left to the type check, and wrapped in a block so the
|
|
107
|
-
* per-array count variable never collides with a sibling check. `minContains: 0`
|
|
108
|
-
* makes the lower bound trivially satisfied. Emits nothing when there is no
|
|
109
|
-
* `contains` or its subschema is not matchable inline (the generation-time guard
|
|
110
|
-
* rejects the latter, so a strict parser never silently drops the constraint).
|
|
111
|
-
*/
|
|
112
|
-
export declare const generateContainsCheck: (acc: string, schema: JSONSchema, label: string, context?: StrictAssertionContext) => string[];
|
|
113
|
-
/**
|
|
114
|
-
* The composition checks (`not`, `allOf`, `if`/`then`/`else`) for a value the
|
|
115
|
-
* caller has already proven present. Exported for the specialized object parsers
|
|
116
|
-
* (empty-object, pattern-properties, additionalProperties), which build their
|
|
117
|
-
* result outside {@link generateObjectStrictAssertion} and so would otherwise
|
|
118
|
-
* emit no composition check at all.
|
|
119
|
-
*/
|
|
120
|
-
export declare const generateCompositionChecks: (acc: string, schema: JSONSchema, label: string, context?: StrictAssertionContext) => string[];
|
|
121
|
-
/**
|
|
122
|
-
* Emits the object-level keyword checks (`dependentRequired`, `dependentSchemas`,
|
|
123
|
-
* `propertyNames`) for the object reached by `obj`. When `guard` is true the
|
|
124
|
-
* whole block is wrapped in a runtime `isObject` check — used for object-typed
|
|
125
|
-
* *properties*, whose value may be absent or a non-object (the type check
|
|
126
|
-
* reports that separately). The root object and inline sub-parsers pass
|
|
127
|
-
* `guard = false` because the enclosing parser has already proven the value is
|
|
128
|
-
* an object.
|
|
129
|
-
*/
|
|
130
|
-
export declare const generateObjectKeywordChecks: (obj: string, schema: JSONSchema, label: string, guard: boolean, context?: StrictAssertionContext) => string[];
|
|
131
|
-
/**
|
|
132
|
-
* Generates strict-mode assertions for the body of an object parser.
|
|
133
|
-
* Throws on:
|
|
134
|
-
* - non-object input
|
|
135
|
-
* - missing required property
|
|
136
|
-
* - property of the wrong primitive type
|
|
137
|
-
* - enum / pattern / length / min / max / multipleOf violations
|
|
138
|
-
*
|
|
139
|
-
* Properties with a `$ref` are validated by the nested parser's own strict
|
|
140
|
-
* check when that parser is invoked downstream.
|
|
141
|
-
*/
|
|
142
|
-
/**
|
|
143
|
-
* The `allOf` members this assertion must enforce itself: plain object schemas
|
|
144
|
-
* written inline. A `$ref` member is enforced by the parser generated for its
|
|
145
|
-
* target, and a member that composes further (nested `allOf`/`oneOf`/`if`) is
|
|
146
|
-
* left alone rather than half-checked.
|
|
147
|
-
*/
|
|
148
|
-
export declare const inlineAllOfMembers: (schema: JSONSchema) => JSONSchema[];
|
|
149
|
-
export declare const generateObjectStrictAssertion: (schema: JSONSchema, typeName: string, context?: StrictAssertionContext) => string[];
|
|
150
|
-
/**
|
|
151
|
-
* Generates the strict-mode assertion lines for a non-object (scalar, array,
|
|
152
|
-
* type-less) parser. Returns null when the schema constrains nothing this
|
|
153
|
-
* generator can assert on, which is the caller's cue to emit a bare cast.
|
|
154
|
-
*/
|
|
155
|
-
export declare const generateScalarStrictAssertion: (schema: JSONSchema, typeName: string, context?: StrictAssertionContext) => string | null;
|