diff --git a/.gitignore b/.gitignore index 80915d9..47c913b 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ .vscode coverage +dist/ node_modules *.sublime-project diff --git a/dist/formulario.esm.js b/dist/formulario.esm.js deleted file mode 100644 index d5304b8..0000000 --- a/dist/formulario.esm.js +++ /dev/null @@ -1,1485 +0,0 @@ -import isUrl from 'is-url'; -import Vue from 'vue'; -import { Inject, Model, Prop, Watch, Component, Provide } from 'vue-property-decorator'; - -const registry = new Map(); -var id = (prefix) => { - const current = registry.get(prefix) || 0; - const next = current + 1; - registry.set(prefix, next); - return `${prefix}-${next}`; -}; - -var TYPE; -(function (TYPE) { - TYPE["ARRAY"] = "ARRAY"; - TYPE["BIGINT"] = "BIGINT"; - TYPE["BOOLEAN"] = "BOOLEAN"; - TYPE["DATE"] = "DATE"; - TYPE["FUNCTION"] = "FUNCTION"; - TYPE["NUMBER"] = "NUMBER"; - TYPE["RECORD"] = "RECORD"; - TYPE["STRING"] = "STRING"; - TYPE["SYMBOL"] = "SYMBOL"; - TYPE["UNDEFINED"] = "UNDEFINED"; - TYPE["NULL"] = "NULL"; -})(TYPE || (TYPE = {})); -const constructorOf = (value) => { - return Object.getPrototypeOf(value).constructor; -}; -function isRecord(value) { - return constructorOf(value) === Object && Object.keys(Object.getPrototypeOf(value)).length === 0; -} -function isRecordLike(value) { - return typeof value === 'object' && value !== null && (isRecord(value) || Array.isArray(value)); -} -function typeOf(value) { - switch (typeof value) { - case 'bigint': - return TYPE.BIGINT; - case 'boolean': - return TYPE.BOOLEAN; - case 'function': - return TYPE.FUNCTION; - case 'number': - return TYPE.NUMBER; - case 'string': - return TYPE.STRING; - case 'symbol': - return TYPE.SYMBOL; - case 'undefined': - return TYPE.UNDEFINED; - case 'object': - if (value === null) { - return TYPE.NULL; - } - if (value instanceof Date) { - return TYPE.DATE; - } - if (Array.isArray(value)) { - return TYPE.ARRAY; - } - if (isRecord(value)) { - return TYPE.RECORD; - } - return 'InstanceOf<' + constructorOf(value).name + '>'; - } - throw new Error('[Formulario] typeOf - unknown type detected'); -} -function isScalar(value) { - switch (typeof value) { - case 'bigint': - case 'boolean': - case 'number': - case 'string': - case 'symbol': - case 'undefined': - return true; - default: - return value === null; - } -} - -const cloneInstance = (original) => { - return Object.assign(Object.create(Object.getPrototypeOf(original)), original); -}; -/** - * A simple (somewhat non-comprehensive) clone function, valid for our use - * case of needing to unbind reactive watchers. - */ -function clone(value) { - // scalars & immutables - if (isScalar(value) || value instanceof Blob) { - return value; - } - if (value instanceof Date) { - return new Date(value); - } - if (!isRecordLike(value)) { - return cloneInstance(value); - } - if (Array.isArray(value)) { - return value.slice().map(clone); - } - const source = value; - return Object.keys(source).reduce((copy, key) => (Object.assign(Object.assign({}, copy), { [key]: clone(source[key]) })), {}); -} - -/** - * Shorthand for Object.prototype.hasOwnProperty.call (space saving) - */ -function has(ctx, prop) { - return Object.prototype.hasOwnProperty.call(ctx, prop); -} - -/*! ***************************************************************************** -Copyright (c) Microsoft Corporation. - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. -***************************************************************************** */ - -function __rest(s, e) { - var t = {}; - for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) - t[p] = s[p]; - if (s != null && typeof Object.getOwnPropertySymbols === "function") - for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { - if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) - t[p[i]] = s[p[i]]; - } - return t; -} - -function __decorate(decorators, target, key, desc) { - var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); - else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; -} - -const extractIntOrNaN = (value) => { - const numeric = parseInt(value); - return numeric.toString() === value ? numeric : NaN; -}; -const extractPath = (raw) => { - const path = []; - raw.split('.').forEach(key => { - if (/(.*)\[(\d+)]$/.test(key)) { - path.push(...key.substr(0, key.length - 1).split('[').filter(k => k.length)); - } - else { - path.push(key); - } - }); - return path; -}; -function get(state, rawOrPath, fallback = undefined) { - const path = typeof rawOrPath === 'string' ? extractPath(rawOrPath) : rawOrPath; - if (isScalar(state) || path.length === 0) { - return fallback; - } - const key = path.shift(); - const index = extractIntOrNaN(key); - if (!isNaN(index)) { - if (Array.isArray(state) && index >= 0 && index < state.length) { - return path.length === 0 ? state[index] : get(state[index], path, fallback); - } - return undefined; - } - if (has(state, key)) { - const values = state; - return path.length === 0 ? values[key] : get(values[key], path, fallback); - } - return undefined; -} -function set(state, rawOrPath, value) { - const path = typeof rawOrPath === 'string' ? extractPath(rawOrPath) : rawOrPath; - if (path.length === 0) { - return value; - } - const key = path.shift(); - const index = extractIntOrNaN(key); - if (!isRecordLike(state)) { - return set(!isNaN(index) ? [] : {}, [key, ...path], value); - } - if (!isNaN(index) && Array.isArray(state)) { - const slice = [...state]; - slice[index] = path.length === 0 ? value : set(slice[index], path, value); - return slice; - } - const slice = Object.assign({}, state); - slice[key] = path.length === 0 ? value : set(slice[key], path, value); - return slice; -} -const unsetInRecord = (record, prop) => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const _a = record, _b = prop, _ = _a[_b], copy = __rest(_a, [typeof _b === "symbol" ? _b : _b + ""]); - return copy; -}; -function unset(state, rawOrPath) { - if (!isRecordLike(state)) { - return state; - } - const path = typeof rawOrPath === 'string' ? extractPath(rawOrPath) : rawOrPath; - if (path.length === 0) { - return state; - } - const key = path.shift(); - const index = extractIntOrNaN(key); - if (!isNaN(index) && Array.isArray(state) && index >= 0 && index < state.length) { - const slice = [...state]; - if (path.length === 0) { - slice.splice(index, 1); - } - else { - slice[index] = unset(slice[index], path); - } - return slice; - } - if (has(state, key)) { - const slice = Object.assign({}, state); - return path.length === 0 - ? unsetInRecord(slice, key) - : Object.assign(Object.assign({}, slice), { [key]: unset(slice[key], path) }); - } - return state; -} - -/** - * Escape a string for use in regular expressions. - */ -function escapeRegExp(string) { - return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string -} -/** - * Given a string format (date) return a regex to match against. - */ -function regexForFormat(format) { - const escaped = `^${escapeRegExp(format)}$`; - const formats = { - MM: '(0[1-9]|1[012])', - M: '([1-9]|1[012])', - DD: '([012][1-9]|3[01])', - D: '([012]?[1-9]|3[01])', - YYYY: '\\d{4}', - YY: '\\d{2}' - }; - return new RegExp(Object.keys(formats).reduce((regex, format) => { - return regex.replace(format, formats[format]); - }, escaped)); -} - -function datesEquals(a, b) { - return a.getTime() === b.getTime(); -} -function arraysEquals(a, b, predicate) { - if (a.length !== b.length) { - return false; - } - for (let i = 0; i < a.length; i++) { - if (!predicate(a[i], b[i])) { - return false; - } - } - return true; -} -function recordsEquals(a, b, predicate) { - if (Object.keys(a).length !== Object.keys(b).length) { - return false; - } - for (const prop in a) { - if (!has(b, prop) || !predicate(a[prop], b[prop])) { - return false; - } - } - return true; -} -function strictEquals(a, b) { - return a === b; -} -function equals(a, b, predicate) { - const typeOfA = typeOf(a); - const typeOfB = typeOf(b); - return typeOfA === typeOfB && ((typeOfA === TYPE.ARRAY && arraysEquals(a, b, predicate)) || - (typeOfA === TYPE.DATE && datesEquals(a, b)) || - (typeOfA === TYPE.RECORD && recordsEquals(a, b, predicate)) || - (typeOfA.includes('InstanceOf') && equals(Object.entries(a), Object.entries(b), predicate))); -} -function deepEquals(a, b) { - return a === b || equals(a, b, deepEquals); -} -function shallowEquals(a, b) { - return a === b || equals(a, b, strictEquals); -} - -/** - * Given a string, convert snake_case to camelCase - */ -function snakeToCamel(string) { - return string.replace(/([_][a-z0-9])/ig, ($1) => { - if (string.indexOf($1) !== 0 && string[string.indexOf($1) - 1] !== '_') { - return $1.toUpperCase().replace('_', ''); - } - return $1; - }); -} - -const rules = { - /** - * Rule: the value must be "yes", "on", "1", or true - */ - accepted({ value }) { - return ['yes', 'on', '1', 1, true, 'true'].includes(value); - }, - /** - * Rule: checks if a value is after a given date. Defaults to current time - */ - after({ value }, compare = false) { - const compareTimestamp = compare !== false ? Date.parse(compare) : Date.now(); - const valueTimestamp = value instanceof Date ? value.getTime() : Date.parse(value); - return isNaN(valueTimestamp) ? false : (valueTimestamp > compareTimestamp); - }, - /** - * Rule: checks if the value is only alpha - */ - alpha({ value }, set = 'default') { - const sets = { - default: /^[a-zA-ZÀ-ÖØ-öø-ÿ]+$/, - latin: /^[a-zA-Z]+$/, - }; - return typeof value === 'string' && sets[has(sets, set) ? set : 'default'].test(value); - }, - /** - * Rule: checks if the value is alpha numeric - */ - alphanumeric({ value }, set = 'default') { - const sets = { - default: /^[a-zA-Z0-9À-ÖØ-öø-ÿ]+$/, - latin: /^[a-zA-Z0-9]+$/ - }; - return typeof value === 'string' && sets[has(sets, set) ? set : 'default'].test(value); - }, - /** - * Rule: checks if a value is after a given date. Defaults to current time - */ - before({ value }, compare = false) { - const compareTimestamp = compare !== false ? Date.parse(compare) : Date.now(); - const valueTimestamp = value instanceof Date ? value.getTime() : Date.parse(value); - return isNaN(valueTimestamp) ? false : (valueTimestamp < compareTimestamp); - }, - /** - * Rule: checks if the value is between two other values - */ - between({ value }, from = 0, to = 10, force) { - if (from === null || to === null || isNaN(from) || isNaN(to)) { - return false; - } - if ((!isNaN(Number(value)) && force !== 'length') || force === 'value') { - value = Number(value); - return (value > Number(from) && value < Number(to)); - } - if (typeof value === 'string' || force === 'length') { - value = (!isNaN(Number(value)) ? value.toString() : value); - return value.length > from && value.length < to; - } - return false; - }, - /** - * Confirm that the value of one field is the same as another, mostly used - * for password confirmations. - */ - confirm({ value, formValues, name }, field) { - let confirmationFieldName = field; - if (!confirmationFieldName) { - confirmationFieldName = /_confirm$/.test(name) ? name.substr(0, name.length - 8) : `${name}_confirm`; - } - return formValues[confirmationFieldName] === value; - }, - /** - * Rule: ensures the value is a date according to Date.parse(), or a format - * regex. - */ - date({ value }, format = false) { - return format ? regexForFormat(format).test(value) : !isNaN(Date.parse(value)); - }, - /** - * Rule: tests - */ - email({ value }) { - if (!value) { - return true; - } - // eslint-disable-next-line - const isEmail = /^(([^<>()\[\].,;:\s@"]+(\.[^<>()\[\].,;:\s@"]+)*)|(".+"))@(([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{2,})$/i; - return isEmail.test(value); - }, - /** - * Rule: Value ends with one of the given Strings - */ - endsWith({ value }, ...stack) { - if (!value) { - return true; - } - if (typeof value === 'string') { - return stack.length === 0 || stack.some(str => value.endsWith(str)); - } - return false; - }, - /** - * Rule: Value is in an array (stack). - */ - in({ value }, ...stack) { - return stack.some(item => shallowEquals(item, value)); - }, - /** - * Rule: Match the value against a (stack) of patterns or strings - */ - matches({ value }, ...stack) { - return !!stack.find(pattern => { - if (typeof pattern === 'string' && pattern.substr(0, 1) === '/' && pattern.substr(-1) === '/') { - pattern = new RegExp(pattern.substr(1, pattern.length - 2)); - } - if (pattern instanceof RegExp) { - return pattern.test(value); - } - return pattern === value; - }); - }, - /** - * Check the maximum value of a particular. - */ - max({ value }, maximum = 10, force) { - if (Array.isArray(value)) { - maximum = !isNaN(Number(maximum)) ? Number(maximum) : maximum; - return value.length <= maximum; - } - if ((!isNaN(value) && force !== 'length') || force === 'value') { - value = !isNaN(value) ? Number(value) : value; - return value <= maximum; - } - if (typeof value === 'string' || (force === 'length')) { - value = !isNaN(value) ? String(value) : value; - return value.length <= maximum; - } - return false; - }, - /** - * Check the minimum value of a particular. - */ - min({ value }, minimum = 1, force) { - if (Array.isArray(value)) { - minimum = !isNaN(minimum) ? Number(minimum) : minimum; - return value.length >= minimum; - } - if ((!isNaN(value) && force !== 'length') || force === 'value') { - value = !isNaN(value) ? Number(value) : value; - return value >= minimum; - } - if (typeof value === 'string' || (force === 'length')) { - value = !isNaN(value) ? String(value) : value; - return value.length >= minimum; - } - return false; - }, - /** - * Rule: Value is not in stack. - */ - not({ value }, ...stack) { - return !stack.some(item => shallowEquals(item, value)); - }, - /** - * Rule: checks if the value is only alpha numeric - */ - number({ value }) { - return String(value).length > 0 && !isNaN(Number(value)); - }, - /** - * Rule: must be a value - */ - required({ value }, isRequired = true) { - if (!isRequired || ['no', 'false'].includes(isRequired)) { - return true; - } - if (Array.isArray(value)) { - return !!value.length; - } - if (typeof value === 'string') { - return !!value; - } - if (typeof value === 'object') { - return (!value) ? false : !!Object.keys(value).length; - } - return true; - }, - /** - * Rule: Value starts with one of the given Strings - */ - startsWith({ value }, ...stack) { - if (!value) { - return true; - } - if (typeof value === 'string') { - return stack.length === 0 || stack.some(str => value.startsWith(str)); - } - return false; - }, - /** - * Rule: checks if a string is a valid url - */ - url({ value }) { - if (!value) { - return true; - } - return isUrl(value); - }, - /** - * Rule: not a true rule — more like a compiler flag. - */ - bail() { - return true; - }, -}; - -/** - * Message builders, names match rules names, see @/validation/rules - */ -const messages = { - /** - * Fallback for rules without message builder - * @param vm - * @param context - */ - default(vm, context) { - return vm.$t('validation.default', context); - }, - accepted(vm, context) { - return vm.$t('validation.accepted', context); - }, - after(vm, context, compare = false) { - if (typeof compare === 'string' && compare.length) { - return vm.$t('validation.after.compare', context); - } - return vm.$t('validation.after.default', context); - }, - alpha(vm, context) { - return vm.$t('validation.alpha', context); - }, - alphanumeric(vm, context) { - return vm.$t('validation.alphanumeric', context); - }, - before(vm, context, compare = false) { - if (typeof compare === 'string' && compare.length) { - return vm.$t('validation.before.compare', context); - } - return vm.$t('validation.before.default', context); - }, - between(vm, context, from = 0, to = 10, force) { - const data = Object.assign(Object.assign({}, context), { from, to }); - if ((!isNaN(context.value) && force !== 'length') || force === 'value') { - return vm.$t('validation.between.force', data); - } - return vm.$t('validation.between.default', data); - }, - confirm(vm, context) { - return vm.$t('validation.confirm', context); - }, - date(vm, context, format = false) { - if (typeof format === 'string' && format.length) { - return vm.$t('validation.date.format', context); - } - return vm.$t('validation.date.default', context); - }, - email(vm, context) { - return vm.$t('validation.email.default', context); - }, - endsWith(vm, context) { - return vm.$t('validation.endsWith.default', context); - }, - in(vm, context) { - if (typeof context.value === 'string' && context.value) { - return vm.$t('validation.in.string', context); - } - return vm.$t('validation.in.default', context); - }, - matches(vm, context) { - return vm.$t('validation.matches.default', context); - }, - max(vm, context, maximum = 10, force) { - if (Array.isArray(context.value)) { - return vm.$tc('validation.max.array', maximum, context); - } - if ((!isNaN(context.value) && force !== 'length') || force === 'value') { - return vm.$tc('validation.max.force', maximum, context); - } - return vm.$tc('validation.max.default', maximum, context); - }, - min(vm, context, minimum = 1, force) { - if (Array.isArray(context.value)) { - return vm.$tc('validation.min.array', minimum, context); - } - if ((!isNaN(context.value) && force !== 'length') || force === 'value') { - return vm.$tc('validation.min.force', minimum, context); - } - return vm.$tc('validation.min.default', minimum, context); - }, - not(vm, context) { - return vm.$t('validation.not.default', context); - }, - number(vm, context) { - return vm.$t('validation.number.default', context); - }, - required(vm, context) { - return vm.$t('validation.required.default', context); - }, - startsWith(vm, context) { - return vm.$t('validation.startsWith.default', context); - }, - url(vm, context) { - return vm.$t('validation.url.default', context); - } -}; - -class Formulario { - constructor(options) { - this.validationRules = {}; - this.validationMessages = {}; - this._registry = new Map(); - this.validationRules = rules; - this.validationMessages = messages; - this.extend(options || {}); - } - /** - * Given a set of options, apply them to the pre-existing options. - */ - extend(extendWith) { - if (typeof extendWith === 'object') { - this.validationRules = Object.assign(Object.assign({}, this.validationRules), (extendWith.validationRules || {})); - this.validationMessages = Object.assign(Object.assign({}, this.validationMessages), (extendWith.validationMessages || {})); - return this; - } - throw new Error(`[Formulario]: Formulario.extend(): should be passed an object (was ${typeof extendWith})`); - } - runValidation(id) { - if (!this._registry.has(id)) { - throw new Error(`[Formulario]: Formulario.runValidation(): no forms with id "${id}"`); - } - const form = this._registry.get(id); - return form.runValidation(); - } - resetValidation(id) { - if (!this._registry.has(id)) { - return; - } - const form = this._registry.get(id); - form.resetValidation(); - } - /** - * Used by forms instances to add themselves into a registry - * @internal - */ - register(id, form) { - if (this._registry.has(id)) { - throw new Error(`[Formulario]: Formulario.register(): id "${id}" is already in use`); - } - this._registry.set(id, form); - } - /** - * Used by forms instances to remove themselves from a registry - * @internal - */ - unregister(id) { - if (this._registry.has(id)) { - this._registry.delete(id); - } - } - /** - * Get validation rules by merging any passed in with global rules. - * @internal - */ - getRules(extendWith = {}) { - return Object.assign(Object.assign({}, this.validationRules), extendWith); - } - /** - * Get validation messages by merging any passed in with global messages. - * @internal - */ - getMessages(vm, extendWith) { - const raw = Object.assign(Object.assign({}, this.validationMessages), extendWith); - const messages = {}; - for (const name in raw) { - messages[name] = (context, ...args) => { - const fn = raw[name]; - return typeof fn === 'string' ? fn : fn(vm, context, ...args); - }; - } - return messages; - } -} - -function createValidator(ruleFn, ruleName, ruleArgs, messageFn) { - return (context) => { - return Promise.resolve(ruleFn(context, ...ruleArgs)).then(valid => { - return !valid ? { - rule: ruleName, - args: ruleArgs, - context, - message: messageFn(context, ...ruleArgs), - } : null; - }); - }; -} -function parseModifier(ruleName) { - if (/^[\^]/.test(ruleName.charAt(0))) { - return [snakeToCamel(ruleName.substr(1)), ruleName.charAt(0)]; - } - return [snakeToCamel(ruleName), null]; -} -function processSingleArrayConstraint(constraint, rules, messages) { - const args = constraint.slice(); - const first = args.shift(); - if (typeof first === 'function') { - return [first, null, null]; - } - if (typeof first !== 'string') { - throw new Error('[Formulario]: For array constraint first element must be rule name or Validator function'); - } - const [name, modifier] = parseModifier(first); - if (has(rules, name)) { - return [ - createValidator(rules[name], name, args, messages[name] || messages.default), - name, - modifier, - ]; - } - throw new Error(`[Formulario] Can't create validator for constraint: ${JSON.stringify(constraint)}`); -} -function processSingleStringConstraint(constraint, rules, messages) { - const args = constraint.split(':'); - const [name, modifier] = parseModifier(args.shift() || ''); - if (has(rules, name)) { - return [ - createValidator(rules[name], name, args.length ? args.join(':').split(',') : [], messages[name] || messages.default), - name, - modifier, - ]; - } - throw new Error(`[Formulario] Can't create validator for constraint: ${constraint}`); -} -function processSingleConstraint(constraint, rules, messages) { - if (typeof constraint === 'function') { - return [constraint, null, null]; - } - if (Array.isArray(constraint) && constraint.length) { - return processSingleArrayConstraint(constraint, rules, messages); - } - if (typeof constraint === 'string') { - return processSingleStringConstraint(constraint, rules, messages); - } - return [() => Promise.resolve(null), null, null]; -} -function processConstraints(constraints, rules, messages) { - if (typeof constraints === 'string') { - return processConstraints(constraints.split('|').filter(f => f.length), rules, messages); - } - if (!Array.isArray(constraints)) { - return []; - } - return constraints.map(constraint => processSingleConstraint(constraint, rules, messages)); -} -function enlarge(groups) { - const enlarged = []; - if (groups.length) { - let current = groups.shift(); - enlarged.push(current); - groups.forEach((group) => { - if (!group.bail && group.bail === current.bail) { - current.validators.push(...group.validators); - } - else { - current = Object.assign({}, group); - enlarged.push(current); - } - }); - } - return enlarged; -} -/** - * Given an array of rules, group them by bail signals. For example for this: - * bail|required|min:10|max:20 - * we would expect: - * [[required], [min], [max]] - * because any sub-array failure would cause a shutdown. While - * ^required|min:10|max:10 - * would return: - * [[required], [min, max]] - * and no bailing would produce: - * [[required, min, max]] - * @param {array} rules - */ -function createValidatorGroups(rules) { - const mapper = ([validator, /** name */ , modifier]) => ({ - validators: [validator], - bail: modifier === '^', - }); - const groups = []; - const bailIndex = rules.findIndex(([, name]) => name && name.toLowerCase() === 'bail'); - if (bailIndex >= 0) { - groups.push(...enlarge(rules.splice(0, bailIndex + 1).slice(0, -1).map(mapper))); - groups.push(...rules.map(([validator]) => ({ - validators: [validator], - bail: true, - }))); - } - else { - groups.push(...enlarge(rules.map(mapper))); - } - return groups; -} -function validateByGroup(group, context) { - return Promise.all(group.validators.map(validate => validate(context))) - .then(violations => violations.filter(v => v !== null)); -} -function validate(validators, context) { - return new Promise(resolve => { - const resolveGroups = (groups, all = []) => { - if (groups.length) { - const current = groups.shift(); - validateByGroup(current, context).then(violations => { - // The rule passed or its a non-bailing group, and there are additional groups to check, continue - if ((violations.length === 0 || !current.bail) && groups.length) { - return resolveGroups(groups, all.concat(violations)); - } - return resolve(all.concat(violations)); - }); - } - else { - resolve([]); - } - }; - resolveGroups(createValidatorGroups(validators)); - }); -} - -let FormularioField = class FormularioField extends Vue { - constructor() { - super(...arguments); - this.proxy = this.hasModel ? this.value : ''; - this.localErrors = []; - this.violations = []; - this.validationRun = Promise.resolve([]); - } - get fullPath() { - return this.__Formulario_path !== '' ? `${this.__Formulario_path}.${this.name}` : this.name; - } - /** Determines if this formulario element is v-modeled or not. */ - get hasModel() { - return has(this.$options.propsData || {}, 'value'); - } - get context() { - return Object.defineProperty({ - name: this.fullPath, - path: this.fullPath, - runValidation: this.runValidation.bind(this), - violations: this.violations, - errors: this.localErrors, - allErrors: [...this.localErrors, ...this.violations.map(v => v.message)], - }, 'model', { - get: () => this.modelGetConverter(this.proxy), - set: (value) => { - this._syncProxy(this.modelSetConverter(value, this.proxy)); - }, - }); - } - get _normalizedValidationRules() { - const rules = {}; - Object.keys(this.validationRules).forEach(key => { - rules[snakeToCamel(key)] = this.validationRules[key]; - }); - return rules; - } - get _normalizedValidationMessages() { - const messages = {}; - Object.keys(this.validationMessages).forEach(key => { - messages[snakeToCamel(key)] = this.validationMessages[key]; - }); - return messages; - } - _onValueChange() { - this._syncProxy(this.value); - } - _onProxyChange() { - if (this.validationBehavior === 'live') { - this.runValidation(); - } - else { - this.resetValidation(); - } - } - /** @internal */ - created() { - if (typeof this.__FormularioForm_register === 'function') { - this.__FormularioForm_register(this.fullPath, this); - } - if (this.validationBehavior === 'live') { - this.runValidation(); - } - } - /** @internal */ - beforeDestroy() { - if (typeof this.__FormularioForm_unregister === 'function') { - this.__FormularioForm_unregister(this.fullPath, this.unregisterBehavior); - } - } - runValidation() { - this.validationRun = this._validate().then(violations => { - this.violations = violations; - this._emitValidation(this.fullPath, violations); - return this.violations; - }); - return this.validationRun; - } - hasValidationErrors() { - return new Promise(resolve => { - this.$nextTick(() => { - this.validationRun.then(() => resolve(this.violations.length > 0)); - }); - }); - } - /** @internal */ - setErrors(errors) { - if (!this.errorsDisabled) { - this.localErrors = errors; - } - } - /** @internal */ - resetValidation() { - this.localErrors = []; - this.violations = []; - } - _syncProxy(value) { - if (!deepEquals(value, this.proxy)) { - this.proxy = value; - this.$emit('input', value); - if (typeof this.__FormularioForm_set === 'function') { - this.__FormularioForm_set(this.fullPath, value); - this.__FormularioForm_emitInput(); - } - } - } - _validate() { - return validate(processConstraints(this.validation, this.$formulario.getRules(this._normalizedValidationRules), this.$formulario.getMessages(this, this._normalizedValidationMessages)), { - value: this.proxy, - name: this.fullPath, - formValues: this.__FormularioForm_getState(), - }); - } - _emitValidation(path, violations) { - this.$emit('validation', { path, violations }); - if (typeof this.__FormularioForm_emitValidation === 'function') { - this.__FormularioForm_emitValidation(path, violations); - } - } -}; -__decorate([ - Inject({ default: '' }) -], FormularioField.prototype, "__Formulario_path", void 0); -__decorate([ - Inject({ default: undefined }) -], FormularioField.prototype, "__FormularioForm_set", void 0); -__decorate([ - Inject({ default: () => () => { } }) -], FormularioField.prototype, "__FormularioForm_emitInput", void 0); -__decorate([ - Inject({ default: () => () => { } }) -], FormularioField.prototype, "__FormularioForm_emitValidation", void 0); -__decorate([ - Inject({ default: undefined }) -], FormularioField.prototype, "__FormularioForm_register", void 0); -__decorate([ - Inject({ default: undefined }) -], FormularioField.prototype, "__FormularioForm_unregister", void 0); -__decorate([ - Inject({ default: () => () => ({}) }) -], FormularioField.prototype, "__FormularioForm_getState", void 0); -__decorate([ - Model('input', { default: '' }) -], FormularioField.prototype, "value", void 0); -__decorate([ - Prop({ - required: true, - validator: (name) => typeof name === 'string' && name.length > 0, - }) -], FormularioField.prototype, "name", void 0); -__decorate([ - Prop({ default: '' }) -], FormularioField.prototype, "validation", void 0); -__decorate([ - Prop({ default: () => ({}) }) -], FormularioField.prototype, "validationRules", void 0); -__decorate([ - Prop({ default: () => ({}) }) -], FormularioField.prototype, "validationMessages", void 0); -__decorate([ - Prop({ - default: 'demand', - validator: (behavior) => ['demand', 'live', 'submit'].includes(behavior) - }) -], FormularioField.prototype, "validationBehavior", void 0); -__decorate([ - Prop({ default: false }) -], FormularioField.prototype, "errorsDisabled", void 0); -__decorate([ - Prop({ default: () => (value) => value }) -], FormularioField.prototype, "modelGetConverter", void 0); -__decorate([ - Prop({ default: () => (value) => value }) -], FormularioField.prototype, "modelSetConverter", void 0); -__decorate([ - Prop({ default: 'div' }) -], FormularioField.prototype, "tag", void 0); -__decorate([ - Prop({ default: 'none' }) -], FormularioField.prototype, "unregisterBehavior", void 0); -__decorate([ - Watch('value') -], FormularioField.prototype, "_onValueChange", null); -__decorate([ - Watch('proxy') -], FormularioField.prototype, "_onProxyChange", null); -FormularioField = __decorate([ - Component({ name: 'FormularioField', inheritAttrs: false }) -], FormularioField); -var script = FormularioField; - -function normalizeComponent(template, style, script, scopeId, isFunctionalTemplate, moduleIdentifier /* server only */, shadowMode, createInjector, createInjectorSSR, createInjectorShadow) { - if (typeof shadowMode !== 'boolean') { - createInjectorSSR = createInjector; - createInjector = shadowMode; - shadowMode = false; - } - // Vue.extend constructor export interop. - const options = typeof script === 'function' ? script.options : script; - // render functions - if (template && template.render) { - options.render = template.render; - options.staticRenderFns = template.staticRenderFns; - options._compiled = true; - // functional template - if (isFunctionalTemplate) { - options.functional = true; - } - } - // scopedId - if (scopeId) { - options._scopeId = scopeId; - } - let hook; - if (moduleIdentifier) { - // server build - hook = function (context) { - // 2.3 injection - context = - context || // cached call - (this.$vnode && this.$vnode.ssrContext) || // stateful - (this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext); // functional - // 2.2 with runInNewContext: true - if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') { - context = __VUE_SSR_CONTEXT__; - } - // inject component styles - if (style) { - style.call(this, createInjectorSSR(context)); - } - // register component module identifier for async chunk inference - if (context && context._registeredComponents) { - context._registeredComponents.add(moduleIdentifier); - } - }; - // used by ssr in case component is cached and beforeCreate - // never gets called - options._ssrRegister = hook; - } - else if (style) { - hook = shadowMode - ? function (context) { - style.call(this, createInjectorShadow(context, this.$root.$options.shadowRoot)); - } - : function (context) { - style.call(this, createInjector(context)); - }; - } - if (hook) { - if (options.functional) { - // register for functional component in vue file - const originalRender = options.render; - options.render = function renderWithStyleInjection(h, context) { - hook.call(context); - return originalRender(h, context); - }; - } - else { - // inject component registration as beforeCreate hook - const existing = options.beforeCreate; - options.beforeCreate = existing ? [].concat(existing, hook) : [hook]; - } - } - return script; -} - -/* script */ -const __vue_script__ = script; - -/* template */ -var __vue_render__ = function() { - var _vm = this; - var _h = _vm.$createElement; - var _c = _vm._self._c || _h; - return _c( - _vm.tag, - _vm._b({ tag: "component" }, "component", _vm.$attrs, false), - [_vm._t("default", null, { context: _vm.context })], - 2 - ) -}; -var __vue_staticRenderFns__ = []; -__vue_render__._withStripped = true; - - /* style */ - const __vue_inject_styles__ = undefined; - /* scoped */ - const __vue_scope_id__ = undefined; - /* module identifier */ - const __vue_module_identifier__ = undefined; - /* functional template */ - const __vue_is_functional_template__ = false; - /* style inject */ - - /* style inject SSR */ - - /* style inject shadow dom */ - - - - const __vue_component__ = /*#__PURE__*/normalizeComponent( - { render: __vue_render__, staticRenderFns: __vue_staticRenderFns__ }, - __vue_inject_styles__, - __vue_script__, - __vue_scope_id__, - __vue_is_functional_template__, - __vue_module_identifier__, - false, - undefined, - undefined, - undefined - ); - -let FormularioFieldGroup = class FormularioFieldGroup extends Vue { - get fullPath() { - const path = `${this.name}`; - if (parseInt(path).toString() === path) { - return `${this.__Formulario_path}[${path}]`; - } - if (this.__Formulario_path === '') { - return path; - } - return `${this.__Formulario_path}.${path}`; - } -}; -__decorate([ - Inject({ default: '' }) -], FormularioFieldGroup.prototype, "__Formulario_path", void 0); -__decorate([ - Prop({ required: true }) -], FormularioFieldGroup.prototype, "name", void 0); -__decorate([ - Provide('__Formulario_path') -], FormularioFieldGroup.prototype, "fullPath", null); -FormularioFieldGroup = __decorate([ - Component({ name: 'FormularioFieldGroup' }) -], FormularioFieldGroup); -var script$1 = FormularioFieldGroup; - -/* script */ -const __vue_script__$1 = script$1; - -/* template */ -var __vue_render__$1 = function() { - var _vm = this; - var _h = _vm.$createElement; - var _c = _vm._self._c || _h; - return _c("div", [_vm._t("default")], 2) -}; -var __vue_staticRenderFns__$1 = []; -__vue_render__$1._withStripped = true; - - /* style */ - const __vue_inject_styles__$1 = undefined; - /* scoped */ - const __vue_scope_id__$1 = undefined; - /* module identifier */ - const __vue_module_identifier__$1 = undefined; - /* functional template */ - const __vue_is_functional_template__$1 = false; - /* style inject */ - - /* style inject SSR */ - - /* style inject shadow dom */ - - - - const __vue_component__$1 = /*#__PURE__*/normalizeComponent( - { render: __vue_render__$1, staticRenderFns: __vue_staticRenderFns__$1 }, - __vue_inject_styles__$1, - __vue_script__$1, - __vue_scope_id__$1, - __vue_is_functional_template__$1, - __vue_module_identifier__$1, - false, - undefined, - undefined, - undefined - ); - -const update = (state, path, value) => { - if (value === undefined) { - return unset(state, path); - } - return set(state, path, value); -}; -let FormularioForm = class FormularioForm extends Vue { - constructor() { - super(...arguments); - this.proxy = {}; - this.registry = new Map(); - // Local error messages are temporal, they wiped each resetValidation call - this.localFieldsErrors = {}; - this.localFormErrors = []; - } - get fieldsErrorsComputed() { - return Object.assign(Object.assign({}, this.fieldsErrors), this.localFieldsErrors); - } - get formErrorsComputed() { - return [...this.formErrors, ...this.localFormErrors]; - } - register(path, field) { - if (!this.registry.has(path)) { - this.registry.set(path, field); - } - const value = get(this.proxy, path); - if (!field.hasModel) { - if (value !== undefined) { - field.proxy = value; - } - else { - this.setFieldValue(path, null); - this.emitInput(); - } - } - else if (!deepEquals(field.proxy, value)) { - this.setFieldValue(path, field.proxy); - this.emitInput(); - } - if (has(this.fieldsErrorsComputed, path)) { - field.setErrors(this.fieldsErrorsComputed[path]); - } - } - unregister(path, behavior) { - if (this.registry.has(path)) { - this.registry.delete(path); - if (behavior === 'unset') { - this.proxy = unset(this.proxy, path); - this.emitInput(); - } - } - } - getState() { - return this.proxy; - } - setFieldValue(path, value) { - this.proxy = update(this.proxy, path, value); - } - emitInput() { - this.$emit('input', clone(this.proxy)); - } - emitValidation(path, violations) { - this.$emit('validation', { path, violations }); - } - onStateChange(newState) { - const newProxy = clone(newState); - const oldProxy = this.proxy; - let proxyHasChanges = false; - this.registry.forEach((field, path) => { - const newValue = get(newState, path, null); - const oldValue = get(oldProxy, path, null); - field.proxy = newValue; - if (!deepEquals(newValue, oldValue)) { - field.$emit('input', newValue); - update(newProxy, path, newValue); - proxyHasChanges = true; - } - }); - this.proxy = newProxy; - if (proxyHasChanges) { - this.emitInput(); - } - } - onFieldsErrorsChange(fieldsErrors) { - this.registry.forEach((field, path) => { - field.setErrors(fieldsErrors[path] || []); - }); - } - created() { - this.$formulario.register(this.id, this); - if (typeof this.state === 'object') { - this.proxy = clone(this.state); - } - } - beforeDestroy() { - this.$formulario.unregister(this.id); - } - runValidation() { - const runs = []; - const violations = {}; - this.registry.forEach((field, path) => { - runs.push(field.runValidation().then(v => { violations[path] = v; })); - }); - return Promise.all(runs).then(() => violations); - } - hasValidationErrors() { - return this.runValidation().then(violations => { - return Object.keys(violations).some(path => violations[path].length > 0); - }); - } - setErrors({ formErrors, fieldsErrors }) { - this.localFormErrors = formErrors || []; - this.localFieldsErrors = fieldsErrors || {}; - } - resetValidation() { - this.localFormErrors = []; - this.localFieldsErrors = {}; - this.registry.forEach((field) => { - field.resetValidation(); - }); - } - onSubmit() { - return this.runValidation().then(violations => { - const hasErrors = Object.keys(violations).some(path => violations[path].length > 0); - if (!hasErrors) { - this.$emit('submit', clone(this.proxy)); - } - else { - this.$emit('error', violations); - } - }); - } -}; -__decorate([ - Model('input', { default: () => ({}) }) -], FormularioForm.prototype, "state", void 0); -__decorate([ - Prop({ default: () => id('formulario-form') }) -], FormularioForm.prototype, "id", void 0); -__decorate([ - Prop({ default: () => ({}) }) -], FormularioForm.prototype, "fieldsErrors", void 0); -__decorate([ - Prop({ default: () => ([]) }) -], FormularioForm.prototype, "formErrors", void 0); -__decorate([ - Provide('__FormularioForm_register') -], FormularioForm.prototype, "register", null); -__decorate([ - Provide('__FormularioForm_unregister') -], FormularioForm.prototype, "unregister", null); -__decorate([ - Provide('__FormularioForm_getState') -], FormularioForm.prototype, "getState", null); -__decorate([ - Provide('__FormularioForm_set') -], FormularioForm.prototype, "setFieldValue", null); -__decorate([ - Provide('__FormularioForm_emitInput') -], FormularioForm.prototype, "emitInput", null); -__decorate([ - Provide('__FormularioForm_emitValidation') -], FormularioForm.prototype, "emitValidation", null); -__decorate([ - Watch('state', { deep: true }) -], FormularioForm.prototype, "onStateChange", null); -__decorate([ - Watch('fieldsErrorsComputed', { deep: true, immediate: true }) -], FormularioForm.prototype, "onFieldsErrorsChange", null); -FormularioForm = __decorate([ - Component({ name: 'FormularioForm' }) -], FormularioForm); -var script$2 = FormularioForm; - -/* script */ -const __vue_script__$2 = script$2; - -/* template */ -var __vue_render__$2 = function() { - var _vm = this; - var _h = _vm.$createElement; - var _c = _vm._self._c || _h; - return _c( - "form", - { - on: { - submit: function($event) { - $event.preventDefault(); - return _vm.onSubmit($event) - } - } - }, - [_vm._t("default", null, { errors: _vm.formErrorsComputed })], - 2 - ) -}; -var __vue_staticRenderFns__$2 = []; -__vue_render__$2._withStripped = true; - - /* style */ - const __vue_inject_styles__$2 = undefined; - /* scoped */ - const __vue_scope_id__$2 = undefined; - /* module identifier */ - const __vue_module_identifier__$2 = undefined; - /* functional template */ - const __vue_is_functional_template__$2 = false; - /* style inject */ - - /* style inject SSR */ - - /* style inject shadow dom */ - - - - const __vue_component__$2 = /*#__PURE__*/normalizeComponent( - { render: __vue_render__$2, staticRenderFns: __vue_staticRenderFns__$2 }, - __vue_inject_styles__$2, - __vue_script__$2, - __vue_scope_id__$2, - __vue_is_functional_template__$2, - __vue_module_identifier__$2, - false, - undefined, - undefined, - undefined - ); - -var index = { - Formulario, - install(Vue, options) { - Vue.component('FormularioField', __vue_component__); - Vue.component('FormularioFieldGroup', __vue_component__$1); - Vue.component('FormularioForm', __vue_component__$2); - Vue.mixin({ - beforeCreate() { - const o = this.$options; - if (typeof o.formulario === 'function') { - this.$formulario = o.formulario(); - } - else if (o.parent && o.parent.$formulario) { - this.$formulario = o.parent.$formulario; - } - else { - this.$formulario = new Formulario(options); - } - } - }); - }, -}; - -export default index; -export { Formulario, __vue_component__ as FormularioField, __vue_component__$1 as FormularioFieldGroup, __vue_component__$2 as FormularioForm }; diff --git a/dist/formulario.min.js b/dist/formulario.min.js deleted file mode 100644 index 5b79aaa..0000000 --- a/dist/formulario.min.js +++ /dev/null @@ -1,20 +0,0 @@ -var VueFormulario=function(t,e){"use strict";e=e&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e;var r=function(t){if("string"!=typeof t)return!1;var e=t.match(o);if(!e)return!1;var r=e[1];if(!r)return!1;if(i.test(r)||n.test(r))return!0;return!1},o=/^(?:\w+:)?\/\/(\S+)$/,i=/^localhost[\:?\d]*(?:[^\:?\d]\S*)?$/,n=/^[^\s\.]+\.\S{2,}$/;const a=new Map;var s;!function(t){t.ARRAY="ARRAY",t.BIGINT="BIGINT",t.BOOLEAN="BOOLEAN",t.DATE="DATE",t.FUNCTION="FUNCTION",t.NUMBER="NUMBER",t.RECORD="RECORD",t.STRING="STRING",t.SYMBOL="SYMBOL",t.UNDEFINED="UNDEFINED",t.NULL="NULL"}(s||(s={}));const l=t=>Object.getPrototypeOf(t).constructor;function u(t){return l(t)===Object&&0===Object.keys(Object.getPrototypeOf(t)).length}function c(t){return"object"==typeof t&&null!==t&&(u(t)||Array.isArray(t))}function f(t){switch(typeof t){case"bigint":return s.BIGINT;case"boolean":return s.BOOLEAN;case"function":return s.FUNCTION;case"number":return s.NUMBER;case"string":return s.STRING;case"symbol":return s.SYMBOL;case"undefined":return s.UNDEFINED;case"object":return null===t?s.NULL:t instanceof Date?s.DATE:Array.isArray(t)?s.ARRAY:u(t)?s.RECORD:"InstanceOf<"+l(t).name+">"}throw new Error("[Formulario] typeOf - unknown type detected")}function d(t){switch(typeof t){case"bigint":case"boolean":case"number":case"string":case"symbol":case"undefined":return!0;default:return null===t}}function p(t){if(d(t)||t instanceof Blob)return t;if(t instanceof Date)return new Date(t);if(!c(t))return e=t,Object.assign(Object.create(Object.getPrototypeOf(e)),e);var e;if(Array.isArray(t))return t.slice().map(p);const r=t;return Object.keys(r).reduce(((t,e)=>Object.assign(Object.assign({},t),{[e]:p(r[e])})),{})}function h(t,e){return Object.prototype.hasOwnProperty.call(t,e)} -/*! ***************************************************************************** - Copyright (c) Microsoft Corporation. - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. - ***************************************************************************** */function m(t,e,r,o){var i,n=arguments.length,a=n<3?e:null===o?o=Object.getOwnPropertyDescriptor(e,r):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(t,e,r,o);else for(var s=t.length-1;s>=0;s--)(i=t[s])&&(a=(n<3?i(a):n>3?i(e,r,a):i(e,r))||a);return n>3&&a&&Object.defineProperty(e,r,a),a}const y=t=>{const e=parseInt(t);return e.toString()===t?e:NaN},v=t=>{const e=[];return t.split(".").forEach((t=>{/(.*)\[(\d+)]$/.test(t)?e.push(...t.substr(0,t.length-1).split("[").filter((t=>t.length))):e.push(t)})),e};function g(t,e,r){const o="string"==typeof e?v(e):e;if(d(t)||0===o.length)return r;const i=o.shift(),n=y(i);if(!isNaN(n))return Array.isArray(t)&&n>=0&&n{const r=t,o=e;r[o];return function(t,e){var r={};for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&e.indexOf(o)<0&&(r[o]=t[o]);if(null!=t&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(o=Object.getOwnPropertySymbols(t);i=0&&i0!==t.indexOf(e)&&"_"!==t[t.indexOf(e)-1]?e.toUpperCase().replace("_",""):e))}const w={accepted:({value:t})=>["yes","on","1",1,!0,"true"].includes(t),after({value:t},e=!1){const r=!1!==e?Date.parse(e):Date.now(),o=t instanceof Date?t.getTime():Date.parse(t);return!isNaN(o)&&o>r},alpha({value:t},e="default"){const r={default:/^[a-zA-ZÀ-ÖØ-öø-ÿ]+$/,latin:/^[a-zA-Z]+$/};return"string"==typeof t&&r[h(r,e)?e:"default"].test(t)},alphanumeric({value:t},e="default"){const r={default:/^[a-zA-Z0-9À-ÖØ-öø-ÿ]+$/,latin:/^[a-zA-Z0-9]+$/};return"string"==typeof t&&r[h(r,e)?e:"default"].test(t)},before({value:t},e=!1){const r=!1!==e?Date.parse(e):Date.now(),o=t instanceof Date?t.getTime():Date.parse(t);return!isNaN(o)&&onull!==e&&null!==r&&!isNaN(e)&&!isNaN(r)&&(!isNaN(Number(t))&&"length"!==o||"value"===o?(t=Number(t))>Number(e)&&te&&t.lengthe?function(t){const e=`^${r=t,r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}$`;var r;const o={MM:"(0[1-9]|1[012])",M:"([1-9]|1[012])",DD:"([012][1-9]|3[01])",D:"([012]?[1-9]|3[01])",YYYY:"\\d{4}",YY:"\\d{2}"};return new RegExp(Object.keys(o).reduce(((t,e)=>t.replace(e,o[e])),e))}(e).test(t):!isNaN(Date.parse(t)),email({value:t}){if(!t)return!0;return/^(([^<>()\[\].,;:\s@"]+(\.[^<>()\[\].,;:\s@"]+)*)|(".+"))@(([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{2,})$/i.test(t)},endsWith:({value:t},...e)=>!t||"string"==typeof t&&(0===e.length||e.some((e=>t.endsWith(e)))),in:({value:t},...e)=>e.some((e=>j(e,t))),matches:({value:t},...e)=>!!e.find((e=>("string"==typeof e&&"/"===e.substr(0,1)&&"/"===e.substr(-1)&&(e=new RegExp(e.substr(1,e.length-2))),e instanceof RegExp?e.test(t):e===t))),max:({value:t},e=10,r)=>Array.isArray(t)?(e=isNaN(Number(e))?e:Number(e),t.length<=e):!isNaN(t)&&"length"!==r||"value"===r?(t=isNaN(t)?t:Number(t))<=e:("string"==typeof t||"length"===r)&&(t=isNaN(t)?t:String(t)).length<=e,min:({value:t},e=1,r)=>Array.isArray(t)?(e=isNaN(e)?e:Number(e),t.length>=e):!isNaN(t)&&"length"!==r||"value"===r?(t=isNaN(t)?t:Number(t))>=e:("string"==typeof t||"length"===r)&&(t=isNaN(t)?t:String(t)).length>=e,not:({value:t},...e)=>!e.some((e=>j(e,t))),number:({value:t})=>String(t).length>0&&!isNaN(Number(t)),required:({value:t},e=!0)=>!(e&&!["no","false"].includes(e))||(Array.isArray(t)?!!t.length:"string"==typeof t?!!t:"object"!=typeof t||!!t&&!!Object.keys(t).length),startsWith:({value:t},...e)=>!t||"string"==typeof t&&(0===e.length||e.some((e=>t.startsWith(e)))),url:({value:t})=>!t||r(t),bail:()=>!0},R={default:(t,e)=>t.$t("validation.default",e),accepted:(t,e)=>t.$t("validation.accepted",e),after:(t,e,r=!1)=>"string"==typeof r&&r.length?t.$t("validation.after.compare",e):t.$t("validation.after.default",e),alpha:(t,e)=>t.$t("validation.alpha",e),alphanumeric:(t,e)=>t.$t("validation.alphanumeric",e),before:(t,e,r=!1)=>"string"==typeof r&&r.length?t.$t("validation.before.compare",e):t.$t("validation.before.default",e),between(t,e,r=0,o=10,i){const n=Object.assign(Object.assign({},e),{from:r,to:o});return!isNaN(e.value)&&"length"!==i||"value"===i?t.$t("validation.between.force",n):t.$t("validation.between.default",n)},confirm:(t,e)=>t.$t("validation.confirm",e),date:(t,e,r=!1)=>"string"==typeof r&&r.length?t.$t("validation.date.format",e):t.$t("validation.date.default",e),email:(t,e)=>t.$t("validation.email.default",e),endsWith:(t,e)=>t.$t("validation.endsWith.default",e),in:(t,e)=>"string"==typeof e.value&&e.value?t.$t("validation.in.string",e):t.$t("validation.in.default",e),matches:(t,e)=>t.$t("validation.matches.default",e),max:(t,e,r=10,o)=>Array.isArray(e.value)?t.$tc("validation.max.array",r,e):!isNaN(e.value)&&"length"!==o||"value"===o?t.$tc("validation.max.force",r,e):t.$tc("validation.max.default",r,e),min:(t,e,r=1,o)=>Array.isArray(e.value)?t.$tc("validation.min.array",r,e):!isNaN(e.value)&&"length"!==o||"value"===o?t.$tc("validation.min.force",r,e):t.$tc("validation.min.default",r,e),not:(t,e)=>t.$t("validation.not.default",e),number:(t,e)=>t.$t("validation.number.default",e),required:(t,e)=>t.$t("validation.required.default",e),startsWith:(t,e)=>t.$t("validation.startsWith.default",e),url:(t,e)=>t.$t("validation.url.default",e)};class x{constructor(t){this.validationRules={},this.validationMessages={},this._registry=new Map,this.validationRules=w,this.validationMessages=R,this.extend(t||{})}extend(t){if("object"==typeof t)return this.validationRules=Object.assign(Object.assign({},this.validationRules),t.validationRules||{}),this.validationMessages=Object.assign(Object.assign({},this.validationMessages),t.validationMessages||{}),this;throw new Error(`[Formulario]: Formulario.extend(): should be passed an object (was ${typeof t})`)}runValidation(t){if(!this._registry.has(t))throw new Error(`[Formulario]: Formulario.runValidation(): no forms with id "${t}"`);return this._registry.get(t).runValidation()}resetValidation(t){if(!this._registry.has(t))return;this._registry.get(t).resetValidation()}register(t,e){if(this._registry.has(t))throw new Error(`[Formulario]: Formulario.register(): id "${t}" is already in use`);this._registry.set(t,e)}unregister(t){this._registry.has(t)&&this._registry.delete(t)}getRules(t={}){return Object.assign(Object.assign({},this.validationRules),t)}getMessages(t,e){const r=Object.assign(Object.assign({},this.validationMessages),e),o={};for(const e in r)o[e]=(o,...i)=>{const n=r[e];return"string"==typeof n?n:n(t,o,...i)};return o}} -/** - * vue-class-component v7.2.3 - * (c) 2015-present Evan You - * @license MIT - */function A(t){return(A="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function P(t,e,r){return e in t?Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):t[e]=r,t}function V(t){return function(t){if(Array.isArray(t)){for(var e=0,r=new Array(t.length);e0&&T("Component class must inherit Vue or its descendant class when class property is used."),n}var U=["data","beforeCreate","created","beforeMount","mounted","beforeDestroy","destroyed","beforeUpdate","updated","activated","deactivated","render","errorCaptured","serverPrefetch"];function k(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};r.name=r.name||t._componentTag||t.name;var o=t.prototype;Object.getOwnPropertyNames(o).forEach((function(t){if("constructor"!==t)if(U.indexOf(t)>-1)r[t]=o[t];else{var e=Object.getOwnPropertyDescriptor(o,t);void 0!==e.value?"function"==typeof e.value?(r.methods||(r.methods={}))[t]=e.value:(r.mixins||(r.mixins=[])).push({data:function(){return P({},t,e.value)}}):(e.get||e.set)&&((r.computed||(r.computed={}))[t]={get:e.get,set:e.set})}})),(r.mixins||(r.mixins=[])).push({data:function(){return B(this,t)}});var i=t.__decorators__;i&&(i.forEach((function(t){return t(r)})),delete t.__decorators__);var n=Object.getPrototypeOf(t.prototype),a=n instanceof e?n.constructor:e,s=a.extend(r);return G(s,t,a),S()&&D(s,t),s}var L=["cid","super","options","superOptions","extendOptions","sealedOptions","component","directive","filter"],Y={prototype:!0,arguments:!0,callee:!0,caller:!0};function G(t,e,r){Object.getOwnPropertyNames(e).forEach((function(o){if(!Y[o]){var i=Object.getOwnPropertyDescriptor(t,o);if(!i||i.configurable){var n,a,s=Object.getOwnPropertyDescriptor(e,o);if(!M){if("cid"===o)return;var l=Object.getOwnPropertyDescriptor(r,o);if(n=s.value,a=A(n),null!=n&&("object"===a||"function"===a)&&l&&l.value===s.value)return}"production"!==process.env.NODE_ENV&&L.indexOf(o)>=0&&T("Static property name '".concat(o,"' declared on class '").concat(e.name,"' ")+"conflicts with reserved property name of Vue internal. It may cause unexpected behavior of the component. Consider renaming the property."),Object.defineProperty(t,o,s)}}}))}function z(t){return"function"==typeof t?k(t):function(e){return k(e,t)}}z.registerHooks=function(t){U.push.apply(U,V(t))};function W(t){return I((function(e,r){void 0===e.inject&&(e.inject={}),Array.isArray(e.inject)||(e.inject[r]=t||r)}))}function q(t){return I((function(e,r){var o,i=e.provide;("function"!=typeof(o=i)||!o.managed&&!o.managedReactive)&&(i=e.provide=function(t){var e=function(){var r=this,o="function"==typeof t?t.call(this):t;for(var i in(o=Object.create(o||null)).__reactiveInject__=this.__reactiveInject__||{},e.managed)o[e.managed[i]]=this[i];var n=function(t){o[e.managedReactive[t]]=a[t],Object.defineProperty(o.__reactiveInject__,e.managedReactive[t],{enumerable:!0,get:function(){return r[t]}})},a=this;for(var i in e.managedReactive)n(i);return o};return e.managed={},e.managedReactive={},e}(i)),i.managed[r]=t||r}))}var Z="undefined"!=typeof Reflect&&void 0!==Reflect.getMetadata;function K(t,e,r){if(Z&&!Array.isArray(t)&&"function"!=typeof t&&void 0===t.type){var o=Reflect.getMetadata("design:type",e,r);o!==Object&&(t.type=o)}}function X(t,e){return void 0===e&&(e={}),function(r,o){K(e,r,o),I((function(r,o){(r.props||(r.props={}))[o]=e,r.model={prop:o,event:t||o}}))(r,o)}}function H(t){return void 0===t&&(t={}),function(e,r){K(t,e,r),I((function(e,r){(e.props||(e.props={}))[r]=t}))(e,r)}}function J(t,e){void 0===e&&(e={});var r=e.deep,o=void 0!==r&&r,i=e.immediate,n=void 0!==i&&i;return I((function(e,r){"object"!=typeof e.watch&&(e.watch=Object.create(null));var i=e.watch;"object"!=typeof i[t]||Array.isArray(i[t])?void 0===i[t]&&(i[t]=[]):i[t]=[i[t]],i[t].push({handler:r,deep:o,immediate:n})}))}function Q(t,e,r,o){return i=>Promise.resolve(t(i,...r)).then((t=>t?null:{rule:e,args:r,context:i,message:o(i,...r)}))}function tt(t){return/^[\^]/.test(t.charAt(0))?[$(t.substr(1)),t.charAt(0)]:[$(t),null]}function et(t,e,r){return"function"==typeof t?[t,null,null]:Array.isArray(t)&&t.length?function(t,e,r){const o=t.slice(),i=o.shift();if("function"==typeof i)return[i,null,null];if("string"!=typeof i)throw new Error("[Formulario]: For array constraint first element must be rule name or Validator function");const[n,a]=tt(i);if(h(e,n))return[Q(e[n],n,o,r[n]||r.default),n,a];throw new Error("[Formulario] Can't create validator for constraint: "+JSON.stringify(t))}(t,e,r):"string"==typeof t?function(t,e,r){const o=t.split(":"),[i,n]=tt(o.shift()||"");if(h(e,i))return[Q(e[i],i,o.length?o.join(":").split(","):[],r[i]||r.default),i,n];throw new Error("[Formulario] Can't create validator for constraint: "+t)}(t,e,r):[()=>Promise.resolve(null),null,null]}function rt(t,e,r){return"string"==typeof t?rt(t.split("|").filter((t=>t.length)),e,r):Array.isArray(t)?t.map((t=>et(t,e,r))):[]}function ot(t){const e=[];if(t.length){let r=t.shift();e.push(r),t.forEach((t=>{t.bail||t.bail!==r.bail?(r=Object.assign({},t),e.push(r)):r.validators.push(...t.validators)}))}return e}function it(t,e){return new Promise((r=>{const o=(t,i=[])=>{if(t.length){const n=t.shift();(function(t,e){return Promise.all(t.validators.map((t=>t(e)))).then((t=>t.filter((t=>null!==t))))})(n,e).then((e=>0!==e.length&&n.bail||!t.length?r(i.concat(e)):o(t,i.concat(e))))}else r([])};o(function(t){const e=([t,,e])=>({validators:[t],bail:"^"===e}),r=[],o=t.findIndex((([,t])=>t&&"bail"===t.toLowerCase()));return o>=0?(r.push(...ot(t.splice(0,o+1).slice(0,-1).map(e))),r.push(...t.map((([t])=>({validators:[t],bail:!0}))))):r.push(...ot(t.map(e))),r}(t))}))}let nt=class extends e{constructor(){super(...arguments),this.proxy=this.hasModel?this.value:"",this.localErrors=[],this.violations=[],this.validationRun=Promise.resolve([])}get fullPath(){return""!==this.__Formulario_path?`${this.__Formulario_path}.${this.name}`:this.name}get hasModel(){return h(this.$options.propsData||{},"value")}get context(){return Object.defineProperty({name:this.fullPath,path:this.fullPath,runValidation:this.runValidation.bind(this),violations:this.violations,errors:this.localErrors,allErrors:[...this.localErrors,...this.violations.map((t=>t.message))]},"model",{get:()=>this.modelGetConverter(this.proxy),set:t=>{this._syncProxy(this.modelSetConverter(t,this.proxy))}})}get _normalizedValidationRules(){const t={};return Object.keys(this.validationRules).forEach((e=>{t[$(e)]=this.validationRules[e]})),t}get _normalizedValidationMessages(){const t={};return Object.keys(this.validationMessages).forEach((e=>{t[$(e)]=this.validationMessages[e]})),t}_onValueChange(){this._syncProxy(this.value)}_onProxyChange(){"live"===this.validationBehavior?this.runValidation():this.resetValidation()}created(){"function"==typeof this.__FormularioForm_register&&this.__FormularioForm_register(this.fullPath,this),"live"===this.validationBehavior&&this.runValidation()}beforeDestroy(){"function"==typeof this.__FormularioForm_unregister&&this.__FormularioForm_unregister(this.fullPath,this.unregisterBehavior)}runValidation(){return this.validationRun=this._validate().then((t=>(this.violations=t,this._emitValidation(this.fullPath,t),this.violations))),this.validationRun}hasValidationErrors(){return new Promise((t=>{this.$nextTick((()=>{this.validationRun.then((()=>t(this.violations.length>0)))}))}))}setErrors(t){this.errorsDisabled||(this.localErrors=t)}resetValidation(){this.localErrors=[],this.violations=[]}_syncProxy(t){E(t,this.proxy)||(this.proxy=t,this.$emit("input",t),"function"==typeof this.__FormularioForm_set&&(this.__FormularioForm_set(this.fullPath,t),this.__FormularioForm_emitInput()))}_validate(){return it(rt(this.validation,this.$formulario.getRules(this._normalizedValidationRules),this.$formulario.getMessages(this,this._normalizedValidationMessages)),{value:this.proxy,name:this.fullPath,formValues:this.__FormularioForm_getState()})}_emitValidation(t,e){this.$emit("validation",{path:t,violations:e}),"function"==typeof this.__FormularioForm_emitValidation&&this.__FormularioForm_emitValidation(t,e)}};function at(t,e,r,o,i,n,a,s,l,u){"boolean"!=typeof a&&(l=s,s=a,a=!1);const c="function"==typeof r?r.options:r;let f;if(t&&t.render&&(c.render=t.render,c.staticRenderFns=t.staticRenderFns,c._compiled=!0,i&&(c.functional=!0)),o&&(c._scopeId=o),n?(f=function(t){(t=t||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||"undefined"==typeof __VUE_SSR_CONTEXT__||(t=__VUE_SSR_CONTEXT__),e&&e.call(this,l(t)),t&&t._registeredComponents&&t._registeredComponents.add(n)},c._ssrRegister=f):e&&(f=a?function(t){e.call(this,u(t,this.$root.$options.shadowRoot))}:function(t){e.call(this,s(t))}),f)if(c.functional){const t=c.render;c.render=function(e,r){return f.call(r),t(e,r)}}else{const t=c.beforeCreate;c.beforeCreate=t?[].concat(t,f):[f]}return r}m([W({default:""})],nt.prototype,"__Formulario_path",void 0),m([W({default:void 0})],nt.prototype,"__FormularioForm_set",void 0),m([W({default:()=>()=>{}})],nt.prototype,"__FormularioForm_emitInput",void 0),m([W({default:()=>()=>{}})],nt.prototype,"__FormularioForm_emitValidation",void 0),m([W({default:void 0})],nt.prototype,"__FormularioForm_register",void 0),m([W({default:void 0})],nt.prototype,"__FormularioForm_unregister",void 0),m([W({default:()=>()=>({})})],nt.prototype,"__FormularioForm_getState",void 0),m([X("input",{default:""})],nt.prototype,"value",void 0),m([H({required:!0,validator:t=>"string"==typeof t&&t.length>0})],nt.prototype,"name",void 0),m([H({default:""})],nt.prototype,"validation",void 0),m([H({default:()=>({})})],nt.prototype,"validationRules",void 0),m([H({default:()=>({})})],nt.prototype,"validationMessages",void 0),m([H({default:"demand",validator:t=>["demand","live","submit"].includes(t)})],nt.prototype,"validationBehavior",void 0),m([H({default:!1})],nt.prototype,"errorsDisabled",void 0),m([H({default:()=>t=>t})],nt.prototype,"modelGetConverter",void 0),m([H({default:()=>t=>t})],nt.prototype,"modelSetConverter",void 0),m([H({default:"div"})],nt.prototype,"tag",void 0),m([H({default:"none"})],nt.prototype,"unregisterBehavior",void 0),m([J("value")],nt.prototype,"_onValueChange",null),m([J("proxy")],nt.prototype,"_onProxyChange",null),nt=m([z({name:"FormularioField",inheritAttrs:!1})],nt);const st=nt;var lt=function(){var t=this,e=t.$createElement;return(t._self._c||e)(t.tag,t._b({tag:"component"},"component",t.$attrs,!1),[t._t("default",null,{context:t.context})],2)};lt._withStripped=!0;const ut=at({render:lt,staticRenderFns:[]},undefined,st,undefined,false,undefined,!1,void 0,void 0,void 0);let ct=class extends e{get fullPath(){const t=""+this.name;return parseInt(t).toString()===t?`${this.__Formulario_path}[${t}]`:""===this.__Formulario_path?t:`${this.__Formulario_path}.${t}`}};m([W({default:""})],ct.prototype,"__Formulario_path",void 0),m([H({required:!0})],ct.prototype,"name",void 0),m([q("__Formulario_path")],ct.prototype,"fullPath",null),ct=m([z({name:"FormularioFieldGroup"})],ct);const ft=ct;var dt=function(){var t=this,e=t.$createElement;return(t._self._c||e)("div",[t._t("default")],2)};dt._withStripped=!0;const pt=at({render:dt,staticRenderFns:[]},undefined,ft,undefined,false,undefined,!1,void 0,void 0,void 0),ht=(t,e,r)=>void 0===r?O(t,e):_(t,e,r);let mt=class extends e{constructor(){super(...arguments),this.proxy={},this.registry=new Map,this.localFieldsErrors={},this.localFormErrors=[]}get fieldsErrorsComputed(){return Object.assign(Object.assign({},this.fieldsErrors),this.localFieldsErrors)}get formErrorsComputed(){return[...this.formErrors,...this.localFormErrors]}register(t,e){this.registry.has(t)||this.registry.set(t,e);const r=g(this.proxy,t);e.hasModel?E(e.proxy,r)||(this.setFieldValue(t,e.proxy),this.emitInput()):void 0!==r?e.proxy=r:(this.setFieldValue(t,null),this.emitInput()),h(this.fieldsErrorsComputed,t)&&e.setErrors(this.fieldsErrorsComputed[t])}unregister(t,e){this.registry.has(t)&&(this.registry.delete(t),"unset"===e&&(this.proxy=O(this.proxy,t),this.emitInput()))}getState(){return this.proxy}setFieldValue(t,e){this.proxy=ht(this.proxy,t,e)}emitInput(){this.$emit("input",p(this.proxy))}emitValidation(t,e){this.$emit("validation",{path:t,violations:e})}onStateChange(t){const e=p(t),r=this.proxy;let o=!1;this.registry.forEach(((i,n)=>{const a=g(t,n,null),s=g(r,n,null);i.proxy=a,E(a,s)||(i.$emit("input",a),ht(e,n,a),o=!0)})),this.proxy=e,o&&this.emitInput()}onFieldsErrorsChange(t){this.registry.forEach(((e,r)=>{e.setErrors(t[r]||[])}))}created(){this.$formulario.register(this.id,this),"object"==typeof this.state&&(this.proxy=p(this.state))}beforeDestroy(){this.$formulario.unregister(this.id)}runValidation(){const t=[],e={};return this.registry.forEach(((r,o)=>{t.push(r.runValidation().then((t=>{e[o]=t})))})),Promise.all(t).then((()=>e))}hasValidationErrors(){return this.runValidation().then((t=>Object.keys(t).some((e=>t[e].length>0))))}setErrors({formErrors:t,fieldsErrors:e}){this.localFormErrors=t||[],this.localFieldsErrors=e||{}}resetValidation(){this.localFormErrors=[],this.localFieldsErrors={},this.registry.forEach((t=>{t.resetValidation()}))}onSubmit(){return this.runValidation().then((t=>{Object.keys(t).some((e=>t[e].length>0))?this.$emit("error",t):this.$emit("submit",p(this.proxy))}))}};m([X("input",{default:()=>({})})],mt.prototype,"state",void 0),m([H({default:()=>(t=>{const e=(a.get(t)||0)+1;return a.set(t,e),`${t}-${e}`})("formulario-form")})],mt.prototype,"id",void 0),m([H({default:()=>({})})],mt.prototype,"fieldsErrors",void 0),m([H({default:()=>[]})],mt.prototype,"formErrors",void 0),m([q("__FormularioForm_register")],mt.prototype,"register",null),m([q("__FormularioForm_unregister")],mt.prototype,"unregister",null),m([q("__FormularioForm_getState")],mt.prototype,"getState",null),m([q("__FormularioForm_set")],mt.prototype,"setFieldValue",null),m([q("__FormularioForm_emitInput")],mt.prototype,"emitInput",null),m([q("__FormularioForm_emitValidation")],mt.prototype,"emitValidation",null),m([J("state",{deep:!0})],mt.prototype,"onStateChange",null),m([J("fieldsErrorsComputed",{deep:!0,immediate:!0})],mt.prototype,"onFieldsErrorsChange",null),mt=m([z({name:"FormularioForm"})],mt);const yt=mt;var vt=function(){var t=this,e=t.$createElement;return(t._self._c||e)("form",{on:{submit:function(e){return e.preventDefault(),t.onSubmit(e)}}},[t._t("default",null,{errors:t.formErrorsComputed})],2)};vt._withStripped=!0;const gt=at({render:vt,staticRenderFns:[]},undefined,yt,undefined,false,undefined,!1,void 0,void 0,void 0);var _t={Formulario:x,install(t,e){t.component("FormularioField",ut),t.component("FormularioFieldGroup",pt),t.component("FormularioForm",gt),t.mixin({beforeCreate(){const t=this.$options;"function"==typeof t.formulario?this.$formulario=t.formulario():t.parent&&t.parent.$formulario?this.$formulario=t.parent.$formulario:this.$formulario=new x(e)}})}};return t.Formulario=x,t.FormularioField=ut,t.FormularioFieldGroup=pt,t.FormularioForm=gt,t.default=_t,t}({},Vue); diff --git a/dist/formulario.umd.js b/dist/formulario.umd.js deleted file mode 100644 index 1c17c08..0000000 --- a/dist/formulario.umd.js +++ /dev/null @@ -1,1497 +0,0 @@ -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('is-url'), require('vue'), require('vue-property-decorator')) : - typeof define === 'function' && define.amd ? define(['exports', 'is-url', 'vue', 'vue-property-decorator'], factory) : - (global = global || self, factory(global.Formulario = {}, global.isUrl, global.Vue, global.vuePropertyDecorator)); -}(this, (function (exports, isUrl, Vue, vuePropertyDecorator) { 'use strict'; - - isUrl = isUrl && Object.prototype.hasOwnProperty.call(isUrl, 'default') ? isUrl['default'] : isUrl; - Vue = Vue && Object.prototype.hasOwnProperty.call(Vue, 'default') ? Vue['default'] : Vue; - - const registry = new Map(); - var id = (prefix) => { - const current = registry.get(prefix) || 0; - const next = current + 1; - registry.set(prefix, next); - return `${prefix}-${next}`; - }; - - var TYPE; - (function (TYPE) { - TYPE["ARRAY"] = "ARRAY"; - TYPE["BIGINT"] = "BIGINT"; - TYPE["BOOLEAN"] = "BOOLEAN"; - TYPE["DATE"] = "DATE"; - TYPE["FUNCTION"] = "FUNCTION"; - TYPE["NUMBER"] = "NUMBER"; - TYPE["RECORD"] = "RECORD"; - TYPE["STRING"] = "STRING"; - TYPE["SYMBOL"] = "SYMBOL"; - TYPE["UNDEFINED"] = "UNDEFINED"; - TYPE["NULL"] = "NULL"; - })(TYPE || (TYPE = {})); - const constructorOf = (value) => { - return Object.getPrototypeOf(value).constructor; - }; - function isRecord(value) { - return constructorOf(value) === Object && Object.keys(Object.getPrototypeOf(value)).length === 0; - } - function isRecordLike(value) { - return typeof value === 'object' && value !== null && (isRecord(value) || Array.isArray(value)); - } - function typeOf(value) { - switch (typeof value) { - case 'bigint': - return TYPE.BIGINT; - case 'boolean': - return TYPE.BOOLEAN; - case 'function': - return TYPE.FUNCTION; - case 'number': - return TYPE.NUMBER; - case 'string': - return TYPE.STRING; - case 'symbol': - return TYPE.SYMBOL; - case 'undefined': - return TYPE.UNDEFINED; - case 'object': - if (value === null) { - return TYPE.NULL; - } - if (value instanceof Date) { - return TYPE.DATE; - } - if (Array.isArray(value)) { - return TYPE.ARRAY; - } - if (isRecord(value)) { - return TYPE.RECORD; - } - return 'InstanceOf<' + constructorOf(value).name + '>'; - } - throw new Error('[Formulario] typeOf - unknown type detected'); - } - function isScalar(value) { - switch (typeof value) { - case 'bigint': - case 'boolean': - case 'number': - case 'string': - case 'symbol': - case 'undefined': - return true; - default: - return value === null; - } - } - - const cloneInstance = (original) => { - return Object.assign(Object.create(Object.getPrototypeOf(original)), original); - }; - /** - * A simple (somewhat non-comprehensive) clone function, valid for our use - * case of needing to unbind reactive watchers. - */ - function clone(value) { - // scalars & immutables - if (isScalar(value) || value instanceof Blob) { - return value; - } - if (value instanceof Date) { - return new Date(value); - } - if (!isRecordLike(value)) { - return cloneInstance(value); - } - if (Array.isArray(value)) { - return value.slice().map(clone); - } - const source = value; - return Object.keys(source).reduce((copy, key) => (Object.assign(Object.assign({}, copy), { [key]: clone(source[key]) })), {}); - } - - /** - * Shorthand for Object.prototype.hasOwnProperty.call (space saving) - */ - function has(ctx, prop) { - return Object.prototype.hasOwnProperty.call(ctx, prop); - } - - /*! ***************************************************************************** - Copyright (c) Microsoft Corporation. - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - PERFORMANCE OF THIS SOFTWARE. - ***************************************************************************** */ - - function __rest(s, e) { - var t = {}; - for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) - t[p] = s[p]; - if (s != null && typeof Object.getOwnPropertySymbols === "function") - for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { - if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) - t[p[i]] = s[p[i]]; - } - return t; - } - - function __decorate(decorators, target, key, desc) { - var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); - else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; - } - - const extractIntOrNaN = (value) => { - const numeric = parseInt(value); - return numeric.toString() === value ? numeric : NaN; - }; - const extractPath = (raw) => { - const path = []; - raw.split('.').forEach(key => { - if (/(.*)\[(\d+)]$/.test(key)) { - path.push(...key.substr(0, key.length - 1).split('[').filter(k => k.length)); - } - else { - path.push(key); - } - }); - return path; - }; - function get(state, rawOrPath, fallback = undefined) { - const path = typeof rawOrPath === 'string' ? extractPath(rawOrPath) : rawOrPath; - if (isScalar(state) || path.length === 0) { - return fallback; - } - const key = path.shift(); - const index = extractIntOrNaN(key); - if (!isNaN(index)) { - if (Array.isArray(state) && index >= 0 && index < state.length) { - return path.length === 0 ? state[index] : get(state[index], path, fallback); - } - return undefined; - } - if (has(state, key)) { - const values = state; - return path.length === 0 ? values[key] : get(values[key], path, fallback); - } - return undefined; - } - function set(state, rawOrPath, value) { - const path = typeof rawOrPath === 'string' ? extractPath(rawOrPath) : rawOrPath; - if (path.length === 0) { - return value; - } - const key = path.shift(); - const index = extractIntOrNaN(key); - if (!isRecordLike(state)) { - return set(!isNaN(index) ? [] : {}, [key, ...path], value); - } - if (!isNaN(index) && Array.isArray(state)) { - const slice = [...state]; - slice[index] = path.length === 0 ? value : set(slice[index], path, value); - return slice; - } - const slice = Object.assign({}, state); - slice[key] = path.length === 0 ? value : set(slice[key], path, value); - return slice; - } - const unsetInRecord = (record, prop) => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const _a = record, _b = prop, _ = _a[_b], copy = __rest(_a, [typeof _b === "symbol" ? _b : _b + ""]); - return copy; - }; - function unset(state, rawOrPath) { - if (!isRecordLike(state)) { - return state; - } - const path = typeof rawOrPath === 'string' ? extractPath(rawOrPath) : rawOrPath; - if (path.length === 0) { - return state; - } - const key = path.shift(); - const index = extractIntOrNaN(key); - if (!isNaN(index) && Array.isArray(state) && index >= 0 && index < state.length) { - const slice = [...state]; - if (path.length === 0) { - slice.splice(index, 1); - } - else { - slice[index] = unset(slice[index], path); - } - return slice; - } - if (has(state, key)) { - const slice = Object.assign({}, state); - return path.length === 0 - ? unsetInRecord(slice, key) - : Object.assign(Object.assign({}, slice), { [key]: unset(slice[key], path) }); - } - return state; - } - - /** - * Escape a string for use in regular expressions. - */ - function escapeRegExp(string) { - return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string - } - /** - * Given a string format (date) return a regex to match against. - */ - function regexForFormat(format) { - const escaped = `^${escapeRegExp(format)}$`; - const formats = { - MM: '(0[1-9]|1[012])', - M: '([1-9]|1[012])', - DD: '([012][1-9]|3[01])', - D: '([012]?[1-9]|3[01])', - YYYY: '\\d{4}', - YY: '\\d{2}' - }; - return new RegExp(Object.keys(formats).reduce((regex, format) => { - return regex.replace(format, formats[format]); - }, escaped)); - } - - function datesEquals(a, b) { - return a.getTime() === b.getTime(); - } - function arraysEquals(a, b, predicate) { - if (a.length !== b.length) { - return false; - } - for (let i = 0; i < a.length; i++) { - if (!predicate(a[i], b[i])) { - return false; - } - } - return true; - } - function recordsEquals(a, b, predicate) { - if (Object.keys(a).length !== Object.keys(b).length) { - return false; - } - for (const prop in a) { - if (!has(b, prop) || !predicate(a[prop], b[prop])) { - return false; - } - } - return true; - } - function strictEquals(a, b) { - return a === b; - } - function equals(a, b, predicate) { - const typeOfA = typeOf(a); - const typeOfB = typeOf(b); - return typeOfA === typeOfB && ((typeOfA === TYPE.ARRAY && arraysEquals(a, b, predicate)) || - (typeOfA === TYPE.DATE && datesEquals(a, b)) || - (typeOfA === TYPE.RECORD && recordsEquals(a, b, predicate)) || - (typeOfA.includes('InstanceOf') && equals(Object.entries(a), Object.entries(b), predicate))); - } - function deepEquals(a, b) { - return a === b || equals(a, b, deepEquals); - } - function shallowEquals(a, b) { - return a === b || equals(a, b, strictEquals); - } - - /** - * Given a string, convert snake_case to camelCase - */ - function snakeToCamel(string) { - return string.replace(/([_][a-z0-9])/ig, ($1) => { - if (string.indexOf($1) !== 0 && string[string.indexOf($1) - 1] !== '_') { - return $1.toUpperCase().replace('_', ''); - } - return $1; - }); - } - - const rules = { - /** - * Rule: the value must be "yes", "on", "1", or true - */ - accepted({ value }) { - return ['yes', 'on', '1', 1, true, 'true'].includes(value); - }, - /** - * Rule: checks if a value is after a given date. Defaults to current time - */ - after({ value }, compare = false) { - const compareTimestamp = compare !== false ? Date.parse(compare) : Date.now(); - const valueTimestamp = value instanceof Date ? value.getTime() : Date.parse(value); - return isNaN(valueTimestamp) ? false : (valueTimestamp > compareTimestamp); - }, - /** - * Rule: checks if the value is only alpha - */ - alpha({ value }, set = 'default') { - const sets = { - default: /^[a-zA-ZÀ-ÖØ-öø-ÿ]+$/, - latin: /^[a-zA-Z]+$/, - }; - return typeof value === 'string' && sets[has(sets, set) ? set : 'default'].test(value); - }, - /** - * Rule: checks if the value is alpha numeric - */ - alphanumeric({ value }, set = 'default') { - const sets = { - default: /^[a-zA-Z0-9À-ÖØ-öø-ÿ]+$/, - latin: /^[a-zA-Z0-9]+$/ - }; - return typeof value === 'string' && sets[has(sets, set) ? set : 'default'].test(value); - }, - /** - * Rule: checks if a value is after a given date. Defaults to current time - */ - before({ value }, compare = false) { - const compareTimestamp = compare !== false ? Date.parse(compare) : Date.now(); - const valueTimestamp = value instanceof Date ? value.getTime() : Date.parse(value); - return isNaN(valueTimestamp) ? false : (valueTimestamp < compareTimestamp); - }, - /** - * Rule: checks if the value is between two other values - */ - between({ value }, from = 0, to = 10, force) { - if (from === null || to === null || isNaN(from) || isNaN(to)) { - return false; - } - if ((!isNaN(Number(value)) && force !== 'length') || force === 'value') { - value = Number(value); - return (value > Number(from) && value < Number(to)); - } - if (typeof value === 'string' || force === 'length') { - value = (!isNaN(Number(value)) ? value.toString() : value); - return value.length > from && value.length < to; - } - return false; - }, - /** - * Confirm that the value of one field is the same as another, mostly used - * for password confirmations. - */ - confirm({ value, formValues, name }, field) { - let confirmationFieldName = field; - if (!confirmationFieldName) { - confirmationFieldName = /_confirm$/.test(name) ? name.substr(0, name.length - 8) : `${name}_confirm`; - } - return formValues[confirmationFieldName] === value; - }, - /** - * Rule: ensures the value is a date according to Date.parse(), or a format - * regex. - */ - date({ value }, format = false) { - return format ? regexForFormat(format).test(value) : !isNaN(Date.parse(value)); - }, - /** - * Rule: tests - */ - email({ value }) { - if (!value) { - return true; - } - // eslint-disable-next-line - const isEmail = /^(([^<>()\[\].,;:\s@"]+(\.[^<>()\[\].,;:\s@"]+)*)|(".+"))@(([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{2,})$/i; - return isEmail.test(value); - }, - /** - * Rule: Value ends with one of the given Strings - */ - endsWith({ value }, ...stack) { - if (!value) { - return true; - } - if (typeof value === 'string') { - return stack.length === 0 || stack.some(str => value.endsWith(str)); - } - return false; - }, - /** - * Rule: Value is in an array (stack). - */ - in({ value }, ...stack) { - return stack.some(item => shallowEquals(item, value)); - }, - /** - * Rule: Match the value against a (stack) of patterns or strings - */ - matches({ value }, ...stack) { - return !!stack.find(pattern => { - if (typeof pattern === 'string' && pattern.substr(0, 1) === '/' && pattern.substr(-1) === '/') { - pattern = new RegExp(pattern.substr(1, pattern.length - 2)); - } - if (pattern instanceof RegExp) { - return pattern.test(value); - } - return pattern === value; - }); - }, - /** - * Check the maximum value of a particular. - */ - max({ value }, maximum = 10, force) { - if (Array.isArray(value)) { - maximum = !isNaN(Number(maximum)) ? Number(maximum) : maximum; - return value.length <= maximum; - } - if ((!isNaN(value) && force !== 'length') || force === 'value') { - value = !isNaN(value) ? Number(value) : value; - return value <= maximum; - } - if (typeof value === 'string' || (force === 'length')) { - value = !isNaN(value) ? String(value) : value; - return value.length <= maximum; - } - return false; - }, - /** - * Check the minimum value of a particular. - */ - min({ value }, minimum = 1, force) { - if (Array.isArray(value)) { - minimum = !isNaN(minimum) ? Number(minimum) : minimum; - return value.length >= minimum; - } - if ((!isNaN(value) && force !== 'length') || force === 'value') { - value = !isNaN(value) ? Number(value) : value; - return value >= minimum; - } - if (typeof value === 'string' || (force === 'length')) { - value = !isNaN(value) ? String(value) : value; - return value.length >= minimum; - } - return false; - }, - /** - * Rule: Value is not in stack. - */ - not({ value }, ...stack) { - return !stack.some(item => shallowEquals(item, value)); - }, - /** - * Rule: checks if the value is only alpha numeric - */ - number({ value }) { - return String(value).length > 0 && !isNaN(Number(value)); - }, - /** - * Rule: must be a value - */ - required({ value }, isRequired = true) { - if (!isRequired || ['no', 'false'].includes(isRequired)) { - return true; - } - if (Array.isArray(value)) { - return !!value.length; - } - if (typeof value === 'string') { - return !!value; - } - if (typeof value === 'object') { - return (!value) ? false : !!Object.keys(value).length; - } - return true; - }, - /** - * Rule: Value starts with one of the given Strings - */ - startsWith({ value }, ...stack) { - if (!value) { - return true; - } - if (typeof value === 'string') { - return stack.length === 0 || stack.some(str => value.startsWith(str)); - } - return false; - }, - /** - * Rule: checks if a string is a valid url - */ - url({ value }) { - if (!value) { - return true; - } - return isUrl(value); - }, - /** - * Rule: not a true rule — more like a compiler flag. - */ - bail() { - return true; - }, - }; - - /** - * Message builders, names match rules names, see @/validation/rules - */ - const messages = { - /** - * Fallback for rules without message builder - * @param vm - * @param context - */ - default(vm, context) { - return vm.$t('validation.default', context); - }, - accepted(vm, context) { - return vm.$t('validation.accepted', context); - }, - after(vm, context, compare = false) { - if (typeof compare === 'string' && compare.length) { - return vm.$t('validation.after.compare', context); - } - return vm.$t('validation.after.default', context); - }, - alpha(vm, context) { - return vm.$t('validation.alpha', context); - }, - alphanumeric(vm, context) { - return vm.$t('validation.alphanumeric', context); - }, - before(vm, context, compare = false) { - if (typeof compare === 'string' && compare.length) { - return vm.$t('validation.before.compare', context); - } - return vm.$t('validation.before.default', context); - }, - between(vm, context, from = 0, to = 10, force) { - const data = Object.assign(Object.assign({}, context), { from, to }); - if ((!isNaN(context.value) && force !== 'length') || force === 'value') { - return vm.$t('validation.between.force', data); - } - return vm.$t('validation.between.default', data); - }, - confirm(vm, context) { - return vm.$t('validation.confirm', context); - }, - date(vm, context, format = false) { - if (typeof format === 'string' && format.length) { - return vm.$t('validation.date.format', context); - } - return vm.$t('validation.date.default', context); - }, - email(vm, context) { - return vm.$t('validation.email.default', context); - }, - endsWith(vm, context) { - return vm.$t('validation.endsWith.default', context); - }, - in(vm, context) { - if (typeof context.value === 'string' && context.value) { - return vm.$t('validation.in.string', context); - } - return vm.$t('validation.in.default', context); - }, - matches(vm, context) { - return vm.$t('validation.matches.default', context); - }, - max(vm, context, maximum = 10, force) { - if (Array.isArray(context.value)) { - return vm.$tc('validation.max.array', maximum, context); - } - if ((!isNaN(context.value) && force !== 'length') || force === 'value') { - return vm.$tc('validation.max.force', maximum, context); - } - return vm.$tc('validation.max.default', maximum, context); - }, - min(vm, context, minimum = 1, force) { - if (Array.isArray(context.value)) { - return vm.$tc('validation.min.array', minimum, context); - } - if ((!isNaN(context.value) && force !== 'length') || force === 'value') { - return vm.$tc('validation.min.force', minimum, context); - } - return vm.$tc('validation.min.default', minimum, context); - }, - not(vm, context) { - return vm.$t('validation.not.default', context); - }, - number(vm, context) { - return vm.$t('validation.number.default', context); - }, - required(vm, context) { - return vm.$t('validation.required.default', context); - }, - startsWith(vm, context) { - return vm.$t('validation.startsWith.default', context); - }, - url(vm, context) { - return vm.$t('validation.url.default', context); - } - }; - - class Formulario { - constructor(options) { - this.validationRules = {}; - this.validationMessages = {}; - this._registry = new Map(); - this.validationRules = rules; - this.validationMessages = messages; - this.extend(options || {}); - } - /** - * Given a set of options, apply them to the pre-existing options. - */ - extend(extendWith) { - if (typeof extendWith === 'object') { - this.validationRules = Object.assign(Object.assign({}, this.validationRules), (extendWith.validationRules || {})); - this.validationMessages = Object.assign(Object.assign({}, this.validationMessages), (extendWith.validationMessages || {})); - return this; - } - throw new Error(`[Formulario]: Formulario.extend(): should be passed an object (was ${typeof extendWith})`); - } - runValidation(id) { - if (!this._registry.has(id)) { - throw new Error(`[Formulario]: Formulario.runValidation(): no forms with id "${id}"`); - } - const form = this._registry.get(id); - return form.runValidation(); - } - resetValidation(id) { - if (!this._registry.has(id)) { - return; - } - const form = this._registry.get(id); - form.resetValidation(); - } - /** - * Used by forms instances to add themselves into a registry - * @internal - */ - register(id, form) { - if (this._registry.has(id)) { - throw new Error(`[Formulario]: Formulario.register(): id "${id}" is already in use`); - } - this._registry.set(id, form); - } - /** - * Used by forms instances to remove themselves from a registry - * @internal - */ - unregister(id) { - if (this._registry.has(id)) { - this._registry.delete(id); - } - } - /** - * Get validation rules by merging any passed in with global rules. - * @internal - */ - getRules(extendWith = {}) { - return Object.assign(Object.assign({}, this.validationRules), extendWith); - } - /** - * Get validation messages by merging any passed in with global messages. - * @internal - */ - getMessages(vm, extendWith) { - const raw = Object.assign(Object.assign({}, this.validationMessages), extendWith); - const messages = {}; - for (const name in raw) { - messages[name] = (context, ...args) => { - const fn = raw[name]; - return typeof fn === 'string' ? fn : fn(vm, context, ...args); - }; - } - return messages; - } - } - - function createValidator(ruleFn, ruleName, ruleArgs, messageFn) { - return (context) => { - return Promise.resolve(ruleFn(context, ...ruleArgs)).then(valid => { - return !valid ? { - rule: ruleName, - args: ruleArgs, - context, - message: messageFn(context, ...ruleArgs), - } : null; - }); - }; - } - function parseModifier(ruleName) { - if (/^[\^]/.test(ruleName.charAt(0))) { - return [snakeToCamel(ruleName.substr(1)), ruleName.charAt(0)]; - } - return [snakeToCamel(ruleName), null]; - } - function processSingleArrayConstraint(constraint, rules, messages) { - const args = constraint.slice(); - const first = args.shift(); - if (typeof first === 'function') { - return [first, null, null]; - } - if (typeof first !== 'string') { - throw new Error('[Formulario]: For array constraint first element must be rule name or Validator function'); - } - const [name, modifier] = parseModifier(first); - if (has(rules, name)) { - return [ - createValidator(rules[name], name, args, messages[name] || messages.default), - name, - modifier, - ]; - } - throw new Error(`[Formulario] Can't create validator for constraint: ${JSON.stringify(constraint)}`); - } - function processSingleStringConstraint(constraint, rules, messages) { - const args = constraint.split(':'); - const [name, modifier] = parseModifier(args.shift() || ''); - if (has(rules, name)) { - return [ - createValidator(rules[name], name, args.length ? args.join(':').split(',') : [], messages[name] || messages.default), - name, - modifier, - ]; - } - throw new Error(`[Formulario] Can't create validator for constraint: ${constraint}`); - } - function processSingleConstraint(constraint, rules, messages) { - if (typeof constraint === 'function') { - return [constraint, null, null]; - } - if (Array.isArray(constraint) && constraint.length) { - return processSingleArrayConstraint(constraint, rules, messages); - } - if (typeof constraint === 'string') { - return processSingleStringConstraint(constraint, rules, messages); - } - return [() => Promise.resolve(null), null, null]; - } - function processConstraints(constraints, rules, messages) { - if (typeof constraints === 'string') { - return processConstraints(constraints.split('|').filter(f => f.length), rules, messages); - } - if (!Array.isArray(constraints)) { - return []; - } - return constraints.map(constraint => processSingleConstraint(constraint, rules, messages)); - } - function enlarge(groups) { - const enlarged = []; - if (groups.length) { - let current = groups.shift(); - enlarged.push(current); - groups.forEach((group) => { - if (!group.bail && group.bail === current.bail) { - current.validators.push(...group.validators); - } - else { - current = Object.assign({}, group); - enlarged.push(current); - } - }); - } - return enlarged; - } - /** - * Given an array of rules, group them by bail signals. For example for this: - * bail|required|min:10|max:20 - * we would expect: - * [[required], [min], [max]] - * because any sub-array failure would cause a shutdown. While - * ^required|min:10|max:10 - * would return: - * [[required], [min, max]] - * and no bailing would produce: - * [[required, min, max]] - * @param {array} rules - */ - function createValidatorGroups(rules) { - const mapper = ([validator, /** name */ , modifier]) => ({ - validators: [validator], - bail: modifier === '^', - }); - const groups = []; - const bailIndex = rules.findIndex(([, name]) => name && name.toLowerCase() === 'bail'); - if (bailIndex >= 0) { - groups.push(...enlarge(rules.splice(0, bailIndex + 1).slice(0, -1).map(mapper))); - groups.push(...rules.map(([validator]) => ({ - validators: [validator], - bail: true, - }))); - } - else { - groups.push(...enlarge(rules.map(mapper))); - } - return groups; - } - function validateByGroup(group, context) { - return Promise.all(group.validators.map(validate => validate(context))) - .then(violations => violations.filter(v => v !== null)); - } - function validate(validators, context) { - return new Promise(resolve => { - const resolveGroups = (groups, all = []) => { - if (groups.length) { - const current = groups.shift(); - validateByGroup(current, context).then(violations => { - // The rule passed or its a non-bailing group, and there are additional groups to check, continue - if ((violations.length === 0 || !current.bail) && groups.length) { - return resolveGroups(groups, all.concat(violations)); - } - return resolve(all.concat(violations)); - }); - } - else { - resolve([]); - } - }; - resolveGroups(createValidatorGroups(validators)); - }); - } - - let FormularioField = class FormularioField extends Vue { - constructor() { - super(...arguments); - this.proxy = this.hasModel ? this.value : ''; - this.localErrors = []; - this.violations = []; - this.validationRun = Promise.resolve([]); - } - get fullPath() { - return this.__Formulario_path !== '' ? `${this.__Formulario_path}.${this.name}` : this.name; - } - /** Determines if this formulario element is v-modeled or not. */ - get hasModel() { - return has(this.$options.propsData || {}, 'value'); - } - get context() { - return Object.defineProperty({ - name: this.fullPath, - path: this.fullPath, - runValidation: this.runValidation.bind(this), - violations: this.violations, - errors: this.localErrors, - allErrors: [...this.localErrors, ...this.violations.map(v => v.message)], - }, 'model', { - get: () => this.modelGetConverter(this.proxy), - set: (value) => { - this._syncProxy(this.modelSetConverter(value, this.proxy)); - }, - }); - } - get _normalizedValidationRules() { - const rules = {}; - Object.keys(this.validationRules).forEach(key => { - rules[snakeToCamel(key)] = this.validationRules[key]; - }); - return rules; - } - get _normalizedValidationMessages() { - const messages = {}; - Object.keys(this.validationMessages).forEach(key => { - messages[snakeToCamel(key)] = this.validationMessages[key]; - }); - return messages; - } - _onValueChange() { - this._syncProxy(this.value); - } - _onProxyChange() { - if (this.validationBehavior === 'live') { - this.runValidation(); - } - else { - this.resetValidation(); - } - } - /** @internal */ - created() { - if (typeof this.__FormularioForm_register === 'function') { - this.__FormularioForm_register(this.fullPath, this); - } - if (this.validationBehavior === 'live') { - this.runValidation(); - } - } - /** @internal */ - beforeDestroy() { - if (typeof this.__FormularioForm_unregister === 'function') { - this.__FormularioForm_unregister(this.fullPath, this.unregisterBehavior); - } - } - runValidation() { - this.validationRun = this._validate().then(violations => { - this.violations = violations; - this._emitValidation(this.fullPath, violations); - return this.violations; - }); - return this.validationRun; - } - hasValidationErrors() { - return new Promise(resolve => { - this.$nextTick(() => { - this.validationRun.then(() => resolve(this.violations.length > 0)); - }); - }); - } - /** @internal */ - setErrors(errors) { - if (!this.errorsDisabled) { - this.localErrors = errors; - } - } - /** @internal */ - resetValidation() { - this.localErrors = []; - this.violations = []; - } - _syncProxy(value) { - if (!deepEquals(value, this.proxy)) { - this.proxy = value; - this.$emit('input', value); - if (typeof this.__FormularioForm_set === 'function') { - this.__FormularioForm_set(this.fullPath, value); - this.__FormularioForm_emitInput(); - } - } - } - _validate() { - return validate(processConstraints(this.validation, this.$formulario.getRules(this._normalizedValidationRules), this.$formulario.getMessages(this, this._normalizedValidationMessages)), { - value: this.proxy, - name: this.fullPath, - formValues: this.__FormularioForm_getState(), - }); - } - _emitValidation(path, violations) { - this.$emit('validation', { path, violations }); - if (typeof this.__FormularioForm_emitValidation === 'function') { - this.__FormularioForm_emitValidation(path, violations); - } - } - }; - __decorate([ - vuePropertyDecorator.Inject({ default: '' }) - ], FormularioField.prototype, "__Formulario_path", void 0); - __decorate([ - vuePropertyDecorator.Inject({ default: undefined }) - ], FormularioField.prototype, "__FormularioForm_set", void 0); - __decorate([ - vuePropertyDecorator.Inject({ default: () => () => { } }) - ], FormularioField.prototype, "__FormularioForm_emitInput", void 0); - __decorate([ - vuePropertyDecorator.Inject({ default: () => () => { } }) - ], FormularioField.prototype, "__FormularioForm_emitValidation", void 0); - __decorate([ - vuePropertyDecorator.Inject({ default: undefined }) - ], FormularioField.prototype, "__FormularioForm_register", void 0); - __decorate([ - vuePropertyDecorator.Inject({ default: undefined }) - ], FormularioField.prototype, "__FormularioForm_unregister", void 0); - __decorate([ - vuePropertyDecorator.Inject({ default: () => () => ({}) }) - ], FormularioField.prototype, "__FormularioForm_getState", void 0); - __decorate([ - vuePropertyDecorator.Model('input', { default: '' }) - ], FormularioField.prototype, "value", void 0); - __decorate([ - vuePropertyDecorator.Prop({ - required: true, - validator: (name) => typeof name === 'string' && name.length > 0, - }) - ], FormularioField.prototype, "name", void 0); - __decorate([ - vuePropertyDecorator.Prop({ default: '' }) - ], FormularioField.prototype, "validation", void 0); - __decorate([ - vuePropertyDecorator.Prop({ default: () => ({}) }) - ], FormularioField.prototype, "validationRules", void 0); - __decorate([ - vuePropertyDecorator.Prop({ default: () => ({}) }) - ], FormularioField.prototype, "validationMessages", void 0); - __decorate([ - vuePropertyDecorator.Prop({ - default: 'demand', - validator: (behavior) => ['demand', 'live', 'submit'].includes(behavior) - }) - ], FormularioField.prototype, "validationBehavior", void 0); - __decorate([ - vuePropertyDecorator.Prop({ default: false }) - ], FormularioField.prototype, "errorsDisabled", void 0); - __decorate([ - vuePropertyDecorator.Prop({ default: () => (value) => value }) - ], FormularioField.prototype, "modelGetConverter", void 0); - __decorate([ - vuePropertyDecorator.Prop({ default: () => (value) => value }) - ], FormularioField.prototype, "modelSetConverter", void 0); - __decorate([ - vuePropertyDecorator.Prop({ default: 'div' }) - ], FormularioField.prototype, "tag", void 0); - __decorate([ - vuePropertyDecorator.Prop({ default: 'none' }) - ], FormularioField.prototype, "unregisterBehavior", void 0); - __decorate([ - vuePropertyDecorator.Watch('value') - ], FormularioField.prototype, "_onValueChange", null); - __decorate([ - vuePropertyDecorator.Watch('proxy') - ], FormularioField.prototype, "_onProxyChange", null); - FormularioField = __decorate([ - vuePropertyDecorator.Component({ name: 'FormularioField', inheritAttrs: false }) - ], FormularioField); - var script = FormularioField; - - function normalizeComponent(template, style, script, scopeId, isFunctionalTemplate, moduleIdentifier /* server only */, shadowMode, createInjector, createInjectorSSR, createInjectorShadow) { - if (typeof shadowMode !== 'boolean') { - createInjectorSSR = createInjector; - createInjector = shadowMode; - shadowMode = false; - } - // Vue.extend constructor export interop. - const options = typeof script === 'function' ? script.options : script; - // render functions - if (template && template.render) { - options.render = template.render; - options.staticRenderFns = template.staticRenderFns; - options._compiled = true; - // functional template - if (isFunctionalTemplate) { - options.functional = true; - } - } - // scopedId - if (scopeId) { - options._scopeId = scopeId; - } - let hook; - if (moduleIdentifier) { - // server build - hook = function (context) { - // 2.3 injection - context = - context || // cached call - (this.$vnode && this.$vnode.ssrContext) || // stateful - (this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext); // functional - // 2.2 with runInNewContext: true - if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') { - context = __VUE_SSR_CONTEXT__; - } - // inject component styles - if (style) { - style.call(this, createInjectorSSR(context)); - } - // register component module identifier for async chunk inference - if (context && context._registeredComponents) { - context._registeredComponents.add(moduleIdentifier); - } - }; - // used by ssr in case component is cached and beforeCreate - // never gets called - options._ssrRegister = hook; - } - else if (style) { - hook = shadowMode - ? function (context) { - style.call(this, createInjectorShadow(context, this.$root.$options.shadowRoot)); - } - : function (context) { - style.call(this, createInjector(context)); - }; - } - if (hook) { - if (options.functional) { - // register for functional component in vue file - const originalRender = options.render; - options.render = function renderWithStyleInjection(h, context) { - hook.call(context); - return originalRender(h, context); - }; - } - else { - // inject component registration as beforeCreate hook - const existing = options.beforeCreate; - options.beforeCreate = existing ? [].concat(existing, hook) : [hook]; - } - } - return script; - } - - /* script */ - const __vue_script__ = script; - - /* template */ - var __vue_render__ = function() { - var _vm = this; - var _h = _vm.$createElement; - var _c = _vm._self._c || _h; - return _c( - _vm.tag, - _vm._b({ tag: "component" }, "component", _vm.$attrs, false), - [_vm._t("default", null, { context: _vm.context })], - 2 - ) - }; - var __vue_staticRenderFns__ = []; - __vue_render__._withStripped = true; - - /* style */ - const __vue_inject_styles__ = undefined; - /* scoped */ - const __vue_scope_id__ = undefined; - /* module identifier */ - const __vue_module_identifier__ = undefined; - /* functional template */ - const __vue_is_functional_template__ = false; - /* style inject */ - - /* style inject SSR */ - - /* style inject shadow dom */ - - - - const __vue_component__ = /*#__PURE__*/normalizeComponent( - { render: __vue_render__, staticRenderFns: __vue_staticRenderFns__ }, - __vue_inject_styles__, - __vue_script__, - __vue_scope_id__, - __vue_is_functional_template__, - __vue_module_identifier__, - false, - undefined, - undefined, - undefined - ); - - let FormularioFieldGroup = class FormularioFieldGroup extends Vue { - get fullPath() { - const path = `${this.name}`; - if (parseInt(path).toString() === path) { - return `${this.__Formulario_path}[${path}]`; - } - if (this.__Formulario_path === '') { - return path; - } - return `${this.__Formulario_path}.${path}`; - } - }; - __decorate([ - vuePropertyDecorator.Inject({ default: '' }) - ], FormularioFieldGroup.prototype, "__Formulario_path", void 0); - __decorate([ - vuePropertyDecorator.Prop({ required: true }) - ], FormularioFieldGroup.prototype, "name", void 0); - __decorate([ - vuePropertyDecorator.Provide('__Formulario_path') - ], FormularioFieldGroup.prototype, "fullPath", null); - FormularioFieldGroup = __decorate([ - vuePropertyDecorator.Component({ name: 'FormularioFieldGroup' }) - ], FormularioFieldGroup); - var script$1 = FormularioFieldGroup; - - /* script */ - const __vue_script__$1 = script$1; - - /* template */ - var __vue_render__$1 = function() { - var _vm = this; - var _h = _vm.$createElement; - var _c = _vm._self._c || _h; - return _c("div", [_vm._t("default")], 2) - }; - var __vue_staticRenderFns__$1 = []; - __vue_render__$1._withStripped = true; - - /* style */ - const __vue_inject_styles__$1 = undefined; - /* scoped */ - const __vue_scope_id__$1 = undefined; - /* module identifier */ - const __vue_module_identifier__$1 = undefined; - /* functional template */ - const __vue_is_functional_template__$1 = false; - /* style inject */ - - /* style inject SSR */ - - /* style inject shadow dom */ - - - - const __vue_component__$1 = /*#__PURE__*/normalizeComponent( - { render: __vue_render__$1, staticRenderFns: __vue_staticRenderFns__$1 }, - __vue_inject_styles__$1, - __vue_script__$1, - __vue_scope_id__$1, - __vue_is_functional_template__$1, - __vue_module_identifier__$1, - false, - undefined, - undefined, - undefined - ); - - const update = (state, path, value) => { - if (value === undefined) { - return unset(state, path); - } - return set(state, path, value); - }; - let FormularioForm = class FormularioForm extends Vue { - constructor() { - super(...arguments); - this.proxy = {}; - this.registry = new Map(); - // Local error messages are temporal, they wiped each resetValidation call - this.localFieldsErrors = {}; - this.localFormErrors = []; - } - get fieldsErrorsComputed() { - return Object.assign(Object.assign({}, this.fieldsErrors), this.localFieldsErrors); - } - get formErrorsComputed() { - return [...this.formErrors, ...this.localFormErrors]; - } - register(path, field) { - if (!this.registry.has(path)) { - this.registry.set(path, field); - } - const value = get(this.proxy, path); - if (!field.hasModel) { - if (value !== undefined) { - field.proxy = value; - } - else { - this.setFieldValue(path, null); - this.emitInput(); - } - } - else if (!deepEquals(field.proxy, value)) { - this.setFieldValue(path, field.proxy); - this.emitInput(); - } - if (has(this.fieldsErrorsComputed, path)) { - field.setErrors(this.fieldsErrorsComputed[path]); - } - } - unregister(path, behavior) { - if (this.registry.has(path)) { - this.registry.delete(path); - if (behavior === 'unset') { - this.proxy = unset(this.proxy, path); - this.emitInput(); - } - } - } - getState() { - return this.proxy; - } - setFieldValue(path, value) { - this.proxy = update(this.proxy, path, value); - } - emitInput() { - this.$emit('input', clone(this.proxy)); - } - emitValidation(path, violations) { - this.$emit('validation', { path, violations }); - } - onStateChange(newState) { - const newProxy = clone(newState); - const oldProxy = this.proxy; - let proxyHasChanges = false; - this.registry.forEach((field, path) => { - const newValue = get(newState, path, null); - const oldValue = get(oldProxy, path, null); - field.proxy = newValue; - if (!deepEquals(newValue, oldValue)) { - field.$emit('input', newValue); - update(newProxy, path, newValue); - proxyHasChanges = true; - } - }); - this.proxy = newProxy; - if (proxyHasChanges) { - this.emitInput(); - } - } - onFieldsErrorsChange(fieldsErrors) { - this.registry.forEach((field, path) => { - field.setErrors(fieldsErrors[path] || []); - }); - } - created() { - this.$formulario.register(this.id, this); - if (typeof this.state === 'object') { - this.proxy = clone(this.state); - } - } - beforeDestroy() { - this.$formulario.unregister(this.id); - } - runValidation() { - const runs = []; - const violations = {}; - this.registry.forEach((field, path) => { - runs.push(field.runValidation().then(v => { violations[path] = v; })); - }); - return Promise.all(runs).then(() => violations); - } - hasValidationErrors() { - return this.runValidation().then(violations => { - return Object.keys(violations).some(path => violations[path].length > 0); - }); - } - setErrors({ formErrors, fieldsErrors }) { - this.localFormErrors = formErrors || []; - this.localFieldsErrors = fieldsErrors || {}; - } - resetValidation() { - this.localFormErrors = []; - this.localFieldsErrors = {}; - this.registry.forEach((field) => { - field.resetValidation(); - }); - } - onSubmit() { - return this.runValidation().then(violations => { - const hasErrors = Object.keys(violations).some(path => violations[path].length > 0); - if (!hasErrors) { - this.$emit('submit', clone(this.proxy)); - } - else { - this.$emit('error', violations); - } - }); - } - }; - __decorate([ - vuePropertyDecorator.Model('input', { default: () => ({}) }) - ], FormularioForm.prototype, "state", void 0); - __decorate([ - vuePropertyDecorator.Prop({ default: () => id('formulario-form') }) - ], FormularioForm.prototype, "id", void 0); - __decorate([ - vuePropertyDecorator.Prop({ default: () => ({}) }) - ], FormularioForm.prototype, "fieldsErrors", void 0); - __decorate([ - vuePropertyDecorator.Prop({ default: () => ([]) }) - ], FormularioForm.prototype, "formErrors", void 0); - __decorate([ - vuePropertyDecorator.Provide('__FormularioForm_register') - ], FormularioForm.prototype, "register", null); - __decorate([ - vuePropertyDecorator.Provide('__FormularioForm_unregister') - ], FormularioForm.prototype, "unregister", null); - __decorate([ - vuePropertyDecorator.Provide('__FormularioForm_getState') - ], FormularioForm.prototype, "getState", null); - __decorate([ - vuePropertyDecorator.Provide('__FormularioForm_set') - ], FormularioForm.prototype, "setFieldValue", null); - __decorate([ - vuePropertyDecorator.Provide('__FormularioForm_emitInput') - ], FormularioForm.prototype, "emitInput", null); - __decorate([ - vuePropertyDecorator.Provide('__FormularioForm_emitValidation') - ], FormularioForm.prototype, "emitValidation", null); - __decorate([ - vuePropertyDecorator.Watch('state', { deep: true }) - ], FormularioForm.prototype, "onStateChange", null); - __decorate([ - vuePropertyDecorator.Watch('fieldsErrorsComputed', { deep: true, immediate: true }) - ], FormularioForm.prototype, "onFieldsErrorsChange", null); - FormularioForm = __decorate([ - vuePropertyDecorator.Component({ name: 'FormularioForm' }) - ], FormularioForm); - var script$2 = FormularioForm; - - /* script */ - const __vue_script__$2 = script$2; - - /* template */ - var __vue_render__$2 = function() { - var _vm = this; - var _h = _vm.$createElement; - var _c = _vm._self._c || _h; - return _c( - "form", - { - on: { - submit: function($event) { - $event.preventDefault(); - return _vm.onSubmit($event) - } - } - }, - [_vm._t("default", null, { errors: _vm.formErrorsComputed })], - 2 - ) - }; - var __vue_staticRenderFns__$2 = []; - __vue_render__$2._withStripped = true; - - /* style */ - const __vue_inject_styles__$2 = undefined; - /* scoped */ - const __vue_scope_id__$2 = undefined; - /* module identifier */ - const __vue_module_identifier__$2 = undefined; - /* functional template */ - const __vue_is_functional_template__$2 = false; - /* style inject */ - - /* style inject SSR */ - - /* style inject shadow dom */ - - - - const __vue_component__$2 = /*#__PURE__*/normalizeComponent( - { render: __vue_render__$2, staticRenderFns: __vue_staticRenderFns__$2 }, - __vue_inject_styles__$2, - __vue_script__$2, - __vue_scope_id__$2, - __vue_is_functional_template__$2, - __vue_module_identifier__$2, - false, - undefined, - undefined, - undefined - ); - - var index = { - Formulario, - install(Vue, options) { - Vue.component('FormularioField', __vue_component__); - Vue.component('FormularioFieldGroup', __vue_component__$1); - Vue.component('FormularioForm', __vue_component__$2); - Vue.mixin({ - beforeCreate() { - const o = this.$options; - if (typeof o.formulario === 'function') { - this.$formulario = o.formulario(); - } - else if (o.parent && o.parent.$formulario) { - this.$formulario = o.parent.$formulario; - } - else { - this.$formulario = new Formulario(options); - } - } - }); - }, - }; - - exports.Formulario = Formulario; - exports.FormularioField = __vue_component__; - exports.FormularioFieldGroup = __vue_component__$1; - exports.FormularioForm = __vue_component__$2; - exports.default = index; - - Object.defineProperty(exports, '__esModule', { value: true }); - -})));