### Install MySQL Driver Source: https://github.com/kysely-org/kysely-typeorm/blob/main/README.md Install the MySQL driver for use with TypeORM and Kysely. ```sh npm i mysql2 ``` -------------------------------- ### Install PostgreSQL Driver Source: https://github.com/kysely-org/kysely-typeorm/blob/main/README.md Install the PostgreSQL driver for use with TypeORM and Kysely. ```sh npm i pg ``` -------------------------------- ### Install SQLite Driver Source: https://github.com/kysely-org/kysely-typeorm/blob/main/README.md Install the SQLite driver for use with TypeORM and Kysely. ```sh npm i better-sqlite3 ``` -------------------------------- ### Install Kysely and TypeORM Dependencies Source: https://github.com/kysely-org/kysely-typeorm/blob/main/README.md Install the main dependencies for Kysely and TypeORM. Additional packages are required for specific database support. ```sh npm i kysely kysely-typeorm typeorm ``` -------------------------------- ### Install MS SQL Server (MSSQL) Driver Source: https://github.com/kysely-org/kysely-typeorm/blob/main/README.md Install the MS SQL Server driver. Note that TypeORM uses 'mssql' which is different from Kysely's core drivers. ```sh npm i mssql ``` -------------------------------- ### Multi-Dialect Sub-Dialect Setup for Kysely-TypeORM Source: https://context7.com/kysely-org/kysely-typeorm/llms.txt Configure Kysely sub-dialects to match TypeORM data source types. This setup supports PostgreSQL, MySQL, MSSQL, and SQLite (both 'sqlite' and 'better-sqlite3' TypeORM types). Ensure the `kyselySubDialect` matches the TypeORM data source. ```typescript import { MssqlAdapter, MssqlIntrospector, MssqlQueryCompiler, MysqlAdapter, MysqlIntrospector, MysqlQueryCompiler, PostgresAdapter, PostgresIntrospector, PostgresQueryCompiler, SqliteAdapter, SqliteIntrospector, SqliteQueryCompiler, } from 'kysely' import type { KyselySubDialect } from 'kysely-typeorm' const subDialects: Record = { postgres: { createAdapter: () => new PostgresAdapter(), createIntrospector: (db) => new PostgresIntrospector(db), createQueryCompiler: () => new PostgresQueryCompiler(), }, mysql: { createAdapter: () => new MysqlAdapter(), createIntrospector: (db) => new MysqlIntrospector(db), createQueryCompiler: () => new MysqlQueryCompiler(), }, mssql: { createAdapter: () => new MssqlAdapter(), createIntrospector: (db) => new MssqlIntrospector(db), createQueryCompiler: () => new MssqlQueryCompiler(), }, // shared for both 'sqlite' and 'better-sqlite3' TypeORM types: sqlite: { createAdapter: () => new SqliteAdapter(), createIntrospector: (db) => new SqliteIntrospector(db), createQueryCompiler: () => new SqliteQueryCompiler(), }, } ``` -------------------------------- ### Configure KyselyTypeORMDialect with MySQL Sub-Dialect Source: https://context7.com/kysely-org/kysely-typeorm/llms.txt Shows how to define the `KyselySubDialect` for MySQL and use it within the `KyselyTypeORMDialectConfig` to initialize the dialect. This configuration is passed to the `KyselyTypeORMDialect` constructor. ```typescript import { MysqlAdapter, MysqlIntrospector, MysqlQueryCompiler, } from 'kysely' import { DataSource } from 'typeorm' import { KyselyTypeORMDialect, type KyselyTypeORMDialectConfig, type KyselySubDialect, } from 'kysely-typeorm' const mysqlSubDialect: KyselySubDialect = { createAdapter: () => new MysqlAdapter(), createIntrospector: (db) => new MysqlIntrospector(db), createQueryCompiler: () => new MysqlQueryCompiler(), } const config: KyselyTypeORMDialectConfig = { kyselySubDialect: mysqlSubDialect, typeORMDataSource: new DataSource({ type: 'mysql', host: 'localhost', port: 3308, username: 'kysely', password: 'kysely', database: 'kysely_test', bigNumberStrings: true, supportBigNumbers: true, entities: [], }), } const dialect = new KyselyTypeORMDialect(config) ``` -------------------------------- ### Create Kysely Instance with TypeORM DataSource Source: https://github.com/kysely-org/kysely-typeorm/blob/main/README.md Initializes a Kysely instance, passing the TypeORM DataSource to `KyselyTypeORMDialect`. This allows Kysely to interact with the TypeORM connection. Optional plugins like `CamelCasePlugin` can be included. ```typescript import { CamelCasePlugin, // optional Kysely, PostgresAdapter, PostgresIntrospector, PostgresQueryCompiler, } from "kysely"; import { KyselyTypeORMDialect } from "kysely-typeorm"; import type { Database } from "./types/database"; import { dataSource } from "./typeorm"; export const kysely = new Kysely({ dialect: new KyselyTypeORMDialect({ // kysely-typeorm also supports MySQL, MS SQL Server (MSSQL), and SQLite. kyselySubDialect: { createAdapter: () => new PostgresAdapter(), createIntrospector: (db) => new PostgresIntrospector(db), createQueryCompiler: () => new PostgresQueryCompiler(), }, typeORMDataSource: dataSource, }), // `CamelCasePlugin` is used to align with `typeorm-naming-strategies`'s `SnakeNamingStrategy`. plugins: [new CamelCasePlugin()], // optional }); ``` -------------------------------- ### KyselyTypeORMDialect Usage Source: https://context7.com/kysely-org/kysely-typeorm/llms.txt Demonstrates how to initialize a TypeORM DataSource and then use it to construct a Kysely instance with KyselyTypeORMDialect for type-safe queries. ```APIDOC ## KyselyTypeORMDialect ### Description `KyselyTypeORMDialect` implements Kysely's `Dialect` interface, allowing you to use Kysely's type-safe query builder with an existing TypeORM `DataSource`. ### Method Constructor ### Parameters - **config** (KyselyTypeORMDialectConfig) - Required - Configuration object for the dialect. - **kyselySubDialect** (KyselySubDialect) - Required - The Kysely sub-dialect matching the TypeORM driver (e.g., PostgresAdapter, PostgresIntrospector, PostgresQueryCompiler). - **typeORMDataSource** (DataSource) - Required - An initialized TypeORM `DataSource` instance. ### Request Example ```ts import 'reflect-metadata' import { CamelCasePlugin, Kysely, ParseJSONResultsPlugin, PostgresAdapter, PostgresIntrospector, PostgresQueryCompiler, } from 'kysely' import { DataSource } from 'typeorm' import { SnakeNamingStrategy } from 'typeorm-naming-strategies' import { KyselyTypeORMDialect } from 'kysely-typeorm' import { PersonEntity, PetEntity, ToyEntity } from './entities' import type { Database } from './types' // 1. Create (or reuse) an existing TypeORM DataSource. const dataSource = new DataSource({ type: 'postgres', host: 'localhost', port: 5434, username: 'kysely', database: 'kysely_test', entities: [PersonEntity, PetEntity, ToyEntity], namingStrategy: new SnakeNamingStrategy(), poolSize: 10, useUTC: true, logging: false, }) await dataSource.initialize() await dataSource.synchronize() // 2. Construct the Kysely instance with KyselyTypeORMDialect. export const kysely = new Kysely({ dialect: new KyselyTypeORMDialect({ // Provide the sub-dialect matching the TypeORM driver. kyselySubDialect: { createAdapter: () => new PostgresAdapter(), createIntrospector: (db) => new PostgresIntrospector(db), createQueryCompiler: () => new PostgresQueryCompiler(), }, typeORMDataSource: dataSource, }), plugins: [ new ParseJSONResultsPlugin(), // parses JSON columns automatically new CamelCasePlugin(), // maps snake_case columns to camelCase ], }) // 3. Run a type-safe query. const people = await kysely .selectFrom('person') .select(['id', 'firstName', 'lastName', 'gender']) .where('gender', '=', 'female') .orderBy('id', 'asc') .execute() // => [{ id: 1, firstName: 'Jennifer', lastName: 'Aniston', gender: 'female' }] ``` ``` -------------------------------- ### KyselyTypeORMDialectConfig Interface Source: https://context7.com/kysely-org/kysely-typeorm/llms.txt Defines the configuration object required for initializing `KyselyTypeORMDialect`, specifying the Kysely sub-dialect and the TypeORM DataSource. ```APIDOC ## KyselyTypeORMDialectConfig ### Description `KyselyTypeORMDialectConfig` is the shape of the object passed to `KyselyTypeORMDialect`. It requires exactly two properties: `kyselySubDialect` and `typeORMDataSource`. ### Properties - **kyselySubDialect** (KyselySubDialect) - Required - The Kysely sub-dialect matching the TypeORM data source type. - **typeORMDataSource** (DataSource) - Required - The already-created TypeORM `DataSource` instance. ### Request Example ```ts import { MysqlAdapter, MysqlIntrospector, MysqlQueryCompiler, } from 'kysely' import { DataSource } from 'typeorm' import { KyselyTypeORMDialect, type KyselyTypeORMDialectConfig, type KyselySubDialect, } from 'kysely-typeorm' const mysqlSubDialect: KyselySubDialect = { createAdapter: () => new MysqlAdapter(), createIntrospector: (db) => new MysqlIntrospector(db), createQueryCompiler: () => new MysqlQueryCompiler(), } const config: KyselyTypeORMDialectConfig = { kyselySubDialect: mysqlSubDialect, typeORMDataSource: new DataSource({ type: 'mysql', host: 'localhost', port: 3308, username: 'kysely', password: 'kysely', database: 'kysely_test', bigNumberStrings: true, supportBigNumbers: true, entities: [], }), } const dialect = new KyselyTypeORMDialect(config) ``` ``` -------------------------------- ### Update Toy Entity with Kysely-TypeORM Types Source: https://github.com/kysely-org/kysely-typeorm/blob/main/README.md Illustrates updating the `ToyEntity` with `Generated` and `NonAttribute` types from `kysely-typeorm` for seamless Kysely usage. ```typescript import type {Generated, NonAttribute} from 'kysely-typeorm' import {BaseEntity, Column, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn, RelationId} from 'typeorm' import {PetEntity} from './Pet' @Entity({name: 'toy'}) export class ToyEntity extends BaseEntity { @PrimaryGeneratedColumn({type: 'integer'}) id: Generated @Column({type: 'varchar', length: 255, unique: true}) name: string @Column({type: 'double precision'}) price: number @ManyToOne(() => PetEntity, (pet) => pet.toys, {onDelete: 'CASCADE'}) @JoinColumn({name: 'pet_id', referencedColumnName: 'id'}) pet: NonAttribute @RelationId((toy: ToyEntity) => toy.pet) petId: number } ``` -------------------------------- ### Update Pet Entity with Kysely-TypeORM Types Source: https://github.com/kysely-org/kysely-typeorm/blob/main/README.md Shows how to update the `PetEntity` using `Generated` and `NonAttribute` types from `kysely-typeorm` for better integration with Kysely. ```typescript import type {Generated, NonAttribute} from 'kysely-typeorm' import { BaseEntity, Column, Entity, Index, JoinColumn, ManyToOne, OneToMany, PrimaryGeneratedColumn, RelationId, } from 'typeorm' import {PersonEntity} from './Person' import {ToyEntity} from './Toy' @Entity({name: 'pet'}) export class PetEntity extends BaseEntity { @PrimaryGeneratedColumn() id: Generated @Column({type: 'varchar', length: 255, unique: true}) name: string @ManyToOne(() => PersonEntity, (person) => person.pets, {onDelete: 'CASCADE'}) @JoinColumn({name: 'owner_id', referencedColumnName: 'id'}) @Index('pet_owner_id_index') owner: NonAttribute @RelationId((pet: PetEntity) => pet.owner) ownerId: number @Column({type: 'varchar', length: 50}) species: 'dog' | 'cat' | 'hamster' @OneToMany(() => ToyEntity, (toy) => toy.pet, {cascade: ['insert']}) toys: NonAttribute } ``` -------------------------------- ### Stream Query Results with Kysely Source: https://context7.com/kysely-org/kysely-typeorm/llms.txt Use the `.stream()` method to iterate over query results one row at a time, suitable for large tables to avoid loading everything into memory. This works transparently through TypeORM's QueryRunner for supported dialects. ```typescript for await (const person of kysely .selectFrom('person') .selectAll() .stream()) { console.log(person.firstName, person.lastName) // Each iteration yields one row: { id, firstName, lastName, gender, ... } } ``` -------------------------------- ### Transaction support with isolation levels Source: https://context7.com/kysely-org/kysely-typeorm/llms.txt KyselyTypeORMDialect supports Kysely's standard transaction() API by delegating to TypeORM's QueryRunner. Isolation levels are mapped from Kysely's names to TypeORM's, though 'snapshot' isolation is not supported and will throw an error. ```typescript // Supported isolation levels: 'read committed', 'read uncommitted', // 'repeatable read', 'serializable' const result = await kysely.transaction().execute(async (trx) => { const person = await trx .insertInto('person') .values({ gender: 'female', firstName: 'Jennifer', lastName: 'Aniston' }) .returning('id') .executeTakeFirstOrThrow() await trx .insertInto('pet') .values({ name: 'Catto', species: 'cat', ownerId: person.id }) .execute() return person }) // With explicit isolation level: await kysely .transaction() .setIsolationLevel('serializable') .execute(async (trx) => { await trx .updateTable('person') .set({ maritalStatus: 'widowed' }) .where('id', '=', 1) .execute() }) ``` -------------------------------- ### Define Database Schema with KyselifyEntity Source: https://github.com/kysely-org/kysely-typeorm/blob/main/README.md Defines the Kysely database schema by translating TypeORM entities into Kysely table types using the `KyselifyEntity` helper. This ensures type safety for database operations. ```typescript import type { KyselifyEntity } from "kysely-typeorm"; import type { PersonEntity } from "../entities/Person"; import type { PetEntity } from "../entities/Pet"; import type { ToyEntity } from "../entities/Toy"; export type PersonTable = KyselifyEntity; // ^? { id: Generated, firstName: string | null, ... } export type PetTable = KyselifyEntity; export type ToyTable = KyselifyEntity; export interface Database { person: PersonTable; pet: PetTable; toy: ToyTable; } ``` -------------------------------- ### Mark Always DB-Generated and Read-Only Columns with GeneratedAlways Source: https://context7.com/kysely-org/kysely-typeorm/llms.txt GeneratedAlways maps to Kysely's GeneratedAlways, ensuring the column is omitted from INSERT and UPDATE operations. This is ideal for surrogate primary keys that should never be manually provided. ```typescript import { PrimaryGeneratedColumn, Entity } from 'typeorm' import type { GeneratedAlways } from 'kysely-typeorm' @Entity({ name: 'comment' }) export class CommentEntity { @PrimaryGeneratedColumn() id: GeneratedAlways // cannot be provided in INSERT or UPDATE // ... } // TypeScript compile error if you try to provide 'id' in .values({ id: 5, ... }) await kysely.insertInto('comment').values({ body: 'Nice post!' }).execute() ``` -------------------------------- ### Update Person Entity with Kysely-TypeORM Types Source: https://github.com/kysely-org/kysely-typeorm/blob/main/README.md Demonstrates updating the `PersonEntity` to use Kysely-TypeORM's `Generated`, `JSONColumnType`, `SimpleArray`, and `NonAttribute` types for enhanced type safety and compatibility with Kysely. ```typescript import type {Generated, JSONColumnType, NonAttribute, SimpleArray} from 'kysely-typeorm' import {BaseEntity, Column, Entity, OneToMany, PrimaryGeneratedColumn} from 'typeorm' import {PetEntity} from './Pet' @Entity({name: 'person'}) export class PersonEntity extends BaseEntity { @PrimaryGeneratedColumn() id: Generated @Column({type: 'varchar', length: 255, nullable: true}) firstName: string | null @Column({type: 'varchar', length: 255, nullable: true}) middleName: string | null @Column({type: 'varchar', length: 255, nullable: true}) lastName: string | null @Column({type: 'varchar', length: 50}) gender: 'male' | 'female' | 'other' @Column({type: 'varchar', length: 50, nullable: true}) maritalStatus: 'single' | 'married' | 'divorced' | 'widowed' | null @Column({type: 'simple-array', nullable: true}) listOfDemands: SimpleArray @Column({type: 'simple-json', nullable: true}) metadata: JSONColumnType | null> @Column({type: 'jsonb', nullable: true}) lastSession: JSONColumnType<{ loggedInAt: string } | null> @OneToMany(() => PetEntity, (pet) => pet.owner, {cascade: ['insert']}) pets: NonAttribute } ``` -------------------------------- ### Type JSON or simple-json columns with JSONColumnType Source: https://context7.com/kysely-org/kysely-typeorm/llms.txt JSONColumnType wraps Kysely's ColumnType for JSON columns. The column is read as type T but written as a string (JSON.stringify-ed value). Use this for TypeORM's 'simple-json', 'json', and 'jsonb' column types. ```typescript import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm' import type { GeneratedAlways, JSONColumnType } from 'kysely-typeorm' interface UserSettings { theme: 'light' | 'dark' language: string } @Entity({ name: 'user' }) export class UserEntity { @PrimaryGeneratedColumn() id: GeneratedAlways @Column({ type: 'simple-json', nullable: true }) settings: JSONColumnType // Select type: UserSettings | null // Insert/Update type: string | null } // INSERT — must stringify the object: await kysely .insertInto('user') .values({ settings: JSON.stringify({ theme: 'dark', language: 'en' }) }) .execute() // SELECT with ParseJSONResultsPlugin — automatically parsed back to UserSettings: const user = await kysely .selectFrom('user') .select(['id', 'settings']) .where('id', '=', 1) .executeTakeFirstOrThrow() // user.settings => { theme: 'dark', language: 'en' } ``` -------------------------------- ### Convert TypeORM Entity to Kysely Table Type with KyselifyEntity Source: https://context7.com/kysely-org/kysely-typeorm/llms.txt KyselifyEntity transforms a TypeORM entity class into a Kysely table interface. It handles specific TypeORM column types like Generated, GeneratedAlways, NonAttribute, SimpleArray, and JSONColumnType, mapping them to their Kysely equivalents or excluding them as appropriate. ```typescript import { BaseEntity, Column, CreateDateColumn, Entity, Generated as TypeORMGenerated, JoinColumn, ManyToOne, OneToMany, PrimaryGeneratedColumn, RelationId, UpdateDateColumn, } from 'typeorm' import type { Generated, GeneratedAlways, JSONColumnType, KyselifyEntity, NonAttribute, SimpleArray, } from 'kysely-typeorm' // --- Entity definitions --- @Entity({ name: 'person' }) export class PersonEntity extends BaseEntity { @PrimaryGeneratedColumn() id: GeneratedAlways // read-only, DB-generated @Column({ type: 'varchar', length: 255 }) username: string @Column({ type: 'simple-array', nullable: true }) tags: SimpleArray // stored as comma-separated string @Column({ type: 'simple-json', nullable: true }) metadata: JSONColumnType | null> @CreateDateColumn() createdAt: Generated // write-optional @UpdateDateColumn() updatedAt: Generated @Column() @TypeORMGenerated('uuid') uuid: Generated @OneToMany(() => PostEntity, (p) => p.person) posts: NonAttribute // excluded from Kysely type } // --- Derived Kysely types --- export type Person = KyselifyEntity // => { // id: GeneratedAlways // username: string // tags: string | null (raw CSV string) // metadata: ColumnType | null, string, string> // createdAt: Generated // updatedAt: Generated // uuid: Generated // // posts is absent // } export interface Database { person: Person } ``` -------------------------------- ### Type TypeORM simple-array columns with SimpleArray Source: https://context7.com/kysely-org/kysely-typeorm/llms.txt SimpleArray correctly types TypeORM's 'simple-array' column as 'string' (or 'null') in Kysely, matching the database storage. The database stores arrays as comma-separated strings, which are parsed back to arrays at the entity layer. ```typescript import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm' import type { GeneratedAlways, SimpleArray } from 'kysely-typeorm' @Entity({ name: 'person' }) export class PersonEntity { @PrimaryGeneratedColumn() id: GeneratedAlways @Column({ type: 'simple-array', nullable: true }) tags: SimpleArray // In DB: "typescript,kysely,typeorm" // KyselifyEntity types this as: string | null } // INSERT stores the raw CSV string: await kysely .insertInto('person') .values({ tags: JSON.stringify(['typescript', 'kysely']) }) .execute() // SELECT returns the raw CSV string — use ParseJSONResultsPlugin or manual parse: const row = await kysely.selectFrom('person').selectAll().executeTakeFirstOrThrow() const tags: string[] = row.tags ? row.tags.split(',') : [] ``` -------------------------------- ### Mark DB-Generated and Write-Optional Columns with Generated Source: https://context7.com/kysely-org/kysely-typeorm/llms.txt Use Generated to indicate columns that are generated by the database and are optional during insertion. This type is converted to Kysely's Generated, making the column optional on INSERT but always present on SELECT. It's suitable for auto-increment primary keys, timestamp columns, and version columns. ```typescript import { Column, Entity, PrimaryGeneratedColumn, VersionColumn, CreateDateColumn } from 'typeorm' import type { Generated } from 'kysely-typeorm' @Entity({ name: 'post' }) export class PostEntity { @PrimaryGeneratedColumn() id: Generated // optional on INSERT, always returned on SELECT @Column({ type: 'varchar' }) title: string @VersionColumn() version: Generated // auto-incremented by TypeORM on every update @CreateDateColumn() createdAt: Generated } // Usage in a query — id, version, createdAt are not required in .values(): await kysely .insertInto('post') .values({ title: 'Hello Kysely' }) // id/version/createdAt omitted safely .execute() ``` -------------------------------- ### Exclude ORM-only properties with NonAttribute Source: https://context7.com/kysely-org/kysely-typeorm/llms.txt Use NonAttribute to exclude TypeORM relation properties, @RelationId arrays, and @VirtualColumn computations from Kysely's generated table types. This prevents non-column data from appearing in Kysely's SELECT/INSERT/UPDATE suggestions. ```typescript import { Column, Entity, JoinColumn, ManyToOne, OneToMany, PrimaryGeneratedColumn, RelationId, VirtualColumn, } from 'typeorm' import type { GeneratedAlways, NonAttribute } from 'kysely-typeorm' import { PersonEntity } from './Person' import { ToyEntity } from './Toy' @Entity({ name: 'pet' }) export class PetEntity { @PrimaryGeneratedColumn() id: GeneratedAlways @Column({ type: 'varchar', length: 255 }) name: string @ManyToOne(() => PersonEntity, (p) => p.pets, { onDelete: 'CASCADE' }) @JoinColumn({ name: 'owner_id', referencedColumnName: 'id' }) owner: NonAttribute // excluded from Kysely type @RelationId((pet: PetEntity) => pet.owner) ownerId: number // kept — actual FK column @OneToMany(() => ToyEntity, (t) => t.pet) toys: NonAttribute // excluded from Kysely type @VirtualColumn({ query: (alias) => `select count(*) from toy where pet_id = ${alias}.id` }) totalToys: NonAttribute // excluded from Kysely type } // KyselifyEntity => { id: GeneratedAlways, name: string, ownerId: number } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.