{"version":3,"sources":["../../src/express/factory.ts","../../src/helpers.ts","../../src/core/types.ts","../../src/core/baseUtility.ts","../../src/express/utility.ts","../../src/express/index.ts"],"sourcesContent":["import type { ErrorRequestHandler, RequestHandler } from \"express\";\nimport type { ExpressErrorUtility } from \"./utility\";\n\nexport interface BasicMiddlewareOptions {\n    projectName: string;\n    apiKey: string;\n}\n\ntype BaseHandlerContext<TErrorUtility extends ExpressErrorUtility> = {\n    instance: TErrorUtility;\n};\n\nexport type ExpressMiddlewareSetup<\n    TMiddlewareOptions extends BasicMiddlewareOptions\n> = (opts: TMiddlewareOptions) => {\n        initialize: RequestHandler;\n        onError: ErrorRequestHandler;\n    }\n\n/*\n    The setupTryCatchFactory function allows the construction of a setupTryCatch\n    with a consistent interface for both testing and normal use.\n    Here, we use a custom instance of the ExpressErrorUtility that exposes a mapError method.\n    Subsequently, we insert the mapped error into the mock server response, enabling us to test\n    the mapping with real parameters\n*/\nexport const setupTryCatchFactory = <\n    TErrorUtility extends ExpressErrorUtility,\n    THandlerContext extends BaseHandlerContext<TErrorUtility>,\n    TMiddlewareOptions extends BasicMiddlewareOptions = BasicMiddlewareOptions\n>(factoryOptions: {\n    createContext: (options: TMiddlewareOptions) => THandlerContext;\n    handlers: {\n        initialize: (context: THandlerContext) => RequestHandler;\n        onError: (context: THandlerContext) => ErrorRequestHandler;\n    };\n}): ExpressMiddlewareSetup<TMiddlewareOptions> => {\n    return (options: TMiddlewareOptions) => {\n        const context = factoryOptions.createContext(options);\n\n        return {\n            initialize: factoryOptions.handlers.initialize(context),\n            onError: factoryOptions.handlers.onError(context),\n        };\n    };\n};\n","import type { AxiosError } from 'axios';\n\nexport function isAxiosError(e: unknown): e is AxiosError {\n    return (\n        e !== null &&\n        typeof e === \"object\" &&\n        (e as Pick<AxiosError, \"isAxiosError\">).isAxiosError === true\n    );\n}\n","export type SendErrorResponse =\n\t| {\n\t\t\tid: string;\n\t  }\n\t| undefined;\n\nexport interface ErrorUtilityMethods<TRequest> {\n\tsendError(\n\t\terror: Error | unknown,\n\t\tuserContext?: Record<string, unknown>,\n\t): Promise<SendErrorResponse>;\n\tsendErrorFromEndPoint(\n\t\terror: Error | unknown,\n\t\trequest: TRequest,\n\t\tuserContext?: Record<string, unknown>,\n\t): Promise<SendErrorResponse>;\n}\n\nexport class WrappedError extends Error {\n\treadonly value: unknown;\n\tconstructor(message: string, value: unknown) {\n\t\tsuper(message);\n\n\t\tthis.value = value;\n\t}\n}\n\nexport interface HttpRequest {\n\turl?: string;\n\tmethod?: string;\n\tpath?: string;\n\tbody?: unknown;\n\tquery?: Record<string, unknown>;\n\theaders?: Record<string, unknown>;\n}\n\nexport interface MappedHttpRequest {\n\tmethod: string | null;\n\turl: string | null;\n\trequestBody: unknown | null;\n\tquery: Record<string, unknown> | null;\n\theaders: Record<string, unknown> | null;\n}\n\nexport type ErrorDetails<\n\tT extends Record<string, unknown> = Record<string, unknown>,\n> = {\n\tname: string;\n\tmessage: string;\n} & T;\n\nexport type ErrorRequestContext = Record<string, unknown> | null;\n\nexport interface ErrorRequest<\n\tTDetails extends Record<string, unknown> = Record<string, unknown>,\n> {\n\terrorName: string;\n\terrorDetails: ErrorDetails<TDetails>;\n\tstack: string | null;\n\tcontext: ErrorRequestContext;\n\tuser: string;\n\tprojectName: string;\n}\n\nexport type AxiosErrorRequest = ErrorRequest<{\n\turl: string | null;\n\tquery: Record<string, string | string[] | undefined> | null;\n\tparams: unknown | null;\n\tmethod: string | null;\n\tstatusCode: number;\n\trequestBody: unknown | null;\n\tresponseBody: unknown | null;\n}>;\n","import { isAxiosError } from \"../helpers\";\nimport type {\n\tMappedHttpRequest,\n\tErrorRequest,\n\tAxiosErrorRequest,\n\tErrorUtilityMethods,\n\tErrorDetails,\n\tErrorRequestContext,\n} from \"./types\";\nimport { WrappedError } from \"./types\";\nimport type { AxiosError } from \"axios\";\n\nexport abstract class BaseErrorUtility<TRequest>\n\timplements ErrorUtilityMethods<TRequest>\n{\n\tconstructor(\n\t\tprotected readonly projectName: string,\n\t\tprotected readonly apiKey: string,\n\t\tprotected readonly debug?: boolean,\n\t) {\n\t\tif (!projectName.length) {\n\t\t\tthrow new Error(\"Invalid project name\");\n\t\t}\n\n\t\tif (!apiKey.length) {\n\t\t\tthrow new Error(\"Invalid API key\");\n\t\t}\n\t}\n\n\tprotected abstract mapRequest(\n\t\trequest: TRequest,\n\t): Promise<MappedHttpRequest> | MappedHttpRequest;\n\n\tasync sendError(\n\t\terror: Error | unknown,\n\t\tuserContext?: Record<string, unknown>,\n\t) {\n\t\ttry {\n\t\t\tconst payload = await this.mapErrorRequestPayload(\n\t\t\t\terror,\n\t\t\t\tundefined,\n\t\t\t\tuserContext,\n\t\t\t);\n\n\t\t\treturn this.send(payload);\n\t\t} catch (err) {\n\t\t\tif (this.debug) {\n\t\t\t\tconsole.log(err);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Sends error and request details to try-catch-cloud service.\n\t * You can manually map details from your route to request object.\n\t *\n\t * ```\n\t *  errorTrack.sendErrorFromEndpoint(\n\t *      error,\n\t *      {\n\t *          url: req.originalUrl.split(\"?\")[0],\n\t *          method: req.method,\n\t *          headers: req.headers,\n\t *          query: req.query,\n\t *          body,\n\t *      },\n\t *      { ...context }\n\t *  );\n\t * ```\n\t */\n\tasync sendErrorFromEndPoint(\n\t\terror: Error | unknown,\n\t\trequest: TRequest,\n\t\tuserContext?: Record<string, unknown>,\n\t) {\n\t\ttry {\n\t\t\tconst payload = await this.mapErrorRequestPayload(\n\t\t\t\terror,\n\t\t\t\trequest,\n\t\t\t\tuserContext,\n\t\t\t);\n\n\t\t\treturn this.send(payload);\n\t\t} catch (err) {\n\t\t\tif (this.debug) {\n\t\t\t\tconsole.log(err);\n\t\t\t}\n\t\t}\n\t}\n\n\tprotected async send(payload: ErrorRequest): Promise<{ id: string }> {\n\t\tconst result = await fetch(\"https://oleksiikilevoi.site/api/err-log/new\", {\n\t\t\tmethod: \"POST\",\n\t\t\tbody: JSON.stringify(payload),\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t},\n\t\t});\n\n\t\tif (this.debug) {\n\t\t\tconsole.info(\"Send result\", await result.text());\n\t\t}\n\n        const data: { id: string } = await result.json();\n\n        return data;\n\t}\n\n\t/**\n\t * It has to return Promise to be compatible with different implementations\n\t * e.g. Hono returns Promise when accessing req.json()\n\t */\n\tprotected async mapErrorRequestPayload(\n\t\terror: Error | unknown,\n\t\trequest?: TRequest,\n\t\tcontext?: Record<string, unknown>,\n\t): Promise<ErrorRequest> {\n\t\tif (!(error instanceof Error)) {\n\t\t\treturn this.mapErrorRequestPayload(\n\t\t\t\tnew WrappedError(\"An unexpected value was thrown\", error),\n\t\t\t\trequest,\n\t\t\t\tcontext,\n\t\t\t);\n\t\t}\n\n\t\tif (isAxiosError(error)) {\n\t\t\treturn this.mapAxiosError(error, request, context);\n\t\t}\n\n\t\tconst { stack, ...restErrorDetails } = error;\n\n\t\treturn {\n\t\t\t...(request ? await this.mapRequest(request) : {}),\n\t\t\terrorName: error.name,\n\t\t\terrorDetails: this.sanitizeValue({\n\t\t\t\t...restErrorDetails,\n\t\t\t\tname: error.name,\n\t\t\t\tmessage: error.message,\n\t\t\t}) as ErrorDetails,\n\t\t\tstack: error.stack ?? null,\n\t\t\tcontext: this.sanitizeValue(context ?? null) as ErrorRequestContext,\n\t\t\tuser: this.apiKey,\n\t\t\tprojectName: this.projectName,\n\t\t};\n\t}\n\n\tprotected mapAxiosRequestBody(error: AxiosError) {\n\t\ttry {\n\t\t\tconst config = error.config;\n\t\t\tconst headers: Record<string, string> = config?.headers ?? {};\n\t\t\tconst contentType: string =\n\t\t\t\theaders[\"content-type\"] ?? headers[\"Content-Type\"] ?? \"\";\n\n\t\t\tif (!contentType.length) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tif (contentType.startsWith(\"multipart/form-data\")) {\n\t\t\t\treturn \"#form-data\";\n\t\t\t}\n\n\t\t\tif (contentType === \"application/json\") {\n\t\t\t\treturn JSON.parse(config?.data);\n\t\t\t}\n\n\t\t\tif (contentType.match(/^text\\/.+$/)) {\n\t\t\t\treturn config?.data as string;\n\t\t\t}\n\n\t\t\tif (contentType === \"application/x-www-form-urlencoded\") {\n\t\t\t\treturn new URLSearchParams(config?.data).toString();\n\t\t\t}\n\n\t\t\tif (contentType === \"application/xml\") {\n\t\t\t\treturn decodeURIComponent(config?.data); // Assuming data is already a string\n\t\t\t}\n\n\t\t\tif (contentType === \"application/octet-stream\") {\n\t\t\t\treturn \"#binary-data\";\n\t\t\t}\n\n\t\t\treturn \"#tcc/mapping-failed\";\n\t\t} catch (e) {\n\t\t\tif (this.debug) {\n\t\t\t\tconsole.error(e);\n\t\t\t}\n\n\t\t\treturn \"#tcc/mapping-failed\";\n\t\t}\n\t}\n\n\tprotected async mapAxiosError(\n\t\terror: AxiosError,\n\t\trequest?: TRequest,\n\t\tcontext?: ErrorRequestContext,\n\t): Promise<AxiosErrorRequest> {\n\t\tconst { config, response } = error;\n\t\tconst requestBody = this.mapAxiosRequestBody(error);\n\t\tconst responseBody = response?.data;\n\n\t\tconst rawUrl = config?.url ?? \"\";\n\t\tconst query = Object.fromEntries([\n\t\t\t...(URL.canParse(rawUrl) ? new URL(rawUrl).searchParams.entries() : []),\n\t\t]);\n\n\t\tconst axiosDetails = {\n\t\t\turl: config?.url ?? null,\n\t\t\tquery: Object.keys(query).length ? query : null,\n\t\t\tparams: config?.params ?? null,\n\t\t\tmethod: config?.method?.toUpperCase() || null,\n\t\t\tstatusCode: response?.status ?? 0,\n\t\t\trequestBody,\n\t\t\tresponseBody: responseBody ?? null,\n\t\t\theaders: config?.headers ?? {},\n\t\t};\n\n\t\treturn {\n\t\t\t...(request ? await this.mapRequest(request) : {}),\n\t\t\terrorName: error.constructor.name ?? error.name,\n\t\t\terrorDetails: this.sanitizeValue({\n\t\t\t\t...axiosDetails,\n\t\t\t\tname: error.name,\n\t\t\t\tmessage: error.message,\n\t\t\t}) as ErrorDetails<typeof axiosDetails>,\n\t\t\tstack: error.stack ?? null,\n\t\t\tcontext: context ?? null,\n\t\t\tuser: this.apiKey,\n\t\t\tprojectName: this.projectName,\n\t\t};\n\t}\n\n\tprotected sanitizeValue(value: unknown, level = 1): unknown {\n\t\tif (typeof value === \"object\" && value !== null && !Array.isArray(value)) {\n\t\t\tconst result: Record<string, unknown> = {};\n\n\t\t\tfor (const [key, objValue] of Object.entries(value)) {\n\t\t\t\tresult[key] = this.sanitizeValue(objValue, level + 1);\n\t\t\t}\n\n\t\t\treturn result;\n\t\t}\n\n\t\tif (typeof value === \"object\" && Array.isArray(value)) {\n\t\t\treturn value.map((item) => this.sanitizeValue(item, level + 1));\n\t\t}\n\n\t\tif (typeof value === \"function\") {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn value;\n\t}\n}\n","import type { Request } from 'express';\nimport type { MappedHttpRequest, SendErrorResponse } from \"../core/types\";\nimport { BaseErrorUtility } from '../core/baseUtility';\n\n/**\n * Implements request mapping for Express.  \n * See `sendErrorFromEndPoint` method.\n */\nexport class ExpressErrorUtility extends BaseErrorUtility<Request> {\n    protected mapRequest(req: Request): MappedHttpRequest {\n        const headers = req.headers;\n        const method = req.method.toUpperCase();\n        const [url] = req.originalUrl.split(\"?\");\n\n        return {\n            method,\n            url,\n            requestBody: req.body && Object.keys(req.body).length ? req.body : null,\n            query: Object.keys(req.query).length ? req.query : null,\n            headers: Object.keys(headers).length ? headers : null,\n        };\n    }\n\n    /**\n     * Sends error and Express request details to try-catch-cloud service.  \n     * ```\n     * app.use((error, req, res, next) => {\n     *  errorUtility.sendErrorFromEndPoint(error, req)\n     *     .catch((e) => { ... });\n     *\n     *   res.status(500).json({ message: \"Internal server error\" });\n     * });\n     * ```\n     */\n    async sendErrorFromEndPoint (error: unknown, request: Request, userContext?: Record<string, unknown> | undefined): Promise<SendErrorResponse> {\n        return super.sendErrorFromEndPoint(error, request, userContext);\n    }\n}\n","import type { Request, Response, NextFunction } from \"express\";\nimport type { ExtendedRequest } from \"./types\";\nimport { setupTryCatchFactory } from \"./factory\";\nimport { ExpressErrorUtility } from \"./utility\";\n\nexport { ExpressErrorUtility } from './utility';\n\n/**\n * It returns two handlers - `initialize` and `onError`.\n * Add `initialize` to your app using `app.use` before all route handlers.\n * Add `onError` after all route handlers and before other error handlers.\n *\n * @param MiddlewareOptions - pass project name and your API key here.\n */\nexport const setupTryCatch = setupTryCatchFactory({\n    createContext: (opts) => ({\n        instance: new ExpressErrorUtility(opts.projectName, opts.apiKey),\n    }),\n    handlers: {\n        initialize:\n            (context) => (req: Request, res: Response, next: NextFunction) => {\n                (req as ExtendedRequest).tryCatchContext = {};\n\n                next();\n            },\n        onError:\n            (context) =>\n            (\n                error: unknown,\n                req: Request,\n                res: Response,\n                next: NextFunction\n            ) => {\n                const tccReq = req as ExtendedRequest;\n                const errorContext = tccReq.tryCatchContext ?? {};\n\n                context.instance\n                    .sendErrorFromEndPoint(error, req, errorContext)\n                    .catch((e) => {\n                        console.warn(e);\n                    });\n\n                return next(error);\n            },\n    },\n});\n\n/**\n * Adds context details to try-catch-cloud error.\n * If you call it multiple times, it collects all details,\n * but details with the same name will be overwritten with the latest value.\n *\n * @example\n * addContext(req, { username: 'hugo_reyes8' }); // Context: { username: 'hugo_reyes8' }\n * addContext(req, { age: 29 }); // Context: { username: 'hugo_reyes8', age: 29 }\n * addContext(req, { age: 32 }); // Context: { username: 'hugo_reyes8', age: 32 }\n *\n * @param req - Express request\n * @param details - Context details\n */\nexport const addContext = (\n    req: Request,\n    details: Record<string, unknown>\n): void => {\n    const tccReq = req as ExtendedRequest;\n\n    if (!tccReq.tryCatchContext) {\n        (req as ExtendedRequest).tryCatchContext = {};\n    }\n\n    tccReq.tryCatchContext = {\n        ...tccReq.tryCatchContext,\n        ...details,\n    };\n};\n"],"mappings":"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","names":[]}