source: trip-planner-front/node_modules/ajv/lib/vocabularies/code.ts@ 8d391a1

Last change on this file since 8d391a1 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 5.0 KB
Line 
1import type {AnySchema, SchemaMap} from "../types"
2import type {SchemaCxt} from "../compile"
3import type {KeywordCxt} from "../compile/validate"
4import {CodeGen, _, and, or, not, nil, strConcat, getProperty, Code, Name} from "../compile/codegen"
5import {alwaysValidSchema, Type} from "../compile/util"
6import N from "../compile/names"
7
8export 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
16export 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
28export function reportMissingProp(cxt: KeywordCxt, missing: Name): void {
29 cxt.setParams({missingProperty: missing}, true)
30 cxt.error()
31}
32
33export 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
41export function isOwnProperty(gen: CodeGen, data: Name, property: Name | string): Code {
42 return _`${hasPropFunc(gen)}.call(${data}, ${property})`
43}
44
45export 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
55export 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
65export function allSchemaProperties(schemaMap?: SchemaMap): string[] {
66 return schemaMap ? Object.keys(schemaMap).filter((p) => p !== "__proto__") : []
67}
68
69export function schemaProperties(it: SchemaCxt, schemaMap: SchemaMap): string[] {
70 return allSchemaProperties(schemaMap).filter(
71 (p) => !alwaysValidSchema(it, schemaMap[p] as AnySchema)
72 )
73}
74
75export 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
93export function usePattern({gen, it: {opts}}: KeywordCxt, pattern: string): Name {
94 const u = opts.unicodeRegExp ? "u" : ""
95 return gen.scopeValue("pattern", {
96 key: pattern,
97 ref: new RegExp(pattern, u),
98 code: _`new RegExp(${pattern}, ${u})`,
99 })
100}
101
102export function validateArray(cxt: KeywordCxt): Name {
103 const {gen, data, keyword, it} = cxt
104 const valid = gen.name("valid")
105 if (it.allErrors) {
106 const validArr = gen.let("valid", true)
107 validateItems(() => gen.assign(validArr, false))
108 return validArr
109 }
110 gen.var(valid, true)
111 validateItems(() => gen.break())
112 return valid
113
114 function validateItems(notValid: () => void): void {
115 const len = gen.const("len", _`${data}.length`)
116 gen.forRange("i", 0, len, (i) => {
117 cxt.subschema(
118 {
119 keyword,
120 dataProp: i,
121 dataPropType: Type.Num,
122 },
123 valid
124 )
125 gen.if(not(valid), notValid)
126 })
127 }
128}
129
130export function validateUnion(cxt: KeywordCxt): void {
131 const {gen, schema, keyword, it} = cxt
132 /* istanbul ignore if */
133 if (!Array.isArray(schema)) throw new Error("ajv implementation error")
134 const alwaysValid = schema.some((sch: AnySchema) => alwaysValidSchema(it, sch))
135 if (alwaysValid && !it.opts.unevaluated) return
136
137 const valid = gen.let("valid", false)
138 const schValid = gen.name("_valid")
139
140 gen.block(() =>
141 schema.forEach((_sch: AnySchema, i: number) => {
142 const schCxt = cxt.subschema(
143 {
144 keyword,
145 schemaProp: i,
146 compositeRule: true,
147 },
148 schValid
149 )
150 gen.assign(valid, _`${valid} || ${schValid}`)
151 const merged = cxt.mergeValidEvaluated(schCxt, schValid)
152 // can short-circuit if `unevaluatedProperties/Items` not supported (opts.unevaluated !== true)
153 // or if all properties and items were evaluated (it.props === true && it.items === true)
154 if (!merged) gen.if(not(valid))
155 })
156 )
157
158 cxt.result(
159 valid,
160 () => cxt.reset(),
161 () => cxt.error(true)
162 )
163}
Note: See TracBrowser for help on using the repository browser.