12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- import type {
- CodeKeywordDefinition,
- KeywordErrorDefinition,
- ErrorObject,
- AnySchema,
- } from "../../types"
- import {_, not, and, Name, Code} from "../../compile/codegen"
- import {alwaysValidSchema, Type} from "../../compile/util"
- import N from "../../compile/names"
- export type UnevaluatedPropertiesError = ErrorObject<
- "unevaluatedProperties",
- {unevaluatedProperty: string},
- AnySchema
- >
- const error: KeywordErrorDefinition = {
- message: "must NOT have unevaluated properties",
- params: ({params}) => _`{unevaluatedProperty: ${params.unevaluatedProperty}}`,
- }
- const def: CodeKeywordDefinition = {
- keyword: "unevaluatedProperties",
- type: "object",
- schemaType: ["boolean", "object"],
- trackErrors: true,
- error,
- code(cxt) {
- const {gen, schema, data, errsCount, it} = cxt
- /* istanbul ignore if */
- if (!errsCount) throw new Error("ajv implementation error")
- const {allErrors, props} = it
- if (props instanceof Name) {
- gen.if(_`${props} !== true`, () =>
- gen.forIn("key", data, (key: Name) =>
- gen.if(unevaluatedDynamic(props, key), () => unevaluatedPropCode(key))
- )
- )
- } else if (props !== true) {
- gen.forIn("key", data, (key: Name) =>
- props === undefined
- ? unevaluatedPropCode(key)
- : gen.if(unevaluatedStatic(props, key), () => unevaluatedPropCode(key))
- )
- }
- it.props = true
- cxt.ok(_`${errsCount} === ${N.errors}`)
- function unevaluatedPropCode(key: Name): void {
- if (schema === false) {
- cxt.setParams({unevaluatedProperty: key})
- cxt.error()
- if (!allErrors) gen.break()
- return
- }
- if (!alwaysValidSchema(it, schema)) {
- const valid = gen.name("valid")
- cxt.subschema(
- {
- keyword: "unevaluatedProperties",
- dataProp: key,
- dataPropType: Type.Str,
- },
- valid
- )
- if (!allErrors) gen.if(not(valid), () => gen.break())
- }
- }
- function unevaluatedDynamic(evaluatedProps: Name, key: Name): Code {
- return _`!${evaluatedProps} || !${evaluatedProps}[${key}]`
- }
- function unevaluatedStatic(evaluatedProps: {[K in string]?: true}, key: Name): Code {
- const ps: Code[] = []
- for (const p in evaluatedProps) {
- if (evaluatedProps[p] === true) ps.push(_`${key} !== ${p}`)
- }
- return and(...ps)
- }
- },
- }
- export default def
|