@@ -5,10 +5,19 @@ import { logger } from '@sentry/core';
55import { DEBUG_BUILD } from '../debug-build' ;
66import { isCjs } from '../utils/commonjs' ;
77
8- let moduleCache : { [ key : string ] : string } ;
8+ type ModuleInfo = Record < string , string > ;
9+
10+ let moduleCache : ModuleInfo | undefined ;
911
1012const INTEGRATION_NAME = 'Modules' ;
1113
14+ declare const __SENTRY_SERVER_MODULES__ : Record < string , string > ;
15+
16+ /**
17+ * This is replaced at build time with the modules loaded by the server.
18+ */
19+ const SERVER_MODULES = typeof __SENTRY_SERVER_MODULES__ === 'undefined' ? { } : __SENTRY_SERVER_MODULES__ ;
20+
1221const _modulesIntegration = ( ( ) => {
1322 // This integration only works in CJS contexts
1423 if ( ! isCjs ( ) ) {
@@ -52,17 +61,23 @@ function getPaths(): string[] {
5261}
5362
5463/** Extract information about package.json modules */
55- function collectModules ( ) : {
56- [ name : string ] : string ;
57- } {
64+ function collectModules ( ) : ModuleInfo {
65+ return {
66+ ...SERVER_MODULES ,
67+ ...getModulesFromPackageJson ( ) ,
68+ ...collectRequireModules ( ) ,
69+ } ;
70+ }
71+
72+ /** Extract information about package.json modules from require.cache */
73+ function collectRequireModules ( ) : ModuleInfo {
5874 const mainPaths = require . main ?. paths || [ ] ;
5975 const paths = getPaths ( ) ;
60- const infos : {
61- [ name : string ] : string ;
62- } = { } ;
63- const seen : {
64- [ path : string ] : boolean ;
65- } = { } ;
76+
77+ // We start with the modules from package.json (if possible)
78+ // These may be overwritten by more specific versions from the require.cache
79+ const infos : ModuleInfo = { } ;
80+ const seen = new Set < string > ( ) ;
6681
6782 paths . forEach ( path => {
6883 let dir = path ;
@@ -72,15 +87,15 @@ function collectModules(): {
7287 const orig = dir ;
7388 dir = dirname ( orig ) ;
7489
75- if ( ! dir || orig === dir || seen [ orig ] ) {
90+ if ( ! dir || orig === dir || seen . has ( orig ) ) {
7691 return undefined ;
7792 }
7893 if ( mainPaths . indexOf ( dir ) < 0 ) {
7994 return updir ( ) ;
8095 }
8196
8297 const pkgfile = join ( orig , 'package.json' ) ;
83- seen [ orig ] = true ;
98+ seen . add ( orig ) ;
8499
85100 if ( ! existsSync ( pkgfile ) ) {
86101 return updir ( ) ;
@@ -104,9 +119,35 @@ function collectModules(): {
104119}
105120
106121/** Fetches the list of modules and the versions loaded by the entry file for your node.js app. */
107- function _getModules ( ) : { [ key : string ] : string } {
122+ function _getModules ( ) : ModuleInfo {
108123 if ( ! moduleCache ) {
109124 moduleCache = collectModules ( ) ;
110125 }
111126 return moduleCache ;
112127}
128+
129+ interface PackageJson {
130+ dependencies ?: Record < string , string > ;
131+ devDependencies ?: Record < string , string > ;
132+ }
133+
134+ function getPackageJson ( ) : PackageJson {
135+ try {
136+ // @ts -expect-error This actually works, we transpile this in CJS
137+ const filePath = join ( dirname ( import . meta. url ) , 'package.json' ) ;
138+ const packageJson = JSON . parse ( readFileSync ( filePath , 'utf8' ) ) as PackageJson ;
139+
140+ return packageJson ;
141+ } catch ( e ) {
142+ return { } ;
143+ }
144+ }
145+
146+ function getModulesFromPackageJson ( ) : ModuleInfo {
147+ const packageJson = getPackageJson ( ) ;
148+
149+ return {
150+ ...packageJson . dependencies ,
151+ ...packageJson . devDependencies ,
152+ } ;
153+ }
0 commit comments