@reactionary/medusa 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 +517 -0
- package/capabilities/category.capability.js +216 -0
- package/capabilities/checkout.capability.js +533 -0
- package/capabilities/identity.capability.js +128 -0
- package/capabilities/inventory.capability.js +142 -0
- package/capabilities/order-search.capability.js +161 -0
- package/capabilities/order.capability.js +179 -0
- package/capabilities/price.capability.js +120 -0
- package/capabilities/product-associations.capability.js +148 -0
- package/capabilities/product-recommendations.capability.js +116 -0
- package/capabilities/product-search.capability.js +177 -0
- package/capabilities/product.capability.js +252 -0
- package/capabilities/profile.capability.js +333 -0
- package/core/client.js +269 -0
- package/core/initialize.js +290 -0
- package/core/initialize.types.js +13 -0
- package/factories/cart/cart.factory.js +17 -0
- package/factories/category/category.factory.js +17 -0
- package/factories/checkout/checkout.factory.js +22 -0
- package/factories/identity/identity.factory.js +12 -0
- package/factories/index.js +12 -0
- package/factories/inventory/inventory.factory.js +12 -0
- package/factories/order/order.factory.js +12 -0
- package/factories/order-search/order-search.factory.js +12 -0
- package/factories/price/price.factory.js +12 -0
- package/factories/product/product.factory.js +12 -0
- package/factories/product-associations/product-associations.factory.js +12 -0
- package/factories/product-search/product-search.factory.js +12 -0
- package/factories/profile/profile.factory.js +12 -0
- package/index.js +17 -0
- package/package.json +17 -0
- package/schema/capabilities.schema.js +43 -0
- package/schema/configuration.schema.js +11 -0
- package/schema/medusa.schema.js +26 -0
- package/src/capabilities/cart.capability.d.ts +100 -0
- package/src/capabilities/category.capability.d.ts +36 -0
- package/src/capabilities/checkout.capability.d.ts +88 -0
- package/src/capabilities/identity.capability.d.ts +13 -0
- package/src/capabilities/inventory.capability.d.ts +21 -0
- package/src/capabilities/order-search.capability.d.ts +53 -0
- package/src/capabilities/order.capability.d.ts +49 -0
- package/src/capabilities/price.capability.d.ts +16 -0
- package/src/capabilities/product-associations.capability.d.ts +19 -0
- package/src/capabilities/product-recommendations.capability.d.ts +41 -0
- package/src/capabilities/product-search.capability.d.ts +45 -0
- package/src/capabilities/product.capability.d.ts +32 -0
- package/src/capabilities/profile.capability.d.ts +39 -0
- package/src/core/client.d.ts +81 -0
- package/src/core/initialize.d.ts +5 -0
- package/src/core/initialize.types.d.ts +108 -0
- package/src/factories/cart/cart.factory.d.ts +9 -0
- package/src/factories/category/category.factory.d.ts +9 -0
- package/src/factories/checkout/checkout.factory.d.ts +11 -0
- package/src/factories/identity/identity.factory.d.ts +7 -0
- package/src/factories/index.d.ts +12 -0
- package/src/factories/inventory/inventory.factory.d.ts +7 -0
- package/src/factories/order/order.factory.d.ts +7 -0
- package/src/factories/order-search/order-search.factory.d.ts +7 -0
- package/src/factories/price/price.factory.d.ts +9 -0
- package/src/factories/product/product.factory.d.ts +7 -0
- package/src/factories/product-associations/product-associations.factory.d.ts +7 -0
- package/src/factories/product-search/product-search.factory.d.ts +7 -0
- package/src/factories/profile/profile.factory.d.ts +7 -0
- package/src/index.d.ts +17 -0
- package/src/schema/capabilities.schema.d.ts +116 -0
- package/src/schema/configuration.schema.d.ts +9 -0
- package/src/schema/medusa.schema.d.ts +33 -0
- package/src/test/test-utils.d.ts +2 -0
- package/src/utils/medusa-helpers.d.ts +35 -0
- package/test/test-utils.js +12 -0
- package/utils/medusa-helpers.js +72 -0
|
@@ -0,0 +1,533 @@
|
|
|
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
|
+
AddressIdentifierSchema,
|
|
14
|
+
CheckoutMutationAddPaymentInstructionSchema,
|
|
15
|
+
CheckoutMutationFinalizeCheckoutSchema,
|
|
16
|
+
CheckoutMutationInitiateCheckoutSchema,
|
|
17
|
+
CheckoutMutationRemovePaymentInstructionSchema,
|
|
18
|
+
CheckoutMutationSetShippingAddressSchema,
|
|
19
|
+
CheckoutMutationSetShippingInstructionSchema,
|
|
20
|
+
CheckoutCapability,
|
|
21
|
+
CheckoutQueryByIdSchema,
|
|
22
|
+
CheckoutQueryForAvailablePaymentMethodsSchema,
|
|
23
|
+
CheckoutQueryForAvailableShippingMethodsSchema,
|
|
24
|
+
CheckoutSchema,
|
|
25
|
+
MonetaryAmountSchema,
|
|
26
|
+
PaymentMethodSchema,
|
|
27
|
+
Reactionary,
|
|
28
|
+
ShippingMethodIdentifierSchema,
|
|
29
|
+
ShippingMethodSchema,
|
|
30
|
+
success,
|
|
31
|
+
error
|
|
32
|
+
} from "@reactionary/core";
|
|
33
|
+
import createDebug from "debug";
|
|
34
|
+
import * as z from "zod";
|
|
35
|
+
import { handleProviderError, parseMedusaCostBreakdown, parseMedusaItemPrice } from "../utils/medusa-helpers.js";
|
|
36
|
+
import {
|
|
37
|
+
} from "../schema/medusa.schema.js";
|
|
38
|
+
const debug = createDebug("reactionary:medusa:checkout");
|
|
39
|
+
class CheckoutNotReadyForFinalizationError extends Error {
|
|
40
|
+
constructor(checkoutIdentifier) {
|
|
41
|
+
super(
|
|
42
|
+
"Checkout is not ready for finalization. Ensure all required fields are set and valid. " + (checkoutIdentifier ? `Checkout ID: ${JSON.stringify(checkoutIdentifier)}` : "")
|
|
43
|
+
);
|
|
44
|
+
this.checkoutIdentifier = checkoutIdentifier;
|
|
45
|
+
this.name = "CheckoutNotReadyForFinalizationError";
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
class MedusaCheckoutCapability extends CheckoutCapability {
|
|
49
|
+
constructor(config, cache, context, medusaApi, factory) {
|
|
50
|
+
super(cache, context);
|
|
51
|
+
this.medusaApi = medusaApi;
|
|
52
|
+
this.config = config;
|
|
53
|
+
this.factory = factory;
|
|
54
|
+
}
|
|
55
|
+
config;
|
|
56
|
+
factory;
|
|
57
|
+
/**
|
|
58
|
+
* This controls which fields are always included when fetching a cart
|
|
59
|
+
* You can override this in a subclass to add more fields as needed.
|
|
60
|
+
*
|
|
61
|
+
* example: this.includedFields = [includedFields, '+discounts.*'].join(',');
|
|
62
|
+
*/
|
|
63
|
+
includedFields = ["+items.*"].join(",");
|
|
64
|
+
initiateCheckoutForCartPayload(payload) {
|
|
65
|
+
return {
|
|
66
|
+
billing_address: payload.billingAddress ? this.mapAddressToStoreAddress(payload.billingAddress) : void 0,
|
|
67
|
+
shipping_address: payload.billingAddress ? this.mapAddressToStoreAddress(payload.billingAddress) : void 0,
|
|
68
|
+
email: payload.notificationEmail,
|
|
69
|
+
metadata: {
|
|
70
|
+
sms_notification: payload.notificationPhone
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
async initiateCheckoutForCart(payload) {
|
|
75
|
+
const client = await this.medusaApi.getClient();
|
|
76
|
+
if (debug.enabled) {
|
|
77
|
+
debug(
|
|
78
|
+
`Initiating checkout for cart with key: ${payload.cart.identifier.key}`
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
const response = await client.store.cart.update(
|
|
82
|
+
payload.cart.identifier.key,
|
|
83
|
+
this.initiateCheckoutForCartPayload(payload),
|
|
84
|
+
{
|
|
85
|
+
fields: this.includedFields
|
|
86
|
+
}
|
|
87
|
+
);
|
|
88
|
+
return success(this.parseSingle(response.cart));
|
|
89
|
+
}
|
|
90
|
+
async getById(payload) {
|
|
91
|
+
const client = await this.medusaApi.getClient();
|
|
92
|
+
const response = await client.store.cart.retrieve(payload.identifier.key, {
|
|
93
|
+
fields: this.includedFields
|
|
94
|
+
});
|
|
95
|
+
return success(this.parseSingle(response.cart));
|
|
96
|
+
}
|
|
97
|
+
setShippingAddressPayload(payload) {
|
|
98
|
+
return {
|
|
99
|
+
shipping_address: this.mapAddressToStoreAddress(payload.shippingAddress)
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
async setShippingAddress(payload) {
|
|
103
|
+
const client = await this.medusaApi.getClient();
|
|
104
|
+
const response = await client.store.cart.update(
|
|
105
|
+
payload.checkout.key,
|
|
106
|
+
this.setShippingAddressPayload(payload),
|
|
107
|
+
{
|
|
108
|
+
fields: this.includedFields
|
|
109
|
+
}
|
|
110
|
+
);
|
|
111
|
+
return success(this.parseSingle(response.cart));
|
|
112
|
+
}
|
|
113
|
+
getAvailableShippingMethodsPayload(payload) {
|
|
114
|
+
return {
|
|
115
|
+
cart_id: payload.checkout.key
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
async getAvailableShippingMethods(payload) {
|
|
119
|
+
const client = await this.medusaApi.getClient();
|
|
120
|
+
if (debug.enabled) {
|
|
121
|
+
debug(
|
|
122
|
+
`Fetching available shipping methods for checkout with key: ${payload.checkout.key}`
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
const shippingMethodResponse = await client.store.fulfillment.listCartOptions(
|
|
126
|
+
this.getAvailableShippingMethodsPayload(payload)
|
|
127
|
+
);
|
|
128
|
+
const shippingMethods = [];
|
|
129
|
+
for (const sm of shippingMethodResponse.shipping_options) {
|
|
130
|
+
shippingMethods.push(
|
|
131
|
+
ShippingMethodSchema.parse({
|
|
132
|
+
identifier: ShippingMethodIdentifierSchema.parse({ key: sm.id }),
|
|
133
|
+
name: sm.name,
|
|
134
|
+
description: sm.type.description || "",
|
|
135
|
+
price: MonetaryAmountSchema.parse({
|
|
136
|
+
value: sm.calculated_price.calculated_amount || 0,
|
|
137
|
+
currency: sm.calculated_price.currency_code?.toUpperCase()
|
|
138
|
+
}),
|
|
139
|
+
deliveryTime: ""
|
|
140
|
+
})
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
if (debug.enabled) {
|
|
144
|
+
debug(
|
|
145
|
+
`Found ${shippingMethods.length} shipping methods for checkout with key: ${payload.checkout.key}`,
|
|
146
|
+
shippingMethods
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
return success(
|
|
150
|
+
shippingMethods.map((x) => this.factory.parseShippingMethod(this.context, x))
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
getAvailablePaymentMethodsPayload(payload, regionId) {
|
|
154
|
+
return {
|
|
155
|
+
region_id: regionId
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
async getAvailablePaymentMethods(payload) {
|
|
159
|
+
const client = await this.medusaApi.getClient();
|
|
160
|
+
if (debug.enabled) {
|
|
161
|
+
debug(
|
|
162
|
+
`Fetching available payment methods for checkout with key: ${payload.checkout.key}`
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
const checkout = await client.store.cart.retrieve(payload.checkout.key);
|
|
166
|
+
const paymentMethodResponse = await client.store.payment.listPaymentProviders(
|
|
167
|
+
this.getAvailablePaymentMethodsPayload(
|
|
168
|
+
payload,
|
|
169
|
+
checkout.cart.region_id || (await this.medusaApi.getActiveRegion()).id
|
|
170
|
+
)
|
|
171
|
+
);
|
|
172
|
+
const paymentMethods = [];
|
|
173
|
+
for (const pm of paymentMethodResponse.payment_providers) {
|
|
174
|
+
paymentMethods.push(
|
|
175
|
+
{
|
|
176
|
+
identifier: {
|
|
177
|
+
method: pm.id,
|
|
178
|
+
name: pm.id,
|
|
179
|
+
paymentProcessor: pm.id
|
|
180
|
+
},
|
|
181
|
+
logo: void 0,
|
|
182
|
+
description: pm.id,
|
|
183
|
+
isPunchOut: true
|
|
184
|
+
}
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
if (debug.enabled) {
|
|
188
|
+
debug(
|
|
189
|
+
`Found ${paymentMethods.length} payment methods for checkout with key: ${payload.checkout.key}`,
|
|
190
|
+
paymentMethods
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
return success(
|
|
194
|
+
paymentMethods.map((x) => this.factory.parsePaymentMethod(this.context, x))
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
addPaymentInstructionPayload(payload) {
|
|
198
|
+
return {
|
|
199
|
+
provider_id: payload.paymentInstruction.paymentMethod.method,
|
|
200
|
+
data: payload.paymentInstruction.protocolData.reduce((acc, curr) => {
|
|
201
|
+
acc[curr.key] = curr.value;
|
|
202
|
+
return acc;
|
|
203
|
+
}, {})
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
async addPaymentInstruction(payload) {
|
|
207
|
+
const client = await this.medusaApi.getClient();
|
|
208
|
+
if (debug.enabled) {
|
|
209
|
+
debug(
|
|
210
|
+
`Adding payment instruction ${payload.paymentInstruction.paymentMethod.name} to checkout with key: ${payload.checkout.key}`
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
try {
|
|
214
|
+
const cartResponse = await client.store.cart.retrieve(
|
|
215
|
+
payload.checkout.key
|
|
216
|
+
);
|
|
217
|
+
const paymentSessionResponse = await client.store.payment.initiatePaymentSession(cartResponse.cart, this.addPaymentInstructionPayload(payload));
|
|
218
|
+
const updatedCartResponse = await client.store.cart.retrieve(
|
|
219
|
+
payload.checkout.key,
|
|
220
|
+
{
|
|
221
|
+
fields: this.includedFields
|
|
222
|
+
}
|
|
223
|
+
);
|
|
224
|
+
return success(this.parseSingle(updatedCartResponse.cart));
|
|
225
|
+
} catch (error2) {
|
|
226
|
+
debug("Failed to add payment instruction: {0}", [error2]);
|
|
227
|
+
throw new Error(
|
|
228
|
+
`Failed to add payment instruction: ${error2 instanceof Error ? error2.message : "Unknown error"}`
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
removePaymentInstruction(payload) {
|
|
233
|
+
throw new Error("Method not implemented.");
|
|
234
|
+
}
|
|
235
|
+
setShippingInstructionPayload(payload) {
|
|
236
|
+
return {
|
|
237
|
+
option_id: payload.shippingInstruction.shippingMethod.key,
|
|
238
|
+
data: {
|
|
239
|
+
consent_for_unattended_delivery: payload.shippingInstruction.consentForUnattendedDelivery + "",
|
|
240
|
+
instructions: payload.shippingInstruction.instructions || ""
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
async setShippingInstruction(payload) {
|
|
245
|
+
const client = await this.medusaApi.getClient();
|
|
246
|
+
const medusaId = payload.checkout;
|
|
247
|
+
try {
|
|
248
|
+
if (payload.shippingInstruction.shippingMethod) {
|
|
249
|
+
await client.store.cart.addShippingMethod(medusaId.key, this.setShippingInstructionPayload(payload));
|
|
250
|
+
}
|
|
251
|
+
await client.store.cart.update(medusaId.key, {
|
|
252
|
+
metadata: {
|
|
253
|
+
consent_for_unattended_delivery: payload.shippingInstruction.consentForUnattendedDelivery + "",
|
|
254
|
+
instructions: payload.shippingInstruction.instructions || "",
|
|
255
|
+
pickup_point: payload.shippingInstruction.pickupPoint || ""
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
const response = await client.store.cart.retrieve(medusaId.key, {
|
|
259
|
+
fields: this.includedFields
|
|
260
|
+
});
|
|
261
|
+
if (response.cart) {
|
|
262
|
+
return success(this.parseSingle(response.cart));
|
|
263
|
+
}
|
|
264
|
+
throw new Error("Failed to set shipping method");
|
|
265
|
+
} catch (error2) {
|
|
266
|
+
handleProviderError("set shipping method", error2);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
async finalizeCheckout(payload) {
|
|
270
|
+
const checkout = await this.getById({ identifier: payload.checkout });
|
|
271
|
+
if (!checkout.success || !checkout.value.readyForFinalization) {
|
|
272
|
+
throw new CheckoutNotReadyForFinalizationError(payload.checkout);
|
|
273
|
+
}
|
|
274
|
+
const client = await this.medusaApi.getClient();
|
|
275
|
+
const medusaId = payload.checkout;
|
|
276
|
+
const response = await client.store.cart.complete(medusaId.key);
|
|
277
|
+
if (response.type === "order") {
|
|
278
|
+
await client.store.cart.update(medusaId.key, {
|
|
279
|
+
metadata: {
|
|
280
|
+
order_id: response.order.id,
|
|
281
|
+
order_display_id: response.order?.display_id ? 0 : ""
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
const refreshedCheckout = await this.getById({
|
|
285
|
+
identifier: payload.checkout
|
|
286
|
+
});
|
|
287
|
+
if (!refreshedCheckout.success) {
|
|
288
|
+
throw new Error(`Unable to reload checkout ${payload.checkout.key} after completion`);
|
|
289
|
+
}
|
|
290
|
+
return success(refreshedCheckout.value);
|
|
291
|
+
}
|
|
292
|
+
throw new Error("Something failed during order creation");
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Extension point to map an Address to a Store Address
|
|
296
|
+
* @param address
|
|
297
|
+
* @returns
|
|
298
|
+
*/
|
|
299
|
+
mapAddressToStoreAddress(address) {
|
|
300
|
+
return {
|
|
301
|
+
first_name: address.firstName,
|
|
302
|
+
last_name: address.lastName,
|
|
303
|
+
address_1: address.streetAddress,
|
|
304
|
+
address_2: address.streetNumber || "",
|
|
305
|
+
city: address.city,
|
|
306
|
+
postal_code: address.postalCode,
|
|
307
|
+
country_code: address.countryCode?.toLowerCase()
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Extension point to control the parsing of an address from a store cart address
|
|
312
|
+
* @param storeAddress
|
|
313
|
+
* @returns
|
|
314
|
+
*/
|
|
315
|
+
composeAddressFromStoreAddress(storeAddress) {
|
|
316
|
+
return {
|
|
317
|
+
identifier: AddressIdentifierSchema.parse({
|
|
318
|
+
nickName: storeAddress.id
|
|
319
|
+
}),
|
|
320
|
+
firstName: storeAddress.first_name || "",
|
|
321
|
+
lastName: storeAddress.last_name || "",
|
|
322
|
+
streetAddress: storeAddress.address_1 || "",
|
|
323
|
+
streetNumber: storeAddress.address_2 || "",
|
|
324
|
+
city: storeAddress.city || "",
|
|
325
|
+
postalCode: storeAddress.postal_code || "",
|
|
326
|
+
countryCode: storeAddress.country_code || "",
|
|
327
|
+
region: ""
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Extension point to control the parsing of a single cart item price
|
|
332
|
+
* @param remoteItem
|
|
333
|
+
* @param currency
|
|
334
|
+
* @returns
|
|
335
|
+
*/
|
|
336
|
+
parseItemPrice(remoteItem, currency) {
|
|
337
|
+
return parseMedusaItemPrice(remoteItem, currency);
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Extension point to control the parsing of the cost breakdown of a cart
|
|
341
|
+
* @param remote
|
|
342
|
+
* @returns
|
|
343
|
+
*/
|
|
344
|
+
parseCostBreakdown(remote) {
|
|
345
|
+
return parseMedusaCostBreakdown(remote);
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Extension point to control the parsing of a single checkout item
|
|
349
|
+
* @param remoteItem
|
|
350
|
+
* @param currency
|
|
351
|
+
* @returns
|
|
352
|
+
*/
|
|
353
|
+
parseCheckoutItem(remoteItem, currency) {
|
|
354
|
+
const unitPrice = remoteItem.unit_price || 0;
|
|
355
|
+
const totalPrice = unitPrice * remoteItem.quantity || 0;
|
|
356
|
+
const discountTotal = remoteItem.discount_total || 0;
|
|
357
|
+
const item = {
|
|
358
|
+
identifier: {
|
|
359
|
+
key: remoteItem.id
|
|
360
|
+
},
|
|
361
|
+
variant: {
|
|
362
|
+
sku: remoteItem.variant_sku || ""
|
|
363
|
+
},
|
|
364
|
+
quantity: remoteItem.quantity || 1,
|
|
365
|
+
price: this.parseItemPrice(remoteItem, currency)
|
|
366
|
+
};
|
|
367
|
+
return item;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Extension point to control the parsing of the Checkout object
|
|
371
|
+
* @param remote
|
|
372
|
+
* @returns
|
|
373
|
+
*/
|
|
374
|
+
parseSingle(remote) {
|
|
375
|
+
const identifier = {
|
|
376
|
+
key: remote.id
|
|
377
|
+
// region_id: remote.region_id,
|
|
378
|
+
};
|
|
379
|
+
const name = "" + (remote.metadata?.["name"] || "");
|
|
380
|
+
const description = "" + (remote.metadata?.["description"] || "");
|
|
381
|
+
const price = this.parseCostBreakdown(remote);
|
|
382
|
+
const items = new Array();
|
|
383
|
+
for (const remoteItem of remote.items || []) {
|
|
384
|
+
items.push(this.parseCheckoutItem(remoteItem, price.grandTotal.currency));
|
|
385
|
+
}
|
|
386
|
+
const billingAddress = remote.billing_address ? this.composeAddressFromStoreAddress(remote.billing_address) : void 0;
|
|
387
|
+
const shippingAddress = remote.shipping_address ? this.composeAddressFromStoreAddress(remote.shipping_address) : void 0;
|
|
388
|
+
const backupUnattendedDelivery = remote.metadata?.["consent_for_unattended_delivery"] !== void 0 ? remote.metadata?.["consent_for_unattended_delivery"] === "true" : void 0;
|
|
389
|
+
const backupInstructions = remote.metadata?.["instructions"] !== void 0 ? remote.metadata?.["instructions"] + "" : void 0;
|
|
390
|
+
const backupPickupPoint = remote.metadata?.["pickup_point"] !== void 0 ? remote.metadata?.["pickup_point"] + "" : void 0;
|
|
391
|
+
let shippingInstruction;
|
|
392
|
+
remote.shipping_methods?.forEach((sm) => {
|
|
393
|
+
let pickupPoint = "";
|
|
394
|
+
let instructions = "";
|
|
395
|
+
let consentForUnattendedDelivery = false;
|
|
396
|
+
if (sm.data) {
|
|
397
|
+
pickupPoint = sm.data["pickup_point"] + "" || "";
|
|
398
|
+
instructions = sm.data["instructions"] + "" || "";
|
|
399
|
+
consentForUnattendedDelivery = sm.data["consent_for_unattended_delivery"] === "true";
|
|
400
|
+
}
|
|
401
|
+
if (!pickupPoint) {
|
|
402
|
+
pickupPoint = backupPickupPoint || "";
|
|
403
|
+
}
|
|
404
|
+
if (!instructions) {
|
|
405
|
+
instructions = backupInstructions || "";
|
|
406
|
+
}
|
|
407
|
+
if (!consentForUnattendedDelivery) {
|
|
408
|
+
consentForUnattendedDelivery = backupUnattendedDelivery || false;
|
|
409
|
+
}
|
|
410
|
+
shippingInstruction = {
|
|
411
|
+
shippingMethod: { key: sm.shipping_option_id },
|
|
412
|
+
consentForUnattendedDelivery,
|
|
413
|
+
instructions,
|
|
414
|
+
pickupPoint
|
|
415
|
+
};
|
|
416
|
+
});
|
|
417
|
+
const paymentInstructions = new Array();
|
|
418
|
+
for (const remotePayment of remote.payment_collection?.payment_sessions || []) {
|
|
419
|
+
if (remotePayment.status === "canceled" || remotePayment.status === "error") {
|
|
420
|
+
console.warn(
|
|
421
|
+
`Skipping payment session ${remotePayment.id} with status ${remotePayment.status}`
|
|
422
|
+
);
|
|
423
|
+
continue;
|
|
424
|
+
}
|
|
425
|
+
const paymentMethodIdentifier = {
|
|
426
|
+
method: remotePayment.provider_id,
|
|
427
|
+
name: remotePayment.provider_id,
|
|
428
|
+
paymentProcessor: remotePayment.provider_id
|
|
429
|
+
};
|
|
430
|
+
paymentInstructions.push(
|
|
431
|
+
{
|
|
432
|
+
identifier: {
|
|
433
|
+
key: remotePayment.id
|
|
434
|
+
},
|
|
435
|
+
amount: {
|
|
436
|
+
value: remotePayment.amount,
|
|
437
|
+
currency: remotePayment.currency_code?.toUpperCase()
|
|
438
|
+
},
|
|
439
|
+
paymentMethod: paymentMethodIdentifier,
|
|
440
|
+
protocolData: remotePayment.data ? Object.entries(remotePayment.data).map(([key, value]) => ({
|
|
441
|
+
key,
|
|
442
|
+
value: String(value)
|
|
443
|
+
})) : [],
|
|
444
|
+
status: "pending"
|
|
445
|
+
}
|
|
446
|
+
);
|
|
447
|
+
}
|
|
448
|
+
const originalCartReference = {
|
|
449
|
+
key: remote.id,
|
|
450
|
+
region: remote.region_id
|
|
451
|
+
};
|
|
452
|
+
let resultingOrder = void 0;
|
|
453
|
+
if (remote.metadata?.["order_id"]) {
|
|
454
|
+
resultingOrder = {
|
|
455
|
+
key: remote.metadata?.["order_id"] + "" || "",
|
|
456
|
+
display_id: Number(remote.metadata?.["order_display_id"] + "" || "0")
|
|
457
|
+
};
|
|
458
|
+
}
|
|
459
|
+
const result = {
|
|
460
|
+
identifier,
|
|
461
|
+
name,
|
|
462
|
+
description,
|
|
463
|
+
price,
|
|
464
|
+
items,
|
|
465
|
+
originalCartReference,
|
|
466
|
+
paymentInstructions,
|
|
467
|
+
readyForFinalization: false,
|
|
468
|
+
billingAddress,
|
|
469
|
+
resultingOrder,
|
|
470
|
+
shippingAddress,
|
|
471
|
+
shippingInstruction
|
|
472
|
+
};
|
|
473
|
+
return this.factory.parseCheckout(this.context, result);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
__decorateClass([
|
|
477
|
+
Reactionary({
|
|
478
|
+
inputSchema: CheckoutMutationInitiateCheckoutSchema,
|
|
479
|
+
outputSchema: CheckoutSchema
|
|
480
|
+
})
|
|
481
|
+
], MedusaCheckoutCapability.prototype, "initiateCheckoutForCart", 1);
|
|
482
|
+
__decorateClass([
|
|
483
|
+
Reactionary({
|
|
484
|
+
inputSchema: CheckoutQueryByIdSchema,
|
|
485
|
+
outputSchema: CheckoutSchema.nullable()
|
|
486
|
+
})
|
|
487
|
+
], MedusaCheckoutCapability.prototype, "getById", 1);
|
|
488
|
+
__decorateClass([
|
|
489
|
+
Reactionary({
|
|
490
|
+
inputSchema: CheckoutMutationSetShippingAddressSchema,
|
|
491
|
+
outputSchema: CheckoutSchema
|
|
492
|
+
})
|
|
493
|
+
], MedusaCheckoutCapability.prototype, "setShippingAddress", 1);
|
|
494
|
+
__decorateClass([
|
|
495
|
+
Reactionary({
|
|
496
|
+
inputSchema: CheckoutQueryForAvailableShippingMethodsSchema,
|
|
497
|
+
outputSchema: z.array(ShippingMethodSchema)
|
|
498
|
+
})
|
|
499
|
+
], MedusaCheckoutCapability.prototype, "getAvailableShippingMethods", 1);
|
|
500
|
+
__decorateClass([
|
|
501
|
+
Reactionary({
|
|
502
|
+
inputSchema: CheckoutQueryForAvailablePaymentMethodsSchema,
|
|
503
|
+
outputSchema: z.array(PaymentMethodSchema)
|
|
504
|
+
})
|
|
505
|
+
], MedusaCheckoutCapability.prototype, "getAvailablePaymentMethods", 1);
|
|
506
|
+
__decorateClass([
|
|
507
|
+
Reactionary({
|
|
508
|
+
inputSchema: CheckoutMutationAddPaymentInstructionSchema,
|
|
509
|
+
outputSchema: CheckoutSchema
|
|
510
|
+
})
|
|
511
|
+
], MedusaCheckoutCapability.prototype, "addPaymentInstruction", 1);
|
|
512
|
+
__decorateClass([
|
|
513
|
+
Reactionary({
|
|
514
|
+
inputSchema: CheckoutMutationRemovePaymentInstructionSchema,
|
|
515
|
+
outputSchema: CheckoutSchema
|
|
516
|
+
})
|
|
517
|
+
], MedusaCheckoutCapability.prototype, "removePaymentInstruction", 1);
|
|
518
|
+
__decorateClass([
|
|
519
|
+
Reactionary({
|
|
520
|
+
inputSchema: CheckoutMutationSetShippingInstructionSchema,
|
|
521
|
+
outputSchema: CheckoutSchema
|
|
522
|
+
})
|
|
523
|
+
], MedusaCheckoutCapability.prototype, "setShippingInstruction", 1);
|
|
524
|
+
__decorateClass([
|
|
525
|
+
Reactionary({
|
|
526
|
+
inputSchema: CheckoutMutationFinalizeCheckoutSchema,
|
|
527
|
+
outputSchema: CheckoutSchema
|
|
528
|
+
})
|
|
529
|
+
], MedusaCheckoutCapability.prototype, "finalizeCheckout", 1);
|
|
530
|
+
export {
|
|
531
|
+
CheckoutNotReadyForFinalizationError,
|
|
532
|
+
MedusaCheckoutCapability
|
|
533
|
+
};
|
|
@@ -0,0 +1,128 @@
|
|
|
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:medusa:identity");
|
|
24
|
+
class MedusaIdentityCapability extends IdentityCapability {
|
|
25
|
+
config;
|
|
26
|
+
medusaApi;
|
|
27
|
+
constructor(config, cache, context, medusaApi) {
|
|
28
|
+
super(cache, context);
|
|
29
|
+
this.config = config;
|
|
30
|
+
this.medusaApi = medusaApi;
|
|
31
|
+
}
|
|
32
|
+
createAnonymousIdentity() {
|
|
33
|
+
return {
|
|
34
|
+
type: "Anonymous"
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
async getSelf(_payload) {
|
|
38
|
+
try {
|
|
39
|
+
const medusaClient = await this.medusaApi.getClient();
|
|
40
|
+
const token = await medusaClient.client.getToken();
|
|
41
|
+
if (!token) {
|
|
42
|
+
debug("No active session token found, returning anonymous identity");
|
|
43
|
+
const identity2 = this.createAnonymousIdentity();
|
|
44
|
+
this.updateIdentityContext(identity2);
|
|
45
|
+
return success(identity2);
|
|
46
|
+
}
|
|
47
|
+
const customerResponse = await medusaClient.store.customer.retrieve();
|
|
48
|
+
if (customerResponse.customer) {
|
|
49
|
+
debug("Customer authenticated:", customerResponse.customer.email);
|
|
50
|
+
const identity2 = {
|
|
51
|
+
id: {
|
|
52
|
+
userId: customerResponse.customer.id
|
|
53
|
+
},
|
|
54
|
+
type: "Registered"
|
|
55
|
+
};
|
|
56
|
+
this.updateIdentityContext(identity2);
|
|
57
|
+
return success(identity2);
|
|
58
|
+
}
|
|
59
|
+
const identity = this.createAnonymousIdentity();
|
|
60
|
+
this.updateIdentityContext(identity);
|
|
61
|
+
return success(identity);
|
|
62
|
+
} catch (error) {
|
|
63
|
+
debug("getSelf failed, returning anonymous identity:", error);
|
|
64
|
+
const identity = this.createAnonymousIdentity();
|
|
65
|
+
this.updateIdentityContext(identity);
|
|
66
|
+
return success(identity);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
async login(payload) {
|
|
70
|
+
debug("Attempting login for user:", payload.username);
|
|
71
|
+
const identity = await this.medusaApi.login(
|
|
72
|
+
payload.username,
|
|
73
|
+
payload.password,
|
|
74
|
+
this.context
|
|
75
|
+
);
|
|
76
|
+
this.updateIdentityContext(identity);
|
|
77
|
+
return success(identity);
|
|
78
|
+
}
|
|
79
|
+
async logout(_payload) {
|
|
80
|
+
debug("Logging out user");
|
|
81
|
+
const identity = await this.medusaApi.logout(this.context);
|
|
82
|
+
this.updateIdentityContext(identity);
|
|
83
|
+
return success(identity);
|
|
84
|
+
}
|
|
85
|
+
async register(payload) {
|
|
86
|
+
debug("Registering new user:", payload.username);
|
|
87
|
+
const nameParts = payload.username.split(".");
|
|
88
|
+
const firstName = nameParts[0] || "User";
|
|
89
|
+
const lastName = nameParts.slice(1).join(" ") || "Account";
|
|
90
|
+
const identity = await this.medusaApi.register(
|
|
91
|
+
payload.username,
|
|
92
|
+
// Using username as email
|
|
93
|
+
payload.password,
|
|
94
|
+
firstName,
|
|
95
|
+
lastName,
|
|
96
|
+
this.context
|
|
97
|
+
);
|
|
98
|
+
this.updateIdentityContext(identity);
|
|
99
|
+
return success(identity);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
__decorateClass([
|
|
103
|
+
Reactionary({
|
|
104
|
+
inputSchema: IdentityQuerySelfSchema,
|
|
105
|
+
outputSchema: IdentitySchema
|
|
106
|
+
})
|
|
107
|
+
], MedusaIdentityCapability.prototype, "getSelf", 1);
|
|
108
|
+
__decorateClass([
|
|
109
|
+
Reactionary({
|
|
110
|
+
inputSchema: IdentityMutationLoginSchema,
|
|
111
|
+
outputSchema: IdentitySchema
|
|
112
|
+
})
|
|
113
|
+
], MedusaIdentityCapability.prototype, "login", 1);
|
|
114
|
+
__decorateClass([
|
|
115
|
+
Reactionary({
|
|
116
|
+
inputSchema: IdentityMutationLogoutSchema,
|
|
117
|
+
outputSchema: IdentitySchema
|
|
118
|
+
})
|
|
119
|
+
], MedusaIdentityCapability.prototype, "logout", 1);
|
|
120
|
+
__decorateClass([
|
|
121
|
+
Reactionary({
|
|
122
|
+
inputSchema: IdentityMutationRegisterSchema,
|
|
123
|
+
outputSchema: IdentitySchema
|
|
124
|
+
})
|
|
125
|
+
], MedusaIdentityCapability.prototype, "register", 1);
|
|
126
|
+
export {
|
|
127
|
+
MedusaIdentityCapability
|
|
128
|
+
};
|