@shopify/hydrogen 2026.10.0-preview.4 → 2026.10.0
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/dist/cli/index.mjs +23 -12
- package/dist/client/client.d.mts +18 -15
- package/dist/client/client.mjs +8 -3
- package/dist/client/client.mjs.map +1 -1
- package/dist/client/errors.d.mts +35 -13
- package/dist/client/errors.mjs +23 -13
- package/dist/client/errors.mjs.map +1 -1
- package/dist/client/types.d.mts +140 -90
- package/dist/core/analytics/cart-tracker.d.mts +19 -10
- package/dist/core/analytics/cart-tracker.mjs +18 -10
- package/dist/core/analytics/cart-tracker.mjs.map +1 -1
- package/dist/core/analytics/events.d.mts +17 -11
- package/dist/core/analytics/events.mjs +13 -4
- package/dist/core/analytics/events.mjs.map +1 -1
- package/dist/core/analytics/types.d.mts +207 -118
- package/dist/core/analytics/utils/flatten-connection.d.mts +11 -9
- package/dist/core/analytics/utils/flatten-connection.mjs +7 -6
- package/dist/core/analytics/utils/flatten-connection.mjs.map +1 -1
- package/dist/core/cache/fetch-with-cache.d.mts +24 -4
- package/dist/core/cache/fetch-with-cache.mjs +17 -2
- package/dist/core/cache/fetch-with-cache.mjs.map +1 -1
- package/dist/core/cache/key.d.mts +2 -0
- package/dist/core/cache/key.mjs.map +1 -1
- package/dist/core/cache/run-with-cache.d.mts +56 -8
- package/dist/core/cache/run-with-cache.mjs +17 -6
- package/dist/core/cache/run-with-cache.mjs.map +1 -1
- package/dist/core/cache/store.d.mts +8 -6
- package/dist/core/cache/store.mjs.map +1 -1
- package/dist/core/cache/strategies.d.mts +27 -2
- package/dist/core/cache/strategies.mjs +6 -0
- package/dist/core/cache/strategies.mjs.map +1 -1
- package/dist/core/cart/actions.d.mts +37 -30
- package/dist/core/cart/actions.mjs +21 -9
- package/dist/core/cart/actions.mjs.map +1 -1
- package/dist/core/cart/attach-quantity-input.d.mts +8 -7
- package/dist/core/cart/attach-quantity-input.mjs +8 -7
- package/dist/core/cart/attach-quantity-input.mjs.map +1 -1
- package/dist/core/cart/buyer-identity-sync.d.mts +7 -6
- package/dist/core/cart/buyer-identity-sync.mjs.map +1 -1
- package/dist/core/cart/cart.d.mts +59 -46
- package/dist/core/cart/cart.mjs +46 -29
- package/dist/core/cart/cart.mjs.map +1 -1
- package/dist/core/cart/cookie.d.mts +8 -4
- package/dist/core/cart/cookie.mjs +8 -4
- package/dist/core/cart/cookie.mjs.map +1 -1
- package/dist/core/cart/form.d.mts +34 -20
- package/dist/core/cart/form.mjs +6 -4
- package/dist/core/cart/form.mjs.map +1 -1
- package/dist/core/cart/get-cart.d.mts +27 -15
- package/dist/core/cart/get-cart.mjs +13 -8
- package/dist/core/cart/get-cart.mjs.map +1 -1
- package/dist/core/cart/quantity.d.mts +16 -5
- package/dist/core/cart/quantity.mjs +16 -5
- package/dist/core/cart/quantity.mjs.map +1 -1
- package/dist/core/cart/queries.d.mts +25 -19
- package/dist/core/cart/queries.mjs +15 -1
- package/dist/core/cart/queries.mjs.map +1 -1
- package/dist/core/cart/server-handlers.d.mts +82 -45
- package/dist/core/cart/server-handlers.mjs +4 -0
- package/dist/core/cart/server-handlers.mjs.map +1 -1
- package/dist/core/cart/state.d.mts +110 -64
- package/dist/core/cart/state.mjs +24 -6
- package/dist/core/cart/state.mjs.map +1 -1
- package/dist/core/collection/collection.d.mts +52 -53
- package/dist/core/collection/collection.mjs +5 -3
- package/dist/core/collection/collection.mjs.map +1 -1
- package/dist/core/collection/reconciler.d.mts +23 -16
- package/dist/core/collection/reconciler.mjs +8 -4
- package/dist/core/collection/reconciler.mjs.map +1 -1
- package/dist/core/collection/state.d.mts +31 -26
- package/dist/core/collection/state.mjs +4 -3
- package/dist/core/collection/state.mjs.map +1 -1
- package/dist/core/collection/url.d.mts +70 -29
- package/dist/core/collection/url.mjs +63 -25
- package/dist/core/collection/url.mjs.map +1 -1
- package/dist/core/constants.d.mts +1 -0
- package/dist/core/constants.mjs +1 -0
- package/dist/core/constants.mjs.map +1 -1
- package/dist/core/logging/logging.d.mts +14 -8
- package/dist/core/logging/logging.mjs +15 -10
- package/dist/core/logging/logging.mjs.map +1 -1
- package/dist/core/logging/types.d.mts +28 -11
- package/dist/core/logging/types.mjs.map +1 -1
- package/dist/core/money/format.d.mts +6 -4
- package/dist/core/money/format.mjs +19 -9
- package/dist/core/money/format.mjs.map +1 -1
- package/dist/core/money/types.d.mts +41 -25
- package/dist/core/predictive-search/form.d.mts +37 -7
- package/dist/core/predictive-search/form.mjs +21 -3
- package/dist/core/predictive-search/form.mjs.map +1 -1
- package/dist/core/predictive-search/queries.d.mts +18 -30
- package/dist/core/predictive-search/queries.mjs +7 -3
- package/dist/core/predictive-search/queries.mjs.map +1 -1
- package/dist/core/predictive-search/search.d.mts +25 -27
- package/dist/core/predictive-search/search.mjs +20 -19
- package/dist/core/predictive-search/search.mjs.map +1 -1
- package/dist/core/predictive-search/server-handlers.d.mts +25 -26
- package/dist/core/predictive-search/server-handlers.mjs +4 -0
- package/dist/core/predictive-search/server-handlers.mjs.map +1 -1
- package/dist/core/predictive-search/store.d.mts +65 -24
- package/dist/core/predictive-search/store.mjs +12 -1
- package/dist/core/predictive-search/store.mjs.map +1 -1
- package/dist/core/predictive-search/url.d.mts +36 -37
- package/dist/core/predictive-search/url.mjs +14 -6
- package/dist/core/predictive-search/url.mjs.map +1 -1
- package/dist/core/product/form.d.mts +63 -16
- package/dist/core/product/form.mjs +8 -2
- package/dist/core/product/form.mjs.map +1 -1
- package/dist/core/product/options.d.mts +8 -10
- package/dist/core/product/options.mjs +8 -10
- package/dist/core/product/options.mjs.map +1 -1
- package/dist/core/product/product-form.d.mts +77 -29
- package/dist/core/product/product-form.mjs +32 -10
- package/dist/core/product/product-form.mjs.map +1 -1
- package/dist/core/product/state.d.mts +55 -32
- package/dist/core/product/url.d.mts +19 -13
- package/dist/core/product/url.mjs +10 -10
- package/dist/core/product/url.mjs.map +1 -1
- package/dist/core/request-context.d.mts +77 -19
- package/dist/core/request-context.mjs +5 -1
- package/dist/core/request-context.mjs.map +1 -1
- package/dist/core/request-routing/handle-shopify-redirects.d.mts +12 -4
- package/dist/core/request-routing/handle-shopify-redirects.mjs +9 -2
- package/dist/core/request-routing/handle-shopify-redirects.mjs.map +1 -1
- package/dist/core/request-routing/handle-shopify-routes.d.mts +5 -5
- package/dist/core/request-routing/handle-shopify-routes.mjs +7 -5
- package/dist/core/request-routing/handle-shopify-routes.mjs.map +1 -1
- package/dist/core/request-routing/interceptors/proxy.mjs +79 -43
- package/dist/core/request-routing/interceptors/proxy.mjs.map +1 -1
- package/dist/core/request-routing/interceptors/ucp-profile-proxy.mjs +69 -0
- package/dist/core/request-routing/interceptors/ucp-profile-proxy.mjs.map +1 -0
- package/dist/core/request-routing/interceptors/url-redirects.mjs +6 -1
- package/dist/core/request-routing/interceptors/url-redirects.mjs.map +1 -1
- package/dist/core/request-routing/interceptors/well-known.mjs +1 -1
- package/dist/core/request-routing/interceptors/well-known.mjs.map +1 -1
- package/dist/core/request-routing/registered-routes.d.mts +12 -0
- package/dist/core/request-routing/registered-routes.mjs +12 -0
- package/dist/core/request-routing/registered-routes.mjs.map +1 -1
- package/dist/core/request-routing/route-types.d.mts +43 -18
- package/dist/core/shop-pay/shop-pay.d.mts +71 -35
- package/dist/core/shop-pay/shop-pay.mjs +36 -10
- package/dist/core/shop-pay/shop-pay.mjs.map +1 -1
- package/dist/core/shopify-scripts/index.d.mts +15 -5
- package/dist/core/shopify-scripts/index.mjs +15 -5
- package/dist/core/shopify-scripts/index.mjs.map +1 -1
- package/dist/core/shopify-scripts/initialize.d.mts +12 -4
- package/dist/core/shopify-scripts/initialize.mjs +12 -4
- package/dist/core/shopify-scripts/initialize.mjs.map +1 -1
- package/dist/core/shopify-scripts/types.d.mts +58 -25
- package/dist/core/standard-routes/build.d.mts +11 -12
- package/dist/core/standard-routes/build.mjs +11 -12
- package/dist/core/standard-routes/build.mjs.map +1 -1
- package/dist/core/standard-routes/types.d.mts +30 -24
- package/dist/core/url.mjs +2 -1
- package/dist/core/url.mjs.map +1 -1
- package/dist/customer-account/client.d.mts +36 -69
- package/dist/customer-account/client.mjs +7 -8
- package/dist/customer-account/client.mjs.map +1 -1
- package/dist/customer-account/errors.d.mts +45 -36
- package/dist/customer-account/errors.mjs +21 -36
- package/dist/customer-account/errors.mjs.map +1 -1
- package/dist/customer-account/graphql.d.mts +11 -23
- package/dist/customer-account/graphql.mjs +3 -9
- package/dist/customer-account/graphql.mjs.map +1 -1
- package/dist/customer-account/session.d.mts +130 -100
- package/dist/customer-account/session.mjs +32 -10
- package/dist/customer-account/session.mjs.map +1 -1
- package/dist/customer-account/type-resolver.d.mts +7 -8
- package/dist/development/client/client.d.mts +18 -15
- package/dist/development/client/client.mjs +8 -3
- package/dist/development/client/client.mjs.map +1 -1
- package/dist/development/client/errors.d.mts +35 -13
- package/dist/development/client/errors.mjs +23 -13
- package/dist/development/client/errors.mjs.map +1 -1
- package/dist/development/client/types.d.mts +140 -90
- package/dist/development/core/analytics/cart-tracker.d.mts +19 -10
- package/dist/development/core/analytics/cart-tracker.mjs +18 -10
- package/dist/development/core/analytics/cart-tracker.mjs.map +1 -1
- package/dist/development/core/analytics/events.d.mts +17 -11
- package/dist/development/core/analytics/events.mjs +13 -4
- package/dist/development/core/analytics/events.mjs.map +1 -1
- package/dist/development/core/analytics/types.d.mts +207 -118
- package/dist/development/core/analytics/utils/flatten-connection.d.mts +11 -9
- package/dist/development/core/analytics/utils/flatten-connection.mjs +7 -6
- package/dist/development/core/analytics/utils/flatten-connection.mjs.map +1 -1
- package/dist/development/core/cache/fetch-with-cache.d.mts +24 -4
- package/dist/development/core/cache/fetch-with-cache.mjs +17 -2
- package/dist/development/core/cache/fetch-with-cache.mjs.map +1 -1
- package/dist/development/core/cache/key.d.mts +2 -0
- package/dist/development/core/cache/key.mjs.map +1 -1
- package/dist/development/core/cache/run-with-cache.d.mts +56 -8
- package/dist/development/core/cache/run-with-cache.mjs +17 -6
- package/dist/development/core/cache/run-with-cache.mjs.map +1 -1
- package/dist/development/core/cache/store.d.mts +8 -6
- package/dist/development/core/cache/store.mjs.map +1 -1
- package/dist/development/core/cache/strategies.d.mts +27 -2
- package/dist/development/core/cache/strategies.mjs +6 -0
- package/dist/development/core/cache/strategies.mjs.map +1 -1
- package/dist/development/core/cart/actions.d.mts +37 -30
- package/dist/development/core/cart/actions.mjs +21 -9
- package/dist/development/core/cart/actions.mjs.map +1 -1
- package/dist/development/core/cart/attach-quantity-input.d.mts +8 -7
- package/dist/development/core/cart/attach-quantity-input.mjs +8 -7
- package/dist/development/core/cart/attach-quantity-input.mjs.map +1 -1
- package/dist/development/core/cart/buyer-identity-sync.d.mts +6 -5
- package/dist/development/core/cart/buyer-identity-sync.mjs.map +1 -1
- package/dist/development/core/cart/cart.d.mts +59 -46
- package/dist/development/core/cart/cart.mjs +46 -29
- package/dist/development/core/cart/cart.mjs.map +1 -1
- package/dist/development/core/cart/cookie.d.mts +8 -4
- package/dist/development/core/cart/cookie.mjs +8 -4
- package/dist/development/core/cart/cookie.mjs.map +1 -1
- package/dist/development/core/cart/form.d.mts +34 -20
- package/dist/development/core/cart/form.mjs +6 -4
- package/dist/development/core/cart/form.mjs.map +1 -1
- package/dist/development/core/cart/get-cart.d.mts +27 -15
- package/dist/development/core/cart/get-cart.mjs +13 -8
- package/dist/development/core/cart/get-cart.mjs.map +1 -1
- package/dist/development/core/cart/quantity.d.mts +16 -5
- package/dist/development/core/cart/quantity.mjs +16 -5
- package/dist/development/core/cart/quantity.mjs.map +1 -1
- package/dist/development/core/cart/queries.d.mts +25 -19
- package/dist/development/core/cart/queries.mjs +15 -1
- package/dist/development/core/cart/queries.mjs.map +1 -1
- package/dist/development/core/cart/server-handlers.d.mts +82 -45
- package/dist/development/core/cart/server-handlers.mjs +4 -0
- package/dist/development/core/cart/server-handlers.mjs.map +1 -1
- package/dist/development/core/cart/state.d.mts +110 -64
- package/dist/development/core/cart/state.mjs +24 -6
- package/dist/development/core/cart/state.mjs.map +1 -1
- package/dist/development/core/collection/collection.d.mts +52 -53
- package/dist/development/core/collection/collection.mjs +5 -3
- package/dist/development/core/collection/collection.mjs.map +1 -1
- package/dist/development/core/collection/reconciler.d.mts +23 -16
- package/dist/development/core/collection/reconciler.mjs +8 -4
- package/dist/development/core/collection/reconciler.mjs.map +1 -1
- package/dist/development/core/collection/state.d.mts +31 -26
- package/dist/development/core/collection/state.mjs +4 -3
- package/dist/development/core/collection/state.mjs.map +1 -1
- package/dist/development/core/collection/url.d.mts +70 -29
- package/dist/development/core/collection/url.mjs +63 -25
- package/dist/development/core/collection/url.mjs.map +1 -1
- package/dist/development/core/constants.mjs.map +1 -1
- package/dist/development/core/logging/logging.d.mts +14 -8
- package/dist/development/core/logging/logging.mjs +15 -10
- package/dist/development/core/logging/logging.mjs.map +1 -1
- package/dist/development/core/logging/types.d.mts +28 -11
- package/dist/development/core/logging/types.mjs.map +1 -1
- package/dist/development/core/money/format.d.mts +6 -4
- package/dist/development/core/money/format.mjs +19 -9
- package/dist/development/core/money/format.mjs.map +1 -1
- package/dist/development/core/money/types.d.mts +41 -25
- package/dist/development/core/predictive-search/form.d.mts +37 -7
- package/dist/development/core/predictive-search/form.mjs +21 -3
- package/dist/development/core/predictive-search/form.mjs.map +1 -1
- package/dist/development/core/predictive-search/queries.d.mts +18 -30
- package/dist/development/core/predictive-search/queries.mjs +7 -3
- package/dist/development/core/predictive-search/queries.mjs.map +1 -1
- package/dist/development/core/predictive-search/search.d.mts +25 -27
- package/dist/development/core/predictive-search/search.mjs +20 -19
- package/dist/development/core/predictive-search/search.mjs.map +1 -1
- package/dist/development/core/predictive-search/server-handlers.d.mts +25 -26
- package/dist/development/core/predictive-search/server-handlers.mjs +4 -0
- package/dist/development/core/predictive-search/server-handlers.mjs.map +1 -1
- package/dist/development/core/predictive-search/store.d.mts +65 -24
- package/dist/development/core/predictive-search/store.mjs +12 -1
- package/dist/development/core/predictive-search/store.mjs.map +1 -1
- package/dist/development/core/predictive-search/url.d.mts +36 -37
- package/dist/development/core/predictive-search/url.mjs +14 -6
- package/dist/development/core/predictive-search/url.mjs.map +1 -1
- package/dist/development/core/product/form.d.mts +63 -16
- package/dist/development/core/product/form.mjs +8 -2
- package/dist/development/core/product/form.mjs.map +1 -1
- package/dist/development/core/product/options.d.mts +8 -10
- package/dist/development/core/product/options.mjs +8 -10
- package/dist/development/core/product/options.mjs.map +1 -1
- package/dist/development/core/product/product-form.d.mts +77 -29
- package/dist/development/core/product/product-form.mjs +32 -10
- package/dist/development/core/product/product-form.mjs.map +1 -1
- package/dist/development/core/product/state.d.mts +55 -32
- package/dist/development/core/product/url.d.mts +19 -13
- package/dist/development/core/product/url.mjs +10 -10
- package/dist/development/core/product/url.mjs.map +1 -1
- package/dist/development/core/request-context.d.mts +77 -19
- package/dist/development/core/request-context.mjs +5 -1
- package/dist/development/core/request-context.mjs.map +1 -1
- package/dist/development/core/request-routing/handle-shopify-redirects.d.mts +12 -4
- package/dist/development/core/request-routing/handle-shopify-redirects.mjs +9 -2
- package/dist/development/core/request-routing/handle-shopify-redirects.mjs.map +1 -1
- package/dist/development/core/request-routing/handle-shopify-routes.development.d.mts +9 -1
- package/dist/development/core/request-routing/handle-shopify-routes.development.mjs +7 -0
- package/dist/development/core/request-routing/handle-shopify-routes.development.mjs.map +1 -1
- package/dist/development/core/request-routing/handle-shopify-routes.mjs +7 -5
- package/dist/development/core/request-routing/handle-shopify-routes.mjs.map +1 -1
- package/dist/development/core/request-routing/interceptors/proxy.mjs +79 -43
- package/dist/development/core/request-routing/interceptors/proxy.mjs.map +1 -1
- package/dist/development/core/request-routing/interceptors/ucp-profile-proxy.mjs +69 -0
- package/dist/development/core/request-routing/interceptors/ucp-profile-proxy.mjs.map +1 -0
- package/dist/development/core/request-routing/interceptors/url-redirects.mjs +6 -1
- package/dist/development/core/request-routing/interceptors/url-redirects.mjs.map +1 -1
- package/dist/development/core/request-routing/interceptors/well-known.mjs +1 -1
- package/dist/development/core/request-routing/interceptors/well-known.mjs.map +1 -1
- package/dist/development/core/request-routing/registered-routes.d.mts +12 -0
- package/dist/development/core/request-routing/registered-routes.mjs +12 -0
- package/dist/development/core/request-routing/registered-routes.mjs.map +1 -1
- package/dist/development/core/request-routing/route-types.d.mts +43 -18
- package/dist/development/core/shop-pay/shop-pay.d.mts +71 -35
- package/dist/development/core/shop-pay/shop-pay.mjs +36 -10
- package/dist/development/core/shop-pay/shop-pay.mjs.map +1 -1
- package/dist/development/core/shopify-scripts/index.d.mts +15 -5
- package/dist/development/core/shopify-scripts/index.mjs +15 -5
- package/dist/development/core/shopify-scripts/index.mjs.map +1 -1
- package/dist/development/core/shopify-scripts/initialize.d.mts +12 -4
- package/dist/development/core/shopify-scripts/initialize.mjs +12 -4
- package/dist/development/core/shopify-scripts/initialize.mjs.map +1 -1
- package/dist/development/core/shopify-scripts/types.d.mts +58 -25
- package/dist/development/core/standard-routes/build.d.mts +11 -12
- package/dist/development/core/standard-routes/build.mjs +11 -12
- package/dist/development/core/standard-routes/build.mjs.map +1 -1
- package/dist/development/core/standard-routes/types.d.mts +30 -24
- package/dist/development/core/url.mjs +2 -1
- package/dist/development/core/url.mjs.map +1 -1
- package/dist/development/customer-account/session.d.mts +45 -54
- package/dist/development/customer-account/session.mjs +20 -4
- package/dist/development/customer-account/session.mjs.map +1 -1
- package/dist/development/globals.d.mts +20 -11
- package/dist/development/graphql/generated/storefront-api-types.d.mts +127 -1
- package/dist/development/graphql/graphql.d.mts +17 -16
- package/dist/development/graphql/graphql.mjs +7 -8
- package/dist/development/graphql/graphql.mjs.map +1 -1
- package/dist/development/graphql/type-resolver.d.mts +15 -8
- package/dist/development/react/cart.d.mts +78 -32
- package/dist/development/react/cart.mjs +56 -29
- package/dist/development/react/cart.mjs.map +1 -1
- package/dist/development/react/collection.d.mts +40 -22
- package/dist/development/react/collection.mjs +27 -7
- package/dist/development/react/collection.mjs.map +1 -1
- package/dist/development/react/predictive-search.d.mts +65 -50
- package/dist/development/react/predictive-search.mjs +23 -21
- package/dist/development/react/predictive-search.mjs.map +1 -1
- package/dist/development/react/product.d.mts +45 -16
- package/dist/development/react/product.mjs +13 -11
- package/dist/development/react/product.mjs.map +1 -1
- package/dist/development/react/shop-pay.d.mts +15 -0
- package/dist/development/react/shop-pay.mjs +9 -0
- package/dist/development/react/shop-pay.mjs.map +1 -1
- package/dist/development/react/shopify-scripts.d.mts +23 -2
- package/dist/development/react/shopify-scripts.mjs +9 -0
- package/dist/development/react/shopify-scripts.mjs.map +1 -1
- package/dist/development/vue/cart.d.mts +28 -23
- package/dist/development/vue/cart.mjs +42 -25
- package/dist/development/vue/cart.mjs.map +1 -1
- package/dist/development/vue/collection.d.mts +20 -12
- package/dist/development/vue/collection.mjs +15 -7
- package/dist/development/vue/collection.mjs.map +1 -1
- package/dist/development/vue/index.d.mts +2 -2
- package/dist/development/vue/index.mjs +2 -2
- package/dist/development/vue/predictive-search.d.mts +31 -36
- package/dist/development/vue/predictive-search.mjs +16 -22
- package/dist/development/vue/predictive-search.mjs.map +1 -1
- package/dist/development/vue/product.d.mts +16 -15
- package/dist/development/vue/product.mjs +11 -11
- package/dist/development/vue/product.mjs.map +1 -1
- package/dist/development/vue/shop-pay.d.mts +14 -17
- package/dist/development/vue/shop-pay.mjs +8 -0
- package/dist/development/vue/shop-pay.mjs.map +1 -1
- package/dist/development/vue/shopify-scripts.d.mts +11 -0
- package/dist/development/vue/shopify-scripts.mjs +6 -0
- package/dist/development/vue/shopify-scripts.mjs.map +1 -1
- package/dist/globals.d.mts +20 -11
- package/dist/graphql/generated/storefront-api-types.d.mts +127 -1
- package/dist/graphql/graphql.d.mts +17 -16
- package/dist/graphql/graphql.mjs +7 -8
- package/dist/graphql/graphql.mjs.map +1 -1
- package/dist/graphql/type-resolver.d.mts +15 -8
- package/dist/react/cart.d.mts +78 -32
- package/dist/react/cart.mjs +56 -29
- package/dist/react/cart.mjs.map +1 -1
- package/dist/react/collection.d.mts +40 -22
- package/dist/react/collection.mjs +27 -7
- package/dist/react/collection.mjs.map +1 -1
- package/dist/react/predictive-search.d.mts +65 -50
- package/dist/react/predictive-search.mjs +23 -21
- package/dist/react/predictive-search.mjs.map +1 -1
- package/dist/react/product.d.mts +45 -16
- package/dist/react/product.mjs +13 -11
- package/dist/react/product.mjs.map +1 -1
- package/dist/react/shop-pay.d.mts +15 -0
- package/dist/react/shop-pay.mjs +9 -0
- package/dist/react/shop-pay.mjs.map +1 -1
- package/dist/react/shopify-scripts.d.mts +23 -2
- package/dist/react/shopify-scripts.mjs +9 -0
- package/dist/react/shopify-scripts.mjs.map +1 -1
- package/dist/ts-plugin/index.cjs +6 -0
- package/dist/ts-plugin/index.cjs.map +1 -1
- package/dist/ts-plugin/index.d.cts +6 -0
- package/dist/vite/local-https.d.mts +51 -17
- package/dist/vite/local-https.mjs +26 -5
- package/dist/vite/local-https.mjs.map +1 -1
- package/dist/vue/cart.d.mts +28 -23
- package/dist/vue/cart.mjs +42 -25
- package/dist/vue/cart.mjs.map +1 -1
- package/dist/vue/collection.d.mts +20 -12
- package/dist/vue/collection.mjs +15 -7
- package/dist/vue/collection.mjs.map +1 -1
- package/dist/vue/index.d.mts +2 -2
- package/dist/vue/index.mjs +2 -2
- package/dist/vue/predictive-search.d.mts +31 -36
- package/dist/vue/predictive-search.mjs +16 -22
- package/dist/vue/predictive-search.mjs.map +1 -1
- package/dist/vue/product.d.mts +16 -15
- package/dist/vue/product.mjs +11 -11
- package/dist/vue/product.mjs.map +1 -1
- package/dist/vue/shop-pay.d.mts +14 -17
- package/dist/vue/shop-pay.mjs +8 -0
- package/dist/vue/shop-pay.mjs.map +1 -1
- package/dist/vue/shopify-scripts.d.mts +11 -0
- package/dist/vue/shopify-scripts.mjs +6 -0
- package/dist/vue/shopify-scripts.mjs.map +1 -1
- package/package.json +3 -1
- package/skills/hydrogen-analytics/SKILL.md +1 -1
- package/skills/hydrogen-cart-ui/SKILL.md +28 -2
- package/skills/hydrogen-collection-browser/SKILL.md +9 -1
- package/skills/hydrogen-collection-browser/references/nextjs.md +1 -1
- package/skills/hydrogen-collection-browser/references/nuxt.md +1 -1
- package/skills/hydrogen-collection-browser/references/react.md +151 -32
- package/skills/hydrogen-customer-account/SKILL.md +2 -0
- package/skills/hydrogen-request-handlers/SKILL.md +21 -11
- package/skills/hydrogen-setup/references/analytics.md +14 -8
- package/skills/hydrogen-setup/steps/1-inspect-app.md +2 -2
- package/skills/hydrogen-setup/steps/6-product-detail-page.md +21 -11
- package/skills/hydrogen-storefront-client/SKILL.md +1 -1
- package/skills/hydrogen-storefront-client/references/caching.md +2 -0
- package/skills/hydrogen-variant-form/SKILL.md +25 -7
- package/skills/hydrogen-variant-form/references/nextjs.md +39 -4
- package/skills/hydrogen-variant-form/references/nuxt.md +83 -42
- package/skills/hydrogen-variant-form/references/react.md +45 -9
|
@@ -15,16 +15,12 @@ const LOCAL_ORIGIN_HOSTS = new Set([
|
|
|
15
15
|
"::1",
|
|
16
16
|
"[::1]"
|
|
17
17
|
]);
|
|
18
|
-
const USER_AGENT = `Hydrogen 2026.10.0
|
|
18
|
+
const USER_AGENT = `Hydrogen 2026.10.0`;
|
|
19
19
|
const CUSTOMER_ACCOUNT_GRAPHQL_PERSONALIZATION_REASON = "customer-account-graphql";
|
|
20
20
|
/**
|
|
21
|
-
* Creates a server
|
|
22
|
-
* Account API.
|
|
21
|
+
* Creates a client that sends Customer Account API requests from your server. Create the client with the current request's context.
|
|
23
22
|
*
|
|
24
|
-
*
|
|
25
|
-
* construction time. The returned client auto-injects the `language` variable
|
|
26
|
-
* from `requestContext.i18n.language` when applicable, composes abort signals,
|
|
27
|
-
* and marks responses as personalized (sets `private, no-store` cache headers).
|
|
23
|
+
* The function throws when the shop ID, API version, or timeout is invalid, when the request context has no HTTPS URL, when no fetch implementation is available, and when the function runs in a browser.
|
|
28
24
|
*
|
|
29
25
|
* @example
|
|
30
26
|
* ```ts
|
|
@@ -41,7 +37,10 @@ const CUSTOMER_ACCOUNT_GRAPHQL_PERSONALIZATION_REASON = "customer-account-graphq
|
|
|
41
37
|
* );
|
|
42
38
|
* ```
|
|
43
39
|
*
|
|
44
|
-
* @
|
|
40
|
+
* @param options - The shop ID, the API version, the request context, a custom fetch, and the request timeout.
|
|
41
|
+
* @returns A client with the GraphQL endpoint URL and a `graphql()` method for Customer Account API requests.
|
|
42
|
+
* @throws {Error} When called in a browser, when the shop ID, API version, or timeout is invalid, when no fetch is available, or when the request context URL is missing or not HTTPS.
|
|
43
|
+
* @publicDocs
|
|
45
44
|
*/
|
|
46
45
|
function createCustomerAccountClient({ shopId, customerApiVersion = CUSTOMER_ACCOUNT_API_VERSION, requestContext, fetch: customFetch, defaultTimeoutInMs = DEFAULT_TIMEOUT_IN_MS }) {
|
|
47
46
|
if (typeof document !== "undefined") throw new Error("Customer Account API tokens cannot be used in a browser context. Use this client from server or edge routes only.");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.mjs","names":[],"sources":["../../src/customer-account/client.ts"],"sourcesContent":["import type { GraphQLFormattedError } from \"../client/types\";\nimport { CUSTOMER_ACCOUNT_API_VERSION, DEFAULT_TIMEOUT_IN_MS } from \"../core/constants\";\nimport type { ShopifyRequestContext } from \"../core/request-context\";\nimport { isObjectRecord } from \"../core/utils/record\";\nimport {\n CustomerAccountApiError,\n CustomerAccountAuthenticationError,\n CustomerAccountTimeoutError,\n} from \"./errors\";\nimport {\n assertCustomerAccountDocument,\n type AnyCustomerAccountDocument,\n type CustomerAccountDocument,\n} from \"./graphql\";\n\nconst SHOP_ID_RE = /^\\d+$/;\nconst CUSTOMER_API_VERSION_RE = /^\\d{4}-\\d{2}$/;\nconst MAX_ASCII_CONTROL_CODE_POINT = 31;\nconst ASCII_DELETE_CODE_POINT = 127;\nconst MAX_SET_TIMEOUT_IN_MS = 2_147_483_647;\nconst LOCAL_ORIGIN_HOSTS = new Set([\"localhost\", \"127.0.0.1\", \"::1\", \"[::1]\"]);\nconst USER_AGENT = `Hydrogen ${__HYDROGEN_VERSION__}`;\nconst CUSTOMER_ACCOUNT_GRAPHQL_PERSONALIZATION_REASON = \"customer-account-graphql\";\n\ntype AccessToken = string | null | undefined;\ntype FetchCustomerAccountGraphqlParams = {\n fetch: typeof globalThis.fetch;\n apiUrl: string;\n accessToken: string;\n origin: string;\n query: string;\n variables: Record<string, unknown>;\n signal: AbortSignal;\n timeoutSignal: AbortSignal;\n timeoutInMs: number;\n};\n\n/**\n * Options for {@link createCustomerAccountClient}.\n *\n * The client validates `shopId`, `customerApiVersion`, and `defaultTimeoutInMs`\n * at construction time and throws synchronously on invalid values.\n */\nexport type CreateCustomerAccountClientOptions = {\n /** Numeric Shopify shop ID as a string (e.g. `\"12345\"`). Validated against `/^\\d+$/`. */\n shopId: string;\n /**\n * Customer Account API version in `YYYY-MM` format.\n * Defaults to {@link CUSTOMER_ACCOUNT_API_VERSION}.\n */\n customerApiVersion?: string;\n /**\n * Request-scoped context created by `createShopifyRequestContext`. Must\n * have a `url` property (throws at construction when missing or non-HTTPS;\n * `http://localhost`, `127.0.0.1` and `::1` are accepted and sent as\n * HTTPS). Supplies the i18n language for automatic `$language` variable\n * injection, an abort signal that propagates request cancellation, and a\n * personalization marker (sets `private, no-store` and removes CDN cache\n * headers).\n */\n requestContext: ShopifyRequestContext;\n /** Custom `fetch` implementation. Falls back to `globalThis.fetch`. */\n fetch?: typeof globalThis.fetch;\n /**\n * Per-request timeout in milliseconds. Must be a positive safe integer no\n * greater than 2,147,483,647. Defaults to 30,000 ms.\n */\n defaultTimeoutInMs?: number;\n};\n\n/**\n * Per-call options passed to {@link CustomerAccountClient.graphql}.\n * See `variables` for automatic `$language` injection.\n */\nexport type CustomerAccountGraphqlOptions<Variables = Record<string, unknown>> = {\n /** Customer Account API access token, e.g. from `CustomerSession.getAccessToken()` or `getOrRefreshAccessToken()`. */\n accessToken: string;\n /**\n * Query variables. When the GraphQL document declares a `$language` variable\n * and you omit it here, the client injects it automatically from\n * `requestContext.i18n.language`.\n */\n variables?: Variables;\n /**\n * Optional abort signal. Combined with the request context signal and the\n * per-request timeout signal via `AbortSignal.any`, so cancellation from any\n * source stops the request.\n */\n signal?: AbortSignal;\n};\n\ntype ResultOfDoc<Doc> =\n Doc extends CustomerAccountDocument<infer Result, never, string> ? Result : never;\ntype VariablesOfDoc<Doc> =\n Doc extends CustomerAccountDocument<unknown, infer Variables, string> ? Variables : never;\ntype OptionalAutoVariables<Variables> = \"language\" extends keyof Variables\n ? { language?: Variables[\"language\"] }\n : {};\ntype UserVariables<Doc> = Omit<VariablesOfDoc<Doc>, \"language\"> &\n OptionalAutoVariables<VariablesOfDoc<Doc>>;\ntype HasNoRequiredKeys<T> = Record<string, never> extends T ? true : false;\n\n/**\n * Discriminated union returned by {@link CustomerAccountClient.graphql}.\n *\n * Discriminate on the presence of `errors`, not via `Partial`:\n *\n * - **Success:** `data` is always present, `errors` is `undefined`.\n * - **Partial or error:** `errors` is a non-empty array of\n * {@link GraphQLFormattedError}, and `data` may be `null`.\n *\n * Both arms expose the raw response `headers` for inspecting\n * `x-request-id` or rate-limit metadata.\n */\nexport type CustomerAccountGraphqlResult<Result = unknown> =\n | { data: Result; errors?: undefined; headers: Headers }\n | { data: Result | null; errors: GraphQLFormattedError[]; headers: Headers };\n\n/**\n * Conditional rest parameter for {@link CustomerAccountClient.graphql}.\n *\n * When the document has no required user variables (after `language` is\n * excluded from the requirement), `options.variables` is optional. When the\n * document declares required variables, the type forces the caller to supply\n * them, turning a missing-variables bug into a compile error.\n */\nexport type CustomerAccountGqlRestParam<Doc extends AnyCustomerAccountDocument> =\n HasNoRequiredKeys<UserVariables<Doc>> extends true\n ? [options: CustomerAccountGraphqlOptions<UserVariables<Doc>>]\n : [\n options: CustomerAccountGraphqlOptions<UserVariables<Doc>> & {\n variables: UserVariables<Doc>;\n },\n ];\n\n/**\n * A server-side GraphQL client for the Shopify Customer Account API.\n *\n * Created by {@link createCustomerAccountClient}. Each call to `graphql()`\n * validates that the document was produced by `gql()` (runtime branded with a\n * private Symbol), validates the access token, auto-injects the `language`\n * variable from i18n context when applicable, and marks the response as\n * personalized so the app response is sent with private, no-store cache headers.\n */\nexport type CustomerAccountClient = {\n /** Constructed endpoint: `https://shopify.com/{shopId}/account/customer/api/{version}/graphql`. */\n readonly apiUrl: string;\n /**\n * Send a GraphQL request to the Customer Account API.\n *\n * The document must be created by `gql()`. At call time the client:\n * 1. Validates the document brand and options object.\n * 2. Marks the response as personalized (sets `private, no-store`).\n * 3. Validates the access token.\n * 4. Throws if a signal is already aborted.\n * 5. Combines the request context signal, the caller's signal, and a timeout\n * signal via `AbortSignal.any`.\n * 6. Auto-injects the `language` variable from `requestContext.i18n.language`\n * when the document declares `$language` and the caller omits it.\n *\n * @throws {TypeError} When the document is not a branded `gql()` result.\n * @throws {CustomerAccountAuthenticationError} When the access token fails pre-flight validation.\n * @throws {CustomerAccountTimeoutError} When the request exceeds `defaultTimeoutInMs`.\n * @throws {CustomerAccountApiError} On non-OK HTTP status, unparseable JSON, or missing `data`.\n *\n * @example\n * ```ts\n * const result = await client.graphql(\n * gql(`query { customer { firstName lastName } }`),\n * { accessToken },\n * );\n *\n * if (result.errors) {\n * console.error(result.errors);\n * } else {\n * console.log(result.data.customer.firstName);\n * }\n * ```\n */\n graphql: <const Doc extends AnyCustomerAccountDocument>(\n document: Doc,\n ...options: CustomerAccountGqlRestParam<Doc>\n ) => Promise<CustomerAccountGraphqlResult<ResultOfDoc<Doc>>>;\n};\n\n/**\n * Creates a server-only {@link CustomerAccountClient} for the Shopify Customer\n * Account API.\n *\n * Validates `shopId`, `customerApiVersion`, and `defaultTimeoutInMs` at\n * construction time. The returned client auto-injects the `language` variable\n * from `requestContext.i18n.language` when applicable, composes abort signals,\n * and marks responses as personalized (sets `private, no-store` cache headers).\n *\n * @example\n * ```ts\n * import { createCustomerAccountClient, gql } from \"@shopify/hydrogen/customer-account\";\n *\n * const customerAccount = createCustomerAccountClient({\n * shopId: \"12345\",\n * requestContext,\n * });\n *\n * const { data } = await customerAccount.graphql(\n * gql(`query { customer { firstName } }`),\n * { accessToken },\n * );\n * ```\n *\n * @throws {Error} When called in a browser context, when `shopId`, `customerApiVersion`, or `defaultTimeoutInMs` is invalid, when no `fetch` is available, or when `requestContext.url` is missing or not HTTPS.\n */\nexport function createCustomerAccountClient({\n shopId,\n customerApiVersion = CUSTOMER_ACCOUNT_API_VERSION,\n requestContext,\n fetch: customFetch,\n defaultTimeoutInMs = DEFAULT_TIMEOUT_IN_MS,\n}: CreateCustomerAccountClientOptions): CustomerAccountClient {\n if (typeof document !== \"undefined\") {\n throw new Error(\n \"Customer Account API tokens cannot be used in a browser context. Use this client from server or edge routes only.\",\n );\n }\n\n validateShopId(shopId);\n validateCustomerApiVersion(customerApiVersion);\n validateTimeout(defaultTimeoutInMs);\n\n const resolvedFetch = customFetch ?? globalThis.fetch;\n if (typeof resolvedFetch !== \"function\") {\n throw new Error(\n \"No fetch function available. Pass a fetch option or ensure globalThis.fetch exists.\",\n );\n }\n\n const origin = getOrigin(requestContext.url);\n const apiUrl = `https://shopify.com/${shopId}/account/customer/api/${customerApiVersion}/graphql`;\n\n async function graphql<const Doc extends AnyCustomerAccountDocument>(\n document: Doc,\n ...rest: CustomerAccountGqlRestParam<Doc>\n ): Promise<CustomerAccountGraphqlResult<ResultOfDoc<Doc>>>;\n async function graphql(\n document: AnyCustomerAccountDocument,\n ...rest: [options?: CustomerAccountGraphqlOptions<unknown>]\n ): Promise<CustomerAccountGraphqlResult<unknown>> {\n assertCustomerAccountDocument(document);\n const options = validateGraphqlOptions(rest[0]);\n requestContext.markResponseAsPersonalized(CUSTOMER_ACCOUNT_GRAPHQL_PERSONALIZATION_REASON);\n const accessToken = validateAccessToken(options.accessToken);\n const externalSignals = [requestContext.signal, options.signal].filter(\n (signal): signal is AbortSignal => Boolean(signal),\n );\n throwIfAlreadyAborted(externalSignals);\n\n const { signal: timeoutSignal, cleanup: cleanupTimeout } =\n createCustomerAccountTimeoutSignal(defaultTimeoutInMs);\n externalSignals.push(timeoutSignal);\n const signal = AbortSignal.any(externalSignals);\n\n try {\n const variables = getVariables(\n document,\n getOptionalVariables(options.variables),\n requestContext.i18n.language,\n );\n const response = await fetchCustomerAccountGraphql({\n fetch: resolvedFetch,\n apiUrl,\n accessToken,\n origin,\n query: document.source,\n variables,\n signal,\n timeoutSignal,\n timeoutInMs: defaultTimeoutInMs,\n });\n\n return await readCustomerAccountGraphqlResponse(\n response,\n signal,\n timeoutSignal,\n defaultTimeoutInMs,\n );\n } finally {\n cleanupTimeout();\n }\n }\n\n return { apiUrl, graphql };\n}\n\nasync function fetchCustomerAccountGraphql({\n fetch,\n apiUrl,\n accessToken,\n origin,\n query,\n variables,\n signal,\n timeoutSignal,\n timeoutInMs,\n}: FetchCustomerAccountGraphqlParams): Promise<Response> {\n try {\n return await withAbort(\n fetch(apiUrl, {\n method: \"POST\",\n headers: new Headers({\n Authorization: accessToken,\n \"Content-Type\": \"application/json\",\n Origin: origin,\n \"User-Agent\": USER_AGENT,\n }),\n body: JSON.stringify({ query, variables }),\n cache: \"no-store\",\n redirect: \"manual\",\n signal,\n }),\n signal,\n );\n } catch (cause) {\n throwIfCustomerAccountSignalAborted(signal, timeoutSignal, timeoutInMs);\n if (isAbortError(cause)) throw cause;\n throw new CustomerAccountApiError(\"Customer Account API request failed\", { cause });\n }\n}\n\nasync function readCustomerAccountGraphqlResponse(\n response: Response,\n signal: AbortSignal,\n timeoutSignal: AbortSignal,\n timeoutInMs: number,\n): Promise<CustomerAccountGraphqlResult<unknown>> {\n const requestId = response.headers.get(\"x-request-id\") ?? undefined;\n if (!response.ok) {\n cancelResponseBody(response);\n throw new CustomerAccountApiError(`Customer Account API responded with ${response.status}`, {\n status: response.status,\n requestId,\n retryAfter: response.headers.get(\"retry-after\") ?? undefined,\n });\n }\n\n let body: { data?: unknown; errors?: GraphQLFormattedError[] };\n try {\n body = parseGraphqlResponse(await withAbort(response.json(), signal));\n } catch (cause) {\n cancelResponseBody(response);\n\n throwIfCustomerAccountSignalAborted(signal, timeoutSignal, timeoutInMs);\n if (isAbortError(cause)) throw cause;\n throw new CustomerAccountApiError(\"Failed to parse Customer Account API response as JSON\", {\n status: response.status,\n requestId,\n cause,\n });\n }\n\n if (body.errors) {\n return { data: body.data ?? null, errors: body.errors, headers: response.headers };\n }\n\n if (body.data == null) {\n throw new CustomerAccountApiError(\"Customer Account API response did not include data\", {\n status: response.status,\n requestId,\n });\n }\n\n return { data: body.data, headers: response.headers };\n}\n\nfunction cancelResponseBody(response: Response): void {\n try {\n void response.body?.cancel().catch(() => undefined);\n } catch {}\n}\n\nfunction validateTimeout(timeoutInMs: number): void {\n if (\n !Number.isSafeInteger(timeoutInMs) ||\n timeoutInMs <= 0 ||\n timeoutInMs > MAX_SET_TIMEOUT_IN_MS\n ) {\n throw new Error(\n `defaultTimeoutInMs must be a positive safe integer no greater than ${MAX_SET_TIMEOUT_IN_MS}`,\n );\n }\n}\n\nfunction createCustomerAccountTimeoutSignal(timeoutInMs: number): {\n signal: AbortSignal;\n cleanup: () => void;\n} {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => {\n controller.abort(new CustomerAccountTimeoutError(timeoutInMs));\n }, timeoutInMs);\n\n return { signal: controller.signal, cleanup: () => clearTimeout(timeoutId) };\n}\n\nfunction withAbort<T>(promise: T | Promise<T>, signal: AbortSignal | undefined): Promise<T> {\n if (!signal) return Promise.resolve(promise);\n if (signal.aborted) {\n return Promise.reject(\n signal.reason ?? new DOMException(\"signal is aborted without reason\", \"AbortError\"),\n );\n }\n\n return new Promise<T>((resolve, reject) => {\n const abort = () => {\n signal.removeEventListener(\"abort\", abort);\n const reason =\n signal.reason ?? new DOMException(\"signal is aborted without reason\", \"AbortError\");\n reject(reason);\n };\n signal.addEventListener(\"abort\", abort, { once: true });\n Promise.resolve(promise).then(\n (value) => {\n signal.removeEventListener(\"abort\", abort);\n resolve(value);\n },\n (error) => {\n signal.removeEventListener(\"abort\", abort);\n reject(error);\n },\n );\n });\n}\n\nfunction getVariables(\n document: { variableNames: ReadonlySet<string> },\n variables: Record<string, unknown>,\n language: ShopifyRequestContext[\"i18n\"][\"language\"],\n): Record<string, unknown> {\n if (!document.variableNames.has(\"language\")) return variables;\n if (\"language\" in variables) return variables;\n return { ...variables, language };\n}\n\nfunction throwIfAlreadyAborted(signals: AbortSignal[]): void {\n const abortedSignal = signals.find((signal) => signal.aborted);\n if (!abortedSignal) return;\n throw abortedSignal.reason ?? new DOMException(\"signal is aborted without reason\", \"AbortError\");\n}\n\nfunction throwIfCustomerAccountSignalAborted(\n signal: AbortSignal,\n timeoutSignal: AbortSignal,\n timeoutInMs: number,\n): void {\n if (!signal.aborted) return;\n if (timeoutSignal.aborted && signal.reason === timeoutSignal.reason) {\n const reason = timeoutSignal.reason;\n throw reason instanceof CustomerAccountTimeoutError\n ? reason\n : new CustomerAccountTimeoutError(timeoutInMs);\n }\n throw signal.reason ?? new DOMException(\"signal is aborted without reason\", \"AbortError\");\n}\n\nfunction isAbortError(cause: unknown): cause is DOMException {\n return cause instanceof DOMException && cause.name === \"AbortError\";\n}\n\nfunction parseGraphqlResponse(json: unknown): {\n data?: unknown;\n errors?: GraphQLFormattedError[];\n} {\n if (!isObjectRecord(json)) {\n throw new Error(\"Customer Account API returned unexpected JSON type\");\n }\n\n if (!(\"data\" in json) && !(\"errors\" in json)) {\n throw new Error(\"Customer Account API response must include data or errors\");\n }\n const errors = json.errors;\n if (errors !== undefined && !isGraphqlErrorArray(errors)) {\n throw new Error(\"Customer Account API returned invalid GraphQL errors\");\n }\n return { data: json.data, errors };\n}\n\nfunction isGraphqlErrorArray(value: unknown): value is GraphQLFormattedError[] {\n if (!Array.isArray(value)) return false;\n return value.every((error) => {\n return typeof error === \"object\" && error !== null && typeof error.message === \"string\";\n });\n}\n\nfunction validateShopId(shopId: string): void {\n if (!SHOP_ID_RE.test(shopId)) {\n throw new Error(\"shopId must be a numeric Shopify shop ID string\");\n }\n}\n\nfunction validateCustomerApiVersion(customerApiVersion: string): void {\n if (!CUSTOMER_API_VERSION_RE.test(customerApiVersion)) {\n throw new Error(\"customerApiVersion must use YYYY-MM format\");\n }\n}\n\nfunction validateAccessToken(accessToken: AccessToken): string {\n if (\n typeof accessToken !== \"string\" ||\n accessToken === \"\" ||\n accessToken.trim() !== accessToken ||\n hasAsciiControlCharacter(accessToken)\n ) {\n throw new CustomerAccountAuthenticationError();\n }\n return accessToken;\n}\n\nfunction validateGraphqlOptions(\n options: CustomerAccountGraphqlOptions<unknown> | undefined,\n): CustomerAccountGraphqlOptions<unknown> {\n if (typeof options !== \"object\" || options === null) {\n throw new CustomerAccountAuthenticationError();\n }\n return options;\n}\n\nfunction getOptionalVariables(variables: unknown): Record<string, unknown> {\n if (variables === undefined) return {};\n if (!isObjectRecord(variables)) {\n throw new TypeError(\"Customer Account API variables must be an object\");\n }\n return variables;\n}\n\nfunction hasAsciiControlCharacter(value: string): boolean {\n for (let index = 0; index < value.length; index++) {\n const codePoint = value.charCodeAt(index);\n if (codePoint <= MAX_ASCII_CONTROL_CODE_POINT || codePoint === ASCII_DELETE_CODE_POINT) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Customer Account API requires an HTTPS Origin, but local dev frameworks often\n * receive `http://localhost` requests. Keep that local-only exception without\n * weakening origin validation for non-local requests.\n */\nfunction getOrigin(requestUrl: string | undefined): string {\n if (!requestUrl) {\n throw new Error(\"requestContext.url is required for Customer Account API requests\");\n }\n\n const url = new URL(requestUrl);\n if (url.protocol === \"https:\") return url.origin;\n if (url.protocol === \"http:\" && LOCAL_ORIGIN_HOSTS.has(url.hostname)) {\n return `https://${url.host}`;\n }\n throw new Error(`Customer Account API origin must use HTTPS. Received: ${requestUrl}`);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.mjs","names":[],"sources":["../../src/customer-account/client.ts"],"sourcesContent":["import type { GraphQLFormattedError } from \"../client/types\";\nimport { CUSTOMER_ACCOUNT_API_VERSION, DEFAULT_TIMEOUT_IN_MS } from \"../core/constants\";\nimport type { ShopifyRequestContext } from \"../core/request-context\";\nimport { isObjectRecord } from \"../core/utils/record\";\nimport {\n CustomerAccountApiError,\n CustomerAccountAuthenticationError,\n CustomerAccountTimeoutError,\n} from \"./errors\";\nimport {\n assertCustomerAccountDocument,\n type AnyCustomerAccountDocument,\n type CustomerAccountDocument,\n} from \"./graphql\";\n\nconst SHOP_ID_RE = /^\\d+$/;\nconst CUSTOMER_API_VERSION_RE = /^\\d{4}-\\d{2}$/;\nconst MAX_ASCII_CONTROL_CODE_POINT = 31;\nconst ASCII_DELETE_CODE_POINT = 127;\nconst MAX_SET_TIMEOUT_IN_MS = 2_147_483_647;\nconst LOCAL_ORIGIN_HOSTS = new Set([\"localhost\", \"127.0.0.1\", \"::1\", \"[::1]\"]);\nconst USER_AGENT = `Hydrogen ${__HYDROGEN_VERSION__}`;\nconst CUSTOMER_ACCOUNT_GRAPHQL_PERSONALIZATION_REASON = \"customer-account-graphql\";\n\n/** A Customer Account API access token, or `null` or `undefined` when the customer has none. */\ntype AccessToken = string | null | undefined;\ntype FetchCustomerAccountGraphqlParams = {\n fetch: typeof globalThis.fetch;\n apiUrl: string;\n accessToken: string;\n origin: string;\n query: string;\n variables: Record<string, unknown>;\n signal: AbortSignal;\n timeoutSignal: AbortSignal;\n timeoutInMs: number;\n};\n\n/**\n * Options for creating a Customer Account API client.\n */\nexport type CreateCustomerAccountClientOptions = {\n /** Numeric Shopify shop ID as a string of digits, such as `12345`. */\n shopId: string;\n /**\n * Customer Account API version in `YYYY-MM` format. Defaults to `2026-10`.\n */\n customerApiVersion?: string;\n /**\n * The context for the current request, from `createShopifyRequestContext`.\n *\n * The context's URL must use HTTPS, or creating the client throws. Local `http://` URLs on localhost, 127.0.0.1, and ::1 also work for development.\n *\n * The client fills `$language` from the context's language and stops requests when the context's signal aborts.\n */\n requestContext: ShopifyRequestContext;\n /** Custom fetch implementation. Defaults to the global fetch. */\n fetch?: typeof globalThis.fetch;\n /**\n * Timeout for each request in milliseconds. Must be a positive integer no greater than 2,147,483,647. Defaults to `30000`.\n */\n defaultTimeoutInMs?: number;\n};\n\n/**\n * Options for a single Customer Account API request.\n */\nexport type CustomerAccountGraphqlOptions<Variables = Record<string, unknown>> = {\n /** The customer's access token, such as one from the customer session's `getOrRefreshAccessToken()` method. */\n accessToken: string;\n /**\n * The document's variables. When the document declares `$language` and you omit it, the client fills the variable from the request context's language.\n */\n variables?: Variables;\n /**\n * Stops this request when the signal aborts. The request also stops when the request context's signal aborts or the timeout passes.\n */\n signal?: AbortSignal;\n};\n\ntype ResultOfDoc<Doc> =\n Doc extends CustomerAccountDocument<infer Result, never, string> ? Result : never;\n/** The variables that a Customer Account document declares. */\ntype VariablesOfDoc<Doc> =\n Doc extends CustomerAccountDocument<unknown, infer Variables, string> ? Variables : never;\n/** An optional `language` variable for a document that declares `$language`. The client fills a missing value from the request context. */\ntype OptionalAutoVariables<Variables> = \"language\" extends keyof Variables\n ? { language?: Variables[\"language\"] }\n : {};\ntype UserVariables<Doc> = Omit<VariablesOfDoc<Doc>, \"language\"> &\n OptionalAutoVariables<VariablesOfDoc<Doc>>;\ntype HasNoRequiredKeys<T> = Record<string, never> extends T ? true : false;\n\n/**\n * Result of a Customer Account API request. Check `errors` to tell the outcomes apart.\n *\n * On success, `data` holds the result and `errors` is `undefined`. When the response has GraphQL errors, `errors` holds them and `data` can be `null`. Every result includes the raw response headers.\n */\nexport type CustomerAccountGraphqlResult<Result = unknown> =\n | { data: Result; errors?: undefined; headers: Headers }\n | { data: Result | null; errors: GraphQLFormattedError[]; headers: Headers };\n\n/**\n * The options argument for a Customer Account API request.\n *\n * Pass `variables` when the document declares a required variable other than `language`. TypeScript reports an error when a required variable is missing.\n */\nexport type CustomerAccountGqlRestParam<Doc extends AnyCustomerAccountDocument> =\n HasNoRequiredKeys<UserVariables<Doc>> extends true\n ? [options: CustomerAccountGraphqlOptions<UserVariables<Doc>>]\n : [\n options: CustomerAccountGraphqlOptions<UserVariables<Doc>> & {\n variables: UserVariables<Doc>;\n },\n ];\n\n/**\n * A client that sends Customer Account API requests from your server for the current request.\n */\nexport type CustomerAccountClient = {\n /** The GraphQL endpoint, `https://shopify.com/{shopId}/account/customer/api/{version}/graphql`. */\n readonly apiUrl: string;\n /**\n * Sends a Customer Account API query or mutation with the customer's access token, and returns the data, any GraphQL errors, and the response headers. Pass a document from the Customer Account `gql` function.\n *\n * The request makes the final response private and uncacheable when you call `applyResponseHeaders()`. When the document declares `$language` and you omit it, the client fills the variable from the request context's language.\n *\n * The method throws a `TypeError` for a document from any other `gql` function, including the Storefront API `gql` function, and for variables that aren't an object. When a signal aborts, the method throws the signal's reason. A missing or malformed access token throws `CustomerAccountAuthenticationError`, a timeout throws `CustomerAccountTimeoutError`, and other request failures throw `CustomerAccountApiError`.\n *\n * @throws {TypeError} When another gql function created the document, or when the variables aren't an object.\n * @throws {CustomerAccountAuthenticationError} When the options object is missing or the access token fails validation.\n * @throws {CustomerAccountTimeoutError} When the request exceeds the client's timeout.\n * @throws {CustomerAccountApiError} On a non-OK HTTP status, unparseable JSON, a response without data, or a network failure.\n *\n * @example\n * ```ts\n * const result = await client.graphql(\n * gql(`query { customer { firstName lastName } }`),\n * { accessToken },\n * );\n *\n * if (result.errors) {\n * console.error(result.errors);\n * } else {\n * console.log(result.data.customer.firstName);\n * }\n * ```\n */\n graphql: <const Doc extends AnyCustomerAccountDocument>(\n document: Doc,\n ...options: CustomerAccountGqlRestParam<Doc>\n ) => Promise<CustomerAccountGraphqlResult<ResultOfDoc<Doc>>>;\n};\n\n/**\n * Creates a client that sends Customer Account API requests from your server. Create the client with the current request's context.\n *\n * The function throws when the shop ID, API version, or timeout is invalid, when the request context has no HTTPS URL, when no fetch implementation is available, and when the function runs in a browser.\n *\n * @example\n * ```ts\n * import { createCustomerAccountClient, gql } from \"@shopify/hydrogen/customer-account\";\n *\n * const customerAccount = createCustomerAccountClient({\n * shopId: \"12345\",\n * requestContext,\n * });\n *\n * const { data } = await customerAccount.graphql(\n * gql(`query { customer { firstName } }`),\n * { accessToken },\n * );\n * ```\n *\n * @param options - The shop ID, the API version, the request context, a custom fetch, and the request timeout.\n * @returns A client with the GraphQL endpoint URL and a `graphql()` method for Customer Account API requests.\n * @throws {Error} When called in a browser, when the shop ID, API version, or timeout is invalid, when no fetch is available, or when the request context URL is missing or not HTTPS.\n * @publicDocs\n */\nexport function createCustomerAccountClient({\n shopId,\n customerApiVersion = CUSTOMER_ACCOUNT_API_VERSION,\n requestContext,\n fetch: customFetch,\n defaultTimeoutInMs = DEFAULT_TIMEOUT_IN_MS,\n}: CreateCustomerAccountClientOptions): CustomerAccountClient {\n if (typeof document !== \"undefined\") {\n throw new Error(\n \"Customer Account API tokens cannot be used in a browser context. Use this client from server or edge routes only.\",\n );\n }\n\n validateShopId(shopId);\n validateCustomerApiVersion(customerApiVersion);\n validateTimeout(defaultTimeoutInMs);\n\n const resolvedFetch = customFetch ?? globalThis.fetch;\n if (typeof resolvedFetch !== \"function\") {\n throw new Error(\n \"No fetch function available. Pass a fetch option or ensure globalThis.fetch exists.\",\n );\n }\n\n const origin = getOrigin(requestContext.url);\n const apiUrl = `https://shopify.com/${shopId}/account/customer/api/${customerApiVersion}/graphql`;\n\n async function graphql<const Doc extends AnyCustomerAccountDocument>(\n document: Doc,\n ...rest: CustomerAccountGqlRestParam<Doc>\n ): Promise<CustomerAccountGraphqlResult<ResultOfDoc<Doc>>>;\n async function graphql(\n document: AnyCustomerAccountDocument,\n ...rest: [options?: CustomerAccountGraphqlOptions<unknown>]\n ): Promise<CustomerAccountGraphqlResult<unknown>> {\n assertCustomerAccountDocument(document);\n const options = validateGraphqlOptions(rest[0]);\n requestContext.markResponseAsPersonalized(CUSTOMER_ACCOUNT_GRAPHQL_PERSONALIZATION_REASON);\n const accessToken = validateAccessToken(options.accessToken);\n const externalSignals = [requestContext.signal, options.signal].filter(\n (signal): signal is AbortSignal => Boolean(signal),\n );\n throwIfAlreadyAborted(externalSignals);\n\n const { signal: timeoutSignal, cleanup: cleanupTimeout } =\n createCustomerAccountTimeoutSignal(defaultTimeoutInMs);\n externalSignals.push(timeoutSignal);\n const signal = AbortSignal.any(externalSignals);\n\n try {\n const variables = getVariables(\n document,\n getOptionalVariables(options.variables),\n requestContext.i18n.language,\n );\n const response = await fetchCustomerAccountGraphql({\n fetch: resolvedFetch,\n apiUrl,\n accessToken,\n origin,\n query: document.source,\n variables,\n signal,\n timeoutSignal,\n timeoutInMs: defaultTimeoutInMs,\n });\n\n return await readCustomerAccountGraphqlResponse(\n response,\n signal,\n timeoutSignal,\n defaultTimeoutInMs,\n );\n } finally {\n cleanupTimeout();\n }\n }\n\n return { apiUrl, graphql };\n}\n\nasync function fetchCustomerAccountGraphql({\n fetch,\n apiUrl,\n accessToken,\n origin,\n query,\n variables,\n signal,\n timeoutSignal,\n timeoutInMs,\n}: FetchCustomerAccountGraphqlParams): Promise<Response> {\n try {\n return await withAbort(\n fetch(apiUrl, {\n method: \"POST\",\n headers: new Headers({\n Authorization: accessToken,\n \"Content-Type\": \"application/json\",\n Origin: origin,\n \"User-Agent\": USER_AGENT,\n }),\n body: JSON.stringify({ query, variables }),\n cache: \"no-store\",\n redirect: \"manual\",\n signal,\n }),\n signal,\n );\n } catch (cause) {\n throwIfCustomerAccountSignalAborted(signal, timeoutSignal, timeoutInMs);\n if (isAbortError(cause)) throw cause;\n throw new CustomerAccountApiError(\"Customer Account API request failed\", { cause });\n }\n}\n\nasync function readCustomerAccountGraphqlResponse(\n response: Response,\n signal: AbortSignal,\n timeoutSignal: AbortSignal,\n timeoutInMs: number,\n): Promise<CustomerAccountGraphqlResult<unknown>> {\n const requestId = response.headers.get(\"x-request-id\") ?? undefined;\n if (!response.ok) {\n cancelResponseBody(response);\n throw new CustomerAccountApiError(`Customer Account API responded with ${response.status}`, {\n status: response.status,\n requestId,\n retryAfter: response.headers.get(\"retry-after\") ?? undefined,\n });\n }\n\n let body: { data?: unknown; errors?: GraphQLFormattedError[] };\n try {\n body = parseGraphqlResponse(await withAbort(response.json(), signal));\n } catch (cause) {\n cancelResponseBody(response);\n\n throwIfCustomerAccountSignalAborted(signal, timeoutSignal, timeoutInMs);\n if (isAbortError(cause)) throw cause;\n throw new CustomerAccountApiError(\"Failed to parse Customer Account API response as JSON\", {\n status: response.status,\n requestId,\n cause,\n });\n }\n\n if (body.errors) {\n return { data: body.data ?? null, errors: body.errors, headers: response.headers };\n }\n\n if (body.data == null) {\n throw new CustomerAccountApiError(\"Customer Account API response did not include data\", {\n status: response.status,\n requestId,\n });\n }\n\n return { data: body.data, headers: response.headers };\n}\n\nfunction cancelResponseBody(response: Response): void {\n try {\n void response.body?.cancel().catch(() => undefined);\n } catch {}\n}\n\nfunction validateTimeout(timeoutInMs: number): void {\n if (\n !Number.isSafeInteger(timeoutInMs) ||\n timeoutInMs <= 0 ||\n timeoutInMs > MAX_SET_TIMEOUT_IN_MS\n ) {\n throw new Error(\n `defaultTimeoutInMs must be a positive safe integer no greater than ${MAX_SET_TIMEOUT_IN_MS}`,\n );\n }\n}\n\nfunction createCustomerAccountTimeoutSignal(timeoutInMs: number): {\n signal: AbortSignal;\n cleanup: () => void;\n} {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => {\n controller.abort(new CustomerAccountTimeoutError(timeoutInMs));\n }, timeoutInMs);\n\n return { signal: controller.signal, cleanup: () => clearTimeout(timeoutId) };\n}\n\nfunction withAbort<T>(promise: T | Promise<T>, signal: AbortSignal | undefined): Promise<T> {\n if (!signal) return Promise.resolve(promise);\n if (signal.aborted) {\n return Promise.reject(\n signal.reason ?? new DOMException(\"signal is aborted without reason\", \"AbortError\"),\n );\n }\n\n return new Promise<T>((resolve, reject) => {\n const abort = () => {\n signal.removeEventListener(\"abort\", abort);\n const reason =\n signal.reason ?? new DOMException(\"signal is aborted without reason\", \"AbortError\");\n reject(reason);\n };\n signal.addEventListener(\"abort\", abort, { once: true });\n Promise.resolve(promise).then(\n (value) => {\n signal.removeEventListener(\"abort\", abort);\n resolve(value);\n },\n (error) => {\n signal.removeEventListener(\"abort\", abort);\n reject(error);\n },\n );\n });\n}\n\nfunction getVariables(\n document: { variableNames: ReadonlySet<string> },\n variables: Record<string, unknown>,\n language: ShopifyRequestContext[\"i18n\"][\"language\"],\n): Record<string, unknown> {\n if (!document.variableNames.has(\"language\")) return variables;\n if (\"language\" in variables) return variables;\n return { ...variables, language };\n}\n\nfunction throwIfAlreadyAborted(signals: AbortSignal[]): void {\n const abortedSignal = signals.find((signal) => signal.aborted);\n if (!abortedSignal) return;\n throw abortedSignal.reason ?? new DOMException(\"signal is aborted without reason\", \"AbortError\");\n}\n\nfunction throwIfCustomerAccountSignalAborted(\n signal: AbortSignal,\n timeoutSignal: AbortSignal,\n timeoutInMs: number,\n): void {\n if (!signal.aborted) return;\n if (timeoutSignal.aborted && signal.reason === timeoutSignal.reason) {\n const reason = timeoutSignal.reason;\n throw reason instanceof CustomerAccountTimeoutError\n ? reason\n : new CustomerAccountTimeoutError(timeoutInMs);\n }\n throw signal.reason ?? new DOMException(\"signal is aborted without reason\", \"AbortError\");\n}\n\nfunction isAbortError(cause: unknown): cause is DOMException {\n return cause instanceof DOMException && cause.name === \"AbortError\";\n}\n\nfunction parseGraphqlResponse(json: unknown): {\n data?: unknown;\n errors?: GraphQLFormattedError[];\n} {\n if (!isObjectRecord(json)) {\n throw new Error(\"Customer Account API returned unexpected JSON type\");\n }\n\n if (!(\"data\" in json) && !(\"errors\" in json)) {\n throw new Error(\"Customer Account API response must include data or errors\");\n }\n const errors = json.errors;\n if (errors !== undefined && !isGraphqlErrorArray(errors)) {\n throw new Error(\"Customer Account API returned invalid GraphQL errors\");\n }\n return { data: json.data, errors };\n}\n\nfunction isGraphqlErrorArray(value: unknown): value is GraphQLFormattedError[] {\n if (!Array.isArray(value)) return false;\n return value.every((error) => {\n return typeof error === \"object\" && error !== null && typeof error.message === \"string\";\n });\n}\n\nfunction validateShopId(shopId: string): void {\n if (!SHOP_ID_RE.test(shopId)) {\n throw new Error(\"shopId must be a numeric Shopify shop ID string\");\n }\n}\n\nfunction validateCustomerApiVersion(customerApiVersion: string): void {\n if (!CUSTOMER_API_VERSION_RE.test(customerApiVersion)) {\n throw new Error(\"customerApiVersion must use YYYY-MM format\");\n }\n}\n\nfunction validateAccessToken(accessToken: AccessToken): string {\n if (\n typeof accessToken !== \"string\" ||\n accessToken === \"\" ||\n accessToken.trim() !== accessToken ||\n hasAsciiControlCharacter(accessToken)\n ) {\n throw new CustomerAccountAuthenticationError();\n }\n return accessToken;\n}\n\nfunction validateGraphqlOptions(\n options: CustomerAccountGraphqlOptions<unknown> | undefined,\n): CustomerAccountGraphqlOptions<unknown> {\n if (typeof options !== \"object\" || options === null) {\n throw new CustomerAccountAuthenticationError();\n }\n return options;\n}\n\nfunction getOptionalVariables(variables: unknown): Record<string, unknown> {\n if (variables === undefined) return {};\n if (!isObjectRecord(variables)) {\n throw new TypeError(\"Customer Account API variables must be an object\");\n }\n return variables;\n}\n\nfunction hasAsciiControlCharacter(value: string): boolean {\n for (let index = 0; index < value.length; index++) {\n const codePoint = value.charCodeAt(index);\n if (codePoint <= MAX_ASCII_CONTROL_CODE_POINT || codePoint === ASCII_DELETE_CODE_POINT) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Customer Account API requires an HTTPS Origin, but local dev frameworks often\n * receive `http://localhost` requests. Keep that local-only exception without\n * weakening origin validation for non-local requests.\n */\nfunction getOrigin(requestUrl: string | undefined): string {\n if (!requestUrl) {\n throw new Error(\"requestContext.url is required for Customer Account API requests\");\n }\n\n const url = new URL(requestUrl);\n if (url.protocol === \"https:\") return url.origin;\n if (url.protocol === \"http:\" && LOCAL_ORIGIN_HOSTS.has(url.hostname)) {\n return `https://${url.host}`;\n }\n throw new Error(`Customer Account API origin must use HTTPS. Received: ${requestUrl}`);\n}\n"],"mappings":"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"}
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
//#region src/customer-account/errors.d.ts
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
* `CustomerAccountClient.graphql()` when the API responds with a non-OK
|
|
5
|
-
* HTTP status, when the response body cannot be parsed as JSON, or when the
|
|
6
|
-
* parsed response is missing `data`. Also thrown (without subclassing) for
|
|
7
|
-
* OAuth token-request timeouts and network failures.
|
|
3
|
+
* The error that a Customer Account API request throws when the request fails. The client throws this error for a non-OK HTTP status, a response that isn't valid GraphQL, a response without data, or a network failure. The OAuth callback also throws this error when its token request times out.
|
|
8
4
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* failures where no response arrived. `retryAfter` is populated only on
|
|
13
|
-
* non-OK responses.
|
|
5
|
+
* Catch this class to handle every Customer Account API failure, including authentication and timeout errors. Read `status`, `requestId`, and `retryAfter` to handle the failure. Network failures have no status or request ID, and only non-OK responses include a retry-after value.
|
|
6
|
+
*
|
|
7
|
+
* @publicDocs
|
|
14
8
|
*/
|
|
15
9
|
declare class CustomerAccountApiError extends Error {
|
|
16
|
-
/** HTTP status
|
|
10
|
+
/** The HTTP status of the response, including a response that Hydrogen can't parse. */
|
|
17
11
|
readonly status?: number;
|
|
18
|
-
/**
|
|
12
|
+
/** The response's `x-request-id` header. Include the ID in Shopify support requests. */
|
|
19
13
|
readonly requestId?: string;
|
|
20
|
-
/**
|
|
14
|
+
/** The `retry-after` header on a non-OK response. Use the value to schedule a retry of a rate-limited request. */
|
|
21
15
|
readonly retryAfter?: string;
|
|
16
|
+
/** `CustomerAccountApiError`. Each subclass sets its own class name. */
|
|
17
|
+
name: string;
|
|
18
|
+
/** Describes the failure, such as the HTTP status that the API returned. */
|
|
19
|
+
message: string;
|
|
20
|
+
/** The stack trace, when the JavaScript runtime records one. */
|
|
21
|
+
stack?: string;
|
|
22
22
|
constructor(message: string, options?: {
|
|
23
23
|
status?: number;
|
|
24
24
|
requestId?: string;
|
|
@@ -27,44 +27,53 @@ declare class CustomerAccountApiError extends Error {
|
|
|
27
27
|
});
|
|
28
28
|
}
|
|
29
29
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
30
|
+
* The error that a Customer Account API request throws when the access token is missing or malformed. The client throws this error before it sends the request when the token is empty, has leading or trailing whitespace, or contains control characters. The client also throws this error when you omit the options argument.
|
|
31
|
+
*
|
|
32
|
+
* When the API rejects a token, the client throws `CustomerAccountApiError` with the response status.
|
|
33
|
+
*
|
|
34
|
+
* @publicDocs
|
|
35
35
|
*/
|
|
36
36
|
declare class CustomerAccountAuthenticationError extends CustomerAccountApiError {
|
|
37
|
+
/** Always `CustomerAccountAuthenticationError`. */
|
|
38
|
+
name: string;
|
|
39
|
+
/** Always `"Customer Account API access token is required"`. */
|
|
40
|
+
message: string;
|
|
41
|
+
/** The stack trace, when the JavaScript runtime records one. */
|
|
42
|
+
stack?: string;
|
|
37
43
|
constructor(message?: string);
|
|
38
44
|
}
|
|
39
45
|
/**
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* {@link CustomerAccountApiError}.
|
|
46
|
+
* The error that a Customer Account API request throws when the request takes longer than the client's timeout. The timeout covers the whole request, including reading the response body.
|
|
47
|
+
*
|
|
48
|
+
* @publicDocs
|
|
44
49
|
*/
|
|
45
50
|
declare class CustomerAccountTimeoutError extends CustomerAccountApiError {
|
|
46
|
-
/** The timeout
|
|
51
|
+
/** The timeout that the request exceeded, in milliseconds. */
|
|
47
52
|
readonly timeoutInMs: number;
|
|
53
|
+
/** Always `CustomerAccountTimeoutError`. */
|
|
54
|
+
name: string;
|
|
55
|
+
/** States the timeout, such as `"Customer Account API request timed out after 30000ms"`. */
|
|
56
|
+
message: string;
|
|
57
|
+
/** The stack trace, when the JavaScript runtime records one. */
|
|
58
|
+
stack?: string;
|
|
48
59
|
constructor(timeoutInMs: number);
|
|
49
60
|
}
|
|
50
61
|
/**
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* `undefined`). Extends `Error` directly, **not**
|
|
55
|
-
* {@link CustomerAccountApiError}. A `catch` block for
|
|
56
|
-
* `CustomerAccountApiError` will not catch this error.
|
|
62
|
+
* The error that the OAuth callback throws when customer sign-in fails. Sign-in fails when the callback doesn't match the sign-in that `prepareLoginUrl()` started, when that sign-in started more than 10 minutes earlier, when the code exchange fails, or when Shopify's tokens fail validation. The authorize route catches this error and redirects the customer to the failed-login path. Token refreshes never throw this error, and a failed refresh returns `undefined`.
|
|
63
|
+
*
|
|
64
|
+
* Read `code` to handle each failure. The codes are `missing_callback_params`, `state_mismatch`, `missing_pending_login`, `token_exchange_rejected`, `token_exchange_failed`, `invalid_token_response`, `nonce_mismatch`, `issuer_mismatch`, `audience_mismatch`, `expired_id_token`, and `invalid_id_token`.
|
|
57
65
|
*
|
|
58
|
-
*
|
|
59
|
-
* `"missing_callback_params"`, `"state_mismatch"`,
|
|
60
|
-
* `"token_exchange_rejected"`, `"token_exchange_failed"`,
|
|
61
|
-
* `"invalid_token_response"`, `"nonce_mismatch"`, `"issuer_mismatch"`,
|
|
62
|
-
* `"audience_mismatch"`, `"expired_id_token"`, `"invalid_id_token"`,
|
|
63
|
-
* `"missing_pending_login"`.
|
|
66
|
+
* @publicDocs
|
|
64
67
|
*/
|
|
65
68
|
declare class CustomerAccountOAuthError extends Error {
|
|
66
|
-
/**
|
|
69
|
+
/** The failure code, one of the codes in the class description. */
|
|
67
70
|
readonly code: string;
|
|
71
|
+
/** Always `CustomerAccountOAuthError`. */
|
|
72
|
+
name: string;
|
|
73
|
+
/** Describes the sign-in failure. Read `code` to handle the failure. */
|
|
74
|
+
message: string;
|
|
75
|
+
/** The stack trace, when the JavaScript runtime records one. */
|
|
76
|
+
stack?: string;
|
|
68
77
|
constructor(code: string, message: string, options?: {
|
|
69
78
|
cause?: unknown;
|
|
70
79
|
});
|
|
@@ -1,23 +1,17 @@
|
|
|
1
1
|
//#region src/customer-account/errors.ts
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
* `CustomerAccountClient.graphql()` when the API responds with a non-OK
|
|
5
|
-
* HTTP status, when the response body cannot be parsed as JSON, or when the
|
|
6
|
-
* parsed response is missing `data`. Also thrown (without subclassing) for
|
|
7
|
-
* OAuth token-request timeouts and network failures.
|
|
3
|
+
* The error that a Customer Account API request throws when the request fails. The client throws this error for a non-OK HTTP status, a response that isn't valid GraphQL, a response without data, or a network failure. The OAuth callback also throws this error when its token request times out.
|
|
8
4
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* failures where no response arrived. `retryAfter` is populated only on
|
|
13
|
-
* non-OK responses.
|
|
5
|
+
* Catch this class to handle every Customer Account API failure, including authentication and timeout errors. Read `status`, `requestId`, and `retryAfter` to handle the failure. Network failures have no status or request ID, and only non-OK responses include a retry-after value.
|
|
6
|
+
*
|
|
7
|
+
* @publicDocs
|
|
14
8
|
*/
|
|
15
9
|
var CustomerAccountApiError = class extends Error {
|
|
16
|
-
/** HTTP status
|
|
10
|
+
/** The HTTP status of the response, including a response that Hydrogen can't parse. */
|
|
17
11
|
status;
|
|
18
|
-
/**
|
|
12
|
+
/** The response's `x-request-id` header. Include the ID in Shopify support requests. */
|
|
19
13
|
requestId;
|
|
20
|
-
/**
|
|
14
|
+
/** The `retry-after` header on a non-OK response. Use the value to schedule a retry of a rate-limited request. */
|
|
21
15
|
retryAfter;
|
|
22
16
|
constructor(message, options) {
|
|
23
17
|
super(message, options?.cause ? { cause: options.cause } : void 0);
|
|
@@ -28,11 +22,11 @@ var CustomerAccountApiError = class extends Error {
|
|
|
28
22
|
}
|
|
29
23
|
};
|
|
30
24
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
25
|
+
* The error that a Customer Account API request throws when the access token is missing or malformed. The client throws this error before it sends the request when the token is empty, has leading or trailing whitespace, or contains control characters. The client also throws this error when you omit the options argument.
|
|
26
|
+
*
|
|
27
|
+
* When the API rejects a token, the client throws `CustomerAccountApiError` with the response status.
|
|
28
|
+
*
|
|
29
|
+
* @publicDocs
|
|
36
30
|
*/
|
|
37
31
|
var CustomerAccountAuthenticationError = class extends CustomerAccountApiError {
|
|
38
32
|
constructor(message = "Customer Account API access token is required") {
|
|
@@ -41,13 +35,12 @@ var CustomerAccountAuthenticationError = class extends CustomerAccountApiError {
|
|
|
41
35
|
}
|
|
42
36
|
};
|
|
43
37
|
/**
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
* {@link CustomerAccountApiError}.
|
|
38
|
+
* The error that a Customer Account API request throws when the request takes longer than the client's timeout. The timeout covers the whole request, including reading the response body.
|
|
39
|
+
*
|
|
40
|
+
* @publicDocs
|
|
48
41
|
*/
|
|
49
42
|
var CustomerAccountTimeoutError = class extends CustomerAccountApiError {
|
|
50
|
-
/** The timeout
|
|
43
|
+
/** The timeout that the request exceeded, in milliseconds. */
|
|
51
44
|
timeoutInMs;
|
|
52
45
|
constructor(timeoutInMs) {
|
|
53
46
|
super(`Customer Account API request timed out after ${timeoutInMs}ms`);
|
|
@@ -56,22 +49,14 @@ var CustomerAccountTimeoutError = class extends CustomerAccountApiError {
|
|
|
56
49
|
}
|
|
57
50
|
};
|
|
58
51
|
/**
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
* `undefined`). Extends `Error` directly, **not**
|
|
63
|
-
* {@link CustomerAccountApiError}. A `catch` block for
|
|
64
|
-
* `CustomerAccountApiError` will not catch this error.
|
|
52
|
+
* The error that the OAuth callback throws when customer sign-in fails. Sign-in fails when the callback doesn't match the sign-in that `prepareLoginUrl()` started, when that sign-in started more than 10 minutes earlier, when the code exchange fails, or when Shopify's tokens fail validation. The authorize route catches this error and redirects the customer to the failed-login path. Token refreshes never throw this error, and a failed refresh returns `undefined`.
|
|
53
|
+
*
|
|
54
|
+
* Read `code` to handle each failure. The codes are `missing_callback_params`, `state_mismatch`, `missing_pending_login`, `token_exchange_rejected`, `token_exchange_failed`, `invalid_token_response`, `nonce_mismatch`, `issuer_mismatch`, `audience_mismatch`, `expired_id_token`, and `invalid_id_token`.
|
|
65
55
|
*
|
|
66
|
-
*
|
|
67
|
-
* `"missing_callback_params"`, `"state_mismatch"`,
|
|
68
|
-
* `"token_exchange_rejected"`, `"token_exchange_failed"`,
|
|
69
|
-
* `"invalid_token_response"`, `"nonce_mismatch"`, `"issuer_mismatch"`,
|
|
70
|
-
* `"audience_mismatch"`, `"expired_id_token"`, `"invalid_id_token"`,
|
|
71
|
-
* `"missing_pending_login"`.
|
|
56
|
+
* @publicDocs
|
|
72
57
|
*/
|
|
73
58
|
var CustomerAccountOAuthError = class extends Error {
|
|
74
|
-
/**
|
|
59
|
+
/** The failure code, one of the codes in the class description. */
|
|
75
60
|
code;
|
|
76
61
|
constructor(code, message, options) {
|
|
77
62
|
super(message, options?.cause ? { cause: options.cause } : void 0);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.mjs","names":[],"sources":["../../src/customer-account/errors.ts"],"sourcesContent":["/**\n *
|
|
1
|
+
{"version":3,"file":"errors.mjs","names":[],"sources":["../../src/customer-account/errors.ts"],"sourcesContent":["/**\n * The error that a Customer Account API request throws when the request fails. The client throws this error for a non-OK HTTP status, a response that isn't valid GraphQL, a response without data, or a network failure. The OAuth callback also throws this error when its token request times out.\n *\n * Catch this class to handle every Customer Account API failure, including authentication and timeout errors. Read `status`, `requestId`, and `retryAfter` to handle the failure. Network failures have no status or request ID, and only non-OK responses include a retry-after value.\n *\n * @publicDocs\n */\nexport class CustomerAccountApiError extends Error {\n /** The HTTP status of the response, including a response that Hydrogen can't parse. */\n readonly status?: number;\n /** The response's `x-request-id` header. Include the ID in Shopify support requests. */\n readonly requestId?: string;\n /** The `retry-after` header on a non-OK response. Use the value to schedule a retry of a rate-limited request. */\n readonly retryAfter?: string;\n\n /** `CustomerAccountApiError`. Each subclass sets its own class name. */\n declare name: string;\n /** Describes the failure, such as the HTTP status that the API returned. */\n declare message: string;\n /** The stack trace, when the JavaScript runtime records one. */\n declare stack?: string;\n\n constructor(\n message: string,\n options?: { status?: number; requestId?: string; retryAfter?: string; cause?: unknown },\n ) {\n super(message, options?.cause ? { cause: options.cause } : undefined);\n this.name = \"CustomerAccountApiError\";\n this.status = options?.status;\n this.requestId = options?.requestId;\n this.retryAfter = options?.retryAfter;\n }\n}\n\n/**\n * The error that a Customer Account API request throws when the access token is missing or malformed. The client throws this error before it sends the request when the token is empty, has leading or trailing whitespace, or contains control characters. The client also throws this error when you omit the options argument.\n *\n * When the API rejects a token, the client throws `CustomerAccountApiError` with the response status.\n *\n * @publicDocs\n */\nexport class CustomerAccountAuthenticationError extends CustomerAccountApiError {\n /** Always `CustomerAccountAuthenticationError`. */\n declare name: string;\n /** Always `\"Customer Account API access token is required\"`. */\n declare message: string;\n /** The stack trace, when the JavaScript runtime records one. */\n declare stack?: string;\n\n constructor(message = \"Customer Account API access token is required\") {\n super(message);\n this.name = \"CustomerAccountAuthenticationError\";\n }\n}\n\n/**\n * The error that a Customer Account API request throws when the request takes longer than the client's timeout. The timeout covers the whole request, including reading the response body.\n *\n * @publicDocs\n */\nexport class CustomerAccountTimeoutError extends CustomerAccountApiError {\n /** The timeout that the request exceeded, in milliseconds. */\n readonly timeoutInMs: number;\n\n /** Always `CustomerAccountTimeoutError`. */\n declare name: string;\n /** States the timeout, such as `\"Customer Account API request timed out after 30000ms\"`. */\n declare message: string;\n /** The stack trace, when the JavaScript runtime records one. */\n declare stack?: string;\n\n constructor(timeoutInMs: number) {\n super(`Customer Account API request timed out after ${timeoutInMs}ms`);\n this.name = \"CustomerAccountTimeoutError\";\n this.timeoutInMs = timeoutInMs;\n }\n}\n\n/**\n * The error that the OAuth callback throws when customer sign-in fails. Sign-in fails when the callback doesn't match the sign-in that `prepareLoginUrl()` started, when that sign-in started more than 10 minutes earlier, when the code exchange fails, or when Shopify's tokens fail validation. The authorize route catches this error and redirects the customer to the failed-login path. Token refreshes never throw this error, and a failed refresh returns `undefined`.\n *\n * Read `code` to handle each failure. The codes are `missing_callback_params`, `state_mismatch`, `missing_pending_login`, `token_exchange_rejected`, `token_exchange_failed`, `invalid_token_response`, `nonce_mismatch`, `issuer_mismatch`, `audience_mismatch`, `expired_id_token`, and `invalid_id_token`.\n *\n * @publicDocs\n */\nexport class CustomerAccountOAuthError extends Error {\n /** The failure code, one of the codes in the class description. */\n readonly code: string;\n\n /** Always `CustomerAccountOAuthError`. */\n declare name: string;\n /** Describes the sign-in failure. Read `code` to handle the failure. */\n declare message: string;\n /** The stack trace, when the JavaScript runtime records one. */\n declare stack?: string;\n\n constructor(code: string, message: string, options?: { cause?: unknown }) {\n super(message, options?.cause ? { cause: options.cause } : undefined);\n this.name = \"CustomerAccountOAuthError\";\n this.code = code;\n }\n}\n"],"mappings":";;;;;;;;AAOA,IAAa,0BAAb,cAA6C,MAAM;;CAEjD,AAAS;;CAET,AAAS;;CAET,AAAS;CAST,YACE,SACA,SACA;AACA,QAAM,SAAS,SAAS,QAAQ,EAAE,OAAO,QAAQ,OAAO,GAAG,OAAU;AACrE,OAAK,OAAO;AACZ,OAAK,SAAS,SAAS;AACvB,OAAK,YAAY,SAAS;AAC1B,OAAK,aAAa,SAAS;;;;;;;;;;AAW/B,IAAa,qCAAb,cAAwD,wBAAwB;CAQ9E,YAAY,UAAU,iDAAiD;AACrE,QAAM,QAAQ;AACd,OAAK,OAAO;;;;;;;;AAShB,IAAa,8BAAb,cAAiD,wBAAwB;;CAEvE,AAAS;CAST,YAAY,aAAqB;AAC/B,QAAM,gDAAgD,YAAY,IAAI;AACtE,OAAK,OAAO;AACZ,OAAK,cAAc;;;;;;;;;;AAWvB,IAAa,4BAAb,cAA+C,MAAM;;CAEnD,AAAS;CAST,YAAY,MAAc,SAAiB,SAA+B;AACxE,QAAM,SAAS,SAAS,QAAQ,EAAE,OAAO,QAAQ,OAAO,GAAG,OAAU;AACrE,OAAK,OAAO;AACZ,OAAK,OAAO"}
|
|
@@ -10,34 +10,28 @@ type CustomerAccountTadaGql = initGraphQLTada<{
|
|
|
10
10
|
}>;
|
|
11
11
|
declare const CUSTOMER_ACCOUNT_DOCUMENT: unique symbol;
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
13
|
+
* A Customer Account API query or mutation that `gql` from `@shopify/hydrogen/customer-account` returns. TypeScript infers the result and variables types from the document's GraphQL source.
|
|
14
14
|
*
|
|
15
|
-
*
|
|
16
|
-
* `InferResult` and `InferVariables` can derive typed responses. The
|
|
17
|
-
* `[CUSTOMER_ACCOUNT_DOCUMENT]` brand is private and cannot be constructed
|
|
18
|
-
* externally — only `gql()` produces valid instances. Passing a plain object
|
|
19
|
-
* with a `source` property to `CustomerAccountClient.graphql()` will throw
|
|
20
|
-
* a `TypeError` at runtime.
|
|
15
|
+
* Create documents only with the Customer Account `gql` function. The client throws a `TypeError` for any other object.
|
|
21
16
|
*/
|
|
22
17
|
type CustomerAccountDocument<Result = unknown, Variables = never, Source extends string = string> = DocumentDecoration<Result, Variables> & {
|
|
23
18
|
readonly [CUSTOMER_ACCOUNT_DOCUMENT]: true;
|
|
24
19
|
readonly source: Source;
|
|
25
20
|
};
|
|
26
|
-
/**
|
|
21
|
+
/** Any Customer Account API document. Use the type as a constraint when a function accepts any document. */
|
|
27
22
|
type AnyCustomerAccountDocument = CustomerAccountDocument<unknown, never, string>;
|
|
28
|
-
/** Extracts the source string literal type from a
|
|
23
|
+
/** Extracts the source string literal type from a Customer Account document. */
|
|
29
24
|
type SourceOf<Doc> = Doc extends {
|
|
30
25
|
readonly source: infer Source extends string;
|
|
31
26
|
} ? Source : never;
|
|
32
27
|
/**
|
|
33
|
-
*
|
|
34
|
-
* documents at the type level, joining each with a newline. An empty
|
|
35
|
-
* tuple produces `""`.
|
|
28
|
+
* Joins the source strings of a tuple of fragment documents with newlines at the type level. An empty tuple produces `""`.
|
|
36
29
|
*/
|
|
37
30
|
type FragmentSources<Fragments extends readonly AnyCustomerAccountDocument[]> = Fragments extends readonly [] ? "" : Fragments extends readonly [infer Only extends AnyCustomerAccountDocument] ? SourceOf<Only> : Fragments extends readonly [infer First extends AnyCustomerAccountDocument, ...infer Rest extends readonly AnyCustomerAccountDocument[]] ? `${SourceOf<First>}\n${FragmentSources<Rest>}` : string;
|
|
38
31
|
/**
|
|
39
|
-
* Combines an operation source with its
|
|
40
|
-
*
|
|
32
|
+
* Combines an operation source with the sources of its fragments at the type level. With no fragments, the result is the operation source.
|
|
33
|
+
*
|
|
34
|
+
* @publicDocs
|
|
41
35
|
*/
|
|
42
36
|
type ComposedSource<Source extends string, Fragments extends readonly AnyCustomerAccountDocument[]> = FragmentSources<Fragments> extends "" ? Source : `${Source}\n${FragmentSources<Fragments>}`;
|
|
43
37
|
type CustomerAccountGql = {
|
|
@@ -45,16 +39,9 @@ type CustomerAccountGql = {
|
|
|
45
39
|
<const Source extends string, const Fragments extends readonly AnyCustomerAccountDocument[], const DocumentSource extends string = ComposedSource<Source, Fragments>>(source: Source, fragments: Fragments): CustomerAccountDocument<InferResult<DocumentSource>, InferVariables<DocumentSource>, DocumentSource>;
|
|
46
40
|
} & CustomerAccountTadaGql;
|
|
47
41
|
/**
|
|
48
|
-
* Creates a
|
|
49
|
-
* string. This is a regular function call, not a tagged template literal.
|
|
50
|
-
*
|
|
51
|
-
* The returned document is branded with a private Symbol that
|
|
52
|
-
* `CustomerAccountClient.graphql()` validates at runtime — passing a plain
|
|
53
|
-
* object with a `source` property will throw a `TypeError`.
|
|
42
|
+
* Creates a typed Customer Account API query or mutation from a GraphQL source string. Pass the document to the Customer Account API client. Call `gql` as a regular function. Tagged template syntax doesn't work.
|
|
54
43
|
*
|
|
55
|
-
*
|
|
56
|
-
* are deduplicated by source string identity (`Set` check, not by fragment
|
|
57
|
-
* name) and appended to the operation source.
|
|
44
|
+
* Pass an array of fragment documents as the second argument to append the fragments to the operation. Each fragment must come from this `gql` function, or the call throws a `TypeError`.
|
|
58
45
|
*
|
|
59
46
|
* @example
|
|
60
47
|
* ```ts
|
|
@@ -90,6 +77,7 @@ type CustomerAccountGql = {
|
|
|
90
77
|
* }
|
|
91
78
|
* `, [ORDER_FIELDS]);
|
|
92
79
|
* ```
|
|
80
|
+
* @publicDocs
|
|
93
81
|
*/
|
|
94
82
|
declare const gql: CustomerAccountGql;
|
|
95
83
|
//#endregion
|
|
@@ -4,16 +4,9 @@ import { isObjectRecord } from "../core/utils/record.mjs";
|
|
|
4
4
|
const CUSTOMER_ACCOUNT_DOCUMENT = Symbol("CustomerAccountDocument");
|
|
5
5
|
const VARIABLE_DEFINITION_RE = /\$([_A-Za-z][_0-9A-Za-z]*)\s*:/g;
|
|
6
6
|
/**
|
|
7
|
-
* Creates a
|
|
8
|
-
* string. This is a regular function call, not a tagged template literal.
|
|
7
|
+
* Creates a typed Customer Account API query or mutation from a GraphQL source string. Pass the document to the Customer Account API client. Call `gql` as a regular function. Tagged template syntax doesn't work.
|
|
9
8
|
*
|
|
10
|
-
*
|
|
11
|
-
* `CustomerAccountClient.graphql()` validates at runtime — passing a plain
|
|
12
|
-
* object with a `source` property will throw a `TypeError`.
|
|
13
|
-
*
|
|
14
|
-
* An optional second argument accepts an array of fragment documents. Fragments
|
|
15
|
-
* are deduplicated by source string identity (`Set` check, not by fragment
|
|
16
|
-
* name) and appended to the operation source.
|
|
9
|
+
* Pass an array of fragment documents as the second argument to append the fragments to the operation. Each fragment must come from this `gql` function, or the call throws a `TypeError`.
|
|
17
10
|
*
|
|
18
11
|
* @example
|
|
19
12
|
* ```ts
|
|
@@ -49,6 +42,7 @@ const VARIABLE_DEFINITION_RE = /\$([_A-Za-z][_0-9A-Za-z]*)\s*:/g;
|
|
|
49
42
|
* }
|
|
50
43
|
* `, [ORDER_FIELDS]);
|
|
51
44
|
* ```
|
|
45
|
+
* @publicDocs
|
|
52
46
|
*/
|
|
53
47
|
const gql = ((source, fragments) => {
|
|
54
48
|
let query = source;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graphql.mjs","names":[],"sources":["../../src/customer-account/graphql.ts"],"sourcesContent":["import type { DocumentDecoration, initGraphQLTada as InitGraphQLTada } from \"gql.tada\";\n\nimport { isObjectRecord } from \"../core/utils/record\";\nimport type { introspection } from \"../graphql/generated/customer-account-graphql-env\";\nimport type { CustomerAccountScalars } from \"../graphql/scalars\";\nimport type { InferResult, InferVariables } from \"./type-resolver\";\n\ntype CustomerAccountTadaGql = InitGraphQLTada<{\n introspection: introspection;\n scalars: CustomerAccountScalars;\n}>;\n\nconst CUSTOMER_ACCOUNT_DOCUMENT = Symbol(\"CustomerAccountDocument\");\nconst VARIABLE_DEFINITION_RE = /\\$([_A-Za-z][_0-9A-Za-z]*)\\s*:/g;\n\n/**\n *
|
|
1
|
+
{"version":3,"file":"graphql.mjs","names":[],"sources":["../../src/customer-account/graphql.ts"],"sourcesContent":["import type { DocumentDecoration, initGraphQLTada as InitGraphQLTada } from \"gql.tada\";\n\nimport { isObjectRecord } from \"../core/utils/record\";\nimport type { introspection } from \"../graphql/generated/customer-account-graphql-env\";\nimport type { CustomerAccountScalars } from \"../graphql/scalars\";\nimport type { InferResult, InferVariables } from \"./type-resolver\";\n\ntype CustomerAccountTadaGql = InitGraphQLTada<{\n introspection: introspection;\n scalars: CustomerAccountScalars;\n}>;\n\nconst CUSTOMER_ACCOUNT_DOCUMENT = Symbol(\"CustomerAccountDocument\");\nconst VARIABLE_DEFINITION_RE = /\\$([_A-Za-z][_0-9A-Za-z]*)\\s*:/g;\n\n/**\n * A Customer Account API query or mutation that `gql` from `@shopify/hydrogen/customer-account` returns. TypeScript infers the result and variables types from the document's GraphQL source.\n *\n * Create documents only with the Customer Account `gql` function. The client throws a `TypeError` for any other object.\n */\nexport type CustomerAccountDocument<\n Result = unknown,\n Variables = never,\n Source extends string = string,\n> = DocumentDecoration<Result, Variables> & {\n readonly [CUSTOMER_ACCOUNT_DOCUMENT]: true;\n readonly source: Source;\n};\n\n/** Any Customer Account API document. Use the type as a constraint when a function accepts any document. */\nexport type AnyCustomerAccountDocument = CustomerAccountDocument<unknown, never, string>;\n\n/** Extracts the source string literal type from a Customer Account document. */\nexport type SourceOf<Doc> = Doc extends { readonly source: infer Source extends string }\n ? Source\n : never;\n\n/**\n * Joins the source strings of a tuple of fragment documents with newlines at the type level. An empty tuple produces `\"\"`.\n */\nexport type FragmentSources<Fragments extends readonly AnyCustomerAccountDocument[]> =\n Fragments extends readonly []\n ? \"\"\n : Fragments extends readonly [infer Only extends AnyCustomerAccountDocument]\n ? SourceOf<Only>\n : Fragments extends readonly [\n infer First extends AnyCustomerAccountDocument,\n ...infer Rest extends readonly AnyCustomerAccountDocument[],\n ]\n ? `${SourceOf<First>}\\n${FragmentSources<Rest>}`\n : string;\n\n/**\n * Combines an operation source with the sources of its fragments at the type level. With no fragments, the result is the operation source.\n *\n * @publicDocs\n */\nexport type ComposedSource<\n Source extends string,\n Fragments extends readonly AnyCustomerAccountDocument[],\n> = FragmentSources<Fragments> extends \"\" ? Source : `${Source}\\n${FragmentSources<Fragments>}`;\n\ntype CustomerAccountDocumentValue = AnyCustomerAccountDocument & {\n readonly variableNames: ReadonlySet<string>;\n};\n\ntype CustomerAccountGql = {\n <const Source extends string>(\n source: Source,\n ): CustomerAccountDocument<InferResult<Source>, InferVariables<Source>, Source>;\n <\n const Source extends string,\n const Fragments extends readonly AnyCustomerAccountDocument[],\n const DocumentSource extends string = ComposedSource<Source, Fragments>,\n >(\n source: Source,\n fragments: Fragments,\n ): CustomerAccountDocument<\n InferResult<DocumentSource>,\n InferVariables<DocumentSource>,\n DocumentSource\n >;\n} & CustomerAccountTadaGql;\n\n/**\n * Creates a typed Customer Account API query or mutation from a GraphQL source string. Pass the document to the Customer Account API client. Call `gql` as a regular function. Tagged template syntax doesn't work.\n *\n * Pass an array of fragment documents as the second argument to append the fragments to the operation. Each fragment must come from this `gql` function, or the call throws a `TypeError`.\n *\n * @example\n * ```ts\n * import { gql } from \"@shopify/hydrogen/customer-account\";\n *\n * const CUSTOMER_QUERY = gql(`\n * query CustomerDetails {\n * customer {\n * firstName\n * lastName\n * emailAddress { emailAddress }\n * }\n * }\n * `);\n * ```\n *\n * @example\n * ```ts\n * const ORDER_FIELDS = gql(`\n * fragment OrderFields on Order {\n * id\n * totalPrice { amount currencyCode }\n * }\n * `);\n *\n * const ORDERS_QUERY = gql(`\n * query CustomerOrders {\n * customer {\n * orders(first: 10) {\n * nodes { ...OrderFields }\n * }\n * }\n * }\n * `, [ORDER_FIELDS]);\n * ```\n * @publicDocs\n */\n// oxlint-disable-next-line typescript-eslint/consistent-type-assertions -- gql.tada adds phantom helper properties to the function type that are not used at runtime.\nexport const gql = ((source: string, fragments?: readonly CustomerAccountDocument[]) => {\n let query = source;\n\n if (fragments) {\n const seen = new Set<string>();\n for (const fragment of fragments) {\n assertCustomerAccountDocument(fragment);\n if (!seen.has(fragment.source)) {\n seen.add(fragment.source);\n query += \"\\n\" + fragment.source;\n }\n }\n }\n\n const document = {\n [CUSTOMER_ACCOUNT_DOCUMENT]: true,\n source: query,\n variableNames: getVariableNames(query),\n } satisfies CustomerAccountDocumentValue;\n return document;\n}) as unknown as CustomerAccountGql;\n\nexport function isCustomerAccountDocument(value: unknown): value is CustomerAccountDocumentValue {\n if (!isObjectRecord(value)) return false;\n return value[CUSTOMER_ACCOUNT_DOCUMENT] === true && typeof value.source === \"string\";\n}\n\nexport function assertCustomerAccountDocument(\n value: unknown,\n): asserts value is CustomerAccountDocumentValue {\n if (!isCustomerAccountDocument(value)) {\n throw new TypeError(\"Expected a Customer Account API document returned by CAAPI.gql().\");\n }\n}\n\nfunction getVariableNames(source: string): ReadonlySet<string> {\n const names = new Set<string>();\n for (const match of source.matchAll(VARIABLE_DEFINITION_RE)) {\n names.add(match[1]);\n }\n return names;\n}\n\n/**\n * Creates a typed Customer Account API query or mutation from a GraphQL source string. Pass the document to the Customer Account API client. Call `gql` as a regular function.\n *\n * Pass an array of fragment documents as the second argument to append the fragments to the operation. Each fragment must come from this `gql` function, or the call throws a `TypeError`.\n *\n * To validate documents, run `hydrogen gql check` in your `typecheck` script with the `@shopify/hydrogen/ts-plugin` setup. Framework typecheck commands don't validate the documents.\n *\n * @publicDocs\n */\nexport type CustomerAccountGqlForDocs =\n /**\n * @param source - The GraphQL source of an operation or a fragment.\n * @param fragments - The fragment documents that the operation uses.\n * @returns A typed document to pass to the Customer Account API client.\n */\n (source: string, fragments?: readonly AnyCustomerAccountDocument[]) => AnyCustomerAccountDocument;\n"],"mappings":";;;AAYA,MAAM,4BAA4B,OAAO,0BAA0B;AACnE,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiH/B,MAAa,QAAQ,QAAgB,cAAmD;CACtF,IAAI,QAAQ;AAEZ,KAAI,WAAW;EACb,MAAM,uBAAO,IAAI,KAAa;AAC9B,OAAK,MAAM,YAAY,WAAW;AAChC,iCAA8B,SAAS;AACvC,OAAI,CAAC,KAAK,IAAI,SAAS,OAAO,EAAE;AAC9B,SAAK,IAAI,SAAS,OAAO;AACzB,aAAS,OAAO,SAAS;;;;AAU/B,QAAO;GAJJ,4BAA4B;EAC7B,QAAQ;EACR,eAAe,iBAAiB,MAAM;EAEzB;;AAGjB,SAAgB,0BAA0B,OAAuD;AAC/F,KAAI,CAAC,eAAe,MAAM,CAAE,QAAO;AACnC,QAAO,MAAM,+BAA+B,QAAQ,OAAO,MAAM,WAAW;;AAG9E,SAAgB,8BACd,OAC+C;AAC/C,KAAI,CAAC,0BAA0B,MAAM,CACnC,OAAM,IAAI,UAAU,oEAAoE;;AAI5F,SAAS,iBAAiB,QAAqC;CAC7D,MAAM,wBAAQ,IAAI,KAAa;AAC/B,MAAK,MAAM,SAAS,OAAO,SAAS,uBAAuB,CACzD,OAAM,IAAI,MAAM,GAAG;AAErB,QAAO"}
|