massive update, probably broken
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / table / node_modules / ajv / dist / compile / validate / index.js
1 "use strict";
2 Object.defineProperty(exports, "__esModule", { value: true });
3 exports.getData = exports.KeywordCxt = exports.validateFunctionCode = void 0;
4 const boolSchema_1 = require("./boolSchema");
5 const dataType_1 = require("./dataType");
6 const applicability_1 = require("./applicability");
7 const dataType_2 = require("./dataType");
8 const defaults_1 = require("./defaults");
9 const keyword_1 = require("./keyword");
10 const subschema_1 = require("./subschema");
11 const codegen_1 = require("../codegen");
12 const names_1 = require("../names");
13 const resolve_1 = require("../resolve");
14 const util_1 = require("../util");
15 const errors_1 = require("../errors");
16 // schema compilation - generates validation function, subschemaCode (below) is used for subschemas
17 function validateFunctionCode(it) {
18     if (isSchemaObj(it)) {
19         checkKeywords(it);
20         if (schemaCxtHasRules(it)) {
21             topSchemaObjCode(it);
22             return;
23         }
24     }
25     validateFunction(it, () => (0, boolSchema_1.topBoolOrEmptySchema)(it));
26 }
27 exports.validateFunctionCode = validateFunctionCode;
28 function validateFunction({ gen, validateName, schema, schemaEnv, opts }, body) {
29     if (opts.code.es5) {
30         gen.func(validateName, (0, codegen_1._) `${names_1.default.data}, ${names_1.default.valCxt}`, schemaEnv.$async, () => {
31             gen.code((0, codegen_1._) `"use strict"; ${funcSourceUrl(schema, opts)}`);
32             destructureValCxtES5(gen, opts);
33             gen.code(body);
34         });
35     }
36     else {
37         gen.func(validateName, (0, codegen_1._) `${names_1.default.data}, ${destructureValCxt(opts)}`, schemaEnv.$async, () => gen.code(funcSourceUrl(schema, opts)).code(body));
38     }
39 }
40 function destructureValCxt(opts) {
41     return (0, codegen_1._) `{${names_1.default.instancePath}="", ${names_1.default.parentData}, ${names_1.default.parentDataProperty}, ${names_1.default.rootData}=${names_1.default.data}${opts.dynamicRef ? (0, codegen_1._) `, ${names_1.default.dynamicAnchors}={}` : codegen_1.nil}}={}`;
42 }
43 function destructureValCxtES5(gen, opts) {
44     gen.if(names_1.default.valCxt, () => {
45         gen.var(names_1.default.instancePath, (0, codegen_1._) `${names_1.default.valCxt}.${names_1.default.instancePath}`);
46         gen.var(names_1.default.parentData, (0, codegen_1._) `${names_1.default.valCxt}.${names_1.default.parentData}`);
47         gen.var(names_1.default.parentDataProperty, (0, codegen_1._) `${names_1.default.valCxt}.${names_1.default.parentDataProperty}`);
48         gen.var(names_1.default.rootData, (0, codegen_1._) `${names_1.default.valCxt}.${names_1.default.rootData}`);
49         if (opts.dynamicRef)
50             gen.var(names_1.default.dynamicAnchors, (0, codegen_1._) `${names_1.default.valCxt}.${names_1.default.dynamicAnchors}`);
51     }, () => {
52         gen.var(names_1.default.instancePath, (0, codegen_1._) `""`);
53         gen.var(names_1.default.parentData, (0, codegen_1._) `undefined`);
54         gen.var(names_1.default.parentDataProperty, (0, codegen_1._) `undefined`);
55         gen.var(names_1.default.rootData, names_1.default.data);
56         if (opts.dynamicRef)
57             gen.var(names_1.default.dynamicAnchors, (0, codegen_1._) `{}`);
58     });
59 }
60 function topSchemaObjCode(it) {
61     const { schema, opts, gen } = it;
62     validateFunction(it, () => {
63         if (opts.$comment && schema.$comment)
64             commentKeyword(it);
65         checkNoDefault(it);
66         gen.let(names_1.default.vErrors, null);
67         gen.let(names_1.default.errors, 0);
68         if (opts.unevaluated)
69             resetEvaluated(it);
70         typeAndKeywords(it);
71         returnResults(it);
72     });
73     return;
74 }
75 function resetEvaluated(it) {
76     // TODO maybe some hook to execute it in the end to check whether props/items are Name, as in assignEvaluated
77     const { gen, validateName } = it;
78     it.evaluated = gen.const("evaluated", (0, codegen_1._) `${validateName}.evaluated`);
79     gen.if((0, codegen_1._) `${it.evaluated}.dynamicProps`, () => gen.assign((0, codegen_1._) `${it.evaluated}.props`, (0, codegen_1._) `undefined`));
80     gen.if((0, codegen_1._) `${it.evaluated}.dynamicItems`, () => gen.assign((0, codegen_1._) `${it.evaluated}.items`, (0, codegen_1._) `undefined`));
81 }
82 function funcSourceUrl(schema, opts) {
83     const schId = typeof schema == "object" && schema[opts.schemaId];
84     return schId && (opts.code.source || opts.code.process) ? (0, codegen_1._) `/*# sourceURL=${schId} */` : codegen_1.nil;
85 }
86 // schema compilation - this function is used recursively to generate code for sub-schemas
87 function subschemaCode(it, valid) {
88     if (isSchemaObj(it)) {
89         checkKeywords(it);
90         if (schemaCxtHasRules(it)) {
91             subSchemaObjCode(it, valid);
92             return;
93         }
94     }
95     (0, boolSchema_1.boolOrEmptySchema)(it, valid);
96 }
97 function schemaCxtHasRules({ schema, self }) {
98     if (typeof schema == "boolean")
99         return !schema;
100     for (const key in schema)
101         if (self.RULES.all[key])
102             return true;
103     return false;
104 }
105 function isSchemaObj(it) {
106     return typeof it.schema != "boolean";
107 }
108 function subSchemaObjCode(it, valid) {
109     const { schema, gen, opts } = it;
110     if (opts.$comment && schema.$comment)
111         commentKeyword(it);
112     updateContext(it);
113     checkAsyncSchema(it);
114     const errsCount = gen.const("_errs", names_1.default.errors);
115     typeAndKeywords(it, errsCount);
116     // TODO var
117     gen.var(valid, (0, codegen_1._) `${errsCount} === ${names_1.default.errors}`);
118 }
119 function checkKeywords(it) {
120     (0, util_1.checkUnknownRules)(it);
121     checkRefsAndKeywords(it);
122 }
123 function typeAndKeywords(it, errsCount) {
124     if (it.opts.jtd)
125         return schemaKeywords(it, [], false, errsCount);
126     const types = (0, dataType_1.getSchemaTypes)(it.schema);
127     const checkedTypes = (0, dataType_1.coerceAndCheckDataType)(it, types);
128     schemaKeywords(it, types, !checkedTypes, errsCount);
129 }
130 function checkRefsAndKeywords(it) {
131     const { schema, errSchemaPath, opts, self } = it;
132     if (schema.$ref && opts.ignoreKeywordsWithRef && (0, util_1.schemaHasRulesButRef)(schema, self.RULES)) {
133         self.logger.warn(`$ref: keywords ignored in schema at path "${errSchemaPath}"`);
134     }
135 }
136 function checkNoDefault(it) {
137     const { schema, opts } = it;
138     if (schema.default !== undefined && opts.useDefaults && opts.strictSchema) {
139         (0, util_1.checkStrictMode)(it, "default is ignored in the schema root");
140     }
141 }
142 function updateContext(it) {
143     const schId = it.schema[it.opts.schemaId];
144     if (schId)
145         it.baseId = (0, resolve_1.resolveUrl)(it.baseId, schId);
146 }
147 function checkAsyncSchema(it) {
148     if (it.schema.$async && !it.schemaEnv.$async)
149         throw new Error("async schema in sync schema");
150 }
151 function commentKeyword({ gen, schemaEnv, schema, errSchemaPath, opts }) {
152     const msg = schema.$comment;
153     if (opts.$comment === true) {
154         gen.code((0, codegen_1._) `${names_1.default.self}.logger.log(${msg})`);
155     }
156     else if (typeof opts.$comment == "function") {
157         const schemaPath = (0, codegen_1.str) `${errSchemaPath}/$comment`;
158         const rootName = gen.scopeValue("root", { ref: schemaEnv.root });
159         gen.code((0, codegen_1._) `${names_1.default.self}.opts.$comment(${msg}, ${schemaPath}, ${rootName}.schema)`);
160     }
161 }
162 function returnResults(it) {
163     const { gen, schemaEnv, validateName, ValidationError, opts } = it;
164     if (schemaEnv.$async) {
165         // TODO assign unevaluated
166         gen.if((0, codegen_1._) `${names_1.default.errors} === 0`, () => gen.return(names_1.default.data), () => gen.throw((0, codegen_1._) `new ${ValidationError}(${names_1.default.vErrors})`));
167     }
168     else {
169         gen.assign((0, codegen_1._) `${validateName}.errors`, names_1.default.vErrors);
170         if (opts.unevaluated)
171             assignEvaluated(it);
172         gen.return((0, codegen_1._) `${names_1.default.errors} === 0`);
173     }
174 }
175 function assignEvaluated({ gen, evaluated, props, items }) {
176     if (props instanceof codegen_1.Name)
177         gen.assign((0, codegen_1._) `${evaluated}.props`, props);
178     if (items instanceof codegen_1.Name)
179         gen.assign((0, codegen_1._) `${evaluated}.items`, items);
180 }
181 function schemaKeywords(it, types, typeErrors, errsCount) {
182     const { gen, schema, data, allErrors, opts, self } = it;
183     const { RULES } = self;
184     if (schema.$ref && (opts.ignoreKeywordsWithRef || !(0, util_1.schemaHasRulesButRef)(schema, RULES))) {
185         gen.block(() => keywordCode(it, "$ref", RULES.all.$ref.definition)); // TODO typecast
186         return;
187     }
188     if (!opts.jtd)
189         checkStrictTypes(it, types);
190     gen.block(() => {
191         for (const group of RULES.rules)
192             groupKeywords(group);
193         groupKeywords(RULES.post);
194     });
195     function groupKeywords(group) {
196         if (!(0, applicability_1.shouldUseGroup)(schema, group))
197             return;
198         if (group.type) {
199             gen.if((0, dataType_2.checkDataType)(group.type, data, opts.strictNumbers));
200             iterateKeywords(it, group);
201             if (types.length === 1 && types[0] === group.type && typeErrors) {
202                 gen.else();
203                 (0, dataType_2.reportTypeError)(it);
204             }
205             gen.endIf();
206         }
207         else {
208             iterateKeywords(it, group);
209         }
210         // TODO make it "ok" call?
211         if (!allErrors)
212             gen.if((0, codegen_1._) `${names_1.default.errors} === ${errsCount || 0}`);
213     }
214 }
215 function iterateKeywords(it, group) {
216     const { gen, schema, opts: { useDefaults }, } = it;
217     if (useDefaults)
218         (0, defaults_1.assignDefaults)(it, group.type);
219     gen.block(() => {
220         for (const rule of group.rules) {
221             if ((0, applicability_1.shouldUseRule)(schema, rule)) {
222                 keywordCode(it, rule.keyword, rule.definition, group.type);
223             }
224         }
225     });
226 }
227 function checkStrictTypes(it, types) {
228     if (it.schemaEnv.meta || !it.opts.strictTypes)
229         return;
230     checkContextTypes(it, types);
231     if (!it.opts.allowUnionTypes)
232         checkMultipleTypes(it, types);
233     checkKeywordTypes(it, it.dataTypes);
234 }
235 function checkContextTypes(it, types) {
236     if (!types.length)
237         return;
238     if (!it.dataTypes.length) {
239         it.dataTypes = types;
240         return;
241     }
242     types.forEach((t) => {
243         if (!includesType(it.dataTypes, t)) {
244             strictTypesError(it, `type "${t}" not allowed by context "${it.dataTypes.join(",")}"`);
245         }
246     });
247     it.dataTypes = it.dataTypes.filter((t) => includesType(types, t));
248 }
249 function checkMultipleTypes(it, ts) {
250     if (ts.length > 1 && !(ts.length === 2 && ts.includes("null"))) {
251         strictTypesError(it, "use allowUnionTypes to allow union type keyword");
252     }
253 }
254 function checkKeywordTypes(it, ts) {
255     const rules = it.self.RULES.all;
256     for (const keyword in rules) {
257         const rule = rules[keyword];
258         if (typeof rule == "object" && (0, applicability_1.shouldUseRule)(it.schema, rule)) {
259             const { type } = rule.definition;
260             if (type.length && !type.some((t) => hasApplicableType(ts, t))) {
261                 strictTypesError(it, `missing type "${type.join(",")}" for keyword "${keyword}"`);
262             }
263         }
264     }
265 }
266 function hasApplicableType(schTs, kwdT) {
267     return schTs.includes(kwdT) || (kwdT === "number" && schTs.includes("integer"));
268 }
269 function includesType(ts, t) {
270     return ts.includes(t) || (t === "integer" && ts.includes("number"));
271 }
272 function strictTypesError(it, msg) {
273     const schemaPath = it.schemaEnv.baseId + it.errSchemaPath;
274     msg += ` at "${schemaPath}" (strictTypes)`;
275     (0, util_1.checkStrictMode)(it, msg, it.opts.strictTypes);
276 }
277 class KeywordCxt {
278     constructor(it, def, keyword) {
279         (0, keyword_1.validateKeywordUsage)(it, def, keyword);
280         this.gen = it.gen;
281         this.allErrors = it.allErrors;
282         this.keyword = keyword;
283         this.data = it.data;
284         this.schema = it.schema[keyword];
285         this.$data = def.$data && it.opts.$data && this.schema && this.schema.$data;
286         this.schemaValue = (0, util_1.schemaRefOrVal)(it, this.schema, keyword, this.$data);
287         this.schemaType = def.schemaType;
288         this.parentSchema = it.schema;
289         this.params = {};
290         this.it = it;
291         this.def = def;
292         if (this.$data) {
293             this.schemaCode = it.gen.const("vSchema", getData(this.$data, it));
294         }
295         else {
296             this.schemaCode = this.schemaValue;
297             if (!(0, keyword_1.validSchemaType)(this.schema, def.schemaType, def.allowUndefined)) {
298                 throw new Error(`${keyword} value must be ${JSON.stringify(def.schemaType)}`);
299             }
300         }
301         if ("code" in def ? def.trackErrors : def.errors !== false) {
302             this.errsCount = it.gen.const("_errs", names_1.default.errors);
303         }
304     }
305     result(condition, successAction, failAction) {
306         this.failResult((0, codegen_1.not)(condition), successAction, failAction);
307     }
308     failResult(condition, successAction, failAction) {
309         this.gen.if(condition);
310         if (failAction)
311             failAction();
312         else
313             this.error();
314         if (successAction) {
315             this.gen.else();
316             successAction();
317             if (this.allErrors)
318                 this.gen.endIf();
319         }
320         else {
321             if (this.allErrors)
322                 this.gen.endIf();
323             else
324                 this.gen.else();
325         }
326     }
327     pass(condition, failAction) {
328         this.failResult((0, codegen_1.not)(condition), undefined, failAction);
329     }
330     fail(condition) {
331         if (condition === undefined) {
332             this.error();
333             if (!this.allErrors)
334                 this.gen.if(false); // this branch will be removed by gen.optimize
335             return;
336         }
337         this.gen.if(condition);
338         this.error();
339         if (this.allErrors)
340             this.gen.endIf();
341         else
342             this.gen.else();
343     }
344     fail$data(condition) {
345         if (!this.$data)
346             return this.fail(condition);
347         const { schemaCode } = this;
348         this.fail((0, codegen_1._) `${schemaCode} !== undefined && (${(0, codegen_1.or)(this.invalid$data(), condition)})`);
349     }
350     error(append, errorParams, errorPaths) {
351         if (errorParams) {
352             this.setParams(errorParams);
353             this._error(append, errorPaths);
354             this.setParams({});
355             return;
356         }
357         this._error(append, errorPaths);
358     }
359     _error(append, errorPaths) {
360         ;
361         (append ? errors_1.reportExtraError : errors_1.reportError)(this, this.def.error, errorPaths);
362     }
363     $dataError() {
364         (0, errors_1.reportError)(this, this.def.$dataError || errors_1.keyword$DataError);
365     }
366     reset() {
367         if (this.errsCount === undefined)
368             throw new Error('add "trackErrors" to keyword definition');
369         (0, errors_1.resetErrorsCount)(this.gen, this.errsCount);
370     }
371     ok(cond) {
372         if (!this.allErrors)
373             this.gen.if(cond);
374     }
375     setParams(obj, assign) {
376         if (assign)
377             Object.assign(this.params, obj);
378         else
379             this.params = obj;
380     }
381     block$data(valid, codeBlock, $dataValid = codegen_1.nil) {
382         this.gen.block(() => {
383             this.check$data(valid, $dataValid);
384             codeBlock();
385         });
386     }
387     check$data(valid = codegen_1.nil, $dataValid = codegen_1.nil) {
388         if (!this.$data)
389             return;
390         const { gen, schemaCode, schemaType, def } = this;
391         gen.if((0, codegen_1.or)((0, codegen_1._) `${schemaCode} === undefined`, $dataValid));
392         if (valid !== codegen_1.nil)
393             gen.assign(valid, true);
394         if (schemaType.length || def.validateSchema) {
395             gen.elseIf(this.invalid$data());
396             this.$dataError();
397             if (valid !== codegen_1.nil)
398                 gen.assign(valid, false);
399         }
400         gen.else();
401     }
402     invalid$data() {
403         const { gen, schemaCode, schemaType, def, it } = this;
404         return (0, codegen_1.or)(wrong$DataType(), invalid$DataSchema());
405         function wrong$DataType() {
406             if (schemaType.length) {
407                 /* istanbul ignore if */
408                 if (!(schemaCode instanceof codegen_1.Name))
409                     throw new Error("ajv implementation error");
410                 const st = Array.isArray(schemaType) ? schemaType : [schemaType];
411                 return (0, codegen_1._) `${(0, dataType_2.checkDataTypes)(st, schemaCode, it.opts.strictNumbers, dataType_2.DataType.Wrong)}`;
412             }
413             return codegen_1.nil;
414         }
415         function invalid$DataSchema() {
416             if (def.validateSchema) {
417                 const validateSchemaRef = gen.scopeValue("validate$data", { ref: def.validateSchema }); // TODO value.code for standalone
418                 return (0, codegen_1._) `!${validateSchemaRef}(${schemaCode})`;
419             }
420             return codegen_1.nil;
421         }
422     }
423     subschema(appl, valid) {
424         const subschema = (0, subschema_1.getSubschema)(this.it, appl);
425         (0, subschema_1.extendSubschemaData)(subschema, this.it, appl);
426         (0, subschema_1.extendSubschemaMode)(subschema, appl);
427         const nextContext = { ...this.it, ...subschema, items: undefined, props: undefined };
428         subschemaCode(nextContext, valid);
429         return nextContext;
430     }
431     mergeEvaluated(schemaCxt, toName) {
432         const { it, gen } = this;
433         if (!it.opts.unevaluated)
434             return;
435         if (it.props !== true && schemaCxt.props !== undefined) {
436             it.props = util_1.mergeEvaluated.props(gen, schemaCxt.props, it.props, toName);
437         }
438         if (it.items !== true && schemaCxt.items !== undefined) {
439             it.items = util_1.mergeEvaluated.items(gen, schemaCxt.items, it.items, toName);
440         }
441     }
442     mergeValidEvaluated(schemaCxt, valid) {
443         const { it, gen } = this;
444         if (it.opts.unevaluated && (it.props !== true || it.items !== true)) {
445             gen.if(valid, () => this.mergeEvaluated(schemaCxt, codegen_1.Name));
446             return true;
447         }
448     }
449 }
450 exports.KeywordCxt = KeywordCxt;
451 function keywordCode(it, keyword, def, ruleType) {
452     const cxt = new KeywordCxt(it, def, keyword);
453     if ("code" in def) {
454         def.code(cxt, ruleType);
455     }
456     else if (cxt.$data && def.validate) {
457         (0, keyword_1.funcKeywordCode)(cxt, def);
458     }
459     else if ("macro" in def) {
460         (0, keyword_1.macroKeywordCode)(cxt, def);
461     }
462     else if (def.compile || def.validate) {
463         (0, keyword_1.funcKeywordCode)(cxt, def);
464     }
465 }
466 const JSON_POINTER = /^\/(?:[^~]|~0|~1)*$/;
467 const RELATIVE_JSON_POINTER = /^([0-9]+)(#|\/(?:[^~]|~0|~1)*)?$/;
468 function getData($data, { dataLevel, dataNames, dataPathArr }) {
469     let jsonPointer;
470     let data;
471     if ($data === "")
472         return names_1.default.rootData;
473     if ($data[0] === "/") {
474         if (!JSON_POINTER.test($data))
475             throw new Error(`Invalid JSON-pointer: ${$data}`);
476         jsonPointer = $data;
477         data = names_1.default.rootData;
478     }
479     else {
480         const matches = RELATIVE_JSON_POINTER.exec($data);
481         if (!matches)
482             throw new Error(`Invalid JSON-pointer: ${$data}`);
483         const up = +matches[1];
484         jsonPointer = matches[2];
485         if (jsonPointer === "#") {
486             if (up >= dataLevel)
487                 throw new Error(errorMsg("property/index", up));
488             return dataPathArr[dataLevel - up];
489         }
490         if (up > dataLevel)
491             throw new Error(errorMsg("data", up));
492         data = dataNames[dataLevel - up];
493         if (!jsonPointer)
494             return data;
495     }
496     let expr = data;
497     const segments = jsonPointer.split("/");
498     for (const segment of segments) {
499         if (segment) {
500             data = (0, codegen_1._) `${data}${(0, codegen_1.getProperty)((0, util_1.unescapeJsonPointer)(segment))}`;
501             expr = (0, codegen_1._) `${expr} && ${data}`;
502         }
503     }
504     return expr;
505     function errorMsg(pointerType, up) {
506         return `Cannot access ${pointerType} ${up} levels up, current level is ${dataLevel}`;
507     }
508 }
509 exports.getData = getData;
510 //# sourceMappingURL=index.js.map