@reactionary/magento 0.0.1 → 0.10.18
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/LICENSE +21 -0
- package/capabilities/cart.capability.js +22 -22
- package/capabilities/category.capability.js +10 -9
- package/capabilities/checkout.capability.js +308 -0
- package/capabilities/identity.capability.js +31 -16
- package/capabilities/inventory.capability.js +2 -2
- package/capabilities/order-search.capability.js +150 -0
- package/capabilities/order.capability.js +51 -0
- package/capabilities/price.capability.js +2 -2
- package/capabilities/product-associations.capability.js +118 -0
- package/capabilities/product-recommendations.capability.js +148 -0
- package/capabilities/product-reviews.capability.js +182 -0
- package/capabilities/product-search.capability.js +2 -2
- package/capabilities/product.capability.js +6 -5
- package/capabilities/profile.capability.js +283 -0
- package/core/client.js +324 -24
- package/core/initialize.js +150 -2
- package/core/product-reviews.graphql.js +72 -0
- package/factories/category/category.factory.js +1 -1
- package/factories/checkout/checkout.factory.js +203 -0
- package/factories/index.js +6 -0
- package/factories/order/order.factory.js +115 -0
- package/factories/order-search/order-search.factory.js +79 -0
- package/factories/product/product.factory.js +23 -18
- package/factories/product-associations/product-associations.factory.js +25 -0
- package/factories/product-reviews/product-reviews.factory.js +65 -0
- package/factories/product-search/product-search.factory.js +3 -4
- package/factories/profile/profile.factory.js +61 -0
- package/index.js +9 -0
- package/package.json +11 -6
- package/schema/capabilities.schema.js +16 -2
- package/schema/configuration.schema.js +5 -1
- package/src/capabilities/cart.capability.d.ts +5 -0
- package/src/capabilities/checkout.capability.d.ts +30 -0
- package/src/capabilities/order-search.capability.d.ts +16 -0
- package/src/capabilities/order.capability.d.ts +12 -0
- package/src/capabilities/product-associations.capability.d.ts +23 -0
- package/src/capabilities/product-recommendations.capability.d.ts +24 -0
- package/src/capabilities/product-reviews.capability.d.ts +35 -0
- package/src/capabilities/profile.capability.d.ts +24 -0
- package/src/core/client.d.ts +77 -2
- package/src/core/initialize.types.d.ts +40 -7
- package/src/core/product-reviews.graphql.d.ts +10 -0
- package/src/factories/category/category.factory.d.ts +2 -2
- package/src/factories/checkout/checkout.factory.d.ts +32 -0
- package/src/factories/index.d.ts +6 -0
- package/src/factories/order/order.factory.d.ts +77 -0
- package/src/factories/order-search/order-search.factory.d.ts +43 -0
- package/src/factories/product/product.factory.d.ts +2 -1
- package/src/factories/product-associations/product-associations.factory.d.ts +15 -0
- package/src/factories/product-reviews/product-reviews.factory.d.ts +40 -0
- package/src/factories/profile/profile.factory.d.ts +43 -0
- package/src/index.d.ts +9 -0
- package/src/schema/capabilities.schema.d.ts +50 -2
- package/src/schema/configuration.schema.d.ts +7 -0
- package/src/schema/magento.types.d.ts +219 -0
- package/src/utils/magento-product-lookup.d.ts +15 -0
- package/src/utils/magento-product.d.ts +36 -0
- package/src/utils/magento-review.d.ts +20 -0
- package/utils/magento-product-lookup.js +76 -0
- package/utils/magento-product.js +110 -0
- package/utils/magento-review.js +34 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Solteq
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -5,8 +5,7 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
5
5
|
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
6
6
|
if (decorator = decorators[i])
|
|
7
7
|
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8
|
-
if (kind && result)
|
|
9
|
-
__defProp(target, key, result);
|
|
8
|
+
if (kind && result) __defProp(target, key, result);
|
|
10
9
|
return result;
|
|
11
10
|
};
|
|
12
11
|
import {
|
|
@@ -39,6 +38,7 @@ class MagentoCartCapability extends CartCapability {
|
|
|
39
38
|
this.config = config;
|
|
40
39
|
this.factory = factory;
|
|
41
40
|
}
|
|
41
|
+
magentoApi;
|
|
42
42
|
config;
|
|
43
43
|
factory;
|
|
44
44
|
async getById(payload) {
|
|
@@ -60,6 +60,16 @@ class MagentoCartCapability extends CartCapability {
|
|
|
60
60
|
});
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* Fetches the cart (with merged totals) and parses it into the model. Shared
|
|
65
|
+
* by all mutations that return the resulting cart.
|
|
66
|
+
*/
|
|
67
|
+
async respondWithCart(key) {
|
|
68
|
+
const cartResponse = await this.getCartWithTotals(key);
|
|
69
|
+
return success(
|
|
70
|
+
this.factory.parseCart(this.context, { ...cartResponse, _requestedId: key })
|
|
71
|
+
);
|
|
72
|
+
}
|
|
63
73
|
async add(payload) {
|
|
64
74
|
try {
|
|
65
75
|
let cartIdentifier = payload.cart;
|
|
@@ -77,8 +87,7 @@ class MagentoCartCapability extends CartCapability {
|
|
|
77
87
|
qty: payload.quantity
|
|
78
88
|
};
|
|
79
89
|
await this.magentoApi.addItemToCart(magentoId.key, item);
|
|
80
|
-
|
|
81
|
-
return success(this.factory.parseCart(this.context, { ...cartResponse, _requestedId: magentoId.key }));
|
|
90
|
+
return this.respondWithCart(magentoId.key);
|
|
82
91
|
} catch (err) {
|
|
83
92
|
debug("Failed to add item to cart:", err);
|
|
84
93
|
throw err;
|
|
@@ -88,8 +97,7 @@ class MagentoCartCapability extends CartCapability {
|
|
|
88
97
|
try {
|
|
89
98
|
const magentoId = payload.cart;
|
|
90
99
|
await this.magentoApi.removeCartItem(magentoId.key, Number(payload.item.key));
|
|
91
|
-
|
|
92
|
-
return success(this.factory.parseCart(this.context, { ...cartResponse, _requestedId: magentoId.key }));
|
|
100
|
+
return this.respondWithCart(magentoId.key);
|
|
93
101
|
} catch (err) {
|
|
94
102
|
debug("Failed to remove item from cart:", err);
|
|
95
103
|
throw err;
|
|
@@ -103,8 +111,7 @@ class MagentoCartCapability extends CartCapability {
|
|
|
103
111
|
qty: payload.quantity
|
|
104
112
|
};
|
|
105
113
|
await this.magentoApi.updateCartItem(magentoId.key, Number(payload.item.key), item);
|
|
106
|
-
|
|
107
|
-
return success(this.factory.parseCart(this.context, { ...cartResponse, _requestedId: magentoId.key }));
|
|
114
|
+
return this.respondWithCart(magentoId.key);
|
|
108
115
|
} catch (err) {
|
|
109
116
|
debug("Failed to change quantity:", err);
|
|
110
117
|
throw err;
|
|
@@ -112,8 +119,7 @@ class MagentoCartCapability extends CartCapability {
|
|
|
112
119
|
}
|
|
113
120
|
async getActiveCartId() {
|
|
114
121
|
try {
|
|
115
|
-
const
|
|
116
|
-
const activeCartId = await tokenStore.getItem("activeCartId");
|
|
122
|
+
const activeCartId = await this.magentoApi.getActiveCartId();
|
|
117
123
|
if (activeCartId) {
|
|
118
124
|
return success(
|
|
119
125
|
MagentoCartIdentifierSchema.parse({
|
|
@@ -133,16 +139,14 @@ class MagentoCartCapability extends CartCapability {
|
|
|
133
139
|
}
|
|
134
140
|
}
|
|
135
141
|
async deleteCart(_payload) {
|
|
136
|
-
|
|
137
|
-
await tokenStore.removeItem("activeCartId");
|
|
142
|
+
await this.magentoApi.clearActiveCartId();
|
|
138
143
|
return success(void 0);
|
|
139
144
|
}
|
|
140
145
|
async applyCouponCode(payload) {
|
|
141
146
|
try {
|
|
142
147
|
const magentoId = payload.cart;
|
|
143
148
|
await this.magentoApi.applyCoupon(magentoId.key, payload.couponCode);
|
|
144
|
-
|
|
145
|
-
return success(this.factory.parseCart(this.context, { ...cartResponse, _requestedId: magentoId.key }));
|
|
149
|
+
return this.respondWithCart(magentoId.key);
|
|
146
150
|
} catch (err) {
|
|
147
151
|
debug("Failed to apply coupon:", err);
|
|
148
152
|
throw err;
|
|
@@ -152,8 +156,7 @@ class MagentoCartCapability extends CartCapability {
|
|
|
152
156
|
try {
|
|
153
157
|
const magentoId = payload.cart;
|
|
154
158
|
await this.magentoApi.removeCoupon(magentoId.key);
|
|
155
|
-
|
|
156
|
-
return success(this.factory.parseCart(this.context, { ...cartResponse, _requestedId: magentoId.key }));
|
|
159
|
+
return this.respondWithCart(magentoId.key);
|
|
157
160
|
} catch (err) {
|
|
158
161
|
debug("Failed to remove coupon:", err);
|
|
159
162
|
throw err;
|
|
@@ -163,8 +166,7 @@ class MagentoCartCapability extends CartCapability {
|
|
|
163
166
|
throw new Error("Currency change not implemented for Magento");
|
|
164
167
|
}
|
|
165
168
|
async listCarts(_payload) {
|
|
166
|
-
const
|
|
167
|
-
const activeCartId = await tokenStore.getItem("activeCartId");
|
|
169
|
+
const activeCartId = await this.magentoApi.getActiveCartId();
|
|
168
170
|
if (activeCartId) {
|
|
169
171
|
const cartWithTotals = await this.getCartWithTotals(activeCartId);
|
|
170
172
|
return success(this.factory.parseCartPaginatedSearchResult(this.context, {
|
|
@@ -180,8 +182,7 @@ class MagentoCartCapability extends CartCapability {
|
|
|
180
182
|
}
|
|
181
183
|
async createCart(_payload) {
|
|
182
184
|
const identifier = await this.createNewCart();
|
|
183
|
-
|
|
184
|
-
return success(this.factory.parseCart(this.context, { ...cartResponse, _requestedId: identifier.key }));
|
|
185
|
+
return this.respondWithCart(identifier.key);
|
|
185
186
|
}
|
|
186
187
|
async renameCart(_payload) {
|
|
187
188
|
throw new Error("renameCart not implemented for Magento");
|
|
@@ -191,8 +192,7 @@ class MagentoCartCapability extends CartCapability {
|
|
|
191
192
|
const identifier = MagentoCartIdentifierSchema.parse({
|
|
192
193
|
key: cartId.replace(/^"|"$/g, "")
|
|
193
194
|
});
|
|
194
|
-
|
|
195
|
-
await tokenStore.setItem("activeCartId", identifier.key);
|
|
195
|
+
await this.magentoApi.setActiveCartId(identifier.key);
|
|
196
196
|
return identifier;
|
|
197
197
|
}
|
|
198
198
|
async getCartWithTotals(cartId) {
|
|
@@ -5,8 +5,7 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
5
5
|
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
6
6
|
if (decorator = decorators[i])
|
|
7
7
|
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8
|
-
if (kind && result)
|
|
9
|
-
__defProp(target, key, result);
|
|
8
|
+
if (kind && result) __defProp(target, key, result);
|
|
10
9
|
return result;
|
|
11
10
|
};
|
|
12
11
|
import {
|
|
@@ -32,6 +31,7 @@ class MagentoCategoryCapability extends CategoryCapability {
|
|
|
32
31
|
this.config = config;
|
|
33
32
|
this.factory = factory;
|
|
34
33
|
}
|
|
34
|
+
magentoApi;
|
|
35
35
|
config;
|
|
36
36
|
factory;
|
|
37
37
|
async getById(payload) {
|
|
@@ -44,7 +44,8 @@ class MagentoCategoryCapability extends CategoryCapability {
|
|
|
44
44
|
identifier: payload
|
|
45
45
|
});
|
|
46
46
|
}
|
|
47
|
-
|
|
47
|
+
const cleanedResponse = await this.cleanupParentPointersForCategory(response);
|
|
48
|
+
return success(await this.factory.parseCategory(this.context, cleanedResponse));
|
|
48
49
|
} catch (e) {
|
|
49
50
|
debug("Error getting category by id", e);
|
|
50
51
|
return error({
|
|
@@ -89,7 +90,8 @@ class MagentoCategoryCapability extends CategoryCapability {
|
|
|
89
90
|
identifier: payload.id
|
|
90
91
|
});
|
|
91
92
|
}
|
|
92
|
-
|
|
93
|
+
let pathIds = (category.path || "").split("/").filter(Boolean);
|
|
94
|
+
pathIds = pathIds.filter((x) => Number(x) > Number(this.config.rootCategoryId));
|
|
93
95
|
if (pathIds.length === 0) {
|
|
94
96
|
return success([await this.factory.parseCategory(this.context, await this.cleanupParentPointersForCategory(category))]);
|
|
95
97
|
}
|
|
@@ -101,7 +103,7 @@ class MagentoCategoryCapability extends CategoryCapability {
|
|
|
101
103
|
const items = response.items || [];
|
|
102
104
|
const results = [];
|
|
103
105
|
for (const id of pathIds) {
|
|
104
|
-
const found = items.find((c) =>
|
|
106
|
+
const found = items.find((c) => c.id === Number(id));
|
|
105
107
|
if (found) {
|
|
106
108
|
results.push(await this.factory.parseCategory(this.context, await this.cleanupParentPointersForCategory(found)));
|
|
107
109
|
}
|
|
@@ -138,7 +140,7 @@ class MagentoCategoryCapability extends CategoryCapability {
|
|
|
138
140
|
...response,
|
|
139
141
|
pageSize,
|
|
140
142
|
currentPage
|
|
141
|
-
})
|
|
143
|
+
}, payload)
|
|
142
144
|
);
|
|
143
145
|
}
|
|
144
146
|
async findTopCategories(payload) {
|
|
@@ -160,7 +162,7 @@ class MagentoCategoryCapability extends CategoryCapability {
|
|
|
160
162
|
...response,
|
|
161
163
|
pageSize,
|
|
162
164
|
currentPage
|
|
163
|
-
})
|
|
165
|
+
}, payload)
|
|
164
166
|
);
|
|
165
167
|
}
|
|
166
168
|
async cacheCategoryKeyToIdMapping(key, id) {
|
|
@@ -184,7 +186,7 @@ class MagentoCategoryCapability extends CategoryCapability {
|
|
|
184
186
|
if (!response) {
|
|
185
187
|
return null;
|
|
186
188
|
}
|
|
187
|
-
const magentoId = String(response.
|
|
189
|
+
const magentoId = String(response.id);
|
|
188
190
|
await this.cacheCategoryKeyToIdMapping(key, magentoId);
|
|
189
191
|
return magentoId;
|
|
190
192
|
}
|
|
@@ -207,7 +209,6 @@ class MagentoCategoryCapability extends CategoryCapability {
|
|
|
207
209
|
const parentKey = await this.translateMagentoIdToCategoryKey(String(category.parent_id));
|
|
208
210
|
if (parentKey) {
|
|
209
211
|
category.parent_id = Number(parentKey);
|
|
210
|
-
await this.cacheCategoryKeyToIdMapping(parentKey, String(category.parent_id));
|
|
211
212
|
}
|
|
212
213
|
}
|
|
213
214
|
return category;
|
|
@@ -0,0 +1,308 @@
|
|
|
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) __defProp(target, key, result);
|
|
9
|
+
return result;
|
|
10
|
+
};
|
|
11
|
+
import {
|
|
12
|
+
CheckoutCapability,
|
|
13
|
+
CheckoutMutationAddPaymentInstructionSchema,
|
|
14
|
+
CheckoutMutationFinalizeCheckoutSchema,
|
|
15
|
+
CheckoutMutationInitiateCheckoutSchema,
|
|
16
|
+
CheckoutMutationRemovePaymentInstructionSchema,
|
|
17
|
+
CheckoutMutationSetShippingAddressSchema,
|
|
18
|
+
CheckoutMutationSetShippingInstructionSchema,
|
|
19
|
+
CheckoutQueryByIdSchema,
|
|
20
|
+
CheckoutQueryForAvailablePaymentMethodsSchema,
|
|
21
|
+
CheckoutQueryForAvailableShippingMethodsSchema,
|
|
22
|
+
CheckoutSchema,
|
|
23
|
+
PaymentMethodSchema,
|
|
24
|
+
Reactionary,
|
|
25
|
+
ShippingMethodSchema,
|
|
26
|
+
error,
|
|
27
|
+
success
|
|
28
|
+
} from "@reactionary/core";
|
|
29
|
+
import createDebug from "debug";
|
|
30
|
+
import * as z from "zod";
|
|
31
|
+
import {
|
|
32
|
+
encodeShippingMethodKey
|
|
33
|
+
} from "../factories/checkout/checkout.factory.js";
|
|
34
|
+
const debug = createDebug("reactionary:magento:checkout");
|
|
35
|
+
class CheckoutNotReadyForFinalizationError extends Error {
|
|
36
|
+
constructor(checkoutIdentifier) {
|
|
37
|
+
super(
|
|
38
|
+
`Checkout is not ready for finalization. Checkout ID: ${JSON.stringify(checkoutIdentifier)}`
|
|
39
|
+
);
|
|
40
|
+
this.checkoutIdentifier = checkoutIdentifier;
|
|
41
|
+
this.name = "CheckoutNotReadyForFinalizationError";
|
|
42
|
+
}
|
|
43
|
+
checkoutIdentifier;
|
|
44
|
+
}
|
|
45
|
+
class MagentoCheckoutCapability extends CheckoutCapability {
|
|
46
|
+
constructor(config, cache, context, magentoApi, factory) {
|
|
47
|
+
super(cache, context);
|
|
48
|
+
this.magentoApi = magentoApi;
|
|
49
|
+
this.config = config;
|
|
50
|
+
this.factory = factory;
|
|
51
|
+
}
|
|
52
|
+
magentoApi;
|
|
53
|
+
config;
|
|
54
|
+
factory;
|
|
55
|
+
toMagentoAddress(address, email) {
|
|
56
|
+
return {
|
|
57
|
+
firstname: address.firstName,
|
|
58
|
+
lastname: address.lastName,
|
|
59
|
+
street: [address.streetAddress, address.streetNumber].filter(
|
|
60
|
+
(part) => Boolean(part)
|
|
61
|
+
),
|
|
62
|
+
city: address.city,
|
|
63
|
+
region: address.region || void 0,
|
|
64
|
+
postcode: address.postalCode,
|
|
65
|
+
country_id: address.countryCode,
|
|
66
|
+
telephone: "000",
|
|
67
|
+
email
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
async loadCartAndTotals(cartKey) {
|
|
71
|
+
const cart = await this.magentoApi.getCart(cartKey);
|
|
72
|
+
let totals;
|
|
73
|
+
try {
|
|
74
|
+
totals = await this.magentoApi.getCartTotals(cartKey);
|
|
75
|
+
} catch (err) {
|
|
76
|
+
debug("Failed to fetch cart totals: %O", err);
|
|
77
|
+
}
|
|
78
|
+
return { cart, totals };
|
|
79
|
+
}
|
|
80
|
+
async buildCheckout(cartKey, state) {
|
|
81
|
+
const { cart, totals } = await this.loadCartAndTotals(cartKey);
|
|
82
|
+
const data = {
|
|
83
|
+
cart,
|
|
84
|
+
totals,
|
|
85
|
+
state,
|
|
86
|
+
requestedKey: cartKey
|
|
87
|
+
};
|
|
88
|
+
return this.factory.parseCheckout(this.context, data);
|
|
89
|
+
}
|
|
90
|
+
async initiateCheckoutForCart(payload) {
|
|
91
|
+
const cartKey = payload.cart.identifier.key;
|
|
92
|
+
const state = await this.magentoApi.getCheckoutState(cartKey);
|
|
93
|
+
state.email = payload.notificationEmail ?? state.email;
|
|
94
|
+
state.phone = payload.notificationPhone ?? state.phone;
|
|
95
|
+
if (payload.billingAddress) {
|
|
96
|
+
const billingAddress = this.toMagentoAddress(
|
|
97
|
+
payload.billingAddress,
|
|
98
|
+
state.email
|
|
99
|
+
);
|
|
100
|
+
state.billingAddress = billingAddress;
|
|
101
|
+
try {
|
|
102
|
+
await this.magentoApi.setCheckoutBillingAddress(cartKey, billingAddress);
|
|
103
|
+
} catch (err) {
|
|
104
|
+
debug("Failed to persist billing address on quote: %O", err);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
await this.magentoApi.setCheckoutState(cartKey, state);
|
|
108
|
+
return success(await this.buildCheckout(cartKey, state));
|
|
109
|
+
}
|
|
110
|
+
async getById(payload) {
|
|
111
|
+
const cartKey = payload.identifier.key;
|
|
112
|
+
try {
|
|
113
|
+
const state = await this.magentoApi.getCheckoutState(cartKey);
|
|
114
|
+
return success(await this.buildCheckout(cartKey, state));
|
|
115
|
+
} catch (err) {
|
|
116
|
+
debug("Failed to load checkout: %O", err);
|
|
117
|
+
return error({
|
|
118
|
+
type: "NotFound",
|
|
119
|
+
identifier: payload.identifier
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
async setShippingAddress(payload) {
|
|
124
|
+
const cartKey = payload.checkout.key;
|
|
125
|
+
const state = await this.magentoApi.getCheckoutState(cartKey);
|
|
126
|
+
state.shippingAddress = this.toMagentoAddress(
|
|
127
|
+
payload.shippingAddress,
|
|
128
|
+
state.email
|
|
129
|
+
);
|
|
130
|
+
await this.magentoApi.setCheckoutState(cartKey, state);
|
|
131
|
+
return success(await this.buildCheckout(cartKey, state));
|
|
132
|
+
}
|
|
133
|
+
async getAvailableShippingMethods(payload) {
|
|
134
|
+
const cartKey = payload.checkout.key;
|
|
135
|
+
const state = await this.magentoApi.getCheckoutState(cartKey);
|
|
136
|
+
const address = state.shippingAddress || state.billingAddress;
|
|
137
|
+
if (!address) {
|
|
138
|
+
return success([]);
|
|
139
|
+
}
|
|
140
|
+
const methods = await this.magentoApi.estimateShippingMethods(cartKey, address);
|
|
141
|
+
const shippingMethods = methods.filter((method) => method.available).map((method) => this.factory.parseShippingMethod(this.context, method));
|
|
142
|
+
return success(shippingMethods);
|
|
143
|
+
}
|
|
144
|
+
async getAvailablePaymentMethods(payload) {
|
|
145
|
+
const cartKey = payload.checkout.key;
|
|
146
|
+
const methods = await this.magentoApi.getPaymentMethods(cartKey);
|
|
147
|
+
const paymentMethods = methods.map(
|
|
148
|
+
(method) => this.factory.parsePaymentMethod(this.context, method)
|
|
149
|
+
);
|
|
150
|
+
return success(paymentMethods);
|
|
151
|
+
}
|
|
152
|
+
async addPaymentInstruction(payload) {
|
|
153
|
+
const cartKey = payload.checkout.key;
|
|
154
|
+
const state = await this.magentoApi.getCheckoutState(cartKey);
|
|
155
|
+
const instruction = {
|
|
156
|
+
key: `pi_${Date.now()}`,
|
|
157
|
+
method: payload.paymentInstruction.paymentMethod.method,
|
|
158
|
+
name: payload.paymentInstruction.paymentMethod.name,
|
|
159
|
+
paymentProcessor: payload.paymentInstruction.paymentMethod.paymentProcessor,
|
|
160
|
+
amountValue: payload.paymentInstruction.amount.value,
|
|
161
|
+
amountCurrency: payload.paymentInstruction.amount.currency,
|
|
162
|
+
protocolData: payload.paymentInstruction.protocolData,
|
|
163
|
+
status: "pending"
|
|
164
|
+
};
|
|
165
|
+
state.paymentInstructions = [
|
|
166
|
+
...state.paymentInstructions ?? [],
|
|
167
|
+
instruction
|
|
168
|
+
];
|
|
169
|
+
await this.magentoApi.setCheckoutState(cartKey, state);
|
|
170
|
+
return success(await this.buildCheckout(cartKey, state));
|
|
171
|
+
}
|
|
172
|
+
async removePaymentInstruction(payload) {
|
|
173
|
+
const cartKey = payload.checkout.key;
|
|
174
|
+
const state = await this.magentoApi.getCheckoutState(cartKey);
|
|
175
|
+
state.paymentInstructions = (state.paymentInstructions ?? []).filter(
|
|
176
|
+
(pi) => pi.key !== payload.paymentInstruction.key
|
|
177
|
+
);
|
|
178
|
+
await this.magentoApi.setCheckoutState(cartKey, state);
|
|
179
|
+
return success(await this.buildCheckout(cartKey, state));
|
|
180
|
+
}
|
|
181
|
+
async setShippingInstruction(payload) {
|
|
182
|
+
const cartKey = payload.checkout.key;
|
|
183
|
+
const state = await this.magentoApi.getCheckoutState(cartKey);
|
|
184
|
+
const address = state.shippingAddress || state.billingAddress;
|
|
185
|
+
if (!address) {
|
|
186
|
+
return error({
|
|
187
|
+
type: "InvalidInput",
|
|
188
|
+
error: "A shipping or billing address is required before selecting a shipping method"
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
const requestedKey = payload.shippingInstruction.shippingMethod.key;
|
|
192
|
+
const methods = await this.magentoApi.estimateShippingMethods(cartKey, address);
|
|
193
|
+
const method = methods.find(
|
|
194
|
+
(m) => encodeShippingMethodKey(m.carrier_code, m.method_code) === requestedKey
|
|
195
|
+
);
|
|
196
|
+
if (!method) {
|
|
197
|
+
return error({
|
|
198
|
+
type: "NotFound",
|
|
199
|
+
identifier: payload.shippingInstruction.shippingMethod
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
await this.magentoApi.setShippingInformation(cartKey, {
|
|
203
|
+
addressInformation: {
|
|
204
|
+
shipping_address: address,
|
|
205
|
+
billing_address: state.billingAddress ?? address,
|
|
206
|
+
shipping_method_code: method.method_code,
|
|
207
|
+
shipping_carrier_code: method.carrier_code
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
state.shippingInstruction = {
|
|
211
|
+
shippingMethodKey: requestedKey,
|
|
212
|
+
carrierCode: method.carrier_code,
|
|
213
|
+
methodCode: method.method_code,
|
|
214
|
+
instructions: payload.shippingInstruction.instructions || "",
|
|
215
|
+
pickupPoint: payload.shippingInstruction.pickupPoint || "",
|
|
216
|
+
consentForUnattendedDelivery: payload.shippingInstruction.consentForUnattendedDelivery
|
|
217
|
+
};
|
|
218
|
+
await this.magentoApi.setCheckoutState(cartKey, state);
|
|
219
|
+
return success(await this.buildCheckout(cartKey, state));
|
|
220
|
+
}
|
|
221
|
+
async finalizeCheckout(payload) {
|
|
222
|
+
const cartKey = payload.checkout.key;
|
|
223
|
+
const state = await this.magentoApi.getCheckoutState(cartKey);
|
|
224
|
+
const paymentInstruction = state.paymentInstructions?.[0];
|
|
225
|
+
if (!paymentInstruction || !state.shippingInstruction) {
|
|
226
|
+
throw new CheckoutNotReadyForFinalizationError(payload.checkout);
|
|
227
|
+
}
|
|
228
|
+
const orderId = await this.magentoApi.placeOrder(cartKey, {
|
|
229
|
+
email: state.email,
|
|
230
|
+
paymentMethod: {
|
|
231
|
+
method: paymentInstruction.method
|
|
232
|
+
},
|
|
233
|
+
billingAddress: state.billingAddress
|
|
234
|
+
});
|
|
235
|
+
state.orderId = String(orderId);
|
|
236
|
+
await this.magentoApi.setCheckoutState(cartKey, state);
|
|
237
|
+
await this.magentoApi.clearActiveCartId();
|
|
238
|
+
try {
|
|
239
|
+
return success(await this.buildCheckout(cartKey, state));
|
|
240
|
+
} catch (err) {
|
|
241
|
+
debug("Cart no longer retrievable after order placement: %O", err);
|
|
242
|
+
const data = {
|
|
243
|
+
cart: { id: 0, items: [], customer: {} },
|
|
244
|
+
state,
|
|
245
|
+
requestedKey: cartKey
|
|
246
|
+
};
|
|
247
|
+
return success(this.factory.parseCheckout(this.context, data));
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
__decorateClass([
|
|
252
|
+
Reactionary({
|
|
253
|
+
inputSchema: CheckoutMutationInitiateCheckoutSchema,
|
|
254
|
+
outputSchema: CheckoutSchema
|
|
255
|
+
})
|
|
256
|
+
], MagentoCheckoutCapability.prototype, "initiateCheckoutForCart", 1);
|
|
257
|
+
__decorateClass([
|
|
258
|
+
Reactionary({
|
|
259
|
+
inputSchema: CheckoutQueryByIdSchema,
|
|
260
|
+
outputSchema: CheckoutSchema.nullable()
|
|
261
|
+
})
|
|
262
|
+
], MagentoCheckoutCapability.prototype, "getById", 1);
|
|
263
|
+
__decorateClass([
|
|
264
|
+
Reactionary({
|
|
265
|
+
inputSchema: CheckoutMutationSetShippingAddressSchema,
|
|
266
|
+
outputSchema: CheckoutSchema
|
|
267
|
+
})
|
|
268
|
+
], MagentoCheckoutCapability.prototype, "setShippingAddress", 1);
|
|
269
|
+
__decorateClass([
|
|
270
|
+
Reactionary({
|
|
271
|
+
inputSchema: CheckoutQueryForAvailableShippingMethodsSchema,
|
|
272
|
+
outputSchema: z.array(ShippingMethodSchema)
|
|
273
|
+
})
|
|
274
|
+
], MagentoCheckoutCapability.prototype, "getAvailableShippingMethods", 1);
|
|
275
|
+
__decorateClass([
|
|
276
|
+
Reactionary({
|
|
277
|
+
inputSchema: CheckoutQueryForAvailablePaymentMethodsSchema,
|
|
278
|
+
outputSchema: z.array(PaymentMethodSchema)
|
|
279
|
+
})
|
|
280
|
+
], MagentoCheckoutCapability.prototype, "getAvailablePaymentMethods", 1);
|
|
281
|
+
__decorateClass([
|
|
282
|
+
Reactionary({
|
|
283
|
+
inputSchema: CheckoutMutationAddPaymentInstructionSchema,
|
|
284
|
+
outputSchema: CheckoutSchema
|
|
285
|
+
})
|
|
286
|
+
], MagentoCheckoutCapability.prototype, "addPaymentInstruction", 1);
|
|
287
|
+
__decorateClass([
|
|
288
|
+
Reactionary({
|
|
289
|
+
inputSchema: CheckoutMutationRemovePaymentInstructionSchema,
|
|
290
|
+
outputSchema: CheckoutSchema
|
|
291
|
+
})
|
|
292
|
+
], MagentoCheckoutCapability.prototype, "removePaymentInstruction", 1);
|
|
293
|
+
__decorateClass([
|
|
294
|
+
Reactionary({
|
|
295
|
+
inputSchema: CheckoutMutationSetShippingInstructionSchema,
|
|
296
|
+
outputSchema: CheckoutSchema
|
|
297
|
+
})
|
|
298
|
+
], MagentoCheckoutCapability.prototype, "setShippingInstruction", 1);
|
|
299
|
+
__decorateClass([
|
|
300
|
+
Reactionary({
|
|
301
|
+
inputSchema: CheckoutMutationFinalizeCheckoutSchema,
|
|
302
|
+
outputSchema: CheckoutSchema
|
|
303
|
+
})
|
|
304
|
+
], MagentoCheckoutCapability.prototype, "finalizeCheckout", 1);
|
|
305
|
+
export {
|
|
306
|
+
CheckoutNotReadyForFinalizationError,
|
|
307
|
+
MagentoCheckoutCapability
|
|
308
|
+
};
|
|
@@ -5,8 +5,7 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
5
5
|
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
6
6
|
if (decorator = decorators[i])
|
|
7
7
|
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8
|
-
if (kind && result)
|
|
9
|
-
__defProp(target, key, result);
|
|
8
|
+
if (kind && result) __defProp(target, key, result);
|
|
10
9
|
return result;
|
|
11
10
|
};
|
|
12
11
|
import {
|
|
@@ -27,6 +26,7 @@ class MagentoIdentityCapability extends IdentityCapability {
|
|
|
27
26
|
this.magentoApi = magentoApi;
|
|
28
27
|
this.config = config;
|
|
29
28
|
}
|
|
29
|
+
magentoApi;
|
|
30
30
|
config;
|
|
31
31
|
createAnonymousIdentity() {
|
|
32
32
|
return {
|
|
@@ -34,23 +34,38 @@ class MagentoIdentityCapability extends IdentityCapability {
|
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
36
|
async getSelf(_payload) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
37
|
+
const customerToken = await this.magentoApi.getCustomerToken();
|
|
38
|
+
if (customerToken) {
|
|
39
|
+
try {
|
|
40
|
+
const client = await this.magentoApi.getClient();
|
|
41
|
+
const me = await client.store.customer.me();
|
|
42
|
+
const identity2 = {
|
|
43
|
+
id: {
|
|
44
|
+
userId: String(me.id)
|
|
45
|
+
},
|
|
46
|
+
type: "Registered"
|
|
47
|
+
};
|
|
48
|
+
this.updateIdentityContext(identity2);
|
|
49
|
+
return success(identity2);
|
|
50
|
+
} catch (err) {
|
|
51
|
+
debug("getSelf: customer token present but /me failed:", err);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const activeCartId = await this.magentoApi.getActiveCartId();
|
|
55
|
+
if (activeCartId) {
|
|
56
|
+
debug("Active cart found without customer token, treating as guest");
|
|
57
|
+
const identity2 = {
|
|
58
|
+
type: "Guest",
|
|
41
59
|
id: {
|
|
42
|
-
userId:
|
|
43
|
-
}
|
|
44
|
-
type: "Registered"
|
|
60
|
+
userId: "guest"
|
|
61
|
+
}
|
|
45
62
|
};
|
|
46
|
-
this.updateIdentityContext(
|
|
47
|
-
return success(
|
|
48
|
-
} catch (err) {
|
|
49
|
-
debug("getSelf failed, returning anonymous identity:", err);
|
|
50
|
-
const identity = this.createAnonymousIdentity();
|
|
51
|
-
this.updateIdentityContext(identity);
|
|
52
|
-
return success(identity);
|
|
63
|
+
this.updateIdentityContext(identity2);
|
|
64
|
+
return success(identity2);
|
|
53
65
|
}
|
|
66
|
+
const identity = this.createAnonymousIdentity();
|
|
67
|
+
this.updateIdentityContext(identity);
|
|
68
|
+
return success(identity);
|
|
54
69
|
}
|
|
55
70
|
async login(payload) {
|
|
56
71
|
debug("Attempting login for user:", payload.username);
|
|
@@ -5,8 +5,7 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
5
5
|
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
6
6
|
if (decorator = decorators[i])
|
|
7
7
|
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8
|
-
if (kind && result)
|
|
9
|
-
__defProp(target, key, result);
|
|
8
|
+
if (kind && result) __defProp(target, key, result);
|
|
10
9
|
return result;
|
|
11
10
|
};
|
|
12
11
|
import {
|
|
@@ -25,6 +24,7 @@ class MagentoInventoryCapability extends InventoryCapability {
|
|
|
25
24
|
this.config = config;
|
|
26
25
|
this.factory = factory;
|
|
27
26
|
}
|
|
27
|
+
magentoApi;
|
|
28
28
|
config;
|
|
29
29
|
factory;
|
|
30
30
|
async getBySKU(payload) {
|