UNPKG

@shopify/storefront-api-client

Version:

Shopify Storefront API Client - A lightweight JS client to interact with Shopify's Storefront API

151 lines (134 loc) 3.82 kB
import { createGraphQLClient, getCurrentSupportedApiVersions, validateDomainAndGetStoreUrl, validateApiVersion, generateGetGQLClientParams, generateGetHeaders, } from '@shopify/graphql-client'; import { StorefrontApiClientOptions, StorefrontApiClient, StorefrontApiClientConfig, StorefrontOperations, } from './types'; import { DEFAULT_SDK_VARIANT, DEFAULT_CLIENT_VERSION, SDK_VARIANT_HEADER, SDK_VARIANT_SOURCE_HEADER, SDK_VERSION_HEADER, DEFAULT_CONTENT_TYPE, PUBLIC_ACCESS_TOKEN_HEADER, PRIVATE_ACCESS_TOKEN_HEADER, CLIENT, } from './constants'; import { validateRequiredAccessTokens, validatePrivateAccessTokenUsage, } from './validations'; export function createStorefrontApiClient({ storeDomain, apiVersion, publicAccessToken, privateAccessToken, clientName, retries = 0, customFetchApi, logger, }: StorefrontApiClientOptions): StorefrontApiClient { const currentSupportedApiVersions = getCurrentSupportedApiVersions(); const storeUrl = validateDomainAndGetStoreUrl({ client: CLIENT, storeDomain, }); const baseApiVersionValidationParams = { client: CLIENT, currentSupportedApiVersions, logger, }; validateApiVersion({...baseApiVersionValidationParams, apiVersion}); validateRequiredAccessTokens(publicAccessToken, privateAccessToken); validatePrivateAccessTokenUsage(privateAccessToken); const apiUrlFormatter = generateApiUrlFormatter( storeUrl, apiVersion, baseApiVersionValidationParams, ); const config: StorefrontApiClientConfig = { storeDomain: storeUrl, apiVersion, ...(publicAccessToken ? {publicAccessToken} : { privateAccessToken: privateAccessToken!, }), headers: { 'Content-Type': DEFAULT_CONTENT_TYPE, Accept: DEFAULT_CONTENT_TYPE, [SDK_VARIANT_HEADER]: DEFAULT_SDK_VARIANT, [SDK_VERSION_HEADER]: DEFAULT_CLIENT_VERSION, ...(clientName ? {[SDK_VARIANT_SOURCE_HEADER]: clientName} : {}), ...(publicAccessToken ? {[PUBLIC_ACCESS_TOKEN_HEADER]: publicAccessToken} : {[PRIVATE_ACCESS_TOKEN_HEADER]: privateAccessToken!}), }, apiUrl: apiUrlFormatter(), clientName, }; const graphqlClient = createGraphQLClient({ headers: config.headers, url: config.apiUrl, retries, customFetchApi, logger, }); const getHeaders = generateGetHeaders(config); const getApiUrl = generateGetApiUrl(config, apiUrlFormatter); const getGQLClientParams = generateGetGQLClientParams<StorefrontOperations>({ getHeaders, getApiUrl, }); const client: StorefrontApiClient = { config, getHeaders, getApiUrl, fetch: (...props) => { return graphqlClient.fetch(...getGQLClientParams(...props)); }, request: (...props) => { return graphqlClient.request(...getGQLClientParams(...props)); }, requestStream: (...props) => { return graphqlClient.requestStream(...getGQLClientParams(...props)); }, }; return Object.freeze(client); } function generateApiUrlFormatter( storeUrl: string, defaultApiVersion: string, baseApiVersionValidationParams: Omit< Parameters<typeof validateApiVersion>[0], 'apiVersion' >, ) { return (apiVersion?: string) => { if (apiVersion) { validateApiVersion({ ...baseApiVersionValidationParams, apiVersion, }); } const urlApiVersion = (apiVersion ?? defaultApiVersion).trim(); return `${storeUrl}/api/${urlApiVersion}/graphql.json`; }; } function generateGetApiUrl( config: StorefrontApiClientConfig, apiUrlFormatter: (version?: string) => string, ): StorefrontApiClient['getApiUrl'] { return (propApiVersion?: string) => { return propApiVersion ? apiUrlFormatter(propApiVersion) : config.apiUrl; }; }