1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- import type {
- CodeKeywordDefinition,
- ErrorObject,
- KeywordErrorDefinition,
- AnySchema,
- } from "../../types"
- import type {SchemaObjCxt} from "../../compile"
- import type {KeywordCxt} from "../../compile/validate"
- import {_, str, not, Name} from "../../compile/codegen"
- import {alwaysValidSchema, checkStrictMode} from "../../compile/util"
- export type IfKeywordError = ErrorObject<"if", {failingKeyword: string}, AnySchema>
- const error: KeywordErrorDefinition = {
- message: ({params}) => str`must match "${params.ifClause}" schema`,
- params: ({params}) => _`{failingKeyword: ${params.ifClause}}`,
- }
- const def: CodeKeywordDefinition = {
- keyword: "if",
- schemaType: ["object", "boolean"],
- trackErrors: true,
- error,
- code(cxt: KeywordCxt) {
- const {gen, parentSchema, it} = cxt
- if (parentSchema.then === undefined && parentSchema.else === undefined) {
- checkStrictMode(it, '"if" without "then" and "else" is ignored')
- }
- const hasThen = hasSchema(it, "then")
- const hasElse = hasSchema(it, "else")
- if (!hasThen && !hasElse) return
- const valid = gen.let("valid", true)
- const schValid = gen.name("_valid")
- validateIf()
- cxt.reset()
- if (hasThen && hasElse) {
- const ifClause = gen.let("ifClause")
- cxt.setParams({ifClause})
- gen.if(schValid, validateClause("then", ifClause), validateClause("else", ifClause))
- } else if (hasThen) {
- gen.if(schValid, validateClause("then"))
- } else {
- gen.if(not(schValid), validateClause("else"))
- }
- cxt.pass(valid, () => cxt.error(true))
- function validateIf(): void {
- const schCxt = cxt.subschema(
- {
- keyword: "if",
- compositeRule: true,
- createErrors: false,
- allErrors: false,
- },
- schValid
- )
- cxt.mergeEvaluated(schCxt)
- }
- function validateClause(keyword: string, ifClause?: Name): () => void {
- return () => {
- const schCxt = cxt.subschema({keyword}, schValid)
- gen.assign(valid, schValid)
- cxt.mergeValidEvaluated(schCxt, valid)
- if (ifClause) gen.assign(ifClause, _`${keyword}`)
- else cxt.setParams({ifClause: keyword})
- }
- }
- },
- }
- function hasSchema(it: SchemaObjCxt, keyword: string): boolean {
- const schema = it.schema[keyword]
- return schema !== undefined && !alwaysValidSchema(it, schema)
- }
- export default def
|