@conform-to/dom 1.17.1 → 1.19.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 +1 -1
- package/dist/dom.d.ts +13 -9
- package/dist/dom.js +93 -26
- package/dist/dom.mjs +92 -26
- package/dist/form.js +23 -23
- package/dist/form.mjs +24 -24
- package/dist/formdata.d.ts +106 -69
- package/dist/formdata.js +186 -142
- package/dist/formdata.mjs +177 -136
- package/dist/future/index.d.ts +3 -3
- package/dist/future/index.js +9 -7
- package/dist/future/index.mjs +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4 -3
- package/dist/index.mjs +1 -1
- package/dist/standard-schema.d.ts +2 -14
- package/dist/standard-schema.js +4 -9
- package/dist/standard-schema.mjs +5 -10
- package/dist/submission.js +11 -11
- package/dist/submission.mjs +12 -12
- package/dist/types.d.ts +40 -20
- package/package.json +1 -1
package/dist/formdata.js
CHANGED
|
@@ -9,12 +9,48 @@ var standardSchema = require('./standard-schema.js');
|
|
|
9
9
|
|
|
10
10
|
var DEFAULT_INTENT_NAME = '__INTENT__';
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Returns whether an error payload contains a meaningful value.
|
|
14
|
+
* Empty strings and empty arrays are treated as no error.
|
|
15
|
+
*/
|
|
16
|
+
function hasError(error) {
|
|
17
|
+
return error != null && error !== '' && (!Array.isArray(error) || error.length > 0);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Normalizes a form error object by removing empty error payloads such as
|
|
22
|
+
* empty strings and empty arrays.
|
|
23
|
+
*
|
|
24
|
+
* Returns `null` when no form-level or field-level errors remain.
|
|
25
|
+
*/
|
|
26
|
+
function normalizeFormError(error) {
|
|
27
|
+
var _error$fieldErrors;
|
|
28
|
+
if (error === null) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
var formErrors = hasError(error.formErrors) ? error.formErrors : null;
|
|
32
|
+
var fieldErrors = Object.entries((_error$fieldErrors = error.fieldErrors) !== null && _error$fieldErrors !== void 0 ? _error$fieldErrors : {}).reduce((result, _ref) => {
|
|
33
|
+
var [name, value] = _ref;
|
|
34
|
+
if (hasError(value)) {
|
|
35
|
+
result[name] = value;
|
|
36
|
+
}
|
|
37
|
+
return result;
|
|
38
|
+
}, {});
|
|
39
|
+
if (formErrors === null && Object.keys(fieldErrors).length === 0) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
formErrors,
|
|
44
|
+
fieldErrors
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
12
48
|
/**
|
|
13
49
|
* Construct a form data with the submitter value.
|
|
14
50
|
* It utilizes the submitter argument on the FormData constructor from modern browsers
|
|
15
51
|
* with fallback to append the submitter value in case it is not unsupported.
|
|
16
52
|
*
|
|
17
|
-
*
|
|
53
|
+
* See https://developer.mozilla.org/en-US/docs/Web/API/FormData/FormData#parameters
|
|
18
54
|
*/
|
|
19
55
|
function getFormData(form, submitter) {
|
|
20
56
|
var payload = new FormData(form, submitter);
|
|
@@ -37,14 +73,14 @@ function getFormData(form, submitter) {
|
|
|
37
73
|
/**
|
|
38
74
|
* Convert a string path into an array of segments.
|
|
39
75
|
*
|
|
40
|
-
*
|
|
76
|
+
* **Example:**
|
|
41
77
|
* ```js
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
78
|
+
* parsePath("object.key"); // → ['object', 'key']
|
|
79
|
+
* parsePath("array[0].content"); // → ['array', 0, 'content']
|
|
80
|
+
* parsePath("todos[]"); // → ['todos', '']
|
|
45
81
|
* ```
|
|
46
82
|
*/
|
|
47
|
-
function
|
|
83
|
+
function parsePath(path) {
|
|
48
84
|
if (!path) return [];
|
|
49
85
|
var tokenRegex = /([^.[\]]+)|\[(\d*)\]/g;
|
|
50
86
|
var segments = [];
|
|
@@ -83,15 +119,15 @@ function getPathSegments(path) {
|
|
|
83
119
|
/**
|
|
84
120
|
* Returns a formatted name from the path segments based on the dot and bracket notation.
|
|
85
121
|
*
|
|
86
|
-
*
|
|
122
|
+
* **Example:**
|
|
87
123
|
* ```js
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
124
|
+
* formatPath(['object', 'key']); // → "object.key"
|
|
125
|
+
* formatPath(['array', 0, 'content']); // → "array[0].content"
|
|
126
|
+
* formatPath(['todos', '']); // → "todos[]"
|
|
91
127
|
* ```
|
|
92
128
|
*/
|
|
93
|
-
function
|
|
94
|
-
return segments.reduce((path, segment) =>
|
|
129
|
+
function formatPath(segments) {
|
|
130
|
+
return segments.reduce((path, segment) => appendPath(path, segment), '');
|
|
95
131
|
}
|
|
96
132
|
|
|
97
133
|
/**
|
|
@@ -102,63 +138,66 @@ function formatPathSegments(segments) {
|
|
|
102
138
|
* - segment = `number` ⇒ bracket notation "[n]"
|
|
103
139
|
* - segment = `string` ⇒ dot-notation ".prop"
|
|
104
140
|
*/
|
|
105
|
-
function
|
|
141
|
+
function appendPath(path, segment) {
|
|
142
|
+
var base = path !== null && path !== void 0 ? path : '';
|
|
143
|
+
|
|
106
144
|
// 1) nothing to append
|
|
107
145
|
if (typeof segment === 'undefined') {
|
|
108
|
-
return
|
|
146
|
+
return base;
|
|
109
147
|
}
|
|
110
148
|
|
|
111
149
|
// 2) explicit empty-segment => empty bracket
|
|
112
150
|
if (segment === '') {
|
|
113
151
|
// even as first segment, "[]" is valid
|
|
114
|
-
return "".concat(
|
|
152
|
+
return "".concat(base, "[]");
|
|
115
153
|
}
|
|
116
154
|
|
|
117
155
|
// 3) numeric index => [n]
|
|
118
156
|
if (typeof segment === 'number') {
|
|
119
|
-
return "".concat(
|
|
157
|
+
return "".concat(base, "[").concat(segment, "]");
|
|
120
158
|
}
|
|
121
159
|
|
|
122
160
|
// 4) non-empty string => .prop (no leading dot if no base)
|
|
123
|
-
return
|
|
161
|
+
return base ? "".concat(base, ".").concat(segment) : segment;
|
|
124
162
|
}
|
|
125
163
|
|
|
126
164
|
/**
|
|
127
165
|
* Returns true if `prefix` is a valid leading path of `name`.
|
|
128
166
|
*
|
|
129
|
-
*
|
|
167
|
+
* **Example:**
|
|
130
168
|
* ```js
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
169
|
+
* isPathPrefix("foo.bar.baz", "foo.bar") // → true
|
|
170
|
+
* isPathPrefix("foo.bar[3].baz", "foo.bar[3]") // → true
|
|
171
|
+
* isPathPrefix("foo.bar[3].baz", "foo.bar") // → true
|
|
172
|
+
* isPathPrefix("foo.bar[3].baz", "foo.baz") // → false
|
|
173
|
+
* isPathPrefix("foo", "foo.bar") // → false
|
|
136
174
|
* ```
|
|
137
175
|
*/
|
|
138
|
-
function
|
|
139
|
-
return getRelativePath(name,
|
|
176
|
+
function isPathPrefix(name, prefix) {
|
|
177
|
+
return getRelativePath(name, parsePath(prefix)) !== null;
|
|
140
178
|
}
|
|
141
179
|
|
|
142
180
|
/**
|
|
143
|
-
* Return the segments of `
|
|
181
|
+
* Return the segments of `fullPath` that come after the `basePath` prefix.
|
|
144
182
|
*
|
|
145
|
-
* @param
|
|
146
|
-
* @param basePath
|
|
147
|
-
* @returns The “tail” segments, or `null` if `
|
|
183
|
+
* @param fullPath Full path as a dot/bracket string or array of segments
|
|
184
|
+
* @param basePath Base path as a dot/bracket string or array of segments
|
|
185
|
+
* @returns The “tail” segments, or `null` if `fullPath` isn’t nested under `basePath`
|
|
148
186
|
*
|
|
149
|
-
*
|
|
187
|
+
* **Example:**
|
|
150
188
|
* ```js
|
|
151
189
|
* getRelativePath("foo.bar[0].qux", ["foo","bar"]) // → [0, "qux"]
|
|
152
190
|
* getRelativePath("a.b.c.d", ["a","b"]) // → ["c","d"]
|
|
153
191
|
* getRelativePath("foo", ["foo","bar"]) // → null
|
|
154
192
|
* ```
|
|
155
193
|
*/
|
|
156
|
-
function getRelativePath(
|
|
157
|
-
var
|
|
194
|
+
function getRelativePath(fullPath, basePath) {
|
|
195
|
+
var fullPathSegments = typeof fullPath === 'string' ? parsePath(fullPath) : fullPath;
|
|
196
|
+
var basePathSegments = typeof basePath === 'string' ? parsePath(basePath) : basePath;
|
|
158
197
|
|
|
159
198
|
// if full is at least as long *and* starts with the base…
|
|
160
|
-
if (
|
|
161
|
-
return
|
|
199
|
+
if (fullPathSegments.length >= basePathSegments.length && basePathSegments.every((segment, i) => segment === fullPathSegments[i])) {
|
|
200
|
+
return fullPathSegments.slice(basePathSegments.length);
|
|
162
201
|
}
|
|
163
202
|
return null;
|
|
164
203
|
}
|
|
@@ -166,11 +205,11 @@ function getRelativePath(name, basePath) {
|
|
|
166
205
|
/**
|
|
167
206
|
* Assign a value to a target object by following the path segments.
|
|
168
207
|
*/
|
|
169
|
-
function
|
|
208
|
+
function setPathValue(target, pathOrSegments, valueOrFn) {
|
|
170
209
|
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
|
|
171
210
|
try {
|
|
172
211
|
// 1) normalize + validate path
|
|
173
|
-
var segments = typeof pathOrSegments === 'string' ?
|
|
212
|
+
var segments = typeof pathOrSegments === 'string' ? parsePath(pathOrSegments) : pathOrSegments;
|
|
174
213
|
if (segments.length === 0) {
|
|
175
214
|
throw new Error('Cannot set value at the object root');
|
|
176
215
|
}
|
|
@@ -222,9 +261,9 @@ function setValueAtPath(target, pathOrSegments, valueOrFn) {
|
|
|
222
261
|
/**
|
|
223
262
|
* Retrive the value from a target object by following the path segments.
|
|
224
263
|
*/
|
|
225
|
-
function
|
|
264
|
+
function getPathValue(target, pathOrSegments) {
|
|
226
265
|
var pointer = target;
|
|
227
|
-
var segments = typeof pathOrSegments === 'string' ?
|
|
266
|
+
var segments = typeof pathOrSegments === 'string' ? parsePath(pathOrSegments) : pathOrSegments;
|
|
228
267
|
for (var segment of segments) {
|
|
229
268
|
if (segment === '') {
|
|
230
269
|
throw new Error("Cannot access empty segment \"[]\" in \"".concat(pathOrSegments, "\""));
|
|
@@ -264,8 +303,9 @@ function isEmptyValue(value) {
|
|
|
264
303
|
* This function structures the form values based on the naming convention.
|
|
265
304
|
* It also includes all the field names and extracts the intent from the submission.
|
|
266
305
|
*
|
|
267
|
-
*
|
|
268
|
-
*
|
|
306
|
+
* See https://conform.guide/api/react/future/parseSubmission
|
|
307
|
+
*
|
|
308
|
+
* **Example:**
|
|
269
309
|
* ```ts
|
|
270
310
|
* const formData = new FormData();
|
|
271
311
|
*
|
|
@@ -301,29 +341,27 @@ function parseSubmission(formData, options) {
|
|
|
301
341
|
var _options$skipEntry;
|
|
302
342
|
if (_name !== intentName && !(options !== null && options !== void 0 && (_options$skipEntry = options.skipEntry) !== null && _options$skipEntry !== void 0 && _options$skipEntry.call(options, _name))) {
|
|
303
343
|
var _options$stripEmptyVa;
|
|
304
|
-
var
|
|
305
|
-
var segments =
|
|
344
|
+
var value = formData.getAll(_name);
|
|
345
|
+
var segments = parsePath(_name);
|
|
306
346
|
|
|
307
347
|
// If the name ends with [], remove the empty segment and keep the full array
|
|
308
348
|
// Otherwise, unwrap single values
|
|
309
349
|
if (segments.length > 0 && segments[segments.length - 1] === '') {
|
|
310
350
|
segments.pop();
|
|
311
351
|
} else {
|
|
312
|
-
|
|
352
|
+
value = value.length > 1 ? value : value[0];
|
|
313
353
|
}
|
|
314
|
-
|
|
315
|
-
// Check if the value is empty and should be skipped (defaults to true)
|
|
316
|
-
var stripEmptyValues = (_options$stripEmptyVa = options === null || options === void 0 ? void 0 : options.stripEmptyValues) !== null && _options$stripEmptyVa !== void 0 ? _options$stripEmptyVa : true;
|
|
354
|
+
var stripEmptyValues = (_options$stripEmptyVa = options === null || options === void 0 ? void 0 : options.stripEmptyValues) !== null && _options$stripEmptyVa !== void 0 ? _options$stripEmptyVa : false;
|
|
317
355
|
if (stripEmptyValues) {
|
|
318
356
|
// For arrays, filter out individual empty items
|
|
319
|
-
if (Array.isArray(
|
|
320
|
-
|
|
357
|
+
if (Array.isArray(value)) {
|
|
358
|
+
value = value.filter(item => !isEmptyValue(item));
|
|
321
359
|
}
|
|
322
|
-
if (isEmptyValue(
|
|
323
|
-
|
|
360
|
+
if (isEmptyValue(value)) {
|
|
361
|
+
value = undefined;
|
|
324
362
|
}
|
|
325
363
|
}
|
|
326
|
-
|
|
364
|
+
setPathValue(submission.payload, segments, value, {
|
|
327
365
|
silent: true // Avoid errors if the path is invalid
|
|
328
366
|
});
|
|
329
367
|
submission.fields.push(_name);
|
|
@@ -345,8 +383,9 @@ function parseSubmission(formData, options) {
|
|
|
345
383
|
* file inputs cannot be initialized with files.
|
|
346
384
|
* You can specify `keepFiles: true` to keep the files if needed.
|
|
347
385
|
*
|
|
348
|
-
*
|
|
349
|
-
*
|
|
386
|
+
* See https://conform.guide/api/react/future/report
|
|
387
|
+
*
|
|
388
|
+
* **Example:**
|
|
350
389
|
* ```ts
|
|
351
390
|
* // Report the submission with the field errors
|
|
352
391
|
* report(submission, {
|
|
@@ -377,32 +416,19 @@ function report(submission) {
|
|
|
377
416
|
var error;
|
|
378
417
|
if (options.error == null) {
|
|
379
418
|
error = options.error;
|
|
380
|
-
} else {
|
|
419
|
+
} else if ('issues' in options.error) {
|
|
381
420
|
var _options$error$issues;
|
|
382
421
|
error = standardSchema.formatIssues((_options$error$issues = options.error.issues) !== null && _options$error$issues !== void 0 ? _options$error$issues : []);
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
}
|
|
386
|
-
if (options.error.fieldErrors) {
|
|
387
|
-
for (var [_name2, messages] of Object.entries(options.error.fieldErrors)) {
|
|
388
|
-
if (messages.length === 0) {
|
|
389
|
-
continue;
|
|
390
|
-
}
|
|
391
|
-
if (!error.fieldErrors[_name2]) {
|
|
392
|
-
error.fieldErrors[_name2] = messages;
|
|
393
|
-
} else {
|
|
394
|
-
error.fieldErrors[_name2].push(...messages);
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
}
|
|
422
|
+
} else {
|
|
423
|
+
error = normalizeFormError(options.error);
|
|
398
424
|
}
|
|
399
425
|
var targetValue = typeof options.value === 'undefined' || submission.payload === options.value && !options.reset ? undefined : options.value && !options.keepFiles ? util.stripFiles(options.value) : (_options$value = options.value) !== null && _options$value !== void 0 ? _options$value : {};
|
|
400
426
|
if (options.hideFields) {
|
|
401
|
-
for (var
|
|
402
|
-
var path =
|
|
403
|
-
|
|
427
|
+
for (var _name2 of options.hideFields) {
|
|
428
|
+
var path = parsePath(_name2);
|
|
429
|
+
setPathValue(submission.payload, path, undefined);
|
|
404
430
|
if (targetValue) {
|
|
405
|
-
|
|
431
|
+
setPathValue(targetValue, path, undefined);
|
|
406
432
|
}
|
|
407
433
|
}
|
|
408
434
|
}
|
|
@@ -419,8 +445,9 @@ function report(submission) {
|
|
|
419
445
|
/**
|
|
420
446
|
* A utility function that checks whether the current form data differs from the default values.
|
|
421
447
|
*
|
|
422
|
-
*
|
|
423
|
-
*
|
|
448
|
+
* See https://conform.guide/api/react/future/isDirty
|
|
449
|
+
*
|
|
450
|
+
* **Example: Enable a submit button only if the form is dirty**
|
|
424
451
|
*
|
|
425
452
|
* ```tsx
|
|
426
453
|
* const dirty = useFormData(
|
|
@@ -451,59 +478,16 @@ formData, options) {
|
|
|
451
478
|
intentName: options === null || options === void 0 ? void 0 : options.intentName,
|
|
452
479
|
skipEntry: options === null || options === void 0 ? void 0 : options.skipEntry
|
|
453
480
|
}).payload : formData;
|
|
454
|
-
var
|
|
455
|
-
var serializeData = value => {
|
|
481
|
+
var serialize = (value, context) => {
|
|
456
482
|
if (options !== null && options !== void 0 && options.serialize) {
|
|
457
|
-
return options.serialize(value,
|
|
483
|
+
return options.serialize(value, {
|
|
484
|
+
name: context.name,
|
|
485
|
+
defaultSerialize
|
|
486
|
+
});
|
|
458
487
|
}
|
|
459
|
-
return
|
|
488
|
+
return defaultSerialize(value);
|
|
460
489
|
};
|
|
461
|
-
|
|
462
|
-
var value = serializeData(data);
|
|
463
|
-
if (typeof value === 'undefined') {
|
|
464
|
-
value = data;
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
// Removes empty strings, so that both empty string, empty file, null and undefined are treated as the same
|
|
468
|
-
if (value === '' || value === null) {
|
|
469
|
-
return undefined;
|
|
470
|
-
}
|
|
471
|
-
if (dom.isGlobalInstance(value, 'File')) {
|
|
472
|
-
// Remove empty File as well, which happens if no File was selected
|
|
473
|
-
if (value.name === '' && value.size === 0) {
|
|
474
|
-
return undefined;
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
// If the value is a File, no need to serialize it
|
|
478
|
-
return value;
|
|
479
|
-
}
|
|
480
|
-
if (Array.isArray(value)) {
|
|
481
|
-
if (value.length === 0) {
|
|
482
|
-
return undefined;
|
|
483
|
-
}
|
|
484
|
-
var array = value.map(normalize);
|
|
485
|
-
if (array.length === 1 && (typeof array[0] === 'string' || array[0] === undefined)) {
|
|
486
|
-
return array[0];
|
|
487
|
-
}
|
|
488
|
-
return array;
|
|
489
|
-
}
|
|
490
|
-
if (util.isPlainObject(value)) {
|
|
491
|
-
var entries = Object.entries(value).reduce((list, _ref) => {
|
|
492
|
-
var [key, value] = _ref;
|
|
493
|
-
var normalizedValue = normalize(value);
|
|
494
|
-
if (typeof normalizedValue !== 'undefined') {
|
|
495
|
-
list.push([key, normalizedValue]);
|
|
496
|
-
}
|
|
497
|
-
return list;
|
|
498
|
-
}, []);
|
|
499
|
-
if (entries.length === 0) {
|
|
500
|
-
return undefined;
|
|
501
|
-
}
|
|
502
|
-
return Object.fromEntries(entries);
|
|
503
|
-
}
|
|
504
|
-
return value;
|
|
505
|
-
}
|
|
506
|
-
return !util.deepEqual(normalize(formValue), normalize(defaultValue));
|
|
490
|
+
return !util.deepEqual(normalize(formValue, serialize), normalize(options === null || options === void 0 ? void 0 : options.defaultValue, serialize));
|
|
507
491
|
}
|
|
508
492
|
|
|
509
493
|
/**
|
|
@@ -515,25 +499,25 @@ formData, options) {
|
|
|
515
499
|
* - null -> '' (empty string)
|
|
516
500
|
* - boolean -> 'on' | '' (checked semantics)
|
|
517
501
|
* - number | bigint -> value.toString()
|
|
518
|
-
* - Date -> value.toISOString()
|
|
502
|
+
* - Date -> value.toISOString() without trailing `Z`
|
|
519
503
|
* - File -> File
|
|
520
504
|
* - FileList -> File[]
|
|
521
505
|
* - Array -> string[] or File[] if all items serialize to the same kind; otherwise undefined
|
|
522
506
|
* - anything else -> undefined
|
|
523
507
|
*/
|
|
524
|
-
function
|
|
508
|
+
function defaultSerialize(value) {
|
|
525
509
|
function serializePrimitive(value) {
|
|
526
510
|
if (typeof value === 'string' || value === null) {
|
|
527
511
|
return value;
|
|
528
512
|
}
|
|
529
513
|
if (typeof value === 'boolean') {
|
|
530
|
-
return value ? 'on' :
|
|
514
|
+
return value ? 'on' : null;
|
|
531
515
|
}
|
|
532
516
|
if (typeof value === 'number' || typeof value === 'bigint') {
|
|
533
517
|
return value.toString();
|
|
534
518
|
}
|
|
535
519
|
if (value instanceof Date) {
|
|
536
|
-
return value.toISOString();
|
|
520
|
+
return value.toISOString().slice(0, -1);
|
|
537
521
|
}
|
|
538
522
|
if (dom.isGlobalInstance(value, 'File')) {
|
|
539
523
|
return value;
|
|
@@ -576,10 +560,68 @@ function serialize(value) {
|
|
|
576
560
|
return serializePrimitive(value);
|
|
577
561
|
}
|
|
578
562
|
|
|
563
|
+
/**
|
|
564
|
+
* Recursively serializes a value using the provided serialize function,
|
|
565
|
+
* collapsing empty leaves (`null`, `''`, empty files) to `undefined`
|
|
566
|
+
* and removing empty containers (objects with no remaining keys, empty arrays).
|
|
567
|
+
*
|
|
568
|
+
* When serialize returns `undefined` for a value (i.e. it can't be represented
|
|
569
|
+
* as form data), the raw value is kept and recursed into if it's an object or array.
|
|
570
|
+
*
|
|
571
|
+
* Single-element arrays where the element is a string or undefined are unwrapped
|
|
572
|
+
* to handle the case where a multi-value field (e.g. checkboxes) has only one value.
|
|
573
|
+
*/
|
|
574
|
+
function normalize(value) {
|
|
575
|
+
var serialize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : defaultSerialize;
|
|
576
|
+
var name = arguments.length > 2 ? arguments[2] : undefined;
|
|
577
|
+
var data = serialize(value, {
|
|
578
|
+
name
|
|
579
|
+
});
|
|
580
|
+
if (typeof data === 'undefined') {
|
|
581
|
+
data = value;
|
|
582
|
+
}
|
|
583
|
+
if (data === '' || data === null) {
|
|
584
|
+
return undefined;
|
|
585
|
+
}
|
|
586
|
+
if (dom.isGlobalInstance(data, 'File')) {
|
|
587
|
+
if (data.name === '' && data.size === 0) {
|
|
588
|
+
return undefined;
|
|
589
|
+
}
|
|
590
|
+
return data;
|
|
591
|
+
}
|
|
592
|
+
if (Array.isArray(data)) {
|
|
593
|
+
if (data.length === 0) {
|
|
594
|
+
return undefined;
|
|
595
|
+
}
|
|
596
|
+
var array = data.map((item, index) => normalize(item, serialize, appendPath(name, index)));
|
|
597
|
+
if (array.length === 1 && (typeof array[0] === 'string' || array[0] === undefined)) {
|
|
598
|
+
return array[0];
|
|
599
|
+
}
|
|
600
|
+
return array;
|
|
601
|
+
}
|
|
602
|
+
if (util.isPlainObject(data)) {
|
|
603
|
+
var entries = Object.entries(data).reduce((list, _ref2) => {
|
|
604
|
+
var [key, value] = _ref2;
|
|
605
|
+
var normalizedValue = normalize(value, serialize, appendPath(name, key));
|
|
606
|
+
if (typeof normalizedValue !== 'undefined') {
|
|
607
|
+
list.push([key, normalizedValue]);
|
|
608
|
+
}
|
|
609
|
+
return list;
|
|
610
|
+
}, []);
|
|
611
|
+
if (entries.length === 0) {
|
|
612
|
+
return undefined;
|
|
613
|
+
}
|
|
614
|
+
return Object.fromEntries(entries);
|
|
615
|
+
}
|
|
616
|
+
return data;
|
|
617
|
+
}
|
|
618
|
+
|
|
579
619
|
/**
|
|
580
620
|
* Retrieve a field value from FormData with optional type guards.
|
|
581
621
|
*
|
|
582
|
-
*
|
|
622
|
+
* **Example:**
|
|
623
|
+
*
|
|
624
|
+
* ```ts
|
|
583
625
|
* // Basic field access: return `unknown`
|
|
584
626
|
* const email = getFieldValue(formData, 'email');
|
|
585
627
|
* // String type: returns `string`
|
|
@@ -594,6 +636,7 @@ function serialize(value) {
|
|
|
594
636
|
* const items = getFieldValue<Item[]>(formData, 'items', { type: 'object', array: true });
|
|
595
637
|
* // Optional string type: returns `string | undefined`
|
|
596
638
|
* const bio = getFieldValue(formData, 'bio', { type: 'string', optional: true });
|
|
639
|
+
* ```
|
|
597
640
|
*/
|
|
598
641
|
|
|
599
642
|
function getFieldValue(formData, name, options) {
|
|
@@ -609,11 +652,9 @@ function getFieldValue(formData, name, options) {
|
|
|
609
652
|
// Get value based on array option
|
|
610
653
|
value = array ? formData.getAll(name) : formData.get(name);
|
|
611
654
|
} else {
|
|
612
|
-
// Parse formData and use
|
|
613
|
-
var _submission = parseSubmission(formData
|
|
614
|
-
|
|
615
|
-
});
|
|
616
|
-
value = getValueAtPath(_submission.payload, name);
|
|
655
|
+
// Parse formData and use getPathValue
|
|
656
|
+
var _submission = parseSubmission(formData);
|
|
657
|
+
value = getPathValue(_submission.payload, name);
|
|
617
658
|
}
|
|
618
659
|
|
|
619
660
|
// If optional and value is undefined, skip validation and return early
|
|
@@ -648,16 +689,19 @@ function getFieldValue(formData, name, options) {
|
|
|
648
689
|
}
|
|
649
690
|
|
|
650
691
|
exports.DEFAULT_INTENT_NAME = DEFAULT_INTENT_NAME;
|
|
651
|
-
exports.
|
|
652
|
-
exports.
|
|
692
|
+
exports.appendPath = appendPath;
|
|
693
|
+
exports.defaultSerialize = defaultSerialize;
|
|
694
|
+
exports.formatPath = formatPath;
|
|
653
695
|
exports.getFieldValue = getFieldValue;
|
|
654
696
|
exports.getFormData = getFormData;
|
|
655
|
-
exports.
|
|
697
|
+
exports.getPathValue = getPathValue;
|
|
656
698
|
exports.getRelativePath = getRelativePath;
|
|
657
|
-
exports.
|
|
699
|
+
exports.hasError = hasError;
|
|
658
700
|
exports.isDirty = isDirty;
|
|
659
|
-
exports.
|
|
701
|
+
exports.isPathPrefix = isPathPrefix;
|
|
702
|
+
exports.normalize = normalize;
|
|
703
|
+
exports.normalizeFormError = normalizeFormError;
|
|
704
|
+
exports.parsePath = parsePath;
|
|
660
705
|
exports.parseSubmission = parseSubmission;
|
|
661
706
|
exports.report = report;
|
|
662
|
-
exports.
|
|
663
|
-
exports.setValueAtPath = setValueAtPath;
|
|
707
|
+
exports.setPathValue = setPathValue;
|