@sentry/wizard 2.4.0 → 2.4.2

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 CHANGED
@@ -1,13 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.4.2
4
+
5
+ - feat(nextjs): Add sentry.edge.config.js template (#227)
6
+
7
+ ## 2.4.1
8
+
9
+ - feat: Add logic to add @sentry/nextjs if it's missing when running the wizard (#219)
10
+ - fix: Print localhost with `http` instead of `https` (#212)
11
+ - feat: Add project_platform as query param if -s and -i are set (#221)
12
+ - feat: Add promo code option used for signup flows (#223)
13
+
3
14
  ## 2.4.0
4
15
 
5
16
  - Raise nextjs version limit to include 13 (#206)
6
- - feat(react-native): Xcode plugin includes collect modules script ([#210](https://github.com/getsentry/sentry-wizard/pull/210))
17
+ - feat(react-native): Xcode plugin includes collect modules script (#210)
7
18
 
8
19
  ## 1.4.0
9
20
 
10
- - feat(react-native): Xcode plugin includes collect modules script ([#213](https://github.com/getsentry/sentry-wizard/pull/213))
21
+ - feat(react-native): Xcode plugin includes collect modules script (#213)
11
22
 
12
23
  ## 2.3.1
13
24
 
package/README.md CHANGED
@@ -73,6 +73,8 @@ Options:
73
73
  [array] [choices: "ios", "android"]
74
74
  -u, --url The url to your Sentry installation
75
75
  env: SENTRY_WIZARD_URL [default: "https://sentry.io/"]
76
+ -s, --signup Redirect to signup page if not logged in
77
+ Use if don't have a Sentry account [boolean]
76
78
  ```
77
79
 
78
80
  ## Resources
package/bin.ts CHANGED
@@ -41,6 +41,16 @@ const argv = require('yargs')
41
41
  alias: 'url',
42
42
  default: DEFAULT_URL,
43
43
  describe: 'The url to your Sentry installation\nenv: SENTRY_WIZARD_URL',
44
+ })
45
+ .option('s', {
46
+ alias: 'signup',
47
+ default: false,
48
+ describe: 'Redirect to signup page if not logged in',
49
+ type: 'boolean',
50
+ })
51
+ .option('promo-code', {
52
+ alias: 'promo-code',
53
+ describe: 'A promo code that will be applied during signup',
44
54
  }).argv;
45
55
 
46
56
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
@@ -0,0 +1,17 @@
1
+ // This file configures the initialization of Sentry on the server.
2
+ // The config you add here will be used whenever middleware or an Edge route handles a request.
3
+ // https://docs.sentry.io/platforms/javascript/guides/nextjs/
4
+
5
+ import * as Sentry from '@sentry/nextjs';
6
+
7
+ const SENTRY_DSN = process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN;
8
+
9
+ Sentry.init({
10
+ dsn: SENTRY_DSN || '___DSN___',
11
+ // Adjust this value in production, or use tracesSampler for greater control
12
+ tracesSampleRate: 1.0,
13
+ // ...
14
+ // Note: if you want to override the automatic release value, do not set a
15
+ // `release` value here - use the environment variable `SENTRY_RELEASE`, so
16
+ // that it will also get attached to your source maps
17
+ });
package/dist/bin.js CHANGED
@@ -50,6 +50,16 @@ var argv = require('yargs')
50
50
  alias: 'url',
51
51
  default: Constants_1.DEFAULT_URL,
52
52
  describe: 'The url to your Sentry installation\nenv: SENTRY_WIZARD_URL',
53
+ })
54
+ .option('s', {
55
+ alias: 'signup',
56
+ default: false,
57
+ describe: 'Redirect to signup page if not logged in',
58
+ type: 'boolean',
59
+ })
60
+ .option('promo-code', {
61
+ alias: 'promo-code',
62
+ describe: 'A promo code that will be applied during signup',
53
63
  }).argv;
54
64
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
55
65
  Setup_1.run(argv);
package/dist/bin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bin.js","sourceRoot":"","sources":["../bin.ts"],"names":[],"mappings":";;;;;;;;;;;;;AACA,6CAAqE;AACrE,qCAAkC;AAClC,8CAA4B;AAE5B,IAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC;KAC1B,MAAM,CAAC,OAAO,EAAE;IACf,OAAO,EAAE,KAAK;IACd,QAAQ,EAAE,kDAAkD;IAC5D,IAAI,EAAE,SAAS;CAChB,CAAC;KACD,MAAM,CAAC,WAAW,EAAE;IACnB,OAAO,EAAE,KAAK;IACd,QAAQ,EAAE,4DAA4D;IACtE,IAAI,EAAE,SAAS;CAChB,CAAC;KACD,MAAM,CAAC,cAAc,EAAE;IACtB,OAAO,EAAE,KAAK;IACd,QAAQ,EACN,qEAAqE;IACvE,IAAI,EAAE,SAAS;CAChB,CAAC;KACD,MAAM,CAAC,OAAO,EAAE;IACf,OAAO,EAAE,KAAK;IACd,QAAQ,EACN,8EAA8E;IAChF,IAAI,EAAE,SAAS;CAChB,CAAC;KACD,MAAM,CAAC,GAAG,EAAE;IACX,KAAK,EAAE,aAAa;IACpB,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,uBAAW,CAAC;IACjC,QAAQ,EAAE,iEAAiE;CAC5E,CAAC;KACD,MAAM,CAAC,GAAG,EAAE;IACX,KAAK,EAAE,UAAU;IACjB,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,oBAAQ,CAAC;IAC9B,QAAQ,EAAE,iDAAiD;IAC3D,IAAI,EAAE,OAAO;CACd,CAAC;KACD,MAAM,CAAC,GAAG,EAAE;IACX,KAAK,EAAE,KAAK;IACZ,OAAO,EAAE,uBAAW;IACpB,QAAQ,EAAE,6DAA6D;CACxE,CAAC,CAAC,IAAI,CAAC;AAEV,mEAAmE;AACnE,WAAG,CAAC,IAAI,CAAC,CAAC","sourcesContent":["#!/usr/bin/env node\nimport { DEFAULT_URL, Integration, Platform } from './lib/Constants';\nimport { run } from './lib/Setup';\nexport * from './lib/Setup';\n\nconst argv = require('yargs')\n .option('debug', {\n default: false,\n describe: 'Enable verbose logging\\nenv: SENTRY_WIZARD_DEBUG',\n type: 'boolean',\n })\n .option('uninstall', {\n default: false,\n describe: 'Revert project setup process\\nenv: SENTRY_WIZARD_UNINSTALL',\n type: 'boolean',\n })\n .option('skip-connect', {\n default: false,\n describe:\n 'Skips the connection to the server\\nenv: SENTRY_WIZARD_SKIP_CONNECT',\n type: 'boolean',\n })\n .option('quiet', {\n default: false,\n describe:\n 'Do not fallback to prompting user asking questions\\nenv: SENTRY_WIZARD_QUIET',\n type: 'boolean',\n })\n .option('i', {\n alias: 'integration',\n choices: Object.keys(Integration),\n describe: 'Choose the integration to setup\\nenv: SENTRY_WIZARD_INTEGRATION',\n })\n .option('p', {\n alias: 'platform',\n choices: Object.keys(Platform),\n describe: 'Choose platform(s)\\nenv: SENTRY_WIZARD_PLATFORM',\n type: 'array',\n })\n .option('u', {\n alias: 'url',\n default: DEFAULT_URL,\n describe: 'The url to your Sentry installation\\nenv: SENTRY_WIZARD_URL',\n }).argv;\n\n// eslint-disable-next-line @typescript-eslint/no-floating-promises\nrun(argv);\n"]}
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../bin.ts"],"names":[],"mappings":";;;;;;;;;;;;;AACA,6CAAqE;AACrE,qCAAkC;AAClC,8CAA4B;AAE5B,IAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC;KAC1B,MAAM,CAAC,OAAO,EAAE;IACf,OAAO,EAAE,KAAK;IACd,QAAQ,EAAE,kDAAkD;IAC5D,IAAI,EAAE,SAAS;CAChB,CAAC;KACD,MAAM,CAAC,WAAW,EAAE;IACnB,OAAO,EAAE,KAAK;IACd,QAAQ,EAAE,4DAA4D;IACtE,IAAI,EAAE,SAAS;CAChB,CAAC;KACD,MAAM,CAAC,cAAc,EAAE;IACtB,OAAO,EAAE,KAAK;IACd,QAAQ,EACN,qEAAqE;IACvE,IAAI,EAAE,SAAS;CAChB,CAAC;KACD,MAAM,CAAC,OAAO,EAAE;IACf,OAAO,EAAE,KAAK;IACd,QAAQ,EACN,8EAA8E;IAChF,IAAI,EAAE,SAAS;CAChB,CAAC;KACD,MAAM,CAAC,GAAG,EAAE;IACX,KAAK,EAAE,aAAa;IACpB,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,uBAAW,CAAC;IACjC,QAAQ,EAAE,iEAAiE;CAC5E,CAAC;KACD,MAAM,CAAC,GAAG,EAAE;IACX,KAAK,EAAE,UAAU;IACjB,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,oBAAQ,CAAC;IAC9B,QAAQ,EAAE,iDAAiD;IAC3D,IAAI,EAAE,OAAO;CACd,CAAC;KACD,MAAM,CAAC,GAAG,EAAE;IACX,KAAK,EAAE,KAAK;IACZ,OAAO,EAAE,uBAAW;IACpB,QAAQ,EAAE,6DAA6D;CACxE,CAAC;KACD,MAAM,CAAC,GAAG,EAAE;IACX,KAAK,EAAE,QAAQ;IACf,OAAO,EAAE,KAAK;IACd,QAAQ,EAAE,0CAA0C;IACpD,IAAI,EAAE,SAAS;CAChB,CAAC;KACD,MAAM,CAAC,YAAY,EAAE;IACpB,KAAK,EAAE,YAAY;IACnB,QAAQ,EAAE,iDAAiD;CAC5D,CAAC,CAAC,IAAI,CAAC;AAEV,mEAAmE;AACnE,WAAG,CAAC,IAAI,CAAC,CAAC","sourcesContent":["#!/usr/bin/env node\nimport { DEFAULT_URL, Integration, Platform } from './lib/Constants';\nimport { run } from './lib/Setup';\nexport * from './lib/Setup';\n\nconst argv = require('yargs')\n .option('debug', {\n default: false,\n describe: 'Enable verbose logging\\nenv: SENTRY_WIZARD_DEBUG',\n type: 'boolean',\n })\n .option('uninstall', {\n default: false,\n describe: 'Revert project setup process\\nenv: SENTRY_WIZARD_UNINSTALL',\n type: 'boolean',\n })\n .option('skip-connect', {\n default: false,\n describe:\n 'Skips the connection to the server\\nenv: SENTRY_WIZARD_SKIP_CONNECT',\n type: 'boolean',\n })\n .option('quiet', {\n default: false,\n describe:\n 'Do not fallback to prompting user asking questions\\nenv: SENTRY_WIZARD_QUIET',\n type: 'boolean',\n })\n .option('i', {\n alias: 'integration',\n choices: Object.keys(Integration),\n describe: 'Choose the integration to setup\\nenv: SENTRY_WIZARD_INTEGRATION',\n })\n .option('p', {\n alias: 'platform',\n choices: Object.keys(Platform),\n describe: 'Choose platform(s)\\nenv: SENTRY_WIZARD_PLATFORM',\n type: 'array',\n })\n .option('u', {\n alias: 'url',\n default: DEFAULT_URL,\n describe: 'The url to your Sentry installation\\nenv: SENTRY_WIZARD_URL',\n })\n .option('s', {\n alias: 'signup',\n default: false,\n describe: 'Redirect to signup page if not logged in',\n type: 'boolean',\n })\n .option('promo-code', {\n alias: 'promo-code',\n describe: 'A promo code that will be applied during signup',\n }).argv;\n\n// eslint-disable-next-line @typescript-eslint/no-floating-promises\nrun(argv);\n"]}
@@ -13,6 +13,7 @@ export declare enum Platform {
13
13
  export declare function getPlatformChoices(): any[];
14
14
  export declare function getPlatformDescription(type: string): string;
15
15
  export declare function getIntegrationDescription(type: string): string;
16
+ export declare function mapIntegrationToPlatform(type: string): string;
16
17
  export declare function getIntegrationChoices(): any[];
17
18
  export interface Args {
18
19
  url: string;
@@ -22,5 +23,7 @@ export interface Args {
22
23
  platform: Platform[];
23
24
  skipConnect: boolean;
24
25
  quiet: boolean;
26
+ signup: boolean;
27
+ promoCode?: string;
25
28
  }
26
29
  export declare const DEFAULT_URL = "https://sentry.io/";
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DEFAULT_URL = exports.getIntegrationChoices = exports.getIntegrationDescription = exports.getPlatformDescription = exports.getPlatformChoices = exports.Platform = exports.Integration = void 0;
3
+ exports.DEFAULT_URL = exports.getIntegrationChoices = exports.mapIntegrationToPlatform = exports.getIntegrationDescription = exports.getPlatformDescription = exports.getPlatformChoices = exports.Platform = exports.Integration = void 0;
4
4
  /** Key value should be the same here */
5
5
  var Integration;
6
6
  (function (Integration) {
@@ -47,6 +47,21 @@ function getIntegrationDescription(type) {
47
47
  }
48
48
  }
49
49
  exports.getIntegrationDescription = getIntegrationDescription;
50
+ function mapIntegrationToPlatform(type) {
51
+ switch (type) {
52
+ case Integration.reactNative:
53
+ return 'react-native';
54
+ case Integration.cordova:
55
+ return 'cordova';
56
+ case Integration.electron:
57
+ return 'javascript-electron';
58
+ case Integration.nextjs:
59
+ return 'javascript-nextjs';
60
+ default:
61
+ throw new Error("Unknown integration " + type);
62
+ }
63
+ }
64
+ exports.mapIntegrationToPlatform = mapIntegrationToPlatform;
50
65
  function getIntegrationChoices() {
51
66
  return Object.keys(Integration).map(function (type) { return ({
52
67
  name: getIntegrationDescription(type),
@@ -1 +1 @@
1
- {"version":3,"file":"Constants.js","sourceRoot":"","sources":["../../lib/Constants.ts"],"names":[],"mappings":";;;AAAA,wCAAwC;AACxC,IAAY,WAKX;AALD,WAAY,WAAW;IACrB,0CAA2B,CAAA;IAC3B,kCAAmB,CAAA;IACnB,oCAAqB,CAAA;IACrB,gCAAiB,CAAA;AACnB,CAAC,EALW,WAAW,GAAX,mBAAW,KAAX,mBAAW,QAKtB;AAED,wCAAwC;AACxC,IAAY,QAGX;AAHD,WAAY,QAAQ;IAClB,uBAAW,CAAA;IACX,+BAAmB,CAAA;AACrB,CAAC,EAHW,QAAQ,GAAR,gBAAQ,KAAR,gBAAQ,QAGnB;AAED,SAAgB,kBAAkB;IAChC,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,UAAC,QAAgB,IAAK,OAAA,CAAC;QACtD,OAAO,EAAE,IAAI;QACb,IAAI,EAAE,sBAAsB,CAAC,QAAQ,CAAC;QACtC,KAAK,EAAE,QAAQ;KAChB,CAAC,EAJqD,CAIrD,CAAC,CAAC;AACN,CAAC;AAND,gDAMC;AAED,SAAgB,sBAAsB,CAAC,IAAY;IACjD,QAAQ,IAAI,EAAE;QACZ,KAAK,QAAQ,CAAC,GAAG;YACf,OAAO,KAAK,CAAC;QACf;YACE,OAAO,SAAS,CAAC;KACpB;AACH,CAAC;AAPD,wDAOC;AAED,SAAgB,yBAAyB,CAAC,IAAY;IACpD,QAAQ,IAAI,EAAE;QACZ,KAAK,WAAW,CAAC,WAAW;YAC1B,OAAO,cAAc,CAAC;QACxB,KAAK,WAAW,CAAC,OAAO;YACtB,OAAO,SAAS,CAAC;QACnB,KAAK,WAAW,CAAC,QAAQ;YACvB,OAAO,UAAU,CAAC;QACpB,KAAK,WAAW,CAAC,MAAM;YACrB,OAAO,SAAS,CAAC;QACnB;YACE,OAAO,cAAc,CAAC;KACzB;AACH,CAAC;AAbD,8DAaC;AAED,SAAgB,qBAAqB;IACnC,OAAO,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,UAAC,IAAY,IAAK,OAAA,CAAC;QACrD,IAAI,EAAE,yBAAyB,CAAC,IAAI,CAAC;QACrC,KAAK,EAAE,IAAI;KACZ,CAAC,EAHoD,CAGpD,CAAC,CAAC;AACN,CAAC;AALD,sDAKC;AAYY,QAAA,WAAW,GAAG,oBAAoB,CAAC","sourcesContent":["/** Key value should be the same here */\nexport enum Integration {\n reactNative = 'reactNative',\n cordova = 'cordova',\n electron = 'electron',\n nextjs = 'nextjs',\n}\n\n/** Key value should be the same here */\nexport enum Platform {\n ios = 'ios',\n android = 'android',\n}\n\nexport function getPlatformChoices(): any[] {\n return Object.keys(Platform).map((platform: string) => ({\n checked: true,\n name: getPlatformDescription(platform),\n value: platform,\n }));\n}\n\nexport function getPlatformDescription(type: string): string {\n switch (type) {\n case Platform.ios:\n return 'iOS';\n default:\n return 'Android';\n }\n}\n\nexport function getIntegrationDescription(type: string): string {\n switch (type) {\n case Integration.reactNative:\n return 'React Native';\n case Integration.cordova:\n return 'Cordova';\n case Integration.electron:\n return 'Electron';\n case Integration.nextjs:\n return 'Next.js';\n default:\n return 'React Native';\n }\n}\n\nexport function getIntegrationChoices(): any[] {\n return Object.keys(Integration).map((type: string) => ({\n name: getIntegrationDescription(type),\n value: type,\n }));\n}\n\nexport interface Args {\n url: string;\n debug: boolean;\n uninstall: boolean;\n integration: Integration;\n platform: Platform[];\n skipConnect: boolean;\n quiet: boolean;\n}\n\nexport const DEFAULT_URL = 'https://sentry.io/';\n"]}
1
+ {"version":3,"file":"Constants.js","sourceRoot":"","sources":["../../lib/Constants.ts"],"names":[],"mappings":";;;AAAA,wCAAwC;AACxC,IAAY,WAKX;AALD,WAAY,WAAW;IACrB,0CAA2B,CAAA;IAC3B,kCAAmB,CAAA;IACnB,oCAAqB,CAAA;IACrB,gCAAiB,CAAA;AACnB,CAAC,EALW,WAAW,GAAX,mBAAW,KAAX,mBAAW,QAKtB;AAED,wCAAwC;AACxC,IAAY,QAGX;AAHD,WAAY,QAAQ;IAClB,uBAAW,CAAA;IACX,+BAAmB,CAAA;AACrB,CAAC,EAHW,QAAQ,GAAR,gBAAQ,KAAR,gBAAQ,QAGnB;AAED,SAAgB,kBAAkB;IAChC,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,UAAC,QAAgB,IAAK,OAAA,CAAC;QACtD,OAAO,EAAE,IAAI;QACb,IAAI,EAAE,sBAAsB,CAAC,QAAQ,CAAC;QACtC,KAAK,EAAE,QAAQ;KAChB,CAAC,EAJqD,CAIrD,CAAC,CAAC;AACN,CAAC;AAND,gDAMC;AAED,SAAgB,sBAAsB,CAAC,IAAY;IACjD,QAAQ,IAAI,EAAE;QACZ,KAAK,QAAQ,CAAC,GAAG;YACf,OAAO,KAAK,CAAC;QACf;YACE,OAAO,SAAS,CAAC;KACpB;AACH,CAAC;AAPD,wDAOC;AAED,SAAgB,yBAAyB,CAAC,IAAY;IACpD,QAAQ,IAAI,EAAE;QACZ,KAAK,WAAW,CAAC,WAAW;YAC1B,OAAO,cAAc,CAAC;QACxB,KAAK,WAAW,CAAC,OAAO;YACtB,OAAO,SAAS,CAAC;QACnB,KAAK,WAAW,CAAC,QAAQ;YACvB,OAAO,UAAU,CAAC;QACpB,KAAK,WAAW,CAAC,MAAM;YACrB,OAAO,SAAS,CAAC;QACnB;YACE,OAAO,cAAc,CAAC;KACzB;AACH,CAAC;AAbD,8DAaC;AAED,SAAgB,wBAAwB,CAAC,IAAY;IACnD,QAAQ,IAAI,EAAE;QACZ,KAAK,WAAW,CAAC,WAAW;YAC1B,OAAO,cAAc,CAAC;QACxB,KAAK,WAAW,CAAC,OAAO;YACtB,OAAO,SAAS,CAAC;QACnB,KAAK,WAAW,CAAC,QAAQ;YACvB,OAAO,qBAAqB,CAAC;QAC/B,KAAK,WAAW,CAAC,MAAM;YACrB,OAAO,mBAAmB,CAAC;QAC7B;YACE,MAAM,IAAI,KAAK,CAAC,yBAAuB,IAAM,CAAC,CAAC;KAClD;AACH,CAAC;AAbD,4DAaC;AAED,SAAgB,qBAAqB;IACnC,OAAO,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,UAAC,IAAY,IAAK,OAAA,CAAC;QACrD,IAAI,EAAE,yBAAyB,CAAC,IAAI,CAAC;QACrC,KAAK,EAAE,IAAI;KACZ,CAAC,EAHoD,CAGpD,CAAC,CAAC;AACN,CAAC;AALD,sDAKC;AAcY,QAAA,WAAW,GAAG,oBAAoB,CAAC","sourcesContent":["/** Key value should be the same here */\nexport enum Integration {\n reactNative = 'reactNative',\n cordova = 'cordova',\n electron = 'electron',\n nextjs = 'nextjs',\n}\n\n/** Key value should be the same here */\nexport enum Platform {\n ios = 'ios',\n android = 'android',\n}\n\nexport function getPlatformChoices(): any[] {\n return Object.keys(Platform).map((platform: string) => ({\n checked: true,\n name: getPlatformDescription(platform),\n value: platform,\n }));\n}\n\nexport function getPlatformDescription(type: string): string {\n switch (type) {\n case Platform.ios:\n return 'iOS';\n default:\n return 'Android';\n }\n}\n\nexport function getIntegrationDescription(type: string): string {\n switch (type) {\n case Integration.reactNative:\n return 'React Native';\n case Integration.cordova:\n return 'Cordova';\n case Integration.electron:\n return 'Electron';\n case Integration.nextjs:\n return 'Next.js';\n default:\n return 'React Native';\n }\n}\n\nexport function mapIntegrationToPlatform(type: string): string {\n switch (type) {\n case Integration.reactNative:\n return 'react-native';\n case Integration.cordova:\n return 'cordova';\n case Integration.electron:\n return 'javascript-electron';\n case Integration.nextjs:\n return 'javascript-nextjs';\n default:\n throw new Error(`Unknown integration ${type}`);\n }\n}\n\nexport function getIntegrationChoices(): any[] {\n return Object.keys(Integration).map((type: string) => ({\n name: getIntegrationDescription(type),\n value: type,\n }));\n}\n\nexport interface Args {\n url: string;\n debug: boolean;\n uninstall: boolean;\n integration: Integration;\n platform: Platform[];\n skipConnect: boolean;\n quiet: boolean;\n signup: boolean;\n promoCode?: string;\n}\n\nexport const DEFAULT_URL = 'https://sentry.io/';\n"]}
@@ -72,6 +72,8 @@ function sanitizeAndValidateArgs(argv) {
72
72
  // @ts-ignore skip-connect does not exist on args
73
73
  delete argv['skip-connect'];
74
74
  }
75
+ // @ts-ignore skip-connect does not exist on args
76
+ argv.promoCode = argv['promo-code'];
75
77
  }
76
78
  function getCurrentIntegration(answers) {
77
79
  return _.get(answers, 'integration');
@@ -1 +1 @@
1
- {"version":3,"file":"Wizard.js","sourceRoot":"","sources":["../../../lib/Helper/Wizard.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,0BAA4B;AAE5B,0CAAiD;AAGjD,yCAAwC;AACxC,qCAAgD;AAEhD,SAAS,uBAAuB,CAAC,IAAU;IACzC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,GAAG,GAAG,uBAAW,CAAC;QACvB,aAAG,CAAC,kCAAgC,IAAI,CAAC,GAAK,CAAC,CAAC;KACjD;IACD,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE;QAC5B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,aAAG,CAAC,kCAAkC,CAAC,CAAC;KACzC;IACD,IAAI,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC;IACvB,OAAO,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;IAC5C,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;IAC/C,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC;IACnB,iDAAiD;IACjD,IAAI,IAAI,CAAC,cAAc,CAAC,EAAE;QACxB,iDAAiD;QACjD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC;QACxC,iDAAiD;QACjD,OAAO,IAAI,CAAC,cAAc,CAAC,CAAC;KAC7B;AACH,CAAC;AAED,SAAgB,qBAAqB,CAAC,OAAgB;IACpD,OAAO,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,aAAa,CAAoB,CAAC;AAC1D,CAAC;AAFD,sDAEC;AAED,SAAsB,WAAW,CAC/B,IAAU;IACV,eAAyC;SAAzC,UAAyC,EAAzC,qBAAyC,EAAzC,IAAyC;QAAzC,8BAAyC;;;;;;;;;oBAGvC,uBAAuB,CAAC,IAAI,CAAC,CAAC;oBAC9B,IAAI,IAAI,CAAC,KAAK,EAAE;wBACd,eAAK,CAAC,IAAI,CAAC,CAAC;qBACb;oBACD,IAAI,IAAI,CAAC,KAAK,EAAE;wBACd,aAAG,CAAC,4CAA4C,CAAC,CAAC;qBACnD;oBACM,qBAAM,KAAK;6BACf,GAAG,CAAC,UAAA,IAAI,IAAI,OAAA,IAAI,IAAI,CAAC,IAAI,CAAC,EAAd,CAAc,CAAC;6BAC3B,MAAM,CAAC,UAAO,MAAM,EAAE,IAAI;;;;4CACN,qBAAM,MAAM,EAAA;;wCAAzB,UAAU,GAAG,SAAY;wCACf,qBAAM,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,EAAA;;wCAArC,OAAO,GAAG,SAA2B;wCAC3C,4CAAY,UAAU,GAAK,OAAO,GAAG;;;6BACtC,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAA;wBANzB,sBAAO,SAMkB,EAAC;;;oBAE1B,qBAAS,CAAC,IAAI,EAAE,CAAC;oBACjB,YAAE,EAAE,CAAC;oBACL,aAAG,CAAC,4BAA4B,CAAC,CAAC;oBAClC,aAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,GAAC,CAAC,OAAO,CAAC,CAAC;oBAChC,YAAE,EAAE,CAAC;oBACL,aAAG,CAAC,2CAA2C,CAAC,CAAC;oBACjD,aAAG,CAAC,mCAAmC,CAAC,CAAC;oBACzC,sBAAO,EAAE,EAAC;;;;;CAEb;AA7BD,kCA6BC","sourcesContent":["import { Answers } from 'inquirer';\nimport * as _ from 'lodash';\n\nimport { Args, DEFAULT_URL } from '../Constants';\nimport { IStep } from '../Steps/BaseStep';\nimport { BaseIntegration } from '../Steps/Integrations/BaseIntegration';\nimport { BottomBar } from './BottomBar';\nimport { debug, dim, nl, red } from './Logging';\n\nfunction sanitizeAndValidateArgs(argv: Args): void {\n if (!argv.url) {\n argv.url = DEFAULT_URL;\n dim(`no URL provided, fallback to ${argv.url}`);\n }\n if (argv.quiet === undefined) {\n argv.quiet = true;\n dim('will activate quiet mode for you');\n }\n let baseUrl = argv.url;\n baseUrl += baseUrl.endsWith('/') ? '' : '/';\n baseUrl = baseUrl.replace(/:\\/(?!\\/)/g, '://');\n argv.url = baseUrl;\n // @ts-ignore skip-connect does not exist on args\n if (argv['skip-connect']) {\n // @ts-ignore skip-connect does not exist on args\n argv.skipConnect = argv['skip-connect'];\n // @ts-ignore skip-connect does not exist on args\n delete argv['skip-connect'];\n }\n}\n\nexport function getCurrentIntegration(answers: Answers): BaseIntegration {\n return _.get(answers, 'integration') as BaseIntegration;\n}\n\nexport async function startWizard<M extends IStep>(\n argv: Args,\n ...steps: Array<{ new (debug: Args): M }>\n): Promise<Answers> {\n try {\n sanitizeAndValidateArgs(argv);\n if (argv.debug) {\n debug(argv);\n }\n if (argv.quiet) {\n dim(\"Quiet mode On, DAMA, don't ask me anything\");\n }\n return await steps\n .map(step => new step(argv))\n .reduce(async (answer, step) => {\n const prevAnswer = await answer;\n const answers = await step.emit(prevAnswer);\n return { ...prevAnswer, ...answers };\n }, Promise.resolve({}));\n } catch (e) {\n BottomBar.hide();\n nl();\n red('Sentry Wizard failed with:');\n red(argv.debug ? e : e.message);\n nl();\n red('Protip: Add --debug to see whats going on');\n red('OR use --help to see your options');\n return {};\n }\n}\n"]}
1
+ {"version":3,"file":"Wizard.js","sourceRoot":"","sources":["../../../lib/Helper/Wizard.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,0BAA4B;AAE5B,0CAAiD;AAGjD,yCAAwC;AACxC,qCAAgD;AAEhD,SAAS,uBAAuB,CAAC,IAAU;IACzC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,GAAG,GAAG,uBAAW,CAAC;QACvB,aAAG,CAAC,kCAAgC,IAAI,CAAC,GAAK,CAAC,CAAC;KACjD;IACD,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE;QAC5B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,aAAG,CAAC,kCAAkC,CAAC,CAAC;KACzC;IACD,IAAI,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC;IACvB,OAAO,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;IAC5C,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;IAC/C,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC;IACnB,iDAAiD;IACjD,IAAI,IAAI,CAAC,cAAc,CAAC,EAAE;QACxB,iDAAiD;QACjD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC;QACxC,iDAAiD;QACjD,OAAO,IAAI,CAAC,cAAc,CAAC,CAAC;KAC7B;IACD,iDAAiD;IACjD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC;AACtC,CAAC;AAED,SAAgB,qBAAqB,CAAC,OAAgB;IACpD,OAAO,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,aAAa,CAAoB,CAAC;AAC1D,CAAC;AAFD,sDAEC;AAED,SAAsB,WAAW,CAC/B,IAAU;IACV,eAAyC;SAAzC,UAAyC,EAAzC,qBAAyC,EAAzC,IAAyC;QAAzC,8BAAyC;;;;;;;;;oBAGvC,uBAAuB,CAAC,IAAI,CAAC,CAAC;oBAC9B,IAAI,IAAI,CAAC,KAAK,EAAE;wBACd,eAAK,CAAC,IAAI,CAAC,CAAC;qBACb;oBACD,IAAI,IAAI,CAAC,KAAK,EAAE;wBACd,aAAG,CAAC,4CAA4C,CAAC,CAAC;qBACnD;oBACM,qBAAM,KAAK;6BACf,GAAG,CAAC,UAAA,IAAI,IAAI,OAAA,IAAI,IAAI,CAAC,IAAI,CAAC,EAAd,CAAc,CAAC;6BAC3B,MAAM,CAAC,UAAO,MAAM,EAAE,IAAI;;;;4CACN,qBAAM,MAAM,EAAA;;wCAAzB,UAAU,GAAG,SAAY;wCACf,qBAAM,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,EAAA;;wCAArC,OAAO,GAAG,SAA2B;wCAC3C,4CAAY,UAAU,GAAK,OAAO,GAAG;;;6BACtC,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAA;wBANzB,sBAAO,SAMkB,EAAC;;;oBAE1B,qBAAS,CAAC,IAAI,EAAE,CAAC;oBACjB,YAAE,EAAE,CAAC;oBACL,aAAG,CAAC,4BAA4B,CAAC,CAAC;oBAClC,aAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAC,CAAC,CAAC,CAAC,GAAC,CAAC,OAAO,CAAC,CAAC;oBAChC,YAAE,EAAE,CAAC;oBACL,aAAG,CAAC,2CAA2C,CAAC,CAAC;oBACjD,aAAG,CAAC,mCAAmC,CAAC,CAAC;oBACzC,sBAAO,EAAE,EAAC;;;;;CAEb;AA7BD,kCA6BC","sourcesContent":["import { Answers } from 'inquirer';\nimport * as _ from 'lodash';\n\nimport { Args, DEFAULT_URL } from '../Constants';\nimport { IStep } from '../Steps/BaseStep';\nimport { BaseIntegration } from '../Steps/Integrations/BaseIntegration';\nimport { BottomBar } from './BottomBar';\nimport { debug, dim, nl, red } from './Logging';\n\nfunction sanitizeAndValidateArgs(argv: Args): void {\n if (!argv.url) {\n argv.url = DEFAULT_URL;\n dim(`no URL provided, fallback to ${argv.url}`);\n }\n if (argv.quiet === undefined) {\n argv.quiet = true;\n dim('will activate quiet mode for you');\n }\n let baseUrl = argv.url;\n baseUrl += baseUrl.endsWith('/') ? '' : '/';\n baseUrl = baseUrl.replace(/:\\/(?!\\/)/g, '://');\n argv.url = baseUrl;\n // @ts-ignore skip-connect does not exist on args\n if (argv['skip-connect']) {\n // @ts-ignore skip-connect does not exist on args\n argv.skipConnect = argv['skip-connect'];\n // @ts-ignore skip-connect does not exist on args\n delete argv['skip-connect'];\n }\n // @ts-ignore skip-connect does not exist on args\n argv.promoCode = argv['promo-code'];\n}\n\nexport function getCurrentIntegration(answers: Answers): BaseIntegration {\n return _.get(answers, 'integration') as BaseIntegration;\n}\n\nexport async function startWizard<M extends IStep>(\n argv: Args,\n ...steps: Array<{ new (debug: Args): M }>\n): Promise<Answers> {\n try {\n sanitizeAndValidateArgs(argv);\n if (argv.debug) {\n debug(argv);\n }\n if (argv.quiet) {\n dim(\"Quiet mode On, DAMA, don't ask me anything\");\n }\n return await steps\n .map(step => new step(argv))\n .reduce(async (answer, step) => {\n const prevAnswer = await answer;\n const answers = await step.emit(prevAnswer);\n return { ...prevAnswer, ...answers };\n }, Promise.resolve({}));\n } catch (e) {\n BottomBar.hide();\n nl();\n red('Sentry Wizard failed with:');\n red(argv.debug ? e : e.message);\n nl();\n red('Protip: Add --debug to see whats going on');\n red('OR use --help to see your options');\n return {};\n }\n}\n"]}
@@ -10,6 +10,7 @@ var args = {
10
10
  skipConnect: false,
11
11
  uninstall: false,
12
12
  url: 'https://localhost:1234',
13
+ signup: false,
13
14
  };
14
15
  var demoAnswers = {
15
16
  config: {
@@ -1 +1 @@
1
- {"version":3,"file":"SentryCli.js","sourceRoot":"","sources":["../../../../lib/Helper/__tests__/SentryCli.ts"],"names":[],"mappings":"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","sourcesContent":["/// <reference types=\"jest\" />\nimport { Answers } from 'inquirer';\n\nimport { Args, Integration, Platform } from '../../Constants';\nimport { SentryCli } from '../SentryCli';\n\nconst args: Args = {\n debug: false,\n integration: Integration.reactNative,\n platform: [Platform.ios],\n quiet: false,\n skipConnect: false,\n uninstall: false,\n url: 'https://localhost:1234',\n};\n\nconst demoAnswers: Answers = {\n config: {\n auth: {\n token: 'abcd',\n },\n organization: {\n slug: 'test_org',\n },\n project: {\n slug: 'test_proj',\n },\n },\n};\n\ndescribe('SentryCli', () => {\n test('convertAnswersToProperties', () => {\n const resolveFunc = jest.fn().mockReturnValue('node_modules/sentry/cli');\n const sentry = new SentryCli(args);\n sentry.setResolveFunction(resolveFunc);\n const props = sentry.convertAnswersToProperties(demoAnswers);\n expect(props['defaults/url']).toBe('https://localhost:1234');\n expect(props['defaults/org']).toBe('test_org');\n expect(props['defaults/project']).toBe('test_proj');\n expect(props['auth/token']).toBe('abcd');\n expect(props['cli/executable']).toBe('node_modules/sentry/cli');\n });\n\n test('dump properties', () => {\n const resolveFunc = jest.fn().mockReturnValue('node_modules/sentry/cli');\n const sentry = new SentryCli(args);\n sentry.setResolveFunction(resolveFunc);\n const props = sentry.convertAnswersToProperties(demoAnswers);\n expect(sentry.dumpProperties(props))\n .toBe(`defaults.url=https://localhost:1234\ndefaults.org=test_org\ndefaults.project=test_proj\nauth.token=abcd\ncli.executable=node_modules/sentry/cli\n`);\n });\n\n test('convertAnswersToProperties windows', () => {\n const resolveFunc = jest.fn().mockReturnValue('node_modules\\\\sentry\\\\cli');\n const sentry = new SentryCli(args);\n sentry.setResolveFunction(resolveFunc);\n const props = sentry.convertAnswersToProperties(demoAnswers);\n expect(props['defaults/url']).toBe('https://localhost:1234');\n expect(props['defaults/org']).toBe('test_org');\n expect(props['defaults/project']).toBe('test_proj');\n expect(props['auth/token']).toBe('abcd');\n expect(props['cli/executable']).toBe('node_modules\\\\\\\\sentry\\\\\\\\cli');\n });\n\n test('dump properties windows', () => {\n const resolveFunc = jest.fn().mockReturnValue('node_modules\\\\sentry\\\\cli');\n const sentry = new SentryCli(args);\n sentry.setResolveFunction(resolveFunc);\n const props = sentry.convertAnswersToProperties(demoAnswers);\n expect(sentry.dumpProperties(props))\n .toBe(`defaults.url=https://localhost:1234\ndefaults.org=test_org\ndefaults.project=test_proj\nauth.token=abcd\ncli.executable=node_modules\\\\\\\\sentry\\\\\\\\cli\n`);\n });\n});\n"]}
1
+ {"version":3,"file":"SentryCli.js","sourceRoot":"","sources":["../../../../lib/Helper/__tests__/SentryCli.ts"],"names":[],"mappings":"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","sourcesContent":["/// <reference types=\"jest\" />\nimport { Answers } from 'inquirer';\n\nimport { Args, Integration, Platform } from '../../Constants';\nimport { SentryCli } from '../SentryCli';\n\nconst args: Args = {\n debug: false,\n integration: Integration.reactNative,\n platform: [Platform.ios],\n quiet: false,\n skipConnect: false,\n uninstall: false,\n url: 'https://localhost:1234',\n signup: false,\n};\n\nconst demoAnswers: Answers = {\n config: {\n auth: {\n token: 'abcd',\n },\n organization: {\n slug: 'test_org',\n },\n project: {\n slug: 'test_proj',\n },\n },\n};\n\ndescribe('SentryCli', () => {\n test('convertAnswersToProperties', () => {\n const resolveFunc = jest.fn().mockReturnValue('node_modules/sentry/cli');\n const sentry = new SentryCli(args);\n sentry.setResolveFunction(resolveFunc);\n const props = sentry.convertAnswersToProperties(demoAnswers);\n expect(props['defaults/url']).toBe('https://localhost:1234');\n expect(props['defaults/org']).toBe('test_org');\n expect(props['defaults/project']).toBe('test_proj');\n expect(props['auth/token']).toBe('abcd');\n expect(props['cli/executable']).toBe('node_modules/sentry/cli');\n });\n\n test('dump properties', () => {\n const resolveFunc = jest.fn().mockReturnValue('node_modules/sentry/cli');\n const sentry = new SentryCli(args);\n sentry.setResolveFunction(resolveFunc);\n const props = sentry.convertAnswersToProperties(demoAnswers);\n expect(sentry.dumpProperties(props))\n .toBe(`defaults.url=https://localhost:1234\ndefaults.org=test_org\ndefaults.project=test_proj\nauth.token=abcd\ncli.executable=node_modules/sentry/cli\n`);\n });\n\n test('convertAnswersToProperties windows', () => {\n const resolveFunc = jest.fn().mockReturnValue('node_modules\\\\sentry\\\\cli');\n const sentry = new SentryCli(args);\n sentry.setResolveFunction(resolveFunc);\n const props = sentry.convertAnswersToProperties(demoAnswers);\n expect(props['defaults/url']).toBe('https://localhost:1234');\n expect(props['defaults/org']).toBe('test_org');\n expect(props['defaults/project']).toBe('test_proj');\n expect(props['auth/token']).toBe('abcd');\n expect(props['cli/executable']).toBe('node_modules\\\\\\\\sentry\\\\\\\\cli');\n });\n\n test('dump properties windows', () => {\n const resolveFunc = jest.fn().mockReturnValue('node_modules\\\\sentry\\\\cli');\n const sentry = new SentryCli(args);\n sentry.setResolveFunction(resolveFunc);\n const props = sentry.convertAnswersToProperties(demoAnswers);\n expect(sentry.dumpProperties(props))\n .toBe(`defaults.url=https://localhost:1234\ndefaults.org=test_org\ndefaults.project=test_proj\nauth.token=abcd\ncli.executable=node_modules\\\\\\\\sentry\\\\\\\\cli\n`);\n });\n});\n"]}
@@ -13,6 +13,10 @@ export declare class NextJs extends BaseIntegration {
13
13
  private _createNextConfig;
14
14
  private _setTemplate;
15
15
  private _fillAndCopyTemplate;
16
+ private _hasPackageInstalled;
17
+ private _getPackageMangerChoice;
18
+ private _getInstallCommand;
19
+ private _installPackage;
16
20
  private _checkPackageVersion;
17
21
  private _fulfillsVersionRange;
18
22
  private _spliceInPlace;
@@ -70,11 +70,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
70
70
  exports.NextJs = void 0;
71
71
  /* eslint-disable max-lines */
72
72
  var chalk_1 = require("chalk");
73
+ var child_process_1 = require("child_process");
73
74
  var fs = require("fs");
74
75
  var inquirer_1 = require("inquirer");
75
76
  var _ = require("lodash");
76
77
  var path = require("path");
77
78
  var semver_1 = require("semver");
79
+ var util_1 = require("util");
78
80
  var Logging_1 = require("../../Helper/Logging");
79
81
  var SentryCli_1 = require("../../Helper/SentryCli");
80
82
  var BaseIntegration_1 = require("./BaseIntegration");
@@ -92,6 +94,7 @@ var TEMPLATE_DESTINATIONS = {
92
94
  'next.config.js': ['.'],
93
95
  'sentry.server.config.js': ['.'],
94
96
  'sentry.client.config.js': ['.'],
97
+ 'sentry.edge.config.js': ['.'],
95
98
  };
96
99
  var appPackage = {};
97
100
  try {
@@ -135,7 +138,7 @@ var NextJs = /** @class */ (function (_super) {
135
138
  hasFirstEvent = (_f = (_e = (_d = (_c = answers.wizard) === null || _c === void 0 ? void 0 : _c.projects) === null || _d === void 0 ? void 0 : _d.find) === null || _e === void 0 ? void 0 : _e.call(_d, function (p) { return p.slug === selectedProjectSlug; })) === null || _f === void 0 ? void 0 : _f.firstEvent;
136
139
  if (!hasFirstEvent) {
137
140
  this._setTemplate(templateDirectory, 'sentry_sample_error.js', ['pages', 'src/pages'], dsn);
138
- Logging_1.l(chalk_1.default.bgYellowBright("\n|------------------------------------------------------------------------|\n| Installation Complete |\n| To verify your installation and finish onboarding, launch your Next.js |\n| application, navigate to https://localhost:3000/sentry_sample_error |\n| and send us a sample error. |\n|------------------------------------------------------------------------|\n"));
141
+ Logging_1.l(chalk_1.default.bgYellowBright("\n|------------------------------------------------------------------------|\n| Installation Complete |\n| To verify your installation and finish onboarding, launch your Next.js |\n| application, navigate to http://localhost:3000/sentry_sample_error |\n| and send us a sample error. |\n|------------------------------------------------------------------------|\n"));
139
142
  }
140
143
  }
141
144
  Logging_1.l('For more information, see https://docs.sentry.io/platforms/javascript/guides/nextjs/');
@@ -147,7 +150,7 @@ var NextJs = /** @class */ (function (_super) {
147
150
  };
148
151
  NextJs.prototype.shouldConfigure = function (_answers) {
149
152
  return __awaiter(this, void 0, void 0, function () {
150
- var userAnswers, hasCompatibleNextjsVersion, hasCompatibleSdkVersion, hasAllPackagesCompatible;
153
+ var userAnswers, hasCompatibleNextjsVersion, packageManager, hasSdkInstalled, hasCompatibleSdkVersion, hasAllPackagesCompatible;
151
154
  return __generator(this, function (_a) {
152
155
  switch (_a.label) {
153
156
  case 0:
@@ -157,19 +160,33 @@ var NextJs = /** @class */ (function (_super) {
157
160
  Logging_1.nl();
158
161
  userAnswers = { continue: true };
159
162
  hasCompatibleNextjsVersion = this._checkPackageVersion('next', COMPATIBLE_NEXTJS_VERSIONS, true);
163
+ packageManager = this._getPackageMangerChoice();
164
+ hasSdkInstalled = this._hasPackageInstalled('@sentry/nextjs');
165
+ hasCompatibleSdkVersion = false;
166
+ if (!(!hasSdkInstalled && packageManager && hasCompatibleNextjsVersion)) return [3 /*break*/, 2];
167
+ return [4 /*yield*/, this._installPackage('@sentry/nextjs', packageManager)];
168
+ case 1:
169
+ _a.sent();
170
+ // can assume it's compatible since we just installed it
171
+ hasCompatibleSdkVersion = true;
172
+ return [3 /*break*/, 3];
173
+ case 2:
174
+ // otherwise, let's check the version and spit out the appropriate error
160
175
  hasCompatibleSdkVersion = this._checkPackageVersion('@sentry/nextjs', COMPATIBLE_SDK_VERSIONS, true);
176
+ _a.label = 3;
177
+ case 3:
161
178
  hasAllPackagesCompatible = hasCompatibleNextjsVersion && hasCompatibleSdkVersion;
162
- if (!(!hasAllPackagesCompatible && !this._argv.quiet)) return [3 /*break*/, 2];
179
+ if (!(!hasAllPackagesCompatible && !this._argv.quiet)) return [3 /*break*/, 5];
163
180
  return [4 /*yield*/, inquirer_1.prompt({
164
181
  message: 'There were errors during your project checkup, do you still want to continue?',
165
182
  name: 'continue',
166
183
  default: false,
167
184
  type: 'confirm',
168
185
  })];
169
- case 1:
186
+ case 4:
170
187
  userAnswers = _a.sent();
171
- _a.label = 2;
172
- case 2:
188
+ _a.label = 5;
189
+ case 5:
173
190
  Logging_1.nl();
174
191
  if (!userAnswers['continue']) {
175
192
  throw new Error('Please install the required dependencies to continue.');
@@ -301,6 +318,51 @@ var NextJs = /** @class */ (function (_super) {
301
318
  var filledTemplate = templateContent.replace('___DSN___', dsn);
302
319
  fs.writeFileSync(targetPath, filledTemplate);
303
320
  };
321
+ NextJs.prototype._hasPackageInstalled = function (packageName) {
322
+ var depsVersion = _.get(appPackage, ['dependencies', packageName]);
323
+ var devDepsVersion = _.get(appPackage, ['devDependencies', packageName]);
324
+ return !!depsVersion || !!devDepsVersion;
325
+ };
326
+ NextJs.prototype._getPackageMangerChoice = function () {
327
+ if (fs.existsSync(path.join(process.cwd(), 'yarn.lock'))) {
328
+ return 'yarn';
329
+ }
330
+ if (fs.existsSync(path.join(process.cwd(), 'pnpm-lock.yaml'))) {
331
+ return 'pnpm';
332
+ }
333
+ if (fs.existsSync(path.join(process.cwd(), 'package-lock.json'))) {
334
+ return 'npm';
335
+ }
336
+ return null;
337
+ };
338
+ NextJs.prototype._getInstallCommand = function (packageManager) {
339
+ switch (packageManager) {
340
+ case 'yarn':
341
+ return 'yarn add';
342
+ case 'pnpm':
343
+ return 'pnpm add';
344
+ case 'npm':
345
+ return 'npm install';
346
+ default:
347
+ throw new Error("Unknown package manager: " + packageManager);
348
+ }
349
+ };
350
+ NextJs.prototype._installPackage = function (packageName, packageManager) {
351
+ return __awaiter(this, void 0, void 0, function () {
352
+ var command;
353
+ return __generator(this, function (_a) {
354
+ switch (_a.label) {
355
+ case 0:
356
+ command = this._getInstallCommand(packageManager);
357
+ return [4 /*yield*/, util_1.promisify(child_process_1.exec)(command + " " + packageName)];
358
+ case 1:
359
+ _a.sent();
360
+ Logging_1.green("\u2713 Added `" + packageName + "` using `" + command + "`.");
361
+ return [2 /*return*/];
362
+ }
363
+ });
364
+ });
365
+ };
304
366
  NextJs.prototype._checkPackageVersion = function (packageName, acceptableVersions, canBeLatest) {
305
367
  var depsVersion = _.get(appPackage, ['dependencies', packageName]);
306
368
  var devDepsVersion = _.get(appPackage, ['devDependencies', packageName]);
@@ -1 +1 @@
1
- {"version":3,"file":"NextJs.js","sourceRoot":"","sources":["../../../../lib/Steps/Integrations/NextJs.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable max-lines */\nimport Chalk from 'chalk';\nimport * 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 <14.0.0';\nconst COMPATIBLE_SDK_VERSIONS = '>=7.3.0';\nconst PROPERTIES_FILENAME = 'sentry.properties';\nconst SENTRYCLIRC_FILENAME = '.sentryclirc';\nconst GITIGNORE_FILENAME = '.gitignore';\nconst CONFIG_DIR = 'configs/';\nconst MERGEABLE_CONFIG_INFIX = 'wizardcopy';\n\n// for those files which can go in more than one place, the list of places they\n// could go (the first one which works will be used)\nconst TEMPLATE_DESTINATIONS: { [key: string]: string[] } = {\n '_error.js': ['pages', 'src/pages'],\n 'next.config.js': ['.'],\n 'sentry.server.config.js': ['.'],\n 'sentry.client.config.js': ['.'],\n};\n\nlet appPackage: any = {};\n\ntry {\n appPackage = require(path.join(process.cwd(), 'package.json'));\n} catch {\n // We don't need to have this\n}\n\nexport class NextJs extends BaseIntegration {\n protected _sentryCli: SentryCli;\n\n constructor(protected _argv: Args) {\n super(_argv);\n this._sentryCli = new SentryCli(this._argv);\n }\n\n public async emit(answers: Answers): Promise<Answers> {\n const dsn = _.get(answers, ['config', 'dsn', 'public'], null);\n nl();\n\n const sentryCliProps = this._sentryCli.convertAnswersToProperties(answers);\n await this._createSentryCliConfig(sentryCliProps);\n\n const templateDirectory = path.join(\n __dirname,\n '..',\n '..',\n '..',\n 'NextJs',\n );\n const configDirectory = path.join(\n templateDirectory,\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 const selectedProjectSlug: string | null = answers.config?.project?.slug;\n if (selectedProjectSlug) {\n const hasFirstEvent = answers.wizard?.projects?.find?.((p: { slug: string; }) => p.slug === selectedProjectSlug)?.firstEvent;\n if (!hasFirstEvent) {\n this._setTemplate(\n templateDirectory,\n 'sentry_sample_error.js',\n ['pages', 'src/pages'],\n dsn,\n );\n l(\n Chalk.bgYellowBright(`\n|------------------------------------------------------------------------|\n| Installation Complete |\n| To verify your installation and finish onboarding, launch your Next.js |\n| application, navigate to https://localhost:3000/sentry_sample_error |\n| and send us a sample error. |\n|------------------------------------------------------------------------|\n`\n )\n );\n }\n }\n\n l(\n 'For more information, see https://docs.sentry.io/platforms/javascript/guides/nextjs/',\n );\n nl();\n\n return {};\n }\n\n public async shouldConfigure(_answers: Answers): Promise<Answers> {\n if (this._shouldConfigure) {\n return this._shouldConfigure;\n }\n\n nl();\n\n let userAnswers: Answers = { continue: true };\n const hasCompatibleNextjsVersion = this._checkPackageVersion('next', COMPATIBLE_NEXTJS_VERSIONS, true);\n const hasCompatibleSdkVersion = this._checkPackageVersion('@sentry/nextjs', COMPATIBLE_SDK_VERSIONS, true);\n const hasAllPackagesCompatible = hasCompatibleNextjsVersion && hasCompatibleSdkVersion;\n\n if (!hasAllPackagesCompatible && !this._argv.quiet) {\n userAnswers = await prompt({\n message:\n 'There were errors during your project checkup, do you still want to continue?',\n name: 'continue',\n default: false,\n type: 'confirm',\n });\n }\n\n nl();\n\n if (!userAnswers['continue']) {\n throw new Error('Please install the required dependencies to continue.');\n }\n\n this._shouldConfigure = Promise.resolve({ nextjs: true });\n // eslint-disable-next-line @typescript-eslint/unbound-method\n return this.shouldConfigure;\n }\n\n private async _createSentryCliConfig(\n cliProps: SentryCliProps,\n ): Promise<void> {\n const { 'auth/token': authToken, ...cliPropsToWrite } = cliProps;\n\n /**\n * To not commit the auth token to the VCS, instead of adding it to the\n * properties file (like the rest of props), it's added to the Sentry CLI\n * config, which is added to the gitignore. This way makes the properties\n * file safe to commit without exposing any auth tokens.\n */\n if (authToken) {\n try {\n await fs.promises.appendFile(\n SENTRYCLIRC_FILENAME,\n this._sentryCli.dumpConfig({ auth: { token: authToken } }),\n );\n green(`✓ Successfully added the auth token to ${SENTRYCLIRC_FILENAME}`);\n } catch {\n red(\n `⚠ Could not add the auth token to ${SENTRYCLIRC_FILENAME}, ` +\n `please add it to identify your user account:\\n${authToken}`,\n );\n nl();\n }\n } else {\n red(\n `⚠ Did not find an auth token, please add your token to ${SENTRYCLIRC_FILENAME}`,\n );\n l(\n 'To generate an auth token, visit https://sentry.io/settings/account/api/auth-tokens/',\n );\n l(\n 'To learn how to configure Sentry CLI, visit ' +\n 'https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#configure-sentry-cli',\n );\n }\n\n await this._addToGitignore(\n SENTRYCLIRC_FILENAME,\n `⚠ Could not add ${SENTRYCLIRC_FILENAME} to ${GITIGNORE_FILENAME}, ` +\n 'please add it to not commit your auth key.',\n );\n\n try {\n await fs.promises.writeFile(\n `./${PROPERTIES_FILENAME}`,\n this._sentryCli.dumpProperties(cliPropsToWrite),\n );\n green(`✓ Successfully created sentry.properties`);\n } catch {\n red(`⚠ Could not add org and project data to ${PROPERTIES_FILENAME}`);\n l(\n 'See docs for a manual setup: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#configure-sentry-cli',\n );\n }\n nl();\n }\n\n private async _addToGitignore(\n filepath: string,\n errorMsg: string,\n ): Promise<void> {\n /**\n * Don't check whether the given file is ignored because:\n * 1. It's tricky to check it without git.\n * 2. Git might not be installed or accessible.\n * 3. It's convenient to use a module to interact with git, but it would\n * increase the size x2 approximately. Docs say to run the Wizard without\n * installing it, and duplicating the size would slow the set-up down.\n * 4. The Wizard is meant to be run once.\n * 5. A message is logged informing users it's been added to the gitignore.\n * 6. It will be added to the gitignore as many times as it runs - not a big\n * deal.\n * 7. It's straightforward to remove it from the gitignore.\n */\n try {\n await fs.promises.appendFile(\n GITIGNORE_FILENAME,\n `\\n# Sentry\\n${filepath}\\n`,\n );\n green(`✓ ${filepath} added to ${GITIGNORE_FILENAME}`);\n } catch {\n red(errorMsg);\n }\n }\n\n private _createNextConfig(configDirectory: string, dsn: any): void {\n const templates = fs.readdirSync(configDirectory);\n for (const template of templates) {\n this._setTemplate(\n configDirectory,\n template,\n TEMPLATE_DESTINATIONS[template],\n dsn,\n );\n }\n red(\n '⚠ Performance monitoring is enabled capturing 100% of transactions.\\n' +\n ' Learn more in https://docs.sentry.io/product/performance/',\n );\n nl();\n }\n\n private _setTemplate(\n configDirectory: string,\n templateFile: string,\n destinationOptions: string[],\n dsn: string,\n ): void {\n const templatePath = path.join(configDirectory, templateFile);\n\n for (const destinationDir of destinationOptions) {\n if (!fs.existsSync(destinationDir)) {\n continue;\n }\n\n const destinationPath = path.join(destinationDir, templateFile);\n // in case the file in question already exists, we'll make a copy with\n // `MERGEABLE_CONFIG_INFIX` inserted just before the extension, so as not\n // to overwrite the existing file\n const mergeableFilePath = path.join(\n destinationDir,\n this._spliceInPlace(\n templateFile.split('.'),\n -1,\n 0,\n MERGEABLE_CONFIG_INFIX,\n ).join('.'),\n );\n\n if (!fs.existsSync(destinationPath)) {\n this._fillAndCopyTemplate(templatePath, destinationPath, dsn);\n } else if (!fs.existsSync(mergeableFilePath)) {\n this._fillAndCopyTemplate(templatePath, mergeableFilePath, dsn);\n red(\n `File \\`${templateFile}\\` already exists, so created \\`${mergeableFilePath}\\`.\\n` +\n 'Please merge those files.',\n );\n nl();\n } else {\n red(\n `Both \\`${templateFile}\\` and \\`${mergeableFilePath}\\` already exist.\\n` +\n 'Please merge those files.',\n );\n nl();\n }\n return;\n }\n\n red(\n `Could not find appropriate destination for \\`${templateFile}\\`. Tried: ${destinationOptions}.`,\n );\n nl();\n }\n\n private _fillAndCopyTemplate(\n sourcePath: string,\n targetPath: string,\n dsn: string,\n ): void {\n const templateContent = fs.readFileSync(sourcePath).toString();\n const filledTemplate = templateContent.replace('___DSN___', dsn);\n fs.writeFileSync(targetPath, filledTemplate);\n }\n\n private _checkPackageVersion(\n packageName: string,\n acceptableVersions: string,\n canBeLatest: boolean,\n ): boolean {\n const depsVersion = _.get(appPackage, ['dependencies', packageName]);\n const devDepsVersion = _.get(appPackage, ['devDependencies', packageName]);\n\n if (!depsVersion && !devDepsVersion) {\n red(`✗ ${packageName} isn't in your dependencies.`);\n red(' Please install it with yarn/npm.');\n return false;\n } else if (\n !this._fulfillsVersionRange(\n depsVersion,\n acceptableVersions,\n canBeLatest,\n ) &&\n !this._fulfillsVersionRange(\n devDepsVersion,\n acceptableVersions,\n canBeLatest,\n )\n ) {\n red(\n `✗ Your \\`package.json\\` specifies a version of \\`${packageName}\\` outside of the compatible version range ${acceptableVersions}.\\n`,\n );\n return false;\n } else {\n green(\n `✓ A compatible version of \\`${packageName}\\` is specified in \\`package.json\\`.`,\n );\n return true;\n }\n }\n\n private _fulfillsVersionRange(\n version: string,\n acceptableVersions: string,\n canBeLatest: boolean,\n ): boolean {\n if (version === 'latest') {\n return canBeLatest;\n }\n\n let cleanedUserVersion, isRange;\n\n if (valid(version)) {\n cleanedUserVersion = valid(version);\n isRange = false;\n } else if (validRange(version)) {\n cleanedUserVersion = validRange(version);\n isRange = true;\n }\n\n return (\n // If the given version is a bogus format, this will still be undefined and we'll automatically reject it\n !!cleanedUserVersion &&\n (isRange\n ? subset(cleanedUserVersion, acceptableVersions)\n : satisfies(cleanedUserVersion, acceptableVersions))\n );\n }\n\n private _spliceInPlace(\n arr: Array<any>,\n start: number,\n deleteCount: number,\n ...inserts: any[]\n ): Array<any> {\n arr.splice(start, deleteCount, ...inserts);\n return arr;\n }\n}\n"]}
1
+ {"version":3,"file":"NextJs.js","sourceRoot":"","sources":["../../../../lib/Steps/Integrations/NextJs.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable max-lines */\nimport Chalk from 'chalk';\nimport { exec } from 'child_process';\nimport * as fs from 'fs';\nimport { Answers, prompt } from 'inquirer';\nimport * as _ from 'lodash';\nimport * as path from 'path';\nimport { satisfies, subset, valid, validRange } from 'semver';\nimport { promisify } from 'util';\n\nimport { Args } from '../../Constants';\nimport { debug, green, l, nl, red } from '../../Helper/Logging';\nimport { SentryCli, SentryCliProps } from '../../Helper/SentryCli';\nimport { BaseIntegration } from './BaseIntegration';\n\ntype PackageManager = 'yarn' | 'npm' | 'pnpm';\n\nconst COMPATIBLE_NEXTJS_VERSIONS = '>=10.0.8 <14.0.0';\nconst COMPATIBLE_SDK_VERSIONS = '>=7.3.0';\nconst PROPERTIES_FILENAME = 'sentry.properties';\nconst SENTRYCLIRC_FILENAME = '.sentryclirc';\nconst GITIGNORE_FILENAME = '.gitignore';\nconst CONFIG_DIR = 'configs/';\nconst MERGEABLE_CONFIG_INFIX = 'wizardcopy';\n\n// for those files which can go in more than one place, the list of places they\n// could go (the first one which works will be used)\nconst TEMPLATE_DESTINATIONS: { [key: string]: string[] } = {\n '_error.js': ['pages', 'src/pages'],\n 'next.config.js': ['.'],\n 'sentry.server.config.js': ['.'],\n 'sentry.client.config.js': ['.'],\n 'sentry.edge.config.js': ['.'],\n};\n\nlet appPackage: any = {};\n\ntry {\n appPackage = require(path.join(process.cwd(), 'package.json'));\n} catch {\n // We don't need to have this\n}\n\nexport class NextJs extends BaseIntegration {\n protected _sentryCli: SentryCli;\n\n constructor(protected _argv: Args) {\n super(_argv);\n this._sentryCli = new SentryCli(this._argv);\n }\n\n public async emit(answers: Answers): Promise<Answers> {\n const dsn = _.get(answers, ['config', 'dsn', 'public'], null);\n nl();\n\n const sentryCliProps = this._sentryCli.convertAnswersToProperties(answers);\n await this._createSentryCliConfig(sentryCliProps);\n\n const templateDirectory = path.join(__dirname, '..', '..', '..', 'NextJs');\n const configDirectory = path.join(templateDirectory, CONFIG_DIR);\n\n if (fs.existsSync(configDirectory)) {\n this._createNextConfig(configDirectory, dsn);\n } else {\n debug(\n `Couldn't find ${configDirectory}, probably because you ran this from inside of \\`/lib\\` rather than \\`/dist\\``,\n );\n nl();\n }\n\n const selectedProjectSlug: string | null = answers.config?.project?.slug;\n if (selectedProjectSlug) {\n const hasFirstEvent = answers.wizard?.projects?.find?.(\n (p: { slug: string }) => p.slug === selectedProjectSlug,\n )?.firstEvent;\n if (!hasFirstEvent) {\n this._setTemplate(\n templateDirectory,\n 'sentry_sample_error.js',\n ['pages', 'src/pages'],\n dsn,\n );\n l(\n Chalk.bgYellowBright(`\n|------------------------------------------------------------------------|\n| Installation Complete |\n| To verify your installation and finish onboarding, launch your Next.js |\n| application, navigate to http://localhost:3000/sentry_sample_error |\n| and send us a sample error. |\n|------------------------------------------------------------------------|\n`),\n );\n }\n }\n\n l(\n 'For more information, see https://docs.sentry.io/platforms/javascript/guides/nextjs/',\n );\n nl();\n\n return {};\n }\n\n public async shouldConfigure(_answers: Answers): Promise<Answers> {\n if (this._shouldConfigure) {\n return this._shouldConfigure;\n }\n\n nl();\n\n let userAnswers: Answers = { continue: true };\n const hasCompatibleNextjsVersion = this._checkPackageVersion(\n 'next',\n COMPATIBLE_NEXTJS_VERSIONS,\n true,\n );\n\n const packageManager = this._getPackageMangerChoice();\n const hasSdkInstalled = this._hasPackageInstalled('@sentry/nextjs');\n\n let hasCompatibleSdkVersion = false;\n // if no package but we have nextjs, let's add it if we can\n if (!hasSdkInstalled && packageManager && hasCompatibleNextjsVersion) {\n await this._installPackage('@sentry/nextjs', packageManager);\n // can assume it's compatible since we just installed it\n hasCompatibleSdkVersion = true;\n } else {\n // otherwise, let's check the version and spit out the appropriate error\n hasCompatibleSdkVersion = this._checkPackageVersion(\n '@sentry/nextjs',\n COMPATIBLE_SDK_VERSIONS,\n true,\n );\n }\n const hasAllPackagesCompatible =\n hasCompatibleNextjsVersion && hasCompatibleSdkVersion;\n\n if (!hasAllPackagesCompatible && !this._argv.quiet) {\n userAnswers = await prompt({\n message:\n 'There were errors during your project checkup, do you still want to continue?',\n name: 'continue',\n default: false,\n type: 'confirm',\n });\n }\n\n nl();\n\n if (!userAnswers['continue']) {\n throw new Error('Please install the required dependencies to continue.');\n }\n\n this._shouldConfigure = Promise.resolve({ nextjs: true });\n // eslint-disable-next-line @typescript-eslint/unbound-method\n return this.shouldConfigure;\n }\n\n private async _createSentryCliConfig(\n cliProps: SentryCliProps,\n ): Promise<void> {\n const { 'auth/token': authToken, ...cliPropsToWrite } = cliProps;\n\n /**\n * To not commit the auth token to the VCS, instead of adding it to the\n * properties file (like the rest of props), it's added to the Sentry CLI\n * config, which is added to the gitignore. This way makes the properties\n * file safe to commit without exposing any auth tokens.\n */\n if (authToken) {\n try {\n await fs.promises.appendFile(\n SENTRYCLIRC_FILENAME,\n this._sentryCli.dumpConfig({ auth: { token: authToken } }),\n );\n green(`✓ Successfully added the auth token to ${SENTRYCLIRC_FILENAME}`);\n } catch {\n red(\n `⚠ Could not add the auth token to ${SENTRYCLIRC_FILENAME}, ` +\n `please add it to identify your user account:\\n${authToken}`,\n );\n nl();\n }\n } else {\n red(\n `⚠ Did not find an auth token, please add your token to ${SENTRYCLIRC_FILENAME}`,\n );\n l(\n 'To generate an auth token, visit https://sentry.io/settings/account/api/auth-tokens/',\n );\n l(\n 'To learn how to configure Sentry CLI, visit ' +\n 'https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#configure-sentry-cli',\n );\n }\n\n await this._addToGitignore(\n SENTRYCLIRC_FILENAME,\n `⚠ Could not add ${SENTRYCLIRC_FILENAME} to ${GITIGNORE_FILENAME}, ` +\n 'please add it to not commit your auth key.',\n );\n\n try {\n await fs.promises.writeFile(\n `./${PROPERTIES_FILENAME}`,\n this._sentryCli.dumpProperties(cliPropsToWrite),\n );\n green(`✓ Successfully created sentry.properties`);\n } catch {\n red(`⚠ Could not add org and project data to ${PROPERTIES_FILENAME}`);\n l(\n 'See docs for a manual setup: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#configure-sentry-cli',\n );\n }\n nl();\n }\n\n private async _addToGitignore(\n filepath: string,\n errorMsg: string,\n ): Promise<void> {\n /**\n * Don't check whether the given file is ignored because:\n * 1. It's tricky to check it without git.\n * 2. Git might not be installed or accessible.\n * 3. It's convenient to use a module to interact with git, but it would\n * increase the size x2 approximately. Docs say to run the Wizard without\n * installing it, and duplicating the size would slow the set-up down.\n * 4. The Wizard is meant to be run once.\n * 5. A message is logged informing users it's been added to the gitignore.\n * 6. It will be added to the gitignore as many times as it runs - not a big\n * deal.\n * 7. It's straightforward to remove it from the gitignore.\n */\n try {\n await fs.promises.appendFile(\n GITIGNORE_FILENAME,\n `\\n# Sentry\\n${filepath}\\n`,\n );\n green(`✓ ${filepath} added to ${GITIGNORE_FILENAME}`);\n } catch {\n red(errorMsg);\n }\n }\n\n private _createNextConfig(configDirectory: string, dsn: any): void {\n const templates = fs.readdirSync(configDirectory);\n for (const template of templates) {\n this._setTemplate(\n configDirectory,\n template,\n TEMPLATE_DESTINATIONS[template],\n dsn,\n );\n }\n red(\n '⚠ Performance monitoring is enabled capturing 100% of transactions.\\n' +\n ' Learn more in https://docs.sentry.io/product/performance/',\n );\n nl();\n }\n\n private _setTemplate(\n configDirectory: string,\n templateFile: string,\n destinationOptions: string[],\n dsn: string,\n ): void {\n const templatePath = path.join(configDirectory, templateFile);\n\n for (const destinationDir of destinationOptions) {\n if (!fs.existsSync(destinationDir)) {\n continue;\n }\n\n const destinationPath = path.join(destinationDir, templateFile);\n // in case the file in question already exists, we'll make a copy with\n // `MERGEABLE_CONFIG_INFIX` inserted just before the extension, so as not\n // to overwrite the existing file\n const mergeableFilePath = path.join(\n destinationDir,\n this._spliceInPlace(\n templateFile.split('.'),\n -1,\n 0,\n MERGEABLE_CONFIG_INFIX,\n ).join('.'),\n );\n\n if (!fs.existsSync(destinationPath)) {\n this._fillAndCopyTemplate(templatePath, destinationPath, dsn);\n } else if (!fs.existsSync(mergeableFilePath)) {\n this._fillAndCopyTemplate(templatePath, mergeableFilePath, dsn);\n red(\n `File \\`${templateFile}\\` already exists, so created \\`${mergeableFilePath}\\`.\\n` +\n 'Please merge those files.',\n );\n nl();\n } else {\n red(\n `Both \\`${templateFile}\\` and \\`${mergeableFilePath}\\` already exist.\\n` +\n 'Please merge those files.',\n );\n nl();\n }\n return;\n }\n\n red(\n `Could not find appropriate destination for \\`${templateFile}\\`. Tried: ${destinationOptions}.`,\n );\n nl();\n }\n\n private _fillAndCopyTemplate(\n sourcePath: string,\n targetPath: string,\n dsn: string,\n ): void {\n const templateContent = fs.readFileSync(sourcePath).toString();\n const filledTemplate = templateContent.replace('___DSN___', dsn);\n fs.writeFileSync(targetPath, filledTemplate);\n }\n\n private _hasPackageInstalled(packageName: string): boolean {\n const depsVersion = _.get(appPackage, ['dependencies', packageName]);\n const devDepsVersion = _.get(appPackage, ['devDependencies', packageName]);\n return !!depsVersion || !!devDepsVersion;\n }\n\n private _getPackageMangerChoice(): PackageManager | null {\n if (fs.existsSync(path.join(process.cwd(), 'yarn.lock'))) {\n return 'yarn';\n }\n if (fs.existsSync(path.join(process.cwd(), 'pnpm-lock.yaml'))) {\n return 'pnpm';\n }\n if (fs.existsSync(path.join(process.cwd(), 'package-lock.json'))) {\n return 'npm';\n }\n return null;\n }\n\n private _getInstallCommand(packageManager: PackageManager): string {\n switch (packageManager) {\n case 'yarn':\n return 'yarn add';\n case 'pnpm':\n return 'pnpm add';\n case 'npm':\n return 'npm install';\n default:\n throw new Error(`Unknown package manager: ${packageManager}`);\n }\n }\n\n private async _installPackage(\n packageName: string,\n packageManager: PackageManager,\n ): Promise<void> {\n const command = this._getInstallCommand(packageManager);\n await promisify(exec)(`${command} ${packageName}`);\n green(`✓ Added \\`${packageName}\\` using \\`${command}\\`.`);\n return;\n }\n\n private _checkPackageVersion(\n packageName: string,\n acceptableVersions: string,\n canBeLatest: boolean,\n ): boolean {\n const depsVersion = _.get(appPackage, ['dependencies', packageName]);\n const devDepsVersion = _.get(appPackage, ['devDependencies', packageName]);\n\n if (!depsVersion && !devDepsVersion) {\n red(`✗ ${packageName} isn't in your dependencies.`);\n red(' Please install it with yarn/npm.');\n return false;\n } else if (\n !this._fulfillsVersionRange(\n depsVersion,\n acceptableVersions,\n canBeLatest,\n ) &&\n !this._fulfillsVersionRange(\n devDepsVersion,\n acceptableVersions,\n canBeLatest,\n )\n ) {\n red(\n `✗ Your \\`package.json\\` specifies a version of \\`${packageName}\\` outside of the compatible version range ${acceptableVersions}.\\n`,\n );\n return false;\n } else {\n green(\n `✓ A compatible version of \\`${packageName}\\` is specified in \\`package.json\\`.`,\n );\n return true;\n }\n }\n\n private _fulfillsVersionRange(\n version: string,\n acceptableVersions: string,\n canBeLatest: boolean,\n ): boolean {\n if (version === 'latest') {\n return canBeLatest;\n }\n\n let cleanedUserVersion, isRange;\n\n if (valid(version)) {\n cleanedUserVersion = valid(version);\n isRange = false;\n } else if (validRange(version)) {\n cleanedUserVersion = validRange(version);\n isRange = true;\n }\n\n return (\n // If the given version is a bogus format, this will still be undefined and we'll automatically reject it\n !!cleanedUserVersion &&\n (isRange\n ? subset(cleanedUserVersion, acceptableVersions)\n : satisfies(cleanedUserVersion, acceptableVersions))\n );\n }\n\n private _spliceInPlace(\n arr: Array<any>,\n start: number,\n deleteCount: number,\n ...inserts: any[]\n ): Array<any> {\n arr.splice(start, deleteCount, ...inserts);\n return arr;\n }\n}\n"]}
@@ -50,6 +50,8 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
50
50
  };
51
51
  Object.defineProperty(exports, "__esModule", { value: true });
52
52
  exports.OpenSentry = void 0;
53
+ var url_1 = require("url");
54
+ var Constants_1 = require("../Constants");
53
55
  var BottomBar_1 = require("../Helper/BottomBar");
54
56
  var Logging_1 = require("../Helper/Logging");
55
57
  var Wizard_1 = require("../Helper/Wizard");
@@ -63,7 +65,7 @@ var OpenSentry = /** @class */ (function (_super) {
63
65
  }
64
66
  OpenSentry.prototype.emit = function (answers) {
65
67
  return __awaiter(this, void 0, void 0, function () {
66
- var baseUrl, data, urlToOpen, e_1;
68
+ var baseUrl, data, urlObj, urlToOpen, e_1;
67
69
  return __generator(this, function (_a) {
68
70
  switch (_a.label) {
69
71
  case 0: return [4 /*yield*/, Wizard_1.getCurrentIntegration(answers).shouldEmit(answers)];
@@ -86,7 +88,18 @@ var OpenSentry = /** @class */ (function (_super) {
86
88
  case 3:
87
89
  data = _a.sent();
88
90
  BottomBar_1.BottomBar.hide();
89
- urlToOpen = baseUrl + "account/settings/wizard/" + data.hash + "/";
91
+ urlObj = new url_1.URL(baseUrl + "account/settings/wizard/" + data.hash + "/");
92
+ if (this._argv.signup) {
93
+ urlObj.searchParams.set('signup', '1');
94
+ // integration maps to platform in the wizard
95
+ if (this._argv.integration) {
96
+ urlObj.searchParams.set('project_platform', Constants_1.mapIntegrationToPlatform(this._argv.integration));
97
+ }
98
+ if (this._argv.promoCode) {
99
+ urlObj.searchParams.set('code', this._argv.promoCode);
100
+ }
101
+ }
102
+ urlToOpen = urlObj.toString();
90
103
  opn(urlToOpen);
91
104
  Logging_1.nl();
92
105
  Logging_1.l('Please open');
@@ -1 +1 @@
1
- {"version":3,"file":"OpenSentry.js","sourceRoot":"","sources":["../../../lib/Steps/OpenSentry.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,iDAAgD;AAChD,6CAA2D;AAC3D,2CAAyD;AACzD,uCAAsC;AAEtC,IAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;AAC3B,IAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEzB;IAAgC,8BAAQ;IAAxC;;IA4CA,CAAC;IA3Cc,yBAAI,GAAjB,UAAkB,OAAgB;;;;;4BAC1B,qBAAM,8BAAqB,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,EAAA;;wBAA9D,IAAI,CAAC,CAAC,SAAwD,CAAC,EAAE;4BAC/D,aAAG,CAAC,yDAAyD,CAAC,CAAC;4BAC/D,sBAAO,EAAE,EAAC;yBACX;wBACD,IAAI,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;4BAC1B,aAAG,CAAC,+BAA+B,CAAC,CAAC;4BACrC,sBAAO,EAAE,EAAC;yBACX;wBAEK,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;wBAE/B,qBAAS,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;wBACpC,IAAI,CAAC,KAAK,CAAC,wBAAsB,OAAS,CAAC,CAAC;;;;wBAG7B,qBAAM,EAAE,CAAC,GAAG,CAAI,OAAO,kBAAe,CAAC,CAAC,IAAI,EAAA;;wBAAnD,IAAI,GAAG,SAA4C;wBAEzD,qBAAS,CAAC,IAAI,EAAE,CAAC;wBAEX,SAAS,GAAM,OAAO,gCAA2B,IAAI,CAAC,IAAI,MAAG,CAAC;wBAEpE,GAAG,CAAC,SAAS,CAAC,CAAC;wBACf,YAAE,EAAE,CAAC;wBACL,WAAC,CAAC,aAAa,CAAC,CAAC;wBACjB,eAAK,CAAC,SAAS,CAAC,CAAC;wBACjB,WAAC,CAAC,4CAA4C,CAAC,CAAC;wBAChD,YAAE,EAAE,CAAC;wBAEL,sBAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAC;;;wBAE3B,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC;wBAC9B,qBAAS,CAAC,IAAI,EAAE,CAAC;wBACjB,YAAE,EAAE,CAAC;wBACL,aAAG,CACD,gCAA8B,OAAO,mCAAgC,CACtE,CAAC;wBACF,WAAC,CACC,0EAA0E,CAC3E,CAAC;wBACF,sBAAO,EAAE,EAAC;;;;;KAEb;IACH,iBAAC;AAAD,CAAC,AA5CD,CAAgC,mBAAQ,GA4CvC;AA5CY,gCAAU","sourcesContent":["import { Answers } from 'inquirer';\n\nimport { BottomBar } from '../Helper/BottomBar';\nimport { dim, green, l, nl, red } from '../Helper/Logging';\nimport { getCurrentIntegration } from '../Helper/Wizard';\nimport { BaseStep } from './BaseStep';\n\nconst opn = require('opn');\nconst r2 = require('r2');\n\nexport class OpenSentry extends BaseStep {\n public async emit(answers: Answers): Promise<Answers> {\n if (!(await getCurrentIntegration(answers).shouldEmit(answers))) {\n dim('Skipping connection to Sentry due files already patched');\n return {};\n }\n if (this._argv.skipConnect) {\n dim('Skipping connection to Sentry');\n return {};\n }\n\n const baseUrl = this._argv.url;\n\n BottomBar.show('Loading wizard...');\n this.debug(`Loading wizard for ${baseUrl}`);\n\n try {\n const data = await r2.get(`${baseUrl}api/0/wizard/`).json;\n\n BottomBar.hide();\n\n const urlToOpen = `${baseUrl}account/settings/wizard/${data.hash}/`;\n\n opn(urlToOpen);\n nl();\n l('Please open');\n green(urlToOpen);\n l(\"in your browser (if it's not open already)\");\n nl();\n\n return { hash: data.hash };\n } catch (e) {\n this._argv.skipConnect = true;\n BottomBar.hide();\n nl();\n red(\n `Wizard couldn't connect to ${baseUrl}\\nmake sure the url is correct`,\n );\n l(\n 'But no worries, we fall back to asking you stuff instead, so here we go:',\n );\n return {};\n }\n }\n}\n"]}
1
+ {"version":3,"file":"OpenSentry.js","sourceRoot":"","sources":["../../../lib/Steps/OpenSentry.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,2BAA0B;AAE1B,0CAAwD;AACxD,iDAAgD;AAChD,6CAA2D;AAC3D,2CAAyD;AACzD,uCAAsC;AAEtC,IAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;AAC3B,IAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEzB;IAAgC,8BAAQ;IAAxC;;IA2DA,CAAC;IA1Dc,yBAAI,GAAjB,UAAkB,OAAgB;;;;;4BAC1B,qBAAM,8BAAqB,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,EAAA;;wBAA9D,IAAI,CAAC,CAAC,SAAwD,CAAC,EAAE;4BAC/D,aAAG,CAAC,yDAAyD,CAAC,CAAC;4BAC/D,sBAAO,EAAE,EAAC;yBACX;wBACD,IAAI,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;4BAC1B,aAAG,CAAC,+BAA+B,CAAC,CAAC;4BACrC,sBAAO,EAAE,EAAC;yBACX;wBAEK,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;wBAE/B,qBAAS,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;wBACpC,IAAI,CAAC,KAAK,CAAC,wBAAsB,OAAS,CAAC,CAAC;;;;wBAG7B,qBAAM,EAAE,CAAC,GAAG,CAAI,OAAO,kBAAe,CAAC,CAAC,IAAI,EAAA;;wBAAnD,IAAI,GAAG,SAA4C;wBAEzD,qBAAS,CAAC,IAAI,EAAE,CAAC;wBAEX,MAAM,GAAG,IAAI,SAAG,CAAI,OAAO,gCAA2B,IAAI,CAAC,IAAI,MAAG,CAAC,CAAC;wBAC1E,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;4BACrB,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;4BACvC,6CAA6C;4BAC7C,IAAI,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;gCAC1B,MAAM,CAAC,YAAY,CAAC,GAAG,CACrB,kBAAkB,EAClB,oCAAwB,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CACjD,CAAC;6BACH;4BACD,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE;gCACxB,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;6BACvD;yBACF;wBAEK,SAAS,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;wBAEpC,GAAG,CAAC,SAAS,CAAC,CAAC;wBACf,YAAE,EAAE,CAAC;wBACL,WAAC,CAAC,aAAa,CAAC,CAAC;wBACjB,eAAK,CAAC,SAAS,CAAC,CAAC;wBACjB,WAAC,CAAC,4CAA4C,CAAC,CAAC;wBAChD,YAAE,EAAE,CAAC;wBAEL,sBAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAC;;;wBAE3B,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC;wBAC9B,qBAAS,CAAC,IAAI,EAAE,CAAC;wBACjB,YAAE,EAAE,CAAC;wBACL,aAAG,CACD,gCAA8B,OAAO,mCAAgC,CACtE,CAAC;wBACF,WAAC,CACC,0EAA0E,CAC3E,CAAC;wBACF,sBAAO,EAAE,EAAC;;;;;KAEb;IACH,iBAAC;AAAD,CAAC,AA3DD,CAAgC,mBAAQ,GA2DvC;AA3DY,gCAAU","sourcesContent":["import { Answers } from 'inquirer';\nimport { URL } from 'url';\n\nimport { mapIntegrationToPlatform } from '../Constants';\nimport { BottomBar } from '../Helper/BottomBar';\nimport { dim, green, l, nl, red } from '../Helper/Logging';\nimport { getCurrentIntegration } from '../Helper/Wizard';\nimport { BaseStep } from './BaseStep';\n\nconst opn = require('opn');\nconst r2 = require('r2');\n\nexport class OpenSentry extends BaseStep {\n public async emit(answers: Answers): Promise<Answers> {\n if (!(await getCurrentIntegration(answers).shouldEmit(answers))) {\n dim('Skipping connection to Sentry due files already patched');\n return {};\n }\n if (this._argv.skipConnect) {\n dim('Skipping connection to Sentry');\n return {};\n }\n\n const baseUrl = this._argv.url;\n\n BottomBar.show('Loading wizard...');\n this.debug(`Loading wizard for ${baseUrl}`);\n\n try {\n const data = await r2.get(`${baseUrl}api/0/wizard/`).json;\n\n BottomBar.hide();\n\n const urlObj = new URL(`${baseUrl}account/settings/wizard/${data.hash}/`);\n if (this._argv.signup) {\n urlObj.searchParams.set('signup', '1');\n // integration maps to platform in the wizard\n if (this._argv.integration) {\n urlObj.searchParams.set(\n 'project_platform',\n mapIntegrationToPlatform(this._argv.integration),\n );\n }\n if (this._argv.promoCode) {\n urlObj.searchParams.set('code', this._argv.promoCode);\n }\n }\n\n const urlToOpen = urlObj.toString();\n\n opn(urlToOpen);\n nl();\n l('Please open');\n green(urlToOpen);\n l(\"in your browser (if it's not open already)\");\n nl();\n\n return { hash: data.hash };\n } catch (e) {\n this._argv.skipConnect = true;\n BottomBar.hide();\n nl();\n red(\n `Wizard couldn't connect to ${baseUrl}\\nmake sure the url is correct`,\n );\n l(\n 'But no worries, we fall back to asking you stuff instead, so here we go:',\n );\n return {};\n }\n }\n}\n"]}
@@ -53,6 +53,9 @@ exports.SentryProjectSelector = void 0;
53
53
  var inquirer_1 = require("inquirer");
54
54
  var _ = require("lodash");
55
55
  var BaseStep_1 = require("./BaseStep");
56
+ function sleep(n) {
57
+ return new Promise(function (resolve) { return setTimeout(resolve, n); });
58
+ }
56
59
  var SentryProjectSelector = /** @class */ (function (_super) {
57
60
  __extends(SentryProjectSelector, _super);
58
61
  function SentryProjectSelector() {
@@ -74,10 +77,17 @@ var SentryProjectSelector = /** @class */ (function (_super) {
74
77
  throw new Error('no projects');
75
78
  }
76
79
  selectedProject = null;
77
- if (!(answers.wizard.projects.length === 1)) return [3 /*break*/, 1];
80
+ if (!(answers.wizard.projects.length === 1)) return [3 /*break*/, 2];
78
81
  selectedProject = { selectedProject: answers.wizard.projects[0] };
79
- return [3 /*break*/, 3];
80
- case 1: return [4 /*yield*/, inquirer_1.prompt([
82
+ // the wizard CLI closes too quickly when we skip the prompt
83
+ // as it will cause the UI to be stuck saying Waiting for wizard to connect
84
+ return [4 /*yield*/, sleep(1000)];
85
+ case 1:
86
+ // the wizard CLI closes too quickly when we skip the prompt
87
+ // as it will cause the UI to be stuck saying Waiting for wizard to connect
88
+ _a.sent();
89
+ return [3 /*break*/, 4];
90
+ case 2: return [4 /*yield*/, inquirer_1.prompt([
81
91
  {
82
92
  choices: answers.wizard.projects.map(function (project) {
83
93
  return {
@@ -90,10 +100,10 @@ var SentryProjectSelector = /** @class */ (function (_super) {
90
100
  type: 'list',
91
101
  },
92
102
  ])];
93
- case 2:
103
+ case 3:
94
104
  selectedProject = _a.sent();
95
- _a.label = 3;
96
- case 3: return [2 /*return*/, {
105
+ _a.label = 4;
106
+ case 4: return [2 /*return*/, {
97
107
  config: {
98
108
  auth: {
99
109
  token: _.get(answers, 'wizard.apiKeys.token', null),
@@ -1 +1 @@
1
- {"version":3,"file":"SentryProjectSelector.js","sourceRoot":"","sources":["../../../lib/Steps/SentryProjectSelector.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,qCAA2C;AAC3C,0BAA4B;AAE5B,uCAAsC;AAEtC;IAA2C,yCAAQ;IAAnD;;IAiEA,CAAC;IAhEc,oCAAI,GAAjB,UAAkB,OAAgB;;;;;;wBAChC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;wBAEpB,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE;4BAC7B,2DAA2D;4BAC3D,sBAAO,EAAE,EAAC;yBACX;wBAED,IACE,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,iBAAiB,CAAC;4BACjC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EACpC;4BACA,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC;yBAChC;wBAEG,eAAe,GAAG,IAAI,CAAC;6BACvB,CAAA,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAA,EAApC,wBAAoC;wBACtC,eAAe,GAAG,EAAE,eAAe,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;;4BAEhD,qBAAM,iBAAM,CAAC;4BAC7B;gCACE,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAC,OAAY;oCAChD,OAAO;wCACL,IAAI,EAAK,OAAO,CAAC,YAAY,CAAC,IAAI,WAAM,OAAO,CAAC,IAAM;wCACtD,KAAK,EAAE,OAAO;qCACf,CAAC;gCACJ,CAAC,CAAC;gCACF,OAAO,EAAE,uCAAuC;gCAChD,IAAI,EAAE,iBAAiB;gCACvB,IAAI,EAAE,MAAM;6BACb;yBACF,CAAC,EAAA;;wBAZF,eAAe,GAAG,SAYhB,CAAC;;4BAGL,sBAAO;4BACL,MAAM,EAAE;gCACN,IAAI,EAAE;oCACJ,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,sBAAsB,EAAE,IAAI,CAAC;iCACpD;gCACD,GAAG,EAAE;oCACH,MAAM,EAAE,CAAC,CAAC,GAAG,CACX,eAAe,EACf,mCAAmC,EACnC,IAAI,CACL;oCACD,MAAM,EAAE,CAAC,CAAC,GAAG,CACX,eAAe,EACf,mCAAmC,EACnC,IAAI,CACL;iCACF;gCACD,YAAY,EAAE;oCACZ,IAAI,EAAE,CAAC,CAAC,GAAG,CACT,eAAe,EACf,mCAAmC,EACnC,IAAI,CACL;iCACF;gCACD,OAAO,EAAE;oCACP,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,eAAe,EAAE,sBAAsB,EAAE,IAAI,CAAC;iCAC3D;6BACF;yBACF,EAAC;;;;KACH;IACH,4BAAC;AAAD,CAAC,AAjED,CAA2C,mBAAQ,GAiElD;AAjEY,sDAAqB","sourcesContent":["import { Answers, prompt } from 'inquirer';\nimport * as _ from 'lodash';\n\nimport { BaseStep } from './BaseStep';\n\nexport class SentryProjectSelector extends BaseStep {\n public async emit(answers: Answers): Promise<any> {\n this.debug(answers);\n\n if (!_.has(answers, 'wizard')) {\n // we skip this completly because the wizard wasn't running\n return {};\n }\n\n if (\n _.has(answers, 'wizard.projects') &&\n answers.wizard.projects.length === 0\n ) {\n throw new Error('no projects');\n }\n\n let selectedProject = null;\n if (answers.wizard.projects.length === 1) {\n selectedProject = { selectedProject: answers.wizard.projects[0] };\n } else {\n selectedProject = await prompt([\n {\n choices: answers.wizard.projects.map((project: any) => {\n return {\n name: `${project.organization.name} / ${project.slug}`,\n value: project,\n };\n }),\n message: 'Please select your project in Sentry:',\n name: 'selectedProject',\n type: 'list',\n },\n ]);\n }\n\n return {\n config: {\n auth: {\n token: _.get(answers, 'wizard.apiKeys.token', null),\n },\n dsn: {\n public: _.get(\n selectedProject,\n 'selectedProject.keys.0.dsn.public',\n null,\n ),\n secret: _.get(\n selectedProject,\n 'selectedProject.keys.0.dsn.secret',\n null,\n ),\n },\n organization: {\n slug: _.get(\n selectedProject,\n 'selectedProject.organization.slug',\n null,\n ),\n },\n project: {\n slug: _.get(selectedProject, 'selectedProject.slug', null),\n },\n },\n };\n }\n}\n"]}
1
+ {"version":3,"file":"SentryProjectSelector.js","sourceRoot":"","sources":["../../../lib/Steps/SentryProjectSelector.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,qCAA2C;AAC3C,0BAA4B;AAE5B,uCAAsC;AAEtC,SAAS,KAAK,CAAC,CAAS;IACtB,OAAO,IAAI,OAAO,CAAC,UAAA,OAAO,IAAI,OAAA,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,EAAtB,CAAsB,CAAC,CAAC;AACxD,CAAC;AAED;IAA2C,yCAAQ;IAAnD;;IAoEA,CAAC;IAnEc,oCAAI,GAAjB,UAAkB,OAAgB;;;;;;wBAChC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;wBAEpB,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE;4BAC7B,2DAA2D;4BAC3D,sBAAO,EAAE,EAAC;yBACX;wBAED,IACE,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,iBAAiB,CAAC;4BACjC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EACpC;4BACA,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC;yBAChC;wBAEG,eAAe,GAAG,IAAI,CAAC;6BACvB,CAAA,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAA,EAApC,wBAAoC;wBACtC,eAAe,GAAG,EAAE,eAAe,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;wBAClE,4DAA4D;wBAC5D,2EAA2E;wBAC3E,qBAAM,KAAK,CAAC,IAAI,CAAC,EAAA;;wBAFjB,4DAA4D;wBAC5D,2EAA2E;wBAC3E,SAAiB,CAAC;;4BAEA,qBAAM,iBAAM,CAAC;4BAC7B;gCACE,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAC,OAAY;oCAChD,OAAO;wCACL,IAAI,EAAK,OAAO,CAAC,YAAY,CAAC,IAAI,WAAM,OAAO,CAAC,IAAM;wCACtD,KAAK,EAAE,OAAO;qCACf,CAAC;gCACJ,CAAC,CAAC;gCACF,OAAO,EAAE,uCAAuC;gCAChD,IAAI,EAAE,iBAAiB;gCACvB,IAAI,EAAE,MAAM;6BACb;yBACF,CAAC,EAAA;;wBAZF,eAAe,GAAG,SAYhB,CAAC;;4BAGL,sBAAO;4BACL,MAAM,EAAE;gCACN,IAAI,EAAE;oCACJ,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,sBAAsB,EAAE,IAAI,CAAC;iCACpD;gCACD,GAAG,EAAE;oCACH,MAAM,EAAE,CAAC,CAAC,GAAG,CACX,eAAe,EACf,mCAAmC,EACnC,IAAI,CACL;oCACD,MAAM,EAAE,CAAC,CAAC,GAAG,CACX,eAAe,EACf,mCAAmC,EACnC,IAAI,CACL;iCACF;gCACD,YAAY,EAAE;oCACZ,IAAI,EAAE,CAAC,CAAC,GAAG,CACT,eAAe,EACf,mCAAmC,EACnC,IAAI,CACL;iCACF;gCACD,OAAO,EAAE;oCACP,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,eAAe,EAAE,sBAAsB,EAAE,IAAI,CAAC;iCAC3D;6BACF;yBACF,EAAC;;;;KACH;IACH,4BAAC;AAAD,CAAC,AApED,CAA2C,mBAAQ,GAoElD;AApEY,sDAAqB","sourcesContent":["import { Answers, prompt } from 'inquirer';\nimport * as _ from 'lodash';\n\nimport { BaseStep } from './BaseStep';\n\nfunction sleep(n: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, n));\n}\n\nexport class SentryProjectSelector extends BaseStep {\n public async emit(answers: Answers): Promise<any> {\n this.debug(answers);\n\n if (!_.has(answers, 'wizard')) {\n // we skip this completly because the wizard wasn't running\n return {};\n }\n\n if (\n _.has(answers, 'wizard.projects') &&\n answers.wizard.projects.length === 0\n ) {\n throw new Error('no projects');\n }\n\n let selectedProject = null;\n if (answers.wizard.projects.length === 1) {\n selectedProject = { selectedProject: answers.wizard.projects[0] };\n // the wizard CLI closes too quickly when we skip the prompt\n // as it will cause the UI to be stuck saying Waiting for wizard to connect\n await sleep(1000);\n } else {\n selectedProject = await prompt([\n {\n choices: answers.wizard.projects.map((project: any) => {\n return {\n name: `${project.organization.name} / ${project.slug}`,\n value: project,\n };\n }),\n message: 'Please select your project in Sentry:',\n name: 'selectedProject',\n type: 'list',\n },\n ]);\n }\n\n return {\n config: {\n auth: {\n token: _.get(answers, 'wizard.apiKeys.token', null),\n },\n dsn: {\n public: _.get(\n selectedProject,\n 'selectedProject.keys.0.dsn.public',\n null,\n ),\n secret: _.get(\n selectedProject,\n 'selectedProject.keys.0.dsn.secret',\n null,\n ),\n },\n organization: {\n slug: _.get(\n selectedProject,\n 'selectedProject.organization.slug',\n null,\n ),\n },\n project: {\n slug: _.get(selectedProject, 'selectedProject.slug', null),\n },\n },\n };\n }\n}\n"]}
package/lib/Constants.ts CHANGED
@@ -44,6 +44,21 @@ export function getIntegrationDescription(type: string): string {
44
44
  }
45
45
  }
46
46
 
47
+ export function mapIntegrationToPlatform(type: string): string {
48
+ switch (type) {
49
+ case Integration.reactNative:
50
+ return 'react-native';
51
+ case Integration.cordova:
52
+ return 'cordova';
53
+ case Integration.electron:
54
+ return 'javascript-electron';
55
+ case Integration.nextjs:
56
+ return 'javascript-nextjs';
57
+ default:
58
+ throw new Error(`Unknown integration ${type}`);
59
+ }
60
+ }
61
+
47
62
  export function getIntegrationChoices(): any[] {
48
63
  return Object.keys(Integration).map((type: string) => ({
49
64
  name: getIntegrationDescription(type),
@@ -59,6 +74,8 @@ export interface Args {
59
74
  platform: Platform[];
60
75
  skipConnect: boolean;
61
76
  quiet: boolean;
77
+ signup: boolean;
78
+ promoCode?: string;
62
79
  }
63
80
 
64
81
  export const DEFAULT_URL = 'https://sentry.io/';
@@ -27,6 +27,8 @@ function sanitizeAndValidateArgs(argv: Args): void {
27
27
  // @ts-ignore skip-connect does not exist on args
28
28
  delete argv['skip-connect'];
29
29
  }
30
+ // @ts-ignore skip-connect does not exist on args
31
+ argv.promoCode = argv['promo-code'];
30
32
  }
31
33
 
32
34
  export function getCurrentIntegration(answers: Answers): BaseIntegration {
@@ -12,6 +12,7 @@ const args: Args = {
12
12
  skipConnect: false,
13
13
  uninstall: false,
14
14
  url: 'https://localhost:1234',
15
+ signup: false,
15
16
  };
16
17
 
17
18
  const demoAnswers: Answers = {
@@ -1,16 +1,20 @@
1
1
  /* eslint-disable max-lines */
2
2
  import Chalk from 'chalk';
3
+ import { exec } from 'child_process';
3
4
  import * as fs from 'fs';
4
5
  import { Answers, prompt } from 'inquirer';
5
6
  import * as _ from 'lodash';
6
7
  import * as path from 'path';
7
8
  import { satisfies, subset, valid, validRange } from 'semver';
9
+ import { promisify } from 'util';
8
10
 
9
11
  import { Args } from '../../Constants';
10
12
  import { debug, green, l, nl, red } from '../../Helper/Logging';
11
13
  import { SentryCli, SentryCliProps } from '../../Helper/SentryCli';
12
14
  import { BaseIntegration } from './BaseIntegration';
13
15
 
16
+ type PackageManager = 'yarn' | 'npm' | 'pnpm';
17
+
14
18
  const COMPATIBLE_NEXTJS_VERSIONS = '>=10.0.8 <14.0.0';
15
19
  const COMPATIBLE_SDK_VERSIONS = '>=7.3.0';
16
20
  const PROPERTIES_FILENAME = 'sentry.properties';
@@ -26,6 +30,7 @@ const TEMPLATE_DESTINATIONS: { [key: string]: string[] } = {
26
30
  'next.config.js': ['.'],
27
31
  'sentry.server.config.js': ['.'],
28
32
  'sentry.client.config.js': ['.'],
33
+ 'sentry.edge.config.js': ['.'],
29
34
  };
30
35
 
31
36
  let appPackage: any = {};
@@ -51,17 +56,8 @@ export class NextJs extends BaseIntegration {
51
56
  const sentryCliProps = this._sentryCli.convertAnswersToProperties(answers);
52
57
  await this._createSentryCliConfig(sentryCliProps);
53
58
 
54
- const templateDirectory = path.join(
55
- __dirname,
56
- '..',
57
- '..',
58
- '..',
59
- 'NextJs',
60
- );
61
- const configDirectory = path.join(
62
- templateDirectory,
63
- CONFIG_DIR,
64
- );
59
+ const templateDirectory = path.join(__dirname, '..', '..', '..', 'NextJs');
60
+ const configDirectory = path.join(templateDirectory, CONFIG_DIR);
65
61
 
66
62
  if (fs.existsSync(configDirectory)) {
67
63
  this._createNextConfig(configDirectory, dsn);
@@ -74,7 +70,9 @@ export class NextJs extends BaseIntegration {
74
70
 
75
71
  const selectedProjectSlug: string | null = answers.config?.project?.slug;
76
72
  if (selectedProjectSlug) {
77
- const hasFirstEvent = answers.wizard?.projects?.find?.((p: { slug: string; }) => p.slug === selectedProjectSlug)?.firstEvent;
73
+ const hasFirstEvent = answers.wizard?.projects?.find?.(
74
+ (p: { slug: string }) => p.slug === selectedProjectSlug,
75
+ )?.firstEvent;
78
76
  if (!hasFirstEvent) {
79
77
  this._setTemplate(
80
78
  templateDirectory,
@@ -87,11 +85,10 @@ export class NextJs extends BaseIntegration {
87
85
  |------------------------------------------------------------------------|
88
86
  | Installation Complete |
89
87
  | To verify your installation and finish onboarding, launch your Next.js |
90
- | application, navigate to https://localhost:3000/sentry_sample_error |
88
+ | application, navigate to http://localhost:3000/sentry_sample_error |
91
89
  | and send us a sample error. |
92
90
  |------------------------------------------------------------------------|
93
- `
94
- )
91
+ `),
95
92
  );
96
93
  }
97
94
  }
@@ -112,9 +109,31 @@ export class NextJs extends BaseIntegration {
112
109
  nl();
113
110
 
114
111
  let userAnswers: Answers = { continue: true };
115
- const hasCompatibleNextjsVersion = this._checkPackageVersion('next', COMPATIBLE_NEXTJS_VERSIONS, true);
116
- const hasCompatibleSdkVersion = this._checkPackageVersion('@sentry/nextjs', COMPATIBLE_SDK_VERSIONS, true);
117
- const hasAllPackagesCompatible = hasCompatibleNextjsVersion && hasCompatibleSdkVersion;
112
+ const hasCompatibleNextjsVersion = this._checkPackageVersion(
113
+ 'next',
114
+ COMPATIBLE_NEXTJS_VERSIONS,
115
+ true,
116
+ );
117
+
118
+ const packageManager = this._getPackageMangerChoice();
119
+ const hasSdkInstalled = this._hasPackageInstalled('@sentry/nextjs');
120
+
121
+ let hasCompatibleSdkVersion = false;
122
+ // if no package but we have nextjs, let's add it if we can
123
+ if (!hasSdkInstalled && packageManager && hasCompatibleNextjsVersion) {
124
+ await this._installPackage('@sentry/nextjs', packageManager);
125
+ // can assume it's compatible since we just installed it
126
+ hasCompatibleSdkVersion = true;
127
+ } else {
128
+ // otherwise, let's check the version and spit out the appropriate error
129
+ hasCompatibleSdkVersion = this._checkPackageVersion(
130
+ '@sentry/nextjs',
131
+ COMPATIBLE_SDK_VERSIONS,
132
+ true,
133
+ );
134
+ }
135
+ const hasAllPackagesCompatible =
136
+ hasCompatibleNextjsVersion && hasCompatibleSdkVersion;
118
137
 
119
138
  if (!hasAllPackagesCompatible && !this._argv.quiet) {
120
139
  userAnswers = await prompt({
@@ -303,6 +322,48 @@ export class NextJs extends BaseIntegration {
303
322
  fs.writeFileSync(targetPath, filledTemplate);
304
323
  }
305
324
 
325
+ private _hasPackageInstalled(packageName: string): boolean {
326
+ const depsVersion = _.get(appPackage, ['dependencies', packageName]);
327
+ const devDepsVersion = _.get(appPackage, ['devDependencies', packageName]);
328
+ return !!depsVersion || !!devDepsVersion;
329
+ }
330
+
331
+ private _getPackageMangerChoice(): PackageManager | null {
332
+ if (fs.existsSync(path.join(process.cwd(), 'yarn.lock'))) {
333
+ return 'yarn';
334
+ }
335
+ if (fs.existsSync(path.join(process.cwd(), 'pnpm-lock.yaml'))) {
336
+ return 'pnpm';
337
+ }
338
+ if (fs.existsSync(path.join(process.cwd(), 'package-lock.json'))) {
339
+ return 'npm';
340
+ }
341
+ return null;
342
+ }
343
+
344
+ private _getInstallCommand(packageManager: PackageManager): string {
345
+ switch (packageManager) {
346
+ case 'yarn':
347
+ return 'yarn add';
348
+ case 'pnpm':
349
+ return 'pnpm add';
350
+ case 'npm':
351
+ return 'npm install';
352
+ default:
353
+ throw new Error(`Unknown package manager: ${packageManager}`);
354
+ }
355
+ }
356
+
357
+ private async _installPackage(
358
+ packageName: string,
359
+ packageManager: PackageManager,
360
+ ): Promise<void> {
361
+ const command = this._getInstallCommand(packageManager);
362
+ await promisify(exec)(`${command} ${packageName}`);
363
+ green(`✓ Added \`${packageName}\` using \`${command}\`.`);
364
+ return;
365
+ }
366
+
306
367
  private _checkPackageVersion(
307
368
  packageName: string,
308
369
  acceptableVersions: string,
@@ -1,5 +1,7 @@
1
1
  import { Answers } from 'inquirer';
2
+ import { URL } from 'url';
2
3
 
4
+ import { mapIntegrationToPlatform } from '../Constants';
3
5
  import { BottomBar } from '../Helper/BottomBar';
4
6
  import { dim, green, l, nl, red } from '../Helper/Logging';
5
7
  import { getCurrentIntegration } from '../Helper/Wizard';
@@ -29,7 +31,22 @@ export class OpenSentry extends BaseStep {
29
31
 
30
32
  BottomBar.hide();
31
33
 
32
- const urlToOpen = `${baseUrl}account/settings/wizard/${data.hash}/`;
34
+ const urlObj = new URL(`${baseUrl}account/settings/wizard/${data.hash}/`);
35
+ if (this._argv.signup) {
36
+ urlObj.searchParams.set('signup', '1');
37
+ // integration maps to platform in the wizard
38
+ if (this._argv.integration) {
39
+ urlObj.searchParams.set(
40
+ 'project_platform',
41
+ mapIntegrationToPlatform(this._argv.integration),
42
+ );
43
+ }
44
+ if (this._argv.promoCode) {
45
+ urlObj.searchParams.set('code', this._argv.promoCode);
46
+ }
47
+ }
48
+
49
+ const urlToOpen = urlObj.toString();
33
50
 
34
51
  opn(urlToOpen);
35
52
  nl();
@@ -3,6 +3,10 @@ import * as _ from 'lodash';
3
3
 
4
4
  import { BaseStep } from './BaseStep';
5
5
 
6
+ function sleep(n: number): Promise<void> {
7
+ return new Promise(resolve => setTimeout(resolve, n));
8
+ }
9
+
6
10
  export class SentryProjectSelector extends BaseStep {
7
11
  public async emit(answers: Answers): Promise<any> {
8
12
  this.debug(answers);
@@ -22,6 +26,9 @@ export class SentryProjectSelector extends BaseStep {
22
26
  let selectedProject = null;
23
27
  if (answers.wizard.projects.length === 1) {
24
28
  selectedProject = { selectedProject: answers.wizard.projects[0] };
29
+ // the wizard CLI closes too quickly when we skip the prompt
30
+ // as it will cause the UI to be stuck saying Waiting for wizard to connect
31
+ await sleep(1000);
25
32
  } else {
26
33
  selectedProject = await prompt([
27
34
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/wizard",
3
- "version": "2.4.0",
3
+ "version": "2.4.2",
4
4
  "homepage": "https://github.com/getsentry/sentry-wizard",
5
5
  "repository": "https://github.com/getsentry/sentry-wizard",
6
6
  "description": "Sentry wizard helping you to configure your project",
@@ -0,0 +1,17 @@
1
+ // This file configures the initialization of Sentry on the server.
2
+ // The config you add here will be used whenever middleware or an Edge route handles a request.
3
+ // https://docs.sentry.io/platforms/javascript/guides/nextjs/
4
+
5
+ import * as Sentry from '@sentry/nextjs';
6
+
7
+ const SENTRY_DSN = process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN;
8
+
9
+ Sentry.init({
10
+ dsn: SENTRY_DSN || '___DSN___',
11
+ // Adjust this value in production, or use tracesSampler for greater control
12
+ tracesSampleRate: 1.0,
13
+ // ...
14
+ // Note: if you want to override the automatic release value, do not set a
15
+ // `release` value here - use the environment variable `SENTRY_RELEASE`, so
16
+ // that it will also get attached to your source maps
17
+ });