@sentry/wizard 3.34.3 → 3.35.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 +17 -1
- package/dist/e2e-tests/tests/nuxt-3.test.d.ts +1 -0
- package/dist/e2e-tests/tests/nuxt-3.test.js +231 -0
- package/dist/e2e-tests/tests/nuxt-3.test.js.map +1 -0
- package/dist/e2e-tests/tests/nuxt-4.test.d.ts +1 -0
- package/dist/e2e-tests/tests/nuxt-4.test.js +232 -0
- package/dist/e2e-tests/tests/nuxt-4.test.js.map +1 -0
- package/dist/e2e-tests/tests/remix.test.js +92 -27
- package/dist/e2e-tests/tests/remix.test.js.map +1 -1
- package/dist/e2e-tests/tests/sveltekit.test.js +102 -42
- package/dist/e2e-tests/tests/sveltekit.test.js.map +1 -1
- package/dist/e2e-tests/utils/index.d.ts +18 -1
- package/dist/e2e-tests/utils/index.js +31 -2
- package/dist/e2e-tests/utils/index.js.map +1 -1
- package/dist/lib/Constants.d.ts +1 -0
- package/dist/lib/Constants.js +1 -0
- package/dist/lib/Constants.js.map +1 -1
- package/dist/package.json +3 -3
- package/dist/src/apple/templates.js +2 -2
- package/dist/src/apple/templates.js.map +1 -1
- package/dist/src/nextjs/nextjs-wizard.js +1 -0
- package/dist/src/nextjs/nextjs-wizard.js.map +1 -1
- package/dist/src/nuxt/nuxt-wizard.d.ts +3 -0
- package/dist/src/nuxt/nuxt-wizard.js +220 -0
- package/dist/src/nuxt/nuxt-wizard.js.map +1 -0
- package/dist/src/nuxt/sdk-example.d.ts +8 -0
- package/dist/src/nuxt/sdk-example.js +179 -0
- package/dist/src/nuxt/sdk-example.js.map +1 -0
- package/dist/src/nuxt/sdk-setup.d.ts +8 -0
- package/dist/src/nuxt/sdk-setup.js +275 -0
- package/dist/src/nuxt/sdk-setup.js.map +1 -0
- package/dist/src/nuxt/templates.d.ts +22 -0
- package/dist/src/nuxt/templates.js +84 -0
- package/dist/src/nuxt/templates.js.map +1 -0
- package/dist/src/nuxt/utils.d.ts +1 -0
- package/dist/src/nuxt/utils.js +71 -0
- package/dist/src/nuxt/utils.js.map +1 -0
- package/dist/src/remix/remix-wizard.js +2 -1
- package/dist/src/remix/remix-wizard.js.map +1 -1
- package/dist/src/run.d.ts +1 -1
- package/dist/src/run.js +30 -23
- package/dist/src/run.js.map +1 -1
- package/dist/src/sourcemaps/tools/rollup.js +1 -1
- package/dist/src/sourcemaps/tools/rollup.js.map +1 -1
- package/dist/src/sveltekit/sveltekit-wizard.js +2 -1
- package/dist/src/sveltekit/sveltekit-wizard.js.map +1 -1
- package/dist/src/utils/clack-utils.d.ts +6 -2
- package/dist/src/utils/clack-utils.js +30 -10
- package/dist/src/utils/clack-utils.js.map +1 -1
- package/dist/test/nuxt/templates.test.d.ts +1 -0
- package/dist/test/nuxt/templates.test.js +70 -0
- package/dist/test/nuxt/templates.test.js.map +1 -0
- package/e2e-tests/README.md +59 -0
- package/e2e-tests/test-applications/nuxt-3-test-app/README.md +75 -0
- package/e2e-tests/test-applications/nuxt-3-test-app/nuxt.config.ts +5 -0
- package/e2e-tests/test-applications/nuxt-3-test-app/package.json +18 -0
- package/e2e-tests/test-applications/nuxt-3-test-app/public/favicon.ico +0 -0
- package/e2e-tests/test-applications/nuxt-3-test-app/public/robots.txt +1 -0
- package/e2e-tests/tests/nuxt-3.test.ts +169 -0
- package/e2e-tests/tests/nuxt-4.test.ts +168 -0
- package/e2e-tests/tests/remix.test.ts +163 -50
- package/e2e-tests/tests/sveltekit.test.ts +180 -79
- package/e2e-tests/utils/index.ts +31 -1
- package/lib/Constants.ts +1 -0
- package/package.json +3 -3
- package/src/apple/templates.ts +14 -2
- package/src/nextjs/nextjs-wizard.ts +1 -0
- package/src/nuxt/nuxt-wizard.ts +166 -0
- package/src/nuxt/sdk-example.ts +135 -0
- package/src/nuxt/sdk-setup.ts +209 -0
- package/src/nuxt/templates.ts +296 -0
- package/src/nuxt/utils.ts +32 -0
- package/src/remix/remix-wizard.ts +2 -1
- package/src/run.ts +7 -0
- package/src/sourcemaps/tools/rollup.ts +1 -1
- package/src/sveltekit/sveltekit-wizard.ts +2 -1
- package/src/utils/clack-utils.ts +32 -8
- package/test/nuxt/templates.test.ts +228 -0
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
checkIfRunsOnProdMode,
|
|
10
10
|
checkPackageJson,
|
|
11
11
|
cleanupGit,
|
|
12
|
+
createFile,
|
|
12
13
|
KEYS,
|
|
13
14
|
revertLocalChanges,
|
|
14
15
|
startWizardInstance,
|
|
@@ -16,65 +17,93 @@ import {
|
|
|
16
17
|
} from '../utils';
|
|
17
18
|
import * as path from 'path';
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
20
|
+
const SERVER_HOOK_TEMPLATE = `import type { Handle } from '@sveltejs/kit';
|
|
21
|
+
|
|
22
|
+
export const handle: Handle = async ({ event, resolve }) => {
|
|
23
|
+
if (event.url.pathname.startsWith('/custom')) {
|
|
24
|
+
return new Response('custom response');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const response = await resolve(event);
|
|
28
|
+
return response;
|
|
29
|
+
};
|
|
30
|
+
`;
|
|
31
|
+
const CLIENT_HOOK_TEMPLATE = `
|
|
32
|
+
export async function handleError({ error, event }) {
|
|
33
|
+
// you can capture the \`error\` and \`event\` from the client
|
|
34
|
+
// but it only runs if the unexpected error comes from \`+ page.ts\`
|
|
35
|
+
console.log(error)
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
// don't show sensitive data to the user
|
|
39
|
+
message: 'Yikes! 💩',
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
`;
|
|
43
|
+
|
|
44
|
+
async function runWizardOnSvelteKitProject(projectDir: string, integration: Integration, fileModificationFn?: (projectDir: string, integration: Integration) => unknown) {
|
|
45
|
+
const wizardInstance = startWizardInstance(integration, projectDir);
|
|
46
|
+
let packageManagerPrompted = false;
|
|
47
|
+
|
|
48
|
+
if (fileModificationFn) {
|
|
49
|
+
fileModificationFn(projectDir, integration);
|
|
50
|
+
|
|
51
|
+
// As we modified project, we have a warning prompt before we get the package manager prompt
|
|
52
|
+
await wizardInstance.waitForOutput(
|
|
53
|
+
'Do you want to continue anyway?',
|
|
54
|
+
);
|
|
28
55
|
|
|
29
|
-
|
|
56
|
+
packageManagerPrompted = await wizardInstance.sendStdinAndWaitForOutput(
|
|
57
|
+
[KEYS.ENTER],
|
|
30
58
|
'Please select your package manager.',
|
|
31
|
-
{
|
|
32
|
-
optional: true,
|
|
33
|
-
}
|
|
34
59
|
);
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
(await wizardInstance.sendStdinAndWaitForOutput(
|
|
39
|
-
// Selecting `yarn` as the package manager
|
|
40
|
-
[KEYS.DOWN, KEYS.ENTER],
|
|
41
|
-
// "Do you want to enable Tracing", sometimes doesn't work as `Tracing` can be printed in bold.
|
|
42
|
-
'to track the performance of your application?',
|
|
43
|
-
{
|
|
44
|
-
timeout: 240_000,
|
|
45
|
-
}
|
|
46
|
-
));
|
|
47
|
-
|
|
48
|
-
const replayOptionPrompted =
|
|
49
|
-
tracingOptionPrompted &&
|
|
50
|
-
(await wizardInstance.sendStdinAndWaitForOutput(
|
|
51
|
-
[KEYS.ENTER],
|
|
52
|
-
// "Do you want to enable Sentry Session Replay", sometimes doesn't work as `Sentry Session Replay` can be printed in bold.
|
|
53
|
-
'to get a video-like reproduction of errors during a user session?',
|
|
54
|
-
));
|
|
55
|
-
|
|
56
|
-
replayOptionPrompted &&
|
|
57
|
-
(await wizardInstance.sendStdinAndWaitForOutput(
|
|
58
|
-
[KEYS.ENTER],
|
|
59
|
-
'Do you want to create an example page',
|
|
60
|
-
{
|
|
61
|
-
optional: true,
|
|
62
|
-
},
|
|
63
|
-
));
|
|
64
|
-
|
|
65
|
-
await wizardInstance.sendStdinAndWaitForOutput(
|
|
66
|
-
[KEYS.ENTER, KEYS.ENTER],
|
|
67
|
-
'Successfully installed the Sentry SvelteKit SDK!',
|
|
60
|
+
} else {
|
|
61
|
+
packageManagerPrompted = await wizardInstance.waitForOutput(
|
|
62
|
+
'Please select your package manager'
|
|
68
63
|
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const tracingOptionPrompted =
|
|
67
|
+
packageManagerPrompted &&
|
|
68
|
+
(await wizardInstance.sendStdinAndWaitForOutput(
|
|
69
|
+
// Selecting `yarn` as the package manager
|
|
70
|
+
[KEYS.DOWN, KEYS.ENTER],
|
|
71
|
+
// "Do you want to enable Tracing", sometimes doesn't work as `Tracing` can be printed in bold.
|
|
72
|
+
'to track the performance of your application?',
|
|
73
|
+
{
|
|
74
|
+
timeout: 240_000,
|
|
75
|
+
}
|
|
76
|
+
));
|
|
77
|
+
|
|
78
|
+
const replayOptionPrompted =
|
|
79
|
+
tracingOptionPrompted &&
|
|
80
|
+
(await wizardInstance.sendStdinAndWaitForOutput(
|
|
81
|
+
[KEYS.ENTER],
|
|
82
|
+
// "Do you want to enable Sentry Session Replay", sometimes doesn't work as `Sentry Session Replay` can be printed in bold.
|
|
83
|
+
'to get a video-like reproduction of errors during a user session?',
|
|
84
|
+
));
|
|
85
|
+
|
|
86
|
+
replayOptionPrompted &&
|
|
87
|
+
(await wizardInstance.sendStdinAndWaitForOutput(
|
|
88
|
+
[KEYS.ENTER],
|
|
89
|
+
'Do you want to create an example page',
|
|
90
|
+
{
|
|
91
|
+
optional: true,
|
|
92
|
+
},
|
|
93
|
+
));
|
|
69
94
|
|
|
70
|
-
|
|
71
|
-
|
|
95
|
+
await wizardInstance.sendStdinAndWaitForOutput(
|
|
96
|
+
[KEYS.ENTER, KEYS.ENTER],
|
|
97
|
+
'Successfully installed the Sentry SvelteKit SDK!',
|
|
98
|
+
);
|
|
72
99
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
cleanupGit(projectDir);
|
|
76
|
-
});
|
|
100
|
+
wizardInstance.kill();
|
|
101
|
+
}
|
|
77
102
|
|
|
103
|
+
function checkSvelteKitProject(projectDir: string, integration: Integration, options?: {
|
|
104
|
+
devModeExpectedOutput: string;
|
|
105
|
+
prodModeExpectedOutput: string;
|
|
106
|
+
}) {
|
|
78
107
|
test('should have the correct package.json', () => {
|
|
79
108
|
checkPackageJson(projectDir, integration);
|
|
80
109
|
});
|
|
@@ -99,11 +128,43 @@ describe('Sveltekit', () => {
|
|
|
99
128
|
checkFileExists(path.resolve(projectDir, 'src/hooks.client.ts'));
|
|
100
129
|
});
|
|
101
130
|
|
|
102
|
-
test('
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
131
|
+
test('builds successfully', async () => {
|
|
132
|
+
await checkIfBuilds(projectDir, 'Successfully uploaded source maps to Sentry');
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
test('runs on dev mode correctly', async () => {
|
|
136
|
+
await checkIfRunsOnDevMode(projectDir, options?.devModeExpectedOutput || 'ready in');
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
test('runs on prod mode correctly', async () => {
|
|
140
|
+
await checkIfRunsOnProdMode(projectDir, options?.prodModeExpectedOutput || 'to expose', 'preview');
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
describe('Sveltekit', () => {
|
|
145
|
+
describe('without existing hooks', () => {
|
|
146
|
+
const integration = Integration.sveltekit;
|
|
147
|
+
const projectDir = path.resolve(
|
|
148
|
+
__dirname,
|
|
149
|
+
'../test-applications/sveltekit-test-app',
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
beforeAll(async () => {
|
|
153
|
+
await runWizardOnSvelteKitProject(projectDir, integration);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
afterAll(() => {
|
|
157
|
+
revertLocalChanges(projectDir);
|
|
158
|
+
cleanupGit(projectDir);
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
checkSvelteKitProject(projectDir, integration);
|
|
162
|
+
|
|
163
|
+
test('hooks.client.ts contains sentry', () => {
|
|
164
|
+
checkFileContents(
|
|
165
|
+
path.resolve(projectDir, 'src/hooks.client.ts'),
|
|
166
|
+
[`import * as Sentry from '@sentry/sveltekit';`,
|
|
167
|
+
`Sentry.init({
|
|
107
168
|
dsn: '${TEST_ARGS.PROJECT_DSN}',
|
|
108
169
|
|
|
109
170
|
tracesSampleRate: 1.0,
|
|
@@ -118,37 +179,77 @@ describe('Sveltekit', () => {
|
|
|
118
179
|
|
|
119
180
|
// If you don't want to use Session Replay, just remove the line below:
|
|
120
181
|
integrations: [replayIntegration()],
|
|
121
|
-
})
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
`Sentry.init({
|
|
182
|
+
});`, 'export const handleError = handleErrorWithSentry(']);
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
test('hooks.server.ts contains sentry', () => {
|
|
186
|
+
checkFileContents(
|
|
187
|
+
path.resolve(projectDir, 'src/hooks.server.ts'),
|
|
188
|
+
[
|
|
189
|
+
`import * as Sentry from '@sentry/sveltekit';`,
|
|
190
|
+
`Sentry.init({
|
|
131
191
|
dsn: '${TEST_ARGS.PROJECT_DSN}',
|
|
132
192
|
|
|
133
193
|
tracesSampleRate: 1.0,
|
|
134
194
|
|
|
135
195
|
// uncomment the line below to enable Spotlight (https://spotlightjs.com)
|
|
136
196
|
// spotlight: import.meta.env.DEV,
|
|
137
|
-
})
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
test('runs on dev mode correctly', async () => {
|
|
142
|
-
await checkIfRunsOnDevMode(projectDir, 'ready in');
|
|
197
|
+
});`, 'export const handleError = handleErrorWithSentry();']);
|
|
198
|
+
});
|
|
143
199
|
});
|
|
144
200
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
201
|
+
describe('with existing hooks', () => {
|
|
202
|
+
const integration = Integration.sveltekit;
|
|
203
|
+
const projectDir = path.resolve(
|
|
204
|
+
__dirname,
|
|
205
|
+
'../test-applications/sveltekit-test-app',
|
|
206
|
+
);
|
|
148
207
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
208
|
+
beforeAll(async () => {
|
|
209
|
+
await runWizardOnSvelteKitProject(projectDir, integration, (projectDir) => {
|
|
210
|
+
createFile(
|
|
211
|
+
path.resolve(projectDir, 'src/hooks.server.ts'),
|
|
212
|
+
SERVER_HOOK_TEMPLATE,
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
createFile(
|
|
216
|
+
path.resolve(projectDir, 'src/hooks.client.ts'),
|
|
217
|
+
CLIENT_HOOK_TEMPLATE,
|
|
218
|
+
)
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
afterAll(() => {
|
|
223
|
+
revertLocalChanges(projectDir);
|
|
224
|
+
cleanupGit(projectDir);
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
checkSvelteKitProject(projectDir, integration);
|
|
228
|
+
|
|
229
|
+
// These are removed from the common tests as the content is different
|
|
230
|
+
// when the hooks are merged instead of created from the template
|
|
231
|
+
test('hooks.client.ts contains sentry instrumentation', () => {
|
|
232
|
+
checkFileContents(
|
|
233
|
+
path.resolve(projectDir, 'src/hooks.client.ts'),
|
|
234
|
+
[`import * as Sentry from '@sentry/sveltekit';`,
|
|
235
|
+
`Sentry.init({
|
|
236
|
+
dsn: "${TEST_ARGS.PROJECT_DSN}",
|
|
237
|
+
tracesSampleRate: 1,
|
|
238
|
+
replaysSessionSampleRate: 0.1,
|
|
239
|
+
replaysOnErrorSampleRate: 1,
|
|
240
|
+
integrations: [Sentry.replayIntegration()]
|
|
241
|
+
})`, 'export const handleError = Sentry.handleErrorWithSentry(']);
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
test('hooks.server.ts contains sentry init', () => {
|
|
245
|
+
checkFileContents(
|
|
246
|
+
path.resolve(projectDir, 'src/hooks.server.ts'),
|
|
247
|
+
[`import * as Sentry from '@sentry/sveltekit';`,
|
|
248
|
+
`Sentry.init({
|
|
249
|
+
dsn: "${TEST_ARGS.PROJECT_DSN}",
|
|
250
|
+
tracesSampleRate: 1
|
|
251
|
+
})`, 'export const handleError = Sentry.handleErrorWithSentry();']);
|
|
252
|
+
});
|
|
152
253
|
});
|
|
153
254
|
});
|
|
154
255
|
|
package/e2e-tests/utils/index.ts
CHANGED
|
@@ -227,11 +227,39 @@ export function startWizardInstance(
|
|
|
227
227
|
}
|
|
228
228
|
|
|
229
229
|
/**
|
|
230
|
-
*
|
|
230
|
+
* Create a file with the given content
|
|
231
231
|
*
|
|
232
232
|
* @param filePath
|
|
233
233
|
* @param content
|
|
234
234
|
*/
|
|
235
|
+
export function createFile(filePath: string, content?: string) {
|
|
236
|
+
return fs.writeFileSync(filePath, content || '');
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Modify the file with the new content
|
|
241
|
+
*
|
|
242
|
+
* @param filePath
|
|
243
|
+
* @param oldContent
|
|
244
|
+
* @param newContent
|
|
245
|
+
*/
|
|
246
|
+
export function modifyFile(filePath: string, replaceMap: Record<string, string>) {
|
|
247
|
+
const fileContent = fs.readFileSync(filePath, 'utf-8');
|
|
248
|
+
let newFileContent = fileContent;
|
|
249
|
+
|
|
250
|
+
for (const [oldContent, newContent] of Object.entries(replaceMap)) {
|
|
251
|
+
newFileContent = newFileContent.replace(oldContent, newContent);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
fs.writeFileSync(filePath, newFileContent);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Read the file contents and check if it contains the given content
|
|
259
|
+
*
|
|
260
|
+
* @param {string} filePath
|
|
261
|
+
* @param {(string | string[])} content
|
|
262
|
+
*/
|
|
235
263
|
export function checkFileContents(
|
|
236
264
|
filePath: string,
|
|
237
265
|
content: string | string[],
|
|
@@ -255,6 +283,7 @@ export function checkFileExists(filePath: string) {
|
|
|
255
283
|
|
|
256
284
|
/**
|
|
257
285
|
* Check if the package.json contains the given integration
|
|
286
|
+
*
|
|
258
287
|
* @param projectDir
|
|
259
288
|
* @param integration
|
|
260
289
|
*/
|
|
@@ -264,6 +293,7 @@ export function checkPackageJson(projectDir: string, integration: Integration) {
|
|
|
264
293
|
|
|
265
294
|
/**
|
|
266
295
|
* Check if the .sentryclirc contains the auth token
|
|
296
|
+
*
|
|
267
297
|
* @param projectDir
|
|
268
298
|
*/
|
|
269
299
|
export function checkSentryCliRc(projectDir: string) {
|
package/lib/Constants.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentry/wizard",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.35.0",
|
|
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",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@clack/core": "^0.3.4",
|
|
27
27
|
"@clack/prompts": "0.7.0",
|
|
28
|
-
"@sentry/cli": "^1.
|
|
29
|
-
"@sentry/node": "^7.
|
|
28
|
+
"@sentry/cli": "^1.77.3",
|
|
29
|
+
"@sentry/node": "^7.119.2",
|
|
30
30
|
"axios": "1.7.4",
|
|
31
31
|
"chalk": "^2.4.1",
|
|
32
32
|
"glob": "^8.1.0",
|
package/src/apple/templates.ts
CHANGED
|
@@ -20,7 +20,13 @@ export function getSwiftSnippet(dsn: string): string {
|
|
|
20
20
|
return ` SentrySDK.start { options in
|
|
21
21
|
options.dsn = "${dsn}"
|
|
22
22
|
options.debug = true // Enabled debug when first installing is always helpful
|
|
23
|
-
|
|
23
|
+
// Set tracesSampleRate to 1.0 to capture 100% of transactions for performance monitoring.
|
|
24
|
+
// We recommend adjusting this value in production.
|
|
25
|
+
options.tracesSampleRate = 1.0
|
|
26
|
+
|
|
27
|
+
// Sample rate for profiling, applied on top of TracesSampleRate.
|
|
28
|
+
// We recommend adjusting this value in production.
|
|
29
|
+
options.profilesSampleRate = 1.0
|
|
24
30
|
|
|
25
31
|
// Uncomment the following lines to add more data to your events
|
|
26
32
|
// options.attachScreenshot = true // This adds a screenshot to the error events
|
|
@@ -34,7 +40,13 @@ export function getObjcSnippet(dsn: string): string {
|
|
|
34
40
|
return ` [SentrySDK startWithConfigureOptions:^(SentryOptions * options) {
|
|
35
41
|
options.dsn = @"${dsn}";
|
|
36
42
|
options.debug = YES; // Enabled debug when first installing is always helpful
|
|
37
|
-
|
|
43
|
+
// Set tracesSampleRate to 1.0 to capture 100% of transactions for performance monitoring.
|
|
44
|
+
// We recommend adjusting this value in production.
|
|
45
|
+
options.tracesSampleRate = @1.0;
|
|
46
|
+
|
|
47
|
+
// Sample rate for profiling, applied on top of TracesSampleRate.
|
|
48
|
+
// We recommend adjusting this value in production.
|
|
49
|
+
options.profilesSampleRate = @1.0;
|
|
38
50
|
|
|
39
51
|
//Uncomment the following lines to add more data to your events
|
|
40
52
|
//options.attachScreenshot = YES; //This will add a screenshot to the error events
|
|
@@ -94,6 +94,7 @@ export async function runNextjsWizardWithTelemetry(
|
|
|
94
94
|
const { packageManager: packageManagerFromInstallStep } =
|
|
95
95
|
await installPackage({
|
|
96
96
|
packageName: '@sentry/nextjs@^8',
|
|
97
|
+
packageNameDisplayLabel: '@sentry/nextjs',
|
|
97
98
|
alreadyInstalled: !!packageJson?.dependencies?.['@sentry/nextjs'],
|
|
98
99
|
});
|
|
99
100
|
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
// @ts-ignore - clack is ESM and TS complains about that. It works though
|
|
2
|
+
import * as clack from '@clack/prompts';
|
|
3
|
+
import * as Sentry from '@sentry/node';
|
|
4
|
+
import { lt, minVersion } from 'semver';
|
|
5
|
+
import type { WizardOptions } from '../utils/types';
|
|
6
|
+
import { traceStep, withTelemetry } from '../telemetry';
|
|
7
|
+
import {
|
|
8
|
+
abort,
|
|
9
|
+
abortIfCancelled,
|
|
10
|
+
addDotEnvSentryBuildPluginFile,
|
|
11
|
+
askShouldCreateExampleComponent,
|
|
12
|
+
askShouldCreateExamplePage,
|
|
13
|
+
confirmContinueIfNoOrDirtyGitRepo,
|
|
14
|
+
ensurePackageIsInstalled,
|
|
15
|
+
getOrAskForProjectData,
|
|
16
|
+
getPackageDotJson,
|
|
17
|
+
installPackage,
|
|
18
|
+
printWelcome,
|
|
19
|
+
runPrettierIfInstalled,
|
|
20
|
+
} from '../utils/clack-utils';
|
|
21
|
+
import { getPackageVersion, hasPackageInstalled } from '../utils/package-json';
|
|
22
|
+
import { addSDKModule, getNuxtConfig, createConfigFiles } from './sdk-setup';
|
|
23
|
+
import {
|
|
24
|
+
createExampleComponent,
|
|
25
|
+
createExamplePage,
|
|
26
|
+
supportsExamplePage,
|
|
27
|
+
} from './sdk-example';
|
|
28
|
+
import { isNuxtV4 } from './utils';
|
|
29
|
+
import chalk from 'chalk';
|
|
30
|
+
|
|
31
|
+
export function runNuxtWizard(options: WizardOptions) {
|
|
32
|
+
return withTelemetry(
|
|
33
|
+
{
|
|
34
|
+
enabled: options.telemetryEnabled,
|
|
35
|
+
integration: 'nuxt',
|
|
36
|
+
wizardOptions: options,
|
|
37
|
+
},
|
|
38
|
+
() => runNuxtWizardWithTelemetry(options),
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export async function runNuxtWizardWithTelemetry(
|
|
43
|
+
options: WizardOptions,
|
|
44
|
+
): Promise<void> {
|
|
45
|
+
printWelcome({
|
|
46
|
+
wizardName: 'Sentry Nuxt Wizard',
|
|
47
|
+
promoCode: options.promoCode,
|
|
48
|
+
telemetryEnabled: options.telemetryEnabled,
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
await confirmContinueIfNoOrDirtyGitRepo();
|
|
52
|
+
|
|
53
|
+
const packageJson = await getPackageDotJson();
|
|
54
|
+
|
|
55
|
+
await ensurePackageIsInstalled(packageJson, 'nuxt', 'Nuxt');
|
|
56
|
+
|
|
57
|
+
const nuxtVersion = getPackageVersion('nuxt', packageJson);
|
|
58
|
+
Sentry.setTag('nuxt-version', nuxtVersion);
|
|
59
|
+
|
|
60
|
+
const minVer = minVersion(nuxtVersion || '0.0.0');
|
|
61
|
+
|
|
62
|
+
if (!nuxtVersion || !minVer || lt(minVer, '3.7.0')) {
|
|
63
|
+
clack.log.warn(
|
|
64
|
+
"It seems you're using a Nuxt version <3.7.0 which is not supported by Sentry.\nWe recommend upgrading to the latest version before you continue.",
|
|
65
|
+
);
|
|
66
|
+
const shouldContinue = await abortIfCancelled(
|
|
67
|
+
clack.select({
|
|
68
|
+
message: 'Do you want to continue anyway?',
|
|
69
|
+
options: [
|
|
70
|
+
{
|
|
71
|
+
label: 'Yes, continue',
|
|
72
|
+
hint: 'The SDK might not work correctly',
|
|
73
|
+
value: true,
|
|
74
|
+
},
|
|
75
|
+
{ label: "No, I'll upgrade first", value: false },
|
|
76
|
+
],
|
|
77
|
+
}),
|
|
78
|
+
);
|
|
79
|
+
if (!shouldContinue) {
|
|
80
|
+
await abort('Exiting Wizard', 0);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const { authToken, selectedProject, selfHosted, sentryUrl } =
|
|
86
|
+
await getOrAskForProjectData(options, 'javascript-nuxt');
|
|
87
|
+
|
|
88
|
+
const sdkAlreadyInstalled = hasPackageInstalled('@sentry/nuxt', packageJson);
|
|
89
|
+
Sentry.setTag('sdk-already-installed', sdkAlreadyInstalled);
|
|
90
|
+
|
|
91
|
+
await installPackage({
|
|
92
|
+
packageName: '@sentry/nuxt',
|
|
93
|
+
alreadyInstalled: sdkAlreadyInstalled,
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
await addDotEnvSentryBuildPluginFile(authToken);
|
|
97
|
+
|
|
98
|
+
const nuxtConfig = await traceStep('load-nuxt-config', getNuxtConfig);
|
|
99
|
+
|
|
100
|
+
const projectData = {
|
|
101
|
+
org: selectedProject.organization.slug,
|
|
102
|
+
project: selectedProject.slug,
|
|
103
|
+
projectId: selectedProject.id,
|
|
104
|
+
url: sentryUrl,
|
|
105
|
+
selfHosted,
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
await traceStep('configure-sdk', async () => {
|
|
109
|
+
await addSDKModule(nuxtConfig, projectData);
|
|
110
|
+
await createConfigFiles(selectedProject.keys[0].dsn.public);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
let shouldCreateExamplePage = false;
|
|
114
|
+
let shouldCreateExampleButton = false;
|
|
115
|
+
|
|
116
|
+
const isV4 = await isNuxtV4(nuxtConfig, nuxtVersion);
|
|
117
|
+
const canCreateExamplePage = await supportsExamplePage(isV4);
|
|
118
|
+
Sentry.setTag('supports-example-page-creation', canCreateExamplePage);
|
|
119
|
+
|
|
120
|
+
if (canCreateExamplePage) {
|
|
121
|
+
shouldCreateExamplePage = await askShouldCreateExamplePage();
|
|
122
|
+
|
|
123
|
+
if (shouldCreateExamplePage) {
|
|
124
|
+
await traceStep('create-example-page', async () =>
|
|
125
|
+
createExamplePage(isV4, projectData),
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
} else {
|
|
129
|
+
shouldCreateExampleButton = await askShouldCreateExampleComponent();
|
|
130
|
+
|
|
131
|
+
if (shouldCreateExampleButton) {
|
|
132
|
+
await traceStep('create-example-component', async () =>
|
|
133
|
+
createExampleComponent(isV4),
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
await runPrettierIfInstalled();
|
|
139
|
+
|
|
140
|
+
clack.outro(
|
|
141
|
+
buildOutroMessage(shouldCreateExamplePage, shouldCreateExampleButton),
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function buildOutroMessage(
|
|
146
|
+
shouldCreateExamplePage: boolean,
|
|
147
|
+
shouldCreateExampleButton: boolean,
|
|
148
|
+
): string {
|
|
149
|
+
let msg = chalk.green('\nSuccessfully installed the Sentry Nuxt SDK!');
|
|
150
|
+
|
|
151
|
+
if (shouldCreateExamplePage) {
|
|
152
|
+
msg += `\n\nYou can validate your setup by visiting ${chalk.cyan(
|
|
153
|
+
'"/sentry-example-page"',
|
|
154
|
+
)}.`;
|
|
155
|
+
}
|
|
156
|
+
if (shouldCreateExampleButton) {
|
|
157
|
+
msg += `\n\nYou can validate your setup by adding the ${chalk.cyan(
|
|
158
|
+
'`SentryExampleButton`',
|
|
159
|
+
)} component to a page and triggering it.`;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
msg += `\n\nCheck out the SDK documentation for further configuration:
|
|
163
|
+
https://docs.sentry.io/platforms/javascript/guides/nuxt/`;
|
|
164
|
+
|
|
165
|
+
return msg;
|
|
166
|
+
}
|