@allgemein/schema-api
Version:
Library for schema api
208 lines • 8.86 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.DefaultValidator = void 0;
const lodash_1 = require("lodash");
const IClassRef_1 = require("../../api/IClassRef");
const IEntityRef_1 = require("../../api/IEntityRef");
const base_1 = require("@allgemein/base");
const ClassRef_1 = require("../ClassRef");
const Constants_1 = require("../Constants");
const MetadataRegistry_1 = require("../registry/MetadataRegistry");
class DefaultValidator {
static define(validator) {
this.validators.push(validator);
if (validator.involveOnOptionKey) {
this.lookupKeys.unshift(validator.involveOnOptionKey);
this.lookupKeys = (0, lodash_1.uniq)(this.lookupKeys);
}
}
static async validationInfo(ref) {
let clazz = null;
if ((0, IEntityRef_1.isEntityRef)(ref) || (0, IClassRef_1.isClassRef)(ref)) {
clazz = ref.getClass();
}
else if ((0, lodash_1.isFunction)(ref)) {
clazz = ref;
}
else {
throw new Error('not implemented for ' + ref);
}
return this.getValidationHandlesForFn(clazz);
}
static async validate(instance, ref) {
let classRef = null;
if (ref) {
if ((0, IEntityRef_1.isEntityRef)(ref)) {
classRef = ref.getClassRef();
}
else {
classRef = ref;
}
}
else {
const target = base_1.ClassUtils.getFunction(instance);
if (!target) {
throw new base_1.NotYetImplementedError();
}
classRef = ClassRef_1.ClassRef.get(target);
}
// const entries:IPropertyExtentions[] = MetadataStorage
// .key(XS_ANNOTATION_OPTIONS_CACHE)
// .filter((x:IPropertyExtentions) =>
// x.object === classRef.getClass() && (has(x.options, 'format') || has(x.options, 'format'))
// );
const classErrors = [];
const toValidateList = this.getValidationHandlesForFn(classRef.getClass());
for (const toValidateEntry of toValidateList) {
for (const handle of toValidateEntry.handles) {
let value = null;
let isPropertyCheck = toValidateEntry.property ? true : false;
if (isPropertyCheck) {
value = instance[toValidateEntry.property];
}
else {
value = instance;
}
// @ts-ignore
let instanceOptions = (0, lodash_1.clone)(toValidateEntry.options[handle.name]);
if (isPropertyCheck) {
instanceOptions.property = toValidateEntry.property;
}
if (handle.defaultOptions) {
(0, lodash_1.defaults)(instanceOptions, handle.defaultOptions);
}
if (!(await handle.fn(value, instanceOptions, instance))) {
const error = {
metaType: toValidateEntry.property ? 'property' : 'entity',
property: toValidateEntry.property,
value: value,
constraints: {}
};
classErrors.push(error);
let msg = (0, lodash_1.get)(instanceOptions, 'message', null);
if (msg) {
msg = msg.replace('%propertyName', error.property).replace('%value', value);
(0, lodash_1.keys)(instanceOptions).forEach(k => {
let v = instanceOptions[k];
if ((0, lodash_1.isObjectLike)(v) || (0, lodash_1.isArray)(v)) {
v = JSON.stringify(v);
}
msg = msg.replace('%options.' + k, v);
});
error.constraints[handle.name] = msg;
}
}
}
}
// validate entity
// const classErrors = await this.validateHandles(classRef, instance);
// for (const ref of classRef.getPropertyRefs()) {
// if (ref.isReference()) {
// // TODO
// } else {
// classErrors.push(...await this.validateHandles(ref, ref.get(instance)));
// }
// }
return classErrors;
}
//
//
// static async validateHandles(ref: IBaseRef, value: any) {
// const handleKeys = this.getHandleKeys(ref);
// if (isEmpty(handleKeys)) {
// return [];
// }
// const handles = this.getHandles(handleKeys);
// const errors: IValidationError[] = [];
// for (const handle of handles) {
// if (handle) {
// }
// }
// return errors;
// }
//
//
// static getHandles(handleKeys: string[]): { name: string, fn: (value: any) => boolean, opts?: { message?: string } }[] {
// return [].concat(...handleKeys.map(k => this.validators.filter(y => y.name === k)));
// }
//
static getValidationHandlesForFn(fn) {
const entries = [];
const entriesSecond = MetadataRegistry_1.MetadataRegistry.$().getCached().filter(x => x.target === fn && (0, lodash_1.intersection)(this.lookupKeys, (0, lodash_1.keys)(x)).length > 0);
for (const e of entriesSecond) {
const handlesAndOptions = this.extractValidationInfox(e);
const validationEntry = {
target: fn,
};
(0, lodash_1.assign)(validationEntry, handlesAndOptions);
if (e.propertyName) {
validationEntry.property = e.propertyName;
}
entries.push(validationEntry);
}
const entriesFirst = base_1.MetadataStorage
.key(Constants_1.XS_ANNOTATION_OPTIONS_CACHE)
.filter((x) => x.object === fn && (0, lodash_1.intersection)(this.lookupKeys, (0, lodash_1.keys)(x.options)).length > 0);
for (const e of entriesFirst) {
const alreadyAsProperty = entries.find(x => x.property === e.property);
const handlesAndOptions = this.extractValidationInfox(e.options);
if (alreadyAsProperty) {
for (let i = 0; i < handlesAndOptions.handles.length; i++) {
const handle = handlesAndOptions.handles[i];
if (alreadyAsProperty.handles.find(x => x.name === handle.name)) {
// ignore double declarations
continue;
}
alreadyAsProperty.handles.push(handle);
(0, lodash_1.set)(alreadyAsProperty.options, handle.name, (0, lodash_1.get)(handlesAndOptions.options, handle.name, {}));
}
}
else {
const validationEntry = {
target: fn,
};
(0, lodash_1.assign)(validationEntry, handlesAndOptions);
if (e.property) {
validationEntry.property = e.property;
}
entries.push(validationEntry);
}
}
return entries;
}
static extractValidationInfox(entryOptions) {
const intersect = (0, lodash_1.intersection)(this.lookupKeys, (0, lodash_1.keys)(entryOptions));
const handles = [];
const options = {};
for (const k of intersect) {
const isLookupKey = ['validate', 'format'].includes(k);
const valueForKey = (0, lodash_1.get)(entryOptions, k, null);
const handle = this.validators.find(x => x.name === valueForKey || x.involveOnOptionKey === k);
if (handle) {
const handleAlreadySet = handles.find(x => x.name === handle.name);
if (!handleAlreadySet) {
handles.push(handle);
}
let v = (0, lodash_1.clone)((0, lodash_1.get)(entryOptions, 'validateOptions.' + handle.name, {}));
if (!isLookupKey) {
// pass additional value
v[handle.involveOnOptionKey] = (0, lodash_1.get)(entryOptions, handle.involveOnOptionKey, null);
}
if (v) {
if (!options[handle.name]) {
options[handle.name] = {};
}
(0, lodash_1.merge)(options[handle.name], v);
}
}
}
return {
handles: handles,
options: options
};
}
}
exports.DefaultValidator = DefaultValidator;
DefaultValidator.validators = [];
DefaultValidator.lookupKeys = ['format', 'validate'];
//# sourceMappingURL=DefaultValidator.js.map