UNPKG

@crowdin/crowdin-api-client

Version:
319 lines (318 loc) 12.7 kB
"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;