@famgia/omnify-laravel 0.0.106 → 0.0.107

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() {
@@ -1648,12 +1818,30 @@ function generateRelation(propName, assoc, schema, schemas, options) {
1648
1818
  }
1649
1819
  case "ManyToMany": {
1650
1820
  const pivotTable = assoc.joinTable ?? `${toSnakeCase(propName)}_pivot`;
1821
+ let pivotFieldNames = [];
1822
+ if (assoc.pivotFields && Object.keys(assoc.pivotFields).length > 0) {
1823
+ pivotFieldNames = Object.keys(assoc.pivotFields).map((f) => toSnakeCase(f));
1824
+ } else if (assoc.mappedBy && assoc.target) {
1825
+ const targetSchema = schemas[assoc.target];
1826
+ if (targetSchema?.properties) {
1827
+ const owningProp = targetSchema.properties[assoc.mappedBy];
1828
+ if (owningProp?.type === "Association") {
1829
+ const owningAssoc = owningProp;
1830
+ if (owningAssoc.pivotFields && Object.keys(owningAssoc.pivotFields).length > 0) {
1831
+ pivotFieldNames = Object.keys(owningAssoc.pivotFields).map((f) => toSnakeCase(f));
1832
+ }
1833
+ }
1834
+ }
1835
+ }
1836
+ const pivotFieldsCode = pivotFieldNames.length > 0 ? pivotFieldNames.map((f) => `'${f}'`).join(", ") : null;
1837
+ const withPivotLine = pivotFieldsCode ? `
1838
+ ->withPivot(${pivotFieldsCode})` : "";
1651
1839
  return ` /**
1652
1840
  * The ${propName} that belong to this model.
1653
1841
  */
1654
1842
  public function ${methodName}(): BelongsToMany
1655
1843
  {
1656
- return $this->belongsToMany(${targetClass}::class, '${pivotTable}')
1844
+ return $this->belongsToMany(${targetClass}::class, '${pivotTable}')${withPivotLine}
1657
1845
  ->withTimestamps();
1658
1846
  }`;
1659
1847
  }
@@ -4620,6 +4808,8 @@ function laravelPlugin(options) {
4620
4808
  }
4621
4809
  // Annotate the CommonJS export names for ESM import in node:
4622
4810
  0 && (module.exports = {
4811
+ extractManyToManyRelations,
4812
+ extractMorphToManyRelations,
4623
4813
  formatColumnMethod,
4624
4814
  formatForeignKey,
4625
4815
  formatIndex,
@@ -4634,6 +4824,9 @@ function laravelPlugin(options) {
4634
4824
  generateMigrations,
4635
4825
  generateMigrationsFromChanges,
4636
4826
  generateModels,
4827
+ generateMorphToManyPivotBlueprint,
4828
+ generatePivotTableBlueprint,
4829
+ generatePivotTableName,
4637
4830
  generatePrimaryKeyColumn,
4638
4831
  generateProviderRegistration,
4639
4832
  generateSoftDeleteColumn,