UNPKG

ebay-api

Version:

eBay API for Node and Browser

178 lines (177 loc) 6.01 kB
import { EBayInvalidAccessToken, handleEBayError } from '../../errors/index.js'; import Api from '../index.js'; export const defaultApiHeaders = { 'Content-Type': 'application/json', 'Cache-Control': 'no-cache', // @ts-ignore ...(typeof window === 'undefined' ? { 'Accept-Encoding': 'application/gzip' } : {}) }; const additionalHeaders = { marketplaceId: 'X-EBAY-C-MARKETPLACE-ID', endUserCtx: 'X-EBAY-C-ENDUSERCTX', acceptLanguage: 'Accept-Language', contentLanguage: 'Content-Language', }; export default class Restful extends Api { constructor(config, req, auth, apiConfig = {}) { super(config, req, auth); this.apiConfig = { ...this.getApiConfig(), ...apiConfig }; } static buildServerUrl(schema, subdomain, sandbox, tld) { return `${schema}${subdomain}.${sandbox ? 'sandbox.' : ''}${tld}`; } /** * Enable to supports the use of OAuth tokens for user authorization. */ get useIaf() { return false; } get schema() { return 'https://'; } get subdomain() { return 'api'; } get apiVersionPath() { return ''; } getServerUrl({ schema, subdomain, apiVersion, basePath, sandbox, tld }) { return Restful.buildServerUrl(schema, subdomain, sandbox, tld) + apiVersion + basePath; } getApiConfig() { return { subdomain: this.subdomain, useIaf: this.useIaf, apiVersion: this.apiVersionPath, basePath: this.basePath, schema: this.schema, sandbox: this.config.sandbox, tld: 'ebay.com', headers: {}, returnResponse: false, sign: false }; } get baseUrl() { return this.getServerUrl(this.apiConfig); } /** * Create a new instances of it self with specified api config. * @param apiConfig */ api(apiConfig) { // @ts-ignore return new this.constructor(this.config, this.req, this.auth, apiConfig); } /** * Use "apix" subdomain */ get apix() { return this.api({ subdomain: 'apix' }); } /** * Use "apiz" subdomain */ get apiz() { return this.api({ subdomain: 'apiz' }); } /** * Sign request */ get sign() { return this.api({ sign: true }); } async get(path, config = {}, apiConfig) { return this.doRequest({ method: 'get', path, config }, apiConfig); } async delete(path, config = {}, apiConfig) { return this.doRequest({ method: 'delete', path, config }, apiConfig); } async post(path, data, config = {}, apiConfig) { return this.doRequest({ method: 'post', path, data, config }, apiConfig); } async put(path, data, config = {}, apiConfig) { return this.doRequest({ method: 'put', path, data, config }, apiConfig); } get additionalHeaders() { return Object.keys(additionalHeaders) // @ts-ignore .filter(key => typeof this.config[key] !== 'undefined') .reduce((headers, key) => { // @ts-ignore headers[additionalHeaders[key]] = this.config[key]; return headers; }, {}); } async enrichRequestConfig(apiRequest, payload = null, apiConfig = this.apiConfig) { const authHeader = await this.auth.getHeaderAuthorization(apiConfig.useIaf); const signatureHeaders = apiConfig.sign ? this.getDigitalSignatureHeaders({ method: apiRequest.method.toUpperCase(), authority: Restful.buildServerUrl('', apiConfig.subdomain, apiConfig.sandbox, apiConfig.tld), path: apiConfig.apiVersion + apiConfig.basePath + apiRequest.path }, payload) : {}; const headers = { ...defaultApiHeaders, ...this.additionalHeaders, ...authHeader, ...apiConfig.headers, ...signatureHeaders }; return { ...apiRequest.config, headers: { ...(apiRequest.config.headers || {}), ...headers } }; } async doRequest(payload, apiConfig) { try { return await this.request(payload, apiConfig); } catch (error) { if (this.shouldRefreshToken(error)) { // Try again and refresh token return await this.request(payload, apiConfig, true /* refresh token */); } throw error; } } shouldRefreshToken(error) { if (!this.config.autoRefreshToken) { return false; } if (error.name === EBayInvalidAccessToken.name) { return true; } return error?.meta?.res?.status === 401 && this.apiConfig.basePath === '/post-order/v2'; } async request(apiRequest, apiConfig = this.apiConfig, refreshToken = false) { const { path, method, data } = apiRequest; const apiCfg = { ...this.apiConfig, ...apiConfig }; const endpoint = this.getServerUrl(apiCfg) + path; try { if (refreshToken) { await this.auth.OAuth2.refreshToken(); } const enrichedConfig = await this.enrichRequestConfig(apiRequest, data, apiCfg); const args = ['get', 'delete'].includes(method) ? [enrichedConfig] : [data, enrichedConfig]; // @ts-ignore const response = await this.req[method](endpoint, ...args); if (this.apiConfig.returnResponse) { return response; } else { return response.data; } } catch (ex) { handleEBayError(ex); } } }