Spaces:
Sleeping
Sleeping
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 | |