@whatsaaaa/form-builder-schema 0.4.1 → 0.6.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 CHANGED
@@ -36,7 +36,7 @@ Empty optional fields output `undefined`. Rules never run on empty values, and a
36
36
 
37
37
  ## Field types
38
38
 
39
- There is a type for every native control, plus three display elements. Anything more specific is a `ui.widget` variant of one of them, or your own type: a star rating is a `number` with `ui: { widget: 'rating' }`, and a colour picker is a `text` with a `hexColor` rule.
39
+ There is a type for every native control, two types that hold other fields, and three display elements. Anything more specific is a `ui.widget` variant of one of them, or your own type: a star rating is a `number` with `ui: { widget: 'rating' }`, and a colour picker is a `text` with a `hexColor` rule.
40
40
 
41
41
  | Type | Kind | Value | Props | Checks |
42
42
  | ------------------------------------- | -------------------------------------- | ----------------------------------- | ------------------------ | -------------------------------- |
@@ -69,6 +69,29 @@ There is a type for every native control, plus three display elements. Anything
69
69
 
70
70
  They need no `name`, add no output key, and can't have `rules` or `required`. Their `text` can be an i18n key: renderers resolve it with the same function you pass as `resolveMessage`. Whether a paragraph renders markdown is up to the renderer.
71
71
 
72
+ ### Groups and arrays
73
+
74
+ | Type | Kind | Value | Props |
75
+ | ------- | ------ | -------------------------------------- | -------------------------------- |
76
+ | `group` | object | an object with a key for each field | `fields` |
77
+ | `array` | array | a list of single values, or of objects | exactly one of `of` and `fields` |
78
+
79
+ ```json
80
+ {
81
+ "name": "address",
82
+ "type": "group",
83
+ "fields": [
84
+ { "name": "city", "type": "text", "required": true },
85
+ { "name": "zip", "type": "text" }
86
+ ]
87
+ }
88
+ ```
89
+
90
+ - **A group** builds `{ address: { city, zip } }`, so Formisch's path for the city is `['address', 'city']`. It is always there and its fields decide what is required, so it can't have `required` or `default`.
91
+ - **An array with `of`** is a list of single values, such as tags. `of` is the field each item uses, and it needs no `name`. **An array with `fields`** is a list of objects, such as order lines.
92
+ - **Rules on an array**, like `minLength`, count its items. A required array needs at least one item. A missing array is read as `[]`, so its rules still run.
93
+ - Display elements can go inside both. A name only has to be unique among the fields next to it.
94
+
72
95
  ## Rules
73
96
 
74
97
  Every Valibot action whose arguments fit in JSON is a rule with the same name. Params go next to `rule`, and a rule without a `message` uses Valibot's message, so [`@valibot/i18n`](https://valibot.dev/guides/internationalization/) works.
@@ -106,7 +129,7 @@ const { build } = createSchemaBuilder({
106
129
  })
107
130
  ```
108
131
 
109
- The built-in `email` and `url` types use the `email` and `url` rules, so keep `formatRules` (or replace those types), or `createSchemaBuilder` throws a `TypeError`.
132
+ The built-in `email` and `url` types use the `email` and `url` rules, so keep `formatRules` (or replace those types), or `createSchemaBuilder` throws a `TypeError`. `includeDefaultRules: false` leaves out the built-in form rules too; add them back with `formRules: defaultFormRules`.
110
133
 
111
134
  ### Listing rules
112
135
 
@@ -117,6 +140,43 @@ const { rulesForKind } = createSchemaBuilder()
117
140
  rulesForKind('file').map(([name, def]) => def.meta?.label) // ['Minimum size', …]
118
141
  ```
119
142
 
143
+ ## Form rules
144
+
145
+ A form rule checks a field against other fields, such as a repeated password or a date range. Form rules go in `formRules`, next to `fields`, and each one names the `field` its error shows on:
146
+
147
+ ```json
148
+ {
149
+ "version": "1",
150
+ "fields": [
151
+ { "name": "password", "type": "password", "required": true },
152
+ { "name": "password2", "type": "password", "required": true },
153
+ { "name": "start", "type": "date" },
154
+ { "name": "end", "type": "date" }
155
+ ],
156
+ "formRules": [
157
+ { "rule": "sameAs", "field": "password2", "other": "password", "message": "Passwords differ" },
158
+ {
159
+ "rule": "compare",
160
+ "field": "end",
161
+ "op": "gt",
162
+ "other": "start",
163
+ "message": "After the start"
164
+ }
165
+ ]
166
+ }
167
+ ```
168
+
169
+ | Rule | Params | Kinds | Passes when |
170
+ | --------------- | ------------------------------------------ | ----------------------------- | ----------------- |
171
+ | `sameAs` | `other` | string, number, boolean, date | `field === other` |
172
+ | `differentFrom` | `other` | string, number, boolean, date | `field !== other` |
173
+ | `compare` | `op` (`lt`, `lte`, `gt` or `gte`), `other` | number, date | `field op other` |
174
+
175
+ - **Paths** name fields by their value: `'password2'`, `'address.zip'` for a field in a group, and `'lines.*.qty'` for a field in the items of an array. A rule on a path with `*` runs once per item, and its error shows on that item's field. A path it reads with `*` means the same item, so `{ "field": "lines.*.qty", "op": "lte", "other": "lines.*.stock" }` compares each line with itself.
176
+ - **A form rule runs last**, after every field's own rules, and only when the fields it reads have no issues. So a password that is too short never also shows "Passwords differ". It never runs on an empty value either: make the fields required when they must be filled.
177
+ - **`message` is required.** It goes through `resolveMessage` like every other message, with the rule's field in `ctx.field`.
178
+ - The fields a rule reads must have the same kind: `compare` on a number and a date is `kind_mismatch`. A date with `output: 'date'` is compared by its time, so compare it with another date that has `output: 'date'`.
179
+
120
180
  ## Checking definitions
121
181
 
122
182
  `validate(json)` never throws. It returns every problem in the definition, in document order:
@@ -128,13 +188,17 @@ if (!result.success) {
128
188
  }
129
189
  ```
130
190
 
131
- `build(json)` runs the same checks and throws one `DefinitionError` with all of them. Issue codes are `invalid_shape`, `unsupported_version`, `unknown_key`, `unknown_type`, `missing_name`, `duplicate_name`, `invalid_props`, `unknown_rule`, `unknown_param`, `invalid_params` and `kind_mismatch`.
191
+ `build(json)` runs the same checks and throws one `DefinitionError` with all of them. Issue codes are `invalid_shape`, `unsupported_version`, `unknown_key`, `unknown_type`, `missing_name`, `invalid_name`, `duplicate_name`, `invalid_props`, `invalid_default`, `unknown_rule`, `unknown_param`, `invalid_params`, `kind_mismatch` and `unknown_field`. An issue in a nested field has its full path, such as `['fields', 2, 'fields', 0, 'rules', 1]`.
192
+
193
+ - **Names** are one key of the value, so a name with `.`, `[` or `]` is `invalid_name`.
194
+ - **Defaults** must pass the field's own schema, rules included, or they are `invalid_default`. An empty default, like `''`, counts as none.
195
+ - **Form rules** report on `['formRules', 0]` and below. A `field` path that names no field with a value is `unknown_field` on `['formRules', 0, 'field']`, and a path the rule reads gets it on `['formRules', 0]`. When a field the rule reads has issues of its own, the rule adds none.
132
196
 
133
197
  Keys on a field must be reserved keys (`RESERVED_FIELD_KEYS`) or props of its type. Put renderer settings under `ui`, which is never checked.
134
198
 
135
199
  ## Extending
136
200
 
137
- `createSchemaBuilder({ kinds, fieldTypes, rules })` merges your entries over the defaults by key. The merged registries are returned as `kinds`, `fieldTypes` and `rules`.
201
+ `createSchemaBuilder({ kinds, fieldTypes, rules, formRules })` merges your entries over the defaults by key. The merged registries are returned as `kinds`, `fieldTypes`, `rules` and `formRules`.
138
202
 
139
203
  ```ts
140
204
  const tags = defineFieldType({
@@ -165,8 +229,49 @@ const { build } = createSchemaBuilder({ fieldTypes: { tags }, rules: { even } })
165
229
  })
166
230
  ```
167
231
 
232
+ - A **field type whose value holds other fields** sets `container: true` and builds them with `ctx.buildFields(fields, path)`, or `ctx.buildField(field, path)` for the items of a list. The builder checks those fields like any others, so their issues have their full path. A container's kind is `object` or `array`, its value is never empty, and Formisch keeps a field for each child.
233
+ - To **test a field type on its own**, give its `schema()` a context from `createBuildContext()`. Its `buildFields` and `buildField` use the default registries and throw a `DefinitionError` when the child fields have issues:
234
+
235
+ ```ts
236
+ const schema = myType.schema?.(field, createBuildContext({ path: ['fields', 0] }))
237
+ ```
238
+
239
+ - A **form rule** lists the paths it reads besides `field`, and checks their values with a plain function. The builder checks that the fields exist and have one of `kinds`, and runs `check` only when none of them has an issue or is empty:
240
+
241
+ ```ts
242
+ const sameZip = defineFormRule({
243
+ params: v.object({ others: v.array(v.string()) }),
244
+ reads: (params) => params.others,
245
+ kinds: ['string'],
246
+ check: (values) => new Set(values).size === 1, // the value of `field`, then the others
247
+ meta: { label: 'Same ZIP', category: 'comparison' },
248
+ })
249
+
250
+ const { build } = createSchemaBuilder({ formRules: { sameZip } })
251
+ ```
252
+
253
+ `sameKind: true` requires every field it reads to have the same kind. `rule`, `field` and `message` are reserved (`RESERVED_FORM_RULE_KEYS`), so params can't use them.
254
+
168
255
  - Mistakes in the registry, such as an unknown kind or a reserved props key, throw a `TypeError` from `createSchemaBuilder`.
169
256
 
257
+ ## Initial input and walking fields
258
+
259
+ Two plain functions read a definition without a builder, for renderers and adapters:
260
+
261
+ ```ts
262
+ import { getInitialInput, walkFields } from '@whatsaaaa/form-builder-schema'
263
+
264
+ const form = useForm({ schema: build(json), initialInput: getInitialInput(json) })
265
+
266
+ for (const { field, dataPath, definitionPath, depth } of walkFields(json)) {
267
+ // e.g. dataPath ['lines', '*', 'quantity'], definitionPath ['fields', 2, 'fields', 1], depth 1
268
+ }
269
+ ```
270
+
271
+ - `getInitialInput` gives each field's `default`, nested the way the value is. A group gives an object, and an array without a default gives `[]`. Other fields without a default are left out.
272
+ - `walkFields` yields every field at every depth, in document order, with a group or array before its fields. The fields of an array's items come once, with `'*'` in place of the index. A field without a name, like a heading, has its parent's `dataPath`.
273
+ - Both know the built-in `group` and `array` types only, and neither checks the definition, so run `validate()` first.
274
+
170
275
  ## Messages
171
276
 
172
277
  ```ts
package/dist/index.d.ts CHANGED
@@ -5,12 +5,6 @@ type AnyAction = v.GenericPipeAction;
5
5
  * A `v.object()` schema. The builder reads its `entries` to find unknown keys.
6
6
  */
7
7
  type AnyObjectSchema = v.ObjectSchema<v.ObjectEntries, v.ErrorMessage<v.ObjectIssue> | undefined>;
8
- interface KindDef {
9
- /** True when the input means "no value". */
10
- isEmpty(input: unknown): boolean;
11
- /** Extra check for required fields after normalize rules ran. Omit it when isEmpty is enough. */
12
- required?(message: string): AnyAction | null;
13
- }
14
8
  /**
15
9
  * The built-in kinds, plus any string so consumers can register their own.
16
10
  */
@@ -18,6 +12,8 @@ type ValueKind = 'string' | 'number' | 'boolean' | 'date' | 'array' | 'file' | '
18
12
  interface JsonForm {
19
13
  version: '1';
20
14
  fields: readonly JsonField[];
15
+ /** Rules that check a field against other fields. They run after every field's own rules. */
16
+ formRules?: readonly JsonFormRule[];
21
17
  }
22
18
  interface JsonField {
23
19
  name?: string;
@@ -40,10 +36,17 @@ interface JsonRule {
40
36
  message?: string;
41
37
  [param: string]: unknown;
42
38
  }
39
+ interface JsonFormRule {
40
+ rule: string;
41
+ /** Where the error shows, as a dot path: `'password2'`, `'address.zip'` or `'lines.*.qty'`. */
42
+ field: string;
43
+ message: string;
44
+ [param: string]: unknown;
45
+ }
43
46
  /** Where something is in a definition, e.g. `['fields', 0, 'rules', 1]`. */
44
47
  type DefinitionPath = readonly (string | number)[];
45
48
  /** Public API: adding a code is a minor change, renaming one is breaking. */
46
- type DefinitionIssueCode = 'invalid_shape' | 'unsupported_version' | 'unknown_key' | 'unknown_type' | 'missing_name' | 'duplicate_name' | 'invalid_props' | 'unknown_rule' | 'unknown_param' | 'invalid_params' | 'kind_mismatch';
49
+ type DefinitionIssueCode = 'invalid_shape' | 'unsupported_version' | 'unknown_key' | 'unknown_type' | 'missing_name' | 'invalid_name' | 'duplicate_name' | 'invalid_props' | 'invalid_default' | 'unknown_rule' | 'unknown_param' | 'invalid_params' | 'kind_mismatch' | 'unknown_field';
47
50
  interface DefinitionIssue {
48
51
  code: DefinitionIssueCode;
49
52
  path: DefinitionPath;
@@ -89,6 +92,13 @@ interface FieldTypeDef<TProps extends AnyObjectSchema = AnyObjectSchema> {
89
92
  required?(message: string): AnyAction | null;
90
93
  /** Runs last, after every rule, e.g. to turn an ISO string into a `Date`. */
91
94
  finalize?(field: FieldWithProps<TProps>): AnyAction | undefined;
95
+ /**
96
+ * True for a type whose value holds other fields, built with `ctx.buildFields` or
97
+ * `ctx.buildField`. Its kind must be `'object'` or `'array'`. The value is never empty: a
98
+ * missing one becomes `{}` or `[]`, and the rules always run. Formisch then sees the object or
99
+ * array schema itself, so it keeps a field for each child.
100
+ */
101
+ container?: boolean;
92
102
  }
93
103
  /**
94
104
  * Picks the kind from the field. Declared as a method so it stays bivariant, like `schema()`.
@@ -101,6 +111,26 @@ type FieldWithProps<TProps extends AnyObjectSchema = AnyObjectSchema> = JsonFiel
101
111
  interface BuildContext {
102
112
  /** Where the field is in the definition, e.g. `['fields', 2]`. */
103
113
  readonly path: DefinitionPath;
114
+ /**
115
+ * Checks and builds child fields with the same registries, and returns their object schema.
116
+ * Their issues land in the same `validate()` result. `path` is where the list is in the
117
+ * definition, e.g. `[...ctx.path, 'fields']`.
118
+ */
119
+ buildFields(fields: readonly JsonField[], path: DefinitionPath): AnyObjectSchema;
120
+ /** Checks and builds one field for the items of a list. Its name isn't needed or used. */
121
+ buildField(field: JsonField, path: DefinitionPath): AnySchema;
122
+ }
123
+ /**
124
+ * A build context for testing a field type on its own, without a definition around it.
125
+ * `buildFields` and `buildField` use the default registries and throw a `DefinitionError` when
126
+ * the child fields have issues. `overrides` replaces any member, e.g. `path`.
127
+ */
128
+ export declare function createBuildContext(overrides?: Partial<BuildContext>): BuildContext;
129
+ interface KindDef {
130
+ /** True when the input means "no value". */
131
+ isEmpty(input: unknown): boolean;
132
+ /** Extra check for required fields after normalize rules ran. Omit it when isEmpty is enough. */
133
+ required?(message: string): AnyAction | null;
104
134
  }
105
135
  /**
106
136
  * `normalize` rules (trim, change case) run before the required check, so `' '` with `trim` counts
@@ -129,15 +159,42 @@ interface RuleDef<TParams extends AnyObjectSchema = AnyObjectSchema> {
129
159
  /** Method syntax keeps `create` bivariant, so specific rules fit in a `Record<string, RuleDef>`. */
130
160
  create(params: v.InferOutput<TParams>, message?: string): AnyAction;
131
161
  }
162
+ /**
163
+ * A rule that checks a field against other fields, e.g. that two passwords match. It goes in the
164
+ * definition's `formRules`, and its error shows on the field named by `field`.
165
+ */
166
+ interface FormRuleDef<TParams extends AnyObjectSchema = AnyObjectSchema> {
167
+ /** Its params, next to `rule`, `field` and `message` in the definition. Unknown ones fail. */
168
+ params?: TParams;
169
+ /**
170
+ * The paths the rule reads besides `field`, e.g. `[params.other]`, so the builder can check
171
+ * that those fields exist. Method syntax keeps it bivariant, like `check()`.
172
+ */
173
+ reads(params: v.InferOutput<TParams>): readonly string[];
174
+ /** The kinds the fields it reads may have. Any kind when omitted. */
175
+ kinds?: readonly ValueKind[];
176
+ /** True when every field it reads must have the same kind, e.g. to compare them. */
177
+ sameKind?: boolean;
178
+ /**
179
+ * True when the values pass. `values` holds the value of `field`, then the values of the paths
180
+ * from `reads()`, in that order. It only runs when all of them are valid and none is empty.
181
+ */
182
+ check(values: readonly unknown[], params: v.InferOutput<TParams>): boolean;
183
+ meta?: RuleMeta;
184
+ }
132
185
  interface MessageContext {
133
186
  field: JsonField;
134
187
  rule?: string;
135
188
  path: DefinitionPath;
136
189
  }
190
+ /** The schema of a list of fields: an object with a key for each field that has a value. */
191
+ type FieldsSchema = v.ObjectSchema<v.ObjectEntries, undefined>;
137
192
  interface SchemaBuilderOptions {
138
193
  kinds?: Record<string, KindDef>;
139
194
  fieldTypes?: Record<string, FieldTypeDef>;
140
195
  rules?: Record<string, RuleDef>;
196
+ formRules?: Record<string, FormRuleDef>;
197
+ /** With false, only your own rules and form rules are registered. Defaults to true. */
141
198
  includeDefaultRules?: boolean;
142
199
  messages?: {
143
200
  required?: string;
@@ -149,15 +206,56 @@ interface SchemaBuilderOptions {
149
206
  resolveMessage?(key: string, ctx: MessageContext): string | undefined;
150
207
  }
151
208
  export declare function createSchemaBuilder(options?: SchemaBuilderOptions): {
152
- build: (json: JsonForm) => v.ObjectSchema<v.ObjectEntries, undefined>;
209
+ build: (json: JsonForm) => FieldsSchema;
153
210
  validate: (json: unknown) => ValidateResult;
154
211
  rulesForKind: (kind: ValueKind) => [name: string, def: RuleDef][];
155
212
  kinds: Readonly<Record<string, KindDef>>;
156
213
  fieldTypes: Readonly<Record<string, FieldTypeDef<AnyObjectSchema>>>;
157
214
  rules: Readonly<Record<string, RuleDef<AnyObjectSchema>>>;
215
+ formRules: Readonly<Record<string, FormRuleDef<AnyObjectSchema>>>;
158
216
  };
217
+ /**
218
+ * Formisch's `initialInput` for a definition: each field's `default`, nested the way the value
219
+ * is. A group gives an object, and an array without a default gives `[]`. Other fields without
220
+ * a default are left out. Like `walkFields`, it reads the built-in `group` and `array` types
221
+ * and needs no builder.
222
+ */
223
+ export declare function getInitialInput(definition: JsonForm): Record<string, unknown>;
224
+ /** One field found by `walkFields`. */
225
+ interface WalkedField {
226
+ field: JsonField;
227
+ /** The field's type, e.g. `'text'`. */
228
+ type: string;
229
+ /**
230
+ * Where the field's value is, as a Formisch path: `['address', 'city']`. The items of an array
231
+ * have no fixed index, so they have `'*'` in its place. A field without a name, like a
232
+ * heading, has its parent's path.
233
+ */
234
+ dataPath: readonly (string | number)[];
235
+ /** Where the field is in the definition: `['fields', 1, 'fields', 0]`. */
236
+ definitionPath: DefinitionPath;
237
+ /** 0 for the form's own fields, 1 for the fields inside them, and so on. */
238
+ depth: number;
239
+ }
240
+ /**
241
+ * Every field of a definition, at every depth, in document order. A group or an array comes
242
+ * before its fields, and the fields of an array's items come once. It reads the built-in
243
+ * `group` and `array` types and needs no builder, so it doesn't check the definition: run
244
+ * `validate()` first.
245
+ */
246
+ export declare function walkFields(definition: JsonForm): Generator<WalkedField, void, undefined>;
159
247
  /** Every built-in field type. */
160
248
  export declare const defaultFieldTypes: {
249
+ group: FieldTypeDef<import("valibot").ObjectSchema<{
250
+ readonly fields: import("valibot").ArraySchema<import("valibot").CustomSchema<JsonField, undefined>, undefined>;
251
+ }, undefined>>;
252
+ array: FieldTypeDef<import("valibot").SchemaWithPipe<readonly [import("valibot").ObjectSchema<{
253
+ readonly of: import("valibot").OptionalSchema<import("valibot").CustomSchema<JsonField, undefined>, undefined>;
254
+ readonly fields: import("valibot").OptionalSchema<import("valibot").ArraySchema<import("valibot").CustomSchema<JsonField, undefined>, undefined>, undefined>;
255
+ }, undefined>, import("valibot").CheckAction<{
256
+ of?: JsonField | undefined;
257
+ fields?: JsonField[] | undefined;
258
+ }, "Give exactly one of \"of\" and \"fields\"">]>>;
161
259
  heading: FieldTypeDef<import("valibot").ObjectSchema<{
162
260
  readonly text: import("valibot").StringSchema<undefined>;
163
261
  readonly level: import("valibot").OptionalSchema<import("valibot").SchemaWithPipe<readonly [import("valibot").NumberSchema<undefined>, import("valibot").IntegerAction<number, undefined>, import("valibot").MinValueAction<number, 1, undefined>, import("valibot").MaxValueAction<number, 6, undefined>]>, undefined>;
@@ -535,6 +633,7 @@ export declare const defaultRules: {
535
633
  readonly value: import("valibot").SchemaWithPipe<readonly [import("valibot").NumberSchema<undefined>, import("valibot").IntegerAction<number, undefined>, import("valibot").MinValueAction<number, 0, undefined>]>;
536
634
  }, undefined>>;
537
635
  };
636
+ export declare const defineFormRule: <T extends AnyObjectSchema>(def: FormRuleDef<T>) => FormRuleDef<T>;
538
637
  export declare const defineRule: <T extends AnyObjectSchema>(def: RuleDef<T>) => RuleDef<T>;
539
638
  /** Size and type of a File or Blob. */
540
639
  export declare const fileRules: {
@@ -587,6 +686,19 @@ export declare const formatRules: {
587
686
  readonly types: v.SchemaWithPipe<readonly [v.ArraySchema<v.PicklistSchema<readonly ["md4", "md5", "sha1", "sha256", "sha384", "sha512", "ripemd128", "ripemd160", "tiger128", "tiger160", "tiger192", "crc32", "crc32b", "adler32"], undefined>, undefined>, v.MinLengthAction<("md4" | "md5" | "sha1" | "sha256" | "sha384" | "sha512" | "ripemd128" | "ripemd160" | "tiger128" | "tiger160" | "tiger192" | "crc32" | "crc32b" | "adler32")[], 1, "Pick at least one hash type">]>;
588
687
  }, undefined>>;
589
688
  };
689
+ /** Every built-in form rule. */
690
+ export declare const defaultFormRules: {
691
+ sameAs: FormRuleDef<v.ObjectSchema<{
692
+ readonly other: v.StringSchema<undefined>;
693
+ }, undefined>>;
694
+ differentFrom: FormRuleDef<v.ObjectSchema<{
695
+ readonly other: v.StringSchema<undefined>;
696
+ }, undefined>>;
697
+ compare: FormRuleDef<v.ObjectSchema<{
698
+ readonly op: v.PicklistSchema<["lt", "lte", "gt", "gte"], undefined>;
699
+ readonly other: v.StringSchema<undefined>;
700
+ }, undefined>>;
701
+ };
590
702
  /** Characters of a string, or items of an array */
591
703
  export declare const lengthRules: {
592
704
  length: RuleDef<v.ObjectSchema<{
@@ -681,5 +793,9 @@ export declare const RESERVED_FIELD_KEYS: readonly ["name", "type", "label", "de
681
793
  * Rule keys this package owns. A rule's params can't use them.
682
794
  */
683
795
  export declare const RESERVED_RULE_KEYS: readonly ["rule", "message"];
684
- export type { AnyAction, AnyObjectSchema, AnySchema, BuildContext, DefinitionIssue, DefinitionIssueCode, DefinitionPath, FieldTypeDef, FieldWithProps, JsonField, JsonForm, JsonRule, KindDef, KindOf, MessageContext, RuleCategory, RuleDef, RuleMeta, RuleStage, SchemaBuilderOptions, ValidateResult, ValueKind };
796
+ /**
797
+ * Form rule keys this package owns. A form rule's params can't use them.
798
+ */
799
+ export declare const RESERVED_FORM_RULE_KEYS: readonly ["rule", "field", "message"];
800
+ export type { AnyAction, AnyObjectSchema, AnySchema, BuildContext, DefinitionIssue, DefinitionIssueCode, DefinitionPath, FieldTypeDef, FieldWithProps, FormRuleDef, JsonField, JsonForm, JsonFormRule, JsonRule, KindDef, KindOf, MessageContext, RuleCategory, RuleDef, RuleMeta, RuleStage, SchemaBuilderOptions, ValidateResult, ValueKind, WalkedField };
685
801
  //# sourceMappingURL=index.d.ts.map