massive update, probably broken
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / table / node_modules / ajv / lib / vocabularies / applicator / patternProperties.ts
1 import type {CodeKeywordDefinition} from "../../types"
2 import type {KeywordCxt} from "../../compile/validate"
3 import {allSchemaProperties, usePattern} from "../code"
4 import {_, not, Name} from "../../compile/codegen"
5 import {alwaysValidSchema, checkStrictMode} from "../../compile/util"
6 import {evaluatedPropsToName, Type} from "../../compile/util"
7 import {AnySchema} from "../../types"
8
9 const def: CodeKeywordDefinition = {
10   keyword: "patternProperties",
11   type: "object",
12   schemaType: "object",
13   code(cxt: KeywordCxt) {
14     const {gen, schema, data, parentSchema, it} = cxt
15     const {opts} = it
16     const patterns = allSchemaProperties(schema)
17     const alwaysValidPatterns = patterns.filter((p) =>
18       alwaysValidSchema(it, schema[p] as AnySchema)
19     )
20
21     if (
22       patterns.length === 0 ||
23       (alwaysValidPatterns.length === patterns.length &&
24         (!it.opts.unevaluated || it.props === true))
25     ) {
26       return
27     }
28
29     const checkProperties =
30       opts.strictSchema && !opts.allowMatchingProperties && parentSchema.properties
31     const valid = gen.name("valid")
32     if (it.props !== true && !(it.props instanceof Name)) {
33       it.props = evaluatedPropsToName(gen, it.props)
34     }
35     const {props} = it
36     validatePatternProperties()
37
38     function validatePatternProperties(): void {
39       for (const pat of patterns) {
40         if (checkProperties) checkMatchingProperties(pat)
41         if (it.allErrors) {
42           validateProperties(pat)
43         } else {
44           gen.var(valid, true) // TODO var
45           validateProperties(pat)
46           gen.if(valid)
47         }
48       }
49     }
50
51     function checkMatchingProperties(pat: string): void {
52       for (const prop in checkProperties) {
53         if (new RegExp(pat).test(prop)) {
54           checkStrictMode(
55             it,
56             `property ${prop} matches pattern ${pat} (use allowMatchingProperties)`
57           )
58         }
59       }
60     }
61
62     function validateProperties(pat: string): void {
63       gen.forIn("key", data, (key) => {
64         gen.if(_`${usePattern(cxt, pat)}.test(${key})`, () => {
65           const alwaysValid = alwaysValidPatterns.includes(pat)
66           if (!alwaysValid) {
67             cxt.subschema(
68               {
69                 keyword: "patternProperties",
70                 schemaProp: pat,
71                 dataProp: key,
72                 dataPropType: Type.Str,
73               },
74               valid
75             )
76           }
77
78           if (it.opts.unevaluated && props !== true) {
79             gen.assign(_`${props}[${key}]`, true)
80           } else if (!alwaysValid && !it.allErrors) {
81             // can short-circuit if `unevaluatedProperties` is not supported (opts.next === false)
82             // or if all properties were evaluated (props === true)
83             gen.if(not(valid), () => gen.break())
84           }
85         })
86       })
87     }
88   },
89 }
90
91 export default def