From 4a50bce0d0ec108af721a0dd2bc0910b77aeef9e Mon Sep 17 00:00:00 2001 From: Bret Little Date: Tue, 25 Jul 2023 09:46:47 -0400 Subject: [PATCH] Fix docs --- .../docs/generated/generated_docs_data.json | 4 ++-- .../docs/generated/generated_docs_data.json | 22 +++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/hydrogen-react/docs/generated/generated_docs_data.json b/packages/hydrogen-react/docs/generated/generated_docs_data.json index 04d7a6aee5..f4101acf24 100644 --- a/packages/hydrogen-react/docs/generated/generated_docs_data.json +++ b/packages/hydrogen-react/docs/generated/generated_docs_data.json @@ -6720,7 +6720,7 @@ "name": "StorefrontClientReturn", "value": "StorefrontClientReturn" }, - "value": "export function createStorefrontClient(\n props: StorefrontClientProps,\n): StorefrontClientReturn {\n const {\n storeDomain,\n privateStorefrontToken,\n publicStorefrontToken,\n storefrontApiVersion = SFAPI_VERSION,\n contentType,\n } = props;\n\n if (storefrontApiVersion !== SFAPI_VERSION) {\n warnOnce(\n `StorefrontClient: The Storefront API version that you're using is different than the version this build of Hydrogen React is targeting. You may run into unexpected errors if these versions don't match. Received verion: \"${storefrontApiVersion}\"; expected version \"${SFAPI_VERSION}\"`,\n );\n }\n\n // only warn if not in a browser environment\n if (__HYDROGEN_DEV__ && !privateStorefrontToken && !globalThis.document) {\n warnOnce(\n `StorefrontClient: Using a private storefront token is recommended for server environments. Refer to the authentication https://shopify.dev/api/storefront#authentication documentation for more details.`,\n );\n }\n\n // only warn if in a browser environment and you're using the privateStorefrontToken\n if (__HYDROGEN_DEV__ && privateStorefrontToken && globalThis.document) {\n warnOnce(\n `StorefrontClient: You are attempting to use a private token in an environment where it can be easily accessed by anyone. This is a security risk; please use the public token and the 'publicStorefrontToken' prop`,\n );\n }\n\n const isMockShop = (domain: string): boolean => domain.includes('mock.shop');\n const getShopifyDomain: StorefrontClientReturn['getShopifyDomain'] = (\n overrideProps,\n ) => {\n const domain = overrideProps?.storeDomain ?? storeDomain;\n return domain.includes('://') ? domain : `https://${domain}`;\n };\n\n return {\n getShopifyDomain,\n getStorefrontApiUrl(overrideProps): string {\n const domain = getShopifyDomain(overrideProps);\n const apiUrl = domain + (domain.endsWith('/') ? 'api' : '/api');\n\n if (isMockShop(domain)) return apiUrl;\n\n return `${apiUrl}/${\n overrideProps?.storefrontApiVersion ?? storefrontApiVersion\n }/graphql.json`;\n },\n getPrivateTokenHeaders(overrideProps): Record {\n if (\n !privateStorefrontToken &&\n !overrideProps?.privateStorefrontToken &&\n !isMockShop(storeDomain)\n ) {\n throw new Error(\n `StorefrontClient: You did not pass in a 'privateStorefrontToken' while using 'getPrivateTokenHeaders()'`,\n );\n }\n\n if (__HYDROGEN_DEV__ && !overrideProps?.buyerIp) {\n warnOnce(\n `StorefrontClient: it is recommended to pass in the 'buyerIp' property which improves analytics and data in the admin.`,\n );\n }\n\n const finalContentType = overrideProps?.contentType ?? contentType;\n\n return {\n // default to json\n 'content-type':\n finalContentType === 'graphql'\n ? 'application/graphql'\n : 'application/json',\n 'X-SDK-Variant': 'hydrogen-react',\n 'X-SDK-Variant-Source': 'react',\n 'X-SDK-Version': storefrontApiVersion,\n 'Shopify-Storefront-Private-Token':\n overrideProps?.privateStorefrontToken ?? privateStorefrontToken ?? '',\n ...(overrideProps?.buyerIp\n ? {'Shopify-Storefront-Buyer-IP': overrideProps.buyerIp}\n : {}),\n };\n },\n getPublicTokenHeaders(overrideProps): Record {\n if (\n !publicStorefrontToken &&\n !overrideProps?.publicStorefrontToken &&\n !isMockShop(storeDomain)\n ) {\n throw new Error(\n `StorefrontClient: You did not pass in a 'publicStorefrontToken' while using 'getPublicTokenHeaders()'`,\n );\n }\n\n const finalContentType =\n overrideProps?.contentType ?? contentType ?? 'json';\n\n return getPublicTokenHeadersRaw(\n finalContentType,\n storefrontApiVersion,\n overrideProps?.publicStorefrontToken ?? publicStorefrontToken ?? '',\n );\n },\n };\n}" + "value": "export function createStorefrontClient(\n props: StorefrontClientProps,\n): StorefrontClientReturn {\n const {\n storeDomain,\n privateStorefrontToken,\n publicStorefrontToken,\n storefrontApiVersion = SFAPI_VERSION,\n contentType,\n } = props;\n\n if (!storeDomain) {\n throw new Error(\n H2_PREFIX_ERROR +\n `\\`storeDomain\\` is required when creating a new Storefront client.\\nReceived \"${storeDomain}\".`,\n );\n }\n\n if (storefrontApiVersion !== SFAPI_VERSION) {\n warnOnce(\n `The Storefront API version that you're using is different than the version this build of Hydrogen React is targeting.` +\n `\\nYou may run into unexpected errors if these versions don't match. Received verion: \"${storefrontApiVersion}\"; expected version \"${SFAPI_VERSION}\"`,\n );\n }\n\n // only warn if not in a browser environment\n if (__HYDROGEN_DEV__ && !privateStorefrontToken && !globalThis.document) {\n warnOnce(\n `Using a private storefront token is recommended for server environments.` +\n `\\nRefer to the authentication https://shopify.dev/api/storefront#authentication documentation for more details.`,\n );\n }\n\n // only warn if in a browser environment and you're using the privateStorefrontToken\n if (__HYDROGEN_DEV__ && privateStorefrontToken && globalThis.document) {\n warnOnce(\n 'You are attempting to use a private token in an environment where it can be easily accessed by anyone.' +\n '\\nThis is a security risk; please use the public token and the `publicStorefrontToken` prop',\n );\n }\n\n const isMockShop = (domain: string): boolean => domain.includes('mock.shop');\n const getShopifyDomain: StorefrontClientReturn['getShopifyDomain'] = (\n overrideProps,\n ) => {\n const domain = overrideProps?.storeDomain ?? storeDomain;\n return domain.includes('://') ? domain : `https://${domain}`;\n };\n\n return {\n getShopifyDomain,\n getStorefrontApiUrl(overrideProps): string {\n const domain = getShopifyDomain(overrideProps);\n const apiUrl = domain + (domain.endsWith('/') ? 'api' : '/api');\n\n if (isMockShop(domain)) return apiUrl;\n\n return `${apiUrl}/${\n overrideProps?.storefrontApiVersion ?? storefrontApiVersion\n }/graphql.json`;\n },\n getPrivateTokenHeaders(overrideProps): Record {\n if (\n !privateStorefrontToken &&\n !overrideProps?.privateStorefrontToken &&\n !isMockShop(storeDomain)\n ) {\n throw new Error(\n H2_PREFIX_ERROR +\n 'You did not pass in a `privateStorefrontToken` while using `createStorefrontClient()` or `getPrivateTokenHeaders()`',\n );\n }\n\n if (__HYDROGEN_DEV__ && !overrideProps?.buyerIp) {\n warnOnce(\n 'It is recommended to pass in the `buyerIp` property which improves analytics and data in the admin.',\n );\n }\n\n const finalContentType = overrideProps?.contentType ?? contentType;\n\n return {\n // default to json\n 'content-type':\n finalContentType === 'graphql'\n ? 'application/graphql'\n : 'application/json',\n 'X-SDK-Variant': 'hydrogen-react',\n 'X-SDK-Variant-Source': 'react',\n 'X-SDK-Version': storefrontApiVersion,\n 'Shopify-Storefront-Private-Token':\n overrideProps?.privateStorefrontToken ?? privateStorefrontToken ?? '',\n ...(overrideProps?.buyerIp\n ? {'Shopify-Storefront-Buyer-IP': overrideProps.buyerIp}\n : {}),\n };\n },\n getPublicTokenHeaders(overrideProps): Record {\n if (\n !publicStorefrontToken &&\n !overrideProps?.publicStorefrontToken &&\n !isMockShop(storeDomain)\n ) {\n throw new Error(\n H2_PREFIX_ERROR +\n 'You did not pass in a `publicStorefrontToken` while using `createStorefrontClient()` or `getPublicTokenHeaders()`',\n );\n }\n\n const finalContentType =\n overrideProps?.contentType ?? contentType ?? 'json';\n\n return getPublicTokenHeadersRaw(\n finalContentType,\n storefrontApiVersion,\n overrideProps?.publicStorefrontToken ?? publicStorefrontToken ?? '',\n );\n },\n };\n}" }, "StorefrontClientProps": { "filePath": "/storefront-client.ts", @@ -7162,7 +7162,7 @@ "name": "UseMoneyValue", "value": "UseMoneyValue" }, - "value": "export function useMoney(money: MoneyV2): UseMoneyValue {\n const {countryIsoCode, languageIsoCode} = useShop();\n const locale = `${languageIsoCode}-${countryIsoCode}`;\n\n if (!locale) {\n throw new Error(\n `useMoney(): Unable to get 'locale' from 'useShop()', which means that 'locale' was not passed to ''. 'locale' is required for 'useMoney()' to work`,\n );\n }\n\n const amount = parseFloat(money.amount);\n\n const options = useMemo(\n () => ({\n style: 'currency',\n currency: money.currencyCode,\n }),\n [money.currencyCode],\n );\n\n const defaultFormatter = useLazyFormatter(locale, options);\n\n const nameFormatter = useLazyFormatter(locale, {\n ...options,\n currencyDisplay: 'name',\n });\n\n const narrowSymbolFormatter = useLazyFormatter(locale, {\n ...options,\n currencyDisplay: 'narrowSymbol',\n });\n\n const withoutTrailingZerosFormatter = useLazyFormatter(locale, {\n ...options,\n minimumFractionDigits: 0,\n maximumFractionDigits: 0,\n });\n\n const withoutCurrencyFormatter = useLazyFormatter(locale);\n\n const withoutTrailingZerosOrCurrencyFormatter = useLazyFormatter(locale, {\n minimumFractionDigits: 0,\n maximumFractionDigits: 0,\n });\n\n const isPartCurrency = (part: Intl.NumberFormatPart): boolean =>\n part.type === 'currency';\n\n // By wrapping these properties in functions, we only\n // create formatters if they are going to be used.\n const lazyFormatters = useMemo(\n () => ({\n original: () => money,\n currencyCode: () => money.currencyCode,\n\n localizedString: () => defaultFormatter().format(amount),\n\n parts: () => defaultFormatter().formatToParts(amount),\n\n withoutTrailingZeros: () =>\n amount % 1 === 0\n ? withoutTrailingZerosFormatter().format(amount)\n : defaultFormatter().format(amount),\n\n withoutTrailingZerosAndCurrency: () =>\n amount % 1 === 0\n ? withoutTrailingZerosOrCurrencyFormatter().format(amount)\n : withoutCurrencyFormatter().format(amount),\n\n currencyName: () =>\n nameFormatter().formatToParts(amount).find(isPartCurrency)?.value ??\n money.currencyCode, // e.g. \"US dollars\"\n\n currencySymbol: () =>\n defaultFormatter().formatToParts(amount).find(isPartCurrency)?.value ??\n money.currencyCode, // e.g. \"USD\"\n\n currencyNarrowSymbol: () =>\n narrowSymbolFormatter().formatToParts(amount).find(isPartCurrency)\n ?.value ?? '', // e.g. \"$\"\n\n amount: () =>\n defaultFormatter()\n .formatToParts(amount)\n .filter((part) =>\n ['decimal', 'fraction', 'group', 'integer', 'literal'].includes(\n part.type,\n ),\n )\n .map((part) => part.value)\n .join(''),\n }),\n [\n money,\n amount,\n nameFormatter,\n defaultFormatter,\n narrowSymbolFormatter,\n withoutCurrencyFormatter,\n withoutTrailingZerosFormatter,\n withoutTrailingZerosOrCurrencyFormatter,\n ],\n );\n\n // Call functions automatically when the properties are accessed\n // to keep these functions as an implementation detail.\n return useMemo(\n () =>\n new Proxy(lazyFormatters as unknown as UseMoneyValue, {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n get: (target, key) => Reflect.get(target, key)?.call(null),\n }),\n [lazyFormatters],\n );\n}" + "value": "export function useMoney(money: MoneyV2): UseMoneyValue {\n const {countryIsoCode, languageIsoCode} = useShop();\n const locale = languageIsoCode.includes('_')\n ? languageIsoCode.replace('_', '-')\n : `${languageIsoCode}-${countryIsoCode}`;\n\n if (!locale) {\n throw new Error(\n `useMoney(): Unable to get 'locale' from 'useShop()', which means that 'locale' was not passed to ''. 'locale' is required for 'useMoney()' to work`,\n );\n }\n\n const amount = parseFloat(money.amount);\n\n const options = useMemo(\n () => ({\n style: 'currency',\n currency: money.currencyCode,\n }),\n [money.currencyCode],\n );\n\n const defaultFormatter = useLazyFormatter(locale, options);\n\n const nameFormatter = useLazyFormatter(locale, {\n ...options,\n currencyDisplay: 'name',\n });\n\n const narrowSymbolFormatter = useLazyFormatter(locale, {\n ...options,\n currencyDisplay: 'narrowSymbol',\n });\n\n const withoutTrailingZerosFormatter = useLazyFormatter(locale, {\n ...options,\n minimumFractionDigits: 0,\n maximumFractionDigits: 0,\n });\n\n const withoutCurrencyFormatter = useLazyFormatter(locale);\n\n const withoutTrailingZerosOrCurrencyFormatter = useLazyFormatter(locale, {\n minimumFractionDigits: 0,\n maximumFractionDigits: 0,\n });\n\n const isPartCurrency = (part: Intl.NumberFormatPart): boolean =>\n part.type === 'currency';\n\n // By wrapping these properties in functions, we only\n // create formatters if they are going to be used.\n const lazyFormatters = useMemo(\n () => ({\n original: () => money,\n currencyCode: () => money.currencyCode,\n\n localizedString: () => defaultFormatter().format(amount),\n\n parts: () => defaultFormatter().formatToParts(amount),\n\n withoutTrailingZeros: () =>\n amount % 1 === 0\n ? withoutTrailingZerosFormatter().format(amount)\n : defaultFormatter().format(amount),\n\n withoutTrailingZerosAndCurrency: () =>\n amount % 1 === 0\n ? withoutTrailingZerosOrCurrencyFormatter().format(amount)\n : withoutCurrencyFormatter().format(amount),\n\n currencyName: () =>\n nameFormatter().formatToParts(amount).find(isPartCurrency)?.value ??\n money.currencyCode, // e.g. \"US dollars\"\n\n currencySymbol: () =>\n defaultFormatter().formatToParts(amount).find(isPartCurrency)?.value ??\n money.currencyCode, // e.g. \"USD\"\n\n currencyNarrowSymbol: () =>\n narrowSymbolFormatter().formatToParts(amount).find(isPartCurrency)\n ?.value ?? '', // e.g. \"$\"\n\n amount: () =>\n defaultFormatter()\n .formatToParts(amount)\n .filter((part) =>\n ['decimal', 'fraction', 'group', 'integer', 'literal'].includes(\n part.type,\n ),\n )\n .map((part) => part.value)\n .join(''),\n }),\n [\n money,\n amount,\n nameFormatter,\n defaultFormatter,\n narrowSymbolFormatter,\n withoutCurrencyFormatter,\n withoutTrailingZerosFormatter,\n withoutTrailingZerosOrCurrencyFormatter,\n ],\n );\n\n // Call functions automatically when the properties are accessed\n // to keep these functions as an implementation detail.\n return useMemo(\n () =>\n new Proxy(lazyFormatters as unknown as UseMoneyValue, {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call\n get: (target, key) => Reflect.get(target, key)?.call(null),\n }),\n [lazyFormatters],\n );\n}" }, "UseMoneyValue": { "filePath": "/useMoney.tsx", diff --git a/packages/hydrogen/docs/generated/generated_docs_data.json b/packages/hydrogen/docs/generated/generated_docs_data.json index 50b560dcb1..0e84103dd2 100644 --- a/packages/hydrogen/docs/generated/generated_docs_data.json +++ b/packages/hydrogen/docs/generated/generated_docs_data.json @@ -7883,7 +7883,7 @@ "name": "StorefrontClient", "value": "StorefrontClient" }, - "value": "export function createStorefrontClient(\n options: CreateStorefrontClientOptions,\n): StorefrontClient {\n const {\n storefrontHeaders,\n cache,\n waitUntil,\n buyerIp,\n i18n,\n requestGroupId,\n storefrontId,\n ...clientOptions\n } = options;\n const H2_PREFIX_WARN = '[h2:warn:createStorefrontClient] ';\n const H2_PREFIX_ERROR = '[h2:error:createStorefrontClient] ';\n\n if (process.env.NODE_ENV === 'development' && !cache) {\n warnOnce(\n H2_PREFIX_WARN +\n 'Storefront API client created without a cache instance. This may slow down your sub-requests.',\n );\n }\n\n const {\n getPublicTokenHeaders,\n getPrivateTokenHeaders,\n getStorefrontApiUrl,\n getShopifyDomain,\n } = createStorefrontUtilities(clientOptions);\n\n const getHeaders = clientOptions.privateStorefrontToken\n ? getPrivateTokenHeaders\n : getPublicTokenHeaders;\n\n const defaultHeaders = getHeaders({\n contentType: 'json',\n buyerIp: storefrontHeaders?.buyerIp || buyerIp,\n });\n\n defaultHeaders[STOREFRONT_REQUEST_GROUP_ID_HEADER] =\n storefrontHeaders?.requestGroupId || requestGroupId || generateUUID();\n\n if (storefrontId) defaultHeaders[SHOPIFY_STOREFRONT_ID_HEADER] = storefrontId;\n if (LIB_VERSION) defaultHeaders['user-agent'] = `Hydrogen ${LIB_VERSION}`;\n\n if (storefrontHeaders && storefrontHeaders.cookie) {\n const cookies = getShopifyCookies(storefrontHeaders.cookie ?? '');\n\n if (cookies[SHOPIFY_Y])\n defaultHeaders[SHOPIFY_STOREFRONT_Y_HEADER] = cookies[SHOPIFY_Y];\n if (cookies[SHOPIFY_S])\n defaultHeaders[SHOPIFY_STOREFRONT_S_HEADER] = cookies[SHOPIFY_S];\n }\n\n // Deprecation warning\n if (process.env.NODE_ENV === 'development' && !storefrontHeaders) {\n warnOnce(\n H2_PREFIX_WARN +\n '`requestGroupId` and `buyerIp` will be deprecated in the next calendar release. Please use `getStorefrontHeaders`',\n );\n }\n\n async function fetchStorefrontApi({\n query,\n mutation,\n variables,\n cache: cacheOptions,\n headers = [],\n storefrontApiVersion,\n }: StorefrontQueryOptions | StorefrontMutationOptions): Promise {\n const userHeaders =\n headers instanceof Headers\n ? Object.fromEntries(headers.entries())\n : Array.isArray(headers)\n ? Object.fromEntries(headers)\n : headers;\n\n query = query ?? mutation;\n\n const queryVariables = {...variables};\n\n if (i18n) {\n if (!variables?.country && /\\$country/.test(query)) {\n queryVariables.country = i18n.country;\n }\n\n if (!variables?.language && /\\$language/.test(query)) {\n queryVariables.language = i18n.language;\n }\n }\n\n const url = getStorefrontApiUrl({storefrontApiVersion});\n const requestInit: RequestInit = {\n method: 'POST',\n headers: {...defaultHeaders, ...userHeaders},\n body: JSON.stringify({\n query,\n variables: queryVariables,\n }),\n };\n\n const [body, response] = await fetchWithServerCache(url, requestInit, {\n cacheInstance: mutation ? undefined : cache,\n cache: cacheOptions || CacheShort(),\n shouldCacheResponse: checkGraphQLErrors,\n waitUntil,\n });\n\n const errorOptions: StorefrontErrorOptions = {\n response,\n type: mutation ? 'mutation' : 'query',\n query,\n queryVariables,\n errors: undefined,\n };\n\n if (!response.ok) {\n /**\n * The Storefront API might return a string error, or a JSON-formatted {error: string}.\n * We try both and conform them to a single {errors} format.\n */\n let errors;\n try {\n errors = parseJSON(body);\n } catch (_e) {\n errors = [{message: body}];\n }\n\n throwError({...errorOptions, errors});\n }\n\n const {data, errors} = body as StorefrontApiResponse;\n\n if (errors?.length) {\n throwError({\n ...errorOptions,\n errors,\n ErrorConstructor: StorefrontApiError,\n });\n }\n\n return data as T;\n }\n\n return {\n storefront: {\n /**\n * Sends a GraphQL query to the Storefront API.\n *\n * Example:\n *\n * ```js\n * async function loader ({context: {storefront}}) {\n * const data = await storefront.query('query { ... }', {\n * variables: {},\n * cache: storefront.CacheLong()\n * });\n * }\n * ```\n */\n query: ((query: string, payload) => {\n query = minifyQuery(query);\n if (isMutationRE.test(query)) {\n throw new Error(\n H2_PREFIX_ERROR + '`storefront.query` cannot execute mutations',\n );\n }\n\n return fetchStorefrontApi({...payload, query});\n }),\n /**\n * Sends a GraphQL mutation to the Storefront API.\n *\n * Example:\n *\n * ```js\n * async function loader ({context: {storefront}}) {\n * await storefront.mutate('mutation { ... }', {\n * variables: {},\n * });\n * }\n * ```\n */\n mutate: ((mutation: string, payload) => {\n mutation = minifyQuery(mutation);\n if (isQueryRE.test(mutation)) {\n throw new Error(\n H2_PREFIX_ERROR + '`storefront.mutate` cannot execute queries',\n );\n }\n\n return fetchStorefrontApi({...payload, mutation});\n }),\n cache,\n CacheNone,\n CacheLong,\n CacheShort,\n CacheCustom,\n generateCacheControlHeader,\n getPublicTokenHeaders,\n getPrivateTokenHeaders,\n getShopifyDomain,\n getApiUrl: getStorefrontApiUrl,\n /**\n * Wether it's a GraphQL error returned in the Storefront API response.\n *\n * Example:\n *\n * ```js\n * async function loader ({context: {storefront}}) {\n * try {\n * await storefront.query(...);\n * } catch(error) {\n * if (storefront.isApiError(error)) {\n * // ...\n * }\n *\n * throw error;\n * }\n * }\n * ```\n */\n isApiError: isStorefrontApiError,\n i18n: (i18n ?? defaultI18n) as TI18n,\n },\n };\n}" + "value": "export function createStorefrontClient(\n options: CreateStorefrontClientOptions,\n): StorefrontClient {\n const {\n storefrontHeaders,\n cache,\n waitUntil,\n buyerIp,\n i18n,\n requestGroupId,\n storefrontId,\n ...clientOptions\n } = options;\n const H2_PREFIX_WARN = '[h2:warn:createStorefrontClient] ';\n\n if (process.env.NODE_ENV === 'development' && !cache) {\n warnOnce(\n H2_PREFIX_WARN +\n 'Storefront API client created without a cache instance. This may slow down your sub-requests.',\n );\n }\n\n const {\n getPublicTokenHeaders,\n getPrivateTokenHeaders,\n getStorefrontApiUrl,\n getShopifyDomain,\n } = createStorefrontUtilities(clientOptions);\n\n const getHeaders = clientOptions.privateStorefrontToken\n ? getPrivateTokenHeaders\n : getPublicTokenHeaders;\n\n const defaultHeaders = getHeaders({\n contentType: 'json',\n buyerIp: storefrontHeaders?.buyerIp || buyerIp,\n });\n\n defaultHeaders[STOREFRONT_REQUEST_GROUP_ID_HEADER] =\n storefrontHeaders?.requestGroupId || requestGroupId || generateUUID();\n\n if (storefrontId) defaultHeaders[SHOPIFY_STOREFRONT_ID_HEADER] = storefrontId;\n if (LIB_VERSION) defaultHeaders['user-agent'] = `Hydrogen ${LIB_VERSION}`;\n\n if (storefrontHeaders && storefrontHeaders.cookie) {\n const cookies = getShopifyCookies(storefrontHeaders.cookie ?? '');\n\n if (cookies[SHOPIFY_Y])\n defaultHeaders[SHOPIFY_STOREFRONT_Y_HEADER] = cookies[SHOPIFY_Y];\n if (cookies[SHOPIFY_S])\n defaultHeaders[SHOPIFY_STOREFRONT_S_HEADER] = cookies[SHOPIFY_S];\n }\n\n // Deprecation warning\n if (process.env.NODE_ENV === 'development' && !storefrontHeaders) {\n warnOnce(\n H2_PREFIX_WARN +\n '`requestGroupId` and `buyerIp` will be deprecated in the next calendar release. Please use `getStorefrontHeaders`',\n );\n }\n\n async function fetchStorefrontApi({\n query,\n mutation,\n variables,\n cache: cacheOptions,\n headers = [],\n storefrontApiVersion,\n }: StorefrontQueryOptions | StorefrontMutationOptions): Promise {\n const userHeaders =\n headers instanceof Headers\n ? Object.fromEntries(headers.entries())\n : Array.isArray(headers)\n ? Object.fromEntries(headers)\n : headers;\n\n query = query ?? mutation;\n\n const queryVariables = {...variables};\n\n if (i18n) {\n if (!variables?.country && /\\$country/.test(query)) {\n queryVariables.country = i18n.country;\n }\n\n if (!variables?.language && /\\$language/.test(query)) {\n queryVariables.language = i18n.language;\n }\n }\n\n const url = getStorefrontApiUrl({storefrontApiVersion});\n const requestInit: RequestInit = {\n method: 'POST',\n headers: {...defaultHeaders, ...userHeaders},\n body: JSON.stringify({\n query,\n variables: queryVariables,\n }),\n };\n\n const [body, response] = await fetchWithServerCache(url, requestInit, {\n cacheInstance: mutation ? undefined : cache,\n cache: cacheOptions || CacheShort(),\n shouldCacheResponse: checkGraphQLErrors,\n waitUntil,\n });\n\n const errorOptions: StorefrontErrorOptions = {\n response,\n type: mutation ? 'mutation' : 'query',\n query,\n queryVariables,\n errors: undefined,\n };\n\n if (!response.ok) {\n /**\n * The Storefront API might return a string error, or a JSON-formatted {error: string}.\n * We try both and conform them to a single {errors} format.\n */\n let errors;\n try {\n errors = parseJSON(body);\n } catch (_e) {\n errors = [{message: body}];\n }\n\n throwError({...errorOptions, errors});\n }\n\n const {data, errors} = body as StorefrontApiResponse;\n\n if (errors?.length) {\n throwError({\n ...errorOptions,\n errors,\n ErrorConstructor: StorefrontApiError,\n });\n }\n\n return data as T;\n }\n\n return {\n storefront: {\n /**\n * Sends a GraphQL query to the Storefront API.\n *\n * Example:\n *\n * ```js\n * async function loader ({context: {storefront}}) {\n * const data = await storefront.query('query { ... }', {\n * variables: {},\n * cache: storefront.CacheLong()\n * });\n * }\n * ```\n */\n query: ((query: string, payload) => {\n query = minifyQuery(query);\n if (isMutationRE.test(query)) {\n throw new Error(\n '[h2:error:storefront.query] Cannot execute mutations',\n );\n }\n\n return fetchStorefrontApi({...payload, query});\n }),\n /**\n * Sends a GraphQL mutation to the Storefront API.\n *\n * Example:\n *\n * ```js\n * async function loader ({context: {storefront}}) {\n * await storefront.mutate('mutation { ... }', {\n * variables: {},\n * });\n * }\n * ```\n */\n mutate: ((mutation: string, payload) => {\n mutation = minifyQuery(mutation);\n if (isQueryRE.test(mutation)) {\n throw new Error(\n '[h2:error:storefront.mutate] Cannot execute queries',\n );\n }\n\n return fetchStorefrontApi({...payload, mutation});\n }),\n cache,\n CacheNone,\n CacheLong,\n CacheShort,\n CacheCustom,\n generateCacheControlHeader,\n getPublicTokenHeaders,\n getPrivateTokenHeaders,\n getShopifyDomain,\n getApiUrl: getStorefrontApiUrl,\n /**\n * Wether it's a GraphQL error returned in the Storefront API response.\n *\n * Example:\n *\n * ```js\n * async function loader ({context: {storefront}}) {\n * try {\n * await storefront.query(...);\n * } catch(error) {\n * if (storefront.isApiError(error)) {\n * // ...\n * }\n *\n * throw error;\n * }\n * }\n * ```\n */\n isApiError: isStorefrontApiError,\n i18n: (i18n ?? defaultI18n) as TI18n,\n },\n };\n}" }, "CreateStorefrontClientOptions": { "filePath": "/storefront.ts", @@ -9544,7 +9544,7 @@ "filePath": "/Image.tsx", "syntaxKind": "TypeAliasDeclaration", "name": "SrcSetOptions", - "value": "{\n intervals: number;\n startingWidth: number;\n incrementSize: number;\n placeholderWidth: number;\n}", + "value": "{\n /** The number of sizes to generate */\n intervals: number;\n /** The smallest image size */\n startingWidth: number;\n /** The increment by which to increase for each size, in pixels */\n incrementSize: number;\n /** The size used for placeholder fallback images */\n placeholderWidth: number;\n}", "description": "", "members": [ { @@ -9552,28 +9552,28 @@ "syntaxKind": "PropertySignature", "name": "intervals", "value": "number", - "description": "" + "description": "The number of sizes to generate" }, { "filePath": "/Image.tsx", "syntaxKind": "PropertySignature", "name": "startingWidth", "value": "number", - "description": "" + "description": "The smallest image size" }, { "filePath": "/Image.tsx", "syntaxKind": "PropertySignature", "name": "incrementSize", "value": "number", - "description": "" + "description": "The increment by which to increase for each size, in pixels" }, { "filePath": "/Image.tsx", "syntaxKind": "PropertySignature", "name": "placeholderWidth", "value": "number", - "description": "" + "description": "The size used for placeholder fallback images" } ] }, @@ -12363,7 +12363,7 @@ "filePath": "/Image.tsx", "syntaxKind": "TypeAliasDeclaration", "name": "SrcSetOptions", - "value": "{\n intervals: number;\n startingWidth: number;\n incrementSize: number;\n placeholderWidth: number;\n}", + "value": "{\n /** The number of sizes to generate */\n intervals: number;\n /** The smallest image size */\n startingWidth: number;\n /** The increment by which to increase for each size, in pixels */\n incrementSize: number;\n /** The size used for placeholder fallback images */\n placeholderWidth: number;\n}", "description": "", "members": [ { @@ -12371,28 +12371,28 @@ "syntaxKind": "PropertySignature", "name": "intervals", "value": "number", - "description": "" + "description": "The number of sizes to generate" }, { "filePath": "/Image.tsx", "syntaxKind": "PropertySignature", "name": "startingWidth", "value": "number", - "description": "" + "description": "The smallest image size" }, { "filePath": "/Image.tsx", "syntaxKind": "PropertySignature", "name": "incrementSize", "value": "number", - "description": "" + "description": "The increment by which to increase for each size, in pixels" }, { "filePath": "/Image.tsx", "syntaxKind": "PropertySignature", "name": "placeholderWidth", "value": "number", - "description": "" + "description": "The size used for placeholder fallback images" } ] },