chore: Additional typehints, Object/ObjectType replaced with Record<string, any>
This commit is contained in:
parent
a3eb14a745
commit
54bf820824
18
.eslintrc.js
18
.eslintrc.js
@ -6,11 +6,14 @@ module.exports = {
|
||||
sourceType: 'module',
|
||||
},
|
||||
|
||||
plugins: ['@typescript-eslint'],
|
||||
|
||||
// https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style
|
||||
extends: [
|
||||
'standard',
|
||||
'@vue/standard',
|
||||
'@vue/typescript',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:vue/recommended',
|
||||
],
|
||||
|
||||
@ -19,17 +22,18 @@ module.exports = {
|
||||
},
|
||||
|
||||
rules: {
|
||||
// allow paren-less arrow functions
|
||||
'@typescript-eslint/ban-ts-ignore': 'off', // @TODO
|
||||
'@typescript-eslint/no-empty-function': 'off',
|
||||
'@typescript-eslint/no-explicit-any': 'off', // @TODO
|
||||
'@typescript-eslint/no-unused-vars': ['error'], // @TODO
|
||||
'arrow-parens': 0,
|
||||
'comma-dangle': ['error', 'only-multiline'],
|
||||
'indent': ['error', 4, { SwitchCase: 1 }],
|
||||
'max-depth': ['error', 3],
|
||||
'max-lines-per-function': ['error', 40],
|
||||
'no-console': ['warn', {allow: ['warn', 'error']}],
|
||||
// allow debugger during development
|
||||
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
|
||||
'no-unused-vars': 'off',
|
||||
'@typescript-eslint/no-unused-vars': ['error'],
|
||||
'vue/html-closing-bracket-spacing': ['error', {
|
||||
startTag: 'never',
|
||||
endTag: 'never',
|
||||
@ -42,4 +46,12 @@ module.exports = {
|
||||
ignores: [],
|
||||
}],
|
||||
},
|
||||
|
||||
overrides: [{
|
||||
files: ['*/**/shims-*.d.ts'],
|
||||
rules: {
|
||||
'@typescript-eslint/no-empty-interface': 'off',
|
||||
'@typescript-eslint/no-unused-vars': 'off',
|
||||
},
|
||||
}],
|
||||
}
|
||||
|
@ -1,26 +1,25 @@
|
||||
import nanoid from 'nanoid/non-secure'
|
||||
import { AxiosResponse, AxiosError } from '@/axios.types'
|
||||
import { ObjectType } from '@/common.types'
|
||||
|
||||
interface FileItem {
|
||||
uuid: string
|
||||
name: string
|
||||
path: string | false
|
||||
progress: number | false
|
||||
error: any | false
|
||||
complete: boolean
|
||||
file: File
|
||||
justFinished: boolean
|
||||
removeFile(): void
|
||||
previewData: string | false
|
||||
uuid: string;
|
||||
name: string;
|
||||
path: string | false;
|
||||
progress: number | false;
|
||||
error: any | false;
|
||||
complete: boolean;
|
||||
file: File;
|
||||
justFinished: boolean;
|
||||
removeFile(): void;
|
||||
previewData: string | false;
|
||||
}
|
||||
|
||||
interface ProgressSetter {
|
||||
(progress: number): void
|
||||
(progress: number): void;
|
||||
}
|
||||
|
||||
interface ErrorHandler {
|
||||
(error: AxiosError): any
|
||||
(error: AxiosError): any;
|
||||
}
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
@ -32,11 +31,11 @@ class FileUpload {
|
||||
public input: DataTransfer
|
||||
public fileList: FileList
|
||||
public files: FileItem[]
|
||||
public options: ObjectType
|
||||
public context: ObjectType
|
||||
public options: Record<string, any>
|
||||
public context: Record<string, any>
|
||||
public results: any[] | boolean
|
||||
|
||||
constructor (input: DataTransfer, context: ObjectType = {}, options: ObjectType = {}) {
|
||||
constructor (input: DataTransfer, context: Record<string, any> = {}, options: Record<string, any> = {}) {
|
||||
this.input = input
|
||||
this.fileList = input.files
|
||||
this.files = []
|
||||
@ -54,7 +53,7 @@ class FileUpload {
|
||||
* Given a pre-existing array of files, create a faux FileList.
|
||||
* @param {array} items expects an array of objects [{ url: '/uploads/file.pdf' }]
|
||||
*/
|
||||
rehydrateFileList (items: any[]) {
|
||||
rehydrateFileList (items: any[]): void {
|
||||
const fauxFileList = items.reduce((fileList, item) => {
|
||||
const key = this.options ? this.options.fileUrlKey : 'url'
|
||||
const url = item[key]
|
||||
@ -75,7 +74,7 @@ class FileUpload {
|
||||
* Produce an array of files and alert the callback.
|
||||
* @param {FileList} fileList
|
||||
*/
|
||||
addFileList (fileList: FileList) {
|
||||
addFileList (fileList: FileList): void {
|
||||
for (let i = 0; i < fileList.length; i++) {
|
||||
const file: File = fileList[i]
|
||||
const uuid = nanoid()
|
||||
@ -98,7 +97,7 @@ class FileUpload {
|
||||
/**
|
||||
* Check if the file has an.
|
||||
*/
|
||||
hasUploader () {
|
||||
hasUploader (): boolean {
|
||||
return !!this.context.uploader
|
||||
}
|
||||
|
||||
@ -108,7 +107,7 @@ class FileUpload {
|
||||
*
|
||||
* https://github.com/axios/axios/issues/737
|
||||
*/
|
||||
uploaderIsAxios () {
|
||||
uploaderIsAxios (): boolean {
|
||||
return this.hasUploader &&
|
||||
typeof this.context.uploader.request === 'function' &&
|
||||
typeof this.context.uploader.get === 'function' &&
|
||||
@ -119,7 +118,7 @@ class FileUpload {
|
||||
/**
|
||||
* Get a new uploader function.
|
||||
*/
|
||||
getUploader (...args: [File, ProgressSetter, ErrorHandler, ObjectType]) {
|
||||
getUploader (...args: [File, ProgressSetter, ErrorHandler, Record<string, any>]) {
|
||||
if (this.uploaderIsAxios()) {
|
||||
const data = new FormData()
|
||||
data.append(this.context.name || 'file', args[0])
|
||||
@ -184,7 +183,7 @@ class FileUpload {
|
||||
/**
|
||||
* Remove a file from the uploader (and the file list)
|
||||
*/
|
||||
removeFile (uuid: string) {
|
||||
removeFile (uuid: string): void {
|
||||
this.files = this.files.filter(file => file.uuid !== uuid)
|
||||
this.context.performValidation()
|
||||
if (window && this.fileList instanceof FileList) {
|
||||
@ -223,7 +222,7 @@ class FileUpload {
|
||||
return this.files
|
||||
}
|
||||
|
||||
toString () {
|
||||
toString (): string {
|
||||
const descriptor = this.files.length ? this.files.length + ' files' : 'empty'
|
||||
return this.results ? JSON.stringify(this.results, null, ' ') : `FileUpload(${descriptor})`
|
||||
}
|
||||
|
@ -15,18 +15,15 @@ export default class FormSubmission {
|
||||
|
||||
/**
|
||||
* Determine if the form has any validation errors.
|
||||
*
|
||||
* @return {Promise} resolves a boolean
|
||||
*/
|
||||
hasValidationErrors () {
|
||||
hasValidationErrors (): Promise<boolean> {
|
||||
return (this.form as any).hasValidationErrors()
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously generate the values payload of this form.
|
||||
* @return {Promise} resolves to json
|
||||
*/
|
||||
values () {
|
||||
values (): Promise<Record<string, any>> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const form = this.form as any
|
||||
const pending = []
|
||||
@ -36,9 +33,10 @@ export default class FormSubmission {
|
||||
if (
|
||||
Object.prototype.hasOwnProperty.call(values, key) &&
|
||||
typeof form.proxy[key] === 'object' &&
|
||||
form.proxy[key] instanceof FileUpload) {
|
||||
form.proxy[key] instanceof FileUpload
|
||||
) {
|
||||
pending.push(
|
||||
form.proxy[key].upload().then((data: Object) => Object.assign(values, { [key]: data }))
|
||||
form.proxy[key].upload().then((data: Record<string, any>) => Object.assign(values, { [key]: data }))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -12,27 +12,26 @@ import merge from '@/utils/merge'
|
||||
import FormularioForm from '@/FormularioForm.vue'
|
||||
import FormularioInput from '@/FormularioInput.vue'
|
||||
import FormularioGrouping from '@/FormularioGrouping.vue'
|
||||
import { ObjectType } from '@/common.types'
|
||||
import { ValidationContext } from '@/validation/types'
|
||||
|
||||
interface ErrorHandler {
|
||||
(error: any, formName?: string): any
|
||||
(error: any, formName?: string): any;
|
||||
}
|
||||
|
||||
interface FormularioOptions {
|
||||
components?: { [name: string]: VueConstructor }
|
||||
plugins?: any[]
|
||||
library?: any
|
||||
rules?: any
|
||||
mimes?: any
|
||||
locale?: any
|
||||
uploader?: any
|
||||
uploadUrl?: any
|
||||
fileUrlKey?: any
|
||||
errorHandler?: ErrorHandler
|
||||
uploadJustCompleteDuration?: any
|
||||
validationMessages?: any
|
||||
idPrefix?: string
|
||||
components?: { [name: string]: VueConstructor };
|
||||
plugins?: any[];
|
||||
library?: any;
|
||||
rules?: any;
|
||||
mimes?: any;
|
||||
locale?: any;
|
||||
uploader?: any;
|
||||
uploadUrl?: any;
|
||||
fileUrlKey?: any;
|
||||
errorHandler?: ErrorHandler;
|
||||
uploadJustCompleteDuration?: any;
|
||||
validationMessages?: any;
|
||||
idPrefix?: string;
|
||||
}
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
@ -122,7 +121,7 @@ export default class Formulario {
|
||||
/**
|
||||
* Get validation rules by merging any passed in with global rules.
|
||||
*/
|
||||
rules (rules: Object = {}) {
|
||||
rules (rules: Record<string, any> = {}) {
|
||||
return { ...this.options.rules, ...rules }
|
||||
}
|
||||
|
||||
@ -206,7 +205,7 @@ export default class Formulario {
|
||||
/**
|
||||
* Set the form values.
|
||||
*/
|
||||
setValues (formName: string, values?: ObjectType) {
|
||||
setValues (formName: string, values?: Record<string, any>) {
|
||||
if (values) {
|
||||
const form = this.registry.get(formName) as FormularioForm
|
||||
// @ts-ignore
|
||||
@ -224,7 +223,7 @@ export default class Formulario {
|
||||
/**
|
||||
* Get the global upload url.
|
||||
*/
|
||||
getUploadUrl () {
|
||||
getUploadUrl (): string | boolean {
|
||||
return this.options.uploadUrl || false
|
||||
}
|
||||
|
||||
@ -239,7 +238,7 @@ export default class Formulario {
|
||||
/**
|
||||
* Create a new instance of an upload.
|
||||
*/
|
||||
createUpload (data: DataTransfer, context: ObjectType) {
|
||||
createUpload (data: DataTransfer, context: Record<string, any>) {
|
||||
return new FileUpload(data, context, this.options)
|
||||
}
|
||||
}
|
||||
|
@ -14,32 +14,31 @@ import {
|
||||
Watch,
|
||||
} from 'vue-property-decorator'
|
||||
import { arrayify, getNested, has, setNested, shallowEqualObjects } from '@/libs/utils'
|
||||
import { ObjectType } from '@/common.types'
|
||||
import Registry from '@/libs/registry'
|
||||
import FormSubmission from '@/FormSubmission'
|
||||
import FormularioInput from '@/FormularioInput.vue'
|
||||
|
||||
@Component
|
||||
export default class FormularioForm extends Vue {
|
||||
@Provide() formularioFieldValidation (errorObject) {
|
||||
return this.$emit('validation', errorObject)
|
||||
@Provide() formularioFieldValidation (errorObject): void {
|
||||
this.$emit('validation', errorObject)
|
||||
}
|
||||
|
||||
@Provide() formularioRegister = this.register
|
||||
@Provide() formularioDeregister = this.deregister
|
||||
@Provide() formularioSetter = this.setFieldValue
|
||||
@Provide() getFormValues = () => this.proxy
|
||||
@Provide() getFormValues = (): Record<string, any> => this.proxy
|
||||
@Provide() observeErrors = this.addErrorObserver
|
||||
@Provide() path: string = ''
|
||||
@Provide() path = ''
|
||||
|
||||
@Provide() removeErrorObserver (observer) {
|
||||
@Provide() removeErrorObserver (observer): void {
|
||||
this.errorObservers = this.errorObservers.filter(obs => obs.callback !== observer)
|
||||
}
|
||||
|
||||
@Model('input', {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}) readonly formularioValue!: Object
|
||||
}) readonly formularioValue!: Record<string, any>
|
||||
|
||||
@Prop({
|
||||
type: [String, Boolean],
|
||||
@ -49,31 +48,31 @@ export default class FormularioForm extends Vue {
|
||||
@Prop({
|
||||
type: [Object, Boolean],
|
||||
default: false
|
||||
}) readonly values!: Object | Boolean
|
||||
}) readonly values!: Record<string, any> | boolean
|
||||
|
||||
@Prop({
|
||||
type: [Object, Boolean],
|
||||
default: false
|
||||
}) readonly errors!: Object | Boolean
|
||||
}) readonly errors!: Record<string, any> | boolean
|
||||
|
||||
@Prop({
|
||||
type: Array,
|
||||
default: () => ([])
|
||||
}) readonly formErrors!: []
|
||||
|
||||
public proxy: Object = {}
|
||||
public proxy: Record<string, any> = {}
|
||||
|
||||
registry: Registry = new Registry(this)
|
||||
|
||||
childrenShouldShowErrors: boolean = false
|
||||
childrenShouldShowErrors = false
|
||||
|
||||
formShouldShowErrors: boolean = false
|
||||
formShouldShowErrors = false
|
||||
|
||||
errorObservers: [] = []
|
||||
|
||||
namedErrors: [] = []
|
||||
|
||||
namedFieldErrors: Object = {}
|
||||
namedFieldErrors: Record<string, any> = {}
|
||||
|
||||
get mergedFormErrors () {
|
||||
return this.formErrors.concat(this.namedErrors)
|
||||
@ -95,11 +94,11 @@ export default class FormularioForm extends Vue {
|
||||
return errors
|
||||
}
|
||||
|
||||
get hasFormErrorObservers () {
|
||||
get hasFormErrorObservers (): boolean {
|
||||
return this.errorObservers.some(o => o.type === 'form')
|
||||
}
|
||||
|
||||
get hasInitialValue () {
|
||||
get hasInitialValue (): boolean {
|
||||
return (
|
||||
(this.formularioValue && typeof this.formularioValue === 'object') ||
|
||||
(this.values && typeof this.values === 'object') ||
|
||||
@ -107,14 +106,14 @@ export default class FormularioForm extends Vue {
|
||||
)
|
||||
}
|
||||
|
||||
get isVmodeled () {
|
||||
get isVmodeled (): boolean {
|
||||
return !!(has(this.$options.propsData, 'formularioValue') &&
|
||||
this._events &&
|
||||
Array.isArray(this._events.input) &&
|
||||
this._events.input.length)
|
||||
}
|
||||
|
||||
get initialValues () {
|
||||
get initialValues (): Record<string, any> {
|
||||
if (
|
||||
has(this.$options.propsData, 'formularioValue') &&
|
||||
typeof this.formularioValue === 'object'
|
||||
@ -136,50 +135,50 @@ export default class FormularioForm extends Vue {
|
||||
}
|
||||
|
||||
@Watch('formularioValue', { deep: true })
|
||||
onFormularioValueChanged (values) {
|
||||
onFormularioValueChanged (values): void {
|
||||
if (this.isVmodeled && values && typeof values === 'object') {
|
||||
this.setValues(values)
|
||||
}
|
||||
}
|
||||
|
||||
@Watch('mergedFormErrors')
|
||||
onMergedFormErrorsChanged (errors) {
|
||||
onMergedFormErrorsChanged (errors): void {
|
||||
this.errorObservers
|
||||
.filter(o => o.type === 'form')
|
||||
.forEach(o => o.callback(errors))
|
||||
}
|
||||
|
||||
@Watch('mergedFieldErrors', { immediate: true })
|
||||
onMergedFieldErrorsChanged (errors) {
|
||||
onMergedFieldErrorsChanged (errors): void {
|
||||
this.errorObservers
|
||||
.filter(o => o.type === 'input')
|
||||
.forEach(o => o.callback(errors[o.field] || []))
|
||||
}
|
||||
|
||||
created () {
|
||||
created (): void {
|
||||
this.$formulario.register(this)
|
||||
this.applyInitialValues()
|
||||
}
|
||||
|
||||
destroyed () {
|
||||
destroyed (): void {
|
||||
this.$formulario.deregister(this)
|
||||
}
|
||||
|
||||
public register (field: string, component: FormularioInput) {
|
||||
public register (field: string, component: FormularioInput): void {
|
||||
this.registry.register(field, component)
|
||||
}
|
||||
|
||||
public deregister (field: string) {
|
||||
public deregister (field: string): void {
|
||||
this.registry.remove(field)
|
||||
}
|
||||
|
||||
applyErrors ({ formErrors, inputErrors }) {
|
||||
applyErrors ({ formErrors, inputErrors }): void {
|
||||
// given an object of errors, apply them to this form
|
||||
this.namedErrors = formErrors
|
||||
this.namedFieldErrors = inputErrors
|
||||
}
|
||||
|
||||
addErrorObserver (observer) {
|
||||
addErrorObserver (observer): void {
|
||||
if (!this.errorObservers.find(obs => observer.callback === obs.callback)) {
|
||||
this.errorObservers.push(observer)
|
||||
if (observer.type === 'form') {
|
||||
@ -190,13 +189,13 @@ export default class FormularioForm extends Vue {
|
||||
}
|
||||
}
|
||||
|
||||
registerErrorComponent (component) {
|
||||
registerErrorComponent (component): void {
|
||||
if (!this.errorComponents.includes(component)) {
|
||||
this.errorComponents.push(component)
|
||||
}
|
||||
}
|
||||
|
||||
formSubmitted () {
|
||||
formSubmitted (): Promise<void> {
|
||||
// perform validation here
|
||||
this.showErrors()
|
||||
const submission = new FormSubmission(this)
|
||||
@ -208,17 +207,16 @@ export default class FormularioForm extends Vue {
|
||||
this.$emit('submit', data)
|
||||
return data
|
||||
}
|
||||
return undefined
|
||||
})
|
||||
}
|
||||
|
||||
applyInitialValues () {
|
||||
applyInitialValues (): void {
|
||||
if (this.hasInitialValue) {
|
||||
this.proxy = this.initialValues
|
||||
}
|
||||
}
|
||||
|
||||
setFieldValue (field, value) {
|
||||
setFieldValue (field, value): void {
|
||||
if (value === undefined) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const { [field]: value, ...proxy } = this.proxy
|
||||
@ -229,21 +227,21 @@ export default class FormularioForm extends Vue {
|
||||
this.$emit('input', Object.assign({}, this.proxy))
|
||||
}
|
||||
|
||||
hasValidationErrors () {
|
||||
hasValidationErrors (): Promise<boolean> {
|
||||
return Promise.all(this.registry.reduce((resolvers, cmp) => {
|
||||
resolvers.push(cmp.performValidation() && cmp.getValidationErrors())
|
||||
return resolvers
|
||||
}, [])).then(errorObjects => errorObjects.some(item => item.hasErrors))
|
||||
}
|
||||
|
||||
showErrors () {
|
||||
showErrors (): void {
|
||||
this.childrenShouldShowErrors = true
|
||||
this.registry.forEach((input: FormularioInput) => {
|
||||
input.formShouldShowErrors = true
|
||||
})
|
||||
}
|
||||
|
||||
hideErrors () {
|
||||
hideErrors (): void {
|
||||
this.childrenShouldShowErrors = false
|
||||
this.registry.forEach((input: FormularioInput) => {
|
||||
input.formShouldShowErrors = false
|
||||
@ -251,7 +249,7 @@ export default class FormularioForm extends Vue {
|
||||
})
|
||||
}
|
||||
|
||||
setValues (values: ObjectType) {
|
||||
setValues (values: Record<string, any>): void {
|
||||
// Collect all keys, existing and incoming
|
||||
const keys = Array.from(new Set(Object.keys(values).concat(Object.keys(this.proxy))))
|
||||
keys.forEach(field => {
|
||||
|
@ -26,7 +26,6 @@ import {
|
||||
} from 'vue-property-decorator'
|
||||
import { shallowEqualObjects, parseRules, snakeToCamel, has, arrayify, groupBails } from './libs/utils'
|
||||
import { ValidationError } from '@/validation/types'
|
||||
import { ObjectType } from '@/common.types'
|
||||
|
||||
const ERROR_BEHAVIOR = {
|
||||
BLUR: 'blur',
|
||||
@ -37,10 +36,10 @@ const ERROR_BEHAVIOR = {
|
||||
@Component({ inheritAttrs: false })
|
||||
export default class FormularioInput extends Vue {
|
||||
@Inject({ default: undefined }) formularioSetter!: Function|undefined
|
||||
@Inject({ default: () => () => ({}) }) formularioFieldValidation!: Function
|
||||
@Inject({ default: () => (): void => {} }) formularioFieldValidation!: Function
|
||||
@Inject({ default: undefined }) formularioRegister!: Function|undefined
|
||||
@Inject({ default: undefined }) formularioDeregister!: Function|undefined
|
||||
@Inject({ default: () => () => ({}) }) getFormValues!: Function
|
||||
@Inject({ default: () => (): Record<string, any> => ({}) }) getFormValues!: Function
|
||||
@Inject({ default: undefined }) observeErrors!: Function|undefined
|
||||
@Inject({ default: undefined }) removeErrorObserver!: Function|undefined
|
||||
@Inject({ default: '' }) path!: string
|
||||
@ -74,12 +73,12 @@ export default class FormularioInput extends Vue {
|
||||
@Prop({
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
}) validationRules!: ObjectType
|
||||
}) validationRules!: Record<string, any>
|
||||
|
||||
@Prop({
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
}) validationMessages!: ObjectType
|
||||
}) validationMessages!: Record<string, any>
|
||||
|
||||
@Prop({
|
||||
type: [Array, String, Boolean],
|
||||
@ -96,23 +95,23 @@ export default class FormularioInput extends Vue {
|
||||
@Prop({ default: false }) disableErrors!: boolean
|
||||
@Prop({ default: true }) preventWindowDrops!: boolean
|
||||
@Prop({ default: 'preview' }) imageBehavior!: string
|
||||
@Prop({ default: false }) uploader!: Function|Object|boolean
|
||||
@Prop({ default: false }) uploader!: Function|Record<string, any>|boolean
|
||||
@Prop({ default: false }) uploadUrl!: string|boolean
|
||||
@Prop({ default: 'live' }) uploadBehavior!: string
|
||||
|
||||
defaultId: string = this.$formulario.nextId(this)
|
||||
localAttributes: ObjectType = {}
|
||||
localAttributes: Record<string, any> = {}
|
||||
localErrors: ValidationError[] = []
|
||||
proxy: ObjectType = this.getInitialValue()
|
||||
proxy: Record<string, any> = this.getInitialValue()
|
||||
behavioralErrorVisibility: boolean = this.errorBehavior === 'live'
|
||||
formShouldShowErrors: boolean = false
|
||||
formShouldShowErrors = false
|
||||
validationErrors: [] = []
|
||||
pendingValidation: Promise<any> = Promise.resolve()
|
||||
// These registries are used for injected messages registrants only (mostly internal).
|
||||
ruleRegistry: [] = []
|
||||
messageRegistry: ObjectType = {}
|
||||
messageRegistry: Record<string, any> = {}
|
||||
|
||||
get context () {
|
||||
get context (): Record<string, any> {
|
||||
return this.defineModel({
|
||||
attributes: this.elementAttributes,
|
||||
blurHandler: this.blurHandler.bind(this),
|
||||
@ -164,7 +163,7 @@ export default class FormularioInput extends Vue {
|
||||
/**
|
||||
* Reducer for attributes that will be applied to each core input element.
|
||||
*/
|
||||
get elementAttributes () {
|
||||
get elementAttributes (): Record<string, any> {
|
||||
const attrs = Object.assign({}, this.localAttributes)
|
||||
// pass the ID prop through to the root element
|
||||
if (this.id) {
|
||||
@ -188,14 +187,14 @@ export default class FormularioInput extends Vue {
|
||||
/**
|
||||
* Return the element’s name, or select a fallback.
|
||||
*/
|
||||
get nameOrFallback () {
|
||||
get nameOrFallback (): string {
|
||||
return this.path !== '' ? `${this.path}.${this.name}` : this.name
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if an input has a user-defined name.
|
||||
*/
|
||||
get hasGivenName () {
|
||||
get hasGivenName (): boolean {
|
||||
return typeof this.name !== 'boolean'
|
||||
}
|
||||
|
||||
@ -210,21 +209,21 @@ export default class FormularioInput extends Vue {
|
||||
* Use the uploadURL on the input if it exists, otherwise use the uploadURL
|
||||
* that is defined as a plugin option.
|
||||
*/
|
||||
get mergedUploadUrl () {
|
||||
get mergedUploadUrl (): string | boolean {
|
||||
return this.uploadUrl || this.$formulario.getUploadUrl()
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this computed property have errors
|
||||
*/
|
||||
get hasErrors () {
|
||||
get hasErrors (): boolean {
|
||||
return this.allErrors.length > 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if form has actively visible errors (of any kind)
|
||||
*/
|
||||
get hasVisibleErrors () {
|
||||
get hasVisibleErrors (): boolean {
|
||||
return ((this.validationErrors && this.showValidationErrors) || !!this.explicitErrors.length)
|
||||
}
|
||||
|
||||
@ -275,12 +274,12 @@ export default class FormularioInput extends Vue {
|
||||
}
|
||||
|
||||
@Watch('$attrs', { deep: true })
|
||||
onAttrsChanged (value) {
|
||||
onAttrsChanged (value): void {
|
||||
this.updateLocalAttributes(value)
|
||||
}
|
||||
|
||||
@Watch('proxy')
|
||||
onProxyChanged (newValue, oldValue) {
|
||||
onProxyChanged (newValue, oldValue): void {
|
||||
this.performValidation()
|
||||
if (!this.isVmodeled && !shallowEqualObjects(newValue, oldValue)) {
|
||||
this.context.model = newValue
|
||||
@ -288,18 +287,18 @@ export default class FormularioInput extends Vue {
|
||||
}
|
||||
|
||||
@Watch('formularioValue')
|
||||
onFormularioValueChanged (newValue, oldValue) {
|
||||
onFormularioValueChanged (newValue, oldValue): void {
|
||||
if (this.isVmodeled && !shallowEqualObjects(newValue, oldValue)) {
|
||||
this.context.model = newValue
|
||||
}
|
||||
}
|
||||
|
||||
@Watch('showValidationErrors', { immediate: true })
|
||||
onShowValidationErrorsChanged (val) {
|
||||
onShowValidationErrorsChanged (val): void {
|
||||
this.$emit('error-visibility', val)
|
||||
}
|
||||
|
||||
created () {
|
||||
created (): void {
|
||||
this.applyInitialValue()
|
||||
if (this.formularioRegister && typeof this.formularioRegister === 'function') {
|
||||
this.formularioRegister(this.nameOrFallback, this)
|
||||
@ -312,7 +311,7 @@ export default class FormularioInput extends Vue {
|
||||
}
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
beforeDestroy () {
|
||||
beforeDestroy (): void {
|
||||
if (!this.disableErrors && typeof this.removeErrorObserver === 'function') {
|
||||
this.removeErrorObserver(this.setErrors)
|
||||
}
|
||||
@ -346,7 +345,7 @@ export default class FormularioInput extends Vue {
|
||||
/**
|
||||
* Set the value from a model.
|
||||
*/
|
||||
modelSetter (value) {
|
||||
modelSetter (value): void {
|
||||
if (!shallowEqualObjects(value, this.proxy)) {
|
||||
this.proxy = value
|
||||
}
|
||||
@ -366,16 +365,16 @@ export default class FormularioInput extends Vue {
|
||||
}
|
||||
}
|
||||
|
||||
getInitialValue () {
|
||||
if (has(this.$options.propsData as ObjectType, 'value')) {
|
||||
getInitialValue (): any {
|
||||
if (has(this.$options.propsData as Record<string, any>, 'value')) {
|
||||
return this.value
|
||||
} else if (has(this.$options.propsData as ObjectType, 'formularioValue')) {
|
||||
} else if (has(this.$options.propsData as Record<string, any>, 'formularioValue')) {
|
||||
return this.formularioValue
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
applyInitialValue () {
|
||||
applyInitialValue (): void {
|
||||
// This should only be run immediately on created and ensures that the
|
||||
// proxy and the model are both the same before any additional registration.
|
||||
if (!shallowEqualObjects(this.context.model, this.proxy)) {
|
||||
@ -383,7 +382,7 @@ export default class FormularioInput extends Vue {
|
||||
}
|
||||
}
|
||||
|
||||
updateLocalAttributes (value) {
|
||||
updateLocalAttributes (value): void {
|
||||
if (!shallowEqualObjects(value, this.localAttributes)) {
|
||||
this.localAttributes = value
|
||||
}
|
||||
@ -432,7 +431,7 @@ export default class FormularioInput extends Vue {
|
||||
})
|
||||
}
|
||||
|
||||
didValidate (messages) {
|
||||
didValidate (messages): void {
|
||||
const validationChanged = !shallowEqualObjects(messages, this.validationErrors)
|
||||
this.validationErrors = messages
|
||||
if (validationChanged) {
|
||||
@ -461,7 +460,7 @@ export default class FormularioInput extends Vue {
|
||||
}
|
||||
}
|
||||
|
||||
getMessageFunc (ruleName) {
|
||||
getMessageFunc (ruleName: string) {
|
||||
ruleName = snakeToCamel(ruleName)
|
||||
if (this.messages && typeof this.messages[ruleName] !== 'undefined') {
|
||||
switch (typeof this.messages[ruleName]) {
|
||||
@ -497,11 +496,11 @@ export default class FormularioInput extends Vue {
|
||||
}
|
||||
}
|
||||
|
||||
setErrors (errors) {
|
||||
setErrors (errors): void {
|
||||
this.localErrors = arrayify(errors)
|
||||
}
|
||||
|
||||
registerRule (rule, args, ruleName, message = null) {
|
||||
registerRule (rule, args, ruleName, message = null): void {
|
||||
if (!this.ruleRegistry.some(r => r[2] === ruleName)) {
|
||||
// These are the raw rule format since they will be used directly.
|
||||
this.ruleRegistry.push([rule, args, ruleName])
|
||||
@ -511,7 +510,7 @@ export default class FormularioInput extends Vue {
|
||||
}
|
||||
}
|
||||
|
||||
removeRule (key) {
|
||||
removeRule (key): void {
|
||||
const ruleIndex = this.ruleRegistry.findIndex(r => r[2] === key)
|
||||
if (ruleIndex >= 0) {
|
||||
this.ruleRegistry.splice(ruleIndex, 1)
|
||||
|
@ -46,14 +46,14 @@ const validationMessages = {
|
||||
/**
|
||||
* The value is not a letter.
|
||||
*/
|
||||
alpha (vm: FormularioInput, context: Object): string {
|
||||
alpha (vm: FormularioInput, context: Record<string, any>): string {
|
||||
return vm.$t('validation.alpha', context)
|
||||
},
|
||||
|
||||
/**
|
||||
* Rule: checks if the value is alpha numeric
|
||||
*/
|
||||
alphanumeric (vm: FormularioInput, context: Object): string {
|
||||
alphanumeric (vm: FormularioInput, context: Record<string, any>): string {
|
||||
return vm.$t('validation.alphanumeric', context)
|
||||
},
|
||||
|
||||
@ -116,7 +116,7 @@ const validationMessages = {
|
||||
/**
|
||||
* Value is an allowed value.
|
||||
*/
|
||||
in: function (vm: FormularioInput, context: ValidationContext) {
|
||||
in: function (vm: FormularioInput, context: ValidationContext): string {
|
||||
if (typeof context.value === 'string' && context.value) {
|
||||
return vm.$t('validation.in.string', context)
|
||||
}
|
||||
@ -127,14 +127,14 @@ const validationMessages = {
|
||||
/**
|
||||
* Value is not a match.
|
||||
*/
|
||||
matches (vm: FormularioInput, context: ValidationContext) {
|
||||
matches (vm: FormularioInput, context: ValidationContext): string {
|
||||
return vm.$t('validation.matches.default', context)
|
||||
},
|
||||
|
||||
/**
|
||||
* The maximum value allowed.
|
||||
*/
|
||||
max (vm: FormularioInput, context: ValidationContext) {
|
||||
max (vm: FormularioInput, context: ValidationContext): string {
|
||||
const maximum = context.args[0] as number
|
||||
|
||||
if (Array.isArray(context.value)) {
|
||||
@ -150,7 +150,7 @@ const validationMessages = {
|
||||
/**
|
||||
* The (field-level) error message for mime errors.
|
||||
*/
|
||||
mime (vm: FormularioInput, context: ValidationContext) {
|
||||
mime (vm: FormularioInput, context: ValidationContext): string {
|
||||
const types = context.args[0]
|
||||
|
||||
if (types) {
|
||||
@ -163,7 +163,7 @@ const validationMessages = {
|
||||
/**
|
||||
* The maximum value allowed.
|
||||
*/
|
||||
min (vm: FormularioInput, context: ValidationContext) {
|
||||
min (vm: FormularioInput, context: ValidationContext): string {
|
||||
const minimum = context.args[0] as number
|
||||
|
||||
if (Array.isArray(context.value)) {
|
||||
@ -179,35 +179,35 @@ const validationMessages = {
|
||||
/**
|
||||
* The field is not an allowed value
|
||||
*/
|
||||
not (vm: FormularioInput, context: Object) {
|
||||
not (vm: FormularioInput, context: Record<string, any>): string {
|
||||
return vm.$t('validation.not.default', context)
|
||||
},
|
||||
|
||||
/**
|
||||
* The field is not a number
|
||||
*/
|
||||
number (vm: FormularioInput, context: Object) {
|
||||
number (vm: FormularioInput, context: Record<string, any>): string {
|
||||
return vm.$t('validation.number.default', context)
|
||||
},
|
||||
|
||||
/**
|
||||
* Required field.
|
||||
*/
|
||||
required (vm: FormularioInput, context: Object) {
|
||||
required (vm: FormularioInput, context: Record<string, any>): string {
|
||||
return vm.$t('validation.required.default', context)
|
||||
},
|
||||
|
||||
/**
|
||||
* Starts with specified value
|
||||
*/
|
||||
startsWith (vm: FormularioInput, context: Object) {
|
||||
startsWith (vm: FormularioInput, context: Record<string, any>): string {
|
||||
return vm.$t('validation.startsWith.default', context)
|
||||
},
|
||||
|
||||
/**
|
||||
* Value is not a url.
|
||||
*/
|
||||
url (vm: FormularioInput, context: Object) {
|
||||
url (vm: FormularioInput, context: Record<string, any>): string {
|
||||
return vm.$t('validation.url.default', context)
|
||||
}
|
||||
}
|
||||
|
@ -1,2 +0,0 @@
|
||||
export type ArrayType = [any]
|
||||
export type ObjectType = { [key: string]: any }
|
@ -1,5 +1,4 @@
|
||||
import { shallowEqualObjects, has, getNested } from './utils'
|
||||
import { ObjectType } from '@/common.types'
|
||||
import FormularioForm from '@/FormularioForm.vue'
|
||||
import FormularioInput from '@/FormularioInput.vue'
|
||||
|
||||
@ -23,36 +22,33 @@ export default class Registry {
|
||||
/**
|
||||
* Add an item to the registry.
|
||||
*/
|
||||
add (name: string, component: FormularioInput) {
|
||||
add (name: string, component: FormularioInput): void {
|
||||
this.registry.set(name, component)
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an item from the registry.
|
||||
* @param {string} name
|
||||
*/
|
||||
remove (name: string) {
|
||||
remove (name: string): void {
|
||||
this.registry.delete(name)
|
||||
// @ts-ignore
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const { [name]: value, ...newProxy } = this.ctx.proxy
|
||||
// @ts-ignore
|
||||
this.ctx.proxy = newProxy
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the registry has the given key.
|
||||
*/
|
||||
has (key: string) {
|
||||
has (key: string): boolean {
|
||||
return this.registry.has(key)
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the registry has elements, that equals or nested given key
|
||||
*/
|
||||
hasNested (key: string) {
|
||||
hasNested (key: string): boolean {
|
||||
for (const i of this.registry.keys()) {
|
||||
if (i === key || i.includes(key + '.')) {
|
||||
return true
|
||||
@ -72,7 +68,7 @@ export default class Registry {
|
||||
/**
|
||||
* Get registry value for key or nested to given key
|
||||
*/
|
||||
getNested (key: string) {
|
||||
getNested (key: string): Map<string, FormularioInput> {
|
||||
const result = new Map()
|
||||
|
||||
for (const i of this.registry.keys()) {
|
||||
@ -87,7 +83,7 @@ export default class Registry {
|
||||
/**
|
||||
* Map over the registry (recursively).
|
||||
*/
|
||||
map (mapper: Function) {
|
||||
map (mapper: Function): Record<string, any> {
|
||||
const value = {}
|
||||
this.registry.forEach((component, field) => Object.assign(value, { [field]: mapper(component, field) }))
|
||||
return value
|
||||
@ -96,7 +92,7 @@ export default class Registry {
|
||||
/**
|
||||
* Map over the registry (recursively).
|
||||
*/
|
||||
forEach (callback: Function) {
|
||||
forEach (callback: Function): void {
|
||||
this.registry.forEach((component, field) => {
|
||||
callback(component, field)
|
||||
})
|
||||
@ -114,13 +110,13 @@ export default class Registry {
|
||||
* @param {string} field name of the field.
|
||||
* @param {FormularioForm} component the actual component instance.
|
||||
*/
|
||||
register (field: string, component: FormularioInput) {
|
||||
register (field: string, component: FormularioInput): void {
|
||||
if (this.registry.has(field)) {
|
||||
return false
|
||||
return
|
||||
}
|
||||
this.registry.set(field, component)
|
||||
const hasVModelValue = has(component.$options.propsData as ObjectType, 'formularioValue')
|
||||
const hasValue = has(component.$options.propsData as ObjectType, 'value')
|
||||
const hasVModelValue = has(component.$options.propsData as Record<string, any>, 'formularioValue')
|
||||
const hasValue = has(component.$options.propsData as Record<string, any>, 'value')
|
||||
if (
|
||||
!hasVModelValue &&
|
||||
// @ts-ignore
|
||||
|
@ -1,16 +1,12 @@
|
||||
import FileUpload from '@/FileUpload'
|
||||
import {
|
||||
ArrayType,
|
||||
ObjectType,
|
||||
} from '@/common.types'
|
||||
|
||||
/**
|
||||
* Function to map over an object.
|
||||
* @param {Object} original An object to map over
|
||||
* @param {Function} callback
|
||||
*/
|
||||
export function map (original: ObjectType, callback: Function) {
|
||||
const obj: ObjectType = {}
|
||||
export function map (original: Record<string, any>, callback: Function): Record<string, any> {
|
||||
const obj: Record<string, any> = {}
|
||||
for (const key in original) {
|
||||
if (Object.prototype.hasOwnProperty.call(original, key)) {
|
||||
obj[key] = callback(key, original[key])
|
||||
@ -19,7 +15,7 @@ export function map (original: ObjectType, callback: Function) {
|
||||
return obj
|
||||
}
|
||||
|
||||
export function shallowEqualObjects (objA: any, objB: any) {
|
||||
export function shallowEqualObjects (objA: Record<string, any>, objB: Record<string, any>): boolean {
|
||||
if (objA === objB) {
|
||||
return true
|
||||
}
|
||||
@ -66,7 +62,7 @@ export function snakeToCamel (string: string | any) {
|
||||
* If given parameter is not string, object ot array, result will be an empty array.
|
||||
* @param {*} item
|
||||
*/
|
||||
export function arrayify (item: any) {
|
||||
export function arrayify (item: any): any[] {
|
||||
if (!item) {
|
||||
return []
|
||||
}
|
||||
@ -102,7 +98,7 @@ export function parseRules (validation: any, rules: any): any[] {
|
||||
* Given a string or function, parse it and return an array in the format
|
||||
* [fn, [...arguments]]
|
||||
*/
|
||||
function parseRule (rule: any, rules: ObjectType) {
|
||||
function parseRule (rule: any, rules: Record<string, any>) {
|
||||
if (typeof rule === 'function') {
|
||||
return [rule, []]
|
||||
}
|
||||
@ -243,12 +239,12 @@ export function isScalar (data: any) {
|
||||
* A simple (somewhat non-comprehensive) cloneDeep function, valid for our use
|
||||
* case of needing to unbind reactive watchers.
|
||||
*/
|
||||
export function cloneDeep (value: any) {
|
||||
export function cloneDeep (value: any): any {
|
||||
if (typeof value !== 'object') {
|
||||
return value
|
||||
}
|
||||
|
||||
const copy: ArrayType | ObjectType = Array.isArray(value) ? [] : {}
|
||||
const copy: any | Record<string, any> = Array.isArray(value) ? [] : {}
|
||||
|
||||
for (const key in value) {
|
||||
if (Object.prototype.hasOwnProperty.call(value, key)) {
|
||||
@ -267,7 +263,7 @@ export function cloneDeep (value: any) {
|
||||
* Given a locale string, parse the options.
|
||||
* @param {string} locale
|
||||
*/
|
||||
export function parseLocale (locale: string) {
|
||||
export function parseLocale (locale: string): string[] {
|
||||
const segments = locale.split('-')
|
||||
return segments.reduce((options: string[], segment: string) => {
|
||||
if (options.length) {
|
||||
@ -280,21 +276,14 @@ export function parseLocale (locale: string) {
|
||||
/**
|
||||
* Shorthand for Object.prototype.hasOwnProperty.call (space saving)
|
||||
*/
|
||||
export function has (ctx: ObjectType, prop: string): boolean {
|
||||
export function has (ctx: Record<string, any>, prop: string): boolean {
|
||||
return Object.prototype.hasOwnProperty.call(ctx, prop)
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a unique Symbol identifier on an object.
|
||||
*/
|
||||
export function setId (o: object, id: Symbol) {
|
||||
return Object.defineProperty(o, '__id', Object.assign(Object.create(null), { value: id || Symbol('uuid') }))
|
||||
}
|
||||
|
||||
export function getNested (obj: ObjectType, field: string) {
|
||||
export function getNested (obj: Record<string, any>, field: string): any {
|
||||
const fieldParts = field.split('.')
|
||||
|
||||
let result: ObjectType = obj
|
||||
let result: Record<string, any> = obj
|
||||
|
||||
for (const key in fieldParts) {
|
||||
const matches = fieldParts[key].match(/(.+)\[(\d+)\]$/)
|
||||
@ -315,10 +304,10 @@ export function getNested (obj: ObjectType, field: string) {
|
||||
return result
|
||||
}
|
||||
|
||||
export function setNested (obj: ObjectType, field: string, value: any) {
|
||||
export function setNested (obj: Record<string, any>, field: string, value: any): void {
|
||||
const fieldParts = field.split('.')
|
||||
|
||||
let subProxy: ObjectType = obj
|
||||
let subProxy: Record<string, any> = obj
|
||||
for (let i = 0; i < fieldParts.length; i++) {
|
||||
const fieldPart = fieldParts[i]
|
||||
const matches = fieldPart.match(/(.+)\[(\d+)\]$/)
|
||||
@ -348,6 +337,4 @@ export function setNested (obj: ObjectType, field: string, value: any) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return obj
|
||||
}
|
||||
|
20
src/shims-ext.d.ts
vendored
20
src/shims-ext.d.ts
vendored
@ -1,20 +1,20 @@
|
||||
import Formulario from '@/Formulario'
|
||||
|
||||
declare module 'vue/types/vue' {
|
||||
interface VueRoute {
|
||||
path: string
|
||||
interface Vue {
|
||||
$formulario: Formulario;
|
||||
$route: VueRoute;
|
||||
$t: Function;
|
||||
$tc: Function;
|
||||
}
|
||||
|
||||
interface Vue {
|
||||
$formulario: Formulario,
|
||||
$route: VueRoute,
|
||||
$t: Function,
|
||||
$tc: Function,
|
||||
interface VueRoute {
|
||||
path: string;
|
||||
}
|
||||
|
||||
interface FormularioForm extends Vue {
|
||||
name: string | boolean
|
||||
proxy: Object
|
||||
hasValidationErrors(): Promise<boolean>
|
||||
name: string | boolean;
|
||||
proxy: Record<string, any>;
|
||||
hasValidationErrors(): Promise<boolean>;
|
||||
}
|
||||
}
|
||||
|
4
src/shims-tsx.d.ts
vendored
4
src/shims-tsx.d.ts
vendored
@ -2,12 +2,10 @@ import Vue, { VNode } from 'vue'
|
||||
|
||||
declare global {
|
||||
namespace JSX {
|
||||
// tslint:disable no-empty-interface
|
||||
interface Element extends VNode {}
|
||||
// tslint:disable no-empty-interface
|
||||
interface ElementClass extends Vue {}
|
||||
interface IntrinsicElements {
|
||||
[elem: string]: any
|
||||
[elem: string]: any;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,35 +1,38 @@
|
||||
import isPlainObject from 'is-plain-object'
|
||||
import { ObjectType } from '@/common.types.ts'
|
||||
import { has } from '@/libs/utils.ts'
|
||||
|
||||
/**
|
||||
* Create a new object by copying properties of base and mergeWith.
|
||||
* Note: arrays don't overwrite - they push
|
||||
*
|
||||
* @param {Object} base
|
||||
* @param {Object} mergeWith
|
||||
* @param {Object} a
|
||||
* @param {Object} b
|
||||
* @param {boolean} concatArrays
|
||||
*/
|
||||
export default function merge (base: ObjectType, mergeWith: ObjectType, concatArrays: boolean = true) {
|
||||
const merged: ObjectType = {}
|
||||
export default function merge (
|
||||
a: Record<string, any>,
|
||||
b: Record<string, any>,
|
||||
concatArrays = true
|
||||
): Record<string, any> {
|
||||
const merged: Record<string, any> = {}
|
||||
|
||||
for (const key in base) {
|
||||
if (has(mergeWith, key)) {
|
||||
if (isPlainObject(mergeWith[key]) && isPlainObject(base[key])) {
|
||||
merged[key] = merge(base[key], mergeWith[key], concatArrays)
|
||||
} else if (concatArrays && Array.isArray(base[key]) && Array.isArray(mergeWith[key])) {
|
||||
merged[key] = base[key].concat(mergeWith[key])
|
||||
for (const key in a) {
|
||||
if (has(b, key)) {
|
||||
if (isPlainObject(b[key]) && isPlainObject(a[key])) {
|
||||
merged[key] = merge(a[key], b[key], concatArrays)
|
||||
} else if (concatArrays && Array.isArray(a[key]) && Array.isArray(b[key])) {
|
||||
merged[key] = a[key].concat(b[key])
|
||||
} else {
|
||||
merged[key] = mergeWith[key]
|
||||
merged[key] = b[key]
|
||||
}
|
||||
} else {
|
||||
merged[key] = base[key]
|
||||
merged[key] = a[key]
|
||||
}
|
||||
}
|
||||
|
||||
for (const prop in mergeWith) {
|
||||
for (const prop in b) {
|
||||
if (!has(merged, prop)) {
|
||||
merged[prop] = mergeWith[prop]
|
||||
merged[prop] = b[prop]
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,12 +2,11 @@
|
||||
import isUrl from 'is-url'
|
||||
import FileUpload from '../FileUpload'
|
||||
import { shallowEqualObjects, regexForFormat, has } from '@/libs/utils'
|
||||
import { ObjectType } from '@/common.types'
|
||||
import { ValidatableData } from '@/validation/types'
|
||||
|
||||
interface ConfirmValidatableData extends ValidatableData {
|
||||
getFormValues: () => ObjectType,
|
||||
name: string,
|
||||
getFormValues: () => Record<string, any>;
|
||||
name: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -33,7 +32,7 @@ export default {
|
||||
/**
|
||||
* Rule: checks if the value is only alpha
|
||||
*/
|
||||
alpha ({ value }: { value: string }, set: string = 'default'): Promise<boolean> {
|
||||
alpha ({ value }: { value: string }, set = 'default'): Promise<boolean> {
|
||||
const sets = {
|
||||
default: /^[a-zA-ZÀ-ÖØ-öø-ÿ]+$/,
|
||||
latin: /^[a-zA-Z]+$/
|
||||
@ -69,7 +68,7 @@ export default {
|
||||
* Rule: checks if the value is between two other values
|
||||
*/
|
||||
between ({ value }: { value: string|number }, from: number|any = 0, to: number|any = 10, force?: string): Promise<boolean> {
|
||||
return Promise.resolve((() => {
|
||||
return Promise.resolve(((): boolean => {
|
||||
if (from === null || to === null || isNaN(from) || isNaN(to)) {
|
||||
return false
|
||||
}
|
||||
@ -92,7 +91,7 @@ export default {
|
||||
* for password confirmations.
|
||||
*/
|
||||
confirm ({ value, getFormValues, name }: ConfirmValidatableData, field?: string): Promise<boolean> {
|
||||
return Promise.resolve((() => {
|
||||
return Promise.resolve(((): boolean => {
|
||||
const formValues = getFormValues()
|
||||
let confirmationFieldName = field
|
||||
if (!confirmationFieldName) {
|
||||
@ -168,7 +167,7 @@ export default {
|
||||
mime ({ value }: { value: any }, ...types: string[]): Promise<boolean> {
|
||||
if (value instanceof FileUpload) {
|
||||
const files = value.getFiles()
|
||||
const isMimeCorrect = (file: File) => types.includes(file.type)
|
||||
const isMimeCorrect = (file: File): boolean => types.includes(file.type)
|
||||
const allValid: boolean = files.reduce((valid: boolean, { file }) => valid && isMimeCorrect(file), true)
|
||||
|
||||
return Promise.resolve(allValid)
|
||||
@ -181,7 +180,7 @@ export default {
|
||||
* Check the minimum value of a particular.
|
||||
*/
|
||||
min ({ value }: { value: any }, minimum: number | any = 1, force?: string): Promise<boolean> {
|
||||
return Promise.resolve((() => {
|
||||
return Promise.resolve(((): boolean => {
|
||||
if (Array.isArray(value)) {
|
||||
minimum = !isNaN(minimum) ? Number(minimum) : minimum
|
||||
return value.length >= minimum
|
||||
@ -202,7 +201,7 @@ export default {
|
||||
* Check the maximum value of a particular.
|
||||
*/
|
||||
max ({ value }: { value: any }, maximum: string | number = 10, force?: string): Promise<boolean> {
|
||||
return Promise.resolve((() => {
|
||||
return Promise.resolve(((): boolean => {
|
||||
if (Array.isArray(value)) {
|
||||
maximum = !isNaN(Number(maximum)) ? Number(maximum) : maximum
|
||||
return value.length <= maximum
|
||||
@ -239,7 +238,7 @@ export default {
|
||||
* Rule: must be a value
|
||||
*/
|
||||
required ({ value }: { value: any }, isRequired: string|boolean = true): Promise<boolean> {
|
||||
return Promise.resolve((() => {
|
||||
return Promise.resolve(((): boolean => {
|
||||
if (!isRequired || ['no', 'false'].includes(isRequired as string)) {
|
||||
return true
|
||||
}
|
||||
|
@ -1,17 +1,17 @@
|
||||
interface ValidatableData {
|
||||
value: any,
|
||||
value: any;
|
||||
}
|
||||
|
||||
interface ValidationContext {
|
||||
args: any[]
|
||||
name: string
|
||||
value: any
|
||||
args: any[];
|
||||
name: string;
|
||||
value: any;
|
||||
}
|
||||
|
||||
interface ValidationError {
|
||||
rule?: string
|
||||
context?: any
|
||||
message: string
|
||||
rule?: string;
|
||||
context?: any;
|
||||
message: string;
|
||||
}
|
||||
|
||||
export { ValidatableData }
|
||||
|
@ -265,9 +265,8 @@ describe('FormularioForm', () => {
|
||||
const wrapper = mount(FormularioForm, {
|
||||
propsData: { values: { name: 'Dave Barnett', candy: true } },
|
||||
slots: { default: `
|
||||
|
||||
<FormularioInput v-slot="inputProps" name="name" validation="required" >
|
||||
<input v-model="inputProps.context.model" type="text">
|
||||
<FormularioInput v-slot="{ context }" name="name" validation="required">
|
||||
<input v-model="context.model" type="text">
|
||||
</FormularioInput>
|
||||
` }
|
||||
})
|
||||
@ -288,12 +287,8 @@ describe('FormularioForm', () => {
|
||||
const wrapper = mount({
|
||||
template: `
|
||||
<div>
|
||||
<FormularioForm
|
||||
name="login"
|
||||
/>
|
||||
<FormularioForm
|
||||
name="register"
|
||||
/>
|
||||
<FormularioForm name="login" />
|
||||
<FormularioForm name="register" />
|
||||
</div>
|
||||
`
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user