Skip to content

Commit

Permalink
Merge branch 'develop' into feat/workflow-step-context
Browse files Browse the repository at this point in the history
  • Loading branch information
carlos-r-l-rodrigues authored Mar 20, 2024
2 parents a4d05d6 + 20243e2 commit f1549be
Show file tree
Hide file tree
Showing 51 changed files with 1,426 additions and 2,061 deletions.
6 changes: 6 additions & 0 deletions .changeset/calm-spoons-look.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@medusajs/core-flows": minor
"@medusajs/medusa": minor
---

Align the v2 product HTTP endpoints to follow conventions
5 changes: 5 additions & 0 deletions .changeset/slow-plants-clean.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@medusajs/utils": patch
---

feat(utils): autogenerates create and update methods when dto is provided
256 changes: 133 additions & 123 deletions integration-tests/api/__tests__/admin/product.js

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,6 @@ export const createVariantPriceSet = async ({
})

return await pricingModuleService.retrieve(priceSet.id, {
relations: ["money_amounts"],
relations: ["price_set_money_amounts.money_amount"],
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ export const deletePriceListsStep = createStep(
ModuleRegistrationName.PRICING
)

// TODO: Implement soft delete price lists
await pricingModule.deletePriceLists(ids)
await pricingModule.softDeletePriceLists(ids)

return new StepResponse(void 0, ids)
},
Expand All @@ -24,7 +23,6 @@ export const deletePriceListsStep = createStep(
ModuleRegistrationName.PRICING
)

// TODO: Implement restore price lists
// await pricingModule.restorePriceLists(idsToRestore)
await pricingModule.restorePriceLists(idsToRestore)
}
)
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,24 @@ export const removePriceListPricesStep = createStep(
{ relations: ["price_list"] }
)

await pricingModule.removePrices(psmas.map((psma) => psma.id))
await pricingModule.softDeletePriceSetMoneyAmounts(
psmas.map((psma) => psma.id)
)

return new StepResponse(
null,
psmas.map((psma) => psma.id)
)
},
async (ids, { container }) => {
if (!ids) {
if (!ids?.length) {
return
}

const pricingModule = container.resolve<IPricingModuleService>(
ModuleRegistrationName.PRICING
)

// TODO: This needs to be implemented
// pricingModule.restorePrices(ids)
await pricingModule.restorePriceSetMoneyAmounts(ids)
}
)
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Modules } from "@medusajs/modules-sdk"
import { ILinkModule } from "@medusajs/types"
import { ContainerRegistrationKeys } from "@medusajs/utils"
import { StepResponse, createStep } from "@medusajs/workflows-sdk"

Expand All @@ -11,39 +10,24 @@ export const removeVariantPricingLinkStepId = "remove-variant-pricing-link"
export const removeVariantPricingLinkStep = createStep(
removeVariantPricingLinkStepId,
async (data: StepInput, { container }) => {
const remoteLink = container.resolve(ContainerRegistrationKeys.REMOTE_LINK)
const linkModule: ILinkModule = remoteLink.getLinkModule(
Modules.PRODUCT,
"variant_id",
Modules.PRICING,
"price_set_id"
)

const links = (await linkModule.list(
{
variant_id: data.variant_ids,
},
{ select: ["id", "variant_id", "price_set_id"] }
)) as { id: string; variant_id: string; price_set_id: string }[]
if (!data.variant_ids.length) {
return
}

await remoteLink.delete(links.map((link) => link.id))
return new StepResponse(void 0, links)
const remoteLink = container.resolve(ContainerRegistrationKeys.REMOTE_LINK)
await remoteLink.delete({
[Modules.PRODUCT]: { variant_id: data.variant_ids },
})
return new StepResponse(void 0, data.variant_ids)
},
async (prevData, { container }) => {
if (!prevData?.length) {
return
}

const remoteLink = container.resolve(ContainerRegistrationKeys.REMOTE_LINK)
await remoteLink.create(
prevData.map((entry) => ({
[Modules.PRODUCT]: {
variant_id: entry.variant_id,
},
[Modules.PRICING]: {
price_set_id: entry.price_set_id,
},
}))
)
await remoteLink.restore({
[Modules.PRODUCT]: { variant_id: prevData },
})
}
)
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ export const deleteProductVariantsWorkflowId = "delete-product-variants"
export const deleteProductVariantsWorkflow = createWorkflow(
deleteProductVariantsWorkflowId,
(input: WorkflowData<WorkflowInput>): WorkflowData<void> => {
// Question: Should we also remove the price set manually, or would that be cascaded?
removeVariantPricingLinkStep({ variant_ids: input.ids })
return deleteProductVariantsStep(input.ids)
}
Expand Down
3 changes: 0 additions & 3 deletions packages/core-flows/src/product/workflows/delete-products.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,7 @@ export const deleteProductsWorkflow = createWorkflow(
.map((variant) => variant.id)
})

// Question: Should we also remove the price set manually, or would that be cascaded?
// Question: Since we soft-delete the product, how do we restore the product with the prices and the links?
removeVariantPricingLinkStep({ variant_ids: variantsToBeDeleted })

return deleteProductsStep(input.ids)
}
)
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import {
updateProductOptionsWorkflow,
} from "@medusajs/core-flows"

import { UpdateProductDTO } from "@medusajs/types"
import { remoteQueryObjectFromString } from "@medusajs/utils"
import { UpdateProductOptionDTO } from "../../../../../../../../types/dist"
import { refetchProduct, remapProduct } from "../../../helpers"

export const GET = async (
req: AuthenticatedMedusaRequest,
Expand Down Expand Up @@ -51,7 +51,12 @@ export const POST = async (
throw errors[0].error
}

res.status(200).json({ product_option: result[0] })
const product = await refetchProduct(
productId,
req.scope,
req.remoteQueryConfig.fields
)
res.status(200).json({ product: remapProduct(product) })
}

export const DELETE = async (
Expand All @@ -71,9 +76,16 @@ export const DELETE = async (
throw errors[0].error
}

const product = await refetchProduct(
productId,
req.scope,
req.remoteQueryConfig.fields
)

res.status(200).json({
id: optionId,
object: "product_option",
deleted: true,
parent: product,
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
import { CreateProductOptionDTO } from "@medusajs/types"
import { createProductOptionsWorkflow } from "@medusajs/core-flows"
import { remoteQueryObjectFromString } from "@medusajs/utils"
import { refetchProduct, remapProduct } from "../../helpers"

export const GET = async (
req: AuthenticatedMedusaRequest,
Expand Down Expand Up @@ -56,5 +57,10 @@ export const POST = async (
throw errors[0].error
}

res.status(200).json({ product_option: result[0] })
const product = await refetchProduct(
productId,
req.scope,
req.remoteQueryConfig.fields
)
res.status(200).json({ product: remapProduct(product) })
}
9 changes: 7 additions & 2 deletions packages/medusa/src/api-v2/admin/products/[id]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {

import { UpdateProductDTO } from "@medusajs/types"
import { remoteQueryObjectFromString } from "@medusajs/utils"
import { remapKeysForProduct, remapProduct } from "../helpers"
import { refetchProduct, remapKeysForProduct, remapProduct } from "../helpers"

export const GET = async (
req: AuthenticatedMedusaRequest,
Expand Down Expand Up @@ -47,7 +47,12 @@ export const POST = async (
throw errors[0].error
}

res.status(200).json({ product: remapProduct(result[0]) })
const product = await refetchProduct(
result[0].id,
req.scope,
req.remoteQueryConfig.fields
)
res.status(200).json({ product: remapProduct(product) })
}

export const DELETE = async (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@ import {
} from "@medusajs/core-flows"

import { UpdateProductVariantDTO } from "@medusajs/types"
import { defaultAdminProductsVariantFields } from "../../../query-config"
import { remoteQueryObjectFromString } from "@medusajs/utils"
import { remapKeysForVariant, remapVariant } from "../../../helpers"
import {
refetchProduct,
remapKeysForVariant,
remapProduct,
remapVariant,
} from "../../../helpers"

export const GET = async (
req: AuthenticatedMedusaRequest,
Expand Down Expand Up @@ -56,7 +60,12 @@ export const POST = async (
throw errors[0].error
}

res.status(200).json({ variant: remapVariant(result[0]) })
const product = await refetchProduct(
productId,
req.scope,
req.remoteQueryConfig.fields
)
res.status(200).json({ product: remapProduct(product) })
}

export const DELETE = async (
Expand All @@ -77,9 +86,16 @@ export const DELETE = async (
throw errors[0].error
}

const product = await refetchProduct(
productId,
req.scope,
req.remoteQueryConfig.fields
)

res.status(200).json({
id: variantId,
object: "variant",
deleted: true,
parent: product,
})
}
19 changes: 7 additions & 12 deletions packages/medusa/src/api-v2/admin/products/[id]/variants/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { CreateProductVariantDTO } from "@medusajs/types"
import { createProductVariantsWorkflow } from "@medusajs/core-flows"
import { remoteQueryObjectFromString } from "@medusajs/utils"
import {
remapKeysForProduct,
refetchProduct,
remapKeysForVariant,
remapProduct,
remapVariant,
Expand Down Expand Up @@ -64,15 +64,10 @@ export const POST = async (
throw errors[0].error
}

const remoteQuery = req.scope.resolve("remoteQuery")
const queryObject = remoteQueryObjectFromString({
entryPoint: "product",
variables: {
filters: { id: productId },
},
fields: remapKeysForProduct(req.remoteQueryConfig.fields ?? []),
})

const products = await remoteQuery(queryObject)
res.status(200).json({ product: remapProduct(products[0]) })
const product = await refetchProduct(
productId,
req.scope,
req.remoteQueryConfig.fields
)
res.status(200).json({ product: remapProduct(product) })
}
49 changes: 40 additions & 9 deletions packages/medusa/src/api-v2/admin/products/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,40 @@
import { ProductDTO, ProductVariantDTO } from "@medusajs/types"
import { MedusaContainer, ProductDTO, ProductVariantDTO } from "@medusajs/types"
import { remoteQueryObjectFromString } from "@medusajs/utils"

const isPricing = (fieldName: string) =>
fieldName.startsWith("variants.prices") ||
fieldName.startsWith("*variants.prices") ||
fieldName.startsWith("prices") ||
fieldName.startsWith("*prices")

// The variant had prices before, but that is not part of the price_set money amounts. Do we remap the request and response or not?
export const remapKeysForProduct = (selectFields: string[]) => {
const productFields = selectFields.filter(
(fieldName: string) => !fieldName.startsWith("variants.prices")
(fieldName: string) => !isPricing(fieldName)
)
const pricingFields = selectFields
.filter((fieldName: string) => fieldName.startsWith("variants.prices"))
.filter((fieldName: string) => isPricing(fieldName))
.map((fieldName: string) =>
fieldName.replace("variants.prices.", "variants.price_set.money_amounts.")
fieldName.replace(
"variants.prices.",
"variants.price_set.price_set_money_amounts.money_amount."
)
)

return [...productFields, ...pricingFields]
}

export const remapKeysForVariant = (selectFields: string[]) => {
const variantFields = selectFields.filter(
(fieldName: string) => !fieldName.startsWith("prices")
(fieldName: string) => !isPricing(fieldName)
)
const pricingFields = selectFields
.filter((fieldName: string) => fieldName.startsWith("prices"))
.filter((fieldName: string) => isPricing(fieldName))
.map((fieldName: string) =>
fieldName.replace("prices.", "price_set.money_amounts.")
fieldName.replace(
"prices.",
"price_set.price_set_money_amounts.money_amount."
)
)

return [...variantFields, ...pricingFields]
Expand All @@ -37,10 +50,28 @@ export const remapProduct = (p: ProductDTO) => {
export const remapVariant = (v: ProductVariantDTO) => {
return {
...v,
prices: (v as any).price_set?.money_amounts?.map((ma) => ({
...ma,
prices: (v as any).price_set?.price_set_money_amounts?.map((psma) => ({
...psma.money_amount,
variant_id: v.id,
})),
price_set: undefined,
}
}

export const refetchProduct = async (
productId: string,
scope: MedusaContainer,
fields: string[]
) => {
const remoteQuery = scope.resolve("remoteQuery")
const queryObject = remoteQueryObjectFromString({
entryPoint: "product",
variables: {
filters: { id: productId },
},
fields: remapKeysForProduct(fields ?? []),
})

const products = await remoteQuery(queryObject)
return products[0]
}
Loading

0 comments on commit f1549be

Please sign in to comment.