diff --git a/.travis.yml b/.travis.yml index 54e7569e5e..44c32e3fef 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,10 @@ branches: only: - master +before_install: + - curl -o- -L https://yarnpkg.com/install.sh | bash + - export PATH="$HOME/.yarn/bin:$PATH" + matrix: include: - language: node_js @@ -44,7 +48,10 @@ matrix: - pip - yarn env: LANE='ios' - before_install: .travis/before_install.sh + before_install: + - curl -o- -L https://yarnpkg.com/install.sh | bash + - export PATH="$HOME/.yarn/bin:$PATH" + - .travis/before_install.sh before_script: - sudo easy_install virtualenv - virtualenv ~/virtualenv @@ -54,6 +61,7 @@ matrix: - language: node_js node_js: 8 script: .travis/deploy.sh + env: LANE='deploy' after_success: - npm install -g @zeus-ci/cli - zeus upload -t "application/tar+npm" *.tgz diff --git a/.travis/before_install.sh b/.travis/before_install.sh index b0594f5eab..aae4b6f245 100755 --- a/.travis/before_install.sh +++ b/.travis/before_install.sh @@ -3,11 +3,9 @@ set -e if [ "$LANE" = "ios" ]; then brew update brew install yarn + brew outdated node || brew upgrade node brew outdated yarn || brew upgrade yarn elif [ "$LANE" = "android" ]; then node --version - curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - - echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list - sudo apt-get update -qq - sudo apt-get install -y -qq yarn + npm install -g yarn fi diff --git a/.travis/run.sh b/.travis/run.sh index 8805754cd3..9c26a9a0dd 100755 --- a/.travis/run.sh +++ b/.travis/run.sh @@ -2,7 +2,7 @@ set -e if [ "$LANE" = "node" ]; then yarn install - npm run test-typescript + npm run test:typescript cd appium npm install -g react-native-cli diff --git a/examples b/examples index 206f193745..7430886808 160000 --- a/examples +++ b/examples @@ -1 +1 @@ -Subproject commit 206f19374559bffd2f09ee000547e5949625db46 +Subproject commit 7430886808df92dbcda9f9ff78a61e8ee8e737ce diff --git a/lib/raven-plugin.js b/lib/raven-plugin.js index 7b3b371dd6..ac76e4ea0d 100644 --- a/lib/raven-plugin.js +++ b/lib/raven-plugin.js @@ -183,11 +183,11 @@ function reactNativePlugin(Raven, options, internalDataCallback) { */ reactNativePlugin._persistPayload = function(payload) { var AsyncStorage = require('react-native').AsyncStorage; - return AsyncStorage.setItem(ASYNC_STORAGE_KEY, JSON.stringify(payload))[ - 'catch' - ](function() { - return null; - }); + return AsyncStorage.setItem(ASYNC_STORAGE_KEY, JSON.stringify(payload))['catch']( + function() { + return null; + } + ); }; /** diff --git a/package.json b/package.json index 7c617a9a46..4ab742a261 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "preversion:changelog": "grep -q -F \"## v$npm_package_version\" CHANGELOG.md", "version": "npm run preversion:changelog && node ./scripts/version-bump.js && git add -A", "precommit": "lint-staged", - "test-typescript": "node_modules/typescript/bin/tsc --noImplicitAny --allowJs typescript/Sentry-tests.ts" + "test:typescript": "node_modules/typescript/bin/tsc --noImplicitAny --allowJs typescript/Sentry-tests.ts" }, "keywords": [ "react-native", @@ -25,17 +25,14 @@ "react-native": ">=0.38.0" }, "dependencies": { - "chalk": "^2.3.0", - "glob": "^7.1.1", - "inquirer": "^3.3.0", "raven-js": "^3.19.1", - "sentry-cli-binary": "^1.21.0", - "xcode": "^1.0.0" + "@sentry/wizard": "^0.6.0", + "sentry-cli-binary": "^1.21.0" }, "rnpm": { "commands": { - "postlink": "node node_modules/react-native-sentry/scripts/postlink.js", - "postunlink": "node node_modules/react-native-sentry/scripts/postunlink.js" + "postlink": "node node_modules/@sentry/wizard/dist/bin.js -t reactNative -p ios android", + "postunlink": "node node_modules/@sentry/wizard/dist/bin.js -t reactNative -p ios android --uninstall" }, "android": { "packageInstance": "new RNSentryPackage(MainApplication.this)" diff --git a/scripts/postlink.js b/scripts/postlink.js deleted file mode 100644 index 3de3060c6b..0000000000 --- a/scripts/postlink.js +++ /dev/null @@ -1,491 +0,0 @@ -const glob = require('glob'); -const fs = require('fs'); -const inquirer = require('inquirer'); -const xcode = require('xcode'); -const chalk = require('chalk'); -const pbxFile = require('xcode/lib/pbxFile'); -const path = require('path'); -const PLATFORMS = ['android', 'ios']; -const OBJC_HEADER = - '\ -#if __has_include()\n\ -#import // This is used for versions of react >= 0.40\n\ -#else\n\ -#import "RNSentry.h" // This is used for versions of react < 0.40\n\ -#endif'; - -let cachedDsn = null; -let cachedProps = {}; -let patchedAny = false; -let didShowInfoHint = false; -let configurePlatform = {}; - -function getPlatformName(platform) { - return ( - { - android: 'Android', - ios: 'iOS' - }[platform] || platform - ); -} - -function considerShowingInfoHint() { - if (didShowInfoHint) { - return; - } - - let {green, dim} = chalk; - function l(msg) { - console.log(msg); - } - - l(''); - l(green('You are about to configure Sentry for React Native')); - l(dim('We will ask you a bunch of questions to configure Sentry for you.')); - l(dim('If you chose not to configure an integration you can run link again')); - l(dim('later to configure that platform.')); - l(''); - l('You will need the DSN and an API key for the application to proceed.'); - l('The keys can be found the project settings and at sentry.io/api/'); - l(''); - didShowInfoHint = true; -} - -function shouldConfigurePlatform(platform) { - if (configurePlatform[platform] !== undefined) { - return Promise.resolve(configurePlatform[platform]); - } - // if a sentry.properties file exists for the platform we want to configure - // without asking the user. This means that re-linking later will not - // bring up a useless dialog. - if ( - fs.existsSync(platform + '/sentry.properties') || - fs.existsSync(process.cwd() + platform + '/sentry.properties') - ) { - configurePlatform[platform] = true; - let {dim} = chalk; - console.log(dim(platform + '/sentry.properties already exists')); - return Promise.resolve(true); - } - - considerShowingInfoHint(); - return inquirer - .prompt([ - { - type: 'list', - name: 'configure', - message: `Do you want to configure Sentry for ${getPlatformName(platform)}?`, - choices: [ - { - name: 'Yes', - value: true - }, - { - name: 'No (or later)', - value: false - } - ] - } - ]) - .then(function(answers) { - configurePlatform[platform] = answers.configure; - return Promise.resolve(answers.configure); - }); -} - -function getDsn(platform) { - considerShowingInfoHint(); - return inquirer - .prompt([ - { - type: 'input', - default: cachedDsn || process.env.SENTRY_DSN || 'YOUR_DSN_HERE', - message: 'The DSN for ' + getPlatformName(platform), - name: 'dsn', - validate: function(value) { - let m = value.match( - /^(?:(\w+):)?\/\/(?:(\w+)(:\w+)?@)?([\w\.-]+)(?::(\d+))?(\/.*)$/ - ); - if (!m) { - return 'invalid dsn format'; - } - if (m[1] !== 'http' && m[1] !== 'https') { - return 'unsupported protocol for dsn: ' + m[1]; - } - if (!m[3]) { - return 'missing secret in dsn'; - } - return true; - } - } - ]) - .then(function(answers) { - cachedDsn = answers.dsn; - return Promise.resolve(answers.dsn); - }); -} - -function getDefaultUrl() { - if (cachedDsn) { - let match = cachedDsn.match(/^(https?).*?@(.*?)\//); - if (match) { - return match[1] + '://' + match[2] + '/'; - } - } - return 'https://sentry.io/'; -} - -function getProperties(platform) { - return inquirer - .prompt([ - { - type: 'input', - default: cachedProps['defaults/url'] || process.env.SENTRY_URL || getDefaultUrl(), - message: - 'The Sentry Server URL for ' + - getPlatformName(platform) + - '. Only needed if you use self hosted Sentry, press enter to use default.', - name: 'defaults/url' - }, - { - type: 'input', - default: cachedProps['defaults/org'] || process.env.SENTRY_ORG || 'your-org-slug', - message: 'The Organization for ' + getPlatformName(platform), - name: 'defaults/org' - }, - { - type: 'input', - default: - cachedProps['defaults/project'] || - process.env.SENTRY_PROJECT || - 'your-project-slug', - message: 'The Project for ' + getPlatformName(platform), - name: 'defaults/project' - }, - { - type: 'password', - default: - cachedProps['auth/token'] || process.env.SENTRY_AUTH_TOKEN || 'YOUR_AUTH_TOKEN', - message: 'The Auth-Token for ' + getPlatformName(platform), - name: 'auth/token' - } - ]) - .then(function(answers) { - cachedProps = answers; - return Promise.resolve(answers); - }); -} - -function dumpProperties(props) { - let rv = []; - for (let key in props) { - let value = props[key]; - key = key.replace(/\//g, '.'); - if (value === undefined || value === null) { - rv.push('#' + key + '='); - } else { - rv.push(key + '=' + value); - } - } - return rv.join('\n') + '\n'; -} - -function patchAppDelegate(contents) { - // add the header if it's not there yet. - if (!contents.match(/#import "RNSentry.h"/)) { - contents = contents.replace(/(#import )/, '$1\n' + OBJC_HEADER); - } - - // add root view init. - let rootViewMatch = contents.match(/RCTRootView\s*\*\s*([^\s=]+)\s*=\s*\[/); - if (rootViewMatch) { - let rootViewInit = '[RNSentry installWithRootView:' + rootViewMatch[1] + '];'; - if (contents.indexOf(rootViewInit) < 0) { - contents = contents.replace( - /^(\s*)RCTRootView\s*\*\s*[^\s=]+\s*=\s*\[([^]*?\s*\]\s*;\s*$)/m, - function(match, indent) { - return match.trimRight() + '\n' + indent + rootViewInit + '\n'; - } - ); - } - } - - return Promise.resolve(contents); -} - -function patchAppJs(contents, filename) { - // since the init call could live in other places too, we really only - // want to do this if we managed to patch any of the other files as well. - if (contents.match(/Sentry.config\(/) || !patchedAny) { - return Promise.resolve(null); - } - - // if we match react-native-sentry somewhere, we already patched the file - // and no longer need to - if (contents.match('react-native-sentry')) { - Promise.resolve(contents); - } - - return new Promise((resolve, reject) => { - let promises = []; - for (let platform of PLATFORMS) { - promises.push( - shouldConfigurePlatform(platform).then(shouldConfigure => { - if (!shouldConfigure) { - return Promise.resolve(null); - } - return getDsn(platform).then(dsn => { - let platformDsn = {}; - platformDsn[platform] = dsn; - return Promise.resolve(platformDsn); - }); - }) - ); - } - Promise.all(promises).then(dsns => { - let config = {}; - dsns.forEach(value => { - if (value) Object.assign(config, value); - }); - if (Object.keys(config).length === 0) resolve(null); - resolve( - contents.replace(/^([^]*)(import\s+[^;]*?;$)/m, match => { - return ( - match + - "\n\nimport { Sentry } from 'react-native-sentry';\n\n" + - `const sentryDsn = Platform.select(${JSON.stringify(config)});\n` + - 'Sentry.config(sentryDsn).install();\n' - ); - }) - ); - }); - }); -} - -function patchIndexJs(contents, filename) { - // since the init call could live in other places too, we really only - // want to do this if we managed to patch any of the other files as well. - if (contents.match(/Sentry.config\(/) || !patchedAny) { - return Promise.resolve(null); - } - - let platform = filename.match(/index\.([^.]+?)\.js/)[1]; - return shouldConfigurePlatform(platform).then(shouldConfigure => { - if (!shouldConfigure) { - return null; - } - // if we match react-native-sentry somewhere, we already patched the file - // and no longer need to - if (contents.match('react-native-sentry')) { - Promise.resolve(contents); - } - return getDsn(platform).then(function(dsn) { - return Promise.resolve( - contents.replace(/^([^]*)(import\s+[^;]*?;$)/m, function(match) { - return ( - match + - "\n\nimport { Sentry } from 'react-native-sentry';\n\n" + - 'Sentry.config(' + - JSON.stringify(dsn) + - ').install();\n' - ); - }) - ); - }); - }); -} - -function patchBuildGradle(contents) { - let applyFrom = 'apply from: "../../node_modules/react-native-sentry/sentry.gradle"'; - if (contents.indexOf(applyFrom) >= 0) { - return Promise.resolve(null); - } - - return shouldConfigurePlatform('android').then(shouldConfigure => { - if (!shouldConfigure) { - return null; - } - - return Promise.resolve( - contents.replace( - /^apply from: "..\/..\/node_modules\/react-native\/react.gradle"/m, - function(match) { - return match + '\n' + applyFrom; - } - ) - ); - }); -} - -function patchExistingXcodeBuildScripts(buildScripts) { - for (let script of buildScripts) { - if ( - !script.shellScript.match(/(packager|scripts)\/react-native-xcode\.sh\b/) || - script.shellScript.match(/sentry-cli\s+react-native[\s-]xcode/) - ) { - continue; - } - let code = JSON.parse(script.shellScript); - code = - 'export SENTRY_PROPERTIES=sentry.properties\n' + - code.replace(/^.*?\/(packager|scripts)\/react-native-xcode\.sh\s*/m, function( - match - ) { - return ( - '../node_modules/sentry-cli-binary/bin/sentry-cli react-native xcode ' + match - ); - }); - script.shellScript = JSON.stringify(code); - } -} - -function addNewXcodeBuildPhaseForSymbols(buildScripts, proj) { - for (let script of buildScripts) { - if (script.shellScript.match(/sentry-cli\s+upload-dsym/)) { - return; - } - } - - proj.addBuildPhase( - [], - 'PBXShellScriptBuildPhase', - 'Upload Debug Symbols to Sentry', - null, - { - shellPath: '/bin/sh', - shellScript: - 'export SENTRY_PROPERTIES=sentry.properties\\n' + - '../node_modules/sentry-cli-binary/bin/sentry-cli upload-dsym' - } - ); -} - -function addZLibToXcode(proj) { - proj.addPbxGroup([], 'Frameworks', 'Application'); - proj.addFramework('libz.tbd', { - link: true, - target: proj.getFirstTarget().uuid - }); -} - -function patchXcodeProj(contents, filename) { - let proj = xcode.project(filename); - return new Promise(function(resolve, reject) { - proj.parse(function(err) { - if (err) { - reject(err); - return; - } - - let buildScripts = []; - for (let key in proj.hash.project.objects.PBXShellScriptBuildPhase || {}) { - let val = proj.hash.project.objects.PBXShellScriptBuildPhase[key]; - if (val.isa) { - buildScripts.push(val); - } - } - - patchExistingXcodeBuildScripts(buildScripts); - addNewXcodeBuildPhaseForSymbols(buildScripts, proj); - addZLibToXcode(proj); - - // we always modify the xcode file in memory but we only want to save it - // in case the user wants configuration for ios. This is why we check - // here first if changes are made before we might prompt the platform - // continue prompt. - let newContents = proj.writeSync(); - if (newContents === contents) { - resolve(null); - } else { - return shouldConfigurePlatform('ios').then(shouldConfigure => { - resolve(shouldConfigure ? newContents : null); - }); - } - }); - }); -} - -function patchMatchingFile(pattern, func) { - let matches = glob.sync(pattern, { - ignore: ['node_modules/**', 'ios/Pods/**', '**/Pods/**'] - }); - let rv = Promise.resolve(); - matches.forEach(function(match) { - let contents = fs.readFileSync(match, { - encoding: 'utf-8' - }); - rv = rv.then(() => func(contents, match)).then(function(newContents) { - if (newContents !== null && contents !== undefined && contents != newContents) { - patchedAny = true; - fs.writeFileSync(match, newContents); - } - }); - }); - return rv; -} - -function addSentryInit() { - let rv = Promise.resolve(); - // rm 0.49 introduced an App.js for both platforms - rv = rv.then(() => patchMatchingFile('App.js', patchAppJs)); - for (let platform of PLATFORMS) { - rv = rv.then(() => patchMatchingFile(`index.${platform}.js`, patchIndexJs)); - } - return rv; -} - -function resolveSentryCliBinaryPath(props) { - return new Promise(function(resolve, reject) { - try { - const cliPath = require.resolve('sentry-cli-binary/bin/sentry-cli'); - props['cli/executable'] = path.relative(process.cwd(), cliPath); - } catch (e) { - // we do nothing and leave everyting as it is - } - resolve(props); - }); -} - -function addSentryProperties() { - let rv = Promise.resolve(); - - for (let platform of PLATFORMS) { - // This will create the ios/android folder before trying to write - // sentry.properties in it which would fail otherwise - if (!fs.existsSync(platform)) { - fs.mkdirSync(platform); - } - let fn = platform + '/sentry.properties'; - if (fs.existsSync(fn)) { - continue; - } - - rv = rv.then(() => - shouldConfigurePlatform(platform).then(shouldConfigure => { - if (!shouldConfigure) { - return null; - } - return getProperties(platform).then(resolveSentryCliBinaryPath).then(props => { - fs.writeFileSync(fn, dumpProperties(props)); - }); - }) - ); - } - - return rv; -} - -Promise.resolve() - /* these steps patch the build files without user interactions */ - .then(() => patchMatchingFile('**/app/build.gradle', patchBuildGradle)) - .then(() => patchMatchingFile('ios/*.xcodeproj/project.pbxproj', patchXcodeProj)) - .then(() => patchMatchingFile('**/AppDelegate.m', patchAppDelegate)) - /* if any of the previous steps did something, this will patch - the index.PLATFORM.js files with the necessary initialization code */ - .then(() => addSentryInit()) - /* writes sentry.properties files with the API key and other settings */ - .then(() => addSentryProperties()) - .catch(function(e) { - console.log('Could not link react-native-sentry: ' + e); - return Promise.resolve(); - }); diff --git a/scripts/postunlink.js b/scripts/postunlink.js deleted file mode 100644 index ca95f3064f..0000000000 --- a/scripts/postunlink.js +++ /dev/null @@ -1,145 +0,0 @@ -let glob = require('glob'); -let fs = require('fs'); -let xcode = require('xcode'); - -function unpatchAppDelegate(contents) { - return Promise.resolve( - contents - .replace(/^#if __has_include\(\)[^]*?\#endif\r?\n/m, '') - .replace(/^#import\s+(?:|"RNSentry.h")\s*?\r?\n/m, '') - .replace(/(\r?\n|^)\s*\[RNSentry\s+installWithRootView:.*?\];\s*?\r?\n/m, '') - ); -} - -function unpatchBuildGradle(contents) { - return Promise.resolve( - contents.replace( - /^\s*apply from: ["']..\/..\/node_modules\/react-native-sentry\/sentry.gradle["'];?\s*?\r?\n/m, - '' - ) - ); -} - -function unpatchXcodeBuildScripts(proj) { - let scripts = proj.hash.project.objects.PBXShellScriptBuildPhase || {}; - let firstTarget = proj.getFirstTarget().uuid; - let nativeTargets = proj.hash.project.objects.PBXNativeTarget; - - // scripts to patch partially. Run this first so that we don't - // accidentally delete some scripts later entirely that we only want to - // rewrite. - for (let key of Object.keys(scripts)) { - let script = scripts[key]; - - // ignore comments - if (typeof script === 'string') { - continue; - } - - // ignore scripts that do not invoke the react-native-xcode command. - if (!script.shellScript.match(/sentry-cli\s+react-native[\s-]xcode\b/)) { - continue; - } - - script.shellScript = JSON.stringify( - JSON.parse(script.shellScript) - // "legacy" location for this. This is what happens if users followed - // the old documentation for where to add the bundle command - .replace( - /^..\/node_modules\/react-native-sentry\/bin\/bundle-frameworks\s*?\r\n?/m, - '' - ) - // legacy location for dsym upload - .replace( - /^..\/node_modules\/sentry-cli-binary\/bin\/sentry-cli upload-dsym\s*?\r?\n/m, - '' - ) - // remove sentry properties export - .replace(/^export SENTRY_PROPERTIES=sentry.properties\r?\n/m, '') - // unwrap react-native-xcode.sh command. In case someone replaced it - // entirely with the sentry-cli command we need to put the original - // version back in. - .replace( - /^(?:..\/node_modules\/sentry-cli-binary\/bin\/)?sentry-cli\s+react-native[\s-]xcode(\s+.*?)$/m, - function(match, m1) { - let rv = m1.trim(); - if (rv === '') { - return '../node_modules/react-native/packager/react-native-xcode.sh'; - } else { - return rv; - } - } - ) - ); - } - - // scripts to kill entirely. - for (let key of Object.keys(scripts)) { - let script = scripts[key]; - - // ignore comments and keys that got deleted - if (typeof script === 'string' || script === undefined) { - continue; - } - - if ( - script.shellScript.match(/react-native-sentry\/bin\/bundle-frameworks\b/) || - script.shellScript.match(/sentry-cli-binary\/bin\/sentry-cli\s+upload-dsym\b/) - ) { - delete scripts[key]; - delete scripts[key + '_comment']; - let phases = nativeTargets[firstTarget].buildPhases; - if (phases) { - for (let i = 0; i < phases.length; i++) { - if (phases[i].value === key) { - phases.splice(i, 1); - break; - } - } - } - continue; - } - } -} - -function unpatchXcodeProj(contents, filename) { - let proj = xcode.project(filename); - return new Promise(function(resolve, reject) { - proj.parse(function(err) { - if (err) { - reject(err); - return; - } - - unpatchXcodeBuildScripts(proj); - resolve(proj.writeSync()); - }); - }); -} - -function patchMatchingFile(pattern, func) { - let matches = glob.sync(pattern, { - ignore: 'node_modules/**' - }); - let rv = Promise.resolve(); - matches.forEach(function(match) { - let contents = fs.readFileSync(match, { - encoding: 'utf-8' - }); - rv = rv.then(() => func(contents, match)).then(function(newContents) { - if (contents != newContents) { - fs.writeFileSync(match, newContents); - } - }); - }); - return rv; -} - -Promise.resolve() - .then(() => patchMatchingFile('**/*.xcodeproj/project.pbxproj', unpatchXcodeProj)) - .then(() => patchMatchingFile('**/AppDelegate.m', unpatchAppDelegate)) - .then(() => patchMatchingFile('**/app/build.gradle', unpatchBuildGradle)) - .catch(function(e) { - console.log('Could not unlink react-native-sentry: ' + e); - return Promise.resolve(); - }); diff --git a/yarn.lock b/yarn.lock index c88cb10892..55b1526e5c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,21 @@ # yarn lockfile v1 +"@sentry/wizard@^0.5.3": + version "0.5.3" + resolved "https://registry.yarnpkg.com/@sentry/wizard/-/wizard-0.5.3.tgz#18236ea9fb9c3638c3829b22218ce02590d51744" + dependencies: + chalk "^2.3.0" + glob "^7.1.2" + inquirer "^4.0.0" + lodash "^4.17.4" + open "^0.0.5" + r2 "^2.0.0" + read-env "^1.1.1" + sentry-cli-binary "^1.21.0" + xcode "^1.0.0" + yargs "^10.0.3" + ansi-escapes@^1.0.0: version "1.4.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" @@ -77,6 +92,10 @@ camelcase@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" +caseless@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" @@ -252,7 +271,7 @@ figures@^2.0.0: dependencies: escape-string-regexp "^1.0.5" -find-up@^2.0.0: +find-up@^2.0.0, find-up@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" dependencies: @@ -274,7 +293,7 @@ get-stream@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" -glob@^7.1.1, glob@^7.1.2: +glob@^7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" dependencies: @@ -336,9 +355,9 @@ inherits@2: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" -inquirer@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" +inquirer@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-4.0.0.tgz#56c6354ae4e6201917027249bbd7667fca2cc031" dependencies: ansi-escapes "^3.0.0" chalk "^2.0.0" @@ -417,6 +436,10 @@ is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" +is-typedarray@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -592,6 +615,10 @@ mute-stream@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" +node-fetch@^2.0.0-alpha.8: + version "2.0.0-alpha.9" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.0.0-alpha.9.tgz#990c0634f510f76449a0d6f6eaec96b22f273628" + normalize-package-data@^2.3.2: version "2.4.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" @@ -649,6 +676,10 @@ onetime@^2.0.0: dependencies: mimic-fn "^1.0.0" +open@^0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/open/-/open-0.0.5.tgz#42c3e18ec95466b6bf0dc42f3a2945c3f0cad8fc" + ora@^0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/ora/-/ora-0.2.3.tgz#37527d220adcd53c39b73571d754156d5db657a4" @@ -743,8 +774,8 @@ plist@2.0.1: xmldom "0.1.x" prettier@^1.7.4: - version "1.7.4" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.7.4.tgz#5e8624ae9363c80f95ec644584ecdf55d74f93fa" + version "1.8.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.8.2.tgz#bff83e7fd573933c607875e5ba3abbdffb96aeb8" pretty-format@^21.2.1: version "21.2.1" @@ -761,9 +792,23 @@ pseudomap@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" +r2@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/r2/-/r2-2.0.0.tgz#fadc6558ac96f230d3dfa5bc039f0f97771968d9" + dependencies: + caseless "^0.12.0" + node-fetch "^2.0.0-alpha.8" + typedarray-to-buffer "^3.1.2" + raven-js@^3.19.1: - version "3.19.1" - resolved "https://registry.yarnpkg.com/raven-js/-/raven-js-3.19.1.tgz#a5d25646556fc2c86d2b188ae4f425c144c08dd8" + version "3.20.1" + resolved "https://registry.yarnpkg.com/raven-js/-/raven-js-3.20.1.tgz#3170bdb35c05098ddb8548ee5be0687f9d763330" + +read-env@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/read-env/-/read-env-1.1.1.tgz#561f16438792b19ed10ffede0315bde37f9f87fc" + dependencies: + camelcase "^4.1.0" read-pkg-up@^2.0.0: version "2.0.0" @@ -847,8 +892,8 @@ rxjs@^5.0.0-beta.11: resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" sentry-cli-binary@^1.21.0: - version "1.21.0" - resolved "https://registry.yarnpkg.com/sentry-cli-binary/-/sentry-cli-binary-1.21.0.tgz#3752563994d9a1c23828d61165ffa3b074cf6bb7" + version "1.24.1" + resolved "https://registry.yarnpkg.com/sentry-cli-binary/-/sentry-cli-binary-1.24.1.tgz#1ba26f49e7d2a0906b9879e6da87804f01517969" dependencies: progress "2.0.0" @@ -983,9 +1028,15 @@ tmp@^0.0.33: dependencies: os-tmpdir "~1.0.2" +typedarray-to-buffer@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.2.tgz#1017b32d984ff556eba100f501589aba1ace2e04" + dependencies: + is-typedarray "^1.0.0" + typescript@^2.5.3: - version "2.5.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.5.3.tgz#df3dcdc38f3beb800d4bc322646b04a3f6ca7f0d" + version "2.6.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.6.2.tgz#3c5b6fd7f6de0914269027f03c0946758f7673a4" uuid@3.0.1: version "3.0.1" @@ -1049,6 +1100,29 @@ yargs-parser@^7.0.0: dependencies: camelcase "^4.1.0" +yargs-parser@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-8.0.0.tgz#21d476330e5a82279a4b881345bf066102e219c6" + dependencies: + camelcase "^4.1.0" + +yargs@^10.0.3: + version "10.0.3" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-10.0.3.tgz#6542debd9080ad517ec5048fb454efe9e4d4aaae" + dependencies: + cliui "^3.2.0" + decamelize "^1.1.1" + find-up "^2.1.0" + get-caller-file "^1.0.1" + os-locale "^2.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1" + yargs-parser "^8.0.0" + yargs@^8.0.2: version "8.0.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-8.0.2.tgz#6299a9055b1cefc969ff7e79c1d918dceb22c360"