@shopify/hydrogen 0.25.0 → 0.26.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.
Files changed (128) hide show
  1. package/CHANGELOG.md +90 -0
  2. package/dist/esnext/components/{CartEstimatedCost/CartEstimatedCost.client.d.ts → CartCost/CartCost.client.d.ts} +3 -3
  3. package/dist/esnext/components/{CartEstimatedCost/CartEstimatedCost.client.js → CartCost/CartCost.client.js} +7 -7
  4. package/dist/esnext/components/CartCost/index.d.ts +1 -0
  5. package/dist/esnext/components/CartCost/index.js +1 -0
  6. package/dist/esnext/components/CartLinePrice/CartLinePrice.client.js +2 -2
  7. package/dist/esnext/components/CartLineProvider/context.d.ts +3 -3
  8. package/dist/esnext/components/CartProvider/CartProvider.client.js +37 -27
  9. package/dist/esnext/components/CartProvider/cart-queries.d.ts +1 -1
  10. package/dist/esnext/components/CartProvider/cart-queries.js +3 -3
  11. package/dist/esnext/components/CartProvider/graphql/CartAttributesUpdateMutation.d.ts +5 -5
  12. package/dist/esnext/components/CartProvider/graphql/CartBuyerIdentityUpdateMutation.d.ts +5 -5
  13. package/dist/esnext/components/CartProvider/graphql/CartCreateMutation.d.ts +5 -5
  14. package/dist/esnext/components/CartProvider/graphql/CartDiscountCodesUpdateMutation.d.ts +5 -5
  15. package/dist/esnext/components/CartProvider/graphql/CartFragment.d.ts +5 -5
  16. package/dist/esnext/components/CartProvider/graphql/CartLineAddMutation.d.ts +5 -5
  17. package/dist/esnext/components/CartProvider/graphql/CartLineRemoveMutation.d.ts +5 -5
  18. package/dist/esnext/components/CartProvider/graphql/CartLineUpdateMutation.d.ts +5 -5
  19. package/dist/esnext/components/CartProvider/graphql/CartNoteUpdateMutation.d.ts +5 -5
  20. package/dist/esnext/components/CartProvider/graphql/CartQuery.d.ts +5 -5
  21. package/dist/esnext/components/CartProvider/hooks.client.d.ts +1 -1
  22. package/dist/esnext/components/CartProvider/hooks.client.js +16 -11
  23. package/dist/esnext/components/CartProvider/types.d.ts +3 -3
  24. package/dist/esnext/components/CartShopPayButton/CartShopPayButton.client.d.ts +1 -3
  25. package/dist/esnext/components/CartShopPayButton/CartShopPayButton.client.js +2 -4
  26. package/dist/esnext/components/Link/Link.client.d.ts +2 -0
  27. package/dist/esnext/components/Link/Link.client.js +14 -7
  28. package/dist/esnext/components/LocalizationProvider/LocalizationClientProvider.client.d.ts +2 -2
  29. package/dist/esnext/components/LocalizationProvider/LocalizationClientProvider.client.js +1 -1
  30. package/dist/esnext/components/LocalizationProvider/LocalizationContext.client.d.ts +6 -3
  31. package/dist/esnext/components/LocalizationProvider/LocalizationProvider.server.d.ts +8 -20
  32. package/dist/esnext/components/LocalizationProvider/LocalizationProvider.server.js +18 -33
  33. package/dist/esnext/components/LocalizationProvider/index.d.ts +0 -1
  34. package/dist/esnext/components/LocalizationProvider/index.js +0 -1
  35. package/dist/esnext/components/Metafield/Metafield.client.js +3 -3
  36. package/dist/esnext/components/Seo/DefaultPageSeo.client.js +3 -3
  37. package/dist/esnext/components/Seo/DescriptionSeo.client.js +1 -1
  38. package/dist/esnext/components/Seo/HomePageSeo.client.d.ts +1 -1
  39. package/dist/esnext/components/Seo/HomePageSeo.client.js +3 -3
  40. package/dist/esnext/components/Seo/ImageSeo.client.js +1 -1
  41. package/dist/esnext/components/Seo/NoIndexSeo.client.js +3 -3
  42. package/dist/esnext/components/Seo/ProductSeo.client.js +2 -2
  43. package/dist/esnext/components/Seo/Seo.client.js +1 -1
  44. package/dist/esnext/components/Seo/TitleSeo.client.js +1 -1
  45. package/dist/esnext/components/Seo/TwitterSeo.client.js +1 -1
  46. package/dist/esnext/components/Seo/seo-types.d.ts +1 -0
  47. package/dist/esnext/components/ShopPayButton/ShopPayButton.client.d.ts +3 -1
  48. package/dist/esnext/components/ShopPayButton/ShopPayButton.client.js +8 -3
  49. package/dist/esnext/components/index.d.ts +2 -2
  50. package/dist/esnext/components/index.js +2 -2
  51. package/dist/esnext/constants.d.ts +1 -1
  52. package/dist/esnext/constants.js +1 -1
  53. package/dist/esnext/entry-client.js +7 -5
  54. package/dist/esnext/entry-server.js +40 -40
  55. package/dist/esnext/foundation/Analytics/connectors/PerformanceMetrics/PerformanceMetricsDebug.client.js +1 -1
  56. package/dist/esnext/foundation/Analytics/connectors/Shopify/ShopifyAnalytics.client.js +1 -1
  57. package/dist/esnext/foundation/FileRoutes/FileRoutes.server.js +1 -1
  58. package/dist/esnext/foundation/HydrogenRequest/HydrogenRequest.server.d.ts +9 -1
  59. package/dist/esnext/foundation/HydrogenRequest/HydrogenRequest.server.js +6 -0
  60. package/dist/esnext/foundation/Route/Route.server.js +1 -1
  61. package/dist/esnext/foundation/Router/BrowserRouter.client.d.ts +1 -1
  62. package/dist/esnext/foundation/Router/BrowserRouter.client.js +7 -5
  63. package/dist/esnext/foundation/ServerRequestProvider/ServerRequestProvider.d.ts +5 -4
  64. package/dist/esnext/foundation/ServerRequestProvider/ServerRequestProvider.js +9 -7
  65. package/dist/esnext/foundation/ShopifyProvider/ShopifyProvider.server.js +4 -0
  66. package/dist/esnext/foundation/ShopifyProvider/types.d.ts +1 -0
  67. package/dist/esnext/foundation/useNavigate/useNavigate.d.ts +2 -0
  68. package/dist/esnext/foundation/useNavigate/useNavigate.js +19 -0
  69. package/dist/esnext/foundation/useQuery/hooks.js +1 -4
  70. package/dist/esnext/foundation/useRouteParams/RouteParamsProvider.client.d.ts +3 -0
  71. package/dist/esnext/foundation/useRouteParams/RouteParamsProvider.client.js +8 -3
  72. package/dist/esnext/foundation/useUrl/useUrl.js +5 -3
  73. package/dist/esnext/framework/cache/in-memory.d.ts +12 -7
  74. package/dist/esnext/framework/cache/in-memory.js +49 -21
  75. package/dist/esnext/framework/load-config.d.ts +5 -0
  76. package/dist/esnext/framework/load-config.js +7 -0
  77. package/dist/esnext/framework/plugin.js +1 -1
  78. package/dist/esnext/framework/plugins/vite-plugin-hydrogen-client-middleware.js +2 -3
  79. package/dist/esnext/framework/plugins/vite-plugin-hydrogen-config.js +2 -2
  80. package/dist/esnext/framework/plugins/vite-plugin-hydrogen-rsc.d.ts +2 -1
  81. package/dist/esnext/framework/plugins/vite-plugin-hydrogen-rsc.js +2 -1
  82. package/dist/esnext/framework/types.d.ts +1 -0
  83. package/dist/esnext/framework/viteception.d.ts +2 -1
  84. package/dist/esnext/framework/viteception.js +2 -1
  85. package/dist/esnext/hooks/useCartLine/useCartLine.d.ts +3 -3
  86. package/dist/esnext/hooks/useLocalization/useLocalization.d.ts +4 -0
  87. package/dist/esnext/hooks/useLocalization/useLocalization.js +14 -0
  88. package/dist/esnext/hooks/useMeasurement/hooks.js +2 -2
  89. package/dist/esnext/hooks/useMoney/hooks.js +2 -2
  90. package/dist/esnext/index.d.ts +3 -0
  91. package/dist/esnext/index.js +1 -0
  92. package/dist/esnext/platforms/node.d.ts +1 -1
  93. package/dist/esnext/platforms/node.js +2 -1
  94. package/dist/esnext/storefront-api-types.d.ts +105 -3
  95. package/dist/esnext/storefront-api-types.js +8 -0
  96. package/dist/esnext/types.d.ts +10 -0
  97. package/dist/esnext/utilities/apiRoutes.d.ts +4 -3
  98. package/dist/esnext/utilities/image_size.js +11 -0
  99. package/dist/esnext/utilities/log/log-cache-api-status.js +3 -0
  100. package/dist/esnext/utilities/storefrontApi.d.ts +1 -0
  101. package/dist/esnext/utilities/storefrontApi.js +1 -1
  102. package/dist/esnext/version.d.ts +1 -1
  103. package/dist/esnext/version.js +1 -1
  104. package/dist/node/framework/cache/in-memory.d.ts +12 -7
  105. package/dist/node/framework/cache/in-memory.js +49 -21
  106. package/dist/node/framework/load-config.d.ts +5 -0
  107. package/dist/node/framework/load-config.js +11 -0
  108. package/dist/node/framework/plugin.js +1 -1
  109. package/dist/node/framework/plugins/vite-plugin-hydrogen-client-middleware.js +2 -3
  110. package/dist/node/framework/plugins/vite-plugin-hydrogen-config.js +2 -2
  111. package/dist/node/framework/plugins/vite-plugin-hydrogen-rsc.d.ts +2 -1
  112. package/dist/node/framework/plugins/vite-plugin-hydrogen-rsc.js +2 -1
  113. package/dist/node/framework/types.d.ts +1 -0
  114. package/dist/node/framework/viteception.d.ts +2 -1
  115. package/dist/node/framework/viteception.js +2 -1
  116. package/package.json +13 -3
  117. package/vendor/react-server-dom-vite/cjs/react-server-dom-vite-plugin.js +46 -17
  118. package/vendor/react-server-dom-vite/cjs/react-server-dom-vite.development.js +18 -3
  119. package/vendor/react-server-dom-vite/cjs/react-server-dom-vite.production.min.js +2 -2
  120. package/vendor/react-server-dom-vite/esm/react-server-dom-vite-client-proxy.js +2 -1
  121. package/vendor/react-server-dom-vite/esm/react-server-dom-vite-plugin.js +46 -17
  122. package/vendor/react-server-dom-vite/esm/react-server-dom-vite.js +18 -3
  123. package/dist/esnext/components/CartEstimatedCost/index.d.ts +0 -1
  124. package/dist/esnext/components/CartEstimatedCost/index.js +0 -1
  125. package/dist/esnext/hooks/useCountry/index.d.ts +0 -1
  126. package/dist/esnext/hooks/useCountry/index.js +0 -1
  127. package/dist/esnext/hooks/useCountry/useCountry.d.ts +0 -7
  128. package/dist/esnext/hooks/useCountry/useCountry.js +0 -17
@@ -1,48 +1,76 @@
1
1
  /**
2
- * This is an in-memory implementation of `Cache` that *barely*
3
- * works and is only meant to be used during development.
2
+ * This is a limited implementation of an in-memory cache.
3
+ * It only supports the `cache-control` header.
4
+ * It does NOT support `age` or `expires` headers.
5
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Cache
4
6
  */
5
7
  export class InMemoryCache {
6
- store;
8
+ #store;
7
9
  constructor() {
8
- this.store = new Map();
10
+ this.#store = new Map();
9
11
  }
10
- put(request, response) {
11
- this.store.set(request.url, {
12
- value: response,
13
- date: new Date(),
12
+ add(request) {
13
+ throw new Error('Method not implemented. Use `put` instead.');
14
+ }
15
+ addAll(requests) {
16
+ throw new Error('Method not implemented. Use `put` instead.');
17
+ }
18
+ matchAll(request, options) {
19
+ throw new Error('Method not implemented. Use `match` instead.');
20
+ }
21
+ async put(request, response) {
22
+ if (request.method !== 'GET') {
23
+ throw new TypeError('Cannot cache response to non-GET request.');
24
+ }
25
+ if (response.status === 206) {
26
+ throw new TypeError('Cannot cache response to a range request (206 Partial Content).');
27
+ }
28
+ if (response.headers.get('vary')?.includes('*')) {
29
+ throw new TypeError("Cannot cache response with 'Vary: *' header.");
30
+ }
31
+ this.#store.set(request.url, {
32
+ body: new Uint8Array(await response.arrayBuffer()),
33
+ status: response.status,
34
+ headers: [...response.headers],
35
+ timestamp: Date.now(),
14
36
  });
15
37
  }
16
- match(request) {
17
- const match = this.store.get(request.url);
38
+ async match(request) {
39
+ if (request.method !== 'GET')
40
+ return;
41
+ const match = this.#store.get(request.url);
18
42
  if (!match) {
19
43
  return;
20
44
  }
21
- const { value, date } = match;
22
- const cacheControl = value.headers.get('cache-control') || '';
45
+ const { body, timestamp, ...metadata } = match;
46
+ const headers = new Headers(metadata.headers);
47
+ const cacheControl = headers.get('cache-control') || '';
23
48
  const maxAge = parseInt(cacheControl.match(/max-age=(\d+)/)?.[1] || '0', 10);
24
49
  const swr = parseInt(cacheControl.match(/stale-while-revalidate=(\d+)/)?.[1] || '0', 10);
25
- const age = (new Date().valueOf() - date.valueOf()) / 1000;
50
+ const age = (Date.now() - timestamp) / 1000;
26
51
  const isMiss = age > maxAge + swr;
27
52
  if (isMiss) {
28
- this.store.delete(request.url);
53
+ this.#store.delete(request.url);
29
54
  return;
30
55
  }
31
56
  const isStale = age > maxAge;
32
- const headers = new Headers(value.headers);
33
57
  headers.set('cache', isStale ? 'STALE' : 'HIT');
34
- headers.set('date', date.toUTCString());
35
- const response = new Response(value.body, {
58
+ headers.set('date', new Date(timestamp).toUTCString());
59
+ return new Response(body, {
60
+ status: metadata.status ?? 200,
36
61
  headers,
37
62
  });
38
- return response;
39
63
  }
40
- delete(request) {
41
- this.store.delete(request.url);
64
+ async delete(request) {
65
+ if (this.#store.has(request.url)) {
66
+ this.#store.delete(request.url);
67
+ return true;
68
+ }
69
+ return false;
42
70
  }
43
71
  keys(request) {
44
72
  const cacheKeys = [];
45
- for (const url of this.store.keys()) {
73
+ for (const url of this.#store.keys()) {
46
74
  if (!request || request.url === url) {
47
75
  cacheKeys.push(new Request(url));
48
76
  }
@@ -0,0 +1,5 @@
1
+ export declare function loadConfig(options?: {
2
+ root: string;
3
+ }): Promise<{
4
+ configuration: any;
5
+ }>;
@@ -0,0 +1,7 @@
1
+ // Provide Hydrogen config loader to external tools like the CLI
2
+ import { VIRTUAL_PROXY_HYDROGEN_CONFIG_ID } from './plugins/vite-plugin-hydrogen-virtual-files';
3
+ import { viteception } from './viteception';
4
+ export async function loadConfig(options = { root: process.cwd() }) {
5
+ const { loaded } = await viteception([VIRTUAL_PROXY_HYDROGEN_CONFIG_ID], options);
6
+ return { configuration: loaded[0].default };
7
+ }
@@ -24,7 +24,7 @@ const hydrogenPlugin = (pluginOptions = {}) => {
24
24
  hydrationAutoImport(),
25
25
  ssrInterop(),
26
26
  cssModulesRsc(),
27
- rsc(),
27
+ rsc(pluginOptions),
28
28
  platformEntry(),
29
29
  suppressWarnings(),
30
30
  pluginOptions.purgeQueryCacheOnBuild && purgeQueryCache(),
@@ -13,9 +13,8 @@ export default () => {
13
13
  server.middlewares.use(async (req, res, next) => {
14
14
  const url = req.url;
15
15
  try {
16
- if (url.includes('.client.js') &&
17
- url.includes('?v=') &&
18
- !url.includes('node_modules')) {
16
+ if (/\.client\.[jt]sx?\?v=/.test(url) &&
17
+ !/\/node_modules\//.test(url)) {
19
18
  const result = await server.transformRequest(url, { html: false });
20
19
  if (result) {
21
20
  return send(req, res, result.code, 'js', {
@@ -12,7 +12,7 @@ export default () => {
12
12
  format: 'es',
13
13
  };
14
14
  }
15
- if (process.env.NODE_ENV !== 'development') {
15
+ if (process.env.NODE_ENV !== 'development' && !process.env.LOCAL_DEV) {
16
16
  /**
17
17
  * Ofuscate production asset name - To prevent ad blocker logics that blocks
18
18
  * certain files due to how it is named.
@@ -32,7 +32,7 @@ export default () => {
32
32
  },
33
33
  },
34
34
  build: {
35
- minify: config.build?.minify ?? 'esbuild',
35
+ minify: config.build?.minify ?? (process.env.LOCAL_DEV ? false : 'esbuild'),
36
36
  sourcemap: true,
37
37
  rollupOptions: config.build?.rollupOptions
38
38
  ? Object.assign(rollupOptions, config.build.rollupOptions)
@@ -1 +1,2 @@
1
- export default function (): any;
1
+ import { HydrogenVitePluginOptions } from '../types';
2
+ export default function (options?: HydrogenVitePluginOptions): any;
@@ -2,7 +2,7 @@
2
2
  import reactServerDomVite from '@shopify/hydrogen/vendor/react-server-dom-vite/plugin.js';
3
3
  import { HYDROGEN_DEFAULT_SERVER_ENTRY } from './vite-plugin-hydrogen-middleware';
4
4
  import { VIRTUAL_PROXY_HYDROGEN_ROUTES_ID } from './vite-plugin-hydrogen-virtual-files';
5
- export default function () {
5
+ export default function (options) {
6
6
  return reactServerDomVite({
7
7
  serverBuildEntries: [
8
8
  HYDROGEN_DEFAULT_SERVER_ENTRY,
@@ -18,5 +18,6 @@ export default function () {
18
18
  // TODO: revisit this when RSC splits into two bundles
19
19
  /\.test\.[tj]sx?$/.test(importer));
20
20
  },
21
+ ...options,
21
22
  });
22
23
  }
@@ -2,4 +2,5 @@ export interface HydrogenVitePluginOptions {
2
2
  devCache?: boolean;
3
3
  purgeQueryCacheOnBuild?: boolean;
4
4
  configPath?: string;
5
+ optimizeBoundaries?: boolean | 'build';
5
6
  }
@@ -1,4 +1,5 @@
1
- export declare function viteception(paths: string[]): Promise<{
1
+ import { InlineConfig } from 'vite';
2
+ export declare function viteception(paths: string[], options?: InlineConfig): Promise<{
2
3
  server: import("vite").ViteDevServer;
3
4
  loaded: Record<string, any>[];
4
5
  }>;
@@ -1,10 +1,11 @@
1
1
  import { createServer } from 'vite';
2
- export async function viteception(paths) {
2
+ export async function viteception(paths, options) {
3
3
  const isWorker = process.env.WORKER;
4
4
  delete process.env.WORKER;
5
5
  const server = await createServer({
6
6
  clearScreen: false,
7
7
  server: { middlewareMode: 'ssr' },
8
+ ...options,
8
9
  });
9
10
  if (isWorker) {
10
11
  process.env.WORKER = isWorker;
@@ -7,13 +7,13 @@ export declare function useCartLine(): {
7
7
  attributes: ({
8
8
  __typename?: "Attribute" | undefined;
9
9
  } & Pick<import("../../storefront-api-types").Attribute, "key" | "value">)[];
10
- estimatedCost: {
11
- __typename?: "CartLineEstimatedCost" | undefined;
10
+ cost: {
11
+ __typename?: "CartLineCost" | undefined;
12
12
  } & {
13
13
  totalAmount: {
14
14
  __typename?: "MoneyV2" | undefined;
15
15
  } & Pick<import("../../storefront-api-types").MoneyV2, "currencyCode" | "amount">;
16
- compareAtAmount?: import("../../storefront-api-types").Maybe<{
16
+ compareAtAmountPerQuantity?: import("../../storefront-api-types").Maybe<{
17
17
  __typename?: "MoneyV2" | undefined;
18
18
  } & Pick<import("../../storefront-api-types").MoneyV2, "currencyCode" | "amount">> | undefined;
19
19
  };
@@ -0,0 +1,4 @@
1
+ import { type LocalizationContextValue } from '../../components/LocalizationProvider/LocalizationContext.client';
2
+ export declare function useLocalization(): LocalizationContextValue & {
3
+ locale: string;
4
+ };
@@ -0,0 +1,14 @@
1
+ import { useMemo } from 'react';
2
+ import { LocalizationContext, } from '../../components/LocalizationProvider/LocalizationContext.client';
3
+ import { useEnvContext } from '../../foundation/ssr-interop';
4
+ export function useLocalization() {
5
+ const localization = useEnvContext((req) => req.ctx.localization, LocalizationContext);
6
+ if (localization == null) {
7
+ throw new Error('No Localization Context available');
8
+ }
9
+ const localizationValue = useMemo(() => ({
10
+ ...localization,
11
+ locale: localization.language.isoCode + '-' + localization.country.isoCode,
12
+ }), [localization]);
13
+ return localizationValue;
14
+ }
@@ -1,8 +1,8 @@
1
1
  import { useMemo } from 'react';
2
- import { useShop } from '../../foundation';
2
+ import { useLocalization } from '../useLocalization/useLocalization';
3
3
  import { getMeasurementAsParts, getMeasurementAsString } from '../../utilities';
4
4
  export function useMeasurement(measurement, options = {}) {
5
- const { locale } = useShop();
5
+ const { locale } = useLocalization();
6
6
  return useMemo(() => {
7
7
  return {
8
8
  localizedString: getMeasurementAsString(measurement, locale, options),
@@ -1,12 +1,12 @@
1
1
  import { useMemo } from 'react';
2
- import { useShop } from '../../foundation/useShop';
2
+ import { useLocalization } from '../useLocalization/useLocalization';
3
3
  /**
4
4
  * The `useMoney` hook takes a [MoneyV2 object](https://shopify.dev/api/storefront/reference/common-objects/moneyv2) and returns a
5
5
  * default-formatted string of the amount with the correct currency indicator, along with some of the parts provided by
6
6
  * [Intl.NumberFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat).
7
7
  */
8
8
  export function useMoney(money) {
9
- const { locale } = useShop();
9
+ const { locale } = useLocalization();
10
10
  const amount = parseFloat(money.amount);
11
11
  const options = useMemo(() => ({
12
12
  style: 'currency',
@@ -25,6 +25,7 @@ export { useServerAnalytics } from './foundation/Analytics/hook';
25
25
  export { ShopifyAnalytics } from './foundation/Analytics/connectors/Shopify/ShopifyAnalytics.server';
26
26
  export { ShopifyAnalyticsConstants } from './foundation/Analytics/connectors/Shopify/const';
27
27
  export { useSession } from './foundation/useSession/useSession';
28
+ export { useLocalization } from './hooks/useLocalization/useLocalization';
28
29
  export { Cookie } from './foundation/Cookie/Cookie';
29
30
  /**
30
31
  * Export server-only CartQuery here instead of `CartProvider.client` to prevent
@@ -37,3 +38,5 @@ export { CartQuery } from './components/CartProvider/cart-queries';
37
38
  export { fetchSync } from './foundation/fetchSync/server/fetchSync';
38
39
  export { type HydrogenRequest } from './foundation/HydrogenRequest/HydrogenRequest.server';
39
40
  export { type HydrogenResponse } from './foundation/HydrogenResponse/HydrogenResponse.server';
41
+ export { type HydrogenRouteProps } from './types';
42
+ export { type ResourceGetter as HydrogenApiRoute, RequestOptions as HydrogenApiRouteOptions, } from './utilities/apiRoutes';
@@ -25,6 +25,7 @@ export { useServerAnalytics } from './foundation/Analytics/hook';
25
25
  export { ShopifyAnalytics } from './foundation/Analytics/connectors/Shopify/ShopifyAnalytics.server';
26
26
  export { ShopifyAnalyticsConstants } from './foundation/Analytics/connectors/Shopify/const';
27
27
  export { useSession } from './foundation/useSession/useSession';
28
+ export { useLocalization } from './hooks/useLocalization/useLocalization';
28
29
  export { Cookie } from './foundation/Cookie/Cookie';
29
30
  /**
30
31
  * Export server-only CartQuery here instead of `CartProvider.client` to prevent
@@ -3,7 +3,7 @@ import connect from 'connect';
3
3
  declare type CreateServerOptions = {
4
4
  cache?: Cache;
5
5
  };
6
- export declare function createServer({ cache }?: CreateServerOptions): Promise<{
6
+ export declare function createServer({ cache, }?: CreateServerOptions): Promise<{
7
7
  app: connect.Server;
8
8
  }>;
9
9
  export {};
@@ -13,8 +13,9 @@ import serveStatic from 'serve-static';
13
13
  import compression from 'compression';
14
14
  import bodyParser from 'body-parser';
15
15
  import connect from 'connect';
16
+ import { InMemoryCache } from '../framework/cache/in-memory';
16
17
  const handleRequest = entrypoint;
17
- export async function createServer({ cache } = {}) {
18
+ export async function createServer({ cache = new InMemoryCache(), } = {}) {
18
19
  // @ts-ignore
19
20
  globalThis.Oxygen = { env: process.env };
20
21
  const app = connect();
@@ -401,22 +401,31 @@ export declare enum CardBrand {
401
401
  /** A cart represents the merchandise that a buyer intends to purchase, and the estimated cost associated with the cart. To learn how to interact with a cart during a customer's session, refer to [Manage a cart with the Storefront API](https://shopify.dev/api/examples/cart). */
402
402
  export declare type Cart = Node & {
403
403
  __typename?: 'Cart';
404
+ /** An attribute associated with the cart. */
405
+ attribute?: Maybe<Attribute>;
404
406
  /** The attributes associated with the cart. Attributes are represented as key-value pairs. */
405
407
  attributes: Array<Attribute>;
406
408
  /** Information about the buyer that is interacting with the cart. */
407
409
  buyerIdentity: CartBuyerIdentity;
408
410
  /** The URL of the checkout for the cart. */
409
411
  checkoutUrl: Scalars['URL'];
412
+ /** The estimated costs that the buyer will pay at checkout. The costs are subject to change and changes will be reflected at checkout. The `cost` field uses the `buyerIdentity` field to determine [international pricing](https://shopify.dev/api/examples/international-pricing#create-a-cart). */
413
+ cost: CartCost;
410
414
  /** The date and time when the cart was created. */
411
415
  createdAt: Scalars['DateTime'];
412
416
  /** The delivery groups available for the cart, based on the default address of the logged-in customer. */
413
417
  deliveryGroups: CartDeliveryGroupConnection;
418
+ /** The discounts that have been applied to the entire cart. */
419
+ discountAllocations: Array<CartAutomaticDiscountAllocation | CartCodeDiscountAllocation | CartCustomDiscountAllocation>;
414
420
  /**
415
421
  * The case-insensitive discount codes that the customer added at checkout.
416
422
  *
417
423
  */
418
424
  discountCodes: Array<CartDiscountCode>;
419
- /** The estimated costs that the buyer will pay at checkout. The estimated costs are subject to change and changes will be reflected at checkout. The `estimatedCost` field uses the `buyerIdentity` field to determine [international pricing](https://shopify.dev/api/examples/international-pricing#create-a-cart). */
425
+ /**
426
+ * The estimated costs that the buyer will pay at checkout. The estimated costs are subject to change and changes will be reflected at checkout. The `estimatedCost` field uses the `buyerIdentity` field to determine [international pricing](https://shopify.dev/api/examples/international-pricing#create-a-cart).
427
+ * @deprecated Use `cost` instead
428
+ */
420
429
  estimatedCost: CartEstimatedCost;
421
430
  /** A globally-unique identifier. */
422
431
  id: Scalars['ID'];
@@ -430,6 +439,10 @@ export declare type Cart = Node & {
430
439
  updatedAt: Scalars['DateTime'];
431
440
  };
432
441
  /** A cart represents the merchandise that a buyer intends to purchase, and the estimated cost associated with the cart. To learn how to interact with a cart during a customer's session, refer to [Manage a cart with the Storefront API](https://shopify.dev/api/examples/cart). */
442
+ export declare type CartAttributeArgs = {
443
+ key: Scalars['String'];
444
+ };
445
+ /** A cart represents the merchandise that a buyer intends to purchase, and the estimated cost associated with the cart. To learn how to interact with a cart during a customer's session, refer to [Manage a cart with the Storefront API](https://shopify.dev/api/examples/cart). */
433
446
  export declare type CartDeliveryGroupsArgs = {
434
447
  after?: InputMaybe<Scalars['String']>;
435
448
  before?: InputMaybe<Scalars['String']>;
@@ -506,6 +519,33 @@ export declare type CartCodeDiscountAllocation = CartDiscountAllocation & {
506
519
  /** The discounted amount that has been applied to the cart line. */
507
520
  discountedAmount: MoneyV2;
508
521
  };
522
+ /**
523
+ * The costs that the buyer will pay at checkout.
524
+ * It uses [`CartBuyerIdentity`](https://shopify.dev/api/storefront/reference/cart/cartbuyeridentity) to determine
525
+ * [international pricing](https://shopify.dev/api/examples/international-pricing#create-a-cart).
526
+ *
527
+ */
528
+ export declare type CartCost = {
529
+ __typename?: 'CartCost';
530
+ /** The estimated amount, before taxes and discounts, for the customer to pay at checkout. The checkout charge amount doesn't include any deferred payments that'll be paid at a later date. If the cart has no deferred payments, the checkout charge amount is equivalent to subtotalAmount. */
531
+ checkoutChargeAmount: MoneyV2;
532
+ /** The amount, before taxes and cart-level discounts, for the customer to pay. */
533
+ subtotalAmount: MoneyV2;
534
+ /** Whether or not the subtotal amount is estimated. */
535
+ subtotalAmountEstimated: Scalars['Boolean'];
536
+ /** The total amount for the customer to pay. */
537
+ totalAmount: MoneyV2;
538
+ /** Whether or not the total amount is estimated. */
539
+ totalAmountEstimated: Scalars['Boolean'];
540
+ /** The duty amount for the customer to pay at checkout. */
541
+ totalDutyAmount?: Maybe<MoneyV2>;
542
+ /** Whether or not the total duty amount is estimated. */
543
+ totalDutyAmountEstimated: Scalars['Boolean'];
544
+ /** The tax amount for the customer to pay at checkout. */
545
+ totalTaxAmount?: Maybe<MoneyV2>;
546
+ /** Whether or not the total tax amount is estimated. */
547
+ totalTaxAmountEstimated: Scalars['Boolean'];
548
+ };
509
549
  /** Return type for `cartCreate` mutation. */
510
550
  export declare type CartCreatePayload = {
511
551
  __typename?: 'CartCreatePayload';
@@ -514,6 +554,14 @@ export declare type CartCreatePayload = {
514
554
  /** The list of errors that occurred from executing the mutation. */
515
555
  userErrors: Array<CartUserError>;
516
556
  };
557
+ /** The discounts automatically applied to the cart line based on prerequisites that have been met. */
558
+ export declare type CartCustomDiscountAllocation = CartDiscountAllocation & {
559
+ __typename?: 'CartCustomDiscountAllocation';
560
+ /** The discounted amount that has been applied to the cart line. */
561
+ discountedAmount: MoneyV2;
562
+ /** The title of the allocated discount. */
563
+ title: Scalars['String'];
564
+ };
517
565
  /** Information about the options available for one or more line items to be delivered to a specific address. */
518
566
  export declare type CartDeliveryGroup = {
519
567
  __typename?: 'CartDeliveryGroup';
@@ -614,6 +662,8 @@ export declare enum CartErrorCode {
614
662
  */
615
663
  export declare type CartEstimatedCost = {
616
664
  __typename?: 'CartEstimatedCost';
665
+ /** The estimated amount, before taxes and discounts, for the customer to pay at checkout. The checkout charge amount doesn't include any deferred payments that'll be paid at a later date. If the cart has no deferred payments, the checkout charge amount is equivalent to subtotalAmount. */
666
+ checkoutChargeAmount: MoneyV2;
617
667
  /** The estimated amount, before taxes and discounts, for the customer to pay. */
618
668
  subtotalAmount: MoneyV2;
619
669
  /** The estimated total amount for the customer to pay. */
@@ -642,11 +692,18 @@ export declare type CartInput = {
642
692
  /** Represents information about the merchandise in the cart. */
643
693
  export declare type CartLine = Node & {
644
694
  __typename?: 'CartLine';
695
+ /** An attribute associated with the cart line. */
696
+ attribute?: Maybe<Attribute>;
645
697
  /** The attributes associated with the cart line. Attributes are represented as key-value pairs. */
646
698
  attributes: Array<Attribute>;
699
+ /** The cost of the merchandise that the buyer will pay for at checkout. The costs are subject to change and changes will be reflected at checkout. */
700
+ cost: CartLineCost;
647
701
  /** The discounts that have been applied to the cart line. */
648
- discountAllocations: Array<CartAutomaticDiscountAllocation | CartCodeDiscountAllocation>;
649
- /** The estimated cost of the merchandise that the buyer will pay for at checkout. The estimated costs are subject to change and changes will be reflected at checkout. */
702
+ discountAllocations: Array<CartAutomaticDiscountAllocation | CartCodeDiscountAllocation | CartCustomDiscountAllocation>;
703
+ /**
704
+ * The estimated cost of the merchandise that the buyer will pay for at checkout. The estimated costs are subject to change and changes will be reflected at checkout.
705
+ * @deprecated Use `cost` instead
706
+ */
650
707
  estimatedCost: CartLineEstimatedCost;
651
708
  /** A globally-unique identifier. */
652
709
  id: Scalars['ID'];
@@ -657,6 +714,10 @@ export declare type CartLine = Node & {
657
714
  /** The selling plan associated with the cart line and the effect that each selling plan has on variants when they're purchased. */
658
715
  sellingPlanAllocation?: Maybe<SellingPlanAllocation>;
659
716
  };
717
+ /** Represents information about the merchandise in the cart. */
718
+ export declare type CartLineAttributeArgs = {
719
+ key: Scalars['String'];
720
+ };
660
721
  /**
661
722
  * An auto-generated type for paginating through multiple CartLines.
662
723
  *
@@ -670,6 +731,18 @@ export declare type CartLineConnection = {
670
731
  /** Information to aid in pagination. */
671
732
  pageInfo: PageInfo;
672
733
  };
734
+ /** The cost of the merchandise line that the buyer will pay at checkout. */
735
+ export declare type CartLineCost = {
736
+ __typename?: 'CartLineCost';
737
+ /** The amount of the merchandise line. */
738
+ amountPerQuantity: MoneyV2;
739
+ /** The compare at amount of the merchandise line. */
740
+ compareAtAmountPerQuantity?: Maybe<MoneyV2>;
741
+ /** The cost of the merchandise line before line-level discounts. */
742
+ subtotalAmount: MoneyV2;
743
+ /** The total cost of the merchandise line. */
744
+ totalAmount: MoneyV2;
745
+ };
673
746
  /**
674
747
  * An auto-generated type which holds one CartLine and a cursor during pagination.
675
748
  *
@@ -5457,6 +5530,8 @@ export declare type SelectedOptionInput = {
5457
5530
  /** Represents how products and variants can be sold and purchased. */
5458
5531
  export declare type SellingPlan = {
5459
5532
  __typename?: 'SellingPlan';
5533
+ /** The initial payment due for the purchase. */
5534
+ checkoutCharge: SellingPlanCheckoutCharge;
5460
5535
  /** The description of the selling plan. */
5461
5536
  description?: Maybe<Scalars['String']>;
5462
5537
  /** A globally-unique identifier. */
@@ -5473,8 +5548,12 @@ export declare type SellingPlan = {
5473
5548
  /** Represents an association between a variant and a selling plan. Selling plan allocations describe the options offered for each variant, and the price of the variant when purchased with a selling plan. */
5474
5549
  export declare type SellingPlanAllocation = {
5475
5550
  __typename?: 'SellingPlanAllocation';
5551
+ /** The checkout charge amount due for the purchase. */
5552
+ checkoutChargeAmount: MoneyV2;
5476
5553
  /** A list of price adjustments, with a maximum of two. When there are two, the first price adjustment goes into effect at the time of purchase, while the second one starts after a certain number of orders. A price adjustment represents how a selling plan affects pricing when a variant is purchased with a selling plan. Prices display in the customer's currency if the shop is configured for it. */
5477
5554
  priceAdjustments: Array<SellingPlanAllocationPriceAdjustment>;
5555
+ /** The remaining balance charge amount due for the purchase. */
5556
+ remainingBalanceChargeAmount: MoneyV2;
5478
5557
  /** A representation of how products and variants can be sold and purchased. For example, an individual selling plan could be '6 weeks of prepaid granola, delivered weekly'. */
5479
5558
  sellingPlan: SellingPlan;
5480
5559
  };
@@ -5514,6 +5593,29 @@ export declare type SellingPlanAllocationPriceAdjustment = {
5514
5593
  /** The resulting price per unit for the variant associated with the selling plan. If the variant isn't sold by quantity or measurement, then this field returns `null`. */
5515
5594
  unitPrice?: Maybe<MoneyV2>;
5516
5595
  };
5596
+ /** The initial payment due for the purchase. */
5597
+ export declare type SellingPlanCheckoutCharge = {
5598
+ __typename?: 'SellingPlanCheckoutCharge';
5599
+ /** The charge type for the checkout charge. */
5600
+ type: SellingPlanCheckoutChargeType;
5601
+ /** The charge value for the checkout charge. */
5602
+ value: SellingPlanCheckoutChargeValue;
5603
+ };
5604
+ /** The percentage value of the price used for checkout charge. */
5605
+ export declare type SellingPlanCheckoutChargePercentageValue = {
5606
+ __typename?: 'SellingPlanCheckoutChargePercentageValue';
5607
+ /** The percentage value of the price used for checkout charge. */
5608
+ percentage: Scalars['Float'];
5609
+ };
5610
+ /** The checkout charge when the full amount isn't charged at checkout. */
5611
+ export declare enum SellingPlanCheckoutChargeType {
5612
+ /** The checkout charge is a percentage of the product or variant price. */
5613
+ Percentage = "PERCENTAGE",
5614
+ /** The checkout charge is a fixed price amount. */
5615
+ Price = "PRICE"
5616
+ }
5617
+ /** The portion of the price to be charged at checkout. */
5618
+ export declare type SellingPlanCheckoutChargeValue = MoneyV2 | SellingPlanCheckoutChargePercentageValue;
5517
5619
  /**
5518
5620
  * An auto-generated type for paginating through multiple SellingPlans.
5519
5621
  *
@@ -1673,6 +1673,14 @@ export var ProductVariantSortKeys;
1673
1673
  /** Sort by the `title` value. */
1674
1674
  ProductVariantSortKeys["Title"] = "TITLE";
1675
1675
  })(ProductVariantSortKeys || (ProductVariantSortKeys = {}));
1676
+ /** The checkout charge when the full amount isn't charged at checkout. */
1677
+ export var SellingPlanCheckoutChargeType;
1678
+ (function (SellingPlanCheckoutChargeType) {
1679
+ /** The checkout charge is a percentage of the product or variant price. */
1680
+ SellingPlanCheckoutChargeType["Percentage"] = "PERCENTAGE";
1681
+ /** The checkout charge is a fixed price amount. */
1682
+ SellingPlanCheckoutChargeType["Price"] = "PRICE";
1683
+ })(SellingPlanCheckoutChargeType || (SellingPlanCheckoutChargeType = {}));
1676
1684
  /** The different kinds of order transactions. */
1677
1685
  export var TransactionKind;
1678
1686
  (function (TransactionKind) {
@@ -62,6 +62,7 @@ export declare type InlineHydrogenConfig = ClientConfig & {
62
62
  serverAnalyticsConnectors?: Array<ServerAnalyticsConnector>;
63
63
  logger?: LoggerConfig;
64
64
  session?: (log: Logger) => SessionStorageAdapter;
65
+ poweredByHeader?: boolean;
65
66
  __EXPERIMENTAL__devTools?: boolean;
66
67
  };
67
68
  export declare type ResolvedHydrogenConfig = Omit<InlineHydrogenConfig, 'routes'> & {
@@ -103,3 +104,12 @@ export interface AllCacheOptions {
103
104
  }
104
105
  export declare type CachingStrategy = AllCacheOptions;
105
106
  export declare type PreloadOptions = boolean | string;
107
+ export declare type HydrogenRouteProps = {
108
+ request: HydrogenRequest;
109
+ response: HydrogenResponse;
110
+ log: Logger;
111
+ params: Record<string, any>;
112
+ pathname: string;
113
+ search: string;
114
+ [key: string]: any;
115
+ };
@@ -1,14 +1,15 @@
1
1
  import { ResolvedHydrogenConfig, ResolvedHydrogenRoutes } from '../types';
2
2
  import type { HydrogenRequest } from '../foundation/HydrogenRequest/HydrogenRequest.server';
3
3
  import { SessionApi, SessionStorageAdapter } from '../foundation/session/session';
4
+ import { UseShopQueryResponse } from '../hooks/useShopQuery/hooks';
4
5
  declare type RouteParams = Record<string, string>;
5
- declare type RequestOptions = {
6
+ export declare type RequestOptions = {
6
7
  params: RouteParams;
7
- queryShop: (args: QueryShopArgs) => Promise<any>;
8
+ queryShop: <T>(args: QueryShopArgs) => Promise<UseShopQueryResponse<T>>;
8
9
  session: SessionApi | null;
9
10
  hydrogenConfig: ResolvedHydrogenConfig;
10
11
  };
11
- export declare type ResourceGetter = (request: Request, requestOptions: RequestOptions) => Promise<Response | Object | String>;
12
+ export declare type ResourceGetter = (request: HydrogenRequest, requestOptions: RequestOptions) => Promise<Response | Object | String>;
12
13
  interface HydrogenApiRoute {
13
14
  path: string;
14
15
  resource: ResourceGetter;
@@ -11,6 +11,17 @@ const ALL_CDN_HOSTNAMES = [...PRODUCTION_CDN_HOSTNAMES, ...LOCAL_CDN_HOSTNAMES];
11
11
  * Adds image size parameters to an image URL hosted by Shopify's CDN
12
12
  */
13
13
  export function addImageSizeParametersToUrl({ src, width, height, crop, scale, }) {
14
+ if (scale) {
15
+ // Have to do this specifically for 'scale' because it doesn't currently work otherwise.
16
+ // I'm also intentionally leaving 'scale' as a searchParam because that way it'll "just work" in the future and we can just delete this whole section of code
17
+ // We assume here that the last `.` is the delimiter between the file name and the file type
18
+ const baseUrl = new URL(src);
19
+ const fileDelimiterIndex = baseUrl.pathname.lastIndexOf('.');
20
+ const fileName = baseUrl.pathname.slice(0, fileDelimiterIndex);
21
+ const fileType = baseUrl.pathname.slice(fileDelimiterIndex);
22
+ baseUrl.pathname = `${fileName}${`@${scale.toString()}x`}${fileType}`;
23
+ src = baseUrl.toString();
24
+ }
14
25
  const newUrl = new URL(src);
15
26
  width && newUrl.searchParams.append('width', width.toString());
16
27
  height && newUrl.searchParams.append('height', height.toString());
@@ -9,6 +9,9 @@ export function logCacheApiStatus(status, url) {
9
9
  if (url.includes('shopify.dev')) {
10
10
  url = decodeURIComponent(url);
11
11
  queryName = findQueryName(url);
12
+ if (url.includes('?lock')) {
13
+ queryName += '-lock';
14
+ }
12
15
  }
13
16
  log.debug(gray(`[Cache] ${status?.padEnd(8)} ${queryName ? `query ${queryName}` : url}`));
14
17
  }
@@ -2,3 +2,4 @@ export declare function getStorefrontApiRequestHeaders({ buyerIp, storefrontToke
2
2
  buyerIp?: string | null;
3
3
  storefrontToken: string;
4
4
  }): Record<string, any>;
5
+ export declare function getOxygenVariable(key: string): any;
@@ -21,6 +21,6 @@ export function getStorefrontApiRequestHeaders({ buyerIp, storefrontToken, }) {
21
21
  }
22
22
  return headers;
23
23
  }
24
- function getOxygenVariable(key) {
24
+ export function getOxygenVariable(key) {
25
25
  return typeof Oxygen !== 'undefined' ? Oxygen?.env?.[key] : null;
26
26
  }
@@ -1 +1 @@
1
- export declare const LIB_VERSION = "0.25.0";
1
+ export declare const LIB_VERSION = "0.26.1";
@@ -1 +1 @@
1
- export const LIB_VERSION = '0.25.0';
1
+ export const LIB_VERSION = '0.26.1';