@crowdin/app-project-module
Version:
Module that generates for you all common endpoints for serving standalone Crowdin App
301 lines (300 loc) • 15.2 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.temporaryErrorDebug = exports.handleUserError = exports.AppModuleAggregateError = exports.AppUserModuleError = exports.AppModuleError = exports.getErrorMessage = exports.isInternalErrorMessage = exports.isAxiosError = exports.logError = exports.log = exports.withContextError = exports.withContext = exports.prepareContext = exports.initialize = void 0;
const logsFormatter = __importStar(require("@crowdin/logs-formatter"));
const storage_1 = require("../storage");
let logConfig;
let onError;
function initialize(config) {
logConfig = config.logger;
onError = config.onError;
}
exports.initialize = initialize;
function prepareContext(context) {
return {
orgId: context.crowdinId,
userId: context.clientId,
projectId: context.jwtPayload.context.project_id,
};
}
exports.prepareContext = prepareContext;
function withContext(context) {
return (message) => log(message, context);
}
exports.withContext = withContext;
function withContextError(context) {
return (e) => logError(e, context);
}
exports.withContextError = withContextError;
function log(message, context) {
var _a, _b, _c;
if (logConfig === null || logConfig === void 0 ? void 0 : logConfig.enabled) {
if (logConfig.log) {
logConfig.log(message, context);
}
else {
let prefix = `[${new Date().toISOString()}]`;
if (context) {
logsFormatter.resetContext();
logsFormatter.setContext({
appIdentifier: context.appIdentifier || '',
project: {
id: context.jwtPayload.context.project_id,
identifier: (_a = context.jwtPayload.context.project_identifier) !== null && _a !== void 0 ? _a : '',
// eslint-disable-next-line @typescript-eslint/camelcase
organization_id: context.jwtPayload.context.organization_id,
// eslint-disable-next-line @typescript-eslint/camelcase
user_id: context.jwtPayload.context.user_id,
},
user: {
id: context.jwtPayload.context.user_id,
login: (_b = context.jwtPayload.context.user_login) !== null && _b !== void 0 ? _b : '',
},
organization: {
id: context.jwtPayload.context.organization_id,
domain: (_c = context.jwtPayload.context.organization_domain) !== null && _c !== void 0 ? _c : '',
},
});
prefix += ` Context [${JSON.stringify(prepareContext(context))}]`;
}
// eslint-disable-next-line no-console
console.log(`${prefix} ${message}`);
}
}
}
exports.log = log;
function logError(e, context) {
var _a, _b, _c;
if (onError) {
onError(e, context);
}
else {
if (context) {
logsFormatter.resetContext();
logsFormatter.setContext({
appIdentifier: context.appIdentifier || '',
project: {
id: context.jwtPayload.context.project_id,
identifier: (_a = context.jwtPayload.context.project_identifier) !== null && _a !== void 0 ? _a : '',
// eslint-disable-next-line @typescript-eslint/camelcase
organization_id: context.jwtPayload.context.organization_id,
// eslint-disable-next-line @typescript-eslint/camelcase
user_id: context.jwtPayload.context.user_id,
},
user: {
id: context.jwtPayload.context.user_id,
login: (_b = context.jwtPayload.context.user_login) !== null && _b !== void 0 ? _b : '',
},
organization: {
id: context.jwtPayload.context.organization_id,
domain: (_c = context.jwtPayload.context.organization_domain) !== null && _c !== void 0 ? _c : '',
},
});
}
if (e instanceof AppModuleAggregateError) {
if (e.errors && e.errors.length > 0) {
for (const error of e.errors) {
errorOutputByType(error);
}
}
}
else {
errorOutputByType(e);
}
}
}
exports.logError = logError;
function errorOutputByType(error) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
if (error instanceof AppUserModuleError) {
return;
}
const message = error.message || error;
if (isAxiosError(error)) {
const request = (error === null || error === void 0 ? void 0 : error.config) || ((_a = error.data) === null || _a === void 0 ? void 0 : _a.config)
? {
url: ((_b = error.config) === null || _b === void 0 ? void 0 : _b.url) || ((_c = error.data) === null || _c === void 0 ? void 0 : _c.config.url),
method: ((_d = error.config) === null || _d === void 0 ? void 0 : _d.method) || ((_e = error.data) === null || _e === void 0 ? void 0 : _e.config.method),
data: ((_f = error.config) === null || _f === void 0 ? void 0 : _f.data) || ((_g = error.data) === null || _g === void 0 ? void 0 : _g.config.data),
}
: {};
const response = (error === null || error === void 0 ? void 0 : error.response) || ((_h = error.data) === null || _h === void 0 ? void 0 : _h.response)
? {
data: ((_j = error.response) === null || _j === void 0 ? void 0 : _j.data) || ((_k = error.data) === null || _k === void 0 ? void 0 : _k.response.data),
status: ((_l = error.response) === null || _l === void 0 ? void 0 : _l.status) || ((_m = error.data) === null || _m === void 0 ? void 0 : _m.response.status),
}
: {};
console.error(message, { attributes: JSON.stringify({ request, response }) }, { backtrace: error.stack });
}
else {
console.error(message, error.data ? { attributes: typeof error.data === 'object' ? JSON.stringify(error.data) : error.data } : '', error.stack ? { backtrace: error.stack } : '');
}
}
function isAxiosError(e) {
return !!e.isAxiosError;
}
exports.isAxiosError = isAxiosError;
function isInternalErrorMessage(message) {
const internalErrorMessagePrefixes = ['SQL'];
for (const prefix of internalErrorMessagePrefixes) {
if (message.startsWith(prefix)) {
return true;
}
}
return false;
}
exports.isInternalErrorMessage = isInternalErrorMessage;
function getErrorMessage(err) {
let message = 'Internal Server Error';
if (typeof err === 'string') {
message = err;
}
else if (err.message && typeof err.message === 'string') {
message = err.message;
}
return isInternalErrorMessage(message) ? 'Internal Server Error' : message;
}
exports.getErrorMessage = getErrorMessage;
class AppModuleError extends Error {
constructor(error, data) {
super(typeof error === 'string' ? error : error.message);
this.isAxiosError = false;
this.name = 'AppModuleError';
if (typeof error !== 'string' && error.stack) {
this.stack = error.stack;
}
this.appData = data;
if (typeof error !== 'string') {
this.data = Object.assign({}, error);
}
if (isAxiosError(error)) {
this.isAxiosError = true;
}
}
}
exports.AppModuleError = AppModuleError;
class AppUserModuleError extends AppModuleError {
constructor(error, data) {
super(error, data);
this.name = 'AppUserModuleError';
}
}
exports.AppUserModuleError = AppUserModuleError;
class AppModuleAggregateError extends Error {
constructor(errors, message) {
super(message);
this.name = 'AppModuleAggregateError';
this.errors = errors;
}
}
exports.AppModuleAggregateError = AppModuleAggregateError;
function storeUserError({ action, error, crowdinId, clientId, }) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;
return __awaiter(this, void 0, void 0, function* () {
const data = {};
if (isAxiosError(error)) {
data.requestParams = {
method: ((_a = error === null || error === void 0 ? void 0 : error.request) === null || _a === void 0 ? void 0 : _a.method) || ((_c = (_b = error === null || error === void 0 ? void 0 : error.data) === null || _b === void 0 ? void 0 : _b.request) === null || _c === void 0 ? void 0 : _c.method),
protocol: ((_d = error === null || error === void 0 ? void 0 : error.request) === null || _d === void 0 ? void 0 : _d.protocol) || ((_f = (_e = error === null || error === void 0 ? void 0 : error.data) === null || _e === void 0 ? void 0 : _e.request) === null || _f === void 0 ? void 0 : _f.protocol),
host: ((_g = error === null || error === void 0 ? void 0 : error.request) === null || _g === void 0 ? void 0 : _g.host) || ((_j = (_h = error === null || error === void 0 ? void 0 : error.data) === null || _h === void 0 ? void 0 : _h.request) === null || _j === void 0 ? void 0 : _j.host),
path: ((_k = error === null || error === void 0 ? void 0 : error.request) === null || _k === void 0 ? void 0 : _k.path) || ((_m = (_l = error === null || error === void 0 ? void 0 : error.data) === null || _l === void 0 ? void 0 : _l.request) === null || _m === void 0 ? void 0 : _m.path),
};
data.responseData = {
data: ((_o = error === null || error === void 0 ? void 0 : error.response) === null || _o === void 0 ? void 0 : _o.data) || ((_q = (_p = error === null || error === void 0 ? void 0 : error.data) === null || _p === void 0 ? void 0 : _p.response) === null || _q === void 0 ? void 0 : _q.data),
status: ((_r = error === null || error === void 0 ? void 0 : error.response) === null || _r === void 0 ? void 0 : _r.status) || ((_t = (_s = error === null || error === void 0 ? void 0 : error.data) === null || _s === void 0 ? void 0 : _s.response) === null || _t === void 0 ? void 0 : _t.status),
statusText: ((_u = error === null || error === void 0 ? void 0 : error.response) === null || _u === void 0 ? void 0 : _u.statusText) || ((_w = (_v = error === null || error === void 0 ? void 0 : error.data) === null || _v === void 0 ? void 0 : _v.response) === null || _w === void 0 ? void 0 : _w.statusText),
};
}
if ((error instanceof AppModuleError || error instanceof AppUserModuleError) && error.appData) {
data.appData = error.appData;
}
yield (0, storage_1.getStorage)().saveUserError(action, (error === null || error === void 0 ? void 0 : error.message) || JSON.stringify(error, null, 2), JSON.stringify(data), `${Date.now()}`, crowdinId, clientId);
});
}
function mergeAppModuleAggregateErrors(errors) {
const result = [];
const mergedData = {
AppModuleError: {},
AppUserModuleError: {},
};
for (const errorItem of errors) {
if (errorItem instanceof AppModuleError || errorItem instanceof AppUserModuleError) {
if (typeof errorItem.appData === 'object' &&
errorItem.appData !== null &&
!Array.isArray(errorItem.appData)) {
if (!mergedData[errorItem.name][errorItem.message]) {
mergedData[errorItem.name][errorItem.message] = {};
}
for (const key in errorItem.appData) {
mergedData[errorItem.name][errorItem.message][key] = (mergedData[errorItem.name][errorItem.message][key] || []).concat(errorItem.appData[key]);
}
}
else if (errorItem.appData) {
mergedData[errorItem.name][errorItem.message] = (mergedData[errorItem.name][errorItem.message] || []).concat(errorItem.appData);
}
continue;
}
result.push(errorItem);
}
for (const key in mergedData.AppModuleError) {
result.push(new AppModuleError(key, mergedData.AppModuleError[key]));
}
for (const key in mergedData.AppUserModuleError) {
result.push(new AppUserModuleError(key, mergedData.AppUserModuleError[key]));
}
return result;
}
function handleUserError({ action, error, crowdinId, clientId, }) {
return __awaiter(this, void 0, void 0, function* () {
if (typeof error === 'string') {
return;
}
if (error instanceof AppModuleAggregateError) {
const mergedErrors = mergeAppModuleAggregateErrors(error.errors);
for (const key in mergedErrors) {
yield handleUserError({ action, error: mergedErrors[key], crowdinId, clientId });
}
}
else {
yield storeUserError({ action, error, crowdinId, clientId });
}
});
}
exports.handleUserError = handleUserError;
function temporaryErrorDebug(msg, req) {
// eslint-disable-next-line no-console
console.log(msg, req.headers, Object.assign({ originalUrl: req.originalUrl }, req.query));
}
exports.temporaryErrorDebug = temporaryErrorDebug;