@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/{chunk-XR2DTIIS.js → chunk-GDFAEEEG.js} +225 -3
- package/dist/chunk-GDFAEEEG.js.map +1 -0
- package/dist/index.cjs +229 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +72 -1
- package/dist/index.d.ts +72 -1
- package/dist/index.js +11 -1
- package/dist/plugin.cjs +92 -2
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.js +1 -1
- package/package.json +4 -4
- package/stubs/ai-guides/cursor/laravel-controller.mdc.stub +14 -0
- package/stubs/ai-guides/cursor/laravel.mdc.stub +15 -1
- package/stubs/ai-guides/cursor/omnify-migrations.mdc.stub +109 -0
- package/stubs/ai-guides/laravel/openapi.md.stub +42 -5
- package/dist/chunk-XR2DTIIS.js.map +0 -1
|
@@ -556,6 +556,9 @@ function extractManyToManyRelations(schema, allSchemas) {
|
|
|
556
556
|
if (assocProp.relation !== "ManyToMany") {
|
|
557
557
|
continue;
|
|
558
558
|
}
|
|
559
|
+
if (assocProp.mappedBy) {
|
|
560
|
+
continue;
|
|
561
|
+
}
|
|
559
562
|
const targetName = assocProp.target;
|
|
560
563
|
if (!targetName) {
|
|
561
564
|
continue;
|
|
@@ -570,6 +573,19 @@ function extractManyToManyRelations(schema, allSchemas) {
|
|
|
570
573
|
const pivotTableName = generatePivotTableName(sourceTable, targetTable, assocProp.joinTable);
|
|
571
574
|
const sourceColumn = sourceTable.replace(/ies$/, "y").replace(/s$/, "") + "_id";
|
|
572
575
|
const targetColumn = targetTable.replace(/ies$/, "y").replace(/s$/, "") + "_id";
|
|
576
|
+
const pivotFields = [];
|
|
577
|
+
if (assocProp.pivotFields) {
|
|
578
|
+
for (const [fieldName, fieldDef] of Object.entries(assocProp.pivotFields)) {
|
|
579
|
+
pivotFields.push({
|
|
580
|
+
name: toColumnName(fieldName),
|
|
581
|
+
type: fieldDef.type,
|
|
582
|
+
nullable: fieldDef.nullable,
|
|
583
|
+
default: fieldDef.default,
|
|
584
|
+
length: fieldDef.length,
|
|
585
|
+
unsigned: fieldDef.unsigned
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
}
|
|
573
589
|
pivotTables.push({
|
|
574
590
|
tableName: pivotTableName,
|
|
575
591
|
sourceTable,
|
|
@@ -579,11 +595,35 @@ function extractManyToManyRelations(schema, allSchemas) {
|
|
|
579
595
|
sourcePkType,
|
|
580
596
|
targetPkType,
|
|
581
597
|
onDelete: assocProp.onDelete,
|
|
582
|
-
onUpdate: assocProp.onUpdate
|
|
598
|
+
onUpdate: assocProp.onUpdate,
|
|
599
|
+
pivotFields: pivotFields.length > 0 ? pivotFields : void 0
|
|
583
600
|
});
|
|
584
601
|
}
|
|
585
602
|
return pivotTables;
|
|
586
603
|
}
|
|
604
|
+
function pivotFieldToColumn(field) {
|
|
605
|
+
const method = TYPE_METHOD_MAP[field.type] ?? "string";
|
|
606
|
+
const args = [field.name];
|
|
607
|
+
const modifiers = [];
|
|
608
|
+
if (method === "string" && field.length) {
|
|
609
|
+
args.push(field.length);
|
|
610
|
+
}
|
|
611
|
+
if (field.nullable) {
|
|
612
|
+
modifiers.push({ method: "nullable" });
|
|
613
|
+
}
|
|
614
|
+
if (field.default !== void 0 && field.default !== null) {
|
|
615
|
+
modifiers.push({ method: "default", args: [field.default] });
|
|
616
|
+
}
|
|
617
|
+
if (field.unsigned && (method === "tinyInteger" || method === "integer" || method === "bigInteger")) {
|
|
618
|
+
modifiers.push({ method: "unsigned" });
|
|
619
|
+
}
|
|
620
|
+
return {
|
|
621
|
+
name: field.name,
|
|
622
|
+
method,
|
|
623
|
+
args,
|
|
624
|
+
modifiers
|
|
625
|
+
};
|
|
626
|
+
}
|
|
587
627
|
function generatePivotTableBlueprint(pivot) {
|
|
588
628
|
const columns = [];
|
|
589
629
|
const foreignKeys = [];
|
|
@@ -612,6 +652,11 @@ function generatePivotTableBlueprint(pivot) {
|
|
|
612
652
|
args: [pivot.targetColumn],
|
|
613
653
|
modifiers: []
|
|
614
654
|
});
|
|
655
|
+
if (pivot.pivotFields && pivot.pivotFields.length > 0) {
|
|
656
|
+
for (const field of pivot.pivotFields) {
|
|
657
|
+
columns.push(pivotFieldToColumn(field));
|
|
658
|
+
}
|
|
659
|
+
}
|
|
615
660
|
columns.push(...generateTimestampColumns());
|
|
616
661
|
foreignKeys.push({
|
|
617
662
|
columns: [pivot.sourceColumn],
|
|
@@ -647,6 +692,126 @@ function generatePivotTableBlueprint(pivot) {
|
|
|
647
692
|
indexes
|
|
648
693
|
};
|
|
649
694
|
}
|
|
695
|
+
function extractMorphToManyRelations(schema, allSchemas) {
|
|
696
|
+
const morphPivotTables = [];
|
|
697
|
+
if (!schema.properties) {
|
|
698
|
+
return morphPivotTables;
|
|
699
|
+
}
|
|
700
|
+
for (const [propName, property] of Object.entries(schema.properties)) {
|
|
701
|
+
if (property.type !== "Association") {
|
|
702
|
+
continue;
|
|
703
|
+
}
|
|
704
|
+
const assocProp = property;
|
|
705
|
+
if (assocProp.relation !== "MorphToMany") {
|
|
706
|
+
continue;
|
|
707
|
+
}
|
|
708
|
+
const targetName = assocProp.target;
|
|
709
|
+
if (!targetName) {
|
|
710
|
+
continue;
|
|
711
|
+
}
|
|
712
|
+
const targetSchema = allSchemas[targetName];
|
|
713
|
+
const targetTable = toTableName(targetName);
|
|
714
|
+
const targetPkType = targetSchema ? getIdType(targetSchema) : "BigInt";
|
|
715
|
+
const isOwningSide = assocProp.owning ?? schema.name < targetName;
|
|
716
|
+
if (!isOwningSide) {
|
|
717
|
+
continue;
|
|
718
|
+
}
|
|
719
|
+
const morphTargets = [];
|
|
720
|
+
morphTargets.push(schema.name);
|
|
721
|
+
for (const [otherName, otherSchema] of Object.entries(allSchemas)) {
|
|
722
|
+
if (otherName === schema.name) continue;
|
|
723
|
+
if (!otherSchema.properties) continue;
|
|
724
|
+
for (const otherProp of Object.values(otherSchema.properties)) {
|
|
725
|
+
if (otherProp.type !== "Association") continue;
|
|
726
|
+
const otherAssoc = otherProp;
|
|
727
|
+
if (otherAssoc.relation === "MorphToMany" && otherAssoc.target === targetName) {
|
|
728
|
+
if (!morphTargets.includes(otherName)) {
|
|
729
|
+
morphTargets.push(otherName);
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
const defaultTableName = targetTable.replace(/s$/, "") + "ables";
|
|
735
|
+
const tableName = assocProp.joinTable ?? defaultTableName;
|
|
736
|
+
const targetColumn = targetTable.replace(/ies$/, "y").replace(/s$/, "") + "_id";
|
|
737
|
+
const morphName = propName.replace(/s$/, "") + "able";
|
|
738
|
+
morphPivotTables.push({
|
|
739
|
+
tableName,
|
|
740
|
+
targetTable,
|
|
741
|
+
targetColumn,
|
|
742
|
+
targetPkType,
|
|
743
|
+
morphName,
|
|
744
|
+
morphTargets,
|
|
745
|
+
onDelete: assocProp.onDelete,
|
|
746
|
+
onUpdate: assocProp.onUpdate
|
|
747
|
+
});
|
|
748
|
+
}
|
|
749
|
+
return morphPivotTables;
|
|
750
|
+
}
|
|
751
|
+
function generateMorphToManyPivotBlueprint(pivot) {
|
|
752
|
+
const columns = [];
|
|
753
|
+
const foreignKeys = [];
|
|
754
|
+
const indexes = [];
|
|
755
|
+
const getMethodForPkType = (pkType) => {
|
|
756
|
+
switch (pkType) {
|
|
757
|
+
case "Int":
|
|
758
|
+
return "unsignedInteger";
|
|
759
|
+
case "Uuid":
|
|
760
|
+
return "uuid";
|
|
761
|
+
case "String":
|
|
762
|
+
return "string";
|
|
763
|
+
default:
|
|
764
|
+
return "unsignedBigInteger";
|
|
765
|
+
}
|
|
766
|
+
};
|
|
767
|
+
columns.push({
|
|
768
|
+
name: pivot.targetColumn,
|
|
769
|
+
method: getMethodForPkType(pivot.targetPkType),
|
|
770
|
+
args: [pivot.targetColumn],
|
|
771
|
+
modifiers: []
|
|
772
|
+
});
|
|
773
|
+
const typeColumnName = `${pivot.morphName}_type`;
|
|
774
|
+
columns.push({
|
|
775
|
+
name: typeColumnName,
|
|
776
|
+
method: "enum",
|
|
777
|
+
args: [typeColumnName, pivot.morphTargets],
|
|
778
|
+
modifiers: []
|
|
779
|
+
});
|
|
780
|
+
const idColumnName = `${pivot.morphName}_id`;
|
|
781
|
+
columns.push({
|
|
782
|
+
name: idColumnName,
|
|
783
|
+
method: "unsignedBigInteger",
|
|
784
|
+
// Default to BigInt for polymorphic IDs
|
|
785
|
+
args: [idColumnName],
|
|
786
|
+
modifiers: []
|
|
787
|
+
});
|
|
788
|
+
foreignKeys.push({
|
|
789
|
+
columns: [pivot.targetColumn],
|
|
790
|
+
references: "id",
|
|
791
|
+
on: [pivot.targetTable],
|
|
792
|
+
onDelete: pivot.onDelete ?? "cascade",
|
|
793
|
+
onUpdate: pivot.onUpdate ?? "cascade"
|
|
794
|
+
});
|
|
795
|
+
indexes.push({
|
|
796
|
+
columns: [pivot.targetColumn, typeColumnName, idColumnName],
|
|
797
|
+
unique: true
|
|
798
|
+
});
|
|
799
|
+
indexes.push({
|
|
800
|
+
columns: [typeColumnName, idColumnName],
|
|
801
|
+
unique: false
|
|
802
|
+
});
|
|
803
|
+
indexes.push({
|
|
804
|
+
columns: [pivot.targetColumn],
|
|
805
|
+
unique: false
|
|
806
|
+
});
|
|
807
|
+
return {
|
|
808
|
+
tableName: pivot.tableName,
|
|
809
|
+
columns,
|
|
810
|
+
primaryKey: [pivot.targetColumn, typeColumnName, idColumnName],
|
|
811
|
+
foreignKeys,
|
|
812
|
+
indexes
|
|
813
|
+
};
|
|
814
|
+
}
|
|
650
815
|
|
|
651
816
|
// src/migration/generator.ts
|
|
652
817
|
function generateTimestamp() {
|
|
@@ -713,6 +878,16 @@ function generateCreateMigration(blueprint, options = {}) {
|
|
|
713
878
|
const indexContent = renderIndexes(blueprint);
|
|
714
879
|
const content = `<?php
|
|
715
880
|
|
|
881
|
+
/**
|
|
882
|
+
* DO NOT EDIT - This file is auto-generated by Omnify.
|
|
883
|
+
* Any changes will be overwritten on next generation.
|
|
884
|
+
*
|
|
885
|
+
* To modify the schema, edit the corresponding YAML file in schemas/
|
|
886
|
+
* and run: npx omnify generate
|
|
887
|
+
*
|
|
888
|
+
* @generated by @famgia/omnify-laravel
|
|
889
|
+
*/
|
|
890
|
+
|
|
716
891
|
use Illuminate\\Database\\Migrations\\Migration;
|
|
717
892
|
use Illuminate\\Database\\Schema\\Blueprint;
|
|
718
893
|
use Illuminate\\Support\\Facades\\Schema;
|
|
@@ -754,6 +929,13 @@ function generateDropMigration(tableName, options = {}) {
|
|
|
754
929
|
` : "";
|
|
755
930
|
const content = `<?php
|
|
756
931
|
|
|
932
|
+
/**
|
|
933
|
+
* DO NOT EDIT - This file is auto-generated by Omnify.
|
|
934
|
+
* Any changes will be overwritten on next generation.
|
|
935
|
+
*
|
|
936
|
+
* @generated by @famgia/omnify-laravel
|
|
937
|
+
*/
|
|
938
|
+
|
|
757
939
|
use Illuminate\\Database\\Migrations\\Migration;
|
|
758
940
|
use Illuminate\\Database\\Schema\\Blueprint;
|
|
759
941
|
use Illuminate\\Support\\Facades\\Schema;
|
|
@@ -1066,6 +1248,16 @@ function generateAlterMigrationContent(tableName, change, options = {}) {
|
|
|
1066
1248
|
` : "";
|
|
1067
1249
|
return `<?php
|
|
1068
1250
|
|
|
1251
|
+
/**
|
|
1252
|
+
* DO NOT EDIT - This file is auto-generated by Omnify.
|
|
1253
|
+
* Any changes will be overwritten on next generation.
|
|
1254
|
+
*
|
|
1255
|
+
* To modify the schema, edit the corresponding YAML file in schemas/
|
|
1256
|
+
* and run: npx omnify generate
|
|
1257
|
+
*
|
|
1258
|
+
* @generated by @famgia/omnify-laravel
|
|
1259
|
+
*/
|
|
1260
|
+
|
|
1069
1261
|
use Illuminate\\Database\\Migrations\\Migration;
|
|
1070
1262
|
use Illuminate\\Database\\Schema\\Blueprint;
|
|
1071
1263
|
use Illuminate\\Support\\Facades\\Schema;
|
|
@@ -1123,6 +1315,13 @@ function generateDropTableMigration(schemaName, options = {}) {
|
|
|
1123
1315
|
` : "";
|
|
1124
1316
|
const content = `<?php
|
|
1125
1317
|
|
|
1318
|
+
/**
|
|
1319
|
+
* DO NOT EDIT - This file is auto-generated by Omnify.
|
|
1320
|
+
* Any changes will be overwritten on next generation.
|
|
1321
|
+
*
|
|
1322
|
+
* @generated by @famgia/omnify-laravel
|
|
1323
|
+
*/
|
|
1324
|
+
|
|
1126
1325
|
use Illuminate\\Database\\Migrations\\Migration;
|
|
1127
1326
|
use Illuminate\\Database\\Schema\\Blueprint;
|
|
1128
1327
|
use Illuminate\\Support\\Facades\\Schema;
|
|
@@ -1600,12 +1799,30 @@ function generateRelation(propName, assoc, schema, schemas, options) {
|
|
|
1600
1799
|
}
|
|
1601
1800
|
case "ManyToMany": {
|
|
1602
1801
|
const pivotTable = assoc.joinTable ?? `${toSnakeCase(propName)}_pivot`;
|
|
1802
|
+
let pivotFieldNames = [];
|
|
1803
|
+
if (assoc.pivotFields && Object.keys(assoc.pivotFields).length > 0) {
|
|
1804
|
+
pivotFieldNames = Object.keys(assoc.pivotFields).map((f) => toSnakeCase(f));
|
|
1805
|
+
} else if (assoc.mappedBy && assoc.target) {
|
|
1806
|
+
const targetSchema = schemas[assoc.target];
|
|
1807
|
+
if (targetSchema?.properties) {
|
|
1808
|
+
const owningProp = targetSchema.properties[assoc.mappedBy];
|
|
1809
|
+
if (owningProp?.type === "Association") {
|
|
1810
|
+
const owningAssoc = owningProp;
|
|
1811
|
+
if (owningAssoc.pivotFields && Object.keys(owningAssoc.pivotFields).length > 0) {
|
|
1812
|
+
pivotFieldNames = Object.keys(owningAssoc.pivotFields).map((f) => toSnakeCase(f));
|
|
1813
|
+
}
|
|
1814
|
+
}
|
|
1815
|
+
}
|
|
1816
|
+
}
|
|
1817
|
+
const pivotFieldsCode = pivotFieldNames.length > 0 ? pivotFieldNames.map((f) => `'${f}'`).join(", ") : null;
|
|
1818
|
+
const withPivotLine = pivotFieldsCode ? `
|
|
1819
|
+
->withPivot(${pivotFieldsCode})` : "";
|
|
1603
1820
|
return ` /**
|
|
1604
1821
|
* The ${propName} that belong to this model.
|
|
1605
1822
|
*/
|
|
1606
1823
|
public function ${methodName}(): BelongsToMany
|
|
1607
1824
|
{
|
|
1608
|
-
return $this->belongsToMany(${targetClass}::class, '${pivotTable}')
|
|
1825
|
+
return $this->belongsToMany(${targetClass}::class, '${pivotTable}')${withPivotLine}
|
|
1609
1826
|
->withTimestamps();
|
|
1610
1827
|
}`;
|
|
1611
1828
|
}
|
|
@@ -4578,6 +4795,11 @@ export {
|
|
|
4578
4795
|
formatColumnMethod,
|
|
4579
4796
|
formatForeignKey,
|
|
4580
4797
|
formatIndex,
|
|
4798
|
+
generatePivotTableName,
|
|
4799
|
+
extractManyToManyRelations,
|
|
4800
|
+
generatePivotTableBlueprint,
|
|
4801
|
+
extractMorphToManyRelations,
|
|
4802
|
+
generateMorphToManyPivotBlueprint,
|
|
4581
4803
|
generateMigrations,
|
|
4582
4804
|
generateMigrationFromSchema,
|
|
4583
4805
|
generateDropMigrationForTable,
|
|
@@ -4595,4 +4817,4 @@ export {
|
|
|
4595
4817
|
shouldGenerateAIGuides,
|
|
4596
4818
|
laravelPlugin
|
|
4597
4819
|
};
|
|
4598
|
-
//# sourceMappingURL=chunk-
|
|
4820
|
+
//# sourceMappingURL=chunk-GDFAEEEG.js.map
|