scdb-cli 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/index.js +110 -0
- package/package.json +11 -0
package/index.js
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createInterface } from 'readline';
|
|
3
|
+
import { createClient } from 'scdb-lib';
|
|
4
|
+
|
|
5
|
+
const apiKey = process.env.SECURE_DB_API_KEY;
|
|
6
|
+
const url = "http://localhost:" + String(process.env.SECURE_DB_API_KEY).substring(4, 8);
|
|
7
|
+
|
|
8
|
+
function getClient() {
|
|
9
|
+
if (!apiKey) {
|
|
10
|
+
console.error('Set SECURE_DB_API_KEY (or pass --key) to use the CLI.');
|
|
11
|
+
process.exit(1);
|
|
12
|
+
}
|
|
13
|
+
return createClient({ url, apiKey });
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function printResult(rows) {
|
|
17
|
+
if (rows.length === 0) {
|
|
18
|
+
console.log('(0 rows)');
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const keys = Object.keys(rows[0]);
|
|
22
|
+
console.log(keys.join('\t'));
|
|
23
|
+
console.log(keys.map(() => '---').join('\t'));
|
|
24
|
+
rows.forEach((row) => {
|
|
25
|
+
console.log(keys.map((k) => String(row[k] ?? '')).join('\t'));
|
|
26
|
+
});
|
|
27
|
+
console.log(`(${rows.length} row(s))`);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async function runOne(client, sql, params = []) {
|
|
31
|
+
const trimmed = sql.trim().toUpperCase();
|
|
32
|
+
const isWrite = /^(INSERT|UPDATE|DELETE|CREATE|DROP|ALTER|REPLACE)\s/.test(trimmed);
|
|
33
|
+
if (isWrite) {
|
|
34
|
+
const result = await client.execute(sql, params);
|
|
35
|
+
console.log('Changes:', result.changes, 'Last ID:', result.lastInsertRowid);
|
|
36
|
+
} else {
|
|
37
|
+
const rows = await client.query(sql, params);
|
|
38
|
+
printResult(rows);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async function interactive() {
|
|
43
|
+
const client = getClient();
|
|
44
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
45
|
+
console.log('Secure DB CLI (interactive). Enter SQL; empty line to run. Type exit to quit.\n');
|
|
46
|
+
let buffer = '';
|
|
47
|
+
const prompt = () => process.stdout.write('> ');
|
|
48
|
+
prompt();
|
|
49
|
+
for await (const line of rl) {
|
|
50
|
+
const trimmed = line.trim();
|
|
51
|
+
if (trimmed.toLowerCase() === 'exit' || trimmed.toLowerCase() === 'quit') break;
|
|
52
|
+
if (trimmed === '') {
|
|
53
|
+
if (buffer.trim()) {
|
|
54
|
+
try {
|
|
55
|
+
await runOne(client, buffer, []);
|
|
56
|
+
} catch (err) {
|
|
57
|
+
console.error(err.message || err);
|
|
58
|
+
}
|
|
59
|
+
buffer = '';
|
|
60
|
+
}
|
|
61
|
+
} else {
|
|
62
|
+
buffer += (buffer ? '\n' : '') + line;
|
|
63
|
+
}
|
|
64
|
+
prompt();
|
|
65
|
+
}
|
|
66
|
+
rl.close();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async function main() {
|
|
70
|
+
const args = process.argv.slice(2);
|
|
71
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
72
|
+
console.log(`
|
|
73
|
+
Usage:
|
|
74
|
+
secure-db Interactive mode (requires SECURE_DB_API_KEY)
|
|
75
|
+
secure-db run "SELECT ..." Run one query
|
|
76
|
+
secure-db run -f file.sql Run SQL from file
|
|
77
|
+
|
|
78
|
+
Environment:
|
|
79
|
+
SECURE_DB_API_KEY API key (required)
|
|
80
|
+
SECURE_DB_API_URL API base URL (default: http://localhost:3000)
|
|
81
|
+
`);
|
|
82
|
+
process.exit(0);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const keyIdx = args.indexOf('--key');
|
|
86
|
+
if (keyIdx !== -1 && args[keyIdx + 1]) {
|
|
87
|
+
process.env.SECURE_DB_API_KEY = args[keyIdx + 1];
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (args[0] === 'run') {
|
|
91
|
+
const client = getClient();
|
|
92
|
+
if (args[1] === '-f' && args[2]) {
|
|
93
|
+
const fs = await import('fs');
|
|
94
|
+
const sql = fs.readFileSync(args[2], 'utf8');
|
|
95
|
+
await runOne(client, sql, []);
|
|
96
|
+
} else if (args[1]) {
|
|
97
|
+
await runOne(client, args[1], []);
|
|
98
|
+
} else {
|
|
99
|
+
console.error('Usage: secure-db run "SQL" or secure-db run -f file.sql');
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
} else {
|
|
103
|
+
await interactive();
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
main().catch((err) => {
|
|
108
|
+
console.error(err.message || err);
|
|
109
|
+
process.exit(1);
|
|
110
|
+
});
|