1+ /* eslint-disable @typescript-eslint/no-non-null-assertion */
2+ /* eslint-disable @typescript-eslint/no-var-requires */
13/* eslint-disable @typescript-eslint/no-explicit-any */
2- // import { version as nextVersion } from './node_modules/next/package.json';
34import { getSentryRelease } from '@sentry/node' ;
45import { logger } from '@sentry/utils' ;
56import defaultWebpackPlugin , { SentryCliPluginOptions } from '@sentry/webpack-plugin' ;
67import * as SentryWebpackPlugin from '@sentry/webpack-plugin' ;
78import * as fs from 'fs' ;
9+ import * as path from 'path' ;
10+
11+ /**
12+ * Starting at `startPath`, move up one directory at a time, searching for `searchFile`.
13+ *
14+ * @param startPath The location from which to start the search.
15+ * @param searchFile The file to search for
16+ * @returns The absolute path of the file, if it's found, or undefined if it's not.
17+ */
18+ function findUp ( startPath : string , searchFile : string ) : string | undefined {
19+ if ( ! fs . existsSync ( startPath ) ) {
20+ throw new Error ( `The given \`startPath\` value (${ startPath } ) does not exist.` ) ;
21+ }
22+
23+ let currentDir = fs . statSync ( startPath ) . isFile ( ) ? path . dirname ( startPath ) : startPath ;
24+ while ( currentDir !== '/' ) {
25+ const possiblePath = path . join ( currentDir , searchFile ) ;
26+ if ( fs . existsSync ( possiblePath ) ) {
27+ return possiblePath ;
28+ }
29+
30+ currentDir = path . join ( currentDir , '..' ) ;
31+ }
32+
33+ return undefined ;
34+ }
835
936/**
1037 * Next requires that plugins be tagged with the same version number as the currently-running `next.js` package, so
@@ -14,27 +41,39 @@ export function syncPluginVersionWithNextVersion(): void {
1441 // TODO Once we get at least to TS 2.9, we can use `"resolveJsonModule": true` in our `compilerOptions` and we'll be
1542 // able to do:
1643 // import { version as nextVersion } from './node_modules/next/package.json';
44+ let nextVersion ;
1745
18- // eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-member-access
19- const nextVersion = ( require ( '../../../../next/package.json' ) as any ) . version ;
20- if ( ! nextVersion ) {
21- logger . error ( '[next-plugin-sentry] Cannot read next.js version. Plug-in will not work.' ) ;
46+ try {
47+ // `require.resolve` returns the location of the packages `"main"` entry point, as specified in its `package.json`
48+ const nextResolvedMain = require . resolve ( 'next' ) ;
49+ // since we don't know where in the package's directory that entry point is, search upward until we find a folder
50+ // containing `package.json`
51+ const nextPackageJsonPath = findUp ( nextResolvedMain , 'package.json' ) ;
52+ nextVersion = nextPackageJsonPath && ( require ( nextPackageJsonPath ) as { version : string } ) . version ;
53+ } catch ( err ) {
54+ // eslint-disable-next-line no-console
55+ console . error ( `[next-plugin-sentry] Cannot read next.js version. Plug-in will not work.\nReceived error: ${ err } ` ) ;
2256 return ;
2357 }
2458
25- const pluginPackageDotJsonPath = `../../../next-plugin-sentry/package.json` ;
26- // eslint-disable-next-line @typescript-eslint/no-var-requires
27- const pluginPackageDotJson = require ( pluginPackageDotJsonPath ) ; // see TODO above
28- if ( ! pluginPackageDotJson ) {
29- logger . error ( `[next-plugin-sentry] Cannot read ${ pluginPackageDotJsonPath } . Plug-in will not work.` ) ;
59+ let pluginPackageJsonPath , pluginPackageJson ;
60+
61+ try {
62+ const pluginResolvedMain = require . resolve ( '@sentry/next-plugin-sentry' ) ;
63+ // see notes above about why we need to call `findUp`
64+ pluginPackageJsonPath = findUp ( pluginResolvedMain , 'package.json' ) ;
65+ pluginPackageJson = pluginPackageJsonPath && require ( pluginPackageJsonPath ) ;
66+ } catch ( err ) {
67+ // eslint-disable-next-line no-console
68+ console . error (
69+ `[next-plugin-sentry] Cannot find \`@sentry/next-plugin-sentry\`. Plug-in will not work. ` +
70+ `Please try reinstalling \`@sentry/nextjs\`.\nReceived error: ${ err } ` ,
71+ ) ;
3072 return ;
3173 }
3274
33- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
34- ( pluginPackageDotJson as any ) . version = nextVersion ;
35- // interestingly, the `require` calls above seem to resolve from a different starting point than `fs` does here, which
36- // is why we can't just use `pluginPackageDotJsonPath` again
37- fs . writeFileSync ( './node_modules/@sentry/next-plugin-sentry/package.json' , JSON . stringify ( pluginPackageDotJson ) ) ;
75+ ( pluginPackageJson as { version : string } ) . version = nextVersion ! ;
76+ fs . writeFileSync ( pluginPackageJsonPath ! , JSON . stringify ( pluginPackageJson ) ) ;
3877}
3978
4079type WebpackConfig = { devtool : string ; plugins : Array < { [ key : string ] : any } > } ;
0 commit comments