@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
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,
|