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 🙏

© 2024 – Pkg Stats / Ryan Hefner

cuery

v3.0.1

Published

> A composable SQL query builder based inspired by > [styled-components :nail_care:](https://styled-components.com) :sparkles:

Downloads

15

Readme

Cuery - Composable SQL Querying build status

A composable SQL query builder based inspired by styled-components :nail_care: :sparkles:

:dancer: Replace weird $1 or ? in your queries with simple functions!

:star: PostgreSQL and MySQL support!

:lock: Type safety (and autocompletion) with TypeScript

Why

In 2016, I wrote a blog post about composing SQL queries and published this library as a reference. The years passed, and there are much cooler ways of doing it, so this is the new way - using template literals.

Installation

For PostgreSQL users:

yarn add cuery pg
# or
npm install --save cuery pg

For MySQL users:

yarn add cuery mysql
# or
npm install --save cuery mysql

API

Import the modules for the database you use:

  • cuery/pg for PostgreSQL
  • cuery/mysql for MySQL

Both modules export the same two basic functions:

sql<Input, Output> template literal

The sql<Input, Output> template literal is meant for constructing an SQL query. It accepts functions, that will be acted as "getters" from the object you supply to the execute function, and compose other SQL queries too.

The two generics are meant for type safety, so you would declare your input and output types co-located with your query, just like a function: (input: Input) => Output.

It returns an SQL query, that later can be executed with the options needed, such as a pool (or a connection in MySQL)

const returnsNumber = sql<
  {}, // Takes no parameters as input
  { age: number }
>` // Returns a number as output
  SELECT 27 AS age
`;

const takesNumberAndReturnsIt = sql<
  { age: number }, // Takes a number as input
  { age: number }
>` // Returns a number as output
  SELECT ${p => p.age} AS age
`;

(await takesNumberAndReturnsIt.execute({ age: 27 }, { pool: new Pg.Pool() }))[0]
  .age === 27;

createSqlWithDefaults(defaults)

This function returns an sql<Input, Output> template literal function, that defaults to a specific execute options. Normally, it would be stored in a specific file in your project, that contains the information about the database connection, so you won't need to pass it all around your application.

const sql = createSqlWithDefaults({ pool: new Pg.Pool() });
const query = sql<{}, { age: number }>`SELECT 27 AS age`;
(await query.execute({}))[0].age === 27;

raw

This function is a helper function to say that the primitive passed into this function should be stringified and be added "as is" to the query. This is unsafe by nature, but when used correctly can have good implications like generating table names.

sql<{}, {}>`SELECT 27 AS ${raw("age")}`;

Usage

PostgreSQL

import { sql } from "cuery/pg";

const usersQuery = sql`SELECT name, age FROM users`;
const usersWithNameQuery = sql<{ name: string }, { name: string; age: number }>`
  SELECT name, age FROM (${usersQuery})
  WHERE name = ${params => params.name}
`;

// pool = new Pg.Pool()

const rows = await usersWithNameQuery.execute({ name: "John" }, { pool });
rows[0].age; // Type safe!

MySQL

import { sql } from "cuery/mysql";

const usersQuery = sql`SELECT name, age FROM users`;
const usersWithNameQuery = sql<{ name: string }, { name: string; age: number }>`
  SELECT name, age FROM (${usersQuery})
  WHERE name = ${params => params.name}
`;

// connection = create a new mysql connection

const rows = await usersWithNameQuery.execute({ name: "John" }, { connection });
rows[0].age; // Type safe!

Transformations

You can declare helper methods that do magic on your queries, like limit:

function limit<Input, Output>(query: Query<Input, Output>) {
  return sql<Input & { limit: Number; offset: Number }, Output>`
    SELECT *
    FROM (${query}) LIMITED__QUERY__${raw(Math.floor(Math.random() * 99999))}
    LIMIT ${p => p.limit}
    OFFSET ${p => p.offset}
  `;
}

// then you can just compose your queries!

const users = sql<
  {},
  { name: string; age: number }
>`SELECT name, age FROM users`;
const usersWithLimit = limit(users);
execute(usersWithLimit, { limit: 10, offset: 10 }); // start with offset of 10, then take 10 records.

Running tests

docker run --rm -d -p 5432:5432 -e POSTGRES_PASSWORD=password postgres:10
docker run --rm -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=password mysql:5.7
npm test