@sentry/wizard 1.2.12 → 1.2.16

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.
@@ -59,8 +59,16 @@ var __rest = (this && this.__rest) || function (s, e) {
59
59
  }
60
60
  return t;
61
61
  };
62
+ var __spreadArrays = (this && this.__spreadArrays) || function () {
63
+ for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
64
+ for (var r = Array(s), k = 0, i = 0; i < il; i++)
65
+ for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
66
+ r[k] = a[j];
67
+ return r;
68
+ };
62
69
  Object.defineProperty(exports, "__esModule", { value: true });
63
70
  exports.NextJs = void 0;
71
+ /* eslint-disable max-lines */
64
72
  var fs = require("fs");
65
73
  var inquirer_1 = require("inquirer");
66
74
  var _ = require("lodash");
@@ -69,12 +77,20 @@ var semver_1 = require("semver");
69
77
  var Logging_1 = require("../../Helper/Logging");
70
78
  var SentryCli_1 = require("../../Helper/SentryCli");
71
79
  var BaseIntegration_1 = require("./BaseIntegration");
72
- var MIN_NEXTJS_VERSION = '10.0.8'; // Must be a fixed version: `X.Y.Z`
80
+ var COMPATIBLE_NEXTJS_VERSIONS = '>=10.0.8 <12.0.0';
73
81
  var PROPERTIES_FILENAME = 'sentry.properties';
74
82
  var SENTRYCLIRC_FILENAME = '.sentryclirc';
75
83
  var GITIGNORE_FILENAME = '.gitignore';
76
84
  var CONFIG_DIR = 'configs/';
77
- var MERGEABLE_CONFIG_PREFIX = '_';
85
+ var MERGEABLE_CONFIG_INFIX = 'wizardcopy';
86
+ // for those files which can go in more than one place, the list of places they
87
+ // could go (the first one which works will be used)
88
+ var TEMPLATE_DESTINATIONS = {
89
+ '_error.js': ['pages', 'src/pages'],
90
+ 'next.config.js': ['.'],
91
+ 'sentry.server.config.js': ['.'],
92
+ 'sentry.client.config.js': ['.'],
93
+ };
78
94
  var appPackage = {};
79
95
  try {
80
96
  appPackage = require(path.join(process.cwd(), 'package.json'));
@@ -107,7 +123,7 @@ var NextJs = /** @class */ (function (_super) {
107
123
  this._createNextConfig(configDirectory, dsn);
108
124
  }
109
125
  else {
110
- Logging_1.debug("Couldn't find " + configDirectory + ", probably because you run from src");
126
+ Logging_1.debug("Couldn't find " + configDirectory + ", probably because you ran this from inside of `/lib` rather than `/dist`");
111
127
  Logging_1.nl();
112
128
  }
113
129
  Logging_1.l('For more information, see https://docs.sentry.io/platforms/javascript/guides/nextjs/');
@@ -128,7 +144,7 @@ var NextJs = /** @class */ (function (_super) {
128
144
  }
129
145
  Logging_1.nl();
130
146
  userAnswers = { continue: true };
131
- if (!(!this._checkDep('next', true) && !this._argv.quiet)) return [3 /*break*/, 2];
147
+ if (!(!this._checkUserNextVersion('next') && !this._argv.quiet)) return [3 /*break*/, 2];
132
148
  return [4 /*yield*/, inquirer_1.prompt({
133
149
  message: 'There were errors during your project checkup, do you still want to continue?',
134
150
  name: 'continue',
@@ -161,7 +177,7 @@ var NextJs = /** @class */ (function (_super) {
161
177
  _c.label = 1;
162
178
  case 1:
163
179
  _c.trys.push([1, 3, , 4]);
164
- return [4 /*yield*/, fs.promises.appendFile(SENTRYCLIRC_FILENAME, this._sentryCli.dumpProperties({ 'auth/token': authToken }))];
180
+ return [4 /*yield*/, fs.promises.appendFile(SENTRYCLIRC_FILENAME, this._sentryCli.dumpConfig({ auth: { token: authToken } }))];
165
181
  case 2:
166
182
  _c.sent();
167
183
  Logging_1.green("\u2713 Successfully added the auth token to " + SENTRYCLIRC_FILENAME);
@@ -228,78 +244,92 @@ var NextJs = /** @class */ (function (_super) {
228
244
  var templates = fs.readdirSync(configDirectory);
229
245
  for (var _i = 0, templates_1 = templates; _i < templates_1.length; _i++) {
230
246
  var template = templates_1[_i];
231
- this._setTemplate(configDirectory, template, dsn);
247
+ this._setTemplate(configDirectory, template, TEMPLATE_DESTINATIONS[template], dsn);
232
248
  }
233
249
  Logging_1.red('⚠ Performance monitoring is enabled capturing 100% of transactions.\n' +
234
250
  ' Learn more in https://docs.sentry.io/product/performance/');
235
251
  Logging_1.nl();
236
252
  };
237
- NextJs.prototype._setTemplate = function (configDirectory, template, dsn) {
238
- var templatePath = path.join(configDirectory, template);
239
- var mergeableFile = MERGEABLE_CONFIG_PREFIX + template;
240
- if (!fs.existsSync(template)) {
241
- this._fillAndCopyTemplate(templatePath, template, dsn);
242
- }
243
- else if (!fs.existsSync(mergeableFile)) {
244
- this._fillAndCopyTemplate(templatePath, mergeableFile, dsn);
245
- Logging_1.red("File " + template + " already exists, so created " + mergeableFile + ".\n" +
246
- "Please, merge those files.");
247
- Logging_1.nl();
248
- }
249
- else {
250
- Logging_1.red("File " + template + " already exists, and " + mergeableFile + " also exists.\n" +
251
- 'Please, merge those files.');
252
- Logging_1.nl();
253
+ NextJs.prototype._setTemplate = function (configDirectory, templateFile, destinationOptions, dsn) {
254
+ var templatePath = path.join(configDirectory, templateFile);
255
+ for (var _i = 0, destinationOptions_1 = destinationOptions; _i < destinationOptions_1.length; _i++) {
256
+ var destinationDir = destinationOptions_1[_i];
257
+ if (!fs.existsSync(destinationDir)) {
258
+ continue;
259
+ }
260
+ var destinationPath = path.join(destinationDir, templateFile);
261
+ // in case the file in question already exists, we'll make a copy with
262
+ // `MERGEABLE_CONFIG_INFIX` inserted just before the extension, so as not
263
+ // to overwrite the existing file
264
+ var mergeableFilePath = path.join(destinationDir, this._spliceInPlace(templateFile.split('.'), -1, 0, MERGEABLE_CONFIG_INFIX).join('.'));
265
+ if (!fs.existsSync(destinationPath)) {
266
+ this._fillAndCopyTemplate(templatePath, destinationPath, dsn);
267
+ }
268
+ else if (!fs.existsSync(mergeableFilePath)) {
269
+ this._fillAndCopyTemplate(templatePath, mergeableFilePath, dsn);
270
+ Logging_1.red("File `" + templateFile + "` already exists, so created `" + mergeableFilePath + "`.\n" +
271
+ 'Please merge those files.');
272
+ Logging_1.nl();
273
+ }
274
+ else {
275
+ Logging_1.red("Both `" + templateFile + "` and `" + mergeableFilePath + "` already exist.\n" +
276
+ 'Please merge those files.');
277
+ Logging_1.nl();
278
+ }
279
+ return;
253
280
  }
281
+ Logging_1.red("Could not find appropriate destination for `" + templateFile + "`. Tried: " + destinationOptions + ".");
282
+ Logging_1.nl();
254
283
  };
255
284
  NextJs.prototype._fillAndCopyTemplate = function (sourcePath, targetPath, dsn) {
256
285
  var templateContent = fs.readFileSync(sourcePath).toString();
257
286
  var filledTemplate = templateContent.replace('___DSN___', dsn);
258
287
  fs.writeFileSync(targetPath, filledTemplate);
259
288
  };
260
- NextJs.prototype._checkDep = function (packageName, minVersion) {
261
- var depVersion = _.get(appPackage, ['dependencies', packageName], '0.0.0');
262
- var devDepVersion = _.get(appPackage, ['devDependencies', packageName], '0.0.0');
263
- if (!_.get(appPackage, "dependencies." + packageName, false) &&
264
- !_.get(appPackage, "devDependencies." + packageName, false)) {
265
- Logging_1.red("\u2717 " + packageName + " isn't in your dependencies");
266
- Logging_1.red(" please install it with yarn/npm");
289
+ NextJs.prototype._checkUserNextVersion = function (packageName) {
290
+ var depsVersion = _.get(appPackage, ['dependencies', packageName]);
291
+ var devDepsVersion = _.get(appPackage, ['devDependencies', packageName]);
292
+ if (!depsVersion && !devDepsVersion) {
293
+ Logging_1.red("\u2717 " + packageName + " isn't in your dependencies.");
294
+ Logging_1.red(' Please install it with yarn/npm.');
267
295
  return false;
268
296
  }
269
- else if (!this._fulfillsMinVersion(depVersion) &&
270
- !this._fulfillsMinVersion(devDepVersion)) {
271
- Logging_1.red("\u2717 Your installed version of `" + packageName + "` is not supported, >=" + MIN_NEXTJS_VERSION + " needed.");
297
+ else if (!this._fulfillsVersionRange(depsVersion) &&
298
+ !this._fulfillsVersionRange(devDepsVersion)) {
299
+ Logging_1.red("\u2717 Your `package.json` specifies a version of `" + packageName + "` outside of the compatible version range " + COMPATIBLE_NEXTJS_VERSIONS + ".\n");
272
300
  return false;
273
301
  }
274
302
  else {
275
- if (minVersion) {
276
- Logging_1.green("\u2713 " + packageName + " >= " + MIN_NEXTJS_VERSION + " is installed");
277
- }
278
- else {
279
- Logging_1.green("\u2713 " + packageName + " is installed");
280
- }
303
+ Logging_1.green("\u2713 A compatible version of `" + packageName + "` is specified in `package.json`.");
281
304
  return true;
282
305
  }
283
306
  };
284
- NextJs.prototype._fulfillsMinVersion = function (version) {
285
- // The latest version, which at the moment is greater than the minimum
286
- // version, shouldn't be a blocker in the wizard.
307
+ NextJs.prototype._fulfillsVersionRange = function (version) {
308
+ // The latest version is currently 12.x, which is not yet supported.
287
309
  if (version === 'latest') {
288
- return true;
310
+ return false;
289
311
  }
290
- var cleanedVersion = semver_1.clean(version);
291
- if (cleanedVersion) {
292
- // gte(x, y) : true if x >= y
293
- return semver_1.gte(cleanedVersion, MIN_NEXTJS_VERSION);
312
+ var cleanedUserVersion, isRange;
313
+ if (semver_1.valid(version)) {
314
+ cleanedUserVersion = semver_1.valid(version);
315
+ isRange = false;
294
316
  }
295
- var minVersionRange = ">=" + MIN_NEXTJS_VERSION;
296
- var userVersionRange = semver_1.validRange(version);
297
- var minUserVersion = semver_1.minVersion(userVersionRange);
298
- if (minUserVersion == null) {
299
- // This should never happen
300
- return false;
317
+ else if (semver_1.validRange(version)) {
318
+ cleanedUserVersion = semver_1.validRange(version);
319
+ isRange = true;
320
+ }
321
+ return (!!cleanedUserVersion &&
322
+ (isRange
323
+ ? semver_1.subset(cleanedUserVersion, COMPATIBLE_NEXTJS_VERSIONS)
324
+ : semver_1.satisfies(cleanedUserVersion, COMPATIBLE_NEXTJS_VERSIONS)));
325
+ };
326
+ NextJs.prototype._spliceInPlace = function (arr, start, deleteCount) {
327
+ var inserts = [];
328
+ for (var _i = 3; _i < arguments.length; _i++) {
329
+ inserts[_i - 3] = arguments[_i];
301
330
  }
302
- return semver_1.satisfies(minUserVersion, minVersionRange);
331
+ arr.splice.apply(arr, __spreadArrays([start, deleteCount], inserts));
332
+ return arr;
303
333
  };
304
334
  return NextJs;
305
335
  }(BaseIntegration_1.BaseIntegration));
@@ -1 +1 @@
1
- {"version":3,"file":"NextJs.js","sourceRoot":"","sources":["../../../../lib/Steps/Integrations/NextJs.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'fs';\nimport { Answers, prompt } from 'inquirer';\nimport * as _ from 'lodash';\nimport * as path from 'path';\nimport { clean, gte, minVersion, satisfies, validRange } from 'semver';\n\nimport { Args } from '../../Constants';\nimport { debug, green, l, nl, red } from '../../Helper/Logging';\nimport { SentryCli, SentryCliProps } from '../../Helper/SentryCli';\nimport { BaseIntegration } from './BaseIntegration';\n\nconst MIN_NEXTJS_VERSION = '10.0.8'; // Must be a fixed version: `X.Y.Z`\nconst PROPERTIES_FILENAME = 'sentry.properties';\nconst SENTRYCLIRC_FILENAME = '.sentryclirc';\nconst GITIGNORE_FILENAME = '.gitignore';\nconst CONFIG_DIR = 'configs/';\nconst MERGEABLE_CONFIG_PREFIX = '_';\n\nlet appPackage: any = {};\n\ntry {\n appPackage = require(path.join(process.cwd(), 'package.json'));\n} catch {\n // We don't need to have this\n}\n\nexport class NextJs extends BaseIntegration {\n protected _sentryCli: SentryCli;\n\n constructor(protected _argv: Args) {\n super(_argv);\n this._sentryCli = new SentryCli(this._argv);\n }\n\n public async emit(answers: Answers): Promise<Answers> {\n const dsn = _.get(answers, ['config', 'dsn', 'public'], null);\n nl();\n\n const sentryCliProps = this._sentryCli.convertAnswersToProperties(answers);\n await this._createSentryCliConfig(sentryCliProps);\n\n const configDirectory = path.join(\n __dirname,\n '..',\n '..',\n '..',\n 'NextJs',\n CONFIG_DIR,\n );\n\n if (fs.existsSync(configDirectory)) {\n this._createNextConfig(configDirectory, dsn);\n } else {\n debug(\n `Couldn't find ${configDirectory}, probably because you run from src`,\n );\n nl();\n }\n\n l(\n 'For more information, see https://docs.sentry.io/platforms/javascript/guides/nextjs/',\n );\n nl();\n\n return {};\n }\n\n public async shouldConfigure(_answers: Answers): Promise<Answers> {\n if (this._shouldConfigure) {\n return this._shouldConfigure;\n }\n\n nl();\n\n let userAnswers: Answers = { continue: true };\n if (!this._checkDep('next', true) && !this._argv.quiet) {\n userAnswers = await prompt({\n message:\n 'There were errors during your project checkup, do you still want to continue?',\n name: 'continue',\n default: false,\n type: 'confirm',\n });\n }\n\n nl();\n\n if (!userAnswers['continue']) {\n throw new Error('Please install the required dependencies to continue.');\n }\n\n this._shouldConfigure = Promise.resolve({ nextjs: true });\n // eslint-disable-next-line @typescript-eslint/unbound-method\n return this.shouldConfigure;\n }\n\n private async _createSentryCliConfig(\n cliProps: SentryCliProps,\n ): Promise<void> {\n const { 'auth/token': authToken, ...cliPropsToWrite } = cliProps;\n\n /**\n * To not commit the auth token to the VCS, instead of adding it to the\n * properties file (like the rest of props), it's added to the Sentry CLI\n * config, which is added to the gitignore. This way makes the properties\n * file safe to commit without exposing any auth tokens.\n */\n if (authToken) {\n try {\n await fs.promises.appendFile(\n SENTRYCLIRC_FILENAME,\n this._sentryCli.dumpProperties({ 'auth/token': authToken }),\n );\n green(`✓ Successfully added the auth token to ${SENTRYCLIRC_FILENAME}`);\n } catch {\n red(\n `⚠ Could not add the auth token to ${SENTRYCLIRC_FILENAME}, ` +\n `please add it to identify your user account:\\n${authToken}`,\n );\n nl();\n }\n } else {\n red(\n `⚠ Did not find an auth token, please add your token to ${SENTRYCLIRC_FILENAME}`,\n );\n l(\n 'To generate an auth token, visit https://sentry.io/settings/account/api/auth-tokens/',\n );\n l(\n 'To learn how to configure Sentry CLI, visit ' +\n 'https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#configure-sentry-cli',\n );\n }\n\n await this._addToGitignore(\n SENTRYCLIRC_FILENAME,\n `⚠ Could not add ${SENTRYCLIRC_FILENAME} to ${GITIGNORE_FILENAME}, ` +\n 'please add it to not commit your auth key.',\n );\n\n try {\n await fs.promises.writeFile(\n `./${PROPERTIES_FILENAME}`,\n this._sentryCli.dumpProperties(cliPropsToWrite),\n );\n green(`✓ Successfully created sentry.properties`);\n } catch {\n red(`⚠ Could not add org and project data to ${PROPERTIES_FILENAME}`);\n l(\n 'See docs for a manual setup: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#configure-sentry-cli',\n );\n }\n nl();\n }\n\n private async _addToGitignore(\n filepath: string,\n errorMsg: string,\n ): Promise<void> {\n /**\n * Don't check whether the given file is ignored because:\n * 1. It's tricky to check it without git.\n * 2. Git might not be installed or accessible.\n * 3. It's convenient to use a module to interact with git, but it would\n * increase the size x2 approximately. Docs say to run the Wizard without\n * installing it, and duplicating the size would slow the set-up down.\n * 4. The Wizard is meant to be run once.\n * 5. A message is logged informing users it's been added to the gitignore.\n * 6. It will be added to the gitignore as many times as it runs - not a big\n * deal.\n * 7. It's straightforward to remove it from the gitignore.\n */\n try {\n await fs.promises.appendFile(\n GITIGNORE_FILENAME,\n `\\n# Sentry\\n${filepath}\\n`,\n );\n green(`✓ ${filepath} added to ${GITIGNORE_FILENAME}`);\n } catch {\n red(errorMsg);\n }\n }\n\n private _createNextConfig(configDirectory: string, dsn: any): void {\n const templates = fs.readdirSync(configDirectory);\n for (const template of templates) {\n this._setTemplate(configDirectory, template, dsn);\n }\n red(\n '⚠ Performance monitoring is enabled capturing 100% of transactions.\\n' +\n ' Learn more in https://docs.sentry.io/product/performance/',\n );\n nl();\n }\n\n private _setTemplate(\n configDirectory: string,\n template: string,\n dsn: string,\n ): void {\n const templatePath = path.join(configDirectory, template);\n const mergeableFile = MERGEABLE_CONFIG_PREFIX + template;\n if (!fs.existsSync(template)) {\n this._fillAndCopyTemplate(templatePath, template, dsn);\n } else if (!fs.existsSync(mergeableFile)) {\n this._fillAndCopyTemplate(templatePath, mergeableFile, dsn);\n red(\n `File ${template} already exists, so created ${mergeableFile}.\\n` +\n `Please, merge those files.`,\n );\n nl();\n } else {\n red(\n `File ${template} already exists, and ${mergeableFile} also exists.\\n` +\n 'Please, merge those files.',\n );\n nl();\n }\n }\n\n private _fillAndCopyTemplate(\n sourcePath: string,\n targetPath: string,\n dsn: string,\n ): void {\n const templateContent = fs.readFileSync(sourcePath).toString();\n const filledTemplate = templateContent.replace('___DSN___', dsn);\n fs.writeFileSync(targetPath, filledTemplate);\n }\n\n private _checkDep(packageName: string, minVersion?: boolean): boolean {\n const depVersion = _.get(\n appPackage,\n ['dependencies', packageName],\n '0.0.0',\n );\n const devDepVersion = _.get(\n appPackage,\n ['devDependencies', packageName],\n '0.0.0',\n );\n\n if (\n !_.get(appPackage, `dependencies.${packageName}`, false) &&\n !_.get(appPackage, `devDependencies.${packageName}`, false)\n ) {\n red(`✗ ${packageName} isn't in your dependencies`);\n red(` please install it with yarn/npm`);\n return false;\n } else if (\n !this._fulfillsMinVersion(depVersion) &&\n !this._fulfillsMinVersion(devDepVersion)\n ) {\n red(\n `✗ Your installed version of \\`${packageName}\\` is not supported, >=${MIN_NEXTJS_VERSION} needed.`,\n );\n return false;\n } else {\n if (minVersion) {\n green(`✓ ${packageName} >= ${MIN_NEXTJS_VERSION} is installed`);\n } else {\n green(`✓ ${packageName} is installed`);\n }\n return true;\n }\n }\n\n private _fulfillsMinVersion(version: string): boolean {\n // The latest version, which at the moment is greater than the minimum\n // version, shouldn't be a blocker in the wizard.\n if (version === 'latest') {\n return true;\n }\n\n const cleanedVersion = clean(version);\n if (cleanedVersion) {\n // gte(x, y) : true if x >= y\n return gte(cleanedVersion, MIN_NEXTJS_VERSION);\n }\n\n const minVersionRange = `>=${MIN_NEXTJS_VERSION}`;\n const userVersionRange = validRange(version);\n const minUserVersion = minVersion(userVersionRange);\n if (minUserVersion == null) {\n // This should never happen\n return false;\n }\n return satisfies(minUserVersion, minVersionRange);\n }\n}\n"]}
1
+ {"version":3,"file":"NextJs.js","sourceRoot":"","sources":["../../../../lib/Steps/Integrations/NextJs.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable max-lines */\nimport * as fs from 'fs';\nimport { Answers, prompt } from 'inquirer';\nimport * as _ from 'lodash';\nimport * as path from 'path';\nimport { satisfies, subset, valid, validRange } from 'semver';\n\nimport { Args } from '../../Constants';\nimport { debug, green, l, nl, red } from '../../Helper/Logging';\nimport { SentryCli, SentryCliProps } from '../../Helper/SentryCli';\nimport { BaseIntegration } from './BaseIntegration';\n\nconst COMPATIBLE_NEXTJS_VERSIONS = '>=10.0.8 <12.0.0';\nconst PROPERTIES_FILENAME = 'sentry.properties';\nconst SENTRYCLIRC_FILENAME = '.sentryclirc';\nconst GITIGNORE_FILENAME = '.gitignore';\nconst CONFIG_DIR = 'configs/';\nconst MERGEABLE_CONFIG_INFIX = 'wizardcopy';\n\n// for those files which can go in more than one place, the list of places they\n// could go (the first one which works will be used)\nconst TEMPLATE_DESTINATIONS: { [key: string]: string[] } = {\n '_error.js': ['pages', 'src/pages'],\n 'next.config.js': ['.'],\n 'sentry.server.config.js': ['.'],\n 'sentry.client.config.js': ['.'],\n};\n\nlet appPackage: any = {};\n\ntry {\n appPackage = require(path.join(process.cwd(), 'package.json'));\n} catch {\n // We don't need to have this\n}\n\nexport class NextJs extends BaseIntegration {\n protected _sentryCli: SentryCli;\n\n constructor(protected _argv: Args) {\n super(_argv);\n this._sentryCli = new SentryCli(this._argv);\n }\n\n public async emit(answers: Answers): Promise<Answers> {\n const dsn = _.get(answers, ['config', 'dsn', 'public'], null);\n nl();\n\n const sentryCliProps = this._sentryCli.convertAnswersToProperties(answers);\n await this._createSentryCliConfig(sentryCliProps);\n\n const configDirectory = path.join(\n __dirname,\n '..',\n '..',\n '..',\n 'NextJs',\n CONFIG_DIR,\n );\n\n if (fs.existsSync(configDirectory)) {\n this._createNextConfig(configDirectory, dsn);\n } else {\n debug(\n `Couldn't find ${configDirectory}, probably because you ran this from inside of \\`/lib\\` rather than \\`/dist\\``,\n );\n nl();\n }\n\n l(\n 'For more information, see https://docs.sentry.io/platforms/javascript/guides/nextjs/',\n );\n nl();\n\n return {};\n }\n\n public async shouldConfigure(_answers: Answers): Promise<Answers> {\n if (this._shouldConfigure) {\n return this._shouldConfigure;\n }\n\n nl();\n\n let userAnswers: Answers = { continue: true };\n if (!this._checkUserNextVersion('next') && !this._argv.quiet) {\n userAnswers = await prompt({\n message:\n 'There were errors during your project checkup, do you still want to continue?',\n name: 'continue',\n default: false,\n type: 'confirm',\n });\n }\n\n nl();\n\n if (!userAnswers['continue']) {\n throw new Error('Please install the required dependencies to continue.');\n }\n\n this._shouldConfigure = Promise.resolve({ nextjs: true });\n // eslint-disable-next-line @typescript-eslint/unbound-method\n return this.shouldConfigure;\n }\n\n private async _createSentryCliConfig(\n cliProps: SentryCliProps,\n ): Promise<void> {\n const { 'auth/token': authToken, ...cliPropsToWrite } = cliProps;\n\n /**\n * To not commit the auth token to the VCS, instead of adding it to the\n * properties file (like the rest of props), it's added to the Sentry CLI\n * config, which is added to the gitignore. This way makes the properties\n * file safe to commit without exposing any auth tokens.\n */\n if (authToken) {\n try {\n await fs.promises.appendFile(\n SENTRYCLIRC_FILENAME,\n this._sentryCli.dumpConfig({ auth: { token: authToken } }),\n );\n green(`✓ Successfully added the auth token to ${SENTRYCLIRC_FILENAME}`);\n } catch {\n red(\n `⚠ Could not add the auth token to ${SENTRYCLIRC_FILENAME}, ` +\n `please add it to identify your user account:\\n${authToken}`,\n );\n nl();\n }\n } else {\n red(\n `⚠ Did not find an auth token, please add your token to ${SENTRYCLIRC_FILENAME}`,\n );\n l(\n 'To generate an auth token, visit https://sentry.io/settings/account/api/auth-tokens/',\n );\n l(\n 'To learn how to configure Sentry CLI, visit ' +\n 'https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#configure-sentry-cli',\n );\n }\n\n await this._addToGitignore(\n SENTRYCLIRC_FILENAME,\n `⚠ Could not add ${SENTRYCLIRC_FILENAME} to ${GITIGNORE_FILENAME}, ` +\n 'please add it to not commit your auth key.',\n );\n\n try {\n await fs.promises.writeFile(\n `./${PROPERTIES_FILENAME}`,\n this._sentryCli.dumpProperties(cliPropsToWrite),\n );\n green(`✓ Successfully created sentry.properties`);\n } catch {\n red(`⚠ Could not add org and project data to ${PROPERTIES_FILENAME}`);\n l(\n 'See docs for a manual setup: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#configure-sentry-cli',\n );\n }\n nl();\n }\n\n private async _addToGitignore(\n filepath: string,\n errorMsg: string,\n ): Promise<void> {\n /**\n * Don't check whether the given file is ignored because:\n * 1. It's tricky to check it without git.\n * 2. Git might not be installed or accessible.\n * 3. It's convenient to use a module to interact with git, but it would\n * increase the size x2 approximately. Docs say to run the Wizard without\n * installing it, and duplicating the size would slow the set-up down.\n * 4. The Wizard is meant to be run once.\n * 5. A message is logged informing users it's been added to the gitignore.\n * 6. It will be added to the gitignore as many times as it runs - not a big\n * deal.\n * 7. It's straightforward to remove it from the gitignore.\n */\n try {\n await fs.promises.appendFile(\n GITIGNORE_FILENAME,\n `\\n# Sentry\\n${filepath}\\n`,\n );\n green(`✓ ${filepath} added to ${GITIGNORE_FILENAME}`);\n } catch {\n red(errorMsg);\n }\n }\n\n private _createNextConfig(configDirectory: string, dsn: any): void {\n const templates = fs.readdirSync(configDirectory);\n for (const template of templates) {\n this._setTemplate(\n configDirectory,\n template,\n TEMPLATE_DESTINATIONS[template],\n dsn,\n );\n }\n red(\n '⚠ Performance monitoring is enabled capturing 100% of transactions.\\n' +\n ' Learn more in https://docs.sentry.io/product/performance/',\n );\n nl();\n }\n\n private _setTemplate(\n configDirectory: string,\n templateFile: string,\n destinationOptions: string[],\n dsn: string,\n ): void {\n const templatePath = path.join(configDirectory, templateFile);\n\n for (const destinationDir of destinationOptions) {\n if (!fs.existsSync(destinationDir)) {\n continue;\n }\n\n const destinationPath = path.join(destinationDir, templateFile);\n // in case the file in question already exists, we'll make a copy with\n // `MERGEABLE_CONFIG_INFIX` inserted just before the extension, so as not\n // to overwrite the existing file\n const mergeableFilePath = path.join(\n destinationDir,\n this._spliceInPlace(\n templateFile.split('.'),\n -1,\n 0,\n MERGEABLE_CONFIG_INFIX,\n ).join('.'),\n );\n\n if (!fs.existsSync(destinationPath)) {\n this._fillAndCopyTemplate(templatePath, destinationPath, dsn);\n } else if (!fs.existsSync(mergeableFilePath)) {\n this._fillAndCopyTemplate(templatePath, mergeableFilePath, dsn);\n red(\n `File \\`${templateFile}\\` already exists, so created \\`${mergeableFilePath}\\`.\\n` +\n 'Please merge those files.',\n );\n nl();\n } else {\n red(\n `Both \\`${templateFile}\\` and \\`${mergeableFilePath}\\` already exist.\\n` +\n 'Please merge those files.',\n );\n nl();\n }\n return;\n }\n\n red(\n `Could not find appropriate destination for \\`${templateFile}\\`. Tried: ${destinationOptions}.`,\n );\n nl();\n }\n\n private _fillAndCopyTemplate(\n sourcePath: string,\n targetPath: string,\n dsn: string,\n ): void {\n const templateContent = fs.readFileSync(sourcePath).toString();\n const filledTemplate = templateContent.replace('___DSN___', dsn);\n fs.writeFileSync(targetPath, filledTemplate);\n }\n\n private _checkUserNextVersion(packageName: string): boolean {\n const depsVersion = _.get(appPackage, ['dependencies', packageName]);\n const devDepsVersion = _.get(appPackage, ['devDependencies', packageName]);\n\n if (!depsVersion && !devDepsVersion) {\n red(`✗ ${packageName} isn't in your dependencies.`);\n red(' Please install it with yarn/npm.');\n return false;\n } else if (\n !this._fulfillsVersionRange(depsVersion) &&\n !this._fulfillsVersionRange(devDepsVersion)\n ) {\n red(\n `✗ Your \\`package.json\\` specifies a version of \\`${packageName}\\` outside of the compatible version range ${COMPATIBLE_NEXTJS_VERSIONS}.\\n`,\n );\n return false;\n } else {\n green(\n `✓ A compatible version of \\`${packageName}\\` is specified in \\`package.json\\`.`,\n );\n return true;\n }\n }\n\n private _fulfillsVersionRange(version: string): boolean {\n // The latest version is currently 12.x, which is not yet supported.\n if (version === 'latest') {\n return false;\n }\n\n let cleanedUserVersion, isRange;\n\n if (valid(version)) {\n cleanedUserVersion = valid(version);\n isRange = false;\n } else if (validRange(version)) {\n cleanedUserVersion = validRange(version);\n isRange = true;\n }\n\n return (\n !!cleanedUserVersion &&\n (isRange\n ? subset(cleanedUserVersion, COMPATIBLE_NEXTJS_VERSIONS)\n : satisfies(cleanedUserVersion, COMPATIBLE_NEXTJS_VERSIONS))\n );\n }\n\n private _spliceInPlace(\n arr: Array<any>,\n start: number,\n deleteCount: number,\n ...inserts: any[]\n ): Array<any> {\n arr.splice(start, deleteCount, ...inserts);\n return arr;\n }\n}\n"]}
@@ -8,6 +8,8 @@ export interface SentryCliProps {
8
8
  [s: string]: string;
9
9
  }
10
10
 
11
+ type SentryCliConfig = Record<string, SentryCliProps>;
12
+
11
13
  export class SentryCli {
12
14
  // eslint-disable-next-line @typescript-eslint/typedef
13
15
  private _resolve = require.resolve;
@@ -35,6 +37,7 @@ export class SentryCli {
35
37
  return props;
36
38
  }
37
39
 
40
+ /** Create the contents of a `sentry.properties` file */
38
41
  public dumpProperties(props: SentryCliProps): string {
39
42
  const rv = [];
40
43
  for (let key in props) {
@@ -43,6 +46,7 @@ export class SentryCli {
43
46
  const value = props[key];
44
47
  key = key.replace(/\//g, '.');
45
48
  if (value === undefined || value === null) {
49
+ // comment that property out since it has no value
46
50
  rv.push(`#${key}=`);
47
51
  } else {
48
52
  rv.push(`${key}=${value}`);
@@ -52,4 +56,17 @@ export class SentryCli {
52
56
  // eslint-disable-next-line prefer-template
53
57
  return rv.join('\n') + '\n';
54
58
  }
59
+
60
+ public dumpConfig(config: SentryCliConfig): string {
61
+ const dumpedSections: string[] = [];
62
+ for (const sectionName in config) {
63
+ // eslint-disable-next-line no-prototype-builtins
64
+ if (config.hasOwnProperty(sectionName)) {
65
+ const props = this.dumpProperties(config[sectionName]);
66
+ const section = `[${sectionName}]\n${props}`;
67
+ dumpedSections.push(section);
68
+ }
69
+ }
70
+ return dumpedSections.join('\n');
71
+ }
55
72
  }
@@ -21,7 +21,7 @@ export abstract class BaseIntegration extends BaseStep {
21
21
  /**
22
22
  * This can be used for example for platform:boolean to determine
23
23
  * if we should configure iOS/Android.
24
- * Basically this will be merged into answers so it can be check by a later step.
24
+ * Basically this will be merged into answers so it can be checked by a later step.
25
25
  */
26
26
  public async shouldConfigure(_answers: Answers): Promise<Answers> {
27
27
  if (this._shouldConfigure) {
@@ -34,7 +34,10 @@ export abstract class BaseIntegration extends BaseStep {
34
34
  public async shouldEmit(_answers: Answers): Promise<boolean> {
35
35
  return (
36
36
  _.keys(
37
- _.pickBy(await this.shouldConfigure(_answers), (active: boolean) => active),
37
+ _.pickBy(
38
+ await this.shouldConfigure(_answers),
39
+ (active: boolean) => active,
40
+ ),
38
41
  ).length > 0
39
42
  );
40
43
  }
@@ -1,20 +1,30 @@
1
+ /* eslint-disable max-lines */
1
2
  import * as fs from 'fs';
2
3
  import { Answers, prompt } from 'inquirer';
3
4
  import * as _ from 'lodash';
4
5
  import * as path from 'path';
5
- import { clean, gte, minVersion, satisfies, validRange } from 'semver';
6
+ import { satisfies, subset, valid, validRange } from 'semver';
6
7
 
7
8
  import { Args } from '../../Constants';
8
9
  import { debug, green, l, nl, red } from '../../Helper/Logging';
9
10
  import { SentryCli, SentryCliProps } from '../../Helper/SentryCli';
10
11
  import { BaseIntegration } from './BaseIntegration';
11
12
 
12
- const MIN_NEXTJS_VERSION = '10.0.8'; // Must be a fixed version: `X.Y.Z`
13
+ const COMPATIBLE_NEXTJS_VERSIONS = '>=10.0.8 <12.0.0';
13
14
  const PROPERTIES_FILENAME = 'sentry.properties';
14
15
  const SENTRYCLIRC_FILENAME = '.sentryclirc';
15
16
  const GITIGNORE_FILENAME = '.gitignore';
16
17
  const CONFIG_DIR = 'configs/';
17
- const MERGEABLE_CONFIG_PREFIX = '_';
18
+ const MERGEABLE_CONFIG_INFIX = 'wizardcopy';
19
+
20
+ // for those files which can go in more than one place, the list of places they
21
+ // could go (the first one which works will be used)
22
+ const TEMPLATE_DESTINATIONS: { [key: string]: string[] } = {
23
+ '_error.js': ['pages', 'src/pages'],
24
+ 'next.config.js': ['.'],
25
+ 'sentry.server.config.js': ['.'],
26
+ 'sentry.client.config.js': ['.'],
27
+ };
18
28
 
19
29
  let appPackage: any = {};
20
30
 
@@ -52,7 +62,7 @@ export class NextJs extends BaseIntegration {
52
62
  this._createNextConfig(configDirectory, dsn);
53
63
  } else {
54
64
  debug(
55
- `Couldn't find ${configDirectory}, probably because you run from src`,
65
+ `Couldn't find ${configDirectory}, probably because you ran this from inside of \`/lib\` rather than \`/dist\``,
56
66
  );
57
67
  nl();
58
68
  }
@@ -73,7 +83,7 @@ export class NextJs extends BaseIntegration {
73
83
  nl();
74
84
 
75
85
  let userAnswers: Answers = { continue: true };
76
- if (!this._checkDep('next', true) && !this._argv.quiet) {
86
+ if (!this._checkUserNextVersion('next') && !this._argv.quiet) {
77
87
  userAnswers = await prompt({
78
88
  message:
79
89
  'There were errors during your project checkup, do you still want to continue?',
@@ -109,7 +119,7 @@ export class NextJs extends BaseIntegration {
109
119
  try {
110
120
  await fs.promises.appendFile(
111
121
  SENTRYCLIRC_FILENAME,
112
- this._sentryCli.dumpProperties({ 'auth/token': authToken }),
122
+ this._sentryCli.dumpConfig({ auth: { token: authToken } }),
113
123
  );
114
124
  green(`✓ Successfully added the auth token to ${SENTRYCLIRC_FILENAME}`);
115
125
  } catch {
@@ -184,7 +194,12 @@ export class NextJs extends BaseIntegration {
184
194
  private _createNextConfig(configDirectory: string, dsn: any): void {
185
195
  const templates = fs.readdirSync(configDirectory);
186
196
  for (const template of templates) {
187
- this._setTemplate(configDirectory, template, dsn);
197
+ this._setTemplate(
198
+ configDirectory,
199
+ template,
200
+ TEMPLATE_DESTINATIONS[template],
201
+ dsn,
202
+ );
188
203
  }
189
204
  red(
190
205
  '⚠ Performance monitoring is enabled capturing 100% of transactions.\n' +
@@ -195,27 +210,54 @@ export class NextJs extends BaseIntegration {
195
210
 
196
211
  private _setTemplate(
197
212
  configDirectory: string,
198
- template: string,
213
+ templateFile: string,
214
+ destinationOptions: string[],
199
215
  dsn: string,
200
216
  ): void {
201
- const templatePath = path.join(configDirectory, template);
202
- const mergeableFile = MERGEABLE_CONFIG_PREFIX + template;
203
- if (!fs.existsSync(template)) {
204
- this._fillAndCopyTemplate(templatePath, template, dsn);
205
- } else if (!fs.existsSync(mergeableFile)) {
206
- this._fillAndCopyTemplate(templatePath, mergeableFile, dsn);
207
- red(
208
- `File ${template} already exists, so created ${mergeableFile}.\n` +
209
- `Please, merge those files.`,
210
- );
211
- nl();
212
- } else {
213
- red(
214
- `File ${template} already exists, and ${mergeableFile} also exists.\n` +
215
- 'Please, merge those files.',
217
+ const templatePath = path.join(configDirectory, templateFile);
218
+
219
+ for (const destinationDir of destinationOptions) {
220
+ if (!fs.existsSync(destinationDir)) {
221
+ continue;
222
+ }
223
+
224
+ const destinationPath = path.join(destinationDir, templateFile);
225
+ // in case the file in question already exists, we'll make a copy with
226
+ // `MERGEABLE_CONFIG_INFIX` inserted just before the extension, so as not
227
+ // to overwrite the existing file
228
+ const mergeableFilePath = path.join(
229
+ destinationDir,
230
+ this._spliceInPlace(
231
+ templateFile.split('.'),
232
+ -1,
233
+ 0,
234
+ MERGEABLE_CONFIG_INFIX,
235
+ ).join('.'),
216
236
  );
217
- nl();
237
+
238
+ if (!fs.existsSync(destinationPath)) {
239
+ this._fillAndCopyTemplate(templatePath, destinationPath, dsn);
240
+ } else if (!fs.existsSync(mergeableFilePath)) {
241
+ this._fillAndCopyTemplate(templatePath, mergeableFilePath, dsn);
242
+ red(
243
+ `File \`${templateFile}\` already exists, so created \`${mergeableFilePath}\`.\n` +
244
+ 'Please merge those files.',
245
+ );
246
+ nl();
247
+ } else {
248
+ red(
249
+ `Both \`${templateFile}\` and \`${mergeableFilePath}\` already exist.\n` +
250
+ 'Please merge those files.',
251
+ );
252
+ nl();
253
+ }
254
+ return;
218
255
  }
256
+
257
+ red(
258
+ `Could not find appropriate destination for \`${templateFile}\`. Tried: ${destinationOptions}.`,
259
+ );
260
+ nl();
219
261
  }
220
262
 
221
263
  private _fillAndCopyTemplate(
@@ -228,63 +270,61 @@ export class NextJs extends BaseIntegration {
228
270
  fs.writeFileSync(targetPath, filledTemplate);
229
271
  }
230
272
 
231
- private _checkDep(packageName: string, minVersion?: boolean): boolean {
232
- const depVersion = _.get(
233
- appPackage,
234
- ['dependencies', packageName],
235
- '0.0.0',
236
- );
237
- const devDepVersion = _.get(
238
- appPackage,
239
- ['devDependencies', packageName],
240
- '0.0.0',
241
- );
273
+ private _checkUserNextVersion(packageName: string): boolean {
274
+ const depsVersion = _.get(appPackage, ['dependencies', packageName]);
275
+ const devDepsVersion = _.get(appPackage, ['devDependencies', packageName]);
242
276
 
243
- if (
244
- !_.get(appPackage, `dependencies.${packageName}`, false) &&
245
- !_.get(appPackage, `devDependencies.${packageName}`, false)
246
- ) {
247
- red(`✗ ${packageName} isn't in your dependencies`);
248
- red(` please install it with yarn/npm`);
277
+ if (!depsVersion && !devDepsVersion) {
278
+ red(`✗ ${packageName} isn't in your dependencies.`);
279
+ red(' Please install it with yarn/npm.');
249
280
  return false;
250
281
  } else if (
251
- !this._fulfillsMinVersion(depVersion) &&
252
- !this._fulfillsMinVersion(devDepVersion)
282
+ !this._fulfillsVersionRange(depsVersion) &&
283
+ !this._fulfillsVersionRange(devDepsVersion)
253
284
  ) {
254
285
  red(
255
- `✗ Your installed version of \`${packageName}\` is not supported, >=${MIN_NEXTJS_VERSION} needed.`,
286
+ `✗ Your \`package.json\` specifies a version of \`${packageName}\` outside of the compatible version range ${COMPATIBLE_NEXTJS_VERSIONS}.\n`,
256
287
  );
257
288
  return false;
258
289
  } else {
259
- if (minVersion) {
260
- green(`✓ ${packageName} >= ${MIN_NEXTJS_VERSION} is installed`);
261
- } else {
262
- green(`✓ ${packageName} is installed`);
263
- }
290
+ green(
291
+ `✓ A compatible version of \`${packageName}\` is specified in \`package.json\`.`,
292
+ );
264
293
  return true;
265
294
  }
266
295
  }
267
296
 
268
- private _fulfillsMinVersion(version: string): boolean {
269
- // The latest version, which at the moment is greater than the minimum
270
- // version, shouldn't be a blocker in the wizard.
297
+ private _fulfillsVersionRange(version: string): boolean {
298
+ // The latest version is currently 12.x, which is not yet supported.
271
299
  if (version === 'latest') {
272
- return true;
300
+ return false;
273
301
  }
274
302
 
275
- const cleanedVersion = clean(version);
276
- if (cleanedVersion) {
277
- // gte(x, y) : true if x >= y
278
- return gte(cleanedVersion, MIN_NEXTJS_VERSION);
279
- }
303
+ let cleanedUserVersion, isRange;
280
304
 
281
- const minVersionRange = `>=${MIN_NEXTJS_VERSION}`;
282
- const userVersionRange = validRange(version);
283
- const minUserVersion = minVersion(userVersionRange);
284
- if (minUserVersion == null) {
285
- // This should never happen
286
- return false;
305
+ if (valid(version)) {
306
+ cleanedUserVersion = valid(version);
307
+ isRange = false;
308
+ } else if (validRange(version)) {
309
+ cleanedUserVersion = validRange(version);
310
+ isRange = true;
287
311
  }
288
- return satisfies(minUserVersion, minVersionRange);
312
+
313
+ return (
314
+ !!cleanedUserVersion &&
315
+ (isRange
316
+ ? subset(cleanedUserVersion, COMPATIBLE_NEXTJS_VERSIONS)
317
+ : satisfies(cleanedUserVersion, COMPATIBLE_NEXTJS_VERSIONS))
318
+ );
319
+ }
320
+
321
+ private _spliceInPlace(
322
+ arr: Array<any>,
323
+ start: number,
324
+ deleteCount: number,
325
+ ...inserts: any[]
326
+ ): Array<any> {
327
+ arr.splice(start, deleteCount, ...inserts);
328
+ return arr;
289
329
  }
290
330
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/wizard",
3
- "version": "1.2.12",
3
+ "version": "1.2.16",
4
4
  "homepage": "https://github.com/getsentry/sentry-wizard",
5
5
  "repository": "https://github.com/getsentry/sentry-wizard",
6
6
  "description": "Sentry wizard helping you to configure your project",