@sentry/wizard 3.31.0 → 3.33.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 (53) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +19 -24
  3. package/bin.ts +71 -21
  4. package/dist/bin.js +97 -52
  5. package/dist/bin.js.map +1 -1
  6. package/dist/e2e-tests/jest.config.d.ts +15 -0
  7. package/dist/e2e-tests/jest.config.js +17 -0
  8. package/dist/e2e-tests/jest.config.js.map +1 -0
  9. package/dist/e2e-tests/tests/remix.test.d.ts +1 -0
  10. package/dist/e2e-tests/tests/remix.test.js +187 -0
  11. package/dist/e2e-tests/tests/remix.test.js.map +1 -0
  12. package/dist/e2e-tests/utils/index.d.ts +117 -0
  13. package/dist/e2e-tests/utils/index.js +353 -0
  14. package/dist/e2e-tests/utils/index.js.map +1 -0
  15. package/dist/lib/Steps/SentryProjectSelector.js +1 -1
  16. package/dist/lib/Steps/SentryProjectSelector.js.map +1 -1
  17. package/dist/package.json +7 -3
  18. package/dist/src/remix/sdk-example.js +5 -1
  19. package/dist/src/remix/sdk-example.js.map +1 -1
  20. package/dist/src/run.d.ts +13 -1
  21. package/dist/src/run.js +34 -7
  22. package/dist/src/run.js.map +1 -1
  23. package/dist/src/sourcemaps/sourcemaps-wizard.d.ts +2 -2
  24. package/dist/src/sourcemaps/sourcemaps-wizard.js.map +1 -1
  25. package/dist/src/sourcemaps/tools/remix.d.ts +2 -2
  26. package/dist/src/sourcemaps/tools/remix.js.map +1 -1
  27. package/dist/src/telemetry.js +1 -0
  28. package/dist/src/telemetry.js.map +1 -1
  29. package/dist/src/utils/clack-utils.js +29 -19
  30. package/dist/src/utils/clack-utils.js.map +1 -1
  31. package/dist/src/utils/types.d.ts +11 -14
  32. package/dist/src/utils/types.js.map +1 -1
  33. package/e2e-tests/jest.config.ts +14 -0
  34. package/e2e-tests/test-applications/remix-test-app/app/entry.client.tsx +18 -0
  35. package/e2e-tests/test-applications/remix-test-app/app/entry.server.tsx +140 -0
  36. package/e2e-tests/test-applications/remix-test-app/app/root.tsx +30 -0
  37. package/e2e-tests/test-applications/remix-test-app/app/routes/_index.tsx +48 -0
  38. package/e2e-tests/test-applications/remix-test-app/app/tailwind.css +3 -0
  39. package/e2e-tests/test-applications/remix-test-app/package.json +37 -0
  40. package/e2e-tests/test-applications/remix-test-app/postcss.config.js +6 -0
  41. package/e2e-tests/test-applications/remix-test-app/tailwind.config.ts +9 -0
  42. package/e2e-tests/test-applications/remix-test-app/vite.config.ts +16 -0
  43. package/e2e-tests/tests/remix.test.ts +163 -0
  44. package/e2e-tests/utils/index.ts +302 -0
  45. package/lib/Steps/SentryProjectSelector.ts +1 -1
  46. package/package.json +7 -3
  47. package/src/remix/sdk-example.ts +6 -0
  48. package/src/run.ts +53 -11
  49. package/src/sourcemaps/sourcemaps-wizard.ts +4 -3
  50. package/src/sourcemaps/tools/remix.ts +2 -2
  51. package/src/telemetry.ts +1 -0
  52. package/src/utils/clack-utils.ts +28 -10
  53. package/src/utils/types.ts +14 -14
package/src/run.ts CHANGED
@@ -4,7 +4,7 @@ import { abortIfCancelled } from './utils/clack-utils';
4
4
  import { runReactNativeWizard } from './react-native/react-native-wizard';
5
5
 
6
6
  import { run as legacyRun } from '../lib/Setup';
7
- import { WizardOptions } from './utils/types';
7
+ import type { PreselectedProject, WizardOptions } from './utils/types';
8
8
  import { runAndroidWizard } from './android/android-wizard';
9
9
  import { runAppleWizard } from './apple/apple-wizard';
10
10
  import { runNextjsWizard } from './nextjs/nextjs-wizard';
@@ -12,8 +12,8 @@ import { runRemixWizard } from './remix/remix-wizard';
12
12
  import { runSvelteKitWizard } from './sveltekit/sveltekit-wizard';
13
13
  import { runSourcemapsWizard } from './sourcemaps/sourcemaps-wizard';
14
14
  import { readEnvironment } from '../lib/Helper/Env';
15
- import { Platform } from '../lib/Constants';
16
- import { PackageDotJson } from './utils/package-json';
15
+ import type { Platform } from '../lib/Constants';
16
+ import type { PackageDotJson } from './utils/package-json';
17
17
 
18
18
  type WizardIntegration =
19
19
  | 'reactNative'
@@ -36,13 +36,53 @@ type Args = {
36
36
  quiet: boolean;
37
37
  disableTelemetry: boolean;
38
38
  promoCode?: string;
39
-
39
+ preSelectedProject?: {
40
+ authToken: string;
41
+ selfHosted: boolean;
42
+ dsn: string;
43
+ projectId: string;
44
+ projectSlug: string;
45
+ projectName: string;
46
+ orgId: string;
47
+ orgName: string;
48
+ orgSlug: string;
49
+ };
40
50
  url?: string;
41
51
  platform?: Platform[];
42
52
  org?: string;
43
53
  project?: string;
54
+ saas?: boolean;
44
55
  };
45
56
 
57
+ function preSelectedProjectArgsToObject(
58
+ args: Args,
59
+ ): PreselectedProject | undefined {
60
+ if (!args.preSelectedProject) {
61
+ return undefined;
62
+ }
63
+
64
+ return {
65
+ authToken: args.preSelectedProject.authToken,
66
+ selfHosted: args.preSelectedProject.selfHosted,
67
+ project: {
68
+ id: args.preSelectedProject.projectId,
69
+ keys: [
70
+ {
71
+ dsn: {
72
+ public: args.preSelectedProject.dsn,
73
+ },
74
+ },
75
+ ],
76
+ organization: {
77
+ id: args.preSelectedProject.orgId,
78
+ name: args.preSelectedProject.orgName,
79
+ slug: args.preSelectedProject.orgSlug,
80
+ },
81
+ slug: args.preSelectedProject.projectSlug,
82
+ },
83
+ };
84
+ }
85
+
46
86
  export async function run(argv: Args) {
47
87
  const finalArgs = {
48
88
  ...argv,
@@ -79,18 +119,20 @@ export async function run(argv: Args) {
79
119
  }
80
120
 
81
121
  const wizardOptions: WizardOptions = {
82
- telemetryEnabled: !argv.disableTelemetry,
83
- promoCode: argv.promoCode,
84
- url: argv.url,
85
- orgSlug: argv.org,
86
- projectSlug: argv.project,
122
+ telemetryEnabled: !finalArgs.disableTelemetry,
123
+ promoCode: finalArgs.promoCode,
124
+ url: finalArgs.url,
125
+ orgSlug: finalArgs.org,
126
+ projectSlug: finalArgs.project,
127
+ saas: finalArgs.saas,
128
+ preSelectedProject: preSelectedProjectArgsToObject(finalArgs),
87
129
  };
88
130
 
89
131
  switch (integration) {
90
132
  case 'reactNative':
91
133
  await runReactNativeWizard({
92
134
  ...wizardOptions,
93
- uninstall: argv.uninstall,
135
+ uninstall: finalArgs.uninstall,
94
136
  });
95
137
  break;
96
138
 
@@ -129,7 +171,7 @@ export async function run(argv: Args) {
129
171
  break;
130
172
 
131
173
  default:
132
- clack.log.error(`No setup wizard selected!`);
174
+ clack.log.error('No setup wizard selected!');
133
175
  }
134
176
  }
135
177
 
@@ -13,20 +13,21 @@ import {
13
13
  getOrAskForProjectData,
14
14
  } from '../utils/clack-utils';
15
15
  import { isUnicodeSupported } from '../utils/vendor/is-unicorn-supported';
16
- import { SourceMapUploadToolConfigurationOptions } from './tools/types';
16
+ import type { SourceMapUploadToolConfigurationOptions } from './tools/types';
17
17
  import { configureVitePlugin } from './tools/vite';
18
18
  import { setupNpmScriptInCI, configureSentryCLI } from './tools/sentry-cli';
19
19
  import { configureWebPackPlugin } from './tools/webpack';
20
20
  import { configureTscSourcemapGenerationFlow } from './tools/tsc';
21
21
  import { configureRollupPlugin } from './tools/rollup';
22
22
  import { configureEsbuildPlugin } from './tools/esbuild';
23
- import { WizardOptions } from '../utils/types';
23
+ import type { WizardOptions } from '../utils/types';
24
24
  import { configureCRASourcemapGenerationFlow } from './tools/create-react-app';
25
25
  import { ensureMinimumSdkVersionIsInstalled } from './utils/sdk-version';
26
26
  import { traceStep, withTelemetry } from '../telemetry';
27
27
  import { checkIfMoreSuitableWizardExistsAndAskForRedirect } from './utils/other-wizards';
28
28
  import { configureAngularSourcemapGenerationFlow } from './tools/angular';
29
- import { detectUsedTool, SupportedTools } from './utils/detect-tool';
29
+ import type { SupportedTools } from './utils/detect-tool';
30
+ import { detectUsedTool } from './utils/detect-tool';
30
31
  import { configureNextJsSourceMapsUpload } from './tools/nextjs';
31
32
  import { configureRemixSourceMapsUpload } from './tools/remix';
32
33
  import { detectPackageManger } from '../utils/package-manager';
@@ -4,8 +4,8 @@ import chalk from 'chalk';
4
4
  import { runRemixWizard } from '../../remix/remix-wizard';
5
5
  import { traceStep } from '../../telemetry';
6
6
  import { abortIfCancelled } from '../../utils/clack-utils';
7
- import { WizardOptions } from '../../utils/types';
8
- import { SourceMapUploadToolConfigurationOptions } from './types';
7
+ import type { WizardOptions } from '../../utils/types';
8
+ import type { SourceMapUploadToolConfigurationOptions } from './types';
9
9
 
10
10
  import * as Sentry from '@sentry/node';
11
11
 
package/src/telemetry.ts CHANGED
@@ -34,6 +34,7 @@ export async function withTelemetry<F>(
34
34
  // Set tag for passed CLI args
35
35
  sentryHub.setTag('args.project', !!options.wizardOptions.projectSlug);
36
36
  sentryHub.setTag('args.org', !!options.wizardOptions.orgSlug);
37
+ sentryHub.setTag('args.saas', !!options.wizardOptions.saas);
37
38
 
38
39
  try {
39
40
  return await startSpan(
@@ -691,20 +691,29 @@ export async function runPrettierIfInstalled(): Promise<void> {
691
691
  return;
692
692
  }
693
693
 
694
+ const changedOrUntrackedFiles = getUncommittedOrUntrackedFiles()
695
+ .map((filename) => {
696
+ return filename.startsWith('- ') ? filename.slice(2) : filename;
697
+ })
698
+ .join(' ');
699
+
694
700
  const prettierSpinner = clack.spinner();
695
701
  prettierSpinner.start('Running Prettier on your files.');
696
702
 
697
703
  try {
698
704
  await new Promise<void>((resolve, reject) => {
699
- childProcess.exec('npx prettier --write .', (err) => {
700
- if (err) {
701
- reject(err);
702
- } else {
703
- resolve();
704
- }
705
- });
705
+ childProcess.exec(
706
+ `npx prettier --ignore-unknown --write ${changedOrUntrackedFiles}`,
707
+ (err) => {
708
+ if (err) {
709
+ reject(err);
710
+ } else {
711
+ resolve();
712
+ }
713
+ },
714
+ );
706
715
  });
707
- } catch {
716
+ } catch (e) {
708
717
  prettierSpinner.stop('Prettier failed to run.');
709
718
  clack.log.error(
710
719
  'Prettier failed to run. There may be formatting issues in your updated files.',
@@ -847,7 +856,7 @@ export async function getOrAskForProjectData(
847
856
  }
848
857
  const { url: sentryUrl, selfHosted } = await traceStep(
849
858
  'ask-self-hosted',
850
- () => askForSelfHosted(options.url),
859
+ () => askForSelfHosted(options.url, options.saas),
851
860
  );
852
861
 
853
862
  const { projects, apiKeys } = await traceStep('login', () =>
@@ -908,10 +917,19 @@ ${chalk.cyan(
908
917
  *
909
918
  * @param urlFromArgs the url passed via the --url arg
910
919
  */
911
- async function askForSelfHosted(urlFromArgs?: string): Promise<{
920
+ async function askForSelfHosted(
921
+ urlFromArgs?: string,
922
+ saas?: boolean,
923
+ ): Promise<{
912
924
  url: string;
913
925
  selfHosted: boolean;
914
926
  }> {
927
+ if (saas) {
928
+ Sentry.setTag('url', SAAS_URL);
929
+ Sentry.setTag('self-hosted', false);
930
+ return { url: SAAS_URL, selfHosted: false };
931
+ }
932
+
915
933
  if (!urlFromArgs) {
916
934
  const choice: 'saas' | 'self-hosted' | symbol = await abortIfCancelled(
917
935
  clack.select({
@@ -1,20 +1,20 @@
1
1
  export interface SentryProjectData {
2
2
  id: string;
3
3
  slug: string;
4
- status: string;
5
4
  organization: {
6
5
  id: string;
7
6
  name: string;
8
7
  slug: string;
9
- region: string;
10
- status: {
11
- id: string;
12
- name: string;
13
- };
14
8
  };
15
- keys: [{ dsn: { public: string }; isActive: boolean }];
9
+ keys: [{ dsn: { public: string } }];
16
10
  }
17
11
 
12
+ export type PreselectedProject = {
13
+ project: SentryProjectData;
14
+ authToken: string;
15
+ selfHosted: boolean;
16
+ };
17
+
18
18
  export type WizardOptions = {
19
19
  /**
20
20
  * Controls whether the wizard should send telemetry data to Sentry.
@@ -47,16 +47,16 @@ export type WizardOptions = {
47
47
  */
48
48
  projectSlug?: string;
49
49
 
50
+ /**
51
+ * If this option is set, the wizard will skip the self-hosted or SaaS
52
+ * selection step and directly assume that the wizard is used for Sentry SaaS.
53
+ */
54
+ saas?: boolean;
55
+
50
56
  /**
51
57
  * If this is set, the wizard will skip the login and project selection step.
52
- * (This can not yet be set externally but for example when redirecting from
53
- * one wizard to another when the project was already selected)
54
58
  */
55
- preSelectedProject?: {
56
- project: SentryProjectData;
57
- authToken: string;
58
- selfHosted: boolean;
59
- };
59
+ preSelectedProject?: PreselectedProject;
60
60
  };
61
61
 
62
62
  export interface Feature {