| import type { |
| CodeKeywordDefinition, |
| ErrorObject, |
| KeywordErrorDefinition, |
| AnySchema, |
| } from "../../types" |
| import type {KeywordCxt} from "../../compile/validate" |
| import {_, str, not, Name} from "../../compile/codegen" |
| import {alwaysValidSchema, Type} from "../../compile/util" |
| |
| export type UnevaluatedItemsError = ErrorObject<"unevaluatedItems", {limit: number}, AnySchema> |
| |
| const error: KeywordErrorDefinition = { |
| message: ({params: {len}}) => str`must NOT have more than ${len} items`, |
| params: ({params: {len}}) => _`{limit: ${len}}`, |
| } |
| |
| const def: CodeKeywordDefinition = { |
| keyword: "unevaluatedItems", |
| type: "array", |
| schemaType: ["boolean", "object"], |
| error, |
| code(cxt: KeywordCxt) { |
| const {gen, schema, data, it} = cxt |
| const items = it.items || 0 |
| if (items === true) return |
| const len = gen.const("len", _`${data}.length`) |
| if (schema === false) { |
| cxt.setParams({len: items}) |
| cxt.fail(_`${len} > ${items}`) |
| } else if (typeof schema == "object" && !alwaysValidSchema(it, schema)) { |
| const valid = gen.var("valid", _`${len} <= ${items}`) |
| gen.if(not(valid), () => validateItems(valid, items)) |
| cxt.ok(valid) |
| } |
| it.items = true |
| |
| function validateItems(valid: Name, from: Name | number): void { |
| gen.forRange("i", from, len, (i) => { |
| cxt.subschema({keyword: "unevaluatedItems", dataProp: i, dataPropType: Type.Num}, valid) |
| if (!it.allErrors) gen.if(not(valid), () => gen.break()) |
| }) |
| } |
| }, |
| } |
| |
| export default def |