fix(medusa): Allow deleting metadata fields (#3055)
This commit is contained in:
1 parent
6481b0c357
commit
fcba705701
4 files changed
+57
-3
No files matched your search
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@medusajs/medusa": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix(medusa): Allow users to unset metadata fields in updates.
|
||||||
@@ -1334,6 +1334,37 @@ describe("/admin/products", () => {
|
|||||||
expect(response.data.product.images.length).toEqual(0)
|
expect(response.data.product.images.length).toEqual(0)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("updates a product by deleting a field from metadata", async () => {
|
||||||
|
const api = useApi()
|
||||||
|
|
||||||
|
const product = await simpleProductFactory(dbConnection, {
|
||||||
|
metadata: {
|
||||||
|
"test-key": "test-value",
|
||||||
|
"test-key-2": "test-value-2",
|
||||||
|
"test-key-3": "test-value-3",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const payload = {
|
||||||
|
metadata: {
|
||||||
|
"test-key": "",
|
||||||
|
"test-key-2": null,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await api.post(
|
||||||
|
"/admin/products/" + product.id,
|
||||||
|
payload,
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(response.status).toEqual(200)
|
||||||
|
expect(response.data.product.metadata).toEqual({
|
||||||
|
"test-key-2": null,
|
||||||
|
"test-key-3": "test-value-3",
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
it("fails to update product with invalid status", async () => {
|
it("fails to update product with invalid status", async () => {
|
||||||
const api = useApi()
|
const api = useApi()
|
||||||
|
|
||||||
|
|||||||
@@ -5,17 +5,17 @@ import {
|
|||||||
ProductType,
|
ProductType,
|
||||||
ShippingProfile,
|
ShippingProfile,
|
||||||
ShippingProfileType,
|
ShippingProfileType,
|
||||||
Store
|
Store,
|
||||||
} from "@medusajs/medusa"
|
} from "@medusajs/medusa"
|
||||||
import faker from "faker"
|
import faker from "faker"
|
||||||
import { Connection } from "typeorm"
|
import { Connection } from "typeorm"
|
||||||
import {
|
import {
|
||||||
ProductVariantFactoryData,
|
ProductVariantFactoryData,
|
||||||
simpleProductVariantFactory
|
simpleProductVariantFactory,
|
||||||
} from "./simple-product-variant-factory"
|
} from "./simple-product-variant-factory"
|
||||||
import {
|
import {
|
||||||
SalesChannelFactoryData,
|
SalesChannelFactoryData,
|
||||||
simpleSalesChannelFactory
|
simpleSalesChannelFactory,
|
||||||
} from "./simple-sales-channel-factory"
|
} from "./simple-sales-channel-factory"
|
||||||
|
|
||||||
export type ProductFactoryData = {
|
export type ProductFactoryData = {
|
||||||
@@ -28,6 +28,7 @@ export type ProductFactoryData = {
|
|||||||
options?: { id: string; title: string }[]
|
options?: { id: string; title: string }[]
|
||||||
variants?: ProductVariantFactoryData[]
|
variants?: ProductVariantFactoryData[]
|
||||||
sales_channels?: SalesChannelFactoryData[]
|
sales_channels?: SalesChannelFactoryData[]
|
||||||
|
metadata?: Record<string, unknown>
|
||||||
}
|
}
|
||||||
|
|
||||||
export const simpleProductFactory = async (
|
export const simpleProductFactory = async (
|
||||||
@@ -83,6 +84,7 @@ export const simpleProductFactory = async (
|
|||||||
discountable: !data.is_giftcard,
|
discountable: !data.is_giftcard,
|
||||||
tags: [] as ProductTag[],
|
tags: [] as ProductTag[],
|
||||||
profile_id: data.is_giftcard ? gcProfile?.id : defaultProfile?.id,
|
profile_id: data.is_giftcard ? gcProfile?.id : defaultProfile?.id,
|
||||||
|
metadata: data.metadata || null,
|
||||||
} as Product
|
} as Product
|
||||||
|
|
||||||
if (typeof data.tags !== "undefined") {
|
if (typeof data.tags !== "undefined") {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ export function setMetadata(
|
|||||||
): Record<string, unknown> {
|
): Record<string, unknown> {
|
||||||
const existing = obj.metadata || {}
|
const existing = obj.metadata || {}
|
||||||
const newData = {}
|
const newData = {}
|
||||||
|
|
||||||
for (const [key, value] of Object.entries(metadata)) {
|
for (const [key, value] of Object.entries(metadata)) {
|
||||||
if (typeof key !== "string") {
|
if (typeof key !== "string") {
|
||||||
throw new MedusaError(
|
throw new MedusaError(
|
||||||
@@ -19,6 +20,21 @@ export function setMetadata(
|
|||||||
"Key type is invalid. Metadata keys must be strings"
|
"Key type is invalid. Metadata keys must be strings"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We reserve the empty string as a way to delete a key.
|
||||||
|
* If the value is an empty string, we don't
|
||||||
|
* set it, and if it exists in the existing metadata, we
|
||||||
|
* unset the field.
|
||||||
|
*/
|
||||||
|
if (value === "") {
|
||||||
|
if (key in existing) {
|
||||||
|
delete existing[key]
|
||||||
|
}
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
newData[key] = value
|
newData[key] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user