@sentry/wizard 3.0.0 → 3.1.0-beta.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 +4 -0
- package/bin.ts +9 -2
- package/dist/bin.js +10 -2
- package/dist/bin.js.map +1 -1
- package/dist/lib/Helper/MergeConfig.js +1 -0
- package/dist/lib/Helper/MergeConfig.js.map +1 -1
- package/dist/lib/Steps/BaseStep.js.map +1 -1
- package/dist/lib/Steps/Initial.js +1 -0
- package/dist/lib/Steps/Initial.js.map +1 -1
- package/dist/lib/Steps/Integrations/BaseIntegration.js +2 -0
- package/dist/lib/Steps/Integrations/BaseIntegration.js.map +1 -1
- package/dist/lib/Steps/Integrations/Cordova.js +1 -0
- package/dist/lib/Steps/Integrations/Cordova.js.map +1 -1
- package/dist/lib/Steps/Integrations/Electron.js +2 -0
- package/dist/lib/Steps/Integrations/Electron.js.map +1 -1
- package/dist/lib/Steps/Integrations/MobileProject.js +1 -0
- package/dist/lib/Steps/Integrations/MobileProject.js.map +1 -1
- package/dist/lib/Steps/Integrations/NextJs.js +1 -0
- package/dist/lib/Steps/Integrations/NextJs.js.map +1 -1
- package/dist/lib/Steps/Integrations/ReactNative.js +2 -1
- package/dist/lib/Steps/Integrations/ReactNative.js.map +1 -1
- package/dist/lib/Steps/Result.js +1 -0
- package/dist/lib/Steps/Result.js.map +1 -1
- package/dist/lib/Steps/WaitForSentry.js +42 -47
- package/dist/lib/Steps/WaitForSentry.js.map +1 -1
- package/dist/lib/Steps/Welcome.js +1 -0
- package/dist/lib/Steps/Welcome.js.map +1 -1
- package/dist/src/clack-utils.d.ts +40 -0
- package/dist/src/clack-utils.js +329 -0
- package/dist/src/clack-utils.js.map +1 -0
- package/dist/src/nextjs-wizard.d.ts +5 -0
- package/dist/src/nextjs-wizard.js +346 -0
- package/dist/src/nextjs-wizard.js.map +1 -0
- package/lib/Helper/MergeConfig.ts +1 -0
- package/lib/Steps/BaseStep.ts +1 -1
- package/lib/Steps/Initial.ts +1 -0
- package/lib/Steps/Integrations/BaseIntegration.ts +2 -0
- package/lib/Steps/Integrations/Cordova.ts +2 -1
- package/lib/Steps/Integrations/Electron.ts +3 -1
- package/lib/Steps/Integrations/MobileProject.ts +1 -0
- package/lib/Steps/Integrations/NextJs.ts +1 -0
- package/lib/Steps/Integrations/ReactNative.ts +3 -2
- package/lib/Steps/Result.ts +1 -0
- package/lib/Steps/WaitForSentry.ts +1 -1
- package/lib/Steps/Welcome.ts +2 -1
- package/package.json +10 -3
- package/src/clack-utils.ts +346 -0
- package/src/nextjs-wizard.ts +619 -0
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
+
function step(op) {
|
|
16
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
18
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
+
switch (op[0]) {
|
|
21
|
+
case 0: case 1: t = op; break;
|
|
22
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
+
default:
|
|
26
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
+
if (t[2]) _.ops.pop();
|
|
31
|
+
_.trys.pop(); continue;
|
|
32
|
+
}
|
|
33
|
+
op = body.call(thisArg, _);
|
|
34
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
39
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
40
|
+
if (ar || !(i in from)) {
|
|
41
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
42
|
+
ar[i] = from[i];
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
46
|
+
};
|
|
47
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
+
exports.runNextjsWizard = void 0;
|
|
49
|
+
/* eslint-disable max-lines */
|
|
50
|
+
var clack = require("@clack/prompts");
|
|
51
|
+
var chalk_1 = require("chalk");
|
|
52
|
+
var fs = require("fs");
|
|
53
|
+
var magicast_1 = require("magicast");
|
|
54
|
+
var path = require("path");
|
|
55
|
+
var clack_utils_1 = require("./clack-utils");
|
|
56
|
+
// eslint-disable-next-line complexity
|
|
57
|
+
function runNextjsWizard(options) {
|
|
58
|
+
var _a, _b;
|
|
59
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
60
|
+
var packageJsonFileContents, packageJson, continueWithoutNext, _c, sentryUrl, selfHosted, _d, projects, apiKeys, selectedProject, isUsingTypescript, configVariants, _i, configVariants_1, configVariant, jsConfig, tsConfig, jsConfigExists, tsConfigExists, shouldWriteFile, existingConfigs, overwriteExistingConfigs, webpackOptionsTemplate, sentryBuildOptionsTemplate, newNextConfigTemplate, nextConfigJs, nextConfigMjs, nextConfigJsExists, nextConfigMjsExists, nextConfgiJsContent, probablyIncludesSdk, shouldInject, injectAnyhow, cjsAppendix, nextConfgiMjsContent, probablyIncludesSdk, shouldInject, injectAnyhow, mod, expressionToWrap, newCode, e_1, shouldContinue, maybePagesDirPath, maybeSrcPagesDirPath, pagesLocation, examplePageContents, mightBeUsingVercel;
|
|
61
|
+
return __generator(this, function (_e) {
|
|
62
|
+
switch (_e.label) {
|
|
63
|
+
case 0:
|
|
64
|
+
(0, clack_utils_1.printWelcome)({
|
|
65
|
+
wizardName: 'Sentry Next.js Wizard',
|
|
66
|
+
promoCode: options.promoCode,
|
|
67
|
+
});
|
|
68
|
+
return [4 /*yield*/, (0, clack_utils_1.confirmContinueEvenThoughNoGitRepo)()];
|
|
69
|
+
case 1:
|
|
70
|
+
_e.sent();
|
|
71
|
+
return [4 /*yield*/, fs.promises
|
|
72
|
+
.readFile(path.join(process.cwd(), 'package.json'), 'utf8')
|
|
73
|
+
.catch(function () {
|
|
74
|
+
clack.log.error('Could not find package.json. Make sure to run the wizard in the root of your Next.js app!');
|
|
75
|
+
(0, clack_utils_1.abort)();
|
|
76
|
+
})];
|
|
77
|
+
case 2:
|
|
78
|
+
packageJsonFileContents = _e.sent();
|
|
79
|
+
packageJson = undefined;
|
|
80
|
+
try {
|
|
81
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
82
|
+
packageJson = JSON.parse(packageJsonFileContents);
|
|
83
|
+
}
|
|
84
|
+
catch (e) {
|
|
85
|
+
clack.log.error('Unable to parse your package.json. Make sure it has a valid format!');
|
|
86
|
+
(0, clack_utils_1.abort)();
|
|
87
|
+
}
|
|
88
|
+
if (!!((_a = packageJson === null || packageJson === void 0 ? void 0 : packageJson.dependencies) === null || _a === void 0 ? void 0 : _a['next'])) return [3 /*break*/, 4];
|
|
89
|
+
return [4 /*yield*/, clack.confirm({
|
|
90
|
+
message: 'Next.js does not seem to be installed. Do you still want to continue?',
|
|
91
|
+
initialValue: false,
|
|
92
|
+
})];
|
|
93
|
+
case 3:
|
|
94
|
+
continueWithoutNext = _e.sent();
|
|
95
|
+
(0, clack_utils_1.abortIfCancelled)(continueWithoutNext);
|
|
96
|
+
if (!continueWithoutNext) {
|
|
97
|
+
(0, clack_utils_1.abort)();
|
|
98
|
+
}
|
|
99
|
+
_e.label = 4;
|
|
100
|
+
case 4: return [4 /*yield*/, (0, clack_utils_1.askForSelfHosted)()];
|
|
101
|
+
case 5:
|
|
102
|
+
_c = _e.sent(), sentryUrl = _c.url, selfHosted = _c.selfHosted;
|
|
103
|
+
return [4 /*yield*/, (0, clack_utils_1.askForWizardLogin)({
|
|
104
|
+
promoCode: options.promoCode,
|
|
105
|
+
url: sentryUrl,
|
|
106
|
+
})];
|
|
107
|
+
case 6:
|
|
108
|
+
_d = _e.sent(), projects = _d.projects, apiKeys = _d.apiKeys;
|
|
109
|
+
return [4 /*yield*/, clack.select({
|
|
110
|
+
message: 'Select your Sentry project.',
|
|
111
|
+
options: projects.map(function (project) {
|
|
112
|
+
return {
|
|
113
|
+
value: project,
|
|
114
|
+
label: "".concat(project.organization.slug, "/").concat(project.slug),
|
|
115
|
+
};
|
|
116
|
+
}),
|
|
117
|
+
})];
|
|
118
|
+
case 7:
|
|
119
|
+
selectedProject = _e.sent();
|
|
120
|
+
(0, clack_utils_1.abortIfCancelled)(selectedProject);
|
|
121
|
+
return [4 /*yield*/, (0, clack_utils_1.installPackage)({
|
|
122
|
+
packageName: '@sentry/nextjs',
|
|
123
|
+
alreadyInstalled: !!((_b = packageJson === null || packageJson === void 0 ? void 0 : packageJson.dependencies) === null || _b === void 0 ? void 0 : _b['@sentry/nextjs']),
|
|
124
|
+
})];
|
|
125
|
+
case 8:
|
|
126
|
+
_e.sent();
|
|
127
|
+
isUsingTypescript = false;
|
|
128
|
+
try {
|
|
129
|
+
isUsingTypescript = fs.existsSync(path.join(process.cwd(), 'tsconfig.json'));
|
|
130
|
+
}
|
|
131
|
+
catch (e) {
|
|
132
|
+
// noop - Default to assuming user is not using typescript
|
|
133
|
+
}
|
|
134
|
+
configVariants = ['server', 'client', 'edge'];
|
|
135
|
+
_i = 0, configVariants_1 = configVariants;
|
|
136
|
+
_e.label = 9;
|
|
137
|
+
case 9:
|
|
138
|
+
if (!(_i < configVariants_1.length)) return [3 /*break*/, 14];
|
|
139
|
+
configVariant = configVariants_1[_i];
|
|
140
|
+
jsConfig = "sentry.".concat(configVariant, ".config.js");
|
|
141
|
+
tsConfig = "sentry.".concat(configVariant, ".config.ts");
|
|
142
|
+
jsConfigExists = fs.existsSync(path.join(process.cwd(), jsConfig));
|
|
143
|
+
tsConfigExists = fs.existsSync(path.join(process.cwd(), tsConfig));
|
|
144
|
+
shouldWriteFile = true;
|
|
145
|
+
if (!(jsConfigExists || tsConfigExists)) return [3 /*break*/, 11];
|
|
146
|
+
existingConfigs = [];
|
|
147
|
+
if (jsConfigExists) {
|
|
148
|
+
existingConfigs.push(jsConfig);
|
|
149
|
+
}
|
|
150
|
+
if (tsConfigExists) {
|
|
151
|
+
existingConfigs.push(tsConfig);
|
|
152
|
+
}
|
|
153
|
+
return [4 /*yield*/, clack.confirm({
|
|
154
|
+
message: "Found existing Sentry ".concat(configVariant, " config (").concat(existingConfigs.join(', '), "). Overwrite ").concat(existingConfigs.length > 1 ? 'them' : 'it', "?"),
|
|
155
|
+
})];
|
|
156
|
+
case 10:
|
|
157
|
+
overwriteExistingConfigs = _e.sent();
|
|
158
|
+
(0, clack_utils_1.abortIfCancelled)(overwriteExistingConfigs);
|
|
159
|
+
shouldWriteFile = overwriteExistingConfigs;
|
|
160
|
+
if (overwriteExistingConfigs) {
|
|
161
|
+
if (jsConfigExists) {
|
|
162
|
+
fs.unlinkSync(path.join(process.cwd(), jsConfig));
|
|
163
|
+
clack.log.warn("Removed existing ".concat(chalk_1.default.bold(jsConfig), "."));
|
|
164
|
+
}
|
|
165
|
+
if (tsConfigExists) {
|
|
166
|
+
fs.unlinkSync(path.join(process.cwd(), tsConfig));
|
|
167
|
+
clack.log.warn("Removed existing ".concat(chalk_1.default.bold(tsConfig), "."));
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
_e.label = 11;
|
|
171
|
+
case 11:
|
|
172
|
+
if (!shouldWriteFile) return [3 /*break*/, 13];
|
|
173
|
+
return [4 /*yield*/, fs.promises.writeFile(path.join(process.cwd(), isUsingTypescript ? tsConfig : jsConfig), getSentryConfigContents(selectedProject.keys[0].dsn.public, configVariant), { encoding: 'utf8', flag: 'w' })];
|
|
174
|
+
case 12:
|
|
175
|
+
_e.sent();
|
|
176
|
+
clack.log.success("Created fresh ".concat(chalk_1.default.bold(isUsingTypescript ? tsConfig : jsConfig), "."));
|
|
177
|
+
_e.label = 13;
|
|
178
|
+
case 13:
|
|
179
|
+
_i++;
|
|
180
|
+
return [3 /*break*/, 9];
|
|
181
|
+
case 14:
|
|
182
|
+
webpackOptionsTemplate = "{\n // For all available options, see:\n // https://github.com/getsentry/sentry-webpack-plugin#options\n\n // Suppresses source map uploading logs during build\n silent: true,\n\n org: \"".concat(selectedProject.organization.slug, "\",\n project: \"").concat(selectedProject.slug, "\",\n }");
|
|
183
|
+
sentryBuildOptionsTemplate = "{\n // For all available options, see:\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/\n\n // Upload a larger set of source maps for prettier stack traces (increases build time)\n widenClientFileUpload: true,\n\n // Transpiles SDK to be compatible with IE11 (increases bundle size)\n transpileClientSDK: true,\n\n // Routes browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers (increases server load)\n tunnelRoute: \"/monitoring\",\n\n // Hides source maps from generated client bundles\n hideSourceMaps: true,\n\n // Automatically tree-shake Sentry logger statements to reduce bundle size\n disableLogger: true,\n }";
|
|
184
|
+
newNextConfigTemplate = "const { withSentryConfig } = require(\"@sentry/nextjs\");\n\n/** @type {import('next').NextConfig} */\nconst nextConfig = {};\n\nmodule.exports = withSentryConfig(\n nextConfig,\n ".concat(webpackOptionsTemplate, ",\n ").concat(sentryBuildOptionsTemplate, "\n);\n");
|
|
185
|
+
nextConfigJs = 'next.config.js';
|
|
186
|
+
nextConfigMjs = 'next.config.mjs';
|
|
187
|
+
nextConfigJsExists = fs.existsSync(path.join(process.cwd(), nextConfigJs));
|
|
188
|
+
nextConfigMjsExists = fs.existsSync(path.join(process.cwd(), nextConfigMjs));
|
|
189
|
+
if (!(!nextConfigJsExists && !nextConfigMjsExists)) return [3 /*break*/, 16];
|
|
190
|
+
return [4 /*yield*/, fs.promises.writeFile(path.join(process.cwd(), nextConfigJs), newNextConfigTemplate, { encoding: 'utf8', flag: 'w' })];
|
|
191
|
+
case 15:
|
|
192
|
+
_e.sent();
|
|
193
|
+
clack.log.success("Created ".concat(chalk_1.default.bold('next.config.js'), " with Sentry configuration."));
|
|
194
|
+
_e.label = 16;
|
|
195
|
+
case 16:
|
|
196
|
+
if (!nextConfigJsExists) return [3 /*break*/, 19];
|
|
197
|
+
nextConfgiJsContent = fs.readFileSync(path.join(process.cwd(), nextConfigJs), 'utf8');
|
|
198
|
+
probablyIncludesSdk = nextConfgiJsContent.includes('@sentry/nextjs') &&
|
|
199
|
+
nextConfgiJsContent.includes('withSentryConfig');
|
|
200
|
+
shouldInject = true;
|
|
201
|
+
if (!probablyIncludesSdk) return [3 /*break*/, 18];
|
|
202
|
+
return [4 /*yield*/, clack.confirm({
|
|
203
|
+
message: "".concat(chalk_1.default.bold(nextConfigMjs), " already contains Sentry SDK configuration. Should the wizard modify it anyways?"),
|
|
204
|
+
})];
|
|
205
|
+
case 17:
|
|
206
|
+
injectAnyhow = _e.sent();
|
|
207
|
+
(0, clack_utils_1.abortIfCancelled)(injectAnyhow);
|
|
208
|
+
shouldInject = injectAnyhow;
|
|
209
|
+
_e.label = 18;
|
|
210
|
+
case 18:
|
|
211
|
+
if (shouldInject) {
|
|
212
|
+
cjsAppendix = "\n\n// Inected Content via Sentry Wizard Below\n\nconst { withSentryConfig } = require(\"@sentry/nextjs\");\n\nmodule.exports = withSentryConfig(\n module.exports,\n ".concat(webpackOptionsTemplate, ",\n ").concat(sentryBuildOptionsTemplate, "\n);\n");
|
|
213
|
+
fs.appendFileSync(path.join(process.cwd(), nextConfigJs), cjsAppendix, 'utf8');
|
|
214
|
+
clack.log.success("Added Sentry configuration to ".concat(chalk_1.default.bold(nextConfigJs), ". ").concat(chalk_1.default.dim('(you probably want to clean this up a bit!)')));
|
|
215
|
+
}
|
|
216
|
+
_e.label = 19;
|
|
217
|
+
case 19:
|
|
218
|
+
if (!nextConfigMjsExists) return [3 /*break*/, 26];
|
|
219
|
+
nextConfgiMjsContent = fs.readFileSync(path.join(process.cwd(), nextConfigMjs), 'utf8');
|
|
220
|
+
probablyIncludesSdk = nextConfgiMjsContent.includes('@sentry/nextjs') &&
|
|
221
|
+
nextConfgiMjsContent.includes('withSentryConfig');
|
|
222
|
+
shouldInject = true;
|
|
223
|
+
if (!probablyIncludesSdk) return [3 /*break*/, 21];
|
|
224
|
+
return [4 /*yield*/, clack.confirm({
|
|
225
|
+
message: "".concat(chalk_1.default.bold(nextConfigMjs), " already contains Sentry SDK configuration. Should the wizard modify it anyways?"),
|
|
226
|
+
})];
|
|
227
|
+
case 20:
|
|
228
|
+
injectAnyhow = _e.sent();
|
|
229
|
+
(0, clack_utils_1.abortIfCancelled)(injectAnyhow);
|
|
230
|
+
shouldInject = injectAnyhow;
|
|
231
|
+
_e.label = 21;
|
|
232
|
+
case 21:
|
|
233
|
+
_e.trys.push([21, 24, , 26]);
|
|
234
|
+
if (!shouldInject) return [3 /*break*/, 23];
|
|
235
|
+
mod = (0, magicast_1.parseModule)(nextConfgiMjsContent);
|
|
236
|
+
mod.imports.$add({
|
|
237
|
+
from: '@sentry/nextjs',
|
|
238
|
+
imported: 'withSentryConfig',
|
|
239
|
+
local: 'withSentryConfig',
|
|
240
|
+
});
|
|
241
|
+
expressionToWrap = (0, magicast_1.generateCode)(mod.exports.default.$ast).code;
|
|
242
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
243
|
+
mod.exports.default = magicast_1.builders.raw("withSentryConfig(\n ".concat(expressionToWrap, ",\n ").concat(webpackOptionsTemplate, ",\n ").concat(sentryBuildOptionsTemplate, "\n)"));
|
|
244
|
+
newCode = mod.generate().code;
|
|
245
|
+
return [4 /*yield*/, fs.promises.writeFile(path.join(process.cwd(), nextConfigMjs), newCode, {
|
|
246
|
+
encoding: 'utf8',
|
|
247
|
+
flag: 'w',
|
|
248
|
+
})];
|
|
249
|
+
case 22:
|
|
250
|
+
_e.sent();
|
|
251
|
+
clack.log.success("Added Sentry configuration to ".concat(chalk_1.default.bold(nextConfigMjs), ". ").concat(chalk_1.default.dim('(you probably want to clean this up a bit!)')));
|
|
252
|
+
_e.label = 23;
|
|
253
|
+
case 23: return [3 /*break*/, 26];
|
|
254
|
+
case 24:
|
|
255
|
+
e_1 = _e.sent();
|
|
256
|
+
clack.log.warn(chalk_1.default.yellow("Something went wrong writing to ".concat(chalk_1.default.bold(nextConfigMjs))));
|
|
257
|
+
clack.log.info("Please put the following code snippet into ".concat(chalk_1.default.bold(nextConfigMjs), ": ").concat(chalk_1.default.dim('You probably have to clean it up a bit.'), "\n"));
|
|
258
|
+
// eslint-disable-next-line no-console
|
|
259
|
+
console.log("\n\n// next.config.mjs\nimport { withSentryConfig } from \"@sentry/nextjs\";\n\nexport default withSentryConfig(\n yourNextConfig,\n ".concat(webpackOptionsTemplate, ",\n ").concat(sentryBuildOptionsTemplate, "\n);\n"));
|
|
260
|
+
return [4 /*yield*/, clack.confirm({
|
|
261
|
+
message: "Are you done putting the snippet above into ".concat(chalk_1.default.bold(nextConfigMjs), "?"),
|
|
262
|
+
active: 'Yes',
|
|
263
|
+
inactive: 'No, get me out of here',
|
|
264
|
+
})];
|
|
265
|
+
case 25:
|
|
266
|
+
shouldContinue = _e.sent();
|
|
267
|
+
(0, clack_utils_1.abortIfCancelled)(shouldContinue);
|
|
268
|
+
if (!shouldContinue) {
|
|
269
|
+
(0, clack_utils_1.abort)();
|
|
270
|
+
}
|
|
271
|
+
return [3 /*break*/, 26];
|
|
272
|
+
case 26:
|
|
273
|
+
maybePagesDirPath = path.join(process.cwd(), 'pages');
|
|
274
|
+
maybeSrcPagesDirPath = path.join(process.cwd(), 'src', 'pages');
|
|
275
|
+
pagesLocation = fs.existsSync(maybePagesDirPath) &&
|
|
276
|
+
fs.lstatSync(maybePagesDirPath).isDirectory()
|
|
277
|
+
? ['pages']
|
|
278
|
+
: fs.existsSync(maybeSrcPagesDirPath) &&
|
|
279
|
+
fs.lstatSync(maybeSrcPagesDirPath).isDirectory()
|
|
280
|
+
? ['src', 'pages']
|
|
281
|
+
: undefined;
|
|
282
|
+
if (!pagesLocation) {
|
|
283
|
+
pagesLocation = ['pages'];
|
|
284
|
+
fs.mkdirSync(path.join.apply(path, __spreadArray([process.cwd()], pagesLocation, false)), {
|
|
285
|
+
recursive: true,
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
if (!pagesLocation) return [3 /*break*/, 29];
|
|
289
|
+
examplePageContents = createExamplePage({
|
|
290
|
+
selfHosted: selfHosted,
|
|
291
|
+
orgSlug: selectedProject.organization.slug,
|
|
292
|
+
projectId: selectedProject.id,
|
|
293
|
+
url: sentryUrl,
|
|
294
|
+
});
|
|
295
|
+
return [4 /*yield*/, fs.promises.writeFile(path.join.apply(path, __spreadArray(__spreadArray([process.cwd()], pagesLocation, false), ['sentry-example-page.js'], false)), examplePageContents, { encoding: 'utf8', flag: 'w' })];
|
|
296
|
+
case 27:
|
|
297
|
+
_e.sent();
|
|
298
|
+
clack.log.success("Created ".concat(chalk_1.default.bold(path.join.apply(path, __spreadArray(__spreadArray([], pagesLocation, false), ['sentry-example-page.js'], false))), "."));
|
|
299
|
+
fs.mkdirSync(path.join.apply(path, __spreadArray(__spreadArray([process.cwd()], pagesLocation, false), ['api'], false)), {
|
|
300
|
+
recursive: true,
|
|
301
|
+
});
|
|
302
|
+
return [4 /*yield*/, fs.promises.writeFile(path.join.apply(path, __spreadArray(__spreadArray([process.cwd()], pagesLocation, false), ['api',
|
|
303
|
+
'sentry-example-api.js'], false)), exampleApiRoute, { encoding: 'utf8', flag: 'w' })];
|
|
304
|
+
case 28:
|
|
305
|
+
_e.sent();
|
|
306
|
+
clack.log.success("Created ".concat(chalk_1.default.bold(path.join.apply(path, __spreadArray(__spreadArray([], pagesLocation, false), ['api', 'sentry-example-api.js'], false))), "."));
|
|
307
|
+
_e.label = 29;
|
|
308
|
+
case 29: return [4 /*yield*/, (0, clack_utils_1.addSentryCliRc)(apiKeys.token)];
|
|
309
|
+
case 30:
|
|
310
|
+
_e.sent();
|
|
311
|
+
mightBeUsingVercel = fs.existsSync(path.join(process.cwd(), 'vercel.json'));
|
|
312
|
+
clack.outro("".concat(chalk_1.default.green('Everything is set up!'), "\n\n ").concat(chalk_1.default.cyan('You can validate your setup by starting your dev environment (`next dev`) and visiting "/sentry-example-page".'), "\n").concat(mightBeUsingVercel
|
|
313
|
+
? "\n \u25B2 It seems like you're using Vercel. We recommend using the Sentry Vercel integration: https://vercel.com/integrations/sentry\n"
|
|
314
|
+
: '', "\n ").concat(chalk_1.default.dim('If you encounter any issues, let us know here: https://github.com/getsentry/sentry-javascript/issues')));
|
|
315
|
+
return [2 /*return*/];
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
exports.runNextjsWizard = runNextjsWizard;
|
|
321
|
+
function getSentryConfigContents(dsn, config) {
|
|
322
|
+
var primer;
|
|
323
|
+
if (config === 'server') {
|
|
324
|
+
primer = "// This file configures the initialization of Sentry on the server.\n// The config you add here will be used whenever the server handles a request.\n// https://docs.sentry.io/platforms/javascript/guides/nextjs/";
|
|
325
|
+
}
|
|
326
|
+
else if (config === 'client') {
|
|
327
|
+
primer = "// This file configures the initialization of Sentry on the client.\n// The config you add here will be used whenever a users loads a page in their browser.\n// https://docs.sentry.io/platforms/javascript/guides/nextjs/";
|
|
328
|
+
}
|
|
329
|
+
else if (config === 'edge') {
|
|
330
|
+
primer = "// This file configures the initialization of Sentry for edge features (middleware, edge routes, and so on).\n// The config you add here will be used whenever one of the edge features is loaded.\n// Note that this config is unrelated to the Verel Edge Runtime and is also required when running locally.\n// https://docs.sentry.io/platforms/javascript/guides/nextjs/";
|
|
331
|
+
}
|
|
332
|
+
var additionalOptions = '';
|
|
333
|
+
if (config === 'client') {
|
|
334
|
+
additionalOptions = "\n\n replaysOnErrorSampleRate: 1.0,\n\n // This sets the sample rate to be 10%. You may want this to be 100% while\n // in development and sample at a lower rate in production\n replaysSessionSampleRate: 0.1,\n\n // You can remove this option if you're not planning to use the Sentry Session Replay feature:\n integrations: [\n new Sentry.Replay({\n // Additional Replay configuration goes in here, for example:\n maskAllText: true,\n blockAllMedia: true,\n }),\n ],";
|
|
335
|
+
}
|
|
336
|
+
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
|
337
|
+
return "".concat(primer, "\n\nimport * as Sentry from \"@sentry/nextjs\";\n\nSentry.init({\n dsn: \"").concat(dsn, "\",\n\n // Adjust this value in production, or use tracesSampler for greater control\n tracesSampleRate: 1,\n\n // Setting this option to true will print useful information to the console while you're setting up Sentry.\n debug: false,").concat(additionalOptions, "\n});\n");
|
|
338
|
+
}
|
|
339
|
+
function createExamplePage(options) {
|
|
340
|
+
var issuesPageLink = options.selfHosted
|
|
341
|
+
? "".concat(options.url, "organizations/").concat(options.orgSlug, "/issues/?project=").concat(options.projectId)
|
|
342
|
+
: "https://".concat(options.orgSlug, ".sentry.io/issues/?project=").concat(options.projectId);
|
|
343
|
+
return "import Head from \"next/head\";\nimport * as Sentry from \"@sentry/nextjs\";\n\nexport default function Home() {\n return (\n <div>\n <Head>\n <title>Sentry Onboarding</title>\n <meta name=\"description\" content=\"Test Sentry for your Next.js app!\" />\n </Head>\n\n <main\n style={{\n minHeight: \"100vh\",\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n alignItems: \"center\",\n }}\n >\n <h1 style={{ fontSize: \"4rem\", margin: \"14px 0\" }}>\n <svg\n style={{\n height: \"1em\",\n }}\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 200 44\"\n >\n <path\n fill=\"currentColor\"\n d=\"M124.32,28.28,109.56,9.22h-3.68V34.77h3.73V15.19l15.18,19.58h3.26V9.22h-3.73ZM87.15,23.54h13.23V20.22H87.14V12.53h14.93V9.21H83.34V34.77h18.92V31.45H87.14ZM71.59,20.3h0C66.44,19.06,65,18.08,65,15.7c0-2.14,1.89-3.59,4.71-3.59a12.06,12.06,0,0,1,7.07,2.55l2-2.83a14.1,14.1,0,0,0-9-3c-5.06,0-8.59,3-8.59,7.27,0,4.6,3,6.19,8.46,7.52C74.51,24.74,76,25.78,76,28.11s-2,3.77-5.09,3.77a12.34,12.34,0,0,1-8.3-3.26l-2.25,2.69a15.94,15.94,0,0,0,10.42,3.85c5.48,0,9-2.95,9-7.51C79.75,23.79,77.47,21.72,71.59,20.3ZM195.7,9.22l-7.69,12-7.64-12h-4.46L186,24.67V34.78h3.84V24.55L200,9.22Zm-64.63,3.46h8.37v22.1h3.84V12.68h8.37V9.22H131.08ZM169.41,24.8c3.86-1.07,6-3.77,6-7.63,0-4.91-3.59-8-9.38-8H154.67V34.76h3.8V25.58h6.45l6.48,9.2h4.44l-7-9.82Zm-10.95-2.5V12.6h7.17c3.74,0,5.88,1.77,5.88,4.84s-2.29,4.86-5.84,4.86Z M29,2.26a4.67,4.67,0,0,0-8,0L14.42,13.53A32.21,32.21,0,0,1,32.17,40.19H27.55A27.68,27.68,0,0,0,12.09,17.47L6,28a15.92,15.92,0,0,1,9.23,12.17H4.62A.76.76,0,0,1,4,39.06l2.94-5a10.74,10.74,0,0,0-3.36-1.9l-2.91,5a4.54,4.54,0,0,0,1.69,6.24A4.66,4.66,0,0,0,4.62,44H19.15a19.4,19.4,0,0,0-8-17.31l2.31-4A23.87,23.87,0,0,1,23.76,44H36.07a35.88,35.88,0,0,0-16.41-31.8l4.67-8a.77.77,0,0,1,1.05-.27c.53.29,20.29,34.77,20.66,35.17a.76.76,0,0,1-.68,1.13H40.6q.09,1.91,0,3.81h4.78A4.59,4.59,0,0,0,50,39.43a4.49,4.49,0,0,0-.62-2.28Z\"\n ></path>\n </svg>\n </h1>\n\n <p>Get started by sending us a sample error:</p>\n <button\n type=\"button\"\n style={{\n padding: \"12px\",\n cursor: \"pointer\",\n backgroundColor: \"#AD6CAA\",\n borderRadius: \"4px\",\n border: \"none\",\n color: \"white\",\n fontSize: \"14px\",\n margin: \"18px\",\n }}\n onClick={async () => {\n const transaction = Sentry.startTransaction({\n name: \"Example Frontend Transaction\",\n });\n\n Sentry.configureScope((scope) => {\n scope.setSpan(transaction);\n });\n\n try {\n const res = await fetch(\"/api/sentry-example-api\");\n if (!res.ok) {\n throw new Error(\"Sentry Example Frontend Error\");\n }\n } finally {\n transaction.finish();\n }\n }}\n >\n Throw error!\n </button>\n\n <p>\n Next, look for the error on the{\" \"}\n <a href=\"".concat(issuesPageLink, "\">Issues Page</a>.\n </p>\n <p style={{ marginTop: \"24px\" }}>\n For more information, see{\" \"}\n <a href=\"https://docs.sentry.io/platforms/javascript/guides/nextjs/\">\n https://docs.sentry.io/platforms/javascript/guides/nextjs/\n </a>\n </p>\n </main>\n </div>\n );\n}\n");
|
|
344
|
+
}
|
|
345
|
+
var exampleApiRoute = "// A faulty API route to test Sentry's error monitoring\nexport default function handler(_req, res) {\n throw new Error(\"Sentry Example API Route Error\");\n res.status(200).json({ name: \"John Doe\" });\n}\n";
|
|
346
|
+
//# sourceMappingURL=nextjs-wizard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nextjs-wizard.js","sourceRoot":"","sources":["../../src/nextjs-wizard.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable max-lines */\nimport * as clack from '@clack/prompts';\nimport chalk from 'chalk';\nimport * as fs from 'fs';\nimport { builders, generateCode, parseModule } from 'magicast';\nimport * as path from 'path';\n\nimport {\n abort,\n abortIfCancelled,\n addSentryCliRc,\n askForSelfHosted,\n askForWizardLogin,\n confirmContinueEvenThoughNoGitRepo,\n installPackage,\n printWelcome,\n SentryProjectData,\n} from './clack-utils';\n\ninterface NextjsWizardOptions {\n promoCode?: string;\n}\n\n// eslint-disable-next-line complexity\nexport async function runNextjsWizard(\n options: NextjsWizardOptions,\n): Promise<void> {\n printWelcome({\n wizardName: 'Sentry Next.js Wizard',\n promoCode: options.promoCode,\n });\n\n await confirmContinueEvenThoughNoGitRepo();\n\n const packageJsonFileContents = await fs.promises\n .readFile(path.join(process.cwd(), 'package.json'), 'utf8')\n .catch(() => {\n clack.log.error(\n 'Could not find package.json. Make sure to run the wizard in the root of your Next.js app!',\n );\n abort();\n });\n\n let packageJson:\n | { dependencies?: { ['@sentry/nextjs']: string; ['next']: string } }\n | undefined = undefined;\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n packageJson = JSON.parse(packageJsonFileContents);\n } catch (e) {\n clack.log.error(\n 'Unable to parse your package.json. Make sure it has a valid format!',\n );\n\n abort();\n }\n\n if (!packageJson?.dependencies?.['next']) {\n const continueWithoutNext = await clack.confirm({\n message:\n 'Next.js does not seem to be installed. Do you still want to continue?',\n initialValue: false,\n });\n\n abortIfCancelled(continueWithoutNext);\n\n if (!continueWithoutNext) {\n abort();\n }\n }\n\n const { url: sentryUrl, selfHosted } = await askForSelfHosted();\n\n const { projects, apiKeys } = await askForWizardLogin({\n promoCode: options.promoCode,\n url: sentryUrl,\n });\n\n const selectedProject: SentryProjectData | symbol = await clack.select({\n message: 'Select your Sentry project.',\n options: projects.map(project => {\n return {\n value: project,\n label: `${project.organization.slug}/${project.slug}`,\n };\n }),\n });\n\n abortIfCancelled(selectedProject);\n\n await installPackage({\n packageName: '@sentry/nextjs',\n alreadyInstalled: !!packageJson?.dependencies?.['@sentry/nextjs'],\n });\n\n let isUsingTypescript = false;\n try {\n isUsingTypescript = fs.existsSync(\n path.join(process.cwd(), 'tsconfig.json'),\n );\n } catch (e) {\n // noop - Default to assuming user is not using typescript\n }\n\n const configVariants = ['server', 'client', 'edge'] as const;\n\n for (const configVariant of configVariants) {\n const jsConfig = `sentry.${configVariant}.config.js`;\n const tsConfig = `sentry.${configVariant}.config.ts`;\n\n const jsConfigExists = fs.existsSync(path.join(process.cwd(), jsConfig));\n const tsConfigExists = fs.existsSync(path.join(process.cwd(), tsConfig));\n\n let shouldWriteFile = true;\n\n if (jsConfigExists || tsConfigExists) {\n const existingConfigs = [];\n\n if (jsConfigExists) {\n existingConfigs.push(jsConfig);\n }\n\n if (tsConfigExists) {\n existingConfigs.push(tsConfig);\n }\n\n const overwriteExistingConfigs = await clack.confirm({\n message: `Found existing Sentry ${configVariant} config (${existingConfigs.join(\n ', ',\n )}). Overwrite ${existingConfigs.length > 1 ? 'them' : 'it'}?`,\n });\n\n abortIfCancelled(overwriteExistingConfigs);\n\n shouldWriteFile = overwriteExistingConfigs;\n\n if (overwriteExistingConfigs) {\n if (jsConfigExists) {\n fs.unlinkSync(path.join(process.cwd(), jsConfig));\n clack.log.warn(`Removed existing ${chalk.bold(jsConfig)}.`);\n }\n if (tsConfigExists) {\n fs.unlinkSync(path.join(process.cwd(), tsConfig));\n clack.log.warn(`Removed existing ${chalk.bold(tsConfig)}.`);\n }\n }\n }\n\n if (shouldWriteFile) {\n await fs.promises.writeFile(\n path.join(process.cwd(), isUsingTypescript ? tsConfig : jsConfig),\n getSentryConfigContents(\n selectedProject.keys[0].dsn.public,\n configVariant,\n ),\n { encoding: 'utf8', flag: 'w' },\n );\n clack.log.success(\n `Created fresh ${chalk.bold(isUsingTypescript ? tsConfig : jsConfig)}.`,\n );\n }\n }\n\n const webpackOptionsTemplate = `{\n // For all available options, see:\n // https://github.com/getsentry/sentry-webpack-plugin#options\n\n // Suppresses source map uploading logs during build\n silent: true,\n\n org: \"${selectedProject.organization.slug}\",\n project: \"${selectedProject.slug}\",\n }`;\n\n const sentryBuildOptionsTemplate = `{\n // For all available options, see:\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/\n\n // Upload a larger set of source maps for prettier stack traces (increases build time)\n widenClientFileUpload: true,\n\n // Transpiles SDK to be compatible with IE11 (increases bundle size)\n transpileClientSDK: true,\n\n // Routes browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers (increases server load)\n tunnelRoute: \"/monitoring\",\n\n // Hides source maps from generated client bundles\n hideSourceMaps: true,\n\n // Automatically tree-shake Sentry logger statements to reduce bundle size\n disableLogger: true,\n }`;\n\n const newNextConfigTemplate = `const { withSentryConfig } = require(\"@sentry/nextjs\");\n\n/** @type {import('next').NextConfig} */\nconst nextConfig = {};\n\nmodule.exports = withSentryConfig(\n nextConfig,\n ${webpackOptionsTemplate},\n ${sentryBuildOptionsTemplate}\n);\n`;\n\n const nextConfigJs = 'next.config.js';\n const nextConfigMjs = 'next.config.mjs';\n\n const nextConfigJsExists = fs.existsSync(\n path.join(process.cwd(), nextConfigJs),\n );\n const nextConfigMjsExists = fs.existsSync(\n path.join(process.cwd(), nextConfigMjs),\n );\n\n if (!nextConfigJsExists && !nextConfigMjsExists) {\n await fs.promises.writeFile(\n path.join(process.cwd(), nextConfigJs),\n newNextConfigTemplate,\n { encoding: 'utf8', flag: 'w' },\n );\n\n clack.log.success(\n `Created ${chalk.bold('next.config.js')} with Sentry configuration.`,\n );\n }\n\n if (nextConfigJsExists) {\n const nextConfgiJsContent = fs.readFileSync(\n path.join(process.cwd(), nextConfigJs),\n 'utf8',\n );\n\n const probablyIncludesSdk =\n nextConfgiJsContent.includes('@sentry/nextjs') &&\n nextConfgiJsContent.includes('withSentryConfig');\n\n let shouldInject = true;\n\n if (probablyIncludesSdk) {\n const injectAnyhow = await clack.confirm({\n message: `${chalk.bold(\n nextConfigMjs,\n )} already contains Sentry SDK configuration. Should the wizard modify it anyways?`,\n });\n\n abortIfCancelled(injectAnyhow);\n\n shouldInject = injectAnyhow;\n }\n\n if (shouldInject) {\n const cjsAppendix = `\n\n// Inected Content via Sentry Wizard Below\n\nconst { withSentryConfig } = require(\"@sentry/nextjs\");\n\nmodule.exports = withSentryConfig(\n module.exports,\n ${webpackOptionsTemplate},\n ${sentryBuildOptionsTemplate}\n);\n`;\n fs.appendFileSync(\n path.join(process.cwd(), nextConfigJs),\n cjsAppendix,\n 'utf8',\n );\n\n clack.log.success(\n `Added Sentry configuration to ${chalk.bold(nextConfigJs)}. ${chalk.dim(\n '(you probably want to clean this up a bit!)',\n )}`,\n );\n }\n }\n\n if (nextConfigMjsExists) {\n const nextConfgiMjsContent = fs.readFileSync(\n path.join(process.cwd(), nextConfigMjs),\n 'utf8',\n );\n\n const probablyIncludesSdk =\n nextConfgiMjsContent.includes('@sentry/nextjs') &&\n nextConfgiMjsContent.includes('withSentryConfig');\n\n let shouldInject = true;\n\n if (probablyIncludesSdk) {\n const injectAnyhow = await clack.confirm({\n message: `${chalk.bold(\n nextConfigMjs,\n )} already contains Sentry SDK configuration. Should the wizard modify it anyways?`,\n });\n\n abortIfCancelled(injectAnyhow);\n shouldInject = injectAnyhow;\n }\n\n try {\n if (shouldInject) {\n const mod = parseModule(nextConfgiMjsContent);\n mod.imports.$add({\n from: '@sentry/nextjs',\n imported: 'withSentryConfig',\n local: 'withSentryConfig',\n });\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access\n const expressionToWrap = generateCode(mod.exports.default.$ast).code;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n mod.exports.default = builders.raw(`withSentryConfig(\n ${expressionToWrap},\n ${webpackOptionsTemplate},\n ${sentryBuildOptionsTemplate}\n)`);\n const newCode = mod.generate().code;\n\n await fs.promises.writeFile(\n path.join(process.cwd(), nextConfigMjs),\n newCode,\n {\n encoding: 'utf8',\n flag: 'w',\n },\n );\n clack.log.success(\n `Added Sentry configuration to ${chalk.bold(\n nextConfigMjs,\n )}. ${chalk.dim('(you probably want to clean this up a bit!)')}`,\n );\n }\n } catch (e) {\n clack.log.warn(\n chalk.yellow(\n `Something went wrong writing to ${chalk.bold(nextConfigMjs)}`,\n ),\n );\n clack.log.info(\n `Please put the following code snippet into ${chalk.bold(\n nextConfigMjs,\n )}: ${chalk.dim('You probably have to clean it up a bit.')}\\n`,\n );\n\n // eslint-disable-next-line no-console\n console.log(`\\n\n// next.config.mjs\nimport { withSentryConfig } from \"@sentry/nextjs\";\n\nexport default withSentryConfig(\n yourNextConfig,\n ${webpackOptionsTemplate},\n ${sentryBuildOptionsTemplate}\n);\\n`);\n\n const shouldContinue = await clack.confirm({\n message: `Are you done putting the snippet above into ${chalk.bold(\n nextConfigMjs,\n )}?`,\n active: 'Yes',\n inactive: 'No, get me out of here',\n });\n\n abortIfCancelled(shouldContinue);\n if (!shouldContinue) {\n abort();\n }\n }\n }\n\n const maybePagesDirPath = path.join(process.cwd(), 'pages');\n const maybeSrcPagesDirPath = path.join(process.cwd(), 'src', 'pages');\n\n let pagesLocation =\n fs.existsSync(maybePagesDirPath) &&\n fs.lstatSync(maybePagesDirPath).isDirectory()\n ? ['pages']\n : fs.existsSync(maybeSrcPagesDirPath) &&\n fs.lstatSync(maybeSrcPagesDirPath).isDirectory()\n ? ['src', 'pages']\n : undefined;\n\n if (!pagesLocation) {\n pagesLocation = ['pages'];\n fs.mkdirSync(path.join(process.cwd(), ...pagesLocation), {\n recursive: true,\n });\n }\n\n if (pagesLocation) {\n const examplePageContents = createExamplePage({\n selfHosted,\n orgSlug: selectedProject.organization.slug,\n projectId: selectedProject.id,\n url: sentryUrl,\n });\n\n await fs.promises.writeFile(\n path.join(process.cwd(), ...pagesLocation, 'sentry-example-page.js'),\n examplePageContents,\n { encoding: 'utf8', flag: 'w' },\n );\n\n clack.log.success(\n `Created ${chalk.bold(\n path.join(...pagesLocation, 'sentry-example-page.js'),\n )}.`,\n );\n\n fs.mkdirSync(path.join(process.cwd(), ...pagesLocation, 'api'), {\n recursive: true,\n });\n\n await fs.promises.writeFile(\n path.join(\n process.cwd(),\n ...pagesLocation,\n 'api',\n 'sentry-example-api.js',\n ),\n exampleApiRoute,\n { encoding: 'utf8', flag: 'w' },\n );\n\n clack.log.success(\n `Created ${chalk.bold(\n path.join(...pagesLocation, 'api', 'sentry-example-api.js'),\n )}.`,\n );\n }\n\n await addSentryCliRc(apiKeys.token);\n\n const mightBeUsingVercel = fs.existsSync(\n path.join(process.cwd(), 'vercel.json'),\n );\n\n clack.outro(\n `${chalk.green('Everything is set up!')}\n\n ${chalk.cyan(\n 'You can validate your setup by starting your dev environment (`next dev`) and visiting \"/sentry-example-page\".',\n )}\n${\n mightBeUsingVercel\n ? `\n ▲ It seems like you're using Vercel. We recommend using the Sentry Vercel integration: https://vercel.com/integrations/sentry\n`\n : ''\n}\n ${chalk.dim(\n 'If you encounter any issues, let us know here: https://github.com/getsentry/sentry-javascript/issues',\n )}`,\n );\n}\n\nfunction getSentryConfigContents(\n dsn: string,\n config: 'server' | 'client' | 'edge',\n): string {\n let primer;\n if (config === 'server') {\n primer = `// This file configures the initialization of Sentry on the server.\n// The config you add here will be used whenever the server handles a request.\n// https://docs.sentry.io/platforms/javascript/guides/nextjs/`;\n } else if (config === 'client') {\n primer = `// This file configures the initialization of Sentry on the client.\n// The config you add here will be used whenever a users loads a page in their browser.\n// https://docs.sentry.io/platforms/javascript/guides/nextjs/`;\n } else if (config === 'edge') {\n primer = `// This file configures the initialization of Sentry for edge features (middleware, edge routes, and so on).\n// The config you add here will be used whenever one of the edge features is loaded.\n// Note that this config is unrelated to the Verel Edge Runtime and is also required when running locally.\n// https://docs.sentry.io/platforms/javascript/guides/nextjs/`;\n }\n\n let additionalOptions = '';\n if (config === 'client') {\n additionalOptions = `\n\n replaysOnErrorSampleRate: 1.0,\n\n // This sets the sample rate to be 10%. You may want this to be 100% while\n // in development and sample at a lower rate in production\n replaysSessionSampleRate: 0.1,\n\n // You can remove this option if you're not planning to use the Sentry Session Replay feature:\n integrations: [\n new Sentry.Replay({\n // Additional Replay configuration goes in here, for example:\n maskAllText: true,\n blockAllMedia: true,\n }),\n ],`;\n }\n\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n return `${primer}\n\nimport * as Sentry from \"@sentry/nextjs\";\n\nSentry.init({\n dsn: \"${dsn}\",\n\n // Adjust this value in production, or use tracesSampler for greater control\n tracesSampleRate: 1,\n\n // Setting this option to true will print useful information to the console while you're setting up Sentry.\n debug: false,${additionalOptions}\n});\n`;\n}\n\nfunction createExamplePage(options: {\n selfHosted: boolean;\n url: string;\n orgSlug: string;\n projectId: string;\n}): string {\n const issuesPageLink = options.selfHosted\n ? `${options.url}organizations/${options.orgSlug}/issues/?project=${options.projectId}`\n : `https://${options.orgSlug}.sentry.io/issues/?project=${options.projectId}`;\n\n return `import Head from \"next/head\";\nimport * as Sentry from \"@sentry/nextjs\";\n\nexport default function Home() {\n return (\n <div>\n <Head>\n <title>Sentry Onboarding</title>\n <meta name=\"description\" content=\"Test Sentry for your Next.js app!\" />\n </Head>\n\n <main\n style={{\n minHeight: \"100vh\",\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n alignItems: \"center\",\n }}\n >\n <h1 style={{ fontSize: \"4rem\", margin: \"14px 0\" }}>\n <svg\n style={{\n height: \"1em\",\n }}\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 200 44\"\n >\n <path\n fill=\"currentColor\"\n d=\"M124.32,28.28,109.56,9.22h-3.68V34.77h3.73V15.19l15.18,19.58h3.26V9.22h-3.73ZM87.15,23.54h13.23V20.22H87.14V12.53h14.93V9.21H83.34V34.77h18.92V31.45H87.14ZM71.59,20.3h0C66.44,19.06,65,18.08,65,15.7c0-2.14,1.89-3.59,4.71-3.59a12.06,12.06,0,0,1,7.07,2.55l2-2.83a14.1,14.1,0,0,0-9-3c-5.06,0-8.59,3-8.59,7.27,0,4.6,3,6.19,8.46,7.52C74.51,24.74,76,25.78,76,28.11s-2,3.77-5.09,3.77a12.34,12.34,0,0,1-8.3-3.26l-2.25,2.69a15.94,15.94,0,0,0,10.42,3.85c5.48,0,9-2.95,9-7.51C79.75,23.79,77.47,21.72,71.59,20.3ZM195.7,9.22l-7.69,12-7.64-12h-4.46L186,24.67V34.78h3.84V24.55L200,9.22Zm-64.63,3.46h8.37v22.1h3.84V12.68h8.37V9.22H131.08ZM169.41,24.8c3.86-1.07,6-3.77,6-7.63,0-4.91-3.59-8-9.38-8H154.67V34.76h3.8V25.58h6.45l6.48,9.2h4.44l-7-9.82Zm-10.95-2.5V12.6h7.17c3.74,0,5.88,1.77,5.88,4.84s-2.29,4.86-5.84,4.86Z M29,2.26a4.67,4.67,0,0,0-8,0L14.42,13.53A32.21,32.21,0,0,1,32.17,40.19H27.55A27.68,27.68,0,0,0,12.09,17.47L6,28a15.92,15.92,0,0,1,9.23,12.17H4.62A.76.76,0,0,1,4,39.06l2.94-5a10.74,10.74,0,0,0-3.36-1.9l-2.91,5a4.54,4.54,0,0,0,1.69,6.24A4.66,4.66,0,0,0,4.62,44H19.15a19.4,19.4,0,0,0-8-17.31l2.31-4A23.87,23.87,0,0,1,23.76,44H36.07a35.88,35.88,0,0,0-16.41-31.8l4.67-8a.77.77,0,0,1,1.05-.27c.53.29,20.29,34.77,20.66,35.17a.76.76,0,0,1-.68,1.13H40.6q.09,1.91,0,3.81h4.78A4.59,4.59,0,0,0,50,39.43a4.49,4.49,0,0,0-.62-2.28Z\"\n ></path>\n </svg>\n </h1>\n\n <p>Get started by sending us a sample error:</p>\n <button\n type=\"button\"\n style={{\n padding: \"12px\",\n cursor: \"pointer\",\n backgroundColor: \"#AD6CAA\",\n borderRadius: \"4px\",\n border: \"none\",\n color: \"white\",\n fontSize: \"14px\",\n margin: \"18px\",\n }}\n onClick={async () => {\n const transaction = Sentry.startTransaction({\n name: \"Example Frontend Transaction\",\n });\n\n Sentry.configureScope((scope) => {\n scope.setSpan(transaction);\n });\n\n try {\n const res = await fetch(\"/api/sentry-example-api\");\n if (!res.ok) {\n throw new Error(\"Sentry Example Frontend Error\");\n }\n } finally {\n transaction.finish();\n }\n }}\n >\n Throw error!\n </button>\n\n <p>\n Next, look for the error on the{\" \"}\n <a href=\"${issuesPageLink}\">Issues Page</a>.\n </p>\n <p style={{ marginTop: \"24px\" }}>\n For more information, see{\" \"}\n <a href=\"https://docs.sentry.io/platforms/javascript/guides/nextjs/\">\n https://docs.sentry.io/platforms/javascript/guides/nextjs/\n </a>\n </p>\n </main>\n </div>\n );\n}\n`;\n}\n\nconst exampleApiRoute = `// A faulty API route to test Sentry's error monitoring\nexport default function handler(_req, res) {\n throw new Error(\"Sentry Example API Route Error\");\n res.status(200).json({ name: \"John Doe\" });\n}\n`;\n"]}
|
|
@@ -9,6 +9,7 @@ export function mergeConfigFile(
|
|
|
9
9
|
const templateFile = fs.readFileSync(templatePath, 'utf8');
|
|
10
10
|
const sourceFile = fs.readFileSync(sourcePath, 'utf8');
|
|
11
11
|
const newText = templateFile.replace('// ORIGINAL CONFIG', sourceFile);
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/no-implied-eval
|
|
12
13
|
Function(newText); // check if the file is valid javascript
|
|
13
14
|
fs.writeFileSync(sourcePath, newText);
|
|
14
15
|
return true;
|
package/lib/Steps/BaseStep.ts
CHANGED
|
@@ -4,7 +4,7 @@ import type { Args } from '../Constants';
|
|
|
4
4
|
import { debug, nl } from '../Helper/Logging';
|
|
5
5
|
|
|
6
6
|
export abstract class BaseStep implements IStep {
|
|
7
|
-
protected _isDebug
|
|
7
|
+
protected _isDebug = false;
|
|
8
8
|
public constructor(protected _argv: Args) {
|
|
9
9
|
this._isDebug = _argv.debug;
|
|
10
10
|
}
|
package/lib/Steps/Initial.ts
CHANGED
|
@@ -14,6 +14,7 @@ export abstract class BaseIntegration extends BaseStep {
|
|
|
14
14
|
this.type = this.construct;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
17
18
|
public async uninstall(_answers: Answers): Promise<Answers> {
|
|
18
19
|
return {};
|
|
19
20
|
}
|
|
@@ -24,6 +25,7 @@ export abstract class BaseIntegration extends BaseStep {
|
|
|
24
25
|
* Basically this will be merged into answers so it can be checked by a later step.
|
|
25
26
|
*/
|
|
26
27
|
public async shouldConfigure(_answers: Answers): Promise<Answers> {
|
|
28
|
+
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
27
29
|
if (this._shouldConfigure) {
|
|
28
30
|
return this._shouldConfigure;
|
|
29
31
|
}
|
|
@@ -12,7 +12,7 @@ const xcode = require('xcode');
|
|
|
12
12
|
|
|
13
13
|
export class Cordova extends BaseIntegration {
|
|
14
14
|
protected _sentryCli: SentryCli;
|
|
15
|
-
protected _folderPrefix
|
|
15
|
+
protected _folderPrefix = 'platforms';
|
|
16
16
|
protected _pluginFolder: string[] = ['.'];
|
|
17
17
|
|
|
18
18
|
public constructor(protected _argv: Args) {
|
|
@@ -50,6 +50,7 @@ export class Cordova extends BaseIntegration {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
public async shouldConfigure(_answers: Answers): Promise<Answers> {
|
|
53
|
+
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
53
54
|
if (this._shouldConfigure) {
|
|
54
55
|
return this._shouldConfigure;
|
|
55
56
|
}
|
|
@@ -24,7 +24,7 @@ Sentry.init({
|
|
|
24
24
|
|
|
25
25
|
let appPackage: any = {};
|
|
26
26
|
|
|
27
|
-
function printExample(example: string, title
|
|
27
|
+
function printExample(example: string, title = ''): void {
|
|
28
28
|
if (title) {
|
|
29
29
|
l(title);
|
|
30
30
|
}
|
|
@@ -48,6 +48,7 @@ export class Electron extends BaseIntegration {
|
|
|
48
48
|
this._sentryCli = new SentryCli(this._argv);
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
51
52
|
public async emit(answers: Answers): Promise<Answers> {
|
|
52
53
|
const dsn = _.get(answers, ['config', 'dsn', 'public'], null);
|
|
53
54
|
nl();
|
|
@@ -72,6 +73,7 @@ export class Electron extends BaseIntegration {
|
|
|
72
73
|
}
|
|
73
74
|
|
|
74
75
|
public async shouldConfigure(_answers: Answers): Promise<Answers> {
|
|
76
|
+
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
75
77
|
if (this._shouldConfigure) {
|
|
76
78
|
return this._shouldConfigure;
|
|
77
79
|
}
|
|
@@ -33,6 +33,7 @@ export abstract class MobileProject extends BaseIntegration {
|
|
|
33
33
|
: (await this._platformSelector()).platform;
|
|
34
34
|
|
|
35
35
|
const shouldConfigurePlatforms: any = {};
|
|
36
|
+
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
36
37
|
_.keys(Platform).forEach(async (platform: Platform) => {
|
|
37
38
|
shouldConfigurePlatforms[platform] =
|
|
38
39
|
_.indexOf(this._platforms, platform) >= 0
|
|
@@ -102,6 +102,7 @@ export class NextJs extends BaseIntegration {
|
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
public async shouldConfigure(_answers: Answers): Promise<Answers> {
|
|
105
|
+
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
105
106
|
if (this._shouldConfigure) {
|
|
106
107
|
return this._shouldConfigure;
|
|
107
108
|
}
|
|
@@ -35,7 +35,7 @@ export class ReactNative extends MobileProject {
|
|
|
35
35
|
/**
|
|
36
36
|
* All React Native versions have app/build.gradle with android section.
|
|
37
37
|
*/
|
|
38
|
-
private static _buildGradleAndroidSectionBeginning
|
|
38
|
+
private static _buildGradleAndroidSectionBeginning = /^android {/m;
|
|
39
39
|
|
|
40
40
|
protected _answers: Answers;
|
|
41
41
|
protected _sentryCli: SentryCli;
|
|
@@ -150,6 +150,7 @@ export class ReactNative extends MobileProject {
|
|
|
150
150
|
return {};
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
153
154
|
protected async _shouldConfigurePlatform(platform: string): Promise<boolean> {
|
|
154
155
|
let result = false;
|
|
155
156
|
|
|
@@ -340,7 +341,7 @@ export class ReactNative extends MobileProject {
|
|
|
340
341
|
}
|
|
341
342
|
let code = JSON.parse(script.shellScript);
|
|
342
343
|
code =
|
|
343
|
-
// eslint-disable-next-line prefer-template
|
|
344
|
+
// eslint-disable-next-line prefer-template, @typescript-eslint/restrict-plus-operands
|
|
344
345
|
'export SENTRY_PROPERTIES=sentry.properties\n' +
|
|
345
346
|
'export EXTRA_PACKAGER_ARGS="--sourcemap-output $DERIVED_FILE_DIR/main.jsbundle.map"\n' +
|
|
346
347
|
code.replace(
|
package/lib/Steps/Result.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { green, nl } from '../Helper/Logging';
|
|
|
4
4
|
import { BaseStep } from './BaseStep';
|
|
5
5
|
|
|
6
6
|
export class Result extends BaseStep {
|
|
7
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
7
8
|
public async emit(answers: Answers): Promise<Answers> {
|
|
8
9
|
this.debug(answers);
|
|
9
10
|
nl();
|
|
@@ -16,7 +16,7 @@ export class WaitForSentry extends BaseStep {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
// eslint-disable-next-line no-async-promise-executor
|
|
19
|
-
return new Promise(
|
|
19
|
+
return new Promise((resolve, _reject) => {
|
|
20
20
|
this.debug(answers);
|
|
21
21
|
|
|
22
22
|
BottomBar.show('Waiting for Sentry...');
|
package/lib/Steps/Welcome.ts
CHANGED
|
@@ -4,8 +4,9 @@ import { dim, green } from '../Helper/Logging';
|
|
|
4
4
|
import { BaseStep } from './BaseStep';
|
|
5
5
|
|
|
6
6
|
export class Welcome extends BaseStep {
|
|
7
|
-
private static _didShow
|
|
7
|
+
private static _didShow = false;
|
|
8
8
|
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
9
10
|
public async emit(_answers: Answers): Promise<Answers> {
|
|
10
11
|
if (Welcome._didShow) {
|
|
11
12
|
return {};
|