@conform-to/dom 1.0.2 → 1.0.4
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 +1 -1
- package/form.d.ts +3 -3
- package/form.js +83 -50
- package/form.mjs +85 -52
- package/formdata.d.ts +3 -3
- package/formdata.js +4 -12
- package/formdata.mjs +4 -12
- package/package.json +1 -1
- package/submission.d.ts +3 -2
- package/submission.js +29 -86
- package/submission.mjs +30 -87
package/README
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
╚══════╝ ╚═════╝ ╚═╝ ╚══╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
Version 1.0.
|
|
11
|
+
Version 1.0.3 / License MIT / Copyright (c) 2024 Edmund Hung
|
|
12
12
|
|
|
13
13
|
A type-safe form validation library utilizing web fundamentals to progressively enhance HTML Forms with full support for server frameworks like Remix and Next.js.
|
|
14
14
|
|
package/form.d.ts
CHANGED
|
@@ -5,11 +5,11 @@ export type Combine<T> = {
|
|
|
5
5
|
[K in keyof BaseCombine<T>]: BaseCombine<T>[K];
|
|
6
6
|
};
|
|
7
7
|
export type DefaultValue<Schema> = Schema extends string | number | boolean | Date | bigint | null | undefined ? Schema | string | null | undefined : Schema extends File ? null | undefined : Schema extends Array<infer Item> ? Array<DefaultValue<Item>> | null | undefined : Schema extends Record<string, any> ? {
|
|
8
|
-
[Key in keyof
|
|
8
|
+
[Key in keyof Schema]?: DefaultValue<Schema[Key]>;
|
|
9
9
|
} | null | undefined : string | null | undefined;
|
|
10
10
|
export type FormValue<Schema> = Schema extends string | number | boolean | Date | bigint | null | undefined ? string | undefined : Schema extends File ? File | undefined : Schema extends File[] ? File | Array<File> | undefined : Schema extends Array<infer Item> ? string | Array<FormValue<Item>> | undefined : Schema extends Record<string, any> ? {
|
|
11
|
-
[Key in keyof
|
|
12
|
-
} | undefined : unknown;
|
|
11
|
+
[Key in keyof Schema]?: FormValue<Schema[Key]>;
|
|
12
|
+
} | null | undefined : unknown;
|
|
13
13
|
declare const error: unique symbol;
|
|
14
14
|
declare const field: unique symbol;
|
|
15
15
|
declare const form: unique symbol;
|
package/form.js
CHANGED
|
@@ -11,9 +11,7 @@ var submission = require('./submission.js');
|
|
|
11
11
|
function createFormMeta(options, initialized) {
|
|
12
12
|
var _lastResult$initialVa, _options$constraint, _lastResult$state$val, _lastResult$state, _ref;
|
|
13
13
|
var lastResult = !initialized ? options.lastResult : undefined;
|
|
14
|
-
var defaultValue = options.defaultValue ?
|
|
15
|
-
// @ts-expect-error
|
|
16
|
-
submission.serialize(options.defaultValue) : {};
|
|
14
|
+
var defaultValue = options.defaultValue ? submission.serialize(options.defaultValue) : {};
|
|
17
15
|
var initialValue = (_lastResult$initialVa = lastResult === null || lastResult === void 0 ? void 0 : lastResult.initialValue) !== null && _lastResult$initialVa !== void 0 ? _lastResult$initialVa : defaultValue;
|
|
18
16
|
var result = {
|
|
19
17
|
submissionStatus: lastResult === null || lastResult === void 0 ? void 0 : lastResult.status,
|
|
@@ -29,9 +27,7 @@ function createFormMeta(options, initialized) {
|
|
|
29
27
|
// We can consider adding a warning if it happens
|
|
30
28
|
error: (_ref = lastResult === null || lastResult === void 0 ? void 0 : lastResult.error) !== null && _ref !== void 0 ? _ref : {}
|
|
31
29
|
};
|
|
32
|
-
|
|
33
|
-
handleIntent(result, lastResult.intent);
|
|
34
|
-
}
|
|
30
|
+
handleIntent(result, lastResult === null || lastResult === void 0 ? void 0 : lastResult.intent, lastResult === null || lastResult === void 0 ? void 0 : lastResult.fields);
|
|
35
31
|
return result;
|
|
36
32
|
}
|
|
37
33
|
function getDefaultKey(defaultValue, prefix) {
|
|
@@ -47,24 +43,71 @@ function getDefaultKey(defaultValue, prefix) {
|
|
|
47
43
|
return result;
|
|
48
44
|
}, {});
|
|
49
45
|
}
|
|
50
|
-
function
|
|
46
|
+
function setFieldsValidated(meta, fields) {
|
|
47
|
+
for (var _name of Object.keys(meta.error).concat(fields !== null && fields !== void 0 ? fields : [])) {
|
|
48
|
+
meta.validated[_name] = true;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function handleIntent(meta, intent, fields, initialized) {
|
|
52
|
+
if (!intent) {
|
|
53
|
+
setFieldsValidated(meta, fields);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
51
56
|
switch (intent.type) {
|
|
57
|
+
case 'validate':
|
|
58
|
+
{
|
|
59
|
+
if (intent.payload.name) {
|
|
60
|
+
meta.validated[intent.payload.name] = true;
|
|
61
|
+
} else {
|
|
62
|
+
setFieldsValidated(meta, fields);
|
|
63
|
+
}
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
52
66
|
case 'update':
|
|
53
67
|
{
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
68
|
+
var {
|
|
69
|
+
name: _name2,
|
|
70
|
+
validated,
|
|
71
|
+
value
|
|
72
|
+
} = intent.payload;
|
|
73
|
+
if (typeof value !== 'undefined') {
|
|
74
|
+
updateValue(meta, _name2 !== null && _name2 !== void 0 ? _name2 : '', submission.serialize(value));
|
|
75
|
+
}
|
|
76
|
+
if (typeof validated !== 'undefined') {
|
|
77
|
+
// Clean up previous validated state
|
|
78
|
+
if (_name2) {
|
|
79
|
+
submission.setState(meta.validated, _name2, () => undefined);
|
|
80
|
+
} else {
|
|
81
|
+
meta.validated = {};
|
|
82
|
+
}
|
|
83
|
+
if (validated) {
|
|
84
|
+
if (formdata.isPlainObject(value) || Array.isArray(value)) {
|
|
85
|
+
Object.assign(meta.validated, formdata.flatten(value, {
|
|
86
|
+
resolve() {
|
|
87
|
+
return true;
|
|
88
|
+
},
|
|
89
|
+
prefix: _name2
|
|
90
|
+
}));
|
|
91
|
+
}
|
|
92
|
+
meta.validated[_name2 !== null && _name2 !== void 0 ? _name2 : ''] = true;
|
|
93
|
+
} else if (_name2) {
|
|
94
|
+
delete meta.validated[_name2];
|
|
95
|
+
}
|
|
59
96
|
}
|
|
60
97
|
break;
|
|
61
98
|
}
|
|
62
99
|
case 'reset':
|
|
63
100
|
{
|
|
64
|
-
var _intent$payload$
|
|
65
|
-
var
|
|
66
|
-
var _value = formdata.getValue(meta.defaultValue,
|
|
67
|
-
updateValue(meta,
|
|
101
|
+
var _intent$payload$name;
|
|
102
|
+
var _name3 = (_intent$payload$name = intent.payload.name) !== null && _intent$payload$name !== void 0 ? _intent$payload$name : '';
|
|
103
|
+
var _value = formdata.getValue(meta.defaultValue, _name3);
|
|
104
|
+
updateValue(meta, _name3, _value);
|
|
105
|
+
if (_name3) {
|
|
106
|
+
submission.setState(meta.validated, _name3, () => undefined);
|
|
107
|
+
delete meta.validated[_name3];
|
|
108
|
+
} else {
|
|
109
|
+
meta.validated = {};
|
|
110
|
+
}
|
|
68
111
|
break;
|
|
69
112
|
}
|
|
70
113
|
case 'insert':
|
|
@@ -77,9 +120,18 @@ function handleIntent(meta, intent, initialized) {
|
|
|
77
120
|
submission.setListState(meta.key, intent, util.generateId);
|
|
78
121
|
submission.setListValue(meta.initialValue, intent);
|
|
79
122
|
}
|
|
123
|
+
submission.setListState(meta.validated, intent);
|
|
124
|
+
meta.validated[intent.payload.name] = true;
|
|
80
125
|
break;
|
|
81
126
|
}
|
|
82
127
|
}
|
|
128
|
+
meta.error = Object.entries(meta.error).reduce((result, _ref3) => {
|
|
129
|
+
var [name, error] = _ref3;
|
|
130
|
+
if (meta.validated[name]) {
|
|
131
|
+
result[name] = error;
|
|
132
|
+
}
|
|
133
|
+
return result;
|
|
134
|
+
}, {});
|
|
83
135
|
}
|
|
84
136
|
function updateValue(meta, name, value) {
|
|
85
137
|
meta.initialValue = util.clone(meta.initialValue);
|
|
@@ -170,8 +222,8 @@ function createValidProxy(error) {
|
|
|
170
222
|
function createDirtyProxy(defaultValue, value, shouldDirtyConsider) {
|
|
171
223
|
return createStateProxy(name => JSON.stringify(defaultValue[name]) !== JSON.stringify(value[name], (key, value) => {
|
|
172
224
|
if (name === '' && key === '' && value) {
|
|
173
|
-
return Object.entries(value).reduce((result,
|
|
174
|
-
var [name, value] =
|
|
225
|
+
return Object.entries(value).reduce((result, _ref4) => {
|
|
226
|
+
var [name, value] = _ref4;
|
|
175
227
|
if (!shouldDirtyConsider(name)) {
|
|
176
228
|
return result;
|
|
177
229
|
}
|
|
@@ -190,11 +242,11 @@ function shouldNotify(prev, next, cache, scope) {
|
|
|
190
242
|
var prefixes = (_scope$prefix = scope.prefix) !== null && _scope$prefix !== void 0 ? _scope$prefix : [];
|
|
191
243
|
var names = (_scope$name = scope.name) !== null && _scope$name !== void 0 ? _scope$name : [];
|
|
192
244
|
var list = prefixes.length === 0 ? names : Array.from(new Set([...Object.keys(prev), ...Object.keys(next)]));
|
|
193
|
-
var _loop = function _loop(
|
|
194
|
-
if (prefixes.length === 0 || names.includes(
|
|
245
|
+
var _loop = function _loop(_name4) {
|
|
246
|
+
if (prefixes.length === 0 || names.includes(_name4) || prefixes.some(prefix => formdata.isPrefix(_name4, prefix))) {
|
|
195
247
|
var _cache$_name;
|
|
196
|
-
(_cache$_name = cache[
|
|
197
|
-
if (cache[
|
|
248
|
+
(_cache$_name = cache[_name4]) !== null && _cache$_name !== void 0 ? _cache$_name : cache[_name4] = compareFn(prev[_name4], next[_name4]);
|
|
249
|
+
if (cache[_name4]) {
|
|
198
250
|
return {
|
|
199
251
|
v: true
|
|
200
252
|
};
|
|
@@ -202,8 +254,8 @@ function shouldNotify(prev, next, cache, scope) {
|
|
|
202
254
|
}
|
|
203
255
|
},
|
|
204
256
|
_ret;
|
|
205
|
-
for (var
|
|
206
|
-
_ret = _loop(
|
|
257
|
+
for (var _name4 of list) {
|
|
258
|
+
_ret = _loop(_name4);
|
|
207
259
|
if (_ret) return _ret.v;
|
|
208
260
|
}
|
|
209
261
|
}
|
|
@@ -268,19 +320,6 @@ function createFormContext(options) {
|
|
|
268
320
|
var next = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
269
321
|
return prev !== next;
|
|
270
322
|
}
|
|
271
|
-
function getStateInput(form) {
|
|
272
|
-
var element = form.elements.namedItem(submission.STATE);
|
|
273
|
-
util.invariant(element === null || dom.isFieldElement(element), "The input name \"".concat(submission.STATE, "\" is reserved by Conform. Please use another name."));
|
|
274
|
-
if (!element) {
|
|
275
|
-
var input = document.createElement('input');
|
|
276
|
-
input.type = 'hidden';
|
|
277
|
-
input.name = submission.STATE;
|
|
278
|
-
input.value = '';
|
|
279
|
-
form.append(input);
|
|
280
|
-
return input;
|
|
281
|
-
}
|
|
282
|
-
return element;
|
|
283
|
-
}
|
|
284
323
|
function getSerializedState() {
|
|
285
324
|
return JSON.stringify({
|
|
286
325
|
validated: meta.validated
|
|
@@ -290,10 +329,6 @@ function createFormContext(options) {
|
|
|
290
329
|
var form = event.target;
|
|
291
330
|
var submitter = event.submitter;
|
|
292
331
|
util.invariant(form === getFormElement(), "The submit event is dispatched by form#".concat(form.id, " instead of form#").concat(latestOptions.formId));
|
|
293
|
-
var input = getStateInput(form);
|
|
294
|
-
|
|
295
|
-
// To ensure it capturing latest state before parsing
|
|
296
|
-
input.value = getSerializedState();
|
|
297
332
|
var formData = formdata.getFormData(form, submitter);
|
|
298
333
|
var result = {
|
|
299
334
|
formData,
|
|
@@ -372,14 +407,14 @@ function createFormContext(options) {
|
|
|
372
407
|
updateFormMeta(createFormMeta(latestOptions, true));
|
|
373
408
|
}
|
|
374
409
|
function report(result) {
|
|
375
|
-
var _result$error, _result$state
|
|
410
|
+
var _result$error, _result$state;
|
|
376
411
|
var formElement = getFormElement();
|
|
377
412
|
if (!result.initialValue) {
|
|
378
413
|
formElement === null || formElement === void 0 || formElement.reset();
|
|
379
414
|
return;
|
|
380
415
|
}
|
|
381
|
-
var error = Object.entries((_result$error = result.error) !== null && _result$error !== void 0 ? _result$error : {}).reduce((result,
|
|
382
|
-
var [name, newError] =
|
|
416
|
+
var error = Object.entries((_result$error = result.error) !== null && _result$error !== void 0 ? _result$error : {}).reduce((result, _ref5) => {
|
|
417
|
+
var [name, newError] = _ref5;
|
|
383
418
|
var error = newError === null ? meta.error[name] : newError;
|
|
384
419
|
if (error) {
|
|
385
420
|
result[name] = error;
|
|
@@ -389,16 +424,14 @@ function createFormContext(options) {
|
|
|
389
424
|
var update = _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, meta), {}, {
|
|
390
425
|
submissionStatus: result.status,
|
|
391
426
|
value: result.initialValue,
|
|
392
|
-
|
|
393
|
-
|
|
427
|
+
validated: _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, meta.validated), (_result$state = result.state) === null || _result$state === void 0 ? void 0 : _result$state.validated),
|
|
428
|
+
error
|
|
394
429
|
});
|
|
395
|
-
|
|
396
|
-
handleIntent(update, result.intent, true);
|
|
397
|
-
}
|
|
430
|
+
handleIntent(update, result.intent, result.fields, true);
|
|
398
431
|
updateFormMeta(update);
|
|
399
432
|
if (formElement && result.status === 'error') {
|
|
400
433
|
for (var element of formElement.elements) {
|
|
401
|
-
if (dom.isFieldElement(element) && error[element.name]) {
|
|
434
|
+
if (dom.isFieldElement(element) && meta.error[element.name]) {
|
|
402
435
|
element.focus();
|
|
403
436
|
break;
|
|
404
437
|
}
|
package/form.mjs
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import { objectSpread2 as _objectSpread2 } from './_virtual/_rollupPluginBabelHelpers.mjs';
|
|
2
|
-
import { flatten, formatPaths, getPaths, getValue,
|
|
2
|
+
import { flatten, formatPaths, getPaths, getValue, isPlainObject, setValue, normalize, getFormData, isPrefix } from './formdata.mjs';
|
|
3
3
|
import { getFormAction, getFormEncType, getFormMethod, isFieldElement, requestSubmit } from './dom.mjs';
|
|
4
4
|
import { generateId, clone, invariant } from './util.mjs';
|
|
5
|
-
import { serialize, setListState, setListValue, setState, getSubmissionContext, INTENT, serializeIntent
|
|
5
|
+
import { serialize, setListState, setListValue, setState, getSubmissionContext, INTENT, serializeIntent } from './submission.mjs';
|
|
6
6
|
|
|
7
7
|
function createFormMeta(options, initialized) {
|
|
8
8
|
var _lastResult$initialVa, _options$constraint, _lastResult$state$val, _lastResult$state, _ref;
|
|
9
9
|
var lastResult = !initialized ? options.lastResult : undefined;
|
|
10
|
-
var defaultValue = options.defaultValue ?
|
|
11
|
-
// @ts-expect-error
|
|
12
|
-
serialize(options.defaultValue) : {};
|
|
10
|
+
var defaultValue = options.defaultValue ? serialize(options.defaultValue) : {};
|
|
13
11
|
var initialValue = (_lastResult$initialVa = lastResult === null || lastResult === void 0 ? void 0 : lastResult.initialValue) !== null && _lastResult$initialVa !== void 0 ? _lastResult$initialVa : defaultValue;
|
|
14
12
|
var result = {
|
|
15
13
|
submissionStatus: lastResult === null || lastResult === void 0 ? void 0 : lastResult.status,
|
|
@@ -25,9 +23,7 @@ function createFormMeta(options, initialized) {
|
|
|
25
23
|
// We can consider adding a warning if it happens
|
|
26
24
|
error: (_ref = lastResult === null || lastResult === void 0 ? void 0 : lastResult.error) !== null && _ref !== void 0 ? _ref : {}
|
|
27
25
|
};
|
|
28
|
-
|
|
29
|
-
handleIntent(result, lastResult.intent);
|
|
30
|
-
}
|
|
26
|
+
handleIntent(result, lastResult === null || lastResult === void 0 ? void 0 : lastResult.intent, lastResult === null || lastResult === void 0 ? void 0 : lastResult.fields);
|
|
31
27
|
return result;
|
|
32
28
|
}
|
|
33
29
|
function getDefaultKey(defaultValue, prefix) {
|
|
@@ -43,24 +39,71 @@ function getDefaultKey(defaultValue, prefix) {
|
|
|
43
39
|
return result;
|
|
44
40
|
}, {});
|
|
45
41
|
}
|
|
46
|
-
function
|
|
42
|
+
function setFieldsValidated(meta, fields) {
|
|
43
|
+
for (var _name of Object.keys(meta.error).concat(fields !== null && fields !== void 0 ? fields : [])) {
|
|
44
|
+
meta.validated[_name] = true;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function handleIntent(meta, intent, fields, initialized) {
|
|
48
|
+
if (!intent) {
|
|
49
|
+
setFieldsValidated(meta, fields);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
47
52
|
switch (intent.type) {
|
|
53
|
+
case 'validate':
|
|
54
|
+
{
|
|
55
|
+
if (intent.payload.name) {
|
|
56
|
+
meta.validated[intent.payload.name] = true;
|
|
57
|
+
} else {
|
|
58
|
+
setFieldsValidated(meta, fields);
|
|
59
|
+
}
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
48
62
|
case 'update':
|
|
49
63
|
{
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
64
|
+
var {
|
|
65
|
+
name: _name2,
|
|
66
|
+
validated,
|
|
67
|
+
value
|
|
68
|
+
} = intent.payload;
|
|
69
|
+
if (typeof value !== 'undefined') {
|
|
70
|
+
updateValue(meta, _name2 !== null && _name2 !== void 0 ? _name2 : '', serialize(value));
|
|
71
|
+
}
|
|
72
|
+
if (typeof validated !== 'undefined') {
|
|
73
|
+
// Clean up previous validated state
|
|
74
|
+
if (_name2) {
|
|
75
|
+
setState(meta.validated, _name2, () => undefined);
|
|
76
|
+
} else {
|
|
77
|
+
meta.validated = {};
|
|
78
|
+
}
|
|
79
|
+
if (validated) {
|
|
80
|
+
if (isPlainObject(value) || Array.isArray(value)) {
|
|
81
|
+
Object.assign(meta.validated, flatten(value, {
|
|
82
|
+
resolve() {
|
|
83
|
+
return true;
|
|
84
|
+
},
|
|
85
|
+
prefix: _name2
|
|
86
|
+
}));
|
|
87
|
+
}
|
|
88
|
+
meta.validated[_name2 !== null && _name2 !== void 0 ? _name2 : ''] = true;
|
|
89
|
+
} else if (_name2) {
|
|
90
|
+
delete meta.validated[_name2];
|
|
91
|
+
}
|
|
55
92
|
}
|
|
56
93
|
break;
|
|
57
94
|
}
|
|
58
95
|
case 'reset':
|
|
59
96
|
{
|
|
60
|
-
var _intent$payload$
|
|
61
|
-
var
|
|
62
|
-
var _value = getValue(meta.defaultValue,
|
|
63
|
-
updateValue(meta,
|
|
97
|
+
var _intent$payload$name;
|
|
98
|
+
var _name3 = (_intent$payload$name = intent.payload.name) !== null && _intent$payload$name !== void 0 ? _intent$payload$name : '';
|
|
99
|
+
var _value = getValue(meta.defaultValue, _name3);
|
|
100
|
+
updateValue(meta, _name3, _value);
|
|
101
|
+
if (_name3) {
|
|
102
|
+
setState(meta.validated, _name3, () => undefined);
|
|
103
|
+
delete meta.validated[_name3];
|
|
104
|
+
} else {
|
|
105
|
+
meta.validated = {};
|
|
106
|
+
}
|
|
64
107
|
break;
|
|
65
108
|
}
|
|
66
109
|
case 'insert':
|
|
@@ -73,9 +116,18 @@ function handleIntent(meta, intent, initialized) {
|
|
|
73
116
|
setListState(meta.key, intent, generateId);
|
|
74
117
|
setListValue(meta.initialValue, intent);
|
|
75
118
|
}
|
|
119
|
+
setListState(meta.validated, intent);
|
|
120
|
+
meta.validated[intent.payload.name] = true;
|
|
76
121
|
break;
|
|
77
122
|
}
|
|
78
123
|
}
|
|
124
|
+
meta.error = Object.entries(meta.error).reduce((result, _ref3) => {
|
|
125
|
+
var [name, error] = _ref3;
|
|
126
|
+
if (meta.validated[name]) {
|
|
127
|
+
result[name] = error;
|
|
128
|
+
}
|
|
129
|
+
return result;
|
|
130
|
+
}, {});
|
|
79
131
|
}
|
|
80
132
|
function updateValue(meta, name, value) {
|
|
81
133
|
meta.initialValue = clone(meta.initialValue);
|
|
@@ -166,8 +218,8 @@ function createValidProxy(error) {
|
|
|
166
218
|
function createDirtyProxy(defaultValue, value, shouldDirtyConsider) {
|
|
167
219
|
return createStateProxy(name => JSON.stringify(defaultValue[name]) !== JSON.stringify(value[name], (key, value) => {
|
|
168
220
|
if (name === '' && key === '' && value) {
|
|
169
|
-
return Object.entries(value).reduce((result,
|
|
170
|
-
var [name, value] =
|
|
221
|
+
return Object.entries(value).reduce((result, _ref4) => {
|
|
222
|
+
var [name, value] = _ref4;
|
|
171
223
|
if (!shouldDirtyConsider(name)) {
|
|
172
224
|
return result;
|
|
173
225
|
}
|
|
@@ -186,11 +238,11 @@ function shouldNotify(prev, next, cache, scope) {
|
|
|
186
238
|
var prefixes = (_scope$prefix = scope.prefix) !== null && _scope$prefix !== void 0 ? _scope$prefix : [];
|
|
187
239
|
var names = (_scope$name = scope.name) !== null && _scope$name !== void 0 ? _scope$name : [];
|
|
188
240
|
var list = prefixes.length === 0 ? names : Array.from(new Set([...Object.keys(prev), ...Object.keys(next)]));
|
|
189
|
-
var _loop = function _loop(
|
|
190
|
-
if (prefixes.length === 0 || names.includes(
|
|
241
|
+
var _loop = function _loop(_name4) {
|
|
242
|
+
if (prefixes.length === 0 || names.includes(_name4) || prefixes.some(prefix => isPrefix(_name4, prefix))) {
|
|
191
243
|
var _cache$_name;
|
|
192
|
-
(_cache$_name = cache[
|
|
193
|
-
if (cache[
|
|
244
|
+
(_cache$_name = cache[_name4]) !== null && _cache$_name !== void 0 ? _cache$_name : cache[_name4] = compareFn(prev[_name4], next[_name4]);
|
|
245
|
+
if (cache[_name4]) {
|
|
194
246
|
return {
|
|
195
247
|
v: true
|
|
196
248
|
};
|
|
@@ -198,8 +250,8 @@ function shouldNotify(prev, next, cache, scope) {
|
|
|
198
250
|
}
|
|
199
251
|
},
|
|
200
252
|
_ret;
|
|
201
|
-
for (var
|
|
202
|
-
_ret = _loop(
|
|
253
|
+
for (var _name4 of list) {
|
|
254
|
+
_ret = _loop(_name4);
|
|
203
255
|
if (_ret) return _ret.v;
|
|
204
256
|
}
|
|
205
257
|
}
|
|
@@ -264,19 +316,6 @@ function createFormContext(options) {
|
|
|
264
316
|
var next = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
265
317
|
return prev !== next;
|
|
266
318
|
}
|
|
267
|
-
function getStateInput(form) {
|
|
268
|
-
var element = form.elements.namedItem(STATE);
|
|
269
|
-
invariant(element === null || isFieldElement(element), "The input name \"".concat(STATE, "\" is reserved by Conform. Please use another name."));
|
|
270
|
-
if (!element) {
|
|
271
|
-
var input = document.createElement('input');
|
|
272
|
-
input.type = 'hidden';
|
|
273
|
-
input.name = STATE;
|
|
274
|
-
input.value = '';
|
|
275
|
-
form.append(input);
|
|
276
|
-
return input;
|
|
277
|
-
}
|
|
278
|
-
return element;
|
|
279
|
-
}
|
|
280
319
|
function getSerializedState() {
|
|
281
320
|
return JSON.stringify({
|
|
282
321
|
validated: meta.validated
|
|
@@ -286,10 +325,6 @@ function createFormContext(options) {
|
|
|
286
325
|
var form = event.target;
|
|
287
326
|
var submitter = event.submitter;
|
|
288
327
|
invariant(form === getFormElement(), "The submit event is dispatched by form#".concat(form.id, " instead of form#").concat(latestOptions.formId));
|
|
289
|
-
var input = getStateInput(form);
|
|
290
|
-
|
|
291
|
-
// To ensure it capturing latest state before parsing
|
|
292
|
-
input.value = getSerializedState();
|
|
293
328
|
var formData = getFormData(form, submitter);
|
|
294
329
|
var result = {
|
|
295
330
|
formData,
|
|
@@ -368,14 +403,14 @@ function createFormContext(options) {
|
|
|
368
403
|
updateFormMeta(createFormMeta(latestOptions, true));
|
|
369
404
|
}
|
|
370
405
|
function report(result) {
|
|
371
|
-
var _result$error, _result$state
|
|
406
|
+
var _result$error, _result$state;
|
|
372
407
|
var formElement = getFormElement();
|
|
373
408
|
if (!result.initialValue) {
|
|
374
409
|
formElement === null || formElement === void 0 || formElement.reset();
|
|
375
410
|
return;
|
|
376
411
|
}
|
|
377
|
-
var error = Object.entries((_result$error = result.error) !== null && _result$error !== void 0 ? _result$error : {}).reduce((result,
|
|
378
|
-
var [name, newError] =
|
|
412
|
+
var error = Object.entries((_result$error = result.error) !== null && _result$error !== void 0 ? _result$error : {}).reduce((result, _ref5) => {
|
|
413
|
+
var [name, newError] = _ref5;
|
|
379
414
|
var error = newError === null ? meta.error[name] : newError;
|
|
380
415
|
if (error) {
|
|
381
416
|
result[name] = error;
|
|
@@ -385,16 +420,14 @@ function createFormContext(options) {
|
|
|
385
420
|
var update = _objectSpread2(_objectSpread2({}, meta), {}, {
|
|
386
421
|
submissionStatus: result.status,
|
|
387
422
|
value: result.initialValue,
|
|
388
|
-
|
|
389
|
-
|
|
423
|
+
validated: _objectSpread2(_objectSpread2({}, meta.validated), (_result$state = result.state) === null || _result$state === void 0 ? void 0 : _result$state.validated),
|
|
424
|
+
error
|
|
390
425
|
});
|
|
391
|
-
|
|
392
|
-
handleIntent(update, result.intent, true);
|
|
393
|
-
}
|
|
426
|
+
handleIntent(update, result.intent, result.fields, true);
|
|
394
427
|
updateFormMeta(update);
|
|
395
428
|
if (formElement && result.status === 'error') {
|
|
396
429
|
for (var element of formElement.elements) {
|
|
397
|
-
if (isFieldElement(element) && error[element.name]) {
|
|
430
|
+
if (isFieldElement(element) && meta.error[element.name]) {
|
|
398
431
|
element.focus();
|
|
399
432
|
break;
|
|
400
433
|
}
|
package/formdata.d.ts
CHANGED
|
@@ -45,9 +45,9 @@ export declare function isFile(obj: unknown): obj is File;
|
|
|
45
45
|
/**
|
|
46
46
|
* Normalize value by removing empty object or array, empty string and null values
|
|
47
47
|
*/
|
|
48
|
-
export declare function normalize<Type extends Record<string, unknown>>(value: Type
|
|
49
|
-
export declare function normalize<Type extends Array<unknown>>(value: Type
|
|
50
|
-
export declare function normalize(value: unknown): unknown | undefined;
|
|
48
|
+
export declare function normalize<Type extends Record<string, unknown>>(value: Type, acceptFile?: boolean): Type | undefined;
|
|
49
|
+
export declare function normalize<Type extends Array<unknown>>(value: Type, acceptFile?: boolean): Type | undefined;
|
|
50
|
+
export declare function normalize(value: unknown, acceptFile?: boolean): unknown | undefined;
|
|
51
51
|
/**
|
|
52
52
|
* Flatten a tree into a dictionary
|
|
53
53
|
*/
|
package/formdata.js
CHANGED
|
@@ -136,9 +136,10 @@ function isFile(obj) {
|
|
|
136
136
|
*/
|
|
137
137
|
|
|
138
138
|
function normalize(value) {
|
|
139
|
+
var acceptFile = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
139
140
|
if (isPlainObject(value)) {
|
|
140
141
|
var obj = Object.keys(value).sort().reduce((result, key) => {
|
|
141
|
-
var data = normalize(value[key]);
|
|
142
|
+
var data = normalize(value[key], acceptFile);
|
|
142
143
|
if (typeof data !== 'undefined') {
|
|
143
144
|
result[key] = data;
|
|
144
145
|
}
|
|
@@ -153,20 +154,11 @@ function normalize(value) {
|
|
|
153
154
|
if (value.length === 0) {
|
|
154
155
|
return undefined;
|
|
155
156
|
}
|
|
156
|
-
return value.map(normalize);
|
|
157
|
+
return value.map(item => normalize(item, acceptFile));
|
|
157
158
|
}
|
|
158
|
-
if (typeof value === 'string' && value === '' || value === null || isFile(value) && value.size === 0) {
|
|
159
|
+
if (typeof value === 'string' && value === '' || value === null || isFile(value) && (!acceptFile || value.size === 0)) {
|
|
159
160
|
return;
|
|
160
161
|
}
|
|
161
|
-
|
|
162
|
-
// We will skip serializing file if the result is sent to the client
|
|
163
|
-
if (isFile(value)) {
|
|
164
|
-
return Object.assign(value, {
|
|
165
|
-
toJSON() {
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
162
|
return value;
|
|
171
163
|
}
|
|
172
164
|
|
package/formdata.mjs
CHANGED
|
@@ -132,9 +132,10 @@ function isFile(obj) {
|
|
|
132
132
|
*/
|
|
133
133
|
|
|
134
134
|
function normalize(value) {
|
|
135
|
+
var acceptFile = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
135
136
|
if (isPlainObject(value)) {
|
|
136
137
|
var obj = Object.keys(value).sort().reduce((result, key) => {
|
|
137
|
-
var data = normalize(value[key]);
|
|
138
|
+
var data = normalize(value[key], acceptFile);
|
|
138
139
|
if (typeof data !== 'undefined') {
|
|
139
140
|
result[key] = data;
|
|
140
141
|
}
|
|
@@ -149,20 +150,11 @@ function normalize(value) {
|
|
|
149
150
|
if (value.length === 0) {
|
|
150
151
|
return undefined;
|
|
151
152
|
}
|
|
152
|
-
return value.map(normalize);
|
|
153
|
+
return value.map(item => normalize(item, acceptFile));
|
|
153
154
|
}
|
|
154
|
-
if (typeof value === 'string' && value === '' || value === null || isFile(value) && value.size === 0) {
|
|
155
|
+
if (typeof value === 'string' && value === '' || value === null || isFile(value) && (!acceptFile || value.size === 0)) {
|
|
155
156
|
return;
|
|
156
157
|
}
|
|
157
|
-
|
|
158
|
-
// We will skip serializing file if the result is sent to the client
|
|
159
|
-
if (isFile(value)) {
|
|
160
|
-
return Object.assign(value, {
|
|
161
|
-
toJSON() {
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
158
|
return value;
|
|
167
159
|
}
|
|
168
160
|
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "A set of opinionated helpers built on top of the Constraint Validation API",
|
|
4
4
|
"homepage": "https://conform.guide",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"version": "1.0.
|
|
6
|
+
"version": "1.0.4",
|
|
7
7
|
"main": "index.js",
|
|
8
8
|
"module": "index.mjs",
|
|
9
9
|
"types": "index.d.ts",
|
package/submission.d.ts
CHANGED
|
@@ -5,10 +5,10 @@ export type SubmissionState = {
|
|
|
5
5
|
export type SubmissionContext<Value = null, FormError = string[]> = {
|
|
6
6
|
intent: Intent | null;
|
|
7
7
|
payload: Record<string, unknown>;
|
|
8
|
-
fields: string
|
|
8
|
+
fields: Set<string>;
|
|
9
9
|
value?: Value;
|
|
10
10
|
error?: Record<string, FormError | null> | null;
|
|
11
|
-
state
|
|
11
|
+
state?: SubmissionState;
|
|
12
12
|
};
|
|
13
13
|
export type Submission<Schema, FormError = string[], FormValue = Schema> = {
|
|
14
14
|
status: 'success';
|
|
@@ -25,6 +25,7 @@ export type SubmissionResult<FormError = string[]> = {
|
|
|
25
25
|
status?: 'error' | 'success';
|
|
26
26
|
intent?: Intent;
|
|
27
27
|
initialValue?: Record<string, unknown> | null;
|
|
28
|
+
fields?: string[];
|
|
28
29
|
error?: Record<string, FormError | null>;
|
|
29
30
|
state?: SubmissionState;
|
|
30
31
|
};
|
package/submission.js
CHANGED
|
@@ -18,15 +18,21 @@ var STATE = '__state__';
|
|
|
18
18
|
function getSubmissionContext(body) {
|
|
19
19
|
var intent = body.get(INTENT);
|
|
20
20
|
var state = body.get(STATE);
|
|
21
|
-
var payload = {};
|
|
22
|
-
var fields = [];
|
|
23
21
|
util.invariant((typeof intent === 'string' || intent === null) && (typeof state === 'string' || state === null), "The input name \"".concat(INTENT, "\" and \"").concat(STATE, "\" are reserved by Conform. Please use another name for your input."));
|
|
22
|
+
var context = {
|
|
23
|
+
payload: {},
|
|
24
|
+
fields: new Set(),
|
|
25
|
+
intent: getIntent(intent)
|
|
26
|
+
};
|
|
27
|
+
if (state) {
|
|
28
|
+
context.state = JSON.parse(state);
|
|
29
|
+
}
|
|
24
30
|
var _loop = function _loop(next) {
|
|
25
31
|
if (name === INTENT || name === STATE) {
|
|
26
32
|
return 1; // continue
|
|
27
33
|
}
|
|
28
|
-
fields.
|
|
29
|
-
formdata.setValue(payload, name, prev => {
|
|
34
|
+
context.fields.add(name);
|
|
35
|
+
formdata.setValue(context.payload, name, prev => {
|
|
30
36
|
if (!prev) {
|
|
31
37
|
return next;
|
|
32
38
|
} else if (Array.isArray(prev)) {
|
|
@@ -39,30 +45,17 @@ function getSubmissionContext(body) {
|
|
|
39
45
|
for (var [name, next] of body.entries()) {
|
|
40
46
|
if (_loop(next)) continue;
|
|
41
47
|
}
|
|
42
|
-
return
|
|
43
|
-
payload,
|
|
44
|
-
intent: getIntent(intent),
|
|
45
|
-
state: state ? JSON.parse(state) : {
|
|
46
|
-
validated: {}
|
|
47
|
-
},
|
|
48
|
-
fields
|
|
49
|
-
};
|
|
48
|
+
return context;
|
|
50
49
|
}
|
|
51
50
|
function parse(payload, options) {
|
|
52
51
|
var context = getSubmissionContext(payload);
|
|
53
52
|
var intent = context.intent;
|
|
54
53
|
if (intent) {
|
|
55
54
|
switch (intent.type) {
|
|
56
|
-
case 'validate':
|
|
57
|
-
if (intent.payload.name) {
|
|
58
|
-
context.state.validated[intent.payload.name] = true;
|
|
59
|
-
}
|
|
60
|
-
break;
|
|
61
55
|
case 'update':
|
|
62
56
|
{
|
|
63
57
|
var {
|
|
64
|
-
name
|
|
65
|
-
validated
|
|
58
|
+
name
|
|
66
59
|
} = intent.payload;
|
|
67
60
|
var _value = serialize(intent.payload.value);
|
|
68
61
|
if (typeof _value !== 'undefined') {
|
|
@@ -73,27 +66,6 @@ function parse(payload, options) {
|
|
|
73
66
|
context.payload = _value;
|
|
74
67
|
}
|
|
75
68
|
}
|
|
76
|
-
if (typeof validated !== 'undefined') {
|
|
77
|
-
// Clean up previous validated state
|
|
78
|
-
if (name) {
|
|
79
|
-
setState(context.state.validated, name, () => undefined);
|
|
80
|
-
} else {
|
|
81
|
-
context.state.validated = {};
|
|
82
|
-
}
|
|
83
|
-
if (validated) {
|
|
84
|
-
if (formdata.isPlainObject(_value) || Array.isArray(_value)) {
|
|
85
|
-
Object.assign(context.state.validated, formdata.flatten(_value, {
|
|
86
|
-
resolve() {
|
|
87
|
-
return true;
|
|
88
|
-
},
|
|
89
|
-
prefix: name
|
|
90
|
-
}));
|
|
91
|
-
}
|
|
92
|
-
context.state.validated[name !== null && name !== void 0 ? name : ''] = true;
|
|
93
|
-
} else if (name) {
|
|
94
|
-
delete context.state.validated[name];
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
69
|
break;
|
|
98
70
|
}
|
|
99
71
|
case 'reset':
|
|
@@ -103,11 +75,8 @@ function parse(payload, options) {
|
|
|
103
75
|
} = intent.payload;
|
|
104
76
|
if (_name) {
|
|
105
77
|
formdata.setValue(context.payload, _name, () => undefined);
|
|
106
|
-
setState(context.state.validated, _name, () => undefined);
|
|
107
|
-
delete context.state.validated[_name];
|
|
108
78
|
} else {
|
|
109
79
|
context.payload = {};
|
|
110
|
-
context.state.validated = {};
|
|
111
80
|
}
|
|
112
81
|
break;
|
|
113
82
|
}
|
|
@@ -116,25 +85,15 @@ function parse(payload, options) {
|
|
|
116
85
|
case 'reorder':
|
|
117
86
|
{
|
|
118
87
|
setListValue(context.payload, intent);
|
|
119
|
-
setListState(context.state.validated, intent);
|
|
120
|
-
context.state.validated[intent.payload.name] = true;
|
|
121
88
|
break;
|
|
122
89
|
}
|
|
123
90
|
}
|
|
124
91
|
}
|
|
125
92
|
var result = options.resolve(context.payload, intent);
|
|
126
|
-
var mergeResolveResult = resolved => {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
context.state.validated[_name2] = true;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
return createSubmission(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, context), {}, {
|
|
134
|
-
value: resolved.value,
|
|
135
|
-
error: resolved.error
|
|
136
|
-
}));
|
|
137
|
-
};
|
|
93
|
+
var mergeResolveResult = resolved => createSubmission(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, context), {}, {
|
|
94
|
+
value: resolved.value,
|
|
95
|
+
error: resolved.error
|
|
96
|
+
}));
|
|
138
97
|
if (result instanceof Promise) {
|
|
139
98
|
return result.then(mergeResolveResult);
|
|
140
99
|
}
|
|
@@ -161,50 +120,34 @@ function createSubmission(context) {
|
|
|
161
120
|
};
|
|
162
121
|
}
|
|
163
122
|
function replySubmission(context) {
|
|
164
|
-
var _context$intent, _options$formErrors, _normalize;
|
|
123
|
+
var _context$intent, _context$intent$paylo, _options$formErrors, _normalize;
|
|
165
124
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
166
|
-
|
|
167
|
-
case 'reset':
|
|
168
|
-
{
|
|
169
|
-
var _context$intent$paylo;
|
|
170
|
-
var name = (_context$intent$paylo = context.intent.payload.name) !== null && _context$intent$paylo !== void 0 ? _context$intent$paylo : '';
|
|
171
|
-
if (name === '') {
|
|
172
|
-
return {
|
|
173
|
-
initialValue: null
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
if ('resetForm' in options && options.resetForm) {
|
|
125
|
+
if ('resetForm' in options && options.resetForm || ((_context$intent = context.intent) === null || _context$intent === void 0 ? void 0 : _context$intent.type) === 'reset' && ((_context$intent$paylo = context.intent.payload.name) !== null && _context$intent$paylo !== void 0 ? _context$intent$paylo : '') === '') {
|
|
179
126
|
return {
|
|
180
127
|
initialValue: null
|
|
181
128
|
};
|
|
182
129
|
}
|
|
183
130
|
if ('hideFields' in options && options.hideFields) {
|
|
184
|
-
for (var
|
|
185
|
-
var _value2 = formdata.getValue(context.payload,
|
|
131
|
+
for (var name of options.hideFields) {
|
|
132
|
+
var _value2 = formdata.getValue(context.payload, name);
|
|
186
133
|
if (typeof _value2 !== 'undefined') {
|
|
187
|
-
formdata.setValue(context.payload,
|
|
134
|
+
formdata.setValue(context.payload, name, () => undefined);
|
|
188
135
|
}
|
|
189
136
|
}
|
|
190
137
|
}
|
|
191
|
-
var submissionError = context.error ? Object.entries(context.error).reduce((result, _ref) => {
|
|
192
|
-
var [name, error] = _ref;
|
|
193
|
-
if (context.state.validated[name]) {
|
|
194
|
-
result[name] = error;
|
|
195
|
-
}
|
|
196
|
-
return result;
|
|
197
|
-
}, {}) : undefined;
|
|
198
138
|
var extraError = 'formErrors' in options || 'fieldErrors' in options ? formdata.normalize(_rollupPluginBabelHelpers.objectSpread2({
|
|
199
139
|
'': (_options$formErrors = options.formErrors) !== null && _options$formErrors !== void 0 ? _options$formErrors : null
|
|
200
140
|
}, options.fieldErrors)) : null;
|
|
201
|
-
var error =
|
|
141
|
+
var error = context.error || extraError ? _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, context.error), extraError) : undefined;
|
|
202
142
|
return {
|
|
203
143
|
status: context.intent ? undefined : error ? 'error' : 'success',
|
|
204
144
|
intent: context.intent ? context.intent : undefined,
|
|
205
|
-
initialValue: (_normalize = formdata.normalize(context.payload
|
|
145
|
+
initialValue: (_normalize = formdata.normalize(context.payload,
|
|
146
|
+
// We can't serialize the file and send it back from the server, but we can preserve it in the client
|
|
147
|
+
typeof document !== 'undefined')) !== null && _normalize !== void 0 ? _normalize : {},
|
|
206
148
|
error,
|
|
207
|
-
state: context.state
|
|
149
|
+
state: context.state,
|
|
150
|
+
fields: Array.from(context.fields)
|
|
208
151
|
};
|
|
209
152
|
}
|
|
210
153
|
function getIntent(serializedIntent) {
|
|
@@ -310,8 +253,8 @@ function setListState(state, intent, getDefaultValue) {
|
|
|
310
253
|
function serialize(defaultValue) {
|
|
311
254
|
if (formdata.isPlainObject(defaultValue)) {
|
|
312
255
|
// @ts-expect-error FIXME
|
|
313
|
-
return Object.entries(defaultValue).reduce((result,
|
|
314
|
-
var [key, value] =
|
|
256
|
+
return Object.entries(defaultValue).reduce((result, _ref) => {
|
|
257
|
+
var [key, value] = _ref;
|
|
315
258
|
// @ts-ignore-error FIXME
|
|
316
259
|
result[key] = serialize(value);
|
|
317
260
|
return result;
|
package/submission.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { objectSpread2 as _objectSpread2 } from './_virtual/_rollupPluginBabelHelpers.mjs';
|
|
2
|
-
import { setValue, isPlainObject,
|
|
2
|
+
import { setValue, isPlainObject, getValue, normalize, flatten, isPrefix } from './formdata.mjs';
|
|
3
3
|
import { invariant } from './util.mjs';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -14,15 +14,21 @@ var STATE = '__state__';
|
|
|
14
14
|
function getSubmissionContext(body) {
|
|
15
15
|
var intent = body.get(INTENT);
|
|
16
16
|
var state = body.get(STATE);
|
|
17
|
-
var payload = {};
|
|
18
|
-
var fields = [];
|
|
19
17
|
invariant((typeof intent === 'string' || intent === null) && (typeof state === 'string' || state === null), "The input name \"".concat(INTENT, "\" and \"").concat(STATE, "\" are reserved by Conform. Please use another name for your input."));
|
|
18
|
+
var context = {
|
|
19
|
+
payload: {},
|
|
20
|
+
fields: new Set(),
|
|
21
|
+
intent: getIntent(intent)
|
|
22
|
+
};
|
|
23
|
+
if (state) {
|
|
24
|
+
context.state = JSON.parse(state);
|
|
25
|
+
}
|
|
20
26
|
var _loop = function _loop(next) {
|
|
21
27
|
if (name === INTENT || name === STATE) {
|
|
22
28
|
return 1; // continue
|
|
23
29
|
}
|
|
24
|
-
fields.
|
|
25
|
-
setValue(payload, name, prev => {
|
|
30
|
+
context.fields.add(name);
|
|
31
|
+
setValue(context.payload, name, prev => {
|
|
26
32
|
if (!prev) {
|
|
27
33
|
return next;
|
|
28
34
|
} else if (Array.isArray(prev)) {
|
|
@@ -35,30 +41,17 @@ function getSubmissionContext(body) {
|
|
|
35
41
|
for (var [name, next] of body.entries()) {
|
|
36
42
|
if (_loop(next)) continue;
|
|
37
43
|
}
|
|
38
|
-
return
|
|
39
|
-
payload,
|
|
40
|
-
intent: getIntent(intent),
|
|
41
|
-
state: state ? JSON.parse(state) : {
|
|
42
|
-
validated: {}
|
|
43
|
-
},
|
|
44
|
-
fields
|
|
45
|
-
};
|
|
44
|
+
return context;
|
|
46
45
|
}
|
|
47
46
|
function parse(payload, options) {
|
|
48
47
|
var context = getSubmissionContext(payload);
|
|
49
48
|
var intent = context.intent;
|
|
50
49
|
if (intent) {
|
|
51
50
|
switch (intent.type) {
|
|
52
|
-
case 'validate':
|
|
53
|
-
if (intent.payload.name) {
|
|
54
|
-
context.state.validated[intent.payload.name] = true;
|
|
55
|
-
}
|
|
56
|
-
break;
|
|
57
51
|
case 'update':
|
|
58
52
|
{
|
|
59
53
|
var {
|
|
60
|
-
name
|
|
61
|
-
validated
|
|
54
|
+
name
|
|
62
55
|
} = intent.payload;
|
|
63
56
|
var _value = serialize(intent.payload.value);
|
|
64
57
|
if (typeof _value !== 'undefined') {
|
|
@@ -69,27 +62,6 @@ function parse(payload, options) {
|
|
|
69
62
|
context.payload = _value;
|
|
70
63
|
}
|
|
71
64
|
}
|
|
72
|
-
if (typeof validated !== 'undefined') {
|
|
73
|
-
// Clean up previous validated state
|
|
74
|
-
if (name) {
|
|
75
|
-
setState(context.state.validated, name, () => undefined);
|
|
76
|
-
} else {
|
|
77
|
-
context.state.validated = {};
|
|
78
|
-
}
|
|
79
|
-
if (validated) {
|
|
80
|
-
if (isPlainObject(_value) || Array.isArray(_value)) {
|
|
81
|
-
Object.assign(context.state.validated, flatten(_value, {
|
|
82
|
-
resolve() {
|
|
83
|
-
return true;
|
|
84
|
-
},
|
|
85
|
-
prefix: name
|
|
86
|
-
}));
|
|
87
|
-
}
|
|
88
|
-
context.state.validated[name !== null && name !== void 0 ? name : ''] = true;
|
|
89
|
-
} else if (name) {
|
|
90
|
-
delete context.state.validated[name];
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
65
|
break;
|
|
94
66
|
}
|
|
95
67
|
case 'reset':
|
|
@@ -99,11 +71,8 @@ function parse(payload, options) {
|
|
|
99
71
|
} = intent.payload;
|
|
100
72
|
if (_name) {
|
|
101
73
|
setValue(context.payload, _name, () => undefined);
|
|
102
|
-
setState(context.state.validated, _name, () => undefined);
|
|
103
|
-
delete context.state.validated[_name];
|
|
104
74
|
} else {
|
|
105
75
|
context.payload = {};
|
|
106
|
-
context.state.validated = {};
|
|
107
76
|
}
|
|
108
77
|
break;
|
|
109
78
|
}
|
|
@@ -112,25 +81,15 @@ function parse(payload, options) {
|
|
|
112
81
|
case 'reorder':
|
|
113
82
|
{
|
|
114
83
|
setListValue(context.payload, intent);
|
|
115
|
-
setListState(context.state.validated, intent);
|
|
116
|
-
context.state.validated[intent.payload.name] = true;
|
|
117
84
|
break;
|
|
118
85
|
}
|
|
119
86
|
}
|
|
120
87
|
}
|
|
121
88
|
var result = options.resolve(context.payload, intent);
|
|
122
|
-
var mergeResolveResult = resolved => {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
context.state.validated[_name2] = true;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
return createSubmission(_objectSpread2(_objectSpread2({}, context), {}, {
|
|
130
|
-
value: resolved.value,
|
|
131
|
-
error: resolved.error
|
|
132
|
-
}));
|
|
133
|
-
};
|
|
89
|
+
var mergeResolveResult = resolved => createSubmission(_objectSpread2(_objectSpread2({}, context), {}, {
|
|
90
|
+
value: resolved.value,
|
|
91
|
+
error: resolved.error
|
|
92
|
+
}));
|
|
134
93
|
if (result instanceof Promise) {
|
|
135
94
|
return result.then(mergeResolveResult);
|
|
136
95
|
}
|
|
@@ -157,50 +116,34 @@ function createSubmission(context) {
|
|
|
157
116
|
};
|
|
158
117
|
}
|
|
159
118
|
function replySubmission(context) {
|
|
160
|
-
var _context$intent, _options$formErrors, _normalize;
|
|
119
|
+
var _context$intent, _context$intent$paylo, _options$formErrors, _normalize;
|
|
161
120
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
162
|
-
|
|
163
|
-
case 'reset':
|
|
164
|
-
{
|
|
165
|
-
var _context$intent$paylo;
|
|
166
|
-
var name = (_context$intent$paylo = context.intent.payload.name) !== null && _context$intent$paylo !== void 0 ? _context$intent$paylo : '';
|
|
167
|
-
if (name === '') {
|
|
168
|
-
return {
|
|
169
|
-
initialValue: null
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
if ('resetForm' in options && options.resetForm) {
|
|
121
|
+
if ('resetForm' in options && options.resetForm || ((_context$intent = context.intent) === null || _context$intent === void 0 ? void 0 : _context$intent.type) === 'reset' && ((_context$intent$paylo = context.intent.payload.name) !== null && _context$intent$paylo !== void 0 ? _context$intent$paylo : '') === '') {
|
|
175
122
|
return {
|
|
176
123
|
initialValue: null
|
|
177
124
|
};
|
|
178
125
|
}
|
|
179
126
|
if ('hideFields' in options && options.hideFields) {
|
|
180
|
-
for (var
|
|
181
|
-
var _value2 = getValue(context.payload,
|
|
127
|
+
for (var name of options.hideFields) {
|
|
128
|
+
var _value2 = getValue(context.payload, name);
|
|
182
129
|
if (typeof _value2 !== 'undefined') {
|
|
183
|
-
setValue(context.payload,
|
|
130
|
+
setValue(context.payload, name, () => undefined);
|
|
184
131
|
}
|
|
185
132
|
}
|
|
186
133
|
}
|
|
187
|
-
var submissionError = context.error ? Object.entries(context.error).reduce((result, _ref) => {
|
|
188
|
-
var [name, error] = _ref;
|
|
189
|
-
if (context.state.validated[name]) {
|
|
190
|
-
result[name] = error;
|
|
191
|
-
}
|
|
192
|
-
return result;
|
|
193
|
-
}, {}) : undefined;
|
|
194
134
|
var extraError = 'formErrors' in options || 'fieldErrors' in options ? normalize(_objectSpread2({
|
|
195
135
|
'': (_options$formErrors = options.formErrors) !== null && _options$formErrors !== void 0 ? _options$formErrors : null
|
|
196
136
|
}, options.fieldErrors)) : null;
|
|
197
|
-
var error =
|
|
137
|
+
var error = context.error || extraError ? _objectSpread2(_objectSpread2({}, context.error), extraError) : undefined;
|
|
198
138
|
return {
|
|
199
139
|
status: context.intent ? undefined : error ? 'error' : 'success',
|
|
200
140
|
intent: context.intent ? context.intent : undefined,
|
|
201
|
-
initialValue: (_normalize = normalize(context.payload
|
|
141
|
+
initialValue: (_normalize = normalize(context.payload,
|
|
142
|
+
// We can't serialize the file and send it back from the server, but we can preserve it in the client
|
|
143
|
+
typeof document !== 'undefined')) !== null && _normalize !== void 0 ? _normalize : {},
|
|
202
144
|
error,
|
|
203
|
-
state: context.state
|
|
145
|
+
state: context.state,
|
|
146
|
+
fields: Array.from(context.fields)
|
|
204
147
|
};
|
|
205
148
|
}
|
|
206
149
|
function getIntent(serializedIntent) {
|
|
@@ -306,8 +249,8 @@ function setListState(state, intent, getDefaultValue) {
|
|
|
306
249
|
function serialize(defaultValue) {
|
|
307
250
|
if (isPlainObject(defaultValue)) {
|
|
308
251
|
// @ts-expect-error FIXME
|
|
309
|
-
return Object.entries(defaultValue).reduce((result,
|
|
310
|
-
var [key, value] =
|
|
252
|
+
return Object.entries(defaultValue).reduce((result, _ref) => {
|
|
253
|
+
var [key, value] = _ref;
|
|
311
254
|
// @ts-ignore-error FIXME
|
|
312
255
|
result[key] = serialize(value);
|
|
313
256
|
return result;
|