fix(utils): build query conversion breaking the underlying API operator map (#9533)

This commit is contained in:
Adrien de Peretti
2024-10-11 18:03:58 +02:00
committed by GitHub
parent 69b9e73be7
commit 5c9e289c4d
3 changed files with 100 additions and 6 deletions

View File

@@ -80,9 +80,7 @@ export interface FindConfig<Entity> {
* 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`
* to sort retrieved records in an ascending order, or `DESC` to sort retrieved records in a descending order.
*/
order?: {
[K: string]: "ASC" | "DESC"
}
order?: Record<string, "ASC" | "DESC" | (string & {})>
/**
* A boolean indicating whether deleted records should also be retrieved as part of the result. This only works if the entity extends the

View File

@@ -0,0 +1,97 @@
import { buildQuery } from "../build-query"
import { SoftDeletableFilterKey } from "../../dal/mikro-orm/mikro-orm-soft-deletable-filter"
describe("buildQuery", () => {
test("should return empty where and basic options when no filters or config provided", () => {
const result = buildQuery()
expect(result).toEqual({
where: {},
options: {
populate: [],
fields: undefined,
limit: undefined,
offset: undefined,
},
})
})
test("should build basic where clause", () => {
const filters = { name: "test", age: 25 }
const result = buildQuery(filters)
expect(result.where).toEqual(filters)
})
test("should handle array values in filters", () => {
const filters = { id: [1, 2, 3, 3] }
const result = buildQuery(filters)
expect(result.where).toEqual({ id: [1, 2, 3] }) // Deduplication
})
test("should handle nested object filters", () => {
const filters = { user: { name: "John", age: 30 } }
const result = buildQuery(filters)
expect(result.where).toEqual(filters)
})
test("should handle $or operator", () => {
const filters = { $or: [{ name: "John" }, { age: 30 }] }
const result = buildQuery(filters)
expect(result.where).toEqual(filters)
})
test("should handle $and operator", () => {
const filters = { $and: [{ name: "John" }, { age: 30 }] }
const result = buildQuery(filters)
expect(result.where).toEqual(filters)
})
test("should apply config options", () => {
const config = {
relations: ["user", "order"],
select: ["id", "name"],
take: 10,
skip: 5,
order: { createdAt: "DESC" },
}
const result = buildQuery({}, config)
expect(result.options).toMatchObject({
populate: ["user", "order"],
fields: ["id", "name"],
limit: 10,
offset: 5,
orderBy: { createdAt: "DESC" },
})
})
test("should handle withDeleted flag", () => {
const filters = { deleted_at: "some-value" }
const result = buildQuery(filters)
expect(result.options.filters).toHaveProperty(SoftDeletableFilterKey)
expect(result.options.filters?.[SoftDeletableFilterKey]).toEqual({
withDeleted: true,
})
})
test("should apply additional filters from config", () => {
const config = {
filters: {
customFilter: { someOption: true },
},
}
const result = buildQuery({}, config)
expect(result.options.filters).toHaveProperty("customFilter")
expect(result.options.filters?.["customFilter"]).toEqual({
someOption: true,
})
})
test("should merge options from config", () => {
const config = {
options: {
customOption: "value",
},
}
const result = buildQuery({}, config)
expect(result.options).toHaveProperty("customOption", "value")
})
})

View File

@@ -13,7 +13,7 @@ type FilterFlags = {
export function buildQuery<T = any, TDto = any>(
filters: Record<string, any> = {},
config: FindConfig<TDto> & { primaryKeyFields?: string | string[] } = {}
): DAL.FindOptions<T> {
): Required<DAL.FindOptions<T>> {
const where: DAL.FilterQuery<T> = {}
const filterFlags: FilterFlags = {}
buildWhere(filters, where, filterFlags)
@@ -73,8 +73,7 @@ function buildWhere(
}
if (Array.isArray(value)) {
value = deduplicate(value)
where[prop] = ["$in", "$nin"].includes(prop) ? value : { $in: value }
where[prop] = deduplicate(value)
continue
}