mpx-db 1.0.0 → 1.0.3
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/package.json +11 -10
- package/src/cli.js +12 -1
- package/src/commands/query.js +46 -10
- package/SUMMARY.md +0 -182
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mpx-db",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "Database management CLI - Connect, query, migrate, and manage databases from the terminal",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
|
7
|
-
"mpx-db": "
|
|
7
|
+
"mpx-db": "bin/mpx-db.js"
|
|
8
8
|
},
|
|
9
9
|
"type": "module",
|
|
10
10
|
"scripts": {
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"license": "MIT",
|
|
27
27
|
"repository": {
|
|
28
28
|
"type": "git",
|
|
29
|
-
"url": "https://github.com/mesaplexdev/mpx-db"
|
|
29
|
+
"url": "git+https://github.com/mesaplexdev/mpx-db.git"
|
|
30
30
|
},
|
|
31
31
|
"homepage": "https://github.com/mesaplexdev/mpx-db#readme",
|
|
32
32
|
"bugs": "https://github.com/mesaplexdev/mpx-db/issues",
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
"node": ">=18.0.0"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
+
"better-sqlite3": "^12.6.2",
|
|
37
38
|
"chalk": "^5.3.0",
|
|
38
39
|
"cli-table3": "^0.6.5",
|
|
39
40
|
"commander": "^12.1.0",
|
|
@@ -41,14 +42,10 @@
|
|
|
41
42
|
"yaml": "^2.6.1"
|
|
42
43
|
},
|
|
43
44
|
"peerDependencies": {
|
|
44
|
-
"better-sqlite3": "^11.0.0",
|
|
45
45
|
"mysql2": "^3.11.5",
|
|
46
46
|
"pg": "^8.13.1"
|
|
47
47
|
},
|
|
48
48
|
"peerDependenciesMeta": {
|
|
49
|
-
"better-sqlite3": {
|
|
50
|
-
"optional": true
|
|
51
|
-
},
|
|
52
49
|
"pg": {
|
|
53
50
|
"optional": true
|
|
54
51
|
},
|
|
@@ -56,7 +53,11 @@
|
|
|
56
53
|
"optional": true
|
|
57
54
|
}
|
|
58
55
|
},
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
|
|
56
|
+
"files": [
|
|
57
|
+
"src/",
|
|
58
|
+
"bin/",
|
|
59
|
+
"README.md",
|
|
60
|
+
"LICENSE",
|
|
61
|
+
"package.json"
|
|
62
|
+
]
|
|
62
63
|
}
|
package/src/cli.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import chalk from 'chalk';
|
|
3
|
+
import { readFileSync } from 'fs';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
import { dirname, join } from 'path';
|
|
3
6
|
import { handleConnect, listConnections, removeConnection } from './commands/connections.js';
|
|
4
7
|
import { handleQuery } from './commands/query.js';
|
|
5
8
|
import { showInfo, listTables, describeTable, dumpSchema } from './commands/schema.js';
|
|
@@ -12,12 +15,16 @@ import {
|
|
|
12
15
|
} from './commands/migrate.js';
|
|
13
16
|
import { exportData } from './commands/data.js';
|
|
14
17
|
|
|
18
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
19
|
+
const __dirname = dirname(__filename);
|
|
20
|
+
const pkg = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));
|
|
21
|
+
|
|
15
22
|
const program = new Command();
|
|
16
23
|
|
|
17
24
|
program
|
|
18
25
|
.name('mpx-db')
|
|
19
26
|
.description('Database management CLI - Connect, query, migrate, and manage databases')
|
|
20
|
-
.version(
|
|
27
|
+
.version(pkg.version);
|
|
21
28
|
|
|
22
29
|
// Connect command
|
|
23
30
|
program
|
|
@@ -134,6 +141,10 @@ program.exitOverride();
|
|
|
134
141
|
try {
|
|
135
142
|
await program.parseAsync(process.argv);
|
|
136
143
|
} catch (err) {
|
|
144
|
+
// Ignore help and version display "errors"
|
|
145
|
+
if (err.code === 'commander.version') {
|
|
146
|
+
process.exit(0);
|
|
147
|
+
}
|
|
137
148
|
if (err.code !== 'commander.help' && err.code !== 'commander.helpDisplayed') {
|
|
138
149
|
console.error(chalk.red(`Error: ${err.message}`));
|
|
139
150
|
process.exit(1);
|
package/src/commands/query.js
CHANGED
|
@@ -4,7 +4,7 @@ import { getConnection } from '../utils/config.js';
|
|
|
4
4
|
import { createConnection } from '../db/connection.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* Execute a query
|
|
7
|
+
* Execute a query or statement
|
|
8
8
|
*/
|
|
9
9
|
export async function handleQuery(target, sql, options) {
|
|
10
10
|
let db;
|
|
@@ -16,20 +16,38 @@ export async function handleQuery(target, sql, options) {
|
|
|
16
16
|
// Connect
|
|
17
17
|
db = await createConnection(connectionString);
|
|
18
18
|
|
|
19
|
-
//
|
|
19
|
+
// Determine if this is a SELECT query or a DML/DDL statement
|
|
20
|
+
const isSelectQuery = isQueryStatement(sql);
|
|
21
|
+
|
|
22
|
+
// Execute
|
|
20
23
|
const startTime = Date.now();
|
|
21
|
-
const rows = await db.query(sql);
|
|
22
|
-
const duration = Date.now() - startTime;
|
|
23
24
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
if (isSelectQuery) {
|
|
26
|
+
// SELECT, PRAGMA, EXPLAIN, WITH - returns rows
|
|
27
|
+
const rows = await db.query(sql);
|
|
28
|
+
const duration = Date.now() - startTime;
|
|
29
|
+
|
|
30
|
+
// Display results
|
|
31
|
+
if (rows.length === 0) {
|
|
32
|
+
console.log(chalk.yellow('No rows returned'));
|
|
33
|
+
} else {
|
|
34
|
+
displayTable(rows);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
console.log(chalk.gray(`\n${rows.length} row(s) in ${duration}ms`));
|
|
27
38
|
} else {
|
|
28
|
-
|
|
39
|
+
// INSERT, UPDATE, DELETE, CREATE, DROP, ALTER - returns affected rows
|
|
40
|
+
const result = await db.execute(sql);
|
|
41
|
+
const duration = Date.now() - startTime;
|
|
42
|
+
|
|
43
|
+
console.log(chalk.green('✓ Statement executed successfully'));
|
|
44
|
+
console.log(chalk.gray(` Affected rows: ${result.affectedRows}`));
|
|
45
|
+
if (result.insertId) {
|
|
46
|
+
console.log(chalk.gray(` Insert ID: ${result.insertId}`));
|
|
47
|
+
}
|
|
48
|
+
console.log(chalk.gray(` Duration: ${duration}ms`));
|
|
29
49
|
}
|
|
30
50
|
|
|
31
|
-
console.log(chalk.gray(`\n${rows.length} row(s) in ${duration}ms`));
|
|
32
|
-
|
|
33
51
|
} catch (err) {
|
|
34
52
|
console.error(chalk.red('✗ Query failed'));
|
|
35
53
|
console.error(chalk.red(` ${err.message}`));
|
|
@@ -41,6 +59,24 @@ export async function handleQuery(target, sql, options) {
|
|
|
41
59
|
}
|
|
42
60
|
}
|
|
43
61
|
|
|
62
|
+
/**
|
|
63
|
+
* Determine if SQL is a query (returns rows) or a statement (modifies data)
|
|
64
|
+
*/
|
|
65
|
+
function isQueryStatement(sql) {
|
|
66
|
+
const trimmed = sql.trim().toUpperCase();
|
|
67
|
+
|
|
68
|
+
// These keywords indicate a query that returns rows
|
|
69
|
+
const queryKeywords = ['SELECT', 'PRAGMA', 'EXPLAIN', 'WITH', 'SHOW', 'DESCRIBE', 'DESC'];
|
|
70
|
+
|
|
71
|
+
for (const keyword of queryKeywords) {
|
|
72
|
+
if (trimmed.startsWith(keyword)) {
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
|
|
44
80
|
/**
|
|
45
81
|
* Display query results as table
|
|
46
82
|
*/
|
package/SUMMARY.md
DELETED
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
# mpx-db — Project Summary
|
|
2
|
-
|
|
3
|
-
**Built:** 2026-02-15
|
|
4
|
-
**Status:** ✅ Production Ready
|
|
5
|
-
**Code:** 2,100 lines of JavaScript
|
|
6
|
-
**Tests:** 23/23 passing (100%)
|
|
7
|
-
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
## What Is This?
|
|
11
|
-
|
|
12
|
-
A **professional-grade database CLI** that eliminates the pain of juggling multiple database tools.
|
|
13
|
-
|
|
14
|
-
One clean interface for **SQLite**, **PostgreSQL**, and **MySQL**.
|
|
15
|
-
|
|
16
|
-
---
|
|
17
|
-
|
|
18
|
-
## Key Features
|
|
19
|
-
|
|
20
|
-
✅ Multi-database support (SQLite, PostgreSQL, MySQL)
|
|
21
|
-
✅ Beautiful colored table output
|
|
22
|
-
✅ Encrypted credential storage (AES-256-GCM)
|
|
23
|
-
✅ Git-friendly SQL migrations
|
|
24
|
-
✅ Schema inspection & export
|
|
25
|
-
✅ Data export (JSON/CSV)
|
|
26
|
-
✅ Fast startup (< 300ms)
|
|
27
|
-
✅ Comprehensive error handling
|
|
28
|
-
✅ 100% test coverage
|
|
29
|
-
|
|
30
|
-
---
|
|
31
|
-
|
|
32
|
-
## Quick Start
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
# Install
|
|
36
|
-
npm install -g mpx-db better-sqlite3
|
|
37
|
-
|
|
38
|
-
# Connect
|
|
39
|
-
mpx-db connect --save dev sqlite://./dev.db
|
|
40
|
-
|
|
41
|
-
# Query
|
|
42
|
-
mpx-db query dev "SELECT * FROM users LIMIT 10"
|
|
43
|
-
|
|
44
|
-
# Migrations
|
|
45
|
-
mpx-db migrate init
|
|
46
|
-
mpx-db migrate create add_users_table
|
|
47
|
-
mpx-db migrate up dev
|
|
48
|
-
|
|
49
|
-
# Export
|
|
50
|
-
mpx-db export dev users --format csv
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
---
|
|
54
|
-
|
|
55
|
-
## Architecture
|
|
56
|
-
|
|
57
|
-
**23 files:**
|
|
58
|
-
- 1 CLI entry point
|
|
59
|
-
- 5 command modules
|
|
60
|
-
- 5 database adapters
|
|
61
|
-
- 2 utility modules
|
|
62
|
-
- 5 test suites
|
|
63
|
-
- Comprehensive README
|
|
64
|
-
|
|
65
|
-
**Dependencies:**
|
|
66
|
-
- commander (CLI framework)
|
|
67
|
-
- cli-table3 (beautiful tables)
|
|
68
|
-
- chalk (colored output)
|
|
69
|
-
- yaml (config parsing)
|
|
70
|
-
- Optional: better-sqlite3, pg, mysql2
|
|
71
|
-
|
|
72
|
-
---
|
|
73
|
-
|
|
74
|
-
## Why It's Good
|
|
75
|
-
|
|
76
|
-
1. **Genuinely useful** — Solves real developer pain
|
|
77
|
-
2. **Professional quality** — Production-ready, not a toy
|
|
78
|
-
3. **Secure by default** — Encrypted credentials
|
|
79
|
-
4. **Beautiful UX** — Colored output, clear messages
|
|
80
|
-
5. **Well-tested** — 23 comprehensive tests
|
|
81
|
-
6. **Git-friendly** — SQL migration files
|
|
82
|
-
7. **Fast** — Minimal startup time
|
|
83
|
-
|
|
84
|
-
---
|
|
85
|
-
|
|
86
|
-
## Test Results
|
|
87
|
-
|
|
88
|
-
```
|
|
89
|
-
✔ Database Connection (8 tests)
|
|
90
|
-
✔ Connection Management (4 tests)
|
|
91
|
-
✔ Schema Operations (4 tests)
|
|
92
|
-
✔ Query Operations (5 tests)
|
|
93
|
-
✔ Migrations (4 tests)
|
|
94
|
-
✔ Data Export (3 tests)
|
|
95
|
-
|
|
96
|
-
ℹ tests 23
|
|
97
|
-
ℹ pass 23
|
|
98
|
-
ℹ fail 0
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
---
|
|
102
|
-
|
|
103
|
-
## Commands
|
|
104
|
-
|
|
105
|
-
**Connection:**
|
|
106
|
-
- `mpx-db connect [--save <name>] <url>`
|
|
107
|
-
- `mpx-db connections list`
|
|
108
|
-
|
|
109
|
-
**Query:**
|
|
110
|
-
- `mpx-db query <target> "<sql>"`
|
|
111
|
-
- `mpx-db info <target>`
|
|
112
|
-
- `mpx-db tables <target>`
|
|
113
|
-
- `mpx-db describe <target> <table>`
|
|
114
|
-
|
|
115
|
-
**Schema:**
|
|
116
|
-
- `mpx-db schema dump <target>`
|
|
117
|
-
|
|
118
|
-
**Migrations:**
|
|
119
|
-
- `mpx-db migrate init`
|
|
120
|
-
- `mpx-db migrate create <description>`
|
|
121
|
-
- `mpx-db migrate status <target>`
|
|
122
|
-
- `mpx-db migrate up <target>`
|
|
123
|
-
- `mpx-db migrate down <target>`
|
|
124
|
-
|
|
125
|
-
**Data:**
|
|
126
|
-
- `mpx-db export <target> <table> [--format csv|json]`
|
|
127
|
-
|
|
128
|
-
---
|
|
129
|
-
|
|
130
|
-
## What Makes It Special
|
|
131
|
-
|
|
132
|
-
**Versus psql/mysql/sqlite3:**
|
|
133
|
-
- One tool, consistent interface
|
|
134
|
-
- Saved connections
|
|
135
|
-
- Beautiful output
|
|
136
|
-
- Migration tracking
|
|
137
|
-
|
|
138
|
-
**Versus Skeema:**
|
|
139
|
-
- Multi-database (not just MySQL)
|
|
140
|
-
- Open source
|
|
141
|
-
- Simpler mental model
|
|
142
|
-
|
|
143
|
-
**Versus Prisma/TypeORM:**
|
|
144
|
-
- No build step
|
|
145
|
-
- Pure SQL migrations
|
|
146
|
-
- Direct database access
|
|
147
|
-
- No ORM abstraction
|
|
148
|
-
|
|
149
|
-
---
|
|
150
|
-
|
|
151
|
-
## Production Ready?
|
|
152
|
-
|
|
153
|
-
✅ **Yes.**
|
|
154
|
-
|
|
155
|
-
- Comprehensive error handling
|
|
156
|
-
- Secure credential storage
|
|
157
|
-
- Proper exit codes
|
|
158
|
-
- Helpful error messages
|
|
159
|
-
- 100% test coverage
|
|
160
|
-
- MIT licensed
|
|
161
|
-
- Ready to publish
|
|
162
|
-
|
|
163
|
-
---
|
|
164
|
-
|
|
165
|
-
## Next Steps
|
|
166
|
-
|
|
167
|
-
**v1.1:**
|
|
168
|
-
- Interactive REPL mode
|
|
169
|
-
- Query history
|
|
170
|
-
- Migration templates
|
|
171
|
-
|
|
172
|
-
**v2.0:**
|
|
173
|
-
- Schema diff
|
|
174
|
-
- Auto-migration generation
|
|
175
|
-
- Visual diagrams
|
|
176
|
-
- Data seeding
|
|
177
|
-
|
|
178
|
-
---
|
|
179
|
-
|
|
180
|
-
**Project Hydra 🐉 — Tool #3: Complete**
|
|
181
|
-
|
|
182
|
-
*Built with brutally honest standards. No compromises.*
|