Skip to content

Commit 36ddac0

Browse files
logaretmclaude
andcommitted
fix(nitro): Scope sourcemap deletion to output dir and log it
`filesToDeleteAfterUpload` previously defaulted to `['**/*.map']`, which is resolved from the project root and could traverse `node_modules`. Scope the default to `nitro.options.output.serverDir` so we only touch maps we generated. Also log the chosen glob in debug mode to match the Nuxt SDK UX. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 1c13825 commit 36ddac0

2 files changed

Lines changed: 41 additions & 2 deletions

File tree

packages/nitro/src/sourceMaps.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,18 +67,33 @@ function normalizePath(path: string): string {
6767
return path.replace(/^(\.\.\/)+/, './');
6868
}
6969

70+
/**
71+
* Removes a trailing slash from a path so glob patterns can be appended cleanly.
72+
*/
73+
function removeTrailingSlash(path: string): string {
74+
return path.replace(/\/$/, '');
75+
}
76+
7077
/**
7178
* Builds the plugin options for `createSentryBuildPluginManager` from the Sentry Nitro options.
7279
*
7380
* Only exported for testing purposes.
7481
*/
82+
// oxlint-disable-next-line complexity
7583
export function getPluginOptions(
7684
options?: SentryNitroOptions,
7785
sentryEnabledSourcemaps?: boolean,
7886
outputDir?: string,
7987
): BundlerPluginOptions {
8088
const defaultFilesToDelete =
81-
sentryEnabledSourcemaps && outputDir ? [`${outputDir.replace(/\\/g, '/')}/**/*.map`] : undefined;
89+
sentryEnabledSourcemaps && outputDir ? [`${removeTrailingSlash(outputDir)}/**/*.map`] : undefined;
90+
91+
if (options?.debug && defaultFilesToDelete && options?.sourcemaps?.filesToDeleteAfterUpload === undefined) {
92+
// eslint-disable-next-line no-console
93+
console.log(
94+
`[@sentry/nitro] Setting \`sourcemaps.filesToDeleteAfterUpload: ["${defaultFilesToDelete[0]}"]\` to delete generated source maps after they were uploaded to Sentry.`,
95+
);
96+
}
8297

8398
return {
8499
org: options?.org ?? process.env.SENTRY_ORG,

packages/nitro/test/sourceMaps.test.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,35 @@ describe('getPluginOptions', () => {
5151
});
5252

5353
it('respects user-provided filesToDeleteAfterUpload even when Sentry enabled sourcemaps', () => {
54-
const options = getPluginOptions({ sourcemaps: { filesToDeleteAfterUpload: ['dist/**/*.map'] } }, true);
54+
const options = getPluginOptions(
55+
{ sourcemaps: { filesToDeleteAfterUpload: ['dist/**/*.map'] } },
56+
true,
57+
'/project/.output/server',
58+
);
5559

5660
expect(options.sourcemaps?.filesToDeleteAfterUpload).toEqual(['dist/**/*.map']);
5761
});
5862

63+
it('logs the default filesToDeleteAfterUpload glob in debug mode', () => {
64+
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
65+
getPluginOptions({ debug: true }, true, '/project/.output/server');
66+
67+
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining('/project/.output/server/**/*.map'));
68+
logSpy.mockRestore();
69+
});
70+
71+
it('does not log the default glob when user provides filesToDeleteAfterUpload', () => {
72+
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
73+
getPluginOptions(
74+
{ debug: true, sourcemaps: { filesToDeleteAfterUpload: ['dist/**/*.map'] } },
75+
true,
76+
'/project/.output/server',
77+
);
78+
79+
expect(logSpy).not.toHaveBeenCalledWith(expect.stringContaining('filesToDeleteAfterUpload'));
80+
logSpy.mockRestore();
81+
});
82+
5983
it('uses environment variables as fallback', () => {
6084
process.env.SENTRY_ORG = 'env-org';
6185
process.env.SENTRY_PROJECT = 'env-project';

0 commit comments

Comments
 (0)