@bshg/validation
Version:
Validation Library for TypeScript projects
372 lines (371 loc) • 19.1 kB
JavaScript
"use strict";
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
var _Validator_instances, _Validator_id, _Validator_options, _Validator_getter, _Validator_items, _Validator_nested, _Validator_ready, _Validator_validatorItems_get, _Validator_nestedValues_get, _Validator_info, _Validator_warn, _Validator_error;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Validator = void 0;
const results_1 = require("../results");
const validator_item_1 = require("./validator-item");
const options_1 = require("../options");
const logger_1 = __importDefault(require("../logger"));
const exceptions_1 = require("../exceptions");
class Validator {
constructor() {
_Validator_instances.add(this);
_Validator_id.set(this, Object.getPrototypeOf(this).constructor.name);
_Validator_options.set(this, options_1.options);
_Validator_getter.set(this, void 0);
_Validator_items.set(this, void 0);
_Validator_nested.set(this, void 0);
// TODO: show the status in the results collections
this.status = {};
}
config(config) {
if (__classPrivateFieldGet(this, _Validator_getter, "f") != undefined && __classPrivateFieldGet(this, _Validator_getter, "f").call(this) == undefined)
throw new exceptions_1.BshgError(__classPrivateFieldGet(this, _Validator_id, "f"), `The Object is undefined! We can not create a validator for undefined object.`);
if (config.id)
__classPrivateFieldSet(this, _Validator_id, config.id, "f");
if (config.items) {
const fields = {};
for (const key in config.items) {
if (!Object.prototype.hasOwnProperty.call(config.items, key))
continue;
const item = new validator_item_1.ValidatorItem();
item.container = () => __classPrivateFieldGet(this, _Validator_getter, "f").call(this);
item.get = () => __classPrivateFieldGet(this, _Validator_getter, "f").call(this)[key];
item.set = (value) => (__classPrivateFieldGet(this, _Validator_getter, "f").call(this)[key] = value);
item.name = key;
item.setValidations(config.items[key]);
item.validator = this;
fields[key] = item;
}
__classPrivateFieldSet(this, _Validator_items, fields, "f");
}
if (config.nested) {
for (const key in config.nested) {
if (!Object.prototype.hasOwnProperty.call(config.nested, key))
continue;
const nested = config.nested[key];
if (nested == undefined)
continue;
__classPrivateFieldSet(nested, _Validator_getter, () => __classPrivateFieldGet(this, _Validator_getter, "f").call(this)[key], "f");
// @ts-ignore
nested.status.field = key;
this.nested[key] = nested;
}
}
return this;
}
get nested() {
if (!__classPrivateFieldGet(this, _Validator_nested, "f"))
__classPrivateFieldSet(this, _Validator_nested, {}, "f");
return __classPrivateFieldGet(this, _Validator_nested, "f");
}
get items() {
return __classPrivateFieldGet(this, _Validator_items, "f") ? __classPrivateFieldGet(this, _Validator_items, "f") : {};
}
options(value) {
__classPrivateFieldSet(this, _Validator_options, { ...__classPrivateFieldGet(this, _Validator_options, "f"), ...value }, "f");
return this;
}
allGood() {
const filtered = __classPrivateFieldGet(this, _Validator_instances, "a", _Validator_validatorItems_get).filter(it => it.valid != undefined); /* filter out the none validated items */
if (filtered.length == 0)
return this.status.valid != undefined && this.status.valid; // no validation are applied
const result = filtered.every((it) => it.valid);
this.status.valid = result;
this.status.message = result ? undefined : "invalid";
return result;
}
applyAll() {
__classPrivateFieldGet(this, _Validator_instances, "a", _Validator_validatorItems_get).forEach((it) => it.validate());
}
async applyAllAsync() {
await Promise.all(__classPrivateFieldGet(this, _Validator_instances, "a", _Validator_validatorItems_get).map(async (it) => await it.validateAsync()));
}
reset() {
const validators = [this, ...__classPrivateFieldGet(this, _Validator_instances, "a", _Validator_nestedValues_get)];
validators.forEach((it) => __classPrivateFieldGet(it, _Validator_instances, "a", _Validator_validatorItems_get).forEach((it) => it.reset()));
}
init(getter) {
__classPrivateFieldSet(this, _Validator_getter, getter, "f");
return this;
}
///////////////////////////////////////////////////
///////////// CONTEXT /////////////////////////////
///////////////////////////////////////////////////
withContext(context) {
this.context = context;
return this;
}
///////////////////////////////////////////////////
///////////// ERRORS GENERATORS ///////////////////
///////////////////////////////////////////////////
generateErrorsAsObject() {
var _a;
const result = {};
if (__classPrivateFieldGet(this, _Validator_instances, "a", _Validator_validatorItems_get).length > 0) {
const simple = __classPrivateFieldGet(this, _Validator_instances, "a", _Validator_validatorItems_get)
.filter(it => it && !it.valid)
.map((it) => {
return {
field: it.name,
message: it.message,
valid: false,
value: it.get(),
};
});
if (simple.length > 0)
result.items = simple;
}
if (__classPrivateFieldGet(this, _Validator_nested, "f")) {
const nested = {};
for (let key in __classPrivateFieldGet(this, _Validator_nested, "f")) {
if (__classPrivateFieldGet(this, _Validator_nested, "f")[key] != undefined) {
// @ts-ignore
nested[key] = (_a = __classPrivateFieldGet(this, _Validator_nested, "f")[key]) === null || _a === void 0 ? void 0 : _a.generateErrorsAsObject();
}
}
if (Object.keys(nested).length > 0)
result.nested = nested;
}
return result;
}
generateErrorsAsArray() {
var _a;
const result = {};
if (__classPrivateFieldGet(this, _Validator_instances, "a", _Validator_validatorItems_get).length > 0) {
const simple = __classPrivateFieldGet(this, _Validator_instances, "a", _Validator_validatorItems_get)
.filter((it) => it && !it.valid)
.map((it) => {
return {
field: it.name,
message: it.message,
valid: false,
value: it.get(),
};
});
if (simple.length > 0)
result.items = simple;
}
if (__classPrivateFieldGet(this, _Validator_nested, "f")) {
const nested = [];
for (let key in __classPrivateFieldGet(this, _Validator_nested, "f")) {
const error = {};
error.field = key;
error.result = (_a = __classPrivateFieldGet(this, _Validator_nested, "f")[key]) === null || _a === void 0 ? void 0 : _a.generateErrorsAsArray();
nested.push(error);
}
if (nested.length > 0)
result.nested = nested;
}
return result;
}
generateErrors() {
if (__classPrivateFieldGet(this, _Validator_options, "f").resultsType == "array")
return this.generateErrorsAsArray();
else
return this.generateErrorsAsObject();
}
///////////////////////////////////////////////////
///////////// SINGLE VALIDATIONS //////////////////
///////////////////////////////////////////////////
validate(data) {
if (data) {
__classPrivateFieldSet(this, _Validator_getter, () => data, "f");
}
const validators = [this, ...Object.values(this.nested)];
validators.forEach((it) => {
if (__classPrivateFieldGet(it, _Validator_instances, "m", _Validator_ready).call(it))
it.applyAll();
});
const isValid = validators.every((it) => it.allGood());
__classPrivateFieldGet(this, _Validator_instances, "m", _Validator_info).call(this, `validation result `, isValid);
return isValid;
}
async validateAsync(data) {
if (data) {
__classPrivateFieldSet(this, _Validator_getter, () => data, "f");
}
const validators = [this, ...Object.values(this.nested)];
await Promise.all(validators.map(async (it) => {
if (__classPrivateFieldGet(it, _Validator_instances, "m", _Validator_ready).call(it))
await it.applyAllAsync();
}));
const isValid = validators.every((it) => it.allGood());
__classPrivateFieldGet(this, _Validator_instances, "m", _Validator_info).call(this, `validation result `, isValid);
return isValid;
}
validateInfo(data) {
if (this.validate(data))
return { success: true };
else {
const results = this.generateErrors();
__classPrivateFieldGet(this, _Validator_instances, "m", _Validator_info).call(this, results);
return { success: false, results };
}
}
async validateInfoAsync(data) {
const res = await this.validateAsync(data);
if (res)
return { success: true };
else {
const results = this.generateErrors();
__classPrivateFieldGet(this, _Validator_instances, "m", _Validator_info).call(this, results);
return { success: false, results };
}
}
validateThrow(data) {
if (!this.validate(data)) {
const results = this.generateErrors();
__classPrivateFieldGet(this, _Validator_instances, "m", _Validator_info).call(this, results);
throw new results_1.BshValidationError(results);
}
}
async validateThrowAsync(data) {
const res = await this.validateAsync(data);
if (!res) {
const results = this.generateErrors();
__classPrivateFieldGet(this, _Validator_instances, "m", _Validator_info).call(this, results);
throw new results_1.BshValidationError(results);
}
}
///////////////////////////////////////////////////
///////////// BATCH VALIDATIONS ///////////////////
///////////////////////////////////////////////////
batchValidate(...data) {
const results = [];
data === null || data === void 0 ? void 0 : data.forEach(it => {
results.push(this.init(() => it).validateInfo());
});
return { success: results.every(it => it.success), results };
}
async batchValidateAsync(...data) {
const results = [];
// TODO: Do the validations in the same time for all items,
// to reduce the validation duration
// if it is possible?
for (let it of data) {
const validatorResultInfo = await this.init(() => it).validateInfoAsync();
results.push(validatorResultInfo);
}
return { success: results.every(it => it.success), results };
}
batchValidateThrow(...data) {
const batchResult = this.batchValidate(...data);
if (!batchResult.success)
throw new results_1.BshBatchValidationError(batchResult.results);
}
async batchValidateThrowAsync(...data) {
const batchResult = await this.batchValidateAsync(...data);
if (!batchResult.success)
throw new results_1.BshBatchValidationError(batchResult.results);
}
///////////////////////////////////////////////////
///////////// IMPORT METHOD ///////////////////////
///////////////////////////////////////////////////
import(results) {
var _a;
if (__classPrivateFieldGet(this, _Validator_items, "f") != undefined) {
(_a = results.items) === null || _a === void 0 ? void 0 : _a.forEach(it => {
const validatorItem = __classPrivateFieldGet(this, _Validator_items, "f")[it.field];
if (validatorItem == undefined) {
__classPrivateFieldGet(this, _Validator_instances, "m", _Validator_warn).call(this, `Unknown validatorItem '${it.field}' in ${__classPrivateFieldGet(this, _Validator_id, "f")}!\nIt Will be ignored!`);
}
else {
validatorItem.valid = it.valid;
validatorItem.message = it.message;
// TODO: add these logs to separate file to let the code source clean
if (__classPrivateFieldGet(this, _Validator_getter, "f") == undefined)
__classPrivateFieldGet(this, _Validator_instances, "m", _Validator_warn).call(this, `if the value of '${it.field}' value is modified, the change will be ignored unless the \`.init()\` method is used. To ensure the update is applied, please use \`.init()\` to apply the changes correctly.`);
else
validatorItem.set(it.value);
}
});
}
else if (results.items) {
__classPrivateFieldGet(this, _Validator_instances, "m", _Validator_warn).call(this, `No Simple Fields Found in ${__classPrivateFieldGet(this, _Validator_id, "f")}`);
}
if (__classPrivateFieldGet(this, _Validator_nested, "f") != undefined) {
if (__classPrivateFieldGet(this, _Validator_options, "f").resultsType == "object") {
const nested = results.nested;
for (const key in nested) {
// @ts-ignore
const validator = __classPrivateFieldGet(this, _Validator_nested, "f")[key];
if (nested[key] != undefined)
validator === null || validator === void 0 ? void 0 : validator.import(nested[key]);
}
}
else {
const nested = results.nested;
nested.forEach(it => {
const validator = __classPrivateFieldGet(this, _Validator_nested, "f") != undefined ? ((__classPrivateFieldGet(this, _Validator_nested, "f"))[it.field]) : undefined;
if (validator == undefined) {
__classPrivateFieldGet(this, _Validator_instances, "m", _Validator_warn).call(this, `${it.field} is unknown nested validator in ${__classPrivateFieldGet(this, _Validator_id, "f")}!\nIt Will be ignored!`);
}
else {
validator.import(it.result);
}
});
}
}
else if (results.nested) {
__classPrivateFieldGet(this, _Validator_instances, "m", _Validator_warn).call(this, `No Nested Validator Exist in ${__classPrivateFieldGet(this, _Validator_id, "f")}! But the error has.`);
}
}
///////////////////////////////////////////////////
///////////// ONCHNAGE EVENT METHOD ///////////////
///////////////////////////////////////////////////
onChange(event) {
this.onChangeEvent = event;
return this;
}
///////////////////////////////////////////////////
///////////// GET ITEM STATUS /////////////////////
///////////////////////////////////////////////////
validateItem(key) {
var _a;
(_a = this.items[key]) === null || _a === void 0 ? void 0 : _a.validate();
}
isItemValid(key) {
var _a;
return (_a = this.items[key]) === null || _a === void 0 ? void 0 : _a.valid;
}
itemMessage(key) {
var _a;
return (_a = this.items[key]) === null || _a === void 0 ? void 0 : _a.message;
}
}
exports.Validator = Validator;
_Validator_id = new WeakMap(), _Validator_options = new WeakMap(), _Validator_getter = new WeakMap(), _Validator_items = new WeakMap(), _Validator_nested = new WeakMap(), _Validator_instances = new WeakSet(), _Validator_ready = function _Validator_ready() {
if (__classPrivateFieldGet(this, _Validator_getter, "f") == undefined || __classPrivateFieldGet(this, _Validator_getter, "f").call(this) == undefined) {
this.status.valid = false;
this.status.message = `The value ${this.status.field ? "of " + this.status.field : ""} is undefined.`;
return false;
}
this.status.valid = undefined;
this.status.message = undefined;
return true;
}, _Validator_validatorItems_get = function _Validator_validatorItems_get() {
return __classPrivateFieldGet(this, _Validator_items, "f") ? Object.values(__classPrivateFieldGet(this, _Validator_items, "f")) : [];
}, _Validator_nestedValues_get = function _Validator_nestedValues_get() {
return Object.values(this.nested);
}, _Validator_info = function _Validator_info(...data) {
logger_1.default.info(__classPrivateFieldGet(this, _Validator_id, "f"), __classPrivateFieldGet(this, _Validator_options, "f").dev || false, ...data);
}, _Validator_warn = function _Validator_warn(...data) {
logger_1.default.warn(__classPrivateFieldGet(this, _Validator_id, "f"), __classPrivateFieldGet(this, _Validator_options, "f").dev || false, ...data);
}, _Validator_error = function _Validator_error(...data) {
logger_1.default.error(__classPrivateFieldGet(this, _Validator_id, "f"), true, ...data);
};