@conform-to/dom 0.1.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -37
- package/_virtual/_rollupPluginBabelHelpers.js +47 -0
- package/index.d.ts +79 -59
- package/index.js +217 -180
- package/module/_virtual/_rollupPluginBabelHelpers.js +42 -0
- package/module/index.js +204 -172
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,42 +1,11 @@
|
|
|
1
1
|
# @conform-to/dom
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> This package is a transitive dependency for the rest of the conform packages with no intention to be used directly at the moment. Use at your own risk.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Conform is a form validation library built on top of the [Constraint Validation](https://caniuse.com/constraint-validation) API.
|
|
6
6
|
|
|
7
|
-
- [
|
|
8
|
-
- [
|
|
9
|
-
- [
|
|
10
|
-
- [getName](#getName)
|
|
11
|
-
- [getPaths](#getPaths)
|
|
12
|
-
- [isFieldElement](#isFieldElement)
|
|
13
|
-
- [parse](#parse)
|
|
14
|
-
- [reportValidity](#reportValidity)
|
|
15
|
-
- [setFieldState](#setFieldState)
|
|
16
|
-
- [shouldSkipValidate](#shouldSkipValidate)
|
|
17
|
-
- [setFieldState](#setFieldState)
|
|
18
|
-
- [transform](#transform)
|
|
7
|
+
- **Progressive Enhancement**: It is designed based on the [HTML specification](https://html.spec.whatwg.org/dev/form-control-infrastructure.html#the-constraint-validation-api). From validating the form to reporting error messages for each field, if you don't like part of the solution, just replace it with your own.
|
|
8
|
+
- **Framework Agnostic**: The DOM is the only dependency. Conform makes use of native [Web APIs](https://developer.mozilla.org/en-US/docs/Web/API) exclusively. You don't have to use React / Vue / Svelte to utilise this library.
|
|
9
|
+
- **Flexible Setup**: It can validates fields anywhere in the dom with the help of [form attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#form). Also enables CSS pseudo-classes like `:valid` and `:invalid`, allowing flexible styling across your form without the need to manipulate the class names.
|
|
19
10
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
### createFieldConfig
|
|
23
|
-
|
|
24
|
-
### getFieldElements
|
|
25
|
-
|
|
26
|
-
### getName
|
|
27
|
-
|
|
28
|
-
### getPaths
|
|
29
|
-
|
|
30
|
-
### isFieldElement
|
|
31
|
-
|
|
32
|
-
### isFieldsetElement
|
|
33
|
-
|
|
34
|
-
### parse
|
|
35
|
-
|
|
36
|
-
### reportValidity
|
|
37
|
-
|
|
38
|
-
### setFieldState
|
|
39
|
-
|
|
40
|
-
### shouldSkipValidate
|
|
41
|
-
|
|
42
|
-
### transform
|
|
11
|
+
Checkout the [repository](https://github.com/edmundhung/conform) if you want to know more!
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
function ownKeys(object, enumerableOnly) {
|
|
6
|
+
var keys = Object.keys(object);
|
|
7
|
+
|
|
8
|
+
if (Object.getOwnPropertySymbols) {
|
|
9
|
+
var symbols = Object.getOwnPropertySymbols(object);
|
|
10
|
+
enumerableOnly && (symbols = symbols.filter(function (sym) {
|
|
11
|
+
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
|
12
|
+
})), keys.push.apply(keys, symbols);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return keys;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function _objectSpread2(target) {
|
|
19
|
+
for (var i = 1; i < arguments.length; i++) {
|
|
20
|
+
var source = null != arguments[i] ? arguments[i] : {};
|
|
21
|
+
i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
|
|
22
|
+
_defineProperty(target, key, source[key]);
|
|
23
|
+
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
|
|
24
|
+
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return target;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function _defineProperty(obj, key, value) {
|
|
32
|
+
if (key in obj) {
|
|
33
|
+
Object.defineProperty(obj, key, {
|
|
34
|
+
value: value,
|
|
35
|
+
enumerable: true,
|
|
36
|
+
configurable: true,
|
|
37
|
+
writable: true
|
|
38
|
+
});
|
|
39
|
+
} else {
|
|
40
|
+
obj[key] = value;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return obj;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
exports.defineProperty = _defineProperty;
|
|
47
|
+
exports.objectSpread2 = _objectSpread2;
|
package/index.d.ts
CHANGED
|
@@ -1,76 +1,96 @@
|
|
|
1
|
-
export declare type
|
|
1
|
+
export declare type Primitive = null | undefined | string | number | boolean | Date;
|
|
2
|
+
export declare type FieldElement = HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement | HTMLButtonElement;
|
|
3
|
+
export interface FieldConfig<Schema = unknown> extends FieldConstraint {
|
|
4
|
+
name: string;
|
|
5
|
+
defaultValue?: FieldValue<Schema>;
|
|
6
|
+
initialError?: FieldError<Schema>['details'];
|
|
7
|
+
form?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare type FieldValue<Schema> = Schema extends Primitive | File ? string : Schema extends Array<infer InnerType> ? Array<FieldValue<InnerType>> : Schema extends Record<string, any> ? {
|
|
10
|
+
[Key in keyof Schema]?: FieldValue<Schema[Key]>;
|
|
11
|
+
} : unknown;
|
|
12
|
+
export interface FieldError<Schema> {
|
|
13
|
+
message?: string;
|
|
14
|
+
details?: Schema extends Primitive | File ? never : Schema extends Array<infer InnerType> ? Array<FieldError<InnerType>> : Schema extends Record<string, any> ? {
|
|
15
|
+
[Key in keyof Schema]?: FieldError<Schema[Key]>;
|
|
16
|
+
} : unknown;
|
|
17
|
+
}
|
|
18
|
+
export declare type FieldConstraint = {
|
|
2
19
|
required?: boolean;
|
|
3
20
|
minLength?: number;
|
|
4
21
|
maxLength?: number;
|
|
5
|
-
min?: string;
|
|
6
|
-
max?: string;
|
|
22
|
+
min?: string | number;
|
|
23
|
+
max?: string | number;
|
|
7
24
|
step?: string;
|
|
8
25
|
multiple?: boolean;
|
|
9
26
|
pattern?: string;
|
|
10
27
|
};
|
|
11
|
-
export
|
|
12
|
-
|
|
13
|
-
initialValue?: FieldsetData<Type, string>;
|
|
14
|
-
error?: FieldsetData<Type, string>;
|
|
15
|
-
form?: string;
|
|
16
|
-
constraint?: Constraint;
|
|
17
|
-
}
|
|
18
|
-
export declare type Schema<Type extends Record<string, any>> = {
|
|
19
|
-
fields: {
|
|
20
|
-
[Key in keyof Type]-?: Constraint;
|
|
21
|
-
};
|
|
22
|
-
validate?: (element: FieldsetElement) => void;
|
|
28
|
+
export declare type FieldsetConstraint<Schema extends Record<string, any>> = {
|
|
29
|
+
[Key in keyof Schema]?: FieldConstraint;
|
|
23
30
|
};
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
export declare type
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
*/
|
|
38
|
-
export declare type FieldElement = HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement | HTMLButtonElement;
|
|
39
|
-
export declare type FormResult<T> = {
|
|
40
|
-
state: 'processed';
|
|
41
|
-
value: FieldsetData<T, string> | null;
|
|
42
|
-
error: FieldsetData<T, string> | null;
|
|
31
|
+
export declare type Schema<Shape extends Record<string, any>, Source> = {
|
|
32
|
+
source: Source;
|
|
33
|
+
constraint: FieldsetConstraint<Shape>;
|
|
34
|
+
validate: (element: HTMLFormElement, submitter?: HTMLInputElement | HTMLButtonElement | null) => void;
|
|
35
|
+
parse: (payload: FormData | URLSearchParams) => Submission<Shape>;
|
|
36
|
+
};
|
|
37
|
+
export interface FormState<Schema extends Record<string, any>> {
|
|
38
|
+
value: FieldValue<Schema>;
|
|
39
|
+
error: FieldError<Schema>;
|
|
40
|
+
}
|
|
41
|
+
export declare type Submission<T extends Record<string, unknown>> = {
|
|
42
|
+
state: 'modified';
|
|
43
|
+
form: FormState<T>;
|
|
43
44
|
} | {
|
|
44
45
|
state: 'rejected';
|
|
45
|
-
|
|
46
|
-
error: FieldsetData<T, string>;
|
|
46
|
+
form: FormState<T>;
|
|
47
47
|
} | {
|
|
48
48
|
state: 'accepted';
|
|
49
|
-
|
|
49
|
+
data: T;
|
|
50
|
+
form: FormState<T>;
|
|
50
51
|
};
|
|
51
|
-
export declare function isFieldsetElement(element: unknown): element is FieldsetElement;
|
|
52
52
|
export declare function isFieldElement(element: unknown): element is FieldElement;
|
|
53
|
-
export declare function setFieldState(field: unknown, state: {
|
|
54
|
-
touched: boolean;
|
|
55
|
-
}): void;
|
|
56
|
-
export declare function reportValidity(fieldset: FieldsetElement): boolean;
|
|
57
|
-
export declare function createFieldConfig<Type extends Record<string, any>>(schema: Schema<Type>, options: {
|
|
58
|
-
name?: string;
|
|
59
|
-
form?: string;
|
|
60
|
-
initialValue?: FieldsetData<Type, string>;
|
|
61
|
-
error?: FieldsetData<Type, string>;
|
|
62
|
-
}): {
|
|
63
|
-
[Key in keyof Type]-?: FieldConfig<Type[Key]>;
|
|
64
|
-
};
|
|
65
|
-
export declare function shouldSkipValidate(event: SubmitEvent): boolean;
|
|
66
53
|
export declare function getPaths(name?: string): Array<string | number>;
|
|
54
|
+
export declare function getFormData(form: HTMLFormElement, submitter?: HTMLInputElement | HTMLButtonElement | null): FormData;
|
|
67
55
|
export declare function getName(paths: Array<string | number>): string;
|
|
68
|
-
export declare function
|
|
69
|
-
export declare function
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
56
|
+
export declare function getKey(fieldName: string, fieldsetName?: string): string | null;
|
|
57
|
+
export declare function setFormError(form: HTMLFormElement, errors: Array<[string, string]>): void;
|
|
58
|
+
export declare function setValue<T>(target: any, paths: Array<string | number>, valueFn: (prev?: T) => T): void;
|
|
59
|
+
export declare function flatten(data: unknown, prefix?: string): Array<[string, FormDataEntryValue]>;
|
|
60
|
+
export declare function unflatten(entries: Array<[string, FormDataEntryValue]> | Iterable<[string, FormDataEntryValue]>): Record<string, unknown>;
|
|
61
|
+
export declare function createSubmission(payload: FormData | URLSearchParams): Submission<Record<string, unknown>>;
|
|
62
|
+
export declare function createValidate(handler: (field: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement | HTMLButtonElement, formData: FormData) => void): (form: HTMLFormElement, submitter?: HTMLInputElement | HTMLButtonElement | null) => void;
|
|
63
|
+
export declare function getFormElement(element: HTMLFormElement | HTMLFieldSetElement | HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement | HTMLButtonElement | null): HTMLFormElement | null;
|
|
64
|
+
export declare type ListCommand<Schema> = {
|
|
65
|
+
type: 'prepend';
|
|
66
|
+
payload: {
|
|
67
|
+
defaultValue: Schema;
|
|
68
|
+
};
|
|
69
|
+
} | {
|
|
70
|
+
type: 'append';
|
|
71
|
+
payload: {
|
|
72
|
+
defaultValue: Schema;
|
|
73
|
+
};
|
|
74
|
+
} | {
|
|
75
|
+
type: 'replace';
|
|
76
|
+
payload: {
|
|
77
|
+
defaultValue: Schema;
|
|
78
|
+
index: number;
|
|
79
|
+
};
|
|
80
|
+
} | {
|
|
81
|
+
type: 'remove';
|
|
82
|
+
payload: {
|
|
83
|
+
index: number;
|
|
84
|
+
};
|
|
85
|
+
} | {
|
|
86
|
+
type: 'reorder';
|
|
87
|
+
payload: {
|
|
88
|
+
from: number;
|
|
89
|
+
to: number;
|
|
90
|
+
};
|
|
74
91
|
};
|
|
75
|
-
export declare
|
|
76
|
-
export declare function
|
|
92
|
+
export declare const listCommandKey = "__conform__";
|
|
93
|
+
export declare function serializeListCommand<Schema>(name: string, { type, payload }: ListCommand<Schema>): string;
|
|
94
|
+
export declare function parseListCommand<Schema>(serialized: string): [string, ListCommand<Schema>];
|
|
95
|
+
export declare function updateList<Type>(list: Array<Type>, command: ListCommand<Type>): Array<Type>;
|
|
96
|
+
export declare function applyListCommand(payload: FormData | URLSearchParams): FormData | URLSearchParams;
|
package/index.js
CHANGED
|
@@ -2,83 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
/**
|
|
6
|
-
* Data structure of the form value
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Element that maintains a list of fields
|
|
11
|
-
* i.e. fieldset.elements
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Element type that might be a candiate of Constraint Validation
|
|
16
|
-
*/
|
|
17
|
-
function isFieldsetElement(element) {
|
|
18
|
-
return element instanceof Element && (element.tagName === 'FORM' || element.tagName === 'FIELDSET');
|
|
19
|
-
}
|
|
20
5
|
function isFieldElement(element) {
|
|
21
6
|
return element instanceof Element && (element.tagName === 'INPUT' || element.tagName === 'SELECT' || element.tagName === 'TEXTAREA' || element.tagName === 'BUTTON');
|
|
22
7
|
}
|
|
23
|
-
function setFieldState(field, state) {
|
|
24
|
-
if (isFieldsetElement(field)) {
|
|
25
|
-
for (var _element of field.elements) {
|
|
26
|
-
setFieldState(_element, state);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
if (!isFieldElement(field)) {
|
|
33
|
-
console.warn('Only input/select/textarea/button element can be touched');
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
if (state.touched) {
|
|
38
|
-
field.dataset.touched = 'true';
|
|
39
|
-
} else {
|
|
40
|
-
delete field.dataset.touched;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
function reportValidity(fieldset) {
|
|
44
|
-
var isValid = true;
|
|
45
|
-
|
|
46
|
-
for (var field of fieldset.elements) {
|
|
47
|
-
if (isFieldElement(field) && field.dataset.touched && !field.checkValidity()) {
|
|
48
|
-
isValid = false;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return isValid;
|
|
53
|
-
}
|
|
54
|
-
function createFieldConfig(schema, options) {
|
|
55
|
-
var result = {};
|
|
56
|
-
|
|
57
|
-
for (var key of Object.keys(schema.fields)) {
|
|
58
|
-
var _options$initialValue, _options$error;
|
|
59
|
-
|
|
60
|
-
var constraint = schema.fields[key];
|
|
61
|
-
var config = {
|
|
62
|
-
name: options.name ? "".concat(options.name, ".").concat(key) : key,
|
|
63
|
-
form: options.form,
|
|
64
|
-
initialValue: (_options$initialValue = options.initialValue) === null || _options$initialValue === void 0 ? void 0 : _options$initialValue[key],
|
|
65
|
-
error: (_options$error = options.error) === null || _options$error === void 0 ? void 0 : _options$error[key],
|
|
66
|
-
constraint
|
|
67
|
-
};
|
|
68
|
-
result[key] = config;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return result;
|
|
72
|
-
}
|
|
73
|
-
function shouldSkipValidate(event) {
|
|
74
|
-
var _event$submitter, _event$submitter2;
|
|
75
|
-
|
|
76
|
-
if (((_event$submitter = event.submitter) === null || _event$submitter === void 0 ? void 0 : _event$submitter.tagName) === 'BUTTON' || ((_event$submitter2 = event.submitter) === null || _event$submitter2 === void 0 ? void 0 : _event$submitter2.tagName) === 'INPUT') {
|
|
77
|
-
return event.submitter.formNoValidate;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
return false;
|
|
81
|
-
}
|
|
82
8
|
function getPaths(name) {
|
|
83
9
|
var pattern = /(\w+)\[(\d+)\]/;
|
|
84
10
|
|
|
@@ -96,6 +22,15 @@ function getPaths(name) {
|
|
|
96
22
|
return [matches[1], Number(matches[2])];
|
|
97
23
|
});
|
|
98
24
|
}
|
|
25
|
+
function getFormData(form, submitter) {
|
|
26
|
+
var payload = new FormData(form);
|
|
27
|
+
|
|
28
|
+
if (submitter !== null && submitter !== void 0 && submitter.name) {
|
|
29
|
+
payload.append(submitter.name, submitter.value);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return payload;
|
|
33
|
+
}
|
|
99
34
|
function getName(paths) {
|
|
100
35
|
return paths.reduce((name, path) => {
|
|
101
36
|
if (name === '' || path === '') {
|
|
@@ -109,144 +44,246 @@ function getName(paths) {
|
|
|
109
44
|
return [name, path].join('.');
|
|
110
45
|
}, '');
|
|
111
46
|
}
|
|
112
|
-
function
|
|
113
|
-
var
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
var paths = getPaths(key);
|
|
117
|
-
var length = paths.length;
|
|
118
|
-
var lastIndex = length - 1;
|
|
119
|
-
var index = -1;
|
|
120
|
-
var pointer = result;
|
|
121
|
-
|
|
122
|
-
while (pointer != null && ++index < length) {
|
|
123
|
-
var _key = paths[index];
|
|
124
|
-
var next = paths[index + 1];
|
|
125
|
-
var newValue = value;
|
|
126
|
-
|
|
127
|
-
if (index != lastIndex) {
|
|
128
|
-
var _pointer$_key;
|
|
47
|
+
function getKey(fieldName) {
|
|
48
|
+
var fieldsetName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
|
|
49
|
+
var name = fieldsetName === '' || fieldName.startsWith(fieldsetName) ? fieldName.slice(fieldsetName ? fieldsetName.length + 1 : 0) : '';
|
|
50
|
+
var paths = getPaths(name);
|
|
129
51
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
// ? pointer[key].concat(newValue)
|
|
134
|
-
// : [pointer[key], newValue];
|
|
135
|
-
// } else {
|
|
52
|
+
if (paths.length > 1) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
136
55
|
|
|
56
|
+
return typeof paths[0] === 'string' ? paths[0] : null;
|
|
57
|
+
}
|
|
58
|
+
function setFormError(form, errors) {
|
|
59
|
+
var firstErrorByName = Object.fromEntries([...errors].reverse());
|
|
137
60
|
|
|
138
|
-
|
|
61
|
+
for (var _element of form.elements) {
|
|
62
|
+
var _firstErrorByName$_el;
|
|
139
63
|
|
|
140
|
-
|
|
64
|
+
if (!isFieldElement(_element)) {
|
|
65
|
+
continue;
|
|
141
66
|
}
|
|
142
|
-
}
|
|
143
67
|
|
|
144
|
-
|
|
68
|
+
_element.setCustomValidity((_firstErrorByName$_el = firstErrorByName[_element.name]) !== null && _firstErrorByName$_el !== void 0 ? _firstErrorByName$_el : '');
|
|
69
|
+
}
|
|
145
70
|
}
|
|
146
|
-
function
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
71
|
+
function setValue(target, paths, valueFn) {
|
|
72
|
+
var length = paths.length;
|
|
73
|
+
var lastIndex = length - 1;
|
|
74
|
+
var index = -1;
|
|
75
|
+
var pointer = target;
|
|
76
|
+
|
|
77
|
+
while (pointer != null && ++index < length) {
|
|
78
|
+
var _pointer$key;
|
|
79
|
+
|
|
80
|
+
var key = paths[index];
|
|
81
|
+
var next = paths[index + 1];
|
|
82
|
+
var newValue = index != lastIndex ? (_pointer$key = pointer[key]) !== null && _pointer$key !== void 0 ? _pointer$key : typeof next === 'number' ? [] : {} : valueFn(pointer[key]);
|
|
83
|
+
pointer[key] = newValue;
|
|
84
|
+
pointer = pointer[key];
|
|
85
|
+
}
|
|
153
86
|
}
|
|
154
|
-
function
|
|
155
|
-
var
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
87
|
+
function flatten(data) {
|
|
88
|
+
var prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
|
|
89
|
+
var entries = [];
|
|
90
|
+
|
|
91
|
+
if (typeof data === 'string' || typeof data === 'undefined' || data instanceof File) {
|
|
92
|
+
entries.push([prefix, data !== null && data !== void 0 ? data : '']);
|
|
93
|
+
} else if (Array.isArray(data)) {
|
|
94
|
+
for (var i = 0; i < data.length; i++) {
|
|
95
|
+
entries.push(...flatten(data[i], "".concat(prefix, "[").concat(i, "]")));
|
|
96
|
+
}
|
|
97
|
+
} else {
|
|
98
|
+
for (var [key, value] of Object.entries(Object(data))) {
|
|
99
|
+
entries.push(...flatten(value, prefix ? "".concat(prefix, ".").concat(key) : key));
|
|
100
|
+
}
|
|
159
101
|
}
|
|
160
102
|
|
|
161
|
-
|
|
103
|
+
return entries;
|
|
104
|
+
}
|
|
105
|
+
function unflatten(entries) {
|
|
106
|
+
var result = {};
|
|
162
107
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
108
|
+
var _loop = function _loop(key, value) {
|
|
109
|
+
var paths = getPaths(key);
|
|
110
|
+
setValue(result, paths, prev => {
|
|
111
|
+
if (prev) {
|
|
112
|
+
throw new Error('Entry with the same name is not supported');
|
|
167
113
|
}
|
|
168
114
|
|
|
169
|
-
|
|
170
|
-
|
|
115
|
+
return value;
|
|
116
|
+
});
|
|
117
|
+
};
|
|
171
118
|
|
|
172
|
-
|
|
173
|
-
|
|
119
|
+
for (var [key, value] of entries) {
|
|
120
|
+
_loop(key, value);
|
|
121
|
+
}
|
|
174
122
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
123
|
+
return result;
|
|
124
|
+
}
|
|
125
|
+
function createSubmission(payload) {
|
|
126
|
+
var value = {};
|
|
179
127
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
128
|
+
try {
|
|
129
|
+
var modifiedPayload = applyListCommand(payload);
|
|
130
|
+
value = unflatten(modifiedPayload.entries());
|
|
183
131
|
|
|
184
|
-
|
|
185
|
-
case 'prepend':
|
|
186
|
-
{
|
|
187
|
-
var initialValue = JSON.parse(json);
|
|
188
|
-
list.unshift(initialValue);
|
|
189
|
-
break;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
case 'append':
|
|
193
|
-
{
|
|
194
|
-
var _initialValue = JSON.parse(json);
|
|
195
|
-
|
|
196
|
-
list.push(_initialValue);
|
|
197
|
-
break;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
case 'remove':
|
|
201
|
-
var {
|
|
202
|
-
index
|
|
203
|
-
} = JSON.parse(json);
|
|
204
|
-
list.splice(index, 1);
|
|
205
|
-
break;
|
|
206
|
-
|
|
207
|
-
default:
|
|
208
|
-
throw new Error('Invalid action found; Only `prepend`, `append` and `remove` is accepted');
|
|
209
|
-
}
|
|
210
|
-
} catch (e) {
|
|
132
|
+
if (payload !== modifiedPayload) {
|
|
211
133
|
return {
|
|
212
|
-
state: '
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
134
|
+
state: 'modified',
|
|
135
|
+
form: {
|
|
136
|
+
value,
|
|
137
|
+
error: {}
|
|
216
138
|
}
|
|
217
139
|
};
|
|
218
140
|
}
|
|
219
|
-
|
|
141
|
+
} catch (e) {
|
|
220
142
|
return {
|
|
221
|
-
state: '
|
|
222
|
-
|
|
223
|
-
|
|
143
|
+
state: 'rejected',
|
|
144
|
+
form: {
|
|
145
|
+
value,
|
|
146
|
+
error: {
|
|
147
|
+
message: e instanceof Error ? e.message : 'Submission failed'
|
|
148
|
+
}
|
|
149
|
+
}
|
|
224
150
|
};
|
|
225
151
|
}
|
|
226
152
|
|
|
227
153
|
return {
|
|
228
154
|
state: 'accepted',
|
|
229
|
-
value
|
|
155
|
+
data: value,
|
|
156
|
+
form: {
|
|
157
|
+
value,
|
|
158
|
+
error: {}
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
function createValidate(handler) {
|
|
163
|
+
return (form, submitter) => {
|
|
164
|
+
var formData = getFormData(form, submitter);
|
|
165
|
+
|
|
166
|
+
for (var _field of form.elements) {
|
|
167
|
+
if (isFieldElement(_field)) {
|
|
168
|
+
handler(_field, formData);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
230
171
|
};
|
|
231
172
|
}
|
|
232
|
-
function
|
|
233
|
-
var
|
|
173
|
+
function getFormElement(element) {
|
|
174
|
+
var form = element instanceof HTMLFormElement ? element : element === null || element === void 0 ? void 0 : element.form;
|
|
175
|
+
|
|
176
|
+
if (!form) {
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
234
179
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
180
|
+
return form;
|
|
181
|
+
}
|
|
182
|
+
var listCommandKey = '__conform__';
|
|
183
|
+
function serializeListCommand(name, _ref) {
|
|
184
|
+
var {
|
|
185
|
+
type,
|
|
186
|
+
payload
|
|
187
|
+
} = _ref;
|
|
188
|
+
return [name, type, JSON.stringify(payload)].join('::');
|
|
189
|
+
}
|
|
190
|
+
function parseListCommand(serialized) {
|
|
191
|
+
var [name, type, json] = serialized.split('::');
|
|
192
|
+
return [name, {
|
|
193
|
+
type: type,
|
|
194
|
+
payload: JSON.parse(json)
|
|
195
|
+
}];
|
|
196
|
+
}
|
|
197
|
+
function updateList(list, command) {
|
|
198
|
+
switch (command.type) {
|
|
199
|
+
case 'prepend':
|
|
200
|
+
{
|
|
201
|
+
list.unshift(command.payload.defaultValue);
|
|
202
|
+
break;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
case 'append':
|
|
206
|
+
{
|
|
207
|
+
list.push(command.payload.defaultValue);
|
|
208
|
+
break;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
case 'replace':
|
|
212
|
+
{
|
|
213
|
+
list.splice(command.payload.index, 1, command.payload.defaultValue);
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
case 'remove':
|
|
218
|
+
list.splice(command.payload.index, 1);
|
|
219
|
+
break;
|
|
220
|
+
|
|
221
|
+
case 'reorder':
|
|
222
|
+
list.splice(command.payload.to, 0, ...list.splice(command.payload.from, 1));
|
|
223
|
+
break;
|
|
224
|
+
|
|
225
|
+
default:
|
|
226
|
+
throw new Error('Invalid list command');
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return list;
|
|
230
|
+
}
|
|
231
|
+
function applyListCommand(payload) {
|
|
232
|
+
var command = payload.get(listCommandKey);
|
|
233
|
+
|
|
234
|
+
if (!command) {
|
|
235
|
+
return payload;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
payload.delete(listCommandKey);
|
|
239
|
+
|
|
240
|
+
if (command instanceof File) {
|
|
241
|
+
throw new Error("The \"".concat(listCommandKey, "\" key could not be used for file upload"));
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
var result = new FormData();
|
|
245
|
+
var entries = [];
|
|
246
|
+
var [key, listCommand] = parseListCommand(command);
|
|
247
|
+
|
|
248
|
+
for (var [name, value] of payload) {
|
|
249
|
+
if (name.startsWith(key)) {
|
|
250
|
+
entries.push([name.replace(key, 'list'), value]);
|
|
251
|
+
} else {
|
|
252
|
+
result.append(name, value);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
var {
|
|
257
|
+
list
|
|
258
|
+
} = unflatten(entries);
|
|
259
|
+
|
|
260
|
+
if (!Array.isArray(list)) {
|
|
261
|
+
throw new Error('The list command can only be applied to a list');
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
updateList(list, listCommand);
|
|
265
|
+
|
|
266
|
+
for (var [_name, _value] of flatten(list, key)) {
|
|
267
|
+
result.append(_name, _value);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
return result;
|
|
239
271
|
}
|
|
240
272
|
|
|
241
|
-
exports.
|
|
242
|
-
exports.
|
|
243
|
-
exports.
|
|
273
|
+
exports.applyListCommand = applyListCommand;
|
|
274
|
+
exports.createSubmission = createSubmission;
|
|
275
|
+
exports.createValidate = createValidate;
|
|
276
|
+
exports.flatten = flatten;
|
|
277
|
+
exports.getFormData = getFormData;
|
|
278
|
+
exports.getFormElement = getFormElement;
|
|
279
|
+
exports.getKey = getKey;
|
|
244
280
|
exports.getName = getName;
|
|
245
281
|
exports.getPaths = getPaths;
|
|
246
282
|
exports.isFieldElement = isFieldElement;
|
|
247
|
-
exports.
|
|
248
|
-
exports.
|
|
249
|
-
exports.
|
|
250
|
-
exports.
|
|
251
|
-
exports.
|
|
252
|
-
exports.
|
|
283
|
+
exports.listCommandKey = listCommandKey;
|
|
284
|
+
exports.parseListCommand = parseListCommand;
|
|
285
|
+
exports.serializeListCommand = serializeListCommand;
|
|
286
|
+
exports.setFormError = setFormError;
|
|
287
|
+
exports.setValue = setValue;
|
|
288
|
+
exports.unflatten = unflatten;
|
|
289
|
+
exports.updateList = updateList;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
function ownKeys(object, enumerableOnly) {
|
|
2
|
+
var keys = Object.keys(object);
|
|
3
|
+
|
|
4
|
+
if (Object.getOwnPropertySymbols) {
|
|
5
|
+
var symbols = Object.getOwnPropertySymbols(object);
|
|
6
|
+
enumerableOnly && (symbols = symbols.filter(function (sym) {
|
|
7
|
+
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
|
8
|
+
})), keys.push.apply(keys, symbols);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return keys;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function _objectSpread2(target) {
|
|
15
|
+
for (var i = 1; i < arguments.length; i++) {
|
|
16
|
+
var source = null != arguments[i] ? arguments[i] : {};
|
|
17
|
+
i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
|
|
18
|
+
_defineProperty(target, key, source[key]);
|
|
19
|
+
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
|
|
20
|
+
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return target;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function _defineProperty(obj, key, value) {
|
|
28
|
+
if (key in obj) {
|
|
29
|
+
Object.defineProperty(obj, key, {
|
|
30
|
+
value: value,
|
|
31
|
+
enumerable: true,
|
|
32
|
+
configurable: true,
|
|
33
|
+
writable: true
|
|
34
|
+
});
|
|
35
|
+
} else {
|
|
36
|
+
obj[key] = value;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return obj;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export { _defineProperty as defineProperty, _objectSpread2 as objectSpread2 };
|
package/module/index.js
CHANGED
|
@@ -1,80 +1,6 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Data structure of the form value
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Element that maintains a list of fields
|
|
7
|
-
* i.e. fieldset.elements
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Element type that might be a candiate of Constraint Validation
|
|
12
|
-
*/
|
|
13
|
-
function isFieldsetElement(element) {
|
|
14
|
-
return element instanceof Element && (element.tagName === 'FORM' || element.tagName === 'FIELDSET');
|
|
15
|
-
}
|
|
16
1
|
function isFieldElement(element) {
|
|
17
2
|
return element instanceof Element && (element.tagName === 'INPUT' || element.tagName === 'SELECT' || element.tagName === 'TEXTAREA' || element.tagName === 'BUTTON');
|
|
18
3
|
}
|
|
19
|
-
function setFieldState(field, state) {
|
|
20
|
-
if (isFieldsetElement(field)) {
|
|
21
|
-
for (var _element of field.elements) {
|
|
22
|
-
setFieldState(_element, state);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
if (!isFieldElement(field)) {
|
|
29
|
-
console.warn('Only input/select/textarea/button element can be touched');
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
if (state.touched) {
|
|
34
|
-
field.dataset.touched = 'true';
|
|
35
|
-
} else {
|
|
36
|
-
delete field.dataset.touched;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
function reportValidity(fieldset) {
|
|
40
|
-
var isValid = true;
|
|
41
|
-
|
|
42
|
-
for (var field of fieldset.elements) {
|
|
43
|
-
if (isFieldElement(field) && field.dataset.touched && !field.checkValidity()) {
|
|
44
|
-
isValid = false;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return isValid;
|
|
49
|
-
}
|
|
50
|
-
function createFieldConfig(schema, options) {
|
|
51
|
-
var result = {};
|
|
52
|
-
|
|
53
|
-
for (var key of Object.keys(schema.fields)) {
|
|
54
|
-
var _options$initialValue, _options$error;
|
|
55
|
-
|
|
56
|
-
var constraint = schema.fields[key];
|
|
57
|
-
var config = {
|
|
58
|
-
name: options.name ? "".concat(options.name, ".").concat(key) : key,
|
|
59
|
-
form: options.form,
|
|
60
|
-
initialValue: (_options$initialValue = options.initialValue) === null || _options$initialValue === void 0 ? void 0 : _options$initialValue[key],
|
|
61
|
-
error: (_options$error = options.error) === null || _options$error === void 0 ? void 0 : _options$error[key],
|
|
62
|
-
constraint
|
|
63
|
-
};
|
|
64
|
-
result[key] = config;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
return result;
|
|
68
|
-
}
|
|
69
|
-
function shouldSkipValidate(event) {
|
|
70
|
-
var _event$submitter, _event$submitter2;
|
|
71
|
-
|
|
72
|
-
if (((_event$submitter = event.submitter) === null || _event$submitter === void 0 ? void 0 : _event$submitter.tagName) === 'BUTTON' || ((_event$submitter2 = event.submitter) === null || _event$submitter2 === void 0 ? void 0 : _event$submitter2.tagName) === 'INPUT') {
|
|
73
|
-
return event.submitter.formNoValidate;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
return false;
|
|
77
|
-
}
|
|
78
4
|
function getPaths(name) {
|
|
79
5
|
var pattern = /(\w+)\[(\d+)\]/;
|
|
80
6
|
|
|
@@ -92,6 +18,15 @@ function getPaths(name) {
|
|
|
92
18
|
return [matches[1], Number(matches[2])];
|
|
93
19
|
});
|
|
94
20
|
}
|
|
21
|
+
function getFormData(form, submitter) {
|
|
22
|
+
var payload = new FormData(form);
|
|
23
|
+
|
|
24
|
+
if (submitter !== null && submitter !== void 0 && submitter.name) {
|
|
25
|
+
payload.append(submitter.name, submitter.value);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return payload;
|
|
29
|
+
}
|
|
95
30
|
function getName(paths) {
|
|
96
31
|
return paths.reduce((name, path) => {
|
|
97
32
|
if (name === '' || path === '') {
|
|
@@ -105,133 +40,230 @@ function getName(paths) {
|
|
|
105
40
|
return [name, path].join('.');
|
|
106
41
|
}, '');
|
|
107
42
|
}
|
|
108
|
-
function
|
|
109
|
-
var
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
var paths = getPaths(key);
|
|
113
|
-
var length = paths.length;
|
|
114
|
-
var lastIndex = length - 1;
|
|
115
|
-
var index = -1;
|
|
116
|
-
var pointer = result;
|
|
117
|
-
|
|
118
|
-
while (pointer != null && ++index < length) {
|
|
119
|
-
var _key = paths[index];
|
|
120
|
-
var next = paths[index + 1];
|
|
121
|
-
var newValue = value;
|
|
122
|
-
|
|
123
|
-
if (index != lastIndex) {
|
|
124
|
-
var _pointer$_key;
|
|
43
|
+
function getKey(fieldName) {
|
|
44
|
+
var fieldsetName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
|
|
45
|
+
var name = fieldsetName === '' || fieldName.startsWith(fieldsetName) ? fieldName.slice(fieldsetName ? fieldsetName.length + 1 : 0) : '';
|
|
46
|
+
var paths = getPaths(name);
|
|
125
47
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
// ? pointer[key].concat(newValue)
|
|
130
|
-
// : [pointer[key], newValue];
|
|
131
|
-
// } else {
|
|
48
|
+
if (paths.length > 1) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
132
51
|
|
|
52
|
+
return typeof paths[0] === 'string' ? paths[0] : null;
|
|
53
|
+
}
|
|
54
|
+
function setFormError(form, errors) {
|
|
55
|
+
var firstErrorByName = Object.fromEntries([...errors].reverse());
|
|
133
56
|
|
|
134
|
-
|
|
57
|
+
for (var _element of form.elements) {
|
|
58
|
+
var _firstErrorByName$_el;
|
|
135
59
|
|
|
136
|
-
|
|
60
|
+
if (!isFieldElement(_element)) {
|
|
61
|
+
continue;
|
|
137
62
|
}
|
|
138
|
-
}
|
|
139
63
|
|
|
140
|
-
|
|
64
|
+
_element.setCustomValidity((_firstErrorByName$_el = firstErrorByName[_element.name]) !== null && _firstErrorByName$_el !== void 0 ? _firstErrorByName$_el : '');
|
|
65
|
+
}
|
|
141
66
|
}
|
|
142
|
-
function
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
67
|
+
function setValue(target, paths, valueFn) {
|
|
68
|
+
var length = paths.length;
|
|
69
|
+
var lastIndex = length - 1;
|
|
70
|
+
var index = -1;
|
|
71
|
+
var pointer = target;
|
|
72
|
+
|
|
73
|
+
while (pointer != null && ++index < length) {
|
|
74
|
+
var _pointer$key;
|
|
75
|
+
|
|
76
|
+
var key = paths[index];
|
|
77
|
+
var next = paths[index + 1];
|
|
78
|
+
var newValue = index != lastIndex ? (_pointer$key = pointer[key]) !== null && _pointer$key !== void 0 ? _pointer$key : typeof next === 'number' ? [] : {} : valueFn(pointer[key]);
|
|
79
|
+
pointer[key] = newValue;
|
|
80
|
+
pointer = pointer[key];
|
|
81
|
+
}
|
|
149
82
|
}
|
|
150
|
-
function
|
|
151
|
-
var
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
83
|
+
function flatten(data) {
|
|
84
|
+
var prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
|
|
85
|
+
var entries = [];
|
|
86
|
+
|
|
87
|
+
if (typeof data === 'string' || typeof data === 'undefined' || data instanceof File) {
|
|
88
|
+
entries.push([prefix, data !== null && data !== void 0 ? data : '']);
|
|
89
|
+
} else if (Array.isArray(data)) {
|
|
90
|
+
for (var i = 0; i < data.length; i++) {
|
|
91
|
+
entries.push(...flatten(data[i], "".concat(prefix, "[").concat(i, "]")));
|
|
92
|
+
}
|
|
93
|
+
} else {
|
|
94
|
+
for (var [key, value] of Object.entries(Object(data))) {
|
|
95
|
+
entries.push(...flatten(value, prefix ? "".concat(prefix, ".").concat(key) : key));
|
|
96
|
+
}
|
|
155
97
|
}
|
|
156
98
|
|
|
157
|
-
|
|
99
|
+
return entries;
|
|
100
|
+
}
|
|
101
|
+
function unflatten(entries) {
|
|
102
|
+
var result = {};
|
|
158
103
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
104
|
+
var _loop = function _loop(key, value) {
|
|
105
|
+
var paths = getPaths(key);
|
|
106
|
+
setValue(result, paths, prev => {
|
|
107
|
+
if (prev) {
|
|
108
|
+
throw new Error('Entry with the same name is not supported');
|
|
163
109
|
}
|
|
164
110
|
|
|
165
|
-
|
|
166
|
-
|
|
111
|
+
return value;
|
|
112
|
+
});
|
|
113
|
+
};
|
|
167
114
|
|
|
168
|
-
|
|
169
|
-
|
|
115
|
+
for (var [key, value] of entries) {
|
|
116
|
+
_loop(key, value);
|
|
117
|
+
}
|
|
170
118
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
119
|
+
return result;
|
|
120
|
+
}
|
|
121
|
+
function createSubmission(payload) {
|
|
122
|
+
var value = {};
|
|
175
123
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
124
|
+
try {
|
|
125
|
+
var modifiedPayload = applyListCommand(payload);
|
|
126
|
+
value = unflatten(modifiedPayload.entries());
|
|
179
127
|
|
|
180
|
-
|
|
181
|
-
case 'prepend':
|
|
182
|
-
{
|
|
183
|
-
var initialValue = JSON.parse(json);
|
|
184
|
-
list.unshift(initialValue);
|
|
185
|
-
break;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
case 'append':
|
|
189
|
-
{
|
|
190
|
-
var _initialValue = JSON.parse(json);
|
|
191
|
-
|
|
192
|
-
list.push(_initialValue);
|
|
193
|
-
break;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
case 'remove':
|
|
197
|
-
var {
|
|
198
|
-
index
|
|
199
|
-
} = JSON.parse(json);
|
|
200
|
-
list.splice(index, 1);
|
|
201
|
-
break;
|
|
202
|
-
|
|
203
|
-
default:
|
|
204
|
-
throw new Error('Invalid action found; Only `prepend`, `append` and `remove` is accepted');
|
|
205
|
-
}
|
|
206
|
-
} catch (e) {
|
|
128
|
+
if (payload !== modifiedPayload) {
|
|
207
129
|
return {
|
|
208
|
-
state: '
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
130
|
+
state: 'modified',
|
|
131
|
+
form: {
|
|
132
|
+
value,
|
|
133
|
+
error: {}
|
|
212
134
|
}
|
|
213
135
|
};
|
|
214
136
|
}
|
|
215
|
-
|
|
137
|
+
} catch (e) {
|
|
216
138
|
return {
|
|
217
|
-
state: '
|
|
218
|
-
|
|
219
|
-
|
|
139
|
+
state: 'rejected',
|
|
140
|
+
form: {
|
|
141
|
+
value,
|
|
142
|
+
error: {
|
|
143
|
+
message: e instanceof Error ? e.message : 'Submission failed'
|
|
144
|
+
}
|
|
145
|
+
}
|
|
220
146
|
};
|
|
221
147
|
}
|
|
222
148
|
|
|
223
149
|
return {
|
|
224
150
|
state: 'accepted',
|
|
225
|
-
value
|
|
151
|
+
data: value,
|
|
152
|
+
form: {
|
|
153
|
+
value,
|
|
154
|
+
error: {}
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
function createValidate(handler) {
|
|
159
|
+
return (form, submitter) => {
|
|
160
|
+
var formData = getFormData(form, submitter);
|
|
161
|
+
|
|
162
|
+
for (var _field of form.elements) {
|
|
163
|
+
if (isFieldElement(_field)) {
|
|
164
|
+
handler(_field, formData);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
226
167
|
};
|
|
227
168
|
}
|
|
228
|
-
function
|
|
229
|
-
var
|
|
169
|
+
function getFormElement(element) {
|
|
170
|
+
var form = element instanceof HTMLFormElement ? element : element === null || element === void 0 ? void 0 : element.form;
|
|
171
|
+
|
|
172
|
+
if (!form) {
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
230
175
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
176
|
+
return form;
|
|
177
|
+
}
|
|
178
|
+
var listCommandKey = '__conform__';
|
|
179
|
+
function serializeListCommand(name, _ref) {
|
|
180
|
+
var {
|
|
181
|
+
type,
|
|
182
|
+
payload
|
|
183
|
+
} = _ref;
|
|
184
|
+
return [name, type, JSON.stringify(payload)].join('::');
|
|
185
|
+
}
|
|
186
|
+
function parseListCommand(serialized) {
|
|
187
|
+
var [name, type, json] = serialized.split('::');
|
|
188
|
+
return [name, {
|
|
189
|
+
type: type,
|
|
190
|
+
payload: JSON.parse(json)
|
|
191
|
+
}];
|
|
192
|
+
}
|
|
193
|
+
function updateList(list, command) {
|
|
194
|
+
switch (command.type) {
|
|
195
|
+
case 'prepend':
|
|
196
|
+
{
|
|
197
|
+
list.unshift(command.payload.defaultValue);
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
case 'append':
|
|
202
|
+
{
|
|
203
|
+
list.push(command.payload.defaultValue);
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
case 'replace':
|
|
208
|
+
{
|
|
209
|
+
list.splice(command.payload.index, 1, command.payload.defaultValue);
|
|
210
|
+
break;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
case 'remove':
|
|
214
|
+
list.splice(command.payload.index, 1);
|
|
215
|
+
break;
|
|
216
|
+
|
|
217
|
+
case 'reorder':
|
|
218
|
+
list.splice(command.payload.to, 0, ...list.splice(command.payload.from, 1));
|
|
219
|
+
break;
|
|
220
|
+
|
|
221
|
+
default:
|
|
222
|
+
throw new Error('Invalid list command');
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return list;
|
|
226
|
+
}
|
|
227
|
+
function applyListCommand(payload) {
|
|
228
|
+
var command = payload.get(listCommandKey);
|
|
229
|
+
|
|
230
|
+
if (!command) {
|
|
231
|
+
return payload;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
payload.delete(listCommandKey);
|
|
235
|
+
|
|
236
|
+
if (command instanceof File) {
|
|
237
|
+
throw new Error("The \"".concat(listCommandKey, "\" key could not be used for file upload"));
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
var result = new FormData();
|
|
241
|
+
var entries = [];
|
|
242
|
+
var [key, listCommand] = parseListCommand(command);
|
|
243
|
+
|
|
244
|
+
for (var [name, value] of payload) {
|
|
245
|
+
if (name.startsWith(key)) {
|
|
246
|
+
entries.push([name.replace(key, 'list'), value]);
|
|
247
|
+
} else {
|
|
248
|
+
result.append(name, value);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
var {
|
|
253
|
+
list
|
|
254
|
+
} = unflatten(entries);
|
|
255
|
+
|
|
256
|
+
if (!Array.isArray(list)) {
|
|
257
|
+
throw new Error('The list command can only be applied to a list');
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
updateList(list, listCommand);
|
|
261
|
+
|
|
262
|
+
for (var [_name, _value] of flatten(list, key)) {
|
|
263
|
+
result.append(_name, _value);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
return result;
|
|
235
267
|
}
|
|
236
268
|
|
|
237
|
-
export {
|
|
269
|
+
export { applyListCommand, createSubmission, createValidate, flatten, getFormData, getFormElement, getKey, getName, getPaths, isFieldElement, listCommandKey, parseListCommand, serializeListCommand, setFormError, setValue, unflatten, updateList };
|
package/package.json
CHANGED