feat: Add generic link filter middleware (#6969)

This commit is contained in:
Oli Juhl
2024-04-06 11:18:03 +02:00
committed by GitHub
parent 94146e4bfe
commit c31dea02eb
8 changed files with 82 additions and 94 deletions

View File

@@ -1,11 +1,9 @@
import { transformBody, transformQuery } from "../../../api/middlewares"
import { MiddlewareRoute } from "../../../loaders/helpers/routing/types"
import { authenticate } from "../../../utils/authenticate-middleware"
import { maybeApplyLinkFilter } from "../../utils/maybe-apply-link-filter"
import * as QueryConfig from "./query-config"
import {
maybeApplyPriceListsFilter,
maybeApplySalesChannelsFilter,
} from "./utils"
import { maybeApplyPriceListsFilter } from "./utils"
import {
AdminGetProductsOptionsParams,
AdminGetProductsParams,
@@ -35,7 +33,11 @@ export const adminProductRoutesMiddlewares: MiddlewareRoute[] = [
AdminGetProductsParams,
QueryConfig.listProductQueryConfig
),
maybeApplySalesChannelsFilter(),
maybeApplyLinkFilter({
entryPoint: "product_sales_channel",
resourceId: "product_id",
filterableField: "sales_channel_id",
}),
maybeApplyPriceListsFilter(),
],
},

View File

@@ -1,3 +1 @@
export * from "./maybe-apply-price-lists-filter"
export * from "./maybe-apply-sales-channels-filter"

View File

@@ -1,36 +0,0 @@
import {
ContainerRegistrationKeys,
remoteQueryObjectFromString,
} from "@medusajs/utils"
import { NextFunction } from "express"
import { MedusaRequest } from "../../../../types/routing"
import { AdminGetProductsParams } from "../validators"
export function maybeApplySalesChannelsFilter() {
return async (req: MedusaRequest, _, next: NextFunction) => {
const filterableFields: AdminGetProductsParams = req.filterableFields
if (!filterableFields.sales_channel_id) {
return next()
}
const salesChannelIds = filterableFields.sales_channel_id
delete filterableFields.sales_channel_id
const remoteQuery = req.scope.resolve(
ContainerRegistrationKeys.REMOTE_QUERY
)
const queryObject = remoteQueryObjectFromString({
entryPoint: "product_sales_channel",
fields: ["product_id"],
variables: { sales_channel_id: salesChannelIds },
})
const productsInSalesChannels = await remoteQuery(queryObject)
filterableFields.id = productsInSalesChannels.map((p) => p.product_id)
return next()
}
}

View File

@@ -1,6 +1,7 @@
import { transformBody, transformQuery } from "../../../api/middlewares"
import { MiddlewareRoute } from "../../../loaders/helpers/routing/types"
import { authenticate } from "../../../utils/authenticate-middleware"
import { maybeApplyLinkFilter } from "../../utils/maybe-apply-link-filter"
import * as QueryConfig from "./query-config"
import {
AdminGetSalesChannelsParams,
@@ -24,6 +25,16 @@ export const adminSalesChannelRoutesMiddlewares: MiddlewareRoute[] = [
AdminGetSalesChannelsParams,
QueryConfig.listTransformQueryConfig
),
maybeApplyLinkFilter({
entryPoint: "sales_channel_location",
resourceId: "sales_channel_id",
filterableField: "location_id",
}),
maybeApplyLinkFilter({
entryPoint: "publishable_api_key_sales_channel",
resourceId: "sales_channel_id",
filterableField: "publishable_key_id",
}),
],
},
{

View File

@@ -46,6 +46,20 @@ export class AdminGetSalesChannelsParams extends extendedFindParamsMixin({
@Type(() => OperatorMapValidator)
created_at?: OperatorMap<string>
/**
* Filter by location id
*/
@IsString({ each: true })
@IsOptional()
location_id?: string | string[]
/**
* Filter by publishable api keys
*/
@IsString({ each: true })
@IsOptional()
publishable_key_id?: string | string[]
/**
* Date filters to apply on sales channels' `updated_at` field.
*/

View File

@@ -14,8 +14,8 @@ import {
import { MiddlewareRoute } from "../../../types/middlewares"
import { authenticate } from "../../../utils/authenticate-middleware"
import { maybeApplyLinkFilter } from "../../utils/maybe-apply-link-filter"
import { validateAndTransformBody } from "../../utils/validate-body"
import { applySalesChannelsFilter } from "./utils/apply-sales-channel-filter"
export const adminStockLocationRoutesMiddlewares: MiddlewareRoute[] = [
{
@@ -42,7 +42,11 @@ export const adminStockLocationRoutesMiddlewares: MiddlewareRoute[] = [
AdminGetStockLocationsParams,
QueryConfig.listTransformQueryConfig
),
applySalesChannelsFilter(),
maybeApplyLinkFilter({
entryPoint: "sales_channel_location",
resourceId: "stock_location_id",
filterableField: "sales_channel_id",
}),
],
},
{

View File

@@ -1,49 +0,0 @@
import {
ContainerRegistrationKeys,
remoteQueryObjectFromString,
} from "@medusajs/utils"
import { AdminGetStockLocationsParams } from "../validators"
import { MedusaRequest } from "../../../../types/routing"
import { Modules } from "@medusajs/modules-sdk"
import { NextFunction } from "express"
export function applySalesChannelsFilter() {
return async (req: MedusaRequest, _, next: NextFunction) => {
const filterableFields: AdminGetStockLocationsParams = req.filterableFields
if (!filterableFields.sales_channel_id) {
return next()
}
const salesChannelIds = Array.isArray(filterableFields.sales_channel_id)
? filterableFields.sales_channel_id
: [filterableFields.sales_channel_id]
delete filterableFields.sales_channel_id
const remoteLinkService = req.scope.resolve(
ContainerRegistrationKeys.REMOTE_LINK
)
const stockLocationSalesChannelLinkModuleService =
await remoteLinkService.getLinkModule(
Modules.SALES_CHANNEL,
"sales_channel_id",
Modules.STOCK_LOCATION,
"stock_location_id"
)
const stockLocationSalesChannelLinks =
await stockLocationSalesChannelLinkModuleService.list(
{ sales_channel_id: salesChannelIds },
{}
)
filterableFields.id = stockLocationSalesChannelLinks.map(
(link) => link.stock_location_id
)
return next()
}
}

View File

@@ -0,0 +1,44 @@
import {
ContainerRegistrationKeys,
remoteQueryObjectFromString,
} from "@medusajs/utils"
import { NextFunction } from "express"
import { MedusaRequest } from "../../types/routing"
export function maybeApplyLinkFilter({
entryPoint,
resourceId,
filterableField,
}) {
return async (req: MedusaRequest, _, next: NextFunction) => {
const filterableFields = req.filterableFields
if (!filterableFields?.[filterableField]) {
return next()
}
const filterFields = filterableFields[filterableField]
const idsToFilterBy = Array.isArray(filterFields)
? filterFields
: [filterFields]
delete filterableFields[filterableField]
const remoteQuery = req.scope.resolve(
ContainerRegistrationKeys.REMOTE_QUERY
)
const queryObject = remoteQueryObjectFromString({
entryPoint,
fields: [resourceId],
variables: { [filterableField]: idsToFilterBy },
})
const resources = await remoteQuery(queryObject)
filterableFields.id = resources.map((p) => p[resourceId])
return next()
}
}