ngx-vest-forms
Version:
Opinionated template-driven forms library for Angular
61 lines • 7.96 kB
JavaScript
import { isDevMode } from '@angular/core';
/**
* Clean error that improves the DX when making typo's in the `name` or `ngModelGroup` attributes
*/
export class ShapeMismatchError extends Error {
constructor(errorList) {
super(`Shape mismatch:\n\n${errorList.join('\n')}\n\n`);
}
}
/**
* Validates a form value against a shape
* When there is something in the form value that is not in the shape, throw an error
* This is how we throw runtime errors in develop when the developer has made a typo in the `name` or `ngModelGroup`
* attributes.
* @param formVal
* @param shape
*/
export function validateShape(formVal, shape) {
// Only execute in dev mode
if (isDevMode()) {
const errors = validateFormValue(formVal, shape);
if (errors.length) {
throw new ShapeMismatchError(errors);
}
}
}
/**
* Validates a form value against a shape value to see if it matches
* Returns clean errors that have a good DX
* @param formValue
* @param shape
* @param path
*/
function validateFormValue(formValue, shape, path = '') {
const errors = [];
for (const key in formValue) {
if (Object.keys(formValue).includes(key)) {
// In form arrays we don't know how many items there are
// This means that we always need to provide one record in the shape of our form array
// so every time reset the key to '0' when the key is a number and is bigger than 0
let keyToCompareWith = key;
if (parseFloat(key) > 0) {
keyToCompareWith = '0';
}
const newPath = path ? `${path}.${key}` : key;
if (typeof formValue[key] === 'object' && formValue[key] !== null) {
if ((typeof shape[keyToCompareWith] !== 'object' ||
shape[keyToCompareWith] === null) &&
isNaN(parseFloat(key))) {
errors.push(`[ngModelGroup] Mismatch: '${newPath}'`);
}
errors.push(...validateFormValue(formValue[key], shape[keyToCompareWith], newPath));
}
else if ((shape ? !(key in shape) : true) && isNaN(parseFloat(key))) {
errors.push(`[ngModel] Mismatch '${newPath}'`);
}
}
}
return errors;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hhcGUtdmFsaWRhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC12ZXN0LWZvcm1zL3NyYy9saWIvdXRpbHMvc2hhcGUtdmFsaWRhdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTFDOztHQUVHO0FBQ0gsTUFBTSxPQUFPLGtCQUFtQixTQUFRLEtBQUs7SUFDM0MsWUFBWSxTQUFtQjtRQUM3QixLQUFLLENBQUMsc0JBQXNCLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzFELENBQUM7Q0FDRjtBQUVEOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLFVBQVUsYUFBYSxDQUMzQixPQUE0QixFQUM1QixLQUEwQjtJQUUxQiwyQkFBMkI7SUFDM0IsSUFBSSxTQUFTLEVBQUUsRUFBRSxDQUFDO1FBQ2hCLE1BQU0sTUFBTSxHQUFHLGlCQUFpQixDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQztRQUNqRCxJQUFJLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNsQixNQUFNLElBQUksa0JBQWtCLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDdkMsQ0FBQztJQUNILENBQUM7QUFDSCxDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsU0FBUyxpQkFBaUIsQ0FDeEIsU0FBOEIsRUFDOUIsS0FBMEIsRUFDMUIsT0FBZSxFQUFFO0lBRWpCLE1BQU0sTUFBTSxHQUFhLEVBQUUsQ0FBQztJQUM1QixLQUFLLE1BQU0sR0FBRyxJQUFJLFNBQVMsRUFBRSxDQUFDO1FBQzVCLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN6Qyx3REFBd0Q7WUFDeEQsc0ZBQXNGO1lBQ3RGLG1GQUFtRjtZQUNuRixJQUFJLGdCQUFnQixHQUFHLEdBQUcsQ0FBQztZQUMzQixJQUFJLFVBQVUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDeEIsZ0JBQWdCLEdBQUcsR0FBRyxDQUFDO1lBQ3pCLENBQUM7WUFDRCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxJQUFJLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUM7WUFDOUMsSUFBSSxPQUFPLFNBQVMsQ0FBQyxHQUFHLENBQUMsS0FBSyxRQUFRLElBQUksU0FBUyxDQUFDLEdBQUcsQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDO2dCQUNsRSxJQUNFLENBQUMsT0FBTyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxRQUFRO29CQUMxQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxJQUFJLENBQUM7b0JBQ25DLEtBQUssQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsRUFDdEIsQ0FBQztvQkFDRCxNQUFNLENBQUMsSUFBSSxDQUFDLDZCQUE2QixPQUFPLEdBQUcsQ0FBQyxDQUFDO2dCQUN2RCxDQUFDO2dCQUNELE1BQU0sQ0FBQyxJQUFJLENBQ1QsR0FBRyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEVBQUUsS0FBSyxDQUFDLGdCQUFnQixDQUFDLEVBQUUsT0FBTyxDQUFDLENBQ3ZFLENBQUM7WUFDSixDQUFDO2lCQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLEtBQUssQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDO2dCQUN0RSxNQUFNLENBQUMsSUFBSSxDQUFDLHVCQUF1QixPQUFPLEdBQUcsQ0FBQyxDQUFDO1lBQ2pELENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUNELE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpc0Rldk1vZGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuLyoqXG4gKiBDbGVhbiBlcnJvciB0aGF0IGltcHJvdmVzIHRoZSBEWCB3aGVuIG1ha2luZyB0eXBvJ3MgaW4gdGhlIGBuYW1lYCBvciBgbmdNb2RlbEdyb3VwYCBhdHRyaWJ1dGVzXG4gKi9cbmV4cG9ydCBjbGFzcyBTaGFwZU1pc21hdGNoRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIGNvbnN0cnVjdG9yKGVycm9yTGlzdDogc3RyaW5nW10pIHtcbiAgICBzdXBlcihgU2hhcGUgbWlzbWF0Y2g6XFxuXFxuJHtlcnJvckxpc3Quam9pbignXFxuJyl9XFxuXFxuYCk7XG4gIH1cbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgYSBmb3JtIHZhbHVlIGFnYWluc3QgYSBzaGFwZVxuICogV2hlbiB0aGVyZSBpcyBzb21ldGhpbmcgaW4gdGhlIGZvcm0gdmFsdWUgdGhhdCBpcyBub3QgaW4gdGhlIHNoYXBlLCB0aHJvdyBhbiBlcnJvclxuICogVGhpcyBpcyBob3cgd2UgdGhyb3cgcnVudGltZSBlcnJvcnMgaW4gZGV2ZWxvcCB3aGVuIHRoZSBkZXZlbG9wZXIgaGFzIG1hZGUgYSB0eXBvIGluIHRoZSBgbmFtZWAgb3IgYG5nTW9kZWxHcm91cGBcbiAqIGF0dHJpYnV0ZXMuXG4gKiBAcGFyYW0gZm9ybVZhbFxuICogQHBhcmFtIHNoYXBlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZVNoYXBlKFxuICBmb3JtVmFsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICBzaGFwZTogUmVjb3JkPHN0cmluZywgYW55PlxuKTogdm9pZCB7XG4gIC8vIE9ubHkgZXhlY3V0ZSBpbiBkZXYgbW9kZVxuICBpZiAoaXNEZXZNb2RlKCkpIHtcbiAgICBjb25zdCBlcnJvcnMgPSB2YWxpZGF0ZUZvcm1WYWx1ZShmb3JtVmFsLCBzaGFwZSk7XG4gICAgaWYgKGVycm9ycy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBTaGFwZU1pc21hdGNoRXJyb3IoZXJyb3JzKTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgYSBmb3JtIHZhbHVlIGFnYWluc3QgYSBzaGFwZSB2YWx1ZSB0byBzZWUgaWYgaXQgbWF0Y2hlc1xuICogUmV0dXJucyBjbGVhbiBlcnJvcnMgdGhhdCBoYXZlIGEgZ29vZCBEWFxuICogQHBhcmFtIGZvcm1WYWx1ZVxuICogQHBhcmFtIHNoYXBlXG4gKiBAcGFyYW0gcGF0aFxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZUZvcm1WYWx1ZShcbiAgZm9ybVZhbHVlOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICBzaGFwZTogUmVjb3JkPHN0cmluZywgYW55PixcbiAgcGF0aDogc3RyaW5nID0gJydcbik6IHN0cmluZ1tdIHtcbiAgY29uc3QgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuICBmb3IgKGNvbnN0IGtleSBpbiBmb3JtVmFsdWUpIHtcbiAgICBpZiAoT2JqZWN0LmtleXMoZm9ybVZhbHVlKS5pbmNsdWRlcyhrZXkpKSB7XG4gICAgICAvLyBJbiBmb3JtIGFycmF5cyB3ZSBkb24ndCBrbm93IGhvdyBtYW55IGl0ZW1zIHRoZXJlIGFyZVxuICAgICAgLy8gVGhpcyBtZWFucyB0aGF0IHdlIGFsd2F5cyBuZWVkIHRvIHByb3ZpZGUgb25lIHJlY29yZCBpbiB0aGUgc2hhcGUgb2Ygb3VyIGZvcm0gYXJyYXlcbiAgICAgIC8vIHNvIGV2ZXJ5IHRpbWUgcmVzZXQgdGhlIGtleSB0byAnMCcgd2hlbiB0aGUga2V5IGlzIGEgbnVtYmVyIGFuZCBpcyBiaWdnZXIgdGhhbiAwXG4gICAgICBsZXQga2V5VG9Db21wYXJlV2l0aCA9IGtleTtcbiAgICAgIGlmIChwYXJzZUZsb2F0KGtleSkgPiAwKSB7XG4gICAgICAgIGtleVRvQ29tcGFyZVdpdGggPSAnMCc7XG4gICAgICB9XG4gICAgICBjb25zdCBuZXdQYXRoID0gcGF0aCA/IGAke3BhdGh9LiR7a2V5fWAgOiBrZXk7XG4gICAgICBpZiAodHlwZW9mIGZvcm1WYWx1ZVtrZXldID09PSAnb2JqZWN0JyAmJiBmb3JtVmFsdWVba2V5XSAhPT0gbnVsbCkge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgKHR5cGVvZiBzaGFwZVtrZXlUb0NvbXBhcmVXaXRoXSAhPT0gJ29iamVjdCcgfHxcbiAgICAgICAgICAgIHNoYXBlW2tleVRvQ29tcGFyZVdpdGhdID09PSBudWxsKSAmJlxuICAgICAgICAgIGlzTmFOKHBhcnNlRmxvYXQoa2V5KSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgZXJyb3JzLnB1c2goYFtuZ01vZGVsR3JvdXBdIE1pc21hdGNoOiAnJHtuZXdQYXRofSdgKTtcbiAgICAgICAgfVxuICAgICAgICBlcnJvcnMucHVzaChcbiAgICAgICAgICAuLi52YWxpZGF0ZUZvcm1WYWx1ZShmb3JtVmFsdWVba2V5XSwgc2hhcGVba2V5VG9Db21wYXJlV2l0aF0sIG5ld1BhdGgpXG4gICAgICAgICk7XG4gICAgICB9IGVsc2UgaWYgKChzaGFwZSA/ICEoa2V5IGluIHNoYXBlKSA6IHRydWUpICYmIGlzTmFOKHBhcnNlRmxvYXQoa2V5KSkpIHtcbiAgICAgICAgZXJyb3JzLnB1c2goYFtuZ01vZGVsXSBNaXNtYXRjaCAnJHtuZXdQYXRofSdgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIGVycm9ycztcbn1cbiJdfQ==