@crowdin/crowdin-api-client
Version:
JavaScript library for Crowdin API
319 lines (318 loc) • 12.7 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isOptionalNumber = exports.isOptionalString = exports.CrowdinApi = exports.handleHttpClientError = exports.CrowdinValidationError = exports.CrowdinError = exports.BooleanInt = void 0;
const axios_1 = require("axios");
const http_client_error_1 = require("./http-client-error");
const axiosProvider_1 = require("./internal/axios/axiosProvider");
const fetchClient_1 = require("./internal/fetch/fetchClient");
const fetchClientError_1 = require("./internal/fetch/fetchClientError");
const retry_1 = require("./internal/retry");
/**
* @internal
*/
var BooleanInt;
(function (BooleanInt) {
BooleanInt[BooleanInt["TRUE"] = 1] = "TRUE";
BooleanInt[BooleanInt["FALSE"] = 0] = "FALSE";
})(BooleanInt = exports.BooleanInt || (exports.BooleanInt = {}));
/**
* @internal
*/
class CrowdinError extends Error {
constructor(message, code, apiError) {
super(message);
this.code = code;
this.apiError = apiError;
}
}
exports.CrowdinError = CrowdinError;
/**
* @internal
*/
class CrowdinValidationError extends CrowdinError {
constructor(message, validationCodes, apiError) {
super(message, 400, apiError);
this.validationCodes = validationCodes;
}
}
exports.CrowdinValidationError = CrowdinValidationError;
function isAxiosError(error) {
var _a;
return error instanceof axios_1.AxiosError || !!((_a = error.response) === null || _a === void 0 ? void 0 : _a.data);
}
/**
* @internal
*/
function handleHttpClientError(error) {
var _a, _b, _c, _d, _e, _f;
let crowdinResponseErrors = null;
if (isAxiosError(error)) {
crowdinResponseErrors = ((_b = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.errors) || ((_d = (_c = error.response) === null || _c === void 0 ? void 0 : _c.data) === null || _d === void 0 ? void 0 : _d.error);
}
else if (error instanceof fetchClientError_1.FetchClientJsonPayloadError) {
crowdinResponseErrors =
error.jsonPayload &&
typeof error.jsonPayload === 'object' &&
('errors' in error.jsonPayload || 'error' in error.jsonPayload)
? error.jsonPayload.errors || error.jsonPayload.error
: null;
}
if (Array.isArray(crowdinResponseErrors)) {
const validationCodes = [];
const validationMessages = [];
crowdinResponseErrors.forEach((e) => {
var _a, _b, _c;
if (typeof e.index === 'number' || typeof ((_a = e.error) === null || _a === void 0 ? void 0 : _a.key) === 'number') {
throw new CrowdinValidationError(JSON.stringify(crowdinResponseErrors, null, 2), [], crowdinResponseErrors);
}
if (((_b = e.error) === null || _b === void 0 ? void 0 : _b.key) && Array.isArray((_c = e.error) === null || _c === void 0 ? void 0 : _c.errors)) {
const codes = [];
e.error.errors.forEach((er) => {
if (er.message && er.code) {
codes.push(er.code);
validationMessages.push(er.message);
}
});
validationCodes.push({ key: e.error.key, codes });
}
});
const message = validationMessages.length === 0 ? 'Validation error' : validationMessages.join(', ');
throw new CrowdinValidationError(message, validationCodes, crowdinResponseErrors);
}
else if ((crowdinResponseErrors === null || crowdinResponseErrors === void 0 ? void 0 : crowdinResponseErrors.message) && (crowdinResponseErrors === null || crowdinResponseErrors === void 0 ? void 0 : crowdinResponseErrors.code)) {
throw new CrowdinError(crowdinResponseErrors.message, crowdinResponseErrors.code, crowdinResponseErrors);
}
if (error instanceof Error) {
const code = error instanceof axios_1.AxiosError && ((_e = error.response) === null || _e === void 0 ? void 0 : _e.status)
? (_f = error.response) === null || _f === void 0 ? void 0 : _f.status
: error instanceof fetchClientError_1.FetchClientJsonPayloadError
? error.statusCode
: 500;
throw new CrowdinError(error.message, code, crowdinResponseErrors);
}
throw new CrowdinError(`unknown http error: ${String(error)}`, 500, crowdinResponseErrors);
}
exports.handleHttpClientError = handleHttpClientError;
class CrowdinApi {
/**
* @param credentials credentials
* @param config optional configuration of the client
*/
constructor(credentials, config) {
this.fetchAllFlag = false;
this.token = credentials.token;
this.organization = credentials.organization;
if (credentials.baseUrl) {
this.url = credentials.baseUrl;
}
else {
if (this.organization) {
this.url = `https://${this.organization}.${CrowdinApi.CROWDIN_URL_SUFFIX}`;
}
else {
this.url = `https://${CrowdinApi.CROWDIN_URL_SUFFIX}`;
}
}
let retryConfig;
if (config === null || config === void 0 ? void 0 : config.retryConfig) {
retryConfig = config.retryConfig;
}
else {
retryConfig = {
waitInterval: 0,
retries: 0,
conditions: [],
};
}
this.retryService = new retry_1.RetryService(retryConfig);
if (config === null || config === void 0 ? void 0 : config.httpRequestTimeout) {
CrowdinApi.FETCH_INSTANCE.withTimeout(config === null || config === void 0 ? void 0 : config.httpRequestTimeout);
CrowdinApi.AXIOS_INSTANCE.defaults.timeout = config === null || config === void 0 ? void 0 : config.httpRequestTimeout;
}
this.config = config;
}
graphql(req, config = {}) {
let url;
if (config === null || config === void 0 ? void 0 : config.url) {
url = config.url;
}
else {
if (this.organization) {
url = `https://${this.organization}.api.crowdin.com/api/graphql`;
}
else {
url = 'https://api.crowdin.com/api/graphql';
}
}
return this.post(url, req, this.defaultConfig());
}
addQueryParam(url, name, value) {
if (value) {
url += new RegExp(/\?.+=.*/g).test(url) ? '&' : '?';
url += `${name}=${this.encodeUrlParam(value)}`;
}
return url;
}
defaultConfig() {
var _a, _b;
const config = {
headers: {
Authorization: `Bearer ${this.token}`,
},
};
if ((_a = this.config) === null || _a === void 0 ? void 0 : _a.userAgent) {
config.headers['User-Agent'] = this.config.userAgent;
}
if ((_b = this.config) === null || _b === void 0 ? void 0 : _b.integrationUserAgent) {
config.headers['X-Crowdin-Integrations-User-Agent'] = this.config.integrationUserAgent;
}
return config;
}
/** @internal */
get httpClient() {
var _a, _b;
if ((_a = this.config) === null || _a === void 0 ? void 0 : _a.httpClient) {
return this.config.httpClient;
}
if ((_b = this.config) === null || _b === void 0 ? void 0 : _b.httpClientType) {
switch (this.config.httpClientType) {
case 'axios':
return CrowdinApi.AXIOS_INSTANCE;
case 'fetch':
return CrowdinApi.FETCH_INSTANCE;
default:
return CrowdinApi.AXIOS_INSTANCE;
}
}
return CrowdinApi.AXIOS_INSTANCE;
}
withFetchAll(maxLimit) {
this.fetchAllFlag = true;
this.maxLimit = maxLimit;
return this;
}
async getList(url, limit, offset, config) {
const conf = config !== null && config !== void 0 ? config : this.defaultConfig();
if (this.fetchAllFlag) {
this.fetchAllFlag = false;
const maxAmount = this.maxLimit;
this.maxLimit = undefined;
return await this.fetchAll(url, conf, maxAmount);
}
else {
url = this.addQueryParam(url, 'limit', limit);
url = this.addQueryParam(url, 'offset', offset);
return this.get(url, conf);
}
}
async fetchAll(url, config, maxAmount) {
let limit = 500;
if (maxAmount && maxAmount < limit) {
limit = maxAmount;
}
let offset = 0;
let resp;
for (;;) {
let urlWithPagination = this.addQueryParam(url, 'limit', limit);
urlWithPagination = this.addQueryParam(urlWithPagination, 'offset', offset);
const e = await this.get(urlWithPagination, config);
if (!resp) {
resp = e;
}
else {
resp.data = resp.data.concat(e.data);
resp.pagination.limit += e.data.length;
}
if (e.data.length < limit || (maxAmount && resp.data.length >= maxAmount)) {
break;
}
else {
offset += limit;
}
if (maxAmount && maxAmount < resp.data.length + limit) {
limit = maxAmount - resp.data.length;
}
}
return resp;
}
encodeUrlParam(param) {
return encodeURIComponent(param);
}
//Http overrides
get(url, config) {
return this.retryService
.executeAsyncFunc(() => this.httpClient.get(url, config))
.catch((err) => handleHttpClientError((0, http_client_error_1.toHttpClientError)(err)));
}
delete(url, config) {
return this.retryService
.executeAsyncFunc(() => this.httpClient.delete(url, config))
.catch((err) => handleHttpClientError((0, http_client_error_1.toHttpClientError)(err)));
}
head(url, config) {
return this.retryService
.executeAsyncFunc(() => this.httpClient.head(url, config))
.catch((err) => handleHttpClientError((0, http_client_error_1.toHttpClientError)(err)));
}
post(url, data, config) {
return this.retryService
.executeAsyncFunc(() => this.httpClient.post(url, data, config))
.catch((err) => handleHttpClientError((0, http_client_error_1.toHttpClientError)(err)));
}
put(url, data, config) {
return this.retryService
.executeAsyncFunc(() => this.httpClient.put(url, data, config))
.catch((err) => handleHttpClientError((0, http_client_error_1.toHttpClientError)(err)));
}
patch(url, data, config) {
return this.retryService
.executeAsyncFunc(() => this.httpClient.patch(url, data, config))
.catch((err) => handleHttpClientError((0, http_client_error_1.toHttpClientError)(err)));
}
}
exports.CrowdinApi = CrowdinApi;
CrowdinApi.CROWDIN_URL_SUFFIX = 'api.crowdin.com/api/v2';
CrowdinApi.AXIOS_INSTANCE = new axiosProvider_1.AxiosProvider().axios;
CrowdinApi.FETCH_INSTANCE = new fetchClient_1.FetchClient();
let deprecationEmittedForOptionalParams = false;
function emitDeprecationWarning() {
if (!deprecationEmittedForOptionalParams) {
if (typeof process !== 'undefined' && typeof process.emitWarning === 'function') {
process.emitWarning('Passing optional parameters individually is deprecated. Pass a sole object instead', 'DeprecationWarning');
}
else {
console.warn('DeprecationWarning: Passing optional parameters individually is deprecated. Pass a sole object instead');
}
deprecationEmittedForOptionalParams = true;
}
}
/**
* @internal
*/
function isOptionalString(parameter, parameterInArgs) {
if (typeof parameter === 'string' || typeof parameter === 'undefined') {
if (parameterInArgs) {
emitDeprecationWarning();
}
return true;
}
else {
return false;
}
}
exports.isOptionalString = isOptionalString;
/**
* @internal
*/
function isOptionalNumber(parameter, parameterInArgs) {
if (typeof parameter === 'number' || typeof parameter === 'undefined') {
if (parameterInArgs) {
emitDeprecationWarning();
}
return true;
}
else {
return false;
}
}
exports.isOptionalNumber = isOptionalNumber;