@sentry/wizard 1.2.13 → 1.2.17
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/CHANGELOG.md +100 -82
- package/README.md +29 -12
- package/dist/NextJs/configs/_error.js +65 -0
- package/dist/NextJs/configs/next.config.js +2 -2
- package/dist/lib/Helper/SentryCli.d.ts +1 -0
- package/dist/lib/Helper/SentryCli.js +2 -0
- package/dist/lib/Helper/SentryCli.js.map +1 -1
- package/dist/lib/Steps/Integrations/BaseIntegration.d.ts +1 -1
- package/dist/lib/Steps/Integrations/BaseIntegration.js +3 -2
- package/dist/lib/Steps/Integrations/BaseIntegration.js.map +1 -1
- package/dist/lib/Steps/Integrations/NextJs.d.ts +3 -2
- package/dist/lib/Steps/Integrations/NextJs.js +82 -52
- package/dist/lib/Steps/Integrations/NextJs.js.map +1 -1
- package/lib/Helper/SentryCli.ts +2 -0
- package/lib/Steps/Integrations/BaseIntegration.ts +5 -2
- package/lib/Steps/Integrations/NextJs.ts +104 -64
- package/package.json +1 -1
- package/scripts/NextJs/configs/_error.js +65 -0
- package/scripts/NextJs/configs/next.config.js +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,276 +2,294 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 1.2.17
|
|
6
|
+
|
|
7
|
+
- Support Next.js v12 (#152)
|
|
8
|
+
|
|
9
|
+
## 1.2.16
|
|
10
|
+
|
|
11
|
+
- fix(nextjs): Do not capture 404s as exceptions in `_error` (#146)
|
|
12
|
+
|
|
13
|
+
## 1.2.15
|
|
14
|
+
|
|
15
|
+
- Check version range rather than minimum version for nextjs (#143)
|
|
16
|
+
|
|
17
|
+
## 1.2.14
|
|
18
|
+
|
|
19
|
+
- Automatically include `pages/_error.js` when setting up nextjs project (#140)
|
|
20
|
+
- Clarify "Usage" section of `README.md` (#139)
|
|
21
|
+
|
|
5
22
|
## 1.2.13
|
|
6
23
|
|
|
7
|
-
|
|
24
|
+
- Fix `.sentryclirc` file formatting (#131)
|
|
8
25
|
|
|
9
26
|
## 1.2.12
|
|
10
27
|
|
|
11
|
-
|
|
28
|
+
- Don't expose auth token in `sentry.properties` (#128)
|
|
12
29
|
|
|
13
30
|
## 1.2.11
|
|
14
31
|
|
|
15
|
-
|
|
32
|
+
- Parse Next.js version as a string, instead of int (#122)
|
|
16
33
|
|
|
17
34
|
## 1.2.10
|
|
18
35
|
|
|
19
|
-
|
|
36
|
+
- Check new contents before overwriting a file (#117)
|
|
20
37
|
|
|
21
38
|
## 1.2.9
|
|
22
39
|
|
|
23
|
-
|
|
24
|
-
|
|
40
|
+
- Add performance monitoring support to nextjs scripts (#114)
|
|
41
|
+
- Make webpack silent by default in nextjs config (#113)
|
|
25
42
|
|
|
26
43
|
## v1.2.8
|
|
27
44
|
|
|
28
|
-
|
|
45
|
+
- Fix React Native JS patching throwing errors due to incorrect argument
|
|
29
46
|
|
|
30
47
|
## v1.2.7
|
|
31
48
|
|
|
32
|
-
|
|
33
|
-
|
|
49
|
+
- Fix React Native uninstall script
|
|
50
|
+
- Fix platform selection issues and repeated prompts on Mobile Projects.
|
|
34
51
|
|
|
35
52
|
## v1.2.6
|
|
36
53
|
|
|
37
|
-
|
|
54
|
+
- Get release from environment for the Next.js SDK
|
|
38
55
|
|
|
39
56
|
## v1.2.5
|
|
40
57
|
|
|
41
|
-
|
|
58
|
+
- Ignore coverage when linting and clarify Next.js messages.
|
|
42
59
|
|
|
43
60
|
## v1.2.4
|
|
44
61
|
|
|
45
|
-
|
|
46
|
-
|
|
62
|
+
- Add Next.js SDK initialization config files.
|
|
63
|
+
- Update webpack config file of Next.js.
|
|
47
64
|
|
|
48
65
|
## v1.2.3
|
|
49
66
|
|
|
50
|
-
|
|
51
|
-
|
|
67
|
+
- Don't use `package` as a varname in the NextJS config
|
|
68
|
+
- Enable env variables in the NextJS config
|
|
52
69
|
|
|
53
70
|
## v1.2.2
|
|
54
71
|
|
|
55
|
-
|
|
72
|
+
- Add support for `NEXT_PUBLIC_SENTRY_DSN`
|
|
56
73
|
|
|
57
74
|
## v1.2.1
|
|
58
75
|
|
|
59
|
-
|
|
76
|
+
- Update `next.config.js`, and create mergeable configs when they already exist
|
|
60
77
|
|
|
61
78
|
## v1.2.0
|
|
62
79
|
|
|
63
|
-
|
|
80
|
+
- Add support for Next.js
|
|
64
81
|
|
|
65
82
|
## v1.1.4
|
|
66
83
|
|
|
67
|
-
|
|
84
|
+
- Bump @sentry/cli `1.52.4`
|
|
68
85
|
|
|
69
86
|
## v1.1.3
|
|
70
87
|
|
|
71
|
-
|
|
72
|
-
|
|
88
|
+
- Add sourcemap output path to derived data to react native ios script
|
|
89
|
+
- Bump @sentry/cli `1.52.3`
|
|
73
90
|
|
|
74
91
|
## v1.1.2
|
|
75
92
|
|
|
76
|
-
|
|
93
|
+
- Don't `cli/executable` for Android project on react-native
|
|
77
94
|
|
|
78
95
|
## v1.1.1
|
|
79
96
|
|
|
80
|
-
|
|
97
|
+
- Bump @sentry/cli `1.51.0`
|
|
81
98
|
|
|
82
99
|
## v1.1.0
|
|
83
100
|
|
|
84
|
-
|
|
101
|
+
- Bump @sentry/cli `1.50.0`
|
|
85
102
|
|
|
86
103
|
## v1.0.2
|
|
87
104
|
|
|
88
|
-
|
|
105
|
+
- Several dependeny bumps with related security updates
|
|
89
106
|
|
|
90
107
|
## v1.0.1
|
|
91
108
|
|
|
92
|
-
|
|
93
|
-
|
|
109
|
+
- Strip only `Sentry*` frameworks for Cordova
|
|
110
|
+
- Guard Xcode project updates for react-native
|
|
94
111
|
|
|
95
112
|
## v1.0.0
|
|
96
113
|
|
|
97
|
-
|
|
114
|
+
- Support for new `@sentry/react-native`
|
|
98
115
|
|
|
99
116
|
## v0.13.0
|
|
100
117
|
|
|
101
|
-
|
|
118
|
+
- Bump @sentry/cli `1.43.0`
|
|
102
119
|
|
|
103
120
|
## v0.12.1
|
|
104
121
|
|
|
105
|
-
|
|
122
|
+
- Bump @sentry/cli `1.36.1`
|
|
106
123
|
|
|
107
124
|
## v0.12.0
|
|
108
125
|
|
|
109
|
-
|
|
110
|
-
|
|
126
|
+
- Fixed #22
|
|
127
|
+
- Bumped dependencies
|
|
111
128
|
|
|
112
129
|
## v0.11.1
|
|
113
130
|
|
|
114
|
-
|
|
131
|
+
- Fixed #16
|
|
115
132
|
|
|
116
133
|
## v0.11.0
|
|
117
134
|
|
|
118
|
-
|
|
135
|
+
- Update all dependencies, Fix tests on travis
|
|
119
136
|
|
|
120
137
|
## v0.10.3
|
|
121
138
|
|
|
122
|
-
|
|
139
|
+
- Use public DSN for react-native
|
|
123
140
|
|
|
124
141
|
## v0.10.2
|
|
125
142
|
|
|
126
|
-
|
|
143
|
+
- Remove secret DSN part check for prompt
|
|
127
144
|
|
|
128
145
|
## v0.10.1
|
|
129
146
|
|
|
130
|
-
|
|
147
|
+
- Use opn in favor of open
|
|
131
148
|
|
|
132
149
|
## v0.10.0
|
|
133
150
|
|
|
134
|
-
|
|
151
|
+
- Change Cordova wizard steps to only run once and create properties file in
|
|
152
|
+
root
|
|
135
153
|
|
|
136
154
|
## v0.9.7
|
|
137
155
|
|
|
138
|
-
|
|
156
|
+
- Fix a bug where sentry-wizard will ask for parameters on uninstall
|
|
139
157
|
|
|
140
158
|
## v0.9.6
|
|
141
159
|
|
|
142
|
-
|
|
160
|
+
- Fix electron symbol upload script
|
|
143
161
|
|
|
144
162
|
## v0.9.5
|
|
145
163
|
|
|
146
|
-
|
|
164
|
+
- Update Electron instructions to latest SDK version
|
|
147
165
|
|
|
148
166
|
## v0.9.4
|
|
149
167
|
|
|
150
|
-
|
|
151
|
-
|
|
168
|
+
- Restore Node compatibility
|
|
169
|
+
- Add more tests
|
|
152
170
|
|
|
153
171
|
## v0.9.3
|
|
154
172
|
|
|
155
|
-
|
|
173
|
+
- Fix Electron installation code - Fixes #7
|
|
156
174
|
|
|
157
175
|
## v0.9.2
|
|
158
176
|
|
|
159
|
-
|
|
160
|
-
|
|
177
|
+
- Support Electron prereleases in symbol upload
|
|
178
|
+
- Correctly upload Electron dSYMs for macOS
|
|
161
179
|
|
|
162
180
|
## v0.9.1
|
|
163
181
|
|
|
164
|
-
|
|
182
|
+
- Add strip arch script for cordova
|
|
165
183
|
|
|
166
184
|
## v0.9.0
|
|
167
185
|
|
|
168
|
-
|
|
186
|
+
- Add support for electron projects
|
|
169
187
|
|
|
170
188
|
## v0.8.3
|
|
171
189
|
|
|
172
|
-
|
|
190
|
+
- Fixed an issue where file exsists always returned false
|
|
173
191
|
|
|
174
192
|
## v0.8.2
|
|
175
193
|
|
|
176
|
-
|
|
194
|
+
- Move sentry.properties file to plugins folder for Cordova
|
|
177
195
|
|
|
178
196
|
## v0.8.1
|
|
179
197
|
|
|
180
|
-
|
|
181
|
-
|
|
198
|
+
- Fix react-native js file patching
|
|
199
|
+
- Bump sentry-cli to 1.28.4
|
|
182
200
|
|
|
183
201
|
## v0.8.0
|
|
184
202
|
|
|
185
|
-
|
|
203
|
+
- Fix Cordova sentry-cli upload-dsym command for Xcode
|
|
186
204
|
|
|
187
205
|
## v0.7.5
|
|
188
206
|
|
|
189
|
-
|
|
207
|
+
- Bump sentry-cli version to 1.28.1
|
|
190
208
|
|
|
191
209
|
## v0.7.4
|
|
192
210
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
211
|
+
- Bump sentry-cli version to 1.27.1
|
|
212
|
+
- Fix Cordova integration
|
|
213
|
+
- Fix issue in file checker to default to false
|
|
196
214
|
|
|
197
215
|
## v0.7.3
|
|
198
216
|
|
|
199
|
-
|
|
217
|
+
- Bump sentry-cli version
|
|
200
218
|
|
|
201
219
|
## v0.7.2
|
|
202
220
|
|
|
203
|
-
|
|
204
|
-
|
|
221
|
+
- Fix quiet mode and default parameter
|
|
222
|
+
- Fix version detection for @sentry/cli
|
|
205
223
|
|
|
206
224
|
## v0.7.1
|
|
207
225
|
|
|
208
|
-
|
|
226
|
+
- Improve function call for wizard and parameter validation/sanitation
|
|
209
227
|
|
|
210
228
|
## v0.7.0
|
|
211
229
|
|
|
212
|
-
|
|
230
|
+
- Use @sentry/cli
|
|
213
231
|
|
|
214
232
|
## v0.6.1
|
|
215
233
|
|
|
216
|
-
|
|
234
|
+
- Fixed https://github.com/getsentry/react-native-sentry/issues/304
|
|
217
235
|
|
|
218
236
|
## v0.6.0
|
|
219
237
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
238
|
+
- Add quiet mode --quiet
|
|
239
|
+
- Fallback to user prompts when not able to connect to Sentry
|
|
240
|
+
- Renamed parameter type/protype to integration
|
|
223
241
|
|
|
224
242
|
## v0.5.3
|
|
225
243
|
|
|
226
|
-
|
|
244
|
+
- Passing answers fixed in file helper
|
|
227
245
|
|
|
228
246
|
## v0.5.2
|
|
229
247
|
|
|
230
|
-
|
|
248
|
+
- Platform check
|
|
231
249
|
|
|
232
250
|
## v0.5.1
|
|
233
251
|
|
|
234
|
-
|
|
252
|
+
- Fix skip connection also for polling
|
|
235
253
|
|
|
236
254
|
## v0.5.0
|
|
237
255
|
|
|
238
|
-
|
|
239
|
-
|
|
256
|
+
- Add skip connection option to skip connecting to Sentry
|
|
257
|
+
- Add possiblity to overwrite args with ENV vars SENTRY_WIZARD prefixed
|
|
240
258
|
|
|
241
259
|
## v0.4.0
|
|
242
260
|
|
|
243
|
-
|
|
261
|
+
- Fix uninstall step for react-native
|
|
244
262
|
|
|
245
263
|
## v0.3.2
|
|
246
264
|
|
|
247
|
-
|
|
265
|
+
- Fix sentry-cli version
|
|
248
266
|
|
|
249
267
|
## v0.3.1
|
|
250
268
|
|
|
251
|
-
|
|
269
|
+
- Fix polling and json reponse parsing
|
|
252
270
|
|
|
253
271
|
## v0.3.0
|
|
254
272
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
273
|
+
- Add support for cordova
|
|
274
|
+
- Internal refactorings
|
|
275
|
+
- Check if project is already setup
|
|
258
276
|
|
|
259
277
|
## v0.2.2
|
|
260
278
|
|
|
261
|
-
|
|
279
|
+
- Fix build process
|
|
262
280
|
|
|
263
281
|
## v0.2.1
|
|
264
282
|
|
|
265
|
-
|
|
283
|
+
- Fix build process
|
|
266
284
|
|
|
267
285
|
## v0.2.0
|
|
268
286
|
|
|
269
|
-
|
|
287
|
+
- Add support for react-native
|
|
270
288
|
|
|
271
289
|
## v0.1.1
|
|
272
290
|
|
|
273
|
-
|
|
291
|
+
- Fix build process
|
|
274
292
|
|
|
275
293
|
## v0.1.0
|
|
276
294
|
|
|
277
|
-
|
|
295
|
+
- Inital release
|
package/README.md
CHANGED
|
@@ -4,34 +4,51 @@
|
|
|
4
4
|
</a>
|
|
5
5
|
<br/>
|
|
6
6
|
<h1>Sentry Wizard</h1>
|
|
7
|
-
<h4>
|
|
7
|
+
<h4>The Sentry Wizard helps you set up your React Native, Cordova, Electron or Next.js projects with Sentry.</h4>
|
|
8
8
|
</p>
|
|
9
9
|
|
|
10
|
-
[](https://travis-ci.org/getsentry/sentry-wizard)
|
|
11
10
|
[](https://www.npmjs.com/package/@sentry/wizard)
|
|
12
11
|
[](https://www.npmjs.com/package/@sentry/wizard)
|
|
13
12
|
[](https://www.npmjs.com/package/@sentry/wizard)
|
|
14
|
-
[](https://discord.gg/Ww9hbqr)
|
|
13
|
+
[](https://discord.gg/Ww9hbqr)
|
|
15
14
|
|
|
16
15
|
[](https://david-dm.org/getsentry/sentry-wizard?view=list)
|
|
17
16
|
[](https://david-dm.org/getsentry/sentry-wizard?type=dev&view=list)
|
|
18
17
|
[](https://david-dm.org/getsentry/sentry-wizard?type=peer&view=list)
|
|
19
18
|
|
|
20
|
-
|
|
21
19
|

|
|
22
20
|
|
|
23
|
-
|
|
24
21
|
# Usage
|
|
25
22
|
|
|
26
|
-
|
|
23
|
+
There are multiple ways to run the Wizard.
|
|
24
|
+
|
|
25
|
+
1. Install globally and run it anywhere:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install -g @sentry/wizard
|
|
29
|
+
# or
|
|
30
|
+
yarn global add @sentry/wizard
|
|
31
|
+
|
|
32
|
+
sentry-wizard
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
2. Install and run it in your project with `yarn`:
|
|
27
36
|
|
|
37
|
+
```bash
|
|
38
|
+
yarn add @sentry/wizard
|
|
39
|
+
yarn sentry-wizard
|
|
28
40
|
```
|
|
29
|
-
|
|
41
|
+
|
|
42
|
+
3. Run it directly without installing:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
npx @sentry/wizard
|
|
30
46
|
```
|
|
31
47
|
|
|
32
|
-
|
|
48
|
+
At the current moment, the wizard is meant to be used for React Native, Cordova, Electron or Next.js. If you have other platforms you would like the wizard to support, please open a [GitHub issue](https://github.com/getsentry/sentry-wizard/issues)!
|
|
33
49
|
|
|
34
50
|
# Options
|
|
51
|
+
|
|
35
52
|
```
|
|
36
53
|
Options:
|
|
37
54
|
--help Show help [boolean]
|
|
@@ -56,7 +73,7 @@ Options:
|
|
|
56
73
|
|
|
57
74
|
## Resources
|
|
58
75
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
76
|
+
- [](https://forum.sentry.io/c/sdks)
|
|
77
|
+
- [](https://discord.gg/Ww9hbqr)
|
|
78
|
+
- [](http://stackoverflow.com/questions/tagged/sentry)
|
|
79
|
+
- [](https://twitter.com/intent/follow?screen_name=getsentry)
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import NextErrorComponent from 'next/error';
|
|
2
|
+
|
|
3
|
+
import * as Sentry from '@sentry/nextjs';
|
|
4
|
+
|
|
5
|
+
const MyError = ({ statusCode, hasGetInitialPropsRun, err }) => {
|
|
6
|
+
if (!hasGetInitialPropsRun && err) {
|
|
7
|
+
// getInitialProps is not called in case of
|
|
8
|
+
// https://github.com/vercel/next.js/issues/8592. As a workaround, we pass
|
|
9
|
+
// err via _app.js so it can be captured
|
|
10
|
+
Sentry.captureException(err);
|
|
11
|
+
// Flushing is not required in this case as it only happens on the client
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return <NextErrorComponent statusCode={statusCode} />;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
MyError.getInitialProps = async (context) => {
|
|
18
|
+
const errorInitialProps = await NextErrorComponent.getInitialProps(context);
|
|
19
|
+
|
|
20
|
+
const { res, err, asPath } = context;
|
|
21
|
+
|
|
22
|
+
// Workaround for https://github.com/vercel/next.js/issues/8592, mark when
|
|
23
|
+
// getInitialProps has run
|
|
24
|
+
errorInitialProps.hasGetInitialPropsRun = true;
|
|
25
|
+
|
|
26
|
+
// Returning early because we don't want to log 404 errors to Sentry.
|
|
27
|
+
if (res?.statusCode === 404) {
|
|
28
|
+
return errorInitialProps;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Running on the server, the response object (`res`) is available.
|
|
32
|
+
//
|
|
33
|
+
// Next.js will pass an err on the server if a page's data fetching methods
|
|
34
|
+
// threw or returned a Promise that rejected
|
|
35
|
+
//
|
|
36
|
+
// Running on the client (browser), Next.js will provide an err if:
|
|
37
|
+
//
|
|
38
|
+
// - a page's `getInitialProps` threw or returned a Promise that rejected
|
|
39
|
+
// - an exception was thrown somewhere in the React lifecycle (render,
|
|
40
|
+
// componentDidMount, etc) that was caught by Next.js's React Error
|
|
41
|
+
// Boundary. Read more about what types of exceptions are caught by Error
|
|
42
|
+
// Boundaries: https://reactjs.org/docs/error-boundaries.html
|
|
43
|
+
|
|
44
|
+
if (err) {
|
|
45
|
+
Sentry.captureException(err);
|
|
46
|
+
|
|
47
|
+
// Flushing before returning is necessary if deploying to Vercel, see
|
|
48
|
+
// https://vercel.com/docs/platform/limits#streaming-responses
|
|
49
|
+
await Sentry.flush(2000);
|
|
50
|
+
|
|
51
|
+
return errorInitialProps;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// If this point is reached, getInitialProps was called without any
|
|
55
|
+
// information about what the error might be. This is unexpected and may
|
|
56
|
+
// indicate a bug introduced in Next.js, so record it in Sentry
|
|
57
|
+
Sentry.captureException(
|
|
58
|
+
new Error(`_error.js getInitialProps missing data at path: ${asPath}`),
|
|
59
|
+
);
|
|
60
|
+
await Sentry.flush(2000);
|
|
61
|
+
|
|
62
|
+
return errorInitialProps;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
export default MyError;
|
|
@@ -9,7 +9,7 @@ const moduleExports = {
|
|
|
9
9
|
// Your existing module.exports
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
-
const
|
|
12
|
+
const sentryWebpackPluginOptions = {
|
|
13
13
|
// Additional config options for the Sentry Webpack plugin. Keep in mind that
|
|
14
14
|
// the following options are set automatically, and overriding them is not
|
|
15
15
|
// recommended:
|
|
@@ -23,4 +23,4 @@ const SentryWebpackPluginOptions = {
|
|
|
23
23
|
|
|
24
24
|
// Make sure adding Sentry options is the last code to run before exporting, to
|
|
25
25
|
// ensure that your source maps include changes from all other Webpack plugins
|
|
26
|
-
module.exports = withSentryConfig(moduleExports,
|
|
26
|
+
module.exports = withSentryConfig(moduleExports, sentryWebpackPluginOptions);
|
|
@@ -10,6 +10,7 @@ export declare class SentryCli {
|
|
|
10
10
|
constructor(_argv: Args);
|
|
11
11
|
setResolveFunction(resolve: (path: string) => string): void;
|
|
12
12
|
convertAnswersToProperties(answers: Answers): SentryCliProps;
|
|
13
|
+
/** Create the contents of a `sentry.properties` file */
|
|
13
14
|
dumpProperties(props: SentryCliProps): string;
|
|
14
15
|
dumpConfig(config: SentryCliConfig): string;
|
|
15
16
|
}
|
|
@@ -29,6 +29,7 @@ var SentryCli = /** @class */ (function () {
|
|
|
29
29
|
}
|
|
30
30
|
return props;
|
|
31
31
|
};
|
|
32
|
+
/** Create the contents of a `sentry.properties` file */
|
|
32
33
|
SentryCli.prototype.dumpProperties = function (props) {
|
|
33
34
|
var rv = [];
|
|
34
35
|
for (var key in props) {
|
|
@@ -37,6 +38,7 @@ var SentryCli = /** @class */ (function () {
|
|
|
37
38
|
var value = props[key];
|
|
38
39
|
key = key.replace(/\//g, '.');
|
|
39
40
|
if (value === undefined || value === null) {
|
|
41
|
+
// comment that property out since it has no value
|
|
40
42
|
rv.push("#" + key + "=");
|
|
41
43
|
}
|
|
42
44
|
else {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SentryCli.js","sourceRoot":"","sources":["../../../lib/Helper/SentryCli.ts"],"names":[],"mappings":";;;AACA,0BAA4B;AAC5B,2BAA6B;AAU7B;IAIE,mBAAsB,KAAW;QAAX,UAAK,GAAL,KAAK,CAAM;QAHjC,sDAAsD;QAC9C,aAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAEC,CAAC;IAE9B,sCAAkB,GAAzB,UAA0B,OAAiC;QACzD,IAAI,CAAC,QAAQ,GAAG,OAAc,CAAC;IACjC,CAAC;IAEM,8CAA0B,GAAjC,UAAkC,OAAgB;QAChD,IAAM,KAAK,GAAmB,EAAE,CAAC;QACjC,KAAK,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;QACvC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,0BAA0B,EAAE,IAAI,CAAC,CAAC;QACzE,KAAK,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,qBAAqB,EAAE,IAAI,CAAC,CAAC;QACxE,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,mBAAmB,EAAE,IAAI,CAAC,CAAC;QAChE,IAAI;YACF,IAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,4BAA4B,CAAC,CAAC;YAC5D,KAAK,CAAC,gBAAgB,CAAC,GAAG,IAAI;iBAC3B,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC;iBAChC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;SAC3B;QAAC,OAAO,CAAC,EAAE;YACV,6CAA6C;SAC9C;QACD,OAAO,KAAK,CAAC;IACf,CAAC;
|
|
1
|
+
{"version":3,"file":"SentryCli.js","sourceRoot":"","sources":["../../../lib/Helper/SentryCli.ts"],"names":[],"mappings":";;;AACA,0BAA4B;AAC5B,2BAA6B;AAU7B;IAIE,mBAAsB,KAAW;QAAX,UAAK,GAAL,KAAK,CAAM;QAHjC,sDAAsD;QAC9C,aAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAEC,CAAC;IAE9B,sCAAkB,GAAzB,UAA0B,OAAiC;QACzD,IAAI,CAAC,QAAQ,GAAG,OAAc,CAAC;IACjC,CAAC;IAEM,8CAA0B,GAAjC,UAAkC,OAAgB;QAChD,IAAM,KAAK,GAAmB,EAAE,CAAC;QACjC,KAAK,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;QACvC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,0BAA0B,EAAE,IAAI,CAAC,CAAC;QACzE,KAAK,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,qBAAqB,EAAE,IAAI,CAAC,CAAC;QACxE,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,mBAAmB,EAAE,IAAI,CAAC,CAAC;QAChE,IAAI;YACF,IAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,4BAA4B,CAAC,CAAC;YAC5D,KAAK,CAAC,gBAAgB,CAAC,GAAG,IAAI;iBAC3B,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC;iBAChC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;SAC3B;QAAC,OAAO,CAAC,EAAE;YACV,6CAA6C;SAC9C;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,wDAAwD;IACjD,kCAAc,GAArB,UAAsB,KAAqB;QACzC,IAAM,EAAE,GAAG,EAAE,CAAC;QACd,KAAK,IAAI,GAAG,IAAI,KAAK,EAAE;YACrB,iDAAiD;YACjD,IAAI,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE;gBAC7B,IAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;gBACzB,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;gBAC9B,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE;oBACzC,kDAAkD;oBAClD,EAAE,CAAC,IAAI,CAAC,MAAI,GAAG,MAAG,CAAC,CAAC;iBACrB;qBAAM;oBACL,EAAE,CAAC,IAAI,CAAI,GAAG,SAAI,KAAO,CAAC,CAAC;iBAC5B;aACF;SACF;QACD,2CAA2C;QAC3C,OAAO,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC9B,CAAC;IAEM,8BAAU,GAAjB,UAAkB,MAAuB;QACvC,IAAM,cAAc,GAAa,EAAE,CAAC;QACpC,KAAK,IAAM,WAAW,IAAI,MAAM,EAAE;YAChC,iDAAiD;YACjD,IAAI,MAAM,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE;gBACtC,IAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;gBACvD,IAAM,OAAO,GAAG,MAAI,WAAW,WAAM,KAAO,CAAC;gBAC7C,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;aAC9B;SACF;QACD,OAAO,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC;IACH,gBAAC;AAAD,CAAC,AA3DD,IA2DC;AA3DY,8BAAS","sourcesContent":["import { Answers } from 'inquirer';\nimport * as _ from 'lodash';\nimport * as path from 'path';\n\nimport { Args } from '../Constants';\n\nexport interface SentryCliProps {\n [s: string]: string;\n}\n\ntype SentryCliConfig = Record<string, SentryCliProps>;\n\nexport class SentryCli {\n // eslint-disable-next-line @typescript-eslint/typedef\n private _resolve = require.resolve;\n\n constructor(protected _argv: Args) {}\n\n public setResolveFunction(resolve: (path: string) => string): void {\n this._resolve = resolve as any;\n }\n\n public convertAnswersToProperties(answers: Answers): SentryCliProps {\n const props: SentryCliProps = {};\n props['defaults/url'] = this._argv.url;\n props['defaults/org'] = _.get(answers, 'config.organization.slug', null);\n props['defaults/project'] = _.get(answers, 'config.project.slug', null);\n props['auth/token'] = _.get(answers, 'config.auth.token', null);\n try {\n const cliPath = this._resolve('@sentry/cli/bin/sentry-cli');\n props['cli/executable'] = path\n .relative(process.cwd(), cliPath)\n .replace(/\\\\/g, '\\\\\\\\');\n } catch (e) {\n // we do nothing and leave everyting as it is\n }\n return props;\n }\n\n /** Create the contents of a `sentry.properties` file */\n public dumpProperties(props: SentryCliProps): string {\n const rv = [];\n for (let key in props) {\n // eslint-disable-next-line no-prototype-builtins\n if (props.hasOwnProperty(key)) {\n const value = props[key];\n key = key.replace(/\\//g, '.');\n if (value === undefined || value === null) {\n // comment that property out since it has no value\n rv.push(`#${key}=`);\n } else {\n rv.push(`${key}=${value}`);\n }\n }\n }\n // eslint-disable-next-line prefer-template\n return rv.join('\\n') + '\\n';\n }\n\n public dumpConfig(config: SentryCliConfig): string {\n const dumpedSections: string[] = [];\n for (const sectionName in config) {\n // eslint-disable-next-line no-prototype-builtins\n if (config.hasOwnProperty(sectionName)) {\n const props = this.dumpProperties(config[sectionName]);\n const section = `[${sectionName}]\\n${props}`;\n dumpedSections.push(section);\n }\n }\n return dumpedSections.join('\\n');\n }\n}\n"]}
|
|
@@ -10,7 +10,7 @@ export declare abstract class BaseIntegration extends BaseStep {
|
|
|
10
10
|
/**
|
|
11
11
|
* This can be used for example for platform:boolean to determine
|
|
12
12
|
* if we should configure iOS/Android.
|
|
13
|
-
* Basically this will be merged into answers so it can be
|
|
13
|
+
* Basically this will be merged into answers so it can be checked by a later step.
|
|
14
14
|
*/
|
|
15
15
|
shouldConfigure(_answers: Answers): Promise<Answers>;
|
|
16
16
|
shouldEmit(_answers: Answers): Promise<boolean>;
|
|
@@ -71,7 +71,7 @@ var BaseIntegration = /** @class */ (function (_super) {
|
|
|
71
71
|
/**
|
|
72
72
|
* This can be used for example for platform:boolean to determine
|
|
73
73
|
* if we should configure iOS/Android.
|
|
74
|
-
* Basically this will be merged into answers so it can be
|
|
74
|
+
* Basically this will be merged into answers so it can be checked by a later step.
|
|
75
75
|
*/
|
|
76
76
|
BaseIntegration.prototype.shouldConfigure = function (_answers) {
|
|
77
77
|
return __awaiter(this, void 0, void 0, function () {
|
|
@@ -93,7 +93,8 @@ var BaseIntegration = /** @class */ (function (_super) {
|
|
|
93
93
|
_b = (_a = _).keys;
|
|
94
94
|
_d = (_c = _).pickBy;
|
|
95
95
|
return [4 /*yield*/, this.shouldConfigure(_answers)];
|
|
96
|
-
case 1: return [2 /*return*/, (_b.apply(_a, [_d.apply(_c, [_e.sent(),
|
|
96
|
+
case 1: return [2 /*return*/, (_b.apply(_a, [_d.apply(_c, [_e.sent(),
|
|
97
|
+
function (active) { return active; }])]).length > 0)];
|
|
97
98
|
}
|
|
98
99
|
});
|
|
99
100
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseIntegration.js","sourceRoot":"","sources":["../../../../lib/Steps/Integrations/BaseIntegration.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,0BAA4B;AAG5B,wCAAuC;AAEvC;IAA8C,mCAAQ;IAIpD,yBAAsB,KAAW;QAAjC,YACE,kBAAM,KAAK,CAAC,SAGb;QAJqB,WAAK,GAAL,KAAK,CAAM;QAE/B,kEAAkE;QAClE,KAAI,CAAC,IAAI,GAAG,KAAI,CAAC,SAAS,CAAC;;IAC7B,CAAC;IAEY,mCAAS,GAAtB,UAAuB,QAAiB;;;gBACtC,sBAAO,EAAE,EAAC;;;KACX;IAED;;;;OAIG;IACU,yCAAe,GAA5B,UAA6B,QAAiB;;;gBAC5C,IAAI,IAAI,CAAC,gBAAgB,EAAE;oBACzB,sBAAO,IAAI,CAAC,gBAAgB,EAAC;iBAC9B;gBACD,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC5D,sBAAO,IAAI,CAAC,gBAAgB,EAAC;;;KAC9B;IAEY,oCAAU,GAAvB,UAAwB,QAAiB;;;;;;wBAErC,KAAA,CAAA,KAAA,CAAC,CAAA,CAAC,IAAI,CAAA;wBACJ,KAAA,CAAA,KAAA,CAAC,CAAA,CAAC,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"BaseIntegration.js","sourceRoot":"","sources":["../../../../lib/Steps/Integrations/BaseIntegration.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,0BAA4B;AAG5B,wCAAuC;AAEvC;IAA8C,mCAAQ;IAIpD,yBAAsB,KAAW;QAAjC,YACE,kBAAM,KAAK,CAAC,SAGb;QAJqB,WAAK,GAAL,KAAK,CAAM;QAE/B,kEAAkE;QAClE,KAAI,CAAC,IAAI,GAAG,KAAI,CAAC,SAAS,CAAC;;IAC7B,CAAC;IAEY,mCAAS,GAAtB,UAAuB,QAAiB;;;gBACtC,sBAAO,EAAE,EAAC;;;KACX;IAED;;;;OAIG;IACU,yCAAe,GAA5B,UAA6B,QAAiB;;;gBAC5C,IAAI,IAAI,CAAC,gBAAgB,EAAE;oBACzB,sBAAO,IAAI,CAAC,gBAAgB,EAAC;iBAC9B;gBACD,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC5D,sBAAO,IAAI,CAAC,gBAAgB,EAAC;;;KAC9B;IAEY,oCAAU,GAAvB,UAAwB,QAAiB;;;;;;wBAErC,KAAA,CAAA,KAAA,CAAC,CAAA,CAAC,IAAI,CAAA;wBACJ,KAAA,CAAA,KAAA,CAAC,CAAA,CAAC,MAAM,CAAA;wBACN,qBAAM,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAA;4BAH1C,sBAAO,CACL,cACE,cACE,SAAoC;gCACpC,UAAC,MAAe,IAAK,OAAA,MAAM,EAAN,CAAM,EAC5B,EACF,CAAC,MAAM,GAAG,CAAC,CACb,EAAC;;;;KACH;IAGH,sBAAC;AAAD,CAAC,AAvCD,CAA8C,mBAAQ,GAuCrD;AAvCqB,0CAAe","sourcesContent":["import { Answers } from 'inquirer';\nimport * as _ from 'lodash';\n\nimport { Args } from '../../Constants';\nimport { BaseStep } from '../BaseStep';\n\nexport abstract class BaseIntegration extends BaseStep {\n public type: string;\n protected _shouldConfigure: Promise<Answers>;\n\n constructor(protected _argv: Args) {\n super(_argv);\n // @ts-ignore property construct does not exist on BaseIntegration\n this.type = this.construct;\n }\n\n public async uninstall(_answers: Answers): Promise<Answers> {\n return {};\n }\n\n /**\n * This can be used for example for platform:boolean to determine\n * if we should configure iOS/Android.\n * Basically this will be merged into answers so it can be checked by a later step.\n */\n public async shouldConfigure(_answers: Answers): Promise<Answers> {\n if (this._shouldConfigure) {\n return this._shouldConfigure;\n }\n this._shouldConfigure = Promise.resolve({ platform: true });\n return this._shouldConfigure;\n }\n\n public async shouldEmit(_answers: Answers): Promise<boolean> {\n return (\n _.keys(\n _.pickBy(\n await this.shouldConfigure(_answers),\n (active: boolean) => active,\n ),\n ).length > 0\n );\n }\n\n public abstract emit(answers: Answers): Promise<Answers>;\n}\n"]}
|
|
@@ -13,6 +13,7 @@ export declare class NextJs extends BaseIntegration {
|
|
|
13
13
|
private _createNextConfig;
|
|
14
14
|
private _setTemplate;
|
|
15
15
|
private _fillAndCopyTemplate;
|
|
16
|
-
private
|
|
17
|
-
private
|
|
16
|
+
private _checkUserNextVersion;
|
|
17
|
+
private _fulfillsVersionRange;
|
|
18
|
+
private _spliceInPlace;
|
|
18
19
|
}
|
|
@@ -59,8 +59,16 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
59
59
|
}
|
|
60
60
|
return t;
|
|
61
61
|
};
|
|
62
|
+
var __spreadArrays = (this && this.__spreadArrays) || function () {
|
|
63
|
+
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
|
|
64
|
+
for (var r = Array(s), k = 0, i = 0; i < il; i++)
|
|
65
|
+
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
|
|
66
|
+
r[k] = a[j];
|
|
67
|
+
return r;
|
|
68
|
+
};
|
|
62
69
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
63
70
|
exports.NextJs = void 0;
|
|
71
|
+
/* eslint-disable max-lines */
|
|
64
72
|
var fs = require("fs");
|
|
65
73
|
var inquirer_1 = require("inquirer");
|
|
66
74
|
var _ = require("lodash");
|
|
@@ -69,12 +77,20 @@ var semver_1 = require("semver");
|
|
|
69
77
|
var Logging_1 = require("../../Helper/Logging");
|
|
70
78
|
var SentryCli_1 = require("../../Helper/SentryCli");
|
|
71
79
|
var BaseIntegration_1 = require("./BaseIntegration");
|
|
72
|
-
var
|
|
80
|
+
var COMPATIBLE_NEXTJS_VERSIONS = '>=10.0.8 <13.0.0';
|
|
73
81
|
var PROPERTIES_FILENAME = 'sentry.properties';
|
|
74
82
|
var SENTRYCLIRC_FILENAME = '.sentryclirc';
|
|
75
83
|
var GITIGNORE_FILENAME = '.gitignore';
|
|
76
84
|
var CONFIG_DIR = 'configs/';
|
|
77
|
-
var
|
|
85
|
+
var MERGEABLE_CONFIG_INFIX = 'wizardcopy';
|
|
86
|
+
// for those files which can go in more than one place, the list of places they
|
|
87
|
+
// could go (the first one which works will be used)
|
|
88
|
+
var TEMPLATE_DESTINATIONS = {
|
|
89
|
+
'_error.js': ['pages', 'src/pages'],
|
|
90
|
+
'next.config.js': ['.'],
|
|
91
|
+
'sentry.server.config.js': ['.'],
|
|
92
|
+
'sentry.client.config.js': ['.'],
|
|
93
|
+
};
|
|
78
94
|
var appPackage = {};
|
|
79
95
|
try {
|
|
80
96
|
appPackage = require(path.join(process.cwd(), 'package.json'));
|
|
@@ -107,7 +123,7 @@ var NextJs = /** @class */ (function (_super) {
|
|
|
107
123
|
this._createNextConfig(configDirectory, dsn);
|
|
108
124
|
}
|
|
109
125
|
else {
|
|
110
|
-
Logging_1.debug("Couldn't find " + configDirectory + ", probably because you
|
|
126
|
+
Logging_1.debug("Couldn't find " + configDirectory + ", probably because you ran this from inside of `/lib` rather than `/dist`");
|
|
111
127
|
Logging_1.nl();
|
|
112
128
|
}
|
|
113
129
|
Logging_1.l('For more information, see https://docs.sentry.io/platforms/javascript/guides/nextjs/');
|
|
@@ -128,7 +144,7 @@ var NextJs = /** @class */ (function (_super) {
|
|
|
128
144
|
}
|
|
129
145
|
Logging_1.nl();
|
|
130
146
|
userAnswers = { continue: true };
|
|
131
|
-
if (!(!this.
|
|
147
|
+
if (!(!this._checkUserNextVersion('next') && !this._argv.quiet)) return [3 /*break*/, 2];
|
|
132
148
|
return [4 /*yield*/, inquirer_1.prompt({
|
|
133
149
|
message: 'There were errors during your project checkup, do you still want to continue?',
|
|
134
150
|
name: 'continue',
|
|
@@ -228,78 +244,92 @@ var NextJs = /** @class */ (function (_super) {
|
|
|
228
244
|
var templates = fs.readdirSync(configDirectory);
|
|
229
245
|
for (var _i = 0, templates_1 = templates; _i < templates_1.length; _i++) {
|
|
230
246
|
var template = templates_1[_i];
|
|
231
|
-
this._setTemplate(configDirectory, template, dsn);
|
|
247
|
+
this._setTemplate(configDirectory, template, TEMPLATE_DESTINATIONS[template], dsn);
|
|
232
248
|
}
|
|
233
249
|
Logging_1.red('⚠ Performance monitoring is enabled capturing 100% of transactions.\n' +
|
|
234
250
|
' Learn more in https://docs.sentry.io/product/performance/');
|
|
235
251
|
Logging_1.nl();
|
|
236
252
|
};
|
|
237
|
-
NextJs.prototype._setTemplate = function (configDirectory,
|
|
238
|
-
var templatePath = path.join(configDirectory,
|
|
239
|
-
var
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
+
NextJs.prototype._setTemplate = function (configDirectory, templateFile, destinationOptions, dsn) {
|
|
254
|
+
var templatePath = path.join(configDirectory, templateFile);
|
|
255
|
+
for (var _i = 0, destinationOptions_1 = destinationOptions; _i < destinationOptions_1.length; _i++) {
|
|
256
|
+
var destinationDir = destinationOptions_1[_i];
|
|
257
|
+
if (!fs.existsSync(destinationDir)) {
|
|
258
|
+
continue;
|
|
259
|
+
}
|
|
260
|
+
var destinationPath = path.join(destinationDir, templateFile);
|
|
261
|
+
// in case the file in question already exists, we'll make a copy with
|
|
262
|
+
// `MERGEABLE_CONFIG_INFIX` inserted just before the extension, so as not
|
|
263
|
+
// to overwrite the existing file
|
|
264
|
+
var mergeableFilePath = path.join(destinationDir, this._spliceInPlace(templateFile.split('.'), -1, 0, MERGEABLE_CONFIG_INFIX).join('.'));
|
|
265
|
+
if (!fs.existsSync(destinationPath)) {
|
|
266
|
+
this._fillAndCopyTemplate(templatePath, destinationPath, dsn);
|
|
267
|
+
}
|
|
268
|
+
else if (!fs.existsSync(mergeableFilePath)) {
|
|
269
|
+
this._fillAndCopyTemplate(templatePath, mergeableFilePath, dsn);
|
|
270
|
+
Logging_1.red("File `" + templateFile + "` already exists, so created `" + mergeableFilePath + "`.\n" +
|
|
271
|
+
'Please merge those files.');
|
|
272
|
+
Logging_1.nl();
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
Logging_1.red("Both `" + templateFile + "` and `" + mergeableFilePath + "` already exist.\n" +
|
|
276
|
+
'Please merge those files.');
|
|
277
|
+
Logging_1.nl();
|
|
278
|
+
}
|
|
279
|
+
return;
|
|
253
280
|
}
|
|
281
|
+
Logging_1.red("Could not find appropriate destination for `" + templateFile + "`. Tried: " + destinationOptions + ".");
|
|
282
|
+
Logging_1.nl();
|
|
254
283
|
};
|
|
255
284
|
NextJs.prototype._fillAndCopyTemplate = function (sourcePath, targetPath, dsn) {
|
|
256
285
|
var templateContent = fs.readFileSync(sourcePath).toString();
|
|
257
286
|
var filledTemplate = templateContent.replace('___DSN___', dsn);
|
|
258
287
|
fs.writeFileSync(targetPath, filledTemplate);
|
|
259
288
|
};
|
|
260
|
-
NextJs.prototype.
|
|
261
|
-
var
|
|
262
|
-
var
|
|
263
|
-
if (!
|
|
264
|
-
|
|
265
|
-
Logging_1.red(
|
|
266
|
-
Logging_1.red(" please install it with yarn/npm");
|
|
289
|
+
NextJs.prototype._checkUserNextVersion = function (packageName) {
|
|
290
|
+
var depsVersion = _.get(appPackage, ['dependencies', packageName]);
|
|
291
|
+
var devDepsVersion = _.get(appPackage, ['devDependencies', packageName]);
|
|
292
|
+
if (!depsVersion && !devDepsVersion) {
|
|
293
|
+
Logging_1.red("\u2717 " + packageName + " isn't in your dependencies.");
|
|
294
|
+
Logging_1.red(' Please install it with yarn/npm.');
|
|
267
295
|
return false;
|
|
268
296
|
}
|
|
269
|
-
else if (!this.
|
|
270
|
-
!this.
|
|
271
|
-
Logging_1.red("\u2717 Your
|
|
297
|
+
else if (!this._fulfillsVersionRange(depsVersion) &&
|
|
298
|
+
!this._fulfillsVersionRange(devDepsVersion)) {
|
|
299
|
+
Logging_1.red("\u2717 Your `package.json` specifies a version of `" + packageName + "` outside of the compatible version range " + COMPATIBLE_NEXTJS_VERSIONS + ".\n");
|
|
272
300
|
return false;
|
|
273
301
|
}
|
|
274
302
|
else {
|
|
275
|
-
|
|
276
|
-
Logging_1.green("\u2713 " + packageName + " >= " + MIN_NEXTJS_VERSION + " is installed");
|
|
277
|
-
}
|
|
278
|
-
else {
|
|
279
|
-
Logging_1.green("\u2713 " + packageName + " is installed");
|
|
280
|
-
}
|
|
303
|
+
Logging_1.green("\u2713 A compatible version of `" + packageName + "` is specified in `package.json`.");
|
|
281
304
|
return true;
|
|
282
305
|
}
|
|
283
306
|
};
|
|
284
|
-
NextJs.prototype.
|
|
285
|
-
// The latest version
|
|
286
|
-
// version, shouldn't be a blocker in the wizard.
|
|
307
|
+
NextJs.prototype._fulfillsVersionRange = function (version) {
|
|
308
|
+
// The latest version is currently 12.x, which is not yet supported.
|
|
287
309
|
if (version === 'latest') {
|
|
288
|
-
return
|
|
310
|
+
return false;
|
|
289
311
|
}
|
|
290
|
-
var
|
|
291
|
-
if (
|
|
292
|
-
|
|
293
|
-
|
|
312
|
+
var cleanedUserVersion, isRange;
|
|
313
|
+
if (semver_1.valid(version)) {
|
|
314
|
+
cleanedUserVersion = semver_1.valid(version);
|
|
315
|
+
isRange = false;
|
|
294
316
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
317
|
+
else if (semver_1.validRange(version)) {
|
|
318
|
+
cleanedUserVersion = semver_1.validRange(version);
|
|
319
|
+
isRange = true;
|
|
320
|
+
}
|
|
321
|
+
return (!!cleanedUserVersion &&
|
|
322
|
+
(isRange
|
|
323
|
+
? semver_1.subset(cleanedUserVersion, COMPATIBLE_NEXTJS_VERSIONS)
|
|
324
|
+
: semver_1.satisfies(cleanedUserVersion, COMPATIBLE_NEXTJS_VERSIONS)));
|
|
325
|
+
};
|
|
326
|
+
NextJs.prototype._spliceInPlace = function (arr, start, deleteCount) {
|
|
327
|
+
var inserts = [];
|
|
328
|
+
for (var _i = 3; _i < arguments.length; _i++) {
|
|
329
|
+
inserts[_i - 3] = arguments[_i];
|
|
301
330
|
}
|
|
302
|
-
|
|
331
|
+
arr.splice.apply(arr, __spreadArrays([start, deleteCount], inserts));
|
|
332
|
+
return arr;
|
|
303
333
|
};
|
|
304
334
|
return NextJs;
|
|
305
335
|
}(BaseIntegration_1.BaseIntegration));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NextJs.js","sourceRoot":"","sources":["../../../../lib/Steps/Integrations/NextJs.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'fs';\nimport { Answers, prompt } from 'inquirer';\nimport * as _ from 'lodash';\nimport * as path from 'path';\nimport { clean, gte, minVersion, satisfies, validRange } from 'semver';\n\nimport { Args } from '../../Constants';\nimport { debug, green, l, nl, red } from '../../Helper/Logging';\nimport { SentryCli, SentryCliProps } from '../../Helper/SentryCli';\nimport { BaseIntegration } from './BaseIntegration';\n\nconst MIN_NEXTJS_VERSION = '10.0.8'; // Must be a fixed version: `X.Y.Z`\nconst PROPERTIES_FILENAME = 'sentry.properties';\nconst SENTRYCLIRC_FILENAME = '.sentryclirc';\nconst GITIGNORE_FILENAME = '.gitignore';\nconst CONFIG_DIR = 'configs/';\nconst MERGEABLE_CONFIG_PREFIX = '_';\n\nlet appPackage: any = {};\n\ntry {\n appPackage = require(path.join(process.cwd(), 'package.json'));\n} catch {\n // We don't need to have this\n}\n\nexport class NextJs extends BaseIntegration {\n protected _sentryCli: SentryCli;\n\n constructor(protected _argv: Args) {\n super(_argv);\n this._sentryCli = new SentryCli(this._argv);\n }\n\n public async emit(answers: Answers): Promise<Answers> {\n const dsn = _.get(answers, ['config', 'dsn', 'public'], null);\n nl();\n\n const sentryCliProps = this._sentryCli.convertAnswersToProperties(answers);\n await this._createSentryCliConfig(sentryCliProps);\n\n const configDirectory = path.join(\n __dirname,\n '..',\n '..',\n '..',\n 'NextJs',\n CONFIG_DIR,\n );\n\n if (fs.existsSync(configDirectory)) {\n this._createNextConfig(configDirectory, dsn);\n } else {\n debug(\n `Couldn't find ${configDirectory}, probably because you run from src`,\n );\n nl();\n }\n\n l(\n 'For more information, see https://docs.sentry.io/platforms/javascript/guides/nextjs/',\n );\n nl();\n\n return {};\n }\n\n public async shouldConfigure(_answers: Answers): Promise<Answers> {\n if (this._shouldConfigure) {\n return this._shouldConfigure;\n }\n\n nl();\n\n let userAnswers: Answers = { continue: true };\n if (!this._checkDep('next', true) && !this._argv.quiet) {\n userAnswers = await prompt({\n message:\n 'There were errors during your project checkup, do you still want to continue?',\n name: 'continue',\n default: false,\n type: 'confirm',\n });\n }\n\n nl();\n\n if (!userAnswers['continue']) {\n throw new Error('Please install the required dependencies to continue.');\n }\n\n this._shouldConfigure = Promise.resolve({ nextjs: true });\n // eslint-disable-next-line @typescript-eslint/unbound-method\n return this.shouldConfigure;\n }\n\n private async _createSentryCliConfig(\n cliProps: SentryCliProps,\n ): Promise<void> {\n const { 'auth/token': authToken, ...cliPropsToWrite } = cliProps;\n\n /**\n * To not commit the auth token to the VCS, instead of adding it to the\n * properties file (like the rest of props), it's added to the Sentry CLI\n * config, which is added to the gitignore. This way makes the properties\n * file safe to commit without exposing any auth tokens.\n */\n if (authToken) {\n try {\n await fs.promises.appendFile(\n SENTRYCLIRC_FILENAME,\n this._sentryCli.dumpConfig({ auth: { token: authToken } }),\n );\n green(`✓ Successfully added the auth token to ${SENTRYCLIRC_FILENAME}`);\n } catch {\n red(\n `⚠ Could not add the auth token to ${SENTRYCLIRC_FILENAME}, ` +\n `please add it to identify your user account:\\n${authToken}`,\n );\n nl();\n }\n } else {\n red(\n `⚠ Did not find an auth token, please add your token to ${SENTRYCLIRC_FILENAME}`,\n );\n l(\n 'To generate an auth token, visit https://sentry.io/settings/account/api/auth-tokens/',\n );\n l(\n 'To learn how to configure Sentry CLI, visit ' +\n 'https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#configure-sentry-cli',\n );\n }\n\n await this._addToGitignore(\n SENTRYCLIRC_FILENAME,\n `⚠ Could not add ${SENTRYCLIRC_FILENAME} to ${GITIGNORE_FILENAME}, ` +\n 'please add it to not commit your auth key.',\n );\n\n try {\n await fs.promises.writeFile(\n `./${PROPERTIES_FILENAME}`,\n this._sentryCli.dumpProperties(cliPropsToWrite),\n );\n green(`✓ Successfully created sentry.properties`);\n } catch {\n red(`⚠ Could not add org and project data to ${PROPERTIES_FILENAME}`);\n l(\n 'See docs for a manual setup: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#configure-sentry-cli',\n );\n }\n nl();\n }\n\n private async _addToGitignore(\n filepath: string,\n errorMsg: string,\n ): Promise<void> {\n /**\n * Don't check whether the given file is ignored because:\n * 1. It's tricky to check it without git.\n * 2. Git might not be installed or accessible.\n * 3. It's convenient to use a module to interact with git, but it would\n * increase the size x2 approximately. Docs say to run the Wizard without\n * installing it, and duplicating the size would slow the set-up down.\n * 4. The Wizard is meant to be run once.\n * 5. A message is logged informing users it's been added to the gitignore.\n * 6. It will be added to the gitignore as many times as it runs - not a big\n * deal.\n * 7. It's straightforward to remove it from the gitignore.\n */\n try {\n await fs.promises.appendFile(\n GITIGNORE_FILENAME,\n `\\n# Sentry\\n${filepath}\\n`,\n );\n green(`✓ ${filepath} added to ${GITIGNORE_FILENAME}`);\n } catch {\n red(errorMsg);\n }\n }\n\n private _createNextConfig(configDirectory: string, dsn: any): void {\n const templates = fs.readdirSync(configDirectory);\n for (const template of templates) {\n this._setTemplate(configDirectory, template, dsn);\n }\n red(\n '⚠ Performance monitoring is enabled capturing 100% of transactions.\\n' +\n ' Learn more in https://docs.sentry.io/product/performance/',\n );\n nl();\n }\n\n private _setTemplate(\n configDirectory: string,\n template: string,\n dsn: string,\n ): void {\n const templatePath = path.join(configDirectory, template);\n const mergeableFile = MERGEABLE_CONFIG_PREFIX + template;\n if (!fs.existsSync(template)) {\n this._fillAndCopyTemplate(templatePath, template, dsn);\n } else if (!fs.existsSync(mergeableFile)) {\n this._fillAndCopyTemplate(templatePath, mergeableFile, dsn);\n red(\n `File ${template} already exists, so created ${mergeableFile}.\\n` +\n `Please, merge those files.`,\n );\n nl();\n } else {\n red(\n `File ${template} already exists, and ${mergeableFile} also exists.\\n` +\n 'Please, merge those files.',\n );\n nl();\n }\n }\n\n private _fillAndCopyTemplate(\n sourcePath: string,\n targetPath: string,\n dsn: string,\n ): void {\n const templateContent = fs.readFileSync(sourcePath).toString();\n const filledTemplate = templateContent.replace('___DSN___', dsn);\n fs.writeFileSync(targetPath, filledTemplate);\n }\n\n private _checkDep(packageName: string, minVersion?: boolean): boolean {\n const depVersion = _.get(\n appPackage,\n ['dependencies', packageName],\n '0.0.0',\n );\n const devDepVersion = _.get(\n appPackage,\n ['devDependencies', packageName],\n '0.0.0',\n );\n\n if (\n !_.get(appPackage, `dependencies.${packageName}`, false) &&\n !_.get(appPackage, `devDependencies.${packageName}`, false)\n ) {\n red(`✗ ${packageName} isn't in your dependencies`);\n red(` please install it with yarn/npm`);\n return false;\n } else if (\n !this._fulfillsMinVersion(depVersion) &&\n !this._fulfillsMinVersion(devDepVersion)\n ) {\n red(\n `✗ Your installed version of \\`${packageName}\\` is not supported, >=${MIN_NEXTJS_VERSION} needed.`,\n );\n return false;\n } else {\n if (minVersion) {\n green(`✓ ${packageName} >= ${MIN_NEXTJS_VERSION} is installed`);\n } else {\n green(`✓ ${packageName} is installed`);\n }\n return true;\n }\n }\n\n private _fulfillsMinVersion(version: string): boolean {\n // The latest version, which at the moment is greater than the minimum\n // version, shouldn't be a blocker in the wizard.\n if (version === 'latest') {\n return true;\n }\n\n const cleanedVersion = clean(version);\n if (cleanedVersion) {\n // gte(x, y) : true if x >= y\n return gte(cleanedVersion, MIN_NEXTJS_VERSION);\n }\n\n const minVersionRange = `>=${MIN_NEXTJS_VERSION}`;\n const userVersionRange = validRange(version);\n const minUserVersion = minVersion(userVersionRange);\n if (minUserVersion == null) {\n // This should never happen\n return false;\n }\n return satisfies(minUserVersion, minVersionRange);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"NextJs.js","sourceRoot":"","sources":["../../../../lib/Steps/Integrations/NextJs.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable max-lines */\nimport * as fs from 'fs';\nimport { Answers, prompt } from 'inquirer';\nimport * as _ from 'lodash';\nimport * as path from 'path';\nimport { satisfies, subset, valid, validRange } from 'semver';\n\nimport { Args } from '../../Constants';\nimport { debug, green, l, nl, red } from '../../Helper/Logging';\nimport { SentryCli, SentryCliProps } from '../../Helper/SentryCli';\nimport { BaseIntegration } from './BaseIntegration';\n\nconst COMPATIBLE_NEXTJS_VERSIONS = '>=10.0.8 <13.0.0';\nconst PROPERTIES_FILENAME = 'sentry.properties';\nconst SENTRYCLIRC_FILENAME = '.sentryclirc';\nconst GITIGNORE_FILENAME = '.gitignore';\nconst CONFIG_DIR = 'configs/';\nconst MERGEABLE_CONFIG_INFIX = 'wizardcopy';\n\n// for those files which can go in more than one place, the list of places they\n// could go (the first one which works will be used)\nconst TEMPLATE_DESTINATIONS: { [key: string]: string[] } = {\n '_error.js': ['pages', 'src/pages'],\n 'next.config.js': ['.'],\n 'sentry.server.config.js': ['.'],\n 'sentry.client.config.js': ['.'],\n};\n\nlet appPackage: any = {};\n\ntry {\n appPackage = require(path.join(process.cwd(), 'package.json'));\n} catch {\n // We don't need to have this\n}\n\nexport class NextJs extends BaseIntegration {\n protected _sentryCli: SentryCli;\n\n constructor(protected _argv: Args) {\n super(_argv);\n this._sentryCli = new SentryCli(this._argv);\n }\n\n public async emit(answers: Answers): Promise<Answers> {\n const dsn = _.get(answers, ['config', 'dsn', 'public'], null);\n nl();\n\n const sentryCliProps = this._sentryCli.convertAnswersToProperties(answers);\n await this._createSentryCliConfig(sentryCliProps);\n\n const configDirectory = path.join(\n __dirname,\n '..',\n '..',\n '..',\n 'NextJs',\n CONFIG_DIR,\n );\n\n if (fs.existsSync(configDirectory)) {\n this._createNextConfig(configDirectory, dsn);\n } else {\n debug(\n `Couldn't find ${configDirectory}, probably because you ran this from inside of \\`/lib\\` rather than \\`/dist\\``,\n );\n nl();\n }\n\n l(\n 'For more information, see https://docs.sentry.io/platforms/javascript/guides/nextjs/',\n );\n nl();\n\n return {};\n }\n\n public async shouldConfigure(_answers: Answers): Promise<Answers> {\n if (this._shouldConfigure) {\n return this._shouldConfigure;\n }\n\n nl();\n\n let userAnswers: Answers = { continue: true };\n if (!this._checkUserNextVersion('next') && !this._argv.quiet) {\n userAnswers = await prompt({\n message:\n 'There were errors during your project checkup, do you still want to continue?',\n name: 'continue',\n default: false,\n type: 'confirm',\n });\n }\n\n nl();\n\n if (!userAnswers['continue']) {\n throw new Error('Please install the required dependencies to continue.');\n }\n\n this._shouldConfigure = Promise.resolve({ nextjs: true });\n // eslint-disable-next-line @typescript-eslint/unbound-method\n return this.shouldConfigure;\n }\n\n private async _createSentryCliConfig(\n cliProps: SentryCliProps,\n ): Promise<void> {\n const { 'auth/token': authToken, ...cliPropsToWrite } = cliProps;\n\n /**\n * To not commit the auth token to the VCS, instead of adding it to the\n * properties file (like the rest of props), it's added to the Sentry CLI\n * config, which is added to the gitignore. This way makes the properties\n * file safe to commit without exposing any auth tokens.\n */\n if (authToken) {\n try {\n await fs.promises.appendFile(\n SENTRYCLIRC_FILENAME,\n this._sentryCli.dumpConfig({ auth: { token: authToken } }),\n );\n green(`✓ Successfully added the auth token to ${SENTRYCLIRC_FILENAME}`);\n } catch {\n red(\n `⚠ Could not add the auth token to ${SENTRYCLIRC_FILENAME}, ` +\n `please add it to identify your user account:\\n${authToken}`,\n );\n nl();\n }\n } else {\n red(\n `⚠ Did not find an auth token, please add your token to ${SENTRYCLIRC_FILENAME}`,\n );\n l(\n 'To generate an auth token, visit https://sentry.io/settings/account/api/auth-tokens/',\n );\n l(\n 'To learn how to configure Sentry CLI, visit ' +\n 'https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#configure-sentry-cli',\n );\n }\n\n await this._addToGitignore(\n SENTRYCLIRC_FILENAME,\n `⚠ Could not add ${SENTRYCLIRC_FILENAME} to ${GITIGNORE_FILENAME}, ` +\n 'please add it to not commit your auth key.',\n );\n\n try {\n await fs.promises.writeFile(\n `./${PROPERTIES_FILENAME}`,\n this._sentryCli.dumpProperties(cliPropsToWrite),\n );\n green(`✓ Successfully created sentry.properties`);\n } catch {\n red(`⚠ Could not add org and project data to ${PROPERTIES_FILENAME}`);\n l(\n 'See docs for a manual setup: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#configure-sentry-cli',\n );\n }\n nl();\n }\n\n private async _addToGitignore(\n filepath: string,\n errorMsg: string,\n ): Promise<void> {\n /**\n * Don't check whether the given file is ignored because:\n * 1. It's tricky to check it without git.\n * 2. Git might not be installed or accessible.\n * 3. It's convenient to use a module to interact with git, but it would\n * increase the size x2 approximately. Docs say to run the Wizard without\n * installing it, and duplicating the size would slow the set-up down.\n * 4. The Wizard is meant to be run once.\n * 5. A message is logged informing users it's been added to the gitignore.\n * 6. It will be added to the gitignore as many times as it runs - not a big\n * deal.\n * 7. It's straightforward to remove it from the gitignore.\n */\n try {\n await fs.promises.appendFile(\n GITIGNORE_FILENAME,\n `\\n# Sentry\\n${filepath}\\n`,\n );\n green(`✓ ${filepath} added to ${GITIGNORE_FILENAME}`);\n } catch {\n red(errorMsg);\n }\n }\n\n private _createNextConfig(configDirectory: string, dsn: any): void {\n const templates = fs.readdirSync(configDirectory);\n for (const template of templates) {\n this._setTemplate(\n configDirectory,\n template,\n TEMPLATE_DESTINATIONS[template],\n dsn,\n );\n }\n red(\n '⚠ Performance monitoring is enabled capturing 100% of transactions.\\n' +\n ' Learn more in https://docs.sentry.io/product/performance/',\n );\n nl();\n }\n\n private _setTemplate(\n configDirectory: string,\n templateFile: string,\n destinationOptions: string[],\n dsn: string,\n ): void {\n const templatePath = path.join(configDirectory, templateFile);\n\n for (const destinationDir of destinationOptions) {\n if (!fs.existsSync(destinationDir)) {\n continue;\n }\n\n const destinationPath = path.join(destinationDir, templateFile);\n // in case the file in question already exists, we'll make a copy with\n // `MERGEABLE_CONFIG_INFIX` inserted just before the extension, so as not\n // to overwrite the existing file\n const mergeableFilePath = path.join(\n destinationDir,\n this._spliceInPlace(\n templateFile.split('.'),\n -1,\n 0,\n MERGEABLE_CONFIG_INFIX,\n ).join('.'),\n );\n\n if (!fs.existsSync(destinationPath)) {\n this._fillAndCopyTemplate(templatePath, destinationPath, dsn);\n } else if (!fs.existsSync(mergeableFilePath)) {\n this._fillAndCopyTemplate(templatePath, mergeableFilePath, dsn);\n red(\n `File \\`${templateFile}\\` already exists, so created \\`${mergeableFilePath}\\`.\\n` +\n 'Please merge those files.',\n );\n nl();\n } else {\n red(\n `Both \\`${templateFile}\\` and \\`${mergeableFilePath}\\` already exist.\\n` +\n 'Please merge those files.',\n );\n nl();\n }\n return;\n }\n\n red(\n `Could not find appropriate destination for \\`${templateFile}\\`. Tried: ${destinationOptions}.`,\n );\n nl();\n }\n\n private _fillAndCopyTemplate(\n sourcePath: string,\n targetPath: string,\n dsn: string,\n ): void {\n const templateContent = fs.readFileSync(sourcePath).toString();\n const filledTemplate = templateContent.replace('___DSN___', dsn);\n fs.writeFileSync(targetPath, filledTemplate);\n }\n\n private _checkUserNextVersion(packageName: string): boolean {\n const depsVersion = _.get(appPackage, ['dependencies', packageName]);\n const devDepsVersion = _.get(appPackage, ['devDependencies', packageName]);\n\n if (!depsVersion && !devDepsVersion) {\n red(`✗ ${packageName} isn't in your dependencies.`);\n red(' Please install it with yarn/npm.');\n return false;\n } else if (\n !this._fulfillsVersionRange(depsVersion) &&\n !this._fulfillsVersionRange(devDepsVersion)\n ) {\n red(\n `✗ Your \\`package.json\\` specifies a version of \\`${packageName}\\` outside of the compatible version range ${COMPATIBLE_NEXTJS_VERSIONS}.\\n`,\n );\n return false;\n } else {\n green(\n `✓ A compatible version of \\`${packageName}\\` is specified in \\`package.json\\`.`,\n );\n return true;\n }\n }\n\n private _fulfillsVersionRange(version: string): boolean {\n // The latest version is currently 12.x, which is not yet supported.\n if (version === 'latest') {\n return false;\n }\n\n let cleanedUserVersion, isRange;\n\n if (valid(version)) {\n cleanedUserVersion = valid(version);\n isRange = false;\n } else if (validRange(version)) {\n cleanedUserVersion = validRange(version);\n isRange = true;\n }\n\n return (\n !!cleanedUserVersion &&\n (isRange\n ? subset(cleanedUserVersion, COMPATIBLE_NEXTJS_VERSIONS)\n : satisfies(cleanedUserVersion, COMPATIBLE_NEXTJS_VERSIONS))\n );\n }\n\n private _spliceInPlace(\n arr: Array<any>,\n start: number,\n deleteCount: number,\n ...inserts: any[]\n ): Array<any> {\n arr.splice(start, deleteCount, ...inserts);\n return arr;\n }\n}\n"]}
|
package/lib/Helper/SentryCli.ts
CHANGED
|
@@ -37,6 +37,7 @@ export class SentryCli {
|
|
|
37
37
|
return props;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
/** Create the contents of a `sentry.properties` file */
|
|
40
41
|
public dumpProperties(props: SentryCliProps): string {
|
|
41
42
|
const rv = [];
|
|
42
43
|
for (let key in props) {
|
|
@@ -45,6 +46,7 @@ export class SentryCli {
|
|
|
45
46
|
const value = props[key];
|
|
46
47
|
key = key.replace(/\//g, '.');
|
|
47
48
|
if (value === undefined || value === null) {
|
|
49
|
+
// comment that property out since it has no value
|
|
48
50
|
rv.push(`#${key}=`);
|
|
49
51
|
} else {
|
|
50
52
|
rv.push(`${key}=${value}`);
|
|
@@ -21,7 +21,7 @@ export abstract class BaseIntegration extends BaseStep {
|
|
|
21
21
|
/**
|
|
22
22
|
* This can be used for example for platform:boolean to determine
|
|
23
23
|
* if we should configure iOS/Android.
|
|
24
|
-
* Basically this will be merged into answers so it can be
|
|
24
|
+
* Basically this will be merged into answers so it can be checked by a later step.
|
|
25
25
|
*/
|
|
26
26
|
public async shouldConfigure(_answers: Answers): Promise<Answers> {
|
|
27
27
|
if (this._shouldConfigure) {
|
|
@@ -34,7 +34,10 @@ export abstract class BaseIntegration extends BaseStep {
|
|
|
34
34
|
public async shouldEmit(_answers: Answers): Promise<boolean> {
|
|
35
35
|
return (
|
|
36
36
|
_.keys(
|
|
37
|
-
_.pickBy(
|
|
37
|
+
_.pickBy(
|
|
38
|
+
await this.shouldConfigure(_answers),
|
|
39
|
+
(active: boolean) => active,
|
|
40
|
+
),
|
|
38
41
|
).length > 0
|
|
39
42
|
);
|
|
40
43
|
}
|
|
@@ -1,20 +1,30 @@
|
|
|
1
|
+
/* eslint-disable max-lines */
|
|
1
2
|
import * as fs from 'fs';
|
|
2
3
|
import { Answers, prompt } from 'inquirer';
|
|
3
4
|
import * as _ from 'lodash';
|
|
4
5
|
import * as path from 'path';
|
|
5
|
-
import {
|
|
6
|
+
import { satisfies, subset, valid, validRange } from 'semver';
|
|
6
7
|
|
|
7
8
|
import { Args } from '../../Constants';
|
|
8
9
|
import { debug, green, l, nl, red } from '../../Helper/Logging';
|
|
9
10
|
import { SentryCli, SentryCliProps } from '../../Helper/SentryCli';
|
|
10
11
|
import { BaseIntegration } from './BaseIntegration';
|
|
11
12
|
|
|
12
|
-
const
|
|
13
|
+
const COMPATIBLE_NEXTJS_VERSIONS = '>=10.0.8 <13.0.0';
|
|
13
14
|
const PROPERTIES_FILENAME = 'sentry.properties';
|
|
14
15
|
const SENTRYCLIRC_FILENAME = '.sentryclirc';
|
|
15
16
|
const GITIGNORE_FILENAME = '.gitignore';
|
|
16
17
|
const CONFIG_DIR = 'configs/';
|
|
17
|
-
const
|
|
18
|
+
const MERGEABLE_CONFIG_INFIX = 'wizardcopy';
|
|
19
|
+
|
|
20
|
+
// for those files which can go in more than one place, the list of places they
|
|
21
|
+
// could go (the first one which works will be used)
|
|
22
|
+
const TEMPLATE_DESTINATIONS: { [key: string]: string[] } = {
|
|
23
|
+
'_error.js': ['pages', 'src/pages'],
|
|
24
|
+
'next.config.js': ['.'],
|
|
25
|
+
'sentry.server.config.js': ['.'],
|
|
26
|
+
'sentry.client.config.js': ['.'],
|
|
27
|
+
};
|
|
18
28
|
|
|
19
29
|
let appPackage: any = {};
|
|
20
30
|
|
|
@@ -52,7 +62,7 @@ export class NextJs extends BaseIntegration {
|
|
|
52
62
|
this._createNextConfig(configDirectory, dsn);
|
|
53
63
|
} else {
|
|
54
64
|
debug(
|
|
55
|
-
`Couldn't find ${configDirectory}, probably because you
|
|
65
|
+
`Couldn't find ${configDirectory}, probably because you ran this from inside of \`/lib\` rather than \`/dist\``,
|
|
56
66
|
);
|
|
57
67
|
nl();
|
|
58
68
|
}
|
|
@@ -73,7 +83,7 @@ export class NextJs extends BaseIntegration {
|
|
|
73
83
|
nl();
|
|
74
84
|
|
|
75
85
|
let userAnswers: Answers = { continue: true };
|
|
76
|
-
if (!this.
|
|
86
|
+
if (!this._checkUserNextVersion('next') && !this._argv.quiet) {
|
|
77
87
|
userAnswers = await prompt({
|
|
78
88
|
message:
|
|
79
89
|
'There were errors during your project checkup, do you still want to continue?',
|
|
@@ -184,7 +194,12 @@ export class NextJs extends BaseIntegration {
|
|
|
184
194
|
private _createNextConfig(configDirectory: string, dsn: any): void {
|
|
185
195
|
const templates = fs.readdirSync(configDirectory);
|
|
186
196
|
for (const template of templates) {
|
|
187
|
-
this._setTemplate(
|
|
197
|
+
this._setTemplate(
|
|
198
|
+
configDirectory,
|
|
199
|
+
template,
|
|
200
|
+
TEMPLATE_DESTINATIONS[template],
|
|
201
|
+
dsn,
|
|
202
|
+
);
|
|
188
203
|
}
|
|
189
204
|
red(
|
|
190
205
|
'⚠ Performance monitoring is enabled capturing 100% of transactions.\n' +
|
|
@@ -195,27 +210,54 @@ export class NextJs extends BaseIntegration {
|
|
|
195
210
|
|
|
196
211
|
private _setTemplate(
|
|
197
212
|
configDirectory: string,
|
|
198
|
-
|
|
213
|
+
templateFile: string,
|
|
214
|
+
destinationOptions: string[],
|
|
199
215
|
dsn: string,
|
|
200
216
|
): void {
|
|
201
|
-
const templatePath = path.join(configDirectory,
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
'
|
|
217
|
+
const templatePath = path.join(configDirectory, templateFile);
|
|
218
|
+
|
|
219
|
+
for (const destinationDir of destinationOptions) {
|
|
220
|
+
if (!fs.existsSync(destinationDir)) {
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const destinationPath = path.join(destinationDir, templateFile);
|
|
225
|
+
// in case the file in question already exists, we'll make a copy with
|
|
226
|
+
// `MERGEABLE_CONFIG_INFIX` inserted just before the extension, so as not
|
|
227
|
+
// to overwrite the existing file
|
|
228
|
+
const mergeableFilePath = path.join(
|
|
229
|
+
destinationDir,
|
|
230
|
+
this._spliceInPlace(
|
|
231
|
+
templateFile.split('.'),
|
|
232
|
+
-1,
|
|
233
|
+
0,
|
|
234
|
+
MERGEABLE_CONFIG_INFIX,
|
|
235
|
+
).join('.'),
|
|
216
236
|
);
|
|
217
|
-
|
|
237
|
+
|
|
238
|
+
if (!fs.existsSync(destinationPath)) {
|
|
239
|
+
this._fillAndCopyTemplate(templatePath, destinationPath, dsn);
|
|
240
|
+
} else if (!fs.existsSync(mergeableFilePath)) {
|
|
241
|
+
this._fillAndCopyTemplate(templatePath, mergeableFilePath, dsn);
|
|
242
|
+
red(
|
|
243
|
+
`File \`${templateFile}\` already exists, so created \`${mergeableFilePath}\`.\n` +
|
|
244
|
+
'Please merge those files.',
|
|
245
|
+
);
|
|
246
|
+
nl();
|
|
247
|
+
} else {
|
|
248
|
+
red(
|
|
249
|
+
`Both \`${templateFile}\` and \`${mergeableFilePath}\` already exist.\n` +
|
|
250
|
+
'Please merge those files.',
|
|
251
|
+
);
|
|
252
|
+
nl();
|
|
253
|
+
}
|
|
254
|
+
return;
|
|
218
255
|
}
|
|
256
|
+
|
|
257
|
+
red(
|
|
258
|
+
`Could not find appropriate destination for \`${templateFile}\`. Tried: ${destinationOptions}.`,
|
|
259
|
+
);
|
|
260
|
+
nl();
|
|
219
261
|
}
|
|
220
262
|
|
|
221
263
|
private _fillAndCopyTemplate(
|
|
@@ -228,63 +270,61 @@ export class NextJs extends BaseIntegration {
|
|
|
228
270
|
fs.writeFileSync(targetPath, filledTemplate);
|
|
229
271
|
}
|
|
230
272
|
|
|
231
|
-
private
|
|
232
|
-
const
|
|
233
|
-
|
|
234
|
-
['dependencies', packageName],
|
|
235
|
-
'0.0.0',
|
|
236
|
-
);
|
|
237
|
-
const devDepVersion = _.get(
|
|
238
|
-
appPackage,
|
|
239
|
-
['devDependencies', packageName],
|
|
240
|
-
'0.0.0',
|
|
241
|
-
);
|
|
273
|
+
private _checkUserNextVersion(packageName: string): boolean {
|
|
274
|
+
const depsVersion = _.get(appPackage, ['dependencies', packageName]);
|
|
275
|
+
const devDepsVersion = _.get(appPackage, ['devDependencies', packageName]);
|
|
242
276
|
|
|
243
|
-
if (
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
) {
|
|
247
|
-
red(`✗ ${packageName} isn't in your dependencies`);
|
|
248
|
-
red(` please install it with yarn/npm`);
|
|
277
|
+
if (!depsVersion && !devDepsVersion) {
|
|
278
|
+
red(`✗ ${packageName} isn't in your dependencies.`);
|
|
279
|
+
red(' Please install it with yarn/npm.');
|
|
249
280
|
return false;
|
|
250
281
|
} else if (
|
|
251
|
-
!this.
|
|
252
|
-
!this.
|
|
282
|
+
!this._fulfillsVersionRange(depsVersion) &&
|
|
283
|
+
!this._fulfillsVersionRange(devDepsVersion)
|
|
253
284
|
) {
|
|
254
285
|
red(
|
|
255
|
-
`✗ Your
|
|
286
|
+
`✗ Your \`package.json\` specifies a version of \`${packageName}\` outside of the compatible version range ${COMPATIBLE_NEXTJS_VERSIONS}.\n`,
|
|
256
287
|
);
|
|
257
288
|
return false;
|
|
258
289
|
} else {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
green(`✓ ${packageName} is installed`);
|
|
263
|
-
}
|
|
290
|
+
green(
|
|
291
|
+
`✓ A compatible version of \`${packageName}\` is specified in \`package.json\`.`,
|
|
292
|
+
);
|
|
264
293
|
return true;
|
|
265
294
|
}
|
|
266
295
|
}
|
|
267
296
|
|
|
268
|
-
private
|
|
269
|
-
// The latest version
|
|
270
|
-
// version, shouldn't be a blocker in the wizard.
|
|
297
|
+
private _fulfillsVersionRange(version: string): boolean {
|
|
298
|
+
// The latest version is currently 12.x, which is not yet supported.
|
|
271
299
|
if (version === 'latest') {
|
|
272
|
-
return
|
|
300
|
+
return false;
|
|
273
301
|
}
|
|
274
302
|
|
|
275
|
-
|
|
276
|
-
if (cleanedVersion) {
|
|
277
|
-
// gte(x, y) : true if x >= y
|
|
278
|
-
return gte(cleanedVersion, MIN_NEXTJS_VERSION);
|
|
279
|
-
}
|
|
303
|
+
let cleanedUserVersion, isRange;
|
|
280
304
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
if (
|
|
285
|
-
|
|
286
|
-
|
|
305
|
+
if (valid(version)) {
|
|
306
|
+
cleanedUserVersion = valid(version);
|
|
307
|
+
isRange = false;
|
|
308
|
+
} else if (validRange(version)) {
|
|
309
|
+
cleanedUserVersion = validRange(version);
|
|
310
|
+
isRange = true;
|
|
287
311
|
}
|
|
288
|
-
|
|
312
|
+
|
|
313
|
+
return (
|
|
314
|
+
!!cleanedUserVersion &&
|
|
315
|
+
(isRange
|
|
316
|
+
? subset(cleanedUserVersion, COMPATIBLE_NEXTJS_VERSIONS)
|
|
317
|
+
: satisfies(cleanedUserVersion, COMPATIBLE_NEXTJS_VERSIONS))
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
private _spliceInPlace(
|
|
322
|
+
arr: Array<any>,
|
|
323
|
+
start: number,
|
|
324
|
+
deleteCount: number,
|
|
325
|
+
...inserts: any[]
|
|
326
|
+
): Array<any> {
|
|
327
|
+
arr.splice(start, deleteCount, ...inserts);
|
|
328
|
+
return arr;
|
|
289
329
|
}
|
|
290
330
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentry/wizard",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.17",
|
|
4
4
|
"homepage": "https://github.com/getsentry/sentry-wizard",
|
|
5
5
|
"repository": "https://github.com/getsentry/sentry-wizard",
|
|
6
6
|
"description": "Sentry wizard helping you to configure your project",
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import NextErrorComponent from 'next/error';
|
|
2
|
+
|
|
3
|
+
import * as Sentry from '@sentry/nextjs';
|
|
4
|
+
|
|
5
|
+
const MyError = ({ statusCode, hasGetInitialPropsRun, err }) => {
|
|
6
|
+
if (!hasGetInitialPropsRun && err) {
|
|
7
|
+
// getInitialProps is not called in case of
|
|
8
|
+
// https://github.com/vercel/next.js/issues/8592. As a workaround, we pass
|
|
9
|
+
// err via _app.js so it can be captured
|
|
10
|
+
Sentry.captureException(err);
|
|
11
|
+
// Flushing is not required in this case as it only happens on the client
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return <NextErrorComponent statusCode={statusCode} />;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
MyError.getInitialProps = async (context) => {
|
|
18
|
+
const errorInitialProps = await NextErrorComponent.getInitialProps(context);
|
|
19
|
+
|
|
20
|
+
const { res, err, asPath } = context;
|
|
21
|
+
|
|
22
|
+
// Workaround for https://github.com/vercel/next.js/issues/8592, mark when
|
|
23
|
+
// getInitialProps has run
|
|
24
|
+
errorInitialProps.hasGetInitialPropsRun = true;
|
|
25
|
+
|
|
26
|
+
// Returning early because we don't want to log 404 errors to Sentry.
|
|
27
|
+
if (res?.statusCode === 404) {
|
|
28
|
+
return errorInitialProps;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Running on the server, the response object (`res`) is available.
|
|
32
|
+
//
|
|
33
|
+
// Next.js will pass an err on the server if a page's data fetching methods
|
|
34
|
+
// threw or returned a Promise that rejected
|
|
35
|
+
//
|
|
36
|
+
// Running on the client (browser), Next.js will provide an err if:
|
|
37
|
+
//
|
|
38
|
+
// - a page's `getInitialProps` threw or returned a Promise that rejected
|
|
39
|
+
// - an exception was thrown somewhere in the React lifecycle (render,
|
|
40
|
+
// componentDidMount, etc) that was caught by Next.js's React Error
|
|
41
|
+
// Boundary. Read more about what types of exceptions are caught by Error
|
|
42
|
+
// Boundaries: https://reactjs.org/docs/error-boundaries.html
|
|
43
|
+
|
|
44
|
+
if (err) {
|
|
45
|
+
Sentry.captureException(err);
|
|
46
|
+
|
|
47
|
+
// Flushing before returning is necessary if deploying to Vercel, see
|
|
48
|
+
// https://vercel.com/docs/platform/limits#streaming-responses
|
|
49
|
+
await Sentry.flush(2000);
|
|
50
|
+
|
|
51
|
+
return errorInitialProps;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// If this point is reached, getInitialProps was called without any
|
|
55
|
+
// information about what the error might be. This is unexpected and may
|
|
56
|
+
// indicate a bug introduced in Next.js, so record it in Sentry
|
|
57
|
+
Sentry.captureException(
|
|
58
|
+
new Error(`_error.js getInitialProps missing data at path: ${asPath}`),
|
|
59
|
+
);
|
|
60
|
+
await Sentry.flush(2000);
|
|
61
|
+
|
|
62
|
+
return errorInitialProps;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
export default MyError;
|
|
@@ -9,7 +9,7 @@ const moduleExports = {
|
|
|
9
9
|
// Your existing module.exports
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
-
const
|
|
12
|
+
const sentryWebpackPluginOptions = {
|
|
13
13
|
// Additional config options for the Sentry Webpack plugin. Keep in mind that
|
|
14
14
|
// the following options are set automatically, and overriding them is not
|
|
15
15
|
// recommended:
|
|
@@ -23,4 +23,4 @@ const SentryWebpackPluginOptions = {
|
|
|
23
23
|
|
|
24
24
|
// Make sure adding Sentry options is the last code to run before exporting, to
|
|
25
25
|
// ensure that your source maps include changes from all other Webpack plugins
|
|
26
|
-
module.exports = withSentryConfig(moduleExports,
|
|
26
|
+
module.exports = withSentryConfig(moduleExports, sentryWebpackPluginOptions);
|