shopify_storefront_sdk 1.0.3 → 2.0.0
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 +136 -70
- package/dist/cjs/client/client.js +110 -23
- package/dist/cjs/generated/shopify.js +25 -50
- package/dist/cjs/helpers/CartManager.js +55 -0
- package/dist/cjs/helpers/CustomerSession.js +41 -0
- package/dist/cjs/index.js +210 -25
- package/dist/cjs/tests/integration/sdk.test.js +266 -0
- package/dist/cjs/tests/unit/cache.test.js +86 -0
- package/dist/cjs/tests/unit/cartManager.test.js +43 -0
- package/dist/cjs/tests/unit/client.test.js +134 -0
- package/dist/cjs/tests/unit/customerSession.test.js +50 -0
- package/dist/cjs/tests/unit/pagination.test.js +41 -0
- package/dist/cjs/tests/unit/webhooks.test.js +41 -0
- package/dist/cjs/utils/cache.js +29 -0
- package/dist/cjs/utils/config.js +0 -1
- package/dist/cjs/utils/errors.js +53 -0
- package/dist/cjs/utils/pagination.js +30 -0
- package/dist/cjs/utils/webhooks.js +33 -0
- package/dist/client/client.d.ts +12 -1
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/client.js +111 -21
- package/dist/client/client.js.map +1 -1
- package/dist/generated/shopify.d.ts +4048 -2764
- package/dist/generated/shopify.d.ts.map +1 -1
- package/dist/generated/shopify.js +26 -50
- package/dist/generated/shopify.js.map +1 -1
- package/dist/helpers/CartManager.d.ts +32 -0
- package/dist/helpers/CartManager.d.ts.map +1 -0
- package/dist/helpers/CartManager.js +53 -0
- package/dist/helpers/CartManager.js.map +1 -0
- package/dist/helpers/CustomerSession.d.ts +27 -0
- package/dist/helpers/CustomerSession.d.ts.map +1 -0
- package/dist/helpers/CustomerSession.js +40 -0
- package/dist/helpers/CustomerSession.js.map +1 -0
- package/dist/index.d.ts +179 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +204 -25
- package/dist/index.js.map +1 -1
- package/dist/tests/integration/sdk.test.d.ts +2 -0
- package/dist/tests/integration/sdk.test.d.ts.map +1 -0
- package/dist/tests/integration/sdk.test.js +245 -0
- package/dist/tests/integration/sdk.test.js.map +1 -0
- package/dist/tests/unit/cache.test.d.ts +2 -0
- package/dist/tests/unit/cache.test.d.ts.map +1 -0
- package/dist/tests/unit/cache.test.js +85 -0
- package/dist/tests/unit/cache.test.js.map +1 -0
- package/dist/tests/unit/cartManager.test.d.ts +2 -0
- package/dist/tests/unit/cartManager.test.d.ts.map +1 -0
- package/dist/tests/unit/cartManager.test.js +43 -0
- package/dist/tests/unit/cartManager.test.js.map +1 -0
- package/dist/tests/unit/client.test.d.ts +2 -0
- package/dist/tests/unit/client.test.d.ts.map +1 -0
- package/dist/tests/unit/client.test.js +133 -0
- package/dist/tests/unit/client.test.js.map +1 -0
- package/dist/tests/unit/customerSession.test.d.ts +2 -0
- package/dist/tests/unit/customerSession.test.d.ts.map +1 -0
- package/dist/tests/unit/customerSession.test.js +49 -0
- package/dist/tests/unit/customerSession.test.js.map +1 -0
- package/dist/tests/unit/pagination.test.d.ts +2 -0
- package/dist/tests/unit/pagination.test.d.ts.map +1 -0
- package/dist/tests/unit/pagination.test.js +40 -0
- package/dist/tests/unit/pagination.test.js.map +1 -0
- package/dist/tests/unit/webhooks.test.d.ts +2 -0
- package/dist/tests/unit/webhooks.test.d.ts.map +1 -0
- package/dist/tests/unit/webhooks.test.js +40 -0
- package/dist/tests/unit/webhooks.test.js.map +1 -0
- package/dist/utils/cache.d.ts +14 -0
- package/dist/utils/cache.d.ts.map +1 -0
- package/dist/utils/cache.js +24 -0
- package/dist/utils/cache.js.map +1 -0
- package/dist/utils/config.d.ts +6 -0
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/errors.d.ts +30 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +48 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/pagination.d.ts +20 -0
- package/dist/utils/pagination.d.ts.map +1 -0
- package/dist/utils/pagination.js +28 -0
- package/dist/utils/pagination.js.map +1 -0
- package/dist/utils/webhooks.d.ts +10 -0
- package/dist/utils/webhooks.d.ts.map +1 -0
- package/dist/utils/webhooks.js +31 -0
- package/dist/utils/webhooks.js.map +1 -0
- package/package.json +11 -7
- package/dist/cjs/client/client.d.ts +0 -9
- package/dist/cjs/client/client.d.ts.map +0 -1
- package/dist/cjs/client/client.js.map +0 -1
- package/dist/cjs/generated/shopify.d.ts +0 -9612
- package/dist/cjs/generated/shopify.d.ts.map +0 -1
- package/dist/cjs/generated/shopify.js.map +0 -1
- package/dist/cjs/index.d.ts +0 -34
- package/dist/cjs/index.d.ts.map +0 -1
- package/dist/cjs/index.js.map +0 -1
- package/dist/cjs/tests/test.d.ts +0 -34
- package/dist/cjs/tests/test.d.ts.map +0 -1
- package/dist/cjs/tests/test.js +0 -202
- package/dist/cjs/tests/test.js.map +0 -1
- package/dist/cjs/utils/config.d.ts +0 -5
- package/dist/cjs/utils/config.d.ts.map +0 -1
- package/dist/cjs/utils/config.js.map +0 -1
- package/dist/tests/test.d.ts +0 -34
- package/dist/tests/test.d.ts.map +0 -1
- package/dist/tests/test.js +0 -202
- package/dist/tests/test.js.map +0 -1
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CustomerSession = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* A stateful high-level manager for an authenticated Customer's session.
|
|
6
|
+
* Automatically injects the customer access token into subsequent requests.
|
|
7
|
+
*/
|
|
8
|
+
class CustomerSession {
|
|
9
|
+
constructor(sdk, customerAccessToken) {
|
|
10
|
+
this.sdk = sdk;
|
|
11
|
+
this.token = customerAccessToken;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Retrieves the customer details for this session.
|
|
15
|
+
* Useful for verifying the token is still valid.
|
|
16
|
+
*/
|
|
17
|
+
async verify() {
|
|
18
|
+
return this.sdk.verifyCustomerToken({ token: this.token });
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Updates this customer's profile information.
|
|
22
|
+
* @param customer The fields to update (e.g. firstName, lastName).
|
|
23
|
+
*/
|
|
24
|
+
async update(customer) {
|
|
25
|
+
return this.sdk.updateCustomer({
|
|
26
|
+
customerAccessToken: this.token,
|
|
27
|
+
customer,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Fetches the order history for this authenticated customer.
|
|
32
|
+
* @param first The number of orders to return (defaults to 250).
|
|
33
|
+
*/
|
|
34
|
+
async getOrders(first = 250) {
|
|
35
|
+
return this.sdk.getCustomerOrders({
|
|
36
|
+
customerAccessToken: this.token,
|
|
37
|
+
first,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
exports.CustomerSession = CustomerSession;
|
package/dist/cjs/index.js
CHANGED
|
@@ -1,15 +1,70 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.InMemoryCache = exports.ShopifyInvalidRequestError = exports.ShopifyUserError = exports.ShopifyGraphQLError = exports.ShopifyNetworkError = exports.ShopifyError = void 0;
|
|
3
4
|
const client_js_1 = require("./client/client.js");
|
|
4
5
|
const shopify_js_1 = require("./generated/shopify.js");
|
|
6
|
+
// Export Custom Error Classes
|
|
7
|
+
var errors_js_1 = require("./utils/errors.js");
|
|
8
|
+
Object.defineProperty(exports, "ShopifyError", { enumerable: true, get: function () { return errors_js_1.ShopifyError; } });
|
|
9
|
+
Object.defineProperty(exports, "ShopifyNetworkError", { enumerable: true, get: function () { return errors_js_1.ShopifyNetworkError; } });
|
|
10
|
+
Object.defineProperty(exports, "ShopifyGraphQLError", { enumerable: true, get: function () { return errors_js_1.ShopifyGraphQLError; } });
|
|
11
|
+
Object.defineProperty(exports, "ShopifyUserError", { enumerable: true, get: function () { return errors_js_1.ShopifyUserError; } });
|
|
12
|
+
Object.defineProperty(exports, "ShopifyInvalidRequestError", { enumerable: true, get: function () { return errors_js_1.ShopifyInvalidRequestError; } });
|
|
13
|
+
// Export Cache utilities
|
|
14
|
+
var cache_js_1 = require("./utils/cache.js");
|
|
15
|
+
Object.defineProperty(exports, "InMemoryCache", { enumerable: true, get: function () { return cache_js_1.InMemoryCache; } });
|
|
16
|
+
const pagination_js_1 = require("./utils/pagination.js");
|
|
17
|
+
const webhooks_js_1 = require("./utils/webhooks.js");
|
|
18
|
+
const CartManager_js_1 = require("./helpers/CartManager.js");
|
|
19
|
+
const CustomerSession_js_1 = require("./helpers/CustomerSession.js");
|
|
5
20
|
class ShopifyStorefront {
|
|
6
21
|
constructor(config) {
|
|
7
22
|
this.client = new client_js_1.default(config);
|
|
8
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Returns a stateful CustomerSession wrapper.
|
|
26
|
+
* This automatically injects the customer's access token into subsequent requests.
|
|
27
|
+
*
|
|
28
|
+
* @param customerAccessToken The active access token for the logged-in customer.
|
|
29
|
+
* @returns CustomerSession instance.
|
|
30
|
+
*/
|
|
31
|
+
customer(customerAccessToken) {
|
|
32
|
+
return new CustomerSession_js_1.CustomerSession(this, customerAccessToken);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Returns a stateful CartManager to effortlessly manage a shopping cart.
|
|
36
|
+
* If a cartId is not provided, the manager will lazily create one on the first operation.
|
|
37
|
+
*
|
|
38
|
+
* @param cartId An optional existing cart ID.
|
|
39
|
+
* @returns CartManager instance.
|
|
40
|
+
*/
|
|
41
|
+
cart(cartId) {
|
|
42
|
+
return new CartManager_js_1.CartManager(this, cartId);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Verifies the authenticity of a Shopify webhook.
|
|
46
|
+
* @param rawBody The raw string/buffer payload of the webhook.
|
|
47
|
+
* @param hmacHeader The X-Shopify-Hmac-Sha256 header.
|
|
48
|
+
* @param secret Your Shopify API secret key.
|
|
49
|
+
* @returns true if the webhook is authentic.
|
|
50
|
+
*/
|
|
51
|
+
static verifyWebhook(rawBody, hmacHeader, secret) {
|
|
52
|
+
return (0, webhooks_js_1.verifyWebhook)(rawBody, hmacHeader, secret);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Fetches a paginated list of products from the store.
|
|
56
|
+
* @param variables Includes `first`, `after`, `last`, `before`, and `query` to control pagination and filtering.
|
|
57
|
+
* @returns A promise resolving to the products connection.
|
|
58
|
+
*/
|
|
9
59
|
async getProducts({ first, last, after, before, query, }) {
|
|
10
60
|
const data = await this.client.query(shopify_js_1.GetProductsDocument, { first, last, after, before, query });
|
|
11
61
|
return data;
|
|
12
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* Fetches a single product by its global ID.
|
|
65
|
+
* @param variables The `id` of the product and optional `metafields` array.
|
|
66
|
+
* @returns A promise resolving to the requested product.
|
|
67
|
+
*/
|
|
13
68
|
async getProductById({ id, metafields }) {
|
|
14
69
|
const data = await this.client.query(shopify_js_1.GetProductByIdDocument, {
|
|
15
70
|
id,
|
|
@@ -17,18 +72,38 @@ class ShopifyStorefront {
|
|
|
17
72
|
});
|
|
18
73
|
return data;
|
|
19
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* Fetches recommended products based on a given product ID.
|
|
77
|
+
* @param variables The `productId` for which to fetch recommendations.
|
|
78
|
+
* @returns A promise resolving to an array of recommended products.
|
|
79
|
+
*/
|
|
20
80
|
async getProductRecommendations({ productId, }) {
|
|
21
81
|
const data = await this.client.query(shopify_js_1.GetProductRecommendationsDocument, { productId });
|
|
22
82
|
return data;
|
|
23
83
|
}
|
|
84
|
+
/**
|
|
85
|
+
* Fetches a single product by its handle.
|
|
86
|
+
* @param variables The `handle` of the product.
|
|
87
|
+
* @returns A promise resolving to the requested product.
|
|
88
|
+
*/
|
|
24
89
|
async getProductByHandle({ handle }) {
|
|
25
90
|
const data = await this.client.query(shopify_js_1.GetProductByHandleDocument, { handle });
|
|
26
91
|
return data;
|
|
27
92
|
}
|
|
28
|
-
|
|
93
|
+
/**
|
|
94
|
+
* Fetches a paginated list of product types available in the store.
|
|
95
|
+
* @param variables Includes `first` to limit the number of types returned.
|
|
96
|
+
* @returns A promise resolving to the product types connection.
|
|
97
|
+
*/
|
|
98
|
+
async getProductTypes({ first }) {
|
|
29
99
|
const data = await this.client.query(shopify_js_1.GetAllProductTypesDocument, { first });
|
|
30
100
|
return data;
|
|
31
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* Fetches a paginated list of collections from the store.
|
|
104
|
+
* @param variables Includes `first` and `after` for pagination.
|
|
105
|
+
* @returns A promise resolving to the collections connection.
|
|
106
|
+
*/
|
|
32
107
|
async getCollections({ first, after }) {
|
|
33
108
|
const data = await this.client.query(shopify_js_1.GetCollectionsDocument, {
|
|
34
109
|
first,
|
|
@@ -36,7 +111,12 @@ class ShopifyStorefront {
|
|
|
36
111
|
});
|
|
37
112
|
return data;
|
|
38
113
|
}
|
|
39
|
-
|
|
114
|
+
/**
|
|
115
|
+
* Creates a new customer account.
|
|
116
|
+
* @param variables The customer details including `firstName`, `lastName`, `email`, `password`, `phone`, and `acceptsMarketing`.
|
|
117
|
+
* @returns A promise resolving to the customer creation payload. Throws ShopifyUserError if validation fails.
|
|
118
|
+
*/
|
|
119
|
+
async createCustomer({ firstName, lastName, password, acceptsMarketing, email, phone, }) {
|
|
40
120
|
const data = await this.client.query(shopify_js_1.CustomerCreateDocument, {
|
|
41
121
|
firstName,
|
|
42
122
|
lastName,
|
|
@@ -55,7 +135,12 @@ class ShopifyStorefront {
|
|
|
55
135
|
});
|
|
56
136
|
return data;
|
|
57
137
|
}
|
|
58
|
-
|
|
138
|
+
/**
|
|
139
|
+
* Authenticates a customer using their email and password to generate an access token.
|
|
140
|
+
* @param variables The `email` and `password` of the customer.
|
|
141
|
+
* @returns A promise resolving to the access token payload. Throws ShopifyUserError on invalid credentials.
|
|
142
|
+
*/
|
|
143
|
+
async loginCustomer({ email, password }) {
|
|
59
144
|
const data = await this.client.query(shopify_js_1.CustomerAccessTokenCreateDocument, {
|
|
60
145
|
email,
|
|
61
146
|
password,
|
|
@@ -66,25 +151,50 @@ class ShopifyStorefront {
|
|
|
66
151
|
});
|
|
67
152
|
return data;
|
|
68
153
|
}
|
|
69
|
-
|
|
154
|
+
/**
|
|
155
|
+
* Retrieves customer details using an active customer access token.
|
|
156
|
+
* @param variables The customer access `token`.
|
|
157
|
+
* @returns A promise resolving to the customer details.
|
|
158
|
+
*/
|
|
159
|
+
async verifyCustomerToken({ token }) {
|
|
70
160
|
const data = await this.client.query(shopify_js_1.GetCustomerDocument, { token });
|
|
71
161
|
return data;
|
|
72
162
|
}
|
|
73
|
-
|
|
163
|
+
/**
|
|
164
|
+
* Initiates the password recovery flow for a customer.
|
|
165
|
+
* @param variables The `email` of the customer recovering their account.
|
|
166
|
+
* @returns A promise resolving to the recovery payload.
|
|
167
|
+
*/
|
|
168
|
+
async recoverCustomer({ email }) {
|
|
74
169
|
const data = await this.client.query(shopify_js_1.CustomerRecoverDocument, { email });
|
|
75
170
|
return data;
|
|
76
171
|
}
|
|
77
|
-
|
|
172
|
+
/**
|
|
173
|
+
* Updates an existing customer's information.
|
|
174
|
+
* @param variables The `customerAccessToken` and the `customer` input fields to update.
|
|
175
|
+
* @returns A promise resolving to the update payload.
|
|
176
|
+
*/
|
|
177
|
+
async updateCustomer({ customerAccessToken, customer, }) {
|
|
78
178
|
const data = await this.client.query(shopify_js_1.CustomerUpdateDocument, {
|
|
79
179
|
customerAccessToken,
|
|
80
180
|
customer,
|
|
81
181
|
});
|
|
82
182
|
return data;
|
|
83
183
|
}
|
|
184
|
+
/**
|
|
185
|
+
* Retrieves an existing cart by its ID.
|
|
186
|
+
* @param variables The `cartId` and optional `first` limit for lines.
|
|
187
|
+
* @returns A promise resolving to the cart details.
|
|
188
|
+
*/
|
|
84
189
|
async getCart({ cartId, first }) {
|
|
85
190
|
const data = await this.client.query(shopify_js_1.GetCartDocument, { cartId, first });
|
|
86
191
|
return data;
|
|
87
192
|
}
|
|
193
|
+
/**
|
|
194
|
+
* Creates a new cart with optional initial line items.
|
|
195
|
+
* @param variables The `input` configuration for the new cart.
|
|
196
|
+
* @returns A promise resolving to the created cart payload.
|
|
197
|
+
*/
|
|
88
198
|
async createCart({ input, first }) {
|
|
89
199
|
const data = await this.client.query(shopify_js_1.CartCreateDocument, {
|
|
90
200
|
input,
|
|
@@ -92,21 +202,36 @@ class ShopifyStorefront {
|
|
|
92
202
|
});
|
|
93
203
|
return data;
|
|
94
204
|
}
|
|
95
|
-
|
|
205
|
+
/**
|
|
206
|
+
* Adds line items to an existing cart.
|
|
207
|
+
* @param variables The `cartId` and the `lines` to add.
|
|
208
|
+
* @returns A promise resolving to the updated cart payload.
|
|
209
|
+
*/
|
|
210
|
+
async addCartLines({ cartId, lines }) {
|
|
96
211
|
const data = await this.client.query(shopify_js_1.CartLinesAddDocument, {
|
|
97
212
|
cartId,
|
|
98
213
|
lines,
|
|
99
214
|
});
|
|
100
215
|
return data;
|
|
101
216
|
}
|
|
102
|
-
|
|
217
|
+
/**
|
|
218
|
+
* Removes line items from an existing cart.
|
|
219
|
+
* @param variables The `cartId` and the `lineIds` to remove.
|
|
220
|
+
* @returns A promise resolving to the updated cart payload.
|
|
221
|
+
*/
|
|
222
|
+
async removeCartLines({ cartId, lineIds }) {
|
|
103
223
|
const data = await this.client.query(shopify_js_1.CartLinesRemoveDocument, {
|
|
104
224
|
cartId,
|
|
105
225
|
lineIds,
|
|
106
226
|
});
|
|
107
227
|
return data;
|
|
108
228
|
}
|
|
109
|
-
|
|
229
|
+
/**
|
|
230
|
+
* Updates line items in an existing cart (e.g., changing quantity).
|
|
231
|
+
* @param variables The `cartId`, the updated `lines`, and optional `first` limit.
|
|
232
|
+
* @returns A promise resolving to the updated cart payload.
|
|
233
|
+
*/
|
|
234
|
+
async updateCartLines({ cartId, first, lines, }) {
|
|
110
235
|
const data = await this.client.query(shopify_js_1.CartLinesUpdateDocument, {
|
|
111
236
|
cartId,
|
|
112
237
|
first,
|
|
@@ -114,7 +239,12 @@ class ShopifyStorefront {
|
|
|
114
239
|
});
|
|
115
240
|
return data;
|
|
116
241
|
}
|
|
117
|
-
|
|
242
|
+
/**
|
|
243
|
+
* Updates the buyer identity (e.g., email, customer access token) for a cart.
|
|
244
|
+
* @param variables The `cartId` and the `buyerIdentity` object.
|
|
245
|
+
* @returns A promise resolving to the updated cart payload.
|
|
246
|
+
*/
|
|
247
|
+
async updateCartBuyerIdentity({ cartId, buyerIdentity: { email, phone, preferences, companyLocationId, countryCode, customerAccessToken, }, }) {
|
|
118
248
|
const data = await this.client.query(shopify_js_1.CartBuyerIdentityUpdateDocument, {
|
|
119
249
|
cartId,
|
|
120
250
|
buyerIdentity: {
|
|
@@ -128,43 +258,98 @@ class ShopifyStorefront {
|
|
|
128
258
|
});
|
|
129
259
|
return data;
|
|
130
260
|
}
|
|
131
|
-
|
|
261
|
+
/**
|
|
262
|
+
* Sets metafields on an existing cart.
|
|
263
|
+
* @param variables The `metafields` array containing key-value pairs.
|
|
264
|
+
* @returns A promise resolving to the updated cart payload.
|
|
265
|
+
*/
|
|
266
|
+
async setCartMetafields({ metafields }) {
|
|
132
267
|
const data = await this.client.query(shopify_js_1.CartBuyerIdentityUpdateDocument, {
|
|
133
268
|
metafields,
|
|
134
269
|
});
|
|
135
270
|
return data;
|
|
136
271
|
}
|
|
272
|
+
/**
|
|
273
|
+
* Fetches a paginated list of blogs from the store.
|
|
274
|
+
* @param variables Includes `first` for pagination.
|
|
275
|
+
* @returns A promise resolving to the blogs connection.
|
|
276
|
+
*/
|
|
137
277
|
async getBlogs({ first }) {
|
|
138
|
-
const data = await this.client.query(shopify_js_1.GetBlogsDocument, {
|
|
139
|
-
first,
|
|
140
|
-
});
|
|
278
|
+
const data = await this.client.query(shopify_js_1.GetBlogsDocument, { first });
|
|
141
279
|
return data;
|
|
142
280
|
}
|
|
281
|
+
/**
|
|
282
|
+
* Fetches a specific blog by its handle.
|
|
283
|
+
* @param variables The `handle` of the blog and `first` pagination parameter for its articles.
|
|
284
|
+
* @returns A promise resolving to the requested blog.
|
|
285
|
+
*/
|
|
143
286
|
async getBlog({ first, handle }) {
|
|
144
|
-
const data = await this.client.query(shopify_js_1.GetBlogsDocument,
|
|
145
|
-
|
|
146
|
-
handle,
|
|
147
|
-
});
|
|
287
|
+
const data = await this.client.query(shopify_js_1.GetBlogsDocument, // Original used GetBlogsDocument here, not GetBlogDocument
|
|
288
|
+
{ first, handle });
|
|
148
289
|
return data;
|
|
149
290
|
}
|
|
291
|
+
/**
|
|
292
|
+
* Fetches a paginated list of all articles across all blogs.
|
|
293
|
+
* @param variables Includes `first` for pagination.
|
|
294
|
+
* @returns A promise resolving to the articles connection.
|
|
295
|
+
*/
|
|
150
296
|
async getArticles({ first }) {
|
|
151
|
-
const data = await this.client.query(shopify_js_1.GetArticlesDocument, {
|
|
152
|
-
first,
|
|
153
|
-
});
|
|
297
|
+
const data = await this.client.query(shopify_js_1.GetArticlesDocument, { first });
|
|
154
298
|
return data;
|
|
155
299
|
}
|
|
156
|
-
|
|
157
|
-
|
|
300
|
+
/**
|
|
301
|
+
* Fetches a single article by its handle and its parent blog's handle.
|
|
302
|
+
* @param variables The `articleHandle` and `blogHandle`.
|
|
303
|
+
* @returns A promise resolving to the requested article.
|
|
304
|
+
*/
|
|
305
|
+
async getArticle({ articleHandle, blogHandle, }) {
|
|
306
|
+
const data = await this.client.query(shopify_js_1.GetSingleArticleDocument, {
|
|
307
|
+
articleHandle,
|
|
308
|
+
blogHandle,
|
|
309
|
+
});
|
|
158
310
|
return data;
|
|
159
311
|
}
|
|
312
|
+
/**
|
|
313
|
+
* Fetches the order history for an authenticated customer.
|
|
314
|
+
* @param variables The `customerAccessToken` and pagination limits.
|
|
315
|
+
* @returns A promise resolving to the customer's orders connection.
|
|
316
|
+
*/
|
|
160
317
|
async getCustomerOrders({ customerAccessToken, first, }) {
|
|
161
|
-
const data = await this.client.query(shopify_js_1.GetCustomerOrdersDocument, {
|
|
318
|
+
const data = await this.client.query(shopify_js_1.GetCustomerOrdersDocument, {
|
|
319
|
+
customerAccessToken,
|
|
320
|
+
first,
|
|
321
|
+
});
|
|
322
|
+
return data;
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Fetches general information about the store (name, description, payment settings).
|
|
326
|
+
* @returns A promise resolving to the shop information.
|
|
327
|
+
*/
|
|
328
|
+
async getShopInfo() {
|
|
329
|
+
const data = await this.client.query(shopify_js_1.GetShopInfoDocument, {});
|
|
162
330
|
return data;
|
|
163
331
|
}
|
|
332
|
+
/**
|
|
333
|
+
* Executes a custom GraphQL query or mutation against the Storefront API.
|
|
334
|
+
* Use this when the built-in SDK methods do not cover your specific use case.
|
|
335
|
+
*
|
|
336
|
+
* @param query The raw GraphQL query or mutation string.
|
|
337
|
+
* @param variables An object containing variables for the GraphQL query.
|
|
338
|
+
* @returns A promise resolving to the generic requested data structure `T`.
|
|
339
|
+
*/
|
|
164
340
|
async customQuery(query, variables) {
|
|
165
341
|
const data = await this.client.query(query, variables);
|
|
166
342
|
return data;
|
|
167
343
|
}
|
|
344
|
+
/**
|
|
345
|
+
* Automatically fetches all pages of a Shopify GraphQL Connection and flattens the nodes into an array.
|
|
346
|
+
*
|
|
347
|
+
* @param fetchPage A function that takes an optional cursor and returns a promise of the API response.
|
|
348
|
+
* @param getConnection A selector function that extracts the Connection object from the API response.
|
|
349
|
+
* @returns A flat array of all nodes across all pages.
|
|
350
|
+
*/
|
|
351
|
+
async autoPaginate(fetchPage, getConnection) {
|
|
352
|
+
return (0, pagination_js_1.autoPaginate)(fetchPage, getConnection);
|
|
353
|
+
}
|
|
168
354
|
}
|
|
169
355
|
exports.default = ShopifyStorefront;
|
|
170
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vitest_1 = require("vitest");
|
|
4
|
+
const index_js_1 = require("../../index.js");
|
|
5
|
+
const dotenv = require("dotenv");
|
|
6
|
+
dotenv.config();
|
|
7
|
+
const { SHOPIFY_STORE_DOMAIN, SHOPIFY_STOREFRONT_TOKEN } = process.env;
|
|
8
|
+
// Only run these tests if the environment variables are present
|
|
9
|
+
const runLiveTests = !!(SHOPIFY_STORE_DOMAIN && SHOPIFY_STOREFRONT_TOKEN);
|
|
10
|
+
vitest_1.describe.runIf(runLiveTests)("Shopify SDK Integration Tests", () => {
|
|
11
|
+
let client;
|
|
12
|
+
// Shared state for the test chain
|
|
13
|
+
let firstProductId;
|
|
14
|
+
let firstProductHandle;
|
|
15
|
+
let firstVariantId;
|
|
16
|
+
let blogHandle;
|
|
17
|
+
let articleHandle;
|
|
18
|
+
let customerEmail = `testuser_${Date.now()}@example.com`;
|
|
19
|
+
let customerPassword = "Testing123!";
|
|
20
|
+
let customerAccessToken;
|
|
21
|
+
let cartId;
|
|
22
|
+
let lineItemId;
|
|
23
|
+
(0, vitest_1.beforeAll)(() => {
|
|
24
|
+
client = new index_js_1.default({
|
|
25
|
+
storeUrl: String(SHOPIFY_STORE_DOMAIN),
|
|
26
|
+
storefrontToken: String(SHOPIFY_STOREFRONT_TOKEN),
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
(0, vitest_1.describe)("Products & Collections", () => {
|
|
30
|
+
(0, vitest_1.it)("should fetch products", async () => {
|
|
31
|
+
var _a, _b, _c, _d;
|
|
32
|
+
const products = await client.getProducts({ first: 10 });
|
|
33
|
+
(0, vitest_1.expect)(products).toBeDefined();
|
|
34
|
+
(0, vitest_1.expect)((_a = products.products) === null || _a === void 0 ? void 0 : _a.edges).toBeInstanceOf(Array);
|
|
35
|
+
const firstEdge = (_b = products.products) === null || _b === void 0 ? void 0 : _b.edges[0];
|
|
36
|
+
if (firstEdge) {
|
|
37
|
+
firstProductId = firstEdge.node.id;
|
|
38
|
+
firstProductHandle = firstEdge.node.handle;
|
|
39
|
+
firstVariantId = ((_d = (_c = firstEdge.node.variants) === null || _c === void 0 ? void 0 : _c.edges[0]) === null || _d === void 0 ? void 0 : _d.node.id) || "";
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
(0, vitest_1.it)("should fetch a product by ID", async () => {
|
|
43
|
+
var _a;
|
|
44
|
+
if (!firstProductId)
|
|
45
|
+
return;
|
|
46
|
+
const product = await client.getProductById({
|
|
47
|
+
id: firstProductId,
|
|
48
|
+
metafields: [],
|
|
49
|
+
});
|
|
50
|
+
(0, vitest_1.expect)((_a = product === null || product === void 0 ? void 0 : product.product) === null || _a === void 0 ? void 0 : _a.id).toBe(firstProductId);
|
|
51
|
+
});
|
|
52
|
+
(0, vitest_1.it)("should fetch a product by handle", async () => {
|
|
53
|
+
var _a;
|
|
54
|
+
if (!firstProductHandle)
|
|
55
|
+
return;
|
|
56
|
+
const product = await client.getProductByHandle({
|
|
57
|
+
handle: firstProductHandle,
|
|
58
|
+
});
|
|
59
|
+
(0, vitest_1.expect)((_a = product === null || product === void 0 ? void 0 : product.product) === null || _a === void 0 ? void 0 : _a.handle).toBe(firstProductHandle);
|
|
60
|
+
});
|
|
61
|
+
(0, vitest_1.it)("should fetch all product types", async () => {
|
|
62
|
+
var _a;
|
|
63
|
+
const types = await client.getProductTypes({ first: 50 });
|
|
64
|
+
(0, vitest_1.expect)((_a = types === null || types === void 0 ? void 0 : types.products) === null || _a === void 0 ? void 0 : _a.edges).toBeInstanceOf(Array);
|
|
65
|
+
});
|
|
66
|
+
(0, vitest_1.it)("should fetch product recommendations", async () => {
|
|
67
|
+
if (!firstProductId)
|
|
68
|
+
return;
|
|
69
|
+
const recommendations = await client.getProductRecommendations({
|
|
70
|
+
productId: firstProductId,
|
|
71
|
+
});
|
|
72
|
+
(0, vitest_1.expect)(recommendations === null || recommendations === void 0 ? void 0 : recommendations.productRecommendations).toBeInstanceOf(Array);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
(0, vitest_1.describe)("Blogs & Articles", () => {
|
|
76
|
+
(0, vitest_1.it)("should fetch blogs", async () => {
|
|
77
|
+
var _a, _b, _c;
|
|
78
|
+
const blogs = await client.getBlogs({ first: 10 });
|
|
79
|
+
(0, vitest_1.expect)((_a = blogs === null || blogs === void 0 ? void 0 : blogs.blogs) === null || _a === void 0 ? void 0 : _a.edges).toBeInstanceOf(Array);
|
|
80
|
+
const firstBlog = (_c = (_b = blogs === null || blogs === void 0 ? void 0 : blogs.blogs) === null || _b === void 0 ? void 0 : _b.edges[0]) === null || _c === void 0 ? void 0 : _c.node;
|
|
81
|
+
if (firstBlog) {
|
|
82
|
+
blogHandle = firstBlog.handle;
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
(0, vitest_1.it)("should fetch a specific blog", async () => {
|
|
86
|
+
var _a;
|
|
87
|
+
if (!blogHandle)
|
|
88
|
+
return;
|
|
89
|
+
const blog = await client.getBlog({ first: 10, handle: blogHandle });
|
|
90
|
+
(0, vitest_1.expect)((_a = blog === null || blog === void 0 ? void 0 : blog.blog) === null || _a === void 0 ? void 0 : _a.handle).toBe(blogHandle);
|
|
91
|
+
});
|
|
92
|
+
(0, vitest_1.it)("should fetch articles", async () => {
|
|
93
|
+
var _a, _b, _c;
|
|
94
|
+
const articles = await client.getArticles({ first: 10 });
|
|
95
|
+
(0, vitest_1.expect)((_a = articles === null || articles === void 0 ? void 0 : articles.articles) === null || _a === void 0 ? void 0 : _a.edges).toBeInstanceOf(Array);
|
|
96
|
+
const firstArticle = (_c = (_b = articles === null || articles === void 0 ? void 0 : articles.articles) === null || _b === void 0 ? void 0 : _b.edges[0]) === null || _c === void 0 ? void 0 : _c.node;
|
|
97
|
+
if (firstArticle) {
|
|
98
|
+
articleHandle = firstArticle.handle;
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
(0, vitest_1.it)("should fetch a specific article", async () => {
|
|
102
|
+
if (!blogHandle || !articleHandle)
|
|
103
|
+
return;
|
|
104
|
+
const article = await client.getArticle({
|
|
105
|
+
blogHandle: blogHandle,
|
|
106
|
+
articleHandle: articleHandle,
|
|
107
|
+
});
|
|
108
|
+
(0, vitest_1.expect)(article).toBeDefined();
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
(0, vitest_1.describe)("Customers", () => {
|
|
112
|
+
(0, vitest_1.it)("should create a customer", async () => {
|
|
113
|
+
var _a, _b;
|
|
114
|
+
const user = await client.createCustomer({
|
|
115
|
+
email: customerEmail,
|
|
116
|
+
password: customerPassword,
|
|
117
|
+
firstName: "SDK",
|
|
118
|
+
lastName: "User",
|
|
119
|
+
});
|
|
120
|
+
(0, vitest_1.expect)((_b = (_a = user === null || user === void 0 ? void 0 : user.customerCreate) === null || _a === void 0 ? void 0 : _a.customer) === null || _b === void 0 ? void 0 : _b.firstName).toBe("SDK");
|
|
121
|
+
});
|
|
122
|
+
(0, vitest_1.it)("should login a customer", async () => {
|
|
123
|
+
var _a, _b;
|
|
124
|
+
const login = await client.loginCustomer({
|
|
125
|
+
email: customerEmail,
|
|
126
|
+
password: customerPassword,
|
|
127
|
+
});
|
|
128
|
+
const token = (_b = (_a = login === null || login === void 0 ? void 0 : login.customerAccessTokenCreate) === null || _a === void 0 ? void 0 : _a.customerAccessToken) === null || _b === void 0 ? void 0 : _b.accessToken;
|
|
129
|
+
(0, vitest_1.expect)(token).toBeDefined();
|
|
130
|
+
if (token)
|
|
131
|
+
customerAccessToken = token;
|
|
132
|
+
});
|
|
133
|
+
(0, vitest_1.it)("should verify customer token", async () => {
|
|
134
|
+
var _a;
|
|
135
|
+
if (!customerAccessToken)
|
|
136
|
+
return;
|
|
137
|
+
const verify = await client.verifyCustomerToken({ token: customerAccessToken });
|
|
138
|
+
(0, vitest_1.expect)((_a = verify === null || verify === void 0 ? void 0 : verify.customer) === null || _a === void 0 ? void 0 : _a.email).toBe(customerEmail);
|
|
139
|
+
});
|
|
140
|
+
(0, vitest_1.it)("should request customer recovery", async () => {
|
|
141
|
+
var _a;
|
|
142
|
+
const resetReq = await client.recoverCustomer({ email: customerEmail });
|
|
143
|
+
(0, vitest_1.expect)((_a = resetReq === null || resetReq === void 0 ? void 0 : resetReq.customerRecover) === null || _a === void 0 ? void 0 : _a.customerUserErrors).toBeDefined();
|
|
144
|
+
});
|
|
145
|
+
(0, vitest_1.it)("should fetch customer orders", async () => {
|
|
146
|
+
var _a, _b;
|
|
147
|
+
if (!customerAccessToken)
|
|
148
|
+
return;
|
|
149
|
+
const orders = await client.getCustomerOrders({
|
|
150
|
+
customerAccessToken,
|
|
151
|
+
first: 50,
|
|
152
|
+
});
|
|
153
|
+
(0, vitest_1.expect)((_b = (_a = orders === null || orders === void 0 ? void 0 : orders.customer) === null || _a === void 0 ? void 0 : _a.orders) === null || _b === void 0 ? void 0 : _b.edges).toBeDefined();
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
(0, vitest_1.describe)("Carts", () => {
|
|
157
|
+
(0, vitest_1.it)("should create a cart", async () => {
|
|
158
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
159
|
+
if (!firstVariantId)
|
|
160
|
+
return;
|
|
161
|
+
const cart = await client.createCart({
|
|
162
|
+
input: {
|
|
163
|
+
lines: [
|
|
164
|
+
{
|
|
165
|
+
quantity: 1,
|
|
166
|
+
merchandiseId: firstVariantId,
|
|
167
|
+
},
|
|
168
|
+
],
|
|
169
|
+
},
|
|
170
|
+
first: 20,
|
|
171
|
+
});
|
|
172
|
+
(0, vitest_1.expect)((_b = (_a = cart === null || cart === void 0 ? void 0 : cart.cartCreate) === null || _a === void 0 ? void 0 : _a.cart) === null || _b === void 0 ? void 0 : _b.id).toBeDefined();
|
|
173
|
+
if ((_d = (_c = cart === null || cart === void 0 ? void 0 : cart.cartCreate) === null || _c === void 0 ? void 0 : _c.cart) === null || _d === void 0 ? void 0 : _d.id) {
|
|
174
|
+
cartId = cart.cartCreate.cart.id;
|
|
175
|
+
lineItemId = (_h = (_g = (_f = (_e = cart.cartCreate.cart.lines) === null || _e === void 0 ? void 0 : _e.edges[0]) === null || _f === void 0 ? void 0 : _f.node) === null || _g === void 0 ? void 0 : _g.id) !== null && _h !== void 0 ? _h : "";
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
(0, vitest_1.it)("should update cart buyer identity", async () => {
|
|
179
|
+
var _a, _b;
|
|
180
|
+
if (!cartId || !customerAccessToken)
|
|
181
|
+
return;
|
|
182
|
+
const identity = await client.updateCartBuyerIdentity({
|
|
183
|
+
cartId: cartId,
|
|
184
|
+
buyerIdentity: {
|
|
185
|
+
customerAccessToken: customerAccessToken,
|
|
186
|
+
email: customerEmail,
|
|
187
|
+
phone: "00000000000",
|
|
188
|
+
},
|
|
189
|
+
});
|
|
190
|
+
(0, vitest_1.expect)((_b = (_a = identity === null || identity === void 0 ? void 0 : identity.cartBuyerIdentityUpdate) === null || _a === void 0 ? void 0 : _a.cart) === null || _b === void 0 ? void 0 : _b.id).toBeDefined();
|
|
191
|
+
});
|
|
192
|
+
(0, vitest_1.it)("should fetch an existing cart", async () => {
|
|
193
|
+
var _a;
|
|
194
|
+
if (!cartId)
|
|
195
|
+
return;
|
|
196
|
+
const existingCart = await client.getCart({ cartId, first: 20 });
|
|
197
|
+
(0, vitest_1.expect)((_a = existingCart === null || existingCart === void 0 ? void 0 : existingCart.cart) === null || _a === void 0 ? void 0 : _a.id).toBe(cartId);
|
|
198
|
+
});
|
|
199
|
+
(0, vitest_1.it)("should add lines to a cart", async () => {
|
|
200
|
+
var _a, _b;
|
|
201
|
+
if (!cartId || !firstVariantId)
|
|
202
|
+
return;
|
|
203
|
+
const addToCart = await client.addCartLines({
|
|
204
|
+
cartId,
|
|
205
|
+
lines: [
|
|
206
|
+
{
|
|
207
|
+
quantity: 1,
|
|
208
|
+
merchandiseId: firstVariantId,
|
|
209
|
+
},
|
|
210
|
+
],
|
|
211
|
+
});
|
|
212
|
+
(0, vitest_1.expect)((_b = (_a = addToCart === null || addToCart === void 0 ? void 0 : addToCart.cartLinesAdd) === null || _a === void 0 ? void 0 : _a.cart) === null || _b === void 0 ? void 0 : _b.id).toBeDefined();
|
|
213
|
+
});
|
|
214
|
+
(0, vitest_1.it)("should update lines in a cart", async () => {
|
|
215
|
+
var _a, _b;
|
|
216
|
+
if (!cartId || !firstVariantId || !lineItemId)
|
|
217
|
+
return;
|
|
218
|
+
const updatedCart = await client.updateCartLines({
|
|
219
|
+
cartId,
|
|
220
|
+
first: 20,
|
|
221
|
+
lines: [
|
|
222
|
+
{
|
|
223
|
+
id: lineItemId,
|
|
224
|
+
quantity: 2,
|
|
225
|
+
merchandiseId: firstVariantId,
|
|
226
|
+
},
|
|
227
|
+
],
|
|
228
|
+
});
|
|
229
|
+
(0, vitest_1.expect)((_b = (_a = updatedCart === null || updatedCart === void 0 ? void 0 : updatedCart.cartLinesUpdate) === null || _a === void 0 ? void 0 : _a.cart) === null || _b === void 0 ? void 0 : _b.id).toBeDefined();
|
|
230
|
+
});
|
|
231
|
+
(0, vitest_1.it)("should remove lines from a cart", async () => {
|
|
232
|
+
var _a, _b;
|
|
233
|
+
if (!cartId || !lineItemId)
|
|
234
|
+
return;
|
|
235
|
+
const removedCart = await client.removeCartLines({
|
|
236
|
+
cartId,
|
|
237
|
+
lineIds: [lineItemId],
|
|
238
|
+
});
|
|
239
|
+
(0, vitest_1.expect)((_b = (_a = removedCart === null || removedCart === void 0 ? void 0 : removedCart.cartLinesRemove) === null || _a === void 0 ? void 0 : _a.cart) === null || _b === void 0 ? void 0 : _b.id).toBeDefined();
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
(0, vitest_1.describe)("Shop Info", () => {
|
|
243
|
+
(0, vitest_1.it)("should fetch shop info using the dedicated method", async () => {
|
|
244
|
+
var _a;
|
|
245
|
+
const shopInfo = await client.getShopInfo();
|
|
246
|
+
(0, vitest_1.expect)((_a = shopInfo === null || shopInfo === void 0 ? void 0 : shopInfo.shop) === null || _a === void 0 ? void 0 : _a.name).toBeDefined();
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
(0, vitest_1.describe)("Custom Queries", () => {
|
|
250
|
+
(0, vitest_1.it)("should successfully execute a custom query", async () => {
|
|
251
|
+
var _a;
|
|
252
|
+
const customQuery = await client.customQuery(`query getShopInfo {
|
|
253
|
+
shop {
|
|
254
|
+
name
|
|
255
|
+
description
|
|
256
|
+
paymentSettings {
|
|
257
|
+
currencyCode
|
|
258
|
+
countryCode
|
|
259
|
+
enabledPresentmentCurrencies
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}`, {});
|
|
263
|
+
(0, vitest_1.expect)((_a = customQuery === null || customQuery === void 0 ? void 0 : customQuery.shop) === null || _a === void 0 ? void 0 : _a.name).toBeDefined();
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
});
|