A truthful and complete 1 TypeScript code generator for PostgreSQL database schemas.
npm install true-pg
# or
yarn add true-pg
# or
bun add true-pg
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:
import { Kysely } from "kysely";
import { Database } from "./models/index.ts";
const db = new Kysely<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:
bun install # install dependencies
cd sample
bun run ../src/bin.ts
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.
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 for all possible config file formats.
The recommended default is truepg.config.ts
, or .config/truepg.ts
.
Example config file:
import { config } from "true-pg";
export default config({
uri: "postgres://user:password@localhost:5432/database",
out: "src/models",
generators: ["kysely", "zod"],
defaultSchema: "public",
});
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" |
🔔 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:
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.
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) |
Footnotes
-
We support codegen for tables, views, materialized views, enums, composite types, domains, ranges, and functions. ↩