@sentry/wizard 3.34.2 → 3.34.3
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 +5 -0
- package/dist/e2e-tests/jest.config.d.ts +1 -0
- package/dist/e2e-tests/jest.config.js +5 -0
- package/dist/e2e-tests/jest.config.js.map +1 -1
- package/dist/e2e-tests/tests/nextjs.test.d.ts +1 -0
- package/dist/e2e-tests/tests/nextjs.test.js +221 -0
- package/dist/e2e-tests/tests/nextjs.test.js.map +1 -0
- package/dist/e2e-tests/tests/remix.test.js +47 -43
- package/dist/e2e-tests/tests/remix.test.js.map +1 -1
- package/dist/e2e-tests/tests/sveltekit.test.d.ts +1 -0
- package/dist/e2e-tests/tests/sveltekit.test.js +186 -0
- package/dist/e2e-tests/tests/sveltekit.test.js.map +1 -0
- package/dist/e2e-tests/utils/index.d.ts +13 -2
- package/dist/e2e-tests/utils/index.js +45 -13
- package/dist/e2e-tests/utils/index.js.map +1 -1
- package/dist/package.json +3 -5
- package/dist/src/apple/templates.d.ts +1 -1
- package/dist/src/apple/templates.js +6 -2
- package/dist/src/apple/templates.js.map +1 -1
- package/dist/src/apple/xcode-manager.js +2 -1
- package/dist/src/apple/xcode-manager.js.map +1 -1
- package/dist/src/nextjs/nextjs-wizard.js +68 -47
- package/dist/src/nextjs/nextjs-wizard.js.map +1 -1
- package/dist/src/nextjs/templates.d.ts +1 -0
- package/dist/src/nextjs/templates.js +5 -1
- package/dist/src/nextjs/templates.js.map +1 -1
- package/e2e-tests/.env.example +11 -0
- package/e2e-tests/jest.config.ts +8 -1
- package/e2e-tests/package.json +14 -0
- package/e2e-tests/run.sh +15 -0
- package/e2e-tests/test-applications/nextjs-test-app/next.config.mjs +4 -0
- package/e2e-tests/test-applications/nextjs-test-app/package.json +22 -0
- package/e2e-tests/test-applications/nextjs-test-app/src/app/layout.tsx +20 -0
- package/e2e-tests/test-applications/nextjs-test-app/src/app/page.tsx +90 -0
- package/e2e-tests/test-applications/sveltekit-test-app/package.json +21 -0
- package/e2e-tests/test-applications/sveltekit-test-app/src/app.d.ts +13 -0
- package/e2e-tests/test-applications/sveltekit-test-app/src/app.html +11 -0
- package/e2e-tests/test-applications/sveltekit-test-app/src/lib/index.ts +1 -0
- package/e2e-tests/test-applications/sveltekit-test-app/src/routes/+page.svelte +2 -0
- package/e2e-tests/test-applications/sveltekit-test-app/svelte.config.js +18 -0
- package/e2e-tests/test-applications/sveltekit-test-app/vite.config.ts +6 -0
- package/e2e-tests/tests/nextjs.test.ts +161 -0
- package/e2e-tests/tests/remix.test.ts +35 -44
- package/e2e-tests/tests/sveltekit.test.ts +154 -0
- package/e2e-tests/utils/index.ts +54 -11
- package/package.json +3 -5
- package/src/apple/templates.ts +5 -1
- package/src/apple/xcode-manager.ts +2 -0
- package/src/nextjs/nextjs-wizard.ts +31 -6
- package/src/nextjs/templates.ts +15 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/* eslint-disable jest/expect-expect */
|
|
2
|
+
import { Integration } from '../../lib/Constants';
|
|
3
|
+
import {
|
|
4
|
+
checkEnvBuildPlugin,
|
|
5
|
+
checkFileContents,
|
|
6
|
+
checkFileExists,
|
|
7
|
+
checkIfBuilds,
|
|
8
|
+
checkIfRunsOnDevMode,
|
|
9
|
+
checkIfRunsOnProdMode,
|
|
10
|
+
checkPackageJson,
|
|
11
|
+
cleanupGit,
|
|
12
|
+
KEYS,
|
|
13
|
+
revertLocalChanges,
|
|
14
|
+
startWizardInstance,
|
|
15
|
+
TEST_ARGS,
|
|
16
|
+
} from '../utils';
|
|
17
|
+
import * as path from 'path';
|
|
18
|
+
|
|
19
|
+
describe('Sveltekit', () => {
|
|
20
|
+
const integration = Integration.sveltekit;
|
|
21
|
+
const projectDir = path.resolve(
|
|
22
|
+
__dirname,
|
|
23
|
+
'../test-applications/sveltekit-test-app',
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
beforeAll(async () => {
|
|
27
|
+
const wizardInstance = startWizardInstance(integration, projectDir);
|
|
28
|
+
|
|
29
|
+
const packageManagerPrompted = await wizardInstance.waitForOutput(
|
|
30
|
+
'Please select your package manager.',
|
|
31
|
+
{
|
|
32
|
+
optional: true,
|
|
33
|
+
}
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
const tracingOptionPrompted =
|
|
37
|
+
packageManagerPrompted &&
|
|
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!',
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
wizardInstance.kill();
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
afterAll(() => {
|
|
74
|
+
revertLocalChanges(projectDir);
|
|
75
|
+
cleanupGit(projectDir);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
test('should have the correct package.json', () => {
|
|
79
|
+
checkPackageJson(projectDir, integration);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test('should have the correct .env.sentry-build-plugin', () => {
|
|
83
|
+
checkEnvBuildPlugin(projectDir);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test('example page exists', () => {
|
|
87
|
+
checkFileExists(path.resolve(projectDir, 'src/routes/sentry-example/+page.svelte'));
|
|
88
|
+
checkFileExists(path.resolve(projectDir, 'src/routes/sentry-example/+server.js'));
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test('vite.config contains sentry plugin', () => {
|
|
92
|
+
checkFileContents(path.resolve(projectDir, 'vite.config.ts'), `plugins: [sentrySvelteKit({
|
|
93
|
+
sourceMapsUploadOptions: {
|
|
94
|
+
`);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
test('hook files created', () => {
|
|
98
|
+
checkFileExists(path.resolve(projectDir, 'src/hooks.server.ts'));
|
|
99
|
+
checkFileExists(path.resolve(projectDir, 'src/hooks.client.ts'));
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
test('hooks.client.ts contains sentry import', () => {
|
|
103
|
+
checkFileContents(
|
|
104
|
+
path.resolve(projectDir, 'src/hooks.client.ts'),
|
|
105
|
+
[`import * as Sentry from '@sentry/sveltekit';`,
|
|
106
|
+
`Sentry.init({
|
|
107
|
+
dsn: '${TEST_ARGS.PROJECT_DSN}',
|
|
108
|
+
|
|
109
|
+
tracesSampleRate: 1.0,
|
|
110
|
+
|
|
111
|
+
// This sets the sample rate to be 10%. You may want this to be 100% while
|
|
112
|
+
// in development and sample at a lower rate in production
|
|
113
|
+
replaysSessionSampleRate: 0.1,
|
|
114
|
+
|
|
115
|
+
// If the entire session is not sampled, use the below sample rate to sample
|
|
116
|
+
// sessions when an error occurs.
|
|
117
|
+
replaysOnErrorSampleRate: 1.0,
|
|
118
|
+
|
|
119
|
+
// If you don't want to use Session Replay, just remove the line below:
|
|
120
|
+
integrations: [replayIntegration()],
|
|
121
|
+
});`]);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
test('hooks.server.ts contains sentry import', () => {
|
|
126
|
+
checkFileContents(
|
|
127
|
+
path.resolve(projectDir, 'src/hooks.server.ts'),
|
|
128
|
+
[
|
|
129
|
+
`import * as Sentry from '@sentry/sveltekit';`,
|
|
130
|
+
`Sentry.init({
|
|
131
|
+
dsn: '${TEST_ARGS.PROJECT_DSN}',
|
|
132
|
+
|
|
133
|
+
tracesSampleRate: 1.0,
|
|
134
|
+
|
|
135
|
+
// uncomment the line below to enable Spotlight (https://spotlightjs.com)
|
|
136
|
+
// spotlight: import.meta.env.DEV,
|
|
137
|
+
});`])
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
test('runs on dev mode correctly', async () => {
|
|
142
|
+
await checkIfRunsOnDevMode(projectDir, 'ready in');
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
test('should build successfully', async () => {
|
|
146
|
+
await checkIfBuilds(projectDir, 'Successfully uploaded source maps to Sentry');
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
test('runs on prod mode correctly', async () => {
|
|
150
|
+
// We can't use the full prompt `Network: use--host to expose` as `--host` can be printed in bold.
|
|
151
|
+
await checkIfRunsOnProdMode(projectDir, 'to expose', "preview");
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
|
package/e2e-tests/utils/index.ts
CHANGED
|
@@ -16,8 +16,11 @@ export const KEYS = {
|
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
export const TEST_ARGS = {
|
|
19
|
-
AUTH_TOKEN: 'TEST_AUTH_TOKEN',
|
|
20
|
-
PROJECT_DSN:
|
|
19
|
+
AUTH_TOKEN: process.env.SENTRY_TEST_AUTH_TOKEN || 'TEST_AUTH_TOKEN',
|
|
20
|
+
PROJECT_DSN:
|
|
21
|
+
process.env.SENTRY_TEST_DSN || 'https://public@dsn.ingest.sentry.io/1337',
|
|
22
|
+
ORG_SLUG: process.env.SENTRY_TEST_ORG || 'TEST_ORG_SLUG',
|
|
23
|
+
PROJECT_SLUG: process.env.SENTRY_TEST_PROJECT || 'TEST_PROJECT_SLUG',
|
|
21
24
|
};
|
|
22
25
|
|
|
23
26
|
export const log = {
|
|
@@ -55,6 +58,28 @@ export class WizardTestEnv {
|
|
|
55
58
|
this.taskHandle.stdin.write(input);
|
|
56
59
|
}
|
|
57
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Sends the input and waits for the output.
|
|
63
|
+
* @returns a promise that resolves when the output was found
|
|
64
|
+
* @throws an error when the output was not found within the timeout
|
|
65
|
+
*/
|
|
66
|
+
sendStdinAndWaitForOutput(
|
|
67
|
+
input: string | string[],
|
|
68
|
+
output: string,
|
|
69
|
+
options?: { timeout?: number; optional?: boolean },
|
|
70
|
+
) {
|
|
71
|
+
const outputPromise = this.waitForOutput(output, options);
|
|
72
|
+
|
|
73
|
+
if (Array.isArray(input)) {
|
|
74
|
+
for (const i of input) {
|
|
75
|
+
this.sendStdin(i);
|
|
76
|
+
}
|
|
77
|
+
} else {
|
|
78
|
+
this.sendStdin(input);
|
|
79
|
+
}
|
|
80
|
+
return outputPromise;
|
|
81
|
+
}
|
|
82
|
+
|
|
58
83
|
/**
|
|
59
84
|
* Waits for the provided output with `.includes()` logic.
|
|
60
85
|
*
|
|
@@ -71,7 +96,7 @@ export class WizardTestEnv {
|
|
|
71
96
|
} = {},
|
|
72
97
|
) {
|
|
73
98
|
const { timeout, optional } = {
|
|
74
|
-
timeout:
|
|
99
|
+
timeout: 60_000,
|
|
75
100
|
optional: false,
|
|
76
101
|
...options,
|
|
77
102
|
};
|
|
@@ -122,7 +147,7 @@ export function initGit(projectDir: string): void {
|
|
|
122
147
|
execSync('git commit -m init', { cwd: projectDir });
|
|
123
148
|
} catch (e) {
|
|
124
149
|
log.error('Error initializing git');
|
|
125
|
-
|
|
150
|
+
log.error(e);
|
|
126
151
|
}
|
|
127
152
|
}
|
|
128
153
|
|
|
@@ -139,7 +164,7 @@ export function cleanupGit(projectDir: string): void {
|
|
|
139
164
|
execSync(`rm -rf ${projectDir}/.git`);
|
|
140
165
|
} catch (e) {
|
|
141
166
|
log.error('Error cleaning up git');
|
|
142
|
-
|
|
167
|
+
log.error(e);
|
|
143
168
|
}
|
|
144
169
|
}
|
|
145
170
|
|
|
@@ -159,7 +184,7 @@ export function revertLocalChanges(projectDir: string): void {
|
|
|
159
184
|
execSync('git clean -fd .', { cwd: projectDir });
|
|
160
185
|
} catch (e) {
|
|
161
186
|
log.error('Error reverting local changes');
|
|
162
|
-
|
|
187
|
+
log.error(e);
|
|
163
188
|
}
|
|
164
189
|
}
|
|
165
190
|
|
|
@@ -173,6 +198,7 @@ export function revertLocalChanges(projectDir: string): void {
|
|
|
173
198
|
export function startWizardInstance(
|
|
174
199
|
integration: Integration,
|
|
175
200
|
projectDir: string,
|
|
201
|
+
debug = false,
|
|
176
202
|
): WizardTestEnv {
|
|
177
203
|
const binPath = path.join(__dirname, '../../dist/bin.js');
|
|
178
204
|
|
|
@@ -191,8 +217,12 @@ export function startWizardInstance(
|
|
|
191
217
|
TEST_ARGS.AUTH_TOKEN,
|
|
192
218
|
'--preSelectedProject.dsn',
|
|
193
219
|
TEST_ARGS.PROJECT_DSN,
|
|
220
|
+
'--preSelectedProject.orgSlug',
|
|
221
|
+
TEST_ARGS.ORG_SLUG,
|
|
222
|
+
'--preSelectedProject.projectSlug',
|
|
223
|
+
TEST_ARGS.PROJECT_SLUG,
|
|
194
224
|
],
|
|
195
|
-
{ cwd: projectDir },
|
|
225
|
+
{ cwd: projectDir, debug },
|
|
196
226
|
);
|
|
197
227
|
}
|
|
198
228
|
|
|
@@ -266,7 +296,11 @@ export async function checkIfBuilds(
|
|
|
266
296
|
cwd: projectDir,
|
|
267
297
|
});
|
|
268
298
|
|
|
269
|
-
await expect(
|
|
299
|
+
await expect(
|
|
300
|
+
testEnv.waitForOutput(expectedOutput, {
|
|
301
|
+
timeout: 120_000,
|
|
302
|
+
}),
|
|
303
|
+
).resolves.toBe(true);
|
|
270
304
|
}
|
|
271
305
|
|
|
272
306
|
/**
|
|
@@ -280,7 +314,11 @@ export async function checkIfRunsOnDevMode(
|
|
|
280
314
|
) {
|
|
281
315
|
const testEnv = new WizardTestEnv('npm', ['run', 'dev'], { cwd: projectDir });
|
|
282
316
|
|
|
283
|
-
await expect(
|
|
317
|
+
await expect(
|
|
318
|
+
testEnv.waitForOutput(expectedOutput, {
|
|
319
|
+
timeout: 120_000,
|
|
320
|
+
}),
|
|
321
|
+
).resolves.toBe(true);
|
|
284
322
|
testEnv.kill();
|
|
285
323
|
}
|
|
286
324
|
|
|
@@ -292,11 +330,16 @@ export async function checkIfRunsOnDevMode(
|
|
|
292
330
|
export async function checkIfRunsOnProdMode(
|
|
293
331
|
projectDir: string,
|
|
294
332
|
expectedOutput: string,
|
|
333
|
+
startCommand = 'start',
|
|
295
334
|
) {
|
|
296
|
-
const testEnv = new WizardTestEnv('npm', ['run',
|
|
335
|
+
const testEnv = new WizardTestEnv('npm', ['run', startCommand], {
|
|
297
336
|
cwd: projectDir,
|
|
298
337
|
});
|
|
299
338
|
|
|
300
|
-
await expect(
|
|
339
|
+
await expect(
|
|
340
|
+
testEnv.waitForOutput(expectedOutput, {
|
|
341
|
+
timeout: 120_000,
|
|
342
|
+
}),
|
|
343
|
+
).resolves.toBe(true);
|
|
301
344
|
testEnv.kill();
|
|
302
345
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentry/wizard",
|
|
3
|
-
"version": "3.34.
|
|
3
|
+
"version": "3.34.3",
|
|
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",
|
|
@@ -55,6 +55,7 @@
|
|
|
55
55
|
"@types/yargs": "^16.0.9",
|
|
56
56
|
"@typescript-eslint/eslint-plugin": "^5.13.0",
|
|
57
57
|
"@typescript-eslint/parser": "^5.13.0",
|
|
58
|
+
"dotenv": "^16.4.5",
|
|
58
59
|
"eslint": "^8.18.0",
|
|
59
60
|
"eslint-config-prettier": "^8.3.0",
|
|
60
61
|
"eslint-plugin-jest": "^25.3.0",
|
|
@@ -66,9 +67,6 @@
|
|
|
66
67
|
"tsx": "^3.14.0",
|
|
67
68
|
"typescript": "^5.0.4"
|
|
68
69
|
},
|
|
69
|
-
"resolutions": {
|
|
70
|
-
"**/xmldom": "^0.6.0"
|
|
71
|
-
},
|
|
72
70
|
"engines": {
|
|
73
71
|
"node": ">=14.18.0",
|
|
74
72
|
"npm": ">=3.10.7",
|
|
@@ -87,7 +85,7 @@
|
|
|
87
85
|
"fix:prettier": "prettier --write \"{lib,src,test}/**/*.ts\"",
|
|
88
86
|
"fix:eslint": "eslint . --format stylish --fix",
|
|
89
87
|
"test": "yarn build && jest",
|
|
90
|
-
"test:e2e": "yarn build &&
|
|
88
|
+
"test:e2e": "yarn build && ./e2e-tests/run.sh",
|
|
91
89
|
"try": "ts-node bin.ts",
|
|
92
90
|
"try:uninstall": "ts-node bin.ts --uninstall",
|
|
93
91
|
"test:watch": "jest --watch"
|
package/src/apple/templates.ts
CHANGED
|
@@ -2,9 +2,13 @@ export function getRunScriptTemplate(
|
|
|
2
2
|
orgSlug: string,
|
|
3
3
|
projectSlug: string,
|
|
4
4
|
uploadSource = true,
|
|
5
|
+
includeHomebrewPath = false,
|
|
5
6
|
): string {
|
|
6
7
|
// eslint-disable-next-line no-useless-escape
|
|
7
|
-
|
|
8
|
+
const includeHomebrew = includeHomebrewPath
|
|
9
|
+
? '\\nif [[ "$(uname -m)" == arm64 ]]; then\\nexport PATH="/opt/homebrew/bin:$PATH"\\nfi'
|
|
10
|
+
: '';
|
|
11
|
+
return `# This script is responsable to upload debug symbols and source context for Sentry.${includeHomebrew}\\nif which sentry-cli >/dev/null; then\\nexport SENTRY_ORG=${orgSlug}\\nexport SENTRY_PROJECT=${projectSlug}\\nERROR=$(sentry-cli debug-files upload ${
|
|
8
12
|
uploadSource ? '--include-sources ' : ''
|
|
9
13
|
}"$DWARF_DSYM_FOLDER_PATH" 2>&1 >/dev/null)\\nif [ ! $? -eq 0 ]; then\\necho "warning: sentry-cli - $ERROR"\\nfi\\nelse\\necho "warning: sentry-cli not installed, download from https://github.com/getsentry/sentry-cli/releases"\\nfi\\n`;
|
|
10
14
|
}
|
|
@@ -164,6 +164,7 @@ function addUploadSymbolsScript(
|
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
+
const isHomebrewInstalled = fs.existsSync('/opt/homebrew/bin/sentry-cli');
|
|
167
168
|
xcodeProject.addBuildPhase(
|
|
168
169
|
[],
|
|
169
170
|
'PBXShellScriptBuildPhase',
|
|
@@ -178,6 +179,7 @@ function addUploadSymbolsScript(
|
|
|
178
179
|
sentryProject.organization.slug,
|
|
179
180
|
sentryProject.slug,
|
|
180
181
|
uploadSource,
|
|
182
|
+
isHomebrewInstalled,
|
|
181
183
|
),
|
|
182
184
|
},
|
|
183
185
|
);
|
|
@@ -44,6 +44,7 @@ import {
|
|
|
44
44
|
getSentryExamplePageContents,
|
|
45
45
|
getSimpleUnderscoreErrorCopyPasteSnippet,
|
|
46
46
|
getWithSentryConfigOptionsTemplate,
|
|
47
|
+
getNextjsConfigMjsTemplate,
|
|
47
48
|
} from './templates';
|
|
48
49
|
import { traceStep, withTelemetry } from '../telemetry';
|
|
49
50
|
import { getPackageVersion, hasPackageInstalled } from '../utils/package-json';
|
|
@@ -196,7 +197,7 @@ export async function runNextjsWizardWithTelemetry(
|
|
|
196
197
|
|
|
197
198
|
const shouldContinue = await abortIfCancelled(
|
|
198
199
|
clack.confirm({
|
|
199
|
-
message: `Did add the code to your ${chalk.cyan(
|
|
200
|
+
message: `Did you add the code to your ${chalk.cyan(
|
|
200
201
|
path.join(...pagesLocation, underscoreErrorPageFile),
|
|
201
202
|
)} file as described above?`,
|
|
202
203
|
active: 'Yes',
|
|
@@ -278,7 +279,7 @@ export async function runNextjsWizardWithTelemetry(
|
|
|
278
279
|
|
|
279
280
|
const shouldContinue = await abortIfCancelled(
|
|
280
281
|
clack.confirm({
|
|
281
|
-
message: `Did add the code to your ${chalk.cyan(
|
|
282
|
+
message: `Did you add the code to your ${chalk.cyan(
|
|
282
283
|
path.join(...appDirLocation, globalErrorPageFile),
|
|
283
284
|
)} file as described above?`,
|
|
284
285
|
active: 'Yes',
|
|
@@ -564,15 +565,39 @@ async function createOrMergeNextJsFiles(
|
|
|
564
565
|
if (!foundNextConfigFile) {
|
|
565
566
|
Sentry.setTag('next-config-strategy', 'create');
|
|
566
567
|
|
|
568
|
+
// Try to figure out whether the user prefers ESM
|
|
569
|
+
let isTypeModule = false;
|
|
570
|
+
try {
|
|
571
|
+
const packageJsonText = await fs.promises.readFile(
|
|
572
|
+
path.join(process.cwd(), 'package.json'),
|
|
573
|
+
'utf8',
|
|
574
|
+
);
|
|
575
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
576
|
+
const packageJson = JSON.parse(packageJsonText);
|
|
577
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
578
|
+
if (packageJson.type === 'module') {
|
|
579
|
+
isTypeModule = true;
|
|
580
|
+
}
|
|
581
|
+
} catch {
|
|
582
|
+
// noop
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
// We are creating `next.config.(m)js` files by default as they are supported by the most Next.js versions
|
|
586
|
+
const configFilename = isTypeModule
|
|
587
|
+
? nextConfigPossibleFilesMap.mjs
|
|
588
|
+
: nextConfigPossibleFilesMap.js;
|
|
589
|
+
const configContent = isTypeModule
|
|
590
|
+
? getNextjsConfigMjsTemplate(withSentryConfigOptionsTemplate)
|
|
591
|
+
: getNextjsConfigCjsTemplate(withSentryConfigOptionsTemplate);
|
|
592
|
+
|
|
567
593
|
await fs.promises.writeFile(
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
getNextjsConfigCjsTemplate(withSentryConfigOptionsTemplate),
|
|
594
|
+
path.join(process.cwd(), configFilename),
|
|
595
|
+
configContent,
|
|
571
596
|
{ encoding: 'utf8', flag: 'w' },
|
|
572
597
|
);
|
|
573
598
|
|
|
574
599
|
clack.log.success(
|
|
575
|
-
`Created ${chalk.cyan(
|
|
600
|
+
`Created ${chalk.cyan(configFilename)} with Sentry configuration.`,
|
|
576
601
|
);
|
|
577
602
|
|
|
578
603
|
return;
|
package/src/nextjs/templates.ts
CHANGED
|
@@ -81,6 +81,21 @@ module.exports = withSentryConfig(
|
|
|
81
81
|
`;
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
+
export function getNextjsConfigMjsTemplate(
|
|
85
|
+
withSentryConfigOptionsTemplate: string,
|
|
86
|
+
): string {
|
|
87
|
+
return `import { withSentryConfig } from "@sentry/nextjs";
|
|
88
|
+
|
|
89
|
+
/** @type {import('next').NextConfig} */
|
|
90
|
+
const nextConfig = {};
|
|
91
|
+
|
|
92
|
+
export default withSentryConfig(
|
|
93
|
+
nextConfig,
|
|
94
|
+
${withSentryConfigOptionsTemplate}
|
|
95
|
+
);
|
|
96
|
+
`;
|
|
97
|
+
}
|
|
98
|
+
|
|
84
99
|
export function getNextjsConfigCjsAppendix(
|
|
85
100
|
withSentryConfigOptionsTemplate: string,
|
|
86
101
|
): string {
|