trainingpeaks-sdk
Version:
TypeScript SDK for TrainingPeaks API integration
83 lines (82 loc) • 3.19 kB
JavaScript
import { createTokenRefreshHandler } from './token-refresh-handler.js';
const extractSetCookieHeaders = (response) => {
const setCookieHeader = response.headers['set-cookie'] ||
response.headers['Set-Cookie'];
if (Array.isArray(setCookieHeader)) {
return setCookieHeader;
}
else if (typeof setCookieHeader === 'string') {
return [setCookieHeader];
}
return [];
};
const requestAndWrap = async (client, method, url, data, options) => {
const response = await client.request({
method,
url,
data,
...options,
});
return {
data: response.data,
success: true,
cookies: extractSetCookieHeaders(response),
};
};
export const executeRequestWithRefresh = async (axiosConfig, requestConfig, config) => {
const { client, sessionStorage, logger, maxRefreshRetries = 1 } = config;
let retries = 0;
while (retries <= maxRefreshRetries) {
try {
const response = await client.request(axiosConfig);
return response;
}
catch (error) {
const is401Error = error?.response?.status === 401;
const isLastRetry = retries >= maxRefreshRetries;
if (!is401Error || isLastRetry) {
throw error;
}
logger.warn('Received 401 error, attempting token refresh', {
url: requestConfig.url,
method: requestConfig.method,
retry: retries + 1,
maxRetries: maxRefreshRetries,
});
const refreshHttpClient = {
get: async (url, options) => {
return requestAndWrap(client, 'GET', url, undefined, options);
},
post: async (url, data, options) => {
return requestAndWrap(client, 'POST', url, data, options);
},
put: async (url, data, options) => {
return requestAndWrap(client, 'PUT', url, data, options);
},
patch: async (url, data, options) => {
return requestAndWrap(client, 'PATCH', url, data, options);
},
delete: async (url, options) => {
return requestAndWrap(client, 'DELETE', url, undefined, options);
},
};
const tokenHandler = createTokenRefreshHandler(refreshHttpClient, sessionStorage, logger);
const refreshedToken = await tokenHandler.ensureValidToken();
if (!refreshedToken) {
logger.error('Token refresh failed, cannot retry request');
throw error;
}
axiosConfig.headers = {
...axiosConfig.headers,
Authorization: `Bearer ${refreshedToken.accessToken}`,
};
logger.info('Token refreshed successfully, retrying request', {
url: requestConfig.url,
method: requestConfig.method,
retry: retries + 1,
});
retries++;
}
}
throw new Error('Unexpected end of retry loop');
};