fix: Allow filtering products by variant options in store (#7784)

This commit is contained in:
Stevche Radevski authored and GitHub committed 2024-06-21 10:42:09 +02:00
1 parent ee35379e21
commit 944051a951
6 files changed
+246 -508

No files matched your search

@@ -22,6 +22,7 @@ export const StoreGetProductVariantsParams = createFindParams({
q: z.string().optional(),
id: z.union([z.string(), z.array(z.string())]).optional(),
status: ProductStatusEnum.array().optional(),
options: z.object({ value: z.string(), option_id: z.string() }).optional(),
created_at: createOperatorMap().optional(),
updated_at: createOperatorMap().optional(),
deleted_at: createOperatorMap().optional(),
@@ -39,7 +40,16 @@ export const StoreGetProductsParams = createFindParams({
.object({
region_id: z.string().optional(),
currency_code: z.string().optional(),
variants: StoreGetProductVariantsParams.optional(),
variants: z
.object({
status: ProductStatusEnum.array().optional(),
options: z
.object({ value: z.string(), option_id: z.string() })
.optional(),
$and: z.lazy(() => StoreGetProductsParams.array()).optional(),
$or: z.lazy(() => StoreGetProductsParams.array()).optional(),
})
.optional(),
$and: z.lazy(() => StoreGetProductsParams.array()).optional(),
$or: z.lazy(() => StoreGetProductsParams.array()).optional(),
})
@@ -9,18 +9,41 @@ import {
prepareRetrieveQuery,
} from "../../utils/get-query-config"
import { zodValidator } from "./zod-helper"
import { MedusaError } from "@medusajs/utils"
/**
* Normalize an input query, especially from array like query params to an array type
* e.g: /admin/orders/?fields[]=id,status,cart_id becomes { fields: ["id", "status", "cart_id"] }
*
* We only support up to 2 levels of depth for query params in order to have a somewhat readable query param, and limit possible performance issues
*/
const normalizeQuery = (req: MedusaRequest) => {
return Object.entries(req.query).reduce((acc, [key, val]) => {
if (Array.isArray(val) && val.length === 1) {
acc[key] = (val as string[])[0].split(",")
} else {
acc[key] = val
let normalizedValue = val
if (Array.isArray(val) && val.length === 1 && typeof val[0] === "string") {
normalizedValue = val[0].split(",")
}
if (key.includes(".")) {
const [parent, child, ...others] = key.split(".")
if (others.length > 0) {
throw new MedusaError(
MedusaError.Types.INVALID_ARGUMENT,
`Key accessor more than 2 levels deep: ${key}`
)
}
if (!acc[parent]) {
acc[parent] = {}
}
acc[parent] = {
...acc[parent],
[child]: normalizedValue,
}
} else {
acc[key] = normalizedValue
}
return acc
}, {})
}