feat(medusa): Add product isolation FF to update cart (#5168)
**What** Update cart must use the remote query when being in product isolation mode. This pr is a first iteration that aims to quickly make compatible the end point in isolation. In a future iteration, this end point will be migrated to a workflow Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
27d74cb399
commit
dfa5d041c9
6
.changeset/moody-cycles-explain.md
Normal file
6
.changeset/moody-cycles-explain.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@medusajs/medusa": patch
|
||||
"@medusajs/modules-sdk": patch
|
||||
---
|
||||
|
||||
Feat/update cart product isolation
|
||||
@@ -15,6 +15,7 @@ import { AddressPayload } from "../../../../types/common"
|
||||
import { FeatureFlagDecorators } from "../../../../utils/feature-flag-decorators"
|
||||
import { IsType } from "../../../../utils/validators/is-type"
|
||||
import { cleanResponseData } from "../../../../utils/clean-response-data"
|
||||
import IsolateProductDomainFeatureFlag from "../../../../loaders/feature-flags/isolate-product-domain"
|
||||
|
||||
/**
|
||||
* @oas [post] /store/carts/{id}
|
||||
@@ -75,14 +76,22 @@ export default async (req, res) => {
|
||||
const validated = req.validatedBody as StorePostCartsCartReq
|
||||
|
||||
const cartService: CartService = req.scope.resolve("cartService")
|
||||
const featureFlagRouter = req.scope.resolve("featureFlagRouter")
|
||||
const manager: EntityManager = req.scope.resolve("manager")
|
||||
|
||||
if (req.user?.customer_id) {
|
||||
validated.customer_id = req.user.customer_id
|
||||
}
|
||||
|
||||
let cart
|
||||
if (featureFlagRouter.isFeatureEnabled(IsolateProductDomainFeatureFlag.key)) {
|
||||
cart = await retrieveCartWithIsolatedProductModule(req, id)
|
||||
}
|
||||
|
||||
await manager.transaction(async (transactionManager) => {
|
||||
await cartService.withTransaction(transactionManager).update(id, validated)
|
||||
await cartService
|
||||
.withTransaction(transactionManager)
|
||||
.update(cart ?? id, validated)
|
||||
|
||||
const updated = await cartService
|
||||
.withTransaction(transactionManager)
|
||||
@@ -101,9 +110,60 @@ export default async (req, res) => {
|
||||
select: defaultStoreCartFields,
|
||||
relations: defaultStoreCartRelations,
|
||||
})
|
||||
|
||||
res.json({ cart: cleanResponseData(data, []) })
|
||||
}
|
||||
|
||||
async function retrieveCartWithIsolatedProductModule(req, id: string) {
|
||||
const cartService = req.scope.resolve("cartService")
|
||||
const remoteQuery = req.scope.resolve("remoteQuery")
|
||||
|
||||
const relations = [
|
||||
"items",
|
||||
"shipping_methods",
|
||||
"shipping_methods.shipping_option",
|
||||
"shipping_address",
|
||||
"billing_address",
|
||||
"gift_cards",
|
||||
"customer",
|
||||
"region",
|
||||
"payment_sessions",
|
||||
"region.countries",
|
||||
"discounts",
|
||||
"discounts.rule",
|
||||
]
|
||||
|
||||
const cart = await cartService.retrieve(id, {
|
||||
relations,
|
||||
})
|
||||
|
||||
const products = await remoteQuery({
|
||||
products: {
|
||||
__args: {
|
||||
id: cart.items.map((i) => i.product_id),
|
||||
},
|
||||
fields: ["id"],
|
||||
variants: {
|
||||
fields: ["id"],
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const variantsMap = new Map(
|
||||
products.flatMap((p) => p.variants).map((v) => [v.id, v])
|
||||
)
|
||||
|
||||
cart.items.forEach((item) => {
|
||||
if (!item.variant_id) {
|
||||
return
|
||||
}
|
||||
|
||||
item.variant = variantsMap.get(item.variant_id)
|
||||
})
|
||||
|
||||
return cart
|
||||
}
|
||||
|
||||
class GiftCard {
|
||||
@IsString()
|
||||
code: string
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { FlagRouter } from "@medusajs/utils"
|
||||
import { isEmpty, isEqual } from "lodash"
|
||||
import { MedusaError, isDefined } from "medusa-core-utils"
|
||||
import { isDefined, MedusaError } from "medusa-core-utils"
|
||||
import { DeepPartial, EntityManager, In, IsNull, Not } from "typeorm"
|
||||
import {
|
||||
CustomShippingOptionService,
|
||||
CustomerService,
|
||||
CustomShippingOptionService,
|
||||
DiscountService,
|
||||
EventBusService,
|
||||
GiftCardService,
|
||||
@@ -29,8 +29,8 @@ import SalesChannelFeatureFlag from "../loaders/feature-flags/sales-channels"
|
||||
import {
|
||||
Address,
|
||||
Cart,
|
||||
CustomShippingOption,
|
||||
Customer,
|
||||
CustomShippingOption,
|
||||
Discount,
|
||||
DiscountRule,
|
||||
DiscountRuleType,
|
||||
@@ -49,9 +49,9 @@ import {
|
||||
CartCreateProps,
|
||||
CartUpdateProps,
|
||||
FilterableCartProps,
|
||||
isCart,
|
||||
LineItemUpdate,
|
||||
LineItemValidateData,
|
||||
isCart,
|
||||
} from "../types/cart"
|
||||
import {
|
||||
AddressPayload,
|
||||
@@ -1098,7 +1098,7 @@ class CartService extends TransactionBaseService {
|
||||
}
|
||||
}
|
||||
|
||||
async update(cartId: string, data: CartUpdateProps): Promise<Cart> {
|
||||
async update(cartOrId: string | Cart, data: CartUpdateProps): Promise<Cart> {
|
||||
return await this.atomicPhase_(
|
||||
async (transactionManager: EntityManager) => {
|
||||
const cartRepo = transactionManager.withRepository(this.cartRepository_)
|
||||
@@ -1117,9 +1117,11 @@ class CartService extends TransactionBaseService {
|
||||
"discounts.rule",
|
||||
]
|
||||
|
||||
const cart = await this.retrieve(cartId, {
|
||||
relations,
|
||||
})
|
||||
const cart = !isString(cartOrId)
|
||||
? cartOrId
|
||||
: await this.retrieve(cartOrId, {
|
||||
relations,
|
||||
})
|
||||
|
||||
const originalCartCustomer = { ...(cart.customer ?? {}) }
|
||||
if (data.customer_id) {
|
||||
|
||||
@@ -12,8 +12,8 @@ import {
|
||||
} from "@medusajs/types"
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
ModulesSdkUtils,
|
||||
isObject,
|
||||
ModulesSdkUtils,
|
||||
} from "@medusajs/utils"
|
||||
import { MODULE_PACKAGE_NAMES, Modules } from "./definitions"
|
||||
import { MedusaModule } from "./medusa-module"
|
||||
@@ -69,7 +69,7 @@ export async function MedusaApp({
|
||||
modules: Record<string, LoadedModule | LoadedModule[]>
|
||||
link: RemoteLink | undefined
|
||||
query: (
|
||||
query: string | RemoteJoinerQuery,
|
||||
query: string | RemoteJoinerQuery | object,
|
||||
variables?: Record<string, unknown>
|
||||
) => Promise<any>
|
||||
}> {
|
||||
@@ -152,7 +152,7 @@ export async function MedusaApp({
|
||||
|
||||
let link: RemoteLink | undefined = undefined
|
||||
let query: (
|
||||
query: string | RemoteJoinerQuery,
|
||||
query: string | RemoteJoinerQuery | object,
|
||||
variables?: Record<string, unknown>
|
||||
) => Promise<any>
|
||||
|
||||
@@ -172,7 +172,7 @@ export async function MedusaApp({
|
||||
customRemoteFetchData: remoteFetchData,
|
||||
})
|
||||
query = async (
|
||||
query: string | RemoteJoinerQuery,
|
||||
query: string | RemoteJoinerQuery | object,
|
||||
variables?: Record<string, unknown>
|
||||
) => {
|
||||
return await remoteQuery.query(query, variables)
|
||||
|
||||
Reference in New Issue
Block a user