@pgplex/pgconsole 0.0.2 → 0.0.4
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/client/assets/{index-BzxpiRse.js → index-D1j7ALWF.js} +9 -9
- package/dist/client/assets/index-DgePIECN.css +2 -0
- package/dist/client/assets/{sql-BEfBO0hN.js → sql-qjXzJq_H.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/server.mjs +55 -20
- package/dist/server.mjs.map +2 -2
- package/package.json +1 -1
- package/dist/client/assets/index-BXV6P4Bi.css +0 -2
package/dist/server.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
1
2
|
import { createRequire } from 'module';
|
|
2
3
|
const require = createRequire(import.meta.url);
|
|
3
4
|
const __filename = fileURLToPath(import.meta.url);
|
|
@@ -41057,7 +41058,7 @@ async function loadConfig(configPath) {
|
|
|
41057
41058
|
const path5 = configPath || "pgconsole.toml";
|
|
41058
41059
|
if (!existsSync(path5)) {
|
|
41059
41060
|
throw new Error(`Config file not found: ${path5}
|
|
41060
|
-
See https://docs.pgconsole.com/configuration/
|
|
41061
|
+
See https://docs.pgconsole.com/configuration/config`);
|
|
41061
41062
|
}
|
|
41062
41063
|
const content = readFileSync(path5, "utf-8");
|
|
41063
41064
|
const parsed = parse2(content);
|
|
@@ -41374,7 +41375,7 @@ See https://docs.pgconsole.com/configuration/toml-config`);
|
|
|
41374
41375
|
}
|
|
41375
41376
|
}
|
|
41376
41377
|
const iam = [];
|
|
41377
|
-
const validPermissions = ["read", "write", "ddl", "admin"];
|
|
41378
|
+
const validPermissions = ["read", "write", "ddl", "admin", "explain", "execute", "export"];
|
|
41378
41379
|
const rawIAM = parsed.iam || [];
|
|
41379
41380
|
for (let i2 = 0; i2 < rawIAM.length; i2++) {
|
|
41380
41381
|
const rule = rawIAM[i2];
|
|
@@ -41394,10 +41395,13 @@ See https://docs.pgconsole.com/configuration/toml-config`);
|
|
|
41394
41395
|
if (typeof perm !== "string") {
|
|
41395
41396
|
throw new Error(`IAM rule ${ruleNum} has invalid permission: must be string`);
|
|
41396
41397
|
}
|
|
41397
|
-
if (
|
|
41398
|
-
|
|
41398
|
+
if (perm === "allPermissions") {
|
|
41399
|
+
permissions.push(...validPermissions);
|
|
41400
|
+
} else if (!validPermissions.includes(perm)) {
|
|
41401
|
+
throw new Error(`IAM rule ${ruleNum} has invalid permission: ${perm}. Must be one of: ${validPermissions.join(", ")}, allPermissions`);
|
|
41402
|
+
} else {
|
|
41403
|
+
permissions.push(perm);
|
|
41399
41404
|
}
|
|
41400
|
-
permissions.push(perm);
|
|
41401
41405
|
}
|
|
41402
41406
|
if (!Array.isArray(rule.members) || rule.members.length === 0) {
|
|
41403
41407
|
throw new Error(`IAM rule ${ruleNum} missing required field: members (must be non-empty array)`);
|
|
@@ -41408,7 +41412,7 @@ See https://docs.pgconsole.com/configuration/toml-config`);
|
|
|
41408
41412
|
throw new Error(`IAM rule ${ruleNum} has invalid member: must be non-empty string`);
|
|
41409
41413
|
}
|
|
41410
41414
|
const m2 = member.trim();
|
|
41411
|
-
if (m2 === "
|
|
41415
|
+
if (m2 === "allUsers") {
|
|
41412
41416
|
members.push(m2);
|
|
41413
41417
|
} else if (m2.startsWith("user:")) {
|
|
41414
41418
|
const email = m2.slice(5);
|
|
@@ -41426,7 +41430,7 @@ See https://docs.pgconsole.com/configuration/toml-config`);
|
|
|
41426
41430
|
}
|
|
41427
41431
|
members.push(m2);
|
|
41428
41432
|
} else {
|
|
41429
|
-
throw new Error(`IAM rule ${ruleNum} has invalid member format: ${m2}. Must be "
|
|
41433
|
+
throw new Error(`IAM rule ${ruleNum} has invalid member format: ${m2}. Must be "allUsers", "user:xxx", or "group:xxx"`);
|
|
41430
41434
|
}
|
|
41431
41435
|
}
|
|
41432
41436
|
iam.push({ connection, permissions, members });
|
|
@@ -41451,13 +41455,6 @@ See https://docs.pgconsole.com/configuration/toml-config`);
|
|
|
41451
41455
|
throw new Error(`Too many [[users]] entries: ${users.length} configured but current license only allows ${limit2}. Remove users or upgrade your license.`);
|
|
41452
41456
|
}
|
|
41453
41457
|
}
|
|
41454
|
-
console.log(`Loaded ${users.length} user(s), ${groups.length} group(s), ${labels.length} label(s) and ${connections.length} connection(s) from ${path5}`);
|
|
41455
|
-
if (ai) {
|
|
41456
|
-
console.log(`AI configured with ${ai.providers.length} provider(s)`);
|
|
41457
|
-
}
|
|
41458
|
-
if (iam.length > 0) {
|
|
41459
|
-
console.log(`IAM configured with ${iam.length} rule(s)`);
|
|
41460
|
-
}
|
|
41461
41458
|
}
|
|
41462
41459
|
function getLabels() {
|
|
41463
41460
|
return loadedConfig.labels;
|
|
@@ -57496,7 +57493,7 @@ function extractPostgresVersion(versionString) {
|
|
|
57496
57493
|
}
|
|
57497
57494
|
|
|
57498
57495
|
// server/lib/iam.ts
|
|
57499
|
-
var ALL_PERMISSIONS = ["read", "write", "ddl", "admin"];
|
|
57496
|
+
var ALL_PERMISSIONS = ["read", "write", "ddl", "admin", "explain", "execute", "export"];
|
|
57500
57497
|
function requirePermission(user, connectionId, permission, action) {
|
|
57501
57498
|
if (!user) {
|
|
57502
57499
|
throw new ConnectError("Authentication required", Code.Unauthenticated);
|
|
@@ -57541,7 +57538,7 @@ function getUserPermissions(email, connectionId) {
|
|
|
57541
57538
|
continue;
|
|
57542
57539
|
}
|
|
57543
57540
|
const matches = rule.members.some((member) => {
|
|
57544
|
-
if (member === "
|
|
57541
|
+
if (member === "allUsers") {
|
|
57545
57542
|
return true;
|
|
57546
57543
|
}
|
|
57547
57544
|
if (member.startsWith("user:")) {
|
|
@@ -57756,6 +57753,7 @@ function transformStatement(node, source) {
|
|
|
57756
57753
|
if ("AlterPublicationStmt" in obj) return { kind: "alter_publication", source };
|
|
57757
57754
|
if ("ReassignOwnedStmt" in obj) return { kind: "reassign_owned", source };
|
|
57758
57755
|
if ("DropOwnedStmt" in obj) return { kind: "drop_owned", source };
|
|
57756
|
+
if ("CallStmt" in obj) return { kind: "call", source };
|
|
57759
57757
|
return { kind: "unknown", raw: node, source };
|
|
57760
57758
|
}
|
|
57761
57759
|
function transformSelect(raw) {
|
|
@@ -62077,9 +62075,14 @@ function getRequiredPermission(kind) {
|
|
|
62077
62075
|
switch (kind) {
|
|
62078
62076
|
// Read-only
|
|
62079
62077
|
case "select":
|
|
62080
|
-
case "explain":
|
|
62081
62078
|
case "show":
|
|
62082
62079
|
return "read";
|
|
62080
|
+
// Explain
|
|
62081
|
+
case "explain":
|
|
62082
|
+
return "explain";
|
|
62083
|
+
// Execute (stored procedures)
|
|
62084
|
+
case "call":
|
|
62085
|
+
return "execute";
|
|
62083
62086
|
// DML (data modification)
|
|
62084
62087
|
case "insert":
|
|
62085
62088
|
case "update":
|
|
@@ -62104,7 +62107,7 @@ function getRequiredPermission(kind) {
|
|
|
62104
62107
|
case "revoke":
|
|
62105
62108
|
case "refresh_matview":
|
|
62106
62109
|
return "ddl";
|
|
62107
|
-
// COPY
|
|
62110
|
+
// COPY (data import/export via server filesystem)
|
|
62108
62111
|
case "copy":
|
|
62109
62112
|
return "write";
|
|
62110
62113
|
// Session/transaction control - safe operations
|
|
@@ -92526,8 +92529,9 @@ app.use((req, res, next) => {
|
|
|
92526
92529
|
async function start() {
|
|
92527
92530
|
const args = parseArgs();
|
|
92528
92531
|
const port = args.port || process.env.PORT || 9876;
|
|
92532
|
+
const configPath = args.config || "pgconsole.toml";
|
|
92529
92533
|
try {
|
|
92530
|
-
await loadConfig(
|
|
92534
|
+
await loadConfig(configPath);
|
|
92531
92535
|
} catch (error) {
|
|
92532
92536
|
console.error("Failed to load config:", error instanceof Error ? error.message : error);
|
|
92533
92537
|
process.exit(1);
|
|
@@ -92545,9 +92549,40 @@ async function start() {
|
|
|
92545
92549
|
console.error("\nConnection test failed:", error instanceof Error ? error.message : error);
|
|
92546
92550
|
process.exit(1);
|
|
92547
92551
|
}
|
|
92548
|
-
app.listen(port, () => {
|
|
92552
|
+
const server = app.listen(port, () => {
|
|
92553
|
+
console.log(`
|
|
92554
|
+
___
|
|
92555
|
+
/\\_ \\
|
|
92556
|
+
_____ __ ___ ___ ___ ____ ___\\//\\ \\ __
|
|
92557
|
+
/\\ '__\`\\ /'_ \`\\ /'___\\ / __\`\\ /' _ \`\\ /',__\\ / __\`\\\\ \\ \\ /'__\`\\
|
|
92558
|
+
\\ \\ \\L\\ \\/\\ \\L\\ \\/\\ \\__//\\ \\L\\ \\/\\ \\/\\ \\/\\__, \`\\/\\ \\L\\ \\\\_\\ \\_/\\ __/
|
|
92559
|
+
\\ \\ ,__/\\ \\____ \\ \\____\\ \\____/\\ \\_\\ \\_\\/\\____/\\ \\____//\\____\\ \\____\\
|
|
92560
|
+
\\ \\ \\/ \\/___L\\ \\/____/\\/___/ \\/_/\\/_/\\/___/ \\/___/ \\/____/\\/____/
|
|
92561
|
+
\\ \\_\\ /\\____/
|
|
92562
|
+
\\/_/ \\_/__/
|
|
92563
|
+
|
|
92564
|
+
Version ${"0.0.4"}
|
|
92565
|
+
`);
|
|
92549
92566
|
console.log(`Server running on http://localhost:${port}`);
|
|
92567
|
+
const browserUrl = false ? `http://localhost:5173` : getExternalUrl() || `http://localhost:${port}`;
|
|
92568
|
+
console.log(`Open in browser: ${browserUrl}`);
|
|
92550
92569
|
});
|
|
92570
|
+
server.on("error", (err) => {
|
|
92571
|
+
if (err.code === "EADDRINUSE") {
|
|
92572
|
+
console.error(`Error: Port ${port} is already in use.`);
|
|
92573
|
+
} else {
|
|
92574
|
+
console.error(`Error starting server: ${err.message}`);
|
|
92575
|
+
}
|
|
92576
|
+
process.exit(1);
|
|
92577
|
+
});
|
|
92578
|
+
const shutdown = () => {
|
|
92579
|
+
console.log("\nShutting down...");
|
|
92580
|
+
server.close(() => {
|
|
92581
|
+
process.exit(0);
|
|
92582
|
+
});
|
|
92583
|
+
};
|
|
92584
|
+
process.on("SIGTERM", shutdown);
|
|
92585
|
+
process.on("SIGINT", shutdown);
|
|
92551
92586
|
}
|
|
92552
92587
|
start();
|
|
92553
92588
|
/*! Bundled license information:
|