@famgia/omnify 1.0.100 → 1.0.102

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.
@@ -4,6 +4,91 @@
4
4
 
5
5
  All schemas are stored in `schemas/` directory with `.yaml` extension.
6
6
 
7
+ ## Multi-language Support (i18n)
8
+
9
+ Omnify supports multi-language labels and placeholders for internationalized applications.
10
+
11
+ ### Supported Locales
12
+
13
+ | Code | Language |
14
+ | ------- | ------------------------------ |
15
+ | `ja` | Japanese (日本語) |
16
+ | `en` | English |
17
+ | `vi` | Vietnamese (Tiếng Việt) |
18
+ | `ko` | Korean (한국어) |
19
+ | `zh-CN` | Simplified Chinese (简体中文) |
20
+ | `zh-TW` | Traditional Chinese (繁體中文) |
21
+ | `th` | Thai (ภาษาไทย) |
22
+ | `es` | Spanish (Español) |
23
+
24
+ ### Usage in Schema
25
+
26
+ ```yaml
27
+ # Model-level i18n
28
+ displayName:
29
+ ja: 顧客
30
+ en: Customer
31
+ vi: Khách hàng
32
+
33
+ description:
34
+ ja: 顧客情報を管理するモデル
35
+ en: Model for managing customer information
36
+ vi: Model quản lý thông tin khách hàng
37
+
38
+ properties:
39
+ email:
40
+ type: Email
41
+ # Property-level i18n
42
+ displayName:
43
+ ja: メールアドレス
44
+ en: Email Address
45
+ vi: Địa chỉ email
46
+ placeholder:
47
+ ja: "例:customer@example.com"
48
+ en: "e.g. customer@example.com"
49
+ vi: "VD: customer@example.com"
50
+ description:
51
+ ja: 連絡先メールアドレス
52
+ en: Contact email address
53
+ vi: Địa chỉ email liên hệ
54
+
55
+ notes:
56
+ type: Text
57
+ nullable: true
58
+ displayName:
59
+ ja: 備考
60
+ en: Notes
61
+ vi: Ghi chú
62
+ placeholder:
63
+ ja: 顧客に関するメモを入力してください
64
+ en: Enter notes about this customer
65
+ vi: Nhập ghi chú về khách hàng này
66
+ ```
67
+
68
+ ### Enum i18n
69
+
70
+ ```yaml
71
+ name: PostStatus
72
+ kind: enum
73
+ displayName:
74
+ ja: 投稿ステータス
75
+ en: Post Status
76
+ vi: Trạng thái bài viết
77
+ values:
78
+ draft:
79
+ ja: 下書き
80
+ en: Draft
81
+ vi: Bản nháp
82
+ published:
83
+ ja: 公開済み
84
+ en: Published
85
+ vi: Đã xuất bản
86
+ archived:
87
+ ja: アーカイブ
88
+ en: Archived
89
+ vi: Đã lưu trữ
90
+ ```
91
+
7
92
  ## Object Schema Structure
8
93
 
9
94
  ```yaml
@@ -17,77 +102,370 @@ description: # Optional: i18n description
17
102
  ja: 説明文
18
103
  en: Description
19
104
  group: group-name # Optional: for organizing schemas
105
+ titleIndex: name # Optional: property to use as record title/label
20
106
  options:
21
- id: true # Auto-generate id column (default: true)
22
- idType: BigInt # Id type: BigInt, Int, Uuid, String (default: BigInt)
23
- softDelete: true # Enable soft delete (deleted_at column)
24
- timestamps: true # Enable created_at, updated_at
25
- tableName: custom_name # Custom table name
26
- hidden: false # Hide from model generation (default: false)
107
+ # See Schema Options below
27
108
  properties:
28
109
  # Property definitions here
29
110
  ```
30
111
 
112
+ ### Schema Options Reference
113
+
114
+ | Option | Type | Default | Description |
115
+ | ------------------------------ | ------- | ---------- | -------------------------------------------------- |
116
+ | `id` | boolean | `true` | Auto-generate `id` primary key column |
117
+ | `idType` | string | `BigInt` | ID type: `BigInt`, `Int`, `Uuid`, `String` |
118
+ | `timestamps` | boolean | `false` | Add `created_at`, `updated_at` columns |
119
+ | `softDelete` | boolean | `false` | Add `deleted_at` column for soft deletes |
120
+ | `tableName` | string | - | Custom table name (default: pluralized snake_case) |
121
+ | `hidden` | boolean | `false` | Skip model generation (migrations only) |
122
+ | `translations` | boolean | `false` | Enable translations support |
123
+ | `unique` | array | - | Unique constraints (see below) |
124
+ | `indexes` | array | - | Database indexes (see below) |
125
+ | `authenticatable` | boolean | `false` | Enable auth trait (User-like schemas) |
126
+ | `authenticatableLoginIdField` | string | `email` | Login ID field for auth |
127
+ | `authenticatablePasswordField` | string | `password` | Password field for auth |
128
+ | `authenticatableGuardName` | string | - | Guard name for auth |
129
+
130
+ ### Schema Options Example
131
+
132
+ ```yaml
133
+ options:
134
+ id: true
135
+ idType: BigInt
136
+ timestamps: true
137
+ softDelete: true
138
+ tableName: custom_table_name
139
+ hidden: false
140
+
141
+ # Unique constraints
142
+ unique:
143
+ - email # Single column unique
144
+ - [tenant_id, slug] # Composite unique
145
+
146
+ # Database indexes
147
+ indexes:
148
+ - columns: [status] # Simple index
149
+ - columns: [published_at]
150
+ name: idx_published # Custom index name
151
+ - columns: [status, published_at]
152
+ unique: true # Unique index
153
+ - columns: [title]
154
+ type: fulltext # Fulltext index (MySQL)
155
+ ```
156
+
157
+ ### Authenticatable Schema (User)
158
+
159
+ ```yaml
160
+ name: User
161
+ displayName:
162
+ ja: ユーザー
163
+ en: User
164
+ options:
165
+ timestamps: true
166
+ softDelete: true
167
+ authenticatable: true
168
+ authenticatableLoginIdField: email
169
+ authenticatablePasswordField: password
170
+ authenticatableGuardName: web
171
+
172
+ properties:
173
+ email:
174
+ type: Email
175
+ unique: true
176
+ password:
177
+ type: Password
178
+ name:
179
+ type: String
180
+ ```
181
+
31
182
  ## Property Types
32
183
 
33
184
  ### String Types
34
- | Type | Description | Options |
35
- |------|-------------|---------|
36
- | `String` | Short text (varchar) | `length`, `default` |
37
- | `Text` | Text (~65KB) | `default` |
38
- | `MediumText` | Medium text (~16MB) | `default` |
39
- | `LongText` | Long text (~4GB) | `default` |
185
+ | Type | Description | Options |
186
+ | ------------ | -------------------- | ---------------------- |
187
+ | `String` | Short text (varchar) | `length`, `default` |
188
+ | `Email` | Email address | `length`, `default` |
189
+ | `Password` | Hashed password | `length` (auto-hidden) |
190
+ | `Text` | Text (~65KB) | `default` |
191
+ | `MediumText` | Medium text (~16MB) | `default` |
192
+ | `LongText` | Long text (~4GB) | `default` |
40
193
 
41
194
  ### Numeric Types
42
- | Type | Description | Options |
43
- |------|-------------|---------|
44
- | `TinyInt` | 8-bit integer (-128~127) | `default`, `unsigned` |
45
- | `Int` | 32-bit integer | `default`, `unsigned` |
46
- | `BigInt` | 64-bit integer | `default`, `unsigned` |
47
- | `Float` | Floating point | `default` |
48
- | `Decimal` | Precise decimal | `precision`, `scale`, `default` |
195
+ | Type | Description | Options |
196
+ | --------- | ------------------------ | ------------------------------- |
197
+ | `TinyInt` | 8-bit integer (-128~127) | `default`, `unsigned` |
198
+ | `Int` | 32-bit integer | `default`, `unsigned` |
199
+ | `BigInt` | 64-bit integer | `default`, `unsigned` |
200
+ | `Float` | Floating point | `default` |
201
+ | `Decimal` | Precise decimal | `precision`, `scale`, `default` |
49
202
 
50
203
  ### Date/Time Types
51
- | Type | Description | Options |
52
- |------|-------------|---------|
53
- | `Date` | Date only | `default` |
54
- | `DateTime` | Date and time | `default` |
55
- | `Timestamp` | Timestamp | `useCurrent`, `useCurrentOnUpdate` |
204
+ | Type | Description | Options |
205
+ | ----------- | ------------- | ---------------------------------- |
206
+ | `Date` | Date only | `default` |
207
+ | `Time` | Time only | `default` |
208
+ | `DateTime` | Date and time | `default` |
209
+ | `Timestamp` | Timestamp | `useCurrent`, `useCurrentOnUpdate` |
56
210
 
57
211
  ### Other Types
58
- | Type | Description | Options |
59
- |------|-------------|---------|
60
- | `Boolean` | True/false | `default` |
61
- | `Json` | JSON object | `default` |
62
- | `EnumRef` | Reference to enum | `enum` (required), `default` |
212
+ | Type | Description | Options |
213
+ | ------------- | ----------------------------- | ------------------------------------------- |
214
+ | `Boolean` | True/false | `default` |
215
+ | `Json` | JSON object | `default` |
216
+ | `EnumRef` | Reference to shared enum | `enum` (required), `default` |
217
+ | `Enum` | Inline enum values | `enum` (array of values), `default` |
218
+ | `File` | File attachment (polymorphic) | `multiple`, `maxFiles`, `accept`, `maxSize` |
219
+ | `Point` | Spatial POINT (lat/lng) | - |
220
+ | `Coordinates` | Two DECIMALs (lat, lng) | - (more portable than Point) |
221
+
222
+ ### File Type Example
223
+
224
+ ```yaml
225
+ avatar:
226
+ type: File
227
+ displayName:
228
+ ja: プロフィール画像
229
+ en: Profile Image
230
+ accept: [jpg, png, webp] # Allowed extensions
231
+ maxSize: 2048 # Max file size in KB
232
+
233
+ attachments:
234
+ type: File
235
+ multiple: true # Allow multiple files
236
+ maxFiles: 5 # Maximum number of files
237
+ accept: [pdf, doc, docx]
238
+ maxSize: 10240
239
+ ```
240
+
241
+ ### Inline Enum Example
242
+
243
+ ```yaml
244
+ priority:
245
+ type: Enum
246
+ enum: [low, medium, high] # Inline values
247
+ default: medium
248
+ displayName:
249
+ ja: 優先度
250
+ en: Priority
251
+ ```
252
+
253
+ ### Japan Types (Plugin: @famgia/omnify-japan)
254
+
255
+ Requires `@famgia/omnify-japan` plugin in `omnify.config.ts`.
256
+
257
+ #### Simple Types
258
+ | Type | Description | SQL Output |
259
+ | -------------------- | ---------------------------------- | ------------- |
260
+ | `JapanesePhone` | Phone number (e.g., 090-1234-5678) | `VARCHAR(15)` |
261
+ | `JapanesePostalCode` | Postal code (e.g., 123-4567) | `VARCHAR(8)` |
262
+
263
+ ```yaml
264
+ phone:
265
+ type: JapanesePhone
266
+ displayName:
267
+ ja: 電話番号
268
+ en: Phone Number
269
+ placeholder:
270
+ ja: "例:090-1234-5678"
271
+ en: "e.g. 090-1234-5678"
272
+
273
+ postal_code:
274
+ type: JapanesePostalCode
275
+ displayName:
276
+ ja: 郵便番号
277
+ en: Postal Code
278
+ ```
279
+
280
+ #### Compound Types (Auto-expand to multiple columns)
281
+
282
+ | Type | Expanded Columns |
283
+ | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
284
+ | `JapaneseName` | `{prefix}_lastname`, `{prefix}_firstname`, `{prefix}_kana_lastname`, `{prefix}_kana_firstname` |
285
+ | `JapaneseAddress` | `{prefix}_postal_code`, `{prefix}_prefecture`, `{prefix}_address1`, `{prefix}_address2`, `{prefix}_address3` |
286
+ | `JapaneseBankAccount` | `{prefix}_bank_code`, `{prefix}_bank_name`, `{prefix}_branch_code`, `{prefix}_branch_name`, `{prefix}_account_type`, `{prefix}_account_number`, `{prefix}_account_holder` |
287
+
288
+ ##### JapaneseName Example
289
+
290
+ ```yaml
291
+ name:
292
+ type: JapaneseName
293
+ displayName:
294
+ ja: 氏名
295
+ en: Full Name
296
+ # Override individual fields
297
+ fields:
298
+ Lastname:
299
+ length: 100 # Override VARCHAR length (default: 50)
300
+ displayName:
301
+ ja: 顧客姓
302
+ en: Customer Last Name
303
+ placeholder:
304
+ ja: "例:山田"
305
+ en: "e.g. Yamada"
306
+ Firstname:
307
+ length: 100
308
+ placeholder:
309
+ ja: "例:太郎"
310
+ en: "e.g. Taro"
311
+ KanaLastname:
312
+ length: 200
313
+ nullable: true # Make optional (default: required)
314
+ hidden: true # Hide from forms
315
+ placeholder:
316
+ ja: "例:ヤマダ"
317
+ en: "e.g. Yamada (Kana)"
318
+ KanaFirstname:
319
+ length: 200
320
+ nullable: true
321
+ hidden: true
322
+ ```
323
+
324
+ ##### JapaneseAddress Example
325
+
326
+ ```yaml
327
+ address:
328
+ type: JapaneseAddress
329
+ displayName:
330
+ ja: 住所
331
+ en: Address
332
+ fields:
333
+ # PostalCode: uses plugin default (例:123-4567)
334
+ # Prefecture: uses Prefecture enum from plugin (47 prefectures)
335
+ Address1:
336
+ displayName:
337
+ ja: 市区町村
338
+ en: City/Ward
339
+ Address2:
340
+ displayName:
341
+ ja: 番地
342
+ en: Street Address
343
+ Address3:
344
+ nullable: true
345
+ placeholder:
346
+ ja: "マンション名・部屋番号(任意)"
347
+ en: "Apartment/Room (optional)"
348
+ ```
349
+
350
+ ##### JapaneseBankAccount Example
351
+
352
+ ```yaml
353
+ bank:
354
+ type: JapaneseBankAccount
355
+ nullable: true
356
+ displayName:
357
+ ja: 銀行口座
358
+ en: Bank Account
359
+ fields:
360
+ BankCode:
361
+ nullable: true
362
+ # Format: 4-digit code (e.g., 0001)
363
+ BankName:
364
+ nullable: true
365
+ BranchCode:
366
+ nullable: true
367
+ # Format: 3-digit code (e.g., 001)
368
+ BranchName:
369
+ nullable: true
370
+ AccountType:
371
+ nullable: true
372
+ # Uses BankAccountType enum: 1(普通), 2(当座), 4(貯蓄)
373
+ AccountNumber:
374
+ nullable: true
375
+ # Format: 7-digit number
376
+ AccountHolder:
377
+ nullable: true
378
+ # Katakana only (e.g., ヤマダ タロウ)
379
+ ```
380
+
381
+ #### Plugin Enums
382
+
383
+ | Enum | Description | Values |
384
+ | ----------------- | ----------------------- | ----------------------------------------------- |
385
+ | `Prefecture` | 47 Japanese prefectures | `hokkaido`, `tokyo`, `osaka`, ... (string keys) |
386
+ | `PrefectureCode` | Prefecture JIS codes | `1`-`47` (numeric) |
387
+ | `BankAccountType` | Bank account types | `1`=普通, `2`=当座, `4`=貯蓄 |
63
388
 
64
389
  ### Association Type
65
- | Type | Description | Options |
66
- |------|-------------|---------|
67
- | `Association` | Relation | `relation`, `target`, `onDelete`, `mappedBy` |
390
+ | Type | Description | Options |
391
+ | ------------- | ----------- | -------------------------------------------- |
392
+ | `Association` | Relation | `relation`, `target`, `onDelete`, `mappedBy` |
68
393
 
69
394
  ## Property Options
70
395
 
396
+ ### All Property Options Reference
397
+
398
+ | Option | Type | Default | Description |
399
+ | ------------- | --------------- | ------- | -------------------------------------------- |
400
+ | `type` | string | - | **Required.** Property type |
401
+ | `displayName` | LocalizedString | - | Human-readable label (i18n) |
402
+ | `description` | LocalizedString | - | Field description/help text (i18n) |
403
+ | `placeholder` | LocalizedString | - | Form input placeholder (i18n) |
404
+ | `nullable` | boolean | `false` | Allow NULL in database |
405
+ | `unique` | boolean | `false` | Unique constraint |
406
+ | `default` | any | - | Default value |
407
+ | `primary` | boolean | `false` | Primary key (use with `options.id: false`) |
408
+ | `hidden` | boolean | `false` | Hide from API responses (Laravel: `$hidden`) |
409
+ | `fillable` | boolean | `true` | Mass assignable (Laravel: `$fillable`) |
410
+ | `renamedFrom` | string | - | Previous column name (for rename migrations) |
411
+ | `length` | number | `255` | VARCHAR length (String/Email/Password only) |
412
+ | `unsigned` | boolean | `false` | Unsigned number (numeric types only) |
413
+ | `precision` | number | `8` | Total digits (Decimal only) |
414
+ | `scale` | number | `2` | Decimal places (Decimal only) |
415
+ | `rules` | object | - | Validation rules (app-level, NOT database) |
416
+ | `fields` | object | - | Per-field overrides (compound types only) |
417
+
418
+ ### Example with All Options
419
+
71
420
  ```yaml
72
421
  properties:
73
422
  name:
74
423
  type: String
424
+ length: 100 # VARCHAR(100)
75
425
  displayName:
76
426
  ja: 名前
77
427
  en: Name
78
- placeholder: # Placeholder for form inputs (multi-language)
428
+ description:
429
+ ja: ユーザーの表示名
430
+ en: Display name for the user
431
+ placeholder:
79
432
  ja: 名前を入力
80
433
  en: Enter name
81
- vi: Nhập tên
82
- nullable: false # Nullable (default: false)
83
- unique: true # Unique constraint
84
- primary: true # Primary key (use with options.id: false)
85
- default: 'default' # Default value
86
- rules: # Validation rules (app-level, not DB)
87
- required: true
88
- maxLength: 255
434
+ nullable: false # NOT NULL
435
+ unique: true # UNIQUE constraint
436
+ default: 'Guest' # Default value
437
+ rules:
438
+ required: true # App-level validation
439
+ minLength: 2
440
+ maxLength: 100
441
+
442
+ password:
443
+ type: Password
444
+ hidden: true # Auto-hidden for Password, but explicit is clearer
445
+ fillable: true # Allow mass assignment
446
+
447
+ old_email:
448
+ type: Email
449
+ renamedFrom: email_address # Rename migration from old column name
450
+
451
+ price:
452
+ type: Decimal
453
+ precision: 10 # Total 10 digits
454
+ scale: 2 # 2 decimal places (e.g., 99999999.99)
455
+ unsigned: true # Positive only
89
456
  ```
90
457
 
458
+ ### Validation Rules (App-level)
459
+
460
+ ```yaml
461
+ rules:
462
+ required: true # Field is required (form validation)
463
+ minLength: 2 # Minimum string length
464
+ maxLength: 255 # Maximum string length
465
+ ```
466
+
467
+ **Note:** `rules` are for application/form validation only. They do NOT affect database structure. Use `nullable: false` for database-level NOT NULL constraint.
468
+
91
469
  ## Placeholder for Compound Types
92
470
 
93
471
  For compound types (like JapaneseName, JapaneseAddress), you can customize placeholders per field:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@famgia/omnify",
3
- "version": "1.0.100",
3
+ "version": "1.0.102",
4
4
  "description": "Schema-driven database migration system with TypeScript types and Laravel migrations",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -25,14 +25,14 @@
25
25
  "README.md"
26
26
  ],
27
27
  "dependencies": {
28
- "@famgia/omnify-cli": "0.0.96",
29
- "@famgia/omnify-core": "0.0.90",
30
- "@famgia/omnify-typescript": "0.0.78",
31
- "@famgia/omnify-types": "0.0.88",
32
- "@famgia/omnify-laravel": "0.0.99",
33
- "@famgia/omnify-atlas": "0.0.84",
34
- "@famgia/omnify-mcp": "0.0.76",
35
- "@famgia/omnify-japan": "0.0.83"
28
+ "@famgia/omnify-typescript": "0.0.80",
29
+ "@famgia/omnify-laravel": "0.0.101",
30
+ "@famgia/omnify-atlas": "0.0.86",
31
+ "@famgia/omnify-core": "0.0.92",
32
+ "@famgia/omnify-types": "0.0.90",
33
+ "@famgia/omnify-cli": "0.0.98",
34
+ "@famgia/omnify-japan": "0.0.85",
35
+ "@famgia/omnify-mcp": "0.0.78"
36
36
  },
37
37
  "keywords": [
38
38
  "omnify",