@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.
Files changed (67) hide show
  1. package/lib/bulk-exporter/handlers/exportProductsHandler.js +2 -2
  2. package/lib/bulk-importer/handlers/product/create.d.ts +18 -6
  3. package/lib/bulk-importer/handlers/product/create.js +5 -3
  4. package/lib/bulk-importer/handlers/product/update.d.ts +18 -6
  5. package/lib/bulk-importer/handlers/product/update.js +5 -2
  6. package/lib/directors/FilterDirector.js +23 -18
  7. package/lib/directors/WorkerDirector.js +1 -1
  8. package/lib/errors.d.ts +1 -0
  9. package/lib/errors.js +5 -0
  10. package/lib/factory/index.d.ts +12 -1
  11. package/lib/factory/index.js +12 -1
  12. package/lib/factory/registerAssortmentSearchFilter.d.ts +2 -1
  13. package/lib/factory/registerAssortmentSearchFilter.js +6 -3
  14. package/lib/factory/registerDeliveryPricing.d.ts +7 -0
  15. package/lib/factory/registerDeliveryPricing.js +30 -0
  16. package/lib/factory/registerDeliveryProvider.d.ts +12 -0
  17. package/lib/factory/registerDeliveryProvider.js +46 -0
  18. package/lib/factory/registerEnrollment.d.ts +18 -0
  19. package/lib/factory/registerEnrollment.js +43 -0
  20. package/lib/factory/registerFileAdapter.d.ts +17 -0
  21. package/lib/factory/registerFileAdapter.js +24 -0
  22. package/lib/factory/registerOrderDiscount.d.ts +13 -0
  23. package/lib/factory/registerOrderDiscount.js +39 -0
  24. package/lib/factory/registerOrderPricing.d.ts +7 -0
  25. package/lib/factory/registerOrderPricing.js +30 -0
  26. package/lib/factory/registerPaymentPricing.d.ts +7 -0
  27. package/lib/factory/registerPaymentPricing.js +30 -0
  28. package/lib/factory/registerPaymentProvider.d.ts +15 -0
  29. package/lib/factory/registerPaymentProvider.js +53 -0
  30. package/lib/factory/registerProductDiscount.d.ts +20 -0
  31. package/lib/factory/registerProductDiscount.js +47 -0
  32. package/lib/factory/registerProductDiscoverabilityFilter.d.ts +2 -1
  33. package/lib/factory/registerProductDiscoverabilityFilter.js +6 -3
  34. package/lib/factory/registerProductPricing.d.ts +7 -0
  35. package/lib/factory/registerProductPricing.js +30 -0
  36. package/lib/factory/registerProductSearchFilter.d.ts +2 -1
  37. package/lib/factory/registerProductSearchFilter.js +4 -3
  38. package/lib/factory/registerQuotation.d.ts +12 -0
  39. package/lib/factory/registerQuotation.js +52 -0
  40. package/lib/factory/registerWorker.js +1 -1
  41. package/lib/services/addMultipleCartProducts.js +3 -2
  42. package/lib/services/createFilter.d.ts +3 -0
  43. package/lib/services/createFilter.js +6 -0
  44. package/lib/services/createFilterOption.d.ts +5 -0
  45. package/lib/services/createFilterOption.js +8 -0
  46. package/lib/services/createSignedURL.js +2 -1
  47. package/lib/services/deleteCart.d.ts +2 -0
  48. package/lib/services/deleteCart.js +7 -0
  49. package/lib/services/deleteDeadCarts.d.ts +2 -0
  50. package/lib/services/deleteDeadCarts.js +17 -0
  51. package/lib/services/deleteUser.js +2 -5
  52. package/lib/services/index.d.ts +10 -0
  53. package/lib/services/index.js +10 -0
  54. package/lib/services/loadFilterOptions.js +3 -3
  55. package/lib/services/processEnrollment.js +2 -1
  56. package/lib/services/processOrder.js +3 -2
  57. package/lib/services/processQuotation.js +11 -13
  58. package/lib/services/proposeQuotation.js +3 -0
  59. package/lib/services/removeFilterOption.d.ts +6 -0
  60. package/lib/services/removeFilterOption.js +8 -0
  61. package/lib/services/removeProduct.js +2 -1
  62. package/lib/services/updateCalculation.js +2 -1
  63. package/lib/services/updateFilter.d.ts +3 -0
  64. package/lib/services/updateFilter.js +8 -0
  65. package/lib/services/uploadFileFromStream.js +2 -1
  66. package/lib/services/validateOrder.js +7 -8
  67. package/package.json +6 -3
@@ -21,7 +21,7 @@ const PRODUCT_CSV_SCHEMA = {
21
21
  'countryCode',
22
22
  'isTaxable',
23
23
  'isNetPrice',
24
- 'maxQuantity',
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
- maxQuantity: p.maxQuantity ?? '',
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.ZodMiniNullable<z.ZodMiniOptional<z.ZodMiniString<string>>>;
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
- maxQuantity: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
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.ZodMiniNullable<z.ZodMiniOptional<z.ZodMiniString<string>>>;
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
- maxQuantity: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
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.ZodMiniNullable<z.ZodMiniOptional<z.ZodMiniString<string>>>;
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
- maxQuantity: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
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.nullable(z.optional(z.string())),
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
- maxQuantity: z.optional(z.number()),
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.ZodMiniNullable<z.ZodMiniOptional<z.ZodMiniString<string>>>;
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
- maxQuantity: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
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.ZodMiniNullable<z.ZodMiniOptional<z.ZodMiniString<string>>>;
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
- maxQuantity: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
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.ZodMiniNullable<z.ZodMiniOptional<z.ZodMiniString<string>>>;
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
- maxQuantity: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
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.nullable(z.optional(z.string())),
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
- maxQuantity: z.optional(z.number()),
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
- const productIdsMap = filter.type === FilterType.SWITCH
84
- ? {
85
- true: await this.findProductIds(filter, { value: true }, unchainedAPI),
86
- false: await this.findProductIds(filter, { value: { $in: [null, false] } }, unchainedAPI),
87
- }
88
- : await (filter.options || []).reduce(async (accumulatorPromise, option) => {
89
- const accumulator = await accumulatorPromise;
90
- return {
91
- ...accumulator,
92
- [option]: await this.findProductIds(filter, { value: option }, unchainedAPI),
93
- };
94
- }, Promise.resolve({}));
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
- for (const val of additionalValues)
108
- result.add(val);
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 filtersSettings.setCachedProductIds(filter._id, productIds, productIdMap);
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) {
@@ -0,0 +1 @@
1
+ export declare const createServiceError: (name: string, message: string) => Error;
package/lib/errors.js ADDED
@@ -0,0 +1,5 @@
1
+ export const createServiceError = (name, message) => {
2
+ const error = new Error(message);
3
+ error.name = name;
4
+ return error;
5
+ };
@@ -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
- export { registerProductDiscoverabilityFilter, registerPickUpDelivery, registerShippingDelivery, registerInvoicePayment, registerWorker, registerPhysicalWarehousing, registerVirtualWarehousing, registerProductSearchFilter, registerAssortmentSearchFilter, };
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, };
@@ -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
- export { registerProductDiscoverabilityFilter, registerPickUpDelivery, registerShippingDelivery, registerInvoicePayment, registerWorker, registerPhysicalWarehousing, registerVirtualWarehousing, registerProductSearchFilter, registerAssortmentSearchFilter, };
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-${crypto.randomUUID()}`,
7
- label: 'Assortment Search Filter (auto-generated)',
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;