UNPKG

@bshg/validation

Version:

Validation Library for TypeScript projects

372 lines (371 loc) 19.1 kB
"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); };