Skip to content

Commit fa27960

Browse files
authored
Merge pull request #314 from drizzle-team/big-types-refactoring
2 parents 9a4dd68 + 6f26c51 commit fa27960

File tree

205 files changed

+5658
-7895
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

205 files changed

+5658
-7895
lines changed

.eslintrc.cjs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ module.exports = {
22
root: true,
33
extends: ['plugin:@typescript-eslint/base'],
44
parser: '@typescript-eslint/parser',
5-
plugins: ['import'],
5+
plugins: ['import', 'unused-imports'],
66
rules: {
77
'@typescript-eslint/consistent-type-imports': [
88
'error',
@@ -12,5 +12,10 @@ module.exports = {
1212
],
1313
'import/no-cycle': 'error',
1414
'import/no-self-import': 'error',
15+
'import/no-empty-named-blocks': 'error',
16+
'unused-imports/no-unused-imports': 'error',
17+
'import/no-useless-path-segments': 'error',
18+
'import/newline-after-import': 'error',
19+
'import/no-duplicates': 'error',
1520
},
1621
};

.npmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
recursive-install = true
2+
prefer-workspace-packages = true

changelogs/drizzle-orm/0.23.0.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
- 🎉 Added Knex and Kysely adapters! They allow you to manage the schemas and migrations with Drizzle and query the data with your favorite query builder. See documentation for more details:
2+
- [Knex adapter](https://github.com/drizzle-team/drizzle-knex)
3+
- [Kysely adapter](https://github.com/drizzle-team/drizzle-kysely)
4+
5+
- 🎉 Added "type maps" to all entities. You can access them via the special `_` property. For example:
6+
7+
```ts
8+
const users = mysqlTable('users', {
9+
id: int('id').primaryKey(),
10+
name: text('name').notNull(),
11+
});
12+
13+
type UserFields = typeof users['_']['columns'];
14+
type InsertUser = typeof users['_']['model']['insert'];
15+
```
16+
17+
Full documentation on the type maps is coming soon.
18+
19+
- 🎉 Added `.$type()` method to all column builders to allow overriding the data type. It also replaces the optional generics on columns.
20+
21+
```ts
22+
// Before
23+
const test = mysqlTable('test', {
24+
jsonField: json<Data>('json_field'),
25+
});
26+
27+
// After
28+
const test = mysqlTable('test', {
29+
jsonField: json('json_field').$type<Data>(),
30+
});
31+
```
32+
33+
- ❗ Changed syntax for text-based enum columns:
34+
35+
```ts
36+
// Before
37+
const test = mysqlTable('test', {
38+
role: text<'admin' | 'user'>('role'),
39+
});
40+
41+
// After
42+
const test = mysqlTable('test', {
43+
role: text('role', { enum: ['admin', 'user'] }),
44+
});
45+
```
46+
47+
- 🎉 Allowed passing an array of values into `.insert().values()` directly without spreading:
48+
49+
```ts
50+
const users = mysqlTable('users', {
51+
id: int('id').primaryKey(),
52+
name: text('name').notNull(),
53+
});
54+
55+
await users.insert().values([
56+
{ name: 'John' },
57+
{ name: 'Jane' },
58+
]);
59+
```
60+
61+
The spread syntax is now deprecated and will be removed in one of the next releases.
62+
63+
- 🎉 Added "table creators" to allow for table name customization:
64+
65+
```ts
66+
import { mysqlTableCreator } from 'drizzle-orm/mysql-core';
67+
68+
const mysqlTable = mysqlTableCreator((name) => `myprefix_${name}`);
69+
70+
const users = mysqlTable('users', {
71+
id: int('id').primaryKey(),
72+
name: text('name').notNull(),
73+
});
74+
75+
// Users table is a normal table, but its name is `myprefix_users` in runtime
76+
```
77+
78+
- 🎉 Implemented support for selecting/joining raw SQL expressions:
79+
80+
```ts
81+
// select current_date + s.a as dates from generate_series(0,14,7) as s(a);
82+
const result = await db
83+
.select({
84+
dates: sql`current_date + s.a`,
85+
})
86+
.from(sql`generate_series(0,14,7) as s(a)`);
87+
```
88+
89+
- 🐛 Fixed a lot of bugs from user feedback on GitHub and Discord (thank you! ❤). Fixes #293 #301 #276 #269 #253 #311 #312

docs/custom-types.lite.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,13 @@ export type CustomTypeValues = {
204204
/**
205205
* What config type should be used for {@link CustomTypeParams} `dataType` generation
206206
*/
207-
config?: Record<string, unknown>;
207+
config?: unknown;
208+
209+
/**
210+
* Whether the config argument should be required or not
211+
* @default false
212+
*/
213+
configRequired?: boolean;
208214

209215
/**
210216
* If your custom data type should be notNull by default you can use `notNull: true`
@@ -231,7 +237,7 @@ export type CustomTypeValues = {
231237
default?: boolean;
232238
};
233239

234-
export interface CustomTypeParams<T extends CustomTypeValues> {
240+
export interface CustomTypeParams<T extends Partial<CustomTypeValues>> {
235241
/**
236242
* Database data type string representation, that is used for migrations
237243
* @example
@@ -261,7 +267,7 @@ export interface CustomTypeParams<T extends CustomTypeValues> {
261267
* }
262268
* ```
263269
*/
264-
dataType: (config: T['config']) => string;
270+
dataType: (config: T['config'] | (Equal<T['configRequired'], true> extends true ? never : undefined)) => string;
265271

266272
/**
267273
* Optional mapping function, between user input and driver
@@ -273,7 +279,7 @@ export interface CustomTypeParams<T extends CustomTypeValues> {
273279
* }
274280
* ```
275281
*/
276-
toDriver?: (value: T['data']) => T['driverData'];
282+
toDriver?: (value: T['data']) => T['driverData'] | SQL;
277283

278284
/**
279285
* Optional mapping function, that is responsible for data mapping from database to JS/TS code

docs/custom-types.md

Lines changed: 69 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,17 @@ Each type creation should use 2 classes:
3030

3131
```typescript
3232
export class PgTextBuilder<TData extends string = string>
33-
extends PgColumnBuilder<
34-
ColumnBuilderConfig<{ data: TData; driverParam: string }>
35-
>
33+
extends PgColumnBuilder<
34+
ColumnBuilderConfig<{ data: TData; driverParam: string }>
35+
>
3636
{
37-
protected override $pgColumnBuilderBrand!: 'PgTextBuilder';
37+
3838

39-
build<TTableName extends string>(
40-
table: AnyPgTable<{ name: TTableName }>,
41-
): PgText<TTableName, TData> {
42-
return new PgText(table, this.config);
43-
}
39+
build<TTableName extends string>(
40+
table: AnyPgTable<{ name: TTableName }>,
41+
): PgText<TTableName, TData> {
42+
return new PgText(table, this.config);
43+
}
4444
}
4545
```
4646

@@ -62,7 +62,7 @@ Column class has set of types/functions, that could be overridden to get needed
6262

6363
```typescript
6464
override mapToDriverValue(value: TData): string {
65-
return JSON.stringify(value);
65+
return JSON.stringify(value);
6666
}
6767
```
6868

@@ -72,35 +72,35 @@ override mapToDriverValue(value: TData): string {
7272

7373
```typescript
7474
override mapFromDriverValue(value: number | string): number {
75-
if (typeof value === 'string') {
76-
return parseInt(value);
77-
}
78-
return value;
75+
if (typeof value === 'string') {
76+
return parseInt(value);
77+
}
78+
return value;
7979
}
8080
```
8181

8282
#### Column class example
8383

8484
```typescript
8585
export class PgText<TTableName extends string, TData extends string>
86-
extends PgColumn<ColumnConfig<{ tableName: TTableName; data: TData; driverParam: string }>> {
87-
protected override $pgColumnBrand!: 'PgText';
86+
extends PgColumn<ColumnConfig<{ tableName: TTableName; data: TData; driverParam: string }>> {
87+
8888

89-
constructor(table: AnyPgTable<{ name: TTableName }>, builder: PgTextBuilder<TData>['config']) {
90-
super(table, builder);
91-
}
89+
constructor(table: AnyPgTable<{ name: TTableName }>, builder: PgTextBuilder<TData>['config']) {
90+
super(table, builder);
91+
}
9292

93-
getSQLType(): string {
94-
return 'text';
95-
}
93+
getSQLType(): string {
94+
return 'text';
95+
}
9696

97-
override mapFromDriverValue(value: string): TData {
98-
return value as TData
99-
}
97+
override mapFromDriverValue(value: string): TData {
98+
return value as TData
99+
}
100100

101-
override mapToDriverValue(value: TData): string {
102-
return value
103-
}
101+
override mapToDriverValue(value: TData): string {
102+
return value
103+
}
104104
}
105105
```
106106

@@ -122,42 +122,42 @@ import { AnyPgTable } from '~/table';
122122
import { PgColumn, PgColumnBuilder } from './common';
123123

124124
export class PgTextBuilder<TData extends string = string>
125-
extends PgColumnBuilder<
126-
ColumnBuilderConfig<{ data: TData; driverParam: string }>
127-
>
125+
extends PgColumnBuilder<
126+
ColumnBuilderConfig<{ data: TData; driverParam: string }>
127+
>
128128
{
129-
protected override $pgColumnBuilderBrand!: 'PgTextBuilder';
129+
130130

131-
build<TTableName extends string>(
132-
table: AnyPgTable<{ name: TTableName }>,
133-
): PgText<TTableName, TData> {
134-
return new PgText(table, this.config);
135-
}
131+
build<TTableName extends string>(
132+
table: AnyPgTable<{ name: TTableName }>,
133+
): PgText<TTableName, TData> {
134+
return new PgText(table, this.config);
135+
}
136136
}
137137

138138
export class PgText<TTableName extends string, TData extends string>
139-
extends PgColumn<
140-
ColumnConfig<{ tableName: TTableName; data: TData; driverParam: string }>
141-
>
139+
extends PgColumn<
140+
ColumnConfig<{ tableName: TTableName; data: TData; driverParam: string }>
141+
>
142142
{
143-
protected override $pgColumnBrand!: 'PgText';
144-
145-
constructor(
146-
table: AnyPgTable<{ name: TTableName }>,
147-
builder: PgTextBuilder<TData>['config'],
148-
) {
149-
super(table, builder);
150-
}
151-
152-
getSQLType(): string {
153-
return 'text';
154-
}
143+
144+
145+
constructor(
146+
table: AnyPgTable<{ name: TTableName }>,
147+
builder: PgTextBuilder<TData>['config'],
148+
) {
149+
super(table, builder);
150+
}
151+
152+
getSQLType(): string {
153+
return 'text';
154+
}
155155
}
156156

157157
export function text<T extends string = string>(
158-
name: string,
158+
name: string,
159159
): PgTextBuilder<T> {
160-
return new PgTextBuilder(name);
160+
return new PgTextBuilder(name);
161161
}
162162
```
163163

@@ -181,40 +181,40 @@ export function text<T extends string = string>(
181181

182182
```typescript
183183
export class PgCITextBuilder<TData extends string = string> extends PgColumnBuilder<
184-
ColumnBuilderConfig<{ data: TData; driverParam: string }>
184+
ColumnBuilderConfig<{ data: TData; driverParam: string }>
185185
> {
186186
protected $pgColumnBuilderBrand: string = 'PgCITextBuilder';
187187

188-
build<TTableName extends string>(table: AnyPgTable<{ name: TTableName }>): PgCIText<TTableName, TData> {
189-
return new PgCIText(table, this.config);
190-
}
188+
build<TTableName extends string>(table: AnyPgTable<{ name: TTableName }>): PgCIText<TTableName, TData> {
189+
return new PgCIText(table, this.config);
190+
}
191191
}
192192

193193
export class PgCIText<TTableName extends string, TData extends string>
194-
extends PgColumn<ColumnConfig<{ tableName: TTableName; data: TData; driverParam: string }>>
194+
extends PgColumn<ColumnConfig<{ tableName: TTableName; data: TData; driverParam: string }>>
195195
{
196-
protected override $pgColumnBrand!: 'PgCIText';
196+
197197

198-
constructor(table: AnyPgTable<{ name: TTableName }>, builder: PgCITextBuilder<TData>['config']) {
199-
super(table, builder);
200-
}
198+
constructor(table: AnyPgTable<{ name: TTableName }>, builder: PgCITextBuilder<TData>['config']) {
199+
super(table, builder);
200+
}
201201

202-
getSQLType(): string {
203-
return 'citext';
204-
}
202+
getSQLType(): string {
203+
return 'citext';
204+
}
205205
}
206206

207207
export function citext<T extends string = string>(name: string): PgCITextBuilder<T> {
208-
return new PgCITextBuilder(name);
208+
return new PgCITextBuilder(name);
209209
}
210210
```
211211

212212
#### Usage example
213213

214214
```typescript
215215
const table = pgTable('table', {
216-
id: integer('id').primaryKey(),
217-
ciname: citext('ciname')
216+
id: integer('id').primaryKey(),
217+
ciname: citext('ciname')
218218
})
219219
```
220220

0 commit comments

Comments
 (0)