@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.
@@ -1,16 +1,9 @@
1
- import { formatPathSegments } from './formdata.mjs';
1
+ import { formatPath } from './formdata.mjs';
2
2
  import { isPlainObject } from './util.mjs';
3
3
 
4
- /**
5
- * A widened version of `StandardSchemaV1.Issue`.
6
- *
7
- * The `path` elements and `PropertyKey` fields are loosened to `unknown`
8
- * to stay compatible with Valibot's native issue type.
9
- */
10
-
11
4
  function formatIssues(issues) {
12
5
  var error = {
13
- formErrors: [],
6
+ formErrors: null,
14
7
  fieldErrors: {}
15
8
  };
16
9
  for (var issue of issues) {
@@ -22,8 +15,10 @@ function formatIssues(issues) {
22
15
  }
23
16
  return path;
24
17
  })) !== null && _issue$path$map !== void 0 ? _issue$path$map : [];
25
- var name = formatPathSegments(segments !== null && segments !== void 0 ? segments : []);
18
+ var name = formatPath(segments !== null && segments !== void 0 ? segments : []);
26
19
  if (!name) {
20
+ var _error$formErrors;
21
+ (_error$formErrors = error.formErrors) !== null && _error$formErrors !== void 0 ? _error$formErrors : error.formErrors = [];
27
22
  error.formErrors.push(issue.message);
28
23
  } else {
29
24
  var _error$fieldErrors, _error$fieldErrors$na;
@@ -33,7 +33,7 @@ function getSubmissionContext(body) {
33
33
  return 1; // continue
34
34
  }
35
35
  context.fields.add(name);
36
- formdata.setValueAtPath(context.payload, name, prev => {
36
+ formdata.setPathValue(context.payload, name, prev => {
37
37
  if (!prev) {
38
38
  return next;
39
39
  } else if (Array.isArray(prev)) {
@@ -57,11 +57,11 @@ function parse(payload, options) {
57
57
  switch (intent.type) {
58
58
  case 'update':
59
59
  {
60
- var name = formdata.appendPathSegment(intent.payload.name, intent.payload.index);
60
+ var name = formdata.appendPath(intent.payload.name, intent.payload.index);
61
61
  var _value = intent.payload.value;
62
62
  if (typeof intent.payload.value !== 'undefined') {
63
63
  if (name) {
64
- formdata.setValueAtPath(context.payload, name, () => _value);
64
+ formdata.setPathValue(context.payload, name, () => _value);
65
65
  } else {
66
66
  context.payload = _value;
67
67
  }
@@ -70,9 +70,9 @@ function parse(payload, options) {
70
70
  }
71
71
  case 'reset':
72
72
  {
73
- var _name = formdata.appendPathSegment(intent.payload.name, intent.payload.index);
73
+ var _name = formdata.appendPath(intent.payload.name, intent.payload.index);
74
74
  if (_name) {
75
- formdata.setValueAtPath(context.payload, _name, () => undefined);
75
+ formdata.setPathValue(context.payload, _name, () => undefined);
76
76
  } else {
77
77
  context.payload = {};
78
78
  }
@@ -127,9 +127,9 @@ function replySubmission(context) {
127
127
  }
128
128
  if ('hideFields' in options && options.hideFields) {
129
129
  for (var name of options.hideFields) {
130
- var _value2 = formdata.getValueAtPath(context.payload, name);
130
+ var _value2 = formdata.getPathValue(context.payload, name);
131
131
  if (typeof _value2 !== 'undefined') {
132
- formdata.setValueAtPath(context.payload, name, () => undefined);
132
+ formdata.setPathValue(context.payload, name, () => undefined);
133
133
  }
134
134
  }
135
135
  }
@@ -201,7 +201,7 @@ function updateList(list, intent) {
201
201
  }
202
202
  }
203
203
  function setListValue(data, intent) {
204
- formdata.setValueAtPath(data, intent.payload.name, value => {
204
+ formdata.setPathValue(data, intent.payload.name, value => {
205
205
  var list = value !== null && value !== void 0 ? value : [];
206
206
  updateList(list, intent);
207
207
  return list;
@@ -218,8 +218,8 @@ function setState(state, name, valueFn) {
218
218
  var target = {};
219
219
  var _loop2 = function _loop2() {
220
220
  var value = state[_key];
221
- if (formdata.isPrefix(_key, name) && _key !== name) {
222
- formdata.setValueAtPath(target, _key, currentValue => {
221
+ if (formdata.isPathPrefix(_key, name) && _key !== name) {
222
+ formdata.setPathValue(target, _key, currentValue => {
223
223
  if (typeof currentValue === 'undefined') {
224
224
  return value;
225
225
  }
@@ -239,7 +239,7 @@ function setState(state, name, valueFn) {
239
239
  for (var _key of keys) {
240
240
  _loop2();
241
241
  }
242
- var result = valueFn(formdata.getValueAtPath(target, name));
242
+ var result = valueFn(formdata.getPathValue(target, name));
243
243
  Object.assign(state, flatten(result, {
244
244
  resolve(data) {
245
245
  if (util.isPlainObject(data) || Array.isArray(data)) {
@@ -1,6 +1,6 @@
1
1
  import { objectSpread2 as _objectSpread2 } from './_virtual/_rollupPluginBabelHelpers.mjs';
2
2
  import { isGlobalInstance } from './dom.mjs';
3
- import { appendPathSegment, setValueAtPath, getValueAtPath, isPrefix } from './formdata.mjs';
3
+ import { appendPath, setPathValue, getPathValue, isPathPrefix } from './formdata.mjs';
4
4
  import { isPlainObject, invariant } from './util.mjs';
5
5
 
6
6
  /**
@@ -29,7 +29,7 @@ function getSubmissionContext(body) {
29
29
  return 1; // continue
30
30
  }
31
31
  context.fields.add(name);
32
- setValueAtPath(context.payload, name, prev => {
32
+ setPathValue(context.payload, name, prev => {
33
33
  if (!prev) {
34
34
  return next;
35
35
  } else if (Array.isArray(prev)) {
@@ -53,11 +53,11 @@ function parse(payload, options) {
53
53
  switch (intent.type) {
54
54
  case 'update':
55
55
  {
56
- var name = appendPathSegment(intent.payload.name, intent.payload.index);
56
+ var name = appendPath(intent.payload.name, intent.payload.index);
57
57
  var _value = intent.payload.value;
58
58
  if (typeof intent.payload.value !== 'undefined') {
59
59
  if (name) {
60
- setValueAtPath(context.payload, name, () => _value);
60
+ setPathValue(context.payload, name, () => _value);
61
61
  } else {
62
62
  context.payload = _value;
63
63
  }
@@ -66,9 +66,9 @@ function parse(payload, options) {
66
66
  }
67
67
  case 'reset':
68
68
  {
69
- var _name = appendPathSegment(intent.payload.name, intent.payload.index);
69
+ var _name = appendPath(intent.payload.name, intent.payload.index);
70
70
  if (_name) {
71
- setValueAtPath(context.payload, _name, () => undefined);
71
+ setPathValue(context.payload, _name, () => undefined);
72
72
  } else {
73
73
  context.payload = {};
74
74
  }
@@ -123,9 +123,9 @@ function replySubmission(context) {
123
123
  }
124
124
  if ('hideFields' in options && options.hideFields) {
125
125
  for (var name of options.hideFields) {
126
- var _value2 = getValueAtPath(context.payload, name);
126
+ var _value2 = getPathValue(context.payload, name);
127
127
  if (typeof _value2 !== 'undefined') {
128
- setValueAtPath(context.payload, name, () => undefined);
128
+ setPathValue(context.payload, name, () => undefined);
129
129
  }
130
130
  }
131
131
  }
@@ -197,7 +197,7 @@ function updateList(list, intent) {
197
197
  }
198
198
  }
199
199
  function setListValue(data, intent) {
200
- setValueAtPath(data, intent.payload.name, value => {
200
+ setPathValue(data, intent.payload.name, value => {
201
201
  var list = value !== null && value !== void 0 ? value : [];
202
202
  updateList(list, intent);
203
203
  return list;
@@ -214,8 +214,8 @@ function setState(state, name, valueFn) {
214
214
  var target = {};
215
215
  var _loop2 = function _loop2() {
216
216
  var value = state[_key];
217
- if (isPrefix(_key, name) && _key !== name) {
218
- setValueAtPath(target, _key, currentValue => {
217
+ if (isPathPrefix(_key, name) && _key !== name) {
218
+ setPathValue(target, _key, currentValue => {
219
219
  if (typeof currentValue === 'undefined') {
220
220
  return value;
221
221
  }
@@ -235,7 +235,7 @@ function setState(state, name, valueFn) {
235
235
  for (var _key of keys) {
236
236
  _loop2();
237
237
  }
238
- var result = valueFn(getValueAtPath(target, name));
238
+ var result = valueFn(getPathValue(target, name));
239
239
  Object.assign(state, flatten(result, {
240
240
  resolve(data) {
241
241
  if (isPlainObject(data) || Array.isArray(data)) {
package/dist/types.d.ts CHANGED
@@ -12,15 +12,35 @@ export type FormValue<Type extends JsonPrimitive | FormDataEntryValue = JsonPrim
12
12
  /**
13
13
  * Form error object that contains both form errors and field errors.
14
14
  */
15
- export type FormError<ErrorShape = string> = {
15
+ export type FormError<ErrorShape = string[]> = {
16
16
  /**
17
- * The error of the form.
17
+ * The form-level error payload.
18
+ * Set to `null` when there is no form-level error.
18
19
  */
19
- formErrors: ErrorShape[];
20
+ formErrors: ErrorShape | null;
20
21
  /**
21
- * The field errors based on the field name.
22
+ * Field-level error payloads mapped by field name.
23
+ * Use `null` to explicitly clear a field error.
22
24
  */
23
- fieldErrors: Record<string, ErrorShape[]>;
25
+ fieldErrors: Record<string, ErrorShape | null>;
26
+ };
27
+ /**
28
+ * A widened version of `StandardSchemaV1.Issue`.
29
+ *
30
+ * The `path` elements and `PropertyKey` fields are loosened to `unknown`
31
+ * to stay compatible with Valibot's native issue type.
32
+ */
33
+ export type StandardSchemaIssue = {
34
+ readonly message: string;
35
+ readonly path?: ReadonlyArray<unknown | {
36
+ key: unknown;
37
+ }> | undefined;
38
+ };
39
+ export type StandardSchemaError = Partial<Record<keyof FormError, never>> & {
40
+ issues: ReadonlyArray<StandardSchemaIssue>;
41
+ };
42
+ export type CustomError<ErrorShape> = Partial<FormError<ErrorShape>> & {
43
+ issues?: never;
24
44
  };
25
45
  /**
26
46
  * Structured data parsed from a form submission.
@@ -30,7 +50,7 @@ export type Submission<ValueType extends JsonPrimitive | FormDataEntryValue = Js
30
50
  * The submitted values mapped by field name.
31
51
  * Supports nested names like `user.email` or indexed names like `items[0].id`.
32
52
  *
33
- * @example
53
+ * **Example:**
34
54
  * ```json
35
55
  * {
36
56
  * "username": "johndoe",
@@ -58,7 +78,7 @@ export type Submission<ValueType extends JsonPrimitive | FormDataEntryValue = Js
58
78
  /**
59
79
  * The result of a submission.
60
80
  */
61
- export type SubmissionResult<ErrorShape = string, ValueType extends JsonPrimitive | FormDataEntryValue = JsonPrimitive | FormDataEntryValue> = {
81
+ export type SubmissionResult<ErrorShape = string[], ValueType extends JsonPrimitive | FormDataEntryValue = JsonPrimitive | FormDataEntryValue> = {
62
82
  /**
63
83
  * The original submission data.
64
84
  */
@@ -81,8 +101,9 @@ export type FieldName<FieldShape> = string & {
81
101
  '~shape'?: FieldShape;
82
102
  };
83
103
  /**
84
- * The input attributes related to form field constraints
85
- * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Constraint_validation
104
+ * The input attributes related to form field constraints.
105
+ *
106
+ * See https://developer.mozilla.org/en-US/docs/Web/HTML/Constraint_validation
86
107
  */
87
108
  export type ValidationAttributes = {
88
109
  required?: boolean | undefined;
@@ -103,23 +124,22 @@ export type Serializable<T> = T extends File ? undefined : T extends Array<infer
103
124
  [K in keyof T]: Serializable<T[K]>;
104
125
  } : T;
105
126
  /**
106
- * Converts an arbitrary value into a {@link SerializedValue}.
127
+ * Converts an arbitrary value into a form value.
107
128
  *
108
129
  * This function is used to prepare field values for submission,
109
130
  * ensuring they are compatible with the browser's `FormData` API.
110
- *
111
- * @param value - The original value to serialize.
112
- * @returns A `SerializedValue` if the input can be represented in `FormData`,
113
- * or `undefined` if it cannot be serialized.
114
131
  */
115
- export type Serialize = (value: unknown) => SerializedValue | null | undefined;
132
+ export type Serialize = (value: unknown, ctx: {
133
+ name: string | undefined;
134
+ }) => FormValue<FormDataEntryValue> | null | undefined;
116
135
  /**
117
- * A value that can be serialized into `FormData`.
118
- *
119
- * - `string` and `File` are supported natively by `FormData`.
120
- * - Arrays allow representing multi-value fields.
136
+ * A custom serializer that can override specific values and delegate everything
137
+ * else back to the default serializer.
121
138
  */
122
- export type SerializedValue = string | string[] | File | File[];
139
+ export type CustomSerialize = (value: unknown, ctx: {
140
+ name: string | undefined;
141
+ defaultSerialize: (value: unknown) => ReturnType<Serialize>;
142
+ }) => FormValue<FormDataEntryValue> | null | undefined;
123
143
  /**
124
144
  * Flatten a discriminated union into a single type with all properties.
125
145
  */
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.17.1",
6
+ "version": "1.19.0",
7
7
  "main": "./dist/index.js",
8
8
  "module": "./dist/index.mjs",
9
9
  "types": "./dist/index.d.ts",