@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
JavaScript
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