@sentry/wizard 3.3.2 → 3.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/bin.ts +29 -19
- package/dist/bin.js +23 -18
- package/dist/bin.js.map +1 -1
- package/dist/lib/Helper/Wizard.js +0 -9
- package/dist/lib/Helper/Wizard.js.map +1 -1
- package/dist/lib/Setup.js.map +1 -1
- package/dist/lib/Steps/ChooseIntegration.js +26 -10
- package/dist/lib/Steps/ChooseIntegration.js.map +1 -1
- package/dist/lib/Steps/Integrations/{NextJs.d.ts → NextJsShim.d.ts} +1 -1
- package/dist/lib/Steps/Integrations/{NextJs.js → NextJsShim.js} +13 -10
- package/dist/lib/Steps/Integrations/NextJsShim.js.map +1 -0
- package/dist/lib/Steps/Integrations/SourceMapsShim.js +4 -1
- package/dist/lib/Steps/Integrations/SourceMapsShim.js.map +1 -1
- package/dist/lib/Steps/Integrations/{SvelteKit.d.ts → SvelteKitShim.d.ts} +1 -1
- package/dist/lib/Steps/Integrations/{SvelteKit.js → SvelteKitShim.js} +13 -10
- package/dist/lib/Steps/Integrations/SvelteKitShim.js.map +1 -0
- package/dist/package.json +3 -3
- package/dist/src/nextjs/nextjs-wizard.d.ts +2 -5
- package/dist/src/nextjs/nextjs-wizard.js +1 -1
- package/dist/src/nextjs/nextjs-wizard.js.map +1 -1
- package/dist/src/sourcemaps/sourcemaps-wizard.d.ts +2 -5
- package/dist/src/sourcemaps/sourcemaps-wizard.js +68 -31
- package/dist/src/sourcemaps/sourcemaps-wizard.js.map +1 -1
- package/dist/src/sourcemaps/tools/create-react-app.d.ts +1 -0
- package/dist/src/sourcemaps/tools/create-react-app.js +69 -0
- package/dist/src/sourcemaps/tools/create-react-app.js.map +1 -0
- package/dist/src/sourcemaps/tools/esbuild.d.ts +2 -0
- package/dist/src/sourcemaps/tools/esbuild.js +109 -0
- package/dist/src/sourcemaps/tools/esbuild.js.map +1 -0
- package/dist/src/sourcemaps/tools/rollup.d.ts +2 -0
- package/dist/src/sourcemaps/tools/rollup.js +109 -0
- package/dist/src/sourcemaps/tools/rollup.js.map +1 -0
- package/dist/src/sourcemaps/tools/sentry-cli.d.ts +2 -2
- package/dist/src/sourcemaps/tools/sentry-cli.js +111 -91
- package/dist/src/sourcemaps/tools/sentry-cli.js.map +1 -1
- package/dist/src/sourcemaps/tools/tsc.d.ts +1 -0
- package/dist/src/sourcemaps/tools/tsc.js +93 -0
- package/dist/src/sourcemaps/tools/tsc.js.map +1 -0
- package/dist/src/sourcemaps/utils/sdk-version.d.ts +14 -0
- package/dist/src/sourcemaps/utils/sdk-version.js +275 -0
- package/dist/src/sourcemaps/utils/sdk-version.js.map +1 -0
- package/dist/src/sveltekit/sveltekit-wizard.d.ts +2 -5
- package/dist/src/sveltekit/sveltekit-wizard.js +1 -1
- package/dist/src/sveltekit/sveltekit-wizard.js.map +1 -1
- package/dist/src/utils/clack-utils.d.ts +13 -2
- package/dist/src/utils/clack-utils.js +78 -45
- package/dist/src/utils/clack-utils.js.map +1 -1
- package/dist/src/utils/types.d.ts +12 -0
- package/dist/src/utils/types.js +3 -0
- package/dist/src/utils/types.js.map +1 -0
- package/lib/Helper/Wizard.ts +0 -9
- package/lib/Setup.ts +1 -0
- package/lib/Steps/ChooseIntegration.ts +35 -11
- package/lib/Steps/Integrations/{NextJs.ts → NextJsShim.ts} +5 -2
- package/lib/Steps/Integrations/SourceMapsShim.ts +4 -1
- package/lib/Steps/Integrations/{SvelteKit.ts → SvelteKitShim.ts} +5 -2
- package/package.json +3 -3
- package/src/nextjs/nextjs-wizard.ts +3 -8
- package/src/sourcemaps/sourcemaps-wizard.ts +67 -38
- package/src/sourcemaps/tools/create-react-app.ts +19 -0
- package/src/sourcemaps/tools/esbuild.ts +65 -0
- package/src/sourcemaps/tools/rollup.ts +69 -0
- package/src/sourcemaps/tools/sentry-cli.ts +114 -105
- package/src/sourcemaps/tools/tsc.ts +39 -0
- package/src/sourcemaps/utils/sdk-version.ts +264 -0
- package/src/sveltekit/sveltekit-wizard.ts +3 -6
- package/src/utils/clack-utils.ts +71 -29
- package/src/utils/types.ts +13 -0
- package/dist/lib/Steps/Integrations/NextJs.js.map +0 -1
- package/dist/lib/Steps/Integrations/SvelteKit.js.map +0 -1
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// @ts-ignore - clack is ESM and TS complains about that. It works though
|
|
2
|
+
import clack, { select } from '@clack/prompts';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import {
|
|
5
|
+
abortIfCancelled,
|
|
6
|
+
addDotEnvSentryBuildPluginFile,
|
|
7
|
+
getPackageDotJson,
|
|
8
|
+
hasPackageInstalled,
|
|
9
|
+
installPackage,
|
|
10
|
+
} from '../../utils/clack-utils';
|
|
11
|
+
|
|
12
|
+
import {
|
|
13
|
+
SourceMapUploadToolConfigurationFunction,
|
|
14
|
+
SourceMapUploadToolConfigurationOptions,
|
|
15
|
+
} from './types';
|
|
16
|
+
|
|
17
|
+
const getCodeSnippet = (options: SourceMapUploadToolConfigurationOptions) =>
|
|
18
|
+
chalk.gray(`
|
|
19
|
+
${chalk.greenBright(
|
|
20
|
+
'const { sentryEsbuildPlugin } = require("@sentry/esbuild-plugin");',
|
|
21
|
+
)}
|
|
22
|
+
|
|
23
|
+
require("esbuild").build({
|
|
24
|
+
${chalk.greenBright(
|
|
25
|
+
'sourcemap: true, // Source map generation must be turned on',
|
|
26
|
+
)}
|
|
27
|
+
plugins: [
|
|
28
|
+
// Put the Sentry esbuild plugin after all other plugins
|
|
29
|
+
${chalk.greenBright(`sentryEsbuildPlugin({
|
|
30
|
+
authToken: process.env.SENTRY_AUTH_TOKEN,
|
|
31
|
+
org: "${options.orgSlug}",
|
|
32
|
+
project: "${options.projectSlug}",${
|
|
33
|
+
options.selfHosted ? `\n url: "${options.url}",` : ''
|
|
34
|
+
}
|
|
35
|
+
}),`)}
|
|
36
|
+
],
|
|
37
|
+
});
|
|
38
|
+
`);
|
|
39
|
+
|
|
40
|
+
export const configureEsbuildPlugin: SourceMapUploadToolConfigurationFunction =
|
|
41
|
+
async (options) => {
|
|
42
|
+
await installPackage({
|
|
43
|
+
packageName: '@sentry/esbuild-plugin',
|
|
44
|
+
alreadyInstalled: hasPackageInstalled(
|
|
45
|
+
'@sentry/esbuild-plugin',
|
|
46
|
+
await getPackageDotJson(),
|
|
47
|
+
),
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
clack.log.step(`Add the following code to your esbuild config:`);
|
|
51
|
+
|
|
52
|
+
// Intentially logging directly to console here so that the code can be copied/pasted directly
|
|
53
|
+
// eslint-disable-next-line no-console
|
|
54
|
+
console.log(getCodeSnippet(options));
|
|
55
|
+
|
|
56
|
+
await abortIfCancelled(
|
|
57
|
+
select({
|
|
58
|
+
message: 'Did you copy the snippet above?',
|
|
59
|
+
options: [{ label: 'Yes, continue!', value: true }],
|
|
60
|
+
initialValue: true,
|
|
61
|
+
}),
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
await addDotEnvSentryBuildPluginFile(options.authToken);
|
|
65
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// @ts-ignore - clack is ESM and TS complains about that. It works though
|
|
2
|
+
import clack, { select } from '@clack/prompts';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import {
|
|
5
|
+
abortIfCancelled,
|
|
6
|
+
addDotEnvSentryBuildPluginFile,
|
|
7
|
+
getPackageDotJson,
|
|
8
|
+
hasPackageInstalled,
|
|
9
|
+
installPackage,
|
|
10
|
+
} from '../../utils/clack-utils';
|
|
11
|
+
|
|
12
|
+
import {
|
|
13
|
+
SourceMapUploadToolConfigurationFunction,
|
|
14
|
+
SourceMapUploadToolConfigurationOptions,
|
|
15
|
+
} from './types';
|
|
16
|
+
|
|
17
|
+
const getCodeSnippet = (options: SourceMapUploadToolConfigurationOptions) =>
|
|
18
|
+
chalk.gray(`
|
|
19
|
+
${chalk.greenBright(
|
|
20
|
+
'import { sentryRollupPlugin } from "@sentry/rollup-plugin";',
|
|
21
|
+
)}
|
|
22
|
+
|
|
23
|
+
export default {
|
|
24
|
+
output: {
|
|
25
|
+
${chalk.greenBright(
|
|
26
|
+
'sourcemap: true, // Source map generation must be turned on',
|
|
27
|
+
)}
|
|
28
|
+
},
|
|
29
|
+
plugins: [
|
|
30
|
+
// Put the Sentry rollup plugin after all other plugins
|
|
31
|
+
${chalk.greenBright(`sentryRollupPlugin({
|
|
32
|
+
authToken: process.env.SENTRY_AUTH_TOKEN,
|
|
33
|
+
org: "${options.orgSlug}",
|
|
34
|
+
project: "${options.projectSlug}",${
|
|
35
|
+
options.selfHosted ? `\n url: "${options.url}",` : ''
|
|
36
|
+
}
|
|
37
|
+
}),`)}
|
|
38
|
+
],
|
|
39
|
+
};
|
|
40
|
+
`);
|
|
41
|
+
|
|
42
|
+
export const configureRollupPlugin: SourceMapUploadToolConfigurationFunction =
|
|
43
|
+
async (options) => {
|
|
44
|
+
await installPackage({
|
|
45
|
+
packageName: '@sentry/rollup-plugin',
|
|
46
|
+
alreadyInstalled: hasPackageInstalled(
|
|
47
|
+
'@sentry/rollup-plugin',
|
|
48
|
+
await getPackageDotJson(),
|
|
49
|
+
),
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
clack.log.step(
|
|
53
|
+
`Add the following code to your rollup config:`,
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
// Intentially logging directly to console here so that the code can be copied/pasted directly
|
|
57
|
+
// eslint-disable-next-line no-console
|
|
58
|
+
console.log(getCodeSnippet(options));
|
|
59
|
+
|
|
60
|
+
await abortIfCancelled(
|
|
61
|
+
select({
|
|
62
|
+
message: 'Did you copy the snippet above?',
|
|
63
|
+
options: [{ label: 'Yes, continue!', value: true }],
|
|
64
|
+
initialValue: true,
|
|
65
|
+
}),
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
await addDotEnvSentryBuildPluginFile(options.authToken);
|
|
69
|
+
};
|
|
@@ -12,117 +12,126 @@ import {
|
|
|
12
12
|
installPackage,
|
|
13
13
|
} from '../../utils/clack-utils';
|
|
14
14
|
|
|
15
|
-
import {
|
|
16
|
-
|
|
17
|
-
export const configureSentryCLI: SourceMapUploadToolConfigurationFunction =
|
|
18
|
-
async (options) => {
|
|
19
|
-
const packageDotJson = await getPackageDotJson();
|
|
20
|
-
|
|
21
|
-
await installPackage({
|
|
22
|
-
packageName: '@sentry/cli',
|
|
23
|
-
alreadyInstalled: hasPackageInstalled('@sentry/cli', packageDotJson),
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
let validPath = false;
|
|
27
|
-
let relativeArtifactPath;
|
|
28
|
-
do {
|
|
29
|
-
const rawArtifactPath = await abortIfCancelled(
|
|
30
|
-
clack.text({
|
|
31
|
-
message: 'Where are your build artifacts located?',
|
|
32
|
-
placeholder: `.${path.sep}out`,
|
|
33
|
-
}),
|
|
34
|
-
);
|
|
35
|
-
|
|
36
|
-
if (path.isAbsolute(rawArtifactPath)) {
|
|
37
|
-
relativeArtifactPath = path.relative(process.cwd(), rawArtifactPath);
|
|
38
|
-
} else {
|
|
39
|
-
relativeArtifactPath = rawArtifactPath;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
try {
|
|
43
|
-
await fs.promises.access(
|
|
44
|
-
path.join(process.cwd(), relativeArtifactPath),
|
|
45
|
-
);
|
|
46
|
-
validPath = true;
|
|
47
|
-
} catch {
|
|
48
|
-
validPath = await abortIfCancelled(
|
|
49
|
-
clack.select({
|
|
50
|
-
message: `We couldn't find artifacts at ${relativeArtifactPath}. Are you sure that this is the location that contains your build artifacts?`,
|
|
51
|
-
options: [
|
|
52
|
-
{
|
|
53
|
-
label: 'No, let me verify.',
|
|
54
|
-
value: false,
|
|
55
|
-
},
|
|
56
|
-
{ label: 'Yes, I am sure!', value: true },
|
|
57
|
-
],
|
|
58
|
-
initialValue: false,
|
|
59
|
-
}),
|
|
60
|
-
);
|
|
61
|
-
}
|
|
62
|
-
} while (!validPath);
|
|
63
|
-
|
|
64
|
-
const relativePosixArtifactPath = relativeArtifactPath
|
|
65
|
-
.split(path.sep)
|
|
66
|
-
.join(path.posix.sep);
|
|
67
|
-
|
|
68
|
-
await abortIfCancelled(
|
|
69
|
-
clack.select({
|
|
70
|
-
message: `Verify that your build tool is generating source maps. ${chalk.dim(
|
|
71
|
-
'(Your build output folder should contain .js.map files after a build)',
|
|
72
|
-
)}`,
|
|
73
|
-
options: [{ label: 'I checked. Continue!', value: true }],
|
|
74
|
-
initialValue: true,
|
|
75
|
-
}),
|
|
76
|
-
);
|
|
15
|
+
import { SourceMapUploadToolConfigurationOptions } from './types';
|
|
77
16
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
} ${relativePosixArtifactPath} && sentry-cli${
|
|
84
|
-
options.selfHosted ? ` --url ${options.url}` : ''
|
|
85
|
-
} sourcemaps upload --org ${options.orgSlug} --project ${
|
|
86
|
-
options.projectSlug
|
|
87
|
-
} ${relativePosixArtifactPath}`;
|
|
88
|
-
|
|
89
|
-
await fs.promises.writeFile(
|
|
90
|
-
path.join(process.cwd(), 'package.json'),
|
|
91
|
-
JSON.stringify(packageDotJson, null, 2),
|
|
92
|
-
);
|
|
17
|
+
export async function configureSentryCLI(
|
|
18
|
+
options: SourceMapUploadToolConfigurationOptions,
|
|
19
|
+
configureSourcemapGenerationFlow: () => Promise<void> = defaultConfigureSourcemapGenerationFlow,
|
|
20
|
+
): Promise<void> {
|
|
21
|
+
const packageDotJson = await getPackageDotJson();
|
|
93
22
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
'after',
|
|
99
|
-
)} building your application but ${chalk.bold('before')} deploying!`,
|
|
100
|
-
);
|
|
23
|
+
await installPackage({
|
|
24
|
+
packageName: '@sentry/cli',
|
|
25
|
+
alreadyInstalled: hasPackageInstalled('@sentry/cli', packageDotJson),
|
|
26
|
+
});
|
|
101
27
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
),
|
|
115
|
-
},
|
|
116
|
-
],
|
|
117
|
-
initialValue: true,
|
|
28
|
+
let validPath = false;
|
|
29
|
+
let relativeArtifactPath;
|
|
30
|
+
do {
|
|
31
|
+
const rawArtifactPath = await abortIfCancelled(
|
|
32
|
+
clack.text({
|
|
33
|
+
message: 'Where are your build artifacts located?',
|
|
34
|
+
placeholder: `.${path.sep}out`,
|
|
35
|
+
validate(value) {
|
|
36
|
+
if (!value) {
|
|
37
|
+
return 'Please enter a path.';
|
|
38
|
+
}
|
|
39
|
+
},
|
|
118
40
|
}),
|
|
119
41
|
);
|
|
120
42
|
|
|
121
|
-
|
|
43
|
+
if (path.isAbsolute(rawArtifactPath)) {
|
|
44
|
+
relativeArtifactPath = path.relative(process.cwd(), rawArtifactPath);
|
|
45
|
+
} else {
|
|
46
|
+
relativeArtifactPath = rawArtifactPath;
|
|
47
|
+
}
|
|
122
48
|
|
|
123
|
-
|
|
124
|
-
|
|
49
|
+
try {
|
|
50
|
+
await fs.promises.access(path.join(process.cwd(), relativeArtifactPath));
|
|
51
|
+
validPath = true;
|
|
52
|
+
} catch {
|
|
53
|
+
validPath = await abortIfCancelled(
|
|
54
|
+
clack.select({
|
|
55
|
+
message: `We couldn't find artifacts at ${relativeArtifactPath}. Are you sure that this is the location that contains your build artifacts?`,
|
|
56
|
+
options: [
|
|
57
|
+
{
|
|
58
|
+
label: 'No, let me verify.',
|
|
59
|
+
value: false,
|
|
60
|
+
},
|
|
61
|
+
{ label: 'Yes, I am sure!', value: true },
|
|
62
|
+
],
|
|
63
|
+
initialValue: false,
|
|
64
|
+
}),
|
|
65
|
+
);
|
|
125
66
|
}
|
|
67
|
+
} while (!validPath);
|
|
68
|
+
|
|
69
|
+
const relativePosixArtifactPath = relativeArtifactPath
|
|
70
|
+
.split(path.sep)
|
|
71
|
+
.join(path.posix.sep);
|
|
72
|
+
|
|
73
|
+
await configureSourcemapGenerationFlow();
|
|
74
|
+
|
|
75
|
+
packageDotJson.scripts = packageDotJson.scripts || {};
|
|
76
|
+
packageDotJson.scripts['sentry:ci'] = `sentry-cli sourcemaps inject --org ${
|
|
77
|
+
options.orgSlug
|
|
78
|
+
} --project ${
|
|
79
|
+
options.projectSlug
|
|
80
|
+
} ${relativePosixArtifactPath} && sentry-cli${
|
|
81
|
+
options.selfHosted ? ` --url ${options.url}` : ''
|
|
82
|
+
} sourcemaps upload --org ${options.orgSlug} --project ${
|
|
83
|
+
options.projectSlug
|
|
84
|
+
} ${relativePosixArtifactPath}`;
|
|
85
|
+
|
|
86
|
+
await fs.promises.writeFile(
|
|
87
|
+
path.join(process.cwd(), 'package.json'),
|
|
88
|
+
JSON.stringify(packageDotJson, null, 2),
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
clack.log.info(
|
|
92
|
+
`Added a ${chalk.cyan('sentry:ci')} script to your ${chalk.cyan(
|
|
93
|
+
'package.json',
|
|
94
|
+
)}. Make sure to run this script ${chalk.bold(
|
|
95
|
+
'after',
|
|
96
|
+
)} building your application but ${chalk.bold('before')} deploying!`,
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
const addedToCI = await abortIfCancelled(
|
|
100
|
+
clack.select({
|
|
101
|
+
message: `Did you add a step to your CI pipeline that runs the ${chalk.cyan(
|
|
102
|
+
'sentry:ci',
|
|
103
|
+
)} script ${chalk.bold('right after')} building your application?`,
|
|
104
|
+
options: [
|
|
105
|
+
{ label: 'Yes, continue!', value: true },
|
|
106
|
+
{
|
|
107
|
+
label: "I'll do it later...",
|
|
108
|
+
value: false,
|
|
109
|
+
hint: chalk.yellow(
|
|
110
|
+
'You need to run the command after each build for source maps to work properly.',
|
|
111
|
+
),
|
|
112
|
+
},
|
|
113
|
+
],
|
|
114
|
+
initialValue: true,
|
|
115
|
+
}),
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
Sentry.setTag('added-ci-script', addedToCI);
|
|
119
|
+
|
|
120
|
+
if (!addedToCI) {
|
|
121
|
+
clack.log.info("Don't forget! :)");
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
await addSentryCliRc(options.authToken);
|
|
125
|
+
}
|
|
126
126
|
|
|
127
|
-
|
|
128
|
-
|
|
127
|
+
async function defaultConfigureSourcemapGenerationFlow(): Promise<void> {
|
|
128
|
+
await abortIfCancelled(
|
|
129
|
+
clack.select({
|
|
130
|
+
message: `Verify that your build tool is generating source maps. ${chalk.dim(
|
|
131
|
+
'(Your build output folder should contain .js.map files after a build)',
|
|
132
|
+
)}`,
|
|
133
|
+
options: [{ label: 'I checked. Continue!', value: true }],
|
|
134
|
+
initialValue: true,
|
|
135
|
+
}),
|
|
136
|
+
);
|
|
137
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// @ts-ignore - clack is ESM and TS complains about that. It works though
|
|
2
|
+
import clack, { select } from '@clack/prompts';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { abortIfCancelled } from '../../utils/clack-utils';
|
|
5
|
+
|
|
6
|
+
export async function configureTscSourcemapGenerationFlow(): Promise<void> {
|
|
7
|
+
clack.log.step(
|
|
8
|
+
`Add the following code to your ${chalk.bold(
|
|
9
|
+
'tsconfig.json',
|
|
10
|
+
)} file: ${chalk.dim(
|
|
11
|
+
'(This ensures that source maps are generated correctly)',
|
|
12
|
+
)}`,
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
// Intentially logging directly to console here so that the code can be copied/pasted directly
|
|
16
|
+
// eslint-disable-next-line no-console
|
|
17
|
+
console.log(codeSnippet);
|
|
18
|
+
|
|
19
|
+
await abortIfCancelled(
|
|
20
|
+
select({
|
|
21
|
+
message: 'Did you update your config as shown in the snippet above?',
|
|
22
|
+
options: [{ label: 'Yes, continue!', value: true }],
|
|
23
|
+
initialValue: true,
|
|
24
|
+
}),
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const codeSnippet = chalk.gray(`
|
|
29
|
+
{
|
|
30
|
+
"compilerOptions": {
|
|
31
|
+
${chalk.greenBright('"sourceMap": true,')}
|
|
32
|
+
${chalk.greenBright('"inlineSources": true,')}
|
|
33
|
+
|
|
34
|
+
// Set \`sourceRoot\` to "/" to strip the build path prefix from
|
|
35
|
+
// generated source code references. This will improve issue grouping in Sentry.
|
|
36
|
+
${chalk.greenBright('"sourceRoot": "/"')}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
`);
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
// @ts-ignore - clack is ESM and TS complains about that. It works though
|
|
2
|
+
import clack from '@clack/prompts';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { minVersion, satisfies } from 'semver';
|
|
5
|
+
import {
|
|
6
|
+
abortIfCancelled,
|
|
7
|
+
getPackageDotJson,
|
|
8
|
+
getPackageVersion,
|
|
9
|
+
installPackage,
|
|
10
|
+
} from '../../utils/clack-utils';
|
|
11
|
+
|
|
12
|
+
import * as Sentry from '@sentry/node';
|
|
13
|
+
|
|
14
|
+
const MINIMUM_DEBUG_ID_SDK_VERSION = '7.47.0';
|
|
15
|
+
|
|
16
|
+
// This array is orderd by the SDKs we want to check for first.
|
|
17
|
+
// The reason is that some SDKs depend on others and some users might
|
|
18
|
+
// have added the dependencies to their package.json. We want to make sure
|
|
19
|
+
// that we actually detect the "top-level" SDK first.
|
|
20
|
+
const SENTRY_SDK_PACKAGE_NAMES = [
|
|
21
|
+
// SDKs using other framework SDKs need to be checked first
|
|
22
|
+
'@sentry/gatsby',
|
|
23
|
+
'@sentry/nextjs',
|
|
24
|
+
'@sentry/remix',
|
|
25
|
+
'@sentry/sveltekit',
|
|
26
|
+
|
|
27
|
+
// Framework SDKs
|
|
28
|
+
'@sentry/angular',
|
|
29
|
+
'@sentry/angular-ivy',
|
|
30
|
+
'@sentry/ember',
|
|
31
|
+
'@sentry/react',
|
|
32
|
+
'@sentry/svelte',
|
|
33
|
+
'@sentry/vue',
|
|
34
|
+
'@sentry/serverless',
|
|
35
|
+
|
|
36
|
+
// Base SDKs
|
|
37
|
+
'@sentry/browser',
|
|
38
|
+
'@sentry/node',
|
|
39
|
+
] as const;
|
|
40
|
+
|
|
41
|
+
type SdkPackage = {
|
|
42
|
+
name: (typeof SENTRY_SDK_PACKAGE_NAMES)[number];
|
|
43
|
+
version: string;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Check for a minimum SDK version and prompt the user to upgrade if necessary.
|
|
48
|
+
* We distinguish between 4 cases here:
|
|
49
|
+
*
|
|
50
|
+
* 1. Users didn't install any SDK yet
|
|
51
|
+
* -> We tell them to install an SDK and then continue with the wizard
|
|
52
|
+
* 2. Users installed an SDK in the range >=7.47.0
|
|
53
|
+
* -> All good, no need to do anything!
|
|
54
|
+
* 3. Users installed an SDK in the range >=7.0.0 <= 7.46.0
|
|
55
|
+
* -> We ask if they want to auto-update to the latest version
|
|
56
|
+
* 4. Users installed an SDK in the range <7.x
|
|
57
|
+
* -> We tell users to manually upgrade (migrate between majors)
|
|
58
|
+
*/
|
|
59
|
+
export async function ensureMinimumSdkVersionIsInstalled(): Promise<void> {
|
|
60
|
+
const packageJson = await getPackageDotJson();
|
|
61
|
+
|
|
62
|
+
const installedSdkPackages = SENTRY_SDK_PACKAGE_NAMES.map((packageName) => ({
|
|
63
|
+
name: packageName,
|
|
64
|
+
version: getPackageVersion(packageName, packageJson),
|
|
65
|
+
})).filter((sdkPackage): sdkPackage is SdkPackage => !!sdkPackage.version);
|
|
66
|
+
|
|
67
|
+
const installedSdkPackage =
|
|
68
|
+
installedSdkPackages.length > 0 && installedSdkPackages[0];
|
|
69
|
+
|
|
70
|
+
// Case 1:
|
|
71
|
+
if (!installedSdkPackage) {
|
|
72
|
+
return await handleNoSdkInstalled();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const { name: installedSdkName, version: installedSdkVersionOrRange } =
|
|
76
|
+
installedSdkPackage;
|
|
77
|
+
|
|
78
|
+
const minInstalledVersion = getMinInstalledVersion(
|
|
79
|
+
installedSdkVersionOrRange,
|
|
80
|
+
installedSdkName,
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
if (!minInstalledVersion) {
|
|
84
|
+
// This is handled in the getMinInstalledVersion function
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const hasDebugIdCompatibleSdkVersion = satisfies(
|
|
89
|
+
minInstalledVersion,
|
|
90
|
+
`>=${MINIMUM_DEBUG_ID_SDK_VERSION}`,
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
// Case 2:
|
|
94
|
+
if (hasDebugIdCompatibleSdkVersion) {
|
|
95
|
+
Sentry.setTag('initial-sdk-version', '>=7.47.0');
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const hasV7SdkVersion = satisfies(minInstalledVersion, '>=7.0.0');
|
|
100
|
+
|
|
101
|
+
clack.log.warn(
|
|
102
|
+
`${chalk.yellowBright(
|
|
103
|
+
`It seems like you're using an outdated version (${installedSdkVersionOrRange}) of the ${chalk.bold(
|
|
104
|
+
installedSdkName,
|
|
105
|
+
)} SDK.`,
|
|
106
|
+
)}
|
|
107
|
+
Uploading source maps is easiest with an SDK from version ${chalk.bold(
|
|
108
|
+
MINIMUM_DEBUG_ID_SDK_VERSION,
|
|
109
|
+
)} or newer.
|
|
110
|
+
`,
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
// Case 3:
|
|
114
|
+
if (hasV7SdkVersion) {
|
|
115
|
+
await handleAutoUpdateSdk(installedSdkName);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Case 4:
|
|
120
|
+
await handleManuallyUpdateSdk(minInstalledVersion);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
async function handleManuallyUpdateSdk(minInstalledVersion: string) {
|
|
124
|
+
Sentry.setTag(
|
|
125
|
+
'initial-sdk-version',
|
|
126
|
+
`${satisfies(minInstalledVersion, '>=6.0.0') ? '6.x' : '<6.0.0'}`,
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
clack.log
|
|
130
|
+
.info(`When upgrading from a version older than 7.0.0, make sure to follow the migration guide:
|
|
131
|
+
https://github.com/getsentry/sentry-javascript/blob/develop/MIGRATION.md#upgrading-from-6x-to-7x
|
|
132
|
+
`);
|
|
133
|
+
|
|
134
|
+
const didUpdate = await abortIfCancelled(
|
|
135
|
+
clack.select({
|
|
136
|
+
message: 'Did you update your SDK to the latest version?',
|
|
137
|
+
options: [
|
|
138
|
+
{
|
|
139
|
+
label: 'Yes!',
|
|
140
|
+
value: true,
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
label: "No, I'll do it later...",
|
|
144
|
+
value: false,
|
|
145
|
+
hint: chalk.yellow(
|
|
146
|
+
`Remember to update your SDK to at least ${MINIMUM_DEBUG_ID_SDK_VERSION}.`,
|
|
147
|
+
),
|
|
148
|
+
},
|
|
149
|
+
],
|
|
150
|
+
initialValue: true,
|
|
151
|
+
}),
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
Sentry.setTag(
|
|
155
|
+
'resolved-sdk-status',
|
|
156
|
+
didUpdate ? 'updated-manually' : 'update-later',
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
async function handleAutoUpdateSdk(packageName: string) {
|
|
161
|
+
Sentry.setTag('initial-sdk-version', '>=7.0.0 <7.47.0');
|
|
162
|
+
|
|
163
|
+
const shouldUpdate = await abortIfCancelled(
|
|
164
|
+
clack.select({
|
|
165
|
+
message:
|
|
166
|
+
'Do you want to automatically update your SDK to the latest version?',
|
|
167
|
+
options: [
|
|
168
|
+
{
|
|
169
|
+
label: 'Yes!',
|
|
170
|
+
value: true,
|
|
171
|
+
hint: chalk.green('Recommended'),
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
label: "No, I'll do it later...",
|
|
175
|
+
value: false,
|
|
176
|
+
hint: chalk.yellow(
|
|
177
|
+
`Remember to update your SDK to at least ${MINIMUM_DEBUG_ID_SDK_VERSION}.`,
|
|
178
|
+
),
|
|
179
|
+
},
|
|
180
|
+
],
|
|
181
|
+
initialValue: true,
|
|
182
|
+
}),
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
if (shouldUpdate) {
|
|
186
|
+
await installPackage({
|
|
187
|
+
packageName,
|
|
188
|
+
alreadyInstalled: true,
|
|
189
|
+
askBeforeUpdating: false, // we already did this above
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
Sentry.setTag(
|
|
194
|
+
'resolved-sdk-status',
|
|
195
|
+
shouldUpdate ? 'updated-automatically' : 'update-later',
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
async function handleNoSdkInstalled(): Promise<void> {
|
|
200
|
+
Sentry.setTag('initial-sdk-version', 'none');
|
|
201
|
+
|
|
202
|
+
clack.log.warn(
|
|
203
|
+
`${chalk.yellowBright(
|
|
204
|
+
`It seems like you didn't yet install a Sentry SDK in your project.`,
|
|
205
|
+
)}
|
|
206
|
+
We recommend setting up the SDK before continuing with the source maps wizard.
|
|
207
|
+
|
|
208
|
+
${chalk.dim(`Take a look at our docs to get started:
|
|
209
|
+
https://docs.sentry.io/`)}`,
|
|
210
|
+
);
|
|
211
|
+
|
|
212
|
+
const installedSDK = await abortIfCancelled(
|
|
213
|
+
clack.select({
|
|
214
|
+
message: 'Did you set up your Sentry SDK?',
|
|
215
|
+
options: [
|
|
216
|
+
{ label: 'Yes, continue!', value: true },
|
|
217
|
+
{
|
|
218
|
+
label: "I'll do it later...",
|
|
219
|
+
value: false,
|
|
220
|
+
hint: chalk.yellow(
|
|
221
|
+
'You need to set up an SDK before you can use Sentry',
|
|
222
|
+
),
|
|
223
|
+
},
|
|
224
|
+
],
|
|
225
|
+
initialValue: true,
|
|
226
|
+
}),
|
|
227
|
+
);
|
|
228
|
+
|
|
229
|
+
Sentry.setTag(
|
|
230
|
+
'resolved-sdk-status',
|
|
231
|
+
installedSDK ? 'installed-manually' : 'install-later',
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
function getMinInstalledVersion(
|
|
236
|
+
installedSdkVersionOrRange: string,
|
|
237
|
+
installedSdkName: string,
|
|
238
|
+
): string | undefined {
|
|
239
|
+
try {
|
|
240
|
+
// If `minVersion` is unable to parse the version it will throw an error
|
|
241
|
+
// However, it will also return `null` if the parameter is undefined, which
|
|
242
|
+
// we explicitly checked before but the typing doesn't know that.
|
|
243
|
+
const minInstalledVersion = minVersion(installedSdkVersionOrRange)?.version;
|
|
244
|
+
if (minInstalledVersion) {
|
|
245
|
+
return minInstalledVersion;
|
|
246
|
+
}
|
|
247
|
+
} catch {
|
|
248
|
+
// handling this, along with the `null` case below
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
Sentry.setTag('initial-sdk-version', 'unknown');
|
|
252
|
+
clack.log.warn(
|
|
253
|
+
`${chalk.yellow(
|
|
254
|
+
`Could not parse the version of your installed SDK ("${installedSdkName}": "${installedSdkVersionOrRange}")`,
|
|
255
|
+
)}
|
|
256
|
+
|
|
257
|
+
Please make sure that your Sentry SDK is updated to version ${chalk.bold(
|
|
258
|
+
MINIMUM_DEBUG_ID_SDK_VERSION,
|
|
259
|
+
)} or newer.
|
|
260
|
+
`,
|
|
261
|
+
);
|
|
262
|
+
|
|
263
|
+
return undefined;
|
|
264
|
+
}
|
|
@@ -13,17 +13,14 @@ import {
|
|
|
13
13
|
installPackage,
|
|
14
14
|
printWelcome,
|
|
15
15
|
} from '../utils/clack-utils';
|
|
16
|
+
import { WizardOptions } from '../utils/types';
|
|
16
17
|
import { createExamplePage } from './sdk-example';
|
|
17
18
|
import { createOrMergeSvelteKitFiles, loadSvelteConfig } from './sdk-setup';
|
|
18
19
|
|
|
19
20
|
import { setupCLIConfig } from './sentry-cli-setup';
|
|
20
21
|
|
|
21
|
-
interface SvelteKitWizardOptions {
|
|
22
|
-
promoCode?: string;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
22
|
export async function runSvelteKitWizard(
|
|
26
|
-
options:
|
|
23
|
+
options: WizardOptions,
|
|
27
24
|
): Promise<void> {
|
|
28
25
|
printWelcome({
|
|
29
26
|
wizardName: 'Sentry SvelteKit Wizard',
|
|
@@ -35,7 +32,7 @@ export async function runSvelteKitWizard(
|
|
|
35
32
|
const packageJson = await getPackageDotJson();
|
|
36
33
|
await ensurePackageIsInstalled(packageJson, '@sveltejs/kit', 'Sveltekit');
|
|
37
34
|
|
|
38
|
-
const { url: sentryUrl, selfHosted } = await askForSelfHosted();
|
|
35
|
+
const { url: sentryUrl, selfHosted } = await askForSelfHosted(options.url);
|
|
39
36
|
|
|
40
37
|
const { projects, apiKeys } = await askForWizardLogin({
|
|
41
38
|
promoCode: options.promoCode,
|