From 38611fb18f25b61414ff1d58e62717402f217605 Mon Sep 17 00:00:00 2001 From: Drayke Date: Tue, 23 Mar 2021 09:35:27 +0100 Subject: [PATCH] feat(core): Enable population of relational custom fields from CSV --- .../e2e/__snapshots__/import.e2e-spec.ts.snap | 12 +++++++++ packages/core/e2e/fixtures/product-import.csv | 22 ++++++++-------- packages/core/e2e/import.e2e-spec.ts | 25 ++++++++++++++++--- .../providers/import-parser/import-parser.ts | 11 +++++++- 4 files changed, 55 insertions(+), 15 deletions(-) diff --git a/packages/core/e2e/__snapshots__/import.e2e-spec.ts.snap b/packages/core/e2e/__snapshots__/import.e2e-spec.ts.snap index 913f82a1f6..8b98cb9482 100644 --- a/packages/core/e2e/__snapshots__/import.e2e-spec.ts.snap +++ b/packages/core/e2e/__snapshots__/import.e2e-spec.ts.snap @@ -17,6 +17,9 @@ Object { }, ], "customFields": Object { + "owner": Object { + "id": "T_1", + }, "pageType": "default", }, "description": "A great device for stretching paper.", @@ -111,6 +114,9 @@ exports[`Import resolver imports products 2`] = ` Object { "assets": Array [], "customFields": Object { + "owner": Object { + "id": "T_1", + }, "pageType": "expanded", }, "description": "Mabef description", @@ -154,6 +160,9 @@ exports[`Import resolver imports products 3`] = ` Object { "assets": Array [], "customFields": Object { + "owner": Object { + "id": "T_1", + }, "pageType": "default", }, "description": "Really mega pencils", @@ -241,6 +250,9 @@ exports[`Import resolver imports products 4`] = ` Object { "assets": Array [], "customFields": Object { + "owner": Object { + "id": "T_1", + }, "pageType": "default", }, "description": "Keeps the paint off the clothes", diff --git a/packages/core/e2e/fixtures/product-import.csv b/packages/core/e2e/fixtures/product-import.csv index 10ffc0208c..1be2a60dff 100644 --- a/packages/core/e2e/fixtures/product-import.csv +++ b/packages/core/e2e/fixtures/product-import.csv @@ -1,12 +1,12 @@ -name , slug , description , assets , facets , optionGroups , optionValues , sku , price , taxCategory , stockOnHand , trackInventory , variantAssets , variantFacets , product:pageType , variant:weight -Perfect Paper Stretcher , perfect-paper-stretcher , A great device for stretching paper. , "pps1.jpg|pps2.jpg" , , size , Half Imperial , PPS12 , 45.3 , standard , 0 , false , , Brand:KB|Type:Accessory , default , 100 - , , , , , , Quarter Imperial , PPS14 , 32.5 , standard , 0 , false , , Brand:KB|Type:Accessory , , 100 - , , , , , , Full Imperial , PPSF , 59.5 , standard , -10 , false , , Brand:KB|Type:Accessory , , 100 -Mabef M/02 Studio Easel , , Mabef description , , , , , M02 , 910.7 , standard , 100 , false , , Brand:Mabef|Type:Easel , expanded , 300 -Giotto Mega Pencils , , Really mega pencils , , , box size , Box of 8 , 225400 , 4.16 , standard , , false , "box-of-8.jpg" , Collection:Xmas Sale , default , 200 - , , , , , , Box of 12 , 225600 , 6.24 , standard , , false , "box-of-12.jpg" , Collection:Xmas Sale , , 200 +name , slug , description , assets , facets , optionGroups , optionValues , sku , price , taxCategory , stockOnHand , trackInventory , variantAssets , variantFacets , product:pageType , variant:weight,product:owner +Perfect Paper Stretcher , perfect-paper-stretcher , A great device for stretching paper. , "pps1.jpg|pps2.jpg" , , size , Half Imperial , PPS12 , 45.3 , standard , 0 , false , , Brand:KB|Type:Accessory , default , 100,"{""id"": 1}" + , , , , , , Quarter Imperial , PPS14 , 32.5 , standard , 0 , false , , Brand:KB|Type:Accessory , , 100,"{""id"": 1}" + , , , , , , Full Imperial , PPSF , 59.5 , standard , -10 , false , , Brand:KB|Type:Accessory , , 100,"{""id"": 1}" +Mabef M/02 Studio Easel , , Mabef description , , , , , M02 , 910.7 , standard , 100 , false , , Brand:Mabef|Type:Easel , expanded , 300,"{""id"": 1}" +Giotto Mega Pencils , , Really mega pencils , , , box size , Box of 8 , 225400 , 4.16 , standard , , false , "box-of-8.jpg" , Collection:Xmas Sale , default , 200,"{""id"": 1}" + , , , , , , Box of 12 , 225600 , 6.24 , standard , , false , "box-of-12.jpg" , Collection:Xmas Sale , , 200,"{""id"": 1}" -Artists Smock , , Keeps the paint off the clothes , , Material:Denim|Collection:clothes , "size|colour" , "small|beige" , 10112 , 11.99 , reduced , , false , , , default , 500 - , , , , , , "large|beige" , 10113 , 11.99 , reduced , , false , , , default , 500 - , , , , , , "small|navy" , 10114 , 11.99 , reduced , , false , , , default , 500 - , , , , , , "large|navy" , 10115 , 11.99 , reduced , , false , , , default , 500 +Artists Smock , , Keeps the paint off the clothes , , Material:Denim|Collection:clothes , "size|colour" , "small|beige" , 10112 , 11.99 , reduced , , false , , , default , 500,"{""id"": 1}" + , , , , , , "large|beige" , 10113 , 11.99 , reduced , , false , , , default , 500,"{""id"": 1}" + , , , , , , "small|navy" , 10114 , 11.99 , reduced , , false , , , default , 500,"{""id"": 1}" + , , , , , , "large|navy" , 10115 , 11.99 , reduced , , false , , , default , 500,"{""id"": 1}" diff --git a/packages/core/e2e/import.e2e-spec.ts b/packages/core/e2e/import.e2e-spec.ts index 14e88d668c..c56aa5b81f 100644 --- a/packages/core/e2e/import.e2e-spec.ts +++ b/packages/core/e2e/import.e2e-spec.ts @@ -1,16 +1,27 @@ import { omit } from '@vendure/common/lib/omit'; +import { User } from '@vendure/core'; import { createTestEnvironment } from '@vendure/testing'; import gql from 'graphql-tag'; import path from 'path'; import { initialData } from '../../../e2e-common/e2e-initial-data'; -import { TEST_SETUP_TIMEOUT_MS, testConfig } from '../../../e2e-common/test-config'; +import { testConfig, TEST_SETUP_TIMEOUT_MS } from '../../../e2e-common/test-config'; describe('Import resolver', () => { const { server, adminClient } = createTestEnvironment({ ...testConfig, customFields: { - Product: [{ type: 'string', name: 'pageType' }], + Product: [ + { type: 'string', name: 'pageType' }, + { + name: 'owner', + public: true, + nullable: true, + type: 'relation', + entity: User, + eager: true, + }, + ], ProductVariant: [{ type: 'int', name: 'weight' }], }, }); @@ -58,7 +69,7 @@ describe('Import resolver', () => { }); expect(result.importProducts.errors).toEqual([ - 'Invalid Record Length: header length is 16, got 1 on line 8', + 'Invalid Record Length: header length is 17, got 1 on line 8', ]); expect(result.importProducts.imported).toBe(4); expect(result.importProducts.processed).toBe(4); @@ -100,6 +111,9 @@ describe('Import resolver', () => { } customFields { pageType + owner { + id + } } variants { id @@ -201,5 +215,10 @@ describe('Import resolver', () => { expect(smock.variants[1].options.map(byCode).sort()).toEqual(['beige', 'large']); expect(smock.variants[2].options.map(byCode).sort()).toEqual(['navy', 'small']); expect(smock.variants[3].options.map(byCode).sort()).toEqual(['large', 'navy']); + + expect(paperStretcher.customFields.owner.id).toBe('T_1'); + expect(easel.customFields.owner.id).toBe('T_1'); + expect(pencils.customFields.owner.id).toBe('T_1'); + expect(smock.customFields.owner.id).toBe('T_1'); }, 20000); }); diff --git a/packages/core/src/data-import/providers/import-parser/import-parser.ts b/packages/core/src/data-import/providers/import-parser/import-parser.ts index 75c6b40118..81b2b86b1d 100644 --- a/packages/core/src/data-import/providers/import-parser/import-parser.ts +++ b/packages/core/src/data-import/providers/import-parser/import-parser.ts @@ -267,6 +267,15 @@ function parseVariantFromRecord(r: RawProductRecord): ParsedProductVariant { }; } +function isRelationObject(value: string) { + try { + const parsed = JSON.parse(value); + return parsed && parsed.hasOwnProperty('id'); + } catch(e) { + return false; + } +} + function parseCustomFields(prefix: 'product' | 'variant', r: RawProductRecord): { [name: string]: string } { return Object.entries(r) .filter(([key, value]) => { @@ -276,7 +285,7 @@ function parseCustomFields(prefix: 'product' | 'variant', r: RawProductRecord): const fieldName = key.replace(`${prefix}:`, ''); return { ...output, - [fieldName]: value, + [fieldName]: isRelationObject(value) ? JSON.parse(value) : value, }; }, {}); }