@sentry/wizard 3.28.0 → 3.29.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 +8 -0
- package/dist/package.json +1 -1
- package/dist/src/nextjs/nextjs-wizard.js +9 -4
- package/dist/src/nextjs/nextjs-wizard.js.map +1 -1
- package/dist/src/nextjs/templates.js +2 -2
- package/dist/src/nextjs/templates.js.map +1 -1
- package/dist/src/react-native/react-native-wizard.js +4 -1
- package/dist/src/react-native/react-native-wizard.js.map +1 -1
- package/dist/src/remix/remix-wizard.d.ts +1 -1
- package/dist/src/remix/remix-wizard.js +27 -11
- package/dist/src/remix/remix-wizard.js.map +1 -1
- package/dist/src/remix/sdk-setup.d.ts +24 -3
- package/dist/src/remix/sdk-setup.js +95 -61
- package/dist/src/remix/sdk-setup.js.map +1 -1
- package/dist/src/sveltekit/sveltekit-wizard.js +3 -1
- package/dist/src/sveltekit/sveltekit-wizard.js.map +1 -1
- package/dist/src/utils/clack-utils.d.ts +3 -0
- package/dist/src/utils/clack-utils.js +59 -1
- package/dist/src/utils/clack-utils.js.map +1 -1
- package/dist/test/remix/client-entry.test.d.ts +1 -0
- package/dist/test/remix/client-entry.test.js +41 -0
- package/dist/test/remix/client-entry.test.js.map +1 -0
- package/dist/test/remix/server-instrumentation.test.d.ts +1 -0
- package/dist/test/remix/server-instrumentation.test.js +22 -0
- package/dist/test/remix/server-instrumentation.test.js.map +1 -0
- package/package.json +1 -1
- package/src/nextjs/nextjs-wizard.ts +9 -5
- package/src/nextjs/templates.ts +12 -3
- package/src/react-native/react-native-wizard.ts +4 -0
- package/src/remix/remix-wizard.ts +32 -6
- package/src/remix/sdk-setup.ts +145 -48
- package/src/sveltekit/sveltekit-wizard.ts +3 -0
- package/src/utils/clack-utils.ts +47 -1
- package/test/remix/client-entry.test.ts +122 -0
- package/test/remix/server-instrumentation.test.ts +38 -0
|
@@ -7,15 +7,17 @@ import {
|
|
|
7
7
|
askShouldCreateExamplePage,
|
|
8
8
|
confirmContinueIfNoOrDirtyGitRepo,
|
|
9
9
|
ensurePackageIsInstalled,
|
|
10
|
+
featureSelectionPrompt,
|
|
10
11
|
getOrAskForProjectData,
|
|
11
12
|
getPackageDotJson,
|
|
12
13
|
installPackage,
|
|
13
14
|
isUsingTypeScript,
|
|
14
15
|
printWelcome,
|
|
15
16
|
rcCliSetupConfig,
|
|
17
|
+
runPrettierIfInstalled,
|
|
16
18
|
} from '../utils/clack-utils';
|
|
17
19
|
import { hasPackageInstalled } from '../utils/package-json';
|
|
18
|
-
import { WizardOptions } from '../utils/types';
|
|
20
|
+
import type { WizardOptions } from '../utils/types';
|
|
19
21
|
import {
|
|
20
22
|
initializeSentryOnEntryClient,
|
|
21
23
|
instrumentSentryOnEntryServer,
|
|
@@ -76,8 +78,22 @@ async function runRemixWizardWithTelemetry(
|
|
|
76
78
|
const isTS = isUsingTypeScript();
|
|
77
79
|
const isV2 = isRemixV2(remixConfig, packageJson);
|
|
78
80
|
const viteConfig = findFile('vite.config');
|
|
79
|
-
|
|
80
|
-
|
|
81
|
+
const selectedFeatures = await featureSelectionPrompt([
|
|
82
|
+
{
|
|
83
|
+
id: 'performance',
|
|
84
|
+
prompt: `Do you want to enable ${chalk.bold(
|
|
85
|
+
'Tracing',
|
|
86
|
+
)} to track the performance of your application?`,
|
|
87
|
+
enabledHint: 'recommended',
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
id: 'replay',
|
|
91
|
+
prompt: `Do you want to enable ${chalk.bold(
|
|
92
|
+
'Sentry Session Replay',
|
|
93
|
+
)} to get a video-like reproduction of errors during a user session?`,
|
|
94
|
+
enabledHint: 'recommended, but increases bundle size',
|
|
95
|
+
},
|
|
96
|
+
] as const);
|
|
81
97
|
|
|
82
98
|
if (viteConfig) {
|
|
83
99
|
await traceStep(
|
|
@@ -108,6 +124,8 @@ async function runRemixWizardWithTelemetry(
|
|
|
108
124
|
url: sentryUrl === DEFAULT_URL ? undefined : sentryUrl,
|
|
109
125
|
isHydrogen: isHydrogenApp(packageJson),
|
|
110
126
|
});
|
|
127
|
+
|
|
128
|
+
await addSentryCliConfig({ authToken }, rcCliSetupConfig);
|
|
111
129
|
} catch (e) {
|
|
112
130
|
clack.log
|
|
113
131
|
.warn(`Could not update build script to generate and upload sourcemaps.
|
|
@@ -139,7 +157,7 @@ async function runRemixWizardWithTelemetry(
|
|
|
139
157
|
|
|
140
158
|
await traceStep('Initialize Sentry on client entry', async () => {
|
|
141
159
|
try {
|
|
142
|
-
await initializeSentryOnEntryClient(dsn, isTS);
|
|
160
|
+
await initializeSentryOnEntryClient(dsn, isTS, selectedFeatures);
|
|
143
161
|
} catch (e) {
|
|
144
162
|
clack.log.warn(`Could not initialize Sentry on client entry.
|
|
145
163
|
Please do it manually using instructions from https://docs.sentry.io/platforms/javascript/guides/remix/manual-setup/`);
|
|
@@ -151,7 +169,10 @@ async function runRemixWizardWithTelemetry(
|
|
|
151
169
|
|
|
152
170
|
await traceStep('Create server instrumentation file', async () => {
|
|
153
171
|
try {
|
|
154
|
-
instrumentationFile = await createServerInstrumentationFile(
|
|
172
|
+
instrumentationFile = await createServerInstrumentationFile(
|
|
173
|
+
dsn,
|
|
174
|
+
selectedFeatures,
|
|
175
|
+
);
|
|
155
176
|
} catch (e) {
|
|
156
177
|
clack.log.warn(
|
|
157
178
|
'Could not create a server instrumentation file. Please do it manually using instructions from https://docs.sentry.io/platforms/javascript/guides/remix/manual-setup/',
|
|
@@ -166,7 +187,10 @@ async function runRemixWizardWithTelemetry(
|
|
|
166
187
|
'Create server instrumentation file and import it',
|
|
167
188
|
async () => {
|
|
168
189
|
try {
|
|
169
|
-
serverFileInstrumented = await insertServerInstrumentationFile(
|
|
190
|
+
serverFileInstrumented = await insertServerInstrumentationFile(
|
|
191
|
+
dsn,
|
|
192
|
+
selectedFeatures,
|
|
193
|
+
);
|
|
170
194
|
} catch (e) {
|
|
171
195
|
clack.log.warn(
|
|
172
196
|
'Could not create a server instrumentation file. Please do it manually using instructions from https://docs.sentry.io/platforms/javascript/guides/remix/manual-setup/',
|
|
@@ -216,6 +240,8 @@ async function runRemixWizardWithTelemetry(
|
|
|
216
240
|
});
|
|
217
241
|
}
|
|
218
242
|
|
|
243
|
+
await runPrettierIfInstalled();
|
|
244
|
+
|
|
219
245
|
clack.outro(`
|
|
220
246
|
${chalk.green(
|
|
221
247
|
'Sentry has been successfully configured for your Remix project.',
|
package/src/remix/sdk-setup.ts
CHANGED
|
@@ -76,23 +76,72 @@ export function runRemixReveal(isTS: boolean): void {
|
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
+
function getInitCallArgs(
|
|
80
|
+
dsn: string,
|
|
81
|
+
type: 'client' | 'server',
|
|
82
|
+
selectedFeatures: {
|
|
83
|
+
performance: boolean;
|
|
84
|
+
replay: boolean;
|
|
85
|
+
},
|
|
86
|
+
) {
|
|
87
|
+
const initCallArgs = {
|
|
88
|
+
dsn,
|
|
89
|
+
} as Record<string, unknown>;
|
|
90
|
+
|
|
91
|
+
// Adding tracing sample rate for both client and server
|
|
92
|
+
if (selectedFeatures.performance) {
|
|
93
|
+
initCallArgs.tracesSampleRate = 1.0;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Adding integrations and replay options only for client
|
|
97
|
+
if (
|
|
98
|
+
type === 'client' &&
|
|
99
|
+
(selectedFeatures.performance || selectedFeatures.replay)
|
|
100
|
+
) {
|
|
101
|
+
initCallArgs.integrations = [];
|
|
102
|
+
|
|
103
|
+
if (selectedFeatures.performance) {
|
|
104
|
+
// @ts-expect-error - Adding Proxified AST node to the array
|
|
105
|
+
initCallArgs.integrations.push(
|
|
106
|
+
builders.functionCall(
|
|
107
|
+
'Sentry.browserTracingIntegration',
|
|
108
|
+
builders.raw('{ useEffect, useLocation, useMatches }'),
|
|
109
|
+
),
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (selectedFeatures.replay) {
|
|
114
|
+
// @ts-expect-error - Adding Proxified AST node to the array
|
|
115
|
+
initCallArgs.integrations.push(
|
|
116
|
+
builders.functionCall('Sentry.replayIntegration', {
|
|
117
|
+
maskAllText: true,
|
|
118
|
+
blockAllMedia: true,
|
|
119
|
+
}),
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
initCallArgs.replaysSessionSampleRate = 0.1;
|
|
123
|
+
initCallArgs.replaysOnErrorSampleRate = 1.0;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Adding autoInstrumentRemix option only for server
|
|
128
|
+
if (type === 'server') {
|
|
129
|
+
initCallArgs.autoInstrumentRemix = true;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return initCallArgs;
|
|
133
|
+
}
|
|
134
|
+
|
|
79
135
|
function insertClientInitCall(
|
|
80
136
|
dsn: string,
|
|
81
137
|
originalHooksMod: ProxifiedModule<any>,
|
|
138
|
+
selectedFeatures: {
|
|
139
|
+
performance: boolean;
|
|
140
|
+
replay: boolean;
|
|
141
|
+
},
|
|
82
142
|
): void {
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
tracesSampleRate: 1.0,
|
|
86
|
-
replaysSessionSampleRate: 0.1,
|
|
87
|
-
replaysOnErrorSampleRate: 1.0,
|
|
88
|
-
integrations: [
|
|
89
|
-
builders.functionCall(
|
|
90
|
-
'Sentry.browserTracingIntegration',
|
|
91
|
-
builders.raw('{ useEffect, useLocation, useMatches }'),
|
|
92
|
-
),
|
|
93
|
-
builders.functionCall('Sentry.replayIntegration'),
|
|
94
|
-
],
|
|
95
|
-
});
|
|
143
|
+
const initCallArgs = getInitCallArgs(dsn, 'client', selectedFeatures);
|
|
144
|
+
const initCall = builders.functionCall('Sentry.init', initCallArgs);
|
|
96
145
|
|
|
97
146
|
const originalHooksModAST = originalHooksMod.$ast as Program;
|
|
98
147
|
const initCallInsertionIndex =
|
|
@@ -107,7 +156,13 @@ function insertClientInitCall(
|
|
|
107
156
|
);
|
|
108
157
|
}
|
|
109
158
|
|
|
110
|
-
export
|
|
159
|
+
export function generateServerInstrumentationFile(
|
|
160
|
+
dsn: string,
|
|
161
|
+
selectedFeatures: {
|
|
162
|
+
performance: boolean;
|
|
163
|
+
replay: boolean;
|
|
164
|
+
},
|
|
165
|
+
) {
|
|
111
166
|
// create an empty file named `instrument.server.mjs`
|
|
112
167
|
const instrumentationFile = 'instrumentation.server.mjs';
|
|
113
168
|
const instrumentationFileMod = parseModule('');
|
|
@@ -118,11 +173,8 @@ export async function createServerInstrumentationFile(dsn: string) {
|
|
|
118
173
|
local: 'Sentry',
|
|
119
174
|
});
|
|
120
175
|
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
tracesSampleRate: 1.0,
|
|
124
|
-
autoInstrumentRemix: true,
|
|
125
|
-
});
|
|
176
|
+
const initCallArgs = getInitCallArgs(dsn, 'server', selectedFeatures);
|
|
177
|
+
const initCall = builders.functionCall('Sentry.init', initCallArgs);
|
|
126
178
|
|
|
127
179
|
const instrumentationFileModAST = instrumentationFileMod.$ast as Program;
|
|
128
180
|
|
|
@@ -138,13 +190,35 @@ export async function createServerInstrumentationFile(dsn: string) {
|
|
|
138
190
|
generateCode(initCall).code,
|
|
139
191
|
);
|
|
140
192
|
|
|
141
|
-
|
|
193
|
+
return { instrumentationFile, instrumentationFileMod };
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export async function createServerInstrumentationFile(
|
|
197
|
+
dsn: string,
|
|
198
|
+
selectedFeatures: {
|
|
199
|
+
performance: boolean;
|
|
200
|
+
replay: boolean;
|
|
201
|
+
},
|
|
202
|
+
) {
|
|
203
|
+
const { instrumentationFile, instrumentationFileMod } =
|
|
204
|
+
generateServerInstrumentationFile(dsn, selectedFeatures);
|
|
205
|
+
|
|
206
|
+
await writeFile(instrumentationFileMod.$ast, instrumentationFile);
|
|
142
207
|
|
|
143
208
|
return instrumentationFile;
|
|
144
209
|
}
|
|
145
210
|
|
|
146
|
-
export async function insertServerInstrumentationFile(
|
|
147
|
-
|
|
211
|
+
export async function insertServerInstrumentationFile(
|
|
212
|
+
dsn: string,
|
|
213
|
+
selectedFeatures: {
|
|
214
|
+
performance: boolean;
|
|
215
|
+
replay: boolean;
|
|
216
|
+
},
|
|
217
|
+
) {
|
|
218
|
+
const instrumentationFile = await createServerInstrumentationFile(
|
|
219
|
+
dsn,
|
|
220
|
+
selectedFeatures,
|
|
221
|
+
);
|
|
148
222
|
|
|
149
223
|
const expressServerPath = await findCustomExpressServerImplementation();
|
|
150
224
|
|
|
@@ -297,9 +371,52 @@ export async function updateBuildScript(args: {
|
|
|
297
371
|
/* eslint-enable @typescript-eslint/no-unsafe-member-access */
|
|
298
372
|
}
|
|
299
373
|
|
|
374
|
+
export function updateEntryClientMod(
|
|
375
|
+
originalEntryClientMod: ProxifiedModule<any>,
|
|
376
|
+
dsn: string,
|
|
377
|
+
selectedFeatures: {
|
|
378
|
+
performance: boolean;
|
|
379
|
+
replay: boolean;
|
|
380
|
+
},
|
|
381
|
+
): ProxifiedModule<any> {
|
|
382
|
+
originalEntryClientMod.imports.$add({
|
|
383
|
+
from: '@sentry/remix',
|
|
384
|
+
imported: '*',
|
|
385
|
+
local: 'Sentry',
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
if (selectedFeatures.performance) {
|
|
389
|
+
originalEntryClientMod.imports.$add({
|
|
390
|
+
from: '@remix-run/react',
|
|
391
|
+
imported: 'useLocation',
|
|
392
|
+
local: 'useLocation',
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
originalEntryClientMod.imports.$add({
|
|
396
|
+
from: '@remix-run/react',
|
|
397
|
+
imported: 'useMatches',
|
|
398
|
+
local: 'useMatches',
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
originalEntryClientMod.imports.$add({
|
|
402
|
+
from: 'react',
|
|
403
|
+
imported: 'useEffect',
|
|
404
|
+
local: 'useEffect',
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
insertClientInitCall(dsn, originalEntryClientMod, selectedFeatures);
|
|
409
|
+
|
|
410
|
+
return originalEntryClientMod;
|
|
411
|
+
}
|
|
412
|
+
|
|
300
413
|
export async function initializeSentryOnEntryClient(
|
|
301
414
|
dsn: string,
|
|
302
415
|
isTS: boolean,
|
|
416
|
+
selectedFeatures: {
|
|
417
|
+
performance: boolean;
|
|
418
|
+
replay: boolean;
|
|
419
|
+
},
|
|
303
420
|
): Promise<void> {
|
|
304
421
|
const clientEntryFilename = `entry.client.${isTS ? 'tsx' : 'jsx'}`;
|
|
305
422
|
|
|
@@ -315,34 +432,14 @@ export async function initializeSentryOnEntryClient(
|
|
|
315
432
|
return;
|
|
316
433
|
}
|
|
317
434
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
originalEntryClientMod.imports.$add({
|
|
325
|
-
from: 'react',
|
|
326
|
-
imported: 'useEffect',
|
|
327
|
-
local: 'useEffect',
|
|
328
|
-
});
|
|
329
|
-
|
|
330
|
-
originalEntryClientMod.imports.$add({
|
|
331
|
-
from: '@remix-run/react',
|
|
332
|
-
imported: 'useLocation',
|
|
333
|
-
local: 'useLocation',
|
|
334
|
-
});
|
|
335
|
-
|
|
336
|
-
originalEntryClientMod.imports.$add({
|
|
337
|
-
from: '@remix-run/react',
|
|
338
|
-
imported: 'useMatches',
|
|
339
|
-
local: 'useMatches',
|
|
340
|
-
});
|
|
341
|
-
|
|
342
|
-
insertClientInitCall(dsn, originalEntryClientMod);
|
|
435
|
+
const updatedEntryClientMod = updateEntryClientMod(
|
|
436
|
+
originalEntryClientMod,
|
|
437
|
+
dsn,
|
|
438
|
+
selectedFeatures,
|
|
439
|
+
);
|
|
343
440
|
|
|
344
441
|
await writeFile(
|
|
345
|
-
|
|
442
|
+
updatedEntryClientMod.$ast,
|
|
346
443
|
path.join(process.cwd(), 'app', clientEntryFilename),
|
|
347
444
|
);
|
|
348
445
|
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
getPackageDotJson,
|
|
16
16
|
installPackage,
|
|
17
17
|
printWelcome,
|
|
18
|
+
runPrettierIfInstalled,
|
|
18
19
|
} from '../utils/clack-utils';
|
|
19
20
|
import { getPackageVersion, hasPackageInstalled } from '../utils/package-json';
|
|
20
21
|
import type { WizardOptions } from '../utils/types';
|
|
@@ -163,6 +164,8 @@ export async function runSvelteKitWizardWithTelemetry(
|
|
|
163
164
|
}
|
|
164
165
|
}
|
|
165
166
|
|
|
167
|
+
await runPrettierIfInstalled();
|
|
168
|
+
|
|
166
169
|
clack.outro(buildOutroMessage(shouldCreateExamplePage));
|
|
167
170
|
}
|
|
168
171
|
|
package/src/utils/clack-utils.ts
CHANGED
|
@@ -670,6 +670,52 @@ async function addCliConfigFileToGitIgnore(filename: string): Promise<void> {
|
|
|
670
670
|
}
|
|
671
671
|
}
|
|
672
672
|
|
|
673
|
+
export async function runPrettierIfInstalled(): Promise<void> {
|
|
674
|
+
return traceStep('run-prettier', async () => {
|
|
675
|
+
const packageJson = await getPackageDotJson();
|
|
676
|
+
const prettierInstalled = hasPackageInstalled('prettier', packageJson);
|
|
677
|
+
|
|
678
|
+
if (prettierInstalled) {
|
|
679
|
+
// prompt the user if they want to run prettier
|
|
680
|
+
const shouldRunPrettier = await abortIfCancelled(
|
|
681
|
+
clack.confirm({
|
|
682
|
+
message:
|
|
683
|
+
'Looks like you have Prettier in your project. Do you want to run it on your files?',
|
|
684
|
+
}),
|
|
685
|
+
);
|
|
686
|
+
|
|
687
|
+
if (!shouldRunPrettier) {
|
|
688
|
+
return;
|
|
689
|
+
}
|
|
690
|
+
} else {
|
|
691
|
+
return;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
const prettierSpinner = clack.spinner();
|
|
695
|
+
prettierSpinner.start('Running Prettier on your files.');
|
|
696
|
+
|
|
697
|
+
try {
|
|
698
|
+
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
|
+
});
|
|
706
|
+
});
|
|
707
|
+
} catch {
|
|
708
|
+
prettierSpinner.stop('Prettier failed to run.');
|
|
709
|
+
clack.log.error(
|
|
710
|
+
'Prettier failed to run. There may be formatting issues in your updated files.',
|
|
711
|
+
);
|
|
712
|
+
return;
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
prettierSpinner.stop('Prettier has formatted your files.');
|
|
716
|
+
});
|
|
717
|
+
}
|
|
718
|
+
|
|
673
719
|
/**
|
|
674
720
|
* Checks if @param packageId is listed as a dependency in @param packageJson.
|
|
675
721
|
* If not, it will ask users if they want to continue without the package.
|
|
@@ -734,7 +780,7 @@ export async function getPackageDotJson(): Promise<PackageDotJson> {
|
|
|
734
780
|
return packageJson || {};
|
|
735
781
|
}
|
|
736
782
|
|
|
737
|
-
async function getPackageManager(): Promise<PackageManager> {
|
|
783
|
+
export async function getPackageManager(): Promise<PackageManager> {
|
|
738
784
|
const detectedPackageManager = detectPackageManger();
|
|
739
785
|
|
|
740
786
|
if (detectedPackageManager) {
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
// @ts-expect-error - magicast is ESM and TS complains about that. It works though
|
|
2
|
+
import { parseModule } from 'magicast';
|
|
3
|
+
import { updateEntryClientMod } from '../../src/remix/sdk-setup';
|
|
4
|
+
|
|
5
|
+
describe('initializeSentryOnEntryClient', () => {
|
|
6
|
+
it('should initialize Sentry on client entry with all features enabled', () => {
|
|
7
|
+
// Empty entry.client.tsx file for testing
|
|
8
|
+
const originalEntryClientMod = parseModule('');
|
|
9
|
+
|
|
10
|
+
const dsn = 'https://sentry.io/123';
|
|
11
|
+
const selectedFeatures = {
|
|
12
|
+
performance: true,
|
|
13
|
+
replay: true,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const result = updateEntryClientMod(
|
|
17
|
+
originalEntryClientMod,
|
|
18
|
+
dsn,
|
|
19
|
+
selectedFeatures,
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
expect(result.generate().code).toMatchInlineSnapshot(`
|
|
23
|
+
"import { useEffect,} from "react";
|
|
24
|
+
|
|
25
|
+
import {
|
|
26
|
+
useLocation,
|
|
27
|
+
useMatches,
|
|
28
|
+
} from "@remix-run/react";
|
|
29
|
+
|
|
30
|
+
import * as Sentry from "@sentry/remix";
|
|
31
|
+
|
|
32
|
+
Sentry.init({
|
|
33
|
+
dsn: "https://sentry.io/123",
|
|
34
|
+
tracesSampleRate: 1,
|
|
35
|
+
|
|
36
|
+
integrations: [Sentry.browserTracingIntegration({
|
|
37
|
+
useEffect,
|
|
38
|
+
useLocation,
|
|
39
|
+
useMatches
|
|
40
|
+
}), Sentry.replayIntegration({
|
|
41
|
+
maskAllText: true,
|
|
42
|
+
blockAllMedia: true
|
|
43
|
+
})],
|
|
44
|
+
|
|
45
|
+
replaysSessionSampleRate: 0.1,
|
|
46
|
+
replaysOnErrorSampleRate: 1
|
|
47
|
+
})"
|
|
48
|
+
`);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('should initialize Sentry on client entry when performance disabled', () => {
|
|
52
|
+
// Empty entry.client.tsx file for testing
|
|
53
|
+
const originalEntryClientMod = parseModule('');
|
|
54
|
+
|
|
55
|
+
const dsn = 'https://sentry.io/123';
|
|
56
|
+
const selectedFeatures = {
|
|
57
|
+
performance: false,
|
|
58
|
+
replay: true,
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const result = updateEntryClientMod(
|
|
62
|
+
originalEntryClientMod,
|
|
63
|
+
dsn,
|
|
64
|
+
selectedFeatures,
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
expect(result.generate().code).toMatchInlineSnapshot(`
|
|
68
|
+
"import * as Sentry from "@sentry/remix";
|
|
69
|
+
|
|
70
|
+
Sentry.init({
|
|
71
|
+
dsn: "https://sentry.io/123",
|
|
72
|
+
|
|
73
|
+
integrations: [Sentry.replayIntegration({
|
|
74
|
+
maskAllText: true,
|
|
75
|
+
blockAllMedia: true
|
|
76
|
+
})],
|
|
77
|
+
|
|
78
|
+
replaysSessionSampleRate: 0.1,
|
|
79
|
+
replaysOnErrorSampleRate: 1
|
|
80
|
+
})"
|
|
81
|
+
`);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('should initialize Sentry on client entry when replay disabled', () => {
|
|
85
|
+
// Empty entry.client.tsx file for testing
|
|
86
|
+
const originalEntryClientMod = parseModule('');
|
|
87
|
+
|
|
88
|
+
const dsn = 'https://sentry.io/123';
|
|
89
|
+
const selectedFeatures = {
|
|
90
|
+
performance: true,
|
|
91
|
+
replay: false,
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const result = updateEntryClientMod(
|
|
95
|
+
originalEntryClientMod,
|
|
96
|
+
dsn,
|
|
97
|
+
selectedFeatures,
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
expect(result.generate().code).toMatchInlineSnapshot(`
|
|
101
|
+
"import { useEffect,} from "react";
|
|
102
|
+
|
|
103
|
+
import {
|
|
104
|
+
useLocation,
|
|
105
|
+
useMatches,
|
|
106
|
+
} from "@remix-run/react";
|
|
107
|
+
|
|
108
|
+
import * as Sentry from "@sentry/remix";
|
|
109
|
+
|
|
110
|
+
Sentry.init({
|
|
111
|
+
dsn: "https://sentry.io/123",
|
|
112
|
+
tracesSampleRate: 1,
|
|
113
|
+
|
|
114
|
+
integrations: [Sentry.browserTracingIntegration({
|
|
115
|
+
useEffect,
|
|
116
|
+
useLocation,
|
|
117
|
+
useMatches
|
|
118
|
+
})]
|
|
119
|
+
})"
|
|
120
|
+
`);
|
|
121
|
+
});
|
|
122
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { generateServerInstrumentationFile } from '../../src/remix/sdk-setup';
|
|
2
|
+
|
|
3
|
+
describe('generateServerInstrumentationFile', () => {
|
|
4
|
+
it('should generate server instrumentation file', () => {
|
|
5
|
+
const result = generateServerInstrumentationFile('https://sentry.io/123', {
|
|
6
|
+
performance: true,
|
|
7
|
+
replay: true,
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
expect(result.instrumentationFileMod.generate().code)
|
|
11
|
+
.toMatchInlineSnapshot(`
|
|
12
|
+
"import * as Sentry from "@sentry/remix";
|
|
13
|
+
|
|
14
|
+
Sentry.init({
|
|
15
|
+
dsn: "https://sentry.io/123",
|
|
16
|
+
tracesSampleRate: 1,
|
|
17
|
+
autoInstrumentRemix: true
|
|
18
|
+
})"
|
|
19
|
+
`);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('should generate server instrumentation file when performance is disabled', () => {
|
|
23
|
+
const result = generateServerInstrumentationFile('https://sentry.io/123', {
|
|
24
|
+
performance: false,
|
|
25
|
+
replay: true,
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
expect(result.instrumentationFileMod.generate().code)
|
|
29
|
+
.toMatchInlineSnapshot(`
|
|
30
|
+
"import * as Sentry from "@sentry/remix";
|
|
31
|
+
|
|
32
|
+
Sentry.init({
|
|
33
|
+
dsn: "https://sentry.io/123",
|
|
34
|
+
autoInstrumentRemix: true
|
|
35
|
+
})"
|
|
36
|
+
`);
|
|
37
|
+
});
|
|
38
|
+
});
|