@famgia/omnify-react 0.0.1

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.
@@ -0,0 +1,425 @@
1
+ // src/lib/zod-i18n.ts
2
+ var DEFAULT_MESSAGES = {
3
+ required: {
4
+ en: "${displayName} is required",
5
+ ja: "${displayName}\u306F\u5FC5\u9808\u3067\u3059",
6
+ vi: "${displayName} l\xE0 b\u1EAFt bu\u1ED9c",
7
+ ko: "${displayName}\uC740(\uB294) \uD544\uC218\uC785\uB2C8\uB2E4",
8
+ "zh-CN": "${displayName}\u662F\u5FC5\u586B\u9879",
9
+ "zh-TW": "${displayName}\u70BA\u5FC5\u586B\u6B04\u4F4D",
10
+ th: "${displayName} \u0E08\u0E33\u0E40\u0E1B\u0E47\u0E19\u0E15\u0E49\u0E2D\u0E07\u0E01\u0E23\u0E2D\u0E01",
11
+ es: "${displayName} es obligatorio"
12
+ },
13
+ minLength: {
14
+ en: "${displayName} must be at least ${min} characters",
15
+ ja: "${displayName}\u306F${min}\u6587\u5B57\u4EE5\u4E0A\u3067\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044",
16
+ vi: "${displayName} ph\u1EA3i c\xF3 \xEDt nh\u1EA5t ${min} k\xFD t\u1EF1",
17
+ ko: "${displayName}\uC740(\uB294) ${min}\uC790 \uC774\uC0C1\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4",
18
+ "zh-CN": "${displayName}\u81F3\u5C11\u9700\u8981${min}\u4E2A\u5B57\u7B26",
19
+ "zh-TW": "${displayName}\u81F3\u5C11\u9700\u8981${min}\u500B\u5B57\u5143",
20
+ th: "${displayName} \u0E15\u0E49\u0E2D\u0E07\u0E21\u0E35\u0E2D\u0E22\u0E48\u0E32\u0E07\u0E19\u0E49\u0E2D\u0E22 ${min} \u0E15\u0E31\u0E27\u0E2D\u0E31\u0E01\u0E29\u0E23",
21
+ es: "${displayName} debe tener al menos ${min} caracteres"
22
+ },
23
+ maxLength: {
24
+ en: "${displayName} must be at most ${max} characters",
25
+ ja: "${displayName}\u306F${max}\u6587\u5B57\u4EE5\u5185\u3067\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044",
26
+ vi: "${displayName} kh\xF4ng \u0111\u01B0\u1EE3c qu\xE1 ${max} k\xFD t\u1EF1",
27
+ ko: "${displayName}\uC740(\uB294) ${max}\uC790 \uC774\uD558\uC5EC\uC57C \uD569\uB2C8\uB2E4",
28
+ "zh-CN": "${displayName}\u6700\u591A${max}\u4E2A\u5B57\u7B26",
29
+ "zh-TW": "${displayName}\u6700\u591A${max}\u500B\u5B57\u5143",
30
+ th: "${displayName} \u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E01\u0E34\u0E19 ${max} \u0E15\u0E31\u0E27\u0E2D\u0E31\u0E01\u0E29\u0E23",
31
+ es: "${displayName} debe tener como m\xE1ximo ${max} caracteres"
32
+ },
33
+ min: {
34
+ en: "${displayName} must be at least ${min}",
35
+ ja: "${displayName}\u306F${min}\u4EE5\u4E0A\u3067\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044",
36
+ vi: "${displayName} ph\u1EA3i l\u1EDBn h\u01A1n ho\u1EB7c b\u1EB1ng ${min}",
37
+ ko: "${displayName}\uC740(\uB294) ${min} \uC774\uC0C1\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4",
38
+ "zh-CN": "${displayName}\u5FC5\u987B\u5927\u4E8E\u7B49\u4E8E${min}",
39
+ "zh-TW": "${displayName}\u5FC5\u9808\u5927\u65BC\u7B49\u65BC${min}",
40
+ th: "${displayName} \u0E15\u0E49\u0E2D\u0E07\u0E21\u0E32\u0E01\u0E01\u0E27\u0E48\u0E32\u0E2B\u0E23\u0E37\u0E2D\u0E40\u0E17\u0E48\u0E32\u0E01\u0E31\u0E1A ${min}",
41
+ es: "${displayName} debe ser al menos ${min}"
42
+ },
43
+ max: {
44
+ en: "${displayName} must be at most ${max}",
45
+ ja: "${displayName}\u306F${max}\u4EE5\u4E0B\u3067\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044",
46
+ vi: "${displayName} ph\u1EA3i nh\u1ECF h\u01A1n ho\u1EB7c b\u1EB1ng ${max}",
47
+ ko: "${displayName}\uC740(\uB294) ${max} \uC774\uD558\uC5EC\uC57C \uD569\uB2C8\uB2E4",
48
+ "zh-CN": "${displayName}\u5FC5\u987B\u5C0F\u4E8E\u7B49\u4E8E${max}",
49
+ "zh-TW": "${displayName}\u5FC5\u9808\u5C0F\u65BC\u7B49\u65BC${max}",
50
+ th: "${displayName} \u0E15\u0E49\u0E2D\u0E07\u0E19\u0E49\u0E2D\u0E22\u0E01\u0E27\u0E48\u0E32\u0E2B\u0E23\u0E37\u0E2D\u0E40\u0E17\u0E48\u0E32\u0E01\u0E31\u0E1A ${max}",
51
+ es: "${displayName} debe ser como m\xE1ximo ${max}"
52
+ },
53
+ email: {
54
+ en: "Please enter a valid email address",
55
+ ja: "\u6709\u52B9\u306A\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044",
56
+ vi: "Vui l\xF2ng nh\u1EADp \u0111\u1ECBa ch\u1EC9 email h\u1EE3p l\u1EC7",
57
+ ko: "\uC720\uD6A8\uD55C \uC774\uBA54\uC77C \uC8FC\uC18C\uB97C \uC785\uB825\uD558\uC138\uC694",
58
+ "zh-CN": "\u8BF7\u8F93\u5165\u6709\u6548\u7684\u7535\u5B50\u90AE\u4EF6\u5730\u5740",
59
+ "zh-TW": "\u8ACB\u8F38\u5165\u6709\u6548\u7684\u96FB\u5B50\u90F5\u4EF6\u5730\u5740",
60
+ th: "\u0E01\u0E23\u0E38\u0E13\u0E32\u0E01\u0E23\u0E2D\u0E01\u0E2D\u0E35\u0E40\u0E21\u0E25\u0E17\u0E35\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
61
+ es: "Por favor, introduce una direcci\xF3n de correo electr\xF3nico v\xE1lida"
62
+ },
63
+ url: {
64
+ en: "Please enter a valid URL",
65
+ ja: "\u6709\u52B9\u306AURL\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044",
66
+ vi: "Vui l\xF2ng nh\u1EADp URL h\u1EE3p l\u1EC7",
67
+ ko: "\uC720\uD6A8\uD55C URL\uC744 \uC785\uB825\uD558\uC138\uC694",
68
+ "zh-CN": "\u8BF7\u8F93\u5165\u6709\u6548\u7684URL",
69
+ "zh-TW": "\u8ACB\u8F38\u5165\u6709\u6548\u7684\u7DB2\u5740",
70
+ th: "\u0E01\u0E23\u0E38\u0E13\u0E32\u0E01\u0E23\u0E2D\u0E01 URL \u0E17\u0E35\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
71
+ es: "Por favor, introduce una URL v\xE1lida"
72
+ },
73
+ pattern: {
74
+ en: "${displayName} format is invalid",
75
+ ja: "${displayName}\u306E\u5F62\u5F0F\u304C\u6B63\u3057\u304F\u3042\u308A\u307E\u305B\u3093",
76
+ vi: "${displayName} kh\xF4ng \u0111\xFAng \u0111\u1ECBnh d\u1EA1ng",
77
+ ko: "${displayName} \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4",
78
+ "zh-CN": "${displayName}\u683C\u5F0F\u4E0D\u6B63\u786E",
79
+ "zh-TW": "${displayName}\u683C\u5F0F\u4E0D\u6B63\u78BA",
80
+ th: "\u0E23\u0E39\u0E1B\u0E41\u0E1A\u0E1A${displayName}\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
81
+ es: "El formato de ${displayName} no es v\xE1lido"
82
+ }
83
+ };
84
+ var currentLocale = "ja";
85
+ var fallbackLocale = "en";
86
+ var customMessages = {};
87
+ function setZodLocale(locale) {
88
+ currentLocale = locale;
89
+ }
90
+ function getZodLocale() {
91
+ return currentLocale;
92
+ }
93
+ function setZodFallbackLocale(locale) {
94
+ fallbackLocale = locale;
95
+ }
96
+ function getZodFallbackLocale() {
97
+ return fallbackLocale;
98
+ }
99
+ function addZodMessages(messages) {
100
+ for (const [key, locales] of Object.entries(messages)) {
101
+ customMessages[key] = { ...customMessages[key], ...locales };
102
+ }
103
+ }
104
+ function getZodMessage(key, params = {}) {
105
+ const messages = customMessages[key] ?? DEFAULT_MESSAGES[key];
106
+ if (!messages) return key;
107
+ let message = messages[currentLocale] ?? messages[fallbackLocale] ?? messages["en"] ?? key;
108
+ for (const [param, value] of Object.entries(params)) {
109
+ message = message.replace(new RegExp(`\\$\\{${param}\\}`, "g"), String(value));
110
+ }
111
+ return message;
112
+ }
113
+ function getZodMessages(locale) {
114
+ const targetLocale = locale ?? currentLocale;
115
+ const result = {};
116
+ for (const [key, locales] of Object.entries(DEFAULT_MESSAGES)) {
117
+ result[key] = locales[targetLocale] ?? locales[fallbackLocale] ?? locales["en"] ?? key;
118
+ }
119
+ for (const [key, locales] of Object.entries(customMessages)) {
120
+ if (locales[targetLocale]) {
121
+ result[key] = locales[targetLocale];
122
+ }
123
+ }
124
+ return result;
125
+ }
126
+
127
+ // src/lib/form-validation.ts
128
+ function zodRule(schema, displayName) {
129
+ const field = displayName ?? "\u3053\u306E\u9805\u76EE";
130
+ return {
131
+ validator: async (_, value) => {
132
+ if (value === void 0 || value === null || value === "") {
133
+ if (schema.safeParse(void 0).success) return;
134
+ throw new Error(getZodMessage("required", { displayName: field }));
135
+ }
136
+ const result = schema.safeParse(value);
137
+ if (result.success) return;
138
+ const issue = result.error.issues[0];
139
+ if (!issue) {
140
+ throw new Error(getZodMessage("required", { displayName: field }));
141
+ }
142
+ const issueAny = issue;
143
+ switch (issue.code) {
144
+ case "too_small": {
145
+ const origin = issueAny.origin;
146
+ const minimum = issueAny.minimum;
147
+ if (origin === "string" && minimum === 1) {
148
+ throw new Error(getZodMessage("required", { displayName: field }));
149
+ }
150
+ if (origin === "string") {
151
+ throw new Error(getZodMessage("minLength", { displayName: field, min: minimum }));
152
+ }
153
+ throw new Error(getZodMessage("min", { displayName: field, min: minimum }));
154
+ }
155
+ case "too_big": {
156
+ const origin = issueAny.origin;
157
+ const maximum = issueAny.maximum;
158
+ if (origin === "string") {
159
+ throw new Error(getZodMessage("maxLength", { displayName: field, max: maximum }));
160
+ }
161
+ throw new Error(getZodMessage("max", { displayName: field, max: maximum }));
162
+ }
163
+ // Zod v4: 'invalid_string' → 'invalid_format'
164
+ case "invalid_format": {
165
+ const format = issueAny.format;
166
+ if (format === "email") {
167
+ throw new Error(getZodMessage("email", { displayName: field }));
168
+ }
169
+ if (format === "url") {
170
+ throw new Error(getZodMessage("url", { displayName: field }));
171
+ }
172
+ if (format === "regex") {
173
+ throw new Error(getZodMessage("pattern", { displayName: field }));
174
+ }
175
+ break;
176
+ }
177
+ // Zod v3: 'invalid_string' (handled via default case for forward compatibility)
178
+ default: {
179
+ if (issue.code === "invalid_string") {
180
+ const validation = issueAny.validation;
181
+ if (validation === "email") {
182
+ throw new Error(getZodMessage("email", { displayName: field }));
183
+ }
184
+ if (validation === "url") {
185
+ throw new Error(getZodMessage("url", { displayName: field }));
186
+ }
187
+ if (validation === "regex") {
188
+ throw new Error(getZodMessage("pattern", { displayName: field }));
189
+ }
190
+ }
191
+ break;
192
+ }
193
+ case "invalid_type": {
194
+ const expected = issueAny.expected;
195
+ if (expected && value === void 0) {
196
+ throw new Error(getZodMessage("required", { displayName: field }));
197
+ }
198
+ break;
199
+ }
200
+ }
201
+ throw new Error(issue.message);
202
+ }
203
+ };
204
+ }
205
+ function requiredRule(displayName) {
206
+ return {
207
+ required: true,
208
+ message: getZodMessage("required", { displayName })
209
+ };
210
+ }
211
+ function isZodRequired(schema) {
212
+ const schemaDesc = schema?._def?.typeName;
213
+ const inner = schema?._def?.innerType;
214
+ if (schemaDesc === "ZodOptional" || schemaDesc === "ZodNullable") return false;
215
+ if (inner?._def?.typeName === "ZodOptional" || inner?._def?.typeName === "ZodNullable") return false;
216
+ return true;
217
+ }
218
+
219
+ // src/lib/rules/kana.ts
220
+ import { z } from "zod";
221
+ var CHAR_RANGES = {
222
+ // Full-width Katakana: ァ-ヶ (U+30A1-U+30F6) + ー (U+30FC)
223
+ fullWidthKatakana: "\u30A1-\u30F6\u30FC",
224
+ // Half-width Katakana: ヲ-゚ (U+FF66-U+FF9F)
225
+ halfWidthKatakana: "\uFF66-\uFF9F",
226
+ // Hiragana: ぁ-ゖ (U+3041-U+3096)
227
+ hiragana: "\u3041-\u3096",
228
+ // Full-width numbers: 0-9
229
+ fullWidthNumbers: "\uFF10-\uFF19",
230
+ // Half-width numbers: 0-9
231
+ halfWidthNumbers: "0-9",
232
+ // Full-width space:  (U+3000)
233
+ fullWidthSpace: "\u3000",
234
+ // Half-width space
235
+ halfWidthSpace: " ",
236
+ // Common special chars for names
237
+ defaultSpecialChars: ["\u30FC", "\u30FB"]
238
+ };
239
+ var DEFAULT_OPTIONS = {
240
+ fullWidthKatakana: true,
241
+ halfWidthKatakana: false,
242
+ hiragana: false,
243
+ allowNumbers: false,
244
+ fullWidthNumbers: false,
245
+ halfWidthNumbers: false,
246
+ allowSpaces: true,
247
+ allowSpecialChars: ["\u30FC", "\u30FB"],
248
+ message: ""
249
+ };
250
+ function buildKanaPattern(options = {}) {
251
+ const opts = { ...DEFAULT_OPTIONS, ...options };
252
+ const parts = [];
253
+ if (opts.fullWidthKatakana) {
254
+ parts.push(CHAR_RANGES.fullWidthKatakana);
255
+ }
256
+ if (opts.halfWidthKatakana) {
257
+ parts.push(CHAR_RANGES.halfWidthKatakana);
258
+ }
259
+ if (opts.hiragana) {
260
+ parts.push(CHAR_RANGES.hiragana);
261
+ }
262
+ if (opts.allowNumbers || opts.fullWidthNumbers) {
263
+ parts.push(CHAR_RANGES.fullWidthNumbers);
264
+ }
265
+ if (opts.allowNumbers || opts.halfWidthNumbers) {
266
+ parts.push(CHAR_RANGES.halfWidthNumbers);
267
+ }
268
+ if (opts.allowSpaces) {
269
+ parts.push(CHAR_RANGES.fullWidthSpace);
270
+ parts.push(CHAR_RANGES.halfWidthSpace);
271
+ }
272
+ if (opts.allowSpecialChars && opts.allowSpecialChars.length > 0) {
273
+ const escaped = opts.allowSpecialChars.map((c) => c.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("");
274
+ parts.push(escaped);
275
+ }
276
+ return `^[${parts.join("")}]*$`;
277
+ }
278
+ function getDefaultMessage(options = {}, locale = "ja") {
279
+ const opts = { ...DEFAULT_OPTIONS, ...options };
280
+ const messages = {
281
+ ja: {
282
+ fullWidthKatakana: "\u5168\u89D2\u30AB\u30BF\u30AB\u30CA",
283
+ halfWidthKatakana: "\u534A\u89D2\u30AB\u30BF\u30AB\u30CA",
284
+ hiragana: "\u3072\u3089\u304C\u306A",
285
+ mixed: "\u30AB\u30CA\u6587\u5B57"
286
+ },
287
+ en: {
288
+ fullWidthKatakana: "full-width katakana",
289
+ halfWidthKatakana: "half-width katakana",
290
+ hiragana: "hiragana",
291
+ mixed: "kana characters"
292
+ }
293
+ };
294
+ const msg = messages[locale] ?? messages["ja"];
295
+ let type = msg.mixed;
296
+ if (opts.fullWidthKatakana && !opts.halfWidthKatakana && !opts.hiragana) {
297
+ type = msg.fullWidthKatakana;
298
+ } else if (opts.halfWidthKatakana && !opts.fullWidthKatakana && !opts.hiragana) {
299
+ type = msg.halfWidthKatakana;
300
+ } else if (opts.hiragana && !opts.fullWidthKatakana && !opts.halfWidthKatakana) {
301
+ type = msg.hiragana;
302
+ }
303
+ if (locale === "ja") {
304
+ return `${type}\u3067\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044`;
305
+ }
306
+ return `Please enter in ${type}`;
307
+ }
308
+ function createKanaRegex(options = {}) {
309
+ return new RegExp(buildKanaPattern(options));
310
+ }
311
+ function validateKana(value, options = {}) {
312
+ if (!value) return true;
313
+ const regex = createKanaRegex(options);
314
+ return regex.test(value);
315
+ }
316
+ function getKanaPattern(options = {}) {
317
+ return buildKanaPattern(options);
318
+ }
319
+ function getKanaErrorMessage(options = {}, locale = "ja") {
320
+ return options.message ?? getDefaultMessage(options, locale);
321
+ }
322
+ var KATAKANA_FULL_WIDTH = {
323
+ fullWidthKatakana: true,
324
+ halfWidthKatakana: false,
325
+ hiragana: false,
326
+ allowSpaces: true,
327
+ allowSpecialChars: ["\u30FC", "\u30FB"]
328
+ };
329
+ var KATAKANA_HALF_WIDTH = {
330
+ fullWidthKatakana: false,
331
+ halfWidthKatakana: true,
332
+ hiragana: false,
333
+ allowSpaces: true,
334
+ allowSpecialChars: ["\uFF70"]
335
+ // Half-width prolonged sound mark
336
+ };
337
+ var HIRAGANA = {
338
+ fullWidthKatakana: false,
339
+ halfWidthKatakana: false,
340
+ hiragana: true,
341
+ allowSpaces: true,
342
+ allowSpecialChars: ["\u30FC"]
343
+ };
344
+ var KANA_ANY = {
345
+ fullWidthKatakana: true,
346
+ halfWidthKatakana: true,
347
+ hiragana: true,
348
+ allowSpaces: true,
349
+ allowSpecialChars: ["\u30FC", "\u30FB", "\uFF70"]
350
+ };
351
+ var KATAKANA_WITH_NUMBERS = {
352
+ fullWidthKatakana: true,
353
+ halfWidthKatakana: false,
354
+ hiragana: false,
355
+ allowNumbers: true,
356
+ allowSpaces: true,
357
+ allowSpecialChars: ["\u30FC", "\u30FB"]
358
+ };
359
+ var KATAKANA_PATTERN = /^[ァ-ヶー・  ]*$/;
360
+ var KATAKANA_HALF_PATTERN = /^[ヲ-゚ー ]*$/;
361
+ var HIRAGANA_PATTERN = /^[ぁ-ゖー  ]*$/;
362
+ var KANA_ANY_PATTERN = /^[ァ-ヶぁ-ゖヲ-゚ー・ー  ]*$/;
363
+ function kanaString(options = {}) {
364
+ const opts = { ...KATAKANA_FULL_WIDTH, ...options };
365
+ const regex = createKanaRegex(opts);
366
+ const message = getKanaErrorMessage(opts);
367
+ return z.string().regex(regex, { message });
368
+ }
369
+ function withKana(options = {}) {
370
+ return kanaString(options);
371
+ }
372
+ var kanaRules = {
373
+ createRegex: createKanaRegex,
374
+ validate: validateKana,
375
+ getPattern: getKanaPattern,
376
+ getMessage: getKanaErrorMessage,
377
+ // Zod helpers
378
+ string: kanaString,
379
+ // Presets
380
+ presets: {
381
+ fullWidthKatakana: KATAKANA_FULL_WIDTH,
382
+ halfWidthKatakana: KATAKANA_HALF_WIDTH,
383
+ hiragana: HIRAGANA,
384
+ any: KANA_ANY,
385
+ withNumbers: KATAKANA_WITH_NUMBERS
386
+ },
387
+ // Pattern constants for direct use
388
+ patterns: {
389
+ katakana: KATAKANA_PATTERN,
390
+ katakanaHalf: KATAKANA_HALF_PATTERN,
391
+ hiragana: HIRAGANA_PATTERN,
392
+ any: KANA_ANY_PATTERN
393
+ }
394
+ };
395
+ export {
396
+ HIRAGANA,
397
+ HIRAGANA_PATTERN,
398
+ KANA_ANY,
399
+ KANA_ANY_PATTERN,
400
+ KATAKANA_FULL_WIDTH,
401
+ KATAKANA_HALF_PATTERN,
402
+ KATAKANA_HALF_WIDTH,
403
+ KATAKANA_PATTERN,
404
+ KATAKANA_WITH_NUMBERS,
405
+ addZodMessages,
406
+ createKanaRegex,
407
+ getKanaErrorMessage,
408
+ getKanaPattern,
409
+ getZodFallbackLocale,
410
+ getZodLocale,
411
+ getZodMessage,
412
+ getZodMessages,
413
+ isZodRequired,
414
+ getKanaPattern as kanaPattern,
415
+ createKanaRegex as kanaRegex,
416
+ kanaRules,
417
+ kanaString,
418
+ requiredRule,
419
+ setZodFallbackLocale,
420
+ setZodLocale,
421
+ validateKana,
422
+ withKana,
423
+ zodRule
424
+ };
425
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/lib/zod-i18n.ts","../../src/lib/form-validation.ts","../../src/lib/rules/kana.ts"],"sourcesContent":["/**\n * Zod i18n - Localization for Zod validation messages\n *\n * This module provides locale-aware validation messages for Zod schemas.\n * It works independently of generated schemas and can be configured at runtime.\n *\n * @example\n * ```typescript\n * import { setZodLocale, getZodMessage } from '@famgia/omnify-react/lib';\n *\n * // Set locale once at app level\n * setZodLocale('ja');\n *\n * // Get translated message\n * const msg = getZodMessage('required', { displayName: 'Email' });\n * ```\n */\n\n// Default validation messages for all supported locales\nconst DEFAULT_MESSAGES: Record<string, Record<string, string>> = {\n required: {\n en: '${displayName} is required',\n ja: '${displayName}は必須です',\n vi: '${displayName} là bắt buộc',\n ko: '${displayName}은(는) 필수입니다',\n 'zh-CN': '${displayName}是必填项',\n 'zh-TW': '${displayName}為必填欄位',\n th: '${displayName} จำเป็นต้องกรอก',\n es: '${displayName} es obligatorio',\n },\n minLength: {\n en: '${displayName} must be at least ${min} characters',\n ja: '${displayName}は${min}文字以上で入力してください',\n vi: '${displayName} phải có ít nhất ${min} ký tự',\n ko: '${displayName}은(는) ${min}자 이상이어야 합니다',\n 'zh-CN': '${displayName}至少需要${min}个字符',\n 'zh-TW': '${displayName}至少需要${min}個字元',\n th: '${displayName} ต้องมีอย่างน้อย ${min} ตัวอักษร',\n es: '${displayName} debe tener al menos ${min} caracteres',\n },\n maxLength: {\n en: '${displayName} must be at most ${max} characters',\n ja: '${displayName}は${max}文字以内で入力してください',\n vi: '${displayName} không được quá ${max} ký tự',\n ko: '${displayName}은(는) ${max}자 이하여야 합니다',\n 'zh-CN': '${displayName}最多${max}个字符',\n 'zh-TW': '${displayName}最多${max}個字元',\n th: '${displayName} ต้องไม่เกิน ${max} ตัวอักษร',\n es: '${displayName} debe tener como máximo ${max} caracteres',\n },\n min: {\n en: '${displayName} must be at least ${min}',\n ja: '${displayName}は${min}以上で入力してください',\n vi: '${displayName} phải lớn hơn hoặc bằng ${min}',\n ko: '${displayName}은(는) ${min} 이상이어야 합니다',\n 'zh-CN': '${displayName}必须大于等于${min}',\n 'zh-TW': '${displayName}必須大於等於${min}',\n th: '${displayName} ต้องมากกว่าหรือเท่ากับ ${min}',\n es: '${displayName} debe ser al menos ${min}',\n },\n max: {\n en: '${displayName} must be at most ${max}',\n ja: '${displayName}は${max}以下で入力してください',\n vi: '${displayName} phải nhỏ hơn hoặc bằng ${max}',\n ko: '${displayName}은(는) ${max} 이하여야 합니다',\n 'zh-CN': '${displayName}必须小于等于${max}',\n 'zh-TW': '${displayName}必須小於等於${max}',\n th: '${displayName} ต้องน้อยกว่าหรือเท่ากับ ${max}',\n es: '${displayName} debe ser como máximo ${max}',\n },\n email: {\n en: 'Please enter a valid email address',\n ja: '有効なメールアドレスを入力してください',\n vi: 'Vui lòng nhập địa chỉ email hợp lệ',\n ko: '유효한 이메일 주소를 입력하세요',\n 'zh-CN': '请输入有效的电子邮件地址',\n 'zh-TW': '請輸入有效的電子郵件地址',\n th: 'กรุณากรอกอีเมลที่ถูกต้อง',\n es: 'Por favor, introduce una dirección de correo electrónico válida',\n },\n url: {\n en: 'Please enter a valid URL',\n ja: '有効なURLを入力してください',\n vi: 'Vui lòng nhập URL hợp lệ',\n ko: '유효한 URL을 입력하세요',\n 'zh-CN': '请输入有效的URL',\n 'zh-TW': '請輸入有效的網址',\n th: 'กรุณากรอก URL ที่ถูกต้อง',\n es: 'Por favor, introduce una URL válida',\n },\n pattern: {\n en: '${displayName} format is invalid',\n ja: '${displayName}の形式が正しくありません',\n vi: '${displayName} không đúng định dạng',\n ko: '${displayName} 형식이 올바르지 않습니다',\n 'zh-CN': '${displayName}格式不正确',\n 'zh-TW': '${displayName}格式不正確',\n th: 'รูปแบบ${displayName}ไม่ถูกต้อง',\n es: 'El formato de ${displayName} no es válido',\n },\n};\n\n// State\nlet currentLocale = 'ja';\nlet fallbackLocale = 'en';\nlet customMessages: Record<string, Record<string, string>> = {};\n\n/**\n * Reset all settings to defaults (for testing)\n * @internal\n */\nexport function resetZodI18n(): void {\n currentLocale = 'ja';\n fallbackLocale = 'en';\n customMessages = {};\n}\n\n/**\n * Set current locale for Zod validation messages\n */\nexport function setZodLocale(locale: string): void {\n currentLocale = locale;\n}\n\n/**\n * Get current locale\n */\nexport function getZodLocale(): string {\n return currentLocale;\n}\n\n/**\n * Set fallback locale (used when message not found in current locale)\n */\nexport function setZodFallbackLocale(locale: string): void {\n fallbackLocale = locale;\n}\n\n/**\n * Get fallback locale\n */\nexport function getZodFallbackLocale(): string {\n return fallbackLocale;\n}\n\n/**\n * Add custom validation messages\n * @param messages - Object with message keys and locale values\n */\nexport function addZodMessages(messages: Record<string, Record<string, string>>): void {\n for (const [key, locales] of Object.entries(messages)) {\n customMessages[key] = { ...customMessages[key], ...locales };\n }\n}\n\n/**\n * Get translated validation message\n *\n * @param key - Message key (e.g., 'required', 'minLength')\n * @param params - Template parameters to replace\n * @returns Formatted message string\n *\n * @example\n * getZodMessage('required', { displayName: '氏名' })\n * // => '氏名は必須です'\n */\nexport function getZodMessage(\n key: string,\n params: Record<string, string | number> = {}\n): string {\n // Try custom messages first, then defaults\n const messages = customMessages[key] ?? DEFAULT_MESSAGES[key];\n if (!messages) return key;\n\n let message =\n messages[currentLocale] ??\n messages[fallbackLocale] ??\n messages['en'] ??\n key;\n\n // Replace template placeholders\n for (const [param, value] of Object.entries(params)) {\n message = message.replace(new RegExp(`\\\\$\\\\{${param}\\\\}`, 'g'), String(value));\n }\n\n return message;\n}\n\n/**\n * Get all messages for a specific locale\n */\nexport function getZodMessages(locale?: string): Record<string, string> {\n const targetLocale = locale ?? currentLocale;\n const result: Record<string, string> = {};\n\n // Start with defaults\n for (const [key, locales] of Object.entries(DEFAULT_MESSAGES)) {\n result[key] = locales[targetLocale] ?? locales[fallbackLocale] ?? locales['en'] ?? key;\n }\n\n // Override with custom\n for (const [key, locales] of Object.entries(customMessages)) {\n if (locales[targetLocale]) {\n result[key] = locales[targetLocale];\n }\n }\n\n return result;\n}\n","/**\n * Form validation utilities for Ant Design + Zod\n *\n * Compatible with Zod v3.x and v4.x\n *\n * @example\n * ```typescript\n * import { zodRule, requiredRule } from '@famgia/omnify-react/lib';\n *\n * <Form.Item\n * name=\"email\"\n * rules={[zodRule(customerSchemas.email, 'メールアドレス')]}\n * >\n * <Input />\n * </Form.Item>\n * ```\n */\n\nimport type { RuleObject } from 'antd/es/form';\nimport type { z } from 'zod';\nimport { getZodMessage } from './zod-i18n';\n\n/**\n * Convert Zod schema to Ant Design Form rule with i18n support\n *\n * @example\n * // Set locale once at component level\n * setZodLocale('ja');\n *\n * // Use without passing locale\n * <Form.Item\n * name=\"email\"\n * rules={[zodRule(customerSchemas.email, 'メールアドレス')]}\n * >\n * <Input />\n * </Form.Item>\n */\nexport function zodRule<T extends z.ZodTypeAny>(\n schema: T,\n displayName?: string\n): RuleObject {\n const field = displayName ?? 'この項目';\n\n return {\n validator: async (_, value) => {\n // 空チェック - 必須として扱う\n if (value === undefined || value === null || value === '') {\n if (schema.safeParse(undefined).success) return;\n throw new Error(getZodMessage('required', { displayName: field }));\n }\n\n const result = schema.safeParse(value);\n if (result.success) return;\n\n // 最初のZodエラーを取得\n const issue = result.error.issues[0];\n if (!issue) {\n throw new Error(getZodMessage('required', { displayName: field }));\n }\n\n // エラータイプに基づいて翻訳(Zod v3/v4対応)\n const issueAny = issue as unknown as Record<string, unknown>;\n switch (issue.code) {\n case 'too_small': {\n const origin = issueAny.origin as string | undefined;\n const minimum = issueAny.minimum as number;\n if (origin === 'string' && minimum === 1) {\n throw new Error(getZodMessage('required', { displayName: field }));\n }\n if (origin === 'string') {\n throw new Error(getZodMessage('minLength', { displayName: field, min: minimum }));\n }\n throw new Error(getZodMessage('min', { displayName: field, min: minimum }));\n }\n\n case 'too_big': {\n const origin = issueAny.origin as string | undefined;\n const maximum = issueAny.maximum as number;\n if (origin === 'string') {\n throw new Error(getZodMessage('maxLength', { displayName: field, max: maximum }));\n }\n throw new Error(getZodMessage('max', { displayName: field, max: maximum }));\n }\n\n // Zod v4: 'invalid_string' → 'invalid_format'\n case 'invalid_format': {\n const format = issueAny.format as string | undefined;\n if (format === 'email') {\n throw new Error(getZodMessage('email', { displayName: field }));\n }\n if (format === 'url') {\n throw new Error(getZodMessage('url', { displayName: field }));\n }\n if (format === 'regex') {\n throw new Error(getZodMessage('pattern', { displayName: field }));\n }\n break;\n }\n\n // Zod v3: 'invalid_string' (handled via default case for forward compatibility)\n default: {\n // Zod v3 compatibility: handle invalid_string code\n if ((issue.code as string) === 'invalid_string') {\n const validation = issueAny.validation as string | undefined;\n if (validation === 'email') {\n throw new Error(getZodMessage('email', { displayName: field }));\n }\n if (validation === 'url') {\n throw new Error(getZodMessage('url', { displayName: field }));\n }\n if (validation === 'regex') {\n throw new Error(getZodMessage('pattern', { displayName: field }));\n }\n }\n break;\n }\n\n case 'invalid_type': {\n const expected = issueAny.expected as string | undefined;\n if (expected && value === undefined) {\n throw new Error(getZodMessage('required', { displayName: field }));\n }\n break;\n }\n }\n\n // フォールバック: Zodのオリジナルメッセージを使用\n throw new Error(issue.message);\n },\n };\n}\n\n/**\n * Create required rule with i18n message\n *\n * @example\n * <Form.Item\n * name=\"name\"\n * rules={[requiredRule('名前')]}\n * >\n * <Input />\n * </Form.Item>\n */\nexport function requiredRule(displayName: string): RuleObject {\n return {\n required: true,\n message: getZodMessage('required', { displayName }),\n };\n}\n\n/**\n * Check if a Zod schema represents a required field\n */\nexport function isZodRequired(schema: z.ZodTypeAny): boolean {\n const schemaDesc = (schema as any)?._def?.typeName;\n const inner = (schema as any)?._def?.innerType;\n\n if (schemaDesc === 'ZodOptional' || schemaDesc === 'ZodNullable') return false;\n if (inner?._def?.typeName === 'ZodOptional' || inner?._def?.typeName === 'ZodNullable') return false;\n\n return true;\n}\n","/**\n * Japanese Kana Validation Rules\n *\n * Provides configurable validation for Japanese character input:\n * - 全角カタカナ (Full-width Katakana) - default\n * - 半角カタカナ (Half-width Katakana)\n * - ひらがな (Hiragana)\n * - Mixed modes\n *\n * @example\n * ```typescript\n * import { kanaString, KATAKANA_PATTERN } from '@famgia/omnify-react/lib';\n * import { z } from 'zod';\n *\n * // Method 1: Use kanaString helper\n * const schema = z.object({\n * name_kana: kanaString(), // 全角カタカナ (default)\n * });\n *\n * // Method 2: Use pattern directly\n * const schema2 = z.object({\n * name_kana: z.string().regex(KATAKANA_PATTERN, '全角カタカナで入力してください'),\n * });\n * ```\n */\n\nimport { z } from 'zod';\n\nexport interface KanaRuleOptions {\n /** Allow full-width katakana (ア-ン) - default: true */\n fullWidthKatakana?: boolean;\n /** Allow half-width katakana (ア-ン) - default: false */\n halfWidthKatakana?: boolean;\n /** Allow hiragana (あ-ん) - default: false */\n hiragana?: boolean;\n /** Allow numbers (0-9, 0-9) - default: false */\n allowNumbers?: boolean;\n /** Allow full-width numbers (0-9) - default: false */\n fullWidthNumbers?: boolean;\n /** Allow half-width numbers (0-9) - default: false */\n halfWidthNumbers?: boolean;\n /** Allow spaces (full-width and half-width) - default: true */\n allowSpaces?: boolean;\n /** Allow specific special characters - default: ['ー', '・'] */\n allowSpecialChars?: string[];\n /** Custom error message */\n message?: string;\n}\n\n// Character ranges\nconst CHAR_RANGES = {\n // Full-width Katakana: ァ-ヶ (U+30A1-U+30F6) + ー (U+30FC)\n fullWidthKatakana: 'ァ-ヶー',\n // Half-width Katakana: ヲ-゚ (U+FF66-U+FF9F)\n halfWidthKatakana: 'ヲ-゚',\n // Hiragana: ぁ-ゖ (U+3041-U+3096)\n hiragana: 'ぁ-ゖ',\n // Full-width numbers: 0-9\n fullWidthNumbers: '0-9',\n // Half-width numbers: 0-9\n halfWidthNumbers: '0-9',\n // Full-width space:  (U+3000)\n fullWidthSpace: ' ',\n // Half-width space\n halfWidthSpace: ' ',\n // Common special chars for names\n defaultSpecialChars: ['ー', '・'],\n} as const;\n\n// Default options: 全角カタカナ + spaces + ー・\nconst DEFAULT_OPTIONS: Required<KanaRuleOptions> = {\n fullWidthKatakana: true,\n halfWidthKatakana: false,\n hiragana: false,\n allowNumbers: false,\n fullWidthNumbers: false,\n halfWidthNumbers: false,\n allowSpaces: true,\n allowSpecialChars: ['ー', '・'],\n message: '',\n};\n\n/**\n * Build regex pattern from options\n */\nfunction buildKanaPattern(options: KanaRuleOptions = {}): string {\n const opts = { ...DEFAULT_OPTIONS, ...options };\n const parts: string[] = [];\n\n if (opts.fullWidthKatakana) {\n parts.push(CHAR_RANGES.fullWidthKatakana);\n }\n if (opts.halfWidthKatakana) {\n parts.push(CHAR_RANGES.halfWidthKatakana);\n }\n if (opts.hiragana) {\n parts.push(CHAR_RANGES.hiragana);\n }\n if (opts.allowNumbers || opts.fullWidthNumbers) {\n parts.push(CHAR_RANGES.fullWidthNumbers);\n }\n if (opts.allowNumbers || opts.halfWidthNumbers) {\n parts.push(CHAR_RANGES.halfWidthNumbers);\n }\n if (opts.allowSpaces) {\n parts.push(CHAR_RANGES.fullWidthSpace);\n parts.push(CHAR_RANGES.halfWidthSpace);\n }\n if (opts.allowSpecialChars && opts.allowSpecialChars.length > 0) {\n // Escape special regex chars\n const escaped = opts.allowSpecialChars\n .map((c) => c.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'))\n .join('');\n parts.push(escaped);\n }\n\n return `^[${parts.join('')}]*$`;\n}\n\n/**\n * Get default error message based on options\n */\nfunction getDefaultMessage(options: KanaRuleOptions = {}, locale = 'ja'): string {\n const opts = { ...DEFAULT_OPTIONS, ...options };\n\n const messages: Record<string, Record<string, string>> = {\n ja: {\n fullWidthKatakana: '全角カタカナ',\n halfWidthKatakana: '半角カタカナ',\n hiragana: 'ひらがな',\n mixed: 'カナ文字',\n },\n en: {\n fullWidthKatakana: 'full-width katakana',\n halfWidthKatakana: 'half-width katakana',\n hiragana: 'hiragana',\n mixed: 'kana characters',\n },\n };\n\n const msg = messages[locale] ?? messages['ja'];\n\n // Determine what type to show in message\n let type = msg.mixed;\n if (opts.fullWidthKatakana && !opts.halfWidthKatakana && !opts.hiragana) {\n type = msg.fullWidthKatakana;\n } else if (opts.halfWidthKatakana && !opts.fullWidthKatakana && !opts.hiragana) {\n type = msg.halfWidthKatakana;\n } else if (opts.hiragana && !opts.fullWidthKatakana && !opts.halfWidthKatakana) {\n type = msg.hiragana;\n }\n\n if (locale === 'ja') {\n return `${type}で入力してください`;\n }\n return `Please enter in ${type}`;\n}\n\n/**\n * Create a kana validation regex\n */\nexport function createKanaRegex(options: KanaRuleOptions = {}): RegExp {\n return new RegExp(buildKanaPattern(options));\n}\n\n/**\n * Validate a string against kana rules\n */\nexport function validateKana(value: string, options: KanaRuleOptions = {}): boolean {\n if (!value) return true; // Empty is valid (use required for that)\n const regex = createKanaRegex(options);\n return regex.test(value);\n}\n\n/**\n * Get kana validation pattern string (for Zod .regex())\n */\nexport function getKanaPattern(options: KanaRuleOptions = {}): string {\n return buildKanaPattern(options);\n}\n\n/**\n * Get error message for kana validation\n */\nexport function getKanaErrorMessage(options: KanaRuleOptions = {}, locale = 'ja'): string {\n return options.message ?? getDefaultMessage(options, locale);\n}\n\n// ============================================================================\n// Preset configurations\n// ============================================================================\n\n/** 全角カタカナ (Full-width Katakana) - Default for Japanese names */\nexport const KATAKANA_FULL_WIDTH: KanaRuleOptions = {\n fullWidthKatakana: true,\n halfWidthKatakana: false,\n hiragana: false,\n allowSpaces: true,\n allowSpecialChars: ['ー', '・'],\n};\n\n/** 半角カタカナ (Half-width Katakana) - Legacy systems */\nexport const KATAKANA_HALF_WIDTH: KanaRuleOptions = {\n fullWidthKatakana: false,\n halfWidthKatakana: true,\n hiragana: false,\n allowSpaces: true,\n allowSpecialChars: ['ー'], // Half-width prolonged sound mark\n};\n\n/** ひらがな (Hiragana) */\nexport const HIRAGANA: KanaRuleOptions = {\n fullWidthKatakana: false,\n halfWidthKatakana: false,\n hiragana: true,\n allowSpaces: true,\n allowSpecialChars: ['ー'],\n};\n\n/** カタカナ + ひらがな (Any kana) */\nexport const KANA_ANY: KanaRuleOptions = {\n fullWidthKatakana: true,\n halfWidthKatakana: true,\n hiragana: true,\n allowSpaces: true,\n allowSpecialChars: ['ー', '・', 'ー'],\n};\n\n/** 全角カタカナ + 数字 (Full-width katakana with numbers) */\nexport const KATAKANA_WITH_NUMBERS: KanaRuleOptions = {\n fullWidthKatakana: true,\n halfWidthKatakana: false,\n hiragana: false,\n allowNumbers: true,\n allowSpaces: true,\n allowSpecialChars: ['ー', '・'],\n};\n\n// ============================================================================\n// Pattern strings for Zod .regex()\n// ============================================================================\n\n/** Pattern: 全角カタカナ + スペース + ー・ (for z.string().regex()) */\nexport const KATAKANA_PATTERN = /^[ァ-ヶー・  ]*$/;\n\n/** Pattern: 半角カタカナ (for z.string().regex()) */\nexport const KATAKANA_HALF_PATTERN = /^[ヲ-゚ー ]*$/;\n\n/** Pattern: ひらがな (for z.string().regex()) */\nexport const HIRAGANA_PATTERN = /^[ぁ-ゖー  ]*$/;\n\n/** Pattern: すべてのかな (for z.string().regex()) */\nexport const KANA_ANY_PATTERN = /^[ァ-ヶぁ-ゖヲ-゚ー・ー  ]*$/;\n\n// ============================================================================\n// Zod refinement helpers\n// ============================================================================\n\n/**\n * Create Zod string schema with kana validation\n * @example\n * const schema = z.object({\n * name_kana: kanaString(), // 全角カタカナ (default)\n * name_kana2: kanaString({ hiragana: true }), // カタカナ + ひらがな\n * });\n */\nexport function kanaString(options: KanaRuleOptions = {}) {\n const opts = { ...KATAKANA_FULL_WIDTH, ...options };\n const regex = createKanaRegex(opts);\n const message = getKanaErrorMessage(opts);\n\n return z.string().regex(regex, { message });\n}\n\n/**\n * Add kana validation to existing Zod string schema\n * @example\n * const schema = z.string().min(1).pipe(withKana());\n */\nexport function withKana(options: KanaRuleOptions = {}) {\n return kanaString(options);\n}\n\n// Default export\nexport const kanaRules = {\n createRegex: createKanaRegex,\n validate: validateKana,\n getPattern: getKanaPattern,\n getMessage: getKanaErrorMessage,\n // Zod helpers\n string: kanaString,\n // Presets\n presets: {\n fullWidthKatakana: KATAKANA_FULL_WIDTH,\n halfWidthKatakana: KATAKANA_HALF_WIDTH,\n hiragana: HIRAGANA,\n any: KANA_ANY,\n withNumbers: KATAKANA_WITH_NUMBERS,\n },\n // Pattern constants for direct use\n patterns: {\n katakana: KATAKANA_PATTERN,\n katakanaHalf: KATAKANA_HALF_PATTERN,\n hiragana: HIRAGANA_PATTERN,\n any: KANA_ANY_PATTERN,\n },\n};\n"],"mappings":"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","names":[]}
package/package.json ADDED
@@ -0,0 +1,110 @@
1
+ {
2
+ "name": "@famgia/omnify-react",
3
+ "version": "0.0.1",
4
+ "description": "React runtime components, hooks, and utilities for Omnify schemas",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/index.js"
14
+ },
15
+ "require": {
16
+ "types": "./dist/index.d.cts",
17
+ "default": "./dist/index.cjs"
18
+ }
19
+ },
20
+ "./components": {
21
+ "import": {
22
+ "types": "./dist/components/index.d.ts",
23
+ "default": "./dist/components/index.js"
24
+ },
25
+ "require": {
26
+ "types": "./dist/components/index.d.cts",
27
+ "default": "./dist/components/index.cjs"
28
+ }
29
+ },
30
+ "./hooks": {
31
+ "import": {
32
+ "types": "./dist/hooks/index.d.ts",
33
+ "default": "./dist/hooks/index.js"
34
+ },
35
+ "require": {
36
+ "types": "./dist/hooks/index.d.cts",
37
+ "default": "./dist/hooks/index.cjs"
38
+ }
39
+ },
40
+ "./lib": {
41
+ "import": {
42
+ "types": "./dist/lib/index.d.ts",
43
+ "default": "./dist/lib/index.js"
44
+ },
45
+ "require": {
46
+ "types": "./dist/lib/index.d.cts",
47
+ "default": "./dist/lib/index.cjs"
48
+ }
49
+ }
50
+ },
51
+ "files": [
52
+ "dist",
53
+ "scripts",
54
+ "README.md"
55
+ ],
56
+ "keywords": [
57
+ "omnify",
58
+ "react",
59
+ "typescript",
60
+ "antd",
61
+ "zod",
62
+ "form",
63
+ "validation",
64
+ "i18n"
65
+ ],
66
+ "author": "Famgia",
67
+ "license": "MIT",
68
+ "repository": {
69
+ "type": "git",
70
+ "url": "https://github.com/ecsol/omnify-ts.git",
71
+ "directory": "packages/omnify-react"
72
+ },
73
+ "dependencies": {
74
+ "@tanstack/react-query": "^5.90.0"
75
+ },
76
+ "peerDependencies": {
77
+ "antd": "^6.0.0",
78
+ "react": "^18.0.0 || ^19.0.0",
79
+ "react-dom": "^18.0.0 || ^19.0.0",
80
+ "zod": "^3.25.0 || ^4.0.0"
81
+ },
82
+ "peerDependenciesMeta": {
83
+ "antd": {
84
+ "optional": false
85
+ },
86
+ "zod": {
87
+ "optional": false
88
+ }
89
+ },
90
+ "devDependencies": {
91
+ "@ant-design/icons": "^6.0.0",
92
+ "@types/react": "^19.0.0",
93
+ "@types/react-dom": "^19.0.0",
94
+ "antd": "^6.1.4",
95
+ "react": "^19.0.0",
96
+ "react-dom": "^19.0.0",
97
+ "tsup": "^8.5.1",
98
+ "typescript": "^5.8.3",
99
+ "vitest": "^3.2.4",
100
+ "zod": "^4.3.5"
101
+ },
102
+ "scripts": {
103
+ "build": "tsup",
104
+ "clean": "rm -rf dist",
105
+ "typecheck": "tsc --noEmit",
106
+ "test": "vitest run",
107
+ "test:watch": "vitest",
108
+ "postinstall": "node scripts/postinstall.cjs"
109
+ }
110
+ }