@shopify/hydrogen 1.4.1 → 1.4.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/dist/esnext/components/CartProvider/CartActions.client.d.ts +1 -2
- package/dist/esnext/components/CartProvider/CartActions.client.js +1 -101
- package/dist/esnext/components/CartProvider/CartProvider.client.js +24 -2
- package/dist/esnext/components/CartProvider/CartProviderV2.client.d.ts +2 -1
- package/dist/esnext/components/CartProvider/CartProviderV2.client.js +186 -73
- package/dist/esnext/components/CartProvider/types.d.ts +7 -1
- package/dist/esnext/components/CartProvider/useCartAPIStateMachine.client.d.ts +3 -4
- package/dist/esnext/components/CartProvider/useCartAPIStateMachine.client.js +47 -32
- package/dist/esnext/entry-server.js +12 -9
- package/dist/esnext/foundation/Analytics/connectors/Shopify/ShopifyAnalytics.client.js +4 -2
- package/dist/esnext/foundation/Analytics/connectors/Shopify/ShopifyAnalytics.server.js +2 -2
- package/dist/esnext/foundation/ShopifyProvider/ShopifyProvider.server.js +2 -1
- package/dist/esnext/index.d.ts +1 -1
- package/dist/esnext/utilities/apiRoutes.js +1 -1
- package/dist/esnext/utilities/log/log.d.ts +1 -1
- package/dist/esnext/utilities/log/log.js +2 -2
- package/dist/esnext/utilities/storefrontApi.js +3 -6
- package/dist/esnext/version.d.ts +1 -1
- package/dist/esnext/version.js +1 -1
- package/package.json +1 -1
|
@@ -17,7 +17,7 @@ export declare function useCartActions({ numCartLines, cartFragment, countryCode
|
|
|
17
17
|
/** Maximum number of cart lines to fetch. Defaults to 250 cart lines. */
|
|
18
18
|
numCartLines?: number;
|
|
19
19
|
/** A fragment used to query the Storefront API's [Cart object](https://shopify.dev/api/storefront/latest/objects/cart) for all queries and mutations. A default value is used if no argument is provided. */
|
|
20
|
-
cartFragment
|
|
20
|
+
cartFragment: string;
|
|
21
21
|
/** The ISO country code for i18n. */
|
|
22
22
|
countryCode?: CountryCode;
|
|
23
23
|
}): {
|
|
@@ -59,4 +59,3 @@ export declare function useCartActions({ numCartLines, cartFragment, countryCode
|
|
|
59
59
|
}>;
|
|
60
60
|
cartFragment: string;
|
|
61
61
|
};
|
|
62
|
-
export declare const defaultCartFragment = "\nfragment CartFragment on Cart {\n id\n checkoutUrl\n totalQuantity\n buyerIdentity {\n countryCode\n customer {\n id\n email\n firstName\n lastName\n displayName\n }\n email\n phone\n }\n lines(first: $numCartLines) {\n edges {\n node {\n id\n quantity\n attributes {\n key\n value\n }\n cost {\n totalAmount {\n amount\n currencyCode\n }\n compareAtAmountPerQuantity {\n amount\n currencyCode\n }\n }\n merchandise {\n ... on ProductVariant {\n id\n availableForSale\n compareAtPriceV2 {\n ...MoneyFragment\n }\n priceV2 {\n ...MoneyFragment\n }\n requiresShipping\n title\n image {\n ...ImageFragment\n }\n product {\n handle\n title\n }\n selectedOptions {\n name\n value\n }\n }\n }\n }\n }\n }\n cost {\n subtotalAmount {\n ...MoneyFragment\n }\n totalAmount {\n ...MoneyFragment\n }\n totalDutyAmount {\n ...MoneyFragment\n }\n totalTaxAmount {\n ...MoneyFragment\n }\n }\n note\n attributes {\n key\n value\n }\n discountCodes {\n code\n }\n}\n\nfragment MoneyFragment on MoneyV2 {\n currencyCode\n amount\n}\nfragment ImageFragment on Image {\n id\n url\n altText\n width\n height\n}\n";
|
|
@@ -7,7 +7,7 @@ import { useCartFetch } from './hooks.client.js';
|
|
|
7
7
|
*
|
|
8
8
|
* See [cart API graphql mutations](https://shopify.dev/api/storefront/2022-07/objects/Cart)
|
|
9
9
|
*/
|
|
10
|
-
export function useCartActions({ numCartLines, cartFragment
|
|
10
|
+
export function useCartActions({ numCartLines, cartFragment, countryCode = CountryCode.Us, }) {
|
|
11
11
|
const fetchCart = useCartFetch();
|
|
12
12
|
const cartFetch = useCallback((cartId) => {
|
|
13
13
|
return fetchCart({
|
|
@@ -130,103 +130,3 @@ export function useCartActions({ numCartLines, cartFragment = defaultCartFragmen
|
|
|
130
130
|
cartFragment,
|
|
131
131
|
]);
|
|
132
132
|
}
|
|
133
|
-
export const defaultCartFragment = `
|
|
134
|
-
fragment CartFragment on Cart {
|
|
135
|
-
id
|
|
136
|
-
checkoutUrl
|
|
137
|
-
totalQuantity
|
|
138
|
-
buyerIdentity {
|
|
139
|
-
countryCode
|
|
140
|
-
customer {
|
|
141
|
-
id
|
|
142
|
-
email
|
|
143
|
-
firstName
|
|
144
|
-
lastName
|
|
145
|
-
displayName
|
|
146
|
-
}
|
|
147
|
-
email
|
|
148
|
-
phone
|
|
149
|
-
}
|
|
150
|
-
lines(first: $numCartLines) {
|
|
151
|
-
edges {
|
|
152
|
-
node {
|
|
153
|
-
id
|
|
154
|
-
quantity
|
|
155
|
-
attributes {
|
|
156
|
-
key
|
|
157
|
-
value
|
|
158
|
-
}
|
|
159
|
-
cost {
|
|
160
|
-
totalAmount {
|
|
161
|
-
amount
|
|
162
|
-
currencyCode
|
|
163
|
-
}
|
|
164
|
-
compareAtAmountPerQuantity {
|
|
165
|
-
amount
|
|
166
|
-
currencyCode
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
merchandise {
|
|
170
|
-
... on ProductVariant {
|
|
171
|
-
id
|
|
172
|
-
availableForSale
|
|
173
|
-
compareAtPriceV2 {
|
|
174
|
-
...MoneyFragment
|
|
175
|
-
}
|
|
176
|
-
priceV2 {
|
|
177
|
-
...MoneyFragment
|
|
178
|
-
}
|
|
179
|
-
requiresShipping
|
|
180
|
-
title
|
|
181
|
-
image {
|
|
182
|
-
...ImageFragment
|
|
183
|
-
}
|
|
184
|
-
product {
|
|
185
|
-
handle
|
|
186
|
-
title
|
|
187
|
-
}
|
|
188
|
-
selectedOptions {
|
|
189
|
-
name
|
|
190
|
-
value
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
cost {
|
|
198
|
-
subtotalAmount {
|
|
199
|
-
...MoneyFragment
|
|
200
|
-
}
|
|
201
|
-
totalAmount {
|
|
202
|
-
...MoneyFragment
|
|
203
|
-
}
|
|
204
|
-
totalDutyAmount {
|
|
205
|
-
...MoneyFragment
|
|
206
|
-
}
|
|
207
|
-
totalTaxAmount {
|
|
208
|
-
...MoneyFragment
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
note
|
|
212
|
-
attributes {
|
|
213
|
-
key
|
|
214
|
-
value
|
|
215
|
-
}
|
|
216
|
-
discountCodes {
|
|
217
|
-
code
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
fragment MoneyFragment on MoneyV2 {
|
|
222
|
-
currencyCode
|
|
223
|
-
amount
|
|
224
|
-
}
|
|
225
|
-
fragment ImageFragment on Image {
|
|
226
|
-
id
|
|
227
|
-
url
|
|
228
|
-
altText
|
|
229
|
-
width
|
|
230
|
-
height
|
|
231
|
-
}
|
|
232
|
-
`;
|
|
@@ -6,6 +6,28 @@ import { useCartFetch } from './hooks.client.js';
|
|
|
6
6
|
import { CartContext } from './context.js';
|
|
7
7
|
import { CART_ID_STORAGE_KEY } from './constants.js';
|
|
8
8
|
import { ClientAnalytics } from '../../foundation/Analytics/ClientAnalytics.js';
|
|
9
|
+
function getLocalStoragePolyfill() {
|
|
10
|
+
const storage = {};
|
|
11
|
+
return {
|
|
12
|
+
removeItem(key) {
|
|
13
|
+
delete storage[key];
|
|
14
|
+
},
|
|
15
|
+
setItem(key, value) {
|
|
16
|
+
storage[key] = value;
|
|
17
|
+
},
|
|
18
|
+
getItem(key) {
|
|
19
|
+
return storage[key];
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
const localStorage = (function () {
|
|
24
|
+
try {
|
|
25
|
+
return window.localStorage || getLocalStoragePolyfill();
|
|
26
|
+
}
|
|
27
|
+
catch (e) {
|
|
28
|
+
return getLocalStoragePolyfill();
|
|
29
|
+
}
|
|
30
|
+
})();
|
|
9
31
|
function cartReducer(state, action) {
|
|
10
32
|
switch (action.type) {
|
|
11
33
|
case 'cartFetch': {
|
|
@@ -179,7 +201,7 @@ export function CartProvider({ children, numCartLines, onCreate, onLineAdd, onLi
|
|
|
179
201
|
},
|
|
180
202
|
});
|
|
181
203
|
if (!data?.cart) {
|
|
182
|
-
|
|
204
|
+
localStorage.removeItem(CART_ID_STORAGE_KEY);
|
|
183
205
|
dispatch({ type: 'resetCart' });
|
|
184
206
|
return;
|
|
185
207
|
}
|
|
@@ -226,7 +248,7 @@ export function CartProvider({ children, numCartLines, onCreate, onLineAdd, onLi
|
|
|
226
248
|
type: 'resolve',
|
|
227
249
|
cart: cartFromGraphQL(data.cartCreate.cart),
|
|
228
250
|
});
|
|
229
|
-
|
|
251
|
+
localStorage.setItem(CART_ID_STORAGE_KEY, data.cartCreate.cart.id);
|
|
230
252
|
}
|
|
231
253
|
}, [
|
|
232
254
|
onCreate,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { CartFragmentFragment } from './graphql/CartFragment.js';
|
|
3
3
|
import { CartBuyerIdentityInput, CountryCode } from '../../storefront-api-types.js';
|
|
4
|
-
export declare function CartProviderV2({ children, numCartLines, onCreate, onLineAdd, onLineRemove, onLineUpdate, onNoteUpdate, onBuyerIdentityUpdate, onAttributesUpdate, onDiscountCodesUpdate, onCreateComplete, onLineAddComplete, onLineRemoveComplete, onLineUpdateComplete, onNoteUpdateComplete, onBuyerIdentityUpdateComplete, onAttributesUpdateComplete, onDiscountCodesUpdateComplete, data, cartFragment, customerAccessToken, countryCode, }: {
|
|
4
|
+
export declare function CartProviderV2({ children, numCartLines, onCreate, onLineAdd, onLineRemove, onLineUpdate, onNoteUpdate, onBuyerIdentityUpdate, onAttributesUpdate, onDiscountCodesUpdate, onCreateComplete, onLineAddComplete, onLineRemoveComplete, onLineUpdateComplete, onNoteUpdateComplete, onBuyerIdentityUpdateComplete, onAttributesUpdateComplete, onDiscountCodesUpdateComplete, data: cart, cartFragment, customerAccessToken, countryCode, }: {
|
|
5
5
|
/** Any `ReactNode` elements. */
|
|
6
6
|
children: React.ReactNode;
|
|
7
7
|
/** Maximum number of cart lines to fetch. Defaults to 250 cart lines. */
|
|
@@ -47,3 +47,4 @@ export declare function CartProviderV2({ children, numCartLines, onCreate, onLin
|
|
|
47
47
|
/** The ISO country code for i18n. */
|
|
48
48
|
countryCode?: CountryCode;
|
|
49
49
|
}): JSX.Element;
|
|
50
|
+
export declare const defaultCartFragment = "\nfragment CartFragment on Cart {\n id\n checkoutUrl\n totalQuantity\n buyerIdentity {\n countryCode\n customer {\n id\n email\n firstName\n lastName\n displayName\n }\n email\n phone\n }\n lines(first: $numCartLines) {\n edges {\n node {\n id\n quantity\n attributes {\n key\n value\n }\n cost {\n totalAmount {\n amount\n currencyCode\n }\n compareAtAmountPerQuantity {\n amount\n currencyCode\n }\n }\n merchandise {\n ... on ProductVariant {\n id\n availableForSale\n compareAtPriceV2 {\n ...MoneyFragment\n }\n priceV2 {\n ...MoneyFragment\n }\n requiresShipping\n title\n image {\n ...ImageFragment\n }\n product {\n handle\n title\n }\n selectedOptions {\n name\n value\n }\n }\n }\n }\n }\n }\n cost {\n subtotalAmount {\n ...MoneyFragment\n }\n totalAmount {\n ...MoneyFragment\n }\n totalDutyAmount {\n ...MoneyFragment\n }\n totalTaxAmount {\n ...MoneyFragment\n }\n }\n note\n attributes {\n key\n value\n }\n discountCodes {\n code\n }\n}\n\nfragment MoneyFragment on MoneyV2 {\n currencyCode\n amount\n}\nfragment ImageFragment on Image {\n id\n url\n altText\n width\n height\n}\n";
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
2
2
|
import { CountryCode, } from '../../storefront-api-types.js';
|
|
3
3
|
import { CartContext } from './context.js';
|
|
4
|
-
import { useCartActions } from './CartActions.client.js';
|
|
5
4
|
import { useCartAPIStateMachine } from './useCartAPIStateMachine.client.js';
|
|
6
5
|
import { CART_ID_STORAGE_KEY } from './constants.js';
|
|
7
6
|
import { ClientAnalytics } from '../../foundation/Analytics/ClientAnalytics.js';
|
|
8
|
-
export function CartProviderV2({ children, numCartLines, onCreate, onLineAdd, onLineRemove, onLineUpdate, onNoteUpdate, onBuyerIdentityUpdate, onAttributesUpdate, onDiscountCodesUpdate, onCreateComplete, onLineAddComplete, onLineRemoveComplete, onLineUpdateComplete, onNoteUpdateComplete, onBuyerIdentityUpdateComplete, onAttributesUpdateComplete, onDiscountCodesUpdateComplete, data: cart, cartFragment, customerAccessToken, countryCode = CountryCode.Us, }) {
|
|
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, }) {
|
|
9
8
|
if (countryCode)
|
|
10
9
|
countryCode = countryCode.toUpperCase();
|
|
11
10
|
const [prevCountryCode, setPrevCountryCode] = useState(countryCode);
|
|
@@ -17,32 +16,34 @@ export function CartProviderV2({ children, numCartLines, onCreate, onLineAdd, on
|
|
|
17
16
|
setPrevCustomerAccessToken(customerAccessToken);
|
|
18
17
|
customerOverridesCountryCode.current = false;
|
|
19
18
|
}
|
|
20
|
-
const { cartFragment: usedCartFragment } = useCartActions({
|
|
21
|
-
numCartLines,
|
|
22
|
-
cartFragment,
|
|
23
|
-
countryCode,
|
|
24
|
-
});
|
|
25
19
|
const [cartState, cartSend] = useCartAPIStateMachine({
|
|
26
20
|
numCartLines,
|
|
21
|
+
data: cart,
|
|
27
22
|
cartFragment,
|
|
23
|
+
countryCode,
|
|
28
24
|
onCartActionEntry(context, event) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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);
|
|
46
47
|
}
|
|
47
48
|
},
|
|
48
49
|
onCartActionOptimisticUI(context, event) {
|
|
@@ -81,44 +82,72 @@ export function CartProviderV2({ children, numCartLines, onCreate, onLineAdd, on
|
|
|
81
82
|
},
|
|
82
83
|
onCartActionComplete(context, event) {
|
|
83
84
|
const cartActionEvent = event.payload.cartActionEvent;
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
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);
|
|
112
118
|
}
|
|
113
119
|
},
|
|
114
120
|
});
|
|
115
|
-
const
|
|
121
|
+
const cartReady = useRef(false);
|
|
116
122
|
const cartCompleted = cartState.matches('cartCompleted');
|
|
117
123
|
const countryChanged = (cartState.value === 'idle' ||
|
|
118
124
|
cartState.value === 'error' ||
|
|
119
125
|
cartState.value === 'cartCompleted') &&
|
|
120
126
|
countryCode !== cartState?.context?.cart?.buyerIdentity?.countryCode &&
|
|
121
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
|
|
122
151
|
useEffect(() => {
|
|
123
152
|
if (!countryChanged || customerOverridesCountryCode.current)
|
|
124
153
|
return;
|
|
@@ -135,11 +164,11 @@ export function CartProviderV2({ children, numCartLines, onCreate, onLineAdd, on
|
|
|
135
164
|
]);
|
|
136
165
|
// send cart events when ready
|
|
137
166
|
const onCartReadySend = useCallback((cartEvent) => {
|
|
138
|
-
if (!cartReady) {
|
|
167
|
+
if (!cartReady.current) {
|
|
139
168
|
return console.warn("Cart isn't ready yet");
|
|
140
169
|
}
|
|
141
170
|
cartSend(cartEvent);
|
|
142
|
-
}, [
|
|
171
|
+
}, [cartSend]);
|
|
143
172
|
// save cart id to local storage
|
|
144
173
|
useEffect(() => {
|
|
145
174
|
if (cartState?.context?.cart?.id && storageAvailable('localStorage')) {
|
|
@@ -162,22 +191,6 @@ export function CartProviderV2({ children, numCartLines, onCreate, onLineAdd, on
|
|
|
162
191
|
}
|
|
163
192
|
}
|
|
164
193
|
}, [cartCompleted]);
|
|
165
|
-
// fetch cart from local storage if cart id present and set cart as ready for use
|
|
166
|
-
useEffect(() => {
|
|
167
|
-
if (!cartReady && storageAvailable('localStorage')) {
|
|
168
|
-
try {
|
|
169
|
-
const cartId = window.localStorage.getItem(CART_ID_STORAGE_KEY);
|
|
170
|
-
if (cartId) {
|
|
171
|
-
cartSend({ type: 'CART_FETCH', payload: { cartId } });
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
catch (error) {
|
|
175
|
-
console.warn('error fetching cartId');
|
|
176
|
-
console.warn(error);
|
|
177
|
-
}
|
|
178
|
-
setCartReady(true);
|
|
179
|
-
}
|
|
180
|
-
}, [cartReady, cartSend]);
|
|
181
194
|
const cartCreate = useCallback((cartInput) => {
|
|
182
195
|
if (countryCode && !cartInput.buyerIdentity?.countryCode) {
|
|
183
196
|
if (cartInput.buyerIdentity == null) {
|
|
@@ -263,15 +276,15 @@ export function CartProviderV2({ children, numCartLines, onCreate, onLineAdd, on
|
|
|
263
276
|
},
|
|
264
277
|
});
|
|
265
278
|
},
|
|
266
|
-
cartFragment
|
|
279
|
+
cartFragment,
|
|
267
280
|
};
|
|
268
281
|
}, [
|
|
269
282
|
cartCreate,
|
|
283
|
+
cartFragment,
|
|
270
284
|
cartState?.context?.cart,
|
|
271
285
|
cartState?.context?.errors,
|
|
272
286
|
cartState.value,
|
|
273
287
|
onCartReadySend,
|
|
274
|
-
usedCartFragment,
|
|
275
288
|
]);
|
|
276
289
|
return (React.createElement(CartContext.Provider, { value: cartContextValue }, children));
|
|
277
290
|
}
|
|
@@ -368,3 +381,103 @@ function publishDiscountCodesUpdateAnalytics(context, event) {
|
|
|
368
381
|
prevCart: context.prevCart,
|
|
369
382
|
});
|
|
370
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
|
+
`;
|
|
@@ -121,6 +121,12 @@ export declare type CartCreateEvent = {
|
|
|
121
121
|
type: 'CART_CREATE';
|
|
122
122
|
payload: CartInput;
|
|
123
123
|
};
|
|
124
|
+
export declare type CartSetEvent = {
|
|
125
|
+
type: 'CART_SET';
|
|
126
|
+
payload: {
|
|
127
|
+
cart: CartFragmentFragment;
|
|
128
|
+
};
|
|
129
|
+
};
|
|
124
130
|
export declare type CartLineAddEvent = {
|
|
125
131
|
type: 'CARTLINE_ADD';
|
|
126
132
|
payload: {
|
|
@@ -163,7 +169,7 @@ export declare type DiscountCodesUpdateEvent = {
|
|
|
163
169
|
discountCodes: string[];
|
|
164
170
|
};
|
|
165
171
|
};
|
|
166
|
-
export declare type CartMachineActionEvent = CartFetchEvent | CartCreateEvent | CartLineAddEvent | CartLineRemoveEvent | CartLineUpdateEvent | NoteUpdateEvent | BuyerIdentityUpdateEvent | CartAttributesUpdateEvent | DiscountCodesUpdateEvent;
|
|
172
|
+
export declare type CartMachineActionEvent = CartFetchEvent | CartCreateEvent | CartSetEvent | CartLineAddEvent | CartLineRemoveEvent | CartLineUpdateEvent | NoteUpdateEvent | BuyerIdentityUpdateEvent | CartAttributesUpdateEvent | DiscountCodesUpdateEvent;
|
|
167
173
|
export declare type CartMachineFetchResultEvent = {
|
|
168
174
|
type: 'CART_COMPLETED';
|
|
169
175
|
payload: {
|
|
@@ -2,7 +2,7 @@ import { StateMachine } from '@xstate/fsm';
|
|
|
2
2
|
import { CartFragmentFragment } from './graphql/CartFragment.js';
|
|
3
3
|
import { Cart, CartMachineActionEvent, CartMachineContext, CartMachineEvent, CartMachineFetchResultEvent, CartMachineTypeState } from './types.js';
|
|
4
4
|
import { CountryCode } from '../../storefront-api-types.js';
|
|
5
|
-
export declare function useCartAPIStateMachine({ numCartLines, onCartActionEntry, onCartActionOptimisticUI, onCartActionComplete, data, cartFragment, countryCode, }: {
|
|
5
|
+
export declare function useCartAPIStateMachine({ numCartLines, onCartActionEntry, onCartActionOptimisticUI, onCartActionComplete, data: cart, cartFragment, countryCode, }: {
|
|
6
6
|
/** Maximum number of cart lines to fetch. Defaults to 250 cart lines. */
|
|
7
7
|
numCartLines?: number;
|
|
8
8
|
/** A callback that is invoked just before a Cart API action executes. */
|
|
@@ -11,12 +11,11 @@ export declare function useCartAPIStateMachine({ numCartLines, onCartActionEntry
|
|
|
11
11
|
onCartActionOptimisticUI?: (context: CartMachineContext, event: CartMachineEvent) => Partial<CartMachineContext>;
|
|
12
12
|
/** A callback that is invoked after a Cart API completes. */
|
|
13
13
|
onCartActionComplete?: (context: CartMachineContext, event: CartMachineFetchResultEvent) => void;
|
|
14
|
-
/** A callback that is invoked after a Cart API completes. */
|
|
15
14
|
/** An object with fields that correspond to the Storefront API's [Cart object](https://shopify.dev/api/storefront/latest/objects/cart). */
|
|
16
15
|
data?: CartFragmentFragment;
|
|
17
16
|
/** A fragment used to query the Storefront API's [Cart object](https://shopify.dev/api/storefront/latest/objects/cart) for all queries and mutations. A default value is used if no argument is provided. */
|
|
18
|
-
cartFragment
|
|
17
|
+
cartFragment: string;
|
|
19
18
|
/** The ISO country code for i18n. */
|
|
20
19
|
countryCode?: CountryCode;
|
|
21
|
-
}): readonly [StateMachine.State<CartMachineContext, CartMachineEvent, CartMachineTypeState>, (event: "CART_FETCH" | "CART_CREATE" | "CARTLINE_ADD" | "CARTLINE_REMOVE" | "CARTLINE_UPDATE" | "NOTE_UPDATE" | "BUYER_IDENTITY_UPDATE" | "CART_ATTRIBUTES_UPDATE" | "DISCOUNT_CODES_UPDATE" | "CART_COMPLETED" | "RESOLVE" | "ERROR" | CartMachineEvent) => void, StateMachine.Service<CartMachineContext, CartMachineEvent, CartMachineTypeState>];
|
|
20
|
+
}): readonly [StateMachine.State<CartMachineContext, CartMachineEvent, CartMachineTypeState>, (event: "CART_FETCH" | "CART_CREATE" | "CART_SET" | "CARTLINE_ADD" | "CARTLINE_REMOVE" | "CARTLINE_UPDATE" | "NOTE_UPDATE" | "BUYER_IDENTITY_UPDATE" | "CART_ATTRIBUTES_UPDATE" | "DISCOUNT_CODES_UPDATE" | "CART_COMPLETED" | "RESOLVE" | "ERROR" | CartMachineEvent) => void, StateMachine.Service<CartMachineContext, CartMachineEvent, CartMachineTypeState>];
|
|
22
21
|
export declare function cartFromGraphQL(cart: CartFragmentFragment): Cart;
|
|
@@ -53,6 +53,15 @@ const INITIALIZING_CART_EVENTS = {
|
|
|
53
53
|
CART_CREATE: {
|
|
54
54
|
target: 'cartCreating',
|
|
55
55
|
},
|
|
56
|
+
CART_SET: {
|
|
57
|
+
target: 'idle',
|
|
58
|
+
actions: [
|
|
59
|
+
assign({
|
|
60
|
+
rawCartResult: (_, event) => event.payload.cart,
|
|
61
|
+
cart: (_, event) => cartFromGraphQL(event.payload.cart),
|
|
62
|
+
}),
|
|
63
|
+
],
|
|
64
|
+
},
|
|
56
65
|
};
|
|
57
66
|
const UPDATING_CART_EVENTS = {
|
|
58
67
|
CARTLINE_ADD: {
|
|
@@ -77,46 +86,52 @@ const UPDATING_CART_EVENTS = {
|
|
|
77
86
|
target: 'discountCodesUpdating',
|
|
78
87
|
},
|
|
79
88
|
};
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
},
|
|
87
|
-
cartCompleted: {
|
|
88
|
-
on: INITIALIZING_CART_EVENTS,
|
|
89
|
+
function createCartMachine(initialCart) {
|
|
90
|
+
return createMachine({
|
|
91
|
+
id: 'Cart',
|
|
92
|
+
initial: initialCart ? 'idle' : 'uninitialized',
|
|
93
|
+
context: {
|
|
94
|
+
cart: initialCart && cartFromGraphQL(initialCart),
|
|
89
95
|
},
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
96
|
+
states: {
|
|
97
|
+
uninitialized: {
|
|
98
|
+
on: INITIALIZING_CART_EVENTS,
|
|
99
|
+
},
|
|
100
|
+
cartCompleted: {
|
|
101
|
+
on: INITIALIZING_CART_EVENTS,
|
|
102
|
+
},
|
|
103
|
+
initializationError: {
|
|
104
|
+
on: INITIALIZING_CART_EVENTS,
|
|
105
|
+
},
|
|
106
|
+
idle: {
|
|
107
|
+
on: { ...INITIALIZING_CART_EVENTS, ...UPDATING_CART_EVENTS },
|
|
108
|
+
},
|
|
109
|
+
error: {
|
|
110
|
+
on: { ...INITIALIZING_CART_EVENTS, ...UPDATING_CART_EVENTS },
|
|
111
|
+
},
|
|
112
|
+
cartFetching: invokeCart('cartFetchAction', {
|
|
113
|
+
errorTarget: 'initializationError',
|
|
114
|
+
}),
|
|
115
|
+
cartCreating: invokeCart('cartCreateAction', {
|
|
116
|
+
errorTarget: 'initializationError',
|
|
117
|
+
}),
|
|
118
|
+
cartLineRemoving: invokeCart('cartLineRemoveAction'),
|
|
119
|
+
cartLineUpdating: invokeCart('cartLineUpdateAction'),
|
|
120
|
+
cartLineAdding: invokeCart('cartLineAddAction'),
|
|
121
|
+
noteUpdating: invokeCart('noteUpdateAction'),
|
|
122
|
+
buyerIdentityUpdating: invokeCart('buyerIdentityUpdateAction'),
|
|
123
|
+
cartAttributesUpdating: invokeCart('cartAttributesUpdateAction'),
|
|
124
|
+
discountCodesUpdating: invokeCart('discountCodesUpdateAction'),
|
|
98
125
|
},
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}),
|
|
102
|
-
cartCreating: invokeCart('cartCreateAction', {
|
|
103
|
-
errorTarget: 'initializationError',
|
|
104
|
-
}),
|
|
105
|
-
cartLineRemoving: invokeCart('cartLineRemoveAction'),
|
|
106
|
-
cartLineUpdating: invokeCart('cartLineUpdateAction'),
|
|
107
|
-
cartLineAdding: invokeCart('cartLineAddAction'),
|
|
108
|
-
noteUpdating: invokeCart('noteUpdateAction'),
|
|
109
|
-
buyerIdentityUpdating: invokeCart('buyerIdentityUpdateAction'),
|
|
110
|
-
cartAttributesUpdating: invokeCart('cartAttributesUpdateAction'),
|
|
111
|
-
discountCodesUpdating: invokeCart('discountCodesUpdateAction'),
|
|
112
|
-
},
|
|
113
|
-
});
|
|
126
|
+
});
|
|
127
|
+
}
|
|
114
128
|
export function useCartAPIStateMachine({ numCartLines, onCartActionEntry, onCartActionOptimisticUI, onCartActionComplete, data: cart, cartFragment, countryCode, }) {
|
|
115
129
|
const { cartFetch, cartCreate, cartLineAdd, cartLineUpdate, cartLineRemove, noteUpdate, buyerIdentityUpdate, cartAttributesUpdate, discountCodesUpdate, } = useCartActions({
|
|
116
130
|
numCartLines,
|
|
117
131
|
cartFragment,
|
|
118
132
|
countryCode,
|
|
119
133
|
});
|
|
134
|
+
const cartMachine = useMemo(() => createCartMachine(cart), [cart]);
|
|
120
135
|
const [state, send, service] = useMachine(cartMachine, {
|
|
121
136
|
actions: {
|
|
122
137
|
cartFetchAction: async (_, event) => {
|
|
@@ -152,9 +152,12 @@ async function processRequest(handleRequest, App, url, request, sessionApi, opti
|
|
|
152
152
|
const rsc = runRSC({ App, state, log, request, response });
|
|
153
153
|
if (isRSCRequest) {
|
|
154
154
|
const buffered = await bufferReadableStream(rsc.readable.getReader());
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
155
|
+
const rscDidError = !!rsc.didError();
|
|
156
|
+
postRequestTasks('rsc', rscDidError ? 500 : 200, request, response, rscDidError);
|
|
157
|
+
if (rscDidError) {
|
|
158
|
+
response.headers.set('cache-control', response.cacheControlHeader);
|
|
159
|
+
cacheResponse(response, request, [buffered], revalidate);
|
|
160
|
+
}
|
|
158
161
|
return new Response(buffered, {
|
|
159
162
|
headers: response.headers,
|
|
160
163
|
});
|
|
@@ -319,7 +322,7 @@ async function runSSR({ rsc, state, request, response, nodeResponse, nonce, dev,
|
|
|
319
322
|
// Last SSR write might be pending, delay closing the writable one tick
|
|
320
323
|
setTimeout(() => {
|
|
321
324
|
writable.close();
|
|
322
|
-
postRequestTasks('str', responseOptions.status, request, response);
|
|
325
|
+
postRequestTasks('str', responseOptions.status, request, response, !!didError());
|
|
323
326
|
response.status = responseOptions.status;
|
|
324
327
|
cacheResponse(response, request, savedChunks, revalidate);
|
|
325
328
|
}, 0);
|
|
@@ -328,7 +331,7 @@ async function runSSR({ rsc, state, request, response, nodeResponse, nonce, dev,
|
|
|
328
331
|
else {
|
|
329
332
|
// Redirects do not write body
|
|
330
333
|
writable.close();
|
|
331
|
-
postRequestTasks('str', responseOptions.status, request, response);
|
|
334
|
+
postRequestTasks('str', responseOptions.status, request, response, !!didError());
|
|
332
335
|
}
|
|
333
336
|
if (response.canStream()) {
|
|
334
337
|
return new Response(transform.readable, responseOptions);
|
|
@@ -376,7 +379,7 @@ async function runSSR({ rsc, state, request, response, nodeResponse, nonce, dev,
|
|
|
376
379
|
log.trace('node complete ssr');
|
|
377
380
|
if (!revalidate &&
|
|
378
381
|
(response.canStream() || nodeResponse.writableEnded)) {
|
|
379
|
-
postRequestTasks('str', nodeResponse.statusCode, request, response);
|
|
382
|
+
postRequestTasks('str', nodeResponse.statusCode, request, response, !!didError());
|
|
380
383
|
return;
|
|
381
384
|
}
|
|
382
385
|
writeHeadToNodeResponse(nodeResponse, response, log, didError());
|
|
@@ -396,8 +399,8 @@ async function runSSR({ rsc, state, request, response, nodeResponse, nonce, dev,
|
|
|
396
399
|
let html = template;
|
|
397
400
|
if (!error) {
|
|
398
401
|
html = assembleHtml({ ssrHtml, rscPayload, request, template });
|
|
399
|
-
postRequestTasks('ssr', nodeResponse.statusCode, request, response);
|
|
400
402
|
}
|
|
403
|
+
postRequestTasks('ssr', nodeResponse.statusCode, request, response, !!didError());
|
|
401
404
|
if (!nodeResponse.writableEnded) {
|
|
402
405
|
nodeResponse.write(html);
|
|
403
406
|
nodeResponse.end();
|
|
@@ -506,8 +509,8 @@ function isRedirect(response) {
|
|
|
506
509
|
function flightContainer(chunk) {
|
|
507
510
|
return `<meta data-flight="${htmlEncode(chunk)}" />`;
|
|
508
511
|
}
|
|
509
|
-
function postRequestTasks(type, status, request, response) {
|
|
510
|
-
logServerResponse(type, request, status);
|
|
512
|
+
function postRequestTasks(type, status, request, response, didError) {
|
|
513
|
+
logServerResponse(type, request, status, didError);
|
|
511
514
|
logCacheControlHeaders(type, request, response);
|
|
512
515
|
logQueryTimings(type, request);
|
|
513
516
|
request.savePreloadQueries();
|
|
@@ -74,7 +74,9 @@ function getCookieDomain(cookieDomain) {
|
|
|
74
74
|
function trackPageView(payload) {
|
|
75
75
|
microSessionCount += 1;
|
|
76
76
|
try {
|
|
77
|
-
|
|
77
|
+
payload &&
|
|
78
|
+
payload.shopify &&
|
|
79
|
+
sendToServer(storefrontPageViewSchema(payload));
|
|
78
80
|
}
|
|
79
81
|
catch (error) {
|
|
80
82
|
console.error(`Error Shopify analytics: ${ClientAnalytics.eventNames.PAGE_VIEW}`, error);
|
|
@@ -94,7 +96,7 @@ function buildStorefrontPageViewPayload(payload) {
|
|
|
94
96
|
const shopify = payload.shopify;
|
|
95
97
|
let formattedData = {
|
|
96
98
|
appClientId: '6167201',
|
|
97
|
-
hydrogenSubchannelId: shopify.storefrontId,
|
|
99
|
+
hydrogenSubchannelId: shopify.storefrontId || '0',
|
|
98
100
|
isPersistentCookie: shopify.isPersistentCookie,
|
|
99
101
|
uniqToken: shopify.userId,
|
|
100
102
|
visitToken: shopify.sessionId,
|
|
@@ -10,7 +10,7 @@ import { CacheLong } from '../../../Cache/strategies/index.js';
|
|
|
10
10
|
import { gql } from '../../../../utilities/graphql-tag.js';
|
|
11
11
|
import { SHOPIFY_Y, SHOPIFY_S } from '../../../../constants.js';
|
|
12
12
|
export function ShopifyAnalytics({ cookieDomain }) {
|
|
13
|
-
const { storeDomain } = useShop();
|
|
13
|
+
const { storeDomain, storefrontId } = useShop();
|
|
14
14
|
const request = useServerRequest();
|
|
15
15
|
const cookies = parse(request.headers.get('Cookie') || '');
|
|
16
16
|
const domain = cookieDomain || storeDomain;
|
|
@@ -23,7 +23,7 @@ export function ShopifyAnalytics({ cookieDomain }) {
|
|
|
23
23
|
shopify: {
|
|
24
24
|
shopId: id,
|
|
25
25
|
currency: currencyCode,
|
|
26
|
-
storefrontId
|
|
26
|
+
storefrontId,
|
|
27
27
|
acceptedLanguage: request.headers.get('Accept-Language')?.replace(/-.*/, '') || 'en',
|
|
28
28
|
isPersistentCookie: !!cookies[SHOPIFY_S] || !!cookies[SHOPIFY_Y],
|
|
29
29
|
},
|
|
@@ -16,7 +16,8 @@ export const CLIENT_CONTEXT_ALLOW_LIST = [
|
|
|
16
16
|
function makeShopifyContext(shopifyConfig) {
|
|
17
17
|
const countryCode = shopifyConfig.defaultCountryCode ?? DEFAULT_COUNTRY;
|
|
18
18
|
const languageCode = shopifyConfig.defaultLanguageCode ?? DEFAULT_LANGUAGE;
|
|
19
|
-
const storefrontId =
|
|
19
|
+
const storefrontId = shopifyConfig.storefrontId ??
|
|
20
|
+
getOxygenVariable(SHOPIFY_STOREFRONT_ID_VARIABLE);
|
|
20
21
|
const shopifyProviderServerValue = {
|
|
21
22
|
defaultCountryCode: countryCode.toUpperCase(),
|
|
22
23
|
defaultLanguageCode: languageCode.toUpperCase(),
|
package/dist/esnext/index.d.ts
CHANGED
|
@@ -40,5 +40,5 @@ export { CartQuery } from './components/CartProvider/cart-queries.js';
|
|
|
40
40
|
export { fetchSync } from './foundation/fetchSync/server/fetchSync.js';
|
|
41
41
|
export { type HydrogenRequest } from './foundation/HydrogenRequest/HydrogenRequest.server.js';
|
|
42
42
|
export { type HydrogenResponse } from './foundation/HydrogenResponse/HydrogenResponse.server.js';
|
|
43
|
-
export { type HydrogenRouteProps } from './types.js';
|
|
43
|
+
export { type HydrogenRouteProps, type CachingStrategy } from './types.js';
|
|
44
44
|
export { type ResourceGetter as HydrogenApiRoute, RequestOptions as HydrogenApiRouteOptions, } from './utilities/apiRoutes.js';
|
|
@@ -161,7 +161,7 @@ export async function renderApiRoute(request, route, hydrogenConfig, { session,
|
|
|
161
161
|
});
|
|
162
162
|
}
|
|
163
163
|
if (!suppressLog) {
|
|
164
|
-
logServerResponse('api', request, response.status ?? 200);
|
|
164
|
+
logServerResponse('api', request, response.status ?? 200, false);
|
|
165
165
|
}
|
|
166
166
|
if (response instanceof Request) {
|
|
167
167
|
const url = new URL(request.url);
|
|
@@ -24,5 +24,5 @@ export declare type RenderType = 'str' | 'rsc' | 'ssr' | 'api';
|
|
|
24
24
|
export declare function getLoggerWithContext(context: Partial<HydrogenRequest>): Logger;
|
|
25
25
|
export declare const log: Logger;
|
|
26
26
|
export declare function setLogger(config?: LoggerConfig): void;
|
|
27
|
-
export declare function logServerResponse(type: RenderType, request: HydrogenRequest, responseStatus: number): void;
|
|
27
|
+
export declare function logServerResponse(type: RenderType, request: HydrogenRequest, responseStatus: number, didError: boolean): void;
|
|
28
28
|
export {};
|
|
@@ -72,7 +72,7 @@ const SERVER_RESPONSE_MAP = {
|
|
|
72
72
|
rsc: 'Server Components',
|
|
73
73
|
ssr: 'buffered SSR',
|
|
74
74
|
};
|
|
75
|
-
export function logServerResponse(type, request, responseStatus) {
|
|
75
|
+
export function logServerResponse(type, request, responseStatus, didError) {
|
|
76
76
|
const log = getLoggerWithContext(request);
|
|
77
77
|
const coloredResponseStatus = responseStatus >= 500
|
|
78
78
|
? red(responseStatus)
|
|
@@ -85,5 +85,5 @@ export function logServerResponse(type, request, responseStatus) {
|
|
|
85
85
|
const styledType = italic(fullType.padEnd(17));
|
|
86
86
|
const paddedTiming = ((getTime() - request.time).toFixed(2) + ' ms').padEnd(10);
|
|
87
87
|
const url = parseUrl(type, request.url);
|
|
88
|
-
log.debug(`${request.method} ${styledType} ${coloredResponseStatus} ${paddedTiming} ${url}`);
|
|
88
|
+
log.debug(`${request.method} ${styledType} ${coloredResponseStatus} ${didError || responseStatus >= 400 ? red('error') : green('ok ')} ${paddedTiming} ${url}`);
|
|
89
89
|
}
|
|
@@ -13,7 +13,7 @@ export function getStorefrontApiRequestHeaders({ buyerIp, publicStorefrontToken,
|
|
|
13
13
|
log.error('No secret Shopify storefront API token was defined. This means your app will be rate limited!\nSee how to add the token: ');
|
|
14
14
|
}
|
|
15
15
|
else if (privateStorefrontToken) {
|
|
16
|
-
log.warn('The private shopify storefront API token was loaded implicitly by an environment variable. This is deprecated, and instead the variable should be defined directly in the Hydrogen Config.\nFor more information: ');
|
|
16
|
+
log.warn('The private shopify storefront API token was loaded implicitly by an environment variable. This is deprecated, and instead the variable should be defined directly in the Hydrogen Config.\nFor more information: https://shopify.dev/custom-storefronts/hydrogen/framework/hydrogen-config');
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
}
|
|
@@ -21,11 +21,8 @@ export function getStorefrontApiRequestHeaders({ buyerIp, publicStorefrontToken,
|
|
|
21
21
|
storefrontId = getOxygenVariable(SHOPIFY_STOREFRONT_ID_VARIABLE);
|
|
22
22
|
if (!storefrontIdWarned) {
|
|
23
23
|
storefrontIdWarned = true;
|
|
24
|
-
if (
|
|
25
|
-
log.warn('
|
|
26
|
-
}
|
|
27
|
-
else if (storefrontId) {
|
|
28
|
-
log.warn('The storefrontId was loaded implicitly by an environment variable. This is deprecated, and instead the variable should be defined directly in the Hydrogen Config.\nFor more information: ');
|
|
24
|
+
if (storefrontId) {
|
|
25
|
+
log.warn('The storefrontId was loaded implicitly by an environment variable. This is deprecated, and instead the variable should be defined directly in the Hydrogen Config.\nFor more information: https://shopify.dev/custom-storefronts/hydrogen/framework/hydrogen-config');
|
|
29
26
|
}
|
|
30
27
|
}
|
|
31
28
|
}
|
package/dist/esnext/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const LIB_VERSION = "1.4.
|
|
1
|
+
export declare const LIB_VERSION = "1.4.3";
|
package/dist/esnext/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const LIB_VERSION = '1.4.
|
|
1
|
+
export const LIB_VERSION = '1.4.3';
|