An open API service indexing awesome lists of open source software.

https://github.com/feathers-studio/true-pg

Most complete and truthful TypeScript type generator for PostgreSQL. Supports Kysely and Zod generation!
https://github.com/feathers-studio/true-pg

Last synced: 3 months ago
JSON representation

Most complete and truthful TypeScript type generator for PostgreSQL. Supports Kysely and Zod generation!

Awesome Lists containing this project

README

          

# true-pg

A truthful and complete [^1] TypeScript code generator for PostgreSQL database schemas.

## Installation

```bash
npm install true-pg
# or
yarn add true-pg
# or
bun add true-pg
```

## Quickstart

```bash
npx true-pg --all-generators --uri postgres://user:password@localhost:5432/database --out ./models
```

This will generate a `models` directory with the following structure:

```
models/
├── index.ts
├── public/
│ ├── index.ts
│ ├── tables/
│ │ ├── index.ts
│ │ └── User.ts
│ └── views/
│ ├── enums/
│ └── ...
```

You can then import the `Database` type from the `index.ts` file and pass it to Kysely:

```typescript
import { Kysely } from "kysely";
import { Database } from "./models/index.ts";

const db = new Kysely( ... );
```

## Sample Database

A sample database and generated models are available in the `sample` directory. You can browse the generated models in the `sample/models` directory.

To run the sample yourself, run:

```bash
bun install # install dependencies
cd sample
bun run ../src/bin.ts
```

## Detailed Usage

### Command Line Interface

```bash
true-pg [options]
```

Options:

- `-h, --help` - Show help information
- `-c, --config [path]` - Path to config file (JSON)
- `-u, --uri [uri]` - Database URI (Postgres only!)
- `-o, --out [path]` - Path to output directory (defaults to "models")
- `-g, --generator [generator]` - Generator to use (e.g. `kysely`, `zod`). Can be specified multiple times.
- `-A, --all-generators` - Enable all built-in generators

You can configure true-pg either through command-line arguments or a config file.

### Configuration file

If an explicit config file is not provided via `--config`, true-pg will look for a config file in the current working directory.

We use cosmiconfig to load the config file. See the [cosmiconfig docs](https://github.com/cosmiconfig/cosmiconfig#usage-for-end-users) for all possible config file formats.

The recommended default is `truepg.config.ts`, or `.config/truepg.ts`.

Example config file:

```typescript
import { config } from "true-pg";

export default config({
uri: "postgres://user:password@localhost:5432/database",
out: "src/models",
generators: ["kysely", "zod"],
defaultSchema: "public",
});
```

## Configuration Options

| Option | Description | Default |
| --------------- | -------------------------------------------------------- | ------------------- |
| `uri` | PostgreSQL connection URI | Required, or config |
| `config` | Knex connection config object | Required, or uri |
| `out` | Output directory for generated files | `"models"` |
| `generators` | Generators to use (e.g. `kysely`, `zod`) | `"kysely"` |
| `defaultSchema` | Default schema to use (Kysely schema will be unprefixed) | `"public"` |

## Customising Code Generation

> 🔔 HERE BE DRAGONS!
>
> Keep in mind that programmatic usage of `true-pg` is not yet stable. Functions and methods may change until we're comfortable with the API.
>
> However, if you're interested, we welcome your feedback and contributions!

You can create a custom generator to control how code is generated:

```typescript
import { createGenerator, generate } from "true-pg";

const generator = createGenerator(opts => ({
formatSchemaName: name => `${name}Schema`,
formatSchemaMemberName: type => `${type.name}Type`,
formatType: (ctx, type) => `${type}Interface`,
table: (ctx, table) => {
// Custom table type generation
},
enum: (ctx, en) => {
// Custom enum type generation
},
composite: (ctx, composite) => {
// Custom composite type generation
},
function: (ctx, func) => {
// Custom function type generation
},
schemaKindIndex: (ctx, schema, kind) => {
// Custom schema kind index generation
},
schemaIndex: (ctx, schema) => {
// Custom schema index generation
},
fullIndex: (ctx, schemas) => {
// Custom full index generation
},
}));

await generate(
{
uri: "postgres://user:password@localhost:5432/database",
generators: [], // empty array to disable generators
out: "src/models",
},
[generator],
);
```

Filenames will be created using the `format*` methods of the FIRST generator passed to `generate` or via the `--generator` CLI option.

## Schema Generator Interface

The `SchemaGenerator` interface provides methods to customize code generation:

| Method | Description |
| ------------------------------- | ----------------------------------------------------------------- |
| `formatSchema(name)` | Formats schema names (public -> PublicSchema) |
| `formatSchemaType(type)` | Formats schema type names (user_sessions -> UserSessions) |
| `formatType(type)` | Formats type names (pg_catalog.int4 -> number) |
| `table(types, table)` | Generates code for tables |
| `view(types, view)` | Generates code for views |
| `materialisedView(types, view)` | Generates code for materialised views |
| `enum(types, en)` | Generates code for enums |
| `composite(types, composite)` | Generates code for composite types |
| `domain(types, domain)` | Generates code for domains |
| `range(types, range)` | Generates code for ranges |
| `function(types, func)` | Generates code for functions |
| `schemaKindIndex(schema, kind)` | Generates index for a schema kind (models/public/tables/index.ts) |
| `schemaIndex(schema)` | Generates index for a schema (models/public/index.ts) |
| `fullIndex(schemas)` | Generates full index (models/index.ts) |

## License

[MIT](LICENSE)

[^1]: We support codegen for tables, views, materialized views, enums, composite types, domains, ranges, and functions.