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.
@@ -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
- #!/usr/bin/env node
2
+
3
3
  import {
4
4
  connect,
5
5
  disconnect,
6
6
  executeQuery,
7
7
  getConnection,
8
8
  testConnection
9
- } from "./chunk-4IGBRCNN.js";
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-4KECNFPA.js");
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
- if (process.env.NODE_ENV === "production") {
335
- const clientDist = path.join(__dirname, "../client");
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
+ };
@@ -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
- if (process.env.NODE_ENV === "production") {
330
- const clientDist = path.join(__dirname, "../client");
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 });
@@ -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
- if (process.env.NODE_ENV === "production") {
330
- const clientDist = path.join(__dirname, "../client");
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.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",