@shopify/hydrogen 2026.4.5 → 2026.10.0-preview.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +73 -13
- package/bin/hydrogen.mjs +7 -0
- package/dist/cli/index.mjs +647 -0
- package/dist/client/client.d.mts +34 -0
- package/dist/client/client.mjs +206 -0
- package/dist/client/client.mjs.map +1 -0
- package/dist/client/errors.d.mts +48 -0
- package/dist/client/errors.mjs +52 -0
- package/dist/client/errors.mjs.map +1 -0
- package/dist/client/index.d.mts +4 -0
- package/dist/client/types.d.mts +147 -0
- package/dist/core/analytics/cart-tracker.d.mts +8 -0
- package/dist/core/analytics/cart-tracker.mjs +144 -0
- package/dist/core/analytics/cart-tracker.mjs.map +1 -0
- package/dist/core/analytics/events.d.mts +15 -0
- package/dist/core/analytics/events.mjs +15 -0
- package/dist/core/analytics/events.mjs.map +1 -0
- package/dist/core/analytics/index.d.mts +3 -0
- package/dist/core/analytics/types.d.mts +143 -0
- package/dist/core/analytics/utils/flatten-connection.d.mts +19 -0
- package/dist/core/analytics/utils/flatten-connection.mjs +25 -0
- package/dist/core/analytics/utils/flatten-connection.mjs.map +1 -0
- package/dist/core/cache/cache-status.mjs +17 -0
- package/dist/core/cache/cache-status.mjs.map +1 -0
- package/dist/core/cache/fetch-with-cache.d.mts +43 -0
- package/dist/core/cache/fetch-with-cache.mjs +188 -0
- package/dist/core/cache/fetch-with-cache.mjs.map +1 -0
- package/dist/core/cache/key.d.mts +6 -0
- package/dist/core/cache/key.mjs +27 -0
- package/dist/core/cache/key.mjs.map +1 -0
- package/dist/core/cache/run-with-cache.d.mts +36 -0
- package/dist/core/cache/run-with-cache.mjs +114 -0
- package/dist/core/cache/run-with-cache.mjs.map +1 -0
- package/dist/core/cache/store.d.mts +19 -0
- package/dist/core/cache/store.mjs +62 -0
- package/dist/core/cache/store.mjs.map +1 -0
- package/dist/core/cache/strategies.d.mts +39 -0
- package/dist/core/cache/strategies.mjs +70 -0
- package/dist/core/cache/strategies.mjs.map +1 -0
- package/dist/core/cart/actions.d.mts +50 -0
- package/dist/core/cart/actions.mjs +240 -0
- package/dist/core/cart/actions.mjs.map +1 -0
- package/dist/core/cart/attach-quantity-input.d.mts +5 -0
- package/dist/core/cart/attach-quantity-input.mjs +17 -0
- package/dist/core/cart/attach-quantity-input.mjs.map +1 -0
- package/dist/core/cart/buyer-identity-sync.d.mts +23 -0
- package/dist/core/cart/buyer-identity-sync.mjs +9 -0
- package/dist/core/cart/buyer-identity-sync.mjs.map +1 -0
- package/dist/core/cart/cart.d.mts +37 -0
- package/dist/core/cart/cart.mjs +1707 -0
- package/dist/core/cart/cart.mjs.map +1 -0
- package/dist/core/cart/cookie.d.mts +5 -0
- package/dist/core/cart/cookie.mjs +28 -0
- package/dist/core/cart/cookie.mjs.map +1 -0
- package/dist/core/cart/form.d.mts +130 -0
- package/dist/core/cart/form.mjs +75 -0
- package/dist/core/cart/form.mjs.map +1 -0
- package/dist/core/cart/get-cart.d.mts +25 -0
- package/dist/core/cart/get-cart.mjs +32 -0
- package/dist/core/cart/get-cart.mjs.map +1 -0
- package/dist/core/cart/index.d.mts +10 -0
- package/dist/core/cart/quantity.d.mts +10 -0
- package/dist/core/cart/quantity.mjs +14 -0
- package/dist/core/cart/quantity.mjs.map +1 -0
- package/dist/core/cart/queries.d.mts +4296 -0
- package/dist/core/cart/queries.mjs +70 -0
- package/dist/core/cart/queries.mjs.map +1 -0
- package/dist/core/cart/server-handlers.d.mts +82 -0
- package/dist/core/cart/server-handlers.mjs +322 -0
- package/dist/core/cart/server-handlers.mjs.map +1 -0
- package/dist/core/cart/state.d.mts +137 -0
- package/dist/core/cart/state.mjs +76 -0
- package/dist/core/cart/state.mjs.map +1 -0
- package/dist/core/cart/sync-quantity-inputs.mjs +16 -0
- package/dist/core/cart/sync-quantity-inputs.mjs.map +1 -0
- package/dist/core/collection/collection.d.mts +134 -0
- package/dist/core/collection/collection.mjs +170 -0
- package/dist/core/collection/collection.mjs.map +1 -0
- package/dist/core/collection/index.d.mts +6 -0
- package/dist/core/collection/reconciler.d.mts +32 -0
- package/dist/core/collection/reconciler.mjs +89 -0
- package/dist/core/collection/reconciler.mjs.map +1 -0
- package/dist/core/collection/state.d.mts +66 -0
- package/dist/core/collection/state.mjs +20 -0
- package/dist/core/collection/state.mjs.map +1 -0
- package/dist/core/collection/url.d.mts +71 -0
- package/dist/core/collection/url.mjs +376 -0
- package/dist/core/collection/url.mjs.map +1 -0
- package/dist/core/constants.d.mts +5 -0
- package/dist/core/constants.mjs +8 -0
- package/dist/core/constants.mjs.map +1 -0
- package/dist/core/headers.mjs +43 -0
- package/dist/core/headers.mjs.map +1 -0
- package/dist/core/index.d.mts +56 -0
- package/dist/core/index.mjs +45 -0
- package/dist/core/logging/logging.d.mts +21 -0
- package/dist/core/logging/logging.mjs +99 -0
- package/dist/core/logging/logging.mjs.map +1 -0
- package/dist/core/logging/types.d.mts +40 -0
- package/dist/core/logging/types.mjs +18 -0
- package/dist/core/logging/types.mjs.map +1 -0
- package/dist/core/money/cache.mjs +25 -0
- package/dist/core/money/cache.mjs.map +1 -0
- package/dist/core/money/format.d.mts +15 -0
- package/dist/core/money/format.mjs +243 -0
- package/dist/core/money/format.mjs.map +1 -0
- package/dist/core/money/types.d.mts +47 -0
- package/dist/core/observable.mjs +46 -0
- package/dist/core/observable.mjs.map +1 -0
- package/dist/core/predictive-search/constants.d.mts +5 -0
- package/dist/core/predictive-search/constants.mjs +6 -0
- package/dist/core/predictive-search/constants.mjs.map +1 -0
- package/dist/core/predictive-search/form.d.mts +31 -0
- package/dist/core/predictive-search/form.mjs +31 -0
- package/dist/core/predictive-search/form.mjs.map +1 -0
- package/dist/core/predictive-search/index.d.mts +6 -0
- package/dist/core/predictive-search/queries.d.mts +118 -0
- package/dist/core/predictive-search/queries.mjs +81 -0
- package/dist/core/predictive-search/queries.mjs.map +1 -0
- package/dist/core/predictive-search/search.d.mts +32 -0
- package/dist/core/predictive-search/search.mjs +74 -0
- package/dist/core/predictive-search/search.mjs.map +1 -0
- package/dist/core/predictive-search/server-handlers.d.mts +36 -0
- package/dist/core/predictive-search/server-handlers.mjs +113 -0
- package/dist/core/predictive-search/server-handlers.mjs.map +1 -0
- package/dist/core/predictive-search/store.d.mts +44 -0
- package/dist/core/predictive-search/store.mjs +224 -0
- package/dist/core/predictive-search/store.mjs.map +1 -0
- package/dist/core/predictive-search/url.d.mts +41 -0
- package/dist/core/predictive-search/url.mjs +71 -0
- package/dist/core/predictive-search/url.mjs.map +1 -0
- package/dist/core/product/accept-variant-id.mjs +98 -0
- package/dist/core/product/accept-variant-id.mjs.map +1 -0
- package/dist/core/product/form.d.mts +63 -0
- package/dist/core/product/form.mjs +44 -0
- package/dist/core/product/form.mjs.map +1 -0
- package/dist/core/product/index.d.mts +5 -0
- package/dist/core/product/options.d.mts +43 -0
- package/dist/core/product/options.mjs +296 -0
- package/dist/core/product/options.mjs.map +1 -0
- package/dist/core/product/product-form.d.mts +72 -0
- package/dist/core/product/product-form.mjs +158 -0
- package/dist/core/product/product-form.mjs.map +1 -0
- package/dist/core/product/state.d.mts +68 -0
- package/dist/core/product/url.d.mts +47 -0
- package/dist/core/product/url.mjs +69 -0
- package/dist/core/product/url.mjs.map +1 -0
- package/dist/core/request-context.d.mts +75 -0
- package/dist/core/request-context.mjs +141 -0
- package/dist/core/request-context.mjs.map +1 -0
- package/dist/core/request-routing/handle-shopify-redirects.d.mts +17 -0
- package/dist/core/request-routing/handle-shopify-redirects.mjs +31 -0
- package/dist/core/request-routing/handle-shopify-redirects.mjs.map +1 -0
- package/dist/core/request-routing/handle-shopify-routes.d.mts +14 -0
- package/dist/core/request-routing/handle-shopify-routes.mjs +42 -0
- package/dist/core/request-routing/handle-shopify-routes.mjs.map +1 -0
- package/dist/core/request-routing/interceptors/admin-redirect.mjs +12 -0
- package/dist/core/request-routing/interceptors/admin-redirect.mjs.map +1 -0
- package/dist/core/request-routing/interceptors/ajax-api.mjs +16 -0
- package/dist/core/request-routing/interceptors/ajax-api.mjs.map +1 -0
- package/dist/core/request-routing/interceptors/api-proxy.mjs +20 -0
- package/dist/core/request-routing/interceptors/api-proxy.mjs.map +1 -0
- package/dist/core/request-routing/interceptors/checkout.mjs +58 -0
- package/dist/core/request-routing/interceptors/checkout.mjs.map +1 -0
- package/dist/core/request-routing/interceptors/mcp-proxy.mjs +23 -0
- package/dist/core/request-routing/interceptors/mcp-proxy.mjs.map +1 -0
- package/dist/core/request-routing/interceptors/proxy.mjs +73 -0
- package/dist/core/request-routing/interceptors/proxy.mjs.map +1 -0
- package/dist/core/request-routing/interceptors/query-param-redirect.mjs +22 -0
- package/dist/core/request-routing/interceptors/query-param-redirect.mjs.map +1 -0
- package/dist/core/request-routing/interceptors/sfapi-proxy.mjs +27 -0
- package/dist/core/request-routing/interceptors/sfapi-proxy.mjs.map +1 -0
- package/dist/core/request-routing/interceptors/standard-routes.mjs +19 -0
- package/dist/core/request-routing/interceptors/standard-routes.mjs.map +1 -0
- package/dist/core/request-routing/interceptors/url-redirects.mjs +27 -0
- package/dist/core/request-routing/interceptors/url-redirects.mjs.map +1 -0
- package/dist/core/request-routing/interceptors/well-known.mjs +22 -0
- package/dist/core/request-routing/interceptors/well-known.mjs.map +1 -0
- package/dist/core/request-routing/registered-routes.d.mts +7 -0
- package/dist/core/request-routing/registered-routes.mjs +72 -0
- package/dist/core/request-routing/registered-routes.mjs.map +1 -0
- package/dist/core/request-routing/route-types.d.mts +56 -0
- package/dist/core/request-routing/safe-apply-response-headers.mjs +16 -0
- package/dist/core/request-routing/safe-apply-response-headers.mjs.map +1 -0
- package/dist/core/shop-pay/shop-pay.d.mts +102 -0
- package/dist/core/shop-pay/shop-pay.mjs +289 -0
- package/dist/core/shop-pay/shop-pay.mjs.map +1 -0
- package/dist/core/shopify-scripts/analytics.mjs +26 -0
- package/dist/core/shopify-scripts/analytics.mjs.map +1 -0
- package/dist/core/shopify-scripts/consent.mjs +17 -0
- package/dist/core/shopify-scripts/consent.mjs.map +1 -0
- package/dist/core/shopify-scripts/constants.mjs +19 -0
- package/dist/core/shopify-scripts/constants.mjs.map +1 -0
- package/dist/core/shopify-scripts/deprecated-cookies.mjs +97 -0
- package/dist/core/shopify-scripts/deprecated-cookies.mjs.map +1 -0
- package/dist/core/shopify-scripts/global.d.mts +1 -0
- package/dist/core/shopify-scripts/global.mjs +86 -0
- package/dist/core/shopify-scripts/global.mjs.map +1 -0
- package/dist/core/shopify-scripts/index.d.mts +27 -0
- package/dist/core/shopify-scripts/index.mjs +135 -0
- package/dist/core/shopify-scripts/index.mjs.map +1 -0
- package/dist/core/shopify-scripts/initialize.d.mts +18 -0
- package/dist/core/shopify-scripts/initialize.mjs +27 -0
- package/dist/core/shopify-scripts/initialize.mjs.map +1 -0
- package/dist/core/shopify-scripts/page-view.mjs +49 -0
- package/dist/core/shopify-scripts/page-view.mjs.map +1 -0
- package/dist/core/shopify-scripts/perfkit.mjs +33 -0
- package/dist/core/shopify-scripts/perfkit.mjs.map +1 -0
- package/dist/core/shopify-scripts/render.d.mts +1 -0
- package/dist/core/shopify-scripts/render.mjs +23 -0
- package/dist/core/shopify-scripts/render.mjs.map +1 -0
- package/dist/core/shopify-scripts/types.d.mts +76 -0
- package/dist/core/shopify-scripts/utils/cookie-domain.mjs +43 -0
- package/dist/core/shopify-scripts/utils/cookie-domain.mjs.map +1 -0
- package/dist/core/shopify-scripts/utils/inline-script.mjs +8 -0
- package/dist/core/shopify-scripts/utils/inline-script.mjs.map +1 -0
- package/dist/core/shopify-scripts/utils/navigation.mjs +46 -0
- package/dist/core/shopify-scripts/utils/navigation.mjs.map +1 -0
- package/dist/core/shopify-scripts/utils/tracking-values.mjs +65 -0
- package/dist/core/shopify-scripts/utils/tracking-values.mjs.map +1 -0
- package/dist/core/shopify-scripts/utils/uuid.mjs +17 -0
- package/dist/core/shopify-scripts/utils/uuid.mjs.map +1 -0
- package/dist/core/shopify-scripts/webmcp.mjs +22 -0
- package/dist/core/shopify-scripts/webmcp.mjs.map +1 -0
- package/dist/core/standard-routes/build.d.mts +34 -0
- package/dist/core/standard-routes/build.mjs +54 -0
- package/dist/core/standard-routes/build.mjs.map +1 -0
- package/dist/core/standard-routes/defaults.mjs +31 -0
- package/dist/core/standard-routes/defaults.mjs.map +1 -0
- package/dist/core/standard-routes/match.mjs +108 -0
- package/dist/core/standard-routes/match.mjs.map +1 -0
- package/dist/core/standard-routes/path.mjs +58 -0
- package/dist/core/standard-routes/path.mjs.map +1 -0
- package/dist/core/standard-routes/redirects.mjs +51 -0
- package/dist/core/standard-routes/redirects.mjs.map +1 -0
- package/dist/core/standard-routes/types.d.mts +95 -0
- package/dist/core/url.mjs +42 -0
- package/dist/core/url.mjs.map +1 -0
- package/dist/core/utils/load-script.mjs +34 -0
- package/dist/core/utils/load-script.mjs.map +1 -0
- package/dist/core/utils/parse-gid.mjs +33 -0
- package/dist/core/utils/parse-gid.mjs.map +1 -0
- package/dist/core/utils/record.mjs +8 -0
- package/dist/core/utils/record.mjs.map +1 -0
- package/dist/customer-account/client.d.mts +50 -0
- package/dist/customer-account/client.mjs +239 -0
- package/dist/customer-account/client.mjs.map +1 -0
- package/dist/customer-account/errors.d.mts +28 -0
- package/dist/customer-account/errors.mjs +39 -0
- package/dist/customer-account/errors.mjs.map +1 -0
- package/dist/customer-account/graphql.d.mts +29 -0
- package/dist/customer-account/graphql.mjs +39 -0
- package/dist/customer-account/graphql.mjs.map +1 -0
- package/dist/customer-account/index.d.mts +7 -0
- package/dist/customer-account/index.mjs +7 -0
- package/dist/customer-account/session.d.mts +117 -0
- package/dist/customer-account/session.mjs +733 -0
- package/dist/customer-account/session.mjs.map +1 -0
- package/dist/customer-account/type-resolver.d.mts +11 -0
- package/dist/customer-account-api-types.d.ts +3269 -3270
- package/dist/customer-account.schema.json +50753 -1
- package/dist/development/_virtual/_@oxc-project_runtime@0.127.0/helpers/taggedTemplateLiteral.mjs +7 -0
- package/dist/development/client/client.d.mts +34 -0
- package/dist/development/client/client.mjs +206 -0
- package/dist/development/client/client.mjs.map +1 -0
- package/dist/development/client/errors.d.mts +48 -0
- package/dist/development/client/errors.mjs +57 -0
- package/dist/development/client/errors.mjs.map +1 -0
- package/dist/development/client/index.d.mts +4 -0
- package/dist/development/client/types.d.mts +147 -0
- package/dist/development/core/analytics/cart-tracker.d.mts +8 -0
- package/dist/development/core/analytics/cart-tracker.mjs +144 -0
- package/dist/development/core/analytics/cart-tracker.mjs.map +1 -0
- package/dist/development/core/analytics/events.d.mts +15 -0
- package/dist/development/core/analytics/events.mjs +15 -0
- package/dist/development/core/analytics/events.mjs.map +1 -0
- package/dist/development/core/analytics/index.d.mts +3 -0
- package/dist/development/core/analytics/types.d.mts +143 -0
- package/dist/development/core/analytics/utils/flatten-connection.d.mts +19 -0
- package/dist/development/core/analytics/utils/flatten-connection.mjs +25 -0
- package/dist/development/core/analytics/utils/flatten-connection.mjs.map +1 -0
- package/dist/development/core/cache/cache-status.mjs +17 -0
- package/dist/development/core/cache/cache-status.mjs.map +1 -0
- package/dist/development/core/cache/fetch-with-cache.d.mts +43 -0
- package/dist/development/core/cache/fetch-with-cache.mjs +188 -0
- package/dist/development/core/cache/fetch-with-cache.mjs.map +1 -0
- package/dist/development/core/cache/key.d.mts +6 -0
- package/dist/development/core/cache/key.mjs +27 -0
- package/dist/development/core/cache/key.mjs.map +1 -0
- package/dist/development/core/cache/run-with-cache.d.mts +36 -0
- package/dist/development/core/cache/run-with-cache.mjs +114 -0
- package/dist/development/core/cache/run-with-cache.mjs.map +1 -0
- package/dist/development/core/cache/store.d.mts +19 -0
- package/dist/development/core/cache/store.mjs +62 -0
- package/dist/development/core/cache/store.mjs.map +1 -0
- package/dist/development/core/cache/strategies.d.mts +39 -0
- package/dist/development/core/cache/strategies.mjs +70 -0
- package/dist/development/core/cache/strategies.mjs.map +1 -0
- package/dist/development/core/cart/actions.d.mts +50 -0
- package/dist/development/core/cart/actions.mjs +240 -0
- package/dist/development/core/cart/actions.mjs.map +1 -0
- package/dist/development/core/cart/attach-quantity-input.d.mts +5 -0
- package/dist/development/core/cart/attach-quantity-input.mjs +17 -0
- package/dist/development/core/cart/attach-quantity-input.mjs.map +1 -0
- package/dist/development/core/cart/buyer-identity-sync.d.mts +19 -0
- package/dist/development/core/cart/buyer-identity-sync.mjs +6 -0
- package/dist/development/core/cart/buyer-identity-sync.mjs.map +1 -0
- package/dist/development/core/cart/cart.d.mts +37 -0
- package/dist/development/core/cart/cart.mjs +1707 -0
- package/dist/development/core/cart/cart.mjs.map +1 -0
- package/dist/development/core/cart/cookie.d.mts +5 -0
- package/dist/development/core/cart/cookie.mjs +28 -0
- package/dist/development/core/cart/cookie.mjs.map +1 -0
- package/dist/development/core/cart/form.d.mts +130 -0
- package/dist/development/core/cart/form.mjs +75 -0
- package/dist/development/core/cart/form.mjs.map +1 -0
- package/dist/development/core/cart/get-cart.d.mts +25 -0
- package/dist/development/core/cart/get-cart.mjs +32 -0
- package/dist/development/core/cart/get-cart.mjs.map +1 -0
- package/dist/development/core/cart/index.d.mts +10 -0
- package/dist/development/core/cart/quantity.d.mts +10 -0
- package/dist/development/core/cart/quantity.mjs +14 -0
- package/dist/development/core/cart/quantity.mjs.map +1 -0
- package/dist/development/core/cart/queries.d.mts +4296 -0
- package/dist/development/core/cart/queries.mjs +70 -0
- package/dist/development/core/cart/queries.mjs.map +1 -0
- package/dist/development/core/cart/server-handlers.d.mts +82 -0
- package/dist/development/core/cart/server-handlers.mjs +322 -0
- package/dist/development/core/cart/server-handlers.mjs.map +1 -0
- package/dist/development/core/cart/state.d.mts +137 -0
- package/dist/development/core/cart/state.mjs +76 -0
- package/dist/development/core/cart/state.mjs.map +1 -0
- package/dist/development/core/cart/sync-quantity-inputs.mjs +16 -0
- package/dist/development/core/cart/sync-quantity-inputs.mjs.map +1 -0
- package/dist/development/core/collection/collection.d.mts +134 -0
- package/dist/development/core/collection/collection.mjs +170 -0
- package/dist/development/core/collection/collection.mjs.map +1 -0
- package/dist/development/core/collection/index.d.mts +6 -0
- package/dist/development/core/collection/reconciler.d.mts +32 -0
- package/dist/development/core/collection/reconciler.mjs +89 -0
- package/dist/development/core/collection/reconciler.mjs.map +1 -0
- package/dist/development/core/collection/state.d.mts +66 -0
- package/dist/development/core/collection/state.mjs +20 -0
- package/dist/development/core/collection/state.mjs.map +1 -0
- package/dist/development/core/collection/url.d.mts +71 -0
- package/dist/development/core/collection/url.mjs +376 -0
- package/dist/development/core/collection/url.mjs.map +1 -0
- package/dist/development/core/constants.mjs +7 -0
- package/dist/development/core/constants.mjs.map +1 -0
- package/dist/development/core/development.d.mts +56 -0
- package/dist/development/core/development.mjs +45 -0
- package/dist/development/core/headers.mjs +43 -0
- package/dist/development/core/headers.mjs.map +1 -0
- package/dist/development/core/index.d.mts +54 -0
- package/dist/development/core/logging/logging.d.mts +21 -0
- package/dist/development/core/logging/logging.mjs +99 -0
- package/dist/development/core/logging/logging.mjs.map +1 -0
- package/dist/development/core/logging/types.d.mts +40 -0
- package/dist/development/core/logging/types.mjs +18 -0
- package/dist/development/core/logging/types.mjs.map +1 -0
- package/dist/development/core/money/cache.mjs +25 -0
- package/dist/development/core/money/cache.mjs.map +1 -0
- package/dist/development/core/money/format.d.mts +15 -0
- package/dist/development/core/money/format.mjs +243 -0
- package/dist/development/core/money/format.mjs.map +1 -0
- package/dist/development/core/money/types.d.mts +47 -0
- package/dist/development/core/observable.mjs +46 -0
- package/dist/development/core/observable.mjs.map +1 -0
- package/dist/development/core/predictive-search/constants.d.mts +5 -0
- package/dist/development/core/predictive-search/constants.mjs +6 -0
- package/dist/development/core/predictive-search/constants.mjs.map +1 -0
- package/dist/development/core/predictive-search/form.d.mts +31 -0
- package/dist/development/core/predictive-search/form.mjs +31 -0
- package/dist/development/core/predictive-search/form.mjs.map +1 -0
- package/dist/development/core/predictive-search/index.d.mts +6 -0
- package/dist/development/core/predictive-search/queries.d.mts +118 -0
- package/dist/development/core/predictive-search/queries.mjs +81 -0
- package/dist/development/core/predictive-search/queries.mjs.map +1 -0
- package/dist/development/core/predictive-search/search.d.mts +32 -0
- package/dist/development/core/predictive-search/search.mjs +74 -0
- package/dist/development/core/predictive-search/search.mjs.map +1 -0
- package/dist/development/core/predictive-search/server-handlers.d.mts +36 -0
- package/dist/development/core/predictive-search/server-handlers.mjs +113 -0
- package/dist/development/core/predictive-search/server-handlers.mjs.map +1 -0
- package/dist/development/core/predictive-search/store.d.mts +44 -0
- package/dist/development/core/predictive-search/store.mjs +224 -0
- package/dist/development/core/predictive-search/store.mjs.map +1 -0
- package/dist/development/core/predictive-search/url.d.mts +41 -0
- package/dist/development/core/predictive-search/url.mjs +71 -0
- package/dist/development/core/predictive-search/url.mjs.map +1 -0
- package/dist/development/core/product/accept-variant-id.mjs +98 -0
- package/dist/development/core/product/accept-variant-id.mjs.map +1 -0
- package/dist/development/core/product/form.d.mts +63 -0
- package/dist/development/core/product/form.mjs +44 -0
- package/dist/development/core/product/form.mjs.map +1 -0
- package/dist/development/core/product/index.d.mts +5 -0
- package/dist/development/core/product/options.d.mts +43 -0
- package/dist/development/core/product/options.mjs +296 -0
- package/dist/development/core/product/options.mjs.map +1 -0
- package/dist/development/core/product/product-form.d.mts +72 -0
- package/dist/development/core/product/product-form.mjs +158 -0
- package/dist/development/core/product/product-form.mjs.map +1 -0
- package/dist/development/core/product/state.d.mts +68 -0
- package/dist/development/core/product/url.d.mts +47 -0
- package/dist/development/core/product/url.mjs +69 -0
- package/dist/development/core/product/url.mjs.map +1 -0
- package/dist/development/core/request-context.d.mts +75 -0
- package/dist/development/core/request-context.mjs +141 -0
- package/dist/development/core/request-context.mjs.map +1 -0
- package/dist/development/core/request-routing/handle-shopify-redirects.d.mts +17 -0
- package/dist/development/core/request-routing/handle-shopify-redirects.mjs +31 -0
- package/dist/development/core/request-routing/handle-shopify-redirects.mjs.map +1 -0
- package/dist/development/core/request-routing/handle-shopify-routes.d.mts +1 -0
- package/dist/development/core/request-routing/handle-shopify-routes.development.d.mts +11 -0
- package/dist/development/core/request-routing/handle-shopify-routes.development.mjs +16 -0
- package/dist/development/core/request-routing/handle-shopify-routes.development.mjs.map +1 -0
- package/dist/development/core/request-routing/handle-shopify-routes.mjs +42 -0
- package/dist/development/core/request-routing/handle-shopify-routes.mjs.map +1 -0
- package/dist/development/core/request-routing/interceptors/admin-redirect.mjs +12 -0
- package/dist/development/core/request-routing/interceptors/admin-redirect.mjs.map +1 -0
- package/dist/development/core/request-routing/interceptors/ajax-api.mjs +16 -0
- package/dist/development/core/request-routing/interceptors/ajax-api.mjs.map +1 -0
- package/dist/development/core/request-routing/interceptors/api-proxy.mjs +20 -0
- package/dist/development/core/request-routing/interceptors/api-proxy.mjs.map +1 -0
- package/dist/development/core/request-routing/interceptors/checkout.mjs +58 -0
- package/dist/development/core/request-routing/interceptors/checkout.mjs.map +1 -0
- package/dist/development/core/request-routing/interceptors/graphiql.mjs +46 -0
- package/dist/development/core/request-routing/interceptors/graphiql.mjs.map +1 -0
- package/dist/development/core/request-routing/interceptors/mcp-proxy.mjs +23 -0
- package/dist/development/core/request-routing/interceptors/mcp-proxy.mjs.map +1 -0
- package/dist/development/core/request-routing/interceptors/proxy.mjs +73 -0
- package/dist/development/core/request-routing/interceptors/proxy.mjs.map +1 -0
- package/dist/development/core/request-routing/interceptors/query-param-redirect.mjs +22 -0
- package/dist/development/core/request-routing/interceptors/query-param-redirect.mjs.map +1 -0
- package/dist/development/core/request-routing/interceptors/sfapi-proxy.mjs +27 -0
- package/dist/development/core/request-routing/interceptors/sfapi-proxy.mjs.map +1 -0
- package/dist/development/core/request-routing/interceptors/standard-routes.mjs +19 -0
- package/dist/development/core/request-routing/interceptors/standard-routes.mjs.map +1 -0
- package/dist/development/core/request-routing/interceptors/url-redirects.mjs +27 -0
- package/dist/development/core/request-routing/interceptors/url-redirects.mjs.map +1 -0
- package/dist/development/core/request-routing/interceptors/well-known.mjs +22 -0
- package/dist/development/core/request-routing/interceptors/well-known.mjs.map +1 -0
- package/dist/development/core/request-routing/registered-routes.d.mts +7 -0
- package/dist/development/core/request-routing/registered-routes.mjs +72 -0
- package/dist/development/core/request-routing/registered-routes.mjs.map +1 -0
- package/dist/development/core/request-routing/route-types.d.mts +56 -0
- package/dist/development/core/request-routing/safe-apply-response-headers.mjs +16 -0
- package/dist/development/core/request-routing/safe-apply-response-headers.mjs.map +1 -0
- package/dist/development/core/shop-pay/shop-pay.d.mts +102 -0
- package/dist/development/core/shop-pay/shop-pay.mjs +289 -0
- package/dist/development/core/shop-pay/shop-pay.mjs.map +1 -0
- package/dist/development/core/shopify-scripts/analytics.mjs +26 -0
- package/dist/development/core/shopify-scripts/analytics.mjs.map +1 -0
- package/dist/development/core/shopify-scripts/consent.mjs +17 -0
- package/dist/development/core/shopify-scripts/consent.mjs.map +1 -0
- package/dist/development/core/shopify-scripts/constants.mjs +19 -0
- package/dist/development/core/shopify-scripts/constants.mjs.map +1 -0
- package/dist/development/core/shopify-scripts/deprecated-cookies.mjs +97 -0
- package/dist/development/core/shopify-scripts/deprecated-cookies.mjs.map +1 -0
- package/dist/development/core/shopify-scripts/global.d.mts +1 -0
- package/dist/development/core/shopify-scripts/global.mjs +86 -0
- package/dist/development/core/shopify-scripts/global.mjs.map +1 -0
- package/dist/development/core/shopify-scripts/index.d.mts +27 -0
- package/dist/development/core/shopify-scripts/index.mjs +145 -0
- package/dist/development/core/shopify-scripts/index.mjs.map +1 -0
- package/dist/development/core/shopify-scripts/initialize.d.mts +18 -0
- package/dist/development/core/shopify-scripts/initialize.mjs +27 -0
- package/dist/development/core/shopify-scripts/initialize.mjs.map +1 -0
- package/dist/development/core/shopify-scripts/page-view.mjs +49 -0
- package/dist/development/core/shopify-scripts/page-view.mjs.map +1 -0
- package/dist/development/core/shopify-scripts/perfkit.mjs +33 -0
- package/dist/development/core/shopify-scripts/perfkit.mjs.map +1 -0
- package/dist/development/core/shopify-scripts/render.d.mts +1 -0
- package/dist/development/core/shopify-scripts/render.mjs +23 -0
- package/dist/development/core/shopify-scripts/render.mjs.map +1 -0
- package/dist/development/core/shopify-scripts/types.d.mts +76 -0
- package/dist/development/core/shopify-scripts/utils/cookie-domain.mjs +43 -0
- package/dist/development/core/shopify-scripts/utils/cookie-domain.mjs.map +1 -0
- package/dist/development/core/shopify-scripts/utils/inline-script.mjs +8 -0
- package/dist/development/core/shopify-scripts/utils/inline-script.mjs.map +1 -0
- package/dist/development/core/shopify-scripts/utils/navigation.mjs +46 -0
- package/dist/development/core/shopify-scripts/utils/navigation.mjs.map +1 -0
- package/dist/development/core/shopify-scripts/utils/tracking-values.mjs +65 -0
- package/dist/development/core/shopify-scripts/utils/tracking-values.mjs.map +1 -0
- package/dist/development/core/shopify-scripts/utils/uuid.mjs +17 -0
- package/dist/development/core/shopify-scripts/utils/uuid.mjs.map +1 -0
- package/dist/development/core/shopify-scripts/webmcp.mjs +22 -0
- package/dist/development/core/shopify-scripts/webmcp.mjs.map +1 -0
- package/dist/development/core/standard-routes/build.d.mts +34 -0
- package/dist/development/core/standard-routes/build.mjs +54 -0
- package/dist/development/core/standard-routes/build.mjs.map +1 -0
- package/dist/development/core/standard-routes/defaults.mjs +31 -0
- package/dist/development/core/standard-routes/defaults.mjs.map +1 -0
- package/dist/development/core/standard-routes/match.mjs +108 -0
- package/dist/development/core/standard-routes/match.mjs.map +1 -0
- package/dist/development/core/standard-routes/path.mjs +58 -0
- package/dist/development/core/standard-routes/path.mjs.map +1 -0
- package/dist/development/core/standard-routes/redirects.mjs +51 -0
- package/dist/development/core/standard-routes/redirects.mjs.map +1 -0
- package/dist/development/core/standard-routes/types.d.mts +95 -0
- package/dist/development/core/types.d.mts +11 -0
- package/dist/development/core/url.mjs +42 -0
- package/dist/development/core/url.mjs.map +1 -0
- package/dist/development/core/utils/load-script.mjs +34 -0
- package/dist/development/core/utils/load-script.mjs.map +1 -0
- package/dist/development/core/utils/parse-gid.mjs +33 -0
- package/dist/development/core/utils/parse-gid.mjs.map +1 -0
- package/dist/development/customer-account/session.d.mts +46 -0
- package/dist/development/customer-account/session.mjs +21 -0
- package/dist/development/customer-account/session.mjs.map +1 -0
- package/dist/development/globals.d.mts +64 -0
- package/dist/development/graphql/generated/customer-account-api-types.d.mts +13 -0
- package/dist/development/graphql/generated/graphql-env.d.mts +19280 -0
- package/dist/development/graphql/generated/storefront-api-types.d.mts +47 -0
- package/dist/development/graphql/graphql.d.mts +40 -0
- package/dist/development/graphql/graphql.mjs +16 -0
- package/dist/development/graphql/graphql.mjs.map +1 -0
- package/dist/development/graphql/index.d.mts +2 -0
- package/dist/development/graphql/scalars.d.mts +15 -0
- package/dist/development/graphql/type-resolver.d.mts +229 -0
- package/dist/development/react/cart.d.mts +44 -0
- package/dist/development/react/cart.mjs +155 -0
- package/dist/development/react/cart.mjs.map +1 -0
- package/dist/development/react/collection.d.mts +91 -0
- package/dist/development/react/collection.mjs +129 -0
- package/dist/development/react/collection.mjs.map +1 -0
- package/dist/development/react/index.d.mts +13 -0
- package/dist/development/react/index.mjs +10 -0
- package/dist/development/react/predictive-search.d.mts +49 -0
- package/dist/development/react/predictive-search.mjs +133 -0
- package/dist/development/react/predictive-search.mjs.map +1 -0
- package/dist/development/react/product.d.mts +72 -0
- package/dist/development/react/product.mjs +127 -0
- package/dist/development/react/product.mjs.map +1 -0
- package/dist/development/react/shop-pay.d.mts +9 -0
- package/dist/development/react/shop-pay.mjs +16 -0
- package/dist/development/react/shop-pay.mjs.map +1 -0
- package/dist/development/react/shopify-scripts.d.mts +20 -0
- package/dist/development/react/shopify-scripts.mjs +39 -0
- package/dist/development/react/shopify-scripts.mjs.map +1 -0
- package/dist/development/vendor/standard-actions.d.mts +134 -0
- package/dist/development/vendor/standard-events.d.mts +1107 -0
- package/dist/development/vue/cart.d.mts +46 -0
- package/dist/development/vue/cart.mjs +122 -0
- package/dist/development/vue/cart.mjs.map +1 -0
- package/dist/development/vue/collection.d.mts +46 -0
- package/dist/development/vue/collection.mjs +108 -0
- package/dist/development/vue/collection.mjs.map +1 -0
- package/dist/development/vue/index.d.mts +11 -0
- package/dist/development/vue/index.mjs +8 -0
- package/dist/development/vue/predictive-search.d.mts +124 -0
- package/dist/development/vue/predictive-search.mjs +171 -0
- package/dist/development/vue/predictive-search.mjs.map +1 -0
- package/dist/development/vue/product.d.mts +57 -0
- package/dist/development/vue/product.mjs +167 -0
- package/dist/development/vue/product.mjs.map +1 -0
- package/dist/development/vue/shop-pay.d.mts +25 -0
- package/dist/development/vue/shop-pay.mjs +35 -0
- package/dist/development/vue/shop-pay.mjs.map +1 -0
- package/dist/development/vue/shopify-scripts.d.mts +127 -0
- package/dist/development/vue/shopify-scripts.mjs +79 -0
- package/dist/development/vue/shopify-scripts.mjs.map +1 -0
- package/dist/globals.d.mts +64 -0
- package/dist/graphql/generated/customer-account-api-types.d.mts +13 -0
- package/dist/graphql/generated/customer-account-graphql-env.d.mts +22170 -0
- package/dist/graphql/generated/graphql-env.d.mts +19280 -0
- package/dist/graphql/generated/storefront-api-types.d.mts +47 -0
- package/dist/graphql/graphql.d.mts +40 -0
- package/dist/graphql/graphql.mjs +16 -0
- package/dist/graphql/graphql.mjs.map +1 -0
- package/dist/graphql/index.d.mts +2 -0
- package/dist/graphql/scalars.d.mts +26 -0
- package/dist/graphql/type-resolver.d.mts +229 -0
- package/dist/react/cart.d.mts +44 -0
- package/dist/react/cart.mjs +155 -0
- package/dist/react/cart.mjs.map +1 -0
- package/dist/react/collection.d.mts +91 -0
- package/dist/react/collection.mjs +129 -0
- package/dist/react/collection.mjs.map +1 -0
- package/dist/react/index.d.mts +13 -0
- package/dist/react/index.mjs +10 -0
- package/dist/react/predictive-search.d.mts +49 -0
- package/dist/react/predictive-search.mjs +133 -0
- package/dist/react/predictive-search.mjs.map +1 -0
- package/dist/react/product.d.mts +72 -0
- package/dist/react/product.mjs +127 -0
- package/dist/react/product.mjs.map +1 -0
- package/dist/react/shop-pay.d.mts +9 -0
- package/dist/react/shop-pay.mjs +16 -0
- package/dist/react/shop-pay.mjs.map +1 -0
- package/dist/react/shopify-scripts.d.mts +20 -0
- package/dist/react/shopify-scripts.mjs +39 -0
- package/dist/react/shopify-scripts.mjs.map +1 -0
- package/dist/storefront-api-types.d.ts +2351 -2390
- package/dist/storefront.schema.json +41534 -1
- package/dist/ts-plugin/index.cjs +68 -0
- package/dist/ts-plugin/index.cjs.map +1 -0
- package/dist/ts-plugin/index.d.cts +4 -0
- package/dist/vendor/standard-actions.d.mts +134 -0
- package/dist/vendor/standard-events.d.mts +1107 -0
- package/dist/vite/certificate-prompt.mjs +24 -0
- package/dist/vite/certificate-prompt.mjs.map +1 -0
- package/dist/vite/index.d.mts +2 -0
- package/dist/vite/index.mjs +3 -0
- package/dist/vite/local-https.d.mts +47 -0
- package/dist/vite/local-https.mjs +276 -0
- package/dist/vite/local-https.mjs.map +1 -0
- package/dist/vite/mkcert.mjs +141 -0
- package/dist/vite/mkcert.mjs.map +1 -0
- package/dist/vue/cart.d.mts +46 -0
- package/dist/vue/cart.mjs +122 -0
- package/dist/vue/cart.mjs.map +1 -0
- package/dist/vue/collection.d.mts +46 -0
- package/dist/vue/collection.mjs +108 -0
- package/dist/vue/collection.mjs.map +1 -0
- package/dist/vue/index.d.mts +11 -0
- package/dist/vue/index.mjs +8 -0
- package/dist/vue/predictive-search.d.mts +124 -0
- package/dist/vue/predictive-search.mjs +171 -0
- package/dist/vue/predictive-search.mjs.map +1 -0
- package/dist/vue/product.d.mts +57 -0
- package/dist/vue/product.mjs +167 -0
- package/dist/vue/product.mjs.map +1 -0
- package/dist/vue/shop-pay.d.mts +25 -0
- package/dist/vue/shop-pay.mjs +35 -0
- package/dist/vue/shop-pay.mjs.map +1 -0
- package/dist/vue/shopify-scripts.d.mts +127 -0
- package/dist/vue/shopify-scripts.mjs +79 -0
- package/dist/vue/shopify-scripts.mjs.map +1 -0
- package/package.json +116 -86
- package/skills/hydrogen-analytics/SKILL.md +80 -0
- package/skills/hydrogen-analytics/references/react.md +160 -0
- package/skills/hydrogen-analytics/references/vue.md +80 -0
- package/skills/hydrogen-cart-drawer/SKILL.md +248 -0
- package/skills/hydrogen-cart-drawer/references/accessibility.md +109 -0
- package/skills/hydrogen-cart-drawer/references/css.md +67 -0
- package/skills/hydrogen-cart-ui/SKILL.md +224 -0
- package/skills/hydrogen-cart-ui/references/nextjs.md +89 -0
- package/skills/hydrogen-cart-ui/references/react.md +285 -0
- package/skills/hydrogen-cart-ui/references/vue.md +228 -0
- package/skills/hydrogen-collection-browser/SKILL.md +83 -0
- package/skills/hydrogen-collection-browser/references/nextjs.md +118 -0
- package/skills/hydrogen-collection-browser/references/nuxt.md +108 -0
- package/skills/hydrogen-collection-browser/references/react.md +301 -0
- package/skills/hydrogen-customer-account/SKILL.md +107 -0
- package/skills/hydrogen-image/SKILL.md +65 -0
- package/skills/hydrogen-local-https/SKILL.md +142 -0
- package/skills/hydrogen-markets/SKILL.md +221 -0
- package/skills/hydrogen-markets/references/nextjs.md +157 -0
- package/skills/hydrogen-money/SKILL.md +67 -0
- package/skills/hydrogen-oxygen/SKILL.md +245 -0
- package/skills/hydrogen-oxygen/references/react-router.md +230 -0
- package/skills/hydrogen-predictive-search/SKILL.md +130 -0
- package/skills/hydrogen-predictive-search/references/react.md +32 -0
- package/skills/hydrogen-predictive-search/references/vue.md +40 -0
- package/skills/hydrogen-request-handlers/SKILL.md +107 -0
- package/skills/hydrogen-request-handlers/references/frameworks.md +179 -0
- package/skills/hydrogen-request-handlers/references/nextjs.md +137 -0
- package/skills/hydrogen-request-handlers/references/nuxt.md +215 -0
- package/skills/hydrogen-routing/SKILL.md +171 -0
- package/skills/hydrogen-setup/SKILL.md +50 -0
- package/skills/hydrogen-setup/references/analytics.md +624 -0
- package/skills/hydrogen-setup/steps/1-inspect-app.md +62 -0
- package/skills/hydrogen-setup/steps/10-analytics.md +10 -0
- package/skills/hydrogen-setup/steps/11-verify.md +31 -0
- package/skills/hydrogen-setup/steps/2-scaffold.md +86 -0
- package/skills/hydrogen-setup/steps/3-build-home-page.md +37 -0
- package/skills/hydrogen-setup/steps/4-collection-and-search.md +14 -0
- package/skills/hydrogen-setup/steps/5-cart.md +10 -0
- package/skills/hydrogen-setup/steps/6-product-detail-page.md +416 -0
- package/skills/hydrogen-setup/steps/7-shopify-runtime-scripts.md +69 -0
- package/skills/hydrogen-setup/steps/8-cart-drawer-and-navbar.md +35 -0
- package/skills/hydrogen-setup/steps/9-account-page.md +54 -0
- package/skills/hydrogen-shop-pay/SKILL.md +79 -0
- package/skills/hydrogen-shop-pay/references/core.md +66 -0
- package/skills/hydrogen-shop-pay/references/react.md +50 -0
- package/skills/hydrogen-shop-pay/references/vue.md +39 -0
- package/skills/hydrogen-smoke-test/SKILL.md +205 -0
- package/skills/hydrogen-storefront-client/SKILL.md +322 -0
- package/skills/hydrogen-storefront-client/references/astro.md +125 -0
- package/skills/hydrogen-storefront-client/references/caching.md +25 -0
- package/skills/hydrogen-storefront-client/references/nextjs.md +121 -0
- package/skills/hydrogen-storefront-client/references/nuxt.md +121 -0
- package/skills/hydrogen-storefront-client/references/query-validation.md +95 -0
- package/skills/hydrogen-storefront-client/references/react-router.md +81 -0
- package/skills/hydrogen-storefront-client/references/solidstart.md +131 -0
- package/skills/hydrogen-storefront-client/references/sveltekit.md +169 -0
- package/skills/hydrogen-variant-form/SKILL.md +267 -0
- package/skills/hydrogen-variant-form/references/nextjs.md +207 -0
- package/skills/hydrogen-variant-form/references/nuxt.md +95 -0
- package/skills/hydrogen-variant-form/references/react.md +71 -0
- package/dist/dev/get-virtual-routes-H72465VB.js +0 -74
- package/dist/dev/hydrogen-routes.d.ts +0 -5
- package/dist/dev/hydrogen-routes.js +0 -25
- package/dist/development/get-virtual-routes-ACFZHU42.js +0 -71
- package/dist/development/get-virtual-routes-ACFZHU42.js.map +0 -1
- package/dist/development/index.cjs +0 -6978
- package/dist/development/index.cjs.map +0 -1
- package/dist/development/index.js +0 -6631
- package/dist/development/index.js.map +0 -1
- package/dist/development/log-seo-tags-IG37ONQ2.js +0 -74
- package/dist/development/log-seo-tags-IG37ONQ2.js.map +0 -1
- package/dist/development/react-router-preset.d.ts +0 -45
- package/dist/development/react-router-preset.js +0 -49
- package/dist/development/react-router-preset.js.map +0 -1
- package/dist/index.cjs +0 -1
- package/dist/oxygen/index.d.ts +0 -197
- package/dist/oxygen/index.js +0 -107
- package/dist/production/get-virtual-routes-ZZEGQQDV.js +0 -3
- package/dist/production/get-virtual-routes-ZZEGQQDV.js.map +0 -1
- package/dist/production/index.cjs +0 -1019
- package/dist/production/index.cjs.map +0 -1
- package/dist/production/index.d.cts +0 -3260
- package/dist/production/index.d.ts +0 -3260
- package/dist/production/index.js +0 -1019
- package/dist/production/index.js.map +0 -1
- package/dist/production/log-seo-tags-TY72EQWZ.js +0 -2
- package/dist/production/log-seo-tags-TY72EQWZ.js.map +0 -1
- package/dist/production/react-router-preset.d.ts +0 -45
- package/dist/production/react-router-preset.js +0 -11
- package/dist/react-router.d.ts +0 -75
- package/dist/vite/chunk-4O5OI3OO.js +0 -127
- package/dist/vite/chunk-FAQ7TVHC.js +0 -9
- package/dist/vite/chunk-QXBQVDMY.js +0 -68
- package/dist/vite/compat-date.d.ts +0 -3
- package/dist/vite/compat-date.js +0 -6
- package/dist/vite/get-virtual-routes.d.ts +0 -21
- package/dist/vite/get-virtual-routes.js +0 -74
- package/dist/vite/hydrogen-middleware.d.ts +0 -9
- package/dist/vite/hydrogen-middleware.js +0 -7
- package/dist/vite/plugin.d.ts +0 -22
- package/dist/vite/plugin.js +0 -171
- package/dist/vite/request-events.d.ts +0 -144
- package/dist/vite/request-events.js +0 -10
- package/dist/vite/types.d.ts +0 -5
- package/dist/vite/types.js +0 -0
- package/dist/vite/virtual-routes/assets/debug-network.css +0 -609
- package/dist/vite/virtual-routes/assets/favicon-dark.svg +0 -20
- package/dist/vite/virtual-routes/assets/favicon.svg +0 -28
- package/dist/vite/virtual-routes/assets/inter-variable-font.woff2 +0 -0
- package/dist/vite/virtual-routes/assets/jetbrainsmono-variable-font.woff2 +0 -0
- package/dist/vite/virtual-routes/assets/styles.css +0 -249
- package/dist/vite/virtual-routes/components/FlameChartWrapper.jsx +0 -123
- package/dist/vite/virtual-routes/components/HydrogenLogoBaseBW.jsx +0 -32
- package/dist/vite/virtual-routes/components/HydrogenLogoBaseColor.jsx +0 -47
- package/dist/vite/virtual-routes/components/IconBanner.jsx +0 -292
- package/dist/vite/virtual-routes/components/IconClose.jsx +0 -38
- package/dist/vite/virtual-routes/components/IconDiscard.jsx +0 -44
- package/dist/vite/virtual-routes/components/IconError.jsx +0 -61
- package/dist/vite/virtual-routes/components/IconGithub.jsx +0 -23
- package/dist/vite/virtual-routes/components/IconTwitter.jsx +0 -21
- package/dist/vite/virtual-routes/components/Layout.jsx +0 -7
- package/dist/vite/virtual-routes/components/RequestDetails.jsx +0 -171
- package/dist/vite/virtual-routes/components/RequestTable.jsx +0 -91
- package/dist/vite/virtual-routes/components/RequestWaterfall.jsx +0 -151
- package/dist/vite/virtual-routes/layout.jsx +0 -33
- package/dist/vite/virtual-routes/lib/useDebugNetworkServer.jsx +0 -178
- package/dist/vite/virtual-routes/routes/[.]well-known.appspecific.com[.]chrome[.]devtools[.]json.jsx +0 -37
- package/dist/vite/virtual-routes/routes/[.]well-known.appspecific.com[.]chrome[.]devtools[.]json.tsx +0 -79
- package/dist/vite/virtual-routes/routes/graphiql.jsx +0 -5
- package/dist/vite/virtual-routes/routes/index.jsx +0 -265
- package/dist/vite/virtual-routes/routes/subrequest-profiler.jsx +0 -243
- package/dist/vite/virtual-routes/virtual-root-with-layout.jsx +0 -63
- package/dist/vite/virtual-routes/virtual-root.jsx +0 -67
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handle-shopify-routes.mjs","names":[],"sources":["../../../../src/core/request-routing/handle-shopify-routes.ts"],"sourcesContent":["import { handleProductVariantId } from \"../product/accept-variant-id\";\nimport { handleAjaxApi } from \"./interceptors/ajax-api\";\nimport { handleShopifyApiProxy } from \"./interceptors/api-proxy\";\nimport { handleCheckoutRedirect } from \"./interceptors/checkout\";\nimport { handleMcpProxy } from \"./interceptors/mcp-proxy\";\nimport { handleSfapiProxy } from \"./interceptors/sfapi-proxy\";\nimport { handleWellKnownProxy } from \"./interceptors/well-known\";\nimport { handleShopifyRouteHandlers } from \"./registered-routes\";\nimport type { HydrogenRouteHandler, HydrogenRouteInterceptor } from \"./route-types\";\nimport { safeApplyResponseHeaders } from \"./safe-apply-response-headers\";\n\nconst SHOPIFY_ROUTE_INTERCEPTORS = [\n handleShopifyApiProxy,\n handleSfapiProxy,\n handleProductVariantId,\n handleShopifyRouteHandlers,\n handleCheckoutRedirect,\n handleWellKnownProxy,\n handleMcpProxy,\n handleAjaxApi,\n] satisfies readonly HydrogenRouteInterceptor[];\n\n/**\n * Matches a request against Shopify standard routes and any registered handler\n * groups, returning a raw `Response` (redirect or JSON) when one matches, or\n * `null` when none do. Use it as the first step of request handling, before\n * framework routing. Matched responses already include request-context\n * response headers.\n */\nexport const handleShopifyRoutes: HydrogenRouteHandler = (options) => {\n if (options.requestContext !== options.storefrontClient.requestContext) {\n throw new Error(\n \"handleShopifyRoutes must receive the same requestContext used by storefrontClient.\",\n );\n }\n\n const url = new URL(options.request.url);\n\n for (const interceptor of SHOPIFY_ROUTE_INTERCEPTORS) {\n const responsePromise = interceptor(url, options);\n if (!responsePromise) continue;\n\n return responsePromise.then((response) =>\n safeApplyResponseHeaders(response, options.requestContext),\n );\n }\n\n return null;\n};\n"],"mappings":";;;;;;;;;;;AAWA,MAAM,6BAA6B;CACjC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;;;;;;;AASD,MAAa,uBAA6C,YAAY;AACpE,KAAI,QAAQ,mBAAmB,QAAQ,iBAAiB,eACtD,OAAM,IAAI,MACR,qFACD;CAGH,MAAM,MAAM,IAAI,IAAI,QAAQ,QAAQ,IAAI;AAExC,MAAK,MAAM,eAAe,4BAA4B;EACpD,MAAM,kBAAkB,YAAY,KAAK,QAAQ;AACjD,MAAI,CAAC,gBAAiB;AAEtB,SAAO,gBAAgB,MAAM,aAC3B,yBAAyB,UAAU,QAAQ,eAAe,CAC3D;;AAGH,QAAO"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
//#region src/core/request-routing/interceptors/admin-redirect.ts
|
|
2
|
+
function handleAdminRedirect({ request, storefrontClient }) {
|
|
3
|
+
if (new URL(request.url).pathname !== "/admin") return null;
|
|
4
|
+
return new Response(null, {
|
|
5
|
+
status: 301,
|
|
6
|
+
headers: { location: new URL("/admin", storefrontClient.storeUrl).toString() }
|
|
7
|
+
});
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
//#endregion
|
|
11
|
+
export { handleAdminRedirect };
|
|
12
|
+
//# sourceMappingURL=admin-redirect.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin-redirect.mjs","names":[],"sources":["../../../../../src/core/request-routing/interceptors/admin-redirect.ts"],"sourcesContent":["import type { RedirectOptions } from \"../handle-shopify-redirects\";\n\ntype AdminRedirectOptions = Pick<RedirectOptions, \"request\" | \"storefrontClient\">;\n\nexport function handleAdminRedirect({\n request,\n storefrontClient,\n}: AdminRedirectOptions): Response | null {\n const url = new URL(request.url);\n if (url.pathname !== \"/admin\") return null;\n\n return new Response(null, {\n status: 301,\n headers: { location: new URL(\"/admin\", storefrontClient.storeUrl).toString() },\n });\n}\n"],"mappings":";AAIA,SAAgB,oBAAoB,EAClC,SACA,oBACwC;AAExC,KAAI,IADY,IAAI,QAAQ,IACrB,CAAC,aAAa,SAAU,QAAO;AAEtC,QAAO,IAAI,SAAS,MAAM;EACxB,QAAQ;EACR,SAAS,EAAE,UAAU,IAAI,IAAI,UAAU,iBAAiB,SAAS,CAAC,UAAU,EAAE;EAC/E,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { AJAX_API_REQUEST_HEADER_ALLOWLIST } from "../../headers.mjs";
|
|
2
|
+
import { AJAX_CART_RE } from "../../url.mjs";
|
|
3
|
+
import { createProxyInterceptor } from "./proxy.mjs";
|
|
4
|
+
|
|
5
|
+
//#region src/core/request-routing/interceptors/ajax-api.ts
|
|
6
|
+
const rewriteShopifyJsPathname = (pathname) => pathname.replace(/\.js$/i, ".json");
|
|
7
|
+
const handleAjaxApi = createProxyInterceptor({
|
|
8
|
+
match: AJAX_CART_RE,
|
|
9
|
+
requestHeaders: { allow: AJAX_API_REQUEST_HEADER_ALLOWLIST },
|
|
10
|
+
rewritePathname: rewriteShopifyJsPathname,
|
|
11
|
+
scope: "ajax-api"
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
//#endregion
|
|
15
|
+
export { handleAjaxApi, rewriteShopifyJsPathname };
|
|
16
|
+
//# sourceMappingURL=ajax-api.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ajax-api.mjs","names":[],"sources":["../../../../../src/core/request-routing/interceptors/ajax-api.ts"],"sourcesContent":["import { AJAX_API_REQUEST_HEADER_ALLOWLIST } from \"../../headers\";\nimport { AJAX_CART_RE } from \"../../url\";\nimport { createProxyInterceptor } from \"./proxy\";\n\n// Known workaround for Shopify server redirects on `.js` endpoints.\nexport const rewriteShopifyJsPathname = (pathname: string): string =>\n pathname.replace(/\\.js$/i, \".json\");\n\nexport const handleAjaxApi = createProxyInterceptor({\n match: AJAX_CART_RE,\n requestHeaders: { allow: AJAX_API_REQUEST_HEADER_ALLOWLIST },\n rewritePathname: rewriteShopifyJsPathname,\n scope: \"ajax-api\",\n});\n"],"mappings":";;;;;AAKA,MAAa,4BAA4B,aACvC,SAAS,QAAQ,UAAU,QAAQ;AAErC,MAAa,gBAAgB,uBAAuB;CAClD,OAAO;CACP,gBAAgB,EAAE,OAAO,mCAAmC;CAC5D,iBAAiB;CACjB,OAAO;CACR,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { PROXY_REQUEST_HEADER_DENYLIST } from "../../headers.mjs";
|
|
2
|
+
import { SHOPIFY_API_PROXY_PREFIX, SHOPIFY_API_PROXY_RE } from "../../url.mjs";
|
|
3
|
+
import { createProxyInterceptor } from "./proxy.mjs";
|
|
4
|
+
import { rewriteShopifyJsPathname } from "./ajax-api.mjs";
|
|
5
|
+
|
|
6
|
+
//#region src/core/request-routing/interceptors/api-proxy.ts
|
|
7
|
+
const handleShopifyApiProxy = createProxyInterceptor({
|
|
8
|
+
match: SHOPIFY_API_PROXY_RE,
|
|
9
|
+
requestHeaders: { deny: PROXY_REQUEST_HEADER_DENYLIST },
|
|
10
|
+
rewritePathname: (pathname) => {
|
|
11
|
+
const upstreamPathname = "/" + pathname.slice(SHOPIFY_API_PROXY_PREFIX.length).replace(/^\/+/, "");
|
|
12
|
+
if (upstreamPathname.startsWith("/cdn/")) throw new Error("CDN proxy is not supported.");
|
|
13
|
+
return rewriteShopifyJsPathname(upstreamPathname);
|
|
14
|
+
},
|
|
15
|
+
scope: "shopify-api-proxy"
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
//#endregion
|
|
19
|
+
export { handleShopifyApiProxy };
|
|
20
|
+
//# sourceMappingURL=api-proxy.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-proxy.mjs","names":[],"sources":["../../../../../src/core/request-routing/interceptors/api-proxy.ts"],"sourcesContent":["import { PROXY_REQUEST_HEADER_DENYLIST } from \"../../headers\";\nimport { SHOPIFY_API_PROXY_PREFIX, SHOPIFY_API_PROXY_RE } from \"../../url\";\nimport { rewriteShopifyJsPathname } from \"./ajax-api\";\nimport { createProxyInterceptor } from \"./proxy\";\n\nexport const handleShopifyApiProxy = createProxyInterceptor({\n match: SHOPIFY_API_PROXY_RE,\n requestHeaders: { deny: PROXY_REQUEST_HEADER_DENYLIST },\n rewritePathname: (pathname) => {\n const upstreamPathname =\n \"/\" + pathname.slice(SHOPIFY_API_PROXY_PREFIX.length).replace(/^\\/+/, \"\");\n\n if (upstreamPathname.startsWith(\"/cdn/\")) {\n throw new Error(\"CDN proxy is not supported.\");\n }\n\n return rewriteShopifyJsPathname(upstreamPathname);\n },\n scope: \"shopify-api-proxy\",\n});\n"],"mappings":";;;;;;AAKA,MAAa,wBAAwB,uBAAuB;CAC1D,OAAO;CACP,gBAAgB,EAAE,MAAM,+BAA+B;CACvD,kBAAkB,aAAa;EAC7B,MAAM,mBACJ,MAAM,SAAS,MAAM,yBAAyB,OAAO,CAAC,QAAQ,QAAQ,GAAG;AAE3E,MAAI,iBAAiB,WAAW,QAAQ,CACtC,OAAM,IAAI,MAAM,8BAA8B;AAGhD,SAAO,yBAAyB,iBAAiB;;CAEnD,OAAO;CACR,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { getLogger } from "../../logging/logging.mjs";
|
|
2
|
+
import { CHECKOUT_RE, isHydrogenServerHandoffPath } from "../../url.mjs";
|
|
3
|
+
import { getCart, getCartId } from "../../cart/get-cart.mjs";
|
|
4
|
+
|
|
5
|
+
//#region src/core/request-routing/interceptors/checkout.ts
|
|
6
|
+
const log = getLogger("checkout");
|
|
7
|
+
const MOCK_SHOP_CART_PERMALINK_ORIGIN = "https://demostore.mock.shop";
|
|
8
|
+
const handleCheckoutRedirect = (url, { request, storefrontClient }) => {
|
|
9
|
+
if (!isHydrogenServerHandoffPath(url.pathname)) return null;
|
|
10
|
+
if (request.method !== "GET" && request.method !== "HEAD") return Promise.resolve(new Response("Method Not Allowed", { status: 405 }));
|
|
11
|
+
return (CHECKOUT_RE.test(url.pathname) ? getCheckoutRedirectUrl(request, storefrontClient) : getCartRedirectUrl(request, storefrontClient)).then((redirectUrl) => {
|
|
12
|
+
if (redirectUrl.pathname !== "/") {
|
|
13
|
+
mergeSearchParams(redirectUrl, url.searchParams);
|
|
14
|
+
redirectUrl.searchParams.set("payment", url.searchParams.get("payment") ?? "shop_pay");
|
|
15
|
+
}
|
|
16
|
+
return new Response(null, {
|
|
17
|
+
status: 302,
|
|
18
|
+
headers: { location: redirectUrl.toString() }
|
|
19
|
+
});
|
|
20
|
+
}).catch((error) => {
|
|
21
|
+
log.error("checkout redirect request failed", { error });
|
|
22
|
+
const message = error instanceof Error ? error.message : "Internal redirect error";
|
|
23
|
+
return new Response(JSON.stringify({ error: message }), {
|
|
24
|
+
status: 502,
|
|
25
|
+
headers: { "content-type": "application/json" }
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
async function getCheckoutRedirectUrl(request, storefrontClient) {
|
|
30
|
+
const cartId = getCartId(request);
|
|
31
|
+
if (!cartId) return new URL("/", request.url);
|
|
32
|
+
const result = await getCart(cartId, storefrontClient);
|
|
33
|
+
return result.cart?.checkoutUrl ? new URL(result.cart.checkoutUrl) : new URL("/", request.url);
|
|
34
|
+
}
|
|
35
|
+
async function getCartRedirectUrl(request, storefrontClient) {
|
|
36
|
+
const sourceUrl = new URL(request.url);
|
|
37
|
+
const redirectUrl = new URL(sourceUrl.pathname, getCartPermalinkOrigin(storefrontClient.storeUrl));
|
|
38
|
+
const cartId = getCartId(request);
|
|
39
|
+
if (!cartId) return redirectUrl;
|
|
40
|
+
try {
|
|
41
|
+
const result = await getCart(cartId, storefrontClient);
|
|
42
|
+
if (result.cart?.checkoutUrl) mergeSearchParams(redirectUrl, new URL(result.cart.checkoutUrl).searchParams);
|
|
43
|
+
} catch (error) {
|
|
44
|
+
log.warn("checkout redirect could not load cart permalink tracking params", { error });
|
|
45
|
+
}
|
|
46
|
+
return redirectUrl;
|
|
47
|
+
}
|
|
48
|
+
function getCartPermalinkOrigin(storeUrl) {
|
|
49
|
+
const url = new URL(storeUrl);
|
|
50
|
+
return url.hostname === "mock.shop" ? MOCK_SHOP_CART_PERMALINK_ORIGIN : url.origin;
|
|
51
|
+
}
|
|
52
|
+
function mergeSearchParams(target, source) {
|
|
53
|
+
for (const [key, value] of source) if (!target.searchParams.has(key)) target.searchParams.append(key, value);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
//#endregion
|
|
57
|
+
export { handleCheckoutRedirect };
|
|
58
|
+
//# sourceMappingURL=checkout.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkout.mjs","names":[],"sources":["../../../../../src/core/request-routing/interceptors/checkout.ts"],"sourcesContent":["import type { StorefrontClient } from \"../../../client\";\nimport { getCart, getCartId } from \"../../cart/get-cart\";\nimport { getLogger } from \"../../logging\";\nimport { CHECKOUT_RE, isHydrogenServerHandoffPath } from \"../../url\";\nimport type { HydrogenRouteInterceptor } from \"../route-types\";\n\nconst log = getLogger(\"checkout\");\nconst MOCK_SHOP_CART_PERMALINK_ORIGIN = \"https://demostore.mock.shop\";\n\nexport const handleCheckoutRedirect: HydrogenRouteInterceptor = (\n url,\n { request, storefrontClient },\n) => {\n if (!isHydrogenServerHandoffPath(url.pathname)) {\n return null;\n }\n\n if (request.method !== \"GET\" && request.method !== \"HEAD\") {\n return Promise.resolve(new Response(\"Method Not Allowed\", { status: 405 }));\n }\n\n const redirectUrlPromise = CHECKOUT_RE.test(url.pathname)\n ? getCheckoutRedirectUrl(request, storefrontClient)\n : getCartRedirectUrl(request, storefrontClient);\n\n return redirectUrlPromise\n .then((redirectUrl) => {\n if (redirectUrl.pathname !== \"/\") {\n mergeSearchParams(redirectUrl, url.searchParams);\n redirectUrl.searchParams.set(\"payment\", url.searchParams.get(\"payment\") ?? \"shop_pay\");\n }\n\n return new Response(null, {\n status: 302,\n headers: { location: redirectUrl.toString() },\n });\n })\n .catch((error) => {\n log.error(\"checkout redirect request failed\", { error });\n const message = error instanceof Error ? error.message : \"Internal redirect error\";\n\n return new Response(JSON.stringify({ error: message }), {\n status: 502,\n headers: { \"content-type\": \"application/json\" },\n });\n });\n};\n\nasync function getCheckoutRedirectUrl(\n request: Request,\n storefrontClient: StorefrontClient,\n): Promise<URL> {\n const cartId = getCartId(request);\n if (!cartId) return new URL(\"/\", request.url);\n\n const result = await getCart(cartId, storefrontClient);\n return result.cart?.checkoutUrl ? new URL(result.cart.checkoutUrl) : new URL(\"/\", request.url);\n}\n\nasync function getCartRedirectUrl(\n request: Request,\n storefrontClient: StorefrontClient,\n): Promise<URL> {\n const sourceUrl = new URL(request.url);\n const redirectUrl = new URL(\n sourceUrl.pathname,\n getCartPermalinkOrigin(storefrontClient.storeUrl),\n );\n\n const cartId = getCartId(request);\n if (!cartId) return redirectUrl;\n\n try {\n const result = await getCart(cartId, storefrontClient);\n if (result.cart?.checkoutUrl) {\n mergeSearchParams(redirectUrl, new URL(result.cart.checkoutUrl).searchParams);\n }\n } catch (error) {\n log.warn(\"checkout redirect could not load cart permalink tracking params\", { error });\n }\n\n return redirectUrl;\n}\n\nfunction getCartPermalinkOrigin(storeUrl: string): string {\n const url = new URL(storeUrl);\n return url.hostname === \"mock.shop\" ? MOCK_SHOP_CART_PERMALINK_ORIGIN : url.origin;\n}\n\nfunction mergeSearchParams(target: URL, source: URLSearchParams): void {\n for (const [key, value] of source) {\n if (!target.searchParams.has(key)) target.searchParams.append(key, value);\n }\n}\n"],"mappings":";;;;;AAMA,MAAM,MAAM,UAAU,WAAW;AACjC,MAAM,kCAAkC;AAExC,MAAa,0BACX,KACA,EAAE,SAAS,uBACR;AACH,KAAI,CAAC,4BAA4B,IAAI,SAAS,CAC5C,QAAO;AAGT,KAAI,QAAQ,WAAW,SAAS,QAAQ,WAAW,OACjD,QAAO,QAAQ,QAAQ,IAAI,SAAS,sBAAsB,EAAE,QAAQ,KAAK,CAAC,CAAC;AAO7E,SAJ2B,YAAY,KAAK,IAAI,SAAS,GACrD,uBAAuB,SAAS,iBAAiB,GACjD,mBAAmB,SAAS,iBAAiB,EAG9C,MAAM,gBAAgB;AACrB,MAAI,YAAY,aAAa,KAAK;AAChC,qBAAkB,aAAa,IAAI,aAAa;AAChD,eAAY,aAAa,IAAI,WAAW,IAAI,aAAa,IAAI,UAAU,IAAI,WAAW;;AAGxF,SAAO,IAAI,SAAS,MAAM;GACxB,QAAQ;GACR,SAAS,EAAE,UAAU,YAAY,UAAU,EAAE;GAC9C,CAAC;GACF,CACD,OAAO,UAAU;AAChB,MAAI,MAAM,oCAAoC,EAAE,OAAO,CAAC;EACxD,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AAEzD,SAAO,IAAI,SAAS,KAAK,UAAU,EAAE,OAAO,SAAS,CAAC,EAAE;GACtD,QAAQ;GACR,SAAS,EAAE,gBAAgB,oBAAoB;GAChD,CAAC;GACF;;AAGN,eAAe,uBACb,SACA,kBACc;CACd,MAAM,SAAS,UAAU,QAAQ;AACjC,KAAI,CAAC,OAAQ,QAAO,IAAI,IAAI,KAAK,QAAQ,IAAI;CAE7C,MAAM,SAAS,MAAM,QAAQ,QAAQ,iBAAiB;AACtD,QAAO,OAAO,MAAM,cAAc,IAAI,IAAI,OAAO,KAAK,YAAY,GAAG,IAAI,IAAI,KAAK,QAAQ,IAAI;;AAGhG,eAAe,mBACb,SACA,kBACc;CACd,MAAM,YAAY,IAAI,IAAI,QAAQ,IAAI;CACtC,MAAM,cAAc,IAAI,IACtB,UAAU,UACV,uBAAuB,iBAAiB,SAAS,CAClD;CAED,MAAM,SAAS,UAAU,QAAQ;AACjC,KAAI,CAAC,OAAQ,QAAO;AAEpB,KAAI;EACF,MAAM,SAAS,MAAM,QAAQ,QAAQ,iBAAiB;AACtD,MAAI,OAAO,MAAM,YACf,mBAAkB,aAAa,IAAI,IAAI,OAAO,KAAK,YAAY,CAAC,aAAa;UAExE,OAAO;AACd,MAAI,KAAK,mEAAmE,EAAE,OAAO,CAAC;;AAGxF,QAAO;;AAGT,SAAS,uBAAuB,UAA0B;CACxD,MAAM,MAAM,IAAI,IAAI,SAAS;AAC7B,QAAO,IAAI,aAAa,cAAc,kCAAkC,IAAI;;AAG9E,SAAS,kBAAkB,QAAa,QAA+B;AACrE,MAAK,MAAM,CAAC,KAAK,UAAU,OACzB,KAAI,CAAC,OAAO,aAAa,IAAI,IAAI,CAAE,QAAO,aAAa,OAAO,KAAK,MAAM"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { _taggedTemplateLiteral } from "../../../_virtual/_@oxc-project_runtime@0.127.0/helpers/taggedTemplateLiteral.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/core/request-routing/interceptors/graphiql.ts
|
|
4
|
+
var _templateObject;
|
|
5
|
+
const DEV_SCHEMA_FETCH_TIMEOUT_MS = 1e4;
|
|
6
|
+
const handleGraphiql = (url, { request, storefrontClient, graphiql: graphiqlOptions }) => {
|
|
7
|
+
if (request.method !== "GET" || url.pathname !== "/graphiql") return null;
|
|
8
|
+
return createGraphiqlResponse(storefrontClient, graphiqlOptions);
|
|
9
|
+
};
|
|
10
|
+
async function createGraphiqlResponse(storefrontClient, graphiqlOptions) {
|
|
11
|
+
const schemas = {};
|
|
12
|
+
schemas.storefront = {
|
|
13
|
+
name: "Storefront API",
|
|
14
|
+
authHeader: "X-Shopify-Storefront-Access-Token",
|
|
15
|
+
apiUrl: `${storefrontClient.storeUrl}/api/unstable/graphql.json`,
|
|
16
|
+
icon: "SF"
|
|
17
|
+
};
|
|
18
|
+
if (graphiqlOptions?.customerAccount) {
|
|
19
|
+
const { apiUrl, accessToken, schemaUrl } = graphiqlOptions.customerAccount;
|
|
20
|
+
try {
|
|
21
|
+
const schemaJson = await (await fetch(schemaUrl, { signal: AbortSignal.timeout(DEV_SCHEMA_FETCH_TIMEOUT_MS) })).json();
|
|
22
|
+
if (typeof schemaJson === "object" && schemaJson !== null) schemas["customer-account"] = {
|
|
23
|
+
name: "Customer Account API",
|
|
24
|
+
value: schemaJson,
|
|
25
|
+
authHeader: "Authorization",
|
|
26
|
+
accessToken,
|
|
27
|
+
apiUrl,
|
|
28
|
+
icon: "CA"
|
|
29
|
+
};
|
|
30
|
+
} catch {}
|
|
31
|
+
}
|
|
32
|
+
const favicon = "https://avatars.githubusercontent.com/u/12972006?s=48&v=4";
|
|
33
|
+
const html = String.raw;
|
|
34
|
+
return new Response(html(_templateObject || (_templateObject = _taggedTemplateLiteral([
|
|
35
|
+
"\n <!DOCTYPE html>\n <html lang=\"en\">\n <head>\n <title>GraphiQL</title>\n <link rel=\"icon\" type=\"image/x-icon\" href=\"",
|
|
36
|
+
"\" />\n <meta charset=\"utf-8\" />\n <style>\n body {\n height: 100%;\n margin: 0;\n width: 100%;\n overflow: hidden;\n background-color: hsl(219, 29%, 18%);\n }\n #graphiql {\n height: 100vh;\n }\n #graphiql > .placeholder {\n color: slategray;\n width: fit-content;\n margin: 40px auto;\n font-family: Arial;\n }\n .graphiql-api-toolbar-label {\n position: absolute;\n bottom: -6px;\n right: -4px;\n font-size: 8px;\n }\n </style>\n <link rel=\"stylesheet\" href=\"https://esm.sh/graphiql/dist/style.css\" />\n <link rel=\"stylesheet\" href=\"https://esm.sh/@graphiql/plugin-explorer/dist/style.css\" />\n <script type=\"importmap\">\n {\n \"imports\": {\n \"react\": \"https://esm.sh/react@19.1.0\",\n \"react/jsx-runtime\": \"https://esm.sh/react@19.1.0/jsx-runtime\",\n \"react-dom\": \"https://esm.sh/react-dom@19.1.0\",\n \"react-dom/client\": \"https://esm.sh/react-dom@19.1.0/client\",\n \"graphql\": \"https://esm.sh/graphql@16.11.0\",\n \"graphiql\": \"https://esm.sh/graphiql?standalone&external=react,react-dom,@graphiql/react,graphql\",\n \"@graphiql/plugin-explorer\": \"https://esm.sh/@graphiql/plugin-explorer?standalone&external=react,@graphiql/react,graphql\",\n \"@graphiql/react\": \"https://esm.sh/@graphiql/react?standalone&external=react,react-dom,graphql\",\n \"@graphiql/toolkit\": \"https://esm.sh/@graphiql/toolkit?standalone&external=graphql\"\n }\n }\n <\/script>\n <script type=\"module\">\n import React from \"react\";\n import ReactDOM from \"react-dom/client\";\n import { GraphiQL, HISTORY_PLUGIN } from \"graphiql\";\n import { createGraphiQLFetcher } from \"@graphiql/toolkit\";\n import { explorerPlugin } from \"@graphiql/plugin-explorer\";\n import { ToolbarButton } from \"@graphiql/react\";\n import createJSONWorker from \"https://esm.sh/monaco-editor/esm/vs/language/json/json.worker.js?worker\";\n import createGraphQLWorker from \"https://esm.sh/monaco-graphql/esm/graphql.worker.js?worker\";\n import createEditorWorker from \"https://esm.sh/monaco-editor/esm/vs/editor/editor.worker.js?worker\";\n import { parse, print } from \"graphql\";\n\n globalThis.MonacoEnvironment = {\n getWorker(_workerId, label) {\n switch (label) {\n case \"json\":\n return createJSONWorker();\n case \"graphql\":\n return createGraphQLWorker();\n }\n return createEditorWorker();\n },\n };\n\n const windowUrl = new URL(document.URL);\n const startingSchemaKey = windowUrl.searchParams.get(\"schema\") || \"storefront\";\n\n let initialQuery = \"{ shop { name } }\";\n if (windowUrl.searchParams.has(\"query\")) {\n initialQuery = decodeURIComponent(windowUrl.searchParams.get(\"query\") ?? initialQuery);\n }\n\n initialQuery = print(parse(initialQuery));\n\n let variables;\n if (windowUrl.searchParams.has(\"variables\")) {\n variables = decodeURIComponent(windowUrl.searchParams.get(\"variables\") ?? \"\");\n }\n\n if (variables) {\n variables = JSON.stringify(JSON.parse(variables), null, 2);\n }\n\n const schemas = ",
|
|
37
|
+
";\n\n let lastActiveTabIndex = -1;\n let lastTabAmount = -1;\n\n const TAB_STATE_KEY = \"graphiql:tabState\";\n const storage = {\n getTabState: () => JSON.parse(localStorage.getItem(TAB_STATE_KEY)),\n setTabState: (state) => localStorage.setItem(TAB_STATE_KEY, JSON.stringify(state)),\n };\n\n let nextSchemaKey;\n\n function App() {\n const [activeSchema, setActiveSchema] = React.useState(startingSchemaKey);\n\n const schema = schemas[activeSchema];\n\n if (!schema) {\n throw new Error(\"No schema found for \" + activeSchema);\n }\n\n const requestHeaders = schema.accessToken\n ? { [schema.authHeader]: schema.accessToken }\n : {};\n\n const fetcher = createGraphiQLFetcher({\n url: schema.apiUrl,\n headers: requestHeaders,\n enableIncrementalDelivery: false,\n });\n\n function createJsonFetcher(options, httpFetch) {\n if (activeSchema === \"storefront\") {\n return fetcher(options, httpFetch);\n } else {\n if (options.operationName === \"IntrospectionQuery\") {\n return { data: schema.value };\n } else {\n return fetcher(options, httpFetch);\n }\n }\n }\n\n const keys = Object.keys(schemas);\n\n function onTabChange(state) {\n const { activeTabIndex, tabs } = state;\n const activeTab = tabs[activeTabIndex];\n\n if (activeTabIndex === lastActiveTabIndex && lastTabAmount === tabs.length) {\n if (nextSchemaKey && activeTab && activeTab.schemaKey !== nextSchemaKey) {\n activeTab.schemaKey = nextSchemaKey;\n nextSchemaKey = undefined;\n storage.setTabState(state);\n setTimeout(() => storage.setTabState(state), 500);\n }\n return;\n }\n\n if (activeTab) {\n if (!activeTab.schemaKey) {\n if (lastTabAmount < tabs.length) {\n activeTab.schemaKey = activeSchema;\n storage.setTabState(state);\n }\n }\n\n const nextSchema = activeTab.schemaKey || \"storefront\";\n\n if (nextSchema !== activeSchema) {\n setActiveSchema(nextSchema);\n }\n }\n\n lastActiveTabIndex = activeTabIndex;\n lastTabAmount = tabs.length;\n }\n\n const plugins = [HISTORY_PLUGIN, explorerPlugin()];\n\n const props = {\n fetcher: createJsonFetcher,\n defaultEditorToolsVisibility: true,\n initialQuery,\n variables,\n schema: schema.value,\n plugins,\n onTabChange,\n };\n\n function toggleSelectedApi() {\n const activeKeyIndex = keys.indexOf(activeSchema);\n nextSchemaKey = keys[(activeKeyIndex + 1) % keys.length];\n if (nextSchemaKey) setActiveSchema(nextSchemaKey);\n }\n\n const CustomToolbar = React.createElement(GraphiQL.Toolbar, { key: \"Custom Toolbar\" }, [\n React.createElement(\n ToolbarButton,\n {\n key: \"api-wrapper\",\n onClick: toggleSelectedApi,\n label: \"Toggle between different API schemas\",\n },\n [\n React.createElement(\"div\", { key: \"icon\", style: { textAlign: \"center\" } }, [\n schema.icon,\n React.createElement(\n \"div\",\n {\n key: \"icon-label\",\n className: \"graphiql-api-toolbar-label\",\n },\n \"API\",\n ),\n ]),\n ],\n ),\n ]);\n\n const CustomLogo = React.createElement(GraphiQL.Logo, { key: \"Logo replacement\" }, [\n React.createElement(\n \"div\",\n {\n key: \"Logo wrapper\",\n style: { display: \"flex\", alignItems: \"center\" },\n },\n [\n React.createElement(\n \"div\",\n {\n key: \"api\",\n className: \"graphiql-logo\",\n style: { paddingRight: 0, whiteSpace: \"nowrap\" },\n },\n [schema.name],\n ),\n React.createElement(GraphiQL.Logo, { key: \"logo\" }),\n ],\n ),\n ]);\n\n return React.createElement(GraphiQL, props, [CustomToolbar, CustomLogo]);\n }\n\n const container = document.getElementById(\"graphiql\");\n const root = ReactDOM.createRoot(container);\n root.render(React.createElement(App));\n <\/script>\n </head>\n <body>\n <div id=\"graphiql\">\n <div class=\"placeholder\">Loading GraphiQL...</div>\n </div>\n </body>\n </html>\n "
|
|
38
|
+
])), favicon, JSON.stringify(schemas).replace(/</g, "\\u003c")), {
|
|
39
|
+
status: 200,
|
|
40
|
+
headers: { "content-type": "text/html" }
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
//#endregion
|
|
45
|
+
export { handleGraphiql };
|
|
46
|
+
//# sourceMappingURL=graphiql.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graphiql.mjs","names":[],"sources":["../../../../../src/core/request-routing/interceptors/graphiql.ts"],"sourcesContent":["import type { StorefrontClient } from \"../../../client\";\nimport type { GraphiQLOptions } from \"../../types\";\nimport type { HydrogenRouteInterceptor } from \"../route-types\";\n\nconst DEV_SCHEMA_FETCH_TIMEOUT_MS = 10_000;\n\ntype GraphiqlRouteOptions = {\n graphiql?: GraphiQLOptions;\n};\n\nexport const handleGraphiql: HydrogenRouteInterceptor<GraphiqlRouteOptions> = (\n url,\n { request, storefrontClient, graphiql: graphiqlOptions },\n) => {\n if (request.method !== \"GET\" || url.pathname !== \"/graphiql\") return null;\n\n return createGraphiqlResponse(storefrontClient, graphiqlOptions);\n};\n\nasync function createGraphiqlResponse(\n storefrontClient: StorefrontClient,\n graphiqlOptions?: GraphiQLOptions,\n): Promise<Response> {\n const schemas: Record<\n string,\n {\n name: string;\n value?: object;\n accessToken?: string;\n authHeader: string;\n apiUrl: string;\n icon: string;\n }\n > = {};\n\n const sfapiUrl = `${storefrontClient.storeUrl}/api/unstable/graphql.json`;\n\n schemas.storefront = {\n name: \"Storefront API\",\n authHeader: \"X-Shopify-Storefront-Access-Token\",\n apiUrl: sfapiUrl,\n icon: \"SF\",\n };\n\n if (graphiqlOptions?.customerAccount) {\n const { apiUrl, accessToken, schemaUrl } = graphiqlOptions.customerAccount;\n\n try {\n const schemaResponse = await fetch(schemaUrl, {\n signal: AbortSignal.timeout(DEV_SCHEMA_FETCH_TIMEOUT_MS),\n });\n const schemaJson: unknown = await schemaResponse.json();\n\n if (typeof schemaJson === \"object\" && schemaJson !== null) {\n schemas[\"customer-account\"] = {\n name: \"Customer Account API\",\n value: schemaJson as object,\n authHeader: \"Authorization\",\n accessToken,\n apiUrl,\n icon: \"CA\",\n };\n }\n } catch {\n // CAAPI schema unavailable — skip the tab silently\n }\n }\n\n const favicon = \"https://avatars.githubusercontent.com/u/12972006?s=48&v=4\";\n\n const html = String.raw;\n\n return new Response(\n html`\n <!DOCTYPE html>\n <html lang=\"en\">\n <head>\n <title>GraphiQL</title>\n <link rel=\"icon\" type=\"image/x-icon\" href=\"${favicon}\" />\n <meta charset=\"utf-8\" />\n <style>\n body {\n height: 100%;\n margin: 0;\n width: 100%;\n overflow: hidden;\n background-color: hsl(219, 29%, 18%);\n }\n #graphiql {\n height: 100vh;\n }\n #graphiql > .placeholder {\n color: slategray;\n width: fit-content;\n margin: 40px auto;\n font-family: Arial;\n }\n .graphiql-api-toolbar-label {\n position: absolute;\n bottom: -6px;\n right: -4px;\n font-size: 8px;\n }\n </style>\n <link rel=\"stylesheet\" href=\"https://esm.sh/graphiql/dist/style.css\" />\n <link rel=\"stylesheet\" href=\"https://esm.sh/@graphiql/plugin-explorer/dist/style.css\" />\n <script type=\"importmap\">\n {\n \"imports\": {\n \"react\": \"https://esm.sh/react@19.1.0\",\n \"react/jsx-runtime\": \"https://esm.sh/react@19.1.0/jsx-runtime\",\n \"react-dom\": \"https://esm.sh/react-dom@19.1.0\",\n \"react-dom/client\": \"https://esm.sh/react-dom@19.1.0/client\",\n \"graphql\": \"https://esm.sh/graphql@16.11.0\",\n \"graphiql\": \"https://esm.sh/graphiql?standalone&external=react,react-dom,@graphiql/react,graphql\",\n \"@graphiql/plugin-explorer\": \"https://esm.sh/@graphiql/plugin-explorer?standalone&external=react,@graphiql/react,graphql\",\n \"@graphiql/react\": \"https://esm.sh/@graphiql/react?standalone&external=react,react-dom,graphql\",\n \"@graphiql/toolkit\": \"https://esm.sh/@graphiql/toolkit?standalone&external=graphql\"\n }\n }\n </script>\n <script type=\"module\">\n import React from \"react\";\n import ReactDOM from \"react-dom/client\";\n import { GraphiQL, HISTORY_PLUGIN } from \"graphiql\";\n import { createGraphiQLFetcher } from \"@graphiql/toolkit\";\n import { explorerPlugin } from \"@graphiql/plugin-explorer\";\n import { ToolbarButton } from \"@graphiql/react\";\n import createJSONWorker from \"https://esm.sh/monaco-editor/esm/vs/language/json/json.worker.js?worker\";\n import createGraphQLWorker from \"https://esm.sh/monaco-graphql/esm/graphql.worker.js?worker\";\n import createEditorWorker from \"https://esm.sh/monaco-editor/esm/vs/editor/editor.worker.js?worker\";\n import { parse, print } from \"graphql\";\n\n globalThis.MonacoEnvironment = {\n getWorker(_workerId, label) {\n switch (label) {\n case \"json\":\n return createJSONWorker();\n case \"graphql\":\n return createGraphQLWorker();\n }\n return createEditorWorker();\n },\n };\n\n const windowUrl = new URL(document.URL);\n const startingSchemaKey = windowUrl.searchParams.get(\"schema\") || \"storefront\";\n\n let initialQuery = \"{ shop { name } }\";\n if (windowUrl.searchParams.has(\"query\")) {\n initialQuery = decodeURIComponent(windowUrl.searchParams.get(\"query\") ?? initialQuery);\n }\n\n initialQuery = print(parse(initialQuery));\n\n let variables;\n if (windowUrl.searchParams.has(\"variables\")) {\n variables = decodeURIComponent(windowUrl.searchParams.get(\"variables\") ?? \"\");\n }\n\n if (variables) {\n variables = JSON.stringify(JSON.parse(variables), null, 2);\n }\n\n const schemas = ${JSON.stringify(schemas).replace(/</g, '\\\\u003c')};\n\n let lastActiveTabIndex = -1;\n let lastTabAmount = -1;\n\n const TAB_STATE_KEY = \"graphiql:tabState\";\n const storage = {\n getTabState: () => JSON.parse(localStorage.getItem(TAB_STATE_KEY)),\n setTabState: (state) => localStorage.setItem(TAB_STATE_KEY, JSON.stringify(state)),\n };\n\n let nextSchemaKey;\n\n function App() {\n const [activeSchema, setActiveSchema] = React.useState(startingSchemaKey);\n\n const schema = schemas[activeSchema];\n\n if (!schema) {\n throw new Error(\"No schema found for \" + activeSchema);\n }\n\n const requestHeaders = schema.accessToken\n ? { [schema.authHeader]: schema.accessToken }\n : {};\n\n const fetcher = createGraphiQLFetcher({\n url: schema.apiUrl,\n headers: requestHeaders,\n enableIncrementalDelivery: false,\n });\n\n function createJsonFetcher(options, httpFetch) {\n if (activeSchema === \"storefront\") {\n return fetcher(options, httpFetch);\n } else {\n if (options.operationName === \"IntrospectionQuery\") {\n return { data: schema.value };\n } else {\n return fetcher(options, httpFetch);\n }\n }\n }\n\n const keys = Object.keys(schemas);\n\n function onTabChange(state) {\n const { activeTabIndex, tabs } = state;\n const activeTab = tabs[activeTabIndex];\n\n if (activeTabIndex === lastActiveTabIndex && lastTabAmount === tabs.length) {\n if (nextSchemaKey && activeTab && activeTab.schemaKey !== nextSchemaKey) {\n activeTab.schemaKey = nextSchemaKey;\n nextSchemaKey = undefined;\n storage.setTabState(state);\n setTimeout(() => storage.setTabState(state), 500);\n }\n return;\n }\n\n if (activeTab) {\n if (!activeTab.schemaKey) {\n if (lastTabAmount < tabs.length) {\n activeTab.schemaKey = activeSchema;\n storage.setTabState(state);\n }\n }\n\n const nextSchema = activeTab.schemaKey || \"storefront\";\n\n if (nextSchema !== activeSchema) {\n setActiveSchema(nextSchema);\n }\n }\n\n lastActiveTabIndex = activeTabIndex;\n lastTabAmount = tabs.length;\n }\n\n const plugins = [HISTORY_PLUGIN, explorerPlugin()];\n\n const props = {\n fetcher: createJsonFetcher,\n defaultEditorToolsVisibility: true,\n initialQuery,\n variables,\n schema: schema.value,\n plugins,\n onTabChange,\n };\n\n function toggleSelectedApi() {\n const activeKeyIndex = keys.indexOf(activeSchema);\n nextSchemaKey = keys[(activeKeyIndex + 1) % keys.length];\n if (nextSchemaKey) setActiveSchema(nextSchemaKey);\n }\n\n const CustomToolbar = React.createElement(GraphiQL.Toolbar, { key: \"Custom Toolbar\" }, [\n React.createElement(\n ToolbarButton,\n {\n key: \"api-wrapper\",\n onClick: toggleSelectedApi,\n label: \"Toggle between different API schemas\",\n },\n [\n React.createElement(\"div\", { key: \"icon\", style: { textAlign: \"center\" } }, [\n schema.icon,\n React.createElement(\n \"div\",\n {\n key: \"icon-label\",\n className: \"graphiql-api-toolbar-label\",\n },\n \"API\",\n ),\n ]),\n ],\n ),\n ]);\n\n const CustomLogo = React.createElement(GraphiQL.Logo, { key: \"Logo replacement\" }, [\n React.createElement(\n \"div\",\n {\n key: \"Logo wrapper\",\n style: { display: \"flex\", alignItems: \"center\" },\n },\n [\n React.createElement(\n \"div\",\n {\n key: \"api\",\n className: \"graphiql-logo\",\n style: { paddingRight: 0, whiteSpace: \"nowrap\" },\n },\n [schema.name],\n ),\n React.createElement(GraphiQL.Logo, { key: \"logo\" }),\n ],\n ),\n ]);\n\n return React.createElement(GraphiQL, props, [CustomToolbar, CustomLogo]);\n }\n\n const container = document.getElementById(\"graphiql\");\n const root = ReactDOM.createRoot(container);\n root.render(React.createElement(App));\n </script>\n </head>\n <body>\n <div id=\"graphiql\">\n <div class=\"placeholder\">Loading GraphiQL...</div>\n </div>\n </body>\n </html>\n `,\n { status: 200, headers: { \"content-type\": \"text/html\" } },\n );\n}\n"],"mappings":";;;;AAIA,MAAM,8BAA8B;AAMpC,MAAa,kBACX,KACA,EAAE,SAAS,kBAAkB,UAAU,sBACpC;AACH,KAAI,QAAQ,WAAW,SAAS,IAAI,aAAa,YAAa,QAAO;AAErE,QAAO,uBAAuB,kBAAkB,gBAAgB;;AAGlE,eAAe,uBACb,kBACA,iBACmB;CACnB,MAAM,UAUF,EAAE;AAIN,SAAQ,aAAa;EACnB,MAAM;EACN,YAAY;EACZ,QAAQ,GALU,iBAAiB,SAAS;EAM5C,MAAM;EACP;AAED,KAAI,iBAAiB,iBAAiB;EACpC,MAAM,EAAE,QAAQ,aAAa,cAAc,gBAAgB;AAE3D,MAAI;GAIF,MAAM,aAAsB,OAAM,MAHL,MAAM,WAAW,EAC5C,QAAQ,YAAY,QAAQ,4BAA4B,EACzD,CAAC,EAC+C,MAAM;AAEvD,OAAI,OAAO,eAAe,YAAY,eAAe,KACnD,SAAQ,sBAAsB;IAC5B,MAAM;IACN,OAAO;IACP,YAAY;IACZ;IACA;IACA,MAAM;IACP;UAEG;;CAKV,MAAM,UAAU;CAEhB,MAAM,OAAO,OAAO;AAEpB,QAAO,IAAI,SACT;;;;MAKmD,SAsFzB,KAAK,UAAU,QAAQ,CAAC,QAAQ,MAAM,UAAU,CA6JzE,EACD;EAAE,QAAQ;EAAK,SAAS,EAAE,gBAAgB,aAAa;EAAE,CAC1D"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { MCP_REQUEST_HEADER_ALLOWLIST } from "../../headers.mjs";
|
|
2
|
+
import { MCP_RE } from "../../url.mjs";
|
|
3
|
+
import { createProxyInterceptor } from "./proxy.mjs";
|
|
4
|
+
|
|
5
|
+
//#region src/core/request-routing/interceptors/mcp-proxy.ts
|
|
6
|
+
const JSON_RPC_INTERNAL_ERROR = -32603;
|
|
7
|
+
const handleMcpProxy = createProxyInterceptor({
|
|
8
|
+
match: MCP_RE,
|
|
9
|
+
requestHeaders: { allow: MCP_REQUEST_HEADER_ALLOWLIST },
|
|
10
|
+
formatError: (message) => ({
|
|
11
|
+
jsonrpc: "2.0",
|
|
12
|
+
error: {
|
|
13
|
+
code: JSON_RPC_INTERNAL_ERROR,
|
|
14
|
+
message
|
|
15
|
+
},
|
|
16
|
+
id: null
|
|
17
|
+
}),
|
|
18
|
+
scope: "mcp-proxy"
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
//#endregion
|
|
22
|
+
export { handleMcpProxy };
|
|
23
|
+
//# sourceMappingURL=mcp-proxy.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-proxy.mjs","names":[],"sources":["../../../../../src/core/request-routing/interceptors/mcp-proxy.ts"],"sourcesContent":["import { MCP_REQUEST_HEADER_ALLOWLIST } from \"../../headers\";\nimport { MCP_RE } from \"../../url\";\nimport { createProxyInterceptor } from \"./proxy\";\n\nconst JSON_RPC_INTERNAL_ERROR = -32603;\n\nexport const handleMcpProxy = createProxyInterceptor({\n match: MCP_RE,\n requestHeaders: { allow: MCP_REQUEST_HEADER_ALLOWLIST },\n formatError: (message) => ({\n jsonrpc: \"2.0\",\n error: { code: JSON_RPC_INTERNAL_ERROR, message },\n id: null,\n }),\n scope: \"mcp-proxy\",\n});\n"],"mappings":";;;;;AAIA,MAAM,0BAA0B;AAEhC,MAAa,iBAAiB,uBAAuB;CACnD,OAAO;CACP,gBAAgB,EAAE,OAAO,8BAA8B;CACvD,cAAc,aAAa;EACzB,SAAS;EACT,OAAO;GAAE,MAAM;GAAyB;GAAS;EACjD,IAAI;EACL;CACD,OAAO;CACR,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { getLogger } from "../../logging/logging.mjs";
|
|
2
|
+
import { extractHeaders } from "../../headers.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/core/request-routing/interceptors/proxy.ts
|
|
5
|
+
const PROXY_TIMEOUT_MS = 3e4;
|
|
6
|
+
function createProxyInterceptor(descriptor) {
|
|
7
|
+
const log = getLogger(descriptor.scope);
|
|
8
|
+
const formatError = descriptor.formatError ?? defaultFormatError;
|
|
9
|
+
return (url, options) => {
|
|
10
|
+
const { request, storefrontClient } = options;
|
|
11
|
+
if (!descriptor.match.test(url.pathname)) return null;
|
|
12
|
+
if (descriptor.methods && !descriptor.methods.includes(request.method)) return null;
|
|
13
|
+
let upstreamUrl;
|
|
14
|
+
let init;
|
|
15
|
+
try {
|
|
16
|
+
const upstreamPathname = descriptor.rewritePathname?.(url.pathname) ?? url.pathname;
|
|
17
|
+
upstreamUrl = new URL(upstreamPathname + url.search, storefrontClient.storeUrl);
|
|
18
|
+
const forwardedHeaders = createProxyRequestHeaders(descriptor, request);
|
|
19
|
+
options.requestContext.applyStorefrontRequestHeaders(forwardedHeaders);
|
|
20
|
+
descriptor.requestHeaders.prepare?.(forwardedHeaders, options, url);
|
|
21
|
+
init = {
|
|
22
|
+
method: request.method,
|
|
23
|
+
body: request.body,
|
|
24
|
+
headers: forwardedHeaders,
|
|
25
|
+
signal: AbortSignal.timeout(descriptor.timeoutMs ?? PROXY_TIMEOUT_MS),
|
|
26
|
+
redirect: descriptor.redirect ?? "manual"
|
|
27
|
+
};
|
|
28
|
+
if (request.body) init.duplex = "half";
|
|
29
|
+
} catch (error) {
|
|
30
|
+
log.error("request failed", { error });
|
|
31
|
+
return Promise.resolve(createProxyErrorResponse(error, 500, formatError));
|
|
32
|
+
}
|
|
33
|
+
return fetch(upstreamUrl, init).then((upstreamResponse) => {
|
|
34
|
+
const headers = createProxyResponseHeaders(upstreamResponse.headers);
|
|
35
|
+
descriptor.responseHeaders?.prepare?.(headers, options, url);
|
|
36
|
+
options.requestContext.consumeStorefrontResponseHeaders(headers);
|
|
37
|
+
return new Response(upstreamResponse.body, {
|
|
38
|
+
status: upstreamResponse.status,
|
|
39
|
+
statusText: upstreamResponse.statusText,
|
|
40
|
+
headers
|
|
41
|
+
});
|
|
42
|
+
}).catch((error) => {
|
|
43
|
+
log.error("request failed", { error });
|
|
44
|
+
return createProxyErrorResponse(error, 502, formatError);
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function defaultFormatError(message) {
|
|
49
|
+
return { error: message };
|
|
50
|
+
}
|
|
51
|
+
function createProxyErrorResponse(error, status, formatError) {
|
|
52
|
+
const message = error instanceof Error ? error.message : "Internal proxy error";
|
|
53
|
+
return new Response(JSON.stringify(formatError(message)), {
|
|
54
|
+
status,
|
|
55
|
+
headers: { "content-type": "application/json" }
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
function createProxyRequestHeaders(descriptor, request) {
|
|
59
|
+
const { allow, deny } = descriptor.requestHeaders;
|
|
60
|
+
const headers = allow ? new Headers(extractHeaders((key) => request.headers.get(key), allow)) : new Headers(request.headers);
|
|
61
|
+
for (const header of deny ?? []) headers.delete(header);
|
|
62
|
+
return headers;
|
|
63
|
+
}
|
|
64
|
+
function createProxyResponseHeaders(upstreamHeaders) {
|
|
65
|
+
const headers = new Headers(upstreamHeaders);
|
|
66
|
+
headers.delete("content-encoding");
|
|
67
|
+
headers.delete("content-length");
|
|
68
|
+
return headers;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
//#endregion
|
|
72
|
+
export { createProxyInterceptor, createProxyResponseHeaders };
|
|
73
|
+
//# sourceMappingURL=proxy.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy.mjs","names":[],"sources":["../../../../../src/core/request-routing/interceptors/proxy.ts"],"sourcesContent":["import { extractHeaders } from \"../../headers\";\nimport { getLogger } from \"../../logging\";\nimport type { HydrogenRouteInterceptor, HydrogenRoutesOptions } from \"../route-types\";\n\nconst PROXY_TIMEOUT_MS = 30_000;\n\ntype PrepareHeaders = (headers: Headers, options: HydrogenRoutesOptions, url: URL) => void;\n\ntype ProxyRequestHeaderOptions = (\n | { allow: readonly string[]; deny?: never }\n | { allow?: never; deny: readonly string[] }\n) & {\n prepare?: PrepareHeaders;\n};\n\ntype ProxyResponseHeaderOptions = {\n prepare?: PrepareHeaders;\n};\n\ntype ProxyDescriptor = {\n match: RegExp;\n methods?: readonly string[];\n formatError?: (message: string) => unknown;\n redirect?: RequestRedirect;\n scope: string;\n timeoutMs?: number;\n rewritePathname?: (pathname: string) => string;\n requestHeaders: ProxyRequestHeaderOptions;\n responseHeaders?: ProxyResponseHeaderOptions;\n};\n\nexport function createProxyInterceptor(descriptor: ProxyDescriptor): HydrogenRouteInterceptor {\n const log = getLogger(descriptor.scope);\n const formatError = descriptor.formatError ?? defaultFormatError;\n\n return (url, options) => {\n const { request, storefrontClient } = options;\n if (!descriptor.match.test(url.pathname)) return null;\n if (descriptor.methods && !descriptor.methods.includes(request.method)) return null;\n\n let upstreamUrl: URL;\n let init: RequestInit & { duplex?: \"half\" };\n try {\n const upstreamPathname = descriptor.rewritePathname?.(url.pathname) ?? url.pathname;\n upstreamUrl = new URL(upstreamPathname + url.search, storefrontClient.storeUrl);\n const forwardedHeaders = createProxyRequestHeaders(descriptor, request);\n options.requestContext.applyStorefrontRequestHeaders(forwardedHeaders);\n descriptor.requestHeaders.prepare?.(forwardedHeaders, options, url);\n\n init = {\n method: request.method,\n body: request.body,\n headers: forwardedHeaders,\n signal: AbortSignal.timeout(descriptor.timeoutMs ?? PROXY_TIMEOUT_MS),\n redirect: descriptor.redirect ?? \"manual\",\n };\n\n // Node's fetch requires this when forwarding a streaming request body.\n if (request.body) init.duplex = \"half\";\n } catch (error) {\n log.error(\"request failed\", { error });\n return Promise.resolve(createProxyErrorResponse(error, 500, formatError));\n }\n\n return fetch(upstreamUrl, init)\n .then((upstreamResponse) => {\n const headers = createProxyResponseHeaders(upstreamResponse.headers);\n descriptor.responseHeaders?.prepare?.(headers, options, url);\n options.requestContext.consumeStorefrontResponseHeaders(headers);\n\n return new Response(upstreamResponse.body, {\n status: upstreamResponse.status,\n statusText: upstreamResponse.statusText,\n headers,\n });\n })\n .catch((error) => {\n log.error(\"request failed\", { error });\n return createProxyErrorResponse(error, 502, formatError);\n });\n };\n}\n\nfunction defaultFormatError(message: string): { error: string } {\n return { error: message };\n}\n\nfunction createProxyErrorResponse(\n error: unknown,\n status: number,\n formatError: (message: string) => unknown,\n): Response {\n const message = error instanceof Error ? error.message : \"Internal proxy error\";\n return new Response(JSON.stringify(formatError(message)), {\n status,\n headers: { \"content-type\": \"application/json\" },\n });\n}\n\nfunction createProxyRequestHeaders(descriptor: ProxyDescriptor, request: Request): Headers {\n const { allow, deny } = descriptor.requestHeaders;\n const headers = allow\n ? new Headers(extractHeaders((key) => request.headers.get(key), allow))\n : new Headers(request.headers);\n for (const header of deny ?? []) headers.delete(header);\n return headers;\n}\n\nexport function createProxyResponseHeaders(upstreamHeaders: Headers): Headers {\n const headers = new Headers(upstreamHeaders);\n headers.delete(\"content-encoding\");\n headers.delete(\"content-length\");\n return headers;\n}\n"],"mappings":";;;;AAIA,MAAM,mBAAmB;AA2BzB,SAAgB,uBAAuB,YAAuD;CAC5F,MAAM,MAAM,UAAU,WAAW,MAAM;CACvC,MAAM,cAAc,WAAW,eAAe;AAE9C,SAAQ,KAAK,YAAY;EACvB,MAAM,EAAE,SAAS,qBAAqB;AACtC,MAAI,CAAC,WAAW,MAAM,KAAK,IAAI,SAAS,CAAE,QAAO;AACjD,MAAI,WAAW,WAAW,CAAC,WAAW,QAAQ,SAAS,QAAQ,OAAO,CAAE,QAAO;EAE/E,IAAI;EACJ,IAAI;AACJ,MAAI;GACF,MAAM,mBAAmB,WAAW,kBAAkB,IAAI,SAAS,IAAI,IAAI;AAC3E,iBAAc,IAAI,IAAI,mBAAmB,IAAI,QAAQ,iBAAiB,SAAS;GAC/E,MAAM,mBAAmB,0BAA0B,YAAY,QAAQ;AACvE,WAAQ,eAAe,8BAA8B,iBAAiB;AACtE,cAAW,eAAe,UAAU,kBAAkB,SAAS,IAAI;AAEnE,UAAO;IACL,QAAQ,QAAQ;IAChB,MAAM,QAAQ;IACd,SAAS;IACT,QAAQ,YAAY,QAAQ,WAAW,aAAa,iBAAiB;IACrE,UAAU,WAAW,YAAY;IAClC;AAGD,OAAI,QAAQ,KAAM,MAAK,SAAS;WACzB,OAAO;AACd,OAAI,MAAM,kBAAkB,EAAE,OAAO,CAAC;AACtC,UAAO,QAAQ,QAAQ,yBAAyB,OAAO,KAAK,YAAY,CAAC;;AAG3E,SAAO,MAAM,aAAa,KAAK,CAC5B,MAAM,qBAAqB;GAC1B,MAAM,UAAU,2BAA2B,iBAAiB,QAAQ;AACpE,cAAW,iBAAiB,UAAU,SAAS,SAAS,IAAI;AAC5D,WAAQ,eAAe,iCAAiC,QAAQ;AAEhE,UAAO,IAAI,SAAS,iBAAiB,MAAM;IACzC,QAAQ,iBAAiB;IACzB,YAAY,iBAAiB;IAC7B;IACD,CAAC;IACF,CACD,OAAO,UAAU;AAChB,OAAI,MAAM,kBAAkB,EAAE,OAAO,CAAC;AACtC,UAAO,yBAAyB,OAAO,KAAK,YAAY;IACxD;;;AAIR,SAAS,mBAAmB,SAAoC;AAC9D,QAAO,EAAE,OAAO,SAAS;;AAG3B,SAAS,yBACP,OACA,QACA,aACU;CACV,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,QAAO,IAAI,SAAS,KAAK,UAAU,YAAY,QAAQ,CAAC,EAAE;EACxD;EACA,SAAS,EAAE,gBAAgB,oBAAoB;EAChD,CAAC;;AAGJ,SAAS,0BAA0B,YAA6B,SAA2B;CACzF,MAAM,EAAE,OAAO,SAAS,WAAW;CACnC,MAAM,UAAU,QACZ,IAAI,QAAQ,gBAAgB,QAAQ,QAAQ,QAAQ,IAAI,IAAI,EAAE,MAAM,CAAC,GACrE,IAAI,QAAQ,QAAQ,QAAQ;AAChC,MAAK,MAAM,UAAU,QAAQ,EAAE,CAAE,SAAQ,OAAO,OAAO;AACvD,QAAO;;AAGT,SAAgB,2BAA2B,iBAAmC;CAC5E,MAAM,UAAU,IAAI,QAAQ,gBAAgB;AAC5C,SAAQ,OAAO,mBAAmB;AAClC,SAAQ,OAAO,iBAAiB;AAChC,QAAO"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
//#region src/core/request-routing/interceptors/query-param-redirect.ts
|
|
2
|
+
function handleQueryParamRedirect(request) {
|
|
3
|
+
const url = new URL(request.url);
|
|
4
|
+
const redirectTo = url.searchParams.get("return_to") || url.searchParams.get("redirect");
|
|
5
|
+
if (!redirectTo) return null;
|
|
6
|
+
if (!isSameOrigin(request.url, redirectTo)) return null;
|
|
7
|
+
return new Response(null, {
|
|
8
|
+
status: 301,
|
|
9
|
+
headers: { location: redirectTo }
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
function isSameOrigin(requestUrl, redirectUrl) {
|
|
13
|
+
try {
|
|
14
|
+
return new URL(requestUrl).origin === new URL(redirectUrl, requestUrl).origin;
|
|
15
|
+
} catch {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
//#endregion
|
|
21
|
+
export { handleQueryParamRedirect };
|
|
22
|
+
//# sourceMappingURL=query-param-redirect.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-param-redirect.mjs","names":[],"sources":["../../../../../src/core/request-routing/interceptors/query-param-redirect.ts"],"sourcesContent":["export function handleQueryParamRedirect(request: Request): Response | null {\n const url = new URL(request.url);\n const redirectTo = url.searchParams.get(\"return_to\") || url.searchParams.get(\"redirect\");\n\n if (!redirectTo) return null;\n if (!isSameOrigin(request.url, redirectTo)) return null;\n\n return new Response(null, {\n status: 301,\n headers: { location: redirectTo },\n });\n}\n\nfunction isSameOrigin(requestUrl: string, redirectUrl: string): boolean {\n try {\n return new URL(requestUrl).origin === new URL(redirectUrl, requestUrl).origin;\n } catch {\n return false;\n }\n}\n"],"mappings":";AAAA,SAAgB,yBAAyB,SAAmC;CAC1E,MAAM,MAAM,IAAI,IAAI,QAAQ,IAAI;CAChC,MAAM,aAAa,IAAI,aAAa,IAAI,YAAY,IAAI,IAAI,aAAa,IAAI,WAAW;AAExF,KAAI,CAAC,WAAY,QAAO;AACxB,KAAI,CAAC,aAAa,QAAQ,KAAK,WAAW,CAAE,QAAO;AAEnD,QAAO,IAAI,SAAS,MAAM;EACxB,QAAQ;EACR,SAAS,EAAE,UAAU,YAAY;EAClC,CAAC;;AAGJ,SAAS,aAAa,YAAoB,aAA8B;AACtE,KAAI;AACF,SAAO,IAAI,IAAI,WAAW,CAAC,WAAW,IAAI,IAAI,aAAa,WAAW,CAAC;SACjE;AACN,SAAO"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { SFAPI_REQUEST_HEADER_ALLOWLIST, STOREFRONT_BUYER_IP_HEADER, STOREFRONT_ID_HEADER } from "../../headers.mjs";
|
|
2
|
+
import { SFAPI_RE } from "../../url.mjs";
|
|
3
|
+
import { createProxyInterceptor } from "./proxy.mjs";
|
|
4
|
+
|
|
5
|
+
//#region src/core/request-routing/interceptors/sfapi-proxy.ts
|
|
6
|
+
const handleSfapiProxy = createProxyInterceptor({
|
|
7
|
+
match: SFAPI_RE,
|
|
8
|
+
requestHeaders: {
|
|
9
|
+
allow: SFAPI_REQUEST_HEADER_ALLOWLIST,
|
|
10
|
+
prepare: (headers, { requestContext, storefrontClient }) => {
|
|
11
|
+
headers.delete(STOREFRONT_ID_HEADER);
|
|
12
|
+
if (storefrontClient.storefrontId) headers.set(STOREFRONT_ID_HEADER, storefrontClient.storefrontId);
|
|
13
|
+
headers.delete(STOREFRONT_BUYER_IP_HEADER);
|
|
14
|
+
const { buyerIp } = requestContext;
|
|
15
|
+
if (buyerIp) {
|
|
16
|
+
headers.set(STOREFRONT_BUYER_IP_HEADER, buyerIp);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
if (storefrontClient.type === "private") throw new Error("requestContext.buyerIp is required for private Storefront API proxy requests");
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
scope: "sfapi-proxy"
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
//#endregion
|
|
26
|
+
export { handleSfapiProxy };
|
|
27
|
+
//# sourceMappingURL=sfapi-proxy.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sfapi-proxy.mjs","names":[],"sources":["../../../../../src/core/request-routing/interceptors/sfapi-proxy.ts"],"sourcesContent":["import {\n SFAPI_REQUEST_HEADER_ALLOWLIST,\n STOREFRONT_BUYER_IP_HEADER,\n STOREFRONT_ID_HEADER,\n} from \"../../headers\";\nimport { SFAPI_RE } from \"../../url\";\nimport { createProxyInterceptor } from \"./proxy\";\n\nexport const handleSfapiProxy = createProxyInterceptor({\n match: SFAPI_RE,\n requestHeaders: {\n allow: SFAPI_REQUEST_HEADER_ALLOWLIST,\n prepare: (headers, { requestContext, storefrontClient }) => {\n headers.delete(STOREFRONT_ID_HEADER);\n if (storefrontClient.storefrontId) {\n headers.set(STOREFRONT_ID_HEADER, storefrontClient.storefrontId);\n }\n\n headers.delete(STOREFRONT_BUYER_IP_HEADER);\n const { buyerIp } = requestContext;\n if (buyerIp) {\n headers.set(STOREFRONT_BUYER_IP_HEADER, buyerIp);\n return;\n }\n if (storefrontClient.type === \"private\") {\n throw new Error(\n \"requestContext.buyerIp is required for private Storefront API proxy requests\",\n );\n }\n },\n },\n scope: \"sfapi-proxy\",\n});\n"],"mappings":";;;;;AAQA,MAAa,mBAAmB,uBAAuB;CACrD,OAAO;CACP,gBAAgB;EACd,OAAO;EACP,UAAU,SAAS,EAAE,gBAAgB,uBAAuB;AAC1D,WAAQ,OAAO,qBAAqB;AACpC,OAAI,iBAAiB,aACnB,SAAQ,IAAI,sBAAsB,iBAAiB,aAAa;AAGlE,WAAQ,OAAO,2BAA2B;GAC1C,MAAM,EAAE,YAAY;AACpB,OAAI,SAAS;AACX,YAAQ,IAAI,4BAA4B,QAAQ;AAChD;;AAEF,OAAI,iBAAiB,SAAS,UAC5B,OAAM,IAAI,MACR,+EACD;;EAGN;CACD,OAAO;CACR,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { getStandardRouteTarget, isStandardRouteSelfRedirect } from "../../standard-routes/redirects.mjs";
|
|
2
|
+
import { createRedirectLocation, createRedirectResponse } from "./url-redirects.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/core/request-routing/interceptors/standard-routes.ts
|
|
5
|
+
function handleStandardRouteRedirects({ request, storefrontClient, routeTemplates }) {
|
|
6
|
+
const url = new URL(request.url);
|
|
7
|
+
const target = getStandardRouteTarget({
|
|
8
|
+
pathname: url.pathname,
|
|
9
|
+
pathPrefix: storefrontClient.requestContext.i18n.pathPrefix,
|
|
10
|
+
routeTemplates
|
|
11
|
+
});
|
|
12
|
+
if (!target) return null;
|
|
13
|
+
const location = createRedirectLocation(target, url.searchParams);
|
|
14
|
+
return isStandardRouteSelfRedirect(request.url, location) ? null : createRedirectResponse(location);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
//#endregion
|
|
18
|
+
export { handleStandardRouteRedirects };
|
|
19
|
+
//# sourceMappingURL=standard-routes.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"standard-routes.mjs","names":[],"sources":["../../../../../src/core/request-routing/interceptors/standard-routes.ts"],"sourcesContent":["import type { StorefrontClient } from \"../../../client\";\nimport {\n getStandardRouteTarget,\n isStandardRouteSelfRedirect,\n type ShopifyRouteTemplates,\n} from \"../../standard-routes/index\";\nimport { createRedirectLocation, createRedirectResponse } from \"./url-redirects\";\n\nexport function handleStandardRouteRedirects({\n request,\n storefrontClient,\n routeTemplates,\n}: {\n request: Request;\n storefrontClient: StorefrontClient;\n routeTemplates: ShopifyRouteTemplates;\n}): Response | null {\n const url = new URL(request.url);\n const target = getStandardRouteTarget({\n pathname: url.pathname,\n pathPrefix: storefrontClient.requestContext.i18n.pathPrefix,\n routeTemplates,\n });\n\n if (!target) return null;\n\n const location = createRedirectLocation(target, url.searchParams);\n\n return isStandardRouteSelfRedirect(request.url, location)\n ? null\n : createRedirectResponse(location);\n}\n"],"mappings":";;;;AAQA,SAAgB,6BAA6B,EAC3C,SACA,kBACA,kBAKkB;CAClB,MAAM,MAAM,IAAI,IAAI,QAAQ,IAAI;CAChC,MAAM,SAAS,uBAAuB;EACpC,UAAU,IAAI;EACd,YAAY,iBAAiB,eAAe,KAAK;EACjD;EACD,CAAC;AAEF,KAAI,CAAC,OAAQ,QAAO;CAEpB,MAAM,WAAW,uBAAuB,QAAQ,IAAI,aAAa;AAEjE,QAAO,4BAA4B,QAAQ,KAAK,SAAS,GACrD,OACA,uBAAuB,SAAS"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { gql } from "../../../graphql/graphql.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/core/request-routing/interceptors/url-redirects.ts
|
|
4
|
+
const REDIRECT_QUERY = gql(`query redirects($query:String){urlRedirects(first:1 query:$query){edges{node{target}}}}`);
|
|
5
|
+
const PLACEHOLDER_BASE = "https://0.0.0.0";
|
|
6
|
+
async function handleUrlRedirects({ request, storefrontClient }) {
|
|
7
|
+
const { pathname, searchParams } = new URL(request.url);
|
|
8
|
+
const queryPath = pathname.toLowerCase().replace(/\/+$/, "");
|
|
9
|
+
const target = (await storefrontClient.graphql(REDIRECT_QUERY, { variables: { query: `path:${queryPath}` } })).data?.urlRedirects?.edges[0]?.node.target;
|
|
10
|
+
if (!target) return null;
|
|
11
|
+
return createRedirectResponse(createRedirectLocation(target, searchParams));
|
|
12
|
+
}
|
|
13
|
+
function createRedirectLocation(location, searchParams) {
|
|
14
|
+
const url = new URL(location, PLACEHOLDER_BASE);
|
|
15
|
+
for (const [key, value] of searchParams) url.searchParams.append(key, value);
|
|
16
|
+
return url.toString().replace(PLACEHOLDER_BASE, "");
|
|
17
|
+
}
|
|
18
|
+
function createRedirectResponse(location, status = 301) {
|
|
19
|
+
return new Response(null, {
|
|
20
|
+
status,
|
|
21
|
+
headers: { location }
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
//#endregion
|
|
26
|
+
export { createRedirectLocation, createRedirectResponse, handleUrlRedirects };
|
|
27
|
+
//# sourceMappingURL=url-redirects.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"url-redirects.mjs","names":[],"sources":["../../../../../src/core/request-routing/interceptors/url-redirects.ts"],"sourcesContent":["import { gql } from \"../../../graphql\";\nimport type { RedirectOptions } from \"../handle-shopify-redirects\";\n\ntype UrlRedirectOptions = Pick<RedirectOptions, \"request\" | \"storefrontClient\">;\n\nconst REDIRECT_QUERY = gql(`\n query redirects($query: String) {\n urlRedirects(first: 1, query: $query) {\n edges {\n node {\n target\n }\n }\n }\n }\n`);\n\n// Used as a base for `new URL()` when constructing relative redirect URLs.\n// Stripped from the output — only needed because `new URL` requires a base for relative paths.\nconst PLACEHOLDER_BASE = \"https://0.0.0.0\";\n\nexport async function handleUrlRedirects({\n request,\n storefrontClient,\n}: UrlRedirectOptions): Promise<Response | null> {\n const url = new URL(request.url);\n const { pathname, searchParams } = url;\n\n const queryPath = pathname.toLowerCase().replace(/\\/+$/, \"\");\n const result = await storefrontClient.graphql(REDIRECT_QUERY, {\n variables: { query: `path:${queryPath}` },\n });\n\n const target = result.data?.urlRedirects?.edges[0]?.node.target;\n if (!target) return null;\n\n return createRedirectResponse(createRedirectLocation(target, searchParams));\n}\n\nexport function createRedirectLocation(location: string, searchParams: URLSearchParams): string {\n const url = new URL(location, PLACEHOLDER_BASE);\n\n for (const [key, value] of searchParams) {\n url.searchParams.append(key, value);\n }\n\n return url.toString().replace(PLACEHOLDER_BASE, \"\");\n}\n\nexport function createRedirectResponse(location: string, status: number = 301): Response {\n return new Response(null, {\n status,\n headers: { location },\n });\n}\n"],"mappings":";;;AAKA,MAAA,iBAAA,IAAA,0FAUA;AAIA,MAAA,mBAAA;AAEA,eAAA,mBAAA,EACA,SACA,oBACA;CAEA,MAAA,EAAA,UAAA,iBAAA,IADA,IAAA,QAAA,IACA;CAEA,MAAA,YAAA,SAAA,aAAA,CAAA,QAAA,QAAA,GAAA;CAKA,MAAA,UAAA,MAJA,iBAAA,QAAA,gBAAA,EACA,WAAA,EAAA,OAAA,QAAA,aAAA,EACA,CAAA,EAEA,MAAA,cAAA,MAAA,IAAA,KAAA;AACA,KAAA,CAAA,OAAA,QAAA;AAEA,QAAA,uBAAA,uBAAA,QAAA,aAAA,CAAA;;AAGA,SAAA,uBAAA,UAAA,cAAA;CACA,MAAA,MAAA,IAAA,IAAA,UAAA,iBAAA;AAEA,MAAA,MAAA,CAAA,KAAA,UAAA,aACA,KAAA,aAAA,OAAA,KAAA,MAAA;AAGA,QAAA,IAAA,UAAA,CAAA,QAAA,kBAAA,GAAA;;AAGA,SAAA,uBAAA,UAAA,SAAA,KAAA;AACA,QAAA,IAAA,SAAA,MAAA;EACA;EACA,SAAA,EAAA,UAAA;EACA,CAAA"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { PROXY_REQUEST_HEADER_DENYLIST } from "../../headers.mjs";
|
|
2
|
+
import { WELL_KNOWN_RE } from "../../url.mjs";
|
|
3
|
+
import { createProxyInterceptor } from "./proxy.mjs";
|
|
4
|
+
|
|
5
|
+
//#region src/core/request-routing/interceptors/well-known.ts
|
|
6
|
+
/**
|
|
7
|
+
* Proxies allowlisted Shopify `.well-known` resources through the headless
|
|
8
|
+
* storefront origin to the Online Store, so first-party services (Apple Pay
|
|
9
|
+
* domain verification, Frontend Event Collector ingress) behave the same way
|
|
10
|
+
* they do on Online Store storefronts. See {@link WELL_KNOWN_RE} for the
|
|
11
|
+
* allowlist.
|
|
12
|
+
*/
|
|
13
|
+
const handleWellKnownProxy = createProxyInterceptor({
|
|
14
|
+
match: WELL_KNOWN_RE,
|
|
15
|
+
requestHeaders: { deny: PROXY_REQUEST_HEADER_DENYLIST },
|
|
16
|
+
redirect: "follow",
|
|
17
|
+
scope: "well-known-proxy"
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
//#endregion
|
|
21
|
+
export { handleWellKnownProxy };
|
|
22
|
+
//# sourceMappingURL=well-known.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"well-known.mjs","names":[],"sources":["../../../../../src/core/request-routing/interceptors/well-known.ts"],"sourcesContent":["import { PROXY_REQUEST_HEADER_DENYLIST } from \"../../headers\";\nimport { WELL_KNOWN_RE } from \"../../url\";\nimport { createProxyInterceptor } from \"./proxy\";\n\n/**\n * Proxies allowlisted Shopify `.well-known` resources through the headless\n * storefront origin to the Online Store, so first-party services (Apple Pay\n * domain verification, Frontend Event Collector ingress) behave the same way\n * they do on Online Store storefronts. See {@link WELL_KNOWN_RE} for the\n * allowlist.\n */\nexport const handleWellKnownProxy = createProxyInterceptor({\n match: WELL_KNOWN_RE,\n requestHeaders: { deny: PROXY_REQUEST_HEADER_DENYLIST },\n redirect: \"follow\",\n scope: \"well-known-proxy\",\n});\n"],"mappings":";;;;;;;;;;;;AAWA,MAAa,uBAAuB,uBAAuB;CACzD,OAAO;CACP,gBAAgB,EAAE,MAAM,+BAA+B;CACvD,UAAU;CACV,OAAO;CACR,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { CallableRouteHandler, ShopifyRedirectStatus, ShopifyRouteError, ShopifyRouteErrorResult, ShopifyRouteHandler, ShopifyRouteHandlerContext, ShopifyRouteHandlerGroup, ShopifyRouteHandlerResult, ShopifyRouteJsonResult, ShopifyRouteRedirectResult, ShopifyRouteSessionManager } from "./route-types.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/core/request-routing/registered-routes.d.ts
|
|
4
|
+
declare function createShopifyRouteHandler<const TPathname extends string, const TMethod extends string>(pathname: TPathname, method: TMethod, handler: (context: ShopifyRouteHandlerContext) => Promise<ShopifyRouteHandlerResult>): ShopifyRouteHandler<TPathname, TMethod>;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { createShopifyRouteHandler };
|
|
7
|
+
//# sourceMappingURL=registered-routes.d.mts.map
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
//#region src/core/request-routing/registered-routes.ts
|
|
2
|
+
const HTTP_OK_STATUS = 200;
|
|
3
|
+
const HTTP_SEE_OTHER_STATUS = 303;
|
|
4
|
+
const HTTP_METHOD_NOT_ALLOWED_STATUS = 405;
|
|
5
|
+
const HTTP_BAD_REQUEST_STATUS = 400;
|
|
6
|
+
const VALID_REDIRECT_STATUSES = [
|
|
7
|
+
301,
|
|
8
|
+
302,
|
|
9
|
+
303,
|
|
10
|
+
307,
|
|
11
|
+
308
|
|
12
|
+
];
|
|
13
|
+
function createShopifyRouteHandler(pathname, method, handler) {
|
|
14
|
+
return createCallableRouteHandler(pathname, method, handler);
|
|
15
|
+
}
|
|
16
|
+
function createCallableRouteHandler(pathname, method, handler) {
|
|
17
|
+
return Object.assign(handler, {
|
|
18
|
+
pathname,
|
|
19
|
+
method
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
const handleShopifyRouteHandlers = (url, { request, sessionManager, storefrontClient, requestContext, handlers = [] }) => {
|
|
23
|
+
const context = {
|
|
24
|
+
request,
|
|
25
|
+
sessionManager,
|
|
26
|
+
storefrontClient,
|
|
27
|
+
requestContext
|
|
28
|
+
};
|
|
29
|
+
const routeHandlers = handlers.flatMap((group) => Object.values(group));
|
|
30
|
+
if (routeHandlers.length === 0) return null;
|
|
31
|
+
const pathMatches = routeHandlers.filter((entry) => entry.pathname === url.pathname);
|
|
32
|
+
if (pathMatches.length === 0) return null;
|
|
33
|
+
const match = pathMatches.find((candidate) => candidate.method === request.method);
|
|
34
|
+
if (!match) return Promise.resolve(new Response("Method Not Allowed", { status: HTTP_METHOD_NOT_ALLOWED_STATUS }));
|
|
35
|
+
return match(context).then((result) => createShopifyRouteResponse(result, request));
|
|
36
|
+
};
|
|
37
|
+
function createShopifyRouteResponse(result, request) {
|
|
38
|
+
if (result.type === "redirect") {
|
|
39
|
+
const headers = new Headers(result.headers);
|
|
40
|
+
headers.set("location", resolveRedirectLocation(result.location, request));
|
|
41
|
+
return new Response(null, {
|
|
42
|
+
status: getRedirectStatus(result.status),
|
|
43
|
+
headers
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
if (result.type === "error") {
|
|
47
|
+
const headers = new Headers(result.headers);
|
|
48
|
+
headers.set("content-type", "application/json");
|
|
49
|
+
return new Response(JSON.stringify({ error: result.error }), {
|
|
50
|
+
status: result.status ?? HTTP_BAD_REQUEST_STATUS,
|
|
51
|
+
headers
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
const headers = new Headers(result.headers);
|
|
55
|
+
headers.set("content-type", "application/json");
|
|
56
|
+
return new Response(JSON.stringify(result.data), {
|
|
57
|
+
status: HTTP_OK_STATUS,
|
|
58
|
+
headers
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
function getRedirectStatus(status) {
|
|
62
|
+
const redirectStatus = status ?? HTTP_SEE_OTHER_STATUS;
|
|
63
|
+
if (VALID_REDIRECT_STATUSES.some((validStatus) => validStatus === redirectStatus)) return redirectStatus;
|
|
64
|
+
throw new Error(`Invalid Shopify route redirect status ${redirectStatus}. Expected one of: ${VALID_REDIRECT_STATUSES.join(", ")}.`);
|
|
65
|
+
}
|
|
66
|
+
function resolveRedirectLocation(location, request) {
|
|
67
|
+
return new URL(location, new URL(request.url).origin).toString();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
//#endregion
|
|
71
|
+
export { createCallableRouteHandler, createShopifyRouteHandler, handleShopifyRouteHandlers };
|
|
72
|
+
//# sourceMappingURL=registered-routes.mjs.map
|