kysely-codegen

repository·master·Indexed 22 days ago

https://github.com/robinblomberg/kysely-codegen

A tool that automatically generates TypeScript type definitions for Kysely based on an existing database schema. It supports multiple dialects including PostgreSQL, MySQL, SQLite, MSSQL, and LibSQL. The tool provides features for custom type mapping, column overrides, and camel-case conversion, and can be configured via CLI arguments, configuration files, or programmatically using the Cli class.

Tokens
6.5K
Snippets
16
Records
35
Agent score
78%

What's inside kysely-codegen

  1. Understand the generated output format

    master

    The generator produces a TypeScript file containing interfaces for your tables (models) and a central DB interface. When using customImports, overrides, or typeMapping, the generated code will include the corresponding imports and type definitions.

    import type { InstantRange } from './custom-types';
    import type { MyCustomType } from '@my-org/custom-types';
    import type { OriginalType as AliasedType } from './types';
    import type { Temporal } from '@js-temporal/polyfill';
    
    export interface EventModel {
      createdAt: Temporal.Instant;
      dateRange: ColumnType<InstantRange, InstantRange, never>;
      eventDate: Temporal.PlainDate;
    }
    
    export interface UserModel {
      settings: { theme: 'dark' };
    }
    
    // ...
    
    export interface DB {
      bacchi: Bacchus;
      events: EventModel;
      users: UserModel;
    }
  2. Use advanced configuration for custom types and overrides

    master

    For complex type generation, use the following advanced configuration keys:

    • customImports: Map type names to specific import paths. Supports aliasing using the # syntax (e.g., ./types#OriginalType).
    • overrides: Manually define types for specific columns or tables. You can use ColumnType<Read, Write, Input> or literal object structures.
    • singularize: Provide regex patterns to transform table names into model names.
    • typeMapping: Map database types (like timestamptz) to specific TypeScript types (like Temporal.Instant).
    {
      "camelCase": true,
      "customImports": {
        "InstantRange": "./custom-types",
        "MyCustomType": "@my-org/custom-types",
        "AliasedType": "./types#OriginalType"
      },
      "overrides": {
        "columns": {
          "events.date_range": "ColumnType<InstantRange, InstantRange, never>",
          "posts.author_type": "AliasedType",
          "users.settings": "{ theme: 'dark' }"
        }
      },
      "singularize": {
        "/^(.*?)s?$/": "$1_model",
        "/(bacch)(?:us|i)$/i": "$1us"
      },
      "typeMapping": {
        "date": "Temporal.PlainDate",
        "interval": "Temporal.Duration",
        "timestamptz": "Temporal.Instant"
      }
    }
  3. Generate Kysely type definitions

    master

    The easiest way to generate types is to set a DATABASE_URL environment variable in an .env file and run the kysely-codegen command.

    Supported Connection String Formats:

    • PostgreSQL: postgres://username:password@yourdomain.com/database
    • MySQL: mysql://username:password@yourdomain.com/database
    • SQLite: C:/Program Files/sqlite3/db (path to file)
    • MSSQL: Server=mssql;Database=database;User Id=user;Password=password
    • LibSQL: libsql://token@host:port/database

    Note: If using PlanetScale, include the SSL query string parameter: ssl={"rejectUnauthorized":true}.

    To specify a custom output path for the generated .d.ts file, use the --out-file flag.

    kysely-codegen --out-file ./src/db/db.d.ts
  4. Install kysely-codegen and database drivers

    master

    To use kysely-codegen, install it as a development dependency. You must also install kysely along with the driver specific to your database.

    # Install the codegen
    npm install --save-dev kysely-codegen
    
    # Install Kysely and your driver
    # PostgreSQL
    npm install kysely pg
    
    # MySQL
    npm install kysely mysql2
    
    # SQLite
    npm install kysely better-sqlite3
    
    # MSSQL
    npm install kysely tedious tarn @tediousjs/connection-string@1.0.0
    
    # LibSQL
    npm install @libsql/kysely-libsql
    npm install --save-dev kysely-codegen
  5. Configure custom type imports and overrides

    master

    Use --custom-imports to map database types to custom TypeScript types from external packages or local files. You can use the # syntax for named imports with aliasing.

    Basic Example:

    # Map 'InstantRange' to a local file
    kysely-codegen --custom-imports='{"InstantRange":"./custom-types"}'

    Named Imports with Aliasing:

    # Import 'OriginalType' from './types' and alias it as 'MyType'
    kysely-codegen --custom-imports='{"MyType":"./types#OriginalType"}'

    After defining custom imports, you can use --overrides to apply specific ColumnType definitions to columns using the table_name.column_name syntax.

    kysely-codegen --custom-imports='{"MyType":"./types#OriginalType","DateRange":"@org/utils#CustomDateRange"}'
  6. Configure `kysely-codegen` via CLI flags or config file

    master

    You can configure the generator using command-line flags or by providing a configuration file via the --config-file flag. When both are used, CLI flags take precedence over configuration file settings.

    Note on Deprecations:

    • Use --default-schema instead of --schema.
    • Use --singularize instead of --singular.
  7. Run database environments via Docker Compose

    master

    The project provides a docker-compose.yml file to quickly spin up local development environments for various database engines supported by kysely-codegen. You can use these services to host your schema before running the codegen tool.

    Available services include:

    • kysely_codegen_postgres: PostgreSQL
    • kysely_codegen_mysql: MySQL
    • kysely_codegen_libsql: LibSQL
    • kysely_codegen_adminer: A web-based database management tool (Adminer) accessible on port 8081.
  8. Use generated type definitions in Kysely

    master

    Once generated, import the DB type into your Kysely instance to enable full type safety for your queries.

    import { Kysely, PostgresDialect } from 'kysely';
    import { DB } from './path/to/generated/db'; // Import your generated DB type
    import { Pool } from 'pg';
    
    const db = new Kysely<DB>({
      dialect: new PostgresDialect({
        pool: new Pool({
          connectionString: process.env.DATABASE_URL,
        }),
      }),
    });
    
    // Queries are now type-safe
    const rows = await db.selectFrom('users').selectAll().execute();

    For function parameters, use Kysely's Insertable, Selectable, and Updateable utility types combined with the generated table interfaces.

    import { Kysely, PostgresDialect } from 'kysely';
    import { DB } from 'kysely-codegen';
    import { Pool } from 'pg';
    
    const db = new Kysely<DB>({
      dialect: new PostgresDialect({
        pool: new Pool({
          connectionString: process.env.DATABASE_URL,
        }),
      }),
    });
    
    const rows = await db.selectFrom('users').selectAll().execute();
    //    ^ { created_at: Date; email: string; id: number; ... }[]
  9. Map database types using --type-mapping

    master

    The --type-mapping flag allows you to automatically map all columns of a specific database type to a custom TypeScript type. This is more efficient than overriding individual columns.

    Example: To map PostgreSQL timestamptz to a Temporal.Instant type:

    # 1. Define the mapping
    # 2. Provide the custom import for the target type
    kysely-codegen --type-mapping='{"timestamptz":"Temporal.Instant"}' --custom-imports='{"Temporal":"@js-temporal/polyfill"}'
  10. Configure MySQL for local development

    master

    The kysely_codegen_mysql service uses the official mysql:latest image. You can configure the database using the following environment variables:

    • MYSQL_DATABASE: The name of the database to create.
    • MYSQL_USER: The username for the database.
    • MYSQL_PASSWORD: The password for the user.
    • MYSQL_ROOT_PASSWORD: The password for the root user.

    By default, it maps the internal port 3306 to host port 3306.

    services:
      kysely_codegen_mysql:
        image: mysql:latest
        environment:
          - MYSQL_DATABASE=database
          - MYSQL_PASSWORD=password
          - MYSQL_ROOT_PASSWORD=password
          - MYSQL_USER=user
        ports:
          - 3306:3306