@reactionary/provider-medusa 0.1.13 → 0.2.2
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/client.js +2 -23
- package/core/initialize.js +4 -0
- package/index.js +1 -0
- package/package.json +2 -2
- package/providers/cart.provider.js +68 -58
- package/providers/category.provider.js +19 -53
- package/providers/checkout.provider.js +18 -40
- package/providers/identity.provider.js +9 -25
- package/providers/inventory.provider.js +7 -22
- package/providers/price.provider.js +8 -13
- package/providers/product-search.provider.js +31 -35
- package/providers/product.provider.js +13 -13
- package/providers/profile.provider.js +323 -0
- package/schema/capabilities.schema.js +2 -1
- package/src/core/client.d.ts +0 -35
- package/src/index.d.ts +1 -0
- package/src/providers/cart.provider.d.ts +10 -10
- package/src/providers/category.provider.d.ts +8 -50
- package/src/providers/checkout.provider.d.ts +10 -10
- package/src/providers/identity.provider.d.ts +5 -5
- package/src/providers/inventory.provider.d.ts +2 -2
- package/src/providers/price.provider.d.ts +3 -3
- package/src/providers/product-search.provider.d.ts +3 -17
- package/src/providers/product.provider.d.ts +4 -4
- package/src/providers/profile.provider.d.ts +30 -0
- package/src/schema/capabilities.schema.d.ts +3 -2
- package/test/cart.provider.spec.js +69 -49
- package/test/category.provider.spec.js +125 -63
- package/test/checkout.spec.js +80 -49
- package/test/identity.provider.spec.js +22 -7
- package/test/inventory.provider.spec.js +35 -24
- package/test/large-cart.provider.spec.js +57 -31
- package/test/price.provider.spec.js +57 -36
- package/test/product.provider.spec.js +78 -49
- package/test/search.provider.spec.js +47 -20
|
@@ -17,8 +17,7 @@ import {
|
|
|
17
17
|
IdentityMutationRegisterSchema,
|
|
18
18
|
IdentityMutationLoginSchema,
|
|
19
19
|
IdentityMutationLogoutSchema,
|
|
20
|
-
|
|
21
|
-
RegisteredIdentitySchema
|
|
20
|
+
success
|
|
22
21
|
} from "@reactionary/core";
|
|
23
22
|
import createDebug from "debug";
|
|
24
23
|
const debug = createDebug("reactionary:medusa:identity");
|
|
@@ -30,13 +29,6 @@ class MedusaIdentityProvider extends IdentityProvider {
|
|
|
30
29
|
}
|
|
31
30
|
createAnonymousIdentity() {
|
|
32
31
|
return {
|
|
33
|
-
meta: {
|
|
34
|
-
cache: {
|
|
35
|
-
hit: false,
|
|
36
|
-
key: ""
|
|
37
|
-
},
|
|
38
|
-
placeholder: false
|
|
39
|
-
},
|
|
40
32
|
type: "Anonymous"
|
|
41
33
|
};
|
|
42
34
|
}
|
|
@@ -46,29 +38,22 @@ class MedusaIdentityProvider extends IdentityProvider {
|
|
|
46
38
|
const token = await medusaClient.client.getToken();
|
|
47
39
|
if (!token) {
|
|
48
40
|
debug("No active session token found, returning anonymous identity");
|
|
49
|
-
return this.createAnonymousIdentity();
|
|
41
|
+
return success(this.createAnonymousIdentity());
|
|
50
42
|
}
|
|
51
43
|
const customerResponse = await medusaClient.store.customer.retrieve();
|
|
52
44
|
if (customerResponse.customer) {
|
|
53
45
|
debug("Customer authenticated:", customerResponse.customer.email);
|
|
54
|
-
return {
|
|
46
|
+
return success({
|
|
55
47
|
id: {
|
|
56
48
|
userId: customerResponse.customer.id
|
|
57
49
|
},
|
|
58
|
-
meta: {
|
|
59
|
-
cache: {
|
|
60
|
-
hit: false,
|
|
61
|
-
key: ""
|
|
62
|
-
},
|
|
63
|
-
placeholder: false
|
|
64
|
-
},
|
|
65
50
|
type: "Registered"
|
|
66
|
-
};
|
|
51
|
+
});
|
|
67
52
|
}
|
|
68
|
-
return this.createAnonymousIdentity();
|
|
53
|
+
return success(this.createAnonymousIdentity());
|
|
69
54
|
} catch (error) {
|
|
70
55
|
debug("getSelf failed, returning anonymous identity:", error);
|
|
71
|
-
return this.createAnonymousIdentity();
|
|
56
|
+
return success(this.createAnonymousIdentity());
|
|
72
57
|
}
|
|
73
58
|
}
|
|
74
59
|
async login(payload) {
|
|
@@ -78,12 +63,12 @@ class MedusaIdentityProvider extends IdentityProvider {
|
|
|
78
63
|
payload.password,
|
|
79
64
|
this.context
|
|
80
65
|
);
|
|
81
|
-
return identity;
|
|
66
|
+
return success(identity);
|
|
82
67
|
}
|
|
83
68
|
async logout(_payload) {
|
|
84
69
|
debug("Logging out user");
|
|
85
70
|
const identity = await this.client.logout(this.context);
|
|
86
|
-
return identity;
|
|
71
|
+
return success(identity);
|
|
87
72
|
}
|
|
88
73
|
async register(payload) {
|
|
89
74
|
debug("Registering new user:", payload.username);
|
|
@@ -98,8 +83,7 @@ class MedusaIdentityProvider extends IdentityProvider {
|
|
|
98
83
|
lastName,
|
|
99
84
|
this.context
|
|
100
85
|
);
|
|
101
|
-
return identity;
|
|
102
|
-
;
|
|
86
|
+
return success(identity);
|
|
103
87
|
}
|
|
104
88
|
}
|
|
105
89
|
__decorateClass([
|
|
@@ -13,7 +13,8 @@ import {
|
|
|
13
13
|
InventoryProvider,
|
|
14
14
|
InventorySchema,
|
|
15
15
|
InventoryQueryBySKUSchema,
|
|
16
|
-
Reactionary
|
|
16
|
+
Reactionary,
|
|
17
|
+
success
|
|
17
18
|
} from "@reactionary/core";
|
|
18
19
|
import { MedusaAdminClient } from "../core/client.js";
|
|
19
20
|
import createDebug from "debug";
|
|
@@ -41,7 +42,7 @@ class MedusaInventoryProvider extends InventoryProvider {
|
|
|
41
42
|
if (debug.enabled) {
|
|
42
43
|
debug(`No inventory items found for SKU: ${sku}`);
|
|
43
44
|
}
|
|
44
|
-
return this.createEmptyInventoryResult(sku, fulfillmentCenterKey);
|
|
45
|
+
return success(this.createEmptyInventoryResult(sku, fulfillmentCenterKey));
|
|
45
46
|
}
|
|
46
47
|
const inventoryItem = inventoryResponse.inventory_items[0];
|
|
47
48
|
const locationsResponse = await adminClient.admin.stockLocation.list({
|
|
@@ -66,19 +67,19 @@ class MedusaInventoryProvider extends InventoryProvider {
|
|
|
66
67
|
if (debug.enabled) {
|
|
67
68
|
debug(`No stock location found with name: ${fulfillmentCenterKey}`);
|
|
68
69
|
}
|
|
69
|
-
return this.createEmptyInventoryResult(sku, fulfillmentCenterKey);
|
|
70
|
+
return success(this.createEmptyInventoryResult(sku, fulfillmentCenterKey));
|
|
70
71
|
}
|
|
71
|
-
return this.parseSingle({
|
|
72
|
+
return success(this.parseSingle({
|
|
72
73
|
sku: payload.variant.sku,
|
|
73
74
|
fulfillmentCenterKey,
|
|
74
75
|
quantity,
|
|
75
76
|
inventoryItemId: inventoryItem.id
|
|
76
|
-
});
|
|
77
|
+
}));
|
|
77
78
|
} catch (error) {
|
|
78
79
|
if (debug.enabled) {
|
|
79
80
|
debug(`Error fetching inventory for SKU: ${sku}`, error);
|
|
80
81
|
}
|
|
81
|
-
return this.createEmptyInventoryResult(sku, fulfillmentCenterKey);
|
|
82
|
+
return success(this.createEmptyInventoryResult(sku, fulfillmentCenterKey));
|
|
82
83
|
}
|
|
83
84
|
}
|
|
84
85
|
parseSingle(_body) {
|
|
@@ -95,16 +96,8 @@ class MedusaInventoryProvider extends InventoryProvider {
|
|
|
95
96
|
if (quantity > 0) {
|
|
96
97
|
status = "inStock";
|
|
97
98
|
}
|
|
98
|
-
const meta = {
|
|
99
|
-
cache: {
|
|
100
|
-
hit: false,
|
|
101
|
-
key: this.generateCacheKeySingle(identifier)
|
|
102
|
-
},
|
|
103
|
-
placeholder: false
|
|
104
|
-
};
|
|
105
99
|
const result = {
|
|
106
100
|
identifier,
|
|
107
|
-
meta,
|
|
108
101
|
quantity,
|
|
109
102
|
status
|
|
110
103
|
};
|
|
@@ -124,16 +117,8 @@ class MedusaInventoryProvider extends InventoryProvider {
|
|
|
124
117
|
};
|
|
125
118
|
const quantity = 0;
|
|
126
119
|
const status = "outOfStock";
|
|
127
|
-
const meta = {
|
|
128
|
-
cache: {
|
|
129
|
-
hit: false,
|
|
130
|
-
key: this.generateCacheKeySingle(identifier)
|
|
131
|
-
},
|
|
132
|
-
placeholder: true
|
|
133
|
-
};
|
|
134
120
|
const result = {
|
|
135
121
|
identifier,
|
|
136
|
-
meta,
|
|
137
122
|
quantity,
|
|
138
123
|
status
|
|
139
124
|
};
|
|
@@ -14,7 +14,8 @@ import {
|
|
|
14
14
|
PriceSchema,
|
|
15
15
|
CustomerPriceQuerySchema,
|
|
16
16
|
ListPriceQuerySchema,
|
|
17
|
-
Reactionary
|
|
17
|
+
Reactionary,
|
|
18
|
+
success
|
|
18
19
|
} from "@reactionary/core";
|
|
19
20
|
import createDebug from "debug";
|
|
20
21
|
const debug = createDebug("reactionary:medusa:price");
|
|
@@ -24,11 +25,13 @@ class MedusaPriceProvider extends PriceProvider {
|
|
|
24
25
|
this.client = client;
|
|
25
26
|
this.config = config;
|
|
26
27
|
}
|
|
27
|
-
getListPrice(payload) {
|
|
28
|
-
|
|
28
|
+
async getListPrice(payload) {
|
|
29
|
+
const result = await this.getBySKU(payload);
|
|
30
|
+
return success(result);
|
|
29
31
|
}
|
|
30
|
-
getCustomerPrice(payload) {
|
|
31
|
-
|
|
32
|
+
async getCustomerPrice(payload) {
|
|
33
|
+
const result = await this.getBySKU(payload);
|
|
34
|
+
return success(result);
|
|
32
35
|
}
|
|
33
36
|
async getBySKU(payload) {
|
|
34
37
|
const sku = payload.variant.sku;
|
|
@@ -80,16 +83,8 @@ class MedusaPriceProvider extends PriceProvider {
|
|
|
80
83
|
currency: this.context.languageContext.currencyCode
|
|
81
84
|
};
|
|
82
85
|
}
|
|
83
|
-
const meta = {
|
|
84
|
-
cache: {
|
|
85
|
-
hit: false,
|
|
86
|
-
key: this.generateCacheKeySingle(identifier)
|
|
87
|
-
},
|
|
88
|
-
placeholder: calculatedPrice === void 0
|
|
89
|
-
};
|
|
90
86
|
const result = {
|
|
91
87
|
identifier,
|
|
92
|
-
meta,
|
|
93
88
|
tieredPrices: [],
|
|
94
89
|
unitPrice
|
|
95
90
|
};
|
|
@@ -17,11 +17,11 @@ import {
|
|
|
17
17
|
ProductVariantOptionSchema,
|
|
18
18
|
ProductOptionIdentifierSchema,
|
|
19
19
|
ProductSearchResultItemVariantSchema,
|
|
20
|
-
createPaginatedResponseSchema,
|
|
21
20
|
Reactionary,
|
|
22
21
|
ProductSearchResultSchema,
|
|
23
22
|
FacetValueIdentifierSchema,
|
|
24
|
-
FacetIdentifierSchema
|
|
23
|
+
FacetIdentifierSchema,
|
|
24
|
+
success
|
|
25
25
|
} from "@reactionary/core";
|
|
26
26
|
import createDebug from "debug";
|
|
27
27
|
const debug = createDebug("reactionary:medusa:search");
|
|
@@ -65,13 +65,21 @@ class MedusaSearchProvider extends ProductSearchProvider {
|
|
|
65
65
|
const client = await this.client.getClient();
|
|
66
66
|
let categoryIdToFind = null;
|
|
67
67
|
if (payload.search.categoryFilter?.key) {
|
|
68
|
-
debug(
|
|
69
|
-
|
|
68
|
+
debug(
|
|
69
|
+
`Resolving category filter for key: ${payload.search.categoryFilter.key}`
|
|
70
|
+
);
|
|
71
|
+
const category = await this.resolveCategoryIdByExternalId(
|
|
72
|
+
payload.search.categoryFilter.key
|
|
73
|
+
);
|
|
70
74
|
if (category) {
|
|
71
75
|
categoryIdToFind = category.id;
|
|
72
|
-
debug(
|
|
76
|
+
debug(
|
|
77
|
+
`Resolved category filter key ${payload.search.categoryFilter.key} to id: ${categoryIdToFind}`
|
|
78
|
+
);
|
|
73
79
|
} else {
|
|
74
|
-
debug(
|
|
80
|
+
debug(
|
|
81
|
+
`Could not resolve category filter for key: ${payload.search.categoryFilter.key}`
|
|
82
|
+
);
|
|
75
83
|
}
|
|
76
84
|
}
|
|
77
85
|
const finalSearch = (payload.search.term || "").trim().replace("*", "");
|
|
@@ -83,19 +91,19 @@ class MedusaSearchProvider extends ProductSearchProvider {
|
|
|
83
91
|
});
|
|
84
92
|
const result = this.parsePaginatedResult(response);
|
|
85
93
|
if (debug.enabled) {
|
|
86
|
-
debug(
|
|
94
|
+
debug(
|
|
95
|
+
`Search for term "${payload.search.term}" returned ${response.products.length} products (page ${payload.search.paginationOptions.pageNumber} of ${result.totalPages})`
|
|
96
|
+
);
|
|
87
97
|
}
|
|
88
98
|
result.identifier = {
|
|
89
99
|
...payload.search
|
|
90
100
|
};
|
|
91
|
-
result
|
|
92
|
-
cache: { hit: false, key: "" },
|
|
93
|
-
placeholder: false
|
|
94
|
-
};
|
|
95
|
-
return result;
|
|
101
|
+
return success(result);
|
|
96
102
|
}
|
|
97
103
|
parsePaginatedResult(remote) {
|
|
98
|
-
const products = remote.products.map(
|
|
104
|
+
const products = remote.products.map(
|
|
105
|
+
(p) => this.parseSingle(p)
|
|
106
|
+
);
|
|
99
107
|
const result = {
|
|
100
108
|
identifier: {
|
|
101
109
|
facets: [],
|
|
@@ -106,10 +114,6 @@ class MedusaSearchProvider extends ProductSearchProvider {
|
|
|
106
114
|
},
|
|
107
115
|
term: ""
|
|
108
116
|
},
|
|
109
|
-
meta: {
|
|
110
|
-
cache: { hit: false, key: "unknown" },
|
|
111
|
-
placeholder: false
|
|
112
|
-
},
|
|
113
117
|
pageNumber: (Math.ceil(remote.offset / remote.limit) || 0) + 1,
|
|
114
118
|
pageSize: remote.limit,
|
|
115
119
|
totalCount: remote.count,
|
|
@@ -129,16 +133,8 @@ class MedusaSearchProvider extends ProductSearchProvider {
|
|
|
129
133
|
if (heroVariant) {
|
|
130
134
|
variants.push(this.parseVariant(heroVariant, _body));
|
|
131
135
|
}
|
|
132
|
-
const meta = {
|
|
133
|
-
cache: {
|
|
134
|
-
hit: false,
|
|
135
|
-
key: ""
|
|
136
|
-
},
|
|
137
|
-
placeholder: false
|
|
138
|
-
};
|
|
139
136
|
const result = {
|
|
140
137
|
identifier,
|
|
141
|
-
meta,
|
|
142
138
|
name,
|
|
143
139
|
slug,
|
|
144
140
|
variants
|
|
@@ -151,18 +147,18 @@ class MedusaSearchProvider extends ProductSearchProvider {
|
|
|
151
147
|
altText: product.title || void 0
|
|
152
148
|
});
|
|
153
149
|
const mappedOptions = variant.options?.filter((x) => x.option?.title === "Color").map(
|
|
154
|
-
(opt) => ProductVariantOptionSchema.parse(
|
|
155
|
-
{
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
}
|
|
161
|
-
)
|
|
150
|
+
(opt) => ProductVariantOptionSchema.parse({
|
|
151
|
+
identifier: ProductOptionIdentifierSchema.parse({
|
|
152
|
+
key: opt.option_id
|
|
153
|
+
}),
|
|
154
|
+
name: opt.value || ""
|
|
155
|
+
})
|
|
162
156
|
) || [];
|
|
163
157
|
const mappedOption = variant.options?.[0];
|
|
164
158
|
return ProductSearchResultItemVariantSchema.parse({
|
|
165
|
-
variant: ProductVariantIdentifierSchema.parse({
|
|
159
|
+
variant: ProductVariantIdentifierSchema.parse({
|
|
160
|
+
sku: variant.sku || ""
|
|
161
|
+
}),
|
|
166
162
|
image: img
|
|
167
163
|
});
|
|
168
164
|
}
|
|
@@ -174,7 +170,7 @@ class MedusaSearchProvider extends ProductSearchProvider {
|
|
|
174
170
|
facet: facetIdentifier,
|
|
175
171
|
key: payload.categoryPath[payload.categoryPath.length - 1].identifier.key
|
|
176
172
|
});
|
|
177
|
-
return facetValueIdentifier;
|
|
173
|
+
return success(facetValueIdentifier);
|
|
178
174
|
}
|
|
179
175
|
parseFacetValue(facetValueIdentifier, label, count) {
|
|
180
176
|
throw new Error("Method not implemented.");
|
|
@@ -17,7 +17,9 @@ import {
|
|
|
17
17
|
ProductQueryBySKUSchema,
|
|
18
18
|
ProductQueryBySlugSchema,
|
|
19
19
|
ProductSchema,
|
|
20
|
-
Reactionary
|
|
20
|
+
Reactionary,
|
|
21
|
+
success,
|
|
22
|
+
error
|
|
21
23
|
} from "@reactionary/core";
|
|
22
24
|
import createDebug from "debug";
|
|
23
25
|
const debug = createDebug("reactionary:medusa:product");
|
|
@@ -37,13 +39,13 @@ class MedusaProductProvider extends ProductProvider {
|
|
|
37
39
|
response = await client.store.product.retrieve(payload.identifier.key, {
|
|
38
40
|
fields: "+metadata,+categories.metadata.*"
|
|
39
41
|
});
|
|
40
|
-
} catch (
|
|
42
|
+
} catch (error2) {
|
|
41
43
|
if (debug.enabled) {
|
|
42
|
-
debug(`Product with ID: ${payload.identifier.key} not found, returning empty product. Error %O `,
|
|
44
|
+
debug(`Product with ID: ${payload.identifier.key} not found, returning empty product. Error %O `, error2);
|
|
43
45
|
}
|
|
44
|
-
return this.createEmptyProduct(payload.identifier.key);
|
|
46
|
+
return success(this.createEmptyProduct(payload.identifier.key));
|
|
45
47
|
}
|
|
46
|
-
return this.parseSingle(response.product);
|
|
48
|
+
return success(this.parseSingle(response.product));
|
|
47
49
|
}
|
|
48
50
|
async getBySlug(payload) {
|
|
49
51
|
const client = await this.client.getClient();
|
|
@@ -60,9 +62,12 @@ class MedusaProductProvider extends ProductProvider {
|
|
|
60
62
|
debug(`Found ${response.count} products for slug: ${payload.slug}`);
|
|
61
63
|
}
|
|
62
64
|
if (response.count === 0) {
|
|
63
|
-
return
|
|
65
|
+
return error({
|
|
66
|
+
type: "NotFound",
|
|
67
|
+
identifier: payload
|
|
68
|
+
});
|
|
64
69
|
}
|
|
65
|
-
return this.parseSingle(response.products[0]);
|
|
70
|
+
return success(this.parseSingle(response.products[0]));
|
|
66
71
|
}
|
|
67
72
|
async getBySKU(payload) {
|
|
68
73
|
if (debug.enabled) {
|
|
@@ -76,7 +81,7 @@ class MedusaProductProvider extends ProductProvider {
|
|
|
76
81
|
}
|
|
77
82
|
product.variants = [];
|
|
78
83
|
product.variants.push(variant);
|
|
79
|
-
return this.parseSingle(product);
|
|
84
|
+
return success(this.parseSingle(product));
|
|
80
85
|
}
|
|
81
86
|
parseSingle(_body) {
|
|
82
87
|
const identifier = ProductIdentifierSchema.parse({ key: _body.id });
|
|
@@ -99,10 +104,6 @@ class MedusaProductProvider extends ProductProvider {
|
|
|
99
104
|
..._body.variants.slice(1).map((variant) => this.parseVariant(variant, _body))
|
|
100
105
|
);
|
|
101
106
|
}
|
|
102
|
-
const meta = {
|
|
103
|
-
cache: { hit: false, key: this.generateCacheKeySingle(identifier) },
|
|
104
|
-
placeholder: false
|
|
105
|
-
};
|
|
106
107
|
const result = {
|
|
107
108
|
brand: "",
|
|
108
109
|
description,
|
|
@@ -110,7 +111,6 @@ class MedusaProductProvider extends ProductProvider {
|
|
|
110
111
|
longDescription: "",
|
|
111
112
|
mainVariant,
|
|
112
113
|
manufacturer: "",
|
|
113
|
-
meta,
|
|
114
114
|
name,
|
|
115
115
|
options: [],
|
|
116
116
|
parentCategories,
|