feat: Components conststructors are exposed as external API, added TypeScript declarations
This commit is contained in:
parent
6224b40e02
commit
dfc6557bc6
35
.eslintrc.js
35
.eslintrc.js
@ -1,30 +1,27 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
root: true,
|
root: true,
|
||||||
|
|
||||||
parserOptions: {
|
|
||||||
parser: '@typescript-eslint/parser',
|
|
||||||
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',
|
|
||||||
],
|
|
||||||
|
|
||||||
env: {
|
env: {
|
||||||
browser: true,
|
browser: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
parserOptions: {
|
||||||
|
parser: '@typescript-eslint/parser',
|
||||||
|
},
|
||||||
|
|
||||||
|
plugins: [
|
||||||
|
'@typescript-eslint',
|
||||||
|
'vue',
|
||||||
|
],
|
||||||
|
|
||||||
|
// https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style
|
||||||
|
extends: [
|
||||||
|
'plugin:@typescript-eslint/eslint-recommended',
|
||||||
|
'plugin:@typescript-eslint/recommended',
|
||||||
|
'plugin:vue/recommended',
|
||||||
|
],
|
||||||
|
|
||||||
rules: {
|
rules: {
|
||||||
'@typescript-eslint/camelcase': ['error', {
|
|
||||||
allow: ['^__Formulario'],
|
|
||||||
}],
|
|
||||||
'@typescript-eslint/no-empty-function': 'off',
|
'@typescript-eslint/no-empty-function': 'off',
|
||||||
'@typescript-eslint/no-explicit-any': 'off', // @TODO
|
'@typescript-eslint/no-explicit-any': 'off', // @TODO
|
||||||
'@typescript-eslint/no-unused-vars': ['error'], // @TODO
|
'@typescript-eslint/no-unused-vars': ['error'], // @TODO
|
||||||
|
@ -9,7 +9,6 @@ export default {
|
|||||||
input: 'src/index.ts',
|
input: 'src/index.ts',
|
||||||
output: [{
|
output: [{
|
||||||
name: 'Formulario',
|
name: 'Formulario',
|
||||||
exports: 'default',
|
|
||||||
globals: {
|
globals: {
|
||||||
'is-plain-object': 'isPlainObject',
|
'is-plain-object': 'isPlainObject',
|
||||||
'is-url': 'isUrl',
|
'is-url': 'isUrl',
|
||||||
|
@ -11,7 +11,6 @@ export default {
|
|||||||
input: 'src/index.ts',
|
input: 'src/index.ts',
|
||||||
output: {
|
output: {
|
||||||
name: 'VueFormulario',
|
name: 'VueFormulario',
|
||||||
exports: 'default',
|
|
||||||
format: 'iife',
|
format: 'iife',
|
||||||
globals: {
|
globals: {
|
||||||
'is-plain-object': 'isPlainObject',
|
'is-plain-object': 'isPlainObject',
|
||||||
|
94
index.d.ts
vendored
Normal file
94
index.d.ts
vendored
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
// noinspection JSUnusedGlobalSymbols
|
||||||
|
|
||||||
|
import type { Vue } from 'vue/types/vue'
|
||||||
|
import type { PluginObject } from 'vue/types/plugin'
|
||||||
|
|
||||||
|
import type { DefineComponent } from './types/vue'
|
||||||
|
|
||||||
|
import type { FormularioFormConstructor } from './types/form'
|
||||||
|
|
||||||
|
import type {
|
||||||
|
ModelGetConverter,
|
||||||
|
ModelSetConverter,
|
||||||
|
ValidationBehaviour,
|
||||||
|
UnregisterBehaviour,
|
||||||
|
} from './types/field'
|
||||||
|
|
||||||
|
import type {
|
||||||
|
ValidationMessageFn,
|
||||||
|
ValidationMessageI18NFn,
|
||||||
|
ValidationRuleFn,
|
||||||
|
Violation,
|
||||||
|
} from './types/validation'
|
||||||
|
|
||||||
|
import type { Options } from './types/plugin'
|
||||||
|
|
||||||
|
declare const FormularioForm: FormularioFormConstructor
|
||||||
|
|
||||||
|
export { FormularioForm }
|
||||||
|
|
||||||
|
declare const FormularioField: DefineComponent<{
|
||||||
|
name: string;
|
||||||
|
value?: unknown;
|
||||||
|
validation?: string|any[];
|
||||||
|
/** Defaults to 'demand' */
|
||||||
|
validationBehavior?: ValidationBehaviour;
|
||||||
|
validationRules?: Record<string, ValidationRuleFn>;
|
||||||
|
validationMessages?: Record<string, ValidationMessageI18NFn|string>;
|
||||||
|
errorsDisabled?: boolean;
|
||||||
|
modelGetConverter?: ModelGetConverter;
|
||||||
|
modelSetConverter?: ModelSetConverter;
|
||||||
|
/** Defaults to 'none' */
|
||||||
|
unregisterBehavior?: UnregisterBehaviour;
|
||||||
|
tag?: string;
|
||||||
|
}, {
|
||||||
|
runValidation(): Promise<Violation[]>;
|
||||||
|
hasValidationErrors (): Promise<boolean>;
|
||||||
|
/** @internal */
|
||||||
|
resetValidation(): void;
|
||||||
|
}>
|
||||||
|
|
||||||
|
export { FormularioField }
|
||||||
|
|
||||||
|
declare class Formulario {
|
||||||
|
public validationRules: Record<string, ValidationRuleFn>;
|
||||||
|
public validationMessages: Record<string, ValidationMessageI18NFn|string>;
|
||||||
|
|
||||||
|
constructor (options?: Options);
|
||||||
|
|
||||||
|
/** Given a set of options, apply them to the pre-existing options. */
|
||||||
|
public extend (extendWith: Options): Formulario;
|
||||||
|
|
||||||
|
public runValidation (id: string): Promise<Record<string, Violation[]>>;
|
||||||
|
|
||||||
|
public resetValidation (id: string): void;
|
||||||
|
|
||||||
|
/** Used by forms instances to add themselves into a registry */
|
||||||
|
public register (id: string, form: InstanceType<FormularioFormConstructor>): void;
|
||||||
|
|
||||||
|
/** Used by forms instances to remove themselves from a registry */
|
||||||
|
public unregister (id: string): void;
|
||||||
|
|
||||||
|
/** Get validation rules by merging any passed in with global rules. */
|
||||||
|
public getRules (extendWith: Record<string, ValidationRuleFn> = {}): Record<string, ValidationRuleFn>;
|
||||||
|
|
||||||
|
/** Get validation messages by merging any passed in with global messages. */
|
||||||
|
public getMessages (
|
||||||
|
vm: Vue,
|
||||||
|
extendWith: Record<string, ValidationMessageI18NFn|string>
|
||||||
|
): Record<string, ValidationMessageFn>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Formulario }
|
||||||
|
|
||||||
|
declare module 'vue/types/vue' {
|
||||||
|
interface Vue {
|
||||||
|
readonly $formulario: Formulario;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare const VueFormulario: PluginObject<Options> & {
|
||||||
|
Formulario: Formulario,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default VueFormulario
|
26
package.json
26
package.json
@ -24,7 +24,7 @@
|
|||||||
"build:iife": "rollup --config build/rollup.iife.config.js --format iife --file dist/formulario.min.js",
|
"build:iife": "rollup --config build/rollup.iife.config.js --format iife --file dist/formulario.min.js",
|
||||||
"build:size": "gzip -c dist/formulario.esm.js | wc -c",
|
"build:size": "gzip -c dist/formulario.esm.js | wc -c",
|
||||||
"build:umd": "rollup --config build/rollup.config.js --format umd --file dist/formulario.umd.js",
|
"build:umd": "rollup --config build/rollup.config.js --format umd --file dist/formulario.umd.js",
|
||||||
"lint": "vue-cli-service lint",
|
"lint": "eslint --ext .js,.mjs,.ts,.vue",
|
||||||
"release": "standard-version",
|
"release": "standard-version",
|
||||||
"release:minor": "standard-version --release-as minor",
|
"release:minor": "standard-version --release-as minor",
|
||||||
"release:patch": "standard-version --release-as patch",
|
"release:patch": "standard-version --release-as patch",
|
||||||
@ -52,28 +52,24 @@
|
|||||||
"@storybook/vue": "^6.0.26",
|
"@storybook/vue": "^6.0.26",
|
||||||
"@types/is-url": "^1.2.28",
|
"@types/is-url": "^1.2.28",
|
||||||
"@types/jest": "^26.0.14",
|
"@types/jest": "^26.0.14",
|
||||||
"@typescript-eslint/eslint-plugin": "^2.26.0",
|
"@typescript-eslint/eslint-plugin": "^6.16.0",
|
||||||
"@typescript-eslint/parser": "^2.26.0",
|
"@typescript-eslint/parser": "^6.16.0",
|
||||||
"@vue/cli-plugin-babel": "^4.3.1",
|
"@vue/cli-plugin-babel": "^4.3.1",
|
||||||
"@vue/cli-plugin-eslint": "^4.3.1",
|
|
||||||
"@vue/cli-plugin-typescript": "^4.5.7",
|
"@vue/cli-plugin-typescript": "^4.5.7",
|
||||||
"@vue/cli-service": "^4.5.4",
|
"@vue/cli-service": "^4.5.4",
|
||||||
"@vue/component-compiler-utils": "^3.1.2",
|
"@vue/component-compiler-utils": "^3.1.2",
|
||||||
"@vue/eslint-config-standard": "^5.1.2",
|
|
||||||
"@vue/eslint-config-typescript": "^5.0.2",
|
|
||||||
"@vue/test-utils": "^1.0.2",
|
"@vue/test-utils": "^1.0.2",
|
||||||
"autoprefixer": "^9.7.6",
|
"autoprefixer": "^9.7.6",
|
||||||
"babel-core": "^7.0.0-bridge.0",
|
"babel-core": "^7.0.0-bridge.0",
|
||||||
"babel-eslint": "^10.1.0",
|
|
||||||
"babel-jest": "^25.5.1",
|
"babel-jest": "^25.5.1",
|
||||||
"bootstrap-scss": "^4.5.2",
|
"bootstrap-scss": "^4.5.2",
|
||||||
"eslint": "^5.16.0",
|
"eslint": "^8.56.0",
|
||||||
"eslint-config-standard": "^12.0.0",
|
"eslint-config-standard": "^17.1.0",
|
||||||
"eslint-plugin-import": "^2.20.1",
|
"eslint-friendly-formatter": "^4.0.1",
|
||||||
"eslint-plugin-node": "^8.0.1",
|
"eslint-plugin-import": "^2.29.1",
|
||||||
"eslint-plugin-promise": "^4.1.1",
|
"eslint-plugin-node": "^11.1.0",
|
||||||
"eslint-plugin-standard": "^4.0.0",
|
"eslint-plugin-promise": "^6.1.1",
|
||||||
"eslint-plugin-vue": "^5.2.3",
|
"eslint-plugin-vue": "^9.19.2",
|
||||||
"flush-promises": "^1.0.2",
|
"flush-promises": "^1.0.2",
|
||||||
"jest": "^26.5.2",
|
"jest": "^26.5.2",
|
||||||
"jest-vue-preprocessor": "^1.7.1",
|
"jest-vue-preprocessor": "^1.7.1",
|
||||||
@ -88,7 +84,7 @@
|
|||||||
"sass-loader": "^10.0.3",
|
"sass-loader": "^10.0.3",
|
||||||
"standard-version": "^9.3.0",
|
"standard-version": "^9.3.0",
|
||||||
"ts-jest": "^26.4.1",
|
"ts-jest": "^26.4.1",
|
||||||
"typescript": "~3.9.3",
|
"typescript": "^4.9.5",
|
||||||
"vue": "^2.6.11",
|
"vue": "^2.6.11",
|
||||||
"vue-cli-plugin-storybook": "^1.3.0",
|
"vue-cli-plugin-storybook": "^1.3.0",
|
||||||
"vue-jest": "^3.0.5",
|
"vue-jest": "^3.0.5",
|
||||||
|
@ -1,33 +1,28 @@
|
|||||||
import merge from '@/utils/merge'
|
import type { FormularioFormConstructor } from '../types/form'
|
||||||
import validationRules from '@/validation/rules'
|
|
||||||
import validationMessages from '@/validation/messages'
|
|
||||||
|
|
||||||
import {
|
import type {
|
||||||
ValidationContext,
|
ValidationContext,
|
||||||
ValidationRuleFn,
|
ValidationRuleFn,
|
||||||
ValidationMessageFn,
|
ValidationMessageFn,
|
||||||
ValidationMessageI18NFn,
|
ValidationMessageI18NFn,
|
||||||
Violation,
|
Violation,
|
||||||
} from '@/validation/validator'
|
} from '../types/validation'
|
||||||
|
|
||||||
import { FormularioForm } from '@/types'
|
import type { Options } from '../types/plugin'
|
||||||
|
|
||||||
export interface FormularioOptions {
|
import merge from '@/utils/merge'
|
||||||
validationRules?: Record<string, ValidationRuleFn>;
|
|
||||||
validationMessages?: Record<string, ValidationMessageI18NFn|string>;
|
import validationRules from '@/validation/rules'
|
||||||
}
|
import validationMessages from '@/validation/messages'
|
||||||
|
|
||||||
/**
|
|
||||||
* The base formulario library.
|
|
||||||
*/
|
|
||||||
export default class Formulario {
|
export default class Formulario {
|
||||||
public validationRules: Record<string, ValidationRuleFn> = {}
|
public validationRules: Record<string, ValidationRuleFn> = {}
|
||||||
public validationMessages: Record<string, ValidationMessageI18NFn|string> = {}
|
public validationMessages: Record<string, ValidationMessageI18NFn|string> = {}
|
||||||
|
|
||||||
private readonly registry: Map<string, FormularioForm>
|
private readonly _registry: Map<string, InstanceType<FormularioFormConstructor>>
|
||||||
|
|
||||||
public constructor (options?: FormularioOptions) {
|
public constructor (options?: Options) {
|
||||||
this.registry = new Map()
|
this._registry = new Map()
|
||||||
|
|
||||||
this.validationRules = validationRules
|
this.validationRules = validationRules
|
||||||
this.validationMessages = validationMessages
|
this.validationMessages = validationMessages
|
||||||
@ -38,7 +33,7 @@ export default class Formulario {
|
|||||||
/**
|
/**
|
||||||
* Given a set of options, apply them to the pre-existing options.
|
* Given a set of options, apply them to the pre-existing options.
|
||||||
*/
|
*/
|
||||||
public extend (extendWith: FormularioOptions): Formulario {
|
public extend (extendWith: Options): Formulario {
|
||||||
if (typeof extendWith === 'object') {
|
if (typeof extendWith === 'object') {
|
||||||
this.validationRules = merge(this.validationRules, extendWith.validationRules || {})
|
this.validationRules = merge(this.validationRules, extendWith.validationRules || {})
|
||||||
this.validationMessages = merge(this.validationMessages, extendWith.validationMessages || {})
|
this.validationMessages = merge(this.validationMessages, extendWith.validationMessages || {})
|
||||||
@ -48,21 +43,21 @@ export default class Formulario {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public runValidation (id: string): Promise<Record<string, Violation[]>> {
|
public runValidation (id: string): Promise<Record<string, Violation[]>> {
|
||||||
if (!this.registry.has(id)) {
|
if (!this._registry.has(id)) {
|
||||||
throw new Error(`[Formulario]: Formulario.runValidation(): no forms with id "${id}"`)
|
throw new Error(`[Formulario]: Formulario.runValidation(): no forms with id "${id}"`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const form = this.registry.get(id) as FormularioForm
|
const form = this._registry.get(id) as InstanceType<FormularioFormConstructor>
|
||||||
|
|
||||||
return form.runValidation()
|
return form.runValidation()
|
||||||
}
|
}
|
||||||
|
|
||||||
public resetValidation (id: string): void {
|
public resetValidation (id: string): void {
|
||||||
if (!this.registry.has(id)) {
|
if (!this._registry.has(id)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const form = this.registry.get(id) as FormularioForm
|
const form = this._registry.get(id) as InstanceType<FormularioFormConstructor>
|
||||||
|
|
||||||
form.resetValidation()
|
form.resetValidation()
|
||||||
}
|
}
|
||||||
@ -71,12 +66,12 @@ export default class Formulario {
|
|||||||
* Used by forms instances to add themselves into a registry
|
* Used by forms instances to add themselves into a registry
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
public register (id: string, form: FormularioForm): void {
|
public register (id: string, form: InstanceType<FormularioFormConstructor>): void {
|
||||||
if (this.registry.has(id)) {
|
if (this._registry.has(id)) {
|
||||||
throw new Error(`[Formulario]: Formulario.register(): id "${id}" is already in use`)
|
throw new Error(`[Formulario]: Formulario.register(): id "${id}" is already in use`)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.registry.set(id, form)
|
this._registry.set(id, form)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -84,8 +79,8 @@ export default class Formulario {
|
|||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
public unregister (id: string): void {
|
public unregister (id: string): void {
|
||||||
if (this.registry.has(id)) {
|
if (this._registry.has(id)) {
|
||||||
this.registry.delete(id)
|
this._registry.delete(id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,21 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import type {
|
||||||
|
Context,
|
||||||
|
Empty,
|
||||||
|
ModelGetConverter,
|
||||||
|
ModelSetConverter,
|
||||||
|
ValidationBehaviour,
|
||||||
|
UnregisterBehaviour,
|
||||||
|
} from '../types/field'
|
||||||
|
|
||||||
|
import type {
|
||||||
|
ValidationRuleFn,
|
||||||
|
ValidationMessageI18NFn,
|
||||||
|
Violation,
|
||||||
|
} from '../types/validation'
|
||||||
|
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import {
|
import {
|
||||||
Component,
|
Component,
|
||||||
@ -16,38 +31,19 @@ import {
|
|||||||
Prop,
|
Prop,
|
||||||
Watch,
|
Watch,
|
||||||
} from 'vue-property-decorator'
|
} from 'vue-property-decorator'
|
||||||
|
|
||||||
|
import { processConstraints, validate } from '@/validation/validator'
|
||||||
|
|
||||||
import { deepEquals, has, snakeToCamel } from './utils'
|
import { deepEquals, has, snakeToCamel } from './utils'
|
||||||
import {
|
|
||||||
processConstraints,
|
|
||||||
validate,
|
|
||||||
ValidationRuleFn,
|
|
||||||
ValidationMessageI18NFn,
|
|
||||||
Violation,
|
|
||||||
} from '@/validation/validator'
|
|
||||||
|
|
||||||
import {
|
|
||||||
FormularioFieldContext,
|
|
||||||
FormularioFieldModelGetConverter as ModelGetConverter,
|
|
||||||
FormularioFieldModelSetConverter as ModelSetConverter,
|
|
||||||
Empty,
|
|
||||||
} from '@/types'
|
|
||||||
|
|
||||||
import { UNREGISTER_BEHAVIOR } from '@/enum'
|
|
||||||
|
|
||||||
const VALIDATION_BEHAVIOR = {
|
|
||||||
DEMAND: 'demand',
|
|
||||||
LIVE: 'live',
|
|
||||||
SUBMIT: 'submit',
|
|
||||||
}
|
|
||||||
|
|
||||||
@Component({ name: 'FormularioField', inheritAttrs: false })
|
@Component({ name: 'FormularioField', inheritAttrs: false })
|
||||||
export default class FormularioField extends Vue {
|
export default class FormularioField extends Vue {
|
||||||
@Inject({ default: '' }) __Formulario_path!: string
|
@Inject({ default: '' }) __Formulario_path!: string
|
||||||
@Inject({ default: undefined }) __FormularioForm_set!: Function|undefined
|
@Inject({ default: undefined }) __FormularioForm_set!: ((path: string, value: unknown) => void)|undefined
|
||||||
@Inject({ default: () => (): void => {} }) __FormularioForm_emitInput!: Function
|
@Inject({ default: () => (): void => {} }) __FormularioForm_emitInput!: () => void
|
||||||
@Inject({ default: () => (): void => {} }) __FormularioForm_emitValidation!: Function
|
@Inject({ default: () => (): void => {} }) __FormularioForm_emitValidation!: (path: string, violations: Violation[]) => void
|
||||||
@Inject({ default: undefined }) __FormularioForm_register!: Function|undefined
|
@Inject({ default: undefined }) __FormularioForm_register!: ((path: string, field: FormularioField) => void)|undefined
|
||||||
@Inject({ default: undefined }) __FormularioForm_unregister!: Function|undefined
|
@Inject({ default: undefined }) __FormularioForm_unregister!: ((path: string, behavior: UnregisterBehaviour) => void)|undefined
|
||||||
|
|
||||||
@Inject({ default: () => (): Record<string, unknown> => ({}) })
|
@Inject({ default: () => (): Record<string, unknown> => ({}) })
|
||||||
__FormularioForm_getState!: () => Record<string, unknown>
|
__FormularioForm_getState!: () => Record<string, unknown>
|
||||||
@ -63,9 +59,9 @@ export default class FormularioField extends Vue {
|
|||||||
@Prop({ default: () => ({}) }) validationRules!: Record<string, ValidationRuleFn>
|
@Prop({ default: () => ({}) }) validationRules!: Record<string, ValidationRuleFn>
|
||||||
@Prop({ default: () => ({}) }) validationMessages!: Record<string, ValidationMessageI18NFn|string>
|
@Prop({ default: () => ({}) }) validationMessages!: Record<string, ValidationMessageI18NFn|string>
|
||||||
@Prop({
|
@Prop({
|
||||||
default: VALIDATION_BEHAVIOR.DEMAND,
|
default: 'demand',
|
||||||
validator: behavior => Object.values(VALIDATION_BEHAVIOR).includes(behavior)
|
validator: (behavior: string) => ['demand', 'live', 'submit'].includes(behavior)
|
||||||
}) validationBehavior!: string
|
}) validationBehavior!: ValidationBehaviour
|
||||||
|
|
||||||
// Affects only setting of local errors
|
// Affects only setting of local errors
|
||||||
@Prop({ default: false }) errorsDisabled!: boolean
|
@Prop({ default: false }) errorsDisabled!: boolean
|
||||||
@ -74,7 +70,7 @@ export default class FormularioField extends Vue {
|
|||||||
@Prop({ default: () => <T, U>(value: U|T): U|T => value }) modelSetConverter!: ModelSetConverter
|
@Prop({ default: () => <T, U>(value: U|T): U|T => value }) modelSetConverter!: ModelSetConverter
|
||||||
|
|
||||||
@Prop({ default: 'div' }) tag!: string
|
@Prop({ default: 'div' }) tag!: string
|
||||||
@Prop({ default: UNREGISTER_BEHAVIOR.NONE }) unregisterBehavior!: string
|
@Prop({ default: 'none' }) unregisterBehavior!: UnregisterBehaviour
|
||||||
|
|
||||||
public proxy: unknown = this.hasModel ? this.value : ''
|
public proxy: unknown = this.hasModel ? this.value : ''
|
||||||
|
|
||||||
@ -88,14 +84,12 @@ export default class FormularioField extends Vue {
|
|||||||
return this.__Formulario_path !== '' ? `${this.__Formulario_path}.${this.name}` : this.name
|
return this.__Formulario_path !== '' ? `${this.__Formulario_path}.${this.name}` : this.name
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Determines if this formulario element is v-modeled or not. */
|
||||||
* Determines if this formulario element is v-modeled or not.
|
|
||||||
*/
|
|
||||||
public get hasModel (): boolean {
|
public get hasModel (): boolean {
|
||||||
return has(this.$options.propsData || {}, 'value')
|
return has(this.$options.propsData || {}, 'value')
|
||||||
}
|
}
|
||||||
|
|
||||||
private get context (): FormularioFieldContext<unknown> {
|
private get context (): Context<unknown> {
|
||||||
return Object.defineProperty({
|
return Object.defineProperty({
|
||||||
name: this.fullPath,
|
name: this.fullPath,
|
||||||
path: this.fullPath,
|
path: this.fullPath,
|
||||||
@ -103,15 +97,15 @@ export default class FormularioField extends Vue {
|
|||||||
violations: this.violations,
|
violations: this.violations,
|
||||||
errors: this.localErrors,
|
errors: this.localErrors,
|
||||||
allErrors: [...this.localErrors, ...this.violations.map(v => v.message)],
|
allErrors: [...this.localErrors, ...this.violations.map(v => v.message)],
|
||||||
}, 'model', {
|
} as Context<unknown>, 'model', {
|
||||||
get: () => this.modelGetConverter(this.proxy),
|
get: () => this.modelGetConverter(this.proxy),
|
||||||
set: (value: unknown): void => {
|
set: (value: unknown): void => {
|
||||||
this.syncProxy(this.modelSetConverter(value, this.proxy))
|
this._syncProxy(this.modelSetConverter(value, this.proxy))
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private get normalizedValidationRules (): Record<string, ValidationRuleFn> {
|
private get _normalizedValidationRules (): Record<string, ValidationRuleFn> {
|
||||||
const rules: Record<string, ValidationRuleFn> = {}
|
const rules: Record<string, ValidationRuleFn> = {}
|
||||||
Object.keys(this.validationRules).forEach(key => {
|
Object.keys(this.validationRules).forEach(key => {
|
||||||
rules[snakeToCamel(key)] = this.validationRules[key]
|
rules[snakeToCamel(key)] = this.validationRules[key]
|
||||||
@ -119,7 +113,7 @@ export default class FormularioField extends Vue {
|
|||||||
return rules
|
return rules
|
||||||
}
|
}
|
||||||
|
|
||||||
private get normalizedValidationMessages (): Record<string, ValidationMessageI18NFn|string> {
|
private get _normalizedValidationMessages (): Record<string, ValidationMessageI18NFn|string> {
|
||||||
const messages: Record<string, ValidationMessageI18NFn|string> = {}
|
const messages: Record<string, ValidationMessageI18NFn|string> = {}
|
||||||
Object.keys(this.validationMessages).forEach(key => {
|
Object.keys(this.validationMessages).forEach(key => {
|
||||||
messages[snakeToCamel(key)] = this.validationMessages[key]
|
messages[snakeToCamel(key)] = this.validationMessages[key]
|
||||||
@ -128,42 +122,70 @@ export default class FormularioField extends Vue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Watch('value')
|
@Watch('value')
|
||||||
private onValueChange (): void {
|
private _onValueChange (): void {
|
||||||
this.syncProxy(this.value)
|
this._syncProxy(this.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Watch('proxy')
|
@Watch('proxy')
|
||||||
private onProxyChange (): void {
|
private _onProxyChange (): void {
|
||||||
if (this.validationBehavior === VALIDATION_BEHAVIOR.LIVE) {
|
if (this.validationBehavior === 'live') {
|
||||||
this.runValidation()
|
this.runValidation()
|
||||||
} else {
|
} else {
|
||||||
this.resetValidation()
|
this.resetValidation()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** @internal */
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
public created (): void {
|
public created (): void {
|
||||||
if (typeof this.__FormularioForm_register === 'function') {
|
if (typeof this.__FormularioForm_register === 'function') {
|
||||||
this.__FormularioForm_register(this.fullPath, this)
|
this.__FormularioForm_register(this.fullPath, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.validationBehavior === VALIDATION_BEHAVIOR.LIVE) {
|
if (this.validationBehavior === 'live') {
|
||||||
this.runValidation()
|
this.runValidation()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** @internal */
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
public beforeDestroy (): void {
|
public beforeDestroy (): void {
|
||||||
if (typeof this.__FormularioForm_unregister === 'function') {
|
if (typeof this.__FormularioForm_unregister === 'function') {
|
||||||
this.__FormularioForm_unregister(this.fullPath, this.unregisterBehavior)
|
this.__FormularioForm_unregister(this.fullPath, this.unregisterBehavior)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private syncProxy (value: unknown): void {
|
public runValidation (): Promise<Violation[]> {
|
||||||
|
this.validationRun = this._validate().then(violations => {
|
||||||
|
this.violations = violations
|
||||||
|
this._emitValidation(this.fullPath, violations)
|
||||||
|
|
||||||
|
return this.violations
|
||||||
|
})
|
||||||
|
|
||||||
|
return this.validationRun
|
||||||
|
}
|
||||||
|
|
||||||
|
public hasValidationErrors (): Promise<boolean> {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.validationRun.then(() => resolve(this.violations.length > 0))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
|
public setErrors (errors: string[]): void {
|
||||||
|
if (!this.errorsDisabled) {
|
||||||
|
this.localErrors = errors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
|
public resetValidation (): void {
|
||||||
|
this.localErrors = []
|
||||||
|
this.violations = []
|
||||||
|
}
|
||||||
|
|
||||||
|
private _syncProxy (value: unknown): void {
|
||||||
if (!deepEquals(value, this.proxy)) {
|
if (!deepEquals(value, this.proxy)) {
|
||||||
this.proxy = value
|
this.proxy = value
|
||||||
this.$emit('input', value)
|
this.$emit('input', value)
|
||||||
@ -175,22 +197,11 @@ export default class FormularioField extends Vue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public runValidation (): Promise<Violation[]> {
|
private _validate (): Promise<Violation[]> {
|
||||||
this.validationRun = this.validate().then(violations => {
|
|
||||||
this.violations = violations
|
|
||||||
this.emitValidation(this.fullPath, violations)
|
|
||||||
|
|
||||||
return this.violations
|
|
||||||
})
|
|
||||||
|
|
||||||
return this.validationRun
|
|
||||||
}
|
|
||||||
|
|
||||||
private validate (): Promise<Violation[]> {
|
|
||||||
return validate(processConstraints(
|
return validate(processConstraints(
|
||||||
this.validation,
|
this.validation,
|
||||||
this.$formulario.getRules(this.normalizedValidationRules),
|
this.$formulario.getRules(this._normalizedValidationRules),
|
||||||
this.$formulario.getMessages(this, this.normalizedValidationMessages),
|
this.$formulario.getMessages(this, this._normalizedValidationMessages),
|
||||||
), {
|
), {
|
||||||
value: this.proxy,
|
value: this.proxy,
|
||||||
name: this.fullPath,
|
name: this.fullPath,
|
||||||
@ -198,36 +209,11 @@ export default class FormularioField extends Vue {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private emitValidation (path: string, violations: Violation[]): void {
|
private _emitValidation (path: string, violations: Violation[]): void {
|
||||||
this.$emit('validation', { path, violations })
|
this.$emit('validation', { path, violations })
|
||||||
if (typeof this.__FormularioForm_emitValidation === 'function') {
|
if (typeof this.__FormularioForm_emitValidation === 'function') {
|
||||||
this.__FormularioForm_emitValidation(path, violations)
|
this.__FormularioForm_emitValidation(path, violations)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public hasValidationErrors (): Promise<boolean> {
|
|
||||||
return new Promise(resolve => {
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.validationRun.then(() => resolve(this.violations.length > 0))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
public setErrors (errors: string[]): void {
|
|
||||||
if (!this.errorsDisabled) {
|
|
||||||
this.localErrors = errors
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
public resetValidation (): void {
|
|
||||||
this.localErrors = []
|
|
||||||
this.violations = []
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -5,7 +5,11 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import type { UnregisterBehaviour } from '../types/field'
|
||||||
|
import type { Violation } from '../types/validation'
|
||||||
|
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Component,
|
Component,
|
||||||
Model,
|
Model,
|
||||||
@ -13,6 +17,7 @@ import {
|
|||||||
Provide,
|
Provide,
|
||||||
Watch,
|
Watch,
|
||||||
} from 'vue-property-decorator'
|
} from 'vue-property-decorator'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
id,
|
id,
|
||||||
clone,
|
clone,
|
||||||
@ -25,9 +30,6 @@ import {
|
|||||||
} from '@/utils'
|
} from '@/utils'
|
||||||
|
|
||||||
import { FormularioField } from '@/types'
|
import { FormularioField } from '@/types'
|
||||||
import { Violation } from '@/validation/validator'
|
|
||||||
|
|
||||||
import { UNREGISTER_BEHAVIOR } from '@/enum'
|
|
||||||
|
|
||||||
const update = (state: Record<string, unknown>, path: string, value: unknown): Record<string, unknown> => {
|
const update = (state: Record<string, unknown>, path: string, value: unknown): Record<string, unknown> => {
|
||||||
if (value === undefined) {
|
if (value === undefined) {
|
||||||
@ -90,11 +92,11 @@ export default class FormularioForm extends Vue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Provide('__FormularioForm_unregister')
|
@Provide('__FormularioForm_unregister')
|
||||||
private unregister (path: string, behavior: string): void {
|
private unregister (path: string, behavior: UnregisterBehaviour): void {
|
||||||
if (this.registry.has(path)) {
|
if (this.registry.has(path)) {
|
||||||
this.registry.delete(path)
|
this.registry.delete(path)
|
||||||
|
|
||||||
if (behavior === UNREGISTER_BEHAVIOR.UNSET) {
|
if (behavior === 'unset') {
|
||||||
this.proxy = unset(this.proxy, path) as Record<string, unknown>
|
this.proxy = unset(this.proxy, path) as Record<string, unknown>
|
||||||
this.emitInput()
|
this.emitInput()
|
||||||
}
|
}
|
||||||
@ -183,17 +185,17 @@ export default class FormularioForm extends Vue {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
public setErrors ({ fieldsErrors, formErrors }: {
|
public setErrors ({ formErrors, fieldsErrors }: {
|
||||||
fieldsErrors?: Record<string, string[]>;
|
|
||||||
formErrors?: string[];
|
formErrors?: string[];
|
||||||
|
fieldsErrors?: Record<string, string[]>;
|
||||||
}): void {
|
}): void {
|
||||||
this.localFieldsErrors = fieldsErrors || {}
|
|
||||||
this.localFormErrors = formErrors || []
|
this.localFormErrors = formErrors || []
|
||||||
|
this.localFieldsErrors = fieldsErrors || {}
|
||||||
}
|
}
|
||||||
|
|
||||||
public resetValidation (): void {
|
public resetValidation (): void {
|
||||||
this.localFieldsErrors = {}
|
|
||||||
this.localFormErrors = []
|
this.localFormErrors = []
|
||||||
|
this.localFieldsErrors = {}
|
||||||
this.registry.forEach((field: FormularioField) => {
|
this.registry.forEach((field: FormularioField) => {
|
||||||
field.resetValidation()
|
field.resetValidation()
|
||||||
})
|
})
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
export const UNREGISTER_BEHAVIOR = {
|
|
||||||
NONE: 'none',
|
|
||||||
UNSET: 'unset',
|
|
||||||
}
|
|
14
src/index.ts
14
src/index.ts
@ -1,14 +1,22 @@
|
|||||||
import { VueConstructor } from 'vue'
|
import type { VueConstructor } from 'vue'
|
||||||
|
import type { Options } from '../types/plugin'
|
||||||
|
|
||||||
import Formulario, { FormularioOptions } from '@/Formulario.ts'
|
import Formulario from '@/Formulario'
|
||||||
|
|
||||||
import FormularioField from '@/FormularioField.vue'
|
import FormularioField from '@/FormularioField.vue'
|
||||||
import FormularioFieldGroup from '@/FormularioFieldGroup.vue'
|
import FormularioFieldGroup from '@/FormularioFieldGroup.vue'
|
||||||
import FormularioForm from '@/FormularioForm.vue'
|
import FormularioForm from '@/FormularioForm.vue'
|
||||||
|
|
||||||
|
export {
|
||||||
|
Formulario,
|
||||||
|
FormularioField,
|
||||||
|
FormularioFieldGroup,
|
||||||
|
FormularioForm,
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
Formulario,
|
Formulario,
|
||||||
install (Vue: VueConstructor, options?: FormularioOptions): void {
|
install (Vue: VueConstructor, options?: Options): void {
|
||||||
Vue.component('FormularioField', FormularioField)
|
Vue.component('FormularioField', FormularioField)
|
||||||
Vue.component('FormularioFieldGroup', FormularioFieldGroup)
|
Vue.component('FormularioFieldGroup', FormularioFieldGroup)
|
||||||
Vue.component('FormularioForm', FormularioForm)
|
Vue.component('FormularioForm', FormularioForm)
|
||||||
|
9
src/shims-ext.d.ts
vendored
9
src/shims-ext.d.ts
vendored
@ -3,12 +3,7 @@ import Formulario from '@/Formulario'
|
|||||||
declare module 'vue/types/vue' {
|
declare module 'vue/types/vue' {
|
||||||
interface Vue {
|
interface Vue {
|
||||||
$formulario: Formulario;
|
$formulario: Formulario;
|
||||||
$route: VueRoute;
|
$t: any;
|
||||||
$t: Function;
|
$tc: any;
|
||||||
$tc: Function;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface VueRoute {
|
|
||||||
path: string;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
27
src/types.ts
27
src/types.ts
@ -1,10 +1,6 @@
|
|||||||
import Vue from 'vue'
|
import type { Violation } from '../types/validation'
|
||||||
import { Violation } from '@/validation/validator'
|
|
||||||
|
|
||||||
export interface FormularioForm extends Vue {
|
import Vue from 'vue'
|
||||||
runValidation(): Promise<Record<string, Violation[]>>;
|
|
||||||
resetValidation(): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface FormularioField extends Vue {
|
export interface FormularioField extends Vue {
|
||||||
hasModel: boolean;
|
hasModel: boolean;
|
||||||
@ -14,25 +10,6 @@ export interface FormularioField extends Vue {
|
|||||||
resetValidation(): void;
|
resetValidation(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type FormularioFieldContext<T> = {
|
|
||||||
model: T;
|
|
||||||
name: string;
|
|
||||||
runValidation(): Promise<Violation[]>;
|
|
||||||
violations: Violation[];
|
|
||||||
errors: string[];
|
|
||||||
allErrors: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface FormularioFieldModelGetConverter {
|
|
||||||
<U, T>(value: U|Empty): U|T|Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface FormularioFieldModelSetConverter {
|
|
||||||
<T, U>(curr: U|T, prev: U|Empty): U|T;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Empty = undefined | null
|
|
||||||
|
|
||||||
export enum TYPE {
|
export enum TYPE {
|
||||||
ARRAY = 'ARRAY',
|
ARRAY = 'ARRAY',
|
||||||
BIGINT = 'BIGINT',
|
BIGINT = 'BIGINT',
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import isPlainObject from 'is-plain-object'
|
import isPlainObject from 'is-plain-object'
|
||||||
import has from '@/utils/has.ts'
|
import has from '@/utils/has'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new object by copying properties of base and mergeWith.
|
* Create a new object by copying properties of base and mergeWith.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import {
|
import type {
|
||||||
ValidationContext,
|
ValidationContext,
|
||||||
ValidationMessageI18NFn,
|
ValidationMessageI18NFn,
|
||||||
} from '@/validation/validator'
|
} from '../../types/validation'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Message builders, names match rules names, see @/validation/rules
|
* Message builders, names match rules names, see @/validation/rules
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import isUrl from 'is-url'
|
import type {
|
||||||
import { has, regexForFormat, shallowEquals } from '@/utils'
|
|
||||||
import {
|
|
||||||
ValidationContext,
|
ValidationContext,
|
||||||
ValidationRuleFn,
|
ValidationRuleFn,
|
||||||
} from '@/validation/validator'
|
} from '../../types/validation'
|
||||||
|
|
||||||
|
import isUrl from 'is-url'
|
||||||
|
import { has, regexForFormat, shallowEquals } from '@/utils'
|
||||||
|
|
||||||
const rules: Record<string, ValidationRuleFn> = {
|
const rules: Record<string, ValidationRuleFn> = {
|
||||||
/**
|
/**
|
||||||
|
@ -1,42 +1,14 @@
|
|||||||
|
import type {
|
||||||
|
ValidationContext,
|
||||||
|
ValidationMessageFn,
|
||||||
|
ValidationRuleFn,
|
||||||
|
Validator,
|
||||||
|
ValidatorGroup,
|
||||||
|
Violation,
|
||||||
|
} from '../../types/validation'
|
||||||
|
|
||||||
import { has, snakeToCamel } from '@/utils'
|
import { has, snakeToCamel } from '@/utils'
|
||||||
|
|
||||||
export interface Validator {
|
|
||||||
(context: ValidationContext): Promise<Violation|null>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Violation {
|
|
||||||
message: string;
|
|
||||||
rule: string|null;
|
|
||||||
args: any[];
|
|
||||||
context: ValidationContext|null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ValidationRuleFn {
|
|
||||||
(context: ValidationContext, ...args: any[]): Promise<boolean>|boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ValidationMessageFn {
|
|
||||||
(context: ValidationContext, ...args: any[]): string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ValidationMessageI18NFn {
|
|
||||||
(vm: Vue, context: ValidationContext, ...args: any[]): string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ValidationContext {
|
|
||||||
// The value of the field (do not mutate!),
|
|
||||||
value: any;
|
|
||||||
// If wrapped in a FormulateForm, the value of other form fields.
|
|
||||||
formValues: Record<string, any>;
|
|
||||||
// The validation name to be used
|
|
||||||
name: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type ValidatorGroup = {
|
|
||||||
validators: Validator[];
|
|
||||||
bail: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createValidator (
|
export function createValidator (
|
||||||
ruleFn: ValidationRuleFn,
|
ruleFn: ValidationRuleFn,
|
||||||
ruleName: string|null,
|
ruleName: string|null,
|
||||||
|
@ -4,7 +4,6 @@ import { mount } from '@vue/test-utils'
|
|||||||
import flushPromises from 'flush-promises'
|
import flushPromises from 'flush-promises'
|
||||||
|
|
||||||
import Formulario from '@/index.ts'
|
import Formulario from '@/index.ts'
|
||||||
import FormularioFieldGroup from '@/FormularioFieldGroup.vue'
|
|
||||||
import FormularioForm from '@/FormularioForm.vue'
|
import FormularioForm from '@/FormularioForm.vue'
|
||||||
|
|
||||||
Vue.use(Formulario)
|
Vue.use(Formulario)
|
||||||
|
34
types/field.d.ts
vendored
Normal file
34
types/field.d.ts
vendored
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import type { Violation } from './validation'
|
||||||
|
|
||||||
|
export type Empty = undefined | null
|
||||||
|
|
||||||
|
export type Context<T> = {
|
||||||
|
model: T;
|
||||||
|
name: string;
|
||||||
|
path: string;
|
||||||
|
violations: Violation[];
|
||||||
|
errors: string[];
|
||||||
|
allErrors: string[];
|
||||||
|
runValidation(): Promise<Violation[]>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ModelGetConverter {
|
||||||
|
<U, T>(value: U|Empty): U|T|Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ModelSetConverter {
|
||||||
|
<T, U>(curr: U|T, prev: U|Empty): U|T;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* - 'demand': triggers validation on manual call
|
||||||
|
* - 'live': triggers validation on any changes
|
||||||
|
* - 'submit': triggers validation on form submit event
|
||||||
|
*/
|
||||||
|
export type ValidationBehaviour = 'demand' | 'live' | 'submit'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* - 'none': no any specific effects
|
||||||
|
* - 'unset': the value under field's path will be unset and path will be removed from the state
|
||||||
|
*/
|
||||||
|
export type UnregisterBehaviour = 'none' | 'unset'
|
17
types/form.d.ts
vendored
Normal file
17
types/form.d.ts
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import type { DefineComponent } from './vue'
|
||||||
|
import type { Violation } from './validation'
|
||||||
|
|
||||||
|
export type FormularioFormConstructor = DefineComponent<{
|
||||||
|
id?: string;
|
||||||
|
state?: Record<string, unknown>;
|
||||||
|
fieldsErrors?: Record<string, string[]>;
|
||||||
|
formErrors?: string[];
|
||||||
|
}, {
|
||||||
|
setErrors ({ formErrors, fieldsErrors }: {
|
||||||
|
formErrors?: string[];
|
||||||
|
fieldsErrors?: Record<string, string[]>;
|
||||||
|
}): void;
|
||||||
|
runValidation(): Promise<Record<string, Violation[]>>;
|
||||||
|
hasValidationErrors (): Promise<boolean>;
|
||||||
|
resetValidation(): void;
|
||||||
|
}>
|
9
types/plugin.d.ts
vendored
Normal file
9
types/plugin.d.ts
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import type {
|
||||||
|
ValidationMessageI18NFn,
|
||||||
|
ValidationRuleFn
|
||||||
|
} from './validation'
|
||||||
|
|
||||||
|
export interface Options {
|
||||||
|
validationRules?: Record<string, ValidationRuleFn>;
|
||||||
|
validationMessages?: Record<string, ValidationMessageI18NFn|string>;
|
||||||
|
}
|
38
types/validation.d.ts
vendored
Normal file
38
types/validation.d.ts
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import { Vue } from 'vue/types/vue'
|
||||||
|
|
||||||
|
export interface ValidationContext {
|
||||||
|
// The value of the field (do not mutate!),
|
||||||
|
value: any;
|
||||||
|
// If wrapped in a FormulateForm, the value of other form fields.
|
||||||
|
formValues: Record<string, any>;
|
||||||
|
// The validation name to be used
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Violation {
|
||||||
|
message: string;
|
||||||
|
rule: string|null;
|
||||||
|
args: any[];
|
||||||
|
context: ValidationContext|null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Validator {
|
||||||
|
(context: ValidationContext): Promise<Violation|null>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ValidatorGroup = {
|
||||||
|
validators: Validator[];
|
||||||
|
bail: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ValidationRuleFn {
|
||||||
|
(context: ValidationContext, ...args: any[]): Promise<boolean>|boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ValidationMessageFn {
|
||||||
|
(context: ValidationContext, ...args: any[]): string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ValidationMessageI18NFn {
|
||||||
|
(vm: Vue, context: ValidationContext, ...args: any[]): string;
|
||||||
|
}
|
3
types/vue.d.ts
vendored
Normal file
3
types/vue.d.ts
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import type { Vue, VueConstructor } from 'vue/types/vue'
|
||||||
|
|
||||||
|
export type DefineComponent<Props, Methods> = VueConstructor<Vue & Required<Props> & Methods>
|
Loading…
Reference in New Issue
Block a user