kysely-org / kysely-ctl

Command-line tool for Kysely
MIT License
46 stars 1 forks source link

Type-safe seed file generation #42

Open igalklebanov opened 2 weeks ago

igalklebanov commented 2 weeks ago

closes #40.

Hey :wave:

Seed files, unlike migrations, need to evolve with the codebase and the database schema. Thus, they have to be type-safe and bound to the latest Database interface. But, kysely seed make uses Kysely<any>.

This PR adds the ability to generate type-safe seed files.

Adds a databaseInterface prop @ config.seeds, with the given type:

export type DatabaseInterface = 'auto' | 'off' | DatabaseInterfaceConfig

export interface DatabaseInterfaceConfig {
    /**
     * Whether the database interface is the default export.
     *
     * Default is `false`.
     */
    isDefaultExport?: boolean

    /**
     * Name of the database interface.
     *
     * Default is `'DB'`.
     */
    name?: string

    /**
     * Path to the database interface, relative to the seed folder.
     */
    path: string
}

The default is auto.

auto will try to resolve a DatabaseInterfaceConfig based on installed codegen libraries and their configuration. If it fails, will fallback to off.

off falls back to Kysely<any> (non-type-safe template).


OLD VERSION..

Adds a databaseInterfacePath prop @ config.seeds, with the given structure:

<file-path-relative-to-seed-folder-or-node-modules>[#<database-type-name>]

If kysely-codegen is detected, it defaults to using DB from kysely-codegen

import type { DB } from 'kysely-codegen'
import type { Kysely } from 'kysely'

export async function seed(db: Kysely<DB>): Promise<void> {
    // seed code goes here...
    // note: this function is mandatory. you must implement this function.
}

, otherwise uses a non-type-safe template with Kysely<any>.

import type { Kysely } from "kysely";

export async function seed(db: Kysely<any>): Promise<void> {
  // seed code goes here...
  // note: this function is mandatory. you must implement this function.
}

If a path is provided without a database name prefix (#DBName), and prisma-kysely is installed, Database interface name defaults to DB.

import type { DB } from 'path/to/prisma/types'
import type { Kysely } from 'kysely'

export async function seed(db: Kysely<DB>): Promise<void> {
    // seed code goes here...
    // note: this function is mandatory. you must implement this function.
}