UNPKG

1.89 kBPlain TextView Raw
1import type {CodeKeywordDefinition, AnySchema, AnySchemaObject} from "../../types"
2import type {KeywordCxt} from "../../compile/validate"
3import {_} from "../../compile/codegen"
4import {alwaysValidSchema, mergeEvaluated, checkStrictMode} from "../../compile/util"
5import {validateArray} from "../code"
6
7const def: CodeKeywordDefinition = {
8 keyword: "items",
9 type: "array",
10 schemaType: ["object", "array", "boolean"],
11 before: "uniqueItems",
12 code(cxt: KeywordCxt) {
13 const {schema, it} = cxt
14 if (Array.isArray(schema)) return validateTuple(cxt, "additionalItems", schema)
15 it.items = true
16 if (alwaysValidSchema(it, schema)) return
17 cxt.ok(validateArray(cxt))
18 },
19}
20
21export function validateTuple(
22 cxt: KeywordCxt,
23 extraItems: string,
24 schArr: AnySchema[] = cxt.schema
25): void {
26 const {gen, parentSchema, data, keyword, it} = cxt
27 checkStrictTuple(parentSchema)
28 if (it.opts.unevaluated && schArr.length && it.items !== true) {
29 it.items = mergeEvaluated.items(gen, schArr.length, it.items)
30 }
31 const valid = gen.name("valid")
32 const len = gen.const("len", _`${data}.length`)
33 schArr.forEach((sch: AnySchema, i: number) => {
34 if (alwaysValidSchema(it, sch)) return
35 gen.if(_`${len} > ${i}`, () =>
36 cxt.subschema(
37 {
38 keyword,
39 schemaProp: i,
40 dataProp: i,
41 },
42 valid
43 )
44 )
45 cxt.ok(valid)
46 })
47
48 function checkStrictTuple(sch: AnySchemaObject): void {
49 const {opts, errSchemaPath} = it
50 const l = schArr.length
51 const fullTuple = l === sch.minItems && (l === sch.maxItems || sch[extraItems] === false)
52 if (opts.strictTuples && !fullTuple) {
53 const msg = `"${keyword}" is ${l}-tuple, but minItems or maxItems/${extraItems} are not specified or different at path "${errSchemaPath}"`
54 checkStrictMode(it, msg, opts.strictTuples)
55 }
56 }
57}
58
59export default def