Skip to content

Commit 5c9e289

Browse files
authored
fix(utils): build query conversion breaking the underlying API operator map (#9533)
1 parent 69b9e73 commit 5c9e289

File tree

3 files changed

+100
-6
lines changed

3 files changed

+100
-6
lines changed

packages/core/types/src/common/common.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,7 @@ export interface FindConfig<Entity> {
8080
* An object used to specify how to sort the returned records. Its keys are the names of attributes of the entity, and a key's value can either be `ASC`
8181
* to sort retrieved records in an ascending order, or `DESC` to sort retrieved records in a descending order.
8282
*/
83-
order?: {
84-
[K: string]: "ASC" | "DESC"
85-
}
83+
order?: Record<string, "ASC" | "DESC" | (string & {})>
8684

8785
/**
8886
* A boolean indicating whether deleted records should also be retrieved as part of the result. This only works if the entity extends the
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import { buildQuery } from "../build-query"
2+
import { SoftDeletableFilterKey } from "../../dal/mikro-orm/mikro-orm-soft-deletable-filter"
3+
4+
describe("buildQuery", () => {
5+
test("should return empty where and basic options when no filters or config provided", () => {
6+
const result = buildQuery()
7+
expect(result).toEqual({
8+
where: {},
9+
options: {
10+
populate: [],
11+
fields: undefined,
12+
limit: undefined,
13+
offset: undefined,
14+
},
15+
})
16+
})
17+
18+
test("should build basic where clause", () => {
19+
const filters = { name: "test", age: 25 }
20+
const result = buildQuery(filters)
21+
expect(result.where).toEqual(filters)
22+
})
23+
24+
test("should handle array values in filters", () => {
25+
const filters = { id: [1, 2, 3, 3] }
26+
const result = buildQuery(filters)
27+
expect(result.where).toEqual({ id: [1, 2, 3] }) // Deduplication
28+
})
29+
30+
test("should handle nested object filters", () => {
31+
const filters = { user: { name: "John", age: 30 } }
32+
const result = buildQuery(filters)
33+
expect(result.where).toEqual(filters)
34+
})
35+
36+
test("should handle $or operator", () => {
37+
const filters = { $or: [{ name: "John" }, { age: 30 }] }
38+
const result = buildQuery(filters)
39+
expect(result.where).toEqual(filters)
40+
})
41+
42+
test("should handle $and operator", () => {
43+
const filters = { $and: [{ name: "John" }, { age: 30 }] }
44+
const result = buildQuery(filters)
45+
expect(result.where).toEqual(filters)
46+
})
47+
48+
test("should apply config options", () => {
49+
const config = {
50+
relations: ["user", "order"],
51+
select: ["id", "name"],
52+
take: 10,
53+
skip: 5,
54+
order: { createdAt: "DESC" },
55+
}
56+
const result = buildQuery({}, config)
57+
expect(result.options).toMatchObject({
58+
populate: ["user", "order"],
59+
fields: ["id", "name"],
60+
limit: 10,
61+
offset: 5,
62+
orderBy: { createdAt: "DESC" },
63+
})
64+
})
65+
66+
test("should handle withDeleted flag", () => {
67+
const filters = { deleted_at: "some-value" }
68+
const result = buildQuery(filters)
69+
expect(result.options.filters).toHaveProperty(SoftDeletableFilterKey)
70+
expect(result.options.filters?.[SoftDeletableFilterKey]).toEqual({
71+
withDeleted: true,
72+
})
73+
})
74+
75+
test("should apply additional filters from config", () => {
76+
const config = {
77+
filters: {
78+
customFilter: { someOption: true },
79+
},
80+
}
81+
const result = buildQuery({}, config)
82+
expect(result.options.filters).toHaveProperty("customFilter")
83+
expect(result.options.filters?.["customFilter"]).toEqual({
84+
someOption: true,
85+
})
86+
})
87+
88+
test("should merge options from config", () => {
89+
const config = {
90+
options: {
91+
customOption: "value",
92+
},
93+
}
94+
const result = buildQuery({}, config)
95+
expect(result.options).toHaveProperty("customOption", "value")
96+
})
97+
})

packages/core/utils/src/modules-sdk/build-query.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ type FilterFlags = {
1313
export function buildQuery<T = any, TDto = any>(
1414
filters: Record<string, any> = {},
1515
config: FindConfig<TDto> & { primaryKeyFields?: string | string[] } = {}
16-
): DAL.FindOptions<T> {
16+
): Required<DAL.FindOptions<T>> {
1717
const where: DAL.FilterQuery<T> = {}
1818
const filterFlags: FilterFlags = {}
1919
buildWhere(filters, where, filterFlags)
@@ -73,8 +73,7 @@ function buildWhere(
7373
}
7474

7575
if (Array.isArray(value)) {
76-
value = deduplicate(value)
77-
where[prop] = ["$in", "$nin"].includes(prop) ? value : { $in: value }
76+
where[prop] = deduplicate(value)
7877
continue
7978
}
8079

0 commit comments

Comments
 (0)