Skip to content

Commit 3847840

Browse files
authored
Merge branch 'develop' into lforst-undici-normal-require
2 parents 24f1a95 + 7ec21da commit 3847840

File tree

85 files changed

+1947
-785
lines changed

Some content is hidden

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

85 files changed

+1947
-785
lines changed

.github/workflows/build.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -913,6 +913,7 @@ jobs:
913913
'generic-ts3.8',
914914
'node-experimental-fastify-app',
915915
'node-hapi-app',
916+
'node-exports-test-app',
916917
]
917918
build-command:
918919
- false
@@ -946,6 +947,9 @@ jobs:
946947
uses: actions/setup-node@v4
947948
with:
948949
node-version-file: 'dev-packages/e2e-tests/package.json'
950+
- name: Set up Bun
951+
if: matrix.test-application == 'node-exports-test-app'
952+
uses: oven-sh/setup-bun@v1
949953
- name: Restore caches
950954
uses: ./.github/actions/restore-cache
951955
env:

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ convenient interface and improved consistency between various JavaScript environ
3232
- [Supported Platforms](#supported-platforms)
3333
- [Installation and Usage](#installation-and-usage)
3434
- [Other Packages](#other-packages)
35+
- [Bug Bounty Program](#bug-bounty-program)
3536

3637
## Supported Platforms
3738

@@ -104,3 +105,13 @@ below:
104105
utility functions useful for various SDKs.
105106
- [`@sentry/types`](https://github.com/getsentry/sentry-javascript/tree/master/packages/types): Types used in all
106107
packages.
108+
109+
## Bug Bounty Program
110+
111+
Our bug bounty program aims to improve the security of our open source projects by encouraging the community to identify
112+
and report potential security vulnerabilities. Your reward will depend on the severity of the identified vulnerability.
113+
114+
Our program is currently running on an invitation basis. If you're interested in participating, please send us an email
115+
to [email protected] and tell us, that you are interested in auditing this repository.
116+
117+
For more details, please have a look at https://sentry.io/security/#vulnerability-disclosure.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import * as Sentry from '@sentry/browser';
2+
3+
window.Sentry = Sentry;
4+
5+
Sentry.init({
6+
dsn: 'https://[email protected]/1337',
7+
// disable pageload transaction
8+
integrations: [Sentry.BrowserTracing({ tracingOrigins: ['http://example.com'], startTransactionOnPageLoad: false })],
9+
tracesSampleRate: 1,
10+
});
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fetch('http://example.com/0').then(fetch('http://example.com/1').then(fetch('http://example.com/2')));
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { expect } from '@playwright/test';
2+
3+
import { sentryTest } from '../../../../utils/fixtures';
4+
import { envelopeUrlRegex, shouldSkipTracingTest } from '../../../../utils/helpers';
5+
6+
sentryTest(
7+
'there should be no span created for fetch requests with no active span',
8+
async ({ getLocalTestPath, page }) => {
9+
if (shouldSkipTracingTest()) {
10+
sentryTest.skip();
11+
}
12+
13+
const url = await getLocalTestPath({ testDir: __dirname });
14+
15+
let requestCount = 0;
16+
page.on('request', request => {
17+
expect(envelopeUrlRegex.test(request.url())).toBe(false);
18+
requestCount++;
19+
});
20+
21+
await page.goto(url);
22+
23+
// Here are the requests that should exist:
24+
// 1. HTML page
25+
// 2. Init JS bundle
26+
// 3. Subject JS bundle
27+
// 4 [OPTIONAl] CDN JS bundle
28+
// and then 3 fetch requests
29+
if (process.env.PW_BUNDLE && process.env.PW_BUNDLE.startsWith('bundle_')) {
30+
expect(requestCount).toBe(7);
31+
} else {
32+
expect(requestCount).toBe(6);
33+
}
34+
},
35+
);
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import * as Sentry from '@sentry/browser';
2+
3+
window.Sentry = Sentry;
4+
5+
Sentry.init({
6+
dsn: 'https://[email protected]/1337',
7+
// disable pageload transaction
8+
integrations: [Sentry.BrowserTracing({ tracingOrigins: ['http://example.com'], startTransactionOnPageLoad: false })],
9+
tracesSampleRate: 1,
10+
});
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
const xhr_1 = new XMLHttpRequest();
2+
xhr_1.open('GET', 'http://example.com/0');
3+
xhr_1.send();
4+
5+
const xhr_2 = new XMLHttpRequest();
6+
xhr_2.open('GET', 'http://example.com/1');
7+
xhr_2.send();
8+
9+
const xhr_3 = new XMLHttpRequest();
10+
xhr_3.open('GET', 'http://example.com/2');
11+
xhr_3.send();
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { expect } from '@playwright/test';
2+
3+
import { sentryTest } from '../../../../utils/fixtures';
4+
import { envelopeUrlRegex, shouldSkipTracingTest } from '../../../../utils/helpers';
5+
6+
sentryTest(
7+
'there should be no span created for xhr requests with no active span',
8+
async ({ getLocalTestPath, page }) => {
9+
if (shouldSkipTracingTest()) {
10+
sentryTest.skip();
11+
}
12+
13+
const url = await getLocalTestPath({ testDir: __dirname });
14+
15+
let requestCount = 0;
16+
page.on('request', request => {
17+
expect(envelopeUrlRegex.test(request.url())).toBe(false);
18+
requestCount++;
19+
});
20+
21+
await page.goto(url);
22+
23+
// Here are the requests that should exist:
24+
// 1. HTML page
25+
// 2. Init JS bundle
26+
// 3. Subject JS bundle
27+
// 4 [OPTIONAl] CDN JS bundle
28+
// and then 3 fetch requests
29+
if (process.env.PW_BUNDLE && process.env.PW_BUNDLE.startsWith('bundle_')) {
30+
expect(requestCount).toBe(7);
31+
} else {
32+
expect(requestCount).toBe(6);
33+
}
34+
},
35+
);

dev-packages/browser-integration-tests/utils/helpers.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { Page, Request } from '@playwright/test';
22
import type { EnvelopeItemType, Event, EventEnvelopeHeaders } from '@sentry/types';
33

4-
const envelopeUrlRegex = /\.sentry\.io\/api\/\d+\/envelope\//;
4+
export const envelopeUrlRegex = /\.sentry\.io\/api\/\d+\/envelope\//;
55

66
export const envelopeParser = (request: Request | null): unknown[] => {
77
// https://develop.sentry.dev/sdk/envelopes/
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
@sentry:registry=http://127.0.0.1:4873
2+
@sentry-internal:registry=http://127.0.0.1:4873
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Consistent Node Export Test
2+
3+
This test "app" ensures that we consistently re-export exports from `@sentry/node` in packages depending on
4+
`@sentry/node`.
5+
6+
## How to add new package
7+
8+
1. Add package as a dependency to the test app
9+
2. In `scripts/consistentExports.ts`:
10+
- add namespace import
11+
- add `DEPENDENTS` entry
12+
- add any ignores/exclusion entries as necessary
13+
- if the package is still under development, you can also set `skip: true`
14+
15+
## Limitations:
16+
17+
- This script only checks top-level exports for now (e.g. `metrics` but no sub-exports like `metrics.increment`)
18+
- This script only checks ESM transpiled code for now, not CJS
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"name": "node-express-app",
3+
"version": "1.0.0",
4+
"private": true,
5+
"type": "module",
6+
"scripts": {
7+
"build": "tsc",
8+
"start": "pnpm build && bun run ./dist/consistentExports.js",
9+
"test": " bun run ./dist/consistentExports.js",
10+
"clean": "npx rimraf node_modules,pnpm-lock.yaml,dist",
11+
"test:build": "pnpm install && pnpm build",
12+
"test:assert": "pnpm test"
13+
},
14+
"dependencies": {
15+
"@sentry/node": "latest || *",
16+
"@sentry/sveltekit": "latest || *",
17+
"@sentry/remix": "latest || *",
18+
"@sentry/astro": "latest || *",
19+
"@sentry/nextjs": "latest || *",
20+
"@sentry/serverless": "latest || *",
21+
"@sentry/bun": "latest || *",
22+
"@sentry/types": "latest || *",
23+
"@types/node": "18.15.1",
24+
"typescript": "4.9.5"
25+
},
26+
"devDependencies": {
27+
"ts-node": "10.9.1"
28+
},
29+
"volta": {
30+
"extends": "../../package.json"
31+
}
32+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import * as SentryAstro from '@sentry/astro';
2+
import * as SentryBun from '@sentry/bun';
3+
import * as SentryNextJs from '@sentry/nextjs';
4+
import * as SentryNode from '@sentry/node';
5+
import * as SentryRemix from '@sentry/remix';
6+
import * as SentryServerless from '@sentry/serverless';
7+
import * as SentrySvelteKit from '@sentry/sveltekit';
8+
9+
/* List of exports that are safe to ignore / we don't require in any depending package */
10+
const NODE_EXPORTS_IGNORE = [
11+
'default',
12+
// Probably generated by transpilation, no need to require it
13+
'__esModule',
14+
// this function was deprecated almost immediately after it was introduced
15+
// due to a name change (startSpan). No need to re-export it IMHO.
16+
'startActiveSpan',
17+
// this was never meant for external use (and documented as such)
18+
'trace',
19+
// These Node exports were only made for type definition fixes (see #10339)
20+
'Undici',
21+
'Http',
22+
'DebugSession',
23+
'AnrIntegrationOptions',
24+
'LocalVariablesIntegrationOptions',
25+
];
26+
27+
type Dependent = {
28+
package: string;
29+
exports: string[];
30+
ignoreExports?: string[];
31+
skip?: boolean;
32+
};
33+
34+
const DEPENDENTS: Dependent[] = [
35+
{
36+
package: '@sentry/astro',
37+
exports: Object.keys(SentryAstro),
38+
},
39+
{
40+
package: '@sentry/bun',
41+
exports: Object.keys(SentryBun),
42+
ignoreExports: [
43+
// not supported in bun:
44+
'Handlers',
45+
'NodeClient',
46+
'hapiErrorPlugin',
47+
'makeNodeTransport',
48+
],
49+
},
50+
{
51+
package: '@sentry/nextjs',
52+
// Next.js doesn't require explicit exports, so we can just merge top level and `default` exports:
53+
// @ts-expect-error: `default` is not in the type definition but it's defined
54+
exports: Object.keys({ ...SentryNextJs, ...SentryNextJs.default }),
55+
},
56+
{
57+
package: '@sentry/remix',
58+
exports: Object.keys(SentryRemix),
59+
},
60+
{
61+
package: '@sentry/serverless',
62+
exports: Object.keys(SentryServerless),
63+
ignoreExports: ['cron', 'hapiErrorPlugin', 'enableAnrDetection'],
64+
},
65+
{
66+
package: '@sentry/sveltekit',
67+
exports: Object.keys(SentrySvelteKit),
68+
},
69+
];
70+
71+
/* Sanitized list of node exports */
72+
const nodeExports = Object.keys(SentryNode).filter(e => !NODE_EXPORTS_IGNORE.includes(e));
73+
74+
console.log('🔎 Checking for consistent exports of @sentry/node exports in depending packages');
75+
76+
const missingExports: Record<string, string[]> = {};
77+
const dependentsToCheck = DEPENDENTS.filter(d => !d.skip);
78+
79+
for (const nodeExport of nodeExports) {
80+
for (const dependent of dependentsToCheck) {
81+
if (dependent.ignoreExports?.includes(nodeExport)) {
82+
continue;
83+
}
84+
if (!dependent.exports.includes(nodeExport)) {
85+
missingExports[dependent.package] = [...(missingExports[dependent.package] ?? []), nodeExport];
86+
}
87+
}
88+
}
89+
90+
if (Object.keys(missingExports).length > 0) {
91+
console.error('\n❌ Found missing exports from @sentry/node in the following packages:\n');
92+
console.log(JSON.stringify(missingExports, null, 2));
93+
process.exit(1);
94+
}
95+
96+
console.log('✅ All good :)');
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"compilerOptions": {
3+
"types": ["node"],
4+
"esModuleInterop": true,
5+
"lib": ["ES6"],
6+
"strict": true,
7+
"outDir": "dist",
8+
"target": "ESNext",
9+
"moduleResolution": "node",
10+
"skipLibCheck": true
11+
},
12+
"include": ["scripts/**/*.ts"]
13+
}

dev-packages/node-integration-tests/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"test:watch": "yarn test --watch"
2828
},
2929
"dependencies": {
30+
"@hapi/hapi": "^20.3.0",
3031
"@prisma/client": "3.15.2",
3132
"@sentry/node": "7.98.0",
3233
"@sentry/tracing": "7.98.0",

dev-packages/node-integration-tests/src/index.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,11 @@ export function startExpressServerAndSendPortToRunner(app: Express): void {
2929
console.log(`{"port":${address.port}}`);
3030
});
3131
}
32+
33+
/**
34+
* Sends the port to the runner
35+
*/
36+
export function sendPortToRunner(port: number): void {
37+
// eslint-disable-next-line no-console
38+
console.log(`{"port":${port}}`);
39+
}

0 commit comments

Comments
 (0)