UNPKG

@shopify/admin-api-client

Version:

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

119 lines (116 loc) 5.23 kB
import { getCurrentSupportedApiVersions, validateDomainAndGetStoreUrl, validateApiVersion, validateRetries, generateHttpFetch } from '@shopify/graphql-client'; import { validateServerSideUsage, validateRequiredAccessToken } from '../validations.mjs'; import { CLIENT, RETRIABLE_STATUS_CODES, DEFAULT_RETRY_WAIT_TIME, DEFAULT_CLIENT_VERSION, DEFAULT_CONTENT_TYPE, ACCESS_TOKEN_HEADER } from '../constants.mjs'; import { Method } from './types.mjs'; function createAdminRestApiClient({ storeDomain, apiVersion, accessToken, userAgentPrefix, logger, customFetchApi = fetch, retries: clientRetries = 0, scheme = 'https', defaultRetryTime = DEFAULT_RETRY_WAIT_TIME, formatPaths = true, isTesting, }) { const currentSupportedApiVersions = getCurrentSupportedApiVersions(); const storeUrl = validateDomainAndGetStoreUrl({ client: CLIENT, storeDomain, }).replace('https://', `${scheme}://`); const baseApiVersionValidationParams = { client: CLIENT, currentSupportedApiVersions, logger, }; validateServerSideUsage(isTesting); validateApiVersion({ client: CLIENT, currentSupportedApiVersions, apiVersion, logger, }); validateRequiredAccessToken(accessToken); validateRetries({ client: CLIENT, retries: clientRetries }); const apiUrlFormatter = generateApiUrlFormatter(storeUrl, apiVersion, baseApiVersionValidationParams, formatPaths); const clientLogger = generateClientLogger(logger); const httpFetch = generateHttpFetch({ customFetchApi, clientLogger, defaultRetryWaitTime: defaultRetryTime, client: CLIENT, retriableCodes: RETRIABLE_STATUS_CODES, }); const request = async (path, { method, data, headers: requestHeadersObj, searchParams, retries = 0, apiVersion, }) => { validateRetries({ client: CLIENT, retries }); const url = apiUrlFormatter(path, searchParams ?? {}, apiVersion); const requestHeaders = normalizedHeaders(requestHeadersObj ?? {}); const userAgent = [ ...(requestHeaders['user-agent'] ? [requestHeaders['user-agent']] : []), ...(userAgentPrefix ? [userAgentPrefix] : []), `${CLIENT} v${DEFAULT_CLIENT_VERSION}`, ].join(' | '); const headers = normalizedHeaders({ 'Content-Type': DEFAULT_CONTENT_TYPE, ...requestHeaders, Accept: DEFAULT_CONTENT_TYPE, [ACCESS_TOKEN_HEADER]: accessToken, 'User-Agent': userAgent, }); const body = data && typeof data !== 'string' ? JSON.stringify(data) : data; return httpFetch([url, { method, headers, ...(body ? { body } : undefined) }], 1, retries ?? clientRetries); }; return { get: (path, options) => request(path, { method: Method.Get, ...options }), put: (path, options) => request(path, { method: Method.Put, ...options }), post: (path, options) => request(path, { method: Method.Post, ...options }), delete: (path, options) => request(path, { method: Method.Delete, ...options }), }; } function generateApiUrlFormatter(storeUrl, defaultApiVersion, baseApiVersionValidationParams, formatPaths = true) { return (path, searchParams, apiVersion) => { if (apiVersion) { validateApiVersion({ ...baseApiVersionValidationParams, apiVersion, }); } function convertValue(params, key, value) { if (Array.isArray(value)) { value.forEach((arrayValue) => convertValue(params, `${key}[]`, arrayValue)); return; } else if (typeof value === 'object') { Object.entries(value).forEach(([objKey, objValue]) => convertValue(params, `${key}[${objKey}]`, objValue)); return; } params.append(key, String(value)); } const urlApiVersion = (apiVersion ?? defaultApiVersion).trim(); let cleanPath = path.replace(/^\//, ''); if (formatPaths) { if (!cleanPath.startsWith('admin')) { cleanPath = `admin/api/${urlApiVersion}/${cleanPath}`; } if (!cleanPath.endsWith('.json')) { cleanPath = `${cleanPath}.json`; } } const params = new URLSearchParams(); if (searchParams) { for (const [key, value] of Object.entries(searchParams)) { convertValue(params, key, value); } } const queryString = params.toString() ? `?${params.toString()}` : ''; return `${storeUrl}/${cleanPath}${queryString}`; }; } function generateClientLogger(logger) { return (logContent) => { if (logger) { logger(logContent); } }; } function normalizedHeaders(headersObj) { const normalizedHeaders = {}; for (const [key, value] of Object.entries(headersObj)) { normalizedHeaders[key.toLowerCase()] = Array.isArray(value) ? value.join(', ') : String(value); } return normalizedHeaders; } export { createAdminRestApiClient }; //# sourceMappingURL=client.mjs.map