@famgia/omnify-laravel 0.0.9 → 0.0.10

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.
@@ -26,6 +26,12 @@ var PK_METHOD_MAP = {
26
26
  Uuid: "uuid",
27
27
  String: "string"
28
28
  };
29
+ function getIdType(schema) {
30
+ return schema.options?.idType ?? "BigInt";
31
+ }
32
+ function hasAutoId(schema) {
33
+ return schema.options?.id !== false;
34
+ }
29
35
  function toColumnName(propertyName) {
30
36
  return propertyName.replace(/([A-Z])/g, "_$1").toLowerCase().replace(/^_/, "");
31
37
  }
@@ -133,6 +139,54 @@ function generateSoftDeleteColumn() {
133
139
  modifiers: [{ method: "nullable" }]
134
140
  };
135
141
  }
142
+ function generatePolymorphicColumns(propertyName, property, allSchemas) {
143
+ if (property.type !== "Association") {
144
+ return null;
145
+ }
146
+ const assocProp = property;
147
+ if (assocProp.relation !== "MorphTo") {
148
+ return null;
149
+ }
150
+ const targets = assocProp.targets;
151
+ if (!targets || targets.length === 0) {
152
+ return null;
153
+ }
154
+ const columnBaseName = toColumnName(propertyName);
155
+ const typeColumnName = `${columnBaseName}_type`;
156
+ const idColumnName = `${columnBaseName}_id`;
157
+ const typeColumn = {
158
+ name: typeColumnName,
159
+ method: "enum",
160
+ args: [typeColumnName, targets],
161
+ modifiers: [{ method: "nullable" }]
162
+ };
163
+ let idMethod = "unsignedBigInteger";
164
+ for (const targetName of targets) {
165
+ const targetSchema = allSchemas[targetName];
166
+ if (targetSchema) {
167
+ const targetIdType = targetSchema.options?.idType ?? "BigInt";
168
+ if (targetIdType === "Uuid") {
169
+ idMethod = "uuid";
170
+ break;
171
+ } else if (targetIdType === "String") {
172
+ idMethod = "string";
173
+ }
174
+ }
175
+ }
176
+ const idColumn = {
177
+ name: idColumnName,
178
+ method: idMethod,
179
+ args: idMethod === "string" ? [idColumnName, 255] : [idColumnName],
180
+ modifiers: [{ method: "nullable" }]
181
+ };
182
+ const indexes = [
183
+ {
184
+ columns: [typeColumnName, idColumnName],
185
+ unique: false
186
+ }
187
+ ];
188
+ return { typeColumn, idColumn, indexes };
189
+ }
136
190
  function generateForeignKey(propertyName, property, allSchemas) {
137
191
  if (property.type !== "Association") {
138
192
  return null;
@@ -147,7 +201,7 @@ function generateForeignKey(propertyName, property, allSchemas) {
147
201
  const columnName = toColumnName(propertyName) + "_id";
148
202
  const targetSchema = assocProp.target ? allSchemas[assocProp.target] : void 0;
149
203
  const targetTable = assocProp.target ? toTableName(assocProp.target) : "unknown";
150
- const targetPkType = targetSchema?.options?.primaryKeyType ?? "BigInt";
204
+ const targetPkType = targetSchema ? getIdType(targetSchema) : "BigInt";
151
205
  let method = "unsignedBigInteger";
152
206
  if (targetPkType === "Int") {
153
207
  method = "unsignedInteger";
@@ -180,8 +234,10 @@ function schemaToBlueprint(schema, allSchemas) {
180
234
  const columns = [];
181
235
  const foreignKeys = [];
182
236
  const indexes = [];
183
- const pkType = schema.options?.primaryKeyType ?? "BigInt";
184
- columns.push(generatePrimaryKeyColumn(pkType));
237
+ if (hasAutoId(schema)) {
238
+ const pkType = getIdType(schema);
239
+ columns.push(generatePrimaryKeyColumn(pkType));
240
+ }
185
241
  if (schema.properties) {
186
242
  for (const [propName, property] of Object.entries(schema.properties)) {
187
243
  const columnMethod = propertyToColumnMethod(propName, property);
@@ -194,6 +250,12 @@ function schemaToBlueprint(schema, allSchemas) {
194
250
  foreignKeys.push(fkResult.foreignKey);
195
251
  indexes.push(fkResult.index);
196
252
  }
253
+ const polyResult = generatePolymorphicColumns(propName, property, allSchemas);
254
+ if (polyResult) {
255
+ columns.push(polyResult.typeColumn);
256
+ columns.push(polyResult.idColumn);
257
+ indexes.push(...polyResult.indexes);
258
+ }
197
259
  }
198
260
  }
199
261
  if (schema.options?.timestamps !== false) {
@@ -287,7 +349,7 @@ function extractManyToManyRelations(schema, allSchemas) {
287
349
  return pivotTables;
288
350
  }
289
351
  const sourceTable = toTableName(schema.name);
290
- const sourcePkType = schema.options?.primaryKeyType ?? "BigInt";
352
+ const sourcePkType = getIdType(schema);
291
353
  for (const [, property] of Object.entries(schema.properties)) {
292
354
  if (property.type !== "Association") {
293
355
  continue;
@@ -302,7 +364,7 @@ function extractManyToManyRelations(schema, allSchemas) {
302
364
  }
303
365
  const targetSchema = allSchemas[targetName];
304
366
  const targetTable = toTableName(targetName);
305
- const targetPkType = targetSchema?.options?.primaryKeyType ?? "BigInt";
367
+ const targetPkType = targetSchema ? getIdType(targetSchema) : "BigInt";
306
368
  const isOwningSide = assocProp.owning ?? schema.name < targetName;
307
369
  if (!isOwningSide) {
308
370
  continue;
@@ -964,12 +1026,25 @@ function getPropertyType(property, _allSchemas) {
964
1026
  const assocProp = property;
965
1027
  const targetName = assocProp.target ?? "unknown";
966
1028
  switch (assocProp.relation) {
1029
+ // Standard relations
967
1030
  case "OneToOne":
968
1031
  case "ManyToOne":
969
1032
  return targetName;
970
1033
  case "OneToMany":
971
1034
  case "ManyToMany":
972
1035
  return `${targetName}[]`;
1036
+ // Polymorphic relations
1037
+ case "MorphTo":
1038
+ if (assocProp.targets && assocProp.targets.length > 0) {
1039
+ return assocProp.targets.join(" | ");
1040
+ }
1041
+ return "unknown";
1042
+ case "MorphOne":
1043
+ return targetName;
1044
+ case "MorphMany":
1045
+ case "MorphToMany":
1046
+ case "MorphedByMany":
1047
+ return `${targetName}[]`;
973
1048
  default:
974
1049
  return "unknown";
975
1050
  }
@@ -991,30 +1066,68 @@ function getPropertyType(property, _allSchemas) {
991
1066
  }
992
1067
  return TYPE_MAP[property.type] ?? "unknown";
993
1068
  }
994
- function propertyToTSProperty(propertyName, property, allSchemas, options = {}) {
995
- const type = getPropertyType(property, allSchemas);
1069
+ function propertyToTSProperties(propertyName, property, allSchemas, options = {}) {
996
1070
  const baseProp = property;
997
- return {
1071
+ const isReadonly = options.readonly ?? true;
1072
+ if (property.type === "Association") {
1073
+ const assocProp = property;
1074
+ if (assocProp.relation === "MorphTo" && assocProp.targets && assocProp.targets.length > 0) {
1075
+ const propBaseName = toPropertyName(propertyName);
1076
+ const targetUnion = assocProp.targets.map((t) => `'${t}'`).join(" | ");
1077
+ const relationUnion = assocProp.targets.join(" | ");
1078
+ return [
1079
+ {
1080
+ name: `${propBaseName}Type`,
1081
+ type: targetUnion,
1082
+ optional: true,
1083
+ // Polymorphic columns are nullable
1084
+ readonly: isReadonly,
1085
+ comment: `Polymorphic type for ${propertyName}`
1086
+ },
1087
+ {
1088
+ name: `${propBaseName}Id`,
1089
+ type: "number",
1090
+ optional: true,
1091
+ readonly: isReadonly,
1092
+ comment: `Polymorphic ID for ${propertyName}`
1093
+ },
1094
+ {
1095
+ name: propBaseName,
1096
+ type: `${relationUnion} | null`,
1097
+ optional: true,
1098
+ readonly: isReadonly,
1099
+ comment: baseProp.displayName ?? `Polymorphic relation to ${assocProp.targets.join(", ")}`
1100
+ }
1101
+ ];
1102
+ }
1103
+ }
1104
+ const type = getPropertyType(property, allSchemas);
1105
+ return [{
998
1106
  name: toPropertyName(propertyName),
999
1107
  type,
1000
1108
  optional: baseProp.nullable ?? false,
1001
- readonly: options.readonly ?? true,
1109
+ readonly: isReadonly,
1002
1110
  comment: baseProp.displayName
1003
- };
1111
+ }];
1112
+ }
1113
+ function propertyToTSProperty(propertyName, property, allSchemas, options = {}) {
1114
+ return propertyToTSProperties(propertyName, property, allSchemas, options)[0];
1004
1115
  }
1005
1116
  function schemaToInterface(schema, allSchemas, options = {}) {
1006
1117
  const properties = [];
1007
- const pkType = schema.options?.primaryKeyType ?? "BigInt";
1008
- properties.push({
1009
- name: "id",
1010
- type: PK_TYPE_MAP[pkType] ?? "number",
1011
- optional: false,
1012
- readonly: options.readonly ?? true,
1013
- comment: "Primary key"
1014
- });
1118
+ if (schema.options?.id !== false) {
1119
+ const pkType = schema.options?.idType ?? "BigInt";
1120
+ properties.push({
1121
+ name: "id",
1122
+ type: PK_TYPE_MAP[pkType] ?? "number",
1123
+ optional: false,
1124
+ readonly: options.readonly ?? true,
1125
+ comment: "Primary key"
1126
+ });
1127
+ }
1015
1128
  if (schema.properties) {
1016
1129
  for (const [propName, property] of Object.entries(schema.properties)) {
1017
- properties.push(propertyToTSProperty(propName, property, allSchemas, options));
1130
+ properties.push(...propertyToTSProperties(propName, property, allSchemas, options));
1018
1131
  }
1019
1132
  }
1020
1133
  if (schema.options?.timestamps !== false) {
@@ -1431,4 +1544,4 @@ export {
1431
1544
  getTypeScriptPath,
1432
1545
  laravelPlugin
1433
1546
  };
1434
- //# sourceMappingURL=chunk-6FFGIVB3.js.map
1547
+ //# sourceMappingURL=chunk-UEJWSSDU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/migration/schema-builder.ts","../src/migration/generator.ts","../src/migration/alter-generator.ts","../src/typescript/interface-generator.ts","../src/typescript/enum-generator.ts","../src/typescript/generator.ts","../src/plugin.ts"],"sourcesContent":["/**\n * @famgia/omnify-laravel - Schema Builder Converter\n *\n * Converts SQL types and operations to Laravel Schema Builder methods.\n */\n\nimport type { PropertyDefinition, LoadedSchema, SchemaCollection } from '@famgia/omnify-types';\nimport type {\n ColumnMethod,\n ColumnModifier,\n ForeignKeyDefinition,\n IndexDefinition,\n TableBlueprint,\n} from './types.js';\n\n/**\n * Maps Omnify property types to Laravel column methods.\n */\nconst TYPE_METHOD_MAP: Record<string, string> = {\n String: 'string',\n Int: 'integer',\n BigInt: 'bigInteger',\n Float: 'double',\n Decimal: 'decimal',\n Boolean: 'boolean',\n Text: 'text',\n LongText: 'longText',\n Date: 'date',\n Time: 'time',\n Timestamp: 'timestamp',\n Json: 'json',\n Email: 'string',\n Password: 'string',\n File: 'string',\n MultiFile: 'json',\n Enum: 'enum',\n Select: 'string',\n Lookup: 'unsignedBigInteger',\n};\n\n/**\n * Maps primary key types to Laravel methods.\n */\nconst PK_METHOD_MAP: Record<string, string> = {\n Int: 'increments',\n BigInt: 'bigIncrements',\n Uuid: 'uuid',\n String: 'string',\n};\n\n/**\n * Gets the ID type from schema options.\n */\nfunction getIdType(schema: LoadedSchema): 'Int' | 'BigInt' | 'Uuid' | 'String' {\n return (schema.options?.idType ?? 'BigInt') as 'Int' | 'BigInt' | 'Uuid' | 'String';\n}\n\n/**\n * Checks if the schema should have an auto-generated ID column.\n * Returns false if options.id is explicitly set to false.\n */\nfunction hasAutoId(schema: LoadedSchema): boolean {\n return schema.options?.id !== false;\n}\n\n/**\n * Converts a property name to snake_case column name.\n */\nexport function toColumnName(propertyName: string): string {\n return propertyName.replace(/([A-Z])/g, '_$1').toLowerCase().replace(/^_/, '');\n}\n\n/**\n * Converts schema name to snake_case plural table name.\n */\nexport function toTableName(schemaName: string): string {\n const snakeCase = schemaName\n .replace(/([A-Z])/g, '_$1')\n .toLowerCase()\n .replace(/^_/, '');\n\n // Simple pluralization\n if (snakeCase.endsWith('y')) {\n return snakeCase.slice(0, -1) + 'ies';\n } else if (\n snakeCase.endsWith('s') ||\n snakeCase.endsWith('x') ||\n snakeCase.endsWith('ch') ||\n snakeCase.endsWith('sh')\n ) {\n return snakeCase + 'es';\n } else {\n return snakeCase + 's';\n }\n}\n\n/**\n * Converts a property to Laravel column method.\n */\nexport function propertyToColumnMethod(\n propertyName: string,\n property: PropertyDefinition\n): ColumnMethod | null {\n // Skip associations - they're handled separately\n if (property.type === 'Association') {\n return null;\n }\n\n const columnName = toColumnName(propertyName);\n const method = TYPE_METHOD_MAP[property.type] ?? 'string';\n const args: (string | number | boolean)[] = [columnName];\n const modifiers: ColumnModifier[] = [];\n\n // Handle length for string types\n const propWithLength = property as { length?: number };\n if (method === 'string' && propWithLength.length) {\n args.push(propWithLength.length);\n }\n\n // Handle precision and scale for decimal types\n if (property.type === 'Decimal') {\n const decimalProp = property as { precision?: number; scale?: number };\n const precision = decimalProp.precision ?? 8;\n const scale = decimalProp.scale ?? 2;\n args.push(precision, scale);\n }\n\n // Handle enum values\n if (property.type === 'Enum') {\n const enumProp = property as { enum?: readonly string[] };\n if (enumProp.enum && enumProp.enum.length > 0) {\n args.push(enumProp.enum as unknown as string);\n }\n }\n\n // Add modifiers\n const baseProp = property as {\n nullable?: boolean;\n unique?: boolean;\n default?: unknown;\n unsigned?: boolean;\n };\n\n if (baseProp.nullable) {\n modifiers.push({ method: 'nullable' });\n }\n\n if (baseProp.unique) {\n modifiers.push({ method: 'unique' });\n }\n\n if (baseProp.default !== undefined) {\n const defaultValue = typeof baseProp.default === 'string'\n ? baseProp.default\n : JSON.stringify(baseProp.default);\n modifiers.push({ method: 'default', args: [defaultValue] });\n }\n\n if (baseProp.unsigned && (method === 'integer' || method === 'bigInteger')) {\n modifiers.push({ method: 'unsigned' });\n }\n\n return {\n name: columnName,\n method,\n args,\n modifiers,\n };\n}\n\n/**\n * Generates primary key column method.\n */\nexport function generatePrimaryKeyColumn(\n pkType: 'Int' | 'BigInt' | 'Uuid' | 'String' = 'BigInt'\n): ColumnMethod {\n const method = PK_METHOD_MAP[pkType] ?? 'bigIncrements';\n\n if (pkType === 'Uuid') {\n return {\n name: 'id',\n method: 'uuid',\n args: ['id'],\n modifiers: [{ method: 'primary' }],\n };\n }\n\n if (pkType === 'String') {\n return {\n name: 'id',\n method: 'string',\n args: ['id', 255],\n modifiers: [{ method: 'primary' }],\n };\n }\n\n // For Int/BigInt, use increments which auto-creates primary key\n return {\n name: 'id',\n method,\n args: ['id'],\n modifiers: [],\n };\n}\n\n/**\n * Generates timestamp columns.\n */\nexport function generateTimestampColumns(): ColumnMethod[] {\n return [\n {\n name: 'created_at',\n method: 'timestamp',\n args: ['created_at'],\n modifiers: [{ method: 'nullable' }],\n },\n {\n name: 'updated_at',\n method: 'timestamp',\n args: ['updated_at'],\n modifiers: [{ method: 'nullable' }],\n },\n ];\n}\n\n/**\n * Generates soft delete column.\n */\nexport function generateSoftDeleteColumn(): ColumnMethod {\n return {\n name: 'deleted_at',\n method: 'timestamp',\n args: ['deleted_at'],\n modifiers: [{ method: 'nullable' }],\n };\n}\n\n/**\n * Polymorphic column result with type enum and id column.\n */\nexport interface PolymorphicColumnsResult {\n typeColumn: ColumnMethod;\n idColumn: ColumnMethod;\n indexes: IndexDefinition[];\n}\n\n/**\n * Generates polymorphic columns for MorphTo relations.\n * Creates {name}_type (ENUM) and {name}_id columns.\n */\nexport function generatePolymorphicColumns(\n propertyName: string,\n property: PropertyDefinition,\n allSchemas: SchemaCollection\n): PolymorphicColumnsResult | null {\n if (property.type !== 'Association') {\n return null;\n }\n\n const assocProp = property as {\n relation?: string;\n targets?: readonly string[];\n };\n\n // Only handle MorphTo - it creates the type and id columns\n if (assocProp.relation !== 'MorphTo') {\n return null;\n }\n\n const targets = assocProp.targets;\n if (!targets || targets.length === 0) {\n return null;\n }\n\n const columnBaseName = toColumnName(propertyName);\n const typeColumnName = `${columnBaseName}_type`;\n const idColumnName = `${columnBaseName}_id`;\n\n // Generate ENUM type column with target schema names as values\n const typeColumn: ColumnMethod = {\n name: typeColumnName,\n method: 'enum',\n args: [typeColumnName, targets as unknown as string],\n modifiers: [{ method: 'nullable' }],\n };\n\n // For polymorphic id, we need to determine the largest ID type among targets\n // Default to unsignedBigInteger for maximum compatibility\n let idMethod = 'unsignedBigInteger';\n\n // Check if any target uses UUID or String - those take precedence\n for (const targetName of targets) {\n const targetSchema = allSchemas[targetName];\n if (targetSchema) {\n const targetIdType = (targetSchema.options?.idType ?? 'BigInt') as string;\n if (targetIdType === 'Uuid') {\n idMethod = 'uuid';\n break; // UUID takes highest precedence\n } else if (targetIdType === 'String') {\n idMethod = 'string';\n // Don't break - UUID still takes precedence\n }\n }\n }\n\n const idColumn: ColumnMethod = {\n name: idColumnName,\n method: idMethod,\n args: idMethod === 'string' ? [idColumnName, 255] : [idColumnName],\n modifiers: [{ method: 'nullable' }],\n };\n\n // Create composite index for faster polymorphic lookups\n const indexes: IndexDefinition[] = [\n {\n columns: [typeColumnName, idColumnName],\n unique: false,\n },\n ];\n\n return { typeColumn, idColumn, indexes };\n}\n\n/**\n * Generates foreign key column and constraint from association.\n */\nexport function generateForeignKey(\n propertyName: string,\n property: PropertyDefinition,\n allSchemas: SchemaCollection\n): { column: ColumnMethod; foreignKey: ForeignKeyDefinition; index: IndexDefinition } | null {\n if (property.type !== 'Association') {\n return null;\n }\n\n const assocProp = property as {\n relation?: string;\n target?: string;\n onDelete?: string;\n onUpdate?: string;\n mappedBy?: string;\n owningSide?: boolean;\n };\n\n // Only create FK column for ManyToOne and OneToOne (owning side)\n if (assocProp.relation !== 'ManyToOne' && assocProp.relation !== 'OneToOne') {\n return null;\n }\n\n // Skip inverse side (mappedBy means this is the inverse side)\n if (assocProp.mappedBy) {\n return null;\n }\n\n const columnName = toColumnName(propertyName) + '_id';\n const targetSchema = assocProp.target ? allSchemas[assocProp.target] : undefined;\n const targetTable = assocProp.target ? toTableName(assocProp.target) : 'unknown';\n const targetPkType = targetSchema ? getIdType(targetSchema) : 'BigInt';\n\n // Determine column method based on target PK type\n let method = 'unsignedBigInteger';\n if (targetPkType === 'Int') {\n method = 'unsignedInteger';\n } else if (targetPkType === 'Uuid') {\n method = 'uuid';\n } else if (targetPkType === 'String') {\n method = 'string';\n }\n\n const column: ColumnMethod = {\n name: columnName,\n method,\n args: [columnName],\n modifiers: assocProp.relation === 'ManyToOne' ? [{ method: 'nullable' }] : [],\n };\n\n const foreignKey: ForeignKeyDefinition = {\n columns: [columnName],\n references: 'id',\n on: [targetTable],\n onDelete: assocProp.onDelete ?? 'restrict',\n onUpdate: assocProp.onUpdate ?? 'cascade',\n };\n\n // Don't specify index name - let Laravel auto-generate unique names\n const index: IndexDefinition = {\n columns: [columnName],\n unique: false,\n };\n\n return { column, foreignKey, index };\n}\n\n/**\n * Generates table blueprint from schema.\n */\nexport function schemaToBlueprint(\n schema: LoadedSchema,\n allSchemas: SchemaCollection\n): TableBlueprint {\n const tableName = toTableName(schema.name);\n const columns: ColumnMethod[] = [];\n const foreignKeys: ForeignKeyDefinition[] = [];\n const indexes: IndexDefinition[] = [];\n\n // Primary key (only if id is not disabled)\n if (hasAutoId(schema)) {\n const pkType = getIdType(schema);\n columns.push(generatePrimaryKeyColumn(pkType));\n }\n\n // Process properties\n if (schema.properties) {\n for (const [propName, property] of Object.entries(schema.properties)) {\n // Handle regular columns\n const columnMethod = propertyToColumnMethod(propName, property);\n if (columnMethod) {\n columns.push(columnMethod);\n }\n\n // Handle foreign keys (standard associations)\n const fkResult = generateForeignKey(propName, property, allSchemas);\n if (fkResult) {\n columns.push(fkResult.column);\n foreignKeys.push(fkResult.foreignKey);\n indexes.push(fkResult.index);\n }\n\n // Handle polymorphic columns (MorphTo)\n const polyResult = generatePolymorphicColumns(propName, property, allSchemas);\n if (polyResult) {\n columns.push(polyResult.typeColumn);\n columns.push(polyResult.idColumn);\n indexes.push(...polyResult.indexes);\n }\n }\n }\n\n // Timestamps\n if (schema.options?.timestamps !== false) {\n columns.push(...generateTimestampColumns());\n }\n\n // Soft delete\n if (schema.options?.softDelete) {\n columns.push(generateSoftDeleteColumn());\n }\n\n // Custom indexes\n if (schema.options?.indexes) {\n for (const index of schema.options.indexes) {\n indexes.push({\n name: index.name,\n columns: index.columns.map(toColumnName),\n unique: index.unique ?? false,\n });\n }\n }\n\n // Unique constraints\n if (schema.options?.unique) {\n const uniqueConstraints = Array.isArray(schema.options.unique[0])\n ? (schema.options.unique as readonly (readonly string[])[])\n : [schema.options.unique as readonly string[]];\n\n for (const constraint of uniqueConstraints) {\n indexes.push({\n columns: constraint.map(toColumnName),\n unique: true,\n });\n }\n }\n\n return {\n tableName,\n columns,\n primaryKey: ['id'],\n foreignKeys,\n indexes,\n };\n}\n\n/**\n * Formats a column method to PHP code.\n */\nexport function formatColumnMethod(column: ColumnMethod): string {\n const args = column.args.map(arg => {\n if (typeof arg === 'string') {\n return `'${arg}'`;\n }\n if (Array.isArray(arg)) {\n return `[${(arg as string[]).map(v => `'${v}'`).join(', ')}]`;\n }\n return String(arg);\n }).join(', ');\n\n let code = `$table->${column.method}(${args})`;\n\n for (const modifier of column.modifiers) {\n if (modifier.args && modifier.args.length > 0) {\n const modArgs = modifier.args.map(arg => {\n if (typeof arg === 'string') {\n return `'${arg}'`;\n }\n return String(arg);\n }).join(', ');\n code += `->${modifier.method}(${modArgs})`;\n } else {\n code += `->${modifier.method}()`;\n }\n }\n\n return code + ';';\n}\n\n/**\n * Formats a foreign key to PHP code.\n */\nexport function formatForeignKey(fk: ForeignKeyDefinition): string {\n const column = fk.columns[0];\n const table = fk.on[0];\n let code = `$table->foreign('${column}')->references('${fk.references}')->on('${table}')`;\n\n if (fk.onDelete) {\n code += `->onDelete('${fk.onDelete}')`;\n }\n if (fk.onUpdate) {\n code += `->onUpdate('${fk.onUpdate}')`;\n }\n\n return code + ';';\n}\n\n/**\n * Formats an index to PHP code.\n */\nexport function formatIndex(index: IndexDefinition): string {\n const columns = index.columns.length === 1\n ? `'${index.columns[0]}'`\n : `[${index.columns.map(c => `'${c}'`).join(', ')}]`;\n\n const method = index.unique ? 'unique' : 'index';\n const name = index.name ? `, '${index.name}'` : '';\n\n return `$table->${method}(${columns}${name});`;\n}\n\n/**\n * Pivot table information for ManyToMany relationships.\n */\nexport interface PivotTableInfo {\n tableName: string;\n sourceTable: string;\n targetTable: string;\n sourceColumn: string;\n targetColumn: string;\n sourcePkType: 'Int' | 'BigInt' | 'Uuid' | 'String';\n targetPkType: 'Int' | 'BigInt' | 'Uuid' | 'String';\n onDelete: string | undefined;\n onUpdate: string | undefined;\n}\n\n/**\n * Polymorphic pivot table information for MorphToMany relationships.\n */\nexport interface MorphToManyPivotInfo {\n tableName: string;\n /** The fixed target schema that uses MorphToMany */\n targetTable: string;\n targetColumn: string;\n targetPkType: 'Int' | 'BigInt' | 'Uuid' | 'String';\n /** Base name for polymorphic columns (creates {name}_type and {name}_id) */\n morphName: string;\n /** Schema names that can be morphed to */\n morphTargets: readonly string[];\n onDelete: string | undefined;\n onUpdate: string | undefined;\n}\n\n/**\n * Generates pivot table name for ManyToMany relationship.\n * Uses alphabetical ordering for consistency.\n */\nexport function generatePivotTableName(\n sourceTable: string,\n targetTable: string,\n customName?: string\n): string {\n if (customName) {\n return customName;\n }\n\n // Sort alphabetically for consistent naming\n const tables = [sourceTable, targetTable].sort();\n // Remove trailing 's' and join with underscore\n const singular1 = tables[0]!.replace(/ies$/, 'y').replace(/s$/, '');\n const singular2 = tables[1]!.replace(/ies$/, 'y').replace(/s$/, '');\n return `${singular1}_${singular2}`;\n}\n\n/**\n * Extracts ManyToMany relationships from a schema.\n */\nexport function extractManyToManyRelations(\n schema: LoadedSchema,\n allSchemas: SchemaCollection\n): PivotTableInfo[] {\n const pivotTables: PivotTableInfo[] = [];\n\n if (!schema.properties) {\n return pivotTables;\n }\n\n const sourceTable = toTableName(schema.name);\n const sourcePkType = getIdType(schema);\n\n for (const [, property] of Object.entries(schema.properties)) {\n if (property.type !== 'Association') {\n continue;\n }\n\n const assocProp = property as {\n relation?: string;\n target?: string;\n joinTable?: string;\n onDelete?: string;\n onUpdate?: string;\n owning?: boolean;\n };\n\n // Only handle ManyToMany on the owning side (or if not specified, use alphabetical order)\n if (assocProp.relation !== 'ManyToMany') {\n continue;\n }\n\n const targetName = assocProp.target;\n if (!targetName) {\n continue;\n }\n\n const targetSchema = allSchemas[targetName];\n const targetTable = toTableName(targetName);\n const targetPkType = targetSchema ? getIdType(targetSchema) : 'BigInt';\n\n // Determine if this side owns the relationship\n // Default: alphabetically first schema owns it\n const isOwningSide = assocProp.owning ?? (schema.name < targetName);\n\n if (!isOwningSide) {\n continue; // Skip non-owning side to avoid duplicate pivot tables\n }\n\n const pivotTableName = generatePivotTableName(sourceTable, targetTable, assocProp.joinTable);\n\n // Column names: singular form of table name + _id\n const sourceColumn = sourceTable.replace(/ies$/, 'y').replace(/s$/, '') + '_id';\n const targetColumn = targetTable.replace(/ies$/, 'y').replace(/s$/, '') + '_id';\n\n pivotTables.push({\n tableName: pivotTableName,\n sourceTable,\n targetTable,\n sourceColumn,\n targetColumn,\n sourcePkType,\n targetPkType,\n onDelete: assocProp.onDelete,\n onUpdate: assocProp.onUpdate,\n });\n }\n\n return pivotTables;\n}\n\n/**\n * Generates blueprint for a pivot table.\n */\nexport function generatePivotTableBlueprint(pivot: PivotTableInfo): TableBlueprint {\n const columns: ColumnMethod[] = [];\n const foreignKeys: ForeignKeyDefinition[] = [];\n const indexes: IndexDefinition[] = [];\n\n // Determine column methods based on PK types\n const getMethodForPkType = (pkType: string): string => {\n switch (pkType) {\n case 'Int': return 'unsignedInteger';\n case 'Uuid': return 'uuid';\n case 'String': return 'string';\n default: return 'unsignedBigInteger';\n }\n };\n\n // Source column\n columns.push({\n name: pivot.sourceColumn,\n method: getMethodForPkType(pivot.sourcePkType),\n args: [pivot.sourceColumn],\n modifiers: [],\n });\n\n // Target column\n columns.push({\n name: pivot.targetColumn,\n method: getMethodForPkType(pivot.targetPkType),\n args: [pivot.targetColumn],\n modifiers: [],\n });\n\n // Foreign keys\n foreignKeys.push({\n columns: [pivot.sourceColumn],\n references: 'id',\n on: [pivot.sourceTable],\n onDelete: pivot.onDelete ?? 'cascade',\n onUpdate: pivot.onUpdate ?? 'cascade',\n });\n\n foreignKeys.push({\n columns: [pivot.targetColumn],\n references: 'id',\n on: [pivot.targetTable],\n onDelete: pivot.onDelete ?? 'cascade',\n onUpdate: pivot.onUpdate ?? 'cascade',\n });\n\n // Composite primary key / unique constraint\n indexes.push({\n columns: [pivot.sourceColumn, pivot.targetColumn],\n unique: true,\n });\n\n // Individual indexes for faster lookups (no name - let Laravel auto-generate)\n indexes.push({\n columns: [pivot.sourceColumn],\n unique: false,\n });\n\n indexes.push({\n columns: [pivot.targetColumn],\n unique: false,\n });\n\n return {\n tableName: pivot.tableName,\n columns,\n primaryKey: [pivot.sourceColumn, pivot.targetColumn],\n foreignKeys,\n indexes,\n };\n}\n\n/**\n * Extracts MorphToMany relationships from a schema.\n * MorphToMany creates a pivot table with polymorphic type/id columns.\n */\nexport function extractMorphToManyRelations(\n schema: LoadedSchema,\n allSchemas: SchemaCollection\n): MorphToManyPivotInfo[] {\n const morphPivotTables: MorphToManyPivotInfo[] = [];\n\n if (!schema.properties) {\n return morphPivotTables;\n }\n\n for (const [propName, property] of Object.entries(schema.properties)) {\n if (property.type !== 'Association') {\n continue;\n }\n\n const assocProp = property as {\n relation?: string;\n target?: string;\n joinTable?: string;\n onDelete?: string;\n onUpdate?: string;\n owning?: boolean;\n };\n\n if (assocProp.relation !== 'MorphToMany') {\n continue;\n }\n\n const targetName = assocProp.target;\n if (!targetName) {\n continue;\n }\n\n const targetSchema = allSchemas[targetName];\n const targetTable = toTableName(targetName);\n const targetPkType = targetSchema ? getIdType(targetSchema) : 'BigInt';\n\n // Determine if this side owns the relationship\n const isOwningSide = assocProp.owning ?? (schema.name < targetName);\n\n if (!isOwningSide) {\n continue;\n }\n\n // Find all schemas that have MorphedByMany pointing to this target\n // to determine the morphTargets for the ENUM\n const morphTargets: string[] = [];\n\n // The source schema itself is a morph target\n morphTargets.push(schema.name);\n\n // Look for other schemas with MorphToMany to the same target\n for (const [otherName, otherSchema] of Object.entries(allSchemas)) {\n if (otherName === schema.name) continue;\n if (!otherSchema.properties) continue;\n\n for (const otherProp of Object.values(otherSchema.properties)) {\n if (otherProp.type !== 'Association') continue;\n const otherAssoc = otherProp as { relation?: string; target?: string };\n if (otherAssoc.relation === 'MorphToMany' && otherAssoc.target === targetName) {\n if (!morphTargets.includes(otherName)) {\n morphTargets.push(otherName);\n }\n }\n }\n }\n\n // Default table name: taggables (for Tag target), commentables, etc.\n const defaultTableName = targetTable.replace(/s$/, '') + 'ables';\n const tableName = assocProp.joinTable ?? defaultTableName;\n\n // Column name for the target side (e.g., tag_id for Tag)\n const targetColumn = targetTable.replace(/ies$/, 'y').replace(/s$/, '') + '_id';\n\n // MorphName is typically the property name or a convention like 'taggable'\n const morphName = propName.replace(/s$/, '') + 'able';\n\n morphPivotTables.push({\n tableName,\n targetTable,\n targetColumn,\n targetPkType,\n morphName,\n morphTargets,\n onDelete: assocProp.onDelete,\n onUpdate: assocProp.onUpdate,\n });\n }\n\n return morphPivotTables;\n}\n\n/**\n * Generates blueprint for a polymorphic pivot table (MorphToMany).\n */\nexport function generateMorphToManyPivotBlueprint(pivot: MorphToManyPivotInfo): TableBlueprint {\n const columns: ColumnMethod[] = [];\n const foreignKeys: ForeignKeyDefinition[] = [];\n const indexes: IndexDefinition[] = [];\n\n const getMethodForPkType = (pkType: string): string => {\n switch (pkType) {\n case 'Int': return 'unsignedInteger';\n case 'Uuid': return 'uuid';\n case 'String': return 'string';\n default: return 'unsignedBigInteger';\n }\n };\n\n // Target column (e.g., tag_id)\n columns.push({\n name: pivot.targetColumn,\n method: getMethodForPkType(pivot.targetPkType),\n args: [pivot.targetColumn],\n modifiers: [],\n });\n\n // Polymorphic type column as ENUM\n const typeColumnName = `${pivot.morphName}_type`;\n columns.push({\n name: typeColumnName,\n method: 'enum',\n args: [typeColumnName, pivot.morphTargets as unknown as string],\n modifiers: [],\n });\n\n // Polymorphic ID column\n const idColumnName = `${pivot.morphName}_id`;\n columns.push({\n name: idColumnName,\n method: 'unsignedBigInteger', // Default to BigInt for polymorphic IDs\n args: [idColumnName],\n modifiers: [],\n });\n\n // Foreign key for target\n foreignKeys.push({\n columns: [pivot.targetColumn],\n references: 'id',\n on: [pivot.targetTable],\n onDelete: pivot.onDelete ?? 'cascade',\n onUpdate: pivot.onUpdate ?? 'cascade',\n });\n\n // Unique constraint for polymorphic pivot (target + morphable)\n indexes.push({\n columns: [pivot.targetColumn, typeColumnName, idColumnName],\n unique: true,\n });\n\n // Index for faster polymorphic lookups\n indexes.push({\n columns: [typeColumnName, idColumnName],\n unique: false,\n });\n\n // Index for target lookups\n indexes.push({\n columns: [pivot.targetColumn],\n unique: false,\n });\n\n return {\n tableName: pivot.tableName,\n columns,\n primaryKey: [pivot.targetColumn, typeColumnName, idColumnName],\n foreignKeys,\n indexes,\n };\n}\n","/**\n * @famgia/omnify-laravel - Migration Generator\n *\n * Generates Laravel migration files from schemas.\n */\n\nimport type { LoadedSchema, SchemaCollection } from '@famgia/omnify-types';\nimport type {\n MigrationFile,\n MigrationOptions,\n TableBlueprint,\n} from './types.js';\nimport {\n schemaToBlueprint,\n formatColumnMethod,\n formatForeignKey,\n formatIndex,\n extractManyToManyRelations,\n generatePivotTableBlueprint,\n} from './schema-builder.js';\n\n/**\n * Generates timestamp prefix for migration file name.\n */\nfunction generateTimestamp(): string {\n const now = new Date();\n const year = now.getFullYear();\n const month = String(now.getMonth() + 1).padStart(2, '0');\n const day = String(now.getDate()).padStart(2, '0');\n const hours = String(now.getHours()).padStart(2, '0');\n const minutes = String(now.getMinutes()).padStart(2, '0');\n const seconds = String(now.getSeconds()).padStart(2, '0');\n return `${year}_${month}_${day}_${hours}${minutes}${seconds}`;\n}\n\n/**\n * Converts table name to Laravel migration class name.\n */\nfunction toClassName(tableName: string, type: 'create' | 'alter' | 'drop'): string {\n const pascalCase = tableName\n .split('_')\n .map(word => word.charAt(0).toUpperCase() + word.slice(1))\n .join('');\n\n switch (type) {\n case 'create':\n return `Create${pascalCase}Table`;\n case 'alter':\n return `Alter${pascalCase}Table`;\n case 'drop':\n return `Drop${pascalCase}Table`;\n }\n}\n\n/**\n * Generates file name for migration.\n */\nfunction generateFileName(\n tableName: string,\n type: 'create' | 'alter' | 'drop',\n timestamp?: string\n): string {\n const ts = timestamp ?? generateTimestamp();\n const action = type === 'create' ? 'create' : type === 'drop' ? 'drop' : 'update';\n return `${ts}_${action}_${tableName}_table.php`;\n}\n\n/**\n * Renders the up method body for a create table operation.\n */\nfunction renderCreateTableUp(blueprint: TableBlueprint): string {\n const lines: string[] = [];\n\n // Column definitions\n for (const column of blueprint.columns) {\n lines.push(` ${formatColumnMethod(column)}`);\n }\n\n // Foreign keys (separate for Laravel best practices)\n // Note: Foreign keys should be in a separate migration or at the end\n // We'll include them in the same migration for simplicity\n\n return lines.join('\\n');\n}\n\n/**\n * Renders foreign key constraints (usually added after all columns).\n */\nfunction renderForeignKeys(blueprint: TableBlueprint): string {\n if (blueprint.foreignKeys.length === 0) {\n return '';\n }\n\n const lines = blueprint.foreignKeys.map(fk => ` ${formatForeignKey(fk)}`);\n return '\\n' + lines.join('\\n');\n}\n\n/**\n * Renders indexes.\n */\nfunction renderIndexes(blueprint: TableBlueprint): string {\n // Filter out indexes that are already handled (primary key, unique columns)\n const customIndexes = blueprint.indexes.filter(idx => {\n // Skip single-column unique indexes (handled by column modifier)\n if (idx.unique && idx.columns.length === 1) {\n return false;\n }\n return true;\n });\n\n if (customIndexes.length === 0) {\n return '';\n }\n\n const lines = customIndexes.map(idx => ` ${formatIndex(idx)}`);\n return '\\n' + lines.join('\\n');\n}\n\n/**\n * Generates a create table migration.\n */\nfunction generateCreateMigration(\n blueprint: TableBlueprint,\n options: MigrationOptions = {}\n): MigrationFile {\n const className = toClassName(blueprint.tableName, 'create');\n const fileName = generateFileName(blueprint.tableName, 'create', options.timestamp);\n\n const connection = options.connection\n ? `\\n protected $connection = '${options.connection}';\\n`\n : '';\n\n const upContent = renderCreateTableUp(blueprint);\n const foreignKeyContent = renderForeignKeys(blueprint);\n const indexContent = renderIndexes(blueprint);\n\n const content = `<?php\n\nuse Illuminate\\\\Database\\\\Migrations\\\\Migration;\nuse Illuminate\\\\Database\\\\Schema\\\\Blueprint;\nuse Illuminate\\\\Support\\\\Facades\\\\Schema;\n\nreturn new class extends Migration\n{${connection}\n /**\n * Run the migrations.\n */\n public function up(): void\n {\n Schema::create('${blueprint.tableName}', function (Blueprint $table) {\n${upContent}${foreignKeyContent}${indexContent}\n });\n }\n\n /**\n * Reverse the migrations.\n */\n public function down(): void\n {\n Schema::dropIfExists('${blueprint.tableName}');\n }\n};\n`;\n\n return {\n fileName,\n className,\n content,\n tables: [blueprint.tableName],\n type: 'create',\n };\n}\n\n/**\n * Generates a drop table migration.\n */\nfunction generateDropMigration(\n tableName: string,\n options: MigrationOptions = {}\n): MigrationFile {\n const className = toClassName(tableName, 'drop');\n const fileName = generateFileName(tableName, 'drop', options.timestamp);\n\n const connection = options.connection\n ? `\\n protected $connection = '${options.connection}';\\n`\n : '';\n\n const content = `<?php\n\nuse Illuminate\\\\Database\\\\Migrations\\\\Migration;\nuse Illuminate\\\\Database\\\\Schema\\\\Blueprint;\nuse Illuminate\\\\Support\\\\Facades\\\\Schema;\n\nreturn new class extends Migration\n{${connection}\n /**\n * Run the migrations.\n */\n public function up(): void\n {\n Schema::dropIfExists('${tableName}');\n }\n\n /**\n * Reverse the migrations.\n */\n public function down(): void\n {\n // Cannot recreate table without schema information\n // This is a one-way migration\n }\n};\n`;\n\n return {\n fileName,\n className,\n content,\n tables: [tableName],\n type: 'drop',\n };\n}\n\n/**\n * Extracts FK dependencies from a schema.\n * Returns array of schema names that this schema depends on.\n */\nfunction extractDependencies(schema: LoadedSchema): string[] {\n const deps: string[] = [];\n\n if (!schema.properties) {\n return deps;\n }\n\n for (const property of Object.values(schema.properties)) {\n if (property.type !== 'Association') {\n continue;\n }\n\n const assocProp = property as {\n relation?: string;\n target?: string;\n mappedBy?: string;\n };\n\n // ManyToOne and OneToOne (owning side) create FK columns\n if (\n (assocProp.relation === 'ManyToOne' || assocProp.relation === 'OneToOne') &&\n !assocProp.mappedBy &&\n assocProp.target\n ) {\n deps.push(assocProp.target);\n }\n }\n\n return deps;\n}\n\n/**\n * Topological sort of schemas based on FK dependencies.\n * Returns schemas in order where dependencies come before dependents.\n */\nfunction topologicalSort(schemas: SchemaCollection): LoadedSchema[] {\n const schemaList = Object.values(schemas).filter(s => s.kind !== 'enum');\n const sorted: LoadedSchema[] = [];\n const visited = new Set<string>();\n const visiting = new Set<string>(); // For cycle detection\n\n function visit(schema: LoadedSchema): void {\n if (visited.has(schema.name)) {\n return;\n }\n\n if (visiting.has(schema.name)) {\n // Circular dependency - just continue (FK can be nullable)\n return;\n }\n\n visiting.add(schema.name);\n\n // Visit dependencies first\n const deps = extractDependencies(schema);\n for (const depName of deps) {\n const depSchema = schemas[depName];\n if (depSchema && depSchema.kind !== 'enum') {\n visit(depSchema);\n }\n }\n\n visiting.delete(schema.name);\n visited.add(schema.name);\n sorted.push(schema);\n }\n\n // Visit all schemas\n for (const schema of schemaList) {\n visit(schema);\n }\n\n return sorted;\n}\n\n/**\n * Generates migrations for all schemas.\n */\nexport function generateMigrations(\n schemas: SchemaCollection,\n options: MigrationOptions = {}\n): MigrationFile[] {\n const migrations: MigrationFile[] = [];\n const pivotTablesGenerated = new Set<string>();\n let timestampOffset = 0;\n\n // Sort schemas by FK dependencies (topological sort)\n const sortedSchemas = topologicalSort(schemas);\n\n // First pass: generate main table migrations in dependency order\n for (const schema of sortedSchemas) {\n // Generate timestamp with offset to ensure unique filenames\n const timestamp = options.timestamp ?? generateTimestamp();\n const offsetTimestamp = incrementTimestamp(timestamp, timestampOffset);\n timestampOffset++;\n\n const blueprint = schemaToBlueprint(schema, schemas);\n const migration = generateCreateMigration(blueprint, {\n ...options,\n timestamp: offsetTimestamp,\n });\n migrations.push(migration);\n }\n\n // Second pass: generate pivot table migrations for ManyToMany (always last)\n for (const schema of sortedSchemas) {\n const pivotTables = extractManyToManyRelations(schema, schemas);\n\n for (const pivot of pivotTables) {\n // Skip if already generated\n if (pivotTablesGenerated.has(pivot.tableName)) {\n continue;\n }\n pivotTablesGenerated.add(pivot.tableName);\n\n const timestamp = options.timestamp ?? generateTimestamp();\n const offsetTimestamp = incrementTimestamp(timestamp, timestampOffset);\n timestampOffset++;\n\n const blueprint = generatePivotTableBlueprint(pivot);\n const migration = generateCreateMigration(blueprint, {\n ...options,\n timestamp: offsetTimestamp,\n });\n migrations.push(migration);\n }\n }\n\n return migrations;\n}\n\n/**\n * Increments a timestamp by seconds.\n */\nfunction incrementTimestamp(timestamp: string, seconds: number): string {\n if (seconds === 0) return timestamp;\n\n // Parse timestamp: YYYY_MM_DD_HHMMSS\n const parts = timestamp.split('_');\n if (parts.length < 4) {\n // Invalid format, return original\n return timestamp;\n }\n\n const yearPart = parts[0] ?? '2024';\n const monthPart = parts[1] ?? '01';\n const dayPart = parts[2] ?? '01';\n const timePart = parts[3] ?? '000000';\n\n const year = parseInt(yearPart, 10);\n const month = parseInt(monthPart, 10) - 1;\n const day = parseInt(dayPart, 10);\n const hours = parseInt(timePart.substring(0, 2), 10);\n const minutes = parseInt(timePart.substring(2, 4), 10);\n const secs = parseInt(timePart.substring(4, 6), 10);\n\n const date = new Date(year, month, day, hours, minutes, secs + seconds);\n\n const newYear = date.getFullYear();\n const newMonth = String(date.getMonth() + 1).padStart(2, '0');\n const newDay = String(date.getDate()).padStart(2, '0');\n const newHours = String(date.getHours()).padStart(2, '0');\n const newMinutes = String(date.getMinutes()).padStart(2, '0');\n const newSecs = String(date.getSeconds()).padStart(2, '0');\n\n return `${newYear}_${newMonth}_${newDay}_${newHours}${newMinutes}${newSecs}`;\n}\n\n/**\n * Generates migration from a single schema.\n */\nexport function generateMigrationFromSchema(\n schema: LoadedSchema,\n allSchemas: SchemaCollection,\n options: MigrationOptions = {}\n): MigrationFile {\n const blueprint = schemaToBlueprint(schema, allSchemas);\n return generateCreateMigration(blueprint, options);\n}\n\n/**\n * Generates drop migration for a table.\n */\nexport function generateDropMigrationForTable(\n tableName: string,\n options: MigrationOptions = {}\n): MigrationFile {\n return generateDropMigration(tableName, options);\n}\n\n/**\n * Formats migration content for writing to file.\n */\nexport function formatMigrationFile(migration: MigrationFile): string {\n return migration.content;\n}\n\n/**\n * Gets the output path for a migration file.\n */\nexport function getMigrationPath(\n migration: MigrationFile,\n outputDir: string = 'database/migrations'\n): string {\n return `${outputDir}/${migration.fileName}`;\n}\n","/**\n * @famgia/omnify-laravel - ALTER Migration Generator\n *\n * Generates Laravel migration files for ALTER table operations.\n */\n\nimport type { SchemaChange, PropertySnapshot } from '@famgia/omnify-atlas';\nimport type { MigrationFile, MigrationOptions } from './types.js';\nimport { toTableName, toColumnName } from './schema-builder.js';\n\n/**\n * Maps Omnify property types to Laravel column methods.\n */\nconst TYPE_METHOD_MAP: Record<string, string> = {\n String: 'string',\n Int: 'integer',\n BigInt: 'bigInteger',\n Float: 'double',\n Decimal: 'decimal',\n Boolean: 'boolean',\n Text: 'text',\n LongText: 'longText',\n Date: 'date',\n Time: 'time',\n Timestamp: 'timestamp',\n Json: 'json',\n Email: 'string',\n Password: 'string',\n File: 'string',\n MultiFile: 'json',\n Enum: 'enum',\n Select: 'string',\n Lookup: 'unsignedBigInteger',\n};\n\n/**\n * Generates timestamp prefix for migration file name.\n */\nfunction generateTimestamp(): string {\n const now = new Date();\n const year = now.getFullYear();\n const month = String(now.getMonth() + 1).padStart(2, '0');\n const day = String(now.getDate()).padStart(2, '0');\n const hours = String(now.getHours()).padStart(2, '0');\n const minutes = String(now.getMinutes()).padStart(2, '0');\n const seconds = String(now.getSeconds()).padStart(2, '0');\n return `${year}_${month}_${day}_${hours}${minutes}${seconds}`;\n}\n\n/**\n * Formats a column addition.\n */\nfunction formatAddColumn(columnName: string, prop: PropertySnapshot): string {\n const snakeColumn = toColumnName(columnName);\n const method = TYPE_METHOD_MAP[prop.type] ?? 'string';\n\n let code: string;\n\n // Handle decimal with precision and scale\n if (prop.type === 'Decimal') {\n const precision = prop.precision ?? 8;\n const scale = prop.scale ?? 2;\n code = `$table->${method}('${snakeColumn}', ${precision}, ${scale})`;\n } else {\n code = `$table->${method}('${snakeColumn}')`;\n }\n\n // Add modifiers\n if (prop.nullable) code += '->nullable()';\n if (prop.unique) code += '->unique()';\n if (prop.default !== undefined) {\n const defaultValue = typeof prop.default === 'string'\n ? `'${prop.default}'`\n : JSON.stringify(prop.default);\n code += `->default(${defaultValue})`;\n }\n\n return code + ';';\n}\n\n/**\n * Formats a column removal.\n */\nfunction formatDropColumn(columnName: string): string {\n const snakeColumn = toColumnName(columnName);\n return `$table->dropColumn('${snakeColumn}');`;\n}\n\n/**\n * Formats a column rename.\n * Note: Requires doctrine/dbal package in Laravel.\n */\nfunction formatRenameColumn(oldName: string, newName: string): string {\n const oldSnake = toColumnName(oldName);\n const newSnake = toColumnName(newName);\n return `$table->renameColumn('${oldSnake}', '${newSnake}');`;\n}\n\n/**\n * Formats a column modification.\n * Note: Requires doctrine/dbal package in Laravel.\n */\nfunction formatModifyColumn(\n columnName: string,\n _prevProp: PropertySnapshot,\n currProp: PropertySnapshot\n): string {\n const snakeColumn = toColumnName(columnName);\n const method = TYPE_METHOD_MAP[currProp.type] ?? 'string';\n\n let code: string;\n\n // Handle decimal with precision and scale\n if (currProp.type === 'Decimal') {\n const precision = currProp.precision ?? 8;\n const scale = currProp.scale ?? 2;\n code = `$table->${method}('${snakeColumn}', ${precision}, ${scale})`;\n } else {\n code = `$table->${method}('${snakeColumn}')`;\n }\n\n // Add modifiers\n if (currProp.nullable) code += '->nullable()';\n if (currProp.unique) code += '->unique()';\n if (currProp.default !== undefined) {\n const defaultValue = typeof currProp.default === 'string'\n ? `'${currProp.default}'`\n : JSON.stringify(currProp.default);\n code += `->default(${defaultValue})`;\n }\n\n return code + '->change();';\n}\n\n/**\n * Formats an index addition.\n */\nfunction formatAddIndex(columns: readonly string[], unique: boolean): string {\n const snakeColumns = columns.map(toColumnName);\n const method = unique ? 'unique' : 'index';\n const colsArg = snakeColumns.length === 1\n ? `'${snakeColumns[0]}'`\n : `[${snakeColumns.map(c => `'${c}'`).join(', ')}]`;\n\n return `$table->${method}(${colsArg});`;\n}\n\n/**\n * Formats an index removal.\n */\nfunction formatDropIndex(tableName: string, columns: readonly string[], unique: boolean): string {\n const snakeColumns = columns.map(toColumnName);\n const method = unique ? 'dropUnique' : 'dropIndex';\n\n // Laravel generates index names as: {table}_{columns}_{type}\n const suffix = unique ? 'unique' : 'index';\n const indexName = `${tableName}_${snakeColumns.join('_')}_${suffix}`;\n\n return `$table->${method}('${indexName}');`;\n}\n\n/**\n * Generates ALTER migration content for a schema change.\n */\nfunction generateAlterMigrationContent(\n tableName: string,\n change: SchemaChange,\n options: MigrationOptions = {}\n): string {\n const upLines: string[] = [];\n const downLines: string[] = [];\n\n // Column changes\n if (change.columnChanges) {\n for (const col of change.columnChanges) {\n if (col.changeType === 'added' && col.currentDef) {\n upLines.push(` ${formatAddColumn(col.column, col.currentDef)}`);\n downLines.push(` ${formatDropColumn(col.column)}`);\n } else if (col.changeType === 'removed' && col.previousDef) {\n upLines.push(` ${formatDropColumn(col.column)}`);\n downLines.push(` ${formatAddColumn(col.column, col.previousDef)}`);\n } else if (col.changeType === 'modified' && col.previousDef && col.currentDef) {\n upLines.push(` ${formatModifyColumn(col.column, col.previousDef, col.currentDef)}`);\n downLines.push(` ${formatModifyColumn(col.column, col.currentDef, col.previousDef)}`);\n } else if (col.changeType === 'renamed' && col.previousColumn) {\n // Rename column\n upLines.push(` ${formatRenameColumn(col.previousColumn, col.column)}`);\n downLines.push(` ${formatRenameColumn(col.column, col.previousColumn)}`);\n\n // If there are also property modifications, apply them after rename\n if (col.modifications && col.modifications.length > 0 && col.previousDef && col.currentDef) {\n upLines.push(` ${formatModifyColumn(col.column, col.previousDef, col.currentDef)}`);\n downLines.push(` ${formatModifyColumn(col.column, col.currentDef, col.previousDef)}`);\n }\n }\n }\n }\n\n // Index changes\n if (change.indexChanges) {\n for (const idx of change.indexChanges) {\n if (idx.changeType === 'added') {\n upLines.push(` ${formatAddIndex(idx.index.columns, idx.index.unique)}`);\n downLines.push(` ${formatDropIndex(tableName, idx.index.columns, idx.index.unique)}`);\n } else {\n upLines.push(` ${formatDropIndex(tableName, idx.index.columns, idx.index.unique)}`);\n downLines.push(` ${formatAddIndex(idx.index.columns, idx.index.unique)}`);\n }\n }\n }\n\n // Option changes (timestamps, softDelete)\n if (change.optionChanges) {\n if (change.optionChanges.timestamps) {\n const { from, to } = change.optionChanges.timestamps;\n if (to && !from) {\n upLines.push(` $table->timestamps();`);\n downLines.push(` $table->dropTimestamps();`);\n } else if (from && !to) {\n upLines.push(` $table->dropTimestamps();`);\n downLines.push(` $table->timestamps();`);\n }\n }\n\n if (change.optionChanges.softDelete) {\n const { from, to } = change.optionChanges.softDelete;\n if (to && !from) {\n upLines.push(` $table->softDeletes();`);\n downLines.push(` $table->dropSoftDeletes();`);\n } else if (from && !to) {\n upLines.push(` $table->dropSoftDeletes();`);\n downLines.push(` $table->softDeletes();`);\n }\n }\n }\n\n const connection = options.connection\n ? `\\n protected $connection = '${options.connection}';\\n`\n : '';\n\n return `<?php\n\nuse Illuminate\\\\Database\\\\Migrations\\\\Migration;\nuse Illuminate\\\\Database\\\\Schema\\\\Blueprint;\nuse Illuminate\\\\Support\\\\Facades\\\\Schema;\n\nreturn new class extends Migration\n{${connection}\n /**\n * Run the migrations.\n */\n public function up(): void\n {\n Schema::table('${tableName}', function (Blueprint $table) {\n${upLines.join('\\n')}\n });\n }\n\n /**\n * Reverse the migrations.\n */\n public function down(): void\n {\n Schema::table('${tableName}', function (Blueprint $table) {\n${downLines.join('\\n')}\n });\n }\n};\n`;\n}\n\n/**\n * Generates ALTER migration for a modified schema.\n */\nexport function generateAlterMigration(\n change: SchemaChange,\n options: MigrationOptions = {}\n): MigrationFile | null {\n if (change.changeType !== 'modified') {\n return null;\n }\n\n // Check if there are actual changes to migrate\n const hasChanges =\n (change.columnChanges && change.columnChanges.length > 0) ||\n (change.indexChanges && change.indexChanges.length > 0) ||\n (change.optionChanges &&\n (change.optionChanges.timestamps ||\n change.optionChanges.softDelete));\n\n if (!hasChanges) {\n return null;\n }\n\n const tableName = toTableName(change.schemaName);\n const timestamp = options.timestamp ?? generateTimestamp();\n const fileName = `${timestamp}_update_${tableName}_table.php`;\n\n const content = generateAlterMigrationContent(tableName, change, options);\n\n return {\n fileName,\n className: `Update${change.schemaName}Table`,\n content,\n tables: [tableName],\n type: 'alter',\n };\n}\n\n/**\n * Generates DROP migration for a removed schema.\n */\nexport function generateDropTableMigration(\n schemaName: string,\n options: MigrationOptions = {}\n): MigrationFile {\n const tableName = toTableName(schemaName);\n const timestamp = options.timestamp ?? generateTimestamp();\n const fileName = `${timestamp}_drop_${tableName}_table.php`;\n\n const connection = options.connection\n ? `\\n protected $connection = '${options.connection}';\\n`\n : '';\n\n const content = `<?php\n\nuse Illuminate\\\\Database\\\\Migrations\\\\Migration;\nuse Illuminate\\\\Database\\\\Schema\\\\Blueprint;\nuse Illuminate\\\\Support\\\\Facades\\\\Schema;\n\nreturn new class extends Migration\n{${connection}\n /**\n * Run the migrations.\n */\n public function up(): void\n {\n Schema::dropIfExists('${tableName}');\n }\n\n /**\n * Reverse the migrations.\n */\n public function down(): void\n {\n // Cannot recreate table without full schema\n // Consider restoring from backup if needed\n }\n};\n`;\n\n return {\n fileName,\n className: `Drop${schemaName}Table`,\n content,\n tables: [tableName],\n type: 'drop',\n };\n}\n\n/**\n * Generates migrations for all schema changes.\n */\nexport function generateMigrationsFromChanges(\n changes: readonly SchemaChange[],\n options: MigrationOptions = {}\n): MigrationFile[] {\n const migrations: MigrationFile[] = [];\n let timestampOffset = 0;\n\n const getNextTimestamp = () => {\n const ts = options.timestamp ?? generateTimestamp();\n const offset = timestampOffset++;\n if (offset === 0) return ts;\n\n // Increment seconds\n const parts = ts.split('_');\n if (parts.length >= 4) {\n const timePart = parts[3] ?? '000000';\n const secs = parseInt(timePart.substring(4, 6), 10) + offset;\n const newSecs = String(secs % 60).padStart(2, '0');\n parts[3] = timePart.substring(0, 4) + newSecs;\n return parts.join('_');\n }\n return ts;\n };\n\n for (const change of changes) {\n if (change.changeType === 'modified') {\n const migration = generateAlterMigration(change, {\n ...options,\n timestamp: getNextTimestamp(),\n });\n if (migration) {\n migrations.push(migration);\n }\n } else if (change.changeType === 'removed') {\n migrations.push(\n generateDropTableMigration(change.schemaName, {\n ...options,\n timestamp: getNextTimestamp(),\n })\n );\n }\n // 'added' changes are handled by the regular CREATE migration generator\n }\n\n return migrations;\n}\n","/**\n * @famgia/omnify-laravel - TypeScript Interface Generator\n *\n * Generates TypeScript interfaces from schemas.\n */\n\nimport type { LoadedSchema, PropertyDefinition, SchemaCollection } from '@famgia/omnify-types';\nimport type { TSInterface, TSProperty, TypeScriptOptions } from './types.js';\n\n/**\n * Maps Omnify property types to TypeScript types.\n */\nconst TYPE_MAP: Record<string, string> = {\n String: 'string',\n Int: 'number',\n BigInt: 'number',\n Float: 'number',\n Boolean: 'boolean',\n Text: 'string',\n LongText: 'string',\n Date: 'string',\n Time: 'string',\n Timestamp: 'string',\n Json: 'unknown',\n Email: 'string',\n Password: 'string',\n File: 'string',\n MultiFile: 'string[]',\n Enum: 'string',\n Select: 'string',\n Lookup: 'number',\n};\n\n/**\n * Maps primary key types to TypeScript types.\n */\nconst PK_TYPE_MAP: Record<string, string> = {\n Int: 'number',\n BigInt: 'number',\n Uuid: 'string',\n String: 'string',\n};\n\n/**\n * Converts property name to TypeScript property name.\n * Preserves camelCase.\n */\nexport function toPropertyName(name: string): string {\n return name;\n}\n\n/**\n * Converts schema name to TypeScript interface name.\n * Preserves PascalCase.\n */\nexport function toInterfaceName(schemaName: string): string {\n return schemaName;\n}\n\n/**\n * Gets TypeScript type for a property.\n */\nexport function getPropertyType(\n property: PropertyDefinition,\n _allSchemas: SchemaCollection\n): string {\n // Handle associations\n if (property.type === 'Association') {\n const assocProp = property as {\n relation?: string;\n target?: string;\n targets?: readonly string[];\n };\n\n const targetName = assocProp.target ?? 'unknown';\n\n switch (assocProp.relation) {\n // Standard relations\n case 'OneToOne':\n case 'ManyToOne':\n return targetName;\n case 'OneToMany':\n case 'ManyToMany':\n return `${targetName}[]`;\n\n // Polymorphic relations\n case 'MorphTo':\n // Union type of all possible targets\n if (assocProp.targets && assocProp.targets.length > 0) {\n return assocProp.targets.join(' | ');\n }\n return 'unknown';\n case 'MorphOne':\n return targetName;\n case 'MorphMany':\n case 'MorphToMany':\n case 'MorphedByMany':\n return `${targetName}[]`;\n\n default:\n return 'unknown';\n }\n }\n\n // Handle enum types\n if (property.type === 'Enum') {\n const enumProp = property as { enum?: string | readonly string[] };\n if (typeof enumProp.enum === 'string') {\n // Reference to a named enum\n return enumProp.enum;\n }\n if (Array.isArray(enumProp.enum)) {\n // Inline enum - create union type\n return enumProp.enum.map(v => `'${v}'`).join(' | ');\n }\n }\n\n // Handle Select with options\n if (property.type === 'Select') {\n const selectProp = property as { options?: readonly string[] };\n if (selectProp.options && selectProp.options.length > 0) {\n return selectProp.options.map(v => `'${v}'`).join(' | ');\n }\n }\n\n // Standard type mapping\n return TYPE_MAP[property.type] ?? 'unknown';\n}\n\n/**\n * Converts a property to TypeScript property definition.\n * For MorphTo, returns multiple properties (_type, _id, and relation).\n */\nexport function propertyToTSProperties(\n propertyName: string,\n property: PropertyDefinition,\n allSchemas: SchemaCollection,\n options: TypeScriptOptions = {}\n): TSProperty[] {\n const baseProp = property as { nullable?: boolean; displayName?: string };\n const isReadonly = options.readonly ?? true;\n\n // Handle MorphTo specially - it creates _type and _id columns\n if (property.type === 'Association') {\n const assocProp = property as {\n relation?: string;\n targets?: readonly string[];\n };\n\n if (assocProp.relation === 'MorphTo' && assocProp.targets && assocProp.targets.length > 0) {\n const propBaseName = toPropertyName(propertyName);\n const targetUnion = assocProp.targets.map(t => `'${t}'`).join(' | ');\n const relationUnion = assocProp.targets.join(' | ');\n\n return [\n {\n name: `${propBaseName}Type`,\n type: targetUnion,\n optional: true, // Polymorphic columns are nullable\n readonly: isReadonly,\n comment: `Polymorphic type for ${propertyName}`,\n },\n {\n name: `${propBaseName}Id`,\n type: 'number',\n optional: true,\n readonly: isReadonly,\n comment: `Polymorphic ID for ${propertyName}`,\n },\n {\n name: propBaseName,\n type: `${relationUnion} | null`,\n optional: true,\n readonly: isReadonly,\n comment: baseProp.displayName ?? `Polymorphic relation to ${assocProp.targets.join(', ')}`,\n },\n ];\n }\n }\n\n // Default: single property\n const type = getPropertyType(property, allSchemas);\n\n return [{\n name: toPropertyName(propertyName),\n type,\n optional: baseProp.nullable ?? false,\n readonly: isReadonly,\n comment: baseProp.displayName,\n }];\n}\n\n/**\n * Converts a property to TypeScript property definition (legacy - returns single property).\n */\nexport function propertyToTSProperty(\n propertyName: string,\n property: PropertyDefinition,\n allSchemas: SchemaCollection,\n options: TypeScriptOptions = {}\n): TSProperty {\n return propertyToTSProperties(propertyName, property, allSchemas, options)[0]!;\n}\n\n/**\n * Generates TypeScript interface from schema.\n */\nexport function schemaToInterface(\n schema: LoadedSchema,\n allSchemas: SchemaCollection,\n options: TypeScriptOptions = {}\n): TSInterface {\n const properties: TSProperty[] = [];\n\n // ID property (only if id is not disabled)\n if (schema.options?.id !== false) {\n const pkType = (schema.options?.idType ?? 'BigInt') as keyof typeof PK_TYPE_MAP;\n properties.push({\n name: 'id',\n type: PK_TYPE_MAP[pkType] ?? 'number',\n optional: false,\n readonly: options.readonly ?? true,\n comment: 'Primary key',\n });\n }\n\n // Schema properties\n if (schema.properties) {\n for (const [propName, property] of Object.entries(schema.properties)) {\n // Use propertyToTSProperties which handles MorphTo returning multiple properties\n properties.push(...propertyToTSProperties(propName, property, allSchemas, options));\n }\n }\n\n // Timestamps\n if (schema.options?.timestamps !== false) {\n properties.push(\n {\n name: 'createdAt',\n type: 'string',\n optional: true,\n readonly: options.readonly ?? true,\n comment: 'Creation timestamp',\n },\n {\n name: 'updatedAt',\n type: 'string',\n optional: true,\n readonly: options.readonly ?? true,\n comment: 'Last update timestamp',\n }\n );\n }\n\n // Soft delete\n if (schema.options?.softDelete) {\n properties.push({\n name: 'deletedAt',\n type: 'string',\n optional: true,\n readonly: options.readonly ?? true,\n comment: 'Soft delete timestamp',\n });\n }\n\n return {\n name: toInterfaceName(schema.name),\n properties,\n comment: schema.displayName ?? schema.name,\n };\n}\n\n/**\n * Formats a TypeScript property.\n */\nexport function formatProperty(property: TSProperty): string {\n const readonly = property.readonly ? 'readonly ' : '';\n const optional = property.optional ? '?' : '';\n const comment = property.comment ? ` /** ${property.comment} */\\n` : '';\n return `${comment} ${readonly}${property.name}${optional}: ${property.type};`;\n}\n\n/**\n * Formats a TypeScript interface.\n */\nexport function formatInterface(iface: TSInterface): string {\n const comment = iface.comment ? `/**\\n * ${iface.comment}\\n */\\n` : '';\n const extendsClause = iface.extends && iface.extends.length > 0\n ? ` extends ${iface.extends.join(', ')}`\n : '';\n const properties = iface.properties.map(formatProperty).join('\\n');\n\n return `${comment}export interface ${iface.name}${extendsClause} {\\n${properties}\\n}`;\n}\n\n/**\n * Generates interfaces for all schemas.\n */\nexport function generateInterfaces(\n schemas: SchemaCollection,\n options: TypeScriptOptions = {}\n): TSInterface[] {\n const interfaces: TSInterface[] = [];\n\n for (const schema of Object.values(schemas)) {\n // Skip enum schemas\n if (schema.kind === 'enum') {\n continue;\n }\n\n interfaces.push(schemaToInterface(schema, schemas, options));\n }\n\n return interfaces;\n}\n","/**\n * @famgia/omnify-laravel - TypeScript Enum Generator\n *\n * Generates TypeScript enums from schema enum definitions.\n */\n\nimport type { LoadedSchema, SchemaCollection } from '@famgia/omnify-types';\nimport type { TSEnum, TSEnumValue, TSTypeAlias } from './types.js';\n\n/**\n * Converts enum value to valid TypeScript enum member name.\n */\nexport function toEnumMemberName(value: string): string {\n // Convert to PascalCase and remove invalid characters\n return value\n .split(/[-_\\s]+/)\n .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join('')\n .replace(/[^a-zA-Z0-9]/g, '');\n}\n\n/**\n * Converts schema name to TypeScript enum name.\n */\nexport function toEnumName(schemaName: string): string {\n return schemaName;\n}\n\n/**\n * Generates TypeScript enum from schema enum.\n */\nexport function schemaToEnum(schema: LoadedSchema): TSEnum | null {\n if (schema.kind !== 'enum' || !schema.values) {\n return null;\n }\n\n const values: TSEnumValue[] = schema.values.map(value => ({\n name: toEnumMemberName(value),\n value,\n }));\n\n return {\n name: toEnumName(schema.name),\n values,\n comment: schema.displayName ?? schema.name,\n };\n}\n\n/**\n * Generates enums for all enum schemas.\n */\nexport function generateEnums(schemas: SchemaCollection): TSEnum[] {\n const enums: TSEnum[] = [];\n\n for (const schema of Object.values(schemas)) {\n if (schema.kind === 'enum') {\n const enumDef = schemaToEnum(schema);\n if (enumDef) {\n enums.push(enumDef);\n }\n }\n }\n\n return enums;\n}\n\n/**\n * Formats a TypeScript enum.\n */\nexport function formatEnum(enumDef: TSEnum): string {\n const comment = enumDef.comment ? `/**\\n * ${enumDef.comment}\\n */\\n` : '';\n const values = enumDef.values\n .map(v => ` ${v.name} = '${v.value}',`)\n .join('\\n');\n\n return `${comment}export enum ${enumDef.name} {\\n${values}\\n}`;\n}\n\n/**\n * Generates a union type alias as an alternative to enum.\n */\nexport function enumToUnionType(enumDef: TSEnum): TSTypeAlias {\n const type = enumDef.values\n .map(v => `'${v.value}'`)\n .join(' | ');\n\n return {\n name: enumDef.name,\n type,\n comment: enumDef.comment,\n };\n}\n\n/**\n * Formats a TypeScript type alias.\n */\nexport function formatTypeAlias(alias: TSTypeAlias): string {\n const comment = alias.comment ? `/**\\n * ${alias.comment}\\n */\\n` : '';\n return `${comment}export type ${alias.name} = ${alias.type};`;\n}\n\n/**\n * Extracts inline enums from properties for type generation.\n */\nexport function extractInlineEnums(schemas: SchemaCollection): TSTypeAlias[] {\n const typeAliases: TSTypeAlias[] = [];\n\n for (const schema of Object.values(schemas)) {\n if (schema.kind === 'enum' || !schema.properties) {\n continue;\n }\n\n for (const [propName, property] of Object.entries(schema.properties)) {\n if (property.type === 'Enum') {\n const enumProp = property as { enum?: readonly string[]; displayName?: string };\n\n // Only handle inline array enums (not references to named enums)\n if (Array.isArray(enumProp.enum) && enumProp.enum.length > 0) {\n const typeName = `${schema.name}${propName.charAt(0).toUpperCase() + propName.slice(1)}`;\n typeAliases.push({\n name: typeName,\n type: enumProp.enum.map(v => `'${v}'`).join(' | '),\n comment: enumProp.displayName ?? `${schema.name} ${propName} enum`,\n });\n }\n }\n\n if (property.type === 'Select') {\n const selectProp = property as { options?: readonly string[]; displayName?: string };\n\n if (selectProp.options && selectProp.options.length > 0) {\n const typeName = `${schema.name}${propName.charAt(0).toUpperCase() + propName.slice(1)}`;\n typeAliases.push({\n name: typeName,\n type: selectProp.options.map(v => `'${v}'`).join(' | '),\n comment: selectProp.displayName ?? `${schema.name} ${propName} options`,\n });\n }\n }\n }\n }\n\n return typeAliases;\n}\n","/**\n * @famgia/omnify-laravel - TypeScript Generator\n *\n * Main TypeScript code generator combining interfaces, enums, and types.\n */\n\nimport type { SchemaCollection } from '@famgia/omnify-types';\nimport type { TypeScriptFile, TypeScriptOptions, TSInterface, TSEnum, TSTypeAlias } from './types.js';\nimport { generateInterfaces, formatInterface } from './interface-generator.js';\nimport { generateEnums, formatEnum, formatTypeAlias, extractInlineEnums } from './enum-generator.js';\n\n/**\n * Default options for TypeScript generation.\n */\nconst DEFAULT_OPTIONS: TypeScriptOptions = {\n singleFile: true,\n fileName: 'types.ts',\n readonly: true,\n strictNullChecks: true,\n};\n\n/**\n * Generates the file header comment.\n */\nfunction generateHeader(): string {\n return `/**\n * Auto-generated TypeScript types from Omnify schemas.\n * DO NOT EDIT - This file is automatically generated.\n */\n\n`;\n}\n\n/**\n * Generates all TypeScript code as a single file.\n */\nexport function generateTypeScriptFile(\n schemas: SchemaCollection,\n options: TypeScriptOptions = {}\n): TypeScriptFile {\n const opts = { ...DEFAULT_OPTIONS, ...options };\n const parts: string[] = [generateHeader()];\n const types: string[] = [];\n\n // Generate enums first (they're referenced by interfaces)\n const enums = generateEnums(schemas);\n if (enums.length > 0) {\n parts.push('// Enums\\n');\n for (const enumDef of enums) {\n parts.push(formatEnum(enumDef));\n parts.push('\\n\\n');\n types.push(enumDef.name);\n }\n }\n\n // Generate inline enum type aliases\n const inlineEnums = extractInlineEnums(schemas);\n if (inlineEnums.length > 0) {\n parts.push('// Type Aliases\\n');\n for (const alias of inlineEnums) {\n parts.push(formatTypeAlias(alias));\n parts.push('\\n\\n');\n types.push(alias.name);\n }\n }\n\n // Generate interfaces\n const interfaces = generateInterfaces(schemas, opts);\n if (interfaces.length > 0) {\n parts.push('// Interfaces\\n');\n for (const iface of interfaces) {\n parts.push(formatInterface(iface));\n parts.push('\\n\\n');\n types.push(iface.name);\n }\n }\n\n return {\n fileName: opts.fileName ?? 'types.ts',\n content: parts.join('').trim() + '\\n',\n types,\n };\n}\n\n/**\n * Generates TypeScript code as multiple files.\n */\nexport function generateTypeScriptFiles(\n schemas: SchemaCollection,\n options: TypeScriptOptions = {}\n): TypeScriptFile[] {\n const opts = { ...DEFAULT_OPTIONS, ...options };\n const files: TypeScriptFile[] = [];\n\n // Enums file\n const enums = generateEnums(schemas);\n if (enums.length > 0) {\n const content = generateHeader() +\n enums.map(formatEnum).join('\\n\\n') + '\\n';\n files.push({\n fileName: 'enums.ts',\n content,\n types: enums.map(e => e.name),\n });\n }\n\n // Inline enums/type aliases file\n const inlineEnums = extractInlineEnums(schemas);\n if (inlineEnums.length > 0) {\n const content = generateHeader() +\n inlineEnums.map(formatTypeAlias).join('\\n\\n') + '\\n';\n files.push({\n fileName: 'type-aliases.ts',\n content,\n types: inlineEnums.map(a => a.name),\n });\n }\n\n // Individual interface files\n const interfaces = generateInterfaces(schemas, opts);\n for (const iface of interfaces) {\n const imports = collectImports(iface, enums, inlineEnums, interfaces);\n const importStatement = formatImports(imports);\n\n const content = generateHeader() +\n (importStatement ? importStatement + '\\n\\n' : '') +\n formatInterface(iface) + '\\n';\n\n files.push({\n fileName: `${toKebabCase(iface.name)}.ts`,\n content,\n types: [iface.name],\n });\n }\n\n // Index file\n const indexContent = generateIndexFile(files);\n files.push({\n fileName: 'index.ts',\n content: indexContent,\n types: [],\n });\n\n return files;\n}\n\n/**\n * Converts PascalCase to kebab-case.\n */\nfunction toKebabCase(name: string): string {\n return name\n .replace(/([A-Z])/g, '-$1')\n .toLowerCase()\n .replace(/^-/, '');\n}\n\n/**\n * Collects imports needed for an interface.\n */\nfunction collectImports(\n iface: TSInterface,\n enums: TSEnum[],\n typeAliases: TSTypeAlias[],\n allInterfaces: TSInterface[]\n): Map<string, string[]> {\n const imports = new Map<string, string[]>();\n const enumNames = new Set(enums.map(e => e.name));\n const aliasNames = new Set(typeAliases.map(a => a.name));\n const interfaceNames = new Set(allInterfaces.map(i => i.name));\n\n for (const prop of iface.properties) {\n // Check if type references an enum\n if (enumNames.has(prop.type)) {\n const existing = imports.get('./enums.js') ?? [];\n if (!existing.includes(prop.type)) {\n imports.set('./enums.js', [...existing, prop.type]);\n }\n }\n\n // Check if type references a type alias\n if (aliasNames.has(prop.type)) {\n const existing = imports.get('./type-aliases.js') ?? [];\n if (!existing.includes(prop.type)) {\n imports.set('./type-aliases.js', [...existing, prop.type]);\n }\n }\n\n // Check if type references another interface (for relationships)\n const baseType = prop.type.replace('[]', '');\n if (interfaceNames.has(baseType) && baseType !== iface.name) {\n const fileName = `./${toKebabCase(baseType)}.js`;\n const existing = imports.get(fileName) ?? [];\n if (!existing.includes(baseType)) {\n imports.set(fileName, [...existing, baseType]);\n }\n }\n }\n\n return imports;\n}\n\n/**\n * Formats import statements.\n */\nfunction formatImports(imports: Map<string, string[]>): string {\n if (imports.size === 0) return '';\n\n const lines: string[] = [];\n for (const [path, names] of imports) {\n lines.push(`import type { ${names.join(', ')} } from '${path}';`);\n }\n return lines.join('\\n');\n}\n\n/**\n * Generates index.ts file for re-exports.\n */\nfunction generateIndexFile(files: TypeScriptFile[]): string {\n const exports: string[] = [generateHeader().trim(), ''];\n\n for (const file of files) {\n if (file.fileName === 'index.ts') continue;\n const moduleName = file.fileName.replace('.ts', '.js');\n exports.push(`export * from './${moduleName}';`);\n }\n\n return exports.join('\\n') + '\\n';\n}\n\n/**\n * Generates TypeScript types with configurable output.\n */\nexport function generateTypeScript(\n schemas: SchemaCollection,\n options: TypeScriptOptions = {}\n): TypeScriptFile[] {\n const opts = { ...DEFAULT_OPTIONS, ...options };\n\n if (opts.singleFile) {\n return [generateTypeScriptFile(schemas, opts)];\n }\n\n return generateTypeScriptFiles(schemas, opts);\n}\n\n/**\n * Gets output path for a TypeScript file.\n */\nexport function getTypeScriptPath(\n file: TypeScriptFile,\n outputDir: string = 'src/types'\n): string {\n return `${outputDir}/${file.fileName}`;\n}\n","/**\n * @famgia/omnify-laravel - Plugin\n *\n * Plugin wrapper for Laravel migration and TypeScript type generators.\n *\n * @example\n * ```typescript\n * import { defineConfig } from '@famgia/omnify';\n * import laravel from '@famgia/omnify-laravel/plugin';\n *\n * export default defineConfig({\n * plugins: [\n * laravel({\n * migrationsPath: 'database/migrations',\n * typesPath: 'resources/js/types',\n * singleFile: true,\n * }),\n * ],\n * });\n * ```\n */\n\nimport type { OmnifyPlugin, GeneratorOutput, GeneratorContext } from '@famgia/omnify-types';\nimport { generateMigrations, getMigrationPath, type MigrationOptions } from './migration/index.js';\nimport { generateTypeScript, type TypeScriptOptions } from './typescript/index.js';\n\n/**\n * Options for the Laravel plugin.\n */\nexport interface LaravelPluginOptions {\n /**\n * Path for Laravel migration files.\n * @default 'database/migrations'\n */\n migrationsPath?: string;\n\n /**\n * Path for TypeScript type files.\n * @default 'types'\n */\n typesPath?: string;\n\n /**\n * Generate all types in a single file.\n * @default true\n */\n singleFile?: boolean;\n\n /**\n * Database connection name for migrations.\n */\n connection?: string;\n\n /**\n * Custom timestamp for migration file names (mainly for testing).\n */\n timestamp?: string;\n\n /**\n * Generate TypeScript types.\n * @default true\n */\n generateTypes?: boolean;\n\n /**\n * Generate Laravel migrations.\n * @default true\n */\n generateMigrations?: boolean;\n}\n\n/**\n * Resolved options with defaults applied.\n */\ninterface ResolvedOptions {\n migrationsPath: string;\n typesPath: string;\n singleFile: boolean;\n connection: string | undefined;\n timestamp: string | undefined;\n generateTypes: boolean;\n generateMigrations: boolean;\n}\n\n/**\n * Resolves options with defaults.\n */\nfunction resolveOptions(options?: LaravelPluginOptions): ResolvedOptions {\n return {\n migrationsPath: options?.migrationsPath ?? 'database/migrations',\n typesPath: options?.typesPath ?? 'types',\n singleFile: options?.singleFile ?? true,\n connection: options?.connection,\n timestamp: options?.timestamp,\n generateTypes: options?.generateTypes ?? true,\n generateMigrations: options?.generateMigrations ?? true,\n };\n}\n\n/**\n * Creates the Laravel plugin with the specified options.\n *\n * @param options - Plugin configuration options\n * @returns OmnifyPlugin configured for Laravel\n */\nexport default function laravelPlugin(options?: LaravelPluginOptions): OmnifyPlugin {\n const resolved = resolveOptions(options);\n\n return {\n name: '@famgia/omnify-laravel',\n version: '0.0.7',\n\n generators: [\n // Laravel Migrations Generator\n ...(resolved.generateMigrations\n ? [\n {\n name: 'laravel-migrations',\n description: 'Generate Laravel migration files',\n\n generate: async (ctx: GeneratorContext): Promise<GeneratorOutput[]> => {\n const migrationOptions: MigrationOptions = {\n connection: resolved.connection,\n timestamp: resolved.timestamp,\n };\n\n const migrations = generateMigrations(ctx.schemas, migrationOptions);\n\n return migrations.map((migration) => ({\n path: getMigrationPath(migration, resolved.migrationsPath),\n content: migration.content,\n type: 'migration' as const,\n metadata: {\n tableName: migration.tables[0],\n migrationType: migration.type,\n },\n }));\n },\n },\n ]\n : []),\n\n // TypeScript Types Generator\n ...(resolved.generateTypes\n ? [\n {\n name: 'typescript-types',\n description: 'Generate TypeScript type definitions',\n\n generate: async (ctx: GeneratorContext): Promise<GeneratorOutput[]> => {\n const tsOptions: TypeScriptOptions = {\n singleFile: resolved.singleFile,\n };\n\n const files = generateTypeScript(ctx.schemas, tsOptions);\n\n return files.map((file) => ({\n path: `${resolved.typesPath}/${file.fileName}`,\n content: file.content,\n type: 'type' as const,\n metadata: {\n types: file.types,\n },\n }));\n },\n },\n ]\n : []),\n ],\n };\n}\n\n// Named export for flexibility\nexport { laravelPlugin };\n"],"mappings":"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","names":["TYPE_METHOD_MAP","generateTimestamp"]}