datapeek 0.1.1 → 0.1.2
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/dist/cli/chunk-PTI2CUG6.js +119 -0
- package/dist/cli/index.js +20 -5
- package/dist/cli/mssql-5VFXLOGV.js +18 -0
- package/dist/server/dev.js +17 -2
- package/dist/server/index.js +17 -2
- package/package.json +7 -2
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
// src/server/db/mssql.ts
|
|
5
|
+
import sql from "mssql";
|
|
6
|
+
var pool = null;
|
|
7
|
+
function parseConnectionString(connectionString) {
|
|
8
|
+
const config = {
|
|
9
|
+
server: "",
|
|
10
|
+
database: "",
|
|
11
|
+
options: {
|
|
12
|
+
encrypt: true,
|
|
13
|
+
trustServerCertificate: false,
|
|
14
|
+
enableArithAbort: true
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
const parts = connectionString.split(";");
|
|
18
|
+
for (const part of parts) {
|
|
19
|
+
const [key, ...valueParts] = part.split("=");
|
|
20
|
+
const value = valueParts.join("=").trim();
|
|
21
|
+
const keyLower = key.trim().toLowerCase();
|
|
22
|
+
switch (keyLower) {
|
|
23
|
+
case "server":
|
|
24
|
+
case "data source":
|
|
25
|
+
let serverValue = value;
|
|
26
|
+
if (serverValue.startsWith("tcp:")) {
|
|
27
|
+
serverValue = serverValue.substring(4);
|
|
28
|
+
}
|
|
29
|
+
const [serverHost, serverPort] = serverValue.split(",");
|
|
30
|
+
config.server = serverHost.trim();
|
|
31
|
+
if (serverPort) {
|
|
32
|
+
config.port = parseInt(serverPort.trim(), 10);
|
|
33
|
+
}
|
|
34
|
+
break;
|
|
35
|
+
case "database":
|
|
36
|
+
case "initial catalog":
|
|
37
|
+
config.database = value;
|
|
38
|
+
break;
|
|
39
|
+
case "user id":
|
|
40
|
+
case "userid":
|
|
41
|
+
case "uid":
|
|
42
|
+
config.user = value;
|
|
43
|
+
break;
|
|
44
|
+
case "password":
|
|
45
|
+
case "pwd":
|
|
46
|
+
config.password = value;
|
|
47
|
+
break;
|
|
48
|
+
case "port":
|
|
49
|
+
config.port = parseInt(value, 10);
|
|
50
|
+
break;
|
|
51
|
+
case "encrypt":
|
|
52
|
+
config.options.encrypt = value.toLowerCase() === "true";
|
|
53
|
+
break;
|
|
54
|
+
case "trustservercertificate":
|
|
55
|
+
case "trust server certificate":
|
|
56
|
+
config.options.trustServerCertificate = value.toLowerCase() === "true";
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return config;
|
|
61
|
+
}
|
|
62
|
+
async function testConnection(config) {
|
|
63
|
+
const testPool = typeof config === "string" ? new sql.ConnectionPool(parseConnectionString(config)) : new sql.ConnectionPool(config);
|
|
64
|
+
try {
|
|
65
|
+
await testPool.connect();
|
|
66
|
+
await testPool.close();
|
|
67
|
+
} catch (error) {
|
|
68
|
+
throw error;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async function connect(config) {
|
|
72
|
+
await disconnect();
|
|
73
|
+
const connectionConfig = typeof config === "string" ? parseConnectionString(config) : config;
|
|
74
|
+
pool = new sql.ConnectionPool(connectionConfig);
|
|
75
|
+
try {
|
|
76
|
+
await pool.connect();
|
|
77
|
+
} catch (error) {
|
|
78
|
+
pool = null;
|
|
79
|
+
throw error;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
async function disconnect() {
|
|
83
|
+
if (pool) {
|
|
84
|
+
try {
|
|
85
|
+
await pool.close();
|
|
86
|
+
} catch (error) {
|
|
87
|
+
}
|
|
88
|
+
pool = null;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function getConnection() {
|
|
92
|
+
return pool;
|
|
93
|
+
}
|
|
94
|
+
async function executeQuery(query, parameters) {
|
|
95
|
+
if (!pool || !pool.connected) {
|
|
96
|
+
throw new Error("Not connected to database");
|
|
97
|
+
}
|
|
98
|
+
const request = pool.request();
|
|
99
|
+
if (parameters) {
|
|
100
|
+
for (const param of parameters) {
|
|
101
|
+
if (param.type) {
|
|
102
|
+
request.input(param.name, param.type, param.value);
|
|
103
|
+
} else {
|
|
104
|
+
request.input(param.name, param.value);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
const result = await request.query(query);
|
|
109
|
+
return result.recordset || [];
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export {
|
|
113
|
+
parseConnectionString,
|
|
114
|
+
testConnection,
|
|
115
|
+
connect,
|
|
116
|
+
disconnect,
|
|
117
|
+
getConnection,
|
|
118
|
+
executeQuery
|
|
119
|
+
};
|
package/dist/cli/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
2
|
+
|
|
3
3
|
import {
|
|
4
4
|
connect,
|
|
5
5
|
disconnect,
|
|
6
6
|
executeQuery,
|
|
7
7
|
getConnection,
|
|
8
8
|
testConnection
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-PTI2CUG6.js";
|
|
10
10
|
|
|
11
11
|
// src/cli/index.ts
|
|
12
12
|
import { Command } from "commander";
|
|
@@ -16,6 +16,7 @@ import express from "express";
|
|
|
16
16
|
import cors from "cors";
|
|
17
17
|
import path from "path";
|
|
18
18
|
import { fileURLToPath } from "url";
|
|
19
|
+
import { existsSync } from "fs";
|
|
19
20
|
|
|
20
21
|
// src/server/routes/connection.ts
|
|
21
22
|
import { Router } from "express";
|
|
@@ -89,7 +90,7 @@ connectionRoutes.delete("/", async (req, res) => {
|
|
|
89
90
|
});
|
|
90
91
|
connectionRoutes.get("/status", async (req, res) => {
|
|
91
92
|
try {
|
|
92
|
-
const { getConnection: getConnection2, executeQuery: executeQuery2 } = await import("./mssql-
|
|
93
|
+
const { getConnection: getConnection2, executeQuery: executeQuery2 } = await import("./mssql-5VFXLOGV.js");
|
|
93
94
|
const pool = getConnection2();
|
|
94
95
|
if (pool && pool.connected) {
|
|
95
96
|
try {
|
|
@@ -331,8 +332,9 @@ async function startServer(port, connectionString) {
|
|
|
331
332
|
app.use("/api/connect", connectionRoutes);
|
|
332
333
|
app.use("/api/tables", tableRoutes);
|
|
333
334
|
app.use("/api/query", queryRoutes);
|
|
334
|
-
|
|
335
|
-
|
|
335
|
+
const clientDist = path.join(__dirname, "../client");
|
|
336
|
+
const clientExists = existsSync(clientDist) && existsSync(path.join(clientDist, "index.html"));
|
|
337
|
+
if (clientExists) {
|
|
336
338
|
app.use(express.static(clientDist));
|
|
337
339
|
app.get("*", (req, res) => {
|
|
338
340
|
if (req.path.startsWith("/api")) {
|
|
@@ -340,6 +342,19 @@ async function startServer(port, connectionString) {
|
|
|
340
342
|
}
|
|
341
343
|
res.sendFile(path.join(clientDist, "index.html"));
|
|
342
344
|
});
|
|
345
|
+
} else {
|
|
346
|
+
app.get("/", (req, res) => {
|
|
347
|
+
res.send(`
|
|
348
|
+
<html>
|
|
349
|
+
<head><title>Datapeek</title></head>
|
|
350
|
+
<body>
|
|
351
|
+
<h1>Datapeek Server</h1>
|
|
352
|
+
<p>Server is running. Please build the client with: npm run build:client</p>
|
|
353
|
+
<p>API available at: <a href="/api/health">/api/health</a></p>
|
|
354
|
+
</body>
|
|
355
|
+
</html>
|
|
356
|
+
`);
|
|
357
|
+
});
|
|
343
358
|
}
|
|
344
359
|
app.get("/api/health", (req, res) => {
|
|
345
360
|
res.json({ status: "ok", hasConnectionString: !!providedConnectionString });
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
connect,
|
|
5
|
+
disconnect,
|
|
6
|
+
executeQuery,
|
|
7
|
+
getConnection,
|
|
8
|
+
parseConnectionString,
|
|
9
|
+
testConnection
|
|
10
|
+
} from "./chunk-PTI2CUG6.js";
|
|
11
|
+
export {
|
|
12
|
+
connect,
|
|
13
|
+
disconnect,
|
|
14
|
+
executeQuery,
|
|
15
|
+
getConnection,
|
|
16
|
+
parseConnectionString,
|
|
17
|
+
testConnection
|
|
18
|
+
};
|
package/dist/server/dev.js
CHANGED
|
@@ -11,6 +11,7 @@ import express from "express";
|
|
|
11
11
|
import cors from "cors";
|
|
12
12
|
import path from "path";
|
|
13
13
|
import { fileURLToPath } from "url";
|
|
14
|
+
import { existsSync } from "fs";
|
|
14
15
|
|
|
15
16
|
// src/server/routes/connection.ts
|
|
16
17
|
import { Router } from "express";
|
|
@@ -326,8 +327,9 @@ async function startServer(port2, connectionString2) {
|
|
|
326
327
|
app.use("/api/connect", connectionRoutes);
|
|
327
328
|
app.use("/api/tables", tableRoutes);
|
|
328
329
|
app.use("/api/query", queryRoutes);
|
|
329
|
-
|
|
330
|
-
|
|
330
|
+
const clientDist = path.join(__dirname, "../client");
|
|
331
|
+
const clientExists = existsSync(clientDist) && existsSync(path.join(clientDist, "index.html"));
|
|
332
|
+
if (clientExists) {
|
|
331
333
|
app.use(express.static(clientDist));
|
|
332
334
|
app.get("*", (req, res) => {
|
|
333
335
|
if (req.path.startsWith("/api")) {
|
|
@@ -335,6 +337,19 @@ async function startServer(port2, connectionString2) {
|
|
|
335
337
|
}
|
|
336
338
|
res.sendFile(path.join(clientDist, "index.html"));
|
|
337
339
|
});
|
|
340
|
+
} else {
|
|
341
|
+
app.get("/", (req, res) => {
|
|
342
|
+
res.send(`
|
|
343
|
+
<html>
|
|
344
|
+
<head><title>Datapeek</title></head>
|
|
345
|
+
<body>
|
|
346
|
+
<h1>Datapeek Server</h1>
|
|
347
|
+
<p>Server is running. Please build the client with: npm run build:client</p>
|
|
348
|
+
<p>API available at: <a href="/api/health">/api/health</a></p>
|
|
349
|
+
</body>
|
|
350
|
+
</html>
|
|
351
|
+
`);
|
|
352
|
+
});
|
|
338
353
|
}
|
|
339
354
|
app.get("/api/health", (req, res) => {
|
|
340
355
|
res.json({ status: "ok", hasConnectionString: !!providedConnectionString });
|
package/dist/server/index.js
CHANGED
|
@@ -11,6 +11,7 @@ import express from "express";
|
|
|
11
11
|
import cors from "cors";
|
|
12
12
|
import path from "path";
|
|
13
13
|
import { fileURLToPath } from "url";
|
|
14
|
+
import { existsSync } from "fs";
|
|
14
15
|
|
|
15
16
|
// src/server/routes/connection.ts
|
|
16
17
|
import { Router } from "express";
|
|
@@ -326,8 +327,9 @@ async function startServer(port, connectionString) {
|
|
|
326
327
|
app.use("/api/connect", connectionRoutes);
|
|
327
328
|
app.use("/api/tables", tableRoutes);
|
|
328
329
|
app.use("/api/query", queryRoutes);
|
|
329
|
-
|
|
330
|
-
|
|
330
|
+
const clientDist = path.join(__dirname, "../client");
|
|
331
|
+
const clientExists = existsSync(clientDist) && existsSync(path.join(clientDist, "index.html"));
|
|
332
|
+
if (clientExists) {
|
|
331
333
|
app.use(express.static(clientDist));
|
|
332
334
|
app.get("*", (req, res) => {
|
|
333
335
|
if (req.path.startsWith("/api")) {
|
|
@@ -335,6 +337,19 @@ async function startServer(port, connectionString) {
|
|
|
335
337
|
}
|
|
336
338
|
res.sendFile(path.join(clientDist, "index.html"));
|
|
337
339
|
});
|
|
340
|
+
} else {
|
|
341
|
+
app.get("/", (req, res) => {
|
|
342
|
+
res.send(`
|
|
343
|
+
<html>
|
|
344
|
+
<head><title>Datapeek</title></head>
|
|
345
|
+
<body>
|
|
346
|
+
<h1>Datapeek Server</h1>
|
|
347
|
+
<p>Server is running. Please build the client with: npm run build:client</p>
|
|
348
|
+
<p>API available at: <a href="/api/health">/api/health</a></p>
|
|
349
|
+
</body>
|
|
350
|
+
</html>
|
|
351
|
+
`);
|
|
352
|
+
});
|
|
338
353
|
}
|
|
339
354
|
app.get("/api/health", (req, res) => {
|
|
340
355
|
res.json({ status: "ok", hasConnectionString: !!providedConnectionString });
|
package/package.json
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "datapeek",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "A local SQL database browser CLI tool",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"datapeek": "./dist/cli/index.js"
|
|
8
8
|
},
|
|
9
|
+
"exports": {
|
|
10
|
+
".": "./dist/server/index.js",
|
|
11
|
+
"./cli": "./dist/cli/index.js"
|
|
12
|
+
},
|
|
9
13
|
"engines": {
|
|
10
14
|
"node": ">=18.0.0"
|
|
11
15
|
},
|
|
@@ -22,7 +26,8 @@
|
|
|
22
26
|
"build": "npm run build:client && npm run build:server",
|
|
23
27
|
"build:client": "vite build",
|
|
24
28
|
"build:server": "tsup",
|
|
25
|
-
"prepublishOnly": "npm run build"
|
|
29
|
+
"prepublishOnly": "npm run build",
|
|
30
|
+
"postinstall": "chmod +x dist/cli/index.js || true"
|
|
26
31
|
},
|
|
27
32
|
"keywords": [
|
|
28
33
|
"sql",
|