@omnifyjp/omnify 1.1.0 → 1.1.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@omnifyjp/omnify",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "description": "Schema-driven code generation for Laravel, TypeScript, and SQL",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -36,10 +36,10 @@
36
36
  "zod": "^3.24.0"
37
37
  },
38
38
  "optionalDependencies": {
39
- "@omnifyjp/omnify-darwin-arm64": "1.1.0",
40
- "@omnifyjp/omnify-darwin-x64": "1.1.0",
41
- "@omnifyjp/omnify-linux-x64": "1.1.0",
42
- "@omnifyjp/omnify-linux-arm64": "1.1.0",
43
- "@omnifyjp/omnify-win32-x64": "1.1.0"
39
+ "@omnifyjp/omnify-darwin-arm64": "1.1.2",
40
+ "@omnifyjp/omnify-darwin-x64": "1.1.2",
41
+ "@omnifyjp/omnify-linux-x64": "1.1.2",
42
+ "@omnifyjp/omnify-linux-arm64": "1.1.2",
43
+ "@omnifyjp/omnify-win32-x64": "1.1.2"
44
44
  }
45
45
  }
@@ -42,20 +42,23 @@ function generateBaseModel(name, schema, reader, config) {
42
42
  const hasTimestamps = options.timestamps ?? false;
43
43
  const translatableFields = reader.getTranslatableFields(name);
44
44
  const hasTranslatable = translatableFields.length > 0;
45
- const imports = buildImports(baseNamespace, modelName, hasSoftDelete, isAuthenticatable, hasTranslatable, properties);
45
+ const primaryKey = options['primaryKey'] ?? 'id';
46
+ const rawId = options.id;
47
+ const idType = typeof rawId === 'string' ? rawId : 'BigInt';
48
+ const isCompositeKey = primaryKey.includes(',');
49
+ const needsUuidTrait = !isCompositeKey && idType === 'Uuid';
50
+ const needsUlidTrait = !isCompositeKey && idType === 'Ulid';
51
+ const imports = buildImports(baseNamespace, modelName, hasSoftDelete, isAuthenticatable, hasTranslatable, properties, needsUuidTrait, needsUlidTrait);
46
52
  const docProperties = buildDocProperties(properties, expandedProperties, propertyOrder);
47
53
  const baseClass = isAuthenticatable ? 'Authenticatable' : 'BaseModel';
48
54
  const implementsClause = hasTranslatable ? ' implements TranslatableContract' : '';
49
- const traits = buildTraits(hasSoftDelete, isAuthenticatable, hasTranslatable);
55
+ const traits = buildTraits(hasSoftDelete, isAuthenticatable, hasTranslatable, needsUuidTrait, needsUlidTrait);
50
56
  const fillable = buildFillable(properties, expandedProperties, propertyOrder);
51
57
  const hidden = buildHidden(properties, expandedProperties, propertyOrder);
52
58
  const appends = buildAppends(expandedProperties);
53
59
  const casts = buildCasts(properties, expandedProperties, propertyOrder);
54
60
  const relations = buildRelations(name, properties, propertyOrder, modelNamespace, reader);
55
61
  const accessors = buildAccessors(expandedProperties);
56
- const primaryKey = options['primaryKey'] ?? 'id';
57
- const rawId = options.id;
58
- const idType = typeof rawId === 'string' ? rawId : 'BigInt';
59
62
  let keyTypeSection = '';
60
63
  if (idType === 'Uuid' || idType === 'Ulid' || idType === 'String') {
61
64
  keyTypeSection = `
@@ -161,11 +164,13 @@ function generateUserModel(name, config) {
161
164
  const modelName = toPascalCase(name);
162
165
  const modelNamespace = config.models.namespace;
163
166
  const baseNamespace = config.models.baseNamespace;
167
+ const factoryNamespace = config.factories.namespace;
164
168
  const content = `<?php
165
169
 
166
170
  namespace ${modelNamespace};
167
171
 
168
172
  use ${baseNamespace}\\${modelName}BaseModel;
173
+ use ${factoryNamespace}\\${modelName}Factory;
169
174
  use Illuminate\\Database\\Eloquent\\Factories\\HasFactory;
170
175
 
171
176
  /**
@@ -186,17 +191,31 @@ class ${modelName} extends ${modelName}BaseModel
186
191
  parent::__construct($attributes);
187
192
  }
188
193
 
194
+ /**
195
+ * Create a new factory instance for the model.
196
+ */
197
+ protected static function newFactory(): ${modelName}Factory
198
+ {
199
+ return ${modelName}Factory::new();
200
+ }
201
+
189
202
  // Add your custom methods here
190
203
  }
191
204
  `;
192
205
  return userFile(`${config.models.path}/${modelName}.php`, content);
193
206
  }
194
- function buildImports(baseNamespace, modelName, hasSoftDelete, isAuthenticatable, hasTranslatable, properties) {
207
+ function buildImports(baseNamespace, modelName, hasSoftDelete, isAuthenticatable, hasTranslatable, properties, needsUuidTrait = false, needsUlidTrait = false) {
195
208
  const lines = [];
196
209
  if (isAuthenticatable) {
197
210
  lines.push('use Illuminate\\Foundation\\Auth\\User as Authenticatable;');
198
211
  lines.push('use Illuminate\\Notifications\\Notifiable;');
199
212
  }
213
+ if (needsUuidTrait) {
214
+ lines.push('use Illuminate\\Database\\Eloquent\\Concerns\\HasUuids;');
215
+ }
216
+ if (needsUlidTrait) {
217
+ lines.push('use Illuminate\\Database\\Eloquent\\Concerns\\HasUlids;');
218
+ }
200
219
  // Always include all relation types for simplicity (matching PHP)
201
220
  const allRelationTypes = ['BelongsTo', 'HasMany', 'HasOne', 'BelongsToMany', 'MorphTo', 'MorphOne', 'MorphMany', 'MorphToMany'];
202
221
  for (const type of allRelationTypes) {
@@ -248,9 +267,13 @@ function buildDocProperties(properties, expandedProperties, propertyOrder) {
248
267
  }
249
268
  return lines.length === 0 ? '' : lines.join('\n') + '\n';
250
269
  }
251
- function buildTraits(hasSoftDelete, isAuthenticatable, hasTranslatable) {
270
+ function buildTraits(hasSoftDelete, isAuthenticatable, hasTranslatable, needsUuidTrait = false, needsUlidTrait = false) {
252
271
  const lines = [];
253
272
  lines.push(' use HasLocalizedDisplayName;');
273
+ if (needsUuidTrait)
274
+ lines.push(' use HasUuids;');
275
+ if (needsUlidTrait)
276
+ lines.push(' use HasUlids;');
254
277
  if (isAuthenticatable)
255
278
  lines.push(' use Notifiable;');
256
279
  if (hasSoftDelete)
package/types/schema.d.ts CHANGED
@@ -192,6 +192,17 @@ export interface PropertyDefinition {
192
192
  primary?: boolean;
193
193
  hidden?: boolean;
194
194
  fillable?: boolean;
195
+ /**
196
+ * Mark field as translatable (Astrotomic/laravel-translatable).
197
+ * When true:
198
+ * - A `{model}_translations` table is auto-generated with FK + locale + translatable columns
199
+ * - The field remains in the main table as fallback value
200
+ * - Base model gets `use Translatable` trait + `implements TranslatableContract`
201
+ * - A `{ModelName}Translation` model is generated with `$timestamps = false`
202
+ *
203
+ * Only allowed on: String, Text, MediumText, LongText, Email, EnumRef, Json.
204
+ */
205
+ translatable?: boolean;
195
206
  placeholder?: LocalizedString;
196
207
  /** Per-field overrides for compound types. */
197
208
  fields?: Record<string, CompoundFieldOverride>;