@shopify/cli-hydrogen 11.0.1 → 11.1.1
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/assets/hydrogen/starter/CHANGELOG.md +6 -0
- package/dist/assets/hydrogen/starter/app/components/CartSummary.tsx +30 -7
- package/dist/assets/hydrogen/starter/app/graphql/customer-account/CustomerAddressMutations.ts +7 -4
- package/dist/assets/hydrogen/starter/app/graphql/customer-account/CustomerDetailsQuery.ts +1 -1
- package/dist/assets/hydrogen/starter/app/graphql/customer-account/CustomerOrderQuery.ts +3 -1
- package/dist/assets/hydrogen/starter/app/graphql/customer-account/CustomerOrdersQuery.ts +6 -4
- package/dist/assets/hydrogen/starter/app/graphql/customer-account/CustomerUpdateMutation.ts +3 -2
- package/dist/assets/hydrogen/starter/app/routes/account.addresses.tsx +12 -3
- package/dist/assets/hydrogen/starter/app/routes/account.orders.$id.tsx +4 -1
- package/dist/assets/hydrogen/starter/app/routes/account.orders._index.tsx +1 -0
- package/dist/assets/hydrogen/starter/app/routes/account.profile.tsx +1 -0
- package/dist/assets/hydrogen/starter/app/routes/account.tsx +6 -0
- package/dist/assets/hydrogen/starter/app/routes/cart.tsx +1 -1
- package/dist/assets/hydrogen/starter/customer-accountapi.generated.d.ts +27 -13
- package/dist/assets/hydrogen/starter/package.json +4 -4
- package/dist/assets/hydrogen/starter/tsconfig.json +13 -3
- package/dist/assets/hydrogen/starter/vite.config.ts +1 -1
- package/dist/commands/hydrogen/deploy.js +15 -2
- package/dist/commands/hydrogen/upgrade.js +76 -30
- package/dist/lib/build.js +4 -1
- package/dist/lib/import-utils.js +4 -1
- package/dist/lib/onboarding/setup-template.mocks.js +4 -6
- package/dist/lib/route-validator.js +1 -1
- package/dist/lib/template-diff.js +3 -2
- package/dist/lib/vite-config.js +21 -4
- package/oclif.manifest.json +8 -1
- package/package.json +2 -2
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type {CartApiQueryFragment} from 'storefrontapi.generated';
|
|
2
2
|
import type {CartLayout} from '~/components/CartMain';
|
|
3
3
|
import {CartForm, Money, type OptimisticCart} from '@shopify/hydrogen';
|
|
4
|
-
import {useRef} from 'react';
|
|
5
|
-
import {
|
|
4
|
+
import {useEffect, useRef} from 'react';
|
|
5
|
+
import {FetcherWithComponents, useFetcher} from 'react-router';
|
|
6
6
|
|
|
7
7
|
type CartSummaryProps = {
|
|
8
8
|
cart: OptimisticCart<CartApiQueryFragment | null>;
|
|
@@ -55,28 +55,48 @@ function CartDiscounts({
|
|
|
55
55
|
?.filter((discount) => discount.applicable)
|
|
56
56
|
?.map(({code}) => code) || [];
|
|
57
57
|
|
|
58
|
+
const discountRemoveFetcher = useFetcher({key: 'discount-remove'});
|
|
59
|
+
const discountAddFetcher = useFetcher({key: 'discount-add'});
|
|
60
|
+
const discountCodeInput = useRef<HTMLInputElement>(null);
|
|
61
|
+
|
|
62
|
+
// Clear the discount code input after the discount is added
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
if (discountAddFetcher.data) {
|
|
65
|
+
discountCodeInput.current!.value = '';
|
|
66
|
+
}
|
|
67
|
+
}, [discountAddFetcher.data]);
|
|
68
|
+
|
|
58
69
|
return (
|
|
59
70
|
<div>
|
|
60
71
|
{/* Have existing discount, display it with a remove option */}
|
|
61
72
|
<dl hidden={!codes.length}>
|
|
62
73
|
<div>
|
|
63
74
|
<dt>Discount(s)</dt>
|
|
64
|
-
<UpdateDiscountForm>
|
|
75
|
+
<UpdateDiscountForm fetcherKey="discount-remove">
|
|
65
76
|
<div className="cart-discount">
|
|
66
77
|
<code>{codes?.join(', ')}</code>
|
|
67
78
|
|
|
68
|
-
<button>
|
|
79
|
+
<button disabled={discountRemoveFetcher.state !== 'idle'}>
|
|
80
|
+
Remove
|
|
81
|
+
</button>
|
|
69
82
|
</div>
|
|
70
83
|
</UpdateDiscountForm>
|
|
71
84
|
</div>
|
|
72
85
|
</dl>
|
|
73
86
|
|
|
74
87
|
{/* Show an input to apply a discount */}
|
|
75
|
-
<UpdateDiscountForm discountCodes={codes}>
|
|
88
|
+
<UpdateDiscountForm discountCodes={codes} fetcherKey="discount-add">
|
|
76
89
|
<div>
|
|
77
|
-
<input
|
|
90
|
+
<input
|
|
91
|
+
type="text"
|
|
92
|
+
name="discountCode"
|
|
93
|
+
placeholder="Discount code"
|
|
94
|
+
ref={discountCodeInput}
|
|
95
|
+
/>
|
|
78
96
|
|
|
79
|
-
<button type="submit">
|
|
97
|
+
<button type="submit" disabled={discountAddFetcher.state !== 'idle'}>
|
|
98
|
+
Apply
|
|
99
|
+
</button>
|
|
80
100
|
</div>
|
|
81
101
|
</UpdateDiscountForm>
|
|
82
102
|
</div>
|
|
@@ -86,12 +106,15 @@ function CartDiscounts({
|
|
|
86
106
|
function UpdateDiscountForm({
|
|
87
107
|
discountCodes,
|
|
88
108
|
children,
|
|
109
|
+
fetcherKey,
|
|
89
110
|
}: {
|
|
90
111
|
discountCodes?: string[];
|
|
91
112
|
children: React.ReactNode;
|
|
113
|
+
fetcherKey?: string;
|
|
92
114
|
}) {
|
|
93
115
|
return (
|
|
94
116
|
<CartForm
|
|
117
|
+
fetcherKey={fetcherKey}
|
|
95
118
|
route="/cart"
|
|
96
119
|
action={CartForm.ACTIONS.DiscountCodesUpdate}
|
|
97
120
|
inputs={{
|
package/dist/assets/hydrogen/starter/app/graphql/customer-account/CustomerAddressMutations.ts
CHANGED
|
@@ -4,7 +4,8 @@ export const UPDATE_ADDRESS_MUTATION = `#graphql
|
|
|
4
4
|
$address: CustomerAddressInput!
|
|
5
5
|
$addressId: ID!
|
|
6
6
|
$defaultAddress: Boolean
|
|
7
|
-
|
|
7
|
+
$language: LanguageCode
|
|
8
|
+
) @inContext(language: $language) {
|
|
8
9
|
customerAddressUpdate(
|
|
9
10
|
address: $address
|
|
10
11
|
addressId: $addressId
|
|
@@ -25,8 +26,9 @@ export const UPDATE_ADDRESS_MUTATION = `#graphql
|
|
|
25
26
|
// NOTE: https://shopify.dev/docs/api/customer/latest/mutations/customerAddressDelete
|
|
26
27
|
export const DELETE_ADDRESS_MUTATION = `#graphql
|
|
27
28
|
mutation customerAddressDelete(
|
|
28
|
-
$addressId: ID
|
|
29
|
-
|
|
29
|
+
$addressId: ID!
|
|
30
|
+
$language: LanguageCode
|
|
31
|
+
) @inContext(language: $language) {
|
|
30
32
|
customerAddressDelete(addressId: $addressId) {
|
|
31
33
|
deletedAddressId
|
|
32
34
|
userErrors {
|
|
@@ -43,7 +45,8 @@ export const CREATE_ADDRESS_MUTATION = `#graphql
|
|
|
43
45
|
mutation customerAddressCreate(
|
|
44
46
|
$address: CustomerAddressInput!
|
|
45
47
|
$defaultAddress: Boolean
|
|
46
|
-
|
|
48
|
+
$language: LanguageCode
|
|
49
|
+
) @inContext(language: $language) {
|
|
47
50
|
customerAddressCreate(
|
|
48
51
|
address: $address
|
|
49
52
|
defaultAddress: $defaultAddress
|
|
@@ -31,7 +31,7 @@ export const CUSTOMER_FRAGMENT = `#graphql
|
|
|
31
31
|
|
|
32
32
|
// NOTE: https://shopify.dev/docs/api/customer/latest/queries/customer
|
|
33
33
|
export const CUSTOMER_DETAILS_QUERY = `#graphql
|
|
34
|
-
query CustomerDetails {
|
|
34
|
+
query CustomerDetails($language: LanguageCode) @inContext(language: $language) {
|
|
35
35
|
customer {
|
|
36
36
|
...Customer
|
|
37
37
|
}
|
|
@@ -46,6 +46,7 @@ export const CUSTOMER_ORDER_QUERY = `#graphql
|
|
|
46
46
|
id
|
|
47
47
|
name
|
|
48
48
|
statusPageUrl
|
|
49
|
+
fulfillmentStatus
|
|
49
50
|
processedAt
|
|
50
51
|
fulfillments(first: 1) {
|
|
51
52
|
nodes {
|
|
@@ -77,7 +78,8 @@ export const CUSTOMER_ORDER_QUERY = `#graphql
|
|
|
77
78
|
}
|
|
78
79
|
}
|
|
79
80
|
}
|
|
80
|
-
query Order($orderId: ID
|
|
81
|
+
query Order($orderId: ID!, $language: LanguageCode)
|
|
82
|
+
@inContext(language: $language) {
|
|
81
83
|
order(id: $orderId) {
|
|
82
84
|
... on Order {
|
|
83
85
|
...Order
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// https://shopify.dev/docs/api/customer/latest/objects/Order
|
|
1
|
+
// NOTE: https://shopify.dev/docs/api/customer/latest/objects/Order
|
|
2
2
|
export const ORDER_ITEM_FRAGMENT = `#graphql
|
|
3
3
|
fragment OrderItem on Order {
|
|
4
4
|
totalPrice {
|
|
@@ -6,6 +6,7 @@ export const ORDER_ITEM_FRAGMENT = `#graphql
|
|
|
6
6
|
currencyCode
|
|
7
7
|
}
|
|
8
8
|
financialStatus
|
|
9
|
+
fulfillmentStatus
|
|
9
10
|
fulfillments(first: 1) {
|
|
10
11
|
nodes {
|
|
11
12
|
status
|
|
@@ -17,7 +18,7 @@ export const ORDER_ITEM_FRAGMENT = `#graphql
|
|
|
17
18
|
}
|
|
18
19
|
` as const;
|
|
19
20
|
|
|
20
|
-
// https://shopify.dev/docs/api/customer/latest/objects/Customer
|
|
21
|
+
// NOTE: https://shopify.dev/docs/api/customer/latest/objects/Customer
|
|
21
22
|
export const CUSTOMER_ORDERS_FRAGMENT = `#graphql
|
|
22
23
|
fragment CustomerOrders on Customer {
|
|
23
24
|
orders(
|
|
@@ -42,7 +43,7 @@ export const CUSTOMER_ORDERS_FRAGMENT = `#graphql
|
|
|
42
43
|
${ORDER_ITEM_FRAGMENT}
|
|
43
44
|
` as const;
|
|
44
45
|
|
|
45
|
-
// https://shopify.dev/docs/api/customer/latest/queries/customer
|
|
46
|
+
// NOTE: https://shopify.dev/docs/api/customer/latest/queries/customer
|
|
46
47
|
export const CUSTOMER_ORDERS_QUERY = `#graphql
|
|
47
48
|
${CUSTOMER_ORDERS_FRAGMENT}
|
|
48
49
|
query CustomerOrders(
|
|
@@ -50,7 +51,8 @@ export const CUSTOMER_ORDERS_QUERY = `#graphql
|
|
|
50
51
|
$first: Int
|
|
51
52
|
$last: Int
|
|
52
53
|
$startCursor: String
|
|
53
|
-
|
|
54
|
+
$language: LanguageCode
|
|
55
|
+
) @inContext(language: $language) {
|
|
54
56
|
customer {
|
|
55
57
|
...CustomerOrders
|
|
56
58
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
// NOTE: https://shopify.dev/docs/api/customer/latest/mutations/customerUpdate
|
|
1
2
|
export const CUSTOMER_UPDATE_MUTATION = `#graphql
|
|
2
|
-
# https://shopify.dev/docs/api/customer/latest/mutations/customerUpdate
|
|
3
3
|
mutation customerUpdate(
|
|
4
4
|
$customer: CustomerUpdateInput!
|
|
5
|
-
|
|
5
|
+
$language: LanguageCode
|
|
6
|
+
) @inContext(language: $language) {
|
|
6
7
|
customerUpdate(input: $customer) {
|
|
7
8
|
customer {
|
|
8
9
|
firstName
|
|
@@ -42,7 +42,8 @@ export async function loader({context}: LoaderFunctionArgs) {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
export async function action({request, context}: ActionFunctionArgs) {
|
|
45
|
-
const {customerAccount} = context;
|
|
45
|
+
const {customerAccount, storefront} = context;
|
|
46
|
+
const {i18n} = storefront;
|
|
46
47
|
|
|
47
48
|
try {
|
|
48
49
|
const form = await request.formData();
|
|
@@ -96,7 +97,11 @@ export async function action({request, context}: ActionFunctionArgs) {
|
|
|
96
97
|
const {data, errors} = await customerAccount.mutate(
|
|
97
98
|
CREATE_ADDRESS_MUTATION,
|
|
98
99
|
{
|
|
99
|
-
variables: {
|
|
100
|
+
variables: {
|
|
101
|
+
address,
|
|
102
|
+
defaultAddress,
|
|
103
|
+
language: i18n.language,
|
|
104
|
+
},
|
|
100
105
|
},
|
|
101
106
|
);
|
|
102
107
|
|
|
@@ -145,6 +150,7 @@ export async function action({request, context}: ActionFunctionArgs) {
|
|
|
145
150
|
address,
|
|
146
151
|
addressId: decodeURIComponent(addressId),
|
|
147
152
|
defaultAddress,
|
|
153
|
+
language: i18n.language,
|
|
148
154
|
},
|
|
149
155
|
},
|
|
150
156
|
);
|
|
@@ -190,7 +196,10 @@ export async function action({request, context}: ActionFunctionArgs) {
|
|
|
190
196
|
const {data, errors} = await customerAccount.mutate(
|
|
191
197
|
DELETE_ADDRESS_MUTATION,
|
|
192
198
|
{
|
|
193
|
-
variables: {
|
|
199
|
+
variables: {
|
|
200
|
+
addressId: decodeURIComponent(addressId),
|
|
201
|
+
language: i18n.language,
|
|
202
|
+
},
|
|
194
203
|
},
|
|
195
204
|
);
|
|
196
205
|
|
|
@@ -17,7 +17,10 @@ export async function loader({params, context}: LoaderFunctionArgs) {
|
|
|
17
17
|
const {data, errors} = await context.customerAccount.query(
|
|
18
18
|
CUSTOMER_ORDER_QUERY,
|
|
19
19
|
{
|
|
20
|
-
variables: {
|
|
20
|
+
variables: {
|
|
21
|
+
orderId,
|
|
22
|
+
language: context.storefront.i18n.language,
|
|
23
|
+
},
|
|
21
24
|
},
|
|
22
25
|
);
|
|
23
26
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
|
|
1
2
|
import {data as remixData, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
|
|
2
3
|
import { Form, NavLink, Outlet, useLoaderData } from 'react-router';
|
|
3
4
|
import {CUSTOMER_DETAILS_QUERY} from '~/graphql/customer-account/CustomerDetailsQuery';
|
|
@@ -9,6 +10,11 @@ export function shouldRevalidate() {
|
|
|
9
10
|
export async function loader({context}: LoaderFunctionArgs) {
|
|
10
11
|
const {data, errors} = await context.customerAccount.query(
|
|
11
12
|
CUSTOMER_DETAILS_QUERY,
|
|
13
|
+
{
|
|
14
|
+
variables: {
|
|
15
|
+
language: context.storefront.i18n.language,
|
|
16
|
+
},
|
|
17
|
+
},
|
|
12
18
|
);
|
|
13
19
|
|
|
14
20
|
if (errors?.length || !data?.customer) {
|
|
@@ -9,6 +9,7 @@ export type CustomerAddressUpdateMutationVariables = CustomerAccountAPI.Exact<{
|
|
|
9
9
|
defaultAddress?: CustomerAccountAPI.InputMaybe<
|
|
10
10
|
CustomerAccountAPI.Scalars['Boolean']['input']
|
|
11
11
|
>;
|
|
12
|
+
language?: CustomerAccountAPI.InputMaybe<CustomerAccountAPI.LanguageCode>;
|
|
12
13
|
}>;
|
|
13
14
|
|
|
14
15
|
export type CustomerAddressUpdateMutation = {
|
|
@@ -27,6 +28,7 @@ export type CustomerAddressUpdateMutation = {
|
|
|
27
28
|
|
|
28
29
|
export type CustomerAddressDeleteMutationVariables = CustomerAccountAPI.Exact<{
|
|
29
30
|
addressId: CustomerAccountAPI.Scalars['ID']['input'];
|
|
31
|
+
language?: CustomerAccountAPI.InputMaybe<CustomerAccountAPI.LanguageCode>;
|
|
30
32
|
}>;
|
|
31
33
|
|
|
32
34
|
export type CustomerAddressDeleteMutation = {
|
|
@@ -50,6 +52,7 @@ export type CustomerAddressCreateMutationVariables = CustomerAccountAPI.Exact<{
|
|
|
50
52
|
defaultAddress?: CustomerAccountAPI.InputMaybe<
|
|
51
53
|
CustomerAccountAPI.Scalars['Boolean']['input']
|
|
52
54
|
>;
|
|
55
|
+
language?: CustomerAccountAPI.InputMaybe<CustomerAccountAPI.LanguageCode>;
|
|
53
56
|
}>;
|
|
54
57
|
|
|
55
58
|
export type CustomerAddressCreateMutation = {
|
|
@@ -125,7 +128,7 @@ export type AddressFragment = Pick<
|
|
|
125
128
|
>;
|
|
126
129
|
|
|
127
130
|
export type CustomerDetailsQueryVariables = CustomerAccountAPI.Exact<{
|
|
128
|
-
|
|
131
|
+
language?: CustomerAccountAPI.InputMaybe<CustomerAccountAPI.LanguageCode>;
|
|
129
132
|
}>;
|
|
130
133
|
|
|
131
134
|
export type CustomerDetailsQuery = {
|
|
@@ -224,7 +227,7 @@ export type OrderLineItemFullFragment = Pick<
|
|
|
224
227
|
|
|
225
228
|
export type OrderFragment = Pick<
|
|
226
229
|
CustomerAccountAPI.Order,
|
|
227
|
-
'id' | 'name' | 'statusPageUrl' | 'processedAt'
|
|
230
|
+
'id' | 'name' | 'statusPageUrl' | 'fulfillmentStatus' | 'processedAt'
|
|
228
231
|
> & {
|
|
229
232
|
fulfillments: {nodes: Array<Pick<CustomerAccountAPI.Fulfillment, 'status'>>};
|
|
230
233
|
totalTax?: CustomerAccountAPI.Maybe<
|
|
@@ -296,13 +299,14 @@ export type OrderFragment = Pick<
|
|
|
296
299
|
|
|
297
300
|
export type OrderQueryVariables = CustomerAccountAPI.Exact<{
|
|
298
301
|
orderId: CustomerAccountAPI.Scalars['ID']['input'];
|
|
302
|
+
language?: CustomerAccountAPI.InputMaybe<CustomerAccountAPI.LanguageCode>;
|
|
299
303
|
}>;
|
|
300
304
|
|
|
301
305
|
export type OrderQuery = {
|
|
302
306
|
order?: CustomerAccountAPI.Maybe<
|
|
303
307
|
Pick<
|
|
304
308
|
CustomerAccountAPI.Order,
|
|
305
|
-
'id' | 'name' | 'statusPageUrl' | 'processedAt'
|
|
309
|
+
'id' | 'name' | 'statusPageUrl' | 'fulfillmentStatus' | 'processedAt'
|
|
306
310
|
> & {
|
|
307
311
|
fulfillments: {
|
|
308
312
|
nodes: Array<Pick<CustomerAccountAPI.Fulfillment, 'status'>>;
|
|
@@ -378,7 +382,7 @@ export type OrderQuery = {
|
|
|
378
382
|
|
|
379
383
|
export type OrderItemFragment = Pick<
|
|
380
384
|
CustomerAccountAPI.Order,
|
|
381
|
-
'financialStatus' | 'id' | 'number' | 'processedAt'
|
|
385
|
+
'financialStatus' | 'fulfillmentStatus' | 'id' | 'number' | 'processedAt'
|
|
382
386
|
> & {
|
|
383
387
|
totalPrice: Pick<CustomerAccountAPI.MoneyV2, 'amount' | 'currencyCode'>;
|
|
384
388
|
fulfillments: {nodes: Array<Pick<CustomerAccountAPI.Fulfillment, 'status'>>};
|
|
@@ -389,7 +393,11 @@ export type CustomerOrdersFragment = {
|
|
|
389
393
|
nodes: Array<
|
|
390
394
|
Pick<
|
|
391
395
|
CustomerAccountAPI.Order,
|
|
392
|
-
|
|
396
|
+
| 'financialStatus'
|
|
397
|
+
| 'fulfillmentStatus'
|
|
398
|
+
| 'id'
|
|
399
|
+
| 'number'
|
|
400
|
+
| 'processedAt'
|
|
393
401
|
> & {
|
|
394
402
|
totalPrice: Pick<CustomerAccountAPI.MoneyV2, 'amount' | 'currencyCode'>;
|
|
395
403
|
fulfillments: {
|
|
@@ -417,6 +425,7 @@ export type CustomerOrdersQueryVariables = CustomerAccountAPI.Exact<{
|
|
|
417
425
|
startCursor?: CustomerAccountAPI.InputMaybe<
|
|
418
426
|
CustomerAccountAPI.Scalars['String']['input']
|
|
419
427
|
>;
|
|
428
|
+
language?: CustomerAccountAPI.InputMaybe<CustomerAccountAPI.LanguageCode>;
|
|
420
429
|
}>;
|
|
421
430
|
|
|
422
431
|
export type CustomerOrdersQuery = {
|
|
@@ -425,7 +434,11 @@ export type CustomerOrdersQuery = {
|
|
|
425
434
|
nodes: Array<
|
|
426
435
|
Pick<
|
|
427
436
|
CustomerAccountAPI.Order,
|
|
428
|
-
|
|
437
|
+
| 'financialStatus'
|
|
438
|
+
| 'fulfillmentStatus'
|
|
439
|
+
| 'id'
|
|
440
|
+
| 'number'
|
|
441
|
+
| 'processedAt'
|
|
429
442
|
> & {
|
|
430
443
|
totalPrice: Pick<
|
|
431
444
|
CustomerAccountAPI.MoneyV2,
|
|
@@ -446,6 +459,7 @@ export type CustomerOrdersQuery = {
|
|
|
446
459
|
|
|
447
460
|
export type CustomerUpdateMutationVariables = CustomerAccountAPI.Exact<{
|
|
448
461
|
customer: CustomerAccountAPI.CustomerUpdateInput;
|
|
462
|
+
language?: CustomerAccountAPI.InputMaybe<CustomerAccountAPI.LanguageCode>;
|
|
449
463
|
}>;
|
|
450
464
|
|
|
451
465
|
export type CustomerUpdateMutation = {
|
|
@@ -470,34 +484,34 @@ export type CustomerUpdateMutation = {
|
|
|
470
484
|
};
|
|
471
485
|
|
|
472
486
|
interface GeneratedQueryTypes {
|
|
473
|
-
'#graphql\n query CustomerDetails {\n customer {\n ...Customer\n }\n }\n #graphql\n fragment Customer on Customer {\n id\n firstName\n lastName\n defaultAddress {\n ...Address\n }\n addresses(first: 6) {\n nodes {\n ...Address\n }\n }\n }\n fragment Address on CustomerAddress {\n id\n formatted\n firstName\n lastName\n company\n address1\n address2\n territoryCode\n zoneCode\n city\n zip\n phoneNumber\n }\n\n': {
|
|
487
|
+
'#graphql\n query CustomerDetails($language: LanguageCode) @inContext(language: $language) {\n customer {\n ...Customer\n }\n }\n #graphql\n fragment Customer on Customer {\n id\n firstName\n lastName\n defaultAddress {\n ...Address\n }\n addresses(first: 6) {\n nodes {\n ...Address\n }\n }\n }\n fragment Address on CustomerAddress {\n id\n formatted\n firstName\n lastName\n company\n address1\n address2\n territoryCode\n zoneCode\n city\n zip\n phoneNumber\n }\n\n': {
|
|
474
488
|
return: CustomerDetailsQuery;
|
|
475
489
|
variables: CustomerDetailsQueryVariables;
|
|
476
490
|
};
|
|
477
|
-
'#graphql\n fragment OrderMoney on MoneyV2 {\n amount\n currencyCode\n }\n fragment DiscountApplication on DiscountApplication {\n value {\n __typename\n ... on MoneyV2 {\n ...OrderMoney\n }\n ... on PricingPercentageValue {\n percentage\n }\n }\n }\n fragment OrderLineItemFull on LineItem {\n id\n title\n quantity\n price {\n ...OrderMoney\n }\n discountAllocations {\n allocatedAmount {\n ...OrderMoney\n }\n discountApplication {\n ...DiscountApplication\n }\n }\n totalDiscount {\n ...OrderMoney\n }\n image {\n altText\n height\n url\n id\n width\n }\n variantTitle\n }\n fragment Order on Order {\n id\n name\n statusPageUrl\n processedAt\n fulfillments(first: 1) {\n nodes {\n status\n }\n }\n totalTax {\n ...OrderMoney\n }\n totalPrice {\n ...OrderMoney\n }\n subtotal {\n ...OrderMoney\n }\n shippingAddress {\n name\n formatted(withName: true)\n formattedArea\n }\n discountApplications(first: 100) {\n nodes {\n ...DiscountApplication\n }\n }\n lineItems(first: 100) {\n nodes {\n ...OrderLineItemFull\n }\n }\n }\n query Order($orderId: ID
|
|
491
|
+
'#graphql\n fragment OrderMoney on MoneyV2 {\n amount\n currencyCode\n }\n fragment DiscountApplication on DiscountApplication {\n value {\n __typename\n ... on MoneyV2 {\n ...OrderMoney\n }\n ... on PricingPercentageValue {\n percentage\n }\n }\n }\n fragment OrderLineItemFull on LineItem {\n id\n title\n quantity\n price {\n ...OrderMoney\n }\n discountAllocations {\n allocatedAmount {\n ...OrderMoney\n }\n discountApplication {\n ...DiscountApplication\n }\n }\n totalDiscount {\n ...OrderMoney\n }\n image {\n altText\n height\n url\n id\n width\n }\n variantTitle\n }\n fragment Order on Order {\n id\n name\n statusPageUrl\n fulfillmentStatus\n processedAt\n fulfillments(first: 1) {\n nodes {\n status\n }\n }\n totalTax {\n ...OrderMoney\n }\n totalPrice {\n ...OrderMoney\n }\n subtotal {\n ...OrderMoney\n }\n shippingAddress {\n name\n formatted(withName: true)\n formattedArea\n }\n discountApplications(first: 100) {\n nodes {\n ...DiscountApplication\n }\n }\n lineItems(first: 100) {\n nodes {\n ...OrderLineItemFull\n }\n }\n }\n query Order($orderId: ID!, $language: LanguageCode)\n @inContext(language: $language) {\n order(id: $orderId) {\n ... on Order {\n ...Order\n }\n }\n }\n': {
|
|
478
492
|
return: OrderQuery;
|
|
479
493
|
variables: OrderQueryVariables;
|
|
480
494
|
};
|
|
481
|
-
'#graphql\n #graphql\n fragment CustomerOrders on Customer {\n orders(\n sortKey: PROCESSED_AT,\n reverse: true,\n first: $first,\n last: $last,\n before: $startCursor,\n after: $endCursor\n ) {\n nodes {\n ...OrderItem\n }\n pageInfo {\n hasPreviousPage\n hasNextPage\n endCursor\n startCursor\n }\n }\n }\n #graphql\n fragment OrderItem on Order {\n totalPrice {\n amount\n currencyCode\n }\n financialStatus\n fulfillments(first: 1) {\n nodes {\n status\n }\n }\n id\n number\n processedAt\n }\n\n\n query CustomerOrders(\n $endCursor: String\n $first: Int\n $last: Int\n $startCursor: String\n ) {\n customer {\n ...CustomerOrders\n }\n }\n': {
|
|
495
|
+
'#graphql\n #graphql\n fragment CustomerOrders on Customer {\n orders(\n sortKey: PROCESSED_AT,\n reverse: true,\n first: $first,\n last: $last,\n before: $startCursor,\n after: $endCursor\n ) {\n nodes {\n ...OrderItem\n }\n pageInfo {\n hasPreviousPage\n hasNextPage\n endCursor\n startCursor\n }\n }\n }\n #graphql\n fragment OrderItem on Order {\n totalPrice {\n amount\n currencyCode\n }\n financialStatus\n fulfillmentStatus\n fulfillments(first: 1) {\n nodes {\n status\n }\n }\n id\n number\n processedAt\n }\n\n\n query CustomerOrders(\n $endCursor: String\n $first: Int\n $last: Int\n $startCursor: String\n $language: LanguageCode\n ) @inContext(language: $language) {\n customer {\n ...CustomerOrders\n }\n }\n': {
|
|
482
496
|
return: CustomerOrdersQuery;
|
|
483
497
|
variables: CustomerOrdersQueryVariables;
|
|
484
498
|
};
|
|
485
499
|
}
|
|
486
500
|
|
|
487
501
|
interface GeneratedMutationTypes {
|
|
488
|
-
'#graphql\n mutation customerAddressUpdate(\n $address: CustomerAddressInput!\n $addressId: ID!\n $defaultAddress: Boolean\n ) {\n customerAddressUpdate(\n address: $address\n addressId: $addressId\n defaultAddress: $defaultAddress\n ) {\n customerAddress {\n id\n }\n userErrors {\n code\n field\n message\n }\n }\n }\n': {
|
|
502
|
+
'#graphql\n mutation customerAddressUpdate(\n $address: CustomerAddressInput!\n $addressId: ID!\n $defaultAddress: Boolean\n $language: LanguageCode\n ) @inContext(language: $language) {\n customerAddressUpdate(\n address: $address\n addressId: $addressId\n defaultAddress: $defaultAddress\n ) {\n customerAddress {\n id\n }\n userErrors {\n code\n field\n message\n }\n }\n }\n': {
|
|
489
503
|
return: CustomerAddressUpdateMutation;
|
|
490
504
|
variables: CustomerAddressUpdateMutationVariables;
|
|
491
505
|
};
|
|
492
|
-
'#graphql\n mutation customerAddressDelete(\n $addressId: ID
|
|
506
|
+
'#graphql\n mutation customerAddressDelete(\n $addressId: ID!\n $language: LanguageCode\n ) @inContext(language: $language) {\n customerAddressDelete(addressId: $addressId) {\n deletedAddressId\n userErrors {\n code\n field\n message\n }\n }\n }\n': {
|
|
493
507
|
return: CustomerAddressDeleteMutation;
|
|
494
508
|
variables: CustomerAddressDeleteMutationVariables;
|
|
495
509
|
};
|
|
496
|
-
'#graphql\n mutation customerAddressCreate(\n $address: CustomerAddressInput!\n $defaultAddress: Boolean\n ) {\n customerAddressCreate(\n address: $address\n defaultAddress: $defaultAddress\n ) {\n customerAddress {\n id\n }\n userErrors {\n code\n field\n message\n }\n }\n }\n': {
|
|
510
|
+
'#graphql\n mutation customerAddressCreate(\n $address: CustomerAddressInput!\n $defaultAddress: Boolean\n $language: LanguageCode\n ) @inContext(language: $language) {\n customerAddressCreate(\n address: $address\n defaultAddress: $defaultAddress\n ) {\n customerAddress {\n id\n }\n userErrors {\n code\n field\n message\n }\n }\n }\n': {
|
|
497
511
|
return: CustomerAddressCreateMutation;
|
|
498
512
|
variables: CustomerAddressCreateMutationVariables;
|
|
499
513
|
};
|
|
500
|
-
'#graphql\n
|
|
514
|
+
'#graphql\n mutation customerUpdate(\n $customer: CustomerUpdateInput!\n $language: LanguageCode\n ) @inContext(language: $language) {\n customerUpdate(input: $customer) {\n customer {\n firstName\n lastName\n emailAddress {\n emailAddress\n }\n phoneNumber {\n phoneNumber\n }\n }\n userErrors {\n code\n field\n message\n }\n }\n }\n': {
|
|
501
515
|
return: CustomerUpdateMutation;
|
|
502
516
|
variables: CustomerUpdateMutationVariables;
|
|
503
517
|
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "skeleton",
|
|
3
3
|
"private": true,
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "2025.5.
|
|
5
|
+
"version": "2025.5.2",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"build": "shopify hydrogen build --codegen",
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"isbot": "^5.1.22",
|
|
22
22
|
"react": "^18.2.0",
|
|
23
23
|
"react-dom": "^18.2.0",
|
|
24
|
-
"react-router": "7.6.0",
|
|
25
|
-
"react-router-dom": "7.6.0"
|
|
24
|
+
"react-router": "^7.6.0",
|
|
25
|
+
"react-router-dom": "^7.6.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@eslint/compat": "^1.2.5",
|
|
@@ -60,4 +60,4 @@
|
|
|
60
60
|
"engines": {
|
|
61
61
|
"node": ">=18.0.0"
|
|
62
62
|
}
|
|
63
|
-
}
|
|
63
|
+
}
|
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"include": [
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"env.d.ts",
|
|
4
|
+
"app/**/*.ts",
|
|
5
|
+
"app/**/*.tsx",
|
|
6
|
+
"app/**/*.d.ts",
|
|
7
|
+
"*.ts",
|
|
8
|
+
"*.tsx",
|
|
9
|
+
"*.d.ts",
|
|
6
10
|
".react-router/types/**/*"
|
|
7
11
|
],
|
|
12
|
+
"exclude": [
|
|
13
|
+
"node_modules",
|
|
14
|
+
"dist",
|
|
15
|
+
"build",
|
|
16
|
+
"packages/**/dist/**/*"
|
|
17
|
+
],
|
|
8
18
|
"compilerOptions": {
|
|
9
19
|
"lib": [
|
|
10
20
|
"DOM",
|
|
@@ -7,7 +7,7 @@ import { AbortError } from '@shopify/cli-kit/node/error';
|
|
|
7
7
|
import { writeFile } from '@shopify/cli-kit/node/fs';
|
|
8
8
|
import { ensureIsClean, getLatestGitCommit, GitDirectoryNotCleanError } from '@shopify/cli-kit/node/git';
|
|
9
9
|
import { resolvePath, relativePath } from '@shopify/cli-kit/node/path';
|
|
10
|
-
import { renderWarning, renderSelectPrompt, renderConfirmationPrompt, renderSuccess, renderTasks } from '@shopify/cli-kit/node/ui';
|
|
10
|
+
import { renderWarning, renderSelectPrompt, renderConfirmationPrompt, renderInfo, renderSuccess, renderTasks } from '@shopify/cli-kit/node/ui';
|
|
11
11
|
import { ciPlatform } from '@shopify/cli-kit/node/context/local';
|
|
12
12
|
import { parseToken, createDeploy } from '@shopify/oxygen-cli/deploy';
|
|
13
13
|
import { createRequire } from 'node:module';
|
|
@@ -109,7 +109,11 @@ class Deploy extends Command {
|
|
|
109
109
|
env: "SHOPIFY_HYDROGEN_FLAG_METADATA_VERSION",
|
|
110
110
|
hidden: true
|
|
111
111
|
}),
|
|
112
|
-
...commonFlags.diff
|
|
112
|
+
...commonFlags.diff,
|
|
113
|
+
"force-client-sourcemap": Flags.boolean({
|
|
114
|
+
description: "Client sourcemapping is avoided by default because it makes backend code visible in the browser. Use this flag to force enabling it.",
|
|
115
|
+
env: "SHOPIFY_HYDROGEN_FLAG_FORCE_CLIENT_SOURCEMAP"
|
|
116
|
+
})
|
|
113
117
|
};
|
|
114
118
|
async run() {
|
|
115
119
|
const { flags } = await this.parse(Deploy);
|
|
@@ -160,6 +164,7 @@ async function runDeploy(options) {
|
|
|
160
164
|
envBranch,
|
|
161
165
|
environmentFile,
|
|
162
166
|
force: forceOnUncommitedChanges,
|
|
167
|
+
forceClientSourcemap = false,
|
|
163
168
|
noVerify,
|
|
164
169
|
lockfileCheck,
|
|
165
170
|
jsonOutput,
|
|
@@ -434,6 +439,13 @@ Continue?`.value
|
|
|
434
439
|
}
|
|
435
440
|
};
|
|
436
441
|
if (buildCommand) {
|
|
442
|
+
if (forceClientSourcemap) {
|
|
443
|
+
console.log("");
|
|
444
|
+
renderInfo({
|
|
445
|
+
headline: "The `--force-client-sourcemap` flag is not supported with a custom build command",
|
|
446
|
+
body: "Client sourcemaps will not be generated."
|
|
447
|
+
});
|
|
448
|
+
}
|
|
437
449
|
config.buildCommand = buildCommand;
|
|
438
450
|
} else {
|
|
439
451
|
hooks.buildFunction = async (assetPath) => {
|
|
@@ -448,6 +460,7 @@ Continue?`.value
|
|
|
448
460
|
assetPath,
|
|
449
461
|
lockfileCheck,
|
|
450
462
|
sourcemap: true,
|
|
463
|
+
forceClientSourcemap,
|
|
451
464
|
useCodegen: false,
|
|
452
465
|
entry: ssrEntry
|
|
453
466
|
});
|
|
@@ -6,7 +6,8 @@ import { ensureInsideGitDirectory, isClean } from '@shopify/cli-kit/node/git';
|
|
|
6
6
|
import Command from '@shopify/cli-kit/node/base-command';
|
|
7
7
|
import { renderSuccess, renderInfo, renderConfirmationPrompt, renderTasks, renderSelectPrompt, renderWarning } from '@shopify/cli-kit/node/ui';
|
|
8
8
|
import { readFile, isDirectory, mkdir, fileExists, touchFile, removeFile, writeFile } from '@shopify/cli-kit/node/fs';
|
|
9
|
-
import {
|
|
9
|
+
import { getPackageManager, getDependencies, installNodeModules } from '@shopify/cli-kit/node/node-package-manager';
|
|
10
|
+
import { exec } from '@shopify/cli-kit/node/system';
|
|
10
11
|
import { AbortError } from '@shopify/cli-kit/node/error';
|
|
11
12
|
import { resolvePath, joinPath, dirname } from '@shopify/cli-kit/node/path';
|
|
12
13
|
import { getCliCommand } from '../../lib/shell.js';
|
|
@@ -155,11 +156,25 @@ async function getHydrogenVersion({ appPath }) {
|
|
|
155
156
|
}
|
|
156
157
|
async function getChangelog() {
|
|
157
158
|
if (CACHED_CHANGELOG) return CACHED_CHANGELOG;
|
|
158
|
-
if (isHydrogenMonorepo && hydrogenPackagesPath && process.env.FORCE_CHANGELOG_SOURCE !== "remote") {
|
|
159
|
+
if (process.env.FORCE_CHANGELOG_SOURCE === "local" || isHydrogenMonorepo && hydrogenPackagesPath && process.env.FORCE_CHANGELOG_SOURCE !== "remote") {
|
|
159
160
|
const require2 = createRequire(import.meta.url);
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
161
|
+
const localChangelogPath = isHydrogenMonorepo && hydrogenPackagesPath ? joinPath(dirname(hydrogenPackagesPath), "docs", "changelog.json") : joinPath(process.cwd(), "docs", "changelog.json");
|
|
162
|
+
try {
|
|
163
|
+
const changelog = require2(localChangelogPath);
|
|
164
|
+
CACHED_CHANGELOG = changelog;
|
|
165
|
+
return changelog;
|
|
166
|
+
} catch (error) {
|
|
167
|
+
console.warn(
|
|
168
|
+
`Failed to load local changelog from ${localChangelogPath}:`,
|
|
169
|
+
error.message
|
|
170
|
+
);
|
|
171
|
+
if (process.env.FORCE_CHANGELOG_SOURCE === "local") {
|
|
172
|
+
throw new AbortError(
|
|
173
|
+
"Failed to load local changelog",
|
|
174
|
+
`Could not read changelog from ${localChangelogPath}`
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
163
178
|
}
|
|
164
179
|
try {
|
|
165
180
|
const response = await fetch("https://hydrogen.shopify.dev/changelog.json");
|
|
@@ -394,8 +409,8 @@ function buildUpgradeCommandArgs({
|
|
|
394
409
|
const selectedReactRouter = Object.entries(selectedRelease.dependencies).find(
|
|
395
410
|
isReactRouterDependency
|
|
396
411
|
);
|
|
397
|
-
if (
|
|
398
|
-
const shouldUpgradeReactRouter = semver.lt(
|
|
412
|
+
if (selectedReactRouter) {
|
|
413
|
+
const shouldUpgradeReactRouter = !currentReactRouter || semver.lt(
|
|
399
414
|
getAbsoluteVersion(currentReactRouter[1]),
|
|
400
415
|
getAbsoluteVersion(selectedReactRouter[1])
|
|
401
416
|
);
|
|
@@ -415,24 +430,52 @@ async function upgradeNodeModules({
|
|
|
415
430
|
selectedRelease,
|
|
416
431
|
currentDependencies
|
|
417
432
|
}) {
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
}
|
|
433
|
+
const tasks = [];
|
|
434
|
+
const depsToRemove = [
|
|
435
|
+
...selectedRelease.removeDependencies || [],
|
|
436
|
+
...selectedRelease.removeDevDependencies || []
|
|
437
|
+
].filter((dep) => dep in currentDependencies);
|
|
438
|
+
if (depsToRemove.length > 0) {
|
|
439
|
+
tasks.push({
|
|
440
|
+
title: `Removing deprecated dependencies`,
|
|
441
|
+
task: async () => {
|
|
442
|
+
await uninstallNodeModules({
|
|
443
|
+
directory: appPath,
|
|
444
|
+
packageManager: await getPackageManager(appPath),
|
|
445
|
+
args: depsToRemove
|
|
446
|
+
});
|
|
432
447
|
}
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
const upgradeArgs = buildUpgradeCommandArgs({
|
|
451
|
+
selectedRelease,
|
|
452
|
+
currentDependencies
|
|
453
|
+
});
|
|
454
|
+
if (upgradeArgs.length > 0) {
|
|
455
|
+
tasks.push({
|
|
456
|
+
title: `Upgrading dependencies`,
|
|
457
|
+
task: async () => {
|
|
458
|
+
await installNodeModules({
|
|
459
|
+
directory: appPath,
|
|
460
|
+
packageManager: await getPackageManager(appPath),
|
|
461
|
+
args: upgradeArgs
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
});
|
|
465
|
+
}
|
|
466
|
+
if (tasks.length > 0) {
|
|
467
|
+
await renderTasks(tasks, {});
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
async function uninstallNodeModules({
|
|
471
|
+
directory,
|
|
472
|
+
packageManager,
|
|
473
|
+
args
|
|
474
|
+
}) {
|
|
475
|
+
if (args.length === 0) return;
|
|
476
|
+
const command = packageManager === "npm" ? "uninstall" : packageManager === "yarn" ? "remove" : packageManager === "pnpm" ? "remove" : packageManager === "bun" ? "remove" : "uninstall";
|
|
477
|
+
const actualPackageManager = packageManager === "unknown" ? "npm" : packageManager;
|
|
478
|
+
await exec(actualPackageManager, [command, ...args], { cwd: directory });
|
|
436
479
|
}
|
|
437
480
|
function appendRemixDependencies({
|
|
438
481
|
currentDependencies,
|
|
@@ -453,12 +496,15 @@ function appendReactRouterDependencies({
|
|
|
453
496
|
selectedReactRouter
|
|
454
497
|
}) {
|
|
455
498
|
const command = [];
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
499
|
+
const targetVersion = getAbsoluteVersion(selectedReactRouter[1]);
|
|
500
|
+
const reactRouterPackages = [
|
|
501
|
+
"react-router",
|
|
502
|
+
"react-router-dom",
|
|
503
|
+
"@react-router/dev",
|
|
504
|
+
"@react-router/fs-routes"
|
|
505
|
+
];
|
|
506
|
+
for (const packageName of reactRouterPackages) {
|
|
507
|
+
command.push(`${packageName}@${targetVersion}`);
|
|
462
508
|
}
|
|
463
509
|
return command;
|
|
464
510
|
}
|
package/dist/lib/build.js
CHANGED
|
@@ -55,6 +55,9 @@ function getSkeletonSourceDir() {
|
|
|
55
55
|
}
|
|
56
56
|
return joinPath(dirname(monorepoPackagesPath), "templates", "skeleton");
|
|
57
57
|
}
|
|
58
|
+
function getSkeletonNodeModules() {
|
|
59
|
+
return joinPath(getSkeletonSourceDir(), "node_modules");
|
|
60
|
+
}
|
|
58
61
|
async function getRepoNodeModules() {
|
|
59
62
|
const { stdout } = await execAsync("npm root");
|
|
60
63
|
let nodeModulesPath = stdout.trim();
|
|
@@ -64,4 +67,4 @@ async function getRepoNodeModules() {
|
|
|
64
67
|
return nodeModulesPath;
|
|
65
68
|
}
|
|
66
69
|
|
|
67
|
-
export { ASSETS_DIR_PREFIX, ASSETS_STARTER_DIR, ASSETS_STARTER_DIR_ROUTES, getAssetsDir, getPkgJsonPath, getRepoNodeModules, getSkeletonSourceDir, getStarterDir, getTemplateAppFile, hydrogenPackagesPath, isHydrogenMonorepo };
|
|
70
|
+
export { ASSETS_DIR_PREFIX, ASSETS_STARTER_DIR, ASSETS_STARTER_DIR_ROUTES, getAssetsDir, getPkgJsonPath, getRepoNodeModules, getSkeletonNodeModules, getSkeletonSourceDir, getStarterDir, getTemplateAppFile, hydrogenPackagesPath, isHydrogenMonorepo };
|
package/dist/lib/import-utils.js
CHANGED
|
@@ -10,7 +10,10 @@ async function importVite(root) {
|
|
|
10
10
|
process.env.SHOPIFY_UNIT_TEST ? void 0 : { paths: [root] }
|
|
11
11
|
);
|
|
12
12
|
const vitePackageJson = await findUpAndReadPackageJson(vitePath);
|
|
13
|
-
let viteNodeIndexFile = vitePackageJson.content.exports?.["."]
|
|
13
|
+
let viteNodeIndexFile = vitePackageJson.content.exports?.["."];
|
|
14
|
+
if (typeof viteNodeIndexFile !== "string") {
|
|
15
|
+
viteNodeIndexFile = viteNodeIndexFile?.import;
|
|
16
|
+
}
|
|
14
17
|
if (typeof viteNodeIndexFile !== "string") {
|
|
15
18
|
viteNodeIndexFile = viteNodeIndexFile.default;
|
|
16
19
|
}
|
|
@@ -2,7 +2,7 @@ import { rm, symlink } from 'node:fs/promises';
|
|
|
2
2
|
import { vi } from 'vitest';
|
|
3
3
|
import { writeFile } from '@shopify/cli-kit/node/fs';
|
|
4
4
|
import { dirname, joinPath } from '@shopify/cli-kit/node/path';
|
|
5
|
-
import { getSkeletonSourceDir,
|
|
5
|
+
import { getSkeletonSourceDir, getSkeletonNodeModules } from '../build.js';
|
|
6
6
|
|
|
7
7
|
const { renderTasksHook } = vi.hoisted(() => ({ renderTasksHook: vi.fn() }));
|
|
8
8
|
vi.mock("../template-downloader.js", async () => ({
|
|
@@ -43,15 +43,13 @@ vi.mock(
|
|
|
43
43
|
renderTasksHook.mockImplementationOnce(async () => {
|
|
44
44
|
await writeFile(`${directory}/package-lock.json`, "{}");
|
|
45
45
|
});
|
|
46
|
-
|
|
46
|
+
const targetNodeModules = joinPath(directory, "node_modules");
|
|
47
|
+
await rm(targetNodeModules, {
|
|
47
48
|
force: true,
|
|
48
49
|
recursive: true
|
|
49
50
|
}).catch(() => {
|
|
50
51
|
});
|
|
51
|
-
await symlink(
|
|
52
|
-
await getRepoNodeModules(),
|
|
53
|
-
joinPath(directory, "node_modules")
|
|
54
|
-
);
|
|
52
|
+
await symlink(await getSkeletonNodeModules(), targetNodeModules);
|
|
55
53
|
})
|
|
56
54
|
};
|
|
57
55
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { renderWarning, renderSuccess } from '@shopify/cli-kit/node/ui';
|
|
2
2
|
|
|
3
|
-
const RESERVED_ROUTES = ["^
|
|
3
|
+
const RESERVED_ROUTES = ["^cdn/", "^_t/"];
|
|
4
4
|
function findReservedRoutes(config) {
|
|
5
5
|
const routes = /* @__PURE__ */ new Set();
|
|
6
6
|
Object.values(config.routes).filter(
|
|
@@ -45,7 +45,8 @@ ${colors.dim(
|
|
|
45
45
|
"**/*.generated.d.ts",
|
|
46
46
|
"**/package.json",
|
|
47
47
|
"**/tsconfig.json",
|
|
48
|
-
"**/.shopify"
|
|
48
|
+
"**/.shopify",
|
|
49
|
+
"**/.gitignore"
|
|
49
50
|
]
|
|
50
51
|
}).on("all", async (eventName, eventFilePath) => {
|
|
51
52
|
const targetFile = joinPath(
|
|
@@ -171,7 +172,7 @@ async function applyTemplateDiff(targetDirectory, diffDirectory, templateDir) {
|
|
|
171
172
|
force: true,
|
|
172
173
|
recursive: true,
|
|
173
174
|
filter: createFilter(
|
|
174
|
-
/(^|\/|\\)(dist|node_modules|\.cache
|
|
175
|
+
/(^|\/|\\)(dist|node_modules|\.cache|\.turbo|package\.json|tsconfig\.json|\.gitignore)(\/|\\|$)/i
|
|
175
176
|
)
|
|
176
177
|
});
|
|
177
178
|
await mergePackageJson(diffDirectory, targetDirectory, {
|
package/dist/lib/vite-config.js
CHANGED
|
@@ -37,7 +37,7 @@ async function getViteConfig(root, ssrEntryFlag) {
|
|
|
37
37
|
mode,
|
|
38
38
|
mode
|
|
39
39
|
);
|
|
40
|
-
const { appDirectory, serverBuildFile, routes } =
|
|
40
|
+
const { appDirectory, serverBuildFile, routes } = getReactRouterOrRemixConfigFromVite(resolvedViteConfig);
|
|
41
41
|
const serverOutDir = resolvedViteConfig.build.outDir;
|
|
42
42
|
const clientOutDir = serverOutDir.replace(/server$/, "client");
|
|
43
43
|
const rollupOutput = resolvedViteConfig.build.rollupOptions.output;
|
|
@@ -58,8 +58,8 @@ async function getViteConfig(root, ssrEntryFlag) {
|
|
|
58
58
|
resolvedViteConfig,
|
|
59
59
|
userViteConfig: maybeConfig.config,
|
|
60
60
|
remixConfig: {
|
|
61
|
-
routes,
|
|
62
|
-
appDirectory,
|
|
61
|
+
routes: routes ?? {},
|
|
62
|
+
appDirectory: appDirectory ?? joinPath(resolvedViteConfig.root, "app"),
|
|
63
63
|
rootDirectory: resolvedViteConfig.root,
|
|
64
64
|
serverEntryPoint: (await findFileWithExtension(
|
|
65
65
|
dirname(resolvedSsrEntry),
|
|
@@ -68,7 +68,16 @@ async function getViteConfig(root, ssrEntryFlag) {
|
|
|
68
68
|
}
|
|
69
69
|
};
|
|
70
70
|
}
|
|
71
|
-
function
|
|
71
|
+
function getReactRouterOrRemixConfigFromVite(viteConfig) {
|
|
72
|
+
try {
|
|
73
|
+
const reactRouterConfig = getReactRouterConfigFromVite(viteConfig);
|
|
74
|
+
return reactRouterConfig;
|
|
75
|
+
} catch (error) {
|
|
76
|
+
const remixConfig = getRemixConfigFromVite(viteConfig);
|
|
77
|
+
return remixConfig;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function getReactRouterConfigFromVite(viteConfig) {
|
|
72
81
|
if (!viteConfig.__reactRouterPluginContext) {
|
|
73
82
|
throw new Error("Could not resolve React Router config");
|
|
74
83
|
}
|
|
@@ -79,6 +88,14 @@ function getRemixConfigFromVite(viteConfig) {
|
|
|
79
88
|
routes
|
|
80
89
|
};
|
|
81
90
|
}
|
|
91
|
+
function getRemixConfigFromVite(viteConfig) {
|
|
92
|
+
const { remixConfig } = findHydrogenPlugin(viteConfig)?.api?.getPluginOptions() ?? {};
|
|
93
|
+
return remixConfig ? {
|
|
94
|
+
appDirectory: remixConfig.appDirectory,
|
|
95
|
+
serverBuildFile: remixConfig.serverBuildFile,
|
|
96
|
+
routes: remixConfig.routes
|
|
97
|
+
} : {};
|
|
98
|
+
}
|
|
82
99
|
function findPlugin(config, name) {
|
|
83
100
|
return config.plugins.find((plugin) => plugin.name === name);
|
|
84
101
|
}
|
package/oclif.manifest.json
CHANGED
|
@@ -503,6 +503,13 @@
|
|
|
503
503
|
"required": false,
|
|
504
504
|
"allowNo": false,
|
|
505
505
|
"type": "boolean"
|
|
506
|
+
},
|
|
507
|
+
"force-client-sourcemap": {
|
|
508
|
+
"description": "Client sourcemapping is avoided by default because it makes backend code visible in the browser. Use this flag to force enabling it.",
|
|
509
|
+
"env": "SHOPIFY_HYDROGEN_FLAG_FORCE_CLIENT_SOURCEMAP",
|
|
510
|
+
"name": "force-client-sourcemap",
|
|
511
|
+
"allowNo": false,
|
|
512
|
+
"type": "boolean"
|
|
506
513
|
}
|
|
507
514
|
},
|
|
508
515
|
"hasDynamicHelp": false,
|
|
@@ -1728,5 +1735,5 @@
|
|
|
1728
1735
|
]
|
|
1729
1736
|
}
|
|
1730
1737
|
},
|
|
1731
|
-
"version": "11.
|
|
1738
|
+
"version": "11.1.1"
|
|
1732
1739
|
}
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"access": "public",
|
|
5
5
|
"@shopify:registry": "https://registry.npmjs.org"
|
|
6
6
|
},
|
|
7
|
-
"version": "11.
|
|
7
|
+
"version": "11.1.1",
|
|
8
8
|
"license": "MIT",
|
|
9
9
|
"type": "module",
|
|
10
10
|
"repository": {
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"vitest": "^1.0.4"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@ast-grep/napi": "0.
|
|
40
|
+
"@ast-grep/napi": "0.34.1",
|
|
41
41
|
"@oclif/core": "3.26.5",
|
|
42
42
|
"@shopify/cli-kit": "^3.80.4",
|
|
43
43
|
"@shopify/oxygen-cli": "4.6.18",
|