2023-10-03 11:14:36 +08:00
|
|
|
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
|
const dataType_1 = require("../../compile/validate/dataType");
|
|
|
|
const codegen_1 = require("../../compile/codegen");
|
|
|
|
const equal = require("fast-deep-equal");
|
|
|
|
const error = {
|
|
|
|
message: ({ params: { i, j } }) => codegen_1.str `should NOT have duplicate items (items ## ${j} and ${i} are identical)`,
|
|
|
|
params: ({ params: { i, j } }) => codegen_1._ `{i: ${i}, j: ${j}}`,
|
|
|
|
};
|
|
|
|
const def = {
|
|
|
|
keyword: "uniqueItems",
|
|
|
|
type: "array",
|
|
|
|
schemaType: "boolean",
|
|
|
|
$data: true,
|
|
|
|
error,
|
|
|
|
code(cxt) {
|
|
|
|
const { gen, data, $data, schema, parentSchema, schemaCode, it } = cxt;
|
|
|
|
if (!$data && !schema)
|
|
|
|
return;
|
|
|
|
const valid = gen.let("valid");
|
|
|
|
const itemTypes = parentSchema.items ? dataType_1.getSchemaTypes(parentSchema.items) : [];
|
|
|
|
cxt.block$data(valid, validateUniqueItems, codegen_1._ `${schemaCode} === false`);
|
|
|
|
cxt.ok(valid);
|
|
|
|
function validateUniqueItems() {
|
|
|
|
const i = gen.let("i", codegen_1._ `${data}.length`);
|
|
|
|
const j = gen.let("j");
|
|
|
|
cxt.setParams({ i, j });
|
|
|
|
gen.assign(valid, true);
|
|
|
|
gen.if(codegen_1._ `${i} > 1`, () => (canOptimize() ? loopN : loopN2)(i, j));
|
|
|
|
}
|
|
|
|
function canOptimize() {
|
|
|
|
return itemTypes.length > 0 && !itemTypes.some((t) => t === "object" || t === "array");
|
|
|
|
}
|
|
|
|
function loopN(i, j) {
|
|
|
|
const item = gen.name("item");
|
|
|
|
const wrongType = dataType_1.checkDataTypes(itemTypes, item, it.opts.strict, dataType_1.DataType.Wrong);
|
|
|
|
const indices = gen.const("indices", codegen_1._ `{}`);
|
|
|
|
gen.for(codegen_1._ `;${i}--;`, () => {
|
|
|
|
gen.let(item, codegen_1._ `${data}[${i}]`);
|
|
|
|
gen.if(wrongType, codegen_1._ `continue`);
|
|
|
|
if (itemTypes.length > 1)
|
|
|
|
gen.if(codegen_1._ `typeof ${item} == "string"`, codegen_1._ `${item} += "_"`);
|
|
|
|
gen
|
|
|
|
.if(codegen_1._ `typeof ${indices}[${item}] == "number"`, () => {
|
|
|
|
gen.assign(j, codegen_1._ `${indices}[${item}]`);
|
|
|
|
cxt.error();
|
|
|
|
gen.assign(valid, false).break();
|
|
|
|
})
|
|
|
|
.code(codegen_1._ `${indices}[${item}] = ${i}`);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
function loopN2(i, j) {
|
|
|
|
const eql = cxt.gen.scopeValue("func", {
|
|
|
|
ref: equal,
|
|
|
|
code: codegen_1._ `require("ajv/dist/compile/equal")`,
|
|
|
|
});
|
|
|
|
const outer = gen.name("outer");
|
|
|
|
gen.label(outer).for(codegen_1._ `;${i}--;`, () => gen.for(codegen_1._ `${j} = ${i}; ${j}--;`, () => gen.if(codegen_1._ `${eql}(${data}[${i}], ${data}[${j}])`, () => {
|
|
|
|
cxt.error();
|
|
|
|
gen.assign(valid, false).break(outer);
|
|
|
|
})));
|
|
|
|
}
|
|
|
|
},
|
|
|
|
};
|
|
|
|
exports.default = def;
|
2023-09-25 15:58:56 +08:00
|
|
|
//# sourceMappingURL=uniqueItems.js.map
|