diff --git a/README.md b/README.md index 91b218c0..d7c23f68 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,9 @@ [![build](https://travis-ci.org/sourcegraph/sourcegraph-sentry.svg?branch=master)](https://travis-ci.org/sourcegraph/sentry) [![codecov](https://codecov.io/gh/sourcegraph/sourcegraph-sentry/branch/master/graph/badge.svg)](https://codecov.io/gh/sourcegraph/sourcegraph-sentry) -Sentry helps devs track, organize and break down errors more efficiently, facilitating their debug process. We want to make it more convenient for developers to access Sentry's error tracking tools directly from the code that is doing the error handling, code such as `throw new Error(QUERY)`, `console.log(QUERY)`, `console.error(QUERY)` etc.. +Sentry facilitates the debugging process by helping developers track, organize, and break down errors more efficiently. At Sourcegraph, we want to make it more convenient for developers to access Sentry's error tracking tools directly from the code that is doing the error handling. For example: `throw new Error(QUERY)`, `console.log(QUERY)`, and `console.error(QUERY)`. -The Sentry extension renders a `View logs in Sentry` next to error throwing statements, linking directly to the corresponding Sentry issues stream page. Links are rendered when viewing files on [Sourcegraph](https://sourcegraph.com), GitHub and GitLab. +The Sentry extension renders `View logs in Sentry` next to error throwing statements, and links directly to the corresponding Sentry issues stream page. Links are rendered when viewing files on [Sourcegraph](https://sourcegraph.com), GitHub, and GitLab. - **Sentry: Show/hide Sentry**: toggles Sentry links decorations with each matching error handling code. @@ -17,82 +17,169 @@ The Sentry extension renders a `View logs in Sentry` next to error throwing stat ## Language support -To work, the Sentry Sourcegraph extension must know how to recognize instances of error handling and/or exception throwing for each language. The first version will support: +The Sentry Sourcegraph extension uses common error handling and/or exception throwing patterns specific to each language to identfy Sentry relevant lines of code. The following languages are currently supported: -- TypeScript -- Go -- JavaScript -- Python -- Java +- TypeScript, JavaScript ( e.g. `throw new Error()`, `console.error()`) +- Go ( e.g. `err.message()`) +- JavaScript ( e.g. `console.error()`) +- Python ( e.g. `raise TypeError()`) +- Java ( e.g. `logger.error()`) + +See the [default error patterns](https://sourcegraph.com/github.com/sourcegraph/sourcegraph-sentry@master/-/blob/src/extension.ts?diff=21f9b0716040dd96f917580ec4cacd59f3f1b5be&utm_source=chrome-extension#L11-25). -## Setup +If you need to match more specific patterns in your codebase, you can configure them through [line matches](#improving-error-pattern-recognition-for-your-organization). -Set the following configurations in your settings: +## Basic Setup + +In your Sourcegraph settings (user, organization, or global), add the following configuration: ``` -"sentry.organization": "[Sentry organization name]", +"sentry.decorations.inline": true, +"sentry.organization": "", "sentry.projects": [ - { - "name": "[Project name for the config overview, e.g. Webapp errors]", - "projectId": "[Sentry project ID, e.g. "1334031"]", - "linePatterns": [ - // List of RegExp patterns that match error handling code, e.g. "throw new Error+\\(['\"]([^'\"]+)['\"]\\)", - // !! Make sure to capture the error message in a RegExp group !! - ] - "filters": { - [ - "repositories": [ - // List of RegExp repo names asociated with this Sentry project - ], - "files": [ - // List of RegExp that matches file format, e.g. "\\.tsx?", - // or for more specific matching, folder matching, e.g. "(?:web|shared|src)\/.*\\.tsx?" - ], + { + // All matching error statements in your sourcegraph instance will link to this project + "projectId": "", } - } +] +``` + +For organizations, we recommend to set this once by the site admin in the org or global settings, so that individual org users do not have to configure this individually. + +With this simple configuration, any error that matches the default patterns will link to the specified Sentry organization and project. + +To find your Sentry organization and project ID, go to [sentry.io](http://sentry.io) and look at the URL when on your project page, e.g.: ``` +https://sentry.io/organizations/sourcegraph/events/?project=1251215 +``` + +In the above, `sourcegraph` is the organization and `1251215` is the project ID. -## Important features: +## Mapping multiple Sentry projects to various repositories -File patterns can also be narrowed down to certain folders by specifying this in the RegExp: +Some organizations have multiple Sentry projects that capture errors from various repositories within their organization. Inside each Sentry project, use repository `filters` like so: ``` -... -"files": ["(?:web|shared|src)\/.*\\.tsx?"] -... +"sentry.decorations.inline": true, +"sentry.organization": "", +"sentry.projects": [ + { + // All repositoryA error patterns link to Project A in Sentry + "projectId": "", + "filters": [ + { + "repositories": [ + "myorg/repositoryA$" // Regexp matching repositories that report to this Sentry project + ] + } + ] + }, + { + // All repositoryB error patterns link to Project B in Sentry + "projectId": "", + "filters": [ + { + "repositories": [ + "myorg/repositoryB$" + ] + } + ] + } +] ``` -## Examples +In this example, errors found in `repositoryA` will link to `project_a`, and errors in `repositoryB` will link to `project_b` in Sentry. -- TypeScript +## Mapping a single repository to multiple Sentry projects - Configuration: +Some organizations will have different parts of their code base map to different Sentry projects. For example, all frontend code is sent to one Sentry project, and all backend code is sent to another. - ``` - "sentry.decorations.inline": true, - "sentry.organization": "sourcegraph", - "sentry.projects": [ +You can add multiple Sentry projects and add file `filters` to match specific files or folders, like so: + +``` +"sentry.decorations.inline": true, +"sentry.organization": "", +"sentry.projects": [ { - "name": "sourcegraph", - "projectId": "1334031", - "linePatterns": [ - "throw new Error+\\(['\"]([^'\"]+)['\"]\\)", - "console\\.(warn|debug|info|error)\\(['\"`]([^'\"`]+)['\"`]\\)" - ] + // All JS files link to Project A in Sentry + "projectId": "", "filters": [ { - "repositories": "sourcegraph\/sourcegraph", - "files": ["web\/.*\\.ts?"], - }, + "files": [ + "\\.js?" // RegExp that matches JavaScript files + ] + } + ] + }, + { + // All Go files link to Project B in Sentry + "projectId": "", + "filters": [ { - "files": ["sourcegraph-subfolder\/.*\\.tsx?"] + "files": [ + "\\.go?" + ] } + ] + } +] +``` + +Now, errors found in JS files will link to `project_a` and errors in Go files will link to `project_b` in Sentry. +You can also match repository subdirectories using a regex (e.g. `"(?:web|node)\/.*\\.tsx?"` to match any files with the `.tsx` extension within directories named `web` or `node`). + +## Improving error pattern recognition for your organization + +By default, the extension matches error messages from a few popular languages. However, you may need to define your own patterns to enhance matches for your specific codebase, or that we do not currently support. + +To do this, add a regex to your Sentry project config that captures the static error message generated. For example, to match JS/TS throw statements: + +``` +"sentry.projects": [ + { + // Frontend errors + "projectId": "", + "linePatterns": [ + // Matches JS/TS throw statements: + "throw new [A-Za-z0-9]+\\(['\"]([^'\"]+)['\"]\\)" ] } - ] +] +``` + +The error message should always be captured by the capture group \$INDEX=0. All other capture groups should be made optional with `?:`. For instance, in the above example, note how the first regex group is ignored with `?:`. It will match a variety of `throw new` error types, but doesn't need to be captured. The second regex group captures the error string, which will be used as the search when linked to Sentry. + +## Language Specific Examples + +- TypeScript + + Configuration: + ``` + "sentry.decorations.inline": true, + "sentry.organization": "sourcegraph", + "sentry.projects": [ + { + // Web errors + "projectId": "1334031", + "filters": [ + { + "repositories": "sourcegraph/sourcegraph", + "files": ["web/.*\\.ts?"] + }, + { + "files": ["sourcegraph-about/.*\\.tsx?"] + } + + ], + "linePatterns": [ + "throw new [A-Za-z0-9]+\\(['\"]([^'\"]+)['\"]\\)", + "console\\.(?:warn|debug|info|error)\\(['\"`]([^'\"`]+)['\"`]\\)" + ] + } + ] ``` - [On Sourcegraph](https://sourcegraph.com/github.com/sourcegraph/sourcegraph/-/blob/browser/src/libs/github/file_info.ts#L22) @@ -100,30 +187,31 @@ File patterns can also be narrowed down to certain folders by specifying this in - Go -Configuration: + Configuration: -``` -"sentry.decorations.inline": true, -"sentry.organization": "sourcegraph", -"sentry.projects": [ - "name": "Dev env errors", - "projectId": "213332", - "linePatterns": ["errors\\.New\\(['\"`](.*)['\"`]\\)"], - "filters": [ - { - "repositories": ["sourcegraph\/sourcegraph", "sourcegraph\/dev-repo"], - "files": ["/auth\/.*.go?/"], - }, + ``` + "sentry.decorations.inline": true, + "sentry.organization": "sourcegraph", + "sentry.projects": [ { - "repositories": ["/dev-env/"] + // Dev environment errors + "projectId": "213332", + "filters": [ + { + "repositories": ["sourcegraph/sourcegraph", "sourcegraph/dev-repo"], + "files": ["auth/.*.go?/"] + }, + { + "repositories": ["/dev-env"] + } + ], + "linePatterns": ["errors\\.New\\(['\"`](.*)['\"`]\\)"] } - ], -] - -``` + ] + ``` -- [On Sourcegraph](https://sourcegraph.com/github.com/sourcegraph/sourcegraph/-/blob/cmd/frontend/auth/user_test.go#L54:19) -- [On GitHub](https://github.com/sourcegraph/sourcegraph/blob/master/cmd/frontend/auth/user_test.go#L54) + - [On Sourcegraph](https://sourcegraph.com/github.com/sourcegraph/sourcegraph/-/blob/cmd/frontend/auth/user_test.go#L54:19) + - [On GitHub](https://github.com/sourcegraph/sourcegraph/blob/master/cmd/frontend/auth/user_test.go#L54) - JavaScript diff --git a/package-lock.json b/package-lock.json index 06cbafcf..07ceed7f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1023,6 +1023,42 @@ "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", "dev": true }, + "@sourcegraph/extension-api-classes": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@sourcegraph/extension-api-classes/-/extension-api-classes-1.0.2.tgz", + "integrity": "sha512-2PUTf/hedG+5DTyUmA2QPK7I/qyiwIbgQHcmAeRGlysg17okOeNFRp4AVLJsAh+NLq8poxtbyXP+dIdrCzONgw==", + "dev": true, + "requires": { + "@sourcegraph/extension-api-types": "^2.0.0" + } + }, + "@sourcegraph/extension-api-stubs": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@sourcegraph/extension-api-stubs/-/extension-api-stubs-0.2.0.tgz", + "integrity": "sha512-EhI65jZnDB+/pnRHrwzlFq7JN9NuabJBiZoBmAMghnqtbVD/5pEqm9XJD0LPCg/Uc3FEIVTkVXjNylGn4s0JNA==", + "dev": true, + "requires": { + "@sourcegraph/extension-api-classes": "^1.0.2", + "@types/sinon": "7.0.11", + "rxjs": "^6.5.1", + "sinon": "^7.3.2", + "sourcegraph": "^23.0.1" + }, + "dependencies": { + "@types/sinon": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-7.0.11.tgz", + "integrity": "sha512-6ee09Ugx6GyEr0opUIakmxIWFNmqYPjkqa3/BuxCBokA0klsOLPgMD5K4q40lH7/yZVuJVzOfQpd7pipwjngkQ==", + "dev": true + } + } + }, + "@sourcegraph/extension-api-types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sourcegraph/extension-api-types/-/extension-api-types-2.0.0.tgz", + "integrity": "sha512-Te7F1RQJLBH4C8wQ2xz0nPC2vpe13F80V+Yv+c3GySOoh4DcLNN4P5u51Kh4aZPqeS5DJ7CKvHyX2SM/1EBXNg==", + "dev": true + }, "@sourcegraph/prettierrc": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@sourcegraph/prettierrc/-/prettierrc-2.2.0.tgz", @@ -1060,15 +1096,15 @@ "dev": true }, "@types/lodash": { - "version": "4.14.123", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.123.tgz", - "integrity": "sha512-pQvPkc4Nltyx7G1Ww45OjVqUsJP4UsZm+GWJpigXgkikZqJgRm4c48g027o6tdgubWHwFRF15iFd+Y4Pmqv6+Q==", + "version": "4.14.133", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.133.tgz", + "integrity": "sha512-/3JqnvPnY58GLzG3Y7fpphOhATV1DDZ/Ak3DQufjlRK5E4u+s0CfClfNFtAGBabw+jDGtRFbOZe+Z02ZMWCBNQ==", "dev": true }, "@types/mocha": { - "version": "5.2.6", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.6.tgz", - "integrity": "sha512-1axi39YdtBI7z957vdqXI4Ac25e7YihYQtJa+Clnxg1zTJEaIRbndt71O3sP4GAMgiAm0pY26/b9BrY4MR/PMw==", + "version": "5.2.7", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", + "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==", "dev": true }, "@types/mock-require": { @@ -1093,9 +1129,9 @@ "dev": true }, "@types/sinon": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-7.0.11.tgz", - "integrity": "sha512-6ee09Ugx6GyEr0opUIakmxIWFNmqYPjkqa3/BuxCBokA0klsOLPgMD5K4q40lH7/yZVuJVzOfQpd7pipwjngkQ==", + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-7.0.12.tgz", + "integrity": "sha512-fo0MWpVPSUrnZZhp9wyu+hhI3VJ9+Jhs+PWrokBTg3d2ryNPDOAWF1csIhQuYWBTn7KdZzXpRgpX2o6cwOlPWg==", "dev": true }, "@types/stack-utils": { @@ -1210,6 +1246,21 @@ "normalize-path": "^2.1.1" } }, + "append-transform": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", + "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", + "dev": true, + "requires": { + "default-require-extensions": "^2.0.0" + } + }, + "archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "dev": true + }, "arg": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.0.tgz", @@ -1376,65 +1427,6 @@ "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", "dev": true }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, "babel-runtime": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", @@ -1801,6 +1793,36 @@ "unset-value": "^1.0.0" } }, + "caching-transform": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-3.0.2.tgz", + "integrity": "sha512-Mtgcv3lh3U0zRii/6qVgQODdPA4G3zhG+jtbCWj39RXuUFTMzH0vcdMtaJS1jPowd+It2Pqr6y3NJMQqOqCE2w==", + "dev": true, + "requires": { + "hasha": "^3.0.0", + "make-dir": "^2.0.0", + "package-hash": "^3.0.0", + "write-file-atomic": "^2.4.2" + }, + "dependencies": { + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + } + } + }, "call-me-maybe": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", @@ -2072,6 +2094,12 @@ "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", "dev": true }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, "component-emitter": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", @@ -2172,6 +2200,37 @@ } } }, + "cp-file": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-6.2.0.tgz", + "integrity": "sha512-fmvV4caBnofhPe8kOcitBwSn2f39QLjnAnGq3gO9dfd75mUytzKNZB1hde6QHunW2Rt+OwuBOMc3i1tNElbszA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "make-dir": "^2.0.0", + "nested-error-stacks": "^2.0.0", + "pify": "^4.0.1", + "safe-buffer": "^5.0.1" + }, + "dependencies": { + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + } + } + }, "create-ecdh": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", @@ -2659,6 +2718,23 @@ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, + "default-require-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", + "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", + "dev": true, + "requires": { + "strip-bom": "^3.0.0" + }, + "dependencies": { + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } + } + }, "defaults": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", @@ -2981,6 +3057,12 @@ "is-symbol": "^1.0.2" } }, + "es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -3311,6 +3393,35 @@ } } }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + }, + "dependencies": { + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + } + } + }, "find-up": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", @@ -3350,6 +3461,28 @@ "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", "dev": true }, + "foreground-child": { + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", + "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=", + "dev": true, + "requires": { + "cross-spawn": "^4", + "signal-exit": "^3.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", + "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + } + } + }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -4074,6 +4207,18 @@ "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true }, + "handlebars": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.2.tgz", + "integrity": "sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw==", + "dev": true, + "requires": { + "neo-async": "^2.6.0", + "optimist": "^0.6.1", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4" + } + }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -4180,6 +4325,15 @@ "minimalistic-assert": "^1.0.1" } }, + "hasha": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz", + "integrity": "sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk=", + "dev": true, + "requires": { + "is-stream": "^1.0.1" + } + }, "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -4345,6 +4499,12 @@ "resolve-from": "^3.0.0" } }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, "indent-string": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", @@ -4719,24 +4879,134 @@ "dev": true }, "istanbul-lib-coverage": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", - "integrity": "sha512-dKWuzRGCs4G+67VfW9pBFFz2Jpi4vSp/k7zBcJ888ofV5Mi1g5CUML5GvMvV6u9Cjybftu+E8Cgp+k0dI1E5lw==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", + "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", "dev": true }, + "istanbul-lib-hook": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz", + "integrity": "sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA==", + "dev": true, + "requires": { + "append-transform": "^1.0.0" + } + }, "istanbul-lib-instrument": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.1.0.tgz", - "integrity": "sha512-ooVllVGT38HIk8MxDj/OIHXSYvH+1tq/Vb38s8ixt9GoJadXska4WkGY+0wkmtYCZNYtaARniH/DixUGGLZ0uA==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", + "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", + "dev": true, + "requires": { + "@babel/generator": "^7.4.0", + "@babel/parser": "^7.4.3", + "@babel/template": "^7.4.0", + "@babel/traverse": "^7.4.3", + "@babel/types": "^7.4.0", + "istanbul-lib-coverage": "^2.0.5", + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.1.1.tgz", + "integrity": "sha512-rWYq2e5iYW+fFe/oPPtYJxYgjBm8sC4rmoGdUOgBB7VnwKt6HrL793l2voH1UlsyYZpJ4g0wfjnTEO1s1NP2eQ==", + "dev": true + } + } + }, + "istanbul-lib-report": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", + "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "supports-color": "^6.1.0" + }, + "dependencies": { + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", + "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "rimraf": "^2.6.3", + "source-map": "^0.6.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + } + } + }, + "istanbul-reports": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.6.tgz", + "integrity": "sha512-SKi4rnMyLBKe0Jy2uUdx28h8oG7ph2PPuQPvIAh31d+Ci+lSiEu4C+h3oBPuJ9+mPKhOyW0M8gY4U5NM1WLeXA==", "dev": true, "requires": { - "@babel/generator": "^7.0.0", - "@babel/parser": "^7.0.0", - "@babel/template": "^7.0.0", - "@babel/traverse": "^7.0.0", - "@babel/types": "^7.0.0", - "istanbul-lib-coverage": "^2.0.3", - "semver": "^5.5.0" + "handlebars": "^4.1.2" } }, "jest-diff": { @@ -5027,6 +5297,12 @@ "integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=", "dev": true }, + "lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", + "dev": true + }, "lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -5055,9 +5331,9 @@ } }, "lolex": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-3.1.0.tgz", - "integrity": "sha512-zFo5MgCJ0rZ7gQg69S4pqBsLURbFw11X68C18OcJjJQbqaXm2NoTrGl1IMM3TIz0/BnN1tIs2tzmmqvCsOMMjw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-4.0.1.tgz", + "integrity": "sha512-UHuOBZ5jjsKuzbB/gRNNW8Vg8f00Emgskdq2kvZxgBJCS0aqquAuXai/SkWORlKeZEiNQWZjFZOqIUcH9LqKCw==", "dev": true }, "loose-envify": { @@ -5344,9 +5620,9 @@ } }, "mocha": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.1.2.tgz", - "integrity": "sha512-BgD2/RozoSC3uQK5R0isDcxjqaWw2n5HWdk8njYUyZf2NC79ErO5FtYVX52+rfqGoEgMfJf4fuG0IWh2TMzFoA==", + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.1.4.tgz", + "integrity": "sha512-PN8CIy4RXsIoxoFJzS4QNnCH4psUCPWc4/rPrst/ecSJJbLBkubMiyGCP2Kj/9YnWbotFqAoeXyXMucj7gwCFg==", "dev": true, "requires": { "ansi-colors": "3.2.3", @@ -5358,12 +5634,12 @@ "glob": "7.1.3", "growl": "1.10.5", "he": "1.2.0", - "js-yaml": "3.13.0", + "js-yaml": "3.13.1", "log-symbols": "2.2.0", "minimatch": "3.0.4", "mkdirp": "0.5.1", "ms": "2.1.1", - "node-environment-flags": "1.0.4", + "node-environment-flags": "1.0.5", "object.assign": "4.1.0", "strip-json-comments": "2.0.1", "supports-color": "6.0.0", @@ -5392,6 +5668,16 @@ "locate-path": "^3.0.0" } }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, "ms": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", @@ -5459,6 +5745,18 @@ "to-regex": "^3.0.1" } }, + "neo-async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", + "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", + "dev": true + }, + "nested-error-stacks": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz", + "integrity": "sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==", + "dev": true + }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", @@ -5493,12 +5791,21 @@ "dev": true }, "node-environment-flags": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.4.tgz", - "integrity": "sha512-M9rwCnWVLW7PX+NUWe3ejEdiLYinRpsEre9hMkU/6NS4h+EEulYaDH1gCEZ2gyXsmw+RXYDaV2JkkTNcsPDJ0Q==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", + "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==", "dev": true, "requires": { - "object.getownpropertydescriptors": "^2.0.3" + "object.getownpropertydescriptors": "^2.0.3", + "semver": "^5.7.0" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } } }, "node-forge": { @@ -5629,1036 +5936,87 @@ "dev": true }, "nyc": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-13.3.0.tgz", - "integrity": "sha512-P+FwIuro2aFG6B0Esd9ZDWUd51uZrAEoGutqZxzrVmYl3qSfkLgcQpBPBjtDFsUQLFY1dvTQJPOyeqr8S9GF8w==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-14.1.1.tgz", + "integrity": "sha512-OI0vm6ZGUnoGZv/tLdZ2esSVzDwUC88SNs+6JoSOMVxA+gKMB8Tk7jBwgemLx4O40lhhvZCVw1C+OYLOBOPXWw==", "dev": true, "requires": { "archy": "^1.0.0", - "arrify": "^1.0.1", - "caching-transform": "^3.0.1", + "caching-transform": "^3.0.2", "convert-source-map": "^1.6.0", - "find-cache-dir": "^2.0.0", + "cp-file": "^6.2.0", + "find-cache-dir": "^2.1.0", "find-up": "^3.0.0", "foreground-child": "^1.5.6", "glob": "^7.1.3", - "istanbul-lib-coverage": "^2.0.3", - "istanbul-lib-hook": "^2.0.3", - "istanbul-lib-instrument": "^3.1.0", - "istanbul-lib-report": "^2.0.4", - "istanbul-lib-source-maps": "^3.0.2", - "istanbul-reports": "^2.1.1", - "make-dir": "^1.3.0", + "istanbul-lib-coverage": "^2.0.5", + "istanbul-lib-hook": "^2.0.7", + "istanbul-lib-instrument": "^3.3.0", + "istanbul-lib-report": "^2.0.8", + "istanbul-lib-source-maps": "^3.0.6", + "istanbul-reports": "^2.2.4", + "js-yaml": "^3.13.1", + "make-dir": "^2.1.0", "merge-source-map": "^1.1.0", "resolve-from": "^4.0.0", "rimraf": "^2.6.3", - "signal-exit": "^3.0.2", - "spawn-wrap": "^1.4.2", - "test-exclude": "^5.1.0", - "uuid": "^3.3.2", - "yargs": "^12.0.5", - "yargs-parser": "^11.1.1" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "append-transform": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "default-require-extensions": "^2.0.0" - } - }, - "archy": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "arrify": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "async": { - "version": "2.6.2", - "bundled": true, - "dev": true, - "requires": { - "lodash": "^4.17.11" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "caching-transform": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "hasha": "^3.0.0", - "make-dir": "^1.3.0", - "package-hash": "^3.0.0", - "write-file-atomic": "^2.3.0" - } - }, - "camelcase": { - "version": "5.0.0", - "bundled": true, - "dev": true - }, - "cliui": { - "version": "4.1.0", - "bundled": true, - "dev": true, - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - } - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "commander": { - "version": "2.17.1", - "bundled": true, - "dev": true, - "optional": true - }, - "commondir": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true - }, - "convert-source-map": { - "version": "1.6.0", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "cross-spawn": { - "version": "4.0.2", - "bundled": true, - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "which": "^1.2.9" - } - }, - "debug": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "decamelize": { - "version": "1.2.0", - "bundled": true, - "dev": true - }, - "default-require-extensions": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "strip-bom": "^3.0.0" - } - }, - "end-of-stream": { - "version": "1.4.1", - "bundled": true, - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "error-ex": { - "version": "1.3.2", - "bundled": true, - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es6-error": { - "version": "4.1.1", - "bundled": true, - "dev": true - }, - "execa": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "dependencies": { - "cross-spawn": { - "version": "6.0.5", - "bundled": true, - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - } - } - }, - "find-cache-dir": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^1.0.0", - "pkg-dir": "^3.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "foreground-child": { - "version": "1.5.6", - "bundled": true, - "dev": true, - "requires": { - "cross-spawn": "^4", - "signal-exit": "^3.0.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "get-caller-file": { - "version": "1.0.3", - "bundled": true, - "dev": true - }, - "get-stream": { - "version": "4.1.0", - "bundled": true, - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "glob": { - "version": "7.1.3", - "bundled": true, - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "graceful-fs": { - "version": "4.1.15", - "bundled": true, - "dev": true - }, - "handlebars": { - "version": "4.1.0", - "bundled": true, - "dev": true, - "requires": { - "async": "^2.5.0", - "optimist": "^0.6.1", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "bundled": true, - "dev": true - } - } - }, - "has-flag": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "hasha": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "is-stream": "^1.0.1" - } - }, - "hosted-git-info": { - "version": "2.7.1", - "bundled": true, - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "bundled": true, - "dev": true - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true - }, - "invert-kv": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "is-arrayish": { - "version": "0.2.1", - "bundled": true, - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "isexe": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "istanbul-lib-coverage": { - "version": "2.0.3", - "bundled": true, - "dev": true - }, - "istanbul-lib-hook": { - "version": "2.0.3", - "bundled": true, - "dev": true, - "requires": { - "append-transform": "^1.0.0" - } - }, - "istanbul-lib-report": { - "version": "2.0.4", - "bundled": true, - "dev": true, - "requires": { - "istanbul-lib-coverage": "^2.0.3", - "make-dir": "^1.3.0", - "supports-color": "^6.0.0" - }, - "dependencies": { - "supports-color": { - "version": "6.1.0", - "bundled": true, - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "istanbul-lib-source-maps": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^2.0.3", - "make-dir": "^1.3.0", - "rimraf": "^2.6.2", - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "bundled": true, - "dev": true - } - } - }, - "istanbul-reports": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "requires": { - "handlebars": "^4.1.0" - } - }, - "json-parse-better-errors": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "lcid": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "invert-kv": "^2.0.0" - } - }, - "load-json-file": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.11", - "bundled": true, - "dev": true - }, - "lodash.flattendeep": { - "version": "4.4.0", - "bundled": true, - "dev": true - }, - "lru-cache": { - "version": "4.1.5", - "bundled": true, - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "make-dir": { - "version": "1.3.0", - "bundled": true, - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "map-age-cleaner": { - "version": "0.1.3", - "bundled": true, - "dev": true, - "requires": { - "p-defer": "^1.0.0" - } - }, - "mem": { - "version": "4.1.0", - "bundled": true, - "dev": true, - "requires": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^1.0.0", - "p-is-promise": "^2.0.0" - } - }, - "merge-source-map": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "requires": { - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "bundled": true, - "dev": true - } - } - }, - "mimic-fn": { - "version": "1.2.0", - "bundled": true, - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.10", - "bundled": true, - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true - } - } - }, - "ms": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "bundled": true, - "dev": true - }, - "normalize-package-data": { - "version": "2.5.0", - "bundled": true, - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "npm-run-path": { - "version": "2.0.2", - "bundled": true, - "dev": true, - "requires": { - "path-key": "^2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "optimist": { - "version": "0.6.1", - "bundled": true, - "dev": true, - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "os-locale": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" - } - }, - "p-defer": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "p-finally": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "p-is-promise": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "p-limit": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "package-hash": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "graceful-fs": "^4.1.15", - "hasha": "^3.0.0", - "lodash.flattendeep": "^4.4.0", - "release-zalgo": "^1.0.0" - } - }, - "parse-json": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "path-exists": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "path-key": { - "version": "2.0.1", - "bundled": true, - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "bundled": true, - "dev": true - }, - "path-type": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "pify": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "pkg-dir": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "pseudomap": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "pump": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "read-pkg": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - } - }, - "read-pkg-up": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "find-up": "^3.0.0", - "read-pkg": "^3.0.0" - } - }, - "release-zalgo": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "es6-error": "^4.0.1" - } - }, - "require-directory": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "require-main-filename": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "resolve": { - "version": "1.10.0", - "bundled": true, - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-from": { - "version": "4.0.0", - "bundled": true, - "dev": true - }, - "rimraf": { - "version": "2.6.3", - "bundled": true, - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "dev": true - }, - "semver": { - "version": "5.6.0", - "bundled": true, - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true - }, - "spawn-wrap": { - "version": "1.4.2", - "bundled": true, - "dev": true, - "requires": { - "foreground-child": "^1.5.6", - "mkdirp": "^0.5.0", - "os-homedir": "^1.0.1", - "rimraf": "^2.6.2", - "signal-exit": "^3.0.2", - "which": "^1.3.0" - } - }, - "spdx-correct": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.2.0", - "bundled": true, - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.3", - "bundled": true, - "dev": true - }, - "string-width": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "strip-bom": { + "signal-exit": "^3.0.2", + "spawn-wrap": "^1.4.2", + "test-exclude": "^5.2.3", + "uuid": "^3.3.2", + "yargs": "^13.2.2", + "yargs-parser": "^13.0.0" + }, + "dependencies": { + "find-up": { "version": "3.0.0", - "bundled": true, - "dev": true - }, - "strip-eof": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "test-exclude": { - "version": "5.1.0", - "bundled": true, - "dev": true, - "requires": { - "arrify": "^1.0.1", - "minimatch": "^3.0.4", - "read-pkg-up": "^4.0.0", - "require-main-filename": "^1.0.1" - } - }, - "uglify-js": { - "version": "3.4.9", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "commander": "~2.17.1", - "source-map": "~0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "uuid": { - "version": "3.3.2", - "bundled": true, - "dev": true - }, - "validate-npm-package-license": { - "version": "3.0.4", - "bundled": true, + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" + "locate-path": "^3.0.0" } }, - "which": { - "version": "1.3.1", - "bundled": true, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", "dev": true, "requires": { - "isexe": "^2.0.0" + "argparse": "^1.0.7", + "esprima": "^4.0.0" } }, - "which-module": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "wordwrap": { - "version": "0.0.3", - "bundled": true, - "dev": true - }, - "wrap-ansi": { + "make-dir": { "version": "2.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", "dev": true, "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - } + "pify": "^4.0.1", + "semver": "^5.6.0" } }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "write-file-atomic": { - "version": "2.4.2", - "bundled": true, + "merge-source-map": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", + "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", "dev": true, "requires": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" + "source-map": "^0.6.1" } }, - "y18n": { - "version": "4.0.0", - "bundled": true, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true }, - "yallist": { - "version": "2.1.2", - "bundled": true, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true - }, - "yargs": { - "version": "12.0.5", - "bundled": true, - "dev": true, - "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.2.0", - "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.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 || ^4.0.0", - "yargs-parser": "^11.1.1" - } - }, - "yargs-parser": { - "version": "11.1.1", - "bundled": true, - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } } } }, @@ -6813,6 +6171,30 @@ "is-wsl": "^1.1.0" } }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "dev": true, + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + }, + "dependencies": { + "minimist": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", + "dev": true + }, + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "dev": true + } + } + }, "optionator": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", @@ -6944,6 +6326,18 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, + "package-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-3.0.0.tgz", + "integrity": "sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "hasha": "^3.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + } + }, "pako": { "version": "0.2.9", "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", @@ -7266,6 +6660,26 @@ "pinkie": "^2.0.0" } }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + } + } + }, "pn": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", @@ -7800,9 +7214,9 @@ "dev": true }, "prettier": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.17.0.tgz", - "integrity": "sha512-sXe5lSt2WQlCbydGETgfm1YBShgOX4HxQkFPvbxkcwgDvGDeqVau8h+12+lmSVlP3rHPz0oavfddSZg/q+Szjw==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.17.1.tgz", + "integrity": "sha512-TzGRNvuUSmPgwivDqkZ9tM/qTGW9hqDKWOE9YHiyQdixlKbv7kvEqsmDPrcHJTKwthU774TQwZXVtaQ/mMsvjg==", "dev": true }, "pretty-format": { @@ -8089,6 +7503,15 @@ } } }, + "release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", + "dev": true, + "requires": { + "es6-error": "^4.0.1" + } + }, "remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", @@ -8263,9 +7686,9 @@ } }, "rxjs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz", - "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz", + "integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==", "dev": true, "requires": { "tslib": "^1.9.0" @@ -8481,16 +7904,16 @@ } }, "sinon": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-7.3.1.tgz", - "integrity": "sha512-eQKMaeWovtOtYe2xThEvaHmmxf870Di+bim10c3ZPrL5bZhLGtu8cz+rOBTFz0CwBV4Q/7dYwZiqZbGVLZ+vjQ==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-7.3.2.tgz", + "integrity": "sha512-thErC1z64BeyGiPvF8aoSg0LEnptSaWE7YhdWWbWXgelOyThent7uKOnnEh9zBxDbKixtr5dEko+ws1sZMuFMA==", "dev": true, "requires": { "@sinonjs/commons": "^1.4.0", "@sinonjs/formatio": "^3.2.1", "@sinonjs/samsam": "^3.3.1", "diff": "^3.5.0", - "lolex": "^3.1.0", + "lolex": "^4.0.1", "nise": "^1.4.10", "supports-color": "^5.5.0" } @@ -8655,6 +8078,20 @@ "integrity": "sha512-4We7zqhOagOVxNFdS6/xT/Crhb0Arw/9ytGBu8JuHfjo5yjMtcUYt22kZyu2TaPHXwyPW9muUi1eKSFA6Qg4lw==", "dev": true }, + "spawn-wrap": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.2.tgz", + "integrity": "sha512-vMwR3OmmDhnxCVxM8M+xO/FtIp6Ju/mNaDfCMMW7FDcLRTPFWUswec4LXJHTJE2hwTI9O0YBfygu4DalFl7Ylg==", + "dev": true, + "requires": { + "foreground-child": "^1.5.6", + "mkdirp": "^0.5.0", + "os-homedir": "^1.0.1", + "rimraf": "^2.6.2", + "signal-exit": "^3.0.2", + "which": "^1.3.0" + } + }, "spdx-correct": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", @@ -8956,6 +8393,87 @@ "source-map-support": "~0.5.10" } }, + "test-exclude": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", + "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", + "dev": true, + "requires": { + "glob": "^7.1.3", + "minimatch": "^3.0.4", + "read-pkg-up": "^4.0.0", + "require-main-filename": "^2.0.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "read-pkg-up": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", + "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", + "dev": true, + "requires": { + "find-up": "^3.0.0", + "read-pkg": "^3.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } + } + }, "through2": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", @@ -9073,16 +8591,24 @@ "dev": true }, "ts-node": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.0.3.tgz", - "integrity": "sha512-2qayBA4vdtVRuDo11DEFSsD/SFsBXQBRZZhbRGSIkmYmVkWjULn/GGMdG10KVqkaGndljfaTD8dKjWgcejO8YA==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.2.0.tgz", + "integrity": "sha512-m8XQwUurkbYqXrKqr3WHCW310utRNvV5OnRVeISeea7LoCWVcdfeB/Ntl8JYWFh+WRoUAdBgESrzKochQt7sMw==", "dev": true, "requires": { "arg": "^4.1.0", - "diff": "^3.1.0", + "diff": "^4.0.1", "make-error": "^1.1.1", "source-map-support": "^0.5.6", "yn": "^3.0.0" + }, + "dependencies": { + "diff": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", + "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==", + "dev": true + } } }, "tslib": { @@ -9092,18 +8618,18 @@ "dev": true }, "tslint": { - "version": "5.15.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.15.0.tgz", - "integrity": "sha512-6bIEujKR21/3nyeoX2uBnE8s+tMXCQXhqMmaIPJpHmXJoBJPTLcI7/VHRtUwMhnLVdwLqqY3zmd8Dxqa5CVdJA==", + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.17.0.tgz", + "integrity": "sha512-pflx87WfVoYepTet3xLfDOLDm9Jqi61UXIKePOuca0qoAZyrGWonDG9VTbji58Fy+8gciUn8Bt7y69+KEVjc/w==", "dev": true, "requires": { - "babel-code-frame": "^6.22.0", + "@babel/code-frame": "^7.0.0", "builtin-modules": "^1.1.1", "chalk": "^2.3.0", "commander": "^2.12.1", "diff": "^3.2.0", "glob": "^7.1.1", - "js-yaml": "^3.13.0", + "js-yaml": "^3.13.1", "minimatch": "^3.0.4", "mkdirp": "^0.5.1", "resolve": "^1.3.2", @@ -9112,6 +8638,16 @@ "tsutils": "^2.29.0" }, "dependencies": { + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, "tsutils": { "version": "2.29.0", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", @@ -9202,11 +8738,22 @@ "dev": true }, "typescript": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.3.tgz", - "integrity": "sha512-FFgHdPt4T/duxx6Ndf7hwgMZZjZpB+U0nMNGVCYPq0rEzWKjEDobm4J6yb3CS7naZ0yURFqdw9Gwc7UOh/P9oQ==", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.1.tgz", + "integrity": "sha512-64HkdiRv1yYZsSe4xC1WVgamNigVYjlssIoaH2HcZF0+ijsk5YK2g0G34w9wJkze8+5ow4STd22AynfO6ZYYLw==", "dev": true }, + "uglify-js": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz", + "integrity": "sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg==", + "dev": true, + "optional": true, + "requires": { + "commander": "~2.20.0", + "source-map": "~0.6.1" + } + }, "uncss": { "version": "0.16.2", "resolved": "https://registry.npmjs.org/uncss/-/uncss-0.16.2.tgz", @@ -9636,6 +9183,17 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, + "write-file-atomic": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", + "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, "ws": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", diff --git a/package.json b/package.json index 626841cc..b5bb4549 100644 --- a/package.json +++ b/package.json @@ -179,11 +179,11 @@ "@sourcegraph/tsconfig": "^4.0.0", "@sourcegraph/tslint-config": "^13.2.0", "@types/expect": "1.20.4", - "@types/lodash": "4.14.123", - "@types/mocha": "5.2.6", + "@types/lodash": "4.14.133", + "@types/mocha": "5.2.7", "@types/mock-require": "2.0.0", "@types/node": "11.13.3", - "@types/sinon": "7.0.11", + "@types/sinon": "7.0.12", "expect": "24.1.0", "lnfs-cli": "^2.1.0", "lodash": "^4.17.11", @@ -192,13 +192,13 @@ "mock-require": "^3.0.3", "nyc": "^14.1.0", "parcel-bundler": "^1.12.3", - "prettier": "1.17.0", + "prettier": "1.17.1", "rxjs": "^6.5.1", "sinon": "^7.3.2", "source-map-support": "^0.5.12", "sourcegraph": "^23.0.1", "ts-node": "^8.1.0", - "tslint": "^5.16.0", + "tslint": "^5.17.0", "typescript": "^3.4.5" } } diff --git a/src/extension.ts b/src/extension.ts index 95f21a5b..56fbd23b 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -4,32 +4,25 @@ import * as sourcegraph from 'sourcegraph' import { createDecoration, getParamsFromUriPath, matchSentryProject } from './handler' import { resolveSettings, SentryProject, Settings } from './settings' -/** - * Params derived from the document's URI. - */ -interface Params { - repo: string | null - file: string | null -} - /** * Common error log patterns to use in case no line matching regexes * are set in the sentry extension settings. */ +// TODO: Add these to the Readme const COMMON_ERRORLOG_PATTERNS = [ // typescript/javascript - /throw new Error+\(['"]([^'"]+)['"]\)/gi, - /console\.(error|info|warn)\(['"`]([^'"`]+)['"`]\)/gi, + /throw new [A-Za-z0-9]+\(['"]([^'"]+)['"]\)/gi, + /console\.(?:error|info|warn)\(['"`]([^'"`]+)['"`]\)/gi, // go - /log\.(Printf|Print|Println)\(['"]([^'"]+)['"]\)/gi, + /log\.(?:Printf|Print|Println)\(['"]([^'"]+)['"]\)/gi, /fmt\.Errorf\(['"]([^'"]+)['"]\)/gi, /errors\.New\(['"]([^'"]+)['"]\)/gi, /err\.message\(['"`]([^'"`$]+)['"`]\)/gi, /panic\(['"]([^'"]+)['"]\)/gi, // python - /raise (TypeError|ValueError)\(['"`]([^'"`]+)['"`]\)/gi, + /raise (?:TypeError|ValueError)\(['"`]([^'"`]+)['"`]\)/gi, // java - /logger\.(debug|error)\(['"`]([^'"`]+)['"`]\);/gi, + /logger\.(?:debug|error)\(['"`]([^'"`]+)['"`]\);/gi, ] const DECORATION_TYPE = sourcegraph.app.createDecorationType() @@ -84,9 +77,11 @@ export function getDecorations( documentText: string, sentryProjects?: SentryProject[] ): sourcegraph.TextDocumentDecoration[] { - const params: Params = getParamsFromUriPath(documentUri) + const params = getParamsFromUriPath(documentUri) + if (!params || !params.file || !params.repo) { + return [] + } const matched = sentryProjects && matchSentryProject(params, sentryProjects) - // Do not decorate lines if the document file format does not match the // file matching patterns listed in the Sentry extension configurations. if (!matched) { @@ -95,8 +90,8 @@ export function getDecorations( return buildDecorations( matched.missingConfigs, documentText, - matched.project.projectId, - matched.project.linePatterns + matched.project && matched.project.projectId && matched.project.projectId, + matched.project && matched.project.linePatterns && matched.project.linePatterns ) } @@ -124,11 +119,12 @@ export function buildDecorations( for (const pattern of patterns) { do { match = pattern.exec(line) - // Depending on the line matching pattern the query m is indexed in position 1 or 2. - // TODO: Specify which capture group should be used through configuration. + // Depending on the line matching pattern the query m is indexed in position 1 or 2. if (match && match.length <= 2) { decorations.push(decorateLine(index, match[1], missingConfigData, sentryProjectId)) + // Safeguard if a user forgets to use `?:` and uncapture part of the error message that doesn't need to be captured. + // e.g. } else if (match && match.length > 2) { decorations.push(decorateLine(index, match[2], missingConfigData, sentryProjectId)) } @@ -189,7 +185,8 @@ function buildUrl(errorQuery: string, sentryProjectId?: string): URL { if (sentryProjectId) { url.searchParams.set('project', sentryProjectId) - url.searchParams.set('query', 'is:unresolved ' + errorQuery) + // Query must be wrapped in double quotes to be used as a search query in Sentry + url.searchParams.set('query', 'is:unresolved ' + '"' + errorQuery + '"') url.searchParams.set('statsPeriod', '14d') } diff --git a/src/handler.ts b/src/handler.ts index c2106017..27ac7235 100644 --- a/src/handler.ts +++ b/src/handler.ts @@ -17,21 +17,23 @@ export interface LineDecorationText { * @param textDocumentURI A document URI. * @returns repo and file part of URI. */ -export function getParamsFromUriPath(textDocumentURI: string): Params { - // TODO: Support more than just GitHub & Gitlab. - // TODO: Safeguard for cases where repo/fileMatch are null. - const repoPattern = /(github\.com|gitlab\.com)\/([^\?\#\/]+\/[^\?\#\/]*)/gi +export function getParamsFromUriPath(textDocumentURI: string): Params | null { const filePattern = /#(.*\.(.*))$/gi - const repoMatch = repoPattern.exec(textDocumentURI) - const fileMatch = filePattern.exec(textDocumentURI) - return { - repo: repoMatch && repoMatch[2], - file: fileMatch && fileMatch[1], + try { + const paramsRepo = new URL(textDocumentURI).pathname + const fileMatch = filePattern.exec(textDocumentURI) + return { + repo: paramsRepo, + file: fileMatch && fileMatch[1], + } + } catch (err) { + console.error(err) + return null } } interface Matched { - project: SentryProject + project: SentryProject | undefined missingConfigs: string[] } /** @@ -43,26 +45,35 @@ interface Matched { * @return Sentry projectID this document reports to. */ export function matchSentryProject(params: Params, projects: SentryProject[]): Matched | null { - if (!projects || !params.repo || !params.file) { + if (!params.repo || !params.file) { return null } + let missingConfigs // Check if a Sentry project is associated with this document's repository and/or file and retrieve the project. - // TODO: Handle the null case instead of using a non-null assertion ! - // TODO: Handle cases where the wrong project is matched due to similar repo name, - // e.g. `sourcegraph-jetbrains` repo will match the `sourcegraph` project - for (const project of projects) { - const missingConfigs = findEmptyConfigs(project) + for (const [index, project] of projects.entries()) { + missingConfigs = missingConfigs + ? missingConfigs.concat(findEmptyConfigs(project, 'project', index)) + : findEmptyConfigs(project, 'project', index) - for (const filter of project.filters) { - // both repository and file match - if (filter.files && !matchesFile(filter.files, params.file)) { - break - } + // If there is only one project in the settings and no filters, + // always match with that Sentry project + if (projects.length === 1) { + return { project, missingConfigs: [] } + } - if (filter.repositories && !matchesRepository(filter.repositories, params.repo)) { - break + if (project.filters) { + for (const filter of project.filters) { + if (filter.files && !matchesFile(filter.files, params.file)) { + break + } + + if (filter.repositories && !matchesRepository(filter.repositories, params.repo)) { + break + } + + // both repository and file match + return { project, missingConfigs } } - return { project, missingConfigs } } } return null @@ -80,22 +91,27 @@ function matchesFile(files: string[], fileParam: string): boolean { * Check for missing configurations in the Sentry extension settings * @param settings */ -export function findEmptyConfigs(settings?: SentryProject, path?: string): string[] { - if (!path) { - path = 'settings' - } - if (!settings) { +export function findEmptyConfigs(settings: SentryProject, path: string, index?: number): string[] { + // Check object key length to safeguard against user error of setting an empty repositories array + if ((!settings || Object.keys(settings).length === 0) && path) { return [path] } + // Add repositories to missingConfigs array when no settings.filters are set and return let missingConfigurations: string[] = [] - + if (settings instanceof Object && 'projectId' in settings && !settings.filters) { + return missingConfigurations.concat(path + '[' + index + '].filters[0].repositories') + } if (settings instanceof Array) { for (const [index, element] of settings.entries()) { missingConfigurations = missingConfigurations.concat(findEmptyConfigs(element, path + '[' + index + ']')) } } else if (settings instanceof Object) { for (const [k, v] of Object.entries(settings)) { + // Ensure that each project is indexed correctly + if (path === 'project') { + path += '[' + index + ']' + } missingConfigurations = missingConfigurations.concat(findEmptyConfigs(v, path + '.' + k)) } } @@ -129,7 +145,7 @@ export function createDecoration( return { content: ' View logs in Sentry (❕)» ', hover: - ' Please fill out the following configurations in your Sentry extension settings: ' + + ' Please fill out these configurations for better Sentry project matching: ' + missingConfigData.join(', '), } } diff --git a/src/settings.ts b/src/settings.ts index fdc8aec9..9e34ee28 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -11,11 +11,10 @@ export interface Settings { } export interface SentryProject { - name: string projectId: string // RexExp patterns to match log handeling code, e.g. /log\.(Printf|Print)\(['"]([^'"]+)['"]\)/ - linePatterns: string[] - filters: { + linePatterns?: string[] + filters?: { repositories?: string[] files?: string[] }[] diff --git a/src/test/extension.test.ts b/src/test/extension.test.ts index 2d6ab393..a3990f8f 100644 --- a/src/test/extension.test.ts +++ b/src/test/extension.test.ts @@ -16,33 +16,29 @@ describe('activation', () => { }) }) -const asString = (re: RegExp): string => re.source - const projects: SentryProject[] = [ { - name: 'Webapp typescript errors', projectId: '1334031', linePatterns: [ - /throw new Error+\(['"]([^'"]+)['"]\)/, - /console\.(warn|debug|info|error|log)\(['"`]([^'"`]+)['"`]\)/, - /log\.(Printf|Print|Println)\(['"]([^'"]+)['"]\)/, - ].map(asString), + 'throw new Error+\\([\'"]([^\'"]+)[\'"]\\)', + 'console\\.(?:warn|debug|info|error|log)\\([\'"`]([^\'"`]+)[\'"`]\\)', + 'log\\.(?:Printf|Print|Println)\\([\'"]([^\'"]+)[\'"]\\)', + ], filters: [ { - repositories: [/sourcegraph\/sourcegraph/, /bucket/].map(asString), - files: [/(web|shared|src)\/.*\.tsx?/, /\/.*\\.ts?/].map(asString), + repositories: ['sourcegraph/sourcegraph', '/bucket'], + files: ['(?:web|shared|src)/.*\\.tsx?', '\\.ts?'], }, ], }, { - name: 'Dev env errors', projectId: '213332', - linePatterns: [/log\.(Printf|Print|Println)\(['"]([^'"]+)['"]\)/].map(asString), + linePatterns: ['log\\.(Printf|Print|Println)\\([\'"]([^\'"]+)[\'"]\\)'], filters: [ { - repositories: [/dev-repo/].map(asString), - files: [/(dev)\/.*\\.go?/].map(asString), + repositories: ['/dev-repo'], + files: ['dev/.*\\.go?'], }, ], }, @@ -62,27 +58,25 @@ describe('resolveSettings()', () => { 'sentry.projects': [ { projectId: '1334031', - name: 'Webapp typescript errors', linePatterns: [ - /throw new Error+\(['"]([^'"]+)['"]\)/, - /console\.(warn|debug|info|error|log)\(['"`]([^'"`]+)['"`]\)/, - /log\.(Printf|Print|Println)\(['"]([^'"]+)['"]\)/, - ].map(asString), + 'throw new Error+\\([\'"]([^\'"]+)[\'"]\\)', + 'console\\.(?:warn|debug|info|error|log)\\([\'"`]([^\'"`]+)[\'"`]\\)', + 'log\\.(?:Printf|Print|Println)\\([\'"]([^\'"]+)[\'"]\\)', + ], filters: [ { - repositories: [/sourcegraph\/sourcegraph/, /bucket/].map(asString), - files: [/(web|shared|src)\/.*\.tsx?/, /\/.*\\.ts?/].map(asString), + repositories: ['sourcegraph/sourcegraph', '/bucket'], + files: ['(?:web|shared|src)/.*\\.tsx?', '\\.ts?'], }, ], }, { projectId: '213332', - name: 'Dev env errors', - linePatterns: [/log\.(Printf|Print|Println)\(['"]([^'"]+)['"]\)/].map(asString), + linePatterns: ['log\\.(Printf|Print|Println)\\([\'"]([^\'"]+)[\'"]\\)'], filters: [ { - repositories: [/dev-repo/].map(asString), - files: [/(dev)\/.*\\.go?/].map(asString), + repositories: ['/dev-repo'], + files: ['dev/.*\\.go?'], }, ], }, @@ -108,7 +102,7 @@ const decorateLineInput = [ contentText: ' View logs in Sentry » ', hoverMessage: ' View logs in Sentry » ', linkURL: - 'https://sentry.io/organizations/sourcegraph/issues/?project=134412&query=is%3Aunresolved+cannot+determine+file+path&statsPeriod=14d', + 'https://sentry.io/organizations/sourcegraph/issues/?project=134412&query=is%3Aunresolved+%22cannot+determine+file+path%22&statsPeriod=14d', }, }, }, @@ -127,7 +121,7 @@ const decorateLineInput = [ contentText: ' View logs in Sentry (❕)» ', hoverMessage: ' Add this repository to your Sentry extension settings for project matching.', linkURL: - 'https://sentry.io/organizations/sourcegraph/issues/?project=134412&query=is%3Aunresolved+cannot+determine+file+path&statsPeriod=14d', + 'https://sentry.io/organizations/sourcegraph/issues/?project=134412&query=is%3Aunresolved+%22cannot+determine+file+path%22&statsPeriod=14d', }, }, }, @@ -146,7 +140,7 @@ const decorateLineInput = [ contentText: ' View logs in Sentry (❕)» ', hoverMessage: ' Add this repository to your Sentry extension settings for project matching.', linkURL: - 'https://sentry.io/organizations/sourcegraph/issues/?project=134412&query=is%3Aunresolved+cannot+determine+file+path&statsPeriod=14d', + 'https://sentry.io/organizations/sourcegraph/issues/?project=134412&query=is%3Aunresolved+%22cannot+determine+file+path%22&statsPeriod=14d', }, }, }, @@ -226,7 +220,7 @@ const getDecorationsInput = [ contentText: ' View logs in Sentry » ', hoverMessage: ' View logs in Sentry » ', linkURL: - 'https://sentry.io/organizations/sourcegraph/issues/?project=1334031&query=is%3Aunresolved+cannot+determine+file+path&statsPeriod=14d', + 'https://sentry.io/organizations/sourcegraph/issues/?project=1334031&query=is%3Aunresolved+%22cannot+determine+file+path%22&statsPeriod=14d', }, }, { @@ -238,7 +232,7 @@ const getDecorationsInput = [ contentText: ' View logs in Sentry » ', hoverMessage: ' View logs in Sentry » ', linkURL: - 'https://sentry.io/organizations/sourcegraph/issues/?project=1334031&query=is%3Aunresolved+cannot+determine+delta+info&statsPeriod=14d', + 'https://sentry.io/organizations/sourcegraph/issues/?project=1334031&query=is%3Aunresolved+%22cannot+determine+delta+info%22&statsPeriod=14d', }, }, ], @@ -262,7 +256,7 @@ const getDecorationsInput = [ contentText: ' View logs in Sentry » ', hoverMessage: ' View logs in Sentry » ', linkURL: - 'https://sentry.io/organizations/sourcegraph/issues/?project=1334031&query=is%3Aunresolved+cannot+determine+file+path&statsPeriod=14d', + 'https://sentry.io/organizations/sourcegraph/issues/?project=1334031&query=is%3Aunresolved+%22cannot+determine+file+path%22&statsPeriod=14d', }, }, ], @@ -316,7 +310,7 @@ of(codeView).pipe( contentText: ' View logs in Sentry » ', hoverMessage: ' View logs in Sentry » ', linkURL: - 'https://sentry.io/organizations/sourcegraph/issues/?project=1334031&query=is%3Aunresolved+cannot+determine+file+path&statsPeriod=14d', + 'https://sentry.io/organizations/sourcegraph/issues/?project=1334031&query=is%3Aunresolved+%22cannot+determine+file+path%22&statsPeriod=14d', }, }, ], @@ -460,8 +454,8 @@ describe('buildDecorations()', () => { it('should not render anything due to missing code ', () => expect(buildDecorations([], '')).toEqual([])) // set linePatterns back to original state for the other tests projects[0].linePatterns = [ - /throw new Error+\(['"]([^'"]+)['"]\)/, - /console\.(warn|debug|info|error|log)\(['"`]([^'"`]+)['"`]\)/, - /log\.(Printf|Print|Println)\(['"]([^'"]+)['"]\)/, - ].map(asString) + 'throw new Error+\\([\'"]([^\'"]+)[\'"]\\)', + 'console\\.(?:warn|debug|info|error|log)\\([\'"`]([^\'"`]+)[\'"`]\\)', + 'log\\.(?:Printf|Print|Println)\\([\'"]([^\'"]+)[\'"]\\)', + ] }) diff --git a/src/test/handler.test.ts b/src/test/handler.test.ts index 35a9adee..fb914b1e 100644 --- a/src/test/handler.test.ts +++ b/src/test/handler.test.ts @@ -9,54 +9,48 @@ mock('sourcegraph', sourcegraph) import { createDecoration, findEmptyConfigs, getParamsFromUriPath, matchSentryProject } from '../handler' import { SentryProject } from '../settings' -const asString = (re: RegExp): string => re.source - const projects: SentryProject[] = [ { - name: 'Webapp typescript errors', projectId: '1334031', - linePatterns: [ - /throw new Error+\(['"]([^'"]+)['"]\)/, - /console\.(warn|debug|info|error|log)\(['"`]([^'"`]+)['"`]\)/, - /log\.(Printf|Print|Println)\(['"]([^'"]+)['"]\)/, - ].map(asString), filters: [ { - repositories: [/sourcegraph\/sourcegraph/, /bucket/].map(asString), - files: [/(web|shared|src)\/.*\.tsx?/, /\/.*\\.ts?/].map(asString), + repositories: ['/sourcegraph/sourcegraph', '/bucket'], + files: ['(?:web|shared|src)/.*\\.tsx?', '\\.ts?'], }, ], + linePatterns: [ + 'throw new Error+\\([\'"]([^\'"]+)[\'"]\\)', + 'console\\.(?:warn|debug|info|error|log)\\([\'"`]([^\'"`]+)[\'"`]\\)', + 'log\\.(Printf|Print|Println)\\([\'"]([^\'"]+)[\'"]\\)', + ], }, { - name: 'Dev env errors', projectId: '213332', - linePatterns: [/log\.(Printf|Print|Println)\(['"]([^'"]+)['"]\)/].map(asString), filters: [ { - repositories: [/dev-repo/].map(asString), - files: [/dev\/.*.go?/].map(asString), + repositories: ['/dev-repo'], + files: ['dev/.*\\.go?'], }, ], + linePatterns: ['log\\.(?:Printf|Print|Println)\\([\'"]([^\'"]+)[\'"]\\)'], }, { - name: 'docs pages errors', projectId: '544533', - linePatterns: [/throw new Error+\(['"]([^'"]+)['"]\)/].map(asString), filters: [ { - repositories: [/sourcegraph\/docs/].map(asString), + repositories: ['/sourcegraph/docs'], }, ], + linePatterns: ['throw new Error+\\([\'"]([^\'"]+)[\'"]\\)'], }, { - name: 'dot com errors', projectId: '242677', - linePatterns: [/throw new Error+\(['"]([^'"]+)['"]\)/].map(asString), filters: [ { - files: [/\.tsx?/].map(asString), + files: ['\\.tsx?'], }, ], + linePatterns: ['throw new Error+\\([\'"]([^\'"]+)[\'"]\\)'], }, ] @@ -66,10 +60,9 @@ const setDefaults = async () => { } describe('getParamsFromUriPath', () => { - beforeEach(setDefaults) it('extracts repo and file params from root folder', () => expect(getParamsFromUriPath('git://github.com/sourcegraph/sourcegraph?264...#index.tsx')).toEqual({ - repo: 'sourcegraph/sourcegraph', + repo: '/sourcegraph/sourcegraph', file: 'index.tsx', })) @@ -77,76 +70,73 @@ describe('getParamsFromUriPath', () => { expect( getParamsFromUriPath('git://github.com/sourcegraph/sourcegraph?264...#web/src/e2e/index.e2e.test.tsx') ).toEqual({ - repo: 'sourcegraph/sourcegraph', + repo: '/sourcegraph/sourcegraph', file: 'web/src/e2e/index.e2e.test.tsx', })) - it('return empty repo if host is not GitHub', () => - expect(getParamsFromUriPath('git://unknownhost.com/sourcegraph/testrepo#http/req/main.go')).toEqual({ - repo: null, - file: 'http/req/main.go', - })) + it('returns null if URI is corrupted', () => expect(getParamsFromUriPath('thisisnotavaliduri')).toEqual(null)) - it('return empty file if document has no file format', () => - expect(getParamsFromUriPath('git://github.com/sourcegraph/sourcegraph/testrepo#formatless')).toEqual({ - repo: 'sourcegraph/sourcegraph', + it('returns empty file if document has no file format', () => + expect(getParamsFromUriPath('git://github.com/sourcegraph/testrepo#formatless')).toEqual({ + repo: '/sourcegraph/testrepo', file: null, })) }) const paramsInput = [ { - goal: 'returns a web project that matches the repo and file patterns', + goal: 'returns a web project that matches the repo and file patterns and an empty missingConfigs list', params: { - repo: 'sourcegraph/sourcegraph', + repo: '/sourcegraph/sourcegraph', file: 'web/src/storm/index.tsx', }, expected: { project: projects[0], missingConfigs: [] }, }, { - goal: 'returns a dev project that matches the repo and file patterns', + goal: 'does not return a web project, as the params repo does not match the config repo, despite being similar', params: { - repo: 'sourcegraph/dev-repo', - file: 'dev/backend/main.go', + repo: '/different-sourcegraph/docs', + file: 'web/src/storm/index.md', }, - expected: { project: projects[1], missingConfigs: [] }, + expected: null, }, { - goal: 'returns file false for not matching file patterns', + goal: 'returns a dev project that matches the repo and file patterns and an empty missingConfigs list', params: { - repo: 'sourcegraph/dev-repo', - file: 'dev/test/start.rb', + repo: '/sourcegraph/dev-repo', + file: 'dev/backend/main.go', }, - expected: null, + expected: { project: projects[1], missingConfigs: [] }, }, { - goal: 'returns undefined for not matching repo and false for not matching file patterns', + goal: 'returns null for not matching file patterns', params: { - repo: 'sourcegraph/test-repo', + repo: '/sourcegraph/dev-repo', file: 'dev/test/start.rb', }, expected: null, }, { - goal: 'returns undefined for not matching repo and file patterns', + goal: 'returns null for not matching repo and file patterns', params: { - repo: 'sourcegraph/test-repo', + repo: '/sourcegraph/test-repo', file: 'dev/test/start.rb', }, expected: null, }, { - goal: 'returns project for matching repo and undefined for not having file patterns', + goal: 'returns project for matching repo despite not having a files config and an empty missingConfigs list', params: { - repo: 'sourcegraph/docs', + repo: '/sourcegraph/docs', file: 'src/development/tutorial.tsx', }, expected: { project: projects[2], missingConfigs: [] }, }, { - goal: 'returns project for matching file patterns', + goal: + 'returns project for matching file patterns despite not having a repositories config and an empty missingConfigs list', params: { - repo: 'sourcegraph/website', + repo: '/sourcegraph/website', file: 'web/search/start.tsx', }, expected: { project: projects[3], missingConfigs: [] }, @@ -164,40 +154,85 @@ const incompleteConfigs: { goal: string; settings: SentryProject; expected: stri { goal: 'returns one missing config', settings: { - name: 'sourcegraph', projectId: '1334031', - linePatterns: [/logger\.debug\(['"`]([^'"`]+)['"`]\);/].map(asString), + linePatterns: ['logger\\.debug\\([\'"`]([^\'"`]+)[\'"`]\\);'], filters: [ { - repositories: undefined, - files: [/(web|shared|src).*\.java?/, /(dev|src).*\.java?/, /.java?/].map(asString), + repositories: [], + files: ['(?:web|shared|src)/.*\\.java?', '(?:dev|src)/.*\\.java?', '\\.java?'], }, ], }, - expected: ['settings.filters[0].repositories'], + expected: ['project[0].filters[0].repositories'], }, { - goal: 'returns two missing configs', + goal: 'returns two missing configs with correct indexes', settings: { - name: 'sourcegraph', projectId: '', - linePatterns: [/logger\.debug\(['"`]([^'"`]+)['"`]\);/].map(asString), + linePatterns: ['logger\\.debug\\([\'"`]([^\'"`]+)[\'"`]\\);'], + filters: [ + { + repositories: [], + files: ['(?:web|shared|src)/.*\\.java?', '(?:dev|src)/.*\\.java?', '\\.java?'], + }, + ], + }, + expected: ['project[1].projectId', 'project[1].filters[0].repositories'], + }, + { + goal: 'returns two missing configs with correct indexes', + settings: { + projectId: '1334031', + linePatterns: ['logger\\.debug\\([\'"`]([^\'"`]+)[\'"`]\\);'], filters: [ { - repositories: undefined, - files: [/(web|shared|src).*\.java?/, /(dev|src).*\.java?/, /.java?/].map(asString), + repositories: [], + files: [], }, ], }, - expected: ['settings.projectId', 'settings.filters[0].repositories'], + expected: ['project[2].filters[0].repositories', 'project[2].filters[0].files'], + }, + { + goal: 'returns three missing configs with correct indexes', + settings: { + projectId: '', + linePatterns: ['logger\\.debug\\([\'"`]([^\'"`]+)[\'"`]\\);'], + filters: [ + { + repositories: [], + files: [], + }, + ], + }, + expected: ['project[3].projectId', 'project[3].filters[0].repositories', 'project[3].filters[0].files'], + }, + { + goal: 'returns one missing config and does not expect a files filter', + settings: { + projectId: '425773', + linePatterns: ['logger\\.debug\\([\'"`]([^\'"`]+)[\'"`]\\);'], + filters: [ + { + repositories: [], + }, + ], + }, + expected: ['project[4].filters[0].repositories'], + }, + { + goal: 'returns one missing config and does not expect a files filter', + settings: { + projectId: '425773', + }, + expected: ['project[5].filters[0].repositories'], }, ] describe('findEmptyConfigs()', () => { - for (const config of incompleteConfigs) { - it(config.goal, () => expect(findEmptyConfigs(config.settings)).toEqual(config.expected)) + for (const [index, config] of incompleteConfigs.entries()) { + it(config.goal, () => expect(findEmptyConfigs(config.settings, 'project', index)).toEqual(config.expected)) } - it('handles empty settings', () => expect(findEmptyConfigs()).toEqual(['settings'])) }) const createDecorationInputs = [ @@ -230,8 +265,7 @@ const createDecorationInputs = [ params: { missingConfigData: ['linePatterns', 'files'], sentryProjectId: '1334031', sentryOrg: 'sourcegraph' }, expected: { content: ' View logs in Sentry (❕)» ', - hover: - ' Please fill out the following configurations in your Sentry extension settings: linePatterns, files', + hover: ' Please fill out these configurations for better Sentry project matching: linePatterns, files', }, }, ] diff --git a/yarn.lock b/yarn.lock index c04b1890..5d11d0ce 100644 --- a/yarn.lock +++ b/yarn.lock @@ -29,7 +29,7 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.0.0 <7.4.0", "@babel/generator@^7.3.4": +"@babel/generator@^7.0.0 <7.4.0": version "7.3.4" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.3.4.tgz#9aa48c1989257877a9d971296e5b73bfe72e446e" integrity sha512-8EXhHRFqlVVWXPezBW5keTiQi/rJMQTg/Y9uVCEZ0CAF3PKtCCaVRnp64Ii1ujhkoDhhF1fVsImoN4yJ2uz4Wg== @@ -40,7 +40,7 @@ source-map "^0.5.0" trim-right "^1.0.1" -"@babel/generator@^7.4.0", "@babel/generator@^7.4.4": +"@babel/generator@^7.3.4", "@babel/generator@^7.4.0", "@babel/generator@^7.4.4": version "7.4.4" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.4.4.tgz#174a215eb843fc392c7edcaabeaa873de6e8f041" integrity sha512-53UOLK6TVNqKxf7RUh8NE851EHRxOOeVXKbK2bivdb+iziMyk03Sr4eaE9OELCbyZAAafAKPDwF2TPUES5QbxQ== @@ -197,14 +197,7 @@ "@babel/template" "^7.1.0" "@babel/types" "^7.0.0" -"@babel/helper-split-export-declaration@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz#3aae285c0311c2ab095d997b8c9a94cad547d813" - integrity sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag== - dependencies: - "@babel/types" "^7.0.0" - -"@babel/helper-split-export-declaration@^7.4.4": +"@babel/helper-split-export-declaration@^7.0.0", "@babel/helper-split-export-declaration@^7.4.4": version "7.4.4" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz#ff94894a340be78f53f06af038b205c49d993677" integrity sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q== @@ -239,12 +232,12 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@^7.0.0 <7.4.0", "@babel/parser@^7.2.2", "@babel/parser@^7.3.4": +"@babel/parser@^7.0.0 <7.4.0": version "7.3.4" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.3.4.tgz#a43357e4bbf4b92a437fb9e465c192848287f27c" integrity sha512-tXZCqWtlOOP4wgCp6RjRvLmfuhnqTLy9VHwRochJBCP2nDm27JnnuFEnXFASVyQNHk36jD1tAammsCEEqgscIQ== -"@babel/parser@^7.4.3", "@babel/parser@^7.4.4": +"@babel/parser@^7.2.2", "@babel/parser@^7.3.4", "@babel/parser@^7.4.3", "@babel/parser@^7.4.4": version "7.4.4" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.4.4.tgz#5977129431b8fe33471730d255ce8654ae1250b6" integrity sha512-5pCS4mOsL+ANsFZGdvNLybx4wtqAZJ0MJjMHxvzI3bvIsz6sQvzW8XX92EYIkiPtIvcfG3Aj+Ir5VNyjnZhP7w== @@ -636,7 +629,7 @@ dependencies: regenerator-runtime "^0.12.0" -"@babel/template@^7.0.0 <7.4.0", "@babel/template@^7.1.0", "@babel/template@^7.1.2", "@babel/template@^7.2.2": +"@babel/template@^7.0.0 <7.4.0": version "7.2.2" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.2.2.tgz#005b3fdf0ed96e88041330379e0da9a708eb2907" integrity sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g== @@ -645,7 +638,7 @@ "@babel/parser" "^7.2.2" "@babel/types" "^7.2.2" -"@babel/template@^7.4.0": +"@babel/template@^7.1.0", "@babel/template@^7.1.2", "@babel/template@^7.2.2", "@babel/template@^7.4.0": version "7.4.4" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.4.4.tgz#f4b88d1225689a08f5bc3a17483545be9e4ed237" integrity sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw== @@ -654,7 +647,7 @@ "@babel/parser" "^7.4.4" "@babel/types" "^7.4.4" -"@babel/traverse@^7.0.0 <7.4.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.1.5", "@babel/traverse@^7.3.4": +"@babel/traverse@^7.0.0 <7.4.0": version "7.3.4" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.3.4.tgz#1330aab72234f8dea091b08c4f8b9d05c7119e06" integrity sha512-TvTHKp6471OYEcE/91uWmhR6PrrYywQntCHSaZ8CM8Vmp+pjAusal4nGB2WCCQd0rvI7nOMKn9GnbcvTUz3/ZQ== @@ -669,7 +662,7 @@ globals "^11.1.0" lodash "^4.17.11" -"@babel/traverse@^7.4.3": +"@babel/traverse@^7.1.0", "@babel/traverse@^7.1.5", "@babel/traverse@^7.3.4", "@babel/traverse@^7.4.3": version "7.4.4" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.4.4.tgz#0776f038f6d78361860b6823887d4f3937133fe8" integrity sha512-Gw6qqkw/e6AGzlyj9KnkabJX7VcubqPtkUQVAwkc0wUMldr3A/hezNB3Rc5eIvId95iSGkGIOe5hh1kMKf951A== @@ -684,19 +677,19 @@ globals "^11.1.0" lodash "^4.17.11" -"@babel/types@^7.0.0", "@babel/types@^7.0.0 <7.4.0", "@babel/types@^7.2.0", "@babel/types@^7.2.2", "@babel/types@^7.3.0", "@babel/types@^7.3.4": - version "7.3.4" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.3.4.tgz#bf482eaeaffb367a28abbf9357a94963235d90ed" - integrity sha512-WEkp8MsLftM7O/ty580wAmZzN1nDmCACc5+jFzUt+GUFNNIi3LdRlueYz0YIlmJhlZx1QYDMZL5vdWCL0fNjFQ== +"@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.2.2", "@babel/types@^7.3.0", "@babel/types@^7.3.4", "@babel/types@^7.4.0", "@babel/types@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.4.4.tgz#8db9e9a629bb7c29370009b4b779ed93fe57d5f0" + integrity sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ== dependencies: esutils "^2.0.2" lodash "^4.17.11" to-fast-properties "^2.0.0" -"@babel/types@^7.4.0", "@babel/types@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.4.4.tgz#8db9e9a629bb7c29370009b4b779ed93fe57d5f0" - integrity sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ== +"@babel/types@^7.0.0 <7.4.0": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.3.4.tgz#bf482eaeaffb367a28abbf9357a94963235d90ed" + integrity sha512-WEkp8MsLftM7O/ty580wAmZzN1nDmCACc5+jFzUt+GUFNNIi3LdRlueYz0YIlmJhlZx1QYDMZL5vdWCL0fNjFQ== dependencies: esutils "^2.0.2" lodash "^4.17.11" @@ -890,15 +883,15 @@ resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.0.tgz#1eb8c033e98cf4e1a4cedcaf8bcafe8cb7591e85" integrity sha512-eAtOAFZefEnfJiRFQBGw1eYqa5GTLCZ1y86N0XSI/D6EB+E8z6VPV/UL7Gi5UEclFqoQk+6NRqEDsfmDLXn8sg== -"@types/lodash@4.14.123": - version "4.14.123" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.123.tgz#39be5d211478c8dd3bdae98ee75bb7efe4abfe4d" - integrity sha512-pQvPkc4Nltyx7G1Ww45OjVqUsJP4UsZm+GWJpigXgkikZqJgRm4c48g027o6tdgubWHwFRF15iFd+Y4Pmqv6+Q== +"@types/lodash@4.14.133": + version "4.14.133" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.133.tgz#430721c96da22dd1694443e68e6cec7ba1c1003d" + integrity sha512-/3JqnvPnY58GLzG3Y7fpphOhATV1DDZ/Ak3DQufjlRK5E4u+s0CfClfNFtAGBabw+jDGtRFbOZe+Z02ZMWCBNQ== -"@types/mocha@5.2.6": - version "5.2.6" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.2.6.tgz#b8622d50557dd155e9f2f634b7d68fd38de5e94b" - integrity sha512-1axi39YdtBI7z957vdqXI4Ac25e7YihYQtJa+Clnxg1zTJEaIRbndt71O3sP4GAMgiAm0pY26/b9BrY4MR/PMw== +"@types/mocha@5.2.7": + version "5.2.7" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.2.7.tgz#315d570ccb56c53452ff8638738df60726d5b6ea" + integrity sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ== "@types/mock-require@2.0.0": version "2.0.0" @@ -922,6 +915,11 @@ resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-7.0.11.tgz#6f28f005a36e779b7db0f1359b9fb9eef72aae88" integrity sha512-6ee09Ugx6GyEr0opUIakmxIWFNmqYPjkqa3/BuxCBokA0klsOLPgMD5K4q40lH7/yZVuJVzOfQpd7pipwjngkQ== +"@types/sinon@7.0.12": + version "7.0.12" + resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-7.0.12.tgz#18412939ae45b225bd38715a25c1040cbad80f42" + integrity sha512-fo0MWpVPSUrnZZhp9wyu+hhI3VJ9+Jhs+PWrokBTg3d2ryNPDOAWF1csIhQuYWBTn7KdZzXpRgpX2o6cwOlPWg== + "@types/stack-utils@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" @@ -3472,7 +3470,7 @@ js-levenshtein@^1.1.3: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@3.13.1, js-yaml@^3.13.1: +js-yaml@3.13.1, js-yaml@^3.10.0, js-yaml@^3.12.0, js-yaml@^3.13.1, js-yaml@^3.9.0: version "3.13.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== @@ -3480,14 +3478,6 @@ js-yaml@3.13.1, js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" -js-yaml@^3.10.0, js-yaml@^3.12.0, js-yaml@^3.13.0, js-yaml@^3.9.0: - version "3.13.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.0.tgz#38ee7178ac0eea2c97ff6d96fff4b18c7d8cf98e" - integrity sha512-pZZoSxcCYco+DIKBTimr67J6Hy+EYGZDY/HCWC+iAEA9h1ByhMXAIVUXMcMFpOCxQ/xjXmPI2MkDL5HRm5eFrQ== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" @@ -5092,10 +5082,10 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= -prettier@1.17.0: - version "1.17.0" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.17.0.tgz#53b303676eed22cc14a9f0cec09b477b3026c008" - integrity sha512-sXe5lSt2WQlCbydGETgfm1YBShgOX4HxQkFPvbxkcwgDvGDeqVau8h+12+lmSVlP3rHPz0oavfddSZg/q+Szjw== +prettier@1.17.1: + version "1.17.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.17.1.tgz#ed64b4e93e370cb8a25b9ef7fef3e4fd1c0995db" + integrity sha512-TzGRNvuUSmPgwivDqkZ9tM/qTGW9hqDKWOE9YHiyQdixlKbv7kvEqsmDPrcHJTKwthU774TQwZXVtaQ/mMsvjg== pretty-format@^24.7.0: version "24.7.0" @@ -5596,12 +5586,7 @@ sax@^1.2.4, sax@~1.2.4: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== -"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.6.0: - version "5.6.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" - integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== - -semver@^5.7.0: +"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.6.0, semver@^5.7.0: version "5.7.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== @@ -6256,10 +6241,10 @@ tslint-react@^4.0.0: dependencies: tsutils "^3.9.1" -tslint@^5.16.0: - version "5.16.0" - resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.16.0.tgz#ae61f9c5a98d295b9a4f4553b1b1e831c1984d67" - integrity sha512-UxG2yNxJ5pgGwmMzPMYh/CCnCnh0HfPgtlVRDs1ykZklufFBL1ZoTlWFRz2NQjcoEiDoRp+JyT0lhBbbH/obyA== +tslint@^5.17.0: + version "5.17.0" + resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.17.0.tgz#f9f0ce2011d8e90debaa6e9b4975f24cd16852b8" + integrity sha512-pflx87WfVoYepTet3xLfDOLDm9Jqi61UXIKePOuca0qoAZyrGWonDG9VTbji58Fy+8gciUn8Bt7y69+KEVjc/w== dependencies: "@babel/code-frame" "^7.0.0" builtin-modules "^1.1.1" @@ -6267,7 +6252,7 @@ tslint@^5.16.0: commander "^2.12.1" diff "^3.2.0" glob "^7.1.1" - js-yaml "^3.13.0" + js-yaml "^3.13.1" minimatch "^3.0.4" mkdirp "^0.5.1" resolve "^1.3.2"