UNPKG

@commercelayer/sdk

Version:
151 lines (149 loc) 6.48 kB
import { extractTokenData, isTokenExpired } from './chunk-R2LRLUUY.js'; import { config_default } from './chunk-Z4LKTHPE.js'; import { SdkError, fetchURL, handleError, isExpiredTokenError } from './chunk-ZU7GFVQ6.js'; import { debug_default } from './chunk-XD7GS4QW.js'; // src/client.ts var debug = debug_default("client"); var baseURL = (organization, domain) => { return `https://${organization.toLowerCase()}.${domain || config_default.default.domain}/api`; }; var ApiClient = class _ApiClient { static create(options) { if ((!options.organization || !options.domain) && options.accessToken) { const tokenData = extractTokenData(options.accessToken); if (!options.organization && tokenData?.organization) options.organization = tokenData.organization; if (!options.domain && tokenData?.domain) options.domain = tokenData.domain; } for (const attr of config_default.client.requiredAttributes) if (!options[attr]) throw new SdkError({ message: `Undefined '${attr}' parameter` }); return new _ApiClient(options); } #baseUrl; #accessToken; #organization; #domain; #clientConfig; #interceptors; constructor(options) { debug("new client instance %O", options); this.#baseUrl = baseURL(options.organization ?? "", options.domain); this.#accessToken = options.accessToken; this.#organization = options.organization ?? ""; this.#domain = options.domain; const fetchConfig = { timeout: options.timeout || config_default.client.timeout, fetch: options.fetch, refreshToken: options.refreshToken }; const customHeaders = this.customHeaders(options.headers); const headers = { ...customHeaders, "Accept": "application/vnd.api+json", "Content-Type": "application/vnd.api+json", "Authorization": "Bearer " + this.#accessToken }; if (options.userAgent) headers["User-Agent"] = options.userAgent; fetchConfig.headers = headers; this.#clientConfig = fetchConfig; debug("fetch config: %O", fetchConfig); this.#interceptors = {}; } get interceptors() { return this.#interceptors; } get requestHeaders() { if (!this.#clientConfig.headers) this.#clientConfig.headers = {}; return this.#clientConfig.headers; } /* set requestHeaders(headers: RequestHeaders) { this.#clientConfig.headers = { ...this.#clientConfig.headers, ...headers } } */ config(config) { debug("config %o", config); const def = this.#clientConfig; if (!def.headers) def.headers = {}; if (config.timeout) def.timeout = config.timeout; if (config.userAgent) this.userAgent(config.userAgent); if (config.fetch) this.#clientConfig.fetch = config.fetch; if (config.refreshToken) this.#clientConfig.refreshToken = config.refreshToken; if (config.organization || config.domain) this.#baseUrl = baseURL(config.organization || this.#organization, config.domain || this.#domain); if (config.organization) this.#organization = config.organization; if (config.domain) this.#domain = config.domain; if (config.accessToken) { this.#accessToken = config.accessToken; def.headers.Authorization = "Bearer " + this.#accessToken; } if (config.headers) def.headers = { ...def.headers, ...this.customHeaders(config.headers) }; return this; } userAgent(userAgent) { if (userAgent) this.requestHeaders["User-Agent"] = userAgent; return this; } async request(method, path, body, options) { debug("request %s %s, %O, %O", method, path, body || {}, options || {}); if (options?.userAgent) debug("User-Agent header ignored in request config"); const baseUrl = options?.organization ? baseURL(options.organization, options.domain) : this.#baseUrl; const url = new URL(`${baseUrl}/${path}`); const bodyData = body ? JSON.stringify({ data: body }) : void 0; const headers = { ...this.requestHeaders, ...this.customHeaders(options?.headers) }; const accessToken = options?.accessToken || this.#accessToken; if (accessToken) headers.Authorization = "Bearer " + accessToken; const refreshToken = options?.refreshToken || this.#clientConfig.refreshToken; const fetchFunction = options?.fetch || this.#clientConfig.fetch; const requestOptions = { method, body: bodyData, headers }; const timeout = options?.timeout || this.#clientConfig.timeout; if (timeout) { if (AbortSignal?.timeout) requestOptions.signal = AbortSignal.timeout(timeout); else debug("Timeout not set. Undefined function: %s", "AbortSignal.timeout"); } if (options?.params) Object.entries(options?.params).forEach(([name, value]) => { url.searchParams.append(name, String(value)); }); const clientOptions = { interceptors: this.interceptors, fetch: fetchFunction }; try { return await fetchURL(url, requestOptions, clientOptions).catch((error) => handleError(error)); } catch (err) { if (isExpiredTokenError(err) && refreshToken && isTokenExpired(accessToken)) { debug("Access token has expired"); const newAccessToken = await refreshToken(this.#accessToken).catch((e) => { debug("Refresh token error: %s", e.message); const tokenError = new SdkError({ message: "Error refreshing access token", type: "token-refresh" /* TOKEN_REFRESH */ }); tokenError.source = e; throw tokenError; }); if (newAccessToken) { debug("Access token refreshed"); this.config({ accessToken: newAccessToken }); this.#accessToken = newAccessToken; if (requestOptions.headers) requestOptions.headers.Authorization = `Bearer ${newAccessToken}`; const response = await fetchURL(url, requestOptions, clientOptions).catch((error) => handleError(error)); return response; } } else throw err; } } customHeaders(headers) { const customHeaders = {}; if (headers) { for (const [name, value] of Object.entries(headers)) if (!["accept", "content-type", "authorization", "user-agent"].includes(name.toLowerCase())) customHeaders[name] = value; } return customHeaders; } get currentAccessToken() { return this.#accessToken; } get currentOrganization() { return this.#organization; } }; var client_default = ApiClient; export { client_default }; //# sourceMappingURL=chunk-UUY77JM3.js.map //# sourceMappingURL=chunk-UUY77JM3.js.map