Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions packages/bundler-plugin-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,19 +224,29 @@ export function sentryUnpluginFactory({
plugins.push(releaseInjectionPlugin(injectionCode));
}

if (options.moduleMetadata) {
let metadata: Record<string, unknown>;
if (options.moduleMetadata || options.applicationKey) {
let metadata: Record<string, unknown> = {};

if (options.applicationKey) {
// We use different keys so that if code receives multiple bundling passes.
// It is a bit unfortunate that we have to inject the metadata snippet at the top, which means that if we didn't
// have this mechanism, the first bundling pass would always "win". If this weren't the case we would be fine with
// the last pass winning but the first pass winning is very bad, because it would prevent any sort of overriding.
// We can simply use the `_sentryBundlerPluginAppKey:` to filter for app keys in the SDK.
metadata[`_sentryBundlerPluginAppKey:${options.applicationKey}`] = true;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this is sus but I hope the comment makes sense

}

if (typeof options.moduleMetadata === "function") {
const args = {
org: options.org,
project: options.project,
release: options.release.name,
};
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
metadata = options.moduleMetadata(args);
metadata = { ...metadata, ...options.moduleMetadata(args) };
} else {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
metadata = options.moduleMetadata;
metadata = { ...metadata, ...options.moduleMetadata };
}

const injectionCode = generateModuleMetadataInjectorCode(metadata);
Expand Down
1 change: 1 addition & 0 deletions packages/bundler-plugin-core/src/options-mapping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export function normalizeUserOptions(userOptions: UserOptions) {
metaFramework: userOptions._metaOptions?.telemetry?.metaFramework,
},
},
applicationKey: userOptions.applicationKey,
moduleMetadata: userOptions.moduleMetadata || userOptions._experiments?.moduleMetadata,
_experiments: userOptions._experiments ?? {},
};
Expand Down
6 changes: 6 additions & 0 deletions packages/bundler-plugin-core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,12 @@ export interface Options {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
moduleMetadata?: ModuleMetadata | ModuleMetadataCallback;

/**
* A key which will embedded in all the bundled files. The SDK will be able to use the key to apply filtering
* rules, for example using the `thirdPartyErrorFilterIntegration`.
*/
applicationKey?: string;

/**
* Options that are considered experimental and subject to change.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Simply output the metadata to the console so it can be checked in a test
// eslint-disable-next-line no-console
console.log(JSON.stringify(global._sentryModuleMetadata));
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/* eslint-disable jest/no-standalone-expect */
/* eslint-disable jest/expect-expect */
import { execSync } from "child_process";
import path from "path";
import { testIfNodeMajorVersionIsLessThan18 } from "../../utils/testIf";

function checkBundle(bundlePath: string): void {
const output = execSync(`node ${bundlePath}`, { encoding: "utf-8" });

const map = JSON.parse(output) as Record<string, string>;

// There should be only one key in the map
expect(Object.values(map)).toHaveLength(1);
// The value should be the expected metadata
expect(Object.values(map)).toEqual([{ ["_sentryBundlerPluginAppKey:my-app"]: true }]);
}

describe("appKey injection", () => {
testIfNodeMajorVersionIsLessThan18("webpack 4 bundle", () => {
checkBundle(path.join(__dirname, "out", "webpack4", "bundle.js"));
});

test("webpack 5 bundle", () => {
checkBundle(path.join(__dirname, "out", "webpack5", "bundle.js"));
});

test("esbuild bundle", () => {
checkBundle(path.join(__dirname, "out", "esbuild", "bundle.js"));
});

test("rollup bundle", () => {
checkBundle(path.join(__dirname, "out", "rollup", "bundle.js"));
});

test("vite bundle", () => {
checkBundle(path.join(__dirname, "out", "vite", "bundle.js"));
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import * as path from "path";
import { createCjsBundles } from "../../utils/create-cjs-bundles";

const outputDir = path.resolve(__dirname, "out");

createCjsBundles(
{
bundle: path.resolve(__dirname, "input", "bundle.js"),
},
outputDir,
{
applicationKey: "my-app",
},
["webpack4", "webpack5", "esbuild", "rollup", "vite"]
);