form-validity
Advanced tools
+60
-96
@@ -1,65 +0,14 @@ | ||
| interface Required { | ||
| required: (message?: string) => this; | ||
| } | ||
| interface Min<Value> { | ||
| min(value: Value | string, message?: string): this; | ||
| } | ||
| interface Max<Value> { | ||
| max(value: Value | string, message?: string): this; | ||
| } | ||
| interface MinLength { | ||
| minLength(number: number, message?: string): this; | ||
| } | ||
| interface MaxLength { | ||
| maxLength(number: number, message?: string): this; | ||
| } | ||
| interface Pattern { | ||
| pattern(regexp: RegExp, message?: string): this; | ||
| } | ||
| interface Step { | ||
| step(number: number | string, message?: string): this; | ||
| } | ||
| interface Multiple<Count = void> { | ||
| multiple(count: Count): this; | ||
| } | ||
| interface NoConstraint { | ||
| } | ||
| export interface FieldAttributes { | ||
| type?: Exclude<keyof FieldOption, 'select' | 'textarea' | 'fieldset'>; | ||
| required?: boolean; | ||
| minLength?: number; | ||
| maxLength?: number; | ||
| min?: string | number; | ||
| max?: string | number; | ||
| step?: string | number; | ||
| pattern?: string; | ||
| multiple?: boolean; | ||
| } | ||
| export interface FieldOption { | ||
| checkbox: Required; | ||
| color: NoConstraint; | ||
| date: Required & Min<Date> & Max<Date> & Step; | ||
| datetime: Required & Min<Date> & Max<Date> & Step; | ||
| 'datetime-local': Required & Min<Date> & Max<Date> & Step; | ||
| email: Required & MinLength & MaxLength & Pattern; | ||
| fieldset: Multiple<Number>; | ||
| file: Required; | ||
| hidden: NoConstraint; | ||
| month: Required & Min<Date> & Max<Date> & Step; | ||
| number: Required & Min<number> & Max<number> & Step; | ||
| password: Required & MinLength & MaxLength & Pattern; | ||
| radio: Required; | ||
| range: Min<number> & Max<number> & Step; | ||
| search: Required & MinLength & MaxLength & Pattern; | ||
| select: Required; | ||
| tel: Required & MinLength & MaxLength & Pattern; | ||
| text: Required & MinLength & MaxLength & Pattern; | ||
| textarea: Required & MinLength & MaxLength; | ||
| time: Required & Min<Date> & Max<Date> & Step; | ||
| url: Required & MinLength & MaxLength & Pattern; | ||
| week: Required & Min<Date> & Max<Date> & Step; | ||
| } | ||
| export interface Constraint { | ||
| type: { | ||
| value: keyof FieldOption; | ||
| /** | ||
| * | ||
| */ | ||
| declare const symbol: unique symbol; | ||
| export declare type FieldTag = 'input' | 'textarea' | 'select' | 'fieldset'; | ||
| export declare type InputType = 'checkbox' | 'color' | 'date' | 'date' | 'datetime-local' | 'email' | 'fieldset' | 'file' | 'hidden' | 'month' | 'number' | 'password' | 'radio' | 'range' | 'search' | 'select' | 'tel' | 'text' | 'textarea' | 'time' | 'url' | 'week'; | ||
| export declare type Field<Tag extends FieldTag = FieldTag, Type extends InputType | undefined = undefined> = (Tag extends 'input' ? Type extends 'checkbox' | 'file' | 'radio' ? Required : Type extends 'date' | 'datetime-local' | 'month' | 'time' | 'week' ? Required & Min<Date> & Max<Date> & Step : Type extends 'email' | 'password' | 'search' | 'tel' | 'text' | 'url' ? Required & MinLength & MaxLength & Pattern : Type extends 'number' ? Required & Min<number> & Max<number> & Step : Type extends 'range' ? Min<number> & Max<number> & Step : {} : Tag extends 'select' ? Required : Tag extends 'textarea' ? Required & MinLength & MaxLength : Tag extends 'fieldset' ? Multiple<number> : unknown) & { | ||
| [symbol]: Constraint<Tag>; | ||
| }; | ||
| export declare type Constraint<Tag extends FieldTag = FieldTag> = { | ||
| tag: Tag; | ||
| type?: { | ||
| value: InputType; | ||
| message: string | undefined; | ||
@@ -98,47 +47,62 @@ }; | ||
| }; | ||
| } | ||
| declare const symbol: unique symbol; | ||
| export declare type Field<Type extends keyof FieldOption = keyof FieldOption> = FieldOption[Type] & { | ||
| [symbol]: () => Constraint; | ||
| }; | ||
| /** | ||
| * Helpers for constructing the field constraints | ||
| * Helpers for constructing the field constraint based on the type | ||
| * @see https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Constraint_validation#validation-related_attributes | ||
| */ | ||
| export declare const f: { | ||
| checkbox: () => Field<"checkbox">; | ||
| color: () => Field<"color">; | ||
| date: () => Field<"date">; | ||
| datetime: () => Field<"datetime-local">; | ||
| email: (message?: string | undefined) => Field<"email">; | ||
| fieldset: () => Field<"fieldset">; | ||
| file: () => Field<"file">; | ||
| hidden: () => Field<"hidden">; | ||
| month: () => Field<"month">; | ||
| number: (message?: string | undefined) => Field<"number">; | ||
| password: () => Field<"password">; | ||
| radio: () => Field<"radio">; | ||
| range: () => Field<"range">; | ||
| search: () => Field<"search">; | ||
| select: () => Field<"select">; | ||
| tel: () => Field<"tel">; | ||
| text: () => Field<"text">; | ||
| textarea: () => Field<"textarea">; | ||
| time: () => Field<"time">; | ||
| url: (message?: string | undefined) => Field<"url">; | ||
| week: () => Field<"week">; | ||
| input: { | ||
| <T extends "number" | "email" | "url">(type: T, message?: string | undefined): Field<"input", T>; | ||
| <T_1 extends "textarea" | "select" | "fieldset" | "checkbox" | "color" | "date" | "datetime-local" | "file" | "hidden" | "month" | "password" | "radio" | "range" | "search" | "tel" | "text" | "time" | "week">(type: T_1): Field<"input", T_1>; | ||
| }; | ||
| select: () => Field<'select'>; | ||
| textarea: () => Field<'textarea'>; | ||
| fieldset: () => Field<'fieldset'>; | ||
| }; | ||
| export declare function getConstraint<Type extends keyof FieldOption>(field: Field<Type>): Constraint; | ||
| export declare function getConstraint<Tag extends FieldTag>(field: Field<Tag>): Constraint<Tag>; | ||
| export declare function isElement<T extends HTMLElement>(element: any, tag: string): element is T; | ||
| export declare function isInputElement(element: unknown): element is HTMLInputElement; | ||
| export declare function isSelectElement(element: unknown): element is HTMLSelectElement; | ||
| export declare function isTextareaElement(element: unknown): element is HTMLTextAreaElement; | ||
| export declare function isButtonElement(element: unknown): element is HTMLButtonElement; | ||
| export declare function isDirtyField(element: HTMLSelectElement | HTMLInputElement | HTMLTextAreaElement): boolean; | ||
| export declare function isDirty(element: unknown): boolean; | ||
| export declare function isValidationConstraintSupported(element: unknown): element is HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement; | ||
| export declare function shouldSkipValidate(element: unknown): boolean; | ||
| export declare function draftUpdate(name: string, index?: number): { | ||
| name: string; | ||
| value: string; | ||
| }; | ||
| export declare function getDraft(payload: URLSearchParams | FormData): { | ||
| name: string; | ||
| index: number | null; | ||
| } | null; | ||
| export declare function parse<T>(payload: FormData | URLSearchParams | string, fieldsetCreator: ((value?: Record<string, any>) => Record<string, T>) | Record<string, T>): { | ||
| value: Record<string, any>; | ||
| error: Record<string, string> | null; | ||
| isDraft: boolean; | ||
| }; | ||
| /** | ||
| * Helpers | ||
| */ | ||
| interface Required { | ||
| required(message?: string): this; | ||
| } | ||
| interface Min<Value> { | ||
| min(value: Value | string, message?: string): this; | ||
| } | ||
| interface Max<Value> { | ||
| max(value: Value | string, message?: string): this; | ||
| } | ||
| interface MinLength { | ||
| minLength(number: number, message?: string): this; | ||
| } | ||
| interface MaxLength { | ||
| maxLength(number: number, message?: string): this; | ||
| } | ||
| interface Pattern { | ||
| pattern(regexp: RegExp, message?: string): this; | ||
| } | ||
| interface Step { | ||
| step(number: number | string, message?: string): this; | ||
| } | ||
| interface Multiple<Count = void> { | ||
| multiple(count: Count): this; | ||
| } | ||
| export declare function checkCustomValidity(value: FormDataEntryValue, validity: ValidityState, constraint: Constraint): string | null; | ||
| export {}; |
+307
-266
@@ -5,111 +5,113 @@ 'use strict'; | ||
| var attributesByType = { | ||
| // 'button': [], | ||
| checkbox: ['required'], | ||
| color: [], | ||
| date: ['required', 'minLength', 'maxLength', 'pattern'], | ||
| datetime: ['required', 'minLength', 'maxLength', 'pattern'], | ||
| 'datetime-local': ['required', 'minLength', 'maxLength', 'pattern'], | ||
| email: ['required', 'minLength', 'maxLength', 'pattern'], | ||
| fieldset: ['multiple'], | ||
| file: ['required'], | ||
| hidden: [], | ||
| // 'image': [], | ||
| month: ['required', 'minLength', 'maxLength', 'pattern'], | ||
| number: ['required', 'minLength', 'maxLength', 'pattern'], | ||
| password: ['required', 'minLength', 'maxLength', 'pattern'], | ||
| radio: ['required'], | ||
| range: ['min', 'max', 'step'], | ||
| // 'reset': [], | ||
| search: ['required', 'minLength', 'maxLength', 'pattern'], | ||
| select: ['required'], | ||
| // 'submit': [], | ||
| tel: ['required', 'minLength', 'maxLength', 'pattern'], | ||
| text: ['required', 'minLength', 'maxLength', 'pattern'], | ||
| textarea: ['required', 'minLength', 'maxLength'], | ||
| time: ['required', 'minLength', 'maxLength', 'pattern'], | ||
| url: ['required', 'minLength', 'maxLength', 'pattern'], | ||
| week: ['required', 'minLength', 'maxLength', 'pattern'] | ||
| }; | ||
| var symbol = Symbol('constraints'); | ||
| /** | ||
| * | ||
| */ | ||
| var symbol = Symbol('constraint'); | ||
| function createField(type, message) { | ||
| var supportedAttributes = attributesByType[type]; | ||
| var constraint = { | ||
| type: { | ||
| value: type, | ||
| message: message | ||
| } | ||
| }; | ||
| var field = { | ||
| required(message) { | ||
| constraint.required = { | ||
| message | ||
| }; | ||
| return field; | ||
| }, | ||
| function configureF() { | ||
| function createField(tag, type, message) { | ||
| var constraint = { | ||
| tag | ||
| }; | ||
| min(value, message) { | ||
| constraint.min = { | ||
| value, | ||
| if (type) { | ||
| constraint.type = { | ||
| value: type, | ||
| message | ||
| }; | ||
| return field; | ||
| }, | ||
| } | ||
| max(value, message) { | ||
| constraint.max = { | ||
| value, | ||
| message | ||
| }; | ||
| return field; | ||
| }, | ||
| return { | ||
| required(message) { | ||
| constraint.required = { | ||
| message | ||
| }; | ||
| return this; | ||
| }, | ||
| minLength(value, message) { | ||
| constraint.minLength = { | ||
| value, | ||
| message | ||
| }; | ||
| return field; | ||
| }, | ||
| min(value, message) { | ||
| constraint.min = { | ||
| value, | ||
| message | ||
| }; | ||
| return this; | ||
| }, | ||
| maxLength(value, message) { | ||
| constraint.maxLength = { | ||
| value, | ||
| message | ||
| }; | ||
| return field; | ||
| }, | ||
| max(value, message) { | ||
| constraint.max = { | ||
| value, | ||
| message | ||
| }; | ||
| return this; | ||
| }, | ||
| pattern(value, message) { | ||
| if (value.global || value.ignoreCase || value.multiline) { | ||
| console.warn("global, ignoreCase, and multiline flags are not supported on the pattern attribute"); | ||
| } else { | ||
| var _constraint$pattern; | ||
| minLength(value, message) { | ||
| constraint.minLength = { | ||
| value, | ||
| message | ||
| }; | ||
| return this; | ||
| }, | ||
| constraint.pattern = ((_constraint$pattern = constraint.pattern) !== null && _constraint$pattern !== void 0 ? _constraint$pattern : []).concat({ | ||
| maxLength(value, message) { | ||
| constraint.maxLength = { | ||
| value, | ||
| message | ||
| }); | ||
| } | ||
| }; | ||
| return this; | ||
| }, | ||
| return field; | ||
| }, | ||
| pattern(value, message) { | ||
| if (value.global || value.ignoreCase || value.multiline) { | ||
| console.warn("global, ignoreCase, and multiline flags are not supported on the pattern attribute"); | ||
| } else { | ||
| var _constraint$pattern; | ||
| multiple(value) { | ||
| constraint.multiple = { | ||
| value, | ||
| message | ||
| }; | ||
| return field; | ||
| }, | ||
| constraint.pattern = ((_constraint$pattern = constraint.pattern) !== null && _constraint$pattern !== void 0 ? _constraint$pattern : []).concat({ | ||
| value, | ||
| message | ||
| }); | ||
| } | ||
| [symbol]: () => constraint | ||
| }; // @ts-ignore | ||
| return this; | ||
| }, | ||
| return Object.fromEntries( // @ts-ignore | ||
| [symbol, ...supportedAttributes].map(key => [key, field[key]])); | ||
| multiple(value) { | ||
| constraint.multiple = { | ||
| value, | ||
| message | ||
| }; | ||
| return this; | ||
| }, | ||
| [symbol]: constraint | ||
| }; | ||
| } | ||
| function input(type, message) { | ||
| // @ts-expect-error | ||
| return createField('input', type, message); | ||
| } | ||
| function select() { | ||
| return createField('select'); | ||
| } | ||
| function textarea() { | ||
| return createField('textarea'); | ||
| } | ||
| function fieldset() { | ||
| return createField('fieldset'); | ||
| } | ||
| return { | ||
| input, | ||
| select, | ||
| textarea, | ||
| fieldset | ||
| }; | ||
| } | ||
| /** | ||
| * Helpers for constructing the field constraints | ||
| * Helpers for constructing the field constraint based on the type | ||
| * @see https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Constraint_validation#validation-related_attributes | ||
@@ -119,63 +121,38 @@ */ | ||
| var f = { | ||
| // button: () => createField('button'), | ||
| checkbox: () => createField('checkbox'), | ||
| color: () => createField('color'), | ||
| date: () => createField('date'), | ||
| // datetime: () => createField('datetime'), | ||
| datetime: () => createField('datetime-local'), | ||
| // `datetime` is deprecated | ||
| email: message => createField('email', message), | ||
| fieldset: () => createField('fieldset'), | ||
| file: () => createField('file'), | ||
| hidden: () => createField('hidden'), | ||
| // image: () => createField('image'), | ||
| month: () => createField('month'), | ||
| number: message => createField('number', message), | ||
| password: () => createField('password'), | ||
| radio: () => createField('radio'), | ||
| range: () => createField('range'), | ||
| // reset: () => createField('reset'), | ||
| search: () => createField('search'), | ||
| select: () => createField('select'), | ||
| // submit: () => createField('submit'), | ||
| tel: () => createField('tel'), | ||
| text: () => createField('text'), | ||
| textarea: () => createField('textarea'), | ||
| time: () => createField('time'), | ||
| url: message => createField('url', message), | ||
| week: () => createField('week') | ||
| }; | ||
| var f = configureF(); | ||
| function getConstraint(field) { | ||
| return field[symbol](); | ||
| } // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
| if (typeof field[symbol] === 'undefined') { | ||
| throw new Error('Provided config is not a field; Please ensure only field object is used'); | ||
| } | ||
| return field[symbol]; | ||
| } | ||
| function isElement(element, tag) { | ||
| return !!element && element.tagName.toLowerCase() === tag; | ||
| } | ||
| function isInputElement(element) { | ||
| return isElement(element, 'input'); | ||
| } | ||
| function isSelectElement(element) { | ||
| return isElement(element, 'select'); | ||
| } | ||
| function isTextareaElement(element) { | ||
| return isElement(element, 'textarea'); | ||
| } | ||
| function isButtonElement(element) { | ||
| return isElement(element, 'button'); | ||
| } | ||
| function isDirtyField(element) { | ||
| function isDirty(element) { | ||
| if (isElement(element, 'form')) { | ||
| for (var el of element.elements) { | ||
| if (isDirty(el)) { | ||
| return true; | ||
| } | ||
| } | ||
| return false; | ||
| } | ||
| if (isElement(element, 'input') || isElement(element, 'textarea')) { | ||
| return element.value !== element.defaultValue; | ||
| } else if (isElement(element, 'select')) { | ||
| } | ||
| if (isElement(element, 'select')) { | ||
| var _Array$from$find; | ||
| return element.value !== ((_Array$from$find = Array.from(element.options).find(option => option.defaultSelected)) === null || _Array$from$find === void 0 ? void 0 : _Array$from$find.value); | ||
| } else { | ||
| return false; | ||
| } | ||
| return false; | ||
| } | ||
| function isValidationConstraintSupported(element) { | ||
| if (!isInputElement(element) && !isSelectElement(element) && !isTextareaElement(element)) { | ||
| if (!isElement(element, 'input') && !isElement(element, 'select') && !isElement(element, 'textarea')) { | ||
| return false; | ||
@@ -187,5 +164,106 @@ } | ||
| function shouldSkipValidate(element) { | ||
| return isButtonElement(element) || isInputElement(element) ? element.formNoValidate : false; | ||
| return isElement(element, 'button') || isElement(element, 'input') ? element.formNoValidate : false; | ||
| } | ||
| function draftUpdate(name, index) { | ||
| return { | ||
| name: '__form-validity__', | ||
| value: [name].concat(typeof index === 'undefined' ? [] : ["".concat(index)]).join('|') | ||
| }; | ||
| } | ||
| function getDraft(payload) { | ||
| var update = payload.get('__form-validity__'); | ||
| if (!update) { | ||
| return null; | ||
| } // We are mutating the payload here | ||
| payload.delete('__form-validity__'); | ||
| if (update instanceof File) { | ||
| throw new Error('What?'); | ||
| } | ||
| var [name, indexString] = update.split('|'); | ||
| var index = typeof indexString !== 'undefined' ? Number(indexString) : null; | ||
| return { | ||
| name, | ||
| index | ||
| }; | ||
| } | ||
| function parse(payload, fieldsetCreator) { | ||
| var valueEntries = payload instanceof URLSearchParams || payload instanceof FormData ? payload : new URLSearchParams(payload); | ||
| var update = getDraft(valueEntries); | ||
| var value = unflatten(valueEntries); | ||
| if (update) { | ||
| var list = getItem(value, update.name); | ||
| if (!Array.isArray(list) || update.index !== null && isNaN(update.index)) { | ||
| throw new Error('Oops'); | ||
| } | ||
| if (update.index !== null) { | ||
| list.splice(update.index, 1); | ||
| } else { | ||
| list.push({}); | ||
| } | ||
| } | ||
| var fieldset = typeof fieldsetCreator === 'function' ? fieldsetCreator(value) : fieldsetCreator; | ||
| var valueByName = Object.fromEntries(valueEntries); | ||
| var errorEntries = []; | ||
| if (!update) { | ||
| for (var [name, field] of flatten(fieldset, f => typeof f[symbol] !== 'undefined')) { | ||
| var constraint = getConstraint(field); | ||
| var _value = valueByName[name]; | ||
| var validity = validate(_value, constraint); | ||
| var _message = checkCustomValidity(_value, validity, constraint); | ||
| if (_message) { | ||
| errorEntries.push([name, _message]); | ||
| } | ||
| } | ||
| } | ||
| return { | ||
| value, | ||
| error: errorEntries.length > 0 ? unflatten(errorEntries) : null, | ||
| isDraft: update !== null | ||
| }; | ||
| } | ||
| /** | ||
| * Helpers | ||
| */ | ||
| var pattern = /(\w+)\[(\d+)\]/; | ||
| function getPaths(key) { | ||
| return key.split('.').flatMap(key => { | ||
| var matches = pattern.exec(key); | ||
| if (!matches) { | ||
| return key; | ||
| } | ||
| return [matches[1], Number(matches[2])]; | ||
| }); | ||
| } | ||
| function getItem(obj, key, defaultValue) { | ||
| var target = obj; | ||
| for (var path of getPaths(key)) { | ||
| if (typeof target[path] === 'undefined') { | ||
| return defaultValue; | ||
| } | ||
| target = target[path]; | ||
| } | ||
| return target; | ||
| } | ||
| function flatten(item, isLeaf) { | ||
@@ -202,4 +280,4 @@ var prefix = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ''; | ||
| } else { | ||
| for (var [key, _value] of Object.entries(item)) { | ||
| entries.push(...flatten(_value, isLeaf, prefix ? "".concat(prefix, ".").concat(key) : key)); | ||
| for (var [key, _value2] of Object.entries(item)) { | ||
| entries.push(...flatten(_value2, isLeaf, prefix ? "".concat(prefix, ".").concat(key) : key)); | ||
| } | ||
@@ -212,15 +290,6 @@ } | ||
| function unflatten(entries) { | ||
| var pattern = /(\w+)\[(\d+)\]/; | ||
| var result = {}; | ||
| for (var [key, _value2] of entries) { | ||
| var paths = key.split('.').flatMap(key => { | ||
| var matches = pattern.exec(key); | ||
| if (!matches) { | ||
| return key; | ||
| } | ||
| return [matches[1], Number(matches[2])]; | ||
| }); | ||
| for (var [key, _value3] of entries) { | ||
| var paths = getPaths(key); | ||
| var length = paths.length; | ||
@@ -234,3 +303,3 @@ var lastIndex = length - 1; | ||
| var next = paths[index + 1]; | ||
| var newValue = _value2; | ||
| var newValue = _value3; | ||
@@ -252,139 +321,111 @@ if (index != lastIndex) { | ||
| function validate(value, constraint) { | ||
| var _constraint$pattern2; | ||
| var badInput = false; | ||
| var customError = false; | ||
| var patternMismatch = false; | ||
| var rangeOverflow = false; | ||
| var rangeUnderflow = false; | ||
| var stepMismatch = false; | ||
| var tooLong = false; | ||
| var tooShort = false; | ||
| var typeMismatch = false; | ||
| var valueMissing = false; | ||
| if (value instanceof File) { | ||
| return 'File is not supported yet'; | ||
| } | ||
| var _constraint$type; | ||
| if (constraint.required) { | ||
| if (typeof value === 'undefined' || value === '') { | ||
| var _constraint$required$; | ||
| typeMismatch = ((_constraint$type = constraint.type) === null || _constraint$type === void 0 ? void 0 : _constraint$type.value) !== 'file'; | ||
| } else { | ||
| var _constraint$pattern$s, _constraint$pattern2, _constraint$type2, _constraint$type3; | ||
| return (_constraint$required$ = constraint.required.message) !== null && _constraint$required$ !== void 0 ? _constraint$required$ : 'This field is required'; | ||
| } | ||
| } | ||
| var isURL = value => { | ||
| try { | ||
| new URL(value); | ||
| return true; | ||
| } catch (_unused) { | ||
| return false; | ||
| } | ||
| }; | ||
| if (constraint.minLength) { | ||
| if (typeof value === 'undefined' || value.length < constraint.minLength.value) { | ||
| var _constraint$minLength; | ||
| return (_constraint$minLength = constraint.minLength.message) !== null && _constraint$minLength !== void 0 ? _constraint$minLength : "This field must be at least ".concat(constraint.minLength.value, " characters"); | ||
| } | ||
| patternMismatch = (_constraint$pattern$s = (_constraint$pattern2 = constraint.pattern) === null || _constraint$pattern2 === void 0 ? void 0 : _constraint$pattern2.some(pattern => { | ||
| var match = value === null || value === void 0 ? void 0 : value.match(pattern.value); | ||
| return !match || value !== match[0]; | ||
| })) !== null && _constraint$pattern$s !== void 0 ? _constraint$pattern$s : false; | ||
| rangeOverflow = constraint.max ? typeof value !== 'undefined' && constraint.max.value instanceof Date && new Date(value) > constraint.max.value || typeof value !== 'undefined' && typeof constraint.max.value === 'number' && Number(value) > constraint.max.value : false; | ||
| rangeUnderflow = constraint.min ? constraint.min.value instanceof Date && new Date(value !== null && value !== void 0 ? value : '') < constraint.min.value || typeof constraint.min.value === 'number' && Number(value !== null && value !== void 0 ? value : '') < constraint.min.value : false; | ||
| tooLong = constraint.maxLength ? typeof value !== 'undefined' && value.length > constraint.maxLength.value : false; | ||
| tooShort = constraint.minLength ? typeof value === 'undefined' || value.length < constraint.minLength.value : false; | ||
| typeMismatch = ((_constraint$type2 = constraint.type) === null || _constraint$type2 === void 0 ? void 0 : _constraint$type2.value) === 'email' && !/^\S+@\S+$/.test(value !== null && value !== void 0 ? value : '') || ((_constraint$type3 = constraint.type) === null || _constraint$type3 === void 0 ? void 0 : _constraint$type3.value) === 'url' && !isURL(value !== null && value !== void 0 ? value : ''); | ||
| valueMissing = typeof value === 'undefined' || value === ''; | ||
| } | ||
| if (constraint.maxLength) { | ||
| if (typeof value !== 'undefined' && value.length > constraint.maxLength.value) { | ||
| var _constraint$maxLength; | ||
| return { | ||
| badInput, | ||
| customError, | ||
| patternMismatch, | ||
| rangeOverflow, | ||
| rangeUnderflow, | ||
| stepMismatch, | ||
| tooLong, | ||
| tooShort, | ||
| typeMismatch, | ||
| valid: !patternMismatch && !rangeOverflow && !rangeUnderflow && !stepMismatch && !tooLong && !tooShort && !typeMismatch && !valueMissing, | ||
| valueMissing | ||
| }; | ||
| } | ||
| return (_constraint$maxLength = constraint.maxLength.message) !== null && _constraint$maxLength !== void 0 ? _constraint$maxLength : "This field must be at most ".concat(constraint.maxLength.value, " characters"); | ||
| } | ||
| } | ||
| function checkCustomValidity(value, validity, constraint) { | ||
| if (validity.valueMissing) { | ||
| var _constraint$required$, _constraint$required; | ||
| if (constraint.min) { | ||
| if (constraint.min.value instanceof Date && new Date(value !== null && value !== void 0 ? value : '') < constraint.min.value) { | ||
| var _constraint$min$messa; | ||
| return (_constraint$required$ = (_constraint$required = constraint.required) === null || _constraint$required === void 0 ? void 0 : _constraint$required.message) !== null && _constraint$required$ !== void 0 ? _constraint$required$ : null; | ||
| } else if (validity.tooShort) { | ||
| var _constraint$minLength, _constraint$minLength2; | ||
| return (_constraint$min$messa = constraint.min.message) !== null && _constraint$min$messa !== void 0 ? _constraint$min$messa : "This field must be later than ".concat(constraint.min.value.toISOString()); | ||
| } else if (typeof constraint.min.value === 'number' && Number(value !== null && value !== void 0 ? value : '') < constraint.min.value) { | ||
| var _constraint$min$messa2; | ||
| return (_constraint$minLength = (_constraint$minLength2 = constraint.minLength) === null || _constraint$minLength2 === void 0 ? void 0 : _constraint$minLength2.message) !== null && _constraint$minLength !== void 0 ? _constraint$minLength : null; | ||
| } else if (validity.tooLong) { | ||
| var _constraint$maxLength, _constraint$maxLength2; | ||
| return (_constraint$min$messa2 = constraint.min.message) !== null && _constraint$min$messa2 !== void 0 ? _constraint$min$messa2 : "This field must be greater than or equal to ".concat(constraint.min.value); | ||
| } | ||
| } | ||
| return (_constraint$maxLength = (_constraint$maxLength2 = constraint.maxLength) === null || _constraint$maxLength2 === void 0 ? void 0 : _constraint$maxLength2.message) !== null && _constraint$maxLength !== void 0 ? _constraint$maxLength : null; | ||
| } else if (validity.stepMismatch) { | ||
| var _constraint$step$mess, _constraint$step; | ||
| if (constraint.max) { | ||
| if (typeof value !== 'undefined' && constraint.max.value instanceof Date && new Date(value) > constraint.max.value) { | ||
| var _constraint$max$messa; | ||
| return (_constraint$step$mess = (_constraint$step = constraint.step) === null || _constraint$step === void 0 ? void 0 : _constraint$step.message) !== null && _constraint$step$mess !== void 0 ? _constraint$step$mess : null; | ||
| } else if (validity.rangeUnderflow) { | ||
| var _constraint$min$messa, _constraint$min; | ||
| return (_constraint$max$messa = constraint.max.message) !== null && _constraint$max$messa !== void 0 ? _constraint$max$messa : "This field must be at earlier than ".concat(constraint.max.value.toISOString()); | ||
| } else if (typeof value !== 'undefined' && typeof constraint.max.value === 'number' && Number(value) > constraint.max.value) { | ||
| var _constraint$max$messa2; | ||
| return (_constraint$min$messa = (_constraint$min = constraint.min) === null || _constraint$min === void 0 ? void 0 : _constraint$min.message) !== null && _constraint$min$messa !== void 0 ? _constraint$min$messa : null; | ||
| } else if (validity.rangeOverflow) { | ||
| var _constraint$max$messa, _constraint$max; | ||
| return (_constraint$max$messa2 = constraint.max.message) !== null && _constraint$max$messa2 !== void 0 ? _constraint$max$messa2 : "This field must be less than or equal to ".concat(constraint.max.value); | ||
| } | ||
| } | ||
| return (_constraint$max$messa = (_constraint$max = constraint.max) === null || _constraint$max === void 0 ? void 0 : _constraint$max.message) !== null && _constraint$max$messa !== void 0 ? _constraint$max$messa : null; | ||
| } else if (validity.typeMismatch || validity.badInput) { | ||
| var _constraint$type$mess, _constraint$type4; | ||
| if (constraint.step) ; | ||
| return (_constraint$type$mess = (_constraint$type4 = constraint.type) === null || _constraint$type4 === void 0 ? void 0 : _constraint$type4.message) !== null && _constraint$type$mess !== void 0 ? _constraint$type$mess : null; | ||
| } else if (validity.patternMismatch) { | ||
| if (!constraint.pattern) { | ||
| return null; | ||
| } else if (constraint.pattern.length === 1) { | ||
| var _constraint$pattern$; | ||
| if (constraint.type) { | ||
| switch (constraint.type.value) { | ||
| case 'email': | ||
| if (!/^\S+\@\S+$/.test(value !== null && value !== void 0 ? value : '')) { | ||
| var _constraint$type$mess; | ||
| return (_constraint$pattern$ = constraint.pattern[0].message) !== null && _constraint$pattern$ !== void 0 ? _constraint$pattern$ : null; | ||
| } else { | ||
| var _constraint$pattern$f, _constraint$pattern$f2; | ||
| return (_constraint$type$mess = constraint.type.message) !== null && _constraint$type$mess !== void 0 ? _constraint$type$mess : "This field must be a valid email"; | ||
| } | ||
| break; | ||
| case 'url': | ||
| var isURL = value => { | ||
| try { | ||
| new URL(value); | ||
| return true; | ||
| } catch (_unused) { | ||
| return false; | ||
| } | ||
| }; | ||
| if (!isURL(value !== null && value !== void 0 ? value : '')) { | ||
| var _constraint$type$mess2; | ||
| return (_constraint$type$mess2 = constraint.type.message) !== null && _constraint$type$mess2 !== void 0 ? _constraint$type$mess2 : "This field must be a valid URL"; | ||
| } | ||
| break; | ||
| return (_constraint$pattern$f = (_constraint$pattern$f2 = constraint.pattern.find(pattern => pattern.value.test(value))) === null || _constraint$pattern$f2 === void 0 ? void 0 : _constraint$pattern$f2.message) !== null && _constraint$pattern$f !== void 0 ? _constraint$pattern$f : null; | ||
| } | ||
| } else { | ||
| return ''; | ||
| } | ||
| if ((_constraint$pattern2 = constraint.pattern) !== null && _constraint$pattern2 !== void 0 && _constraint$pattern2.length) { | ||
| var _pattern = constraint.pattern.find(pattern => { | ||
| var match = value === null || value === void 0 ? void 0 : value.match(pattern.value); | ||
| return !match || value !== match[0]; | ||
| }); | ||
| if (_pattern) { | ||
| var _pattern$message; | ||
| return (_pattern$message = _pattern.message) !== null && _pattern$message !== void 0 ? _pattern$message : "This field must be a valid format"; | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| function parse(payload, fieldsetCreator) { | ||
| var valueEntries = payload instanceof URLSearchParams || payload instanceof FormData ? payload : new URLSearchParams(payload); | ||
| var value = unflatten(valueEntries); | ||
| var fieldset = typeof fieldsetCreator === 'function' ? fieldsetCreator(value) : fieldsetCreator; | ||
| var values = Object.fromEntries(valueEntries); | ||
| var errorEntries = []; | ||
| for (var [name, field] of flatten(fieldset, f => typeof f[symbol] === 'function')) { | ||
| var constraint = getConstraint(field); | ||
| var _value3 = values[name]; | ||
| var _message = validate(_value3, constraint); | ||
| if (_message) { | ||
| errorEntries.push([name, _message]); | ||
| } | ||
| } | ||
| return { | ||
| value, | ||
| error: errorEntries.length > 0 ? unflatten(errorEntries) : null | ||
| }; | ||
| } | ||
| exports.checkCustomValidity = checkCustomValidity; | ||
| exports.draftUpdate = draftUpdate; | ||
| exports.f = f; | ||
| exports.getConstraint = getConstraint; | ||
| exports.isButtonElement = isButtonElement; | ||
| exports.isDirtyField = isDirtyField; | ||
| exports.getDraft = getDraft; | ||
| exports.isDirty = isDirty; | ||
| exports.isElement = isElement; | ||
| exports.isInputElement = isInputElement; | ||
| exports.isSelectElement = isSelectElement; | ||
| exports.isTextareaElement = isTextareaElement; | ||
| exports.isValidationConstraintSupported = isValidationConstraintSupported; | ||
| exports.parse = parse; | ||
| exports.shouldSkipValidate = shouldSkipValidate; |
+304
-262
@@ -1,110 +0,112 @@ | ||
| var attributesByType = { | ||
| // 'button': [], | ||
| checkbox: ['required'], | ||
| color: [], | ||
| date: ['required', 'minLength', 'maxLength', 'pattern'], | ||
| datetime: ['required', 'minLength', 'maxLength', 'pattern'], | ||
| 'datetime-local': ['required', 'minLength', 'maxLength', 'pattern'], | ||
| email: ['required', 'minLength', 'maxLength', 'pattern'], | ||
| fieldset: ['multiple'], | ||
| file: ['required'], | ||
| hidden: [], | ||
| // 'image': [], | ||
| month: ['required', 'minLength', 'maxLength', 'pattern'], | ||
| number: ['required', 'minLength', 'maxLength', 'pattern'], | ||
| password: ['required', 'minLength', 'maxLength', 'pattern'], | ||
| radio: ['required'], | ||
| range: ['min', 'max', 'step'], | ||
| // 'reset': [], | ||
| search: ['required', 'minLength', 'maxLength', 'pattern'], | ||
| select: ['required'], | ||
| // 'submit': [], | ||
| tel: ['required', 'minLength', 'maxLength', 'pattern'], | ||
| text: ['required', 'minLength', 'maxLength', 'pattern'], | ||
| textarea: ['required', 'minLength', 'maxLength'], | ||
| time: ['required', 'minLength', 'maxLength', 'pattern'], | ||
| url: ['required', 'minLength', 'maxLength', 'pattern'], | ||
| week: ['required', 'minLength', 'maxLength', 'pattern'] | ||
| }; | ||
| var symbol = Symbol('constraints'); | ||
| /** | ||
| * | ||
| */ | ||
| var symbol = Symbol('constraint'); | ||
| function createField(type, message) { | ||
| var supportedAttributes = attributesByType[type]; | ||
| var constraint = { | ||
| type: { | ||
| value: type, | ||
| message: message | ||
| } | ||
| }; | ||
| var field = { | ||
| required(message) { | ||
| constraint.required = { | ||
| message | ||
| }; | ||
| return field; | ||
| }, | ||
| function configureF() { | ||
| function createField(tag, type, message) { | ||
| var constraint = { | ||
| tag | ||
| }; | ||
| min(value, message) { | ||
| constraint.min = { | ||
| value, | ||
| if (type) { | ||
| constraint.type = { | ||
| value: type, | ||
| message | ||
| }; | ||
| return field; | ||
| }, | ||
| } | ||
| max(value, message) { | ||
| constraint.max = { | ||
| value, | ||
| message | ||
| }; | ||
| return field; | ||
| }, | ||
| return { | ||
| required(message) { | ||
| constraint.required = { | ||
| message | ||
| }; | ||
| return this; | ||
| }, | ||
| minLength(value, message) { | ||
| constraint.minLength = { | ||
| value, | ||
| message | ||
| }; | ||
| return field; | ||
| }, | ||
| min(value, message) { | ||
| constraint.min = { | ||
| value, | ||
| message | ||
| }; | ||
| return this; | ||
| }, | ||
| maxLength(value, message) { | ||
| constraint.maxLength = { | ||
| value, | ||
| message | ||
| }; | ||
| return field; | ||
| }, | ||
| max(value, message) { | ||
| constraint.max = { | ||
| value, | ||
| message | ||
| }; | ||
| return this; | ||
| }, | ||
| pattern(value, message) { | ||
| if (value.global || value.ignoreCase || value.multiline) { | ||
| console.warn("global, ignoreCase, and multiline flags are not supported on the pattern attribute"); | ||
| } else { | ||
| var _constraint$pattern; | ||
| minLength(value, message) { | ||
| constraint.minLength = { | ||
| value, | ||
| message | ||
| }; | ||
| return this; | ||
| }, | ||
| constraint.pattern = ((_constraint$pattern = constraint.pattern) !== null && _constraint$pattern !== void 0 ? _constraint$pattern : []).concat({ | ||
| maxLength(value, message) { | ||
| constraint.maxLength = { | ||
| value, | ||
| message | ||
| }); | ||
| } | ||
| }; | ||
| return this; | ||
| }, | ||
| return field; | ||
| }, | ||
| pattern(value, message) { | ||
| if (value.global || value.ignoreCase || value.multiline) { | ||
| console.warn("global, ignoreCase, and multiline flags are not supported on the pattern attribute"); | ||
| } else { | ||
| var _constraint$pattern; | ||
| multiple(value) { | ||
| constraint.multiple = { | ||
| value, | ||
| message | ||
| }; | ||
| return field; | ||
| }, | ||
| constraint.pattern = ((_constraint$pattern = constraint.pattern) !== null && _constraint$pattern !== void 0 ? _constraint$pattern : []).concat({ | ||
| value, | ||
| message | ||
| }); | ||
| } | ||
| [symbol]: () => constraint | ||
| }; // @ts-ignore | ||
| return this; | ||
| }, | ||
| return Object.fromEntries( // @ts-ignore | ||
| [symbol, ...supportedAttributes].map(key => [key, field[key]])); | ||
| multiple(value) { | ||
| constraint.multiple = { | ||
| value, | ||
| message | ||
| }; | ||
| return this; | ||
| }, | ||
| [symbol]: constraint | ||
| }; | ||
| } | ||
| function input(type, message) { | ||
| // @ts-expect-error | ||
| return createField('input', type, message); | ||
| } | ||
| function select() { | ||
| return createField('select'); | ||
| } | ||
| function textarea() { | ||
| return createField('textarea'); | ||
| } | ||
| function fieldset() { | ||
| return createField('fieldset'); | ||
| } | ||
| return { | ||
| input, | ||
| select, | ||
| textarea, | ||
| fieldset | ||
| }; | ||
| } | ||
| /** | ||
| * Helpers for constructing the field constraints | ||
| * Helpers for constructing the field constraint based on the type | ||
| * @see https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Constraint_validation#validation-related_attributes | ||
@@ -114,63 +116,38 @@ */ | ||
| var f = { | ||
| // button: () => createField('button'), | ||
| checkbox: () => createField('checkbox'), | ||
| color: () => createField('color'), | ||
| date: () => createField('date'), | ||
| // datetime: () => createField('datetime'), | ||
| datetime: () => createField('datetime-local'), | ||
| // `datetime` is deprecated | ||
| email: message => createField('email', message), | ||
| fieldset: () => createField('fieldset'), | ||
| file: () => createField('file'), | ||
| hidden: () => createField('hidden'), | ||
| // image: () => createField('image'), | ||
| month: () => createField('month'), | ||
| number: message => createField('number', message), | ||
| password: () => createField('password'), | ||
| radio: () => createField('radio'), | ||
| range: () => createField('range'), | ||
| // reset: () => createField('reset'), | ||
| search: () => createField('search'), | ||
| select: () => createField('select'), | ||
| // submit: () => createField('submit'), | ||
| tel: () => createField('tel'), | ||
| text: () => createField('text'), | ||
| textarea: () => createField('textarea'), | ||
| time: () => createField('time'), | ||
| url: message => createField('url', message), | ||
| week: () => createField('week') | ||
| }; | ||
| var f = configureF(); | ||
| function getConstraint(field) { | ||
| return field[symbol](); | ||
| } // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
| if (typeof field[symbol] === 'undefined') { | ||
| throw new Error('Provided config is not a field; Please ensure only field object is used'); | ||
| } | ||
| return field[symbol]; | ||
| } | ||
| function isElement(element, tag) { | ||
| return !!element && element.tagName.toLowerCase() === tag; | ||
| } | ||
| function isInputElement(element) { | ||
| return isElement(element, 'input'); | ||
| } | ||
| function isSelectElement(element) { | ||
| return isElement(element, 'select'); | ||
| } | ||
| function isTextareaElement(element) { | ||
| return isElement(element, 'textarea'); | ||
| } | ||
| function isButtonElement(element) { | ||
| return isElement(element, 'button'); | ||
| } | ||
| function isDirtyField(element) { | ||
| function isDirty(element) { | ||
| if (isElement(element, 'form')) { | ||
| for (var el of element.elements) { | ||
| if (isDirty(el)) { | ||
| return true; | ||
| } | ||
| } | ||
| return false; | ||
| } | ||
| if (isElement(element, 'input') || isElement(element, 'textarea')) { | ||
| return element.value !== element.defaultValue; | ||
| } else if (isElement(element, 'select')) { | ||
| } | ||
| if (isElement(element, 'select')) { | ||
| var _Array$from$find; | ||
| return element.value !== ((_Array$from$find = Array.from(element.options).find(option => option.defaultSelected)) === null || _Array$from$find === void 0 ? void 0 : _Array$from$find.value); | ||
| } else { | ||
| return false; | ||
| } | ||
| return false; | ||
| } | ||
| function isValidationConstraintSupported(element) { | ||
| if (!isInputElement(element) && !isSelectElement(element) && !isTextareaElement(element)) { | ||
| if (!isElement(element, 'input') && !isElement(element, 'select') && !isElement(element, 'textarea')) { | ||
| return false; | ||
@@ -182,5 +159,106 @@ } | ||
| function shouldSkipValidate(element) { | ||
| return isButtonElement(element) || isInputElement(element) ? element.formNoValidate : false; | ||
| return isElement(element, 'button') || isElement(element, 'input') ? element.formNoValidate : false; | ||
| } | ||
| function draftUpdate(name, index) { | ||
| return { | ||
| name: '__form-validity__', | ||
| value: [name].concat(typeof index === 'undefined' ? [] : ["".concat(index)]).join('|') | ||
| }; | ||
| } | ||
| function getDraft(payload) { | ||
| var update = payload.get('__form-validity__'); | ||
| if (!update) { | ||
| return null; | ||
| } // We are mutating the payload here | ||
| payload.delete('__form-validity__'); | ||
| if (update instanceof File) { | ||
| throw new Error('What?'); | ||
| } | ||
| var [name, indexString] = update.split('|'); | ||
| var index = typeof indexString !== 'undefined' ? Number(indexString) : null; | ||
| return { | ||
| name, | ||
| index | ||
| }; | ||
| } | ||
| function parse(payload, fieldsetCreator) { | ||
| var valueEntries = payload instanceof URLSearchParams || payload instanceof FormData ? payload : new URLSearchParams(payload); | ||
| var update = getDraft(valueEntries); | ||
| var value = unflatten(valueEntries); | ||
| if (update) { | ||
| var list = getItem(value, update.name); | ||
| if (!Array.isArray(list) || update.index !== null && isNaN(update.index)) { | ||
| throw new Error('Oops'); | ||
| } | ||
| if (update.index !== null) { | ||
| list.splice(update.index, 1); | ||
| } else { | ||
| list.push({}); | ||
| } | ||
| } | ||
| var fieldset = typeof fieldsetCreator === 'function' ? fieldsetCreator(value) : fieldsetCreator; | ||
| var valueByName = Object.fromEntries(valueEntries); | ||
| var errorEntries = []; | ||
| if (!update) { | ||
| for (var [name, field] of flatten(fieldset, f => typeof f[symbol] !== 'undefined')) { | ||
| var constraint = getConstraint(field); | ||
| var _value = valueByName[name]; | ||
| var validity = validate(_value, constraint); | ||
| var _message = checkCustomValidity(_value, validity, constraint); | ||
| if (_message) { | ||
| errorEntries.push([name, _message]); | ||
| } | ||
| } | ||
| } | ||
| return { | ||
| value, | ||
| error: errorEntries.length > 0 ? unflatten(errorEntries) : null, | ||
| isDraft: update !== null | ||
| }; | ||
| } | ||
| /** | ||
| * Helpers | ||
| */ | ||
| var pattern = /(\w+)\[(\d+)\]/; | ||
| function getPaths(key) { | ||
| return key.split('.').flatMap(key => { | ||
| var matches = pattern.exec(key); | ||
| if (!matches) { | ||
| return key; | ||
| } | ||
| return [matches[1], Number(matches[2])]; | ||
| }); | ||
| } | ||
| function getItem(obj, key, defaultValue) { | ||
| var target = obj; | ||
| for (var path of getPaths(key)) { | ||
| if (typeof target[path] === 'undefined') { | ||
| return defaultValue; | ||
| } | ||
| target = target[path]; | ||
| } | ||
| return target; | ||
| } | ||
| function flatten(item, isLeaf) { | ||
@@ -197,4 +275,4 @@ var prefix = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ''; | ||
| } else { | ||
| for (var [key, _value] of Object.entries(item)) { | ||
| entries.push(...flatten(_value, isLeaf, prefix ? "".concat(prefix, ".").concat(key) : key)); | ||
| for (var [key, _value2] of Object.entries(item)) { | ||
| entries.push(...flatten(_value2, isLeaf, prefix ? "".concat(prefix, ".").concat(key) : key)); | ||
| } | ||
@@ -207,15 +285,6 @@ } | ||
| function unflatten(entries) { | ||
| var pattern = /(\w+)\[(\d+)\]/; | ||
| var result = {}; | ||
| for (var [key, _value2] of entries) { | ||
| var paths = key.split('.').flatMap(key => { | ||
| var matches = pattern.exec(key); | ||
| if (!matches) { | ||
| return key; | ||
| } | ||
| return [matches[1], Number(matches[2])]; | ||
| }); | ||
| for (var [key, _value3] of entries) { | ||
| var paths = getPaths(key); | ||
| var length = paths.length; | ||
@@ -229,3 +298,3 @@ var lastIndex = length - 1; | ||
| var next = paths[index + 1]; | ||
| var newValue = _value2; | ||
| var newValue = _value3; | ||
@@ -247,129 +316,102 @@ if (index != lastIndex) { | ||
| function validate(value, constraint) { | ||
| var _constraint$pattern2; | ||
| var badInput = false; | ||
| var customError = false; | ||
| var patternMismatch = false; | ||
| var rangeOverflow = false; | ||
| var rangeUnderflow = false; | ||
| var stepMismatch = false; | ||
| var tooLong = false; | ||
| var tooShort = false; | ||
| var typeMismatch = false; | ||
| var valueMissing = false; | ||
| if (value instanceof File) { | ||
| return 'File is not supported yet'; | ||
| } | ||
| var _constraint$type; | ||
| if (constraint.required) { | ||
| if (typeof value === 'undefined' || value === '') { | ||
| var _constraint$required$; | ||
| typeMismatch = ((_constraint$type = constraint.type) === null || _constraint$type === void 0 ? void 0 : _constraint$type.value) !== 'file'; | ||
| } else { | ||
| var _constraint$pattern$s, _constraint$pattern2, _constraint$type2, _constraint$type3; | ||
| return (_constraint$required$ = constraint.required.message) !== null && _constraint$required$ !== void 0 ? _constraint$required$ : 'This field is required'; | ||
| } | ||
| } | ||
| var isURL = value => { | ||
| try { | ||
| new URL(value); | ||
| return true; | ||
| } catch (_unused) { | ||
| return false; | ||
| } | ||
| }; | ||
| if (constraint.minLength) { | ||
| if (typeof value === 'undefined' || value.length < constraint.minLength.value) { | ||
| var _constraint$minLength; | ||
| return (_constraint$minLength = constraint.minLength.message) !== null && _constraint$minLength !== void 0 ? _constraint$minLength : "This field must be at least ".concat(constraint.minLength.value, " characters"); | ||
| } | ||
| patternMismatch = (_constraint$pattern$s = (_constraint$pattern2 = constraint.pattern) === null || _constraint$pattern2 === void 0 ? void 0 : _constraint$pattern2.some(pattern => { | ||
| var match = value === null || value === void 0 ? void 0 : value.match(pattern.value); | ||
| return !match || value !== match[0]; | ||
| })) !== null && _constraint$pattern$s !== void 0 ? _constraint$pattern$s : false; | ||
| rangeOverflow = constraint.max ? typeof value !== 'undefined' && constraint.max.value instanceof Date && new Date(value) > constraint.max.value || typeof value !== 'undefined' && typeof constraint.max.value === 'number' && Number(value) > constraint.max.value : false; | ||
| rangeUnderflow = constraint.min ? constraint.min.value instanceof Date && new Date(value !== null && value !== void 0 ? value : '') < constraint.min.value || typeof constraint.min.value === 'number' && Number(value !== null && value !== void 0 ? value : '') < constraint.min.value : false; | ||
| tooLong = constraint.maxLength ? typeof value !== 'undefined' && value.length > constraint.maxLength.value : false; | ||
| tooShort = constraint.minLength ? typeof value === 'undefined' || value.length < constraint.minLength.value : false; | ||
| typeMismatch = ((_constraint$type2 = constraint.type) === null || _constraint$type2 === void 0 ? void 0 : _constraint$type2.value) === 'email' && !/^\S+@\S+$/.test(value !== null && value !== void 0 ? value : '') || ((_constraint$type3 = constraint.type) === null || _constraint$type3 === void 0 ? void 0 : _constraint$type3.value) === 'url' && !isURL(value !== null && value !== void 0 ? value : ''); | ||
| valueMissing = typeof value === 'undefined' || value === ''; | ||
| } | ||
| if (constraint.maxLength) { | ||
| if (typeof value !== 'undefined' && value.length > constraint.maxLength.value) { | ||
| var _constraint$maxLength; | ||
| return { | ||
| badInput, | ||
| customError, | ||
| patternMismatch, | ||
| rangeOverflow, | ||
| rangeUnderflow, | ||
| stepMismatch, | ||
| tooLong, | ||
| tooShort, | ||
| typeMismatch, | ||
| valid: !patternMismatch && !rangeOverflow && !rangeUnderflow && !stepMismatch && !tooLong && !tooShort && !typeMismatch && !valueMissing, | ||
| valueMissing | ||
| }; | ||
| } | ||
| return (_constraint$maxLength = constraint.maxLength.message) !== null && _constraint$maxLength !== void 0 ? _constraint$maxLength : "This field must be at most ".concat(constraint.maxLength.value, " characters"); | ||
| } | ||
| } | ||
| function checkCustomValidity(value, validity, constraint) { | ||
| if (validity.valueMissing) { | ||
| var _constraint$required$, _constraint$required; | ||
| if (constraint.min) { | ||
| if (constraint.min.value instanceof Date && new Date(value !== null && value !== void 0 ? value : '') < constraint.min.value) { | ||
| var _constraint$min$messa; | ||
| return (_constraint$required$ = (_constraint$required = constraint.required) === null || _constraint$required === void 0 ? void 0 : _constraint$required.message) !== null && _constraint$required$ !== void 0 ? _constraint$required$ : null; | ||
| } else if (validity.tooShort) { | ||
| var _constraint$minLength, _constraint$minLength2; | ||
| return (_constraint$min$messa = constraint.min.message) !== null && _constraint$min$messa !== void 0 ? _constraint$min$messa : "This field must be later than ".concat(constraint.min.value.toISOString()); | ||
| } else if (typeof constraint.min.value === 'number' && Number(value !== null && value !== void 0 ? value : '') < constraint.min.value) { | ||
| var _constraint$min$messa2; | ||
| return (_constraint$minLength = (_constraint$minLength2 = constraint.minLength) === null || _constraint$minLength2 === void 0 ? void 0 : _constraint$minLength2.message) !== null && _constraint$minLength !== void 0 ? _constraint$minLength : null; | ||
| } else if (validity.tooLong) { | ||
| var _constraint$maxLength, _constraint$maxLength2; | ||
| return (_constraint$min$messa2 = constraint.min.message) !== null && _constraint$min$messa2 !== void 0 ? _constraint$min$messa2 : "This field must be greater than or equal to ".concat(constraint.min.value); | ||
| } | ||
| } | ||
| return (_constraint$maxLength = (_constraint$maxLength2 = constraint.maxLength) === null || _constraint$maxLength2 === void 0 ? void 0 : _constraint$maxLength2.message) !== null && _constraint$maxLength !== void 0 ? _constraint$maxLength : null; | ||
| } else if (validity.stepMismatch) { | ||
| var _constraint$step$mess, _constraint$step; | ||
| if (constraint.max) { | ||
| if (typeof value !== 'undefined' && constraint.max.value instanceof Date && new Date(value) > constraint.max.value) { | ||
| var _constraint$max$messa; | ||
| return (_constraint$step$mess = (_constraint$step = constraint.step) === null || _constraint$step === void 0 ? void 0 : _constraint$step.message) !== null && _constraint$step$mess !== void 0 ? _constraint$step$mess : null; | ||
| } else if (validity.rangeUnderflow) { | ||
| var _constraint$min$messa, _constraint$min; | ||
| return (_constraint$max$messa = constraint.max.message) !== null && _constraint$max$messa !== void 0 ? _constraint$max$messa : "This field must be at earlier than ".concat(constraint.max.value.toISOString()); | ||
| } else if (typeof value !== 'undefined' && typeof constraint.max.value === 'number' && Number(value) > constraint.max.value) { | ||
| var _constraint$max$messa2; | ||
| return (_constraint$min$messa = (_constraint$min = constraint.min) === null || _constraint$min === void 0 ? void 0 : _constraint$min.message) !== null && _constraint$min$messa !== void 0 ? _constraint$min$messa : null; | ||
| } else if (validity.rangeOverflow) { | ||
| var _constraint$max$messa, _constraint$max; | ||
| return (_constraint$max$messa2 = constraint.max.message) !== null && _constraint$max$messa2 !== void 0 ? _constraint$max$messa2 : "This field must be less than or equal to ".concat(constraint.max.value); | ||
| } | ||
| } | ||
| return (_constraint$max$messa = (_constraint$max = constraint.max) === null || _constraint$max === void 0 ? void 0 : _constraint$max.message) !== null && _constraint$max$messa !== void 0 ? _constraint$max$messa : null; | ||
| } else if (validity.typeMismatch || validity.badInput) { | ||
| var _constraint$type$mess, _constraint$type4; | ||
| if (constraint.step) ; | ||
| return (_constraint$type$mess = (_constraint$type4 = constraint.type) === null || _constraint$type4 === void 0 ? void 0 : _constraint$type4.message) !== null && _constraint$type$mess !== void 0 ? _constraint$type$mess : null; | ||
| } else if (validity.patternMismatch) { | ||
| if (!constraint.pattern) { | ||
| return null; | ||
| } else if (constraint.pattern.length === 1) { | ||
| var _constraint$pattern$; | ||
| if (constraint.type) { | ||
| switch (constraint.type.value) { | ||
| case 'email': | ||
| if (!/^\S+\@\S+$/.test(value !== null && value !== void 0 ? value : '')) { | ||
| var _constraint$type$mess; | ||
| return (_constraint$pattern$ = constraint.pattern[0].message) !== null && _constraint$pattern$ !== void 0 ? _constraint$pattern$ : null; | ||
| } else { | ||
| var _constraint$pattern$f, _constraint$pattern$f2; | ||
| return (_constraint$type$mess = constraint.type.message) !== null && _constraint$type$mess !== void 0 ? _constraint$type$mess : "This field must be a valid email"; | ||
| } | ||
| break; | ||
| case 'url': | ||
| var isURL = value => { | ||
| try { | ||
| new URL(value); | ||
| return true; | ||
| } catch (_unused) { | ||
| return false; | ||
| } | ||
| }; | ||
| if (!isURL(value !== null && value !== void 0 ? value : '')) { | ||
| var _constraint$type$mess2; | ||
| return (_constraint$type$mess2 = constraint.type.message) !== null && _constraint$type$mess2 !== void 0 ? _constraint$type$mess2 : "This field must be a valid URL"; | ||
| } | ||
| break; | ||
| return (_constraint$pattern$f = (_constraint$pattern$f2 = constraint.pattern.find(pattern => pattern.value.test(value))) === null || _constraint$pattern$f2 === void 0 ? void 0 : _constraint$pattern$f2.message) !== null && _constraint$pattern$f !== void 0 ? _constraint$pattern$f : null; | ||
| } | ||
| } else { | ||
| return ''; | ||
| } | ||
| if ((_constraint$pattern2 = constraint.pattern) !== null && _constraint$pattern2 !== void 0 && _constraint$pattern2.length) { | ||
| var _pattern = constraint.pattern.find(pattern => { | ||
| var match = value === null || value === void 0 ? void 0 : value.match(pattern.value); | ||
| return !match || value !== match[0]; | ||
| }); | ||
| if (_pattern) { | ||
| var _pattern$message; | ||
| return (_pattern$message = _pattern.message) !== null && _pattern$message !== void 0 ? _pattern$message : "This field must be a valid format"; | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| function parse(payload, fieldsetCreator) { | ||
| var valueEntries = payload instanceof URLSearchParams || payload instanceof FormData ? payload : new URLSearchParams(payload); | ||
| var value = unflatten(valueEntries); | ||
| var fieldset = typeof fieldsetCreator === 'function' ? fieldsetCreator(value) : fieldsetCreator; | ||
| var values = Object.fromEntries(valueEntries); | ||
| var errorEntries = []; | ||
| for (var [name, field] of flatten(fieldset, f => typeof f[symbol] === 'function')) { | ||
| var constraint = getConstraint(field); | ||
| var _value3 = values[name]; | ||
| var _message = validate(_value3, constraint); | ||
| if (_message) { | ||
| errorEntries.push([name, _message]); | ||
| } | ||
| } | ||
| return { | ||
| value, | ||
| error: errorEntries.length > 0 ? unflatten(errorEntries) : null | ||
| }; | ||
| } | ||
| export { f, getConstraint, isButtonElement, isDirtyField, isElement, isInputElement, isSelectElement, isTextareaElement, isValidationConstraintSupported, parse, shouldSkipValidate }; | ||
| export { checkCustomValidity, draftUpdate, f, getConstraint, getDraft, isDirty, isElement, isValidationConstraintSupported, parse, shouldSkipValidate }; |
+1
-1
@@ -5,3 +5,3 @@ { | ||
| "license": "MIT", | ||
| "version": "0.0.2", | ||
| "version": "0.0.3", | ||
| "main": "index.js", | ||
@@ -8,0 +8,0 @@ "module": "module/index.js", |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
32420
4.47%796
2.98%1
Infinity%