@conform-to/dom 0.3.1 → 0.4.0-pre.1
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/index.d.ts +30 -38
- package/index.js +140 -156
- package/module/index.js +133 -149
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -3,18 +3,12 @@ export declare type FieldElement = HTMLInputElement | HTMLSelectElement | HTMLTe
|
|
|
3
3
|
export interface FieldConfig<Schema = unknown> extends FieldConstraint {
|
|
4
4
|
name: string;
|
|
5
5
|
defaultValue?: FieldValue<Schema>;
|
|
6
|
-
initialError?:
|
|
6
|
+
initialError?: Array<[string, string]>;
|
|
7
7
|
form?: string;
|
|
8
8
|
}
|
|
9
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
10
|
[Key in keyof Schema]?: FieldValue<Schema[Key]>;
|
|
11
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
12
|
export declare type FieldConstraint = {
|
|
19
13
|
required?: boolean;
|
|
20
14
|
minLength?: number;
|
|
@@ -28,69 +22,67 @@ export declare type FieldConstraint = {
|
|
|
28
22
|
export declare type FieldsetConstraint<Schema extends Record<string, any>> = {
|
|
29
23
|
[Key in keyof Schema]?: FieldConstraint;
|
|
30
24
|
};
|
|
31
|
-
export declare type Schema
|
|
32
|
-
|
|
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>> {
|
|
25
|
+
export declare type Submission<Schema = unknown> = {
|
|
26
|
+
type?: undefined;
|
|
38
27
|
value: FieldValue<Schema>;
|
|
39
|
-
error:
|
|
40
|
-
}
|
|
41
|
-
export declare type Submission<T extends Record<string, unknown>> = {
|
|
42
|
-
state: 'modified';
|
|
43
|
-
form: FormState<T>;
|
|
44
|
-
} | {
|
|
45
|
-
state: 'rejected';
|
|
46
|
-
form: FormState<T>;
|
|
28
|
+
error: Array<[string, string]>;
|
|
47
29
|
} | {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
30
|
+
type: string;
|
|
31
|
+
metadata: string;
|
|
32
|
+
value: FieldValue<Schema>;
|
|
33
|
+
error: Array<[string, string]>;
|
|
51
34
|
};
|
|
52
35
|
export declare function isFieldElement(element: unknown): element is FieldElement;
|
|
53
|
-
export declare function getPaths(name
|
|
36
|
+
export declare function getPaths(name: string): Array<string | number>;
|
|
54
37
|
export declare function getFormData(form: HTMLFormElement, submitter?: HTMLInputElement | HTMLButtonElement | null): FormData;
|
|
55
38
|
export declare function getName(paths: Array<string | number>): string;
|
|
56
|
-
export declare function
|
|
57
|
-
export declare function
|
|
39
|
+
export declare function shouldValidate(submission: Submission, name: string): boolean;
|
|
40
|
+
export declare function hasError(error: Array<[string, string]>, name: string): boolean;
|
|
41
|
+
export declare function setFormError(form: HTMLFormElement, submission: Submission): void;
|
|
58
42
|
export declare function setValue<T>(target: any, paths: Array<string | number>, valueFn: (prev?: T) => T): void;
|
|
59
|
-
export declare function
|
|
60
|
-
export declare function
|
|
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;
|
|
43
|
+
export declare function requestSubmit(form: HTMLFormElement, submitter?: HTMLButtonElement | HTMLInputElement): void;
|
|
44
|
+
export declare function requestValidate(form: HTMLFormElement, field?: string): void;
|
|
63
45
|
export declare function getFormElement(element: HTMLFormElement | HTMLFieldSetElement | HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement | HTMLButtonElement | null): HTMLFormElement | null;
|
|
64
|
-
export declare
|
|
46
|
+
export declare function focusFirstInvalidField(form: HTMLFormElement): void;
|
|
47
|
+
export declare function getSubmissionType(name: string): string | null;
|
|
48
|
+
export declare function parse<Schema extends Record<string, any>>(payload: FormData | URLSearchParams): Submission<Schema>;
|
|
49
|
+
export declare type Command = {
|
|
50
|
+
name: string;
|
|
51
|
+
value: string;
|
|
52
|
+
};
|
|
53
|
+
export declare type ListCommand<Schema = unknown> = {
|
|
65
54
|
type: 'prepend';
|
|
55
|
+
scope: string;
|
|
66
56
|
payload: {
|
|
67
57
|
defaultValue: Schema;
|
|
68
58
|
};
|
|
69
59
|
} | {
|
|
70
60
|
type: 'append';
|
|
61
|
+
scope: string;
|
|
71
62
|
payload: {
|
|
72
63
|
defaultValue: Schema;
|
|
73
64
|
};
|
|
74
65
|
} | {
|
|
75
66
|
type: 'replace';
|
|
67
|
+
scope: string;
|
|
76
68
|
payload: {
|
|
77
69
|
defaultValue: Schema;
|
|
78
70
|
index: number;
|
|
79
71
|
};
|
|
80
72
|
} | {
|
|
81
73
|
type: 'remove';
|
|
74
|
+
scope: string;
|
|
82
75
|
payload: {
|
|
83
76
|
index: number;
|
|
84
77
|
};
|
|
85
78
|
} | {
|
|
86
79
|
type: 'reorder';
|
|
80
|
+
scope: string;
|
|
87
81
|
payload: {
|
|
88
82
|
from: number;
|
|
89
83
|
to: number;
|
|
90
84
|
};
|
|
91
85
|
};
|
|
92
|
-
export declare
|
|
93
|
-
export declare function
|
|
94
|
-
export declare function
|
|
95
|
-
export declare function updateList<Type>(list: Array<Type>, command: ListCommand<Type>): Array<Type>;
|
|
96
|
-
export declare function applyListCommand(payload: FormData | URLSearchParams): FormData | URLSearchParams;
|
|
86
|
+
export declare function parseListCommand<Schema = unknown>(data: string): ListCommand<Schema>;
|
|
87
|
+
export declare function updateList<Schema>(list: Array<Schema>, command: ListCommand<Schema>): Array<Schema>;
|
|
88
|
+
export declare function handleList<Schema>(submission: Submission<Schema>): Submission<Schema>;
|
package/index.js
CHANGED
|
@@ -2,11 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
+
var _rollupPluginBabelHelpers = require('./_virtual/_rollupPluginBabelHelpers.js');
|
|
6
|
+
|
|
5
7
|
function isFieldElement(element) {
|
|
6
8
|
return element instanceof Element && (element.tagName === 'INPUT' || element.tagName === 'SELECT' || element.tagName === 'TEXTAREA' || element.tagName === 'BUTTON');
|
|
7
9
|
}
|
|
8
10
|
function getPaths(name) {
|
|
9
|
-
var pattern = /(\w
|
|
11
|
+
var pattern = /(\w*)\[(\d+)\]/;
|
|
10
12
|
|
|
11
13
|
if (!name) {
|
|
12
14
|
return [];
|
|
@@ -19,6 +21,10 @@ function getPaths(name) {
|
|
|
19
21
|
return key;
|
|
20
22
|
}
|
|
21
23
|
|
|
24
|
+
if (matches[1] === '') {
|
|
25
|
+
return Number(matches[2]);
|
|
26
|
+
}
|
|
27
|
+
|
|
22
28
|
return [matches[1], Number(matches[2])];
|
|
23
29
|
});
|
|
24
30
|
}
|
|
@@ -33,39 +39,37 @@ function getFormData(form, submitter) {
|
|
|
33
39
|
}
|
|
34
40
|
function getName(paths) {
|
|
35
41
|
return paths.reduce((name, path) => {
|
|
36
|
-
if (name === '' || path === '') {
|
|
37
|
-
return [name, path].join('');
|
|
38
|
-
}
|
|
39
|
-
|
|
40
42
|
if (typeof path === 'number') {
|
|
41
43
|
return "".concat(name, "[").concat(path, "]");
|
|
42
44
|
}
|
|
43
45
|
|
|
46
|
+
if (name === '' || path === '') {
|
|
47
|
+
return [name, path].join('');
|
|
48
|
+
}
|
|
49
|
+
|
|
44
50
|
return [name, path].join('.');
|
|
45
51
|
}, '');
|
|
46
52
|
}
|
|
47
|
-
function
|
|
48
|
-
|
|
49
|
-
var name = fieldsetName === '' || fieldName.startsWith(fieldsetName) ? fieldName.slice(fieldsetName ? fieldsetName.length + 1 : 0) : '';
|
|
50
|
-
var paths = getPaths(name);
|
|
51
|
-
|
|
52
|
-
if (paths.length > 1) {
|
|
53
|
-
return null;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return typeof paths[0] === 'string' ? paths[0] : null;
|
|
53
|
+
function shouldValidate(submission, name) {
|
|
54
|
+
return submission.type !== 'validate' || submission.metadata === name;
|
|
57
55
|
}
|
|
58
|
-
function
|
|
59
|
-
|
|
56
|
+
function hasError(error, name) {
|
|
57
|
+
return typeof error.find(_ref => {
|
|
58
|
+
var [fieldName, message] = _ref;
|
|
59
|
+
return fieldName === name && message !== '';
|
|
60
|
+
}) !== 'undefined';
|
|
61
|
+
}
|
|
62
|
+
function setFormError(form, submission) {
|
|
63
|
+
var firstErrorByName = Object.fromEntries([...submission.error].reverse());
|
|
60
64
|
|
|
61
|
-
for (var
|
|
62
|
-
|
|
65
|
+
for (var element of form.elements) {
|
|
66
|
+
if (isFieldElement(element)) {
|
|
67
|
+
var error = firstErrorByName[element.name];
|
|
63
68
|
|
|
64
|
-
|
|
65
|
-
|
|
69
|
+
if (typeof error !== 'undefined' || shouldValidate(submission, element.name)) {
|
|
70
|
+
element.setCustomValidity(error !== null && error !== void 0 ? error : '');
|
|
71
|
+
}
|
|
66
72
|
}
|
|
67
|
-
|
|
68
|
-
_element.setCustomValidity((_firstErrorByName$_el = firstErrorByName[_element.name]) !== null && _firstErrorByName$_el !== void 0 ? _firstErrorByName$_el : '');
|
|
69
73
|
}
|
|
70
74
|
}
|
|
71
75
|
function setValue(target, paths, valueFn) {
|
|
@@ -84,115 +88,120 @@ function setValue(target, paths, valueFn) {
|
|
|
84
88
|
pointer = pointer[key];
|
|
85
89
|
}
|
|
86
90
|
}
|
|
87
|
-
function
|
|
88
|
-
var
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
91
|
+
function requestSubmit(form, submitter) {
|
|
92
|
+
var submitEvent = new SubmitEvent('submit', {
|
|
93
|
+
bubbles: true,
|
|
94
|
+
cancelable: true,
|
|
95
|
+
submitter
|
|
96
|
+
});
|
|
97
|
+
form.dispatchEvent(submitEvent);
|
|
98
|
+
}
|
|
99
|
+
function requestValidate(form, field) {
|
|
100
|
+
var button = document.createElement('button');
|
|
101
|
+
button.name = 'conform/validate';
|
|
102
|
+
button.value = field !== null && field !== void 0 ? field : '';
|
|
103
|
+
button.hidden = true;
|
|
104
|
+
form.appendChild(button);
|
|
105
|
+
requestSubmit(form, button);
|
|
106
|
+
form.removeChild(button);
|
|
107
|
+
}
|
|
108
|
+
function getFormElement(element) {
|
|
109
|
+
var form = element instanceof HTMLFormElement ? element : element === null || element === void 0 ? void 0 : element.form;
|
|
110
|
+
|
|
111
|
+
if (!form) {
|
|
112
|
+
return null;
|
|
101
113
|
}
|
|
102
114
|
|
|
103
|
-
return
|
|
115
|
+
return form;
|
|
104
116
|
}
|
|
105
|
-
function
|
|
106
|
-
var
|
|
107
|
-
|
|
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');
|
|
113
|
-
}
|
|
117
|
+
function focusFirstInvalidField(form) {
|
|
118
|
+
var currentFocus = document.activeElement;
|
|
114
119
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}
|
|
120
|
+
if (!isFieldElement(currentFocus) || currentFocus.tagName !== 'BUTTON' || currentFocus.form !== form) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
118
123
|
|
|
119
|
-
for (var
|
|
120
|
-
|
|
124
|
+
for (var field of form.elements) {
|
|
125
|
+
if (isFieldElement(field)) {
|
|
126
|
+
// Focus on the first non button field
|
|
127
|
+
if (!field.validity.valid && field.dataset.conformTouched && field.tagName !== 'BUTTON') {
|
|
128
|
+
field.focus();
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
function getSubmissionType(name) {
|
|
135
|
+
var prefix = 'conform/';
|
|
136
|
+
|
|
137
|
+
if (!name.startsWith(prefix) || name.length <= prefix.length) {
|
|
138
|
+
return null;
|
|
121
139
|
}
|
|
122
140
|
|
|
123
|
-
return
|
|
141
|
+
return name.slice(prefix.length);
|
|
124
142
|
}
|
|
125
|
-
function
|
|
126
|
-
var
|
|
143
|
+
function parse(payload) {
|
|
144
|
+
var submission = {
|
|
145
|
+
value: {},
|
|
146
|
+
error: []
|
|
147
|
+
};
|
|
127
148
|
|
|
128
149
|
try {
|
|
129
|
-
var
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
form: {
|
|
136
|
-
value,
|
|
137
|
-
error: {}
|
|
150
|
+
var _loop = function _loop(name, value) {
|
|
151
|
+
var submissionType = getSubmissionType(name);
|
|
152
|
+
|
|
153
|
+
if (submissionType) {
|
|
154
|
+
if (typeof value !== 'string') {
|
|
155
|
+
throw new Error('The conform command could not be used on a file input');
|
|
138
156
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
return {
|
|
143
|
-
state: 'rejected',
|
|
144
|
-
form: {
|
|
145
|
-
value,
|
|
146
|
-
error: {
|
|
147
|
-
message: e instanceof Error ? e.message : 'Submission failed'
|
|
157
|
+
|
|
158
|
+
if (typeof submission.type !== 'undefined') {
|
|
159
|
+
throw new Error('The conform command could only be set on a button');
|
|
148
160
|
}
|
|
161
|
+
|
|
162
|
+
submission = _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, submission), {}, {
|
|
163
|
+
type: submissionType,
|
|
164
|
+
metadata: value
|
|
165
|
+
});
|
|
166
|
+
} else {
|
|
167
|
+
var paths = getPaths(name);
|
|
168
|
+
setValue(submission.value, paths, prev => {
|
|
169
|
+
if (prev) {
|
|
170
|
+
throw new Error('Entry with the same name is not supported');
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return value;
|
|
174
|
+
});
|
|
149
175
|
}
|
|
150
176
|
};
|
|
151
|
-
}
|
|
152
177
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
data: value,
|
|
156
|
-
form: {
|
|
157
|
-
value,
|
|
158
|
-
error: {}
|
|
178
|
+
for (var [name, value] of payload.entries()) {
|
|
179
|
+
_loop(name, value);
|
|
159
180
|
}
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
function createValidate(handler) {
|
|
163
|
-
return (form, submitter) => {
|
|
164
|
-
var formData = getFormData(form, submitter);
|
|
165
181
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
182
|
+
switch (submission.type) {
|
|
183
|
+
case 'list':
|
|
184
|
+
submission = handleList(submission);
|
|
185
|
+
break;
|
|
170
186
|
}
|
|
171
|
-
}
|
|
172
|
-
|
|
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;
|
|
187
|
+
} catch (e) {
|
|
188
|
+
submission.error.push(['', e instanceof Error ? e.message : 'Invalid payload received']);
|
|
178
189
|
}
|
|
179
190
|
|
|
180
|
-
return
|
|
191
|
+
return submission;
|
|
181
192
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
payload: JSON.parse(json)
|
|
195
|
-
}];
|
|
193
|
+
function parseListCommand(data) {
|
|
194
|
+
try {
|
|
195
|
+
var command = JSON.parse(data);
|
|
196
|
+
|
|
197
|
+
if (typeof command.type !== 'string' || !['prepend', 'append', 'replace', 'remove', 'reorder'].includes(command.type)) {
|
|
198
|
+
throw new Error('Unsupported list command type');
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
return command;
|
|
202
|
+
} catch (error) {
|
|
203
|
+
throw new Error("Invalid list command: \"".concat(data, "\"; ").concat(error));
|
|
204
|
+
}
|
|
196
205
|
}
|
|
197
206
|
function updateList(list, command) {
|
|
198
207
|
switch (command.type) {
|
|
@@ -223,67 +232,42 @@ function updateList(list, command) {
|
|
|
223
232
|
break;
|
|
224
233
|
|
|
225
234
|
default:
|
|
226
|
-
throw new Error('
|
|
235
|
+
throw new Error('Unknown list command received');
|
|
227
236
|
}
|
|
228
237
|
|
|
229
238
|
return list;
|
|
230
239
|
}
|
|
231
|
-
function
|
|
232
|
-
|
|
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"));
|
|
240
|
+
function handleList(submission) {
|
|
241
|
+
if (submission.type !== 'list') {
|
|
242
|
+
return submission;
|
|
242
243
|
}
|
|
243
244
|
|
|
244
|
-
var
|
|
245
|
-
var
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
if (name.startsWith(key)) {
|
|
250
|
-
entries.push([name.replace(key, 'list'), value]);
|
|
251
|
-
} else {
|
|
252
|
-
result.append(name, value);
|
|
245
|
+
var command = parseListCommand(submission.metadata);
|
|
246
|
+
var paths = getPaths(command.scope);
|
|
247
|
+
setValue(submission.value, paths, list => {
|
|
248
|
+
if (!Array.isArray(list)) {
|
|
249
|
+
throw new Error('The list command can only be applied to a list');
|
|
253
250
|
}
|
|
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
251
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
result.append(_name, _value);
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
return result;
|
|
252
|
+
return updateList(list, command);
|
|
253
|
+
});
|
|
254
|
+
return submission;
|
|
271
255
|
}
|
|
272
256
|
|
|
273
|
-
exports.
|
|
274
|
-
exports.createSubmission = createSubmission;
|
|
275
|
-
exports.createValidate = createValidate;
|
|
276
|
-
exports.flatten = flatten;
|
|
257
|
+
exports.focusFirstInvalidField = focusFirstInvalidField;
|
|
277
258
|
exports.getFormData = getFormData;
|
|
278
259
|
exports.getFormElement = getFormElement;
|
|
279
|
-
exports.getKey = getKey;
|
|
280
260
|
exports.getName = getName;
|
|
281
261
|
exports.getPaths = getPaths;
|
|
262
|
+
exports.getSubmissionType = getSubmissionType;
|
|
263
|
+
exports.handleList = handleList;
|
|
264
|
+
exports.hasError = hasError;
|
|
282
265
|
exports.isFieldElement = isFieldElement;
|
|
283
|
-
exports.
|
|
266
|
+
exports.parse = parse;
|
|
284
267
|
exports.parseListCommand = parseListCommand;
|
|
285
|
-
exports.
|
|
268
|
+
exports.requestSubmit = requestSubmit;
|
|
269
|
+
exports.requestValidate = requestValidate;
|
|
286
270
|
exports.setFormError = setFormError;
|
|
287
271
|
exports.setValue = setValue;
|
|
288
|
-
exports.
|
|
272
|
+
exports.shouldValidate = shouldValidate;
|
|
289
273
|
exports.updateList = updateList;
|
package/module/index.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { objectSpread2 as _objectSpread2 } from './_virtual/_rollupPluginBabelHelpers.js';
|
|
2
|
+
|
|
1
3
|
function isFieldElement(element) {
|
|
2
4
|
return element instanceof Element && (element.tagName === 'INPUT' || element.tagName === 'SELECT' || element.tagName === 'TEXTAREA' || element.tagName === 'BUTTON');
|
|
3
5
|
}
|
|
4
6
|
function getPaths(name) {
|
|
5
|
-
var pattern = /(\w
|
|
7
|
+
var pattern = /(\w*)\[(\d+)\]/;
|
|
6
8
|
|
|
7
9
|
if (!name) {
|
|
8
10
|
return [];
|
|
@@ -15,6 +17,10 @@ function getPaths(name) {
|
|
|
15
17
|
return key;
|
|
16
18
|
}
|
|
17
19
|
|
|
20
|
+
if (matches[1] === '') {
|
|
21
|
+
return Number(matches[2]);
|
|
22
|
+
}
|
|
23
|
+
|
|
18
24
|
return [matches[1], Number(matches[2])];
|
|
19
25
|
});
|
|
20
26
|
}
|
|
@@ -29,39 +35,37 @@ function getFormData(form, submitter) {
|
|
|
29
35
|
}
|
|
30
36
|
function getName(paths) {
|
|
31
37
|
return paths.reduce((name, path) => {
|
|
32
|
-
if (name === '' || path === '') {
|
|
33
|
-
return [name, path].join('');
|
|
34
|
-
}
|
|
35
|
-
|
|
36
38
|
if (typeof path === 'number') {
|
|
37
39
|
return "".concat(name, "[").concat(path, "]");
|
|
38
40
|
}
|
|
39
41
|
|
|
42
|
+
if (name === '' || path === '') {
|
|
43
|
+
return [name, path].join('');
|
|
44
|
+
}
|
|
45
|
+
|
|
40
46
|
return [name, path].join('.');
|
|
41
47
|
}, '');
|
|
42
48
|
}
|
|
43
|
-
function
|
|
44
|
-
|
|
45
|
-
var name = fieldsetName === '' || fieldName.startsWith(fieldsetName) ? fieldName.slice(fieldsetName ? fieldsetName.length + 1 : 0) : '';
|
|
46
|
-
var paths = getPaths(name);
|
|
47
|
-
|
|
48
|
-
if (paths.length > 1) {
|
|
49
|
-
return null;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return typeof paths[0] === 'string' ? paths[0] : null;
|
|
49
|
+
function shouldValidate(submission, name) {
|
|
50
|
+
return submission.type !== 'validate' || submission.metadata === name;
|
|
53
51
|
}
|
|
54
|
-
function
|
|
55
|
-
|
|
52
|
+
function hasError(error, name) {
|
|
53
|
+
return typeof error.find(_ref => {
|
|
54
|
+
var [fieldName, message] = _ref;
|
|
55
|
+
return fieldName === name && message !== '';
|
|
56
|
+
}) !== 'undefined';
|
|
57
|
+
}
|
|
58
|
+
function setFormError(form, submission) {
|
|
59
|
+
var firstErrorByName = Object.fromEntries([...submission.error].reverse());
|
|
56
60
|
|
|
57
|
-
for (var
|
|
58
|
-
|
|
61
|
+
for (var element of form.elements) {
|
|
62
|
+
if (isFieldElement(element)) {
|
|
63
|
+
var error = firstErrorByName[element.name];
|
|
59
64
|
|
|
60
|
-
|
|
61
|
-
|
|
65
|
+
if (typeof error !== 'undefined' || shouldValidate(submission, element.name)) {
|
|
66
|
+
element.setCustomValidity(error !== null && error !== void 0 ? error : '');
|
|
67
|
+
}
|
|
62
68
|
}
|
|
63
|
-
|
|
64
|
-
_element.setCustomValidity((_firstErrorByName$_el = firstErrorByName[_element.name]) !== null && _firstErrorByName$_el !== void 0 ? _firstErrorByName$_el : '');
|
|
65
69
|
}
|
|
66
70
|
}
|
|
67
71
|
function setValue(target, paths, valueFn) {
|
|
@@ -80,115 +84,120 @@ function setValue(target, paths, valueFn) {
|
|
|
80
84
|
pointer = pointer[key];
|
|
81
85
|
}
|
|
82
86
|
}
|
|
83
|
-
function
|
|
84
|
-
var
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
87
|
+
function requestSubmit(form, submitter) {
|
|
88
|
+
var submitEvent = new SubmitEvent('submit', {
|
|
89
|
+
bubbles: true,
|
|
90
|
+
cancelable: true,
|
|
91
|
+
submitter
|
|
92
|
+
});
|
|
93
|
+
form.dispatchEvent(submitEvent);
|
|
94
|
+
}
|
|
95
|
+
function requestValidate(form, field) {
|
|
96
|
+
var button = document.createElement('button');
|
|
97
|
+
button.name = 'conform/validate';
|
|
98
|
+
button.value = field !== null && field !== void 0 ? field : '';
|
|
99
|
+
button.hidden = true;
|
|
100
|
+
form.appendChild(button);
|
|
101
|
+
requestSubmit(form, button);
|
|
102
|
+
form.removeChild(button);
|
|
103
|
+
}
|
|
104
|
+
function getFormElement(element) {
|
|
105
|
+
var form = element instanceof HTMLFormElement ? element : element === null || element === void 0 ? void 0 : element.form;
|
|
106
|
+
|
|
107
|
+
if (!form) {
|
|
108
|
+
return null;
|
|
97
109
|
}
|
|
98
110
|
|
|
99
|
-
return
|
|
111
|
+
return form;
|
|
100
112
|
}
|
|
101
|
-
function
|
|
102
|
-
var
|
|
103
|
-
|
|
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');
|
|
109
|
-
}
|
|
113
|
+
function focusFirstInvalidField(form) {
|
|
114
|
+
var currentFocus = document.activeElement;
|
|
110
115
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}
|
|
116
|
+
if (!isFieldElement(currentFocus) || currentFocus.tagName !== 'BUTTON' || currentFocus.form !== form) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
114
119
|
|
|
115
|
-
for (var
|
|
116
|
-
|
|
120
|
+
for (var field of form.elements) {
|
|
121
|
+
if (isFieldElement(field)) {
|
|
122
|
+
// Focus on the first non button field
|
|
123
|
+
if (!field.validity.valid && field.dataset.conformTouched && field.tagName !== 'BUTTON') {
|
|
124
|
+
field.focus();
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
function getSubmissionType(name) {
|
|
131
|
+
var prefix = 'conform/';
|
|
132
|
+
|
|
133
|
+
if (!name.startsWith(prefix) || name.length <= prefix.length) {
|
|
134
|
+
return null;
|
|
117
135
|
}
|
|
118
136
|
|
|
119
|
-
return
|
|
137
|
+
return name.slice(prefix.length);
|
|
120
138
|
}
|
|
121
|
-
function
|
|
122
|
-
var
|
|
139
|
+
function parse(payload) {
|
|
140
|
+
var submission = {
|
|
141
|
+
value: {},
|
|
142
|
+
error: []
|
|
143
|
+
};
|
|
123
144
|
|
|
124
145
|
try {
|
|
125
|
-
var
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
form: {
|
|
132
|
-
value,
|
|
133
|
-
error: {}
|
|
146
|
+
var _loop = function _loop(name, value) {
|
|
147
|
+
var submissionType = getSubmissionType(name);
|
|
148
|
+
|
|
149
|
+
if (submissionType) {
|
|
150
|
+
if (typeof value !== 'string') {
|
|
151
|
+
throw new Error('The conform command could not be used on a file input');
|
|
134
152
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
return {
|
|
139
|
-
state: 'rejected',
|
|
140
|
-
form: {
|
|
141
|
-
value,
|
|
142
|
-
error: {
|
|
143
|
-
message: e instanceof Error ? e.message : 'Submission failed'
|
|
153
|
+
|
|
154
|
+
if (typeof submission.type !== 'undefined') {
|
|
155
|
+
throw new Error('The conform command could only be set on a button');
|
|
144
156
|
}
|
|
157
|
+
|
|
158
|
+
submission = _objectSpread2(_objectSpread2({}, submission), {}, {
|
|
159
|
+
type: submissionType,
|
|
160
|
+
metadata: value
|
|
161
|
+
});
|
|
162
|
+
} else {
|
|
163
|
+
var paths = getPaths(name);
|
|
164
|
+
setValue(submission.value, paths, prev => {
|
|
165
|
+
if (prev) {
|
|
166
|
+
throw new Error('Entry with the same name is not supported');
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return value;
|
|
170
|
+
});
|
|
145
171
|
}
|
|
146
172
|
};
|
|
147
|
-
}
|
|
148
173
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
data: value,
|
|
152
|
-
form: {
|
|
153
|
-
value,
|
|
154
|
-
error: {}
|
|
174
|
+
for (var [name, value] of payload.entries()) {
|
|
175
|
+
_loop(name, value);
|
|
155
176
|
}
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
function createValidate(handler) {
|
|
159
|
-
return (form, submitter) => {
|
|
160
|
-
var formData = getFormData(form, submitter);
|
|
161
177
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
178
|
+
switch (submission.type) {
|
|
179
|
+
case 'list':
|
|
180
|
+
submission = handleList(submission);
|
|
181
|
+
break;
|
|
166
182
|
}
|
|
167
|
-
}
|
|
168
|
-
|
|
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;
|
|
183
|
+
} catch (e) {
|
|
184
|
+
submission.error.push(['', e instanceof Error ? e.message : 'Invalid payload received']);
|
|
174
185
|
}
|
|
175
186
|
|
|
176
|
-
return
|
|
187
|
+
return submission;
|
|
177
188
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
payload: JSON.parse(json)
|
|
191
|
-
}];
|
|
189
|
+
function parseListCommand(data) {
|
|
190
|
+
try {
|
|
191
|
+
var command = JSON.parse(data);
|
|
192
|
+
|
|
193
|
+
if (typeof command.type !== 'string' || !['prepend', 'append', 'replace', 'remove', 'reorder'].includes(command.type)) {
|
|
194
|
+
throw new Error('Unsupported list command type');
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return command;
|
|
198
|
+
} catch (error) {
|
|
199
|
+
throw new Error("Invalid list command: \"".concat(data, "\"; ").concat(error));
|
|
200
|
+
}
|
|
192
201
|
}
|
|
193
202
|
function updateList(list, command) {
|
|
194
203
|
switch (command.type) {
|
|
@@ -219,51 +228,26 @@ function updateList(list, command) {
|
|
|
219
228
|
break;
|
|
220
229
|
|
|
221
230
|
default:
|
|
222
|
-
throw new Error('
|
|
231
|
+
throw new Error('Unknown list command received');
|
|
223
232
|
}
|
|
224
233
|
|
|
225
234
|
return list;
|
|
226
235
|
}
|
|
227
|
-
function
|
|
228
|
-
|
|
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"));
|
|
236
|
+
function handleList(submission) {
|
|
237
|
+
if (submission.type !== 'list') {
|
|
238
|
+
return submission;
|
|
238
239
|
}
|
|
239
240
|
|
|
240
|
-
var
|
|
241
|
-
var
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
if (name.startsWith(key)) {
|
|
246
|
-
entries.push([name.replace(key, 'list'), value]);
|
|
247
|
-
} else {
|
|
248
|
-
result.append(name, value);
|
|
241
|
+
var command = parseListCommand(submission.metadata);
|
|
242
|
+
var paths = getPaths(command.scope);
|
|
243
|
+
setValue(submission.value, paths, list => {
|
|
244
|
+
if (!Array.isArray(list)) {
|
|
245
|
+
throw new Error('The list command can only be applied to a list');
|
|
249
246
|
}
|
|
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
247
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
result.append(_name, _value);
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
return result;
|
|
248
|
+
return updateList(list, command);
|
|
249
|
+
});
|
|
250
|
+
return submission;
|
|
267
251
|
}
|
|
268
252
|
|
|
269
|
-
export {
|
|
253
|
+
export { focusFirstInvalidField, getFormData, getFormElement, getName, getPaths, getSubmissionType, handleList, hasError, isFieldElement, parse, parseListCommand, requestSubmit, requestValidate, setFormError, setValue, shouldValidate, updateList };
|
package/package.json
CHANGED