diff --git a/packages/integrations/.eslintrc.js b/packages/integrations/.eslintrc.js index 53c9c4f..d9d440f 100644 --- a/packages/integrations/.eslintrc.js +++ b/packages/integrations/.eslintrc.js @@ -8,7 +8,7 @@ module.exports = { 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', indent: ['error', 4], quotes: ['error', 'single'], - semi: 0, + semi: ['error', 'always'], 'no-extra-semi': 0, 'comma-dangle': ['error', 'always-multiline'], // Reasoning behind using dangling commas -> https://github.com/airbnb/javascript#commas--dangling 'no-useless-constructor': 'off', @@ -20,8 +20,7 @@ module.exports = { 'space-before-function-paren': ['error', 'never'], }, parser: '@typescript-eslint/parser', - parserOptions: { - + parserOptions: { 'ecmaVersion': 'latest', 'sourceType': 'module', }, diff --git a/packages/integrations/src/builders/products/productUpdateBuilder.ts b/packages/integrations/src/builders/products/productUpdateBuilder.ts index 6e03046..82f8073 100644 --- a/packages/integrations/src/builders/products/productUpdateBuilder.ts +++ b/packages/integrations/src/builders/products/productUpdateBuilder.ts @@ -1,4 +1,4 @@ -import { Product, MultilingualDataValue, DataValue, ProductVariant, CategoryPath, MultiCurrencyDataValue, Brand, ProductUpdate } from '@relewise/client'; +import { Product, DataValue, ProductVariant, CategoryPath, Brand, ProductUpdate } from '@relewise/client'; export class ProductUpdateBuilder { private product: Product; @@ -22,14 +22,19 @@ export class ProductUpdateBuilder { this.brandUpdateKind = brandUpdateKind; } - displayName(name: MultilingualDataValue): this { - this.product.displayName = name.value; + displayName(values: { + value: string; + language: string; + }[]): this { + this.product.displayName = { + values: values.map(x => ({ text: x.value, language: { value: x.language } })), + }; return this; } - data(data: Record): this { - this.product.data = data; + data(data: Record): this { + this.product.data = data as Record; // TODO remove dirty hack return this; } @@ -52,14 +57,20 @@ export class ProductUpdateBuilder { return this; } - listPrice(listPrice: MultiCurrencyDataValue): this { - this.product.listPrice = listPrice.value; + listPrice(values: { + amount: number; + currency: string; + }[]): this { + this.product.listPrice = { values: values.map(x => ({ amount: x.amount, currency: { value: x.currency } })) }; return this; } - salesPrice(salesPrice: MultiCurrencyDataValue): this { - this.product.salesPrice = salesPrice.value; + salesPrice(values: { + amount: number; + currency: string; + }[]): this { + this.product.salesPrice = { values: values.map(x => ({ amount: x.amount, currency: { value: x.currency } })) }; return this; } diff --git a/packages/integrations/src/builders/products/productVariantBuilder.ts b/packages/integrations/src/builders/products/productVariantBuilder.ts index 7f08050..01f6d75 100644 --- a/packages/integrations/src/builders/products/productVariantBuilder.ts +++ b/packages/integrations/src/builders/products/productVariantBuilder.ts @@ -1,4 +1,4 @@ -import { MultilingualDataValue, DataValue, ProductVariant, MultiCurrencyDataValue } from '@relewise/client'; +import { DataValue, ProductVariant } from '@relewise/client'; export class ProductVariantBuilder { private variant: ProductVariant; @@ -9,14 +9,19 @@ export class ProductVariantBuilder { this.variant = { id: id }; } - displayName(name: MultilingualDataValue): this { - this.variant.displayName = name.value; + displayName(values: { + value: string; + language: string; + }[]): this { + this.variant.displayName = { + values: values.map(x => ({ text: x.value, language: { value: x.language } })), + }; return this; } - data(data: Record): this { - this.variant.data = data; + data(data: Record): this { + this.variant.data = data as Record; // TODO remove dirty hack return this; } @@ -27,14 +32,20 @@ export class ProductVariantBuilder { return this; } - listPrice(listPrice: MultiCurrencyDataValue): this { - this.variant.listPrice = listPrice.value; + listPrice(values: { + amount: number; + currency: string; + }[]): this { + this.variant.listPrice = { values: values.map(x => ({ amount: x.amount, currency: { value: x.currency } })) }; return this; } - salesPrice(salesPrice: MultiCurrencyDataValue): this { - this.variant.salesPrice = salesPrice.value; + salesPrice(values: { + amount: number; + currency: string; + }[]): this { + this.variant.salesPrice = { values: values.map(x => ({ amount: x.amount, currency: { value: x.currency } })) }; return this; } diff --git a/packages/integrations/src/example.ts b/packages/integrations/src/example.ts index 612a8f2..75c8031 100644 --- a/packages/integrations/src/example.ts +++ b/packages/integrations/src/example.ts @@ -13,7 +13,7 @@ async function example() { integrator.batchSize = 5; - await integrator.updateProduct(product.build()) + await integrator.updateProduct(product.build()); const enable = new ProductAdministrativeActionBuilder({ language: null, @@ -42,11 +42,12 @@ function createProduct(id: string, unix: number) { id: id, productUpdateKind: 'ReplaceProvidedProperties', }) - .displayName(DataValueFactory.multilingual([{ language: 'da', value: 'product navn' }])) + .displayName([{ language: 'da', value: 'product navn' }]) .data({ 'ProductType': DataValueFactory.string('Bluse'), 'Description': DataValueFactory.string('Flot blÄ bluse som er top nice'), 'UnixTimeStamp': DataValueFactory.number(unix), + 'Removed': null, }) - .salesPrice(DataValueFactory.multiCurrency([{ currency: 'DKK', amount: 499.95 }])); + .salesPrice([{ currency: 'DKK', amount: 499.95 }]); } \ No newline at end of file diff --git a/packages/integrations/src/integrator.ts b/packages/integrations/src/integrator.ts index b345db0..e838d1b 100644 --- a/packages/integrations/src/integrator.ts +++ b/packages/integrations/src/integrator.ts @@ -22,7 +22,7 @@ export class Integrator extends RelewiseClient { return this.request( 'TrackProductAdministrativeActionRequest', { - $type: 'Relewise.Client.Requests.Tracking.ProductAdministrativeAction, Relewise.Client', + $type: 'Relewise.Client.Requests.Tracking.TrackProductAdministrativeActionRequest, Relewise.Client', administrativeAction: request, }, options); diff --git a/packages/integrations/tests/integration-tests/products/updates.integration.test.ts b/packages/integrations/tests/integration-tests/products/updates.integration.test.ts new file mode 100644 index 0000000..55b5248 --- /dev/null +++ b/packages/integrations/tests/integration-tests/products/updates.integration.test.ts @@ -0,0 +1,85 @@ +import { test, expect } from '@jest/globals'; +import { Integrator, ProductAdministrativeActionBuilder, ProductUpdateBuilder } from '../../../src'; +import { DataValueFactory } from '@relewise/client'; +const { npm_config_API_KEY: API_KEY, npm_config_DATASET_ID: DATASET_ID, npm_config_SERVER_URL: SERVER_URL } = process.env; + +const integrator = new Integrator(DATASET_ID!, API_KEY!, { serverUrl: SERVER_URL }); + +const unixTimeStamp: number = Date.now(); + +test('Create Product', async() => { + const product = new ProductUpdateBuilder({ + id: '1234', + productUpdateKind: 'ReplaceProvidedProperties', + variantUpdateKind: 'ReplaceProvidedProperties', + }) + .displayName([ + { language: 'da', value: 'Toaster' }, + ]) + .data({ + 'UnixTimestamp': DataValueFactory.number(unixTimeStamp), + 'Description': DataValueFactory.string('Really nice product'), + 'Tags': DataValueFactory.stringCollection(['fall collection', 'blue', 'good-deal']), + 'InStock': DataValueFactory.boolean(true), + }) + .assortments([1, 2, 3]) + .brand({ id: '1', displayName: 'Relewise' }) + .listPrice([{ amount: 100, currency: 'DKK' }]) + .salesPrice([{ amount: 50, currency: 'DKK' }]); + + await integrator.updateProduct(product.build()); + + const enable = new ProductAdministrativeActionBuilder({ + filters: (f) => f.addProductDataFilter('UnixTimeStamp', c => c.addEqualsCondition(DataValueFactory.number(unixTimeStamp))), + productUpdateKind: 'Enable', + }); + integrator.productAdministrativeAction(enable.build()); + + const disable = new ProductAdministrativeActionBuilder({ + filters: (f) => f.addProductDataFilter('UnixTimeStamp', c => c.addEqualsCondition(DataValueFactory.number(unixTimeStamp), /* negated: */ true)), + productUpdateKind: 'Disable', + }); + integrator.productAdministrativeAction(disable.build()); +}); + +test('Batch create products', async() => { + const product = new ProductUpdateBuilder({ + id: '1234', + productUpdateKind: 'ReplaceProvidedProperties', + variantUpdateKind: 'ReplaceProvidedProperties', + }) + .displayName([ + { language: 'da', value: 'Toaster' }, + ]) + .data({ + 'UnixTimestamp': DataValueFactory.number(unixTimeStamp), + 'Description': DataValueFactory.string('Really nice product'), + 'Tags': DataValueFactory.stringCollection(['fall collection', 'blue', 'good-deal']), + 'InStock': DataValueFactory.boolean(true), + }) + .assortments([1, 2, 3]) + .brand({ id: '1', displayName: 'Relewise' }) + .listPrice([{ amount: 100, currency: 'DKK' }]) + .salesPrice([{ amount: 50, currency: 'DKK' }]); + + const product2 = new ProductUpdateBuilder({ + id: '4321', + productUpdateKind: 'ReplaceProvidedProperties', + variantUpdateKind: 'ReplaceProvidedProperties', + }) + .displayName([ + { language: 'da', value: 'Laptop' }, + ]) + .data({ + 'UnixTimestamp': DataValueFactory.number(unixTimeStamp), + 'Description': DataValueFactory.string('Really nice product'), + 'Tags': DataValueFactory.stringCollection(['fall collection', 'blue', 'good-deal']), + 'InStock': DataValueFactory.boolean(true), + }) + .assortments([1, 2, 3]) + .brand({ id: '1', displayName: 'Relewise' }) + .listPrice([{ amount: 100, currency: 'DKK' }]) + .salesPrice([{ amount: 50, currency: 'DKK' }]); + + await integrator.batch([product.build(), product2.build()]); +}); \ No newline at end of file