massive update, probably broken
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / table / node_modules / ajv / lib / vocabularies / code.ts
1 import type {AnySchema, SchemaMap} from "../types"
2 import type {SchemaCxt} from "../compile"
3 import type {KeywordCxt} from "../compile/validate"
4 import {CodeGen, _, and, or, not, nil, strConcat, getProperty, Code, Name} from "../compile/codegen"
5 import {alwaysValidSchema, Type} from "../compile/util"
6 import N from "../compile/names"
7 import {useFunc} from "../compile/util"
8 export function checkReportMissingProp(cxt: KeywordCxt, prop: string): void {
9   const {gen, data, it} = cxt
10   gen.if(noPropertyInData(gen, data, prop, it.opts.ownProperties), () => {
11     cxt.setParams({missingProperty: _`${prop}`}, true)
12     cxt.error()
13   })
14 }
15
16 export function checkMissingProp(
17   {gen, data, it: {opts}}: KeywordCxt,
18   properties: string[],
19   missing: Name
20 ): Code {
21   return or(
22     ...properties.map((prop) =>
23       and(noPropertyInData(gen, data, prop, opts.ownProperties), _`${missing} = ${prop}`)
24     )
25   )
26 }
27
28 export function reportMissingProp(cxt: KeywordCxt, missing: Name): void {
29   cxt.setParams({missingProperty: missing}, true)
30   cxt.error()
31 }
32
33 export function hasPropFunc(gen: CodeGen): Name {
34   return gen.scopeValue("func", {
35     // eslint-disable-next-line @typescript-eslint/unbound-method
36     ref: Object.prototype.hasOwnProperty,
37     code: _`Object.prototype.hasOwnProperty`,
38   })
39 }
40
41 export function isOwnProperty(gen: CodeGen, data: Name, property: Name | string): Code {
42   return _`${hasPropFunc(gen)}.call(${data}, ${property})`
43 }
44
45 export function propertyInData(
46   gen: CodeGen,
47   data: Name,
48   property: Name | string,
49   ownProperties?: boolean
50 ): Code {
51   const cond = _`${data}${getProperty(property)} !== undefined`
52   return ownProperties ? _`${cond} && ${isOwnProperty(gen, data, property)}` : cond
53 }
54
55 export function noPropertyInData(
56   gen: CodeGen,
57   data: Name,
58   property: Name | string,
59   ownProperties?: boolean
60 ): Code {
61   const cond = _`${data}${getProperty(property)} === undefined`
62   return ownProperties ? or(cond, not(isOwnProperty(gen, data, property))) : cond
63 }
64
65 export function allSchemaProperties(schemaMap?: SchemaMap): string[] {
66   return schemaMap ? Object.keys(schemaMap).filter((p) => p !== "__proto__") : []
67 }
68
69 export function schemaProperties(it: SchemaCxt, schemaMap: SchemaMap): string[] {
70   return allSchemaProperties(schemaMap).filter(
71     (p) => !alwaysValidSchema(it, schemaMap[p] as AnySchema)
72   )
73 }
74
75 export function callValidateCode(
76   {schemaCode, data, it: {gen, topSchemaRef, schemaPath, errorPath}, it}: KeywordCxt,
77   func: Code,
78   context: Code,
79   passSchema?: boolean
80 ): Code {
81   const dataAndSchema = passSchema ? _`${schemaCode}, ${data}, ${topSchemaRef}${schemaPath}` : data
82   const valCxt: [Name, Code | number][] = [
83     [N.instancePath, strConcat(N.instancePath, errorPath)],
84     [N.parentData, it.parentData],
85     [N.parentDataProperty, it.parentDataProperty],
86     [N.rootData, N.rootData],
87   ]
88   if (it.opts.dynamicRef) valCxt.push([N.dynamicAnchors, N.dynamicAnchors])
89   const args = _`${dataAndSchema}, ${gen.object(...valCxt)}`
90   return context !== nil ? _`${func}.call(${context}, ${args})` : _`${func}(${args})`
91 }
92
93 const newRegExp = _`new RegExp`
94
95 export function usePattern({gen, it: {opts}}: KeywordCxt, pattern: string): Name {
96   const u = opts.unicodeRegExp ? "u" : ""
97   const {regExp} = opts.code
98   const rx = regExp(pattern, u)
99
100   return gen.scopeValue("pattern", {
101     key: rx.toString(),
102     ref: rx,
103     code: _`${regExp.code === "new RegExp" ? newRegExp : useFunc(gen, regExp)}(${pattern}, ${u})`,
104   })
105 }
106
107 export function validateArray(cxt: KeywordCxt): Name {
108   const {gen, data, keyword, it} = cxt
109   const valid = gen.name("valid")
110   if (it.allErrors) {
111     const validArr = gen.let("valid", true)
112     validateItems(() => gen.assign(validArr, false))
113     return validArr
114   }
115   gen.var(valid, true)
116   validateItems(() => gen.break())
117   return valid
118
119   function validateItems(notValid: () => void): void {
120     const len = gen.const("len", _`${data}.length`)
121     gen.forRange("i", 0, len, (i) => {
122       cxt.subschema(
123         {
124           keyword,
125           dataProp: i,
126           dataPropType: Type.Num,
127         },
128         valid
129       )
130       gen.if(not(valid), notValid)
131     })
132   }
133 }
134
135 export function validateUnion(cxt: KeywordCxt): void {
136   const {gen, schema, keyword, it} = cxt
137   /* istanbul ignore if */
138   if (!Array.isArray(schema)) throw new Error("ajv implementation error")
139   const alwaysValid = schema.some((sch: AnySchema) => alwaysValidSchema(it, sch))
140   if (alwaysValid && !it.opts.unevaluated) return
141
142   const valid = gen.let("valid", false)
143   const schValid = gen.name("_valid")
144
145   gen.block(() =>
146     schema.forEach((_sch: AnySchema, i: number) => {
147       const schCxt = cxt.subschema(
148         {
149           keyword,
150           schemaProp: i,
151           compositeRule: true,
152         },
153         schValid
154       )
155       gen.assign(valid, _`${valid} || ${schValid}`)
156       const merged = cxt.mergeValidEvaluated(schCxt, schValid)
157       // can short-circuit if `unevaluatedProperties/Items` not supported (opts.unevaluated !== true)
158       // or if all properties and items were evaluated (it.props === true && it.items === true)
159       if (!merged) gen.if(not(valid))
160     })
161   )
162
163   cxt.result(
164     valid,
165     () => cxt.reset(),
166     () => cxt.error(true)
167   )
168 }