A slightly nicer interface to Postgres over node-libpq providing both sync and async operations
88
Quality
Pending
Does it follow best practices?
Impact
88%
1.20xAverage score across 10 eval scenarios
Query execution functionality supporting both text queries and parameterized statements with async and sync interfaces for maximum flexibility.
Execute SQL queries asynchronously with optional parameter binding.
/**
* Execute a SQL query asynchronously
* @param text - SQL query text
* @param callback - Callback function receiving results
*/
client.query(
text: string,
callback: (err: Error | null, rows: any[], results?: QueryResult | QueryResult[]) => void
): void;
/**
* Execute a parameterized SQL query asynchronously
* @param text - SQL query text with $1, $2, etc. placeholders
* @param values - Array of parameter values
* @param callback - Callback function receiving results
*/
client.query(
text: string,
values: any[],
callback: (err: Error | null, rows: any[], results?: QueryResult | QueryResult[]) => void
): void;Usage Examples:
const client = new Client();
client.connectSync();
// Simple text query
client.query('SELECT NOW() AS current_time', function(err, rows) {
if (err) throw err;
console.log('Current time:', rows[0].current_time);
});
// Parameterized query for safety
client.query(
'SELECT * FROM users WHERE age > $1 AND city = $2',
[25, 'New York'],
function(err, rows) {
if (err) throw err;
console.log('Found users:', rows);
}
);
// Query with multiple result sets
client.query(
'SELECT 1 as first; SELECT 2 as second',
function(err, rows, results) {
if (err) throw err;
console.log('Multiple results:', results);
// rows will be an array of arrays: [[{first: 1}], [{second: 2}]]
// results will be an array of QueryResult objects
}
);Multiple Result Sets:
When a query contains multiple statements (separated by semicolons), the callback receives arrays:
rows: Array of row arrays, one for each statementresults: Array of QueryResult objects, one for each statementFor single statements:
rows: Simple array of row objectsresults: Single QueryResult object (or undefined for simple queries)Execute SQL queries synchronously, returning results directly.
/**
* Execute a SQL query synchronously
* @param text - SQL query text
* @param values - Optional array of parameter values
* @returns Array of result rows
* @throws Error if query fails
*/
client.querySync(text: string, values?: any[]): any[];Usage Examples:
const client = new Client();
client.connectSync();
try {
// Simple text query
const rows = client.querySync('SELECT NOW() AS current_time');
console.log('Current time:', rows[0].current_time);
// Parameterized query
const users = client.querySync(
'SELECT name, email FROM users WHERE age > $1',
[25]
);
console.log('Users over 25:', users);
// Data modification query
const insertResult = client.querySync(
'INSERT INTO logs (message, created_at) VALUES ($1, NOW()) RETURNING id',
['Application started']
);
console.log('Inserted log ID:', insertResult[0].id);
} catch (err) {
console.error('Query failed:', err.message);
}Query results are returned as arrays of objects by default, with each row as an object with column names as keys.
// Default object mode results
interface QueryResultRow {
[columnName: string]: any;
}
// Array mode results (when arrayMode: true in constructor)
type QueryResultRowArray = any[];Object Mode (Default):
const client = new Client();
const rows = client.querySync('SELECT id, name, age FROM users LIMIT 2');
console.log(rows);
// [
// { id: 1, name: 'Alice', age: 30 },
// { id: 2, name: 'Bob', age: 25 }
// ]Array Mode:
const client = new Client({ arrayMode: true });
const rows = client.querySync('SELECT id, name, age FROM users LIMIT 2');
console.log(rows);
// [
// [1, 'Alice', 30],
// [2, 'Bob', 25]
// ]Cancel a currently executing query.
/**
* Cancel the currently executing query
* @param callback - Required callback function
*/
client.cancel(callback: (err: Error | null) => void): void;Usage Examples:
const client = new Client();
client.connectSync();
// Start a long-running query
client.query('SELECT pg_sleep(60)', function(err, rows) {
if (err) {
console.log('Query was cancelled:', err.message);
} else {
console.log('Query completed');
}
});
// Cancel it after 1 second
setTimeout(function() {
client.cancel(function(err) {
if (err) {
console.error('Cancel failed:', err.message);
} else {
console.log('Cancel request sent');
}
});
}, 1000);Safely escape strings and identifiers for SQL queries.
/**
* Escape a string literal for safe inclusion in SQL
* @param value - String value to escape
* @returns Escaped string literal with quotes
*/
client.escapeLiteral(value: string): string;
/**
* Escape an identifier for safe inclusion in SQL
* @param value - Identifier to escape
* @returns Escaped identifier with quotes if needed
*/
client.escapeIdentifier(value: string): string;Usage Examples:
const client = new Client();
client.connectSync();
const userInput = "Robert'; DROP TABLE students; --";
const tableName = "user data";
// Escape string literal
const escapedValue = client.escapeLiteral(userInput);
console.log(escapedValue); // 'Robert''; DROP TABLE students; --'
// Escape identifier
const escapedTable = client.escapeIdentifier(tableName);
console.log(escapedTable); // "user data"
// Use in queries (although parameterized queries are preferred)
const query = `SELECT * FROM ${escapedTable} WHERE name = ${escapedValue}`;All query operations can throw or return PostgreSQL errors:
// Async error handling
client.query('INVALID SQL', function(err, rows) {
if (err) {
console.error('Query error:', err.message);
// err.message contains PostgreSQL error details
}
});
// Sync error handling
try {
client.querySync('INVALID SQL');
} catch (err) {
console.error('Query error:', err.message);
// err.message contains PostgreSQL error details
}Install with Tessl CLI
npx tessl i tessl/npm-pg-nativeevals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10