UNPKG

1.52 kBPlain TextView Raw
1import type {
2 CodeKeywordDefinition,
3 ErrorObject,
4 KeywordErrorDefinition,
5 AnySchema,
6} from "../../types"
7import type {KeywordCxt} from "../../compile/validate"
8import {_, str, not, Name} from "../../compile/codegen"
9import {alwaysValidSchema, Type} from "../../compile/util"
10
11export type UnevaluatedItemsError = ErrorObject<"unevaluatedItems", {limit: number}, AnySchema>
12
13const error: KeywordErrorDefinition = {
14 message: ({params: {len}}) => str`must NOT have more than ${len} items`,
15 params: ({params: {len}}) => _`{limit: ${len}}`,
16}
17
18const def: CodeKeywordDefinition = {
19 keyword: "unevaluatedItems",
20 type: "array",
21 schemaType: ["boolean", "object"],
22 error,
23 code(cxt: KeywordCxt) {
24 const {gen, schema, data, it} = cxt
25 const items = it.items || 0
26 if (items === true) return
27 const len = gen.const("len", _`${data}.length`)
28 if (schema === false) {
29 cxt.setParams({len: items})
30 cxt.fail(_`${len} > ${items}`)
31 } else if (typeof schema == "object" && !alwaysValidSchema(it, schema)) {
32 const valid = gen.var("valid", _`${len} <= ${items}`)
33 gen.if(not(valid), () => validateItems(valid, items))
34 cxt.ok(valid)
35 }
36 it.items = true
37
38 function validateItems(valid: Name, from: Name | number): void {
39 gen.forRange("i", from, len, (i) => {
40 cxt.subschema({keyword: "unevaluatedItems", dataProp: i, dataPropType: Type.Num}, valid)
41 if (!it.allErrors) gen.if(not(valid), () => gen.break())
42 })
43 }
44 },
45}
46
47export default def