fakebase-studio 1.0.4 → 1.0.6
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/README.md +5 -3
- package/package.json +1 -1
- package/server/dist/db.d.ts +4 -0
- package/server/dist/db.d.ts.map +1 -1
- package/server/dist/db.js +43 -0
- package/server/dist/db.js.map +1 -1
- package/server/dist/index.d.ts.map +1 -1
- package/server/dist/index.js +10 -0
- package/server/dist/index.js.map +1 -1
- package/server/dist/routes/connect.d.ts.map +1 -1
- package/server/dist/routes/connect.js +5 -2
- package/server/dist/routes/connect.js.map +1 -1
- package/server/dist/routes/index.d.ts.map +1 -1
- package/server/dist/routes/index.js +4 -0
- package/server/dist/routes/index.js.map +1 -1
- package/server/dist/routes/queries.d.ts +3 -0
- package/server/dist/routes/queries.d.ts.map +1 -0
- package/server/dist/routes/queries.js +79 -0
- package/server/dist/routes/queries.js.map +1 -0
- package/server/dist/routes/sql.d.ts +3 -0
- package/server/dist/routes/sql.d.ts.map +1 -0
- package/server/dist/routes/sql.js +43 -0
- package/server/dist/routes/sql.js.map +1 -0
- package/server/dist/services/connections.service.d.ts.map +1 -1
- package/server/dist/services/connections.service.js +3 -2
- package/server/dist/services/connections.service.js.map +1 -1
- package/server/dist/services/queries.service.d.ts +11 -0
- package/server/dist/services/queries.service.d.ts.map +1 -0
- package/server/dist/services/queries.service.js +76 -0
- package/server/dist/services/queries.service.js.map +1 -0
- package/server/dist/types/api.d.ts +8 -0
- package/server/dist/types/api.d.ts.map +1 -1
- package/server/dist/utils/errors.d.ts.map +1 -1
- package/server/dist/utils/errors.js +0 -4
- package/server/dist/utils/errors.js.map +1 -1
- package/ui/dist/assets/index-C9faKqyl.css +1 -0
- package/ui/dist/assets/index-CTt9CUvp.js +73 -0
- package/ui/dist/favicon.ico +0 -0
- package/ui/dist/index.html +11 -4
- package/ui/dist/assets/index-3A4u6lT6.css +0 -1
- package/ui/dist/assets/index-g7U-HL5c.js +0 -71
package/README.md
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
## What’s Fakebase?
|
|
2
2
|
|
|
3
|
-
Fakebase is a lightweight PostgreSQL browser built for developers who
|
|
3
|
+
Fakebase is a lightweight PostgreSQL browser built for developers who want to see and manage what’s going on in their database - fast. No setup, no dashboards, no accounts. Connect to any PostgreSQL instance and instantly explore your tables, relationships, indexes, and schema structure in a clean, modern interface. And when you need to take action, Fakebase gives you the essentials: a built-in SQL editor and simple CRUD tools. Fakebase takes responsibility for being the simple tool: open it, connect, understand your database - and manage it with ease.
|
|
4
4
|
|
|
5
|
-
Fakebase focuses on clarity. It gives you a visual overview of your schema with interactive table relationships, lets you browse table data in a structured grid, inspect foreign keys and indexes, and understand how everything connects. It doesn’t try to replace your infrastructure, migrate your schema, or sit between you and your database. It simply connects directly and shows you what’s there - clearly and
|
|
5
|
+
Fakebase focuses on clarity. It gives you a visual overview of your schema with interactive table relationships, lets you browse and edit table data in a structured grid, inspect foreign keys and indexes, and understand how everything connects. It doesn’t try to replace your infrastructure, migrate your schema, or sit between you and your database. It simply connects directly and shows you what’s there - clearly, reliably, and with just enough power to work efficiently.
|
|
6
6
|
|
|
7
|
-
Getting started takes one command: **npx fakebase-studio@latest**. The server starts locally and opens in your browser. Paste in your PostgreSQL connection string and start exploring. No accounts, no cloud sync, no hidden layers. Just you and your database
|
|
7
|
+
Getting started takes one command: **npx fakebase-studio@latest**. The server starts locally and opens in your browser. Paste in your PostgreSQL connection string and start exploring. No accounts, no cloud sync, no hidden layers. Just you and your database.
|
|
8
|
+
|
|
9
|
+
Visit us at https://fakebase.studio
|
|
8
10
|
|
|
9
11
|
## Quick Start
|
|
10
12
|
|
package/package.json
CHANGED
package/server/dist/db.d.ts
CHANGED
|
@@ -15,4 +15,8 @@ export declare function connectToDatabase(connectionString: string): Promise<any
|
|
|
15
15
|
* @deprecated Use getOrCreatePool(connectionString) instead.
|
|
16
16
|
*/
|
|
17
17
|
export declare function getDb(): Pool;
|
|
18
|
+
/**
|
|
19
|
+
* Close all cached pools and the legacy pool. Safe to call multiple times (no-op after first).
|
|
20
|
+
*/
|
|
21
|
+
export declare function closeAllPools(): Promise<void>;
|
|
18
22
|
//# sourceMappingURL=db.d.ts.map
|
package/server/dist/db.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../db.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../db.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAkB1B;;;GAGG;AACH,wBAAgB,eAAe,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAgC9D;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,gBAAgB,EAAE,MAAM,gBAyC/D;AAED;;;GAGG;AACH,wBAAgB,KAAK,SAGpB;AAED;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAqBnD"}
|
package/server/dist/db.js
CHANGED
|
@@ -3,18 +3,34 @@ import { Pool } from "pg";
|
|
|
3
3
|
const connectionPools = new Map();
|
|
4
4
|
// Legacy single pool for backward compatibility with connect endpoint
|
|
5
5
|
let pool = null;
|
|
6
|
+
let closed = false;
|
|
7
|
+
const POOL_CONFIG = {
|
|
8
|
+
max: 10,
|
|
9
|
+
idleTimeoutMillis: 30_000,
|
|
10
|
+
connectionTimeoutMillis: 5000,
|
|
11
|
+
};
|
|
12
|
+
const MAX_CACHED_POOLS = 20;
|
|
6
13
|
/**
|
|
7
14
|
* Get or create a connection pool for the given connection string.
|
|
8
15
|
* Pools are cached and reused for the same connection string.
|
|
9
16
|
*/
|
|
10
17
|
export function getOrCreatePool(connectionString) {
|
|
11
18
|
if (!connectionPools.has(connectionString)) {
|
|
19
|
+
if (connectionPools.size >= MAX_CACHED_POOLS) {
|
|
20
|
+
const firstKey = connectionPools.keys().next().value;
|
|
21
|
+
if (firstKey !== undefined) {
|
|
22
|
+
const oldPool = connectionPools.get(firstKey);
|
|
23
|
+
connectionPools.delete(firstKey);
|
|
24
|
+
oldPool?.end().catch(() => { });
|
|
25
|
+
}
|
|
26
|
+
}
|
|
12
27
|
// Parse connection string to check if it's Supabase or needs SSL
|
|
13
28
|
const isSupabase = connectionString.includes("supabase.co");
|
|
14
29
|
const newPool = new Pool({
|
|
15
30
|
connectionString,
|
|
16
31
|
// Supabase requires SSL connections
|
|
17
32
|
ssl: isSupabase ? { rejectUnauthorized: false } : undefined,
|
|
33
|
+
...POOL_CONFIG,
|
|
18
34
|
});
|
|
19
35
|
// Handle pool errors
|
|
20
36
|
newPool.on("error", (err) => {
|
|
@@ -49,6 +65,7 @@ export async function connectToDatabase(connectionString) {
|
|
|
49
65
|
connectionString,
|
|
50
66
|
// Supabase requires SSL connections
|
|
51
67
|
ssl: isSupabase ? { rejectUnauthorized: false } : undefined,
|
|
68
|
+
...POOL_CONFIG,
|
|
52
69
|
});
|
|
53
70
|
try {
|
|
54
71
|
// Test connection
|
|
@@ -80,4 +97,30 @@ export function getDb() {
|
|
|
80
97
|
throw new Error("Database not connected");
|
|
81
98
|
return pool;
|
|
82
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* Close all cached pools and the legacy pool. Safe to call multiple times (no-op after first).
|
|
102
|
+
*/
|
|
103
|
+
export async function closeAllPools() {
|
|
104
|
+
if (closed)
|
|
105
|
+
return;
|
|
106
|
+
closed = true;
|
|
107
|
+
for (const [, p] of connectionPools) {
|
|
108
|
+
try {
|
|
109
|
+
await p.end();
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
console.warn("Error closing pool:", err);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
connectionPools.clear();
|
|
116
|
+
if (pool) {
|
|
117
|
+
try {
|
|
118
|
+
await pool.end();
|
|
119
|
+
}
|
|
120
|
+
catch (err) {
|
|
121
|
+
console.warn("Error closing legacy pool:", err);
|
|
122
|
+
}
|
|
123
|
+
pool = null;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
83
126
|
//# sourceMappingURL=db.js.map
|
package/server/dist/db.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.js","sourceRoot":"","sources":["../db.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAE1B,+CAA+C;AAC/C,MAAM,eAAe,GAAG,IAAI,GAAG,EAAgB,CAAC;AAEhD,sEAAsE;AACtE,IAAI,IAAI,GAAgB,IAAI,CAAC;AAE7B;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,gBAAwB;IACtD,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAC3C,iEAAiE;QACjE,MAAM,UAAU,GAAG,gBAAgB,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;QAE5D,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC;YACvB,gBAAgB;YAChB,oCAAoC;YACpC,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS;
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../db.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAWA,wBAAsB,WAAW,kBAmEhC"}
|
package/server/dist/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import fastifyCors from "@fastify/cors";
|
|
|
4
4
|
import path from "path";
|
|
5
5
|
import { fileURLToPath } from "url";
|
|
6
6
|
import { registerRoutes } from "./routes/index.js";
|
|
7
|
+
import { closeAllPools } from "./db.js";
|
|
7
8
|
const __filename = fileURLToPath(import.meta.url);
|
|
8
9
|
const __dirname = path.dirname(__filename);
|
|
9
10
|
export async function startServer() {
|
|
@@ -12,6 +13,9 @@ export async function startServer() {
|
|
|
12
13
|
level: "error",
|
|
13
14
|
},
|
|
14
15
|
});
|
|
16
|
+
app.addHook("onClose", async () => {
|
|
17
|
+
await closeAllPools();
|
|
18
|
+
});
|
|
15
19
|
// Global error handler
|
|
16
20
|
app.setErrorHandler((error, request, reply) => {
|
|
17
21
|
request.log.error(error, "Unhandled error");
|
|
@@ -55,6 +59,12 @@ export async function startServer() {
|
|
|
55
59
|
const host = process.env.HOST || "0.0.0.0";
|
|
56
60
|
await app.listen({ port, host });
|
|
57
61
|
console.log(`Fakebase Studio running on http://localhost:${port}`);
|
|
62
|
+
process.once("SIGINT", () => {
|
|
63
|
+
app.close().then(() => process.exit(0)).catch(() => process.exit(1));
|
|
64
|
+
});
|
|
65
|
+
process.once("SIGTERM", () => {
|
|
66
|
+
app.close().then(() => process.exit(0)).catch(() => process.exit(1));
|
|
67
|
+
});
|
|
58
68
|
}
|
|
59
69
|
// Start server when this file is executed directly
|
|
60
70
|
startServer().catch((error) => {
|
package/server/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAC5C,OAAO,WAAW,MAAM,eAAe,CAAC;AACxC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAC5C,OAAO,WAAW,MAAM,eAAe,CAAC;AACxC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAExC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAE3C,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,GAAG,GAAG,OAAO,CAAC;QAClB,MAAM,EAAE;YACN,KAAK,EAAE,OAAO;SACf;KACF,CAAC,CAAC;IAEH,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;QAChC,MAAM,aAAa,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,uBAAuB;IACvB,GAAG,CAAC,eAAe,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QAC5C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC;QAC5C,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACrB,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB;SACxE,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,8BAA8B;IAC9B,MAAM,GAAG,CAAC,QAAQ,CAAC,WAAW,EAAE;QAC9B,MAAM,EAAE,IAAI;KACb,CAAC,CAAC;IAEH,sBAAsB;IACtB,MAAM,cAAc,CAAC,GAAG,CAAC,CAAC;IAE1B,mCAAmC;IACnC,+DAA+D;IAC/D,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,CAAC;IAC3D,MAAM,UAAU,GAAG,YAAY;QAC7B,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC;QACrC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IAEvC,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,GAAG,CAAC,QAAQ,CAAC,aAAa,EAAE;YAChC,IAAI,EAAE,UAAU;YAChB,QAAQ,EAAE,KAAK,EAAE,qCAAqC;SACvD,CAAC,CAAC;QAEH,2EAA2E;QAC3E,GAAG,CAAC,kBAAkB,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE;YACxC,4BAA4B;YAC5B,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBACpC,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;oBAC5B,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,WAAW;iBACnB,CAAC,CAAC;YACL,CAAC;YACD,8CAA8C;YAC9C,OAAO,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;IACL,CAAC;IAED,eAAe;IACf,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;IAC9C,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,SAAS,CAAC;IAC3C,MAAM,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IACjC,OAAO,CAAC,GAAG,CAAC,+CAA+C,IAAI,EAAE,CAAC,CAAC;IAEnE,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE;QAC1B,GAAG,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE;QAC3B,GAAG,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;AACL,CAAC;AAED,mDAAmD;AACnD,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IAC5B,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;IAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../routes/connect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAK/C;;GAEG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../routes/connect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAK/C;;GAEG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA4CvE"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getOrCreatePool } from "../db.js";
|
|
2
2
|
import { sendError, sendSuccess } from "../utils/errors.js";
|
|
3
3
|
/**
|
|
4
4
|
* Register connection-related routes.
|
|
@@ -25,7 +25,10 @@ export async function connectRoutes(app) {
|
|
|
25
25
|
return sendError(reply, 400, new Error("Connection string is required"));
|
|
26
26
|
}
|
|
27
27
|
try {
|
|
28
|
-
const
|
|
28
|
+
const pool = getOrCreatePool(connectionString);
|
|
29
|
+
await pool.query("SELECT 1");
|
|
30
|
+
const result = await pool.query("SELECT current_database() as name");
|
|
31
|
+
const databaseName = result.rows[0].name;
|
|
29
32
|
const data = { databaseName };
|
|
30
33
|
return sendSuccess(reply, data);
|
|
31
34
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connect.js","sourceRoot":"","sources":["../../routes/connect.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"connect.js","sourceRoot":"","sources":["../../routes/connect.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAG5D;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,GAAoB;IACtD,gBAAgB;IAChB,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,IAAI,EAAE;QAC9B,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,mBAAmB,EAAE,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,sBAAsB;IACtB,GAAG,CAAC,IAAI,CACN,cAAc,EACd;QACE,MAAM,EAAE;YACN,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,CAAC,kBAAkB,CAAC;gBAC9B,UAAU,EAAE;oBACV,gBAAgB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;iBACrC;aACF;SACF;KACF,EACD,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QACvB,MAAM,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;QAE1C,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,OAAO,SAAS,CACd,KAAK,EACL,GAAG,EACH,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAC3C,CAAC;QACJ,CAAC;QAED,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,eAAe,CAAC,gBAAgB,CAAC,CAAC;YAC/C,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YAC7B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;YACrE,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAEzC,MAAM,IAAI,GAAuB,EAAE,YAAY,EAAE,CAAC;YAClD,OAAO,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAClC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,SAAS,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;QACtC,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../routes/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../routes/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAS/C;;GAEG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAQxE"}
|
|
@@ -3,6 +3,8 @@ import { schemaRoutes } from "./schema.js";
|
|
|
3
3
|
import { connectionsRoutes } from "./connections.js";
|
|
4
4
|
import { tableDataRoutes } from "./tables.js";
|
|
5
5
|
import { indexesRoutes } from "./indexes.js";
|
|
6
|
+
import { sqlRoutes } from "./sql.js";
|
|
7
|
+
import { queriesRoutes } from "./queries.js";
|
|
6
8
|
/**
|
|
7
9
|
* Register all API routes.
|
|
8
10
|
*/
|
|
@@ -12,5 +14,7 @@ export async function registerRoutes(app) {
|
|
|
12
14
|
await connectionsRoutes(app);
|
|
13
15
|
await tableDataRoutes(app);
|
|
14
16
|
await indexesRoutes(app);
|
|
17
|
+
await sqlRoutes(app);
|
|
18
|
+
await queriesRoutes(app);
|
|
15
19
|
}
|
|
16
20
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../routes/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,GAAoB;IACvD,MAAM,aAAa,CAAC,GAAG,CAAC,CAAC;IACzB,MAAM,YAAY,CAAC,GAAG,CAAC,CAAC;IACxB,MAAM,iBAAiB,CAAC,GAAG,CAAC,CAAC;IAC7B,MAAM,eAAe,CAAC,GAAG,CAAC,CAAC;IAC3B,MAAM,aAAa,CAAC,GAAG,CAAC,CAAC;AAC3B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../routes/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,GAAoB;IACvD,MAAM,aAAa,CAAC,GAAG,CAAC,CAAC;IACzB,MAAM,YAAY,CAAC,GAAG,CAAC,CAAC;IACxB,MAAM,iBAAiB,CAAC,GAAG,CAAC,CAAC;IAC7B,MAAM,eAAe,CAAC,GAAG,CAAC,CAAC;IAC3B,MAAM,aAAa,CAAC,GAAG,CAAC,CAAC;IACzB,MAAM,SAAS,CAAC,GAAG,CAAC,CAAC;IACrB,MAAM,aAAa,CAAC,GAAG,CAAC,CAAC;AAC3B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../../routes/queries.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAS/C,wBAAsB,aAAa,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAwFvE"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { loadQueries, saveQuery, removeQueryById, updateQueryName, } from "../services/queries.service.js";
|
|
2
|
+
import { sendError } from "../utils/errors.js";
|
|
3
|
+
export async function queriesRoutes(app) {
|
|
4
|
+
app.get("/api/queries", async (_request, reply) => {
|
|
5
|
+
try {
|
|
6
|
+
const queries = await loadQueries();
|
|
7
|
+
return reply.send({ success: true, data: queries });
|
|
8
|
+
}
|
|
9
|
+
catch (error) {
|
|
10
|
+
return sendError(reply, 500, error);
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
app.post("/api/queries", {
|
|
14
|
+
schema: {
|
|
15
|
+
body: {
|
|
16
|
+
type: "object",
|
|
17
|
+
required: ["name", "sql"],
|
|
18
|
+
properties: {
|
|
19
|
+
id: { type: "string" },
|
|
20
|
+
name: { type: "string" },
|
|
21
|
+
sql: { type: "string" },
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
}, async (request, reply) => {
|
|
26
|
+
const { id = null, name, sql } = request.body;
|
|
27
|
+
try {
|
|
28
|
+
const query = await saveQuery(id, name, sql);
|
|
29
|
+
return reply.send({ success: true, data: query });
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
return sendError(reply, 500, error);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
app.delete("/api/queries/:id", {
|
|
36
|
+
schema: {
|
|
37
|
+
params: {
|
|
38
|
+
type: "object",
|
|
39
|
+
required: ["id"],
|
|
40
|
+
properties: { id: { type: "string" } },
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
}, async (request, reply) => {
|
|
44
|
+
const { id } = request.params;
|
|
45
|
+
try {
|
|
46
|
+
const removed = await removeQueryById(id);
|
|
47
|
+
if (!removed)
|
|
48
|
+
return sendError(reply, 404, new Error("Query not found"));
|
|
49
|
+
return reply.send({ success: true });
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
return sendError(reply, 500, error);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
app.patch("/api/queries", {
|
|
56
|
+
schema: {
|
|
57
|
+
body: {
|
|
58
|
+
type: "object",
|
|
59
|
+
required: ["id", "name"],
|
|
60
|
+
properties: {
|
|
61
|
+
id: { type: "string" },
|
|
62
|
+
name: { type: "string" },
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
}, async (request, reply) => {
|
|
67
|
+
const { id, name } = request.body;
|
|
68
|
+
try {
|
|
69
|
+
const query = await updateQueryName(id, name);
|
|
70
|
+
if (!query)
|
|
71
|
+
return sendError(reply, 404, new Error("Query not found"));
|
|
72
|
+
return reply.send({ success: true, data: query });
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
return sendError(reply, 500, error);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=queries.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queries.js","sourceRoot":"","sources":["../../routes/queries.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql.d.ts","sourceRoot":"","sources":["../../routes/sql.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAK/C,wBAAsB,SAAS,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA8CnE"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { getOrCreatePool } from "../db.js";
|
|
2
|
+
import { sendError, sendSuccess } from "../utils/errors.js";
|
|
3
|
+
export async function sqlRoutes(app) {
|
|
4
|
+
app.post("/api/sql", {
|
|
5
|
+
schema: {
|
|
6
|
+
body: {
|
|
7
|
+
type: "object",
|
|
8
|
+
required: ["connectionString", "sql"],
|
|
9
|
+
properties: {
|
|
10
|
+
connectionString: { type: "string" },
|
|
11
|
+
sql: { type: "string" },
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
}, async (request, reply) => {
|
|
16
|
+
const { connectionString, sql } = request.body;
|
|
17
|
+
if (!connectionString) {
|
|
18
|
+
return sendError(reply, 400, new Error("Connection string is required"));
|
|
19
|
+
}
|
|
20
|
+
if (!sql.trim()) {
|
|
21
|
+
return sendError(reply, 400, new Error("SQL query is required"));
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
const pool = getOrCreatePool(connectionString);
|
|
25
|
+
const result = await pool.query(sql);
|
|
26
|
+
const data = {
|
|
27
|
+
rows: result.rows,
|
|
28
|
+
rowCount: result.rowCount ?? result.rows.length,
|
|
29
|
+
};
|
|
30
|
+
return sendSuccess(reply, data);
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
const pgError = error;
|
|
34
|
+
return reply.status(200).send({
|
|
35
|
+
success: false,
|
|
36
|
+
error: pgError.message,
|
|
37
|
+
code: pgError.code,
|
|
38
|
+
detail: pgError.detail,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=sql.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql.js","sourceRoot":"","sources":["../../routes/sql.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAG5D,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,GAAoB;IAClD,GAAG,CAAC,IAAI,CACN,UAAU,EACV;QACE,MAAM,EAAE;YACN,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,CAAC,kBAAkB,EAAE,KAAK,CAAC;gBACrC,UAAU,EAAE;oBACV,gBAAgB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBACpC,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;iBACxB;aACF;SACF;KACF,EACD,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QACvB,MAAM,EAAE,gBAAgB,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;QAE/C,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,OAAO,SAAS,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC,CAAC;QAC3E,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;YAChB,OAAO,SAAS,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC,CAAC;QACnE,CAAC;QAED,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,eAAe,CAAC,gBAAgB,CAAC,CAAC;YAC/C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAErC,MAAM,IAAI,GAAmB;gBAC3B,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM;aAChD,CAAC;YACF,OAAO,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAClC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,KAAmD,CAAC;YACpE,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBAC5B,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,OAAO,CAAC,OAAO;gBACtB,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,MAAM,EAAE,OAAO,CAAC,MAAM;aACvB,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connections.service.d.ts","sourceRoot":"","sources":["../../services/connections.service.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,gBAAgB,EAAE,MAAM,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,gBAAgB,EAAE,CAAC;CACjC;AAsCD;;;GAGG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAgBlE;AAUD;;GAEG;AACH,wBAAsB,cAAc,CAClC,gBAAgB,EAAE,MAAM,EACxB,OAAO,GAAE,OAAe,EACxB,YAAY,CAAC,EAAE,MAAM,EACrB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,gBAAgB,CAAC,
|
|
1
|
+
{"version":3,"file":"connections.service.d.ts","sourceRoot":"","sources":["../../services/connections.service.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,gBAAgB,EAAE,MAAM,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,gBAAgB,EAAE,CAAC;CACjC;AAsCD;;;GAGG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAgBlE;AAUD;;GAEG;AACH,wBAAsB,cAAc,CAClC,gBAAgB,EAAE,MAAM,EACxB,OAAO,GAAE,OAAe,EACxB,YAAY,CAAC,EAAE,MAAM,EACrB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,gBAAgB,CAAC,CAqC3B;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CASvE;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,gBAAgB,EAAE,MAAM,EACxB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAalC"}
|
|
@@ -70,10 +70,11 @@ export async function saveConnection(connectionString, success = false, database
|
|
|
70
70
|
// Check if connection string already exists
|
|
71
71
|
const existingIndex = config.connections.findIndex((conn) => conn.connectionString === connectionString);
|
|
72
72
|
const existing = existingIndex >= 0 ? config.connections[existingIndex] : null;
|
|
73
|
+
const resolvedName = name?.trim() || existing?.name?.trim() || "Unnamed";
|
|
73
74
|
const connectionConfig = {
|
|
74
75
|
id: existing?.id ?? crypto.randomUUID(),
|
|
75
76
|
connectionString,
|
|
76
|
-
name:
|
|
77
|
+
name: resolvedName,
|
|
77
78
|
timestamp: existing?.timestamp ?? Date.now(),
|
|
78
79
|
lastUsed: Date.now(),
|
|
79
80
|
success,
|
|
@@ -84,7 +85,7 @@ export async function saveConnection(connectionString, success = false, database
|
|
|
84
85
|
...existing,
|
|
85
86
|
...connectionConfig,
|
|
86
87
|
id: existing.id,
|
|
87
|
-
name:
|
|
88
|
+
name: resolvedName,
|
|
88
89
|
};
|
|
89
90
|
}
|
|
90
91
|
else {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connections.service.js","sourceRoot":"","sources":["../../services/connections.service.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"connections.service.js","sourceRoot":"","sources":["../../services/connections.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface SavedQuery {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
sql: string;
|
|
5
|
+
updatedAt: number;
|
|
6
|
+
}
|
|
7
|
+
export declare function loadQueries(): Promise<SavedQuery[]>;
|
|
8
|
+
export declare function saveQuery(id: string | null, name: string, sql: string): Promise<SavedQuery>;
|
|
9
|
+
export declare function removeQueryById(id: string): Promise<boolean>;
|
|
10
|
+
export declare function updateQueryName(id: string, name: string): Promise<SavedQuery | null>;
|
|
11
|
+
//# sourceMappingURL=queries.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queries.service.d.ts","sourceRoot":"","sources":["../../services/queries.service.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;CACnB;AASD,wBAAsB,WAAW,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAkBzD;AAWD,wBAAsB,SAAS,CAC7B,EAAE,EAAE,MAAM,GAAG,IAAI,EACjB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,UAAU,CAAC,CA4BrB;AAED,wBAAsB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAMlE;AAED,wBAAsB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAQ1F"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import fs from "fs/promises";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import os from "os";
|
|
4
|
+
import crypto from "crypto";
|
|
5
|
+
const CONFIG_DIR = path.join(os.homedir(), ".fakebase-studio");
|
|
6
|
+
const QUERIES_FILE = path.join(CONFIG_DIR, "queries.json");
|
|
7
|
+
async function ensureConfigDir() {
|
|
8
|
+
await fs.mkdir(CONFIG_DIR, { recursive: true }).catch(() => { });
|
|
9
|
+
}
|
|
10
|
+
export async function loadQueries() {
|
|
11
|
+
try {
|
|
12
|
+
await ensureConfigDir();
|
|
13
|
+
const data = await fs.readFile(QUERIES_FILE, "utf-8");
|
|
14
|
+
const parsed = JSON.parse(data);
|
|
15
|
+
const list = Array.isArray(parsed) ? parsed : parsed.queries ?? [];
|
|
16
|
+
return list.filter((q) => q &&
|
|
17
|
+
typeof q === "object" &&
|
|
18
|
+
"id" in q &&
|
|
19
|
+
"name" in q &&
|
|
20
|
+
"sql" in q &&
|
|
21
|
+
"updatedAt" in q);
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
async function saveQueriesList(queries) {
|
|
28
|
+
await ensureConfigDir();
|
|
29
|
+
await fs.writeFile(QUERIES_FILE, JSON.stringify(queries, null, 2), "utf-8");
|
|
30
|
+
}
|
|
31
|
+
export async function saveQuery(id, name, sql) {
|
|
32
|
+
const queries = await loadQueries();
|
|
33
|
+
const now = Date.now();
|
|
34
|
+
const trimmedName = name.trim() || "Untitled query";
|
|
35
|
+
if (id) {
|
|
36
|
+
const idx = queries.findIndex((q) => q.id === id);
|
|
37
|
+
if (idx >= 0) {
|
|
38
|
+
queries[idx] = {
|
|
39
|
+
id: queries[idx].id,
|
|
40
|
+
name: trimmedName,
|
|
41
|
+
sql: sql.trim(),
|
|
42
|
+
updatedAt: now,
|
|
43
|
+
};
|
|
44
|
+
await saveQueriesList(queries);
|
|
45
|
+
return queries[idx];
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
const newQuery = {
|
|
49
|
+
id: crypto.randomUUID(),
|
|
50
|
+
name: trimmedName,
|
|
51
|
+
sql: sql.trim(),
|
|
52
|
+
updatedAt: now,
|
|
53
|
+
};
|
|
54
|
+
queries.unshift(newQuery);
|
|
55
|
+
await saveQueriesList(queries);
|
|
56
|
+
return newQuery;
|
|
57
|
+
}
|
|
58
|
+
export async function removeQueryById(id) {
|
|
59
|
+
const queries = await loadQueries();
|
|
60
|
+
const filtered = queries.filter((q) => q.id !== id);
|
|
61
|
+
if (filtered.length === queries.length)
|
|
62
|
+
return false;
|
|
63
|
+
await saveQueriesList(filtered);
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
export async function updateQueryName(id, name) {
|
|
67
|
+
const queries = await loadQueries();
|
|
68
|
+
const q = queries.find((x) => x.id === id);
|
|
69
|
+
if (!q)
|
|
70
|
+
return null;
|
|
71
|
+
q.name = name.trim() || q.name;
|
|
72
|
+
q.updatedAt = Date.now();
|
|
73
|
+
await saveQueriesList(queries);
|
|
74
|
+
return q;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=queries.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queries.service.js","sourceRoot":"","sources":["../../services/queries.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,6 +12,14 @@ export interface ApiResponse<T = unknown> {
|
|
|
12
12
|
export interface ConnectionResponse {
|
|
13
13
|
databaseName: string;
|
|
14
14
|
}
|
|
15
|
+
export interface SqlRunRequest {
|
|
16
|
+
connectionString: string;
|
|
17
|
+
sql: string;
|
|
18
|
+
}
|
|
19
|
+
export interface SqlRunResponse {
|
|
20
|
+
rows: Record<string, unknown>[];
|
|
21
|
+
rowCount: number;
|
|
22
|
+
}
|
|
15
23
|
export type { SchemaData, Table, Column, ForeignKey } from "./database.js";
|
|
16
24
|
/** Index list item for the Indexes page */
|
|
17
25
|
export interface IndexListItem {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../types/api.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,iBAAiB;IAChC,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,OAAO;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAC;CACtB;AAGD,YAAY,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAM3E,2CAA2C;AAC3C,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,0BAA0B;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,4BAA4B;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,qCAAqC;AACrC,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,yDAAyD;IACzD,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB"}
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../types/api.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,iBAAiB;IAChC,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,OAAO;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAC;CACtB;AAMD,MAAM,WAAW,aAAa;IAC5B,gBAAgB,EAAE,MAAM,CAAC;IACzB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAChC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAGD,YAAY,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAM3E,2CAA2C;AAC3C,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,0BAA0B;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,4BAA4B;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,qCAAqC;AACrC,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,yDAAyD;IACzD,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../utils/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../utils/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CA6C3D;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAMvF;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAKlE"}
|
|
@@ -18,10 +18,6 @@ export function toPublicErrorMessage(error) {
|
|
|
18
18
|
hostname = hostnameMatch[1];
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
-
// Check if it's a Supabase connection
|
|
22
|
-
if (hostname.includes("supabase.co")) {
|
|
23
|
-
return `Cannot resolve Supabase hostname: ${hostname}. Please verify:\n1. Your Supabase project is active (not paused)\n2. The connection string is correct\n3. The hostname format matches: [project-ref].supabase.co (without 'db.' prefix)`;
|
|
24
|
-
}
|
|
25
21
|
return `Cannot resolve hostname: ${hostname}. Please check your connection string and ensure the database server is accessible.`;
|
|
26
22
|
}
|
|
27
23
|
if (message.includes("password authentication failed")) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../utils/errors.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAc;IACjD,IAAI,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IAC9B,MAAM,QAAQ,GAAG,KAA2C,CAAC;IAE7D,sDAAsD;IACtD,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;QACrE,qCAAqC;QACrC,IAAI,QAAQ,GAAI,QAAQ,CAAC,QAAmB,IAAI,cAAc,CAAC;QAC/D,IAAI,QAAQ,KAAK,cAAc,EAAE,CAAC;YAChC,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,CACjC,iDAAiD,CAClD,CAAC;YACF,IAAI,aAAa,EAAE,CAAC;gBAClB,QAAQ,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC;QAED,
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../utils/errors.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAc;IACjD,IAAI,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IAC9B,MAAM,QAAQ,GAAG,KAA2C,CAAC;IAE7D,sDAAsD;IACtD,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;QACrE,qCAAqC;QACrC,IAAI,QAAQ,GAAI,QAAQ,CAAC,QAAmB,IAAI,cAAc,CAAC;QAC/D,IAAI,QAAQ,KAAK,cAAc,EAAE,CAAC;YAChC,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,CACjC,iDAAiD,CAClD,CAAC;YACF,IAAI,aAAa,EAAE,CAAC;gBAClB,QAAQ,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC;QAED,OAAO,4BAA4B,QAAQ,qFAAqF,CAAC;IACnI,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,CAAC,gCAAgC,CAAC,EAAE,CAAC;QACvD,OAAO,iEAAiE,CAAC;IAC3E,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;QAC/E,OAAO,6FAA6F,CAAC;IACvG,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QACjE,OAAO,iFAAiF,CAAC;IAC3F,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC;QAC/G,OAAO,mBAAmB,OAAO,EAAE,CAAC;IACtC,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACjE,OAAO,2BAA2B,OAAO,kCAAkC,CAAC;IAC9E,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,KAAmB,EAAE,UAAkB,EAAE,KAAc;IAC/E,MAAM,OAAO,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAC5C,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC;QAC5B,OAAO,EAAE,KAAK;QACd,KAAK,EAAE,OAAO;KACf,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAI,KAAmB,EAAE,IAAQ;IAC1D,KAAK,CAAC,IAAI,CAAC;QACT,OAAO,EAAE,IAAI;QACb,IAAI;KACL,CAAC,CAAC;AACL,CAAC"}
|