https://github.com/mhweiner/tiny-pg-builder
A safe, tiny, parameterized SQL builder for use with pg.
https://github.com/mhweiner/tiny-pg-builder
Last synced: 24 days ago
JSON representation
A safe, tiny, parameterized SQL builder for use with pg.
- Host: GitHub
- URL: https://github.com/mhweiner/tiny-pg-builder
- Owner: mhweiner
- License: mit
- Created: 2025-03-22T22:38:55.000Z (about 1 month ago)
- Default Branch: main
- Last Pushed: 2025-03-22T22:50:07.000Z (about 1 month ago)
- Last Synced: 2025-03-22T22:51:20.738Z (about 1 month ago)
- Language: JavaScript
- Size: 0 Bytes
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# tiny-pg-builder
[](https://github.com/mhweiner/tiny-pg-builder/actions)
[]()
[](https://conventionalcommits.org)
[](https://github.com/mhweiner/autorel)**tiny-pg-builder** is a utility for safely building parameterized SQL queries for use with [`pg`](https://github.com/brianc/node-postgres).
```ts
// Tagged template
sql`SELECT * FROM logs WHERE id IN (${[8, 9]}) AND level <= ${5}`;
// → { text: 'SELECT * FROM logs WHERE id IN ($1, $2) AND level <= $3', values: [8, 9, 5] }// Conditional query building
const builder = sqlBuilder(sql`SELECT * FROM users WHERE 1=1`);
status && builder.add(sql`AND status = ${'active'}`);
role && builder.add(sql`AND role IN (${['admin', 'editor']})`);
const query = builder.build();
// → { text: 'SELECT * FROM users WHERE 1=1\nAND status = $1\nAND role IN ($2, $3)', values: ['active', 'admin', 'editor'] }// Object-based helpers
buildInsert('users', { id: 1, name: 'Alice' });
// → { text: 'INSERT INTO users (id, name) VALUES ($1, $2)', values: [1, 'Alice'] }
```It’s designed to help you write dynamic SQL without string concatenation or the complexity of an ORM.
_Write SQL the way you want — clearly and safely._
---
**🔐 Safe and Convenient**
- Automatically numbers placeholders (`$1`, `$2`, …) to prevent SQL injection.
- Plays nicely with parameterized queries and prepared statements.**🧰 Flexible Builder API**
- Dynamically build queries with conditionals or loops.
- Easily compose from reusable parts.
- Use `raw()` to safely inject raw SQL when necessary, e.g., for sorting or table names.**🛠️ Object Helpers**
- Generate `INSERT`, `UPDATE`, and `WHERE` clauses [from objects](docs/api.md).**🎯 Works with `pg`**
- Returns `{ text, values }` — drop-in compatible with `pg.query()`.**💬 Template Literal Support**
- Use [tagged templates](#tagged-template-example) for inline queries.
- Automatically expands arrays into `IN ($1, $2, ...)` style.**📦 Zero Dependencies, TypeScript Native**
- Fully typed, 100% test coverage
- No runtime dependencies or bloat---
## Table of Contents
- [Installation](#installation)
- [Examples](#examples)
- [Using with `pg`](#using-with-pg)
- [API Reference](docs/api.md)
- [Philosophy](#philosophy)
- [Contributing](#contributing)
- [Related Projects](#related-projects)
- [License](#license)---
## Installation
```bash
npm i tiny-pg-builder
```---
## Examples
### Tagged Template Example
```ts
import { sql } from 'tiny-pg-builder';const ids = [33, 22, 11];
const query = sql`
SELECT * FROM logs
WHERE id IN (${ids})
AND level <= ${5}
`;// pg.query(query)
// query.text:
// SELECT * FROM logs WHERE id IN ($1, $2, $3) AND level <= $4
// query.values:
// [33, 22, 11, 5]
```---
### Builder API Quick Example
```ts
import { sql, sqlBuilder } from 'tiny-pg-builder';const builder = sqlBuilder(sql`SELECT * FROM users WHERE 1=1`);
builder.add(sql`AND id = ${42}`);
builder.add(sql`AND status = ${'active'}`);
builder.add(sql`AND role IN (${['admin', 'editor']})`);const query = builder.build();
// pg.query(query)
// query.text:
// SELECT * FROM users WHERE 1=1
// AND id = $1
// AND status = $2
// AND role IN ($3, $4)// query.values:
// [42, 'active', 'admin', 'editor']
```See a more real-world example of dynamic query building [here](docs/dynamicSearchQueryExample.md).
---
### 📝 Insert From Object Example
```ts
import { buildInsert } from 'tiny-pg-builder';const user = {
firstName: 'Alice',
lastName: 'Smith',
email: '[email protected]',
isActive: true,
};const query = buildInsert('users', user, { returning: true });
// pg.query(query)
// query.text:
// INSERT INTO "users" ("firstName", "lastName", "email", "isActive")
// VALUES ($1, $2, $3, $4) RETURNING *
// query.values:
// ['Alice', 'Smith', '[email protected]', true]
```---
### 🧩 Complex Composition Example
```ts
import { sql, sqlBuilder, buildWhere } from 'tiny-pg-builder';const query = sqlBuilder(sql`SELECT * FROM users`)
.add(buildWhere({ id: 1, status: 'active', role: ['admin', 'editor'] }))
.add(sql`ORDER BY created_at ${raw('DESC')}`)
.build();// query.text:
// SELECT * FROM users
// WHERE "id" = $1 AND "status" = $2 AND "role" IN ($3, $4)
// ORDER BY created_at DESC// query.values:
// [1, 'active', 'admin', 'editor']
```---
## Using with `pg`
`tiny-pg-builder` works seamlessly with [`pg`](https://github.com/brianc/node-postgres), the most popular PostgreSQL client for Node.js.
Just pass the `{ text, values }` object directly to `pg.query()`:
```ts
import { sql } from 'tiny-pg-builder';
import { Client } from 'pg';const client = new Client();
await client.connect();const query = sql`SELECT * FROM users WHERE id = ${42}`;
const result = await client.query(query);await client.end();
console.log(result.rows);
// → [{ id: 42, name: 'Alice', ... }]
```---
## Philosophy
Most SQL libraries either go too far or not far enough.
- Some are **too low-level**, forcing you to manually manage strings and `$1` bindings.
- Others are **too high-level**, hiding SQL behind complex DSLs or ORMs.`tiny-pg-builder` doesn’t try to replace SQL. It gives you a tiny, composable toolset that lets you work *with* SQL — clearly, safely, and without repetition or risk.
> Write SQL the way you want — clearly and safely.
---
## Contributing
- ⭐ Star this repo if you like it!
- 🐛 Open an [issue](https://github.com/mhweiner/tiny-pg-builder/issues) for bugs or suggestions.
- 🤝 Submit a PR to `main` — all tests must pass.---
# Related Projects
- [autorel](https://github.com/mhweiner/autorel): Automate semantic releases based on conventional commits. Similar to semantic-release but much simpler.
- [hoare](https://github.com/mhweiner/hoare): An easy-to-use, fast, and defensive JS/TS test runner designed to help you to write simple, readable, and maintainable tests.
- [jsout](https://github.com/mhweiner/jsout): A Syslog-compatible, small, and simple logger for Typescript/Javascript projects.
- [cjs-mock](https://github.com/mhweiner/cjs-mock): NodeJS module mocking for CJS (CommonJS) modules for unit testing purposes.
- [brek](https://github.com/mhweiner/brek): powerful yet simple configuration library for Node.js. It’s structured, typed, and designed for dynamic configuration loading, making it perfect for securely managing secrets (e.g., AWS Secrets Manager).