@shopify/hydrogen 1.4.3 → 1.5.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/CartProviderV2.client.js +40 -10
- 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/foundation/Router/BrowserRouter.client.js +7 -1
- package/dist/esnext/framework/plugins/vite-plugin-css-rsc.d.ts +1 -1
- package/dist/esnext/framework/plugins/vite-plugin-css-rsc.js +100 -3
- package/dist/esnext/framework/plugins/vite-plugin-hydrogen-rsc.js +2 -2
- package/dist/esnext/framework/plugins/vite-plugin-platform-entry.js +1 -1
- 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/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 +9 -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-css-rsc.d.ts +1 -1
- package/dist/node/framework/plugins/vite-plugin-css-rsc.js +99 -2
- package/dist/node/framework/plugins/vite-plugin-hydrogen-rsc.js +2 -2
- package/dist/node/framework/plugins/vite-plugin-platform-entry.js +1 -1
- package/package.json +3 -5
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { CurrencyCode } from '../../../storefront-api-types.js';
|
|
2
|
+
import { CartFragmentFragment } from '../../CartProvider/graphql/CartFragment.js';
|
|
3
|
+
export declare const CART_LINE: {
|
|
4
|
+
attributes: {
|
|
5
|
+
key: string;
|
|
6
|
+
value: string;
|
|
7
|
+
}[];
|
|
8
|
+
quantity: number;
|
|
9
|
+
id: string;
|
|
10
|
+
merchandise: {
|
|
11
|
+
id: string;
|
|
12
|
+
availableForSale: boolean;
|
|
13
|
+
priceV2: {
|
|
14
|
+
amount: string;
|
|
15
|
+
currencyCode: CurrencyCode;
|
|
16
|
+
};
|
|
17
|
+
product: {
|
|
18
|
+
handle: string;
|
|
19
|
+
title: string;
|
|
20
|
+
};
|
|
21
|
+
requiresShipping: boolean;
|
|
22
|
+
selectedOptions: {
|
|
23
|
+
name: string;
|
|
24
|
+
value: string;
|
|
25
|
+
}[];
|
|
26
|
+
title: string;
|
|
27
|
+
};
|
|
28
|
+
cost: {
|
|
29
|
+
totalAmount: {
|
|
30
|
+
amount: string;
|
|
31
|
+
currencyCode: CurrencyCode;
|
|
32
|
+
};
|
|
33
|
+
compareAtAmount: {
|
|
34
|
+
amount: string;
|
|
35
|
+
currencyCode: CurrencyCode;
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
export declare function getCartLineMock(options?: Partial<CartFragmentFragment['lines']['edges'][0]['node']>): {
|
|
40
|
+
__typename?: "CartLine" | undefined;
|
|
41
|
+
id: string;
|
|
42
|
+
quantity: number;
|
|
43
|
+
attributes: ({
|
|
44
|
+
__typename?: "Attribute" | undefined;
|
|
45
|
+
} & Pick<import("../../../storefront-api-types.js").Attribute, "key" | "value">)[] | {
|
|
46
|
+
key: string;
|
|
47
|
+
value: string;
|
|
48
|
+
}[];
|
|
49
|
+
cost: ({
|
|
50
|
+
__typename?: "CartLineCost" | undefined;
|
|
51
|
+
} & {
|
|
52
|
+
totalAmount: {
|
|
53
|
+
__typename?: "MoneyV2" | undefined;
|
|
54
|
+
} & Pick<import("../../../storefront-api-types.js").MoneyV2, "currencyCode" | "amount">;
|
|
55
|
+
compareAtAmountPerQuantity?: import("../../../storefront-api-types.js").Maybe<{
|
|
56
|
+
__typename?: "MoneyV2" | undefined;
|
|
57
|
+
} & Pick<import("../../../storefront-api-types.js").MoneyV2, "currencyCode" | "amount">> | undefined;
|
|
58
|
+
}) | {
|
|
59
|
+
totalAmount: {
|
|
60
|
+
amount: string;
|
|
61
|
+
currencyCode: CurrencyCode;
|
|
62
|
+
};
|
|
63
|
+
compareAtAmount: {
|
|
64
|
+
amount: string;
|
|
65
|
+
currencyCode: CurrencyCode;
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
merchandise: {
|
|
69
|
+
id: string;
|
|
70
|
+
availableForSale: boolean;
|
|
71
|
+
priceV2: {
|
|
72
|
+
amount: string;
|
|
73
|
+
currencyCode: CurrencyCode;
|
|
74
|
+
};
|
|
75
|
+
product: {
|
|
76
|
+
handle: string;
|
|
77
|
+
title: string;
|
|
78
|
+
};
|
|
79
|
+
requiresShipping: boolean;
|
|
80
|
+
selectedOptions: {
|
|
81
|
+
name: string;
|
|
82
|
+
value: string;
|
|
83
|
+
}[];
|
|
84
|
+
title: string;
|
|
85
|
+
};
|
|
86
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { CurrencyCode } from '../../../storefront-api-types.js';
|
|
2
|
+
export const CART_LINE = {
|
|
3
|
+
attributes: [{ key: 'color', value: 'red' }],
|
|
4
|
+
quantity: 1,
|
|
5
|
+
id: 'abc',
|
|
6
|
+
merchandise: {
|
|
7
|
+
id: 'def',
|
|
8
|
+
availableForSale: true,
|
|
9
|
+
priceV2: {
|
|
10
|
+
amount: '123',
|
|
11
|
+
currencyCode: CurrencyCode.Usd,
|
|
12
|
+
},
|
|
13
|
+
product: {
|
|
14
|
+
handle: 'foo',
|
|
15
|
+
title: 'Product Name',
|
|
16
|
+
},
|
|
17
|
+
requiresShipping: true,
|
|
18
|
+
selectedOptions: [{ name: 'size', value: 'large' }],
|
|
19
|
+
title: 'Product Name - Large',
|
|
20
|
+
},
|
|
21
|
+
cost: {
|
|
22
|
+
totalAmount: {
|
|
23
|
+
amount: '123',
|
|
24
|
+
currencyCode: CurrencyCode.Usd,
|
|
25
|
+
},
|
|
26
|
+
compareAtAmount: {
|
|
27
|
+
amount: '125',
|
|
28
|
+
currencyCode: CurrencyCode.Usd,
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
export function getCartLineMock(options) {
|
|
33
|
+
return { ...CART_LINE, ...options };
|
|
34
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
1
|
+
import React, { useCallback, useEffect, useMemo, useRef, useState, useTransition, } from 'react';
|
|
2
2
|
import { CountryCode, } from '../../storefront-api-types.js';
|
|
3
3
|
import { CartContext } from './context.js';
|
|
4
4
|
import { useCartAPIStateMachine } from './useCartAPIStateMachine.client.js';
|
|
@@ -125,14 +125,16 @@ export function CartProviderV2({ children, numCartLines, onCreate, onLineAdd, on
|
|
|
125
125
|
cartState.value === 'cartCompleted') &&
|
|
126
126
|
countryCode !== cartState?.context?.cart?.buyerIdentity?.countryCode &&
|
|
127
127
|
!cartState.context.errors;
|
|
128
|
+
const fetchingFromStorage = useRef(false);
|
|
128
129
|
/**
|
|
129
130
|
* Initializes cart with priority in this order:
|
|
130
131
|
* 1. cart props
|
|
131
132
|
* 2. localStorage cartId
|
|
132
133
|
*/
|
|
133
134
|
useEffect(() => {
|
|
134
|
-
if (!cartReady.current) {
|
|
135
|
+
if (!cartReady.current && !fetchingFromStorage.current) {
|
|
135
136
|
if (!cart && storageAvailable('localStorage')) {
|
|
137
|
+
fetchingFromStorage.current = true;
|
|
136
138
|
try {
|
|
137
139
|
const cartId = window.localStorage.getItem(CART_ID_STORAGE_KEY);
|
|
138
140
|
if (cartId) {
|
|
@@ -210,15 +212,18 @@ export function CartProviderV2({ children, numCartLines, onCreate, onLineAdd, on
|
|
|
210
212
|
payload: cartInput,
|
|
211
213
|
});
|
|
212
214
|
}, [countryCode, customerAccessToken, onCartReadySend]);
|
|
215
|
+
// Delays the cart state in the context if the page is hydrating
|
|
216
|
+
// preventing suspense boundary errors.
|
|
217
|
+
const cartDisplayState = useDelayedStateUntilHydration(cartState);
|
|
213
218
|
const cartContextValue = useMemo(() => {
|
|
214
219
|
return {
|
|
215
|
-
...(
|
|
216
|
-
status: transposeStatus(
|
|
217
|
-
error:
|
|
218
|
-
totalQuantity:
|
|
220
|
+
...(cartDisplayState?.context?.cart ?? { lines: [], attributes: [] }),
|
|
221
|
+
status: transposeStatus(cartDisplayState.value),
|
|
222
|
+
error: cartDisplayState?.context?.errors,
|
|
223
|
+
totalQuantity: cartDisplayState?.context?.cart?.totalQuantity ?? 0,
|
|
219
224
|
cartCreate,
|
|
220
225
|
linesAdd(lines) {
|
|
221
|
-
if (
|
|
226
|
+
if (cartDisplayState?.context?.cart?.id) {
|
|
222
227
|
onCartReadySend({
|
|
223
228
|
type: 'CARTLINE_ADD',
|
|
224
229
|
payload: { lines },
|
|
@@ -280,10 +285,10 @@ export function CartProviderV2({ children, numCartLines, onCreate, onLineAdd, on
|
|
|
280
285
|
};
|
|
281
286
|
}, [
|
|
282
287
|
cartCreate,
|
|
288
|
+
cartDisplayState?.context?.cart,
|
|
289
|
+
cartDisplayState?.context?.errors,
|
|
290
|
+
cartDisplayState.value,
|
|
283
291
|
cartFragment,
|
|
284
|
-
cartState?.context?.cart,
|
|
285
|
-
cartState?.context?.errors,
|
|
286
|
-
cartState.value,
|
|
287
292
|
onCartReadySend,
|
|
288
293
|
]);
|
|
289
294
|
return (React.createElement(CartContext.Provider, { value: cartContextValue }, children));
|
|
@@ -311,6 +316,31 @@ function transposeStatus(status) {
|
|
|
311
316
|
return 'updating';
|
|
312
317
|
}
|
|
313
318
|
}
|
|
319
|
+
/**
|
|
320
|
+
* Delays a state update until hydration finishes. Useful for preventing suspense boundaries errors when updating a context
|
|
321
|
+
* @remarks this uses startTransition and waits for it to finish.
|
|
322
|
+
*/
|
|
323
|
+
function useDelayedStateUntilHydration(state) {
|
|
324
|
+
const [isPending, startTransition] = useTransition();
|
|
325
|
+
const [delayedState, setDelayedState] = useState(state);
|
|
326
|
+
const firstTimePending = useRef(false);
|
|
327
|
+
if (isPending) {
|
|
328
|
+
firstTimePending.current = true;
|
|
329
|
+
}
|
|
330
|
+
const firstTimePendingFinished = useRef(false);
|
|
331
|
+
if (!isPending && firstTimePending.current) {
|
|
332
|
+
firstTimePendingFinished.current = true;
|
|
333
|
+
}
|
|
334
|
+
useEffect(() => {
|
|
335
|
+
startTransition(() => {
|
|
336
|
+
if (!firstTimePendingFinished.current) {
|
|
337
|
+
setDelayedState(state);
|
|
338
|
+
}
|
|
339
|
+
});
|
|
340
|
+
}, [state]);
|
|
341
|
+
const displayState = firstTimePendingFinished.current ? state : delayedState;
|
|
342
|
+
return displayState;
|
|
343
|
+
}
|
|
314
344
|
/** Check for storage availability funciton obtained from
|
|
315
345
|
* https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API
|
|
316
346
|
*/
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import type { CartWithActions } from '../types.js';
|
|
2
|
+
import { CartFragmentFragment } from '../graphql/CartFragment.js';
|
|
3
|
+
export declare const CART: {
|
|
4
|
+
id: string;
|
|
5
|
+
checkoutUrl: string;
|
|
6
|
+
attributes: never[];
|
|
7
|
+
buyerIdentity: {};
|
|
8
|
+
discountCodes: never[];
|
|
9
|
+
totalQuantity: number;
|
|
10
|
+
cost: {
|
|
11
|
+
subtotalAmount: {
|
|
12
|
+
currencyCode: import("../../../storefront-api-types.js").CurrencyCode;
|
|
13
|
+
amount: string;
|
|
14
|
+
};
|
|
15
|
+
totalAmount: {
|
|
16
|
+
currencyCode: import("../../../storefront-api-types.js").CurrencyCode;
|
|
17
|
+
amount: string;
|
|
18
|
+
};
|
|
19
|
+
totalTaxAmount: {
|
|
20
|
+
currencyCode: import("../../../storefront-api-types.js").CurrencyCode;
|
|
21
|
+
amount: string;
|
|
22
|
+
};
|
|
23
|
+
totalDutyAmount: {
|
|
24
|
+
currencyCode: import("../../../storefront-api-types.js").CurrencyCode;
|
|
25
|
+
amount: string;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
lines: {
|
|
29
|
+
edges: never[];
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
export declare function getCartMock(options?: Partial<CartFragmentFragment>): {
|
|
33
|
+
__typename?: "Cart" | undefined;
|
|
34
|
+
id: string;
|
|
35
|
+
note?: import("../../../storefront-api-types.js").Maybe<string> | undefined;
|
|
36
|
+
checkoutUrl: string;
|
|
37
|
+
totalQuantity: number;
|
|
38
|
+
buyerIdentity: {};
|
|
39
|
+
lines: ({
|
|
40
|
+
__typename?: "CartLineConnection" | undefined;
|
|
41
|
+
} & {
|
|
42
|
+
edges: ({
|
|
43
|
+
__typename?: "CartLineEdge" | undefined;
|
|
44
|
+
} & {
|
|
45
|
+
node: {
|
|
46
|
+
__typename?: "CartLine" | undefined;
|
|
47
|
+
} & Pick<import("../../../storefront-api-types.js").CartLine, "id" | "quantity"> & {
|
|
48
|
+
attributes: ({
|
|
49
|
+
__typename?: "Attribute" | undefined;
|
|
50
|
+
} & Pick<import("../../../storefront-api-types.js").Attribute, "key" | "value">)[];
|
|
51
|
+
cost: {
|
|
52
|
+
__typename?: "CartLineCost" | undefined;
|
|
53
|
+
} & {
|
|
54
|
+
totalAmount: {
|
|
55
|
+
__typename?: "MoneyV2" | undefined;
|
|
56
|
+
} & Pick<import("../../../storefront-api-types.js").MoneyV2, "currencyCode" | "amount">;
|
|
57
|
+
compareAtAmountPerQuantity?: import("../../../storefront-api-types.js").Maybe<{
|
|
58
|
+
__typename?: "MoneyV2" | undefined;
|
|
59
|
+
} & Pick<import("../../../storefront-api-types.js").MoneyV2, "currencyCode" | "amount">> | undefined;
|
|
60
|
+
};
|
|
61
|
+
merchandise: {
|
|
62
|
+
__typename?: "ProductVariant" | undefined;
|
|
63
|
+
} & Pick<import("../../../storefront-api-types.js").ProductVariant, "id" | "title" | "availableForSale" | "requiresShipping"> & {
|
|
64
|
+
compareAtPriceV2?: import("../../../storefront-api-types.js").Maybe<{
|
|
65
|
+
__typename?: "MoneyV2" | undefined;
|
|
66
|
+
} & Pick<import("../../../storefront-api-types.js").MoneyV2, "currencyCode" | "amount">> | undefined;
|
|
67
|
+
priceV2: {
|
|
68
|
+
__typename?: "MoneyV2" | undefined;
|
|
69
|
+
} & Pick<import("../../../storefront-api-types.js").MoneyV2, "currencyCode" | "amount">;
|
|
70
|
+
image?: import("../../../storefront-api-types.js").Maybe<{
|
|
71
|
+
__typename?: "Image" | undefined;
|
|
72
|
+
} & Pick<import("../../../storefront-api-types.js").Image, "id" | "height" | "width" | "url" | "altText">> | undefined;
|
|
73
|
+
product: {
|
|
74
|
+
__typename?: "Product" | undefined;
|
|
75
|
+
} & Pick<import("../../../storefront-api-types.js").Product, "title" | "handle">;
|
|
76
|
+
selectedOptions: ({
|
|
77
|
+
__typename?: "SelectedOption" | undefined;
|
|
78
|
+
} & Pick<import("../../../storefront-api-types.js").SelectedOption, "name" | "value">)[];
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
})[];
|
|
82
|
+
}) | {
|
|
83
|
+
edges: never[];
|
|
84
|
+
};
|
|
85
|
+
cost: ({
|
|
86
|
+
__typename?: "CartCost" | undefined;
|
|
87
|
+
} & {
|
|
88
|
+
subtotalAmount: {
|
|
89
|
+
__typename?: "MoneyV2" | undefined;
|
|
90
|
+
} & Pick<import("../../../storefront-api-types.js").MoneyV2, "currencyCode" | "amount">;
|
|
91
|
+
totalAmount: {
|
|
92
|
+
__typename?: "MoneyV2" | undefined;
|
|
93
|
+
} & Pick<import("../../../storefront-api-types.js").MoneyV2, "currencyCode" | "amount">;
|
|
94
|
+
totalDutyAmount?: import("../../../storefront-api-types.js").Maybe<{
|
|
95
|
+
__typename?: "MoneyV2" | undefined;
|
|
96
|
+
} & Pick<import("../../../storefront-api-types.js").MoneyV2, "currencyCode" | "amount">> | undefined;
|
|
97
|
+
totalTaxAmount?: import("../../../storefront-api-types.js").Maybe<{
|
|
98
|
+
__typename?: "MoneyV2" | undefined;
|
|
99
|
+
} & Pick<import("../../../storefront-api-types.js").MoneyV2, "currencyCode" | "amount">> | undefined;
|
|
100
|
+
}) | {
|
|
101
|
+
subtotalAmount: {
|
|
102
|
+
currencyCode: import("../../../storefront-api-types.js").CurrencyCode;
|
|
103
|
+
amount: string;
|
|
104
|
+
};
|
|
105
|
+
totalAmount: {
|
|
106
|
+
currencyCode: import("../../../storefront-api-types.js").CurrencyCode;
|
|
107
|
+
amount: string;
|
|
108
|
+
};
|
|
109
|
+
totalTaxAmount: {
|
|
110
|
+
currencyCode: import("../../../storefront-api-types.js").CurrencyCode;
|
|
111
|
+
amount: string;
|
|
112
|
+
};
|
|
113
|
+
totalDutyAmount: {
|
|
114
|
+
currencyCode: import("../../../storefront-api-types.js").CurrencyCode;
|
|
115
|
+
amount: string;
|
|
116
|
+
};
|
|
117
|
+
};
|
|
118
|
+
attributes: ({
|
|
119
|
+
__typename?: "Attribute" | undefined;
|
|
120
|
+
} & Pick<import("../../../storefront-api-types.js").Attribute, "key" | "value">)[];
|
|
121
|
+
discountCodes: ({
|
|
122
|
+
__typename?: "CartDiscountCode" | undefined;
|
|
123
|
+
} & Pick<import("../../../storefront-api-types.js").CartDiscountCode, "code" | "applicable">)[];
|
|
124
|
+
};
|
|
125
|
+
export declare const CART_WITH_LINES: {
|
|
126
|
+
lines: {
|
|
127
|
+
edges: {
|
|
128
|
+
node: {
|
|
129
|
+
attributes: {
|
|
130
|
+
key: string;
|
|
131
|
+
value: string;
|
|
132
|
+
}[];
|
|
133
|
+
quantity: number;
|
|
134
|
+
id: string;
|
|
135
|
+
merchandise: {
|
|
136
|
+
id: string;
|
|
137
|
+
availableForSale: boolean;
|
|
138
|
+
priceV2: {
|
|
139
|
+
amount: string;
|
|
140
|
+
currencyCode: import("../../../storefront-api-types.js").CurrencyCode;
|
|
141
|
+
};
|
|
142
|
+
product: {
|
|
143
|
+
handle: string;
|
|
144
|
+
title: string;
|
|
145
|
+
};
|
|
146
|
+
requiresShipping: boolean;
|
|
147
|
+
selectedOptions: {
|
|
148
|
+
name: string;
|
|
149
|
+
value: string;
|
|
150
|
+
}[];
|
|
151
|
+
title: string;
|
|
152
|
+
};
|
|
153
|
+
cost: {
|
|
154
|
+
totalAmount: {
|
|
155
|
+
amount: string;
|
|
156
|
+
currencyCode: import("../../../storefront-api-types.js").CurrencyCode;
|
|
157
|
+
};
|
|
158
|
+
compareAtAmount: {
|
|
159
|
+
amount: string;
|
|
160
|
+
currencyCode: import("../../../storefront-api-types.js").CurrencyCode;
|
|
161
|
+
};
|
|
162
|
+
};
|
|
163
|
+
};
|
|
164
|
+
}[];
|
|
165
|
+
};
|
|
166
|
+
id: string;
|
|
167
|
+
checkoutUrl: string;
|
|
168
|
+
attributes: never[];
|
|
169
|
+
buyerIdentity: {};
|
|
170
|
+
discountCodes: never[];
|
|
171
|
+
totalQuantity: number;
|
|
172
|
+
cost: {
|
|
173
|
+
subtotalAmount: {
|
|
174
|
+
currencyCode: import("../../../storefront-api-types.js").CurrencyCode;
|
|
175
|
+
amount: string;
|
|
176
|
+
};
|
|
177
|
+
totalAmount: {
|
|
178
|
+
currencyCode: import("../../../storefront-api-types.js").CurrencyCode;
|
|
179
|
+
amount: string;
|
|
180
|
+
};
|
|
181
|
+
totalTaxAmount: {
|
|
182
|
+
currencyCode: import("../../../storefront-api-types.js").CurrencyCode;
|
|
183
|
+
amount: string;
|
|
184
|
+
};
|
|
185
|
+
totalDutyAmount: {
|
|
186
|
+
currencyCode: import("../../../storefront-api-types.js").CurrencyCode;
|
|
187
|
+
amount: string;
|
|
188
|
+
};
|
|
189
|
+
};
|
|
190
|
+
};
|
|
191
|
+
export declare const CART_WITH_LINES_FLATTENED: {
|
|
192
|
+
lines: import("type-fest/source/partial-deep.js").PartialObjectDeep<{
|
|
193
|
+
attributes: {
|
|
194
|
+
key: string;
|
|
195
|
+
value: string;
|
|
196
|
+
}[];
|
|
197
|
+
quantity: number;
|
|
198
|
+
id: string;
|
|
199
|
+
merchandise: {
|
|
200
|
+
id: string;
|
|
201
|
+
availableForSale: boolean;
|
|
202
|
+
priceV2: {
|
|
203
|
+
amount: string;
|
|
204
|
+
currencyCode: import("../../../storefront-api-types.js").CurrencyCode;
|
|
205
|
+
};
|
|
206
|
+
product: {
|
|
207
|
+
handle: string;
|
|
208
|
+
title: string;
|
|
209
|
+
};
|
|
210
|
+
requiresShipping: boolean;
|
|
211
|
+
selectedOptions: {
|
|
212
|
+
name: string;
|
|
213
|
+
value: string;
|
|
214
|
+
}[];
|
|
215
|
+
title: string;
|
|
216
|
+
};
|
|
217
|
+
cost: {
|
|
218
|
+
totalAmount: {
|
|
219
|
+
amount: string;
|
|
220
|
+
currencyCode: import("../../../storefront-api-types.js").CurrencyCode;
|
|
221
|
+
};
|
|
222
|
+
compareAtAmount: {
|
|
223
|
+
amount: string;
|
|
224
|
+
currencyCode: import("../../../storefront-api-types.js").CurrencyCode;
|
|
225
|
+
};
|
|
226
|
+
};
|
|
227
|
+
}>[];
|
|
228
|
+
id: string;
|
|
229
|
+
checkoutUrl: string;
|
|
230
|
+
attributes: never[];
|
|
231
|
+
buyerIdentity: {};
|
|
232
|
+
discountCodes: never[];
|
|
233
|
+
totalQuantity: number;
|
|
234
|
+
cost: {
|
|
235
|
+
subtotalAmount: {
|
|
236
|
+
currencyCode: import("../../../storefront-api-types.js").CurrencyCode;
|
|
237
|
+
amount: string;
|
|
238
|
+
};
|
|
239
|
+
totalAmount: {
|
|
240
|
+
currencyCode: import("../../../storefront-api-types.js").CurrencyCode;
|
|
241
|
+
amount: string;
|
|
242
|
+
};
|
|
243
|
+
totalTaxAmount: {
|
|
244
|
+
currencyCode: import("../../../storefront-api-types.js").CurrencyCode;
|
|
245
|
+
amount: string;
|
|
246
|
+
};
|
|
247
|
+
totalDutyAmount: {
|
|
248
|
+
currencyCode: import("../../../storefront-api-types.js").CurrencyCode;
|
|
249
|
+
amount: string;
|
|
250
|
+
};
|
|
251
|
+
};
|
|
252
|
+
};
|
|
253
|
+
export declare const CART_ACTIONS: CartWithActions;
|
|
254
|
+
export declare const CART_WITH_ACTIONS: CartWithActions;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { CART_LINE } from '../../CartLineProvider/tests/fixtures.js';
|
|
2
|
+
import { getPrice } from '../../../utilities/tests/price.js';
|
|
3
|
+
import { flattenConnection } from '../../../utilities/index.js';
|
|
4
|
+
import { defaultCartFragment } from '../cart-queries.js';
|
|
5
|
+
export const CART = {
|
|
6
|
+
id: 'abc',
|
|
7
|
+
checkoutUrl: 'https://shopify.com/checkout',
|
|
8
|
+
attributes: [],
|
|
9
|
+
buyerIdentity: {},
|
|
10
|
+
discountCodes: [],
|
|
11
|
+
totalQuantity: 0,
|
|
12
|
+
cost: {
|
|
13
|
+
subtotalAmount: getPrice(),
|
|
14
|
+
totalAmount: getPrice(),
|
|
15
|
+
totalTaxAmount: getPrice(),
|
|
16
|
+
totalDutyAmount: getPrice(),
|
|
17
|
+
},
|
|
18
|
+
lines: { edges: [] },
|
|
19
|
+
};
|
|
20
|
+
export function getCartMock(options) {
|
|
21
|
+
return { ...CART, ...options };
|
|
22
|
+
}
|
|
23
|
+
export const CART_WITH_LINES = {
|
|
24
|
+
...CART,
|
|
25
|
+
lines: { edges: [{ node: CART_LINE }] },
|
|
26
|
+
};
|
|
27
|
+
export const CART_WITH_LINES_FLATTENED = {
|
|
28
|
+
...CART,
|
|
29
|
+
lines: flattenConnection(CART_WITH_LINES.lines),
|
|
30
|
+
};
|
|
31
|
+
export const CART_ACTIONS = {
|
|
32
|
+
// @ts-ignore
|
|
33
|
+
lines: [],
|
|
34
|
+
attributes: [],
|
|
35
|
+
status: 'idle',
|
|
36
|
+
cartCreate: () => { },
|
|
37
|
+
linesAdd: () => { },
|
|
38
|
+
linesRemove: () => { },
|
|
39
|
+
linesUpdate: () => { },
|
|
40
|
+
noteUpdate: () => { },
|
|
41
|
+
buyerIdentityUpdate: () => { },
|
|
42
|
+
cartAttributesUpdate: () => { },
|
|
43
|
+
discountCodesUpdate: () => { },
|
|
44
|
+
totalQuantity: CART_WITH_LINES_FLATTENED.lines.reduce((prev, curr) => {
|
|
45
|
+
return prev + (curr?.quantity ?? 0);
|
|
46
|
+
}, 0),
|
|
47
|
+
cartFragment: defaultCartFragment,
|
|
48
|
+
};
|
|
49
|
+
// @ts-ignore
|
|
50
|
+
export const CART_WITH_ACTIONS = {
|
|
51
|
+
...CART_ACTIONS,
|
|
52
|
+
...CART_WITH_LINES_FLATTENED,
|
|
53
|
+
};
|
|
@@ -73,10 +73,8 @@ export function Metafield(props) {
|
|
|
73
73
|
}
|
|
74
74
|
case 'list.single_line_text_field': {
|
|
75
75
|
const Wrapper = as ?? 'ul';
|
|
76
|
-
// @ts-expect-error references currently only exists on 'unstable' SFAPI, but as soon as it does exist we can remove this ts-expect-error because I believe 'list.single_line_text_field' will also only be availabe in the same setting and we also handle if it doesn't exist
|
|
77
76
|
const refArray = parsedMetafield.references
|
|
78
|
-
?
|
|
79
|
-
flattenConnection(parsedMetafield.references)
|
|
77
|
+
? flattenConnection(parsedMetafield.references)
|
|
80
78
|
: [];
|
|
81
79
|
return (React.createElement(Wrapper, { ...passthroughProps }, refArray.map((ref, index) => (
|
|
82
80
|
// there's no unique way to identify these strings, so we do our best by combining the string with the index for the key
|
|
@@ -108,7 +108,13 @@ function useScrollRestoration({ location, pending, serverProps, scrollNeedsResto
|
|
|
108
108
|
}
|
|
109
109
|
// If there is a location hash, scroll to it
|
|
110
110
|
if (location.hash) {
|
|
111
|
-
|
|
111
|
+
let element;
|
|
112
|
+
try {
|
|
113
|
+
element = document.querySelector(location.hash);
|
|
114
|
+
}
|
|
115
|
+
catch (err) {
|
|
116
|
+
// Do nothing, hash may not be a valid selector
|
|
117
|
+
}
|
|
112
118
|
if (element) {
|
|
113
119
|
element.scrollIntoView();
|
|
114
120
|
onFinishNavigating();
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { Plugin } from 'vite';
|
|
1
|
+
import { type Plugin } from 'vite';
|
|
2
2
|
export default function cssRsc(): Plugin;
|