@reactionary/magento 0.0.1
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 +293 -0
- package/capabilities/category.capability.js +254 -0
- package/capabilities/identity.capability.js +107 -0
- package/capabilities/inventory.capability.js +84 -0
- package/capabilities/price.capability.js +72 -0
- package/capabilities/product-search.capability.js +113 -0
- package/capabilities/product.capability.js +146 -0
- package/core/client.js +321 -0
- package/core/initialize.js +176 -0
- package/core/initialize.types.js +13 -0
- package/factories/cart/cart.factory.js +135 -0
- package/factories/category/category.factory.js +48 -0
- package/factories/identity/identity.factory.js +12 -0
- package/factories/index.js +7 -0
- package/factories/inventory/inventory.factory.js +24 -0
- package/factories/price/price.factory.js +43 -0
- package/factories/product/product.factory.js +115 -0
- package/factories/product-search/product-search.factory.js +88 -0
- package/index.js +14 -0
- package/package.json +15 -0
- package/schema/capabilities.schema.js +31 -0
- package/schema/configuration.schema.js +13 -0
- package/schema/magento.schema.js +5 -0
- package/schema/magento.types.js +0 -0
- package/src/capabilities/cart.capability.d.ts +24 -0
- package/src/capabilities/category.capability.d.ts +22 -0
- package/src/capabilities/identity.capability.d.ts +13 -0
- package/src/capabilities/inventory.capability.d.ts +11 -0
- package/src/capabilities/price.capability.d.ts +12 -0
- package/src/capabilities/product-search.capability.d.ts +15 -0
- package/src/capabilities/product.capability.d.ts +14 -0
- package/src/core/client.d.ts +93 -0
- package/src/core/initialize.d.ts +5 -0
- package/src/core/initialize.types.d.ts +80 -0
- package/src/factories/cart/cart.factory.d.ts +20 -0
- package/src/factories/category/category.factory.d.ts +14 -0
- package/src/factories/identity/identity.factory.d.ts +7 -0
- package/src/factories/index.d.ts +7 -0
- package/src/factories/inventory/inventory.factory.d.ts +13 -0
- package/src/factories/price/price.factory.d.ts +15 -0
- package/src/factories/product/product.factory.d.ts +13 -0
- package/src/factories/product-search/product-search.factory.d.ts +12 -0
- package/src/index.d.ts +14 -0
- package/src/schema/capabilities.schema.d.ts +74 -0
- package/src/schema/configuration.schema.d.ts +11 -0
- package/src/schema/magento.schema.d.ts +5 -0
- package/src/schema/magento.types.d.ts +200 -0
package/README.md
ADDED
|
@@ -0,0 +1,293 @@
|
|
|
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
|
+
CartCapability,
|
|
14
|
+
CartIdentifierSchema,
|
|
15
|
+
CartMutationApplyCouponSchema,
|
|
16
|
+
CartMutationChangeCurrencySchema,
|
|
17
|
+
CartMutationCreateCartSchema,
|
|
18
|
+
CartMutationDeleteCartSchema,
|
|
19
|
+
CartMutationItemAddSchema,
|
|
20
|
+
CartMutationItemQuantityChangeSchema,
|
|
21
|
+
CartMutationItemRemoveSchema,
|
|
22
|
+
CartMutationRemoveCouponSchema,
|
|
23
|
+
CartMutationRenameCartSchema,
|
|
24
|
+
CartPaginatedSearchResultSchema,
|
|
25
|
+
CartQueryByIdSchema,
|
|
26
|
+
CartQueryListSchema,
|
|
27
|
+
CartSchema,
|
|
28
|
+
Reactionary,
|
|
29
|
+
success,
|
|
30
|
+
error
|
|
31
|
+
} from "@reactionary/core";
|
|
32
|
+
import createDebug from "debug";
|
|
33
|
+
import { MagentoCartIdentifierSchema } from "../schema/magento.schema.js";
|
|
34
|
+
const debug = createDebug("reactionary:magento:cart");
|
|
35
|
+
class MagentoCartCapability extends CartCapability {
|
|
36
|
+
constructor(config, cache, context, magentoApi, factory) {
|
|
37
|
+
super(cache, context);
|
|
38
|
+
this.magentoApi = magentoApi;
|
|
39
|
+
this.config = config;
|
|
40
|
+
this.factory = factory;
|
|
41
|
+
}
|
|
42
|
+
config;
|
|
43
|
+
factory;
|
|
44
|
+
async getById(payload) {
|
|
45
|
+
try {
|
|
46
|
+
const magentoId = payload.cart;
|
|
47
|
+
const cartResponse = await this.getCartWithTotals(magentoId.key);
|
|
48
|
+
if (cartResponse) {
|
|
49
|
+
return success(this.factory.parseCart(this.context, { ...cartResponse, _requestedId: magentoId.key }));
|
|
50
|
+
}
|
|
51
|
+
return error({
|
|
52
|
+
type: "NotFound",
|
|
53
|
+
identifier: payload
|
|
54
|
+
});
|
|
55
|
+
} catch (err) {
|
|
56
|
+
debug("Failed to get cart by ID:", err);
|
|
57
|
+
return error({
|
|
58
|
+
type: "NotFound",
|
|
59
|
+
identifier: payload
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async add(payload) {
|
|
64
|
+
try {
|
|
65
|
+
let cartIdentifier = payload.cart;
|
|
66
|
+
if (!cartIdentifier) {
|
|
67
|
+
const activeCart = await this.getActiveCartId();
|
|
68
|
+
if (activeCart.success) {
|
|
69
|
+
cartIdentifier = activeCart.value;
|
|
70
|
+
} else {
|
|
71
|
+
cartIdentifier = await this.createNewCart();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const magentoId = cartIdentifier;
|
|
75
|
+
const item = {
|
|
76
|
+
sku: payload.variant.sku,
|
|
77
|
+
qty: payload.quantity
|
|
78
|
+
};
|
|
79
|
+
await this.magentoApi.addItemToCart(magentoId.key, item);
|
|
80
|
+
const cartResponse = await this.getCartWithTotals(magentoId.key);
|
|
81
|
+
return success(this.factory.parseCart(this.context, { ...cartResponse, _requestedId: magentoId.key }));
|
|
82
|
+
} catch (err) {
|
|
83
|
+
debug("Failed to add item to cart:", err);
|
|
84
|
+
throw err;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
async remove(payload) {
|
|
88
|
+
try {
|
|
89
|
+
const magentoId = payload.cart;
|
|
90
|
+
await this.magentoApi.removeCartItem(magentoId.key, Number(payload.item.key));
|
|
91
|
+
const cartResponse = await this.getCartWithTotals(magentoId.key);
|
|
92
|
+
return success(this.factory.parseCart(this.context, { ...cartResponse, _requestedId: magentoId.key }));
|
|
93
|
+
} catch (err) {
|
|
94
|
+
debug("Failed to remove item from cart:", err);
|
|
95
|
+
throw err;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
async changeQuantity(payload) {
|
|
99
|
+
try {
|
|
100
|
+
const magentoId = payload.cart;
|
|
101
|
+
const item = {
|
|
102
|
+
item_id: Number(payload.item.key),
|
|
103
|
+
qty: payload.quantity
|
|
104
|
+
};
|
|
105
|
+
await this.magentoApi.updateCartItem(magentoId.key, Number(payload.item.key), item);
|
|
106
|
+
const cartResponse = await this.getCartWithTotals(magentoId.key);
|
|
107
|
+
return success(this.factory.parseCart(this.context, { ...cartResponse, _requestedId: magentoId.key }));
|
|
108
|
+
} catch (err) {
|
|
109
|
+
debug("Failed to change quantity:", err);
|
|
110
|
+
throw err;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
async getActiveCartId() {
|
|
114
|
+
try {
|
|
115
|
+
const tokenStore = this.magentoApi.tokenStore;
|
|
116
|
+
const activeCartId = await tokenStore.getItem("activeCartId");
|
|
117
|
+
if (activeCartId) {
|
|
118
|
+
return success(
|
|
119
|
+
MagentoCartIdentifierSchema.parse({
|
|
120
|
+
key: activeCartId
|
|
121
|
+
})
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
return error({
|
|
125
|
+
type: "NotFound",
|
|
126
|
+
identifier: void 0
|
|
127
|
+
});
|
|
128
|
+
} catch {
|
|
129
|
+
return error({
|
|
130
|
+
type: "NotFound",
|
|
131
|
+
identifier: void 0
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
async deleteCart(_payload) {
|
|
136
|
+
const tokenStore = this.magentoApi.tokenStore;
|
|
137
|
+
await tokenStore.removeItem("activeCartId");
|
|
138
|
+
return success(void 0);
|
|
139
|
+
}
|
|
140
|
+
async applyCouponCode(payload) {
|
|
141
|
+
try {
|
|
142
|
+
const magentoId = payload.cart;
|
|
143
|
+
await this.magentoApi.applyCoupon(magentoId.key, payload.couponCode);
|
|
144
|
+
const cartResponse = await this.getCartWithTotals(magentoId.key);
|
|
145
|
+
return success(this.factory.parseCart(this.context, { ...cartResponse, _requestedId: magentoId.key }));
|
|
146
|
+
} catch (err) {
|
|
147
|
+
debug("Failed to apply coupon:", err);
|
|
148
|
+
throw err;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
async removeCouponCode(payload) {
|
|
152
|
+
try {
|
|
153
|
+
const magentoId = payload.cart;
|
|
154
|
+
await this.magentoApi.removeCoupon(magentoId.key);
|
|
155
|
+
const cartResponse = await this.getCartWithTotals(magentoId.key);
|
|
156
|
+
return success(this.factory.parseCart(this.context, { ...cartResponse, _requestedId: magentoId.key }));
|
|
157
|
+
} catch (err) {
|
|
158
|
+
debug("Failed to remove coupon:", err);
|
|
159
|
+
throw err;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
async changeCurrency(_payload) {
|
|
163
|
+
throw new Error("Currency change not implemented for Magento");
|
|
164
|
+
}
|
|
165
|
+
async listCarts(_payload) {
|
|
166
|
+
const tokenStore = this.magentoApi.tokenStore;
|
|
167
|
+
const activeCartId = await tokenStore.getItem("activeCartId");
|
|
168
|
+
if (activeCartId) {
|
|
169
|
+
const cartWithTotals = await this.getCartWithTotals(activeCartId);
|
|
170
|
+
return success(this.factory.parseCartPaginatedSearchResult(this.context, {
|
|
171
|
+
items: [cartWithTotals],
|
|
172
|
+
totalCount: 1
|
|
173
|
+
}, _payload));
|
|
174
|
+
} else {
|
|
175
|
+
return success(this.factory.parseCartPaginatedSearchResult(this.context, {
|
|
176
|
+
items: [],
|
|
177
|
+
totalCount: 0
|
|
178
|
+
}, _payload));
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
async createCart(_payload) {
|
|
182
|
+
const identifier = await this.createNewCart();
|
|
183
|
+
const cartResponse = await this.getCartWithTotals(identifier.key);
|
|
184
|
+
return success(this.factory.parseCart(this.context, { ...cartResponse, _requestedId: identifier.key }));
|
|
185
|
+
}
|
|
186
|
+
async renameCart(_payload) {
|
|
187
|
+
throw new Error("renameCart not implemented for Magento");
|
|
188
|
+
}
|
|
189
|
+
async createNewCart() {
|
|
190
|
+
const cartId = await this.magentoApi.createCart();
|
|
191
|
+
const identifier = MagentoCartIdentifierSchema.parse({
|
|
192
|
+
key: cartId.replace(/^"|"$/g, "")
|
|
193
|
+
});
|
|
194
|
+
const tokenStore = this.magentoApi.tokenStore;
|
|
195
|
+
await tokenStore.setItem("activeCartId", identifier.key);
|
|
196
|
+
return identifier;
|
|
197
|
+
}
|
|
198
|
+
async getCartWithTotals(cartId) {
|
|
199
|
+
try {
|
|
200
|
+
const [cartResponse, totalsResponse] = await Promise.all([
|
|
201
|
+
this.magentoApi.getCart(cartId),
|
|
202
|
+
this.magentoApi.getCartTotals(cartId)
|
|
203
|
+
]);
|
|
204
|
+
return {
|
|
205
|
+
...cartResponse,
|
|
206
|
+
...totalsResponse,
|
|
207
|
+
items: (cartResponse.items || []).map((item) => {
|
|
208
|
+
const totalItem = (totalsResponse.items || []).find(
|
|
209
|
+
(t) => t["item_id"] === item["item_id"]
|
|
210
|
+
);
|
|
211
|
+
return { ...item, ...totalItem };
|
|
212
|
+
})
|
|
213
|
+
};
|
|
214
|
+
} catch (err) {
|
|
215
|
+
debug("Failed to get cart with totals:", err);
|
|
216
|
+
return this.magentoApi.getCart(cartId);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
__decorateClass([
|
|
221
|
+
Reactionary({
|
|
222
|
+
inputSchema: CartQueryByIdSchema,
|
|
223
|
+
outputSchema: CartSchema
|
|
224
|
+
})
|
|
225
|
+
], MagentoCartCapability.prototype, "getById", 1);
|
|
226
|
+
__decorateClass([
|
|
227
|
+
Reactionary({
|
|
228
|
+
inputSchema: CartMutationItemAddSchema,
|
|
229
|
+
outputSchema: CartSchema
|
|
230
|
+
})
|
|
231
|
+
], MagentoCartCapability.prototype, "add", 1);
|
|
232
|
+
__decorateClass([
|
|
233
|
+
Reactionary({
|
|
234
|
+
inputSchema: CartMutationItemRemoveSchema,
|
|
235
|
+
outputSchema: CartSchema
|
|
236
|
+
})
|
|
237
|
+
], MagentoCartCapability.prototype, "remove", 1);
|
|
238
|
+
__decorateClass([
|
|
239
|
+
Reactionary({
|
|
240
|
+
inputSchema: CartMutationItemQuantityChangeSchema,
|
|
241
|
+
outputSchema: CartSchema
|
|
242
|
+
})
|
|
243
|
+
], MagentoCartCapability.prototype, "changeQuantity", 1);
|
|
244
|
+
__decorateClass([
|
|
245
|
+
Reactionary({
|
|
246
|
+
outputSchema: CartIdentifierSchema
|
|
247
|
+
})
|
|
248
|
+
], MagentoCartCapability.prototype, "getActiveCartId", 1);
|
|
249
|
+
__decorateClass([
|
|
250
|
+
Reactionary({
|
|
251
|
+
inputSchema: CartMutationDeleteCartSchema,
|
|
252
|
+
outputSchema: CartSchema
|
|
253
|
+
})
|
|
254
|
+
], MagentoCartCapability.prototype, "deleteCart", 1);
|
|
255
|
+
__decorateClass([
|
|
256
|
+
Reactionary({
|
|
257
|
+
inputSchema: CartMutationApplyCouponSchema,
|
|
258
|
+
outputSchema: CartSchema
|
|
259
|
+
})
|
|
260
|
+
], MagentoCartCapability.prototype, "applyCouponCode", 1);
|
|
261
|
+
__decorateClass([
|
|
262
|
+
Reactionary({
|
|
263
|
+
inputSchema: CartMutationRemoveCouponSchema,
|
|
264
|
+
outputSchema: CartSchema
|
|
265
|
+
})
|
|
266
|
+
], MagentoCartCapability.prototype, "removeCouponCode", 1);
|
|
267
|
+
__decorateClass([
|
|
268
|
+
Reactionary({
|
|
269
|
+
inputSchema: CartMutationChangeCurrencySchema,
|
|
270
|
+
outputSchema: CartSchema
|
|
271
|
+
})
|
|
272
|
+
], MagentoCartCapability.prototype, "changeCurrency", 1);
|
|
273
|
+
__decorateClass([
|
|
274
|
+
Reactionary({
|
|
275
|
+
inputSchema: CartQueryListSchema,
|
|
276
|
+
outputSchema: CartPaginatedSearchResultSchema
|
|
277
|
+
})
|
|
278
|
+
], MagentoCartCapability.prototype, "listCarts", 1);
|
|
279
|
+
__decorateClass([
|
|
280
|
+
Reactionary({
|
|
281
|
+
inputSchema: CartMutationCreateCartSchema,
|
|
282
|
+
outputSchema: CartSchema
|
|
283
|
+
})
|
|
284
|
+
], MagentoCartCapability.prototype, "createCart", 1);
|
|
285
|
+
__decorateClass([
|
|
286
|
+
Reactionary({
|
|
287
|
+
inputSchema: CartMutationRenameCartSchema,
|
|
288
|
+
outputSchema: CartSchema
|
|
289
|
+
})
|
|
290
|
+
], MagentoCartCapability.prototype, "renameCart", 1);
|
|
291
|
+
export {
|
|
292
|
+
MagentoCartCapability
|
|
293
|
+
};
|
|
@@ -0,0 +1,254 @@
|
|
|
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
|
+
CategoryCapability,
|
|
14
|
+
CategoryPaginatedResultSchema,
|
|
15
|
+
CategoryQueryByIdSchema,
|
|
16
|
+
CategoryQueryBySlugSchema,
|
|
17
|
+
CategoryQueryForBreadcrumbSchema,
|
|
18
|
+
CategoryQueryForChildCategoriesSchema,
|
|
19
|
+
CategoryQueryForTopCategoriesSchema,
|
|
20
|
+
CategorySchema,
|
|
21
|
+
error,
|
|
22
|
+
Reactionary,
|
|
23
|
+
success
|
|
24
|
+
} from "@reactionary/core";
|
|
25
|
+
import * as z from "zod";
|
|
26
|
+
import createDebug from "debug";
|
|
27
|
+
const debug = createDebug("reactionary:magento:category");
|
|
28
|
+
class MagentoCategoryCapability extends CategoryCapability {
|
|
29
|
+
constructor(config, cache, context, magentoApi, factory) {
|
|
30
|
+
super(cache, context);
|
|
31
|
+
this.magentoApi = magentoApi;
|
|
32
|
+
this.config = config;
|
|
33
|
+
this.factory = factory;
|
|
34
|
+
}
|
|
35
|
+
config;
|
|
36
|
+
factory;
|
|
37
|
+
async getById(payload) {
|
|
38
|
+
const client = await this.magentoApi.getClient();
|
|
39
|
+
try {
|
|
40
|
+
const response = await client.store.category.getByExternalId(payload.id.key);
|
|
41
|
+
if (!response) {
|
|
42
|
+
return error({
|
|
43
|
+
type: "NotFound",
|
|
44
|
+
identifier: payload
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
return success(await this.factory.parseCategory(this.context, await this.cleanupParentPointersForCategory(response.items[0])));
|
|
48
|
+
} catch (e) {
|
|
49
|
+
debug("Error getting category by id", e);
|
|
50
|
+
return error({
|
|
51
|
+
type: "NotFound",
|
|
52
|
+
identifier: payload
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
async getBySlug(payload) {
|
|
57
|
+
const client = await this.magentoApi.getClient();
|
|
58
|
+
const params = new URLSearchParams();
|
|
59
|
+
params.set("searchCriteria[filterGroups][0][filters][0][field]", "url_key");
|
|
60
|
+
params.set("searchCriteria[filterGroups][0][filters][0][value]", payload.slug);
|
|
61
|
+
params.set("searchCriteria[filterGroups][0][filters][0][condition_type]", "eq");
|
|
62
|
+
params.set("searchCriteria[pageSize]", "1");
|
|
63
|
+
try {
|
|
64
|
+
const response = await client.store.category.list(params);
|
|
65
|
+
if (!response.items || response.items.length === 0) {
|
|
66
|
+
return error({
|
|
67
|
+
type: "NotFound",
|
|
68
|
+
identifier: payload
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
return success(
|
|
72
|
+
await this.factory.parseCategory(this.context, await this.cleanupParentPointersForCategory(response.items[0]))
|
|
73
|
+
);
|
|
74
|
+
} catch (e) {
|
|
75
|
+
debug("Error getting category by slug", e);
|
|
76
|
+
return error({
|
|
77
|
+
type: "NotFound",
|
|
78
|
+
identifier: payload
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
async getBreadcrumbPathToCategory(payload) {
|
|
83
|
+
const client = await this.magentoApi.getClient();
|
|
84
|
+
try {
|
|
85
|
+
const category = await client.store.category.getByExternalId(payload.id.key);
|
|
86
|
+
if (!category) {
|
|
87
|
+
return error({
|
|
88
|
+
type: "NotFound",
|
|
89
|
+
identifier: payload.id
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
const pathIds = (category.path || "").split("/").filter(Boolean);
|
|
93
|
+
if (pathIds.length === 0) {
|
|
94
|
+
return success([await this.factory.parseCategory(this.context, await this.cleanupParentPointersForCategory(category))]);
|
|
95
|
+
}
|
|
96
|
+
const params = new URLSearchParams();
|
|
97
|
+
params.set("searchCriteria[filterGroups][0][filters][0][field]", "entity_id");
|
|
98
|
+
params.set("searchCriteria[filterGroups][0][filters][0][value]", pathIds.join(","));
|
|
99
|
+
params.set("searchCriteria[filterGroups][0][filters][0][condition_type]", "in");
|
|
100
|
+
const response = await client.store.category.list(params);
|
|
101
|
+
const items = response.items || [];
|
|
102
|
+
const results = [];
|
|
103
|
+
for (const id of pathIds) {
|
|
104
|
+
const found = items.find((c) => String(c["id"]) === String(id));
|
|
105
|
+
if (found) {
|
|
106
|
+
results.push(await this.factory.parseCategory(this.context, await this.cleanupParentPointersForCategory(found)));
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return success(results);
|
|
110
|
+
} catch (e) {
|
|
111
|
+
debug("Error getting breadcrumb path", e);
|
|
112
|
+
throw new Error("Category not found or error fetching path: " + payload.id.key);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
async findChildCategories(payload) {
|
|
116
|
+
const client = await this.magentoApi.getClient();
|
|
117
|
+
const parentId = await this.translateCategoryKeyToMagentoId(client, payload.parentId.key);
|
|
118
|
+
if (!parentId) {
|
|
119
|
+
return error({
|
|
120
|
+
type: "NotFound",
|
|
121
|
+
identifier: payload.parentId
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
const pageSize = payload.paginationOptions.pageSize;
|
|
125
|
+
const currentPage = payload.paginationOptions.pageNumber;
|
|
126
|
+
const params = new URLSearchParams();
|
|
127
|
+
params.set("searchCriteria[filterGroups][0][filters][0][field]", "parent_id");
|
|
128
|
+
params.set("searchCriteria[filterGroups][0][filters][0][value]", parentId);
|
|
129
|
+
params.set("searchCriteria[filterGroups][0][filters][0][condition_type]", "eq");
|
|
130
|
+
params.set("searchCriteria[filterGroups][1][filters][0][field]", "is_active");
|
|
131
|
+
params.set("searchCriteria[filterGroups][1][filters][0][value]", "1");
|
|
132
|
+
params.set("searchCriteria[filterGroups][1][filters][0][condition_type]", "eq");
|
|
133
|
+
params.set("searchCriteria[pageSize]", String(pageSize));
|
|
134
|
+
params.set("searchCriteria[currentPage]", String(currentPage));
|
|
135
|
+
const response = await this.cleanupParentPointersForPaginatedResult(await client.store.category.list(params));
|
|
136
|
+
return success(
|
|
137
|
+
this.factory.parseCategoryPaginatedResult(this.context, {
|
|
138
|
+
...response,
|
|
139
|
+
pageSize,
|
|
140
|
+
currentPage
|
|
141
|
+
})
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
async findTopCategories(payload) {
|
|
145
|
+
const client = await this.magentoApi.getClient();
|
|
146
|
+
const pageSize = payload.paginationOptions.pageSize;
|
|
147
|
+
const currentPage = payload.paginationOptions.pageNumber;
|
|
148
|
+
const params = new URLSearchParams();
|
|
149
|
+
params.set("searchCriteria[filterGroups][0][filters][0][field]", "parent_id");
|
|
150
|
+
params.set("searchCriteria[filterGroups][0][filters][0][value]", this.config.rootCategoryId);
|
|
151
|
+
params.set("searchCriteria[filterGroups][0][filters][0][condition_type]", "eq");
|
|
152
|
+
params.set("searchCriteria[filterGroups][1][filters][0][field]", "is_active");
|
|
153
|
+
params.set("searchCriteria[filterGroups][1][filters][0][value]", "1");
|
|
154
|
+
params.set("searchCriteria[filterGroups][1][filters][0][condition_type]", "eq");
|
|
155
|
+
params.set("searchCriteria[pageSize]", String(pageSize));
|
|
156
|
+
params.set("searchCriteria[currentPage]", String(currentPage));
|
|
157
|
+
const response = await this.cleanupParentPointersForPaginatedResult(await client.store.category.list(params));
|
|
158
|
+
return success(
|
|
159
|
+
this.factory.parseCategoryPaginatedResult(this.context, {
|
|
160
|
+
...response,
|
|
161
|
+
pageSize,
|
|
162
|
+
currentPage
|
|
163
|
+
})
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
async cacheCategoryKeyToIdMapping(key, id) {
|
|
167
|
+
await this.cache.put(`category_key_to_id:${key}`, id, {
|
|
168
|
+
ttlSeconds: 60 * 60,
|
|
169
|
+
// cache for 1 hour
|
|
170
|
+
dependencyIds: [`category_key:${key}`]
|
|
171
|
+
});
|
|
172
|
+
await this.cache.put(`category_id_to_key:${id}`, key, {
|
|
173
|
+
ttlSeconds: 60 * 60,
|
|
174
|
+
// cache for 1 hour
|
|
175
|
+
dependencyIds: [`category_id:${id}`]
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
async translateCategoryKeyToMagentoId(client, key) {
|
|
179
|
+
const cachedValue = await this.cache.get(`category_key_to_id:${key}`, z.string());
|
|
180
|
+
if (cachedValue) {
|
|
181
|
+
return cachedValue;
|
|
182
|
+
}
|
|
183
|
+
const response = await client.store.category.getByExternalId(key);
|
|
184
|
+
if (!response) {
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
const magentoId = String(response.items[0].id);
|
|
188
|
+
await this.cacheCategoryKeyToIdMapping(key, magentoId);
|
|
189
|
+
return magentoId;
|
|
190
|
+
}
|
|
191
|
+
async translateMagentoIdToCategoryKey(magentoId) {
|
|
192
|
+
const categoryCacheKey = await this.cache.get(`category_id_to_key:${magentoId}`, z.string());
|
|
193
|
+
if (categoryCacheKey) {
|
|
194
|
+
return categoryCacheKey;
|
|
195
|
+
}
|
|
196
|
+
const client = await this.magentoApi.getClient();
|
|
197
|
+
const response = await client.store.category.getById(magentoId);
|
|
198
|
+
const keyAttr = response.custom_attributes?.find((a) => a.attribute_code === "external_id");
|
|
199
|
+
const key = String(keyAttr?.value || "-");
|
|
200
|
+
await this.cacheCategoryKeyToIdMapping(key, magentoId);
|
|
201
|
+
return key;
|
|
202
|
+
}
|
|
203
|
+
async cleanupParentPointersForCategory(category) {
|
|
204
|
+
if (String(category.parent_id) === this.config.rootCategoryId) {
|
|
205
|
+
category.parent_id = 0;
|
|
206
|
+
} else {
|
|
207
|
+
const parentKey = await this.translateMagentoIdToCategoryKey(String(category.parent_id));
|
|
208
|
+
if (parentKey) {
|
|
209
|
+
category.parent_id = Number(parentKey);
|
|
210
|
+
await this.cacheCategoryKeyToIdMapping(parentKey, String(category.parent_id));
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return category;
|
|
214
|
+
}
|
|
215
|
+
async cleanupParentPointersForPaginatedResult(paginatedResult) {
|
|
216
|
+
for (const category of paginatedResult.items) {
|
|
217
|
+
await this.cleanupParentPointersForCategory(category);
|
|
218
|
+
}
|
|
219
|
+
return paginatedResult;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
__decorateClass([
|
|
223
|
+
Reactionary({
|
|
224
|
+
inputSchema: CategoryQueryByIdSchema,
|
|
225
|
+
outputSchema: CategorySchema
|
|
226
|
+
})
|
|
227
|
+
], MagentoCategoryCapability.prototype, "getById", 1);
|
|
228
|
+
__decorateClass([
|
|
229
|
+
Reactionary({
|
|
230
|
+
inputSchema: CategoryQueryBySlugSchema,
|
|
231
|
+
outputSchema: CategorySchema.nullable()
|
|
232
|
+
})
|
|
233
|
+
], MagentoCategoryCapability.prototype, "getBySlug", 1);
|
|
234
|
+
__decorateClass([
|
|
235
|
+
Reactionary({
|
|
236
|
+
inputSchema: CategoryQueryForBreadcrumbSchema,
|
|
237
|
+
outputSchema: z.array(CategorySchema)
|
|
238
|
+
})
|
|
239
|
+
], MagentoCategoryCapability.prototype, "getBreadcrumbPathToCategory", 1);
|
|
240
|
+
__decorateClass([
|
|
241
|
+
Reactionary({
|
|
242
|
+
inputSchema: CategoryQueryForChildCategoriesSchema,
|
|
243
|
+
outputSchema: CategoryPaginatedResultSchema
|
|
244
|
+
})
|
|
245
|
+
], MagentoCategoryCapability.prototype, "findChildCategories", 1);
|
|
246
|
+
__decorateClass([
|
|
247
|
+
Reactionary({
|
|
248
|
+
inputSchema: CategoryQueryForTopCategoriesSchema,
|
|
249
|
+
outputSchema: CategoryPaginatedResultSchema
|
|
250
|
+
})
|
|
251
|
+
], MagentoCategoryCapability.prototype, "findTopCategories", 1);
|
|
252
|
+
export {
|
|
253
|
+
MagentoCategoryCapability
|
|
254
|
+
};
|
|
@@ -0,0 +1,107 @@
|
|
|
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
|
+
IdentityCapability,
|
|
14
|
+
Reactionary,
|
|
15
|
+
IdentityQuerySelfSchema,
|
|
16
|
+
IdentitySchema,
|
|
17
|
+
IdentityMutationRegisterSchema,
|
|
18
|
+
IdentityMutationLoginSchema,
|
|
19
|
+
IdentityMutationLogoutSchema,
|
|
20
|
+
success
|
|
21
|
+
} from "@reactionary/core";
|
|
22
|
+
import createDebug from "debug";
|
|
23
|
+
const debug = createDebug("reactionary:magento:identity");
|
|
24
|
+
class MagentoIdentityCapability extends IdentityCapability {
|
|
25
|
+
constructor(config, cache, context, magentoApi) {
|
|
26
|
+
super(cache, context);
|
|
27
|
+
this.magentoApi = magentoApi;
|
|
28
|
+
this.config = config;
|
|
29
|
+
}
|
|
30
|
+
config;
|
|
31
|
+
createAnonymousIdentity() {
|
|
32
|
+
return {
|
|
33
|
+
type: "Anonymous"
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
async getSelf(_payload) {
|
|
37
|
+
try {
|
|
38
|
+
const client = await this.magentoApi.getClient();
|
|
39
|
+
const me = await client.store.customer.me();
|
|
40
|
+
const identity = {
|
|
41
|
+
id: {
|
|
42
|
+
userId: String(me.id)
|
|
43
|
+
},
|
|
44
|
+
type: "Registered"
|
|
45
|
+
};
|
|
46
|
+
this.updateIdentityContext(identity);
|
|
47
|
+
return success(identity);
|
|
48
|
+
} catch (err) {
|
|
49
|
+
debug("getSelf failed, returning anonymous identity:", err);
|
|
50
|
+
const identity = this.createAnonymousIdentity();
|
|
51
|
+
this.updateIdentityContext(identity);
|
|
52
|
+
return success(identity);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async login(payload) {
|
|
56
|
+
debug("Attempting login for user:", payload.username);
|
|
57
|
+
await this.magentoApi.login(payload.username, payload.password);
|
|
58
|
+
return this.getSelf({});
|
|
59
|
+
}
|
|
60
|
+
async logout(_payload) {
|
|
61
|
+
debug("Logging out user");
|
|
62
|
+
await this.magentoApi.logout();
|
|
63
|
+
const identity = this.createAnonymousIdentity();
|
|
64
|
+
this.updateIdentityContext(identity);
|
|
65
|
+
return success(identity);
|
|
66
|
+
}
|
|
67
|
+
async register(payload) {
|
|
68
|
+
debug("Registering new user:", payload.username);
|
|
69
|
+
const customer = {
|
|
70
|
+
email: payload.username,
|
|
71
|
+
firstname: payload["firstname"] || "User",
|
|
72
|
+
lastname: payload["lastname"] || "Account"
|
|
73
|
+
};
|
|
74
|
+
await this.magentoApi.register(customer, payload.password);
|
|
75
|
+
return this.login({
|
|
76
|
+
username: payload.username,
|
|
77
|
+
password: payload.password
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
__decorateClass([
|
|
82
|
+
Reactionary({
|
|
83
|
+
inputSchema: IdentityQuerySelfSchema,
|
|
84
|
+
outputSchema: IdentitySchema
|
|
85
|
+
})
|
|
86
|
+
], MagentoIdentityCapability.prototype, "getSelf", 1);
|
|
87
|
+
__decorateClass([
|
|
88
|
+
Reactionary({
|
|
89
|
+
inputSchema: IdentityMutationLoginSchema,
|
|
90
|
+
outputSchema: IdentitySchema
|
|
91
|
+
})
|
|
92
|
+
], MagentoIdentityCapability.prototype, "login", 1);
|
|
93
|
+
__decorateClass([
|
|
94
|
+
Reactionary({
|
|
95
|
+
inputSchema: IdentityMutationLogoutSchema,
|
|
96
|
+
outputSchema: IdentitySchema
|
|
97
|
+
})
|
|
98
|
+
], MagentoIdentityCapability.prototype, "logout", 1);
|
|
99
|
+
__decorateClass([
|
|
100
|
+
Reactionary({
|
|
101
|
+
inputSchema: IdentityMutationRegisterSchema,
|
|
102
|
+
outputSchema: IdentitySchema
|
|
103
|
+
})
|
|
104
|
+
], MagentoIdentityCapability.prototype, "register", 1);
|
|
105
|
+
export {
|
|
106
|
+
MagentoIdentityCapability
|
|
107
|
+
};
|