{"version":3,"file":"utils2.cjs","names":["unauthorizedHandler: UnauthorizedHandler | undefined","options: AxiosRequestConfig","onErrorOnce: ((e: Error) => void) | undefined","assistantRequest: RequestInit","data: T","e: unknown"],"sources":["../src/utils.ts"],"sourcesContent":["import { getBrowserId } from '@n8n/constants';\nimport { assert } from '@n8n/utils/assert';\nimport type { AxiosRequestConfig, Method, RawAxiosRequestHeaders } from 'axios';\nimport axios from 'axios';\nimport { jsonParse } from 'n8n-workflow';\nimport type { GenericValue, IDataObject } from 'n8n-workflow';\n\nimport type { IRestApiContext } from './types';\n\nexport const NO_NETWORK_ERROR_CODE = 999;\nexport const STREAM_SEPARATOR = '⧉⇋⇋➽⌑⧉§§\\n';\n\nexport class MfaRequiredError extends Error {\n\tconstructor() {\n\t\tsuper('MFA is required to access this resource. Please set up MFA in your user settings.');\n\t\tthis.name = 'MfaRequiredError';\n\t}\n}\n\nexport class ResponseError extends Error {\n\t// The HTTP status code of response\n\thttpStatusCode?: number;\n\n\t// The error code in the response\n\terrorCode?: number;\n\n\t// The stack trace of the server\n\tserverStackTrace?: string;\n\n\t// Additional metadata from the server (e.g., EULA URL)\n\tmeta?: Record<string, unknown>;\n\n\t// Additional hint from the server\n\thint?: string;\n\n\t/**\n\t * Creates an instance of ResponseError.\n\t * @param {string} message The error message\n\t * @param {number} [errorCode] The error code which can be used by frontend to identify the actual error\n\t * @param {number} [httpStatusCode] The HTTP status code the response should have\n\t * @param {string} [stack] The stack trace\n\t * @param {Record<string, unknown>} [meta] Additional metadata from the server\n\t * @param {string} [hint] Additional hint from the server\n\t */\n\tconstructor(\n\t\tmessage: string,\n\t\toptions: {\n\t\t\terrorCode?: number;\n\t\t\thttpStatusCode?: number;\n\t\t\tstack?: string;\n\t\t\tmeta?: Record<string, unknown>;\n\t\t\thint?: ResponseError['hint'];\n\t\t} = {},\n\t) {\n\t\tsuper(message);\n\t\tthis.name = 'ResponseError';\n\n\t\tconst { errorCode, httpStatusCode, stack, meta, hint } = options;\n\t\tif (errorCode) {\n\t\t\tthis.errorCode = errorCode;\n\t\t}\n\t\tif (httpStatusCode) {\n\t\t\tthis.httpStatusCode = httpStatusCode;\n\t\t}\n\t\tif (stack) {\n\t\t\tthis.serverStackTrace = stack;\n\t\t}\n\t\tif (meta) {\n\t\t\tthis.meta = meta;\n\t\t}\n\t\tif (hint) {\n\t\t\tthis.hint = hint;\n\t\t}\n\t}\n}\n\nexport type UnauthorizedHandler = (baseURL: string) => void;\nlet unauthorizedHandler: UnauthorizedHandler | undefined;\n\n// Called on every 401 from request() below, with its baseURL, so non-n8n hosts can be ignored.\nexport function setUnauthorizedHandler(handler: UnauthorizedHandler): void {\n\tunauthorizedHandler = handler;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst legacyParamSerializer = (params: Record<string, any>) =>\n\tObject.keys(params)\n\t\t.filter((key) => params[key] !== undefined)\n\t\t.map((key) => {\n\t\t\tif (Array.isArray(params[key])) {\n\t\t\t\treturn params[key].map((v: string) => `${key}[]=${encodeURIComponent(v)}`).join('&');\n\t\t\t}\n\t\t\tif (typeof params[key] === 'object') {\n\t\t\t\tparams[key] = JSON.stringify(params[key]);\n\t\t\t}\n\t\t\treturn `${key}=${encodeURIComponent(params[key])}`;\n\t\t})\n\t\t.join('&');\n\nexport async function request(config: {\n\tmethod: Method;\n\tbaseURL: string;\n\tendpoint: string;\n\theaders?: RawAxiosRequestHeaders;\n\tdata?: GenericValue | GenericValue[];\n\twithCredentials?: boolean;\n}) {\n\tconst { method, baseURL, endpoint, headers, data } = config;\n\tconst options: AxiosRequestConfig = {\n\t\tmethod,\n\t\turl: endpoint,\n\t\tbaseURL,\n\t\theaders: headers ?? {},\n\t};\n\tif (baseURL.startsWith('/')) {\n\t\toptions.headers!['browser-id'] = getBrowserId();\n\t}\n\tif (\n\t\timport.meta.env.NODE_ENV !== 'production' &&\n\t\t!baseURL.includes('api.n8n.io') &&\n\t\t!baseURL.includes('n8n.cloud')\n\t) {\n\t\toptions.withCredentials = options.withCredentials ?? true;\n\t}\n\tif (['POST', 'PATCH', 'PUT'].includes(method)) {\n\t\toptions.data = data;\n\t} else if (data) {\n\t\toptions.params = data;\n\t\toptions.paramsSerializer = legacyParamSerializer;\n\t}\n\n\ttry {\n\t\tconst response = await axios.request(options);\n\t\treturn response.data;\n\t} catch (error) {\n\t\tif (error.message === 'Network Error') {\n\t\t\tthrow new ResponseError(\"Can't connect to n8n.\", {\n\t\t\t\terrorCode: NO_NETWORK_ERROR_CODE,\n\t\t\t});\n\t\t}\n\n\t\tconst errorResponseData = error.response?.data;\n\t\tif (errorResponseData?.mfaRequired === true) {\n\t\t\tthrow new MfaRequiredError();\n\t\t}\n\n\t\t// After mfaRequired: that 401 means valid-but-unenrolled, not expired.\n\t\tif (error.response?.status === 401) {\n\t\t\tunauthorizedHandler?.(baseURL);\n\t\t}\n\n\t\tif (errorResponseData?.message !== undefined) {\n\t\t\tif (errorResponseData.name === 'NodeApiError') {\n\t\t\t\terrorResponseData.httpStatusCode = error.response.status;\n\t\t\t\tthrow errorResponseData;\n\t\t\t}\n\n\t\t\tthrow new ResponseError(errorResponseData.message, {\n\t\t\t\terrorCode: errorResponseData.code,\n\t\t\t\thttpStatusCode: error.response.status,\n\t\t\t\tstack: errorResponseData.stack,\n\t\t\t\tmeta: errorResponseData.meta,\n\t\t\t\thint: errorResponseData.hint,\n\t\t\t});\n\t\t}\n\n\t\tthrow error;\n\t}\n}\n\n/**\n * Sends a request to the API and returns the response without extracting the data key.\n * @param context Rest API context\n * @param method HTTP method\n * @param endpoint relative path to the API endpoint\n * @param data request data\n * @returns data and total count\n */\nexport async function getFullApiResponse<T>(\n\tcontext: IRestApiContext,\n\tmethod: Method,\n\tendpoint: string,\n\tdata?: GenericValue | GenericValue[],\n) {\n\tconst response = await request({\n\t\tmethod,\n\t\tbaseURL: context.baseUrl,\n\t\tendpoint,\n\t\theaders: { 'push-ref': context.pushRef },\n\t\tdata,\n\t});\n\n\treturn response as { count: number; data: T };\n}\n\nexport async function makeRestApiRequest<T>(\n\tcontext: IRestApiContext,\n\tmethod: Method,\n\tendpoint: string,\n\tdata?: GenericValue | GenericValue[],\n) {\n\tconst response = await request({\n\t\tmethod,\n\t\tbaseURL: context.baseUrl,\n\t\tendpoint,\n\t\theaders: { 'push-ref': context.pushRef },\n\t\tdata,\n\t});\n\n\t// All cli rest api endpoints return data wrapped in `data` key\n\treturn response.data as T;\n}\n\nexport async function get(\n\tbaseURL: string,\n\tendpoint: string,\n\tparams?: IDataObject,\n\theaders?: RawAxiosRequestHeaders,\n) {\n\treturn await request({ method: 'GET', baseURL, endpoint, headers, data: params });\n}\n\nexport async function post(\n\tbaseURL: string,\n\tendpoint: string,\n\tparams?: IDataObject,\n\theaders?: RawAxiosRequestHeaders,\n) {\n\treturn await request({ method: 'POST', baseURL, endpoint, headers, data: params });\n}\n\nexport async function patch(\n\tbaseURL: string,\n\tendpoint: string,\n\tparams?: IDataObject,\n\theaders?: RawAxiosRequestHeaders,\n) {\n\treturn await request({ method: 'PATCH', baseURL, endpoint, headers, data: params });\n}\n\nexport async function streamRequest<T extends object>(\n\tcontext: IRestApiContext,\n\tapiEndpoint: string,\n\tpayload: object,\n\tonChunk?: (chunk: T) => void,\n\tonDone?: () => void,\n\tonError?: (e: Error) => void,\n\tseparator = STREAM_SEPARATOR,\n\tabortSignal?: AbortSignal,\n): Promise<void> {\n\tlet onErrorOnce: ((e: Error) => void) | undefined = (e: Error) => {\n\t\tonErrorOnce = undefined;\n\t\tonError?.(e);\n\t};\n\tconst headers: Record<string, string> = {\n\t\t'browser-id': getBrowserId(),\n\t\t'Content-Type': 'application/json',\n\t};\n\tconst assistantRequest: RequestInit = {\n\t\theaders,\n\t\tmethod: 'POST',\n\t\tcredentials: 'include',\n\t\tbody: JSON.stringify(payload),\n\t\tsignal: abortSignal,\n\t};\n\ttry {\n\t\tconst response = await fetch(`${context.baseUrl}${apiEndpoint}`, assistantRequest);\n\n\t\tif (response.body) {\n\t\t\t// Handle the streaming response\n\t\t\tconst reader = response.body.getReader();\n\t\t\tconst decoder = new TextDecoder('utf-8');\n\n\t\t\tlet buffer = '';\n\n\t\t\tasync function readStream() {\n\t\t\t\tconst { done, value } = await reader.read();\n\t\t\t\tif (done) {\n\t\t\t\t\tif (!response.ok) {\n\t\t\t\t\t\tonErrorOnce?.(\n\t\t\t\t\t\t\tnew ResponseError(response.statusText, {\n\t\t\t\t\t\t\t\thttpStatusCode: response.status,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t} else if (buffer.trim()) {\n\t\t\t\t\t\t// The stream ended with leftover content that never parsed as JSON.\n\t\t\t\t\t\t// A JSON-like fragment means the stream was cut off mid-chunk;\n\t\t\t\t\t\t// anything else is a plain-text error body from an upstream\n\t\t\t\t\t\t// service — surface its content instead of silently dropping it.\n\t\t\t\t\t\tconst leftover = buffer.trim();\n\t\t\t\t\t\tconst message = /^[[{]/.test(leftover) ? 'Connection lost' : leftover.slice(0, 256);\n\t\t\t\t\t\tonErrorOnce?.(new Error(message));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tonDone?.();\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst chunk = decoder.decode(value);\n\t\t\t\tbuffer += chunk;\n\n\t\t\t\tconst splitChunks = buffer.split(separator);\n\n\t\t\t\tbuffer = '';\n\t\t\t\tfor (const splitChunk of splitChunks) {\n\t\t\t\t\tif (splitChunk) {\n\t\t\t\t\t\tlet data: T;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tdata = jsonParse<T>(splitChunk, { errorMessage: 'Invalid json' });\n\t\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\t\t// incomplete json. append to buffer to complete\n\t\t\t\t\t\t\tbuffer += splitChunk;\n\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tif (response.ok) {\n\t\t\t\t\t\t\t\t// Call chunk callback if request was successful\n\t\t\t\t\t\t\t\tonChunk?.(data);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// Otherwise, call error callback\n\t\t\t\t\t\t\t\tconst message = 'message' in data ? data.message : response.statusText;\n\t\t\t\t\t\t\t\tonErrorOnce?.(\n\t\t\t\t\t\t\t\t\tnew ResponseError(String(message), {\n\t\t\t\t\t\t\t\t\t\thttpStatusCode: response.status,\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch (e: unknown) {\n\t\t\t\t\t\t\tif (e instanceof Error) {\n\t\t\t\t\t\t\t\tonErrorOnce?.(e);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tawait readStream();\n\t\t\t}\n\n\t\t\t// Start reading the stream\n\t\t\tawait readStream();\n\t\t} else if (onErrorOnce) {\n\t\t\tonErrorOnce(new Error(response.statusText));\n\t\t}\n\t} catch (e: unknown) {\n\t\tassert(e instanceof Error);\n\t\tonErrorOnce?.(e);\n\t}\n}\n"],"mappings":"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"}