@famgia/omnify-laravel 0.0.106 → 0.0.108

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/index.cjs CHANGED
@@ -20,6 +20,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ extractManyToManyRelations: () => extractManyToManyRelations,
24
+ extractMorphToManyRelations: () => extractMorphToManyRelations,
23
25
  formatColumnMethod: () => formatColumnMethod,
24
26
  formatForeignKey: () => formatForeignKey,
25
27
  formatIndex: () => formatIndex,
@@ -34,6 +36,9 @@ __export(index_exports, {
34
36
  generateMigrations: () => generateMigrations,
35
37
  generateMigrationsFromChanges: () => generateMigrationsFromChanges,
36
38
  generateModels: () => generateModels,
39
+ generateMorphToManyPivotBlueprint: () => generateMorphToManyPivotBlueprint,
40
+ generatePivotTableBlueprint: () => generatePivotTableBlueprint,
41
+ generatePivotTableName: () => generatePivotTableName,
37
42
  generatePrimaryKeyColumn: () => generatePrimaryKeyColumn,
38
43
  generateProviderRegistration: () => generateProviderRegistration,
39
44
  generateSoftDeleteColumn: () => generateSoftDeleteColumn,
@@ -604,6 +609,9 @@ function extractManyToManyRelations(schema, allSchemas) {
604
609
  if (assocProp.relation !== "ManyToMany") {
605
610
  continue;
606
611
  }
612
+ if (assocProp.mappedBy) {
613
+ continue;
614
+ }
607
615
  const targetName = assocProp.target;
608
616
  if (!targetName) {
609
617
  continue;
@@ -618,6 +626,19 @@ function extractManyToManyRelations(schema, allSchemas) {
618
626
  const pivotTableName = generatePivotTableName(sourceTable, targetTable, assocProp.joinTable);
619
627
  const sourceColumn = sourceTable.replace(/ies$/, "y").replace(/s$/, "") + "_id";
620
628
  const targetColumn = targetTable.replace(/ies$/, "y").replace(/s$/, "") + "_id";
629
+ const pivotFields = [];
630
+ if (assocProp.pivotFields) {
631
+ for (const [fieldName, fieldDef] of Object.entries(assocProp.pivotFields)) {
632
+ pivotFields.push({
633
+ name: toColumnName(fieldName),
634
+ type: fieldDef.type,
635
+ nullable: fieldDef.nullable,
636
+ default: fieldDef.default,
637
+ length: fieldDef.length,
638
+ unsigned: fieldDef.unsigned
639
+ });
640
+ }
641
+ }
621
642
  pivotTables.push({
622
643
  tableName: pivotTableName,
623
644
  sourceTable,
@@ -627,11 +648,35 @@ function extractManyToManyRelations(schema, allSchemas) {
627
648
  sourcePkType,
628
649
  targetPkType,
629
650
  onDelete: assocProp.onDelete,
630
- onUpdate: assocProp.onUpdate
651
+ onUpdate: assocProp.onUpdate,
652
+ pivotFields: pivotFields.length > 0 ? pivotFields : void 0
631
653
  });
632
654
  }
633
655
  return pivotTables;
634
656
  }
657
+ function pivotFieldToColumn(field) {
658
+ const method = TYPE_METHOD_MAP[field.type] ?? "string";
659
+ const args = [field.name];
660
+ const modifiers = [];
661
+ if (method === "string" && field.length) {
662
+ args.push(field.length);
663
+ }
664
+ if (field.nullable) {
665
+ modifiers.push({ method: "nullable" });
666
+ }
667
+ if (field.default !== void 0 && field.default !== null) {
668
+ modifiers.push({ method: "default", args: [field.default] });
669
+ }
670
+ if (field.unsigned && (method === "tinyInteger" || method === "integer" || method === "bigInteger")) {
671
+ modifiers.push({ method: "unsigned" });
672
+ }
673
+ return {
674
+ name: field.name,
675
+ method,
676
+ args,
677
+ modifiers
678
+ };
679
+ }
635
680
  function generatePivotTableBlueprint(pivot) {
636
681
  const columns = [];
637
682
  const foreignKeys = [];
@@ -660,6 +705,11 @@ function generatePivotTableBlueprint(pivot) {
660
705
  args: [pivot.targetColumn],
661
706
  modifiers: []
662
707
  });
708
+ if (pivot.pivotFields && pivot.pivotFields.length > 0) {
709
+ for (const field of pivot.pivotFields) {
710
+ columns.push(pivotFieldToColumn(field));
711
+ }
712
+ }
663
713
  columns.push(...generateTimestampColumns());
664
714
  foreignKeys.push({
665
715
  columns: [pivot.sourceColumn],
@@ -695,6 +745,126 @@ function generatePivotTableBlueprint(pivot) {
695
745
  indexes
696
746
  };
697
747
  }
748
+ function extractMorphToManyRelations(schema, allSchemas) {
749
+ const morphPivotTables = [];
750
+ if (!schema.properties) {
751
+ return morphPivotTables;
752
+ }
753
+ for (const [propName, property] of Object.entries(schema.properties)) {
754
+ if (property.type !== "Association") {
755
+ continue;
756
+ }
757
+ const assocProp = property;
758
+ if (assocProp.relation !== "MorphToMany") {
759
+ continue;
760
+ }
761
+ const targetName = assocProp.target;
762
+ if (!targetName) {
763
+ continue;
764
+ }
765
+ const targetSchema = allSchemas[targetName];
766
+ const targetTable = toTableName(targetName);
767
+ const targetPkType = targetSchema ? getIdType(targetSchema) : "BigInt";
768
+ const isOwningSide = assocProp.owning ?? schema.name < targetName;
769
+ if (!isOwningSide) {
770
+ continue;
771
+ }
772
+ const morphTargets = [];
773
+ morphTargets.push(schema.name);
774
+ for (const [otherName, otherSchema] of Object.entries(allSchemas)) {
775
+ if (otherName === schema.name) continue;
776
+ if (!otherSchema.properties) continue;
777
+ for (const otherProp of Object.values(otherSchema.properties)) {
778
+ if (otherProp.type !== "Association") continue;
779
+ const otherAssoc = otherProp;
780
+ if (otherAssoc.relation === "MorphToMany" && otherAssoc.target === targetName) {
781
+ if (!morphTargets.includes(otherName)) {
782
+ morphTargets.push(otherName);
783
+ }
784
+ }
785
+ }
786
+ }
787
+ const defaultTableName = targetTable.replace(/s$/, "") + "ables";
788
+ const tableName = assocProp.joinTable ?? defaultTableName;
789
+ const targetColumn = targetTable.replace(/ies$/, "y").replace(/s$/, "") + "_id";
790
+ const morphName = propName.replace(/s$/, "") + "able";
791
+ morphPivotTables.push({
792
+ tableName,
793
+ targetTable,
794
+ targetColumn,
795
+ targetPkType,
796
+ morphName,
797
+ morphTargets,
798
+ onDelete: assocProp.onDelete,
799
+ onUpdate: assocProp.onUpdate
800
+ });
801
+ }
802
+ return morphPivotTables;
803
+ }
804
+ function generateMorphToManyPivotBlueprint(pivot) {
805
+ const columns = [];
806
+ const foreignKeys = [];
807
+ const indexes = [];
808
+ const getMethodForPkType = (pkType) => {
809
+ switch (pkType) {
810
+ case "Int":
811
+ return "unsignedInteger";
812
+ case "Uuid":
813
+ return "uuid";
814
+ case "String":
815
+ return "string";
816
+ default:
817
+ return "unsignedBigInteger";
818
+ }
819
+ };
820
+ columns.push({
821
+ name: pivot.targetColumn,
822
+ method: getMethodForPkType(pivot.targetPkType),
823
+ args: [pivot.targetColumn],
824
+ modifiers: []
825
+ });
826
+ const typeColumnName = `${pivot.morphName}_type`;
827
+ columns.push({
828
+ name: typeColumnName,
829
+ method: "enum",
830
+ args: [typeColumnName, pivot.morphTargets],
831
+ modifiers: []
832
+ });
833
+ const idColumnName = `${pivot.morphName}_id`;
834
+ columns.push({
835
+ name: idColumnName,
836
+ method: "unsignedBigInteger",
837
+ // Default to BigInt for polymorphic IDs
838
+ args: [idColumnName],
839
+ modifiers: []
840
+ });
841
+ foreignKeys.push({
842
+ columns: [pivot.targetColumn],
843
+ references: "id",
844
+ on: [pivot.targetTable],
845
+ onDelete: pivot.onDelete ?? "cascade",
846
+ onUpdate: pivot.onUpdate ?? "cascade"
847
+ });
848
+ indexes.push({
849
+ columns: [pivot.targetColumn, typeColumnName, idColumnName],
850
+ unique: true
851
+ });
852
+ indexes.push({
853
+ columns: [typeColumnName, idColumnName],
854
+ unique: false
855
+ });
856
+ indexes.push({
857
+ columns: [pivot.targetColumn],
858
+ unique: false
859
+ });
860
+ return {
861
+ tableName: pivot.tableName,
862
+ columns,
863
+ primaryKey: [pivot.targetColumn, typeColumnName, idColumnName],
864
+ foreignKeys,
865
+ indexes
866
+ };
867
+ }
698
868
 
699
869
  // src/migration/generator.ts
700
870
  function generateTimestamp() {
@@ -761,6 +931,16 @@ function generateCreateMigration(blueprint, options = {}) {
761
931
  const indexContent = renderIndexes(blueprint);
762
932
  const content = `<?php
763
933
 
934
+ /**
935
+ * DO NOT EDIT - This file is auto-generated by Omnify.
936
+ * Any changes will be overwritten on next generation.
937
+ *
938
+ * To modify the schema, edit the corresponding YAML file in schemas/
939
+ * and run: npx omnify generate
940
+ *
941
+ * @generated by @famgia/omnify-laravel
942
+ */
943
+
764
944
  use Illuminate\\Database\\Migrations\\Migration;
765
945
  use Illuminate\\Database\\Schema\\Blueprint;
766
946
  use Illuminate\\Support\\Facades\\Schema;
@@ -802,6 +982,13 @@ function generateDropMigration(tableName, options = {}) {
802
982
  ` : "";
803
983
  const content = `<?php
804
984
 
985
+ /**
986
+ * DO NOT EDIT - This file is auto-generated by Omnify.
987
+ * Any changes will be overwritten on next generation.
988
+ *
989
+ * @generated by @famgia/omnify-laravel
990
+ */
991
+
805
992
  use Illuminate\\Database\\Migrations\\Migration;
806
993
  use Illuminate\\Database\\Schema\\Blueprint;
807
994
  use Illuminate\\Support\\Facades\\Schema;
@@ -1114,6 +1301,16 @@ function generateAlterMigrationContent(tableName, change, options = {}) {
1114
1301
  ` : "";
1115
1302
  return `<?php
1116
1303
 
1304
+ /**
1305
+ * DO NOT EDIT - This file is auto-generated by Omnify.
1306
+ * Any changes will be overwritten on next generation.
1307
+ *
1308
+ * To modify the schema, edit the corresponding YAML file in schemas/
1309
+ * and run: npx omnify generate
1310
+ *
1311
+ * @generated by @famgia/omnify-laravel
1312
+ */
1313
+
1117
1314
  use Illuminate\\Database\\Migrations\\Migration;
1118
1315
  use Illuminate\\Database\\Schema\\Blueprint;
1119
1316
  use Illuminate\\Support\\Facades\\Schema;
@@ -1171,6 +1368,13 @@ function generateDropTableMigration(schemaName, options = {}) {
1171
1368
  ` : "";
1172
1369
  const content = `<?php
1173
1370
 
1371
+ /**
1372
+ * DO NOT EDIT - This file is auto-generated by Omnify.
1373
+ * Any changes will be overwritten on next generation.
1374
+ *
1375
+ * @generated by @famgia/omnify-laravel
1376
+ */
1377
+
1174
1378
  use Illuminate\\Database\\Migrations\\Migration;
1175
1379
  use Illuminate\\Database\\Schema\\Blueprint;
1176
1380
  use Illuminate\\Support\\Facades\\Schema;
@@ -1648,12 +1852,30 @@ function generateRelation(propName, assoc, schema, schemas, options) {
1648
1852
  }
1649
1853
  case "ManyToMany": {
1650
1854
  const pivotTable = assoc.joinTable ?? `${toSnakeCase(propName)}_pivot`;
1855
+ let pivotFieldNames = [];
1856
+ if (assoc.pivotFields && Object.keys(assoc.pivotFields).length > 0) {
1857
+ pivotFieldNames = Object.keys(assoc.pivotFields).map((f) => toSnakeCase(f));
1858
+ } else if (assoc.mappedBy && assoc.target) {
1859
+ const targetSchema = schemas[assoc.target];
1860
+ if (targetSchema?.properties) {
1861
+ const owningProp = targetSchema.properties[assoc.mappedBy];
1862
+ if (owningProp?.type === "Association") {
1863
+ const owningAssoc = owningProp;
1864
+ if (owningAssoc.pivotFields && Object.keys(owningAssoc.pivotFields).length > 0) {
1865
+ pivotFieldNames = Object.keys(owningAssoc.pivotFields).map((f) => toSnakeCase(f));
1866
+ }
1867
+ }
1868
+ }
1869
+ }
1870
+ const pivotFieldsCode = pivotFieldNames.length > 0 ? pivotFieldNames.map((f) => `'${f}'`).join(", ") : null;
1871
+ const withPivotLine = pivotFieldsCode ? `
1872
+ ->withPivot(${pivotFieldsCode})` : "";
1651
1873
  return ` /**
1652
1874
  * The ${propName} that belong to this model.
1653
1875
  */
1654
1876
  public function ${methodName}(): BelongsToMany
1655
1877
  {
1656
- return $this->belongsToMany(${targetClass}::class, '${pivotTable}')
1878
+ return $this->belongsToMany(${targetClass}::class, '${pivotTable}')${withPivotLine}
1657
1879
  ->withTimestamps();
1658
1880
  }`;
1659
1881
  }
@@ -4620,6 +4842,8 @@ function laravelPlugin(options) {
4620
4842
  }
4621
4843
  // Annotate the CommonJS export names for ESM import in node:
4622
4844
  0 && (module.exports = {
4845
+ extractManyToManyRelations,
4846
+ extractMorphToManyRelations,
4623
4847
  formatColumnMethod,
4624
4848
  formatForeignKey,
4625
4849
  formatIndex,
@@ -4634,6 +4858,9 @@ function laravelPlugin(options) {
4634
4858
  generateMigrations,
4635
4859
  generateMigrationsFromChanges,
4636
4860
  generateModels,
4861
+ generateMorphToManyPivotBlueprint,
4862
+ generatePivotTableBlueprint,
4863
+ generatePivotTableName,
4637
4864
  generatePrimaryKeyColumn,
4638
4865
  generateProviderRegistration,
4639
4866
  generateSoftDeleteColumn,