prisma-laravel-migrate 0.1.2 → 0.1.4
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/utils/sort.js +77 -46
- package/package.json +1 -1
package/dist/utils/sort.js
CHANGED
|
@@ -1,78 +1,109 @@
|
|
|
1
|
+
var GenTarget;
|
|
2
|
+
(function (GenTarget) {
|
|
3
|
+
GenTarget[GenTarget["None"] = 0] = "None";
|
|
4
|
+
GenTarget[GenTarget["Model"] = 1] = "Model";
|
|
5
|
+
GenTarget[GenTarget["Migrator"] = 2] = "Migrator";
|
|
6
|
+
})(GenTarget || (GenTarget = {}));
|
|
7
|
+
// normalize anything like: true | 'migrator' | 'both' | flags | { migrator?: boolean }
|
|
8
|
+
function isLocalForMigrator(x) {
|
|
9
|
+
const v = x?.local;
|
|
10
|
+
if (!v)
|
|
11
|
+
return false;
|
|
12
|
+
if (v === true)
|
|
13
|
+
return true; // blanket local
|
|
14
|
+
if (typeof v === "string") {
|
|
15
|
+
const s = v.toLowerCase();
|
|
16
|
+
return s === "migrator" || s === "both" || s === "all" || s === "*";
|
|
17
|
+
}
|
|
18
|
+
if (typeof v === "number")
|
|
19
|
+
return (v & GenTarget.Migrator) !== 0;
|
|
20
|
+
if (typeof v === "object")
|
|
21
|
+
return !!v.migrator || !!v.both || !!v.all;
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
1
24
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* @throws If there’s a cycle in the relationships
|
|
25
|
+
* Topologically sort migrations so FK parents come before children.
|
|
26
|
+
* - Skips migrations marked local for migrator.
|
|
27
|
+
* - Skips FK edges from defs marked local for migrator.
|
|
28
|
+
* - Considers only owning-side FKs.
|
|
29
|
+
* - Dedupes edges; throws on cycles.
|
|
8
30
|
*/
|
|
9
|
-
export function sortMigrations(
|
|
10
|
-
//
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
// 2)
|
|
31
|
+
export function sortMigrations(input) {
|
|
32
|
+
// 0) keep only migrations that will actually emit for migrator
|
|
33
|
+
const migrations = (input || []).filter(m => !isLocalForMigrator(m));
|
|
34
|
+
// 1) table -> migration
|
|
35
|
+
const migMap = new Map(migrations.map(m => [m.tableName, m]));
|
|
36
|
+
// 2) child -> Set<parent>
|
|
15
37
|
const rawDeps = new Map();
|
|
16
|
-
for (const { tableName } of migrations)
|
|
38
|
+
for (const { tableName } of migrations)
|
|
17
39
|
rawDeps.set(tableName, new Set());
|
|
18
|
-
}
|
|
19
40
|
for (const m of migrations) {
|
|
20
|
-
for (const def of m.definitions) {
|
|
21
|
-
//
|
|
22
|
-
|
|
23
|
-
// - this field is a scalar FK column (def.kind === 'scalar')
|
|
24
|
-
// - it's the owning side (relationFromFields non-empty)
|
|
25
|
-
if (!def.relationship ||
|
|
26
|
-
!def.relationship.local ||
|
|
27
|
-
!def.relationFromFields ||
|
|
28
|
-
def.relationFromFields.length === 0) {
|
|
41
|
+
for (const def of m.definitions ?? []) {
|
|
42
|
+
// skip defs silenced for migrator
|
|
43
|
+
if (isLocalForMigrator(def))
|
|
29
44
|
continue;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
45
|
+
const rel = def.relationship;
|
|
46
|
+
if (!rel)
|
|
47
|
+
continue;
|
|
48
|
+
// Owning side? prefer relationship.fields; fallback to relationFromFields if carried through
|
|
49
|
+
const ownFields = Array.isArray(rel.fields) ? rel.fields :
|
|
50
|
+
Array.isArray(def.relationFromFields) ? def.relationFromFields :
|
|
51
|
+
[];
|
|
52
|
+
if (ownFields.length === 0)
|
|
53
|
+
continue;
|
|
54
|
+
// Parent table: allow several keys to be safe
|
|
55
|
+
const parent = rel.on || rel.table || rel.target;
|
|
56
|
+
if (!parent)
|
|
57
|
+
continue;
|
|
58
|
+
if (parent === m.tableName)
|
|
59
|
+
continue; // self-edge ignored
|
|
60
|
+
if (!migMap.has(parent))
|
|
61
|
+
continue; // external table not in this batch
|
|
62
|
+
rawDeps.get(m.tableName).add(parent); // Set dedupes edges
|
|
35
63
|
}
|
|
36
64
|
}
|
|
37
|
-
// 3) Build adjacency
|
|
65
|
+
// 3) Build adjacency & in-degree
|
|
38
66
|
const adj = new Map();
|
|
39
67
|
const inDegree = new Map();
|
|
40
68
|
for (const tbl of migMap.keys()) {
|
|
41
|
-
adj.set(tbl,
|
|
69
|
+
adj.set(tbl, new Set());
|
|
42
70
|
inDegree.set(tbl, 0);
|
|
43
71
|
}
|
|
44
72
|
for (const [child, parents] of rawDeps) {
|
|
45
73
|
for (const parent of parents) {
|
|
46
|
-
if (parent
|
|
47
|
-
|
|
48
|
-
|
|
74
|
+
if (parent === child)
|
|
75
|
+
continue;
|
|
76
|
+
if (!adj.get(parent).has(child)) {
|
|
77
|
+
adj.get(parent).add(child);
|
|
78
|
+
inDegree.set(child, (inDegree.get(child) || 0) + 1);
|
|
79
|
+
}
|
|
49
80
|
}
|
|
50
81
|
}
|
|
51
|
-
// 4) Kahn’s algorithm
|
|
52
|
-
const queue =
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
queue.push(tbl);
|
|
56
|
-
}
|
|
82
|
+
// 4) Kahn’s algorithm
|
|
83
|
+
const queue = Array.from(inDegree.entries())
|
|
84
|
+
.filter(([, d]) => d === 0)
|
|
85
|
+
.map(([t]) => t);
|
|
57
86
|
const sorted = [];
|
|
58
87
|
while (queue.length) {
|
|
59
88
|
const tbl = queue.shift();
|
|
60
89
|
sorted.push(migMap.get(tbl));
|
|
61
90
|
for (const child of adj.get(tbl)) {
|
|
62
|
-
const nd = inDegree.get(child) - 1;
|
|
91
|
+
const nd = (inDegree.get(child) || 0) - 1;
|
|
63
92
|
inDegree.set(child, nd);
|
|
64
93
|
if (nd === 0)
|
|
65
94
|
queue.push(child);
|
|
66
95
|
}
|
|
67
96
|
}
|
|
68
|
-
// 5)
|
|
97
|
+
// 5) Cycle detection
|
|
69
98
|
if (sorted.length !== migrations.length) {
|
|
70
|
-
const
|
|
71
|
-
.
|
|
72
|
-
.
|
|
73
|
-
|
|
99
|
+
const stuck = Array.from(inDegree.entries())
|
|
100
|
+
.filter(([, d]) => d > 0)
|
|
101
|
+
.map(([t]) => t);
|
|
102
|
+
const edgeDump = Array.from(rawDeps.entries())
|
|
103
|
+
.map(([c, ps]) => `${c} ← [${Array.from(ps).join(", ")}]`)
|
|
104
|
+
.join("; ");
|
|
105
|
+
throw new Error(`Cycle detected in migration dependencies. Stuck: ${stuck.join(", ")}. Edges: ${edgeDump}`);
|
|
74
106
|
}
|
|
75
|
-
console.log('\n📦 Sorted Migration Tables:\n' + sorted.map((item, i) => ` ${i + 1}. ${item.tableName}`).join('\n') + '\n');
|
|
76
107
|
return sorted;
|
|
77
108
|
}
|
|
78
109
|
//# sourceMappingURL=sort.js.map
|