@reactionary/provider-commercetools 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/core/capability-descriptors.js +274 -0
- package/core/initialize.js +26 -135
- package/core/initialize.types.js +8 -0
- package/factories/cart/cart.factory.js +108 -0
- package/factories/category/category.factory.js +38 -0
- package/factories/checkout/checkout-initializer-overrides.example.js +67 -0
- package/factories/checkout/checkout.factory.js +232 -0
- package/factories/identity/identity.factory.js +13 -0
- package/factories/inventory/inventory.factory.js +29 -0
- package/factories/order/order.factory.js +113 -0
- package/factories/order-search/order-search.factory.js +67 -0
- package/factories/price/price.factory.js +51 -0
- package/factories/product/product-factory-baseline.example.js +10 -0
- package/factories/product/product-factory-schema-and-parse-extension.example.js +25 -0
- package/factories/product/product-factory-schema-extension.example.js +18 -0
- package/factories/product/product-initializer-factory-extension.example.js +33 -0
- package/factories/product/product-provider-custom-method-only.example.js +38 -0
- package/factories/product/product-provider-schema-signature-extension.example.js +46 -0
- package/factories/product/product.factory.js +150 -0
- package/factories/product/utils.example.js +8 -0
- package/factories/product-associations/product-associations.factory.js +62 -0
- package/factories/product-list/product-list.factory.js +61 -0
- package/factories/product-reviews/product-reviews.factory.js +39 -0
- package/factories/product-search/product-search.factory.js +113 -0
- package/factories/profile/profile.factory.js +61 -0
- package/factories/store/store.factory.js +28 -0
- package/index.js +15 -0
- package/package.json +2 -2
- package/providers/cart.provider.js +14 -126
- package/providers/category.provider.js +9 -41
- package/providers/checkout.provider.js +20 -233
- package/providers/identity.provider.js +22 -9
- package/providers/inventory.provider.js +3 -21
- package/providers/order-search.provider.js +4 -76
- package/providers/order.provider.js +3 -111
- package/providers/price.provider.js +15 -35
- package/providers/product-associations.provider.js +24 -71
- package/providers/product-list.provider.js +13 -12
- package/providers/product-reviews.provider.js +15 -8
- package/providers/product-search.provider.js +4 -112
- package/providers/product.provider.js +5 -139
- package/providers/profile.provider.js +9 -52
- package/providers/store.provider.js +3 -20
- package/schema/capabilities.schema.js +25 -0
- package/src/core/capability-descriptors.d.ts +16 -0
- package/src/core/initialize.d.ts +3 -2
- package/src/core/initialize.types.d.ts +118 -0
- package/src/factories/cart/cart.factory.d.ts +14 -0
- package/src/factories/category/category.factory.d.ts +11 -0
- package/src/factories/checkout/checkout-initializer-overrides.example.d.ts +1 -0
- package/src/factories/checkout/checkout.factory.d.ts +18 -0
- package/src/factories/identity/identity.factory.d.ts +8 -0
- package/src/factories/inventory/inventory.factory.d.ts +9 -0
- package/src/factories/order/order.factory.d.ts +9 -0
- package/src/factories/order-search/order-search.factory.d.ts +11 -0
- package/src/factories/price/price.factory.d.ts +11 -0
- package/src/factories/product/product-factory-baseline.example.d.ts +1 -0
- package/src/factories/product/product-factory-schema-and-parse-extension.example.d.ts +1 -0
- package/src/factories/product/product-factory-schema-extension.example.d.ts +1 -0
- package/src/factories/product/product-initializer-factory-extension.example.d.ts +1 -0
- package/src/factories/product/product-provider-custom-method-only.example.d.ts +1 -0
- package/src/factories/product/product-provider-schema-signature-extension.example.d.ts +1 -0
- package/src/factories/product/product.factory.d.ts +18 -0
- package/src/factories/product/utils.example.d.ts +4 -0
- package/src/factories/product-associations/product-associations.factory.d.ts +15 -0
- package/src/factories/product-list/product-list.factory.d.ts +17 -0
- package/src/factories/product-reviews/product-reviews.factory.d.ts +14 -0
- package/src/factories/product-search/product-search.factory.d.ts +13 -0
- package/src/factories/profile/profile.factory.d.ts +11 -0
- package/src/factories/store/store.factory.d.ts +9 -0
- package/src/index.d.ts +15 -0
- package/src/providers/cart.provider.d.ts +15 -15
- package/src/providers/category.provider.d.ts +13 -23
- package/src/providers/checkout.provider.d.ts +16 -32
- package/src/providers/identity.provider.d.ts +9 -7
- package/src/providers/inventory.provider.d.ts +6 -6
- package/src/providers/order-search.provider.d.ts +7 -65
- package/src/providers/order.provider.d.ts +6 -5
- package/src/providers/price.provider.d.ts +12 -9
- package/src/providers/product-associations.provider.d.ts +11 -18
- package/src/providers/product-list.provider.d.ts +12 -10
- package/src/providers/product-reviews.provider.d.ts +9 -7
- package/src/providers/product-search.provider.d.ts +8 -51
- package/src/providers/product.provider.d.ts +9 -18
- package/src/providers/profile.provider.d.ts +13 -13
- package/src/providers/store.provider.d.ts +6 -6
- package/src/schema/capabilities.schema.d.ts +102 -17
- package/src/test/client-builder-merge-extensions.example.d.ts +1 -0
- package/test/client-builder-merge-extensions.example.js +94 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ImageSchema,
|
|
3
|
+
ProductAttributeIdentifierSchema,
|
|
4
|
+
ProductAttributeSchema,
|
|
5
|
+
ProductAttributeValueIdentifierSchema,
|
|
6
|
+
ProductAttributeValueSchema
|
|
7
|
+
} from "@reactionary/core";
|
|
8
|
+
class CommercetoolsProductFactory {
|
|
9
|
+
// PAIN: not being able to assign a default for productSchema (productSchema: TProductSchema = ProductSchema)
|
|
10
|
+
// because it will invalidate TS' conservative instantiation-point generics
|
|
11
|
+
// PAIN: consider whether we can pass in request context here
|
|
12
|
+
constructor(productSchema) {
|
|
13
|
+
this.productSchema = productSchema;
|
|
14
|
+
}
|
|
15
|
+
parseProduct(context, data) {
|
|
16
|
+
const identifier = { key: data.key || data.id };
|
|
17
|
+
const name = data.name[context.languageContext.locale];
|
|
18
|
+
const slug = data.slug[context.languageContext.locale];
|
|
19
|
+
let description = "";
|
|
20
|
+
if (data.description) {
|
|
21
|
+
description = data.description[context.languageContext.locale];
|
|
22
|
+
}
|
|
23
|
+
const variantLevelAttributes = data.masterVariant.attributes?.map(
|
|
24
|
+
(x) => this.parseAttribute(context, x)
|
|
25
|
+
) || [];
|
|
26
|
+
const specialAttributes = [
|
|
27
|
+
"reactionaryaccessories",
|
|
28
|
+
"reactionaryspareparts",
|
|
29
|
+
"reactionaryreplacements"
|
|
30
|
+
];
|
|
31
|
+
const productLevelAttributes = data.attributes.filter((x) => !specialAttributes.includes(x.name)).map((x) => this.parseAttribute(context, x)) || [];
|
|
32
|
+
const sharedAttributes = [
|
|
33
|
+
...productLevelAttributes,
|
|
34
|
+
...variantLevelAttributes
|
|
35
|
+
];
|
|
36
|
+
const mainVariant = this.parseVariant(context, data.masterVariant, data);
|
|
37
|
+
const otherVariants = [];
|
|
38
|
+
for (const variant of data.variants || []) {
|
|
39
|
+
if (variant.id !== data.masterVariant.id) {
|
|
40
|
+
otherVariants.push(this.parseVariant(context, variant, data));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const result = {
|
|
44
|
+
identifier,
|
|
45
|
+
name,
|
|
46
|
+
slug,
|
|
47
|
+
description,
|
|
48
|
+
sharedAttributes,
|
|
49
|
+
mainVariant,
|
|
50
|
+
brand: "",
|
|
51
|
+
longDescription: "",
|
|
52
|
+
manufacturer: "",
|
|
53
|
+
options: [],
|
|
54
|
+
parentCategories: [],
|
|
55
|
+
published: true,
|
|
56
|
+
variants: otherVariants
|
|
57
|
+
};
|
|
58
|
+
return this.productSchema.parse(result);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Return true, if the attribute is a defining attribute (ie an option)
|
|
62
|
+
* @param attr a variant attribute
|
|
63
|
+
* @returns true if the attribute is an option
|
|
64
|
+
*/
|
|
65
|
+
isVariantAttributeAnOption(attr) {
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
parseVariant(context, variant, product) {
|
|
69
|
+
const identifier = {
|
|
70
|
+
sku: variant.sku
|
|
71
|
+
};
|
|
72
|
+
const images = [
|
|
73
|
+
...(variant.images || []).map(
|
|
74
|
+
(img) => ImageSchema.parse({
|
|
75
|
+
sourceUrl: img.url,
|
|
76
|
+
altText: img.label || "",
|
|
77
|
+
width: img.dimensions?.w,
|
|
78
|
+
height: img.dimensions?.h
|
|
79
|
+
})
|
|
80
|
+
)
|
|
81
|
+
];
|
|
82
|
+
const options = (variant.attributes ?? []).filter((attr) => this.isVariantAttributeAnOption(attr)).map((attr) => {
|
|
83
|
+
const attrVal = this.parseAttributeValue(context, attr);
|
|
84
|
+
const optionIdentifier = {
|
|
85
|
+
key: attr.name
|
|
86
|
+
};
|
|
87
|
+
const option = {
|
|
88
|
+
identifier: optionIdentifier,
|
|
89
|
+
name: attr.name,
|
|
90
|
+
value: {
|
|
91
|
+
identifier: {
|
|
92
|
+
key: attrVal.value,
|
|
93
|
+
option: optionIdentifier
|
|
94
|
+
},
|
|
95
|
+
label: attrVal.label
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
return option;
|
|
99
|
+
}) || [];
|
|
100
|
+
const result = {
|
|
101
|
+
identifier,
|
|
102
|
+
images,
|
|
103
|
+
barcode: "",
|
|
104
|
+
ean: "",
|
|
105
|
+
gtin: "",
|
|
106
|
+
name: product.name[context.languageContext.locale],
|
|
107
|
+
options,
|
|
108
|
+
upc: ""
|
|
109
|
+
};
|
|
110
|
+
return result;
|
|
111
|
+
}
|
|
112
|
+
parseAttribute(context, attr) {
|
|
113
|
+
const result = ProductAttributeSchema.parse({
|
|
114
|
+
identifier: ProductAttributeIdentifierSchema.parse({
|
|
115
|
+
key: attr.name
|
|
116
|
+
}),
|
|
117
|
+
group: "",
|
|
118
|
+
name: attr.name,
|
|
119
|
+
values: [this.parseAttributeValue(context, attr)]
|
|
120
|
+
});
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
123
|
+
parseAttributeValue(context, attr) {
|
|
124
|
+
let attrValue = "";
|
|
125
|
+
if (attr.value && Array.isArray(attr.value)) {
|
|
126
|
+
attrValue = attr.value[0];
|
|
127
|
+
}
|
|
128
|
+
if (attr.value && typeof attr.value === "object") {
|
|
129
|
+
if (context.languageContext.locale in attr.value) {
|
|
130
|
+
attrValue = attr.value[context.languageContext.locale];
|
|
131
|
+
} else {
|
|
132
|
+
attrValue = "-";
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
if (typeof attr.value === "string") {
|
|
136
|
+
attrValue = attr.value;
|
|
137
|
+
}
|
|
138
|
+
const attrVal = ProductAttributeValueSchema.parse({
|
|
139
|
+
identifier: ProductAttributeValueIdentifierSchema.parse({
|
|
140
|
+
key: attrValue
|
|
141
|
+
}),
|
|
142
|
+
value: String(attrValue),
|
|
143
|
+
label: String(attrValue)
|
|
144
|
+
});
|
|
145
|
+
return attrVal;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
export {
|
|
149
|
+
CommercetoolsProductFactory
|
|
150
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ImageSchema,
|
|
3
|
+
ProductOptionIdentifierSchema,
|
|
4
|
+
ProductSearchResultItemVariantSchema,
|
|
5
|
+
ProductVariantIdentifierSchema,
|
|
6
|
+
ProductVariantOptionSchema
|
|
7
|
+
} from "@reactionary/core";
|
|
8
|
+
class CommercetoolsProductAssociationsFactory {
|
|
9
|
+
constructor(productAssociationSchema) {
|
|
10
|
+
this.productAssociationSchema = productAssociationSchema;
|
|
11
|
+
}
|
|
12
|
+
parseAssociation(context, data) {
|
|
13
|
+
const product = this.parseSearchResultItem(context, data.product);
|
|
14
|
+
const result = {
|
|
15
|
+
associationIdentifier: {
|
|
16
|
+
key: `${data.sourceProductKey}-${data.relation}-${product.identifier.key}`
|
|
17
|
+
},
|
|
18
|
+
associationReturnType: "productSearchResultItem",
|
|
19
|
+
product
|
|
20
|
+
};
|
|
21
|
+
return this.productAssociationSchema.parse(result);
|
|
22
|
+
}
|
|
23
|
+
parseSearchResultItem(context, data) {
|
|
24
|
+
const variants = [data.masterVariant, ...data.variants].map(
|
|
25
|
+
(variant) => this.parseVariant(context, variant, data)
|
|
26
|
+
);
|
|
27
|
+
return {
|
|
28
|
+
identifier: { key: data.id },
|
|
29
|
+
name: data.name[context.languageContext.locale] || data.id,
|
|
30
|
+
slug: data.slug?.[context.languageContext.locale] || data.id,
|
|
31
|
+
variants
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
parseVariant(context, variant, product) {
|
|
35
|
+
const sourceImage = variant.images?.[0];
|
|
36
|
+
const image = ImageSchema.parse({
|
|
37
|
+
sourceUrl: sourceImage?.url || "",
|
|
38
|
+
height: sourceImage?.dimensions.h || void 0,
|
|
39
|
+
width: sourceImage?.dimensions.w || void 0,
|
|
40
|
+
altText: sourceImage?.label || product.name[context.languageContext.locale] || void 0
|
|
41
|
+
});
|
|
42
|
+
const mappedOptions = variant.attributes?.filter((attribute) => attribute.name === "Color").map(
|
|
43
|
+
(option) => ProductVariantOptionSchema.parse({
|
|
44
|
+
identifier: ProductOptionIdentifierSchema.parse({
|
|
45
|
+
key: option.name
|
|
46
|
+
}),
|
|
47
|
+
name: option.value || ""
|
|
48
|
+
})
|
|
49
|
+
) || [];
|
|
50
|
+
const mappedOption = mappedOptions?.[0];
|
|
51
|
+
return ProductSearchResultItemVariantSchema.parse({
|
|
52
|
+
variant: ProductVariantIdentifierSchema.parse({
|
|
53
|
+
sku: variant.sku || ""
|
|
54
|
+
}),
|
|
55
|
+
image,
|
|
56
|
+
options: mappedOption
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
export {
|
|
61
|
+
CommercetoolsProductAssociationsFactory
|
|
62
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import {
|
|
2
|
+
} from "@reactionary/core";
|
|
3
|
+
class CommercetoolsProductListFactory {
|
|
4
|
+
constructor(productListSchema, productListItemSchema, productListPaginatedSchema, productListItemPaginatedSchema) {
|
|
5
|
+
this.productListSchema = productListSchema;
|
|
6
|
+
this.productListItemSchema = productListItemSchema;
|
|
7
|
+
this.productListPaginatedSchema = productListPaginatedSchema;
|
|
8
|
+
this.productListItemPaginatedSchema = productListItemPaginatedSchema;
|
|
9
|
+
}
|
|
10
|
+
parseProductList(_context, data) {
|
|
11
|
+
return this.productListSchema.parse(data);
|
|
12
|
+
}
|
|
13
|
+
parseProductListItem(_context, data) {
|
|
14
|
+
return this.productListItemSchema.parse(data);
|
|
15
|
+
}
|
|
16
|
+
parseProductListPaginatedResult(_context, data) {
|
|
17
|
+
return this.productListPaginatedSchema.parse(data);
|
|
18
|
+
}
|
|
19
|
+
parseProductListItemPaginatedResult(_context, data) {
|
|
20
|
+
return this.productListItemPaginatedSchema.parse(data);
|
|
21
|
+
}
|
|
22
|
+
parseListFromCommercetools(list) {
|
|
23
|
+
const listType = list.custom?.fields["listType"] || "favorite";
|
|
24
|
+
const image = list.custom?.fields["imageUrl"];
|
|
25
|
+
const published = list.custom?.fields["published"] && true;
|
|
26
|
+
const publishDateValue = list.custom?.fields["publishedDate"];
|
|
27
|
+
const publishDate = publishDateValue ? new Date(publishDateValue).toISOString() : void 0;
|
|
28
|
+
return this.productListSchema.parse({
|
|
29
|
+
identifier: {
|
|
30
|
+
listType,
|
|
31
|
+
key: list.id
|
|
32
|
+
},
|
|
33
|
+
type: listType,
|
|
34
|
+
name: list.name["en"] || "Unnamed List",
|
|
35
|
+
description: list.description?.["en"] || "",
|
|
36
|
+
published,
|
|
37
|
+
publishDate,
|
|
38
|
+
image: {
|
|
39
|
+
sourceUrl: image || "",
|
|
40
|
+
altText: list.name["en"] || "List Image"
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
parseListItemFromCommercetools(listIdentifier, lineItem) {
|
|
45
|
+
return this.productListItemSchema.parse({
|
|
46
|
+
identifier: {
|
|
47
|
+
list: listIdentifier,
|
|
48
|
+
key: lineItem.id
|
|
49
|
+
},
|
|
50
|
+
variant: {
|
|
51
|
+
sku: lineItem.variant?.sku || ""
|
|
52
|
+
},
|
|
53
|
+
quantity: lineItem.quantity,
|
|
54
|
+
notes: lineItem.custom?.fields["notes"] || "",
|
|
55
|
+
order: lineItem.custom?.fields["order"] || 1
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
export {
|
|
60
|
+
CommercetoolsProductListFactory
|
|
61
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import {
|
|
2
|
+
} from "@reactionary/core";
|
|
3
|
+
class CommercetoolsProductReviewsFactory {
|
|
4
|
+
constructor(ratingSummarySchema, reviewSchema, reviewPaginatedSchema) {
|
|
5
|
+
this.ratingSummarySchema = ratingSummarySchema;
|
|
6
|
+
this.reviewSchema = reviewSchema;
|
|
7
|
+
this.reviewPaginatedSchema = reviewPaginatedSchema;
|
|
8
|
+
}
|
|
9
|
+
parseRatingSummary(_context, data) {
|
|
10
|
+
return this.ratingSummarySchema.parse(data);
|
|
11
|
+
}
|
|
12
|
+
parseReview(_context, data) {
|
|
13
|
+
return this.reviewSchema.parse(data);
|
|
14
|
+
}
|
|
15
|
+
parseReviewPaginatedResult(_context, data) {
|
|
16
|
+
return this.reviewPaginatedSchema.parse(data);
|
|
17
|
+
}
|
|
18
|
+
parseReviewFromCommercetools(_context, review, productKey) {
|
|
19
|
+
return this.reviewSchema.parse({
|
|
20
|
+
identifier: {
|
|
21
|
+
key: review.key || ""
|
|
22
|
+
},
|
|
23
|
+
product: {
|
|
24
|
+
key: productKey
|
|
25
|
+
},
|
|
26
|
+
authorName: review.authorName ?? "Anonymous",
|
|
27
|
+
authorId: review.customer?.id,
|
|
28
|
+
rating: review.rating ?? 0,
|
|
29
|
+
title: review.title ?? "",
|
|
30
|
+
content: review.text ?? "",
|
|
31
|
+
createdAt: review.createdAt,
|
|
32
|
+
updatedAt: review.lastModifiedAt,
|
|
33
|
+
verified: !!review.customer
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export {
|
|
38
|
+
CommercetoolsProductReviewsFactory
|
|
39
|
+
};
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FacetIdentifierSchema,
|
|
3
|
+
FacetValueIdentifierSchema,
|
|
4
|
+
ImageSchema,
|
|
5
|
+
ProductOptionIdentifierSchema,
|
|
6
|
+
ProductSearchResultFacetSchema,
|
|
7
|
+
ProductSearchResultFacetValueSchema,
|
|
8
|
+
ProductSearchResultItemVariantSchema,
|
|
9
|
+
ProductVariantIdentifierSchema,
|
|
10
|
+
ProductVariantOptionSchema
|
|
11
|
+
} from "@reactionary/core";
|
|
12
|
+
class CommercetoolsProductSearchFactory {
|
|
13
|
+
constructor(productSearchResultSchema) {
|
|
14
|
+
this.productSearchResultSchema = productSearchResultSchema;
|
|
15
|
+
}
|
|
16
|
+
parseSearchResult(context, data, query) {
|
|
17
|
+
const identifier = {
|
|
18
|
+
...query.search
|
|
19
|
+
};
|
|
20
|
+
const items = data.results.map(
|
|
21
|
+
(product) => this.parseSingle(context, product.productProjection)
|
|
22
|
+
);
|
|
23
|
+
const facets = [];
|
|
24
|
+
for (const facet of data.facets) {
|
|
25
|
+
const facetIdentifier = FacetIdentifierSchema.parse({
|
|
26
|
+
key: facet.name
|
|
27
|
+
});
|
|
28
|
+
const candidateFacet = this.parseFacet(facetIdentifier, facet);
|
|
29
|
+
if (candidateFacet.values.length > 0) {
|
|
30
|
+
facets.push(candidateFacet);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
const result = {
|
|
34
|
+
identifier,
|
|
35
|
+
pageNumber: (Math.ceil(data.offset / data.limit) || 0) + 1,
|
|
36
|
+
pageSize: data.limit,
|
|
37
|
+
totalCount: data.total || 0,
|
|
38
|
+
totalPages: Math.ceil((data.total || 0) / data.limit || 0) + 1,
|
|
39
|
+
items,
|
|
40
|
+
facets
|
|
41
|
+
};
|
|
42
|
+
return this.productSearchResultSchema.parse(result);
|
|
43
|
+
}
|
|
44
|
+
parseSingle(context, data) {
|
|
45
|
+
const identifier = { key: data.id };
|
|
46
|
+
const name = data.name[context.languageContext.locale] || data.id;
|
|
47
|
+
const slug = data.slug?.[context.languageContext.locale] || data.id;
|
|
48
|
+
const variants = [data.masterVariant, ...data.variants].map(
|
|
49
|
+
(variant) => this.parseVariant(context, variant, data)
|
|
50
|
+
);
|
|
51
|
+
const result = {
|
|
52
|
+
identifier,
|
|
53
|
+
name,
|
|
54
|
+
slug,
|
|
55
|
+
variants
|
|
56
|
+
};
|
|
57
|
+
return result;
|
|
58
|
+
}
|
|
59
|
+
parseFacet(facetIdentifier, facet) {
|
|
60
|
+
const result = ProductSearchResultFacetSchema.parse({
|
|
61
|
+
identifier: facetIdentifier,
|
|
62
|
+
name: facet.name,
|
|
63
|
+
values: []
|
|
64
|
+
});
|
|
65
|
+
const distinctFacet = facet;
|
|
66
|
+
for (const bucket of distinctFacet.buckets || []) {
|
|
67
|
+
const facetValueIdentifier = FacetValueIdentifierSchema.parse({
|
|
68
|
+
facet: facetIdentifier,
|
|
69
|
+
key: bucket.key
|
|
70
|
+
});
|
|
71
|
+
result.values.push(
|
|
72
|
+
this.parseFacetValue(facetValueIdentifier, bucket.key, bucket.count)
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
return result;
|
|
76
|
+
}
|
|
77
|
+
parseFacetValue(facetValueIdentifier, label, count) {
|
|
78
|
+
return ProductSearchResultFacetValueSchema.parse({
|
|
79
|
+
identifier: facetValueIdentifier,
|
|
80
|
+
name: label,
|
|
81
|
+
count,
|
|
82
|
+
active: false
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
parseVariant(context, variant, product) {
|
|
86
|
+
const sourceImage = variant.images?.[0];
|
|
87
|
+
const image = ImageSchema.parse({
|
|
88
|
+
sourceUrl: sourceImage?.url || "",
|
|
89
|
+
height: sourceImage?.dimensions.h || void 0,
|
|
90
|
+
width: sourceImage?.dimensions.w || void 0,
|
|
91
|
+
altText: sourceImage?.label || product.name[context.languageContext.locale] || void 0
|
|
92
|
+
});
|
|
93
|
+
const mappedOptions = variant.attributes?.filter((attribute) => attribute.name === "Color").map(
|
|
94
|
+
(option) => ProductVariantOptionSchema.parse({
|
|
95
|
+
identifier: ProductOptionIdentifierSchema.parse({
|
|
96
|
+
key: option.name
|
|
97
|
+
}),
|
|
98
|
+
name: option.value || ""
|
|
99
|
+
})
|
|
100
|
+
) || [];
|
|
101
|
+
const mappedOption = mappedOptions?.[0];
|
|
102
|
+
return ProductSearchResultItemVariantSchema.parse({
|
|
103
|
+
variant: ProductVariantIdentifierSchema.parse({
|
|
104
|
+
sku: variant.sku || ""
|
|
105
|
+
}),
|
|
106
|
+
image,
|
|
107
|
+
options: mappedOption
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
export {
|
|
112
|
+
CommercetoolsProductSearchFactory
|
|
113
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import {
|
|
2
|
+
} from "@reactionary/core";
|
|
3
|
+
class CommercetoolsProfileFactory {
|
|
4
|
+
constructor(profileSchema) {
|
|
5
|
+
this.profileSchema = profileSchema;
|
|
6
|
+
}
|
|
7
|
+
parseProfile(_context, data) {
|
|
8
|
+
const email = data.email;
|
|
9
|
+
const emailVerified = data.isEmailVerified;
|
|
10
|
+
let defaultBilling = data.addresses.find((address) => address.id === data.defaultBillingAddressId);
|
|
11
|
+
const phone = defaultBilling?.phone ?? "";
|
|
12
|
+
if (this.isIncompleteAddress(defaultBilling)) {
|
|
13
|
+
defaultBilling = void 0;
|
|
14
|
+
}
|
|
15
|
+
const defaultShipping = data.addresses.find(
|
|
16
|
+
(address) => address.id === data.defaultShippingAddressId
|
|
17
|
+
);
|
|
18
|
+
const alternateShippingAddresses = data.addresses.filter((address) => address.id !== data.defaultBillingAddressId).filter((address) => address.id !== data.defaultShippingAddressId).map((address) => this.parseAddress(address));
|
|
19
|
+
const billingAddress = defaultBilling ? this.parseAddress(defaultBilling) : void 0;
|
|
20
|
+
const shippingAddress = defaultShipping ? this.parseAddress(defaultShipping) : void 0;
|
|
21
|
+
const result = {
|
|
22
|
+
identifier: {
|
|
23
|
+
userId: data.id
|
|
24
|
+
},
|
|
25
|
+
email,
|
|
26
|
+
emailVerified,
|
|
27
|
+
alternateShippingAddresses,
|
|
28
|
+
billingAddress,
|
|
29
|
+
shippingAddress,
|
|
30
|
+
createdAt: data.createdAt,
|
|
31
|
+
phone,
|
|
32
|
+
phoneVerified: false,
|
|
33
|
+
updatedAt: data.lastModifiedAt
|
|
34
|
+
};
|
|
35
|
+
return this.profileSchema.parse(result);
|
|
36
|
+
}
|
|
37
|
+
parseAddress(address) {
|
|
38
|
+
return {
|
|
39
|
+
identifier: {
|
|
40
|
+
nickName: address.key || ""
|
|
41
|
+
},
|
|
42
|
+
firstName: address.firstName || "",
|
|
43
|
+
lastName: address.lastName || "",
|
|
44
|
+
streetAddress: address.streetName || "",
|
|
45
|
+
streetNumber: address.streetNumber || "",
|
|
46
|
+
city: address.city || "",
|
|
47
|
+
region: address.region || "",
|
|
48
|
+
postalCode: address.postalCode || "",
|
|
49
|
+
countryCode: address.country
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
isIncompleteAddress(address) {
|
|
53
|
+
if (!address) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
return !address.firstName && !address.lastName && !address.streetName && !address.streetNumber && !address.city;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
export {
|
|
60
|
+
CommercetoolsProfileFactory
|
|
61
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import {
|
|
2
|
+
} from "@reactionary/core";
|
|
3
|
+
class CommercetoolsStoreFactory {
|
|
4
|
+
constructor(storeSchema) {
|
|
5
|
+
this.storeSchema = storeSchema;
|
|
6
|
+
}
|
|
7
|
+
parseStore(_context, data) {
|
|
8
|
+
let name = "";
|
|
9
|
+
if (data.name && data.name["la"]) {
|
|
10
|
+
name = data.name["la"];
|
|
11
|
+
}
|
|
12
|
+
const identifier = {
|
|
13
|
+
key: data.key || ""
|
|
14
|
+
};
|
|
15
|
+
const fulfillmentCenter = {
|
|
16
|
+
key: data.key || ""
|
|
17
|
+
};
|
|
18
|
+
const result = {
|
|
19
|
+
identifier,
|
|
20
|
+
fulfillmentCenter,
|
|
21
|
+
name
|
|
22
|
+
};
|
|
23
|
+
return this.storeSchema.parse(result);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export {
|
|
27
|
+
CommercetoolsStoreFactory
|
|
28
|
+
};
|
package/index.js
CHANGED
|
@@ -9,5 +9,20 @@ export * from "./providers/product-associations.provider.js";
|
|
|
9
9
|
export * from "./providers/product.provider.js";
|
|
10
10
|
export * from "./providers/product-reviews.provider.js";
|
|
11
11
|
export * from "./providers/product-search.provider.js";
|
|
12
|
+
export * from "./factories/product/product.factory.js";
|
|
13
|
+
export * from "./factories/checkout/checkout.factory.js";
|
|
14
|
+
export * from "./factories/product-search/product-search.factory.js";
|
|
15
|
+
export * from "./factories/inventory/inventory.factory.js";
|
|
16
|
+
export * from "./factories/price/price.factory.js";
|
|
17
|
+
export * from "./factories/store/store.factory.js";
|
|
18
|
+
export * from "./factories/order/order.factory.js";
|
|
19
|
+
export * from "./factories/category/category.factory.js";
|
|
20
|
+
export * from "./factories/cart/cart.factory.js";
|
|
21
|
+
export * from "./factories/profile/profile.factory.js";
|
|
22
|
+
export * from "./factories/order-search/order-search.factory.js";
|
|
23
|
+
export * from "./factories/product-associations/product-associations.factory.js";
|
|
24
|
+
export * from "./factories/product-reviews/product-reviews.factory.js";
|
|
25
|
+
export * from "./factories/product-list/product-list.factory.js";
|
|
26
|
+
export * from "./factories/identity/identity.factory.js";
|
|
12
27
|
export * from "./schema/capabilities.schema.js";
|
|
13
28
|
export * from "./schema/configuration.schema.js";
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reactionary/provider-commercetools",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.2",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"types": "src/index.d.ts",
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@reactionary/core": "0.6.
|
|
7
|
+
"@reactionary/core": "0.6.2",
|
|
8
8
|
"debug": "^4.4.3",
|
|
9
9
|
"zod": "4.1.9",
|
|
10
10
|
"@commercetools/ts-client": "^4.2.1",
|