UNPKG

vulcain-corejs

Version:
207 lines (205 loc) 9.45 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments)).next()); }); }; class Validator { constructor(domain, container) { this.domain = domain; this.container = container; } validateAsync(ctx, schemaDesc, val) { return __awaiter(this, void 0, void 0, function* () { let errors = []; if (!schemaDesc || !val) return errors; if (schemaDesc.extends) { let base = this.domain.resolveSchemaDescription(schemaDesc.extends); if (base) { (yield this.validateAsync(ctx, base, val)).forEach(e => { errors.push(e); }); } } let id = val && val[this.domain.getIdProperty(schemaDesc)]; let formatContext = { element: val, schemaElement: schemaDesc, id: id }; // Properties checks for (const ps in schemaDesc.properties) { if (!schemaDesc.properties.hasOwnProperty(ps)) continue; formatContext.propertyName = ps; formatContext.propertySchema = schemaDesc.properties[ps]; formatContext.propertyValue = val[ps]; try { let err = yield this.validatePropertyAsync(ctx, formatContext, schemaDesc.properties[ps], val[ps], val); if (err) { errors.push({ message: err, property: ps, id: formatContext.id }); } } catch (e) { errors.push({ message: this.__formatMessage("Validation error for property {$propertyName} : " + e, formatContext), id: formatContext.id, property: ps }); } } // References checks for (const rs in schemaDesc.references) { if (!schemaDesc.references.hasOwnProperty(rs)) continue; formatContext.propertyName = rs; formatContext.propertySchema = schemaDesc.references[rs]; formatContext.propertyValue = val[rs]; try { let ref = schemaDesc.references[rs]; if (ref.item === "any" && formatContext.propertyValue && formatContext.propertyValue.__schema) { if (ref && ref.dependsOn && !ref.dependsOn(val)) continue; let schema = this.domain.getSchema(formatContext.propertyValue.__schema); if (!schema) continue; errors = errors.concat(yield this.validateAsync(ctx, schema.description, formatContext.propertyValue)); } else { let errors2 = yield this.validateReferenceAsync(ctx, formatContext, ref, val[rs], val); if (errors2) errors = errors.concat(errors2); } } catch (e) { errors.push({ message: this.__formatMessage("Validation error for reference {$propertyName} : " + e, formatContext), id: formatContext.id, property: rs }); } } // Entity check if (schemaDesc.validate) { formatContext.propertyName = formatContext.propertySchema = formatContext.propertyValue = null; try { let err = yield schemaDesc.validate(val, ctx); if (err) errors.push({ message: this.__formatMessage(err, formatContext, schemaDesc), id: formatContext.id }); } catch (e) { errors.push({ message: this.__formatMessage("Validation error for element {__schema} : " + e, formatContext), id: formatContext.id }); } } return errors; }); } validateReferenceAsync(ctx, formatContext, schema, val, entity) { return __awaiter(this, void 0, void 0, function* () { if (!schema) return; if (schema.dependsOn && !schema.dependsOn(entity)) return; if (!val) { if (schema.required) { return [{ message: this.__formatMessage("Reference '{$propertyName}' is required.", formatContext, schema), id: formatContext.id, property: formatContext.propertyName }]; } return null; } if (schema.validators) { for (let validator of schema.validators) { let msg = validator.validate && (yield validator.validate(val, ctx)); if (msg) return [{ message: this.__formatMessage(msg, formatContext, schema), id: formatContext.id, property: formatContext.propertyName }]; } } let err = schema.validate && (yield schema.validate(val, ctx)); if (err) return [err]; let values = schema.cardinality === "one" ? [val] : val; let baseItemSchema = schema.item && schema.item !== "any" && this.domain.getSchema(schema.item, true); let errors = []; for (let val of values) { if (val) { let currentItemSchema = baseItemSchema; if (val.__schema && (!currentItemSchema || val.__schema !== currentItemSchema.name)) { currentItemSchema = this.domain.getSchema(val.__schema, true); if (!baseItemSchema) baseItemSchema = currentItemSchema; } if (currentItemSchema) { errors = errors.concat(yield this.validateAsync(ctx, currentItemSchema.description, val)); } } } return errors; }); } validatePropertyAsync(ctx, formatContext, schema, val, entity) { return __awaiter(this, void 0, void 0, function* () { if (typeof schema === "string") { let type = this.domain._findType(schema); if (!type) { return null; } schema = type; } if (schema.dependsOn && !schema.dependsOn(entity)) return; if (val === undefined || val === null) { if (schema.required) { return this.__formatMessage("Property '{$propertyName}' is required.", formatContext, schema); } return null; } if (schema.validators) { for (let validator of schema.validators) { let err = validator.validate && (yield validator.validate(val, ctx)); if (err) return this.__formatMessage(err, formatContext, validator); } } if (schema.validate) { let err = yield schema.validate(val, ctx); if (err) return this.__formatMessage(err, formatContext, schema); } }); } /** * Format an error message * @param message * @param ctx * @returns {string} * @private */ __formatMessage(message, ctx, validator) { const regex = /{\s*([^}\s]*)\s*}/g; return message.replace(regex, function (match, name) { switch (name) { case "$value": return ctx.propertyValue; case "$schema": return ctx.propertyName ? ctx.propertySchema : ctx.schemaElement; case "$id": return ctx.id; case "$propertyName": return ctx.propertyName; default: if (!name) return null; // Name beginning with $ belongs to schema if (name[0] === "$" && validator) { let p = validator[name] || validator[name.substring(1)]; return (typeof p === "function" && p(validator)) || p; } // Else it's an element's property if (ctx.element) { let p = ctx.element[name]; return (typeof p === "function" && p(ctx.element)) || p; } return null; } }); } } exports.Validator = Validator; //# sourceMappingURL=validator.js.map