import { basename } from 'node:path'; import { collectAgentCandidates, detectAgentClasses } from './agentClass.js'; import { resolveInstrumentFile, buildOptionsImport, ENV_FALLBACK_OPTIONS_FN } from './instrumentFile.js'; import { applyAutoInstrumentTransforms } from './transform.js'; import { resolveWranglerConfig } from './wranglerConfig.js'; function normalizePath(path) { return path.replace(/\\/g, "/"); } const JS_EXTENSION_REGEX = /\.[cm]?[jt]sx?$/; function sentryCloudflareAutoInstrumentPlugin(options = {}) { let wranglerConfig; let entryFilePath; let optionsFn = ENV_FALLBACK_OPTIONS_FN; let optionsImport; return { name: "sentry-cloudflare-auto-instrument", configResolved(config) { const result = resolveWranglerConfig(config.root, options.wranglerConfigPath); if (!result) { config.logger?.warn( options.wranglerConfigPath ? `[sentry] Could not find or parse the wrangler config "${basename(options.wranglerConfigPath)}" (resolved against the Vite root) \u2014 auto-instrumentation disabled.` : "[sentry] No parseable wrangler config found \u2014 auto-instrumentation disabled. Set `wranglerConfigPath` if your config uses a custom name." ); return; } wranglerConfig = result.config; if (wranglerConfig.main) { entryFilePath = normalizePath(wranglerConfig.main); } if (entryFilePath) { const instrumentFilePath = resolveInstrumentFile(entryFilePath); if (instrumentFilePath) { const built = buildOptionsImport(entryFilePath, instrumentFilePath); optionsFn = built.optionsFn; optionsImport = built.importStmt; } } }, async transform(code, id) { if (!wranglerConfig || !entryFilePath) return void 0; if (this.environment?.name === "client") return void 0; const normalizedId = normalizePath(id.replace(/[?#].*$/, "")); if (normalizedId !== entryFilePath) { if (!JS_EXTENSION_REGEX.test(normalizedId) || !JS_EXTENSION_REGEX.test(entryFilePath)) return void 0; if (normalizedId.replace(JS_EXTENSION_REGEX, "") !== entryFilePath.replace(JS_EXTENSION_REGEX, "")) { return void 0; } } let ast; try { ast = this.parse(code); } catch { return void 0; } const classWrappers = /* @__PURE__ */ new Map(); for (const { className } of wranglerConfig.durableObjects) { classWrappers.set(className, "durableObject"); } for (const { className } of wranglerConfig.workflows) { classWrappers.set(className, "workflow"); } for (const className of wranglerConfig.workerEntrypoints) { classWrappers.set(className, "workerEntrypoint"); } const agentCandidates = collectAgentCandidates( ast, [...classWrappers].filter(([, kind]) => kind === "durableObject").map(([name]) => name) ); const agentClasses = agentCandidates.size > 0 ? await detectAgentClasses(ast, normalizedId, agentCandidates, { parse: (code2) => this.parse(code2), resolve: this.resolve ? (source, importer) => this.resolve(source, importer) : void 0 }) : void 0; const result = applyAutoInstrumentTransforms(code, ast, { classWrappers, agentClasses, optionsFn, optionsImport, sameWorkerBindings: wranglerConfig.sameWorkerBindings }); const wrappedClasses = result?.wrappedClasses ?? /* @__PURE__ */ new Set(); const missing = [...classWrappers.keys()].filter((name) => !wrappedClasses.has(name)); if (missing.length > 0) { this.warn?.( `[sentry] Could not auto-instrument ${missing.join(", ")}.The worker entry has no export matching them. Star re-exports (\`export * from "./do"\`) are not matched. Export them by name or wrap them manually with corresponding \`instrument*WithSentry\` helpers.` ); } return result ?? void 0; } }; } export { sentryCloudflareAutoInstrumentPlugin }; //# sourceMappingURL=autoInstrument.js.map