@sentry/wizard 2.4.2 → 2.6.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.
Files changed (30) hide show
  1. package/CHANGELOG.md +16 -4
  2. package/dist/NextJs/configs/next.config.template.js +12 -0
  3. package/dist/lib/Helper/MergeConfig.d.ts +1 -0
  4. package/dist/lib/Helper/MergeConfig.js +20 -0
  5. package/dist/lib/Helper/MergeConfig.js.map +1 -0
  6. package/dist/lib/Helper/__tests__/MergeConfig.d.ts +1 -0
  7. package/dist/lib/Helper/__tests__/MergeConfig.js +46 -0
  8. package/dist/lib/Helper/__tests__/MergeConfig.js.map +1 -0
  9. package/dist/lib/Steps/Integrations/NextJs.d.ts +1 -0
  10. package/dist/lib/Steps/Integrations/NextJs.js +134 -51
  11. package/dist/lib/Steps/Integrations/NextJs.js.map +1 -1
  12. package/dist/lib/Steps/Integrations/ReactNative.d.ts +4 -0
  13. package/dist/lib/Steps/Integrations/ReactNative.js +6 -2
  14. package/dist/lib/Steps/Integrations/ReactNative.js.map +1 -1
  15. package/dist/lib/Steps/Integrations/__tests__/ReactNative.js +34 -3
  16. package/dist/lib/Steps/Integrations/__tests__/ReactNative.js.map +1 -1
  17. package/lib/Helper/MergeConfig.ts +18 -0
  18. package/lib/Helper/__tests__/MergeConfig.ts +77 -0
  19. package/lib/Helper/test-fixtures/next.config.1-merged.js +18 -0
  20. package/lib/Helper/test-fixtures/next.config.1.js +6 -0
  21. package/lib/Helper/test-fixtures/next.config.2.js +8 -0
  22. package/lib/Helper/test-fixtures/next.config.3-merged.js +21 -0
  23. package/lib/Helper/test-fixtures/next.config.3.js +9 -0
  24. package/lib/Helper/test-fixtures/next.config.4-merged.js +21 -0
  25. package/lib/Helper/test-fixtures/next.config.4.js +9 -0
  26. package/lib/Steps/Integrations/NextJs.ts +99 -22
  27. package/lib/Steps/Integrations/ReactNative.ts +9 -2
  28. package/lib/Steps/Integrations/__tests__/ReactNative.ts +28 -3
  29. package/package.json +1 -1
  30. package/scripts/NextJs/configs/next.config.template.js +12 -0
@@ -1 +1 @@
1
- {"version":3,"file":"ReactNative.js","sourceRoot":"","sources":["../../../../lib/Steps/Integrations/ReactNative.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable max-lines */\nimport * as fs from 'fs';\nimport { Answers } from 'inquirer';\nimport * as _ from 'lodash';\nimport * as path from 'path';\n\nimport { Args } from '../../Constants';\nimport { exists, matchesContent, matchFiles, patchMatchingFile } from '../../Helper/File';\nimport { dim, green, red, yellow } from '../../Helper/Logging';\nimport { SentryCli } from '../../Helper/SentryCli';\nimport { MobileProject } from './MobileProject';\n\nconst xcode = require('xcode');\n\nexport class ReactNative extends MobileProject {\n protected _answers: Answers;\n protected _sentryCli: SentryCli;\n\n constructor(protected _argv: Args) {\n super(_argv);\n this._sentryCli = new SentryCli(this._argv);\n }\n\n public async emit(answers: Answers): Promise<Answers> {\n if (this._argv.uninstall) {\n return this.uninstall(answers);\n }\n if (!(await this.shouldEmit(answers))) {\n return {};\n }\n\n const sentryCliProperties = this._sentryCli.convertAnswersToProperties(\n answers,\n );\n\n // eslint-disable-next-line no-async-promise-executor\n return new Promise(async (resolve, reject) => {\n const promises = this.getPlatforms(answers).map(\n async (platform: string) => {\n try {\n if (platform === 'ios') {\n await patchMatchingFile(\n 'ios/*.xcodeproj/project.pbxproj',\n this._patchXcodeProj.bind(this),\n );\n dim(`✅ Patched build script in Xcode project.`);\n } else {\n await patchMatchingFile(\n '**/app/build.gradle',\n this._patchBuildGradle.bind(this),\n );\n dim(`✅ Patched build.gradle file.`);\n }\n await this._patchJsSentryInit(platform, answers);\n await this._addSentryProperties(platform, sentryCliProperties);\n dim(`✅ Added sentry.properties file to ${platform}`);\n\n green(`Successfully set up ${platform} for react-native`);\n } catch (e) {\n red(e);\n }\n },\n );\n Promise.all(promises)\n .then(resolve)\n .catch(reject);\n });\n }\n\n public async uninstall(_answers: Answers): Promise<Answers> {\n await patchMatchingFile(\n '**/*.xcodeproj/project.pbxproj',\n this._unpatchXcodeProj.bind(this),\n );\n await patchMatchingFile(\n '**/app/build.gradle',\n this._unpatchBuildGradle.bind(this),\n );\n return {};\n }\n\n protected async _shouldConfigurePlatform(platform: string): Promise<boolean> {\n let result = false;\n\n if (!exists(`${platform}/sentry.properties`)) {\n result = true;\n this.debug(`${platform}/sentry.properties not exists`);\n }\n\n if (!matchesContent('**/*.xcodeproj/project.pbxproj', /sentry-cli/gi)) {\n result = true;\n this.debug('**/*.xcodeproj/project.pbxproj not matched');\n }\n\n if (!matchesContent('**/app/build.gradle', /sentry\\.gradle/gi)) {\n result = true;\n this.debug('**/app/build.gradle not matched');\n }\n\n const regex = /Sentry/gi;\n if (\n exists(`index.${platform}.js`) &&\n !matchesContent(`index.${platform}.js`, regex)\n ) {\n result = true;\n this.debug(`index.${platform}.js not matched`);\n }\n if (exists('App.js') && !matchesContent('App.js', regex)) {\n result = true;\n this.debug('index.js or App.js not matched');\n }\n\n if (this._argv.uninstall) {\n // if we uninstall we need to invert the result so we remove already patched\n // but leave untouched platforms as they are\n return !result;\n }\n\n return result;\n }\n\n private async _patchJsSentryInit(\n platform: string,\n answers: Answers,\n ): Promise<void> {\n const prefixGlob = '{.,./src}';\n const suffixGlob = '@(j|t|cj|mj)s?(x)';\n const platformGlob = `index.${platform}.${suffixGlob}`;\n // rm 0.49 introduced an App.js for both platforms\n const universalGlob = `App.${suffixGlob}`;\n const jsFileGlob = `${prefixGlob}/+(${platformGlob}|${universalGlob})`;\n\n const jsFileToPatch = matchFiles(jsFileGlob);\n if (jsFileToPatch.length !== 0) {\n await patchMatchingFile(\n jsFileGlob,\n this._patchJs.bind(this),\n answers,\n platform,\n );\n dim(`✅ Patched ${jsFileToPatch.join(', ')} file(s).`);\n } else {\n dim(`🚨 Could not find ${platformGlob} nor ${universalGlob} files.`);\n yellow('❓ Please, visit https://docs.sentry.io/platforms/react-native');\n }\n }\n\n private _addSentryProperties(\n platform: string,\n properties: any,\n ): Promise<void> {\n let rv = Promise.resolve();\n\n // This will create the ios/android folder before trying to write\n // sentry.properties in it which would fail otherwise\n if (!fs.existsSync(platform)) {\n dim(`${platform} folder did not exist, creating it.`);\n fs.mkdirSync(platform);\n }\n const fn = path.join(platform, 'sentry.properties');\n\n if (platform === 'android' && properties['cli/executable']) {\n // We don't need to write the sentry-cli path in the properties file\n // since our gradle plugins already pick it up on the correct spot\n delete properties['cli/executable'];\n }\n rv = rv.then(() =>\n fs.writeFileSync(fn, this._sentryCli.dumpProperties(properties)),\n );\n\n return rv;\n }\n\n private _patchJs(\n contents: string,\n _filename: string,\n answers: Answers,\n platform?: string,\n ): Promise<string | null> {\n // since the init call could live in other places too, we really only\n // want to do this if we managed to patch any of the other files as well.\n if (contents.match(/Sentry.config\\(/)) {\n return Promise.resolve(null);\n }\n\n // if we match @sentry\\/react-native somewhere, we already patched the file\n // and no longer need to\n if (contents.match('@sentry/react-native')) {\n return Promise.resolve(contents);\n }\n\n let dsn = '__DSN__';\n this.getPlatforms(answers).forEach((selectedPlatform: string) => {\n if (platform && selectedPlatform === platform) {\n dsn = _.get(answers, 'config.dsn.public', null);\n } else if (platform === undefined) {\n dsn = _.get(answers, 'config.dsn.public', null);\n }\n });\n\n return Promise.resolve(\n contents.replace(\n /^([^]*)(import\\s+[^;]*?;$)/m,\n match =>\n // eslint-disable-next-line prefer-template\n match +\n \"\\n\\nimport * as Sentry from '@sentry/react-native';\\n\\n\" +\n `Sentry.init({ \\n` +\n ` dsn: '${dsn}', \\n` +\n `});\\n`,\n ),\n );\n }\n\n // ANDROID -----------------------------------------\n\n private _patchBuildGradle(contents: string): Promise<string | null> {\n const applyFrom =\n 'apply from: \"../../node_modules/@sentry/react-native/sentry.gradle\"';\n if (contents.indexOf(applyFrom) >= 0) {\n return Promise.resolve(null);\n }\n return Promise.resolve(\n contents.replace(\n /^apply from: \"..\\/..\\/node_modules\\/react-native\\/react.gradle\"/m,\n // eslint-disable-next-line prefer-template\n match => match + '\\n' + applyFrom,\n ),\n );\n }\n\n private _unpatchBuildGradle(contents: string): Promise<string> {\n return Promise.resolve(\n contents.replace(\n /^\\s*apply from: [\"']..\\/..\\/node_modules\\/@sentry\\/react-native\\/sentry.gradle[\"'];?\\s*?\\r?\\n/m,\n '',\n ),\n );\n }\n\n // IOS -----------------------------------------\n\n private _patchExistingXcodeBuildScripts(buildScripts: any): void {\n for (const script of buildScripts) {\n if (\n !script.shellScript.match(\n /\\/scripts\\/react-native-xcode\\.sh/i,\n ) ||\n script.shellScript.match(/sentry-cli\\s+react-native\\s+xcode/i)\n ) {\n continue;\n }\n let code = JSON.parse(script.shellScript);\n code =\n // eslint-disable-next-line prefer-template\n 'export SENTRY_PROPERTIES=sentry.properties\\n' +\n 'export EXTRA_PACKAGER_ARGS=\"--sourcemap-output $DERIVED_FILE_DIR/main.jsbundle.map\"\\n' +\n code.replace(\n '$REACT_NATIVE_XCODE',\n () =>\n // eslint-disable-next-line no-useless-escape\n '\\\\\\\"../node_modules/@sentry/cli/bin/sentry-cli react-native xcode $REACT_NATIVE_XCODE\\\\\\\"',\n ) +\n '\\n/bin/sh ../node_modules/@sentry/react-native/scripts/collect-modules.sh\\n';\n script.shellScript = JSON.stringify(code);\n }\n }\n\n private _addNewXcodeBuildPhaseForSymbols(buildScripts: any, proj: any): void {\n for (const script of buildScripts) {\n if (script.shellScript.match(/sentry-cli\\s+(upload-dsym|debug-files upload)/)) {\n return;\n }\n }\n\n proj.addBuildPhase(\n [],\n 'PBXShellScriptBuildPhase',\n 'Upload Debug Symbols to Sentry',\n null,\n {\n shellPath: '/bin/sh',\n shellScript:`\nexport SENTRY_PROPERTIES=sentry.properties\n[[ $SENTRY_INCLUDE_NATIVE_SOURCES == \"true\" ]] && INCLUDE_SOURCES_FLAG=\"--include-sources\" || INCLUDE_SOURCES_FLAG=\"\"\n../node_modules/@sentry/cli/bin/sentry-cli debug-files upload \"$INCLUDE_SOURCES_FLAG\"\n`,\n },\n );\n }\n\n private _patchXcodeProj(contents: string, filename: string): Promise<string> {\n const proj = xcode.project(filename);\n return new Promise((resolve, reject) => {\n proj.parse((err: any) => {\n if (err) {\n reject(err);\n return;\n }\n\n const buildScripts = [];\n for (const key in proj.hash.project.objects.PBXShellScriptBuildPhase ||\n {}) {\n if (\n // eslint-disable-next-line no-prototype-builtins\n proj.hash.project.objects.PBXShellScriptBuildPhase.hasOwnProperty(\n key,\n )\n ) {\n const val = proj.hash.project.objects.PBXShellScriptBuildPhase[key];\n if (val.isa) {\n buildScripts.push(val);\n }\n }\n }\n\n try {\n this._patchExistingXcodeBuildScripts(buildScripts);\n } catch (e) {\n red(e);\n }\n try {\n this._addNewXcodeBuildPhaseForSymbols(buildScripts, proj);\n } catch (e) {\n red(e);\n }\n\n // we always modify the xcode file in memory but we only want to save it\n // in case the user wants configuration for ios. This is why we check\n // here first if changes are made before we might prompt the platform\n // continue prompt.\n const newContents = proj.writeSync();\n if (newContents === contents) {\n resolve();\n } else {\n resolve(newContents);\n }\n });\n });\n }\n\n private _unpatchXcodeBuildScripts(proj: any): void {\n const scripts = proj.hash.project.objects.PBXShellScriptBuildPhase || {};\n const firstTarget = proj.getFirstTarget().uuid;\n const nativeTargets = proj.hash.project.objects.PBXNativeTarget;\n\n // scripts to patch partially. Run this first so that we don't\n // accidentally delete some scripts later entirely that we only want to\n // rewrite.\n for (const key of Object.keys(scripts)) {\n const script = scripts[key];\n\n // ignore comments\n if (typeof script === 'string') {\n continue;\n }\n\n // ignore scripts that do not invoke the react-native-xcode command.\n if (!script.shellScript.match(/sentry-cli\\s+react-native\\s+xcode/i)) {\n continue;\n }\n\n script.shellScript = JSON.stringify(\n JSON.parse(script.shellScript)\n // remove sentry properties export\n .replace(/^export SENTRY_PROPERTIES=sentry.properties\\r?\\n/m, '')\n .replace(/^\\/bin\\/sh ..\\/node_modules\\/@sentry\\/react-native\\/scripts\\/collect-modules.sh\\r?\\n/m, '')\n // unwrap react-native-xcode.sh command. In case someone replaced it\n // entirely with the sentry-cli command we need to put the original\n // version back in.\n .replace(\n /\\.\\.\\/node_modules\\/@sentry\\/cli\\/bin\\/sentry-cli\\s+react-native\\s+xcode\\s+\\$REACT_NATIVE_XCODE/i,\n '$REACT_NATIVE_XCODE',\n ),\n );\n }\n\n // scripts to kill entirely.\n for (const key of Object.keys(scripts)) {\n const script = scripts[key];\n\n // ignore comments and keys that got deleted\n if (typeof script === 'string' || script === undefined) {\n continue;\n }\n\n if (\n script.shellScript.match(\n /@sentry\\/cli\\/bin\\/sentry-cli\\s+(upload-dsym|debug-files upload)\\b/,\n )\n ) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete scripts[key];\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete scripts[`${key}_comment`];\n const phases = nativeTargets[firstTarget].buildPhases;\n if (phases) {\n for (let i = 0; i < phases.length; i++) {\n if (phases[i].value === key) {\n phases.splice(i, 1);\n break;\n }\n }\n }\n continue;\n }\n }\n }\n\n private _unpatchXcodeProj(\n _contents: string,\n filename: string,\n ): Promise<string> {\n const proj = xcode.project(filename);\n return new Promise((resolve, reject) => {\n proj.parse((err: any) => {\n if (err) {\n reject(err);\n return;\n }\n\n this._unpatchXcodeBuildScripts(proj);\n resolve(proj.writeSync());\n });\n });\n }\n}\n"]}
1
+ {"version":3,"file":"ReactNative.js","sourceRoot":"","sources":["../../../../lib/Steps/Integrations/ReactNative.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable max-lines */\nimport * as fs from 'fs';\nimport { Answers } from 'inquirer';\nimport * as _ from 'lodash';\nimport * as path from 'path';\n\nimport { Args } from '../../Constants';\nimport { exists, matchesContent, matchFiles, patchMatchingFile } from '../../Helper/File';\nimport { dim, green, red, yellow } from '../../Helper/Logging';\nimport { SentryCli } from '../../Helper/SentryCli';\nimport { MobileProject } from './MobileProject';\n\nconst xcode = require('xcode');\n\nexport class ReactNative extends MobileProject {\n\n /**\n * All React Native versions have app/build.gradle with android section.\n */\n private static _buildGradleAndroidSectionBeginning: RegExp = /^android {/m;\n\n protected _answers: Answers;\n protected _sentryCli: SentryCli;\n\n constructor(protected _argv: Args) {\n super(_argv);\n this._sentryCli = new SentryCli(this._argv);\n }\n\n public async emit(answers: Answers): Promise<Answers> {\n if (this._argv.uninstall) {\n return this.uninstall(answers);\n }\n if (!(await this.shouldEmit(answers))) {\n return {};\n }\n\n const sentryCliProperties = this._sentryCli.convertAnswersToProperties(\n answers,\n );\n\n // eslint-disable-next-line no-async-promise-executor\n return new Promise(async (resolve, reject) => {\n const promises = this.getPlatforms(answers).map(\n async (platform: string) => {\n try {\n if (platform === 'ios') {\n await patchMatchingFile(\n 'ios/*.xcodeproj/project.pbxproj',\n this._patchXcodeProj.bind(this),\n );\n dim(`✅ Patched build script in Xcode project.`);\n } else {\n await patchMatchingFile(\n '**/app/build.gradle',\n this._patchBuildGradle.bind(this),\n );\n dim(`✅ Patched build.gradle file.`);\n }\n await this._patchJsSentryInit(platform, answers);\n await this._addSentryProperties(platform, sentryCliProperties);\n dim(`✅ Added sentry.properties file to ${platform}`);\n\n green(`Successfully set up ${platform} for react-native`);\n } catch (e) {\n red(e);\n }\n },\n );\n Promise.all(promises)\n .then(resolve)\n .catch(reject);\n });\n }\n\n public async uninstall(_answers: Answers): Promise<Answers> {\n await patchMatchingFile(\n '**/*.xcodeproj/project.pbxproj',\n this._unpatchXcodeProj.bind(this),\n );\n await patchMatchingFile(\n '**/app/build.gradle',\n this._unpatchBuildGradle.bind(this),\n );\n return {};\n }\n\n protected async _shouldConfigurePlatform(platform: string): Promise<boolean> {\n let result = false;\n\n if (!exists(`${platform}/sentry.properties`)) {\n result = true;\n this.debug(`${platform}/sentry.properties not exists`);\n }\n\n if (!matchesContent('**/*.xcodeproj/project.pbxproj', /sentry-cli/gi)) {\n result = true;\n this.debug('**/*.xcodeproj/project.pbxproj not matched');\n }\n\n if (!matchesContent('**/app/build.gradle', /sentry\\.gradle/gi)) {\n result = true;\n this.debug('**/app/build.gradle not matched');\n }\n\n const regex = /Sentry/gi;\n if (\n exists(`index.${platform}.js`) &&\n !matchesContent(`index.${platform}.js`, regex)\n ) {\n result = true;\n this.debug(`index.${platform}.js not matched`);\n }\n if (exists('App.js') && !matchesContent('App.js', regex)) {\n result = true;\n this.debug('index.js or App.js not matched');\n }\n\n if (this._argv.uninstall) {\n // if we uninstall we need to invert the result so we remove already patched\n // but leave untouched platforms as they are\n return !result;\n }\n\n return result;\n }\n\n private async _patchJsSentryInit(\n platform: string,\n answers: Answers,\n ): Promise<void> {\n const prefixGlob = '{.,./src}';\n const suffixGlob = '@(j|t|cj|mj)s?(x)';\n const platformGlob = `index.${platform}.${suffixGlob}`;\n // rm 0.49 introduced an App.js for both platforms\n const universalGlob = `App.${suffixGlob}`;\n const jsFileGlob = `${prefixGlob}/+(${platformGlob}|${universalGlob})`;\n\n const jsFileToPatch = matchFiles(jsFileGlob);\n if (jsFileToPatch.length !== 0) {\n await patchMatchingFile(\n jsFileGlob,\n this._patchJs.bind(this),\n answers,\n platform,\n );\n dim(`✅ Patched ${jsFileToPatch.join(', ')} file(s).`);\n } else {\n dim(`🚨 Could not find ${platformGlob} nor ${universalGlob} files.`);\n yellow('❓ Please, visit https://docs.sentry.io/platforms/react-native');\n }\n }\n\n private _addSentryProperties(\n platform: string,\n properties: any,\n ): Promise<void> {\n let rv = Promise.resolve();\n\n // This will create the ios/android folder before trying to write\n // sentry.properties in it which would fail otherwise\n if (!fs.existsSync(platform)) {\n dim(`${platform} folder did not exist, creating it.`);\n fs.mkdirSync(platform);\n }\n const fn = path.join(platform, 'sentry.properties');\n\n if (platform === 'android' && properties['cli/executable']) {\n // We don't need to write the sentry-cli path in the properties file\n // since our gradle plugins already pick it up on the correct spot\n delete properties['cli/executable'];\n }\n rv = rv.then(() =>\n fs.writeFileSync(fn, this._sentryCli.dumpProperties(properties)),\n );\n\n return rv;\n }\n\n private _patchJs(\n contents: string,\n _filename: string,\n answers: Answers,\n platform?: string,\n ): Promise<string | null> {\n // since the init call could live in other places too, we really only\n // want to do this if we managed to patch any of the other files as well.\n if (contents.match(/Sentry.config\\(/)) {\n return Promise.resolve(null);\n }\n\n // if we match @sentry\\/react-native somewhere, we already patched the file\n // and no longer need to\n if (contents.match('@sentry/react-native')) {\n return Promise.resolve(contents);\n }\n\n let dsn = '__DSN__';\n this.getPlatforms(answers).forEach((selectedPlatform: string) => {\n if (platform && selectedPlatform === platform) {\n dsn = _.get(answers, 'config.dsn.public', null);\n } else if (platform === undefined) {\n dsn = _.get(answers, 'config.dsn.public', null);\n }\n });\n\n return Promise.resolve(\n contents.replace(\n /^([^]*)(import\\s+[^;]*?;$)/m,\n match =>\n // eslint-disable-next-line prefer-template\n match +\n \"\\n\\nimport * as Sentry from '@sentry/react-native';\\n\\n\" +\n `Sentry.init({ \\n` +\n ` dsn: '${dsn}', \\n` +\n `});\\n`,\n ),\n );\n }\n\n // ANDROID -----------------------------------------\n\n private _patchBuildGradle(contents: string): Promise<string | null> {\n const applyFrom =\n 'apply from: \"../../node_modules/@sentry/react-native/sentry.gradle\"';\n if (contents.indexOf(applyFrom) >= 0) {\n return Promise.resolve(null);\n }\n\n return Promise.resolve(\n contents.replace(\n ReactNative._buildGradleAndroidSectionBeginning,\n // eslint-disable-next-line prefer-template\n match => applyFrom + '\\n' + match,\n ),\n );\n }\n\n private _unpatchBuildGradle(contents: string): Promise<string> {\n return Promise.resolve(\n contents.replace(\n /^\\s*apply from: [\"']..\\/..\\/node_modules\\/@sentry\\/react-native\\/sentry.gradle[\"'];?\\s*?\\r?\\n/m,\n '',\n ),\n );\n }\n\n // IOS -----------------------------------------\n\n private _patchExistingXcodeBuildScripts(buildScripts: any): void {\n for (const script of buildScripts) {\n if (\n !script.shellScript.match(\n /\\/scripts\\/react-native-xcode\\.sh/i,\n ) ||\n script.shellScript.match(/sentry-cli\\s+react-native\\s+xcode/i)\n ) {\n continue;\n }\n let code = JSON.parse(script.shellScript);\n code =\n // eslint-disable-next-line prefer-template\n 'export SENTRY_PROPERTIES=sentry.properties\\n' +\n 'export EXTRA_PACKAGER_ARGS=\"--sourcemap-output $DERIVED_FILE_DIR/main.jsbundle.map\"\\n' +\n code.replace(\n '$REACT_NATIVE_XCODE',\n () =>\n // eslint-disable-next-line no-useless-escape\n '\\\\\\\"../node_modules/@sentry/cli/bin/sentry-cli react-native xcode $REACT_NATIVE_XCODE\\\\\\\"',\n ) +\n '\\n/bin/sh ../node_modules/@sentry/react-native/scripts/collect-modules.sh\\n';\n script.shellScript = JSON.stringify(code);\n }\n }\n\n private _addNewXcodeBuildPhaseForSymbols(buildScripts: any, proj: any): void {\n for (const script of buildScripts) {\n if (script.shellScript.match(/sentry-cli\\s+(upload-dsym|debug-files upload)/)) {\n return;\n }\n }\n\n proj.addBuildPhase(\n [],\n 'PBXShellScriptBuildPhase',\n 'Upload Debug Symbols to Sentry',\n null,\n {\n shellPath: '/bin/sh',\n shellScript:`\nexport SENTRY_PROPERTIES=sentry.properties\n[[ $SENTRY_INCLUDE_NATIVE_SOURCES == \"true\" ]] && INCLUDE_SOURCES_FLAG=\"--include-sources\" || INCLUDE_SOURCES_FLAG=\"\"\n../node_modules/@sentry/cli/bin/sentry-cli debug-files upload \"$INCLUDE_SOURCES_FLAG\"\n`,\n },\n );\n }\n\n private _patchXcodeProj(contents: string, filename: string): Promise<string> {\n const proj = xcode.project(filename);\n return new Promise((resolve, reject) => {\n proj.parse((err: any) => {\n if (err) {\n reject(err);\n return;\n }\n\n const buildScripts = [];\n for (const key in proj.hash.project.objects.PBXShellScriptBuildPhase ||\n {}) {\n if (\n // eslint-disable-next-line no-prototype-builtins\n proj.hash.project.objects.PBXShellScriptBuildPhase.hasOwnProperty(\n key,\n )\n ) {\n const val = proj.hash.project.objects.PBXShellScriptBuildPhase[key];\n if (val.isa) {\n buildScripts.push(val);\n }\n }\n }\n\n try {\n this._patchExistingXcodeBuildScripts(buildScripts);\n } catch (e) {\n red(e);\n }\n try {\n this._addNewXcodeBuildPhaseForSymbols(buildScripts, proj);\n } catch (e) {\n red(e);\n }\n\n // we always modify the xcode file in memory but we only want to save it\n // in case the user wants configuration for ios. This is why we check\n // here first if changes are made before we might prompt the platform\n // continue prompt.\n const newContents = proj.writeSync();\n if (newContents === contents) {\n resolve();\n } else {\n resolve(newContents);\n }\n });\n });\n }\n\n private _unpatchXcodeBuildScripts(proj: any): void {\n const scripts = proj.hash.project.objects.PBXShellScriptBuildPhase || {};\n const firstTarget = proj.getFirstTarget().uuid;\n const nativeTargets = proj.hash.project.objects.PBXNativeTarget;\n\n // scripts to patch partially. Run this first so that we don't\n // accidentally delete some scripts later entirely that we only want to\n // rewrite.\n for (const key of Object.keys(scripts)) {\n const script = scripts[key];\n\n // ignore comments\n if (typeof script === 'string') {\n continue;\n }\n\n // ignore scripts that do not invoke the react-native-xcode command.\n if (!script.shellScript.match(/sentry-cli\\s+react-native\\s+xcode/i)) {\n continue;\n }\n\n script.shellScript = JSON.stringify(\n JSON.parse(script.shellScript)\n // remove sentry properties export\n .replace(/^export SENTRY_PROPERTIES=sentry.properties\\r?\\n/m, '')\n .replace(/^\\/bin\\/sh ..\\/node_modules\\/@sentry\\/react-native\\/scripts\\/collect-modules.sh\\r?\\n/m, '')\n // unwrap react-native-xcode.sh command. In case someone replaced it\n // entirely with the sentry-cli command we need to put the original\n // version back in.\n .replace(\n /\\.\\.\\/node_modules\\/@sentry\\/cli\\/bin\\/sentry-cli\\s+react-native\\s+xcode\\s+\\$REACT_NATIVE_XCODE/i,\n '$REACT_NATIVE_XCODE',\n ),\n );\n }\n\n // scripts to kill entirely.\n for (const key of Object.keys(scripts)) {\n const script = scripts[key];\n\n // ignore comments and keys that got deleted\n if (typeof script === 'string' || script === undefined) {\n continue;\n }\n\n if (\n script.shellScript.match(\n /@sentry\\/cli\\/bin\\/sentry-cli\\s+(upload-dsym|debug-files upload)\\b/,\n )\n ) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete scripts[key];\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete scripts[`${key}_comment`];\n const phases = nativeTargets[firstTarget].buildPhases;\n if (phases) {\n for (let i = 0; i < phases.length; i++) {\n if (phases[i].value === key) {\n phases.splice(i, 1);\n break;\n }\n }\n }\n continue;\n }\n }\n }\n\n private _unpatchXcodeProj(\n _contents: string,\n filename: string,\n ): Promise<string> {\n const proj = xcode.project(filename);\n return new Promise((resolve, reject) => {\n proj.parse((err: any) => {\n if (err) {\n reject(err);\n return;\n }\n\n this._unpatchXcodeBuildScripts(proj);\n resolve(proj.writeSync());\n });\n });\n }\n}\n"]}
@@ -38,6 +38,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  jest.mock('../../../Helper/Logging.ts'); // We mock logging to not pollute the output
40
40
  var fs = require("fs");
41
+ var path = require("path");
41
42
  var process = require("process");
42
43
  var rimraf = require("rimraf");
43
44
  var Constants_1 = require("../../../Constants");
@@ -45,7 +46,9 @@ var ReactNative_1 = require("../ReactNative");
45
46
  var testDir = 'rn-test';
46
47
  var iosIndexJs = 'index.ios.js';
47
48
  var appTsx = 'src/App.tsx';
49
+ var appBuildGradle = 'android/app/build.gradle';
48
50
  var dummyJsContent = 'import React from "react";\n';
51
+ var dummyAppBuildGradleContent = 'apply plugin: "com.facebook.react"\n\nandroid {\n}\n';
49
52
  var testArgs = {
50
53
  debug: false,
51
54
  integration: Constants_1.Integration.reactNative,
@@ -55,7 +58,7 @@ var testArgs = {
55
58
  uninstall: false,
56
59
  url: 'https://not.used',
57
60
  };
58
- var testAnswers = {
61
+ var mockIosAnswers = {
59
62
  shouldConfigurePlatforms: { 'ios': true },
60
63
  config: {
61
64
  dsn: {
@@ -63,6 +66,14 @@ var testAnswers = {
63
66
  },
64
67
  },
65
68
  };
69
+ var mockAndroidAnswers = {
70
+ shouldConfigurePlatforms: { 'android': true },
71
+ config: {
72
+ dsn: {
73
+ public: 'dns.public.com',
74
+ },
75
+ },
76
+ };
66
77
  describe('ReactNative', function () {
67
78
  var defaultCwd = process.cwd();
68
79
  beforeEach(function () {
@@ -70,8 +81,10 @@ describe('ReactNative', function () {
70
81
  fs.mkdirSync(testDir);
71
82
  process.chdir(testDir);
72
83
  fs.writeFileSync(iosIndexJs, dummyJsContent);
73
- fs.mkdirSync('src');
84
+ fs.mkdirSync(path.dirname(appTsx), { recursive: true });
74
85
  fs.writeFileSync(appTsx, dummyJsContent);
86
+ fs.mkdirSync(path.dirname(appBuildGradle), { recursive: true });
87
+ fs.writeFileSync(appBuildGradle, dummyAppBuildGradleContent);
75
88
  });
76
89
  afterEach(function () {
77
90
  process.chdir(defaultCwd);
@@ -83,7 +96,7 @@ describe('ReactNative', function () {
83
96
  switch (_a.label) {
84
97
  case 0:
85
98
  project = new ReactNative_1.ReactNative(testArgs);
86
- return [4 /*yield*/, project.emit(testAnswers)];
99
+ return [4 /*yield*/, project.emit(mockIosAnswers)];
87
100
  case 1:
88
101
  _a.sent();
89
102
  patchedIosIndexJs = fs.readFileSync(iosIndexJs, 'utf8');
@@ -99,5 +112,23 @@ describe('ReactNative', function () {
99
112
  }
100
113
  });
101
114
  }); });
115
+ test('patches android app build gradle file', function () { return __awaiter(void 0, void 0, void 0, function () {
116
+ var project, patchedAppBuildGradle, expectedPatch;
117
+ return __generator(this, function (_a) {
118
+ switch (_a.label) {
119
+ case 0:
120
+ project = new ReactNative_1.ReactNative(testArgs);
121
+ return [4 /*yield*/, project.emit(mockAndroidAnswers)];
122
+ case 1:
123
+ _a.sent();
124
+ patchedAppBuildGradle = fs.readFileSync(appBuildGradle, 'utf8');
125
+ expectedPatch = 'apply plugin: "com.facebook.react"\n\n' +
126
+ 'apply from: "../../node_modules/@sentry/react-native/sentry.gradle"\n' +
127
+ 'android {\n}\n';
128
+ expect(patchedAppBuildGradle).toEqual(expectedPatch);
129
+ return [2 /*return*/];
130
+ }
131
+ });
132
+ }); });
102
133
  });
103
134
  //# sourceMappingURL=ReactNative.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ReactNative.js","sourceRoot":"","sources":["../../../../../lib/Steps/Integrations/__tests__/ReactNative.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAI,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC,CAAC,4CAA4C;AACrF,uBAAyB;AAEzB,iCAAmC;AACnC,+BAAiC;AAEjC,gDAAiE;AACjE,8CAA6C;AAE7C,IAAM,OAAO,GAAG,SAAS,CAAC;AAC1B,IAAM,UAAU,GAAG,cAAc,CAAC;AAClC,IAAM,MAAM,GAAG,aAAa,CAAC;AAE7B,IAAM,cAAc,GAAG,8BAA8B,CAAC;AAEtD,IAAM,QAAQ,GAAG;IACf,KAAK,EAAE,KAAK;IACZ,WAAW,EAAE,uBAAW,CAAC,WAAW;IACpC,QAAQ,EAAE,CAAC,oBAAQ,CAAC,GAAG,CAAC;IACxB,KAAK,EAAE,IAAI;IACX,WAAW,EAAE,IAAI;IACjB,SAAS,EAAE,KAAK;IAChB,GAAG,EAAE,kBAAkB;CACxB,CAAC;AAEF,IAAM,WAAW,GAAY;IAC3B,wBAAwB,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE;IACzC,MAAM,EAAE;QACN,GAAG,EAAE;YACH,MAAM,EAAE,gBAAgB;SACzB;KACF;CACF,CAAC;AAEF,QAAQ,CAAC,aAAa,EAAE;IAEtB,IAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAEjC,UAAU,CAAC;QACT,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACrB,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACtB,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACvB,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;QAC7C,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACpB,EAAE,CAAC,aAAa,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC;QACR,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAC1B,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,kBAAkB,EAAE;;;;;oBACjB,OAAO,GAAG,IAAI,yBAAW,CAAC,QAAgB,CAAC,CAAC;oBAClD,qBAAM,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,EAAA;;oBAA/B,SAA+B,CAAC;oBAE1B,iBAAiB,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;oBACxD,aAAa,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;oBAChD,aAAa,GAAG,gCAAgC;wBACpD,uDAAuD;wBACvD,kBAAkB;wBAClB,+BAA+B;wBAC/B,SAAS,CAAC;oBACZ,MAAM,CAAC,iBAAiB,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;oBACjD,MAAM,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;;;;SAC9C,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["jest.mock('../../../Helper/Logging.ts'); // We mock logging to not pollute the output\nimport * as fs from 'fs';\nimport { Answers } from 'inquirer';\nimport * as process from 'process';\nimport * as rimraf from 'rimraf';\n\nimport { Args, Integration, Platform } from '../../../Constants';\nimport { ReactNative } from '../ReactNative';\n\nconst testDir = 'rn-test';\nconst iosIndexJs = 'index.ios.js';\nconst appTsx = 'src/App.tsx';\n\nconst dummyJsContent = 'import React from \"react\";\\n';\n\nconst testArgs = {\n debug: false,\n integration: Integration.reactNative,\n platform: [Platform.ios],\n quiet: true,\n skipConnect: true,\n uninstall: false,\n url: 'https://not.used',\n};\n\nconst testAnswers: Answers = {\n shouldConfigurePlatforms: { 'ios': true },\n config: {\n dsn: {\n public: 'dns.public.com',\n },\n },\n};\n\ndescribe('ReactNative', () => {\n\n const defaultCwd = process.cwd();\n\n beforeEach(() => {\n rimraf.sync(testDir);\n fs.mkdirSync(testDir);\n process.chdir(testDir);\n fs.writeFileSync(iosIndexJs, dummyJsContent);\n fs.mkdirSync('src');\n fs.writeFileSync(appTsx, dummyJsContent);\n });\n\n afterEach(() => {\n process.chdir(defaultCwd);\n rimraf.sync(testDir);\n });\n\n test('patches js files', async () => {\n const project = new ReactNative(testArgs as Args);\n await project.emit(testAnswers);\n\n const patchedIosIndexJs = fs.readFileSync(iosIndexJs, 'utf8');\n const patchedAppTsx = fs.readFileSync(appTsx, 'utf8');\n const expectedPatch = 'import React from \"react\";\\n\\n' +\n 'import * as Sentry from \\'@sentry/react-native\\';\\n\\n' +\n 'Sentry.init({ \\n' +\n ' dsn: \\'dns.public.com\\', \\n' +\n '});\\n\\n';\n expect(patchedIosIndexJs).toEqual(expectedPatch);\n expect(patchedAppTsx).toEqual(expectedPatch);\n });\n});\n"]}
1
+ {"version":3,"file":"ReactNative.js","sourceRoot":"","sources":["../../../../../lib/Steps/Integrations/__tests__/ReactNative.ts"],"names":[],"mappings":"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","sourcesContent":["jest.mock('../../../Helper/Logging.ts'); // We mock logging to not pollute the output\nimport * as fs from 'fs';\nimport { Answers } from 'inquirer';\nimport * as path from 'path';\nimport * as process from 'process';\nimport * as rimraf from 'rimraf';\n\nimport { Args, Integration, Platform } from '../../../Constants';\nimport { ReactNative } from '../ReactNative';\n\nconst testDir = 'rn-test';\nconst iosIndexJs = 'index.ios.js';\nconst appTsx = 'src/App.tsx';\nconst appBuildGradle = 'android/app/build.gradle';\n\nconst dummyJsContent = 'import React from \"react\";\\n';\nconst dummyAppBuildGradleContent = 'apply plugin: \"com.facebook.react\"\\n\\nandroid {\\n}\\n';\n\nconst testArgs = {\n debug: false,\n integration: Integration.reactNative,\n platform: [Platform.ios],\n quiet: true,\n skipConnect: true,\n uninstall: false,\n url: 'https://not.used',\n};\n\nconst mockIosAnswers: Answers = {\n shouldConfigurePlatforms: { 'ios': true },\n config: {\n dsn: {\n public: 'dns.public.com',\n },\n },\n};\n\nconst mockAndroidAnswers: Answers = {\n shouldConfigurePlatforms: { 'android': true },\n config: {\n dsn: {\n public: 'dns.public.com',\n },\n },\n};\n\ndescribe('ReactNative', () => {\n\n const defaultCwd = process.cwd();\n\n beforeEach(() => {\n rimraf.sync(testDir);\n fs.mkdirSync(testDir);\n process.chdir(testDir);\n fs.writeFileSync(iosIndexJs, dummyJsContent);\n fs.mkdirSync(path.dirname(appTsx), { recursive: true });\n fs.writeFileSync(appTsx, dummyJsContent);\n fs.mkdirSync(path.dirname(appBuildGradle), { recursive: true });\n fs.writeFileSync(appBuildGradle, dummyAppBuildGradleContent);\n });\n\n afterEach(() => {\n process.chdir(defaultCwd);\n rimraf.sync(testDir);\n });\n\n test('patches js files', async () => {\n const project = new ReactNative(testArgs as Args);\n await project.emit(mockIosAnswers);\n\n const patchedIosIndexJs = fs.readFileSync(iosIndexJs, 'utf8');\n const patchedAppTsx = fs.readFileSync(appTsx, 'utf8');\n const expectedPatch = 'import React from \"react\";\\n\\n' +\n 'import * as Sentry from \\'@sentry/react-native\\';\\n\\n' +\n 'Sentry.init({ \\n' +\n ' dsn: \\'dns.public.com\\', \\n' +\n '});\\n\\n';\n expect(patchedIosIndexJs).toEqual(expectedPatch);\n expect(patchedAppTsx).toEqual(expectedPatch);\n });\n\n test('patches android app build gradle file', async () => {\n const project = new ReactNative(testArgs as Args);\n await project.emit(mockAndroidAnswers);\n\n const patchedAppBuildGradle = fs.readFileSync(appBuildGradle, 'utf8');\n const expectedPatch = 'apply plugin: \"com.facebook.react\"\\n\\n' +\n 'apply from: \"../../node_modules/@sentry/react-native/sentry.gradle\"\\n' +\n 'android {\\n}\\n';\n expect(patchedAppBuildGradle).toEqual(expectedPatch);\n });\n});\n"]}
@@ -0,0 +1,18 @@
1
+ import * as fs from 'fs';
2
+
3
+ // merges the config files
4
+ export function mergeConfigFile(
5
+ sourcePath: string,
6
+ templatePath: string,
7
+ ): boolean {
8
+ try {
9
+ const templateFile = fs.readFileSync(templatePath, 'utf8');
10
+ const sourceFile = fs.readFileSync(sourcePath, 'utf8');
11
+ const newText = templateFile.replace('// ORIGINAL CONFIG', sourceFile);
12
+ Function(newText); // check if the file is valid javascript
13
+ fs.writeFileSync(sourcePath, newText);
14
+ return true;
15
+ } catch (error) {
16
+ return false;
17
+ }
18
+ }
@@ -0,0 +1,77 @@
1
+ /// <reference types="jest" />
2
+ import * as fs from 'fs';
3
+ import * as path from 'path';
4
+
5
+ import { mergeConfigFile } from '../MergeConfig';
6
+
7
+ const configPath = path.join(__dirname, '..', 'test-fixtures/next.config.js');
8
+ const templatePath = path.join(
9
+ __dirname,
10
+ '..',
11
+ '..',
12
+ '..',
13
+ 'scripts/NextJS/configs/next.config.template.js',
14
+ );
15
+
16
+ function configFileNames(num: number): {
17
+ sourcePath: string;
18
+ mergedPath: string;
19
+ } {
20
+ const sourcePath = path.join(
21
+ __dirname,
22
+ '..',
23
+ `test-fixtures/next.config.${num}.js`,
24
+ );
25
+ const mergedPath = path.join(
26
+ __dirname,
27
+ '..',
28
+ `test-fixtures/next.config.${num}-merged.js`,
29
+ );
30
+ return { sourcePath, mergedPath };
31
+ }
32
+
33
+ describe('Merging next.config.js', () => {
34
+ test('merge basic next.config.js', () => {
35
+ const { sourcePath, mergedPath } = configFileNames(1);
36
+ fs.copyFileSync(sourcePath, configPath);
37
+
38
+ expect(mergeConfigFile(configPath, templatePath)).toBe(true);
39
+ expect(
40
+ fs.readFileSync(configPath, 'utf8') ===
41
+ fs.readFileSync(mergedPath, 'utf8'),
42
+ ).toBe(true);
43
+ fs.unlinkSync(configPath);
44
+ });
45
+
46
+ test('merge invalid javascript config', () => {
47
+ const { sourcePath } = configFileNames(2);
48
+ fs.copyFileSync(sourcePath, configPath);
49
+
50
+ expect(mergeConfigFile(configPath, templatePath)).toBe(false);
51
+ fs.unlinkSync(configPath);
52
+ });
53
+
54
+ test('merge more complicated next.config.js', () => {
55
+ const { sourcePath, mergedPath } = configFileNames(3);
56
+ fs.copyFileSync(sourcePath, configPath);
57
+
58
+ expect(mergeConfigFile(configPath, templatePath)).toBe(true);
59
+ expect(
60
+ fs.readFileSync(configPath, 'utf8') ===
61
+ fs.readFileSync(mergedPath, 'utf8'),
62
+ ).toBe(true);
63
+ fs.unlinkSync(configPath);
64
+ });
65
+
66
+ test('merge next.config.js with function', () => {
67
+ const { sourcePath, mergedPath } = configFileNames(4);
68
+ fs.copyFileSync(sourcePath, configPath);
69
+
70
+ expect(mergeConfigFile(configPath, templatePath)).toBe(true);
71
+ expect(
72
+ fs.readFileSync(configPath, 'utf8') ===
73
+ fs.readFileSync(mergedPath, 'utf8'),
74
+ ).toBe(true);
75
+ fs.unlinkSync(configPath);
76
+ });
77
+ });
@@ -0,0 +1,18 @@
1
+ // This file sets a custom webpack configuration to use your Next.js app
2
+ // with Sentry.
3
+ // https://nextjs.org/docs/api-reference/next.config.js/introduction
4
+ // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/
5
+ const { withSentryConfig } = require('@sentry/nextjs');
6
+
7
+ /** @type {import('next').NextConfig} */
8
+ const nextConfig = {
9
+ reactStrictMode: true,
10
+ };
11
+
12
+ module.exports = nextConfig;
13
+
14
+ module.exports = withSentryConfig(
15
+ module.exports,
16
+ { silent: true },
17
+ { hideSourcemaps: true },
18
+ );
@@ -0,0 +1,6 @@
1
+ /** @type {import('next').NextConfig} */
2
+ const nextConfig = {
3
+ reactStrictMode: true,
4
+ };
5
+
6
+ module.exports = nextConfig;
@@ -0,0 +1,8 @@
1
+ /** @type {import('next').NextConfig} */
2
+ const nextConfig = {
3
+ reactStrictMode: true,
4
+
5
+
6
+
7
+
8
+ module.exports = nextConfig;
@@ -0,0 +1,21 @@
1
+ // This file sets a custom webpack configuration to use your Next.js app
2
+ // with Sentry.
3
+ // https://nextjs.org/docs/api-reference/next.config.js/introduction
4
+ // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/
5
+ const { withSentryConfig } = require('@sentry/nextjs');
6
+
7
+ /** @type {import('next').NextConfig} */
8
+ const nextConfig = {
9
+ reactStrictMode: true,
10
+ images: {
11
+ domains: [],
12
+ },
13
+ };
14
+
15
+ module.exports = nextConfig;
16
+
17
+ module.exports = withSentryConfig(
18
+ module.exports,
19
+ { silent: true },
20
+ { hideSourcemaps: true },
21
+ );
@@ -0,0 +1,9 @@
1
+ /** @type {import('next').NextConfig} */
2
+ const nextConfig = {
3
+ reactStrictMode: true,
4
+ images: {
5
+ domains: [],
6
+ },
7
+ };
8
+
9
+ module.exports = nextConfig;
@@ -0,0 +1,21 @@
1
+ // This file sets a custom webpack configuration to use your Next.js app
2
+ // with Sentry.
3
+ // https://nextjs.org/docs/api-reference/next.config.js/introduction
4
+ // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/
5
+ const { withSentryConfig } = require('@sentry/nextjs');
6
+
7
+ module.exports = (phase, { defaultConfig }) => {
8
+ /**
9
+ * @type {import('next').NextConfig}
10
+ */
11
+ const nextConfig = {
12
+ /* config options here */
13
+ };
14
+ return nextConfig;
15
+ };
16
+
17
+ module.exports = withSentryConfig(
18
+ module.exports,
19
+ { silent: true },
20
+ { hideSourcemaps: true },
21
+ );
@@ -0,0 +1,9 @@
1
+ module.exports = (phase, { defaultConfig }) => {
2
+ /**
3
+ * @type {import('next').NextConfig}
4
+ */
5
+ const nextConfig = {
6
+ /* config options here */
7
+ };
8
+ return nextConfig;
9
+ };
@@ -10,6 +10,7 @@ import { promisify } from 'util';
10
10
 
11
11
  import { Args } from '../../Constants';
12
12
  import { debug, green, l, nl, red } from '../../Helper/Logging';
13
+ import { mergeConfigFile } from '../../Helper/MergeConfig';
13
14
  import { SentryCli, SentryCliProps } from '../../Helper/SentryCli';
14
15
  import { BaseIntegration } from './BaseIntegration';
15
16
 
@@ -60,7 +61,7 @@ export class NextJs extends BaseIntegration {
60
61
  const configDirectory = path.join(templateDirectory, CONFIG_DIR);
61
62
 
62
63
  if (fs.existsSync(configDirectory)) {
63
- this._createNextConfig(configDirectory, dsn);
64
+ await this._createNextConfig(configDirectory, dsn);
64
65
  } else {
65
66
  debug(
66
67
  `Couldn't find ${configDirectory}, probably because you ran this from inside of \`/lib\` rather than \`/dist\``,
@@ -74,7 +75,7 @@ export class NextJs extends BaseIntegration {
74
75
  (p: { slug: string }) => p.slug === selectedProjectSlug,
75
76
  )?.firstEvent;
76
77
  if (!hasFirstEvent) {
77
- this._setTemplate(
78
+ await this._setTemplate(
78
79
  templateDirectory,
79
80
  'sentry_sample_error.js',
80
81
  ['pages', 'src/pages'],
@@ -243,10 +244,18 @@ export class NextJs extends BaseIntegration {
243
244
  }
244
245
  }
245
246
 
246
- private _createNextConfig(configDirectory: string, dsn: any): void {
247
+ private async _createNextConfig(
248
+ configDirectory: string,
249
+ dsn: any,
250
+ ): Promise<void> {
247
251
  const templates = fs.readdirSync(configDirectory);
248
- for (const template of templates) {
249
- this._setTemplate(
252
+ // next.config.template.js used for merging next.config.js , not its own template,
253
+ // so it shouldn't have a setTemplate call
254
+ const filteredTemplates = templates.filter(
255
+ (template) => template !== 'next.config.template.js',
256
+ );
257
+ for (const template of filteredTemplates) {
258
+ await this._setTemplate(
250
259
  configDirectory,
251
260
  template,
252
261
  TEMPLATE_DESTINATIONS[template],
@@ -260,19 +269,18 @@ export class NextJs extends BaseIntegration {
260
269
  nl();
261
270
  }
262
271
 
263
- private _setTemplate(
272
+ private async _setTemplate(
264
273
  configDirectory: string,
265
274
  templateFile: string,
266
275
  destinationOptions: string[],
267
276
  dsn: string,
268
- ): void {
277
+ ): Promise<void> {
269
278
  const templatePath = path.join(configDirectory, templateFile);
270
279
 
271
280
  for (const destinationDir of destinationOptions) {
272
281
  if (!fs.existsSync(destinationDir)) {
273
282
  continue;
274
283
  }
275
-
276
284
  const destinationPath = path.join(destinationDir, templateFile);
277
285
  // in case the file in question already exists, we'll make a copy with
278
286
  // `MERGEABLE_CONFIG_INFIX` inserted just before the extension, so as not
@@ -287,23 +295,35 @@ export class NextJs extends BaseIntegration {
287
295
  ).join('.'),
288
296
  );
289
297
 
290
- if (!fs.existsSync(destinationPath)) {
291
- this._fillAndCopyTemplate(templatePath, destinationPath, dsn);
292
- } else if (!fs.existsSync(mergeableFilePath)) {
293
- this._fillAndCopyTemplate(templatePath, mergeableFilePath, dsn);
294
- red(
295
- `File \`${templateFile}\` already exists, so created \`${mergeableFilePath}\`.\n` +
296
- 'Please merge those files.',
298
+ if (templateFile === 'next.config.js') {
299
+ await this._mergeNextConfig(
300
+ destinationPath,
301
+ templatePath,
302
+ destinationDir,
303
+ templateFile,
304
+ configDirectory,
305
+ mergeableFilePath,
297
306
  );
298
- nl();
307
+ return;
299
308
  } else {
300
- red(
301
- `Both \`${templateFile}\` and \`${mergeableFilePath}\` already exist.\n` +
302
- 'Please merge those files.',
303
- );
304
- nl();
309
+ if (!fs.existsSync(destinationPath)) {
310
+ this._fillAndCopyTemplate(templatePath, destinationPath, dsn);
311
+ } else if (!fs.existsSync(mergeableFilePath)) {
312
+ this._fillAndCopyTemplate(templatePath, mergeableFilePath, dsn);
313
+ red(
314
+ `File \`${templateFile}\` already exists, so created \`${mergeableFilePath}\`.\n` +
315
+ 'Please merge those files.',
316
+ );
317
+ nl();
318
+ } else {
319
+ red(
320
+ `Both \`${templateFile}\` and \`${mergeableFilePath}\` already exist.\n` +
321
+ 'Please merge those files.',
322
+ );
323
+ nl();
324
+ }
325
+ return;
305
326
  }
306
- return;
307
327
  }
308
328
 
309
329
  red(
@@ -437,4 +457,61 @@ export class NextJs extends BaseIntegration {
437
457
  arr.splice(start, deleteCount, ...inserts);
438
458
  return arr;
439
459
  }
460
+
461
+ private async _mergeNextConfig(
462
+ destinationPath: string,
463
+ templatePath: string,
464
+ destinationDir: string,
465
+ templateFile: string,
466
+ configDirectory: string,
467
+ mergeableFilePath: string,
468
+ ): Promise<void> {
469
+ // if no next.config.js exists, we'll create one
470
+ if (!fs.existsSync(destinationPath)) {
471
+ fs.copyFileSync(templatePath, destinationPath);
472
+ green('Created File `next.config.js`');
473
+ nl();
474
+ } else {
475
+ // creates a file name for the copy of the original next.config.js file
476
+ // with the name `next.config.original.js`
477
+ const originalFileName = this._spliceInPlace(
478
+ templateFile.split('.'),
479
+ -1,
480
+ 0,
481
+ 'original',
482
+ ).join('.');
483
+ const originalFilePath = path.join(destinationDir, originalFileName);
484
+ // makes copy of original next.config.js
485
+ fs.writeFileSync(originalFilePath, fs.readFileSync(destinationPath));
486
+ await this._addToGitignore(
487
+ originalFilePath,
488
+ 'Unable to add next.config.original.js to gitignore',
489
+ );
490
+
491
+ const mergedTemplatePath = path.join(
492
+ configDirectory,
493
+ 'next.config.template.js',
494
+ );
495
+ // attempts to merge with existing next.config.js, if true -> success
496
+ if (mergeConfigFile(destinationPath, mergedTemplatePath)) {
497
+ green(
498
+ `Updated \`${templateFile}\` with Sentry. The original ${templateFile} was saved as \`next.config.original.js\`.\n` +
499
+ 'Information on the changes made to the Next.js configuration file an be found at https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/',
500
+ );
501
+ nl();
502
+ } else {
503
+ // if merge fails, we'll create a copy of the `next.config.js` template and ask them to merge
504
+ fs.copyFileSync(templatePath, mergeableFilePath);
505
+ await this._addToGitignore(
506
+ mergeableFilePath,
507
+ 'Unable to add next.config.wizard.js template to gitignore',
508
+ );
509
+ red(
510
+ `Unable to merge \`${templateFile}\`, so created \`${mergeableFilePath}\`.\n` +
511
+ 'Please integrate next.config.wizardcopy.js into your next.config.js or next.config.ts file',
512
+ );
513
+ nl();
514
+ }
515
+ }
516
+ }
440
517
  }
@@ -13,6 +13,12 @@ import { MobileProject } from './MobileProject';
13
13
  const xcode = require('xcode');
14
14
 
15
15
  export class ReactNative extends MobileProject {
16
+
17
+ /**
18
+ * All React Native versions have app/build.gradle with android section.
19
+ */
20
+ private static _buildGradleAndroidSectionBeginning: RegExp = /^android {/m;
21
+
16
22
  protected _answers: Answers;
17
23
  protected _sentryCli: SentryCli;
18
24
 
@@ -220,11 +226,12 @@ export class ReactNative extends MobileProject {
220
226
  if (contents.indexOf(applyFrom) >= 0) {
221
227
  return Promise.resolve(null);
222
228
  }
229
+
223
230
  return Promise.resolve(
224
231
  contents.replace(
225
- /^apply from: "..\/..\/node_modules\/react-native\/react.gradle"/m,
232
+ ReactNative._buildGradleAndroidSectionBeginning,
226
233
  // eslint-disable-next-line prefer-template
227
- match => match + '\n' + applyFrom,
234
+ match => applyFrom + '\n' + match,
228
235
  ),
229
236
  );
230
237
  }