1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859 |
- import type {CodeKeywordDefinition, AnySchema, AnySchemaObject} from "../../types"
- import type {KeywordCxt} from "../../compile/validate"
- import {_} from "../../compile/codegen"
- import {alwaysValidSchema, mergeEvaluated, checkStrictMode} from "../../compile/util"
- import {validateArray} from "../code"
- const def: CodeKeywordDefinition = {
- keyword: "items",
- type: "array",
- schemaType: ["object", "array", "boolean"],
- before: "uniqueItems",
- code(cxt: KeywordCxt) {
- const {schema, it} = cxt
- if (Array.isArray(schema)) return validateTuple(cxt, "additionalItems", schema)
- it.items = true
- if (alwaysValidSchema(it, schema)) return
- cxt.ok(validateArray(cxt))
- },
- }
- export function validateTuple(
- cxt: KeywordCxt,
- extraItems: string,
- schArr: AnySchema[] = cxt.schema
- ): void {
- const {gen, parentSchema, data, keyword, it} = cxt
- checkStrictTuple(parentSchema)
- if (it.opts.unevaluated && schArr.length && it.items !== true) {
- it.items = mergeEvaluated.items(gen, schArr.length, it.items)
- }
- const valid = gen.name("valid")
- const len = gen.const("len", _`${data}.length`)
- schArr.forEach((sch: AnySchema, i: number) => {
- if (alwaysValidSchema(it, sch)) return
- gen.if(_`${len} > ${i}`, () =>
- cxt.subschema(
- {
- keyword,
- schemaProp: i,
- dataProp: i,
- },
- valid
- )
- )
- cxt.ok(valid)
- })
- function checkStrictTuple(sch: AnySchemaObject): void {
- const {opts, errSchemaPath} = it
- const l = schArr.length
- const fullTuple = l === sch.minItems && (l === sch.maxItems || sch[extraItems] === false)
- if (opts.strictTuples && !fullTuple) {
- const msg = `"${keyword}" is ${l}-tuple, but minItems or maxItems/${extraItems} are not specified or different at path "${errSchemaPath}"`
- checkStrictMode(it, msg, opts.strictTuples)
- }
- }
- }
- export default def
|