feat: Add batch method to collection and clean up some batch implementations (#7102)

This commit is contained in:
Stevche Radevski authored and GitHub committed 2024-04-22 08:36:22 +00:00
1 parent 0f5b015df0
commit 89143e1032
26 files changed
+425 -123

No files matched your search

@@ -0,0 +1,39 @@
import { batchLinkProductsToCollectionWorkflow } from "@medusajs/core-flows"
import {
AuthenticatedMedusaRequest,
MedusaResponse,
} from "../../../../../types/routing"
import { LinkMethodRequest } from "@medusajs/types/src"
import { refetchCollection } from "../../helpers"
export const POST = async (
req: AuthenticatedMedusaRequest<LinkMethodRequest>,
res: MedusaResponse
) => {
const id = req.params.id
const { add = [], remove = [] } = req.validatedBody
const workflow = batchLinkProductsToCollectionWorkflow(req.scope)
const { result, errors } = await workflow.run({
input: {
id,
add,
remove,
},
throwOnError: false,
})
if (Array.isArray(errors) && errors[0]) {
throw errors[0].error
}
const collection = await refetchCollection(
req.params.id,
req.scope,
req.remoteQueryConfig.fields
)
res.status(200).json({
collection,
})
}
@@ -9,6 +9,7 @@ import {
AdminUpdateCollection,
} from "./validators"
import { validateAndTransformBody } from "../../utils/validate-body"
import { createLinkBody } from "../../utils/validators"
export const adminCollectionRoutesMiddlewares: MiddlewareRoute[] = [
{
@@ -64,5 +65,15 @@ export const adminCollectionRoutesMiddlewares: MiddlewareRoute[] = [
matcher: "/admin/collections/:id",
middlewares: [],
},
// TODO: There were two batch methods, they need to be handled
{
method: ["POST"],
matcher: "/admin/collections/:id/products",
middlewares: [
validateAndTransformBody(createLinkBody()),
validateAndTransformQuery(
AdminGetCollectionParams,
QueryConfig.retrieveTransformQueryConfig
),
],
},
]
@@ -1,11 +1,8 @@
import {
AdminCreateInventoryLocationLevelType,
AdminUpdateInventoryLocationLevelType,
} from "../../../../validators"
import {
MedusaRequest,
MedusaResponse,
} from "../../../../../../../types/routing"
} from "../../../validators"
import { MedusaRequest, MedusaResponse } from "../../../../../../types/routing"
import { bulkCreateDeleteLevelsWorkflow } from "@medusajs/core-flows"
import { BatchMethodRequest } from "@medusajs/types"
@@ -14,6 +14,7 @@ import {
} from "./validators"
import { validateAndTransformBody } from "../../utils/validate-body"
import { createBatchBody } from "../../utils/validators"
import { unlessPath } from "../../utils/unless-path"
export const adminInventoryRoutesMiddlewares: MiddlewareRoute[] = [
{
@@ -84,30 +85,9 @@ export const adminInventoryRoutesMiddlewares: MiddlewareRoute[] = [
),
],
},
{
method: ["DELETE"],
matcher: "/admin/inventory-items/:id/location-levels/:location_id",
middlewares: [
validateAndTransformQuery(
AdminGetInventoryItemParams,
QueryConfig.retrieveTransformQueryConfig
),
],
},
{
method: ["POST"],
matcher: "/admin/inventory-items/:id/location-levels/:location_id",
middlewares: [
validateAndTransformBody(AdminUpdateInventoryLocationLevel),
validateAndTransformQuery(
AdminGetInventoryItemParams,
QueryConfig.retrieveTransformQueryConfig
),
],
},
{
method: ["POST"],
matcher: "/admin/inventory-items/:id/location-levels/op/batch",
matcher: "/admin/inventory-items/:id/location-levels/batch",
middlewares: [
validateAndTransformBody(
createBatchBody(
@@ -121,4 +101,34 @@ export const adminInventoryRoutesMiddlewares: MiddlewareRoute[] = [
),
],
},
{
method: ["DELETE"],
matcher: "/admin/inventory-items/:id/location-levels/:location_id",
middlewares: [
unlessPath(
/.*\/location-levels\/batch/,
validateAndTransformQuery(
AdminGetInventoryItemParams,
QueryConfig.retrieveTransformQueryConfig
)
),
],
},
{
method: ["POST"],
matcher: "/admin/inventory-items/:id/location-levels/:location_id",
middlewares: [
unlessPath(
/.*\/location-levels\/batch/,
validateAndTransformBody(AdminUpdateInventoryLocationLevel)
),
unlessPath(
/.*\/location-levels\/batch/,
validateAndTransformQuery(
AdminGetInventoryItemParams,
QueryConfig.retrieveTransformQueryConfig
)
),
],
},
]
@@ -43,7 +43,7 @@ export const adminPaymentRoutesMiddlewares: MiddlewareRoute[] = [
matcher: "/admin/payments/:id",
middlewares: [
unlessPath(
new RegExp("/admin/payments/payment-providers"),
/.*\/payments\/payment-providers/,
validateAndTransformQuery(
AdminGetPaymentParams,
queryConfig.retrieveTransformQueryConfig
@@ -1,16 +1,24 @@
import { batchPriceListPricesWorkflow } from "@medusajs/core-flows"
import { promiseAll } from "@medusajs/utils"
import {
AuthenticatedMedusaRequest,
MedusaResponse,
} from "../../../../../../types/routing"
import { fetchPriceListPriceIdsForProduct } from "../../../helpers"
import { listPrices } from "../../../queries"
import { adminPriceListPriceRemoteQueryFields } from "../../../query-config"
import { AdminBatchPriceListPricesType } from "../../../validators"
import { BatchMethodRequest } from "@medusajs/types"
import {
AdminCreatePriceListPriceType,
AdminUpdatePriceListPriceType,
} from "../../../validators"
import { batchPriceListPricesWorkflow } from "@medusajs/core-flows"
export const POST = async (
req: AuthenticatedMedusaRequest<AdminBatchPriceListPricesType>,
req: AuthenticatedMedusaRequest<
BatchMethodRequest<
AdminCreatePriceListPriceType,
AdminUpdatePriceListPriceType
>
>,
res: MedusaResponse
) => {
const id = req.params.id
@@ -18,16 +26,8 @@ export const POST = async (
create = [],
update = [],
delete: deletePriceIds = [],
product_id: productIds = [],
} = req.validatedBody
const productPriceIds = await fetchPriceListPriceIdsForProduct(
id,
productIds,
req.scope
)
const priceIdsToDelete = [...deletePriceIds, ...productPriceIds]
const workflow = batchPriceListPricesWorkflow(req.scope)
const { result, errors } = await workflow.run({
input: {
@@ -35,7 +35,7 @@ export const POST = async (
id,
create,
update,
delete: priceIdsToDelete,
delete: deletePriceIds,
},
},
throwOnError: false,
@@ -62,7 +62,7 @@ export const POST = async (
created,
updated,
deleted: {
ids: priceIdsToDelete,
ids: deletePriceIds,
object: "price",
deleted: true,
},
@@ -0,0 +1,60 @@
import { MedusaError } from "@medusajs/utils"
import {
AuthenticatedMedusaRequest,
MedusaResponse,
} from "../../../../../types/routing"
import { batchPriceListPricesWorkflow } from "@medusajs/core-flows"
import { LinkMethodRequest } from "@medusajs/types/src"
import { fetchPriceList, fetchPriceListPriceIdsForProduct } from "../../helpers"
export const POST = async (
req: AuthenticatedMedusaRequest<LinkMethodRequest>,
res: MedusaResponse
) => {
const id = req.params.id
const { add, remove = [] } = req.validatedBody
if (add?.length) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
"Adding products directly to a price list is not supported, please use the /admin/price-lists/:id/prices/batch endpoint instead"
)
}
if (!remove.length) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
"No product ids passed to remove from price list"
)
}
const productPriceIds = await fetchPriceListPriceIdsForProduct(
id,
remove,
req.scope
)
const workflow = batchPriceListPricesWorkflow(req.scope)
const { result, errors } = await workflow.run({
input: {
data: {
id,
create: [],
update: [],
delete: productPriceIds,
},
},
throwOnError: false,
})
if (Array.isArray(errors) && errors[0]) {
throw errors[0].error
}
const priceList = await fetchPriceList(
id,
req.scope,
req.remoteQueryConfig.fields
)
res.status(200).json({ price_list: priceList })
}
@@ -2,14 +2,16 @@ import { MiddlewareRoute } from "../../../loaders/helpers/routing/types"
import { authenticate } from "../../../utils/authenticate-middleware"
import { validateAndTransformBody } from "../../utils/validate-body"
import { validateAndTransformQuery } from "../../utils/validate-query"
import { createBatchBody, createLinkBody } from "../../utils/validators"
import * as QueryConfig from "./query-config"
import {
AdminBatchPriceListPrices,
AdminCreatePriceList,
AdminCreatePriceListPrice,
AdminGetPriceListParams,
AdminGetPriceListPricesParams,
AdminGetPriceListsParams,
AdminUpdatePriceList,
AdminUpdatePriceListPrice,
} from "./validators"
export const adminPriceListsRoutesMiddlewares: MiddlewareRoute[] = [
@@ -60,11 +62,24 @@ export const adminPriceListsRoutesMiddlewares: MiddlewareRoute[] = [
),
],
},
{
method: ["POST"],
matcher: "/admin/price-lists/:id/products",
middlewares: [
validateAndTransformBody(createLinkBody()),
validateAndTransformQuery(
AdminGetPriceListParams,
QueryConfig.listPriceListQueryConfig
),
],
},
{
method: ["POST"],
matcher: "/admin/price-lists/:id/prices/batch",
middlewares: [
validateAndTransformBody(AdminBatchPriceListPrices),
validateAndTransformBody(
createBatchBody(AdminCreatePriceListPrice, AdminUpdatePriceListPrice)
),
validateAndTransformQuery(
AdminGetPriceListPricesParams,
QueryConfig.listPriceListPriceQueryConfig
@@ -40,17 +40,6 @@ export type AdminUpdatePriceListPriceType = z.infer<
typeof AdminUpdatePriceListPrice
>
export const AdminBatchPriceListPrices = z.object({
create: z.array(AdminCreatePriceListPrice).optional(),
update: z.array(AdminUpdatePriceListPrice).optional(),
delete: z.array(z.string()).optional(),
product_id: z.array(z.string()).optional(),
})
export type AdminBatchPriceListPricesType = z.infer<
typeof AdminBatchPriceListPrices
>
export const AdminCreatePriceList = z.object({
title: z.string(),
description: z.string(),
@@ -2,13 +2,13 @@ import { batchProductVariantsWorkflow } from "@medusajs/core-flows"
import {
AuthenticatedMedusaRequest,
MedusaResponse,
} from "../../../../../../../types/routing"
} from "../../../../../../types/routing"
import {
AdminBatchUpdateProductVariantType,
AdminCreateProductType,
} from "../../../../validators"
} from "../../../validators"
import { BatchMethodRequest } from "@medusajs/types"
import { refetchBatchVariants, remapVariantResponse } from "../../../../helpers"
import { refetchBatchVariants, remapVariantResponse } from "../../../helpers"
export const POST = async (
req: AuthenticatedMedusaRequest<
@@ -2,14 +2,13 @@ import { batchProductsWorkflow } from "@medusajs/core-flows"
import {
AuthenticatedMedusaRequest,
MedusaResponse,
} from "../../../../../types/routing"
} from "../../../../types/routing"
import {
AdminBatchUpdateProductType,
AdminCreateProductType,
} from "../../validators"
} from "../validators"
import { BatchMethodRequest } from "@medusajs/types"
import { refetchBatchProducts, remapProductResponse } from "../../helpers"
import { CreateProductDTO, UpsertProductDTO } from "@medusajs/types"
import { refetchBatchProducts, remapProductResponse } from "../helpers"
export const POST = async (
req: AuthenticatedMedusaRequest<
@@ -1,6 +1,7 @@
import { MiddlewareRoute } from "../../../loaders/helpers/routing/types"
import { authenticate } from "../../../utils/authenticate-middleware"
import { maybeApplyLinkFilter } from "../../utils/maybe-apply-link-filter"
import { unlessPath } from "../../utils/unless-path"
import { validateAndTransformBody } from "../../utils/validate-body"
import { validateAndTransformQuery } from "../../utils/validate-query"
import { createBatchBody } from "../../utils/validators"
@@ -45,16 +46,6 @@ export const adminProductRoutesMiddlewares: MiddlewareRoute[] = [
maybeApplyPriceListsFilter(),
],
},
{
method: ["GET"],
matcher: "/admin/products/:id",
middlewares: [
validateAndTransformQuery(
AdminGetProductParams,
QueryConfig.retrieveProductQueryConfig
),
],
},
{
method: ["POST"],
matcher: "/admin/products",
@@ -68,7 +59,7 @@ export const adminProductRoutesMiddlewares: MiddlewareRoute[] = [
},
{
method: ["POST"],
matcher: "/admin/products/op/batch",
matcher: "/admin/products/batch",
middlewares: [
validateAndTransformBody(
createBatchBody(AdminCreateProduct, AdminBatchUpdateProduct)
@@ -79,14 +70,33 @@ export const adminProductRoutesMiddlewares: MiddlewareRoute[] = [
),
],
},
{
method: ["GET"],
matcher: "/admin/products/:id",
middlewares: [
unlessPath(
/.*\/products\/batch/,
validateAndTransformQuery(
AdminGetProductParams,
QueryConfig.retrieveProductQueryConfig
)
),
],
},
{
method: ["POST"],
matcher: "/admin/products/:id",
middlewares: [
validateAndTransformBody(AdminUpdateProduct),
validateAndTransformQuery(
AdminGetProductParams,
QueryConfig.retrieveProductQueryConfig
unlessPath(
/.*\/products\/batch/,
validateAndTransformBody(AdminUpdateProduct)
),
unlessPath(
/.*\/products\/batch/,
validateAndTransformQuery(
AdminGetProductParams,
QueryConfig.retrieveProductQueryConfig
)
),
],
},
@@ -94,13 +104,15 @@ export const adminProductRoutesMiddlewares: MiddlewareRoute[] = [
method: ["DELETE"],
matcher: "/admin/products/:id",
middlewares: [
validateAndTransformQuery(
AdminGetProductParams,
QueryConfig.retrieveProductQueryConfig
unlessPath(
/.*\/products\/batch/,
validateAndTransformQuery(
AdminGetProductParams,
QueryConfig.retrieveProductQueryConfig
)
),
],
},
{
method: ["GET"],
matcher: "/admin/products/:id/variants",
@@ -113,7 +125,18 @@ export const adminProductRoutesMiddlewares: MiddlewareRoute[] = [
},
{
method: ["POST"],
matcher: "/admin/products/:id/variants/op/batch",
matcher: "/admin/products/:id/variants",
middlewares: [
validateAndTransformBody(AdminCreateProductVariant),
validateAndTransformQuery(
AdminGetProductParams,
QueryConfig.retrieveProductQueryConfig
),
],
},
{
method: ["POST"],
matcher: "/admin/products/:id/variants/batch",
middlewares: [
validateAndTransformBody(
createBatchBody(
@@ -132,20 +155,12 @@ export const adminProductRoutesMiddlewares: MiddlewareRoute[] = [
method: ["GET"],
matcher: "/admin/products/:id/variants/:variant_id",
middlewares: [
validateAndTransformQuery(
AdminGetProductVariantParams,
QueryConfig.retrieveVariantConfig
),
],
},
{
method: ["POST"],
matcher: "/admin/products/:id/variants",
middlewares: [
validateAndTransformBody(AdminCreateProductVariant),
validateAndTransformQuery(
AdminGetProductParams,
QueryConfig.retrieveProductQueryConfig
unlessPath(
/.*\/variants\/batch/,
validateAndTransformQuery(
AdminGetProductVariantParams,
QueryConfig.retrieveVariantConfig
)
),
],
},
@@ -153,10 +168,16 @@ export const adminProductRoutesMiddlewares: MiddlewareRoute[] = [
method: ["POST"],
matcher: "/admin/products/:id/variants/:variant_id",
middlewares: [
validateAndTransformBody(AdminUpdateProductVariant),
validateAndTransformQuery(
AdminGetProductParams,
QueryConfig.retrieveProductQueryConfig
unlessPath(
/.*\/variants\/batch/,
validateAndTransformBody(AdminUpdateProductVariant)
),
unlessPath(
/.*\/variants\/batch/,
validateAndTransformQuery(
AdminGetProductParams,
QueryConfig.retrieveProductQueryConfig
)
),
],
},
@@ -164,9 +185,12 @@ export const adminProductRoutesMiddlewares: MiddlewareRoute[] = [
method: ["DELETE"],
matcher: "/admin/products/:id/variants/:variant_id",
middlewares: [
validateAndTransformQuery(
AdminGetProductParams,
QueryConfig.retrieveProductQueryConfig
unlessPath(
/.*\/variants\/batch/,
validateAndTransformQuery(
AdminGetProductParams,
QueryConfig.retrieveProductQueryConfig
)
),
],
},
@@ -8,7 +8,6 @@ export async function zodValidator<T>(
body: T
): Promise<z.ZodRawShape> {
try {
zodSchema
return await zodSchema.parseAsync(body)
} catch (err) {
if (err instanceof ZodError) {
@@ -11,6 +11,13 @@ export const createBatchBody = (
})
}
export const createLinkBody = () => {
return z.object({
add: z.array(z.string()).optional(),
remove: z.array(z.string()).optional(),
})
}
export const createSelectParams = () => {
return z.object({
fields: z.string().optional(),