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.
Files changed (2) hide show
  1. package/dist/utils/sort.js +77 -46
  2. package/package.json +1 -1
@@ -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
- * Reorders migrations so that any table with foreign‐key dependencies
3
- * is always migrated *after* the tables it references.
4
- *
5
- * @param migrations Array of Migration objects (with tableName & definitions[])
6
- * @returns New array sorted in dependency order
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(migrations) {
10
- // 1) Build a map: tableName Migration
11
- const migMap = new Map(migrations
12
- .filter(m => !m.local) // skip ignored models
13
- .map(m => [m.tableName, m]));
14
- // 2) Collect “true” FKs only (skip back‐relation object fields)
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
- // only consider a relationship if:
22
- // - it exists (def.relationship)
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
- const parent = def.relationship.on;
32
- if (!migMap.has(parent) || m.tableName == parent)
33
- continue; // skip external tables
34
- rawDeps.get(m.tableName).add(parent);
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 (parent → dependents) and in-degree (table → count)
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 !== child)
47
- adj.get(parent).push(child);
48
- inDegree.set(child, inDegree.get(child) + 1);
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: enqueue all zero in-degree tables
52
- const queue = [];
53
- for (const [tbl, deg] of inDegree) {
54
- if (deg === 0)
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) If not all processed, there is a genuine cycle
97
+ // 5) Cycle detection
69
98
  if (sorted.length !== migrations.length) {
70
- const cycle = migrations
71
- .map(m => m.tableName)
72
- .filter(t => !sorted.some(s => s.tableName === t));
73
- throw new Error(`Cycle detected in migration dependencies: ${cycle.join(' → ')}`);
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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prisma-laravel-migrate",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Generate laravel migrations and/or models using prisma files",
5
5
  "bin": {
6
6
  "prisma-laravel-migrations": "./dist/cli/migrator.index.js",