Skip to content

Commit ecdd4ec

Browse files
committed
🔀 Merge main: batch API cleanup, prototype pollution fix, v7.4.0
Resolves conflicts from createBatch API refactor (reportError string signature, forceFlush), prototype pollution guards in mergeInto, debugger init version tests, and dep bumps. Converts new Jasmine patterns to Vitest API in auto-merged files.
2 parents 9b01784 + 8af9fbf commit ecdd4ec

91 files changed

Lines changed: 1909 additions & 1200 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitlab-ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
variables:
2-
CURRENT_STAGING: staging-25
2+
CURRENT_STAGING: staging-26
33
APP: 'browser-sdk'
44
CURRENT_CI_IMAGE: 113
55
BUILD_STABLE_REGISTRY: 'registry.ddbuild.io'

CHANGELOG.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,46 @@
1515
1616
---
1717

18+
## v7.4.0
19+
20+
**Public Changes:**
21+
22+
- ✨Rename feature operation APIs to operation ([#4810](https://github.com/DataDog/browser-sdk/pull/4810))
23+
-[RUM-16632] add profiling bridge mode support ([#4747](https://github.com/DataDog/browser-sdk/pull/4747))
24+
- 🐛 [VULN-81506] fix prototype pollution via mergeInto and tryJsonParse ([#4820](https://github.com/DataDog/browser-sdk/pull/4820))
25+
- 🐛 Fix flaky stylesheet rules test ([#4803](https://github.com/DataDog/browser-sdk/pull/4803))
26+
- 🐛 [Profiler] Fix empty session ID & quota check on renew ([#4766](https://github.com/DataDog/browser-sdk/pull/4766))
27+
- 🐛 Tolerate an invalid view URL in the developer extension ([#4773](https://github.com/DataDog/browser-sdk/pull/4773))
28+
- 📝 add deterministic sampling warning to v7.0.0 release notes ([#4805](https://github.com/DataDog/browser-sdk/pull/4805))
29+
- 📝 use typedoc for js-core ([#4801](https://github.com/DataDog/browser-sdk/pull/4801))
30+
31+
**Internal Changes:**
32+
33+
- 👷 Update Node.js to v25 ([#4818](https://github.com/DataDog/browser-sdk/pull/4818))
34+
- 👷 Update Puppeteer to v25 ([#4819](https://github.com/DataDog/browser-sdk/pull/4819))
35+
- 👷 Update dependency babel-loader to v10 ([#4817](https://github.com/DataDog/browser-sdk/pull/4817))
36+
- 👷 Update all non-major dependencies ([#4816](https://github.com/DataDog/browser-sdk/pull/4816))
37+
- 👷 Update dependency undici to v8.5.0 [SECURITY] ([#4808](https://github.com/DataDog/browser-sdk/pull/4808))
38+
- 👷 Update Angular, Vue compiler-dom, and Vite dependencies ([#4799](https://github.com/DataDog/browser-sdk/pull/4799))
39+
- 👷 Add API surface linting for @datadog/js-core via API Extractor ([#4804](https://github.com/DataDog/browser-sdk/pull/4804))
40+
- 👷 Bump @datadog/js-core to 0.0.3 ([#4800](https://github.com/DataDog/browser-sdk/pull/4800))
41+
- 👷 [RUM-16634] Require WebView wildcard to match at least one character ([#4785](https://github.com/DataDog/browser-sdk/pull/4785))
42+
- 👷 Improve checkTelemetryErrors: exclude deprecated datacenters and add detailed logging ([#4794](https://github.com/DataDog/browser-sdk/pull/4794))
43+
- 👷 migrate module builds from TypeScript compiler API to tsdown ([#4767](https://github.com/DataDog/browser-sdk/pull/4767))
44+
- 👷 Update dependency @angular/common to v22.0.1 [SECURITY] ([#4789](https://github.com/DataDog/browser-sdk/pull/4789))
45+
- 👷 Update dependency @angular/core to v22.0.1 [SECURITY] ([#4786](https://github.com/DataDog/browser-sdk/pull/4786))
46+
- 👷 Allow passing a full commit hash to `json-schemas --update` ([#4784](https://github.com/DataDog/browser-sdk/pull/4784))
47+
- 👷 also pin angular-cli deps on angular-app ([#4783](https://github.com/DataDog/browser-sdk/pull/4783))
48+
- 👷 fix performance benchmark CI and rename e2e setup script ([#4781](https://github.com/DataDog/browser-sdk/pull/4781))
49+
- 👷 Update all non-major dependencies ([#4777](https://github.com/DataDog/browser-sdk/pull/4777))
50+
- 👷 Update dependency @vitejs/plugin-react to v6 ([#4776](https://github.com/DataDog/browser-sdk/pull/4776))
51+
- 👷 Update dependency webpack-cli to v7 ([#4780](https://github.com/DataDog/browser-sdk/pull/4780))
52+
- 👷 Update dependency vite to v8 ([#4778](https://github.com/DataDog/browser-sdk/pull/4778))
53+
- 👷 use rum-events-format as a yarn dependency ([#4772](https://github.com/DataDog/browser-sdk/pull/4772))
54+
- ♻️ move hook and merge utilities from browser-core to @datadog/js-core ([#4797](https://github.com/DataDog/browser-sdk/pull/4797))
55+
- ♻️ Migrate browser-core monitoring/display to @datadog/js-core ([#4758](https://github.com/DataDog/browser-sdk/pull/4758))
56+
- 🔧 set ephemeral:false for staging branches ([#4813](https://github.com/DataDog/browser-sdk/pull/4813))
57+
1858
## v7.3.0
1959

2060
**Public Changes:**

developer-extension/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@datadog/browser-sdk-developer-extension",
3-
"version": "7.3.0",
3+
"version": "7.4.0",
44
"private": true,
55
"scripts": {
66
"build": "wxt build",
@@ -19,8 +19,8 @@
1919
"@datadog/browser-logs": "workspace:*",
2020
"@datadog/browser-rum": "workspace:*",
2121
"@datadog/browser-rum-core": "workspace:*",
22-
"@mantine/core": "9.3.0",
23-
"@mantine/hooks": "9.3.0",
22+
"@mantine/core": "9.3.1",
23+
"@mantine/hooks": "9.3.1",
2424
"@tabler/icons-react": "3.44.0",
2525
"clsx": "2.1.1",
2626
"react": "19.2.7",

package.json

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "browser-sdk",
3-
"version": "7.3.0",
3+
"version": "7.4.0",
44
"description": "browser SDK",
55
"private": true,
66
"workspaces": [
@@ -48,16 +48,16 @@
4848
"@jsdevtools/coverage-istanbul-loader": "3.0.5",
4949
"@microsoft/api-extractor": "7.58.9",
5050
"@playwright/test": "1.60.0",
51-
"@swc/core": "1.15.40",
51+
"@swc/core": "1.15.41",
5252
"@types/busboy": "1.5.4",
5353
"@types/chrome": "0.1.43",
5454
"@types/cors": "2.8.19",
5555
"@types/express": "5.0.6",
5656
"@types/jasmine": "3.10.19",
57-
"@types/node": "25.9.2",
57+
"@types/node": "25.9.3",
5858
"@types/node-forge": "1.3.14",
5959
"@types/ws": "8.18.1",
60-
"@typescript-eslint/utils": "8.60.1",
60+
"@typescript-eslint/utils": "8.61.0",
6161
"@vitest/browser": "4.0.18",
6262
"@vitest/browser-playwright": "4.0.18",
6363
"@vitest/browser-webdriverio": "4.0.18",
@@ -68,7 +68,7 @@
6868
"chrome-webstore-upload": "4.0.4",
6969
"cors": "2.8.6",
7070
"emoji-name-map": "2.0.3",
71-
"eslint": "10.4.1",
71+
"eslint": "10.5.0",
7272
"eslint-import-resolver-typescript": "4.4.5",
7373
"eslint-plugin-import-x": "4.16.2",
7474
"eslint-plugin-jasmine": "4.2.2",
@@ -91,17 +91,17 @@
9191
"karma-webpack": "5.0.0",
9292
"minimatch": "10.2.5",
9393
"node-forge": "1.4.0",
94-
"prettier": "3.8.3",
95-
"puppeteer": "24.43.1",
94+
"prettier": "3.8.4",
95+
"puppeteer": "25.1.0",
9696
"swc-loader": "0.2.7",
9797
"terser-webpack-plugin": "5.6.1",
9898
"ts-loader": "9.6.0",
9999
"tsconfig-paths-webpack-plugin": "4.2.0",
100100
"tsdown": "0.22.2",
101101
"typedoc": "0.28.19",
102102
"typescript": "6.0.3",
103-
"typescript-eslint": "8.60.1",
104-
"undici": "8.4.0",
103+
"typescript-eslint": "8.61.0",
104+
"undici": "8.5.0",
105105
"vitest": "4.0.18",
106106
"webdriverio": "9.27.1",
107107
"webpack": "5.107.2",

packages/browser-core/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@datadog/browser-core",
3-
"version": "7.3.0",
3+
"version": "7.4.0",
44
"license": "Apache-2.0",
55
"main": "cjs/index.js",
66
"module": "esm/index.mjs",
@@ -23,7 +23,7 @@
2323
"directory": "packages/browser-core"
2424
},
2525
"dependencies": {
26-
"@datadog/js-core": "0.0.3"
26+
"@datadog/js-core": "0.0.4"
2727
},
2828
"devDependencies": {
2929
"@types/pako": "2.0.4",

packages/browser-core/src/browser/pageMayExitObservable.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Observable } from '../tools/observable'
22
import { objectValues } from '../tools/utils/polyfills'
3-
import { isWorkerEnvironment } from '../tools/globalObject'
3+
import { globalObject } from '../tools/globalObject'
44
import { addEventListeners, addEventListener, DOM_EVENT } from './addEventListener'
55

66
export const PageExitReason = {
@@ -18,8 +18,9 @@ export interface PageMayExitEvent {
1818

1919
export function createPageMayExitObservable(): Observable<PageMayExitEvent> {
2020
return new Observable<PageMayExitEvent>((observable) => {
21-
if (isWorkerEnvironment) {
22-
// Page exit is not observable in worker environments (no window/document events)
21+
const window = globalObject.window
22+
if (!window) {
23+
// Page exit is not observable in non-browser environments
2324
return
2425
}
2526
const { stop: stopListeners } = addEventListeners(

packages/browser-core/src/domain/context/storeContextManager.spec.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@ describe('storeContextManager', () => {
7878
expect(localStorage.getItem(buildStorageKey(PRODUCT_KEY, CustomerDataType.GlobalContext))).toBe('{"qux":"qix"}')
7979
})
8080

81+
it('should return empty context when localStorage contains invalid JSON', () => {
82+
localStorage.setItem(STORAGE_KEY, 'not valid json')
83+
const manager = createStoredContextManager()
84+
expect(manager.getContext()).toEqual({})
85+
})
86+
8187
function createStoredContextManager({
8288
initialContext,
8389
productKey = PRODUCT_KEY,

packages/browser-core/src/domain/context/storeContextManager.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { combine } from '@datadog/js-core/util'
22
import { addEventListener, DOM_EVENT } from '../../browser/addEventListener'
33
import type { Context } from '../../tools/serialisation/context'
4-
import { isEmptyObject } from '../../tools/utils/objectUtils'
4+
import { isEmptyObject, tryJsonParse } from '../../tools/utils/objectUtils'
55
import type { ContextManager } from './contextManager'
66
import type { CustomerDataType } from './contextConstants'
77

@@ -45,7 +45,7 @@ export function storeContextManager(
4545

4646
function getFromStorage() {
4747
const rawContext = localStorage.getItem(storageKey)
48-
return rawContext ? (JSON.parse(rawContext) as Context) : {}
48+
return rawContext ? (tryJsonParse<Context>(rawContext) ?? {}) : {}
4949
}
5050
}
5151

packages/browser-core/src/domain/eventRateLimiter/createEventRateLimiter.spec.ts

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import { vi, beforeEach, describe, expect, it } from 'vitest'
2-
import { relativeToClocks, ONE_MINUTE } from '@datadog/js-core/time'
2+
import { ONE_MINUTE } from '@datadog/js-core/time'
33
import type { Clock } from '../../../test'
44
import { mockClock } from '../../../test'
55
import { noop } from '../../tools/utils/functionUtils'
6-
import type { RawError } from '../error/error.types'
76
import { createEventRateLimiter } from './createEventRateLimiter'
87
import type { EventRateLimiter } from './createEventRateLimiter'
98

@@ -37,18 +36,13 @@ describe('createEventRateLimiter', () => {
3736
expect(eventLimiter.isLimitReached()).toBe(false)
3837
})
3938

40-
it('calls the "onLimitReached" callback with the raw "limit reached" error when the limit is reached', () => {
41-
const onLimitReachedSpy = vi.fn<(rawError: RawError) => void>()
39+
it('calls the "onLimitReached" callback with the "limit reached" message when the limit is reached', () => {
40+
const onLimitReachedSpy = vi.fn<(message: string) => void>()
4241
eventLimiter = createEventRateLimiter('error', onLimitReachedSpy, limit)
4342

4443
eventLimiter.isLimitReached()
4544
eventLimiter.isLimitReached()
46-
expect(onLimitReachedSpy).toHaveBeenCalledTimes(1)
47-
expect(onLimitReachedSpy).toHaveBeenCalledWith({
48-
message: 'Reached max number of errors by minute: 1',
49-
source: 'agent',
50-
startClocks: relativeToClocks(clock.relative(0)),
51-
})
45+
expect(onLimitReachedSpy).toHaveBeenCalledWith('Reached max number of errors by minute: 1')
5246
})
5347

5448
it('returns false when called from the "onLimitReached" callback to bypass the limit for the "limit reached" error', () => {
@@ -65,7 +59,7 @@ describe('createEventRateLimiter', () => {
6559
})
6660

6761
it('does not call the "onLimitReached" callback more than once when the limit is reached', () => {
68-
const onLimitReachedSpy = vi.fn<(rawError: RawError) => void>()
62+
const onLimitReachedSpy = vi.fn<(message: string) => void>()
6963
eventLimiter = createEventRateLimiter('error', onLimitReachedSpy, limit)
7064

7165
eventLimiter.isLimitReached()

packages/browser-core/src/domain/eventRateLimiter/createEventRateLimiter.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
import { ONE_MINUTE, clocksNow } from '@datadog/js-core/time'
1+
import { ONE_MINUTE } from '@datadog/js-core/time'
22
import { setTimeout } from '../../tools/timer'
3-
import type { RawError } from '../error/error.types'
4-
import { ErrorSource } from '../error/error.types'
53

64
export type EventRateLimiter = ReturnType<typeof createEventRateLimiter>
75

@@ -10,7 +8,7 @@ const EVENT_RATE_LIMIT = 3000
108

119
export function createEventRateLimiter(
1210
eventType: string,
13-
onLimitReached: (limitError: RawError) => void,
11+
onLimitReached: (message: string) => void,
1412
limit = EVENT_RATE_LIMIT
1513
) {
1614
let eventCount = 0
@@ -33,11 +31,7 @@ export function createEventRateLimiter(
3331
if (eventCount === limit + 1) {
3432
allowNextEvent = true
3533
try {
36-
onLimitReached({
37-
message: `Reached max number of ${eventType}s by minute: ${limit}`,
38-
source: ErrorSource.AGENT,
39-
startClocks: clocksNow(),
40-
})
34+
onLimitReached(`Reached max number of ${eventType}s by minute: ${limit}`)
4135
} finally {
4236
allowNextEvent = false
4337
}

0 commit comments

Comments
 (0)