Description
sqlc, like protoc, aims to generate code for multiple languages. The second language we're looking to add is TypeScript.
Getting started
Warning
The TypeScript plugin (sqlc-gen-typescript) is under active development. We make no guarantees about backwards compatibility. Please try it out and give us feedback, but don't use it in production just yet.
Create a new directory. Inside, create a sqlc.yaml
with these contents. Add your database schema to schema.sql
and your queries to query.sql
. If you don't have any to try out, skip to the provided example.
version: "2"
plugins:
- name: ts
wasm:
url: "https://downloads.sqlc.dev/plugin/alpha/sqlc-gen-typescript_0.0.0_c6bc663.wasm"
sha256: c6bc663cb5064ef33023f24d96c378512f1d6a0fadd7c9b5bba45a24cbfbb894
sql:
- schema: "schema.sql"
queries: "query.sql"
engine: "postgresql"
codegen:
- plugin: ts
out: src/db
options:
driver: "pg"
runtime: "node"
Running sqlc generate
will output TypeScript into src/db
. Please let us know what you think by leaving a comment on this issue.
Example
With the following schema and queries, sqlc will generate code with zero dependencies (beyond the necessary database driver).
CREATE TABLE authors (
id BIGSERIAL PRIMARY KEY,
name text NOT NULL,
bio text
);
-- name: GetAuthor :one
SELECT * FROM authors
WHERE id = $1 LIMIT 1;
-- name: ListAuthors :many
SELECT * FROM authors
ORDER BY name;
-- name: CreateAuthor :one
INSERT INTO authors (
name, bio
) VALUES (
$1, $2
)
RETURNING *;
-- name: DeleteAuthor :exec
DELETE FROM authors
WHERE id = $1;
import { QueryArrayConfig, QueryArrayResult } from "pg";
interface Client {
query: (config: QueryArrayConfig) => Promise<QueryArrayResult>;
}
export const getAuthorQuery = `-- name: GetAuthor :one
SELECT id, name, bio FROM authors
WHERE id = $1 LIMIT 1`;
export interface GetAuthorArgs {
id: string;
}
export interface GetAuthorRow {
id: string;
name: string;
bio: string | null;
}
export async function getAuthor(client: Client, args: GetAuthorArgs): Promise<GetAuthorRow | null> {
const result = await client.query({
text: getAuthorQuery,
values: [args.id],
rowMode: "array"
});
if (result.rows.length !== 1) {
return null;
}
const row = result.rows[0];
return {
id: row[0],
name: row[1],
bio: row[2]
};
}
export const listAuthorsQuery = `-- name: ListAuthors :many
SELECT id, name, bio FROM authors
ORDER BY name`;
export interface ListAuthorsRow {
id: string;
name: string;
bio: string | null;
}
export async function listAuthors(client: Client): Promise<ListAuthorsRow[]> {
const result = await client.query({
text: listAuthorsQuery,
values: [],
rowMode: "array"
});
return result.rows.map(row => {
return {
id: row[0],
name: row[1],
bio: row[2]
};
});
}
export const createAuthorQuery = `-- name: CreateAuthor :one
INSERT INTO authors (
name, bio
) VALUES (
$1, $2
)
RETURNING id, name, bio`;
export interface CreateAuthorArgs {
name: string;
bio: string | null;
}
export interface CreateAuthorRow {
id: string;
name: string;
bio: string | null;
}
export async function createAuthor(client: Client, args: CreateAuthorArgs): Promise<CreateAuthorRow | null> {
const result = await client.query({
text: createAuthorQuery,
values: [args.name, args.bio],
rowMode: "array"
});
if (result.rows.length !== 1) {
return null;
}
const row = result.rows[0];
return {
id: row[0],
name: row[1],
bio: row[2]
};
}
export const deleteAuthorQuery = `-- name: DeleteAuthor :exec
DELETE FROM authors
WHERE id = $1`;
export interface DeleteAuthorArgs {
id: string;
}
export async function deleteAuthor(client: Client, args: DeleteAuthorArgs): Promise<void> {
await client.query({
text: deleteAuthorQuery,
values: [args.id],
rowMode: "array"
});
}