Skip to content

Commit 490de7b

Browse files
authored
Merge pull request #453 from drizzle-team/384-allow-passing-readonly-arrays-to-enums
2 parents 6e1aa47 + 3bb5a97 commit 490de7b

File tree

27 files changed

+530
-260
lines changed

27 files changed

+530
-260
lines changed

changelogs/drizzle-orm/0.23.13.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- 🎉 All enum and text enum columns now have a properly typed `enumValues` property

changelogs/drizzle-zod/0.3.0.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- 🎉 Added MySQL support

drizzle-orm/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "drizzle-orm",
3-
"version": "0.23.12",
3+
"version": "0.23.13",
44
"description": "Drizzle ORM package for SQL databases",
55
"scripts": {
66
"build": "tsc && resolve-tspaths && cp ../README.md package.json dist/",

drizzle-orm/src/column.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,3 +100,7 @@ export type GetColumnData<TColumn extends AnyColumn, TInferMode extends 'query'
100100
export type InferColumnsDataTypes<TColumns extends Record<string, AnyColumn>> = {
101101
[Key in keyof TColumns]: GetColumnData<TColumns[Key], 'query'>;
102102
};
103+
104+
export interface WithEnum<T extends [string, ...string[]] = [string, ...string[]]> {
105+
enumValues: T;
106+
}

drizzle-orm/src/mysql-core/columns/binary.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export interface MySqlBinaryHKT extends ColumnHKTBase {
1616
export type MySqlBinaryBuilderInitial<TName extends string> = MySqlBinaryBuilder<{
1717
name: TName;
1818
data: string;
19-
driverParam: number | string;
19+
driverParam: string;
2020
notNull: false;
2121
hasDefault: false;
2222
}>;
@@ -39,9 +39,7 @@ export class MySqlBinaryBuilder<T extends ColumnBuilderBaseConfig> extends MySql
3939
}
4040
}
4141

42-
export class MySqlBinary<
43-
T extends ColumnBaseConfig,
44-
> extends MySqlColumn<
42+
export class MySqlBinary<T extends ColumnBaseConfig> extends MySqlColumn<
4543
MySqlBinaryHKT,
4644
T,
4745
MySqlBinaryConfig
Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,33 @@
1-
import type { ColumnBaseConfig, ColumnHKTBase } from '~/column';
1+
import type { ColumnBaseConfig, ColumnHKTBase, WithEnum } from '~/column';
22
import type { ColumnBuilderBaseConfig, ColumnBuilderHKTBase, MakeColumnConfig } from '~/column-builder';
33
import type { AnyMySqlTable } from '~/mysql-core/table';
44
import type { Assume, Writable } from '~/utils';
55
import { MySqlColumn, MySqlColumnBuilder } from './common';
66

77
export interface MySqlCharBuilderHKT extends ColumnBuilderHKTBase {
8-
_type: MySqlCharBuilder<Assume<this['config'], ColumnBuilderBaseConfig>>;
8+
_type: MySqlCharBuilder<Assume<this['config'], ColumnBuilderBaseConfig & WithEnum>>;
99
_columnHKT: MySqlCharHKT;
1010
}
1111

1212
export interface MySqlCharHKT extends ColumnHKTBase {
13-
_type: MySqlChar<Assume<this['config'], ColumnBaseConfig>>;
13+
_type: MySqlChar<Assume<this['config'], ColumnBaseConfig & WithEnum>>;
1414
}
1515

16-
export type MySqlCharBuilderInitial<TName extends string, TEnum extends string[]> = MySqlCharBuilder<{
16+
export type MySqlCharBuilderInitial<TName extends string, TEnum extends [string, ...string[]]> = MySqlCharBuilder<{
1717
name: TName;
1818
data: TEnum[number];
1919
driverParam: number | string;
20-
enum: TEnum;
20+
enumValues: TEnum;
2121
notNull: false;
2222
hasDefault: false;
2323
}>;
2424

25-
export class MySqlCharBuilder<T extends ColumnBuilderBaseConfig> extends MySqlColumnBuilder<
25+
export class MySqlCharBuilder<T extends ColumnBuilderBaseConfig & WithEnum> extends MySqlColumnBuilder<
2626
MySqlCharBuilderHKT,
2727
T,
28-
MySqlCharConfig
28+
MySqlCharConfig<T['enumValues']>
2929
> {
30-
constructor(name: T['name'], config: MySqlCharConfig) {
30+
constructor(name: T['name'], config: MySqlCharConfig<T['enumValues']>) {
3131
super(name);
3232
this.config.length = config.length;
3333
this.config.enum = config.enum;
@@ -36,28 +36,31 @@ export class MySqlCharBuilder<T extends ColumnBuilderBaseConfig> extends MySqlCo
3636
/** @internal */
3737
override build<TTableName extends string>(
3838
table: AnyMySqlTable<{ name: TTableName }>,
39-
): MySqlChar<MakeColumnConfig<T, TTableName>> {
40-
return new MySqlChar<MakeColumnConfig<T, TTableName>>(table, this.config);
39+
): MySqlChar<MakeColumnConfig<T, TTableName> & Pick<T, 'enumValues'>> {
40+
return new MySqlChar<MakeColumnConfig<T, TTableName> & Pick<T, 'enumValues'>>(table, this.config);
4141
}
4242
}
4343

44-
export class MySqlChar<T extends ColumnBaseConfig> extends MySqlColumn<MySqlCharHKT, T, MySqlCharConfig> {
44+
export class MySqlChar<T extends ColumnBaseConfig & WithEnum>
45+
extends MySqlColumn<MySqlCharHKT, T, MySqlCharConfig<T['enumValues']>>
46+
implements WithEnum<T['enumValues']>
47+
{
4548
readonly length: number | undefined = this.config.length;
46-
readonly enum: string[] = this.config.enum ?? [];
49+
readonly enumValues: T['enumValues'] = (this.config.enum ?? []) as T['enumValues'];
4750

4851
getSQLType(): string {
4952
return typeof this.length !== 'undefined' ? `char(${this.length})` : `char`;
5053
}
5154
}
5255

53-
export interface MySqlCharConfig<TEnum extends string[] = string[]> {
56+
export interface MySqlCharConfig<TEnum extends readonly string[] | string[]> {
5457
length?: number;
5558
enum?: TEnum;
5659
}
5760

5861
export function char<TName extends string, U extends string, T extends Readonly<[U, ...U[]]>>(
5962
name: TName,
60-
config: MySqlCharConfig<Writable<T>> = {},
63+
config: MySqlCharConfig<T | Writable<T>> = {},
6164
): MySqlCharBuilderInitial<TName, Writable<T>> {
6265
return new MySqlCharBuilder(name, config);
6366
}

drizzle-orm/src/mysql-core/columns/common.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export abstract class MySqlColumnBuilder<
2929
THKT extends ColumnBuilderHKTBase,
3030
T extends ColumnBuilderBaseConfig,
3131
TRuntimeConfig extends object = {},
32-
TTypeConfig extends Record<string, unknown> = {},
32+
TTypeConfig extends object = {},
3333
> extends ColumnBuilder<THKT, T, TRuntimeConfig, TTypeConfig & { mysqlBrand: 'MySqlColumnBuilder' }> {
3434
private foreignKeyConfigs: ReferenceConfig[] = [];
3535

drizzle-orm/src/mysql-core/columns/enum.ts

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,62 @@
1-
import type { ColumnBaseConfig, ColumnHKTBase } from '~/column';
1+
import type { ColumnBaseConfig, ColumnHKTBase, WithEnum } from '~/column';
22
import type { ColumnBuilderBaseConfig, ColumnBuilderHKTBase, MakeColumnConfig } from '~/column-builder';
33
import type { AnyMySqlTable } from '~/mysql-core/table';
44
import type { Assume, Writable } from '~/utils';
55
import { MySqlColumn, MySqlColumnBuilder } from './common';
66

77
export interface MySqlEnumColumnBuilderHKT extends ColumnBuilderHKTBase {
8-
_type: MySqlEnumColumnBuilder<Assume<this['config'], ColumnBuilderBaseConfig>>;
8+
_type: MySqlEnumColumnBuilder<Assume<this['config'], ColumnBuilderBaseConfig & WithEnum>>;
99
_columnHKT: MySqlEnumColumnHKT;
1010
}
1111

1212
export interface MySqlEnumColumnHKT extends ColumnHKTBase {
13-
_type: MySqlEnumColumn<Assume<this['config'], ColumnBaseConfig>>;
13+
_type: MySqlEnumColumn<Assume<this['config'], ColumnBaseConfig & WithEnum>>;
1414
}
1515

16-
export type MySqlEnumColumnBuilderInitial<TName extends string, TEnum extends string[]> = MySqlEnumColumnBuilder<{
17-
name: TName;
18-
data: TEnum[number];
19-
driverParam: string;
20-
enum: TEnum;
21-
notNull: false;
22-
hasDefault: false;
23-
}>;
24-
25-
export class MySqlEnumColumnBuilder<T extends ColumnBuilderBaseConfig>
26-
extends MySqlColumnBuilder<MySqlEnumColumnBuilderHKT, T, { values: string[] }>
16+
export type MySqlEnumColumnBuilderInitial<TName extends string, TEnum extends [string, ...string[]]> =
17+
MySqlEnumColumnBuilder<{
18+
name: TName;
19+
data: TEnum[number];
20+
driverParam: string;
21+
enumValues: TEnum;
22+
notNull: false;
23+
hasDefault: false;
24+
}>;
25+
26+
export class MySqlEnumColumnBuilder<T extends ColumnBuilderBaseConfig & WithEnum>
27+
extends MySqlColumnBuilder<MySqlEnumColumnBuilderHKT, T, Pick<T, 'enumValues'>>
2728
{
28-
constructor(name: T['name'], values: string[]) {
29+
constructor(name: T['name'], values: T['enumValues']) {
2930
super(name);
30-
this.config.values = values;
31+
this.config.enumValues = values;
3132
}
3233

3334
/** @internal */
3435
override build<TTableName extends string>(
3536
table: AnyMySqlTable<{ name: TTableName }>,
36-
): MySqlEnumColumn<MakeColumnConfig<T, TTableName>> {
37-
return new MySqlEnumColumn<MakeColumnConfig<T, TTableName>>(
37+
): MySqlEnumColumn<MakeColumnConfig<T, TTableName> & Pick<T, 'enumValues'>> {
38+
return new MySqlEnumColumn<MakeColumnConfig<T, TTableName> & Pick<T, 'enumValues'>>(
3839
table,
3940
this.config,
4041
);
4142
}
4243
}
4344

44-
export class MySqlEnumColumn<T extends ColumnBaseConfig>
45-
extends MySqlColumn<MySqlEnumColumnHKT, T, { values: readonly string[] }>
45+
export class MySqlEnumColumn<T extends ColumnBaseConfig & WithEnum>
46+
extends MySqlColumn<MySqlEnumColumnHKT, T, Pick<T, 'enumValues'>>
47+
implements WithEnum<T['enumValues']>
4648
{
47-
readonly values: readonly string[] = this.config.values;
49+
readonly enumValues: T['enumValues'] = this.config.enumValues;
4850

4951
getSQLType(): string {
50-
return `enum(${this.values.map((value) => `'${value}'`).join(',')})`;
52+
return `enum(${this.enumValues.map((value) => `'${value}'`).join(',')})`;
5153
}
5254
}
5355

5456
export function mysqlEnum<TName extends string, U extends string, T extends Readonly<[U, ...U[]]>>(
5557
name: TName,
5658
values: T | Writable<T>,
57-
): MySqlEnumColumnBuilderInitial<TName, Writable<T>>;
58-
export function mysqlEnum(name: string, values: string[]) {
59+
): MySqlEnumColumnBuilderInitial<TName, Writable<T>> {
5960
if (values.length === 0) throw Error(`You have an empty array for "${name}" enum values`);
6061

6162
return new MySqlEnumColumnBuilder(name, values);

drizzle-orm/src/mysql-core/columns/json.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ export class MySqlJsonBuilder<T extends ColumnBuilderBaseConfig> extends MySqlCo
3131
}
3232

3333
export class MySqlJson<T extends ColumnBaseConfig> extends MySqlColumn<MySqlJsonHKT, T> {
34+
declare protected $mysqlColumnBrand: 'MySqlJson';
35+
3436
getSQLType(): string {
3537
return 'json';
3638
}
Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { ColumnBaseConfig, ColumnHKTBase } from '~/column';
1+
import type { ColumnBaseConfig, ColumnHKTBase, WithEnum } from '~/column';
22
import type { ColumnBuilderBaseConfig, ColumnBuilderHKTBase, MakeColumnConfig } from '~/column-builder';
33
import type { AnyMySqlTable } from '~/mysql-core/table';
44
import type { Assume, Writable } from '~/utils';
@@ -7,81 +7,82 @@ import { MySqlColumn, MySqlColumnBuilder } from './common';
77
export type MySqlTextColumnType = 'tinytext' | 'text' | 'mediumtext' | 'longtext';
88

99
export interface MySqlTextBuilderHKT extends ColumnBuilderHKTBase {
10-
_type: MySqlTextBuilder<Assume<this['config'], ColumnBuilderBaseConfig>>;
10+
_type: MySqlTextBuilder<Assume<this['config'], ColumnBuilderBaseConfig & WithEnum>>;
1111
_columnHKT: MySqlTextHKT;
1212
}
1313

1414
export interface MySqlTextHKT extends ColumnHKTBase {
15-
_type: MySqlText<Assume<this['config'], ColumnBaseConfig>>;
15+
_type: MySqlText<Assume<this['config'], ColumnBaseConfig & WithEnum>>;
1616
}
1717

18-
export type MySqlTextBuilderInitial<TName extends string, TEnum extends string[]> = MySqlTextBuilder<{
18+
export type MySqlTextBuilderInitial<TName extends string, TEnum extends [string, ...string[]]> = MySqlTextBuilder<{
1919
name: TName;
2020
data: TEnum[number];
2121
driverParam: string;
22-
enum: TEnum;
22+
enumValues: TEnum;
2323
notNull: false;
2424
hasDefault: false;
2525
}>;
2626

27-
export class MySqlTextBuilder<T extends ColumnBuilderBaseConfig> extends MySqlColumnBuilder<
27+
export class MySqlTextBuilder<T extends ColumnBuilderBaseConfig & WithEnum> extends MySqlColumnBuilder<
2828
MySqlTextBuilderHKT,
2929
T,
30-
{ textType: MySqlTextColumnType; enum: string[] }
30+
{ textType: MySqlTextColumnType; enumValues: T['enumValues'] | undefined }
3131
> {
32-
constructor(name: T['name'], textType: MySqlTextColumnType, config: MySqlTextConfig<string[]>) {
32+
constructor(name: T['name'], textType: MySqlTextColumnType, config: MySqlTextConfig<T['enumValues']>) {
3333
super(name);
3434
this.config.textType = textType;
35-
this.config.enum = config.enum ?? [];
35+
this.config.enumValues = config.enum;
3636
}
3737

3838
/** @internal */
3939
override build<TTableName extends string>(
4040
table: AnyMySqlTable<{ name: TTableName }>,
41-
): MySqlText<MakeColumnConfig<T, TTableName>> {
42-
return new MySqlText<MakeColumnConfig<T, TTableName>>(table, this.config);
41+
): MySqlText<MakeColumnConfig<T, TTableName> & Pick<T, 'enumValues'>> {
42+
return new MySqlText<MakeColumnConfig<T, TTableName> & Pick<T, 'enumValues'>>(table, this.config);
4343
}
4444
}
4545

46-
export class MySqlText<T extends ColumnBaseConfig>
47-
extends MySqlColumn<MySqlTextHKT, T, { textType: MySqlTextColumnType; enum: string[] }>
46+
export class MySqlText<T extends ColumnBaseConfig & WithEnum>
47+
extends MySqlColumn<MySqlTextHKT, T, { textType: MySqlTextColumnType; enumValues: T['enumValues'] | undefined }>
48+
implements WithEnum<T['enumValues']>
4849
{
4950
private textType: MySqlTextColumnType = this.config.textType;
50-
readonly enum: string[] = this.config.enum;
51+
readonly enumValues: T['enumValues'] = (this.config.enumValues ?? []) as T['enumValues'];
5152

5253
getSQLType(): string {
5354
return this.textType;
5455
}
5556
}
5657

57-
export interface MySqlTextConfig<TEnum extends string[]> {
58+
export interface MySqlTextConfig<TEnum extends readonly string[] | string[]> {
5859
enum?: TEnum;
5960
}
6061

6162
export function text<TName extends string, U extends string, T extends Readonly<[U, ...U[]]>>(
6263
name: TName,
63-
config: MySqlTextConfig<Writable<T>> = {},
64+
config: MySqlTextConfig<T | Writable<T>> = {},
6465
): MySqlTextBuilderInitial<TName, Writable<T>> {
6566
return new MySqlTextBuilder(name, 'text', config);
6667
}
6768

6869
export function tinytext<TName extends string, U extends string, T extends Readonly<[U, ...U[]]>>(
6970
name: TName,
70-
config: MySqlTextConfig<Writable<T>> = {},
71+
config: MySqlTextConfig<T | Writable<T>> = {},
7172
): MySqlTextBuilderInitial<TName, Writable<T>> {
7273
return new MySqlTextBuilder(name, 'tinytext', config);
7374
}
7475

7576
export function mediumtext<TName extends string, U extends string, T extends Readonly<[U, ...U[]]>>(
7677
name: TName,
77-
config: MySqlTextConfig<Writable<T>> = {},
78+
config: MySqlTextConfig<T | Writable<T>> = {},
7879
): MySqlTextBuilderInitial<TName, Writable<T>> {
7980
return new MySqlTextBuilder(name, 'mediumtext', config);
8081
}
8182

8283
export function longtext<TName extends string, U extends string, T extends Readonly<[U, ...U[]]>>(
8384
name: TName,
84-
config: MySqlTextConfig<Writable<T>> = {},
85+
config: MySqlTextConfig<T | Writable<T>> = {},
8586
): MySqlTextBuilderInitial<TName, Writable<T>> {
8687
return new MySqlTextBuilder(name, 'longtext', config);
8788
}

drizzle-orm/src/mysql-core/columns/varbinary.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ export interface MySqlVarBinaryHKT extends ColumnHKTBase {
1515

1616
export type MySqlVarBinaryBuilderInitial<TName extends string> = MySqlVarBinaryBuilder<{
1717
name: TName;
18-
data: number;
19-
driverParam: number | string;
18+
data: string;
19+
driverParam: string;
2020
notNull: false;
2121
hasDefault: false;
2222
}>;

0 commit comments

Comments
 (0)