migratex 1.0.0

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/README.md ADDED
@@ -0,0 +1,188 @@
1
+ # migratex
2
+
3
+ a schema diff and migration engine that sits on top of your ORM. it treats database changes like a graph — not a numbered list — enabling deterministic migrations, drift detection, and safe CI/CD workflows.
4
+
5
+ works with **drizzle**, **prisma**, and **typeorm**. supports **postgres** (mysql coming soon).
6
+
7
+ ## why
8
+
9
+ every ORM handles migrations the same way: numbered files in a folder. `001_create_users.sql`, `002_add_posts.sql`, and so on. works fine solo. put a team on it and two devs on different branches will both create `004_*.sql`, someone has to manually rename theirs, and you pray the SQL doesn't conflict. at scale this is a constant source of broken deploys, merge pain, and wasted time.
10
+
11
+ migratex fixes this by replacing linear migrations with a DAG (like git uses for commits) and auto-generating the SQL from your ORM schema.
12
+
13
+ ## features
14
+
15
+ ### auto-generated migrations
16
+ stop writing SQL by hand. migratex reads your ORM schema, introspects the database, diffs them, and generates `up.sql` and `down.sql` automatically. change your schema file, run one command, done.
17
+
18
+ > **the problem this solves:** hand-written migrations drift from the ORM schema over time. someone forgets to add an index in the migration that they added in the schema. or the migration SQL has a typo that doesn't match what the ORM expects. migratex eliminates this entire class of bugs.
19
+
20
+ ### DAG-based migration graph
21
+ migrations are nodes in a graph with content-addressed IDs (SHA-256 hashes), not numbered files. two branches can create migrations independently and merge cleanly — no renaming, no ordering conflicts.
22
+
23
+ > **the problem this solves:** on any team with parallel feature branches, linear migrations constantly collide. devs waste time renaming files, resolving fake conflicts, and coordinating who gets the next number. the DAG makes this a non-issue.
24
+
25
+ ### conflict detection
26
+ migratex understands the schema semantically. if two branches add a `status` column to the same table with different types, it tells you. if they touch different tables, it merges cleanly. real conflicts get caught, false positives don't.
27
+
28
+ > **the problem this solves:** with linear migrations, you only find out about real schema conflicts when the migration runs (or worse, in production). migratex catches them at merge time, before anything touches the database.
29
+
30
+ ### drift detection
31
+ compares your ORM schema against the actual database. catches out-of-band changes — someone ran `ALTER TABLE` directly on prod at 2am, or a migration was applied manually and never committed.
32
+
33
+ > **the problem this solves:** shadow changes to the database that nobody knows about until something breaks. "it works on my machine" but prod has an extra column nobody added through migrations.
34
+
35
+ ### CI-friendly
36
+ `migratex check` validates the migration graph and detects drift. drop it in your pipeline — it exits non-zero if anything is wrong.
37
+
38
+ > **the problem this solves:** broken migrations making it to production because there's no automated gate. migratex check catches graph issues, missing parents, cycles, and schema drift before deploy.
39
+
40
+ ### advisory locking
41
+ `migratex apply` uses database advisory locks. safe to run from multiple instances — no double-applying, no race conditions.
42
+
43
+ ### up and down migrations
44
+ every migration automatically gets a reverse. rollbacks are generated, not hand-written.
45
+
46
+ ## install
47
+
48
+ ```bash
49
+ npm install migratex
50
+ ```
51
+
52
+ ## quickstart
53
+
54
+ ### init
55
+
56
+ ```bash
57
+ $ migratex init
58
+
59
+ ? ORM: drizzle
60
+ ? Dialect: pg
61
+ ? Schema path: ./src/schema.ts
62
+ ? Connection: postgresql://user:pass@localhost:5432/mydb
63
+ ? Migrations dir: ./migrations
64
+
65
+ Created migratex.config.yaml
66
+ Created migrations/
67
+ ```
68
+
69
+ ### generate
70
+
71
+ change your ORM schema, then:
72
+
73
+ ```bash
74
+ $ migratex generate -m "add users table"
75
+
76
+ Reading ORM schema...
77
+ Introspecting database...
78
+ Computing diff...
79
+
80
+ Found 2 change(s):
81
+ create_table users
82
+ create_index users_email_idx
83
+
84
+ Generated migration: a1b2c3d4e5f6
85
+ migrations/a1b2c3d4e5f6/up.sql
86
+ migrations/a1b2c3d4e5f6/down.sql
87
+ Description: add users table
88
+ ```
89
+
90
+ ### apply
91
+
92
+ ```bash
93
+ $ migratex apply
94
+
95
+ Loading migration graph...
96
+ Acquiring lock...
97
+ Applying a1b2c3d4e5f6 — add users table... done
98
+ Releasing lock...
99
+
100
+ 1 migration applied.
101
+ ```
102
+
103
+ ### check
104
+
105
+ ```bash
106
+ $ migratex check
107
+
108
+ Validating migration graph... ok
109
+ Checking for drift... ok
110
+ No issues found.
111
+ ```
112
+
113
+ or when something is wrong:
114
+
115
+ ```bash
116
+ $ migratex check
117
+
118
+ Validating migration graph... ok
119
+ Checking for drift... DRIFT DETECTED
120
+
121
+ Table "users":
122
+ - Column "phone" exists in database but not in ORM schema
123
+ - Column "email" has type "text" in database but "varchar(255)" in ORM schema
124
+
125
+ 1 table has drifted from the expected schema.
126
+ ```
127
+
128
+ ### status
129
+
130
+ ```bash
131
+ $ migratex status
132
+
133
+ Migration graph:
134
+ a1b2c3d4 — create users table [applied]
135
+ d4e5f6a7 — add posts table [applied]
136
+ g7h8i9j0 — add sessions table [pending]
137
+
138
+ Heads: g7h8i9j0
139
+ Applied: 2 | Pending: 1
140
+ ```
141
+
142
+ ## how it works
143
+
144
+ ```
145
+ your ORM schema (TypeScript)
146
+ |
147
+ v
148
+ sidecar extracts it as JSON
149
+ |
150
+ v
151
+ go core diffs it against the actual DB
152
+ |
153
+ v
154
+ generates migration SQL (up + down)
155
+ |
156
+ v
157
+ stores it as a DAG node in migrations/
158
+ ```
159
+
160
+ ```
161
+ migrations/
162
+ graph.json # lightweight index (heads, metadata)
163
+ a1b2c3d4e5f6/
164
+ migration.json # full node (parents, operations, checksums)
165
+ up.sql # apply
166
+ down.sql # revert
167
+ ```
168
+
169
+ each migration node has:
170
+ - **content-addressed ID** — SHA-256 of (parent IDs + operations), truncated to 12 hex chars
171
+ - **parent pointers** — like git commits, can have multiple parents for merges
172
+ - **checksum** — SHA-256 of the up SQL, detects tampering
173
+ - **operations** — structured diff, so conflicts can be detected semantically
174
+
175
+ ## config
176
+
177
+ ```yaml
178
+ # migratex.config.yaml
179
+ orm: drizzle # drizzle | prisma | typeorm
180
+ dialect: pg # pg | mysql
181
+ connection: postgresql://user:pass@localhost:5432/mydb
182
+ schemaPath: ./src/schema.ts
183
+ migrationsDir: ./migrations
184
+ ```
185
+
186
+ ## license
187
+
188
+ MIT
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { execFileSync } = require("child_process");
4
+ const path = require("path");
5
+ const os = require("os");
6
+ const fs = require("fs");
7
+
8
+ function getBinaryPath() {
9
+ const platform = os.platform();
10
+ const arch = os.arch();
11
+
12
+ const platformMap = {
13
+ darwin: "darwin",
14
+ linux: "linux",
15
+ win32: "windows",
16
+ };
17
+
18
+ const archMap = {
19
+ x64: "amd64",
20
+ arm64: "arm64",
21
+ };
22
+
23
+ const goPlatform = platformMap[platform];
24
+ const goArch = archMap[arch];
25
+
26
+ if (!goPlatform || !goArch) {
27
+ console.error(`Unsupported platform: ${platform}-${arch}`);
28
+ process.exit(1);
29
+ }
30
+
31
+ const ext = platform === "win32" ? ".exe" : "";
32
+ const binaryName = `migratex-${goPlatform}-${goArch}${ext}`;
33
+ const binaryPath = path.join(__dirname, "..", "bin", binaryName);
34
+
35
+ if (!fs.existsSync(binaryPath)) {
36
+ console.error(
37
+ `Binary not found: ${binaryPath}\nRun "npm run postinstall" or reinstall the package.`
38
+ );
39
+ process.exit(1);
40
+ }
41
+
42
+ return binaryPath;
43
+ }
44
+
45
+ const binary = getBinaryPath();
46
+
47
+ try {
48
+ execFileSync(binary, process.argv.slice(2), { stdio: "inherit" });
49
+ } catch (err) {
50
+ if (err.status !== undefined) {
51
+ process.exit(err.status);
52
+ }
53
+ throw err;
54
+ }
package/install.js ADDED
@@ -0,0 +1,88 @@
1
+ const https = require("https");
2
+ const http = require("http");
3
+ const fs = require("fs");
4
+ const path = require("path");
5
+ const os = require("os");
6
+
7
+ const platformMap = {
8
+ darwin: "darwin",
9
+ linux: "linux",
10
+ win32: "windows",
11
+ };
12
+
13
+ const archMap = {
14
+ x64: "amd64",
15
+ arm64: "arm64",
16
+ };
17
+
18
+ const platform = platformMap[os.platform()];
19
+ const arch = archMap[os.arch()];
20
+
21
+ if (!platform || !arch) {
22
+ console.error(`Unsupported platform: ${os.platform()}-${os.arch()}`);
23
+ process.exit(1);
24
+ }
25
+
26
+ const pkg = require("./package.json");
27
+ const version = pkg.version;
28
+ const ext = os.platform() === "win32" ? ".exe" : "";
29
+ const binaryName = `migratex-${platform}-${arch}${ext}`;
30
+
31
+ const repo = "Vswaroop04/migrion";
32
+ const url = `https://github.com/${repo}/releases/download/v${version}/${binaryName}`;
33
+
34
+ const dest = path.join(__dirname, "bin", binaryName);
35
+
36
+ // Skip download if binary already exists (e.g. CI pre-packed it)
37
+ if (fs.existsSync(dest)) {
38
+ console.log(`migratex binary already exists at ${dest}`);
39
+ process.exit(0);
40
+ }
41
+
42
+ console.log(`Downloading migratex v${version} for ${platform}-${arch}...`);
43
+ console.log(` ${url}`);
44
+
45
+ function download(url, dest, redirects = 0) {
46
+ if (redirects > 5) {
47
+ console.error("Too many redirects");
48
+ process.exit(1);
49
+ }
50
+
51
+ const client = url.startsWith("https") ? https : http;
52
+
53
+ client
54
+ .get(url, (res) => {
55
+ // Follow redirects (GitHub releases redirect to S3)
56
+ if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
57
+ return download(res.headers.location, dest, redirects + 1);
58
+ }
59
+
60
+ if (res.statusCode !== 200) {
61
+ console.error(`Failed to download: HTTP ${res.statusCode}`);
62
+ console.error(`URL: ${url}`);
63
+ console.error(
64
+ `\nMake sure a GitHub release exists for v${version} with the binary "${binaryName}".`
65
+ );
66
+ process.exit(1);
67
+ }
68
+
69
+ fs.mkdirSync(path.dirname(dest), { recursive: true });
70
+ const file = fs.createWriteStream(dest);
71
+ res.pipe(file);
72
+
73
+ file.on("finish", () => {
74
+ file.close();
75
+ // Make binary executable on unix
76
+ if (os.platform() !== "win32") {
77
+ fs.chmodSync(dest, 0o755);
78
+ }
79
+ console.log(`migratex installed successfully.`);
80
+ });
81
+ })
82
+ .on("error", (err) => {
83
+ console.error(`Download failed: ${err.message}`);
84
+ process.exit(1);
85
+ });
86
+ }
87
+
88
+ download(url, dest);
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "migratex",
3
+ "version": "1.0.0",
4
+ "description": "Schema diff and migration engine for ORMs (Drizzle, Prisma, TypeORM)",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/Vswaroop04/migrion"
9
+ },
10
+ "bin": {
11
+ "migratex": "bin/migratex.js"
12
+ },
13
+ "scripts": {
14
+ "postinstall": "node install.js"
15
+ },
16
+ "files": [
17
+ "bin/migratex.js",
18
+ "install.js"
19
+ ],
20
+ "keywords": [
21
+ "migrations",
22
+ "schema",
23
+ "database",
24
+ "orm",
25
+ "drizzle",
26
+ "prisma",
27
+ "typeorm",
28
+ "postgresql",
29
+ "mysql",
30
+ "dag"
31
+ ],
32
+ "engines": {
33
+ "node": ">=18"
34
+ }
35
+ }