@amritk/generate-parsers 0.17.2 → 0.19.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/AI.md +10 -0
- package/README.md +147 -19
- package/dist/generators/assert-supported-keywords.d.ts +13 -9
- package/dist/generators/assert-supported-keywords.js +58 -18
- package/dist/generators/build-schema.d.ts +9 -1
- package/dist/generators/build-schema.js +5 -2
- package/dist/generators/generate-deep-equal-check.d.ts +24 -0
- package/dist/generators/generate-deep-equal-check.js +35 -0
- package/dist/generators/generate-discriminated-union-validation.js +1 -2
- package/dist/generators/generate-enum-check.d.ts +8 -3
- package/dist/generators/generate-enum-check.js +8 -6
- package/dist/generators/generate-files.d.ts +7 -0
- package/dist/generators/generate-files.js +23 -4
- package/dist/generators/generate-parser-function.d.ts +1 -1
- package/dist/generators/generate-parser-function.js +212 -65
- package/dist/generators/generate-schema-checks.js +10 -8
- package/dist/generators/generate-strict-assertion.d.ts +89 -5
- package/dist/generators/generate-strict-assertion.js +429 -58
- package/dist/generators/generate-type-checks.d.ts +46 -10
- package/dist/generators/generate-type-checks.js +112 -16
- package/dist/generators/generate-unique-items-check.d.ts +16 -0
- package/dist/generators/generate-unique-items-check.js +32 -0
- package/dist/generators/generate-validation-expression.d.ts +29 -4
- package/dist/generators/generate-validation-expression.js +15 -6
- package/dist/generators/subschema-match.d.ts +23 -4
- package/dist/generators/subschema-match.js +312 -48
- package/dist/generators/unevaluated-match.d.ts +19 -0
- package/dist/generators/unevaluated-match.js +206 -0
- package/dist/helpers/collect-imports.d.ts +8 -0
- package/dist/helpers/collect-imports.js +1 -1
- package/dist/helpers/get-default-value.js +45 -2
- package/package.json +9 -3
|
@@ -1,14 +1,116 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { regexLiteral } from "@amritk/helpers/escape-regex-pattern";
|
|
2
2
|
import { getMjstInstanceOf, getMjstPrimitive } from "@amritk/helpers/mjst-extension";
|
|
3
3
|
import { multipleOfFailExpr } from "@amritk/helpers/multiple-of-check";
|
|
4
4
|
import { quoteJsString } from "@amritk/helpers/quote-js-string";
|
|
5
5
|
import { resolveRef } from "@amritk/helpers/resolve-ref";
|
|
6
|
-
import { safeAccessor } from "@amritk/helpers/safe-accessor";
|
|
7
|
-
import { hasConst, hasDependentRequired, hasEnum, hasExclusiveMaximum, hasExclusiveMinimum, hasItems, hasMaxItems, hasMaximum, hasMaxLength, hasMinItems, hasMinimum, hasMinLength, hasMultipleOf, hasPattern, hasProperties, hasPropertyNames, hasRef, hasRequired, hasType, hasUniqueItems, isSchemaObject } from "@amritk/helpers/schema-guards";
|
|
6
|
+
import { hasOwnCheck, missingCheck, safeAccessor } from "@amritk/helpers/safe-accessor";
|
|
7
|
+
import { hasConst, hasDependentRequired, hasEnum, hasExclusiveMaximum, hasExclusiveMinimum, hasItems, hasMaxItems, hasMaximum, hasMaxLength, hasMaxProperties, hasMinItems, hasMinimum, hasMinLength, hasMinProperties, hasMultipleOf, hasPattern, hasProperties, hasPropertyNames, hasRef, hasRequired, hasType, hasUniqueItems, isSchemaObject } from "@amritk/helpers/schema-guards";
|
|
8
|
+
import { maxLengthFailExpr, minLengthFailExpr } from "@amritk/helpers/string-length-check";
|
|
9
|
+
import { generateDeepEqualCheck } from "./generate-deep-equal-check.js";
|
|
8
10
|
import { generateEnumCheck } from "./generate-enum-check.js";
|
|
9
|
-
import { canEnforceUnion, generateUnionCheck, getUnionBranches, isInlineObjectProperty } from "./generate-type-checks.js";
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
11
|
+
import { canEnforceUnion, generateUnionCheck, getUnionBranches, isExclusiveUnion, isInlineObjectProperty, multiTypeCheck } from "./generate-type-checks.js";
|
|
12
|
+
import { generateUniqueItemsCheck } from "./generate-unique-items-check.js";
|
|
13
|
+
import { everyTailItem, getPrefixItems, prefixItemsCapsLength, scalarItemTypeCheck } from "./generate-validation-expression.js";
|
|
14
|
+
import { hasConstrainingRefSibling, subschemaMatchExpr } from "./subschema-match.js";
|
|
15
|
+
const matchContext = (context) => context.rootSchema ? { rootSchema: context.rootSchema } : {};
|
|
16
|
+
const TYPELESS_CONSTRAINT_KEYWORDS = [
|
|
17
|
+
"minimum",
|
|
18
|
+
"maximum",
|
|
19
|
+
"exclusiveMinimum",
|
|
20
|
+
"exclusiveMaximum",
|
|
21
|
+
"multipleOf",
|
|
22
|
+
"minLength",
|
|
23
|
+
"maxLength",
|
|
24
|
+
"pattern",
|
|
25
|
+
"minItems",
|
|
26
|
+
"maxItems",
|
|
27
|
+
"uniqueItems",
|
|
28
|
+
"items",
|
|
29
|
+
"prefixItems",
|
|
30
|
+
"contains"
|
|
31
|
+
];
|
|
32
|
+
const TYPELESS_OBJECT_KEYWORDS = [
|
|
33
|
+
"required",
|
|
34
|
+
"minProperties",
|
|
35
|
+
"maxProperties",
|
|
36
|
+
"propertyNames",
|
|
37
|
+
"patternProperties",
|
|
38
|
+
"additionalProperties",
|
|
39
|
+
"dependentRequired",
|
|
40
|
+
"dependentSchemas"
|
|
41
|
+
];
|
|
42
|
+
const backstopReason = (schema, context) => {
|
|
43
|
+
if (!isSchemaObject(schema))
|
|
44
|
+
return null;
|
|
45
|
+
const record = schema;
|
|
46
|
+
if ("unevaluatedProperties" in record && record["unevaluatedProperties"] !== true)
|
|
47
|
+
return "unevaluatedProperties";
|
|
48
|
+
if ("unevaluatedItems" in record && record["unevaluatedItems"] !== true)
|
|
49
|
+
return "unevaluatedItems";
|
|
50
|
+
if (hasRef(schema) && (!context.useRefImports || hasConstrainingRefSibling(schema)))
|
|
51
|
+
return "$ref";
|
|
52
|
+
if (record["items"] === false && !Array.isArray(record["prefixItems"]))
|
|
53
|
+
return "items";
|
|
54
|
+
if (!("type" in record)) {
|
|
55
|
+
if (TYPELESS_CONSTRAINT_KEYWORDS.some((keyword) => keyword in record))
|
|
56
|
+
return "constraints";
|
|
57
|
+
if (!("properties" in record) && TYPELESS_OBJECT_KEYWORDS.some((keyword) => keyword in record))
|
|
58
|
+
return "constraints";
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
if (Array.isArray(record["type"])) {
|
|
62
|
+
const nonNull = record["type"].filter((type) => type !== "null");
|
|
63
|
+
const constrains = TYPELESS_CONSTRAINT_KEYWORDS.some((keyword) => keyword in record) || TYPELESS_OBJECT_KEYWORDS.some((keyword) => keyword in record);
|
|
64
|
+
if (nonNull.length > 1 && constrains)
|
|
65
|
+
return "constraints";
|
|
66
|
+
}
|
|
67
|
+
return null;
|
|
68
|
+
};
|
|
69
|
+
const backstopSchema = (schema, reason) => {
|
|
70
|
+
if (reason !== "constraints" && reason !== "items")
|
|
71
|
+
return schema;
|
|
72
|
+
const record = schema;
|
|
73
|
+
const residual = {};
|
|
74
|
+
for (const keyword of [
|
|
75
|
+
"type",
|
|
76
|
+
...TYPELESS_CONSTRAINT_KEYWORDS,
|
|
77
|
+
...TYPELESS_OBJECT_KEYWORDS,
|
|
78
|
+
"minContains",
|
|
79
|
+
"maxContains"
|
|
80
|
+
]) {
|
|
81
|
+
if (keyword in record)
|
|
82
|
+
residual[keyword] = record[keyword];
|
|
83
|
+
}
|
|
84
|
+
if ("additionalProperties" in residual && "properties" in record) {
|
|
85
|
+
const properties = record["properties"];
|
|
86
|
+
if (typeof properties === "object" && properties !== null && !Array.isArray(properties)) {
|
|
87
|
+
residual["properties"] = Object.fromEntries(Object.keys(properties).map((k) => [k, true]));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return residual;
|
|
91
|
+
};
|
|
92
|
+
const backstopMessage = (reason, label) => {
|
|
93
|
+
switch (reason) {
|
|
94
|
+
case "unevaluatedProperties":
|
|
95
|
+
return `${label} must NOT have unevaluated properties`;
|
|
96
|
+
case "unevaluatedItems":
|
|
97
|
+
return `${label} must NOT have unevaluated items`;
|
|
98
|
+
case "$ref":
|
|
99
|
+
return `${label} does not satisfy the referenced schema`;
|
|
100
|
+
default:
|
|
101
|
+
return `${label} does not satisfy the schema`;
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
const generateBackstopAssertion = (acc, schema, label, context, optional = false) => {
|
|
105
|
+
const reason = backstopReason(schema, context);
|
|
106
|
+
if (reason === null)
|
|
107
|
+
return [];
|
|
108
|
+
const match = subschemaMatchExpr(acc, backstopSchema(schema, reason), matchContext(context));
|
|
109
|
+
if (match === null || match === "true")
|
|
110
|
+
return [];
|
|
111
|
+
const failure = throwError(backstopMessage(reason, label));
|
|
112
|
+
return [optional ? ` if (${acc} !== undefined && !(${match})) ${failure};` : ` if (!(${match})) ${failure};`];
|
|
113
|
+
};
|
|
12
114
|
const wrongTypeCondition = (accessor, type) => {
|
|
13
115
|
switch (type) {
|
|
14
116
|
case "string":
|
|
@@ -41,28 +143,28 @@ const generateConstraintChecks = (acc, propSchema, field, context = {}) => {
|
|
|
41
143
|
const lines = [];
|
|
42
144
|
if (t === "string") {
|
|
43
145
|
if (hasPattern(propSchema)) {
|
|
44
|
-
const
|
|
45
|
-
lines.push(` if (typeof ${acc} === "string" &&
|
|
146
|
+
const patternLiteral = regexLiteral(propSchema.pattern);
|
|
147
|
+
lines.push(` if (typeof ${acc} === "string" && !${patternLiteral}.test(${acc})) ${throwError(`${field} must match pattern ${propSchema.pattern}`)};`);
|
|
46
148
|
}
|
|
47
149
|
if (hasMinLength(propSchema)) {
|
|
48
|
-
lines.push(` if (typeof ${acc} === "string" && ${acc
|
|
150
|
+
lines.push(` if (typeof ${acc} === "string" && ${minLengthFailExpr(acc, propSchema.minLength)}) ${throwError(`${field} must have at least ${propSchema.minLength} characters`)};`);
|
|
49
151
|
}
|
|
50
152
|
if (hasMaxLength(propSchema)) {
|
|
51
|
-
lines.push(` if (typeof ${acc} === "string" && ${acc
|
|
153
|
+
lines.push(` if (typeof ${acc} === "string" && ${maxLengthFailExpr(acc, propSchema.maxLength)}) ${throwError(`${field} must have at most ${propSchema.maxLength} characters`)};`);
|
|
52
154
|
}
|
|
53
155
|
}
|
|
54
156
|
if (t === "number" || t === "integer") {
|
|
55
157
|
if (hasMinimum(propSchema)) {
|
|
56
|
-
lines.push(` if (typeof ${acc} === "number" && ${acc}
|
|
158
|
+
lines.push(` if (typeof ${acc} === "number" && !(${acc} >= ${propSchema.minimum})) ${throwError(`${field} must be >= ${propSchema.minimum}`)};`);
|
|
57
159
|
}
|
|
58
160
|
if (hasMaximum(propSchema)) {
|
|
59
|
-
lines.push(` if (typeof ${acc} === "number" && ${acc}
|
|
161
|
+
lines.push(` if (typeof ${acc} === "number" && !(${acc} <= ${propSchema.maximum})) ${throwError(`${field} must be <= ${propSchema.maximum}`)};`);
|
|
60
162
|
}
|
|
61
163
|
if (hasExclusiveMinimum(propSchema)) {
|
|
62
|
-
lines.push(` if (typeof ${acc} === "number" && ${acc}
|
|
164
|
+
lines.push(` if (typeof ${acc} === "number" && !(${acc} > ${propSchema.exclusiveMinimum})) ${throwError(`${field} must be > ${propSchema.exclusiveMinimum}`)};`);
|
|
63
165
|
}
|
|
64
166
|
if (hasExclusiveMaximum(propSchema)) {
|
|
65
|
-
lines.push(` if (typeof ${acc} === "number" && ${acc}
|
|
167
|
+
lines.push(` if (typeof ${acc} === "number" && !(${acc} < ${propSchema.exclusiveMaximum})) ${throwError(`${field} must be < ${propSchema.exclusiveMaximum}`)};`);
|
|
66
168
|
}
|
|
67
169
|
if (hasMultipleOf(propSchema)) {
|
|
68
170
|
lines.push(` if (typeof ${acc} === "number" && ${multipleOfFailExpr(acc, propSchema.multipleOf)}) ${throwError(`${field} must be a multiple of ${propSchema.multipleOf}`)};`);
|
|
@@ -76,17 +178,33 @@ const generateConstraintChecks = (acc, propSchema, field, context = {}) => {
|
|
|
76
178
|
lines.push(` if (Array.isArray(${acc}) && ${acc}.length > ${propSchema.maxItems}) ${throwError(`${field} must have at most ${propSchema.maxItems} items`)};`);
|
|
77
179
|
}
|
|
78
180
|
if (hasUniqueItems(propSchema) && propSchema.uniqueItems === true) {
|
|
79
|
-
lines.push(` if (Array.isArray(${acc}) &&
|
|
181
|
+
lines.push(` if (Array.isArray(${acc}) && !(${generateUniqueItemsCheck(acc, propSchema)})) ${throwError(`${field} must NOT have duplicate items`)};`);
|
|
80
182
|
}
|
|
81
|
-
const itemCheck = generateItemCheck(propSchema);
|
|
183
|
+
const itemCheck = generateItemCheck(propSchema, context);
|
|
82
184
|
if (itemCheck) {
|
|
83
|
-
lines.push(` if (Array.isArray(${acc}) && !${acc
|
|
185
|
+
lines.push(` if (Array.isArray(${acc}) && !${everyTailItem(acc, itemCheck.check, propSchema)}) ${throwError(`${field} ${itemCheck.message}`)};`);
|
|
84
186
|
}
|
|
85
|
-
lines.push(...generatePrefixItemsAssertion(acc, field, propSchema, context
|
|
187
|
+
lines.push(...generatePrefixItemsAssertion(acc, field, propSchema, context));
|
|
188
|
+
}
|
|
189
|
+
if (t === "object") {
|
|
190
|
+
lines.push(...generateObjectSizeChecks(acc, propSchema, field, true));
|
|
86
191
|
}
|
|
87
192
|
return lines;
|
|
88
193
|
};
|
|
89
|
-
const
|
|
194
|
+
const generateObjectSizeChecks = (acc, schema, label, guard) => {
|
|
195
|
+
if (!isSchemaObject(schema))
|
|
196
|
+
return [];
|
|
197
|
+
const lines = [];
|
|
198
|
+
const prefix = guard ? `isObject(${acc}) && ` : "";
|
|
199
|
+
if (hasMinProperties(schema)) {
|
|
200
|
+
lines.push(` if (${prefix}Object.keys(${acc}).length < ${schema.minProperties}) ${throwError(`${label} must have at least ${schema.minProperties} properties`)};`);
|
|
201
|
+
}
|
|
202
|
+
if (hasMaxProperties(schema)) {
|
|
203
|
+
lines.push(` if (${prefix}Object.keys(${acc}).length > ${schema.maxProperties}) ${throwError(`${label} must have at most ${schema.maxProperties} properties`)};`);
|
|
204
|
+
}
|
|
205
|
+
return lines;
|
|
206
|
+
};
|
|
207
|
+
const generateItemCheck = (schema, context) => {
|
|
90
208
|
if (!isSchemaObject(schema) || !hasItems(schema) || Array.isArray(schema.items))
|
|
91
209
|
return null;
|
|
92
210
|
const items = schema.items;
|
|
@@ -95,17 +213,175 @@ const generateItemCheck = (schema) => {
|
|
|
95
213
|
return { check: generateEnumCheck("_it", items.enum), message: `items must be one of: ${label}` };
|
|
96
214
|
}
|
|
97
215
|
const scalarCheck = scalarItemTypeCheck(items, "_it");
|
|
98
|
-
if (scalarCheck
|
|
216
|
+
if (scalarCheck !== null && isSchemaObject(items) && hasType(items)) {
|
|
217
|
+
return { check: scalarCheck, message: `items expected ${typeLabel(items.type)}` };
|
|
218
|
+
}
|
|
219
|
+
if (hasRef(items) && context.useRefImports === true || isInlineObjectProperty(items))
|
|
99
220
|
return null;
|
|
100
|
-
|
|
221
|
+
const match = subschemaMatchExpr("_it", items, matchContext(context));
|
|
222
|
+
if (match === null || match === "true")
|
|
223
|
+
return null;
|
|
224
|
+
return { check: match, message: "items do not match the item schema" };
|
|
225
|
+
};
|
|
226
|
+
const nullableObjectShapeChecks = (acc, schema, type, label, optional, context) => {
|
|
227
|
+
if (type !== "object")
|
|
228
|
+
return [];
|
|
229
|
+
const match = subschemaMatchExpr(acc, { ...schema, type: "object" }, matchContext(context));
|
|
230
|
+
if (match === null || match === "true")
|
|
231
|
+
return [];
|
|
232
|
+
const presence = optional ? `${acc} !== undefined && ${acc} !== null` : `${acc} !== null`;
|
|
233
|
+
return [` if (${presence} && !(${match})) ${throwError(`${label} does not match the declared object shape`)};`];
|
|
234
|
+
};
|
|
235
|
+
const generateNotCheck = (acc, schema, label, optional, context) => {
|
|
236
|
+
if (!isSchemaObject(schema) || !("not" in schema))
|
|
237
|
+
return [];
|
|
238
|
+
const match = subschemaMatchExpr(acc, schema["not"], matchContext(context));
|
|
239
|
+
if (match === null || match === "false")
|
|
240
|
+
return [];
|
|
241
|
+
const failure = throwError(`${label} must NOT match the excluded schema`);
|
|
242
|
+
return [optional ? ` if (${acc} !== undefined && (${match})) ${failure};` : ` if (${match}) ${failure};`];
|
|
243
|
+
};
|
|
244
|
+
const generateAllOfChecks = (acc, schema, label, optional, context, skipInlineMembers = false) => {
|
|
245
|
+
if (!isSchemaObject(schema) || !Array.isArray(schema.allOf))
|
|
246
|
+
return [];
|
|
247
|
+
const handledInline = new Set(skipInlineMembers ? inlineAllOfMembers(schema) : []);
|
|
248
|
+
const lines = [];
|
|
249
|
+
for (const member of schema.allOf) {
|
|
250
|
+
if (handledInline.has(member))
|
|
251
|
+
continue;
|
|
252
|
+
const delegated = context.useRefImports === true && hasProperties(schema) && !hasConstrainingRefSibling(member);
|
|
253
|
+
if (isSchemaObject(member) && hasRef(member) && delegated)
|
|
254
|
+
continue;
|
|
255
|
+
const match = subschemaMatchExpr(acc, member, matchContext(context));
|
|
256
|
+
if (match === null || match === "true")
|
|
257
|
+
continue;
|
|
258
|
+
const failure = throwError(`${label} does not satisfy all of the declared schemas`);
|
|
259
|
+
lines.push(optional ? ` if (${acc} !== undefined && !(${match})) ${failure};` : ` if (!(${match})) ${failure};`);
|
|
260
|
+
}
|
|
261
|
+
return lines;
|
|
101
262
|
};
|
|
102
|
-
const
|
|
263
|
+
const flatUnionCheck = (acc, schema, context) => {
|
|
264
|
+
const branches = getUnionBranches(schema);
|
|
265
|
+
if (branches === null || context.stripUnknown === true)
|
|
266
|
+
return null;
|
|
267
|
+
if (!canEnforceUnion(branches, context.rootSchema))
|
|
268
|
+
return null;
|
|
269
|
+
return generateUnionCheck(acc, branches, context.useRefImports ?? false, context.suffix ?? "", isExclusiveUnion(schema));
|
|
270
|
+
};
|
|
271
|
+
const generateUnionMatchChecks = (acc, schema, label, optional, context) => {
|
|
272
|
+
if (!isSchemaObject(schema))
|
|
273
|
+
return [];
|
|
274
|
+
const record = schema;
|
|
275
|
+
const covered = flatUnionCheck(acc, schema, context) === null ? void 0 : isExclusiveUnion(schema) ? "oneOf" : "anyOf";
|
|
276
|
+
const lines = [];
|
|
277
|
+
for (const keyword of ["anyOf", "oneOf"]) {
|
|
278
|
+
if (keyword === covered)
|
|
279
|
+
continue;
|
|
280
|
+
const members = record[keyword];
|
|
281
|
+
if (!Array.isArray(members) || members.length === 0)
|
|
282
|
+
continue;
|
|
283
|
+
const matches = [];
|
|
284
|
+
for (const member of members) {
|
|
285
|
+
const match = subschemaMatchExpr(acc, member, matchContext(context));
|
|
286
|
+
if (match === null)
|
|
287
|
+
break;
|
|
288
|
+
matches.push(match);
|
|
289
|
+
}
|
|
290
|
+
if (matches.length !== members.length)
|
|
291
|
+
continue;
|
|
292
|
+
const check = unionMatchExpr(keyword, matches);
|
|
293
|
+
if (check === null || check === "true")
|
|
294
|
+
continue;
|
|
295
|
+
const failure = throwError(`${label} does not match ${keyword === "anyOf" ? "any of" : "exactly one of"} the declared schemas`);
|
|
296
|
+
lines.push(optional ? ` if (${acc} !== undefined && !(${check})) ${failure};` : ` if (!(${check})) ${failure};`);
|
|
297
|
+
}
|
|
298
|
+
return lines;
|
|
299
|
+
};
|
|
300
|
+
const unionMatchExpr = (keyword, matches) => {
|
|
301
|
+
if (keyword === "anyOf") {
|
|
302
|
+
if (matches.includes("true"))
|
|
303
|
+
return null;
|
|
304
|
+
return matches.length === 1 ? matches[0] : `(${matches.join(" || ")})`;
|
|
305
|
+
}
|
|
306
|
+
if (matches.length === 1)
|
|
307
|
+
return matches[0];
|
|
308
|
+
return `((${matches.map((match) => `(${match} ? 1 : 0)`).join(" + ")}) === 1)`;
|
|
309
|
+
};
|
|
310
|
+
const generateConditionalChecks = (acc, schema, label, context) => {
|
|
311
|
+
if (!isSchemaObject(schema))
|
|
312
|
+
return [];
|
|
313
|
+
const record = schema;
|
|
314
|
+
if (!("if" in record) || !("then" in record) && !("else" in record))
|
|
315
|
+
return [];
|
|
316
|
+
const ifMatch = subschemaMatchExpr(acc, record["if"], matchContext(context));
|
|
317
|
+
if (ifMatch === null)
|
|
318
|
+
return [];
|
|
319
|
+
const lines = [];
|
|
320
|
+
if ("then" in record) {
|
|
321
|
+
const thenMatch = subschemaMatchExpr(acc, record["then"], matchContext(context));
|
|
322
|
+
if (thenMatch === null)
|
|
323
|
+
return [];
|
|
324
|
+
if (thenMatch !== "true") {
|
|
325
|
+
lines.push(` if ((${ifMatch}) && !(${thenMatch})) ${throwError(`${label} does not satisfy the 'then' schema`)};`);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
if ("else" in record) {
|
|
329
|
+
const elseMatch = subschemaMatchExpr(acc, record["else"], matchContext(context));
|
|
330
|
+
if (elseMatch === null)
|
|
331
|
+
return [];
|
|
332
|
+
if (elseMatch !== "true") {
|
|
333
|
+
lines.push(` if (!(${ifMatch}) && !(${elseMatch})) ${throwError(`${label} does not satisfy the 'else' schema`)};`);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
return lines;
|
|
337
|
+
};
|
|
338
|
+
const generateKeyedValueChecks = (obj, schema, label, context = {}) => {
|
|
339
|
+
if (!isSchemaObject(schema))
|
|
340
|
+
return [];
|
|
341
|
+
const record = schema;
|
|
342
|
+
const patternEntries = [];
|
|
343
|
+
const patternSource = record["patternProperties"];
|
|
344
|
+
if (typeof patternSource === "object" && patternSource !== null && !Array.isArray(patternSource)) {
|
|
345
|
+
for (const [pattern, sub] of Object.entries(patternSource)) {
|
|
346
|
+
const match = subschemaMatchExpr("_v", sub, matchContext(context));
|
|
347
|
+
if (match === null || match === "true")
|
|
348
|
+
continue;
|
|
349
|
+
patternEntries.push([pattern, match]);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
const allPatterns = typeof patternSource === "object" && patternSource !== null && !Array.isArray(patternSource) ? Object.keys(patternSource) : [];
|
|
353
|
+
const additional = record["additionalProperties"];
|
|
354
|
+
const additionalMatch = additional !== void 0 && typeof additional !== "boolean" ? subschemaMatchExpr("_v", additional, matchContext(context)) : null;
|
|
355
|
+
const lines = [];
|
|
356
|
+
for (const [pattern, match] of patternEntries) {
|
|
357
|
+
lines.push(` if (${regexLiteral(pattern)}.test(_k) && !(${match})) ${throwError(`${label} invalid value for property `, "_k")};`);
|
|
358
|
+
}
|
|
359
|
+
if (additionalMatch !== null && additionalMatch !== "true") {
|
|
360
|
+
const declared = hasProperties(schema) ? Object.keys(schema.properties) : [];
|
|
361
|
+
const guards = [];
|
|
362
|
+
if (declared.length > 0)
|
|
363
|
+
guards.push(`!${JSON.stringify(declared)}.includes(_k)`);
|
|
364
|
+
for (const pattern of allPatterns)
|
|
365
|
+
guards.push(`!${regexLiteral(pattern)}.test(_k)`);
|
|
366
|
+
const prefix = guards.length > 0 ? `${guards.join(" && ")} && ` : "";
|
|
367
|
+
lines.push(` if (${prefix}!(${additionalMatch})) ${throwError(`${label} invalid value for property `, "_k")};`);
|
|
368
|
+
}
|
|
369
|
+
if (lines.length === 0)
|
|
370
|
+
return [];
|
|
371
|
+
return [
|
|
372
|
+
` for (const _k of Object.keys(${obj})) {`,
|
|
373
|
+
` const _v = (${obj} as Record<string, unknown>)[_k];`,
|
|
374
|
+
...lines,
|
|
375
|
+
` }`
|
|
376
|
+
];
|
|
377
|
+
};
|
|
378
|
+
const generateContainsCheck = (acc, schema, label, context = {}) => {
|
|
103
379
|
if (!isSchemaObject(schema))
|
|
104
380
|
return [];
|
|
105
381
|
const sp = schema;
|
|
106
382
|
if (!("contains" in sp))
|
|
107
383
|
return [];
|
|
108
|
-
const match = subschemaMatchExpr("_c", sp["contains"]);
|
|
384
|
+
const match = subschemaMatchExpr("_c", sp["contains"], matchContext(context));
|
|
109
385
|
if (match === null)
|
|
110
386
|
return [];
|
|
111
387
|
const min = typeof sp["minContains"] === "number" ? sp["minContains"] : 1;
|
|
@@ -126,12 +402,12 @@ const generateDependentRequiredChecks = (obj, schema, label) => {
|
|
|
126
402
|
if (!Array.isArray(deps))
|
|
127
403
|
continue;
|
|
128
404
|
for (const dep of deps) {
|
|
129
|
-
lines.push(` if (${
|
|
405
|
+
lines.push(` if (${hasOwnCheck(obj, trigger)} && ${missingCheck(obj, dep)}) ${throwError(`${label} must have property '${dep}' when '${trigger}' is present`)};`);
|
|
130
406
|
}
|
|
131
407
|
}
|
|
132
408
|
return lines;
|
|
133
409
|
};
|
|
134
|
-
const generateDependentSchemasChecks = (obj, schema, label) => {
|
|
410
|
+
const generateDependentSchemasChecks = (obj, schema, label, context) => {
|
|
135
411
|
const dep = schema["dependentSchemas"];
|
|
136
412
|
if (typeof dep !== "object" || dep === null || Array.isArray(dep))
|
|
137
413
|
return [];
|
|
@@ -140,13 +416,13 @@ const generateDependentSchemasChecks = (obj, schema, label) => {
|
|
|
140
416
|
if (sub === true)
|
|
141
417
|
continue;
|
|
142
418
|
if (sub === false) {
|
|
143
|
-
lines.push(` if (${
|
|
419
|
+
lines.push(` if (${hasOwnCheck(obj, trigger)}) ${throwError(`${label} must NOT have property '${trigger}'`)};`);
|
|
144
420
|
continue;
|
|
145
421
|
}
|
|
146
|
-
const match = subschemaMatchExpr(obj, sub);
|
|
422
|
+
const match = subschemaMatchExpr(obj, sub, matchContext(context));
|
|
147
423
|
if (match === null || match === "true")
|
|
148
424
|
continue;
|
|
149
|
-
lines.push(` if (${
|
|
425
|
+
lines.push(` if (${hasOwnCheck(obj, trigger)} && !(${match})) ${throwError(`${label} does not satisfy the schema required when '${trigger}' is present`)};`);
|
|
150
426
|
}
|
|
151
427
|
return lines;
|
|
152
428
|
};
|
|
@@ -158,7 +434,8 @@ const resolvePositionSchema = (pos, rootSchema) => {
|
|
|
158
434
|
}
|
|
159
435
|
return pos;
|
|
160
436
|
};
|
|
161
|
-
const generatePrefixItemsAssertion = (acc, field, schema,
|
|
437
|
+
const generatePrefixItemsAssertion = (acc, field, schema, context) => {
|
|
438
|
+
const rootSchema = context.rootSchema;
|
|
162
439
|
const prefix = getPrefixItems(schema);
|
|
163
440
|
if (!prefix)
|
|
164
441
|
return [];
|
|
@@ -168,9 +445,8 @@ const generatePrefixItemsAssertion = (acc, field, schema, rootSchema) => {
|
|
|
168
445
|
const el = `${acc}[${i}]`;
|
|
169
446
|
const present = `Array.isArray(${acc}) && ${acc}.length > ${i}`;
|
|
170
447
|
if (isSchemaObject(pos) && hasEnum(pos) && pos.enum.length > 0) {
|
|
171
|
-
const allowed = JSON.stringify(pos.enum);
|
|
172
448
|
const label = pos.enum.map((v) => JSON.stringify(v)).join(", ");
|
|
173
|
-
lines.push(` if (${present} &&
|
|
449
|
+
lines.push(` if (${present} && !${generateEnumCheck(el, pos.enum)}) ${throwError(`${field}[${i}] must be one of: ${label}`)};`);
|
|
174
450
|
continue;
|
|
175
451
|
}
|
|
176
452
|
if (isSchemaObject(pos) && hasType(pos)) {
|
|
@@ -180,16 +456,20 @@ const generatePrefixItemsAssertion = (acc, field, schema, rootSchema) => {
|
|
|
180
456
|
lines.push(` if (${present} && (${wrong})) ${throwError(`${field}[${i}] expected ${typeLabel(pt)}, got `, `typeof ${el}`)};`);
|
|
181
457
|
}
|
|
182
458
|
}
|
|
459
|
+
const match = subschemaMatchExpr(el, prefix[i], matchContext(context));
|
|
460
|
+
if (match !== null && match !== "true") {
|
|
461
|
+
lines.push(` if (${present} && !(${match})) ${throwError(`${field}[${i}] does not match the tuple schema`)};`);
|
|
462
|
+
}
|
|
183
463
|
}
|
|
184
464
|
if (prefixItemsCapsLength(schema)) {
|
|
185
465
|
lines.push(` if (Array.isArray(${acc}) && ${acc}.length > ${prefix.length}) ${throwError(`${field} must NOT have more than ${prefix.length} items`)};`);
|
|
186
466
|
}
|
|
187
467
|
return lines;
|
|
188
468
|
};
|
|
189
|
-
const generatePropertyNameChecks = (obj, schema, label) => {
|
|
469
|
+
const generatePropertyNameChecks = (obj, schema, label, context) => {
|
|
190
470
|
if (!hasPropertyNames(schema) || !isSchemaObject(schema.propertyNames))
|
|
191
471
|
return [];
|
|
192
|
-
const match = subschemaMatchExpr("_name", schema.propertyNames);
|
|
472
|
+
const match = subschemaMatchExpr("_name", schema.propertyNames, matchContext(context));
|
|
193
473
|
if (match === null || match === "true")
|
|
194
474
|
return [];
|
|
195
475
|
return [
|
|
@@ -198,13 +478,19 @@ const generatePropertyNameChecks = (obj, schema, label) => {
|
|
|
198
478
|
` }`
|
|
199
479
|
];
|
|
200
480
|
};
|
|
201
|
-
const
|
|
481
|
+
const generateCompositionChecks = (acc, schema, label, context = {}) => [
|
|
482
|
+
...generateNotCheck(acc, schema, label, false, context),
|
|
483
|
+
...generateAllOfChecks(acc, schema, label, false, context),
|
|
484
|
+
...generateUnionMatchChecks(acc, schema, label, false, context),
|
|
485
|
+
...generateConditionalChecks(acc, schema, label, context)
|
|
486
|
+
];
|
|
487
|
+
const generateObjectKeywordChecks = (obj, schema, label, guard, context = {}) => {
|
|
202
488
|
if (!isSchemaObject(schema))
|
|
203
489
|
return [];
|
|
204
490
|
const inner = [
|
|
205
491
|
...generateDependentRequiredChecks(obj, schema, label),
|
|
206
|
-
...generateDependentSchemasChecks(obj, schema, label),
|
|
207
|
-
...generatePropertyNameChecks(obj, schema, label)
|
|
492
|
+
...generateDependentSchemasChecks(obj, schema, label, context),
|
|
493
|
+
...generatePropertyNameChecks(obj, schema, label, context)
|
|
208
494
|
];
|
|
209
495
|
if (inner.length === 0)
|
|
210
496
|
return [];
|
|
@@ -217,16 +503,25 @@ const generatePropertyAssertion = (key, propSchema, isRequired, typeName, contex
|
|
|
217
503
|
const field = `[${typeName}] field '${key}'`;
|
|
218
504
|
const lines = [];
|
|
219
505
|
if (isRequired) {
|
|
220
|
-
lines.push(` if (
|
|
506
|
+
lines.push(` if (${missingCheck("input", key)}) ${throwError(`[${typeName}] missing required property '${key}'`)};`);
|
|
507
|
+
}
|
|
508
|
+
if (propSchema === false) {
|
|
509
|
+
lines.push(` if (${hasOwnCheck("input", key)}) ${throwError(`[${typeName}] must NOT have property '${key}'`)};`);
|
|
510
|
+
return lines;
|
|
221
511
|
}
|
|
222
512
|
if (!isSchemaObject(propSchema))
|
|
223
513
|
return lines;
|
|
514
|
+
lines.push(...generateBackstopAssertion(acc, propSchema, field, context, !isRequired));
|
|
224
515
|
if (hasRef(propSchema))
|
|
225
516
|
return lines;
|
|
517
|
+
lines.push(...generateNotCheck(acc, propSchema, field, !isRequired, context));
|
|
518
|
+
lines.push(...generateAllOfChecks(acc, propSchema, field, !isRequired, context));
|
|
519
|
+
lines.push(...generateUnionMatchChecks(acc, propSchema, field, !isRequired, context));
|
|
520
|
+
lines.push(...generateConditionalChecks(acc, propSchema, field, context));
|
|
226
521
|
const unionBranches = getUnionBranches(propSchema);
|
|
227
522
|
if (unionBranches) {
|
|
228
523
|
if (!context.stripUnknown && canEnforceUnion(unionBranches, context.rootSchema)) {
|
|
229
|
-
const check = generateUnionCheck(acc, unionBranches, context.useRefImports ?? false, context.suffix ?? "");
|
|
524
|
+
const check = generateUnionCheck(acc, unionBranches, context.useRefImports ?? false, context.suffix ?? "", isExclusiveUnion(propSchema));
|
|
230
525
|
if (check !== null) {
|
|
231
526
|
const failure = throwError(`${field} does not match any allowed variant`);
|
|
232
527
|
lines.push(isRequired ? ` if (!(${check})) ${failure};` : ` if (${acc} !== undefined && !(${check})) ${failure};`);
|
|
@@ -252,13 +547,33 @@ const generatePropertyAssertion = (key, propSchema, isRequired, typeName, contex
|
|
|
252
547
|
}
|
|
253
548
|
return lines;
|
|
254
549
|
}
|
|
550
|
+
if (hasConst(propSchema)) {
|
|
551
|
+
const equal = generateDeepEqualCheck(acc, propSchema.const);
|
|
552
|
+
const failure = throwError(`${field} must be ${JSON.stringify(propSchema.const)}`);
|
|
553
|
+
lines.push(isRequired ? ` if (!(${equal})) ${failure};` : ` if (${acc} !== undefined && !(${equal})) ${failure};`);
|
|
554
|
+
return lines;
|
|
555
|
+
}
|
|
255
556
|
if (hasEnum(propSchema)) {
|
|
256
|
-
const
|
|
557
|
+
const member = generateEnumCheck(acc, propSchema.enum);
|
|
257
558
|
const label = propSchema.enum.map((v) => JSON.stringify(v)).join(", ");
|
|
258
559
|
if (isRequired) {
|
|
259
|
-
lines.push(` if (
|
|
560
|
+
lines.push(` if (!${member}) ${throwError(`${field} must be one of: ${label}`)};`);
|
|
260
561
|
} else {
|
|
261
|
-
lines.push(` if (${acc} !== undefined &&
|
|
562
|
+
lines.push(` if (${acc} !== undefined && !${member}) ${throwError(`${field} must be one of: ${label}`)};`);
|
|
563
|
+
}
|
|
564
|
+
return lines;
|
|
565
|
+
}
|
|
566
|
+
const multiType = multiTypeCheck(acc, propSchema, { ignoreConstraints: true });
|
|
567
|
+
if (multiType !== void 0) {
|
|
568
|
+
const types = propSchema.type;
|
|
569
|
+
if (multiType !== null) {
|
|
570
|
+
const expected = throwError(`${field} expected ${types.map(typeLabel).join(" | ")}, got `, `typeof ${acc}`);
|
|
571
|
+
lines.push(isRequired ? ` if (!${multiType}) ${expected};` : ` if (${acc} !== undefined && !${multiType}) ${expected};`);
|
|
572
|
+
}
|
|
573
|
+
const nonNull = types.filter((type) => type !== "null");
|
|
574
|
+
if (nonNull.length === 1) {
|
|
575
|
+
lines.push(...generateConstraintChecks(acc, { ...propSchema, type: nonNull[0] }, field, context));
|
|
576
|
+
lines.push(...nullableObjectShapeChecks(acc, propSchema, nonNull[0], field, !isRequired, context));
|
|
262
577
|
}
|
|
263
578
|
return lines;
|
|
264
579
|
}
|
|
@@ -278,32 +593,69 @@ const generatePropertyAssertion = (key, propSchema, isRequired, typeName, contex
|
|
|
278
593
|
if (isSchemaObject(propSchema)) {
|
|
279
594
|
const r = propSchema;
|
|
280
595
|
if ("contains" in r)
|
|
281
|
-
lines.push(...generateContainsCheck(acc, propSchema, field));
|
|
596
|
+
lines.push(...generateContainsCheck(acc, propSchema, field, context));
|
|
282
597
|
if (("dependentRequired" in r || "dependentSchemas" in r || "propertyNames" in r) && !isInlineObjectProperty(propSchema)) {
|
|
283
|
-
lines.push(...generateObjectKeywordChecks(acc, propSchema, field, true));
|
|
598
|
+
lines.push(...generateObjectKeywordChecks(acc, propSchema, field, true, context));
|
|
599
|
+
}
|
|
600
|
+
if ("patternProperties" in r || isSchemaObject(propSchema) && typeof r["additionalProperties"] === "object") {
|
|
601
|
+
const keyed = generateKeyedValueChecks(acc, propSchema, field, context);
|
|
602
|
+
if (keyed.length > 0) {
|
|
603
|
+
lines.push(` if (isObject(${acc})) {`, ...keyed.map((line) => ` ${line}`), ` }`);
|
|
604
|
+
}
|
|
284
605
|
}
|
|
285
606
|
}
|
|
286
607
|
return lines;
|
|
287
608
|
};
|
|
609
|
+
const inlineAllOfMembers = (schema) => {
|
|
610
|
+
if (!isSchemaObject(schema) || !Array.isArray(schema.allOf))
|
|
611
|
+
return [];
|
|
612
|
+
return schema.allOf.filter((member) => {
|
|
613
|
+
if (!isSchemaObject(member) || hasRef(member))
|
|
614
|
+
return false;
|
|
615
|
+
const record = member;
|
|
616
|
+
if ("allOf" in record || "oneOf" in record || "anyOf" in record || "not" in record)
|
|
617
|
+
return false;
|
|
618
|
+
if ("if" in record || "then" in record || "else" in record)
|
|
619
|
+
return false;
|
|
620
|
+
return hasProperties(member) || hasRequired(member);
|
|
621
|
+
});
|
|
622
|
+
};
|
|
288
623
|
const generateObjectStrictAssertion = (schema, typeName, context = {}) => {
|
|
289
624
|
const lines = [];
|
|
290
625
|
lines.push(` if (!isObject(input)) ${throwError(`[${typeName}] expected object, got `, 'input === null ? "null" : typeof input')};`);
|
|
291
626
|
if (!isSchemaObject(schema))
|
|
292
627
|
return lines;
|
|
628
|
+
const required = new Set(hasRequired(schema) ? schema.required : []);
|
|
293
629
|
if (hasProperties(schema)) {
|
|
294
|
-
const required = new Set(hasRequired(schema) ? schema.required : []);
|
|
295
630
|
const props = schema.properties;
|
|
296
631
|
for (const key in props) {
|
|
297
632
|
lines.push(...generatePropertyAssertion(key, props[key], required.has(key), typeName, context));
|
|
298
633
|
}
|
|
634
|
+
for (const key in props)
|
|
635
|
+
required.delete(key);
|
|
636
|
+
}
|
|
637
|
+
for (const key of required) {
|
|
638
|
+
lines.push(` if (${missingCheck("input", key)}) ${throwError(`[${typeName}] missing required property '${key}'`)};`);
|
|
639
|
+
}
|
|
640
|
+
for (const member of inlineAllOfMembers(schema)) {
|
|
641
|
+
lines.push(...generateObjectStrictAssertion(member, typeName, context).slice(1));
|
|
299
642
|
}
|
|
300
643
|
const sr = schema;
|
|
301
644
|
if ("dependentRequired" in sr || "dependentSchemas" in sr || "propertyNames" in sr) {
|
|
302
|
-
lines.push(...generateObjectKeywordChecks("input", schema, `[${typeName}]`, false));
|
|
645
|
+
lines.push(...generateObjectKeywordChecks("input", schema, `[${typeName}]`, false, context));
|
|
303
646
|
}
|
|
647
|
+
lines.push(...generateObjectSizeChecks("input", schema, `[${typeName}]`, false));
|
|
648
|
+
lines.push(...generateNotCheck("input", schema, `[${typeName}]`, false, context));
|
|
649
|
+
lines.push(...generateAllOfChecks("input", schema, `[${typeName}]`, false, context, true));
|
|
650
|
+
lines.push(...generateUnionMatchChecks("input", schema, `[${typeName}]`, false, context));
|
|
651
|
+
lines.push(...generateConditionalChecks("input", schema, `[${typeName}]`, context));
|
|
652
|
+
lines.push(...generateKeyedValueChecks("input", schema, `[${typeName}]`, context));
|
|
653
|
+
lines.push(...generateBackstopAssertion("input", schema, `[${typeName}]`, context));
|
|
304
654
|
return lines;
|
|
305
655
|
};
|
|
306
|
-
const generateScalarStrictAssertion = (schema, typeName,
|
|
656
|
+
const generateScalarStrictAssertion = (schema, typeName, context = {}) => {
|
|
657
|
+
if (schema === false)
|
|
658
|
+
return ` ${throwError(`[${typeName}] schema is false: no value is valid`)};`;
|
|
307
659
|
const got = 'input === null ? "null" : typeof input';
|
|
308
660
|
const instanceOf = getMjstInstanceOf(schema);
|
|
309
661
|
if (instanceOf) {
|
|
@@ -318,12 +670,28 @@ const generateScalarStrictAssertion = (schema, typeName, rootSchema) => {
|
|
|
318
670
|
const label = `[${typeName}]`;
|
|
319
671
|
const lines = [];
|
|
320
672
|
if (hasConst(schema)) {
|
|
321
|
-
const
|
|
322
|
-
lines.push(` if (JSON.stringify(input) !== ${wanted}) ${throwError(`${label} must be ${JSON.stringify(schema.const)}`)};`);
|
|
673
|
+
lines.push(` if (!(${generateDeepEqualCheck("input", schema.const)})) ${throwError(`${label} must be ${JSON.stringify(schema.const)}`)};`);
|
|
323
674
|
} else if (hasEnum(schema)) {
|
|
324
|
-
const allowed = JSON.stringify(schema.enum);
|
|
325
675
|
const enumLabel = schema.enum.map((v) => JSON.stringify(v)).join(", ");
|
|
326
|
-
lines.push(` if (
|
|
676
|
+
lines.push(` if (!${generateEnumCheck("input", schema.enum)}) ${throwError(`${label} must be one of: ${enumLabel}`)};`);
|
|
677
|
+
}
|
|
678
|
+
lines.push(...generateNotCheck("input", schema, label, false, context));
|
|
679
|
+
lines.push(...generateAllOfChecks("input", schema, label, false, context));
|
|
680
|
+
lines.push(...generateUnionMatchChecks("input", schema, label, false, context));
|
|
681
|
+
lines.push(...generateConditionalChecks("input", schema, label, context));
|
|
682
|
+
const rootMultiType = multiTypeCheck("input", schema, { ignoreConstraints: true });
|
|
683
|
+
if (rootMultiType !== void 0) {
|
|
684
|
+
const types = schema.type;
|
|
685
|
+
if (rootMultiType !== null) {
|
|
686
|
+
lines.push(` if (!${rootMultiType}) ${throwError(`${label} expected ${types.map(typeLabel).join(" | ")}, got `, got)};`);
|
|
687
|
+
}
|
|
688
|
+
const nonNull = types.filter((type) => type !== "null");
|
|
689
|
+
if (nonNull.length === 1) {
|
|
690
|
+
lines.push(...generateConstraintChecks("input", { ...schema, type: nonNull[0] }, label, context));
|
|
691
|
+
lines.push(...nullableObjectShapeChecks("input", schema, nonNull[0], label, false, context));
|
|
692
|
+
}
|
|
693
|
+
lines.push(...generateBackstopAssertion("input", schema, label, context));
|
|
694
|
+
return lines.length > 0 ? lines.join("\n") : null;
|
|
327
695
|
}
|
|
328
696
|
if (hasType(schema)) {
|
|
329
697
|
const t = schema.type;
|
|
@@ -332,20 +700,23 @@ const generateScalarStrictAssertion = (schema, typeName, rootSchema) => {
|
|
|
332
700
|
lines.push(` if (${wrongType}) ${throwError(`${label} expected ${typeLabel(t)}, got `, got)};`);
|
|
333
701
|
}
|
|
334
702
|
if (t === "array") {
|
|
335
|
-
|
|
336
|
-
if (itemCheck) {
|
|
337
|
-
lines.push(` if (!(input as readonly unknown[]).every((_it) => ${itemCheck.check})) ${throwError(`${label} ${itemCheck.message}`)};`);
|
|
338
|
-
}
|
|
339
|
-
lines.push(...generateContainsCheck("input", schema, label));
|
|
340
|
-
lines.push(...generatePrefixItemsAssertion("input", label, schema, rootSchema));
|
|
703
|
+
lines.push(...generateContainsCheck("input", schema, label, context));
|
|
341
704
|
}
|
|
342
|
-
lines.push(...generateConstraintChecks("input", schema, label,
|
|
705
|
+
lines.push(...generateConstraintChecks("input", schema, label, context));
|
|
343
706
|
}
|
|
707
|
+
lines.push(...generateBackstopAssertion("input", schema, label, context));
|
|
344
708
|
return lines.length > 0 ? lines.join("\n") : null;
|
|
345
709
|
};
|
|
346
710
|
export {
|
|
711
|
+
backstopReason,
|
|
712
|
+
backstopSchema,
|
|
713
|
+
generateBackstopAssertion,
|
|
714
|
+
generateCompositionChecks,
|
|
347
715
|
generateContainsCheck,
|
|
716
|
+
generateKeyedValueChecks,
|
|
348
717
|
generateObjectKeywordChecks,
|
|
718
|
+
generateObjectSizeChecks,
|
|
349
719
|
generateObjectStrictAssertion,
|
|
350
|
-
generateScalarStrictAssertion
|
|
720
|
+
generateScalarStrictAssertion,
|
|
721
|
+
inlineAllOfMembers
|
|
351
722
|
};
|