123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 |
- import type {KeywordDefinition, KeywordErrorDefinition, KeywordCxt, ErrorObject} from "ajv"
- import {_, str, nil, Name} from "ajv/dist/compile/codegen"
- import type {DefinitionOptions} from "./_types"
- import {metaSchemaRef} from "./_util"
- export type SelectError = ErrorObject<"select", {failingCase?: string; failingDefault?: true}>
- const error: KeywordErrorDefinition = {
- message: ({params: {schemaProp}}) =>
- schemaProp
- ? str`should match case "${schemaProp}" schema`
- : str`should match default case schema`,
- params: ({params: {schemaProp}}) =>
- schemaProp ? _`{failingCase: ${schemaProp}}` : _`{failingDefault: true}`,
- }
- export default function getDef(opts?: DefinitionOptions): KeywordDefinition[] {
- const metaSchema = metaSchemaRef(opts)
- return [
- {
- keyword: "select",
- schemaType: ["string", "number", "boolean", "null"],
- $data: true,
- error,
- dependencies: ["selectCases"],
- code(cxt: KeywordCxt) {
- const {gen, schemaCode, parentSchema} = cxt
- cxt.block$data(nil, () => {
- const valid = gen.let("valid", true)
- const schValid = gen.name("_valid")
- const value = gen.const("value", _`${schemaCode} === null ? "null" : ${schemaCode}`)
- gen.if(false) // optimizer should remove it from generated code
- for (const schemaProp in parentSchema.selectCases) {
- cxt.setParams({schemaProp})
- gen.elseIf(_`"" + ${value} == ${schemaProp}`) // intentional ==, to match numbers and booleans
- const schCxt = cxt.subschema({keyword: "selectCases", schemaProp}, schValid)
- cxt.mergeEvaluated(schCxt, Name)
- gen.assign(valid, schValid)
- }
- gen.else()
- if (parentSchema.selectDefault !== undefined) {
- cxt.setParams({schemaProp: undefined})
- const schCxt = cxt.subschema({keyword: "selectDefault"}, schValid)
- cxt.mergeEvaluated(schCxt, Name)
- gen.assign(valid, schValid)
- }
- gen.endIf()
- cxt.pass(valid)
- })
- },
- },
- {
- keyword: "selectCases",
- dependencies: ["select"],
- metaSchema: {
- type: "object",
- additionalProperties: metaSchema,
- },
- },
- {
- keyword: "selectDefault",
- dependencies: ["select", "selectCases"],
- metaSchema,
- },
- ]
- }
- module.exports = getDef
|