npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@kilbergr/pg-sql

v0.1.0-Dev.27

Published

Postgres SQL tag

Readme

Pg SQL tag

The library is still under development

A library to generate SQL queries for PostgreSQL with the use of sql template tag.

const userId = 1;
const name = 'John Doe';
const queryConfig: QueryConfig = sql`
  SELECT * FROM users WHERE id = :${userId} AND name = :${name}
`;

queryConfig.text; // SELECT * FROM users WHERE id = $1 AND name = $2
queryConfig.values; // [1, 'John Doe']

The library is extensible and allows you to add custom SQL functions.

const tableName = 'my_schema.my_table';
const where = {
  id: { $in: [1, 2, 3] },
  created_at: { $gt: new Date('2020-01-01') },
};

const queryConfig: QueryConfig = sql`
  SELECT * FROM ${Identifier(tableName)}
  ${Where(where)}
`;
// SELECT * FROM "my_schema"."my_table" WHERE "id"
// IN ($1, $2, $3) AND "created_at" > $4
queryConfig.text;
// [1, 2, 3, new Date('2020-01-01')]
queryConfig.values;

Installation

npm install @kilbergr/pg-sql

yarn add @kilbergr/pg-sql

Usage

import { sql, Identifier, Where } from '@kilbergr/pg-sql';

Documentation

The sql is a template tag that generates a QueryConfig object that can be used as an input with the pg library.

Merging queries

The sql template tag allows to merging of multiple queries into a single query. The sql template tag will automatically update the placeholder indexes to match the new query.

const queryOne = sql`
  SELECT * FROM users WHERE id = $1
`;
const queryTwo = sql`
  SELECT * FROM users WHERE name = $1
`;

const queryConfig: QueryConfig = sql`
  ${queryOne}
  UNION
  ${queryTwo}
`;

// SELECT * FROM users WHERE id = $1 UNION SELECT * FROM users WHERE name = $2
queryConfig.text; 

Value binding

Bind a single value

A simple value can be bound to a query using the :${value} syntax.

const userId = 1;
const name = 'John Doe';
const queryConfig: QueryConfig = sql`
  SELECT * FROM users WHERE id = :${userId} AND name = :${name}
`;

queryConfig.text; // SELECT * FROM users WHERE id = $1 AND name = $2
queryConfig.values; // [1, 'John Doe']

Bind an array of values

An array of values can be spread using the ...${value} syntax.

const userIds = [1, 2, 3];
const queryConfig: QueryConfig = sql`
  SELECT * FROM users WHERE id IN ...:${userIds}
`;

queryConfig.text; // SELECT * FROM users WHERE id IN ($1, $2, $3)
queryConfig.values; // [1, 2, 3]

Bind a literal value

The values can be also bound in cases where native bindings are not supported. In this such the value will be treated as a literal string. For example a creation on a partitioned table. The :L${value} syntax or ...L${value} spread syntax can be used.

const partitionIds = ['my_value', 'my_other_value'];

const queryConfig: QueryConfig = sql`
  CREATE TABLE my_table_partition_one 
    PARTITION OF my_table FOR VALUES IN ...:L${partitionIds}
`;

// CREATE TABLE my_table_partition_one
// PARTITION OF my_table FOR VALUES IN ('my_value', 'my_other_value')
queryConfig.text; 
queryConfig.values; // []

Underlying functions

The value binding syntax is a shorthand for the Value function.

const userId = 1;
const name = 'John Doe';

const queryConfig: QueryConfig = sql`
  SELECT * FROM users WHERE id = ${Value(userId)} AND name = ${Value(name)}
`;

queryConfig.text; // SELECT * FROM users WHERE id = $1 AND name = $2
queryConfig.values; // [1, 'John Doe']

The value spread syntax is a shorthand for the Values function.

const userIds = [1, 2, 3];

const queryConfig: QueryConfig = sql`
  SELECT * FROM users WHERE id IN ${Values(userIds, { spreadValues: true })}
`;

queryConfig.text; // SELECT * FROM users WHERE id IN ($1, $2, $3)
queryConfig.values; // [1, 2, 3]

The literal value binding syntax is a shorthand for the Literal function.

const partitionIds = ['my_value', 'my_other_value'];

const queryConfig: QueryConfig = sql`
  CREATE TABLE my_table_partition_one 
    PARTITION OF my_table FOR VALUES IN ${Literal(partitionIds)}
`;

// CREATE TABLE my_table_partition_one
// PARTITION OF my_table FOR VALUES IN ('my_value', 'my_other_value')
queryConfig.text;
queryConfig.values; // []

SQL functions

The sql template tag can be extended with custom SQL functions or a SqlTemplateNode. The SqlTemplateNode is a simple object with a method called parse. It allows you to build more sophisticated SQL fragment builders. (More below)

See a list of built-in SQL functions:

Value

The Value function is used to bind a value or a list of values to a query.

const userId = 1;
const name = 'John Doe';

const queryConfig: QueryConfig = sql`
  SELECT * FROM users WHERE id = ${Value(userId)} AND name = ${Value(name)}
`;

queryConfig.text; // SELECT * FROM users WHERE id = $1 AND name = $2
queryConfig.values; // [1, 'John Doe']

Values

The Values function is used to bind an array of values to a query.

const userIds = [1, 2, 3];

const queryConfig: QueryConfig = sql`
  SELECT * FROM users WHERE id IN ${Values(userIds, { spreadValues: true })}
`;

queryConfig.text; // SELECT * FROM users WHERE id IN ($1, $2, $3)
queryConfig.values; // [1, 2, 3]

Literal

The Literal function is used to bind a literal value to a query in places where native bindings are not supported.


const partitionIds = ['my_value', 'my_other_value'];

const queryConfig: QueryConfig = sql`
  CREATE TABLE my_table_partition_one 
    PARTITION OF my_table FOR VALUES IN ${Literal(partitionIds)}
`;

// CREATE TABLE my_table_partition_one
// PARTITION OF my_table FOR VALUES IN ('my_value', 'my_other_value')

queryConfig.text;
queryConfig.values; // []

Where

The Where function is used to build a WHERE clause from an object.

const where = {
  id: { $in: [1, 2, 3] },
  created_at: { $gt: new Date('2020-01-01') },
};

const queryConfig: QueryConfig = sql`
  SELECT * FROM users
  ${Where(where)}
`;

// SELECT * FROM users WHERE "id" IN ($1, $2, $3) AND "created_at" > $4
queryConfig.text;
// [1, 2, 3, new Date('2020-01-01')]
queryConfig.values;

The Where function supports the following operators:

  • $eq - Equal
  • $neq - Not Equal
  • $gt - Greater than
  • $gte - Greater than or equal
  • $lt - Less than
  • $lte - Less than or equal
  • $in - In
  • $nin - Not in
  • $like - Like
  • $ilike - ILike
  • $or - Or
  • $and - And

Example of writing a where clause:

{
  "id": { "$eq": 1 },
  "name": { "$like": "John%" },
  "$or": {
    "created_at": { 
      "$gt": "2020-01-01", 
      "$lt": "2020-12-31" 
    },
    "updated_at": { "$gt": "2020-01-01" }
  }
}

In

The In function is used to build an IN clause from an array of values.

const userIds = [1, 2, 3];

const queryConfig: QueryConfig = sql`
  SELECT * FROM users WHERE id ${In(userIds)}
`;

queryConfig.text; // SELECT * FROM users WHERE id IN ($1, $2, $3)
queryConfig.values; // [1, 2, 3]

Custom SQL functions

A templating function for sql template tag is a factory that has to return an anonymous function that accepts a SqlTagParserContext object. Then it can do whatever it wants with the context and return a void. The SqlTagParserContext object is a builder that allows to addition of new SQL fragments to the query or bind values.

See an example of how a `Between`` function can be implemented:

export function Between(from: NumericType, to: NumericType) {
  return (context: SqlTagParserContext): void => {
    context
      .addKeyword('BETWEEN')
      .bindValue(from)
      .addKeyword('AND')
      .bindValue(to);
  };
}