@sentry/wizard 2.4.1 → 2.5.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/CHANGELOG.md +16 -4
- package/dist/NextJs/configs/next.config.template.js +12 -0
- package/dist/NextJs/configs/sentry.edge.config.js +17 -0
- package/dist/lib/Helper/MergeConfig.d.ts +1 -0
- package/dist/lib/Helper/MergeConfig.js +20 -0
- package/dist/lib/Helper/MergeConfig.js.map +1 -0
- package/dist/lib/Helper/__tests__/MergeConfig.d.ts +1 -0
- package/dist/lib/Helper/__tests__/MergeConfig.js +46 -0
- package/dist/lib/Helper/__tests__/MergeConfig.js.map +1 -0
- package/dist/lib/Steps/Integrations/NextJs.d.ts +1 -0
- package/dist/lib/Steps/Integrations/NextJs.js +135 -51
- package/dist/lib/Steps/Integrations/NextJs.js.map +1 -1
- package/lib/Helper/MergeConfig.ts +18 -0
- package/lib/Helper/__tests__/MergeConfig.ts +77 -0
- package/lib/Helper/test-fixtures/next.config.1-merged.js +18 -0
- package/lib/Helper/test-fixtures/next.config.1.js +6 -0
- package/lib/Helper/test-fixtures/next.config.2.js +8 -0
- package/lib/Helper/test-fixtures/next.config.3-merged.js +21 -0
- package/lib/Helper/test-fixtures/next.config.3.js +9 -0
- package/lib/Helper/test-fixtures/next.config.4-merged.js +21 -0
- package/lib/Helper/test-fixtures/next.config.4.js +9 -0
- package/lib/Steps/Integrations/NextJs.ts +100 -22
- package/package.json +1 -1
- package/scripts/NextJs/configs/next.config.template.js +12 -0
- package/scripts/NextJs/configs/sentry.edge.config.js +17 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.5.0
|
|
4
|
+
|
|
5
|
+
- feat: Merge next.config.js files automatically (#222)
|
|
6
|
+
|
|
7
|
+
## 2.4.2
|
|
8
|
+
|
|
9
|
+
- feat(nextjs): Add sentry.edge.config.js template (#227)
|
|
10
|
+
|
|
3
11
|
## 2.4.1
|
|
4
12
|
|
|
5
|
-
- feat: Add logic to add @sentry/nextjs if it's missing when running the wizard
|
|
13
|
+
- feat: Add logic to add @sentry/nextjs if it's missing when running the wizard
|
|
14
|
+
(#219)
|
|
6
15
|
- fix: Print localhost with `http` instead of `https` (#212)
|
|
7
16
|
- feat: Add project_platform as query param if -s and -i are set (#221)
|
|
8
17
|
- feat: Add promo code option used for signup flows (#223)
|
|
@@ -18,12 +27,14 @@
|
|
|
18
27
|
|
|
19
28
|
## 2.3.1
|
|
20
29
|
|
|
21
|
-
- fix(nextjs): Always check for both `next` and `@sentry/nextjs` presence and
|
|
30
|
+
- fix(nextjs): Always check for both `next` and `@sentry/nextjs` presence and
|
|
31
|
+
version (#209)
|
|
22
32
|
- fix: `cli.executable` property should be resolved from cwd (#211)
|
|
23
33
|
|
|
24
34
|
## 2.3.0
|
|
25
35
|
|
|
26
|
-
- feat(react-native): Xcode plugin debug files upload can include source using
|
|
36
|
+
- feat(react-native): Xcode plugin debug files upload can include source using
|
|
37
|
+
env
|
|
27
38
|
- chore(ci): remove jira workflow (#204)
|
|
28
39
|
|
|
29
40
|
## 2.2.2
|
|
@@ -32,7 +43,8 @@
|
|
|
32
43
|
|
|
33
44
|
## 2.2.1
|
|
34
45
|
|
|
35
|
-
- feat(nextjs): Add option to auto-wrap data fetchers and API routes to Next.js
|
|
46
|
+
- feat(nextjs): Add option to auto-wrap data fetchers and API routes to Next.js
|
|
47
|
+
config (#194)
|
|
36
48
|
|
|
37
49
|
## 2.2.0
|
|
38
50
|
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// This file sets a custom webpack configuration to use your Next.js app
|
|
2
|
+
// with Sentry.
|
|
3
|
+
// https://nextjs.org/docs/api-reference/next.config.js/introduction
|
|
4
|
+
// https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/
|
|
5
|
+
const { withSentryConfig } = require('@sentry/nextjs');
|
|
6
|
+
|
|
7
|
+
// ORIGINAL CONFIG
|
|
8
|
+
module.exports = withSentryConfig(
|
|
9
|
+
module.exports,
|
|
10
|
+
{ silent: true },
|
|
11
|
+
{ hideSourcemaps: true },
|
|
12
|
+
);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// This file configures the initialization of Sentry on the server.
|
|
2
|
+
// The config you add here will be used whenever middleware or an Edge route handles a request.
|
|
3
|
+
// https://docs.sentry.io/platforms/javascript/guides/nextjs/
|
|
4
|
+
|
|
5
|
+
import * as Sentry from '@sentry/nextjs';
|
|
6
|
+
|
|
7
|
+
const SENTRY_DSN = process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN;
|
|
8
|
+
|
|
9
|
+
Sentry.init({
|
|
10
|
+
dsn: SENTRY_DSN || '___DSN___',
|
|
11
|
+
// Adjust this value in production, or use tracesSampler for greater control
|
|
12
|
+
tracesSampleRate: 1.0,
|
|
13
|
+
// ...
|
|
14
|
+
// Note: if you want to override the automatic release value, do not set a
|
|
15
|
+
// `release` value here - use the environment variable `SENTRY_RELEASE`, so
|
|
16
|
+
// that it will also get attached to your source maps
|
|
17
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function mergeConfigFile(sourcePath: string, templatePath: string): boolean;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.mergeConfigFile = void 0;
|
|
4
|
+
var fs = require("fs");
|
|
5
|
+
// merges the config files
|
|
6
|
+
function mergeConfigFile(sourcePath, templatePath) {
|
|
7
|
+
try {
|
|
8
|
+
var templateFile = fs.readFileSync(templatePath, 'utf8');
|
|
9
|
+
var sourceFile = fs.readFileSync(sourcePath, 'utf8');
|
|
10
|
+
var newText = templateFile.replace('// ORIGINAL CONFIG', sourceFile);
|
|
11
|
+
Function(newText); // check if the file is valid javascript
|
|
12
|
+
fs.writeFileSync(sourcePath, newText);
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.mergeConfigFile = mergeConfigFile;
|
|
20
|
+
//# sourceMappingURL=MergeConfig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MergeConfig.js","sourceRoot":"","sources":["../../../lib/Helper/MergeConfig.ts"],"names":[],"mappings":";;;AAAA,uBAAyB;AAEzB,0BAA0B;AAC1B,SAAgB,eAAe,CAC7B,UAAkB,EAClB,YAAoB;IAEpB,IAAI;QACF,IAAM,YAAY,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QAC3D,IAAM,UAAU,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QACvD,IAAM,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,oBAAoB,EAAE,UAAU,CAAC,CAAC;QACvE,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,wCAAwC;QAC3D,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACtC,OAAO,IAAI,CAAC;KACb;IAAC,OAAO,KAAK,EAAE;QACd,OAAO,KAAK,CAAC;KACd;AACH,CAAC;AAdD,0CAcC","sourcesContent":["import * as fs from 'fs';\n\n// merges the config files\nexport function mergeConfigFile(\n sourcePath: string,\n templatePath: string,\n): boolean {\n try {\n const templateFile = fs.readFileSync(templatePath, 'utf8');\n const sourceFile = fs.readFileSync(sourcePath, 'utf8');\n const newText = templateFile.replace('// ORIGINAL CONFIG', sourceFile);\n Function(newText); // check if the file is valid javascript\n fs.writeFileSync(sourcePath, newText);\n return true;\n } catch (error) {\n return false;\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/// <reference types="jest" />
|
|
4
|
+
var fs = require("fs");
|
|
5
|
+
var path = require("path");
|
|
6
|
+
var MergeConfig_1 = require("../MergeConfig");
|
|
7
|
+
var configPath = path.join(__dirname, '..', 'test-fixtures/next.config.js');
|
|
8
|
+
var templatePath = path.join(__dirname, '..', '..', '..', 'scripts/NextJS/configs/next.config.template.js');
|
|
9
|
+
function configFileNames(num) {
|
|
10
|
+
var sourcePath = path.join(__dirname, '..', "test-fixtures/next.config." + num + ".js");
|
|
11
|
+
var mergedPath = path.join(__dirname, '..', "test-fixtures/next.config." + num + "-merged.js");
|
|
12
|
+
return { sourcePath: sourcePath, mergedPath: mergedPath };
|
|
13
|
+
}
|
|
14
|
+
describe('Merging next.config.js', function () {
|
|
15
|
+
test('merge basic next.config.js', function () {
|
|
16
|
+
var _a = configFileNames(1), sourcePath = _a.sourcePath, mergedPath = _a.mergedPath;
|
|
17
|
+
fs.copyFileSync(sourcePath, configPath);
|
|
18
|
+
expect(MergeConfig_1.mergeConfigFile(configPath, templatePath)).toBe(true);
|
|
19
|
+
expect(fs.readFileSync(configPath, 'utf8') ===
|
|
20
|
+
fs.readFileSync(mergedPath, 'utf8')).toBe(true);
|
|
21
|
+
fs.unlinkSync(configPath);
|
|
22
|
+
});
|
|
23
|
+
test('merge invalid javascript config', function () {
|
|
24
|
+
var sourcePath = configFileNames(2).sourcePath;
|
|
25
|
+
fs.copyFileSync(sourcePath, configPath);
|
|
26
|
+
expect(MergeConfig_1.mergeConfigFile(configPath, templatePath)).toBe(false);
|
|
27
|
+
fs.unlinkSync(configPath);
|
|
28
|
+
});
|
|
29
|
+
test('merge more complicated next.config.js', function () {
|
|
30
|
+
var _a = configFileNames(3), sourcePath = _a.sourcePath, mergedPath = _a.mergedPath;
|
|
31
|
+
fs.copyFileSync(sourcePath, configPath);
|
|
32
|
+
expect(MergeConfig_1.mergeConfigFile(configPath, templatePath)).toBe(true);
|
|
33
|
+
expect(fs.readFileSync(configPath, 'utf8') ===
|
|
34
|
+
fs.readFileSync(mergedPath, 'utf8')).toBe(true);
|
|
35
|
+
fs.unlinkSync(configPath);
|
|
36
|
+
});
|
|
37
|
+
test('merge next.config.js with function', function () {
|
|
38
|
+
var _a = configFileNames(4), sourcePath = _a.sourcePath, mergedPath = _a.mergedPath;
|
|
39
|
+
fs.copyFileSync(sourcePath, configPath);
|
|
40
|
+
expect(MergeConfig_1.mergeConfigFile(configPath, templatePath)).toBe(true);
|
|
41
|
+
expect(fs.readFileSync(configPath, 'utf8') ===
|
|
42
|
+
fs.readFileSync(mergedPath, 'utf8')).toBe(true);
|
|
43
|
+
fs.unlinkSync(configPath);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
//# sourceMappingURL=MergeConfig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MergeConfig.js","sourceRoot":"","sources":["../../../../lib/Helper/__tests__/MergeConfig.ts"],"names":[],"mappings":"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","sourcesContent":["/// <reference types=\"jest\" />\nimport * as fs from 'fs';\nimport * as path from 'path';\n\nimport { mergeConfigFile } from '../MergeConfig';\n\nconst configPath = path.join(__dirname, '..', 'test-fixtures/next.config.js');\nconst templatePath = path.join(\n __dirname,\n '..',\n '..',\n '..',\n 'scripts/NextJS/configs/next.config.template.js',\n);\n\nfunction configFileNames(num: number): {\n sourcePath: string;\n mergedPath: string;\n} {\n const sourcePath = path.join(\n __dirname,\n '..',\n `test-fixtures/next.config.${num}.js`,\n );\n const mergedPath = path.join(\n __dirname,\n '..',\n `test-fixtures/next.config.${num}-merged.js`,\n );\n return { sourcePath, mergedPath };\n}\n\ndescribe('Merging next.config.js', () => {\n test('merge basic next.config.js', () => {\n const { sourcePath, mergedPath } = configFileNames(1);\n fs.copyFileSync(sourcePath, configPath);\n\n expect(mergeConfigFile(configPath, templatePath)).toBe(true);\n expect(\n fs.readFileSync(configPath, 'utf8') ===\n fs.readFileSync(mergedPath, 'utf8'),\n ).toBe(true);\n fs.unlinkSync(configPath);\n });\n\n test('merge invalid javascript config', () => {\n const { sourcePath } = configFileNames(2);\n fs.copyFileSync(sourcePath, configPath);\n\n expect(mergeConfigFile(configPath, templatePath)).toBe(false);\n fs.unlinkSync(configPath);\n });\n\n test('merge more complicated next.config.js', () => {\n const { sourcePath, mergedPath } = configFileNames(3);\n fs.copyFileSync(sourcePath, configPath);\n\n expect(mergeConfigFile(configPath, templatePath)).toBe(true);\n expect(\n fs.readFileSync(configPath, 'utf8') ===\n fs.readFileSync(mergedPath, 'utf8'),\n ).toBe(true);\n fs.unlinkSync(configPath);\n });\n\n test('merge next.config.js with function', () => {\n const { sourcePath, mergedPath } = configFileNames(4);\n fs.copyFileSync(sourcePath, configPath);\n\n expect(mergeConfigFile(configPath, templatePath)).toBe(true);\n expect(\n fs.readFileSync(configPath, 'utf8') ===\n fs.readFileSync(mergedPath, 'utf8'),\n ).toBe(true);\n fs.unlinkSync(configPath);\n });\n});\n"]}
|
|
@@ -78,6 +78,7 @@ var path = require("path");
|
|
|
78
78
|
var semver_1 = require("semver");
|
|
79
79
|
var util_1 = require("util");
|
|
80
80
|
var Logging_1 = require("../../Helper/Logging");
|
|
81
|
+
var MergeConfig_1 = require("../../Helper/MergeConfig");
|
|
81
82
|
var SentryCli_1 = require("../../Helper/SentryCli");
|
|
82
83
|
var BaseIntegration_1 = require("./BaseIntegration");
|
|
83
84
|
var COMPATIBLE_NEXTJS_VERSIONS = '>=10.0.8 <14.0.0';
|
|
@@ -94,6 +95,7 @@ var TEMPLATE_DESTINATIONS = {
|
|
|
94
95
|
'next.config.js': ['.'],
|
|
95
96
|
'sentry.server.config.js': ['.'],
|
|
96
97
|
'sentry.client.config.js': ['.'],
|
|
98
|
+
'sentry.edge.config.js': ['.'],
|
|
97
99
|
};
|
|
98
100
|
var appPackage = {};
|
|
99
101
|
try {
|
|
@@ -125,21 +127,26 @@ var NextJs = /** @class */ (function (_super) {
|
|
|
125
127
|
_g.sent();
|
|
126
128
|
templateDirectory = path.join(__dirname, '..', '..', '..', 'NextJs');
|
|
127
129
|
configDirectory = path.join(templateDirectory, CONFIG_DIR);
|
|
128
|
-
if (fs.existsSync(configDirectory))
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
130
|
+
if (!fs.existsSync(configDirectory)) return [3 /*break*/, 3];
|
|
131
|
+
return [4 /*yield*/, this._createNextConfig(configDirectory, dsn)];
|
|
132
|
+
case 2:
|
|
133
|
+
_g.sent();
|
|
134
|
+
return [3 /*break*/, 4];
|
|
135
|
+
case 3:
|
|
136
|
+
Logging_1.debug("Couldn't find " + configDirectory + ", probably because you ran this from inside of `/lib` rather than `/dist`");
|
|
137
|
+
Logging_1.nl();
|
|
138
|
+
_g.label = 4;
|
|
139
|
+
case 4:
|
|
135
140
|
selectedProjectSlug = (_b = (_a = answers.config) === null || _a === void 0 ? void 0 : _a.project) === null || _b === void 0 ? void 0 : _b.slug;
|
|
136
|
-
if (selectedProjectSlug)
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
141
|
+
if (!selectedProjectSlug) return [3 /*break*/, 6];
|
|
142
|
+
hasFirstEvent = (_f = (_e = (_d = (_c = answers.wizard) === null || _c === void 0 ? void 0 : _c.projects) === null || _d === void 0 ? void 0 : _d.find) === null || _e === void 0 ? void 0 : _e.call(_d, function (p) { return p.slug === selectedProjectSlug; })) === null || _f === void 0 ? void 0 : _f.firstEvent;
|
|
143
|
+
if (!!hasFirstEvent) return [3 /*break*/, 6];
|
|
144
|
+
return [4 /*yield*/, this._setTemplate(templateDirectory, 'sentry_sample_error.js', ['pages', 'src/pages'], dsn)];
|
|
145
|
+
case 5:
|
|
146
|
+
_g.sent();
|
|
147
|
+
Logging_1.l(chalk_1.default.bgYellowBright("\n|------------------------------------------------------------------------|\n| Installation Complete |\n| To verify your installation and finish onboarding, launch your Next.js |\n| application, navigate to http://localhost:3000/sentry_sample_error |\n| and send us a sample error. |\n|------------------------------------------------------------------------|\n"));
|
|
148
|
+
_g.label = 6;
|
|
149
|
+
case 6:
|
|
143
150
|
Logging_1.l('For more information, see https://docs.sentry.io/platforms/javascript/guides/nextjs/');
|
|
144
151
|
Logging_1.nl();
|
|
145
152
|
return [2 /*return*/, {}];
|
|
@@ -272,45 +279,82 @@ var NextJs = /** @class */ (function (_super) {
|
|
|
272
279
|
});
|
|
273
280
|
};
|
|
274
281
|
NextJs.prototype._createNextConfig = function (configDirectory, dsn) {
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
282
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
283
|
+
var templates, filteredTemplates, _i, filteredTemplates_1, template;
|
|
284
|
+
return __generator(this, function (_a) {
|
|
285
|
+
switch (_a.label) {
|
|
286
|
+
case 0:
|
|
287
|
+
templates = fs.readdirSync(configDirectory);
|
|
288
|
+
filteredTemplates = templates.filter(function (template) { return template !== 'next.config.template.js'; });
|
|
289
|
+
_i = 0, filteredTemplates_1 = filteredTemplates;
|
|
290
|
+
_a.label = 1;
|
|
291
|
+
case 1:
|
|
292
|
+
if (!(_i < filteredTemplates_1.length)) return [3 /*break*/, 4];
|
|
293
|
+
template = filteredTemplates_1[_i];
|
|
294
|
+
return [4 /*yield*/, this._setTemplate(configDirectory, template, TEMPLATE_DESTINATIONS[template], dsn)];
|
|
295
|
+
case 2:
|
|
296
|
+
_a.sent();
|
|
297
|
+
_a.label = 3;
|
|
298
|
+
case 3:
|
|
299
|
+
_i++;
|
|
300
|
+
return [3 /*break*/, 1];
|
|
301
|
+
case 4:
|
|
302
|
+
Logging_1.red('⚠ Performance monitoring is enabled capturing 100% of transactions.\n' +
|
|
303
|
+
' Learn more in https://docs.sentry.io/product/performance/');
|
|
304
|
+
Logging_1.nl();
|
|
305
|
+
return [2 /*return*/];
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
});
|
|
283
309
|
};
|
|
284
310
|
NextJs.prototype._setTemplate = function (configDirectory, templateFile, destinationOptions, dsn) {
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
311
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
312
|
+
var templatePath, _i, destinationOptions_1, destinationDir, destinationPath, mergeableFilePath;
|
|
313
|
+
return __generator(this, function (_a) {
|
|
314
|
+
switch (_a.label) {
|
|
315
|
+
case 0:
|
|
316
|
+
templatePath = path.join(configDirectory, templateFile);
|
|
317
|
+
_i = 0, destinationOptions_1 = destinationOptions;
|
|
318
|
+
_a.label = 1;
|
|
319
|
+
case 1:
|
|
320
|
+
if (!(_i < destinationOptions_1.length)) return [3 /*break*/, 5];
|
|
321
|
+
destinationDir = destinationOptions_1[_i];
|
|
322
|
+
if (!fs.existsSync(destinationDir)) {
|
|
323
|
+
return [3 /*break*/, 4];
|
|
324
|
+
}
|
|
325
|
+
destinationPath = path.join(destinationDir, templateFile);
|
|
326
|
+
mergeableFilePath = path.join(destinationDir, this._spliceInPlace(templateFile.split('.'), -1, 0, MERGEABLE_CONFIG_INFIX).join('.'));
|
|
327
|
+
if (!(templateFile === 'next.config.js')) return [3 /*break*/, 3];
|
|
328
|
+
return [4 /*yield*/, this._mergeNextConfig(destinationPath, templatePath, destinationDir, templateFile, configDirectory, mergeableFilePath)];
|
|
329
|
+
case 2:
|
|
330
|
+
_a.sent();
|
|
331
|
+
return [2 /*return*/];
|
|
332
|
+
case 3:
|
|
333
|
+
if (!fs.existsSync(destinationPath)) {
|
|
334
|
+
this._fillAndCopyTemplate(templatePath, destinationPath, dsn);
|
|
335
|
+
}
|
|
336
|
+
else if (!fs.existsSync(mergeableFilePath)) {
|
|
337
|
+
this._fillAndCopyTemplate(templatePath, mergeableFilePath, dsn);
|
|
338
|
+
Logging_1.red("File `" + templateFile + "` already exists, so created `" + mergeableFilePath + "`.\n" +
|
|
339
|
+
'Please merge those files.');
|
|
340
|
+
Logging_1.nl();
|
|
341
|
+
}
|
|
342
|
+
else {
|
|
343
|
+
Logging_1.red("Both `" + templateFile + "` and `" + mergeableFilePath + "` already exist.\n" +
|
|
344
|
+
'Please merge those files.');
|
|
345
|
+
Logging_1.nl();
|
|
346
|
+
}
|
|
347
|
+
return [2 /*return*/];
|
|
348
|
+
case 4:
|
|
349
|
+
_i++;
|
|
350
|
+
return [3 /*break*/, 1];
|
|
351
|
+
case 5:
|
|
352
|
+
Logging_1.red("Could not find appropriate destination for `" + templateFile + "`. Tried: " + destinationOptions + ".");
|
|
353
|
+
Logging_1.nl();
|
|
354
|
+
return [2 /*return*/];
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
});
|
|
314
358
|
};
|
|
315
359
|
NextJs.prototype._fillAndCopyTemplate = function (sourcePath, targetPath, dsn) {
|
|
316
360
|
var templateContent = fs.readFileSync(sourcePath).toString();
|
|
@@ -408,6 +452,46 @@ var NextJs = /** @class */ (function (_super) {
|
|
|
408
452
|
arr.splice.apply(arr, __spreadArrays([start, deleteCount], inserts));
|
|
409
453
|
return arr;
|
|
410
454
|
};
|
|
455
|
+
NextJs.prototype._mergeNextConfig = function (destinationPath, templatePath, destinationDir, templateFile, configDirectory, mergeableFilePath) {
|
|
456
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
457
|
+
var originalFileName, originalFilePath, mergedTemplatePath;
|
|
458
|
+
return __generator(this, function (_a) {
|
|
459
|
+
switch (_a.label) {
|
|
460
|
+
case 0:
|
|
461
|
+
if (!!fs.existsSync(destinationPath)) return [3 /*break*/, 1];
|
|
462
|
+
fs.copyFileSync(templatePath, destinationPath);
|
|
463
|
+
Logging_1.green('Created File `next.config.js`');
|
|
464
|
+
Logging_1.nl();
|
|
465
|
+
return [3 /*break*/, 5];
|
|
466
|
+
case 1:
|
|
467
|
+
originalFileName = this._spliceInPlace(templateFile.split('.'), -1, 0, 'original').join('.');
|
|
468
|
+
originalFilePath = path.join(destinationDir, originalFileName);
|
|
469
|
+
// makes copy of original next.config.js
|
|
470
|
+
fs.writeFileSync(originalFilePath, fs.readFileSync(destinationPath));
|
|
471
|
+
return [4 /*yield*/, this._addToGitignore(originalFilePath, 'Unable to add next.config.original.js to gitignore')];
|
|
472
|
+
case 2:
|
|
473
|
+
_a.sent();
|
|
474
|
+
mergedTemplatePath = path.join(configDirectory, 'next.config.template.js');
|
|
475
|
+
if (!MergeConfig_1.mergeConfigFile(destinationPath, mergedTemplatePath)) return [3 /*break*/, 3];
|
|
476
|
+
Logging_1.green("Updated `" + templateFile + "` with Sentry. The original " + templateFile + " was saved as `next.config.original.js`.\n" +
|
|
477
|
+
'Information on the changes made to the Next.js configuration file an be found at https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/');
|
|
478
|
+
Logging_1.nl();
|
|
479
|
+
return [3 /*break*/, 5];
|
|
480
|
+
case 3:
|
|
481
|
+
// if merge fails, we'll create a copy of the `next.config.js` template and ask them to merge
|
|
482
|
+
fs.copyFileSync(templatePath, mergeableFilePath);
|
|
483
|
+
return [4 /*yield*/, this._addToGitignore(mergeableFilePath, 'Unable to add next.config.wizard.js template to gitignore')];
|
|
484
|
+
case 4:
|
|
485
|
+
_a.sent();
|
|
486
|
+
Logging_1.red("Unable to merge `" + templateFile + "`, so created `" + mergeableFilePath + "`.\n" +
|
|
487
|
+
'Please integrate next.config.wizardcopy.js into your next.config.js or next.config.ts file');
|
|
488
|
+
Logging_1.nl();
|
|
489
|
+
_a.label = 5;
|
|
490
|
+
case 5: return [2 /*return*/];
|
|
491
|
+
}
|
|
492
|
+
});
|
|
493
|
+
});
|
|
494
|
+
};
|
|
411
495
|
return NextJs;
|
|
412
496
|
}(BaseIntegration_1.BaseIntegration));
|
|
413
497
|
exports.NextJs = NextJs;
|
|
@@ -1 +1 @@
|
|
|
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 Chalk from 'chalk';\nimport { exec } from 'child_process';\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';\nimport { promisify } from 'util';\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\ntype PackageManager = 'yarn' | 'npm' | 'pnpm';\n\nconst COMPATIBLE_NEXTJS_VERSIONS = '>=10.0.8 <14.0.0';\nconst COMPATIBLE_SDK_VERSIONS = '>=7.3.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 templateDirectory = path.join(__dirname, '..', '..', '..', 'NextJs');\n const configDirectory = path.join(templateDirectory, CONFIG_DIR);\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 const selectedProjectSlug: string | null = answers.config?.project?.slug;\n if (selectedProjectSlug) {\n const hasFirstEvent = answers.wizard?.projects?.find?.(\n (p: { slug: string }) => p.slug === selectedProjectSlug,\n )?.firstEvent;\n if (!hasFirstEvent) {\n this._setTemplate(\n templateDirectory,\n 'sentry_sample_error.js',\n ['pages', 'src/pages'],\n dsn,\n );\n l(\n Chalk.bgYellowBright(`\n|------------------------------------------------------------------------|\n| Installation Complete |\n| To verify your installation and finish onboarding, launch your Next.js |\n| application, navigate to http://localhost:3000/sentry_sample_error |\n| and send us a sample error. |\n|------------------------------------------------------------------------|\n`),\n );\n }\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 const hasCompatibleNextjsVersion = this._checkPackageVersion(\n 'next',\n COMPATIBLE_NEXTJS_VERSIONS,\n true,\n );\n\n const packageManager = this._getPackageMangerChoice();\n const hasSdkInstalled = this._hasPackageInstalled('@sentry/nextjs');\n\n let hasCompatibleSdkVersion = false;\n // if no package but we have nextjs, let's add it if we can\n if (!hasSdkInstalled && packageManager && hasCompatibleNextjsVersion) {\n await this._installPackage('@sentry/nextjs', packageManager);\n // can assume it's compatible since we just installed it\n hasCompatibleSdkVersion = true;\n } else {\n // otherwise, let's check the version and spit out the appropriate error\n hasCompatibleSdkVersion = this._checkPackageVersion(\n '@sentry/nextjs',\n COMPATIBLE_SDK_VERSIONS,\n true,\n );\n }\n const hasAllPackagesCompatible =\n hasCompatibleNextjsVersion && hasCompatibleSdkVersion;\n\n if (!hasAllPackagesCompatible && !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 _hasPackageInstalled(packageName: string): boolean {\n const depsVersion = _.get(appPackage, ['dependencies', packageName]);\n const devDepsVersion = _.get(appPackage, ['devDependencies', packageName]);\n return !!depsVersion || !!devDepsVersion;\n }\n\n private _getPackageMangerChoice(): PackageManager | null {\n if (fs.existsSync(path.join(process.cwd(), 'yarn.lock'))) {\n return 'yarn';\n }\n if (fs.existsSync(path.join(process.cwd(), 'pnpm-lock.yaml'))) {\n return 'pnpm';\n }\n if (fs.existsSync(path.join(process.cwd(), 'package-lock.json'))) {\n return 'npm';\n }\n return null;\n }\n\n private _getInstallCommand(packageManager: PackageManager): string {\n switch (packageManager) {\n case 'yarn':\n return 'yarn add';\n case 'pnpm':\n return 'pnpm add';\n case 'npm':\n return 'npm install';\n default:\n throw new Error(`Unknown package manager: ${packageManager}`);\n }\n }\n\n private async _installPackage(\n packageName: string,\n packageManager: PackageManager,\n ): Promise<void> {\n const command = this._getInstallCommand(packageManager);\n await promisify(exec)(`${command} ${packageName}`);\n green(`✓ Added \\`${packageName}\\` using \\`${command}\\`.`);\n return;\n }\n\n private _checkPackageVersion(\n packageName: string,\n acceptableVersions: string,\n canBeLatest: boolean,\n ): 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(\n depsVersion,\n acceptableVersions,\n canBeLatest,\n ) &&\n !this._fulfillsVersionRange(\n devDepsVersion,\n acceptableVersions,\n canBeLatest,\n )\n ) {\n red(\n `✗ Your \\`package.json\\` specifies a version of \\`${packageName}\\` outside of the compatible version range ${acceptableVersions}.\\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(\n version: string,\n acceptableVersions: string,\n canBeLatest: boolean,\n ): boolean {\n if (version === 'latest') {\n return canBeLatest;\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 // If the given version is a bogus format, this will still be undefined and we'll automatically reject it\n !!cleanedUserVersion &&\n (isRange\n ? subset(cleanedUserVersion, acceptableVersions)\n : satisfies(cleanedUserVersion, acceptableVersions))\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"]}
|
|
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 Chalk from 'chalk';\nimport { exec } from 'child_process';\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';\nimport { promisify } from 'util';\n\nimport { Args } from '../../Constants';\nimport { debug, green, l, nl, red } from '../../Helper/Logging';\nimport { mergeConfigFile } from '../../Helper/MergeConfig';\nimport { SentryCli, SentryCliProps } from '../../Helper/SentryCli';\nimport { BaseIntegration } from './BaseIntegration';\n\ntype PackageManager = 'yarn' | 'npm' | 'pnpm';\n\nconst COMPATIBLE_NEXTJS_VERSIONS = '>=10.0.8 <14.0.0';\nconst COMPATIBLE_SDK_VERSIONS = '>=7.3.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 'sentry.edge.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 templateDirectory = path.join(__dirname, '..', '..', '..', 'NextJs');\n const configDirectory = path.join(templateDirectory, CONFIG_DIR);\n\n if (fs.existsSync(configDirectory)) {\n await 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 const selectedProjectSlug: string | null = answers.config?.project?.slug;\n if (selectedProjectSlug) {\n const hasFirstEvent = answers.wizard?.projects?.find?.(\n (p: { slug: string }) => p.slug === selectedProjectSlug,\n )?.firstEvent;\n if (!hasFirstEvent) {\n await this._setTemplate(\n templateDirectory,\n 'sentry_sample_error.js',\n ['pages', 'src/pages'],\n dsn,\n );\n l(\n Chalk.bgYellowBright(`\n|------------------------------------------------------------------------|\n| Installation Complete |\n| To verify your installation and finish onboarding, launch your Next.js |\n| application, navigate to http://localhost:3000/sentry_sample_error |\n| and send us a sample error. |\n|------------------------------------------------------------------------|\n`),\n );\n }\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 const hasCompatibleNextjsVersion = this._checkPackageVersion(\n 'next',\n COMPATIBLE_NEXTJS_VERSIONS,\n true,\n );\n\n const packageManager = this._getPackageMangerChoice();\n const hasSdkInstalled = this._hasPackageInstalled('@sentry/nextjs');\n\n let hasCompatibleSdkVersion = false;\n // if no package but we have nextjs, let's add it if we can\n if (!hasSdkInstalled && packageManager && hasCompatibleNextjsVersion) {\n await this._installPackage('@sentry/nextjs', packageManager);\n // can assume it's compatible since we just installed it\n hasCompatibleSdkVersion = true;\n } else {\n // otherwise, let's check the version and spit out the appropriate error\n hasCompatibleSdkVersion = this._checkPackageVersion(\n '@sentry/nextjs',\n COMPATIBLE_SDK_VERSIONS,\n true,\n );\n }\n const hasAllPackagesCompatible =\n hasCompatibleNextjsVersion && hasCompatibleSdkVersion;\n\n if (!hasAllPackagesCompatible && !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 async _createNextConfig(\n configDirectory: string,\n dsn: any,\n ): Promise<void> {\n const templates = fs.readdirSync(configDirectory);\n // next.config.template.js used for merging next.config.js , not its own template,\n // so it shouldn't have a setTemplate call\n const filteredTemplates = templates.filter(\n (template) => template !== 'next.config.template.js',\n );\n for (const template of filteredTemplates) {\n await 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 async _setTemplate(\n configDirectory: string,\n templateFile: string,\n destinationOptions: string[],\n dsn: string,\n ): Promise<void> {\n const templatePath = path.join(configDirectory, templateFile);\n\n for (const destinationDir of destinationOptions) {\n if (!fs.existsSync(destinationDir)) {\n continue;\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 (templateFile === 'next.config.js') {\n await this._mergeNextConfig(\n destinationPath,\n templatePath,\n destinationDir,\n templateFile,\n configDirectory,\n mergeableFilePath,\n );\n return;\n } else {\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\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 _hasPackageInstalled(packageName: string): boolean {\n const depsVersion = _.get(appPackage, ['dependencies', packageName]);\n const devDepsVersion = _.get(appPackage, ['devDependencies', packageName]);\n return !!depsVersion || !!devDepsVersion;\n }\n\n private _getPackageMangerChoice(): PackageManager | null {\n if (fs.existsSync(path.join(process.cwd(), 'yarn.lock'))) {\n return 'yarn';\n }\n if (fs.existsSync(path.join(process.cwd(), 'pnpm-lock.yaml'))) {\n return 'pnpm';\n }\n if (fs.existsSync(path.join(process.cwd(), 'package-lock.json'))) {\n return 'npm';\n }\n return null;\n }\n\n private _getInstallCommand(packageManager: PackageManager): string {\n switch (packageManager) {\n case 'yarn':\n return 'yarn add';\n case 'pnpm':\n return 'pnpm add';\n case 'npm':\n return 'npm install';\n default:\n throw new Error(`Unknown package manager: ${packageManager}`);\n }\n }\n\n private async _installPackage(\n packageName: string,\n packageManager: PackageManager,\n ): Promise<void> {\n const command = this._getInstallCommand(packageManager);\n await promisify(exec)(`${command} ${packageName}`);\n green(`✓ Added \\`${packageName}\\` using \\`${command}\\`.`);\n return;\n }\n\n private _checkPackageVersion(\n packageName: string,\n acceptableVersions: string,\n canBeLatest: boolean,\n ): 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(\n depsVersion,\n acceptableVersions,\n canBeLatest,\n ) &&\n !this._fulfillsVersionRange(\n devDepsVersion,\n acceptableVersions,\n canBeLatest,\n )\n ) {\n red(\n `✗ Your \\`package.json\\` specifies a version of \\`${packageName}\\` outside of the compatible version range ${acceptableVersions}.\\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(\n version: string,\n acceptableVersions: string,\n canBeLatest: boolean,\n ): boolean {\n if (version === 'latest') {\n return canBeLatest;\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 // If the given version is a bogus format, this will still be undefined and we'll automatically reject it\n !!cleanedUserVersion &&\n (isRange\n ? subset(cleanedUserVersion, acceptableVersions)\n : satisfies(cleanedUserVersion, acceptableVersions))\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 private async _mergeNextConfig(\n destinationPath: string,\n templatePath: string,\n destinationDir: string,\n templateFile: string,\n configDirectory: string,\n mergeableFilePath: string,\n ): Promise<void> {\n // if no next.config.js exists, we'll create one\n if (!fs.existsSync(destinationPath)) {\n fs.copyFileSync(templatePath, destinationPath);\n green('Created File `next.config.js`');\n nl();\n } else {\n // creates a file name for the copy of the original next.config.js file\n // with the name `next.config.original.js`\n const originalFileName = this._spliceInPlace(\n templateFile.split('.'),\n -1,\n 0,\n 'original',\n ).join('.');\n const originalFilePath = path.join(destinationDir, originalFileName);\n // makes copy of original next.config.js\n fs.writeFileSync(originalFilePath, fs.readFileSync(destinationPath));\n await this._addToGitignore(\n originalFilePath,\n 'Unable to add next.config.original.js to gitignore',\n );\n\n const mergedTemplatePath = path.join(\n configDirectory,\n 'next.config.template.js',\n );\n // attempts to merge with existing next.config.js, if true -> success\n if (mergeConfigFile(destinationPath, mergedTemplatePath)) {\n green(\n `Updated \\`${templateFile}\\` with Sentry. The original ${templateFile} was saved as \\`next.config.original.js\\`.\\n` +\n 'Information on the changes made to the Next.js configuration file an be found at https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/',\n );\n nl();\n } else {\n // if merge fails, we'll create a copy of the `next.config.js` template and ask them to merge\n fs.copyFileSync(templatePath, mergeableFilePath);\n await this._addToGitignore(\n mergeableFilePath,\n 'Unable to add next.config.wizard.js template to gitignore',\n );\n red(\n `Unable to merge \\`${templateFile}\\`, so created \\`${mergeableFilePath}\\`.\\n` +\n 'Please integrate next.config.wizardcopy.js into your next.config.js or next.config.ts file',\n );\n nl();\n }\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
|
|
3
|
+
// merges the config files
|
|
4
|
+
export function mergeConfigFile(
|
|
5
|
+
sourcePath: string,
|
|
6
|
+
templatePath: string,
|
|
7
|
+
): boolean {
|
|
8
|
+
try {
|
|
9
|
+
const templateFile = fs.readFileSync(templatePath, 'utf8');
|
|
10
|
+
const sourceFile = fs.readFileSync(sourcePath, 'utf8');
|
|
11
|
+
const newText = templateFile.replace('// ORIGINAL CONFIG', sourceFile);
|
|
12
|
+
Function(newText); // check if the file is valid javascript
|
|
13
|
+
fs.writeFileSync(sourcePath, newText);
|
|
14
|
+
return true;
|
|
15
|
+
} catch (error) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/// <reference types="jest" />
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
|
|
5
|
+
import { mergeConfigFile } from '../MergeConfig';
|
|
6
|
+
|
|
7
|
+
const configPath = path.join(__dirname, '..', 'test-fixtures/next.config.js');
|
|
8
|
+
const templatePath = path.join(
|
|
9
|
+
__dirname,
|
|
10
|
+
'..',
|
|
11
|
+
'..',
|
|
12
|
+
'..',
|
|
13
|
+
'scripts/NextJS/configs/next.config.template.js',
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
function configFileNames(num: number): {
|
|
17
|
+
sourcePath: string;
|
|
18
|
+
mergedPath: string;
|
|
19
|
+
} {
|
|
20
|
+
const sourcePath = path.join(
|
|
21
|
+
__dirname,
|
|
22
|
+
'..',
|
|
23
|
+
`test-fixtures/next.config.${num}.js`,
|
|
24
|
+
);
|
|
25
|
+
const mergedPath = path.join(
|
|
26
|
+
__dirname,
|
|
27
|
+
'..',
|
|
28
|
+
`test-fixtures/next.config.${num}-merged.js`,
|
|
29
|
+
);
|
|
30
|
+
return { sourcePath, mergedPath };
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
describe('Merging next.config.js', () => {
|
|
34
|
+
test('merge basic next.config.js', () => {
|
|
35
|
+
const { sourcePath, mergedPath } = configFileNames(1);
|
|
36
|
+
fs.copyFileSync(sourcePath, configPath);
|
|
37
|
+
|
|
38
|
+
expect(mergeConfigFile(configPath, templatePath)).toBe(true);
|
|
39
|
+
expect(
|
|
40
|
+
fs.readFileSync(configPath, 'utf8') ===
|
|
41
|
+
fs.readFileSync(mergedPath, 'utf8'),
|
|
42
|
+
).toBe(true);
|
|
43
|
+
fs.unlinkSync(configPath);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test('merge invalid javascript config', () => {
|
|
47
|
+
const { sourcePath } = configFileNames(2);
|
|
48
|
+
fs.copyFileSync(sourcePath, configPath);
|
|
49
|
+
|
|
50
|
+
expect(mergeConfigFile(configPath, templatePath)).toBe(false);
|
|
51
|
+
fs.unlinkSync(configPath);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test('merge more complicated next.config.js', () => {
|
|
55
|
+
const { sourcePath, mergedPath } = configFileNames(3);
|
|
56
|
+
fs.copyFileSync(sourcePath, configPath);
|
|
57
|
+
|
|
58
|
+
expect(mergeConfigFile(configPath, templatePath)).toBe(true);
|
|
59
|
+
expect(
|
|
60
|
+
fs.readFileSync(configPath, 'utf8') ===
|
|
61
|
+
fs.readFileSync(mergedPath, 'utf8'),
|
|
62
|
+
).toBe(true);
|
|
63
|
+
fs.unlinkSync(configPath);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test('merge next.config.js with function', () => {
|
|
67
|
+
const { sourcePath, mergedPath } = configFileNames(4);
|
|
68
|
+
fs.copyFileSync(sourcePath, configPath);
|
|
69
|
+
|
|
70
|
+
expect(mergeConfigFile(configPath, templatePath)).toBe(true);
|
|
71
|
+
expect(
|
|
72
|
+
fs.readFileSync(configPath, 'utf8') ===
|
|
73
|
+
fs.readFileSync(mergedPath, 'utf8'),
|
|
74
|
+
).toBe(true);
|
|
75
|
+
fs.unlinkSync(configPath);
|
|
76
|
+
});
|
|
77
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// This file sets a custom webpack configuration to use your Next.js app
|
|
2
|
+
// with Sentry.
|
|
3
|
+
// https://nextjs.org/docs/api-reference/next.config.js/introduction
|
|
4
|
+
// https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/
|
|
5
|
+
const { withSentryConfig } = require('@sentry/nextjs');
|
|
6
|
+
|
|
7
|
+
/** @type {import('next').NextConfig} */
|
|
8
|
+
const nextConfig = {
|
|
9
|
+
reactStrictMode: true,
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
module.exports = nextConfig;
|
|
13
|
+
|
|
14
|
+
module.exports = withSentryConfig(
|
|
15
|
+
module.exports,
|
|
16
|
+
{ silent: true },
|
|
17
|
+
{ hideSourcemaps: true },
|
|
18
|
+
);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// This file sets a custom webpack configuration to use your Next.js app
|
|
2
|
+
// with Sentry.
|
|
3
|
+
// https://nextjs.org/docs/api-reference/next.config.js/introduction
|
|
4
|
+
// https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/
|
|
5
|
+
const { withSentryConfig } = require('@sentry/nextjs');
|
|
6
|
+
|
|
7
|
+
/** @type {import('next').NextConfig} */
|
|
8
|
+
const nextConfig = {
|
|
9
|
+
reactStrictMode: true,
|
|
10
|
+
images: {
|
|
11
|
+
domains: [],
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
module.exports = nextConfig;
|
|
16
|
+
|
|
17
|
+
module.exports = withSentryConfig(
|
|
18
|
+
module.exports,
|
|
19
|
+
{ silent: true },
|
|
20
|
+
{ hideSourcemaps: true },
|
|
21
|
+
);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// This file sets a custom webpack configuration to use your Next.js app
|
|
2
|
+
// with Sentry.
|
|
3
|
+
// https://nextjs.org/docs/api-reference/next.config.js/introduction
|
|
4
|
+
// https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/
|
|
5
|
+
const { withSentryConfig } = require('@sentry/nextjs');
|
|
6
|
+
|
|
7
|
+
module.exports = (phase, { defaultConfig }) => {
|
|
8
|
+
/**
|
|
9
|
+
* @type {import('next').NextConfig}
|
|
10
|
+
*/
|
|
11
|
+
const nextConfig = {
|
|
12
|
+
/* config options here */
|
|
13
|
+
};
|
|
14
|
+
return nextConfig;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
module.exports = withSentryConfig(
|
|
18
|
+
module.exports,
|
|
19
|
+
{ silent: true },
|
|
20
|
+
{ hideSourcemaps: true },
|
|
21
|
+
);
|
|
@@ -10,6 +10,7 @@ import { promisify } from 'util';
|
|
|
10
10
|
|
|
11
11
|
import { Args } from '../../Constants';
|
|
12
12
|
import { debug, green, l, nl, red } from '../../Helper/Logging';
|
|
13
|
+
import { mergeConfigFile } from '../../Helper/MergeConfig';
|
|
13
14
|
import { SentryCli, SentryCliProps } from '../../Helper/SentryCli';
|
|
14
15
|
import { BaseIntegration } from './BaseIntegration';
|
|
15
16
|
|
|
@@ -30,6 +31,7 @@ const TEMPLATE_DESTINATIONS: { [key: string]: string[] } = {
|
|
|
30
31
|
'next.config.js': ['.'],
|
|
31
32
|
'sentry.server.config.js': ['.'],
|
|
32
33
|
'sentry.client.config.js': ['.'],
|
|
34
|
+
'sentry.edge.config.js': ['.'],
|
|
33
35
|
};
|
|
34
36
|
|
|
35
37
|
let appPackage: any = {};
|
|
@@ -59,7 +61,7 @@ export class NextJs extends BaseIntegration {
|
|
|
59
61
|
const configDirectory = path.join(templateDirectory, CONFIG_DIR);
|
|
60
62
|
|
|
61
63
|
if (fs.existsSync(configDirectory)) {
|
|
62
|
-
this._createNextConfig(configDirectory, dsn);
|
|
64
|
+
await this._createNextConfig(configDirectory, dsn);
|
|
63
65
|
} else {
|
|
64
66
|
debug(
|
|
65
67
|
`Couldn't find ${configDirectory}, probably because you ran this from inside of \`/lib\` rather than \`/dist\``,
|
|
@@ -73,7 +75,7 @@ export class NextJs extends BaseIntegration {
|
|
|
73
75
|
(p: { slug: string }) => p.slug === selectedProjectSlug,
|
|
74
76
|
)?.firstEvent;
|
|
75
77
|
if (!hasFirstEvent) {
|
|
76
|
-
this._setTemplate(
|
|
78
|
+
await this._setTemplate(
|
|
77
79
|
templateDirectory,
|
|
78
80
|
'sentry_sample_error.js',
|
|
79
81
|
['pages', 'src/pages'],
|
|
@@ -242,10 +244,18 @@ export class NextJs extends BaseIntegration {
|
|
|
242
244
|
}
|
|
243
245
|
}
|
|
244
246
|
|
|
245
|
-
private _createNextConfig(
|
|
247
|
+
private async _createNextConfig(
|
|
248
|
+
configDirectory: string,
|
|
249
|
+
dsn: any,
|
|
250
|
+
): Promise<void> {
|
|
246
251
|
const templates = fs.readdirSync(configDirectory);
|
|
247
|
-
for
|
|
248
|
-
|
|
252
|
+
// next.config.template.js used for merging next.config.js , not its own template,
|
|
253
|
+
// so it shouldn't have a setTemplate call
|
|
254
|
+
const filteredTemplates = templates.filter(
|
|
255
|
+
(template) => template !== 'next.config.template.js',
|
|
256
|
+
);
|
|
257
|
+
for (const template of filteredTemplates) {
|
|
258
|
+
await this._setTemplate(
|
|
249
259
|
configDirectory,
|
|
250
260
|
template,
|
|
251
261
|
TEMPLATE_DESTINATIONS[template],
|
|
@@ -259,19 +269,18 @@ export class NextJs extends BaseIntegration {
|
|
|
259
269
|
nl();
|
|
260
270
|
}
|
|
261
271
|
|
|
262
|
-
private _setTemplate(
|
|
272
|
+
private async _setTemplate(
|
|
263
273
|
configDirectory: string,
|
|
264
274
|
templateFile: string,
|
|
265
275
|
destinationOptions: string[],
|
|
266
276
|
dsn: string,
|
|
267
|
-
): void {
|
|
277
|
+
): Promise<void> {
|
|
268
278
|
const templatePath = path.join(configDirectory, templateFile);
|
|
269
279
|
|
|
270
280
|
for (const destinationDir of destinationOptions) {
|
|
271
281
|
if (!fs.existsSync(destinationDir)) {
|
|
272
282
|
continue;
|
|
273
283
|
}
|
|
274
|
-
|
|
275
284
|
const destinationPath = path.join(destinationDir, templateFile);
|
|
276
285
|
// in case the file in question already exists, we'll make a copy with
|
|
277
286
|
// `MERGEABLE_CONFIG_INFIX` inserted just before the extension, so as not
|
|
@@ -286,23 +295,35 @@ export class NextJs extends BaseIntegration {
|
|
|
286
295
|
).join('.'),
|
|
287
296
|
);
|
|
288
297
|
|
|
289
|
-
if (
|
|
290
|
-
this.
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
298
|
+
if (templateFile === 'next.config.js') {
|
|
299
|
+
await this._mergeNextConfig(
|
|
300
|
+
destinationPath,
|
|
301
|
+
templatePath,
|
|
302
|
+
destinationDir,
|
|
303
|
+
templateFile,
|
|
304
|
+
configDirectory,
|
|
305
|
+
mergeableFilePath,
|
|
296
306
|
);
|
|
297
|
-
|
|
307
|
+
return;
|
|
298
308
|
} else {
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
309
|
+
if (!fs.existsSync(destinationPath)) {
|
|
310
|
+
this._fillAndCopyTemplate(templatePath, destinationPath, dsn);
|
|
311
|
+
} else if (!fs.existsSync(mergeableFilePath)) {
|
|
312
|
+
this._fillAndCopyTemplate(templatePath, mergeableFilePath, dsn);
|
|
313
|
+
red(
|
|
314
|
+
`File \`${templateFile}\` already exists, so created \`${mergeableFilePath}\`.\n` +
|
|
315
|
+
'Please merge those files.',
|
|
316
|
+
);
|
|
317
|
+
nl();
|
|
318
|
+
} else {
|
|
319
|
+
red(
|
|
320
|
+
`Both \`${templateFile}\` and \`${mergeableFilePath}\` already exist.\n` +
|
|
321
|
+
'Please merge those files.',
|
|
322
|
+
);
|
|
323
|
+
nl();
|
|
324
|
+
}
|
|
325
|
+
return;
|
|
304
326
|
}
|
|
305
|
-
return;
|
|
306
327
|
}
|
|
307
328
|
|
|
308
329
|
red(
|
|
@@ -436,4 +457,61 @@ export class NextJs extends BaseIntegration {
|
|
|
436
457
|
arr.splice(start, deleteCount, ...inserts);
|
|
437
458
|
return arr;
|
|
438
459
|
}
|
|
460
|
+
|
|
461
|
+
private async _mergeNextConfig(
|
|
462
|
+
destinationPath: string,
|
|
463
|
+
templatePath: string,
|
|
464
|
+
destinationDir: string,
|
|
465
|
+
templateFile: string,
|
|
466
|
+
configDirectory: string,
|
|
467
|
+
mergeableFilePath: string,
|
|
468
|
+
): Promise<void> {
|
|
469
|
+
// if no next.config.js exists, we'll create one
|
|
470
|
+
if (!fs.existsSync(destinationPath)) {
|
|
471
|
+
fs.copyFileSync(templatePath, destinationPath);
|
|
472
|
+
green('Created File `next.config.js`');
|
|
473
|
+
nl();
|
|
474
|
+
} else {
|
|
475
|
+
// creates a file name for the copy of the original next.config.js file
|
|
476
|
+
// with the name `next.config.original.js`
|
|
477
|
+
const originalFileName = this._spliceInPlace(
|
|
478
|
+
templateFile.split('.'),
|
|
479
|
+
-1,
|
|
480
|
+
0,
|
|
481
|
+
'original',
|
|
482
|
+
).join('.');
|
|
483
|
+
const originalFilePath = path.join(destinationDir, originalFileName);
|
|
484
|
+
// makes copy of original next.config.js
|
|
485
|
+
fs.writeFileSync(originalFilePath, fs.readFileSync(destinationPath));
|
|
486
|
+
await this._addToGitignore(
|
|
487
|
+
originalFilePath,
|
|
488
|
+
'Unable to add next.config.original.js to gitignore',
|
|
489
|
+
);
|
|
490
|
+
|
|
491
|
+
const mergedTemplatePath = path.join(
|
|
492
|
+
configDirectory,
|
|
493
|
+
'next.config.template.js',
|
|
494
|
+
);
|
|
495
|
+
// attempts to merge with existing next.config.js, if true -> success
|
|
496
|
+
if (mergeConfigFile(destinationPath, mergedTemplatePath)) {
|
|
497
|
+
green(
|
|
498
|
+
`Updated \`${templateFile}\` with Sentry. The original ${templateFile} was saved as \`next.config.original.js\`.\n` +
|
|
499
|
+
'Information on the changes made to the Next.js configuration file an be found at https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/',
|
|
500
|
+
);
|
|
501
|
+
nl();
|
|
502
|
+
} else {
|
|
503
|
+
// if merge fails, we'll create a copy of the `next.config.js` template and ask them to merge
|
|
504
|
+
fs.copyFileSync(templatePath, mergeableFilePath);
|
|
505
|
+
await this._addToGitignore(
|
|
506
|
+
mergeableFilePath,
|
|
507
|
+
'Unable to add next.config.wizard.js template to gitignore',
|
|
508
|
+
);
|
|
509
|
+
red(
|
|
510
|
+
`Unable to merge \`${templateFile}\`, so created \`${mergeableFilePath}\`.\n` +
|
|
511
|
+
'Please integrate next.config.wizardcopy.js into your next.config.js or next.config.ts file',
|
|
512
|
+
);
|
|
513
|
+
nl();
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
}
|
|
439
517
|
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// This file sets a custom webpack configuration to use your Next.js app
|
|
2
|
+
// with Sentry.
|
|
3
|
+
// https://nextjs.org/docs/api-reference/next.config.js/introduction
|
|
4
|
+
// https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/
|
|
5
|
+
const { withSentryConfig } = require('@sentry/nextjs');
|
|
6
|
+
|
|
7
|
+
// ORIGINAL CONFIG
|
|
8
|
+
module.exports = withSentryConfig(
|
|
9
|
+
module.exports,
|
|
10
|
+
{ silent: true },
|
|
11
|
+
{ hideSourcemaps: true },
|
|
12
|
+
);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// This file configures the initialization of Sentry on the server.
|
|
2
|
+
// The config you add here will be used whenever middleware or an Edge route handles a request.
|
|
3
|
+
// https://docs.sentry.io/platforms/javascript/guides/nextjs/
|
|
4
|
+
|
|
5
|
+
import * as Sentry from '@sentry/nextjs';
|
|
6
|
+
|
|
7
|
+
const SENTRY_DSN = process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN;
|
|
8
|
+
|
|
9
|
+
Sentry.init({
|
|
10
|
+
dsn: SENTRY_DSN || '___DSN___',
|
|
11
|
+
// Adjust this value in production, or use tracesSampler for greater control
|
|
12
|
+
tracesSampleRate: 1.0,
|
|
13
|
+
// ...
|
|
14
|
+
// Note: if you want to override the automatic release value, do not set a
|
|
15
|
+
// `release` value here - use the environment variable `SENTRY_RELEASE`, so
|
|
16
|
+
// that it will also get attached to your source maps
|
|
17
|
+
});
|