{"version":3,"file":"local-variables-async.js","sources":["../../../../src/integrations/local-variables/local-variables-async.ts"],"sourcesContent":["import { Worker } from 'node:worker_threads';\nimport type { Event, EventHint, Exception, IntegrationFn } from '@sentry/core';\nimport { debug, defineIntegration } from '@sentry/core';\nimport type { NodeClient } from '../../sdk/client';\nimport { isDebuggerEnabled } from '../../utils/debug';\nimport type { FrameVariables, LocalVariablesIntegrationOptions, LocalVariablesWorkerArgs } from './common';\nimport { functionNamesMatch, LOCAL_VARIABLES_KEY } from './common';\n\n// This string is a placeholder that gets overwritten with the worker code.\nexport const base64WorkerScript = '###LocalVariablesWorkerScript###';\n\nfunction log(...args: unknown[]): void {\n  debug.log('[LocalVariables]', ...args);\n}\n\n/**\n * Adds local variables to exception frames\n */\nexport const localVariablesAsyncIntegration = defineIntegration(((\n  integrationOptions: LocalVariablesIntegrationOptions = {},\n) => {\n  function addLocalVariablesToException(exception: Exception, localVariables: FrameVariables[]): void {\n    // Filter out frames where the function name is `new Promise` since these are in the error.stack frames\n    // but do not appear in the debugger call frames\n    const frames = (exception.stacktrace?.frames || []).filter(frame => frame.function !== 'new Promise');\n\n    for (let i = 0; i < frames.length; i++) {\n      // Sentry frames are in reverse order\n      const frameIndex = frames.length - i - 1;\n\n      const frameLocalVariables = localVariables[i];\n      const frame = frames[frameIndex];\n\n      if (!frame || !frameLocalVariables) {\n        // Drop out if we run out of frames to match up\n        break;\n      }\n\n      if (\n        // We need to have vars to add\n        frameLocalVariables.vars === undefined ||\n        // Only skip out-of-app frames if includeOutOfAppFrames is not true\n        (frame.in_app === false && integrationOptions.includeOutOfAppFrames !== true) ||\n        // The function names need to match\n        !functionNamesMatch(frame.function, frameLocalVariables.function)\n      ) {\n        continue;\n      }\n\n      frame.vars = frameLocalVariables.vars;\n    }\n  }\n\n  function addLocalVariablesToEvent(event: Event, hint: EventHint): Event {\n    if (\n      hint.originalException &&\n      typeof hint.originalException === 'object' &&\n      LOCAL_VARIABLES_KEY in hint.originalException &&\n      Array.isArray(hint.originalException[LOCAL_VARIABLES_KEY])\n    ) {\n      for (const exception of event.exception?.values || []) {\n        addLocalVariablesToException(exception, hint.originalException[LOCAL_VARIABLES_KEY]);\n      }\n\n      hint.originalException[LOCAL_VARIABLES_KEY] = undefined;\n    }\n\n    return event;\n  }\n\n  async function startInspector(): Promise<void> {\n    // We load inspector dynamically because on some platforms Node is built without inspector support\n    const inspector = await import('node:inspector');\n    if (!inspector.url()) {\n      inspector.open(0);\n    }\n  }\n\n  function startWorker(options: LocalVariablesWorkerArgs): void {\n    const worker = new Worker(new URL(`data:application/javascript;base64,${base64WorkerScript}`), {\n      workerData: options,\n      // We don't want any Node args to be passed to the worker\n      execArgv: [],\n      env: { ...process.env, NODE_OPTIONS: undefined },\n    });\n\n    process.on('exit', () => {\n      // eslint-disable-next-line @typescript-eslint/no-floating-promises\n      worker.terminate();\n    });\n\n    worker.once('error', (err: Error) => {\n      log('Worker error', err);\n    });\n\n    worker.once('exit', (code: number) => {\n      log('Worker exit', code);\n    });\n\n    // Ensure this thread can't block app exit\n    worker.unref();\n  }\n\n  return {\n    name: 'LocalVariablesAsync',\n    async setup(client: NodeClient) {\n      const clientOptions = client.getOptions();\n\n      if (!clientOptions.includeLocalVariables) {\n        return;\n      }\n\n      if (await isDebuggerEnabled()) {\n        debug.warn('Local variables capture has been disabled because the debugger was already enabled');\n        return;\n      }\n\n      const options: LocalVariablesWorkerArgs = {\n        ...integrationOptions,\n        debug: debug.isEnabled(),\n      };\n\n      startInspector().then(\n        () => {\n          try {\n            startWorker(options);\n          } catch (e) {\n            debug.error('Failed to start worker', e);\n          }\n        },\n        e => {\n          debug.error('Failed to start inspector', e);\n        },\n      );\n    },\n    processEvent(event: Event, hint: EventHint): Event {\n      return addLocalVariablesToEvent(event, hint);\n    },\n  };\n}) satisfies IntegrationFn);\n"],"names":[],"mappings":";;;;;AAQA;AACO,MAAM,kBAAA,GAAqB;;AAElC,SAAS,GAAG,CAAC,GAAG,IAAI,EAAmB;AACvC,EAAE,KAAK,CAAC,GAAG,CAAC,kBAAkB,EAAE,GAAG,IAAI,CAAC;AACxC;;AAEA;AACA;AACA;AACO,MAAM,8BAAA,GAAiC,iBAAiB,EAAE;AACjE,EAAE,kBAAkB,GAAqC,EAAE;AAC3D,KAAK;AACL,EAAE,SAAS,4BAA4B,CAAC,SAAS,EAAa,cAAc,EAA0B;AACtG;AACA;AACA,IAAI,MAAM,SAAS,CAAC,SAAS,CAAC,UAAU,EAAE,MAAA,IAAU,EAAE,EAAE,MAAM,CAAC,KAAA,IAAS,KAAK,CAAC,QAAA,KAAa,aAAa,CAAC;;AAEzG,IAAI,KAAK,IAAI,CAAA,GAAI,CAAC,EAAE,CAAA,GAAI,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AAC5C;AACA,MAAM,MAAM,aAAa,MAAM,CAAC,MAAA,GAAS,CAAA,GAAI,CAAC;;AAE9C,MAAM,MAAM,mBAAA,GAAsB,cAAc,CAAC,CAAC,CAAC;AACnD,MAAM,MAAM,KAAA,GAAQ,MAAM,CAAC,UAAU,CAAC;;AAEtC,MAAM,IAAI,CAAC,SAAS,CAAC,mBAAmB,EAAE;AAC1C;AACA,QAAQ;AACR,MAAM;;AAEN,MAAM;AACN;AACA,QAAQ,mBAAmB,CAAC,IAAA,KAAS,SAAA;AACrC;AACA,SAAS,KAAK,CAAC,MAAA,KAAW,KAAA,IAAS,kBAAkB,CAAC,qBAAA,KAA0B,IAAI,CAAA;AACpF;AACA,QAAQ,CAAC,kBAAkB,CAAC,KAAK,CAAC,QAAQ,EAAE,mBAAmB,CAAC,QAAQ;AACxE,QAAQ;AACR,QAAQ;AACR,MAAM;;AAEN,MAAM,KAAK,CAAC,IAAA,GAAO,mBAAmB,CAAC,IAAI;AAC3C,IAAI;AACJ,EAAE;;AAEF,EAAE,SAAS,wBAAwB,CAAC,KAAK,EAAS,IAAI,EAAoB;AAC1E,IAAI;AACJ,MAAM,IAAI,CAAC,iBAAA;AACX,MAAM,OAAO,IAAI,CAAC,iBAAA,KAAsB,QAAA;AACxC,MAAM,mBAAA,IAAuB,IAAI,CAAC,iBAAA;AAClC,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,mBAAmB,CAAC;AAC/D,MAAM;AACN,MAAM,KAAK,MAAM,SAAA,IAAa,KAAK,CAAC,SAAS,EAAE,MAAA,IAAU,EAAE,EAAE;AAC7D,QAAQ,4BAA4B,CAAC,SAAS,EAAE,IAAI,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,CAAC;AAC5F,MAAM;;AAEN,MAAM,IAAI,CAAC,iBAAiB,CAAC,mBAAmB,CAAA,GAAI,SAAS;AAC7D,IAAI;;AAEJ,IAAI,OAAO,KAAK;AAChB,EAAE;;AAEF,EAAE,eAAe,cAAc,GAAkB;AACjD;AACA,IAAI,MAAM,SAAA,GAAY,MAAM,OAAO,gBAAgB,CAAC;AACpD,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE;AAC1B,MAAM,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;AACvB,IAAI;AACJ,EAAE;;AAEF,EAAE,SAAS,WAAW,CAAC,OAAO,EAAkC;AAChE,IAAI,MAAM,MAAA,GAAS,IAAI,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC,mCAAmC,EAAE,kBAAkB,CAAC,CAAA,CAAA,EAAA;AACA,MAAA,UAAA,EAAA,OAAA;AACA;AACA,MAAA,QAAA,EAAA,EAAA;AACA,MAAA,GAAA,EAAA,EAAA,GAAA,OAAA,CAAA,GAAA,EAAA,YAAA,EAAA,SAAA,EAAA;AACA,KAAA,CAAA;;AAEA,IAAA,OAAA,CAAA,EAAA,CAAA,MAAA,EAAA,MAAA;AACA;AACA,MAAA,MAAA,CAAA,SAAA,EAAA;AACA,IAAA,CAAA,CAAA;;AAEA,IAAA,MAAA,CAAA,IAAA,CAAA,OAAA,EAAA,CAAA,GAAA,KAAA;AACA,MAAA,GAAA,CAAA,cAAA,EAAA,GAAA,CAAA;AACA,IAAA,CAAA,CAAA;;AAEA,IAAA,MAAA,CAAA,IAAA,CAAA,MAAA,EAAA,CAAA,IAAA,KAAA;AACA,MAAA,GAAA,CAAA,aAAA,EAAA,IAAA,CAAA;AACA,IAAA,CAAA,CAAA;;AAEA;AACA,IAAA,MAAA,CAAA,KAAA,EAAA;AACA,EAAA;;AAEA,EAAA,OAAA;AACA,IAAA,IAAA,EAAA,qBAAA;AACA,IAAA,MAAA,KAAA,CAAA,MAAA,EAAA;AACA,MAAA,MAAA,aAAA,GAAA,MAAA,CAAA,UAAA,EAAA;;AAEA,MAAA,IAAA,CAAA,aAAA,CAAA,qBAAA,EAAA;AACA,QAAA;AACA,MAAA;;AAEA,MAAA,IAAA,MAAA,iBAAA,EAAA,EAAA;AACA,QAAA,KAAA,CAAA,IAAA,CAAA,oFAAA,CAAA;AACA,QAAA;AACA,MAAA;;AAEA,MAAA,MAAA,OAAA,GAAA;AACA,QAAA,GAAA,kBAAA;AACA,QAAA,KAAA,EAAA,KAAA,CAAA,SAAA,EAAA;AACA,OAAA;;AAEA,MAAA,cAAA,EAAA,CAAA,IAAA;AACA,QAAA,MAAA;AACA,UAAA,IAAA;AACA,YAAA,WAAA,CAAA,OAAA,CAAA;AACA,UAAA,CAAA,CAAA,OAAA,CAAA,EAAA;AACA,YAAA,KAAA,CAAA,KAAA,CAAA,wBAAA,EAAA,CAAA,CAAA;AACA,UAAA;AACA,QAAA,CAAA;AACA,QAAA,CAAA,IAAA;AACA,UAAA,KAAA,CAAA,KAAA,CAAA,2BAAA,EAAA,CAAA,CAAA;AACA,QAAA,CAAA;AACA,OAAA;AACA,IAAA,CAAA;AACA,IAAA,YAAA,CAAA,KAAA,EAAA,IAAA,EAAA;AACA,MAAA,OAAA,wBAAA,CAAA,KAAA,EAAA,IAAA,CAAA;AACA,IAAA,CAAA;AACA,GAAA;AACA,CAAA;;;;"}