1
0
mirror of https://github.com/theoludwig/kysely-typegen.git synced 2026-05-22 16:23:25 +02:00

docs: add CONTRIBUTING.md and complete README

This commit is contained in:
2026-05-20 22:05:53 +02:00
parent 88375dedf6
commit 303add091c
4 changed files with 236 additions and 8 deletions
+53
View File
@@ -0,0 +1,53 @@
# Contributing
Thanks a lot for your interest in contributing to **kysely-typegen**! 🎉
## Code of Conduct
**kysely-typegen** adopted the [Contributor Covenant](https://www.contributor-covenant.org/) as its Code of Conduct, and we expect project participants to adhere to it. Please read the full text so that you can understand what actions will and will not be tolerated.
## Open Development
All work on **kysely-typegen** happens directly on this repository. Both core team members and external contributors send pull requests which go through the same review process.
## Types of contributions
- Reporting a bug.
- Suggest a new feature idea.
- Correct spelling errors, improvements or additions to documentation files (README, CONTRIBUTING...).
- Improve structure/format/performance/refactor/tests of the code.
## Pull Requests
- **Please first discuss** the change you wish to make via [issue](https://github.com/theoludwig/kysely-typegen/issues) before making a change. It might avoid a waste of your time.
- Ensure your code respect linting.
- Make sure your **code passes the tests**.
If you're adding new features to **kysely-typegen**, please include tests.
## Commits
The commit message guidelines adheres to [Conventional Commits](https://www.conventionalcommits.org/) and [Semantic Versioning](https://semver.org/) for releases.
## Development Environment
```sh
# Clone the repository
git clone git@github.com:theoludwig/kysely-typegen.git
# Install dependencies
npm clean-install
# Lint
# node --run lint:typescript # already covered by oxlint
node --run lint:oxlint
node --run lint:oxfmt
# Tests
node --run test
# Build
node --run build
```
+177
View File
@@ -1 +1,178 @@
# kysely-typegen
[![version](https://npmx.dev/api/registry/badge/version/kysely-typegen)](https://npmx.dev/package/kysely-typegen) [![license](https://npmx.dev/api/registry/badge/license/kysely-typegen)](https://npmx.dev/package/kysely-typegen)
Generate [Kysely](https://npmx.dev/package/kysely) type definitions from your database.
Thank you [kysely-codegen](https://npmx.dev/package/kysely-codegen) for inspiration and ideas!
## Why?
Why `kysely-typegen` if there is already `kysely-codegen`? Comparison:
| | `kysely-codegen@0.20.0` | `kysely-typegen` |
| ----------------------------- | ---------------------------------------- | ------------------------------------------------------------ |
| **Install Size** | 6.8 MB | 5 kB |
| **Dependencies** | 35 total | 0 (no runtime dependencies) |
| **Type** | CLI | Library/Programmatic Usage |
| **Code Size/Maintainability** | Heavy | Less than 200 LOC/Simple and straightforward |
| **Database Support** | PostgreSQL, MySQL, SQLite, MSSQL, LibSQL | PostgreSQL (but can **easily be extended to more dialects**) |
`kysely-typegen` is a **library** (not a CLI), which means you are in control of where and how to run it, and is designed to be **extensible**, easy to add support for more database dialects.
For example: you can use [Node.js with the `--env-file` CLI option](https://nodejs.org/api/environment_variables.html), `dotenv` dependency is not required (but can be used), **you are in control**.
**Note:** `kysely-typegen` doesn't have the same features and customization as `kysely-codegen`, it has less features to keep it simple and lightweight, but can be extended to your own needs.
## Prerequisites
[Node.js](https://nodejs.org/) >= 24.0.0
## Installation
```sh
npm install --save-dev kysely-typegen
```
Peer dependencies:
```sh
npm install kysely
```
Kysely dialect of your choice, for example: [kysely-postgres-js](https://github.com/kysely-org/kysely-postgres-js)
```sh
npm install kysely-postgres-js postgres
```
## Usage
### Setup Kysely database
Create your Kysely database instance (example with [kysely-postgres-js](https://github.com/kysely-org/kysely-postgres-js)):
```ts
// database.ts
import { Kysely } from "kysely"
import { PostgresJSDialect } from "kysely-postgres-js"
import postgres from "postgres"
import type { DB } from "./codegen.ts"
export const DATABASE_USER = process.env["DATABASE_USER"] ?? "user"
export const DATABASE_PASSWORD = process.env["DATABASE_PASSWORD"] ?? "password"
export const DATABASE_NAME = process.env["DATABASE_NAME"] ?? "database"
export const DATABASE_HOST = process.env["DATABASE_HOST"] ?? "localhost"
export const DATABASE_PORT = Number.parseInt(process.env["DATABASE_PORT"] ?? "5432", 10)
const dialect = new PostgresJSDialect({
postgres: postgres({
database: DATABASE_NAME,
host: DATABASE_HOST,
user: DATABASE_USER,
password: DATABASE_PASSWORD,
port: DATABASE_PORT,
}),
})
export const database = new Kysely<DB>({
dialect,
})
```
### Generate the type definitions
Create a script that uses `kysely-typegen` to introspect your database and write the generated types to a file:
```ts
// codegen.ts
// This is an example, you can be more creative and include more logic, for example time it takes to generate, number of tables/enums generated, etc.
import fs from "node:fs"
import path from "node:path"
import { KyselyTypegenPostgresDialect } from "kysely-typegen"
import { database } from "./database.ts"
const databaseTypegen = new KyselyTypegenPostgresDialect({
database,
})
const result = await databaseTypegen.typegen()
const codegenContent = result.lines.join("\n")
const codegenPath = path.join(process.cwd(), "src/codegen.ts")
await fs.promises.writeFile(codegenPath, codegenContent, "utf-8")
await database.destroy()
```
Run with Node.js (using `--env-file` to load environment variables, no `dotenv` dependency required):
```sh
node --env-file=.env scripts/codegen.ts
```
### Using the type definitions
Import `DB` into `new Kysely<DB>`, and you're done!
```ts
import { database } from "./database.ts"
const rows = await database.selectFrom("users").selectAll().execute()
// ^ { createdAt: Date; email: string; id: number; ... }[]
```
Fully type-safe queries derived from your actual database schema.
## Extending to other database dialects
`kysely-typegen` ships with `KyselyTypegenPostgresDialect`, but you can add support for any database by extending the abstract `KyselyTypegenDialect` class.
Only two things are required:
- `scalars`: a `Record<string, string>` mapping the database column types to TypeScript types.
- `getEnumsMap()`: a method returning a `Map<string, string[]>` of enum names to their values (return an empty `Map` if your database doesn't support enums).
```ts
import { KyselyTypegenDialect } from "kysely-typegen"
import type { Kysely } from "kysely"
export class KyselyTypegenMySQLDialect extends KyselyTypegenDialect {
public database: KyselyTypegenDialect["database"]
public readonly scalars: Record<string, string> = {
bigint: "number",
char: "string",
datetime: "Timestamp",
int: "number",
json: "Json",
text: "string",
tinyint: "number",
varchar: "string",
// ...
}
public constructor(input: { database: Kysely<any> }) {
super()
this.database = input.database
}
protected async getEnumsMap(): Promise<Map<string, string[]>> {
// Query your database's information schema for enum types.
// Key: enum name, Value: array of enum values.
return new Map()
}
}
```
The base class handles introspection (via Kysely's `database.introspection.getTables()`), sorting, and the final type generation. Contributions of new dialects are welcome!
## Contributing
Anyone can help to improve the project, submit a Feature Request, a bug report or even correct a simple spelling mistake.
The steps to contribute can be found in the [CONTRIBUTING.md](/CONTRIBUTING.md) file.
## License
[MIT](./LICENSE)
+2 -2
View File
@@ -33,7 +33,7 @@ const createSchema = async (database: Kysely<any>): Promise<void> => {
return column
.notNull()
.primaryKey()
.defaultTo(sql`gen_random_uuid()`)
.defaultTo(sql`uuidv7()`)
})
.addColumn("colBool", "boolean", (column) => {
return column.notNull()
@@ -163,7 +163,7 @@ const createSchema = async (database: Kysely<any>): Promise<void> => {
return column
.notNull()
.primaryKey()
.defaultTo(sql`gen_random_uuid()`)
.defaultTo(sql`uuidv7()`)
})
.addColumn("username", "varchar(50)", (column) => {
return column.notNull().unique()
+4 -6
View File
@@ -60,6 +60,9 @@ export abstract class KyselyTypegenDialect {
const enumName = enumMetadata.name
result.push(
`export type ${enumName} = ${enumMetadata.values
.sort((a, b) => {
return a.localeCompare(b)
})
.map((value) => {
return `"${value}"`
})
@@ -170,12 +173,7 @@ export class KyselyTypegenPostgresDialect extends KyselyTypegenDialect {
const enums = new Map<string, string[]>()
for (const row of rows) {
const data = row as { enumName: string; enumValue: string }
enums.set(
data.enumName,
[...(enums.get(data.enumName) ?? []), data.enumValue].sort((a, b) => {
return a.localeCompare(b)
}),
)
enums.set(data.enumName, [...(enums.get(data.enumName) ?? []), data.enumValue])
}
return enums
}