mysql-migration 1.2.4 → 1.2.6
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 +33 -7
- package/index.js +12 -0
- package/package.json +1 -1
- package/src/commands/back.js +3 -4
- package/src/commands/create.js +17 -1
- package/src/commands/run.js +3 -6
- package/src/commands/to-cjs.js +49 -0
- package/src/commands/to-esm.js +49 -0
- package/src/utils/moduleLoader.js +29 -0
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
[](https://www.npmjs.com/package/mysql-migration)
|
|
8
8
|
[](LICENSE.md)
|
|
9
|
-
[](https://nodejs.org/)
|
|
10
10
|
|
|
11
11
|
</div>
|
|
12
12
|
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
|
|
23
23
|
## 📋 Prerequisites
|
|
24
24
|
|
|
25
|
-
- **Node.js**
|
|
25
|
+
- **Node.js** v18 or later.
|
|
26
26
|
- **MySQL** instance reachable from where you run the CLI.
|
|
27
27
|
- A project workspace where you can store migration files and configuration.
|
|
28
28
|
|
|
@@ -38,16 +38,18 @@ Or run ad hoc without installing by prefixing commands with `npx`.
|
|
|
38
38
|
|
|
39
39
|
## 🚀 Quick Start
|
|
40
40
|
|
|
41
|
-
**1️⃣
|
|
41
|
+
**1️⃣ Initialize the project**
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
**2️⃣ Initialize the migrations table**
|
|
43
|
+
Run the init command to scaffold the `migrations/` directory and create a default configuration file:
|
|
46
44
|
|
|
47
45
|
```bash
|
|
48
46
|
npx mysql-migration init
|
|
49
47
|
```
|
|
50
48
|
|
|
49
|
+
**2️⃣ Configure your database**
|
|
50
|
+
|
|
51
|
+
Edit the generated `migrations/mysql-migration.config.json` file with your database credentials.
|
|
52
|
+
|
|
51
53
|
**3️⃣ Generate your first migration**
|
|
52
54
|
|
|
53
55
|
```bash
|
|
@@ -91,11 +93,21 @@ Add as many database entries as you need. You can then target each one via the C
|
|
|
91
93
|
| Command | Description |
|
|
92
94
|
|---------|-------------|
|
|
93
95
|
| `npx mysql-migration help` | 📚 Show all available commands |
|
|
94
|
-
| `npx mysql-migration init` | 🎬
|
|
96
|
+
| `npx mysql-migration init` | 🎬 Scaffold migrations directory and config |
|
|
95
97
|
| `npx mysql-migration create <name> <dbName>` | ✏️ Scaffold a timestamped migration file |
|
|
96
98
|
| `npx mysql-migration run [dbName]` | ▶️ Execute all pending migrations |
|
|
97
99
|
| `npx mysql-migration rollback <dbName> <batch>` | ⏪ Roll back migrations to specified batch |
|
|
98
100
|
| `npx mysql-migration batch <dbName>` | 📊 Display recorded batches |
|
|
101
|
+
| `npx mysql-migration to-cjs <dbName>` | 🔄 Convert migrations to CommonJS |
|
|
102
|
+
| `npx mysql-migration to-esm <dbName>` | 🔄 Convert migrations to ESM |
|
|
103
|
+
|
|
104
|
+
### 🎬 Initialize Project
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
npx mysql-migration init
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Scaffolds the `migrations/` directory and creates a default `mysql-migration.config.json` file. Run this once when setting up the tool in a new project.
|
|
99
111
|
|
|
100
112
|
### ✏️ Create a New Migration
|
|
101
113
|
|
|
@@ -129,6 +141,20 @@ npx mysql-migration batch database-name
|
|
|
129
141
|
|
|
130
142
|
View the recorded batches to understand which migrations were executed together.
|
|
131
143
|
|
|
144
|
+
### 🔄 Convert Module System
|
|
145
|
+
|
|
146
|
+
If you need to switch your project between CommonJS (`require`) and ES Modules (`import/export`), you can batch convert your existing migration files.
|
|
147
|
+
|
|
148
|
+
**Convert to CommonJS:**
|
|
149
|
+
```bash
|
|
150
|
+
npx mysql-migration to-cjs database-name
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**Convert to ES Modules:**
|
|
154
|
+
```bash
|
|
155
|
+
npx mysql-migration to-esm database-name
|
|
156
|
+
```
|
|
157
|
+
|
|
132
158
|
## 🔧 Troubleshooting
|
|
133
159
|
|
|
134
160
|
- **Authentication errors**: Verify credentials in `mysql-migration.config.json` match your MySQL user.
|
package/index.js
CHANGED
|
@@ -13,6 +13,8 @@ program
|
|
|
13
13
|
console.log(` rollback <dbName> <batch> Rollback migration`);
|
|
14
14
|
console.log(` create <name> <dbName> Create a new migration`);
|
|
15
15
|
console.log(` batch <dbName> Get the batched migrations`);
|
|
16
|
+
console.log(` to-esm <dbName> Convert migrations to ESM`);
|
|
17
|
+
console.log(` to-cjs <dbName> Convert migrations to CJS`);
|
|
16
18
|
console.log(` help Show this help message\n`);
|
|
17
19
|
});
|
|
18
20
|
//---------------------------------------
|
|
@@ -41,4 +43,14 @@ program
|
|
|
41
43
|
.description("Get the batched migrations")
|
|
42
44
|
.action((dbName) => require("./src/commands/batch")(dbName));
|
|
43
45
|
//---------------------------------------
|
|
46
|
+
program
|
|
47
|
+
.command("to-esm <dbName>")
|
|
48
|
+
.description("Convert migrations to ESM")
|
|
49
|
+
.action((dbName) => require("./src/commands/to-esm")(dbName));
|
|
50
|
+
//---------------------------------------
|
|
51
|
+
program
|
|
52
|
+
.command("to-cjs <dbName>")
|
|
53
|
+
.description("Convert migrations to CJS")
|
|
54
|
+
.action((dbName) => require("./src/commands/to-cjs")(dbName));
|
|
55
|
+
//---------------------------------------
|
|
44
56
|
program.parse(process.argv);
|
package/package.json
CHANGED
package/src/commands/back.js
CHANGED
|
@@ -21,6 +21,7 @@ const {
|
|
|
21
21
|
getCurrentBatch,
|
|
22
22
|
deleteMigration,
|
|
23
23
|
} = require("../utils/functions");
|
|
24
|
+
const { loadModule } = require("../utils/moduleLoader");
|
|
24
25
|
//==============================================================================
|
|
25
26
|
async function back_migration(dbName, batch) {
|
|
26
27
|
const connection = {};
|
|
@@ -67,8 +68,8 @@ async function back_migration(dbName, batch) {
|
|
|
67
68
|
if (!fs.existsSync(`${currentPath}/migrations/${dbName}_db/${file.migration}.js`)) {
|
|
68
69
|
console.warn("\x1b[33m%s\x1b[0m", `Warning: Migration "${file.migration}" not found.`);
|
|
69
70
|
} else {
|
|
70
|
-
const migrationPath = `${currentPath}/migrations/${dbName}_db/${file.migration}`;
|
|
71
|
-
const migration =
|
|
71
|
+
const migrationPath = `${currentPath}/migrations/${dbName}_db/${file.migration}.js`;
|
|
72
|
+
const migration = await loadModule(migrationPath);
|
|
72
73
|
try {
|
|
73
74
|
await migration.down(connection[dbName]);
|
|
74
75
|
await deleteMigration(connection[dbName], file.migration, batchNumber);
|
|
@@ -78,8 +79,6 @@ async function back_migration(dbName, batch) {
|
|
|
78
79
|
);
|
|
79
80
|
} catch (err) {
|
|
80
81
|
console.warn("\x1b[33m%s\x1b[0m", `Warning: "${err}" in migration "${file.migration}".`);
|
|
81
|
-
} finally {
|
|
82
|
-
delete require.cache[require.resolve(migrationPath)];
|
|
83
82
|
}
|
|
84
83
|
}
|
|
85
84
|
}
|
package/src/commands/create.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
//---------------------------------------
|
|
3
3
|
const fs = require("fs");
|
|
4
4
|
const dayjs = require("dayjs");
|
|
5
|
+
const path = require("path");
|
|
5
6
|
//---------------------------------------
|
|
6
7
|
const currentPath = process.cwd();
|
|
7
8
|
const config = require(`${currentPath}/migrations/mysql-migration.config.json`);
|
|
@@ -29,7 +30,22 @@ function create_migration(migrationName, dbName) {
|
|
|
29
30
|
if (fs.existsSync(filePath))
|
|
30
31
|
console.warn("\x1b[33m%s\x1b[0m", `Warning: File "${fileName}" already exists in the "migrations" directory.`);
|
|
31
32
|
else {
|
|
32
|
-
|
|
33
|
+
let isEsm = false;
|
|
34
|
+
try {
|
|
35
|
+
const packageJsonPath = path.join(currentPath, "package.json");
|
|
36
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
37
|
+
const packageJson = require(packageJsonPath);
|
|
38
|
+
if (packageJson.type === "module") {
|
|
39
|
+
isEsm = true;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
} catch (e) {
|
|
43
|
+
// Ignore error, default to CJS
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const exportPrefix = isEsm ? "export default" : "module.exports =";
|
|
47
|
+
|
|
48
|
+
const dataText = `${exportPrefix} {
|
|
33
49
|
up: (connection) => {
|
|
34
50
|
const query = "";
|
|
35
51
|
|
package/src/commands/run.js
CHANGED
|
@@ -21,6 +21,7 @@ const {
|
|
|
21
21
|
getCurrentBatch,
|
|
22
22
|
insertMigration,
|
|
23
23
|
} = require("../utils/functions");
|
|
24
|
+
const { loadModule } = require("../utils/moduleLoader");
|
|
24
25
|
//==============================================================================
|
|
25
26
|
async function run_migration(dbName) {
|
|
26
27
|
const connection = {},
|
|
@@ -66,15 +67,13 @@ async function run_migration(dbName) {
|
|
|
66
67
|
//---------------------------------------
|
|
67
68
|
for (let file of pendingMigrations) {
|
|
68
69
|
const migrationPath = `${currentPath}/migrations/${dbName}_db/${file}`;
|
|
69
|
-
const migration =
|
|
70
|
+
const migration = await loadModule(migrationPath);
|
|
70
71
|
try {
|
|
71
72
|
await migration.up(connection[dbName]);
|
|
72
73
|
await insertMigration(connection[dbName], file.replace(".js", ""), batch);
|
|
73
74
|
console.log("\x1b[36m%s\x1b[0m", `Migrated: "${file}" successfully.`);
|
|
74
75
|
} catch (err) {
|
|
75
76
|
console.warn("\x1b[33m%s\x1b[0m", `Warning: "${err}" in migration "${file}".`);
|
|
76
|
-
} finally {
|
|
77
|
-
delete require.cache[require.resolve(migrationPath)];
|
|
78
77
|
}
|
|
79
78
|
}
|
|
80
79
|
console.log("\x1b[32m%s\x1b[0m", "All migrations have been completed successfully.\n");
|
|
@@ -115,15 +114,13 @@ async function run_migration(dbName) {
|
|
|
115
114
|
//---------------------------------------
|
|
116
115
|
for (let [file, key, batch] of migrations) {
|
|
117
116
|
const migrationPath = `${currentPath}/migrations/${key}_db/${file}`;
|
|
118
|
-
const migration =
|
|
117
|
+
const migration = await loadModule(migrationPath);
|
|
119
118
|
try {
|
|
120
119
|
await migration.up(connection[key]);
|
|
121
120
|
await insertMigration(connection[key], file.replace(".js", ""), batch);
|
|
122
121
|
console.log("\x1b[36m%s\x1b[0m", `Migrated: "${file}" in database "${key}" successfully.`);
|
|
123
122
|
} catch (err) {
|
|
124
123
|
console.warn("\x1b[33m%s\x1b[0m", `Warning: "${err}" in migration "${file}" in database "${key}".`);
|
|
125
|
-
} finally {
|
|
126
|
-
delete require.cache[require.resolve(migrationPath)];
|
|
127
124
|
}
|
|
128
125
|
}
|
|
129
126
|
console.log("\x1b[32m%s\x1b[0m", "All migrations have been completed successfully.\n");
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//---------------------------------------
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
//---------------------------------------
|
|
6
|
+
const currentPath = process.cwd();
|
|
7
|
+
const config = require(`${currentPath}/migrations/mysql-migration.config.json`);
|
|
8
|
+
//---------------------------------------
|
|
9
|
+
function convert_to_cjs(dbName) {
|
|
10
|
+
//---------------------------------------
|
|
11
|
+
const databases = Object.keys(config.databases);
|
|
12
|
+
//---------------------------------------
|
|
13
|
+
if (!databases.includes(dbName)) {
|
|
14
|
+
console.error("\x1b[31m%s\x1b[0m", `Error: Invalid database name "${dbName}" can be: ${databases.join(", ")}.`);
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
//---------------------------------------
|
|
18
|
+
const migrationsDir = `${currentPath}/migrations/${dbName}_db`;
|
|
19
|
+
if (!fs.existsSync(migrationsDir)) {
|
|
20
|
+
console.error("\x1b[31m%s\x1b[0m", `Error: Migrations directory for "${dbName}" not found.`);
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
//---------------------------------------
|
|
24
|
+
const files = fs.readdirSync(migrationsDir);
|
|
25
|
+
let convertedCount = 0;
|
|
26
|
+
|
|
27
|
+
for (const file of files) {
|
|
28
|
+
if (file.endsWith(".js")) {
|
|
29
|
+
const filePath = path.join(migrationsDir, file);
|
|
30
|
+
let content = fs.readFileSync(filePath, "utf8");
|
|
31
|
+
|
|
32
|
+
// Simple check and replace for export default
|
|
33
|
+
if (content.includes("export default")) {
|
|
34
|
+
content = content.replace("export default", "module.exports =");
|
|
35
|
+
fs.writeFileSync(filePath, content);
|
|
36
|
+
console.log("\x1b[32m%s\x1b[0m", `Converted: "${file}" to CJS.`);
|
|
37
|
+
convertedCount++;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (convertedCount === 0) {
|
|
43
|
+
console.log("\x1b[33m%s\x1b[0m", "No files needed conversion.");
|
|
44
|
+
} else {
|
|
45
|
+
console.log("\x1b[32m%s\x1b[0m", `\nSuccessfully converted ${convertedCount} files to CJS.`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
//---------------------------------------
|
|
49
|
+
module.exports = convert_to_cjs;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//---------------------------------------
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
//---------------------------------------
|
|
6
|
+
const currentPath = process.cwd();
|
|
7
|
+
const config = require(`${currentPath}/migrations/mysql-migration.config.json`);
|
|
8
|
+
//---------------------------------------
|
|
9
|
+
function convert_to_esm(dbName) {
|
|
10
|
+
//---------------------------------------
|
|
11
|
+
const databases = Object.keys(config.databases);
|
|
12
|
+
//---------------------------------------
|
|
13
|
+
if (!databases.includes(dbName)) {
|
|
14
|
+
console.error("\x1b[31m%s\x1b[0m", `Error: Invalid database name "${dbName}" can be: ${databases.join(", ")}.`);
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
//---------------------------------------
|
|
18
|
+
const migrationsDir = `${currentPath}/migrations/${dbName}_db`;
|
|
19
|
+
if (!fs.existsSync(migrationsDir)) {
|
|
20
|
+
console.error("\x1b[31m%s\x1b[0m", `Error: Migrations directory for "${dbName}" not found.`);
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
//---------------------------------------
|
|
24
|
+
const files = fs.readdirSync(migrationsDir);
|
|
25
|
+
let convertedCount = 0;
|
|
26
|
+
|
|
27
|
+
for (const file of files) {
|
|
28
|
+
if (file.endsWith(".js")) {
|
|
29
|
+
const filePath = path.join(migrationsDir, file);
|
|
30
|
+
let content = fs.readFileSync(filePath, "utf8");
|
|
31
|
+
|
|
32
|
+
// Simple check and replace for module.exports
|
|
33
|
+
if (content.includes("module.exports =")) {
|
|
34
|
+
content = content.replace("module.exports =", "export default");
|
|
35
|
+
fs.writeFileSync(filePath, content);
|
|
36
|
+
console.log("\x1b[32m%s\x1b[0m", `Converted: "${file}" to ESM.`);
|
|
37
|
+
convertedCount++;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (convertedCount === 0) {
|
|
43
|
+
console.log("\x1b[33m%s\x1b[0m", "No files needed conversion.");
|
|
44
|
+
} else {
|
|
45
|
+
console.log("\x1b[32m%s\x1b[0m", `\nSuccessfully converted ${convertedCount} files to ESM.`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
//---------------------------------------
|
|
49
|
+
module.exports = convert_to_esm;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const path = require("path");
|
|
2
|
+
const { pathToFileURL } = require("url");
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Loads a module from the specified file path using dynamic import.
|
|
6
|
+
* Handles both CommonJS and ES Modules.
|
|
7
|
+
*
|
|
8
|
+
* @param {string} filePath - The absolute path to the file.
|
|
9
|
+
* @returns {Promise<any>} - The loaded module content.
|
|
10
|
+
*/
|
|
11
|
+
async function loadModule(filePath) {
|
|
12
|
+
try {
|
|
13
|
+
// Convert path to file URL for Windows compatibility with dynamic import
|
|
14
|
+
const fileUrl = pathToFileURL(filePath).href;
|
|
15
|
+
const module = await import(fileUrl);
|
|
16
|
+
|
|
17
|
+
// If it's a CJS module loaded via import(), the default export holds the module.exports
|
|
18
|
+
// If it's an ESM module, we return the module namespace object or specific exports
|
|
19
|
+
// For this migration tool, we expect the migration object to be the default export or the module itself
|
|
20
|
+
if (module.default) {
|
|
21
|
+
return module.default;
|
|
22
|
+
}
|
|
23
|
+
return module;
|
|
24
|
+
} catch (error) {
|
|
25
|
+
throw new Error(`Failed to load module at ${filePath}: ${error.message}`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
module.exports = { loadModule };
|