12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- import type {
- CodeKeywordDefinition,
- ErrorObject,
- KeywordErrorDefinition,
- AnySchema,
- } from "../../types"
- import type {KeywordCxt} from "../../compile/validate"
- import {_, Name} from "../../compile/codegen"
- import {alwaysValidSchema} from "../../compile/util"
- import {SchemaCxt} from "../../compile"
- export type OneOfError = ErrorObject<
- "oneOf",
- {passingSchemas: [number, number] | null},
- AnySchema[]
- >
- const error: KeywordErrorDefinition = {
- message: "must match exactly one schema in oneOf",
- params: ({params}) => _`{passingSchemas: ${params.passing}}`,
- }
- const def: CodeKeywordDefinition = {
- keyword: "oneOf",
- schemaType: "array",
- trackErrors: true,
- error,
- code(cxt: KeywordCxt) {
- const {gen, schema, parentSchema, it} = cxt
- /* istanbul ignore if */
- if (!Array.isArray(schema)) throw new Error("ajv implementation error")
- if (it.opts.discriminator && parentSchema.discriminator) return
- const schArr: AnySchema[] = schema
- const valid = gen.let("valid", false)
- const passing = gen.let("passing", null)
- const schValid = gen.name("_valid")
- cxt.setParams({passing})
- // TODO possibly fail straight away (with warning or exception) if there are two empty always valid schemas
- gen.block(validateOneOf)
- cxt.result(
- valid,
- () => cxt.reset(),
- () => cxt.error(true)
- )
- function validateOneOf(): void {
- schArr.forEach((sch: AnySchema, i: number) => {
- let schCxt: SchemaCxt | undefined
- if (alwaysValidSchema(it, sch)) {
- gen.var(schValid, true)
- } else {
- schCxt = cxt.subschema(
- {
- keyword: "oneOf",
- schemaProp: i,
- compositeRule: true,
- },
- schValid
- )
- }
- if (i > 0) {
- gen
- .if(_`${schValid} && ${valid}`)
- .assign(valid, false)
- .assign(passing, _`[${passing}, ${i}]`)
- .else()
- }
- gen.if(schValid, () => {
- gen.assign(valid, true)
- gen.assign(passing, i)
- if (schCxt) cxt.mergeEvaluated(schCxt, Name)
- })
- })
- }
- },
- }
- export default def
|