@reactionary/provider-medusa 0.2.1 → 0.2.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/core/initialize.js +16 -4
- package/index.js +3 -0
- package/package.json +2 -2
- package/providers/order-search.provider.js +157 -0
- package/providers/order.provider.js +175 -0
- package/providers/profile.provider.js +323 -0
- package/schema/capabilities.schema.js +4 -1
- package/src/index.d.ts +3 -0
- package/src/providers/order-search.provider.d.ts +91 -0
- package/src/providers/order.provider.d.ts +51 -0
- package/src/providers/profile.provider.d.ts +30 -0
- package/src/schema/capabilities.schema.d.ts +3 -0
- package/src/utils/medusa-helpers.d.ts +2 -2
package/core/initialize.js
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import { MedusaCartProvider } from "../providers/cart.provider.js";
|
|
2
|
+
import { MedusaCategoryProvider } from "../providers/category.provider.js";
|
|
3
|
+
import { MedusaCheckoutProvider } from "../providers/checkout.provider.js";
|
|
2
4
|
import { MedusaIdentityProvider } from "../providers/identity.provider.js";
|
|
3
5
|
import { MedusaInventoryProvider } from "../providers/inventory.provider.js";
|
|
6
|
+
import { MedusaOrderSearchProvider } from "../providers/order-search.provider.js";
|
|
7
|
+
import { MedusaOrderProvider } from "../providers/order.provider.js";
|
|
4
8
|
import { MedusaPriceProvider } from "../providers/price.provider.js";
|
|
5
|
-
import { MedusaCapabilitiesSchema } from "../schema/capabilities.schema.js";
|
|
6
|
-
import { MedusaConfigurationSchema } from "../schema/configuration.schema.js";
|
|
7
9
|
import { MedusaSearchProvider } from "../providers/product-search.provider.js";
|
|
8
10
|
import { MedusaProductProvider } from "../providers/product.provider.js";
|
|
11
|
+
import { MedusaProfileProvider } from "../providers/profile.provider.js";
|
|
12
|
+
import { MedusaCapabilitiesSchema } from "../schema/capabilities.schema.js";
|
|
13
|
+
import { MedusaConfigurationSchema } from "../schema/configuration.schema.js";
|
|
9
14
|
import { MedusaClient } from "./client.js";
|
|
10
|
-
import { MedusaCategoryProvider } from "../providers/category.provider.js";
|
|
11
|
-
import { MedusaCheckoutProvider } from "../providers/checkout.provider.js";
|
|
12
15
|
function withMedusaCapabilities(configuration, capabilities) {
|
|
13
16
|
return (cache, context) => {
|
|
14
17
|
const client = {};
|
|
@@ -39,6 +42,15 @@ function withMedusaCapabilities(configuration, capabilities) {
|
|
|
39
42
|
if (caps.identity) {
|
|
40
43
|
client.identity = new MedusaIdentityProvider(configuration, cache, context, medusaClient);
|
|
41
44
|
}
|
|
45
|
+
if (caps.profile) {
|
|
46
|
+
client.profile = new MedusaProfileProvider(configuration, cache, context, medusaClient);
|
|
47
|
+
}
|
|
48
|
+
if (caps.order) {
|
|
49
|
+
client.order = new MedusaOrderProvider(configuration, cache, context, medusaClient);
|
|
50
|
+
}
|
|
51
|
+
if (caps.orderSearch) {
|
|
52
|
+
client.orderSearch = new MedusaOrderSearchProvider(configuration, cache, context, medusaClient);
|
|
53
|
+
}
|
|
42
54
|
return client;
|
|
43
55
|
};
|
|
44
56
|
}
|
package/index.js
CHANGED
|
@@ -6,5 +6,8 @@ export * from "./core/client.js";
|
|
|
6
6
|
export * from "./providers/cart.provider.js";
|
|
7
7
|
export * from "./providers/identity.provider.js";
|
|
8
8
|
export * from "./providers/inventory.provider.js";
|
|
9
|
+
export * from "./providers/order.provider.js";
|
|
10
|
+
export * from "./providers/order-search.provider.js";
|
|
9
11
|
export * from "./providers/price.provider.js";
|
|
10
12
|
export * from "./providers/product-search.provider.js";
|
|
13
|
+
export * from "./providers/profile.provider.js";
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reactionary/provider-medusa",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "src/index.d.ts",
|
|
7
7
|
"dependencies": {
|
|
8
8
|
"zod": "4.1.9",
|
|
9
|
-
"@reactionary/core": "0.2.
|
|
9
|
+
"@reactionary/core": "0.2.3",
|
|
10
10
|
"@medusajs/js-sdk": "^2.0.0",
|
|
11
11
|
"debug": "^4.3.4",
|
|
12
12
|
"@medusajs/types": "^2.11.0",
|
|
@@ -0,0 +1,157 @@
|
|
|
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
|
+
OrderSearchProvider,
|
|
15
|
+
OrderSearchQueryByTermSchema,
|
|
16
|
+
OrderSearchResultSchema,
|
|
17
|
+
Reactionary,
|
|
18
|
+
success
|
|
19
|
+
} from "@reactionary/core";
|
|
20
|
+
import createDebug from "debug";
|
|
21
|
+
const debug = createDebug("reactionary:medusa:order-search");
|
|
22
|
+
class MedusaOrderSearchProvider extends OrderSearchProvider {
|
|
23
|
+
constructor(config, cache, context, client) {
|
|
24
|
+
super(cache, context);
|
|
25
|
+
this.config = config;
|
|
26
|
+
this.client = client;
|
|
27
|
+
}
|
|
28
|
+
async queryByTerm(payload) {
|
|
29
|
+
debug("queryByTerm", payload);
|
|
30
|
+
const medusa = await this.client.getClient();
|
|
31
|
+
if (payload.search.term) {
|
|
32
|
+
debug("Searching orders by term is not supported in Medusa");
|
|
33
|
+
}
|
|
34
|
+
if (payload.search.partNumber) {
|
|
35
|
+
debug("Searching orders by part number is not supported in Medusa");
|
|
36
|
+
}
|
|
37
|
+
if (payload.search.startDate) {
|
|
38
|
+
debug("Searching orders by start date is not supported in Medusa");
|
|
39
|
+
}
|
|
40
|
+
if (payload.search.endDate) {
|
|
41
|
+
debug("Searching orders by end date is not supported in Medusa");
|
|
42
|
+
}
|
|
43
|
+
if (payload.search.userId) {
|
|
44
|
+
debug("Searching orders by customer ID is not supported in Medusa");
|
|
45
|
+
}
|
|
46
|
+
const statusFilter = (payload.search.orderStatus ?? []).map((status) => {
|
|
47
|
+
let retStatus = "draft";
|
|
48
|
+
if (status === "AwaitingPayment") {
|
|
49
|
+
retStatus = "draft";
|
|
50
|
+
}
|
|
51
|
+
if (status === "ReleasedToFulfillment") {
|
|
52
|
+
retStatus = "pending";
|
|
53
|
+
}
|
|
54
|
+
if (status === "Shipped") {
|
|
55
|
+
retStatus = "completed";
|
|
56
|
+
}
|
|
57
|
+
if (status === "Cancelled") {
|
|
58
|
+
retStatus = "canceled";
|
|
59
|
+
}
|
|
60
|
+
return retStatus;
|
|
61
|
+
});
|
|
62
|
+
const response = await medusa.store.order.list({
|
|
63
|
+
status: statusFilter,
|
|
64
|
+
limit: payload.search.paginationOptions.pageSize,
|
|
65
|
+
offset: (payload.search.paginationOptions.pageNumber - 1) * payload.search.paginationOptions.pageSize
|
|
66
|
+
});
|
|
67
|
+
const result = this.parsePaginatedResult(response, payload);
|
|
68
|
+
if (debug.enabled) {
|
|
69
|
+
debug(
|
|
70
|
+
`Search for term "${payload.search.term}" returned ${response.orders.length} orders (page ${payload.search.paginationOptions.pageNumber} of ${result.totalPages})`
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
return success(result);
|
|
74
|
+
}
|
|
75
|
+
composeAddressFromStoreAddress(storeAddress) {
|
|
76
|
+
return {
|
|
77
|
+
identifier: AddressIdentifierSchema.parse({
|
|
78
|
+
nickName: storeAddress.id
|
|
79
|
+
}),
|
|
80
|
+
firstName: storeAddress.first_name || "",
|
|
81
|
+
lastName: storeAddress.last_name || "",
|
|
82
|
+
streetAddress: storeAddress.address_1 || "",
|
|
83
|
+
streetNumber: storeAddress.address_2 || "",
|
|
84
|
+
city: storeAddress.city || "",
|
|
85
|
+
postalCode: storeAddress.postal_code || "",
|
|
86
|
+
countryCode: storeAddress.country_code || "",
|
|
87
|
+
region: ""
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
parseSingle(body) {
|
|
91
|
+
const identifier = { key: body.id };
|
|
92
|
+
const userId = {
|
|
93
|
+
userId: body.customer_id || ""
|
|
94
|
+
};
|
|
95
|
+
const customerName = `${body.billing_address?.first_name} ${body.billing_address?.last_name}`;
|
|
96
|
+
const shippingAddress = this.composeAddressFromStoreAddress(body.shipping_address);
|
|
97
|
+
const orderDate = new Date(body.created_at).toISOString();
|
|
98
|
+
let orderStatus = "AwaitingPayment";
|
|
99
|
+
if (body.status === "draft") {
|
|
100
|
+
orderStatus = "AwaitingPayment";
|
|
101
|
+
}
|
|
102
|
+
if (body.status === "pending") {
|
|
103
|
+
orderStatus = "ReleasedToFulfillment";
|
|
104
|
+
}
|
|
105
|
+
if (body.status === "completed") {
|
|
106
|
+
orderStatus = "Shipped";
|
|
107
|
+
}
|
|
108
|
+
if (body.status === "canceled") {
|
|
109
|
+
orderStatus = "Cancelled";
|
|
110
|
+
}
|
|
111
|
+
let inventoryStatus = "NotAllocated";
|
|
112
|
+
if (body.fulfillment_status === "fulfilled") {
|
|
113
|
+
inventoryStatus = "Allocated";
|
|
114
|
+
}
|
|
115
|
+
const totalAmount = {
|
|
116
|
+
currency: body.currency_code.toUpperCase(),
|
|
117
|
+
value: body.total ? body.total : 0
|
|
118
|
+
};
|
|
119
|
+
const order = {
|
|
120
|
+
identifier,
|
|
121
|
+
userId,
|
|
122
|
+
customerName,
|
|
123
|
+
shippingAddress,
|
|
124
|
+
orderDate,
|
|
125
|
+
orderStatus,
|
|
126
|
+
inventoryStatus,
|
|
127
|
+
totalAmount
|
|
128
|
+
};
|
|
129
|
+
return order;
|
|
130
|
+
}
|
|
131
|
+
parsePaginatedResult(body, query) {
|
|
132
|
+
const identifier = {
|
|
133
|
+
...query.search
|
|
134
|
+
};
|
|
135
|
+
const orders = body.orders.map((o) => {
|
|
136
|
+
return this.parseSingle(o);
|
|
137
|
+
});
|
|
138
|
+
const result = {
|
|
139
|
+
identifier,
|
|
140
|
+
pageNumber: (Math.ceil(body.offset / body.limit) || 0) + 1,
|
|
141
|
+
pageSize: body.limit,
|
|
142
|
+
totalCount: body.count,
|
|
143
|
+
totalPages: Math.ceil(body.count / body.limit || 0) + 1,
|
|
144
|
+
items: orders
|
|
145
|
+
};
|
|
146
|
+
return result;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
__decorateClass([
|
|
150
|
+
Reactionary({
|
|
151
|
+
inputSchema: OrderSearchQueryByTermSchema,
|
|
152
|
+
outputSchema: OrderSearchResultSchema
|
|
153
|
+
})
|
|
154
|
+
], MedusaOrderSearchProvider.prototype, "queryByTerm", 1);
|
|
155
|
+
export {
|
|
156
|
+
MedusaOrderSearchProvider
|
|
157
|
+
};
|
|
@@ -0,0 +1,175 @@
|
|
|
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
|
+
OrderProvider,
|
|
14
|
+
OrderQueryByIdSchema,
|
|
15
|
+
OrderSchema,
|
|
16
|
+
Reactionary,
|
|
17
|
+
success,
|
|
18
|
+
error,
|
|
19
|
+
ProductVariantIdentifierSchema
|
|
20
|
+
} from "@reactionary/core";
|
|
21
|
+
import createDebug from "debug";
|
|
22
|
+
import { handleProviderError } from "../utils/medusa-helpers.js";
|
|
23
|
+
import { parseMedusaItemPrice, parseMedusaCostBreakdown } from "../utils/medusa-helpers.js";
|
|
24
|
+
const debug = createDebug("reactionary:medusa:order");
|
|
25
|
+
class MedusaOrderProvider extends OrderProvider {
|
|
26
|
+
constructor(config, cache, context, client) {
|
|
27
|
+
super(cache, context);
|
|
28
|
+
this.config = config;
|
|
29
|
+
this.client = client;
|
|
30
|
+
}
|
|
31
|
+
async getById(payload) {
|
|
32
|
+
debug("getById", payload);
|
|
33
|
+
const medusa = await this.client.getClient();
|
|
34
|
+
try {
|
|
35
|
+
const response = await medusa.store.order.retrieve(payload.order.key);
|
|
36
|
+
const order = this.parseSingle(response.order);
|
|
37
|
+
return success(order);
|
|
38
|
+
} catch (err) {
|
|
39
|
+
return handleProviderError("order", err);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Extension point to control the parsing of a single cart item price
|
|
44
|
+
* @param remoteItem
|
|
45
|
+
* @param currency
|
|
46
|
+
* @returns
|
|
47
|
+
*/
|
|
48
|
+
parseItemPrice(remoteItem, currency) {
|
|
49
|
+
return parseMedusaItemPrice(remoteItem, currency);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Extension point to control the parsing of the cost breakdown of a cart
|
|
53
|
+
* @param remote
|
|
54
|
+
* @returns
|
|
55
|
+
*/
|
|
56
|
+
parseCostBreakdown(remote) {
|
|
57
|
+
return parseMedusaCostBreakdown(remote);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Extension point to control the parsing of a single cart item
|
|
61
|
+
* @param remoteItem
|
|
62
|
+
* @param currency
|
|
63
|
+
* @returns
|
|
64
|
+
*/
|
|
65
|
+
parseOrderItem(remoteItem, currency) {
|
|
66
|
+
const item = {
|
|
67
|
+
identifier: {
|
|
68
|
+
key: remoteItem.id
|
|
69
|
+
},
|
|
70
|
+
variant: ProductVariantIdentifierSchema.parse({
|
|
71
|
+
sku: remoteItem.variant_sku || ""
|
|
72
|
+
}),
|
|
73
|
+
quantity: remoteItem.quantity || 1,
|
|
74
|
+
price: this.parseItemPrice(remoteItem, currency),
|
|
75
|
+
inventoryStatus: "Allocated"
|
|
76
|
+
};
|
|
77
|
+
return item;
|
|
78
|
+
}
|
|
79
|
+
parsePaymentInstruction(remotePayment, order) {
|
|
80
|
+
const paymentMethodIdentifier = {
|
|
81
|
+
method: remotePayment.payment_providers?.[0]?.id || "unknown",
|
|
82
|
+
name: remotePayment.payment_providers?.[0]?.id || "unknown",
|
|
83
|
+
paymentProcessor: remotePayment.payment_providers?.[0]?.id || "unknown"
|
|
84
|
+
};
|
|
85
|
+
let status = "pending";
|
|
86
|
+
switch (remotePayment.status) {
|
|
87
|
+
case "not_paid":
|
|
88
|
+
status = "pending";
|
|
89
|
+
break;
|
|
90
|
+
case "awaiting":
|
|
91
|
+
status = "pending";
|
|
92
|
+
break;
|
|
93
|
+
case "authorized":
|
|
94
|
+
status = "authorized";
|
|
95
|
+
break;
|
|
96
|
+
case "partially_authorized":
|
|
97
|
+
status = "pending";
|
|
98
|
+
break;
|
|
99
|
+
case "canceled":
|
|
100
|
+
status = "canceled";
|
|
101
|
+
break;
|
|
102
|
+
case "failed":
|
|
103
|
+
status = "canceled";
|
|
104
|
+
break;
|
|
105
|
+
case "completed":
|
|
106
|
+
status = "capture";
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
const paymentData = remotePayment.payments?.[0].data || {};
|
|
110
|
+
const pi = {
|
|
111
|
+
identifier: {
|
|
112
|
+
key: remotePayment.id
|
|
113
|
+
},
|
|
114
|
+
amount: {
|
|
115
|
+
value: remotePayment.amount,
|
|
116
|
+
currency: remotePayment.currency_code?.toUpperCase()
|
|
117
|
+
},
|
|
118
|
+
paymentMethod: paymentMethodIdentifier,
|
|
119
|
+
protocolData: paymentData ? Object.entries(paymentData).map(([key, value]) => ({
|
|
120
|
+
key,
|
|
121
|
+
value: String(value)
|
|
122
|
+
})) : [],
|
|
123
|
+
status
|
|
124
|
+
};
|
|
125
|
+
return pi;
|
|
126
|
+
}
|
|
127
|
+
parseSingle(body) {
|
|
128
|
+
const identifier = { key: body.id };
|
|
129
|
+
const userId = {
|
|
130
|
+
userId: body.customer_id || ""
|
|
131
|
+
};
|
|
132
|
+
const items = (body.items || []).map((item) => {
|
|
133
|
+
return this.parseOrderItem(item, body.currency_code.toUpperCase());
|
|
134
|
+
});
|
|
135
|
+
const price = this.parseCostBreakdown(body);
|
|
136
|
+
let orderStatus = "AwaitingPayment";
|
|
137
|
+
if (body.status === "draft") {
|
|
138
|
+
orderStatus = "AwaitingPayment";
|
|
139
|
+
}
|
|
140
|
+
if (body.status === "pending") {
|
|
141
|
+
orderStatus = "ReleasedToFulfillment";
|
|
142
|
+
}
|
|
143
|
+
if (body.status === "completed") {
|
|
144
|
+
orderStatus = "Shipped";
|
|
145
|
+
}
|
|
146
|
+
if (body.status === "canceled") {
|
|
147
|
+
orderStatus = "Cancelled";
|
|
148
|
+
}
|
|
149
|
+
let inventoryStatus = "NotAllocated";
|
|
150
|
+
if (body.fulfillment_status === "fulfilled") {
|
|
151
|
+
inventoryStatus = "Allocated";
|
|
152
|
+
}
|
|
153
|
+
const paymentInstructions = body.payment_collections?.map((pc) => {
|
|
154
|
+
return this.parsePaymentInstruction(pc, body);
|
|
155
|
+
}) || [];
|
|
156
|
+
return {
|
|
157
|
+
identifier,
|
|
158
|
+
userId,
|
|
159
|
+
items,
|
|
160
|
+
price,
|
|
161
|
+
orderStatus,
|
|
162
|
+
inventoryStatus,
|
|
163
|
+
paymentInstructions
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
__decorateClass([
|
|
168
|
+
Reactionary({
|
|
169
|
+
inputSchema: OrderQueryByIdSchema,
|
|
170
|
+
outputSchema: OrderSchema
|
|
171
|
+
})
|
|
172
|
+
], MedusaOrderProvider.prototype, "getById", 1);
|
|
173
|
+
export {
|
|
174
|
+
MedusaOrderProvider
|
|
175
|
+
};
|
|
@@ -0,0 +1,323 @@
|
|
|
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
|
+
ProfileProvider,
|
|
14
|
+
Reactionary,
|
|
15
|
+
ProfileSchema,
|
|
16
|
+
ProfileMutationUpdateSchema,
|
|
17
|
+
ProfileMutationAddShippingAddressSchema,
|
|
18
|
+
ProfileMutationUpdateShippingAddressSchema,
|
|
19
|
+
ProfileMutationRemoveShippingAddressSchema,
|
|
20
|
+
ProfileMutationMakeShippingAddressDefaultSchema,
|
|
21
|
+
ProfileMutationSetBillingAddressSchema,
|
|
22
|
+
success,
|
|
23
|
+
ProfileQueryByIdSchema,
|
|
24
|
+
error
|
|
25
|
+
} from "@reactionary/core";
|
|
26
|
+
import createDebug from "debug";
|
|
27
|
+
const debug = createDebug("reactionary:medusa:profile");
|
|
28
|
+
class MedusaProfileProvider extends ProfileProvider {
|
|
29
|
+
constructor(config, cache, context, client) {
|
|
30
|
+
super(cache, context);
|
|
31
|
+
this.includedFields = ["+metadata.*"];
|
|
32
|
+
this.config = config;
|
|
33
|
+
this.client = client;
|
|
34
|
+
}
|
|
35
|
+
async getById(payload) {
|
|
36
|
+
debug("getById", payload);
|
|
37
|
+
const client = await this.client.getClient();
|
|
38
|
+
const customerResponse = await client.store.customer.retrieve({ fields: this.includedFields.join(",") });
|
|
39
|
+
if (!customerResponse.customer) {
|
|
40
|
+
return error({
|
|
41
|
+
identifier: payload.identifier,
|
|
42
|
+
type: "NotFound"
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
const model = this.parseSingle(customerResponse.customer);
|
|
46
|
+
return success(model);
|
|
47
|
+
}
|
|
48
|
+
async update(payload) {
|
|
49
|
+
debug("update", payload);
|
|
50
|
+
const client = await this.client.getClient();
|
|
51
|
+
const customerResponse = await client.store.customer.retrieve({ fields: this.includedFields.join(",") });
|
|
52
|
+
if (!customerResponse.customer) {
|
|
53
|
+
return error({
|
|
54
|
+
type: "NotFound",
|
|
55
|
+
identifier: payload.identifier
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
const customer = customerResponse.customer;
|
|
59
|
+
const updatedResponse = await client.store.customer.update({
|
|
60
|
+
phone: payload.phone ?? customer.phone
|
|
61
|
+
}, { fields: this.includedFields.join(",") });
|
|
62
|
+
const model = this.parseSingle(updatedResponse.customer);
|
|
63
|
+
return success(model);
|
|
64
|
+
}
|
|
65
|
+
async addShippingAddress(payload) {
|
|
66
|
+
debug("addShippingAddress", payload);
|
|
67
|
+
const client = await this.client.getClient();
|
|
68
|
+
const medusaAddress = this.createMedusaAddress(payload.address);
|
|
69
|
+
const customer = await client.store.customer.retrieve({ fields: this.includedFields.join(",") });
|
|
70
|
+
if (!customer.customer) {
|
|
71
|
+
return error({
|
|
72
|
+
type: "NotFound",
|
|
73
|
+
identifier: payload.identifier
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
const existingAddress = customer.customer.addresses.find((addr) => addr.address_name === payload.address.identifier.nickName);
|
|
77
|
+
if (existingAddress) {
|
|
78
|
+
return error({
|
|
79
|
+
type: "InvalidInput",
|
|
80
|
+
error: {
|
|
81
|
+
message: "Address with the same nickname already exists"
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
const response = await client.store.customer.createAddress(medusaAddress, { fields: this.includedFields.join(",") });
|
|
86
|
+
if (!response.customer) {
|
|
87
|
+
return error({
|
|
88
|
+
type: "InvalidInput",
|
|
89
|
+
error: {
|
|
90
|
+
message: "Failed to add shipping address"
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
const model = this.parseSingle(response.customer);
|
|
95
|
+
return success(model);
|
|
96
|
+
}
|
|
97
|
+
async updateShippingAddress(payload) {
|
|
98
|
+
debug("updateShippingAddress", payload);
|
|
99
|
+
const client = await this.client.getClient();
|
|
100
|
+
const customer = await client.store.customer.retrieve({ fields: this.includedFields.join(",") });
|
|
101
|
+
if (!customer.customer) {
|
|
102
|
+
return error({
|
|
103
|
+
type: "NotFound",
|
|
104
|
+
identifier: payload.identifier
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
const medusaAddress = this.createMedusaAddress(payload.address);
|
|
108
|
+
const existingAddress = customer.customer.addresses.find((addr) => addr.address_name === payload.address.identifier.nickName);
|
|
109
|
+
if (!existingAddress) {
|
|
110
|
+
return error({
|
|
111
|
+
type: "NotFound",
|
|
112
|
+
identifier: payload.address.identifier
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
const response = await client.store.customer.updateAddress(existingAddress.id, medusaAddress, { fields: this.includedFields.join(",") });
|
|
116
|
+
if (!response.customer) {
|
|
117
|
+
return error({
|
|
118
|
+
type: "InvalidInput",
|
|
119
|
+
error: {
|
|
120
|
+
message: "Failed to add shipping address"
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
const model = this.parseSingle(response.customer);
|
|
125
|
+
return success(model);
|
|
126
|
+
}
|
|
127
|
+
async removeShippingAddress(payload) {
|
|
128
|
+
debug("removeShippingAddress", payload);
|
|
129
|
+
const client = await this.client.getClient();
|
|
130
|
+
const customer = await client.store.customer.retrieve({ fields: this.includedFields.join(",") });
|
|
131
|
+
if (!customer.customer) {
|
|
132
|
+
return error({
|
|
133
|
+
type: "NotFound",
|
|
134
|
+
identifier: payload.identifier
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
const existingAddress = customer.customer.addresses.find((addr) => addr.address_name === payload.addressIdentifier.nickName);
|
|
138
|
+
if (!existingAddress) {
|
|
139
|
+
return error({
|
|
140
|
+
type: "NotFound",
|
|
141
|
+
identifier: payload.addressIdentifier
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
const response = await client.store.customer.deleteAddress(existingAddress.id, { fields: this.includedFields.join(",") });
|
|
145
|
+
if (!response.deleted) {
|
|
146
|
+
return error({
|
|
147
|
+
type: "InvalidInput",
|
|
148
|
+
error: {
|
|
149
|
+
message: "Failed to delete shipping address"
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
const customerAfterDelete = await client.store.customer.retrieve({ fields: this.includedFields.join(",") });
|
|
154
|
+
const model = this.parseSingle(customerAfterDelete.customer);
|
|
155
|
+
return success(model);
|
|
156
|
+
}
|
|
157
|
+
async makeShippingAddressDefault(payload) {
|
|
158
|
+
debug("makeShippingAddressDefault", payload);
|
|
159
|
+
const client = await this.client.getClient();
|
|
160
|
+
const customer = await client.store.customer.retrieve({ fields: this.includedFields.join(",") });
|
|
161
|
+
if (!customer.customer) {
|
|
162
|
+
return error({
|
|
163
|
+
type: "NotFound",
|
|
164
|
+
identifier: payload.identifier
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
const existingAddress = customer.customer.addresses.find((addr) => addr.address_name === payload.addressIdentifier.nickName);
|
|
168
|
+
if (!existingAddress) {
|
|
169
|
+
return error({
|
|
170
|
+
type: "NotFound",
|
|
171
|
+
identifier: payload.addressIdentifier
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
const response = await client.store.customer.updateAddress(
|
|
175
|
+
existingAddress.id,
|
|
176
|
+
{
|
|
177
|
+
is_default_shipping: true
|
|
178
|
+
},
|
|
179
|
+
{ fields: this.includedFields.join(",") }
|
|
180
|
+
);
|
|
181
|
+
const model = this.parseSingle(response.customer);
|
|
182
|
+
return success(model);
|
|
183
|
+
}
|
|
184
|
+
async setBillingAddress(payload) {
|
|
185
|
+
debug("setBillingAddress", payload);
|
|
186
|
+
const client = await this.client.getClient();
|
|
187
|
+
const customerResponse = await client.store.customer.retrieve({ fields: this.includedFields.join(",") });
|
|
188
|
+
if (!customerResponse.customer) {
|
|
189
|
+
return error({
|
|
190
|
+
type: "NotFound",
|
|
191
|
+
identifier: payload.identifier
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
let customer = customerResponse.customer;
|
|
195
|
+
const existingAddressWithNickname = customer.addresses.find((addr) => addr.address_name === payload.address.identifier.nickName);
|
|
196
|
+
if (existingAddressWithNickname && !existingAddressWithNickname.is_default_billing) {
|
|
197
|
+
return error({
|
|
198
|
+
type: "InvalidInput",
|
|
199
|
+
error: {
|
|
200
|
+
message: "Another address with the same nickname already exists"
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
const newAddr = this.createMedusaAddress(payload.address);
|
|
205
|
+
newAddr.is_default_billing = true;
|
|
206
|
+
const existingBillingAddress = customer.addresses.find((addr) => addr.is_default_billing);
|
|
207
|
+
if (existingBillingAddress) {
|
|
208
|
+
const updateAddressResponse = await client.store.customer.updateAddress(existingBillingAddress.id, newAddr, { fields: this.includedFields.join(",") });
|
|
209
|
+
customer = updateAddressResponse.customer;
|
|
210
|
+
} else {
|
|
211
|
+
const createAddressResponse = await client.store.customer.createAddress(newAddr, { fields: this.includedFields.join(",") });
|
|
212
|
+
customer = createAddressResponse.customer;
|
|
213
|
+
}
|
|
214
|
+
const model = this.parseSingle(customer);
|
|
215
|
+
return success(model);
|
|
216
|
+
}
|
|
217
|
+
createMedusaAddress(address) {
|
|
218
|
+
return {
|
|
219
|
+
address_name: address.identifier.nickName,
|
|
220
|
+
first_name: address.firstName,
|
|
221
|
+
last_name: address.lastName,
|
|
222
|
+
address_1: address.streetAddress,
|
|
223
|
+
address_2: address.streetNumber,
|
|
224
|
+
city: address.city,
|
|
225
|
+
province: address.region,
|
|
226
|
+
postal_code: address.postalCode,
|
|
227
|
+
country_code: address.countryCode
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
parseAddress(address) {
|
|
231
|
+
return {
|
|
232
|
+
identifier: {
|
|
233
|
+
nickName: address.address_name || ""
|
|
234
|
+
},
|
|
235
|
+
firstName: address.first_name || "",
|
|
236
|
+
lastName: address.last_name || "",
|
|
237
|
+
streetAddress: address.address_1 || "",
|
|
238
|
+
streetNumber: address.address_2 || "",
|
|
239
|
+
city: address.city || "",
|
|
240
|
+
region: address.province || "",
|
|
241
|
+
postalCode: address.postal_code || "",
|
|
242
|
+
countryCode: address.country_code || ""
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
parseSingle(customer) {
|
|
246
|
+
const email = customer.email;
|
|
247
|
+
const emailVerified = customer.metadata?.["email_verified"] === "true";
|
|
248
|
+
const phone = customer.phone || "";
|
|
249
|
+
const phoneVerified = customer.metadata?.["phone_verified"] === "true";
|
|
250
|
+
const addresses = customer.addresses || [];
|
|
251
|
+
let billingAddress = void 0;
|
|
252
|
+
let shippingAddress = void 0;
|
|
253
|
+
const existingBillingAddress = customer.addresses.find((addr) => addr.is_default_billing);
|
|
254
|
+
if (existingBillingAddress) {
|
|
255
|
+
billingAddress = this.parseAddress(existingBillingAddress);
|
|
256
|
+
}
|
|
257
|
+
const existingShippingAddress = customer.addresses.find((addr) => addr.is_default_shipping);
|
|
258
|
+
if (existingShippingAddress) {
|
|
259
|
+
shippingAddress = this.parseAddress(existingShippingAddress);
|
|
260
|
+
}
|
|
261
|
+
const alternateShippingAddresses = [];
|
|
262
|
+
alternateShippingAddresses.push(...addresses.filter((x) => !(x.is_default_billing || x.is_default_shipping)).map((addr) => this.parseAddress(addr)));
|
|
263
|
+
return {
|
|
264
|
+
identifier: {
|
|
265
|
+
userId: customer.id
|
|
266
|
+
},
|
|
267
|
+
email,
|
|
268
|
+
emailVerified,
|
|
269
|
+
phone,
|
|
270
|
+
phoneVerified,
|
|
271
|
+
billingAddress,
|
|
272
|
+
shippingAddress,
|
|
273
|
+
alternateShippingAddresses,
|
|
274
|
+
createdAt: new Date(customer.created_at || "").toISOString(),
|
|
275
|
+
updatedAt: new Date(customer.updated_at || "").toISOString()
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
__decorateClass([
|
|
280
|
+
Reactionary({
|
|
281
|
+
inputSchema: ProfileQueryByIdSchema,
|
|
282
|
+
outputSchema: ProfileSchema
|
|
283
|
+
})
|
|
284
|
+
], MedusaProfileProvider.prototype, "getById", 1);
|
|
285
|
+
__decorateClass([
|
|
286
|
+
Reactionary({
|
|
287
|
+
inputSchema: ProfileMutationUpdateSchema,
|
|
288
|
+
outputSchema: ProfileSchema
|
|
289
|
+
})
|
|
290
|
+
], MedusaProfileProvider.prototype, "update", 1);
|
|
291
|
+
__decorateClass([
|
|
292
|
+
Reactionary({
|
|
293
|
+
inputSchema: ProfileMutationAddShippingAddressSchema,
|
|
294
|
+
outputSchema: ProfileSchema
|
|
295
|
+
})
|
|
296
|
+
], MedusaProfileProvider.prototype, "addShippingAddress", 1);
|
|
297
|
+
__decorateClass([
|
|
298
|
+
Reactionary({
|
|
299
|
+
inputSchema: ProfileMutationUpdateShippingAddressSchema,
|
|
300
|
+
outputSchema: ProfileSchema
|
|
301
|
+
})
|
|
302
|
+
], MedusaProfileProvider.prototype, "updateShippingAddress", 1);
|
|
303
|
+
__decorateClass([
|
|
304
|
+
Reactionary({
|
|
305
|
+
inputSchema: ProfileMutationRemoveShippingAddressSchema,
|
|
306
|
+
outputSchema: ProfileSchema
|
|
307
|
+
})
|
|
308
|
+
], MedusaProfileProvider.prototype, "removeShippingAddress", 1);
|
|
309
|
+
__decorateClass([
|
|
310
|
+
Reactionary({
|
|
311
|
+
inputSchema: ProfileMutationMakeShippingAddressDefaultSchema,
|
|
312
|
+
outputSchema: ProfileSchema
|
|
313
|
+
})
|
|
314
|
+
], MedusaProfileProvider.prototype, "makeShippingAddressDefault", 1);
|
|
315
|
+
__decorateClass([
|
|
316
|
+
Reactionary({
|
|
317
|
+
inputSchema: ProfileMutationSetBillingAddressSchema,
|
|
318
|
+
outputSchema: ProfileSchema
|
|
319
|
+
})
|
|
320
|
+
], MedusaProfileProvider.prototype, "setBillingAddress", 1);
|
|
321
|
+
export {
|
|
322
|
+
MedusaProfileProvider
|
|
323
|
+
};
|
|
@@ -6,8 +6,11 @@ const MedusaCapabilitiesSchema = CapabilitiesSchema.pick({
|
|
|
6
6
|
category: true,
|
|
7
7
|
product: true,
|
|
8
8
|
price: true,
|
|
9
|
+
order: true,
|
|
10
|
+
orderSearch: true,
|
|
9
11
|
inventory: true,
|
|
10
|
-
identity: true
|
|
12
|
+
identity: true,
|
|
13
|
+
profile: true
|
|
11
14
|
}).partial();
|
|
12
15
|
export {
|
|
13
16
|
MedusaCapabilitiesSchema
|
package/src/index.d.ts
CHANGED
|
@@ -6,5 +6,8 @@ export * from './core/client.js';
|
|
|
6
6
|
export * from './providers/cart.provider.js';
|
|
7
7
|
export * from './providers/identity.provider.js';
|
|
8
8
|
export * from './providers/inventory.provider.js';
|
|
9
|
+
export * from './providers/order.provider.js';
|
|
10
|
+
export * from './providers/order-search.provider.js';
|
|
9
11
|
export * from './providers/price.provider.js';
|
|
10
12
|
export * from './providers/product-search.provider.js';
|
|
13
|
+
export * from './providers/profile.provider.js';
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { RequestContext, Cache, OrderSearchQueryByTerm, OrderSearchResult, Result, OrderStatus, Address } from '@reactionary/core';
|
|
2
|
+
import { OrderSearchProvider } from '@reactionary/core';
|
|
3
|
+
import type { MedusaConfiguration } from '../schema/configuration.schema.js';
|
|
4
|
+
import type { MedusaClient } from '../core/client.js';
|
|
5
|
+
import type { StoreOrder, StoreOrderAddress, StoreOrderListResponse } from '@medusajs/types';
|
|
6
|
+
export declare class MedusaOrderSearchProvider extends OrderSearchProvider {
|
|
7
|
+
protected config: MedusaConfiguration;
|
|
8
|
+
protected client: MedusaClient;
|
|
9
|
+
constructor(config: MedusaConfiguration, cache: Cache, context: RequestContext, client: MedusaClient);
|
|
10
|
+
queryByTerm(payload: OrderSearchQueryByTerm): Promise<Result<OrderSearchResult>>;
|
|
11
|
+
protected composeAddressFromStoreAddress(storeAddress: StoreOrderAddress): Address;
|
|
12
|
+
protected parseSingle(body: StoreOrder): {
|
|
13
|
+
identifier: {
|
|
14
|
+
key: string;
|
|
15
|
+
};
|
|
16
|
+
userId: {
|
|
17
|
+
userId: string;
|
|
18
|
+
};
|
|
19
|
+
customerName: string;
|
|
20
|
+
shippingAddress: {
|
|
21
|
+
identifier: {
|
|
22
|
+
nickName: string;
|
|
23
|
+
};
|
|
24
|
+
firstName: string;
|
|
25
|
+
lastName: string;
|
|
26
|
+
streetAddress: string;
|
|
27
|
+
streetNumber: string;
|
|
28
|
+
city: string;
|
|
29
|
+
region: string;
|
|
30
|
+
postalCode: string;
|
|
31
|
+
countryCode: string;
|
|
32
|
+
};
|
|
33
|
+
orderDate: string;
|
|
34
|
+
orderStatus: OrderStatus;
|
|
35
|
+
inventoryStatus: "NotAllocated" | "Allocated";
|
|
36
|
+
totalAmount: {
|
|
37
|
+
value: number;
|
|
38
|
+
currency: "AED" | "AFN" | "ALL" | "AMD" | "ANG" | "AOA" | "ARS" | "AUD" | "AWG" | "AZN" | "BAM" | "BBD" | "BDT" | "BGN" | "BHD" | "BIF" | "BMD" | "BND" | "BOB" | "BOV" | "BRL" | "BSD" | "BTN" | "BWP" | "BYN" | "BZD" | "CAD" | "CDF" | "CHE" | "CHF" | "CHW" | "CLF" | "CLP" | "CNY" | "COP" | "COU" | "CRC" | "CUC" | "CUP" | "CVE" | "CZK" | "DJF" | "DKK" | "DOP" | "DZD" | "EGP" | "ERN" | "ETB" | "EUR" | "FJD" | "FKP" | "GBP" | "GEL" | "GHS" | "GIP" | "GMD" | "GNF" | "GTQ" | "GYD" | "HKD" | "HNL" | "HRK" | "HTG" | "HUF" | "IDR" | "ILS" | "INR" | "IQD" | "IRR" | "ISK" | "JMD" | "JOD" | "JPY" | "KES" | "KGS" | "KHR" | "KMF" | "KPW" | "KRW" | "KWD" | "KYD" | "KZT" | "LAK" | "LBP" | "LKR" | "LRD" | "LSL" | "LYD" | "MAD" | "MDL" | "MGA" | "MKD" | "MMK" | "MNT" | "MOP" | "MRU" | "MUR" | "MVR" | "MWK" | "MXN" | "MXV" | "MYR" | "MZN" | "NAD" | "NGN" | "NIO" | "NOK" | "NPR" | "NZD" | "OMR" | "PAB" | "PEN" | "PGK" | "PHP" | "PKR" | "PLN" | "PYG" | "QAR" | "RON" | "RSD" | "RUB" | "RWF" | "SAR" | "SBD" | "SCR" | "SDG" | "SEK" | "SGD" | "SHP" | "SLE" | "SLL" | "SOS" | "SRD" | "SSP" | "STN" | "SYP" | "SZL" | "THB" | "TJS" | "TMT" | "TND" | "TOP" | "TRY" | "TTD" | "TVD" | "TWD" | "TZS" | "UAH" | "UGX" | "USD" | "USN" | "UYI" | "UYU" | "UYW" | "UZS" | "VED" | "VES" | "VND" | "VUV" | "WST" | "XAF" | "XAG" | "XAU" | "XBA" | "XBB" | "XBC" | "XBD" | "XCD" | "XDR" | "XOF" | "XPD" | "XPF" | "XPT" | "XSU" | "XTS" | "XUA" | "XXX" | "YER" | "ZAR" | "ZMW" | "ZWL";
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
protected parsePaginatedResult(body: StoreOrderListResponse, query: OrderSearchQueryByTerm): {
|
|
42
|
+
identifier: {
|
|
43
|
+
term: string;
|
|
44
|
+
filters: string[];
|
|
45
|
+
paginationOptions: {
|
|
46
|
+
pageNumber: number;
|
|
47
|
+
pageSize: number;
|
|
48
|
+
};
|
|
49
|
+
partNumber?: string[] | undefined;
|
|
50
|
+
orderStatus?: ("AwaitingPayment" | "ReleasedToFulfillment" | "Shipped" | "Cancelled")[] | undefined;
|
|
51
|
+
userId?: {
|
|
52
|
+
userId: string;
|
|
53
|
+
} | undefined;
|
|
54
|
+
startDate?: string | undefined;
|
|
55
|
+
endDate?: string | undefined;
|
|
56
|
+
};
|
|
57
|
+
pageNumber: number;
|
|
58
|
+
pageSize: number;
|
|
59
|
+
totalCount: number;
|
|
60
|
+
totalPages: number;
|
|
61
|
+
items: {
|
|
62
|
+
identifier: {
|
|
63
|
+
key: string;
|
|
64
|
+
};
|
|
65
|
+
userId: {
|
|
66
|
+
userId: string;
|
|
67
|
+
};
|
|
68
|
+
customerName: string;
|
|
69
|
+
orderDate: string;
|
|
70
|
+
orderStatus: "AwaitingPayment" | "ReleasedToFulfillment" | "Shipped" | "Cancelled";
|
|
71
|
+
inventoryStatus: "NotAllocated" | "Allocated" | "Backordered" | "Preordered";
|
|
72
|
+
totalAmount: {
|
|
73
|
+
value: number;
|
|
74
|
+
currency: "AED" | "AFN" | "ALL" | "AMD" | "ANG" | "AOA" | "ARS" | "AUD" | "AWG" | "AZN" | "BAM" | "BBD" | "BDT" | "BGN" | "BHD" | "BIF" | "BMD" | "BND" | "BOB" | "BOV" | "BRL" | "BSD" | "BTN" | "BWP" | "BYN" | "BZD" | "CAD" | "CDF" | "CHE" | "CHF" | "CHW" | "CLF" | "CLP" | "CNY" | "COP" | "COU" | "CRC" | "CUC" | "CUP" | "CVE" | "CZK" | "DJF" | "DKK" | "DOP" | "DZD" | "EGP" | "ERN" | "ETB" | "EUR" | "FJD" | "FKP" | "GBP" | "GEL" | "GHS" | "GIP" | "GMD" | "GNF" | "GTQ" | "GYD" | "HKD" | "HNL" | "HRK" | "HTG" | "HUF" | "IDR" | "ILS" | "INR" | "IQD" | "IRR" | "ISK" | "JMD" | "JOD" | "JPY" | "KES" | "KGS" | "KHR" | "KMF" | "KPW" | "KRW" | "KWD" | "KYD" | "KZT" | "LAK" | "LBP" | "LKR" | "LRD" | "LSL" | "LYD" | "MAD" | "MDL" | "MGA" | "MKD" | "MMK" | "MNT" | "MOP" | "MRU" | "MUR" | "MVR" | "MWK" | "MXN" | "MXV" | "MYR" | "MZN" | "NAD" | "NGN" | "NIO" | "NOK" | "NPR" | "NZD" | "OMR" | "PAB" | "PEN" | "PGK" | "PHP" | "PKR" | "PLN" | "PYG" | "QAR" | "RON" | "RSD" | "RUB" | "RWF" | "SAR" | "SBD" | "SCR" | "SDG" | "SEK" | "SGD" | "SHP" | "SLE" | "SLL" | "SOS" | "SRD" | "SSP" | "STN" | "SYP" | "SZL" | "THB" | "TJS" | "TMT" | "TND" | "TOP" | "TRY" | "TTD" | "TVD" | "TWD" | "TZS" | "UAH" | "UGX" | "USD" | "USN" | "UYI" | "UYU" | "UYW" | "UZS" | "VED" | "VES" | "VND" | "VUV" | "WST" | "XAF" | "XAG" | "XAU" | "XBA" | "XBB" | "XBC" | "XBD" | "XCD" | "XDR" | "XOF" | "XPD" | "XPF" | "XPT" | "XSU" | "XTS" | "XUA" | "XXX" | "YER" | "ZAR" | "ZMW" | "ZWL";
|
|
75
|
+
};
|
|
76
|
+
shippingAddress?: {
|
|
77
|
+
identifier: {
|
|
78
|
+
nickName: string;
|
|
79
|
+
};
|
|
80
|
+
firstName: string;
|
|
81
|
+
lastName: string;
|
|
82
|
+
streetAddress: string;
|
|
83
|
+
streetNumber: string;
|
|
84
|
+
city: string;
|
|
85
|
+
region: string;
|
|
86
|
+
postalCode: string;
|
|
87
|
+
countryCode: string;
|
|
88
|
+
} | undefined;
|
|
89
|
+
}[];
|
|
90
|
+
};
|
|
91
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { Cache, Order, OrderQueryById, RequestContext, Result, NotFoundError, CostBreakDown, Currency, OrderItem, ItemCostBreakdown } from '@reactionary/core';
|
|
2
|
+
import { OrderProvider } from '@reactionary/core';
|
|
3
|
+
import type { MedusaClient } from '../core/client.js';
|
|
4
|
+
import type { MedusaConfiguration } from '../schema/configuration.schema.js';
|
|
5
|
+
import type { StoreOrder, StoreOrderLineItem, StorePaymentCollection } from '@medusajs/types';
|
|
6
|
+
export declare class MedusaOrderProvider extends OrderProvider {
|
|
7
|
+
protected config: MedusaConfiguration;
|
|
8
|
+
protected client: MedusaClient;
|
|
9
|
+
constructor(config: MedusaConfiguration, cache: Cache, context: RequestContext, client: MedusaClient);
|
|
10
|
+
getById(payload: OrderQueryById): Promise<Result<Order, NotFoundError>>;
|
|
11
|
+
/**
|
|
12
|
+
* Extension point to control the parsing of a single cart item price
|
|
13
|
+
* @param remoteItem
|
|
14
|
+
* @param currency
|
|
15
|
+
* @returns
|
|
16
|
+
*/
|
|
17
|
+
protected parseItemPrice(remoteItem: StoreOrderLineItem, currency: Currency): ItemCostBreakdown;
|
|
18
|
+
/**
|
|
19
|
+
* Extension point to control the parsing of the cost breakdown of a cart
|
|
20
|
+
* @param remote
|
|
21
|
+
* @returns
|
|
22
|
+
*/
|
|
23
|
+
protected parseCostBreakdown(remote: StoreOrder): CostBreakDown;
|
|
24
|
+
/**
|
|
25
|
+
* Extension point to control the parsing of a single cart item
|
|
26
|
+
* @param remoteItem
|
|
27
|
+
* @param currency
|
|
28
|
+
* @returns
|
|
29
|
+
*/
|
|
30
|
+
protected parseOrderItem(remoteItem: StoreOrderLineItem, currency: Currency): OrderItem;
|
|
31
|
+
protected parsePaymentInstruction(remotePayment: StorePaymentCollection, order: StoreOrder): {
|
|
32
|
+
identifier: {
|
|
33
|
+
key: string;
|
|
34
|
+
};
|
|
35
|
+
amount: {
|
|
36
|
+
value: number;
|
|
37
|
+
currency: Currency;
|
|
38
|
+
};
|
|
39
|
+
paymentMethod: {
|
|
40
|
+
method: string;
|
|
41
|
+
name: string;
|
|
42
|
+
paymentProcessor: string;
|
|
43
|
+
};
|
|
44
|
+
protocolData: {
|
|
45
|
+
key: string;
|
|
46
|
+
value: string;
|
|
47
|
+
}[];
|
|
48
|
+
status: "pending" | "authorized" | "canceled" | "capture";
|
|
49
|
+
};
|
|
50
|
+
protected parseSingle(body: StoreOrder): Order;
|
|
51
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type Profile, type ProfileMutationAddShippingAddress, type ProfileMutationMakeShippingAddressDefault, type ProfileMutationRemoveShippingAddress, type ProfileMutationSetBillingAddress, type ProfileMutationUpdate, type ProfileMutationUpdateShippingAddress, type ProfileQuerySelf as ProfileQueryById, type RequestContext, type Cache, type Result, type NotFoundError, ProfileProvider, type Address } from '@reactionary/core';
|
|
2
|
+
import type { MedusaConfiguration } from '../schema/configuration.schema.js';
|
|
3
|
+
import type { MedusaClient } from '../core/client.js';
|
|
4
|
+
import type { StoreCreateCustomerAddress, StoreCustomer, StoreCustomerAddress } from '@medusajs/types';
|
|
5
|
+
/**
|
|
6
|
+
* Medusa Profile Provider
|
|
7
|
+
*
|
|
8
|
+
* Implements profile management using Medusa's customer APIs.
|
|
9
|
+
*
|
|
10
|
+
* TODO:
|
|
11
|
+
* - handle email and phone verification status properly using metadata or other means.
|
|
12
|
+
* - handle guest user scenarios (if applicable).
|
|
13
|
+
* - improve error handling and edge cases.
|
|
14
|
+
*/
|
|
15
|
+
export declare class MedusaProfileProvider extends ProfileProvider {
|
|
16
|
+
protected config: MedusaConfiguration;
|
|
17
|
+
protected client: MedusaClient;
|
|
18
|
+
protected includedFields: string[];
|
|
19
|
+
constructor(config: MedusaConfiguration, cache: Cache, context: RequestContext, client: MedusaClient);
|
|
20
|
+
getById(payload: ProfileQueryById): Promise<Result<Profile, NotFoundError>>;
|
|
21
|
+
update(payload: ProfileMutationUpdate): Promise<Result<Profile, NotFoundError>>;
|
|
22
|
+
addShippingAddress(payload: ProfileMutationAddShippingAddress): Promise<Result<Profile, NotFoundError>>;
|
|
23
|
+
updateShippingAddress(payload: ProfileMutationUpdateShippingAddress): Promise<Result<Profile, NotFoundError>>;
|
|
24
|
+
removeShippingAddress(payload: ProfileMutationRemoveShippingAddress): Promise<Result<Profile, NotFoundError>>;
|
|
25
|
+
makeShippingAddressDefault(payload: ProfileMutationMakeShippingAddressDefault): Promise<Result<Profile, NotFoundError>>;
|
|
26
|
+
setBillingAddress(payload: ProfileMutationSetBillingAddress): Promise<Result<Profile, NotFoundError>>;
|
|
27
|
+
protected createMedusaAddress(address: Address): StoreCreateCustomerAddress;
|
|
28
|
+
protected parseAddress(address: StoreCustomerAddress): Address;
|
|
29
|
+
protected parseSingle(customer: StoreCustomer): Profile;
|
|
30
|
+
}
|
|
@@ -4,9 +4,12 @@ export declare const MedusaCapabilitiesSchema: z.ZodObject<{
|
|
|
4
4
|
product: z.ZodOptional<z.ZodBoolean>;
|
|
5
5
|
cart: z.ZodOptional<z.ZodBoolean>;
|
|
6
6
|
checkout: z.ZodOptional<z.ZodBoolean>;
|
|
7
|
+
order: z.ZodOptional<z.ZodBoolean>;
|
|
7
8
|
identity: z.ZodOptional<z.ZodBoolean>;
|
|
8
9
|
inventory: z.ZodOptional<z.ZodBoolean>;
|
|
9
10
|
category: z.ZodOptional<z.ZodBoolean>;
|
|
11
|
+
profile: z.ZodOptional<z.ZodBoolean>;
|
|
10
12
|
productSearch: z.ZodOptional<z.ZodBoolean>;
|
|
13
|
+
orderSearch: z.ZodOptional<z.ZodBoolean>;
|
|
11
14
|
}, z.core.$loose>;
|
|
12
15
|
export type MedusaCapabilities = z.infer<typeof MedusaCapabilitiesSchema>;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { StoreCart } from '@medusajs/types';
|
|
1
|
+
import type { StoreCart, StoreOrder } from '@medusajs/types';
|
|
2
2
|
import type { CostBreakDown, Currency } from '@reactionary/core';
|
|
3
3
|
/**
|
|
4
4
|
* Parses cost breakdown from Medusa StoreCart
|
|
5
5
|
*/
|
|
6
|
-
export declare function parseMedusaCostBreakdown(remote: StoreCart): CostBreakDown;
|
|
6
|
+
export declare function parseMedusaCostBreakdown(remote: StoreCart | StoreOrder): CostBreakDown;
|
|
7
7
|
/**
|
|
8
8
|
* Parses item price structure from Medusa line item
|
|
9
9
|
*/
|