diff --git a/.github/workflows/deploy-template.yml b/.github/workflows/deploy-template.yml index 04926a2b..6794e367 100644 --- a/.github/workflows/deploy-template.yml +++ b/.github/workflows/deploy-template.yml @@ -6,6 +6,10 @@ env: NUXT_SHOPIFY_CLIENTS_STOREFRONT_API_VERSION: ${{ secrets.NUXT_SHOPIFY_CLIENTS_STOREFRONT_API_VERSION }} NUXT_SHOPIFY_CLIENTS_STOREFRONT_PUBLIC_ACCESS_TOKEN: ${{ secrets.NUXT_SHOPIFY_CLIENTS_STOREFRONT_PUBLIC_ACCESS_TOKEN }} + NUXT_SHOPIFY_CLIENTS_CUSTOMER_ACCOUNT_API_VERSION: ${{ secrets.NUXT_SHOPIFY_CLIENTS_CUSTOMER_ACCOUNT_API_VERSION }} + NUXT_SHOPIFY_CLIENTS_CUSTOMER_ACCOUNT_CLIENT_ID: ${{ secrets.NUXT_SHOPIFY_CLIENTS_CUSTOMER_ACCOUNT_CLIENT_ID }} + NUXT_SHOPIFY_CLIENTS_CUSTOMER_ACCOUNT_CLIENT_SECRET: ${{ secrets.NUXT_SHOPIFY_CLIENTS_CUSTOMER_ACCOUNT_CLIENT_SECRET }} + VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }} VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 25d4a87d..6965acc5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,6 +9,10 @@ env: NUXT_SHOPIFY_CLIENTS_ADMIN_API_VERSION: ${{ secrets.NUXT_SHOPIFY_CLIENTS_ADMIN_API_VERSION }} NUXT_SHOPIFY_CLIENTS_ADMIN_ACCESS_TOKEN: ${{ secrets.NUXT_SHOPIFY_CLIENTS_ADMIN_ACCESS_TOKEN }} + NUXT_SHOPIFY_CLIENTS_CUSTOMER_ACCOUNT_API_VERSION: ${{ secrets.NUXT_SHOPIFY_CLIENTS_CUSTOMER_ACCOUNT_API_VERSION }} + NUXT_SHOPIFY_CLIENTS_CUSTOMER_ACCOUNT_CLIENT_ID: ${{ secrets.NUXT_SHOPIFY_CLIENTS_CUSTOMER_ACCOUNT_CLIENT_ID }} + NUXT_SHOPIFY_CLIENTS_CUSTOMER_ACCOUNT_CLIENT_SECRET: ${{ secrets.NUXT_SHOPIFY_CLIENTS_CUSTOMER_ACCOUNT_CLIENT_SECRET }} + on: release: types: [published] diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5735e3bf..38d9b10e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -9,6 +9,10 @@ env: NUXT_SHOPIFY_CLIENTS_ADMIN_API_VERSION: ${{ secrets.NUXT_SHOPIFY_CLIENTS_ADMIN_API_VERSION }} NUXT_SHOPIFY_CLIENTS_ADMIN_ACCESS_TOKEN: ${{ secrets.NUXT_SHOPIFY_CLIENTS_ADMIN_ACCESS_TOKEN }} + NUXT_SHOPIFY_CLIENTS_CUSTOMER_ACCOUNT_API_VERSION: ${{ secrets.NUXT_SHOPIFY_CLIENTS_CUSTOMER_ACCOUNT_API_VERSION }} + NUXT_SHOPIFY_CLIENTS_CUSTOMER_ACCOUNT_CLIENT_ID: ${{ secrets.NUXT_SHOPIFY_CLIENTS_CUSTOMER_ACCOUNT_CLIENT_ID }} + NUXT_SHOPIFY_CLIENTS_CUSTOMER_ACCOUNT_CLIENT_SECRET: ${{ secrets.NUXT_SHOPIFY_CLIENTS_CUSTOMER_ACCOUNT_CLIENT_SECRET }} + on: pull_request: push: diff --git a/bun.lock b/bun.lock index 73a51001..33834d8a 100644 --- a/bun.lock +++ b/bun.lock @@ -76,6 +76,9 @@ "dependencies": { "nuxt": "^4.4.2", }, + "devDependencies": { + "@shopify/hydrogen": "^2026.1.2", + }, }, "playgrounds/playground-v4-mock": { "name": "playground-v4-mock", @@ -182,8 +185,12 @@ "@babel/plugin-syntax-typescript": ["@babel/plugin-syntax-typescript@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A=="], + "@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.28.6", "", { "dependencies": { "@babel/helper-module-transforms": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA=="], + "@babel/plugin-transform-typescript": ["@babel/plugin-transform-typescript@7.28.6", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-create-class-features-plugin": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw=="], + "@babel/preset-typescript": ["@babel/preset-typescript@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.27.1", "@babel/plugin-transform-typescript": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g=="], + "@babel/runtime": ["@babel/runtime@7.28.6", "", {}, "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA=="], "@babel/template": ["@babel/template@7.28.6", "", { "dependencies": { "@babel/code-frame": "^7.28.6", "@babel/parser": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ=="], @@ -308,6 +315,8 @@ "@floating-ui/vue": ["@floating-ui/vue@1.1.10", "", { "dependencies": { "@floating-ui/dom": "^1.7.5", "@floating-ui/utils": "^0.2.10", "vue-demi": ">=0.13.0" } }, "sha512-vdf8f6rHnFPPLRsmL4p12wYl+Ux4mOJOkjzKEMYVnwdf7UFdvBtHlLvQyx8iKG5vhPRbDRgZxdtpmyigDPjzYg=="], + "@google/model-viewer": ["@google/model-viewer@4.2.0", "", { "dependencies": { "@monogrid/gainmap-js": "^3.1.0", "lit": "^3.2.1" }, "peerDependencies": { "three": "^0.182.0" } }, "sha512-RjpAI5cLs9CdvPcMRsOs8Bea/lNmGTTyaPyl16o9Fv6Qn8VSpgBMmXFr/11yb0hTrsojp2dOACEcY77R8hVUVA=="], + "@graphql-codegen/add": ["@graphql-codegen/add@6.0.0", "", { "dependencies": { "@graphql-codegen/plugin-helpers": "^6.0.0", "tslib": "~2.6.0" }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, "sha512-biFdaURX0KTwEJPQ1wkT6BRgNasqgQ5KbCI1a3zwtLtO7XTo7/vKITPylmiU27K5DSOWYnY/1jfSqUAEBuhZrQ=="], "@graphql-codegen/cli": ["@graphql-codegen/cli@6.2.1", "", { "dependencies": { "@babel/generator": "^7.18.13", "@babel/template": "^7.18.10", "@babel/types": "^7.18.13", "@graphql-codegen/client-preset": "^5.2.4", "@graphql-codegen/core": "^5.0.1", "@graphql-codegen/plugin-helpers": "^6.2.0", "@graphql-tools/apollo-engine-loader": "^8.0.28", "@graphql-tools/code-file-loader": "^8.1.28", "@graphql-tools/git-loader": "^8.0.32", "@graphql-tools/github-loader": "^9.0.6", "@graphql-tools/graphql-file-loader": "^8.1.11", "@graphql-tools/json-file-loader": "^8.0.26", "@graphql-tools/load": "^8.1.8", "@graphql-tools/merge": "^9.0.6", "@graphql-tools/url-loader": "^9.0.6", "@graphql-tools/utils": "^11.0.0", "@inquirer/prompts": "^7.8.2", "@whatwg-node/fetch": "^0.10.0", "chalk": "^4.1.0", "cosmiconfig": "^9.0.0", "debounce": "^2.0.0", "detect-indent": "^6.0.0", "graphql-config": "^5.1.6", "is-glob": "^4.0.1", "jiti": "^2.3.0", "json-to-pretty-yaml": "^1.2.2", "listr2": "^9.0.0", "log-symbols": "^4.0.0", "micromatch": "^4.0.5", "shell-quote": "^1.7.3", "string-env-interpolation": "^1.0.1", "ts-log": "^2.2.3", "tslib": "^2.4.0", "yaml": "^2.3.1", "yargs": "^17.0.0" }, "peerDependencies": { "@parcel/watcher": "^2.1.0", "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" }, "optionalPeers": ["@parcel/watcher"], "bin": { "gql-gen": "cjs/bin.js", "graphql-codegen": "cjs/bin.js", "graphql-codegen-esm": "esm/bin.js", "graphql-code-generator": "cjs/bin.js" } }, "sha512-E1B+5nBda2l89Pci5M0HcEj2Hmx2yhORFX+1T3rmwpQjdOiulo+h9JifWxKomUpjfbmU1YkBSd47CCGLFPU10A=="], @@ -534,16 +543,26 @@ "@jsdevtools/ono": ["@jsdevtools/ono@7.1.3", "", {}, "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg=="], + "@juggle/resize-observer": ["@juggle/resize-observer@3.4.0", "", {}, "sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA=="], + "@kwsites/file-exists": ["@kwsites/file-exists@1.1.1", "", { "dependencies": { "debug": "^4.1.1" } }, "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw=="], "@kwsites/promise-deferred": ["@kwsites/promise-deferred@1.1.1", "", {}, "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw=="], + "@lit-labs/ssr-dom-shim": ["@lit-labs/ssr-dom-shim@1.5.1", "", {}, "sha512-Aou5UdlSpr5whQe8AA/bZG0jMj96CoJIWbGfZ91qieWu5AWUMKw8VR/pAkQkJYvBNhmCcWnZlyyk5oze8JIqYA=="], + + "@lit/reactive-element": ["@lit/reactive-element@2.1.2", "", { "dependencies": { "@lit-labs/ssr-dom-shim": "^1.5.0" } }, "sha512-pbCDiVMnne1lYUIaYNN5wrwQXDtHaYtg7YEFPeW+hws6U47WeFvISGUWekPGKWOP1ygrs0ef0o1VJMk1exos5A=="], + "@mapbox/node-pre-gyp": ["@mapbox/node-pre-gyp@2.0.3", "", { "dependencies": { "consola": "^3.2.3", "detect-libc": "^2.0.0", "https-proxy-agent": "^7.0.5", "node-fetch": "^2.6.7", "nopt": "^8.0.0", "semver": "^7.5.3", "tar": "^7.4.0" }, "bin": { "node-pre-gyp": "bin/node-pre-gyp" } }, "sha512-uwPAhccfFJlsfCxMYTwOdVfOz3xqyj8xYL3zJj8f0pb30tLohnnFPhLuqp4/qoEz8sNxe4SESZedcBojRefIzg=="], "@miyaneee/rollup-plugin-json5": ["@miyaneee/rollup-plugin-json5@1.2.0", "", { "dependencies": { "@rollup/pluginutils": "^5.1.0", "json5": "^2.2.3" }, "peerDependencies": { "rollup": "^1.20.0 || ^2.0.0 || ^3.0.0 || ^4.0.0" } }, "sha512-JjTIaXZp9WzhUHpElrqPnl1AzBi/rvRs065F71+aTmlqvTMVkdbjZ8vfFl4nRlgJy+TPBw69ZK4pwFdmOAt4aA=="], + "@mjackson/node-fetch-server": ["@mjackson/node-fetch-server@0.2.0", "", {}, "sha512-EMlH1e30yzmTpGLQjlFmaDAjyOeZhng1/XCd7DExR8PNAnG/G1tyruZxEoUe11ClnwGhGrtsdnyyUx1frSzjng=="], + "@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.27.1", "", { "dependencies": { "@hono/node-server": "^1.19.9", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", "express": "^5.2.1", "express-rate-limit": "^8.2.1", "hono": "^4.11.4", "jose": "^6.1.3", "json-schema-typed": "^8.0.2", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.25 || ^4.0", "zod-to-json-schema": "^3.25.1" }, "peerDependencies": { "@cfworker/json-schema": "^4.1.1" }, "optionalPeers": ["@cfworker/json-schema"] }, "sha512-sr6GbP+4edBwFndLbM60gf07z0FQ79gaExpnsjMGePXqFcSSb7t6iscpjk9DhFhwd+mTEQrzNafGP8/iGGFYaA=="], + "@monogrid/gainmap-js": ["@monogrid/gainmap-js@3.4.0", "", { "dependencies": { "promise-worker-transferable": "^1.0.4" }, "peerDependencies": { "three": ">= 0.159.0" } }, "sha512-2Z0FATFHaoYJ8b+Y4y4Hgfn3FRFwuU5zRrk+9dFWp4uGAdHGqVEdP7HP+gLA3X469KXHmfupJaUbKo1b/aDKIg=="], + "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.1", "", { "dependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" } }, "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A=="], "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="], @@ -808,8 +827,14 @@ "@poppinss/exception": ["@poppinss/exception@1.2.3", "", {}, "sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw=="], + "@react-router/dev": ["@react-router/dev@7.12.0", "", { "dependencies": { "@babel/core": "^7.27.7", "@babel/generator": "^7.27.5", "@babel/parser": "^7.27.7", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/preset-typescript": "^7.27.1", "@babel/traverse": "^7.27.7", "@babel/types": "^7.27.7", "@react-router/node": "7.12.0", "@remix-run/node-fetch-server": "^0.9.0", "arg": "^5.0.1", "babel-dead-code-elimination": "^1.0.6", "chokidar": "^4.0.0", "dedent": "^1.5.3", "es-module-lexer": "^1.3.1", "exit-hook": "2.2.1", "isbot": "^5.1.11", "jsesc": "3.0.2", "lodash": "^4.17.21", "p-map": "^7.0.3", "pathe": "^1.1.2", "picocolors": "^1.1.1", "pkg-types": "^2.3.0", "prettier": "^3.6.2", "react-refresh": "^0.14.0", "semver": "^7.3.7", "tinyglobby": "^0.2.14", "valibot": "^1.2.0", "vite-node": "^3.2.2" }, "peerDependencies": { "@react-router/serve": "^7.12.0", "@vitejs/plugin-rsc": "~0.5.7", "react-router": "^7.12.0", "react-server-dom-webpack": "^19.2.3", "typescript": "^5.1.0", "vite": "^5.1.0 || ^6.0.0 || ^7.0.0", "wrangler": "^3.28.2 || ^4.0.0" }, "optionalPeers": ["@react-router/serve", "@vitejs/plugin-rsc", "react-server-dom-webpack", "typescript", "wrangler"], "bin": { "react-router": "bin.js" } }, "sha512-5GpwXgq4pnOVeG7l6ADkCHA1rthJus1q/A3NRYJAIypclUQDYAzg1/fDNjvaKuTSrq+Nr3u6aj2v+oC+47MX6g=="], + + "@react-router/node": ["@react-router/node@7.12.0", "", { "dependencies": { "@mjackson/node-fetch-server": "^0.2.0" }, "peerDependencies": { "react-router": "7.12.0", "typescript": "^5.1.0" }, "optionalPeers": ["typescript"] }, "sha512-o/t10Cse4LK8kFefqJ8JjC6Ng6YuKD2I87S2AiJs17YAYtXU5W731ZqB73AWyCDd2G14R0dSuqXiASRNK/xLjg=="], + "@remirror/core-constants": ["@remirror/core-constants@3.0.0", "", {}, "sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg=="], + "@remix-run/node-fetch-server": ["@remix-run/node-fetch-server@0.9.0", "", {}, "sha512-SoLMv7dbH+njWzXnOY6fI08dFMI5+/dQ+vY3n8RnnbdG7MdJEgiP28Xj/xWlnRnED/aB6SFw56Zop+LbmaaKqA=="], + "@repeaterjs/repeater": ["@repeaterjs/repeater@3.0.6", "", {}, "sha512-Javneu5lsuhwNCryN+pXH93VPQ8g0dBX7wItHFgYiwQmzE1sVdg5tWHiOgHywzL2W21XQopa7IwIEnNbmeUJYA=="], "@resvg/resvg-js": ["@resvg/resvg-js@2.6.2", "", { "optionalDependencies": { "@resvg/resvg-js-android-arm-eabi": "2.6.2", "@resvg/resvg-js-android-arm64": "2.6.2", "@resvg/resvg-js-darwin-arm64": "2.6.2", "@resvg/resvg-js-darwin-x64": "2.6.2", "@resvg/resvg-js-linux-arm-gnueabihf": "2.6.2", "@resvg/resvg-js-linux-arm64-gnu": "2.6.2", "@resvg/resvg-js-linux-arm64-musl": "2.6.2", "@resvg/resvg-js-linux-x64-gnu": "2.6.2", "@resvg/resvg-js-linux-x64-musl": "2.6.2", "@resvg/resvg-js-win32-arm64-msvc": "2.6.2", "@resvg/resvg-js-win32-ia32-msvc": "2.6.2", "@resvg/resvg-js-win32-x64-msvc": "2.6.2" } }, "sha512-xBaJish5OeGmniDj9cW5PRa/PtmuVU3ziqrbr5xJj901ZDN4TosrVaNZpEiLZAxdfnhAe7uQ7QFWfjPe9d9K2Q=="], @@ -936,6 +961,10 @@ "@shopify/graphql-codegen": ["@shopify/graphql-codegen@0.1.0", "", { "dependencies": { "@graphql-codegen/add": "^5.0.1", "@graphql-codegen/typescript": "^4.0.2", "@graphql-codegen/typescript-operations": "^4.1.0", "type-fest": "^4.5.0" }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, "sha512-G3sSesLj7Czt/J2Bj+XlQ8u4pkfQEt32hsjoS3UGZlf1eAiVw0aBBddp+NI5HqBAi0gM/f7GLRAhG3kktPhZmA=="], + "@shopify/hydrogen": ["@shopify/hydrogen@2026.1.2", "", { "dependencies": { "@shopify/graphql-client": "1.4.1", "@shopify/hydrogen-react": "2026.1.1", "content-security-policy-builder": "^2.2.0", "flame-chart-js": "2.3.1", "isbot": "^5.1.21", "source-map-support": "^0.5.21", "type-fest": "^4.33.0", "use-resize-observer": "^9.1.0", "worktop": "^0.7.3" }, "peerDependencies": { "@react-router/dev": "7.12.0", "react": "^18.3.1 || ~19.0.3 || ~19.1.4 || ^19.2.3", "react-router": "7.12.0", "vite": "^5.1.0 || ^6.2.1" }, "optionalPeers": ["vite"] }, "sha512-ElwTqOYntfqeUSSJtcRBT4McujQr2TU4qB6Of/qtTWZhj7c88JCN32o5dRKt51SmR6IFgOTHx8qLOkF4XczQTQ=="], + + "@shopify/hydrogen-react": ["@shopify/hydrogen-react@2026.1.1", "", { "dependencies": { "@google/model-viewer": "^4.0.0", "@xstate/fsm": "2.0.0", "@xstate/react": "3.2.1", "ast-v8-to-istanbul": "^0.3.11", "graphql": "^16.10.0", "type-fest": "^4.33.0", "use-isomorphic-layout-effect": "1.2.1", "use-sync-external-store": "1.6.0", "worktop": "^0.7.3" }, "peerDependencies": { "react": "^18.3.1 || ~19.0.3 || ~19.1.4 || ^19.2.3", "react-dom": "^18.3.1 || ~19.0.3 || ~19.1.4 || ^19.2.3", "vite": "^5.1.0 || ^6.2.1" } }, "sha512-9Ef0Jy10I+COEDMV7073aCYfIiIRKoRf889WGZQZx2AQb5ZGwEab16VkZObK0BQ0oXW08j3k3XybFsYhOeG6hg=="], + "@shuding/opentype.js": ["@shuding/opentype.js@1.4.0-beta.0", "", { "dependencies": { "fflate": "^0.7.3", "string.prototype.codepointat": "^0.2.1" }, "bin": { "ot": "bin/ot" } }, "sha512-3NgmNyH3l/Hv6EvsWJbsvpcpUba6R8IREQ83nH83cyakCw7uM1arZKNfHwv1Wz6jgqrF/j4x5ELvR6PnK9nTcA=="], "@sindresorhus/base62": ["@sindresorhus/base62@1.0.0", "", {}, "sha512-TeheYy0ILzBEI/CO55CP6zJCSdSWeRtGnHy8U8dWSUH4I68iqTsy7HkMktR4xakThc9jotkPQUXT4ITdbV7cHA=="], @@ -1110,6 +1139,8 @@ "@types/resolve": ["@types/resolve@1.20.2", "", {}, "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q=="], + "@types/trusted-types": ["@types/trusted-types@2.0.7", "", {}, "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="], + "@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], "@types/web-bluetooth": ["@types/web-bluetooth@0.0.21", "", {}, "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA=="], @@ -1274,6 +1305,10 @@ "@whatwg-node/promise-helpers": ["@whatwg-node/promise-helpers@1.3.2", "", { "dependencies": { "tslib": "^2.6.3" } }, "sha512-Nst5JdK47VIl9UcGwtv2Rcgyn5lWtZ0/mhRQ4G8NN2isxpq2TO30iqHzmwoJycjWuyUfg3GFXqP/gFHXeV57IA=="], + "@xstate/fsm": ["@xstate/fsm@2.0.0", "", {}, "sha512-p/zcvBMoU2ap5byMefLkR+AM+Eh99CU/SDEQeccgKlmFNOMDwphaRGqdk+emvel/SaGZ7Rf9sDvzAplLzLdEVQ=="], + + "@xstate/react": ["@xstate/react@3.2.1", "", { "dependencies": { "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.36.0" }, "optionalPeers": ["@xstate/fsm", "xstate"] }, "sha512-L/mqYRxyBWVdIdSaXBHacfvS8NKn3sTKbPb31aRADbE9spsJ1p+tXil0GVQHPlzrmjGeozquLrxuYGiXsFNU7g=="], + "abbrev": ["abbrev@3.0.1", "", {}, "sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg=="], "abort-controller": ["abort-controller@3.0.0", "", { "dependencies": { "event-target-shim": "^5.0.0" } }, "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg=="], @@ -1312,6 +1347,8 @@ "are-docs-informative": ["are-docs-informative@0.0.2", "", {}, "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig=="], + "arg": ["arg@5.0.2", "", {}, "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="], + "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], "aria-hidden": ["aria-hidden@1.2.6", "", { "dependencies": { "tslib": "^2.0.0" } }, "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA=="], @@ -1342,6 +1379,8 @@ "b4a": ["b4a@1.8.0", "", { "peerDependencies": { "react-native-b4a": "*" }, "optionalPeers": ["react-native-b4a"] }, "sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg=="], + "babel-dead-code-elimination": ["babel-dead-code-elimination@1.0.12", "", { "dependencies": { "@babel/core": "^7.23.7", "@babel/parser": "^7.23.6", "@babel/traverse": "^7.23.7", "@babel/types": "^7.23.6" } }, "sha512-GERT7L2TiYcYDtYk1IpD+ASAYXjKbLTDPhBtYj7X1NuRMDTMtAx9kyBenub1Ev41lo91OHCKdmP+egTDmfQ7Ig=="], + "bail": ["bail@2.0.2", "", {}, "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw=="], "balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], @@ -1468,10 +1507,14 @@ "cluster-key-slot": ["cluster-key-slot@1.1.2", "", {}, "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA=="], + "color": ["color@3.2.1", "", { "dependencies": { "color-convert": "^1.9.3", "color-string": "^1.6.0" } }, "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA=="], + "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], + "color-string": ["color-string@1.9.1", "", { "dependencies": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" } }, "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg=="], + "colord": ["colord@2.9.3", "", {}, "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw=="], "colorette": ["colorette@2.0.20", "", {}, "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w=="], @@ -1500,11 +1543,13 @@ "content-disposition": ["content-disposition@1.0.1", "", {}, "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q=="], + "content-security-policy-builder": ["content-security-policy-builder@2.3.0", "", {}, "sha512-qmdEmn1M+WpadIeBLKr9Em8VJSCjtRINCSbYsyJHQ4liTwCmrLzIRpJdJpoVDnsvWUrR5iblYhQJqA4b4Hs/iw=="], + "content-type": ["content-type@1.0.5", "", {}, "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="], "convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="], - "cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="], + "cookie": ["cookie@1.1.1", "", {}, "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ=="], "cookie-es": ["cookie-es@2.0.0", "", {}, "sha512-RAj4E421UYRgqokKUmotqAwuplYw15qtdXfY+hGzgCJ/MBjCVZcSoHK/kH9kocfjRjcDME7IiDWR/1WX1TM2Pg=="], @@ -1582,6 +1627,8 @@ "decompress-response": ["decompress-response@6.0.0", "", { "dependencies": { "mimic-response": "^3.1.0" } }, "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ=="], + "dedent": ["dedent@1.7.2", "", { "peerDependencies": { "babel-plugin-macros": "^3.1.0" }, "optionalPeers": ["babel-plugin-macros"] }, "sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA=="], + "deep-extend": ["deep-extend@0.6.0", "", {}, "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="], "deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="], @@ -1774,6 +1821,8 @@ "execa": ["execa@8.0.1", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^8.0.1", "human-signals": "^5.0.0", "is-stream": "^3.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^5.1.0", "onetime": "^6.0.0", "signal-exit": "^4.1.0", "strip-final-newline": "^3.0.0" } }, "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg=="], + "exit-hook": ["exit-hook@2.2.1", "", {}, "sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw=="], + "expand-template": ["expand-template@2.0.3", "", {}, "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg=="], "expect-type": ["expect-type@1.3.0", "", {}, "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA=="], @@ -1836,6 +1885,8 @@ "fix-dts-default-cjs-exports": ["fix-dts-default-cjs-exports@1.0.1", "", { "dependencies": { "magic-string": "^0.30.17", "mlly": "^1.7.4", "rollup": "^4.34.8" } }, "sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg=="], + "flame-chart-js": ["flame-chart-js@2.3.1", "", { "dependencies": { "color": "^3.1.3", "events": "^3.2.0" } }, "sha512-wi3g+BEYEWcxnFrakPt7A/oXVfMnun6Uvjve3kfscXXCrgP6f1O8o5LOseXfHnVI1jxTWOINnzdXPN/NLw9guQ=="], + "flat": ["flat@6.0.1", "", { "bin": { "flat": "cli.js" } }, "sha512-/3FfIa8mbrg3xE7+wAhWeV+bd7L2Mof+xtZb5dRDKZ+wDvYJK4WDYeIOuOhre5Yv5aQObZrlbRmk3RTSiuQBtw=="], "flat-cache": ["flat-cache@4.0.1", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" } }, "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw=="], @@ -2016,6 +2067,8 @@ "image-size": ["image-size@2.0.2", "", { "bin": { "image-size": "bin/image-size.js" } }, "sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w=="], + "immediate": ["immediate@3.0.6", "", {}, "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="], + "immutable": ["immutable@5.1.5", "", {}, "sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A=="], "import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="], @@ -2112,6 +2165,8 @@ "isarray": ["isarray@1.0.0", "", {}, "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="], + "isbot": ["isbot@5.1.36", "", {}, "sha512-C/ZtXyJqDPZ7G7JPr06ApWyYoHjYexQbS6hPYD4WYCzpv2Qes6Z+CCEfTX4Owzf+1EJ933PoI2p+B9v7wpGZBQ=="], + "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], "isomorphic-git": ["isomorphic-git@1.37.2", "", { "dependencies": { "async-lock": "^1.4.1", "clean-git-ref": "^2.0.1", "crc-32": "^1.2.0", "diff3": "0.0.3", "ignore": "^5.1.4", "minimisted": "^2.0.0", "pako": "^1.0.10", "pify": "^4.0.1", "readable-stream": "^4.0.0", "sha.js": "^2.4.12", "simple-get": "^4.0.1" }, "bin": { "isogit": "cli.cjs" } }, "sha512-HCQBBKmXIMPdHgYGstSBNp6MNmVcMQBbUqJF8xfywFmlpNseO4KKex59YlXqNxhRxmv3fUZwvNWvMyOdc1VvhA=="], @@ -2180,6 +2235,8 @@ "lib0": ["lib0@0.2.117", "", { "dependencies": { "isomorphic.js": "^0.2.4" }, "bin": { "0serve": "bin/0serve.js", "0gentesthtml": "bin/gentesthtml.js", "0ecdsa-generate-keypair": "bin/0ecdsa-generate-keypair.js" } }, "sha512-DeXj9X5xDCjgKLU/7RR+/HQEVzuuEUiwldwOGsHK/sfAfELGWEyTcf0x+uOvCvK3O2zPmZePXWL85vtia6GyZw=="], + "lie": ["lie@3.3.0", "", { "dependencies": { "immediate": "~3.0.5" } }, "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ=="], + "lighthouse-logger": ["lighthouse-logger@2.0.2", "", { "dependencies": { "debug": "^4.4.1", "marky": "^1.2.2" } }, "sha512-vWl2+u5jgOQuZR55Z1WM0XDdrJT6mzMP8zHUct7xTlWhuQs+eV0g+QL0RQdFjT54zVmbhLCP8vIVpy1wGn/gCg=="], "lightningcss": ["lightningcss@1.31.1", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.31.1", "lightningcss-darwin-arm64": "1.31.1", "lightningcss-darwin-x64": "1.31.1", "lightningcss-freebsd-x64": "1.31.1", "lightningcss-linux-arm-gnueabihf": "1.31.1", "lightningcss-linux-arm64-gnu": "1.31.1", "lightningcss-linux-arm64-musl": "1.31.1", "lightningcss-linux-x64-gnu": "1.31.1", "lightningcss-linux-x64-musl": "1.31.1", "lightningcss-win32-arm64-msvc": "1.31.1", "lightningcss-win32-x64-msvc": "1.31.1" } }, "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ=="], @@ -2220,6 +2277,12 @@ "listr2": ["listr2@9.0.5", "", { "dependencies": { "cli-truncate": "^5.0.0", "colorette": "^2.0.20", "eventemitter3": "^5.0.1", "log-update": "^6.1.0", "rfdc": "^1.4.1", "wrap-ansi": "^9.0.0" } }, "sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g=="], + "lit": ["lit@3.3.2", "", { "dependencies": { "@lit/reactive-element": "^2.1.0", "lit-element": "^4.2.0", "lit-html": "^3.3.0" } }, "sha512-NF9zbsP79l4ao2SNrH3NkfmFgN/hBYSQo90saIVI1o5GpjAdCPVstVzO1MrLOakHoEhYkrtRjPK6Ob521aoYWQ=="], + + "lit-element": ["lit-element@4.2.2", "", { "dependencies": { "@lit-labs/ssr-dom-shim": "^1.5.0", "@lit/reactive-element": "^2.1.0", "lit-html": "^3.3.0" } }, "sha512-aFKhNToWxoyhkNDmWZwEva2SlQia+jfG0fjIWV//YeTaWrVnOxD89dPKfigCUspXFmjzOEUQpOkejH5Ly6sG0w=="], + + "lit-html": ["lit-html@3.3.2", "", { "dependencies": { "@types/trusted-types": "^2.0.2" } }, "sha512-Qy9hU88zcmaxBXcc10ZpdK7cOLXvXpRoBxERdtqV9QOrfpMZZ6pSYP91LhpPtap3sFMUiL7Tw2RImbe0Al2/kw=="], + "local-pkg": ["local-pkg@1.1.2", "", { "dependencies": { "mlly": "^1.7.4", "pkg-types": "^2.3.0", "quansync": "^0.2.11" } }, "sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A=="], "locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="], @@ -2526,6 +2589,8 @@ "p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="], + "p-map": ["p-map@7.0.4", "", {}, "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ=="], + "package-json-from-dist": ["package-json-from-dist@1.0.1", "", {}, "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="], "package-manager-detector": ["package-manager-detector@1.6.0", "", {}, "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA=="], @@ -2686,6 +2751,8 @@ "promise": ["promise@7.3.1", "", { "dependencies": { "asap": "~2.0.3" } }, "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg=="], + "promise-worker-transferable": ["promise-worker-transferable@1.0.4", "", { "dependencies": { "is-promise": "^2.1.0", "lie": "^3.0.2" } }, "sha512-bN+0ehEnrXfxV2ZQvU2PetO0n4gqBD4ulq3MI1WOPLgr7/Mg9yRQkX5+0v1vagr74ZTsl7XtzlaYDo2EuCeYJw=="], + "property-information": ["property-information@7.1.0", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="], "prosemirror-changeset": ["prosemirror-changeset@2.4.0", "", { "dependencies": { "prosemirror-transform": "^1.0.0" } }, "sha512-LvqH2v7Q2SF6yxatuPP2e8vSUKS/L+xAU7dPDC4RMyHMhZoGDfBC74mYuyYF4gLqOEG758wajtyhNnsTkuhvng=="], @@ -2752,6 +2819,14 @@ "rc9": ["rc9@3.0.0", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.5" } }, "sha512-MGOue0VqscKWQ104udASX/3GYDcKyPI4j4F8gu/jHHzglpmy9a/anZK3PNe8ug6aZFl+9GxLtdhe3kVZuMaQbA=="], + "react": ["react@19.2.4", "", {}, "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ=="], + + "react-dom": ["react-dom@19.2.4", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.4" } }, "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ=="], + + "react-refresh": ["react-refresh@0.14.2", "", {}, "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA=="], + + "react-router": ["react-router@7.12.0", "", { "dependencies": { "cookie": "^1.0.1", "set-cookie-parser": "^2.6.0" }, "peerDependencies": { "react": ">=18", "react-dom": ">=18" }, "optionalPeers": ["react-dom"] }, "sha512-kTPDYPFzDVGIIGNLS5VJykK0HfHLY5MF3b+xj0/tTyNYL1gF1qs7u67Z9jEhQk2sQ98SUaHxlG31g1JtF7IfVw=="], + "readable-stream": ["readable-stream@4.7.0", "", { "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", "process": "^0.11.10", "string_decoder": "^1.3.0" } }, "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg=="], "readdir-glob": ["readdir-glob@1.1.3", "", { "dependencies": { "minimatch": "^5.1.0" } }, "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA=="], @@ -2774,6 +2849,8 @@ "regexp-tree": ["regexp-tree@0.1.27", "", { "bin": { "regexp-tree": "bin/regexp-tree" } }, "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA=="], + "regexparam": ["regexparam@2.0.2", "", {}, "sha512-A1PeDEYMrkLrfyOwv2jwihXbo9qxdGD3atBYQA9JJgreAx8/7rC6IUkWOw2NQlOxLp2wL0ifQbh1HuidDfYA6w=="], + "regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="], "rehype-external-links": ["rehype-external-links@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "@ungap/structured-clone": "^1.0.0", "hast-util-is-element": "^3.0.0", "is-absolute-url": "^4.0.0", "space-separated-tokens": "^2.0.0", "unist-util-visit": "^5.0.0" } }, "sha512-yp+e5N9V3C6bwBeAC4n796kc86M4gJCdlVhiMTxIrJG5UHDMh+PJANf9heqORJbt1nrCbDwIlAZKjANIaVBbvw=="], @@ -2856,6 +2933,8 @@ "sax": ["sax@1.5.0", "", {}, "sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA=="], + "scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="], + "scslre": ["scslre@0.3.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.8.0", "refa": "^0.12.0", "regexp-ast-analysis": "^0.7.0" } }, "sha512-3A6sD0WYP7+QrjbfNA2FN3FsOaGGFoekCVgTyypy53gPxhbkCIjtO6YWgdrfM+n/8sI8JeXZOIxsHjMTNxQ4nQ=="], "scule": ["scule@1.3.0", "", {}, "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g=="], @@ -2874,6 +2953,8 @@ "serve-static": ["serve-static@2.2.1", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw=="], + "set-cookie-parser": ["set-cookie-parser@2.7.2", "", {}, "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw=="], + "set-function-length": ["set-function-length@1.2.2", "", { "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2" } }, "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg=="], "setimmediate": ["setimmediate@1.0.5", "", {}, "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA=="], @@ -2914,6 +2995,8 @@ "simple-git": ["simple-git@3.32.3", "", { "dependencies": { "@kwsites/file-exists": "^1.1.1", "@kwsites/promise-deferred": "^1.1.1", "debug": "^4.4.0" } }, "sha512-56a5oxFdWlsGygOXHWrG+xjj5w9ZIt2uQbzqiIGdR/6i5iococ7WQ/bNPzWxCJdEUGUCmyMH0t9zMpRJTaKxmw=="], + "simple-swizzle": ["simple-swizzle@0.2.4", "", { "dependencies": { "is-arrayish": "^0.3.1" } }, "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw=="], + "sirv": ["sirv@3.0.2", "", { "dependencies": { "@polka/url": "^1.0.0-next.24", "mrmime": "^2.0.0", "totalist": "^3.0.0" } }, "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g=="], "sisteransi": ["sisteransi@1.0.5", "", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="], @@ -3032,6 +3115,8 @@ "text-decoder": ["text-decoder@1.2.7", "", { "dependencies": { "b4a": "^1.6.4" } }, "sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ=="], + "three": ["three@0.182.0", "", {}, "sha512-GbHabT+Irv+ihI1/f5kIIsZ+Ef9Sl5A1Y7imvS5RQjWgtTPfPnZ43JmlYI7NtCRDK9zir20lQpfg8/9Yd02OvQ=="], + "timeout-signal": ["timeout-signal@2.0.0", "", {}, "sha512-YBGpG4bWsHoPvofT6y/5iqulfXIiIErl5B0LdtHT1mGXDFTAhhRrbUpTvBgYbovr+3cKblya2WAOcpoy90XguA=="], "tiny-inflate": ["tiny-inflate@1.0.3", "", {}, "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw=="], @@ -3180,8 +3265,16 @@ "urlpattern-polyfill": ["urlpattern-polyfill@10.1.0", "", {}, "sha512-IGjKp/o0NL3Bso1PymYURCJxMPNAf/ILOpendP9f5B6e1rTJgdgiOvgfoT8VxCAdY+Wisb9uhGaJJf3yZ2V9nw=="], + "use-isomorphic-layout-effect": ["use-isomorphic-layout-effect@1.2.1", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-tpZZ+EX0gaghDAiFR37hj5MgY6ZN55kLiPkJsKxBMZ6GZdOSPJXiOzPM984oPYZ5AnehYx5WQp1+ME8I/P/pRA=="], + + "use-resize-observer": ["use-resize-observer@9.1.0", "", { "dependencies": { "@juggle/resize-observer": "^3.3.1" }, "peerDependencies": { "react": "16.8.0 - 18", "react-dom": "16.8.0 - 18" } }, "sha512-R25VqO9Wb3asSD4eqtcxk8sJalvIOYBqS8MNZlpDSQ4l4xMQxC/J7Id9HoTqPq8FwULIn0PVW+OAqF2dyYbjow=="], + + "use-sync-external-store": ["use-sync-external-store@1.6.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w=="], + "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], + "valibot": ["valibot@1.2.0", "", { "peerDependencies": { "typescript": ">=5" }, "optionalPeers": ["typescript"] }, "sha512-mm1rxUsmOxzrwnX5arGS+U4T25RdvpPjPN4yR0u9pUBov9+zGVtO84tif1eY4r6zWxVxu3KzIyknJy3rxfRZZg=="], + "vary": ["vary@1.1.2", "", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="], "vaul-vue": ["vaul-vue@0.4.1", "", { "dependencies": { "@vueuse/core": "^10.8.0", "reka-ui": "^2.0.0", "vue": "^3.4.5" } }, "sha512-A6jOWOZX5yvyo1qMn7IveoWN91mJI5L3BUKsIwkg6qrTGgHs1Sb1JF/vyLJgnbN1rH4OOOxFbtqL9A46bOyGUQ=="], @@ -3260,6 +3353,8 @@ "word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="], + "worktop": ["worktop@0.7.3", "", { "dependencies": { "regexparam": "^2.0.0" } }, "sha512-WBHP1hk8pLP7ahAw13fugDWcO0SUAOiCD6DHT/bfLWoCIA/PL9u7GKdudT2nGZ8EGR1APbGCAI6ZzKG1+X+PnQ=="], + "wrap-ansi": ["wrap-ansi@9.0.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww=="], "wrap-ansi-cjs": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], @@ -3532,6 +3627,16 @@ "@poppinss/dumper/supports-color": ["supports-color@10.2.2", "", {}, "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g=="], + "@react-router/dev/chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="], + + "@react-router/dev/es-module-lexer": ["es-module-lexer@1.7.0", "", {}, "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA=="], + + "@react-router/dev/jsesc": ["jsesc@3.0.2", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g=="], + + "@react-router/dev/pathe": ["pathe@1.1.2", "", {}, "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ=="], + + "@react-router/dev/vite-node": ["vite-node@3.2.4", "", { "dependencies": { "cac": "^6.7.14", "debug": "^4.4.1", "es-module-lexer": "^1.7.0", "pathe": "^2.0.3", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" }, "bin": { "vite-node": "vite-node.mjs" } }, "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg=="], + "@rollup/plugin-commonjs/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], "@rollup/plugin-inject/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], @@ -3546,6 +3651,10 @@ "@shopify/graphql-codegen/@graphql-codegen/typescript": ["@graphql-codegen/typescript@4.1.6", "", { "dependencies": { "@graphql-codegen/plugin-helpers": "^5.1.0", "@graphql-codegen/schema-ast": "^4.0.2", "@graphql-codegen/visitor-plugin-common": "5.8.0", "auto-bind": "~4.0.0", "tslib": "~2.6.0" }, "peerDependencies": { "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, "sha512-vpw3sfwf9A7S+kIUjyFxuvrywGxd4lmwmyYnnDVjVE4kSQ6Td3DpqaPTy8aNQ6O96vFoi/bxbZS2BW49PwSUUA=="], + "@shopify/hydrogen/@shopify/graphql-client": ["@shopify/graphql-client@1.4.1", "", {}, "sha512-/w4Uchx8ueI8gwmJd1ZbbIGndsjfMEFlzmay3P7rya5zj7K308xne/ggIvWDweueIut2qf1A8lI58xQl9Pu22w=="], + + "@shopify/hydrogen-react/ast-v8-to-istanbul": ["ast-v8-to-istanbul@0.3.12", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.31", "estree-walker": "^3.0.3", "js-tokens": "^10.0.0" } }, "sha512-BRRC8VRZY2R4Z4lFIL35MwNXmwVqBityvOIwETtsCSwvjl0IdgFsy9NhdaA6j74nUdtJJlIypeRhpDam19Wq3g=="], + "@stylistic/eslint-plugin/eslint-visitor-keys": ["eslint-visitor-keys@4.2.1", "", {}, "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ=="], "@stylistic/eslint-plugin/espree": ["espree@10.4.0", "", { "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.1" } }, "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ=="], @@ -3634,6 +3743,8 @@ "cliui/wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], + "color/color-convert": ["color-convert@1.9.3", "", { "dependencies": { "color-name": "1.1.3" } }, "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="], + "compress-commons/is-stream": ["is-stream@2.0.1", "", {}, "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="], "cross-fetch/node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], @@ -3654,6 +3765,8 @@ "eslint-plugin-vue/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="], + "express/cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="], + "externality/pathe": ["pathe@1.1.2", "", {}, "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ=="], "fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], @@ -3794,6 +3907,8 @@ "postcss-unique-selectors/postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="], + "promise-worker-transferable/is-promise": ["is-promise@2.2.2", "", {}, "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ=="], + "raw-body/iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="], "rc/strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="], @@ -3814,6 +3929,8 @@ "shiki/@shikijs/types": ["@shikijs/types@4.0.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-LCnfBTtQKNtJyc1qMShZr2dJt1uxNI6pI0/YTc2DSNET91aUvnMGHUHsucVCC5AJVcv5XyBqk2NgYRwd20EjbA=="], + "simple-swizzle/is-arrayish": ["is-arrayish@0.3.4", "", {}, "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA=="], + "slice-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], "slice-ansi/is-fullwidth-code-point": ["is-fullwidth-code-point@5.1.0", "", { "dependencies": { "get-east-asian-width": "^1.3.1" } }, "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ=="], @@ -4102,6 +4219,10 @@ "@nuxtjs/mdc/shiki/@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g=="], + "@react-router/dev/chokidar/readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="], + + "@react-router/dev/vite-node/pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], + "@shopify/graphql-codegen/@graphql-codegen/add/@graphql-codegen/plugin-helpers": ["@graphql-codegen/plugin-helpers@5.1.1", "", { "dependencies": { "@graphql-tools/utils": "^10.0.0", "change-case-all": "1.0.15", "common-tags": "1.8.2", "import-from": "4.0.0", "lodash": "~4.17.0", "tslib": "~2.6.0" }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, "sha512-28GHODK2HY1NhdyRcPP3sCz0Kqxyfiz7boIZ8qIxFYmpLYnlDgiYok5fhFLVSZihyOpCs4Fa37gVHf/Q4I2FEg=="], "@shopify/graphql-codegen/@graphql-codegen/add/tslib": ["tslib@2.6.3", "", {}, "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ=="], @@ -4150,6 +4271,8 @@ "cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + "color/color-convert/color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="], + "csso/css-tree/mdn-data": ["mdn-data@2.0.28", "", {}, "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g=="], "fontless/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.3", "", { "os": "aix", "cpu": "ppc64" }, "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg=="], diff --git a/knip.json b/knip.json index 3e01051d..86daa7c3 100644 --- a/knip.json +++ b/knip.json @@ -19,7 +19,8 @@ "@graphql-codegen/import-types-preset", "@graphql-codegen/introspection", "@shopify/api-codegen-preset", - "@graphql-tools/graphql-tag-pluck" + "@graphql-tools/graphql-tag-pluck", + "@shopify/hydrogen" ] }, "docs": { @@ -75,6 +76,9 @@ ], "project": [ "**/*.{ts,vue}" + ], + "ignoreDependencies": [ + "@shopify/hydrogen" ] }, "playgrounds/playground-v4-mock": { diff --git a/package.json b/package.json index 195a87fa..4e8abe6d 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,9 @@ "./storefront": { "types": "./dist/clients/storefront.d.ts" }, + "./customer-account": { + "types": "./dist/clients/customer-account.d.ts" + }, "./admin": { "types": "./dist/clients/admin.d.ts" } @@ -36,6 +39,9 @@ "storefront": [ "./dist/clients/storefront.d.ts" ], + "customer-account": [ + "./dist/clients/customer-account.d.ts" + ], "admin": [ "./dist/clients/admin.d.ts" ] diff --git a/playgrounds/playground-v3/nuxt.config.ts b/playgrounds/playground-v3/nuxt.config.ts index 3fa3e568..93bd0711 100644 --- a/playgrounds/playground-v3/nuxt.config.ts +++ b/playgrounds/playground-v3/nuxt.config.ts @@ -27,7 +27,7 @@ export default defineNuxtConfig({ serverDir: 'server/', - compatibilityDate: '2025-11-01', + compatibilityDate: '2026-03-15', hooks: { // Fix monorepo-specific tsconfig issue when running `nuxt prepare` diff --git a/playgrounds/playground-v4-mock/nuxt.config.ts b/playgrounds/playground-v4-mock/nuxt.config.ts index 1d8b5f8e..9c910106 100644 --- a/playgrounds/playground-v4-mock/nuxt.config.ts +++ b/playgrounds/playground-v4-mock/nuxt.config.ts @@ -15,7 +15,7 @@ export default defineNuxtConfig({ }, }, - compatibilityDate: '2025-11-01', + compatibilityDate: '2026-03-15', shopify: { clients: { diff --git a/playgrounds/playground-v4/app/pages/customer.vue b/playgrounds/playground-v4/app/pages/customer.vue new file mode 100644 index 00000000..4ce335de --- /dev/null +++ b/playgrounds/playground-v4/app/pages/customer.vue @@ -0,0 +1,18 @@ + + + diff --git a/playgrounds/playground-v4/graphql/customer-account/index.ts b/playgrounds/playground-v4/graphql/customer-account/index.ts new file mode 100644 index 00000000..e8fe3c65 --- /dev/null +++ b/playgrounds/playground-v4/graphql/customer-account/index.ts @@ -0,0 +1,7 @@ +export const CUSTOMER_FRAGMENT = `#graphql + fragment CustomerFields on Customer { + id + firstName + lastName + } +` diff --git a/playgrounds/playground-v4/nuxt.config.ts b/playgrounds/playground-v4/nuxt.config.ts index 3addee05..8d25d2fd 100644 --- a/playgrounds/playground-v4/nuxt.config.ts +++ b/playgrounds/playground-v4/nuxt.config.ts @@ -13,6 +13,13 @@ export default defineNuxtConfig({ publicAccessToken: '', }, + customerAccount: { + apiVersion: '', + clientId: '', + + autoImport: false, + }, + admin: { apiVersion: '', accessToken: '', @@ -34,5 +41,5 @@ export default defineNuxtConfig({ }, }, - compatibilityDate: '2025-11-01', + compatibilityDate: '2026-03-15', }) diff --git a/playgrounds/playground-v4/package.json b/playgrounds/playground-v4/package.json index 40ab41f6..83213034 100644 --- a/playgrounds/playground-v4/package.json +++ b/playgrounds/playground-v4/package.json @@ -13,5 +13,8 @@ }, "dependencies": { "nuxt": "^4.4.2" + }, + "devDependencies": { + "@shopify/hydrogen": "^2026.1.2" } } diff --git a/src/clients/customer-account.d.ts b/src/clients/customer-account.d.ts new file mode 100644 index 00000000..2fa4c3a4 --- /dev/null +++ b/src/clients/customer-account.d.ts @@ -0,0 +1,22 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import type { ShopifyApiClient } from '../module' + +export interface CustomerAccountQueries { + [key: string]: { + variables: any + return: any + } + [key: number | symbol]: never +} + +export interface CustomerAccountMutations { + [key: string]: { + variables: any + return: any + } + [key: number | symbol]: never +} + +export interface CustomerAccountOperations extends CustomerAccountQueries, CustomerAccountMutations {} + +export type CustomerAccountApiClient = ShopifyApiClient diff --git a/src/runtime/composables/customer-account.ts b/src/runtime/composables/customer-account.ts new file mode 100644 index 00000000..ff031911 --- /dev/null +++ b/src/runtime/composables/customer-account.ts @@ -0,0 +1,36 @@ +import type { CustomerAccountApiClient, CustomerAccountOperations } from '@nuxtjs/shopify/customer-account' + +import { useRuntimeConfig, useNuxtApp } from '#imports' +import { createClient } from '../utils/client' +import { createCustomerAccountConfig } from '../utils/clients/customer-account' +import useErrors from '../utils/errors' + +export function useCustomerAccount(): CustomerAccountApiClient { + const { _shopify } = useRuntimeConfig().public + + const config = createCustomerAccountConfig(_shopify) + + const nuxtApp = useNuxtApp() + + nuxtApp.hooks.callHook('customer-account:client:configure', { config }) + + const originalClient = createClient(config) + + const request: CustomerAccountApiClient['request'] = async (operation, options) => { + nuxtApp.hooks.callHook('customer-account:client:request', { operation, options }) + + const response = await originalClient.request(operation, options) + + if (response.errors) useErrors(nuxtApp.hooks, 'customer-account:client:errors', response.errors, _shopify?.errors?.throw ?? false) + + nuxtApp.hooks.callHook('customer-account:client:response', { response, operation, options }) + + return response + } + + const client = { ...originalClient, request } satisfies CustomerAccountApiClient + + nuxtApp.hooks.callHook('customer-account:client:create', { client }) + + return client +} diff --git a/src/runtime/server/utils/customer-account.ts b/src/runtime/server/utils/customer-account.ts new file mode 100644 index 00000000..72ec0905 --- /dev/null +++ b/src/runtime/server/utils/customer-account.ts @@ -0,0 +1,37 @@ +import type { CustomerAccountApiClient, CustomerAccountOperations } from '@nuxtjs/shopify/customer-account' + +import { useNitroApp } from 'nitropack/runtime' +import { useRuntimeConfig } from '#imports' +import { createClient } from '../../utils/client' +import { createCustomerAccountConfig } from '../../utils/clients/customer-account' +import useErrors from '../../utils/errors' + +export function useCustomerAccount(): CustomerAccountApiClient { + const { _shopify } = useRuntimeConfig() + + const config = createCustomerAccountConfig(_shopify) + + const nitroApp = useNitroApp() + + nitroApp.hooks.callHook('customer-account:client:configure', { config }) + + const originalClient = createClient(config) + + const request: CustomerAccountApiClient['request'] = async (operation, options) => { + nitroApp.hooks.callHook('customer-account:client:request', { operation, options }) + + const response = await originalClient.request(operation, options) + + if (response.errors) useErrors(nitroApp.hooks, 'customer-account:client:errors', response.errors, _shopify?.errors?.throw ?? false) + + nitroApp.hooks.callHook('customer-account:client:response', { response, operation, options }) + + return response + } + + const client = { ...originalClient, request } satisfies CustomerAccountApiClient + + nitroApp.hooks.callHook('customer-account:client:create', { client }) + + return client +} diff --git a/src/runtime/utils/clients/customer-account.ts b/src/runtime/utils/clients/customer-account.ts new file mode 100644 index 00000000..29d97669 --- /dev/null +++ b/src/runtime/utils/clients/customer-account.ts @@ -0,0 +1,49 @@ +import type { + ShopifyApiClientConfig, + ShopifyConfig, + PublicShopifyConfig, +} from '../../../module' + +import { + createApiUrl, + createStoreDomain, +} from '../client' + +export const createCustomerAccountConfig = (config?: ShopifyConfig | PublicShopifyConfig): ShopifyApiClientConfig => { + if (!config?.clients?.customerAccount) { + throw new Error('Could not create customer account client') + } + + const { + name, + logger, + + clients: { + customerAccount: { + apiVersion, + headers, + + clientId, + clientSecret, + }, + }, + } = config + + if (!name || !clientId) { + throw new Error('Could not create customer account client') + } + + const apiUrl = createApiUrl(createStoreDomain(name), apiVersion) + + return { + storeDomain: createStoreDomain(name), + apiUrl, + apiVersion, + logger, + headers: { + ...(clientId ? { 'Shopify-Storefront-Public-Token': clientId } : {}), + ...(clientSecret ? { 'Shopify-Storefront-Private-Token': clientSecret } : {}), + ...headers, + }, + } satisfies ShopifyApiClientConfig +} diff --git a/src/schemas/config.ts b/src/schemas/config.ts index bdd9fefe..c12691c3 100644 --- a/src/schemas/config.ts +++ b/src/schemas/config.ts @@ -7,6 +7,7 @@ import { z } from 'zod' export enum ShopifyClientType { Storefront = 'storefront', + CustomerAccount = 'customerAccount', Admin = 'admin', } @@ -41,6 +42,13 @@ export const storefrontClientSchema = clientSchema.extend({ cache: clientCacheSchema.or(z.boolean()).optional(), }) +export const customerAccountClientSchema = clientSchema.extend({ + clientId: z.string(), + clientSecret: z.string().optional(), + scope: z.array(z.string()).optional(), + redirectURL: z.string().optional(), +}) + export const adminClientSchema = clientSchema.extend({ accessToken: z.string(), }) @@ -53,6 +61,7 @@ export const moduleOptionsSchema = z.object({ clients: z.object({ [ShopifyClientType.Storefront]: storefrontClientSchema.optional(), [ShopifyClientType.Admin]: adminClientSchema.optional(), + [ShopifyClientType.CustomerAccount]: customerAccountClientSchema.optional(), }), errors: z.object({ diff --git a/src/schemas/runtime.ts b/src/schemas/runtime.ts index e3d3a5b7..3117cdd6 100644 --- a/src/schemas/runtime.ts +++ b/src/schemas/runtime.ts @@ -5,12 +5,14 @@ import { getCurrentApiVersion, getCurrentSupportedApiVersions, } from '@shopify/graphql-client' +import { kebabCase } from 'scule' import { z } from 'zod' import { ShopifyClientType, clientSchema, storefrontClientSchema, + customerAccountClientSchema, adminClientSchema, moduleOptionsSchema, publicModuleOptionsSchema, @@ -24,16 +26,37 @@ const ignores = [ '!.output', ] +const getDefaultDocuments = (clientType: string, { exclude }: { exclude?: boolean } = {}) => { + const clientName = kebabCase(clientType) + const fileEndings = ['gql', 'graphql', 'ts', 'js', ...(clientType !== ShopifyClientType.Admin ? ['vue'] : [])].join(',') + + return [ + `${exclude ? '!' : ''}**/*.${clientName}.{${fileEndings}}`, + `${exclude ? '!' : ''}**/${clientName}.{${fileEndings}}`, + `${exclude ? '!' : ''}**/${clientName}/**/*.{${fileEndings}}`, + `${exclude ? '!' : ''}**/${clientName}/*.{${fileEndings}}`, + `${exclude ? '!' : ''}**/(${clientName})/**/*.{${fileEndings}}`, + `${exclude ? '!' : ''}**/(${clientName})/*.{${fileEndings}}`, + ] +} + const defaultStorefrontDocuments = [ - '**/*.{gql,graphql,ts,js}', - '!**/*.admin.{gql,graphql,ts,js}', - '!**/admin/**/*.{gql,graphql,ts,js}', + '**/*.{gql,graphql,ts,js,vue}', + + ...getDefaultDocuments(ShopifyClientType.Admin, { exclude: true }), + ...getDefaultDocuments(ShopifyClientType.CustomerAccount, { exclude: true }), + ...getDefaultDocuments('customer', { exclude: true }), + ...ignores, +] + +const defaultCustomerAccountDocuments = [ + ...getDefaultDocuments(ShopifyClientType.CustomerAccount), + ...getDefaultDocuments('customer'), ...ignores, ] const defaultAdminDocuments = [ - '**/*.admin.{gql,graphql,ts,js}', - '**/admin/**/*.{gql,graphql,ts,js}', + ...getDefaultDocuments(ShopifyClientType.Admin), ...ignores, ] @@ -85,6 +108,17 @@ const storefrontClientSchemaWithDefaults = clientSchemaWithDefaults.omit({ cache: clientCacheSchemaWithDefaults.or(z.boolean()).optional().default(defaultCacheConfig).transform(v => v === true ? defaultCacheConfig : v), }) +const customerAccountClientSchemaWithDefaults = clientSchemaWithDefaults.omit({ + documents: true, +}).extend({ + clientId: customerAccountClientSchema.shape.clientId, + clientSecret: customerAccountClientSchema.shape.clientSecret, + scope: customerAccountClientSchema.shape.scope, + redirectURL: customerAccountClientSchema.shape.redirectURL, + + documents: customerAccountClientSchema.shape.documents.transform(v => v ? v : defaultCustomerAccountDocuments), +}) + const adminClientSchemaWithDefaults = clientSchemaWithDefaults.omit({ documents: true, }).extend({ @@ -110,6 +144,8 @@ export const moduleOptionsSchemaWithDefaults = moduleOptionsSchema.omit({ error: 'Either a public or private access token must be provided for the storefront client', }).optional(), + [ShopifyClientType.CustomerAccount]: customerAccountClientSchemaWithDefaults.optional(), + [ShopifyClientType.Admin]: adminClientSchemaWithDefaults.optional(), }), @@ -153,6 +189,13 @@ export const publicModuleOptionsSchemaWithDefaults = publicModuleOptionsSchema.o options: defaultCacheOptions, }).transform(v => typeof v === 'undefined' || v === true ? { client: defaultClientCacheOptions, options: defaultCacheOptions } : v), })).optional(), + + [ShopifyClientType.CustomerAccount]: customerAccountClientSchemaWithDefaults.omit({ + sandbox: true, + documents: true, + codegen: true, + autoImport: true, + }).optional(), }), errors: moduleOptionsSchemaWithDefaults.shape.errors, diff --git a/src/setup/clients.ts b/src/setup/clients.ts index 76c06c35..dc421a60 100644 --- a/src/setup/clients.ts +++ b/src/setup/clients.ts @@ -6,8 +6,10 @@ import { useLogger } from '../utils/log' import { getConfiguredClients, isPublicClient, - registerClientServerImports, registerClientImports, + registerClientServerImports, + registerClientAsyncImports, + isPublicAsyncClient, } from '../utils/clients' export default async function setupClients(config: ShopifyConfig, resolver: Resolver) { @@ -22,5 +24,9 @@ export default async function setupClients(config: ShopifyConfig, resolver: Reso if (isPublicClient(config.clients[clientType])) { registerClientImports(clientType, resolver) } + + if (isPublicAsyncClient(config.clients[clientType])) { + registerClientAsyncImports(clientType, resolver) + } } } diff --git a/src/setup/dev.ts b/src/setup/dev.ts index a2f71791..039fe392 100644 --- a/src/setup/dev.ts +++ b/src/setup/dev.ts @@ -9,14 +9,16 @@ export default async function setupDevMode(nuxt: Nuxt, logger: ConsolaInstance) const resolver = createResolver(import.meta.url) const sourceFiles = { - admin: resolver.resolve('../../src/clients/admin.d.ts'), storefront: resolver.resolve('../../src/clients/storefront.d.ts'), + customerAccount: resolver.resolve('../../src/clients/customer-account.d.ts'), + admin: resolver.resolve('../../src/clients/admin.d.ts'), types: resolver.resolve('../../src/types/index.d.ts'), } const sourceFilesExist = await Promise.all([ - stat(sourceFiles.admin).catch(() => false), stat(sourceFiles.storefront).catch(() => false), + stat(sourceFiles.customerAccount).catch(() => false), + stat(sourceFiles.admin).catch(() => false), ]).then(results => results.every(result => result !== false)) if (sourceFilesExist) { @@ -25,6 +27,7 @@ export default async function setupDevMode(nuxt: Nuxt, logger: ConsolaInstance) nuxt.options = defu(nuxt.options, { alias: { '@nuxtjs/shopify/storefront': sourceFiles.storefront, + '@nuxtjs/shopify/customer-account': sourceFiles.customerAccount, '@nuxtjs/shopify/admin': sourceFiles.admin, }, @@ -41,6 +44,7 @@ export default async function setupDevMode(nuxt: Nuxt, logger: ConsolaInstance) tsConfig: { include: [ sourceFiles.storefront, + sourceFiles.customerAccount, sourceFiles.admin, ], }, diff --git a/src/types/index.d.ts b/src/types/index.d.ts index a33e9e0a..57c1eae2 100644 --- a/src/types/index.d.ts +++ b/src/types/index.d.ts @@ -1,5 +1,6 @@ import type { HookResult, Nuxt } from '@nuxt/schema' import type { StorefrontOperations } from '@nuxtjs/shopify/storefront' +import type { CustomerAccountOperations } from '@nuxtjs/shopify/customer-account' import type { AdminOperations } from '@nuxtjs/shopify/admin' import type { AllOperations, @@ -99,6 +100,21 @@ declare module '@nuxt/schema' { */ 'storefront:generate:operations': ({ nuxt, config }: ShopifyTemplateHookParams) => HookResult + /** + * Called before the customer account introspection schema is generated + */ + 'customer-account:generate:introspection': ({ nuxt, config }: ShopifyTemplateHookParams) => HookResult + + /** + * Called before the customer account types are generated + */ + 'customer-account:generate:types': ({ nuxt, config }: ShopifyTemplateHookParams) => HookResult + + /** + * Called before the customer account operations are generated + */ + 'customer-account:generate:operations': ({ nuxt, config }: ShopifyTemplateHookParams) => HookResult + /** * Called before the admin introspection schema is generated */ @@ -150,6 +166,31 @@ declare module '#app' { * Called when the storefront client throws an error within nuxt */ 'storefront:client:errors': ({ errors }: ShopifyErrorHookParams) => HookResult + + /** + * Called before the customer account client is created within nuxt + */ + 'customer-account:client:configure': ({ config }: ShopifyClientOptionHookParams) => HookResult + + /** + * Called after the customer account client is created within nuxt + */ + 'customer-account:client:create': ({ client }: ShopifyClientHookParams) => HookResult + + /** + * Called before the customer account client sends a request within nuxt + */ + 'customer-account:client:request': ({ operation, options }: ShopifyClientRequestHookParams) => HookResult + + /** + * Called after the customer account client receives a response within nuxt + */ + 'customer-account:client:response': ({ response, operation, options }: ShopifyClientResponseHookParams) => HookResult + + /** + * Called when the customer account client throws an error within nuxt + */ + 'customer-account:client:errors': ({ errors }: ShopifyErrorHookParams) => HookResult } } @@ -180,6 +221,31 @@ declare module 'nitropack/types' { */ 'storefront:client:errors': ({ errors }: ShopifyErrorHookParams) => HookResult + /** + * Called before the customer account client is created within nitro + */ + 'customer-account:client:configure': ({ config }: ShopifyClientOptionHookParams) => HookResult + + /** + * Called after the customer account client is created within nitro + */ + 'customer-account:client:create': ({ client }: ShopifyClientHookParams) => HookResult + + /** + * Called before the customer account client sends a request within nitro + */ + 'customer-account:client:request': ({ operation, options }: ShopifyClientRequestHookParams) => HookResult + + /** + * Called after the customer account client receives a response within nitro + */ + 'customer-account:client:response': ({ response, operation, options }: ShopifyClientResponseHookParams) => HookResult + + /** + * Called when the customer account client throws an error within nitro + */ + 'customer-account:client:errors': ({ errors }: ShopifyErrorHookParams) => HookResult + /** * Called before the admin client is created within nitro */ diff --git a/src/utils/clients.ts b/src/utils/clients.ts index f8c3c7c0..26ef1f50 100644 --- a/src/utils/clients.ts +++ b/src/utils/clients.ts @@ -3,41 +3,51 @@ import type { Resolver } from '@nuxt/kit' import type { ShopifyConfig } from '../types' import { addServerImports, addImports } from '@nuxt/kit' -import { upperFirst } from 'scule' +import { upperFirst, kebabCase } from 'scule' import { ShopifyClientType } from '../schemas' export function registerClientServerImports(clientType: ShopifyClientType, resolver: Resolver) { addServerImports([{ - from: resolver.resolve(`./runtime/server/utils/${clientType}`), + from: resolver.resolve(`./runtime/server/utils/${kebabCase(clientType)}`), name: `use${upperFirst(clientType)}`, }]) } export function registerClientImports(clientType: ShopifyClientType, resolver: Resolver) { - addImports([ - { - from: resolver.resolve(`./runtime/composables/${clientType}`), - name: `use${upperFirst(clientType)}`, - }, - { - from: resolver.resolve(`./runtime/composables/async/${clientType}`), - name: `use${upperFirst(clientType)}Data`, - }, - ]) + addImports([{ + from: resolver.resolve(`./runtime/composables/${kebabCase(clientType)}`), + name: `use${upperFirst(clientType)}`, + }]) +} + +export function registerClientAsyncImports(clientType: ShopifyClientType, resolver: Resolver) { + addImports([{ + from: resolver.resolve(`./runtime/composables/async/${kebabCase(clientType)}`), + name: `use${upperFirst(clientType)}Data`, + }]) } export function isPublicClient(config: ShopifyConfig['clients'][ShopifyClientType]): boolean { - return !!( - (config as { publicAccessToken?: string })?.publicAccessToken + return !!((config as { publicAccessToken?: string })?.publicAccessToken + || (config as { mock?: boolean })?.mock + || (config as { clientId?: string })?.clientId + ) +} + +export function isPublicAsyncClient(config: ShopifyConfig['clients'][ShopifyClientType]): boolean { + return !!((config as { publicAccessToken?: string })?.publicAccessToken || (config as { mock?: boolean })?.mock ) } export function hasPublicClient(config: ShopifyConfig): boolean { const storefrontConfig = config.clients[ShopifyClientType.Storefront] + const customerAccountConfig = config.clients[ShopifyClientType.CustomerAccount] - return !!(storefrontConfig?.publicAccessToken || storefrontConfig?.mock) + return !!(storefrontConfig?.publicAccessToken + || storefrontConfig?.mock + || customerAccountConfig?.clientId) } export function getConfiguredClients(config: ShopifyConfig): ShopifyClientType[] { diff --git a/src/utils/codegen.ts b/src/utils/codegen.ts index 7b42ae22..8bbd8e50 100644 --- a/src/utils/codegen.ts +++ b/src/utils/codegen.ts @@ -47,7 +47,7 @@ declare module '@nuxtjs/shopify/${kebabCase(clientType)}' { ` } -function getIntrospection(options: ShopifyTemplateOptions, _config: ShopifyConfig) { +function getIntrospection(options: ShopifyTemplateOptions, config: ShopifyConfig) { const { shopName, clientType, clientConfig, introspection } = options if (introspection && existsSync(introspection)) { @@ -59,12 +59,7 @@ function getIntrospection(options: ShopifyTemplateOptions, _config: ShopifyConfi let apiUrl: string - if (clientType === ShopifyClientType.Admin) { - const adminConfig = clientConfig as NonNullable - apiUrl = `https://${shopName}.myshopify.com/admin/api/${apiVersion}/graphql.json` - headers['X-Shopify-Access-Token'] = adminConfig.accessToken - } - else { + if (clientType === ShopifyClientType.Storefront) { const storefrontConfig = clientConfig as NonNullable if (storefrontConfig.mock) { @@ -81,6 +76,24 @@ function getIntrospection(options: ShopifyTemplateOptions, _config: ShopifyConfi } } } + else if (clientType === ShopifyClientType.CustomerAccount) { + try { + return [import.meta.resolve('@shopify/hydrogen/customer-account.schema.json')] + } + catch (error) { + useLogger(config).error('Failed to load customer account schema. Please ensure @shopify/hydrogen is installed.', error) + } + + return [] + } + else if (clientType === ShopifyClientType.Admin) { + const adminConfig = clientConfig as NonNullable + apiUrl = `https://${shopName}.myshopify.com/admin/api/${apiVersion}/graphql.json` + headers['X-Shopify-Access-Token'] = adminConfig.accessToken + } + else { + throw new Error(`Unsupported client type: ${clientType}`) + } return [ { diff --git a/src/utils/imports.ts b/src/utils/imports.ts index 1e3816f4..24713a4d 100644 --- a/src/utils/imports.ts +++ b/src/utils/imports.ts @@ -5,6 +5,7 @@ import type { ShopifyClientType, ShopifyConfig } from '../types' import { existsSync } from 'node:fs' import { join } from 'node:path' +import { kebabCase } from 'scule' import { addImports, addImportsDir, @@ -58,7 +59,7 @@ export function registerClientTypeImports(nuxt: Nuxt, config: ShopifyConfig, cli if (!clientConfig?.autoImport) return const includeClient = hasPublicClient(config) - const typesPath = join(nuxt.options.buildDir, `types/${clientType}`) + const typesPath = join(nuxt.options.buildDir, `types/${kebabCase(clientType)}`) autoImportDirectory(typesPath, includeClient) } diff --git a/src/utils/sandbox.ts b/src/utils/sandbox.ts index ea7347fa..d986f6ba 100644 --- a/src/utils/sandbox.ts +++ b/src/utils/sandbox.ts @@ -1,21 +1,24 @@ import type { Nuxt } from '@nuxt/schema' import type { H3Event } from 'h3' -import type { ShopifyClientType, ShopifyConfig } from '../types' +import type { ShopifyConfig } from '../types' +import { ShopifyClientType } from '../schemas' import { addDevServerHandler } from '@nuxt/kit' import { createError, defineEventHandler, readValidatedBody } from 'h3' +import { kebabCase } from 'scule' import { z } from 'zod' import { createClient } from '../runtime/utils/client' import { createStorefrontConfig } from '../runtime/utils/clients/storefront' +import { createCustomerAccountConfig } from '../runtime/utils/clients/customer-account' import { createAdminConfig } from '../runtime/utils/clients/admin' import getSandboxTemplate from '../templates/sandbox' function getSandboxUrl(nuxt: Nuxt, clientType: ShopifyClientType): string { const url = new URL(nuxt.options.devServer.url) - return url.href + '_sandbox/' + clientType + return url.href + '_sandbox/' + kebabCase(clientType) } function createSandboxHandler(clientType: ShopifyClientType) { @@ -45,10 +48,13 @@ function createSandboxProxyHandler(nuxt: Nuxt, clientType: ShopifyClientType) { let client: ReturnType switch (clientType) { - case 'storefront': + case ShopifyClientType.Storefront: client = createClient(createStorefrontConfig(config)) break - case 'admin': + case ShopifyClientType.CustomerAccount: + client = createClient(createCustomerAccountConfig(config)) + break + case ShopifyClientType.Admin: client = createClient(createAdminConfig(config)) break default: @@ -64,12 +70,12 @@ function createSandboxProxyHandler(nuxt: Nuxt, clientType: ShopifyClientType) { export function registerSandbox(nuxt: Nuxt, clientType: ShopifyClientType): string { addDevServerHandler({ handler: createSandboxHandler(clientType), - route: `/_sandbox/${clientType}`, + route: `/_sandbox/${kebabCase(clientType)}`, }) addDevServerHandler({ handler: createSandboxProxyHandler(nuxt, clientType), - route: `/_sandbox/proxy/${clientType}`, + route: `/_sandbox/proxy/${kebabCase(clientType)}`, }) return getSandboxUrl(nuxt, clientType) diff --git a/src/utils/templates.ts b/src/utils/templates.ts index 4e9832e0..1351a20d 100644 --- a/src/utils/templates.ts +++ b/src/utils/templates.ts @@ -12,6 +12,7 @@ import { } from '@nuxt/kit' import defu from 'defu' import { minimatch } from 'minimatch' +import { kebabCase } from 'scule' import { createIntrospectionGenerator, @@ -57,7 +58,7 @@ export function registerTemplates( if (!clientConfig) return - const introspectionFilename = `schema/${clientType}.schema.json` + const introspectionFilename = `schema/${kebabCase(clientType)}.schema.json` const introspectionPath = join(nuxt.options.buildDir, introspectionFilename) const introspection = addTemplate({ @@ -73,7 +74,7 @@ export function registerTemplates( write: true, }) - const typesFilename = `types/${clientType}/${clientType}.types` + const typesFilename = `types/${kebabCase(clientType)}/${kebabCase(clientType)}.types` const types = addTypeTemplate({ filename: `${typesFilename}.d.ts`, getContents: createTypesGenerator(config), @@ -86,7 +87,7 @@ export function registerTemplates( }, }) - const operationsFilename = `types/${clientType}/${clientType}.operations` + const operationsFilename = `types/${kebabCase(clientType)}/${kebabCase(clientType)}.operations` const operations = addTypeTemplate({ filename: `${operationsFilename}.d.ts`, getContents: createOperationsGenerator(config), @@ -102,13 +103,13 @@ export function registerTemplates( setupWatcher(nuxt, operations) const index = addTypeTemplate({ - filename: `types/${clientType}/index.d.ts`, + filename: `types/${kebabCase(clientType)}/index.d.ts`, getContents: () => indexTemplate(types.filename, operations.filename).trimStart(), }) nuxt.options = defu(nuxt.options, { alias: { - [`#shopify/${clientType}`]: `./${dirname(index.filename)}`, + [`#shopify/${kebabCase(clientType)}`]: `./${dirname(index.filename)}`, }, nitro: { typescript: { diff --git a/template/nuxt.config.ts b/template/nuxt.config.ts index 1d0ca48a..369e057d 100644 --- a/template/nuxt.config.ts +++ b/template/nuxt.config.ts @@ -19,7 +19,7 @@ export default defineNuxtConfig({ '/blog/**': { isr: 3600 }, }, - compatibilityDate: '2026-03-10', + compatibilityDate: '2026-03-15', vite: { server: {