From 16a02d8e2e8f1d67197fe416c7e4207738324978 Mon Sep 17 00:00:00 2001 From: Charly Gomez Date: Thu, 2 Apr 2026 11:15:01 +0200 Subject: [PATCH 1/3] pass `mapDir` to `rewriteSourcesHook` --- .../src/debug-id-upload.ts | 5 +- packages/bundler-plugin-core/src/types.ts | 5 +- .../test/debug-id-upload.test.ts | 70 +++++++++++++++++++ .../src/generate-documentation-table.ts | 4 +- 4 files changed, 80 insertions(+), 4 deletions(-) create mode 100644 packages/bundler-plugin-core/test/debug-id-upload.test.ts diff --git a/packages/bundler-plugin-core/src/debug-id-upload.ts b/packages/bundler-plugin-core/src/debug-id-upload.ts index 4de1aaa6..b2bf8663 100644 --- a/packages/bundler-plugin-core/src/debug-id-upload.ts +++ b/packages/bundler-plugin-core/src/debug-id-upload.ts @@ -219,7 +219,10 @@ async function prepareSourceMapForDebugIdUpload( } if (map["sources"] && Array.isArray(map["sources"])) { - map["sources"] = map["sources"].map((source: string) => rewriteSourcesHook(source, map)); + const mapDir = path.dirname(sourceMapPath); + map["sources"] = map["sources"].map((source: string) => + rewriteSourcesHook(source, map, { mapDir }) + ); } try { diff --git a/packages/bundler-plugin-core/src/types.ts b/packages/bundler-plugin-core/src/types.ts index 1c00c94a..2d197e3b 100644 --- a/packages/bundler-plugin-core/src/types.ts +++ b/packages/bundler-plugin-core/src/types.ts @@ -138,6 +138,9 @@ export interface Options { /** * Hook to rewrite the `sources` field inside the source map before being uploaded to Sentry. Does not modify the actual source map. * + * The hook receives the source path, the parsed source map object, and a context object containing `mapDir` - + * the directory of the source map file, useful for resolving relative source paths. + * * Defaults to making all sources relative to `process.cwd()` while building. */ rewriteSources?: RewriteSourcesHook; @@ -427,7 +430,7 @@ export interface Options { } // eslint-disable-next-line @typescript-eslint/no-explicit-any -export type RewriteSourcesHook = (source: string, map: any) => string; +export type RewriteSourcesHook = (source: string, map: any, context?: { mapDir: string }) => string; export type ResolveSourceMapHook = ( artifactPath: string, diff --git a/packages/bundler-plugin-core/test/debug-id-upload.test.ts b/packages/bundler-plugin-core/test/debug-id-upload.test.ts new file mode 100644 index 00000000..90e8792a --- /dev/null +++ b/packages/bundler-plugin-core/test/debug-id-upload.test.ts @@ -0,0 +1,70 @@ +import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; +import * as fs from "fs"; +import * as path from "path"; +import * as os from "os"; +import { prepareBundleForDebugIdUpload } from "../src/debug-id-upload"; +import type { RewriteSourcesHook } from "../src/types"; + +describe("prepareBundleForDebugIdUpload", () => { + let tmpDir: string; + + beforeEach(() => { + tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "sentry-test-")); + }); + + afterEach(() => { + fs.rmSync(tmpDir, { recursive: true, force: true }); + }); + + it("passes mapDir context to rewriteSources hook", async () => { + const bundleDir = path.join(tmpDir, "src"); + const uploadDir = path.join(tmpDir, "upload"); + fs.mkdirSync(bundleDir, { recursive: true }); + fs.mkdirSync(uploadDir, { recursive: true }); + + const debugId = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"; + const bundlePath = path.join(bundleDir, "bundle.js"); + const mapPath = path.join(bundleDir, "bundle.js.map"); + + // Bundle with debug ID snippet and sourceMappingURL + fs.writeFileSync( + bundlePath, + `"use strict";\n// some code\n;!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="${debugId}",e._sentryDebugIdIdentifier="sentry-dbid-${debugId}")}catch(e){}}();\n//# sourceMappingURL=bundle.js.map` + ); + + // Source map file + fs.writeFileSync( + mapPath, + JSON.stringify({ + version: 3, + sources: ["../original/file.ts"], + mappings: "AAAA", + }) + ); + + const capturedContexts: Array<{ mapDir: string }> = []; + const rewriteHook: RewriteSourcesHook = (source, _map, context) => { + capturedContexts.push(context); + return source; + }; + + const logger = { + info: vi.fn(), + warn: vi.fn(), + error: vi.fn(), + debug: vi.fn(), + }; + + await prepareBundleForDebugIdUpload( + bundlePath, + uploadDir, + 0, + logger as any, + rewriteHook, + undefined + ); + + expect(capturedContexts).toHaveLength(1); + expect(capturedContexts[0]!.mapDir).toBe(bundleDir); + }); +}); diff --git a/packages/dev-utils/src/generate-documentation-table.ts b/packages/dev-utils/src/generate-documentation-table.ts index 4c0bf776..c7c5f777 100644 --- a/packages/dev-utils/src/generate-documentation-table.ts +++ b/packages/dev-utils/src/generate-documentation-table.ts @@ -95,9 +95,9 @@ errorHandler: (err) => { }, { name: "rewriteSources", - type: "(source: string, map: any) => string", + type: "(source: string, map: any, context?: { mapDir: string }) => string", fullDescription: - "Hook to rewrite the `sources` field inside the source map before being uploaded to Sentry. Does not modify the actual source map. Effectively, this modifies how files inside the stacktrace will show up in Sentry.\n\nDefaults to making all sources relative to `process.cwd()` while building.", + "Hook to rewrite the `sources` field inside the source map before being uploaded to Sentry. Does not modify the actual source map. Effectively, this modifies how files inside the stacktrace will show up in Sentry.\n\nThe `context.mapDir` parameter provides the directory path of the source map file, which is useful for resolving relative source paths (e.g. `path.resolve(context.mapDir, source)`).\n\nDefaults to making all sources relative to `process.cwd()` while building.", }, { name: "resolveSourceMap", From 0e808b73813948dd0d7016961131773be74ae61a Mon Sep 17 00:00:00 2001 From: Charly Gomez Date: Thu, 2 Apr 2026 13:41:52 +0200 Subject: [PATCH 2/3] lint --- packages/bundler-plugin-core/test/debug-id-upload.test.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/bundler-plugin-core/test/debug-id-upload.test.ts b/packages/bundler-plugin-core/test/debug-id-upload.test.ts index 90e8792a..4b70ecf8 100644 --- a/packages/bundler-plugin-core/test/debug-id-upload.test.ts +++ b/packages/bundler-plugin-core/test/debug-id-upload.test.ts @@ -4,6 +4,7 @@ import * as path from "path"; import * as os from "os"; import { prepareBundleForDebugIdUpload } from "../src/debug-id-upload"; import type { RewriteSourcesHook } from "../src/types"; +import { Logger } from "../src"; describe("prepareBundleForDebugIdUpload", () => { let tmpDir: string; @@ -42,7 +43,7 @@ describe("prepareBundleForDebugIdUpload", () => { }) ); - const capturedContexts: Array<{ mapDir: string }> = []; + const capturedContexts: Array<{ mapDir?: string } | undefined> = []; const rewriteHook: RewriteSourcesHook = (source, _map, context) => { capturedContexts.push(context); return source; @@ -53,13 +54,13 @@ describe("prepareBundleForDebugIdUpload", () => { warn: vi.fn(), error: vi.fn(), debug: vi.fn(), - }; + }; await prepareBundleForDebugIdUpload( bundlePath, uploadDir, 0, - logger as any, + logger as Logger, rewriteHook, undefined ); From 86b0b66a5c13e62afad0fc51a3f1d1c3192ab2b3 Mon Sep 17 00:00:00 2001 From: Charly Gomez Date: Thu, 2 Apr 2026 13:47:59 +0200 Subject: [PATCH 3/3] . --- packages/bundler-plugin-core/test/debug-id-upload.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bundler-plugin-core/test/debug-id-upload.test.ts b/packages/bundler-plugin-core/test/debug-id-upload.test.ts index 4b70ecf8..bbcc8621 100644 --- a/packages/bundler-plugin-core/test/debug-id-upload.test.ts +++ b/packages/bundler-plugin-core/test/debug-id-upload.test.ts @@ -54,7 +54,7 @@ describe("prepareBundleForDebugIdUpload", () => { warn: vi.fn(), error: vi.fn(), debug: vi.fn(), - }; + }; await prepareBundleForDebugIdUpload( bundlePath,