UNPKG

@crowdin/app-project-module

Version:

Module that generates for you all common endpoints for serving standalone Crowdin App

314 lines (313 loc) 15.3 kB
"use strict"; 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 () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __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.AppModuleAggregateError = exports.AppUserModuleError = exports.AppModuleError = void 0; exports.initialize = initialize; exports.prepareContext = prepareContext; exports.withContext = withContext; exports.withContextError = withContextError; exports.log = log; exports.logError = logError; exports.isAxiosError = isAxiosError; exports.isInternalErrorMessage = isInternalErrorMessage; exports.getErrorMessage = getErrorMessage; exports.handleUserError = handleUserError; exports.temporaryErrorDebug = temporaryErrorDebug; 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; } function prepareContext(context) { return { orgId: context.crowdinId, userId: context.clientId, projectId: context.jwtPayload.context.project_id, }; } function withContext(context) { return (message) => log(message, context); } function withContextError(context) { return (e) => logError(e, context); } 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 : '', organization_id: context.jwtPayload.context.organization_id, 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}`); } } } function logError(e, context) { var _a, _b, _c; if (onError) { onError({ error: 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 : '', organization_id: context.jwtPayload.context.organization_id, 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); } } } 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; } function isInternalErrorMessage(message) { const internalErrorMessagePrefixes = ['SQL']; for (const prefix of internalErrorMessagePrefixes) { if (message.startsWith(prefix)) { return true; } } return false; } 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; } class AppModuleError extends Error { constructor(error, data) { var _a; 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; // Extract HTTP status code from axios error this.code = ((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) || error.status; } else if (error.code && typeof error.code === 'number') { // If error already has a numeric code property (e.g., CodeError) this.code = error.code; } } } 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(_a) { return __awaiter(this, arguments, void 0, function* ({ action, error, crowdinId, clientId, }) { var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x; const data = {}; if (isAxiosError(error)) { data.requestParams = { method: ((_b = error === null || error === void 0 ? void 0 : error.request) === null || _b === void 0 ? void 0 : _b.method) || ((_d = (_c = error === null || error === void 0 ? void 0 : error.data) === null || _c === void 0 ? void 0 : _c.request) === null || _d === void 0 ? void 0 : _d.method), protocol: ((_e = error === null || error === void 0 ? void 0 : error.request) === null || _e === void 0 ? void 0 : _e.protocol) || ((_g = (_f = error === null || error === void 0 ? void 0 : error.data) === null || _f === void 0 ? void 0 : _f.request) === null || _g === void 0 ? void 0 : _g.protocol), host: ((_h = error === null || error === void 0 ? void 0 : error.request) === null || _h === void 0 ? void 0 : _h.host) || ((_k = (_j = error === null || error === void 0 ? void 0 : error.data) === null || _j === void 0 ? void 0 : _j.request) === null || _k === void 0 ? void 0 : _k.host), path: ((_l = error === null || error === void 0 ? void 0 : error.request) === null || _l === void 0 ? void 0 : _l.path) || ((_o = (_m = error === null || error === void 0 ? void 0 : error.data) === null || _m === void 0 ? void 0 : _m.request) === null || _o === void 0 ? void 0 : _o.path), }; data.responseData = { data: ((_p = error === null || error === void 0 ? void 0 : error.response) === null || _p === void 0 ? void 0 : _p.data) || ((_r = (_q = error === null || error === void 0 ? void 0 : error.data) === null || _q === void 0 ? void 0 : _q.response) === null || _r === void 0 ? void 0 : _r.data), status: ((_s = error === null || error === void 0 ? void 0 : error.response) === null || _s === void 0 ? void 0 : _s.status) || ((_u = (_t = error === null || error === void 0 ? void 0 : error.data) === null || _t === void 0 ? void 0 : _t.response) === null || _u === void 0 ? void 0 : _u.status), statusText: ((_v = error === null || error === void 0 ? void 0 : error.response) === null || _v === void 0 ? void 0 : _v.statusText) || ((_x = (_w = error === null || error === void 0 ? void 0 : error.data) === null || _w === void 0 ? void 0 : _w.response) === null || _x === void 0 ? void 0 : _x.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(_a) { return __awaiter(this, arguments, void 0, function* ({ action, error, crowdinId, clientId, }) { 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 }); } }); } function temporaryErrorDebug(msg, req) { // eslint-disable-next-line no-console console.log(msg, req.headers, Object.assign({ originalUrl: req.originalUrl }, req.query)); }