diff --git a/.eslintignore b/.eslintignore index f52cb1b45b89..66d4fa776cff 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,12 +1,8 @@ # THIS IS A TEMPORARY FILE # THIS WILL BE REMOVED AFTER WE FINISH ESLINT UPGRADE -packages/apm/**/* -packages/ember/**/* -packages/gatsby/**/* packages/integrations/**/* packages/node/**/* packages/react/**/* packages/tracing/**/* packages/typescript/**/* -packages/utils/**/* diff --git a/.eslintrc.js b/.eslintrc.js index 722b72439983..64f5f023ccb1 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -3,8 +3,8 @@ module.exports = { env: { node: true, }, - extends: ['prettier', 'eslint:recommended'], - plugins: ['sentry-sdk', 'jsdoc'], + extends: ['prettier', 'eslint:recommended', 'plugin:import/errors', 'plugin:import/warnings'], + plugins: ['sentry-sdk', 'simple-import-sort'], ignorePatterns: ['eslint-plugin-sentry-sdk'], overrides: [ { @@ -17,8 +17,8 @@ module.exports = { { // Configuration for typescript files files: ['*.ts', '*.tsx', '*.d.ts'], - extends: ['plugin:@typescript-eslint/recommended', 'prettier/@typescript-eslint'], - plugins: ['@typescript-eslint'], + extends: ['plugin:@typescript-eslint/recommended', 'prettier/@typescript-eslint', 'plugin:import/typescript'], + plugins: ['@typescript-eslint', 'jsdoc', 'deprecation'], parser: '@typescript-eslint/parser', parserOptions: { project: './tsconfig.json', @@ -68,6 +68,25 @@ module.exports = { leadingUnderscore: 'require', }, ], + + // Prefer for-of loop over for loop if index is only used to access array + '@typescript-eslint/prefer-for-of': 'error', + + // Make sure all expressions are used. Turned off in tests + // Must disable base rule to prevent false positives + 'no-unused-expressions': 'off', + '@typescript-eslint/no-unused-expressions': 'error', + + // Make sure Promises are handled appropriately + '@typescript-eslint/no-floating-promises': 'error', + + // Do not use deprecated methods + 'deprecation/deprecation': 'error', + + // sort imports + 'simple-import-sort/sort': 'error', + 'sort-imports': 'off', + 'import/order': 'off', }, }, { @@ -95,6 +114,8 @@ module.exports = { 'max-lines': 'off', '@typescript-eslint/explicit-function-return-type': 'off', + 'no-unused-expressions': 'off', + '@typescript-eslint/no-unused-expressions': 'off', }, }, { @@ -128,5 +149,20 @@ module.exports = { // We should require a whitespace beginning a comment 'spaced-comment': 'error', + + // Disallow usage of bitwise operators - this makes it an opt in operation + 'no-bitwise': 'error', + + // Limit cyclomatic complexity + complexity: 'error', + + // Make sure all expressions are used. Turn off on tests. + 'no-unused-expressions': 'error', + + // We shouldn't make assumptions about imports/exports being dereferenced. + 'import/namespace': 'off', + + // imports should be ordered. + 'import/order': ['error', { 'newlines-between': 'always' }], }, }; diff --git a/.gitignore b/.gitignore index 13e3a16d7665..9163b7c1e557 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,7 @@ lint-results.json # legacy tmp.js + +# eslint +.eslintcache +eslintcache/* diff --git a/dangerfile.ts b/dangerfile.ts index 56f90cf5c0e9..61e840109bbe 100644 --- a/dangerfile.ts +++ b/dangerfile.ts @@ -1,12 +1,12 @@ import { exec } from 'child_process'; import { danger, fail, message, schedule, warn } from 'danger'; -import { promisify } from 'util'; -import { resolve } from 'path'; import tslint from 'danger-plugin-tslint'; import { prettyResults } from 'danger-plugin-tslint/dist/prettyResults'; import { CLIEngine } from 'eslint'; +import { resolve } from 'path'; +import { promisify } from 'util'; -const PACKAGES = ['apm', 'integrations', 'node', 'utils']; +const PACKAGES = ['integrations', 'node']; const EXTENSIONS = ['.js', '.jsx', '.ts', '.tsx']; /** @@ -15,6 +15,7 @@ const EXTENSIONS = ['.js', '.jsx', '.ts', '.tsx']; */ async function eslint(): Promise { const allFiles = danger.git.created_files.concat(danger.git.modified_files); + // eslint-disable-next-line deprecation/deprecation const cli = new CLIEngine({}); // let eslint filter down to non-ignored, matching the extensions expected const filesToLint = allFiles.filter(f => !cli.isPathIgnored(f) && EXTENSIONS.some(ext => f.endsWith(ext))); @@ -22,6 +23,7 @@ async function eslint(): Promise { } /** JSDoc */ +// eslint-disable-next-line deprecation/deprecation async function lintFile(linter: CLIEngine, path: string): Promise { const contents = await danger.github.utils.fileContents(path); const report = linter.executeOnText(contents, path); diff --git a/package.json b/package.json index 7d562749076d..8a0a3a1f3492 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "yarn": "1.13.0" }, "workspaces": [ + "packages/angular", "packages/apm", "packages/browser", "packages/core", @@ -52,8 +53,11 @@ "danger-plugin-tslint": "^2.0.0", "eslint": "^7.5.0", "eslint-config-prettier": "^6.11.0", + "eslint-plugin-deprecation": "^1.1.0", + "eslint-plugin-import": "^2.22.0", "eslint-plugin-jsdoc": "^30.0.3", "eslint-plugin-sentry-sdk": "file:./eslint-plugin-sentry-sdk", + "eslint-plugin-simple-import-sort": "^5.0.3", "jest": "^24.7.1", "karma-browserstack-launcher": "^1.5.1", "karma-firefox-launcher": "^1.1.0", diff --git a/packages/angular/.eslintrc.js b/packages/angular/.eslintrc.js new file mode 100644 index 000000000000..bab76a513f84 --- /dev/null +++ b/packages/angular/.eslintrc.js @@ -0,0 +1,20 @@ +module.exports = { + root: true, + env: { + es6: true, + browser: true, + }, + parserOptions: { + ecmaVersion: 2018, + }, + extends: ['../../.eslintrc.js'], + ignorePatterns: ['build/**/*', 'dist/**/*', 'esm/**/*', 'examples/**/*', 'scripts/**/*'], + overrides: [ + { + files: ['*.ts', '*.tsx', '*.d.ts'], + parserOptions: { + project: './tsconfig.json', + }, + }, + ], +}; diff --git a/packages/angular/package.json b/packages/angular/package.json index a17815afa1e1..e1558202b94b 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -42,13 +42,12 @@ "build:watch:esm": "tsc -p tsconfig.esm.json -w --preserveWatchOutput", "clean": "rimraf dist coverage build esm", "link:yarn": "yarn link", - "lint": "run-s lint:prettier lint:tslint", - "lint:prettier": "prettier-check \"{src,test}/**/*.{ts,tsx}\"", - "lint:tslint": "tslint -t stylish -p .", - "lint:tslint:json": "tslint --format json -p . | tee lint-results.json", - "fix": "run-s fix:tslint fix:prettier", - "fix:prettier": "prettier --write \"{src,test}/**/*.{ts,tsx}\"", - "fix:tslint": "tslint --fix -t stylish -p ." + "lint": "run-s lint:prettier lint:eslint", + "lint:prettier": "prettier-check \"{src,test}/**/*.ts\"", + "lint:eslint": "eslint . --cache --cache-location '../../eslintcache/' --format stylish", + "fix": "run-s fix:eslint fix:prettier", + "fix:prettier": "prettier --write \"{src,test}/**/*.ts\"", + "fix:eslint": "eslint . --format stylish --fix" }, "sideEffects": false } diff --git a/packages/angular/src/errorhandler.ts b/packages/angular/src/errorhandler.ts index 9848a4f4bb57..456c67476bd2 100644 --- a/packages/angular/src/errorhandler.ts +++ b/packages/angular/src/errorhandler.ts @@ -61,6 +61,7 @@ class SentryErrorHandler implements AngularErrorHandler { // When in development mode, log the error to console for immediate feedback. if (this._options.logErrors) { + // eslint-disable-next-line no-console console.error(extractedError); } diff --git a/packages/angular/src/tracing.ts b/packages/angular/src/tracing.ts index 2a4b79335b88..03a09fafd27a 100644 --- a/packages/angular/src/tracing.ts +++ b/packages/angular/src/tracing.ts @@ -1,5 +1,3 @@ -// tslint:disable:max-classes-per-file - import { AfterViewInit, Directive, Injectable, Input, OnInit } from '@angular/core'; import { Event, NavigationEnd, NavigationStart, Router } from '@angular/router'; import { getCurrentHub } from '@sentry/browser'; @@ -54,14 +52,7 @@ export function getActiveTransaction(): Transaction | undefined { */ @Injectable({ providedIn: 'root' }) export class TraceService { - private routingSpan?: Span; - - public constructor(private readonly router: Router) { - this.navStart$.subscribe(); - this.navEnd$.subscribe(); - } - - public navStart$: Observable = this.router.events.pipe( + public navStart$: Observable = this._router.events.pipe( filter(event => event instanceof NavigationStart), tap(event => { if (!instrumentationInitialized) { @@ -80,7 +71,7 @@ export class TraceService { } if (activeTransaction) { - this.routingSpan = activeTransaction.startChild({ + this._routingSpan = activeTransaction.startChild({ description: `${navigationEvent.url}`, op: `angular.routing`, tags: { @@ -95,15 +86,22 @@ export class TraceService { }), ); - public navEnd$: Observable = this.router.events.pipe( + public navEnd$: Observable = this._router.events.pipe( filter(event => event instanceof NavigationEnd), tap(() => { - if (this.routingSpan) { - this.routingSpan.finish(); - delete this.routingSpan; + if (this._routingSpan) { + this._routingSpan.finish(); + delete this._routingSpan; } }), ); + + private _routingSpan?: Span; + + public constructor(private readonly _router: Router) { + this.navStart$.subscribe(); + this.navEnd$.subscribe(); + } } const UNKNOWN_COMPONENT = 'unknown'; @@ -113,10 +111,10 @@ const UNKNOWN_COMPONENT = 'unknown'; */ @Directive({ selector: '[trace]' }) export class TraceDirective implements OnInit, AfterViewInit { - private tracingSpan?: Span; - @Input('trace') public componentName: string = UNKNOWN_COMPONENT; + private _tracingSpan?: Span; + /** * Implementation of OnInit lifecycle method * @inheritdoc @@ -124,7 +122,7 @@ export class TraceDirective implements OnInit, AfterViewInit { public ngOnInit(): void { const activeTransaction = getActiveTransaction(); if (activeTransaction) { - this.tracingSpan = activeTransaction.startChild({ + this._tracingSpan = activeTransaction.startChild({ description: `<${this.componentName}>`, op: `angular.initialize`, }); @@ -136,8 +134,8 @@ export class TraceDirective implements OnInit, AfterViewInit { * @inheritdoc */ public ngAfterViewInit(): void { - if (this.tracingSpan) { - this.tracingSpan.finish(); + if (this._tracingSpan) { + this._tracingSpan.finish(); } } } @@ -148,10 +146,11 @@ export class TraceDirective implements OnInit, AfterViewInit { export function TraceClassDecorator(): ClassDecorator { let tracingSpan: Span; - return (target: Function) => { + // eslint-disable-next-line @typescript-eslint/explicit-function-return-type + return target => { // tslint:disable-next-line:no-unsafe-any const originalOnInit = target.prototype.ngOnInit; - // tslint:disable-next-line:no-unsafe-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any target.prototype.ngOnInit = function(...args: any[]): ReturnType { const activeTransaction = getActiveTransaction(); if (activeTransaction) { @@ -161,14 +160,12 @@ export function TraceClassDecorator(): ClassDecorator { }); } if (originalOnInit) { - // tslint:disable-next-line:no-unsafe-any return originalOnInit.apply(this, args); } }; - // tslint:disable-next-line:no-unsafe-any const originalAfterViewInit = target.prototype.ngAfterViewInit; - // tslint:disable-next-line:no-unsafe-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any target.prototype.ngAfterViewInit = function(...args: any[]): ReturnType { if (tracingSpan) { tracingSpan.finish(); @@ -185,8 +182,10 @@ export function TraceClassDecorator(): ClassDecorator { * Decorator function that can be used to capture a single lifecycle methods of the component. */ export function TraceMethodDecorator(): MethodDecorator { + // eslint-disable-next-line @typescript-eslint/explicit-function-return-type, @typescript-eslint/ban-types return (target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => { const originalMethod = descriptor.value; + // eslint-disable-next-line @typescript-eslint/no-explicit-any descriptor.value = function(...args: any[]): ReturnType { const now = timestampWithMs(); const activeTransaction = getActiveTransaction(); diff --git a/packages/angular/tslint.json b/packages/angular/tslint.json deleted file mode 100644 index 41756bd390dd..000000000000 --- a/packages/angular/tslint.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": ["@sentry/typescript/tslint"] -} diff --git a/packages/angular/yarn.lock b/packages/angular/yarn.lock deleted file mode 100644 index 1488531a7883..000000000000 --- a/packages/angular/yarn.lock +++ /dev/null @@ -1,735 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@angular/common@^10.0.3": - version "10.0.3" - resolved "https://registry.yarnpkg.com/@angular/common/-/common-10.0.3.tgz#35baf7e7673a2e9613f66a1a247fbfe476bf7943" - integrity sha512-R2q/Vt07PHgcmvZBVGcYjf6K2xERCHWUYQYN1HsgjVQUu5ypvE7Kqs+6s0BfIoBKc+ejKmjMHHumnm+89O+gXg== - dependencies: - tslib "^2.0.0" - -"@angular/core@^10.0.3": - version "10.0.3" - resolved "https://registry.yarnpkg.com/@angular/core/-/core-10.0.3.tgz#2cfef68c2ac088f9e1bf72cb4601391cff4f9c92" - integrity sha512-EfWAz5StlPYo2ZtvVzeoNlGrFAXRncwGd/CExbLFOZx4HcDXVkATw5d4vnKHmmKacDqnbuvMD2M0Tl0EJi5q4g== - dependencies: - tslib "^2.0.0" - -"@angular/router@^10.0.3": - version "10.0.4" - resolved "https://registry.yarnpkg.com/@angular/router/-/router-10.0.4.tgz#d68c2711b53f3bdc1508d9b7e90b181b4e09f42c" - integrity sha512-iDLWdmltU5pZ6M/fBKC5Kg2o9Aqb1YJ+oHXFu186BQAl2RNeNCmMQ0VaCxjpMgD/MoSxpuRuGQ6rRrCSFCxtcQ== - dependencies: - tslib "^2.0.0" - -"@babel/code-frame@^7.0.0": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" - integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg== - dependencies: - "@babel/highlight" "^7.10.4" - -"@babel/helper-validator-identifier@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2" - integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw== - -"@babel/highlight@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143" - integrity sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA== - dependencies: - "@babel/helper-validator-identifier" "^7.10.4" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@sentry/browser@5.19.1": - version "5.19.1" - resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-5.19.1.tgz#b22f36fc71f36719ad352a54e6b31722622128c0" - integrity sha512-Aon5Nc2n8sIXKg6Xbr4RM3/Xs7vFpXksL56z3yIuGrmpCM8ToQ25/tQv8h+anYi72x5bn1npzaXB/NwU1Qwfhg== - dependencies: - "@sentry/core" "5.19.1" - "@sentry/types" "5.19.1" - "@sentry/utils" "5.19.1" - tslib "^1.9.3" - -"@sentry/core@5.19.1": - version "5.19.1" - resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.19.1.tgz#f5ff7feb1118035f75f1d0bc2a76e2b040d2aa8e" - integrity sha512-BGGxjeT95Og/hloBhQXAVcndVXPmIU6drtF3oKRT12cBpiG965xEDEUwiJVvyb5MAvojdVEZBK2LURUFY/d7Zw== - dependencies: - "@sentry/hub" "5.19.1" - "@sentry/minimal" "5.19.1" - "@sentry/types" "5.19.1" - "@sentry/utils" "5.19.1" - tslib "^1.9.3" - -"@sentry/hub@5.19.1": - version "5.19.1" - resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.19.1.tgz#f3bc8500680974ce43c1eedcd8e90696cc18b306" - integrity sha512-XjfbNGWVeDsP38alm5Cm08YPIw5Hu6HbPkw7a3y1piViTrg4HdtsE+ZJqq0YcURo2RTpg6Ks6coCS/zJxIPygQ== - dependencies: - "@sentry/types" "5.19.1" - "@sentry/utils" "5.19.1" - tslib "^1.9.3" - -"@sentry/minimal@5.19.1": - version "5.19.1" - resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.19.1.tgz#04043d93a7dc90cbed1a31d80f6bf59688ea3100" - integrity sha512-pgNfsaCroEsC8gv+NqmPTIkj4wyK6ZgYLV12IT4k2oJLkGyg45TSAKabyB7oEP5jsj8sRzm8tDomu8M4HpaCHg== - dependencies: - "@sentry/hub" "5.19.1" - "@sentry/types" "5.19.1" - tslib "^1.9.3" - -"@sentry/types@5.19.1": - version "5.19.1" - resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.19.1.tgz#8762f668d3fc2416fbde31d15d13009544caeb54" - integrity sha512-M5MhTLnjqYFwxMwcFPBpBgYQqI9hCvtVuj/A+NvcBHpe7VWOXdn/Sys+zD6C76DWGFYQdw3OWCsZimP24dL8mA== - -"@sentry/utils@5.19.1": - version "5.19.1" - resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.19.1.tgz#e1134db40e4bb9732251e515721cec7ee94d4d9c" - integrity sha512-neUiNBnZSHjWTZWy2QV02EHTx1C2L3DBPzRXlh0ca5xrI7LMBLmhkHlhebn1E5ky3PW1teqZTgmh0jZoL99TEA== - dependencies: - "@sentry/types" "5.19.1" - tslib "^1.9.3" - -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -builtin-modules@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" - integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= - -chalk@^2.0.0, chalk@^2.3.0, chalk@^2.4.1: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= - -commander@^2.12.1: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -cross-spawn@^5.0.1: - version "5.1.0" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" - integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= - dependencies: - lru-cache "^4.0.1" - shebang-command "^1.2.0" - which "^1.2.9" - -cross-spawn@^6.0.5: - version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== - dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" - -define-properties@^1.1.2, define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== - dependencies: - object-keys "^1.0.12" - -diff@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - -error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -es-abstract@^1.17.0-next.1, es-abstract@^1.17.5: - version "1.17.6" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.6.tgz#9142071707857b2cacc7b89ecb670316c3e2d52a" - integrity sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw== - dependencies: - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - is-callable "^1.2.0" - is-regex "^1.1.0" - object-inspect "^1.7.0" - object-keys "^1.1.1" - object.assign "^4.1.0" - string.prototype.trimend "^1.0.1" - string.prototype.trimstart "^1.0.1" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - -esprima@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - -execa@^0.6.0: - version "0.6.3" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.6.3.tgz#57b69a594f081759c69e5370f0d17b9cb11658fe" - integrity sha1-V7aaWU8IF1nGnlNw8NF7nLEWWP4= - dependencies: - cross-spawn "^5.0.1" - get-stream "^3.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" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -get-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" - integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= - -glob@^7.1.1, glob@^7.1.3: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== - dependencies: - 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@^4.1.2: - version "4.2.4" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" - integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - -has-symbols@^1.0.0, has-symbols@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" - integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -hosted-git-info@^2.1.4: - version "2.8.8" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" - integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= - -is-callable@^1.1.4, is-callable@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.0.tgz#83336560b54a38e35e3a2df7afd0454d691468bb" - integrity sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw== - -is-date-object@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" - integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== - -is-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.0.tgz#ece38e389e490df0dc21caea2bd596f987f767ff" - integrity sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw== - dependencies: - has-symbols "^1.0.1" - -is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= - -is-symbol@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" - integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== - dependencies: - has-symbols "^1.0.1" - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - -js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@^3.13.1: - version "3.14.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482" - integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -json-parse-better-errors@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== - -load-json-file@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" - integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= - dependencies: - graceful-fs "^4.1.2" - parse-json "^4.0.0" - pify "^3.0.0" - strip-bom "^3.0.0" - -lru-cache@^4.0.1: - version "4.1.5" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" - integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - -memorystream@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" - integrity sha1-htcJCzDORV1j+64S3aUaR93K+bI= - -minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimist@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" - integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== - -mkdirp@^0.5.1: - version "0.5.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" - integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== - dependencies: - minimist "^1.2.5" - -nice-try@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== - -normalize-package-data@^2.3.2: - version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" - integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -npm-run-all@^4.1.2: - version "4.1.5" - resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.5.tgz#04476202a15ee0e2e214080861bff12a51d98fba" - integrity sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ== - dependencies: - ansi-styles "^3.2.1" - chalk "^2.4.1" - cross-spawn "^6.0.5" - memorystream "^0.3.1" - minimatch "^3.0.4" - pidtree "^0.3.0" - read-pkg "^3.0.0" - shell-quote "^1.6.1" - string.prototype.padend "^3.0.0" - -npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= - dependencies: - path-key "^2.0.0" - -object-inspect@^1.7.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0" - integrity sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA== - -object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object.assign@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" - integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== - dependencies: - define-properties "^1.1.2" - function-bind "^1.1.1" - has-symbols "^1.0.0" - object-keys "^1.0.11" - -once@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= - -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -path-key@^2.0.0, path-key@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= - -path-parse@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" - integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== - -path-type@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" - integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== - dependencies: - pify "^3.0.0" - -pidtree@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.3.1.tgz#ef09ac2cc0533df1f3250ccf2c4d366b0d12114a" - integrity sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA== - -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= - -prettier-check@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/prettier-check/-/prettier-check-2.0.0.tgz#edd086ee12d270579233ccb136a16e6afcfba1ae" - integrity sha512-HZG53XQTJ9Cyi5hi1VFVVFxdlhITJybpZAch3ib9KqI05VUxV+F5Hip0GhSWRItrlDzVyqjSoDQ9KqIn7AHYyw== - dependencies: - execa "^0.6.0" - -prettier@^1.17.0: - version "1.19.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" - integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== - -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= - -read-pkg@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" - integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= - dependencies: - load-json-file "^4.0.0" - normalize-package-data "^2.3.2" - path-type "^3.0.0" - -resolve@^1.10.0, resolve@^1.3.2: - version "1.17.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" - integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== - dependencies: - path-parse "^1.0.6" - -rimraf@^2.6.3: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== - dependencies: - glob "^7.1.3" - -rxjs@^6.6.0: - version "6.6.0" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.0.tgz#af2901eedf02e3a83ffa7f886240ff9018bbec84" - integrity sha512-3HMA8z/Oz61DUHe+SdOiQyzIf4tOx5oQHmMir7IZEu6TMqCLHT4LRcmNaUS0NwOz8VLvmmBduMsoaUvMaIiqzg== - dependencies: - tslib "^1.9.0" - -"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.5.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= - dependencies: - shebang-regex "^1.0.0" - -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= - -shell-quote@^1.6.1: - version "1.7.2" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" - integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg== - -signal-exit@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" - integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== - -spdx-correct@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" - integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" - integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== - -spdx-expression-parse@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" - integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.5" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz#3694b5804567a458d3c8045842a6358632f62654" - integrity sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q== - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - -string.prototype.padend@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.1.0.tgz#dc08f57a8010dc5c153550318f67e13adbb72ac3" - integrity sha512-3aIv8Ffdp8EZj8iLwREGpQaUZiPyrWrpzMBHvkiSW/bK/EGve9np07Vwy7IJ5waydpGXzQZu/F8Oze2/IWkBaA== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - -string.prototype.trimend@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913" - integrity sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.5" - -string.prototype.trimstart@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54" - integrity sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.5" - -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= - -strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: - version "1.13.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043" - integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q== - -tslib@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.0.tgz#18d13fc2dce04051e20f074cc8387fd8089ce4f3" - integrity sha512-lTqkx847PI7xEDYJntxZH89L2/aXInsyF2luSafe/+0fHOMjlBNXdH6th7f70qxLDhul7KZK0zC8V5ZIyHl0/g== - -tslint@^5.16.0: - version "5.20.1" - resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.20.1.tgz#e401e8aeda0152bc44dd07e614034f3f80c67b7d" - integrity sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg== - dependencies: - "@babel/code-frame" "^7.0.0" - builtin-modules "^1.1.1" - chalk "^2.3.0" - commander "^2.12.1" - diff "^4.0.1" - glob "^7.1.1" - js-yaml "^3.13.1" - minimatch "^3.0.4" - mkdirp "^0.5.1" - resolve "^1.3.2" - semver "^5.3.0" - tslib "^1.8.0" - tsutils "^2.29.0" - -tsutils@^2.29.0: - version "2.29.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99" - integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA== - dependencies: - tslib "^1.8.1" - -typescript@^3.5.1: - version "3.9.6" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.6.tgz#8f3e0198a34c3ae17091b35571d3afd31999365a" - integrity sha512-Pspx3oKAPJtjNwE92YS05HQoY7z2SFyOpHo9MqJor3BXAGNaPUs83CuVp9VISFkSjyRfiTpmKuAYGJB7S7hOxw== - -validate-npm-package-license@^3.0.1: - version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" - -which@^1.2.9: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= diff --git a/packages/apm/.eslintrc.js b/packages/apm/.eslintrc.js new file mode 100644 index 000000000000..06e1cc905a45 --- /dev/null +++ b/packages/apm/.eslintrc.js @@ -0,0 +1,26 @@ +module.exports = { + root: true, + env: { + es6: true, + }, + parserOptions: { + ecmaVersion: 2018, + }, + extends: ['../../.eslintrc.js'], + ignorePatterns: ['build/**/*', 'dist/**/*', 'esm/**/*', 'examples/**/*', 'scripts/**/*'], + overrides: [ + { + files: ['*.ts', '*.tsx', '*.d.ts'], + parserOptions: { + project: './tsconfig.json', + }, + }, + { + files: ['test/**/*'], + rules: { + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-non-null-assertion': 'off', + }, + }, + ], +}; diff --git a/packages/apm/package.json b/packages/apm/package.json index 924bf2c5f174..3b6261365993 100644 --- a/packages/apm/package.json +++ b/packages/apm/package.json @@ -50,13 +50,12 @@ "build:watch:esm": "tsc -p tsconfig.esm.json -w --preserveWatchOutput", "clean": "rimraf dist coverage build esm", "link:yarn": "yarn link", - "lint": "run-s lint:prettier lint:tslint", + "lint": "run-s lint:prettier lint:eslint", "lint:prettier": "prettier-check \"{src,test}/**/*.ts\"", - "lint:tslint": "tslint -t stylish -p .", - "lint:tslint:json": "tslint --format json -p . | tee lint-results.json", - "fix": "run-s fix:tslint fix:prettier", + "lint:eslint": "eslint . --cache --cache-location '../../eslintcache/' --format stylish", + "fix": "run-s fix:eslint fix:prettier", "fix:prettier": "prettier --write \"{src,test}/**/*.ts\"", - "fix:tslint": "tslint --fix -t stylish -p .", + "fix:eslint": "eslint . --format stylish --fix", "test": "jest", "test:watch": "jest --watch" }, diff --git a/packages/apm/src/integrations/express.ts b/packages/apm/src/integrations/express.ts index a2ca54d06672..54b7072cc71b 100644 --- a/packages/apm/src/integrations/express.ts +++ b/packages/apm/src/integrations/express.ts @@ -1,7 +1,8 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable prefer-rest-params */ import { Integration, Transaction } from '@sentry/types'; import { logger } from '@sentry/utils'; -// tslint:disable: completed-docs // Have to manually set types because we are using package-alias interface Application { use(...args: any): any; @@ -14,7 +15,6 @@ type NextFunction = (...args: any) => any; interface Response { once(name: string, callback: () => void): void; } -// tslint:enable: completed-docs /** * Internal helper for `__sentry_transaction` @@ -34,12 +34,12 @@ export class Express implements Integration { /** * @inheritDoc */ - public name: string = Express.id; + public static id: string = 'Express'; /** * @inheritDoc */ - public static id: string = 'Express'; + public name: string = Express.id; /** * Express App instance @@ -77,6 +77,7 @@ export class Express implements Integration { * // error handler * app.use(function (err, req, res, next) { ... }) */ +// eslint-disable-next-line @typescript-eslint/ban-types function wrap(fn: Function): RequestHandler | ErrorRequestHandler { const arrity = fn.length; @@ -180,7 +181,7 @@ function wrapUseArgs(args: IArguments): unknown[] { * Patches original app.use to utilize our tracing functionality */ function instrumentMiddlewares(app: Application): Application { - // tslint:disable-next-line: no-unbound-method + // eslint-disable-next-line @typescript-eslint/unbound-method const originalAppUse = app.use; app.use = function(): any { return originalAppUse.apply(this, wrapUseArgs(arguments)); diff --git a/packages/apm/src/integrations/tracing.ts b/packages/apm/src/integrations/tracing.ts index da478728ded0..6de086ddc5f8 100644 --- a/packages/apm/src/integrations/tracing.ts +++ b/packages/apm/src/integrations/tracing.ts @@ -1,4 +1,4 @@ -// tslint:disable: max-file-line-count +/* eslint-disable max-lines */ import { Hub } from '@sentry/hub'; import { Event, EventProcessor, Integration, Severity, Span, SpanContext, TransactionContext } from '@sentry/types'; import { @@ -15,7 +15,6 @@ import { import { Span as SpanClass } from '../span'; import { SpanStatus } from '../spanstatus'; import { Transaction } from '../transaction'; - import { Location } from './types'; /** @@ -41,13 +40,7 @@ export interface TracingOptions { * Default: true */ traceXHR: boolean; - /** - * This function will be called before creating a span for a request with the given url. - * Return false if you don't want a span for the given url. - * - * By default it uses the `tracingOrigins` options as a url match. - */ - shouldCreateSpanForRequest(url: string): boolean; + /** * The time to wait in ms until the transaction will be finished. The transaction will use the end timestamp of * the last finished span as the endtime for the transaction. @@ -111,6 +104,14 @@ export interface TracingOptions { spanDebugTimingInfo: boolean; }; + /** + * This function will be called before creating a span for a request with the given url. + * Return false if you don't want a span for the given url. + * + * By default it uses the `tracingOrigins` options as a url match. + */ + shouldCreateSpanForRequest(url: string): boolean; + /** * beforeNavigate is called before a pageload/navigation transaction is created and allows for users * to set a custom navigation transaction name based on the current `window.location`. Defaults to returning @@ -134,11 +135,6 @@ const defaultTracingOrigins = ['localhost', /^\//]; * Tracing Integration */ export class Tracing implements Integration { - /** - * @inheritDoc - */ - public name: string = Tracing.id; - /** * @inheritDoc */ @@ -147,6 +143,8 @@ export class Tracing implements Integration { /** JSDoc */ public static options: TracingOptions; + public static _activities: { [key: number]: Activity } = {}; + /** * Returns current hub. */ @@ -156,10 +154,6 @@ export class Tracing implements Integration { private static _currentIndex: number = 1; - public static _activities: { [key: number]: Activity } = {}; - - private readonly _emitOptionsWarning: boolean = false; - private static _performanceCursor: number = 0; private static _heartbeatTimer: number = 0; @@ -169,12 +163,15 @@ export class Tracing implements Integration { private static _heartbeatCounter: number = 0; /** Holds the latest LargestContentfulPaint value (it changes during page load). */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any private static _lcp?: { [key: string]: any }; - /** Force any pending LargestContentfulPaint records to be dispatched. */ - private static _forceLCP = () => { - /* No-op, replaced later if LCP API is available. */ - }; + /** + * @inheritDoc + */ + public name: string = Tracing.id; + + private readonly _emitOptionsWarning: boolean = false; /** * Constructor for Tracing @@ -223,69 +220,226 @@ export class Tracing implements Integration { } /** - * @inheritDoc + * Returns the current active idle transaction if there is one */ - public setupOnce(addGlobalEventProcessor: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void { - Tracing._getCurrentHub = getCurrentHub; + public static getTransaction(): Transaction | undefined { + return Tracing._activeTransaction; + } - if (this._emitOptionsWarning) { - logger.warn( - '[Tracing] You need to define `tracingOrigins` in the options. Set an array of urls or patterns to trace.', - ); - logger.warn(`[Tracing] We added a reasonable default for you: ${defaultTracingOrigins}`); + /** + * Starts tracking for a specifc activity + * + * @param name Name of the activity, can be any string (Only used internally to identify the activity) + * @param spanContext If provided a Span with the SpanContext will be created. + * @param options _autoPopAfter_ | Time in ms, if provided the activity will be popped automatically after this timeout. This can be helpful in cases where you cannot gurantee your application knows the state and calls `popActivity` for sure. + */ + public static pushActivity( + name: string, + spanContext?: SpanContext, + options?: { + autoPopAfter?: number; + }, + ): number { + const activeTransaction = Tracing._activeTransaction; + + if (!activeTransaction) { + Tracing._log(`[Tracing] Not pushing activity ${name} since there is no active transaction`); + return 0; } - // Starting pageload transaction - if (global.location && Tracing.options && Tracing.options.startTransactionOnPageLoad) { - Tracing.startIdleTransaction({ - name: Tracing.options.beforeNavigate(window.location), - op: 'pageload', - }); + const _getCurrentHub = Tracing._getCurrentHub; + if (spanContext && _getCurrentHub) { + const hub = _getCurrentHub(); + if (hub) { + const span = activeTransaction.startChild(spanContext); + Tracing._activities[Tracing._currentIndex] = { + name, + span, + }; + } + } else { + Tracing._activities[Tracing._currentIndex] = { + name, + }; } - this._setupXHRTracing(); + Tracing._log(`[Tracing] pushActivity: ${name}#${Tracing._currentIndex}`); + Tracing._log('[Tracing] activies count', Object.keys(Tracing._activities).length); + if (options && typeof options.autoPopAfter === 'number') { + Tracing._log(`[Tracing] auto pop of: ${name}#${Tracing._currentIndex} in ${options.autoPopAfter}ms`); + const index = Tracing._currentIndex; + setTimeout(() => { + Tracing.popActivity(index, { + autoPop: true, + status: SpanStatus.DeadlineExceeded, + }); + }, options.autoPopAfter); + } + // eslint-disable-next-line no-plusplus + return Tracing._currentIndex++; + } - this._setupFetchTracing(); + /** + * Removes activity and finishes the span in case there is one + * @param id the id of the activity being removed + * @param spanData span data that can be updated + * + */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + public static popActivity(id: number, spanData?: { [key: string]: any }): void { + // The !id is on purpose to also fail with 0 + // Since 0 is returned by push activity in case there is no active transaction + if (!id) { + return; + } - this._setupHistory(); + const activity = Tracing._activities[id]; - this._setupErrorHandling(); + if (activity) { + Tracing._log(`[Tracing] popActivity ${activity.name}#${id}`); + const span = activity.span; + if (span) { + if (spanData) { + Object.keys(spanData).forEach((key: string) => { + span.setData(key, spanData[key]); + if (key === 'status_code') { + span.setHttpStatus(spanData[key] as number); + } + if (key === 'status') { + span.setStatus(spanData[key] as SpanStatus); + } + }); + } + if (Tracing.options && Tracing.options.debug && Tracing.options.debug.spanDebugTimingInfo) { + Tracing._addSpanDebugInfo(span); + } + span.finish(); + } + // tslint:disable-next-line: no-dynamic-delete + delete Tracing._activities[id]; + } - this._setupBackgroundTabDetection(); + const count = Object.keys(Tracing._activities).length; - Tracing._pingHeartbeat(); + Tracing._log('[Tracing] activies count', count); - // This EventProcessor makes sure that the transaction is not longer than maxTransactionDuration - addGlobalEventProcessor((event: Event) => { - const self = getCurrentHub().getIntegration(Tracing); - if (!self) { - return event; - } + if (count === 0 && Tracing._activeTransaction) { + const timeout = Tracing.options && Tracing.options.idleTimeout; + Tracing._log(`[Tracing] Flushing Transaction in ${timeout}ms`); + // We need to add the timeout here to have the real endtimestamp of the transaction + // Remeber timestampWithMs is in seconds, timeout is in ms + const end = timestampWithMs() + timeout / 1000; + setTimeout(() => { + Tracing.finishIdleTransaction(end); + }, timeout); + } + } - const isOutdatedTransaction = - event.timestamp && - event.start_timestamp && - (event.timestamp - event.start_timestamp > Tracing.options.maxTransactionDuration || - event.timestamp - event.start_timestamp < 0); + /** + * Get span based on activity id + */ + public static getActivitySpan(id: number): Span | undefined { + if (!id) { + return undefined; + } + const activity = Tracing._activities[id]; + if (activity) { + return activity.span; + } + return undefined; + } - if (Tracing.options.maxTransactionDuration !== 0 && event.type === 'transaction' && isOutdatedTransaction) { - Tracing._log(`[Tracing] Transaction: ${SpanStatus.Cancelled} since it maxed out maxTransactionDuration`); - if (event.contexts && event.contexts.trace) { - event.contexts.trace = { - ...event.contexts.trace, - status: SpanStatus.DeadlineExceeded, - }; - event.tags = { - ...event.tags, - maxTransactionDurationExceeded: 'true', - }; - } + /** + * Sets the status of the current active transaction (if there is one) + */ + public static setTransactionStatus(status: SpanStatus): void { + const active = Tracing._activeTransaction; + if (active) { + Tracing._log('[Tracing] setTransactionStatus', status); + active.setStatus(status); + } + } + + /** + * Starts a Transaction waiting for activity idle to finish + */ + public static startIdleTransaction(transactionContext: TransactionContext): Transaction | undefined { + Tracing._log('[Tracing] startIdleTransaction'); + + const _getCurrentHub = Tracing._getCurrentHub; + if (!_getCurrentHub) { + return undefined; + } + + const hub = _getCurrentHub(); + if (!hub) { + return undefined; + } + + Tracing._activeTransaction = Tracing._getNewTransaction(hub, transactionContext); + + // We set the transaction here on the scope so error events pick up the trace context and attach it to the error + hub.configureScope(scope => scope.setSpan(Tracing._activeTransaction)); + + // The reason we do this here is because of cached responses + // If we start and transaction without an activity it would never finish since there is no activity + const id = Tracing.pushActivity('idleTransactionStarted'); + setTimeout(() => { + Tracing.popActivity(id); + }, (Tracing.options && Tracing.options.idleTimeout) || 100); + + return Tracing._activeTransaction; + } + + /** + * Finishes the current active transaction + */ + public static finishIdleTransaction(endTimestamp: number): void { + const active = Tracing._activeTransaction; + if (active) { + Tracing._log('[Tracing] finishing IdleTransaction', new Date(endTimestamp * 1000).toISOString()); + Tracing._addPerformanceEntries(active); + + if (active.spanRecorder) { + active.spanRecorder.spans = active.spanRecorder.spans.filter((span: Span) => { + // If we are dealing with the transaction itself, we just return it + if (span.spanId === active.spanId) { + return span; + } + + // We cancel all pending spans with status "cancelled" to indicate the idle transaction was finished early + if (!span.endTimestamp) { + span.endTimestamp = endTimestamp; + span.setStatus(SpanStatus.Cancelled); + Tracing._log('[Tracing] cancelling span since transaction ended early', JSON.stringify(span, undefined, 2)); + } + + // We remove all spans that happend after the end of the transaction + // This is here to prevent super long transactions and timing issues + const keepSpan = span.startTimestamp < endTimestamp; + if (!keepSpan) { + Tracing._log( + '[Tracing] discarding Span since it happened after Transaction was finished', + JSON.stringify(span, undefined, 2), + ); + } + return keepSpan; + }); } - return event; - }); + Tracing._log('[Tracing] flushing IdleTransaction'); + active.finish(); + Tracing._resetActiveTransaction(); + } else { + Tracing._log('[Tracing] No active IdleTransaction'); + } } + /** Force any pending LargestContentfulPaint records to be dispatched. */ + private static _forceLCP: () => void = (): void => { + /* No-op, replaced later if LCP API is available. */ + }; + /** * Returns a new Transaction either continued from sentry-trace meta or a new one */ @@ -330,6 +484,7 @@ export class Tracing implements Integration { private static _pingHeartbeat(): void { Tracing._heartbeatTimer = (setTimeout(() => { Tracing._beat(); + // eslint-disable-next-line @typescript-eslint/no-explicit-any }, 5000) as any) as number; } @@ -343,6 +498,7 @@ export class Tracing implements Integration { if (keys.length) { const heartbeatString = keys.reduce((prev: string, current: string) => prev + current); if (heartbeatString === Tracing._prevHeartbeatString) { + // eslint-disable-next-line no-plusplus Tracing._heartbeatCounter++; } else { Tracing._heartbeatCounter = 0; @@ -362,22 +518,6 @@ export class Tracing implements Integration { Tracing._pingHeartbeat(); } - /** - * Discards active transactions if tab moves to background - */ - private _setupBackgroundTabDetection(): void { - if (Tracing.options && Tracing.options.markBackgroundTransactions && global.document) { - document.addEventListener('visibilitychange', () => { - if (document.hidden && Tracing._activeTransaction) { - Tracing._log(`[Tracing] Transaction: ${SpanStatus.Cancelled} -> since tab moved to the background`); - Tracing._activeTransaction.setStatus(SpanStatus.Cancelled); - Tracing._activeTransaction.setTag('visibilitychange', 'document.hidden'); - Tracing.finishIdleTransaction(timestampWithMs()); - } - }); - } - } - /** * Unsets the current active transaction + activities */ @@ -394,162 +534,28 @@ export class Tracing implements Integration { } } } - // ------------------------------------------------------------------ - Tracing._activeTransaction = undefined; - Tracing._activities = {}; - } - - /** - * Registers to History API to detect navigation changes - */ - private _setupHistory(): void { - if (Tracing.options.startTransactionOnLocationChange) { - addInstrumentationHandler({ - callback: historyCallback, - type: 'history', - }); - } - } - - /** - * Attaches to fetch to add sentry-trace header + creating spans - */ - private _setupFetchTracing(): void { - if (Tracing.options.traceFetch && supportsNativeFetch()) { - addInstrumentationHandler({ - callback: fetchCallback, - type: 'fetch', - }); - } - } - - /** - * Attaches to XHR to add sentry-trace header + creating spans - */ - private _setupXHRTracing(): void { - if (Tracing.options.traceXHR) { - addInstrumentationHandler({ - callback: xhrCallback, - type: 'xhr', - }); - } - } - - /** - * Configures global error listeners - */ - private _setupErrorHandling(): void { - // tslint:disable-next-line: completed-docs - function errorCallback(): void { - if (Tracing._activeTransaction) { - /** - * If an error or unhandled promise occurs, we mark the active transaction as failed - */ - Tracing._log(`[Tracing] Transaction: ${SpanStatus.InternalError} -> Global error occured`); - Tracing._activeTransaction.setStatus(SpanStatus.InternalError); - } - } - addInstrumentationHandler({ - callback: errorCallback, - type: 'error', - }); - addInstrumentationHandler({ - callback: errorCallback, - type: 'unhandledrejection', - }); - } - - /** - * Uses logger.log to log things in the SDK or as breadcrumbs if defined in options - */ - private static _log(...args: any[]): void { - if (Tracing.options && Tracing.options.debug && Tracing.options.debug.writeAsBreadcrumbs) { - const _getCurrentHub = Tracing._getCurrentHub; - if (_getCurrentHub) { - _getCurrentHub().addBreadcrumb({ - category: 'tracing', - level: Severity.Debug, - message: safeJoin(args, ' '), - type: 'debug', - }); - } - } - logger.log(...args); - } - - /** - * Starts a Transaction waiting for activity idle to finish - */ - public static startIdleTransaction(transactionContext: TransactionContext): Transaction | undefined { - Tracing._log('[Tracing] startIdleTransaction'); - - const _getCurrentHub = Tracing._getCurrentHub; - if (!_getCurrentHub) { - return undefined; - } - - const hub = _getCurrentHub(); - if (!hub) { - return undefined; - } - - Tracing._activeTransaction = Tracing._getNewTransaction(hub, transactionContext); - - // We set the transaction here on the scope so error events pick up the trace context and attach it to the error - hub.configureScope(scope => scope.setSpan(Tracing._activeTransaction)); - - // The reason we do this here is because of cached responses - // If we start and transaction without an activity it would never finish since there is no activity - const id = Tracing.pushActivity('idleTransactionStarted'); - setTimeout(() => { - Tracing.popActivity(id); - }, (Tracing.options && Tracing.options.idleTimeout) || 100); - - return Tracing._activeTransaction; - } - - /** - * Finishes the current active transaction - */ - public static finishIdleTransaction(endTimestamp: number): void { - const active = Tracing._activeTransaction; - if (active) { - Tracing._log('[Tracing] finishing IdleTransaction', new Date(endTimestamp * 1000).toISOString()); - Tracing._addPerformanceEntries(active); - - if (active.spanRecorder) { - active.spanRecorder.spans = active.spanRecorder.spans.filter((span: Span) => { - // If we are dealing with the transaction itself, we just return it - if (span.spanId === active.spanId) { - return span; - } - - // We cancel all pending spans with status "cancelled" to indicate the idle transaction was finished early - if (!span.endTimestamp) { - span.endTimestamp = endTimestamp; - span.setStatus(SpanStatus.Cancelled); - Tracing._log('[Tracing] cancelling span since transaction ended early', JSON.stringify(span, undefined, 2)); - } - - // We remove all spans that happend after the end of the transaction - // This is here to prevent super long transactions and timing issues - const keepSpan = span.startTimestamp < endTimestamp; - if (!keepSpan) { - Tracing._log( - '[Tracing] discarding Span since it happened after Transaction was finished', - JSON.stringify(span, undefined, 2), - ); - } - return keepSpan; + // ------------------------------------------------------------------ + Tracing._activeTransaction = undefined; + Tracing._activities = {}; + } + + /** + * Uses logger.log to log things in the SDK or as breadcrumbs if defined in options + */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + private static _log(...args: any[]): void { + if (Tracing.options && Tracing.options.debug && Tracing.options.debug.writeAsBreadcrumbs) { + const _getCurrentHub = Tracing._getCurrentHub; + if (_getCurrentHub) { + _getCurrentHub().addBreadcrumb({ + category: 'tracing', + level: Severity.Debug, + message: safeJoin(args, ' '), + type: 'debug', }); } - - Tracing._log('[Tracing] flushing IdleTransaction'); - active.finish(); - Tracing._resetActiveTransaction(); - } else { - Tracing._log('[Tracing] No active IdleTransaction'); } + logger.log(...args); } /** @@ -579,7 +585,7 @@ export class Tracing implements Integration { const timeOrigin = Tracing._msToSec(performance.timeOrigin); - // tslint:disable-next-line: completed-docs + // eslint-disable-next-line jsdoc/require-jsdoc function addPerformanceNavigationTiming(parent: Span, entry: { [key: string]: number }, event: string): void { _startChild(parent, { description: event, @@ -589,7 +595,7 @@ export class Tracing implements Integration { }); } - // tslint:disable-next-line: completed-docs + // eslint-disable-next-line jsdoc/require-jsdoc function addRequest(parent: Span, entry: { [key: string]: number }): void { _startChild(parent, { description: 'request', @@ -609,7 +615,7 @@ export class Tracing implements Integration { let entryScriptSrc: string | undefined; if (global.document) { - // tslint:disable-next-line: prefer-for-of + // eslint-disable-next-line @typescript-eslint/prefer-for-of for (let i = 0; i < document.scripts.length; i++) { // We go through all scripts on the page and look for 'data-entry' // We remember the name and measure the time between this script finished loading and @@ -624,10 +630,10 @@ export class Tracing implements Integration { let entryScriptStartEndTime: number | undefined; let tracingInitMarkStartTime: number | undefined; - // tslint:disable: no-unsafe-any performance .getEntries() .slice(Tracing._performanceCursor) + // eslint-disable-next-line @typescript-eslint/no-explicit-any .forEach((entry: any) => { const startTime = Tracing._msToSec(entry.startTime as number); const duration = Tracing._msToSec(entry.duration as number); @@ -647,7 +653,7 @@ export class Tracing implements Integration { break; case 'mark': case 'paint': - case 'measure': + case 'measure': { const mark = _startChild(transactionSpan, { description: entry.name, endTimestamp: timeOrigin + startTime + duration, @@ -658,7 +664,8 @@ export class Tracing implements Integration { tracingInitMarkStartTime = mark.startTimestamp; } break; - case 'resource': + } + case 'resource': { const resourceName = entry.name.replace(window.location.origin, ''); // we already instrument based on fetch and xhr, so we don't need to // duplicate spans here. @@ -675,6 +682,7 @@ export class Tracing implements Integration { } } break; + } default: // Ignore other entry types. } @@ -716,7 +724,7 @@ export class Tracing implements Integration { { once: true }, ); - const updateLCP = (entry: PerformanceEntry) => { + const updateLCP = (entry: PerformanceEntry): void => { // Only include an LCP entry if the page wasn't hidden prior to // the entry being dispatched. This typically happens when a page is // loaded in a background tab. @@ -726,9 +734,9 @@ export class Tracing implements Integration { // The `renderTime` value may not be available if the element is an image // that's loaded cross-origin without the `Timing-Allow-Origin` header. Tracing._lcp = { - // @ts-ignore + // @ts-ignore property id does not exist on entry ...(entry.id && { elementId: entry.id }), - // @ts-ignore + // @ts-ignore property size does not exist on entry ...(entry.size && { elementSize: entry.size }), value: entry.startTime, }; @@ -744,11 +752,11 @@ export class Tracing implements Integration { // i.e. entries that occurred before calling `observe()` below. po.observe({ buffered: true, - // @ts-ignore + // @ts-ignore not assignable, so have to ignore type: 'largest-contentful-paint', }); - Tracing._forceLCP = () => { + Tracing._forceLCP = (): void => { po.takeRecords().forEach(updateLCP); }; } catch (e) { @@ -756,24 +764,6 @@ export class Tracing implements Integration { } } - /** - * Sets the status of the current active transaction (if there is one) - */ - public static setTransactionStatus(status: SpanStatus): void { - const active = Tracing._activeTransaction; - if (active) { - Tracing._log('[Tracing] setTransactionStatus', status); - active.setStatus(status); - } - } - - /** - * Returns the current active idle transaction if there is one - */ - public static getTransaction(): Transaction | undefined { - return Tracing._activeTransaction; - } - /** * Converts from milliseconds to seconds * @param time time in ms @@ -786,15 +776,15 @@ export class Tracing implements Integration { * Adds debug data to the span */ private static _addSpanDebugInfo(span: Span): void { - // tslint:disable: no-unsafe-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any const debugData: any = {}; if (global.performance) { debugData.performance = true; debugData['performance.timeOrigin'] = global.performance.timeOrigin; debugData['performance.now'] = global.performance.now(); - // tslint:disable-next-line: deprecation + // eslint-disable-next-line deprecation/deprecation if (global.performance.timing) { - // tslint:disable-next-line: deprecation + // eslint-disable-next-line deprecation/deprecation debugData['performance.timing.navigationStart'] = performance.timing.navigationStart; } } else { @@ -806,130 +796,150 @@ export class Tracing implements Integration { } /** - * Starts tracking for a specifc activity - * - * @param name Name of the activity, can be any string (Only used internally to identify the activity) - * @param spanContext If provided a Span with the SpanContext will be created. - * @param options _autoPopAfter_ | Time in ms, if provided the activity will be popped automatically after this timeout. This can be helpful in cases where you cannot gurantee your application knows the state and calls `popActivity` for sure. + * @inheritDoc */ - public static pushActivity( - name: string, - spanContext?: SpanContext, - options?: { - autoPopAfter?: number; - }, - ): number { - const activeTransaction = Tracing._activeTransaction; + public setupOnce(addGlobalEventProcessor: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void { + Tracing._getCurrentHub = getCurrentHub; - if (!activeTransaction) { - Tracing._log(`[Tracing] Not pushing activity ${name} since there is no active transaction`); - return 0; + if (this._emitOptionsWarning) { + logger.warn( + '[Tracing] You need to define `tracingOrigins` in the options. Set an array of urls or patterns to trace.', + ); + logger.warn(`[Tracing] We added a reasonable default for you: ${defaultTracingOrigins}`); } - const _getCurrentHub = Tracing._getCurrentHub; - if (spanContext && _getCurrentHub) { - const hub = _getCurrentHub(); - if (hub) { - const span = activeTransaction.startChild(spanContext); - Tracing._activities[Tracing._currentIndex] = { - name, - span, - }; - } - } else { - Tracing._activities[Tracing._currentIndex] = { - name, - }; + // Starting pageload transaction + if (global.location && Tracing.options && Tracing.options.startTransactionOnPageLoad) { + Tracing.startIdleTransaction({ + name: Tracing.options.beforeNavigate(window.location), + op: 'pageload', + }); } - Tracing._log(`[Tracing] pushActivity: ${name}#${Tracing._currentIndex}`); - Tracing._log('[Tracing] activies count', Object.keys(Tracing._activities).length); - if (options && typeof options.autoPopAfter === 'number') { - Tracing._log(`[Tracing] auto pop of: ${name}#${Tracing._currentIndex} in ${options.autoPopAfter}ms`); - const index = Tracing._currentIndex; - setTimeout(() => { - Tracing.popActivity(index, { - autoPop: true, - status: SpanStatus.DeadlineExceeded, - }); - }, options.autoPopAfter); - } - return Tracing._currentIndex++; - } + this._setupXHRTracing(); - /** - * Removes activity and finishes the span in case there is one - * @param id the id of the activity being removed - * @param spanData span data that can be updated - * - */ - public static popActivity(id: number, spanData?: { [key: string]: any }): void { - // The !id is on purpose to also fail with 0 - // Since 0 is returned by push activity in case there is no active transaction - if (!id) { - return; - } + this._setupFetchTracing(); - const activity = Tracing._activities[id]; + this._setupHistory(); - if (activity) { - Tracing._log(`[Tracing] popActivity ${activity.name}#${id}`); - const span = activity.span; - if (span) { - if (spanData) { - Object.keys(spanData).forEach((key: string) => { - span.setData(key, spanData[key]); - if (key === 'status_code') { - span.setHttpStatus(spanData[key] as number); - } - if (key === 'status') { - span.setStatus(spanData[key] as SpanStatus); - } - }); - } - if (Tracing.options && Tracing.options.debug && Tracing.options.debug.spanDebugTimingInfo) { - Tracing._addSpanDebugInfo(span); + this._setupErrorHandling(); + + this._setupBackgroundTabDetection(); + + Tracing._pingHeartbeat(); + + // This EventProcessor makes sure that the transaction is not longer than maxTransactionDuration + addGlobalEventProcessor((event: Event) => { + const self = getCurrentHub().getIntegration(Tracing); + if (!self) { + return event; + } + + const isOutdatedTransaction = + event.timestamp && + event.start_timestamp && + (event.timestamp - event.start_timestamp > Tracing.options.maxTransactionDuration || + event.timestamp - event.start_timestamp < 0); + + if (Tracing.options.maxTransactionDuration !== 0 && event.type === 'transaction' && isOutdatedTransaction) { + Tracing._log(`[Tracing] Transaction: ${SpanStatus.Cancelled} since it maxed out maxTransactionDuration`); + if (event.contexts && event.contexts.trace) { + event.contexts.trace = { + ...event.contexts.trace, + status: SpanStatus.DeadlineExceeded, + }; + event.tags = { + ...event.tags, + maxTransactionDurationExceeded: 'true', + }; } - span.finish(); } - // tslint:disable-next-line: no-dynamic-delete - delete Tracing._activities[id]; - } - const count = Object.keys(Tracing._activities).length; + return event; + }); + } - Tracing._log('[Tracing] activies count', count); + /** + * Discards active transactions if tab moves to background + */ + private _setupBackgroundTabDetection(): void { + if (Tracing.options && Tracing.options.markBackgroundTransactions && global.document) { + document.addEventListener('visibilitychange', () => { + if (document.hidden && Tracing._activeTransaction) { + Tracing._log(`[Tracing] Transaction: ${SpanStatus.Cancelled} -> since tab moved to the background`); + Tracing._activeTransaction.setStatus(SpanStatus.Cancelled); + Tracing._activeTransaction.setTag('visibilitychange', 'document.hidden'); + Tracing.finishIdleTransaction(timestampWithMs()); + } + }); + } + } - if (count === 0 && Tracing._activeTransaction) { - const timeout = Tracing.options && Tracing.options.idleTimeout; - Tracing._log(`[Tracing] Flushing Transaction in ${timeout}ms`); - // We need to add the timeout here to have the real endtimestamp of the transaction - // Remeber timestampWithMs is in seconds, timeout is in ms - const end = timestampWithMs() + timeout / 1000; - setTimeout(() => { - Tracing.finishIdleTransaction(end); - }, timeout); + /** + * Registers to History API to detect navigation changes + */ + private _setupHistory(): void { + if (Tracing.options.startTransactionOnLocationChange) { + addInstrumentationHandler({ + callback: historyCallback, + type: 'history', + }); } } /** - * Get span based on activity id + * Attaches to fetch to add sentry-trace header + creating spans */ - public static getActivitySpan(id: number): Span | undefined { - if (!id) { - return undefined; + private _setupFetchTracing(): void { + if (Tracing.options.traceFetch && supportsNativeFetch()) { + addInstrumentationHandler({ + callback: fetchCallback, + type: 'fetch', + }); } - const activity = Tracing._activities[id]; - if (activity) { - return activity.span; + } + + /** + * Attaches to XHR to add sentry-trace header + creating spans + */ + private _setupXHRTracing(): void { + if (Tracing.options.traceXHR) { + addInstrumentationHandler({ + callback: xhrCallback, + type: 'xhr', + }); } - return undefined; + } + + /** + * Configures global error listeners + */ + private _setupErrorHandling(): void { + // eslint-disable-next-line jsdoc/require-jsdoc + function errorCallback(): void { + if (Tracing._activeTransaction) { + /** + * If an error or unhandled promise occurs, we mark the active transaction as failed + */ + Tracing._log(`[Tracing] Transaction: ${SpanStatus.InternalError} -> Global error occured`); + Tracing._activeTransaction.setStatus(SpanStatus.InternalError); + } + } + addInstrumentationHandler({ + callback: errorCallback, + type: 'error', + }); + addInstrumentationHandler({ + callback: errorCallback, + type: 'unhandledrejection', + }); } } /** * Creates breadcrumbs from XHR API calls */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any function xhrCallback(handlerData: { [key: string]: any }): void { if (!Tracing.options.traceXHR) { return; @@ -984,6 +994,7 @@ function xhrCallback(handlerData: { [key: string]: any }): void { /** * Creates breadcrumbs from fetch API calls */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any function fetchCallback(handlerData: { [key: string]: any }): void { // tslint:disable: no-unsafe-any if (!Tracing.options.traceFetch) { @@ -1011,6 +1022,7 @@ function fetchCallback(handlerData: { [key: string]: any }): void { const span = activity.span; if (span) { const request = (handlerData.args[0] = handlerData.args[0] as string | Request); + // eslint-disable-next-line @typescript-eslint/no-explicit-any const options = (handlerData.args[1] = (handlerData.args[1] as { [key: string]: any }) || {}); let headers = options.headers; if (isInstanceOf(request, Request)) { @@ -1037,6 +1049,7 @@ function fetchCallback(handlerData: { [key: string]: any }): void { /** * Creates transaction from navigation changes */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any function historyCallback(_: { [key: string]: any }): void { if (Tracing.options.startTransactionOnLocationChange && global && global.location) { Tracing.finishIdleTransaction(timestampWithMs()); diff --git a/packages/apm/src/integrations/types.ts b/packages/apm/src/integrations/types.ts index 331cbee7ba57..357a7b857332 100644 --- a/packages/apm/src/integrations/types.ts +++ b/packages/apm/src/integrations/types.ts @@ -5,6 +5,7 @@ * Based on https://github.com/microsoft/TypeScript/blob/4cf0afe2662980ebcd8d444dbd13d8f47d06fcd5/lib/lib.dom.d.ts#L4051 */ interface DOMStringList { + [index: number]: string; /** * Returns the number of strings in strings. */ @@ -17,9 +18,9 @@ interface DOMStringList { * Returns the string with index index from strings. */ item(index: number): string | null; - [index: number]: string; } +// eslint-disable-next-line no-var declare var DOMStringList: { prototype: DOMStringList; new (): DOMStringList; @@ -61,8 +62,6 @@ export interface Location { * Can be set, to navigate to the given URL. */ href: string; - // tslint:disable-next-line: completed-docs - toString(): string; /** * Returns the Location object's URL's origin. */ @@ -106,4 +105,6 @@ export interface Location { * Removes the current page from the session history and navigates to the given URL. */ replace(url: string): void; + + toString(): string; } diff --git a/packages/apm/src/span.ts b/packages/apm/src/span.ts index eb6c49d42bab..c72cc1e5fff7 100644 --- a/packages/apm/src/span.ts +++ b/packages/apm/src/span.ts @@ -1,3 +1,4 @@ +/* eslint-disable max-lines */ import { Span as SpanInterface, SpanContext } from '@sentry/types'; import { dropUndefinedKeys, timestampWithMs, uuid4 } from '@sentry/utils'; @@ -69,6 +70,7 @@ export class Span implements SpanInterface, SpanContext { /** * @inheritDoc */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any public data: { [key: string]: any } = {}; /** @@ -122,6 +124,32 @@ export class Span implements SpanInterface, SpanContext { } } + /** + * Continues a trace from a string (usually the header). + * @param traceparent Traceparent string + */ + public static fromTraceparent( + traceparent: string, + spanContext?: Pick>, + ): Span | undefined { + const matches = traceparent.match(TRACEPARENT_REGEXP); + if (matches) { + let sampled: boolean | undefined; + if (matches[3] === '1') { + sampled = true; + } else if (matches[3] === '0') { + sampled = false; + } + return new Span({ + ...spanContext, + parentSpanId: matches[2], + sampled, + traceId: matches[1], + }); + } + return undefined; + } + /** * @inheritDoc * @deprecated @@ -153,32 +181,6 @@ export class Span implements SpanInterface, SpanContext { return span; } - /** - * Continues a trace from a string (usually the header). - * @param traceparent Traceparent string - */ - public static fromTraceparent( - traceparent: string, - spanContext?: Pick>, - ): Span | undefined { - const matches = traceparent.match(TRACEPARENT_REGEXP); - if (matches) { - let sampled: boolean | undefined; - if (matches[3] === '1') { - sampled = true; - } else if (matches[3] === '0') { - sampled = false; - } - return new Span({ - ...spanContext, - parentSpanId: matches[2], - sampled, - traceId: matches[1], - }); - } - return undefined; - } - /** * @inheritDoc */ @@ -190,6 +192,7 @@ export class Span implements SpanInterface, SpanContext { /** * @inheritDoc */ + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any public setData(key: string, value: any): this { this.data = { ...this.data, [key]: value }; return this; @@ -244,6 +247,7 @@ export class Span implements SpanInterface, SpanContext { * @inheritDoc */ public getTraceContext(): { + // eslint-disable-next-line @typescript-eslint/no-explicit-any data?: { [key: string]: any }; description?: string; op?: string; @@ -269,6 +273,7 @@ export class Span implements SpanInterface, SpanContext { * @inheritDoc */ public toJSON(): { + // eslint-disable-next-line @typescript-eslint/no-explicit-any data?: { [key: string]: any }; description?: string; op?: string; diff --git a/packages/apm/src/spanstatus.ts b/packages/apm/src/spanstatus.ts index 6aa87a4dc833..e26d19e36139 100644 --- a/packages/apm/src/spanstatus.ts +++ b/packages/apm/src/spanstatus.ts @@ -1,4 +1,5 @@ /** The status of an Span. */ +// eslint-disable-next-line import/export export enum SpanStatus { /** The operation completed successfully. */ Ok = 'ok', @@ -36,7 +37,7 @@ export enum SpanStatus { DataLoss = 'data_loss', } -// tslint:disable:no-unnecessary-qualifier no-namespace +// eslint-disable-next-line @typescript-eslint/no-namespace, import/export export namespace SpanStatus { /** * Converts a HTTP status code into a {@link SpanStatus}. @@ -44,7 +45,6 @@ export namespace SpanStatus { * @param httpStatus The HTTP response status code. * @returns The span status or {@link SpanStatus.UnknownError}. */ - // tslint:disable-next-line:completed-docs export function fromHttpCode(httpStatus: number): SpanStatus { if (httpStatus < 400) { return SpanStatus.Ok; diff --git a/packages/apm/src/transaction.ts b/packages/apm/src/transaction.ts index 9366fca34613..1dede4623a06 100644 --- a/packages/apm/src/transaction.ts +++ b/packages/apm/src/transaction.ts @@ -12,9 +12,10 @@ import { Span as SpanClass } from './span'; * @hidden */ export class SpanRecorder { - private readonly _maxlen: number; public spans: SpanClass[] = []; + private readonly _maxlen: number; + public constructor(maxlen: number = 1000) { this._maxlen = maxlen; } @@ -36,13 +37,13 @@ export class SpanRecorder { /** JSDoc */ export class Transaction extends SpanClass { + public name?: string; + /** * The reference to the current hub. */ private readonly _hub: Hub = (getCurrentHub() as unknown) as Hub; - public name?: string; - private readonly _trimEnd?: boolean; /** diff --git a/packages/apm/test/hub.test.ts b/packages/apm/test/hub.test.ts index e24f1fc6638d..9de5072c4908 100644 --- a/packages/apm/test/hub.test.ts +++ b/packages/apm/test/hub.test.ts @@ -69,7 +69,7 @@ describe('Hub', () => { const hub = new Hub(new BrowserClient({ tracesSampleRate: 1 })); const transaction = hub.startTransaction({ name: 'transaction' }); expect(transaction.spanId).toBeTruthy(); - // tslint:disable-next-line: no-unbound-method + // eslint-disable-next-line @typescript-eslint/unbound-method expect(transaction.setName).toBeTruthy(); }); @@ -80,7 +80,7 @@ describe('Hub', () => { hub.configureScope(scope => { scope.setSpan(parentSpan); }); - // @ts-ignore + // @ts-ignore name does not exist on SpanContext const span = hub.startSpan({ name: 'test' }) as any; expect(span.trace_id).toEqual(parentSpan.trace_id); }); diff --git a/packages/apm/test/span.test.ts b/packages/apm/test/span.test.ts index 0fb373174259..db6e83526f47 100644 --- a/packages/apm/test/span.test.ts +++ b/packages/apm/test/span.test.ts @@ -324,7 +324,7 @@ describe('Span', () => { describe('hub.startSpan', () => { test('finish a transaction', () => { const spy = jest.spyOn(hub as any, 'captureEvent') as any; - // @ts-ignore + // @ts-ignore name does not exist on SpanContext const transaction = hub.startSpan({ name: 'test' }); transaction.finish(); expect(spy).toHaveBeenCalled(); @@ -336,7 +336,7 @@ describe('Span', () => { test('finish a transaction (deprecated way)', () => { const spy = jest.spyOn(hub as any, 'captureEvent') as any; - // @ts-ignore + // @ts-ignore name does not exist on SpanContext const transaction = hub.startSpan({ transaction: 'test' }); transaction.finish(); expect(spy).toHaveBeenCalled(); diff --git a/packages/apm/test/tslint.json b/packages/apm/test/tslint.json deleted file mode 100644 index 0827b5c40259..000000000000 --- a/packages/apm/test/tslint.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "extends": ["../tslint.json"], - "rules": { - "no-unsafe-any": false - } -} diff --git a/packages/apm/tslint.json b/packages/apm/tslint.json deleted file mode 100644 index 3016a27a85cc..000000000000 --- a/packages/apm/tslint.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "@sentry/typescript/tslint" -} diff --git a/packages/browser/.eslintrc.js b/packages/browser/.eslintrc.js index dd9c2479053a..e03f056247e1 100644 --- a/packages/browser/.eslintrc.js +++ b/packages/browser/.eslintrc.js @@ -23,6 +23,7 @@ module.exports = { 'no-console': 'off', 'max-lines': 'off', 'prefer-template': 'off', + 'no-unused-expressions': 'off', }, }, { diff --git a/packages/browser/package.json b/packages/browser/package.json index 463b8238f745..431b1caf5a29 100644 --- a/packages/browser/package.json +++ b/packages/browser/package.json @@ -66,11 +66,10 @@ "link:yarn": "yarn link", "lint": "run-s lint:prettier lint:eslint", "lint:prettier": "prettier-check \"{src,test}/**/*.ts\"", - "lint:eslint": "eslint . --format stylish", - "lint:eslint:json": "eslint . --format json | tee lint-results.json", + "lint:eslint": "eslint . --cache --cache-location '../../eslintcache/' --format stylish", "fix": "run-s fix:eslint fix:prettier", "fix:prettier": "prettier --write \"{src,test}/**/*.ts\"", - "fix:eslint": "lint:eslint --fix", + "fix:eslint": "eslint . --format stylish --fix", "test": "run-s test:unit", "test:unit": "karma start test/unit/karma.conf.js", "test:unit:watch": "karma start test/unit/karma.conf.js --auto-watch --no-single-run", diff --git a/packages/browser/src/tracekit.ts b/packages/browser/src/tracekit.ts index 235e49c90be7..97943c9449a1 100644 --- a/packages/browser/src/tracekit.ts +++ b/packages/browser/src/tracekit.ts @@ -95,7 +95,7 @@ export function computeStackTrace(ex: any): StackTrace { } /** JSDoc */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any +// eslint-disable-next-line @typescript-eslint/no-explicit-any, complexity function computeStackTraceFromStackProp(ex: any): StackTrace | null { if (!ex || !ex.stack) { return null; diff --git a/packages/browser/src/transports/base.ts b/packages/browser/src/transports/base.ts index 7503277a7ff9..00c3ef817cbc 100644 --- a/packages/browser/src/transports/base.ts +++ b/packages/browser/src/transports/base.ts @@ -17,6 +17,7 @@ export abstract class BaseTransport implements Transport { public constructor(public options: TransportOptions) { this._api = new API(this.options.dsn); + // eslint-disable-next-line deprecation/deprecation this.url = this._api.getStoreEndpointWithUrlEncodedAuth(); } diff --git a/packages/browser/test/integration/polyfills/fetch.js b/packages/browser/test/integration/polyfills/fetch.js index 3611142c0683..277a3dee19ce 100644 --- a/packages/browser/test/integration/polyfills/fetch.js +++ b/packages/browser/test/integration/polyfills/fetch.js @@ -232,6 +232,7 @@ function Body() { this.bodyUsed = false; + // eslint-disable-next-line complexity this._initBody = function(body) { this._bodyInit = body; if (!body) { diff --git a/packages/browser/test/integration/run.js b/packages/browser/test/integration/run.js index ca556ace3e12..34ce6a090537 100755 --- a/packages/browser/test/integration/run.js +++ b/packages/browser/test/integration/run.js @@ -1,9 +1,10 @@ #!/usr/bin/env node const fs = require("fs"); +const path = require("path"); + const rimraf = require("rimraf"); const karma = require("karma"); -const path = require("path"); const chokidar = require("chokidar"); const isDebugMode = process.argv.some(x => x === "--debug"); diff --git a/packages/browser/test/package/npm-build.js b/packages/browser/test/package/npm-build.js index a596ba3f9fab..84f4ee283906 100644 --- a/packages/browser/test/package/npm-build.js +++ b/packages/browser/test/package/npm-build.js @@ -1,5 +1,6 @@ const fs = require('fs'); const path = require('path'); + const webpack = require('webpack'); const { JSDOM } = require('jsdom'); diff --git a/packages/browser/test/unit/index.test.ts b/packages/browser/test/unit/index.test.ts index 3ba9d51b2a37..24c3ebb6cc7d 100644 --- a/packages/browser/test/unit/index.test.ts +++ b/packages/browser/test/unit/index.test.ts @@ -16,7 +16,6 @@ import { Scope, wrap, } from '../../src'; - import { SimpleTransport } from './mocks/simpletransport'; const dsn = 'https://53039209a22b4ec1bcc296a3c9fdecd6@sentry.io/4291'; diff --git a/packages/browser/test/unit/tracekit/original.test.ts b/packages/browser/test/unit/tracekit/original.test.ts index 6ceede2cefe7..af0de34c91d7 100644 --- a/packages/browser/test/unit/tracekit/original.test.ts +++ b/packages/browser/test/unit/tracekit/original.test.ts @@ -1,7 +1,6 @@ import { expect } from 'chai'; import { computeStackTrace } from '../../../src/tracekit'; - import { ANDROID_REACT_NATIVE, ANDROID_REACT_NATIVE_HERMES, @@ -11,13 +10,13 @@ import { CHROME_48_BLOB, CHROME_48_EVAL, CHROME_XX_WEBPACK, - FIREFOX_14, FIREFOX_3, + FIREFOX_7, + FIREFOX_14, FIREFOX_31, FIREFOX_43_EVAL, FIREFOX_44_NS_EXCEPTION, FIREFOX_50_RESOURCE_URL, - FIREFOX_7, IE_10, IE_11, IE_11_EVAL, diff --git a/packages/browser/test/unit/transports/base.test.ts b/packages/browser/test/unit/transports/base.test.ts index 708fba4f9251..55ef2230c002 100644 --- a/packages/browser/test/unit/transports/base.test.ts +++ b/packages/browser/test/unit/transports/base.test.ts @@ -19,6 +19,7 @@ describe('BaseTransport', () => { it('has correct endpoint url', () => { const transport = new SimpleTransport({ dsn: testDsn }); + // eslint-disable-next-line deprecation/deprecation expect(transport.url).equal('https://sentry.io/api/42/store/?sentry_key=123&sentry_version=7'); }); }); diff --git a/packages/browser/test/unit/transports/fetch.test.ts b/packages/browser/test/unit/transports/fetch.test.ts index 02a5a85c3785..439941d80533 100644 --- a/packages/browser/test/unit/transports/fetch.test.ts +++ b/packages/browser/test/unit/transports/fetch.test.ts @@ -27,6 +27,7 @@ describe('FetchTransport', () => { }); it('inherits composeEndpointUrl() implementation', () => { + // eslint-disable-next-line deprecation/deprecation expect(transport.url).equal(transportUrl); }); diff --git a/packages/browser/test/unit/transports/xhr.test.ts b/packages/browser/test/unit/transports/xhr.test.ts index 671f42a20c93..51bb1f6351ee 100644 --- a/packages/browser/test/unit/transports/xhr.test.ts +++ b/packages/browser/test/unit/transports/xhr.test.ts @@ -28,6 +28,7 @@ describe('XHRTransport', () => { }); it('inherits composeEndpointUrl() implementation', () => { + // eslint-disable-next-line deprecation/deprecation expect(transport.url).equal(transportUrl); }); diff --git a/packages/core/package.json b/packages/core/package.json index 28b4c5b3e431..46eaaa62bf89 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -41,11 +41,10 @@ "link:yarn": "yarn link", "lint": "run-s lint:prettier lint:eslint", "lint:prettier": "prettier-check \"{src,test}/**/*.ts\"", - "lint:eslint": "eslint . --format stylish", - "lint:eslint:json": "eslint . --format json | tee lint-results.json", + "lint:eslint": "eslint . --cache --cache-location '../../eslintcache/' --format stylish", "fix": "run-s fix:eslint fix:prettier", "fix:prettier": "prettier --write \"{src,test}/**/*.ts\"", - "fix:eslint": "lint:eslint --fix", + "fix:eslint": "eslint . --format stylish --fix", "test": "jest", "test:watch": "jest --watch" }, diff --git a/packages/core/src/baseclient.ts b/packages/core/src/baseclient.ts index e37878f12c6c..799533f77f39 100644 --- a/packages/core/src/baseclient.ts +++ b/packages/core/src/baseclient.ts @@ -91,6 +91,7 @@ export abstract class BaseClient implement let eventId: string | undefined = hint && hint.event_id; this._processing = true; + // eslint-disable-next-line @typescript-eslint/no-floating-promises this._getBackend() .eventFromException(exception, hint) .then(event => { @@ -111,6 +112,7 @@ export abstract class BaseClient implement ? this._getBackend().eventFromMessage(`${message}`, level, hint) : this._getBackend().eventFromException(message, hint); + // eslint-disable-next-line @typescript-eslint/no-floating-promises promisedEvent.then(event => { eventId = this.captureEvent(event, hint, scope); }); diff --git a/packages/core/src/integrations/inboundfilters.ts b/packages/core/src/integrations/inboundfilters.ts index 76922e49e8d5..106cc10caa0f 100644 --- a/packages/core/src/integrations/inboundfilters.ts +++ b/packages/core/src/integrations/inboundfilters.ts @@ -142,14 +142,18 @@ export class InboundFilters implements Integration { private _mergeOptions(clientOptions: Partial = {}): Partial { return { allowUrls: [ + // eslint-disable-next-line deprecation/deprecation ...(this._options.whitelistUrls || []), ...(this._options.allowUrls || []), + // eslint-disable-next-line deprecation/deprecation ...(clientOptions.whitelistUrls || []), ...(clientOptions.allowUrls || []), ], denyUrls: [ + // eslint-disable-next-line deprecation/deprecation ...(this._options.blacklistUrls || []), ...(this._options.denyUrls || []), + // eslint-disable-next-line deprecation/deprecation ...(clientOptions.blacklistUrls || []), ...(clientOptions.denyUrls || []), ], diff --git a/packages/core/test/lib/sdk.test.ts b/packages/core/test/lib/sdk.test.ts index 3ab908ec25b1..9910cf1391dd 100644 --- a/packages/core/test/lib/sdk.test.ts +++ b/packages/core/test/lib/sdk.test.ts @@ -1,4 +1,4 @@ -import { Integration, Client } from '@sentry/types'; +import { Client, Integration } from '@sentry/types'; import { installedIntegrations } from '../../src/integration'; import { initAndBind } from '../../src/sdk'; diff --git a/packages/core/test/mocks/backend.ts b/packages/core/test/mocks/backend.ts index a719b55c0fd3..fabf12fcbc13 100644 --- a/packages/core/test/mocks/backend.ts +++ b/packages/core/test/mocks/backend.ts @@ -44,6 +44,7 @@ export class TestBackend extends BaseBackend { super.sendEvent(event); return; } + // eslint-disable-next-line @typescript-eslint/no-unused-expressions TestBackend.sendEventCalled && TestBackend.sendEventCalled(event); } diff --git a/packages/core/test/mocks/client.ts b/packages/core/test/mocks/client.ts index 46aff9409ab3..810328818eae 100644 --- a/packages/core/test/mocks/client.ts +++ b/packages/core/test/mocks/client.ts @@ -1,6 +1,5 @@ import { BaseClient } from '../../src/baseclient'; import { initAndBind } from '../../src/sdk'; - import { TestBackend, TestOptions } from './backend'; export class TestClient extends BaseClient { diff --git a/packages/ember/addon/index.ts b/packages/ember/addon/index.ts index babe2de8fd73..5a27e1191b5c 100644 --- a/packages/ember/addon/index.ts +++ b/packages/ember/addon/index.ts @@ -6,6 +6,10 @@ import { next } from '@ember/runloop'; import { assert, warn, runInDebug } from '@ember/debug'; import Ember from 'ember'; +declare module '@ember/debug' { + export function assert(desc: string, test: unknown): void; +} + export function InitSentryForEmber(_runtimeConfig: BrowserOptions | undefined) { const config = environmentConfig['@sentry/ember']; assert('Missing configuration', config); @@ -21,7 +25,7 @@ export function InitSentryForEmber(_runtimeConfig: BrowserOptions | undefined) { if (config.ignoreEmberOnErrorWarning) { return; } - next(null, function () { + next(null, function() { warn( 'Ember.onerror found. Using Ember.onerror can hide some errors (such as flushed runloop errors) from Sentry. Use Sentry.captureException to capture errors within Ember.onError or remove it to have errors caught by Sentry directly. This error can be silenced via addon configuration.', !Ember.onerror, @@ -35,7 +39,7 @@ export function InitSentryForEmber(_runtimeConfig: BrowserOptions | undefined) { function createEmberEventProcessor(): void { if (addGlobalEventProcessor) { - addGlobalEventProcessor((event) => { + addGlobalEventProcessor(event => { event.sdk = { ...event.sdk, name: 'sentry.javascript.ember', diff --git a/packages/ember/package.json b/packages/ember/package.json index 395b2fd93855..d12fe4ef8cfd 100644 --- a/packages/ember/package.json +++ b/packages/ember/package.json @@ -17,7 +17,7 @@ "build": "ember build --environment=production", "lint": "npm-run-all --aggregate-output --continue-on-error --parallel lint:*", "lint:hbs": "ember-template-lint .", - "lint:js": "eslint .", + "lint:js": "eslint . --cache --cache-location '../../eslintcache/'", "start": "ember serve", "test": "npm-run-all lint:* test:*", "test:ember": "ember test", diff --git a/packages/gatsby/.eslintrc.js b/packages/gatsby/.eslintrc.js new file mode 100644 index 000000000000..782e01c74b4b --- /dev/null +++ b/packages/gatsby/.eslintrc.js @@ -0,0 +1,21 @@ +module.exports = { + root: true, + env: { + es6: true, + browser: true, + node: true, + }, + parserOptions: { + ecmaVersion: 2018, + }, + extends: ['../../.eslintrc.js'], + ignorePatterns: ['build/**/*', 'dist/**/*', 'esm/**/*', 'examples/**/*', 'scripts/**/*'], + overrides: [ + { + files: ['*.ts', '*.tsx', '*.d.ts'], + parserOptions: { + project: './tsconfig.json', + }, + }, + ], +}; diff --git a/packages/gatsby/gatsby-browser.js b/packages/gatsby/gatsby-browser.js index 005d175c9699..1a86c15c9ad2 100644 --- a/packages/gatsby/gatsby-browser.js +++ b/packages/gatsby/gatsby-browser.js @@ -6,11 +6,15 @@ exports.onClientEntry = function(_, pluginParams) { let BrowserTracingIntegration = undefined; try { BrowserTracingIntegration = require('@sentry/tracing').Integrations.BrowserTracing; - } catch (_) {} + } catch (_) { + /* no-empty */ + } try { /** @deprecated Remove when @sentry/apm is no longer used */ TracingIntegration = require('@sentry/apm').Integrations.Tracing; - } catch (_) {} + } catch (_) { + /* no-empty */ + } const tracesSampleRate = pluginParams.tracesSampleRate !== undefined ? pluginParams.tracesSampleRate : 0; const integrations = [...(pluginParams.integrations || [])]; @@ -25,7 +29,9 @@ exports.onClientEntry = function(_, pluginParams) { Sentry.init({ environment: process.env.NODE_ENV || 'development', + // eslint-disable-next-line no-undef release: __SENTRY_RELEASE__, + // eslint-disable-next-line no-undef dsn: __SENTRY_DSN__, ...pluginParams, tracesSampleRate, diff --git a/packages/gatsby/gatsby-node.js b/packages/gatsby/gatsby-node.js index 8b43eaf215c5..6f9574877403 100644 --- a/packages/gatsby/gatsby-node.js +++ b/packages/gatsby/gatsby-node.js @@ -3,7 +3,7 @@ exports.onCreateWebpackConfig = ({ plugins, actions }) => { plugins: [ plugins.define({ __SENTRY_RELEASE__: JSON.stringify( - process.env.SENTRY_RELEASE || + process.env.SENTRY_RELEASE || // GitHub Actions - https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables process.env.GITHUB_SHA || // Netlify - https://docs.netlify.com/configure-builds/environment-variables/#build-metadata diff --git a/packages/gatsby/package.json b/packages/gatsby/package.json index 12c119fbfdde..20f85d4656e0 100644 --- a/packages/gatsby/package.json +++ b/packages/gatsby/package.json @@ -50,13 +50,12 @@ "build:watch:esm": "tsc -p tsconfig.esm.json -w --preserveWatchOutput", "clean": "rimraf dist coverage build esm", "link:yarn": "yarn link", - "lint": "run-s lint:prettier lint:tslint", - "lint:prettier": "prettier-check \"{src,test}/**/*.{ts,tsx}\"", - "lint:tslint": "tslint -t stylish -p .", - "lint:tslint:json": "tslint --format json -p . | tee lint-results.json", - "fix": "run-s fix:tslint fix:prettier", - "fix:prettier": "prettier --write \"{src,test}/**/*.{ts,tsx}\"", - "fix:tslint": "tslint --fix -t stylish -p .", + "lint": "run-s lint:prettier lint:eslint", + "lint:prettier": "prettier-check \"{src,test}/**/*.ts\"", + "lint:eslint": "eslint . --cache --cache-location '../../eslintcache/' --format stylish", + "fix": "run-s fix:eslint fix:prettier", + "fix:prettier": "prettier --write \"{src,test}/**/*.ts\"", + "fix:eslint": "eslint . --format stylish --fix", "test": "jest", "test:watch": "jest --watch" }, diff --git a/packages/gatsby/tslint.json b/packages/gatsby/tslint.json deleted file mode 100644 index 3016a27a85cc..000000000000 --- a/packages/gatsby/tslint.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "@sentry/typescript/tslint" -} diff --git a/packages/hub/package.json b/packages/hub/package.json index 593f37e07728..6797f627484a 100644 --- a/packages/hub/package.json +++ b/packages/hub/package.json @@ -39,11 +39,10 @@ "link:yarn": "yarn link", "lint": "run-s lint:prettier lint:eslint", "lint:prettier": "prettier-check \"{src,test}/**/*.ts\"", - "lint:eslint": "eslint . --format stylish", - "lint:eslint:json": "eslint . --format json | tee lint-results.json", + "lint:eslint": "eslint . --cache --cache-location '../../eslintcache/' --format stylish", "fix": "run-s fix:eslint fix:prettier", "fix:prettier": "prettier --write \"{src,test}/**/*.ts\"", - "fix:eslint": "lint:eslint --fix", + "fix:eslint": "eslint . --format stylish --fix", "test": "jest", "test:watch": "jest --watch" }, diff --git a/packages/minimal/package.json b/packages/minimal/package.json index 3a07c3aef6fd..5b28674321f5 100644 --- a/packages/minimal/package.json +++ b/packages/minimal/package.json @@ -39,11 +39,10 @@ "link:yarn": "yarn link", "lint": "run-s lint:prettier lint:eslint", "lint:prettier": "prettier-check \"{src,test}/**/*.ts\"", - "lint:eslint": "eslint . --format stylish", - "lint:eslint:json": "eslint . --format json | tee lint-results.json", + "lint:eslint": "eslint . --cache --cache-location '../../eslintcache/' --format stylish", "fix": "run-s fix:eslint fix:prettier", "fix:prettier": "prettier --write \"{src,test}/**/*.ts\"", - "fix:eslint": "lint:eslint --fix", + "fix:eslint": "eslint . --format stylish --fix", "test": "jest", "test:watch": "jest --watch" }, diff --git a/packages/types/package.json b/packages/types/package.json index 6868b9f1fab4..ebba18aa74e6 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -31,8 +31,7 @@ "link:yarn": "yarn link", "lint": "run-s lint:prettier lint:eslint", "lint:prettier": "prettier-check \"{src,test}/**/*.ts\"", - "lint:eslint": "eslint . --format stylish", - "lint:eslint:json": "eslint . --format json | tee lint-results.json", + "lint:eslint": "eslint . --cache --cache-location '../../eslintcache/' --format stylish", "fix": "run-s fix:eslint fix:prettier", "fix:prettier": "prettier --write \"{src,test}/**/*.ts\"", "fix:eslint": "eslint . --format stylish --fix" diff --git a/packages/types/src/severity.ts b/packages/types/src/severity.ts index e9a4c940a80b..43f0b97cf384 100644 --- a/packages/types/src/severity.ts +++ b/packages/types/src/severity.ts @@ -1,4 +1,5 @@ /** JSDoc */ +// eslint-disable-next-line import/export export enum Severity { /** JSDoc */ Fatal = 'fatal', @@ -16,7 +17,7 @@ export enum Severity { Critical = 'critical', } -// eslint-disable-next-line @typescript-eslint/no-namespace +// eslint-disable-next-line @typescript-eslint/no-namespace, import/export export namespace Severity { /** * Converts a string-based level into a {@link Severity}. diff --git a/packages/types/src/status.ts b/packages/types/src/status.ts index ef9b1c27bdbd..c490be6f41d9 100644 --- a/packages/types/src/status.ts +++ b/packages/types/src/status.ts @@ -1,4 +1,5 @@ /** The status of an event. */ +// eslint-disable-next-line import/export export enum Status { /** The status could not be determined. */ Unknown = 'unknown', @@ -14,7 +15,7 @@ export enum Status { Failed = 'failed', } -// eslint-disable-next-line @typescript-eslint/no-namespace +// eslint-disable-next-line @typescript-eslint/no-namespace, import/export export namespace Status { /** * Converts a HTTP status code into a {@link Status}. diff --git a/packages/utils/.eslintrc.js b/packages/utils/.eslintrc.js new file mode 100644 index 000000000000..4be661daef4e --- /dev/null +++ b/packages/utils/.eslintrc.js @@ -0,0 +1,29 @@ +module.exports = { + root: true, + env: { + es6: true, + }, + parserOptions: { + ecmaVersion: 2018, + }, + extends: ['../../.eslintrc.js'], + ignorePatterns: ['build/**/*', 'dist/**/*', 'esm/**/*', 'examples/**/*', 'scripts/**/*'], + overrides: [ + { + files: ['*.ts', '*.tsx', '*.d.ts'], + parserOptions: { + project: './tsconfig.json', + }, + }, + { + files: ['test/**/*'], + rules: { + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-non-null-assertion': 'off', + }, + }, + ], + rules: { + 'max-lines': 'off', + }, +}; diff --git a/packages/utils/.gitignore b/packages/utils/.gitignore index 1a514e34e2c2..0bf02553e3a7 100644 --- a/packages/utils/.gitignore +++ b/packages/utils/.gitignore @@ -1,3 +1,4 @@ *.js.map *.d.ts *.js +!.eslintrc.js diff --git a/packages/utils/package.json b/packages/utils/package.json index f59ccb07e054..ed5797dc7e3e 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -26,7 +26,6 @@ "prettier": "^1.17.0", "prettier-check": "^2.0.0", "rimraf": "^2.6.3", - "tslint": "5.16.0", "typescript": "3.4.5" }, "scripts": { @@ -38,13 +37,12 @@ "build:watch:esm": "tsc -p tsconfig.esm.json -w --preserveWatchOutput", "clean": "rimraf dist esm coverage *.js *.js.map *.d.ts", "link:yarn": "yarn link", - "lint": "run-s lint:prettier lint:tslint", + "lint": "run-s lint:prettier lint:eslint", "lint:prettier": "prettier-check \"{src,test}/**/*.ts\"", - "lint:tslint": "tslint -t stylish -p .", - "lint:tslint:json": "tslint --format json -p . | tee lint-results.json", - "fix": "run-s fix:tslint fix:prettier", + "lint:eslint": "eslint . --cache --cache-location '../../eslintcache/' --format stylish", + "fix": "run-s fix:eslint fix:prettier", "fix:prettier": "prettier --write \"{src,test}/**/*.ts\"", - "fix:tslint": "tslint --fix -t stylish -p .", + "fix:eslint": "eslint . --format stylish --fix", "test": "jest", "test:watch": "jest --watch" }, diff --git a/packages/utils/src/async.ts b/packages/utils/src/async.ts index 736a048be60b..cff2aab42774 100644 --- a/packages/utils/src/async.ts +++ b/packages/utils/src/async.ts @@ -2,9 +2,11 @@ * Consumes the promise and logs the error when it rejects. * @param promise A promise to forget. */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any export function forget(promise: PromiseLike): void { promise.then(null, e => { // TODO: Use a better logging mechanism + // eslint-disable-next-line no-console console.error(e); }); } diff --git a/packages/utils/src/dsn.ts b/packages/utils/src/dsn.ts index 5b1ee9c0d243..5188c6d929ad 100644 --- a/packages/utils/src/dsn.ts +++ b/packages/utils/src/dsn.ts @@ -3,7 +3,7 @@ import { DsnComponents, DsnLike, DsnProtocol } from '@sentry/types'; import { SentryError } from './error'; /** Regular expression used to parse a Dsn. */ -const DSN_REGEX = /^(?:(\w+):)\/\/(?:(\w+)(?::(\w+))?@)([\w\.-]+)(?::(\d+))?\/(.+)/; +const DSN_REGEX = /^(?:(\w+):)\/\/(?:(\w+)(?::(\w+))?@)([\w.-]+)(?::(\d+))?\/(.+)/; /** Error message */ const ERROR_MESSAGE = 'Invalid Dsn'; @@ -46,7 +46,6 @@ export class Dsn implements DsnComponents { * @param withPassword When set to true, the password will be included. */ public toString(withPassword: boolean = false): string { - // tslint:disable-next-line:no-this-assignment const { host, path, pass, port, projectId, protocol, user } = this; return ( `${protocol}://${user}${withPassword && pass ? `:${pass}` : ''}` + diff --git a/packages/utils/src/error.ts b/packages/utils/src/error.ts index dfec74235d87..f913d80a7438 100644 --- a/packages/utils/src/error.ts +++ b/packages/utils/src/error.ts @@ -8,7 +8,6 @@ export class SentryError extends Error { public constructor(public message: string) { super(message); - // tslint:disable:no-unsafe-any this.name = new.target.prototype.constructor.name; setPrototypeOf(this, new.target.prototype); } diff --git a/packages/utils/src/instrument.ts b/packages/utils/src/instrument.ts index 8c89507566ee..c89bcbc6e89b 100644 --- a/packages/utils/src/instrument.ts +++ b/packages/utils/src/instrument.ts @@ -1,5 +1,5 @@ -/* tslint:disable:only-arrow-functions no-unsafe-any */ - +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/ban-types */ import { WrappedFunction } from '@sentry/types'; import { isInstanceOf, isString } from './is'; @@ -81,7 +81,6 @@ function instrument(type: InstrumentHandlerType): void { * @hidden */ export function addInstrumentationHandler(handler: InstrumentHandler): void { - // tslint:disable-next-line:strict-type-predicates if (!handler || typeof handler.type !== 'string' || typeof handler.callback !== 'function') { return; } @@ -221,7 +220,8 @@ function instrumentXHR(): void { fill(xhrproto, 'open', function(originalOpen: () => void): () => void { return function(this: SentryWrappedXMLHttpRequest, ...args: any[]): void { - const xhr = this; // tslint:disable-line:no-this-assignment + // eslint-disable-next-line @typescript-eslint/no-this-alias + const xhr = this; const url = args[1]; xhr.__sentry_xhr__ = { method: isString(args[0]) ? args[0].toUpperCase() : args[0], @@ -342,6 +342,7 @@ function instrumentDOM(): void { ['EventTarget', 'Node'].forEach((target: string) => { const proto = (global as any)[target] && (global as any)[target].prototype; + // eslint-disable-next-line no-prototype-builtins if (!proto || !proto.hasOwnProperty || !proto.hasOwnProperty('addEventListener')) { return; } @@ -428,7 +429,7 @@ let lastCapturedEvent: Event | undefined; * @hidden */ function domEventHandler(name: string, handler: Function, debounce: boolean = false): (event: Event) => void { - return (event: Event) => { + return (event: Event): void => { // reset keypress timeout; e.g. triggering a 'click' after // a 'keypress' will reset the keypress debounce so that a new // set of keypresses can be recorded @@ -466,7 +467,7 @@ function keypressEventHandler(handler: Function): (event: Event) => void { // TODO: if somehow user switches keypress target before // debounce timeout is triggered, we will only capture // a single breadcrumb from the FIRST target (acceptable?) - return (event: Event) => { + return (event: Event): void => { let target; try { @@ -514,6 +515,7 @@ function instrumentError(): void { }); if (_oldOnErrorHandler) { + // eslint-disable-next-line prefer-rest-params return _oldOnErrorHandler.apply(this, arguments); } @@ -530,6 +532,7 @@ function instrumentUnhandledRejection(): void { triggerHandlers('unhandledrejection', e); if (_oldOnUnhandledRejectionHandler) { + // eslint-disable-next-line prefer-rest-params return _oldOnUnhandledRejectionHandler.apply(this, arguments); } diff --git a/packages/utils/src/is.ts b/packages/utils/src/is.ts index 78df030a17e0..855863d5ccb2 100644 --- a/packages/utils/src/is.ts +++ b/packages/utils/src/is.ts @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ /** * Checks whether given value's type is one of a few Error or Error-like * {@link isError}. @@ -92,7 +94,6 @@ export function isPlainObject(wat: any): boolean { * @returns A boolean representing the result. */ export function isEvent(wat: any): boolean { - // tslint:disable-next-line:strict-type-predicates return typeof Event !== 'undefined' && isInstanceOf(wat, Event); } @@ -104,7 +105,6 @@ export function isEvent(wat: any): boolean { * @returns A boolean representing the result. */ export function isElement(wat: any): boolean { - // tslint:disable-next-line:strict-type-predicates return typeof Element !== 'undefined' && isInstanceOf(wat, Element); } @@ -124,9 +124,7 @@ export function isRegExp(wat: any): boolean { * @param wat A value to be checked. */ export function isThenable(wat: any): boolean { - // tslint:disable:no-unsafe-any return Boolean(wat && wat.then && typeof wat.then === 'function'); - // tslint:enable:no-unsafe-any } /** @@ -137,7 +135,6 @@ export function isThenable(wat: any): boolean { * @returns A boolean representing the result. */ export function isSyntheticEvent(wat: any): boolean { - // tslint:disable-next-line:no-unsafe-any return isPlainObject(wat) && 'nativeEvent' in wat && 'preventDefault' in wat && 'stopPropagation' in wat; } /** @@ -150,7 +147,6 @@ export function isSyntheticEvent(wat: any): boolean { */ export function isInstanceOf(wat: any, base: any): boolean { try { - // tslint:disable-next-line:no-unsafe-any return wat instanceof base; } catch (_e) { return false; diff --git a/packages/utils/src/logger.ts b/packages/utils/src/logger.ts index f765dfec61dc..ba804d860991 100644 --- a/packages/utils/src/logger.ts +++ b/packages/utils/src/logger.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { consoleSandbox, getGlobalObject } from './misc'; // TODO: Implement different loggers for different environments @@ -32,7 +33,7 @@ class Logger { return; } consoleSandbox(() => { - global.console.log(`${PREFIX}[Log]: ${args.join(' ')}`); // tslint:disable-line:no-console + global.console.log(`${PREFIX}[Log]: ${args.join(' ')}`); }); } @@ -42,7 +43,7 @@ class Logger { return; } consoleSandbox(() => { - global.console.warn(`${PREFIX}[Warn]: ${args.join(' ')}`); // tslint:disable-line:no-console + global.console.warn(`${PREFIX}[Warn]: ${args.join(' ')}`); }); } @@ -52,7 +53,7 @@ class Logger { return; } consoleSandbox(() => { - global.console.error(`${PREFIX}[Error]: ${args.join(' ')}`); // tslint:disable-line:no-console + global.console.error(`${PREFIX}[Error]: ${args.join(' ')}`); }); } } diff --git a/packages/utils/src/memo.ts b/packages/utils/src/memo.ts index 07b86b4d2021..37848fc9587b 100644 --- a/packages/utils/src/memo.ts +++ b/packages/utils/src/memo.ts @@ -1,4 +1,5 @@ -// tslint:disable:no-unsafe-any +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ /** * Memo class used for decycle json objects. Uses WeakSet if available otherwise array. */ @@ -9,7 +10,6 @@ export class Memo { private readonly _inner: any; public constructor() { - // tslint:disable-next-line this._hasWeakSet = typeof WeakSet === 'function'; this._inner = this._hasWeakSet ? new WeakSet() : []; } @@ -26,7 +26,7 @@ export class Memo { this._inner.add(obj); return false; } - // tslint:disable-next-line:prefer-for-of + // eslint-disable-next-line @typescript-eslint/prefer-for-of for (let i = 0; i < this._inner.length; i++) { const value = this._inner[i]; if (value === obj) { diff --git a/packages/utils/src/misc.ts b/packages/utils/src/misc.ts index 92c1f1c2f00f..4448fef110ee 100644 --- a/packages/utils/src/misc.ts +++ b/packages/utils/src/misc.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { Event, Integration, StackFrame, WrappedFunction } from '@sentry/types'; import { isString } from './is'; @@ -25,8 +26,8 @@ interface SentryGlobal { * * @param request The module path to resolve */ +// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export function dynamicRequire(mod: any, request: string): any { - // tslint:disable-next-line: no-unsafe-any return mod.require(request); } @@ -36,7 +37,6 @@ export function dynamicRequire(mod: any, request: string): any { * @returns Answer to given question */ export function isNodeEnv(): boolean { - // tslint:disable:strict-type-predicates return Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) === '[object process]'; } @@ -56,7 +56,6 @@ export function getGlobalObject(): T & SentryGlobal { ? self : fallbackGlobalObject) as T & SentryGlobal; } -// tslint:enable:strict-type-predicates /** * Extended Window interface that allows for Crypto API usage in IE browsers @@ -80,10 +79,10 @@ export function uuid4(): string { crypto.getRandomValues(arr); // set 4 in byte 7 - // tslint:disable-next-line:no-bitwise + // eslint-disable-next-line no-bitwise arr[3] = (arr[3] & 0xfff) | 0x4000; // set 2 most significant bits of byte 9 to '10' - // tslint:disable-next-line:no-bitwise + // eslint-disable-next-line no-bitwise arr[4] = (arr[4] & 0x3fff) | 0x8000; const pad = (num: number): string => { @@ -100,9 +99,9 @@ export function uuid4(): string { } // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523 return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, c => { - // tslint:disable-next-line:no-bitwise + // eslint-disable-next-line no-bitwise const r = (Math.random() * 16) | 0; - // tslint:disable-next-line:no-bitwise + // eslint-disable-next-line no-bitwise const v = c === 'x' ? r : (r & 0x3) | 0x8; return v.toString(16); }); @@ -127,7 +126,7 @@ export function parseUrl( return {}; } - const match = url.match(/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/); + const match = url.match(/^(([^:/?#]+):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/); if (!match) { return {}; @@ -228,11 +227,12 @@ export function addExceptionMechanism( ): void { // TODO: Use real type with `keyof Mechanism` thingy and maybe make it better? try { - // @ts-ignore - // tslint:disable:no-non-null-assertion + // @ts-ignore Type 'Mechanism | {}' is not assignable to type 'Mechanism | undefined' + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion event.exception!.values![0].mechanism = event.exception!.values![0].mechanism || {}; Object.keys(mechanism).forEach(key => { - // @ts-ignore + // @ts-ignore Mechanism has no index signature + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion event.exception!.values![0].mechanism[key] = mechanism[key]; }); } catch (_oO) { @@ -277,6 +277,7 @@ export function htmlTreeAsString(elem: unknown): string { const sepLength = separator.length; let nextStr; + // eslint-disable-next-line no-plusplus while (currentElem && height++ < MAX_TRAVERSE_HEIGHT) { nextStr = _htmlElementAsString(currentElem); // bail out if @@ -306,10 +307,10 @@ export function htmlTreeAsString(elem: unknown): string { */ function _htmlElementAsString(el: unknown): string { const elem = el as { - getAttribute(key: string): string; // tslint:disable-line:completed-docs tagName?: string; id?: string; className?: string; + getAttribute(key: string): string; }; const out = []; @@ -328,6 +329,7 @@ function _htmlElementAsString(el: unknown): string { out.push(`#${elem.id}`); } + // eslint-disable-next-line prefer-const className = elem.className; if (className && isString(className)) { classes = className.split(/\s+/); @@ -353,11 +355,11 @@ let prevNow = 0; * Cross platform compatible partial performance implementation */ interface CrossPlatformPerformance { + timeOrigin: number; /** * Returns the current timestamp in ms */ now(): number; - timeOrigin: number; } const performanceFallback: CrossPlatformPerformance = { @@ -372,7 +374,7 @@ const performanceFallback: CrossPlatformPerformance = { timeOrigin: INITIAL_TIME, }; -export const crossPlatformPerformance: CrossPlatformPerformance = (() => { +export const crossPlatformPerformance: CrossPlatformPerformance = ((): CrossPlatformPerformance => { if (isNodeEnv()) { try { const perfHooks = dynamicRequire(module, 'perf_hooks') as { performance: CrossPlatformPerformance }; @@ -392,12 +394,11 @@ export const crossPlatformPerformance: CrossPlatformPerformance = (() => { // // While performance.timing.navigationStart is deprecated in favor of performance.timeOrigin, performance.timeOrigin // is not as widely supported. Namely, performance.timeOrigin is undefined in Safari as of writing. - // tslint:disable-next-line:strict-type-predicates if (performance.timeOrigin === undefined) { // As of writing, performance.timing is not available in Web Workers in mainstream browsers, so it is not always a // valid fallback. In the absence of a initial time provided by the browser, fallback to INITIAL_TIME. - // @ts-ignore - // tslint:disable-next-line:deprecation + // @ts-ignore ignored because timeOrigin is a readonly property but we want to override + // eslint-disable-next-line deprecation/deprecation performance.timeOrigin = (performance.timing && performance.timing.navigationStart) || INITIAL_TIME; } diff --git a/packages/utils/src/object.ts b/packages/utils/src/object.ts index 1a2c1ed0fe5c..1318dad98d53 100644 --- a/packages/utils/src/object.ts +++ b/packages/utils/src/object.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { ExtendedError, WrappedFunction } from '@sentry/types'; import { isElement, isError, isEvent, isInstanceOf, isPlainObject, isPrimitive, isSyntheticEvent } from './is'; @@ -23,7 +24,6 @@ export function fill(source: { [key: string]: any }, name: string, replacement: // Make sure it's a function first, as we need to attach an empty prototype for `defineProperties` to work // otherwise it'll throw "TypeError: Object.defineProperties called on non-object" - // tslint:disable-next-line:strict-type-predicates if (typeof wrapped === 'function') { try { wrapped.prototype = wrapped.prototype || {}; @@ -50,10 +50,7 @@ export function fill(source: { [key: string]: any }, name: string, replacement: */ export function urlEncode(object: { [key: string]: any }): string { return Object.keys(object) - .map( - // tslint:disable-next-line:no-unsafe-any - key => `${encodeURIComponent(key)}=${encodeURIComponent(object[key])}`, - ) + .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(object[key])}`) .join('&'); } @@ -71,10 +68,10 @@ function getWalkSource( if (isError(value)) { const error = value as ExtendedError; const err: { + [key: string]: any; stack: string | undefined; message: string; name: string; - [key: string]: any; } = { message: error.message, name: error.name, @@ -126,7 +123,6 @@ function getWalkSource( source.currentTarget = ''; } - // tslint:disable-next-line:strict-type-predicates if (typeof CustomEvent !== 'undefined' && isInstanceOf(value, CustomEvent)) { source.detail = event.detail; } @@ -147,7 +143,7 @@ function getWalkSource( /** Calculates bytes size of input string */ function utf8Length(value: string): number { - // tslint:disable-next-line:no-bitwise + // eslint-disable-next-line no-bitwise return ~-encodeURI(value).split(/%..|./).length; } @@ -201,7 +197,6 @@ function serializeValue(value: any): any { * - serializes Error objects * - filter global objects */ -// tslint:disable-next-line:cyclomatic-complexity function normalizeValue(value: T, key?: any): T | string { if (key === 'domain' && value && typeof value === 'object' && ((value as unknown) as { _events: any })._events) { return '[Domain]'; @@ -228,7 +223,6 @@ function normalizeValue(value: T, key?: any): T | string { return '[SyntheticEvent]'; } - // tslint:disable-next-line:no-tautology-expression if (typeof value === 'number' && value !== value) { return '[NaN]'; } @@ -252,6 +246,7 @@ function normalizeValue(value: T, key?: any): T | string { * @param depth Optional number indicating how deep should walking be performed * @param memo Optional Memo class handling decycling */ +// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export function walk(key: string, value: any, depth: number = +Infinity, memo: Memo = new Memo()): any { // If we reach the maximum depth, serialize whatever has left if (depth === 0) { @@ -259,11 +254,9 @@ export function walk(key: string, value: any, depth: number = +Infinity, memo: M } // If value implements `toJSON` method, call it and return early - // tslint:disable:no-unsafe-any if (value !== null && value !== undefined && typeof value.toJSON === 'function') { return value.toJSON(); } - // tslint:enable:no-unsafe-any // If normalized value is a primitive, there are no branches left to walk, so we can just bail out, as theres no point in going down that branch any further const normalized = normalizeValue(value, key); @@ -311,9 +304,9 @@ export function walk(key: string, value: any, depth: number = +Infinity, memo: M * - Takes care of Error objects serialization * - Optionally limit depth of final output */ +// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export function normalize(input: any, depth?: number): any { try { - // tslint:disable-next-line:no-unsafe-any return JSON.parse(JSON.stringify(input, (key: string, value: any) => walk(key, value, depth))); } catch (_oO) { return '**non-serializable**'; @@ -325,8 +318,8 @@ export function normalize(input: any, depth?: number): any { * and truncated list that will be used inside the event message. * eg. `Non-error exception captured with keys: foo, bar, baz` */ +// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export function extractExceptionKeysForMessage(exception: any, maxLength: number = 40): string { - // tslint:disable:strict-type-predicates const keys = Object.keys(getWalkSource(exception)); keys.sort(); diff --git a/packages/utils/src/path.ts b/packages/utils/src/path.ts index 8e505cdf6dc2..ba885a3f9a56 100644 --- a/packages/utils/src/path.ts +++ b/packages/utils/src/path.ts @@ -11,15 +11,18 @@ function normalizeArray(parts: string[], allowAboveRoot?: boolean): string[] { parts.splice(i, 1); } else if (last === '..') { parts.splice(i, 1); + // eslint-disable-next-line no-plusplus up++; } else if (up) { parts.splice(i, 1); + // eslint-disable-next-line no-plusplus up--; } } // if the path is allowed to go above the root, restore leading ..s if (allowAboveRoot) { + // eslint-disable-next-line no-plusplus for (; up--; up) { parts.unshift('..'); } @@ -30,7 +33,7 @@ function normalizeArray(parts: string[], allowAboveRoot?: boolean): string[] { // Split a filename into [root, dir, basename, ext], unix version // 'root' is just a slash, or nothing. -const splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; +const splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^/]+?|)(\.[^./]*|))(?:[/]*)$/; /** JSDoc */ function splitPath(filename: string): string[] { const parts = splitPathRe.exec(filename); @@ -94,9 +97,10 @@ function trim(arr: string[]): string[] { // posix version /** JSDoc */ export function relative(from: string, to: string): string { - // tslint:disable:no-parameter-reassignment + /* eslint-disable no-param-reassign */ from = resolve(from).substr(1); to = resolve(to).substr(1); + /* eslint-enable no-param-reassign */ const fromParts = trim(from.split('/')); const toParts = trim(to.split('/')); diff --git a/packages/utils/src/polyfill.ts b/packages/utils/src/polyfill.ts index 5c9d0bd2bab0..a79fc7d2f01e 100644 --- a/packages/utils/src/polyfill.ts +++ b/packages/utils/src/polyfill.ts @@ -1,11 +1,12 @@ export const setPrototypeOf = - Object.setPrototypeOf || ({ __proto__: [] } instanceof Array ? setProtoOf : mixinProperties); // tslint:disable-line:no-unbound-method + Object.setPrototypeOf || ({ __proto__: [] } instanceof Array ? setProtoOf : mixinProperties); /** * setPrototypeOf polyfill using __proto__ */ +// eslint-disable-next-line @typescript-eslint/ban-types function setProtoOf(obj: TTarget, proto: TProto): TTarget & TProto { - // @ts-ignore + // @ts-ignore __proto__ does not exist on obj obj.__proto__ = proto; return obj as TTarget & TProto; } @@ -13,10 +14,12 @@ function setProtoOf(obj: TTarget, proto: TProto) /** * setPrototypeOf polyfill using mixin */ +// eslint-disable-next-line @typescript-eslint/ban-types function mixinProperties(obj: TTarget, proto: TProto): TTarget & TProto { for (const prop in proto) { + // eslint-disable-next-line no-prototype-builtins if (!obj.hasOwnProperty(prop)) { - // @ts-ignore + // @ts-ignore typescript complains about indexing so we remove obj[prop] = proto[prop]; } } diff --git a/packages/utils/src/promisebuffer.ts b/packages/utils/src/promisebuffer.ts index 4bb0d4c9ca9e..73e00047e49a 100644 --- a/packages/utils/src/promisebuffer.ts +++ b/packages/utils/src/promisebuffer.ts @@ -3,11 +3,11 @@ import { SyncPromise } from './syncpromise'; /** A simple queue that holds promises. */ export class PromiseBuffer { - public constructor(protected _limit?: number) {} - /** Internal set of queued Promises */ private readonly _buffer: Array> = []; + public constructor(protected _limit?: number) {} + /** * Says if the buffer is ready to take more requests */ diff --git a/packages/utils/src/string.ts b/packages/utils/src/string.ts index 8e6633d389c3..83896358dc4f 100644 --- a/packages/utils/src/string.ts +++ b/packages/utils/src/string.ts @@ -8,7 +8,6 @@ import { isRegExp, isString } from './is'; * @returns string Encoded */ export function truncate(str: string, max: number = 0): string { - // tslint:disable-next-line:strict-type-predicates if (typeof str !== 'string' || max === 0) { return str; } @@ -23,7 +22,6 @@ export function truncate(str: string, max: number = 0): string { * @param max Maximum number of characters in truncated string * @returns string Encoded */ - export function snipLine(line: string, colno: number): string { let newLine = line; const ll = newLine.length; @@ -31,7 +29,8 @@ export function snipLine(line: string, colno: number): string { return newLine; } if (colno > ll) { - colno = ll; // tslint:disable-line:no-parameter-reassignment + // eslint-disable-next-line no-param-reassign + colno = ll; } let start = Math.max(colno - 60, 0); @@ -64,13 +63,14 @@ export function snipLine(line: string, colno: number): string { * @param delimiter string to be placed in-between values * @returns Joined values */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any export function safeJoin(input: any[], delimiter?: string): string { if (!Array.isArray(input)) { return ''; } const output = []; - // tslint:disable-next-line:prefer-for-of + // eslint-disable-next-line @typescript-eslint/prefer-for-of for (let i = 0; i < input.length; i++) { const value = input[i]; try { diff --git a/packages/utils/src/supports.ts b/packages/utils/src/supports.ts index 43e3a66a3059..7185536e95ef 100644 --- a/packages/utils/src/supports.ts +++ b/packages/utils/src/supports.ts @@ -9,7 +9,6 @@ import { getGlobalObject } from './misc'; */ export function supportsErrorEvent(): boolean { try { - // tslint:disable:no-unused-expression new ErrorEvent(''); return true; } catch (e) { @@ -25,11 +24,9 @@ export function supportsErrorEvent(): boolean { */ export function supportsDOMError(): boolean { try { - // It really needs 1 argument, not 0. // Chrome: VM89:1 Uncaught TypeError: Failed to construct 'DOMError': // 1 argument required, but only 0 present. - // @ts-ignore - // tslint:disable:no-unused-expression + // @ts-ignore It really needs 1 argument, not 0. new DOMError(''); return true; } catch (e) { @@ -45,7 +42,6 @@ export function supportsDOMError(): boolean { */ export function supportsDOMException(): boolean { try { - // tslint:disable:no-unused-expression new DOMException(''); return true; } catch (e) { @@ -65,11 +61,8 @@ export function supportsFetch(): boolean { } try { - // tslint:disable-next-line:no-unused-expression new Headers(); - // tslint:disable-next-line:no-unused-expression new Request(''); - // tslint:disable-next-line:no-unused-expression new Response(); return true; } catch (e) { @@ -79,6 +72,7 @@ export function supportsFetch(): boolean { /** * isNativeFetch checks if the given function is a native implementation of fetch() */ +// eslint-disable-next-line @typescript-eslint/ban-types function isNativeFetch(func: Function): boolean { return func && /^function fetch\(\)\s+\{\s+\[native code\]\s+\}$/.test(func.toString()); } @@ -97,7 +91,7 @@ export function supportsNativeFetch(): boolean { const global = getGlobalObject(); // Fast path to avoid DOM I/O - // tslint:disable-next-line:no-unbound-method + // eslint-disable-next-line @typescript-eslint/unbound-method if (isNativeFetch(global.fetch)) { return true; } @@ -106,14 +100,14 @@ export function supportsNativeFetch(): boolean { // so create a "pure" iframe to see if that has native fetch let result = false; const doc = global.document; - // tslint:disable-next-line:no-unbound-method deprecation + // eslint-disable-next-line deprecation/deprecation if (doc && typeof (doc.createElement as unknown) === `function`) { try { const sandbox = doc.createElement('iframe'); sandbox.hidden = true; doc.head.appendChild(sandbox); if (sandbox.contentWindow && sandbox.contentWindow.fetch) { - // tslint:disable-next-line:no-unbound-method + // eslint-disable-next-line @typescript-eslint/unbound-method result = isNativeFetch(sandbox.contentWindow.fetch); } doc.head.removeChild(sandbox); @@ -132,7 +126,6 @@ export function supportsNativeFetch(): boolean { * @returns Answer to the given question. */ export function supportsReportingObserver(): boolean { - // tslint:disable-next-line: no-unsafe-any return 'ReportingObserver' in getGlobalObject(); } @@ -153,7 +146,6 @@ export function supportsReferrerPolicy(): boolean { } try { - // tslint:disable:no-unused-expression new Request('_', { referrerPolicy: 'origin' as ReferrerPolicy, }); @@ -174,8 +166,8 @@ export function supportsHistory(): boolean { // a try/catch block*, will cause Chrome to output an error to console.error // borrowed from: https://github.com/angular/angular.js/pull/13945/files const global = getGlobalObject(); + // eslint-disable-next-line @typescript-eslint/no-explicit-any const chrome = (global as any).chrome; - // tslint:disable-next-line:no-unsafe-any const isChromePackagedApp = chrome && chrome.app && chrome.app.runtime; const hasHistoryApi = 'history' in global && !!global.history.pushState && !!global.history.replaceState; diff --git a/packages/utils/src/syncpromise.ts b/packages/utils/src/syncpromise.ts index efcdb1b0f4b9..a13ecb051da1 100644 --- a/packages/utils/src/syncpromise.ts +++ b/packages/utils/src/syncpromise.ts @@ -1,3 +1,7 @@ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ +/* eslint-disable @typescript-eslint/typedef */ +/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { isThenable } from './is'; /** SyncPromise internal states */ @@ -33,11 +37,6 @@ class SyncPromise implements PromiseLike { } } - /** JSDoc */ - public toString(): string { - return '[object SyncPromise]'; - } - /** JSDoc */ public static resolve(value: T | PromiseLike): PromiseLike { return new SyncPromise(resolve => { @@ -163,6 +162,11 @@ class SyncPromise implements PromiseLike { }); } + /** JSDoc */ + public toString(): string { + return '[object SyncPromise]'; + } + /** JSDoc */ private readonly _resolve = (value?: T | PromiseLike | null) => { this._setResult(States.RESOLVED, value); @@ -220,6 +224,7 @@ class SyncPromise implements PromiseLike { if (this._state === States.RESOLVED) { if (handler.onfulfilled) { + // eslint-disable-next-line @typescript-eslint/no-floating-promises handler.onfulfilled((this._value as unknown) as any); } } diff --git a/packages/utils/test/async.test.ts b/packages/utils/test/async.test.ts index 5cf24e253034..cdb0514a602a 100644 --- a/packages/utils/test/async.test.ts +++ b/packages/utils/test/async.test.ts @@ -1,4 +1,4 @@ -import { filterAsync, forget } from '../src/async'; +import { forget } from '../src/async'; describe('forget', () => { const console = { diff --git a/packages/utils/test/is.test.ts b/packages/utils/test/is.test.ts index 45c975eec890..cd936edacee0 100644 --- a/packages/utils/test/is.test.ts +++ b/packages/utils/test/is.test.ts @@ -16,8 +16,7 @@ if (supportsDOMError()) { describe('isDOMError()', () => { test('should work as advertised', () => { expect(isDOMError(new Error())).toEqual(false); - // See: src/supports.ts for details - // @ts-ignore + // @ts-ignore See: src/supports.ts for details expect(isDOMError(new DOMError(''))).toEqual(true); }); }); @@ -97,6 +96,7 @@ describe('isInstanceOf()', () => { } expect(isInstanceOf(new Error('wat'), Error)).toEqual(true); expect(isInstanceOf(new Date(), Date)).toEqual(true); + // @ts-ignore Foo implicity has any type, doesn't have constructor expect(isInstanceOf(new Foo(), Foo)).toEqual(true); expect(isInstanceOf(new Error('wat'), Foo)).toEqual(false); diff --git a/packages/utils/test/object.test.ts b/packages/utils/test/object.test.ts index 8e1f4754a9cd..2dfbe452fe15 100644 --- a/packages/utils/test/object.test.ts +++ b/packages/utils/test/object.test.ts @@ -60,8 +60,9 @@ describe('fill()', () => { test('internal flags shouldnt be enumerable', () => { const source = { foo: (): number => 42, - }; + } as any; const name = 'foo'; + // @ts-ignore cb has any type const replacement = cb => cb; fill(source, name, replacement); @@ -79,6 +80,7 @@ describe('fill()', () => { const bar = {}; source.foo.prototype = bar; const name = 'foo'; + // @ts-ignore cb has any type const replacement = cb => cb; fill(source, name, replacement); @@ -118,21 +120,15 @@ describe('normalize()', () => { }); test('extracts extra properties from error objects', () => { - const obj = new Error('Wubba Lubba Dub Dub'); - // @ts-ignore + const obj = new Error('Wubba Lubba Dub Dub') as any; obj.reason = new TypeError("I'm pickle Riiick!"); - // @ts-ignore obj.extra = 'some extra prop'; - // Stack is inconsistent across browsers, so override it and just make sure its stringified obj.stack = 'x'; - // @ts-ignore obj.reason.stack = 'x'; // IE 10/11 - // @ts-ignore delete obj.description; - // @ts-ignore delete obj.reason.description; expect(normalize(obj)).toEqual({ @@ -150,22 +146,19 @@ describe('normalize()', () => { describe('decycles cyclical structures', () => { test('circular objects', () => { - const obj = { name: 'Alice' }; - // @ts-ignore + const obj = { name: 'Alice' } as any; obj.self = obj; expect(normalize(obj)).toEqual({ name: 'Alice', self: '[Circular ~]' }); }); test('circular objects with intermediaries', () => { - const obj = { name: 'Alice' }; - // @ts-ignore + const obj = { name: 'Alice' } as any; obj.identity = { self: obj }; expect(normalize(obj)).toEqual({ name: 'Alice', identity: { self: '[Circular ~]' } }); }); test('deep circular objects', () => { - const obj = { name: 'Alice', child: { name: 'Bob' } }; - // @ts-ignore + const obj = { name: 'Alice', child: { name: 'Bob' } } as any; obj.child.self = obj.child; expect(normalize(obj)).toEqual({ name: 'Alice', @@ -174,8 +167,7 @@ describe('normalize()', () => { }); test('deep circular objects with intermediaries', () => { - const obj = { name: 'Alice', child: { name: 'Bob' } }; - // @ts-ignore + const obj = { name: 'Alice', child: { name: 'Bob' } } as any; obj.child.identity = { self: obj.child }; expect(normalize(obj)).toEqual({ name: 'Alice', @@ -184,8 +176,7 @@ describe('normalize()', () => { }); test('circular objects in an array', () => { - const obj = { name: 'Alice' }; - // @ts-ignore + const obj = { name: 'Alice' } as any; obj.self = [obj, obj]; expect(normalize(obj)).toEqual({ name: 'Alice', @@ -197,10 +188,8 @@ describe('normalize()', () => { const obj = { name: 'Alice', children: [{ name: 'Bob' }, { name: 'Eve' }], - }; - // @ts-ignore + } as any; obj.children[0].self = obj.children[0]; - // @ts-ignore obj.children[1].self = obj.children[1]; expect(normalize(obj)).toEqual({ name: 'Alice', @@ -212,6 +201,7 @@ describe('normalize()', () => { }); test('circular arrays', () => { + // eslint-disable-next-line @typescript-eslint/ban-types const obj: object[] = []; obj.push(obj); obj.push(obj); @@ -219,6 +209,7 @@ describe('normalize()', () => { }); test('circular arrays with intermediaries', () => { + // eslint-disable-next-line @typescript-eslint/ban-types const obj: object[] = []; obj.push({ name: 'Alice', self: obj }); obj.push({ name: 'Bob', self: obj }); @@ -229,11 +220,9 @@ describe('normalize()', () => { }); test('repeated objects in objects', () => { - const obj = {}; + const obj = {} as any; const alice = { name: 'Alice' }; - // @ts-ignore obj.alice1 = alice; - // @ts-ignore obj.alice2 = alice; expect(normalize(obj)).toEqual({ alice1: { name: 'Alice' }, @@ -248,17 +237,13 @@ describe('normalize()', () => { }); test('error objects with circular references', () => { - const obj = new Error('Wubba Lubba Dub Dub'); - // @ts-ignore + const obj = new Error('Wubba Lubba Dub Dub') as any; obj.reason = obj; - // Stack is inconsistent across browsers, so override it and just make sure its stringified obj.stack = 'x'; - // @ts-ignore obj.reason.stack = 'x'; // IE 10/11 - // @ts-ignore delete obj.description; expect(normalize(obj)).toEqual({ @@ -274,7 +259,7 @@ describe('normalize()', () => { test('simple object', () => { const circular = { foo: 1, - }; + } as any; circular.bar = circular; const normalized = normalize(circular); @@ -290,7 +275,7 @@ describe('normalize()', () => { test('complex object', () => { const circular = { foo: 1, - }; + } as any; circular.bar = [ { baz: circular, @@ -320,7 +305,7 @@ describe('normalize()', () => { test('object with non-enumerable properties', () => { const circular = { foo: 1, - }; + } as any; circular.bar = circular; circular.baz = { one: 1337, @@ -351,10 +336,9 @@ describe('normalize()', () => { describe('calls toJSON if implemented', () => { test('primitive values', () => { - // tslint:disable:no-construct - const a = new Number(1); + const a = new Number(1) as any; a.toJSON = () => 10; - const b = new String('2'); + const b = new String('2') as any; b.toJSON = () => '20'; expect(normalize(a)).toEqual(10); expect(normalize(b)).toEqual('20'); @@ -364,11 +348,12 @@ describe('normalize()', () => { const a = Object.create({}); a.toJSON = () => 1; function B(): void { - /*no-empty*/ + /* no-empty */ } B.prototype.toJSON = () => 2; - const c = []; + const c: any = []; c.toJSON = () => 3; + // @ts-ignore target lacks a construct signature expect(normalize([{ a }, { b: new B() }, c])).toEqual([{ a: 1 }, { b: 2 }, 3]); }); }); @@ -485,7 +470,7 @@ describe('normalize()', () => { { something: 'else', fn: () => { - /*no-empty*/ + /* no-empty */ }, }, ], @@ -518,7 +503,7 @@ describe('normalize()', () => { }, baz: NaN, qux: function qux(): void { - /*no-empty*/ + /* no-empty */ }, }; const result = normalize(obj); diff --git a/packages/utils/test/promisebuffer.test.ts b/packages/utils/test/promisebuffer.test.ts index c2f6e1efce30..bf4288000f38 100644 --- a/packages/utils/test/promisebuffer.test.ts +++ b/packages/utils/test/promisebuffer.test.ts @@ -1,8 +1,7 @@ +/* eslint-disable @typescript-eslint/no-floating-promises */ import { PromiseBuffer } from '../src/promisebuffer'; import { SyncPromise } from '../src/syncpromise'; -// tslint:disable:no-floating-promises - describe('PromiseBuffer', () => { beforeEach(() => { jest.useFakeTimers(); diff --git a/packages/utils/test/syncpromise.test.ts b/packages/utils/test/syncpromise.test.ts index 685edabd6861..4b2e15008b7c 100644 --- a/packages/utils/test/syncpromise.test.ts +++ b/packages/utils/test/syncpromise.test.ts @@ -77,13 +77,17 @@ describe('SyncPromise', () => { }); }); - return c - .then(val => f(SyncPromise.resolve('x'), val)) - .then(val => f(b, val)) - .then(val => f(a, val)) - .then(val => { - expect(val).toBe(res); - }); + return ( + c + // @ts-ignore Argument of type 'PromiseLike' is not assignable to parameter of type 'SyncPromise' + .then(val => f(SyncPromise.resolve('x'), val)) + .then(val => f(b, val)) + // @ts-ignore Argument of type 'SyncPromise' is not assignable to parameter of type 'string' + .then(val => f(a, val)) + .then(val => { + expect(val).toBe(res); + }) + ); }); test('simple static', () => { @@ -131,6 +135,7 @@ describe('SyncPromise', () => { let foo: number = 1; + // eslint-disable-next-line @typescript-eslint/no-floating-promises new SyncPromise(_ => { foo = 2; }); diff --git a/packages/utils/test/tslint.json b/packages/utils/test/tslint.json deleted file mode 100644 index 3d047d490f0e..000000000000 --- a/packages/utils/test/tslint.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": ["../tslint.json"], - "rules": { - "completed-docs": false, - "no-unused-expression": false, - "no-implicit-dependencies": [true, "dev"], - "no-unsafe-any": false, - // We disable this rule, because order in `serialize()` tests matter - "object-literal-sort-keys": false - } -} diff --git a/packages/utils/tslint.json b/packages/utils/tslint.json deleted file mode 100644 index 3016a27a85cc..000000000000 --- a/packages/utils/tslint.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "@sentry/typescript/tslint" -} diff --git a/yarn.lock b/yarn.lock index 9db02a6f18f1..14f40ee66e2f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,27 @@ # yarn lockfile v1 +"@angular/common@^10.0.3": + version "10.0.8" + resolved "https://registry.yarnpkg.com/@angular/common/-/common-10.0.8.tgz#591263b42f8d03f3730e927251dae175e0d60669" + integrity sha512-Nzk5ckQ8y/qvTmqRdzpwUQELYD9N6DJC5yPWQw+remlkUTw24KX4KMUnt9Iy/2eFQC65MhZoTwostuKpjffrlQ== + dependencies: + tslib "^2.0.0" + +"@angular/core@^10.0.3": + version "10.0.8" + resolved "https://registry.yarnpkg.com/@angular/core/-/core-10.0.8.tgz#dd8855e9faa3f2ba37268144d15402d346b1be57" + integrity sha512-52M1krR/TRZsV9WKPd+r7IPVT8c5Nh+Im1z3/ZY7rG0HmxXsV7YzuTuKV7oyHbWPg0WPJAwyH0+qxBK3kpvc8w== + dependencies: + tslib "^2.0.0" + +"@angular/router@^10.0.3": + version "10.0.8" + resolved "https://registry.yarnpkg.com/@angular/router/-/router-10.0.8.tgz#8eec22a8c1050be4fb4003d177bee9e566df8aaf" + integrity sha512-Plub5gtfRv0Uk/e1Q66LVXRohzfMPqE9a4OqboFDjlWT5a94XSJaSHMgQHZ0esKoRidxijo3aRJOUSc/LAO9JQ== + dependencies: + tslib "^2.0.0" + "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" @@ -2046,6 +2067,58 @@ dependencies: "@types/node" ">= 8" +"@sentry/browser@5.19.1": + version "5.19.1" + resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-5.19.1.tgz#b22f36fc71f36719ad352a54e6b31722622128c0" + integrity sha512-Aon5Nc2n8sIXKg6Xbr4RM3/Xs7vFpXksL56z3yIuGrmpCM8ToQ25/tQv8h+anYi72x5bn1npzaXB/NwU1Qwfhg== + dependencies: + "@sentry/core" "5.19.1" + "@sentry/types" "5.19.1" + "@sentry/utils" "5.19.1" + tslib "^1.9.3" + +"@sentry/core@5.19.1": + version "5.19.1" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.19.1.tgz#f5ff7feb1118035f75f1d0bc2a76e2b040d2aa8e" + integrity sha512-BGGxjeT95Og/hloBhQXAVcndVXPmIU6drtF3oKRT12cBpiG965xEDEUwiJVvyb5MAvojdVEZBK2LURUFY/d7Zw== + dependencies: + "@sentry/hub" "5.19.1" + "@sentry/minimal" "5.19.1" + "@sentry/types" "5.19.1" + "@sentry/utils" "5.19.1" + tslib "^1.9.3" + +"@sentry/hub@5.19.1": + version "5.19.1" + resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.19.1.tgz#f3bc8500680974ce43c1eedcd8e90696cc18b306" + integrity sha512-XjfbNGWVeDsP38alm5Cm08YPIw5Hu6HbPkw7a3y1piViTrg4HdtsE+ZJqq0YcURo2RTpg6Ks6coCS/zJxIPygQ== + dependencies: + "@sentry/types" "5.19.1" + "@sentry/utils" "5.19.1" + tslib "^1.9.3" + +"@sentry/minimal@5.19.1": + version "5.19.1" + resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.19.1.tgz#04043d93a7dc90cbed1a31d80f6bf59688ea3100" + integrity sha512-pgNfsaCroEsC8gv+NqmPTIkj4wyK6ZgYLV12IT4k2oJLkGyg45TSAKabyB7oEP5jsj8sRzm8tDomu8M4HpaCHg== + dependencies: + "@sentry/hub" "5.19.1" + "@sentry/types" "5.19.1" + tslib "^1.9.3" + +"@sentry/types@5.19.1": + version "5.19.1" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.19.1.tgz#8762f668d3fc2416fbde31d15d13009544caeb54" + integrity sha512-M5MhTLnjqYFwxMwcFPBpBgYQqI9hCvtVuj/A+NvcBHpe7VWOXdn/Sys+zD6C76DWGFYQdw3OWCsZimP24dL8mA== + +"@sentry/utils@5.19.1": + version "5.19.1" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.19.1.tgz#e1134db40e4bb9732251e515721cec7ee94d4d9c" + integrity sha512-neUiNBnZSHjWTZWy2QV02EHTx1C2L3DBPzRXlh0ca5xrI7LMBLmhkHlhebn1E5ky3PW1teqZTgmh0jZoL99TEA== + dependencies: + "@sentry/types" "5.19.1" + tslib "^1.9.3" + "@simple-dom/interface@^1.4.0": version "1.4.0" resolved "https://registry.yarnpkg.com/@simple-dom/interface/-/interface-1.4.0.tgz#e8feea579232017f89b0138e2726facda6fbb71f" @@ -2580,6 +2653,11 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd" integrity sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ== +"@types/json5@^0.0.29": + version "0.0.29" + resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" + integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= + "@types/lodash@^4.14.110": version "4.14.158" resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.158.tgz#b38ea8b6fe799acd076d7a8d7ab71c26ef77f785" @@ -2824,6 +2902,17 @@ eslint-scope "^5.0.0" eslint-utils "^2.0.0" +"@typescript-eslint/experimental-utils@^2.19.2 || ^3.0.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-3.9.0.tgz#3171d8ddba0bf02a8c2034188593630914fcf5ee" + integrity sha512-/vSHUDYizSOhrOJdjYxPNGfb4a3ibO8zd4nUKo/QBFOmxosT3cVUV7KIg8Dwi6TXlr667G7YPqFK9+VSZOorNA== + dependencies: + "@types/json-schema" "^7.0.3" + "@typescript-eslint/types" "3.9.0" + "@typescript-eslint/typescript-estree" "3.9.0" + eslint-scope "^5.0.0" + eslint-utils "^2.0.0" + "@typescript-eslint/parser@^3.7.1": version "3.7.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-3.7.1.tgz#5d9ccecb116d12d9c6073e9861c57c9b1aa88128" @@ -2840,6 +2929,11 @@ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-3.7.1.tgz#90375606b2fd73c1224fe9e397ee151e28fa1e0c" integrity sha512-PZe8twm5Z4b61jt7GAQDor6KiMhgPgf4XmUb9zdrwTbgtC/Sj29gXP1dws9yEn4+aJeyXrjsD9XN7AWFhmnUfg== +"@typescript-eslint/types@3.9.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-3.9.0.tgz#be9d0aa451e1bf3ce99f2e6920659e5b2e6bfe18" + integrity sha512-rb6LDr+dk9RVVXO/NJE8dT1pGlso3voNdEIN8ugm4CWM5w5GimbThCMiMl4da1t5u3YwPWEwOnKAULCZgBtBHg== + "@typescript-eslint/typescript-estree@3.7.1": version "3.7.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-3.7.1.tgz#ce1ffbd0fa53f34d4ce851a7a364e392432f6eb3" @@ -2854,6 +2948,20 @@ semver "^7.3.2" tsutils "^3.17.1" +"@typescript-eslint/typescript-estree@3.9.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-3.9.0.tgz#c6abbb50fa0d715cab46fef67ca6378bf2eaca13" + integrity sha512-N+158NKgN4rOmWVfvKOMoMFV5n8XxAliaKkArm/sOypzQ0bUL8MSnOEBW3VFIeffb/K5ce/cAV0yYhR7U4ALAA== + dependencies: + "@typescript-eslint/types" "3.9.0" + "@typescript-eslint/visitor-keys" "3.9.0" + debug "^4.1.1" + glob "^7.1.6" + is-glob "^4.0.1" + lodash "^4.17.15" + semver "^7.3.2" + tsutils "^3.17.1" + "@typescript-eslint/visitor-keys@3.7.1": version "3.7.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-3.7.1.tgz#b90191e74efdee656be8c5a30f428ed16dda46d1" @@ -2861,6 +2969,13 @@ dependencies: eslint-visitor-keys "^1.1.0" +"@typescript-eslint/visitor-keys@3.9.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-3.9.0.tgz#44de8e1b1df67adaf3b94d6b60b80f8faebc8dd3" + integrity sha512-O1qeoGqDbu0EZUC/MZ6F1WHTIzcBVhGqDj3LhTnj65WUA548RXVxUHbYhAW9bZWfb2rnX9QsbbP5nmeJ5Z4+ng== + dependencies: + eslint-visitor-keys "^1.1.0" + "@webassemblyjs/ast@1.7.11": version "1.7.11" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.7.11.tgz#b988582cafbb2b095e8b556526f30c90d057cace" @@ -3606,6 +3721,15 @@ array-ify@^1.0.0: resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" integrity sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4= +array-includes@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.1.tgz#cdd67e6852bdf9c1215460786732255ed2459348" + integrity sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0" + is-string "^1.0.5" + array-to-error@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/array-to-error/-/array-to-error-1.1.1.tgz#d68812926d14097a205579a667eeaf1856a44c07" @@ -3640,6 +3764,14 @@ array-unique@^0.3.2: resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= +array.prototype.flat@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz#0de82b426b0318dbfdb940089e38b043d37f6c7b" + integrity sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + arraybuffer.slice@~0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675" @@ -6494,6 +6626,11 @@ constants-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= +contains-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" + integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= + content-disposition@0.5.3: version "0.5.3" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" @@ -7439,6 +7576,14 @@ dir-glob@^3.0.1: dependencies: path-type "^4.0.0" +doctrine@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" + integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + doctrine@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" @@ -8501,7 +8646,7 @@ error@^7.0.0: dependencies: string-template "~0.2.1" -es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.4, es-abstract@^1.17.5: +es-abstract@^1.17.0, es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.4, es-abstract@^1.17.5: version "1.17.6" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.6.tgz#9142071707857b2cacc7b89ecb670316c3e2d52a" integrity sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw== @@ -8600,6 +8745,31 @@ eslint-config-prettier@^6.11.0: dependencies: get-stdin "^6.0.0" +eslint-import-resolver-node@^0.3.3: + version "0.3.4" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz#85ffa81942c25012d8231096ddf679c03042c717" + integrity sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA== + dependencies: + debug "^2.6.9" + resolve "^1.13.1" + +eslint-module-utils@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz#579ebd094f56af7797d19c9866c9c9486629bfa6" + integrity sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA== + dependencies: + debug "^2.6.9" + pkg-dir "^2.0.0" + +eslint-plugin-deprecation@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-deprecation/-/eslint-plugin-deprecation-1.1.0.tgz#46793ebbec9555d167d59c851ae3da0a21532189" + integrity sha512-+oDa6JbdZXyh7Bx2zx7VoDFZvFnV1pZVPVo/bEGVkuXlLih/evX0LQG2/nSuNg83CmwZTcAFZXXpLgsX4ctIDQ== + dependencies: + "@typescript-eslint/experimental-utils" "^2.19.2 || ^3.0.0" + tslib "^1.10.0" + tsutils "^3.0.0" + eslint-plugin-ember@^8.6.0: version "8.9.2" resolved "https://registry.yarnpkg.com/eslint-plugin-ember/-/eslint-plugin-ember-8.9.2.tgz#064f2ca391958806885356d85d71962b3a69e665" @@ -8618,6 +8788,25 @@ eslint-plugin-es@^3.0.0: eslint-utils "^2.0.0" regexpp "^3.0.0" +eslint-plugin-import@^2.22.0: + version "2.22.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.22.0.tgz#92f7736fe1fde3e2de77623c838dd992ff5ffb7e" + integrity sha512-66Fpf1Ln6aIS5Gr/55ts19eUuoDhAbZgnr6UxK5hbDx6l/QgQgx61AePq+BV4PP2uXQFClgMVzep5zZ94qqsxg== + dependencies: + array-includes "^3.1.1" + array.prototype.flat "^1.2.3" + contains-path "^0.1.0" + debug "^2.6.9" + doctrine "1.5.0" + eslint-import-resolver-node "^0.3.3" + eslint-module-utils "^2.6.0" + has "^1.0.3" + minimatch "^3.0.4" + object.values "^1.1.1" + read-pkg-up "^2.0.0" + resolve "^1.17.0" + tsconfig-paths "^3.9.0" + eslint-plugin-jsdoc@^30.0.3: version "30.0.3" resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-30.0.3.tgz#358896c8114ccbee765774b16f64fd7c952309b1" @@ -8646,6 +8835,11 @@ eslint-plugin-node@^11.1.0: "eslint-plugin-sentry-sdk@file:./eslint-plugin-sentry-sdk": version "0.0.1" +eslint-plugin-simple-import-sort@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-5.0.3.tgz#9ae258ddada6efffc55e47a134afbd279eb31fc6" + integrity sha512-1rf3AWiHeWNCQdAq0iXNnlccnH1UDnelGgrPbjBBHE8d2hXVtOudcmy0vTF4hri3iJ0MKz8jBhmH6lJ0ZWZLHQ== + eslint-scope@^3.7.1: version "3.7.3" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.3.tgz#bb507200d3d17f60247636160b4826284b108535" @@ -11407,6 +11601,11 @@ is-stream@^2.0.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== +is-string@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" + integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== + is-svg@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-3.0.0.tgz#9321dbd29c212e5ca99c4fa9794c714bcafa2f75" @@ -12728,6 +12927,16 @@ load-json-file@^1.0.0: pinkie-promise "^2.0.0" strip-bom "^2.0.0" +load-json-file@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" + integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + strip-bom "^3.0.0" + load-json-file@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" @@ -14411,7 +14620,7 @@ object.pick@^1.3.0: dependencies: isobject "^3.0.1" -object.values@^1.1.0: +object.values@^1.1.0, object.values@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.1.tgz#68a99ecde356b7e9295a3c5e0ce31dc8c953de5e" integrity sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA== @@ -15005,7 +15214,7 @@ path-to-regexp@^1.5.3, path-to-regexp@^1.7.0: dependencies: isarray "0.0.1" -path-type@2.0.0: +path-type@2.0.0, path-type@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= @@ -16004,6 +16213,14 @@ read-pkg-up@^1.0.1: find-up "^1.0.0" read-pkg "^1.0.0" +read-pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" + integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= + dependencies: + find-up "^2.0.0" + read-pkg "^2.0.0" + read-pkg-up@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" @@ -16038,6 +16255,15 @@ read-pkg@^1.0.0: normalize-package-data "^2.3.2" path-type "^1.0.0" +read-pkg@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" + integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= + dependencies: + load-json-file "^2.0.0" + normalize-package-data "^2.3.2" + path-type "^2.0.0" + read-pkg@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" @@ -18521,6 +18747,16 @@ ts-pnp@^1.1.6: resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw== +tsconfig-paths@^3.9.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz#098547a6c4448807e8fcb8eae081064ee9a3c90b" + integrity sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw== + dependencies: + "@types/json5" "^0.0.29" + json5 "^1.0.1" + minimist "^1.2.0" + strip-bom "^3.0.0" + tslib@1.9.3: version "1.9.3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" @@ -18531,6 +18767,11 @@ tslib@^1.10.0, tslib@^1.7.1, tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1. resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043" integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q== +tslib@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.1.tgz#410eb0d113e5b6356490eec749603725b021b43e" + integrity sha512-SgIkNheinmEBgx1IUNirK0TUD4X9yjjBRTqqjggWCU3pUEqIk3/Uwl3yRixYKT6WjQuGiwDv4NomL3wqRCj+CQ== + tslint-config-prettier@^1.18.0: version "1.18.0" resolved "https://registry.yarnpkg.com/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz#75f140bde947d35d8f0d238e0ebf809d64592c37" @@ -18576,6 +18817,25 @@ tslint@5.16.0: tslib "^1.8.0" tsutils "^2.29.0" +tslint@^5.16.0: + version "5.20.1" + resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.20.1.tgz#e401e8aeda0152bc44dd07e614034f3f80c67b7d" + integrity sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg== + dependencies: + "@babel/code-frame" "^7.0.0" + builtin-modules "^1.1.1" + chalk "^2.3.0" + commander "^2.12.1" + diff "^4.0.1" + glob "^7.1.1" + js-yaml "^3.13.1" + minimatch "^3.0.4" + mkdirp "^0.5.1" + resolve "^1.3.2" + semver "^5.3.0" + tslib "^1.8.0" + tsutils "^2.29.0" + tsutils@^2.29.0: version "2.29.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99" @@ -18583,7 +18843,7 @@ tsutils@^2.29.0: dependencies: tslib "^1.8.1" -tsutils@^3.17.1, tsutils@^3.5.0: +tsutils@^3.0.0, tsutils@^3.17.1, tsutils@^3.5.0: version "3.17.1" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g== @@ -18725,7 +18985,7 @@ typescript@3.4.5: resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.4.5.tgz#2d2618d10bb566572b8d7aad5180d84257d70a99" integrity sha512-YycBxUb49UUhdNMU5aJ7z5Ej2XGmaIBL0x34vZ82fn3hGvD+bgrMrVDpatgz2f7YxUMJxMkbWxJZeAvDxVe7Vw== -typescript@^3.9.7: +typescript@^3.5.1, typescript@^3.9.7: version "3.9.7" resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.7.tgz#98d600a5ebdc38f40cb277522f12dc800e9e25fa" integrity sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==