Skip to content

Commit

Permalink
Merge pull request #15611 from getsentry/prepare-release/9.5.0
Browse files Browse the repository at this point in the history
meta(changelog): Update changelog for 9.5.0
  • Loading branch information
AbhiPrasad authored Mar 6, 2025
2 parents f11f7b1 + 79a1eef commit aba909b
Show file tree
Hide file tree
Showing 32 changed files with 1,452 additions and 418 deletions.
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,28 @@

- "You miss 100 percent of the chances you don't take. — Wayne Gretzky" — Michael Scott

## 9.5.0

### Important Changes

We found some issues with the new feedback screenshot annotation where screenshots are not being generated properly. Due to this issue, we are reverting the feature.

- Revert "feat(feedback) Allowing annotation via highlighting & masking ([#15484](https://github.com/getsentry/sentry-javascript/pull/15484))" (#15609)

### Other Changes

- Add cloudflare adapter detection and path generation ([#15603](https://github.com/getsentry/sentry-javascript/pull/15603))
- deps(nextjs): Bump rollup to `4.34.9` ([#15589](https://github.com/getsentry/sentry-javascript/pull/15589))
- feat(bun): Automatically add performance integrations ([#15586](https://github.com/getsentry/sentry-javascript/pull/15586))
- feat(replay): Bump rrweb to 2.34.0 ([#15580](https://github.com/getsentry/sentry-javascript/pull/15580))
- fix(browser): Call original function on early return from patched history API ([#15576](https://github.com/getsentry/sentry-javascript/pull/15576))
- fix(nestjs): Copy metadata in custom decorators ([#15598](https://github.com/getsentry/sentry-javascript/pull/15598))
- fix(react-router): Fix config type import ([#15583](https://github.com/getsentry/sentry-javascript/pull/15583))
- fix(remix): Use correct types export for `@sentry/remix/cloudflare` ([#15599](https://github.com/getsentry/sentry-javascript/pull/15599))
- fix(vue): Attach Pinia state only once per event ([#15588](https://github.com/getsentry/sentry-javascript/pull/15588))

Work in this release was contributed by @msurdi-a8c, @namoscato, and @rileyg98. Thank you for your contributions!

## 9.4.0

- feat(core): Add types for logs protocol and envelope ([#15530](https://github.com/getsentry/sentry-javascript/pull/15530))
Expand Down
2 changes: 1 addition & 1 deletion dev-packages/browser-integration-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"dependencies": {
"@babel/preset-typescript": "^7.16.7",
"@playwright/test": "~1.50.0",
"@sentry-internal/rrweb": "2.33.0",
"@sentry-internal/rrweb": "2.34.0",
"@sentry/browser": "9.4.0",
"axios": "1.7.7",
"babel-loader": "^8.2.2",
Expand Down
2 changes: 1 addition & 1 deletion packages/browser-utils/src/instrument/history.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ function instrumentHistory(): void {
lastHref = to;

if (from === to) {
return;
return originalHistoryFunction.apply(this, args);
}

const handlerData = { from, to } satisfies HandlerDataHistory;
Expand Down
3 changes: 3 additions & 0 deletions packages/bun/src/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as os from 'node:os';
import {
applySdkMetadata,
functionToStringIntegration,
hasSpansEnabled,
inboundFiltersIntegration,
linkedErrorsIntegration,
requestDataIntegration,
Expand All @@ -11,6 +12,7 @@ import type { NodeClient } from '@sentry/node';
import {
consoleIntegration,
contextLinesIntegration,
getAutoPerformanceIntegrations,
httpIntegration,
init as initNode,
modulesIntegration,
Expand Down Expand Up @@ -48,6 +50,7 @@ export function getDefaultIntegrations(_options: Options): Integration[] {
modulesIntegration(),
// Bun Specific
bunServerIntegration(),
...(hasSpansEnabled(_options) ? getAutoPerformanceIntegrations() : []),
];
}

Expand Down
112 changes: 112 additions & 0 deletions packages/bun/test/init.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { type Integration } from '@sentry/core';
import * as sentryNode from '@sentry/node';
import type { Mock } from 'bun:test';
import { afterEach, beforeEach, describe, it, spyOn, mock, expect } from 'bun:test';
import { getClient, init } from '../src';

const PUBLIC_DSN = 'https://username@domain/123';

class MockIntegration implements Integration {
public name: string;
public setupOnce: Mock<() => void>;
public constructor(name: string) {
this.name = name;
this.setupOnce = mock(() => undefined);
}
}

describe('init()', () => {
let mockAutoPerformanceIntegrations: Mock<() => Integration[]>;

beforeEach(() => {
// @ts-expect-error weird
mockAutoPerformanceIntegrations = spyOn(sentryNode, 'getAutoPerformanceIntegrations');
});

afterEach(() => {
mockAutoPerformanceIntegrations.mockRestore();
});

describe('integrations', () => {
it("doesn't install default integrations if told not to", () => {
init({ dsn: PUBLIC_DSN, defaultIntegrations: false });

const client = getClient();

expect(client?.getOptions().integrations).toEqual([]);

expect(mockAutoPerformanceIntegrations).toHaveBeenCalledTimes(0);
});

it('installs merged default integrations, with overrides provided through options', () => {
const mockDefaultIntegrations = [
new MockIntegration('Some mock integration 2.1'),
new MockIntegration('Some mock integration 2.2'),
];

const mockIntegrations = [
new MockIntegration('Some mock integration 2.1'),
new MockIntegration('Some mock integration 2.3'),
];

init({ dsn: PUBLIC_DSN, integrations: mockIntegrations, defaultIntegrations: mockDefaultIntegrations });

expect(mockDefaultIntegrations[0]?.setupOnce).toHaveBeenCalledTimes(0);
expect(mockDefaultIntegrations[1]?.setupOnce).toHaveBeenCalledTimes(1);
expect(mockIntegrations[0]?.setupOnce).toHaveBeenCalledTimes(1);
expect(mockIntegrations[1]?.setupOnce).toHaveBeenCalledTimes(1);
expect(mockAutoPerformanceIntegrations).toHaveBeenCalledTimes(0);
});

it('installs integrations returned from a callback function', () => {
const mockDefaultIntegrations = [
new MockIntegration('Some mock integration 3.1'),
new MockIntegration('Some mock integration 3.2'),
];

const newIntegration = new MockIntegration('Some mock integration 3.3');

init({
dsn: PUBLIC_DSN,
defaultIntegrations: mockDefaultIntegrations,
integrations: integrations => {
const newIntegrations = [...integrations];
newIntegrations[1] = newIntegration;
return newIntegrations;
},
});

expect(mockDefaultIntegrations[0]?.setupOnce).toHaveBeenCalledTimes(1);
expect(mockDefaultIntegrations[1]?.setupOnce).toHaveBeenCalledTimes(0);
expect(newIntegration.setupOnce).toHaveBeenCalledTimes(1);
expect(mockAutoPerformanceIntegrations).toHaveBeenCalledTimes(0);
});

it('installs performance default instrumentations if tracing is enabled', () => {
const autoPerformanceIntegrations = [new MockIntegration('Performance integration')];
mockAutoPerformanceIntegrations.mockImplementation(() => autoPerformanceIntegrations);

const mockIntegrations = [
new MockIntegration('Some mock integration 4.1'),
new MockIntegration('Some mock integration 4.3'),
];

init({
dsn: PUBLIC_DSN,
integrations: mockIntegrations,
tracesSampleRate: 1,
});

expect(mockIntegrations[0]?.setupOnce).toHaveBeenCalledTimes(1);
expect(mockIntegrations[1]?.setupOnce).toHaveBeenCalledTimes(1);
expect(autoPerformanceIntegrations[0]?.setupOnce).toHaveBeenCalledTimes(1);
expect(mockAutoPerformanceIntegrations).toHaveBeenCalledTimes(1);

const integrations = getClient()?.getOptions().integrations;
expect(integrations).toBeArray();
expect(integrations?.map(({ name }) => name)).toContain('Performance integration');
expect(integrations?.map(({ name }) => name)).toContain('Some mock integration 4.1');
expect(integrations?.map(({ name }) => name)).toContain('Some mock integration 4.3');
});
});
});
9 changes: 9 additions & 0 deletions packages/core/src/types-hoist/feedback/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,15 @@ export interface FeedbackGeneralConfiguration {
name: string;
};

/**
* _experiments allows users to enable experimental or internal features.
* We don't consider such features as part of the public API and hence we don't guarantee semver for them.
* Experimental features can be added, changed or removed at any time.
*
* Default: undefined
*/
_experiments: Partial<{ annotations: boolean }>;

/**
* Set an object that will be merged sent as tags data with the event.
*/
Expand Down
4 changes: 2 additions & 2 deletions packages/feedback/src/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ export const NAME_PLACEHOLDER = 'Your Name';
export const NAME_LABEL = 'Name';
export const SUCCESS_MESSAGE_TEXT = 'Thank you for your report!';
export const IS_REQUIRED_LABEL = '(required)';
export const ADD_SCREENSHOT_LABEL = 'Capture Screenshot';
export const REMOVE_SCREENSHOT_LABEL = 'Remove Screenshot';
export const ADD_SCREENSHOT_LABEL = 'Add a screenshot';
export const REMOVE_SCREENSHOT_LABEL = 'Remove screenshot';

export const FEEDBACK_WIDGET_SOURCE = 'widget';
export const FEEDBACK_API_SOURCE = 'api';
Expand Down
3 changes: 3 additions & 0 deletions packages/feedback/src/core/integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ export const buildFeedbackIntegration = ({
email: 'email',
name: 'username',
},
_experiments = {},
tags,
styleNonce,
scriptNonce,
Expand Down Expand Up @@ -158,6 +159,8 @@ export const buildFeedbackIntegration = ({
onSubmitError,
onSubmitSuccess,
onFormSubmitted,

_experiments,
};

let _shadow: ShadowRoot | null = null;
Expand Down
91 changes: 91 additions & 0 deletions packages/feedback/src/screenshot/components/Annotations.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import type { VNode, h as hType } from 'preact';
import type * as Hooks from 'preact/hooks';
import { DOCUMENT } from '../../constants';

interface FactoryParams {
h: typeof hType;
}

export default function AnnotationsFactory({
h, // eslint-disable-line @typescript-eslint/no-unused-vars
}: FactoryParams) {
return function Annotations({
action,
imageBuffer,
annotatingRef,
}: {
action: 'crop' | 'annotate' | '';
imageBuffer: HTMLCanvasElement;
annotatingRef: Hooks.Ref<HTMLCanvasElement>;
}): VNode {
const onAnnotateStart = (): void => {
if (action !== 'annotate') {
return;
}

const handleMouseMove = (moveEvent: MouseEvent): void => {
const annotateCanvas = annotatingRef.current;
if (annotateCanvas) {
const rect = annotateCanvas.getBoundingClientRect();
const x = moveEvent.clientX - rect.x;
const y = moveEvent.clientY - rect.y;

const ctx = annotateCanvas.getContext('2d');
if (ctx) {
ctx.lineTo(x, y);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(x, y);
}
}
};

const handleMouseUp = (): void => {
const ctx = annotatingRef.current?.getContext('2d');
if (ctx) {
ctx.beginPath();
}

// Add your apply annotation logic here
applyAnnotation();

DOCUMENT.removeEventListener('mousemove', handleMouseMove);
DOCUMENT.removeEventListener('mouseup', handleMouseUp);
};

DOCUMENT.addEventListener('mousemove', handleMouseMove);
DOCUMENT.addEventListener('mouseup', handleMouseUp);
};

const applyAnnotation = (): void => {
// Logic to apply the annotation
const imageCtx = imageBuffer.getContext('2d');
const annotateCanvas = annotatingRef.current;
if (imageCtx && annotateCanvas) {
imageCtx.drawImage(
annotateCanvas,
0,
0,
annotateCanvas.width,
annotateCanvas.height,
0,
0,
imageBuffer.width,
imageBuffer.height,
);

const annotateCtx = annotateCanvas.getContext('2d');
if (annotateCtx) {
annotateCtx.clearRect(0, 0, annotateCanvas.width, annotateCanvas.height);
}
}
};
return (
<canvas
class={`editor__annotation ${action === 'annotate' ? 'editor__annotation--active' : ''}`}
onMouseDown={onAnnotateStart}
ref={annotatingRef}
></canvas>
);
};
}
Loading

0 comments on commit aba909b

Please sign in to comment.