mirror of https://github.com/jkjoy/sunpeiwen.git
109 lines
4.0 KiB
JavaScript
109 lines
4.0 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.schemaKeywords = void 0;
|
|
const applicability_1 = require("./applicability");
|
|
const dataType_1 = require("./dataType");
|
|
const defaults_1 = require("./defaults");
|
|
const keyword_1 = require("./keyword");
|
|
const util_1 = require("../util");
|
|
const _1 = require(".");
|
|
const codegen_1 = require("../codegen");
|
|
const names_1 = require("../names");
|
|
function schemaKeywords(it, types, typeErrors, errsCount) {
|
|
const { gen, schema, data, allErrors, opts, self } = it;
|
|
const { RULES } = self;
|
|
if (schema.$ref && (opts.ignoreKeywordsWithRef || !util_1.schemaHasRulesButRef(schema, RULES))) {
|
|
gen.block(() => keyword_1.keywordCode(it, "$ref", RULES.all.$ref.definition)); // TODO typecast
|
|
return;
|
|
}
|
|
if (!opts.jtd)
|
|
checkStrictTypes(it, types);
|
|
gen.block(() => {
|
|
for (const group of RULES.rules)
|
|
groupKeywords(group);
|
|
groupKeywords(RULES.post);
|
|
});
|
|
function groupKeywords(group) {
|
|
if (!applicability_1.shouldUseGroup(schema, group))
|
|
return;
|
|
if (group.type) {
|
|
gen.if(dataType_1.checkDataType(group.type, data, opts.strict));
|
|
iterateKeywords(it, group);
|
|
if (types.length === 1 && types[0] === group.type && typeErrors) {
|
|
gen.else();
|
|
dataType_1.reportTypeError(it);
|
|
}
|
|
gen.endIf();
|
|
}
|
|
else {
|
|
iterateKeywords(it, group);
|
|
}
|
|
// TODO make it "ok" call?
|
|
if (!allErrors)
|
|
gen.if(codegen_1._ `${names_1.default.errors} === ${errsCount || 0}`);
|
|
}
|
|
}
|
|
exports.schemaKeywords = schemaKeywords;
|
|
function iterateKeywords(it, group) {
|
|
const { gen, schema, opts: { useDefaults }, } = it;
|
|
if (useDefaults)
|
|
defaults_1.assignDefaults(it, group.type);
|
|
gen.block(() => {
|
|
for (const rule of group.rules) {
|
|
if (applicability_1.shouldUseRule(schema, rule)) {
|
|
keyword_1.keywordCode(it, rule.keyword, rule.definition, group.type);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
function checkStrictTypes(it, types) {
|
|
if (it.schemaEnv.meta || !it.opts.strictTypes)
|
|
return;
|
|
checkContextTypes(it, types);
|
|
if (!it.opts.allowUnionTypes)
|
|
checkMultipleTypes(it, types);
|
|
checkKeywordTypes(it, it.dataTypes);
|
|
}
|
|
function checkContextTypes(it, types) {
|
|
if (!types.length)
|
|
return;
|
|
if (!it.dataTypes.length) {
|
|
it.dataTypes = types;
|
|
return;
|
|
}
|
|
types.forEach((t) => {
|
|
if (!includesType(it.dataTypes, t)) {
|
|
strictTypesError(it, `type "${t}" not allowed by context "${it.dataTypes.join(",")}"`);
|
|
}
|
|
});
|
|
it.dataTypes = it.dataTypes.filter((t) => includesType(types, t));
|
|
}
|
|
function checkMultipleTypes(it, ts) {
|
|
if (ts.length > 1 && !(ts.length === 2 && ts.includes("null"))) {
|
|
strictTypesError(it, "use allowUnionTypes to allow union type keyword");
|
|
}
|
|
}
|
|
function checkKeywordTypes(it, ts) {
|
|
const rules = it.self.RULES.all;
|
|
for (const keyword in rules) {
|
|
const rule = rules[keyword];
|
|
if (typeof rule == "object" && applicability_1.shouldUseRule(it.schema, rule)) {
|
|
const { type } = rule.definition;
|
|
if (type.length && !type.some((t) => hasApplicableType(ts, t))) {
|
|
strictTypesError(it, `missing type "${type.join(",")}" for keyword "${keyword}"`);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function hasApplicableType(schTs, kwdT) {
|
|
return schTs.includes(kwdT) || (kwdT === "number" && schTs.includes("integer"));
|
|
}
|
|
function includesType(ts, t) {
|
|
return ts.includes(t) || (t === "integer" && ts.includes("number"));
|
|
}
|
|
function strictTypesError(it, msg) {
|
|
const schemaPath = it.schemaEnv.baseId + it.errSchemaPath;
|
|
msg += ` at "${schemaPath}" (strictTypes)`;
|
|
_1.checkStrictMode(it, msg, it.opts.strictTypes);
|
|
}
|
|
//# sourceMappingURL=iterate.js.map
|