@sentry/wizard 3.9.2 → 3.11.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.
Files changed (168) hide show
  1. package/CHANGELOG.md +58 -6
  2. package/dist/lib/Constants.d.ts +2 -0
  3. package/dist/lib/Constants.js +10 -0
  4. package/dist/lib/Constants.js.map +1 -1
  5. package/dist/lib/Steps/ChooseIntegration.js +15 -4
  6. package/dist/lib/Steps/ChooseIntegration.js.map +1 -1
  7. package/dist/lib/Steps/Integrations/Android.d.ts +9 -0
  8. package/dist/lib/Steps/Integrations/Android.js +86 -0
  9. package/dist/lib/Steps/Integrations/Android.js.map +1 -0
  10. package/dist/lib/Steps/Integrations/Cordova.js +5 -1
  11. package/dist/lib/Steps/Integrations/Cordova.js.map +1 -1
  12. package/dist/lib/Steps/Integrations/ReactNative.js +3 -3
  13. package/dist/lib/Steps/Integrations/ReactNative.js.map +1 -1
  14. package/dist/lib/Steps/Integrations/Remix.d.ts +12 -0
  15. package/dist/lib/Steps/Integrations/Remix.js +98 -0
  16. package/dist/lib/Steps/Integrations/Remix.js.map +1 -0
  17. package/dist/lib/Steps/PromptForParameters.js +36 -3
  18. package/dist/lib/Steps/PromptForParameters.js.map +1 -1
  19. package/dist/lib/Steps/SentryProjectSelector.js +1 -1
  20. package/dist/lib/Steps/SentryProjectSelector.js.map +1 -1
  21. package/dist/package.json +4 -3
  22. package/dist/src/android/android-wizard.d.ts +2 -0
  23. package/dist/src/android/android-wizard.js +217 -0
  24. package/dist/src/android/android-wizard.js.map +1 -0
  25. package/dist/src/android/code-tools.d.ts +39 -0
  26. package/dist/src/android/code-tools.js +161 -0
  27. package/dist/src/android/code-tools.js.map +1 -0
  28. package/dist/src/android/gradle.d.ts +62 -0
  29. package/dist/src/android/gradle.js +281 -0
  30. package/dist/src/android/gradle.js.map +1 -0
  31. package/dist/src/android/manifest.d.ts +57 -0
  32. package/dist/src/android/manifest.js +183 -0
  33. package/dist/src/android/manifest.js.map +1 -0
  34. package/dist/src/android/templates.d.ts +11 -0
  35. package/dist/src/android/templates.js +34 -0
  36. package/dist/src/android/templates.js.map +1 -0
  37. package/dist/src/apple/apple-wizard.js +123 -64
  38. package/dist/src/apple/apple-wizard.js.map +1 -1
  39. package/dist/src/apple/cocoapod.js +4 -3
  40. package/dist/src/apple/cocoapod.js.map +1 -1
  41. package/dist/src/apple/code-tools.d.ts +1 -1
  42. package/dist/src/apple/code-tools.js +43 -19
  43. package/dist/src/apple/code-tools.js.map +1 -1
  44. package/dist/src/apple/fastlane.d.ts +1 -1
  45. package/dist/src/apple/fastlane.js +12 -6
  46. package/dist/src/apple/fastlane.js.map +1 -1
  47. package/dist/src/apple/templates.d.ts +2 -2
  48. package/dist/src/apple/templates.js +4 -4
  49. package/dist/src/apple/templates.js.map +1 -1
  50. package/dist/src/apple/xcode-manager.d.ts +19 -3
  51. package/dist/src/apple/xcode-manager.js +126 -24
  52. package/dist/src/apple/xcode-manager.js.map +1 -1
  53. package/dist/src/nextjs/nextjs-wizard.js +49 -11
  54. package/dist/src/nextjs/nextjs-wizard.js.map +1 -1
  55. package/dist/src/nextjs/templates.d.ts +2 -0
  56. package/dist/src/nextjs/templates.js +6 -2
  57. package/dist/src/nextjs/templates.js.map +1 -1
  58. package/dist/src/remix/codemods/handle-error.d.ts +2 -0
  59. package/dist/src/remix/codemods/handle-error.js +70 -0
  60. package/dist/src/remix/codemods/handle-error.js.map +1 -0
  61. package/dist/src/remix/codemods/root-v1.d.ts +1 -0
  62. package/dist/src/remix/codemods/root-v1.js +133 -0
  63. package/dist/src/remix/codemods/root-v1.js.map +1 -0
  64. package/dist/src/remix/codemods/root-v2.d.ts +1 -0
  65. package/dist/src/remix/codemods/root-v2.js +134 -0
  66. package/dist/src/remix/codemods/root-v2.js.map +1 -0
  67. package/dist/src/remix/remix-wizard.d.ts +2 -0
  68. package/dist/src/remix/remix-wizard.js +196 -0
  69. package/dist/src/remix/remix-wizard.js.map +1 -0
  70. package/dist/src/remix/sdk-setup.d.ts +18 -0
  71. package/dist/src/remix/sdk-setup.js +293 -0
  72. package/dist/src/remix/sdk-setup.js.map +1 -0
  73. package/dist/src/remix/templates.d.ts +2 -0
  74. package/dist/src/remix/templates.js +6 -0
  75. package/dist/src/remix/templates.js.map +1 -0
  76. package/dist/src/remix/utils.d.ts +6 -0
  77. package/dist/src/remix/utils.js +55 -0
  78. package/dist/src/remix/utils.js.map +1 -0
  79. package/dist/src/sourcemaps/sourcemaps-wizard.js +49 -25
  80. package/dist/src/sourcemaps/sourcemaps-wizard.js.map +1 -1
  81. package/dist/src/sourcemaps/tools/nextjs.js +1 -1
  82. package/dist/src/sourcemaps/tools/nextjs.js.map +1 -1
  83. package/dist/src/sourcemaps/tools/remix.d.ts +3 -0
  84. package/dist/src/sourcemaps/tools/remix.js +125 -0
  85. package/dist/src/sourcemaps/tools/remix.js.map +1 -0
  86. package/dist/src/sourcemaps/tools/sentry-cli.js +19 -16
  87. package/dist/src/sourcemaps/tools/sentry-cli.js.map +1 -1
  88. package/dist/src/sourcemaps/tools/vite.d.ts +2 -1
  89. package/dist/src/sourcemaps/tools/vite.js +99 -12
  90. package/dist/src/sourcemaps/tools/vite.js.map +1 -1
  91. package/dist/src/sourcemaps/utils/detect-tool.d.ts +1 -1
  92. package/dist/src/sourcemaps/utils/detect-tool.js +1 -0
  93. package/dist/src/sourcemaps/utils/detect-tool.js.map +1 -1
  94. package/dist/src/sveltekit/sdk-setup.js +3 -3
  95. package/dist/src/sveltekit/sdk-setup.js.map +1 -1
  96. package/dist/src/sveltekit/sveltekit-wizard.js +34 -44
  97. package/dist/src/sveltekit/sveltekit-wizard.js.map +1 -1
  98. package/dist/src/telemetry.js +1 -0
  99. package/dist/src/telemetry.js.map +1 -1
  100. package/dist/src/utils/ast-utils.d.ts +2 -2
  101. package/dist/src/utils/ast-utils.js +7 -7
  102. package/dist/src/utils/ast-utils.js.map +1 -1
  103. package/dist/src/utils/clack-utils.d.ts +23 -28
  104. package/dist/src/utils/clack-utils.js +287 -244
  105. package/dist/src/utils/clack-utils.js.map +1 -1
  106. package/dist/src/utils/package-manager.d.ts +10 -0
  107. package/dist/{lib/Helper/PackageManager.js → src/utils/package-manager.js} +42 -74
  108. package/dist/src/utils/package-manager.js.map +1 -0
  109. package/dist/src/utils/release-registry.d.ts +1 -0
  110. package/dist/src/utils/release-registry.js +68 -0
  111. package/dist/src/utils/release-registry.js.map +1 -0
  112. package/dist/src/utils/sentrycli-utils.d.ts +4 -0
  113. package/dist/src/utils/sentrycli-utils.js +41 -0
  114. package/dist/src/utils/sentrycli-utils.js.map +1 -0
  115. package/dist/test/sourcemaps/tools/vite.test.d.ts +1 -0
  116. package/dist/test/sourcemaps/tools/vite.test.js +132 -0
  117. package/dist/test/sourcemaps/tools/vite.test.js.map +1 -0
  118. package/lib/Constants.ts +10 -0
  119. package/lib/Steps/ChooseIntegration.ts +14 -3
  120. package/lib/Steps/Integrations/Android.ts +23 -0
  121. package/lib/Steps/Integrations/Cordova.ts +5 -1
  122. package/lib/Steps/Integrations/ReactNative.ts +9 -3
  123. package/lib/Steps/Integrations/Remix.ts +32 -0
  124. package/lib/Steps/PromptForParameters.ts +48 -3
  125. package/lib/Steps/SentryProjectSelector.ts +3 -1
  126. package/package.json +4 -3
  127. package/src/android/android-wizard.ts +196 -0
  128. package/src/android/code-tools.ts +156 -0
  129. package/src/android/gradle.ts +245 -0
  130. package/src/android/manifest.ts +180 -0
  131. package/src/android/templates.ts +88 -0
  132. package/src/apple/apple-wizard.ts +113 -35
  133. package/src/apple/cocoapod.ts +6 -3
  134. package/src/apple/code-tools.ts +46 -18
  135. package/src/apple/fastlane.ts +6 -12
  136. package/src/apple/templates.ts +2 -8
  137. package/src/apple/xcode-manager.ts +167 -25
  138. package/src/nextjs/nextjs-wizard.ts +72 -8
  139. package/src/nextjs/templates.ts +16 -2
  140. package/src/remix/codemods/handle-error.ts +67 -0
  141. package/src/remix/codemods/root-v1.ts +91 -0
  142. package/src/remix/codemods/root-v2.ts +84 -0
  143. package/src/remix/remix-wizard.ts +132 -0
  144. package/src/remix/sdk-setup.ts +300 -0
  145. package/src/remix/templates.ts +15 -0
  146. package/src/remix/utils.ts +41 -0
  147. package/src/sourcemaps/sourcemaps-wizard.ts +28 -5
  148. package/src/sourcemaps/tools/nextjs.ts +2 -2
  149. package/src/sourcemaps/tools/remix.ts +90 -0
  150. package/src/sourcemaps/tools/sentry-cli.ts +8 -7
  151. package/src/sourcemaps/tools/vite.ts +136 -6
  152. package/src/sourcemaps/utils/detect-tool.ts +4 -1
  153. package/src/sveltekit/sdk-setup.ts +4 -4
  154. package/src/sveltekit/sveltekit-wizard.ts +5 -14
  155. package/src/telemetry.ts +2 -0
  156. package/src/utils/ast-utils.ts +7 -5
  157. package/src/utils/clack-utils.ts +366 -258
  158. package/src/utils/package-manager.ts +61 -0
  159. package/src/utils/release-registry.ts +19 -0
  160. package/src/utils/sentrycli-utils.ts +22 -0
  161. package/test/sourcemaps/tools/vite.test.ts +149 -0
  162. package/dist/lib/Helper/PackageManager.d.ts +0 -22
  163. package/dist/lib/Helper/PackageManager.js.map +0 -1
  164. package/dist/src/utils/vendor/clack-custom-select.d.ts +0 -21
  165. package/dist/src/utils/vendor/clack-custom-select.js +0 -137
  166. package/dist/src/utils/vendor/clack-custom-select.js.map +0 -1
  167. package/lib/Helper/PackageManager.ts +0 -59
  168. package/src/utils/vendor/clack-custom-select.ts +0 -160
@@ -62,7 +62,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
62
62
  return (mod && mod.__esModule) ? mod : { "default": mod };
63
63
  };
64
64
  Object.defineProperty(exports, "__esModule", { value: true });
65
- exports.getOrAskForProjectData = exports.isUsingTypeScript = exports.detectPackageManager = exports.getPackageDotJson = exports.ensurePackageIsInstalled = exports.addDotEnvSentryBuildPluginFile = exports.addSentryCliRc = exports.askForSelfHosted = exports.installPackage = exports.askForProjectSelection = exports.askForItemSelection = exports.askForWizardLogin = exports.askToInstallSentryCLI = exports.confirmContinueEvenThoughNoGitRepo = exports.printWelcome = exports.abortIfCancelled = exports.abort = exports.SENTRY_CLI_RC_FILE = exports.SENTRY_DOT_ENV_FILE = void 0;
65
+ exports.getOrAskForProjectData = exports.isUsingTypeScript = exports.getPackageDotJson = exports.ensurePackageIsInstalled = exports.addDotEnvSentryBuildPluginFile = exports.addSentryCliConfig = exports.installPackage = exports.askForItemSelection = exports.askToInstallSentryCLI = exports.confirmContinueEvenThoughNoGitRepo = exports.printWelcome = exports.abortIfCancelled = exports.abort = exports.sourceMapsCliSetupConfig = exports.SENTRY_PROPERTIES_FILE = exports.SENTRY_CLI_RC_FILE = exports.SENTRY_DOT_ENV_FILE = void 0;
66
66
  // @ts-ignore - clack is ESM and TS complains about that. It works though
67
67
  var clack = __importStar(require("@clack/prompts"));
68
68
  var axios_1 = __importDefault(require("axios"));
@@ -72,15 +72,33 @@ var fs = __importStar(require("fs"));
72
72
  var path = __importStar(require("path"));
73
73
  var timers_1 = require("timers");
74
74
  var url_1 = require("url");
75
- var util_1 = require("util");
76
75
  var Sentry = __importStar(require("@sentry/node"));
77
- var clack_custom_select_1 = require("./vendor/clack-custom-select");
78
76
  var package_json_1 = require("./package-json");
79
77
  var telemetry_1 = require("../telemetry");
78
+ var package_manager_1 = require("./package-manager");
80
79
  var opn = require('opn');
81
80
  exports.SENTRY_DOT_ENV_FILE = '.env.sentry-build-plugin';
82
81
  exports.SENTRY_CLI_RC_FILE = '.sentryclirc';
82
+ exports.SENTRY_PROPERTIES_FILE = 'sentry.properties';
83
83
  var SAAS_URL = 'https://sentry.io/';
84
+ exports.sourceMapsCliSetupConfig = {
85
+ filename: exports.SENTRY_CLI_RC_FILE,
86
+ name: 'source maps',
87
+ likelyAlreadyHasAuthToken: function (contents) {
88
+ return !!(contents.includes('[auth]') && contents.match(/token=./g));
89
+ },
90
+ tokenContent: function (authToken) {
91
+ return "[auth]\ntoken=".concat(authToken);
92
+ },
93
+ likelyAlreadyHasOrgAndProject: function (contents) {
94
+ return !!(contents.includes('[defaults]') &&
95
+ contents.match(/org=./g) &&
96
+ contents.match(/project=./g));
97
+ },
98
+ orgAndProjContent: function (org, project) {
99
+ return "[defaults]\norg=".concat(org, "\nproject=").concat(project);
100
+ },
101
+ };
84
102
  function abort(message, status) {
85
103
  return __awaiter(this, void 0, void 0, function () {
86
104
  var sentryHub, sentryTransaction, sentrySession;
@@ -154,6 +172,9 @@ function printWelcome(options) {
154
172
  if (wizardPackage.version) {
155
173
  welcomeText += "\n\nVersion: ".concat(wizardPackage.version);
156
174
  }
175
+ if (options.telemetryEnabled) {
176
+ welcomeText += "\n\nYou are using the Sentry Wizard with telemetry enabled. This helps us improve the Wizard.\nYou can disable it at any time by running `sentry-wizard --disable-telemetry`.";
177
+ }
157
178
  clack.note(welcomeText);
158
179
  }
159
180
  exports.printWelcome = printWelcome;
@@ -201,99 +222,12 @@ function askToInstallSentryCLI() {
201
222
  });
202
223
  }
203
224
  exports.askToInstallSentryCLI = askToInstallSentryCLI;
204
- function askForWizardLogin(options) {
205
- return __awaiter(this, void 0, void 0, function () {
206
- var hasSentryAccount, wizardHash, _a, loginUrl, urlToOpen, loginSpinner, data;
207
- return __generator(this, function (_b) {
208
- switch (_b.label) {
209
- case 0:
210
- Sentry.setTag('has-promo-code', !!options.promoCode);
211
- return [4 /*yield*/, clack.confirm({
212
- message: 'Do you already have a Sentry account?',
213
- })];
214
- case 1:
215
- hasSentryAccount = _b.sent();
216
- return [4 /*yield*/, abortIfCancelled(hasSentryAccount)];
217
- case 2:
218
- hasSentryAccount = _b.sent();
219
- Sentry.setTag('already-has-sentry-account', hasSentryAccount);
220
- _b.label = 3;
221
- case 3:
222
- _b.trys.push([3, 5, , 10]);
223
- return [4 /*yield*/, axios_1.default.get("".concat(options.url, "api/0/wizard/"))];
224
- case 4:
225
- wizardHash = (_b.sent()).data.hash;
226
- return [3 /*break*/, 10];
227
- case 5:
228
- _a = _b.sent();
229
- if (!(options.url !== SAAS_URL)) return [3 /*break*/, 7];
230
- clack.log.error('Loading Wizard failed. Did you provide the right URL?');
231
- return [4 /*yield*/, abort(chalk_1.default.red('Please check your configuration and try again.\n\n Let us know if you think this is an issue with the wizard or Sentry: https://github.com/getsentry/sentry-wizard/issues'))];
232
- case 6:
233
- _b.sent();
234
- return [3 /*break*/, 9];
235
- case 7:
236
- clack.log.error('Loading Wizard failed.');
237
- return [4 /*yield*/, abort(chalk_1.default.red('Please try again in a few minutes and let us know if this issue persists: https://github.com/getsentry/sentry-wizard/issues'))];
238
- case 8:
239
- _b.sent();
240
- _b.label = 9;
241
- case 9: return [3 /*break*/, 10];
242
- case 10:
243
- loginUrl = new url_1.URL("".concat(options.url, "account/settings/wizard/").concat(wizardHash, "/"));
244
- if (!hasSentryAccount) {
245
- loginUrl.searchParams.set('signup', '1');
246
- if (options.platform) {
247
- loginUrl.searchParams.set('project_platform', options.platform);
248
- }
249
- }
250
- if (options.promoCode) {
251
- loginUrl.searchParams.set('code', options.promoCode);
252
- }
253
- urlToOpen = loginUrl.toString();
254
- clack.log.info("".concat(chalk_1.default.bold("If the browser window didn't open automatically, please open the following link to ".concat(hasSentryAccount ? 'log' : 'sign', " into Sentry:")), "\n\n").concat(chalk_1.default.cyan(urlToOpen)));
255
- opn(urlToOpen).catch(function () {
256
- // opn throws in environments that don't have a browser (e.g. remote shells) so we just noop here
257
- });
258
- loginSpinner = clack.spinner();
259
- loginSpinner.start('Waiting for you to log in using the link above');
260
- return [4 /*yield*/, new Promise(function (resolve) {
261
- var pollingInterval = (0, timers_1.setInterval)(function () {
262
- axios_1.default
263
- .get("".concat(options.url, "api/0/wizard/").concat(wizardHash, "/"))
264
- .then(function (result) {
265
- resolve(result.data);
266
- clearTimeout(timeout);
267
- clearInterval(pollingInterval);
268
- void axios_1.default.delete("".concat(options.url, "api/0/wizard/").concat(wizardHash, "/"));
269
- })
270
- .catch(function () {
271
- // noop - just try again
272
- });
273
- }, 500);
274
- var timeout = setTimeout(function () {
275
- clearInterval(pollingInterval);
276
- loginSpinner.stop('Login timed out. No worries - it happens to the best of us.');
277
- Sentry.setTag('opened-wizard-link', false);
278
- void abort('Please restart the Wizard and log in to complete the setup.');
279
- }, 180000);
280
- })];
281
- case 11:
282
- data = _b.sent();
283
- loginSpinner.stop('Login complete.');
284
- Sentry.setTag('opened-wizard-link', true);
285
- return [2 /*return*/, data];
286
- }
287
- });
288
- });
289
- }
290
- exports.askForWizardLogin = askForWizardLogin;
291
225
  function askForItemSelection(items, message) {
292
226
  return __awaiter(this, void 0, void 0, function () {
293
227
  var selection;
294
228
  return __generator(this, function (_a) {
295
229
  switch (_a.label) {
296
- case 0: return [4 /*yield*/, abortIfCancelled((0, clack_custom_select_1.windowedSelect)({
230
+ case 0: return [4 /*yield*/, abortIfCancelled(clack.select({
297
231
  maxItems: 12,
298
232
  message: message,
299
233
  options: items.map(function (item, index) {
@@ -311,32 +245,6 @@ function askForItemSelection(items, message) {
311
245
  });
312
246
  }
313
247
  exports.askForItemSelection = askForItemSelection;
314
- function askForProjectSelection(projects) {
315
- return __awaiter(this, void 0, void 0, function () {
316
- var selection;
317
- return __generator(this, function (_a) {
318
- switch (_a.label) {
319
- case 0: return [4 /*yield*/, abortIfCancelled((0, clack_custom_select_1.windowedSelect)({
320
- maxItems: 12,
321
- message: 'Select your Sentry project.',
322
- options: projects.map(function (project) {
323
- return {
324
- value: project,
325
- label: "".concat(project.organization.slug, "/").concat(project.slug),
326
- };
327
- }),
328
- }))];
329
- case 1:
330
- selection = _a.sent();
331
- Sentry.setTag('project', selection.slug);
332
- Sentry.setTag('project-platform', selection.platform);
333
- Sentry.setUser({ id: selection.organization.slug });
334
- return [2 /*return*/, selection];
335
- }
336
- });
337
- });
338
- }
339
- exports.askForProjectSelection = askForProjectSelection;
340
248
  function installPackage(_a) {
341
249
  var packageName = _a.packageName, alreadyInstalled = _a.alreadyInstalled, _b = _a.askBeforeUpdating, askBeforeUpdating = _b === void 0 ? true : _b;
342
250
  return __awaiter(this, void 0, void 0, function () {
@@ -359,161 +267,106 @@ function installPackage(_a) {
359
267
  return [4 /*yield*/, getPackageManager()];
360
268
  case 3:
361
269
  packageManager = _c.sent();
362
- sdkInstallSpinner.start("".concat(alreadyInstalled ? 'Updating' : 'Installing', " ").concat(chalk_1.default.bold.cyan(packageName), " with ").concat(chalk_1.default.bold(packageManager), "."));
270
+ sdkInstallSpinner.start("".concat(alreadyInstalled ? 'Updating' : 'Installing', " ").concat(chalk_1.default.bold.cyan(packageName), " with ").concat(chalk_1.default.bold(packageManager.label), "."));
363
271
  _c.label = 4;
364
272
  case 4:
365
- _c.trys.push([4, 11, , 13]);
366
- if (!(packageManager === 'yarn')) return [3 /*break*/, 6];
367
- return [4 /*yield*/, (0, util_1.promisify)(childProcess.exec)("yarn add ".concat(packageName, "@latest"))];
273
+ _c.trys.push([4, 6, , 8]);
274
+ return [4 /*yield*/, (0, package_manager_1.installPackageWithPackageManager)(packageManager, packageName)];
368
275
  case 5:
369
276
  _c.sent();
370
- return [3 /*break*/, 10];
277
+ return [3 /*break*/, 8];
371
278
  case 6:
372
- if (!(packageManager === 'pnpm')) return [3 /*break*/, 8];
373
- return [4 /*yield*/, (0, util_1.promisify)(childProcess.exec)("pnpm add ".concat(packageName, "@latest"))];
374
- case 7:
375
- _c.sent();
376
- return [3 /*break*/, 10];
377
- case 8:
378
- if (!(packageManager === 'npm')) return [3 /*break*/, 10];
379
- return [4 /*yield*/, (0, util_1.promisify)(childProcess.exec)("npm install ".concat(packageName, "@latest"))];
380
- case 9:
381
- _c.sent();
382
- _c.label = 10;
383
- case 10: return [3 /*break*/, 13];
384
- case 11:
385
279
  e_1 = _c.sent();
386
280
  sdkInstallSpinner.stop('Installation failed.');
387
281
  clack.log.error("".concat(chalk_1.default.red('Encountered the following error during installation:'), "\n\n").concat(e_1, "\n\n").concat(chalk_1.default.dim('If you think this issue is caused by the Sentry wizard, let us know here:\nhttps://github.com/getsentry/sentry-wizard/issues')));
388
282
  return [4 /*yield*/, abort()];
389
- case 12:
283
+ case 7:
390
284
  _c.sent();
391
- return [3 /*break*/, 13];
392
- case 13:
393
- sdkInstallSpinner.stop("".concat(alreadyInstalled ? 'Updated' : 'Installed', " ").concat(chalk_1.default.bold.cyan(packageName), " with ").concat(chalk_1.default.bold(packageManager), "."));
285
+ return [3 /*break*/, 8];
286
+ case 8:
287
+ sdkInstallSpinner.stop("".concat(alreadyInstalled ? 'Updated' : 'Installed', " ").concat(chalk_1.default.bold.cyan(packageName), " with ").concat(chalk_1.default.bold(packageManager.label), "."));
394
288
  return [2 /*return*/];
395
289
  }
396
290
  });
397
291
  });
398
292
  }
399
293
  exports.installPackage = installPackage;
400
- /**
401
- * Asks users if they are using SaaS or self-hosted Sentry and returns the validated URL.
402
- *
403
- * If users started the wizard with a --url arg, that URL is used as the default and we skip
404
- * the self-hosted question. However, the passed url is still validated and in case it's
405
- * invalid, users are asked to enter a new one until it is valid.
406
- *
407
- * @param urlFromArgs the url passed via the --url arg
408
- */
409
- function askForSelfHosted(urlFromArgs) {
294
+ function addOrgAndProjectToSentryCliRc(org, project, setupConfig) {
410
295
  return __awaiter(this, void 0, void 0, function () {
411
- var choice, validUrl, tmpUrlFromArgs, url, _a, isSelfHostedUrl;
412
- return __generator(this, function (_b) {
413
- switch (_b.label) {
296
+ var configContents, e_2;
297
+ return __generator(this, function (_a) {
298
+ switch (_a.label) {
414
299
  case 0:
415
- if (!!urlFromArgs) return [3 /*break*/, 2];
416
- return [4 /*yield*/, abortIfCancelled(clack.select({
417
- message: 'Are you using Sentry SaaS or self-hosted Sentry?',
418
- options: [
419
- { value: 'saas', label: 'Sentry SaaS (sentry.io)' },
420
- {
421
- value: 'self-hosted',
422
- label: 'Self-hosted/on-premise/single-tenant',
423
- },
424
- ],
425
- }))];
300
+ configContents = fs.readFileSync(path.join(process.cwd(), setupConfig.filename), 'utf8');
301
+ if (!setupConfig.likelyAlreadyHasOrgAndProject(configContents)) return [3 /*break*/, 1];
302
+ clack.log.warn("".concat(chalk_1.default.bold(setupConfig.filename), " already has org and project. Will not add them."));
303
+ return [3 /*break*/, 4];
426
304
  case 1:
427
- choice = _b.sent();
428
- if (choice === 'saas') {
429
- Sentry.setTag('url', SAAS_URL);
430
- Sentry.setTag('self-hosted', false);
431
- return [2 /*return*/, { url: SAAS_URL, selfHosted: false }];
432
- }
433
- _b.label = 2;
305
+ _a.trys.push([1, 3, , 4]);
306
+ return [4 /*yield*/, fs.promises.appendFile(path.join(process.cwd(), setupConfig.filename), "\n".concat(setupConfig.orgAndProjContent(org, project), "\n"))];
434
307
  case 2:
435
- tmpUrlFromArgs = urlFromArgs;
436
- _b.label = 3;
308
+ _a.sent();
309
+ return [3 /*break*/, 4];
437
310
  case 3:
438
- if (!(validUrl === undefined)) return [3 /*break*/, 6];
439
- _a = tmpUrlFromArgs;
440
- if (_a) return [3 /*break*/, 5];
441
- return [4 /*yield*/, abortIfCancelled(clack.text({
442
- message: "Please enter the URL of your ".concat(urlFromArgs ? '' : 'self-hosted ', "Sentry instance."),
443
- placeholder: 'https://sentry.io/',
444
- }))];
445
- case 4:
446
- _a = (_b.sent());
447
- _b.label = 5;
448
- case 5:
449
- url = _a;
450
- tmpUrlFromArgs = undefined;
451
- try {
452
- validUrl = new url_1.URL(url).toString();
453
- // We assume everywhere else that the URL ends in a slash
454
- if (!validUrl.endsWith('/')) {
455
- validUrl += '/';
456
- }
457
- }
458
- catch (_c) {
459
- clack.log.error('Please enter a valid URL. (It should look something like "https://sentry.mydomain.com/")');
460
- }
461
- return [3 /*break*/, 3];
462
- case 6:
463
- isSelfHostedUrl = new url_1.URL(validUrl).host !== new url_1.URL(SAAS_URL).host;
464
- Sentry.setTag('url', validUrl);
465
- Sentry.setTag('self-hosted', isSelfHostedUrl);
466
- return [2 /*return*/, { url: validUrl, selfHosted: true }];
311
+ e_2 = _a.sent();
312
+ clack.log.warn("".concat(chalk_1.default.bold(setupConfig.filename), " could not be updated with org and project."));
313
+ return [3 /*break*/, 4];
314
+ case 4: return [2 /*return*/];
467
315
  }
468
316
  });
469
317
  });
470
318
  }
471
- exports.askForSelfHosted = askForSelfHosted;
472
- function addSentryCliRc(authToken) {
319
+ function addSentryCliConfig(authToken, setupConfig, orgSlug, projectSlug) {
320
+ if (setupConfig === void 0) { setupConfig = exports.sourceMapsCliSetupConfig; }
473
321
  return __awaiter(this, void 0, void 0, function () {
474
- var clircExists, clircContents, likelyAlreadyHasAuthToken, _a, _b;
322
+ var configExists, configContents, _a, _b;
475
323
  return __generator(this, function (_c) {
476
324
  switch (_c.label) {
477
325
  case 0:
478
- clircExists = fs.existsSync(path.join(process.cwd(), exports.SENTRY_CLI_RC_FILE));
479
- if (!clircExists) return [3 /*break*/, 5];
480
- clircContents = fs.readFileSync(path.join(process.cwd(), exports.SENTRY_CLI_RC_FILE), 'utf8');
481
- likelyAlreadyHasAuthToken = !!(clircContents.includes('[auth]') && clircContents.match(/token=./g));
482
- if (!likelyAlreadyHasAuthToken) return [3 /*break*/, 1];
483
- clack.log.warn("".concat(chalk_1.default.bold(exports.SENTRY_CLI_RC_FILE), " already has auth token. Will not add one."));
326
+ configExists = fs.existsSync(path.join(process.cwd(), setupConfig.filename));
327
+ if (!configExists) return [3 /*break*/, 5];
328
+ configContents = fs.readFileSync(path.join(process.cwd(), setupConfig.filename), 'utf8');
329
+ if (!setupConfig.likelyAlreadyHasAuthToken(configContents)) return [3 /*break*/, 1];
330
+ clack.log.warn("".concat(chalk_1.default.bold(setupConfig.filename), " already has auth token. Will not add one."));
484
331
  return [3 /*break*/, 4];
485
332
  case 1:
486
333
  _c.trys.push([1, 3, , 4]);
487
- return [4 /*yield*/, fs.promises.writeFile(path.join(process.cwd(), exports.SENTRY_CLI_RC_FILE), "".concat(clircContents, "\n[auth]\ntoken=").concat(authToken, "\n"), { encoding: 'utf8', flag: 'w' })];
334
+ return [4 /*yield*/, fs.promises.writeFile(path.join(process.cwd(), setupConfig.filename), "".concat(configContents, "\n").concat(setupConfig.tokenContent(authToken), "\n"), { encoding: 'utf8', flag: 'w' })];
488
335
  case 2:
489
336
  _c.sent();
490
- clack.log.success("Added auth token to ".concat(chalk_1.default.bold(exports.SENTRY_CLI_RC_FILE), " for you to test uploading source maps locally."));
337
+ clack.log.success(chalk_1.default.greenBright("Added auth token to ".concat(chalk_1.default.bold(setupConfig.filename), " for you to test uploading ").concat(setupConfig.name, " locally.")));
491
338
  return [3 /*break*/, 4];
492
339
  case 3:
493
340
  _a = _c.sent();
494
- clack.log.warning("Failed to add auth token to ".concat(chalk_1.default.bold(exports.SENTRY_CLI_RC_FILE), ". Uploading source maps during build will likely not work locally."));
341
+ clack.log.warning("Failed to add auth token to ".concat(chalk_1.default.bold(setupConfig.filename), ". Uploading ").concat(setupConfig.name, " during build will likely not work locally."));
495
342
  return [3 /*break*/, 4];
496
343
  case 4: return [3 /*break*/, 8];
497
344
  case 5:
498
345
  _c.trys.push([5, 7, , 8]);
499
- return [4 /*yield*/, fs.promises.writeFile(path.join(process.cwd(), exports.SENTRY_CLI_RC_FILE), "[auth]\ntoken=".concat(authToken, "\n"), { encoding: 'utf8', flag: 'w' })];
346
+ return [4 /*yield*/, fs.promises.writeFile(path.join(process.cwd(), setupConfig.filename), "".concat(setupConfig.tokenContent(authToken), "\n"), { encoding: 'utf8', flag: 'w' })];
500
347
  case 6:
501
348
  _c.sent();
502
- clack.log.success("Created ".concat(chalk_1.default.bold(exports.SENTRY_CLI_RC_FILE), " with auth token for you to test uploading source maps locally."));
349
+ clack.log.success(chalk_1.default.greenBright("Created ".concat(chalk_1.default.bold(setupConfig.filename), " with auth token for you to test uploading ").concat(setupConfig.name, " locally.")));
503
350
  return [3 /*break*/, 8];
504
351
  case 7:
505
352
  _b = _c.sent();
506
- clack.log.warning("Failed to create ".concat(chalk_1.default.bold(exports.SENTRY_CLI_RC_FILE), " with auth token. Uploading source maps during build will likely not work locally."));
353
+ clack.log.warning("Failed to create ".concat(chalk_1.default.bold(setupConfig.filename), " with auth token. Uploading ").concat(setupConfig.name, " during build will likely not work locally."));
507
354
  return [3 /*break*/, 8];
508
- case 8: return [4 /*yield*/, addAuthTokenFileToGitIgnore(exports.SENTRY_CLI_RC_FILE)];
355
+ case 8:
356
+ if (!(orgSlug && projectSlug)) return [3 /*break*/, 10];
357
+ return [4 /*yield*/, addOrgAndProjectToSentryCliRc(orgSlug, projectSlug, setupConfig)];
509
358
  case 9:
359
+ _c.sent();
360
+ _c.label = 10;
361
+ case 10: return [4 /*yield*/, addAuthTokenFileToGitIgnore(setupConfig.filename)];
362
+ case 11:
510
363
  _c.sent();
511
364
  return [2 /*return*/];
512
365
  }
513
366
  });
514
367
  });
515
368
  }
516
- exports.addSentryCliRc = addSentryCliRc;
369
+ exports.addSentryCliConfig = addSentryCliConfig;
517
370
  function addDotEnvSentryBuildPluginFile(authToken) {
518
371
  return __awaiter(this, void 0, void 0, function () {
519
372
  var envVarContent, dotEnvFilePath, dotEnvFileExists, dotEnvFileContent, hasAuthToken, _a, _b;
@@ -577,7 +430,7 @@ function addAuthTokenFileToGitIgnore(filename) {
577
430
  return [4 /*yield*/, fs.promises.appendFile(path.join(process.cwd(), '.gitignore'), "\n# Sentry Auth Token\n".concat(filename, "\n"), { encoding: 'utf8' })];
578
431
  case 1:
579
432
  _b.sent();
580
- clack.log.success("Added ".concat(chalk_1.default.bold(filename), " to ").concat(chalk_1.default.bold('.gitignore'), "."));
433
+ clack.log.success(chalk_1.default.greenBright("Added ".concat(chalk_1.default.bold(filename), " to ").concat(chalk_1.default.bold('.gitignore'), ".")));
581
434
  return [3 /*break*/, 3];
582
435
  case 2:
583
436
  _a = _b.sent();
@@ -651,39 +504,25 @@ function getPackageManager() {
651
504
  return __generator(this, function (_a) {
652
505
  switch (_a.label) {
653
506
  case 0:
654
- detectedPackageManager = detectPackageManager();
507
+ detectedPackageManager = (0, package_manager_1.detectPackageManger)();
655
508
  if (detectedPackageManager) {
656
509
  return [2 /*return*/, detectedPackageManager];
657
510
  }
658
511
  return [4 /*yield*/, abortIfCancelled(clack.select({
659
512
  message: 'Please select your package manager.',
660
- options: [
661
- { value: 'npm', label: 'Npm' },
662
- { value: 'yarn', label: 'Yarn' },
663
- { value: 'pnpm', label: 'Pnpm' },
664
- ],
513
+ options: package_manager_1.packageManagers.map(function (packageManager) { return ({
514
+ value: packageManager,
515
+ label: packageManager.label,
516
+ }); }),
665
517
  }))];
666
518
  case 1:
667
519
  selectedPackageManager = _a.sent();
668
- Sentry.setTag('package-manager', selectedPackageManager);
520
+ Sentry.setTag('package-manager', selectedPackageManager.name);
669
521
  return [2 /*return*/, selectedPackageManager];
670
522
  }
671
523
  });
672
524
  });
673
525
  }
674
- function detectPackageManager() {
675
- if (fs.existsSync(path.join(process.cwd(), 'yarn.lock'))) {
676
- return 'yarn';
677
- }
678
- if (fs.existsSync(path.join(process.cwd(), 'package-lock.json'))) {
679
- return 'npm';
680
- }
681
- if (fs.existsSync(path.join(process.cwd(), 'pnpm-lock.yaml'))) {
682
- return 'pnpm';
683
- }
684
- return undefined;
685
- }
686
- exports.detectPackageManager = detectPackageManager;
687
526
  function isUsingTypeScript() {
688
527
  try {
689
528
  return fs.existsSync(path.join(process.cwd(), 'tsconfig.json'));
@@ -693,7 +532,18 @@ function isUsingTypeScript() {
693
532
  }
694
533
  }
695
534
  exports.isUsingTypeScript = isUsingTypeScript;
696
- function getOrAskForProjectData(options) {
535
+ /**
536
+ * Checks if we already got project data from a previous wizard invocation.
537
+ * If yes, this data is returned.
538
+ * Otherwise, we start the login flow and ask the user to select a project.
539
+ *
540
+ * Use this function to get project data for the wizard.
541
+ *
542
+ * @param options wizard options
543
+ * @param platform the platform of the wizard
544
+ * @returns project data (org, project, token, url)
545
+ */
546
+ function getOrAskForProjectData(options, platform) {
697
547
  var _a;
698
548
  return __awaiter(this, void 0, void 0, function () {
699
549
  var _b, sentryUrl, selfHosted, _c, projects, apiKeys, selectedProject;
@@ -715,15 +565,22 @@ function getOrAskForProjectData(options) {
715
565
  return askForWizardLogin({
716
566
  promoCode: options.promoCode,
717
567
  url: sentryUrl,
718
- platform: 'javascript-nextjs',
568
+ platform: platform,
719
569
  });
720
570
  })];
721
571
  case 2:
722
572
  _c = _d.sent(), projects = _c.projects, apiKeys = _c.apiKeys;
723
- return [4 /*yield*/, (0, telemetry_1.traceStep)('select-project', function () {
724
- return askForProjectSelection(projects);
725
- })];
573
+ if (!(!projects || !projects.length)) return [3 /*break*/, 4];
574
+ clack.log.error('No projects found. Please create a project in Sentry and try again.');
575
+ Sentry.setTag('no-projects-found', true);
576
+ return [4 /*yield*/, abort()];
726
577
  case 3:
578
+ _d.sent();
579
+ _d.label = 4;
580
+ case 4: return [4 /*yield*/, (0, telemetry_1.traceStep)('select-project', function () {
581
+ return askForProjectSelection(projects);
582
+ })];
583
+ case 5:
727
584
  selectedProject = _d.sent();
728
585
  return [2 /*return*/, {
729
586
  sentryUrl: sentryUrl,
@@ -736,4 +593,190 @@ function getOrAskForProjectData(options) {
736
593
  });
737
594
  }
738
595
  exports.getOrAskForProjectData = getOrAskForProjectData;
596
+ /**
597
+ * Asks users if they are using SaaS or self-hosted Sentry and returns the validated URL.
598
+ *
599
+ * If users started the wizard with a --url arg, that URL is used as the default and we skip
600
+ * the self-hosted question. However, the passed url is still validated and in case it's
601
+ * invalid, users are asked to enter a new one until it is valid.
602
+ *
603
+ * @param urlFromArgs the url passed via the --url arg
604
+ */
605
+ function askForSelfHosted(urlFromArgs) {
606
+ return __awaiter(this, void 0, void 0, function () {
607
+ var choice, validUrl, tmpUrlFromArgs, url, _a, isSelfHostedUrl;
608
+ return __generator(this, function (_b) {
609
+ switch (_b.label) {
610
+ case 0:
611
+ if (!!urlFromArgs) return [3 /*break*/, 2];
612
+ return [4 /*yield*/, abortIfCancelled(clack.select({
613
+ message: 'Are you using Sentry SaaS or self-hosted Sentry?',
614
+ options: [
615
+ { value: 'saas', label: 'Sentry SaaS (sentry.io)' },
616
+ {
617
+ value: 'self-hosted',
618
+ label: 'Self-hosted/on-premise/single-tenant',
619
+ },
620
+ ],
621
+ }))];
622
+ case 1:
623
+ choice = _b.sent();
624
+ if (choice === 'saas') {
625
+ Sentry.setTag('url', SAAS_URL);
626
+ Sentry.setTag('self-hosted', false);
627
+ return [2 /*return*/, { url: SAAS_URL, selfHosted: false }];
628
+ }
629
+ _b.label = 2;
630
+ case 2:
631
+ tmpUrlFromArgs = urlFromArgs;
632
+ _b.label = 3;
633
+ case 3:
634
+ if (!(validUrl === undefined)) return [3 /*break*/, 6];
635
+ _a = tmpUrlFromArgs;
636
+ if (_a) return [3 /*break*/, 5];
637
+ return [4 /*yield*/, abortIfCancelled(clack.text({
638
+ message: "Please enter the URL of your ".concat(urlFromArgs ? '' : 'self-hosted ', "Sentry instance."),
639
+ placeholder: 'https://sentry.io/',
640
+ }))];
641
+ case 4:
642
+ _a = (_b.sent());
643
+ _b.label = 5;
644
+ case 5:
645
+ url = _a;
646
+ tmpUrlFromArgs = undefined;
647
+ try {
648
+ validUrl = new url_1.URL(url).toString();
649
+ // We assume everywhere else that the URL ends in a slash
650
+ if (!validUrl.endsWith('/')) {
651
+ validUrl += '/';
652
+ }
653
+ }
654
+ catch (_c) {
655
+ clack.log.error('Please enter a valid URL. (It should look something like "https://sentry.mydomain.com/")');
656
+ }
657
+ return [3 /*break*/, 3];
658
+ case 6:
659
+ isSelfHostedUrl = new url_1.URL(validUrl).host !== new url_1.URL(SAAS_URL).host;
660
+ Sentry.setTag('url', validUrl);
661
+ Sentry.setTag('self-hosted', isSelfHostedUrl);
662
+ return [2 /*return*/, { url: validUrl, selfHosted: true }];
663
+ }
664
+ });
665
+ });
666
+ }
667
+ function askForWizardLogin(options) {
668
+ return __awaiter(this, void 0, void 0, function () {
669
+ var hasSentryAccount, wizardHash, _a, loginUrl, urlToOpen, loginSpinner, data;
670
+ return __generator(this, function (_b) {
671
+ switch (_b.label) {
672
+ case 0:
673
+ Sentry.setTag('has-promo-code', !!options.promoCode);
674
+ return [4 /*yield*/, clack.confirm({
675
+ message: 'Do you already have a Sentry account?',
676
+ })];
677
+ case 1:
678
+ hasSentryAccount = _b.sent();
679
+ return [4 /*yield*/, abortIfCancelled(hasSentryAccount)];
680
+ case 2:
681
+ hasSentryAccount = _b.sent();
682
+ Sentry.setTag('already-has-sentry-account', hasSentryAccount);
683
+ _b.label = 3;
684
+ case 3:
685
+ _b.trys.push([3, 5, , 10]);
686
+ return [4 /*yield*/, axios_1.default.get("".concat(options.url, "api/0/wizard/"))];
687
+ case 4:
688
+ wizardHash = (_b.sent()).data.hash;
689
+ return [3 /*break*/, 10];
690
+ case 5:
691
+ _a = _b.sent();
692
+ if (!(options.url !== SAAS_URL)) return [3 /*break*/, 7];
693
+ clack.log.error('Loading Wizard failed. Did you provide the right URL?');
694
+ return [4 /*yield*/, abort(chalk_1.default.red('Please check your configuration and try again.\n\n Let us know if you think this is an issue with the wizard or Sentry: https://github.com/getsentry/sentry-wizard/issues'))];
695
+ case 6:
696
+ _b.sent();
697
+ return [3 /*break*/, 9];
698
+ case 7:
699
+ clack.log.error('Loading Wizard failed.');
700
+ return [4 /*yield*/, abort(chalk_1.default.red('Please try again in a few minutes and let us know if this issue persists: https://github.com/getsentry/sentry-wizard/issues'))];
701
+ case 8:
702
+ _b.sent();
703
+ _b.label = 9;
704
+ case 9: return [3 /*break*/, 10];
705
+ case 10:
706
+ loginUrl = new url_1.URL("".concat(options.url, "account/settings/wizard/").concat(wizardHash, "/"));
707
+ if (!hasSentryAccount) {
708
+ loginUrl.searchParams.set('signup', '1');
709
+ if (options.platform) {
710
+ loginUrl.searchParams.set('project_platform', options.platform);
711
+ }
712
+ }
713
+ if (options.promoCode) {
714
+ loginUrl.searchParams.set('code', options.promoCode);
715
+ }
716
+ urlToOpen = loginUrl.toString();
717
+ clack.log.info("".concat(chalk_1.default.bold("If the browser window didn't open automatically, please open the following link to ".concat(hasSentryAccount ? 'log' : 'sign', " into Sentry:")), "\n\n").concat(chalk_1.default.cyan(urlToOpen)));
718
+ opn(urlToOpen).catch(function () {
719
+ // opn throws in environments that don't have a browser (e.g. remote shells) so we just noop here
720
+ });
721
+ loginSpinner = clack.spinner();
722
+ loginSpinner.start('Waiting for you to log in using the link above');
723
+ return [4 /*yield*/, new Promise(function (resolve) {
724
+ var pollingInterval = (0, timers_1.setInterval)(function () {
725
+ axios_1.default
726
+ .get("".concat(options.url, "api/0/wizard/").concat(wizardHash, "/"), {
727
+ headers: {
728
+ 'Accept-Encoding': 'deflate',
729
+ },
730
+ })
731
+ .then(function (result) {
732
+ resolve(result.data);
733
+ clearTimeout(timeout);
734
+ clearInterval(pollingInterval);
735
+ void axios_1.default.delete("".concat(options.url, "api/0/wizard/").concat(wizardHash, "/"));
736
+ })
737
+ .catch(function () {
738
+ // noop - just try again
739
+ });
740
+ }, 500);
741
+ var timeout = setTimeout(function () {
742
+ clearInterval(pollingInterval);
743
+ loginSpinner.stop('Login timed out. No worries - it happens to the best of us.');
744
+ Sentry.setTag('opened-wizard-link', false);
745
+ void abort('Please restart the Wizard and log in to complete the setup.');
746
+ }, 180000);
747
+ })];
748
+ case 11:
749
+ data = _b.sent();
750
+ loginSpinner.stop('Login complete.');
751
+ Sentry.setTag('opened-wizard-link', true);
752
+ return [2 /*return*/, data];
753
+ }
754
+ });
755
+ });
756
+ }
757
+ function askForProjectSelection(projects) {
758
+ return __awaiter(this, void 0, void 0, function () {
759
+ var selection;
760
+ return __generator(this, function (_a) {
761
+ switch (_a.label) {
762
+ case 0: return [4 /*yield*/, abortIfCancelled(clack.select({
763
+ maxItems: 12,
764
+ message: 'Select your Sentry project.',
765
+ options: projects.map(function (project) {
766
+ return {
767
+ value: project,
768
+ label: "".concat(project.organization.slug, "/").concat(project.slug),
769
+ };
770
+ }),
771
+ }))];
772
+ case 1:
773
+ selection = _a.sent();
774
+ Sentry.setTag('project', selection.slug);
775
+ Sentry.setTag('project-platform', selection.platform);
776
+ Sentry.setUser({ id: selection.organization.slug });
777
+ return [2 /*return*/, selection];
778
+ }
779
+ });
780
+ });
781
+ }
739
782
  //# sourceMappingURL=clack-utils.js.map