@reactionary/source 0.6.1 → 0.6.2
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/README.md +14 -11
- package/core/src/client/client-builder.ts +54 -6
- package/core/src/factories/cart.factory.ts +40 -0
- package/core/src/factories/category.factory.ts +40 -0
- package/core/src/factories/checkout.factory.ts +59 -0
- package/core/src/factories/identity.factory.ts +26 -0
- package/core/src/factories/index.ts +15 -0
- package/core/src/factories/inventory.factory.ts +26 -0
- package/core/src/factories/order-search.factory.ts +33 -0
- package/core/src/factories/order.factory.ts +21 -0
- package/core/src/factories/price.factory.ts +29 -0
- package/core/src/factories/product-associations.factory.ts +30 -0
- package/core/src/factories/product-list.factory.ts +82 -0
- package/core/src/factories/product-reviews.factory.ts +58 -0
- package/core/src/factories/product-search.factory.ts +31 -0
- package/core/src/factories/product.factory.ts +21 -0
- package/core/src/factories/profile.factory.ts +23 -0
- package/core/src/factories/store.factory.ts +21 -0
- package/core/src/index.ts +3 -1
- package/core/src/providers/cart.provider.ts +12 -10
- package/core/src/providers/category.provider.ts +9 -7
- package/core/src/providers/checkout.provider.ts +14 -10
- package/core/src/providers/identity.provider.ts +7 -7
- package/core/src/providers/inventory.provider.ts +4 -4
- package/core/src/providers/order-search.provider.ts +4 -2
- package/core/src/providers/order.provider.ts +4 -4
- package/core/src/providers/price.provider.ts +5 -5
- package/core/src/providers/product-associations.provider.ts +6 -4
- package/core/src/providers/product-list.provider.ts +13 -8
- package/core/src/providers/product-reviews.provider.ts +8 -4
- package/core/src/providers/product-search.provider.ts +15 -28
- package/core/src/providers/product.provider.ts +6 -6
- package/core/src/providers/profile.provider.ts +8 -8
- package/core/src/providers/store.provider.ts +2 -2
- package/core/src/test/client-builder.spec.ts +81 -0
- package/examples/node/package.json +7 -7
- package/examples/node/src/basic/basic-node-provider-model-extension.spec.ts +10 -4
- package/examples/node/src/basic/basic-node-provider-query-extension.spec.ts +8 -2
- package/examples/node/src/basic/basic-node-setup.spec.ts +5 -1
- package/examples/node/src/basic/client-creation.spec.ts +3 -3
- package/examples/node/src/utils.ts +41 -41
- package/examples/node/tsconfig.lib.json +2 -1
- package/package.json +1 -1
- package/providers/algolia/src/core/initialize.ts +76 -21
- package/providers/algolia/src/core/initialize.types.ts +107 -0
- package/providers/algolia/src/factories/index.ts +1 -0
- package/providers/algolia/src/factories/product-search/product-search.factory.ts +182 -0
- package/providers/algolia/src/index.ts +2 -2
- package/providers/algolia/src/providers/analytics.provider.ts +4 -4
- package/providers/algolia/src/providers/product-search.provider.ts +67 -184
- package/providers/algolia/src/schema/capabilities.schema.ts +81 -7
- package/providers/algolia/src/test/analytics.spec.ts +9 -1
- package/providers/algolia/src/test/client-builder-product-search-extension.example.ts +85 -0
- package/providers/commercetools/src/core/capability-descriptors.ts +324 -0
- package/providers/commercetools/src/core/initialize.ts +35 -151
- package/providers/commercetools/src/core/initialize.types.ts +174 -0
- package/providers/commercetools/src/factories/cart/cart.factory.ts +142 -0
- package/providers/commercetools/src/factories/category/category.factory.ts +77 -0
- package/providers/commercetools/src/factories/checkout/checkout-initializer-overrides.example.ts +94 -0
- package/providers/commercetools/src/factories/checkout/checkout.factory.ts +338 -0
- package/providers/commercetools/src/factories/identity/identity.factory.ts +26 -0
- package/providers/commercetools/src/factories/inventory/inventory.factory.ts +49 -0
- package/providers/commercetools/src/factories/order/order.factory.ts +149 -0
- package/providers/commercetools/src/factories/order-search/order-search.factory.ts +108 -0
- package/providers/commercetools/src/factories/price/price.factory.ts +76 -0
- package/providers/commercetools/src/factories/product/product-factory-baseline.example.ts +14 -0
- package/providers/commercetools/src/factories/product/product-factory-schema-and-parse-extension.example.ts +35 -0
- package/providers/commercetools/src/factories/product/product-factory-schema-extension.example.ts +23 -0
- package/providers/commercetools/src/factories/product/product-initializer-factory-extension.example.ts +41 -0
- package/providers/commercetools/src/factories/product/product-provider-custom-method-only.example.ts +47 -0
- package/providers/commercetools/src/factories/product/product-provider-schema-signature-extension.example.ts +61 -0
- package/providers/commercetools/src/factories/product/product.factory.ts +220 -0
- package/providers/commercetools/src/factories/product/utils.example.ts +9 -0
- package/providers/commercetools/src/factories/product-associations/product-associations.factory.ts +103 -0
- package/providers/commercetools/src/factories/product-list/product-list.factory.ts +122 -0
- package/providers/commercetools/src/factories/product-reviews/product-reviews.factory.ts +81 -0
- package/providers/commercetools/src/factories/product-search/product-search.factory.ts +182 -0
- package/providers/commercetools/src/factories/profile/profile.factory.ts +94 -0
- package/providers/commercetools/src/factories/store/store.factory.ts +49 -0
- package/providers/commercetools/src/index.ts +15 -0
- package/providers/commercetools/src/providers/cart.provider.ts +67 -193
- package/providers/commercetools/src/providers/category.provider.ts +24 -64
- package/providers/commercetools/src/providers/checkout.provider.ts +50 -322
- package/providers/commercetools/src/providers/identity.provider.ts +35 -15
- package/providers/commercetools/src/providers/inventory.provider.ts +13 -31
- package/providers/commercetools/src/providers/order-search.provider.ts +16 -110
- package/providers/commercetools/src/providers/order.provider.ts +13 -144
- package/providers/commercetools/src/providers/price.provider.ts +37 -51
- package/providers/commercetools/src/providers/product-associations.provider.ts +39 -104
- package/providers/commercetools/src/providers/product-list.provider.ts +38 -23
- package/providers/commercetools/src/providers/product-reviews.provider.ts +34 -14
- package/providers/commercetools/src/providers/product-search.provider.ts +17 -170
- package/providers/commercetools/src/providers/product.provider.ts +20 -199
- package/providers/commercetools/src/providers/profile.provider.ts +27 -73
- package/providers/commercetools/src/providers/store.provider.ts +13 -31
- package/providers/commercetools/src/schema/capabilities.schema.ts +258 -20
- package/providers/commercetools/src/test/caching.spec.ts +18 -2
- package/providers/commercetools/src/test/client-builder-merge-extensions.example.ts +125 -0
- package/providers/fake/src/core/initialize.ts +213 -44
- package/providers/fake/src/core/initialize.types.ts +164 -0
- package/providers/fake/src/factories/cart/cart.factory.ts +34 -0
- package/providers/fake/src/factories/category/category.factory.ts +40 -0
- package/providers/fake/src/factories/checkout/checkout.factory.ts +53 -0
- package/providers/fake/src/factories/identity/identity.factory.ts +25 -0
- package/providers/fake/src/factories/index.ts +14 -0
- package/providers/fake/src/factories/inventory/inventory.factory.ts +25 -0
- package/providers/fake/src/factories/order/order.factory.ts +22 -0
- package/providers/fake/src/factories/order-search/order-search.factory.ts +27 -0
- package/providers/fake/src/factories/price/price.factory.ts +26 -0
- package/providers/fake/src/factories/product/product.factory.ts +22 -0
- package/providers/fake/src/factories/product-associations/product-associations.factory.ts +25 -0
- package/providers/fake/src/factories/product-reviews/product-reviews.factory.ts +53 -0
- package/providers/fake/src/factories/product-search/product-search.factory.ts +27 -0
- package/providers/fake/src/factories/profile/profile.factory.ts +22 -0
- package/providers/fake/src/factories/store/store.factory.ts +22 -0
- package/providers/fake/src/index.ts +2 -0
- package/providers/fake/src/providers/cart.provider.ts +23 -14
- package/providers/fake/src/providers/category.provider.ts +120 -105
- package/providers/fake/src/providers/checkout.provider.ts +39 -20
- package/providers/fake/src/providers/identity.provider.ts +40 -34
- package/providers/fake/src/providers/inventory.provider.ts +26 -24
- package/providers/fake/src/providers/order-search.provider.ts +38 -30
- package/providers/fake/src/providers/order.provider.ts +21 -37
- package/providers/fake/src/providers/price.provider.ts +42 -34
- package/providers/fake/src/providers/product-associations.provider.ts +23 -10
- package/providers/fake/src/providers/product-reviews.provider.ts +71 -69
- package/providers/fake/src/providers/product-search.provider.ts +43 -70
- package/providers/fake/src/providers/product.provider.ts +34 -32
- package/providers/fake/src/providers/profile.provider.ts +62 -55
- package/providers/fake/src/providers/store.provider.ts +38 -22
- package/providers/fake/src/schema/capabilities.schema.ts +175 -18
- package/providers/fake/src/test/cart.provider.spec.ts +20 -3
- package/providers/fake/src/test/category.provider.spec.ts +4 -1
- package/providers/fake/src/test/checkout.provider.spec.ts +12 -2
- package/providers/fake/src/test/client-builder-product-extension.example.ts +75 -0
- package/providers/fake/src/test/order-search.provider.spec.ts +4 -7
- package/providers/fake/src/test/order.provider.spec.ts +4 -6
- package/providers/fake/src/test/price.provider.spec.ts +3 -1
- package/providers/fake/src/test/product.provider.spec.ts +8 -2
- package/providers/fake/src/test/profile.provider.spec.ts +4 -2
- package/providers/google-analytics/src/core/initialize.ts +37 -12
- package/providers/google-analytics/src/core/initialize.types.ts +47 -0
- package/providers/google-analytics/src/index.ts +1 -0
- package/providers/google-analytics/src/schema/capabilities.schema.ts +31 -5
- package/providers/medusa/src/core/initialize.ts +324 -81
- package/providers/medusa/src/core/initialize.types.ts +184 -0
- package/providers/medusa/src/factories/cart/cart.factory.ts +34 -0
- package/providers/medusa/src/factories/category/category.factory.ts +37 -0
- package/providers/medusa/src/factories/checkout/checkout.factory.ts +50 -0
- package/providers/medusa/src/factories/identity/identity.factory.ts +22 -0
- package/providers/medusa/src/factories/index.ts +12 -0
- package/providers/medusa/src/factories/inventory/inventory.factory.ts +25 -0
- package/providers/medusa/src/factories/order/order.factory.ts +22 -0
- package/providers/medusa/src/factories/order-search/order-search.factory.ts +27 -0
- package/providers/medusa/src/factories/price/price.factory.ts +26 -0
- package/providers/medusa/src/factories/product/product.factory.ts +22 -0
- package/providers/medusa/src/factories/product-associations/product-associations.factory.ts +25 -0
- package/providers/medusa/src/factories/product-search/product-search.factory.ts +27 -0
- package/providers/medusa/src/factories/profile/profile.factory.ts +22 -0
- package/providers/medusa/src/index.ts +2 -0
- package/providers/medusa/src/providers/cart.provider.ts +33 -20
- package/providers/medusa/src/providers/category.provider.ts +30 -12
- package/providers/medusa/src/providers/checkout.provider.ts +42 -17
- package/providers/medusa/src/providers/identity.provider.ts +1 -1
- package/providers/medusa/src/providers/inventory.provider.ts +21 -7
- package/providers/medusa/src/providers/order-search.provider.ts +16 -5
- package/providers/medusa/src/providers/order.provider.ts +17 -5
- package/providers/medusa/src/providers/price.provider.ts +26 -7
- package/providers/medusa/src/providers/product-associations.provider.ts +19 -8
- package/providers/medusa/src/providers/product-search.provider.ts +19 -31
- package/providers/medusa/src/providers/product.provider.ts +47 -11
- package/providers/medusa/src/providers/profile.provider.ts +35 -11
- package/providers/medusa/src/schema/capabilities.schema.ts +229 -18
- package/providers/medusa/src/test/cart.provider.spec.ts +18 -2
- package/providers/medusa/src/test/category.provider.spec.ts +4 -1
- package/providers/medusa/src/test/checkout.spec.ts +9 -9
- package/providers/medusa/src/test/inventory.provider.spec.ts +3 -1
- package/providers/medusa/src/test/large-cart.provider.spec.ts +8 -2
- package/providers/medusa/src/test/price.provider.spec.ts +8 -1
- package/providers/medusa/src/test/product.provider.spec.ts +3 -1
- package/providers/medusa/src/test/search.provider.spec.ts +16 -3
- package/providers/meilisearch/src/core/initialize.ts +88 -21
- package/providers/meilisearch/src/core/initialize.types.ts +119 -0
- package/providers/meilisearch/src/factories/index.ts +2 -0
- package/providers/meilisearch/src/factories/order-search/order-search.factory.ts +27 -0
- package/providers/meilisearch/src/factories/product-search/product-search.factory.ts +27 -0
- package/providers/meilisearch/src/index.ts +2 -0
- package/providers/meilisearch/src/providers/index.ts +1 -0
- package/providers/meilisearch/src/providers/order-search.provider.ts +21 -6
- package/providers/meilisearch/src/providers/product-search.provider.ts +24 -8
- package/providers/meilisearch/src/schema/capabilities.schema.ts +95 -8
|
@@ -1,47 +1,45 @@
|
|
|
1
1
|
import {
|
|
2
|
+
type ProductAssociationsFactory,
|
|
3
|
+
type ProductAssociationsFactoryOutput,
|
|
4
|
+
type ProductAssociationsFactoryWithOutput,
|
|
2
5
|
ProductAssociationsProvider,
|
|
3
6
|
Reactionary,
|
|
4
|
-
ImageSchema,
|
|
5
|
-
ProductVariantOptionSchema,
|
|
6
|
-
ProductOptionIdentifierSchema,
|
|
7
|
-
ProductSearchResultItemVariantSchema,
|
|
8
|
-
ProductVariantIdentifierSchema,
|
|
9
7
|
success,
|
|
10
8
|
error,
|
|
11
9
|
} from '@reactionary/core';
|
|
12
10
|
import type {
|
|
13
|
-
ProductVariantIdentifier,
|
|
14
11
|
ProductIdentifier,
|
|
15
|
-
ProductAssociation,
|
|
16
|
-
ProductSearchResultItem,
|
|
17
|
-
ProductSearchResultItemVariant,
|
|
18
12
|
ProductAssociationsGetAccessoriesQuery,
|
|
19
13
|
ProductAssociationsGetSparepartsQuery,
|
|
20
14
|
ProductAssociationsGetReplacementsQuery,
|
|
21
15
|
Result,
|
|
22
16
|
RequestContext,
|
|
23
17
|
Cache,
|
|
24
|
-
ProductOptionIdentifier,
|
|
25
|
-
ProductVariantOption,
|
|
26
18
|
NotFoundError,
|
|
27
19
|
} from '@reactionary/core';
|
|
28
|
-
import type { ProductProjection
|
|
20
|
+
import type { ProductProjection } from '@commercetools/platform-sdk';
|
|
29
21
|
import type { CommercetoolsConfiguration } from '../schema/configuration.schema.js';
|
|
30
22
|
import type { CommercetoolsAPI } from '../core/client.js';
|
|
23
|
+
import type { CommercetoolsProductAssociationsFactory } from '../factories/product-associations/product-associations.factory.js';
|
|
31
24
|
|
|
32
|
-
export class CommercetoolsProductAssociationsProvider
|
|
25
|
+
export class CommercetoolsProductAssociationsProvider<
|
|
26
|
+
TFactory extends ProductAssociationsFactory = CommercetoolsProductAssociationsFactory,
|
|
27
|
+
> extends ProductAssociationsProvider<ProductAssociationsFactoryOutput<TFactory>> {
|
|
33
28
|
protected config: CommercetoolsConfiguration;
|
|
34
29
|
protected commercetools: CommercetoolsAPI;
|
|
30
|
+
protected factory: ProductAssociationsFactoryWithOutput<TFactory>;
|
|
35
31
|
|
|
36
32
|
constructor(
|
|
37
33
|
config: CommercetoolsConfiguration,
|
|
38
34
|
cache: Cache,
|
|
39
35
|
context: RequestContext,
|
|
40
|
-
commercetools: CommercetoolsAPI
|
|
36
|
+
commercetools: CommercetoolsAPI,
|
|
37
|
+
factory: ProductAssociationsFactoryWithOutput<TFactory>,
|
|
41
38
|
) {
|
|
42
39
|
super(cache, context);
|
|
43
40
|
this.config = config;
|
|
44
41
|
this.commercetools = commercetools;
|
|
42
|
+
this.factory = factory;
|
|
45
43
|
}
|
|
46
44
|
|
|
47
45
|
protected async getClient() {
|
|
@@ -49,7 +47,7 @@ export class CommercetoolsProductAssociationsProvider extends ProductAssociation
|
|
|
49
47
|
return client.withProjectKey({ projectKey: this.config.projectKey });
|
|
50
48
|
}
|
|
51
49
|
|
|
52
|
-
protected async fetchAssociatedProductsFor(productKey: ProductIdentifier, maxNumberOfAssociations: number, attributeName: string): Promise<
|
|
50
|
+
protected async fetchAssociatedProductsFor(productKey: ProductIdentifier, maxNumberOfAssociations: number, attributeName: string): Promise<ProductProjection[]> {
|
|
53
51
|
const client = await this.getClient();
|
|
54
52
|
|
|
55
53
|
const product = await client
|
|
@@ -74,7 +72,7 @@ export class CommercetoolsProductAssociationsProvider extends ProductAssociation
|
|
|
74
72
|
if (!associationsAttr) {
|
|
75
73
|
return [];
|
|
76
74
|
}
|
|
77
|
-
const associatedProductSearchItems:
|
|
75
|
+
const associatedProductSearchItems: ProductProjection[] = [];
|
|
78
76
|
|
|
79
77
|
// look up each associated product,
|
|
80
78
|
const allAssociatedProductPromises = (associationsAttr.value as string[]).map(async (associatedProductId) => {
|
|
@@ -90,34 +88,12 @@ export class CommercetoolsProductAssociationsProvider extends ProductAssociation
|
|
|
90
88
|
const associatedProductsResults = await Promise.all(allAssociatedProductPromises);
|
|
91
89
|
const validAssociatedProductsResults = associatedProductsResults.filter(result => !!result).slice(0, maxNumberOfAssociations);
|
|
92
90
|
for (const associatedProductResult of validAssociatedProductsResults) {
|
|
93
|
-
|
|
94
|
-
if (resultItem) {
|
|
95
|
-
associatedProductSearchItems.push(resultItem);
|
|
96
|
-
}
|
|
91
|
+
associatedProductSearchItems.push(associatedProductResult.body);
|
|
97
92
|
}
|
|
98
93
|
return associatedProductSearchItems;
|
|
99
94
|
}
|
|
100
95
|
|
|
101
96
|
|
|
102
|
-
protected parseSingle(body: ProductProjection) {
|
|
103
|
-
const identifier = { key: body.id };
|
|
104
|
-
const name = body.name[this.context.languageContext.locale] || body.id;
|
|
105
|
-
const slug = body.slug?.[this.context.languageContext.locale] || body.id;
|
|
106
|
-
const variants = [body.masterVariant, ...body.variants].map((variant) =>
|
|
107
|
-
this.parseVariant(variant, body)
|
|
108
|
-
);
|
|
109
|
-
|
|
110
|
-
const product = {
|
|
111
|
-
identifier,
|
|
112
|
-
name,
|
|
113
|
-
slug,
|
|
114
|
-
variants,
|
|
115
|
-
} satisfies ProductSearchResultItem;
|
|
116
|
-
|
|
117
|
-
return product;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
|
|
121
97
|
@Reactionary({
|
|
122
98
|
cache: true,
|
|
123
99
|
cacheTimeToLiveInSeconds: 300,
|
|
@@ -126,17 +102,17 @@ export class CommercetoolsProductAssociationsProvider extends ProductAssociation
|
|
|
126
102
|
})
|
|
127
103
|
public override async getAccessories(
|
|
128
104
|
query: ProductAssociationsGetAccessoriesQuery
|
|
129
|
-
): Promise<Result<
|
|
105
|
+
): Promise<Result<ProductAssociationsFactoryOutput<TFactory>[]>> {
|
|
130
106
|
|
|
131
107
|
const associatedProducts = await this.fetchAssociatedProductsFor(query.forProduct, query.numberOfAccessories || 4, 'reactionaryaccessories');
|
|
132
108
|
|
|
133
|
-
const result
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
109
|
+
const result = associatedProducts.map((product) =>
|
|
110
|
+
this.factory.parseAssociation(this.context, {
|
|
111
|
+
sourceProductKey: query.forProduct.key,
|
|
112
|
+
relation: 'accessory',
|
|
113
|
+
product,
|
|
114
|
+
}),
|
|
115
|
+
);
|
|
140
116
|
|
|
141
117
|
return success(result);
|
|
142
118
|
}
|
|
@@ -149,16 +125,16 @@ export class CommercetoolsProductAssociationsProvider extends ProductAssociation
|
|
|
149
125
|
})
|
|
150
126
|
public override async getSpareparts(
|
|
151
127
|
query: ProductAssociationsGetSparepartsQuery
|
|
152
|
-
): Promise<Result<
|
|
128
|
+
): Promise<Result<ProductAssociationsFactoryOutput<TFactory>[]>> {
|
|
153
129
|
const associatedProducts = await this.fetchAssociatedProductsFor(query.forProduct, query.numberOfSpareparts || 4, 'reactionaryspareparts');
|
|
154
130
|
|
|
155
|
-
const result
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
131
|
+
const result = associatedProducts.map((product) =>
|
|
132
|
+
this.factory.parseAssociation(this.context, {
|
|
133
|
+
sourceProductKey: query.forProduct.key,
|
|
134
|
+
relation: 'sparepart',
|
|
135
|
+
product,
|
|
136
|
+
}),
|
|
137
|
+
);
|
|
162
138
|
|
|
163
139
|
return success(result);
|
|
164
140
|
}
|
|
@@ -171,59 +147,18 @@ export class CommercetoolsProductAssociationsProvider extends ProductAssociation
|
|
|
171
147
|
})
|
|
172
148
|
public override async getReplacements(
|
|
173
149
|
query: ProductAssociationsGetReplacementsQuery
|
|
174
|
-
): Promise<Result<
|
|
150
|
+
): Promise<Result<ProductAssociationsFactoryOutput<TFactory>[]>> {
|
|
175
151
|
const associatedProducts = await this.fetchAssociatedProductsFor(query.forProduct, query.numberOfReplacements || 4, 'reactionaryreplacements');
|
|
176
152
|
|
|
177
|
-
const result
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
153
|
+
const result = associatedProducts.map((product) =>
|
|
154
|
+
this.factory.parseAssociation(this.context, {
|
|
155
|
+
sourceProductKey: query.forProduct.key,
|
|
156
|
+
relation: 'replacement',
|
|
157
|
+
product,
|
|
158
|
+
}),
|
|
159
|
+
);
|
|
184
160
|
|
|
185
161
|
return success(result);
|
|
186
162
|
}
|
|
187
163
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
protected parseVariant(
|
|
192
|
-
variant: CTProductVariant,
|
|
193
|
-
product: ProductProjection
|
|
194
|
-
): ProductSearchResultItemVariant {
|
|
195
|
-
const sourceImage = variant.images?.[0];
|
|
196
|
-
|
|
197
|
-
const img = ImageSchema.parse({
|
|
198
|
-
sourceUrl: sourceImage?.url || '',
|
|
199
|
-
height: sourceImage?.dimensions.h || undefined,
|
|
200
|
-
width: sourceImage?.dimensions.w || undefined,
|
|
201
|
-
altText:
|
|
202
|
-
sourceImage?.label ||
|
|
203
|
-
product.name[this.context.languageContext.locale] ||
|
|
204
|
-
undefined,
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
const mappedOptions =
|
|
208
|
-
variant.attributes
|
|
209
|
-
?.filter((x) => x.name === 'Color')
|
|
210
|
-
.map((opt) =>
|
|
211
|
-
ProductVariantOptionSchema.parse({
|
|
212
|
-
identifier: ProductOptionIdentifierSchema.parse({
|
|
213
|
-
key: opt.name,
|
|
214
|
-
} satisfies Partial<ProductOptionIdentifier>),
|
|
215
|
-
name: opt.value || '',
|
|
216
|
-
} satisfies Partial<ProductVariantOption>)
|
|
217
|
-
) || [];
|
|
218
|
-
|
|
219
|
-
const mappedOption = mappedOptions?.[0];
|
|
220
|
-
|
|
221
|
-
return ProductSearchResultItemVariantSchema.parse({
|
|
222
|
-
variant: ProductVariantIdentifierSchema.parse({
|
|
223
|
-
sku: variant.sku || '',
|
|
224
|
-
} satisfies ProductVariantIdentifier),
|
|
225
|
-
image: img,
|
|
226
|
-
options: mappedOption,
|
|
227
|
-
} satisfies Partial<ProductSearchResultItemVariant>);
|
|
228
|
-
}
|
|
229
164
|
}
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import type { MyShoppingListAddLineItemAction, MyShoppingListDraft, MyShoppingListUpdate, MyShoppingListUpdateAction, ShoppingList, ShoppingListLineItem } from '@commercetools/platform-sdk';
|
|
2
2
|
import type {
|
|
3
3
|
Cache,
|
|
4
|
+
ProductListFactory,
|
|
5
|
+
ProductListFactoryItemOutput,
|
|
6
|
+
ProductListFactoryItemPaginatedOutput,
|
|
7
|
+
ProductListFactoryListOutput,
|
|
8
|
+
ProductListFactoryListPaginatedOutput,
|
|
9
|
+
ProductListFactoryWithOutput,
|
|
4
10
|
NotFoundError,
|
|
5
11
|
ProductList,
|
|
6
12
|
ProductListIdentifier,
|
|
@@ -8,12 +14,10 @@ import type {
|
|
|
8
14
|
ProductListItemMutationCreate,
|
|
9
15
|
ProductListItemMutationDelete,
|
|
10
16
|
ProductListItemMutationUpdate,
|
|
11
|
-
ProductListItemPaginatedResult,
|
|
12
17
|
ProductListItemsQuery,
|
|
13
18
|
ProductListMutationCreate,
|
|
14
19
|
ProductListMutationDelete,
|
|
15
20
|
ProductListMutationUpdate,
|
|
16
|
-
ProductListPaginatedResult,
|
|
17
21
|
ProductListQuery,
|
|
18
22
|
ProductListQueryById,
|
|
19
23
|
ProductListType,
|
|
@@ -42,20 +46,31 @@ import {
|
|
|
42
46
|
} from '@reactionary/core';
|
|
43
47
|
import type { CommercetoolsAPI } from '../core/client.js';
|
|
44
48
|
import type { CommercetoolsConfiguration } from '../schema/configuration.schema.js';
|
|
45
|
-
|
|
46
|
-
|
|
49
|
+
import type { CommercetoolsProductListFactory } from '../factories/product-list/product-list.factory.js';
|
|
50
|
+
|
|
51
|
+
export class CommercetoolsProductListProvider<
|
|
52
|
+
TFactory extends ProductListFactory = CommercetoolsProductListFactory,
|
|
53
|
+
> extends ProductListProvider<
|
|
54
|
+
ProductListFactoryListOutput<TFactory>,
|
|
55
|
+
ProductListFactoryItemOutput<TFactory>,
|
|
56
|
+
ProductListFactoryListPaginatedOutput<TFactory>,
|
|
57
|
+
ProductListFactoryItemPaginatedOutput<TFactory>
|
|
58
|
+
> {
|
|
47
59
|
protected config: CommercetoolsConfiguration;
|
|
48
60
|
protected commercetools: CommercetoolsAPI;
|
|
61
|
+
protected factory: ProductListFactoryWithOutput<TFactory>;
|
|
49
62
|
|
|
50
63
|
constructor(
|
|
51
64
|
config: CommercetoolsConfiguration,
|
|
52
65
|
cache: Cache,
|
|
53
66
|
context: RequestContext,
|
|
54
|
-
commercetools: CommercetoolsAPI
|
|
67
|
+
commercetools: CommercetoolsAPI,
|
|
68
|
+
factory: ProductListFactoryWithOutput<TFactory>,
|
|
55
69
|
) {
|
|
56
70
|
super(cache, context);
|
|
57
71
|
this.config = config;
|
|
58
72
|
this.commercetools = commercetools;
|
|
73
|
+
this.factory = factory;
|
|
59
74
|
}
|
|
60
75
|
|
|
61
76
|
protected async getClient() {
|
|
@@ -71,7 +86,7 @@ export class CommercetoolsProductListProvider extends ProductListProvider {
|
|
|
71
86
|
inputSchema: ProductListQueryByIdSchema,
|
|
72
87
|
outputSchema: ProductListSchema
|
|
73
88
|
})
|
|
74
|
-
public override async getById(payload: ProductListQueryById): Promise<Result<
|
|
89
|
+
public override async getById(payload: ProductListQueryById): Promise<Result<ProductListFactoryListOutput<TFactory>>> {
|
|
75
90
|
try {
|
|
76
91
|
const client = await this.getClient();
|
|
77
92
|
const response = await client.shoppingLists()
|
|
@@ -79,7 +94,7 @@ export class CommercetoolsProductListProvider extends ProductListProvider {
|
|
|
79
94
|
.get()
|
|
80
95
|
.execute();
|
|
81
96
|
|
|
82
|
-
return success(this.parseSingle(response.body));
|
|
97
|
+
return success(this.factory.parseProductList(this.context, this.parseSingle(response.body)));
|
|
83
98
|
} catch(err: any) {
|
|
84
99
|
if (err.statusCode === 404) {
|
|
85
100
|
return error<NotFoundError>({
|
|
@@ -101,17 +116,17 @@ export class CommercetoolsProductListProvider extends ProductListProvider {
|
|
|
101
116
|
inputSchema: ProductListQuerySchema,
|
|
102
117
|
outputSchema: ProductListPaginatedResultsSchema
|
|
103
118
|
})
|
|
104
|
-
public override async queryLists(payload: ProductListQuery): Promise<Result<
|
|
119
|
+
public override async queryLists(payload: ProductListQuery): Promise<Result<ProductListFactoryListPaginatedOutput<TFactory>>> {
|
|
105
120
|
|
|
106
121
|
if (this.context.session.identityContext?.identity?.type !== 'Registered') {
|
|
107
|
-
return success({
|
|
122
|
+
return success(this.factory.parseProductListPaginatedResult(this.context, {
|
|
108
123
|
items: [],
|
|
109
124
|
pageNumber: 1,
|
|
110
125
|
pageSize: payload.search.paginationOptions.pageSize,
|
|
111
126
|
totalCount: 0,
|
|
112
127
|
totalPages: 0,
|
|
113
128
|
identifier: payload.search,
|
|
114
|
-
});
|
|
129
|
+
}));
|
|
115
130
|
}
|
|
116
131
|
|
|
117
132
|
const client = await this.getClient();
|
|
@@ -125,14 +140,14 @@ export class CommercetoolsProductListProvider extends ProductListProvider {
|
|
|
125
140
|
}
|
|
126
141
|
}).execute();
|
|
127
142
|
|
|
128
|
-
return success({
|
|
143
|
+
return success(this.factory.parseProductListPaginatedResult(this.context, {
|
|
129
144
|
items: response.body.results.map(list => this.parseSingle(list)),
|
|
130
145
|
pageNumber: payload.search.paginationOptions.pageNumber,
|
|
131
146
|
pageSize: payload.search.paginationOptions.pageSize,
|
|
132
147
|
totalCount: response.body.total || 0,
|
|
133
148
|
totalPages: Math.ceil((response.body.total || 0) / payload.search.paginationOptions.pageSize),
|
|
134
149
|
identifier: payload.search,
|
|
135
|
-
});
|
|
150
|
+
}));
|
|
136
151
|
|
|
137
152
|
}
|
|
138
153
|
|
|
@@ -141,7 +156,7 @@ export class CommercetoolsProductListProvider extends ProductListProvider {
|
|
|
141
156
|
inputSchema: ProductListMutationCreateSchema,
|
|
142
157
|
outputSchema: ProductListSchema
|
|
143
158
|
})
|
|
144
|
-
public override async addList(mutation: ProductListMutationCreate): Promise<Result<
|
|
159
|
+
public override async addList(mutation: ProductListMutationCreate): Promise<Result<ProductListFactoryListOutput<TFactory>>> {
|
|
145
160
|
const client = await this.getClient();
|
|
146
161
|
const localeString = this.getLocaleString();
|
|
147
162
|
|
|
@@ -174,7 +189,7 @@ export class CommercetoolsProductListProvider extends ProductListProvider {
|
|
|
174
189
|
body: draft
|
|
175
190
|
}).execute();
|
|
176
191
|
|
|
177
|
-
return success(this.parseSingle(response.body));
|
|
192
|
+
return success(this.factory.parseProductList(this.context, this.parseSingle(response.body)));
|
|
178
193
|
}
|
|
179
194
|
|
|
180
195
|
@Reactionary({
|
|
@@ -182,7 +197,7 @@ export class CommercetoolsProductListProvider extends ProductListProvider {
|
|
|
182
197
|
inputSchema: ProductListMutationUpdateSchema,
|
|
183
198
|
outputSchema: ProductListSchema
|
|
184
199
|
})
|
|
185
|
-
public override async updateList(mutation: ProductListMutationUpdate): Promise<Result<
|
|
200
|
+
public override async updateList(mutation: ProductListMutationUpdate): Promise<Result<ProductListFactoryListOutput<TFactory>>> {
|
|
186
201
|
const client = await this.getClient();
|
|
187
202
|
const actions: MyShoppingListUpdateAction[] = [];
|
|
188
203
|
const localeString = this.getLocaleString()
|
|
@@ -234,7 +249,7 @@ export class CommercetoolsProductListProvider extends ProductListProvider {
|
|
|
234
249
|
.post({ body: update })
|
|
235
250
|
.execute();
|
|
236
251
|
|
|
237
|
-
return success(this.parseSingle(response.body));
|
|
252
|
+
return success(this.factory.parseProductList(this.context, this.parseSingle(response.body)));
|
|
238
253
|
}
|
|
239
254
|
|
|
240
255
|
@Reactionary({
|
|
@@ -270,7 +285,7 @@ export class CommercetoolsProductListProvider extends ProductListProvider {
|
|
|
270
285
|
inputSchema: ProductListItemQuerySchema,
|
|
271
286
|
outputSchema: ProductListItemPaginatedResultsSchema
|
|
272
287
|
})
|
|
273
|
-
public override async queryListItems(query: ProductListItemsQuery): Promise<Result<
|
|
288
|
+
public override async queryListItems(query: ProductListItemsQuery): Promise<Result<ProductListFactoryItemPaginatedOutput<TFactory>>> {
|
|
274
289
|
const client = await this.getClient();
|
|
275
290
|
|
|
276
291
|
const response = await client.shoppingLists()
|
|
@@ -282,14 +297,14 @@ export class CommercetoolsProductListProvider extends ProductListProvider {
|
|
|
282
297
|
|
|
283
298
|
const items = response.body.lineItems.map(lineItem => this.parseProductListItem(query.search.list, lineItem ));
|
|
284
299
|
|
|
285
|
-
return success({
|
|
300
|
+
return success(this.factory.parseProductListItemPaginatedResult(this.context, {
|
|
286
301
|
items: items.slice((query.search.paginationOptions.pageNumber - 1) * query.search.paginationOptions.pageSize, query.search.paginationOptions.pageNumber * query.search.paginationOptions.pageSize),
|
|
287
302
|
identifier: query.search,
|
|
288
303
|
pageNumber: query.search.paginationOptions.pageNumber,
|
|
289
304
|
pageSize: query.search.paginationOptions.pageSize,
|
|
290
305
|
totalCount: items.length,
|
|
291
306
|
totalPages: Math.ceil(items.length / query.search.paginationOptions.pageSize),
|
|
292
|
-
});
|
|
307
|
+
}));
|
|
293
308
|
}
|
|
294
309
|
|
|
295
310
|
@Reactionary({
|
|
@@ -297,7 +312,7 @@ export class CommercetoolsProductListProvider extends ProductListProvider {
|
|
|
297
312
|
inputSchema: ProductListItemMutationCreateSchema,
|
|
298
313
|
outputSchema: ProductListItemSchema
|
|
299
314
|
})
|
|
300
|
-
public override async addItem(mutation: ProductListItemMutationCreate): Promise<Result<
|
|
315
|
+
public override async addItem(mutation: ProductListItemMutationCreate): Promise<Result<ProductListFactoryItemOutput<TFactory>>> {
|
|
301
316
|
const client = await this.getClient();
|
|
302
317
|
|
|
303
318
|
const lineItemDraft: MyShoppingListAddLineItemAction = {
|
|
@@ -331,7 +346,7 @@ export class CommercetoolsProductListProvider extends ProductListProvider {
|
|
|
331
346
|
throw new Error('The added line item is not the last item in the list, cannot reliably determine the identifier of the added item');
|
|
332
347
|
}
|
|
333
348
|
|
|
334
|
-
return success(this.parseProductListItem(mutation.list, lastItem
|
|
349
|
+
return success(this.factory.parseProductListItem(this.context, this.parseProductListItem(mutation.list, lastItem)));
|
|
335
350
|
}
|
|
336
351
|
|
|
337
352
|
@Reactionary({
|
|
@@ -363,7 +378,7 @@ export class CommercetoolsProductListProvider extends ProductListProvider {
|
|
|
363
378
|
inputSchema: ProductListItemMutationUpdateSchema,
|
|
364
379
|
outputSchema: ProductListItemSchema
|
|
365
380
|
})
|
|
366
|
-
public override async updateItem(mutation: ProductListItemMutationUpdate): Promise<Result<
|
|
381
|
+
public override async updateItem(mutation: ProductListItemMutationUpdate): Promise<Result<ProductListFactoryItemOutput<TFactory>>> {
|
|
367
382
|
const client = await this.getClient();
|
|
368
383
|
|
|
369
384
|
const actions: MyShoppingListUpdateAction[] = [];
|
|
@@ -408,7 +423,7 @@ export class CommercetoolsProductListProvider extends ProductListProvider {
|
|
|
408
423
|
throw new Error('Failed to find the updated line item in response');
|
|
409
424
|
}
|
|
410
425
|
|
|
411
|
-
return success(this.parseProductListItem(mutation.listItem.list, updatedLineItem));
|
|
426
|
+
return success(this.factory.parseProductListItem(this.context, this.parseProductListItem(mutation.listItem.list, updatedLineItem)));
|
|
412
427
|
}
|
|
413
428
|
|
|
414
429
|
/**
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
|
+
type ProductReviewsFactory,
|
|
3
|
+
type ProductReviewsFactoryRatingOutput,
|
|
4
|
+
type ProductReviewsFactoryReviewOutput,
|
|
5
|
+
type ProductReviewsFactoryReviewPaginatedOutput,
|
|
6
|
+
type ProductReviewsFactoryWithOutput,
|
|
2
7
|
ProductReviewsProvider,
|
|
3
8
|
Reactionary,
|
|
4
9
|
success,
|
|
@@ -8,9 +13,8 @@ import {
|
|
|
8
13
|
ProductReviewPaginatedResultSchema,
|
|
9
14
|
} from '@reactionary/core';
|
|
10
15
|
import type {
|
|
11
|
-
ProductReview,
|
|
12
16
|
ProductRatingSummary,
|
|
13
|
-
|
|
17
|
+
ProductReview,
|
|
14
18
|
ProductReviewsListQuery,
|
|
15
19
|
ProductReviewsGetRatingSummaryQuery,
|
|
16
20
|
ProductReviewMutationSubmit,
|
|
@@ -23,20 +27,30 @@ import type {
|
|
|
23
27
|
import type { CommercetoolsConfiguration } from '../schema/configuration.schema.js';
|
|
24
28
|
import type { CommercetoolsAPI } from '../core/client.js';
|
|
25
29
|
import type { Review as CTReview } from '@commercetools/platform-sdk';
|
|
30
|
+
import type { CommercetoolsProductReviewsFactory } from '../factories/product-reviews/product-reviews.factory.js';
|
|
26
31
|
|
|
27
|
-
export class CommercetoolsProductReviewsProvider
|
|
32
|
+
export class CommercetoolsProductReviewsProvider<
|
|
33
|
+
TFactory extends ProductReviewsFactory = CommercetoolsProductReviewsFactory,
|
|
34
|
+
> extends ProductReviewsProvider<
|
|
35
|
+
ProductReviewsFactoryRatingOutput<TFactory>,
|
|
36
|
+
ProductReviewsFactoryReviewPaginatedOutput<TFactory>,
|
|
37
|
+
ProductReviewsFactoryReviewOutput<TFactory>
|
|
38
|
+
> {
|
|
28
39
|
protected config: CommercetoolsConfiguration;
|
|
29
40
|
protected commercetools: CommercetoolsAPI;
|
|
41
|
+
protected factory: ProductReviewsFactoryWithOutput<TFactory>;
|
|
30
42
|
|
|
31
43
|
constructor(
|
|
32
44
|
config: CommercetoolsConfiguration,
|
|
33
45
|
cache: Cache,
|
|
34
46
|
context: RequestContext,
|
|
35
|
-
commercetools: CommercetoolsAPI
|
|
47
|
+
commercetools: CommercetoolsAPI,
|
|
48
|
+
factory: ProductReviewsFactoryWithOutput<TFactory>,
|
|
36
49
|
) {
|
|
37
50
|
super(cache, context);
|
|
38
51
|
this.config = config;
|
|
39
52
|
this.commercetools = commercetools;
|
|
53
|
+
this.factory = factory;
|
|
40
54
|
}
|
|
41
55
|
|
|
42
56
|
protected async getClient() {
|
|
@@ -58,7 +72,7 @@ export class CommercetoolsProductReviewsProvider extends ProductReviewsProvider
|
|
|
58
72
|
})
|
|
59
73
|
public override async getRatingSummary(
|
|
60
74
|
query: ProductReviewsGetRatingSummaryQuery
|
|
61
|
-
): Promise<Result<
|
|
75
|
+
): Promise<Result<ProductReviewsFactoryRatingOutput<TFactory>>> {
|
|
62
76
|
const client = await this.getClient();
|
|
63
77
|
|
|
64
78
|
// Get all reviews for the product to calculate summary
|
|
@@ -80,6 +94,7 @@ export class CommercetoolsProductReviewsProvider extends ProductReviewsProvider
|
|
|
80
94
|
},
|
|
81
95
|
averageRating: 0,
|
|
82
96
|
totalRatings: 0,
|
|
97
|
+
ratingDistribution: undefined,
|
|
83
98
|
}
|
|
84
99
|
|
|
85
100
|
if (response.body.reviewRatingStatistics) {
|
|
@@ -93,9 +108,14 @@ export class CommercetoolsProductReviewsProvider extends ProductReviewsProvider
|
|
|
93
108
|
'5': response.body.reviewRatingStatistics.ratingsDistribution['5'] ?? 0,
|
|
94
109
|
};
|
|
95
110
|
}
|
|
96
|
-
return success(summary);
|
|
111
|
+
return success(this.factory.parseRatingSummary(this.context, summary));
|
|
97
112
|
} else {
|
|
98
|
-
return success(
|
|
113
|
+
return success(
|
|
114
|
+
this.factory.parseRatingSummary(
|
|
115
|
+
this.context,
|
|
116
|
+
this.createEmptyProductRatingSummary({ product: query.product }),
|
|
117
|
+
),
|
|
118
|
+
);
|
|
99
119
|
}
|
|
100
120
|
}
|
|
101
121
|
|
|
@@ -108,7 +128,7 @@ export class CommercetoolsProductReviewsProvider extends ProductReviewsProvider
|
|
|
108
128
|
})
|
|
109
129
|
public override async findReviews(
|
|
110
130
|
query: ProductReviewsListQuery
|
|
111
|
-
): Promise<Result<
|
|
131
|
+
): Promise<Result<ProductReviewsFactoryReviewPaginatedOutput<TFactory>>> {
|
|
112
132
|
const client = await this.getClient();
|
|
113
133
|
|
|
114
134
|
const pageNumber = query.paginationOptions?.pageNumber ?? 1;
|
|
@@ -124,13 +144,13 @@ export class CommercetoolsProductReviewsProvider extends ProductReviewsProvider
|
|
|
124
144
|
});
|
|
125
145
|
|
|
126
146
|
if (!product || !product.body) {
|
|
127
|
-
return success({
|
|
147
|
+
return success(this.factory.parseReviewPaginatedResult(this.context, {
|
|
128
148
|
items: [],
|
|
129
149
|
totalCount: 0,
|
|
130
150
|
pageSize,
|
|
131
151
|
pageNumber,
|
|
132
152
|
totalPages: 0,
|
|
133
|
-
})
|
|
153
|
+
}));
|
|
134
154
|
}
|
|
135
155
|
|
|
136
156
|
// Build where clause
|
|
@@ -175,7 +195,7 @@ export class CommercetoolsProductReviewsProvider extends ProductReviewsProvider
|
|
|
175
195
|
const reviews = response.body.results.map((review) =>
|
|
176
196
|
this.parseSingle(review, query.product.key)
|
|
177
197
|
);
|
|
178
|
-
const returnedResult
|
|
198
|
+
const returnedResult = {
|
|
179
199
|
items: reviews,
|
|
180
200
|
totalCount: response.body.total || reviews.length,
|
|
181
201
|
pageSize,
|
|
@@ -183,7 +203,7 @@ export class CommercetoolsProductReviewsProvider extends ProductReviewsProvider
|
|
|
183
203
|
totalPages: Math.ceil((response.body.total || reviews.length) / Math.max(pageSize, 1)),
|
|
184
204
|
};
|
|
185
205
|
|
|
186
|
-
return success(returnedResult);
|
|
206
|
+
return success(this.factory.parseReviewPaginatedResult(this.context, returnedResult));
|
|
187
207
|
}
|
|
188
208
|
|
|
189
209
|
@Reactionary({
|
|
@@ -195,7 +215,7 @@ export class CommercetoolsProductReviewsProvider extends ProductReviewsProvider
|
|
|
195
215
|
})
|
|
196
216
|
public override async submitReview(
|
|
197
217
|
mutation: ProductReviewMutationSubmit
|
|
198
|
-
): Promise<Result<
|
|
218
|
+
): Promise<Result<ProductReviewsFactoryReviewOutput<TFactory>>> {
|
|
199
219
|
|
|
200
220
|
|
|
201
221
|
if (!(this.context.session.identityContext.identity.type === 'Registered')) {
|
|
@@ -227,7 +247,7 @@ export class CommercetoolsProductReviewsProvider extends ProductReviewsProvider
|
|
|
227
247
|
|
|
228
248
|
const review = this.parseSingle(response.body, mutation.product.key);
|
|
229
249
|
|
|
230
|
-
return success(review);
|
|
250
|
+
return success(this.factory.parseReview(this.context, review));
|
|
231
251
|
}
|
|
232
252
|
|
|
233
253
|
protected parseSingle(review: CTReview, productKey: string): ProductReview {
|