@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 +109 -4
- package/dist/index.d.ts +125 -9
- package/dist/index.js +596 -153
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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,
|
|
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 `
|
|
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 `
|
|
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) =>
|
|
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
|
-
|
|
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
|