@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/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/toml-config`);
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 (!validPermissions.includes(perm)) {
41398
- throw new Error(`IAM rule ${ruleNum} has invalid permission: ${perm}. Must be one of: ${validPermissions.join(", ")}`);
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 === "allAuthenticatedUsers") {
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 "allAuthenticatedUsers", "user:xxx", or "group:xxx"`);
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 === "allAuthenticatedUsers") {
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 depends on direction
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(args.config);
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: