
Security News
TeamPCP and BreachForums Launch $1,000 Contest for Supply Chain Attacks
TeamPCP and BreachForums are promoting a Shai-Hulud supply chain attack contest with a $1,000 prize for the biggest package compromise.
@trithanka/sql-builder
Advanced tools
A lightweight, function-based, chainable SQL query builder for Node.js using MySQL pool connections.
A lightweight, function-based, chainable SQL query builder for Node.js projects using MySQL/MariaDB pool connections and raw queries. Perfect for building dynamic filters, pagination, and safe SQL operations β without a full-blown ORM.
? bindings)pool.execute / pool.querySELECT, INSERT, UPDATE, DELETE.groupBy(...)) & HAVING (.having(...)).build("count"))npm install @trithanka/sql-builder
const { createSelectBuilder } = require('@trithanka/sql-builder');
const { sql, values } = createSelectBuilder('SELECT * FROM users')
.where('status = ?', 'active')
.where('age >= ?', 18)
.where('created_at >= ?', '2024-01-01')
.orderBy('created_at', 'DESC')
.paginate(10, 0)
.build();
console.log('SQL:', sql);
console.log('Values:', values);
// Output:
// SQL: SELECT * FROM users WHERE status = ? AND age >= ? AND created_at >= ? ORDER BY created_at DESC LIMIT ? OFFSET ?
// Values: ['active', 18, '2024-01-01', 10, 0]
const [rows] = await pool.execute(sql, values);
const { createSelectBuilder } = require('@trithanka/sql-builder');
const {
sql,
values,
countSql,
countValues
} = createSelectBuilder(`
SELECT seller_id, COUNT(*) AS sales_count, SUM(amount) AS total_sales
FROM orders
`)
.where('order_date >= ?', '2024-01-01')
.where('status = ?', 'completed')
.groupBy('seller_id')
.having('COUNT(*) >= ?', 5)
.having('SUM(amount) >= ?', 1000)
.orderBy('total_sales', 'DESC')
.paginate(20, 40)
.build('count');
console.log('Main SQL:', sql);
console.log('Main Values:', values);
console.log('Count SQL:', countSql);
console.log('Count Values:', countValues);
// Get paginated results
const [rows] = await pool.execute(sql, values);
// Get total count for pagination
const [[{ total }]] = await pool.execute(countSql, countValues);
console.log('Total records:', total);
const { createSelectBuilder } = require('@trithanka/sql-builder');
// Base SQL already has WHERE clause
const { sql, values } = createSelectBuilder(`
SELECT * FROM users
WHERE status = 'active' AND role = 'admin'
`)
.where('age > ?', 25)
.where('department = ?', 'IT')
.orderBy('name', 'ASC')
.build();
console.log('SQL:', sql);
// Output: SELECT * FROM users WHERE status = 'active' AND role = 'admin' AND age > ? AND department = ? ORDER BY name ASC
const { createSelectBuilder } = require('@trithanka/sql-builder');
const filters = {
status: 'active',
role: 'user',
fromDate: '2024-01-01',
toDate: '2024-12-31',
minAge: 18,
maxAge: 65,
department: 'engineering',
limit: 50,
offset: 0
};
const { sql, values, countSql, countValues } = createSelectBuilder(`
SELECT u.id, u.name, u.email, u.created_at,
COUNT(o.id) as order_count, SUM(o.amount) as total_spent
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
`)
.where('u.status = ?', filters.status)
.where('u.role = ?', filters.role)
.where('u.age >= ?', filters.minAge)
.where('u.age <= ?', filters.maxAge)
.where('u.department = ?', filters.department)
.where('u.created_at >= ?', filters.fromDate)
.where('u.created_at <= ?', filters.toDate)
.groupBy('u.id, u.name, u.email, u.created_at')
.having('COUNT(o.id) > ?', 0)
.orderBy('total_spent', 'DESC')
.paginate(filters.limit, filters.offset)
.build('count');
// Execute both queries
const [rows] = await pool.execute(sql, values);
const [[{ total }]] = await pool.execute(countSql, countValues);
console.log(`Found ${rows.length} users out of ${total} total`);
const { buildInsertQuery } = require('@trithanka/sql-builder');
// Single record insert
const { sql, values } = buildInsertQuery('users', {
name: 'John Doe',
email: 'john@example.com',
age: 30,
status: 'active'
});
console.log('SQL:', sql);
console.log('Values:', values);
// Output:
// SQL: INSERT INTO users (name, email, age, status) VALUES (?, ?, ?, ?)
// Values: ['John Doe', 'john@example.com', 30, 'active']
await pool.execute(sql, values);
const { buildUpdateQuery } = require('@trithanka/sql-builder');
// Update with single condition
const { sql, values } = buildUpdateQuery(
'users',
{
name: 'John Smith',
email: 'johnsmith@example.com',
updated_at: new Date().toISOString()
},
'id = ?',
[101]
);
console.log('SQL:', sql);
console.log('Values:', values);
// Output:
// SQL: UPDATE users SET name = ?, email = ?, updated_at = ? WHERE id = ?
// Values: ['John Smith', 'johnsmith@example.com', '2024-01-15T10:30:00.000Z', 101]
await pool.execute(sql, values);
const { buildDeleteQuery } = require('@trithanka/sql-builder');
// Delete with single condition
const { sql, values } = buildDeleteQuery('users', 'id = ?', [101]);
console.log('SQL:', sql);
console.log('Values:', values);
// Output:
// SQL: DELETE FROM users WHERE id = ?
// Values: [101]
await pool.execute(sql, values);
// β This will throw an error (SQL injection attempt)
try {
createSelectBuilder('SELECT * FROM users')
.orderBy('id; DROP TABLE users; --', 'ASC')
.build();
} catch (error) {
console.log('SQL injection prevented:', error.message);
}
// β
This works safely
createSelectBuilder('SELECT * FROM users')
.orderBy('id', 'ASC')
.build();
// β Invalid pagination values
try {
createSelectBuilder('SELECT * FROM users')
.paginate(-5, -10)
.build();
} catch (error) {
console.log('Invalid pagination rejected:', error.message);
}
// β Invalid column names
try {
createSelectBuilder('SELECT * FROM users')
.orderBy('invalid;column;name', 'ASC')
.build();
} catch (error) {
console.log('Invalid column name rejected:', error.message);
}
// Handles existing WHERE clauses correctly
const { sql } = createSelectBuilder(`
SELECT * FROM users
WHERE status = 'active' -- This comment won't interfere
AND role = 'admin'
`)
.where('age > ?', 25)
.build();
console.log('SQL:', sql);
// Output: SELECT * FROM users WHERE status = 'active' AND role = 'admin' AND age > ?
src/
βββ selectBuilder.js # SELECT query builder with count support
βββ insertBuilder.js # INSERT query builder
βββ updateBuilder.js # UPDATE query builder
βββ deleteBuilder.js # DELETE query builder
βββ index.js # Main exports
pool.execute) and need reusable filters.whereIn(field, [...values]).between(field, from, to).like(field, pattern).isNull(field) / .isNotNull(field)MIT Β© Trithanka
FAQs
A lightweight, function-based, chainable SQL query builder for Node.js using MySQL pool connections.
The npm package @trithanka/sql-builder receives a total of 19 weekly downloads. As such, @trithanka/sql-builder popularity was classified as not popular.
We found that @trithanka/sql-builder demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.Β It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
TeamPCP and BreachForums are promoting a Shai-Hulud supply chain attack contest with a $1,000 prize for the biggest package compromise.

Security News
Packagist urges PHP projects to update Composer after a GitHub token format change exposed some GitHub Actions tokens in CI logs.

Research
GemStuffer abuses RubyGems as an exfiltration channel, packaging scraped UK council portal data into junk gems published from new accounts.