Skip to content
This repository was archived by the owner on Mar 1, 2026. It is now read-only.

Commit 99ee73a

Browse files
committed
feat(orm): support where enum
1 parent 549a026 commit 99ee73a

2 files changed

Lines changed: 101 additions & 2 deletions

File tree

packages/orm/src/client/executor/name-mapper.ts

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { invariant } from '@zenstackhq/common-helpers';
22
import {
33
AliasNode,
4+
BinaryOperationNode,
45
CaseWhenBuilder,
56
ColumnNode,
67
ColumnUpdateNode,
@@ -10,20 +11,21 @@ import {
1011
FromNode,
1112
IdentifierNode,
1213
InsertQueryNode,
14+
type OperationNode,
1315
OperationNodeTransformer,
1416
PrimitiveValueListNode,
1517
ReferenceNode,
1618
ReturningNode,
1719
SelectAllNode,
1820
SelectionNode,
1921
SelectQueryNode,
22+
type SimpleReferenceExpressionNode,
2023
TableNode,
2124
UpdateQueryNode,
2225
ValueListNode,
2326
ValueNode,
2427
ValuesNode,
25-
type OperationNode,
26-
type SimpleReferenceExpressionNode,
28+
WhereNode,
2729
} from 'kysely';
2830
import type { EnumDef, EnumField, FieldDef, ModelDef, SchemaDef } from '../../schema';
2931
import {
@@ -183,6 +185,38 @@ export class QueryNameMapper extends OperationNodeTransformer {
183185
return ColumnNode.create(mappedName);
184186
}
185187

188+
protected override transformWhere(node: WhereNode): WhereNode {
189+
if (
190+
BinaryOperationNode.is(node.where) &&
191+
ReferenceNode.is(node.where.leftOperand) &&
192+
ColumnNode.is(node.where.leftOperand.column) &&
193+
node.where.leftOperand.table &&
194+
TableNode.is(node.where.leftOperand.table) &&
195+
// where: { enumColumn: Enum.VALUE }
196+
(ValueNode.is(node.where.rightOperand) ||
197+
// where: { enumColumn: { in: [Enum.VALUE] } }
198+
PrimitiveValueListNode.is(node.where.rightOperand))
199+
) {
200+
const tableName = node.where.leftOperand.table.table.identifier.name;
201+
const columnNode = node.where.leftOperand.column;
202+
const valueNode = node.where.rightOperand;
203+
204+
let resultValue: OperationNode = valueNode;
205+
206+
if (ValueNode.is(valueNode)) {
207+
resultValue = this.processEnumMappingForValue(tableName, columnNode, valueNode) as OperationNode;
208+
} else if (PrimitiveValueListNode.is(valueNode)) {
209+
resultValue = PrimitiveValueListNode.create(
210+
this.processEnumMappingForValues(tableName, [columnNode], valueNode.values),
211+
);
212+
}
213+
214+
return WhereNode.create(BinaryOperationNode.create(node.where.leftOperand, node.where.operator, resultValue));
215+
}
216+
217+
return super.transformWhere(node);
218+
}
219+
186220
protected override transformUpdateQuery(node: UpdateQueryNode) {
187221
if (!node.table) {
188222
return super.transformUpdateQuery(node);

tests/e2e/orm/client-api/name-mapping.test.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,16 @@ describe('Name mapping tests', () => {
4646
user_role: 'role_user',
4747
});
4848

49+
rawRead = await db.$qbRaw
50+
.selectFrom('users')
51+
.where('user_role', '=', 'role_user')
52+
.selectAll()
53+
.executeTakeFirst();
54+
await expect(rawRead).toMatchObject({
55+
user_email: 'u1@test.com',
56+
user_role: 'role_user',
57+
});
58+
4959
await expect(
5060
db.user.create({
5161
data: {
@@ -66,6 +76,15 @@ describe('Name mapping tests', () => {
6676
user_role: 'MODERATOR',
6777
});
6878

79+
rawRead = await db.$qbRaw
80+
.selectFrom('users')
81+
.where('user_role', '=', 'MODERATOR')
82+
.selectAll()
83+
.executeTakeFirst();
84+
await expect(rawRead).toMatchObject({
85+
user_role: 'MODERATOR',
86+
});
87+
6988
await expect(
7089
db.$qb
7190
.insertInto('User')
@@ -146,6 +165,52 @@ describe('Name mapping tests', () => {
146165
posts: [{ title: 'Post1' }],
147166
});
148167

168+
await expect(
169+
db.user.findFirst({
170+
where: { role: 'USER' },
171+
select: {
172+
email: true,
173+
role: true,
174+
},
175+
}),
176+
).resolves.toMatchObject({
177+
email: 'u1@test.com',
178+
role: 'USER',
179+
});
180+
181+
await expect(
182+
db.user.findMany({
183+
where: { role: 'USER' },
184+
select: {
185+
email: true,
186+
role: true,
187+
},
188+
}),
189+
).resolves.toEqual([expect.objectContaining({ email: 'u1@test.com', role: 'USER' })]);
190+
191+
await expect(
192+
db.user.findFirst({
193+
where: { role: { in: ['USER'] } },
194+
select: {
195+
email: true,
196+
role: true,
197+
},
198+
}),
199+
).resolves.toMatchObject({
200+
email: 'u1@test.com',
201+
role: 'USER',
202+
});
203+
204+
await expect(
205+
db.user.findMany({
206+
where: { role: { in: ['USER'] } },
207+
select: {
208+
email: true,
209+
role: true,
210+
},
211+
}),
212+
).resolves.toEqual([expect.objectContaining({ email: 'u1@test.com', role: 'USER' })]);
213+
149214
// select all
150215
await expect(
151216
db.user.findFirst({

0 commit comments

Comments
 (0)