@sentry/wizard 6.11.0 → 6.13.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 +64 -0
- package/dist/bin.js +16 -1
- package/dist/bin.js.map +1 -1
- package/dist/e2e-tests/tests/angular-17.test.js +3 -4
- package/dist/e2e-tests/tests/angular-17.test.js.map +1 -1
- package/dist/e2e-tests/tests/angular-19.test.js +3 -4
- package/dist/e2e-tests/tests/angular-19.test.js.map +1 -1
- package/dist/e2e-tests/tests/cloudflare-worker.test.js +5 -0
- package/dist/e2e-tests/tests/cloudflare-worker.test.js.map +1 -1
- package/dist/e2e-tests/tests/flutter.test.js +60 -0
- package/dist/e2e-tests/tests/flutter.test.js.map +1 -1
- package/dist/e2e-tests/tests/help-message.test.js +8 -3
- package/dist/e2e-tests/tests/help-message.test.js.map +1 -1
- package/dist/e2e-tests/tests/nuxt-3.test.js +12 -6
- package/dist/e2e-tests/tests/nuxt-3.test.js.map +1 -1
- package/dist/e2e-tests/tests/nuxt-4.test.js +12 -6
- package/dist/e2e-tests/tests/nuxt-4.test.js.map +1 -1
- package/dist/e2e-tests/tests/pnpm-workspace.test.js +8 -4
- package/dist/e2e-tests/tests/pnpm-workspace.test.js.map +1 -1
- package/dist/e2e-tests/tests/react-router-instrumentation-api.test.js +96 -0
- package/dist/e2e-tests/tests/react-router-instrumentation-api.test.js.map +1 -0
- package/dist/e2e-tests/tests/react-router.test.js +6 -7
- package/dist/e2e-tests/tests/react-router.test.js.map +1 -1
- package/dist/e2e-tests/tests/remix.test.js +2 -4
- package/dist/e2e-tests/tests/remix.test.js.map +1 -1
- package/dist/e2e-tests/tests/sveltekit-hooks.test.js +24 -8
- package/dist/e2e-tests/tests/sveltekit-hooks.test.js.map +1 -1
- package/dist/e2e-tests/tests/sveltekit-tracing.test.js +8 -4
- package/dist/e2e-tests/tests/sveltekit-tracing.test.js.map +1 -1
- package/dist/lib/Constants.d.ts +1 -0
- package/dist/lib/Constants.js +5 -0
- package/dist/lib/Constants.js.map +1 -1
- package/dist/lib/Steps/Integrations/Electron.js +2 -2
- package/dist/lib/Steps/Integrations/Electron.js.map +1 -1
- package/dist/src/android/android-wizard.js +3 -0
- package/dist/src/android/android-wizard.js.map +1 -1
- package/dist/src/angular/codemods/main.d.ts +1 -1
- package/dist/src/angular/codemods/main.js +0 -1
- package/dist/src/angular/codemods/main.js.map +1 -1
- package/dist/src/apple/apple-wizard.js +2 -3
- package/dist/src/apple/apple-wizard.js.map +1 -1
- package/dist/src/apple/check-installed-cli.d.ts +1 -1
- package/dist/src/apple/check-installed-cli.js +13 -7
- package/dist/src/apple/check-installed-cli.js.map +1 -1
- package/dist/src/apple/code-tools.js +17 -3
- package/dist/src/apple/code-tools.js.map +1 -1
- package/dist/src/apple/configure-package-manager.js +18 -5
- package/dist/src/apple/configure-package-manager.js.map +1 -1
- package/dist/src/apple/configure-xcode-project.js +8 -1
- package/dist/src/apple/configure-xcode-project.js.map +1 -1
- package/dist/src/apple/lookup-xcode-project.d.ts +8 -5
- package/dist/src/apple/lookup-xcode-project.js +22 -17
- package/dist/src/apple/lookup-xcode-project.js.map +1 -1
- package/dist/src/apple/options.d.ts +5 -0
- package/dist/src/apple/options.js.map +1 -1
- package/dist/src/apple/sentry-swift-package.d.ts +4 -0
- package/dist/src/apple/sentry-swift-package.js +17 -0
- package/dist/src/apple/sentry-swift-package.js.map +1 -0
- package/dist/src/apple/snapshots/apple-snapshots-wizard.d.ts +2 -0
- package/dist/src/apple/snapshots/apple-snapshots-wizard.js +251 -0
- package/dist/src/apple/snapshots/apple-snapshots-wizard.js.map +1 -0
- package/dist/src/apple/snapshots/configure-snapshotpreviews-xcode-project.d.ts +13 -0
- package/dist/src/apple/snapshots/configure-snapshotpreviews-xcode-project.js +48 -0
- package/dist/src/apple/snapshots/configure-snapshotpreviews-xcode-project.js.map +1 -0
- package/dist/src/apple/snapshots/snapshot-test-file.d.ts +18 -0
- package/dist/src/apple/snapshots/snapshot-test-file.js +122 -0
- package/dist/src/apple/snapshots/snapshot-test-file.js.map +1 -0
- package/dist/src/apple/snapshots/snapshot-verification-scheme.d.ts +6 -0
- package/dist/src/apple/snapshots/snapshot-verification-scheme.js +147 -0
- package/dist/src/apple/snapshots/snapshot-verification-scheme.js.map +1 -0
- package/dist/src/apple/snapshots/snapshotpreviews-package.d.ts +4 -0
- package/dist/src/apple/snapshots/snapshotpreviews-package.js +8 -0
- package/dist/src/apple/snapshots/snapshotpreviews-package.js.map +1 -0
- package/dist/src/apple/snapshots/snapshots-cli-preflight.d.ts +23 -0
- package/dist/src/apple/snapshots/snapshots-cli-preflight.js +136 -0
- package/dist/src/apple/snapshots/snapshots-cli-preflight.js.map +1 -0
- package/dist/src/apple/xcode-manager.d.ts +59 -1
- package/dist/src/apple/xcode-manager.js +507 -106
- package/dist/src/apple/xcode-manager.js.map +1 -1
- package/dist/src/cloudflare/cloudflare-wizard.js +5 -0
- package/dist/src/cloudflare/cloudflare-wizard.js.map +1 -1
- package/dist/src/cloudflare/sdk-setup.d.ts +1 -0
- package/dist/src/cloudflare/sdk-setup.js.map +1 -1
- package/dist/src/cloudflare/templates.d.ts +1 -0
- package/dist/src/cloudflare/templates.js +7 -1
- package/dist/src/cloudflare/templates.js.map +1 -1
- package/dist/src/cloudflare/wrap-worker.d.ts +1 -0
- package/dist/src/cloudflare/wrap-worker.js +7 -0
- package/dist/src/cloudflare/wrap-worker.js.map +1 -1
- package/dist/src/flutter/flutter-wizard.js +3 -0
- package/dist/src/flutter/flutter-wizard.js.map +1 -1
- package/dist/src/nextjs/templates.js +12 -6
- package/dist/src/nextjs/templates.js.map +1 -1
- package/dist/src/nuxt/templates.js +12 -6
- package/dist/src/nuxt/templates.js.map +1 -1
- package/dist/src/react-native/expo.d.ts +6 -0
- package/dist/src/react-native/expo.js +27 -1
- package/dist/src/react-native/expo.js.map +1 -1
- package/dist/src/react-native/git.d.ts +5 -0
- package/dist/src/react-native/git.js +32 -1
- package/dist/src/react-native/git.js.map +1 -1
- package/dist/src/react-native/javascript.js +3 -1
- package/dist/src/react-native/javascript.js.map +1 -1
- package/dist/src/react-native/react-native-wizard.js +12 -6
- package/dist/src/react-native/react-native-wizard.js.map +1 -1
- package/dist/src/react-router/codemods/client.entry.d.ts +1 -1
- package/dist/src/react-router/codemods/client.entry.js +124 -26
- package/dist/src/react-router/codemods/client.entry.js.map +1 -1
- package/dist/src/react-router/codemods/react-router-config.js +1 -1
- package/dist/src/react-router/codemods/react-router-config.js.map +1 -1
- package/dist/src/react-router/codemods/server-entry.d.ts +1 -1
- package/dist/src/react-router/codemods/server-entry.js +40 -4
- package/dist/src/react-router/codemods/server-entry.js.map +1 -1
- package/dist/src/react-router/codemods/vite.js +46 -1
- package/dist/src/react-router/codemods/vite.js.map +1 -1
- package/dist/src/react-router/react-router-wizard.js +62 -21
- package/dist/src/react-router/react-router-wizard.js.map +1 -1
- package/dist/src/react-router/sdk-setup.d.ts +5 -3
- package/dist/src/react-router/sdk-setup.js +44 -16
- package/dist/src/react-router/sdk-setup.js.map +1 -1
- package/dist/src/react-router/templates.d.ts +2 -4
- package/dist/src/react-router/templates.js +89 -87
- package/dist/src/react-router/templates.js.map +1 -1
- package/dist/src/remix/sdk-setup.js +1 -2
- package/dist/src/remix/sdk-setup.js.map +1 -1
- package/dist/src/run.d.ts +4 -1
- package/dist/src/run.js +13 -0
- package/dist/src/run.js.map +1 -1
- package/dist/src/sourcemaps/tools/remix.js +4 -4
- package/dist/src/sourcemaps/tools/remix.js.map +1 -1
- package/dist/src/sourcemaps/tools/vite.js +1 -1
- package/dist/src/sourcemaps/tools/vite.js.map +1 -1
- package/dist/src/sveltekit/sdk-setup/setup.js +17 -4
- package/dist/src/sveltekit/sdk-setup/setup.js.map +1 -1
- package/dist/src/sveltekit/sdk-setup/vite.js +1 -1
- package/dist/src/sveltekit/sdk-setup/vite.js.map +1 -1
- package/dist/src/sveltekit/templates.js +12 -6
- package/dist/src/sveltekit/templates.js.map +1 -1
- package/dist/src/utils/ast-utils.d.ts +10 -0
- package/dist/src/utils/ast-utils.js +19 -1
- package/dist/src/utils/ast-utils.js.map +1 -1
- package/dist/src/utils/clack/index.d.ts +2 -1
- package/dist/src/utils/clack/index.js +17 -6
- package/dist/src/utils/clack/index.js.map +1 -1
- package/dist/src/utils/files.d.ts +2 -0
- package/dist/src/utils/files.js +58 -0
- package/dist/src/utils/files.js.map +1 -0
- package/dist/src/utils/git.d.ts +3 -1
- package/dist/src/utils/git.js +2 -1
- package/dist/src/utils/git.js.map +1 -1
- package/dist/src/utils/line-endings.d.ts +1 -0
- package/dist/src/utils/line-endings.js +76 -0
- package/dist/src/utils/line-endings.js.map +1 -0
- 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/angular/angular-wizard.test.js +0 -5
- package/dist/test/angular/angular-wizard.test.js.map +1 -1
- package/dist/test/apple/code-tools.test.js +78 -0
- package/dist/test/apple/code-tools.test.js.map +1 -1
- package/dist/test/apple/configure-package-manager.test.d.ts +1 -0
- package/dist/test/apple/configure-package-manager.test.js +161 -0
- package/dist/test/apple/configure-package-manager.test.js.map +1 -0
- package/dist/test/apple/lookup-xcode-project.test.d.ts +1 -0
- package/dist/test/apple/lookup-xcode-project.test.js +167 -0
- package/dist/test/apple/lookup-xcode-project.test.js.map +1 -0
- package/dist/test/apple/snapshots/apple-snapshots-wizard.test.d.ts +1 -0
- package/dist/test/apple/snapshots/apple-snapshots-wizard.test.js +487 -0
- package/dist/test/apple/snapshots/apple-snapshots-wizard.test.js.map +1 -0
- package/dist/test/apple/snapshots/hosted-test-target-fixture.d.ts +24 -0
- package/dist/test/apple/snapshots/hosted-test-target-fixture.js +191 -0
- package/dist/test/apple/snapshots/hosted-test-target-fixture.js.map +1 -0
- package/dist/test/apple/snapshots/snapshot-test-file.test.d.ts +1 -0
- package/dist/test/apple/snapshots/snapshot-test-file.test.js +110 -0
- package/dist/test/apple/snapshots/snapshot-test-file.test.js.map +1 -0
- package/dist/test/apple/snapshots/snapshot-verification-scheme.test.d.ts +1 -0
- package/dist/test/apple/snapshots/snapshot-verification-scheme.test.js +146 -0
- package/dist/test/apple/snapshots/snapshot-verification-scheme.test.js.map +1 -0
- package/dist/test/apple/snapshots/snapshotpreviews-xcode-smoke.test.d.ts +1 -0
- package/dist/test/apple/snapshots/snapshotpreviews-xcode-smoke.test.js +186 -0
- package/dist/test/apple/snapshots/snapshotpreviews-xcode-smoke.test.js.map +1 -0
- package/dist/test/apple/snapshots/snapshots-cli-preflight.test.d.ts +1 -0
- package/dist/test/apple/snapshots/snapshots-cli-preflight.test.js +192 -0
- package/dist/test/apple/snapshots/snapshots-cli-preflight.test.js.map +1 -0
- package/dist/test/apple/snapshots/source-file-insertion.test.d.ts +1 -0
- package/dist/test/apple/snapshots/source-file-insertion.test.js +77 -0
- package/dist/test/apple/snapshots/source-file-insertion.test.js.map +1 -0
- package/dist/test/apple/xcode-manager.test.js +452 -43
- package/dist/test/apple/xcode-manager.test.js.map +1 -1
- package/dist/test/cloudflare/sdk-setup.test.js +20 -2
- package/dist/test/cloudflare/sdk-setup.test.js.map +1 -1
- package/dist/test/cloudflare/templates.test.js +54 -0
- package/dist/test/cloudflare/templates.test.js.map +1 -1
- package/dist/test/cloudflare/wrap-worker.test.js +74 -11
- package/dist/test/cloudflare/wrap-worker.test.js.map +1 -1
- package/dist/test/constants.test.d.ts +1 -0
- package/dist/test/constants.test.js +12 -0
- package/dist/test/constants.test.js.map +1 -0
- package/dist/test/nextjs/templates.test.js +66 -33
- package/dist/test/nextjs/templates.test.js.map +1 -1
- package/dist/test/nuxt/templates.test.js +66 -36
- package/dist/test/nuxt/templates.test.js.map +1 -1
- package/dist/test/react-native/expo.test.js +140 -0
- package/dist/test/react-native/expo.test.js.map +1 -1
- package/dist/test/react-native/git.test.d.ts +1 -0
- package/dist/test/react-native/git.test.js +160 -0
- package/dist/test/react-native/git.test.js.map +1 -0
- package/dist/test/react-router/codemods/client-entry.test.js +38 -5
- package/dist/test/react-router/codemods/client-entry.test.js.map +1 -1
- package/dist/test/react-router/codemods/server-entry.test.js +83 -0
- package/dist/test/react-router/codemods/server-entry.test.js.map +1 -1
- package/dist/test/react-router/codemods/vite.test.js +89 -0
- package/dist/test/react-router/codemods/vite.test.js.map +1 -1
- package/dist/test/react-router/sdk-setup.test.js +98 -6
- package/dist/test/react-router/sdk-setup.test.js.map +1 -1
- package/dist/test/react-router/templates.test.js +50 -38
- package/dist/test/react-router/templates.test.js.map +1 -1
- package/dist/test/remix/build-script.test.d.ts +1 -0
- package/dist/test/remix/build-script.test.js +124 -0
- package/dist/test/remix/build-script.test.js.map +1 -0
- package/dist/test/remix/client-entry.test.js +4 -10
- package/dist/test/remix/client-entry.test.js.map +1 -1
- package/dist/test/run.test.d.ts +1 -0
- package/dist/test/run.test.js +137 -0
- package/dist/test/run.test.js.map +1 -0
- package/dist/test/sourcemaps/tools/vite.test.js +12 -8
- package/dist/test/sourcemaps/tools/vite.test.js.map +1 -1
- package/dist/test/sveltekit/templates.test.js +78 -27
- package/dist/test/sveltekit/templates.test.js.map +1 -1
- package/dist/test/utils/ast-utils.test.js +22 -0
- package/dist/test/utils/ast-utils.test.js.map +1 -1
- package/dist/test/utils/clack/index.test.js +101 -0
- package/dist/test/utils/clack/index.test.js.map +1 -1
- package/dist/test/utils/git.test.js +10 -0
- package/dist/test/utils/git.test.js.map +1 -1
- package/dist/test/utils/line-endings.test.d.ts +1 -0
- package/dist/test/utils/line-endings.test.js +103 -0
- package/dist/test/utils/line-endings.test.js.map +1 -0
- package/package.json +2 -2
- package/dist/src/react-router/codemods/root.d.ts +0 -1
- package/dist/src/react-router/codemods/root.js +0 -171
- package/dist/src/react-router/codemods/root.js.map +0 -1
- package/dist/test/react-router/codemods/root.test.js +0 -178
- package/dist/test/react-router/codemods/root.test.js.map +0 -1
- /package/dist/{test/react-router/codemods/root.test.d.ts → e2e-tests/tests/react-router-instrumentation-api.test.d.ts} +0 -0
|
@@ -103,6 +103,13 @@ function createSentryConfigFunction(dsn, selectedFeatures) {
|
|
|
103
103
|
];
|
|
104
104
|
configProperties.push(tracesSampleRateProperty);
|
|
105
105
|
}
|
|
106
|
+
if (selectedFeatures.logs) {
|
|
107
|
+
const enableLogsProperty = b.objectProperty(b.identifier('enableLogs'), b.booleanLiteral(true));
|
|
108
|
+
enableLogsProperty.comments = [
|
|
109
|
+
b.commentLine(' Enable logs to be sent to Sentry', true, false),
|
|
110
|
+
];
|
|
111
|
+
configProperties.push(enableLogsProperty);
|
|
112
|
+
}
|
|
106
113
|
const configObject = b.objectExpression(configProperties);
|
|
107
114
|
return b.arrowFunctionExpression([b.identifier('env')], configObject);
|
|
108
115
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wrap-worker.js","sourceRoot":"","sources":["../../../src/cloudflare/wrap-worker.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAAiC;AAEjC,kFAAkF;AAClF,uCAA+C;AAC/C,+EAA+E;AAC/E,sDAAwC;AACxC,kDAAsD;AACtD,kDAA0B;AAG1B,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC;AAEhC;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACI,KAAK,UAAU,oBAAoB,CACxC,cAAsB,EACtB,GAAW,EACX,
|
|
1
|
+
{"version":3,"file":"wrap-worker.js","sourceRoot":"","sources":["../../../src/cloudflare/wrap-worker.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAAiC;AAEjC,kFAAkF;AAClF,uCAA+C;AAC/C,+EAA+E;AAC/E,sDAAwC;AACxC,kDAAsD;AACtD,kDAA0B;AAG1B,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC;AAEhC;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACI,KAAK,UAAU,oBAAoB,CACxC,cAAsB,EACtB,GAAW,EACX,gBAGC;IAED,MAAM,SAAS,GAAG,MAAM,IAAA,mBAAQ,EAAC,cAAc,CAAC,CAAC;IAEjD,IAAI,IAAA,4BAAgB,EAAC,SAAS,CAAC,IAAiB,CAAC,EAAE;QACjD,KAAK,CAAC,GAAG,CAAC,IAAI,CACZ,mCAAmC,eAAK,CAAC,IAAI,CAC3C,cAAc,CACf,kCAAkC,CACpC,CAAC;QACF,OAAO;KACR;IAED,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC;QACrB,IAAI,EAAE,oBAAoB;QAC1B,QAAQ,EAAE,GAAG;QACb,KAAK,EAAE,QAAQ;KAChB,CAAC,CAAC;IAEH,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE;QAC3B,6BAA6B,CAAC,IAAI;YAChC,+GAA+G;YAC/G,MAAM,mBAAmB,GAAG,IAAI,CAAC,KAAK,CAAC,WAA6B,CAAC;YACrE,MAAM,YAAY,GAAG,0BAA0B,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;YACvE,MAAM,aAAa,GAAG,CAAC,CAAC,cAAc,CACpC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,EACtE,CAAC,YAAY,EAAE,mBAAmB,CAAC,CACpC,CAAC;YAEF,sEAAsE;YACtE,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,aAAa,CAAC;YAEvC,OAAO,KAAK,CAAC;QACf,CAAC;KACF,CAAC,CAAC;IAEH,MAAM,IAAA,oBAAS,EAAC,SAAS,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;AAClD,CAAC;AA3CD,oDA2CC;AAED;;GAEG;AACH,SAAS,0BAA0B,CACjC,GAAW,EACX,gBAGC;IAED,MAAM,gBAAgB,GAAuB;QAC3C,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;KAC5D,CAAC;IAEF,IAAI,gBAAgB,CAAC,WAAW,EAAE;QAChC,MAAM,wBAAwB,GAAG,CAAC,CAAC,cAAc,CAC/C,CAAC,CAAC,UAAU,CAAC,kBAAkB,CAAC,EAChC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CACpB,CAAC;QAEF,wBAAwB,CAAC,QAAQ,GAAG;YAClC,CAAC,CAAC,WAAW,CACX,mHAAmH,EACnH,IAAI,EACJ,KAAK,CACN;SACF,CAAC;QAEF,gBAAgB,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;KACjD;IAED,IAAI,gBAAgB,CAAC,IAAI,EAAE;QACzB,MAAM,kBAAkB,GAAG,CAAC,CAAC,cAAc,CACzC,CAAC,CAAC,UAAU,CAAC,YAAY,CAAC,EAC1B,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CACvB,CAAC;QAEF,kBAAkB,CAAC,QAAQ,GAAG;YAC5B,CAAC,CAAC,WAAW,CAAC,mCAAmC,EAAE,IAAI,EAAE,KAAK,CAAC;SAChE,CAAC;QAEF,gBAAgB,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;KAC3C;IAED,MAAM,YAAY,GAAG,CAAC,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;IAE1D,OAAO,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;AACxE,CAAC","sourcesContent":["import * as recast from 'recast';\nimport type { namedTypes as t } from 'ast-types';\n// @ts-expect-error - magicast is ESM and TS complains about that. It works though\nimport { loadFile, writeFile } from 'magicast';\n// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport * as clack from '@clack/prompts';\nimport { hasSentryContent } from '../utils/ast-utils';\nimport chalk from 'chalk';\nimport { ExpressionKind } from 'ast-types/lib/gen/kinds';\n\nconst b = recast.types.builders;\n\n/**\n * Wraps a Cloudflare Worker's default export with Sentry.withSentry()\n *\n * Before:\n * ```\n * export default {\n * async fetch(request, env, ctx) { ... }\n * } satisfies ExportedHandler<Env>;\n * ```\n *\n * After:\n * ```\n * import * as Sentry from '@sentry/cloudflare';\n *\n * export default Sentry.withSentry(\n * (env) => ({\n * dsn: 'your-dsn',\n * tracesSampleRate: 1,\n * }),\n * {\n * async fetch(request, env, ctx) { ... }\n * } satisfies ExportedHandler<Env>\n * );\n * ```\n *\n * @param workerFilePath - Path to the worker file to wrap\n * @param dsn - Sentry DSN for initialization\n * @param selectedFeatures - Feature flags for optional Sentry features\n */\nexport async function wrapWorkerWithSentry(\n workerFilePath: string,\n dsn: string,\n selectedFeatures: {\n performance: boolean;\n logs: boolean;\n },\n): Promise<void> {\n const workerAst = await loadFile(workerFilePath);\n\n if (hasSentryContent(workerAst.$ast as t.Program)) {\n clack.log.warn(\n `Sentry is already configured in ${chalk.cyan(\n workerFilePath,\n )}. Skipping wrapping with Sentry.`,\n );\n return;\n }\n\n workerAst.imports.$add({\n from: '@sentry/cloudflare',\n imported: '*',\n local: 'Sentry',\n });\n\n recast.visit(workerAst.$ast, {\n visitExportDefaultDeclaration(path) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access\n const originalDeclaration = path.value.declaration as ExpressionKind;\n const sentryConfig = createSentryConfigFunction(dsn, selectedFeatures);\n const wrappedExport = b.callExpression(\n b.memberExpression(b.identifier('Sentry'), b.identifier('withSentry')),\n [sentryConfig, originalDeclaration],\n );\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n path.value.declaration = wrappedExport;\n\n return false;\n },\n });\n\n await writeFile(workerAst.$ast, workerFilePath);\n}\n\n/**\n * Creates the Sentry config function: (env) => ({ dsn: '...', ... })\n */\nfunction createSentryConfigFunction(\n dsn: string,\n selectedFeatures: {\n performance: boolean;\n logs: boolean;\n },\n): t.ArrowFunctionExpression {\n const configProperties: t.ObjectProperty[] = [\n b.objectProperty(b.identifier('dsn'), b.stringLiteral(dsn)),\n ];\n\n if (selectedFeatures.performance) {\n const tracesSampleRateProperty = b.objectProperty(\n b.identifier('tracesSampleRate'),\n b.numericLiteral(1),\n );\n\n tracesSampleRateProperty.comments = [\n b.commentLine(\n ' Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.',\n true,\n false,\n ),\n ];\n\n configProperties.push(tracesSampleRateProperty);\n }\n\n if (selectedFeatures.logs) {\n const enableLogsProperty = b.objectProperty(\n b.identifier('enableLogs'),\n b.booleanLiteral(true),\n );\n\n enableLogsProperty.comments = [\n b.commentLine(' Enable logs to be sent to Sentry', true, false),\n ];\n\n configProperties.push(enableLogsProperty);\n }\n\n const configObject = b.objectExpression(configProperties);\n\n return b.arrowFunctionExpression([b.identifier('env')], configObject);\n}\n"]}
|
|
@@ -41,6 +41,7 @@ const telemetry_1 = require("../telemetry");
|
|
|
41
41
|
const code_tools_1 = require("./code-tools");
|
|
42
42
|
const mcp_config_1 = require("../utils/clack/mcp-config");
|
|
43
43
|
const abort_if_sportlight_not_supported_1 = require("../utils/abort-if-sportlight-not-supported");
|
|
44
|
+
const line_endings_1 = require("../utils/line-endings");
|
|
44
45
|
async function runFlutterWizard(options) {
|
|
45
46
|
return (0, telemetry_1.withTelemetry)({
|
|
46
47
|
enabled: options.telemetryEnabled,
|
|
@@ -114,6 +115,8 @@ Set the ${chalk_1.default.cyan('SENTRY_AUTH_TOKEN')} environment variable in you
|
|
|
114
115
|
// ======== OUTRO ========
|
|
115
116
|
// Offer optional project-scoped MCP config for Sentry with org and project scope
|
|
116
117
|
await (0, mcp_config_1.offerProjectScopedMcpConfig)(selectedProject.organization.slug, selectedProject.slug);
|
|
118
|
+
// Fix mixed line endings caused by inserting LF content into CRLF files (Windows)
|
|
119
|
+
(0, line_endings_1.fixLineEndings)();
|
|
117
120
|
const issuesPageLink = selfHosted
|
|
118
121
|
? `${sentryUrl}organizations/${selectedProject.organization.slug}/issues/?project=${selectedProject.id}`
|
|
119
122
|
: `https://${selectedProject.organization.slug}.sentry.io/issues/?project=${selectedProject.id}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flutter-wizard.js","sourceRoot":"","sources":["../../../src/flutter/flutter-wizard.ts"],"names":[],"mappings":"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","sourcesContent":["import * as Sentry from '@sentry/node';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { fetchSdkVersion } from '../utils/release-registry';\nimport { WizardOptions } from '../utils/types';\nimport * as codetools from './code-tools';\nimport { initSnippetColored, pubspecSnippetColored } from './templates';\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';\n\nimport {\n confirmContinueIfNoOrDirtyGitRepo,\n getOrAskForProjectData,\n printWelcome,\n showCopyPasteInstructions,\n} from '../utils/clack';\n\nimport { traceStep, withTelemetry } from '../telemetry';\nimport { findFile } from './code-tools';\nimport { offerProjectScopedMcpConfig } from '../utils/clack/mcp-config';\nimport { abortIfSpotlightNotSupported } from '../utils/abort-if-sportlight-not-supported';\n\nexport async function runFlutterWizard(options: WizardOptions): Promise<void> {\n return withTelemetry(\n {\n enabled: options.telemetryEnabled,\n integration: 'flutter',\n wizardOptions: options,\n },\n () => runFlutterWizardWithTelemetry(options),\n );\n}\n\nasync function runFlutterWizardWithTelemetry(\n options: WizardOptions,\n): Promise<void> {\n printWelcome({\n wizardName: 'Sentry Flutter Wizard',\n promoCode: options.promoCode,\n });\n\n await confirmContinueIfNoOrDirtyGitRepo({\n ignoreGitChanges: options.ignoreGitChanges,\n cwd: undefined,\n });\n\n const projectData = await getOrAskForProjectData(options, 'flutter');\n\n if (projectData.spotlight) {\n return abortIfSpotlightNotSupported('Flutter');\n }\n\n const { selectedProject, selfHosted, sentryUrl, authToken } = projectData;\n\n const projectDir = process.cwd();\n const pubspecFile = path.join(projectDir, 'pubspec.yaml');\n if (!fs.existsSync(pubspecFile)) {\n clack.log.error(\n `Could not find ${chalk.cyan(\n 'pubspec.yaml',\n )}. Make sure you run the wizard in the projects root folder.`,\n );\n return;\n }\n\n // ======== STEP 1. Add sentry_flutter and sentry_dart_plugin to pubspec.yaml ============\n\n clack.log.step(\n `Adding ${chalk.bold('Sentry')} to your apps ${chalk.cyan(\n 'pubspec.yaml',\n )} file.`,\n );\n\n const flutterVersion = await fetchSdkVersion('sentry.dart.flutter');\n const flutterVersionOrAny = flutterVersion ? `^${flutterVersion}` : 'any';\n\n const pluginVersion = await fetchSdkVersion('sentry.dart.plugin');\n const pluginVersionOrAny = pluginVersion ? `^${pluginVersion}` : 'any';\n\n const pubspecPatched = traceStep('Patch pubspec.yaml', () =>\n codetools.patchPubspec(\n pubspecFile,\n flutterVersionOrAny,\n pluginVersionOrAny,\n selectedProject.slug,\n selectedProject.organization.slug,\n ),\n );\n if (!pubspecPatched) {\n clack.log.warn(\n `Could not patch ${chalk.cyan(\n 'pubspec.yaml',\n )}. Add the dependencies to it.`,\n );\n await showCopyPasteInstructions({\n filename: 'pubspec.yaml',\n codeSnippet: pubspecSnippetColored(\n flutterVersionOrAny,\n pluginVersionOrAny,\n selectedProject.slug,\n selectedProject.organization.slug,\n ),\n hint: 'This ensures the Sentry SDK and plugin can be imported.',\n });\n }\n Sentry.setTag('pubspec-patched', pubspecPatched);\n\n // ======== STEP 2. Add sentry.properties with auth token ============\n\n const propertiesAdded = traceStep('Add sentry.properties', () =>\n codetools.addProperties(pubspecFile, authToken),\n );\n if (!propertiesAdded) {\n clack.log.warn(\n `We could not add ${chalk.cyan(\n 'sentry.properties',\n )} file in your project directory in order to provide an auth token for Sentry CLI. You'll have to add it manually, or you can set the SENTRY_AUTH_TOKEN environment variable instead. See https://docs.sentry.io/cli/configuration/#auth-token for more information.`,\n );\n } else {\n clack.log.info(\n `Created a ${chalk.cyan(\n 'sentry.properties',\n )} file in your project directory to provide an auth token for Sentry CLI.\nIt was also added to your ${chalk.cyan('.gitignore')} file.\nSet the ${chalk.cyan(\n 'SENTRY_AUTH_TOKEN',\n )} environment variable in your CI environment. See https://docs.sentry.io/cli/configuration/#auth-token for more information.`,\n );\n }\n Sentry.setTag('sentry-properties-added', pubspecPatched);\n\n // ======== STEP 3. Patch main.dart with setup and a test error snippet ============\n\n clack.log.step(\n `Next, the wizard will patch your ${chalk.cyan(\n 'main.dart',\n )} file with the SDK init and a test error snippet.`,\n );\n\n const mainFile = findFile(`${projectDir}/lib`, 'main.dart');\n const dsn = selectedProject.keys[0].dsn.public;\n const canEnableProfiling =\n fs.existsSync(`${projectDir}/ios`) || fs.existsSync(`${projectDir}/macos`);\n\n const mainPatched = await traceStep('Patch main.dart', () =>\n codetools.patchMain(mainFile, dsn, canEnableProfiling),\n );\n if (!mainPatched) {\n clack.log.warn(\n `Could not patch ${chalk.cyan(\n 'main.dart',\n )} file. Place the following code snippet within the apps main function.`,\n );\n await showCopyPasteInstructions({\n filename: 'main.dart',\n codeSnippet: initSnippetColored(dsn),\n hint: 'This ensures the Sentry SDK is ready to capture errors.',\n });\n }\n Sentry.setTag('main-patched', mainPatched);\n\n // ======== OUTRO ========\n\n // Offer optional project-scoped MCP config for Sentry with org and project scope\n await offerProjectScopedMcpConfig(\n selectedProject.organization.slug,\n selectedProject.slug,\n );\n\n const issuesPageLink = selfHosted\n ? `${sentryUrl}organizations/${selectedProject.organization.slug}/issues/?project=${selectedProject.id}`\n : `https://${selectedProject.organization.slug}.sentry.io/issues/?project=${selectedProject.id}`;\n\n clack.outro(`${chalk.greenBright(\n 'Successfully installed the Sentry Flutter SDK!',\n )}\n \n ${chalk.cyan('Next steps:')}\n 1. Run ${chalk.bold(\n 'flutter run',\n )} to test the setup - we've added a test error that will trigger on app start\n 2. For production builds, run ${chalk.bold(\n 'flutter build apk --obfuscate --split-debug-info=build/debug-info',\n )} (or ios/macos) then ${chalk.bold(\n 'flutter pub run sentry_dart_plugin',\n )} to upload debug symbols\n 3. View your test error and transaction data at ${issuesPageLink}\n \n ${chalk.cyan('Learn more:')}\n - Debug Symbols: https://docs.sentry.io/platforms/dart/guides/flutter/debug-symbols/\n - Performance Monitoring: https://docs.sentry.io/platforms/dart/guides/flutter/performance/\n - Integrations: https://docs.sentry.io/platforms/dart/guides/flutter/integrations/\n `);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"flutter-wizard.js","sourceRoot":"","sources":["../../../src/flutter/flutter-wizard.ts"],"names":[],"mappings":"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","sourcesContent":["import * as Sentry from '@sentry/node';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { fetchSdkVersion } from '../utils/release-registry';\nimport { WizardOptions } from '../utils/types';\nimport * as codetools from './code-tools';\nimport { initSnippetColored, pubspecSnippetColored } from './templates';\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';\n\nimport {\n confirmContinueIfNoOrDirtyGitRepo,\n getOrAskForProjectData,\n printWelcome,\n showCopyPasteInstructions,\n} from '../utils/clack';\n\nimport { traceStep, withTelemetry } from '../telemetry';\nimport { findFile } from './code-tools';\nimport { offerProjectScopedMcpConfig } from '../utils/clack/mcp-config';\nimport { abortIfSpotlightNotSupported } from '../utils/abort-if-sportlight-not-supported';\nimport { fixLineEndings } from '../utils/line-endings';\n\nexport async function runFlutterWizard(options: WizardOptions): Promise<void> {\n return withTelemetry(\n {\n enabled: options.telemetryEnabled,\n integration: 'flutter',\n wizardOptions: options,\n },\n () => runFlutterWizardWithTelemetry(options),\n );\n}\n\nasync function runFlutterWizardWithTelemetry(\n options: WizardOptions,\n): Promise<void> {\n printWelcome({\n wizardName: 'Sentry Flutter Wizard',\n promoCode: options.promoCode,\n });\n\n await confirmContinueIfNoOrDirtyGitRepo({\n ignoreGitChanges: options.ignoreGitChanges,\n cwd: undefined,\n });\n\n const projectData = await getOrAskForProjectData(options, 'flutter');\n\n if (projectData.spotlight) {\n return abortIfSpotlightNotSupported('Flutter');\n }\n\n const { selectedProject, selfHosted, sentryUrl, authToken } = projectData;\n\n const projectDir = process.cwd();\n const pubspecFile = path.join(projectDir, 'pubspec.yaml');\n if (!fs.existsSync(pubspecFile)) {\n clack.log.error(\n `Could not find ${chalk.cyan(\n 'pubspec.yaml',\n )}. Make sure you run the wizard in the projects root folder.`,\n );\n return;\n }\n\n // ======== STEP 1. Add sentry_flutter and sentry_dart_plugin to pubspec.yaml ============\n\n clack.log.step(\n `Adding ${chalk.bold('Sentry')} to your apps ${chalk.cyan(\n 'pubspec.yaml',\n )} file.`,\n );\n\n const flutterVersion = await fetchSdkVersion('sentry.dart.flutter');\n const flutterVersionOrAny = flutterVersion ? `^${flutterVersion}` : 'any';\n\n const pluginVersion = await fetchSdkVersion('sentry.dart.plugin');\n const pluginVersionOrAny = pluginVersion ? `^${pluginVersion}` : 'any';\n\n const pubspecPatched = traceStep('Patch pubspec.yaml', () =>\n codetools.patchPubspec(\n pubspecFile,\n flutterVersionOrAny,\n pluginVersionOrAny,\n selectedProject.slug,\n selectedProject.organization.slug,\n ),\n );\n if (!pubspecPatched) {\n clack.log.warn(\n `Could not patch ${chalk.cyan(\n 'pubspec.yaml',\n )}. Add the dependencies to it.`,\n );\n await showCopyPasteInstructions({\n filename: 'pubspec.yaml',\n codeSnippet: pubspecSnippetColored(\n flutterVersionOrAny,\n pluginVersionOrAny,\n selectedProject.slug,\n selectedProject.organization.slug,\n ),\n hint: 'This ensures the Sentry SDK and plugin can be imported.',\n });\n }\n Sentry.setTag('pubspec-patched', pubspecPatched);\n\n // ======== STEP 2. Add sentry.properties with auth token ============\n\n const propertiesAdded = traceStep('Add sentry.properties', () =>\n codetools.addProperties(pubspecFile, authToken),\n );\n if (!propertiesAdded) {\n clack.log.warn(\n `We could not add ${chalk.cyan(\n 'sentry.properties',\n )} file in your project directory in order to provide an auth token for Sentry CLI. You'll have to add it manually, or you can set the SENTRY_AUTH_TOKEN environment variable instead. See https://docs.sentry.io/cli/configuration/#auth-token for more information.`,\n );\n } else {\n clack.log.info(\n `Created a ${chalk.cyan(\n 'sentry.properties',\n )} file in your project directory to provide an auth token for Sentry CLI.\nIt was also added to your ${chalk.cyan('.gitignore')} file.\nSet the ${chalk.cyan(\n 'SENTRY_AUTH_TOKEN',\n )} environment variable in your CI environment. See https://docs.sentry.io/cli/configuration/#auth-token for more information.`,\n );\n }\n Sentry.setTag('sentry-properties-added', pubspecPatched);\n\n // ======== STEP 3. Patch main.dart with setup and a test error snippet ============\n\n clack.log.step(\n `Next, the wizard will patch your ${chalk.cyan(\n 'main.dart',\n )} file with the SDK init and a test error snippet.`,\n );\n\n const mainFile = findFile(`${projectDir}/lib`, 'main.dart');\n const dsn = selectedProject.keys[0].dsn.public;\n const canEnableProfiling =\n fs.existsSync(`${projectDir}/ios`) || fs.existsSync(`${projectDir}/macos`);\n\n const mainPatched = await traceStep('Patch main.dart', () =>\n codetools.patchMain(mainFile, dsn, canEnableProfiling),\n );\n if (!mainPatched) {\n clack.log.warn(\n `Could not patch ${chalk.cyan(\n 'main.dart',\n )} file. Place the following code snippet within the apps main function.`,\n );\n await showCopyPasteInstructions({\n filename: 'main.dart',\n codeSnippet: initSnippetColored(dsn),\n hint: 'This ensures the Sentry SDK is ready to capture errors.',\n });\n }\n Sentry.setTag('main-patched', mainPatched);\n\n // ======== OUTRO ========\n\n // Offer optional project-scoped MCP config for Sentry with org and project scope\n await offerProjectScopedMcpConfig(\n selectedProject.organization.slug,\n selectedProject.slug,\n );\n\n // Fix mixed line endings caused by inserting LF content into CRLF files (Windows)\n fixLineEndings();\n\n const issuesPageLink = selfHosted\n ? `${sentryUrl}organizations/${selectedProject.organization.slug}/issues/?project=${selectedProject.id}`\n : `https://${selectedProject.organization.slug}.sentry.io/issues/?project=${selectedProject.id}`;\n\n clack.outro(`${chalk.greenBright(\n 'Successfully installed the Sentry Flutter SDK!',\n )}\n \n ${chalk.cyan('Next steps:')}\n 1. Run ${chalk.bold(\n 'flutter run',\n )} to test the setup - we've added a test error that will trigger on app start\n 2. For production builds, run ${chalk.bold(\n 'flutter build apk --obfuscate --split-debug-info=build/debug-info',\n )} (or ios/macos) then ${chalk.bold(\n 'flutter pub run sentry_dart_plugin',\n )} to upload debug symbols\n 3. View your test error and transaction data at ${issuesPageLink}\n \n ${chalk.cyan('Learn more:')}\n - Debug Symbols: https://docs.sentry.io/platforms/dart/guides/flutter/debug-symbols/\n - Performance Monitoring: https://docs.sentry.io/platforms/dart/guides/flutter/performance/\n - Integrations: https://docs.sentry.io/platforms/dart/guides/flutter/integrations/\n `);\n}\n"]}
|
|
@@ -140,9 +140,12 @@ import * as Sentry from "@sentry/nextjs";
|
|
|
140
140
|
Sentry.init({
|
|
141
141
|
dsn: "${dsn}",${performanceOptions}${logsOptions}
|
|
142
142
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
143
|
+
dataCollection: {
|
|
144
|
+
// To disable sending user data and HTTP bodies, uncomment the lines below. For more info visit:
|
|
145
|
+
// https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options/#dataCollection
|
|
146
|
+
// userInfo: false,
|
|
147
|
+
// httpBodies: [],
|
|
148
|
+
},${spotlightOptions}
|
|
146
149
|
});
|
|
147
150
|
`;
|
|
148
151
|
}
|
|
@@ -186,9 +189,12 @@ import * as Sentry from "@sentry/nextjs";
|
|
|
186
189
|
Sentry.init({
|
|
187
190
|
dsn: "${dsn}",${integrationsOptions}${performanceOptions}${logsOptions}${replayOptions}
|
|
188
191
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
+
dataCollection: {
|
|
193
|
+
// To disable sending user data and HTTP bodies, uncomment the lines below. For more info visit:
|
|
194
|
+
// https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options/#dataCollection
|
|
195
|
+
// userInfo: false,
|
|
196
|
+
// httpBodies: [],
|
|
197
|
+
},${spotlightOptions}
|
|
192
198
|
});
|
|
193
199
|
|
|
194
200
|
export const onRouterTransitionStart = Sentry.captureRouterTransitionStart;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/nextjs/templates.ts"],"names":[],"mappings":"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","sourcesContent":["import chalk from 'chalk';\nimport { makeCodeSnippet } from '../utils/clack';\n\ntype WithSentryConfigOptions = {\n orgSlug: string;\n projectSlug: string;\n selfHosted: boolean;\n sentryUrl: string;\n tunnelRoute: boolean;\n};\n\nexport function getWithSentryConfigOptionsTemplate({\n orgSlug,\n projectSlug,\n selfHosted,\n tunnelRoute,\n sentryUrl,\n}: WithSentryConfigOptions): string {\n return `{\n // For all available options, see:\n // https://www.npmjs.com/package/@sentry/webpack-plugin#options\n\n org: \"${orgSlug}\",\n project: \"${projectSlug}\",${\n selfHosted ? `\\n sentryUrl: \"${sentryUrl}\",` : ''\n }\n\n // Only print logs for uploading source maps in CI\n silent: !process.env.CI,\n\n // For all available options, see:\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/\n\n // Upload a larger set of source maps for prettier stack traces (increases build time)\n widenClientFileUpload: true,\n\n // ${\n tunnelRoute ? 'Route' : 'Uncomment to route'\n } browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers.\n // This can increase your server load as well as your hosting bill.\n // Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client-\n // side errors will fail.\n ${tunnelRoute ? '' : '// '}tunnelRoute: \"/monitoring\",\n\n webpack: {\n // Enables automatic instrumentation of Vercel Cron Monitors. (Does not yet work with App Router route handlers.)\n // See the following for more information:\n // https://docs.sentry.io/product/crons/\n // https://vercel.com/docs/cron-jobs\n automaticVercelMonitors: true,\n\n // Tree-shaking options for reducing bundle size\n treeshake: {\n // Automatically tree-shake Sentry logger statements to reduce bundle size\n removeDebugLogging: true,\n },\n },\n}`;\n}\n\nexport function getNextjsConfigCjsTemplate(\n withSentryConfigOptionsTemplate: string,\n): string {\n return `const { withSentryConfig } = require(\"@sentry/nextjs\");\n\n/** @type {import('next').NextConfig} */\nconst nextConfig = {};\n\nmodule.exports = withSentryConfig(nextConfig, ${withSentryConfigOptionsTemplate});\n`;\n}\n\nexport function getNextjsConfigMjsTemplate(\n withSentryConfigOptionsTemplate: string,\n): string {\n return `import { withSentryConfig } from \"@sentry/nextjs\";\n\n/** @type {import('next').NextConfig} */\nconst nextConfig = {};\n\nexport default withSentryConfig(nextConfig, ${withSentryConfigOptionsTemplate});\n`;\n}\n\nexport function getNextjsConfigCjsAppendix(\n withSentryConfigOptionsTemplate: string,\n): string {\n return `\n\n// Injected content via Sentry wizard below\n\nconst { withSentryConfig } = require(\"@sentry/nextjs\");\n\nmodule.exports = withSentryConfig(module.exports, ${withSentryConfigOptionsTemplate});\n`;\n}\n\nexport function getNextjsConfigEsmCopyPasteSnippet(\n withSentryConfigOptionsTemplate: string,\n): string {\n return `\n\n// next.config.mjs\nimport { withSentryConfig } from \"@sentry/nextjs\";\n\nexport default withSentryConfig(yourNextConfig, ${withSentryConfigOptionsTemplate});\n`;\n}\n\nfunction getClientIntegrationsSnippet(features: { replay: boolean }) {\n if (features.replay) {\n return `\n\n // Add optional integrations for additional features\n integrations: [Sentry.replayIntegration()],`;\n }\n\n return '';\n}\n\nfunction getSpotlightOption(spotlight: boolean): string {\n if (!spotlight) {\n return '';\n }\n\n return `\n\n // Spotlight enabled for local development (https://spotlightjs.com)\n spotlight: true,`;\n}\n\nexport function getSentryServersideConfigContents(\n dsn: string,\n config: 'server' | 'edge',\n selectedFeaturesMap: {\n replay: boolean;\n performance: boolean;\n logs: boolean;\n },\n spotlight = false,\n): string {\n let primer = '';\n if (config === 'server') {\n primer = `// This file configures the initialization of Sentry on the server.\n// The config you add here will be used whenever the server handles a request.\n// https://docs.sentry.io/platforms/javascript/guides/nextjs/`;\n } else if (config === 'edge') {\n primer = `// This file configures the initialization of Sentry for edge features (middleware, edge routes, and so on).\n// The config you add here will be used whenever one of the edge features is loaded.\n// Note that this config is unrelated to the Vercel Edge Runtime and is also required when running locally.\n// https://docs.sentry.io/platforms/javascript/guides/nextjs/`;\n }\n\n let performanceOptions = '';\n if (selectedFeaturesMap.performance) {\n performanceOptions += `\n\n // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.\n tracesSampleRate: 1,`;\n }\n\n let logsOptions = '';\n if (selectedFeaturesMap.logs) {\n logsOptions += `\n\n // Enable logs to be sent to Sentry\n enableLogs: true,`;\n }\n\n const spotlightOptions = getSpotlightOption(spotlight);\n\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n return `${primer}\n\nimport * as Sentry from \"@sentry/nextjs\";\n\nSentry.init({\n dsn: \"${dsn}\",${performanceOptions}${logsOptions}\n\n // Enable sending user PII (Personally Identifiable Information)\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options/#sendDefaultPii\n sendDefaultPii: true,${spotlightOptions}\n});\n`;\n}\n\nexport function getInstrumentationClientFileContents(\n dsn: string,\n selectedFeaturesMap: {\n replay: boolean;\n performance: boolean;\n logs: boolean;\n },\n spotlight = false,\n): string {\n const integrationsOptions = getClientIntegrationsSnippet({\n replay: selectedFeaturesMap.replay,\n });\n\n let replayOptions = '';\n\n if (selectedFeaturesMap.replay) {\n replayOptions += `\n\n // Define how likely Replay events are sampled.\n // This sets the sample rate to be 10%. You may want this to be 100% while\n // in development and sample at a lower rate in production\n replaysSessionSampleRate: 0.1,\n\n // Define how likely Replay events are sampled when an error occurs.\n replaysOnErrorSampleRate: 1.0,`;\n }\n\n let performanceOptions = '';\n if (selectedFeaturesMap.performance) {\n performanceOptions += `\n\n // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.\n tracesSampleRate: 1,`;\n }\n\n let logsOptions = '';\n if (selectedFeaturesMap.logs) {\n logsOptions += `\n // Enable logs to be sent to Sentry\n enableLogs: true,`;\n }\n\n const spotlightOptions = getSpotlightOption(spotlight);\n\n return `// This file configures the initialization of Sentry on the client.\n// The added config here will be used whenever a users loads a page in their browser.\n// https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\nimport * as Sentry from \"@sentry/nextjs\";\n\nSentry.init({\n dsn: \"${dsn}\",${integrationsOptions}${performanceOptions}${logsOptions}${replayOptions}\n\n // Enable sending user PII (Personally Identifiable Information)\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options/#sendDefaultPii\n sendDefaultPii: true,${spotlightOptions}\n});\n\nexport const onRouterTransitionStart = Sentry.captureRouterTransitionStart;\n`;\n}\n\nexport function getSentryExamplePageContents(options: {\n selfHosted: boolean;\n sentryUrl: string;\n orgSlug: string;\n projectId: string;\n useClient: boolean;\n isTypeScript?: boolean;\n logsEnabled?: boolean;\n}): string {\n const issuesPageLink = options.selfHosted\n ? `${options.sentryUrl}organizations/${options.orgSlug}/issues/?project=${options.projectId}`\n : `https://${options.orgSlug}.sentry.io/issues/?project=${options.projectId}`;\n\n const loggerPageLoad = options.logsEnabled\n ? `\n Sentry.logger.info(\"Sentry example page loaded\");`\n : '';\n\n const loggerUserAction = options.logsEnabled\n ? `\n Sentry.logger.info(\"User clicked the button, throwing a sample error\");`\n : '';\n\n return `${\n options.useClient ? '\"use client\";\\n\\n' : ''\n }import * as Sentry from \"@sentry/nextjs\";\nimport Head from \"next/head\";\nimport { useEffect, useState } from \"react\";\n\nclass SentryExampleFrontendError extends Error {\n constructor(message${options.isTypeScript ? ': string | undefined' : ''}) {\n super(message);\n this.name = \"SentryExampleFrontendError\";\n }\n}\n\nexport default function Page() {\n const [hasSentError, setHasSentError] = useState(false);\n const [isConnected, setIsConnected] = useState(true);\n\n useEffect(() => {${loggerPageLoad}\n async function checkConnectivity() {\n const result = await Sentry.diagnoseSdkConnectivity();\n setIsConnected(result !== \"sentry-unreachable\");\n }\n checkConnectivity();\n }, []);\n\n return (\n <div>\n <Head>\n <title>sentry-example-page</title>\n <meta name=\"description\" content=\"Test Sentry for your Next.js app!\" />\n </Head>\n\n <main>\n <div className=\"flex-spacer\" />\n <svg\n height=\"40\"\n width=\"40\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n role=\"img\"\n aria-label=\"Sentry logo\"\n >\n <path\n d=\"M21.85 2.995a3.698 3.698 0 0 1 1.353 1.354l16.303 28.278a3.703 3.703 0 0 1-1.354 5.053 3.694 3.694 0 0 1-1.848.496h-3.828a31.149 31.149 0 0 0 0-3.09h3.815a.61.61 0 0 0 .537-.917L20.523 5.893a.61.61 0 0 0-1.057 0l-3.739 6.494a28.948 28.948 0 0 1 9.63 10.453 28.988 28.988 0 0 1 3.499 13.78v1.542h-9.852v-1.544a19.106 19.106 0 0 0-2.182-8.85 19.08 19.08 0 0 0-6.032-6.829l-1.85 3.208a15.377 15.377 0 0 1 6.382 12.484v1.542H3.696A3.694 3.694 0 0 1 0 34.473c0-.648.17-1.286.494-1.849l2.33-4.074a8.562 8.562 0 0 1 2.689 1.536L3.158 34.17a.611.611 0 0 0 .538.917h8.448a12.481 12.481 0 0 0-6.037-9.09l-1.344-.772 4.908-8.545 1.344.77a22.16 22.16 0 0 1 7.705 7.444 22.193 22.193 0 0 1 3.316 10.193h3.699a25.892 25.892 0 0 0-3.811-12.033 25.856 25.856 0 0 0-9.046-8.796l-1.344-.772 5.269-9.136a3.698 3.698 0 0 1 3.2-1.849c.648 0 1.285.17 1.847.495Z\"\n fill=\"currentcolor\"\n />\n </svg>\n <h1>sentry-example-page</h1>\n\n <p className=\"description\">\n Click the button below, and view the sample error on the Sentry{\" \"}\n <a\n target=\"_blank\"\n rel=\"noopener\"\n href=\"${issuesPageLink}\"\n >\n Issues Page\n </a>\n . For more details about setting up Sentry,{\" \"}\n <a\n target=\"_blank\"\n rel=\"noopener\"\n href=\"https://docs.sentry.io/platforms/javascript/guides/nextjs/\"\n >\n read our docs\n </a>\n .\n </p>\n\n <button\n type=\"button\"\n onClick={async () => {${loggerUserAction}\n await Sentry.startSpan(\n {\n name: \"Example Frontend/Backend Span\",\n op: \"test\",\n },\n async () => {\n const res = await fetch(\"/api/sentry-example-api\");\n if (!res.ok) {\n setHasSentError(true);\n }\n },\n );\n throw new SentryExampleFrontendError(\n \"This error is raised on the frontend of the example page.\",\n );\n }}\n disabled={!isConnected}\n >\n <span>Throw Sample Error</span>\n </button>\n\n {hasSentError ? (\n <p className=\"success\">Error sent to Sentry.</p>\n ) : !isConnected ? (\n <div className=\"connectivity-error\">\n <p>\n It looks like network requests to Sentry are being blocked, which\n will prevent errors from being captured. Try disabling your\n ad-blocker to complete the test.\n </p>\n </div>\n ) : (\n <div className=\"success_placeholder\" />\n )}\n\n <div className=\"flex-spacer\" />\n </main>\n\n <style>{\\`\n main {\n display: flex;\n min-height: 100vh;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n gap: 16px;\n padding: 16px;\n font-family: system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", sans-serif;\n }\n\n h1 {\n padding: 0px 4px;\n border-radius: 4px;\n background-color: rgba(24, 20, 35, 0.03);\n font-family: monospace;\n font-size: 20px;\n line-height: 1.2;\n }\n\n p {\n margin: 0;\n font-size: 20px;\n }\n\n a {\n color: #6341F0;\n text-decoration: underline;\n cursor: pointer;\n\n @media (prefers-color-scheme: dark) {\n color: #B3A1FF;\n }\n }\n\n button {\n border-radius: 8px;\n color: white;\n cursor: pointer;\n background-color: #553DB8;\n border: none;\n padding: 0;\n margin-top: 4px;\n\n & > span {\n display: inline-block;\n padding: 12px 16px;\n border-radius: inherit;\n font-size: 20px;\n font-weight: bold;\n line-height: 1;\n background-color: #7553FF;\n border: 1px solid #553DB8;\n transform: translateY(-4px);\n }\n\n &:hover > span {\n transform: translateY(-8px);\n }\n\n &:active > span {\n transform: translateY(0);\n }\n\n &:disabled {\n\t cursor: not-allowed;\n\t opacity: 0.6;\n\n\t & > span {\n\t transform: translateY(0);\n\t border: none\n\t }\n\t }\n }\n\n .description {\n text-align: center;\n color: #6E6C75;\n max-width: 500px;\n line-height: 1.5;\n font-size: 20px;\n\n @media (prefers-color-scheme: dark) {\n color: #A49FB5;\n }\n }\n\n .flex-spacer {\n flex: 1;\n }\n\n .success {\n padding: 12px 16px;\n border-radius: 8px;\n font-size: 20px;\n line-height: 1;\n background-color: #00F261;\n border: 1px solid #00BF4D;\n color: #181423;\n }\n\n .success_placeholder {\n height: 46px;\n }\n\n .connectivity-error {\n padding: 12px 16px;\n background-color: #E50045;\n border-radius: 8px;\n width: 500px;\n color: #FFFFFF;\n border: 1px solid #A80033;\n text-align: center;\n margin: 0;\n }\n\n .connectivity-error a {\n color: #FFFFFF;\n text-decoration: underline;\n }\n \\`}</style>\n </div>\n );\n}\n`;\n}\n\nexport function getSentryExamplePagesDirApiRoute({\n isTypeScript,\n logsEnabled,\n}: {\n isTypeScript: boolean;\n logsEnabled?: boolean;\n}) {\n const sentryImport = logsEnabled\n ? `import * as Sentry from \"@sentry/nextjs\";\n\n`\n : '';\n\n const loggerCall = logsEnabled\n ? ` Sentry.logger.info(\"Sentry example API called\");\n`\n : '';\n\n return `${sentryImport}// Custom error class for Sentry testing\nclass SentryExampleAPIError extends Error {\n constructor(message${isTypeScript ? ': string | undefined' : ''}) {\n super(message);\n this.name = \"SentryExampleAPIError\";\n }\n}\n// A faulty API route to test Sentry's error monitoring\nexport default function handler(_req, res) {\n${loggerCall}throw new SentryExampleAPIError(\"This error is raised on the backend called by the example page.\");\nres.status(200).json({ name: \"John Doe\" });\n}\n`;\n}\n\nexport function getSentryExampleAppDirApiRoute({\n isTypeScript,\n logsEnabled,\n}: {\n isTypeScript: boolean;\n logsEnabled?: boolean;\n}) {\n const sentryImport = logsEnabled\n ? `import * as Sentry from \"@sentry/nextjs\";\n`\n : '';\n\n const loggerCall = logsEnabled\n ? `\n Sentry.logger.info(\"Sentry example API called\");`\n : '';\n\n // Note: We intentionally don't have a return statement after throw - it would be unreachable code\n // We also don't import NextResponse since we don't use it (Biome noUnusedImports rule)\n return `${sentryImport}export const dynamic = \"force-dynamic\";\n\nclass SentryExampleAPIError extends Error {\n constructor(message${isTypeScript ? ': string | undefined' : ''}) {\n super(message);\n this.name = \"SentryExampleAPIError\";\n }\n}\n\n// A faulty API route to test Sentry's error monitoring\nexport function GET() {${loggerCall}\n throw new SentryExampleAPIError(\n \"This error is raised on the backend called by the example page.\",\n );\n}\n`;\n}\n\nexport function getSentryDefaultUnderscoreErrorPage() {\n return `import * as Sentry from \"@sentry/nextjs\";\nimport Error from \"next/error\";\n\nconst CustomErrorComponent = (props) => {\n return <Error statusCode={props.statusCode} />;\n};\n\nCustomErrorComponent.getInitialProps = async (contextData) => {\n // In case this is running in a serverless function, await this in order to give Sentry\n // time to send the error before the lambda exits\n await Sentry.captureUnderscoreErrorException(contextData);\n\n // This will contain the status code of the response\n return Error.getInitialProps(contextData);\n};\n\nexport default CustomErrorComponent;\n`;\n}\n\nexport function getSimpleUnderscoreErrorCopyPasteSnippet() {\n return `\n${chalk.green(`import * as Sentry from '@sentry/nextjs';`)}\n${chalk.green(`import Error from \"next/error\";`)}\n\n${chalk.dim(\n '// Replace \"YourCustomErrorComponent\" with your custom error component!',\n)}\nYourCustomErrorComponent.getInitialProps = async (${chalk.green(\n 'contextData',\n )}) => {\n ${chalk.green('await Sentry.captureUnderscoreErrorException(contextData);')}\n\n ${chalk.dim('// ...other getInitialProps code')}\n\n return Error.getInitialProps(contextData);\n};\n`;\n}\n\nexport function getGenerateMetadataSnippet(isTs: boolean) {\n return makeCodeSnippet(true, (unchanged, plus) => {\n return plus(`\n import * as Sentry from '@sentry/nextjs';\n ${isTs ? `import type { Metadata } from 'next';` : ''}\n\n ${unchanged(\n '// Add or edit your \"generateMetadata\" to include the Sentry trace data:',\n )}\n export function generateMetadata()${isTs ? ': Metadata' : ''} {\n return {\n // ... your existing metadata\n other: {\n ...Sentry.getTraceData()\n }\n };\n }\n`);\n });\n}\n\nexport function getFullUnderscoreErrorCopyPasteSnippet(isTs: boolean) {\n return `\nimport * as Sentry from '@sentry/nextjs';${\n isTs ? '\\nimport type { NextPageContext } from \"next\";' : ''\n }\nimport Error from \"next/error\";\n\n${chalk.dim(\n '// Replace \"YourCustomErrorComponent\" with your custom error component!',\n)}\nYourCustomErrorComponent.getInitialProps = async (contextData${\n isTs ? ': NextPageContext' : ''\n }) => {\n await Sentry.captureUnderscoreErrorException(contextData);\n\n return Error.getInitialProps(contextData);\n};\n`;\n}\n\nexport function getInstrumentationHookContent(\n instrumentationHookLocation: 'src' | 'root',\n) {\n return `import * as Sentry from \"@sentry/nextjs\";\n\nexport async function register() {\n if (process.env.NEXT_RUNTIME === \"nodejs\") {\n await import(\"${\n instrumentationHookLocation === 'root' ? '.' : '..'\n }/sentry.server.config\");\n }\n\n if (process.env.NEXT_RUNTIME === \"edge\") {\n await import(\"${\n instrumentationHookLocation === 'root' ? '.' : '..'\n }/sentry.edge.config\");\n }\n}\n\nexport const onRequestError = Sentry.captureRequestError;\n`;\n}\n\nexport function getInstrumentationHookCopyPasteSnippet(\n instrumentationHookLocation: 'src' | 'root',\n) {\n return makeCodeSnippet(true, (unchanged, plus) => {\n return unchanged(`${plus(\"import * as Sentry from '@sentry/nextjs';\")}\n\nexport ${plus('async')} function register() {\n ${plus(`if (process.env.NEXT_RUNTIME === 'nodejs') {\n await import('${\n instrumentationHookLocation === 'root' ? '.' : '..'\n }/sentry.server.config');\n }\n\n if (process.env.NEXT_RUNTIME === 'edge') {\n await import('${\n instrumentationHookLocation === 'root' ? '.' : '..'\n }/sentry.edge.config');\n }`)}\n}\n\n${plus('export const onRequestError = Sentry.captureRequestError;')}\n`);\n });\n}\n\nexport function getInstrumentationClientHookCopyPasteSnippet(\n dsn: string,\n selectedFeaturesMap: {\n replay: boolean;\n performance: boolean;\n logs: boolean;\n },\n spotlight = false,\n) {\n return makeCodeSnippet(true, (_unchanged, plus) => {\n return plus(\n getInstrumentationClientFileContents(dsn, selectedFeaturesMap, spotlight),\n );\n });\n}\n\nexport function getSentryDefaultGlobalErrorPage(isTs: boolean) {\n return isTs\n ? `\"use client\";\n\nimport * as Sentry from \"@sentry/nextjs\";\nimport NextError from \"next/error\";\nimport { useEffect } from \"react\";\n\nexport default function GlobalError({\n error,\n}: {\n error: Error & { digest?: string };\n}) {\n useEffect(() => {\n Sentry.captureException(error);\n }, [error]);\n\n return (\n <html lang=\"en\">\n <body>\n {/* \\`NextError\\` is the default Next.js error page component. Its type\n definition requires a \\`statusCode\\` prop. However, since the App Router\n does not expose status codes for errors, we simply pass 0 to render a\n generic error message. */}\n <NextError statusCode={0} />\n </body>\n </html>\n );\n}\n`\n : `\"use client\";\n\nimport * as Sentry from \"@sentry/nextjs\";\nimport NextError from \"next/error\";\nimport { useEffect } from \"react\";\n\nexport default function GlobalError({ error }) {\n useEffect(() => {\n Sentry.captureException(error);\n }, [error]);\n\n return (\n <html lang=\"en\">\n <body>\n {/* \\`NextError\\` is the default Next.js error page component. Its type\n definition requires a \\`statusCode\\` prop. However, since the App Router\n does not expose status codes for errors, we simply pass 0 to render a\n generic error message. */}\n <NextError statusCode={0} />\n </body>\n </html>\n );\n}\n`;\n}\n\nexport function getGlobalErrorCopyPasteSnippet(isTs: boolean) {\n if (isTs) {\n return `\"use client\";\n\n${chalk.green('import * as Sentry from \"@sentry/nextjs\";')}\n${chalk.green('import Error from \"next/error\";')}\n${chalk.green('import { useEffect } from \"react\";')}\n\nexport default function GlobalError(${chalk.green(\n '{ error }: { error: Error }',\n )}) {\n ${chalk.green(`useEffect(() => {\n Sentry.captureException(error);\n }, [error]);`)}\n\n return (\n <html>\n <body>\n {/* Your Error component here... */}\n </body>\n </html>\n );\n}\n`;\n }\n return `\"use client\";\n\n${chalk.green('import * as Sentry from \"@sentry/nextjs\";')}\n${chalk.green('import Error from \"next/error\";')}\n${chalk.green('import { useEffect } from \"react\";')}\n\nexport default function GlobalError(${chalk.green('{ error }')}) {\n ${chalk.green(`useEffect(() => {\n Sentry.captureException(error);\n }, [error]);`)}\n\n return (\n <html>\n <body>\n {/* Your Error component here... */}\n </body>\n </html>\n );\n}\n`;\n}\n\nexport const getRootLayout = (\n isTs: boolean,\n) => `// This file was generated by the Sentry wizard because we couldn't find a root layout file.\n// You can delete this file at any time.\n\nexport const metadata = {\n title: 'Sentry NextJS Example',\n description: 'Generated by Sentry',\n}\n\nexport default function RootLayout({\n children,\n}${\n isTs\n ? `: {\n children: React.ReactNode\n}`\n : ''\n}) {\n return (\n <html lang=\"en\">\n <body>{children}</body>\n </html>\n )\n}\n`;\n\nexport const getRootLayoutWithGenerateMetadata = (\n isTs: boolean,\n) => `// This file was generated by the Sentry wizard because we couldn't find a root layout file.\nimport * as Sentry from '@sentry/nextjs';\n${isTs ? `import type { Metadata } from 'next';` : ''}\n\nexport function generateMetadata()${isTs ? ': Metadata' : ''} {\n return {\n other: {\n ...Sentry.getTraceData(),\n }\n }\n};\n\nexport default function RootLayout({\n children,\n}${\n isTs\n ? `: {\n children: React.ReactNode\n}`\n : ''\n}) {\n return (\n <html lang=\"en\">\n <body>{children}</body>\n </html>\n )\n}\n`;\n"]}
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/nextjs/templates.ts"],"names":[],"mappings":"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","sourcesContent":["import chalk from 'chalk';\nimport { makeCodeSnippet } from '../utils/clack';\n\ntype WithSentryConfigOptions = {\n orgSlug: string;\n projectSlug: string;\n selfHosted: boolean;\n sentryUrl: string;\n tunnelRoute: boolean;\n};\n\nexport function getWithSentryConfigOptionsTemplate({\n orgSlug,\n projectSlug,\n selfHosted,\n tunnelRoute,\n sentryUrl,\n}: WithSentryConfigOptions): string {\n return `{\n // For all available options, see:\n // https://www.npmjs.com/package/@sentry/webpack-plugin#options\n\n org: \"${orgSlug}\",\n project: \"${projectSlug}\",${\n selfHosted ? `\\n sentryUrl: \"${sentryUrl}\",` : ''\n }\n\n // Only print logs for uploading source maps in CI\n silent: !process.env.CI,\n\n // For all available options, see:\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/\n\n // Upload a larger set of source maps for prettier stack traces (increases build time)\n widenClientFileUpload: true,\n\n // ${\n tunnelRoute ? 'Route' : 'Uncomment to route'\n } browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers.\n // This can increase your server load as well as your hosting bill.\n // Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client-\n // side errors will fail.\n ${tunnelRoute ? '' : '// '}tunnelRoute: \"/monitoring\",\n\n webpack: {\n // Enables automatic instrumentation of Vercel Cron Monitors. (Does not yet work with App Router route handlers.)\n // See the following for more information:\n // https://docs.sentry.io/product/crons/\n // https://vercel.com/docs/cron-jobs\n automaticVercelMonitors: true,\n\n // Tree-shaking options for reducing bundle size\n treeshake: {\n // Automatically tree-shake Sentry logger statements to reduce bundle size\n removeDebugLogging: true,\n },\n },\n}`;\n}\n\nexport function getNextjsConfigCjsTemplate(\n withSentryConfigOptionsTemplate: string,\n): string {\n return `const { withSentryConfig } = require(\"@sentry/nextjs\");\n\n/** @type {import('next').NextConfig} */\nconst nextConfig = {};\n\nmodule.exports = withSentryConfig(nextConfig, ${withSentryConfigOptionsTemplate});\n`;\n}\n\nexport function getNextjsConfigMjsTemplate(\n withSentryConfigOptionsTemplate: string,\n): string {\n return `import { withSentryConfig } from \"@sentry/nextjs\";\n\n/** @type {import('next').NextConfig} */\nconst nextConfig = {};\n\nexport default withSentryConfig(nextConfig, ${withSentryConfigOptionsTemplate});\n`;\n}\n\nexport function getNextjsConfigCjsAppendix(\n withSentryConfigOptionsTemplate: string,\n): string {\n return `\n\n// Injected content via Sentry wizard below\n\nconst { withSentryConfig } = require(\"@sentry/nextjs\");\n\nmodule.exports = withSentryConfig(module.exports, ${withSentryConfigOptionsTemplate});\n`;\n}\n\nexport function getNextjsConfigEsmCopyPasteSnippet(\n withSentryConfigOptionsTemplate: string,\n): string {\n return `\n\n// next.config.mjs\nimport { withSentryConfig } from \"@sentry/nextjs\";\n\nexport default withSentryConfig(yourNextConfig, ${withSentryConfigOptionsTemplate});\n`;\n}\n\nfunction getClientIntegrationsSnippet(features: { replay: boolean }) {\n if (features.replay) {\n return `\n\n // Add optional integrations for additional features\n integrations: [Sentry.replayIntegration()],`;\n }\n\n return '';\n}\n\nfunction getSpotlightOption(spotlight: boolean): string {\n if (!spotlight) {\n return '';\n }\n\n return `\n\n // Spotlight enabled for local development (https://spotlightjs.com)\n spotlight: true,`;\n}\n\nexport function getSentryServersideConfigContents(\n dsn: string,\n config: 'server' | 'edge',\n selectedFeaturesMap: {\n replay: boolean;\n performance: boolean;\n logs: boolean;\n },\n spotlight = false,\n): string {\n let primer = '';\n if (config === 'server') {\n primer = `// This file configures the initialization of Sentry on the server.\n// The config you add here will be used whenever the server handles a request.\n// https://docs.sentry.io/platforms/javascript/guides/nextjs/`;\n } else if (config === 'edge') {\n primer = `// This file configures the initialization of Sentry for edge features (middleware, edge routes, and so on).\n// The config you add here will be used whenever one of the edge features is loaded.\n// Note that this config is unrelated to the Vercel Edge Runtime and is also required when running locally.\n// https://docs.sentry.io/platforms/javascript/guides/nextjs/`;\n }\n\n let performanceOptions = '';\n if (selectedFeaturesMap.performance) {\n performanceOptions += `\n\n // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.\n tracesSampleRate: 1,`;\n }\n\n let logsOptions = '';\n if (selectedFeaturesMap.logs) {\n logsOptions += `\n\n // Enable logs to be sent to Sentry\n enableLogs: true,`;\n }\n\n const spotlightOptions = getSpotlightOption(spotlight);\n\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n return `${primer}\n\nimport * as Sentry from \"@sentry/nextjs\";\n\nSentry.init({\n dsn: \"${dsn}\",${performanceOptions}${logsOptions}\n\n dataCollection: {\n // To disable sending user data and HTTP bodies, uncomment the lines below. For more info visit:\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options/#dataCollection\n // userInfo: false,\n // httpBodies: [],\n },${spotlightOptions}\n});\n`;\n}\n\nexport function getInstrumentationClientFileContents(\n dsn: string,\n selectedFeaturesMap: {\n replay: boolean;\n performance: boolean;\n logs: boolean;\n },\n spotlight = false,\n): string {\n const integrationsOptions = getClientIntegrationsSnippet({\n replay: selectedFeaturesMap.replay,\n });\n\n let replayOptions = '';\n\n if (selectedFeaturesMap.replay) {\n replayOptions += `\n\n // Define how likely Replay events are sampled.\n // This sets the sample rate to be 10%. You may want this to be 100% while\n // in development and sample at a lower rate in production\n replaysSessionSampleRate: 0.1,\n\n // Define how likely Replay events are sampled when an error occurs.\n replaysOnErrorSampleRate: 1.0,`;\n }\n\n let performanceOptions = '';\n if (selectedFeaturesMap.performance) {\n performanceOptions += `\n\n // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.\n tracesSampleRate: 1,`;\n }\n\n let logsOptions = '';\n if (selectedFeaturesMap.logs) {\n logsOptions += `\n // Enable logs to be sent to Sentry\n enableLogs: true,`;\n }\n\n const spotlightOptions = getSpotlightOption(spotlight);\n\n return `// This file configures the initialization of Sentry on the client.\n// The added config here will be used whenever a users loads a page in their browser.\n// https://docs.sentry.io/platforms/javascript/guides/nextjs/\n\nimport * as Sentry from \"@sentry/nextjs\";\n\nSentry.init({\n dsn: \"${dsn}\",${integrationsOptions}${performanceOptions}${logsOptions}${replayOptions}\n\n dataCollection: {\n // To disable sending user data and HTTP bodies, uncomment the lines below. For more info visit:\n // https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options/#dataCollection\n // userInfo: false,\n // httpBodies: [],\n },${spotlightOptions}\n});\n\nexport const onRouterTransitionStart = Sentry.captureRouterTransitionStart;\n`;\n}\n\nexport function getSentryExamplePageContents(options: {\n selfHosted: boolean;\n sentryUrl: string;\n orgSlug: string;\n projectId: string;\n useClient: boolean;\n isTypeScript?: boolean;\n logsEnabled?: boolean;\n}): string {\n const issuesPageLink = options.selfHosted\n ? `${options.sentryUrl}organizations/${options.orgSlug}/issues/?project=${options.projectId}`\n : `https://${options.orgSlug}.sentry.io/issues/?project=${options.projectId}`;\n\n const loggerPageLoad = options.logsEnabled\n ? `\n Sentry.logger.info(\"Sentry example page loaded\");`\n : '';\n\n const loggerUserAction = options.logsEnabled\n ? `\n Sentry.logger.info(\"User clicked the button, throwing a sample error\");`\n : '';\n\n return `${\n options.useClient ? '\"use client\";\\n\\n' : ''\n }import * as Sentry from \"@sentry/nextjs\";\nimport Head from \"next/head\";\nimport { useEffect, useState } from \"react\";\n\nclass SentryExampleFrontendError extends Error {\n constructor(message${options.isTypeScript ? ': string | undefined' : ''}) {\n super(message);\n this.name = \"SentryExampleFrontendError\";\n }\n}\n\nexport default function Page() {\n const [hasSentError, setHasSentError] = useState(false);\n const [isConnected, setIsConnected] = useState(true);\n\n useEffect(() => {${loggerPageLoad}\n async function checkConnectivity() {\n const result = await Sentry.diagnoseSdkConnectivity();\n setIsConnected(result !== \"sentry-unreachable\");\n }\n checkConnectivity();\n }, []);\n\n return (\n <div>\n <Head>\n <title>sentry-example-page</title>\n <meta name=\"description\" content=\"Test Sentry for your Next.js app!\" />\n </Head>\n\n <main>\n <div className=\"flex-spacer\" />\n <svg\n height=\"40\"\n width=\"40\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n role=\"img\"\n aria-label=\"Sentry logo\"\n >\n <path\n d=\"M21.85 2.995a3.698 3.698 0 0 1 1.353 1.354l16.303 28.278a3.703 3.703 0 0 1-1.354 5.053 3.694 3.694 0 0 1-1.848.496h-3.828a31.149 31.149 0 0 0 0-3.09h3.815a.61.61 0 0 0 .537-.917L20.523 5.893a.61.61 0 0 0-1.057 0l-3.739 6.494a28.948 28.948 0 0 1 9.63 10.453 28.988 28.988 0 0 1 3.499 13.78v1.542h-9.852v-1.544a19.106 19.106 0 0 0-2.182-8.85 19.08 19.08 0 0 0-6.032-6.829l-1.85 3.208a15.377 15.377 0 0 1 6.382 12.484v1.542H3.696A3.694 3.694 0 0 1 0 34.473c0-.648.17-1.286.494-1.849l2.33-4.074a8.562 8.562 0 0 1 2.689 1.536L3.158 34.17a.611.611 0 0 0 .538.917h8.448a12.481 12.481 0 0 0-6.037-9.09l-1.344-.772 4.908-8.545 1.344.77a22.16 22.16 0 0 1 7.705 7.444 22.193 22.193 0 0 1 3.316 10.193h3.699a25.892 25.892 0 0 0-3.811-12.033 25.856 25.856 0 0 0-9.046-8.796l-1.344-.772 5.269-9.136a3.698 3.698 0 0 1 3.2-1.849c.648 0 1.285.17 1.847.495Z\"\n fill=\"currentcolor\"\n />\n </svg>\n <h1>sentry-example-page</h1>\n\n <p className=\"description\">\n Click the button below, and view the sample error on the Sentry{\" \"}\n <a\n target=\"_blank\"\n rel=\"noopener\"\n href=\"${issuesPageLink}\"\n >\n Issues Page\n </a>\n . For more details about setting up Sentry,{\" \"}\n <a\n target=\"_blank\"\n rel=\"noopener\"\n href=\"https://docs.sentry.io/platforms/javascript/guides/nextjs/\"\n >\n read our docs\n </a>\n .\n </p>\n\n <button\n type=\"button\"\n onClick={async () => {${loggerUserAction}\n await Sentry.startSpan(\n {\n name: \"Example Frontend/Backend Span\",\n op: \"test\",\n },\n async () => {\n const res = await fetch(\"/api/sentry-example-api\");\n if (!res.ok) {\n setHasSentError(true);\n }\n },\n );\n throw new SentryExampleFrontendError(\n \"This error is raised on the frontend of the example page.\",\n );\n }}\n disabled={!isConnected}\n >\n <span>Throw Sample Error</span>\n </button>\n\n {hasSentError ? (\n <p className=\"success\">Error sent to Sentry.</p>\n ) : !isConnected ? (\n <div className=\"connectivity-error\">\n <p>\n It looks like network requests to Sentry are being blocked, which\n will prevent errors from being captured. Try disabling your\n ad-blocker to complete the test.\n </p>\n </div>\n ) : (\n <div className=\"success_placeholder\" />\n )}\n\n <div className=\"flex-spacer\" />\n </main>\n\n <style>{\\`\n main {\n display: flex;\n min-height: 100vh;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n gap: 16px;\n padding: 16px;\n font-family: system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", sans-serif;\n }\n\n h1 {\n padding: 0px 4px;\n border-radius: 4px;\n background-color: rgba(24, 20, 35, 0.03);\n font-family: monospace;\n font-size: 20px;\n line-height: 1.2;\n }\n\n p {\n margin: 0;\n font-size: 20px;\n }\n\n a {\n color: #6341F0;\n text-decoration: underline;\n cursor: pointer;\n\n @media (prefers-color-scheme: dark) {\n color: #B3A1FF;\n }\n }\n\n button {\n border-radius: 8px;\n color: white;\n cursor: pointer;\n background-color: #553DB8;\n border: none;\n padding: 0;\n margin-top: 4px;\n\n & > span {\n display: inline-block;\n padding: 12px 16px;\n border-radius: inherit;\n font-size: 20px;\n font-weight: bold;\n line-height: 1;\n background-color: #7553FF;\n border: 1px solid #553DB8;\n transform: translateY(-4px);\n }\n\n &:hover > span {\n transform: translateY(-8px);\n }\n\n &:active > span {\n transform: translateY(0);\n }\n\n &:disabled {\n\t cursor: not-allowed;\n\t opacity: 0.6;\n\n\t & > span {\n\t transform: translateY(0);\n\t border: none\n\t }\n\t }\n }\n\n .description {\n text-align: center;\n color: #6E6C75;\n max-width: 500px;\n line-height: 1.5;\n font-size: 20px;\n\n @media (prefers-color-scheme: dark) {\n color: #A49FB5;\n }\n }\n\n .flex-spacer {\n flex: 1;\n }\n\n .success {\n padding: 12px 16px;\n border-radius: 8px;\n font-size: 20px;\n line-height: 1;\n background-color: #00F261;\n border: 1px solid #00BF4D;\n color: #181423;\n }\n\n .success_placeholder {\n height: 46px;\n }\n\n .connectivity-error {\n padding: 12px 16px;\n background-color: #E50045;\n border-radius: 8px;\n width: 500px;\n color: #FFFFFF;\n border: 1px solid #A80033;\n text-align: center;\n margin: 0;\n }\n\n .connectivity-error a {\n color: #FFFFFF;\n text-decoration: underline;\n }\n \\`}</style>\n </div>\n );\n}\n`;\n}\n\nexport function getSentryExamplePagesDirApiRoute({\n isTypeScript,\n logsEnabled,\n}: {\n isTypeScript: boolean;\n logsEnabled?: boolean;\n}) {\n const sentryImport = logsEnabled\n ? `import * as Sentry from \"@sentry/nextjs\";\n\n`\n : '';\n\n const loggerCall = logsEnabled\n ? ` Sentry.logger.info(\"Sentry example API called\");\n`\n : '';\n\n return `${sentryImport}// Custom error class for Sentry testing\nclass SentryExampleAPIError extends Error {\n constructor(message${isTypeScript ? ': string | undefined' : ''}) {\n super(message);\n this.name = \"SentryExampleAPIError\";\n }\n}\n// A faulty API route to test Sentry's error monitoring\nexport default function handler(_req, res) {\n${loggerCall}throw new SentryExampleAPIError(\"This error is raised on the backend called by the example page.\");\nres.status(200).json({ name: \"John Doe\" });\n}\n`;\n}\n\nexport function getSentryExampleAppDirApiRoute({\n isTypeScript,\n logsEnabled,\n}: {\n isTypeScript: boolean;\n logsEnabled?: boolean;\n}) {\n const sentryImport = logsEnabled\n ? `import * as Sentry from \"@sentry/nextjs\";\n`\n : '';\n\n const loggerCall = logsEnabled\n ? `\n Sentry.logger.info(\"Sentry example API called\");`\n : '';\n\n // Note: We intentionally don't have a return statement after throw - it would be unreachable code\n // We also don't import NextResponse since we don't use it (Biome noUnusedImports rule)\n return `${sentryImport}export const dynamic = \"force-dynamic\";\n\nclass SentryExampleAPIError extends Error {\n constructor(message${isTypeScript ? ': string | undefined' : ''}) {\n super(message);\n this.name = \"SentryExampleAPIError\";\n }\n}\n\n// A faulty API route to test Sentry's error monitoring\nexport function GET() {${loggerCall}\n throw new SentryExampleAPIError(\n \"This error is raised on the backend called by the example page.\",\n );\n}\n`;\n}\n\nexport function getSentryDefaultUnderscoreErrorPage() {\n return `import * as Sentry from \"@sentry/nextjs\";\nimport Error from \"next/error\";\n\nconst CustomErrorComponent = (props) => {\n return <Error statusCode={props.statusCode} />;\n};\n\nCustomErrorComponent.getInitialProps = async (contextData) => {\n // In case this is running in a serverless function, await this in order to give Sentry\n // time to send the error before the lambda exits\n await Sentry.captureUnderscoreErrorException(contextData);\n\n // This will contain the status code of the response\n return Error.getInitialProps(contextData);\n};\n\nexport default CustomErrorComponent;\n`;\n}\n\nexport function getSimpleUnderscoreErrorCopyPasteSnippet() {\n return `\n${chalk.green(`import * as Sentry from '@sentry/nextjs';`)}\n${chalk.green(`import Error from \"next/error\";`)}\n\n${chalk.dim(\n '// Replace \"YourCustomErrorComponent\" with your custom error component!',\n)}\nYourCustomErrorComponent.getInitialProps = async (${chalk.green(\n 'contextData',\n )}) => {\n ${chalk.green('await Sentry.captureUnderscoreErrorException(contextData);')}\n\n ${chalk.dim('// ...other getInitialProps code')}\n\n return Error.getInitialProps(contextData);\n};\n`;\n}\n\nexport function getGenerateMetadataSnippet(isTs: boolean) {\n return makeCodeSnippet(true, (unchanged, plus) => {\n return plus(`\n import * as Sentry from '@sentry/nextjs';\n ${isTs ? `import type { Metadata } from 'next';` : ''}\n\n ${unchanged(\n '// Add or edit your \"generateMetadata\" to include the Sentry trace data:',\n )}\n export function generateMetadata()${isTs ? ': Metadata' : ''} {\n return {\n // ... your existing metadata\n other: {\n ...Sentry.getTraceData()\n }\n };\n }\n`);\n });\n}\n\nexport function getFullUnderscoreErrorCopyPasteSnippet(isTs: boolean) {\n return `\nimport * as Sentry from '@sentry/nextjs';${\n isTs ? '\\nimport type { NextPageContext } from \"next\";' : ''\n }\nimport Error from \"next/error\";\n\n${chalk.dim(\n '// Replace \"YourCustomErrorComponent\" with your custom error component!',\n)}\nYourCustomErrorComponent.getInitialProps = async (contextData${\n isTs ? ': NextPageContext' : ''\n }) => {\n await Sentry.captureUnderscoreErrorException(contextData);\n\n return Error.getInitialProps(contextData);\n};\n`;\n}\n\nexport function getInstrumentationHookContent(\n instrumentationHookLocation: 'src' | 'root',\n) {\n return `import * as Sentry from \"@sentry/nextjs\";\n\nexport async function register() {\n if (process.env.NEXT_RUNTIME === \"nodejs\") {\n await import(\"${\n instrumentationHookLocation === 'root' ? '.' : '..'\n }/sentry.server.config\");\n }\n\n if (process.env.NEXT_RUNTIME === \"edge\") {\n await import(\"${\n instrumentationHookLocation === 'root' ? '.' : '..'\n }/sentry.edge.config\");\n }\n}\n\nexport const onRequestError = Sentry.captureRequestError;\n`;\n}\n\nexport function getInstrumentationHookCopyPasteSnippet(\n instrumentationHookLocation: 'src' | 'root',\n) {\n return makeCodeSnippet(true, (unchanged, plus) => {\n return unchanged(`${plus(\"import * as Sentry from '@sentry/nextjs';\")}\n\nexport ${plus('async')} function register() {\n ${plus(`if (process.env.NEXT_RUNTIME === 'nodejs') {\n await import('${\n instrumentationHookLocation === 'root' ? '.' : '..'\n }/sentry.server.config');\n }\n\n if (process.env.NEXT_RUNTIME === 'edge') {\n await import('${\n instrumentationHookLocation === 'root' ? '.' : '..'\n }/sentry.edge.config');\n }`)}\n}\n\n${plus('export const onRequestError = Sentry.captureRequestError;')}\n`);\n });\n}\n\nexport function getInstrumentationClientHookCopyPasteSnippet(\n dsn: string,\n selectedFeaturesMap: {\n replay: boolean;\n performance: boolean;\n logs: boolean;\n },\n spotlight = false,\n) {\n return makeCodeSnippet(true, (_unchanged, plus) => {\n return plus(\n getInstrumentationClientFileContents(dsn, selectedFeaturesMap, spotlight),\n );\n });\n}\n\nexport function getSentryDefaultGlobalErrorPage(isTs: boolean) {\n return isTs\n ? `\"use client\";\n\nimport * as Sentry from \"@sentry/nextjs\";\nimport NextError from \"next/error\";\nimport { useEffect } from \"react\";\n\nexport default function GlobalError({\n error,\n}: {\n error: Error & { digest?: string };\n}) {\n useEffect(() => {\n Sentry.captureException(error);\n }, [error]);\n\n return (\n <html lang=\"en\">\n <body>\n {/* \\`NextError\\` is the default Next.js error page component. Its type\n definition requires a \\`statusCode\\` prop. However, since the App Router\n does not expose status codes for errors, we simply pass 0 to render a\n generic error message. */}\n <NextError statusCode={0} />\n </body>\n </html>\n );\n}\n`\n : `\"use client\";\n\nimport * as Sentry from \"@sentry/nextjs\";\nimport NextError from \"next/error\";\nimport { useEffect } from \"react\";\n\nexport default function GlobalError({ error }) {\n useEffect(() => {\n Sentry.captureException(error);\n }, [error]);\n\n return (\n <html lang=\"en\">\n <body>\n {/* \\`NextError\\` is the default Next.js error page component. Its type\n definition requires a \\`statusCode\\` prop. However, since the App Router\n does not expose status codes for errors, we simply pass 0 to render a\n generic error message. */}\n <NextError statusCode={0} />\n </body>\n </html>\n );\n}\n`;\n}\n\nexport function getGlobalErrorCopyPasteSnippet(isTs: boolean) {\n if (isTs) {\n return `\"use client\";\n\n${chalk.green('import * as Sentry from \"@sentry/nextjs\";')}\n${chalk.green('import Error from \"next/error\";')}\n${chalk.green('import { useEffect } from \"react\";')}\n\nexport default function GlobalError(${chalk.green(\n '{ error }: { error: Error }',\n )}) {\n ${chalk.green(`useEffect(() => {\n Sentry.captureException(error);\n }, [error]);`)}\n\n return (\n <html>\n <body>\n {/* Your Error component here... */}\n </body>\n </html>\n );\n}\n`;\n }\n return `\"use client\";\n\n${chalk.green('import * as Sentry from \"@sentry/nextjs\";')}\n${chalk.green('import Error from \"next/error\";')}\n${chalk.green('import { useEffect } from \"react\";')}\n\nexport default function GlobalError(${chalk.green('{ error }')}) {\n ${chalk.green(`useEffect(() => {\n Sentry.captureException(error);\n }, [error]);`)}\n\n return (\n <html>\n <body>\n {/* Your Error component here... */}\n </body>\n </html>\n );\n}\n`;\n}\n\nexport const getRootLayout = (\n isTs: boolean,\n) => `// This file was generated by the Sentry wizard because we couldn't find a root layout file.\n// You can delete this file at any time.\n\nexport const metadata = {\n title: 'Sentry NextJS Example',\n description: 'Generated by Sentry',\n}\n\nexport default function RootLayout({\n children,\n}${\n isTs\n ? `: {\n children: React.ReactNode\n}`\n : ''\n}) {\n return (\n <html lang=\"en\">\n <body>{children}</body>\n </html>\n )\n}\n`;\n\nexport const getRootLayoutWithGenerateMetadata = (\n isTs: boolean,\n) => `// This file was generated by the Sentry wizard because we couldn't find a root layout file.\nimport * as Sentry from '@sentry/nextjs';\n${isTs ? `import type { Metadata } from 'next';` : ''}\n\nexport function generateMetadata()${isTs ? ': Metadata' : ''} {\n return {\n other: {\n ...Sentry.getTraceData(),\n }\n }\n};\n\nexport default function RootLayout({\n children,\n}${\n isTs\n ? `: {\n children: React.ReactNode\n}`\n : ''\n}) {\n return (\n <html lang=\"en\">\n <body>{children}</body>\n </html>\n )\n}\n`;\n"]}
|
|
@@ -82,9 +82,12 @@ Sentry.init({
|
|
|
82
82
|
// dsn: useRuntimeConfig().public.sentry.dsn,
|
|
83
83
|
${getConfigBody(dsn, 'client', selectedFeatures)}
|
|
84
84
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
dataCollection: {
|
|
86
|
+
// To disable sending user data and HTTP bodies, uncomment the lines below. For more info visit:
|
|
87
|
+
// https://docs.sentry.io/platforms/javascript/guides/nuxt/configuration/options/#dataCollection
|
|
88
|
+
// userInfo: false,
|
|
89
|
+
// httpBodies: [],
|
|
90
|
+
},
|
|
88
91
|
|
|
89
92
|
// Setting this option to true will print useful information to the console while you're setting up Sentry.
|
|
90
93
|
debug: false,
|
|
@@ -97,9 +100,12 @@ function getSentryServerConfigContents(dsn, selectedFeatures) {
|
|
|
97
100
|
Sentry.init({
|
|
98
101
|
${getConfigBody(dsn, 'server', selectedFeatures)}
|
|
99
102
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
+
dataCollection: {
|
|
104
|
+
// To disable sending user data and HTTP bodies, uncomment the lines below. For more info visit:
|
|
105
|
+
// https://docs.sentry.io/platforms/javascript/guides/nuxt/configuration/options/#dataCollection
|
|
106
|
+
// userInfo: false,
|
|
107
|
+
// httpBodies: [],
|
|
108
|
+
},
|
|
103
109
|
|
|
104
110
|
// Setting this option to true will print useful information to the console while you're setting up Sentry.
|
|
105
111
|
debug: false,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/nuxt/templates.ts"],"names":[],"mappings":"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","sourcesContent":["import { getIssueStreamUrl } from '../utils/url';\n\ntype SelectedSentryFeatures = {\n performance: boolean;\n replay: boolean;\n logs: boolean;\n};\n\nexport function getDefaultNuxtConfig(): string {\n return `// https://nuxt.com/docs/api/configuration/nuxt-config\nexport default defineNuxtConfig({\n compatibilityDate: '2024-04-03',\n devtools: { enabled: true }\n})\n`;\n}\n\nexport function getNuxtModuleFallbackTemplate(\n options: {\n org: string;\n project: string;\n url: string;\n selfHosted: boolean;\n },\n shouldTopLevelImport: boolean,\n): string {\n return ` modules: [\"@sentry/nuxt/module\"],\n sentry: {\n org: \"${options.org}\",\n project: \"${options.project}\",${\n options.selfHosted ? `\\n url: \"${options.url}\",` : ''\n }\n sourcemaps: { \n // This will delete all .map files in the build output after uploading them to Sentry. Modify as needed.\n // For more information, see: https://docs.sentry.io/platforms/javascript/guides/nuxt/sourcemaps/\n filesToDeleteAfterUpload: ['.*/**/*.map'] \n },${\n shouldTopLevelImport\n ? `\\n autoInjectServerSentry: \"top-level-import\",`\n : ''\n }\n },\n sourcemap: { client: \"hidden\" },`;\n}\n\nexport function getSentryConfigContents(\n dsn: string,\n config: 'client' | 'server',\n selectedFeatures: SelectedSentryFeatures,\n): string {\n if (config === 'client') {\n return getSentryClientConfigContents(dsn, selectedFeatures);\n }\n\n return getSentryServerConfigContents(dsn, selectedFeatures);\n}\n\nconst featuresConfigMap: Record<keyof SelectedSentryFeatures, string> = {\n performance: [\n ' // We recommend adjusting this value in production, or using tracesSampler',\n ' // for finer control',\n ' tracesSampleRate: 1.0,',\n ].join('\\n'),\n replay: [\n ' // This sets the sample rate to be 10%. You may want this to be 100% while',\n ' // in development and sample at a lower rate in production',\n ' replaysSessionSampleRate: 0.1,',\n ' ',\n ' // If the entire session is not sampled, use the below sample rate to sample',\n ' // sessions when an error occurs.',\n ' replaysOnErrorSampleRate: 1.0,',\n ' ',\n \" // If you don't want to use Session Replay, just remove the line below:\",\n ' integrations: [Sentry.replayIntegration()],',\n ].join('\\n'),\n logs: [' // Enable logs to be sent to Sentry', ' enableLogs: true,'].join(\n '\\n',\n ),\n};\n\nconst featuresMap: Record<\n 'client' | 'server',\n Array<keyof SelectedSentryFeatures>\n> = {\n client: ['performance', 'replay', 'logs'],\n server: ['performance', 'logs'],\n};\n\nexport function getConfigBody(\n dsn: string,\n variant: 'client' | 'server',\n selectedFeatures: SelectedSentryFeatures,\n) {\n return [\n `dsn: \"${dsn}\",`,\n Object.entries(selectedFeatures)\n .map(([feature, activated]: [keyof SelectedSentryFeatures, boolean]) => {\n return featuresMap[variant].includes(feature) && activated\n ? featuresConfigMap[feature]\n : null;\n })\n .filter(Boolean)\n .join('\\n\\n'),\n ]\n .filter(Boolean)\n .join('\\n\\n');\n}\n\nfunction getSentryClientConfigContents(\n dsn: string,\n selectedFeatures: SelectedSentryFeatures,\n): string {\n return `import * as Sentry from \"@sentry/nuxt\";\n\nSentry.init({\n // If set up, you can use your runtime config here\n // dsn: useRuntimeConfig().public.sentry.dsn,\n ${getConfigBody(dsn, 'client', selectedFeatures)}\n\n // Enable sending of user PII (Personally Identifiable Information)\n // https://docs.sentry.io/platforms/javascript/guides/nuxt/configuration/options/#sendDefaultPii\n sendDefaultPii: true,\n\n // Setting this option to true will print useful information to the console while you're setting up Sentry.\n debug: false,\n});\n`;\n}\n\nfunction getSentryServerConfigContents(\n dsn: string,\n selectedFeatures: SelectedSentryFeatures,\n): string {\n return `import * as Sentry from \"@sentry/nuxt\";\n \nSentry.init({\n ${getConfigBody(dsn, 'server', selectedFeatures)}\n\n // Enable sending of user PII (Personally Identifiable Information)\n // https://docs.sentry.io/platforms/javascript/guides/nuxt/configuration/options/#sendDefaultPii\n sendDefaultPii: true,\n\n // Setting this option to true will print useful information to the console while you're setting up Sentry.\n debug: false,\n});\n`;\n}\n\nexport function getIndexRouteTemplate(): string {\n return `<!--\nThis is just to verify the sentry-example-page.\nFeel free to delete this file.\n-->\n\n<template></template>`;\n}\n\nexport function getSentryExamplePageTemplate(options: {\n url: string;\n org: string;\n projectId: string;\n}): string {\n const { url, org, projectId } = options;\n const issuesPageLink = getIssueStreamUrl({ url, orgSlug: org, projectId });\n\n return `<!--\nThis is just a very simple page with a button to throw an example error.\nFeel free to delete this file.\n-->\n\n<script setup>\n import * as Sentry from '@sentry/nuxt';\n\n class SentryExampleFrontendError extends Error {\n constructor(message) {\n super(message);\n this.name = \"SentryExampleFrontendError\";\n }\n }\n\n const hasSentError = ref(false);\n const isConnected = ref(true);\n \n onMounted(async () => {\n try {\n const result = await Sentry.diagnoseSdkConnectivity();\n isConnected.value = result !== 'sentry-unreachable';\n } catch (error) {\n isConnected.value = false;\n }\n });\n \n async function getSentryData() {\n await Sentry.startSpan(\n {\n name: 'Example Frontend Span',\n op: 'test'\n },\n async () => {\n const res = await $fetch('/api/sentry-example-api', { \n method: 'GET',\n ignoreResponseError: true \n }).catch(() => null);\n if (!res) {\n hasSentError.value = true;\n }\n }\n );\n throw new SentryExampleFrontendError(\"This error is raised on the frontend of the example page.\");\n }\n</script>\n\n<template>\n <title>Sentry Onboarding</title>\n <div>\n <main>\n <div class=\"flex-spacer\" />\n <svg height=\"40\" width=\"40\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M21.85 2.995a3.698 3.698 0 0 1 1.353 1.354l16.303 28.278a3.703 3.703 0 0 1-1.354 5.053 3.694 3.694 0 0 1-1.848.496h-3.828a31.149 31.149 0 0 0 0-3.09h3.815a.61.61 0 0 0 .537-.917L20.523 5.893a.61.61 0 0 0-1.057 0l-3.739 6.494a28.948 28.948 0 0 1 9.63 10.453 28.988 28.988 0 0 1 3.499 13.78v1.542h-9.852v-1.544a19.106 19.106 0 0 0-2.182-8.85 19.08 19.08 0 0 0-6.032-6.829l-1.85 3.208a15.377 15.377 0 0 1 6.382 12.484v1.542H3.696A3.694 3.694 0 0 1 0 34.473c0-.648.17-1.286.494-1.849l2.33-4.074a8.562 8.562 0 0 1 2.689 1.536L3.158 34.17a.611.611 0 0 0 .538.917h8.448a12.481 12.481 0 0 0-6.037-9.09l-1.344-.772 4.908-8.545 1.344.77a22.16 22.16 0 0 1 7.705 7.444 22.193 22.193 0 0 1 3.316 10.193h3.699a25.892 25.892 0 0 0-3.811-12.033 25.856 25.856 0 0 0-9.046-8.796l-1.344-.772 5.269-9.136a3.698 3.698 0 0 1 3.2-1.849c.648 0 1.285.17 1.847.495Z\" fill=\"currentcolor\"/>\n </svg>\n <h1>\n sentry-example-page\n </h1>\n\n <p class=\"description\">\n Click the button below, and view the sample error on the Sentry <a target=\"_blank\" href=\"${issuesPageLink}\">Issues Page</a>.\n For more details about setting up Sentry, <a target=\"_blank\" href=\"https://docs.sentry.io/platforms/javascript/guides/nuxt/\">read our docs</a>.\n </p>\n\n <button\n type=\"button\"\n @click=\"getSentryData\"\n :disabled=\"!isConnected\"\n >\n <span>\n Throw Sample Error\n </span>\n </button>\n\n <p v-if=\"hasSentError\" class=\"success\">\n Sample error was sent to Sentry.\n </p>\n <div v-else-if=\"!isConnected\" class=\"connectivity-error\">\n <p>It looks like network requests to Sentry are being blocked, which will prevent errors from being captured. Try disabling your ad-blocker to complete the test.</p>\n </div>\n <div v-else class=\"success_placeholder\" />\n\n <div class=\"flex-spacer\" />\n </main>\n </div>\n</template>\n\n<style scoped>\n :global(body) {\n margin: 0;\n\n @media (prefers-color-scheme: dark) {\n color: #ededed;\n background-color: #0a0a0a;\n }\n }\n\n main {\n display: flex;\n min-height: 100vh;\n box-sizing: border-box;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n gap: 16px;\n padding: 16px;\n font-family: system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", sans-serif;\n }\n\n h1 {\n padding: 0px 4px;\n margin: 0;\n border-radius: 4px;\n background-color: rgba(24, 20, 35, 0.03);\n font-family: monospace;\n font-size: 20px;\n line-height: 1.2;\n }\n\n p {\n margin: 0;\n font-size: 20px;\n }\n\n a {\n color: #6341F0;\n text-decoration: underline;\n cursor: pointer;\n\n @media (prefers-color-scheme: dark) {\n color: #B3A1FF;\n }\n }\n\n button {\n border-radius: 8px;\n color: white;\n cursor: pointer;\n background-color: #553DB8;\n border: none;\n padding: 0;\n margin-top: 4px;\n\n & > span {\n display: inline-block;\n padding: 12px 16px;\n border-radius: inherit;\n font-size: 20px;\n font-weight: bold;\n line-height: 1;\n background-color: #7553FF;\n border: 1px solid #553DB8;\n transform: translateY(-4px);\n }\n\n &:hover > span {\n transform: translateY(-8px);\n }\n\n &:active > span {\n transform: translateY(0); \n }\n\n &:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n\n & > span {\n transform: translateY(0);\n border: none;\n }\n }\n }\n\n .description {\n text-align: center;\n color: #6E6C75;\n max-width: 500px;\n line-height: 1.5;\n font-size: 20px;\n\n @media (prefers-color-scheme: dark) {\n color: #A49FB5;\n }\n }\n\n .flex-spacer {\n flex: 1;\n }\n\n .success {\n padding: 12px 16px;\n border-radius: 8px;\n font-size: 20px;\n line-height: 1;\n background-color: #00F261;\n border: 1px solid #00BF4D;\n color: #181423;\n }\n\n .success_placeholder {\n height: 46px;\n }\n \n .connectivity-error {\n padding: 12px 16px;\n background-color: #E50045;\n border-radius: 8px;\n width: 500px;\n color: #FFFFFF;\n border: 1px solid #A80033;\n text-align: center;\n margin: 0;\n }\n \n .connectivity-error a {\n color: #FFFFFF;\n text-decoration: underline;\n }\n</style>\n\n`;\n}\n\nexport function getSentryExampleApiTemplate() {\n return `// This is just a very simple API route that throws an example error.\n// Feel free to delete this file.\nimport { defineEventHandler } from '#imports';\n\nexport default defineEventHandler(() => {\n throw new Error(\"Sentry Example API Route Error\");\n});\n`;\n}\n\nexport function getSentryErrorButtonTemplate() {\n return `<!--\nThis is just a very simple component that throws an example error.\nFeel free to delete this file.\n-->\n\n<script setup>\n import * as Sentry from '@sentry/nuxt';\n\n const hasSentError = ref(false);\n \n const throwError = () => {\n Sentry.startSpan(\n {\n name: 'Example Frontend Span',\n op: 'test'\n },\n () => {\n hasSentError.value = true;\n throw new Error('Sentry Example Error');\n }\n )\n };\n</script>\n\n<template>\n <div v-if=\"hasSentError\" class=\"success\">\n Sample error was sent to Sentry.\n </div>\n <button v-else @click=\"throwError\">\n <span>Throw Sample Error</span>\n </button>\n</template>\n\n<style scoped>\n button {\n border-radius: 8px;\n color: white;\n cursor: pointer;\n background-color: #553DB8;\n border: none;\n padding: 0;\n margin-top: 4px;\n font-family: system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", sans-serif;\n\n & > span {\n display: inline-block;\n padding: 12px 16px;\n border-radius: inherit;\n font-size: 20px;\n font-weight: bold;\n line-height: 1;\n background-color: #7553FF;\n border: 1px solid #553DB8;\n transform: translateY(-4px);\n }\n\n &:hover > span {\n transform: translateY(-8px);\n }\n\n &:active > span {\n transform: translateY(0);\n }\n }\n\n .success {\n width: max-content;\n padding: 12px 16px;\n border-radius: 8px;\n font-size: 20px;\n line-height: 1;\n background-color: #00F261;\n border: 1px solid #00BF4D;\n color: #181423;\n font-family: system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", sans-serif;\n }\n</style>\n`;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/nuxt/templates.ts"],"names":[],"mappings":"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","sourcesContent":["import { getIssueStreamUrl } from '../utils/url';\n\ntype SelectedSentryFeatures = {\n performance: boolean;\n replay: boolean;\n logs: boolean;\n};\n\nexport function getDefaultNuxtConfig(): string {\n return `// https://nuxt.com/docs/api/configuration/nuxt-config\nexport default defineNuxtConfig({\n compatibilityDate: '2024-04-03',\n devtools: { enabled: true }\n})\n`;\n}\n\nexport function getNuxtModuleFallbackTemplate(\n options: {\n org: string;\n project: string;\n url: string;\n selfHosted: boolean;\n },\n shouldTopLevelImport: boolean,\n): string {\n return ` modules: [\"@sentry/nuxt/module\"],\n sentry: {\n org: \"${options.org}\",\n project: \"${options.project}\",${\n options.selfHosted ? `\\n url: \"${options.url}\",` : ''\n }\n sourcemaps: { \n // This will delete all .map files in the build output after uploading them to Sentry. Modify as needed.\n // For more information, see: https://docs.sentry.io/platforms/javascript/guides/nuxt/sourcemaps/\n filesToDeleteAfterUpload: ['.*/**/*.map'] \n },${\n shouldTopLevelImport\n ? `\\n autoInjectServerSentry: \"top-level-import\",`\n : ''\n }\n },\n sourcemap: { client: \"hidden\" },`;\n}\n\nexport function getSentryConfigContents(\n dsn: string,\n config: 'client' | 'server',\n selectedFeatures: SelectedSentryFeatures,\n): string {\n if (config === 'client') {\n return getSentryClientConfigContents(dsn, selectedFeatures);\n }\n\n return getSentryServerConfigContents(dsn, selectedFeatures);\n}\n\nconst featuresConfigMap: Record<keyof SelectedSentryFeatures, string> = {\n performance: [\n ' // We recommend adjusting this value in production, or using tracesSampler',\n ' // for finer control',\n ' tracesSampleRate: 1.0,',\n ].join('\\n'),\n replay: [\n ' // This sets the sample rate to be 10%. You may want this to be 100% while',\n ' // in development and sample at a lower rate in production',\n ' replaysSessionSampleRate: 0.1,',\n ' ',\n ' // If the entire session is not sampled, use the below sample rate to sample',\n ' // sessions when an error occurs.',\n ' replaysOnErrorSampleRate: 1.0,',\n ' ',\n \" // If you don't want to use Session Replay, just remove the line below:\",\n ' integrations: [Sentry.replayIntegration()],',\n ].join('\\n'),\n logs: [' // Enable logs to be sent to Sentry', ' enableLogs: true,'].join(\n '\\n',\n ),\n};\n\nconst featuresMap: Record<\n 'client' | 'server',\n Array<keyof SelectedSentryFeatures>\n> = {\n client: ['performance', 'replay', 'logs'],\n server: ['performance', 'logs'],\n};\n\nexport function getConfigBody(\n dsn: string,\n variant: 'client' | 'server',\n selectedFeatures: SelectedSentryFeatures,\n) {\n return [\n `dsn: \"${dsn}\",`,\n Object.entries(selectedFeatures)\n .map(([feature, activated]: [keyof SelectedSentryFeatures, boolean]) => {\n return featuresMap[variant].includes(feature) && activated\n ? featuresConfigMap[feature]\n : null;\n })\n .filter(Boolean)\n .join('\\n\\n'),\n ]\n .filter(Boolean)\n .join('\\n\\n');\n}\n\nfunction getSentryClientConfigContents(\n dsn: string,\n selectedFeatures: SelectedSentryFeatures,\n): string {\n return `import * as Sentry from \"@sentry/nuxt\";\n\nSentry.init({\n // If set up, you can use your runtime config here\n // dsn: useRuntimeConfig().public.sentry.dsn,\n ${getConfigBody(dsn, 'client', selectedFeatures)}\n\n dataCollection: {\n // To disable sending user data and HTTP bodies, uncomment the lines below. For more info visit:\n // https://docs.sentry.io/platforms/javascript/guides/nuxt/configuration/options/#dataCollection\n // userInfo: false,\n // httpBodies: [],\n },\n\n // Setting this option to true will print useful information to the console while you're setting up Sentry.\n debug: false,\n});\n`;\n}\n\nfunction getSentryServerConfigContents(\n dsn: string,\n selectedFeatures: SelectedSentryFeatures,\n): string {\n return `import * as Sentry from \"@sentry/nuxt\";\n \nSentry.init({\n ${getConfigBody(dsn, 'server', selectedFeatures)}\n\n dataCollection: {\n // To disable sending user data and HTTP bodies, uncomment the lines below. For more info visit:\n // https://docs.sentry.io/platforms/javascript/guides/nuxt/configuration/options/#dataCollection\n // userInfo: false,\n // httpBodies: [],\n },\n\n // Setting this option to true will print useful information to the console while you're setting up Sentry.\n debug: false,\n});\n`;\n}\n\nexport function getIndexRouteTemplate(): string {\n return `<!--\nThis is just to verify the sentry-example-page.\nFeel free to delete this file.\n-->\n\n<template></template>`;\n}\n\nexport function getSentryExamplePageTemplate(options: {\n url: string;\n org: string;\n projectId: string;\n}): string {\n const { url, org, projectId } = options;\n const issuesPageLink = getIssueStreamUrl({ url, orgSlug: org, projectId });\n\n return `<!--\nThis is just a very simple page with a button to throw an example error.\nFeel free to delete this file.\n-->\n\n<script setup>\n import * as Sentry from '@sentry/nuxt';\n\n class SentryExampleFrontendError extends Error {\n constructor(message) {\n super(message);\n this.name = \"SentryExampleFrontendError\";\n }\n }\n\n const hasSentError = ref(false);\n const isConnected = ref(true);\n \n onMounted(async () => {\n try {\n const result = await Sentry.diagnoseSdkConnectivity();\n isConnected.value = result !== 'sentry-unreachable';\n } catch (error) {\n isConnected.value = false;\n }\n });\n \n async function getSentryData() {\n await Sentry.startSpan(\n {\n name: 'Example Frontend Span',\n op: 'test'\n },\n async () => {\n const res = await $fetch('/api/sentry-example-api', { \n method: 'GET',\n ignoreResponseError: true \n }).catch(() => null);\n if (!res) {\n hasSentError.value = true;\n }\n }\n );\n throw new SentryExampleFrontendError(\"This error is raised on the frontend of the example page.\");\n }\n</script>\n\n<template>\n <title>Sentry Onboarding</title>\n <div>\n <main>\n <div class=\"flex-spacer\" />\n <svg height=\"40\" width=\"40\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M21.85 2.995a3.698 3.698 0 0 1 1.353 1.354l16.303 28.278a3.703 3.703 0 0 1-1.354 5.053 3.694 3.694 0 0 1-1.848.496h-3.828a31.149 31.149 0 0 0 0-3.09h3.815a.61.61 0 0 0 .537-.917L20.523 5.893a.61.61 0 0 0-1.057 0l-3.739 6.494a28.948 28.948 0 0 1 9.63 10.453 28.988 28.988 0 0 1 3.499 13.78v1.542h-9.852v-1.544a19.106 19.106 0 0 0-2.182-8.85 19.08 19.08 0 0 0-6.032-6.829l-1.85 3.208a15.377 15.377 0 0 1 6.382 12.484v1.542H3.696A3.694 3.694 0 0 1 0 34.473c0-.648.17-1.286.494-1.849l2.33-4.074a8.562 8.562 0 0 1 2.689 1.536L3.158 34.17a.611.611 0 0 0 .538.917h8.448a12.481 12.481 0 0 0-6.037-9.09l-1.344-.772 4.908-8.545 1.344.77a22.16 22.16 0 0 1 7.705 7.444 22.193 22.193 0 0 1 3.316 10.193h3.699a25.892 25.892 0 0 0-3.811-12.033 25.856 25.856 0 0 0-9.046-8.796l-1.344-.772 5.269-9.136a3.698 3.698 0 0 1 3.2-1.849c.648 0 1.285.17 1.847.495Z\" fill=\"currentcolor\"/>\n </svg>\n <h1>\n sentry-example-page\n </h1>\n\n <p class=\"description\">\n Click the button below, and view the sample error on the Sentry <a target=\"_blank\" href=\"${issuesPageLink}\">Issues Page</a>.\n For more details about setting up Sentry, <a target=\"_blank\" href=\"https://docs.sentry.io/platforms/javascript/guides/nuxt/\">read our docs</a>.\n </p>\n\n <button\n type=\"button\"\n @click=\"getSentryData\"\n :disabled=\"!isConnected\"\n >\n <span>\n Throw Sample Error\n </span>\n </button>\n\n <p v-if=\"hasSentError\" class=\"success\">\n Sample error was sent to Sentry.\n </p>\n <div v-else-if=\"!isConnected\" class=\"connectivity-error\">\n <p>It looks like network requests to Sentry are being blocked, which will prevent errors from being captured. Try disabling your ad-blocker to complete the test.</p>\n </div>\n <div v-else class=\"success_placeholder\" />\n\n <div class=\"flex-spacer\" />\n </main>\n </div>\n</template>\n\n<style scoped>\n :global(body) {\n margin: 0;\n\n @media (prefers-color-scheme: dark) {\n color: #ededed;\n background-color: #0a0a0a;\n }\n }\n\n main {\n display: flex;\n min-height: 100vh;\n box-sizing: border-box;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n gap: 16px;\n padding: 16px;\n font-family: system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", sans-serif;\n }\n\n h1 {\n padding: 0px 4px;\n margin: 0;\n border-radius: 4px;\n background-color: rgba(24, 20, 35, 0.03);\n font-family: monospace;\n font-size: 20px;\n line-height: 1.2;\n }\n\n p {\n margin: 0;\n font-size: 20px;\n }\n\n a {\n color: #6341F0;\n text-decoration: underline;\n cursor: pointer;\n\n @media (prefers-color-scheme: dark) {\n color: #B3A1FF;\n }\n }\n\n button {\n border-radius: 8px;\n color: white;\n cursor: pointer;\n background-color: #553DB8;\n border: none;\n padding: 0;\n margin-top: 4px;\n\n & > span {\n display: inline-block;\n padding: 12px 16px;\n border-radius: inherit;\n font-size: 20px;\n font-weight: bold;\n line-height: 1;\n background-color: #7553FF;\n border: 1px solid #553DB8;\n transform: translateY(-4px);\n }\n\n &:hover > span {\n transform: translateY(-8px);\n }\n\n &:active > span {\n transform: translateY(0); \n }\n\n &:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n\n & > span {\n transform: translateY(0);\n border: none;\n }\n }\n }\n\n .description {\n text-align: center;\n color: #6E6C75;\n max-width: 500px;\n line-height: 1.5;\n font-size: 20px;\n\n @media (prefers-color-scheme: dark) {\n color: #A49FB5;\n }\n }\n\n .flex-spacer {\n flex: 1;\n }\n\n .success {\n padding: 12px 16px;\n border-radius: 8px;\n font-size: 20px;\n line-height: 1;\n background-color: #00F261;\n border: 1px solid #00BF4D;\n color: #181423;\n }\n\n .success_placeholder {\n height: 46px;\n }\n \n .connectivity-error {\n padding: 12px 16px;\n background-color: #E50045;\n border-radius: 8px;\n width: 500px;\n color: #FFFFFF;\n border: 1px solid #A80033;\n text-align: center;\n margin: 0;\n }\n \n .connectivity-error a {\n color: #FFFFFF;\n text-decoration: underline;\n }\n</style>\n\n`;\n}\n\nexport function getSentryExampleApiTemplate() {\n return `// This is just a very simple API route that throws an example error.\n// Feel free to delete this file.\nimport { defineEventHandler } from '#imports';\n\nexport default defineEventHandler(() => {\n throw new Error(\"Sentry Example API Route Error\");\n});\n`;\n}\n\nexport function getSentryErrorButtonTemplate() {\n return `<!--\nThis is just a very simple component that throws an example error.\nFeel free to delete this file.\n-->\n\n<script setup>\n import * as Sentry from '@sentry/nuxt';\n\n const hasSentError = ref(false);\n \n const throwError = () => {\n Sentry.startSpan(\n {\n name: 'Example Frontend Span',\n op: 'test'\n },\n () => {\n hasSentError.value = true;\n throw new Error('Sentry Example Error');\n }\n )\n };\n</script>\n\n<template>\n <div v-if=\"hasSentError\" class=\"success\">\n Sample error was sent to Sentry.\n </div>\n <button v-else @click=\"throwError\">\n <span>Throw Sample Error</span>\n </button>\n</template>\n\n<style scoped>\n button {\n border-radius: 8px;\n color: white;\n cursor: pointer;\n background-color: #553DB8;\n border: none;\n padding: 0;\n margin-top: 4px;\n font-family: system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", sans-serif;\n\n & > span {\n display: inline-block;\n padding: 12px 16px;\n border-radius: inherit;\n font-size: 20px;\n font-weight: bold;\n line-height: 1;\n background-color: #7553FF;\n border: 1px solid #553DB8;\n transform: translateY(-4px);\n }\n\n &:hover > span {\n transform: translateY(-8px);\n }\n\n &:active > span {\n transform: translateY(0);\n }\n }\n\n .success {\n width: max-content;\n padding: 12px 16px;\n border-radius: 8px;\n font-size: 20px;\n line-height: 1;\n background-color: #00F261;\n border: 1px solid #00BF4D;\n color: #181423;\n font-family: system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", sans-serif;\n }\n</style>\n`;\n}\n"]}
|
|
@@ -14,3 +14,9 @@ export declare function printSentryExpoMigrationOutro(): void;
|
|
|
14
14
|
export declare function patchExpoAppConfig(options: RNCliSetupConfigContent): Promise<void>;
|
|
15
15
|
export declare function addWithSentryToAppConfigJson(appConfigContent: string, options: RNCliSetupConfigContent): string | null;
|
|
16
16
|
export declare function getSentryAppConfigJsonCodeSnippet({ url, project, org, }: Omit<RNCliSetupConfigContent, 'authToken'>): string;
|
|
17
|
+
/**
|
|
18
|
+
* Checks if the project is using Expo's Config Plugins (CNG)
|
|
19
|
+
* It checks by checking if the native folders are in gitignore or not
|
|
20
|
+
* If native folders are in gitignore then we can skip the native properties file step
|
|
21
|
+
*/
|
|
22
|
+
export declare const isExpoCNG: () => Promise<boolean>;
|
|
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
26
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.getSentryAppConfigJsonCodeSnippet = exports.addWithSentryToAppConfigJson = exports.patchExpoAppConfig = exports.printSentryExpoMigrationOutro = exports.SENTRY_PLUGIN_FUNCTION_NAME = exports.DEPRECATED_SENTRY_EXPO_PLUGIN_NAME = exports.SENTRY_EXPO_PLUGIN_NAME = void 0;
|
|
29
|
+
exports.isExpoCNG = exports.getSentryAppConfigJsonCodeSnippet = exports.addWithSentryToAppConfigJson = exports.patchExpoAppConfig = exports.printSentryExpoMigrationOutro = exports.SENTRY_PLUGIN_FUNCTION_NAME = exports.DEPRECATED_SENTRY_EXPO_PLUGIN_NAME = exports.SENTRY_EXPO_PLUGIN_NAME = void 0;
|
|
30
30
|
// @ts-expect-error - clack is ESM and TS complains about that. It works though
|
|
31
31
|
const clack = __importStar(require("@clack/prompts"));
|
|
32
32
|
const chalk_1 = __importDefault(require("chalk"));
|
|
@@ -35,6 +35,7 @@ const os_1 = require("os");
|
|
|
35
35
|
const Sentry = __importStar(require("@sentry/node"));
|
|
36
36
|
const clack_1 = require("../utils/clack");
|
|
37
37
|
const telemetry_1 = require("../telemetry");
|
|
38
|
+
const git_1 = require("./git");
|
|
38
39
|
exports.SENTRY_EXPO_PLUGIN_NAME = '@sentry/react-native/expo';
|
|
39
40
|
exports.DEPRECATED_SENTRY_EXPO_PLUGIN_NAME = 'sentry-expo';
|
|
40
41
|
exports.SENTRY_PLUGIN_FUNCTION_NAME = 'withSentry';
|
|
@@ -155,4 +156,29 @@ exports.getSentryAppConfigJsonCodeSnippet = getSentryAppConfigJsonCodeSnippet;
|
|
|
155
156
|
function isPlainObject(what) {
|
|
156
157
|
return Object.prototype.toString.call(what) === '[object Object]';
|
|
157
158
|
}
|
|
159
|
+
/**
|
|
160
|
+
* Checks if the project is using Expo's Config Plugins (CNG)
|
|
161
|
+
* It checks by checking if the native folders are in gitignore or not
|
|
162
|
+
* If native folders are in gitignore then we can skip the native properties file step
|
|
163
|
+
*/
|
|
164
|
+
const isExpoCNG = async () => {
|
|
165
|
+
const iOSExists = fs.existsSync('ios');
|
|
166
|
+
const androidExists = fs.existsSync('android');
|
|
167
|
+
const anyNativeFolderExists = iOSExists || androidExists;
|
|
168
|
+
if (!anyNativeFolderExists) {
|
|
169
|
+
// Definitely CNG and using prebuild steps
|
|
170
|
+
return true;
|
|
171
|
+
}
|
|
172
|
+
try {
|
|
173
|
+
const [isIosInGitIgnore, isAndroidInGitIgnore] = await Promise.all([
|
|
174
|
+
iOSExists ? (0, git_1.isFolderInGitignore)('ios') : Promise.resolve(true),
|
|
175
|
+
androidExists ? (0, git_1.isFolderInGitignore)('android') : Promise.resolve(true),
|
|
176
|
+
]);
|
|
177
|
+
return isIosInGitIgnore && isAndroidInGitIgnore;
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
exports.isExpoCNG = isExpoCNG;
|
|
158
184
|
//# 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 * 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"]}
|
|
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';\nimport { isFolderInGitignore } from './git';\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\n/**\n * Checks if the project is using Expo's Config Plugins (CNG)\n * It checks by checking if the native folders are in gitignore or not\n * If native folders are in gitignore then we can skip the native properties file step\n */\nexport const isExpoCNG = async (): Promise<boolean> => {\n const iOSExists = fs.existsSync('ios');\n const androidExists = fs.existsSync('android');\n\n const anyNativeFolderExists = iOSExists || androidExists;\n\n if (!anyNativeFolderExists) {\n // Definitely CNG and using prebuild steps\n return true;\n }\n\n try {\n const [isIosInGitIgnore, isAndroidInGitIgnore] = await Promise.all([\n iOSExists ? isFolderInGitignore('ios') : Promise.resolve(true), // If the folder doesn't exist, we can consider it as ignored\n androidExists ? isFolderInGitignore('android') : Promise.resolve(true),\n ]);\n\n return isIosInGitIgnore && isAndroidInGitIgnore;\n } catch (error) {\n return false;\n }\n};\n"]}
|
|
@@ -1 +1,6 @@
|
|
|
1
1
|
export declare function addToGitignore(filepath: string): Promise<boolean>;
|
|
2
|
+
/**
|
|
3
|
+
* Checks if gitignore file contains ios and android folders
|
|
4
|
+
* Processes line by line, ignoring comments and checking for exact patterns
|
|
5
|
+
*/
|
|
6
|
+
export declare const isFolderInGitignore: (folder: string) => Promise<boolean>;
|