Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/alloc/tusken
100% type-safe query builder compatible with any Postgres client š Generated table/function types, tree-shakable, implicit type casts, and more
https://github.com/alloc/tusken
postgres query-builder typescript
Last synced: about 1 month ago
JSON representation
100% type-safe query builder compatible with any Postgres client š Generated table/function types, tree-shakable, implicit type casts, and more
- Host: GitHub
- URL: https://github.com/alloc/tusken
- Owner: alloc
- License: other
- Created: 2022-08-26T12:05:25.000Z (over 2 years ago)
- Default Branch: alpha
- Last Pushed: 2024-05-31T20:27:37.000Z (7 months ago)
- Last Synced: 2024-11-09T15:04:02.851Z (about 1 month ago)
- Topics: postgres, query-builder, typescript
- Language: TypeScript
- Homepage:
- Size: 858 KB
- Stars: 223
- Watchers: 7
- Forks: 3
- Open Issues: 37
-
Metadata Files:
- Readme: readme.md
- License: LICENSE.md
Awesome Lists containing this project
README
ā ļø This library is currently in alpha. Contributors wanted!
---
# tusken
Postgres client from a galaxy far, far away.
- your database is the source-of-truth for TypeScript generated types
- type safety for all queries (even subqueries)
- all built-in Postgres functions are available and type-safe
- implicit type casts are accounted for
- minimal, intuitive SQL building
- shortcuts for common tasks (eg: `get`, `put`, and more)
- identifiers are case-sensitive
- lightweight, largely tree-shakeable
- works with [`@tusken/cli`] to easily import CSV files, wipe data, generate a type-safe client, dump the schema for migrations, and more
- you control the [`pg`] version as a peer dependency
- query streaming with the `.stream` method (just install [`pg-query-stream`] and run `tusken generate`)[`pg`]: https://www.npmjs.com/package/pg
[`pg-query-stream`]: https://www.npmjs.com/package/pg-query-stream
[`@tusken/cli`]: https://github.com/alloc/tusken/tree/master/packages/tusken-cli### Migrations?
Use [graphile-migrate](https://github.com/graphile/migrate).
## Install
```sh
pnpm i tusken@alpha pg postgres-range postgres-interval
pnpm i @tusken/cli@alpha -D
```## Usage
First, you need a `tusken.config.ts` file in your project root, unless you plan on using the default config. By default, the Postgres database is assumed to exist at `./postgres` relative to the working directory (customize with `dataDir` in your config) and the generated types are emitted into the `./src/generated` folder (customize with `schemaDir` in your config).
```ts
import { defineConfig } from 'tusken/config'export default defineConfig({
dataDir: './postgres',
schemaDir: './src/generated',
connection: {
host: 'localhost',
port: 5432,
user: 'postgres',
password: ' ',
},
pool: {
/* node-postgres pooling options */
},
})
```After running `pnpm tusken generate -d ` in your project root, you can import the database client from `./src/db/` as **the default export.**
```ts
import db, { t, pg } from './db/'
```The `t` export contains your user-defined Postgres tables and many native types. The `pg` export contains your user-defined Postgres functions and many built-in functions.
### Creating, updating, deleting one row
Say we have a basic `user` table like thisā¦
```sql
create table "user" (
"id" serial primary key,
"name" text,
"password" text
)
```To create a user, use the `put` methodā¦
```ts
// Create a user
await db.put(t.user, { name: 'anakin', password: 'padme4eva' })// Update a user (merge, not replace)
await db.put(t.user, 1, { name: 'vader', password: 'darkside4eva' })// Delete a user
await db.put(t.user, 1, null)
```### Getting a row by primary key
Here we can use the `get` methodā¦
```ts
await db.get(t.user, 1)
```Selections are supportedā¦
```ts
await db.get(
t.user(u => [u.name]),
1
)
```Selections can have aliasesā¦
```ts
await db.get(
t.user(u => [{ n: u.name }]),
1
)// You can omit the array if you don't mind giving
// everything an alias.
await db.get(
t.user(u => ({ n: u.name })),
1
)
```Selections can contain function callsā¦
```ts
await db.get(
t.user(u => ({
name: pg.upper(u.name),
})),
1
)
```To select all but a few columnsā¦
```ts
await db.get(t.user.omit('id', 'password'), 1)
```### Inner joins
```ts
// Find all books with >= 100 likes and also get the author of each.
await db.select(t.author).innerJoin(
t.book.where(b => b.likes.gte(100)),
t => t.author.id.eq(t.book.authorId)
)
```Ā
## What's planned?
This is a vague roadmap. Nothing here is guaranteed to be implemented soon, but they will be at some point (contributors welcome).
- math operators
- enum types
- domain types
- composite types
- more geometry types
- array-based primary key
- `ANY` and `SOME` operators
- transactions
- explicit [locking](https://www.postgresql.org/docs/current/explicit-locking.html)
- views & [materialized views](https://www.postgresql.org/docs/14/rules-materializedviews.html)
- table [inheritance](https://www.postgresql.org/docs/current/tutorial-inheritance.html)
- window functions
- plugin packages
- these plugins can do any of:
- alter your schema
- seed your database
- extend the runtime API
- auto-loading of packages with `tusken-plugin-abc` or `@xyz/tusken-plugin-abc` naming scheme
- add some new commands
- `tusken install` (merge plugin schemas into your database)
- `tusken seed` (use plugins to seed your database)
- `NOTIFY`/`LISTEN` support (just copy `pg-pubsub`?)
- define Postgres functions with TypeScript
- more shortcuts for common tasks## What could be improved?
This is a list of existing features that aren't perfect yet. If you find a good candidate for this list, please add it and open a PR.
Contributions are extra welcome in these places:
- comprehensive "playground" example
- subquery support is incomplete
- bug: selectors cannot treat single-column set queries like an array of scalars
- type safety of comparison operators
- all operators are allowed, regardless of data type
- see `.where` methods and `is` function
- the `jsonb` type should be generic
- with option to infer its subtype at build-time from current row data
- missing SQL commands
- `WITH`
- `GROUP BY`
- `UPDATE`
- `MERGE`
- `USING`
- `HAVING`
- `DISTINCT ON`
- `INTERSECT`
- `CASE`
- etc