@famgia/omnify-laravel 0.0.6 → 0.0.8
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/dist/{chunk-BA63DET3.js → chunk-2XKSPWNJ.js} +319 -13
- package/dist/chunk-2XKSPWNJ.js.map +1 -0
- package/dist/index.cjs +321 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +21 -1
- package/dist/index.d.ts +21 -1
- package/dist/index.js +7 -1
- package/dist/plugin.cjs +49 -12
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.js +1 -1
- package/package.json +4 -3
- package/dist/chunk-BA63DET3.js.map +0 -1
|
@@ -163,7 +163,6 @@ function generateForeignKey(propertyName, property, allSchemas) {
|
|
|
163
163
|
onUpdate: assocProp.onUpdate ?? "cascade"
|
|
164
164
|
};
|
|
165
165
|
const index = {
|
|
166
|
-
name: `idx_${columnName}`,
|
|
167
166
|
columns: [columnName],
|
|
168
167
|
unique: false
|
|
169
168
|
};
|
|
@@ -365,12 +364,10 @@ function generatePivotTableBlueprint(pivot) {
|
|
|
365
364
|
unique: true
|
|
366
365
|
});
|
|
367
366
|
indexes.push({
|
|
368
|
-
name: `idx_${pivot.sourceColumn}`,
|
|
369
367
|
columns: [pivot.sourceColumn],
|
|
370
368
|
unique: false
|
|
371
369
|
});
|
|
372
370
|
indexes.push({
|
|
373
|
-
name: `idx_${pivot.targetColumn}`,
|
|
374
371
|
columns: [pivot.targetColumn],
|
|
375
372
|
unique: false
|
|
376
373
|
});
|
|
@@ -521,14 +518,57 @@ return new class extends Migration
|
|
|
521
518
|
type: "drop"
|
|
522
519
|
};
|
|
523
520
|
}
|
|
521
|
+
function extractDependencies(schema) {
|
|
522
|
+
const deps = [];
|
|
523
|
+
if (!schema.properties) {
|
|
524
|
+
return deps;
|
|
525
|
+
}
|
|
526
|
+
for (const property of Object.values(schema.properties)) {
|
|
527
|
+
if (property.type !== "Association") {
|
|
528
|
+
continue;
|
|
529
|
+
}
|
|
530
|
+
const assocProp = property;
|
|
531
|
+
if ((assocProp.relation === "ManyToOne" || assocProp.relation === "OneToOne") && !assocProp.mappedBy && assocProp.target) {
|
|
532
|
+
deps.push(assocProp.target);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
return deps;
|
|
536
|
+
}
|
|
537
|
+
function topologicalSort(schemas) {
|
|
538
|
+
const schemaList = Object.values(schemas).filter((s) => s.kind !== "enum");
|
|
539
|
+
const sorted = [];
|
|
540
|
+
const visited = /* @__PURE__ */ new Set();
|
|
541
|
+
const visiting = /* @__PURE__ */ new Set();
|
|
542
|
+
function visit(schema) {
|
|
543
|
+
if (visited.has(schema.name)) {
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
if (visiting.has(schema.name)) {
|
|
547
|
+
return;
|
|
548
|
+
}
|
|
549
|
+
visiting.add(schema.name);
|
|
550
|
+
const deps = extractDependencies(schema);
|
|
551
|
+
for (const depName of deps) {
|
|
552
|
+
const depSchema = schemas[depName];
|
|
553
|
+
if (depSchema && depSchema.kind !== "enum") {
|
|
554
|
+
visit(depSchema);
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
visiting.delete(schema.name);
|
|
558
|
+
visited.add(schema.name);
|
|
559
|
+
sorted.push(schema);
|
|
560
|
+
}
|
|
561
|
+
for (const schema of schemaList) {
|
|
562
|
+
visit(schema);
|
|
563
|
+
}
|
|
564
|
+
return sorted;
|
|
565
|
+
}
|
|
524
566
|
function generateMigrations(schemas, options = {}) {
|
|
525
567
|
const migrations = [];
|
|
526
568
|
const pivotTablesGenerated = /* @__PURE__ */ new Set();
|
|
527
569
|
let timestampOffset = 0;
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
continue;
|
|
531
|
-
}
|
|
570
|
+
const sortedSchemas = topologicalSort(schemas);
|
|
571
|
+
for (const schema of sortedSchemas) {
|
|
532
572
|
const timestamp = options.timestamp ?? generateTimestamp();
|
|
533
573
|
const offsetTimestamp = incrementTimestamp(timestamp, timestampOffset);
|
|
534
574
|
timestampOffset++;
|
|
@@ -539,10 +579,7 @@ function generateMigrations(schemas, options = {}) {
|
|
|
539
579
|
});
|
|
540
580
|
migrations.push(migration);
|
|
541
581
|
}
|
|
542
|
-
for (const schema of
|
|
543
|
-
if (schema.kind === "enum") {
|
|
544
|
-
continue;
|
|
545
|
-
}
|
|
582
|
+
for (const schema of sortedSchemas) {
|
|
546
583
|
const pivotTables = extractManyToManyRelations(schema, schemas);
|
|
547
584
|
for (const pivot of pivotTables) {
|
|
548
585
|
if (pivotTablesGenerated.has(pivot.tableName)) {
|
|
@@ -601,6 +638,272 @@ function getMigrationPath(migration, outputDir = "database/migrations") {
|
|
|
601
638
|
return `${outputDir}/${migration.fileName}`;
|
|
602
639
|
}
|
|
603
640
|
|
|
641
|
+
// src/migration/alter-generator.ts
|
|
642
|
+
var TYPE_METHOD_MAP2 = {
|
|
643
|
+
String: "string",
|
|
644
|
+
Int: "integer",
|
|
645
|
+
BigInt: "bigInteger",
|
|
646
|
+
Float: "double",
|
|
647
|
+
Boolean: "boolean",
|
|
648
|
+
Text: "text",
|
|
649
|
+
LongText: "longText",
|
|
650
|
+
Date: "date",
|
|
651
|
+
Time: "time",
|
|
652
|
+
Timestamp: "timestamp",
|
|
653
|
+
Json: "json",
|
|
654
|
+
Email: "string",
|
|
655
|
+
Password: "string",
|
|
656
|
+
File: "string",
|
|
657
|
+
MultiFile: "json",
|
|
658
|
+
Enum: "enum",
|
|
659
|
+
Select: "string",
|
|
660
|
+
Lookup: "unsignedBigInteger"
|
|
661
|
+
};
|
|
662
|
+
function generateTimestamp2() {
|
|
663
|
+
const now = /* @__PURE__ */ new Date();
|
|
664
|
+
const year = now.getFullYear();
|
|
665
|
+
const month = String(now.getMonth() + 1).padStart(2, "0");
|
|
666
|
+
const day = String(now.getDate()).padStart(2, "0");
|
|
667
|
+
const hours = String(now.getHours()).padStart(2, "0");
|
|
668
|
+
const minutes = String(now.getMinutes()).padStart(2, "0");
|
|
669
|
+
const seconds = String(now.getSeconds()).padStart(2, "0");
|
|
670
|
+
return `${year}_${month}_${day}_${hours}${minutes}${seconds}`;
|
|
671
|
+
}
|
|
672
|
+
function formatAddColumn(columnName, prop) {
|
|
673
|
+
const snakeColumn = toColumnName(columnName);
|
|
674
|
+
const method = TYPE_METHOD_MAP2[prop.type] ?? "string";
|
|
675
|
+
let code = `$table->${method}('${snakeColumn}')`;
|
|
676
|
+
if (prop.nullable) code += "->nullable()";
|
|
677
|
+
if (prop.unique) code += "->unique()";
|
|
678
|
+
if (prop.default !== void 0) {
|
|
679
|
+
const defaultValue = typeof prop.default === "string" ? `'${prop.default}'` : JSON.stringify(prop.default);
|
|
680
|
+
code += `->default(${defaultValue})`;
|
|
681
|
+
}
|
|
682
|
+
return code + ";";
|
|
683
|
+
}
|
|
684
|
+
function formatDropColumn(columnName) {
|
|
685
|
+
const snakeColumn = toColumnName(columnName);
|
|
686
|
+
return `$table->dropColumn('${snakeColumn}');`;
|
|
687
|
+
}
|
|
688
|
+
function formatRenameColumn(oldName, newName) {
|
|
689
|
+
const oldSnake = toColumnName(oldName);
|
|
690
|
+
const newSnake = toColumnName(newName);
|
|
691
|
+
return `$table->renameColumn('${oldSnake}', '${newSnake}');`;
|
|
692
|
+
}
|
|
693
|
+
function formatModifyColumn(columnName, _prevProp, currProp) {
|
|
694
|
+
const snakeColumn = toColumnName(columnName);
|
|
695
|
+
const method = TYPE_METHOD_MAP2[currProp.type] ?? "string";
|
|
696
|
+
let code = `$table->${method}('${snakeColumn}')`;
|
|
697
|
+
if (currProp.nullable) code += "->nullable()";
|
|
698
|
+
if (currProp.unique) code += "->unique()";
|
|
699
|
+
if (currProp.default !== void 0) {
|
|
700
|
+
const defaultValue = typeof currProp.default === "string" ? `'${currProp.default}'` : JSON.stringify(currProp.default);
|
|
701
|
+
code += `->default(${defaultValue})`;
|
|
702
|
+
}
|
|
703
|
+
return code + "->change();";
|
|
704
|
+
}
|
|
705
|
+
function formatAddIndex(columns, unique) {
|
|
706
|
+
const snakeColumns = columns.map(toColumnName);
|
|
707
|
+
const method = unique ? "unique" : "index";
|
|
708
|
+
const colsArg = snakeColumns.length === 1 ? `'${snakeColumns[0]}'` : `[${snakeColumns.map((c) => `'${c}'`).join(", ")}]`;
|
|
709
|
+
return `$table->${method}(${colsArg});`;
|
|
710
|
+
}
|
|
711
|
+
function formatDropIndex(tableName, columns, unique) {
|
|
712
|
+
const snakeColumns = columns.map(toColumnName);
|
|
713
|
+
const method = unique ? "dropUnique" : "dropIndex";
|
|
714
|
+
const suffix = unique ? "unique" : "index";
|
|
715
|
+
const indexName = `${tableName}_${snakeColumns.join("_")}_${suffix}`;
|
|
716
|
+
return `$table->${method}('${indexName}');`;
|
|
717
|
+
}
|
|
718
|
+
function generateAlterMigrationContent(tableName, change, options = {}) {
|
|
719
|
+
const upLines = [];
|
|
720
|
+
const downLines = [];
|
|
721
|
+
if (change.columnChanges) {
|
|
722
|
+
for (const col of change.columnChanges) {
|
|
723
|
+
if (col.changeType === "added" && col.currentDef) {
|
|
724
|
+
upLines.push(` ${formatAddColumn(col.column, col.currentDef)}`);
|
|
725
|
+
downLines.push(` ${formatDropColumn(col.column)}`);
|
|
726
|
+
} else if (col.changeType === "removed" && col.previousDef) {
|
|
727
|
+
upLines.push(` ${formatDropColumn(col.column)}`);
|
|
728
|
+
downLines.push(` ${formatAddColumn(col.column, col.previousDef)}`);
|
|
729
|
+
} else if (col.changeType === "modified" && col.previousDef && col.currentDef) {
|
|
730
|
+
upLines.push(` ${formatModifyColumn(col.column, col.previousDef, col.currentDef)}`);
|
|
731
|
+
downLines.push(` ${formatModifyColumn(col.column, col.currentDef, col.previousDef)}`);
|
|
732
|
+
} else if (col.changeType === "renamed" && col.previousColumn) {
|
|
733
|
+
upLines.push(` ${formatRenameColumn(col.previousColumn, col.column)}`);
|
|
734
|
+
downLines.push(` ${formatRenameColumn(col.column, col.previousColumn)}`);
|
|
735
|
+
if (col.modifications && col.modifications.length > 0 && col.previousDef && col.currentDef) {
|
|
736
|
+
upLines.push(` ${formatModifyColumn(col.column, col.previousDef, col.currentDef)}`);
|
|
737
|
+
downLines.push(` ${formatModifyColumn(col.column, col.currentDef, col.previousDef)}`);
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
if (change.indexChanges) {
|
|
743
|
+
for (const idx of change.indexChanges) {
|
|
744
|
+
if (idx.changeType === "added") {
|
|
745
|
+
upLines.push(` ${formatAddIndex(idx.index.columns, idx.index.unique)}`);
|
|
746
|
+
downLines.push(` ${formatDropIndex(tableName, idx.index.columns, idx.index.unique)}`);
|
|
747
|
+
} else {
|
|
748
|
+
upLines.push(` ${formatDropIndex(tableName, idx.index.columns, idx.index.unique)}`);
|
|
749
|
+
downLines.push(` ${formatAddIndex(idx.index.columns, idx.index.unique)}`);
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
if (change.optionChanges) {
|
|
754
|
+
if (change.optionChanges.timestamps) {
|
|
755
|
+
const { from, to } = change.optionChanges.timestamps;
|
|
756
|
+
if (to && !from) {
|
|
757
|
+
upLines.push(` $table->timestamps();`);
|
|
758
|
+
downLines.push(` $table->dropTimestamps();`);
|
|
759
|
+
} else if (from && !to) {
|
|
760
|
+
upLines.push(` $table->dropTimestamps();`);
|
|
761
|
+
downLines.push(` $table->timestamps();`);
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
if (change.optionChanges.softDelete) {
|
|
765
|
+
const { from, to } = change.optionChanges.softDelete;
|
|
766
|
+
if (to && !from) {
|
|
767
|
+
upLines.push(` $table->softDeletes();`);
|
|
768
|
+
downLines.push(` $table->dropSoftDeletes();`);
|
|
769
|
+
} else if (from && !to) {
|
|
770
|
+
upLines.push(` $table->dropSoftDeletes();`);
|
|
771
|
+
downLines.push(` $table->softDeletes();`);
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
const connection = options.connection ? `
|
|
776
|
+
protected $connection = '${options.connection}';
|
|
777
|
+
` : "";
|
|
778
|
+
return `<?php
|
|
779
|
+
|
|
780
|
+
use Illuminate\\Database\\Migrations\\Migration;
|
|
781
|
+
use Illuminate\\Database\\Schema\\Blueprint;
|
|
782
|
+
use Illuminate\\Support\\Facades\\Schema;
|
|
783
|
+
|
|
784
|
+
return new class extends Migration
|
|
785
|
+
{${connection}
|
|
786
|
+
/**
|
|
787
|
+
* Run the migrations.
|
|
788
|
+
*/
|
|
789
|
+
public function up(): void
|
|
790
|
+
{
|
|
791
|
+
Schema::table('${tableName}', function (Blueprint $table) {
|
|
792
|
+
${upLines.join("\n")}
|
|
793
|
+
});
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
/**
|
|
797
|
+
* Reverse the migrations.
|
|
798
|
+
*/
|
|
799
|
+
public function down(): void
|
|
800
|
+
{
|
|
801
|
+
Schema::table('${tableName}', function (Blueprint $table) {
|
|
802
|
+
${downLines.join("\n")}
|
|
803
|
+
});
|
|
804
|
+
}
|
|
805
|
+
};
|
|
806
|
+
`;
|
|
807
|
+
}
|
|
808
|
+
function generateAlterMigration(change, options = {}) {
|
|
809
|
+
if (change.changeType !== "modified") {
|
|
810
|
+
return null;
|
|
811
|
+
}
|
|
812
|
+
const hasChanges = change.columnChanges && change.columnChanges.length > 0 || change.indexChanges && change.indexChanges.length > 0 || change.optionChanges && (change.optionChanges.timestamps || change.optionChanges.softDelete);
|
|
813
|
+
if (!hasChanges) {
|
|
814
|
+
return null;
|
|
815
|
+
}
|
|
816
|
+
const tableName = toTableName(change.schemaName);
|
|
817
|
+
const timestamp = options.timestamp ?? generateTimestamp2();
|
|
818
|
+
const fileName = `${timestamp}_update_${tableName}_table.php`;
|
|
819
|
+
const content = generateAlterMigrationContent(tableName, change, options);
|
|
820
|
+
return {
|
|
821
|
+
fileName,
|
|
822
|
+
className: `Update${change.schemaName}Table`,
|
|
823
|
+
content,
|
|
824
|
+
tables: [tableName],
|
|
825
|
+
type: "alter"
|
|
826
|
+
};
|
|
827
|
+
}
|
|
828
|
+
function generateDropTableMigration(schemaName, options = {}) {
|
|
829
|
+
const tableName = toTableName(schemaName);
|
|
830
|
+
const timestamp = options.timestamp ?? generateTimestamp2();
|
|
831
|
+
const fileName = `${timestamp}_drop_${tableName}_table.php`;
|
|
832
|
+
const connection = options.connection ? `
|
|
833
|
+
protected $connection = '${options.connection}';
|
|
834
|
+
` : "";
|
|
835
|
+
const content = `<?php
|
|
836
|
+
|
|
837
|
+
use Illuminate\\Database\\Migrations\\Migration;
|
|
838
|
+
use Illuminate\\Database\\Schema\\Blueprint;
|
|
839
|
+
use Illuminate\\Support\\Facades\\Schema;
|
|
840
|
+
|
|
841
|
+
return new class extends Migration
|
|
842
|
+
{${connection}
|
|
843
|
+
/**
|
|
844
|
+
* Run the migrations.
|
|
845
|
+
*/
|
|
846
|
+
public function up(): void
|
|
847
|
+
{
|
|
848
|
+
Schema::dropIfExists('${tableName}');
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
/**
|
|
852
|
+
* Reverse the migrations.
|
|
853
|
+
*/
|
|
854
|
+
public function down(): void
|
|
855
|
+
{
|
|
856
|
+
// Cannot recreate table without full schema
|
|
857
|
+
// Consider restoring from backup if needed
|
|
858
|
+
}
|
|
859
|
+
};
|
|
860
|
+
`;
|
|
861
|
+
return {
|
|
862
|
+
fileName,
|
|
863
|
+
className: `Drop${schemaName}Table`,
|
|
864
|
+
content,
|
|
865
|
+
tables: [tableName],
|
|
866
|
+
type: "drop"
|
|
867
|
+
};
|
|
868
|
+
}
|
|
869
|
+
function generateMigrationsFromChanges(changes, options = {}) {
|
|
870
|
+
const migrations = [];
|
|
871
|
+
let timestampOffset = 0;
|
|
872
|
+
const getNextTimestamp = () => {
|
|
873
|
+
const ts = options.timestamp ?? generateTimestamp2();
|
|
874
|
+
const offset = timestampOffset++;
|
|
875
|
+
if (offset === 0) return ts;
|
|
876
|
+
const parts = ts.split("_");
|
|
877
|
+
if (parts.length >= 4) {
|
|
878
|
+
const timePart = parts[3] ?? "000000";
|
|
879
|
+
const secs = parseInt(timePart.substring(4, 6), 10) + offset;
|
|
880
|
+
const newSecs = String(secs % 60).padStart(2, "0");
|
|
881
|
+
parts[3] = timePart.substring(0, 4) + newSecs;
|
|
882
|
+
return parts.join("_");
|
|
883
|
+
}
|
|
884
|
+
return ts;
|
|
885
|
+
};
|
|
886
|
+
for (const change of changes) {
|
|
887
|
+
if (change.changeType === "modified") {
|
|
888
|
+
const migration = generateAlterMigration(change, {
|
|
889
|
+
...options,
|
|
890
|
+
timestamp: getNextTimestamp()
|
|
891
|
+
});
|
|
892
|
+
if (migration) {
|
|
893
|
+
migrations.push(migration);
|
|
894
|
+
}
|
|
895
|
+
} else if (change.changeType === "removed") {
|
|
896
|
+
migrations.push(
|
|
897
|
+
generateDropTableMigration(change.schemaName, {
|
|
898
|
+
...options,
|
|
899
|
+
timestamp: getNextTimestamp()
|
|
900
|
+
})
|
|
901
|
+
);
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
return migrations;
|
|
905
|
+
}
|
|
906
|
+
|
|
604
907
|
// src/typescript/interface-generator.ts
|
|
605
908
|
var TYPE_MAP = {
|
|
606
909
|
String: "string",
|
|
@@ -1014,7 +1317,7 @@ function laravelPlugin(options) {
|
|
|
1014
1317
|
const resolved = resolveOptions(options);
|
|
1015
1318
|
return {
|
|
1016
1319
|
name: "@famgia/omnify-laravel",
|
|
1017
|
-
version: "0.0.
|
|
1320
|
+
version: "0.0.7",
|
|
1018
1321
|
generators: [
|
|
1019
1322
|
// Laravel Migrations Generator
|
|
1020
1323
|
...resolved.generateMigrations ? [
|
|
@@ -1081,6 +1384,9 @@ export {
|
|
|
1081
1384
|
generateDropMigrationForTable,
|
|
1082
1385
|
formatMigrationFile,
|
|
1083
1386
|
getMigrationPath,
|
|
1387
|
+
generateAlterMigration,
|
|
1388
|
+
generateDropTableMigration,
|
|
1389
|
+
generateMigrationsFromChanges,
|
|
1084
1390
|
toPropertyName,
|
|
1085
1391
|
toInterfaceName,
|
|
1086
1392
|
getPropertyType,
|
|
@@ -1103,4 +1409,4 @@ export {
|
|
|
1103
1409
|
getTypeScriptPath,
|
|
1104
1410
|
laravelPlugin
|
|
1105
1411
|
};
|
|
1106
|
-
//# sourceMappingURL=chunk-
|
|
1412
|
+
//# sourceMappingURL=chunk-2XKSPWNJ.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 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 * 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 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 * 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?.options?.primaryKeyType ?? '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\n const pkType = (schema.options?.primaryKeyType ?? 'BigInt') as 'Int' | 'BigInt' | 'Uuid' | 'String';\n columns.push(generatePrimaryKeyColumn(pkType));\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\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 }\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 * 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 = (schema.options?.primaryKeyType ?? 'BigInt') as 'Int' | 'BigInt' | 'Uuid' | 'String';\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?.options?.primaryKeyType ?? 'BigInt') as 'Int' | 'BigInt' | 'Uuid' | 'String';\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 * @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 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 = `$table->${method}('${snakeColumn}')`;\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 = `$table->${method}('${snakeColumn}')`;\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 };\n\n const targetName = assocProp.target ?? 'unknown';\n\n switch (assocProp.relation) {\n case 'OneToOne':\n case 'ManyToOne':\n return targetName;\n case 'OneToMany':\n case 'ManyToMany':\n return `${targetName}[]`;\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 */\nexport function propertyToTSProperty(\n propertyName: string,\n property: PropertyDefinition,\n allSchemas: SchemaCollection,\n options: TypeScriptOptions = {}\n): TSProperty {\n const type = getPropertyType(property, allSchemas);\n const baseProp = property as { nullable?: boolean; displayName?: string };\n\n return {\n name: toPropertyName(propertyName),\n type,\n optional: baseProp.nullable ?? false,\n readonly: options.readonly ?? true,\n comment: baseProp.displayName,\n };\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\n const pkType = (schema.options?.primaryKeyType ?? '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 // Schema properties\n if (schema.properties) {\n for (const [propName, property] of Object.entries(schema.properties)) {\n properties.push(propertyToTSProperty(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"]}
|