diff --git a/.env b/.env index 548fd48..5488365 100644 --- a/.env +++ b/.env @@ -4,5 +4,5 @@ SESSION_SECRET="foobar" PUBLIC_STOREFRONT_API_TOKEN=33ad0f277e864013b8e3c21d19432501 PUBLIC_STORE_DOMAIN=hydrogen-preview.myshopify.com PUBLIC_CUSTOMER_ACCOUNT_API_CLIENT_ID=shp_3cecd990-4824-4e27-beb2-46c8e822ec14 -PUBLIC_CUSTOMER_ACCOUNT_API_URL=https://shopify.com/55145660472 PUBLIC_CHECKOUT_DOMAIN=checkout.hydrogen.shop +SHOP_ID=55145660472 diff --git a/.hydrogen/upgrade-2024.7.1-to-2024.10.0.md b/.hydrogen/upgrade-2024.7.1-to-2024.10.0.md new file mode 100644 index 0000000..f1d4cb4 --- /dev/null +++ b/.hydrogen/upgrade-2024.7.1-to-2024.10.0.md @@ -0,0 +1,304 @@ +# Hydrogen upgrade guide: 2024.7.1 to 2024.10.0 + +--- + +## Features + +### Stabilize getSitemap, getSitemapIndex and implement on skeleton [#2589](https://github.com/Shopify/hydrogen/pull/2589) + +#### Step: 1. Update the getSitemapIndex at /app/routes/[sitemap.xml].tsx [#2589](https://github.com/Shopify/hydrogen/pull/2589) + +[#2589](https://github.com/Shopify/hydrogen/pull/2589) + +```diff +- import {unstable__getSitemapIndex as getSitemapIndex} from '@shopify/hydrogen'; ++ import {getSitemapIndex} from '@shopify/hydrogen'; +``` + +#### Step: 2. Update the getSitemap at /app/routes/sitemap.$type.$page[.xml].tsx [#2589](https://github.com/Shopify/hydrogen/pull/2589) + +[#2589](https://github.com/Shopify/hydrogen/pull/2589) + +```diff +- import {unstable__getSitemap as getSitemap} from '@shopify/hydrogen'; ++ import {getSitemap} from '@shopify/hydrogen'; +``` + +### H2O compatibility date [#2380](https://github.com/Shopify/hydrogen/pull/2380) + +#### Check your project is working properly in an Oxygen deployment + +[#2380](https://github.com/Shopify/hydrogen/pull/2380) + +### Simplified creation of app context. [#2333](https://github.com/Shopify/hydrogen/pull/2333) + +#### Step: 1. Create a app/lib/context file and use `createHydrogenContext` in it. [#2333](https://github.com/Shopify/hydrogen/pull/2333) + +[#2333](https://github.com/Shopify/hydrogen/pull/2333) + +```.ts +// in app/lib/context + +import {createHydrogenContext} from '@shopify/hydrogen'; + +export async function createAppLoadContext( + request: Request, + env: Env, + executionContext: ExecutionContext, +) { + const hydrogenContext = createHydrogenContext({ + env, + request, + cache, + waitUntil, + session, + i18n: {language: 'EN', country: 'US'}, + cart: { + queryFragment: CART_QUERY_FRAGMENT, + }, + // ensure to overwrite any options that is not using the default values from your server.ts + }); + + return { + ...hydrogenContext, + // declare additional Remix loader context + }; +} + +``` + +#### Step: 2. Use `createAppLoadContext` method in server.ts Ensure to overwrite any options that is not using the default values in `createHydrogenContext` [#2333](https://github.com/Shopify/hydrogen/pull/2333) + +[#2333](https://github.com/Shopify/hydrogen/pull/2333) + +```diff +// in server.ts + +- import { +- createCartHandler, +- createStorefrontClient, +- createCustomerAccountClient, +- } from '@shopify/hydrogen'; ++ import {createAppLoadContext} from '~/lib/context'; + +export default { + async fetch( + request: Request, + env: Env, + executionContext: ExecutionContext, + ): Promise { + +- const {storefront} = createStorefrontClient( +- ... +- ); + +- const customerAccount = createCustomerAccountClient( +- ... +- ); + +- const cart = createCartHandler( +- ... +- ); + ++ const appLoadContext = await createAppLoadContext( ++ request, ++ env, ++ executionContext, ++ ); + + /** + * Create a Remix request handler and pass + * Hydrogen's Storefront client to the loader context. + */ + const handleRequest = createRequestHandler({ + build: remixBuild, + mode: process.env.NODE_ENV, +- getLoadContext: (): AppLoadContext => ({ +- session, +- storefront, +- customerAccount, +- cart, +- env, +- waitUntil, +- }), ++ getLoadContext: () => appLoadContext, + }); + } +``` + +#### Step: 3. Use infer type for AppLoadContext in env.d.ts [#2333](https://github.com/Shopify/hydrogen/pull/2333) + +[#2333](https://github.com/Shopify/hydrogen/pull/2333) + +```diff +// in env.d.ts + ++ import type {createAppLoadContext} from '~/lib/context'; + ++ interface AppLoadContext extends Awaited> { +- interface AppLoadContext { +- env: Env; +- cart: HydrogenCart; +- storefront: Storefront; +- customerAccount: CustomerAccount; +- session: AppSession; +- waitUntil: ExecutionContext['waitUntil']; +} + +``` + +--- + +--- + +## Fixes + +### Make set up cookie banner by default to false [#2588](https://github.com/Shopify/hydrogen/pull/2588) + +#### If you are using Shopify's cookie banner to handle user consent in your app, you need to set `withPrivacyBanner: true` to the consent config. Without this update, the Shopify cookie banner will not appear. + +[#2588](https://github.com/Shopify/hydrogen/pull/2588) + +```diff + return defer({ + ... + consent: { + checkoutDomain: env.PUBLIC_CHECKOUT_DOMAIN, + storefrontAccessToken: env.PUBLIC_STOREFRONT_API_TOKEN, ++ withPrivacyBanner: true, + // localize the privacy banner + country: args.context.storefront.i18n.country, + language: args.context.storefront.i18n.language, + }, + }); +``` + +### Deprecate usages of product.options.values and use product.options.optionValues instead [#2585](https://github.com/Shopify/hydrogen/pull/2585) + +#### Step: 1. Update your product graphql query to use the new `optionValues` field [#2585](https://github.com/Shopify/hydrogen/pull/2585) + +[#2585](https://github.com/Shopify/hydrogen/pull/2585) + +```diff + const PRODUCT_FRAGMENT = `#graphql + fragment Product on Product { + id + title + options { + name +- values ++ optionValues { ++ name ++ } + } +``` + +#### Step: 2. Update your `` to use the new `optionValues` field [#2585](https://github.com/Shopify/hydrogen/pull/2585) + +[#2585](https://github.com/Shopify/hydrogen/pull/2585) + +```diff + option.values.length > 1)} ++ options={product.options.filter((option) => option.optionValues.length > 1)} + variants={variants} + > +``` + +### Update all cart mutation methods from createCartHandler to return cart warnings [#2572](https://github.com/Shopify/hydrogen/pull/2572) + +#### Check warnings for stock levels + +[#2572](https://github.com/Shopify/hydrogen/pull/2572) + +### Update createWithCache to make it harder to accidentally cache undesired results [#2546](https://github.com/Shopify/hydrogen/pull/2546) + +#### Step: 1. request is now a mandatory prop when initializing createWithCache. [#2546](https://github.com/Shopify/hydrogen/pull/2546) + +[#2546](https://github.com/Shopify/hydrogen/pull/2546) + +```diff +// server.ts +export default { + async fetch( + request: Request, + env: Env, + executionContext: ExecutionContext, + ): Promise { + try { + // ... +- const withCache = createWithCache({cache, waitUntil}); ++ const withCache = createWithCache({cache, waitUntil, request}); +``` + +#### Step: 2. New `withCache.fetch` is for caching simple fetch requests. This method caches the responses if they are OK responses, and you can pass `shouldCacheResponse`, `cacheKey`, etc. to modify behavior. `data` is the consumed body of the response (we need to consume to cache it). [#2546](https://github.com/Shopify/hydrogen/pull/2546) + +[#2546](https://github.com/Shopify/hydrogen/pull/2546) + +```ts +const withCache = createWithCache({cache, waitUntil, request}); + +const {data, response} = await withCache.fetch<{data: T; error: string}>( + 'my-cms.com/api', + { + method: 'POST', + headers: {'Content-type': 'application/json'}, + body, + }, + { + cacheStrategy: CacheLong(), + // Cache if there are no data errors or a specific data that make this result not suited for caching + shouldCacheResponse: (result) => !result?.error, + cacheKey: ['my-cms', body], + displayName: 'My CMS query', + }, +); +``` + +#### Step: 3. The original `withCache` callback function is now `withCache.run`. This is useful to run _multiple_ fetch calls and merge their responses, or run any arbitrary code. It caches anything you return, but you can throw if you don't want to cache anything. [#2546](https://github.com/Shopify/hydrogen/pull/2546) + +[#2546](https://github.com/Shopify/hydrogen/pull/2546) + +```diff + const withCache = createWithCache({cache, waitUntil, request}); + + const fetchMyCMS = (query) => { +- return withCache(['my-cms', query], CacheLong(), async (params) => { ++ return withCache.run({ ++ cacheKey: ['my-cms', query], ++ cacheStrategy: CacheLong(), ++ // Cache if there are no data errors or a specific data that make this result not suited for caching ++ shouldCacheResult: (result) => !result?.errors, ++ }, async(params) => { + const response = await fetch('my-cms.com/api', { + method: 'POST', + body: query, + }); + if (!response.ok) throw new Error(response.statusText); + const {data, error} = await response.json(); + if (error || !data) throw new Error(error ?? 'Missing data'); + params.addDebugData({displayName: 'My CMS query', response}); + return data; + }); + }; +``` + +### Fix an infinite redirect when viewing the cached version of a Hydrogen site on Google Web Cache [#2334](https://github.com/Shopify/hydrogen/pull/2334) + +#### Update your entry.client.jsx file to include this check + +[#2334](https://github.com/Shopify/hydrogen/pull/2334) + +```diff ++ if (!window.location.origin.includes("webcache.googleusercontent.com")) { + startTransition(() => { + hydrateRoot( + document, + + + + ); + }); ++ } +``` diff --git a/app/root.tsx b/app/root.tsx index 904ddca..c663064 100644 --- a/app/root.tsx +++ b/app/root.tsx @@ -107,6 +107,7 @@ async function loadCriticalData({request, context}: LoaderFunctionArgs) { consent: { checkoutDomain: env.PUBLIC_CHECKOUT_DOMAIN, storefrontAccessToken: env.PUBLIC_STOREFRONT_API_TOKEN, + withPrivacyBanner: true, }, selectedLocale: storefront.i18n, }; diff --git a/app/routes/($locale).products.$productHandle.tsx b/app/routes/($locale).products.$productHandle.tsx index a7c5827..1f8a5de 100644 --- a/app/routes/($locale).products.$productHandle.tsx +++ b/app/routes/($locale).products.$productHandle.tsx @@ -275,7 +275,9 @@ export function ProductForm({
option.values.length > 1)} + options={product.options.filter( + (option) => option.optionValues.length > 1, + )} variants={variants} > {({option}) => { @@ -533,7 +535,9 @@ const PRODUCT_QUERY = `#graphql description options { name - values + optionValues { + name + } } selectedVariant: variantBySelectedOptions(selectedOptions: $selectedOptions, ignoreUnknownOptions: true, caseInsensitiveMatch: true) { ...ProductVariantFragment diff --git a/env.d.ts b/env.d.ts index e0557ff..620f8a5 100644 --- a/env.d.ts +++ b/env.d.ts @@ -28,6 +28,7 @@ declare global { PUBLIC_CUSTOMER_ACCOUNT_API_CLIENT_ID: string; PUBLIC_CUSTOMER_ACCOUNT_API_URL: string; PUBLIC_CHECKOUT_DOMAIN: string; + SHOP_ID: string; } } diff --git a/package-lock.json b/package-lock.json index 561440f..7362033 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,12 +9,12 @@ "version": "2.1.6", "dependencies": { "@headlessui/react": "^1.7.2", - "@remix-run/node": "^2.10.1", - "@remix-run/react": "^2.10.1", - "@remix-run/server-runtime": "^2.10.1", - "@shopify/cli": "^3.63.2", - "@shopify/hydrogen": "^2024.7.1", - "@shopify/remix-oxygen": "^2.0.5", + "@remix-run/node": "^2.13.1", + "@remix-run/react": "^2.13.1", + "@remix-run/server-runtime": "^2.13.1", + "@shopify/cli": "^3.69.4", + "@shopify/hydrogen": "^2024.10.0", + "@shopify/remix-oxygen": "^2.0.9", "clsx": "^1.2.1", "cross-env": "^7.0.3", "graphql": "^16.6.0", @@ -30,18 +30,19 @@ }, "devDependencies": { "@graphql-codegen/cli": "^5.0.2", - "@playwright/test": "^1.40.1", - "@remix-run/dev": "^2.10.1", - "@remix-run/eslint-config": "^2.10.1", + "@playwright/test": "^1.48.2", + "@remix-run/dev": "^2.13.1", + "@remix-run/eslint-config": "^2.13.1", "@shopify/eslint-plugin": "^42.0.1", - "@shopify/hydrogen-codegen": "^0.3.1", - "@shopify/mini-oxygen": "^3.0.3", + "@shopify/hydrogen-codegen": "^0.3.2", + "@shopify/mini-oxygen": "^3.1.0", "@shopify/oxygen-workers-types": "^4.1.2", "@shopify/prettier-config": "^1.1.2", "@tailwindcss/forms": "^0.5.3", "@tailwindcss/typography": "^0.5.9", "@total-typescript/ts-reset": "^0.4.2", "@types/eslint": "^8.4.10", + "@types/node": "^22.8.4", "@types/react": "^18.2.22", "@types/react-dom": "^18.2.7", "cross-env": "^7.0.3", @@ -1415,9 +1416,9 @@ } }, "node_modules/@cloudflare/workerd-darwin-64": { - "version": "1.20240304.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20240304.0.tgz", - "integrity": "sha512-rfHlvsWzkqEEQNvm14AOE/BYHYzB9wxQHCaZZEgwOuTl5KpDcs9La0N0LaDTR78ESumIWOcifVmko2VTrZb7TQ==", + "version": "1.20241022.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20241022.0.tgz", + "integrity": "sha512-1NNYun37myMTgCUiPQEJ0cMal4mKZVTpkD0b2tx9hV70xji+frVJcSK8YVLeUm1P+Rw1d/ct8DMgQuCpsz3Fsw==", "cpu": [ "x64" ], @@ -1431,9 +1432,9 @@ } }, "node_modules/@cloudflare/workerd-darwin-arm64": { - "version": "1.20240304.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20240304.0.tgz", - "integrity": "sha512-IXGOxHsPdRYfAzcY6IroI1PDvx3hhXf18qFCloHp8Iw5bzLgq/PTjcp10Z/2xedZ2hVlfpHy1eEptsTmi9YeNw==", + "version": "1.20241022.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20241022.0.tgz", + "integrity": "sha512-FOO/0P0U82EsTLTdweNVgw+4VOk5nghExLPLSppdOziq6IR5HVgP44Kmq5LdsUeHUhwUmfOh9hzaTpkNzUqKvw==", "cpu": [ "arm64" ], @@ -1447,9 +1448,9 @@ } }, "node_modules/@cloudflare/workerd-linux-64": { - "version": "1.20240304.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20240304.0.tgz", - "integrity": "sha512-G1BEzbw9TFIeMvc425F145IetC7fuH4KOkGhseLq9y/mt5PfDWkghwmXSK+q0BiMwm0XAobtzVlHcEr2u4WlRQ==", + "version": "1.20241022.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20241022.0.tgz", + "integrity": "sha512-RsNc19BQJG9yd+ngnjuDeG9ywZG+7t1L4JeglgceyY5ViMNMKVO7Zpbsu69kXslU9h6xyQG+lrmclg3cBpnhYA==", "cpu": [ "x64" ], @@ -1463,9 +1464,9 @@ } }, "node_modules/@cloudflare/workerd-linux-arm64": { - "version": "1.20240304.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20240304.0.tgz", - "integrity": "sha512-LLk/d/y77TRu6QOG3CJUI2cD3Ff2lSg0ts6G83bsm9ZK+WKObWFFSPBy9l81m3EnlKFh7RZCzxN4J10kuDaO8w==", + "version": "1.20241022.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20241022.0.tgz", + "integrity": "sha512-x5mUXpKxfsosxcFmcq5DaqLs37PejHYVRsNz1cWI59ma7aC4y4Qn6Tf3i0r9MwQTF/MccP4SjVslMU6m4W7IaA==", "cpu": [ "arm64" ], @@ -1479,9 +1480,9 @@ } }, "node_modules/@cloudflare/workerd-windows-64": { - "version": "1.20240304.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20240304.0.tgz", - "integrity": "sha512-I/j6nVpM+WDPg+bYUAiKLkwQsjrXFjpOGHvwYmcM44hnDjgODzk7AbVssEIXnhEO3oupBeuKvffr0lvX0Ngmpw==", + "version": "1.20241022.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20241022.0.tgz", + "integrity": "sha512-eBCClx4szCOgKqOlxxbdNszMqQf3MRG1B9BRIqEM/diDfdR9IrZ8l3FaEm+l9gXgPmS6m1NBn40aWuGBl8UTSw==", "cpu": [ "x64" ], @@ -3947,9 +3948,9 @@ "dev": true }, "node_modules/@lit-labs/ssr-dom-shim": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.2.0.tgz", - "integrity": "sha512-yWJKmpGE6lUURKAaIltoPIE/wrbY3TEkqQt+X0m+7fQNnAv0keydnYvbiJFP1PnMhizmIWRWOG5KLhYyc/xl+g==" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.2.1.tgz", + "integrity": "sha512-wx4aBmgeGvFmOKucFKY+8VFJSYZxs9poN3SDNQFF6lT6NrQUnHiPB2PWz2sc4ieEcAaYYzN+1uWahEeTq2aRIQ==" }, "node_modules/@lit/reactive-element": { "version": "1.6.3", @@ -4656,24 +4657,24 @@ } }, "node_modules/@playwright/test": { - "version": "1.44.1", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.44.1.tgz", - "integrity": "sha512-1hZ4TNvD5z9VuhNJ/walIjvMVvYkZKf71axoF/uiAqpntQJXpG64dlXhoDXE3OczPuTuvjf/M5KWFg5VAVUS3Q==", + "version": "1.48.2", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.48.2.tgz", + "integrity": "sha512-54w1xCWfXuax7dz4W2M9uw0gDyh+ti/0K/MxcCUxChFh37kkdxPdfZDw5QBbuPUJHr1CiHJ1hXgSs+GgeQc5Zw==", "dev": true, "dependencies": { - "playwright": "1.44.1" + "playwright": "1.48.2" }, "bin": { "playwright": "cli.js" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/@remix-run/dev": { - "version": "2.10.2", - "resolved": "https://registry.npmjs.org/@remix-run/dev/-/dev-2.10.2.tgz", - "integrity": "sha512-7hHC9WY65IJ5ex9Vrv9PkSg15mmYH63unxPDAR74hSfSkectMgsWtMChzdx7Kp/CzN2rttt3cxPwZnAu6PXJUw==", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/@remix-run/dev/-/dev-2.13.1.tgz", + "integrity": "sha512-7+06Dail6zMyRlRvgrZ4cmQjs2gUb+M24iP4jbmql+0B7VAAPwzCRU0x+BF5z8GSef13kDrH3iXv/BQ2O2yOgw==", "dev": true, "dependencies": { "@babel/core": "^7.21.8", @@ -4686,9 +4687,9 @@ "@babel/types": "^7.22.5", "@mdx-js/mdx": "^2.3.0", "@npmcli/package-json": "^4.0.1", - "@remix-run/node": "2.10.2", - "@remix-run/router": "1.17.1", - "@remix-run/server-runtime": "2.10.2", + "@remix-run/node": "2.13.1", + "@remix-run/router": "1.20.0", + "@remix-run/server-runtime": "2.13.1", "@types/mdx": "^2.0.5", "@vanilla-extract/integration": "^6.2.0", "arg": "^5.0.1", @@ -4702,7 +4703,7 @@ "esbuild-plugins-node-modules-polyfill": "^1.6.0", "execa": "5.1.1", "exit-hook": "2.2.1", - "express": "^4.19.2", + "express": "^4.20.0", "fs-extra": "^10.0.0", "get-port": "^5.1.1", "gunzip-maybe": "^1.4.2", @@ -4728,7 +4729,7 @@ "set-cookie-parser": "^2.6.0", "tar-fs": "^2.1.1", "tsconfig-paths": "^4.0.0", - "ws": "^7.4.5" + "ws": "^7.5.10" }, "bin": { "remix": "dist/cli.js" @@ -4737,8 +4738,8 @@ "node": ">=18.0.0" }, "peerDependencies": { - "@remix-run/react": "^2.10.2", - "@remix-run/serve": "^2.10.2", + "@remix-run/react": "^2.13.1", + "@remix-run/serve": "^2.13.1", "typescript": "^5.1.0", "vite": "^5.1.0", "wrangler": "^3.28.2" @@ -4783,9 +4784,9 @@ } }, "node_modules/@remix-run/dev/node_modules/ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", "dev": true, "engines": { "node": ">=8.3.0" @@ -4804,9 +4805,9 @@ } }, "node_modules/@remix-run/eslint-config": { - "version": "2.10.2", - "resolved": "https://registry.npmjs.org/@remix-run/eslint-config/-/eslint-config-2.10.2.tgz", - "integrity": "sha512-pg1kZXUePaZMg+2gxMpaJ+t69un5anuVmw9CcuqTpPr+8QnP72NCxt0Ic88KXupajJ7GrIK7PfwUkfqNlCN6xQ==", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/@remix-run/eslint-config/-/eslint-config-2.13.1.tgz", + "integrity": "sha512-UNWRHYa++pWrO6qxNI9z7KrmD0/wncWjS36TujoPmlnVDQ2pKIhNZwBi6otJQIuI8TdUPBZstJNgRJ0TWYok6A==", "dev": true, "dependencies": { "@babel/core": "^7.21.8", @@ -4841,11 +4842,11 @@ } }, "node_modules/@remix-run/node": { - "version": "2.10.2", - "resolved": "https://registry.npmjs.org/@remix-run/node/-/node-2.10.2.tgz", - "integrity": "sha512-Ni4yMQCf6avK2fz91/luuS3wnHzqtbxsdc19es1gAWEnUKfeCwqq5v1R0kzNwrXyh5NYCRhxaegzVH3tGsdYFg==", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/@remix-run/node/-/node-2.13.1.tgz", + "integrity": "sha512-2ly7bENj2n2FNBdEN60ZEbNCs5dAOex/QJoo6EZ8RNFfUQxVKAZkMwfQ4ETV2SLWDgkRLj3Jo5n/dx7O2ZGhGw==", "dependencies": { - "@remix-run/server-runtime": "2.10.2", + "@remix-run/server-runtime": "2.13.1", "@remix-run/web-fetch": "^4.4.2", "@web3-storage/multipart-parser": "^1.0.0", "cookie-signature": "^1.1.0", @@ -4866,15 +4867,15 @@ } }, "node_modules/@remix-run/react": { - "version": "2.10.2", - "resolved": "https://registry.npmjs.org/@remix-run/react/-/react-2.10.2.tgz", - "integrity": "sha512-0Fx3AYNjfn6Z/0xmIlVC7exmof20M429PwuApWF1H8YXwdkI+cxLfivRzTa1z7vS55tshurqQum98jQQaUDjoA==", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/@remix-run/react/-/react-2.13.1.tgz", + "integrity": "sha512-kZevCoKMz0ZDOOzTnG95yfM7M9ju38FkWNY1wtxCy+NnUJYrmTerGQtiBsJgMzYD6i29+w4EwoQsdqys7DmMSg==", "dependencies": { - "@remix-run/router": "1.17.1", - "@remix-run/server-runtime": "2.10.2", - "react-router": "6.24.1", - "react-router-dom": "6.24.1", - "turbo-stream": "2.2.0" + "@remix-run/router": "1.20.0", + "@remix-run/server-runtime": "2.13.1", + "react-router": "6.27.0", + "react-router-dom": "6.27.0", + "turbo-stream": "2.4.0" }, "engines": { "node": ">=18.0.0" @@ -4891,25 +4892,25 @@ } }, "node_modules/@remix-run/router": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.17.1.tgz", - "integrity": "sha512-mCOMec4BKd6BRGBZeSnGiIgwsbLGp3yhVqAD8H+PxiRNEHgDpZb8J1TnrSDlg97t0ySKMQJTHCWBCmBpSmkF6Q==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.20.0.tgz", + "integrity": "sha512-mUnk8rPJBI9loFDZ+YzPGdeniYK+FTmRD1TMCz7ev2SNIozyKKpnGgsxO34u6Z4z/t0ITuu7voi/AshfsGsgFg==", "engines": { "node": ">=14.0.0" } }, "node_modules/@remix-run/server-runtime": { - "version": "2.10.2", - "resolved": "https://registry.npmjs.org/@remix-run/server-runtime/-/server-runtime-2.10.2.tgz", - "integrity": "sha512-c6CzKw4WBP4FkPnz63ua7g73/P1v34Uho2C44SZZf8IOVCGzEM9liLq6slDivn0m/UbyQnXThdXmsVjFcobmZg==", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/@remix-run/server-runtime/-/server-runtime-2.13.1.tgz", + "integrity": "sha512-2DfBPRcHKVzE4bCNsNkKB50BhCCKF73x+jiS836OyxSIAL+x0tguV2AEjmGXefEXc5AGGzoxkus0AUUEYa29Vg==", "dependencies": { - "@remix-run/router": "1.17.1", + "@remix-run/router": "1.20.0", "@types/cookie": "^0.6.0", "@web3-storage/multipart-parser": "^1.0.0", "cookie": "^0.6.0", "set-cookie-parser": "^2.4.8", "source-map": "^0.7.3", - "turbo-stream": "2.2.0" + "turbo-stream": "2.4.0" }, "engines": { "node": ">=18.0.0" @@ -5195,9 +5196,9 @@ "dev": true }, "node_modules/@shopify/cli": { - "version": "3.64.0", - "resolved": "https://registry.npmjs.org/@shopify/cli/-/cli-3.64.0.tgz", - "integrity": "sha512-0bZ4mfMdvZSHJp/VIcTRZ8ZOEjkmM+AcWWp+X9eWai3UBnxodTa8ikN/uRLj6LxsgNkUOpOCljmk6f/wjowRlA==", + "version": "3.69.4", + "resolved": "https://registry.npmjs.org/@shopify/cli/-/cli-3.69.4.tgz", + "integrity": "sha512-6DDztLJ/RSwsTiyLa4wXVcsvbGB+bOCub8o5vA5ZRyN7OWUIuS2AFeqZINRX6K6WmdXsHfG6k5ohufYEC81dxw==", "os": [ "darwin", "linux", @@ -5657,14 +5658,14 @@ } }, "node_modules/@shopify/hydrogen": { - "version": "2024.7.1", - "resolved": "https://registry.npmjs.org/@shopify/hydrogen/-/hydrogen-2024.7.1.tgz", - "integrity": "sha512-Vbrx5EBbnzy+GMdDFEOnxyqXHbOWBPyS2dTrHEVfGiof7yinU1qGnFrZJR+p3KhEAF34a3dMySDFGi26k0Yeow==", + "version": "2024.10.0", + "resolved": "https://registry.npmjs.org/@shopify/hydrogen/-/hydrogen-2024.10.0.tgz", + "integrity": "sha512-VPl2l7ScBeH0jTNgboFR+997J8rf/nGs01tas/SEgpeBwtB0aJjWkugKjvB8VXx+SU7TPoRGY089pzkQDh2SbQ==", "dependencies": { - "@shopify/hydrogen-react": "2024.7.1", + "@shopify/hydrogen-react": "2024.10.0", "content-security-policy-builder": "^2.2.0", "source-map-support": "^0.5.21", - "type-fest": "^4.5.0", + "type-fest": "^4.26.1", "use-resize-observer": "^9.1.0", "worktop": "^0.7.3" }, @@ -5681,24 +5682,24 @@ } }, "node_modules/@shopify/hydrogen-codegen": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@shopify/hydrogen-codegen/-/hydrogen-codegen-0.3.1.tgz", - "integrity": "sha512-9tf6WA04Ldu/E/OZ2r7ZJuJXKxZnbOH/JJ30YabqmdCvEXbec9Do8Qb0zWVB/YR/Npy4LJYKeu2xDlUjetdrtA==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@shopify/hydrogen-codegen/-/hydrogen-codegen-0.3.2.tgz", + "integrity": "sha512-e1hWL3y4hHXNFfG7xgn5VLG5OCeaxwVygLFr7IPtRqq2fU67nPGiMBbTgN79ytCyaZJA2N/t1TGU2JO+YWjENw==", "dev": true, "dependencies": { "@shopify/graphql-codegen": "^0.0.2" } }, "node_modules/@shopify/hydrogen-react": { - "version": "2024.7.1", - "resolved": "https://registry.npmjs.org/@shopify/hydrogen-react/-/hydrogen-react-2024.7.1.tgz", - "integrity": "sha512-CE3n3pxt/RcVdbgr/mrBCoLqApNTsTjGL+yJfq4eAng9PBtWRjKKmUzH6WYgUYR9IH31FSeh2qciM05VWEOFVg==", + "version": "2024.10.0", + "resolved": "https://registry.npmjs.org/@shopify/hydrogen-react/-/hydrogen-react-2024.10.0.tgz", + "integrity": "sha512-iU1nLChpIqaIP/ldmkj5Ra1BkFoSC3wP8ARYAZekWjnPowTMKjf/YxNHMrt1i2zE+h6WxvYKMM3E/yB7/KJFrw==", "dependencies": { "@google/model-viewer": "^1.12.1", - "@xstate/fsm": "^2.0.0", - "@xstate/react": "^3.2.1", + "@xstate/fsm": "2.0.0", + "@xstate/react": "3.2.1", "graphql": "^16.6.0", - "type-fest": "^4.5.0", + "type-fest": "^4.26.1", "worktop": "^0.7.3" }, "engines": { @@ -5710,9 +5711,9 @@ } }, "node_modules/@shopify/mini-oxygen": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@shopify/mini-oxygen/-/mini-oxygen-3.0.3.tgz", - "integrity": "sha512-66HPatRPh8II3JMXEv2yk2wmIo7IWoio2McBKNb3VQjlTtuOw8TE398dX3alGcX7LI3utxqRSvuayY8RKT3ofQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@shopify/mini-oxygen/-/mini-oxygen-3.1.0.tgz", + "integrity": "sha512-MrTHsDOTYw/own8X+yYmVEchinfLWwIJnGzsIEDF+S8eeRAcuLvS+KjIWhOFQ6twQkhoyAwGs9K/TvoKfF4NTg==", "dev": true, "dependencies": { "@miniflare/cache": "^2.14.2", @@ -5725,13 +5726,13 @@ "body-parser": "1.20.2", "connect": "^3.7.0", "get-port": "^7.0.0", - "miniflare": "3.20240304.2", + "miniflare": "^3.20240925.0", "mrmime": "1.0.1", "source-map": "^0.7.4", "source-map-support": "^0.5.21", "stack-trace": "^1.0.0-pre2", - "undici": "^5.28.2", - "ws": "^8.16.0" + "undici": "^6.11.1", + "ws": "^8.17.1" }, "engines": { "node": ">=18.0.0" @@ -5757,18 +5758,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@shopify/mini-oxygen/node_modules/undici": { - "version": "5.28.4", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz", - "integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==", - "dev": true, - "dependencies": { - "@fastify/busboy": "^2.0.0" - }, - "engines": { - "node": ">=14.0" - } - }, "node_modules/@shopify/oxygen-workers-types": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/@shopify/oxygen-workers-types/-/oxygen-workers-types-4.1.4.tgz", @@ -5781,9 +5770,9 @@ "dev": true }, "node_modules/@shopify/remix-oxygen": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@shopify/remix-oxygen/-/remix-oxygen-2.0.5.tgz", - "integrity": "sha512-TBhgo5tA45KB+pA2rzMbN+LIUMljJgHoYemO82+emXp1QWz6u477aV4N76uQ9WGk8u+t0n/Gz7h6eHmz6yJ8Yg==", + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@shopify/remix-oxygen/-/remix-oxygen-2.0.9.tgz", + "integrity": "sha512-TNQbR5ZPqnlwuaSoNp2irGIoTs/bksDnL4oYyEwusEVpIJh5XX/xc1NdKQerLWLZBhWOdHOTwgKM0fSe4L78CA==", "peerDependencies": { "@remix-run/server-runtime": "^2.1.0", "@shopify/oxygen-workers-types": "^3.17.3 || ^4.1.2" @@ -5983,12 +5972,12 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.14.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz", - "integrity": "sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==", + "version": "22.8.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.8.4.tgz", + "integrity": "sha512-SpNNxkftTJOPk0oN+y2bIqurEXHTA2AOZ3EJDDKeJ5VzkvvORSvmQXGQarcOzWV1ac7DCaPBEdMDxBsM+d8jWw==", "dev": true, "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~6.19.8" } }, "node_modules/@types/prop-types": { @@ -6462,22 +6451,22 @@ "integrity": "sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==" }, "node_modules/@xstate/fsm": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@xstate/fsm/-/fsm-2.1.0.tgz", - "integrity": "sha512-oJlc0iD0qZvAM7If/KlyJyqUt7wVI8ocpsnlWzAPl97evguPbd+oJbRM9R4A1vYJffYH96+Bx44nLDE6qS8jQg==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@xstate/fsm/-/fsm-2.0.0.tgz", + "integrity": "sha512-p/zcvBMoU2ap5byMefLkR+AM+Eh99CU/SDEQeccgKlmFNOMDwphaRGqdk+emvel/SaGZ7Rf9sDvzAplLzLdEVQ==" }, "node_modules/@xstate/react": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@xstate/react/-/react-3.2.2.tgz", - "integrity": "sha512-feghXWLedyq8JeL13yda3XnHPZKwYDN5HPBLykpLeuNpr9178tQd2/3d0NrH6gSd0sG5mLuLeuD+ck830fgzLQ==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@xstate/react/-/react-3.2.1.tgz", + "integrity": "sha512-L/mqYRxyBWVdIdSaXBHacfvS8NKn3sTKbPb31aRADbE9spsJ1p+tXil0GVQHPlzrmjGeozquLrxuYGiXsFNU7g==", "dependencies": { - "use-isomorphic-layout-effect": "^1.1.2", + "use-isomorphic-layout-effect": "^1.0.0", "use-sync-external-store": "^1.0.0" }, "peerDependencies": { "@xstate/fsm": "^2.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "xstate": "^4.37.2" + "xstate": "^4.36.0" }, "peerDependenciesMeta": { "@xstate/fsm": { @@ -6540,10 +6529,13 @@ } }, "node_modules/acorn-walk": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", - "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", "dev": true, + "dependencies": { + "acorn": "^8.11.0" + }, "engines": { "node": ">=0.4.0" } @@ -7752,9 +7744,9 @@ } }, "node_modules/cookie-signature": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.1.tgz", - "integrity": "sha512-78KWk9T26NhzXtuL26cIJ8/qNHANyJ/ZYrmEXFzUmhZdjpBv+DlWlOANRTGBt48YcyslsLrj0bMLFTmXvLRCOw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", "engines": { "node": ">=6.6.0" } @@ -9832,37 +9824,37 @@ } }, "node_modules/express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", + "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", "dev": true, "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.2", + "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.6.0", + "cookie": "0.7.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "1.2.0", + "finalhandler": "1.3.1", "fresh": "0.5.2", "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", + "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", + "path-to-regexp": "0.1.10", "proxy-addr": "~2.0.7", - "qs": "6.11.0", + "qs": "6.13.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", + "send": "0.19.0", + "serve-static": "1.16.2", "setprototypeof": "1.2.0", "statuses": "2.0.1", "type-is": "~1.6.18", @@ -9873,6 +9865,39 @@ "node": ">= 0.10.0" } }, + "node_modules/express/node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/express/node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/express/node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", @@ -9888,14 +9913,23 @@ "ms": "2.0.0" } }, + "node_modules/express/node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/express/node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", "dev": true, "dependencies": { "debug": "2.6.9", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "on-finished": "2.4.1", "parseurl": "~1.3.3", @@ -9912,6 +9946,21 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, + "node_modules/express/node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -12593,10 +12642,13 @@ } }, "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", - "dev": true + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/merge-stream": { "version": "2.0.0", @@ -13319,9 +13371,9 @@ } }, "node_modules/miniflare": { - "version": "3.20240304.2", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20240304.2.tgz", - "integrity": "sha512-yQ5TBKv7TlvF8khFvvH+1WWk8cBnaLgNzcbJ5DLQOdecxdDxUCVlN38HThd6Nhcz6EY+ckDkww8FkugUbSSpIQ==", + "version": "3.20241022.0", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20241022.0.tgz", + "integrity": "sha512-x9Fbq1Hmz1f0osIT9Qmj78iX4UpCP2EqlZnA/tzj/3+I49vc3Kq0fNqSSKplcdf6HlCHdL3fOBicmreQF4BUUQ==", "dev": true, "dependencies": { "@cspotcode/source-map-support": "0.8.1", @@ -13331,11 +13383,11 @@ "exit-hook": "^2.2.1", "glob-to-regexp": "^0.4.1", "stoppable": "^1.1.0", - "undici": "^5.28.2", - "workerd": "1.20240304.0", - "ws": "^8.11.0", + "undici": "^5.28.4", + "workerd": "1.20241022.0", + "ws": "^8.17.1", "youch": "^3.2.2", - "zod": "^3.20.6" + "zod": "^3.22.3" }, "bin": { "miniflare": "bootstrap.js" @@ -14532,9 +14584,9 @@ } }, "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", + "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", "dev": true }, "node_modules/path-type": { @@ -14707,33 +14759,33 @@ "dev": true }, "node_modules/playwright": { - "version": "1.44.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.44.1.tgz", - "integrity": "sha512-qr/0UJ5CFAtloI3avF95Y0L1xQo6r3LQArLIg/z/PoGJ6xa+EwzrwO5lpNr/09STxdHuUoP2mvuELJS+hLdtgg==", + "version": "1.48.2", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.48.2.tgz", + "integrity": "sha512-NjYvYgp4BPmiwfe31j4gHLa3J7bD2WiBz8Lk2RoSsmX38SVIARZ18VYjxLjAcDsAhA+F4iSEXTSGgjua0rrlgQ==", "dev": true, "dependencies": { - "playwright-core": "1.44.1" + "playwright-core": "1.48.2" }, "bin": { "playwright": "cli.js" }, "engines": { - "node": ">=16" + "node": ">=18" }, "optionalDependencies": { "fsevents": "2.3.2" } }, "node_modules/playwright-core": { - "version": "1.44.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.44.1.tgz", - "integrity": "sha512-wh0JWtYTrhv1+OSsLPgFzGzt67Y7BE/ZS3jEqgGBlp2ppp1ZDj8c+9IARNW4dwf1poq5MgHreEM2KV/GuR4cFA==", + "version": "1.48.2", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.48.2.tgz", + "integrity": "sha512-sjjw+qrLFlriJo64du+EK0kJgZzoQPsabGF4lBvsid+3CNIZIYLgnMj9V6JY5VhM2Peh20DJWIVpVljLLnlawA==", "dev": true, "bin": { "playwright-core": "cli.js" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/playwright/node_modules/fsevents": { @@ -15992,11 +16044,11 @@ } }, "node_modules/react-router": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.24.1.tgz", - "integrity": "sha512-PTXFXGK2pyXpHzVo3rR9H7ip4lSPZZc0bHG5CARmj65fTT6qG7sTngmb6lcYu1gf3y/8KxORoy9yn59pGpCnpg==", + "version": "6.27.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.27.0.tgz", + "integrity": "sha512-YA+HGZXz4jaAkVoYBE98VQl+nVzI+cVI2Oj/06F5ZM+0u3TgedN9Y9kmMRo2mnkSK2nCpNQn0DVob4HCsY/WLw==", "dependencies": { - "@remix-run/router": "1.17.1" + "@remix-run/router": "1.20.0" }, "engines": { "node": ">=14.0.0" @@ -16006,12 +16058,12 @@ } }, "node_modules/react-router-dom": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.24.1.tgz", - "integrity": "sha512-U19KtXqooqw967Vw0Qcn5cOvrX5Ejo9ORmOtJMzYWtCT4/WOfFLIZGGsVLxcd9UkBO0mSTZtXqhZBsWlHr7+Sg==", + "version": "6.27.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.27.0.tgz", + "integrity": "sha512-+bvtFWMC0DgAFrfKXKG9Fc+BcXWRUO1aJIihbB79xaeq0v5UzfvnM5houGUm1Y461WVRcgAQ+Clh5rdb1eCx4g==", "dependencies": { - "@remix-run/router": "1.17.1", - "react-router": "6.24.1" + "@remix-run/router": "1.20.0", + "react-router": "6.27.0" }, "engines": { "node": ">=14.0.0" @@ -16595,9 +16647,9 @@ } }, "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", "dev": true, "dependencies": { "debug": "2.6.9", @@ -16651,20 +16703,29 @@ } }, "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", "dev": true, "dependencies": { - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.18.0" + "send": "0.19.0" }, "engines": { "node": ">= 0.8.0" } }, + "node_modules/serve-static/node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", @@ -17789,9 +17850,9 @@ "dev": true }, "node_modules/turbo-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/turbo-stream/-/turbo-stream-2.2.0.tgz", - "integrity": "sha512-FKFg7A0To1VU4CH9YmSMON5QphK0BXjSoiC7D9yMh+mEEbXLUP9qJ4hEt1qcjKtzncs1OpcnjZO8NgrlVbZH+g==" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/turbo-stream/-/turbo-stream-2.4.0.tgz", + "integrity": "sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==" }, "node_modules/type-check": { "version": "0.4.0", @@ -17806,9 +17867,9 @@ } }, "node_modules/type-fest": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.19.0.tgz", - "integrity": "sha512-CN2l+hWACRiejlnr68vY0/7734Kzu+9+TOslUXbSCQ1ruY9XIHDBSceVXCcHm/oXrdzhtLMMdJEKfemf1yXiZQ==", + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.1.tgz", + "integrity": "sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==", "engines": { "node": ">=16" }, @@ -18070,17 +18131,17 @@ } }, "node_modules/undici": { - "version": "6.19.2", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.19.2.tgz", - "integrity": "sha512-JfjKqIauur3Q6biAtHJ564e3bWa8VvT+7cSiOJHFbX4Erv6CLGDpg8z+Fmg/1OI/47RA+GI2QZaF48SSaLvyBA==", + "version": "6.20.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.20.1.tgz", + "integrity": "sha512-AjQF1QsmqfJys+LXfGTNum+qw4S88CojRInG/6t31W/1fk6G59s92bnAvGz5Cmur+kQv2SURXEvvudLmbrE8QA==", "engines": { "node": ">=18.17" } }, "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", "dev": true }, "node_modules/unified": { @@ -19154,9 +19215,9 @@ } }, "node_modules/workerd": { - "version": "1.20240304.0", - "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20240304.0.tgz", - "integrity": "sha512-/tYxdypPh9NKQje9r7bgBB73vAQfCQZbEPjNlxE/ml7jNKMHnRZv/D+By4xO0IPAifa37D0sJFokvYOahz1Lqw==", + "version": "1.20241022.0", + "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20241022.0.tgz", + "integrity": "sha512-jyGXsgO9DRcJyx6Ovv7gUyDPc3UYC2i/E0p9GFUg6GUzpldw4Y93y9kOmdfsOnKZ3+lY53veSiUniiBPE6Q2NQ==", "dev": true, "hasInstallScript": true, "bin": { @@ -19166,11 +19227,11 @@ "node": ">=16" }, "optionalDependencies": { - "@cloudflare/workerd-darwin-64": "1.20240304.0", - "@cloudflare/workerd-darwin-arm64": "1.20240304.0", - "@cloudflare/workerd-linux-64": "1.20240304.0", - "@cloudflare/workerd-linux-arm64": "1.20240304.0", - "@cloudflare/workerd-windows-64": "1.20240304.0" + "@cloudflare/workerd-darwin-64": "1.20241022.0", + "@cloudflare/workerd-darwin-arm64": "1.20241022.0", + "@cloudflare/workerd-linux-64": "1.20241022.0", + "@cloudflare/workerd-linux-arm64": "1.20241022.0", + "@cloudflare/workerd-windows-64": "1.20241022.0" } }, "node_modules/worktop": { @@ -19226,9 +19287,9 @@ "dev": true }, "node_modules/ws": { - "version": "8.17.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.0.tgz", - "integrity": "sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "dev": true, "engines": { "node": ">=10.0.0" @@ -19328,29 +19389,29 @@ } }, "node_modules/youch": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/youch/-/youch-3.3.3.tgz", - "integrity": "sha512-qSFXUk3UZBLfggAW3dJKg0BMblG5biqSF8M34E06o5CSsZtH92u9Hqmj2RzGiHDi64fhe83+4tENFP2DB6t6ZA==", + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/youch/-/youch-3.3.4.tgz", + "integrity": "sha512-UeVBXie8cA35DS6+nBkls68xaBBXCye0CNznrhszZjTbRVnJKQuNsyLKBTTL4ln1o1rh2PKtv35twV7irj5SEg==", "dev": true, "dependencies": { - "cookie": "^0.5.0", + "cookie": "^0.7.1", "mustache": "^4.2.0", "stacktracey": "^2.1.8" } }, "node_modules/youch/node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/zod": { - "version": "3.22.3", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.3.tgz", - "integrity": "sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==", + "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", "dev": true, "funding": { "url": "https://github.com/sponsors/colinhacks" diff --git a/package.json b/package.json index e43c23c..1e0e538 100644 --- a/package.json +++ b/package.json @@ -21,12 +21,12 @@ "prettier": "@shopify/prettier-config", "dependencies": { "@headlessui/react": "^1.7.2", - "@remix-run/node": "^2.10.1", - "@remix-run/react": "^2.10.1", - "@remix-run/server-runtime": "^2.10.1", - "@shopify/cli": "^3.63.2", - "@shopify/hydrogen": "^2024.7.1", - "@shopify/remix-oxygen": "^2.0.5", + "@remix-run/node": "^2.13.1", + "@remix-run/react": "^2.13.1", + "@remix-run/server-runtime": "^2.13.1", + "@shopify/cli": "^3.69.4", + "@shopify/hydrogen": "^2024.10.0", + "@shopify/remix-oxygen": "^2.0.9", "clsx": "^1.2.1", "cross-env": "^7.0.3", "graphql": "^16.6.0", @@ -42,18 +42,19 @@ }, "devDependencies": { "@graphql-codegen/cli": "^5.0.2", - "@playwright/test": "^1.40.1", - "@remix-run/dev": "^2.10.1", - "@remix-run/eslint-config": "^2.10.1", + "@playwright/test": "^1.48.2", + "@remix-run/dev": "^2.13.1", + "@remix-run/eslint-config": "^2.13.1", "@shopify/eslint-plugin": "^42.0.1", - "@shopify/hydrogen-codegen": "^0.3.1", - "@shopify/mini-oxygen": "^3.0.3", + "@shopify/hydrogen-codegen": "^0.3.2", + "@shopify/mini-oxygen": "^3.1.0", "@shopify/oxygen-workers-types": "^4.1.2", "@shopify/prettier-config": "^1.1.2", "@tailwindcss/forms": "^0.5.3", "@tailwindcss/typography": "^0.5.9", "@total-typescript/ts-reset": "^0.4.2", "@types/eslint": "^8.4.10", + "@types/node": "^22.8.4", "@types/react": "^18.2.22", "@types/react-dom": "^18.2.7", "cross-env": "^7.0.3", diff --git a/playwright.config.ts b/playwright.config.ts index 61eb55e..5527549 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -41,6 +41,8 @@ let config: PlaywrightTestConfig = defineConfig({ /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ trace: 'on-first-retry', + + bypassCSP: true, }, /* Configure projects for major browsers */ diff --git a/server.ts b/server.ts index d645dbe..f557b6e 100644 --- a/server.ts +++ b/server.ts @@ -62,7 +62,7 @@ export default { request, session, customerAccountId: env.PUBLIC_CUSTOMER_ACCOUNT_API_CLIENT_ID, - customerAccountUrl: env.PUBLIC_CUSTOMER_ACCOUNT_API_URL, + shopId: env.SHOP_ID, }); const cart = createCartHandler({ diff --git a/storefrontapi.generated.d.ts b/storefrontapi.generated.d.ts index c752b78..2699089 100644 --- a/storefrontapi.generated.d.ts +++ b/storefrontapi.generated.d.ts @@ -902,7 +902,11 @@ export type ProductQuery = { StorefrontAPI.Product, 'id' | 'title' | 'vendor' | 'handle' | 'descriptionHtml' | 'description' > & { - options: Array>; + options: Array< + Pick & { + optionValues: Array>; + } + >; selectedVariant?: StorefrontAPI.Maybe< Pick< StorefrontAPI.ProductVariant, @@ -1279,7 +1283,7 @@ interface GeneratedQueryTypes { return: PoliciesIndexQuery; variables: PoliciesIndexQueryVariables; }; - '#graphql\n query Product(\n $country: CountryCode\n $language: LanguageCode\n $handle: String!\n $selectedOptions: [SelectedOptionInput!]!\n ) @inContext(country: $country, language: $language) {\n product(handle: $handle) {\n id\n title\n vendor\n handle\n descriptionHtml\n description\n options {\n name\n values\n }\n selectedVariant: variantBySelectedOptions(selectedOptions: $selectedOptions, ignoreUnknownOptions: true, caseInsensitiveMatch: true) {\n ...ProductVariantFragment\n }\n media(first: 7) {\n nodes {\n ...Media\n }\n }\n variants(first: 1) {\n nodes {\n ...ProductVariantFragment\n }\n }\n seo {\n description\n title\n }\n }\n shop {\n name\n primaryDomain {\n url\n }\n shippingPolicy {\n body\n handle\n }\n refundPolicy {\n body\n handle\n }\n }\n }\n #graphql\n fragment Media on Media {\n __typename\n mediaContentType\n alt\n previewImage {\n url\n }\n ... on MediaImage {\n id\n image {\n id\n url\n width\n height\n }\n }\n ... on Video {\n id\n sources {\n mimeType\n url\n }\n }\n ... on Model3d {\n id\n sources {\n mimeType\n url\n }\n }\n ... on ExternalVideo {\n id\n embedUrl\n host\n }\n }\n\n #graphql\n fragment ProductVariantFragment on ProductVariant {\n id\n availableForSale\n selectedOptions {\n name\n value\n }\n image {\n id\n url\n altText\n width\n height\n }\n price {\n amount\n currencyCode\n }\n compareAtPrice {\n amount\n currencyCode\n }\n sku\n title\n unitPrice {\n amount\n currencyCode\n }\n product {\n title\n handle\n }\n }\n\n': { + '#graphql\n query Product(\n $country: CountryCode\n $language: LanguageCode\n $handle: String!\n $selectedOptions: [SelectedOptionInput!]!\n ) @inContext(country: $country, language: $language) {\n product(handle: $handle) {\n id\n title\n vendor\n handle\n descriptionHtml\n description\n options {\n name\n optionValues {\n name\n }\n }\n selectedVariant: variantBySelectedOptions(selectedOptions: $selectedOptions, ignoreUnknownOptions: true, caseInsensitiveMatch: true) {\n ...ProductVariantFragment\n }\n media(first: 7) {\n nodes {\n ...Media\n }\n }\n variants(first: 1) {\n nodes {\n ...ProductVariantFragment\n }\n }\n seo {\n description\n title\n }\n }\n shop {\n name\n primaryDomain {\n url\n }\n shippingPolicy {\n body\n handle\n }\n refundPolicy {\n body\n handle\n }\n }\n }\n #graphql\n fragment Media on Media {\n __typename\n mediaContentType\n alt\n previewImage {\n url\n }\n ... on MediaImage {\n id\n image {\n id\n url\n width\n height\n }\n }\n ... on Video {\n id\n sources {\n mimeType\n url\n }\n }\n ... on Model3d {\n id\n sources {\n mimeType\n url\n }\n }\n ... on ExternalVideo {\n id\n embedUrl\n host\n }\n }\n\n #graphql\n fragment ProductVariantFragment on ProductVariant {\n id\n availableForSale\n selectedOptions {\n name\n value\n }\n image {\n id\n url\n altText\n width\n height\n }\n price {\n amount\n currencyCode\n }\n compareAtPrice {\n amount\n currencyCode\n }\n sku\n title\n unitPrice {\n amount\n currencyCode\n }\n product {\n title\n handle\n }\n }\n\n': { return: ProductQuery; variables: ProductQueryVariables; };