@shopify/cli 3.85.2 → 3.85.4

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.
Files changed (155) hide show
  1. package/dist/assets/hydrogen/bundle/analyzer.html +155 -148
  2. package/dist/assets/hydrogen/starter/CHANGELOG.md +125 -49
  3. package/dist/assets/hydrogen/starter/app/components/AddToCartButton.tsx +1 -1
  4. package/dist/assets/hydrogen/starter/app/components/CartLineItem.tsx +1 -1
  5. package/dist/assets/hydrogen/starter/app/components/CartMain.tsx +1 -1
  6. package/dist/assets/hydrogen/starter/app/components/CartSummary.tsx +62 -29
  7. package/dist/assets/hydrogen/starter/app/components/Header.tsx +1 -1
  8. package/dist/assets/hydrogen/starter/app/components/PageLayout.tsx +1 -1
  9. package/dist/assets/hydrogen/starter/app/components/ProductForm.tsx +2 -2
  10. package/dist/assets/hydrogen/starter/app/components/SearchForm.tsx +1 -1
  11. package/dist/assets/hydrogen/starter/app/components/SearchFormPredictive.tsx +8 -3
  12. package/dist/assets/hydrogen/starter/app/components/SearchResults.tsx +3 -11
  13. package/dist/assets/hydrogen/starter/app/components/SearchResultsPredictive.tsx +2 -6
  14. package/dist/assets/hydrogen/starter/app/entry.client.tsx +10 -2
  15. package/dist/assets/hydrogen/starter/app/entry.server.tsx +5 -3
  16. package/dist/assets/hydrogen/starter/app/graphql/customer-account/CustomerAddressMutations.ts +7 -4
  17. package/dist/assets/hydrogen/starter/app/graphql/customer-account/CustomerDetailsQuery.ts +1 -1
  18. package/dist/assets/hydrogen/starter/app/graphql/customer-account/CustomerOrderQuery.ts +4 -1
  19. package/dist/assets/hydrogen/starter/app/graphql/customer-account/CustomerOrdersQuery.ts +10 -5
  20. package/dist/assets/hydrogen/starter/app/graphql/customer-account/CustomerUpdateMutation.ts +3 -2
  21. package/dist/assets/hydrogen/starter/app/lib/context.ts +34 -17
  22. package/dist/assets/hydrogen/starter/app/lib/fragments.ts +1 -0
  23. package/dist/assets/hydrogen/starter/app/lib/orderFilters.ts +90 -0
  24. package/dist/assets/hydrogen/starter/app/lib/redirect.ts +1 -1
  25. package/dist/assets/hydrogen/starter/app/lib/session.ts +1 -1
  26. package/dist/assets/hydrogen/starter/app/lib/variants.ts +1 -1
  27. package/dist/assets/hydrogen/starter/app/root.tsx +23 -18
  28. package/dist/assets/hydrogen/starter/app/routes/$.tsx +2 -2
  29. package/dist/assets/hydrogen/starter/app/routes/[robots.txt].tsx +2 -2
  30. package/dist/assets/hydrogen/starter/app/routes/[sitemap.xml].tsx +2 -3
  31. package/dist/assets/hydrogen/starter/app/routes/_index.tsx +12 -8
  32. package/dist/assets/hydrogen/starter/app/routes/account.$.tsx +4 -3
  33. package/dist/assets/hydrogen/starter/app/routes/account._index.tsx +1 -1
  34. package/dist/assets/hydrogen/starter/app/routes/account.addresses.tsx +15 -11
  35. package/dist/assets/hydrogen/starter/app/routes/account.orders.$id.tsx +47 -22
  36. package/dist/assets/hydrogen/starter/app/routes/account.orders._index.tsx +152 -23
  37. package/dist/assets/hydrogen/starter/app/routes/account.profile.tsx +11 -8
  38. package/dist/assets/hydrogen/starter/app/routes/account.tsx +16 -4
  39. package/dist/assets/hydrogen/starter/app/routes/account_.authorize.tsx +2 -2
  40. package/dist/assets/hydrogen/starter/app/routes/account_.login.tsx +5 -3
  41. package/dist/assets/hydrogen/starter/app/routes/account_.logout.tsx +3 -2
  42. package/dist/assets/hydrogen/starter/app/routes/api.$version.[graphql.json].tsx +2 -2
  43. package/dist/assets/hydrogen/starter/app/routes/blogs.$blogHandle.$articleHandle.tsx +6 -10
  44. package/dist/assets/hydrogen/starter/app/routes/blogs.$blogHandle._index.tsx +10 -7
  45. package/dist/assets/hydrogen/starter/app/routes/blogs._index.tsx +13 -7
  46. package/dist/assets/hydrogen/starter/app/routes/cart.$lines.tsx +3 -2
  47. package/dist/assets/hydrogen/starter/app/routes/cart.tsx +13 -9
  48. package/dist/assets/hydrogen/starter/app/routes/collections.$handle.tsx +8 -11
  49. package/dist/assets/hydrogen/starter/app/routes/collections._index.tsx +6 -6
  50. package/dist/assets/hydrogen/starter/app/routes/collections.all.tsx +10 -7
  51. package/dist/assets/hydrogen/starter/app/routes/discount.$code.tsx +3 -2
  52. package/dist/assets/hydrogen/starter/app/routes/pages.$handle.tsx +8 -6
  53. package/dist/assets/hydrogen/starter/app/routes/policies.$handle.tsx +7 -4
  54. package/dist/assets/hydrogen/starter/app/routes/policies._index.tsx +19 -13
  55. package/dist/assets/hydrogen/starter/app/routes/products.$handle.tsx +9 -6
  56. package/dist/assets/hydrogen/starter/app/routes/search.tsx +14 -14
  57. package/dist/assets/hydrogen/starter/app/routes/sitemap.$type.$page[.xml].tsx +2 -3
  58. package/dist/assets/hydrogen/starter/app/routes.ts +1 -1
  59. package/dist/assets/hydrogen/starter/app/styles/app.css +53 -1
  60. package/dist/assets/hydrogen/starter/customer-accountapi.generated.d.ts +47 -13
  61. package/dist/assets/hydrogen/starter/env.d.ts +1 -39
  62. package/dist/assets/hydrogen/starter/eslint.config.js +35 -52
  63. package/dist/assets/hydrogen/starter/package.json +14 -15
  64. package/dist/assets/hydrogen/starter/react-router.config.ts +9 -3
  65. package/dist/assets/hydrogen/starter/server.ts +7 -7
  66. package/dist/assets/hydrogen/starter/storefrontapi.generated.d.ts +1 -1
  67. package/dist/assets/hydrogen/starter/tsconfig.json +17 -13
  68. package/dist/assets/hydrogen/starter/vite.config.ts +3 -0
  69. package/dist/assets/hydrogen/virtual-routes/components/RequestDetails.jsx +13 -20
  70. package/dist/assets/hydrogen/virtual-routes/routes/[.]well-known.appspecific.com[.]chrome[.]devtools[.]json.jsx +37 -0
  71. package/dist/{chokidar-TTCYG5AA.js → chokidar-HTKREZL3.js} +482 -7
  72. package/dist/{chunk-TPK3IOCE.js → chunk-2C6DJIBX.js} +4 -4
  73. package/dist/{chunk-J3GJSEAX.js → chunk-2H6AD4EL.js} +5 -5
  74. package/dist/{chunk-GWSQTZJI.js → chunk-2XTIBWBA.js} +3 -3
  75. package/dist/{chunk-IIFNATCS.js → chunk-34TWZ632.js} +3 -4
  76. package/dist/{chunk-AQBAXHB6.js → chunk-3762O47V.js} +2 -2
  77. package/dist/{chunk-BNANL2RF.js → chunk-3JZIRVBB.js} +400 -319
  78. package/dist/{chunk-FZGEJWCA.js → chunk-5AUZG65U.js} +5 -5
  79. package/dist/{chunk-YTNLVKDJ.js → chunk-5JFU2PDH.js} +3 -3
  80. package/dist/{chunk-YCRRJE3E.js → chunk-BRYTLGQH.js} +3 -3
  81. package/dist/{chunk-ETGIQIBS.js → chunk-CBUCMJTB.js} +2 -2
  82. package/dist/{chunk-JJTURC36.js → chunk-DBQFPT3U.js} +6 -6
  83. package/dist/{chunk-PK2ZJN2D.js → chunk-DEMUK3QR.js} +4 -4
  84. package/dist/{chunk-K4MF722S.js → chunk-EPNYJUKL.js} +6 -6
  85. package/dist/{chunk-SJI2AT4E.js → chunk-GMOJ4MM6.js} +5 -5
  86. package/dist/{chunk-MU6B24WQ.js → chunk-JDGRN7YI.js} +4 -4
  87. package/dist/{chunk-CO5XRUNB.js → chunk-JXSJVKPK.js} +3 -3
  88. package/dist/{chunk-3KWF52OH.js → chunk-M6DL6PW7.js} +2 -2
  89. package/dist/{chunk-3HB45LNC.js → chunk-NIJYJVQ7.js} +112 -113
  90. package/dist/{chunk-UWYW5CE4.js → chunk-ON22YJEB.js} +6 -6
  91. package/dist/{chunk-DHC7FUNN.js → chunk-OYGH5GC4.js} +2 -2
  92. package/dist/{chunk-EUJBLPMW.js → chunk-P24ZSULK.js} +3 -3
  93. package/dist/{chunk-63DVTKIC.js → chunk-QCCEM2W7.js} +3 -3
  94. package/dist/{chunk-LYLEKYI6.js → chunk-QCVEBMJO.js} +3 -3
  95. package/dist/{chunk-YTHR7DHB.js → chunk-QDQ64PMY.js} +3 -3
  96. package/dist/{chunk-G6VSMPDS.js → chunk-S5H4ZYTZ.js} +3 -3
  97. package/dist/{chunk-5RQSFT35.js → chunk-SJ6XHMPR.js} +2 -2
  98. package/dist/{chunk-QGFQPDQE.js → chunk-UTGZE4KZ.js} +3 -3
  99. package/dist/{chunk-NONJKAAK.js → chunk-VOXGVQ4Y.js} +6 -6
  100. package/dist/{chunk-B2IMQTAS.js → chunk-VVHZTHIS.js} +7 -7
  101. package/dist/{chunk-HJUBFP6H.js → chunk-W7V5E5TL.js} +4 -4
  102. package/dist/{chunk-PCO7BTB2.js → chunk-XEG67XNW.js} +4 -4
  103. package/dist/{chunk-BBD57WPK.js → chunk-XQMRWA2D.js} +2 -2
  104. package/dist/{chunk-3GLPAOWG.js → chunk-XXIM3XSO.js} +2 -2
  105. package/dist/{chunk-MI76AMGA.js → chunk-Y2BC44O5.js} +4 -4
  106. package/dist/{chunk-EG6MBBEN.js → chunk-Y2JP6WFP.js} +2 -2
  107. package/dist/cli/commands/auth/login.js +11 -11
  108. package/dist/cli/commands/auth/login.test.js +12 -12
  109. package/dist/cli/commands/auth/logout.js +11 -11
  110. package/dist/cli/commands/auth/logout.test.js +12 -12
  111. package/dist/cli/commands/cache/clear.js +11 -11
  112. package/dist/cli/commands/debug/command-flags.js +11 -11
  113. package/dist/cli/commands/docs/generate.js +11 -11
  114. package/dist/cli/commands/docs/generate.test.js +11 -11
  115. package/dist/cli/commands/help.js +11 -11
  116. package/dist/cli/commands/kitchen-sink/async.js +12 -12
  117. package/dist/cli/commands/kitchen-sink/async.test.js +12 -12
  118. package/dist/cli/commands/kitchen-sink/index.js +14 -14
  119. package/dist/cli/commands/kitchen-sink/index.test.js +14 -14
  120. package/dist/cli/commands/kitchen-sink/prompts.js +12 -12
  121. package/dist/cli/commands/kitchen-sink/prompts.test.js +12 -12
  122. package/dist/cli/commands/kitchen-sink/static.js +12 -12
  123. package/dist/cli/commands/kitchen-sink/static.test.js +12 -12
  124. package/dist/cli/commands/notifications/generate.js +12 -12
  125. package/dist/cli/commands/notifications/list.js +12 -12
  126. package/dist/cli/commands/search.js +12 -12
  127. package/dist/cli/commands/upgrade.js +12 -12
  128. package/dist/cli/commands/version.js +12 -12
  129. package/dist/cli/commands/version.test.js +12 -12
  130. package/dist/cli/services/commands/notifications.js +7 -7
  131. package/dist/cli/services/commands/search.js +3 -3
  132. package/dist/cli/services/commands/search.test.js +3 -3
  133. package/dist/cli/services/commands/version.js +4 -4
  134. package/dist/cli/services/commands/version.test.js +5 -5
  135. package/dist/cli/services/kitchen-sink/async.js +3 -3
  136. package/dist/cli/services/kitchen-sink/prompts.js +3 -3
  137. package/dist/cli/services/kitchen-sink/static.js +3 -3
  138. package/dist/cli/services/upgrade.js +4 -4
  139. package/dist/cli/services/upgrade.test.js +5 -5
  140. package/dist/{custom-oclif-loader-MIHTOE44.js → custom-oclif-loader-OFIEXBNK.js} +3 -3
  141. package/dist/{error-handler-NTBLUSJY.js → error-handler-FHZMF7GS.js} +9 -9
  142. package/dist/hooks/postrun.js +7 -7
  143. package/dist/hooks/prerun.js +8 -8
  144. package/dist/index.js +1802 -3509
  145. package/dist/{local-JNP36HLV.js → local-4MIY74VR.js} +3 -3
  146. package/dist/{morph-5D7H6MU2.js → morph-D4BXY376.js} +9 -9
  147. package/dist/{node-package-manager-EHYWEIML.js → node-package-manager-H6KF4PH6.js} +4 -4
  148. package/dist/{path-GB4VIEM6.js → path-COZT77T2.js} +2 -2
  149. package/dist/tsconfig.tsbuildinfo +1 -1
  150. package/dist/{ui-XVYQT3H5.js → ui-R3FDFL2U.js} +3 -3
  151. package/dist/{workerd-X2PCOICQ.js → workerd-JVZ57YOV.js} +13 -13
  152. package/oclif.manifest.json +11 -56
  153. package/package.json +8 -8
  154. package/dist/chokidar-XUA2BN3J.js +0 -1120
  155. package/dist/chunk-F7J5CUMZ.js +0 -497
@@ -1,21 +1,20 @@
1
- import { type MetaFunction, useLoaderData } from 'react-router';
2
- import type {CartQueryDataReturn} from '@shopify/hydrogen';
3
- import {CartForm} from '@shopify/hydrogen';
4
1
  import {
2
+ useLoaderData,
5
3
  data,
6
- type LoaderFunctionArgs,
7
- type ActionFunctionArgs,
8
4
  type HeadersFunction,
9
- } from '@shopify/remix-oxygen';
5
+ } from 'react-router';
6
+ import type {Route} from './+types/cart';
7
+ import type {CartQueryDataReturn} from '@shopify/hydrogen';
8
+ import {CartForm} from '@shopify/hydrogen';
10
9
  import {CartMain} from '~/components/CartMain';
11
10
 
12
- export const meta: MetaFunction = () => {
11
+ export const meta: Route.MetaFunction = () => {
13
12
  return [{title: `Hydrogen | Cart`}];
14
13
  };
15
14
 
16
15
  export const headers: HeadersFunction = ({actionHeaders}) => actionHeaders;
17
16
 
18
- export async function action({request, context}: ActionFunctionArgs) {
17
+ export async function action({request, context}: Route.ActionArgs) {
19
18
  const {cart} = context;
20
19
 
21
20
  const formData = await request.formData();
@@ -67,6 +66,11 @@ export async function action({request, context}: ActionFunctionArgs) {
67
66
  result = await cart.updateGiftCardCodes(giftCardCodes);
68
67
  break;
69
68
  }
69
+ case CartForm.ACTIONS.GiftCardCodesRemove: {
70
+ const appliedGiftCardIds = inputs.giftCardCodes as string[];
71
+ result = await cart.removeGiftCardCodes(appliedGiftCardIds);
72
+ break;
73
+ }
70
74
  case CartForm.ACTIONS.BuyerIdentityUpdate: {
71
75
  result = await cart.updateBuyerIdentity({
72
76
  ...inputs.buyerIdentity,
@@ -100,7 +104,7 @@ export async function action({request, context}: ActionFunctionArgs) {
100
104
  );
101
105
  }
102
106
 
103
- export async function loader({context}: LoaderFunctionArgs) {
107
+ export async function loader({context}: Route.LoaderArgs) {
104
108
  const {cart} = context;
105
109
  return await cart.get();
106
110
  }
@@ -1,15 +1,16 @@
1
- import {redirect, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
2
- import {useLoaderData, type MetaFunction} from 'react-router';
1
+ import {redirect, useLoaderData} from 'react-router';
2
+ import type {Route} from './+types/collections.$handle';
3
3
  import {getPaginationVariables, Analytics} from '@shopify/hydrogen';
4
4
  import {PaginatedResourceSection} from '~/components/PaginatedResourceSection';
5
5
  import {redirectIfHandleIsLocalized} from '~/lib/redirect';
6
6
  import {ProductItem} from '~/components/ProductItem';
7
+ import type {ProductItemFragment} from 'storefrontapi.generated';
7
8
 
8
- export const meta: MetaFunction<typeof loader> = ({data}) => {
9
+ export const meta: Route.MetaFunction = ({data}) => {
9
10
  return [{title: `Hydrogen | ${data?.collection.title ?? ''} Collection`}];
10
11
  };
11
12
 
12
- export async function loader(args: LoaderFunctionArgs) {
13
+ export async function loader(args: Route.LoaderArgs) {
13
14
  // Start fetching non-critical data without blocking time to first byte
14
15
  const deferredData = loadDeferredData(args);
15
16
 
@@ -23,11 +24,7 @@ export async function loader(args: LoaderFunctionArgs) {
23
24
  * Load data necessary for rendering content above the fold. This is the critical data
24
25
  * needed to render the page. If it's unavailable, the whole page should 400 or 500 error.
25
26
  */
26
- async function loadCriticalData({
27
- context,
28
- params,
29
- request,
30
- }: LoaderFunctionArgs) {
27
+ async function loadCriticalData({context, params, request}: Route.LoaderArgs) {
31
28
  const {handle} = params;
32
29
  const {storefront} = context;
33
30
  const paginationVariables = getPaginationVariables(request, {
@@ -64,7 +61,7 @@ async function loadCriticalData({
64
61
  * fetched after the initial page load. If it's unavailable, the page should still 200.
65
62
  * Make sure to not throw any errors here, as it will cause the page to 500.
66
63
  */
67
- function loadDeferredData({context}: LoaderFunctionArgs) {
64
+ function loadDeferredData({context}: Route.LoaderArgs) {
68
65
  return {};
69
66
  }
70
67
 
@@ -75,7 +72,7 @@ export default function Collection() {
75
72
  <div className="collection">
76
73
  <h1>{collection.title}</h1>
77
74
  <p className="collection-description">{collection.description}</p>
78
- <PaginatedResourceSection
75
+ <PaginatedResourceSection<ProductItemFragment>
79
76
  connection={collection.products}
80
77
  resourcesClassName="products-grid"
81
78
  >
@@ -1,10 +1,10 @@
1
- import { useLoaderData, Link } from 'react-router';
2
- import {type LoaderFunctionArgs} from '@shopify/remix-oxygen';
1
+ import {useLoaderData, Link} from 'react-router';
2
+ import type {Route} from './+types/collections._index';
3
3
  import {getPaginationVariables, Image} from '@shopify/hydrogen';
4
4
  import type {CollectionFragment} from 'storefrontapi.generated';
5
5
  import {PaginatedResourceSection} from '~/components/PaginatedResourceSection';
6
6
 
7
- export async function loader(args: LoaderFunctionArgs) {
7
+ export async function loader(args: Route.LoaderArgs) {
8
8
  // Start fetching non-critical data without blocking time to first byte
9
9
  const deferredData = loadDeferredData(args);
10
10
 
@@ -18,7 +18,7 @@ export async function loader(args: LoaderFunctionArgs) {
18
18
  * Load data necessary for rendering content above the fold. This is the critical data
19
19
  * needed to render the page. If it's unavailable, the whole page should 400 or 500 error.
20
20
  */
21
- async function loadCriticalData({context, request}: LoaderFunctionArgs) {
21
+ async function loadCriticalData({context, request}: Route.LoaderArgs) {
22
22
  const paginationVariables = getPaginationVariables(request, {
23
23
  pageBy: 4,
24
24
  });
@@ -38,7 +38,7 @@ async function loadCriticalData({context, request}: LoaderFunctionArgs) {
38
38
  * fetched after the initial page load. If it's unavailable, the page should still 200.
39
39
  * Make sure to not throw any errors here, as it will cause the page to 500.
40
40
  */
41
- function loadDeferredData({context}: LoaderFunctionArgs) {
41
+ function loadDeferredData({context}: Route.LoaderArgs) {
42
42
  return {};
43
43
  }
44
44
 
@@ -48,7 +48,7 @@ export default function Collections() {
48
48
  return (
49
49
  <div className="collections">
50
50
  <h1>Collections</h1>
51
- <PaginatedResourceSection
51
+ <PaginatedResourceSection<CollectionFragment>
52
52
  connection={collections}
53
53
  resourcesClassName="collections-grid"
54
54
  >
@@ -1,14 +1,17 @@
1
- import {type LoaderFunctionArgs} from '@shopify/remix-oxygen';
2
- import {useLoaderData, type MetaFunction} from 'react-router';
1
+ import type {Route} from './+types/collections.all';
2
+ import {
3
+ useLoaderData,
4
+ } from 'react-router';
3
5
  import {getPaginationVariables, Image, Money} from '@shopify/hydrogen';
4
6
  import {PaginatedResourceSection} from '~/components/PaginatedResourceSection';
5
7
  import {ProductItem} from '~/components/ProductItem';
8
+ import type {CollectionItemFragment} from 'storefrontapi.generated';
6
9
 
7
- export const meta: MetaFunction<typeof loader> = () => {
10
+ export const meta: Route.MetaFunction = () => {
8
11
  return [{title: `Hydrogen | Products`}];
9
12
  };
10
13
 
11
- export async function loader(args: LoaderFunctionArgs) {
14
+ export async function loader(args: Route.LoaderArgs) {
12
15
  // Start fetching non-critical data without blocking time to first byte
13
16
  const deferredData = loadDeferredData(args);
14
17
 
@@ -22,7 +25,7 @@ export async function loader(args: LoaderFunctionArgs) {
22
25
  * Load data necessary for rendering content above the fold. This is the critical data
23
26
  * needed to render the page. If it's unavailable, the whole page should 400 or 500 error.
24
27
  */
25
- async function loadCriticalData({context, request}: LoaderFunctionArgs) {
28
+ async function loadCriticalData({context, request}: Route.LoaderArgs) {
26
29
  const {storefront} = context;
27
30
  const paginationVariables = getPaginationVariables(request, {
28
31
  pageBy: 8,
@@ -42,7 +45,7 @@ async function loadCriticalData({context, request}: LoaderFunctionArgs) {
42
45
  * fetched after the initial page load. If it's unavailable, the page should still 200.
43
46
  * Make sure to not throw any errors here, as it will cause the page to 500.
44
47
  */
45
- function loadDeferredData({context}: LoaderFunctionArgs) {
48
+ function loadDeferredData({context}: Route.LoaderArgs) {
46
49
  return {};
47
50
  }
48
51
 
@@ -52,7 +55,7 @@ export default function Collection() {
52
55
  return (
53
56
  <div className="collection">
54
57
  <h1>Products</h1>
55
- <PaginatedResourceSection
58
+ <PaginatedResourceSection<CollectionItemFragment>
56
59
  connection={products}
57
60
  resourcesClassName="products-grid"
58
61
  >
@@ -1,4 +1,5 @@
1
- import {redirect, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
1
+ import {redirect} from 'react-router';
2
+ import type {Route} from './+types/discount.$code';
2
3
 
3
4
  /**
4
5
  * Automatically applies a discount found on the url
@@ -11,7 +12,7 @@ import {redirect, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
11
12
  *
12
13
  * ```
13
14
  */
14
- export async function loader({request, context, params}: LoaderFunctionArgs) {
15
+ export async function loader({request, context, params}: Route.LoaderArgs) {
15
16
  const {cart} = context;
16
17
  const {code} = params;
17
18
 
@@ -1,12 +1,14 @@
1
- import {type LoaderFunctionArgs} from '@shopify/remix-oxygen';
2
- import { useLoaderData, type MetaFunction } from 'react-router';
1
+ import {
2
+ useLoaderData,
3
+ } from 'react-router';
4
+ import type {Route} from './+types/pages.$handle';
3
5
  import {redirectIfHandleIsLocalized} from '~/lib/redirect';
4
6
 
5
- export const meta: MetaFunction<typeof loader> = ({data}) => {
7
+ export const meta: Route.MetaFunction = ({data}) => {
6
8
  return [{title: `Hydrogen | ${data?.page.title ?? ''}`}];
7
9
  };
8
10
 
9
- export async function loader(args: LoaderFunctionArgs) {
11
+ export async function loader(args: Route.LoaderArgs) {
10
12
  // Start fetching non-critical data without blocking time to first byte
11
13
  const deferredData = loadDeferredData(args);
12
14
 
@@ -24,7 +26,7 @@ async function loadCriticalData({
24
26
  context,
25
27
  request,
26
28
  params,
27
- }: LoaderFunctionArgs) {
29
+ }: Route.LoaderArgs) {
28
30
  if (!params.handle) {
29
31
  throw new Error('Missing page handle');
30
32
  }
@@ -54,7 +56,7 @@ async function loadCriticalData({
54
56
  * fetched after the initial page load. If it's unavailable, the page should still 200.
55
57
  * Make sure to not throw any errors here, as it will cause the page to 500.
56
58
  */
57
- function loadDeferredData({context}: LoaderFunctionArgs) {
59
+ function loadDeferredData({context}: Route.LoaderArgs) {
58
60
  return {};
59
61
  }
60
62
 
@@ -1,5 +1,8 @@
1
- import {type LoaderFunctionArgs} from '@shopify/remix-oxygen';
2
- import { Link, useLoaderData, type MetaFunction } from 'react-router';
1
+ import {
2
+ Link,
3
+ useLoaderData,
4
+ } from 'react-router';
5
+ import type {Route} from './+types/policies.$handle';
3
6
  import {type Shop} from '@shopify/hydrogen/storefront-api-types';
4
7
 
5
8
  type SelectedPolicies = keyof Pick<
@@ -7,11 +10,11 @@ type SelectedPolicies = keyof Pick<
7
10
  'privacyPolicy' | 'shippingPolicy' | 'termsOfService' | 'refundPolicy'
8
11
  >;
9
12
 
10
- export const meta: MetaFunction<typeof loader> = ({data}) => {
13
+ export const meta: Route.MetaFunction = ({data}) => {
11
14
  return [{title: `Hydrogen | ${data?.policy.title ?? ''}`}];
12
15
  };
13
16
 
14
- export async function loader({params, context}: LoaderFunctionArgs) {
17
+ export async function loader({params, context}: Route.LoaderArgs) {
15
18
  if (!params.handle) {
16
19
  throw new Response('No handle was passed in', {status: 404});
17
20
  }
@@ -1,9 +1,18 @@
1
- import {type LoaderFunctionArgs} from '@shopify/remix-oxygen';
2
- import { useLoaderData, Link } from 'react-router';
1
+ import {useLoaderData, Link} from 'react-router';
2
+ import type {Route} from './+types/policies._index';
3
+ import type {PoliciesQuery, PolicyItemFragment} from 'storefrontapi.generated';
3
4
 
4
- export async function loader({context}: LoaderFunctionArgs) {
5
- const data = await context.storefront.query(POLICIES_QUERY);
6
- const policies = Object.values(data.shop || {});
5
+ export async function loader({context}: Route.LoaderArgs) {
6
+ const data: PoliciesQuery = await context.storefront.query(POLICIES_QUERY);
7
+
8
+ const shopPolicies = data.shop;
9
+ const policies: PolicyItemFragment[] = [
10
+ shopPolicies?.privacyPolicy,
11
+ shopPolicies?.shippingPolicy,
12
+ shopPolicies?.termsOfService,
13
+ shopPolicies?.refundPolicy,
14
+ shopPolicies?.subscriptionPolicy,
15
+ ].filter((policy): policy is PolicyItemFragment => policy != null);
7
16
 
8
17
  if (!policies.length) {
9
18
  throw new Response('No policies found', {status: 404});
@@ -19,14 +28,11 @@ export default function Policies() {
19
28
  <div className="policies">
20
29
  <h1>Policies</h1>
21
30
  <div>
22
- {policies.map((policy) => {
23
- if (!policy) return null;
24
- return (
25
- <fieldset key={policy.id}>
26
- <Link to={`/policies/${policy.handle}`}>{policy.title}</Link>
27
- </fieldset>
28
- );
29
- })}
31
+ {policies.map((policy) => (
32
+ <fieldset key={policy.id}>
33
+ <Link to={`/policies/${policy.handle}`}>{policy.title}</Link>
34
+ </fieldset>
35
+ ))}
30
36
  </div>
31
37
  </div>
32
38
  );
@@ -1,5 +1,8 @@
1
- import {redirect, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
2
- import { useLoaderData, type MetaFunction } from 'react-router';
1
+ import {
2
+ redirect,
3
+ useLoaderData,
4
+ } from 'react-router';
5
+ import type {Route} from './+types/products.$handle';
3
6
  import {
4
7
  getSelectedProductOptions,
5
8
  Analytics,
@@ -13,7 +16,7 @@ import {ProductImage} from '~/components/ProductImage';
13
16
  import {ProductForm} from '~/components/ProductForm';
14
17
  import {redirectIfHandleIsLocalized} from '~/lib/redirect';
15
18
 
16
- export const meta: MetaFunction<typeof loader> = ({data}) => {
19
+ export const meta: Route.MetaFunction = ({data}) => {
17
20
  return [
18
21
  {title: `Hydrogen | ${data?.product.title ?? ''}`},
19
22
  {
@@ -23,7 +26,7 @@ export const meta: MetaFunction<typeof loader> = ({data}) => {
23
26
  ];
24
27
  };
25
28
 
26
- export async function loader(args: LoaderFunctionArgs) {
29
+ export async function loader(args: Route.LoaderArgs) {
27
30
  // Start fetching non-critical data without blocking time to first byte
28
31
  const deferredData = loadDeferredData(args);
29
32
 
@@ -41,7 +44,7 @@ async function loadCriticalData({
41
44
  context,
42
45
  params,
43
46
  request,
44
- }: LoaderFunctionArgs) {
47
+ }: Route.LoaderArgs) {
45
48
  const {handle} = params;
46
49
  const {storefront} = context;
47
50
 
@@ -73,7 +76,7 @@ async function loadCriticalData({
73
76
  * fetched after the initial page load. If it's unavailable, the page should still 200.
74
77
  * Make sure to not throw any errors here, as it will cause the page to 500.
75
78
  */
76
- function loadDeferredData({context, params}: LoaderFunctionArgs) {
79
+ function loadDeferredData({context, params}: Route.LoaderArgs) {
77
80
  // Put any API calls that is not critical to be available on first page render
78
81
  // For example: product reviews, product recommendations, social feeds.
79
82
 
@@ -1,8 +1,7 @@
1
1
  import {
2
- type LoaderFunctionArgs,
3
- type ActionFunctionArgs,
4
- } from '@shopify/remix-oxygen';
5
- import { useLoaderData, type MetaFunction } from 'react-router';
2
+ useLoaderData,
3
+ } from 'react-router';
4
+ import type {Route} from './+types/search';
6
5
  import {getPaginationVariables, Analytics} from '@shopify/hydrogen';
7
6
  import {SearchForm} from '~/components/SearchForm';
8
7
  import {SearchResults} from '~/components/SearchResults';
@@ -11,12 +10,13 @@ import {
11
10
  type PredictiveSearchReturn,
12
11
  getEmptyPredictiveSearchResult,
13
12
  } from '~/lib/search';
13
+ import type {RegularSearchQuery, PredictiveSearchQuery} from 'storefrontapi.generated';
14
14
 
15
- export const meta: MetaFunction = () => {
15
+ export const meta: Route.MetaFunction = () => {
16
16
  return [{title: `Hydrogen | Search`}];
17
17
  };
18
18
 
19
- export async function loader({request, context}: LoaderFunctionArgs) {
19
+ export async function loader({request, context}: Route.LoaderArgs) {
20
20
  const url = new URL(request.url);
21
21
  const isPredictive = url.searchParams.has('predictive');
22
22
  const searchPromise: Promise<PredictiveSearchReturn | RegularSearchReturn> =
@@ -216,7 +216,7 @@ async function regularSearch({
216
216
  request,
217
217
  context,
218
218
  }: Pick<
219
- LoaderFunctionArgs,
219
+ Route.LoaderArgs,
220
220
  'request' | 'context'
221
221
  >): Promise<RegularSearchReturn> {
222
222
  const {storefront} = context;
@@ -225,7 +225,7 @@ async function regularSearch({
225
225
  const term = String(url.searchParams.get('q') || '');
226
226
 
227
227
  // Search articles, pages, and products for the `q` term
228
- const {errors, ...items} = await storefront.query(SEARCH_QUERY, {
228
+ const {errors, ...items}: {errors?: Array<{message: string}>} & RegularSearchQuery = await storefront.query(SEARCH_QUERY, {
229
229
  variables: {...variables, term},
230
230
  });
231
231
 
@@ -234,12 +234,12 @@ async function regularSearch({
234
234
  }
235
235
 
236
236
  const total = Object.values(items).reduce(
237
- (acc, {nodes}) => acc + nodes.length,
237
+ (acc: number, {nodes}: {nodes: Array<unknown>}) => acc + nodes.length,
238
238
  0,
239
239
  );
240
240
 
241
241
  const error = errors
242
- ? errors.map(({message}) => message).join(', ')
242
+ ? errors.map(({message}: {message: string}) => message).join(', ')
243
243
  : undefined;
244
244
 
245
245
  return {type: 'regular', term, error, result: {total, items}};
@@ -377,7 +377,7 @@ async function predictiveSearch({
377
377
  request,
378
378
  context,
379
379
  }: Pick<
380
- ActionFunctionArgs,
380
+ Route.ActionArgs,
381
381
  'request' | 'context'
382
382
  >): Promise<PredictiveSearchReturn> {
383
383
  const {storefront} = context;
@@ -389,7 +389,7 @@ async function predictiveSearch({
389
389
  if (!term) return {type, term, result: getEmptyPredictiveSearchResult()};
390
390
 
391
391
  // Predictively search articles, collections, pages, products, and queries (suggestions)
392
- const {predictiveSearch: items, errors} = await storefront.query(
392
+ const {predictiveSearch: items, errors}: PredictiveSearchQuery & {errors?: Array<{message: string}>} = await storefront.query(
393
393
  PREDICTIVE_SEARCH_QUERY,
394
394
  {
395
395
  variables: {
@@ -403,7 +403,7 @@ async function predictiveSearch({
403
403
 
404
404
  if (errors) {
405
405
  throw new Error(
406
- `Shopify API errors: ${errors.map(({message}) => message).join(', ')}`,
406
+ `Shopify API errors: ${errors.map(({message}: {message: string}) => message).join(', ')}`,
407
407
  );
408
408
  }
409
409
 
@@ -412,7 +412,7 @@ async function predictiveSearch({
412
412
  }
413
413
 
414
414
  const total = Object.values(items).reduce(
415
- (acc, item) => acc + item.length,
415
+ (acc: number, item: Array<unknown>) => acc + item.length,
416
416
  0,
417
417
  );
418
418
 
@@ -1,11 +1,11 @@
1
- import type {LoaderFunctionArgs} from '@shopify/remix-oxygen';
1
+ import type {Route} from './+types/sitemap.$type.$page[.xml]';
2
2
  import {getSitemap} from '@shopify/hydrogen';
3
3
 
4
4
  export async function loader({
5
5
  request,
6
6
  params,
7
7
  context: {storefront},
8
- }: LoaderFunctionArgs) {
8
+ }: Route.LoaderArgs) {
9
9
  const response = await getSitemap({
10
10
  storefront,
11
11
  request,
@@ -21,4 +21,3 @@ export async function loader({
21
21
 
22
22
  return response;
23
23
  }
24
-
@@ -5,5 +5,5 @@ import {hydrogenRoutes} from '@shopify/hydrogen';
5
5
  export default hydrogenRoutes([
6
6
  ...(await flatRoutes()),
7
7
  // Manual route definitions can be added to this array, in addition to or instead of using the `flatRoutes` file-based routing convention.
8
- // See https://remix.run/docs/en/main/guides/routing for more details
8
+ // See https://reactrouter.com/api/framework-conventions/routes.ts#routests
9
9
  ]) satisfies RouteConfig;
@@ -210,7 +210,6 @@ button.reset:hover:not(:has(> *)) {
210
210
  min-width: fit-content;
211
211
  }
212
212
 
213
-
214
213
  /*
215
214
  * --------------------------------------------------
216
215
  * components/Footer
@@ -520,3 +519,56 @@ button.reset:hover:not(:has(> *)) {
520
519
  .account-logout {
521
520
  display: inline-block;
522
521
  }
522
+
523
+ /*
524
+ * --------------------------------------------------
525
+ * Order Search Form - Minimal & Responsive
526
+ * --------------------------------------------------
527
+ */
528
+ .order-search-form {
529
+ margin-bottom: 1.5rem;
530
+ }
531
+
532
+ .order-search-fieldset {
533
+ border: 1px solid #e5e5e5;
534
+ border-radius: 4px;
535
+ padding: 1rem;
536
+ }
537
+
538
+ .order-search-legend {
539
+ font-weight: 600;
540
+ padding: 0 0.5rem;
541
+ }
542
+
543
+ .order-search-active {
544
+ font-weight: normal;
545
+ opacity: 0.7;
546
+ margin-left: 0.5rem;
547
+ }
548
+
549
+ .order-search-inputs {
550
+ display: grid;
551
+ gap: 1rem;
552
+ margin: 0.25rem 0 1rem;
553
+ grid-template-columns: 1fr;
554
+ }
555
+
556
+ @media (min-width: 640px) {
557
+ .order-search-inputs {
558
+ grid-template-columns: 1fr 1fr;
559
+ }
560
+ }
561
+
562
+ .order-search-input {
563
+ width: 100%;
564
+ padding: 0.5rem;
565
+ border: 1px solid #d1d5db;
566
+ border-radius: 4px;
567
+ font-size: 1rem;
568
+ }
569
+
570
+ .order-search-buttons {
571
+ display: flex;
572
+ gap: 0.75rem;
573
+ flex-wrap: wrap;
574
+ }