@unchainedshop/core 4.0.0-rc.14 → 4.0.0-rc.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/bulk-importer/createBulkImporter.d.ts +61 -0
- package/lib/bulk-importer/createBulkImporter.d.ts.map +1 -0
- package/lib/bulk-importer/createBulkImporter.js +135 -0
- package/lib/bulk-importer/createBulkImporter.js.map +1 -0
- package/lib/bulk-importer/handlers/assortment/create.d.ts +15 -0
- package/lib/bulk-importer/handlers/assortment/create.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/assortment/create.js +62 -0
- package/lib/bulk-importer/handlers/assortment/create.js.map +1 -0
- package/lib/bulk-importer/handlers/assortment/index.d.ts +4 -0
- package/lib/bulk-importer/handlers/assortment/index.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/assortment/index.js +4 -0
- package/lib/bulk-importer/handlers/assortment/index.js.map +1 -0
- package/lib/bulk-importer/handlers/assortment/remove.d.ts +12 -0
- package/lib/bulk-importer/handlers/assortment/remove.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/assortment/remove.js +13 -0
- package/lib/bulk-importer/handlers/assortment/remove.js.map +1 -0
- package/lib/bulk-importer/handlers/assortment/update.d.ts +16 -0
- package/lib/bulk-importer/handlers/assortment/update.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/assortment/update.js +62 -0
- package/lib/bulk-importer/handlers/assortment/update.js.map +1 -0
- package/lib/bulk-importer/handlers/assortment/upsertAssortmentChildren.d.ts +9 -0
- package/lib/bulk-importer/handlers/assortment/upsertAssortmentChildren.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/assortment/upsertAssortmentChildren.js +37 -0
- package/lib/bulk-importer/handlers/assortment/upsertAssortmentChildren.js.map +1 -0
- package/lib/bulk-importer/handlers/assortment/upsertAssortmentFilters.d.ts +9 -0
- package/lib/bulk-importer/handlers/assortment/upsertAssortmentFilters.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/assortment/upsertAssortmentFilters.js +32 -0
- package/lib/bulk-importer/handlers/assortment/upsertAssortmentFilters.js.map +1 -0
- package/lib/bulk-importer/handlers/assortment/upsertAssortmentProducts.d.ts +9 -0
- package/lib/bulk-importer/handlers/assortment/upsertAssortmentProducts.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/assortment/upsertAssortmentProducts.js +37 -0
- package/lib/bulk-importer/handlers/assortment/upsertAssortmentProducts.js.map +1 -0
- package/lib/bulk-importer/handlers/assortment/upsertMedia.d.ts +11 -0
- package/lib/bulk-importer/handlers/assortment/upsertMedia.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/assortment/upsertMedia.js +39 -0
- package/lib/bulk-importer/handlers/assortment/upsertMedia.js.map +1 -0
- package/lib/bulk-importer/handlers/filter/create.d.ts +13 -0
- package/lib/bulk-importer/handlers/filter/create.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/filter/create.js +58 -0
- package/lib/bulk-importer/handlers/filter/create.js.map +1 -0
- package/lib/bulk-importer/handlers/filter/index.d.ts +4 -0
- package/lib/bulk-importer/handlers/filter/index.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/filter/index.js +4 -0
- package/lib/bulk-importer/handlers/filter/index.js.map +1 -0
- package/lib/bulk-importer/handlers/filter/remove.d.ts +12 -0
- package/lib/bulk-importer/handlers/filter/remove.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/filter/remove.js +14 -0
- package/lib/bulk-importer/handlers/filter/remove.js.map +1 -0
- package/lib/bulk-importer/handlers/filter/update.d.ts +13 -0
- package/lib/bulk-importer/handlers/filter/update.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/filter/update.js +48 -0
- package/lib/bulk-importer/handlers/filter/update.js.map +1 -0
- package/lib/bulk-importer/handlers/product/create.d.ts +15 -0
- package/lib/bulk-importer/handlers/product/create.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/product/create.js +53 -0
- package/lib/bulk-importer/handlers/product/create.js.map +1 -0
- package/lib/bulk-importer/handlers/product/index.d.ts +4 -0
- package/lib/bulk-importer/handlers/product/index.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/product/index.js +4 -0
- package/lib/bulk-importer/handlers/product/index.js.map +1 -0
- package/lib/bulk-importer/handlers/product/remove.d.ts +14 -0
- package/lib/bulk-importer/handlers/product/remove.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/product/remove.js +13 -0
- package/lib/bulk-importer/handlers/product/remove.js.map +1 -0
- package/lib/bulk-importer/handlers/product/transformSpecificationToProductStructure.d.ts +3 -0
- package/lib/bulk-importer/handlers/product/transformSpecificationToProductStructure.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/product/transformSpecificationToProductStructure.js +16 -0
- package/lib/bulk-importer/handlers/product/transformSpecificationToProductStructure.js.map +1 -0
- package/lib/bulk-importer/handlers/product/update.d.ts +15 -0
- package/lib/bulk-importer/handlers/product/update.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/product/update.js +48 -0
- package/lib/bulk-importer/handlers/product/update.js.map +1 -0
- package/lib/bulk-importer/handlers/product/upsertMedia.d.ts +10 -0
- package/lib/bulk-importer/handlers/product/upsertMedia.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/product/upsertMedia.js +45 -0
- package/lib/bulk-importer/handlers/product/upsertMedia.js.map +1 -0
- package/lib/bulk-importer/handlers/product/upsertVariations.d.ts +8 -0
- package/lib/bulk-importer/handlers/product/upsertVariations.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/product/upsertVariations.js +48 -0
- package/lib/bulk-importer/handlers/product/upsertVariations.js.map +1 -0
- package/lib/bulk-importer/handlers/utils/convertTagsToLowerCase.d.ts +3 -0
- package/lib/bulk-importer/handlers/utils/convertTagsToLowerCase.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/utils/convertTagsToLowerCase.js +6 -0
- package/lib/bulk-importer/handlers/utils/convertTagsToLowerCase.js.map +1 -0
- package/lib/bulk-importer/upsertAsset.d.ts +12 -0
- package/lib/bulk-importer/upsertAsset.d.ts.map +1 -0
- package/lib/bulk-importer/upsertAsset.js +33 -0
- package/lib/bulk-importer/upsertAsset.js.map +1 -0
- package/lib/core-index.d.ts +7 -5
- package/lib/core-index.d.ts.map +1 -1
- package/lib/core-index.js +5 -1
- package/lib/core-index.js.map +1 -1
- package/lib/directors/FilterAdapter.d.ts +1 -1
- package/lib/directors/FilterAdapter.d.ts.map +1 -1
- package/lib/directors/FilterDirector.d.ts.map +1 -1
- package/lib/directors/FilterDirector.js +6 -7
- package/lib/directors/FilterDirector.js.map +1 -1
- package/lib/directors/PaymentDirector.js +2 -2
- package/lib/directors/PaymentDirector.js.map +1 -1
- package/lib/directors/WorkerAdapter.d.ts +3 -2
- package/lib/directors/WorkerAdapter.d.ts.map +1 -1
- package/lib/directors/WorkerAdapter.js.map +1 -1
- package/lib/factory/index.d.ts +3 -0
- package/lib/factory/index.d.ts.map +1 -0
- package/lib/factory/index.js +3 -0
- package/lib/factory/index.js.map +1 -0
- package/lib/factory/registerProductDiscoverabilityFilter copy.d.ts +5 -0
- package/lib/factory/registerProductDiscoverabilityFilter copy.d.ts.map +1 -0
- package/lib/factory/registerProductDiscoverabilityFilter copy.js +28 -0
- package/lib/factory/registerProductDiscoverabilityFilter copy.js.map +1 -0
- package/lib/factory/registerProductDiscoverabilityFilter.d.ts +5 -0
- package/lib/factory/registerProductDiscoverabilityFilter.d.ts.map +1 -0
- package/lib/factory/registerProductDiscoverabilityFilter.js +27 -0
- package/lib/factory/registerProductDiscoverabilityFilter.js.map +1 -0
- package/lib/modules.d.ts.map +1 -1
- package/lib/modules.js +1 -0
- package/lib/modules.js.map +1 -1
- package/lib/services/activateEnrollment.d.ts.map +1 -1
- package/lib/services/activateEnrollment.js +5 -9
- package/lib/services/activateEnrollment.js.map +1 -1
- package/lib/services/addMessage.d.ts +4 -0
- package/lib/services/addMessage.d.ts.map +1 -0
- package/lib/services/addMessage.js +15 -0
- package/lib/services/addMessage.js.map +1 -0
- package/lib/services/index.d.ts +4 -0
- package/lib/services/index.d.ts.map +1 -1
- package/lib/services/index.js +4 -0
- package/lib/services/index.js.map +1 -1
- package/lib/services/initCartProviders.d.ts.map +1 -1
- package/lib/services/initCartProviders.js +6 -2
- package/lib/services/initCartProviders.js.map +1 -1
- package/lib/services/initializeEnrollment.d.ts.map +1 -1
- package/lib/services/initializeEnrollment.js +5 -9
- package/lib/services/initializeEnrollment.js.map +1 -1
- package/lib/services/processQuotation.d.ts.map +1 -1
- package/lib/services/processQuotation.js +4 -8
- package/lib/services/processQuotation.js.map +1 -1
- package/lib/services/removeFiles.js +2 -2
- package/lib/services/removeFiles.js.map +1 -1
- package/lib/services/searchAssortments.d.ts.map +1 -1
- package/lib/services/searchAssortments.js +2 -1
- package/lib/services/searchAssortments.js.map +1 -1
- package/lib/services/searchProducts.d.ts.map +1 -1
- package/lib/services/searchProducts.js +2 -1
- package/lib/services/searchProducts.js.map +1 -1
- package/lib/services/terminateEnrollment.d.ts.map +1 -1
- package/lib/services/terminateEnrollment.js +5 -9
- package/lib/services/terminateEnrollment.js.map +1 -1
- package/lib/services/updateCalculation.d.ts.map +1 -1
- package/lib/services/updateCalculation.js +5 -3
- package/lib/services/updateCalculation.js.map +1 -1
- package/package.json +21 -20
- package/src/bulk-importer/createBulkImporter.ts +193 -0
- package/src/bulk-importer/handlers/assortment/create.ts +87 -0
- package/src/bulk-importer/handlers/assortment/index.ts +3 -0
- package/src/bulk-importer/handlers/assortment/remove.ts +15 -0
- package/src/bulk-importer/handlers/assortment/update.ts +89 -0
- package/src/bulk-importer/handlers/assortment/upsertAssortmentChildren.ts +52 -0
- package/src/bulk-importer/handlers/assortment/upsertAssortmentFilters.ts +42 -0
- package/src/bulk-importer/handlers/assortment/upsertAssortmentProducts.ts +50 -0
- package/src/bulk-importer/handlers/assortment/upsertMedia.ts +58 -0
- package/src/bulk-importer/handlers/filter/create.ts +76 -0
- package/src/bulk-importer/handlers/filter/index.ts +3 -0
- package/src/bulk-importer/handlers/filter/remove.ts +20 -0
- package/src/bulk-importer/handlers/filter/update.ts +67 -0
- package/src/bulk-importer/handlers/product/create.ts +70 -0
- package/src/bulk-importer/handlers/product/index.ts +3 -0
- package/src/bulk-importer/handlers/product/remove.ts +21 -0
- package/src/bulk-importer/handlers/product/transformSpecificationToProductStructure.ts +22 -0
- package/src/bulk-importer/handlers/product/update.ts +66 -0
- package/src/bulk-importer/handlers/product/upsertMedia.ts +64 -0
- package/src/bulk-importer/handlers/product/upsertVariations.ts +71 -0
- package/src/bulk-importer/handlers/utils/convertTagsToLowerCase.ts +4 -0
- package/src/bulk-importer/upsertAsset.ts +42 -0
- package/src/core-index.ts +11 -6
- package/src/directors/FilterAdapter.ts +1 -1
- package/src/directors/FilterDirector.ts +6 -7
- package/src/directors/PaymentDirector.ts +2 -2
- package/src/directors/WorkerAdapter.ts +8 -3
- package/src/factory/index.ts +3 -0
- package/src/factory/registerProductDiscoverabilityFilter.ts +36 -0
- package/src/modules.ts +1 -0
- package/src/services/activateEnrollment.ts +5 -9
- package/src/services/addMessage.ts +20 -0
- package/src/services/index.ts +4 -0
- package/src/services/initCartProviders.ts +6 -8
- package/src/services/initializeEnrollment.ts +5 -9
- package/src/services/processQuotation.ts +4 -8
- package/src/services/removeFiles.ts +2 -2
- package/src/services/searchAssortments.ts +2 -1
- package/src/services/searchProducts.ts +3 -1
- package/src/services/terminateEnrollment.ts +5 -9
- package/src/services/updateCalculation.ts +5 -3
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { Modules } from '../../../modules.js';
|
|
2
|
+
import createFilter from './create.js';
|
|
3
|
+
|
|
4
|
+
export default async function updateFilter(
|
|
5
|
+
payload: any,
|
|
6
|
+
{ logger, updateShouldUpsertIfIDNotExists }: { logger: any; updateShouldUpsertIfIDNotExists: boolean },
|
|
7
|
+
unchainedAPI: { modules: Modules },
|
|
8
|
+
) {
|
|
9
|
+
const { modules } = unchainedAPI;
|
|
10
|
+
const { specification, _id } = payload;
|
|
11
|
+
|
|
12
|
+
if (!(await modules.filters.filterExists({ filterId: _id }))) {
|
|
13
|
+
if (updateShouldUpsertIfIDNotExists) {
|
|
14
|
+
return createFilter(payload, { logger, createShouldUpsertIfIDExists: false }, unchainedAPI);
|
|
15
|
+
}
|
|
16
|
+
throw new Error(`Can't update non-existing filter ${_id}`);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const { content, options, ...filterData } = specification;
|
|
20
|
+
|
|
21
|
+
if (specification) {
|
|
22
|
+
logger.debug('update filter object', specification);
|
|
23
|
+
await modules.filters.update(_id, {
|
|
24
|
+
...filterData,
|
|
25
|
+
options: options?.map((option) => option.value) || [],
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (content) {
|
|
30
|
+
logger.debug('replace localized content for filter', content);
|
|
31
|
+
await modules.filters.texts.updateTexts(
|
|
32
|
+
{ filterId: _id },
|
|
33
|
+
Object.entries(content).map(([locale, localizedData]: [string, any]) => {
|
|
34
|
+
return {
|
|
35
|
+
locale,
|
|
36
|
+
...localizedData,
|
|
37
|
+
};
|
|
38
|
+
}),
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (options) {
|
|
43
|
+
logger.debug('replace localized content for filter options', content);
|
|
44
|
+
await Promise.all(
|
|
45
|
+
options.map(async ({ content: optionContent, value: optionValue }) => {
|
|
46
|
+
if (optionContent) {
|
|
47
|
+
await modules.filters.texts.updateTexts(
|
|
48
|
+
{ filterId: _id, filterOptionValue: optionValue },
|
|
49
|
+
Object.entries(optionContent).map(([locale, localizedData]: [string, any]) => {
|
|
50
|
+
return {
|
|
51
|
+
locale,
|
|
52
|
+
...localizedData,
|
|
53
|
+
};
|
|
54
|
+
}),
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
}),
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
entity: 'FILTER',
|
|
63
|
+
operation: 'update',
|
|
64
|
+
_id,
|
|
65
|
+
success: true,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { Modules } from '../../../modules.js';
|
|
2
|
+
import { Services } from '../../../services/index.js';
|
|
3
|
+
import upsertVariations from './upsertVariations.js';
|
|
4
|
+
import upsertMedia from './upsertMedia.js';
|
|
5
|
+
import transformSpecificationToProductStructure from './transformSpecificationToProductStructure.js';
|
|
6
|
+
|
|
7
|
+
export default async function createProduct(
|
|
8
|
+
payload: any,
|
|
9
|
+
{ logger, createShouldUpsertIfIDExists },
|
|
10
|
+
unchainedAPI: { modules: Modules; services: Services },
|
|
11
|
+
) {
|
|
12
|
+
const { modules } = unchainedAPI;
|
|
13
|
+
const { specification, media, variations, _id } = payload;
|
|
14
|
+
|
|
15
|
+
if (!specification) throw new Error(`Specification is required when creating new product ${_id}`);
|
|
16
|
+
|
|
17
|
+
if (!specification.content) throw new Error(`Content is required when creating new product ${_id}`);
|
|
18
|
+
|
|
19
|
+
const productData = transformSpecificationToProductStructure(specification);
|
|
20
|
+
logger.debug('create product object', productData);
|
|
21
|
+
try {
|
|
22
|
+
await modules.products.create({
|
|
23
|
+
...productData,
|
|
24
|
+
_id,
|
|
25
|
+
});
|
|
26
|
+
} catch (e) {
|
|
27
|
+
if (!createShouldUpsertIfIDExists) throw e;
|
|
28
|
+
|
|
29
|
+
logger.debug('entity already exists, falling back to update', specification);
|
|
30
|
+
await modules.products.update(_id, {
|
|
31
|
+
...productData,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (!(await modules.products.productExists({ productId: _id }))) {
|
|
36
|
+
throw new Error(`Can't create product ${_id}, fields missing?`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (specification.content) {
|
|
40
|
+
logger.debug('create localized content for product', specification.content);
|
|
41
|
+
await modules.products.texts.updateTexts(
|
|
42
|
+
_id,
|
|
43
|
+
Object.entries(specification.content).map(([locale, localizedData]: [string, any]) => {
|
|
44
|
+
return {
|
|
45
|
+
locale,
|
|
46
|
+
...localizedData,
|
|
47
|
+
};
|
|
48
|
+
}),
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
logger.debug('create product variations', variations);
|
|
53
|
+
await upsertVariations(
|
|
54
|
+
{
|
|
55
|
+
variations: variations || [],
|
|
56
|
+
productId: _id,
|
|
57
|
+
},
|
|
58
|
+
unchainedAPI,
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
logger.debug('create product media', media);
|
|
62
|
+
await upsertMedia({ media: media || [], productId: _id }, unchainedAPI);
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
entity: 'PRODUCT',
|
|
66
|
+
operation: 'create',
|
|
67
|
+
_id,
|
|
68
|
+
success: true,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Modules } from '../../../modules.js';
|
|
2
|
+
import { Services } from '../../../services/index.js';
|
|
3
|
+
|
|
4
|
+
export default async function removeProduct(
|
|
5
|
+
payload: any,
|
|
6
|
+
{ logger },
|
|
7
|
+
unchainedAPI: { modules: Modules; services: Services },
|
|
8
|
+
) {
|
|
9
|
+
const { services } = unchainedAPI;
|
|
10
|
+
const { _id } = payload;
|
|
11
|
+
logger.debug(`remove product ${_id}`);
|
|
12
|
+
|
|
13
|
+
await services.products.removeProduct({ productId: _id });
|
|
14
|
+
|
|
15
|
+
return {
|
|
16
|
+
entity: 'PRODUCT',
|
|
17
|
+
operation: 'remove',
|
|
18
|
+
_id,
|
|
19
|
+
success: true,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import convertTagsToLowerCase from '../utils/convertTagsToLowerCase.js';
|
|
2
|
+
|
|
3
|
+
export default (specification) => {
|
|
4
|
+
const {
|
|
5
|
+
variationResolvers: assignments,
|
|
6
|
+
content, // eslint-disable-line
|
|
7
|
+
warehousing: warehousingEmbeddedSupply,
|
|
8
|
+
...productData
|
|
9
|
+
} = specification;
|
|
10
|
+
|
|
11
|
+
const { dimensions: supply, ...warehousing } = warehousingEmbeddedSupply || {};
|
|
12
|
+
const tags = convertTagsToLowerCase(productData?.tags);
|
|
13
|
+
const proxy = assignments ? { assignments } : undefined;
|
|
14
|
+
|
|
15
|
+
return {
|
|
16
|
+
...productData,
|
|
17
|
+
tags,
|
|
18
|
+
warehousing,
|
|
19
|
+
supply,
|
|
20
|
+
proxy,
|
|
21
|
+
};
|
|
22
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { Modules } from '../../../modules.js';
|
|
2
|
+
import { Services } from '../../../services/index.js';
|
|
3
|
+
import upsertVariations from './upsertVariations.js';
|
|
4
|
+
import upsertMedia from './upsertMedia.js';
|
|
5
|
+
import transformSpecificationToProductStructure from './transformSpecificationToProductStructure.js';
|
|
6
|
+
import createProduct from './create.js';
|
|
7
|
+
|
|
8
|
+
export default async function updateProduct(
|
|
9
|
+
payload: any,
|
|
10
|
+
{ logger, updateShouldUpsertIfIDNotExists },
|
|
11
|
+
unchainedAPI: { modules: Modules; services: Services },
|
|
12
|
+
) {
|
|
13
|
+
const { modules } = unchainedAPI;
|
|
14
|
+
const { specification, media, variations, _id } = payload;
|
|
15
|
+
|
|
16
|
+
if (!(await modules.products.productExists({ productId: _id }))) {
|
|
17
|
+
if (updateShouldUpsertIfIDNotExists) {
|
|
18
|
+
return createProduct(payload, { logger, createShouldUpsertIfIDExists: false }, unchainedAPI);
|
|
19
|
+
}
|
|
20
|
+
throw new Error(`Can't update non-existing product ${_id}`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (specification) {
|
|
24
|
+
const productData = transformSpecificationToProductStructure(specification);
|
|
25
|
+
logger.debug('update product object', productData);
|
|
26
|
+
await modules.products.update(_id, {
|
|
27
|
+
...productData,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
if (specification.content) {
|
|
31
|
+
logger.debug('replace localized content for product', specification.content);
|
|
32
|
+
await modules.products.texts.updateTexts(
|
|
33
|
+
_id,
|
|
34
|
+
Object.entries(specification.content).map(([locale, localizedData]: [string, any]) => {
|
|
35
|
+
return {
|
|
36
|
+
locale,
|
|
37
|
+
...localizedData,
|
|
38
|
+
};
|
|
39
|
+
}),
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (variations) {
|
|
45
|
+
logger.debug('replace variations', variations);
|
|
46
|
+
await upsertVariations(
|
|
47
|
+
{
|
|
48
|
+
variations: variations || [],
|
|
49
|
+
productId: _id,
|
|
50
|
+
},
|
|
51
|
+
unchainedAPI,
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (media) {
|
|
56
|
+
logger.debug('replace product media', media);
|
|
57
|
+
await upsertMedia({ media, productId: _id }, unchainedAPI);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
entity: 'PRODUCT',
|
|
62
|
+
operation: 'update',
|
|
63
|
+
_id,
|
|
64
|
+
success: true,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { ProductMedia } from '@unchainedshop/core-products';
|
|
2
|
+
import { Modules } from '../../../modules.js';
|
|
3
|
+
import { Services } from '../../../services/index.js';
|
|
4
|
+
import convertTagsToLowerCase from '../utils/convertTagsToLowerCase.js';
|
|
5
|
+
import upsertAsset from '../../upsertAsset.js';
|
|
6
|
+
|
|
7
|
+
const upsertProductMedia = async (productMedia: ProductMedia, { modules }: { modules: Modules }) => {
|
|
8
|
+
try {
|
|
9
|
+
const productMediaObj = await modules.products.media.create(productMedia);
|
|
10
|
+
return productMediaObj;
|
|
11
|
+
} catch {
|
|
12
|
+
const { _id, ...productMediaData } = productMedia;
|
|
13
|
+
const productMediaId = _id;
|
|
14
|
+
return modules.products.media.update(productMediaId, productMediaData);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default async function upsertMedia(
|
|
19
|
+
{ media, productId },
|
|
20
|
+
unchainedAPI: { modules: Modules; services: Services },
|
|
21
|
+
) {
|
|
22
|
+
const { modules } = unchainedAPI;
|
|
23
|
+
|
|
24
|
+
const productMediaObjects = await Promise.all(
|
|
25
|
+
media.map(async ({ asset, content, ...mediaData }) => {
|
|
26
|
+
const tags = convertTagsToLowerCase(mediaData?.tags);
|
|
27
|
+
const file = await upsertAsset(
|
|
28
|
+
'product-media',
|
|
29
|
+
{ meta: { ...(asset.meta || {}), productId }, ...asset },
|
|
30
|
+
unchainedAPI,
|
|
31
|
+
);
|
|
32
|
+
if (!file) throw new Error(`Unable to create binary ${asset._id}`);
|
|
33
|
+
const fileId = file._id;
|
|
34
|
+
const productMedia = await upsertProductMedia(
|
|
35
|
+
{
|
|
36
|
+
...mediaData,
|
|
37
|
+
tags,
|
|
38
|
+
productId,
|
|
39
|
+
mediaId: file._id,
|
|
40
|
+
} as ProductMedia,
|
|
41
|
+
unchainedAPI,
|
|
42
|
+
);
|
|
43
|
+
if (!productMedia) throw new Error(`Unable to create product media object for file ${fileId}`);
|
|
44
|
+
|
|
45
|
+
if (content) {
|
|
46
|
+
await modules.products.media.texts.updateMediaTexts(
|
|
47
|
+
productMedia._id,
|
|
48
|
+
Object.entries(content).map(([locale, localizedData]: [string, any]) => {
|
|
49
|
+
return {
|
|
50
|
+
locale,
|
|
51
|
+
...localizedData,
|
|
52
|
+
};
|
|
53
|
+
}),
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
return productMedia;
|
|
57
|
+
}),
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
await modules.products.media.deleteMediaFiles({
|
|
61
|
+
productId,
|
|
62
|
+
excludedProductMediaIds: productMediaObjects.map((obj) => obj._id),
|
|
63
|
+
});
|
|
64
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { ProductVariation } from '@unchainedshop/core-products';
|
|
2
|
+
import { Modules } from '../../../modules.js';
|
|
3
|
+
|
|
4
|
+
const upsert = async (productVariation: ProductVariation, unchainedAPI: { modules: Modules }) => {
|
|
5
|
+
const { modules } = unchainedAPI;
|
|
6
|
+
try {
|
|
7
|
+
const newVariation = await modules.products.variations.create(productVariation);
|
|
8
|
+
return newVariation;
|
|
9
|
+
} catch {
|
|
10
|
+
return modules.products.variations.update(productVariation._id, productVariation);
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export default async function upsertVariations(
|
|
15
|
+
{ variations, productId },
|
|
16
|
+
unchainedAPI: { modules: Modules },
|
|
17
|
+
) {
|
|
18
|
+
const { modules } = unchainedAPI;
|
|
19
|
+
|
|
20
|
+
const upsertedProductVariationIds = await Promise.all(
|
|
21
|
+
variations.map(async ({ content, options, ...variationsRest }) => {
|
|
22
|
+
const variation = await upsert(
|
|
23
|
+
{
|
|
24
|
+
...variationsRest,
|
|
25
|
+
options: options.map((option) => option.value),
|
|
26
|
+
productId,
|
|
27
|
+
},
|
|
28
|
+
unchainedAPI,
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
await Promise.all(
|
|
32
|
+
options.map(async ({ content: optionContent, value: optionValue }) => {
|
|
33
|
+
if (optionContent) {
|
|
34
|
+
await modules.products.variations.texts.updateVariationTexts(
|
|
35
|
+
variation._id,
|
|
36
|
+
Object.entries(optionContent).map(([locale, localizedData]: [string, any]) => {
|
|
37
|
+
return {
|
|
38
|
+
locale,
|
|
39
|
+
...localizedData,
|
|
40
|
+
};
|
|
41
|
+
}),
|
|
42
|
+
optionValue,
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
}),
|
|
46
|
+
);
|
|
47
|
+
if (content) {
|
|
48
|
+
await modules.products.variations.texts.updateVariationTexts(
|
|
49
|
+
variation._id,
|
|
50
|
+
Object.entries(content).map(([locale, localizedData]: [string, any]) => {
|
|
51
|
+
return {
|
|
52
|
+
locale,
|
|
53
|
+
...localizedData,
|
|
54
|
+
};
|
|
55
|
+
}),
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
return variation._id;
|
|
59
|
+
}),
|
|
60
|
+
);
|
|
61
|
+
const allVariations = await modules.products.variations.findProductVariations({
|
|
62
|
+
productId,
|
|
63
|
+
});
|
|
64
|
+
await Promise.all(
|
|
65
|
+
allVariations.map(async (variation) => {
|
|
66
|
+
if (!upsertedProductVariationIds.includes(variation._id)) {
|
|
67
|
+
await modules.products.variations.delete(variation._id);
|
|
68
|
+
}
|
|
69
|
+
}),
|
|
70
|
+
);
|
|
71
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { File } from '@unchainedshop/core-files';
|
|
2
|
+
import { Modules } from '../modules.js';
|
|
3
|
+
import { Services } from '../services/index.js';
|
|
4
|
+
|
|
5
|
+
const upsertAsset = async (
|
|
6
|
+
directoryName: string,
|
|
7
|
+
asset: File & { fileName: string; headers?: Record<string, unknown> },
|
|
8
|
+
unchainedAPI: { modules: Modules; services: Services },
|
|
9
|
+
) => {
|
|
10
|
+
const { modules, services } = unchainedAPI;
|
|
11
|
+
const { _id: fileId, fileName, url, meta, headers, ...assetData } = asset;
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
const existingFile = fileId && (await modules.files.findFile({ fileId }));
|
|
15
|
+
if (existingFile) {
|
|
16
|
+
if (JSON.stringify(meta) === JSON.stringify(existingFile.meta)) {
|
|
17
|
+
return existingFile;
|
|
18
|
+
}
|
|
19
|
+
await modules.files.update(fileId, { meta, ...assetData });
|
|
20
|
+
const updatedFile = await modules.files.findFile({ fileId });
|
|
21
|
+
return updatedFile;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const assetObject = await services.files.uploadFileFromURL({
|
|
25
|
+
directoryName,
|
|
26
|
+
fileInput: {
|
|
27
|
+
fileLink: url,
|
|
28
|
+
fileName,
|
|
29
|
+
fileId,
|
|
30
|
+
headers,
|
|
31
|
+
},
|
|
32
|
+
meta,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
if (!assetObject) throw new Error('Media not created');
|
|
36
|
+
return assetObject;
|
|
37
|
+
} catch {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export default upsertAsset;
|
package/src/core-index.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { mongodb, MigrationRepository, ModuleInput } from '@unchainedshop/mongodb';
|
|
2
2
|
import initServices, { CustomServices, Services } from './services/index.js';
|
|
3
3
|
import initModules, { Modules, ModuleOptions } from './modules.js';
|
|
4
|
+
import createBulkImporterFactory, {
|
|
5
|
+
BulkImporter,
|
|
6
|
+
BulkImportHandler,
|
|
7
|
+
} from './bulk-importer/createBulkImporter.js';
|
|
4
8
|
|
|
5
9
|
import {
|
|
6
10
|
WorkerDirector,
|
|
@@ -18,17 +22,17 @@ import {
|
|
|
18
22
|
WarehousingDirector,
|
|
19
23
|
} from './directors/index.js';
|
|
20
24
|
|
|
25
|
+
export * from './bulk-importer/createBulkImporter.js';
|
|
21
26
|
export * from './services/index.js';
|
|
22
27
|
export * from './directors/index.js';
|
|
23
|
-
|
|
24
|
-
export interface BulkImporter {
|
|
25
|
-
createBulkImporter: (options: any) => any;
|
|
26
|
-
}
|
|
28
|
+
export * from './factory/index.js';
|
|
27
29
|
|
|
28
30
|
export interface UnchainedCoreOptions {
|
|
29
31
|
db: mongodb.Db;
|
|
30
32
|
migrationRepository: MigrationRepository<UnchainedCore>;
|
|
31
|
-
bulkImporter
|
|
33
|
+
bulkImporter?: {
|
|
34
|
+
handlers?: Record<string, BulkImportHandler<UnchainedCore>>;
|
|
35
|
+
};
|
|
32
36
|
modules?: Record<
|
|
33
37
|
string,
|
|
34
38
|
{
|
|
@@ -49,13 +53,14 @@ export interface UnchainedCore {
|
|
|
49
53
|
export const initCore = async ({
|
|
50
54
|
db,
|
|
51
55
|
migrationRepository,
|
|
52
|
-
bulkImporter,
|
|
56
|
+
bulkImporter: bulkImporterOptions = {},
|
|
53
57
|
modules: customModules = {},
|
|
54
58
|
services: customServices = {},
|
|
55
59
|
options = {},
|
|
56
60
|
}: UnchainedCoreOptions): Promise<UnchainedCore> => {
|
|
57
61
|
// Configure custom modules
|
|
58
62
|
|
|
63
|
+
const bulkImporter = createBulkImporterFactory(db, bulkImporterOptions);
|
|
59
64
|
const modules = await initModules({ db, migrationRepository, options }, customModules);
|
|
60
65
|
const services = initServices(modules, customServices);
|
|
61
66
|
|
|
@@ -80,7 +80,7 @@ export const FilterDirector: IFilterDirector = {
|
|
|
80
80
|
initialValue: V,
|
|
81
81
|
) => {
|
|
82
82
|
if (adapters.length === 0) {
|
|
83
|
-
return
|
|
83
|
+
return initialValue;
|
|
84
84
|
}
|
|
85
85
|
return adapters.reduce(async (lastSearchPromise, adapter, index) => {
|
|
86
86
|
return reducer(lastSearchPromise, adapter, index);
|
|
@@ -89,11 +89,10 @@ export const FilterDirector: IFilterDirector = {
|
|
|
89
89
|
|
|
90
90
|
return {
|
|
91
91
|
aggregateProductIds: (params) => {
|
|
92
|
-
|
|
92
|
+
return adapters.reduce(
|
|
93
93
|
(productIds, adapter) => adapter.aggregateProductIds({ productIds }),
|
|
94
94
|
params.productIds,
|
|
95
95
|
);
|
|
96
|
-
return reducedProductIds;
|
|
97
96
|
},
|
|
98
97
|
|
|
99
98
|
searchAssortments: async (params, options) => {
|
|
@@ -113,19 +112,19 @@ export const FilterDirector: IFilterDirector = {
|
|
|
113
112
|
transformProductSelector: async (defaultSelector, options) => {
|
|
114
113
|
return reduceAdapters<mongodb.Filter<Product>>(async (lastSelector, adapter) => {
|
|
115
114
|
return adapter.transformProductSelector(await lastSelector, options);
|
|
116
|
-
}, defaultSelector
|
|
115
|
+
}, defaultSelector);
|
|
117
116
|
},
|
|
118
117
|
|
|
119
118
|
transformSortStage: async (defaultStage, options) => {
|
|
120
119
|
return reduceAdapters<mongodb.FindOptions<Product>['sort']>(async (lastSortStage, adapter) => {
|
|
121
120
|
return adapter.transformSortStage(await lastSortStage, options);
|
|
122
|
-
}, defaultStage
|
|
121
|
+
}, defaultStage);
|
|
123
122
|
},
|
|
124
123
|
|
|
125
124
|
transformFilterSelector: async (defaultSelector) => {
|
|
126
125
|
return reduceAdapters<mongodb.Filter<Filter>>(async (lastSelector, adapter) => {
|
|
127
126
|
return adapter.transformFilterSelector(await lastSelector);
|
|
128
|
-
}, defaultSelector
|
|
127
|
+
}, defaultSelector);
|
|
129
128
|
},
|
|
130
129
|
};
|
|
131
130
|
},
|
|
@@ -161,7 +160,7 @@ export const FilterDirector: IFilterDirector = {
|
|
|
161
160
|
filter.type === FilterType.SWITCH
|
|
162
161
|
? {
|
|
163
162
|
true: await this.findProductIds(filter, { value: true }, unchainedAPI),
|
|
164
|
-
false: await this.findProductIds(filter, { value: false }, unchainedAPI),
|
|
163
|
+
false: await this.findProductIds(filter, { value: { $in: [null, false] } }, unchainedAPI),
|
|
165
164
|
}
|
|
166
165
|
: await (filter.options || []).reduce(async (accumulatorPromise, option) => {
|
|
167
166
|
const accumulator = await accumulatorPromise;
|
|
@@ -101,7 +101,7 @@ export const PaymentDirector: IPaymentDirector = {
|
|
|
101
101
|
try {
|
|
102
102
|
return adapter.isActive(paymentContext.transactionContext);
|
|
103
103
|
} catch (error) {
|
|
104
|
-
logger.error(error
|
|
104
|
+
logger.error(error);
|
|
105
105
|
return false;
|
|
106
106
|
}
|
|
107
107
|
},
|
|
@@ -110,7 +110,7 @@ export const PaymentDirector: IPaymentDirector = {
|
|
|
110
110
|
try {
|
|
111
111
|
return adapter.isPayLaterAllowed(paymentContext.transactionContext);
|
|
112
112
|
} catch (error) {
|
|
113
|
-
logger.error(error
|
|
113
|
+
logger.error(error);
|
|
114
114
|
return false;
|
|
115
115
|
}
|
|
116
116
|
},
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { BaseAdapter, IBaseAdapter } from '@unchainedshop/utils';
|
|
2
2
|
import { WorkResult } from '@unchainedshop/core-worker';
|
|
3
|
-
import { Modules } from '../modules.js';
|
|
3
|
+
import { ModuleOptions, Modules } from '../modules.js';
|
|
4
4
|
import { Services } from '../services/index.js';
|
|
5
|
-
import { BulkImporter } from '../
|
|
5
|
+
import { BulkImporter } from '../bulk-importer/createBulkImporter.js';
|
|
6
6
|
|
|
7
7
|
export type IWorkerAdapter<Input, Output> = IBaseAdapter & {
|
|
8
8
|
type: string;
|
|
@@ -11,7 +11,12 @@ export type IWorkerAdapter<Input, Output> = IBaseAdapter & {
|
|
|
11
11
|
|
|
12
12
|
doWork: (
|
|
13
13
|
input: Input,
|
|
14
|
-
unchainedAPI: {
|
|
14
|
+
unchainedAPI: {
|
|
15
|
+
modules: Modules;
|
|
16
|
+
services: Services;
|
|
17
|
+
bulkImporter: BulkImporter;
|
|
18
|
+
options: ModuleOptions;
|
|
19
|
+
},
|
|
15
20
|
workId: string,
|
|
16
21
|
) => Promise<WorkResult<Output>>;
|
|
17
22
|
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { FilterAdapter, FilterDirector } from '../core-index.js';
|
|
2
|
+
|
|
3
|
+
export default function registerProductDiscoverabilityFilter({
|
|
4
|
+
orderIndex = 0,
|
|
5
|
+
hiddenTagValue = 'hidden',
|
|
6
|
+
}: {
|
|
7
|
+
orderIndex?: number;
|
|
8
|
+
hiddenTagValue?: string;
|
|
9
|
+
}) {
|
|
10
|
+
FilterDirector.registerAdapter({
|
|
11
|
+
...FilterAdapter,
|
|
12
|
+
|
|
13
|
+
key: `shop.unchained.filters.product-discoverability-${crypto.randomUUID()}`,
|
|
14
|
+
label: 'Product Discoverability Filter',
|
|
15
|
+
version: '1.0.0',
|
|
16
|
+
orderIndex,
|
|
17
|
+
|
|
18
|
+
actions: (params) => {
|
|
19
|
+
return {
|
|
20
|
+
...FilterAdapter.actions(params),
|
|
21
|
+
|
|
22
|
+
transformProductSelector: async (lastSelector, options) => {
|
|
23
|
+
const { key } = options || {};
|
|
24
|
+
|
|
25
|
+
if (!key) {
|
|
26
|
+
const newSelector = { ...lastSelector };
|
|
27
|
+
if (!newSelector.$and) newSelector.$and = [];
|
|
28
|
+
newSelector.$and.push({ tags: { $ne: hiddenTagValue } });
|
|
29
|
+
return newSelector;
|
|
30
|
+
}
|
|
31
|
+
return lastSelector;
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
}
|
package/src/modules.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Enrollment, EnrollmentStatus } from '@unchainedshop/core-enrollments';
|
|
2
2
|
import { Modules } from '../modules.js';
|
|
3
3
|
import { processEnrollmentService } from './processEnrollment.js';
|
|
4
|
+
import { addMessageService } from './addMessage.js';
|
|
4
5
|
|
|
5
6
|
export async function activateEnrollmentService(this: Modules, enrollment: Enrollment) {
|
|
6
7
|
if (enrollment.status === EnrollmentStatus.TERMINATED) return enrollment;
|
|
@@ -15,15 +16,10 @@ export async function activateEnrollmentService(this: Modules, enrollment: Enrol
|
|
|
15
16
|
const user = await this.users.findUserById(enrollment.userId);
|
|
16
17
|
const locale = this.users.userLocale(user);
|
|
17
18
|
|
|
18
|
-
await
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
reason: 'status_change',
|
|
23
|
-
locale: locale.baseName,
|
|
24
|
-
template: 'ENROLLMENT_STATUS',
|
|
25
|
-
enrollmentId: updatedEnrollment._id,
|
|
26
|
-
},
|
|
19
|
+
await addMessageService.bind(this)('ENROLLMENT_STATUS', {
|
|
20
|
+
reason: 'status_change',
|
|
21
|
+
locale: locale.baseName,
|
|
22
|
+
enrollmentId: updatedEnrollment._id,
|
|
27
23
|
});
|
|
28
24
|
|
|
29
25
|
return updatedEnrollment;
|