From d930d883699dc078cc4adf35e5525862eaf6b72d Mon Sep 17 00:00:00 2001 From: Stevche Radevski Date: Wed, 1 May 2024 11:25:24 +0200 Subject: [PATCH] fix: Ensure passed Id filters get applied on top of maybe link filter (#7182) --- .../__tests__/product/store/index.spec.ts | 12 ++++++++++++ .../api-v2/utils/maybe-apply-link-filter.ts | 15 ++++++++++++++- .../__tests__/array-intersection.spec.ts | 18 ++++++++++++++++++ .../utils/src/common/array-intersection.ts | 17 +++++++++++++++++ packages/utils/src/common/index.ts | 1 + 5 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 packages/utils/src/common/__tests__/array-intersection.spec.ts create mode 100644 packages/utils/src/common/array-intersection.ts diff --git a/integration-tests/modules/__tests__/product/store/index.spec.ts b/integration-tests/modules/__tests__/product/store/index.spec.ts index bfede76bc6..9001bc78e1 100644 --- a/integration-tests/modules/__tests__/product/store/index.spec.ts +++ b/integration-tests/modules/__tests__/product/store/index.spec.ts @@ -247,6 +247,18 @@ medusaIntegrationTestRunner({ ]) }) + it("should list products by id", async () => { + let response = await api.get(`/store/products?id[]=${product.id}`) + + expect(response.status).toEqual(200) + expect(response.data.count).toEqual(1) + expect(response.data.products).toEqual([ + expect.objectContaining({ + id: product.id, + }), + ]) + }) + it("should throw error when publishable key is invalid", async () => { let error = await api .get(`/store/products?sales_channel_id[]=does-not-exist`, { diff --git a/packages/medusa/src/api-v2/utils/maybe-apply-link-filter.ts b/packages/medusa/src/api-v2/utils/maybe-apply-link-filter.ts index 4523ac0108..0df9508ea2 100644 --- a/packages/medusa/src/api-v2/utils/maybe-apply-link-filter.ts +++ b/packages/medusa/src/api-v2/utils/maybe-apply-link-filter.ts @@ -1,6 +1,7 @@ import { ContainerRegistrationKeys, remoteQueryObjectFromString, + arrayIntersection, } from "@medusajs/utils" import { NextFunction } from "express" import { MedusaRequest } from "../../types/routing" @@ -37,7 +38,19 @@ export function maybeApplyLinkFilter({ const resources = await remoteQuery(queryObject) - filterableFields.id = resources.map((p) => p[resourceId]) + let existingIdFilters = filterableFields.id as string[] | string | undefined + if (existingIdFilters) { + if (typeof existingIdFilters === "string") { + existingIdFilters = [existingIdFilters] + } + + filterableFields.id = arrayIntersection( + existingIdFilters, + resources.map((p) => p[resourceId]) + ) + } else { + filterableFields.id = resources.map((p) => p[resourceId]) + } return next() } diff --git a/packages/utils/src/common/__tests__/array-intersection.spec.ts b/packages/utils/src/common/__tests__/array-intersection.spec.ts new file mode 100644 index 0000000000..3338ad6222 --- /dev/null +++ b/packages/utils/src/common/__tests__/array-intersection.spec.ts @@ -0,0 +1,18 @@ +import { arrayIntersection } from "../array-intersection" + +describe("arrayIntersection", function () { + it("should return the intersection between two arrays", function () { + const output = arrayIntersection(["foo", "bar"], ["bar", "baz"]) + expect(output).toEqual(["bar"]) + }) + + it("should return an empty array if there is no intersection", function () { + const output = arrayIntersection(["bar", "baz"], ["foo", "boo"]) + expect(output).toEqual([]) + }) + + it("should return an all items when the arrays are equivalent", function () { + const output = arrayIntersection(["bar", "baz"], ["baz", "bar"]) + expect(output).toEqual(["baz", "bar"]) + }) +}) diff --git a/packages/utils/src/common/array-intersection.ts b/packages/utils/src/common/array-intersection.ts new file mode 100644 index 0000000000..d88558e4ba --- /dev/null +++ b/packages/utils/src/common/array-intersection.ts @@ -0,0 +1,17 @@ +type ArrayIntersectionElement = string | number + +export function arrayIntersection( + firstArray: TElement[], + secondArray: TElement[] +): TElement[] { + const firstArraySet = new Set(firstArray) + const res = new Set() + + secondArray.forEach((element) => { + if (firstArraySet.has(element)) { + res.add(element) + } + }) + + return Array.from(res) +} diff --git a/packages/utils/src/common/index.ts b/packages/utils/src/common/index.ts index 9f7b839ff1..919937c875 100644 --- a/packages/utils/src/common/index.ts +++ b/packages/utils/src/common/index.ts @@ -1,5 +1,6 @@ export * from "./alter-columns-helper" export * from "./array-difference" +export * from "./array-intersection" export * from "./build-query" export * from "./camel-to-snake-case" export * from "./container"