@zod-utils/react-hook-form 0.1.0 → 0.2.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/dist/index.d.ts CHANGED
@@ -1,66 +1,229 @@
1
+ export * from '@zod-utils/core';
1
2
  import * as react_hook_form from 'react-hook-form';
2
3
  import { FieldValues, DefaultValues, UseFormProps } from 'react-hook-form';
3
4
  import { zodResolver } from '@hookform/resolvers/zod';
4
- import { MakeOptionalAndNullable } from '@zod-utils/core';
5
- export * from '@zod-utils/core';
6
- import { ZodTypeAny, ZodErrorMap } from 'zod';
5
+ import { z } from 'zod';
6
+
7
+ /**
8
+ * Transforms all properties in a type to be optional and nullable.
9
+ *
10
+ * This type utility is the secret sauce behind `useZodForm`'s type transformation.
11
+ * It makes form inputs accept `null | undefined` during editing, while validated
12
+ * output remains exactly as the schema defines.
13
+ *
14
+ * **Why this matters:**
15
+ * - React Hook Form fields often contain `null` or `undefined` during user input
16
+ * - Zod schemas define strict output types without these nullable/optional wrappers
17
+ * - This type bridges the gap, eliminating "Type 'null' is not assignable to..." errors
18
+ *
19
+ * @template T - The object type to transform
20
+ *
21
+ * @example
22
+ * Basic transformation
23
+ * ```typescript
24
+ * type User = {
25
+ * name: string;
26
+ * age: number;
27
+ * };
28
+ *
29
+ * type FormUser = MakeOptionalAndNullable<User>;
30
+ * // Result: {
31
+ * // name?: string | null;
32
+ * // age?: number | null;
33
+ * // }
34
+ * ```
35
+ *
36
+ * @example
37
+ * Usage with useZodForm
38
+ * ```typescript
39
+ * const schema = z.object({
40
+ * title: z.string(),
41
+ * count: z.number(),
42
+ * });
43
+ *
44
+ * const form = useZodForm({ schema });
45
+ *
46
+ * // ✅ These work without type errors:
47
+ * form.setValue('title', null); // Accepts null during editing
48
+ * form.setValue('title', undefined); // Accepts undefined
49
+ * form.reset({ title: null, count: null }); // Reset with null values
50
+ *
51
+ * // But validated output is still:
52
+ * // { title: string, count: number }
53
+ * ```
54
+ *
55
+ * @example
56
+ * Comparison with original type
57
+ * ```typescript
58
+ * type Schema = {
59
+ * email: string;
60
+ * isActive: boolean;
61
+ * };
62
+ *
63
+ * // Original: { email: string; isActive: boolean }
64
+ * // Transformed: { email?: string | null; isActive?: boolean | null }
65
+ *
66
+ * const original: Schema = { email: '', isActive: true }; // OK
67
+ * const original2: Schema = { email: null }; // ❌ Error
68
+ *
69
+ * const transformed: MakeOptionalAndNullable<Schema> = {}; // OK
70
+ * const transformed2: MakeOptionalAndNullable<Schema> = { email: null }; // OK
71
+ * ```
72
+ *
73
+ * @see {@link useZodForm} for how this type is used in practice
74
+ * @since 0.1.0
75
+ */
76
+ type MakeOptionalAndNullable<T> = {
77
+ [K in keyof T]?: T[K] | null;
78
+ };
7
79
 
8
80
  /**
9
- * Type-safe wrapper around useForm with Zod v4 schema integration
10
- * Automatically sets up zodResolver and provides better type inference
81
+ * Type-safe React Hook Form wrapper with automatic Zod v4 schema validation and type transformation.
82
+ *
83
+ * This hook eliminates the TypeScript friction between React Hook Form's nullable field values
84
+ * and Zod's strict output types. It uses a two-type schema pattern where:
85
+ * - **Input type** (`MakeOptionalAndNullable<T>`): Form fields accept `null | undefined` during editing
86
+ * - **Output type** (`T`): Validated data matches exact schema type (no `null | undefined`)
87
+ *
88
+ * **Key Benefits:**
89
+ * - ✅ No more "Type 'null' is not assignable to..." TypeScript errors
90
+ * - ✅ Use `form.setValue()` and `form.reset()` with `null` values freely
91
+ * - ✅ Validated output is still type-safe with exact Zod schema types
92
+ * - ✅ Automatic zodResolver setup - no manual configuration needed
93
+ *
94
+ * @template T - The Zod schema output type (extends FieldValues)
95
+ *
96
+ * @param options - Configuration object
97
+ * @param options.schema - Zod schema with two-type signature `z.ZodType<T, MakeOptionalAndNullable<T>>`
98
+ * @param options.defaultValues - Default form values (accepts nullable/undefined values)
99
+ * @param options.zodResolverOptions - Optional zodResolver configuration
100
+ * @param options....formOptions - All other react-hook-form useForm options
101
+ *
102
+ * @returns React Hook Form instance with type-safe methods
103
+ *
104
+ * @example
105
+ * Basic usage with required fields
106
+ * ```typescript
107
+ * import { useZodForm } from '@zod-utils/react-hook-form';
108
+ * import { z } from 'zod';
109
+ *
110
+ * const schema = z.object({
111
+ * name: z.string().min(1), // Required field
112
+ * age: z.number().min(0),
113
+ * }) satisfies z.ZodType<{ name: string; age: number }, any>;
114
+ *
115
+ * function MyForm() {
116
+ * const form = useZodForm({ schema });
117
+ *
118
+ * // ✅ These work without type errors:
119
+ * form.setValue('name', null); // Accepts null during editing
120
+ * form.reset({ name: null, age: null }); // Reset with null
121
+ *
122
+ * const onSubmit = (data: { name: string; age: number }) => {
123
+ * // ✅ data is exact type - no null | undefined
124
+ * console.log(data.name.toUpperCase()); // Safe to use string methods
125
+ * };
126
+ *
127
+ * return <form onSubmit={form.handleSubmit(onSubmit)}>...</form>;
128
+ * }
129
+ * ```
11
130
  *
12
131
  * @example
13
- * ```ts
132
+ * With default values
133
+ * ```typescript
14
134
  * const schema = z.object({
15
- * name: z.string(),
16
- * age: z.number()
135
+ * username: z.string(),
136
+ * email: z.string().email(),
137
+ * notifications: z.boolean().default(true),
138
+ * }) satisfies z.ZodType<{
139
+ * username: string;
140
+ * email: string;
141
+ * notifications: boolean;
142
+ * }, any>;
143
+ *
144
+ * const form = useZodForm({
145
+ * schema,
146
+ * defaultValues: {
147
+ * username: '',
148
+ * email: '',
149
+ * // notifications gets default from schema
150
+ * },
17
151
  * });
152
+ * ```
153
+ *
154
+ * @example
155
+ * With optional and nullable fields
156
+ * ```typescript
157
+ * const schema = z.object({
158
+ * title: z.string(),
159
+ * description: z.string().optional(), // Optional in output
160
+ * tags: z.array(z.string()).nullable(), // Nullable in output
161
+ * }) satisfies z.ZodType<{
162
+ * title: string;
163
+ * description?: string;
164
+ * tags: string[] | null;
165
+ * }, any>;
166
+ *
167
+ * const form = useZodForm({ schema });
18
168
  *
169
+ * // All fields accept null/undefined during editing
170
+ * form.setValue('title', null);
171
+ * form.setValue('description', undefined);
172
+ * form.setValue('tags', null);
173
+ * ```
174
+ *
175
+ * @example
176
+ * With zodResolver options
177
+ * ```typescript
19
178
  * const form = useZodForm({
20
179
  * schema,
21
- * defaultValues: { name: '', age: 0 }
180
+ * zodResolverOptions: {
181
+ * async: true, // Enable async validation
182
+ * errorMap: customErrorMap, // Custom error messages
183
+ * },
22
184
  * });
23
185
  * ```
186
+ *
187
+ * @example
188
+ * Complete form example
189
+ * ```typescript
190
+ * const userSchema = z.object({
191
+ * name: z.string().min(1, 'Name is required'),
192
+ * email: z.string().email('Invalid email'),
193
+ * age: z.number().min(18, 'Must be 18+'),
194
+ * }) satisfies z.ZodType<{ name: string; email: string; age: number }, any>;
195
+ *
196
+ * function UserForm() {
197
+ * const form = useZodForm({
198
+ * schema: userSchema,
199
+ * defaultValues: { name: '', email: '', age: null },
200
+ * });
201
+ *
202
+ * const onSubmit = (data: { name: string; email: string; age: number }) => {
203
+ * // Type-safe: data has exact types, no null/undefined
204
+ * console.log(`${data.name} is ${data.age} years old`);
205
+ * };
206
+ *
207
+ * return (
208
+ * <form onSubmit={form.handleSubmit(onSubmit)}>
209
+ * <input {...form.register('name')} />
210
+ * <input {...form.register('email')} type="email" />
211
+ * <input {...form.register('age', { valueAsNumber: true })} type="number" />
212
+ * <button type="submit">Submit</button>
213
+ * </form>
214
+ * );
215
+ * }
216
+ * ```
217
+ *
218
+ * @see {@link MakeOptionalAndNullable} for the type transformation utility
219
+ * @see https://react-hook-form.com/docs/useform for React Hook Form documentation
220
+ * @see https://zod.dev for Zod schema documentation
221
+ * @since 0.1.0
24
222
  */
25
223
  declare const useZodForm: <T extends FieldValues>({ schema, zodResolverOptions, ...formOptions }: {
26
- schema: ZodTypeAny;
224
+ schema: z.ZodType<T, MakeOptionalAndNullable<T>>;
27
225
  defaultValues?: DefaultValues<MakeOptionalAndNullable<T>>;
28
226
  zodResolverOptions?: Parameters<typeof zodResolver>[1];
29
- } & Omit<UseFormProps<MakeOptionalAndNullable<T>, unknown, T>, "resolver" | "defaultValues">) => react_hook_form.UseFormReturn<any, unknown, any>;
30
-
31
- /**
32
- * Japanese error map for Zod validation errors
33
- * @param fieldName - Optional custom field name to use in error messages
34
- * @returns Zod error map function
35
- */
36
- declare function createJapaneseErrorMap(fieldName?: string): (issue: Parameters<ZodErrorMap>[0]) => string;
37
-
38
- /**
39
- * English error map for Zod validation errors
40
- * @param fieldName - Optional custom field name to use in error messages
41
- * @returns Zod error map function
42
- */
43
- declare function createEnglishErrorMap(fieldName?: string): (issue: Parameters<ZodErrorMap>[0]) => string;
44
-
45
- /**
46
- * Field namespace mapping for custom error messages
47
- * You can extend this mapping to customize field names in error messages
48
- */
49
- declare const FieldNamespaceMapping: {
50
- department: {
51
- groupName: string;
52
- };
53
- };
54
- type FIELD_NAMESPACE = keyof typeof FieldNamespaceMapping;
55
- /**
56
- * Custom error resolver with field namespace support (Japanese locale)
57
- * @deprecated Use createJapaneseErrorMap or createEnglishErrorMap instead
58
- * @param options - Configuration options
59
- * @param options.fieldNamespace - Namespace for field name mappings
60
- * @returns Error resolver function
61
- */
62
- declare const customErrorResolver: ({ fieldNamespace, }: {
63
- fieldNamespace: FIELD_NAMESPACE;
64
- }) => (issue: Parameters<ZodErrorMap>[0]) => string;
227
+ } & Omit<UseFormProps<MakeOptionalAndNullable<T>, unknown, T>, "resolver" | "defaultValues">) => react_hook_form.UseFormReturn<MakeOptionalAndNullable<T>, unknown, T>;
65
228
 
66
- export { type FIELD_NAMESPACE, FieldNamespaceMapping, createEnglishErrorMap, createJapaneseErrorMap, customErrorResolver, useZodForm };
229
+ export { type MakeOptionalAndNullable, useZodForm };
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
+ var core = require('@zod-utils/core');
3
4
  var zod = require('@hookform/resolvers/zod');
4
5
  var reactHookForm = require('react-hook-form');
5
- var core = require('@zod-utils/core');
6
6
 
7
7
  var __defProp = Object.defineProperty;
8
8
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
@@ -46,286 +46,6 @@ var useZodForm = (_a) => {
46
46
  }, formOptions));
47
47
  };
48
48
 
49
- // src/locales/ja.ts
50
- var Nouns = {
51
- regex: "\u5165\u529B\u5024",
52
- email: "\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9",
53
- url: "URL",
54
- emoji: "\u7D75\u6587\u5B57",
55
- uuid: "UUID",
56
- uuidv4: "UUIDv4",
57
- uuidv6: "UUIDv6",
58
- nanoid: "nanoid",
59
- guid: "GUID",
60
- cuid: "cuid",
61
- cuid2: "cuid2",
62
- ulid: "ULID",
63
- xid: "XID",
64
- ksuid: "KSUID",
65
- datetime: "ISO\u65E5\u6642",
66
- date: "ISO\u65E5\u4ED8",
67
- time: "ISO\u6642\u523B",
68
- duration: "ISO\u671F\u9593",
69
- ipv4: "IPv4\u30A2\u30C9\u30EC\u30B9",
70
- ipv6: "IPv6\u30A2\u30C9\u30EC\u30B9",
71
- cidrv4: "IPv4\u7BC4\u56F2",
72
- cidrv6: "IPv6\u7BC4\u56F2",
73
- base64: "base64\u30A8\u30F3\u30B3\u30FC\u30C9\u6587\u5B57\u5217",
74
- base64url: "base64url\u30A8\u30F3\u30B3\u30FC\u30C9\u6587\u5B57\u5217",
75
- json_string: "JSON\u6587\u5B57\u5217",
76
- e164: "E.164\u756A\u53F7",
77
- jwt: "JWT",
78
- template_literal: "\u5165\u529B\u5024"
79
- };
80
- function stringifyPrimitive(value) {
81
- if (typeof value === "bigint") return `${value.toString()}n`;
82
- if (typeof value === "string") return `"${value}"`;
83
- return `${value}`;
84
- }
85
- function joinValues(array, separator = "\u3001") {
86
- return array.map((val) => stringifyPrimitive(val)).join(separator);
87
- }
88
- var Sizable = {
89
- string: { unit: "\u6587\u5B57", verb: "\u3067\u3042\u308B" },
90
- file: { unit: "\u30D0\u30A4\u30C8", verb: "\u3067\u3042\u308B" },
91
- array: { unit: "\u8981\u7D20", verb: "\u3067\u3042\u308B" },
92
- set: { unit: "\u8981\u7D20", verb: "\u3067\u3042\u308B" }
93
- };
94
- function getSizing(origin) {
95
- var _a;
96
- return (_a = Sizable[origin]) != null ? _a : null;
97
- }
98
- function parsedType(data) {
99
- const t = typeof data;
100
- switch (t) {
101
- case "number": {
102
- return Number.isNaN(data) ? "NaN" : "\u6570\u5024";
103
- }
104
- case "object": {
105
- if (Array.isArray(data)) {
106
- return "\u914D\u5217";
107
- }
108
- if (data === null) {
109
- return "null";
110
- }
111
- if (Object.getPrototypeOf(data) !== Object.prototype && data && data.constructor) {
112
- return data.constructor.name;
113
- }
114
- }
115
- }
116
- return t;
117
- }
118
- function createJapaneseErrorMap(fieldName) {
119
- return (issue) => {
120
- var _a;
121
- const field = fieldName || "\u3053\u306E\u9805\u76EE";
122
- switch (issue.code) {
123
- case "custom": {
124
- return "\u7121\u52B9\u306A\u5165\u529B";
125
- }
126
- case "invalid_type":
127
- return `\u7121\u52B9\u306A\u5165\u529B: ${issue.expected}\u304C\u671F\u5F85\u3055\u308C\u307E\u3057\u305F\u304C\u3001${parsedType(issue.input)}\u304C\u5165\u529B\u3055\u308C\u307E\u3057\u305F`;
128
- case "invalid_value":
129
- if (issue.values.length === 1)
130
- return `\u7121\u52B9\u306A\u5165\u529B: ${stringifyPrimitive(issue.values[0])}\u304C\u671F\u5F85\u3055\u308C\u307E\u3057\u305F`;
131
- return `\u7121\u52B9\u306A\u9078\u629E: ${joinValues(issue.values)}\u306E\u3044\u305A\u308C\u304B\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059`;
132
- case "too_big": {
133
- const adj = issue.inclusive ? "\u4EE5\u4E0B\u3067\u3042\u308B" : "\u3088\u308A\u5C0F\u3055\u3044";
134
- const sizing = getSizing(issue.origin);
135
- if (sizing)
136
- return `\u5927\u304D\u3059\u304E\u308B\u5024: ${field}\u306F${issue.maximum.toString()}${sizing.unit}${adj}\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059`;
137
- return `\u5927\u304D\u3059\u304E\u308B\u5024: ${field}\u306F${issue.maximum.toString()}${adj}\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059`;
138
- }
139
- case "too_small": {
140
- const adj = issue.inclusive ? "\u4EE5\u4E0A\u3067\u3042\u308B" : "\u3088\u308A\u5927\u304D\u3044";
141
- const sizing = getSizing(issue.origin);
142
- if (issue.minimum === 1) {
143
- return "\u5FC5\u9808\u9805\u76EE\u3067\u3059";
144
- }
145
- if (sizing)
146
- return `\u5C0F\u3055\u3059\u304E\u308B\u5024: ${field}\u306F${issue.minimum.toString()}${sizing.unit}${adj}\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059`;
147
- return `\u5C0F\u3055\u3059\u304E\u308B\u5024: ${field}\u306F${issue.minimum.toString()}${adj}\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059`;
148
- }
149
- case "invalid_format": {
150
- const _issue = issue;
151
- if (_issue.format === "starts_with")
152
- return `\u7121\u52B9\u306A\u6587\u5B57\u5217: "${_issue.prefix}"\u3067\u59CB\u307E\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059`;
153
- if (_issue.format === "ends_with")
154
- return `\u7121\u52B9\u306A\u6587\u5B57\u5217: "${_issue.suffix}"\u3067\u7D42\u308F\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059`;
155
- if (_issue.format === "includes")
156
- return `\u7121\u52B9\u306A\u6587\u5B57\u5217: "${_issue.includes}"\u3092\u542B\u3080\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059`;
157
- if (_issue.format === "regex")
158
- return `\u7121\u52B9\u306A\u6587\u5B57\u5217: \u30D1\u30BF\u30FC\u30F3${_issue.pattern}\u306B\u4E00\u81F4\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059`;
159
- return `\u7121\u52B9\u306A${(_a = Nouns[_issue.format]) != null ? _a : issue.format}`;
160
- }
161
- case "not_multiple_of":
162
- return `\u7121\u52B9\u306A\u6570\u5024: ${issue.divisor}\u306E\u500D\u6570\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059`;
163
- case "unrecognized_keys":
164
- return `\u8A8D\u8B58\u3055\u308C\u3066\u3044\u306A\u3044\u30AD\u30FC${issue.keys.length > 1 ? "\u7FA4" : ""}: ${joinValues(issue.keys)}`;
165
- case "invalid_key":
166
- return `${field}\u5185\u306E\u7121\u52B9\u306A\u30AD\u30FC`;
167
- case "invalid_union":
168
- return "\u7121\u52B9\u306A\u5165\u529B";
169
- case "invalid_element":
170
- return `${field}\u5185\u306E\u7121\u52B9\u306A\u5024`;
171
- default:
172
- return "\u7121\u52B9\u306A\u5165\u529B";
173
- }
174
- };
175
- }
176
-
177
- // src/locales/en.ts
178
- var Nouns2 = {
179
- regex: "input",
180
- email: "email address",
181
- url: "URL",
182
- emoji: "emoji",
183
- uuid: "UUID",
184
- uuidv4: "UUIDv4",
185
- uuidv6: "UUIDv6",
186
- nanoid: "nanoid",
187
- guid: "GUID",
188
- cuid: "cuid",
189
- cuid2: "cuid2",
190
- ulid: "ULID",
191
- xid: "XID",
192
- ksuid: "KSUID",
193
- datetime: "ISO datetime",
194
- date: "ISO date",
195
- time: "ISO time",
196
- duration: "ISO duration",
197
- ipv4: "IPv4 address",
198
- ipv6: "IPv6 address",
199
- cidrv4: "IPv4 CIDR",
200
- cidrv6: "IPv6 CIDR",
201
- base64: "base64 encoded string",
202
- base64url: "base64url encoded string",
203
- json_string: "JSON string",
204
- e164: "E.164 phone number",
205
- jwt: "JWT",
206
- template_literal: "input"
207
- };
208
- function stringifyPrimitive2(value) {
209
- if (typeof value === "bigint") return `${value.toString()}n`;
210
- if (typeof value === "string") return `"${value}"`;
211
- return `${value}`;
212
- }
213
- function joinValues2(array, separator = " | ") {
214
- return array.map((val) => stringifyPrimitive2(val)).join(separator);
215
- }
216
- var Sizable2 = {
217
- string: "character",
218
- file: "byte",
219
- array: "item",
220
- set: "item"
221
- };
222
- function getSizing2(origin) {
223
- var _a;
224
- return (_a = Sizable2[origin]) != null ? _a : null;
225
- }
226
- function parsedType2(data) {
227
- const t = typeof data;
228
- switch (t) {
229
- case "number": {
230
- return Number.isNaN(data) ? "NaN" : "number";
231
- }
232
- case "object": {
233
- if (Array.isArray(data)) {
234
- return "array";
235
- }
236
- if (data === null) {
237
- return "null";
238
- }
239
- if (Object.getPrototypeOf(data) !== Object.prototype && data && data.constructor) {
240
- return data.constructor.name;
241
- }
242
- }
243
- }
244
- return t;
245
- }
246
- function createEnglishErrorMap(fieldName) {
247
- return (issue) => {
248
- var _a;
249
- const field = fieldName || "This field";
250
- switch (issue.code) {
251
- case "custom": {
252
- return "Invalid input";
253
- }
254
- case "invalid_type":
255
- return `Invalid type: expected ${issue.expected}, received ${parsedType2(issue.input)}`;
256
- case "invalid_value":
257
- if (issue.values.length === 1)
258
- return `Invalid input: expected ${stringifyPrimitive2(issue.values[0])}`;
259
- return `Invalid option: must be one of ${joinValues2(issue.values)}`;
260
- case "too_big": {
261
- const unit = getSizing2(issue.origin);
262
- const plural = issue.maximum !== 1 ? "s" : "";
263
- if (unit) {
264
- return issue.inclusive ? `${field} must be at most ${issue.maximum} ${unit}${plural}` : `${field} must be less than ${issue.maximum} ${unit}${plural}`;
265
- }
266
- return issue.inclusive ? `${field} must be at most ${issue.maximum}` : `${field} must be less than ${issue.maximum}`;
267
- }
268
- case "too_small": {
269
- const unit = getSizing2(issue.origin);
270
- const plural = issue.minimum !== 1 ? "s" : "";
271
- if (issue.minimum === 1 && !unit) {
272
- return `${field} is required`;
273
- }
274
- if (unit) {
275
- return issue.inclusive ? `${field} must be at least ${issue.minimum} ${unit}${plural}` : `${field} must be greater than ${issue.minimum} ${unit}${plural}`;
276
- }
277
- return issue.inclusive ? `${field} must be at least ${issue.minimum}` : `${field} must be greater than ${issue.minimum}`;
278
- }
279
- case "invalid_format": {
280
- const _issue = issue;
281
- if (_issue.format === "starts_with")
282
- return `Invalid string: must start with "${_issue.prefix}"`;
283
- if (_issue.format === "ends_with")
284
- return `Invalid string: must end with "${_issue.suffix}"`;
285
- if (_issue.format === "includes")
286
- return `Invalid string: must include "${_issue.includes}"`;
287
- if (_issue.format === "regex")
288
- return `Invalid string: must match pattern ${_issue.pattern}`;
289
- return `Invalid ${(_a = Nouns2[_issue.format]) != null ? _a : _issue.format}`;
290
- }
291
- case "not_multiple_of":
292
- return `Invalid number: must be a multiple of ${issue.divisor}`;
293
- case "unrecognized_keys":
294
- return `Unrecognized key${issue.keys.length > 1 ? "s" : ""}: ${joinValues2(issue.keys)}`;
295
- case "invalid_key":
296
- return `Invalid key in ${field}`;
297
- case "invalid_union":
298
- return "Invalid input";
299
- case "invalid_element":
300
- return `Invalid value in ${field}`;
301
- default:
302
- return "Invalid input";
303
- }
304
- };
305
- }
306
-
307
- // src/error-map.ts
308
- var FieldNamespaceMapping = {
309
- department: {
310
- groupName: "\u90E8\u7F72\u30FB\u5E97\u8217\u540D"
311
- }
312
- };
313
- var customErrorResolver = ({
314
- fieldNamespace
315
- }) => {
316
- return (issue) => {
317
- var _a;
318
- const fieldName = FieldNamespaceMapping[fieldNamespace][String(
319
- (_a = issue.path) == null ? void 0 : _a[0]
320
- )] || void 0;
321
- return createJapaneseErrorMap(fieldName)(issue);
322
- };
323
- };
324
-
325
- exports.FieldNamespaceMapping = FieldNamespaceMapping;
326
- exports.createEnglishErrorMap = createEnglishErrorMap;
327
- exports.createJapaneseErrorMap = createJapaneseErrorMap;
328
- exports.customErrorResolver = customErrorResolver;
329
49
  exports.useZodForm = useZodForm;
330
50
  Object.keys(core).forEach(function (k) {
331
51
  if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/use-zod-form.ts","../src/locales/ja.ts","../src/locales/en.ts","../src/error-map.ts"],"names":["zodResolver","useForm","Nouns","stringifyPrimitive","joinValues","Sizable","getSizing","parsedType"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BO,IAAM,UAAA,GAAa,CAAwB,EAAA,KAW5C;AAX4C,EAAA,IAAA,EAAA,GAAA,EAAA,EAChD;AAAA,IAAA,MAAA;AAAA,IACA;AAAA,GA7BF,GA2BkD,EAAA,EAG7C,WAAA,GAAA,SAAA,CAH6C,EAAA,EAG7C;AAAA,IAFH,QAAA;AAAA,IACA;AAAA,GAAA,CAAA;AAWA,EAAA,MAAM,QAAA,GAAWA,eAAA,CAAY,MAAA,EAAe,kBAAkB,CAAA;AAE9D,EAAA,OAAOC,qBAAA,CAAQ,cAAA,CAAA;AAAA,IACb;AAAA,GAAA,EACG,WAAA,CACJ,CAAA;AACH;;;AC5CA,IAAM,KAAA,GAAgC;AAAA,EACpC,KAAA,EAAO,oBAAA;AAAA,EACP,KAAA,EAAO,4CAAA;AAAA,EACP,GAAA,EAAK,KAAA;AAAA,EACL,KAAA,EAAO,oBAAA;AAAA,EACP,IAAA,EAAM,MAAA;AAAA,EACN,MAAA,EAAQ,QAAA;AAAA,EACR,MAAA,EAAQ,QAAA;AAAA,EACR,MAAA,EAAQ,QAAA;AAAA,EACR,IAAA,EAAM,MAAA;AAAA,EACN,IAAA,EAAM,MAAA;AAAA,EACN,KAAA,EAAO,OAAA;AAAA,EACP,IAAA,EAAM,MAAA;AAAA,EACN,GAAA,EAAK,KAAA;AAAA,EACL,KAAA,EAAO,OAAA;AAAA,EACP,QAAA,EAAU,iBAAA;AAAA,EACV,IAAA,EAAM,iBAAA;AAAA,EACN,IAAA,EAAM,iBAAA;AAAA,EACN,QAAA,EAAU,iBAAA;AAAA,EACV,IAAA,EAAM,8BAAA;AAAA,EACN,IAAA,EAAM,8BAAA;AAAA,EACN,MAAA,EAAQ,kBAAA;AAAA,EACR,MAAA,EAAQ,kBAAA;AAAA,EACR,MAAA,EAAQ,wDAAA;AAAA,EACR,SAAA,EAAW,2DAAA;AAAA,EACX,WAAA,EAAa,wBAAA;AAAA,EACb,IAAA,EAAM,mBAAA;AAAA,EACN,GAAA,EAAK,KAAA;AAAA,EACL,gBAAA,EAAkB;AACpB,CAAA;AAEA,SAAS,mBAAmB,KAAA,EAAwB;AAClD,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,SAAiB,CAAA,EAAG,KAAA,CAAM,UAAU,CAAA,CAAA,CAAA;AACzD,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,EAAU,OAAO,IAAI,KAAK,CAAA,CAAA,CAAA;AAC/C,EAAA,OAAO,GAAG,KAAK,CAAA,CAAA;AACjB;AAGA,SAAS,UAAA,CAAkC,KAAA,EAAU,SAAA,GAAY,QAAA,EAAa;AAC5E,EAAA,OAAO,KAAA,CAAM,IAAI,CAAC,GAAA,KAAQ,mBAAmB,GAAG,CAAC,CAAA,CAAE,IAAA,CAAK,SAAS,CAAA;AACnE;AAEA,IAAM,OAAA,GAA0D;AAAA,EAC9D,MAAA,EAAQ,EAAE,IAAA,EAAM,cAAA,EAAM,MAAM,oBAAA,EAAM;AAAA,EAClC,IAAA,EAAM,EAAE,IAAA,EAAM,oBAAA,EAAO,MAAM,oBAAA,EAAM;AAAA,EACjC,KAAA,EAAO,EAAE,IAAA,EAAM,cAAA,EAAM,MAAM,oBAAA,EAAM;AAAA,EACjC,GAAA,EAAK,EAAE,IAAA,EAAM,cAAA,EAAM,MAAM,oBAAA;AAC3B,CAAA;AAEA,SAAS,UAAU,MAAA,EAAuD;AAnD1E,EAAA,IAAA,EAAA;AAoDE,EAAA,OAAA,CAAO,EAAA,GAAA,OAAA,CAAQ,MAAM,CAAA,KAAd,IAAA,GAAA,EAAA,GAAmB,IAAA;AAC5B;AAEA,SAAS,WAAW,IAAA,EAAuB;AACzC,EAAA,MAAM,IAAI,OAAO,IAAA;AAEjB,EAAA,QAAQ,CAAA;AAAG,IACT,KAAK,QAAA,EAAU;AACb,MAAA,OAAO,MAAA,CAAO,KAAA,CAAM,IAAI,CAAA,GAAI,KAAA,GAAQ,cAAA;AAAA,IACtC;AAAA,IACA,KAAK,QAAA,EAAU;AACb,MAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,EAAG;AACvB,QAAA,OAAO,cAAA;AAAA,MACT;AACA,MAAA,IAAI,SAAS,IAAA,EAAM;AACjB,QAAA,OAAO,MAAA;AAAA,MACT;AAEA,MAAA,IACE,MAAA,CAAO,eAAe,IAAI,CAAA,KAAM,OAAO,SAAA,IACvC,IAAA,IACA,KAAK,WAAA,EACL;AACA,QAAA,OAAO,KAAK,WAAA,CAAY,IAAA;AAAA,MAC1B;AAAA,IACF;AAAA;AAEF,EAAA,OAAO,CAAA;AACT;AAOO,SAAS,uBACd,SAAA,EAC+C;AAC/C,EAAA,OAAO,CAAC,KAAA,KAAsC;AA1FhD,IAAA,IAAA,EAAA;AA2FI,IAAA,MAAM,QAAQ,SAAA,IAAa,0BAAA;AAE3B,IAAA,QAAQ,MAAM,IAAA;AAAM,MAClB,KAAK,QAAA,EAAU;AACb,QAAA,OAAO,gCAAA;AAAA,MACT;AAAA,MACA,KAAK,cAAA;AACH,QAAA,OAAO,mCAAU,KAAA,CAAM,QAAQ,+DAAa,UAAA,CAAW,KAAA,CAAM,KAAK,CAAC,CAAA,gDAAA,CAAA;AAAA,MACrE,KAAK,eAAA;AACH,QAAA,IAAI,KAAA,CAAM,OAAO,MAAA,KAAW,CAAA;AAC1B,UAAA,OAAO,mCAAU,kBAAA,CAAmB,KAAA,CAAM,MAAA,CAAO,CAAC,CAAC,CAAC,CAAA,gDAAA,CAAA;AACtD,QAAA,OAAO,CAAA,gCAAA,EAAU,UAAA,CAAW,KAAA,CAAM,MAAM,CAAC,CAAA,0FAAA,CAAA;AAAA,MAC3C,KAAK,SAAA,EAAW;AACd,QAAA,MAAM,GAAA,GAAM,KAAA,CAAM,SAAA,GAAY,gCAAA,GAAU,gCAAA;AACxC,QAAA,MAAM,MAAA,GAAS,SAAA,CAAU,KAAA,CAAM,MAAM,CAAA;AACrC,QAAA,IAAI,MAAA;AACF,UAAA,OAAO,CAAA,sCAAA,EAAW,KAAK,CAAA,MAAA,EAAI,KAAA,CAAM,OAAA,CAAQ,QAAA,EAAU,CAAA,EAAG,MAAA,CAAO,IAAI,CAAA,EAAG,GAAG,CAAA,0CAAA,CAAA;AACzE,QAAA,OAAO,CAAA,sCAAA,EAAW,KAAK,CAAA,MAAA,EAAI,KAAA,CAAM,QAAQ,QAAA,EAAU,GAAG,GAAG,CAAA,0CAAA,CAAA;AAAA,MAC3D;AAAA,MACA,KAAK,WAAA,EAAa;AAChB,QAAA,MAAM,GAAA,GAAM,KAAA,CAAM,SAAA,GAAY,gCAAA,GAAU,gCAAA;AACxC,QAAA,MAAM,MAAA,GAAS,SAAA,CAAU,KAAA,CAAM,MAAM,CAAA;AACrC,QAAA,IAAI,KAAA,CAAM,YAAY,CAAA,EAAG;AACvB,UAAA,OAAO,sCAAA;AAAA,QACT;AACA,QAAA,IAAI,MAAA;AACF,UAAA,OAAO,CAAA,sCAAA,EAAW,KAAK,CAAA,MAAA,EAAI,KAAA,CAAM,OAAA,CAAQ,QAAA,EAAU,CAAA,EAAG,MAAA,CAAO,IAAI,CAAA,EAAG,GAAG,CAAA,0CAAA,CAAA;AACzE,QAAA,OAAO,CAAA,sCAAA,EAAW,KAAK,CAAA,MAAA,EAAI,KAAA,CAAM,QAAQ,QAAA,EAAU,GAAG,GAAG,CAAA,0CAAA,CAAA;AAAA,MAC3D;AAAA,MACA,KAAK,gBAAA,EAAkB;AACrB,QAAA,MAAM,MAAA,GAAS,KAAA;AAIf,QAAA,IAAI,OAAO,MAAA,KAAW,aAAA;AACpB,UAAA,OAAO,CAAA,uCAAA,EAAY,OAAO,MAAM,CAAA,mEAAA,CAAA;AAClC,QAAA,IAAI,OAAO,MAAA,KAAW,WAAA;AACpB,UAAA,OAAO,CAAA,uCAAA,EAAY,OAAO,MAAM,CAAA,mEAAA,CAAA;AAClC,QAAA,IAAI,OAAO,MAAA,KAAW,UAAA;AACpB,UAAA,OAAO,CAAA,uCAAA,EAAY,OAAO,QAAQ,CAAA,6DAAA,CAAA;AACpC,QAAA,IAAI,OAAO,MAAA,KAAW,OAAA;AACpB,UAAA,OAAO,CAAA,8DAAA,EAAe,OAAO,OAAO,CAAA,wEAAA,CAAA;AACtC,QAAA,OAAO,sBAAM,EAAA,GAAA,KAAA,CAAM,MAAA,CAAO,MAAM,CAAA,KAAnB,IAAA,GAAA,EAAA,GAAwB,MAAM,MAAM,CAAA,CAAA;AAAA,MACnD;AAAA,MACA,KAAK,iBAAA;AACH,QAAA,OAAO,CAAA,gCAAA,EAAU,MAAM,OAAO,CAAA,8EAAA,CAAA;AAAA,MAChC,KAAK,mBAAA;AACH,QAAA,OAAO,CAAA,4DAAA,EAAa,KAAA,CAAM,IAAA,CAAK,MAAA,GAAS,CAAA,GAAI,QAAA,GAAM,EAAE,CAAA,EAAA,EAAK,UAAA,CAAW,KAAA,CAAM,IAAI,CAAC,CAAA,CAAA;AAAA,MACjF,KAAK,aAAA;AACH,QAAA,OAAO,GAAG,KAAK,CAAA,0CAAA,CAAA;AAAA,MACjB,KAAK,eAAA;AACH,QAAA,OAAO,gCAAA;AAAA,MACT,KAAK,iBAAA;AACH,QAAA,OAAO,GAAG,KAAK,CAAA,oCAAA,CAAA;AAAA,MACjB;AACE,QAAA,OAAO,gCAAA;AAAA;AACX,EACF,CAAA;AACF;;;ACnJA,IAAMC,MAAAA,GAAgC;AAAA,EACpC,KAAA,EAAO,OAAA;AAAA,EACP,KAAA,EAAO,eAAA;AAAA,EACP,GAAA,EAAK,KAAA;AAAA,EACL,KAAA,EAAO,OAAA;AAAA,EACP,IAAA,EAAM,MAAA;AAAA,EACN,MAAA,EAAQ,QAAA;AAAA,EACR,MAAA,EAAQ,QAAA;AAAA,EACR,MAAA,EAAQ,QAAA;AAAA,EACR,IAAA,EAAM,MAAA;AAAA,EACN,IAAA,EAAM,MAAA;AAAA,EACN,KAAA,EAAO,OAAA;AAAA,EACP,IAAA,EAAM,MAAA;AAAA,EACN,GAAA,EAAK,KAAA;AAAA,EACL,KAAA,EAAO,OAAA;AAAA,EACP,QAAA,EAAU,cAAA;AAAA,EACV,IAAA,EAAM,UAAA;AAAA,EACN,IAAA,EAAM,UAAA;AAAA,EACN,QAAA,EAAU,cAAA;AAAA,EACV,IAAA,EAAM,cAAA;AAAA,EACN,IAAA,EAAM,cAAA;AAAA,EACN,MAAA,EAAQ,WAAA;AAAA,EACR,MAAA,EAAQ,WAAA;AAAA,EACR,MAAA,EAAQ,uBAAA;AAAA,EACR,SAAA,EAAW,0BAAA;AAAA,EACX,WAAA,EAAa,aAAA;AAAA,EACb,IAAA,EAAM,oBAAA;AAAA,EACN,GAAA,EAAK,KAAA;AAAA,EACL,gBAAA,EAAkB;AACpB,CAAA;AAEA,SAASC,oBAAmB,KAAA,EAAwB;AAClD,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,SAAiB,CAAA,EAAG,KAAA,CAAM,UAAU,CAAA,CAAA,CAAA;AACzD,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,EAAU,OAAO,IAAI,KAAK,CAAA,CAAA,CAAA;AAC/C,EAAA,OAAO,GAAG,KAAK,CAAA,CAAA;AACjB;AAGA,SAASC,WAAAA,CACP,KAAA,EACA,SAAA,GAAY,KAAA,EACJ;AACR,EAAA,OAAO,KAAA,CAAM,IAAI,CAAC,GAAA,KAAQD,oBAAmB,GAAG,CAAC,CAAA,CAAE,IAAA,CAAK,SAAS,CAAA;AACnE;AAEA,IAAME,QAAAA,GAAkC;AAAA,EACtC,MAAA,EAAQ,WAAA;AAAA,EACR,IAAA,EAAM,MAAA;AAAA,EACN,KAAA,EAAO,MAAA;AAAA,EACP,GAAA,EAAK;AACP,CAAA;AAEA,SAASC,WAAU,MAAA,EAA+B;AAtDlD,EAAA,IAAA,EAAA;AAuDE,EAAA,OAAA,CAAO,EAAA,GAAAD,QAAAA,CAAQ,MAAM,CAAA,KAAd,IAAA,GAAA,EAAA,GAAmB,IAAA;AAC5B;AAEA,SAASE,YAAW,IAAA,EAAuB;AACzC,EAAA,MAAM,IAAI,OAAO,IAAA;AAEjB,EAAA,QAAQ,CAAA;AAAG,IACT,KAAK,QAAA,EAAU;AACb,MAAA,OAAO,MAAA,CAAO,KAAA,CAAM,IAAI,CAAA,GAAI,KAAA,GAAQ,QAAA;AAAA,IACtC;AAAA,IACA,KAAK,QAAA,EAAU;AACb,MAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,EAAG;AACvB,QAAA,OAAO,OAAA;AAAA,MACT;AACA,MAAA,IAAI,SAAS,IAAA,EAAM;AACjB,QAAA,OAAO,MAAA;AAAA,MACT;AAEA,MAAA,IACE,MAAA,CAAO,eAAe,IAAI,CAAA,KAAM,OAAO,SAAA,IACvC,IAAA,IACA,KAAK,WAAA,EACL;AACA,QAAA,OAAO,KAAK,WAAA,CAAY,IAAA;AAAA,MAC1B;AAAA,IACF;AAAA;AAEF,EAAA,OAAO,CAAA;AACT;AAOO,SAAS,sBACd,SAAA,EAC+C;AAC/C,EAAA,OAAO,CAAC,KAAA,KAAsC;AA7FhD,IAAA,IAAA,EAAA;AA8FI,IAAA,MAAM,QAAQ,SAAA,IAAa,YAAA;AAE3B,IAAA,QAAQ,MAAM,IAAA;AAAM,MAClB,KAAK,QAAA,EAAU;AACb,QAAA,OAAO,eAAA;AAAA,MACT;AAAA,MACA,KAAK,cAAA;AACH,QAAA,OAAO,0BAA0B,KAAA,CAAM,QAAQ,cAAcA,WAAAA,CAAW,KAAA,CAAM,KAAK,CAAC,CAAA,CAAA;AAAA,MACtF,KAAK,eAAA;AACH,QAAA,IAAI,KAAA,CAAM,OAAO,MAAA,KAAW,CAAA;AAC1B,UAAA,OAAO,2BAA2BJ,mBAAAA,CAAmB,KAAA,CAAM,MAAA,CAAO,CAAC,CAAC,CAAC,CAAA,CAAA;AACvE,QAAA,OAAO,CAAA,+BAAA,EAAkCC,WAAAA,CAAW,KAAA,CAAM,MAAM,CAAC,CAAA,CAAA;AAAA,MACnE,KAAK,SAAA,EAAW;AACd,QAAA,MAAM,IAAA,GAAOE,UAAAA,CAAU,KAAA,CAAM,MAAM,CAAA;AACnC,QAAA,MAAM,MAAA,GAAS,KAAA,CAAM,OAAA,KAAY,CAAA,GAAI,GAAA,GAAM,EAAA;AAC3C,QAAA,IAAI,IAAA,EAAM;AACR,UAAA,OAAO,KAAA,CAAM,YACT,CAAA,EAAG,KAAK,oBAAoB,KAAA,CAAM,OAAO,IAAI,IAAI,CAAA,EAAG,MAAM,CAAA,CAAA,GAC1D,CAAA,EAAG,KAAK,CAAA,mBAAA,EAAsB,KAAA,CAAM,OAAO,CAAA,CAAA,EAAI,IAAI,GAAG,MAAM,CAAA,CAAA;AAAA,QAClE;AACA,QAAA,OAAO,KAAA,CAAM,SAAA,GACT,CAAA,EAAG,KAAK,CAAA,iBAAA,EAAoB,KAAA,CAAM,OAAO,CAAA,CAAA,GACzC,CAAA,EAAG,KAAK,CAAA,mBAAA,EAAsB,KAAA,CAAM,OAAO,CAAA,CAAA;AAAA,MACjD;AAAA,MACA,KAAK,WAAA,EAAa;AAChB,QAAA,MAAM,IAAA,GAAOA,UAAAA,CAAU,KAAA,CAAM,MAAM,CAAA;AACnC,QAAA,MAAM,MAAA,GAAS,KAAA,CAAM,OAAA,KAAY,CAAA,GAAI,GAAA,GAAM,EAAA;AAC3C,QAAA,IAAI,KAAA,CAAM,OAAA,KAAY,CAAA,IAAK,CAAC,IAAA,EAAM;AAChC,UAAA,OAAO,GAAG,KAAK,CAAA,YAAA,CAAA;AAAA,QACjB;AACA,QAAA,IAAI,IAAA,EAAM;AACR,UAAA,OAAO,KAAA,CAAM,YACT,CAAA,EAAG,KAAK,qBAAqB,KAAA,CAAM,OAAO,IAAI,IAAI,CAAA,EAAG,MAAM,CAAA,CAAA,GAC3D,CAAA,EAAG,KAAK,CAAA,sBAAA,EAAyB,KAAA,CAAM,OAAO,CAAA,CAAA,EAAI,IAAI,GAAG,MAAM,CAAA,CAAA;AAAA,QACrE;AACA,QAAA,OAAO,KAAA,CAAM,SAAA,GACT,CAAA,EAAG,KAAK,CAAA,kBAAA,EAAqB,KAAA,CAAM,OAAO,CAAA,CAAA,GAC1C,CAAA,EAAG,KAAK,CAAA,sBAAA,EAAyB,KAAA,CAAM,OAAO,CAAA,CAAA;AAAA,MACpD;AAAA,MACA,KAAK,gBAAA,EAAkB;AACrB,QAAA,MAAM,MAAA,GAAS,KAAA;AAIf,QAAA,IAAI,OAAO,MAAA,KAAW,aAAA;AACpB,UAAA,OAAO,CAAA,iCAAA,EAAoC,OAAO,MAAM,CAAA,CAAA,CAAA;AAC1D,QAAA,IAAI,OAAO,MAAA,KAAW,WAAA;AACpB,UAAA,OAAO,CAAA,+BAAA,EAAkC,OAAO,MAAM,CAAA,CAAA,CAAA;AACxD,QAAA,IAAI,OAAO,MAAA,KAAW,UAAA;AACpB,UAAA,OAAO,CAAA,8BAAA,EAAiC,OAAO,QAAQ,CAAA,CAAA,CAAA;AACzD,QAAA,IAAI,OAAO,MAAA,KAAW,OAAA;AACpB,UAAA,OAAO,CAAA,mCAAA,EAAsC,OAAO,OAAO,CAAA,CAAA;AAC7D,QAAA,OAAO,CAAA,QAAA,EAAA,CAAW,KAAAJ,MAAAA,CAAM,MAAA,CAAO,MAAM,CAAA,KAAnB,IAAA,GAAA,EAAA,GAAwB,OAAO,MAAM,CAAA,CAAA;AAAA,MACzD;AAAA,MACA,KAAK,iBAAA;AACH,QAAA,OAAO,CAAA,sCAAA,EAAyC,MAAM,OAAO,CAAA,CAAA;AAAA,MAC/D,KAAK,mBAAA;AACH,QAAA,OAAO,CAAA,gBAAA,EAAmB,KAAA,CAAM,IAAA,CAAK,MAAA,GAAS,CAAA,GAAI,GAAA,GAAM,EAAE,CAAA,EAAA,EAAKE,WAAAA,CAAW,KAAA,CAAM,IAAI,CAAC,CAAA,CAAA;AAAA,MACvF,KAAK,aAAA;AACH,QAAA,OAAO,kBAAkB,KAAK,CAAA,CAAA;AAAA,MAChC,KAAK,eAAA;AACH,QAAA,OAAO,eAAA;AAAA,MACT,KAAK,iBAAA;AACH,QAAA,OAAO,oBAAoB,KAAK,CAAA,CAAA;AAAA,MAClC;AACE,QAAA,OAAO,eAAA;AAAA;AACX,EACF,CAAA;AACF;;;AC1JO,IAAM,qBAAA,GAAwB;AAAA,EACnC,UAAA,EAAY;AAAA,IACV,SAAA,EAAW;AAAA;AAEf;AAWO,IAAM,sBAAsB,CAAC;AAAA,EAClC;AACF,CAAA,KAEM;AACJ,EAAA,OAAO,CAAC,KAAA,KAAsC;AA5BhD,IAAA,IAAA,EAAA;AA6BI,IAAA,MAAM,SAAA,GACJ,qBAAA,CAAsB,cAAc,CAAA,CAClC,MAAA;AAAA,MAAA,CACE,EAAA,GAAA,KAAA,CAAM,SAAN,IAAA,GAAA,MAAA,GAAA,EAAA,CAAa,CAAA;AAAA,KAEjB,CAAA,IAAK,MAAA;AAEP,IAAA,OAAO,sBAAA,CAAuB,SAAS,CAAA,CAAE,KAAK,CAAA;AAAA,EAChD,CAAA;AACF","file":"index.js","sourcesContent":["import { zodResolver } from '@hookform/resolvers/zod';\nimport type { MakeOptionalAndNullable } from '@zod-utils/core';\nimport {\n type DefaultValues,\n type FieldValues,\n type UseFormProps,\n useForm,\n} from 'react-hook-form';\nimport type { ZodTypeAny } from 'zod';\n\n/**\n * Type-safe wrapper around useForm with Zod v4 schema integration\n * Automatically sets up zodResolver and provides better type inference\n *\n * @example\n * ```ts\n * const schema = z.object({\n * name: z.string(),\n * age: z.number()\n * });\n *\n * const form = useZodForm({\n * schema,\n * defaultValues: { name: '', age: 0 }\n * });\n * ```\n */\nexport const useZodForm = <T extends FieldValues>({\n schema,\n zodResolverOptions,\n ...formOptions\n}: {\n schema: ZodTypeAny;\n defaultValues?: DefaultValues<MakeOptionalAndNullable<T>>;\n zodResolverOptions?: Parameters<typeof zodResolver>[1];\n} & Omit<\n UseFormProps<MakeOptionalAndNullable<T>, unknown, T>,\n 'resolver' | 'defaultValues'\n>) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const resolver = zodResolver(schema as any, zodResolverOptions);\n\n return useForm({\n resolver,\n ...formOptions,\n });\n};\n","import type { ZodErrorMap } from 'zod';\n\nconst Nouns: Record<string, string> = {\n regex: '入力値',\n email: 'メールアドレス',\n url: 'URL',\n emoji: '絵文字',\n uuid: 'UUID',\n uuidv4: 'UUIDv4',\n uuidv6: 'UUIDv6',\n nanoid: 'nanoid',\n guid: 'GUID',\n cuid: 'cuid',\n cuid2: 'cuid2',\n ulid: 'ULID',\n xid: 'XID',\n ksuid: 'KSUID',\n datetime: 'ISO日時',\n date: 'ISO日付',\n time: 'ISO時刻',\n duration: 'ISO期間',\n ipv4: 'IPv4アドレス',\n ipv6: 'IPv6アドレス',\n cidrv4: 'IPv4範囲',\n cidrv6: 'IPv6範囲',\n base64: 'base64エンコード文字列',\n base64url: 'base64urlエンコード文字列',\n json_string: 'JSON文字列',\n e164: 'E.164番号',\n jwt: 'JWT',\n template_literal: '入力値',\n};\n\nfunction stringifyPrimitive(value: unknown): string {\n if (typeof value === 'bigint') return `${value.toString()}n`;\n if (typeof value === 'string') return `\"${value}\"`;\n return `${value}`;\n}\n\ntype Primitive = string | number | symbol | bigint | boolean | null | undefined;\nfunction joinValues<T extends Primitive[]>(array: T, separator = '、'): string {\n return array.map((val) => stringifyPrimitive(val)).join(separator);\n}\n\nconst Sizable: Record<string, { unit: string; verb: string }> = {\n string: { unit: '文字', verb: 'である' },\n file: { unit: 'バイト', verb: 'である' },\n array: { unit: '要素', verb: 'である' },\n set: { unit: '要素', verb: 'である' },\n};\n\nfunction getSizing(origin: string): { unit: string; verb: string } | null {\n return Sizable[origin] ?? null;\n}\n\nfunction parsedType(data: unknown): string {\n const t = typeof data;\n\n switch (t) {\n case 'number': {\n return Number.isNaN(data) ? 'NaN' : '数値';\n }\n case 'object': {\n if (Array.isArray(data)) {\n return '配列';\n }\n if (data === null) {\n return 'null';\n }\n\n if (\n Object.getPrototypeOf(data) !== Object.prototype &&\n data &&\n data.constructor\n ) {\n return data.constructor.name;\n }\n }\n }\n return t;\n}\n\n/**\n * Japanese error map for Zod validation errors\n * @param fieldName - Optional custom field name to use in error messages\n * @returns Zod error map function\n */\nexport function createJapaneseErrorMap(\n fieldName?: string,\n): (issue: Parameters<ZodErrorMap>[0]) => string {\n return (issue: Parameters<ZodErrorMap>[0]) => {\n const field = fieldName || 'この項目';\n\n switch (issue.code) {\n case 'custom': {\n return '無効な入力';\n }\n case 'invalid_type':\n return `無効な入力: ${issue.expected}が期待されましたが、${parsedType(issue.input)}が入力されました`;\n case 'invalid_value':\n if (issue.values.length === 1)\n return `無効な入力: ${stringifyPrimitive(issue.values[0])}が期待されました`;\n return `無効な選択: ${joinValues(issue.values)}のいずれかである必要があります`;\n case 'too_big': {\n const adj = issue.inclusive ? '以下である' : 'より小さい';\n const sizing = getSizing(issue.origin);\n if (sizing)\n return `大きすぎる値: ${field}は${issue.maximum.toString()}${sizing.unit}${adj}必要があります`;\n return `大きすぎる値: ${field}は${issue.maximum.toString()}${adj}必要があります`;\n }\n case 'too_small': {\n const adj = issue.inclusive ? '以上である' : 'より大きい';\n const sizing = getSizing(issue.origin);\n if (issue.minimum === 1) {\n return '必須項目です';\n }\n if (sizing)\n return `小さすぎる値: ${field}は${issue.minimum.toString()}${sizing.unit}${adj}必要があります`;\n return `小さすぎる値: ${field}は${issue.minimum.toString()}${adj}必要があります`;\n }\n case 'invalid_format': {\n const _issue = issue as Extract<\n Parameters<ZodErrorMap>[0],\n { code: 'invalid_format' }\n >;\n if (_issue.format === 'starts_with')\n return `無効な文字列: \"${_issue.prefix}\"で始まる必要があります`;\n if (_issue.format === 'ends_with')\n return `無効な文字列: \"${_issue.suffix}\"で終わる必要があります`;\n if (_issue.format === 'includes')\n return `無効な文字列: \"${_issue.includes}\"を含む必要があります`;\n if (_issue.format === 'regex')\n return `無効な文字列: パターン${_issue.pattern}に一致する必要があります`;\n return `無効な${Nouns[_issue.format] ?? issue.format}`;\n }\n case 'not_multiple_of':\n return `無効な数値: ${issue.divisor}の倍数である必要があります`;\n case 'unrecognized_keys':\n return `認識されていないキー${issue.keys.length > 1 ? '群' : ''}: ${joinValues(issue.keys)}`;\n case 'invalid_key':\n return `${field}内の無効なキー`;\n case 'invalid_union':\n return '無効な入力';\n case 'invalid_element':\n return `${field}内の無効な値`;\n default:\n return '無効な入力';\n }\n };\n}\n","import type { ZodErrorMap } from 'zod';\n\nconst Nouns: Record<string, string> = {\n regex: 'input',\n email: 'email address',\n url: 'URL',\n emoji: 'emoji',\n uuid: 'UUID',\n uuidv4: 'UUIDv4',\n uuidv6: 'UUIDv6',\n nanoid: 'nanoid',\n guid: 'GUID',\n cuid: 'cuid',\n cuid2: 'cuid2',\n ulid: 'ULID',\n xid: 'XID',\n ksuid: 'KSUID',\n datetime: 'ISO datetime',\n date: 'ISO date',\n time: 'ISO time',\n duration: 'ISO duration',\n ipv4: 'IPv4 address',\n ipv6: 'IPv6 address',\n cidrv4: 'IPv4 CIDR',\n cidrv6: 'IPv6 CIDR',\n base64: 'base64 encoded string',\n base64url: 'base64url encoded string',\n json_string: 'JSON string',\n e164: 'E.164 phone number',\n jwt: 'JWT',\n template_literal: 'input',\n};\n\nfunction stringifyPrimitive(value: unknown): string {\n if (typeof value === 'bigint') return `${value.toString()}n`;\n if (typeof value === 'string') return `\"${value}\"`;\n return `${value}`;\n}\n\ntype Primitive = string | number | symbol | bigint | boolean | null | undefined;\nfunction joinValues<T extends Primitive[]>(\n array: T,\n separator = ' | ',\n): string {\n return array.map((val) => stringifyPrimitive(val)).join(separator);\n}\n\nconst Sizable: Record<string, string> = {\n string: 'character',\n file: 'byte',\n array: 'item',\n set: 'item',\n};\n\nfunction getSizing(origin: string): string | null {\n return Sizable[origin] ?? null;\n}\n\nfunction parsedType(data: unknown): string {\n const t = typeof data;\n\n switch (t) {\n case 'number': {\n return Number.isNaN(data) ? 'NaN' : 'number';\n }\n case 'object': {\n if (Array.isArray(data)) {\n return 'array';\n }\n if (data === null) {\n return 'null';\n }\n\n if (\n Object.getPrototypeOf(data) !== Object.prototype &&\n data &&\n data.constructor\n ) {\n return data.constructor.name;\n }\n }\n }\n return t;\n}\n\n/**\n * English error map for Zod validation errors\n * @param fieldName - Optional custom field name to use in error messages\n * @returns Zod error map function\n */\nexport function createEnglishErrorMap(\n fieldName?: string,\n): (issue: Parameters<ZodErrorMap>[0]) => string {\n return (issue: Parameters<ZodErrorMap>[0]) => {\n const field = fieldName || 'This field';\n\n switch (issue.code) {\n case 'custom': {\n return 'Invalid input';\n }\n case 'invalid_type':\n return `Invalid type: expected ${issue.expected}, received ${parsedType(issue.input)}`;\n case 'invalid_value':\n if (issue.values.length === 1)\n return `Invalid input: expected ${stringifyPrimitive(issue.values[0])}`;\n return `Invalid option: must be one of ${joinValues(issue.values)}`;\n case 'too_big': {\n const unit = getSizing(issue.origin);\n const plural = issue.maximum !== 1 ? 's' : '';\n if (unit) {\n return issue.inclusive\n ? `${field} must be at most ${issue.maximum} ${unit}${plural}`\n : `${field} must be less than ${issue.maximum} ${unit}${plural}`;\n }\n return issue.inclusive\n ? `${field} must be at most ${issue.maximum}`\n : `${field} must be less than ${issue.maximum}`;\n }\n case 'too_small': {\n const unit = getSizing(issue.origin);\n const plural = issue.minimum !== 1 ? 's' : '';\n if (issue.minimum === 1 && !unit) {\n return `${field} is required`;\n }\n if (unit) {\n return issue.inclusive\n ? `${field} must be at least ${issue.minimum} ${unit}${plural}`\n : `${field} must be greater than ${issue.minimum} ${unit}${plural}`;\n }\n return issue.inclusive\n ? `${field} must be at least ${issue.minimum}`\n : `${field} must be greater than ${issue.minimum}`;\n }\n case 'invalid_format': {\n const _issue = issue as Extract<\n Parameters<ZodErrorMap>[0],\n { code: 'invalid_format' }\n >;\n if (_issue.format === 'starts_with')\n return `Invalid string: must start with \"${_issue.prefix}\"`;\n if (_issue.format === 'ends_with')\n return `Invalid string: must end with \"${_issue.suffix}\"`;\n if (_issue.format === 'includes')\n return `Invalid string: must include \"${_issue.includes}\"`;\n if (_issue.format === 'regex')\n return `Invalid string: must match pattern ${_issue.pattern}`;\n return `Invalid ${Nouns[_issue.format] ?? _issue.format}`;\n }\n case 'not_multiple_of':\n return `Invalid number: must be a multiple of ${issue.divisor}`;\n case 'unrecognized_keys':\n return `Unrecognized key${issue.keys.length > 1 ? 's' : ''}: ${joinValues(issue.keys)}`;\n case 'invalid_key':\n return `Invalid key in ${field}`;\n case 'invalid_union':\n return 'Invalid input';\n case 'invalid_element':\n return `Invalid value in ${field}`;\n default:\n return 'Invalid input';\n }\n };\n}\n","import type { ZodErrorMap } from 'zod';\nimport { createEnglishErrorMap } from './locales/en';\nimport { createJapaneseErrorMap } from './locales/ja';\n\n/**\n * Field namespace mapping for custom error messages\n * You can extend this mapping to customize field names in error messages\n */\nexport const FieldNamespaceMapping = {\n department: {\n groupName: '部署・店舗名',\n },\n};\n\nexport type FIELD_NAMESPACE = keyof typeof FieldNamespaceMapping;\n\n/**\n * Custom error resolver with field namespace support (Japanese locale)\n * @deprecated Use createJapaneseErrorMap or createEnglishErrorMap instead\n * @param options - Configuration options\n * @param options.fieldNamespace - Namespace for field name mappings\n * @returns Error resolver function\n */\nexport const customErrorResolver = ({\n fieldNamespace,\n}: {\n fieldNamespace: FIELD_NAMESPACE;\n}) => {\n return (issue: Parameters<ZodErrorMap>[0]) => {\n const fieldName =\n FieldNamespaceMapping[fieldNamespace][\n String(\n issue.path?.[0],\n ) as keyof (typeof FieldNamespaceMapping)[typeof fieldNamespace]\n ] || undefined;\n\n return createJapaneseErrorMap(fieldName)(issue);\n };\n};\n\n// Re-export locale-specific error maps\nexport { createJapaneseErrorMap } from './locales/ja';\nexport { createEnglishErrorMap } from './locales/en';\n"]}
1
+ {"version":3,"sources":["../src/use-zod-form.ts"],"names":["zodResolver","useForm"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyJO,IAAM,UAAA,GAAa,CAAwB,EAAA,KAW5C;AAX4C,EAAA,IAAA,EAAA,GAAA,EAAA,EAChD;AAAA,IAAA,MAAA;AAAA,IACA;AAAA,GA3JF,GAyJkD,EAAA,EAG7C,WAAA,GAAA,SAAA,CAH6C,EAAA,EAG7C;AAAA,IAFH,QAAA;AAAA,IACA;AAAA,GAAA,CAAA;AAUA,EAAA,MAAM,QAAA,GAAWA,eAAA,CAAY,MAAA,EAAQ,kBAAkB,CAAA;AAEvD,EAAA,OAAOC,qBAAA,CAAQ,cAAA,CAAA;AAAA,IACb;AAAA,GAAA,EACG,WAAA,CACJ,CAAA;AACH","file":"index.js","sourcesContent":["import { zodResolver } from '@hookform/resolvers/zod';\nimport {\n type DefaultValues,\n type FieldValues,\n type UseFormProps,\n useForm,\n} from 'react-hook-form';\nimport type { z } from 'zod';\nimport type { MakeOptionalAndNullable } from './types';\n\n/**\n * Type-safe React Hook Form wrapper with automatic Zod v4 schema validation and type transformation.\n *\n * This hook eliminates the TypeScript friction between React Hook Form's nullable field values\n * and Zod's strict output types. It uses a two-type schema pattern where:\n * - **Input type** (`MakeOptionalAndNullable<T>`): Form fields accept `null | undefined` during editing\n * - **Output type** (`T`): Validated data matches exact schema type (no `null | undefined`)\n *\n * **Key Benefits:**\n * - ✅ No more \"Type 'null' is not assignable to...\" TypeScript errors\n * - ✅ Use `form.setValue()` and `form.reset()` with `null` values freely\n * - ✅ Validated output is still type-safe with exact Zod schema types\n * - ✅ Automatic zodResolver setup - no manual configuration needed\n *\n * @template T - The Zod schema output type (extends FieldValues)\n *\n * @param options - Configuration object\n * @param options.schema - Zod schema with two-type signature `z.ZodType<T, MakeOptionalAndNullable<T>>`\n * @param options.defaultValues - Default form values (accepts nullable/undefined values)\n * @param options.zodResolverOptions - Optional zodResolver configuration\n * @param options....formOptions - All other react-hook-form useForm options\n *\n * @returns React Hook Form instance with type-safe methods\n *\n * @example\n * Basic usage with required fields\n * ```typescript\n * import { useZodForm } from '@zod-utils/react-hook-form';\n * import { z } from 'zod';\n *\n * const schema = z.object({\n * name: z.string().min(1), // Required field\n * age: z.number().min(0),\n * }) satisfies z.ZodType<{ name: string; age: number }, any>;\n *\n * function MyForm() {\n * const form = useZodForm({ schema });\n *\n * // ✅ These work without type errors:\n * form.setValue('name', null); // Accepts null during editing\n * form.reset({ name: null, age: null }); // Reset with null\n *\n * const onSubmit = (data: { name: string; age: number }) => {\n * // ✅ data is exact type - no null | undefined\n * console.log(data.name.toUpperCase()); // Safe to use string methods\n * };\n *\n * return <form onSubmit={form.handleSubmit(onSubmit)}>...</form>;\n * }\n * ```\n *\n * @example\n * With default values\n * ```typescript\n * const schema = z.object({\n * username: z.string(),\n * email: z.string().email(),\n * notifications: z.boolean().default(true),\n * }) satisfies z.ZodType<{\n * username: string;\n * email: string;\n * notifications: boolean;\n * }, any>;\n *\n * const form = useZodForm({\n * schema,\n * defaultValues: {\n * username: '',\n * email: '',\n * // notifications gets default from schema\n * },\n * });\n * ```\n *\n * @example\n * With optional and nullable fields\n * ```typescript\n * const schema = z.object({\n * title: z.string(),\n * description: z.string().optional(), // Optional in output\n * tags: z.array(z.string()).nullable(), // Nullable in output\n * }) satisfies z.ZodType<{\n * title: string;\n * description?: string;\n * tags: string[] | null;\n * }, any>;\n *\n * const form = useZodForm({ schema });\n *\n * // All fields accept null/undefined during editing\n * form.setValue('title', null);\n * form.setValue('description', undefined);\n * form.setValue('tags', null);\n * ```\n *\n * @example\n * With zodResolver options\n * ```typescript\n * const form = useZodForm({\n * schema,\n * zodResolverOptions: {\n * async: true, // Enable async validation\n * errorMap: customErrorMap, // Custom error messages\n * },\n * });\n * ```\n *\n * @example\n * Complete form example\n * ```typescript\n * const userSchema = z.object({\n * name: z.string().min(1, 'Name is required'),\n * email: z.string().email('Invalid email'),\n * age: z.number().min(18, 'Must be 18+'),\n * }) satisfies z.ZodType<{ name: string; email: string; age: number }, any>;\n *\n * function UserForm() {\n * const form = useZodForm({\n * schema: userSchema,\n * defaultValues: { name: '', email: '', age: null },\n * });\n *\n * const onSubmit = (data: { name: string; email: string; age: number }) => {\n * // Type-safe: data has exact types, no null/undefined\n * console.log(`${data.name} is ${data.age} years old`);\n * };\n *\n * return (\n * <form onSubmit={form.handleSubmit(onSubmit)}>\n * <input {...form.register('name')} />\n * <input {...form.register('email')} type=\"email\" />\n * <input {...form.register('age', { valueAsNumber: true })} type=\"number\" />\n * <button type=\"submit\">Submit</button>\n * </form>\n * );\n * }\n * ```\n *\n * @see {@link MakeOptionalAndNullable} for the type transformation utility\n * @see https://react-hook-form.com/docs/useform for React Hook Form documentation\n * @see https://zod.dev for Zod schema documentation\n * @since 0.1.0\n */\nexport const useZodForm = <T extends FieldValues>({\n schema,\n zodResolverOptions,\n ...formOptions\n}: {\n schema: z.ZodType<T, MakeOptionalAndNullable<T>>;\n defaultValues?: DefaultValues<MakeOptionalAndNullable<T>>;\n zodResolverOptions?: Parameters<typeof zodResolver>[1];\n} & Omit<\n UseFormProps<MakeOptionalAndNullable<T>, unknown, T>,\n 'resolver' | 'defaultValues'\n>) => {\n const resolver = zodResolver(schema, zodResolverOptions);\n\n return useForm({\n resolver,\n ...formOptions,\n });\n};\n"]}