drizzle-team / drizzle-orm

Headless TypeScript ORM with a head. Runs on Node, Bun and Deno. Lives on the Edge and yes, it's a JavaScript ORM too 😅
https://orm.drizzle.team
Apache License 2.0
21.52k stars 487 forks source link

Don't enforce type restrictions on mysqlEnum and pgEnum to be non-empty arrays #2429

Open aprilmintacpineda opened 1 month ago

aprilmintacpineda commented 1 month ago

Summary of changes

Related discussion: https://github.com/drizzle-team/drizzle-orm/discussions/1914

Problem:

mysqlEnum and pgEnum both expect the 2nd argument to be of type [string, ...string[]] which means it ensures that we are not passing an empty array to it. However, this would only work smoothly for arrays but not for enums. To get around the limitation, we always have to use the as keyword like so:

mysqlEnum(
  'type',
  Object.values(eCategoryType) as [
    eCategoryType,
    ...eCategoryType[],
  ],
).notNull()

Reason being is because Object.values(eCategoryType) becomes a type of eCategoryType[] which doesn't fit what we are explicitly checking for [eCategoryType, ...eCategoryType[]].

I understand that this restriction was put in place to ensure that no one passes an empty array in there. In this case, I think we can add that kind of restriction in-code rather than in-type -- which looking at the mysqlEnum code, we are already doing by checking values.length === 0.

Note

I saw on some other files that enums are generally expected as [string, ...string[]], these other places are not covered in this PR, this only aims to fix the issue on mysqlEnum and pgEnum.

What will work

enums will work -- now without needing to use as keyword.

image

Regular arrays will still work

image

Empty arrays will now work -- previously there will be a TS error. However, in-code validation will prevent this from happening and throw an error.

image

Patch Package

You can use patch-package to apply the fix right now.

Step 1

yarn add -D patch-package

Step 2

2.1. cd /to/root/of/your/project 2.2. touch patches/drizzle-orm+0.31.0.patch

Step 3

Copy the contents below to the file you just created

patches/drizzle-orm+0.31.0.patch ```diff diff --git a/node_modules/drizzle-orm/mysql-core/columns/enum.d.ts b/node_modules/drizzle-orm/mysql-core/columns/enum.d.ts index 274c06a..9a6d67c 100644 --- a/node_modules/drizzle-orm/mysql-core/columns/enum.d.ts +++ b/node_modules/drizzle-orm/mysql-core/columns/enum.d.ts @@ -3,7 +3,7 @@ import type { ColumnBaseConfig } from "../../column.js"; import { entityKind } from "../../entity.js"; import type { Writable } from "../../utils.js"; import { MySqlColumn, MySqlColumnBuilder } from "./common.js"; -export type MySqlEnumColumnBuilderInitial = MySqlEnumColumnBuilder<{ +export type MySqlEnumColumnBuilderInitial = MySqlEnumColumnBuilder<{ name: TName; dataType: 'string'; columnType: 'MySqlEnumColumn'; @@ -24,4 +24,4 @@ export declare class MySqlEnumColumn>(name: TName, values: T | Writable): MySqlEnumColumnBuilderInitial>; +export declare function mysqlEnum>(name: TName, values: T | Writable): MySqlEnumColumnBuilderInitial>; diff --git a/node_modules/drizzle-orm/pg-core/columns/enum.d.ts b/node_modules/drizzle-orm/pg-core/columns/enum.d.ts index 357f708..c240362 100644 --- a/node_modules/drizzle-orm/pg-core/columns/enum.d.ts +++ b/node_modules/drizzle-orm/pg-core/columns/enum.d.ts @@ -1,10 +1,10 @@ import type { ColumnBuilderBaseConfig } from "../../column-builder.js"; import type { ColumnBaseConfig } from "../../column.js"; import { entityKind } from "../../entity.js"; -import type { AnyPgTable } from "../table.js"; import type { Writable } from "../../utils.js"; +import type { AnyPgTable } from "../table.js"; import { PgColumn, PgColumnBuilder } from "./common.js"; -export type PgEnumColumnBuilderInitial = PgEnumColumnBuilder<{ +export type PgEnumColumnBuilderInitial = PgEnumColumnBuilder<{ name: TName; dataType: 'string'; columnType: 'PgEnumColumn'; @@ -12,15 +12,15 @@ export type PgEnumColumnBuilderInitial; -export interface PgEnum { +export interface PgEnum { (name: TName): PgEnumColumnBuilderInitial; readonly enumName: string; readonly enumValues: TValues; readonly schema: string | undefined; } -export declare function isPgEnum(obj: unknown): obj is PgEnum<[string, ...string[]]>; +export declare function isPgEnum(obj: unknown): obj is PgEnum; export declare class PgEnumColumnBuilder & { - enumValues: [string, ...string[]]; + enumValues: string[]; }> extends PgColumnBuilder; }> { @@ -28,7 +28,7 @@ export declare class PgEnumColumnBuilder); } export declare class PgEnumColumn & { - enumValues: [string, ...string[]]; + enumValues: string[]; }> extends PgColumn; }> { @@ -40,4 +40,4 @@ export declare class PgEnumColumn, config: PgEnumColumnBuilder['config']); getSQLType(): string; } -export declare function pgEnum>(enumName: string, values: T | Writable): PgEnum>; +export declare function pgEnum>(enumName: string, values: T | Writable): PgEnum>; ```

Step 4

yarn patch-package

Step 5

Update your package.json file to the following:

"scripts": {
  // ... your other scripts
  "postinstall": "yarn patch-package"
},