From bae2d1192948e195b273dbca8f059047f57c35e2 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Tue, 18 Feb 2025 14:25:17 +0100 Subject: [PATCH 1/3] feat(core): Accept and await a promise in `sourcemaps.filesToDeleteAfterUpload` --- .../src/plugins/sourcemap-deletion.ts | 6 +++-- packages/bundler-plugin-core/src/types.ts | 6 ++++- .../after-upload-deletion.test.ts | 27 +++++++++++++++++++ .../input/bundle.js | 2 ++ .../after-upload-deletion-promise/setup.ts | 25 +++++++++++++++++ 5 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 packages/integration-tests/fixtures/after-upload-deletion-promise/after-upload-deletion.test.ts create mode 100644 packages/integration-tests/fixtures/after-upload-deletion-promise/input/bundle.js create mode 100644 packages/integration-tests/fixtures/after-upload-deletion-promise/setup.ts diff --git a/packages/bundler-plugin-core/src/plugins/sourcemap-deletion.ts b/packages/bundler-plugin-core/src/plugins/sourcemap-deletion.ts index f1418896..4b44c092 100644 --- a/packages/bundler-plugin-core/src/plugins/sourcemap-deletion.ts +++ b/packages/bundler-plugin-core/src/plugins/sourcemap-deletion.ts @@ -11,7 +11,7 @@ interface FileDeletionPlugin { waitUntilSourcemapFileDependenciesAreFreed: () => Promise; sentryScope: Scope; sentryClient: Client; - filesToDeleteAfterUpload: string | string[] | undefined; + filesToDeleteAfterUpload: string | string[] | Promise | undefined; logger: Logger; } @@ -28,7 +28,9 @@ export function fileDeletionPlugin({ async writeBundle() { try { if (filesToDeleteAfterUpload !== undefined) { - const filePathsToDelete = await glob(filesToDeleteAfterUpload, { + const filesToDelete = await filesToDeleteAfterUpload; + + const filePathsToDelete = await glob(filesToDelete, { absolute: true, nodir: true, }); diff --git a/packages/bundler-plugin-core/src/types.ts b/packages/bundler-plugin-core/src/types.ts index d23cb480..dad516f8 100644 --- a/packages/bundler-plugin-core/src/types.ts +++ b/packages/bundler-plugin-core/src/types.ts @@ -132,9 +132,13 @@ export interface Options { * * The globbing patterns follow the implementation of the `glob` package. (https://www.npmjs.com/package/glob) * + * Note: If you pass in a promise that resolves to a string or array, the plugin will await the promise and use + * the resolved value globs. This is useful if you need to dynamically determine the files to delete. Some + * higher-level Sentry SDKs or options use this feature (e.g. SvelteKit). + * * Use the `debug` option to print information about which files end up being deleted. */ - filesToDeleteAfterUpload?: string | string[]; + filesToDeleteAfterUpload?: string | string[] | Promise; }; /** diff --git a/packages/integration-tests/fixtures/after-upload-deletion-promise/after-upload-deletion.test.ts b/packages/integration-tests/fixtures/after-upload-deletion-promise/after-upload-deletion.test.ts new file mode 100644 index 00000000..0930d474 --- /dev/null +++ b/packages/integration-tests/fixtures/after-upload-deletion-promise/after-upload-deletion.test.ts @@ -0,0 +1,27 @@ +/* eslint-disable jest/no-standalone-expect */ +/* eslint-disable jest/expect-expect */ +import path from "path"; +import fs from "fs"; +import { testIfNodeMajorVersionIsLessThan18 } from "../../utils/testIf"; + +describe("Deletes files with `filesToDeleteAfterUpload` set to a promise", () => { + testIfNodeMajorVersionIsLessThan18("webpack 4 bundle", () => { + expect(fs.existsSync(path.join(__dirname, "out", "webpack4", "bundle.js.map"))).toBe(false); + }); + + test("webpack 5 bundle", () => { + expect(fs.existsSync(path.join(__dirname, "out", "webpack5", "bundle.js.map"))).toBe(false); + }); + + test("esbuild bundle", () => { + expect(fs.existsSync(path.join(__dirname, "out", "esbuild", "bundle.js.map"))).toBe(false); + }); + + test("rollup bundle", () => { + expect(fs.existsSync(path.join(__dirname, "out", "rollup", "bundle.js.map"))).toBe(false); + }); + + test("vite bundle", () => { + expect(fs.existsSync(path.join(__dirname, "out", "vite", "bundle.js.map"))).toBe(false); + }); +}); diff --git a/packages/integration-tests/fixtures/after-upload-deletion-promise/input/bundle.js b/packages/integration-tests/fixtures/after-upload-deletion-promise/input/bundle.js new file mode 100644 index 00000000..aa70f660 --- /dev/null +++ b/packages/integration-tests/fixtures/after-upload-deletion-promise/input/bundle.js @@ -0,0 +1,2 @@ +// eslint-disable-next-line no-console +console.log("whatever"); diff --git a/packages/integration-tests/fixtures/after-upload-deletion-promise/setup.ts b/packages/integration-tests/fixtures/after-upload-deletion-promise/setup.ts new file mode 100644 index 00000000..140a11cb --- /dev/null +++ b/packages/integration-tests/fixtures/after-upload-deletion-promise/setup.ts @@ -0,0 +1,25 @@ +import * as path from "path"; +import { createCjsBundles } from "../../utils/create-cjs-bundles"; + +const outputDir = path.resolve(__dirname, "out"); + +["webpack4", "webpack5", "esbuild", "rollup", "vite"].forEach((bundler) => { + const fileDeletionGlobPromise = new Promise((resolve) => { + setTimeout(() => { + resolve([path.join(__dirname, "out", bundler, "bundle.js.map")]); + }, 1000); + }); + + createCjsBundles( + { + bundle: path.resolve(__dirname, "input", "bundle.js"), + }, + outputDir, + { + sourcemaps: { + filesToDeleteAfterUpload: fileDeletionGlobPromise, + }, + }, + [bundler] + ); +}); From b1ccc0ce092d6eea4d779ae47ec5fbb68424bde8 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Tue, 18 Feb 2025 14:27:19 +0100 Subject: [PATCH 2/3] update readme --- packages/dev-utils/src/generate-documentation-table.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/dev-utils/src/generate-documentation-table.ts b/packages/dev-utils/src/generate-documentation-table.ts index bd56e487..1d2f3244 100644 --- a/packages/dev-utils/src/generate-documentation-table.ts +++ b/packages/dev-utils/src/generate-documentation-table.ts @@ -98,9 +98,9 @@ errorHandler: (err) => { }, { name: "filesToDeleteAfterUpload", - type: "string | string[]", + type: "string | string[] | Promise", fullDescription: - "A glob or an array of globs that specifies the build artifacts that should be deleted after the artifact upload to Sentry has been completed.\n\nThe globbing patterns follow the implementation of the `glob` package. (https://www.npmjs.com/package/glob)\n\nUse the `debug` option to print information about which files end up being deleted.", + "A glob, an array of globs or a promise resolving a glob or array of globs that specifies the build artifacts that should be deleted after the artifact upload to Sentry has been completed.\n\nThe globbing patterns follow the implementation of the `glob` package. (https://www.npmjs.com/package/glob)\n\nUse the `debug` option to print information about which files end up being deleted.", }, { name: "disable", From 731fe668e068ce59c302d917b312af5c04caaa59 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Tue, 18 Feb 2025 15:33:11 +0100 Subject: [PATCH 3/3] allow to resolve promise to undefined --- .../bundler-plugin-core/src/plugins/sourcemap-deletion.ts | 7 +++---- packages/bundler-plugin-core/src/types.ts | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/bundler-plugin-core/src/plugins/sourcemap-deletion.ts b/packages/bundler-plugin-core/src/plugins/sourcemap-deletion.ts index 4b44c092..334282ea 100644 --- a/packages/bundler-plugin-core/src/plugins/sourcemap-deletion.ts +++ b/packages/bundler-plugin-core/src/plugins/sourcemap-deletion.ts @@ -11,7 +11,7 @@ interface FileDeletionPlugin { waitUntilSourcemapFileDependenciesAreFreed: () => Promise; sentryScope: Scope; sentryClient: Client; - filesToDeleteAfterUpload: string | string[] | Promise | undefined; + filesToDeleteAfterUpload: string | string[] | Promise | undefined; logger: Logger; } @@ -27,9 +27,8 @@ export function fileDeletionPlugin({ name: "sentry-file-deletion-plugin", async writeBundle() { try { - if (filesToDeleteAfterUpload !== undefined) { - const filesToDelete = await filesToDeleteAfterUpload; - + const filesToDelete = await filesToDeleteAfterUpload; + if (filesToDelete !== undefined) { const filePathsToDelete = await glob(filesToDelete, { absolute: true, nodir: true, diff --git a/packages/bundler-plugin-core/src/types.ts b/packages/bundler-plugin-core/src/types.ts index dad516f8..e6153fff 100644 --- a/packages/bundler-plugin-core/src/types.ts +++ b/packages/bundler-plugin-core/src/types.ts @@ -138,7 +138,7 @@ export interface Options { * * Use the `debug` option to print information about which files end up being deleted. */ - filesToDeleteAfterUpload?: string | string[] | Promise; + filesToDeleteAfterUpload?: string | string[] | Promise; }; /**