@sentry/react-native 8.2.0 → 8.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -1
- package/RNSentry.podspec +1 -1
- package/android/AGENTS.md +51 -0
- package/android/libs/replay-stubs.jar +0 -0
- package/android/src/main/java/io/sentry/react/RNSentryLogger.java +96 -0
- package/android/src/main/java/io/sentry/react/RNSentryModuleImpl.java +13 -3
- package/android/src/main/java/io/sentry/react/RNSentryStart.java +21 -9
- package/android/src/main/java/io/sentry/react/RNSentryVersion.java +1 -1
- package/dist/js/NativeLogListener.d.ts +16 -0
- package/dist/js/NativeLogListener.d.ts.map +1 -0
- package/dist/js/NativeLogListener.js +72 -0
- package/dist/js/NativeLogListener.js.map +1 -0
- package/dist/js/client.d.ts +1 -0
- package/dist/js/client.d.ts.map +1 -1
- package/dist/js/client.js +14 -3
- package/dist/js/client.js.map +1 -1
- package/dist/js/index.d.ts +4 -4
- package/dist/js/index.d.ts.map +1 -1
- package/dist/js/index.js +2 -2
- package/dist/js/index.js.map +1 -1
- package/dist/js/integrations/default.d.ts.map +1 -1
- package/dist/js/integrations/default.js +2 -1
- package/dist/js/integrations/default.js.map +1 -1
- package/dist/js/integrations/expoconstants.d.ts +24 -0
- package/dist/js/integrations/expoconstants.d.ts.map +1 -0
- package/dist/js/integrations/expoconstants.js +77 -0
- package/dist/js/integrations/expoconstants.js.map +1 -0
- package/dist/js/integrations/expocontext.d.ts.map +1 -1
- package/dist/js/integrations/expocontext.js +35 -1
- package/dist/js/integrations/expocontext.js.map +1 -1
- package/dist/js/integrations/exports.d.ts +1 -0
- package/dist/js/integrations/exports.d.ts.map +1 -1
- package/dist/js/integrations/exports.js +1 -0
- package/dist/js/integrations/exports.js.map +1 -1
- package/dist/js/options.d.ts +26 -0
- package/dist/js/options.d.ts.map +1 -1
- package/dist/js/options.js.map +1 -1
- package/dist/js/sdk.d.ts.map +1 -1
- package/dist/js/sdk.js +3 -2
- package/dist/js/sdk.js.map +1 -1
- package/dist/js/tools/easBuildHooks.d.ts +48 -0
- package/dist/js/tools/easBuildHooks.d.ts.map +1 -0
- package/dist/js/tools/easBuildHooks.js +228 -0
- package/dist/js/tools/easBuildHooks.js.map +1 -0
- package/dist/js/tools/metroconfig.d.ts +4 -0
- package/dist/js/tools/metroconfig.d.ts.map +1 -1
- package/dist/js/tools/metroconfig.js +46 -1
- package/dist/js/tools/metroconfig.js.map +1 -1
- package/dist/js/tracing/expoAsset.d.ts +42 -0
- package/dist/js/tracing/expoAsset.d.ts.map +1 -0
- package/dist/js/tracing/expoAsset.js +60 -0
- package/dist/js/tracing/expoAsset.js.map +1 -0
- package/dist/js/tracing/expoImage.d.ts +61 -0
- package/dist/js/tracing/expoImage.d.ts.map +1 -0
- package/dist/js/tracing/expoImage.js +101 -0
- package/dist/js/tracing/expoImage.js.map +1 -0
- package/dist/js/tracing/index.d.ts +4 -0
- package/dist/js/tracing/index.d.ts.map +1 -1
- package/dist/js/tracing/index.js +2 -0
- package/dist/js/tracing/index.js.map +1 -1
- package/dist/js/tracing/integrations/appStart.d.ts.map +1 -1
- package/dist/js/tracing/integrations/appStart.js +4 -1
- package/dist/js/tracing/integrations/appStart.js.map +1 -1
- package/dist/js/tracing/onSpanEndUtils.d.ts +7 -0
- package/dist/js/tracing/onSpanEndUtils.d.ts.map +1 -1
- package/dist/js/tracing/onSpanEndUtils.js +45 -6
- package/dist/js/tracing/onSpanEndUtils.js.map +1 -1
- package/dist/js/tracing/origin.d.ts +2 -0
- package/dist/js/tracing/origin.d.ts.map +1 -1
- package/dist/js/tracing/origin.js +2 -0
- package/dist/js/tracing/origin.js.map +1 -1
- package/dist/js/tracing/reactnavigation.d.ts +15 -0
- package/dist/js/tracing/reactnavigation.d.ts.map +1 -1
- package/dist/js/tracing/reactnavigation.js +50 -17
- package/dist/js/tracing/reactnavigation.js.map +1 -1
- package/dist/js/tracing/span.d.ts +6 -6
- package/dist/js/tracing/span.d.ts.map +1 -1
- package/dist/js/tracing/span.js +3 -3
- package/dist/js/tracing/span.js.map +1 -1
- package/dist/js/tracing/utils.d.ts +27 -1
- package/dist/js/tracing/utils.d.ts.map +1 -1
- package/dist/js/tracing/utils.js +66 -1
- package/dist/js/tracing/utils.js.map +1 -1
- package/dist/js/utils/expoglobalobject.d.ts +47 -7
- package/dist/js/utils/expoglobalobject.d.ts.map +1 -1
- package/dist/js/utils/expoglobalobject.js.map +1 -1
- package/dist/js/version.d.ts +1 -1
- package/dist/js/version.js +6 -3
- package/dist/js/version.js.map +1 -1
- package/dist/js/wrapper.d.ts.map +1 -1
- package/dist/js/wrapper.js +1 -1
- package/dist/js/wrapper.js.map +1 -1
- package/ios/AGENTS.md +60 -0
- package/ios/RNSentry.mm +4 -1
- package/ios/RNSentryEvents.h +1 -0
- package/ios/RNSentryEvents.m +1 -0
- package/ios/RNSentryNativeLogsForwarder.h +20 -0
- package/ios/RNSentryNativeLogsForwarder.m +145 -0
- package/ios/RNSentryVersion.m +1 -1
- package/package.json +14 -11
- package/plugin/build/utils.d.ts +1 -0
- package/plugin/build/utils.js +19 -1
- package/plugin/build/withSentry.d.ts +1 -0
- package/plugin/build/withSentry.js +28 -0
- package/scripts/eas-build-hook.js +234 -0
- package/scripts/sentry-xcode.sh +7 -0
- package/ts3.8/dist/js/NativeLogListener.d.ts +16 -0
- package/ts3.8/dist/js/client.d.ts +1 -0
- package/ts3.8/dist/js/index.d.ts +4 -4
- package/ts3.8/dist/js/integrations/expoconstants.d.ts +24 -0
- package/ts3.8/dist/js/integrations/exports.d.ts +1 -0
- package/ts3.8/dist/js/options.d.ts +26 -0
- package/ts3.8/dist/js/tracing/expoAsset.d.ts +42 -0
- package/ts3.8/dist/js/tracing/expoImage.d.ts +61 -0
- package/ts3.8/dist/js/tracing/index.d.ts +4 -0
- package/ts3.8/dist/js/tracing/onSpanEndUtils.d.ts +7 -0
- package/ts3.8/dist/js/tracing/origin.d.ts +2 -0
- package/ts3.8/dist/js/tracing/reactnavigation.d.ts +15 -0
- package/ts3.8/dist/js/tracing/span.d.ts +6 -6
- package/ts3.8/dist/js/tracing/utils.d.ts +27 -1
- package/ts3.8/dist/js/utils/expoglobalobject.d.ts +47 -7
- package/ts3.8/dist/js/version.d.ts +1 -1
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EAS Build Hooks for Sentry
|
|
3
|
+
*
|
|
4
|
+
* This module provides utilities for capturing EAS build lifecycle events
|
|
5
|
+
* and sending them to Sentry. It supports the following EAS npm hooks:
|
|
6
|
+
* - eas-build-on-error: Captures build failures
|
|
7
|
+
* - eas-build-on-success: Captures successful builds (optional)
|
|
8
|
+
* - eas-build-on-complete: Captures build completion with metrics
|
|
9
|
+
*
|
|
10
|
+
* @see https://docs.expo.dev/build-reference/npm-hooks/
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Environment variables provided by EAS Build.
|
|
14
|
+
* @see https://docs.expo.dev/build-reference/variables/
|
|
15
|
+
*/
|
|
16
|
+
export interface EASBuildEnv {
|
|
17
|
+
EAS_BUILD?: string;
|
|
18
|
+
EAS_BUILD_ID?: string;
|
|
19
|
+
EAS_BUILD_PLATFORM?: string;
|
|
20
|
+
EAS_BUILD_PROFILE?: string;
|
|
21
|
+
EAS_BUILD_PROJECT_ID?: string;
|
|
22
|
+
EAS_BUILD_GIT_COMMIT_HASH?: string;
|
|
23
|
+
EAS_BUILD_RUN_FROM_CI?: string;
|
|
24
|
+
EAS_BUILD_STATUS?: string;
|
|
25
|
+
EAS_BUILD_APP_VERSION?: string;
|
|
26
|
+
EAS_BUILD_APP_BUILD_VERSION?: string;
|
|
27
|
+
EAS_BUILD_USERNAME?: string;
|
|
28
|
+
EAS_BUILD_WORKINGDIR?: string;
|
|
29
|
+
}
|
|
30
|
+
/** Options for configuring EAS build hook behavior. */
|
|
31
|
+
export interface EASBuildHookOptions {
|
|
32
|
+
dsn?: string;
|
|
33
|
+
tags?: Record<string, string>;
|
|
34
|
+
captureSuccessfulBuilds?: boolean;
|
|
35
|
+
errorMessage?: string;
|
|
36
|
+
successMessage?: string;
|
|
37
|
+
}
|
|
38
|
+
/** Checks if the current environment is an EAS Build. */
|
|
39
|
+
export declare function isEASBuild(): boolean;
|
|
40
|
+
/** Gets the EAS build environment variables. */
|
|
41
|
+
export declare function getEASBuildEnv(): EASBuildEnv;
|
|
42
|
+
/** Captures an EAS build error event. Call this from the eas-build-on-error hook. */
|
|
43
|
+
export declare function captureEASBuildError(options?: EASBuildHookOptions): Promise<void>;
|
|
44
|
+
/** Captures an EAS build success event. Call this from the eas-build-on-success hook. */
|
|
45
|
+
export declare function captureEASBuildSuccess(options?: EASBuildHookOptions): Promise<void>;
|
|
46
|
+
/** Captures an EAS build completion event with status. Call this from the eas-build-on-complete hook. */
|
|
47
|
+
export declare function captureEASBuildComplete(options?: EASBuildHookOptions): Promise<void>;
|
|
48
|
+
//# sourceMappingURL=easBuildHooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"easBuildHooks.d.ts","sourceRoot":"","sources":["../../../src/js/tools/easBuildHooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAWH;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,uDAAuD;AACvD,MAAM,WAAW,mBAAmB;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAoBD,yDAAyD;AACzD,wBAAgB,UAAU,IAAI,OAAO,CAEpC;AAED,gDAAgD;AAChD,wBAAgB,cAAc,IAAI,WAAW,CAe5C;AAkGD,qFAAqF;AACrF,wBAAsB,oBAAoB,CAAC,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0B3F;AAED,yFAAyF;AACzF,wBAAsB,sBAAsB,CAAC,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CA4B7F;AAED,yGAAyG;AACzG,wBAAsB,uBAAuB,CAAC,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAY9F"}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* EAS Build Hooks for Sentry
|
|
4
|
+
*
|
|
5
|
+
* This module provides utilities for capturing EAS build lifecycle events
|
|
6
|
+
* and sending them to Sentry. It supports the following EAS npm hooks:
|
|
7
|
+
* - eas-build-on-error: Captures build failures
|
|
8
|
+
* - eas-build-on-success: Captures successful builds (optional)
|
|
9
|
+
* - eas-build-on-complete: Captures build completion with metrics
|
|
10
|
+
*
|
|
11
|
+
* @see https://docs.expo.dev/build-reference/npm-hooks/
|
|
12
|
+
*/
|
|
13
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
14
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
15
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
16
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
17
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
18
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
19
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.captureEASBuildComplete = exports.captureEASBuildSuccess = exports.captureEASBuildError = exports.getEASBuildEnv = exports.isEASBuild = void 0;
|
|
24
|
+
const core_1 = require("@sentry/core");
|
|
25
|
+
const version_1 = require("../version");
|
|
26
|
+
const SENTRY_DSN_ENV = 'SENTRY_DSN';
|
|
27
|
+
const EAS_BUILD_ENV = 'EAS_BUILD';
|
|
28
|
+
/** Checks if the current environment is an EAS Build. */
|
|
29
|
+
function isEASBuild() {
|
|
30
|
+
return process.env[EAS_BUILD_ENV] === 'true';
|
|
31
|
+
}
|
|
32
|
+
exports.isEASBuild = isEASBuild;
|
|
33
|
+
/** Gets the EAS build environment variables. */
|
|
34
|
+
function getEASBuildEnv() {
|
|
35
|
+
return {
|
|
36
|
+
EAS_BUILD: process.env.EAS_BUILD,
|
|
37
|
+
EAS_BUILD_ID: process.env.EAS_BUILD_ID,
|
|
38
|
+
EAS_BUILD_PLATFORM: process.env.EAS_BUILD_PLATFORM,
|
|
39
|
+
EAS_BUILD_PROFILE: process.env.EAS_BUILD_PROFILE,
|
|
40
|
+
EAS_BUILD_PROJECT_ID: process.env.EAS_BUILD_PROJECT_ID,
|
|
41
|
+
EAS_BUILD_GIT_COMMIT_HASH: process.env.EAS_BUILD_GIT_COMMIT_HASH,
|
|
42
|
+
EAS_BUILD_RUN_FROM_CI: process.env.EAS_BUILD_RUN_FROM_CI,
|
|
43
|
+
EAS_BUILD_STATUS: process.env.EAS_BUILD_STATUS,
|
|
44
|
+
EAS_BUILD_APP_VERSION: process.env.EAS_BUILD_APP_VERSION,
|
|
45
|
+
EAS_BUILD_APP_BUILD_VERSION: process.env.EAS_BUILD_APP_BUILD_VERSION,
|
|
46
|
+
EAS_BUILD_USERNAME: process.env.EAS_BUILD_USERNAME,
|
|
47
|
+
EAS_BUILD_WORKINGDIR: process.env.EAS_BUILD_WORKINGDIR,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
exports.getEASBuildEnv = getEASBuildEnv;
|
|
51
|
+
function getEnvelopeEndpoint(dsn) {
|
|
52
|
+
const { protocol, host, port, path, projectId, publicKey } = dsn;
|
|
53
|
+
const portStr = port ? `:${port}` : '';
|
|
54
|
+
const pathStr = path ? `/${path}` : '';
|
|
55
|
+
return `${protocol}://${host}${portStr}${pathStr}/api/${projectId}/envelope/?sentry_key=${publicKey}&sentry_version=7`;
|
|
56
|
+
}
|
|
57
|
+
function createEASBuildTags(env) {
|
|
58
|
+
const tags = {};
|
|
59
|
+
if (env.EAS_BUILD_PLATFORM)
|
|
60
|
+
tags['eas.platform'] = env.EAS_BUILD_PLATFORM;
|
|
61
|
+
if (env.EAS_BUILD_PROFILE)
|
|
62
|
+
tags['eas.profile'] = env.EAS_BUILD_PROFILE;
|
|
63
|
+
if (env.EAS_BUILD_ID)
|
|
64
|
+
tags['eas.build_id'] = env.EAS_BUILD_ID;
|
|
65
|
+
if (env.EAS_BUILD_PROJECT_ID)
|
|
66
|
+
tags['eas.project_id'] = env.EAS_BUILD_PROJECT_ID;
|
|
67
|
+
if (env.EAS_BUILD_RUN_FROM_CI)
|
|
68
|
+
tags['eas.from_ci'] = env.EAS_BUILD_RUN_FROM_CI;
|
|
69
|
+
if (env.EAS_BUILD_STATUS)
|
|
70
|
+
tags['eas.status'] = env.EAS_BUILD_STATUS;
|
|
71
|
+
if (env.EAS_BUILD_USERNAME)
|
|
72
|
+
tags['eas.username'] = env.EAS_BUILD_USERNAME;
|
|
73
|
+
return tags;
|
|
74
|
+
}
|
|
75
|
+
function createEASBuildContext(env) {
|
|
76
|
+
return {
|
|
77
|
+
build_id: env.EAS_BUILD_ID,
|
|
78
|
+
platform: env.EAS_BUILD_PLATFORM,
|
|
79
|
+
profile: env.EAS_BUILD_PROFILE,
|
|
80
|
+
project_id: env.EAS_BUILD_PROJECT_ID,
|
|
81
|
+
git_commit: env.EAS_BUILD_GIT_COMMIT_HASH,
|
|
82
|
+
from_ci: env.EAS_BUILD_RUN_FROM_CI === 'true',
|
|
83
|
+
status: env.EAS_BUILD_STATUS,
|
|
84
|
+
app_version: env.EAS_BUILD_APP_VERSION,
|
|
85
|
+
build_version: env.EAS_BUILD_APP_BUILD_VERSION,
|
|
86
|
+
username: env.EAS_BUILD_USERNAME,
|
|
87
|
+
working_dir: env.EAS_BUILD_WORKINGDIR,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function createEnvelope(event, dsn) {
|
|
91
|
+
const envelopeHeaders = JSON.stringify({
|
|
92
|
+
event_id: event.event_id,
|
|
93
|
+
sent_at: new Date().toISOString(),
|
|
94
|
+
dsn: (0, core_1.dsnToString)(dsn),
|
|
95
|
+
sdk: event.sdk,
|
|
96
|
+
});
|
|
97
|
+
const itemHeaders = JSON.stringify({ type: 'event', content_type: 'application/json' });
|
|
98
|
+
const itemPayload = JSON.stringify(event);
|
|
99
|
+
return `${envelopeHeaders}\n${itemHeaders}\n${itemPayload}`;
|
|
100
|
+
}
|
|
101
|
+
function sendEvent(event, dsn) {
|
|
102
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
103
|
+
const endpoint = getEnvelopeEndpoint(dsn);
|
|
104
|
+
const envelope = createEnvelope(event, dsn);
|
|
105
|
+
try {
|
|
106
|
+
const response = yield fetch(endpoint, {
|
|
107
|
+
method: 'POST',
|
|
108
|
+
headers: { 'Content-Type': 'application/x-sentry-envelope' },
|
|
109
|
+
body: envelope,
|
|
110
|
+
});
|
|
111
|
+
if (response.status >= 200 && response.status < 300)
|
|
112
|
+
return true;
|
|
113
|
+
console.warn(`[Sentry] Failed to send event: HTTP ${response.status}`);
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
console.error('[Sentry] Failed to send event:', error);
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
function getReleaseFromEASEnv(env) {
|
|
123
|
+
// Honour explicit override first
|
|
124
|
+
if (process.env.SENTRY_RELEASE) {
|
|
125
|
+
return process.env.SENTRY_RELEASE;
|
|
126
|
+
}
|
|
127
|
+
// Best approximation without bundle identifier: version+buildNumber
|
|
128
|
+
if (env.EAS_BUILD_APP_VERSION && env.EAS_BUILD_APP_BUILD_VERSION) {
|
|
129
|
+
return `${env.EAS_BUILD_APP_VERSION}+${env.EAS_BUILD_APP_BUILD_VERSION}`;
|
|
130
|
+
}
|
|
131
|
+
return env.EAS_BUILD_APP_VERSION;
|
|
132
|
+
}
|
|
133
|
+
function createBaseEvent(level, env, customTags) {
|
|
134
|
+
return {
|
|
135
|
+
event_id: (0, core_1.uuid4)(),
|
|
136
|
+
timestamp: Date.now() / 1000,
|
|
137
|
+
platform: 'node',
|
|
138
|
+
level,
|
|
139
|
+
logger: 'eas-build-hook',
|
|
140
|
+
environment: 'eas-build',
|
|
141
|
+
release: getReleaseFromEASEnv(env),
|
|
142
|
+
tags: Object.assign(Object.assign({}, createEASBuildTags(env)), customTags),
|
|
143
|
+
contexts: { eas_build: createEASBuildContext(env), runtime: { name: 'node', version: process.version } },
|
|
144
|
+
sdk: { name: 'sentry.javascript.react-native.eas-build-hooks', version: version_1.SDK_VERSION },
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
/** Captures an EAS build error event. Call this from the eas-build-on-error hook. */
|
|
148
|
+
function captureEASBuildError(options = {}) {
|
|
149
|
+
var _a, _b, _c, _d, _e, _f;
|
|
150
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
151
|
+
const dsnString = (_a = options.dsn) !== null && _a !== void 0 ? _a : process.env[SENTRY_DSN_ENV];
|
|
152
|
+
if (!dsnString) {
|
|
153
|
+
console.warn('[Sentry] No DSN provided. Set SENTRY_DSN environment variable or pass dsn option.');
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
if (!isEASBuild()) {
|
|
157
|
+
console.warn('[Sentry] Not running in EAS Build environment. Skipping error capture.');
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
const dsn = (0, core_1.makeDsn)(dsnString);
|
|
161
|
+
if (!dsn) {
|
|
162
|
+
console.error('[Sentry] Invalid DSN format.');
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
const env = getEASBuildEnv();
|
|
166
|
+
const errorMessage = (_b = options.errorMessage) !== null && _b !== void 0 ? _b : `EAS Build Failed: ${(_c = env.EAS_BUILD_PLATFORM) !== null && _c !== void 0 ? _c : 'unknown'} (${(_d = env.EAS_BUILD_PROFILE) !== null && _d !== void 0 ? _d : 'unknown'})`;
|
|
167
|
+
const event = createBaseEvent('error', env, Object.assign(Object.assign({}, options.tags), { 'eas.hook': 'on-error' }));
|
|
168
|
+
event.exception = {
|
|
169
|
+
values: [{ type: 'EASBuildError', value: errorMessage, mechanism: { type: 'eas-build-hook', handled: true } }],
|
|
170
|
+
};
|
|
171
|
+
event.fingerprint = ['eas-build-error', (_e = env.EAS_BUILD_PLATFORM) !== null && _e !== void 0 ? _e : 'unknown', (_f = env.EAS_BUILD_PROFILE) !== null && _f !== void 0 ? _f : 'unknown'];
|
|
172
|
+
const success = yield sendEvent(event, dsn);
|
|
173
|
+
if (success)
|
|
174
|
+
console.log('[Sentry] Build error captured.');
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
exports.captureEASBuildError = captureEASBuildError;
|
|
178
|
+
/** Captures an EAS build success event. Call this from the eas-build-on-success hook. */
|
|
179
|
+
function captureEASBuildSuccess(options = {}) {
|
|
180
|
+
var _a, _b, _c, _d, _e, _f;
|
|
181
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
182
|
+
if (!options.captureSuccessfulBuilds) {
|
|
183
|
+
console.log('[Sentry] Skipping successful build capture (captureSuccessfulBuilds is false).');
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
const dsnString = (_a = options.dsn) !== null && _a !== void 0 ? _a : process.env[SENTRY_DSN_ENV];
|
|
187
|
+
if (!dsnString) {
|
|
188
|
+
console.warn('[Sentry] No DSN provided. Set SENTRY_DSN environment variable or pass dsn option.');
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
if (!isEASBuild()) {
|
|
192
|
+
console.warn('[Sentry] Not running in EAS Build environment. Skipping success capture.');
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
const dsn = (0, core_1.makeDsn)(dsnString);
|
|
196
|
+
if (!dsn) {
|
|
197
|
+
console.error('[Sentry] Invalid DSN format.');
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
const env = getEASBuildEnv();
|
|
201
|
+
const successMessage = (_b = options.successMessage) !== null && _b !== void 0 ? _b : `EAS Build Succeeded: ${(_c = env.EAS_BUILD_PLATFORM) !== null && _c !== void 0 ? _c : 'unknown'} (${(_d = env.EAS_BUILD_PROFILE) !== null && _d !== void 0 ? _d : 'unknown'})`;
|
|
202
|
+
const event = createBaseEvent('info', env, Object.assign(Object.assign({}, options.tags), { 'eas.hook': 'on-success' }));
|
|
203
|
+
event.message = { formatted: successMessage };
|
|
204
|
+
event.fingerprint = ['eas-build-success', (_e = env.EAS_BUILD_PLATFORM) !== null && _e !== void 0 ? _e : 'unknown', (_f = env.EAS_BUILD_PROFILE) !== null && _f !== void 0 ? _f : 'unknown'];
|
|
205
|
+
const success = yield sendEvent(event, dsn);
|
|
206
|
+
if (success)
|
|
207
|
+
console.log('[Sentry] Build success captured.');
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
exports.captureEASBuildSuccess = captureEASBuildSuccess;
|
|
211
|
+
/** Captures an EAS build completion event with status. Call this from the eas-build-on-complete hook. */
|
|
212
|
+
function captureEASBuildComplete(options = {}) {
|
|
213
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
214
|
+
const env = getEASBuildEnv();
|
|
215
|
+
const status = env.EAS_BUILD_STATUS;
|
|
216
|
+
if (status === 'errored') {
|
|
217
|
+
yield captureEASBuildError(options);
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
if (status === 'finished' && options.captureSuccessfulBuilds) {
|
|
221
|
+
yield captureEASBuildSuccess(Object.assign(Object.assign({}, options), { captureSuccessfulBuilds: true }));
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
console.log(`[Sentry] Build completed with status: ${status !== null && status !== void 0 ? status : 'unknown'}. No event captured.`);
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
exports.captureEASBuildComplete = captureEASBuildComplete;
|
|
228
|
+
//# sourceMappingURL=easBuildHooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"easBuildHooks.js","sourceRoot":"","sources":["../../../src/js/tools/easBuildHooks.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * EAS Build Hooks for Sentry\n *\n * This module provides utilities for capturing EAS build lifecycle events\n * and sending them to Sentry. It supports the following EAS npm hooks:\n * - eas-build-on-error: Captures build failures\n * - eas-build-on-success: Captures successful builds (optional)\n * - eas-build-on-complete: Captures build completion with metrics\n *\n * @see https://docs.expo.dev/build-reference/npm-hooks/\n */\n\n/* eslint-disable no-console */\n\nimport type { DsnComponents } from '@sentry/core';\nimport { dsnToString, makeDsn, uuid4 } from '@sentry/core';\nimport { SDK_VERSION } from '../version';\n\nconst SENTRY_DSN_ENV = 'SENTRY_DSN';\nconst EAS_BUILD_ENV = 'EAS_BUILD';\n\n/**\n * Environment variables provided by EAS Build.\n * @see https://docs.expo.dev/build-reference/variables/\n */\nexport interface EASBuildEnv {\n EAS_BUILD?: string;\n EAS_BUILD_ID?: string;\n EAS_BUILD_PLATFORM?: string;\n EAS_BUILD_PROFILE?: string;\n EAS_BUILD_PROJECT_ID?: string;\n EAS_BUILD_GIT_COMMIT_HASH?: string;\n EAS_BUILD_RUN_FROM_CI?: string;\n EAS_BUILD_STATUS?: string;\n EAS_BUILD_APP_VERSION?: string;\n EAS_BUILD_APP_BUILD_VERSION?: string;\n EAS_BUILD_USERNAME?: string;\n EAS_BUILD_WORKINGDIR?: string;\n}\n\n/** Options for configuring EAS build hook behavior. */\nexport interface EASBuildHookOptions {\n dsn?: string;\n tags?: Record<string, string>;\n captureSuccessfulBuilds?: boolean;\n errorMessage?: string;\n successMessage?: string;\n}\n\ninterface SentryEvent {\n event_id: string;\n timestamp: number;\n platform: string;\n level: 'error' | 'info' | 'warning';\n logger: string;\n environment: string;\n release?: string;\n tags: Record<string, string>;\n contexts: Record<string, Record<string, unknown>>;\n message?: { formatted: string };\n exception?: {\n values: Array<{ type: string; value: string; mechanism: { type: string; handled: boolean } }>;\n };\n fingerprint?: string[];\n sdk: { name: string; version: string };\n}\n\n/** Checks if the current environment is an EAS Build. */\nexport function isEASBuild(): boolean {\n return process.env[EAS_BUILD_ENV] === 'true';\n}\n\n/** Gets the EAS build environment variables. */\nexport function getEASBuildEnv(): EASBuildEnv {\n return {\n EAS_BUILD: process.env.EAS_BUILD,\n EAS_BUILD_ID: process.env.EAS_BUILD_ID,\n EAS_BUILD_PLATFORM: process.env.EAS_BUILD_PLATFORM,\n EAS_BUILD_PROFILE: process.env.EAS_BUILD_PROFILE,\n EAS_BUILD_PROJECT_ID: process.env.EAS_BUILD_PROJECT_ID,\n EAS_BUILD_GIT_COMMIT_HASH: process.env.EAS_BUILD_GIT_COMMIT_HASH,\n EAS_BUILD_RUN_FROM_CI: process.env.EAS_BUILD_RUN_FROM_CI,\n EAS_BUILD_STATUS: process.env.EAS_BUILD_STATUS,\n EAS_BUILD_APP_VERSION: process.env.EAS_BUILD_APP_VERSION,\n EAS_BUILD_APP_BUILD_VERSION: process.env.EAS_BUILD_APP_BUILD_VERSION,\n EAS_BUILD_USERNAME: process.env.EAS_BUILD_USERNAME,\n EAS_BUILD_WORKINGDIR: process.env.EAS_BUILD_WORKINGDIR,\n };\n}\n\nfunction getEnvelopeEndpoint(dsn: DsnComponents): string {\n const { protocol, host, port, path, projectId, publicKey } = dsn;\n const portStr = port ? `:${port}` : '';\n const pathStr = path ? `/${path}` : '';\n return `${protocol}://${host}${portStr}${pathStr}/api/${projectId}/envelope/?sentry_key=${publicKey}&sentry_version=7`;\n}\n\nfunction createEASBuildTags(env: EASBuildEnv): Record<string, string> {\n const tags: Record<string, string> = {};\n if (env.EAS_BUILD_PLATFORM) tags['eas.platform'] = env.EAS_BUILD_PLATFORM;\n if (env.EAS_BUILD_PROFILE) tags['eas.profile'] = env.EAS_BUILD_PROFILE;\n if (env.EAS_BUILD_ID) tags['eas.build_id'] = env.EAS_BUILD_ID;\n if (env.EAS_BUILD_PROJECT_ID) tags['eas.project_id'] = env.EAS_BUILD_PROJECT_ID;\n if (env.EAS_BUILD_RUN_FROM_CI) tags['eas.from_ci'] = env.EAS_BUILD_RUN_FROM_CI;\n if (env.EAS_BUILD_STATUS) tags['eas.status'] = env.EAS_BUILD_STATUS;\n if (env.EAS_BUILD_USERNAME) tags['eas.username'] = env.EAS_BUILD_USERNAME;\n return tags;\n}\n\nfunction createEASBuildContext(env: EASBuildEnv): Record<string, unknown> {\n return {\n build_id: env.EAS_BUILD_ID,\n platform: env.EAS_BUILD_PLATFORM,\n profile: env.EAS_BUILD_PROFILE,\n project_id: env.EAS_BUILD_PROJECT_ID,\n git_commit: env.EAS_BUILD_GIT_COMMIT_HASH,\n from_ci: env.EAS_BUILD_RUN_FROM_CI === 'true',\n status: env.EAS_BUILD_STATUS,\n app_version: env.EAS_BUILD_APP_VERSION,\n build_version: env.EAS_BUILD_APP_BUILD_VERSION,\n username: env.EAS_BUILD_USERNAME,\n working_dir: env.EAS_BUILD_WORKINGDIR,\n };\n}\n\nfunction createEnvelope(event: SentryEvent, dsn: DsnComponents): string {\n const envelopeHeaders = JSON.stringify({\n event_id: event.event_id,\n sent_at: new Date().toISOString(),\n dsn: dsnToString(dsn),\n sdk: event.sdk,\n });\n const itemHeaders = JSON.stringify({ type: 'event', content_type: 'application/json' });\n const itemPayload = JSON.stringify(event);\n return `${envelopeHeaders}\\n${itemHeaders}\\n${itemPayload}`;\n}\n\nasync function sendEvent(event: SentryEvent, dsn: DsnComponents): Promise<boolean> {\n const endpoint = getEnvelopeEndpoint(dsn);\n const envelope = createEnvelope(event, dsn);\n try {\n const response = await fetch(endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-sentry-envelope' },\n body: envelope,\n });\n if (response.status >= 200 && response.status < 300) return true;\n console.warn(`[Sentry] Failed to send event: HTTP ${response.status}`);\n return false;\n } catch (error) {\n console.error('[Sentry] Failed to send event:', error);\n return false;\n }\n}\n\nfunction getReleaseFromEASEnv(env: EASBuildEnv): string | undefined {\n // Honour explicit override first\n if (process.env.SENTRY_RELEASE) {\n return process.env.SENTRY_RELEASE;\n }\n // Best approximation without bundle identifier: version+buildNumber\n if (env.EAS_BUILD_APP_VERSION && env.EAS_BUILD_APP_BUILD_VERSION) {\n return `${env.EAS_BUILD_APP_VERSION}+${env.EAS_BUILD_APP_BUILD_VERSION}`;\n }\n return env.EAS_BUILD_APP_VERSION;\n}\n\nfunction createBaseEvent(\n level: 'error' | 'info' | 'warning',\n env: EASBuildEnv,\n customTags?: Record<string, string>,\n): SentryEvent {\n return {\n event_id: uuid4(),\n timestamp: Date.now() / 1000,\n platform: 'node',\n level,\n logger: 'eas-build-hook',\n environment: 'eas-build',\n release: getReleaseFromEASEnv(env),\n tags: { ...createEASBuildTags(env), ...customTags },\n contexts: { eas_build: createEASBuildContext(env), runtime: { name: 'node', version: process.version } },\n sdk: { name: 'sentry.javascript.react-native.eas-build-hooks', version: SDK_VERSION },\n };\n}\n\n/** Captures an EAS build error event. Call this from the eas-build-on-error hook. */\nexport async function captureEASBuildError(options: EASBuildHookOptions = {}): Promise<void> {\n const dsnString = options.dsn ?? process.env[SENTRY_DSN_ENV];\n if (!dsnString) {\n console.warn('[Sentry] No DSN provided. Set SENTRY_DSN environment variable or pass dsn option.');\n return;\n }\n if (!isEASBuild()) {\n console.warn('[Sentry] Not running in EAS Build environment. Skipping error capture.');\n return;\n }\n const dsn = makeDsn(dsnString);\n if (!dsn) {\n console.error('[Sentry] Invalid DSN format.');\n return;\n }\n const env = getEASBuildEnv();\n const errorMessage =\n options.errorMessage ??\n `EAS Build Failed: ${env.EAS_BUILD_PLATFORM ?? 'unknown'} (${env.EAS_BUILD_PROFILE ?? 'unknown'})`;\n const event = createBaseEvent('error', env, { ...options.tags, 'eas.hook': 'on-error' });\n event.exception = {\n values: [{ type: 'EASBuildError', value: errorMessage, mechanism: { type: 'eas-build-hook', handled: true } }],\n };\n event.fingerprint = ['eas-build-error', env.EAS_BUILD_PLATFORM ?? 'unknown', env.EAS_BUILD_PROFILE ?? 'unknown'];\n const success = await sendEvent(event, dsn);\n if (success) console.log('[Sentry] Build error captured.');\n}\n\n/** Captures an EAS build success event. Call this from the eas-build-on-success hook. */\nexport async function captureEASBuildSuccess(options: EASBuildHookOptions = {}): Promise<void> {\n if (!options.captureSuccessfulBuilds) {\n console.log('[Sentry] Skipping successful build capture (captureSuccessfulBuilds is false).');\n return;\n }\n const dsnString = options.dsn ?? process.env[SENTRY_DSN_ENV];\n if (!dsnString) {\n console.warn('[Sentry] No DSN provided. Set SENTRY_DSN environment variable or pass dsn option.');\n return;\n }\n if (!isEASBuild()) {\n console.warn('[Sentry] Not running in EAS Build environment. Skipping success capture.');\n return;\n }\n const dsn = makeDsn(dsnString);\n if (!dsn) {\n console.error('[Sentry] Invalid DSN format.');\n return;\n }\n const env = getEASBuildEnv();\n const successMessage =\n options.successMessage ??\n `EAS Build Succeeded: ${env.EAS_BUILD_PLATFORM ?? 'unknown'} (${env.EAS_BUILD_PROFILE ?? 'unknown'})`;\n const event = createBaseEvent('info', env, { ...options.tags, 'eas.hook': 'on-success' });\n event.message = { formatted: successMessage };\n event.fingerprint = ['eas-build-success', env.EAS_BUILD_PLATFORM ?? 'unknown', env.EAS_BUILD_PROFILE ?? 'unknown'];\n const success = await sendEvent(event, dsn);\n if (success) console.log('[Sentry] Build success captured.');\n}\n\n/** Captures an EAS build completion event with status. Call this from the eas-build-on-complete hook. */\nexport async function captureEASBuildComplete(options: EASBuildHookOptions = {}): Promise<void> {\n const env = getEASBuildEnv();\n const status = env.EAS_BUILD_STATUS;\n if (status === 'errored') {\n await captureEASBuildError(options);\n return;\n }\n if (status === 'finished' && options.captureSuccessfulBuilds) {\n await captureEASBuildSuccess({ ...options, captureSuccessfulBuilds: true });\n return;\n }\n console.log(`[Sentry] Build completed with status: ${status ?? 'unknown'}. No event captured.`);\n}\n"]}
|
|
@@ -62,6 +62,10 @@ export declare function withSentryBabelTransformer(config: MetroConfig, annotate
|
|
|
62
62
|
* Includes `@sentry/replay` packages based on the `includeWebReplay` flag and current bundle `platform`.
|
|
63
63
|
*/
|
|
64
64
|
export declare function withSentryResolver(config: MetroConfig, includeWebReplay: boolean | undefined): MetroConfig;
|
|
65
|
+
/**
|
|
66
|
+
* Excludes server-only AI/MCP modules from native (Android/iOS) bundles.
|
|
67
|
+
*/
|
|
68
|
+
export declare function withSentryExcludeServerOnlyResolver(config: MetroConfig): MetroConfig;
|
|
65
69
|
/**
|
|
66
70
|
* Collapses Sentry internal frames from the stack trace view in LogBox.
|
|
67
71
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metroconfig.d.ts","sourceRoot":"","sources":["../../../src/js/tools/metroconfig.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAsC,MAAM,OAAO,CAAC;AAc7E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAErE,cAAc,yBAAyB,CAAC;AAIxC,MAAM,WAAW,wBAAwB;IACvC;;;OAGG;IACH,uBAAuB,CAAC,EACpB,OAAO,GACP;QACE,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;KAC9B,CAAC;IACN;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;OAIG;IACH,gCAAgC,CAAC,EAAE,OAAO,CAAC;IAC3C;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CAChC;AAED,MAAM,WAAW,uBAAuB;IACtC;;OAEG;IACH,gBAAgB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEvG;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,WAAW,EACnB,EACE,uBAA+B,EAC/B,gBAAuB,EACvB,gCAAuC,EACvC,WAAkB,GACnB,GAAE,wBAA6B,GAC/B,WAAW,
|
|
1
|
+
{"version":3,"file":"metroconfig.d.ts","sourceRoot":"","sources":["../../../src/js/tools/metroconfig.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAsC,MAAM,OAAO,CAAC;AAc7E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAErE,cAAc,yBAAyB,CAAC;AAIxC,MAAM,WAAW,wBAAwB;IACvC;;;OAGG;IACH,uBAAuB,CAAC,EACpB,OAAO,GACP;QACE,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;KAC9B,CAAC;IACN;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;OAIG;IACH,gCAAgC,CAAC,EAAE,OAAO,CAAC;IAC3C;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CAChC;AAED,MAAM,WAAW,uBAAuB;IACtC;;OAEG;IACH,gBAAgB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEvG;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,WAAW,EACnB,EACE,uBAA+B,EAC/B,gBAAuB,EACvB,gCAAuC,EACvC,WAAkB,GACnB,GAAE,wBAA6B,GAC/B,WAAW,CAsBb;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,oBAAoB,GAAG,uBAAuB,GAAG,wBAA6B,GACtF,WAAW,CAgCb;AAsBD;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,WAAW,EACnB,uBAAuB,EAAE,IAAI,GAAG;IAAE,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,GAC/D,WAAW,CA8Bb;AA0BD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,EAAE,gBAAgB,EAAE,OAAO,GAAG,SAAS,GAAG,WAAW,CA+C1G;AAgBD;;GAEG;AACH,wBAAgB,mCAAmC,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,CA4CpF;AAQD;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,CAiC1E"}
|
|
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.withSentryFramesCollapsed = exports.withSentryResolver = exports.withSentryBabelTransformer = exports.getSentryExpoConfig = exports.withSentryConfig = void 0;
|
|
17
|
+
exports.withSentryFramesCollapsed = exports.withSentryExcludeServerOnlyResolver = exports.withSentryResolver = exports.withSentryBabelTransformer = exports.getSentryExpoConfig = exports.withSentryConfig = void 0;
|
|
18
18
|
const core_1 = require("@sentry/core");
|
|
19
19
|
const process = require("process");
|
|
20
20
|
const process_1 = require("process");
|
|
@@ -43,6 +43,7 @@ function withSentryConfig(config, { annotateReactComponents = false, includeWebR
|
|
|
43
43
|
if (includeWebReplay === false) {
|
|
44
44
|
newConfig = withSentryResolver(newConfig, includeWebReplay);
|
|
45
45
|
}
|
|
46
|
+
newConfig = withSentryExcludeServerOnlyResolver(newConfig);
|
|
46
47
|
if (enableSourceContextInDevelopment) {
|
|
47
48
|
newConfig = (0, metroMiddleware_1.withSentryMiddleware)(newConfig);
|
|
48
49
|
}
|
|
@@ -71,6 +72,7 @@ function getSentryExpoConfig(projectRoot, options = {}) {
|
|
|
71
72
|
if (options.includeWebReplay === false) {
|
|
72
73
|
newConfig = withSentryResolver(newConfig, options.includeWebReplay);
|
|
73
74
|
}
|
|
75
|
+
newConfig = withSentryExcludeServerOnlyResolver(newConfig);
|
|
74
76
|
if ((_b = options.enableSourceContextInDevelopment) !== null && _b !== void 0 ? _b : true) {
|
|
75
77
|
newConfig = (0, metroMiddleware_1.withSentryMiddleware)(newConfig);
|
|
76
78
|
}
|
|
@@ -156,6 +158,49 @@ Please follow one of the following options:
|
|
|
156
158
|
return Object.assign(Object.assign({}, config), { resolver: Object.assign(Object.assign({}, config.resolver), { resolveRequest: sentryResolverRequest }) });
|
|
157
159
|
}
|
|
158
160
|
exports.withSentryResolver = withSentryResolver;
|
|
161
|
+
/**
|
|
162
|
+
* Matches relative import paths to server-only AI/MCP modules within `@sentry/core`.
|
|
163
|
+
*
|
|
164
|
+
* Metro passes the module name as-written in the source code, so for imports inside
|
|
165
|
+
* `@sentry/core`'s barrel file like `export { ... } from './integrations/mcp-server/index.js'`,
|
|
166
|
+
* the `moduleName` will be `./integrations/mcp-server/index.js`.
|
|
167
|
+
*/
|
|
168
|
+
const SERVER_ONLY_MODULE_RE = /\/(mcp-server|tracing\/(vercel-ai|openai|anthropic-ai|google-genai|langchain|langgraph)|utils\/ai)(\/|$)/;
|
|
169
|
+
function isFromSentryCore(originModulePath) {
|
|
170
|
+
return originModulePath.includes('@sentry/core');
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Excludes server-only AI/MCP modules from native (Android/iOS) bundles.
|
|
174
|
+
*/
|
|
175
|
+
function withSentryExcludeServerOnlyResolver(config) {
|
|
176
|
+
var _a;
|
|
177
|
+
const originalResolver = (_a = config.resolver) === null || _a === void 0 ? void 0 : _a.resolveRequest;
|
|
178
|
+
const sentryServerOnlyResolverRequest = (context, moduleName, platform, oldMetroModuleName) => {
|
|
179
|
+
var _a;
|
|
180
|
+
if ((platform === 'android' || platform === 'ios') &&
|
|
181
|
+
isFromSentryCore((_a = context.originModulePath) !== null && _a !== void 0 ? _a : '') &&
|
|
182
|
+
SERVER_ONLY_MODULE_RE.test(oldMetroModuleName !== null && oldMetroModuleName !== void 0 ? oldMetroModuleName : moduleName)) {
|
|
183
|
+
return { type: 'empty' };
|
|
184
|
+
}
|
|
185
|
+
if (originalResolver) {
|
|
186
|
+
return oldMetroModuleName
|
|
187
|
+
? originalResolver(context, moduleName, platform, oldMetroModuleName)
|
|
188
|
+
: originalResolver(context, moduleName, platform);
|
|
189
|
+
}
|
|
190
|
+
// Prior 0.68, context.resolveRequest is sentryServerOnlyResolverRequest itself, which would cause infinite recursion.
|
|
191
|
+
if (context.resolveRequest === sentryServerOnlyResolverRequest) {
|
|
192
|
+
// eslint-disable-next-line no-console
|
|
193
|
+
console.error(`Error: [@sentry/react-native/metro] Can not resolve the defaultResolver on Metro older than 0.68.
|
|
194
|
+
Please include your resolverRequest on your metroconfig or update your Metro version to 0.68 or higher.
|
|
195
|
+
If you are still facing issues, report the issue at http://www.github.com/getsentry/sentry-react-native/issues`);
|
|
196
|
+
// Return required for test.
|
|
197
|
+
return process.exit(-1);
|
|
198
|
+
}
|
|
199
|
+
return context.resolveRequest(context, moduleName, platform);
|
|
200
|
+
};
|
|
201
|
+
return Object.assign(Object.assign({}, config), { resolver: Object.assign(Object.assign({}, config.resolver), { resolveRequest: sentryServerOnlyResolverRequest }) });
|
|
202
|
+
}
|
|
203
|
+
exports.withSentryExcludeServerOnlyResolver = withSentryExcludeServerOnlyResolver;
|
|
159
204
|
/**
|
|
160
205
|
* Collapses Sentry internal frames from the stack trace view in LogBox.
|
|
161
206
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metroconfig.js","sourceRoot":"","sources":["../../../src/js/tools/metroconfig.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,uCAAqC;AAGrC,mCAAmC;AACnC,qCAA8B;AAC9B,iDAA8C;AAC9C,uDAAyD;AACzD,+EAGuC;AACvC,mEAAqH;AACrH,uEAAsE;AACtE,mEAAyE;AAIzE,0DAAwC;AAExC,IAAA,2BAAY,GAAE,CAAC;AA+Cf;;;;;GAKG;AACH,SAAgB,gBAAgB,CAC9B,MAAmB,EACnB,EACE,uBAAuB,GAAG,KAAK,EAC/B,gBAAgB,GAAG,IAAI,EACvB,gCAAgC,GAAG,IAAI,EACvC,WAAW,GAAG,IAAI,MACU,EAAE;IAEhC,8BAA8B,EAAE,CAAC;IAEjC,IAAI,SAAS,GAAG,MAAM,CAAC;IAEvB,SAAS,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;IACzC,SAAS,GAAG,yBAAyB,CAAC,SAAS,CAAC,CAAC;IACjD,IAAI,uBAAuB,EAAE;QAC3B,SAAS,GAAG,0BAA0B,CAAC,SAAS,EAAE,uBAAuB,CAAC,CAAC;KAC5E;IACD,IAAI,gBAAgB,KAAK,KAAK,EAAE;QAC9B,SAAS,GAAG,kBAAkB,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;KAC7D;IACD,IAAI,gCAAgC,EAAE;QACpC,SAAS,GAAG,IAAA,sCAAoB,EAAC,SAAS,CAAC,CAAC;KAC7C;IACD,IAAI,WAAW,EAAE;QACf,SAAS,GAAG,IAAA,mDAAyB,EAAC,SAAS,EAAE,WAAW,CAAC,CAAC;KAC/D;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AA7BD,4CA6BC;AAED;;GAEG;AACH,SAAgB,mBAAmB,CACjC,WAAmB,EACnB,UAAqF,EAAE;;IAEvF,8BAA8B,EAAE,CAAC;IAEjC,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,IAAI,yBAAyB,EAAE,CAAC,gBAAgB,CAAC;IAClG,MAAM,MAAM,GAAG,gBAAgB,CAAC,WAAW,kCACtC,OAAO,KACV,wCAAwC,EAAE;YACxC,GAAG,CAAC,OAAO,CAAC,wCAAwC,IAAI,EAAE,CAAC;YAC3D,GAAG,CAAC,CAAA,MAAA,OAAO,CAAC,mBAAmB,mCAAI,IAAI,EAAC,CAAC,CAAC,CAAC,IAAA,sDAA8B,EAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7F,qEAA6C;SAC9C,IACD,CAAC;IAEH,IAAI,SAAS,GAAG,yBAAyB,CAAC,MAAM,CAAC,CAAC;IAClD,IAAI,OAAO,CAAC,uBAAuB,EAAE;QACnC,SAAS,GAAG,0BAA0B,CAAC,SAAS,EAAE,OAAO,CAAC,uBAAuB,CAAC,CAAC;KACpF;IAED,IAAI,OAAO,CAAC,gBAAgB,KAAK,KAAK,EAAE;QACtC,SAAS,GAAG,kBAAkB,CAAC,SAAS,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;KACrE;IAED,IAAI,MAAA,OAAO,CAAC,gCAAgC,mCAAI,IAAI,EAAE;QACpD,SAAS,GAAG,IAAA,sCAAoB,EAAC,SAAS,CAAC,CAAC;KAC7C;IAED,IAAI,MAAA,OAAO,CAAC,WAAW,mCAAI,IAAI,EAAE;QAC/B,SAAS,GAAG,IAAA,mDAAyB,EAAC,SAAS,EAAE,MAAA,OAAO,CAAC,WAAW,mCAAI,IAAI,CAAC,CAAC;KAC/E;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAlCD,kDAkCC;AAED,SAAS,yBAAyB;IAYhC,IAAI;QACF,8DAA8D;QAC9D,OAAO,OAAO,CAAC,mBAAmB,CAAC,CAAC;KACrC;IAAC,OAAO,CAAC,EAAE;QACV,MAAM,IAAI,KAAK,CAAC,wEAAwE,CAAC,CAAC;KAC3F;AACH,CAAC;AAED;;GAEG;AACH,SAAgB,0BAA0B,CACxC,MAAmB,EACnB,uBAAgE;;IAEhE,MAAM,2BAA2B,GAAG,MAAA,MAAM,CAAC,WAAW,0CAAE,oBAAoB,CAAC;IAC7E,YAAK,CAAC,GAAG,CAAC,2DAA2D,EAAE,2BAA2B,CAAC,CAAC;IAEpG,IAAI,CAAC,2BAA2B,EAAE;QAChC,+EAA+E;QAC/E,sCAAsC;QACtC,OAAO,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAC;QACjE,sCAAsC;QACtC,OAAO,CAAC,IAAI,CAAC,2DAA2D,CAAC,CAAC;QAC1E,OAAO,MAAM,CAAC;KACf;IAED,IAAI,2BAA2B,EAAE;QAC/B,IAAA,qEAAuC,EAAC,2BAA2B,CAAC,CAAC;KACtE;IAED,IAAI,OAAO,uBAAuB,KAAK,QAAQ,EAAE;QAC/C,IAAA,8DAAgC,EAAC;YAC/B,uBAAuB;SACxB,CAAC,CAAC;KACJ;IAED,uCACK,MAAM,KACT,WAAW,kCACN,MAAM,CAAC,WAAW,KACrB,oBAAoB,EAAE,OAAO,CAAC,OAAO,CAAC,0BAA0B,CAAC,OAEnE;AACJ,CAAC;AAjCD,gEAiCC;AAED,SAAS,iBAAiB,CAAC,MAAmB;;IAC5C,MAAM,gBAAgB,GAAG,IAAA,mDAA2B,EAClD,CAAA,MAAA,MAAM,CAAC,UAAU,0CAAE,gBAAgB,KAAI,SAAS,CACxB,CAAC;IAC3B,yFAAyF;IACzF,iCAAiC;IAEjC,uCACK,MAAM,KACT,UAAU,kCACL,MAAM,CAAC,UAAU,KACpB,gBAAgB,OAElB;AACJ,CAAC;AAUD;;GAEG;AACH,SAAgB,kBAAkB,CAAC,MAAmB,EAAE,gBAAqC;;IAC3F,MAAM,gBAAgB,GAAG,MAAA,MAAM,CAAC,QAAQ,0CAAE,cAA2E,CAAC;IAEtH,MAAM,qBAAqB,GAAmB,CAC5C,OAAgC,EAChC,UAAkB,EAClB,QAAuB,EACvB,kBAA2B,EAC3B,EAAE;QACF,IACE,CAAC,gBAAgB,KAAK,KAAK;YACzB,CAAC,gBAAgB,KAAK,SAAS,IAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC;YACrF,CAAC,CAAC,CAAC,kBAAkB,aAAlB,kBAAkB,cAAlB,kBAAkB,GAAI,UAAU,CAAC,CAAC,KAAK,CAAC,+BAA+B,CAAC,EAC3E;YACA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAgB,CAAC;SACxC;QACD,IAAI,gBAAgB,EAAE;YACpB,OAAO,kBAAkB;gBACvB,CAAC,CAAC,gBAAgB,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,kBAAkB,CAAC;gBACrE,CAAC,CAAC,gBAAgB,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;SACrD;QAED,0HAA0H;QAC1H,IAAI,OAAO,CAAC,cAAc,KAAK,qBAAqB,EAAE;YACpD,sCAAsC;YACtC,OAAO,CAAC,KAAK,CACX;;;;;iHAKyG,CAC1G,CAAC;YACF,4BAA4B;YAC5B,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;SACzB;QAED,OAAO,OAAO,CAAC,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;IAC/D,CAAC,CAAC;IAEF,uCACK,MAAM,KACT,QAAQ,kCACH,MAAM,CAAC,QAAQ,KAClB,cAAc,EAAE,qBAAqB,OAEvC;AACJ,CAAC;AA/CD,gDA+CC;AAQD;;GAEG;AACH,SAAgB,yBAAyB,CAAC,MAAmB;;IAC3D,MAAM,sBAAsB,GAAG,MAAA,MAAM,CAAC,YAAY,0CAAE,cAAc,CAAC;IACnE,MAAM,4BAA4B,GAAG,CAAC,KAAiB,EAAW,EAAE,CAClE,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;QAC9B,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,6CAA6C,CAAC;YACjE,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,wCAAwC,CAAC,CAAC,CAAC;IAEnE,MAAM,cAAc,GAAG,CAAC,KAAiB,EAAkC,EAAE;QAC3E,MAAM,8BAA8B,GAAG,CACrC,qBAAsD,EACjC,EAAE,CAAC,iCACrB,qBAAqB,KACxB,QAAQ,EAAE,CAAA,qBAAqB,aAArB,qBAAqB,uBAArB,qBAAqB,CAAE,QAAQ,KAAI,4BAA4B,CAAC,KAAK,CAAC,IAChF,CAAC;QAEH,MAAM,yBAAyB,GAAG,CAAA,sBAAsB,aAAtB,sBAAsB,uBAAtB,sBAAsB,CAAG,KAAK,CAAC,KAAI,SAAS,CAAC;QAE/E,IAAI,yBAAyB,KAAK,SAAS,IAAI,MAAM,IAAI,yBAAyB,EAAE;YAClF,OAAO,yBAAyB,CAAC,IAAI,CAAsB,qBAAqB,CAAC,EAAE,CACjF,8BAA8B,CAAC,qBAAqB,CAAC,CACtD,CAAC;SACH;QAED,OAAO,8BAA8B,CAAC,yBAAyB,CAAC,CAAC;IACnE,CAAC,CAAC;IAEF,uCACK,MAAM,KACT,YAAY,kCACP,MAAM,CAAC,YAAY,KACtB,cAAc,OAEhB;AACJ,CAAC;AAjCD,8DAiCC;AAED;;;;GAIG;AACH,SAAS,8BAA8B;IACrC,aAAG,CAAC,6BAA6B,GAAG,MAAM,CAAC;AAC7C,CAAC","sourcesContent":["import { debug } from '@sentry/core';\nimport type { MetroConfig, MixedOutput, Module, ReadOnlyGraph } from 'metro';\nimport type { CustomResolutionContext, CustomResolver, Resolution } from 'metro-resolver';\nimport * as process from 'process';\nimport { env } from 'process';\nimport { enableLogger } from './enableLogger';\nimport { withSentryMiddleware } from './metroMiddleware';\nimport {\n setSentryBabelTransformerOptions,\n setSentryDefaultBabelTransformerPathEnv,\n} from './sentryBabelTransformerUtils';\nimport { createSentryMetroSerializer, unstableBeforeAssetSerializationDebugIdPlugin } from './sentryMetroSerializer';\nimport { withSentryOptionsFromFile } from './sentryOptionsSerializer';\nimport { unstableReleaseConstantsPlugin } from './sentryReleaseInjector';\nimport type { MetroCustomSerializer } from './utils';\nimport type { DefaultConfigOptions } from './vendor/expo/expoconfig';\n\nexport * from './sentryMetroSerializer';\n\nenableLogger();\n\nexport interface SentryMetroConfigOptions {\n /**\n * Annotates React components with Sentry data.\n * @default false\n */\n annotateReactComponents?:\n | boolean\n | {\n ignoredComponents?: string[];\n };\n /**\n * Adds the Sentry replay package for web.\n * @default true\n */\n includeWebReplay?: boolean;\n /**\n * Add Sentry Metro Server Middleware which\n * enables the app to fetch stack frames source context.\n * @default true\n */\n enableSourceContextInDevelopment?: boolean;\n /**\n * Load Sentry Options from a file. If `true` it will use the default path.\n * If `false` it will not load any options from a file. Only options provided in the code will be used.\n * If `string` it will use the provided path.\n *\n * @default '{projectRoot}/sentry.options.json'\n */\n optionsFile?: string | boolean;\n}\n\nexport interface SentryExpoConfigOptions {\n /**\n * Pass a custom `getDefaultConfig` function to override the default Expo configuration getter.\n */\n getDefaultConfig?: (projectRoot: string, options?: Record<string, unknown>) => Record<string, unknown>;\n\n /**\n * For Expo Web, inject `release` and `version` options from `app.json`, the Expo Application Config.\n *\n * @default true\n */\n injectReleaseForWeb?: boolean;\n}\n\n/**\n * Adds Sentry to the Metro config.\n *\n * Adds Debug ID to the output bundle and source maps.\n * Collapses Sentry frames from the stack trace view in LogBox.\n */\nexport function withSentryConfig(\n config: MetroConfig,\n {\n annotateReactComponents = false,\n includeWebReplay = true,\n enableSourceContextInDevelopment = true,\n optionsFile = true,\n }: SentryMetroConfigOptions = {},\n): MetroConfig {\n setSentryMetroDevServerEnvFlag();\n\n let newConfig = config;\n\n newConfig = withSentryDebugId(newConfig);\n newConfig = withSentryFramesCollapsed(newConfig);\n if (annotateReactComponents) {\n newConfig = withSentryBabelTransformer(newConfig, annotateReactComponents);\n }\n if (includeWebReplay === false) {\n newConfig = withSentryResolver(newConfig, includeWebReplay);\n }\n if (enableSourceContextInDevelopment) {\n newConfig = withSentryMiddleware(newConfig);\n }\n if (optionsFile) {\n newConfig = withSentryOptionsFromFile(newConfig, optionsFile);\n }\n\n return newConfig;\n}\n\n/**\n * This function returns Default Expo configuration with Sentry plugins.\n */\nexport function getSentryExpoConfig(\n projectRoot: string,\n options: DefaultConfigOptions & SentryExpoConfigOptions & SentryMetroConfigOptions = {},\n): MetroConfig {\n setSentryMetroDevServerEnvFlag();\n\n const getDefaultConfig = options.getDefaultConfig || loadExpoMetroConfigModule().getDefaultConfig;\n const config = getDefaultConfig(projectRoot, {\n ...options,\n unstable_beforeAssetSerializationPlugins: [\n ...(options.unstable_beforeAssetSerializationPlugins || []),\n ...(options.injectReleaseForWeb ?? true ? [unstableReleaseConstantsPlugin(projectRoot)] : []),\n unstableBeforeAssetSerializationDebugIdPlugin,\n ],\n });\n\n let newConfig = withSentryFramesCollapsed(config);\n if (options.annotateReactComponents) {\n newConfig = withSentryBabelTransformer(newConfig, options.annotateReactComponents);\n }\n\n if (options.includeWebReplay === false) {\n newConfig = withSentryResolver(newConfig, options.includeWebReplay);\n }\n\n if (options.enableSourceContextInDevelopment ?? true) {\n newConfig = withSentryMiddleware(newConfig);\n }\n\n if (options.optionsFile ?? true) {\n newConfig = withSentryOptionsFromFile(newConfig, options.optionsFile ?? true);\n }\n\n return newConfig;\n}\n\nfunction loadExpoMetroConfigModule(): {\n getDefaultConfig: (\n projectRoot: string,\n options: {\n unstable_beforeAssetSerializationPlugins?: ((serializationInput: {\n graph: ReadOnlyGraph<MixedOutput>;\n premodules: Module[];\n debugId?: string;\n }) => Module[])[];\n },\n ) => MetroConfig;\n} {\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n return require('expo/metro-config');\n } catch (e) {\n throw new Error('Unable to load `expo/metro-config`. Make sure you have Expo installed.');\n }\n}\n\n/**\n * Adds Sentry Babel transformer to the Metro config.\n */\nexport function withSentryBabelTransformer(\n config: MetroConfig,\n annotateReactComponents: true | { ignoredComponents?: string[] },\n): MetroConfig {\n const defaultBabelTransformerPath = config.transformer?.babelTransformerPath;\n debug.log('Default Babel transformer path from `config.transformer`:', defaultBabelTransformerPath);\n\n if (!defaultBabelTransformerPath) {\n // This has to be console.warn because the options is enabled but won't be used\n // eslint-disable-next-line no-console\n console.warn('`transformer.babelTransformerPath` is undefined.');\n // eslint-disable-next-line no-console\n console.warn('Sentry Babel transformer cannot be used. Not adding it...');\n return config;\n }\n\n if (defaultBabelTransformerPath) {\n setSentryDefaultBabelTransformerPathEnv(defaultBabelTransformerPath);\n }\n\n if (typeof annotateReactComponents === 'object') {\n setSentryBabelTransformerOptions({\n annotateReactComponents,\n });\n }\n\n return {\n ...config,\n transformer: {\n ...config.transformer,\n babelTransformerPath: require.resolve('./sentryBabelTransformer'),\n },\n };\n}\n\nfunction withSentryDebugId(config: MetroConfig): MetroConfig {\n const customSerializer = createSentryMetroSerializer(\n config.serializer?.customSerializer || undefined,\n ) as MetroCustomSerializer;\n // MetroConfig types customSerializers as async only, but sync returns are also supported\n // The default serializer is sync\n\n return {\n ...config,\n serializer: {\n ...config.serializer,\n customSerializer,\n },\n };\n}\n\n// Based on: https://github.com/facebook/metro/blob/c21daba415ea26511e157f794689caab9abe8236/packages/metro-resolver/src/resolve.js#L86-L91\ntype CustomResolverBeforeMetro068 = (\n context: CustomResolutionContext,\n realModuleName: string,\n platform: string | null,\n moduleName?: string,\n) => Resolution;\n\n/**\n * Includes `@sentry/replay` packages based on the `includeWebReplay` flag and current bundle `platform`.\n */\nexport function withSentryResolver(config: MetroConfig, includeWebReplay: boolean | undefined): MetroConfig {\n const originalResolver = config.resolver?.resolveRequest as CustomResolver | CustomResolverBeforeMetro068 | undefined;\n\n const sentryResolverRequest: CustomResolver = (\n context: CustomResolutionContext,\n moduleName: string,\n platform: string | null,\n oldMetroModuleName?: string,\n ) => {\n if (\n (includeWebReplay === false ||\n (includeWebReplay === undefined && (platform === 'android' || platform === 'ios'))) &&\n !!(oldMetroModuleName ?? moduleName).match(/@sentry(?:-internal)?\\/replay/)\n ) {\n return { type: 'empty' } as Resolution;\n }\n if (originalResolver) {\n return oldMetroModuleName\n ? originalResolver(context, moduleName, platform, oldMetroModuleName)\n : originalResolver(context, moduleName, platform);\n }\n\n // Prior 0.68, resolve context.resolveRequest is sentryResolver itself, where on later version it is the default resolver.\n if (context.resolveRequest === sentryResolverRequest) {\n // eslint-disable-next-line no-console\n console.error(\n `Error: [@sentry/react-native/metro] Can not resolve the defaultResolver on Metro older than 0.68.\nPlease follow one of the following options:\n- Include your resolverRequest on your metroconfig.\n- Update your Metro version to 0.68 or higher.\n- Set includeWebReplay as true on your metro config.\n- If you are still facing issues, report the issue at http://www.github.com/getsentry/sentry-react-native/issues`,\n );\n // Return required for test.\n return process.exit(-1);\n }\n\n return context.resolveRequest(context, moduleName, platform);\n };\n\n return {\n ...config,\n resolver: {\n ...config.resolver,\n resolveRequest: sentryResolverRequest,\n },\n };\n}\n\ntype MetroFrame = Parameters<Required<Required<MetroConfig>['symbolicator']>['customizeFrame']>[0];\ntype MetroCustomizeFrame = { readonly collapse?: boolean };\ntype MetroCustomizeFrameReturnValue =\n | ReturnType<Required<Required<MetroConfig>['symbolicator']>['customizeFrame']>\n | undefined;\n\n/**\n * Collapses Sentry internal frames from the stack trace view in LogBox.\n */\nexport function withSentryFramesCollapsed(config: MetroConfig): MetroConfig {\n const originalCustomizeFrame = config.symbolicator?.customizeFrame;\n const collapseSentryInternalFrames = (frame: MetroFrame): boolean =>\n typeof frame.file === 'string' &&\n (frame.file.includes('node_modules/@sentry/core/cjs/instrument.js') ||\n frame.file.includes('node_modules/@sentry/core/cjs/debug.js'));\n\n const customizeFrame = (frame: MetroFrame): MetroCustomizeFrameReturnValue => {\n const originalOrSentryCustomizeFrame = (\n originalCustomization: MetroCustomizeFrame | undefined,\n ): MetroCustomizeFrame => ({\n ...originalCustomization,\n collapse: originalCustomization?.collapse || collapseSentryInternalFrames(frame),\n });\n\n const maybePromiseCustomization = originalCustomizeFrame?.(frame) || undefined;\n\n if (maybePromiseCustomization !== undefined && 'then' in maybePromiseCustomization) {\n return maybePromiseCustomization.then<MetroCustomizeFrame>(originalCustomization =>\n originalOrSentryCustomizeFrame(originalCustomization),\n );\n }\n\n return originalOrSentryCustomizeFrame(maybePromiseCustomization);\n };\n\n return {\n ...config,\n symbolicator: {\n ...config.symbolicator,\n customizeFrame,\n },\n };\n}\n\n/**\n * Sets the `___SENTRY_METRO_DEV_SERVER___` environment flag.\n * This is used to determine if the SDK is running in Node in Metro Dev Server.\n * For example during static routes generation in `expo-router`.\n */\nfunction setSentryMetroDevServerEnvFlag(): void {\n env.___SENTRY_METRO_DEV_SERVER___ = 'true';\n}\n"]}
|
|
1
|
+
{"version":3,"file":"metroconfig.js","sourceRoot":"","sources":["../../../src/js/tools/metroconfig.ts"],"names":[],"mappings":"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","sourcesContent":["import { debug } from '@sentry/core';\nimport type { MetroConfig, MixedOutput, Module, ReadOnlyGraph } from 'metro';\nimport type { CustomResolutionContext, CustomResolver, Resolution } from 'metro-resolver';\nimport * as process from 'process';\nimport { env } from 'process';\nimport { enableLogger } from './enableLogger';\nimport { withSentryMiddleware } from './metroMiddleware';\nimport {\n setSentryBabelTransformerOptions,\n setSentryDefaultBabelTransformerPathEnv,\n} from './sentryBabelTransformerUtils';\nimport { createSentryMetroSerializer, unstableBeforeAssetSerializationDebugIdPlugin } from './sentryMetroSerializer';\nimport { withSentryOptionsFromFile } from './sentryOptionsSerializer';\nimport { unstableReleaseConstantsPlugin } from './sentryReleaseInjector';\nimport type { MetroCustomSerializer } from './utils';\nimport type { DefaultConfigOptions } from './vendor/expo/expoconfig';\n\nexport * from './sentryMetroSerializer';\n\nenableLogger();\n\nexport interface SentryMetroConfigOptions {\n /**\n * Annotates React components with Sentry data.\n * @default false\n */\n annotateReactComponents?:\n | boolean\n | {\n ignoredComponents?: string[];\n };\n /**\n * Adds the Sentry replay package for web.\n * @default true\n */\n includeWebReplay?: boolean;\n /**\n * Add Sentry Metro Server Middleware which\n * enables the app to fetch stack frames source context.\n * @default true\n */\n enableSourceContextInDevelopment?: boolean;\n /**\n * Load Sentry Options from a file. If `true` it will use the default path.\n * If `false` it will not load any options from a file. Only options provided in the code will be used.\n * If `string` it will use the provided path.\n *\n * @default '{projectRoot}/sentry.options.json'\n */\n optionsFile?: string | boolean;\n}\n\nexport interface SentryExpoConfigOptions {\n /**\n * Pass a custom `getDefaultConfig` function to override the default Expo configuration getter.\n */\n getDefaultConfig?: (projectRoot: string, options?: Record<string, unknown>) => Record<string, unknown>;\n\n /**\n * For Expo Web, inject `release` and `version` options from `app.json`, the Expo Application Config.\n *\n * @default true\n */\n injectReleaseForWeb?: boolean;\n}\n\n/**\n * Adds Sentry to the Metro config.\n *\n * Adds Debug ID to the output bundle and source maps.\n * Collapses Sentry frames from the stack trace view in LogBox.\n */\nexport function withSentryConfig(\n config: MetroConfig,\n {\n annotateReactComponents = false,\n includeWebReplay = true,\n enableSourceContextInDevelopment = true,\n optionsFile = true,\n }: SentryMetroConfigOptions = {},\n): MetroConfig {\n setSentryMetroDevServerEnvFlag();\n\n let newConfig = config;\n\n newConfig = withSentryDebugId(newConfig);\n newConfig = withSentryFramesCollapsed(newConfig);\n if (annotateReactComponents) {\n newConfig = withSentryBabelTransformer(newConfig, annotateReactComponents);\n }\n if (includeWebReplay === false) {\n newConfig = withSentryResolver(newConfig, includeWebReplay);\n }\n newConfig = withSentryExcludeServerOnlyResolver(newConfig);\n if (enableSourceContextInDevelopment) {\n newConfig = withSentryMiddleware(newConfig);\n }\n if (optionsFile) {\n newConfig = withSentryOptionsFromFile(newConfig, optionsFile);\n }\n\n return newConfig;\n}\n\n/**\n * This function returns Default Expo configuration with Sentry plugins.\n */\nexport function getSentryExpoConfig(\n projectRoot: string,\n options: DefaultConfigOptions & SentryExpoConfigOptions & SentryMetroConfigOptions = {},\n): MetroConfig {\n setSentryMetroDevServerEnvFlag();\n\n const getDefaultConfig = options.getDefaultConfig || loadExpoMetroConfigModule().getDefaultConfig;\n const config = getDefaultConfig(projectRoot, {\n ...options,\n unstable_beforeAssetSerializationPlugins: [\n ...(options.unstable_beforeAssetSerializationPlugins || []),\n ...(options.injectReleaseForWeb ?? true ? [unstableReleaseConstantsPlugin(projectRoot)] : []),\n unstableBeforeAssetSerializationDebugIdPlugin,\n ],\n });\n\n let newConfig = withSentryFramesCollapsed(config);\n if (options.annotateReactComponents) {\n newConfig = withSentryBabelTransformer(newConfig, options.annotateReactComponents);\n }\n\n if (options.includeWebReplay === false) {\n newConfig = withSentryResolver(newConfig, options.includeWebReplay);\n }\n newConfig = withSentryExcludeServerOnlyResolver(newConfig);\n\n if (options.enableSourceContextInDevelopment ?? true) {\n newConfig = withSentryMiddleware(newConfig);\n }\n\n if (options.optionsFile ?? true) {\n newConfig = withSentryOptionsFromFile(newConfig, options.optionsFile ?? true);\n }\n\n return newConfig;\n}\n\nfunction loadExpoMetroConfigModule(): {\n getDefaultConfig: (\n projectRoot: string,\n options: {\n unstable_beforeAssetSerializationPlugins?: ((serializationInput: {\n graph: ReadOnlyGraph<MixedOutput>;\n premodules: Module[];\n debugId?: string;\n }) => Module[])[];\n },\n ) => MetroConfig;\n} {\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n return require('expo/metro-config');\n } catch (e) {\n throw new Error('Unable to load `expo/metro-config`. Make sure you have Expo installed.');\n }\n}\n\n/**\n * Adds Sentry Babel transformer to the Metro config.\n */\nexport function withSentryBabelTransformer(\n config: MetroConfig,\n annotateReactComponents: true | { ignoredComponents?: string[] },\n): MetroConfig {\n const defaultBabelTransformerPath = config.transformer?.babelTransformerPath;\n debug.log('Default Babel transformer path from `config.transformer`:', defaultBabelTransformerPath);\n\n if (!defaultBabelTransformerPath) {\n // This has to be console.warn because the options is enabled but won't be used\n // eslint-disable-next-line no-console\n console.warn('`transformer.babelTransformerPath` is undefined.');\n // eslint-disable-next-line no-console\n console.warn('Sentry Babel transformer cannot be used. Not adding it...');\n return config;\n }\n\n if (defaultBabelTransformerPath) {\n setSentryDefaultBabelTransformerPathEnv(defaultBabelTransformerPath);\n }\n\n if (typeof annotateReactComponents === 'object') {\n setSentryBabelTransformerOptions({\n annotateReactComponents,\n });\n }\n\n return {\n ...config,\n transformer: {\n ...config.transformer,\n babelTransformerPath: require.resolve('./sentryBabelTransformer'),\n },\n };\n}\n\nfunction withSentryDebugId(config: MetroConfig): MetroConfig {\n const customSerializer = createSentryMetroSerializer(\n config.serializer?.customSerializer || undefined,\n ) as MetroCustomSerializer;\n // MetroConfig types customSerializers as async only, but sync returns are also supported\n // The default serializer is sync\n\n return {\n ...config,\n serializer: {\n ...config.serializer,\n customSerializer,\n },\n };\n}\n\n// Based on: https://github.com/facebook/metro/blob/c21daba415ea26511e157f794689caab9abe8236/packages/metro-resolver/src/resolve.js#L86-L91\ntype CustomResolverBeforeMetro068 = (\n context: CustomResolutionContext,\n realModuleName: string,\n platform: string | null,\n moduleName?: string,\n) => Resolution;\n\n/**\n * Includes `@sentry/replay` packages based on the `includeWebReplay` flag and current bundle `platform`.\n */\nexport function withSentryResolver(config: MetroConfig, includeWebReplay: boolean | undefined): MetroConfig {\n const originalResolver = config.resolver?.resolveRequest as CustomResolver | CustomResolverBeforeMetro068 | undefined;\n\n const sentryResolverRequest: CustomResolver = (\n context: CustomResolutionContext,\n moduleName: string,\n platform: string | null,\n oldMetroModuleName?: string,\n ) => {\n if (\n (includeWebReplay === false ||\n (includeWebReplay === undefined && (platform === 'android' || platform === 'ios'))) &&\n !!(oldMetroModuleName ?? moduleName).match(/@sentry(?:-internal)?\\/replay/)\n ) {\n return { type: 'empty' } as Resolution;\n }\n if (originalResolver) {\n return oldMetroModuleName\n ? originalResolver(context, moduleName, platform, oldMetroModuleName)\n : originalResolver(context, moduleName, platform);\n }\n\n // Prior 0.68, resolve context.resolveRequest is sentryResolver itself, where on later version it is the default resolver.\n if (context.resolveRequest === sentryResolverRequest) {\n // eslint-disable-next-line no-console\n console.error(\n `Error: [@sentry/react-native/metro] Can not resolve the defaultResolver on Metro older than 0.68.\nPlease follow one of the following options:\n- Include your resolverRequest on your metroconfig.\n- Update your Metro version to 0.68 or higher.\n- Set includeWebReplay as true on your metro config.\n- If you are still facing issues, report the issue at http://www.github.com/getsentry/sentry-react-native/issues`,\n );\n // Return required for test.\n return process.exit(-1);\n }\n\n return context.resolveRequest(context, moduleName, platform);\n };\n\n return {\n ...config,\n resolver: {\n ...config.resolver,\n resolveRequest: sentryResolverRequest,\n },\n };\n}\n\n/**\n * Matches relative import paths to server-only AI/MCP modules within `@sentry/core`.\n *\n * Metro passes the module name as-written in the source code, so for imports inside\n * `@sentry/core`'s barrel file like `export { ... } from './integrations/mcp-server/index.js'`,\n * the `moduleName` will be `./integrations/mcp-server/index.js`.\n */\nconst SERVER_ONLY_MODULE_RE =\n /\\/(mcp-server|tracing\\/(vercel-ai|openai|anthropic-ai|google-genai|langchain|langgraph)|utils\\/ai)(\\/|$)/;\n\nfunction isFromSentryCore(originModulePath: string): boolean {\n return originModulePath.includes('@sentry/core');\n}\n\n/**\n * Excludes server-only AI/MCP modules from native (Android/iOS) bundles.\n */\nexport function withSentryExcludeServerOnlyResolver(config: MetroConfig): MetroConfig {\n const originalResolver = config.resolver?.resolveRequest as CustomResolver | CustomResolverBeforeMetro068 | undefined;\n\n const sentryServerOnlyResolverRequest: CustomResolver = (\n context: CustomResolutionContext,\n moduleName: string,\n platform: string | null,\n oldMetroModuleName?: string,\n ) => {\n if (\n (platform === 'android' || platform === 'ios') &&\n isFromSentryCore((context as { originModulePath?: string }).originModulePath ?? '') &&\n SERVER_ONLY_MODULE_RE.test(oldMetroModuleName ?? moduleName)\n ) {\n return { type: 'empty' } as Resolution;\n }\n if (originalResolver) {\n return oldMetroModuleName\n ? originalResolver(context, moduleName, platform, oldMetroModuleName)\n : originalResolver(context, moduleName, platform);\n }\n\n // Prior 0.68, context.resolveRequest is sentryServerOnlyResolverRequest itself, which would cause infinite recursion.\n if (context.resolveRequest === sentryServerOnlyResolverRequest) {\n // eslint-disable-next-line no-console\n console.error(\n `Error: [@sentry/react-native/metro] Can not resolve the defaultResolver on Metro older than 0.68.\nPlease include your resolverRequest on your metroconfig or update your Metro version to 0.68 or higher.\nIf you are still facing issues, report the issue at http://www.github.com/getsentry/sentry-react-native/issues`,\n );\n // Return required for test.\n return process.exit(-1);\n }\n\n return context.resolveRequest(context, moduleName, platform);\n };\n\n return {\n ...config,\n resolver: {\n ...config.resolver,\n resolveRequest: sentryServerOnlyResolverRequest,\n },\n };\n}\n\ntype MetroFrame = Parameters<Required<Required<MetroConfig>['symbolicator']>['customizeFrame']>[0];\ntype MetroCustomizeFrame = { readonly collapse?: boolean };\ntype MetroCustomizeFrameReturnValue =\n | ReturnType<Required<Required<MetroConfig>['symbolicator']>['customizeFrame']>\n | undefined;\n\n/**\n * Collapses Sentry internal frames from the stack trace view in LogBox.\n */\nexport function withSentryFramesCollapsed(config: MetroConfig): MetroConfig {\n const originalCustomizeFrame = config.symbolicator?.customizeFrame;\n const collapseSentryInternalFrames = (frame: MetroFrame): boolean =>\n typeof frame.file === 'string' &&\n (frame.file.includes('node_modules/@sentry/core/cjs/instrument.js') ||\n frame.file.includes('node_modules/@sentry/core/cjs/debug.js'));\n\n const customizeFrame = (frame: MetroFrame): MetroCustomizeFrameReturnValue => {\n const originalOrSentryCustomizeFrame = (\n originalCustomization: MetroCustomizeFrame | undefined,\n ): MetroCustomizeFrame => ({\n ...originalCustomization,\n collapse: originalCustomization?.collapse || collapseSentryInternalFrames(frame),\n });\n\n const maybePromiseCustomization = originalCustomizeFrame?.(frame) || undefined;\n\n if (maybePromiseCustomization !== undefined && 'then' in maybePromiseCustomization) {\n return maybePromiseCustomization.then<MetroCustomizeFrame>(originalCustomization =>\n originalOrSentryCustomizeFrame(originalCustomization),\n );\n }\n\n return originalOrSentryCustomizeFrame(maybePromiseCustomization);\n };\n\n return {\n ...config,\n symbolicator: {\n ...config.symbolicator,\n customizeFrame,\n },\n };\n}\n\n/**\n * Sets the `___SENTRY_METRO_DEV_SERVER___` environment flag.\n * This is used to determine if the SDK is running in Node in Metro Dev Server.\n * For example during static routes generation in `expo-router`.\n */\nfunction setSentryMetroDevServerEnvFlag(): void {\n env.___SENTRY_METRO_DEV_SERVER___ = 'true';\n}\n"]}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal interface for expo-asset's Asset instance.
|
|
3
|
+
* We define this to avoid a hard dependency on expo-asset.
|
|
4
|
+
*/
|
|
5
|
+
export interface ExpoAssetInstance {
|
|
6
|
+
name: string;
|
|
7
|
+
type: string;
|
|
8
|
+
hash: string | null;
|
|
9
|
+
uri: string;
|
|
10
|
+
localUri: string | null;
|
|
11
|
+
width: number | null;
|
|
12
|
+
height: number | null;
|
|
13
|
+
downloaded: boolean;
|
|
14
|
+
downloadAsync(): Promise<ExpoAssetInstance>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Represents the expo-asset `Asset` class with its static methods.
|
|
18
|
+
* We only describe the methods that we instrument.
|
|
19
|
+
*/
|
|
20
|
+
export interface ExpoAsset {
|
|
21
|
+
loadAsync(moduleId: number | number[] | string | string[]): Promise<ExpoAssetInstance[]>;
|
|
22
|
+
fromModule(virtualAssetModule: number | string): ExpoAssetInstance;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Wraps expo-asset's `Asset` class to add automated performance monitoring.
|
|
26
|
+
*
|
|
27
|
+
* This function instruments `Asset.loadAsync` static method
|
|
28
|
+
* to create performance spans that measure how long asset loading takes.
|
|
29
|
+
*
|
|
30
|
+
* @param assetClass - The `Asset` class from `expo-asset`
|
|
31
|
+
* @returns The same class with instrumented static methods
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```typescript
|
|
35
|
+
* import { Asset } from 'expo-asset';
|
|
36
|
+
* import * as Sentry from '@sentry/react-native';
|
|
37
|
+
*
|
|
38
|
+
* Sentry.wrapExpoAsset(Asset);
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export declare function wrapExpoAsset<T extends ExpoAsset>(assetClass: T): T;
|
|
42
|
+
//# sourceMappingURL=expoAsset.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expoAsset.d.ts","sourceRoot":"","sources":["../../../src/js/tracing/expoAsset.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAAC;CAC7C;AAED;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;IACzF,UAAU,CAAC,kBAAkB,EAAE,MAAM,GAAG,MAAM,GAAG,iBAAiB,CAAC;CACpE;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,SAAS,EAAE,UAAU,EAAE,CAAC,GAAG,CAAC,CAcnE"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { SPAN_ORIGIN_AUTO_RESOURCE_EXPO_ASSET } from './origin';
|
|
2
|
+
import { describeUrl, traceAsyncOperation } from './utils';
|
|
3
|
+
/**
|
|
4
|
+
* Wraps expo-asset's `Asset` class to add automated performance monitoring.
|
|
5
|
+
*
|
|
6
|
+
* This function instruments `Asset.loadAsync` static method
|
|
7
|
+
* to create performance spans that measure how long asset loading takes.
|
|
8
|
+
*
|
|
9
|
+
* @param assetClass - The `Asset` class from `expo-asset`
|
|
10
|
+
* @returns The same class with instrumented static methods
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* import { Asset } from 'expo-asset';
|
|
15
|
+
* import * as Sentry from '@sentry/react-native';
|
|
16
|
+
*
|
|
17
|
+
* Sentry.wrapExpoAsset(Asset);
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export function wrapExpoAsset(assetClass) {
|
|
21
|
+
if (!assetClass) {
|
|
22
|
+
return assetClass;
|
|
23
|
+
}
|
|
24
|
+
if (assetClass.__sentryWrapped) {
|
|
25
|
+
return assetClass;
|
|
26
|
+
}
|
|
27
|
+
wrapLoadAsync(assetClass);
|
|
28
|
+
assetClass.__sentryWrapped = true;
|
|
29
|
+
return assetClass;
|
|
30
|
+
}
|
|
31
|
+
function wrapLoadAsync(assetClass) {
|
|
32
|
+
if (!assetClass.loadAsync) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const originalLoadAsync = assetClass.loadAsync.bind(assetClass);
|
|
36
|
+
assetClass.loadAsync = ((moduleId) => {
|
|
37
|
+
const moduleIds = Array.isArray(moduleId) ? moduleId : [moduleId];
|
|
38
|
+
const assetCount = moduleIds.length;
|
|
39
|
+
const description = describeModuleIds(moduleIds);
|
|
40
|
+
return traceAsyncOperation({
|
|
41
|
+
op: 'resource.asset',
|
|
42
|
+
name: `Asset load ${description}`,
|
|
43
|
+
attributes: {
|
|
44
|
+
'sentry.origin': SPAN_ORIGIN_AUTO_RESOURCE_EXPO_ASSET,
|
|
45
|
+
'asset.count': assetCount,
|
|
46
|
+
},
|
|
47
|
+
}, () => originalLoadAsync(moduleId));
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
function describeModuleIds(moduleIds) {
|
|
51
|
+
if (moduleIds.length === 1) {
|
|
52
|
+
const id = moduleIds[0];
|
|
53
|
+
if (typeof id === 'string') {
|
|
54
|
+
return describeUrl(id);
|
|
55
|
+
}
|
|
56
|
+
return `asset #${id}`;
|
|
57
|
+
}
|
|
58
|
+
return `${moduleIds.length} assets`;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=expoAsset.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expoAsset.js","sourceRoot":"","sources":["../../../src/js/tracing/expoAsset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oCAAoC,EAAE,MAAM,UAAU,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AA2B3D;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,aAAa,CAAsB,UAAa;IAC9D,IAAI,CAAC,UAAU,EAAE;QACf,OAAO,UAAU,CAAC;KACnB;IAED,IAAK,UAAgD,CAAC,eAAe,EAAE;QACrE,OAAO,UAAU,CAAC;KACnB;IAED,aAAa,CAAC,UAAU,CAAC,CAAC;IAEzB,UAAgD,CAAC,eAAe,GAAG,IAAI,CAAC;IAEzE,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,aAAa,CAAsB,UAAa;IACvD,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE;QACzB,OAAO;KACR;IAED,MAAM,iBAAiB,GAAG,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAEhE,UAAU,CAAC,SAAS,GAAG,CAAC,CAAC,QAA+C,EAAgC,EAAE;QACxG,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAClE,MAAM,UAAU,GAAG,SAAS,CAAC,MAAM,CAAC;QACpC,MAAM,WAAW,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAEjD,OAAO,mBAAmB,CACxB;YACE,EAAE,EAAE,gBAAgB;YACpB,IAAI,EAAE,cAAc,WAAW,EAAE;YACjC,UAAU,EAAE;gBACV,eAAe,EAAE,oCAAoC;gBACrD,aAAa,EAAE,UAAU;aAC1B;SACF,EACD,GAAG,EAAE,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAClC,CAAC;IACJ,CAAC,CAAmB,CAAC;AACvB,CAAC;AAED,SAAS,iBAAiB,CAAC,SAA8B;IACvD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE;QAC1B,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;QACxB,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE;YAC1B,OAAO,WAAW,CAAC,EAAE,CAAC,CAAC;SACxB;QACD,OAAO,UAAU,EAAE,EAAE,CAAC;KACvB;IACD,OAAO,GAAG,SAAS,CAAC,MAAM,SAAS,CAAC;AACtC,CAAC","sourcesContent":["import { SPAN_ORIGIN_AUTO_RESOURCE_EXPO_ASSET } from './origin';\nimport { describeUrl, traceAsyncOperation } from './utils';\n\n/**\n * Internal interface for expo-asset's Asset instance.\n * We define this to avoid a hard dependency on expo-asset.\n */\nexport interface ExpoAssetInstance {\n name: string;\n type: string;\n hash: string | null;\n uri: string;\n localUri: string | null;\n width: number | null;\n height: number | null;\n downloaded: boolean;\n downloadAsync(): Promise<ExpoAssetInstance>;\n}\n\n/**\n * Represents the expo-asset `Asset` class with its static methods.\n * We only describe the methods that we instrument.\n */\nexport interface ExpoAsset {\n loadAsync(moduleId: number | number[] | string | string[]): Promise<ExpoAssetInstance[]>;\n fromModule(virtualAssetModule: number | string): ExpoAssetInstance;\n}\n\n/**\n * Wraps expo-asset's `Asset` class to add automated performance monitoring.\n *\n * This function instruments `Asset.loadAsync` static method\n * to create performance spans that measure how long asset loading takes.\n *\n * @param assetClass - The `Asset` class from `expo-asset`\n * @returns The same class with instrumented static methods\n *\n * @example\n * ```typescript\n * import { Asset } from 'expo-asset';\n * import * as Sentry from '@sentry/react-native';\n *\n * Sentry.wrapExpoAsset(Asset);\n * ```\n */\nexport function wrapExpoAsset<T extends ExpoAsset>(assetClass: T): T {\n if (!assetClass) {\n return assetClass;\n }\n\n if ((assetClass as T & { __sentryWrapped?: boolean }).__sentryWrapped) {\n return assetClass;\n }\n\n wrapLoadAsync(assetClass);\n\n (assetClass as T & { __sentryWrapped?: boolean }).__sentryWrapped = true;\n\n return assetClass;\n}\n\nfunction wrapLoadAsync<T extends ExpoAsset>(assetClass: T): void {\n if (!assetClass.loadAsync) {\n return;\n }\n\n const originalLoadAsync = assetClass.loadAsync.bind(assetClass);\n\n assetClass.loadAsync = ((moduleId: number | number[] | string | string[]): Promise<ExpoAssetInstance[]> => {\n const moduleIds = Array.isArray(moduleId) ? moduleId : [moduleId];\n const assetCount = moduleIds.length;\n const description = describeModuleIds(moduleIds);\n\n return traceAsyncOperation(\n {\n op: 'resource.asset',\n name: `Asset load ${description}`,\n attributes: {\n 'sentry.origin': SPAN_ORIGIN_AUTO_RESOURCE_EXPO_ASSET,\n 'asset.count': assetCount,\n },\n },\n () => originalLoadAsync(moduleId),\n );\n }) as T['loadAsync'];\n}\n\nfunction describeModuleIds(moduleIds: (number | string)[]): string {\n if (moduleIds.length === 1) {\n const id = moduleIds[0];\n if (typeof id === 'string') {\n return describeUrl(id);\n }\n return `asset #${id}`;\n }\n return `${moduleIds.length} assets`;\n}\n"]}
|