UNPKG

vulcain-corejs

Version:
179 lines (177 loc) 6.9 kB
"use strict"; class Validator { constructor(domain, container) { this.domain = domain; this.container = container; } validate(schemaDesc, val) { let errors = []; if (!schemaDesc || !val) return errors; if (schemaDesc.extends) { let base = this.domain.resolveSchemaDescription(schemaDesc.extends); if (base) { this.validate(base, val).forEach(e => { errors.push(e); }); } } let id = val && val[this.domain.getIdProperty(schemaDesc)]; let ctx = { element: val, schemaElement: schemaDesc, id: id }; // Properties checks for (const ps in schemaDesc.properties) { if (!schemaDesc.properties.hasOwnProperty(ps)) continue; ctx.propertyName = ps; ctx.propertySchema = schemaDesc.properties[ps]; ctx.propertyValue = val[ps]; try { let err = this.validateProperty(ctx, schemaDesc.properties[ps], val[ps], val); if (err) { errors.push({ message: err, property: ps, id: ctx.id }); } } catch (e) { errors.push({ message: this.__formatMessage("Validation error for property {$propertyName} : " + e, ctx), id: ctx.id, property: ps }); } } // References checks for (const rs in schemaDesc.references) { if (!schemaDesc.references.hasOwnProperty(rs)) continue; ctx.propertyName = rs; ctx.propertySchema = schemaDesc.references[rs]; ctx.propertyValue = val[rs]; try { let ref = schemaDesc.references[rs]; if (ref.item === "any" && ctx.propertyValue && ctx.propertyValue.__schema) { if (ref && ref.dependsOn && !ref.dependsOn(val)) continue; let schema = this.domain.getSchema(ctx.propertyValue.__schema); if (!schema) continue; errors = errors.concat(this.validate(schema.description, ctx.propertyValue)); } else { let errors2 = this.validateReference(ref, val[rs], val); errors2 && errors2.forEach(err => errors.push({ message: this.__formatMessage(err, ctx, schemaDesc), id: ctx.id, property: rs })); } } catch (e) { errors.push({ message: this.__formatMessage("Validation error for reference {$propertyName} : " + e, ctx), id: ctx.id, property: rs }); } } // Entity check if (schemaDesc.validate) { ctx.propertyName = ctx.propertySchema = ctx.propertyValue = null; try { let err = schemaDesc.validate(val, this.container); if (err) errors.push({ message: this.__formatMessage(err, ctx, schemaDesc), id: ctx.id }); } catch (e) { errors.push({ message: this.__formatMessage("Validation error for element {__schema} : " + e, ctx), id: ctx.id }); } } return errors; } validateReference(schema, val, entity) { if (!schema) return; if (schema.dependsOn && !schema.dependsOn(entity)) return; if (!val) { if (schema.required) { return ["Reference '{$propertyName}' is required."]; } return null; } if (schema.validators) { for (let validator of schema.validators) { let err = validator.validate && validator.validate(val); if (err) return [err]; } } let err = schema.validate && schema.validate(val); if (err) return [err]; let values = schema.cardinality === "one" ? [val] : val; let itemType = schema.item && this.domain._findType(schema.item); let errors = []; for (let val of values) { if (val) { let t = itemType; if (val.__schema && val.__schema !== schema.item) t = this.domain._findType(val.__schema); errors = errors.concat(this.validate(t, val)); } } return errors; } validateProperty(ctx, schema, val, entity) { 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.", ctx, schema); } return null; } if (schema.validators) { for (let validator of schema.validators) { let err = validator.validate && validator.validate(val); if (err) return this.__formatMessage(err, ctx, validator); } } if (schema.validate) { let err = schema.validate(val); if (err) return this.__formatMessage(err, ctx, schema); } } /** * Format an error message * @param message * @param ctx * @returns {string} * @private */ __formatMessage(message, ctx, validator) { var 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