Releases: RobinBlomberg/kysely-codegen
Release list
0.20.0
Many great contributions, bug fixes and new features.
Resolves #284, #287, #307, #308, #72, #301, #275, #283.
defineConfig() and postprocess()
kysely-codegen@0.20.0 adds a defineConfig function that makes it easy to configure kysely-codegen in a type-safe way. It also adds a new Config#postprocess function that makes it possible to process the introspected metadata before generating code. This function allows you to reuse the active kysely-codegen connection to further introspect the database and modify the metadata as needed.
Example of generating enum types from PostGraphile enum tables:
import { sql } from "kysely";
import { defineConfig } from "kysely-codegen";
import pluralize from "pluralize";
export default defineConfig({
camelCase: false,
dateParser: "timestamp",
dialect: "postgres",
excludePattern: "(graphile_migrate.*|graphile_worker._private_*)",
outFile: "./types/database-types.ts",
postprocess: async ({ db, metadata }) => {
const rows = await db
.selectFrom("pg_catalog.pg_constraint as foreign_key_constraint")
.innerJoin(
"pg_catalog.pg_class as from_table",
"from_table.oid",
"foreign_key_constraint.conrelid",
)
.innerJoin(
"pg_catalog.pg_namespace as from_table_namespace",
"from_table_namespace.oid",
"from_table.relnamespace",
)
.innerJoin("pg_catalog.pg_attribute as from_column", (join) =>
join
.onRef("from_column.attrelid", "=", "from_table.oid")
.on(sql`from_column.attnum = any(foreign_key_constraint.conkey)`),
)
.innerJoin(
"pg_catalog.pg_class as to_table",
"to_table.oid",
"foreign_key_constraint.confrelid",
)
.innerJoin(
"pg_catalog.pg_namespace as to_table_namespace",
"to_table_namespace.oid",
"to_table.relnamespace",
)
.innerJoin("pg_catalog.pg_attribute as to_column", (join) =>
join
.onRef("to_column.attrelid", "=", "to_table.oid")
.on(sql`to_column.attnum = any(foreign_key_constraint.confkey)`),
)
.select([
"from_table_namespace.nspname as fromSchema",
"from_table.relname as fromTable",
"from_column.attname as fromColumn",
"to_table_namespace.nspname as enumSchema",
"to_table.relname as enumTable",
"to_column.attname as enumColumn",
])
.where("foreign_key_constraint.contype", "=", "f")
.where(sql<any>`obj_description(to_table.oid, 'pg_class') like '%@enum%'`)
.execute();
await Promise.all(
rows.map(
async ({
fromColumn,
fromSchema,
fromTable,
enumColumn,
enumSchema,
enumTable,
}) => {
const fromTableMetadata = metadata.tables.find(
(table) => table.schema === fromSchema && table.name === fromTable,
);
const fromColumnMetadata = fromTableMetadata?.columns.find(
(column) => column.name === fromColumn,
);
const enumTableMetadata = metadata.tables.find(
(table) => table.schema === enumSchema && table.name === enumTable,
);
const enumColumnMetadata = enumTableMetadata?.columns.find(
(column) => column.name === enumColumn,
);
if (fromColumnMetadata || enumColumnMetadata) {
const dataType = `${pluralize.singular(enumTable)}.${enumColumn}`;
const enumValues = await db
.selectFrom(`${enumSchema}.${enumTable}`)
.select(enumColumn)
.execute()
.then((rows) =>
rows.map((row) => (row as Record<string, string>)[enumColumn]),
);
metadata.enums.set(`${enumSchema}.${dataType}`, enumValues);
if (fromColumnMetadata) {
fromColumnMetadata.dataTypeSchema = enumSchema;
fromColumnMetadata.dataType = dataType;
}
if (enumColumnMetadata) {
enumColumnMetadata.dataTypeSchema = enumSchema;
enumColumnMetadata.dataType = dataType;
}
}
},
),
);
return metadata;
},
singularize: true,
url: process.env.DATABASE_URL,
});Example output:
+type EventTypeName = "TICKET_CREATED" | "TICKET_DELETED" | "TICKET_UPDATED";
+
type Event = {
createdAt: Generated<Timestamp>;
data: JsonValue;
- type: string;
+ type: EventTypeName;
};
type EventType = {
description: string;
- name: string;
+ name: EventTypeName;
};What's Changed
- feat: update
@tediousjs/connection-stringto 1.0.0 by @bakasmarius in #312 - replace
git-diffwithdiffby @paolostyle in #306 - feat(generator): Add support for generate symbol with CJK character by @lightrabbit in #313
- allow 'sqlite://' prefix in database url by @R4stafa in #302
- fix: resolve flaky CLI tests and add GitHub Actions CI by @elitan in #297
- feat: add PostgreSQL materialized view support by @elitan in #298
- feat: add uuid as string in mariadb by @AwaludinAR in #308
- Add support for 'timetz' type in PostgresAdapter by @bombillazo in #291
- Support subpath imports for named imports by @alex-kinokon in #290
- fix(GH-287): Fix for generic type imports by @kevinmichaelchen in #288
- support nullable override types by @itamar82 in #286
- feat: Add defineConfig() function for type-safe TypeScript configs
- feat: Add Config#postprocess() function
- feat: Silence dotenv tips
New Contributors
- @paolostyle made their first contribution in #306
- @lightrabbit made their first contribution in #313
- @R4stafa made their first contribution in #302
- @AwaludinAR made their first contribution in #308
- @alex-kinokon made their first contribution in #290
- @itamar82 made their first contribution in #286
Full Changelog: 0.19.0...0.20.0
0.19.0
New features
Thanks to amazing contributions from @kevinmichaelchen in #274, you can now override types on a global level:
.kysely-codegenrc.json
{
"customImports": {
"InstantRange": "./custom-types",
"CustomDuration": "@my-org/custom-types#Duration",
"Temporal": "@js-temporal/polyfill",
},
"typeMapping": {
"timestamptz": "Temporal.Instant",
"tstzrange": "InstantRange",
"date": "Temporal.PlainDate",
"interval": "CustomDuration"
}
}Example of generated output:
import type { InstantRange } from './custom-types';
import type { Duration as CustomDuration } from '@my-org/custom-types';
import type { Temporal } from '@js-temporal/polyfill';
export interface EventModel {
createdAt: Temporal.Instant;
dateRange: ColumnType<InstantRange, InstantRange, never>;
eventDate: Temporal.PlainDate;
interval: CustomDuration;
}
export interface DB {
events: EventModel;
}What's Changed
- fix(GH-240): crash caused by undeclared dependency by @FaberVitale in #241
- chore(deps): allow kysely 0.28.0 and tedious 19 by @belgattitude in #256
- feat: export config types by @Omar-Awawdeh in #252
- chore(pnpm): pnpm v10.9.0, set onlyBuiltDependencies by @belgattitude in #254
- README: Pin @tediousjs/connection-string to 0.5.0 by @yuriy-sng in #279
- Fix peer dep range by @joefatora in #268
- Add missing cli arg "config-file" to documentation by @SimonSimCity in #263
- Fix inconsistencies between VS Code settings and Prettier configuration by @anonpay-sh in #265
- feat: Support imports for custom types by @kevinmichaelchen in #274
New Contributors
- @FaberVitale made their first contribution in #241
- @belgattitude made their first contribution in #256
- @Omar-Awawdeh made their first contribution in #252
- @yuriy-sng made their first contribution in #279
- @joefatora made their first contribution in #268
- @SimonSimCity made their first contribution in #263
- @anonpay-sh made their first contribution in #265
- @kevinmichaelchen made their first contribution in #274
Full Changelog: 0.18.0...0.19.0
0.18.0
Migration to 0.18.0
The follow CLI options have been changed:
--schemahas been renamed to--default-schema.--singularhas been renamed to--singularize.--runtime-enumsand--runtime-enums-stylehave been merged into a single CLI option--runtime-enums.
Configuration file
All codegen options can also be configured in a .kysely-codegenrc.json (or .js, .ts, .yaml etc.) file or the kysely-codegen property in package.json. See Cosmiconfig for all available configuration file formats.
The default configuration:
{
"camelCase": false,
"dateParser": "timestamp",
"defaultSchemas": [], // ["public"] for PostgreSQL.
"dialect": null,
"domains": true,
"envFile": null,
"excludePattern": null,
"includePattern": null,
"logLevel": "warn",
"numericParser": "string",
"outFile": "./node_modules/kysely-codegen/dist/db.d.ts",
"overrides": {},
"partitions": false,
"print": false,
"runtimeEnums": false,
"singularize": false,
"typeOnlyImports": true,
"url": "env(DATABASE_URL)",
"verify": false
}The configuration object adds support for more advanced options:
{
"camelCase": true,
"overrides": {
"columns": {
"users.settings": "{ theme: 'dark' }"
}
},
"singularize": {
"/^(.*?)s?$/": "$1_model",
"/(bacch)(?:us|i)$/i": "$1us"
}
}The generated output:
export interface UserModel {
settings: { theme: 'dark' };
}
// ...
export interface DB {
bacchi: Bacchus;
users: UserModel;
}Custom serializers and dialects
The new configuration support also adds support for supplying custom serializers.
Here is a stub example of a basic Zod serializer (.kysely-codegenrc.ts):
import { toKyselyCamelCase } from '../../generator';
import type { Config } from '../config';
const config: Config = {
logLevel: 'debug',
outFile: null,
serializer: {
serializeFile: (metadata) => {
let output = 'import { z } from "zod";\n\n';
for (const table of metadata.tables) {
output += 'export const ';
output += toKyselyCamelCase(table.name);
output += 'Schema = z.object({\n';
for (const column of table.columns) {
output += ' ';
output += column.name;
output += ': ';
switch (column.dataType) {
case 'int4':
output += 'z.number().int()';
break;
default:
output += 'z.unknown()';
}
output += ',\n';
}
output += '});\n\n';
}
return output;
},
},
url: 'postgres://user:password@localhost:5433/database',
};
export default config;Example output:
import { z } from "zod";
export const usersSchema = z.object({
baz_qux: z.number().int(),
});Similarly, it's also possible to supply a custom dialect value, allowing you to create a completely new kysely-codegen dialects or extending an existing one with extra logic.
What's Changed
- feat!: Merge "runtime-enums" and "runtime-enums-style" options
- feat!: Deprecate "schemas" option and rename it to "defaultSchemas"
- feat!: Rename "singular" option to "singularize"
- feat: Support kysely-codegen configuration files (using cosmiconfig)
- feat: Add support for custom singularization rules
- feat: Merge all
...IdentifierNodeclasses into a singleIdentifierNodeclass - feat: Add
skipAutogenerationFileCommentserializer option - fix: Fix
overridesnot always applying to the correct column - fix: Fix test flakiness by running all tests in sequence
- fix: Make bun sqlite codegen work again (re-introduce KyselyBunSqliteIntrospectorDialect using the sqlite database from bun:sqlite and the Kysely dialect from 'kysely-bun-sqlite') by @meck93 in #238
- fix: Fix update function example @ README. by @igalklebanov in #227
- chore: Upgrade all dependencies
- chore: Allow @libsql/kysely-libsql@^0.4.1 as a peer dependency @alsiola in #233
New Contributors
Full Changelog: 0.17.0...0.18.0
0.17.0
What's Changed
- fix: fix incorrect timestamp types (fixes #203, #209)
- feat: support named instances for Microsoft Sql Server by @gittgott in #204
- feat: add --date-parser flag to control Postgres DATE type by @brianmcd in #210 (fixes #177, #194)
- docs: list current cli args by @shane-js in #167
- docs: update README.md run instructions by @shane-js in #166
- docs: improve documentation (fixes #178)
- feat(cli): adjust flag descriptions (fixes #193)
- feat: improve error when
.envfile is missing
New Contributors
Full Changelog: 0.16.7...0.17.0
0.16.7
What's Changed
- Allow PG Timestamp to accept string as selectType. by @hevar in #199 (fixes #194, #123, #177)
- Correctly pass the partition option to the Postgres inspector by @fxmouthuy in #197 (fixes #196)
- Fix postgres default schema behavior by @RobinClowers in #200
- Deduplicate repeated
ColumnTypearguments
New Contributors
- @fxmouthuy made their first contribution in #197
- @hevar made their first contribution in #199
Full Changelog: 0.16.4...0.16.7
0.16.4
What's Changed
- feat: accept multiple --schema flags @RobinClowers in #192
- fix: export all internal modules
- fix(generator): fix syntax error in old PostgreSQL versions
- fix(cli): rename misnamed CLI option
- refactor: install knip and remove all unused files/variables
Full Changelog: 0.16.0...0.16.4
0.16.0
Good morning! This is a big one.
What's Changed
- Properly utilize SSL parameter for MSSQL dialect connection by @mjbergman92 in #158
- Make it possible to insert strings into
Intervalcolumns by @qchar in #159 - Add
--singularCLI option by @acro5piano in #162 (fixes #32) - Add new Bun SQLite Dialect by @tlonny in #174 (fixes #153)
- Bump Tedious to v18 by @bakasmarius in #172
- Column overrides by @gittgott in #148 (fixes #30)
- Change type definition for
JsonObjectto make ESLint happy (fixes #181) - Add
--numeric-parseroption for specifying PostgreSQLNumericreturn type (fixes #161 and #109) - Make table names starting with numbers generate valid JavaScript identifiers (fixes #151)
- Make runtime enums generate correct enum keys and add
--runtime-enums-styleCLI option (fixes #150) - Add top-of-file marker comment when generating code (fixes #114)
- Exclude table partitions (fixes #76)
- Support overriding JSON column types (fixes #75)
Refactors and chores
- Bump all dependencies
- Refactor code to make CLI, generator and introspector into separate modules
- Use Vitest test runner
New Contributors
- @bakasmarius made their first contribution in #172
- @mjbergman92 made their first contribution in #158
- @qchar made their first contribution in #159
- @acro5piano made their first contribution in #162
- @tlonny made their first contribution in #174
Full Changelog: 0.15.0...0.16.0
0.15.0
What's Changed
- fix: domain flag is respected by @RobinClowers in #141
- fix flags in readme by @jrhizor in #142
- Fixing bit IdentifierNode to be boolean instead of Buffer by @gittgott in #145
New Contributors
Full Changelog: 0.14.0...0.15.0
0.14.0
What's Changed
- Add a skip-domains flag for postgres by @RobinClowers in #136
- Update compatible tedious versions by @timclark97 in #137
- Set kysely-bun-worker as an optional peer dep by @arempe93 in #138
- typescript comments based on columns comments by @elitan in #139
- feat: runtime enum support by @lsnow99 in #131
New Contributors
- @RobinClowers made their first contribution in #136
- @arempe93 made their first contribution in #138
- @elitan made their first contribution in #139
- @lsnow99 made their first contribution in #131
Full Changelog: 0.13.0...0.14.0
0.13.0
What's Changed
- fix: add 'bun-sqlite' in VALID_DIALECTS by @mtt-artis in #129
- Add MSSQL Support by @timclark97 in #128
- Add include/exclude pattern instructions to README.md by @divmgl in #133
- Expand environment variables from .env by @iffa in #130
New Contributors
- @mtt-artis made their first contribution in #129
- @timclark97 made their first contribution in #128
- @divmgl made their first contribution in #133
- @iffa made their first contribution in #130
Full Changelog: 0.12.0...0.13.0