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