@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/core/client.js
CHANGED
|
@@ -1,11 +1,27 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CREATE_PRODUCT_REVIEW_MUTATION,
|
|
3
|
+
PRODUCT_RATING_SUMMARY_QUERY,
|
|
4
|
+
PRODUCT_REVIEWS_QUERY,
|
|
5
|
+
PRODUCT_REVIEW_RATINGS_METADATA_QUERY
|
|
6
|
+
} from "./product-reviews.graphql.js";
|
|
1
7
|
import createDebug from "debug";
|
|
2
8
|
const debug = createDebug("reactionary:magento");
|
|
3
9
|
const SESSION_KEY = "MAGENTO_PROVIDER";
|
|
10
|
+
function ensureMagentoPasswordPolicy(password) {
|
|
11
|
+
let suffix = "";
|
|
12
|
+
if (!/[A-Z]/.test(password)) suffix += "A";
|
|
13
|
+
if (!/[a-z]/.test(password)) suffix += "a";
|
|
14
|
+
if (!/[0-9]/.test(password)) suffix += "1";
|
|
15
|
+
if (!/[^A-Za-z0-9]/.test(password)) suffix += "!";
|
|
16
|
+
return `${password}${suffix}`;
|
|
17
|
+
}
|
|
4
18
|
class RequestContextTokenStore {
|
|
5
19
|
constructor(context, keyPrefix = "__x") {
|
|
6
20
|
this.context = context;
|
|
7
21
|
this.keyPrefix = keyPrefix;
|
|
8
22
|
}
|
|
23
|
+
context;
|
|
24
|
+
keyPrefix;
|
|
9
25
|
ensureNamespace() {
|
|
10
26
|
if (this.context.session[SESSION_KEY] === void 0) {
|
|
11
27
|
this.context.session[SESSION_KEY] = {};
|
|
@@ -34,13 +50,16 @@ class MagentoRest {
|
|
|
34
50
|
this.getAuthHeader = getAuthHeader;
|
|
35
51
|
this.apiUrl = `${this.baseUrl}/rest/${this.storeCode}`;
|
|
36
52
|
}
|
|
53
|
+
baseUrl;
|
|
54
|
+
storeCode;
|
|
55
|
+
getAuthHeader;
|
|
37
56
|
apiUrl;
|
|
38
57
|
normalizeUrl(path) {
|
|
39
58
|
const base = this.apiUrl.replace(/\/+$/, "");
|
|
40
59
|
const p = path.startsWith("/") ? path : `/${path}`;
|
|
41
60
|
return `${base}${p}`;
|
|
42
61
|
}
|
|
43
|
-
async request(method, path, body) {
|
|
62
|
+
async request(method, path, body, options) {
|
|
44
63
|
const url = this.normalizeUrl(path);
|
|
45
64
|
const headers = {
|
|
46
65
|
"Content-Type": "application/json",
|
|
@@ -51,6 +70,9 @@ class MagentoRest {
|
|
|
51
70
|
headers,
|
|
52
71
|
body: body === void 0 ? void 0 : JSON.stringify(body)
|
|
53
72
|
});
|
|
73
|
+
if (res.status === 404 && options?.allowNotFound) {
|
|
74
|
+
return void 0;
|
|
75
|
+
}
|
|
54
76
|
if (!res.ok) {
|
|
55
77
|
const text = await res.text().catch(() => "");
|
|
56
78
|
throw new Error(
|
|
@@ -65,17 +87,74 @@ ${text}`
|
|
|
65
87
|
return await res.text();
|
|
66
88
|
}
|
|
67
89
|
}
|
|
90
|
+
class MagentoGraphQL {
|
|
91
|
+
constructor(endpoint, storeCode, getAuthHeader) {
|
|
92
|
+
this.endpoint = endpoint;
|
|
93
|
+
this.storeCode = storeCode;
|
|
94
|
+
this.getAuthHeader = getAuthHeader;
|
|
95
|
+
}
|
|
96
|
+
endpoint;
|
|
97
|
+
storeCode;
|
|
98
|
+
getAuthHeader;
|
|
99
|
+
async request(document, variables) {
|
|
100
|
+
const headers = {
|
|
101
|
+
"Content-Type": "application/json",
|
|
102
|
+
...await this.getAuthHeader()
|
|
103
|
+
};
|
|
104
|
+
if (this.storeCode) {
|
|
105
|
+
headers["Store"] = this.storeCode;
|
|
106
|
+
}
|
|
107
|
+
const res = await fetch(this.endpoint, {
|
|
108
|
+
method: "POST",
|
|
109
|
+
headers,
|
|
110
|
+
body: JSON.stringify({ query: document, variables })
|
|
111
|
+
});
|
|
112
|
+
if (!res.ok) {
|
|
113
|
+
const text = await res.text().catch(() => "");
|
|
114
|
+
throw new Error(
|
|
115
|
+
`Magento GraphQL request failed: ${this.endpoint} \u2192 ${res.status}
|
|
116
|
+
${text}`
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
const payload = await res.json();
|
|
120
|
+
if (payload.errors && payload.errors.length > 0) {
|
|
121
|
+
throw new Error(
|
|
122
|
+
`Magento GraphQL request failed: ${payload.errors.map((e) => e.message).join("; ")}`
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
if (payload.data === void 0 || payload.data === null) {
|
|
126
|
+
throw new Error("Magento GraphQL response contained no data.");
|
|
127
|
+
}
|
|
128
|
+
return payload.data;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
68
131
|
class Magento {
|
|
69
|
-
constructor(rest, tokenStore) {
|
|
132
|
+
constructor(rest, tokenStore, authRest, adminRest, graphql) {
|
|
70
133
|
this.rest = rest;
|
|
71
134
|
this.tokenStore = tokenStore;
|
|
135
|
+
this.graphql = graphql;
|
|
136
|
+
this.authRest = authRest ?? rest;
|
|
137
|
+
this.adminRest = adminRest ?? rest;
|
|
138
|
+
}
|
|
139
|
+
rest;
|
|
140
|
+
tokenStore;
|
|
141
|
+
graphql;
|
|
142
|
+
authRest;
|
|
143
|
+
adminRest;
|
|
144
|
+
get gql() {
|
|
145
|
+
if (!this.graphql) {
|
|
146
|
+
throw new Error(
|
|
147
|
+
"Magento GraphQL transport is not configured on this client."
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
return this.graphql;
|
|
72
151
|
}
|
|
73
152
|
auth = {
|
|
74
153
|
login: async (email, password) => {
|
|
75
|
-
const token = await this.
|
|
154
|
+
const token = await this.authRest.request(
|
|
76
155
|
"POST",
|
|
77
156
|
"/V1/integration/customer/token",
|
|
78
|
-
{ username: email, password }
|
|
157
|
+
{ username: email, password: ensureMagentoPasswordPolicy(password) }
|
|
79
158
|
);
|
|
80
159
|
const normalized = typeof token === "string" ? token.replace(/^"|"$/g, "") : String(token);
|
|
81
160
|
await this.tokenStore.setItem("customerToken", normalized);
|
|
@@ -88,10 +167,16 @@ class Magento {
|
|
|
88
167
|
store = {
|
|
89
168
|
customer: {
|
|
90
169
|
register: async (customer, password) => {
|
|
91
|
-
return this.
|
|
170
|
+
return this.authRest.request("POST", "/V1/customers", {
|
|
171
|
+
customer,
|
|
172
|
+
password: password === void 0 ? void 0 : ensureMagentoPasswordPolicy(password)
|
|
173
|
+
});
|
|
92
174
|
},
|
|
93
175
|
me: async () => {
|
|
94
|
-
return this.
|
|
176
|
+
return this.authRest.request("GET", "/V1/customers/me");
|
|
177
|
+
},
|
|
178
|
+
update: async (customer) => {
|
|
179
|
+
return this.authRest.request("PUT", "/V1/customers/me", { customer });
|
|
95
180
|
}
|
|
96
181
|
},
|
|
97
182
|
product: {
|
|
@@ -106,6 +191,37 @@ class Magento {
|
|
|
106
191
|
"GET",
|
|
107
192
|
`/V1/products?${params.toString()}`
|
|
108
193
|
);
|
|
194
|
+
},
|
|
195
|
+
getLinks: async (sku, linkType) => {
|
|
196
|
+
return this.rest.request(
|
|
197
|
+
"GET",
|
|
198
|
+
`/V1/products/${encodeURIComponent(sku)}/links/${encodeURIComponent(linkType)}`
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
productReviews: {
|
|
203
|
+
getSummary: async (sku) => {
|
|
204
|
+
return this.gql.request(
|
|
205
|
+
PRODUCT_RATING_SUMMARY_QUERY,
|
|
206
|
+
{ sku }
|
|
207
|
+
);
|
|
208
|
+
},
|
|
209
|
+
list: async (sku, pageSize, currentPage) => {
|
|
210
|
+
return this.gql.request(
|
|
211
|
+
PRODUCT_REVIEWS_QUERY,
|
|
212
|
+
{ sku, pageSize, currentPage }
|
|
213
|
+
);
|
|
214
|
+
},
|
|
215
|
+
getRatingsMetadata: async () => {
|
|
216
|
+
return this.gql.request(
|
|
217
|
+
PRODUCT_REVIEW_RATINGS_METADATA_QUERY
|
|
218
|
+
);
|
|
219
|
+
},
|
|
220
|
+
create: async (input) => {
|
|
221
|
+
return this.gql.request(
|
|
222
|
+
CREATE_PRODUCT_REVIEW_MUTATION,
|
|
223
|
+
{ input }
|
|
224
|
+
);
|
|
109
225
|
}
|
|
110
226
|
},
|
|
111
227
|
category: {
|
|
@@ -113,12 +229,12 @@ class Magento {
|
|
|
113
229
|
return this.rest.request("GET", `/V1/categories/${encodeURIComponent(categoryId)}`);
|
|
114
230
|
},
|
|
115
231
|
getByExternalId: async (externalId) => {
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
const response = await this.rest.request("GET", `/V1/categories?${
|
|
232
|
+
const params = new URLSearchParams();
|
|
233
|
+
params.set("searchCriteria[filterGroups][0][filters][0][field]", "external_id");
|
|
234
|
+
params.set("searchCriteria[filterGroups][0][filters][0][value]", externalId);
|
|
235
|
+
params.set("searchCriteria[filterGroups][0][filters][0][condition_type]", "eq");
|
|
236
|
+
params.set("searchCriteria[pageSize]", "1");
|
|
237
|
+
const response = await this.rest.request("GET", `/V1/categories/list?${params.toString()}`);
|
|
122
238
|
return response.items?.[0] || null;
|
|
123
239
|
},
|
|
124
240
|
list: async (params) => {
|
|
@@ -133,6 +249,53 @@ class Magento {
|
|
|
133
249
|
return this.rest.request("GET", `/V1/inventory/source-items?${params.toString()}`);
|
|
134
250
|
}
|
|
135
251
|
},
|
|
252
|
+
order: {
|
|
253
|
+
list: async (params) => {
|
|
254
|
+
return this.adminRest.request("GET", `/V1/orders?${params.toString()}`);
|
|
255
|
+
},
|
|
256
|
+
get: async (id) => {
|
|
257
|
+
return this.adminRest.request(
|
|
258
|
+
"GET",
|
|
259
|
+
`/V1/orders/${encodeURIComponent(id)}`,
|
|
260
|
+
void 0,
|
|
261
|
+
{ allowNotFound: true }
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
},
|
|
265
|
+
checkout: {
|
|
266
|
+
estimateShippingMethods: async (cartId, address, customerToken) => {
|
|
267
|
+
const body = { address };
|
|
268
|
+
if (customerToken) {
|
|
269
|
+
return this.rest.request("POST", "/V1/carts/mine/estimate-shipping-methods", body);
|
|
270
|
+
}
|
|
271
|
+
return this.rest.request("POST", `/V1/guest-carts/${cartId}/estimate-shipping-methods`, body);
|
|
272
|
+
},
|
|
273
|
+
getPaymentMethods: async (cartId, customerToken) => {
|
|
274
|
+
if (customerToken) {
|
|
275
|
+
return this.rest.request("GET", "/V1/carts/mine/payment-methods");
|
|
276
|
+
}
|
|
277
|
+
return this.rest.request("GET", `/V1/guest-carts/${cartId}/payment-methods`);
|
|
278
|
+
},
|
|
279
|
+
setShippingInformation: async (cartId, payload, customerToken) => {
|
|
280
|
+
if (customerToken) {
|
|
281
|
+
return this.rest.request("POST", "/V1/carts/mine/shipping-information", payload);
|
|
282
|
+
}
|
|
283
|
+
return this.rest.request("POST", `/V1/guest-carts/${cartId}/shipping-information`, payload);
|
|
284
|
+
},
|
|
285
|
+
setBillingAddress: async (cartId, address, customerToken) => {
|
|
286
|
+
const body = { address };
|
|
287
|
+
if (customerToken) {
|
|
288
|
+
return this.rest.request("POST", "/V1/carts/mine/billing-address", body);
|
|
289
|
+
}
|
|
290
|
+
return this.rest.request("POST", `/V1/guest-carts/${cartId}/billing-address`, body);
|
|
291
|
+
},
|
|
292
|
+
placeOrder: async (cartId, payload, customerToken) => {
|
|
293
|
+
if (customerToken) {
|
|
294
|
+
return this.rest.request("POST", "/V1/carts/mine/payment-information", payload);
|
|
295
|
+
}
|
|
296
|
+
return this.rest.request("POST", `/V1/guest-carts/${cartId}/payment-information`, payload);
|
|
297
|
+
}
|
|
298
|
+
},
|
|
136
299
|
cart: {
|
|
137
300
|
create: async (customerToken) => {
|
|
138
301
|
if (customerToken) {
|
|
@@ -197,20 +360,37 @@ class Magento {
|
|
|
197
360
|
}
|
|
198
361
|
};
|
|
199
362
|
}
|
|
363
|
+
function resolveGraphQLEndpoint(config) {
|
|
364
|
+
if (config.graphqlUrl) {
|
|
365
|
+
return config.graphqlUrl;
|
|
366
|
+
}
|
|
367
|
+
return `${config.baseUrl.replace(/\/+$/, "")}/graphql`;
|
|
368
|
+
}
|
|
200
369
|
class MagentoAdminClient {
|
|
201
370
|
rest;
|
|
202
371
|
client;
|
|
203
372
|
constructor(config, context) {
|
|
204
|
-
|
|
373
|
+
const authHeader = async () => {
|
|
205
374
|
const headers = {};
|
|
206
375
|
const token = config.adminApiKey ?? "";
|
|
207
|
-
if (token)
|
|
208
|
-
headers["Authorization"] = `Bearer ${token}`;
|
|
376
|
+
if (token) headers["Authorization"] = `Bearer ${token}`;
|
|
209
377
|
return headers;
|
|
210
|
-
}
|
|
211
|
-
this.
|
|
212
|
-
|
|
213
|
-
|
|
378
|
+
};
|
|
379
|
+
this.rest = new MagentoRest(config.baseUrl, config.storeCode, authHeader);
|
|
380
|
+
const authRest = new MagentoRest(config.baseUrl, config.authStoreCode, authHeader);
|
|
381
|
+
const graphql = new MagentoGraphQL(
|
|
382
|
+
resolveGraphQLEndpoint(config),
|
|
383
|
+
config.storeCode,
|
|
384
|
+
authHeader
|
|
385
|
+
);
|
|
386
|
+
this.client = new Magento(
|
|
387
|
+
this.rest,
|
|
388
|
+
new RequestContextTokenStore(context),
|
|
389
|
+
authRest,
|
|
390
|
+
void 0,
|
|
391
|
+
graphql
|
|
392
|
+
);
|
|
393
|
+
if (debug.enabled) debug("MagentoAdminClient created");
|
|
214
394
|
}
|
|
215
395
|
async getClient() {
|
|
216
396
|
return this.client;
|
|
@@ -221,7 +401,7 @@ class MagentoClient {
|
|
|
221
401
|
this.config = config;
|
|
222
402
|
this.tokenStore = new RequestContextTokenStore(context);
|
|
223
403
|
this.client = void 0;
|
|
224
|
-
|
|
404
|
+
const authHeader = async () => {
|
|
225
405
|
const headers = {};
|
|
226
406
|
const customerToken = await this.tokenStore.getItem("customerToken");
|
|
227
407
|
if (customerToken) {
|
|
@@ -233,17 +413,40 @@ class MagentoClient {
|
|
|
233
413
|
headers["Authorization"] = `Bearer ${adminToken}`;
|
|
234
414
|
}
|
|
235
415
|
return headers;
|
|
416
|
+
};
|
|
417
|
+
this.rest = new MagentoRest(this.config.baseUrl, this.config.storeCode, authHeader);
|
|
418
|
+
this.authRest = new MagentoRest(this.config.baseUrl, this.config.authStoreCode, authHeader);
|
|
419
|
+
this.adminRest = new MagentoRest(this.config.baseUrl, this.config.storeCode, async () => {
|
|
420
|
+
const headers = {};
|
|
421
|
+
if (this.config.adminApiKey) {
|
|
422
|
+
headers["Authorization"] = `Bearer ${this.config.adminApiKey}`;
|
|
423
|
+
}
|
|
424
|
+
return headers;
|
|
236
425
|
});
|
|
237
|
-
|
|
238
|
-
|
|
426
|
+
this.graphql = new MagentoGraphQL(
|
|
427
|
+
resolveGraphQLEndpoint(this.config),
|
|
428
|
+
this.config.storeCode,
|
|
429
|
+
authHeader
|
|
430
|
+
);
|
|
431
|
+
if (debug.enabled) debug("MagentoClient created");
|
|
239
432
|
}
|
|
433
|
+
config;
|
|
240
434
|
tokenStore;
|
|
241
435
|
rest;
|
|
436
|
+
authRest;
|
|
437
|
+
adminRest;
|
|
438
|
+
graphql;
|
|
242
439
|
client;
|
|
243
440
|
async getClient() {
|
|
244
441
|
if (!this.client) {
|
|
245
442
|
this.client = Promise.resolve(
|
|
246
|
-
new Magento(
|
|
443
|
+
new Magento(
|
|
444
|
+
this.rest,
|
|
445
|
+
this.tokenStore,
|
|
446
|
+
this.authRest,
|
|
447
|
+
this.adminRest,
|
|
448
|
+
this.graphql
|
|
449
|
+
)
|
|
247
450
|
);
|
|
248
451
|
}
|
|
249
452
|
return this.client;
|
|
@@ -260,10 +463,35 @@ class MagentoClient {
|
|
|
260
463
|
const client = await this.getClient();
|
|
261
464
|
return client.store.customer.me();
|
|
262
465
|
}
|
|
466
|
+
async getCustomerToken() {
|
|
467
|
+
return this.tokenStore.getItem("customerToken");
|
|
468
|
+
}
|
|
469
|
+
async getActiveCartId() {
|
|
470
|
+
return this.tokenStore.getItem("activeCartId");
|
|
471
|
+
}
|
|
472
|
+
async setActiveCartId(cartId) {
|
|
473
|
+
return this.tokenStore.setItem("activeCartId", cartId);
|
|
474
|
+
}
|
|
475
|
+
async clearActiveCartId() {
|
|
476
|
+
return this.tokenStore.removeItem("activeCartId");
|
|
477
|
+
}
|
|
263
478
|
async register(customer, password) {
|
|
264
479
|
const client = await this.getClient();
|
|
265
480
|
return client.store.customer.register(customer, password);
|
|
266
481
|
}
|
|
482
|
+
async updateMe(customer) {
|
|
483
|
+
const client = await this.getClient();
|
|
484
|
+
return client.store.customer.update(customer);
|
|
485
|
+
}
|
|
486
|
+
async searchOrders(params) {
|
|
487
|
+
const client = await this.getClient();
|
|
488
|
+
return client.store.order.list(params);
|
|
489
|
+
}
|
|
490
|
+
/** Returns undefined (not a thrown error) when Magento returns a 404 — no order with this entity_id. */
|
|
491
|
+
async getOrderById(id) {
|
|
492
|
+
const client = await this.getClient();
|
|
493
|
+
return client.store.order.get(id);
|
|
494
|
+
}
|
|
267
495
|
async getProductBySKU(sku) {
|
|
268
496
|
const client = await this.getClient();
|
|
269
497
|
return client.store.product.getBySKU(sku);
|
|
@@ -271,6 +499,40 @@ class MagentoClient {
|
|
|
271
499
|
async resolveProductForSKU(sku) {
|
|
272
500
|
return this.getProductBySKU(sku);
|
|
273
501
|
}
|
|
502
|
+
async searchProducts(params) {
|
|
503
|
+
const client = await this.getClient();
|
|
504
|
+
return client.store.product.search(params);
|
|
505
|
+
}
|
|
506
|
+
async getProductLinks(sku, linkType) {
|
|
507
|
+
const client = await this.getClient();
|
|
508
|
+
return client.store.product.getLinks(sku, linkType);
|
|
509
|
+
}
|
|
510
|
+
/** Returns null when no product matches the SKU in the current store scope. */
|
|
511
|
+
async getProductReviewSummary(sku) {
|
|
512
|
+
const client = await this.getClient();
|
|
513
|
+
const result = await client.store.productReviews.getSummary(sku);
|
|
514
|
+
return result.products?.items?.[0] ?? null;
|
|
515
|
+
}
|
|
516
|
+
/** Returns null when no product matches the SKU in the current store scope. */
|
|
517
|
+
async getProductReviews(sku, pageSize, currentPage) {
|
|
518
|
+
const client = await this.getClient();
|
|
519
|
+
const result = await client.store.productReviews.list(
|
|
520
|
+
sku,
|
|
521
|
+
pageSize,
|
|
522
|
+
currentPage
|
|
523
|
+
);
|
|
524
|
+
return result.products?.items?.[0] ?? null;
|
|
525
|
+
}
|
|
526
|
+
async getProductReviewRatingsMetadata() {
|
|
527
|
+
const client = await this.getClient();
|
|
528
|
+
const result = await client.store.productReviews.getRatingsMetadata();
|
|
529
|
+
return result.productReviewRatingsMetadata?.items ?? [];
|
|
530
|
+
}
|
|
531
|
+
async createProductReview(input) {
|
|
532
|
+
const client = await this.getClient();
|
|
533
|
+
const result = await client.store.productReviews.create(input);
|
|
534
|
+
return result.createProductReview?.review ?? null;
|
|
535
|
+
}
|
|
274
536
|
async createCart() {
|
|
275
537
|
const client = await this.getClient();
|
|
276
538
|
const customerToken = await this.tokenStore.getItem("customerToken");
|
|
@@ -311,11 +573,49 @@ class MagentoClient {
|
|
|
311
573
|
const customerToken = await this.tokenStore.getItem("customerToken");
|
|
312
574
|
return client.store.cart.removeCoupon(cartId, customerToken);
|
|
313
575
|
}
|
|
576
|
+
async estimateShippingMethods(cartId, address) {
|
|
577
|
+
const client = await this.getClient();
|
|
578
|
+
const customerToken = await this.tokenStore.getItem("customerToken");
|
|
579
|
+
return client.store.checkout.estimateShippingMethods(cartId, address, customerToken);
|
|
580
|
+
}
|
|
581
|
+
async getPaymentMethods(cartId) {
|
|
582
|
+
const client = await this.getClient();
|
|
583
|
+
const customerToken = await this.tokenStore.getItem("customerToken");
|
|
584
|
+
return client.store.checkout.getPaymentMethods(cartId, customerToken);
|
|
585
|
+
}
|
|
586
|
+
async setShippingInformation(cartId, payload) {
|
|
587
|
+
const client = await this.getClient();
|
|
588
|
+
const customerToken = await this.tokenStore.getItem("customerToken");
|
|
589
|
+
return client.store.checkout.setShippingInformation(cartId, payload, customerToken);
|
|
590
|
+
}
|
|
591
|
+
async setCheckoutBillingAddress(cartId, address) {
|
|
592
|
+
const client = await this.getClient();
|
|
593
|
+
const customerToken = await this.tokenStore.getItem("customerToken");
|
|
594
|
+
return client.store.checkout.setBillingAddress(cartId, address, customerToken);
|
|
595
|
+
}
|
|
596
|
+
async placeOrder(cartId, payload) {
|
|
597
|
+
const client = await this.getClient();
|
|
598
|
+
const customerToken = await this.tokenStore.getItem("customerToken");
|
|
599
|
+
return client.store.checkout.placeOrder(cartId, payload, customerToken);
|
|
600
|
+
}
|
|
601
|
+
async getCheckoutState(cartKey) {
|
|
602
|
+
const raw = await this.tokenStore.getItem(`checkoutState:${cartKey}`);
|
|
603
|
+
if (!raw) {
|
|
604
|
+
return {};
|
|
605
|
+
}
|
|
606
|
+
return JSON.parse(raw);
|
|
607
|
+
}
|
|
608
|
+
async setCheckoutState(cartKey, state) {
|
|
609
|
+
await this.tokenStore.setItem(`checkoutState:${cartKey}`, JSON.stringify(state));
|
|
610
|
+
}
|
|
314
611
|
}
|
|
315
612
|
export {
|
|
316
613
|
Magento,
|
|
317
614
|
MagentoAdminClient,
|
|
318
615
|
MagentoClient,
|
|
616
|
+
MagentoGraphQL,
|
|
319
617
|
RequestContextTokenStore,
|
|
320
|
-
SESSION_KEY
|
|
618
|
+
SESSION_KEY,
|
|
619
|
+
ensureMagentoPasswordPolicy,
|
|
620
|
+
resolveGraphQLEndpoint
|
|
321
621
|
};
|
package/core/initialize.js
CHANGED
|
@@ -7,7 +7,17 @@ import {
|
|
|
7
7
|
InventorySchema,
|
|
8
8
|
PriceSchema,
|
|
9
9
|
ProductSchema,
|
|
10
|
-
ProductSearchResultSchema
|
|
10
|
+
ProductSearchResultSchema,
|
|
11
|
+
ProfileSchema,
|
|
12
|
+
OrderSearchResultSchema,
|
|
13
|
+
OrderSchema,
|
|
14
|
+
CheckoutSchema,
|
|
15
|
+
ShippingMethodSchema,
|
|
16
|
+
PaymentMethodSchema,
|
|
17
|
+
ProductAssociationSchema,
|
|
18
|
+
ProductRatingSummarySchema,
|
|
19
|
+
ProductReviewSchema,
|
|
20
|
+
ProductReviewPaginatedResultSchema
|
|
11
21
|
} from "@reactionary/core";
|
|
12
22
|
import { MagentoCartCapability } from "../capabilities/cart.capability.js";
|
|
13
23
|
import { MagentoCategoryCapability } from "../capabilities/category.capability.js";
|
|
@@ -16,6 +26,13 @@ import { MagentoInventoryCapability } from "../capabilities/inventory.capability
|
|
|
16
26
|
import { MagentoPriceCapability } from "../capabilities/price.capability.js";
|
|
17
27
|
import { MagentoProductSearchCapability } from "../capabilities/product-search.capability.js";
|
|
18
28
|
import { MagentoProductCapability } from "../capabilities/product.capability.js";
|
|
29
|
+
import { MagentoProfileCapability } from "../capabilities/profile.capability.js";
|
|
30
|
+
import { MagentoOrderSearchCapability } from "../capabilities/order-search.capability.js";
|
|
31
|
+
import { MagentoOrderCapability } from "../capabilities/order.capability.js";
|
|
32
|
+
import { MagentoCheckoutCapability } from "../capabilities/checkout.capability.js";
|
|
33
|
+
import { MagentoProductAssociationsCapability } from "../capabilities/product-associations.capability.js";
|
|
34
|
+
import { MagentoProductRecommendationsCapability } from "../capabilities/product-recommendations.capability.js";
|
|
35
|
+
import { MagentoProductReviewsCapability } from "../capabilities/product-reviews.capability.js";
|
|
19
36
|
import {
|
|
20
37
|
MagentoCapabilitiesSchema
|
|
21
38
|
} from "../schema/capabilities.schema.js";
|
|
@@ -29,7 +46,13 @@ import {
|
|
|
29
46
|
MagentoInventoryFactory,
|
|
30
47
|
MagentoPriceFactory,
|
|
31
48
|
MagentoProductFactory,
|
|
32
|
-
MagentoProductSearchFactory
|
|
49
|
+
MagentoProductSearchFactory,
|
|
50
|
+
MagentoProfileFactory,
|
|
51
|
+
MagentoOrderSearchFactory,
|
|
52
|
+
MagentoOrderFactory,
|
|
53
|
+
MagentoCheckoutFactory,
|
|
54
|
+
MagentoProductAssociationsFactory,
|
|
55
|
+
MagentoProductReviewsFactory
|
|
33
56
|
} from "../factories/index.js";
|
|
34
57
|
import {
|
|
35
58
|
resolveCapabilityWithFactory,
|
|
@@ -168,6 +191,131 @@ function withMagentoCapabilities(configuration, capabilities) {
|
|
|
168
191
|
}
|
|
169
192
|
);
|
|
170
193
|
}
|
|
194
|
+
if (caps.profile?.enabled) {
|
|
195
|
+
client.profile = resolveCapabilityWithFactory(
|
|
196
|
+
capabilities.profile,
|
|
197
|
+
{
|
|
198
|
+
factory: new MagentoProfileFactory(ProfileSchema),
|
|
199
|
+
capability: (args) => new MagentoProfileCapability(
|
|
200
|
+
args.config,
|
|
201
|
+
args.cache,
|
|
202
|
+
args.context,
|
|
203
|
+
args.magentoApi,
|
|
204
|
+
args.factory
|
|
205
|
+
)
|
|
206
|
+
},
|
|
207
|
+
buildCapabilityArgs
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
if (caps.orderSearch?.enabled) {
|
|
211
|
+
client.orderSearch = resolveCapabilityWithFactory(
|
|
212
|
+
capabilities.orderSearch,
|
|
213
|
+
{
|
|
214
|
+
factory: new MagentoOrderSearchFactory(OrderSearchResultSchema),
|
|
215
|
+
capability: (args) => new MagentoOrderSearchCapability(
|
|
216
|
+
args.config,
|
|
217
|
+
args.cache,
|
|
218
|
+
args.context,
|
|
219
|
+
args.magentoApi,
|
|
220
|
+
args.factory
|
|
221
|
+
)
|
|
222
|
+
},
|
|
223
|
+
buildCapabilityArgs
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
if (caps.order?.enabled) {
|
|
227
|
+
client.order = resolveCapabilityWithFactory(
|
|
228
|
+
capabilities.order,
|
|
229
|
+
{
|
|
230
|
+
factory: new MagentoOrderFactory(OrderSchema),
|
|
231
|
+
capability: (args) => new MagentoOrderCapability(
|
|
232
|
+
args.config,
|
|
233
|
+
args.cache,
|
|
234
|
+
args.context,
|
|
235
|
+
args.magentoApi,
|
|
236
|
+
args.factory
|
|
237
|
+
)
|
|
238
|
+
},
|
|
239
|
+
buildCapabilityArgs
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
if (caps.checkout?.enabled) {
|
|
243
|
+
client.checkout = resolveCapabilityWithFactory(
|
|
244
|
+
capabilities.checkout,
|
|
245
|
+
{
|
|
246
|
+
factory: new MagentoCheckoutFactory(
|
|
247
|
+
CheckoutSchema,
|
|
248
|
+
ShippingMethodSchema,
|
|
249
|
+
PaymentMethodSchema,
|
|
250
|
+
config
|
|
251
|
+
),
|
|
252
|
+
capability: (args) => new MagentoCheckoutCapability(
|
|
253
|
+
args.config,
|
|
254
|
+
args.cache,
|
|
255
|
+
args.context,
|
|
256
|
+
args.magentoApi,
|
|
257
|
+
args.factory
|
|
258
|
+
)
|
|
259
|
+
},
|
|
260
|
+
buildCapabilityArgs
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
if (caps.productAssociations?.enabled) {
|
|
264
|
+
client.productAssociations = resolveCapabilityWithFactory(
|
|
265
|
+
capabilities.productAssociations,
|
|
266
|
+
{
|
|
267
|
+
factory: new MagentoProductAssociationsFactory(
|
|
268
|
+
ProductAssociationSchema,
|
|
269
|
+
config
|
|
270
|
+
),
|
|
271
|
+
capability: (args) => new MagentoProductAssociationsCapability(
|
|
272
|
+
args.config,
|
|
273
|
+
args.cache,
|
|
274
|
+
args.context,
|
|
275
|
+
args.magentoApi,
|
|
276
|
+
args.factory
|
|
277
|
+
)
|
|
278
|
+
},
|
|
279
|
+
buildCapabilityArgs
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
if (caps.productRecommendations?.enabled) {
|
|
283
|
+
client.productRecommendations = resolveDirectCapability(
|
|
284
|
+
capabilities.productRecommendations,
|
|
285
|
+
(args) => new MagentoProductRecommendationsCapability(
|
|
286
|
+
args.config,
|
|
287
|
+
args.cache,
|
|
288
|
+
args.context,
|
|
289
|
+
args.magentoApi
|
|
290
|
+
),
|
|
291
|
+
{
|
|
292
|
+
cache,
|
|
293
|
+
context,
|
|
294
|
+
config,
|
|
295
|
+
magentoApi
|
|
296
|
+
}
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
if (caps.productReviews?.enabled) {
|
|
300
|
+
client.productReviews = resolveCapabilityWithFactory(
|
|
301
|
+
capabilities.productReviews,
|
|
302
|
+
{
|
|
303
|
+
factory: new MagentoProductReviewsFactory(
|
|
304
|
+
ProductRatingSummarySchema,
|
|
305
|
+
ProductReviewSchema,
|
|
306
|
+
ProductReviewPaginatedResultSchema
|
|
307
|
+
),
|
|
308
|
+
capability: (args) => new MagentoProductReviewsCapability(
|
|
309
|
+
args.config,
|
|
310
|
+
args.cache,
|
|
311
|
+
args.context,
|
|
312
|
+
args.magentoApi,
|
|
313
|
+
args.factory
|
|
314
|
+
)
|
|
315
|
+
},
|
|
316
|
+
buildCapabilityArgs
|
|
317
|
+
);
|
|
318
|
+
}
|
|
171
319
|
return client;
|
|
172
320
|
};
|
|
173
321
|
}
|