fix(utils,core-flows): fix import erasing tags, categories and others (#13724)

* fix(utils,core-flows): fix import erasins tags, categories and others

* Create pink-pumpkins-sin.md

* fix changeset

* fix tests
This commit is contained in:
William Bouchard
2025-10-14 08:08:20 -04:00
committed by GitHub
parent b5ecdfcd12
commit a61d1825ea
3 changed files with 32 additions and 35 deletions

View File

@@ -0,0 +1,6 @@
---
"@medusajs/core-flows": patch
"@medusajs/utils": patch
---
fix(utils,core-flows): fix import erasing tags, categories and others

View File

@@ -26,7 +26,6 @@ describe("CSV processor", () => {
{
"toCreate": {
"sweatshirt": {
"categories": [],
"description": "Reimagine the feeling of a classic sweatshirt. With our cotton sweatshirt, everyday essentials no longer have to be ordinary.",
"discountable": true,
"handle": "sweatshirt",
@@ -52,7 +51,6 @@ describe("CSV processor", () => {
},
],
"status": "published",
"tags": [],
"thumbnail": "https://medusa-public-images.s3.eu-west-1.amazonaws.com/sweatshirt-vintage-front.png",
"title": "Medusa Sweatshirt",
"variants": [
@@ -99,7 +97,6 @@ describe("CSV processor", () => {
{
"toCreate": {
"sweatshirt": {
"categories": [],
"description": "Reimagine the feeling of a classic sweatshirt. With our cotton sweatshirt, everyday essentials no longer have to be ordinary.",
"discountable": true,
"handle": "sweatshirt",
@@ -127,7 +124,6 @@ describe("CSV processor", () => {
},
],
"status": "published",
"tags": [],
"thumbnail": "https://medusa-public-images.s3.eu-west-1.amazonaws.com/sweatshirt-vintage-front.png",
"title": "Medusa Sweatshirt",
"variants": [
@@ -216,7 +212,6 @@ describe("CSV processor", () => {
{
"toCreate": {
"sweatshirt": {
"categories": [],
"description": "Reimagine the feeling of a classic sweatshirt. With our cotton sweatshirt, everyday essentials no longer have to be ordinary.",
"discountable": true,
"handle": "sweatshirt",
@@ -251,7 +246,6 @@ describe("CSV processor", () => {
},
],
"status": "published",
"tags": [],
"thumbnail": "https://medusa-public-images.s3.eu-west-1.amazonaws.com/sweatshirt-vintage-front.png",
"title": "Medusa Sweatshirt",
"variants": [
@@ -343,7 +337,6 @@ describe("CSV processor", () => {
{
"toCreate": {
"shorts": {
"categories": [],
"description": "Reimagine the feeling of classic shorts. With our cotton shorts, everyday essentials no longer have to be ordinary.",
"discountable": true,
"handle": "shorts",
@@ -372,7 +365,6 @@ describe("CSV processor", () => {
},
],
"status": "published",
"tags": [],
"thumbnail": "https://medusa-public-images.s3.eu-west-1.amazonaws.com/shorts-vintage-front.png",
"title": "Medusa Shorts",
"variants": [
@@ -464,7 +456,6 @@ describe("CSV processor", () => {
"weight": 400,
},
"sweatpants": {
"categories": [],
"description": "Reimagine the feeling of classic sweatpants. With our cotton sweatpants, everyday essentials no longer have to be ordinary.",
"discountable": true,
"handle": "sweatpants",
@@ -493,7 +484,6 @@ describe("CSV processor", () => {
},
],
"status": "published",
"tags": [],
"thumbnail": "https://medusa-public-images.s3.eu-west-1.amazonaws.com/sweatpants-gray-front.png",
"title": "Medusa Sweatpants",
"variants": [
@@ -585,7 +575,6 @@ describe("CSV processor", () => {
"weight": 400,
},
"t-shirt": {
"categories": [],
"description": "Reimagine the feeling of a classic T-shirt. With our cotton T-shirts, everyday essentials no longer have to be ordinary.",
"discountable": true,
"handle": "t-shirt",
@@ -627,7 +616,6 @@ describe("CSV processor", () => {
},
],
"status": "published",
"tags": [],
"thumbnail": "https://medusa-public-images.s3.eu-west-1.amazonaws.com/tee-black-front.png",
"title": "Medusa T-Shirt",
"variants": [
@@ -813,7 +801,6 @@ describe("CSV processor", () => {
},
"toUpdate": {
"prod_01JSXX3ZVW4M4RS0NH4MSWCQWA": {
"categories": [],
"description": "Reimagine the feeling of a classic sweatshirt. With our cotton sweatshirt, everyday essentials no longer have to be ordinary.",
"discountable": true,
"handle": "sweatshirt",
@@ -843,7 +830,6 @@ describe("CSV processor", () => {
},
],
"status": "published",
"tags": [],
"thumbnail": "https://medusa-public-images.s3.eu-west-1.amazonaws.com/sweatshirt-vintage-front.png",
"title": "Medusa Sweatshirt",
"variants": [
@@ -935,7 +921,6 @@ describe("CSV processor", () => {
"weight": 400,
},
"prod_01JT598HEWAE555V0A6BD602MG": {
"categories": [],
"description": "Every programmer's best friend.",
"discountable": true,
"handle": "coffee-mug-v3",
@@ -955,7 +940,6 @@ describe("CSV processor", () => {
],
"sales_channels": [],
"status": "published",
"tags": [],
"thumbnail": "https://medusa-public-images.s3.eu-west-1.amazonaws.com/coffee-mug.png",
"title": "Medusa Coffee Mug",
"variants": [
@@ -983,7 +967,6 @@ describe("CSV processor", () => {
"weight": 400,
},
"prod_01JT598HEX26EHDG7SRK37Q3FG": {
"categories": [],
"description": "Reimagine the feeling of classic sweatpants. With our cotton sweatpants, everyday essentials no longer have to be ordinary.",
"discountable": true,
"handle": "sweatpants-v2",
@@ -1009,7 +992,6 @@ describe("CSV processor", () => {
],
"sales_channels": [],
"status": "published",
"tags": [],
"thumbnail": "https://medusa-public-images.s3.eu-west-1.amazonaws.com/sweatpants-gray-front.png",
"title": "Medusa Sweatpants",
"variants": [
@@ -1123,7 +1105,7 @@ describe("CSV processor", () => {
const csvRow = {
"Product Handle": "test-product",
"Variant Title": "Test Variant",
"Variant Metadata": 'invalid json',
"Variant Metadata": "invalid json",
}
const normalized = CSVNormalizer.preProcess(csvRow, 1)
@@ -1158,12 +1140,12 @@ describe("CSV processor", () => {
// Should be in toCreate since we only have handle
expect(result.toCreate["test-product"]).toBeDefined()
expect(result.toCreate["test-product"].is_giftcard).toBe(true)
// Timestamp fields should not be in the output since they're ignored
expect(result.toCreate["test-product"]["created_at"]).toBeUndefined()
expect(result.toCreate["test-product"]["updated_at"]).toBeUndefined()
expect(result.toCreate["test-product"]["deleted_at"]).toBeUndefined()
// Verify that the timestamp fields are present in normalized data but ignored during processing
expect(normalized["product created at"]).toBe("")
expect(normalized["product updated at"]).toBe("")
@@ -1194,17 +1176,17 @@ describe("CSV processor", () => {
// Should be in toCreate since we only have handle
expect(result.toCreate["test-product"]).toBeDefined()
expect(result.toCreate["test-product"].variants).toHaveLength(1)
const variant = result.toCreate["test-product"].variants[0]
expect(variant.title).toBe("Test Variant")
expect(variant.sku).toBe("TEST-SKU")
// Timestamp fields should not be in the variant output since they're ignored
expect(variant["created_at"]).toBeUndefined()
expect(variant["updated_at"]).toBeUndefined()
expect(variant["deleted_at"]).toBeUndefined()
expect(variant["product_id"]).toBeUndefined()
// Verify that the timestamp fields are present in normalized data but ignored during processing
expect(normalized["variant created at"]).toBe("")
expect(normalized["variant updated at"]).toBe("")
@@ -1259,7 +1241,9 @@ describe("CSV processor", () => {
const processor = new CSVNormalizer([normalized])
const result = processor.proccess()
expect(result.toCreate[`test-product-${value}`].is_giftcard).toBe(expected)
expect(result.toCreate[`test-product-${value}`].is_giftcard).toBe(
expected
)
})
})
})

View File

@@ -1,9 +1,9 @@
import {
isPresent,
tryConvertToNumber,
tryConvertToBoolean,
MedusaError,
normalizeCSVValue,
tryConvertToBoolean,
tryConvertToNumber,
} from "../common"
import { AdminCreateProduct, AdminCreateProductVariant } from "@medusajs/types"
@@ -89,11 +89,14 @@ function processAsJson<Output>(
return (csvRow, _, rowNumber, output) => {
const value = csvRow[inputKey]
if (isPresent(value)) {
if (typeof value === 'string') {
if (typeof value === "string") {
try {
output[outputKey] = JSON.parse(value);
output[outputKey] = JSON.parse(value)
} catch (error) {
throw createError(rowNumber, `Invalid value provided for "${inputKey}". Expected a valid JSON string, received "${value}"`);
throw createError(
rowNumber,
`Invalid value provided for "${inputKey}". Expected a valid JSON string, received "${value}"`
)
}
}
}
@@ -164,17 +167,21 @@ function processAsCounterValue<Output extends Record<string, any[]>>(
outputKey: keyof Output
): ColumnProcessor<Output> {
return (csvRow, rowColumns, _, output) => {
output[outputKey] = output[outputKey] ?? []
const existingIds = output[outputKey].map((item) => item[arrayItemKey])
const matchingColumns = rowColumns.filter((rowKey) => inputMatcher.test(rowKey))
rowColumns
.filter((rowKey) => inputMatcher.test(rowKey))
.forEach((rowKey) => {
// Only initialize the array if there are matching columns in the CSV
if (matchingColumns.length > 0) {
output[outputKey] = output[outputKey] ?? []
const existingIds = output[outputKey].map((item) => item[arrayItemKey])
matchingColumns.forEach((rowKey) => {
const value = csvRow[rowKey]
if (!existingIds.includes(value) && isPresent(value)) {
output[outputKey].push({ [arrayItemKey]: value })
}
})
}
}
}