@beignet/react-hook-form 0.0.57 → 0.0.59
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/CHANGELOG.md +21 -0
- package/README.md +96 -78
- package/dist/index.d.ts +117 -59
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +35 -17
- package/dist/index.js.map +1 -1
- package/dist/input-snapshot.d.ts +7 -0
- package/dist/input-snapshot.d.ts.map +1 -0
- package/dist/input-snapshot.js +46 -0
- package/dist/input-snapshot.js.map +1 -0
- package/package.json +4 -4
- package/skills/forms/SKILL.md +45 -18
- package/src/index.ts +323 -103
- package/src/input-snapshot.ts +42 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# @beignet/react-hook-form
|
|
2
2
|
|
|
3
|
+
## 0.0.59
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 8a497ae: Require patched Zod releases for application schemas and generated apps, and update browser-test and UI tooling dependencies.
|
|
8
|
+
- 4a59715: Preserve supplied HTTP request inputs during client validation. React Hook Form
|
|
9
|
+
submissions return parsed values by default, with explicit raw mode and accurate
|
|
10
|
+
disabled/custom resolver types, including optional settings and forwarded React
|
|
11
|
+
Hook Form options that may be undefined. Preserve optional returned properties
|
|
12
|
+
and infer outputs across conditional custom and generated resolver configurations.
|
|
13
|
+
Keep returned form options compatible with native React Hook Form options when
|
|
14
|
+
TypeScript's exact optional property checking is enabled.
|
|
15
|
+
Bind a separate form schema whose parsed output matches the contract input when
|
|
16
|
+
UI values need conversion. Capture data getters
|
|
17
|
+
once while preserving opaque schema input instances and their private state.
|
|
18
|
+
Preserve inherited and non-enumerable path values when capturing URL parameters.
|
|
19
|
+
Require all URL placeholders in client argument types, including defaulted schema
|
|
20
|
+
fields, and capture query getters once with input validation enabled or disabled.
|
|
21
|
+
|
|
22
|
+
## 0.0.58
|
|
23
|
+
|
|
3
24
|
## 0.0.57
|
|
4
25
|
|
|
5
26
|
## 0.0.56
|
package/README.md
CHANGED
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
> Beignet is experimental alpha software. The `0.0.x` package line is for early
|
|
9
9
|
> evaluation, and APIs may change between releases while the framework settles.
|
|
10
10
|
|
|
11
|
-
This package provides automatic form validation
|
|
12
|
-
|
|
11
|
+
This package provides automatic form validation and parsed submissions using a
|
|
12
|
+
contract body schema, or a separate form schema that produces contract input.
|
|
13
|
+
The selected form schema must have object-shaped input. It works with any
|
|
13
14
|
[Standard Schema](https://github.com/standard-schema/standard-schema) library
|
|
14
15
|
(Zod, Valibot, ArkType, etc.).
|
|
15
16
|
|
|
@@ -56,7 +57,7 @@ function CreateTodoForm() {
|
|
|
56
57
|
});
|
|
57
58
|
|
|
58
59
|
const onSubmit = form.handleSubmit((values) => {
|
|
59
|
-
// values is
|
|
60
|
+
// values is parsed schema output: { title: string }
|
|
60
61
|
console.log("Creating todo:", values);
|
|
61
62
|
});
|
|
62
63
|
|
|
@@ -175,12 +176,13 @@ Creates a React Hook Form adapter factory.
|
|
|
175
176
|
const rhf = createReactHookForm();
|
|
176
177
|
```
|
|
177
178
|
|
|
178
|
-
### `rhf(contract)`
|
|
179
|
+
### `rhf(contract, options?)`
|
|
179
180
|
|
|
180
|
-
Creates
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
181
|
+
Creates an adapter using the contract body schema by default. Pass `{ schema }`
|
|
182
|
+
to bind a separate form schema whose output is assignable to the contract body
|
|
183
|
+
input. The selected schema input must be an object with named fields. Scalar
|
|
184
|
+
and array bodies require an explicit object-input form schema that produces
|
|
185
|
+
the request shape. Contracts without a body are rejected.
|
|
184
186
|
|
|
185
187
|
```ts
|
|
186
188
|
const adapter = rhf(createTodo);
|
|
@@ -188,13 +190,14 @@ const adapter = rhf(createTodo);
|
|
|
188
190
|
|
|
189
191
|
### `adapter.useForm(props?)`
|
|
190
192
|
|
|
191
|
-
Returns a React Hook Form `useForm` result with the
|
|
193
|
+
Returns a React Hook Form `useForm` result with the selected schema as resolver.
|
|
192
194
|
|
|
193
195
|
```ts
|
|
194
196
|
const form = adapter.useForm({
|
|
195
|
-
defaultValues
|
|
196
|
-
resolverEnabled
|
|
197
|
-
//
|
|
197
|
+
defaultValues: { title: "" },
|
|
198
|
+
resolverEnabled: true, // default
|
|
199
|
+
submitValues: "parsed", // default; use "raw" for original input
|
|
200
|
+
mode: "onBlur",
|
|
198
201
|
});
|
|
199
202
|
```
|
|
200
203
|
|
|
@@ -217,87 +220,102 @@ form.setError(
|
|
|
217
220
|
|
|
218
221
|
## Type inference
|
|
219
222
|
|
|
220
|
-
|
|
221
|
-
input
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
223
|
+
- Live fields (`register`, `watch`, `setValue`, `getValues`, `defaultValues`)
|
|
224
|
+
use the selected schema's **input**.
|
|
225
|
+
- `handleSubmit` receives parsed schema **output** by default, including
|
|
226
|
+
transforms, defaults, and removal of unknown keys. Live field state is unchanged.
|
|
227
|
+
- `submitValues: "raw"` validates but returns the original submitted snapshot.
|
|
228
|
+
- `resolverEnabled: false` returns unparsed input. Explicit parsed mode requires
|
|
229
|
+
the generated resolver. A dynamic or optional enable flag returns an input/output union.
|
|
230
|
+
- A custom `resolver` owns its output type, even when generation is disabled.
|
|
231
|
+
It cannot be combined with `submitValues`.
|
|
232
|
+
- Both adapter methods accept forwarded `UseFormProps` and optional resolvers.
|
|
233
|
+
An absent override falls back to the generated resolver, or unparsed input
|
|
234
|
+
when generation is disabled. Submit types include every possible output.
|
|
235
|
+
An `undefined` options object uses generated validation and parsed output.
|
|
236
|
+
- Conditional configurations may choose a custom resolver or a generated mode;
|
|
237
|
+
submit types include each branch's output. A single configuration cannot set
|
|
238
|
+
both `resolver` and `submitValues`. If the whole options object may be absent,
|
|
239
|
+
returned properties such as `defaultValues` and `mode` are optional too.
|
|
240
|
+
|
|
241
|
+
### Reuse the contract schema
|
|
242
|
+
|
|
243
|
+
For a number-valued API, use `z.number()` in the contract and configure the
|
|
244
|
+
numeric field with `register("amount", { valueAsNumber: true })`. Submit parsed
|
|
245
|
+
callback values to the typed client; the client sends supplied input unchanged
|
|
246
|
+
and the server independently validates it.
|
|
247
|
+
|
|
248
|
+
Use `z.coerce.number()` in a shared contract when the API intentionally accepts
|
|
249
|
+
numeric strings too. Reusing transforming schemas is appropriate only when
|
|
250
|
+
parsed values remain valid request inputs and parsing again preserves their
|
|
251
|
+
meaning. `z.string().transform(Number)` cannot parse its numeric output; even
|
|
252
|
+
same-type transforms can change a value again. Use a separate form schema for
|
|
253
|
+
such UI conversions, or raw mode to submit original contract input.
|
|
254
|
+
|
|
255
|
+
### Bind a separate form schema
|
|
231
256
|
|
|
232
257
|
```ts
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
.responses({ 200: TodoSchema });
|
|
258
|
+
import { defineContract } from "@beignet/core/contracts";
|
|
259
|
+
import { createReactHookForm } from "@beignet/react-hook-form";
|
|
260
|
+
import { z } from "zod";
|
|
237
261
|
|
|
238
|
-
const
|
|
239
|
-
|
|
262
|
+
const paymentBody = z.object({
|
|
263
|
+
amount: z.number().int().positive(),
|
|
264
|
+
currency: z.string().default("USD"),
|
|
265
|
+
});
|
|
266
|
+
const createPayment = defineContract({ method: "POST", path: "/api/payments" })
|
|
267
|
+
.body(paymentBody)
|
|
268
|
+
.responses({ 201: z.object({ id: z.string() }) });
|
|
269
|
+
const paymentFormSchema = paymentBody.extend({
|
|
270
|
+
amount: z.string().trim().regex(/^\d+$/)
|
|
271
|
+
.transform(Number)
|
|
272
|
+
.pipe(paymentBody.shape.amount),
|
|
240
273
|
});
|
|
241
|
-
```
|
|
242
274
|
|
|
243
|
-
```ts
|
|
244
|
-
// Contract definition
|
|
245
|
-
const createTodo = todos
|
|
246
|
-
.post("/api/todos")
|
|
247
|
-
.body(z.object({
|
|
248
|
-
title: z.string().min(1),
|
|
249
|
-
description: z.string().optional(),
|
|
250
|
-
completed: z.boolean().optional(),
|
|
251
|
-
}))
|
|
252
|
-
.responses({ 201: TodoSchema });
|
|
253
|
-
|
|
254
|
-
// Form values are inferred
|
|
255
275
|
const rhf = createReactHookForm();
|
|
256
|
-
const
|
|
257
|
-
form.
|
|
258
|
-
form.register("description"); // ✓ Valid
|
|
259
|
-
form.register("invalid"); // ✗ Type error
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
For plain schemas like the one above, input and output are identical. For
|
|
263
|
-
coercing or transforming schemas they differ:
|
|
276
|
+
const paymentForm = rhf(createPayment, { schema: paymentFormSchema });
|
|
277
|
+
const form = paymentForm.useForm({ defaultValues: { amount: "" } });
|
|
264
278
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
.
|
|
268
|
-
|
|
269
|
-
amount: z.string().transform(Number),
|
|
270
|
-
note: z.string().optional(),
|
|
271
|
-
}))
|
|
272
|
-
.responses({ 201: PaymentSchema });
|
|
273
|
-
|
|
274
|
-
const form = rhf(createPayment).useForm({
|
|
275
|
-
defaultValues: { amount: "" }, // input: string
|
|
279
|
+
form.watch("amount"); // string
|
|
280
|
+
form.handleSubmit((body) => {
|
|
281
|
+
body.amount; // number, matching the request body input
|
|
282
|
+
body.currency; // string, including the schema default
|
|
276
283
|
});
|
|
284
|
+
```
|
|
277
285
|
|
|
278
|
-
form
|
|
286
|
+
The form schema owns form validation; the adapter does not additionally run the
|
|
287
|
+
contract schema. Derive it from shared validators to keep runtime constraints
|
|
288
|
+
aligned. TypeScript rejects incompatible output shapes but cannot check every
|
|
289
|
+
runtime rule. Raw or disabled submissions use the form schema's input and may
|
|
290
|
+
need mapping before posting to the contract.
|
|
279
291
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
292
|
+
Use `defaultValues` for defaults the UI should display. Generated resolvers
|
|
293
|
+
copy plain objects, arrays, and dates before asynchronous validation, capturing
|
|
294
|
+
own getters once. Class instances, files, functions, and other opaque values
|
|
295
|
+
retain their identity; keep them immutable during validation and submission.
|
|
296
|
+
Custom resolvers own their validation and snapshot behavior.
|
|
284
297
|
|
|
285
|
-
###
|
|
298
|
+
### Options for React Hook Form wrappers
|
|
286
299
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
`
|
|
291
|
-
|
|
292
|
-
and TypeScript rejects it. Send the raw field values instead — validation has
|
|
293
|
-
already passed by the time the submit handler runs:
|
|
300
|
+
`formOptions(...)` returns options compatible with native `UseFormProps`,
|
|
301
|
+
`useForm`, and `createFormControl`, including with `exactOptionalPropertyTypes`
|
|
302
|
+
enabled. Input/output types match the adapter's `useForm`. Partial
|
|
303
|
+
`defaultValues` can narrow React Hook Form's own inference, so supply all three
|
|
304
|
+
generics in that case:
|
|
294
305
|
|
|
295
|
-
```
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
306
|
+
```ts
|
|
307
|
+
import { useForm } from "react-hook-form";
|
|
308
|
+
|
|
309
|
+
const form = useForm<
|
|
310
|
+
z.input<typeof paymentFormSchema>,
|
|
311
|
+
unknown,
|
|
312
|
+
z.output<typeof paymentFormSchema>
|
|
313
|
+
>(paymentForm.formOptions({ defaultValues: { amount: "" } }));
|
|
299
314
|
```
|
|
300
315
|
|
|
316
|
+
The adapter's `useForm` infers these automatically. Submit the callback's values
|
|
317
|
+
instead of rereading mutable field state through `getValues()`.
|
|
318
|
+
|
|
301
319
|
## Standard Schema support
|
|
302
320
|
|
|
303
321
|
This package uses the `@hookform/resolvers/standard-schema` resolver, which works with any Standard Schema compatible library:
|
package/dist/index.d.ts
CHANGED
|
@@ -1,77 +1,135 @@
|
|
|
1
1
|
import { type ErrorMessageOverrides } from "@beignet/core/client";
|
|
2
2
|
import { type ContractLike, type HttpContractConfig, type InferInput, type InferOutput, type ResolveContract, type StandardSchemaV1 } from "@beignet/core/contracts";
|
|
3
|
-
import { type FieldValues, type UseFormProps, type UseFormReturn } from "react-hook-form";
|
|
3
|
+
import { type FieldValues, type Resolver, type UseFormProps, type UseFormReturn } from "react-hook-form";
|
|
4
4
|
/**
|
|
5
5
|
* Keep only object-shaped React Hook Form field values. Arrays are objects in
|
|
6
6
|
* JavaScript, but they do not define the named field-value record expected by
|
|
7
7
|
* this adapter.
|
|
8
8
|
*/
|
|
9
9
|
type ObjectFieldValues<T> = [T] extends [FieldValues] ? Extract<T, readonly unknown[]> extends never ? T : never : never;
|
|
10
|
-
/**
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
*/
|
|
33
|
-
type RhfFormOptions<TContract extends HttpContractConfig> = Omit<UseFormProps<FormInput<TContract>, unknown, FormOutput<TContract>>, "resolver"> & {
|
|
34
|
-
/**
|
|
35
|
-
* Optional override for the resolver. If supplied, this is used instead of
|
|
36
|
-
* the default contract-based resolver.
|
|
37
|
-
*/
|
|
38
|
-
resolver?: UseFormProps<FormInput<TContract>, unknown, FormOutput<TContract>>["resolver"];
|
|
39
|
-
/**
|
|
40
|
-
* Enables or disables automatic resolver generation from the contract body schema.
|
|
41
|
-
* Defaults to true.
|
|
42
|
-
*/
|
|
10
|
+
/** Live fields and defaults use the selected schema's input. */
|
|
11
|
+
type FormInput<S extends StandardSchemaV1> = ObjectFieldValues<InferInput<S>>;
|
|
12
|
+
/** Parsed submissions use the selected schema's output. */
|
|
13
|
+
type FormOutput<S extends StandardSchemaV1> = InferOutput<S>;
|
|
14
|
+
type BodySchema<C extends HttpContractConfig> = Extract<C["body"], StandardSchemaV1>;
|
|
15
|
+
type ReactHookFormContract<T extends ContractLike> = [
|
|
16
|
+
FormInput<BodySchema<ResolveContract<T>>>
|
|
17
|
+
] extends [never] ? never : T;
|
|
18
|
+
/** A form-specific schema produces the request input accepted by the contract. */
|
|
19
|
+
type CompatibleFormSchema<C extends HttpContractConfig, S extends StandardSchemaV1> = [BodySchema<C>] extends [never] ? never : [FormInput<S>] extends [never] ? never : [FormOutput<S>] extends [InferInput<BodySchema<C>>] ? S : never;
|
|
20
|
+
type RhfFormOptions<S extends StandardSchemaV1, Output> = Omit<UseFormProps<FormInput<S>, unknown, Output>, "resolver">;
|
|
21
|
+
type ParsedFormOptions<S extends StandardSchemaV1> = RhfFormOptions<S, FormOutput<S>> & {
|
|
22
|
+
/** Submit parsed schema output. Default: parsed. Requires the generated resolver. */
|
|
23
|
+
submitValues?: "parsed";
|
|
24
|
+
resolver?: undefined;
|
|
25
|
+
/** Generate the schema resolver. Default: true. */
|
|
26
|
+
resolverEnabled?: true;
|
|
27
|
+
};
|
|
28
|
+
type RawFormOptions<S extends StandardSchemaV1> = RhfFormOptions<S, FormInput<S>> & {
|
|
29
|
+
/** Validate with the selected schema and submit original input. */
|
|
30
|
+
submitValues: "raw";
|
|
31
|
+
resolver?: undefined;
|
|
43
32
|
resolverEnabled?: boolean;
|
|
44
33
|
};
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
34
|
+
type DisabledFormOptions<S extends StandardSchemaV1> = RhfFormOptions<S, FormInput<S>> & {
|
|
35
|
+
resolverEnabled: false;
|
|
36
|
+
resolver?: undefined;
|
|
37
|
+
submitValues?: "raw";
|
|
38
|
+
};
|
|
39
|
+
type VariableFormOptions<S extends StandardSchemaV1> = RhfFormOptions<S, FormInput<S> | FormOutput<S>> & {
|
|
40
|
+
resolver?: undefined;
|
|
41
|
+
} & ({
|
|
42
|
+
submitValues?: "raw" | "parsed" | undefined;
|
|
43
|
+
resolverEnabled?: true;
|
|
44
|
+
} | {
|
|
45
|
+
submitValues?: "raw";
|
|
46
|
+
resolverEnabled?: boolean | undefined;
|
|
47
|
+
});
|
|
48
|
+
type CustomFormOptions<S extends StandardSchemaV1, Output> = RhfFormOptions<S, Output> & {
|
|
49
|
+
/** A custom resolver owns its submit output, independently of the schema. */
|
|
50
|
+
resolver: Resolver<FormInput<S>, unknown, Output>;
|
|
51
|
+
resolverEnabled?: boolean;
|
|
52
|
+
submitValues?: never;
|
|
53
|
+
};
|
|
54
|
+
type OptionalResolverFormOptions<S extends StandardSchemaV1, Output> = RhfFormOptions<S, Output> & {
|
|
55
|
+
resolver?: Resolver<FormInput<S>, unknown, Output> | undefined;
|
|
56
|
+
resolverEnabled?: boolean | undefined;
|
|
57
|
+
submitValues?: never;
|
|
58
|
+
};
|
|
59
|
+
type SuppliedResolverFormOptions<S extends StandardSchemaV1, Output> = OptionalResolverFormOptions<S, Output> & {
|
|
60
|
+
resolver: Resolver<FormInput<S>, unknown, Output> | undefined;
|
|
61
|
+
};
|
|
62
|
+
/** An absent override falls back to schema parsing unless generation is disabled. */
|
|
63
|
+
type ResolverFallbackOutput<S extends StandardSchemaV1, Props> = Props extends {
|
|
64
|
+
resolverEnabled: false;
|
|
65
|
+
} ? FormInput<S> : Props extends {
|
|
66
|
+
resolverEnabled?: infer Enabled;
|
|
67
|
+
} ? false extends Enabled ? FormInput<S> | FormOutput<S> : FormOutput<S> : FormOutput<S>;
|
|
68
|
+
type ResolverSubmitOutput<S extends StandardSchemaV1, Output, Props> = Props extends {
|
|
69
|
+
resolver: undefined;
|
|
70
|
+
} ? ResolverFallbackOutput<S, Props> : Props extends {
|
|
71
|
+
resolver: Resolver<FormInput<S>, unknown, Output>;
|
|
72
|
+
} ? Output : Output | ResolverFallbackOutput<S, Props>;
|
|
73
|
+
type ConditionalFormOptions<S extends StandardSchemaV1> = ParsedFormOptions<S> | RawFormOptions<S> | DisabledFormOptions<S> | VariableFormOptions<S> | OptionalResolverFormOptions<S, unknown>;
|
|
74
|
+
type GeneratedSubmitOutput<S extends StandardSchemaV1, Props> = Props extends {
|
|
75
|
+
submitValues: "raw";
|
|
76
|
+
} | {
|
|
77
|
+
resolverEnabled: false;
|
|
78
|
+
} ? FormInput<S> : Props extends {
|
|
79
|
+
submitValues?: infer Mode;
|
|
80
|
+
} ? "raw" extends Mode ? FormInput<S> | ResolverFallbackOutput<S, Props> : ResolverFallbackOutput<S, Props> : ResolverFallbackOutput<S, Props>;
|
|
81
|
+
type CustomSubmitOutput<S extends StandardSchemaV1, R> = R extends Resolver<FormInput<S>, unknown, infer Output> ? Output : never;
|
|
82
|
+
/** Distribute over configurations so each branch contributes only its own output. */
|
|
83
|
+
type ConditionalSubmitOutput<S extends StandardSchemaV1, Props> = Props extends undefined ? FormOutput<S> : Props extends {
|
|
84
|
+
resolver: infer R;
|
|
85
|
+
} ? undefined extends R ? CustomSubmitOutput<S, R> | GeneratedSubmitOutput<S, Props> : CustomSubmitOutput<S, R> : Props extends {
|
|
86
|
+
resolver?: infer R;
|
|
87
|
+
} ? CustomSubmitOutput<S, R> | GeneratedSubmitOutput<S, Props> : GeneratedSubmitOutput<S, Props>;
|
|
88
|
+
type SuppliedFormProps<Props> = undefined extends Props ? Partial<Exclude<Props, undefined>> : Props;
|
|
89
|
+
type FormOptions<Input extends FieldValues, Output, Props> = Omit<Props, "resolver" | "resolverEnabled" | "submitValues"> & Pick<UseFormProps<Input, unknown, Output>, "resolver">;
|
|
90
|
+
/** React Hook Form methods for the selected form schema. */
|
|
91
|
+
type ReactHookFormContractAdapterShape<S extends StandardSchemaV1> = {
|
|
92
|
+
/** Generate options for React Hook Form or a wrapper. */
|
|
93
|
+
formOptions: {
|
|
94
|
+
(props?: undefined): FormOptions<FormInput<S>, FormOutput<S>, Record<never, never>>;
|
|
95
|
+
<Output, Props extends SuppliedResolverFormOptions<S, Output>>(props: SuppliedResolverFormOptions<S, Output> & Props): FormOptions<FormInput<S>, ResolverSubmitOutput<S, Output, Props>, Props>;
|
|
96
|
+
<Props extends RawFormOptions<S> | DisabledFormOptions<S>>(props: Props): FormOptions<FormInput<S>, FormInput<S>, Props>;
|
|
97
|
+
<Props extends ParsedFormOptions<S>>(props: Props): FormOptions<FormInput<S>, FormOutput<S>, Props>;
|
|
98
|
+
<Props extends VariableFormOptions<S>>(props: Props): FormOptions<FormInput<S>, FormInput<S> | FormOutput<S>, Props>;
|
|
99
|
+
<Output, Props extends OptionalResolverFormOptions<S, Output>>(props: OptionalResolverFormOptions<S, Output> & Props): FormOptions<FormInput<S>, Output | ResolverFallbackOutput<S, Props>, Props>;
|
|
100
|
+
<Props extends ParsedFormOptions<S>>(props?: Props): FormOptions<FormInput<S>, FormOutput<S>, Partial<Props>>;
|
|
101
|
+
<Props extends VariableFormOptions<S>>(props: Props | undefined): FormOptions<FormInput<S>, FormInput<S> | FormOutput<S>, Partial<Props>>;
|
|
102
|
+
<Output, Props extends OptionalResolverFormOptions<S, Output>>(props: (OptionalResolverFormOptions<S, Output> & Props) | undefined): FormOptions<FormInput<S>, ResolverSubmitOutput<S, Output, Props> | FormOutput<S>, Partial<Props>>;
|
|
103
|
+
<Props extends ConditionalFormOptions<S> | undefined>(props: Props): FormOptions<FormInput<S>, ConditionalSubmitOutput<S, Props>, SuppliedFormProps<Props>>;
|
|
104
|
+
};
|
|
105
|
+
/** Convenience wrapper around useForm(formOptions(props)). */
|
|
106
|
+
useForm: {
|
|
107
|
+
<Output>(props: CustomFormOptions<S, Output>): UseFormReturn<FormInput<S>, unknown, Output>;
|
|
108
|
+
(props: RawFormOptions<S> | DisabledFormOptions<S>): UseFormReturn<FormInput<S>, unknown, FormInput<S>>;
|
|
109
|
+
(props?: ParsedFormOptions<S>): UseFormReturn<FormInput<S>, unknown, FormOutput<S>>;
|
|
110
|
+
(props?: VariableFormOptions<S>): UseFormReturn<FormInput<S>, unknown, FormInput<S> | FormOutput<S>>;
|
|
111
|
+
<Output, Props extends OptionalResolverFormOptions<S, Output>>(props: OptionalResolverFormOptions<S, Output> & Props): UseFormReturn<FormInput<S>, unknown, Output | ResolverFallbackOutput<S, Props>>;
|
|
112
|
+
<Output, Props extends OptionalResolverFormOptions<S, Output>>(props: (OptionalResolverFormOptions<S, Output> & Props) | undefined): UseFormReturn<FormInput<S>, unknown, ResolverSubmitOutput<S, Output, Props> | FormOutput<S>>;
|
|
113
|
+
<Props extends ConditionalFormOptions<S> | undefined>(props: Props): UseFormReturn<FormInput<S>, unknown, ConditionalSubmitOutput<S, Props>>;
|
|
114
|
+
};
|
|
57
115
|
};
|
|
58
116
|
/**
|
|
59
|
-
*
|
|
60
|
-
* object-shaped.
|
|
117
|
+
* Adapter for a contract body, optionally using a separate form schema.
|
|
118
|
+
* The selected schema must have object-shaped input for named form fields.
|
|
61
119
|
*/
|
|
62
|
-
export type ReactHookFormContractAdapter<TContract extends HttpContractConfig
|
|
63
|
-
FormInput<TContract>
|
|
64
|
-
] extends [never] ? never : ReactHookFormContractAdapterShape<TContract>;
|
|
120
|
+
export type ReactHookFormContractAdapter<TContract extends HttpContractConfig, TSchema extends StandardSchemaV1 = BodySchema<TContract>> = [BodySchema<TContract>] extends [never] ? never : [FormInput<TSchema>] extends [never] ? never : ReactHookFormContractAdapterShape<TSchema>;
|
|
65
121
|
/**
|
|
66
|
-
* Create a React Hook Form adapter factory.
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
* Contracts must declare a body schema whose input is object-shaped. After
|
|
71
|
-
* binding, callers may override or disable the generated resolver through
|
|
72
|
-
* `formOptions(...)` or `useForm(...)`.
|
|
122
|
+
* Create a React Hook Form adapter factory. Bind a contract with rhf(contract),
|
|
123
|
+
* or pass { schema } when the form's input differs from the request body.
|
|
124
|
+
* A separate schema must have object-shaped input and output assignable to the
|
|
125
|
+
* contract body input. Parsed submissions are the default; raw mode is opt-in.
|
|
73
126
|
*/
|
|
74
|
-
export declare function createReactHookForm():
|
|
127
|
+
export declare function createReactHookForm(): {
|
|
128
|
+
<TContractLike extends ContractLike>(contract: ReactHookFormContract<TContractLike>): ReactHookFormContractAdapter<ResolveContract<TContractLike>>;
|
|
129
|
+
<TContractLike extends ContractLike, TSchema extends StandardSchemaV1>(contract: TContractLike, options: {
|
|
130
|
+
schema: CompatibleFormSchema<ResolveContract<TContractLike>, TSchema>;
|
|
131
|
+
}): ReactHookFormContractAdapter<ResolveContract<TContractLike>, TSchema>;
|
|
132
|
+
};
|
|
75
133
|
/**
|
|
76
134
|
* Root-level form error for `form.setError("root", ...)`.
|
|
77
135
|
*/
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACvB,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,eAAe,EAEpB,KAAK,gBAAgB,EACtB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,KAAK,WAAW,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -3,22 +3,42 @@ import { contractErrorMessage, } from "@beignet/core/client";
|
|
|
3
3
|
import { resolveContract, } from "@beignet/core/contracts";
|
|
4
4
|
import { standardSchemaResolver } from "@hookform/resolvers/standard-schema";
|
|
5
5
|
import { useForm as rhfUseForm, } from "react-hook-form";
|
|
6
|
-
|
|
6
|
+
import { snapshotInput } from "./input-snapshot.js";
|
|
7
|
+
function createReactHookFormAdapter(contract, schema) {
|
|
7
8
|
const resolvedContract = resolveContract(contract);
|
|
8
9
|
if (!resolvedContract.body) {
|
|
9
10
|
throw new Error(`rhf(${resolvedContract.name}): Contract has no body schema. ` +
|
|
10
11
|
"React Hook Form requires a body schema to generate form fields and validation. " +
|
|
11
12
|
"Use .body(schema) on the contract builder to define the request body shape.");
|
|
12
13
|
}
|
|
14
|
+
const formSchema = (schema ?? resolvedContract.body);
|
|
13
15
|
function formOptions(props) {
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
const { resolverEnabled = true, resolver: resolverOverride, submitValues = "parsed", ...rest } = props ?? {};
|
|
17
|
+
if (resolverOverride && props?.submitValues !== undefined) {
|
|
18
|
+
throw new Error(`rhf(${resolvedContract.name}): A custom resolver owns its submit values; omit submitValues.`);
|
|
19
|
+
}
|
|
20
|
+
if (props?.submitValues === "parsed" &&
|
|
21
|
+
!resolverEnabled &&
|
|
22
|
+
!resolverOverride) {
|
|
23
|
+
throw new Error(`rhf(${resolvedContract.name}): Parsed submit values require the generated resolver.`);
|
|
24
|
+
}
|
|
25
|
+
let resolver = resolverOverride;
|
|
26
|
+
if (!resolver && resolverEnabled) {
|
|
27
|
+
const generated = submitValues === "parsed"
|
|
28
|
+
? standardSchemaResolver(formSchema)
|
|
29
|
+
: standardSchemaResolver(formSchema, undefined, { raw: true });
|
|
30
|
+
resolver = async (values, context, options) => {
|
|
31
|
+
// Capture data containers before asynchronous validation.
|
|
32
|
+
const snapshot = snapshotInput(values);
|
|
33
|
+
const result = await generated(submitValues === "raw" ? snapshotInput(snapshot) : snapshot, context, options);
|
|
34
|
+
return submitValues === "raw" && Object.keys(result.errors).length === 0
|
|
35
|
+
? { errors: {}, values: snapshot }
|
|
36
|
+
: result;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
20
39
|
return {
|
|
21
40
|
...rest,
|
|
41
|
+
// RHF merges options on rerender; an explicit undefined clears an old resolver.
|
|
22
42
|
resolver,
|
|
23
43
|
};
|
|
24
44
|
}
|
|
@@ -29,18 +49,16 @@ function createReactHookFormAdapter(contract) {
|
|
|
29
49
|
return { formOptions, useForm };
|
|
30
50
|
}
|
|
31
51
|
/**
|
|
32
|
-
* Create a React Hook Form adapter factory.
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* Contracts must declare a body schema whose input is object-shaped. After
|
|
37
|
-
* binding, callers may override or disable the generated resolver through
|
|
38
|
-
* `formOptions(...)` or `useForm(...)`.
|
|
52
|
+
* Create a React Hook Form adapter factory. Bind a contract with rhf(contract),
|
|
53
|
+
* or pass { schema } when the form's input differs from the request body.
|
|
54
|
+
* A separate schema must have object-shaped input and output assignable to the
|
|
55
|
+
* contract body input. Parsed submissions are the default; raw mode is opt-in.
|
|
39
56
|
*/
|
|
40
57
|
export function createReactHookForm() {
|
|
41
|
-
|
|
42
|
-
return createReactHookFormAdapter(contract);
|
|
43
|
-
}
|
|
58
|
+
function rhf(contract, options) {
|
|
59
|
+
return createReactHookFormAdapter(contract, options?.schema);
|
|
60
|
+
}
|
|
61
|
+
return rhf;
|
|
44
62
|
}
|
|
45
63
|
/**
|
|
46
64
|
* Map a failed endpoint call or mutation error to a root-level form error.
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EACL,oBAAoB,GAErB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAML,eAAe,GAEhB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAC7E,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Snapshot data containers without manufacturing invalid copies of opaque
|
|
3
|
+
* instances (which may depend on private fields or native internal slots).
|
|
4
|
+
* Opaque instances and functions remain references and must be treated as immutable.
|
|
5
|
+
*/
|
|
6
|
+
export declare function snapshotInput<T>(input: T): T;
|
|
7
|
+
//# sourceMappingURL=input-snapshot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input-snapshot.d.ts","sourceRoot":"","sources":["../src/input-snapshot.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAoC5C"}
|