diff --git a/packages/core/utils/src/product/__tests__/csv-normalizer.spec.ts b/packages/core/utils/src/product/__tests__/csv-normalizer.spec.ts index 03aec2c18e..d6112d6fc5 100644 --- a/packages/core/utils/src/product/__tests__/csv-normalizer.spec.ts +++ b/packages/core/utils/src/product/__tests__/csv-normalizer.spec.ts @@ -1101,6 +1101,40 @@ describe("CSV processor", () => { `) }) + describe("Variant Metadata column", () => { + it("should process variant metadata as JSON correctly", () => { + const csvRow = { + "Product Handle": "test-product", + "Variant Title": "Test Variant", + "Variant Metadata": '{ "key": "value", "number": 123 }', + } + + const normalized = CSVNormalizer.preProcess(csvRow, 1) + const processor = new CSVNormalizer([normalized]) + const result = processor.proccess() + + expect(result.toCreate["test-product"].variants[0].metadata).toEqual({ + key: "value", + number: 123, + }) + }) + + it("should throw an error for invalid JSON in variant metadata", () => { + const csvRow = { + "Product Handle": "test-product", + "Variant Title": "Test Variant", + "Variant Metadata": 'invalid json', + } + + const normalized = CSVNormalizer.preProcess(csvRow, 1) + const processor = new CSVNormalizer([normalized]) + + expect(() => processor.proccess()).toThrow( + 'Row 1: Invalid value provided for "variant metadata". Expected a valid JSON string, received "invalid json"' + ) + }) + }) + describe("System-generated columns", () => { it("should ignore product timestamp columns during import", () => { const csvRow: Record = { diff --git a/packages/core/utils/src/product/csv-normalizer.ts b/packages/core/utils/src/product/csv-normalizer.ts index 65f49c9f6a..b3fc4e1283 100644 --- a/packages/core/utils/src/product/csv-normalizer.ts +++ b/packages/core/utils/src/product/csv-normalizer.ts @@ -79,6 +79,28 @@ function processAsString( } } +/** + * Process a column value as a json object + */ +function processAsJson( + inputKey: string, + outputKey: keyof Output +): ColumnProcessor { + return (csvRow, _, rowNumber, output) => { + const value = csvRow[inputKey] + if (isPresent(value)) { + if (typeof value === 'string') { + try { + output[outputKey] = JSON.parse(value); + } catch (error) { + throw createError(rowNumber, `Invalid value provided for "${inputKey}". Expected a valid JSON string, received "${value}"`); + } + } + } + return undefined + } +} + /** * Processes a column value but ignores it (no-op processor for system-generated fields) */ @@ -193,7 +215,7 @@ const productStaticColumns: { ), "product weight": processAsNumber("product weight", "weight"), "product width": processAsNumber("product width", "width"), - "product metadata": processAsString("product metadata", "metadata"), + "product metadata": processAsJson("product metadata", "metadata"), "shipping profile id": processAsString( "shipping profile id", "shipping_profile_id" @@ -257,7 +279,7 @@ const variantStaticColumns: { "variant height": processAsNumber("variant height", "height"), "variant length": processAsNumber("variant length", "length"), "variant material": processAsString("variant material", "material"), - "variant metadata": processAsString("variant metadata", "metadata"), + "variant metadata": processAsJson("variant metadata", "metadata"), "variant origin country": processAsString( "variant origin country", "origin_country"