@shopify/hydrogen 1.4.4 → 1.6.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/dist/esnext/components/CartLineProvider/tests/fixtures.d.ts +86 -0
- package/dist/esnext/components/CartLineProvider/tests/fixtures.js +34 -0
- package/dist/esnext/components/CartProvider/CartProvider.client.d.ts +20 -11
- package/dist/esnext/components/CartProvider/CartProvider.client.js +457 -477
- package/dist/esnext/components/CartProvider/cart-queries.d.ts +1 -1
- package/dist/esnext/components/CartProvider/cart-queries.js +4 -1
- package/dist/esnext/components/CartProvider/tests/fixtures.d.ts +254 -0
- package/dist/esnext/components/CartProvider/tests/fixtures.js +53 -0
- package/dist/esnext/components/Metafield/Metafield.client.js +1 -3
- package/dist/esnext/entry-server.js +11 -1
- package/dist/esnext/experimental.d.ts +0 -1
- package/dist/esnext/experimental.js +0 -1
- package/dist/esnext/foundation/Analytics/connectors/Shopify/ShopifyAnalytics.client.js +21 -14
- package/dist/esnext/foundation/Analytics/connectors/Shopify/ShopifyAnalytics.server.js +15 -9
- package/dist/esnext/foundation/Analytics/connectors/Shopify/const.d.ts +5 -0
- package/dist/esnext/foundation/Analytics/connectors/Shopify/const.js +5 -0
- package/dist/esnext/foundation/Analytics/connectors/Shopify/customer-events.client.d.ts +2 -0
- package/dist/esnext/foundation/Analytics/connectors/Shopify/customer-events.client.js +182 -0
- package/dist/esnext/foundation/Analytics/connectors/Shopify/utils.d.ts +3 -0
- package/dist/esnext/foundation/Analytics/connectors/Shopify/utils.js +69 -0
- package/dist/esnext/foundation/HydrogenRequest/HydrogenRequest.server.d.ts +1 -0
- package/dist/esnext/foundation/HydrogenRequest/HydrogenRequest.server.js +2 -8
- package/dist/esnext/framework/plugins/vite-plugin-hydrogen-rsc.js +2 -2
- package/dist/esnext/hooks/useShopQuery/hooks.js +10 -6
- package/dist/esnext/storefront-api-types.d.ts +334 -116
- package/dist/esnext/storefront-api-types.js +3 -1
- package/dist/esnext/testing.d.ts +2 -0
- package/dist/esnext/testing.js +2 -0
- package/dist/esnext/utilities/random.d.ts +1 -0
- package/dist/esnext/utilities/random.js +11 -0
- package/dist/esnext/utilities/tests/MockedServerRequestProvider.server.d.ts +6 -0
- package/dist/esnext/utilities/tests/MockedServerRequestProvider.server.js +9 -0
- package/dist/esnext/utilities/tests/price.d.ts +5 -0
- package/dist/esnext/utilities/tests/price.js +8 -0
- package/dist/esnext/utilities/tests/provider-helpers.d.ts +31 -0
- package/dist/esnext/utilities/tests/provider-helpers.js +36 -0
- package/dist/esnext/version.d.ts +1 -1
- package/dist/esnext/version.js +1 -1
- package/dist/node/framework/plugins/vite-plugin-hydrogen-rsc.js +2 -2
- package/package.json +3 -1
- package/dist/esnext/components/CartProvider/CartProviderV2.client.d.ts +0 -50
- package/dist/esnext/components/CartProvider/CartProviderV2.client.js +0 -483
|
@@ -1,483 +0,0 @@
|
|
|
1
|
-
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
2
|
-
import { CountryCode, } from '../../storefront-api-types.js';
|
|
3
|
-
import { CartContext } from './context.js';
|
|
4
|
-
import { useCartAPIStateMachine } from './useCartAPIStateMachine.client.js';
|
|
5
|
-
import { CART_ID_STORAGE_KEY } from './constants.js';
|
|
6
|
-
import { ClientAnalytics } from '../../foundation/Analytics/ClientAnalytics.js';
|
|
7
|
-
export function CartProviderV2({ children, numCartLines, onCreate, onLineAdd, onLineRemove, onLineUpdate, onNoteUpdate, onBuyerIdentityUpdate, onAttributesUpdate, onDiscountCodesUpdate, onCreateComplete, onLineAddComplete, onLineRemoveComplete, onLineUpdateComplete, onNoteUpdateComplete, onBuyerIdentityUpdateComplete, onAttributesUpdateComplete, onDiscountCodesUpdateComplete, data: cart, cartFragment = defaultCartFragment, customerAccessToken, countryCode = CountryCode.Us, }) {
|
|
8
|
-
if (countryCode)
|
|
9
|
-
countryCode = countryCode.toUpperCase();
|
|
10
|
-
const [prevCountryCode, setPrevCountryCode] = useState(countryCode);
|
|
11
|
-
const [prevCustomerAccessToken, setPrevCustomerAccessToken] = useState(customerAccessToken);
|
|
12
|
-
const customerOverridesCountryCode = useRef(false);
|
|
13
|
-
if (prevCountryCode !== countryCode ||
|
|
14
|
-
prevCustomerAccessToken !== customerAccessToken) {
|
|
15
|
-
setPrevCountryCode(countryCode);
|
|
16
|
-
setPrevCustomerAccessToken(customerAccessToken);
|
|
17
|
-
customerOverridesCountryCode.current = false;
|
|
18
|
-
}
|
|
19
|
-
const [cartState, cartSend] = useCartAPIStateMachine({
|
|
20
|
-
numCartLines,
|
|
21
|
-
data: cart,
|
|
22
|
-
cartFragment,
|
|
23
|
-
countryCode,
|
|
24
|
-
onCartActionEntry(context, event) {
|
|
25
|
-
try {
|
|
26
|
-
switch (event.type) {
|
|
27
|
-
case 'CART_CREATE':
|
|
28
|
-
return onCreate?.();
|
|
29
|
-
case 'CARTLINE_ADD':
|
|
30
|
-
return onLineAdd?.();
|
|
31
|
-
case 'CARTLINE_REMOVE':
|
|
32
|
-
return onLineRemove?.();
|
|
33
|
-
case 'CARTLINE_UPDATE':
|
|
34
|
-
return onLineUpdate?.();
|
|
35
|
-
case 'NOTE_UPDATE':
|
|
36
|
-
return onNoteUpdate?.();
|
|
37
|
-
case 'BUYER_IDENTITY_UPDATE':
|
|
38
|
-
return onBuyerIdentityUpdate?.();
|
|
39
|
-
case 'CART_ATTRIBUTES_UPDATE':
|
|
40
|
-
return onAttributesUpdate?.();
|
|
41
|
-
case 'DISCOUNT_CODES_UPDATE':
|
|
42
|
-
return onDiscountCodesUpdate?.();
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
catch (error) {
|
|
46
|
-
console.error('Cart entry action failed', error);
|
|
47
|
-
}
|
|
48
|
-
},
|
|
49
|
-
onCartActionOptimisticUI(context, event) {
|
|
50
|
-
if (!context?.cart)
|
|
51
|
-
return { cart: undefined };
|
|
52
|
-
switch (event.type) {
|
|
53
|
-
case 'CARTLINE_REMOVE':
|
|
54
|
-
return {
|
|
55
|
-
...context,
|
|
56
|
-
lastValidCart: context.cart,
|
|
57
|
-
cart: {
|
|
58
|
-
...context.cart,
|
|
59
|
-
lines: context?.cart?.lines.filter(({ id }) => !event.payload.lines.includes(id)),
|
|
60
|
-
},
|
|
61
|
-
};
|
|
62
|
-
case 'CARTLINE_UPDATE':
|
|
63
|
-
return {
|
|
64
|
-
...context,
|
|
65
|
-
lastValidCart: context.cart,
|
|
66
|
-
cart: {
|
|
67
|
-
...context.cart,
|
|
68
|
-
lines: context.cart.lines.map((line) => {
|
|
69
|
-
const updatedLine = event.payload.lines.find(({ id }) => id === line.id);
|
|
70
|
-
if (updatedLine && updatedLine.quantity) {
|
|
71
|
-
return {
|
|
72
|
-
...line,
|
|
73
|
-
quantity: updatedLine.quantity,
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
return line;
|
|
77
|
-
}),
|
|
78
|
-
},
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
return { cart: context.cart ? { ...context.cart } : undefined };
|
|
82
|
-
},
|
|
83
|
-
onCartActionComplete(context, event) {
|
|
84
|
-
const cartActionEvent = event.payload.cartActionEvent;
|
|
85
|
-
try {
|
|
86
|
-
switch (event.type) {
|
|
87
|
-
case 'RESOLVE':
|
|
88
|
-
switch (cartActionEvent.type) {
|
|
89
|
-
case 'CART_CREATE':
|
|
90
|
-
publishCreateAnalytics(context, cartActionEvent);
|
|
91
|
-
return onCreateComplete?.();
|
|
92
|
-
case 'CARTLINE_ADD':
|
|
93
|
-
publishLineAddAnalytics(context, cartActionEvent);
|
|
94
|
-
return onLineAddComplete?.();
|
|
95
|
-
case 'CARTLINE_REMOVE':
|
|
96
|
-
publishLineRemoveAnalytics(context, cartActionEvent);
|
|
97
|
-
return onLineRemoveComplete?.();
|
|
98
|
-
case 'CARTLINE_UPDATE':
|
|
99
|
-
publishLineUpdateAnalytics(context, cartActionEvent);
|
|
100
|
-
return onLineUpdateComplete?.();
|
|
101
|
-
case 'NOTE_UPDATE':
|
|
102
|
-
return onNoteUpdateComplete?.();
|
|
103
|
-
case 'BUYER_IDENTITY_UPDATE':
|
|
104
|
-
if (countryCodeNotUpdated(context, cartActionEvent)) {
|
|
105
|
-
customerOverridesCountryCode.current = true;
|
|
106
|
-
}
|
|
107
|
-
return onBuyerIdentityUpdateComplete?.();
|
|
108
|
-
case 'CART_ATTRIBUTES_UPDATE':
|
|
109
|
-
return onAttributesUpdateComplete?.();
|
|
110
|
-
case 'DISCOUNT_CODES_UPDATE':
|
|
111
|
-
publishDiscountCodesUpdateAnalytics(context, cartActionEvent);
|
|
112
|
-
return onDiscountCodesUpdateComplete?.();
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
catch (error) {
|
|
117
|
-
console.error('onCartActionComplete failed', error);
|
|
118
|
-
}
|
|
119
|
-
},
|
|
120
|
-
});
|
|
121
|
-
const cartReady = useRef(false);
|
|
122
|
-
const cartCompleted = cartState.matches('cartCompleted');
|
|
123
|
-
const countryChanged = (cartState.value === 'idle' ||
|
|
124
|
-
cartState.value === 'error' ||
|
|
125
|
-
cartState.value === 'cartCompleted') &&
|
|
126
|
-
countryCode !== cartState?.context?.cart?.buyerIdentity?.countryCode &&
|
|
127
|
-
!cartState.context.errors;
|
|
128
|
-
/**
|
|
129
|
-
* Initializes cart with priority in this order:
|
|
130
|
-
* 1. cart props
|
|
131
|
-
* 2. localStorage cartId
|
|
132
|
-
*/
|
|
133
|
-
useEffect(() => {
|
|
134
|
-
if (!cartReady.current) {
|
|
135
|
-
if (!cart && storageAvailable('localStorage')) {
|
|
136
|
-
try {
|
|
137
|
-
const cartId = window.localStorage.getItem(CART_ID_STORAGE_KEY);
|
|
138
|
-
if (cartId) {
|
|
139
|
-
cartSend({ type: 'CART_FETCH', payload: { cartId } });
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
catch (error) {
|
|
143
|
-
console.warn('error fetching cartId');
|
|
144
|
-
console.warn(error);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
cartReady.current = true;
|
|
148
|
-
}
|
|
149
|
-
}, [cart, cartReady, cartSend]);
|
|
150
|
-
// Update cart country code if cart and props countryCode's as different
|
|
151
|
-
useEffect(() => {
|
|
152
|
-
if (!countryChanged || customerOverridesCountryCode.current)
|
|
153
|
-
return;
|
|
154
|
-
cartSend({
|
|
155
|
-
type: 'BUYER_IDENTITY_UPDATE',
|
|
156
|
-
payload: { buyerIdentity: { countryCode, customerAccessToken } },
|
|
157
|
-
});
|
|
158
|
-
}, [
|
|
159
|
-
countryCode,
|
|
160
|
-
customerAccessToken,
|
|
161
|
-
countryChanged,
|
|
162
|
-
customerOverridesCountryCode,
|
|
163
|
-
cartSend,
|
|
164
|
-
]);
|
|
165
|
-
// send cart events when ready
|
|
166
|
-
const onCartReadySend = useCallback((cartEvent) => {
|
|
167
|
-
if (!cartReady.current) {
|
|
168
|
-
return console.warn("Cart isn't ready yet");
|
|
169
|
-
}
|
|
170
|
-
cartSend(cartEvent);
|
|
171
|
-
}, [cartSend]);
|
|
172
|
-
// save cart id to local storage
|
|
173
|
-
useEffect(() => {
|
|
174
|
-
if (cartState?.context?.cart?.id && storageAvailable('localStorage')) {
|
|
175
|
-
try {
|
|
176
|
-
window.localStorage.setItem(CART_ID_STORAGE_KEY, cartState.context.cart?.id);
|
|
177
|
-
}
|
|
178
|
-
catch (error) {
|
|
179
|
-
console.warn('Failed to save cartId to localStorage', error);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
}, [cartState?.context?.cart?.id]);
|
|
183
|
-
// delete cart from local storage if cart fetched has been completed
|
|
184
|
-
useEffect(() => {
|
|
185
|
-
if (cartCompleted && storageAvailable('localStorage')) {
|
|
186
|
-
try {
|
|
187
|
-
window.localStorage.removeItem(CART_ID_STORAGE_KEY);
|
|
188
|
-
}
|
|
189
|
-
catch (error) {
|
|
190
|
-
console.warn('Failed to delete cartId from localStorage', error);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
}, [cartCompleted]);
|
|
194
|
-
const cartCreate = useCallback((cartInput) => {
|
|
195
|
-
if (countryCode && !cartInput.buyerIdentity?.countryCode) {
|
|
196
|
-
if (cartInput.buyerIdentity == null) {
|
|
197
|
-
cartInput.buyerIdentity = {};
|
|
198
|
-
}
|
|
199
|
-
cartInput.buyerIdentity.countryCode = countryCode;
|
|
200
|
-
}
|
|
201
|
-
if (customerAccessToken &&
|
|
202
|
-
!cartInput.buyerIdentity?.customerAccessToken) {
|
|
203
|
-
if (cartInput.buyerIdentity == null) {
|
|
204
|
-
cartInput.buyerIdentity = {};
|
|
205
|
-
}
|
|
206
|
-
cartInput.buyerIdentity.customerAccessToken = customerAccessToken;
|
|
207
|
-
}
|
|
208
|
-
onCartReadySend({
|
|
209
|
-
type: 'CART_CREATE',
|
|
210
|
-
payload: cartInput,
|
|
211
|
-
});
|
|
212
|
-
}, [countryCode, customerAccessToken, onCartReadySend]);
|
|
213
|
-
const cartContextValue = useMemo(() => {
|
|
214
|
-
return {
|
|
215
|
-
...(cartState?.context?.cart ?? { lines: [], attributes: [] }),
|
|
216
|
-
status: transposeStatus(cartState.value),
|
|
217
|
-
error: cartState?.context?.errors,
|
|
218
|
-
totalQuantity: cartState?.context?.cart?.totalQuantity ?? 0,
|
|
219
|
-
cartCreate,
|
|
220
|
-
linesAdd(lines) {
|
|
221
|
-
if (cartState?.context?.cart?.id) {
|
|
222
|
-
onCartReadySend({
|
|
223
|
-
type: 'CARTLINE_ADD',
|
|
224
|
-
payload: { lines },
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
else {
|
|
228
|
-
cartCreate({ lines });
|
|
229
|
-
}
|
|
230
|
-
},
|
|
231
|
-
linesRemove(lines) {
|
|
232
|
-
onCartReadySend({
|
|
233
|
-
type: 'CARTLINE_REMOVE',
|
|
234
|
-
payload: {
|
|
235
|
-
lines,
|
|
236
|
-
},
|
|
237
|
-
});
|
|
238
|
-
},
|
|
239
|
-
linesUpdate(lines) {
|
|
240
|
-
onCartReadySend({
|
|
241
|
-
type: 'CARTLINE_UPDATE',
|
|
242
|
-
payload: {
|
|
243
|
-
lines,
|
|
244
|
-
},
|
|
245
|
-
});
|
|
246
|
-
},
|
|
247
|
-
noteUpdate(note) {
|
|
248
|
-
onCartReadySend({
|
|
249
|
-
type: 'NOTE_UPDATE',
|
|
250
|
-
payload: {
|
|
251
|
-
note,
|
|
252
|
-
},
|
|
253
|
-
});
|
|
254
|
-
},
|
|
255
|
-
buyerIdentityUpdate(buyerIdentity) {
|
|
256
|
-
onCartReadySend({
|
|
257
|
-
type: 'BUYER_IDENTITY_UPDATE',
|
|
258
|
-
payload: {
|
|
259
|
-
buyerIdentity,
|
|
260
|
-
},
|
|
261
|
-
});
|
|
262
|
-
},
|
|
263
|
-
cartAttributesUpdate(attributes) {
|
|
264
|
-
onCartReadySend({
|
|
265
|
-
type: 'CART_ATTRIBUTES_UPDATE',
|
|
266
|
-
payload: {
|
|
267
|
-
attributes,
|
|
268
|
-
},
|
|
269
|
-
});
|
|
270
|
-
},
|
|
271
|
-
discountCodesUpdate(discountCodes) {
|
|
272
|
-
onCartReadySend({
|
|
273
|
-
type: 'DISCOUNT_CODES_UPDATE',
|
|
274
|
-
payload: {
|
|
275
|
-
discountCodes,
|
|
276
|
-
},
|
|
277
|
-
});
|
|
278
|
-
},
|
|
279
|
-
cartFragment,
|
|
280
|
-
};
|
|
281
|
-
}, [
|
|
282
|
-
cartCreate,
|
|
283
|
-
cartFragment,
|
|
284
|
-
cartState?.context?.cart,
|
|
285
|
-
cartState?.context?.errors,
|
|
286
|
-
cartState.value,
|
|
287
|
-
onCartReadySend,
|
|
288
|
-
]);
|
|
289
|
-
return (React.createElement(CartContext.Provider, { value: cartContextValue }, children));
|
|
290
|
-
}
|
|
291
|
-
function transposeStatus(status) {
|
|
292
|
-
switch (status) {
|
|
293
|
-
case 'uninitialized':
|
|
294
|
-
case 'initializationError':
|
|
295
|
-
return 'uninitialized';
|
|
296
|
-
case 'idle':
|
|
297
|
-
case 'cartCompleted':
|
|
298
|
-
case 'error':
|
|
299
|
-
return 'idle';
|
|
300
|
-
case 'cartFetching':
|
|
301
|
-
return 'fetching';
|
|
302
|
-
case 'cartCreating':
|
|
303
|
-
return 'creating';
|
|
304
|
-
case 'cartLineAdding':
|
|
305
|
-
case 'cartLineRemoving':
|
|
306
|
-
case 'cartLineUpdating':
|
|
307
|
-
case 'noteUpdating':
|
|
308
|
-
case 'buyerIdentityUpdating':
|
|
309
|
-
case 'cartAttributesUpdating':
|
|
310
|
-
case 'discountCodesUpdating':
|
|
311
|
-
return 'updating';
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
/** Check for storage availability funciton obtained from
|
|
315
|
-
* https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API
|
|
316
|
-
*/
|
|
317
|
-
function storageAvailable(type) {
|
|
318
|
-
let storage;
|
|
319
|
-
try {
|
|
320
|
-
storage = window[type];
|
|
321
|
-
const x = '__storage_test__';
|
|
322
|
-
storage.setItem(x, x);
|
|
323
|
-
storage.removeItem(x);
|
|
324
|
-
return true;
|
|
325
|
-
}
|
|
326
|
-
catch (e) {
|
|
327
|
-
return (e instanceof DOMException &&
|
|
328
|
-
// everything except Firefox
|
|
329
|
-
(e.code === 22 ||
|
|
330
|
-
// Firefox
|
|
331
|
-
e.code === 1014 ||
|
|
332
|
-
// test name field too, because code might not be present
|
|
333
|
-
// everything except Firefox
|
|
334
|
-
e.name === 'QuotaExceededError' ||
|
|
335
|
-
// Firefox
|
|
336
|
-
e.name === 'NS_ERROR_DOM_QUOTA_REACHED') &&
|
|
337
|
-
// acknowledge QuotaExceededError only if there's something already stored
|
|
338
|
-
storage &&
|
|
339
|
-
storage.length !== 0);
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
function countryCodeNotUpdated(context, event) {
|
|
343
|
-
return (event.payload.buyerIdentity.countryCode &&
|
|
344
|
-
context.cart?.buyerIdentity?.countryCode !==
|
|
345
|
-
event.payload.buyerIdentity.countryCode);
|
|
346
|
-
}
|
|
347
|
-
// Cart Analytics
|
|
348
|
-
function publishCreateAnalytics(context, event) {
|
|
349
|
-
ClientAnalytics.publish(ClientAnalytics.eventNames.ADD_TO_CART, true, {
|
|
350
|
-
addedCartLines: event.payload.lines,
|
|
351
|
-
cart: context.rawCartResult,
|
|
352
|
-
prevCart: null,
|
|
353
|
-
});
|
|
354
|
-
}
|
|
355
|
-
function publishLineAddAnalytics(context, event) {
|
|
356
|
-
ClientAnalytics.publish(ClientAnalytics.eventNames.ADD_TO_CART, true, {
|
|
357
|
-
addedCartLines: event.payload.lines,
|
|
358
|
-
cart: context.rawCartResult,
|
|
359
|
-
prevCart: context.prevCart,
|
|
360
|
-
});
|
|
361
|
-
}
|
|
362
|
-
function publishLineUpdateAnalytics(context, event) {
|
|
363
|
-
ClientAnalytics.publish(ClientAnalytics.eventNames.UPDATE_CART, true, {
|
|
364
|
-
updatedCartLines: event.payload.lines,
|
|
365
|
-
oldCart: context.prevCart,
|
|
366
|
-
cart: context.rawCartResult,
|
|
367
|
-
prevCart: context.prevCart,
|
|
368
|
-
});
|
|
369
|
-
}
|
|
370
|
-
function publishLineRemoveAnalytics(context, event) {
|
|
371
|
-
ClientAnalytics.publish(ClientAnalytics.eventNames.REMOVE_FROM_CART, true, {
|
|
372
|
-
removedCartLines: event.payload.lines,
|
|
373
|
-
cart: context.rawCartResult,
|
|
374
|
-
prevCart: context.prevCart,
|
|
375
|
-
});
|
|
376
|
-
}
|
|
377
|
-
function publishDiscountCodesUpdateAnalytics(context, event) {
|
|
378
|
-
ClientAnalytics.publish(ClientAnalytics.eventNames.DISCOUNT_CODE_UPDATED, true, {
|
|
379
|
-
updatedDiscountCodes: event.payload.discountCodes,
|
|
380
|
-
cart: context.rawCartResult,
|
|
381
|
-
prevCart: context.prevCart,
|
|
382
|
-
});
|
|
383
|
-
}
|
|
384
|
-
export const defaultCartFragment = `
|
|
385
|
-
fragment CartFragment on Cart {
|
|
386
|
-
id
|
|
387
|
-
checkoutUrl
|
|
388
|
-
totalQuantity
|
|
389
|
-
buyerIdentity {
|
|
390
|
-
countryCode
|
|
391
|
-
customer {
|
|
392
|
-
id
|
|
393
|
-
email
|
|
394
|
-
firstName
|
|
395
|
-
lastName
|
|
396
|
-
displayName
|
|
397
|
-
}
|
|
398
|
-
email
|
|
399
|
-
phone
|
|
400
|
-
}
|
|
401
|
-
lines(first: $numCartLines) {
|
|
402
|
-
edges {
|
|
403
|
-
node {
|
|
404
|
-
id
|
|
405
|
-
quantity
|
|
406
|
-
attributes {
|
|
407
|
-
key
|
|
408
|
-
value
|
|
409
|
-
}
|
|
410
|
-
cost {
|
|
411
|
-
totalAmount {
|
|
412
|
-
amount
|
|
413
|
-
currencyCode
|
|
414
|
-
}
|
|
415
|
-
compareAtAmountPerQuantity {
|
|
416
|
-
amount
|
|
417
|
-
currencyCode
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
merchandise {
|
|
421
|
-
... on ProductVariant {
|
|
422
|
-
id
|
|
423
|
-
availableForSale
|
|
424
|
-
compareAtPriceV2 {
|
|
425
|
-
...MoneyFragment
|
|
426
|
-
}
|
|
427
|
-
priceV2 {
|
|
428
|
-
...MoneyFragment
|
|
429
|
-
}
|
|
430
|
-
requiresShipping
|
|
431
|
-
title
|
|
432
|
-
image {
|
|
433
|
-
...ImageFragment
|
|
434
|
-
}
|
|
435
|
-
product {
|
|
436
|
-
handle
|
|
437
|
-
title
|
|
438
|
-
}
|
|
439
|
-
selectedOptions {
|
|
440
|
-
name
|
|
441
|
-
value
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
cost {
|
|
449
|
-
subtotalAmount {
|
|
450
|
-
...MoneyFragment
|
|
451
|
-
}
|
|
452
|
-
totalAmount {
|
|
453
|
-
...MoneyFragment
|
|
454
|
-
}
|
|
455
|
-
totalDutyAmount {
|
|
456
|
-
...MoneyFragment
|
|
457
|
-
}
|
|
458
|
-
totalTaxAmount {
|
|
459
|
-
...MoneyFragment
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
note
|
|
463
|
-
attributes {
|
|
464
|
-
key
|
|
465
|
-
value
|
|
466
|
-
}
|
|
467
|
-
discountCodes {
|
|
468
|
-
code
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
fragment MoneyFragment on MoneyV2 {
|
|
473
|
-
currencyCode
|
|
474
|
-
amount
|
|
475
|
-
}
|
|
476
|
-
fragment ImageFragment on Image {
|
|
477
|
-
id
|
|
478
|
-
url
|
|
479
|
-
altText
|
|
480
|
-
width
|
|
481
|
-
height
|
|
482
|
-
}
|
|
483
|
-
`;
|