massive update, probably broken
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / table / node_modules / ajv / lib / vocabularies / applicator / additionalProperties.ts
1 import type {
2   CodeKeywordDefinition,
3   AddedKeywordDefinition,
4   ErrorObject,
5   KeywordErrorDefinition,
6   AnySchema,
7 } from "../../types"
8 import {allSchemaProperties, usePattern, isOwnProperty} from "../code"
9 import {_, nil, or, not, Code, Name} from "../../compile/codegen"
10 import N from "../../compile/names"
11 import type {SubschemaArgs} from "../../compile/validate/subschema"
12 import {alwaysValidSchema, schemaRefOrVal, Type} from "../../compile/util"
13
14 export type AdditionalPropertiesError = ErrorObject<
15   "additionalProperties",
16   {additionalProperty: string},
17   AnySchema
18 >
19
20 const error: KeywordErrorDefinition = {
21   message: "must NOT have additional properties",
22   params: ({params}) => _`{additionalProperty: ${params.additionalProperty}}`,
23 }
24
25 const def: CodeKeywordDefinition & AddedKeywordDefinition = {
26   keyword: "additionalProperties",
27   type: ["object"],
28   schemaType: ["boolean", "object"],
29   allowUndefined: true,
30   trackErrors: true,
31   error,
32   code(cxt) {
33     const {gen, schema, parentSchema, data, errsCount, it} = cxt
34     /* istanbul ignore if */
35     if (!errsCount) throw new Error("ajv implementation error")
36     const {allErrors, opts} = it
37     it.props = true
38     if (opts.removeAdditional !== "all" && alwaysValidSchema(it, schema)) return
39     const props = allSchemaProperties(parentSchema.properties)
40     const patProps = allSchemaProperties(parentSchema.patternProperties)
41     checkAdditionalProperties()
42     cxt.ok(_`${errsCount} === ${N.errors}`)
43
44     function checkAdditionalProperties(): void {
45       gen.forIn("key", data, (key: Name) => {
46         if (!props.length && !patProps.length) additionalPropertyCode(key)
47         else gen.if(isAdditional(key), () => additionalPropertyCode(key))
48       })
49     }
50
51     function isAdditional(key: Name): Code {
52       let definedProp: Code
53       if (props.length > 8) {
54         // TODO maybe an option instead of hard-coded 8?
55         const propsSchema = schemaRefOrVal(it, parentSchema.properties, "properties")
56         definedProp = isOwnProperty(gen, propsSchema as Code, key)
57       } else if (props.length) {
58         definedProp = or(...props.map((p) => _`${key} === ${p}`))
59       } else {
60         definedProp = nil
61       }
62       if (patProps.length) {
63         definedProp = or(definedProp, ...patProps.map((p) => _`${usePattern(cxt, p)}.test(${key})`))
64       }
65       return not(definedProp)
66     }
67
68     function deleteAdditional(key: Name): void {
69       gen.code(_`delete ${data}[${key}]`)
70     }
71
72     function additionalPropertyCode(key: Name): void {
73       if (opts.removeAdditional === "all" || (opts.removeAdditional && schema === false)) {
74         deleteAdditional(key)
75         return
76       }
77
78       if (schema === false) {
79         cxt.setParams({additionalProperty: key})
80         cxt.error()
81         if (!allErrors) gen.break()
82         return
83       }
84
85       if (typeof schema == "object" && !alwaysValidSchema(it, schema)) {
86         const valid = gen.name("valid")
87         if (opts.removeAdditional === "failing") {
88           applyAdditionalSchema(key, valid, false)
89           gen.if(not(valid), () => {
90             cxt.reset()
91             deleteAdditional(key)
92           })
93         } else {
94           applyAdditionalSchema(key, valid)
95           if (!allErrors) gen.if(not(valid), () => gen.break())
96         }
97       }
98     }
99
100     function applyAdditionalSchema(key: Name, valid: Name, errors?: false): void {
101       const subschema: SubschemaArgs = {
102         keyword: "additionalProperties",
103         dataProp: key,
104         dataPropType: Type.Str,
105       }
106       if (errors === false) {
107         Object.assign(subschema, {
108           compositeRule: true,
109           createErrors: false,
110           allErrors: false,
111         })
112       }
113       cxt.subschema(subschema, valid)
114     }
115   },
116 }
117
118 export default def