model-layer
Version:
136 lines • 4.75 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ArrayType = void 0;
const Type_1 = require("./Type");
const utils_1 = require("../utils");
const errors_1 = require("../errors");
class ArrayType extends Type_1.Type {
constructor({ sort = false, unique = false, emptyAsNull = false, nullAsEmpty = false, element, ...otherParams }) {
super(otherParams);
if (emptyAsNull && nullAsEmpty) {
throw new errors_1.ConflictNullAndEmptyArrayParameterError({});
}
this.emptyAsNull = emptyAsNull;
this.nullAsEmpty = nullAsEmpty;
this.sort = sort;
this.unique = unique;
this.element = element;
}
static prepareDescription(description, key) {
if (description.type === "array") {
// prepare element description
description.element = Type_1.Type.create(description.element || "any", key);
}
}
prepare(originalValue, key, parentModel) {
if (originalValue == null) {
if (this.nullAsEmpty) {
const emptyArr = [];
Object.freeze(emptyArr);
return emptyArr;
}
return null;
}
const elementDescription = this.element;
const elementTypeAsString = elementDescription.typeAsString();
if (!Array.isArray(originalValue)) {
const valueAsString = utils_1.invalidValuesAsString(originalValue);
throw new errors_1.InvalidArrayError({
elementType: elementTypeAsString,
key,
invalidValue: valueAsString
});
}
const value = originalValue.map((element, i) => {
try {
element = elementDescription.prepare(element, i, parentModel);
}
catch (err) {
const valueAsString = utils_1.invalidValuesAsString(originalValue);
throw new errors_1.InvalidArrayElementError({
index: i,
modelKey: key,
elementType: elementTypeAsString,
invalidValue: valueAsString,
childError: err.message
});
}
return element;
});
if (this.emptyAsNull) {
if (value.length === 0) {
return null;
}
}
if (this.sort) {
if (typeof this.sort === "function") {
value.sort(this.sort);
}
else {
value.sort();
}
}
Object.freeze(value);
return value;
}
validate(value, key) {
const isValid = super.validate(value, key);
if (!isValid) {
return false;
}
if (value && this.unique) {
value.forEach((element, index) => {
if (element == null) {
return;
}
let isDuplicate = false;
let duplicateValue;
for (let i = 0, n = index; i < n; i++) {
const anotherElement = value[i];
if (anotherElement === element) {
isDuplicate = true;
duplicateValue = element;
break;
}
}
if (isDuplicate) {
const valueAsString = utils_1.invalidValuesAsString(value);
throw new errors_1.DuplicateValueForUniqueArrayError({
key,
duplicateValue: utils_1.invalidValuesAsString(duplicateValue),
invalidArr: valueAsString
});
}
});
}
return true;
}
toJSON(value, stack) {
return value.map((item) => this.element.toJSON(item, [...stack]));
}
clone(value, stack, parentModel) {
return value.map((item) => this.element.clone(item, stack, parentModel));
}
equal(selfArr, otherArr, stack) {
if (selfArr == null) {
return otherArr === null;
}
if (!Array.isArray(otherArr)) {
return false;
}
if (selfArr.length !== otherArr.length) {
return false;
}
for (let i = 0, n = selfArr.length; i < n; i++) {
const selfItem = selfArr[i];
const otherItem = otherArr[i];
const isEqual = this.element.equal(selfItem, otherItem, stack);
if (!isEqual) {
return false;
}
}
return true;
}
}
exports.ArrayType = ArrayType;
//# sourceMappingURL=ArrayType.js.map