midql-cli 0.1.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/LICENSE +21 -0
- package/README.md +152 -0
- package/dist/App-W6AAY42M.js +568 -0
- package/dist/chunk-3CIK5I4M.js +396 -0
- package/dist/chunk-3FPZQHHV.js +77 -0
- package/dist/chunk-3QAR6XBK.js +200 -0
- package/dist/chunk-7WNCISNV.js +106 -0
- package/dist/chunk-ATZPL4EX.js +35 -0
- package/dist/chunk-BAAEZXFH.js +73 -0
- package/dist/chunk-GWY47EDH.js +11 -0
- package/dist/chunk-NCN3ZBOJ.js +93 -0
- package/dist/chunk-PXDMSYWH.js +18 -0
- package/dist/chunk-TLTYYFT5.js +237 -0
- package/dist/chunk-VFC3HWTF.js +52 -0
- package/dist/chunk-WN6T44OZ.js +1643 -0
- package/dist/chunk-XJAN6OQ7.js +25 -0
- package/dist/cli.js +101 -0
- package/dist/controller-HDNDKU6K.js +18 -0
- package/dist/csv-F2MFR3XB.js +7 -0
- package/dist/dump-LQ7ULAAL.js +11 -0
- package/dist/execute-E45HSHNE.js +155 -0
- package/dist/humanize-UG6KBAFO.js +100 -0
- package/dist/index.d.ts +185 -0
- package/dist/index.js +55 -0
- package/dist/json-Z56V7OEB.js +7 -0
- package/dist/maintenance-QHIUTVV3.js +49 -0
- package/dist/meta-NZ5Z6NYN.js +369 -0
- package/dist/mysql-GQSXUUEK.js +204 -0
- package/dist/profiles-4QGMCJAO.js +67 -0
- package/dist/query-RCUXCOAF.js +122 -0
- package/dist/restore-4QXG2WRR.js +9 -0
- package/package.json +74 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
countSelect
|
|
4
|
+
} from "./chunk-ATZPL4EX.js";
|
|
5
|
+
import {
|
|
6
|
+
buildQuery,
|
|
7
|
+
dialectFor
|
|
8
|
+
} from "./chunk-TLTYYFT5.js";
|
|
9
|
+
import {
|
|
10
|
+
toCsv
|
|
11
|
+
} from "./chunk-XJAN6OQ7.js";
|
|
12
|
+
import {
|
|
13
|
+
toJson
|
|
14
|
+
} from "./chunk-GWY47EDH.js";
|
|
15
|
+
import {
|
|
16
|
+
astIsWrite,
|
|
17
|
+
classifyAst,
|
|
18
|
+
classifyRawSql,
|
|
19
|
+
hasSqlShape,
|
|
20
|
+
rawSqlIsWrite,
|
|
21
|
+
startsWithSqlKeyword,
|
|
22
|
+
translate
|
|
23
|
+
} from "./chunk-WN6T44OZ.js";
|
|
24
|
+
import {
|
|
25
|
+
PostgresAdapter,
|
|
26
|
+
resolveTarget
|
|
27
|
+
} from "./chunk-3CIK5I4M.js";
|
|
28
|
+
import {
|
|
29
|
+
describeTable,
|
|
30
|
+
formatResultSet,
|
|
31
|
+
formatTableList
|
|
32
|
+
} from "./chunk-7WNCISNV.js";
|
|
33
|
+
import {
|
|
34
|
+
loadConfig
|
|
35
|
+
} from "./chunk-3QAR6XBK.js";
|
|
36
|
+
import "./chunk-PXDMSYWH.js";
|
|
37
|
+
import "./chunk-VFC3HWTF.js";
|
|
38
|
+
|
|
39
|
+
// src/commands/query.ts
|
|
40
|
+
import pc from "picocolors";
|
|
41
|
+
async function createAdapter(target) {
|
|
42
|
+
if (target.dialect === "postgres") {
|
|
43
|
+
return new PostgresAdapter(target.options);
|
|
44
|
+
}
|
|
45
|
+
const { MysqlAdapter } = await import("./mysql-GQSXUUEK.js");
|
|
46
|
+
return new MysqlAdapter(target.options);
|
|
47
|
+
}
|
|
48
|
+
function printResult(result, format) {
|
|
49
|
+
if (format === "json") {
|
|
50
|
+
process.stdout.write(toJson(result));
|
|
51
|
+
} else if (format === "csv") {
|
|
52
|
+
process.stdout.write(toCsv(result));
|
|
53
|
+
} else {
|
|
54
|
+
console.log(formatResultSet(result));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
async function runQueryCommand(input, options) {
|
|
58
|
+
const config = loadConfig();
|
|
59
|
+
const target = resolveTarget(options.db);
|
|
60
|
+
const adapter = await createAdapter(target);
|
|
61
|
+
await adapter.connect();
|
|
62
|
+
try {
|
|
63
|
+
const schema = await adapter.introspect();
|
|
64
|
+
const rawSql = startsWithSqlKeyword(input) && hasSqlShape(input) ? input : null;
|
|
65
|
+
if (rawSql) {
|
|
66
|
+
if (target.readonly && rawSqlIsWrite(rawSql)) {
|
|
67
|
+
console.error(pc.red("Connection is read-only; write statements are blocked."));
|
|
68
|
+
return 1;
|
|
69
|
+
}
|
|
70
|
+
if (classifyRawSql(rawSql) !== "safe" && !options.yes) {
|
|
71
|
+
console.error(pc.yellow("Refusing to run a destructive statement without --yes."));
|
|
72
|
+
return 1;
|
|
73
|
+
}
|
|
74
|
+
printResult(await adapter.query(rawSql), options.format);
|
|
75
|
+
return 0;
|
|
76
|
+
}
|
|
77
|
+
const ast = translate(input, schema, { maxJoinDepth: config.maxJoinDepth });
|
|
78
|
+
if (ast.kind === "showTables") {
|
|
79
|
+
console.log(formatTableList(schema));
|
|
80
|
+
return 0;
|
|
81
|
+
}
|
|
82
|
+
if (ast.kind === "describe") {
|
|
83
|
+
const table = schema.tables.find((entry) => entry.name === ast.table);
|
|
84
|
+
if (!table) {
|
|
85
|
+
console.error(pc.red(`Table "${ast.table}" not found.`));
|
|
86
|
+
return 1;
|
|
87
|
+
}
|
|
88
|
+
console.log(describeTable(table));
|
|
89
|
+
return 0;
|
|
90
|
+
}
|
|
91
|
+
const built = buildQuery(ast, dialectFor(target.dialect));
|
|
92
|
+
if (target.readonly && astIsWrite(ast)) {
|
|
93
|
+
console.error(pc.red("Connection is read-only; write statements are blocked."));
|
|
94
|
+
return 1;
|
|
95
|
+
}
|
|
96
|
+
const danger = classifyAst(ast);
|
|
97
|
+
if (danger !== "safe" && !options.yes) {
|
|
98
|
+
if (ast.kind === "update" || ast.kind === "delete") {
|
|
99
|
+
const countQuery = buildQuery(countSelect(ast), dialectFor(target.dialect));
|
|
100
|
+
const countResult = await adapter.query(countQuery.sql, countQuery.params);
|
|
101
|
+
const total = Number(Object.values(countResult.rows[0] ?? {})[0] ?? 0);
|
|
102
|
+
console.error(
|
|
103
|
+
pc.yellow(
|
|
104
|
+
`This would ${ast.kind.toUpperCase()} ${total} row${total === 1 ? "" : "s"} from "${ast.table}". Re-run with --yes to proceed.`
|
|
105
|
+
)
|
|
106
|
+
);
|
|
107
|
+
} else {
|
|
108
|
+
console.error(pc.yellow("Refusing to run a destructive statement without --yes."));
|
|
109
|
+
}
|
|
110
|
+
console.error(pc.dim(`\u2192 ${built.sql}`));
|
|
111
|
+
return 1;
|
|
112
|
+
}
|
|
113
|
+
console.error(pc.dim(`\u2192 ${built.sql}`));
|
|
114
|
+
printResult(await adapter.query(built.sql, built.params), options.format);
|
|
115
|
+
return 0;
|
|
116
|
+
} finally {
|
|
117
|
+
await adapter.close();
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
export {
|
|
121
|
+
runQueryCommand
|
|
122
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "midql-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Fast, safety-first PostgreSQL/MySQL CLI for developers — schema-aware autocomplete, natural-language shortcuts, destructive-op previews",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"midql": "./dist/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"main": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"README.md",
|
|
17
|
+
"LICENSE"
|
|
18
|
+
],
|
|
19
|
+
"engines": {
|
|
20
|
+
"node": ">=18"
|
|
21
|
+
},
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "tsup",
|
|
24
|
+
"dev": "tsup --watch",
|
|
25
|
+
"lint": "biome check src test",
|
|
26
|
+
"lint:fix": "biome check --write src test",
|
|
27
|
+
"test": "vitest run",
|
|
28
|
+
"test:watch": "vitest",
|
|
29
|
+
"test:int": "cross-env MIDQL_INT=1 vitest run test/integration",
|
|
30
|
+
"typecheck": "tsc --noEmit",
|
|
31
|
+
"prepublishOnly": "npm run lint && npm run typecheck && npm run test && npm run build"
|
|
32
|
+
},
|
|
33
|
+
"keywords": [
|
|
34
|
+
"sql",
|
|
35
|
+
"postgres",
|
|
36
|
+
"postgresql",
|
|
37
|
+
"mysql",
|
|
38
|
+
"cli",
|
|
39
|
+
"repl",
|
|
40
|
+
"database",
|
|
41
|
+
"natural-language",
|
|
42
|
+
"autocomplete",
|
|
43
|
+
"developer-tools"
|
|
44
|
+
],
|
|
45
|
+
"author": "Eser Sariyar (https://github.com/esersariyar)",
|
|
46
|
+
"repository": "github:esersariyar/midql",
|
|
47
|
+
"bugs": "https://github.com/esersariyar/midql/issues",
|
|
48
|
+
"homepage": "https://github.com/esersariyar/midql#readme",
|
|
49
|
+
"license": "MIT",
|
|
50
|
+
"publishConfig": {
|
|
51
|
+
"access": "public"
|
|
52
|
+
},
|
|
53
|
+
"dependencies": {
|
|
54
|
+
"cli-table3": "^0.6.5",
|
|
55
|
+
"commander": "^12.1.0",
|
|
56
|
+
"ink": "^5.0.1",
|
|
57
|
+
"mysql2": "^3.11.0",
|
|
58
|
+
"pg": "^8.13.0",
|
|
59
|
+
"picocolors": "^1.1.0",
|
|
60
|
+
"pluralize": "^8.0.0",
|
|
61
|
+
"react": "^18.3.1"
|
|
62
|
+
},
|
|
63
|
+
"devDependencies": {
|
|
64
|
+
"@biomejs/biome": "^1.9.4",
|
|
65
|
+
"@types/node": "^20.16.0",
|
|
66
|
+
"@types/pg": "^8.11.10",
|
|
67
|
+
"@types/pluralize": "^0.0.33",
|
|
68
|
+
"@types/react": "^18.3.11",
|
|
69
|
+
"cross-env": "^7.0.3",
|
|
70
|
+
"tsup": "^8.3.0",
|
|
71
|
+
"typescript": "^5.6.3",
|
|
72
|
+
"vitest": "^2.1.3"
|
|
73
|
+
}
|
|
74
|
+
}
|