UNPKG

@sentry/remix

Version:
157 lines (153 loc) • 6.06 kB
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); const diagnosticsChannel = require('node:diagnostics_channel'); const core = require('@sentry/core'); const config = require('@sentry/server-utils/orchestrion/config'); const debugId = require('./debugId.js'); const orchestrionLoader = require('./orchestrionLoader.js'); const SOURCE_MAPPING_URL_REGEX = /\n\/\/# sourceMappingURL=\S+\s*$/; const MAX_STAMPED_BODIES = 2e3; const SDK_PACKAGE = "@sentry/remix"; let instrumented = false; function instrumentAssetServer() { if (instrumented) { return; } instrumented = true; diagnosticsChannel.tracingChannel(config.remixV3Channels.REMIX_V3_CREATE_ASSET_SERVER).subscribe({ start(data) { try { const context = data; const options = context.arguments[0]; context._sentryHideSourceMaps = options?.sourceMaps === void 0; context.arguments[0] = withDebugIdOptions(options); } catch { } }, end(data) { try { const { result, _sentryHideSourceMaps } = data; if (result) { stampServedAssets(result, { hideSourceMaps: Boolean(_sentryHideSourceMaps) }); } } catch { } }, asyncStart() { }, asyncEnd() { }, error() { } }); } const debugIdLoader = (url, context, nextLoad) => { const result = nextLoad(url, context); if (result.format !== "module" || typeof result.source !== "string") { return result; } const debugId$1 = debugId.getDebugId(`${context.moduleUrl ?? url} ${result.source}`); return { ...result, source: debugId.injectDebugIdSnippet(result.source, debugId$1) }; }; function withDebugIdOptions(options) { if (!options) { return options; } if (options.sourceMaps === false) { core.consoleSandbox(() => { console.warn( "[Sentry] Source maps are disabled in your asset server (`sourceMaps: false`). Sentry will not override this, so client stack traces stay minified." ); }); } const servesPackages = (options.allowPackages?.length ?? 0) > 0; const allowPackages = servesPackages && !options.allowPackages?.includes(SDK_PACKAGE) ? [...options.allowPackages ?? [], SDK_PACKAGE] : options.allowPackages; const shimUrl = servesPackages ? orchestrionLoader.getShimUrl(options.basePath ?? "/", options.rootDir ?? process.cwd(), options.mounts, orchestrionLoader.resolveShimPath()) : void 0; if (servesPackages && shimUrl === void 0) { core.consoleSandbox(() => { console.warn( "[Sentry] The browser channel shim is outside the asset server's node_modules mount, so browser modules are served without instrumentation. Component render errors need `captureRuntimeErrors(app)`." ); }); } const loaders = (options.scripts?.loaders ?? []).filter( (loader) => loader !== debugIdLoader && !orchestrionLoader.isOrchestrionLoader(loader) ); const external = (options.scripts?.external ?? []).filter((entry) => entry !== shimUrl); return { ...options, ...allowPackages !== options.allowPackages && { allowPackages }, // Hidden unless the app chose otherwise, see `stampServedAssets`. sourceMaps: options.sourceMaps ?? "external", scripts: { ...options.scripts, // The transform first, the debug ID last, so the ID covers the transformed module. loaders: shimUrl === void 0 ? [...loaders, debugIdLoader] : [...loaders, orchestrionLoader.orchestrionLoader(shimUrl), debugIdLoader], // Kept as a URL by the compiler. A bare specifier would not resolve from inside an instrumented // package under pnpm. external: shimUrl === void 0 ? external : [shimUrl, ...external] } }; } const UNSTAMPED_FETCH = /* @__PURE__ */ Symbol.for("sentry.remix.unstampedFetch"); function stampServedAssets(server, { hideSourceMaps }) { const fetchAsset = server.fetch; server[UNSTAMPED_FETCH] = fetchAsset; const stamped = /* @__PURE__ */ new Map(); server.fetch = async (request) => { const response = await fetchAsset(request); if (response?.status !== 200 || request.method !== "GET") { return response; } const url = new URL(request.url); const contentType = response.headers.get("content-type") ?? ""; const etag = response.headers.get("etag"); if (contentType.includes("javascript")) { return withBody(response, await remember(etag, async () => stampModule(await response.text()))); } if (url.pathname.endsWith(".map")) { if (hideSourceMaps) { return null; } const body = await remember(etag, async () => { url.pathname = url.pathname.slice(0, -".map".length); const moduleResponse = await fetchAsset(new Request(url)); const debugId$1 = moduleResponse?.ok ? debugId.findDebugId(await moduleResponse.text()) : void 0; const map = await response.text(); return debugId$1 ? debugId.addDebugIdToSourceMap(map, debugId$1) : map; }); return withBody(response, body); } return response; }; function stampModule(served) { const code = hideSourceMaps ? served.replace(SOURCE_MAPPING_URL_REGEX, "") : served; const debugId$1 = debugId.findDebugId(code); return debugId$1 ? `${code} //# debugId=${debugId$1}` : code; } async function remember(etag, compute) { if (etag === null) { return compute(); } const cached = stamped.get(etag); if (cached !== void 0) { return cached; } const body = await compute(); if (stamped.size >= MAX_STAMPED_BODIES) { stamped.delete(stamped.keys().next().value); } stamped.set(etag, body); return body; } } function withBody(response, body) { const headers = new Headers(response.headers); headers.delete("content-length"); return new Response(body, { status: response.status, statusText: response.statusText, headers }); } exports.UNSTAMPED_FETCH = UNSTAMPED_FETCH; exports.debugIdLoader = debugIdLoader; exports.instrumentAssetServer = instrumentAssetServer; //# sourceMappingURL=assetServer.js.map