Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
10 changes: 5 additions & 5 deletions packages/babel-plugin-component-annotate/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ function functionBodyPushAttributes(
sourceFileName: string | undefined,
attributeNames: string[],
ignoredComponents: string[]
) {
): void {
let jsxNode: Babel.NodePath;

const functionBody = path.get("body").get("body");
Expand Down Expand Up @@ -248,7 +248,7 @@ function processJSX(
sourceFileName: string | undefined,
attributeNames: string[],
ignoredComponents: string[]
) {
): void {
if (!jsxNode) {
return;
}
Expand Down Expand Up @@ -323,7 +323,7 @@ function applyAttributes(
sourceFileName: string | undefined,
attributeNames: string[],
ignoredComponents: string[]
) {
): void {
const [componentAttributeName, elementAttributeName, sourceFileAttributeName] = attributeNames;

if (isReactFragment(t, openingElement)) {
Expand Down Expand Up @@ -390,7 +390,7 @@ function applyAttributes(
}
}

function sourceFileNameFromState(state: AnnotationPluginPass) {
function sourceFileNameFromState(state: AnnotationPluginPass): string | undefined {
const name = fullSourceFileNameFromState(state);
if (!name) {
return undefined;
Expand All @@ -416,7 +416,7 @@ function fullSourceFileNameFromState(state: AnnotationPluginPass): string | null
return null;
}

function isKnownIncompatiblePluginFromState(state: AnnotationPluginPass) {
function isKnownIncompatiblePluginFromState(state: AnnotationPluginPass): boolean {
const fullSourceFileName = fullSourceFileNameFromState(state);

if (!fullSourceFileName) {
Expand Down
12 changes: 6 additions & 6 deletions packages/bundler-plugin-core/src/build-plugin-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ export function createSentryBuildPluginManager(

let sessionHasEnded = false; // Just to prevent infinite loops with beforeExit, which is called whenever the event loop empties out

function endSession() {
function endSession(): void {
if (sessionHasEnded) {
return;
}
Expand Down Expand Up @@ -206,7 +206,7 @@ export function createSentryBuildPluginManager(
* or continue up to them. By default, @param throwByDefault controls if the plugin
* should throw an error (which causes a build fail in most bundlers) or continue.
*/
function handleRecoverableError(unknownError: unknown, throwByDefault: boolean) {
function handleRecoverableError(unknownError: unknown, throwByDefault: boolean): void {
sentrySession.status = "abnormal";
try {
if (options.errorHandler) {
Expand Down Expand Up @@ -251,13 +251,13 @@ export function createSentryBuildPluginManager(
const dependenciesOnBuildArtifacts = new Set<symbol>();
const buildArtifactsDependencySubscribers: (() => void)[] = [];

function notifyBuildArtifactDependencySubscribers() {
function notifyBuildArtifactDependencySubscribers(): void {
buildArtifactsDependencySubscribers.forEach((subscriber) => {
subscriber();
});
}

function createDependencyOnBuildArtifacts() {
function createDependencyOnBuildArtifacts(): () => void {
const dependencyIdentifier = Symbol();
dependenciesOnBuildArtifacts.add(dependencyIdentifier);

Expand All @@ -273,7 +273,7 @@ export function createSentryBuildPluginManager(
* It is very important that this function is called as late as possible before wanting to await the Promise to give
* the dependency producers as much time as possible to register themselves.
*/
function waitUntilBuildArtifactDependenciesAreFreed() {
function waitUntilBuildArtifactDependenciesAreFreed(): Promise<void> {
return new Promise<void>((resolve) => {
buildArtifactsDependencySubscribers.push(() => {
if (dependenciesOnBuildArtifacts.size === 0) {
Expand Down Expand Up @@ -607,7 +607,7 @@ export function createSentryBuildPluginManager(
}
);
const workers: Promise<void>[] = [];
const worker = async () => {
const worker = async (): Promise<void> => {
while (preparationTasks.length > 0) {
const task = preparationTasks.shift();
if (task) {
Expand Down
2 changes: 1 addition & 1 deletion packages/bundler-plugin-core/src/debug-id-upload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export async function prepareBundleForDebugIdUpload(
logger: Logger,
rewriteSourcesHook: RewriteSourcesHook,
resolveSourceMapHook: ResolveSourceMapHook | undefined
) {
): Promise<void> {
let bundleContent;
try {
bundleContent = await promisify(fs.readFile)(bundleFilePath, "utf8");
Expand Down
73 changes: 46 additions & 27 deletions packages/bundler-plugin-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,17 @@ import SentryCli from "@sentry/cli";
import { logger } from "@sentry/utils";
import * as fs from "fs";
import { glob } from "glob";
import MagicString from "magic-string";
import MagicString, { SourceMap } from "magic-string";
import * as path from "path";
import { createUnplugin, TransformResult, UnpluginOptions } from "unplugin";
import { createUnplugin, TransformResult, UnpluginInstance, UnpluginOptions } from "unplugin";
import { createSentryBuildPluginManager } from "./build-plugin-manager";
import { createDebugIdUploadFunction } from "./debug-id-upload";
import { Logger } from "./logger";
import { Options, SentrySDKBuildFlags } from "./types";
import {
generateGlobalInjectorCode,
generateModuleMetadataInjectorCode,
getDependencies,
getPackageJson,
parseMajorVersion,
getBuildInformation as actualGetBuildInformation,
replaceBooleanFlagsInCode,
stringToUUID,
stripQueryAndHashFromPath,
Expand Down Expand Up @@ -46,7 +44,7 @@ export function sentryUnpluginFactory({
debugIdInjectionPlugin,
debugIdUploadPlugin,
bundleSizeOptimizationsPlugin,
}: SentryUnpluginFactoryOptions) {
}: SentryUnpluginFactoryOptions): UnpluginInstance<Options | undefined, true> {
return createUnplugin<Options | undefined, true>((userOptions = {}, unpluginMetaContext) => {
const sentryBuildPluginManager = createSentryBuildPluginManager(userOptions, {
loggerPrefix:
Expand Down Expand Up @@ -177,22 +175,11 @@ export function sentryUnpluginFactory({
}

/**
* @deprecated
* @deprecated This will be removed in v4
*/
// TODO(v4): Don't export this from the package
export function getBuildInformation() {
const packageJson = getPackageJson();

const { deps, depsVersions } = packageJson
? getDependencies(packageJson)
: { deps: [], depsVersions: {} };

return {
deps,
depsVersions,
nodeVersion: parseMajorVersion(process.version),
};
}
// TODO(v4): Don't export this from the package but keep the utils version
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
export const getBuildInformation = actualGetBuildInformation;
Copy link
Member Author

Choose a reason for hiding this comment

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

We had 1:1 the same implementation in the actualGetBuildInformation util function, so I just removed the duplication (but kept the top level export deprecated).


/**
* Determines whether the Sentry CLI binary is in its expected location.
Expand All @@ -203,7 +190,11 @@ export function sentryCliBinaryExists(): boolean {
return fs.existsSync(SentryCli.getPath());
}

export function createRollupReleaseInjectionHooks(injectionCode: string) {
export function createRollupReleaseInjectionHooks(injectionCode: string): {
resolveId: UnpluginOptions["resolveId"];
load: UnpluginOptions["load"];
transform: UnpluginOptions["transform"];
} {
const virtualReleaseInjectionFileId = "\0sentry-release-injection-file";
return {
resolveId(id: string) {
Expand Down Expand Up @@ -260,7 +251,9 @@ export function createRollupReleaseInjectionHooks(injectionCode: string) {
};
}

export function createRollupBundleSizeOptimizationHooks(replacementValues: SentrySDKBuildFlags) {
export function createRollupBundleSizeOptimizationHooks(replacementValues: SentrySDKBuildFlags): {
transform: UnpluginOptions["transform"];
} {
return {
transform(code: string) {
return replaceBooleanFlagsInCode(code, replacementValues);
Expand All @@ -274,7 +267,24 @@ const COMMENT_USE_STRICT_REGEX =
// Note: CodeQL complains that this regex potentially has n^2 runtime. This likely won't affect realistic files.
/^(?:\s*|\/\*(?:.|\r|\n)*?\*\/|\/\/.*[\n\r])*(?:"[^"]*";|'[^']*';)?/;

export function createRollupDebugIdInjectionHooks() {
/**
* Simplified `renderChunk` hook type from Rollup.
* We can't reference the type directly because the Vite plugin complains
* about type mismatches
*/
type RenderChunkHook = (
code: string,
chunk: {
fileName: string;
}
) => {
code: string;
map: SourceMap;
} | null;

export function createRollupDebugIdInjectionHooks(): {
renderChunk: RenderChunkHook;
} {
Comment on lines +270 to +287
Copy link
Member Author

Choose a reason for hiding this comment

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

the comment explains this but maybe just to add: I can't use UnpluginOptions["renderChunk"]; because renderChunk is not a hook known to Unplugin. We manually pass in this hook in a plugin specifically for Rollup and Vite.

return {
renderChunk(code: string, chunk: { fileName: string }) {
if (
Expand Down Expand Up @@ -311,7 +321,9 @@ export function createRollupDebugIdInjectionHooks() {
};
}

export function createRollupModuleMetadataInjectionHooks(injectionCode: string) {
export function createRollupModuleMetadataInjectionHooks(injectionCode: string): {
renderChunk: RenderChunkHook;
} {
return {
renderChunk(code: string, chunk: { fileName: string }) {
if (
Expand Down Expand Up @@ -349,7 +361,12 @@ export function createRollupDebugIdUploadHooks(
upload: (buildArtifacts: string[]) => Promise<void>,
_logger: Logger,
createDependencyOnBuildArtifacts: () => () => void
) {
): {
writeBundle: (
outputOptions: { dir?: string; file?: string },
bundle: { [fileName: string]: unknown }
) => Promise<void>;
} {
Comment on lines +365 to +369
Copy link
Member Author

Choose a reason for hiding this comment

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

Same for writeBundle as for renderChunk (see comment above)

const freeGlobalDependencyOnDebugIdSourcemapArtifacts = createDependencyOnBuildArtifacts();
return {
async writeBundle(
Expand Down Expand Up @@ -390,7 +407,9 @@ export function createRollupDebugIdUploadHooks(
};
}

export function createComponentNameAnnotateHooks(ignoredComponents?: string[]) {
export function createComponentNameAnnotateHooks(ignoredComponents?: string[]): {
transform: UnpluginOptions["transform"];
} {
type ParserPlugins = NonNullable<
NonNullable<Parameters<typeof transformAsync>[1]>["parserOpts"]
>["plugins"];
Expand Down
4 changes: 2 additions & 2 deletions packages/bundler-plugin-core/src/sentry/telemetry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export function setTelemetryDataOnScope(
options: NormalizedOptions,
scope: Scope,
buildTool: string
) {
): void {
const { org, project, release, errorHandler, sourcemaps, reactComponentAnnotation } = options;

scope.setTag("upload-legacy-sourcemaps", !!release.uploadLegacySourcemaps);
Expand Down Expand Up @@ -161,7 +161,7 @@ export async function allowedToSendTelemetry(options: NormalizedOptions): Promis
/**
* Flushing the SDK client can fail. We never want to crash the plugin because of telemetry.
*/
export async function safeFlushTelemetry(sentryClient: Client) {
export async function safeFlushTelemetry(sentryClient: Client): Promise<void> {
try {
await sentryClient.flush(2000);
} catch {
Expand Down
2 changes: 1 addition & 1 deletion packages/bundler-plugin-core/src/sentry/transports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ function createRequestExecutor(options: BaseTransportOptions): TransportRequestE
/**
* Creates a Transport that uses native the native 'http' and 'https' modules to send events to Sentry.
*/
function makeNodeTransport(options: BaseTransportOptions) {
function makeNodeTransport(options: BaseTransportOptions): Transport {
const requestExecutor = createRequestExecutor(options);
return createTransport(options, requestExecutor);
}
Expand Down
12 changes: 8 additions & 4 deletions packages/bundler-plugin-core/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ export function generateGlobalInjectorCode({
}: {
release: string;
injectBuildInformation: boolean;
}) {
}): string {
// The code below is mostly ternary operators because it saves bundle size.
// The checks are to support as many environments as possible. (Node.js, Browser, webworkers, etc.)
let code = `{
Expand Down Expand Up @@ -341,7 +341,7 @@ export function generateGlobalInjectorCode({
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function generateModuleMetadataInjectorCode(metadata: any) {
export function generateModuleMetadataInjectorCode(metadata: any): string {
// The code below is mostly ternary operators because it saves bundle size.
// The checks are to support as many environments as possible. (Node.js, Browser, webworkers, etc.)
// We are merging the metadata objects in case modules are bundled twice with the plugin
Expand Down Expand Up @@ -369,7 +369,11 @@ export function generateModuleMetadataInjectorCode(metadata: any) {
}`;
}

function getBuildInformation() {
export function getBuildInformation(): {
deps: string[];
depsVersions: Record<string, number>;
nodeVersion: number | undefined;
} {
const packageJson = getPackageJson();

const { deps, depsVersions } = packageJson
Expand Down Expand Up @@ -413,7 +417,7 @@ export function replaceBooleanFlagsInCode(
}

// https://turbo.build/repo/docs/reference/system-environment-variables#environment-variables-in-tasks
export function getTurborepoEnvPassthroughWarning(envVarName: string) {
export function getTurborepoEnvPassthroughWarning(envVarName: string): string {
return process.env["TURBO_HASH"]
? `\nYou seem to be using Turborepo, did you forget to put ${envVarName} in \`passThroughEnv\`? https://turbo.build/repo/docs/reference/configuration#passthroughenv`
: "";
Expand Down
2 changes: 1 addition & 1 deletion packages/bundler-plugin-core/test/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import path from "node:path";

type PackageJson = Record<string, unknown>;

function getCwdFor(dirName: string) {
function getCwdFor(dirName: string): string {
return path.resolve(__dirname + dirName);
}

Expand Down
1 change: 1 addition & 0 deletions packages/e2e-tests/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@ module.exports = {
},
rules: {
"no-console": "off",
"@typescript-eslint/explicit-function-return-type": "off",
},
};
4 changes: 4 additions & 0 deletions packages/eslint-configs/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,9 @@ module.exports = {
{ argsIgnorePattern: "^_", caughtErrorsIgnorePattern: "^_" },
],
"no-undef": "error", // https://github.com/typescript-eslint/typescript-eslint/issues/4580#issuecomment-1047144015
// Although for most codebases inferencing the return type is fine, we explicitly ask to annotate
// all functions with a return type. This is so that intent is as clear as possible as well as to
// avoid accidental breaking changes.
"@typescript-eslint/explicit-function-return-type": ["error", { allowExpressions: true }],
},
};
3 changes: 3 additions & 0 deletions packages/integration-tests/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,7 @@ module.exports = {
version: jestPackageJson.version,
},
},
rules: {
"@typescript-eslint/explicit-function-return-type": "off",
},
};
Loading