@unchainedshop/core 5.0.0-alpha.2 → 5.0.0-alpha.3
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-exporter/handlers/exportProductsHandler.js +2 -2
- package/lib/bulk-importer/handlers/product/create.d.ts +18 -6
- package/lib/bulk-importer/handlers/product/create.js +5 -3
- package/lib/bulk-importer/handlers/product/update.d.ts +18 -6
- package/lib/bulk-importer/handlers/product/update.js +5 -2
- package/lib/directors/FilterDirector.js +23 -18
- package/lib/directors/WorkerDirector.js +1 -1
- package/lib/errors.d.ts +1 -0
- package/lib/errors.js +5 -0
- package/lib/factory/index.d.ts +12 -1
- package/lib/factory/index.js +12 -1
- package/lib/factory/registerAssortmentSearchFilter.d.ts +2 -1
- package/lib/factory/registerAssortmentSearchFilter.js +6 -3
- package/lib/factory/registerDeliveryPricing.d.ts +7 -0
- package/lib/factory/registerDeliveryPricing.js +30 -0
- package/lib/factory/registerDeliveryProvider.d.ts +12 -0
- package/lib/factory/registerDeliveryProvider.js +46 -0
- package/lib/factory/registerEnrollment.d.ts +18 -0
- package/lib/factory/registerEnrollment.js +43 -0
- package/lib/factory/registerFileAdapter.d.ts +17 -0
- package/lib/factory/registerFileAdapter.js +24 -0
- package/lib/factory/registerOrderDiscount.d.ts +13 -0
- package/lib/factory/registerOrderDiscount.js +39 -0
- package/lib/factory/registerOrderPricing.d.ts +7 -0
- package/lib/factory/registerOrderPricing.js +30 -0
- package/lib/factory/registerPaymentPricing.d.ts +7 -0
- package/lib/factory/registerPaymentPricing.js +30 -0
- package/lib/factory/registerPaymentProvider.d.ts +15 -0
- package/lib/factory/registerPaymentProvider.js +53 -0
- package/lib/factory/registerProductDiscount.d.ts +20 -0
- package/lib/factory/registerProductDiscount.js +47 -0
- package/lib/factory/registerProductDiscoverabilityFilter.d.ts +2 -1
- package/lib/factory/registerProductDiscoverabilityFilter.js +6 -3
- package/lib/factory/registerProductPricing.d.ts +7 -0
- package/lib/factory/registerProductPricing.js +30 -0
- package/lib/factory/registerProductSearchFilter.d.ts +2 -1
- package/lib/factory/registerProductSearchFilter.js +4 -3
- package/lib/factory/registerQuotation.d.ts +12 -0
- package/lib/factory/registerQuotation.js +52 -0
- package/lib/factory/registerWorker.js +1 -1
- package/lib/services/addMultipleCartProducts.js +3 -2
- package/lib/services/createFilter.d.ts +3 -0
- package/lib/services/createFilter.js +6 -0
- package/lib/services/createFilterOption.d.ts +5 -0
- package/lib/services/createFilterOption.js +8 -0
- package/lib/services/createSignedURL.js +2 -1
- package/lib/services/deleteCart.d.ts +2 -0
- package/lib/services/deleteCart.js +7 -0
- package/lib/services/deleteDeadCarts.d.ts +2 -0
- package/lib/services/deleteDeadCarts.js +17 -0
- package/lib/services/deleteUser.js +2 -5
- package/lib/services/index.d.ts +10 -0
- package/lib/services/index.js +10 -0
- package/lib/services/loadFilterOptions.js +3 -3
- package/lib/services/processEnrollment.js +2 -1
- package/lib/services/processOrder.js +3 -2
- package/lib/services/processQuotation.js +11 -13
- package/lib/services/proposeQuotation.js +3 -0
- package/lib/services/removeFilterOption.d.ts +6 -0
- package/lib/services/removeFilterOption.js +8 -0
- package/lib/services/removeProduct.js +2 -1
- package/lib/services/updateCalculation.js +2 -1
- package/lib/services/updateFilter.d.ts +3 -0
- package/lib/services/updateFilter.js +8 -0
- package/lib/services/uploadFileFromStream.js +2 -1
- package/lib/services/validateOrder.js +7 -8
- package/package.json +6 -3
|
@@ -21,7 +21,7 @@ const PRODUCT_CSV_SCHEMA = {
|
|
|
21
21
|
'countryCode',
|
|
22
22
|
'isTaxable',
|
|
23
23
|
'isNetPrice',
|
|
24
|
-
'
|
|
24
|
+
'minQuantity',
|
|
25
25
|
],
|
|
26
26
|
bundleItemHeaders: ['productId', 'bundleItemProductId', 'quantity', 'configuration'],
|
|
27
27
|
variationItemHeaders: ['productId', 'variationId', 'key', 'type'],
|
|
@@ -77,7 +77,7 @@ const buildPriceRows = (productId, prices = []) => prices.map((p) => ({
|
|
|
77
77
|
isTaxable: p.isTaxable ?? '',
|
|
78
78
|
currencyCode: p.currency?.isoCode ?? '',
|
|
79
79
|
countryCode: p.country?.isoCode ?? '',
|
|
80
|
-
|
|
80
|
+
minQuantity: p.minQuantity ?? '',
|
|
81
81
|
}));
|
|
82
82
|
const buildBundleRows = (productId, bundles = []) => bundles.map((b) => ({
|
|
83
83
|
productId,
|
|
@@ -10,13 +10,17 @@ export declare const ProductCreateSpecificationSchema: z.ZodMiniObject<{
|
|
|
10
10
|
readonly TOKENIZED_PRODUCT: "TOKENIZED_PRODUCT";
|
|
11
11
|
}>;
|
|
12
12
|
sequence: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
|
|
13
|
-
status: z.
|
|
13
|
+
status: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniEnum<{
|
|
14
|
+
readonly DRAFT: "DRAFT";
|
|
15
|
+
readonly ACTIVE: "ACTIVE";
|
|
16
|
+
readonly DELETED: "DELETED";
|
|
17
|
+
}>>>;
|
|
14
18
|
published: z.ZodMiniOptional<z.ZodMiniNullable<z.iso.ZodMiniISODateTime>>;
|
|
15
19
|
tags: z.ZodMiniOptional<z.ZodMiniArray<z.ZodMiniString<string>>>;
|
|
16
20
|
commerce: z.ZodMiniOptional<z.ZodMiniObject<{
|
|
17
21
|
pricing: z.ZodMiniArray<z.ZodMiniObject<{
|
|
18
22
|
amount: z.ZodMiniNumber<number>;
|
|
19
|
-
|
|
23
|
+
minQuantity: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
|
|
20
24
|
isTaxable: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
|
|
21
25
|
isNetPrice: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
|
|
22
26
|
currencyCode: z.ZodMiniString<string>;
|
|
@@ -67,13 +71,17 @@ export declare const ProductCreatePayloadSchema: z.ZodMiniObject<{
|
|
|
67
71
|
readonly TOKENIZED_PRODUCT: "TOKENIZED_PRODUCT";
|
|
68
72
|
}>;
|
|
69
73
|
sequence: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
|
|
70
|
-
status: z.
|
|
74
|
+
status: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniEnum<{
|
|
75
|
+
readonly DRAFT: "DRAFT";
|
|
76
|
+
readonly ACTIVE: "ACTIVE";
|
|
77
|
+
readonly DELETED: "DELETED";
|
|
78
|
+
}>>>;
|
|
71
79
|
published: z.ZodMiniOptional<z.ZodMiniNullable<z.iso.ZodMiniISODateTime>>;
|
|
72
80
|
tags: z.ZodMiniOptional<z.ZodMiniArray<z.ZodMiniString<string>>>;
|
|
73
81
|
commerce: z.ZodMiniOptional<z.ZodMiniObject<{
|
|
74
82
|
pricing: z.ZodMiniArray<z.ZodMiniObject<{
|
|
75
83
|
amount: z.ZodMiniNumber<number>;
|
|
76
|
-
|
|
84
|
+
minQuantity: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
|
|
77
85
|
isTaxable: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
|
|
78
86
|
isNetPrice: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
|
|
79
87
|
currencyCode: z.ZodMiniString<string>;
|
|
@@ -170,13 +178,17 @@ declare namespace createProduct {
|
|
|
170
178
|
readonly TOKENIZED_PRODUCT: "TOKENIZED_PRODUCT";
|
|
171
179
|
}>;
|
|
172
180
|
sequence: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
|
|
173
|
-
status: z.
|
|
181
|
+
status: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniEnum<{
|
|
182
|
+
readonly DRAFT: "DRAFT";
|
|
183
|
+
readonly ACTIVE: "ACTIVE";
|
|
184
|
+
readonly DELETED: "DELETED";
|
|
185
|
+
}>>>;
|
|
174
186
|
published: z.ZodMiniOptional<z.ZodMiniNullable<z.iso.ZodMiniISODateTime>>;
|
|
175
187
|
tags: z.ZodMiniOptional<z.ZodMiniArray<z.ZodMiniString<string>>>;
|
|
176
188
|
commerce: z.ZodMiniOptional<z.ZodMiniObject<{
|
|
177
189
|
pricing: z.ZodMiniArray<z.ZodMiniObject<{
|
|
178
190
|
amount: z.ZodMiniNumber<number>;
|
|
179
|
-
|
|
191
|
+
minQuantity: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
|
|
180
192
|
isTaxable: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
|
|
181
193
|
isNetPrice: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
|
|
182
194
|
currencyCode: z.ZodMiniString<string>;
|
|
@@ -3,17 +3,17 @@ import upsertVariations, { ProductVariationSchema } from "./upsertVariations.js"
|
|
|
3
3
|
import upsertMedia from "./upsertMedia.js";
|
|
4
4
|
import { MediaSchema } from "../assortment/upsertMedia.js";
|
|
5
5
|
import convertTagsToLowerCase from "../utils/convertTagsToLowerCase.js";
|
|
6
|
-
import { ProductType } from '@unchainedshop/core-products';
|
|
6
|
+
import { ProductStatus, ProductType } from '@unchainedshop/core-products';
|
|
7
7
|
export const ProductCreateSpecificationSchema = z.object({
|
|
8
8
|
type: z.enum(ProductType),
|
|
9
9
|
sequence: z.optional(z.number()),
|
|
10
|
-
status: z.
|
|
10
|
+
status: z.nullish(z.enum(ProductStatus)),
|
|
11
11
|
published: z.nullish(z.iso.datetime()),
|
|
12
12
|
tags: z.optional(z.array(z.string())),
|
|
13
13
|
commerce: z.optional(z.object({
|
|
14
14
|
pricing: z.array(z.object({
|
|
15
15
|
amount: z.number(),
|
|
16
|
-
|
|
16
|
+
minQuantity: z.optional(z.number().check(z.gte(0))),
|
|
17
17
|
isTaxable: z.optional(z.boolean()),
|
|
18
18
|
isNetPrice: z.optional(z.boolean()),
|
|
19
19
|
currencyCode: z.string().check(z.minLength(1, 'currencyCode is required')),
|
|
@@ -59,6 +59,7 @@ export const ProductCreatePayloadSchema = z.object({
|
|
|
59
59
|
media: z.optional(z.array(MediaSchema)),
|
|
60
60
|
variations: z.optional(z.array(ProductVariationSchema)),
|
|
61
61
|
});
|
|
62
|
+
const normalizeStatus = (status) => (status === ProductStatus.DRAFT ? null : status);
|
|
62
63
|
const transformSpecification = (specification) => {
|
|
63
64
|
const { variationResolvers: assignments, content, supply, warehousing, sequence, ...productData } = specification;
|
|
64
65
|
const tags = productData?.tags ? convertTagsToLowerCase(productData.tags) : [];
|
|
@@ -67,6 +68,7 @@ const transformSpecification = (specification) => {
|
|
|
67
68
|
...productData,
|
|
68
69
|
...(sequence != null && { sequence }),
|
|
69
70
|
published: productData.published ? new Date(productData.published) : undefined,
|
|
71
|
+
...(productData.status !== undefined && { status: normalizeStatus(productData.status) }),
|
|
70
72
|
tags,
|
|
71
73
|
warehousing,
|
|
72
74
|
supply,
|
|
@@ -4,13 +4,17 @@ import type { Services } from '../../../services/index.ts';
|
|
|
4
4
|
export declare const ProductUpdateSpecificationSchema: z.ZodMiniObject<{
|
|
5
5
|
type: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
6
6
|
sequence: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
|
|
7
|
-
status: z.
|
|
7
|
+
status: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniEnum<{
|
|
8
|
+
readonly DRAFT: "DRAFT";
|
|
9
|
+
readonly ACTIVE: "ACTIVE";
|
|
10
|
+
readonly DELETED: "DELETED";
|
|
11
|
+
}>>>;
|
|
8
12
|
published: z.ZodMiniOptional<z.ZodMiniNullable<z.iso.ZodMiniISODateTime>>;
|
|
9
13
|
tags: z.ZodMiniOptional<z.ZodMiniArray<z.ZodMiniString<string>>>;
|
|
10
14
|
commerce: z.ZodMiniOptional<z.ZodMiniObject<{
|
|
11
15
|
pricing: z.ZodMiniArray<z.ZodMiniObject<{
|
|
12
16
|
amount: z.ZodMiniNumber<number>;
|
|
13
|
-
|
|
17
|
+
minQuantity: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
|
|
14
18
|
isTaxable: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
|
|
15
19
|
isNetPrice: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
|
|
16
20
|
currencyCode: z.ZodMiniString<string>;
|
|
@@ -55,13 +59,17 @@ export declare const ProductUpdatePayloadSchema: z.ZodMiniObject<{
|
|
|
55
59
|
specification: z.ZodMiniOptional<z.ZodMiniObject<{
|
|
56
60
|
type: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
57
61
|
sequence: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
|
|
58
|
-
status: z.
|
|
62
|
+
status: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniEnum<{
|
|
63
|
+
readonly DRAFT: "DRAFT";
|
|
64
|
+
readonly ACTIVE: "ACTIVE";
|
|
65
|
+
readonly DELETED: "DELETED";
|
|
66
|
+
}>>>;
|
|
59
67
|
published: z.ZodMiniOptional<z.ZodMiniNullable<z.iso.ZodMiniISODateTime>>;
|
|
60
68
|
tags: z.ZodMiniOptional<z.ZodMiniArray<z.ZodMiniString<string>>>;
|
|
61
69
|
commerce: z.ZodMiniOptional<z.ZodMiniObject<{
|
|
62
70
|
pricing: z.ZodMiniArray<z.ZodMiniObject<{
|
|
63
71
|
amount: z.ZodMiniNumber<number>;
|
|
64
|
-
|
|
72
|
+
minQuantity: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
|
|
65
73
|
isTaxable: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
|
|
66
74
|
isNetPrice: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
|
|
67
75
|
currencyCode: z.ZodMiniString<string>;
|
|
@@ -152,13 +160,17 @@ declare namespace updateProduct {
|
|
|
152
160
|
specification: z.ZodMiniOptional<z.ZodMiniObject<{
|
|
153
161
|
type: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
154
162
|
sequence: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
|
|
155
|
-
status: z.
|
|
163
|
+
status: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniEnum<{
|
|
164
|
+
readonly DRAFT: "DRAFT";
|
|
165
|
+
readonly ACTIVE: "ACTIVE";
|
|
166
|
+
readonly DELETED: "DELETED";
|
|
167
|
+
}>>>;
|
|
156
168
|
published: z.ZodMiniOptional<z.ZodMiniNullable<z.iso.ZodMiniISODateTime>>;
|
|
157
169
|
tags: z.ZodMiniOptional<z.ZodMiniArray<z.ZodMiniString<string>>>;
|
|
158
170
|
commerce: z.ZodMiniOptional<z.ZodMiniObject<{
|
|
159
171
|
pricing: z.ZodMiniArray<z.ZodMiniObject<{
|
|
160
172
|
amount: z.ZodMiniNumber<number>;
|
|
161
|
-
|
|
173
|
+
minQuantity: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
|
|
162
174
|
isTaxable: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
|
|
163
175
|
isNetPrice: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
|
|
164
176
|
currencyCode: z.ZodMiniString<string>;
|
|
@@ -3,16 +3,17 @@ import upsertVariations, { ProductVariationSchema } from "./upsertVariations.js"
|
|
|
3
3
|
import upsertMedia, { MediaSchema } from "./upsertMedia.js";
|
|
4
4
|
import createProduct, { ProductCreatePayloadSchema } from "./create.js";
|
|
5
5
|
import convertTagsToLowerCase from "../utils/convertTagsToLowerCase.js";
|
|
6
|
+
import { ProductStatus } from '@unchainedshop/core-products';
|
|
6
7
|
export const ProductUpdateSpecificationSchema = z.object({
|
|
7
8
|
type: z.optional(z.string()),
|
|
8
9
|
sequence: z.optional(z.number()),
|
|
9
|
-
status: z.
|
|
10
|
+
status: z.nullish(z.enum(ProductStatus)),
|
|
10
11
|
published: z.nullish(z.iso.datetime()),
|
|
11
12
|
tags: z.optional(z.array(z.string())),
|
|
12
13
|
commerce: z.optional(z.object({
|
|
13
14
|
pricing: z.array(z.object({
|
|
14
15
|
amount: z.number(),
|
|
15
|
-
|
|
16
|
+
minQuantity: z.optional(z.number().check(z.gte(0))),
|
|
16
17
|
isTaxable: z.optional(z.boolean()),
|
|
17
18
|
isNetPrice: z.optional(z.boolean()),
|
|
18
19
|
currencyCode: z.string().check(z.minLength(1, 'currencyCode is required')),
|
|
@@ -58,6 +59,7 @@ export const ProductUpdatePayloadSchema = z.object({
|
|
|
58
59
|
media: z.optional(z.array(MediaSchema)),
|
|
59
60
|
variations: z.optional(z.array(ProductVariationSchema)),
|
|
60
61
|
});
|
|
62
|
+
const normalizeStatus = (status) => (status === ProductStatus.DRAFT ? null : status);
|
|
61
63
|
const transformSpecification = (specification) => {
|
|
62
64
|
const { variationResolvers: assignments, content, supply, warehousing, ...productData } = specification;
|
|
63
65
|
const tags = productData?.tags ? convertTagsToLowerCase(productData.tags) : [];
|
|
@@ -65,6 +67,7 @@ const transformSpecification = (specification) => {
|
|
|
65
67
|
return {
|
|
66
68
|
...productData,
|
|
67
69
|
published: productData.published ? new Date(productData.published) : undefined,
|
|
70
|
+
...(productData.status !== undefined && { status: normalizeStatus(productData.status) }),
|
|
68
71
|
tags,
|
|
69
72
|
warehousing,
|
|
70
73
|
supply,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { mongodb } from '@unchainedshop/mongodb';
|
|
2
2
|
import { BaseDirector } from '@unchainedshop/utils';
|
|
3
|
-
import { filtersSettings, FilterType, } from '@unchainedshop/core-filters';
|
|
3
|
+
import { filterCacheGeneration, filtersSettings, FilterType, } from '@unchainedshop/core-filters';
|
|
4
4
|
import { pluginRegistry } from "../plugins/PluginRegistry.js";
|
|
5
5
|
import { FilterAdapter } from "./FilterAdapter.js";
|
|
6
6
|
export const parseQueryArray = (query) => (query || []).reduce((accumulator, { key, value }) => ({
|
|
@@ -80,18 +80,19 @@ export const FilterDirector = {
|
|
|
80
80
|
},
|
|
81
81
|
async buildProductIdMap(filter, unchainedAPI) {
|
|
82
82
|
const allProductIds = await this.findProductIds(filter, {}, unchainedAPI);
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
83
|
+
if (filter.type === FilterType.SWITCH) {
|
|
84
|
+
return [
|
|
85
|
+
allProductIds,
|
|
86
|
+
{
|
|
87
|
+
true: await this.findProductIds(filter, { value: true }, unchainedAPI),
|
|
88
|
+
false: await this.findProductIds(filter, { value: { $in: [null, false] } }, unchainedAPI),
|
|
89
|
+
},
|
|
90
|
+
];
|
|
91
|
+
}
|
|
92
|
+
const productIdsMap = Object.create(null);
|
|
93
|
+
for (const option of filter.options || []) {
|
|
94
|
+
productIdsMap[option] = await this.findProductIds(filter, { value: option }, unchainedAPI);
|
|
95
|
+
}
|
|
95
96
|
return [allProductIds, productIdsMap];
|
|
96
97
|
},
|
|
97
98
|
async filterProductIds(filter, { values, forceLiveCollection }, unchainedAPI) {
|
|
@@ -102,11 +103,13 @@ export const FilterDirector = {
|
|
|
102
103
|
return new Set(allProductIds);
|
|
103
104
|
const result = new Set();
|
|
104
105
|
for (const key of filteredKeys) {
|
|
106
|
+
if (!Object.hasOwn(keyToProductIdMap, key))
|
|
107
|
+
continue;
|
|
105
108
|
const additionalValues = keyToProductIdMap[key];
|
|
106
|
-
if (additionalValues)
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
109
|
+
if (!additionalValues)
|
|
110
|
+
continue;
|
|
111
|
+
for (const val of additionalValues)
|
|
112
|
+
result.add(val);
|
|
110
113
|
}
|
|
111
114
|
return result;
|
|
112
115
|
},
|
|
@@ -175,6 +178,8 @@ export const FilterDirector = {
|
|
|
175
178
|
if (!filter)
|
|
176
179
|
return;
|
|
177
180
|
const [productIds, productIdMap] = await this.buildProductIdMap(filter, unchainedAPI);
|
|
178
|
-
await
|
|
181
|
+
if (!(await unchainedAPI.modules.filters.filterExists({ filterId: filter._id })))
|
|
182
|
+
return;
|
|
183
|
+
await filtersSettings.setCachedProductIds(filter._id, productIds, productIdMap, filterCacheGeneration(filter));
|
|
179
184
|
},
|
|
180
185
|
};
|
|
@@ -47,7 +47,7 @@ export const WorkerDirector = {
|
|
|
47
47
|
logger.warn(`WorkerDirector: No registered adapter for type: ${type}`);
|
|
48
48
|
}
|
|
49
49
|
try {
|
|
50
|
-
const output = await adapter.doWork(input, unchainedAPI, workId);
|
|
50
|
+
const output = await adapter.doWork(input ?? {}, unchainedAPI, workId);
|
|
51
51
|
return output;
|
|
52
52
|
}
|
|
53
53
|
catch (error) {
|
package/lib/errors.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const createServiceError: (name: string, message: string) => Error;
|
package/lib/errors.js
ADDED
package/lib/factory/index.d.ts
CHANGED
|
@@ -7,4 +7,15 @@ import registerVirtualWarehousing from './registerVirtualWarehousing.ts';
|
|
|
7
7
|
import registerProductSearchFilter from './registerProductSearchFilter.ts';
|
|
8
8
|
import registerAssortmentSearchFilter from './registerAssortmentSearchFilter.ts';
|
|
9
9
|
import registerInvoicePayment from './registerInvoicePayment.ts';
|
|
10
|
-
|
|
10
|
+
import registerPaymentProvider from './registerPaymentProvider.ts';
|
|
11
|
+
import registerDeliveryProvider from './registerDeliveryProvider.ts';
|
|
12
|
+
import registerProductPricing from './registerProductPricing.ts';
|
|
13
|
+
import registerOrderPricing from './registerOrderPricing.ts';
|
|
14
|
+
import registerPaymentPricing from './registerPaymentPricing.ts';
|
|
15
|
+
import registerDeliveryPricing from './registerDeliveryPricing.ts';
|
|
16
|
+
import registerProductDiscount from './registerProductDiscount.ts';
|
|
17
|
+
import registerOrderDiscount from './registerOrderDiscount.ts';
|
|
18
|
+
import registerFileAdapter from './registerFileAdapter.ts';
|
|
19
|
+
import registerQuotation from './registerQuotation.ts';
|
|
20
|
+
import registerEnrollment from './registerEnrollment.ts';
|
|
21
|
+
export { registerProductDiscoverabilityFilter, registerPickUpDelivery, registerShippingDelivery, registerInvoicePayment, registerWorker, registerPhysicalWarehousing, registerVirtualWarehousing, registerProductSearchFilter, registerAssortmentSearchFilter, registerPaymentProvider, registerDeliveryProvider, registerProductPricing, registerOrderPricing, registerPaymentPricing, registerDeliveryPricing, registerProductDiscount, registerOrderDiscount, registerFileAdapter, registerQuotation, registerEnrollment, };
|
package/lib/factory/index.js
CHANGED
|
@@ -7,4 +7,15 @@ import registerVirtualWarehousing from "./registerVirtualWarehousing.js";
|
|
|
7
7
|
import registerProductSearchFilter from "./registerProductSearchFilter.js";
|
|
8
8
|
import registerAssortmentSearchFilter from "./registerAssortmentSearchFilter.js";
|
|
9
9
|
import registerInvoicePayment from "./registerInvoicePayment.js";
|
|
10
|
-
|
|
10
|
+
import registerPaymentProvider from "./registerPaymentProvider.js";
|
|
11
|
+
import registerDeliveryProvider from "./registerDeliveryProvider.js";
|
|
12
|
+
import registerProductPricing from "./registerProductPricing.js";
|
|
13
|
+
import registerOrderPricing from "./registerOrderPricing.js";
|
|
14
|
+
import registerPaymentPricing from "./registerPaymentPricing.js";
|
|
15
|
+
import registerDeliveryPricing from "./registerDeliveryPricing.js";
|
|
16
|
+
import registerProductDiscount from "./registerProductDiscount.js";
|
|
17
|
+
import registerOrderDiscount from "./registerOrderDiscount.js";
|
|
18
|
+
import registerFileAdapter from "./registerFileAdapter.js";
|
|
19
|
+
import registerQuotation from "./registerQuotation.js";
|
|
20
|
+
import registerEnrollment from "./registerEnrollment.js";
|
|
21
|
+
export { registerProductDiscoverabilityFilter, registerPickUpDelivery, registerShippingDelivery, registerInvoicePayment, registerWorker, registerPhysicalWarehousing, registerVirtualWarehousing, registerProductSearchFilter, registerAssortmentSearchFilter, registerPaymentProvider, registerDeliveryProvider, registerProductPricing, registerOrderPricing, registerPaymentPricing, registerDeliveryPricing, registerProductDiscount, registerOrderDiscount, registerFileAdapter, registerQuotation, registerEnrollment, };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { SearchQuery } from '@unchainedshop/core-filters';
|
|
2
2
|
import { type IPlugin } from '../core-index.ts';
|
|
3
|
-
export default function registerAssortmentSearchFilter({ orderIndex, search, }: {
|
|
3
|
+
export default function registerAssortmentSearchFilter({ adapterId, orderIndex, search, }: {
|
|
4
|
+
adapterId?: string;
|
|
4
5
|
orderIndex?: number;
|
|
5
6
|
search: (params: SearchQuery & {
|
|
6
7
|
queryString: string;
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { FilterAdapter } from "../core-index.js";
|
|
2
2
|
import { pluginRegistry } from "../plugins/PluginRegistry.js";
|
|
3
|
-
export default function registerAssortmentSearchFilter({ orderIndex = 0, search, }) {
|
|
3
|
+
export default function registerAssortmentSearchFilter({ adapterId, orderIndex = 0, search, }) {
|
|
4
|
+
const id = adapterId ?? crypto.randomUUID();
|
|
4
5
|
const adapter = {
|
|
5
6
|
...FilterAdapter,
|
|
6
|
-
key: `shop.unchained.filters.assortment-search-${
|
|
7
|
-
label:
|
|
7
|
+
key: `shop.unchained.filters.assortment-search-${id}`,
|
|
8
|
+
label: adapterId
|
|
9
|
+
? `Assortment Search Filter: ${adapterId}`
|
|
10
|
+
: 'Assortment Search Filter (auto-generated)',
|
|
8
11
|
version: '1.0.0',
|
|
9
12
|
orderIndex,
|
|
10
13
|
actions: (params) => {
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type IPlugin, type IDeliveryPricingSheet, type DeliveryPricingAdapterContext } from '../core-index.ts';
|
|
2
|
+
export default function registerDeliveryPricing({ adapterId, orderIndex, isActivatedFor, calculate, }: {
|
|
3
|
+
adapterId: string;
|
|
4
|
+
orderIndex?: number;
|
|
5
|
+
isActivatedFor?: (context: DeliveryPricingAdapterContext) => boolean;
|
|
6
|
+
calculate: (sheet: IDeliveryPricingSheet, context: DeliveryPricingAdapterContext) => Promise<void>;
|
|
7
|
+
}): IPlugin;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { DeliveryPricingAdapter, } from "../core-index.js";
|
|
2
|
+
import { pluginRegistry } from "../plugins/PluginRegistry.js";
|
|
3
|
+
export default function registerDeliveryPricing({ adapterId, orderIndex, isActivatedFor, calculate, }) {
|
|
4
|
+
const adapter = {
|
|
5
|
+
...DeliveryPricingAdapter,
|
|
6
|
+
key: `shop.unchained.pricing.delivery-${adapterId}`,
|
|
7
|
+
label: 'Delivery Pricing: ' + adapterId,
|
|
8
|
+
version: '1.0.0',
|
|
9
|
+
orderIndex: orderIndex ?? 0,
|
|
10
|
+
isActivatedFor: (context) => (isActivatedFor ? isActivatedFor(context) : true),
|
|
11
|
+
actions: (params) => {
|
|
12
|
+
const pricingAdapter = DeliveryPricingAdapter.actions(params);
|
|
13
|
+
return {
|
|
14
|
+
...pricingAdapter,
|
|
15
|
+
calculate: async () => {
|
|
16
|
+
await calculate(pricingAdapter.resultSheet(), params.context);
|
|
17
|
+
return pricingAdapter.calculate();
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
const plugin = {
|
|
23
|
+
key: adapter.key,
|
|
24
|
+
label: adapter.label,
|
|
25
|
+
version: adapter.version,
|
|
26
|
+
adapters: [adapter],
|
|
27
|
+
};
|
|
28
|
+
pluginRegistry.register(plugin);
|
|
29
|
+
return plugin;
|
|
30
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { DeliveryConfiguration } from '@unchainedshop/core-delivery';
|
|
2
|
+
import { DeliveryProviderType } from '@unchainedshop/core-delivery';
|
|
3
|
+
import { type DeliveryContext, type IPlugin } from '../core-index.ts';
|
|
4
|
+
import type { Work } from '@unchainedshop/core-worker';
|
|
5
|
+
export default function registerDeliveryProvider({ adapterId, type, active, autoReleaseAllowed, estimatedDeliveryThroughput, send, }: {
|
|
6
|
+
adapterId: string;
|
|
7
|
+
type?: DeliveryProviderType;
|
|
8
|
+
active?: boolean;
|
|
9
|
+
autoReleaseAllowed?: boolean;
|
|
10
|
+
estimatedDeliveryThroughput?: (warehousingThroughputTime: number, context: DeliveryContext) => Promise<number | null>;
|
|
11
|
+
send: boolean | ((configuration: DeliveryConfiguration, context: DeliveryContext) => Promise<boolean | Work>);
|
|
12
|
+
}): IPlugin;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { DeliveryProviderType } from '@unchainedshop/core-delivery';
|
|
2
|
+
import { DeliveryAdapter, } from "../core-index.js";
|
|
3
|
+
import { pluginRegistry } from "../plugins/PluginRegistry.js";
|
|
4
|
+
export default function registerDeliveryProvider({ adapterId, type = DeliveryProviderType.SHIPPING, active, autoReleaseAllowed, estimatedDeliveryThroughput, send, }) {
|
|
5
|
+
const adapter = {
|
|
6
|
+
...DeliveryAdapter,
|
|
7
|
+
key: `shop.unchained.delivery.${adapterId}`,
|
|
8
|
+
label: 'Delivery: ' + adapterId,
|
|
9
|
+
version: '1.0.0',
|
|
10
|
+
initialConfiguration: [],
|
|
11
|
+
typeSupported: (deliveryType) => {
|
|
12
|
+
return deliveryType === type;
|
|
13
|
+
},
|
|
14
|
+
actions: (config, context) => {
|
|
15
|
+
return {
|
|
16
|
+
...DeliveryAdapter.actions(config, context),
|
|
17
|
+
isActive: () => {
|
|
18
|
+
return active ?? true;
|
|
19
|
+
},
|
|
20
|
+
isAutoReleaseAllowed: () => {
|
|
21
|
+
return autoReleaseAllowed ?? true;
|
|
22
|
+
},
|
|
23
|
+
configurationError: () => {
|
|
24
|
+
return null;
|
|
25
|
+
},
|
|
26
|
+
estimatedDeliveryThroughput: async (warehousingThroughputTime) => {
|
|
27
|
+
if (estimatedDeliveryThroughput) {
|
|
28
|
+
return estimatedDeliveryThroughput(warehousingThroughputTime, context);
|
|
29
|
+
}
|
|
30
|
+
return 0;
|
|
31
|
+
},
|
|
32
|
+
send: async () => {
|
|
33
|
+
return typeof send === 'function' ? await send(config, context) : send;
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
const plugin = {
|
|
39
|
+
key: adapter.key,
|
|
40
|
+
label: adapter.label,
|
|
41
|
+
version: adapter.version,
|
|
42
|
+
adapters: [adapter],
|
|
43
|
+
};
|
|
44
|
+
pluginRegistry.register(plugin);
|
|
45
|
+
return plugin;
|
|
46
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { EnrollmentOrderPositionTemplate, EnrollmentPeriod, EnrollmentPlan } from '@unchainedshop/core-enrollments';
|
|
2
|
+
import type { ProductPlan } from '@unchainedshop/core-products';
|
|
3
|
+
import type { OrderPosition } from '@unchainedshop/core-orders';
|
|
4
|
+
import { type EnrollmentContext, type IPlugin } from '../core-index.ts';
|
|
5
|
+
export default function registerEnrollment({ adapterId, isActivatedFor, transformOrderItem, configurationForOrder, isOverdue, isValidForActivation, nextPeriod, }: {
|
|
6
|
+
adapterId: string;
|
|
7
|
+
isActivatedFor?: (productPlan?: ProductPlan) => boolean;
|
|
8
|
+
transformOrderItem?: (orderPosition: OrderPosition, unchainedAPI: any) => Promise<EnrollmentPlan>;
|
|
9
|
+
configurationForOrder: (params: {
|
|
10
|
+
period: EnrollmentPeriod;
|
|
11
|
+
}, context: EnrollmentContext) => Promise<{
|
|
12
|
+
orderContext?: Record<string, any>;
|
|
13
|
+
orderPositionTemplates: EnrollmentOrderPositionTemplate[];
|
|
14
|
+
} | null>;
|
|
15
|
+
isOverdue?: (context: EnrollmentContext) => Promise<boolean>;
|
|
16
|
+
isValidForActivation?: (context: EnrollmentContext) => Promise<boolean>;
|
|
17
|
+
nextPeriod?: (context: EnrollmentContext) => Promise<EnrollmentPeriod | null>;
|
|
18
|
+
}): IPlugin;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { EnrollmentAdapter, } from "../core-index.js";
|
|
2
|
+
import { pluginRegistry } from "../plugins/PluginRegistry.js";
|
|
3
|
+
export default function registerEnrollment({ adapterId, isActivatedFor, transformOrderItem, configurationForOrder, isOverdue, isValidForActivation, nextPeriod, }) {
|
|
4
|
+
const adapter = {
|
|
5
|
+
...EnrollmentAdapter,
|
|
6
|
+
key: `shop.unchained.enrollment.${adapterId}`,
|
|
7
|
+
label: 'Enrollment: ' + adapterId,
|
|
8
|
+
version: '1.0.0',
|
|
9
|
+
isActivatedFor: (productPlan) => {
|
|
10
|
+
return isActivatedFor ? isActivatedFor(productPlan) : true;
|
|
11
|
+
},
|
|
12
|
+
transformOrderItemToEnrollmentPlan: async (orderPosition, unchainedAPI) => {
|
|
13
|
+
return transformOrderItem
|
|
14
|
+
? transformOrderItem(orderPosition, unchainedAPI)
|
|
15
|
+
: EnrollmentAdapter.transformOrderItemToEnrollmentPlan(orderPosition, unchainedAPI);
|
|
16
|
+
},
|
|
17
|
+
actions: (context) => {
|
|
18
|
+
return {
|
|
19
|
+
...EnrollmentAdapter.actions(context),
|
|
20
|
+
configurationForOrder: async (params) => {
|
|
21
|
+
return configurationForOrder(params, context);
|
|
22
|
+
},
|
|
23
|
+
isOverdue: async () => {
|
|
24
|
+
return isOverdue ? isOverdue(context) : false;
|
|
25
|
+
},
|
|
26
|
+
isValidForActivation: async () => {
|
|
27
|
+
return isValidForActivation ? isValidForActivation(context) : false;
|
|
28
|
+
},
|
|
29
|
+
nextPeriod: async () => {
|
|
30
|
+
return nextPeriod ? nextPeriod(context) : EnrollmentAdapter.actions(context).nextPeriod();
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
const plugin = {
|
|
36
|
+
key: adapter.key,
|
|
37
|
+
label: adapter.label,
|
|
38
|
+
version: adapter.version,
|
|
39
|
+
adapters: [adapter],
|
|
40
|
+
};
|
|
41
|
+
pluginRegistry.register(plugin);
|
|
42
|
+
return plugin;
|
|
43
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type UploadedFile, type UploadFileData } from '@unchainedshop/core-files';
|
|
2
|
+
import { type IPlugin } from '../core-index.ts';
|
|
3
|
+
export default function registerFileAdapter<Context = unknown>({ adapterId, createSignedURL, uploadFileFromStream, createDownloadURL, removeFiles, uploadFileFromURL, }: {
|
|
4
|
+
adapterId: string;
|
|
5
|
+
createSignedURL: (directoryName: string, fileName: string, unchainedAPI: Context) => Promise<(UploadFileData & {
|
|
6
|
+
putURL: string;
|
|
7
|
+
}) | null>;
|
|
8
|
+
uploadFileFromStream: (directoryName: string, rawFile: any, unchainedAPI: Context, options?: Record<string, any>) => Promise<UploadFileData>;
|
|
9
|
+
createDownloadURL?: (file: UploadedFile, expiry?: number) => Promise<string | null>;
|
|
10
|
+
removeFiles?: (files: UploadedFile[], unchainedContext: Context) => Promise<void>;
|
|
11
|
+
uploadFileFromURL?: (directoryName: string, fileInput: {
|
|
12
|
+
fileLink: string;
|
|
13
|
+
fileName: string;
|
|
14
|
+
fileId?: string;
|
|
15
|
+
headers?: Record<string, unknown>;
|
|
16
|
+
}, unchainedAPI: Context) => Promise<UploadFileData>;
|
|
17
|
+
}): IPlugin;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { FileAdapter, } from '@unchainedshop/core-files';
|
|
2
|
+
import {} from "../core-index.js";
|
|
3
|
+
import { pluginRegistry } from "../plugins/PluginRegistry.js";
|
|
4
|
+
export default function registerFileAdapter({ adapterId, createSignedURL, uploadFileFromStream, createDownloadURL, removeFiles, uploadFileFromURL, }) {
|
|
5
|
+
const adapter = {
|
|
6
|
+
...FileAdapter,
|
|
7
|
+
key: `shop.unchained.file-upload.${adapterId}`,
|
|
8
|
+
label: 'File Adapter: ' + adapterId,
|
|
9
|
+
version: '1.0.0',
|
|
10
|
+
createSignedURL,
|
|
11
|
+
uploadFileFromStream,
|
|
12
|
+
...(createDownloadURL ? { createDownloadURL } : {}),
|
|
13
|
+
...(removeFiles ? { removeFiles } : {}),
|
|
14
|
+
...(uploadFileFromURL ? { uploadFileFromURL } : {}),
|
|
15
|
+
};
|
|
16
|
+
const plugin = {
|
|
17
|
+
key: adapter.key,
|
|
18
|
+
label: adapter.label,
|
|
19
|
+
version: adapter.version,
|
|
20
|
+
adapters: [adapter],
|
|
21
|
+
};
|
|
22
|
+
pluginRegistry.register(plugin);
|
|
23
|
+
return plugin;
|
|
24
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { PricingCalculation } from '@unchainedshop/utils';
|
|
2
|
+
import { type DiscountContext, type IPricingSheet, type OrderDiscountConfiguration, type IPlugin } from '../core-index.ts';
|
|
3
|
+
export default function registerOrderDiscount({ adapterId, isValidForSystemTriggering, isValidForCodeTriggering, discountForPricingAdapterKey, reserve, release, }: {
|
|
4
|
+
adapterId: string;
|
|
5
|
+
isValidForSystemTriggering?: (context: DiscountContext) => Promise<boolean>;
|
|
6
|
+
isValidForCodeTriggering?: (code: string, context: DiscountContext) => Promise<boolean>;
|
|
7
|
+
discountForPricingAdapterKey: (params: {
|
|
8
|
+
pricingAdapterKey: string;
|
|
9
|
+
calculationSheet: IPricingSheet<PricingCalculation>;
|
|
10
|
+
}, context: DiscountContext) => OrderDiscountConfiguration | null;
|
|
11
|
+
reserve?: (code: string | undefined, context: DiscountContext) => Promise<any>;
|
|
12
|
+
release?: (context: DiscountContext) => Promise<void>;
|
|
13
|
+
}): IPlugin;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { OrderDiscountAdapter, } from "../core-index.js";
|
|
2
|
+
import { pluginRegistry } from "../plugins/PluginRegistry.js";
|
|
3
|
+
export default function registerOrderDiscount({ adapterId, isValidForSystemTriggering, isValidForCodeTriggering, discountForPricingAdapterKey, reserve, release, }) {
|
|
4
|
+
const adapter = {
|
|
5
|
+
...OrderDiscountAdapter,
|
|
6
|
+
key: `shop.unchained.discount.order-${adapterId}`,
|
|
7
|
+
label: 'Order Discount: ' + adapterId,
|
|
8
|
+
version: '1.0.0',
|
|
9
|
+
actions: async ({ context }) => {
|
|
10
|
+
return {
|
|
11
|
+
...(await OrderDiscountAdapter.actions({ context })),
|
|
12
|
+
isValidForSystemTriggering: async () => {
|
|
13
|
+
return isValidForSystemTriggering ? isValidForSystemTriggering(context) : false;
|
|
14
|
+
},
|
|
15
|
+
isValidForCodeTriggering: async ({ code }) => {
|
|
16
|
+
return isValidForCodeTriggering ? isValidForCodeTriggering(code, context) : false;
|
|
17
|
+
},
|
|
18
|
+
discountForPricingAdapterKey: (params) => {
|
|
19
|
+
return discountForPricingAdapterKey(params, context);
|
|
20
|
+
},
|
|
21
|
+
reserve: async ({ code }) => {
|
|
22
|
+
return reserve ? reserve(code, context) : {};
|
|
23
|
+
},
|
|
24
|
+
release: async () => {
|
|
25
|
+
if (release)
|
|
26
|
+
await release(context);
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
const plugin = {
|
|
32
|
+
key: adapter.key,
|
|
33
|
+
label: adapter.label,
|
|
34
|
+
version: adapter.version,
|
|
35
|
+
adapters: [adapter],
|
|
36
|
+
};
|
|
37
|
+
pluginRegistry.register(plugin);
|
|
38
|
+
return plugin;
|
|
39
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type IPlugin, type IOrderPricingSheet, type OrderPricingAdapterContext } from '../core-index.ts';
|
|
2
|
+
export default function registerOrderPricing({ adapterId, orderIndex, isActivatedFor, calculate, }: {
|
|
3
|
+
adapterId: string;
|
|
4
|
+
orderIndex?: number;
|
|
5
|
+
isActivatedFor?: (context: OrderPricingAdapterContext) => boolean;
|
|
6
|
+
calculate: (sheet: IOrderPricingSheet, context: OrderPricingAdapterContext) => Promise<void>;
|
|
7
|
+
}): IPlugin;
|