@commercelayer/sdk
Version:
Commerce Layer Javascript SDK
151 lines (149 loc) • 6.48 kB
JavaScript
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