@famgia/omnify-typescript 0.0.145 → 0.0.147

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.
@@ -1,13 +0,0 @@
1
- import { JapaneseNameField } from './JapaneseNameField';
2
- import { JapaneseAddressField } from './JapaneseAddressField';
3
- import { JapaneseBankField } from './JapaneseBankField';
4
-
5
- // Namespace style exports (recommended)
6
- export const OmnifyForm = {
7
- JapaneseName: JapaneseNameField,
8
- JapaneseAddress: JapaneseAddressField,
9
- JapaneseBank: JapaneseBankField,
10
- } as const;
11
-
12
- // Legacy exports (backward compatible)
13
- export { JapaneseNameField, JapaneseAddressField, JapaneseBankField };
@@ -1,123 +0,0 @@
1
- /**
2
- * Form validation utilities for Ant Design + Zod
3
- *
4
- * ⚠️ AUTO-GENERATED by Omnify - DO NOT EDIT
5
- * This file is overwritten on every `npx omnify generate`
6
- *
7
- * Compatible with Zod v4.x
8
- */
9
-
10
- import type { RuleObject } from 'antd/es/form';
11
- import type { z } from 'zod';
12
- import { getZodMessage } from './zod-i18n';
13
-
14
- /**
15
- * Convert Zod schema to Ant Design Form rule with i18n support
16
- *
17
- * @example
18
- * // Set locale once at component level
19
- * setZodLocale('ja');
20
- *
21
- * // Use without passing locale
22
- * <Form.Item
23
- * name="email"
24
- * rules={[zodRule(customerSchemas.email, 'メールアドレス')]}
25
- * >
26
- * <Input />
27
- * </Form.Item>
28
- */
29
- export function zodRule<T extends z.ZodTypeAny>(
30
- schema: T,
31
- displayName?: string
32
- ): RuleObject {
33
- const field = displayName ?? 'この項目';
34
-
35
- return {
36
- validator: async (_, value) => {
37
- // 空チェック - 必須として扱う
38
- if (value === undefined || value === null || value === '') {
39
- if (schema.safeParse(undefined).success) return;
40
- throw new Error(getZodMessage('required', { displayName: field }));
41
- }
42
-
43
- const result = schema.safeParse(value);
44
- if (result.success) return;
45
-
46
- // 最初のZodエラーを取得
47
- const issue = result.error.issues[0];
48
- if (!issue) {
49
- throw new Error(getZodMessage('required', { displayName: field }));
50
- }
51
-
52
- // エラータイプに基づいて翻訳(Zod v4対応)
53
- const issueAny = issue as unknown as Record<string, unknown>;
54
- switch (issue.code) {
55
- case 'too_small': {
56
- const origin = issueAny.origin as string | undefined;
57
- const minimum = issueAny.minimum as number;
58
- if (origin === 'string' && minimum === 1) {
59
- throw new Error(getZodMessage('required', { displayName: field }));
60
- }
61
- if (origin === 'string') {
62
- throw new Error(getZodMessage('minLength', { displayName: field, min: minimum }));
63
- }
64
- throw new Error(getZodMessage('min', { displayName: field, min: minimum }));
65
- }
66
-
67
- case 'too_big': {
68
- const origin = issueAny.origin as string | undefined;
69
- const maximum = issueAny.maximum as number;
70
- if (origin === 'string') {
71
- throw new Error(getZodMessage('maxLength', { displayName: field, max: maximum }));
72
- }
73
- throw new Error(getZodMessage('max', { displayName: field, max: maximum }));
74
- }
75
-
76
- // Zod v4: 'invalid_string' → 'invalid_format'
77
- case 'invalid_format': {
78
- const format = issueAny.format as string | undefined;
79
- if (format === 'email') {
80
- throw new Error(getZodMessage('email', { displayName: field }));
81
- }
82
- if (format === 'url') {
83
- throw new Error(getZodMessage('url', { displayName: field }));
84
- }
85
- if (format === 'regex') {
86
- throw new Error(getZodMessage('pattern', { displayName: field }));
87
- }
88
- break;
89
- }
90
-
91
- case 'invalid_type': {
92
- const expected = issueAny.expected as string | undefined;
93
- // Zod v4: チェックはexpectedフィールドを使用
94
- if (expected && value === undefined) {
95
- throw new Error(getZodMessage('required', { displayName: field }));
96
- }
97
- break;
98
- }
99
- }
100
-
101
- // フォールバック: Zodのオリジナルメッセージを使用
102
- throw new Error(issue.message);
103
- },
104
- };
105
- }
106
-
107
- /**
108
- * Create required rule with i18n message
109
- *
110
- * @example
111
- * <Form.Item
112
- * name="name"
113
- * rules={[requiredRule('名前')]}
114
- * >
115
- * <Input />
116
- * </Form.Item>
117
- */
118
- export function requiredRule(displayName: string): RuleObject {
119
- return {
120
- required: true,
121
- message: getZodMessage('required', { displayName }),
122
- };
123
- }
@@ -1,51 +0,0 @@
1
- /**
2
- * Japanese validation rules
3
- *
4
- * ⚠️ AUTO-GENERATED by Omnify - DO NOT EDIT
5
- * This file is overwritten on every `npx omnify generate`
6
- *
7
- * Usage with Zod:
8
- * ```typescript
9
- * import { z } from 'zod';
10
- * import { kanaString, KATAKANA_PATTERN } from '@/omnify/lib/rules';
11
- *
12
- * // Method 1: Use kanaString helper
13
- * const schema = z.object({
14
- * name_kana: kanaString(), // 全角カタカナ (default)
15
- * });
16
- *
17
- * // Method 2: Use pattern directly
18
- * const schema2 = z.object({
19
- * name_kana: z.string().regex(KATAKANA_PATTERN, '全角カタカナで入力してください'),
20
- * });
21
- * ```
22
- */
23
-
24
- export {
25
- // Kana validation
26
- kanaRules,
27
- createKanaRegex,
28
- validateKana,
29
- getKanaPattern,
30
- getKanaErrorMessage,
31
- // Zod helpers
32
- kanaString,
33
- withKana,
34
- // Pattern constants
35
- KATAKANA_PATTERN,
36
- KATAKANA_HALF_PATTERN,
37
- HIRAGANA_PATTERN,
38
- KANA_ANY_PATTERN,
39
- // Presets
40
- KATAKANA_FULL_WIDTH,
41
- KATAKANA_HALF_WIDTH,
42
- HIRAGANA,
43
- KANA_ANY,
44
- KATAKANA_WITH_NUMBERS,
45
- // Types
46
- type KanaRuleOptions,
47
- } from './kana';
48
-
49
- // Re-export as convenient aliases
50
- export { getKanaPattern as kanaPattern } from './kana';
51
- export { createKanaRegex as kanaRegex } from './kana';
@@ -1,294 +0,0 @@
1
- /**
2
- * Japanese Kana Validation Rules
3
- *
4
- * ⚠️ AUTO-GENERATED by Omnify - DO NOT EDIT
5
- * This file is overwritten on every `npx omnify generate`
6
- *
7
- * Provides configurable validation for Japanese character input:
8
- * - 全角カタカナ (Full-width Katakana) - default
9
- * - 半角カタカナ (Half-width Katakana)
10
- * - ひらがな (Hiragana)
11
- * - Mixed modes
12
- */
13
-
14
- export interface KanaRuleOptions {
15
- /** Allow full-width katakana (ア-ン) - default: true */
16
- fullWidthKatakana?: boolean;
17
- /** Allow half-width katakana (ア-ン) - default: false */
18
- halfWidthKatakana?: boolean;
19
- /** Allow hiragana (あ-ん) - default: false */
20
- hiragana?: boolean;
21
- /** Allow numbers (0-9, 0-9) - default: false */
22
- allowNumbers?: boolean;
23
- /** Allow full-width numbers (0-9) - default: false */
24
- fullWidthNumbers?: boolean;
25
- /** Allow half-width numbers (0-9) - default: false */
26
- halfWidthNumbers?: boolean;
27
- /** Allow spaces (full-width and half-width) - default: true */
28
- allowSpaces?: boolean;
29
- /** Allow specific special characters - default: ['ー', '・'] */
30
- allowSpecialChars?: string[];
31
- /** Custom error message */
32
- message?: string;
33
- }
34
-
35
- // Character ranges
36
- const CHAR_RANGES = {
37
- // Full-width Katakana: ァ-ヶ (U+30A1-U+30F6) + ー (U+30FC)
38
- fullWidthKatakana: 'ァ-ヶー',
39
- // Half-width Katakana: ヲ-゚ (U+FF66-U+FF9F)
40
- halfWidthKatakana: 'ヲ-゚',
41
- // Hiragana: ぁ-ゖ (U+3041-U+3096)
42
- hiragana: 'ぁ-ゖ',
43
- // Full-width numbers: 0-9
44
- fullWidthNumbers: '0-9',
45
- // Half-width numbers: 0-9
46
- halfWidthNumbers: '0-9',
47
- // Full-width space:  (U+3000)
48
- fullWidthSpace: ' ',
49
- // Half-width space
50
- halfWidthSpace: ' ',
51
- // Common special chars for names
52
- defaultSpecialChars: ['ー', '・'],
53
- } as const;
54
-
55
- // Default options: 全角カタカナ + spaces + ー・
56
- const DEFAULT_OPTIONS: Required<KanaRuleOptions> = {
57
- fullWidthKatakana: true,
58
- halfWidthKatakana: false,
59
- hiragana: false,
60
- allowNumbers: false,
61
- fullWidthNumbers: false,
62
- halfWidthNumbers: false,
63
- allowSpaces: true,
64
- allowSpecialChars: ['ー', '・'],
65
- message: '',
66
- };
67
-
68
- /**
69
- * Build regex pattern from options
70
- */
71
- function buildKanaPattern(options: KanaRuleOptions = {}): string {
72
- const opts = { ...DEFAULT_OPTIONS, ...options };
73
- const parts: string[] = [];
74
-
75
- if (opts.fullWidthKatakana) {
76
- parts.push(CHAR_RANGES.fullWidthKatakana);
77
- }
78
- if (opts.halfWidthKatakana) {
79
- parts.push(CHAR_RANGES.halfWidthKatakana);
80
- }
81
- if (opts.hiragana) {
82
- parts.push(CHAR_RANGES.hiragana);
83
- }
84
- if (opts.allowNumbers || opts.fullWidthNumbers) {
85
- parts.push(CHAR_RANGES.fullWidthNumbers);
86
- }
87
- if (opts.allowNumbers || opts.halfWidthNumbers) {
88
- parts.push(CHAR_RANGES.halfWidthNumbers);
89
- }
90
- if (opts.allowSpaces) {
91
- parts.push(CHAR_RANGES.fullWidthSpace);
92
- parts.push(CHAR_RANGES.halfWidthSpace);
93
- }
94
- if (opts.allowSpecialChars && opts.allowSpecialChars.length > 0) {
95
- // Escape special regex chars
96
- const escaped = opts.allowSpecialChars.map(c =>
97
- c.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
98
- ).join('');
99
- parts.push(escaped);
100
- }
101
-
102
- return `^[${parts.join('')}]*$`;
103
- }
104
-
105
- /**
106
- * Get default error message based on options
107
- */
108
- function getDefaultMessage(options: KanaRuleOptions = {}, locale: string = 'ja'): string {
109
- const opts = { ...DEFAULT_OPTIONS, ...options };
110
-
111
- const messages: Record<string, Record<string, string>> = {
112
- ja: {
113
- fullWidthKatakana: '全角カタカナ',
114
- halfWidthKatakana: '半角カタカナ',
115
- hiragana: 'ひらがな',
116
- mixed: 'カナ文字',
117
- },
118
- en: {
119
- fullWidthKatakana: 'full-width katakana',
120
- halfWidthKatakana: 'half-width katakana',
121
- hiragana: 'hiragana',
122
- mixed: 'kana characters',
123
- },
124
- };
125
-
126
- const msg = messages[locale] ?? messages['ja'];
127
-
128
- // Determine what type to show in message
129
- let type = msg.mixed;
130
- if (opts.fullWidthKatakana && !opts.halfWidthKatakana && !opts.hiragana) {
131
- type = msg.fullWidthKatakana;
132
- } else if (opts.halfWidthKatakana && !opts.fullWidthKatakana && !opts.hiragana) {
133
- type = msg.halfWidthKatakana;
134
- } else if (opts.hiragana && !opts.fullWidthKatakana && !opts.halfWidthKatakana) {
135
- type = msg.hiragana;
136
- }
137
-
138
- if (locale === 'ja') {
139
- return `${type}で入力してください`;
140
- }
141
- return `Please enter in ${type}`;
142
- }
143
-
144
- /**
145
- * Create a kana validation regex
146
- */
147
- export function createKanaRegex(options: KanaRuleOptions = {}): RegExp {
148
- return new RegExp(buildKanaPattern(options));
149
- }
150
-
151
- /**
152
- * Validate a string against kana rules
153
- */
154
- export function validateKana(value: string, options: KanaRuleOptions = {}): boolean {
155
- if (!value) return true; // Empty is valid (use required for that)
156
- const regex = createKanaRegex(options);
157
- return regex.test(value);
158
- }
159
-
160
- /**
161
- * Get kana validation pattern string (for Zod .regex())
162
- */
163
- export function getKanaPattern(options: KanaRuleOptions = {}): string {
164
- return buildKanaPattern(options);
165
- }
166
-
167
- /**
168
- * Get error message for kana validation
169
- */
170
- export function getKanaErrorMessage(options: KanaRuleOptions = {}, locale: string = 'ja'): string {
171
- return options.message ?? getDefaultMessage(options, locale);
172
- }
173
-
174
- // ============================================================================
175
- // Preset configurations
176
- // ============================================================================
177
-
178
- /** 全角カタカナ (Full-width Katakana) - Default for Japanese names */
179
- export const KATAKANA_FULL_WIDTH: KanaRuleOptions = {
180
- fullWidthKatakana: true,
181
- halfWidthKatakana: false,
182
- hiragana: false,
183
- allowSpaces: true,
184
- allowSpecialChars: ['ー', '・'],
185
- };
186
-
187
- /** 半角カタカナ (Half-width Katakana) - Legacy systems */
188
- export const KATAKANA_HALF_WIDTH: KanaRuleOptions = {
189
- fullWidthKatakana: false,
190
- halfWidthKatakana: true,
191
- hiragana: false,
192
- allowSpaces: true,
193
- allowSpecialChars: ['ー'], // Half-width prolonged sound mark
194
- };
195
-
196
- /** ひらがな (Hiragana) */
197
- export const HIRAGANA: KanaRuleOptions = {
198
- fullWidthKatakana: false,
199
- halfWidthKatakana: false,
200
- hiragana: true,
201
- allowSpaces: true,
202
- allowSpecialChars: ['ー'],
203
- };
204
-
205
- /** カタカナ + ひらがな (Any kana) */
206
- export const KANA_ANY: KanaRuleOptions = {
207
- fullWidthKatakana: true,
208
- halfWidthKatakana: true,
209
- hiragana: true,
210
- allowSpaces: true,
211
- allowSpecialChars: ['ー', '・', 'ー'],
212
- };
213
-
214
- /** 全角カタカナ + 数字 (Full-width katakana with numbers) */
215
- export const KATAKANA_WITH_NUMBERS: KanaRuleOptions = {
216
- fullWidthKatakana: true,
217
- halfWidthKatakana: false,
218
- hiragana: false,
219
- allowNumbers: true,
220
- allowSpaces: true,
221
- allowSpecialChars: ['ー', '・'],
222
- };
223
-
224
- // ============================================================================
225
- // Pattern strings for Zod .regex()
226
- // ============================================================================
227
-
228
- /** Pattern: 全角カタカナ + スペース + ー・ (for z.string().regex()) */
229
- export const KATAKANA_PATTERN = /^[ァ-ヶー・  ]*$/;
230
-
231
- /** Pattern: 半角カタカナ (for z.string().regex()) */
232
- export const KATAKANA_HALF_PATTERN = /^[ヲ-゚ー ]*$/;
233
-
234
- /** Pattern: ひらがな (for z.string().regex()) */
235
- export const HIRAGANA_PATTERN = /^[ぁ-ゖー  ]*$/;
236
-
237
- /** Pattern: すべてのかな (for z.string().regex()) */
238
- export const KANA_ANY_PATTERN = /^[ァ-ヶぁ-ゖヲ-゚ー・ー  ]*$/;
239
-
240
- // ============================================================================
241
- // Zod refinement helpers
242
- // ============================================================================
243
-
244
- import { z } from 'zod';
245
-
246
- /**
247
- * Create Zod string schema with kana validation
248
- * @example
249
- * const schema = z.object({
250
- * name_kana: kanaString(), // 全角カタカナ (default)
251
- * name_kana2: kanaString({ hiragana: true }), // カタカナ + ひらがな
252
- * });
253
- */
254
- export function kanaString(options: KanaRuleOptions = {}) {
255
- const opts = { ...KATAKANA_FULL_WIDTH, ...options };
256
- const regex = createKanaRegex(opts);
257
- const message = getKanaErrorMessage(opts);
258
-
259
- return z.string().regex(regex, { message });
260
- }
261
-
262
- /**
263
- * Add kana validation to existing Zod string schema
264
- * @example
265
- * const schema = z.string().min(1).pipe(withKana());
266
- */
267
- export function withKana(options: KanaRuleOptions = {}) {
268
- return kanaString(options);
269
- }
270
-
271
- // Default export
272
- export const kanaRules = {
273
- createRegex: createKanaRegex,
274
- validate: validateKana,
275
- getPattern: getKanaPattern,
276
- getMessage: getKanaErrorMessage,
277
- // Zod helpers
278
- string: kanaString,
279
- // Presets
280
- presets: {
281
- fullWidthKatakana: KATAKANA_FULL_WIDTH,
282
- halfWidthKatakana: KATAKANA_HALF_WIDTH,
283
- hiragana: HIRAGANA,
284
- any: KANA_ANY,
285
- withNumbers: KATAKANA_WITH_NUMBERS,
286
- },
287
- // Pattern constants for direct use
288
- patterns: {
289
- katakana: KATAKANA_PATTERN,
290
- katakanaHalf: KATAKANA_HALF_PATTERN,
291
- hiragana: HIRAGANA_PATTERN,
292
- any: KANA_ANY_PATTERN,
293
- },
294
- };
@@ -1,119 +0,0 @@
1
- /**
2
- * useFormMutation - Form mutation with auto Laravel error handling
3
- *
4
- * ⚠️ AUTO-GENERATED by Omnify - DO NOT EDIT
5
- * This file is overwritten on every `npx omnify generate`
6
- *
7
- * @example
8
- * const mutation = useFormMutation({
9
- * form,
10
- * mutationFn: (data) => axios.post('/api/customers', data),
11
- * invalidateKeys: [['customers']],
12
- * successMessage: '保存しました',
13
- * });
14
- *
15
- * <Form form={form} onFinish={mutation.mutate}>
16
- * ...
17
- * <Button loading={mutation.isPending}>保存</Button>
18
- * </Form>
19
- */
20
-
21
- import { useMutation, useQueryClient } from '@tanstack/react-query';
22
- import { App } from 'antd';
23
- import type { FormInstance } from 'antd';
24
-
25
- // =============================================================================
26
- // Types
27
- // =============================================================================
28
-
29
- interface UseFormMutationOptions<TData, TResult> {
30
- /** Ant Design form instance */
31
- form: FormInstance;
32
- /** API call function */
33
- mutationFn: (data: TData) => Promise<TResult>;
34
- /** Query keys to invalidate on success */
35
- invalidateKeys?: readonly (readonly unknown[])[];
36
- /** Success message to show */
37
- successMessage?: string;
38
- /** Callback on success */
39
- onSuccess?: (data: TResult) => void;
40
- /** Callback on error */
41
- onError?: (error: unknown) => void;
42
- }
43
-
44
- // =============================================================================
45
- // Laravel Error Helpers
46
- // =============================================================================
47
-
48
- /**
49
- * Parse Laravel validation errors to Ant Design form format
50
- */
51
- function getFormErrors(error: unknown): { name: string; errors: string[] }[] {
52
- const data = (error as any)?.response?.data;
53
- const errors = data?.errors;
54
-
55
- if (!errors || typeof errors !== 'object') return [];
56
-
57
- return Object.entries(errors).map(([name, messages]) => ({
58
- name,
59
- errors: Array.isArray(messages) ? messages : [String(messages)],
60
- }));
61
- }
62
-
63
- /**
64
- * Get general validation message from Laravel response
65
- */
66
- function getValidationMessage(error: unknown): string | null {
67
- const data = (error as any)?.response?.data;
68
- return data?.message || null;
69
- }
70
-
71
- // =============================================================================
72
- // Hook
73
- // =============================================================================
74
-
75
- export function useFormMutation<TData, TResult = unknown>({
76
- form,
77
- mutationFn,
78
- invalidateKeys = [],
79
- successMessage,
80
- onSuccess,
81
- onError,
82
- }: UseFormMutationOptions<TData, TResult>) {
83
- const queryClient = useQueryClient();
84
- const { message } = App.useApp();
85
-
86
- return useMutation({
87
- mutationFn,
88
- onSuccess: (data) => {
89
- // Invalidate queries
90
- invalidateKeys.forEach((key) => {
91
- queryClient.invalidateQueries({ queryKey: [...key] });
92
- });
93
-
94
- // Show success message
95
- if (successMessage) {
96
- message.success(successMessage);
97
- }
98
-
99
- // Custom callback
100
- onSuccess?.(data);
101
- },
102
- onError: (error) => {
103
- // Set form field errors from Laravel validation
104
- const formErrors = getFormErrors(error);
105
- if (formErrors.length > 0) {
106
- form.setFields(formErrors);
107
- }
108
-
109
- // Show general error message
110
- const validationMessage = getValidationMessage(error);
111
- if (validationMessage) {
112
- message.error(validationMessage);
113
- }
114
-
115
- // Custom callback
116
- onError?.(error);
117
- },
118
- });
119
- }
@@ -1,34 +0,0 @@
1
- /**
2
- * Zod i18n - Localization for Zod validation messages
3
- *
4
- * ⚠️ AUTO-GENERATED by Omnify - DO NOT EDIT
5
- * This file is overwritten on every `npx omnify generate`
6
- */
7
-
8
- import { getMessage, defaultLocale } from '../schemas/i18n';
9
-
10
- let currentLocale: string = defaultLocale;
11
-
12
- /**
13
- * Set current locale for Zod validation messages
14
- */
15
- export function setZodLocale(locale: string) {
16
- currentLocale = locale;
17
- }
18
-
19
- /**
20
- * Get current locale
21
- */
22
- export function getZodLocale(): string {
23
- return currentLocale;
24
- }
25
-
26
- /**
27
- * Get translated validation message
28
- */
29
- export function getZodMessage(
30
- key: string,
31
- params?: Record<string, string | number>
32
- ): string {
33
- return getMessage(key, currentLocale, params);
34
- }