@shopify/hydrogen 2024.1.3 → 2024.1.5

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.
@@ -1,7 +1,6 @@
1
1
  'use strict';
2
2
 
3
3
  var hydrogenReact = require('@shopify/hydrogen-react');
4
- var serverRuntime = require('@remix-run/server-runtime');
5
4
  var react = require('react');
6
5
  var react$1 = require('@remix-run/react');
7
6
  var jsxRuntime = require('react/jsx-runtime');
@@ -493,7 +492,7 @@ var warnOnce = (string) => {
493
492
  };
494
493
 
495
494
  // src/version.ts
496
- var LIB_VERSION = "2024.1.3";
495
+ var LIB_VERSION = "2024.1.5";
497
496
 
498
497
  // src/utils/graphql.ts
499
498
  function minifyQuery(string) {
@@ -1061,10 +1060,15 @@ async function storefrontRedirect(options) {
1061
1060
  noAdminRedirect,
1062
1061
  response = new Response("Not Found", { status: 404 })
1063
1062
  } = options;
1064
- const { pathname, search } = new URL(request.url);
1065
- const redirectFrom = pathname + search;
1066
- if (pathname === "/admin" && !noAdminRedirect) {
1067
- return serverRuntime.redirect(`${storefront.getShopifyDomain()}/admin`);
1063
+ const url = new URL(request.url);
1064
+ const isSoftNavigation = url.searchParams.has("_data");
1065
+ url.searchParams.delete("_data");
1066
+ const redirectFrom = url.toString().replace(url.origin, "");
1067
+ if (url.pathname === "/admin" && !noAdminRedirect) {
1068
+ return createRedirectResponse(
1069
+ `${storefront.getShopifyDomain()}/admin`,
1070
+ isSoftNavigation
1071
+ );
1068
1072
  }
1069
1073
  try {
1070
1074
  const { urlRedirects } = await storefront.query(REDIRECT_QUERY, {
@@ -1072,11 +1076,11 @@ async function storefrontRedirect(options) {
1072
1076
  });
1073
1077
  const location = urlRedirects?.edges?.[0]?.node?.target;
1074
1078
  if (location) {
1075
- return new Response(null, { status: 301, headers: { location } });
1079
+ return createRedirectResponse(location, isSoftNavigation);
1076
1080
  }
1077
1081
  const redirectTo = getRedirectUrl(request.url);
1078
1082
  if (redirectTo) {
1079
- return serverRuntime.redirect(redirectTo);
1083
+ return createRedirectResponse(redirectTo, isSoftNavigation);
1080
1084
  }
1081
1085
  } catch (error) {
1082
1086
  console.error(
@@ -1086,6 +1090,19 @@ async function storefrontRedirect(options) {
1086
1090
  }
1087
1091
  return response;
1088
1092
  }
1093
+ function createRedirectResponse(location, isSoftNavigation) {
1094
+ if (isSoftNavigation) {
1095
+ return new Response(null, {
1096
+ status: 200,
1097
+ headers: { "X-Remix-Redirect": location, "X-Remix-Status": "302" }
1098
+ });
1099
+ } else {
1100
+ return new Response(null, {
1101
+ status: 302,
1102
+ headers: { location }
1103
+ });
1104
+ }
1105
+ }
1089
1106
  var REDIRECT_QUERY = `#graphql
1090
1107
  query redirects($query: String) {
1091
1108
  urlRedirects(first: 1, query: $query) {
@@ -1410,6 +1427,19 @@ var graphiqlLoader = async function graphiqlLoader2({
1410
1427
  );
1411
1428
  };
1412
1429
 
1430
+ // src/seo/escape.ts
1431
+ var ESCAPE_LOOKUP = {
1432
+ "&": "\\u0026",
1433
+ ">": "\\u003e",
1434
+ "<": "\\u003c",
1435
+ "\u2028": "\\u2028",
1436
+ "\u2029": "\\u2029"
1437
+ };
1438
+ var ESCAPE_REGEX = /[&><\u2028\u2029]/g;
1439
+ function escapeHtml(html) {
1440
+ return html.replace(ESCAPE_REGEX, (match) => ESCAPE_LOOKUP[match]);
1441
+ }
1442
+
1413
1443
  // src/seo/generate-seo-tags.ts
1414
1444
  var ERROR_PREFIX = "Error in SEO input: ";
1415
1445
  var schema = {
@@ -1585,7 +1615,9 @@ function generateSeoTags(seoInput) {
1585
1615
  "script",
1586
1616
  {
1587
1617
  type: "application/ld+json",
1588
- children: JSON.stringify(block)
1618
+ children: JSON.stringify(block, (k, value) => {
1619
+ return typeof value === "string" ? escapeHtml(value) : value;
1620
+ })
1589
1621
  },
1590
1622
  // @ts-expect-error
1591
1623
  `json-ld-${block?.["@type"] || block?.name || index++}`
@@ -2061,7 +2093,7 @@ var logSubRequestEvent = ({
2061
2093
  }
2062
2094
  });
2063
2095
  } ;
2064
- function redirect2(path, options = {}) {
2096
+ function redirect(path, options = {}) {
2065
2097
  const headers = options.headers ? new Headers(options.headers) : new Headers({});
2066
2098
  headers.set("location", path);
2067
2099
  return new Response(null, { status: options.status || 302, headers });
@@ -2281,7 +2313,7 @@ function defaultAuthStatusHandler(request) {
2281
2313
  return DEFAULT_LOGIN_URL;
2282
2314
  const { pathname } = new URL(request.url);
2283
2315
  const redirectTo = DEFAULT_LOGIN_URL + `?${new URLSearchParams({ return_to: pathname }).toString()}`;
2284
- return redirect2(redirectTo);
2316
+ return redirect(redirectTo);
2285
2317
  }
2286
2318
  function createCustomerAccountClient({
2287
2319
  session,
@@ -2452,7 +2484,7 @@ function createCustomerAccountClient({
2452
2484
  });
2453
2485
  loginUrl.searchParams.append("code_challenge", challenge);
2454
2486
  loginUrl.searchParams.append("code_challenge_method", "S256");
2455
- return redirect2(loginUrl.toString(), {
2487
+ return redirect(loginUrl.toString(), {
2456
2488
  headers: {
2457
2489
  "Set-Cookie": await session.commit()
2458
2490
  }
@@ -2461,7 +2493,7 @@ function createCustomerAccountClient({
2461
2493
  logout: async () => {
2462
2494
  const idToken = session.get(CUSTOMER_ACCOUNT_SESSION_KEY)?.idToken;
2463
2495
  clearSession(session);
2464
- return redirect2(
2496
+ return redirect(
2465
2497
  `${customerAccountUrl}/auth/logout?id_token_hint=${idToken}`,
2466
2498
  {
2467
2499
  status: 302,
@@ -2591,7 +2623,7 @@ function createCustomerAccountClient({
2591
2623
  idToken: id_token,
2592
2624
  redirectPath: void 0
2593
2625
  });
2594
- return redirect2(redirectPath || DEFAULT_REDIRECT_PATH, {
2626
+ return redirect(redirectPath || DEFAULT_REDIRECT_PATH, {
2595
2627
  headers: {
2596
2628
  "Set-Cookie": await session.commit()
2597
2629
  }
@@ -2615,9 +2647,10 @@ function CartForm({
2615
2647
  children,
2616
2648
  action,
2617
2649
  inputs,
2618
- route
2650
+ route,
2651
+ fetcherKey
2619
2652
  }) {
2620
- const fetcher = react$1.useFetcher();
2653
+ const fetcher = react$1.useFetcher({ key: fetcherKey });
2621
2654
  return /* @__PURE__ */ jsxRuntime.jsxs(fetcher.Form, { action: route || "", method: "post", children: [
2622
2655
  (action || inputs) && /* @__PURE__ */ jsxRuntime.jsx(
2623
2656
  "input",