@cli4ai/postgres
Advanced tools
+1
-2
| { | ||
| "name": "@cli4ai/postgres", | ||
| "version": "1.0.5", | ||
| "version": "1.0.6", | ||
| "description": "PostgreSQL read-only queries", | ||
@@ -31,3 +31,2 @@ "author": "cliforai", | ||
| "dependencies": { | ||
| "@cli4ai/lib": "^1.0.2", | ||
| "pg": "^8.0.0", | ||
@@ -34,0 +33,0 @@ "commander": "^14.0.0" |
+30
-2
@@ -48,2 +48,27 @@ #!/usr/bin/env bun | ||
| const PG_IDENTIFIER_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/; | ||
| function parsePositiveInt(value: string, name: string): number { | ||
| const parsed = parseInt(value, 10); | ||
| if (!Number.isFinite(parsed) || parsed < 1) { | ||
| outputError('INVALID_INPUT', `${name} must be a positive integer`, { value }); | ||
| } | ||
| return parsed; | ||
| } | ||
| function getQualifiedTableName(table: string): string { | ||
| const parts = table.split('.'); | ||
| if (parts.length > 2) { | ||
| outputError('INVALID_INPUT', 'Invalid table name', { table }); | ||
| } | ||
| const schema = parts.length === 2 ? parts[0] : 'public'; | ||
| const tableName = parts.length === 2 ? parts[1] : parts[0]; | ||
| if (!PG_IDENTIFIER_PATTERN.test(schema) || !PG_IDENTIFIER_PATTERN.test(tableName)) { | ||
| outputError('INVALID_INPUT', 'Invalid table name', { table }); | ||
| } | ||
| return `"${schema}"."${tableName}"`; | ||
| } | ||
| function getConnectionString(connName?: string): string { | ||
@@ -243,3 +268,5 @@ if (connName) { | ||
| await withClient(connName, async (client) => { | ||
| const result = await client.query(`SELECT * FROM ${table} LIMIT ${parseInt(limit)}`); | ||
| const qualified = getQualifiedTableName(table); | ||
| const parsedLimit = parsePositiveInt(limit, 'limit'); | ||
| const result = await client.query(`SELECT * FROM ${qualified} LIMIT $1`, [parsedLimit]); | ||
| output(result.rows); | ||
@@ -254,3 +281,4 @@ }); | ||
| await withClient(connName, async (client) => { | ||
| const result = await client.query(`SELECT COUNT(*) as count FROM ${table}`); | ||
| const qualified = getQualifiedTableName(table); | ||
| const result = await client.query(`SELECT COUNT(*) as count FROM ${qualified}`); | ||
| output(result.rows[0]); | ||
@@ -257,0 +285,0 @@ }); |
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 3 instances in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 3 instances in 1 package
17169
6.01%2
-33.33%367
6.69%- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed