@reactionary/commercetools 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -0
- package/capabilities/cart.capability.js +324 -0
- package/capabilities/category.capability.js +198 -0
- package/capabilities/checkout.capability.js +374 -0
- package/capabilities/identity.capability.js +95 -0
- package/capabilities/index.js +15 -0
- package/capabilities/inventory.capability.js +63 -0
- package/capabilities/order-search.capability.js +106 -0
- package/capabilities/order.capability.js +48 -0
- package/capabilities/price.capability.js +114 -0
- package/capabilities/product-associations.capability.js +120 -0
- package/capabilities/product-list.capability.js +393 -0
- package/capabilities/product-reviews.capability.js +193 -0
- package/capabilities/product-search.capability.js +297 -0
- package/capabilities/product.capability.js +103 -0
- package/capabilities/profile.capability.js +337 -0
- package/capabilities/store.capability.js +51 -0
- package/core/capability-descriptors.js +274 -0
- package/core/client.js +318 -0
- package/core/initialize.js +47 -0
- package/core/initialize.types.js +8 -0
- package/core/token-cache.js +36 -0
- package/factories/cart/cart.factory.js +110 -0
- package/factories/category/category.factory.js +40 -0
- package/factories/checkout/checkout-initializer-overrides.example.js +67 -0
- package/factories/checkout/checkout.factory.js +235 -0
- package/factories/identity/identity.factory.js +14 -0
- package/factories/inventory/inventory.factory.js +30 -0
- package/factories/order/order.factory.js +114 -0
- package/factories/order-search/order-search.factory.js +68 -0
- package/factories/price/price.factory.js +52 -0
- package/factories/product/product-capability-custom-method-only.example.js +38 -0
- package/factories/product/product-capability-schema-signature-extension.example.js +46 -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.factory.js +151 -0
- package/factories/product/utils.example.js +8 -0
- package/factories/product-associations/product-associations.factory.js +63 -0
- package/factories/product-list/product-list.factory.js +65 -0
- package/factories/product-reviews/product-reviews.factory.js +42 -0
- package/factories/product-search/product-search.factory.js +114 -0
- package/factories/profile/profile.factory.js +62 -0
- package/factories/store/store.factory.js +29 -0
- package/index.js +28 -0
- package/package.json +17 -0
- package/schema/capabilities.schema.js +46 -0
- package/schema/commercetools.schema.js +30 -0
- package/schema/configuration.schema.js +19 -0
- package/schema/session.schema.js +9 -0
- package/src/capabilities/cart.capability.d.ts +34 -0
- package/src/capabilities/category.capability.d.ts +47 -0
- package/src/capabilities/checkout.capability.d.ts +39 -0
- package/src/capabilities/identity.capability.d.ts +14 -0
- package/src/capabilities/index.d.ts +15 -0
- package/src/capabilities/inventory.capability.d.ts +13 -0
- package/src/capabilities/order-search.capability.d.ts +13 -0
- package/src/capabilities/order.capability.d.ts +13 -0
- package/src/capabilities/price.capability.d.ts +18 -0
- package/src/capabilities/product-associations.capability.d.ts +17 -0
- package/src/capabilities/product-list.capability.d.ts +29 -0
- package/src/capabilities/product-reviews.capability.d.ts +18 -0
- package/src/capabilities/product-search.capability.d.ts +82 -0
- package/src/capabilities/product.capability.d.ts +17 -0
- package/src/capabilities/profile.capability.d.ts +30 -0
- package/src/capabilities/store.capability.d.ts +13 -0
- package/src/core/capability-descriptors.d.ts +16 -0
- package/src/core/client.d.ts +55 -0
- package/src/core/initialize.d.ts +5 -0
- package/src/core/initialize.types.d.ts +118 -0
- package/src/core/token-cache.d.ts +9 -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-capability-custom-method-only.example.d.ts +1 -0
- package/src/factories/product/product-capability-schema-signature-extension.example.d.ts +1 -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.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 +28 -0
- package/src/schema/capabilities.schema.d.ts +104 -0
- package/src/schema/commercetools.schema.d.ts +30 -0
- package/src/schema/configuration.schema.d.ts +30 -0
- package/src/schema/session.schema.d.ts +7 -0
- package/src/test/client-builder-merge-extensions.example.d.ts +1 -0
- package/src/test/test-utils.d.ts +27 -0
- package/test/client-builder-merge-extensions.example.js +94 -0
- package/test/test-utils.js +27 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
4
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
5
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
6
|
+
if (decorator = decorators[i])
|
|
7
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8
|
+
if (kind && result)
|
|
9
|
+
__defProp(target, key, result);
|
|
10
|
+
return result;
|
|
11
|
+
};
|
|
12
|
+
import {
|
|
13
|
+
CustomerPriceQuerySchema,
|
|
14
|
+
ListPriceQuerySchema,
|
|
15
|
+
PriceCapability,
|
|
16
|
+
PriceSchema,
|
|
17
|
+
Reactionary,
|
|
18
|
+
success
|
|
19
|
+
} from "@reactionary/core";
|
|
20
|
+
class CommercetoolsPriceCapability extends PriceCapability {
|
|
21
|
+
config;
|
|
22
|
+
commercetools;
|
|
23
|
+
factory;
|
|
24
|
+
constructor(config, cache, context, commercetools, factory) {
|
|
25
|
+
super(cache, context);
|
|
26
|
+
this.config = config;
|
|
27
|
+
this.commercetools = commercetools;
|
|
28
|
+
this.factory = factory;
|
|
29
|
+
}
|
|
30
|
+
async getCustomerPrice(payload) {
|
|
31
|
+
const client = await this.getClient();
|
|
32
|
+
let priceChannelId;
|
|
33
|
+
if (this.config.customerPriceChannelKey) {
|
|
34
|
+
priceChannelId = await this.commercetools.resolveChannelIdByKey(this.config.customerPriceChannelKey);
|
|
35
|
+
} else {
|
|
36
|
+
priceChannelId = await this.commercetools.resolveChannelIdByRole("Primary");
|
|
37
|
+
}
|
|
38
|
+
const response = await client.productProjections().get({
|
|
39
|
+
queryArgs: {
|
|
40
|
+
staged: false,
|
|
41
|
+
priceCountry: this.context.taxJurisdiction.countryCode,
|
|
42
|
+
priceCustomerGroup: void 0,
|
|
43
|
+
priceChannel: priceChannelId,
|
|
44
|
+
priceCurrency: this.context.languageContext.currencyCode,
|
|
45
|
+
where: "variants(sku in (:skus)) OR (masterVariant(sku in (:skus))) ",
|
|
46
|
+
"var.skus": [payload.variant.sku],
|
|
47
|
+
limit: 1
|
|
48
|
+
}
|
|
49
|
+
}).execute();
|
|
50
|
+
const result = response.body.results[0];
|
|
51
|
+
const sku = [result.masterVariant, ...result.variants].find(
|
|
52
|
+
(x) => x.sku === payload.variant.sku
|
|
53
|
+
);
|
|
54
|
+
return success(this.factory.parsePrice(this.context, sku, { includeDiscounts: true }));
|
|
55
|
+
}
|
|
56
|
+
async getListPrice(payload) {
|
|
57
|
+
const client = await this.getClient();
|
|
58
|
+
let priceChannelId;
|
|
59
|
+
if (this.config.listPriceChannelKey) {
|
|
60
|
+
priceChannelId = await this.commercetools.resolveChannelIdByKey(this.config.listPriceChannelKey);
|
|
61
|
+
} else {
|
|
62
|
+
priceChannelId = await this.commercetools.resolveChannelIdByRole("Primary");
|
|
63
|
+
}
|
|
64
|
+
const response = await client.productProjections().get({
|
|
65
|
+
queryArgs: {
|
|
66
|
+
staged: false,
|
|
67
|
+
priceCountry: this.context.taxJurisdiction.countryCode,
|
|
68
|
+
priceCustomerGroup: void 0,
|
|
69
|
+
priceChannel: priceChannelId,
|
|
70
|
+
priceCurrency: this.context.languageContext.currencyCode,
|
|
71
|
+
where: "variants(sku in (:skus)) OR (masterVariant(sku in (:skus))) ",
|
|
72
|
+
"var.skus": [payload.variant.sku],
|
|
73
|
+
limit: 1
|
|
74
|
+
}
|
|
75
|
+
}).execute();
|
|
76
|
+
const result = response.body.results[0];
|
|
77
|
+
const sku = [result.masterVariant, ...result.variants].find(
|
|
78
|
+
(x) => x.sku === payload.variant.sku
|
|
79
|
+
);
|
|
80
|
+
return success(this.factory.parsePrice(this.context, sku));
|
|
81
|
+
}
|
|
82
|
+
async getClient() {
|
|
83
|
+
const client = await this.commercetools.getClient();
|
|
84
|
+
return client.withProjectKey({ projectKey: this.config.projectKey });
|
|
85
|
+
}
|
|
86
|
+
async getChannels() {
|
|
87
|
+
const adminClient = await this.commercetools.getAdminClient();
|
|
88
|
+
const offerPriceChannelPromise = adminClient.withProjectKey({ projectKey: this.config.projectKey }).channels().withKey({ key: "Offer Price" }).get().execute();
|
|
89
|
+
const listPriceChannelPromise = adminClient.withProjectKey({ projectKey: this.config.projectKey }).channels().withKey({ key: "List Price" }).get().execute();
|
|
90
|
+
const [offerChannel, listChannel] = await Promise.all([
|
|
91
|
+
offerPriceChannelPromise,
|
|
92
|
+
listPriceChannelPromise
|
|
93
|
+
]);
|
|
94
|
+
return {
|
|
95
|
+
offer: offerChannel.body.id,
|
|
96
|
+
list: listChannel.body.id
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
__decorateClass([
|
|
101
|
+
Reactionary({
|
|
102
|
+
inputSchema: CustomerPriceQuerySchema,
|
|
103
|
+
outputSchema: PriceSchema
|
|
104
|
+
})
|
|
105
|
+
], CommercetoolsPriceCapability.prototype, "getCustomerPrice", 1);
|
|
106
|
+
__decorateClass([
|
|
107
|
+
Reactionary({
|
|
108
|
+
inputSchema: ListPriceQuerySchema,
|
|
109
|
+
outputSchema: PriceSchema
|
|
110
|
+
})
|
|
111
|
+
], CommercetoolsPriceCapability.prototype, "getListPrice", 1);
|
|
112
|
+
export {
|
|
113
|
+
CommercetoolsPriceCapability
|
|
114
|
+
};
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
4
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
5
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
6
|
+
if (decorator = decorators[i])
|
|
7
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8
|
+
if (kind && result)
|
|
9
|
+
__defProp(target, key, result);
|
|
10
|
+
return result;
|
|
11
|
+
};
|
|
12
|
+
import {
|
|
13
|
+
ProductAssociationsCapability,
|
|
14
|
+
Reactionary,
|
|
15
|
+
success,
|
|
16
|
+
error
|
|
17
|
+
} from "@reactionary/core";
|
|
18
|
+
class CommercetoolsProductAssociationsCapability extends ProductAssociationsCapability {
|
|
19
|
+
config;
|
|
20
|
+
commercetools;
|
|
21
|
+
factory;
|
|
22
|
+
constructor(config, cache, context, commercetools, factory) {
|
|
23
|
+
super(cache, context);
|
|
24
|
+
this.config = config;
|
|
25
|
+
this.commercetools = commercetools;
|
|
26
|
+
this.factory = factory;
|
|
27
|
+
}
|
|
28
|
+
async getClient() {
|
|
29
|
+
const client = await this.commercetools.getClient();
|
|
30
|
+
return client.withProjectKey({ projectKey: this.config.projectKey });
|
|
31
|
+
}
|
|
32
|
+
async fetchAssociatedProductsFor(productKey, maxNumberOfAssociations, attributeName) {
|
|
33
|
+
const client = await this.getClient();
|
|
34
|
+
const product = await client.productProjections().withKey({ key: productKey.key }).get().execute().catch((e) => {
|
|
35
|
+
if (e.statusCode === 404) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
throw e;
|
|
39
|
+
});
|
|
40
|
+
if (!product || !product.body) {
|
|
41
|
+
return [];
|
|
42
|
+
}
|
|
43
|
+
const associatedProducts = [];
|
|
44
|
+
const associationsAttr = product.body.attributes.find((attr) => attr.name === attributeName);
|
|
45
|
+
if (!associationsAttr) {
|
|
46
|
+
return [];
|
|
47
|
+
}
|
|
48
|
+
const associatedProductSearchItems = [];
|
|
49
|
+
const allAssociatedProductPromises = associationsAttr.value.map(async (associatedProductId) => {
|
|
50
|
+
const associatedProduct = client.productProjections().withKey({ key: associatedProductId }).get().execute().catch(() => null);
|
|
51
|
+
return associatedProduct;
|
|
52
|
+
});
|
|
53
|
+
const associatedProductsResults = await Promise.all(allAssociatedProductPromises);
|
|
54
|
+
const validAssociatedProductsResults = associatedProductsResults.filter((result) => !!result).slice(0, maxNumberOfAssociations);
|
|
55
|
+
for (const associatedProductResult of validAssociatedProductsResults) {
|
|
56
|
+
associatedProductSearchItems.push(associatedProductResult.body);
|
|
57
|
+
}
|
|
58
|
+
return associatedProductSearchItems;
|
|
59
|
+
}
|
|
60
|
+
async getAccessories(query) {
|
|
61
|
+
const associatedProducts = await this.fetchAssociatedProductsFor(query.forProduct, query.numberOfAccessories || 4, "reactionaryaccessories");
|
|
62
|
+
const result = associatedProducts.map(
|
|
63
|
+
(product) => this.factory.parseAssociation(this.context, {
|
|
64
|
+
sourceProductKey: query.forProduct.key,
|
|
65
|
+
relation: "accessory",
|
|
66
|
+
product
|
|
67
|
+
})
|
|
68
|
+
);
|
|
69
|
+
return success(result);
|
|
70
|
+
}
|
|
71
|
+
async getSpareparts(query) {
|
|
72
|
+
const associatedProducts = await this.fetchAssociatedProductsFor(query.forProduct, query.numberOfSpareparts || 4, "reactionaryspareparts");
|
|
73
|
+
const result = associatedProducts.map(
|
|
74
|
+
(product) => this.factory.parseAssociation(this.context, {
|
|
75
|
+
sourceProductKey: query.forProduct.key,
|
|
76
|
+
relation: "sparepart",
|
|
77
|
+
product
|
|
78
|
+
})
|
|
79
|
+
);
|
|
80
|
+
return success(result);
|
|
81
|
+
}
|
|
82
|
+
async getReplacements(query) {
|
|
83
|
+
const associatedProducts = await this.fetchAssociatedProductsFor(query.forProduct, query.numberOfReplacements || 4, "reactionaryreplacements");
|
|
84
|
+
const result = associatedProducts.map(
|
|
85
|
+
(product) => this.factory.parseAssociation(this.context, {
|
|
86
|
+
sourceProductKey: query.forProduct.key,
|
|
87
|
+
relation: "replacement",
|
|
88
|
+
product
|
|
89
|
+
})
|
|
90
|
+
);
|
|
91
|
+
return success(result);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
__decorateClass([
|
|
95
|
+
Reactionary({
|
|
96
|
+
cache: true,
|
|
97
|
+
cacheTimeToLiveInSeconds: 300,
|
|
98
|
+
currencyDependentCaching: false,
|
|
99
|
+
localeDependentCaching: false
|
|
100
|
+
})
|
|
101
|
+
], CommercetoolsProductAssociationsCapability.prototype, "getAccessories", 1);
|
|
102
|
+
__decorateClass([
|
|
103
|
+
Reactionary({
|
|
104
|
+
cache: true,
|
|
105
|
+
cacheTimeToLiveInSeconds: 300,
|
|
106
|
+
currencyDependentCaching: false,
|
|
107
|
+
localeDependentCaching: false
|
|
108
|
+
})
|
|
109
|
+
], CommercetoolsProductAssociationsCapability.prototype, "getSpareparts", 1);
|
|
110
|
+
__decorateClass([
|
|
111
|
+
Reactionary({
|
|
112
|
+
cache: true,
|
|
113
|
+
cacheTimeToLiveInSeconds: 300,
|
|
114
|
+
currencyDependentCaching: false,
|
|
115
|
+
localeDependentCaching: false
|
|
116
|
+
})
|
|
117
|
+
], CommercetoolsProductAssociationsCapability.prototype, "getReplacements", 1);
|
|
118
|
+
export {
|
|
119
|
+
CommercetoolsProductAssociationsCapability
|
|
120
|
+
};
|
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
4
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
5
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
6
|
+
if (decorator = decorators[i])
|
|
7
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8
|
+
if (kind && result)
|
|
9
|
+
__defProp(target, key, result);
|
|
10
|
+
return result;
|
|
11
|
+
};
|
|
12
|
+
import {
|
|
13
|
+
error,
|
|
14
|
+
ProductListItemMutationCreateSchema,
|
|
15
|
+
ProductListItemMutationDeleteSchema,
|
|
16
|
+
ProductListItemMutationUpdateSchema,
|
|
17
|
+
ProductListItemPaginatedResultsSchema,
|
|
18
|
+
ProductListItemQuerySchema,
|
|
19
|
+
ProductListItemSchema,
|
|
20
|
+
ProductListMutationCreateSchema,
|
|
21
|
+
ProductListMutationDeleteSchema,
|
|
22
|
+
ProductListMutationUpdateSchema,
|
|
23
|
+
ProductListPaginatedResultsSchema,
|
|
24
|
+
ProductListCapability,
|
|
25
|
+
ProductListQueryByIdSchema,
|
|
26
|
+
ProductListQuerySchema,
|
|
27
|
+
ProductListSchema,
|
|
28
|
+
Reactionary,
|
|
29
|
+
success
|
|
30
|
+
} from "@reactionary/core";
|
|
31
|
+
class CommercetoolsProductListCapability extends ProductListCapability {
|
|
32
|
+
config;
|
|
33
|
+
commercetools;
|
|
34
|
+
factory;
|
|
35
|
+
constructor(config, cache, context, commercetools, factory) {
|
|
36
|
+
super(cache, context);
|
|
37
|
+
this.config = config;
|
|
38
|
+
this.commercetools = commercetools;
|
|
39
|
+
this.factory = factory;
|
|
40
|
+
}
|
|
41
|
+
async getClient() {
|
|
42
|
+
const client = await this.commercetools.getClient();
|
|
43
|
+
return client.withProjectKey({ projectKey: this.config.projectKey }).me();
|
|
44
|
+
}
|
|
45
|
+
async getById(payload) {
|
|
46
|
+
try {
|
|
47
|
+
const client = await this.getClient();
|
|
48
|
+
const response = await client.shoppingLists().withId({ ID: payload.identifier.key }).get().execute();
|
|
49
|
+
return success(this.factory.parseProductList(this.context, this.parseSingle(response.body)));
|
|
50
|
+
} catch (err) {
|
|
51
|
+
if (err.statusCode === 404) {
|
|
52
|
+
return error({
|
|
53
|
+
type: "NotFound",
|
|
54
|
+
identifier: payload
|
|
55
|
+
});
|
|
56
|
+
} else {
|
|
57
|
+
throw err;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async queryLists(payload) {
|
|
62
|
+
if (this.context.session.identityContext?.identity?.type !== "Registered") {
|
|
63
|
+
return success(this.factory.parseProductListPaginatedResult(this.context, {
|
|
64
|
+
items: [],
|
|
65
|
+
pageNumber: 1,
|
|
66
|
+
pageSize: payload.search.paginationOptions.pageSize,
|
|
67
|
+
totalCount: 0,
|
|
68
|
+
totalPages: 0,
|
|
69
|
+
identifier: payload.search
|
|
70
|
+
}));
|
|
71
|
+
}
|
|
72
|
+
const client = await this.getClient();
|
|
73
|
+
const response = await client.shoppingLists().get({
|
|
74
|
+
queryArgs: {
|
|
75
|
+
where: `custom(fields(listType=:listType))`,
|
|
76
|
+
sort: "createdAt desc",
|
|
77
|
+
"var.listType": payload.search.listType,
|
|
78
|
+
limit: payload.search.paginationOptions.pageSize,
|
|
79
|
+
offset: (payload.search.paginationOptions.pageNumber - 1) * payload.search.paginationOptions.pageSize
|
|
80
|
+
}
|
|
81
|
+
}).execute();
|
|
82
|
+
return success(this.factory.parseProductListPaginatedResult(this.context, {
|
|
83
|
+
items: response.body.results.map((list) => this.parseSingle(list)),
|
|
84
|
+
pageNumber: payload.search.paginationOptions.pageNumber,
|
|
85
|
+
pageSize: payload.search.paginationOptions.pageSize,
|
|
86
|
+
totalCount: response.body.total || 0,
|
|
87
|
+
totalPages: Math.ceil((response.body.total || 0) / payload.search.paginationOptions.pageSize),
|
|
88
|
+
identifier: payload.search
|
|
89
|
+
}));
|
|
90
|
+
}
|
|
91
|
+
async addList(mutation) {
|
|
92
|
+
const client = await this.getClient();
|
|
93
|
+
const localeString = this.getLocaleString();
|
|
94
|
+
if (this.context.session.identityContext?.identity?.type !== "Registered") {
|
|
95
|
+
return error({
|
|
96
|
+
type: "InvalidInput",
|
|
97
|
+
error: "Only registered users can have product lists"
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
const draft = {
|
|
101
|
+
name: { [localeString]: mutation.list.name },
|
|
102
|
+
description: mutation.list.description ? { [localeString]: mutation.list.description } : void 0,
|
|
103
|
+
custom: {
|
|
104
|
+
type: {
|
|
105
|
+
key: "reactionaryShoppingList",
|
|
106
|
+
typeId: "type"
|
|
107
|
+
},
|
|
108
|
+
fields: {
|
|
109
|
+
listType: mutation.list.type,
|
|
110
|
+
imageUrl: mutation.list.image ? mutation.list.image.sourceUrl : void 0,
|
|
111
|
+
publishedDate: mutation.list.publishDate ? new Date(mutation.list.publishDate) : void 0,
|
|
112
|
+
published: mutation.list.published || true
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
const response = await client.shoppingLists().post({
|
|
117
|
+
body: draft
|
|
118
|
+
}).execute();
|
|
119
|
+
return success(this.factory.parseProductList(this.context, this.parseSingle(response.body)));
|
|
120
|
+
}
|
|
121
|
+
async updateList(mutation) {
|
|
122
|
+
const client = await this.getClient();
|
|
123
|
+
const actions = [];
|
|
124
|
+
const localeString = this.getLocaleString();
|
|
125
|
+
if (mutation.name) {
|
|
126
|
+
actions.push({
|
|
127
|
+
action: "changeName",
|
|
128
|
+
name: { [localeString]: mutation.name }
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
if (mutation.description !== void 0) {
|
|
132
|
+
actions.push({
|
|
133
|
+
action: "setDescription",
|
|
134
|
+
description: mutation.description ? { [localeString]: mutation.description } : void 0
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
if (mutation.published) {
|
|
138
|
+
actions.push({
|
|
139
|
+
action: "setCustomField",
|
|
140
|
+
name: "published",
|
|
141
|
+
value: mutation.published
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
if (mutation.publishDate) {
|
|
145
|
+
actions.push({
|
|
146
|
+
action: "setCustomField",
|
|
147
|
+
name: "publishedDate",
|
|
148
|
+
value: new Date(mutation.publishDate)
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
if (mutation.image) {
|
|
152
|
+
actions.push({
|
|
153
|
+
action: "setCustomField",
|
|
154
|
+
name: "imageUrl",
|
|
155
|
+
value: mutation.image.sourceUrl
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
const update = {
|
|
159
|
+
version: 0,
|
|
160
|
+
// The auto-correcting middleware will deal with the version
|
|
161
|
+
actions
|
|
162
|
+
};
|
|
163
|
+
const response = await client.shoppingLists().withId({ ID: mutation.list.key }).post({ body: update }).execute();
|
|
164
|
+
return success(this.factory.parseProductList(this.context, this.parseSingle(response.body)));
|
|
165
|
+
}
|
|
166
|
+
async deleteList(mutation) {
|
|
167
|
+
const client = await this.getClient();
|
|
168
|
+
const newestVersion = await client.shoppingLists().withId({ ID: mutation.list.key }).get().execute().then((response) => response.body.version);
|
|
169
|
+
await client.shoppingLists().withId({ ID: mutation.list.key }).delete({
|
|
170
|
+
queryArgs: {
|
|
171
|
+
version: newestVersion
|
|
172
|
+
}
|
|
173
|
+
}).execute();
|
|
174
|
+
return success(void 0);
|
|
175
|
+
}
|
|
176
|
+
async queryListItems(query) {
|
|
177
|
+
const client = await this.getClient();
|
|
178
|
+
const response = await client.shoppingLists().withId({ ID: query.search.list.key }).get({
|
|
179
|
+
queryArgs: { expand: "lineItems[*].variant" }
|
|
180
|
+
}).execute();
|
|
181
|
+
const items = response.body.lineItems.map((lineItem) => this.parseProductListItem(query.search.list, lineItem));
|
|
182
|
+
return success(this.factory.parseProductListItemPaginatedResult(this.context, {
|
|
183
|
+
items: items.slice((query.search.paginationOptions.pageNumber - 1) * query.search.paginationOptions.pageSize, query.search.paginationOptions.pageNumber * query.search.paginationOptions.pageSize),
|
|
184
|
+
identifier: query.search,
|
|
185
|
+
pageNumber: query.search.paginationOptions.pageNumber,
|
|
186
|
+
pageSize: query.search.paginationOptions.pageSize,
|
|
187
|
+
totalCount: items.length,
|
|
188
|
+
totalPages: Math.ceil(items.length / query.search.paginationOptions.pageSize)
|
|
189
|
+
}));
|
|
190
|
+
}
|
|
191
|
+
async addItem(mutation) {
|
|
192
|
+
const client = await this.getClient();
|
|
193
|
+
const lineItemDraft = {
|
|
194
|
+
action: "addLineItem",
|
|
195
|
+
sku: mutation.listItem.variant.sku,
|
|
196
|
+
quantity: mutation.listItem.quantity,
|
|
197
|
+
custom: {
|
|
198
|
+
type: {
|
|
199
|
+
key: "reactionaryShoppingListItem",
|
|
200
|
+
typeId: "type"
|
|
201
|
+
},
|
|
202
|
+
fields: {
|
|
203
|
+
notes: mutation.listItem.notes || "",
|
|
204
|
+
order: mutation.listItem.order || 1
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
const update = {
|
|
209
|
+
version: 0,
|
|
210
|
+
// The auto-correcting middleware will deal with the version
|
|
211
|
+
actions: [lineItemDraft]
|
|
212
|
+
};
|
|
213
|
+
const response = await client.shoppingLists().withId({ ID: mutation.list.key }).post({ body: update, queryArgs: { expand: "lineItems[*].variant" } }).execute();
|
|
214
|
+
const lastItem = response.body.lineItems[response.body.lineItems.length - 1];
|
|
215
|
+
if (lastItem.variant?.sku !== mutation.listItem.variant.sku) {
|
|
216
|
+
throw new Error("The added line item is not the last item in the list, cannot reliably determine the identifier of the added item");
|
|
217
|
+
}
|
|
218
|
+
return success(this.factory.parseProductListItem(this.context, this.parseProductListItem(mutation.list, lastItem)));
|
|
219
|
+
}
|
|
220
|
+
async deleteItem(mutation) {
|
|
221
|
+
const client = await this.getClient();
|
|
222
|
+
const update = {
|
|
223
|
+
version: 0,
|
|
224
|
+
// The auto-correcting middleware will deal with the version
|
|
225
|
+
actions: [{
|
|
226
|
+
action: "removeLineItem",
|
|
227
|
+
lineItemId: mutation.listItem.key
|
|
228
|
+
}]
|
|
229
|
+
};
|
|
230
|
+
await client.shoppingLists().withId({ ID: mutation.listItem.list.key }).post({ body: update }).execute();
|
|
231
|
+
return success(void 0);
|
|
232
|
+
}
|
|
233
|
+
async updateItem(mutation) {
|
|
234
|
+
const client = await this.getClient();
|
|
235
|
+
const actions = [];
|
|
236
|
+
if (mutation.quantity !== void 0) {
|
|
237
|
+
actions.push({
|
|
238
|
+
action: "changeLineItemQuantity",
|
|
239
|
+
lineItemId: mutation.listItem.key,
|
|
240
|
+
quantity: mutation.quantity
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
if (mutation.notes !== void 0) {
|
|
244
|
+
actions.push({
|
|
245
|
+
action: "setLineItemCustomField",
|
|
246
|
+
lineItemId: mutation.listItem.key,
|
|
247
|
+
name: "notes",
|
|
248
|
+
value: mutation.notes
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
if (mutation.order !== void 0) {
|
|
252
|
+
actions.push({
|
|
253
|
+
action: "setLineItemCustomField",
|
|
254
|
+
lineItemId: mutation.listItem.key,
|
|
255
|
+
name: "order",
|
|
256
|
+
value: mutation.order
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
const update = {
|
|
260
|
+
version: 0,
|
|
261
|
+
actions
|
|
262
|
+
};
|
|
263
|
+
const response = await client.shoppingLists().withId({ ID: mutation.listItem.list.key }).post({ body: update, queryArgs: { expand: "lineItems[*].variant" } }).execute();
|
|
264
|
+
const updatedLineItem = response.body.lineItems.find((item) => item.id === mutation.listItem.key);
|
|
265
|
+
if (!updatedLineItem) {
|
|
266
|
+
throw new Error("Failed to find the updated line item in response");
|
|
267
|
+
}
|
|
268
|
+
return success(this.factory.parseProductListItem(this.context, this.parseProductListItem(mutation.listItem.list, updatedLineItem)));
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* It is not clear to me, why i'd want my CUSTOMER defined resources to be localized, since that means, if he changes visual language,
|
|
272
|
+
* the names of his lists will disappear, since they are not translated. But maybe there are usecases for this, so we should support it, but default to english.
|
|
273
|
+
**/
|
|
274
|
+
getLocaleString() {
|
|
275
|
+
return "en";
|
|
276
|
+
}
|
|
277
|
+
parseSingle(list) {
|
|
278
|
+
const localeString = this.getLocaleString();
|
|
279
|
+
const listType = list.custom?.fields["listType"] || "favorite";
|
|
280
|
+
const image = list.custom?.fields["imageUrl"];
|
|
281
|
+
const published = list.custom?.fields["published"] && true;
|
|
282
|
+
const publishDateDate = list.custom?.fields["publishedDate"];
|
|
283
|
+
let publishedDate;
|
|
284
|
+
if (publishDateDate) {
|
|
285
|
+
publishedDate = new Date(publishDateDate).toISOString();
|
|
286
|
+
}
|
|
287
|
+
return {
|
|
288
|
+
identifier: {
|
|
289
|
+
listType,
|
|
290
|
+
key: list.id
|
|
291
|
+
},
|
|
292
|
+
type: listType,
|
|
293
|
+
name: list.name[localeString] || "Unnamed List",
|
|
294
|
+
description: list.description?.[localeString] || "",
|
|
295
|
+
published,
|
|
296
|
+
publishDate: publishedDate,
|
|
297
|
+
image: {
|
|
298
|
+
sourceUrl: image || "",
|
|
299
|
+
altText: list.name[localeString] || "List Image"
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
parseProductListItem(listIdentifier, lineItem) {
|
|
304
|
+
const localeString = this.getLocaleString();
|
|
305
|
+
return {
|
|
306
|
+
identifier: {
|
|
307
|
+
list: listIdentifier,
|
|
308
|
+
key: lineItem.id
|
|
309
|
+
},
|
|
310
|
+
variant: {
|
|
311
|
+
sku: lineItem.variant?.sku || ""
|
|
312
|
+
},
|
|
313
|
+
quantity: lineItem.quantity,
|
|
314
|
+
notes: lineItem.custom?.fields["notes"] || "",
|
|
315
|
+
order: lineItem.custom?.fields["order"] || 1
|
|
316
|
+
// Commercetools doesn't have explicit ordering
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
__decorateClass([
|
|
321
|
+
Reactionary({
|
|
322
|
+
cache: true,
|
|
323
|
+
cacheTimeToLiveInSeconds: 300,
|
|
324
|
+
currencyDependentCaching: false,
|
|
325
|
+
localeDependentCaching: false,
|
|
326
|
+
inputSchema: ProductListQueryByIdSchema,
|
|
327
|
+
outputSchema: ProductListSchema
|
|
328
|
+
})
|
|
329
|
+
], CommercetoolsProductListCapability.prototype, "getById", 1);
|
|
330
|
+
__decorateClass([
|
|
331
|
+
Reactionary({
|
|
332
|
+
cache: true,
|
|
333
|
+
cacheTimeToLiveInSeconds: 300,
|
|
334
|
+
currencyDependentCaching: false,
|
|
335
|
+
localeDependentCaching: false,
|
|
336
|
+
inputSchema: ProductListQuerySchema,
|
|
337
|
+
outputSchema: ProductListPaginatedResultsSchema
|
|
338
|
+
})
|
|
339
|
+
], CommercetoolsProductListCapability.prototype, "queryLists", 1);
|
|
340
|
+
__decorateClass([
|
|
341
|
+
Reactionary({
|
|
342
|
+
cache: false,
|
|
343
|
+
// Mutations should not be cached
|
|
344
|
+
inputSchema: ProductListMutationCreateSchema,
|
|
345
|
+
outputSchema: ProductListSchema
|
|
346
|
+
})
|
|
347
|
+
], CommercetoolsProductListCapability.prototype, "addList", 1);
|
|
348
|
+
__decorateClass([
|
|
349
|
+
Reactionary({
|
|
350
|
+
cache: false,
|
|
351
|
+
inputSchema: ProductListMutationUpdateSchema,
|
|
352
|
+
outputSchema: ProductListSchema
|
|
353
|
+
})
|
|
354
|
+
], CommercetoolsProductListCapability.prototype, "updateList", 1);
|
|
355
|
+
__decorateClass([
|
|
356
|
+
Reactionary({
|
|
357
|
+
cache: false,
|
|
358
|
+
inputSchema: ProductListMutationDeleteSchema
|
|
359
|
+
})
|
|
360
|
+
], CommercetoolsProductListCapability.prototype, "deleteList", 1);
|
|
361
|
+
__decorateClass([
|
|
362
|
+
Reactionary({
|
|
363
|
+
cache: true,
|
|
364
|
+
cacheTimeToLiveInSeconds: 300,
|
|
365
|
+
currencyDependentCaching: false,
|
|
366
|
+
localeDependentCaching: false,
|
|
367
|
+
inputSchema: ProductListItemQuerySchema,
|
|
368
|
+
outputSchema: ProductListItemPaginatedResultsSchema
|
|
369
|
+
})
|
|
370
|
+
], CommercetoolsProductListCapability.prototype, "queryListItems", 1);
|
|
371
|
+
__decorateClass([
|
|
372
|
+
Reactionary({
|
|
373
|
+
cache: false,
|
|
374
|
+
inputSchema: ProductListItemMutationCreateSchema,
|
|
375
|
+
outputSchema: ProductListItemSchema
|
|
376
|
+
})
|
|
377
|
+
], CommercetoolsProductListCapability.prototype, "addItem", 1);
|
|
378
|
+
__decorateClass([
|
|
379
|
+
Reactionary({
|
|
380
|
+
cache: false,
|
|
381
|
+
inputSchema: ProductListItemMutationDeleteSchema
|
|
382
|
+
})
|
|
383
|
+
], CommercetoolsProductListCapability.prototype, "deleteItem", 1);
|
|
384
|
+
__decorateClass([
|
|
385
|
+
Reactionary({
|
|
386
|
+
cache: false,
|
|
387
|
+
inputSchema: ProductListItemMutationUpdateSchema,
|
|
388
|
+
outputSchema: ProductListItemSchema
|
|
389
|
+
})
|
|
390
|
+
], CommercetoolsProductListCapability.prototype, "updateItem", 1);
|
|
391
|
+
export {
|
|
392
|
+
CommercetoolsProductListCapability
|
|
393
|
+
};
|