@sentry/wizard 5.2.0 → 5.4.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 +10 -0
- package/dist/e2e-tests/tests/angular-17.test.js +7 -1
- package/dist/e2e-tests/tests/angular-17.test.js.map +1 -1
- package/dist/e2e-tests/tests/angular-19.test.js +7 -1
- package/dist/e2e-tests/tests/angular-19.test.js.map +1 -1
- package/dist/e2e-tests/tests/flutter.test.js +10 -2
- package/dist/e2e-tests/tests/flutter.test.js.map +1 -1
- package/dist/src/flutter/code-tools.d.ts +1 -0
- package/dist/src/flutter/code-tools.js +10 -0
- package/dist/src/flutter/code-tools.js.map +1 -1
- package/dist/src/flutter/templates.d.ts +3 -0
- package/dist/src/flutter/templates.js +13 -1
- package/dist/src/flutter/templates.js.map +1 -1
- package/dist/src/react-native/expo.js +8 -2
- package/dist/src/react-native/expo.js.map +1 -1
- package/dist/src/sourcemaps/sourcemaps-wizard.js +1 -1
- package/dist/src/sourcemaps/sourcemaps-wizard.js.map +1 -1
- package/dist/src/sourcemaps/tools/sentry-cli.js +15 -17
- package/dist/src/sourcemaps/tools/sentry-cli.js.map +1 -1
- package/dist/src/utils/clack/index.d.ts +7 -0
- package/dist/src/utils/clack/index.js +127 -4
- package/dist/src/utils/clack/index.js.map +1 -1
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/version.js.map +1 -1
- package/dist/test/flutter/code-tools.test.js +1 -0
- package/dist/test/flutter/code-tools.test.js.map +1 -1
- package/dist/test/flutter/templates.test.js +8 -2
- package/dist/test/flutter/templates.test.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 5.4.0
|
|
4
|
+
|
|
5
|
+
- feat: Introduce run build command and prompts in sourcemaps wizard ([#1024](https://github.com/getsentry/sentry-wizard/pull/1024))
|
|
6
|
+
- feat: Add a default build path for create-react-app in soucemaps wizard ([#1025](https://github.com/getsentry/sentry-wizard/pull/1025))
|
|
7
|
+
|
|
8
|
+
## 5.3.0
|
|
9
|
+
|
|
10
|
+
- fix(react-native): Avoid importing `isPlainObject` from `@sentry/utils` ([#1023](https://github.com/getsentry/sentry-wizard/pull/1023))
|
|
11
|
+
- feat(flutter): Add replay configuration option ([#1012](https://github.com/getsentry/sentry-wizard/pull/1012))
|
|
12
|
+
|
|
3
13
|
## 5.2.0
|
|
4
14
|
|
|
5
15
|
- fix(nextjs): Update jsx/tsx snippets ([#1015](https://github.com/getsentry/sentry-wizard/pull/1015))
|
|
@@ -96,7 +96,7 @@ async function runWizardOnAngularProject(projectDir, integration, fileModificati
|
|
|
96
96
|
});
|
|
97
97
|
const sourcemapsConfiguredPromise = wizardInstance.waitForOutput('Added a sentry:sourcemaps script to your package.json');
|
|
98
98
|
const buildScriptPromptedPromise = wizardInstance.waitForOutput('Do you want to automatically run the sentry:sourcemaps script after each production build?');
|
|
99
|
-
const optionalArtifactsNotFoundPromise = wizardInstance.waitForOutput("We couldn't find artifacts", {
|
|
99
|
+
const optionalArtifactsNotFoundPromise = wizardInstance.waitForOutput("We couldn't find build artifacts at", {
|
|
100
100
|
optional: true,
|
|
101
101
|
timeout: 5000,
|
|
102
102
|
});
|
|
@@ -104,6 +104,12 @@ async function runWizardOnAngularProject(projectDir, integration, fileModificati
|
|
|
104
104
|
wizardInstance.sendStdin(utils_1.KEYS.ENTER);
|
|
105
105
|
const optionalArtifactsNotFoundPrompted = await optionalArtifactsNotFoundPromise;
|
|
106
106
|
if (optionalArtifactsNotFoundPrompted) {
|
|
107
|
+
// The wizard now presents options when artifacts aren't found:
|
|
108
|
+
// - "Let the wizard run the build command"
|
|
109
|
+
// - "Enter a different path manually"
|
|
110
|
+
// - "Proceed anyway — I believe the path is correct"
|
|
111
|
+
// We want to select "Proceed anyway" (third option)
|
|
112
|
+
wizardInstance.sendStdin(utils_1.KEYS.DOWN);
|
|
107
113
|
wizardInstance.sendStdin(utils_1.KEYS.DOWN);
|
|
108
114
|
wizardInstance.sendStdin(utils_1.KEYS.ENTER);
|
|
109
115
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"angular-17.test.js","sourceRoot":"","sources":["../../../e2e-tests/tests/angular-17.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { Integration } from '../../lib/Constants';\nimport {\n checkFileContents,\n checkFileDoesNotContain,\n checkFileExists,\n checkIfBuilds,\n checkIfRunsOnDevMode,\n checkIfRunsOnProdMode,\n checkPackageJson,\n cleanupGit,\n KEYS,\n modifyFile,\n revertLocalChanges,\n startWizardInstance,\n} from '../utils';\nimport * as path from 'path';\nimport { TEST_ARGS } from '../utils';\nimport { test, expect, describe, beforeAll, afterAll } from 'vitest';\n\ndescribe.sequential('Angular-17', () => {\n describe('with empty project', () => {\n const integration = Integration.angular;\n const projectDir = path.resolve(\n __dirname,\n '../test-applications/angular-17-test-app',\n );\n\n beforeAll(async () => {\n revertLocalChanges(projectDir);\n await runWizardOnAngularProject(projectDir, integration);\n });\n\n afterAll(() => {\n revertLocalChanges(projectDir);\n cleanupGit(projectDir);\n });\n\n checkAngularProject(projectDir, integration);\n });\n\n describe('with pre-defined ErrorHandler', () => {\n const integration = Integration.angular;\n const projectDir = path.resolve(\n __dirname,\n '../test-applications/angular-17-test-app',\n );\n\n beforeAll(async () => {\n revertLocalChanges(projectDir);\n await runWizardOnAngularProject(projectDir, integration, (projectDir) => {\n modifyFile(`${projectDir}/src/app/app.config.ts`, {\n 'providers: [': `providers: [{\n provide: ErrorHandler,\n useValue: null\n },\n `,\n });\n });\n });\n\n afterAll(() => {\n revertLocalChanges(projectDir);\n cleanupGit(projectDir);\n });\n\n checkAngularProject(projectDir, integration, {\n preExistingErrorHandler: true,\n });\n });\n});\n\nasync function runWizardOnAngularProject(\n projectDir: string,\n integration: Integration,\n fileModificationFn?: (projectDir: string) => unknown,\n) {\n const wizardInstance = startWizardInstance(integration, projectDir, true);\n\n if (fileModificationFn) {\n fileModificationFn(projectDir);\n\n await wizardInstance.waitForOutput('Do you want to continue anyway?');\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n 'Please select your package manager.',\n );\n } else {\n await wizardInstance.waitForOutput('Please select your package manager.');\n }\n\n await wizardInstance.sendStdinAndWaitForOutput(\n // Selecting `yarn v1` as the package manager\n [KEYS.DOWN, KEYS.ENTER],\n // \"Do you want to enable Tracing\", sometimes doesn't work as `Tracing` can be printed in bold.\n 'to track the performance of your application?',\n {\n timeout: 240_000, // installing the sdk can take a while\n optional: true,\n },\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n // select \"Yes\" for tracing\n [KEYS.ENTER],\n // \"Do you want to enable Sentry Session Replay\", sometimes doesn't work as `Sentry Session Replay` can be printed in bold.\n 'to get a video-like reproduction of errors during a user session?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n // select \"Yes\" for replay\n [KEYS.ENTER],\n 'Where are your build artifacts located?',\n {\n timeout: 240_000, // installing Sentry CLI can take a while\n },\n );\n\n const sourcemapsConfiguredPromise = wizardInstance.waitForOutput(\n 'Added a sentry:sourcemaps script to your package.json',\n );\n\n const buildScriptPromptedPromise = wizardInstance.waitForOutput(\n 'Do you want to automatically run the sentry:sourcemaps script after each production build?',\n );\n\n const optionalArtifactsNotFoundPromise = wizardInstance.waitForOutput(\n \"We couldn't find artifacts\",\n {\n optional: true,\n timeout: 5000,\n },\n );\n\n // ./dist is the default value, no need to change it\n wizardInstance.sendStdin(KEYS.ENTER);\n\n const optionalArtifactsNotFoundPrompted =\n await optionalArtifactsNotFoundPromise;\n\n if (optionalArtifactsNotFoundPrompted) {\n wizardInstance.sendStdin(KEYS.DOWN);\n wizardInstance.sendStdin(KEYS.ENTER);\n }\n\n await sourcemapsConfiguredPromise;\n\n await buildScriptPromptedPromise;\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, automatically add sentry:sourcemaps script\n 'Is yarn build your production build command?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, yarn build is the production build command\n 'Are you using a CI/CD tool to build and deploy your application?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.DOWN, KEYS.ENTER], // no CI/CD tool\n 'Do you want to create an example component to test your Sentry setup?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, create example component\n 'Did you apply the snippet above?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, applied the snippet\n 'Looks like you have Prettier in your project. Do you want to run it on your files?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, run prettier\n 'Successfully installed the Sentry Angular SDK!',\n );\n\n wizardInstance.kill();\n}\n\nfunction checkAngularProject(\n projectDir: string,\n integration: Integration,\n options?: {\n preExistingErrorHandler?: boolean;\n },\n) {\n test('package.json is updated correctly', () => {\n checkPackageJson(projectDir, integration);\n\n const packageJsonFile = path.resolve(projectDir, 'package.json');\n checkFileContents(packageJsonFile, [\n `\"sentry:sourcemaps\": \"sentry-cli sourcemaps inject --org ${TEST_ARGS.ORG_SLUG} --project ${TEST_ARGS.PROJECT_SLUG} ./dist && sentry-cli sourcemaps upload --org ${TEST_ARGS.ORG_SLUG} --project ${TEST_ARGS.PROJECT_SLUG} ./dist\"`,\n `\"build\": \"ng build && yarn sentry:sourcemaps\"`,\n ]);\n });\n\n test('Sentry is correctly injected into Angular app config', () => {\n const appConfigFile = path.resolve(projectDir, 'src/main.ts');\n checkFileExists(appConfigFile);\n\n checkFileContents(appConfigFile, [\n `import * as Sentry from '@sentry/angular'`,\n 'Sentry.init({',\n TEST_ARGS.PROJECT_DSN,\n 'Sentry.browserTracingIntegration()',\n 'Sentry.replayIntegration()',\n 'tracesSampleRate: 1',\n 'replaysSessionSampleRate: 0.1',\n 'replaysOnErrorSampleRate: 1',\n ]);\n });\n\n test('Sentry is correctly injected into Angular app module', () => {\n const appModuleFile = path.resolve(projectDir, 'src/app/app.config.ts');\n checkFileExists(appModuleFile);\n\n // Checking if the ErrorHandler is already present in the providers array,\n // and if it is, we skip adding it\n if (options?.preExistingErrorHandler) {\n checkFileDoesNotContain(appModuleFile, 'Sentry.createErrorHandler()');\n }\n\n checkFileContents(appModuleFile, [\n `import * as Sentry from '@sentry/angular'`,\n options?.preExistingErrorHandler\n ? `provide: ErrorHandler,\n useValue: null`\n : `provide: ErrorHandler,\n useValue: Sentry.createErrorHandler()`,\n `provide: Sentry.TraceService,\n deps: [Router]`,\n `provide: APP_INITIALIZER,\n useFactory: () => () => {},\n deps: [Sentry.TraceService],\n multi: true`,\n ]);\n });\n\n test('angular.json is updated correctly', async () => {\n const angularJsonFile = path.resolve(projectDir, 'angular.json');\n checkFileExists(angularJsonFile);\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const angularJson = (await import(angularJsonFile)) as Record<string, any>;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n for (const [, project] of Object.entries(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n angularJson.projects as Record<string, any>,\n )) {\n expect(\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n project?.architect?.build?.configurations?.production?.sourceMap,\n ).toBe(true);\n }\n });\n\n test('builds successfully', async () => {\n await checkIfBuilds(projectDir);\n });\n\n test('runs on prod mode correctly', async () => {\n await checkIfRunsOnProdMode(\n projectDir,\n 'Application bundle generation complete.',\n );\n });\n\n test('runs on dev mode correctly', async () => {\n await checkIfRunsOnDevMode(\n projectDir,\n 'Application bundle generation complete.',\n );\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"angular-17.test.js","sourceRoot":"","sources":["../../../e2e-tests/tests/angular-17.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA,mDAAkD;AAClD,oCAakB;AAClB,2CAA6B;AAC7B,oCAAqC;AACrC,mCAAqE;AAErE,iBAAQ,CAAC,UAAU,CAAC,YAAY,EAAE,GAAG,EAAE;IACrC,IAAA,iBAAQ,EAAC,oBAAoB,EAAE,GAAG,EAAE;QAClC,MAAM,WAAW,GAAG,uBAAW,CAAC,OAAO,CAAC;QACxC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAC7B,SAAS,EACT,0CAA0C,CAC3C,CAAC;QAEF,IAAA,kBAAS,EAAC,KAAK,IAAI,EAAE;YACnB,IAAA,0BAAkB,EAAC,UAAU,CAAC,CAAC;YAC/B,MAAM,yBAAyB,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,IAAA,iBAAQ,EAAC,GAAG,EAAE;YACZ,IAAA,0BAAkB,EAAC,UAAU,CAAC,CAAC;YAC/B,IAAA,kBAAU,EAAC,UAAU,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;QAEH,mBAAmB,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,IAAA,iBAAQ,EAAC,+BAA+B,EAAE,GAAG,EAAE;QAC7C,MAAM,WAAW,GAAG,uBAAW,CAAC,OAAO,CAAC;QACxC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAC7B,SAAS,EACT,0CAA0C,CAC3C,CAAC;QAEF,IAAA,kBAAS,EAAC,KAAK,IAAI,EAAE;YACnB,IAAA,0BAAkB,EAAC,UAAU,CAAC,CAAC;YAC/B,MAAM,yBAAyB,CAAC,UAAU,EAAE,WAAW,EAAE,CAAC,UAAU,EAAE,EAAE;gBACtE,IAAA,kBAAU,EAAC,GAAG,UAAU,wBAAwB,EAAE;oBAChD,cAAc,EAAE;;;;aAIb;iBACJ,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,IAAA,iBAAQ,EAAC,GAAG,EAAE;YACZ,IAAA,0BAAkB,EAAC,UAAU,CAAC,CAAC;YAC/B,IAAA,kBAAU,EAAC,UAAU,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;QAEH,mBAAmB,CAAC,UAAU,EAAE,WAAW,EAAE;YAC3C,uBAAuB,EAAE,IAAI;SAC9B,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,KAAK,UAAU,yBAAyB,CACtC,UAAkB,EAClB,WAAwB,EACxB,kBAAoD;IAEpD,MAAM,cAAc,GAAG,IAAA,2BAAmB,EAAC,WAAW,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;IAE1E,IAAI,kBAAkB,EAAE;QACtB,kBAAkB,CAAC,UAAU,CAAC,CAAC;QAE/B,MAAM,cAAc,CAAC,aAAa,CAAC,iCAAiC,CAAC,CAAC;QAEtE,MAAM,cAAc,CAAC,yBAAyB,CAC5C,CAAC,YAAI,CAAC,KAAK,CAAC,EACZ,qCAAqC,CACtC,CAAC;KACH;SAAM;QACL,MAAM,cAAc,CAAC,aAAa,CAAC,qCAAqC,CAAC,CAAC;KAC3E;IAED,MAAM,cAAc,CAAC,yBAAyB;IAC5C,6CAA6C;IAC7C,CAAC,YAAI,CAAC,IAAI,EAAE,YAAI,CAAC,KAAK,CAAC;IACvB,+FAA+F;IAC/F,+CAA+C,EAC/C;QACE,OAAO,EAAE,MAAO;QAChB,QAAQ,EAAE,IAAI;KACf,CACF,CAAC;IAEF,MAAM,cAAc,CAAC,yBAAyB;IAC5C,2BAA2B;IAC3B,CAAC,YAAI,CAAC,KAAK,CAAC;IACZ,2HAA2H;IAC3H,mEAAmE,CACpE,CAAC;IAEF,MAAM,cAAc,CAAC,yBAAyB;IAC5C,0BAA0B;IAC1B,CAAC,YAAI,CAAC,KAAK,CAAC,EACZ,yCAAyC,EACzC;QACE,OAAO,EAAE,MAAO,EAAE,yCAAyC;KAC5D,CACF,CAAC;IAEF,MAAM,2BAA2B,GAAG,cAAc,CAAC,aAAa,CAC9D,uDAAuD,CACxD,CAAC;IAEF,MAAM,0BAA0B,GAAG,cAAc,CAAC,aAAa,CAC7D,4FAA4F,CAC7F,CAAC;IAEF,MAAM,gCAAgC,GAAG,cAAc,CAAC,aAAa,CACnE,qCAAqC,EACrC;QACE,QAAQ,EAAE,IAAI;QACd,OAAO,EAAE,IAAI;KACd,CACF,CAAC;IAEF,oDAAoD;IACpD,cAAc,CAAC,SAAS,CAAC,YAAI,CAAC,KAAK,CAAC,CAAC;IAErC,MAAM,iCAAiC,GACrC,MAAM,gCAAgC,CAAC;IAEzC,IAAI,iCAAiC,EAAE;QACrC,+DAA+D;QAC/D,2CAA2C;QAC3C,sCAAsC;QACtC,qDAAqD;QACrD,oDAAoD;QACpD,cAAc,CAAC,SAAS,CAAC,YAAI,CAAC,IAAI,CAAC,CAAC;QACpC,cAAc,CAAC,SAAS,CAAC,YAAI,CAAC,IAAI,CAAC,CAAC;QACpC,cAAc,CAAC,SAAS,CAAC,YAAI,CAAC,KAAK,CAAC,CAAC;KACtC;IAED,MAAM,2BAA2B,CAAC;IAElC,MAAM,0BAA0B,CAAC;IAEjC,MAAM,cAAc,CAAC,yBAAyB,CAC5C,CAAC,YAAI,CAAC,KAAK,CAAC,EAAE,kDAAkD;IAChE,8CAA8C,CAC/C,CAAC;IAEF,MAAM,cAAc,CAAC,yBAAyB,CAC5C,CAAC,YAAI,CAAC,KAAK,CAAC,EAAE,kDAAkD;IAChE,kEAAkE,CACnE,CAAC;IAEF,MAAM,cAAc,CAAC,yBAAyB,CAC5C,CAAC,YAAI,CAAC,IAAI,EAAE,YAAI,CAAC,KAAK,CAAC,EAAE,gBAAgB;IACzC,uEAAuE,CACxE,CAAC;IAEF,MAAM,cAAc,CAAC,yBAAyB,CAC5C,CAAC,YAAI,CAAC,KAAK,CAAC,EAAE,gCAAgC;IAC9C,kCAAkC,CACnC,CAAC;IAEF,MAAM,cAAc,CAAC,yBAAyB,CAC5C,CAAC,YAAI,CAAC,KAAK,CAAC,EAAE,2BAA2B;IACzC,oFAAoF,CACrF,CAAC;IAEF,MAAM,cAAc,CAAC,yBAAyB,CAC5C,CAAC,YAAI,CAAC,KAAK,CAAC,EAAE,oBAAoB;IAClC,gDAAgD,CACjD,CAAC;IAEF,cAAc,CAAC,IAAI,EAAE,CAAC;AACxB,CAAC;AAED,SAAS,mBAAmB,CAC1B,UAAkB,EAClB,WAAwB,EACxB,OAEC;IAED,IAAA,aAAI,EAAC,mCAAmC,EAAE,GAAG,EAAE;QAC7C,IAAA,wBAAgB,EAAC,UAAU,EAAE,WAAW,CAAC,CAAC;QAE1C,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;QACjE,IAAA,yBAAiB,EAAC,eAAe,EAAE;YACjC,4DAA4D,iBAAS,CAAC,QAAQ,cAAc,iBAAS,CAAC,YAAY,iDAAiD,iBAAS,CAAC,QAAQ,cAAc,iBAAS,CAAC,YAAY,UAAU;YACnO,+CAA+C;SAChD,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAA,aAAI,EAAC,sDAAsD,EAAE,GAAG,EAAE;QAChE,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;QAC9D,IAAA,uBAAe,EAAC,aAAa,CAAC,CAAC;QAE/B,IAAA,yBAAiB,EAAC,aAAa,EAAE;YAC/B,2CAA2C;YAC3C,eAAe;YACf,iBAAS,CAAC,WAAW;YACrB,oCAAoC;YACpC,4BAA4B;YAC5B,qBAAqB;YACrB,+BAA+B;YAC/B,6BAA6B;SAC9B,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAA,aAAI,EAAC,sDAAsD,EAAE,GAAG,EAAE;QAChE,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,uBAAuB,CAAC,CAAC;QACxE,IAAA,uBAAe,EAAC,aAAa,CAAC,CAAC;QAE/B,0EAA0E;QAC1E,kCAAkC;QAClC,IAAI,OAAO,EAAE,uBAAuB,EAAE;YACpC,IAAA,+BAAuB,EAAC,aAAa,EAAE,6BAA6B,CAAC,CAAC;SACvE;QAED,IAAA,yBAAiB,EAAC,aAAa,EAAE;YAC/B,2CAA2C;YAC3C,OAAO,EAAE,uBAAuB;gBAC9B,CAAC,CAAC;qBACW;gBACb,CAAC,CAAC;4CACkC;YACtC;qBACe;YACf;;;kBAGY;SACb,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAA,aAAI,EAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;QACnD,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;QACjE,IAAA,uBAAe,EAAC,eAAe,CAAC,CAAC;QAEjC,8DAA8D;QAC9D,MAAM,WAAW,GAAG,CAAC,MAAM,MAAM,CAAC,eAAe,CAAC,CAAwB,CAAC;QAE3E,8DAA8D;QAC9D,KAAK,MAAM,CAAC,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO;QACtC,8DAA8D;QAC9D,WAAW,CAAC,QAA+B,CAC5C,EAAE;YACD,IAAA,eAAM;YACJ,sEAAsE;YACtE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,SAAS,CACjE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SACd;IACH,CAAC,CAAC,CAAC;IAEH,IAAA,aAAI,EAAC,qBAAqB,EAAE,KAAK,IAAI,EAAE;QACrC,MAAM,IAAA,qBAAa,EAAC,UAAU,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,IAAA,aAAI,EAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;QAC7C,MAAM,IAAA,6BAAqB,EACzB,UAAU,EACV,yCAAyC,CAC1C,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,IAAA,aAAI,EAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;QAC5C,MAAM,IAAA,4BAAoB,EACxB,UAAU,EACV,yCAAyC,CAC1C,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { Integration } from '../../lib/Constants';\nimport {\n checkFileContents,\n checkFileDoesNotContain,\n checkFileExists,\n checkIfBuilds,\n checkIfRunsOnDevMode,\n checkIfRunsOnProdMode,\n checkPackageJson,\n cleanupGit,\n KEYS,\n modifyFile,\n revertLocalChanges,\n startWizardInstance,\n} from '../utils';\nimport * as path from 'path';\nimport { TEST_ARGS } from '../utils';\nimport { test, expect, describe, beforeAll, afterAll } from 'vitest';\n\ndescribe.sequential('Angular-17', () => {\n describe('with empty project', () => {\n const integration = Integration.angular;\n const projectDir = path.resolve(\n __dirname,\n '../test-applications/angular-17-test-app',\n );\n\n beforeAll(async () => {\n revertLocalChanges(projectDir);\n await runWizardOnAngularProject(projectDir, integration);\n });\n\n afterAll(() => {\n revertLocalChanges(projectDir);\n cleanupGit(projectDir);\n });\n\n checkAngularProject(projectDir, integration);\n });\n\n describe('with pre-defined ErrorHandler', () => {\n const integration = Integration.angular;\n const projectDir = path.resolve(\n __dirname,\n '../test-applications/angular-17-test-app',\n );\n\n beforeAll(async () => {\n revertLocalChanges(projectDir);\n await runWizardOnAngularProject(projectDir, integration, (projectDir) => {\n modifyFile(`${projectDir}/src/app/app.config.ts`, {\n 'providers: [': `providers: [{\n provide: ErrorHandler,\n useValue: null\n },\n `,\n });\n });\n });\n\n afterAll(() => {\n revertLocalChanges(projectDir);\n cleanupGit(projectDir);\n });\n\n checkAngularProject(projectDir, integration, {\n preExistingErrorHandler: true,\n });\n });\n});\n\nasync function runWizardOnAngularProject(\n projectDir: string,\n integration: Integration,\n fileModificationFn?: (projectDir: string) => unknown,\n) {\n const wizardInstance = startWizardInstance(integration, projectDir, true);\n\n if (fileModificationFn) {\n fileModificationFn(projectDir);\n\n await wizardInstance.waitForOutput('Do you want to continue anyway?');\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n 'Please select your package manager.',\n );\n } else {\n await wizardInstance.waitForOutput('Please select your package manager.');\n }\n\n await wizardInstance.sendStdinAndWaitForOutput(\n // Selecting `yarn v1` as the package manager\n [KEYS.DOWN, KEYS.ENTER],\n // \"Do you want to enable Tracing\", sometimes doesn't work as `Tracing` can be printed in bold.\n 'to track the performance of your application?',\n {\n timeout: 240_000, // installing the sdk can take a while\n optional: true,\n },\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n // select \"Yes\" for tracing\n [KEYS.ENTER],\n // \"Do you want to enable Sentry Session Replay\", sometimes doesn't work as `Sentry Session Replay` can be printed in bold.\n 'to get a video-like reproduction of errors during a user session?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n // select \"Yes\" for replay\n [KEYS.ENTER],\n 'Where are your build artifacts located?',\n {\n timeout: 240_000, // installing Sentry CLI can take a while\n },\n );\n\n const sourcemapsConfiguredPromise = wizardInstance.waitForOutput(\n 'Added a sentry:sourcemaps script to your package.json',\n );\n\n const buildScriptPromptedPromise = wizardInstance.waitForOutput(\n 'Do you want to automatically run the sentry:sourcemaps script after each production build?',\n );\n\n const optionalArtifactsNotFoundPromise = wizardInstance.waitForOutput(\n \"We couldn't find build artifacts at\",\n {\n optional: true,\n timeout: 5000,\n },\n );\n\n // ./dist is the default value, no need to change it\n wizardInstance.sendStdin(KEYS.ENTER);\n\n const optionalArtifactsNotFoundPrompted =\n await optionalArtifactsNotFoundPromise;\n\n if (optionalArtifactsNotFoundPrompted) {\n // The wizard now presents options when artifacts aren't found:\n // - \"Let the wizard run the build command\"\n // - \"Enter a different path manually\"\n // - \"Proceed anyway — I believe the path is correct\"\n // We want to select \"Proceed anyway\" (third option)\n wizardInstance.sendStdin(KEYS.DOWN);\n wizardInstance.sendStdin(KEYS.DOWN);\n wizardInstance.sendStdin(KEYS.ENTER);\n }\n\n await sourcemapsConfiguredPromise;\n\n await buildScriptPromptedPromise;\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, automatically add sentry:sourcemaps script\n 'Is yarn build your production build command?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, yarn build is the production build command\n 'Are you using a CI/CD tool to build and deploy your application?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.DOWN, KEYS.ENTER], // no CI/CD tool\n 'Do you want to create an example component to test your Sentry setup?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, create example component\n 'Did you apply the snippet above?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, applied the snippet\n 'Looks like you have Prettier in your project. Do you want to run it on your files?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, run prettier\n 'Successfully installed the Sentry Angular SDK!',\n );\n\n wizardInstance.kill();\n}\n\nfunction checkAngularProject(\n projectDir: string,\n integration: Integration,\n options?: {\n preExistingErrorHandler?: boolean;\n },\n) {\n test('package.json is updated correctly', () => {\n checkPackageJson(projectDir, integration);\n\n const packageJsonFile = path.resolve(projectDir, 'package.json');\n checkFileContents(packageJsonFile, [\n `\"sentry:sourcemaps\": \"sentry-cli sourcemaps inject --org ${TEST_ARGS.ORG_SLUG} --project ${TEST_ARGS.PROJECT_SLUG} ./dist && sentry-cli sourcemaps upload --org ${TEST_ARGS.ORG_SLUG} --project ${TEST_ARGS.PROJECT_SLUG} ./dist\"`,\n `\"build\": \"ng build && yarn sentry:sourcemaps\"`,\n ]);\n });\n\n test('Sentry is correctly injected into Angular app config', () => {\n const appConfigFile = path.resolve(projectDir, 'src/main.ts');\n checkFileExists(appConfigFile);\n\n checkFileContents(appConfigFile, [\n `import * as Sentry from '@sentry/angular'`,\n 'Sentry.init({',\n TEST_ARGS.PROJECT_DSN,\n 'Sentry.browserTracingIntegration()',\n 'Sentry.replayIntegration()',\n 'tracesSampleRate: 1',\n 'replaysSessionSampleRate: 0.1',\n 'replaysOnErrorSampleRate: 1',\n ]);\n });\n\n test('Sentry is correctly injected into Angular app module', () => {\n const appModuleFile = path.resolve(projectDir, 'src/app/app.config.ts');\n checkFileExists(appModuleFile);\n\n // Checking if the ErrorHandler is already present in the providers array,\n // and if it is, we skip adding it\n if (options?.preExistingErrorHandler) {\n checkFileDoesNotContain(appModuleFile, 'Sentry.createErrorHandler()');\n }\n\n checkFileContents(appModuleFile, [\n `import * as Sentry from '@sentry/angular'`,\n options?.preExistingErrorHandler\n ? `provide: ErrorHandler,\n useValue: null`\n : `provide: ErrorHandler,\n useValue: Sentry.createErrorHandler()`,\n `provide: Sentry.TraceService,\n deps: [Router]`,\n `provide: APP_INITIALIZER,\n useFactory: () => () => {},\n deps: [Sentry.TraceService],\n multi: true`,\n ]);\n });\n\n test('angular.json is updated correctly', async () => {\n const angularJsonFile = path.resolve(projectDir, 'angular.json');\n checkFileExists(angularJsonFile);\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const angularJson = (await import(angularJsonFile)) as Record<string, any>;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n for (const [, project] of Object.entries(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n angularJson.projects as Record<string, any>,\n )) {\n expect(\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n project?.architect?.build?.configurations?.production?.sourceMap,\n ).toBe(true);\n }\n });\n\n test('builds successfully', async () => {\n await checkIfBuilds(projectDir);\n });\n\n test('runs on prod mode correctly', async () => {\n await checkIfRunsOnProdMode(\n projectDir,\n 'Application bundle generation complete.',\n );\n });\n\n test('runs on dev mode correctly', async () => {\n await checkIfRunsOnDevMode(\n projectDir,\n 'Application bundle generation complete.',\n );\n });\n}\n"]}
|
|
@@ -95,7 +95,7 @@ async function runWizardOnAngularProject(projectDir, integration, fileModificati
|
|
|
95
95
|
});
|
|
96
96
|
const sourcemapsConfiguredPromise = wizardInstance.waitForOutput('Added a sentry:sourcemaps script to your package.json');
|
|
97
97
|
const buildScriptPromptedPromise = wizardInstance.waitForOutput('Do you want to automatically run the sentry:sourcemaps script after each production build?');
|
|
98
|
-
const optionalArtifactsNotFoundPromise = wizardInstance.waitForOutput("We couldn't find artifacts", {
|
|
98
|
+
const optionalArtifactsNotFoundPromise = wizardInstance.waitForOutput("We couldn't find build artifacts at", {
|
|
99
99
|
optional: true,
|
|
100
100
|
timeout: 5000,
|
|
101
101
|
});
|
|
@@ -103,6 +103,12 @@ async function runWizardOnAngularProject(projectDir, integration, fileModificati
|
|
|
103
103
|
wizardInstance.sendStdin(utils_1.KEYS.ENTER);
|
|
104
104
|
const optionalArtifactsNotFoundPrompted = await optionalArtifactsNotFoundPromise;
|
|
105
105
|
if (optionalArtifactsNotFoundPrompted) {
|
|
106
|
+
// The wizard now presents options when artifacts aren't found:
|
|
107
|
+
// - "Let the wizard run the build command"
|
|
108
|
+
// - "Enter a different path manually"
|
|
109
|
+
// - "Proceed anyway — I believe the path is correct"
|
|
110
|
+
// We want to select "Proceed anyway" (third option)
|
|
111
|
+
wizardInstance.sendStdin(utils_1.KEYS.DOWN);
|
|
106
112
|
wizardInstance.sendStdin(utils_1.KEYS.DOWN);
|
|
107
113
|
wizardInstance.sendStdin(utils_1.KEYS.ENTER);
|
|
108
114
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"angular-19.test.js","sourceRoot":"","sources":["../../../e2e-tests/tests/angular-19.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { Integration } from '../../lib/Constants';\nimport {\n checkFileContents,\n checkFileDoesNotContain,\n checkFileExists,\n checkIfBuilds,\n checkIfRunsOnDevMode,\n checkIfRunsOnProdMode,\n checkPackageJson,\n cleanupGit,\n KEYS,\n modifyFile,\n revertLocalChanges,\n startWizardInstance,\n} from '../utils';\nimport * as path from 'path';\nimport { TEST_ARGS } from '../utils';\nimport { test, expect, describe, beforeAll, afterAll } from 'vitest';\n\ndescribe.sequential('Angular-19', () => {\n describe('with empty project', () => {\n const integration = Integration.angular;\n const projectDir = path.resolve(\n __dirname,\n '../test-applications/angular-19-test-app',\n );\n\n beforeAll(async () => {\n revertLocalChanges(projectDir);\n await runWizardOnAngularProject(projectDir, integration);\n });\n\n afterAll(() => {\n revertLocalChanges(projectDir);\n cleanupGit(projectDir);\n });\n\n checkAngularProject(projectDir, integration);\n });\n describe('with pre-defined ErrorHandler', () => {\n const integration = Integration.angular;\n const projectDir = path.resolve(\n __dirname,\n '../test-applications/angular-19-test-app',\n );\n\n beforeAll(async () => {\n revertLocalChanges(projectDir);\n await runWizardOnAngularProject(projectDir, integration, (projectDir) => {\n modifyFile(`${projectDir}/src/app/app.config.ts`, {\n 'providers: [': `providers: [{\n provide: ErrorHandler,\n useValue: null\n },\n `,\n });\n });\n });\n\n afterAll(() => {\n revertLocalChanges(projectDir);\n cleanupGit(projectDir);\n });\n\n checkAngularProject(projectDir, integration, {\n preExistingErrorHandler: true,\n });\n });\n});\n\nasync function runWizardOnAngularProject(\n projectDir: string,\n integration: Integration,\n fileModificationFn?: (projectDir: string) => unknown,\n) {\n const wizardInstance = startWizardInstance(integration, projectDir, true);\n\n if (fileModificationFn) {\n fileModificationFn(projectDir);\n\n await wizardInstance.waitForOutput('Do you want to continue anyway?');\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n 'Please select your package manager.',\n );\n } else {\n await wizardInstance.waitForOutput('Please select your package manager.');\n }\n\n await wizardInstance.sendStdinAndWaitForOutput(\n // Selecting `yarn` as the package manager\n [KEYS.DOWN, KEYS.ENTER],\n // \"Do you want to enable Tracing\", sometimes doesn't work as `Tracing` can be printed in bold.\n 'to track the performance of your application?',\n {\n timeout: 240_000,\n optional: true,\n },\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n // \"Do you want to enable Sentry Session Replay\", sometimes doesn't work as `Sentry Session Replay` can be printed in bold.\n 'to get a video-like reproduction of errors during a user session?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n // The first choice here is Angular\n [KEYS.ENTER],\n 'Where are your build artifacts located?',\n {\n optional: true,\n timeout: 5000,\n },\n );\n\n const sourcemapsConfiguredPromise = wizardInstance.waitForOutput(\n 'Added a sentry:sourcemaps script to your package.json',\n );\n\n const buildScriptPromptedPromise = wizardInstance.waitForOutput(\n 'Do you want to automatically run the sentry:sourcemaps script after each production build?',\n );\n\n const optionalArtifactsNotFoundPromise = wizardInstance.waitForOutput(\n \"We couldn't find artifacts\",\n {\n optional: true,\n timeout: 5000,\n },\n );\n\n // ./dist is the default value, no need to change it\n wizardInstance.sendStdin(KEYS.ENTER);\n\n const optionalArtifactsNotFoundPrompted =\n await optionalArtifactsNotFoundPromise;\n\n if (optionalArtifactsNotFoundPrompted) {\n wizardInstance.sendStdin(KEYS.DOWN);\n wizardInstance.sendStdin(KEYS.ENTER);\n }\n\n await sourcemapsConfiguredPromise;\n await buildScriptPromptedPromise;\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, automatically add sentry:sourcemaps script\n 'Is yarn build your production build command?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, yarn build is the production build command\n 'Are you using a CI/CD tool to build and deploy your application?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.DOWN, KEYS.ENTER], // no CI/CD tool\n 'Do you want to create an example component to test your Sentry setup?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, create example component\n 'Did you apply the snippet above?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, applied the snippet\n 'Looks like you have Prettier in your project. Do you want to run it on your files?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, run prettier\n 'Successfully installed the Sentry Angular SDK!',\n );\n\n wizardInstance.kill();\n}\n\nfunction checkAngularProject(\n projectDir: string,\n integration: Integration,\n options?: {\n preExistingErrorHandler?: boolean;\n },\n) {\n test('package.json is updated correctly', () => {\n checkPackageJson(projectDir, integration);\n\n const packageJsonFile = path.resolve(projectDir, 'package.json');\n checkFileContents(packageJsonFile, [\n `\"sentry:sourcemaps\": \"sentry-cli sourcemaps inject --org ${TEST_ARGS.ORG_SLUG} --project ${TEST_ARGS.PROJECT_SLUG} ./dist && sentry-cli sourcemaps upload --org ${TEST_ARGS.ORG_SLUG} --project ${TEST_ARGS.PROJECT_SLUG} ./dist\"`,\n `\"build\": \"ng build && yarn sentry:sourcemaps\"`,\n ]);\n });\n\n test('Sentry is correctly injected into Angular app config', () => {\n const appConfigFile = path.resolve(projectDir, 'src/main.ts');\n checkFileExists(appConfigFile);\n\n checkFileContents(appConfigFile, [\n `import * as Sentry from '@sentry/angular'`,\n 'Sentry.init({',\n TEST_ARGS.PROJECT_DSN,\n 'Sentry.browserTracingIntegration()',\n 'Sentry.replayIntegration()',\n 'tracesSampleRate: 1',\n 'replaysSessionSampleRate: 0.1',\n 'replaysOnErrorSampleRate: 1',\n ]);\n });\n\n test('Sentry is correctly injected into Angular app module', () => {\n const appModuleFile = path.resolve(projectDir, 'src/app/app.config.ts');\n checkFileExists(appModuleFile);\n\n // Checking if the ErrorHandler is already present in the providers array,\n // and if it is, we skip adding it\n if (options?.preExistingErrorHandler) {\n checkFileDoesNotContain(appModuleFile, 'Sentry.createErrorHandler()');\n }\n\n checkFileContents(appModuleFile, [\n `import * as Sentry from '@sentry/angular'`,\n options?.preExistingErrorHandler\n ? `provide: ErrorHandler,\n useValue: null`\n : `provide: ErrorHandler,\n useValue: Sentry.createErrorHandler()`,\n `provide: Sentry.TraceService,\n deps: [Router]`,\n `provideAppInitializer(() => {\n inject(Sentry.TraceService);\n })`,\n ]);\n });\n\n test('angular.json is updated correctly', async () => {\n const angularJsonFile = path.resolve(projectDir, 'angular.json');\n checkFileExists(angularJsonFile);\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const angularJson = (await import(angularJsonFile)) as Record<string, any>;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n for (const [, project] of Object.entries(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n angularJson.projects as Record<string, any>,\n )) {\n expect(\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n project?.architect?.build?.configurations?.production?.sourceMap,\n ).toBe(true);\n }\n });\n\n test('builds successfully', async () => {\n await checkIfBuilds(projectDir);\n });\n\n test('runs on prod mode correctly', async () => {\n await checkIfRunsOnProdMode(\n projectDir,\n 'Application bundle generation complete.',\n );\n });\n\n test('runs on dev mode correctly', async () => {\n await checkIfRunsOnDevMode(\n projectDir,\n 'Application bundle generation complete.',\n );\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"angular-19.test.js","sourceRoot":"","sources":["../../../e2e-tests/tests/angular-19.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { Integration } from '../../lib/Constants';\nimport {\n checkFileContents,\n checkFileDoesNotContain,\n checkFileExists,\n checkIfBuilds,\n checkIfRunsOnDevMode,\n checkIfRunsOnProdMode,\n checkPackageJson,\n cleanupGit,\n KEYS,\n modifyFile,\n revertLocalChanges,\n startWizardInstance,\n} from '../utils';\nimport * as path from 'path';\nimport { TEST_ARGS } from '../utils';\nimport { test, expect, describe, beforeAll, afterAll } from 'vitest';\n\ndescribe.sequential('Angular-19', () => {\n describe('with empty project', () => {\n const integration = Integration.angular;\n const projectDir = path.resolve(\n __dirname,\n '../test-applications/angular-19-test-app',\n );\n\n beforeAll(async () => {\n revertLocalChanges(projectDir);\n await runWizardOnAngularProject(projectDir, integration);\n });\n\n afterAll(() => {\n revertLocalChanges(projectDir);\n cleanupGit(projectDir);\n });\n\n checkAngularProject(projectDir, integration);\n });\n describe('with pre-defined ErrorHandler', () => {\n const integration = Integration.angular;\n const projectDir = path.resolve(\n __dirname,\n '../test-applications/angular-19-test-app',\n );\n\n beforeAll(async () => {\n revertLocalChanges(projectDir);\n await runWizardOnAngularProject(projectDir, integration, (projectDir) => {\n modifyFile(`${projectDir}/src/app/app.config.ts`, {\n 'providers: [': `providers: [{\n provide: ErrorHandler,\n useValue: null\n },\n `,\n });\n });\n });\n\n afterAll(() => {\n revertLocalChanges(projectDir);\n cleanupGit(projectDir);\n });\n\n checkAngularProject(projectDir, integration, {\n preExistingErrorHandler: true,\n });\n });\n});\n\nasync function runWizardOnAngularProject(\n projectDir: string,\n integration: Integration,\n fileModificationFn?: (projectDir: string) => unknown,\n) {\n const wizardInstance = startWizardInstance(integration, projectDir, true);\n\n if (fileModificationFn) {\n fileModificationFn(projectDir);\n\n await wizardInstance.waitForOutput('Do you want to continue anyway?');\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n 'Please select your package manager.',\n );\n } else {\n await wizardInstance.waitForOutput('Please select your package manager.');\n }\n\n await wizardInstance.sendStdinAndWaitForOutput(\n // Selecting `yarn` as the package manager\n [KEYS.DOWN, KEYS.ENTER],\n // \"Do you want to enable Tracing\", sometimes doesn't work as `Tracing` can be printed in bold.\n 'to track the performance of your application?',\n {\n timeout: 240_000,\n optional: true,\n },\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n // \"Do you want to enable Sentry Session Replay\", sometimes doesn't work as `Sentry Session Replay` can be printed in bold.\n 'to get a video-like reproduction of errors during a user session?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n // The first choice here is Angular\n [KEYS.ENTER],\n 'Where are your build artifacts located?',\n {\n optional: true,\n timeout: 5000,\n },\n );\n\n const sourcemapsConfiguredPromise = wizardInstance.waitForOutput(\n 'Added a sentry:sourcemaps script to your package.json',\n );\n\n const buildScriptPromptedPromise = wizardInstance.waitForOutput(\n 'Do you want to automatically run the sentry:sourcemaps script after each production build?',\n );\n\n const optionalArtifactsNotFoundPromise = wizardInstance.waitForOutput(\n \"We couldn't find build artifacts at\",\n {\n optional: true,\n timeout: 5000,\n },\n );\n\n // ./dist is the default value, no need to change it\n wizardInstance.sendStdin(KEYS.ENTER);\n\n const optionalArtifactsNotFoundPrompted =\n await optionalArtifactsNotFoundPromise;\n\n if (optionalArtifactsNotFoundPrompted) {\n // The wizard now presents options when artifacts aren't found:\n // - \"Let the wizard run the build command\"\n // - \"Enter a different path manually\"\n // - \"Proceed anyway — I believe the path is correct\"\n // We want to select \"Proceed anyway\" (third option)\n wizardInstance.sendStdin(KEYS.DOWN);\n wizardInstance.sendStdin(KEYS.DOWN);\n wizardInstance.sendStdin(KEYS.ENTER);\n }\n\n await sourcemapsConfiguredPromise;\n await buildScriptPromptedPromise;\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, automatically add sentry:sourcemaps script\n 'Is yarn build your production build command?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, yarn build is the production build command\n 'Are you using a CI/CD tool to build and deploy your application?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.DOWN, KEYS.ENTER], // no CI/CD tool\n 'Do you want to create an example component to test your Sentry setup?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, create example component\n 'Did you apply the snippet above?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, applied the snippet\n 'Looks like you have Prettier in your project. Do you want to run it on your files?',\n );\n\n await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER], // yes, run prettier\n 'Successfully installed the Sentry Angular SDK!',\n );\n\n wizardInstance.kill();\n}\n\nfunction checkAngularProject(\n projectDir: string,\n integration: Integration,\n options?: {\n preExistingErrorHandler?: boolean;\n },\n) {\n test('package.json is updated correctly', () => {\n checkPackageJson(projectDir, integration);\n\n const packageJsonFile = path.resolve(projectDir, 'package.json');\n checkFileContents(packageJsonFile, [\n `\"sentry:sourcemaps\": \"sentry-cli sourcemaps inject --org ${TEST_ARGS.ORG_SLUG} --project ${TEST_ARGS.PROJECT_SLUG} ./dist && sentry-cli sourcemaps upload --org ${TEST_ARGS.ORG_SLUG} --project ${TEST_ARGS.PROJECT_SLUG} ./dist\"`,\n `\"build\": \"ng build && yarn sentry:sourcemaps\"`,\n ]);\n });\n\n test('Sentry is correctly injected into Angular app config', () => {\n const appConfigFile = path.resolve(projectDir, 'src/main.ts');\n checkFileExists(appConfigFile);\n\n checkFileContents(appConfigFile, [\n `import * as Sentry from '@sentry/angular'`,\n 'Sentry.init({',\n TEST_ARGS.PROJECT_DSN,\n 'Sentry.browserTracingIntegration()',\n 'Sentry.replayIntegration()',\n 'tracesSampleRate: 1',\n 'replaysSessionSampleRate: 0.1',\n 'replaysOnErrorSampleRate: 1',\n ]);\n });\n\n test('Sentry is correctly injected into Angular app module', () => {\n const appModuleFile = path.resolve(projectDir, 'src/app/app.config.ts');\n checkFileExists(appModuleFile);\n\n // Checking if the ErrorHandler is already present in the providers array,\n // and if it is, we skip adding it\n if (options?.preExistingErrorHandler) {\n checkFileDoesNotContain(appModuleFile, 'Sentry.createErrorHandler()');\n }\n\n checkFileContents(appModuleFile, [\n `import * as Sentry from '@sentry/angular'`,\n options?.preExistingErrorHandler\n ? `provide: ErrorHandler,\n useValue: null`\n : `provide: ErrorHandler,\n useValue: Sentry.createErrorHandler()`,\n `provide: Sentry.TraceService,\n deps: [Router]`,\n `provideAppInitializer(() => {\n inject(Sentry.TraceService);\n })`,\n ]);\n });\n\n test('angular.json is updated correctly', async () => {\n const angularJsonFile = path.resolve(projectDir, 'angular.json');\n checkFileExists(angularJsonFile);\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const angularJson = (await import(angularJsonFile)) as Record<string, any>;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n for (const [, project] of Object.entries(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n angularJson.projects as Record<string, any>,\n )) {\n expect(\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n project?.architect?.build?.configurations?.production?.sourceMap,\n ).toBe(true);\n }\n });\n\n test('builds successfully', async () => {\n await checkIfBuilds(projectDir);\n });\n\n test('runs on prod mode correctly', async () => {\n await checkIfRunsOnProdMode(\n projectDir,\n 'Application bundle generation complete.',\n );\n });\n\n test('runs on dev mode correctly', async () => {\n await checkIfRunsOnDevMode(\n projectDir,\n 'Application bundle generation complete.',\n );\n });\n}\n"]}
|
|
@@ -43,7 +43,11 @@ const vitest_1 = require("vitest");
|
|
|
43
43
|
(await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER],
|
|
44
44
|
// "Do you want to enable Profiling", sometimes doesn't work as `Profiling` can be printed in bold.
|
|
45
45
|
'to analyze CPU usage and optimize performance-critical code on iOS & macOS?'));
|
|
46
|
-
profilingOptionPrompted &&
|
|
46
|
+
const replayOptionPrompted = profilingOptionPrompted &&
|
|
47
|
+
(await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER],
|
|
48
|
+
// "Do you want to enable Session Replay", sometimes doesn't work as `Session Replay` can be printed in bold.
|
|
49
|
+
'to record user interactions and debug issues?'));
|
|
50
|
+
replayOptionPrompted &&
|
|
47
51
|
(await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER], 'Successfully installed the Sentry Flutter SDK!'));
|
|
48
52
|
wizardInstance.kill();
|
|
49
53
|
});
|
|
@@ -88,7 +92,11 @@ const vitest_1 = require("vitest");
|
|
|
88
92
|
(await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER],
|
|
89
93
|
// "Do you want to enable Tracing", sometimes doesn't work as `Tracing` can be printed in bold.
|
|
90
94
|
'to track the performance of your application?'));
|
|
91
|
-
tracingOptionPrompted &&
|
|
95
|
+
const replayOptionPrompted = tracingOptionPrompted &&
|
|
96
|
+
(await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER],
|
|
97
|
+
// "Do you want to enable Session Replay", sometimes doesn't work as `Session Replay` can be printed in bold.
|
|
98
|
+
'to record user interactions and debug issues?'));
|
|
99
|
+
replayOptionPrompted &&
|
|
92
100
|
(await wizardInstance.sendStdinAndWaitForOutput([utils_1.KEYS.ENTER], 'Successfully installed the Sentry Flutter SDK!'));
|
|
93
101
|
wizardInstance.kill();
|
|
94
102
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flutter.test.js","sourceRoot":"","sources":["../../../e2e-tests/tests/flutter.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA,4CAA8B;AAC9B,gDAAkC;AAClC,mDAAkD;AAClD,oCAKkB;AAClB,oCAA+C;AAC/C,oCAKkB;AAClB,mCAAqE;AAErE,IAAA,iBAAQ,EAAC,SAAS,EAAE,GAAG,EAAE;IACvB,MAAM,WAAW,GAAG,uBAAW,CAAC,OAAO,CAAC;IACxC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAC7B,SAAS,EACT,uCAAuC,CACxC,CAAC;IAEF,IAAA,iBAAQ,EAAC,sBAAsB,EAAE,GAAG,EAAE;QACpC,IAAA,kBAAS,EAAC,KAAK,IAAI,EAAE;YACnB,MAAM,cAAc,GAAG,IAAA,2BAAmB,EAAC,WAAW,EAAE,UAAU,CAAC,CAAC;YAEpE,MAAM,qBAAqB,GAAG,MAAM,cAAc,CAAC,aAAa;YAC9D,+FAA+F;YAC/F,+CAA+C,CAChD,CAAC;YAEF,MAAM,uBAAuB,GAC3B,qBAAqB;gBACrB,CAAC,MAAM,cAAc,CAAC,yBAAyB,CAC7C,CAAC,YAAI,CAAC,KAAK,CAAC;gBACZ,mGAAmG;gBACnG,6EAA6E,CAC9E,CAAC,CAAC;YAEL,uBAAuB;
|
|
1
|
+
{"version":3,"file":"flutter.test.js","sourceRoot":"","sources":["../../../e2e-tests/tests/flutter.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA,4CAA8B;AAC9B,gDAAkC;AAClC,mDAAkD;AAClD,oCAKkB;AAClB,oCAA+C;AAC/C,oCAKkB;AAClB,mCAAqE;AAErE,IAAA,iBAAQ,EAAC,SAAS,EAAE,GAAG,EAAE;IACvB,MAAM,WAAW,GAAG,uBAAW,CAAC,OAAO,CAAC;IACxC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAC7B,SAAS,EACT,uCAAuC,CACxC,CAAC;IAEF,IAAA,iBAAQ,EAAC,sBAAsB,EAAE,GAAG,EAAE;QACpC,IAAA,kBAAS,EAAC,KAAK,IAAI,EAAE;YACnB,MAAM,cAAc,GAAG,IAAA,2BAAmB,EAAC,WAAW,EAAE,UAAU,CAAC,CAAC;YAEpE,MAAM,qBAAqB,GAAG,MAAM,cAAc,CAAC,aAAa;YAC9D,+FAA+F;YAC/F,+CAA+C,CAChD,CAAC;YAEF,MAAM,uBAAuB,GAC3B,qBAAqB;gBACrB,CAAC,MAAM,cAAc,CAAC,yBAAyB,CAC7C,CAAC,YAAI,CAAC,KAAK,CAAC;gBACZ,mGAAmG;gBACnG,6EAA6E,CAC9E,CAAC,CAAC;YAEL,MAAM,oBAAoB,GACxB,uBAAuB;gBACvB,CAAC,MAAM,cAAc,CAAC,yBAAyB,CAC7C,CAAC,YAAI,CAAC,KAAK,CAAC;gBACZ,6GAA6G;gBAC7G,+CAA+C,CAChD,CAAC,CAAC;YAEL,oBAAoB;gBAClB,CAAC,MAAM,cAAc,CAAC,yBAAyB,CAC7C,CAAC,YAAI,CAAC,KAAK,CAAC,EACZ,gDAAgD,CACjD,CAAC,CAAC;YAEL,cAAc,CAAC,IAAI,EAAE,CAAC;QACxB,CAAC,CAAC,CAAC;QAEH,IAAA,iBAAQ,EAAC,GAAG,EAAE;YACZ,IAAA,0BAAkB,EAAC,UAAU,CAAC,CAAC;YAC/B,IAAA,kBAAU,EAAC,UAAU,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;QAEH,IAAA,aAAI,EAAC,0BAA0B,EAAE,GAAG,EAAE;YACpC,IAAA,yBAAiB,EAAC,GAAG,UAAU,eAAe,EAAE,iBAAiB,CAAC,CAAC,CAAC,eAAe;YACnF,IAAA,yBAAiB,EAAC,GAAG,UAAU,eAAe,EAAE,qBAAqB,CAAC,CAAC,CAAC,mBAAmB;YAC3F,IAAA,yBAAiB,EAAC,GAAG,UAAU,eAAe,EAAE,SAAS,CAAC,CAAC,CAAC,wBAAwB;QACtF,CAAC,CAAC,CAAC;QAEH,IAAA,aAAI,EAAC,6CAA6C,EAAE,GAAG,EAAE;YACvD,IAAA,6BAAqB,EAAC,UAAU,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;QAEH,IAAA,aAAI,EAAC,kCAAkC,EAAE,GAAG,EAAE;YAC5C,IAAA,yBAAiB,EAAC,GAAG,UAAU,aAAa,EAAE,mBAAmB,CAAC,CAAC;QACrE,CAAC,CAAC,CAAC;QAEH,IAAA,aAAI,EAAC,iCAAiC,EAAE,GAAG,EAAE;YAC3C,IAAA,yBAAiB,EACf,GAAG,UAAU,gBAAgB,EAC7B,sDAAsD,CACvD,CAAC;YACF,IAAA,yBAAiB,EACf,GAAG,UAAU,gBAAgB,EAC7B,2BAA2B,CAC5B,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,IAAA,aAAI,EAAC,6CAA6C,EAAE,GAAG,EAAE;YACvD,IAAA,yBAAiB,EACf,GAAG,UAAU,gBAAgB,EAC7B,iCAAiC,CAClC,CAAC;YACF,IAAA,yBAAiB,EACf,GAAG,UAAU,gBAAgB,EAC7B,mCAAmC,CACpC,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,IAAA,aAAI,EAAC,kBAAkB,EAAE,KAAK,IAAI,EAAE;YAClC,MAAM,IAAA,4BAAoB,EAAC,UAAU,EAAE,mBAAmB,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAA,iBAAQ,EAAC,yBAAyB,EAAE,GAAG,EAAE;QACvC,IAAA,kBAAS,EAAC,KAAK,IAAI,EAAE;YACnB,MAAM,cAAc,GAAG,IAAA,2BAAmB,EAAC,WAAW,EAAE,UAAU,CAAC,CAAC;YAEpE,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,UAAU,MAAM,CAAC,EAAE;gBACtC,EAAE,CAAC,UAAU,CAAC,GAAG,UAAU,MAAM,EAAE,GAAG,UAAU,OAAO,CAAC,CAAC;aAC1D;YACD,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,UAAU,QAAQ,CAAC,EAAE;gBACxC,EAAE,CAAC,UAAU,CAAC,GAAG,UAAU,QAAQ,EAAE,GAAG,UAAU,SAAS,CAAC,CAAC;aAC9D;YAED,MAAM,gCAAgC,GACpC,MAAM,cAAc,CAAC,aAAa,CAAC,iCAAiC,CAAC,CAAC;YAExE,MAAM,qBAAqB,GACzB,gCAAgC;gBAChC,CAAC,MAAM,cAAc,CAAC,yBAAyB,CAC7C,CAAC,YAAI,CAAC,KAAK,CAAC;gBACZ,+FAA+F;gBAC/F,+CAA+C,CAChD,CAAC,CAAC;YAEL,MAAM,oBAAoB,GACxB,qBAAqB;gBACrB,CAAC,MAAM,cAAc,CAAC,yBAAyB,CAC7C,CAAC,YAAI,CAAC,KAAK,CAAC;gBACZ,6GAA6G;gBAC7G,+CAA+C,CAChD,CAAC,CAAC;YAEL,oBAAoB;gBAClB,CAAC,MAAM,cAAc,CAAC,yBAAyB,CAC7C,CAAC,YAAI,CAAC,KAAK,CAAC,EACZ,gDAAgD,CACjD,CAAC,CAAC;YAEL,cAAc,CAAC,IAAI,EAAE,CAAC;QACxB,CAAC,CAAC,CAAC;QAEH,IAAA,iBAAQ,EAAC,GAAG,EAAE;YACZ,IAAA,0BAAkB,EAAC,UAAU,CAAC,CAAC;YAC/B,IAAA,kBAAU,EAAC,UAAU,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;QAEH,IAAA,aAAI,EAAC,wEAAwE,EAAE,GAAG,EAAE;YAClF,MAAM,WAAW,GAAG,EAAE,CAAC,YAAY,CACjC,GAAG,UAAU,gBAAgB,EAC7B,OAAO,CACR,CAAC;YACF,IAAA,eAAM,EAAC,WAAW,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,mCAAmC,CAAC,CAAC;QACzE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { Integration } from '../../lib/Constants';\nimport {\n KEYS,\n // checkEnvBuildPlugin,\n cleanupGit,\n revertLocalChanges,\n} from '../utils';\nimport { startWizardInstance } from '../utils';\nimport {\n checkFileContents,\n checkIfFlutterBuilds,\n // checkFileExists,\n checkSentryProperties,\n} from '../utils';\nimport { afterAll, beforeAll, describe, expect, test } from 'vitest';\n\ndescribe('Flutter', () => {\n const integration = Integration.flutter;\n const projectDir = path.resolve(\n __dirname,\n '../test-applications/flutter-test-app',\n );\n\n describe('with apple platforms', () => {\n beforeAll(async () => {\n const wizardInstance = startWizardInstance(integration, projectDir);\n\n const tracingOptionPrompted = await wizardInstance.waitForOutput(\n // \"Do you want to enable Tracing\", sometimes doesn't work as `Tracing` can be printed in bold.\n 'to track the performance of your application?',\n );\n\n const profilingOptionPrompted =\n tracingOptionPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n // \"Do you want to enable Profiling\", sometimes doesn't work as `Profiling` can be printed in bold.\n 'to analyze CPU usage and optimize performance-critical code on iOS & macOS?',\n ));\n\n const replayOptionPrompted =\n profilingOptionPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n // \"Do you want to enable Session Replay\", sometimes doesn't work as `Session Replay` can be printed in bold.\n 'to record user interactions and debug issues?',\n ));\n\n replayOptionPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n 'Successfully installed the Sentry Flutter SDK!',\n ));\n\n wizardInstance.kill();\n });\n\n afterAll(() => {\n revertLocalChanges(projectDir);\n cleanupGit(projectDir);\n });\n\n test('pubspec.yaml is updated.', () => {\n checkFileContents(`${projectDir}/pubspec.yaml`, `sentry_flutter:`); // dependencies\n checkFileContents(`${projectDir}/pubspec.yaml`, `sentry_dart_plugin:`); // dev_dependencies\n checkFileContents(`${projectDir}/pubspec.yaml`, `sentry:`); // gradle plugin options\n });\n\n test('sentry.properties exists and has auth token', () => {\n checkSentryProperties(projectDir);\n });\n\n test('.gitignore has sentry.properties', () => {\n checkFileContents(`${projectDir}/.gitignore`, `sentry.properties`);\n });\n\n test('lib/main.dart calls sentry init', () => {\n checkFileContents(\n `${projectDir}/lib/main.dart`,\n `import 'package:sentry_flutter/sentry_flutter.dart';`,\n );\n checkFileContents(\n `${projectDir}/lib/main.dart`,\n `await SentryFlutter.init(`,\n );\n });\n\n test('lib/main.dart enables tracing and profiling', () => {\n checkFileContents(\n `${projectDir}/lib/main.dart`,\n `options.tracesSampleRate = 1.0;`,\n );\n checkFileContents(\n `${projectDir}/lib/main.dart`,\n `options.profilesSampleRate = 1.0;`,\n );\n });\n\n test('builds correctly', async () => {\n await checkIfFlutterBuilds(projectDir, '✓ Built build/web');\n });\n });\n\n describe('without apple platforms', () => {\n beforeAll(async () => {\n const wizardInstance = startWizardInstance(integration, projectDir);\n\n if (fs.existsSync(`${projectDir}/ios`)) {\n fs.renameSync(`${projectDir}/ios`, `${projectDir}/_ios`);\n }\n if (fs.existsSync(`${projectDir}/macos`)) {\n fs.renameSync(`${projectDir}/macos`, `${projectDir}/_macos`);\n }\n\n const continueOnUncommitedFilesPromted =\n await wizardInstance.waitForOutput('Do you want to continue anyway?');\n\n const tracingOptionPrompted =\n continueOnUncommitedFilesPromted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n // \"Do you want to enable Tracing\", sometimes doesn't work as `Tracing` can be printed in bold.\n 'to track the performance of your application?',\n ));\n\n const replayOptionPrompted =\n tracingOptionPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n // \"Do you want to enable Session Replay\", sometimes doesn't work as `Session Replay` can be printed in bold.\n 'to record user interactions and debug issues?',\n ));\n\n replayOptionPrompted &&\n (await wizardInstance.sendStdinAndWaitForOutput(\n [KEYS.ENTER],\n 'Successfully installed the Sentry Flutter SDK!',\n ));\n\n wizardInstance.kill();\n });\n\n afterAll(() => {\n revertLocalChanges(projectDir);\n cleanupGit(projectDir);\n });\n\n test('lib/main.dart does not add profiling with missing ios and macos folder', () => {\n const fileContent = fs.readFileSync(\n `${projectDir}/lib/main.dart`,\n 'utf-8',\n );\n expect(fileContent).not.toContain(`options.profilesSampleRate = 1.0;`);\n });\n });\n});\n"]}
|
|
@@ -11,6 +11,7 @@ export declare function patchMain(mainFile: string | null, dsn: string, canEnabl
|
|
|
11
11
|
export declare function patchMainContent(dsn: string, mainContent: string, selectedFeatures: {
|
|
12
12
|
tracing: boolean;
|
|
13
13
|
profiling: boolean;
|
|
14
|
+
replay: boolean;
|
|
14
15
|
}): string;
|
|
15
16
|
export declare function getLastImportLineLocation(sourceCode: string): number;
|
|
16
17
|
export declare function getDependenciesLocation(sourceCode: string): number;
|
|
@@ -156,12 +156,22 @@ async function patchMain(mainFile, dsn, canEnableProfiling) {
|
|
|
156
156
|
enabledHint: 'recommended, tracing must be enabled',
|
|
157
157
|
});
|
|
158
158
|
}
|
|
159
|
+
features.push({
|
|
160
|
+
id: 'replay',
|
|
161
|
+
prompt: `Do you want to enable ${chalk_1.default.bold('Session Replay')} to record user interactions and debug issues?`,
|
|
162
|
+
enabledHint: 'recommended',
|
|
163
|
+
});
|
|
159
164
|
const selectedFeatures = await (0, clack_1.featureSelectionPrompt)(features);
|
|
160
165
|
const normalizedSelectedFeatures = {
|
|
161
166
|
tracing: selectedFeatures.tracing ?? false,
|
|
162
167
|
profiling: selectedFeatures.profiling ?? false,
|
|
168
|
+
replay: selectedFeatures.replay ?? false,
|
|
163
169
|
};
|
|
164
170
|
mainContent = patchMainContent(dsn, mainContent, normalizedSelectedFeatures);
|
|
171
|
+
if (normalizedSelectedFeatures.replay) {
|
|
172
|
+
clack.log.info(`Session Replay will be enabled with default settings (replaysSessionSampleRate: ${templates_1.sessionReplaySampleRate}, replaysOnErrorSampleRate: ${templates_1.sessionReplayOnErrorSampleRate}).`);
|
|
173
|
+
clack.log.message('By default, all text content, images, and webviews will be masked for privacy. You can customize this in your code later.');
|
|
174
|
+
}
|
|
165
175
|
fs.writeFileSync(mainFile, mainContent, 'utf8');
|
|
166
176
|
clack.log.success(chalk_1.default.greenBright(`Patched ${chalk_1.default.bold('main.dart')} with the Sentry setup and test error snippet.`));
|
|
167
177
|
return true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code-tools.js","sourceRoot":"","sources":["../../../src/flutter/code-tools.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\nimport * as Sentry from '@sentry/node';\n// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport * as clack from '@clack/prompts';\nimport chalk from 'chalk';\nimport {\n sentryImport,\n pubspecOptions,\n sentryProperties,\n initSnippet,\n} from './templates';\nimport { featureSelectionPrompt } from '../utils/clack';\n\n/**\n * Recursively finds a file per name in subfolders.\n * @param dir - The directory to start searching.\n * @param name - The name of the file including path extension.\n * @returns The path to the main.dart file or null if not found.\n */\nexport function findFile(dir: string, name: string): string | null {\n const files: string[] = fs.readdirSync(dir);\n\n for (const file of files) {\n const fullPath: string = path.join(dir, file);\n const stats: fs.Stats = fs.statSync(fullPath);\n\n if (stats.isDirectory()) {\n const result: string | null = findFile(fullPath, name);\n if (result) {\n return result;\n }\n } else if (file === name) {\n return fullPath;\n }\n }\n\n return null;\n}\n\nexport function patchPubspec(\n pubspecFile: string | null,\n sentryDartFlutterVersion: string,\n sentryDartPluginVersion: string,\n project: string,\n org: string,\n): boolean {\n try {\n if (!pubspecFile) {\n throw new Error('pubspec.yaml is not provided or invalid.');\n }\n\n let pubspecContent = fs.readFileSync(pubspecFile, 'utf8');\n\n if (!pubspecContent.includes('sentry_flutter:')) {\n const dependenciesIndex = getDependenciesLocation(pubspecContent);\n\n pubspecContent =\n pubspecContent.slice(0, dependenciesIndex) +\n ` sentry_flutter: ${sentryDartFlutterVersion}\\n` +\n pubspecContent.slice(dependenciesIndex);\n\n clack.log.success(\n chalk.greenBright(\n `${chalk.bold('sentry_flutter')} added to pubspec.yaml`,\n ),\n );\n } else {\n clack.log.success(\n chalk.greenBright(\n `${chalk.bold('sentry_flutter')} is already included in pubspec.yaml`,\n ),\n );\n }\n\n if (!pubspecContent.includes('sentry_dart_plugin:')) {\n const devDependenciesIndex = getDevDependenciesLocation(pubspecContent);\n pubspecContent =\n pubspecContent.slice(0, devDependenciesIndex) +\n ` sentry_dart_plugin: ${sentryDartPluginVersion}\\n` +\n pubspecContent.slice(devDependenciesIndex);\n\n clack.log.success(\n chalk.greenBright(\n `${chalk.bold('sentry_dart_plugin')} added to pubspec.yaml`,\n ),\n );\n } else {\n clack.log.success(\n chalk.greenBright(\n `${chalk.bold(\n 'sentry_dart_plugin',\n )} is already included in pubspec.yaml`,\n ),\n );\n }\n\n if (!pubspecContent.includes('sentry:')) {\n pubspecContent += '\\n';\n pubspecContent += pubspecOptions(project, org);\n\n clack.log.success(\n chalk.greenBright(\n `${chalk.bold('sentry plugin configuration')} added to pubspec.yaml`,\n ),\n );\n } else {\n clack.log.success(\n chalk.greenBright(\n `${chalk.bold(\n 'sentry plugin configuration',\n )} is already included in pubspec.yaml`,\n ),\n );\n }\n\n fs.writeFileSync(pubspecFile, pubspecContent, 'utf8');\n\n return true;\n } catch (error) {\n clack.log.warn(`Failed to read/write ${chalk.cyan('pubspec.yaml')} file.`);\n Sentry.captureException(error);\n return false;\n }\n}\n\nexport function addProperties(pubspecFile: string | null, authToken: string) {\n try {\n if (!pubspecFile) {\n throw new Error('pubspec.yaml is not provided or invalid.');\n }\n\n const pubspecDir = path.dirname(pubspecFile);\n const sentryPropertiesFileName = 'sentry.properties';\n const sentryPropertiesFile = path.join(\n pubspecDir,\n sentryPropertiesFileName,\n );\n const sentryPropertiesContent = sentryProperties(authToken);\n\n fs.writeFileSync(sentryPropertiesFile, sentryPropertiesContent, 'utf8');\n\n const gitignoreFile = path.join(pubspecDir, '.gitignore');\n if (fs.existsSync(gitignoreFile)) {\n fs.appendFileSync(gitignoreFile, `\\n${sentryPropertiesFileName}\\n`);\n } else {\n fs.writeFileSync(gitignoreFile, `${sentryPropertiesFileName}\\n`, 'utf8');\n }\n return true;\n } catch (error) {\n clack.log.warn(`Failed to read/write ${chalk.cyan('pubspec.yaml')} file.`);\n Sentry.captureException(error);\n return false;\n }\n}\n\nexport async function patchMain(\n mainFile: string | null,\n dsn: string,\n canEnableProfiling: boolean,\n): Promise<boolean> {\n try {\n if (!mainFile) {\n throw new Error('pubspec.yaml is not provided or invalid.');\n }\n\n let mainContent = fs.readFileSync(mainFile, 'utf8');\n if (\n /import\\s+['\"]package[:]sentry_flutter\\/sentry_flutter\\.dart['\"];?/i.test(\n mainContent,\n )\n ) {\n // sentry is already configured\n clack.log.success(\n chalk.greenBright(\n `${chalk.bold('main.dart')} already has Sentry configured.`,\n ),\n );\n return true;\n }\n\n const features = [\n {\n id: 'tracing',\n prompt: `Do you want to enable ${chalk.bold(\n 'Tracing',\n )} to track the performance of your application?`,\n enabledHint: 'recommended',\n },\n ];\n if (canEnableProfiling) {\n features.push({\n id: 'profiling',\n prompt: `Do you want to enable ${chalk.bold(\n 'Profiling',\n )} to analyze CPU usage and optimize performance-critical code on iOS & macOS?`,\n enabledHint: 'recommended, tracing must be enabled',\n });\n }\n\n const selectedFeatures = await featureSelectionPrompt(features);\n const normalizedSelectedFeatures = {\n tracing: selectedFeatures.tracing ?? false,\n profiling: selectedFeatures.profiling ?? false,\n };\n mainContent = patchMainContent(\n dsn,\n mainContent,\n normalizedSelectedFeatures,\n );\n\n fs.writeFileSync(mainFile, mainContent, 'utf8');\n\n clack.log.success(\n chalk.greenBright(\n `Patched ${chalk.bold(\n 'main.dart',\n )} with the Sentry setup and test error snippet.`,\n ),\n );\n\n return true;\n } catch (error) {\n clack.log.warn(`Failed to read/write ${chalk.cyan('main.dart')} file.`);\n Sentry.captureException(error);\n return false;\n }\n}\n\nexport function patchMainContent(\n dsn: string,\n mainContent: string,\n selectedFeatures: {\n tracing: boolean;\n profiling: boolean;\n },\n): string {\n const importIndex = getLastImportLineLocation(mainContent);\n mainContent =\n mainContent.slice(0, importIndex) +\n sentryImport +\n mainContent.slice(importIndex);\n\n // Find and replace `runApp(...)`\n mainContent = mainContent.replace(\n /runApp\\(([\\s\\S]*?)\\);/g, // Match the `runApp(...)` invocation\n (_, runAppArgs) => initSnippet(dsn, selectedFeatures, runAppArgs as string),\n );\n\n // Make the `main` function async if it's not already\n mainContent = mainContent.replace(\n /void\\s+main\\(\\)\\s*\\{/g,\n 'Future<void> main() async {',\n );\n\n return mainContent;\n}\n\nexport function getLastImportLineLocation(sourceCode: string): number {\n const importRegex = /import\\s+['\"].*['\"].*;/gim;\n return getLastReqExpLocation(sourceCode, importRegex);\n}\n\nexport function getDependenciesLocation(sourceCode: string): number {\n const dependencyRegex = /^dependencies:\\s*$/gim;\n return getLastReqExpLocation(sourceCode, dependencyRegex);\n}\n\nexport function getDevDependenciesLocation(sourceCode: string): number {\n const dependencyRegex = /^dev_dependencies:\\s*$/gim;\n return getLastReqExpLocation(sourceCode, dependencyRegex);\n}\n\n// Helper\n\nfunction getLastReqExpLocation(sourceCode: string, regExp: RegExp): number {\n let match = regExp.exec(sourceCode);\n let importIndex = 0;\n while (match) {\n importIndex = match.index + match[0].length + 1;\n match = regExp.exec(sourceCode);\n }\n return importIndex;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"code-tools.js","sourceRoot":"","sources":["../../../src/flutter/code-tools.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\nimport * as Sentry from '@sentry/node';\n// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport * as clack from '@clack/prompts';\nimport chalk from 'chalk';\nimport {\n sentryImport,\n pubspecOptions,\n sentryProperties,\n initSnippet,\n sessionReplaySampleRate,\n sessionReplayOnErrorSampleRate,\n} from './templates';\nimport { featureSelectionPrompt } from '../utils/clack';\n\n/**\n * Recursively finds a file per name in subfolders.\n * @param dir - The directory to start searching.\n * @param name - The name of the file including path extension.\n * @returns The path to the main.dart file or null if not found.\n */\nexport function findFile(dir: string, name: string): string | null {\n const files: string[] = fs.readdirSync(dir);\n\n for (const file of files) {\n const fullPath: string = path.join(dir, file);\n const stats: fs.Stats = fs.statSync(fullPath);\n\n if (stats.isDirectory()) {\n const result: string | null = findFile(fullPath, name);\n if (result) {\n return result;\n }\n } else if (file === name) {\n return fullPath;\n }\n }\n\n return null;\n}\n\nexport function patchPubspec(\n pubspecFile: string | null,\n sentryDartFlutterVersion: string,\n sentryDartPluginVersion: string,\n project: string,\n org: string,\n): boolean {\n try {\n if (!pubspecFile) {\n throw new Error('pubspec.yaml is not provided or invalid.');\n }\n\n let pubspecContent = fs.readFileSync(pubspecFile, 'utf8');\n\n if (!pubspecContent.includes('sentry_flutter:')) {\n const dependenciesIndex = getDependenciesLocation(pubspecContent);\n\n pubspecContent =\n pubspecContent.slice(0, dependenciesIndex) +\n ` sentry_flutter: ${sentryDartFlutterVersion}\\n` +\n pubspecContent.slice(dependenciesIndex);\n\n clack.log.success(\n chalk.greenBright(\n `${chalk.bold('sentry_flutter')} added to pubspec.yaml`,\n ),\n );\n } else {\n clack.log.success(\n chalk.greenBright(\n `${chalk.bold('sentry_flutter')} is already included in pubspec.yaml`,\n ),\n );\n }\n\n if (!pubspecContent.includes('sentry_dart_plugin:')) {\n const devDependenciesIndex = getDevDependenciesLocation(pubspecContent);\n pubspecContent =\n pubspecContent.slice(0, devDependenciesIndex) +\n ` sentry_dart_plugin: ${sentryDartPluginVersion}\\n` +\n pubspecContent.slice(devDependenciesIndex);\n\n clack.log.success(\n chalk.greenBright(\n `${chalk.bold('sentry_dart_plugin')} added to pubspec.yaml`,\n ),\n );\n } else {\n clack.log.success(\n chalk.greenBright(\n `${chalk.bold(\n 'sentry_dart_plugin',\n )} is already included in pubspec.yaml`,\n ),\n );\n }\n\n if (!pubspecContent.includes('sentry:')) {\n pubspecContent += '\\n';\n pubspecContent += pubspecOptions(project, org);\n\n clack.log.success(\n chalk.greenBright(\n `${chalk.bold('sentry plugin configuration')} added to pubspec.yaml`,\n ),\n );\n } else {\n clack.log.success(\n chalk.greenBright(\n `${chalk.bold(\n 'sentry plugin configuration',\n )} is already included in pubspec.yaml`,\n ),\n );\n }\n\n fs.writeFileSync(pubspecFile, pubspecContent, 'utf8');\n\n return true;\n } catch (error) {\n clack.log.warn(`Failed to read/write ${chalk.cyan('pubspec.yaml')} file.`);\n Sentry.captureException(error);\n return false;\n }\n}\n\nexport function addProperties(pubspecFile: string | null, authToken: string) {\n try {\n if (!pubspecFile) {\n throw new Error('pubspec.yaml is not provided or invalid.');\n }\n\n const pubspecDir = path.dirname(pubspecFile);\n const sentryPropertiesFileName = 'sentry.properties';\n const sentryPropertiesFile = path.join(\n pubspecDir,\n sentryPropertiesFileName,\n );\n const sentryPropertiesContent = sentryProperties(authToken);\n\n fs.writeFileSync(sentryPropertiesFile, sentryPropertiesContent, 'utf8');\n\n const gitignoreFile = path.join(pubspecDir, '.gitignore');\n if (fs.existsSync(gitignoreFile)) {\n fs.appendFileSync(gitignoreFile, `\\n${sentryPropertiesFileName}\\n`);\n } else {\n fs.writeFileSync(gitignoreFile, `${sentryPropertiesFileName}\\n`, 'utf8');\n }\n return true;\n } catch (error) {\n clack.log.warn(`Failed to read/write ${chalk.cyan('pubspec.yaml')} file.`);\n Sentry.captureException(error);\n return false;\n }\n}\n\nexport async function patchMain(\n mainFile: string | null,\n dsn: string,\n canEnableProfiling: boolean,\n): Promise<boolean> {\n try {\n if (!mainFile) {\n throw new Error('pubspec.yaml is not provided or invalid.');\n }\n\n let mainContent = fs.readFileSync(mainFile, 'utf8');\n if (\n /import\\s+['\"]package[:]sentry_flutter\\/sentry_flutter\\.dart['\"];?/i.test(\n mainContent,\n )\n ) {\n // sentry is already configured\n clack.log.success(\n chalk.greenBright(\n `${chalk.bold('main.dart')} already has Sentry configured.`,\n ),\n );\n return true;\n }\n\n const features = [\n {\n id: 'tracing',\n prompt: `Do you want to enable ${chalk.bold(\n 'Tracing',\n )} to track the performance of your application?`,\n enabledHint: 'recommended',\n },\n ];\n if (canEnableProfiling) {\n features.push({\n id: 'profiling',\n prompt: `Do you want to enable ${chalk.bold(\n 'Profiling',\n )} to analyze CPU usage and optimize performance-critical code on iOS & macOS?`,\n enabledHint: 'recommended, tracing must be enabled',\n });\n }\n features.push({\n id: 'replay',\n prompt: `Do you want to enable ${chalk.bold(\n 'Session Replay',\n )} to record user interactions and debug issues?`,\n enabledHint: 'recommended',\n });\n\n const selectedFeatures = await featureSelectionPrompt(features);\n const normalizedSelectedFeatures = {\n tracing: selectedFeatures.tracing ?? false,\n profiling: selectedFeatures.profiling ?? false,\n replay: selectedFeatures.replay ?? false,\n };\n mainContent = patchMainContent(\n dsn,\n mainContent,\n normalizedSelectedFeatures,\n );\n\n if (normalizedSelectedFeatures.replay) {\n clack.log.info(\n `Session Replay will be enabled with default settings (replaysSessionSampleRate: ${sessionReplaySampleRate}, replaysOnErrorSampleRate: ${sessionReplayOnErrorSampleRate}).`,\n );\n clack.log.message(\n 'By default, all text content, images, and webviews will be masked for privacy. You can customize this in your code later.',\n );\n }\n\n fs.writeFileSync(mainFile, mainContent, 'utf8');\n\n clack.log.success(\n chalk.greenBright(\n `Patched ${chalk.bold(\n 'main.dart',\n )} with the Sentry setup and test error snippet.`,\n ),\n );\n\n return true;\n } catch (error) {\n clack.log.warn(`Failed to read/write ${chalk.cyan('main.dart')} file.`);\n Sentry.captureException(error);\n return false;\n }\n}\n\nexport function patchMainContent(\n dsn: string,\n mainContent: string,\n selectedFeatures: {\n tracing: boolean;\n profiling: boolean;\n replay: boolean;\n },\n): string {\n const importIndex = getLastImportLineLocation(mainContent);\n mainContent =\n mainContent.slice(0, importIndex) +\n sentryImport +\n mainContent.slice(importIndex);\n\n // Find and replace `runApp(...)`\n mainContent = mainContent.replace(\n /runApp\\(([\\s\\S]*?)\\);/g, // Match the `runApp(...)` invocation\n (_, runAppArgs) => initSnippet(dsn, selectedFeatures, runAppArgs as string),\n );\n\n // Make the `main` function async if it's not already\n mainContent = mainContent.replace(\n /void\\s+main\\(\\)\\s*\\{/g,\n 'Future<void> main() async {',\n );\n\n return mainContent;\n}\n\nexport function getLastImportLineLocation(sourceCode: string): number {\n const importRegex = /import\\s+['\"].*['\"].*;/gim;\n return getLastReqExpLocation(sourceCode, importRegex);\n}\n\nexport function getDependenciesLocation(sourceCode: string): number {\n const dependencyRegex = /^dependencies:\\s*$/gim;\n return getLastReqExpLocation(sourceCode, dependencyRegex);\n}\n\nexport function getDevDependenciesLocation(sourceCode: string): number {\n const dependencyRegex = /^dev_dependencies:\\s*$/gim;\n return getLastReqExpLocation(sourceCode, dependencyRegex);\n}\n\n// Helper\n\nfunction getLastReqExpLocation(sourceCode: string, regExp: RegExp): number {\n let match = regExp.exec(sourceCode);\n let importIndex = 0;\n while (match) {\n importIndex = match.index + match[0].length + 1;\n match = regExp.exec(sourceCode);\n }\n return importIndex;\n}\n"]}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
export declare const sentryImport = "import 'package:sentry_flutter/sentry_flutter.dart';\n";
|
|
2
|
+
export declare const sessionReplaySampleRate = 0.1;
|
|
3
|
+
export declare const sessionReplayOnErrorSampleRate = 1;
|
|
2
4
|
export declare function pubspecOptions(project: string, org: string): string;
|
|
3
5
|
export declare function sentryProperties(authToken: string): string;
|
|
4
6
|
export declare function initSnippet(dsn: string, selectedFeaturesMap: {
|
|
5
7
|
tracing: boolean;
|
|
6
8
|
profiling: boolean;
|
|
9
|
+
replay: boolean;
|
|
7
10
|
}, runApp: string): string;
|
|
8
11
|
export declare function pubspecSnippetColored(sentryVersion: string, pluginVersion: string, project: string, org: string): string;
|
|
9
12
|
export declare function initSnippetColored(dsn: string): string;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.initSnippetColored = exports.pubspecSnippetColored = exports.initSnippet = exports.sentryProperties = exports.pubspecOptions = exports.sentryImport = void 0;
|
|
3
|
+
exports.initSnippetColored = exports.pubspecSnippetColored = exports.initSnippet = exports.sentryProperties = exports.pubspecOptions = exports.sessionReplayOnErrorSampleRate = exports.sessionReplaySampleRate = exports.sentryImport = void 0;
|
|
4
4
|
const clack_1 = require("../utils/clack");
|
|
5
5
|
exports.sentryImport = `import 'package:sentry_flutter/sentry_flutter.dart';\n`;
|
|
6
|
+
exports.sessionReplaySampleRate = 0.1;
|
|
7
|
+
exports.sessionReplayOnErrorSampleRate = 1.0;
|
|
6
8
|
function pubspecOptions(project, org) {
|
|
7
9
|
return `sentry:
|
|
8
10
|
upload_debug_symbols: true
|
|
@@ -35,6 +37,16 @@ function initSnippet(dsn, selectedFeaturesMap, runApp) {
|
|
|
35
37
|
// Setting to 1.0 will profile 100% of sampled transactions:
|
|
36
38
|
options.profilesSampleRate = 1.0;`;
|
|
37
39
|
}
|
|
40
|
+
if (selectedFeaturesMap.replay) {
|
|
41
|
+
snippet += `
|
|
42
|
+
// Configure Session Replay
|
|
43
|
+
options.replay.sessionSampleRate = ${exports.sessionReplaySampleRate % 1 === 0
|
|
44
|
+
? `${exports.sessionReplaySampleRate}.0`
|
|
45
|
+
: exports.sessionReplaySampleRate};
|
|
46
|
+
options.replay.onErrorSampleRate = ${exports.sessionReplayOnErrorSampleRate % 1 === 0
|
|
47
|
+
? `${exports.sessionReplayOnErrorSampleRate}.0`
|
|
48
|
+
: exports.sessionReplayOnErrorSampleRate};`;
|
|
49
|
+
}
|
|
38
50
|
snippet += `
|
|
39
51
|
},
|
|
40
52
|
appRunner: () => runApp(SentryWidget(child: ${runApp})),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/flutter/templates.ts"],"names":[],"mappings":";;;AAAA,0CAAiD;AAEpC,QAAA,YAAY,GAAG,wDAAwD,CAAC;
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/flutter/templates.ts"],"names":[],"mappings":";;;AAAA,0CAAiD;AAEpC,QAAA,YAAY,GAAG,wDAAwD,CAAC;AACxE,QAAA,uBAAuB,GAAG,GAAG,CAAC;AAC9B,QAAA,8BAA8B,GAAG,GAAG,CAAC;AAElD,SAAgB,cAAc,CAAC,OAAe,EAAE,GAAW;IACzD,OAAO;;;aAGI,OAAO;SACX,GAAG;CACX,CAAC;AACF,CAAC;AAPD,wCAOC;AAED,SAAgB,gBAAgB,CAAC,SAAiB;IAChD,OAAO,cAAc,SAAS,EAAE,CAAC;AACnC,CAAC;AAFD,4CAEC;AAED,SAAgB,WAAW,CACzB,GAAW,EACX,mBAIC,EACD,MAAc;IAEd,IAAI,OAAO,GAAG;;uBAEO,GAAG;;;qCAGW,CAAC;IAEpC,IAAI,mBAAmB,CAAC,OAAO,EAAE;QAC/B,OAAO,IAAI;;;sCAGuB,CAAC;KACpC;IAED,IAAI,mBAAmB,CAAC,SAAS,IAAI,mBAAmB,CAAC,OAAO,EAAE;QAChE,OAAO,IAAI;;;wCAGyB,CAAC;KACtC;IAED,IAAI,mBAAmB,CAAC,MAAM,EAAE;QAC9B,OAAO,IAAI;;2CAGP,+BAAuB,GAAG,CAAC,KAAK,CAAC;YAC/B,CAAC,CAAC,GAAG,+BAAuB,IAAI;YAChC,CAAC,CAAC,+BACN;2CAEE,sCAA8B,GAAG,CAAC,KAAK,CAAC;YACtC,CAAC,CAAC,GAAG,sCAA8B,IAAI;YACvC,CAAC,CAAC,sCACN,GAAG,CAAC;KACP;IAED,OAAO,IAAI;;kDAEqC,MAAM;;;4EAGoB,CAAC;IAE3E,OAAO,OAAO,CAAC;AACjB,CAAC;AArDD,kCAqDC;AAED,SAAgB,qBAAqB,CACnC,aAAqB,EACrB,aAAqB,EACrB,OAAe,EACf,GAAW;IAEX,MAAM,OAAO,GAAG;oBACE,aAAa;;;wBAGT,aAAa;;EAEnC,cAAc,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC;IAE/B,OAAO,IAAA,uBAAe,EAAC,IAAI,EAAE,CAAC,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE;QACxD,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;AACL,CAAC;AAjBD,sDAiBC;AAED,SAAgB,kBAAkB,CAAC,GAAW;IAC5C,MAAM,OAAO,GAAG;;;;;uBAKK,GAAG;;;;;;;;;;EAUxB,CAAC;IACD,OAAO,IAAA,uBAAe,EAAC,IAAI,EAAE,CAAC,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE;QACxD,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;AACL,CAAC;AApBD,gDAoBC","sourcesContent":["import { makeCodeSnippet } from '../utils/clack';\n\nexport const sentryImport = `import 'package:sentry_flutter/sentry_flutter.dart';\\n`;\nexport const sessionReplaySampleRate = 0.1;\nexport const sessionReplayOnErrorSampleRate = 1.0;\n\nexport function pubspecOptions(project: string, org: string): string {\n return `sentry:\n upload_debug_symbols: true\n upload_source_maps: true\n project: ${project}\n org: ${org}\n`;\n}\n\nexport function sentryProperties(authToken: string): string {\n return `auth_token=${authToken}`;\n}\n\nexport function initSnippet(\n dsn: string,\n selectedFeaturesMap: {\n tracing: boolean;\n profiling: boolean;\n replay: boolean;\n },\n runApp: string,\n): string {\n let snippet = `await SentryFlutter.init(\n (options) {\n options.dsn = '${dsn}';\n // Adds request headers and IP for users, for more info visit:\n // https://docs.sentry.io/platforms/dart/guides/flutter/data-management/data-collected/\n options.sendDefaultPii = true;`;\n\n if (selectedFeaturesMap.tracing) {\n snippet += `\n // Set tracesSampleRate to 1.0 to capture 100% of transactions for tracing.\n // We recommend adjusting this value in production.\n options.tracesSampleRate = 1.0;`;\n }\n\n if (selectedFeaturesMap.profiling && selectedFeaturesMap.tracing) {\n snippet += `\n // The sampling rate for profiling is relative to tracesSampleRate\n // Setting to 1.0 will profile 100% of sampled transactions:\n options.profilesSampleRate = 1.0;`;\n }\n\n if (selectedFeaturesMap.replay) {\n snippet += `\n // Configure Session Replay\n options.replay.sessionSampleRate = ${\n sessionReplaySampleRate % 1 === 0\n ? `${sessionReplaySampleRate}.0`\n : sessionReplaySampleRate\n };\n options.replay.onErrorSampleRate = ${\n sessionReplayOnErrorSampleRate % 1 === 0\n ? `${sessionReplayOnErrorSampleRate}.0`\n : sessionReplayOnErrorSampleRate\n };`;\n }\n\n snippet += `\n },\n appRunner: () => runApp(SentryWidget(child: ${runApp})),\n );\n // TODO: Remove this line after sending the first sample event to sentry.\n await Sentry.captureException(StateError('This is a sample exception.'));`;\n\n return snippet;\n}\n\nexport function pubspecSnippetColored(\n sentryVersion: string,\n pluginVersion: string,\n project: string,\n org: string,\n): string {\n const snippet = `dependencies:\n sentry_flutter: ${sentryVersion}\n\ndev_dependencies:\n sentry_dart_plugin: ${pluginVersion}\n \n${pubspecOptions(project, org)}`;\n\n return makeCodeSnippet(true, (_unchanged, plus, _minus) => {\n return plus(snippet);\n });\n}\n\nexport function initSnippetColored(dsn: string): string {\n const snippet = `import 'package:sentry_flutter/sentry_flutter.dart';\n\nFuture<void>main() async {\n await SentryFlutter.init(\n (options) {\n options.dsn = '${dsn}';\n // Adds request headers and IP for users, for more info visit:\n // https://docs.sentry.io/platforms/dart/guides/flutter/data-management/data-collected/\n options.sendDefaultPii = true;\n // Set tracesSampleRate to 1.0 to capture 100% of transactions for tracing.\n // We recommend adjusting this value in production.\n options.tracesSampleRate = 1.0;\n },\n appRunner: () => runApp(SentryWidget(child: YourApp())),\n )\n}`;\n return makeCodeSnippet(true, (_unchanged, plus, _minus) => {\n return plus(snippet);\n });\n}\n"]}
|
|
@@ -32,7 +32,6 @@ const clack = __importStar(require("@clack/prompts"));
|
|
|
32
32
|
const chalk_1 = __importDefault(require("chalk"));
|
|
33
33
|
const fs = __importStar(require("fs"));
|
|
34
34
|
const os_1 = require("os");
|
|
35
|
-
const utils_1 = require("@sentry/utils");
|
|
36
35
|
const Sentry = __importStar(require("@sentry/node"));
|
|
37
36
|
const clack_1 = require("../utils/clack");
|
|
38
37
|
const telemetry_1 = require("../telemetry");
|
|
@@ -99,7 +98,7 @@ function addWithSentryToAppConfigJson(appConfigContent, options) {
|
|
|
99
98
|
return null;
|
|
100
99
|
}
|
|
101
100
|
if (parsedAppConfig.expo !== undefined &&
|
|
102
|
-
!
|
|
101
|
+
!isPlainObject(parsedAppConfig.expo)) {
|
|
103
102
|
Sentry.setTag('app-config-file-status', 'invalid-json');
|
|
104
103
|
clack.log.error(`Unable to find expo in your ${chalk_1.default.cyan('app.config.json')}. Make sure it has a valid format!`);
|
|
105
104
|
return null;
|
|
@@ -149,4 +148,11 @@ function getSentryAppConfigJsonCodeSnippet({ url, project, org, }) {
|
|
|
149
148
|
});
|
|
150
149
|
}
|
|
151
150
|
exports.getSentryAppConfigJsonCodeSnippet = getSentryAppConfigJsonCodeSnippet;
|
|
151
|
+
/**
|
|
152
|
+
* Checks whether the given value is a plain object (as opposed to something like a class instance or a primitive).
|
|
153
|
+
* vendored from @sentry/utils to avoid registering the dependency.
|
|
154
|
+
*/
|
|
155
|
+
function isPlainObject(what) {
|
|
156
|
+
return Object.prototype.toString.call(what) === '[object Object]';
|
|
157
|
+
}
|
|
152
158
|
//# sourceMappingURL=expo.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"expo.js","sourceRoot":"","sources":["../../../src/react-native/expo.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport * as clack from '@clack/prompts';\nimport chalk from 'chalk';\nimport * as fs from 'fs';\nimport { EOL } from 'os';\n\nimport { isPlainObject } from '@sentry/utils';\nimport * as Sentry from '@sentry/node';\nimport { makeCodeSnippet, showCopyPasteInstructions } from '../utils/clack';\nimport { RNCliSetupConfigContent } from './react-native-wizard';\nimport { traceStep } from '../telemetry';\n\nexport const SENTRY_EXPO_PLUGIN_NAME = '@sentry/react-native/expo';\nexport const DEPRECATED_SENTRY_EXPO_PLUGIN_NAME = 'sentry-expo';\n\nexport const SENTRY_PLUGIN_FUNCTION_NAME = 'withSentry';\n\nconst APP_CONFIG_JSON = `app.json`;\n\nexport interface AppConfigJson {\n expo?: {\n plugins?: Array<[string, undefined | Record<string, unknown>]>;\n };\n}\n\nexport function printSentryExpoMigrationOutro(): void {\n clack.outro(\n `Deprecated ${chalk.cyan(\n 'sentry-expo',\n )} package installed in your dependencies. Please follow the migration guide at ${chalk.cyan(\n 'https://docs.sentry.io/platforms/react-native/migration/sentry-expo/',\n )}`,\n );\n}\n\n/**\n * Finds app.json in the project root and add Sentry Expo `withSentry` plugin.\n */\nexport async function patchExpoAppConfig(options: RNCliSetupConfigContent) {\n function showInstructions() {\n return showCopyPasteInstructions({\n filename: APP_CONFIG_JSON,\n codeSnippet: getSentryAppConfigJsonCodeSnippet(options),\n hint: 'This ensures auto upload of source maps during native app build.',\n });\n }\n\n const appConfigJsonExists = fs.existsSync(APP_CONFIG_JSON);\n\n Sentry.setTag(\n 'app-config-file-status',\n appConfigJsonExists ? 'found' : 'not-found',\n );\n if (!appConfigJsonExists) {\n return await showInstructions();\n }\n\n const patched = await patchAppConfigJson(APP_CONFIG_JSON, options);\n if (!patched) {\n Sentry.setTag('app-config-file-status', 'patch-error');\n clack.log.error(`Unable to patch ${chalk.cyan('app.config.json')}.`);\n return await showInstructions();\n }\n}\n\nasync function patchAppConfigJson(\n path: string,\n options: RNCliSetupConfigContent,\n): Promise<boolean> {\n const appConfigContent = (\n await fs.promises.readFile(path, { encoding: 'utf-8' })\n ).toString();\n const patchedContent = traceStep('app-config-json-patch', () =>\n addWithSentryToAppConfigJson(appConfigContent, options),\n );\n if (patchedContent === null) {\n return false;\n }\n\n try {\n await fs.promises.writeFile(path, patchedContent);\n } catch (error) {\n Sentry.setTag('app-config-file-status', 'json-write-error');\n clack.log.error(`Unable to write ${chalk.cyan('app.config.json')}.`);\n Sentry.captureException(`Unable to write 'app.config.json'.`);\n return false;\n }\n Sentry.setTag('app-config-file-status', 'json-write-success');\n clack.log.success(\n `Added Sentry Expo plugin to ${chalk.cyan('app.config.json')}.`,\n );\n return true;\n}\n\nexport function addWithSentryToAppConfigJson(\n appConfigContent: string,\n options: RNCliSetupConfigContent,\n): string | null {\n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const parsedAppConfig: AppConfigJson = JSON.parse(appConfigContent);\n const includesWithSentry =\n appConfigContent.includes(SENTRY_EXPO_PLUGIN_NAME) ||\n appConfigContent.includes(DEPRECATED_SENTRY_EXPO_PLUGIN_NAME);\n\n if (includesWithSentry) {\n Sentry.setTag('app-config-file-status', 'already-patched');\n clack.log.warn(\n `Your ${chalk.cyan(\n 'app.config.json',\n )} already includes the Sentry Expo plugin.`,\n );\n return null;\n }\n\n if (\n parsedAppConfig.expo !== undefined &&\n !isPlainObject(parsedAppConfig.expo)\n ) {\n Sentry.setTag('app-config-file-status', 'invalid-json');\n clack.log.error(\n `Unable to find expo in your ${chalk.cyan(\n 'app.config.json',\n )}. Make sure it has a valid format!`,\n );\n return null;\n }\n if (\n parsedAppConfig.expo &&\n parsedAppConfig.expo.plugins !== undefined &&\n !Array.isArray(parsedAppConfig.expo.plugins)\n ) {\n Sentry.setTag('app-config-file-status', 'invalid-json');\n clack.log.error(\n `Unable to find expo plugins in your ${chalk.cyan(\n 'app.config.json',\n )}. Make sure it has a valid format!`,\n );\n return null;\n }\n\n parsedAppConfig.expo = parsedAppConfig.expo ?? {};\n parsedAppConfig.expo.plugins = parsedAppConfig.expo.plugins ?? [];\n parsedAppConfig.expo.plugins.push([\n SENTRY_EXPO_PLUGIN_NAME,\n {\n url: options.url,\n project: options.project,\n organization: options.org,\n },\n ]);\n\n return JSON.stringify(parsedAppConfig, null, 2) + EOL;\n } catch (error) {\n Sentry.setTag('app-config-file-status', 'invalid-json');\n clack.log.error(\n `Unable to parse your ${chalk.cyan(\n 'app.config.json',\n )}. Make sure it has a valid format!`,\n );\n Sentry.captureException(`Error to parsing 'app.config.json'`);\n return null;\n }\n}\n\nexport function getSentryAppConfigJsonCodeSnippet({\n url,\n project,\n org,\n}: Omit<RNCliSetupConfigContent, 'authToken'>) {\n return makeCodeSnippet(true, (unchanged, plus, _minus) => {\n return unchanged(`{\n \"name\": \"my app\",\n \"plugins\": [\n ${plus(`[\n \"@sentry/react-native/expo\",\n {\n \"url\": \"${url}\",\n \"project\": \"${project}\",\n \"organization\": \"${org}\"\n }\n ]`)}\n ],\n}`);\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"expo.js","sourceRoot":"","sources":["../../../src/react-native/expo.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport * as clack from '@clack/prompts';\nimport chalk from 'chalk';\nimport * as fs from 'fs';\nimport { EOL } from 'os';\n\nimport * as Sentry from '@sentry/node';\nimport { makeCodeSnippet, showCopyPasteInstructions } from '../utils/clack';\nimport { RNCliSetupConfigContent } from './react-native-wizard';\nimport { traceStep } from '../telemetry';\n\nexport const SENTRY_EXPO_PLUGIN_NAME = '@sentry/react-native/expo';\nexport const DEPRECATED_SENTRY_EXPO_PLUGIN_NAME = 'sentry-expo';\n\nexport const SENTRY_PLUGIN_FUNCTION_NAME = 'withSentry';\n\nconst APP_CONFIG_JSON = `app.json`;\n\nexport interface AppConfigJson {\n expo?: {\n plugins?: Array<[string, undefined | Record<string, unknown>]>;\n };\n}\n\nexport function printSentryExpoMigrationOutro(): void {\n clack.outro(\n `Deprecated ${chalk.cyan(\n 'sentry-expo',\n )} package installed in your dependencies. Please follow the migration guide at ${chalk.cyan(\n 'https://docs.sentry.io/platforms/react-native/migration/sentry-expo/',\n )}`,\n );\n}\n\n/**\n * Finds app.json in the project root and add Sentry Expo `withSentry` plugin.\n */\nexport async function patchExpoAppConfig(options: RNCliSetupConfigContent) {\n function showInstructions() {\n return showCopyPasteInstructions({\n filename: APP_CONFIG_JSON,\n codeSnippet: getSentryAppConfigJsonCodeSnippet(options),\n hint: 'This ensures auto upload of source maps during native app build.',\n });\n }\n\n const appConfigJsonExists = fs.existsSync(APP_CONFIG_JSON);\n\n Sentry.setTag(\n 'app-config-file-status',\n appConfigJsonExists ? 'found' : 'not-found',\n );\n if (!appConfigJsonExists) {\n return await showInstructions();\n }\n\n const patched = await patchAppConfigJson(APP_CONFIG_JSON, options);\n if (!patched) {\n Sentry.setTag('app-config-file-status', 'patch-error');\n clack.log.error(`Unable to patch ${chalk.cyan('app.config.json')}.`);\n return await showInstructions();\n }\n}\n\nasync function patchAppConfigJson(\n path: string,\n options: RNCliSetupConfigContent,\n): Promise<boolean> {\n const appConfigContent = (\n await fs.promises.readFile(path, { encoding: 'utf-8' })\n ).toString();\n const patchedContent = traceStep('app-config-json-patch', () =>\n addWithSentryToAppConfigJson(appConfigContent, options),\n );\n if (patchedContent === null) {\n return false;\n }\n\n try {\n await fs.promises.writeFile(path, patchedContent);\n } catch (error) {\n Sentry.setTag('app-config-file-status', 'json-write-error');\n clack.log.error(`Unable to write ${chalk.cyan('app.config.json')}.`);\n Sentry.captureException(`Unable to write 'app.config.json'.`);\n return false;\n }\n Sentry.setTag('app-config-file-status', 'json-write-success');\n clack.log.success(\n `Added Sentry Expo plugin to ${chalk.cyan('app.config.json')}.`,\n );\n return true;\n}\n\nexport function addWithSentryToAppConfigJson(\n appConfigContent: string,\n options: RNCliSetupConfigContent,\n): string | null {\n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const parsedAppConfig: AppConfigJson = JSON.parse(appConfigContent);\n const includesWithSentry =\n appConfigContent.includes(SENTRY_EXPO_PLUGIN_NAME) ||\n appConfigContent.includes(DEPRECATED_SENTRY_EXPO_PLUGIN_NAME);\n\n if (includesWithSentry) {\n Sentry.setTag('app-config-file-status', 'already-patched');\n clack.log.warn(\n `Your ${chalk.cyan(\n 'app.config.json',\n )} already includes the Sentry Expo plugin.`,\n );\n return null;\n }\n\n if (\n parsedAppConfig.expo !== undefined &&\n !isPlainObject(parsedAppConfig.expo)\n ) {\n Sentry.setTag('app-config-file-status', 'invalid-json');\n clack.log.error(\n `Unable to find expo in your ${chalk.cyan(\n 'app.config.json',\n )}. Make sure it has a valid format!`,\n );\n return null;\n }\n if (\n parsedAppConfig.expo &&\n parsedAppConfig.expo.plugins !== undefined &&\n !Array.isArray(parsedAppConfig.expo.plugins)\n ) {\n Sentry.setTag('app-config-file-status', 'invalid-json');\n clack.log.error(\n `Unable to find expo plugins in your ${chalk.cyan(\n 'app.config.json',\n )}. Make sure it has a valid format!`,\n );\n return null;\n }\n\n parsedAppConfig.expo = parsedAppConfig.expo ?? {};\n parsedAppConfig.expo.plugins = parsedAppConfig.expo.plugins ?? [];\n parsedAppConfig.expo.plugins.push([\n SENTRY_EXPO_PLUGIN_NAME,\n {\n url: options.url,\n project: options.project,\n organization: options.org,\n },\n ]);\n\n return JSON.stringify(parsedAppConfig, null, 2) + EOL;\n } catch (error) {\n Sentry.setTag('app-config-file-status', 'invalid-json');\n clack.log.error(\n `Unable to parse your ${chalk.cyan(\n 'app.config.json',\n )}. Make sure it has a valid format!`,\n );\n Sentry.captureException(`Error to parsing 'app.config.json'`);\n return null;\n }\n}\n\nexport function getSentryAppConfigJsonCodeSnippet({\n url,\n project,\n org,\n}: Omit<RNCliSetupConfigContent, 'authToken'>) {\n return makeCodeSnippet(true, (unchanged, plus, _minus) => {\n return unchanged(`{\n \"name\": \"my app\",\n \"plugins\": [\n ${plus(`[\n \"@sentry/react-native/expo\",\n {\n \"url\": \"${url}\",\n \"project\": \"${project}\",\n \"organization\": \"${org}\"\n }\n ]`)}\n ],\n}`);\n });\n}\n\n/**\n * Checks whether the given value is a plain object (as opposed to something like a class instance or a primitive).\n * vendored from @sentry/utils to avoid registering the dependency.\n */\nfunction isPlainObject(what: unknown): boolean {\n return Object.prototype.toString.call(what) === '[object Object]';\n}\n"]}
|
|
@@ -193,7 +193,7 @@ async function startToolSetupFlow(selectedTool, options, wizardOptions, preSelec
|
|
|
193
193
|
await (0, sentry_cli_1.configureSentryCLI)(options, tsc_1.configureTscSourcemapGenerationFlow);
|
|
194
194
|
break;
|
|
195
195
|
case 'create-react-app':
|
|
196
|
-
await (0, sentry_cli_1.configureSentryCLI)(options, create_react_app_1.configureCRASourcemapGenerationFlow);
|
|
196
|
+
await (0, sentry_cli_1.configureSentryCLI)({ ...options, defaultArtifactPath: `.${path_1.sep}build` }, create_react_app_1.configureCRASourcemapGenerationFlow);
|
|
197
197
|
break;
|
|
198
198
|
case 'wrangler':
|
|
199
199
|
await (0, wrangler_1.configureWrangler)(options);
|