From 07c31ef2b40df2a5a2fe39af79feb07073ce2108 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ole=C5=9B?= Date: Sat, 16 May 2020 17:32:06 +0200 Subject: [PATCH 01/29] chore: update semantic-release configuration (#410) Release new patch versions for "refactor" and "docs" commits. --- release.config.js | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/release.config.js b/release.config.js index b65123d8..c881cc04 100644 --- a/release.config.js +++ b/release.config.js @@ -7,7 +7,21 @@ module.exports = { } ], plugins: [ - '@semantic-release/commit-analyzer', + [ + '@semantic-release/commit-analyzer', + { + preset: 'angular', + releaseRules: [ + { breaking: true, release: 'major' }, + { revert: true, release: 'patch' }, + { type: 'feat', release: 'minor' }, + { type: 'fix', release: 'patch' }, + { type: 'perf', release: 'patch' }, + { type: 'refactor', release: 'patch' }, + { type: 'docs', release: 'patch' } + ] + } + ], '@semantic-release/release-notes-generator', '@semantic-release/npm', '@semantic-release/github' From 5bdc6433e0f30ffb3d331c5b1464f301a1ff5413 Mon Sep 17 00:00:00 2001 From: andyrooger <420834+andyrooger@users.noreply.github.com> Date: Sat, 16 May 2020 16:58:43 +0100 Subject: [PATCH 02/29] refactor(dependency): update babel-code-frame to @babel/code-frame (#409) Update code-frame dependency from v6 to v7 so that we can drop the chalk v1 dependency. Closes #408 --- README.md | 2 +- package.json | 4 ++-- src/formatter/CodeframeFormatter.ts | 15 +++++++++------ yarn.lock | 30 +++++++++++++++++++++++++---- 4 files changed, 38 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 5b4d7772..3105eb1a 100644 --- a/README.md +++ b/README.md @@ -147,7 +147,7 @@ new ForkTsCheckerWebpackPlugin({ (see `src/issue/` and `src/formatter/` for API reference). - **formatterOptions** `object`: - Options passed to formatters (currently only `codeframe` - see [available options](https://www.npmjs.com/package/babel-code-frame#options)) + Options passed to formatters (currently only `codeframe` - see [available options](https://babeljs.io/docs/en/next/babel-code-frame.html#options)) - **silent** `boolean`: If `true`, logger will not be used. Default: `false`. diff --git a/package.json b/package.json index 44dc0da4..63b769d4 100644 --- a/package.json +++ b/package.json @@ -74,7 +74,7 @@ } }, "dependencies": { - "babel-code-frame": "^6.22.0", + "@babel/code-frame": "^7.5.5", "chalk": "^2.4.1", "micromatch": "^3.1.10", "minimatch": "^3.0.4", @@ -84,7 +84,7 @@ }, "devDependencies": { "@commitlint/config-conventional": "^7.5.0", - "@types/babel-code-frame": "^6.20.1", + "@types/babel__code-frame": "^7.0.1", "@types/jest": "^24.0.11", "@types/lodash": "^4.14.134", "@types/micromatch": "^3.1.0", diff --git a/src/formatter/CodeframeFormatter.ts b/src/formatter/CodeframeFormatter.ts index 98e2a14e..6ab34d43 100644 --- a/src/formatter/CodeframeFormatter.ts +++ b/src/formatter/CodeframeFormatter.ts @@ -6,7 +6,7 @@ import { fileExistsSync } from '../FsHelper'; import { IssueSeverity, IssueOrigin } from '../issue'; import { Formatter } from './Formatter'; import { createInternalFormatter } from './InternalFormatter'; -import codeFrame from 'babel-code-frame'; +import { codeFrameColumns } from '@babel/code-frame'; interface CodeFrameFormatterOptions { /** Syntax highlight the code as JavaScript for terminals. default: false */ @@ -45,12 +45,15 @@ function createCodeframeFormatter( let frame = ''; if (source) { - frame = codeFrame( + frame = codeFrameColumns( source, - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - issue.line!, // Assertion: `codeFrame` allows passing undefined, typings are incorrect - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - issue.character!, + { + start: { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + line: issue.line!, // Assertion: `codeFrame` allows passing undefined, typings are incorrect + column: issue.character + } + }, { highlightCode: true, ...(options || {}) diff --git a/yarn.lock b/yarn.lock index 2c7d0cbd..6a0803db 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8,6 +8,13 @@ dependencies: "@babel/highlight" "^7.0.0" +"@babel/code-frame@^7.5.5": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e" + integrity sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g== + dependencies: + "@babel/highlight" "^7.8.3" + "@babel/core@^7.1.0": version "7.4.4" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.4.4.tgz#84055750b05fcd50f9915a826b44fa347a825250" @@ -67,6 +74,11 @@ dependencies: "@babel/types" "^7.4.4" +"@babel/helper-validator-identifier@^7.9.0": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz#90977a8e6fbf6b431a7dc31752eee233bf052d80" + integrity sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g== + "@babel/helpers@^7.4.4": version "7.4.4" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.4.4.tgz#868b0ef59c1dd4e78744562d5ce1b59c89f2f2a5" @@ -84,6 +96,15 @@ esutils "^2.0.2" js-tokens "^4.0.0" +"@babel/highlight@^7.8.3": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.9.0.tgz#4e9b45ccb82b79607271b2979ad82c7b68163079" + integrity sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ== + dependencies: + "@babel/helper-validator-identifier" "^7.9.0" + chalk "^2.0.0" + js-tokens "^4.0.0" + "@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.4": version "7.4.4" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.4.4.tgz#5977129431b8fe33471730d255ce8654ae1250b6" @@ -444,9 +465,10 @@ version "1.3.0" resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.0.tgz#d1d55958d1fccc5527d4aba29fc9c4b942f563ff" -"@types/babel-code-frame@^6.20.1": - version "6.20.1" - resolved "https://registry.yarnpkg.com/@types/babel-code-frame/-/babel-code-frame-6.20.1.tgz#e79a40ea81435034df7b46b5e32e8ed638aea4dd" +"@types/babel__code-frame@^7.0.1": + version "7.0.1" + resolved "https://registry.yarnpkg.com/@types/babel__code-frame/-/babel__code-frame-7.0.1.tgz#baf2529c4abbfb5e4008c845efcfe39a187e2f99" + integrity sha512-FFfbQozKxYmOnCKFYV+EQprjBI7u2yaNc2ly/K9AhzyC8MzXtCtSRqptpw+HUJxhwCOo5mLwf1ATmzyhOaVbDg== "@types/babel__core@^7.1.0": version "7.1.1" @@ -1137,7 +1159,7 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== -babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: +babel-code-frame@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" dependencies: From 3a369ef1d5ceb01f1c38f92dd1ee7898a56b519a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ole=C5=9B?= Date: Thu, 2 Jan 2020 18:39:50 +0100 Subject: [PATCH 03/29] refactor: make CancellationToken independent from TypeScript MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BREAKING CHANGE: ๐Ÿงจ Removed `throwIfCancellationRequested` method from the CancellationToken passed in the `cancel` hook --- package.json | 1 + src/ApiIncrementalChecker.ts | 7 +- src/CancellationToken.ts | 85 ---------- src/FsHelper.ts | 15 +- src/IncrementalChecker.ts | 45 ++++-- src/IncrementalCheckerInterface.ts | 2 +- src/RpcTypes.ts | 4 +- src/cancellation/CancellationToken.ts | 7 + src/cancellation/CancelledError.ts | 9 ++ .../FileBasedCancellationToken.ts | 78 ++++++++++ src/cancellation/index.ts | 5 + .../typescript/TypeScriptCancellationToken.ts | 31 ++++ src/cancellation/typescript/index.ts | 1 + src/formatter/CodeframeFormatter.ts | 3 +- src/index.ts | 10 +- src/service.ts | 10 +- test/unit/CancellationToken.spec.ts | 145 ------------------ test/unit/cancellation/CancelledError.spec.ts | 16 ++ .../FileBasedCancellationToken.spec.ts | 108 +++++++++++++ .../TypeScriptCancellationToken.spec.ts | 61 ++++++++ tsconfig.json | 1 + yarn.lock | 10 +- 22 files changed, 379 insertions(+), 275 deletions(-) delete mode 100644 src/CancellationToken.ts create mode 100644 src/cancellation/CancellationToken.ts create mode 100644 src/cancellation/CancelledError.ts create mode 100644 src/cancellation/FileBasedCancellationToken.ts create mode 100644 src/cancellation/index.ts create mode 100644 src/cancellation/typescript/TypeScriptCancellationToken.ts create mode 100644 src/cancellation/typescript/index.ts delete mode 100644 test/unit/CancellationToken.spec.ts create mode 100644 test/unit/cancellation/CancelledError.spec.ts create mode 100644 test/unit/cancellation/FileBasedCancellationToken.spec.ts create mode 100644 test/unit/cancellation/typescript/TypeScriptCancellationToken.spec.ts diff --git a/package.json b/package.json index 63b769d4..ed8a1a90 100644 --- a/package.json +++ b/package.json @@ -80,6 +80,7 @@ "minimatch": "^3.0.4", "semver": "^5.6.0", "tapable": "^1.0.0", + "tslib": "^1.10.0", "worker-rpc": "^0.1.0" }, "devDependencies": { diff --git a/src/ApiIncrementalChecker.ts b/src/ApiIncrementalChecker.ts index ab0eff66..fd45b0d8 100644 --- a/src/ApiIncrementalChecker.ts +++ b/src/ApiIncrementalChecker.ts @@ -3,7 +3,7 @@ import { IncrementalCheckerInterface, IncrementalCheckerParams } from './IncrementalCheckerInterface'; -import { CancellationToken } from './CancellationToken'; +import { CancellationToken, CancelledError } from './cancellation'; import { CompilerHost } from './CompilerHost'; import { createEslinter } from './createEslinter'; import { @@ -80,7 +80,10 @@ export class ApiIncrementalChecker implements IncrementalCheckerInterface { } for (const updatedFile of this.lastUpdatedFiles) { - cancellationToken.throwIfCancellationRequested(); + if (cancellationToken.isCancellationRequested()) { + throw new CancelledError(); + } + if (this.isFileExcluded(updatedFile)) { continue; } diff --git a/src/CancellationToken.ts b/src/CancellationToken.ts deleted file mode 100644 index e5a52bbe..00000000 --- a/src/CancellationToken.ts +++ /dev/null @@ -1,85 +0,0 @@ -import crypto from 'crypto'; -import * as fs from 'fs'; -import * as os from 'os'; -import * as path from 'path'; -import * as ts from 'typescript'; // Imported for types alone - -import { fileExistsSync } from './FsHelper'; - -export interface CancellationTokenData { - isCancelled: boolean; - cancellationFileName: string; -} - -export class CancellationToken { - private isCancelled: boolean; - private cancellationFileName: string; - private lastCancellationCheckTime: number; - constructor( - private typescript: typeof ts, - cancellationFileName?: string, - isCancelled?: boolean - ) { - this.isCancelled = !!isCancelled; - this.cancellationFileName = - cancellationFileName || crypto.randomBytes(64).toString('hex'); - this.lastCancellationCheckTime = 0; - } - - public static createFromJSON( - typescript: typeof ts, - json: CancellationTokenData - ) { - return new CancellationToken( - typescript, - json.cancellationFileName, - json.isCancelled - ); - } - - public toJSON() { - return { - cancellationFileName: this.cancellationFileName, - isCancelled: this.isCancelled - }; - } - - public getCancellationFilePath() { - return path.join(os.tmpdir(), this.cancellationFileName); - } - - public isCancellationRequested() { - if (this.isCancelled) { - return true; - } - - const time = Date.now(); - const duration = Math.abs(time - this.lastCancellationCheckTime); - - if (duration > 10) { - // check no more than once every 10 ms - this.lastCancellationCheckTime = time; - this.isCancelled = fileExistsSync(this.getCancellationFilePath()); - } - - return this.isCancelled; - } - - public throwIfCancellationRequested() { - if (this.isCancellationRequested()) { - throw new this.typescript.OperationCanceledException(); - } - } - - public requestCancellation() { - fs.writeFileSync(this.getCancellationFilePath(), ''); - this.isCancelled = true; - } - - public cleanupCancellation() { - if (this.isCancelled && fileExistsSync(this.getCancellationFilePath())) { - fs.unlinkSync(this.getCancellationFilePath()); - this.isCancelled = false; - } - } -} diff --git a/src/FsHelper.ts b/src/FsHelper.ts index 9edb2281..5e3d054f 100644 --- a/src/FsHelper.ts +++ b/src/FsHelper.ts @@ -1,22 +1,9 @@ import * as fs from 'fs'; -export function fileExistsSync(filePath: fs.PathLike) { - try { - fs.statSync(filePath); - } catch (err) { - if (err.code === 'ENOENT') { - return false; - } else { - throw err; - } - } - return true; -} - // eslint-disable-next-line @typescript-eslint/no-explicit-any export function throwIfIsInvalidSourceFileError(filepath: string, error: any) { if ( - fileExistsSync(filepath) && + fs.existsSync(filepath) && // check the error type due to file system lag !(error instanceof Error) && !(error.constructor.name === 'FatalError') && diff --git a/src/IncrementalChecker.ts b/src/IncrementalChecker.ts index 1a27c5e5..64669dd9 100644 --- a/src/IncrementalChecker.ts +++ b/src/IncrementalChecker.ts @@ -3,7 +3,11 @@ import * as path from 'path'; import * as ts from 'typescript'; // Imported for types alone; actual requires take place in methods below import { FilesRegister } from './FilesRegister'; -import { CancellationToken } from './CancellationToken'; +import { + CancellationToken, + CancelledError, + TypeScriptCancellationToken +} from './cancellation'; import { ResolveModuleName, ResolveTypeReferenceDirective, @@ -228,22 +232,33 @@ export class IncrementalChecker implements IncrementalCheckerInterface { const tsDiagnostics: ts.Diagnostic[] = []; // select files to check (it's semantic check - we have to include all files :/) const filesToCheck = program.getSourceFiles(); + const tsCancellationToken = cancellationToken + ? new TypeScriptCancellationToken(this.typescript, cancellationToken) + : undefined; filesToCheck.forEach(sourceFile => { - if (cancellationToken) { - cancellationToken.throwIfCancellationRequested(); + if (cancellationToken.isCancellationRequested()) { + throw new CancelledError(); } - const tsDiagnosticsToRegister: ReadonlyArray = this - .checkSyntacticErrors - ? program - .getSemanticDiagnostics(sourceFile, cancellationToken) - .concat( - program.getSyntacticDiagnostics(sourceFile, cancellationToken) - ) - : program.getSemanticDiagnostics(sourceFile, cancellationToken); - - tsDiagnostics.push(...tsDiagnosticsToRegister); + try { + const tsDiagnosticsToRegister: ReadonlyArray = this + .checkSyntacticErrors + ? program + .getSemanticDiagnostics(sourceFile, tsCancellationToken) + .concat( + program.getSyntacticDiagnostics(sourceFile, tsCancellationToken) + ) + : program.getSemanticDiagnostics(sourceFile, tsCancellationToken); + + tsDiagnostics.push(...tsDiagnosticsToRegister); + } catch (error) { + if (error instanceof this.typescript.OperationCanceledException) { + throw new CancelledError(); + } + + throw error; + } }); return createIssuesFromTsDiagnostics(tsDiagnostics, this.typescript); @@ -263,7 +278,9 @@ export class IncrementalChecker implements IncrementalCheckerInterface { const currentEsLintErrors = new Map(); filesToLint.forEach(fileName => { - cancellationToken.throwIfCancellationRequested(); + if (cancellationToken.isCancellationRequested()) { + throw new CancelledError(); + } // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const report = this.eslinter!.getReport(fileName); diff --git a/src/IncrementalCheckerInterface.ts b/src/IncrementalCheckerInterface.ts index 09f095d2..fa908227 100644 --- a/src/IncrementalCheckerInterface.ts +++ b/src/IncrementalCheckerInterface.ts @@ -1,6 +1,6 @@ import * as ts from 'typescript'; // imported for types alone -import { CancellationToken } from './CancellationToken'; +import { CancellationToken } from './cancellation'; import { ResolveTypeReferenceDirective, ResolveModuleName } from './resolution'; import { createEslinter } from './createEslinter'; import { Issue } from './issue'; diff --git a/src/RpcTypes.ts b/src/RpcTypes.ts index 86848a66..164b19de 100644 --- a/src/RpcTypes.ts +++ b/src/RpcTypes.ts @@ -1,8 +1,8 @@ -import { CancellationTokenData } from './CancellationToken'; +import { FileBasedCancellationTokenJSON } from './cancellation'; import { Message } from './Message'; export const RUN = 'run'; -export type RunPayload = CancellationTokenData; +export type RunPayload = FileBasedCancellationTokenJSON; export type RunResult = | Message // when run was cancelled via CancellationToken, undefined is returned diff --git a/src/cancellation/CancellationToken.ts b/src/cancellation/CancellationToken.ts new file mode 100644 index 00000000..e93b2a8d --- /dev/null +++ b/src/cancellation/CancellationToken.ts @@ -0,0 +1,7 @@ +interface CancellationToken { + isCancellationRequested(): boolean; + requestCancellation(): void; + cleanupCancellation(): void; +} + +export { CancellationToken }; diff --git a/src/cancellation/CancelledError.ts b/src/cancellation/CancelledError.ts new file mode 100644 index 00000000..43e9b71c --- /dev/null +++ b/src/cancellation/CancelledError.ts @@ -0,0 +1,9 @@ +class CancelledError extends Error { + constructor(message = 'Operation has been cancelled.') { + super(message); + + Object.setPrototypeOf(this, CancelledError.prototype); + } +} + +export { CancelledError }; diff --git a/src/cancellation/FileBasedCancellationToken.ts b/src/cancellation/FileBasedCancellationToken.ts new file mode 100644 index 00000000..c66d23b3 --- /dev/null +++ b/src/cancellation/FileBasedCancellationToken.ts @@ -0,0 +1,78 @@ +import * as crypto from 'crypto'; +import * as fs from 'fs'; +import * as os from 'os'; +import * as path from 'path'; + +import { CancellationToken } from './CancellationToken'; + +interface FileBasedCancellationTokenJSON { + readonly cancellationFilePath: string; + readonly isCancelled: boolean; +} + +class FileBasedCancellationToken implements CancellationToken { + private readonly cancellationFilePath: string; + private isCancelled: boolean; + private lastCancellationCheckTime: number; + + constructor( + cancellationFilePath = path.join( + os.tmpdir(), + crypto.randomBytes(20).toString('hex') + ), + isCancelled = false + ) { + this.cancellationFilePath = cancellationFilePath; + this.isCancelled = isCancelled; + this.lastCancellationCheckTime = 0; + } + + static createFromJSON(json: FileBasedCancellationTokenJSON) { + return new FileBasedCancellationToken( + json.cancellationFilePath, + json.isCancelled + ); + } + + toJSON(): FileBasedCancellationTokenJSON { + return { + cancellationFilePath: this.cancellationFilePath, + isCancelled: this.isCancelled + }; + } + + isCancellationRequested() { + if (this.isCancelled) { + return true; + } + + const time = Date.now(); + const duration = Math.abs(time - this.lastCancellationCheckTime); + + if (duration > 20) { + // check no more than once every 20ms + this.lastCancellationCheckTime = time; + this.isCancelled = fs.existsSync(this.cancellationFilePath); + } + + return this.isCancelled; + } + + requestCancellation() { + fs.writeFileSync(this.cancellationFilePath, ''); + this.isCancelled = true; + } + + cleanupCancellation() { + if (this.isCancelled && fs.existsSync(this.cancellationFilePath)) { + try { + fs.unlinkSync(this.cancellationFilePath); + } catch (error) { + // fail silently as the file is in the tmp directory + } + this.isCancelled = false; + } + } +} + +export { FileBasedCancellationToken, FileBasedCancellationTokenJSON }; diff --git a/src/cancellation/index.ts b/src/cancellation/index.ts new file mode 100644 index 00000000..75a03768 --- /dev/null +++ b/src/cancellation/index.ts @@ -0,0 +1,5 @@ +export * from './CancellationToken'; +export * from './FileBasedCancellationToken'; +export * from './CancelledError'; + +export * from './typescript'; diff --git a/src/cancellation/typescript/TypeScriptCancellationToken.ts b/src/cancellation/typescript/TypeScriptCancellationToken.ts new file mode 100644 index 00000000..4e18e656 --- /dev/null +++ b/src/cancellation/typescript/TypeScriptCancellationToken.ts @@ -0,0 +1,31 @@ +import * as ts from 'typescript'; + +import { CancellationToken } from '../CancellationToken'; + +class TypeScriptCancellationToken + implements CancellationToken, ts.CancellationToken { + constructor( + private readonly typescript: typeof ts, + private readonly token: CancellationToken + ) {} + + isCancellationRequested() { + return this.token.isCancellationRequested(); + } + + requestCancellation() { + return this.token.requestCancellation(); + } + + cleanupCancellation() { + return this.token.cleanupCancellation(); + } + + throwIfCancellationRequested() { + if (this.token.isCancellationRequested()) { + throw new this.typescript.OperationCanceledException(); + } + } +} + +export { TypeScriptCancellationToken }; diff --git a/src/cancellation/typescript/index.ts b/src/cancellation/typescript/index.ts new file mode 100644 index 00000000..45dc881a --- /dev/null +++ b/src/cancellation/typescript/index.ts @@ -0,0 +1 @@ +export * from './TypeScriptCancellationToken'; diff --git a/src/formatter/CodeframeFormatter.ts b/src/formatter/CodeframeFormatter.ts index 6ab34d43..cfeff8e6 100644 --- a/src/formatter/CodeframeFormatter.ts +++ b/src/formatter/CodeframeFormatter.ts @@ -2,7 +2,6 @@ import * as os from 'os'; import * as fs from 'fs'; import chalk from 'chalk'; -import { fileExistsSync } from '../FsHelper'; import { IssueSeverity, IssueOrigin } from '../issue'; import { Formatter } from './Formatter'; import { createInternalFormatter } from './InternalFormatter'; @@ -41,7 +40,7 @@ function createCodeframeFormatter( const file = issue.file; const source = - file && fileExistsSync(file) && fs.readFileSync(file, 'utf-8'); + file && fs.existsSync(file) && fs.readFileSync(file, 'utf-8'); let frame = ''; if (source) { diff --git a/src/index.ts b/src/index.ts index bead3ddc..40b83a5f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,6 @@ import * as path from 'path'; import * as childProcess from 'child_process'; +import * as fs from 'fs'; import * as webpack from 'webpack'; import * as ts from 'typescript'; import * as semver from 'semver'; @@ -7,7 +8,7 @@ import micromatch from 'micromatch'; import chalk from 'chalk'; import { RpcProvider } from 'worker-rpc'; -import { CancellationToken } from './CancellationToken'; +import { FileBasedCancellationToken } from './cancellation'; import { Formatter, createFormatter, @@ -15,7 +16,6 @@ import { FormatterType, FormatterOptions } from './formatter'; -import { fileExistsSync } from './FsHelper'; import { Message } from './Message'; import { getForkTsCheckerWebpackPluginHooks } from './hooks'; import { RUN, RunPayload, RunResult } from './RpcTypes'; @@ -102,7 +102,7 @@ class ForkTsCheckerWebpackPlugin { private compiler: any = undefined; private started: [number, number] | undefined = undefined; private elapsed: [number, number] | undefined = undefined; - private cancellationToken: CancellationToken | undefined = undefined; + private cancellationToken: FileBasedCancellationToken | undefined = undefined; private isWatching = false; private checkDone = false; @@ -280,7 +280,7 @@ class ForkTsCheckerWebpackPlugin { this.tsconfigPath = this.computeContextPath(this.tsconfig); // validate config - const tsconfigOk = fileExistsSync(this.tsconfigPath); + const tsconfigOk = fs.existsSync(this.tsconfigPath); // validate logger if (this.logger) { @@ -371,7 +371,7 @@ class ForkTsCheckerWebpackPlugin { this.started = process.hrtime(); // create new token for current job - this.cancellationToken = new CancellationToken(this.typescript); + this.cancellationToken = new FileBasedCancellationToken(); if (!this.service || !this.service.connected) { this.spawnService(); } diff --git a/src/service.ts b/src/service.ts index d979e221..2781e18e 100644 --- a/src/service.ts +++ b/src/service.ts @@ -1,7 +1,11 @@ import * as ts from 'typescript'; // import for types alone import { IncrementalChecker } from './IncrementalChecker'; -import { CancellationToken } from './CancellationToken'; +import { + CancellationToken, + CancelledError, + FileBasedCancellationToken +} from './cancellation'; import { IncrementalCheckerInterface, IncrementalCheckerParams @@ -87,7 +91,7 @@ async function run(cancellationToken: CancellationToken) { lints.push(...(await checker.getEsLintIssues(cancellationToken))); } } catch (error) { - if (error instanceof typescript.OperationCanceledException) { + if (error instanceof CancelledError) { return undefined; } @@ -106,7 +110,7 @@ async function run(cancellationToken: CancellationToken) { rpc.registerRpcHandler(RUN, message => typeof message !== 'undefined' - ? run(CancellationToken.createFromJSON(typescript, message)) + ? run(FileBasedCancellationToken.createFromJSON(message)) : undefined ); diff --git a/test/unit/CancellationToken.spec.ts b/test/unit/CancellationToken.spec.ts deleted file mode 100644 index 8db29546..00000000 --- a/test/unit/CancellationToken.spec.ts +++ /dev/null @@ -1,145 +0,0 @@ -import * as os from 'os'; -import * as ts from 'typescript'; -import mockFs from 'mock-fs'; -import { CancellationToken } from '../../lib/CancellationToken'; -import { fileExistsSync } from '../../lib/FsHelper'; - -describe('[UNIT] CancellationToken', () => { - beforeEach(() => { - mockFs({ - [os.tmpdir()]: mockFs.directory() - }); - }); - - afterEach(() => { - mockFs.restore(); - }); - - it('should create valid cancellation token', () => { - const tokenA = new CancellationToken(require('typescript')); - expect(tokenA.isCancellationRequested()).toBe(false); - - const tokenB = new CancellationToken( - require('typescript'), - 'FA#FERgSERgRT$rA$#rA#Ea@RweFRgERG' - ); - expect(tokenB.isCancellationRequested()).toBe(false); - - const tokenC = new CancellationToken( - require('typescript'), - 'GFERWgEgeF#R2erwreWrweWER', - false - ); - expect(tokenC.isCancellationRequested()).toBe(false); - - const tokenD = new CancellationToken( - require('typescript'), - 'REGg$#R2$#@r@#R$#T43T$#t43t', - true - ); - expect(tokenD.isCancellationRequested()).toBe(true); - }); - - it('should serialize to JSON', () => { - const tokenA = new CancellationToken(require('typescript')); - const json = JSON.stringify(tokenA); - - expect(typeof json).toBe('string'); - expect(function() { - JSON.parse(json); - }).not.toThrowError(Error); - expect(typeof JSON.parse(json)).toBe('object'); - - const tokenB = CancellationToken.createFromJSON( - // eslint-disable-next-line @typescript-eslint/no-var-requires - require('typescript'), - JSON.parse(json) - ); - expect(tokenA.getCancellationFilePath()).toBe( - tokenB.getCancellationFilePath() - ); - expect(tokenA.isCancellationRequested()).toBe( - tokenB.isCancellationRequested() - ); - }); - - it('should generate path in os.tmpdir() directory', () => { - const tokenA = new CancellationToken(require('typescript')); - - expect(tokenA.getCancellationFilePath().indexOf(os.tmpdir())).toBe(0); - }); - - it('should throw ts.OperationCanceledException error on cancelled', () => { - const tokenA = new CancellationToken(require('typescript')); - expect(function() { - tokenA.throwIfCancellationRequested(); - }).not.toThrowError(); - - const tokenB = new CancellationToken( - require('typescript'), - 'rgeer#R23r$#T$3t#$t43', - true - ); - expect(function() { - tokenB.throwIfCancellationRequested(); - }).toThrow(ts.OperationCanceledException); - }); - - it('should write file in filesystem on requestCancellation', () => { - const tokenA = new CancellationToken(require('typescript')); - tokenA.requestCancellation(); - - expect(tokenA.isCancellationRequested()).toBe(true); - expect(fileExistsSync(tokenA.getCancellationFilePath())).toBe(true); - }); - - it('should cleanup file on cleanupCancellation', () => { - const tokenA = new CancellationToken(require('typescript')); - tokenA.requestCancellation(); - tokenA.cleanupCancellation(); - - expect(tokenA.isCancellationRequested()).toBe(false); - expect(fileExistsSync(tokenA.getCancellationFilePath())).toBe(false); - - // make sure we can call it as many times as we want to - expect(function() { - tokenA.cleanupCancellation(); - }).not.toThrowError(Error); - expect(tokenA.isCancellationRequested()).toBe(false); - }); - - it('should not throw error on cleanupCancellation with no file exists', () => { - const tokenA = new CancellationToken( - require('typescript'), - 'some_file_that_doesnt_exists', - true - ); - - expect(function() { - tokenA.cleanupCancellation(); - }).not.toThrowError(); - expect(function() { - tokenA.cleanupCancellation(); - }).not.toThrowError(); - }); - - it('should throttle check for 10 ms', done => { - const tokenA = new CancellationToken(require('typescript')); - const tokenB = CancellationToken.createFromJSON( - // eslint-disable-next-line @typescript-eslint/no-var-requires - require('typescript'), - tokenA.toJSON() - ); - - expect(tokenA.isCancellationRequested()).toBe(false); - expect(tokenB.isCancellationRequested()).toBe(false); - - tokenA.requestCancellation(); - expect(tokenA.isCancellationRequested()).toBe(true); - - setTimeout(function() { - expect(tokenB.isCancellationRequested()).toBe(true); - done(); - }, 20); - }); -}); diff --git a/test/unit/cancellation/CancelledError.spec.ts b/test/unit/cancellation/CancelledError.spec.ts new file mode 100644 index 00000000..e261bab7 --- /dev/null +++ b/test/unit/cancellation/CancelledError.spec.ts @@ -0,0 +1,16 @@ +import { CancelledError } from '../../../lib/cancellation'; + +describe('[UNIT] cancellation/CancelledError', () => { + it('defines CancelledError with default message', () => { + const error = new CancelledError(); + + expect(error).toBeInstanceOf(Error); + expect(error.message).toEqual('Operation has been cancelled.'); + }); + + it('allows to pass custom message', () => { + const error = new CancelledError('Fetching has been cancelled.'); + + expect(error.message).toEqual('Fetching has been cancelled.'); + }); +}); diff --git a/test/unit/cancellation/FileBasedCancellationToken.spec.ts b/test/unit/cancellation/FileBasedCancellationToken.spec.ts new file mode 100644 index 00000000..3ed37d46 --- /dev/null +++ b/test/unit/cancellation/FileBasedCancellationToken.spec.ts @@ -0,0 +1,108 @@ +import * as os from 'os'; +import * as path from 'path'; +import * as fs from 'fs'; +import mockFs from 'mock-fs'; + +import { FileBasedCancellationToken } from '../../../lib/cancellation'; + +describe('[UNIT] cancellation/FileBasedCancellationToken', () => { + beforeEach(() => { + mockFs({ + [os.tmpdir()]: mockFs.directory() + }); + }); + + afterEach(() => { + mockFs.restore(); + }); + + it('creates valid cancellation token', () => { + const tokenA = new FileBasedCancellationToken(); + expect(tokenA.isCancellationRequested()).toBe(false); + + const tokenB = new FileBasedCancellationToken( + path.join(os.tmpdir(), 'FA#FERgSERgRT$rA$#rA#Ea@RweFRgERG') + ); + expect(tokenB.isCancellationRequested()).toBe(false); + + const tokenC = new FileBasedCancellationToken( + path.join(os.tmpdir(), 'GFERWgEgeF#R2erwreWrweWER'), + false + ); + expect(tokenC.isCancellationRequested()).toBe(false); + + const tokenD = new FileBasedCancellationToken( + path.join(os.tmpdir(), 'REGg$#R2$#@r@#R$#T43T$#t43t'), + true + ); + expect(tokenD.isCancellationRequested()).toBe(true); + }); + + it('serializes to JSON', () => { + const tokenA = new FileBasedCancellationToken(); + const json = JSON.stringify(tokenA); + + expect(typeof json).toBe('string'); + expect(() => JSON.parse(json)).not.toThrowError(); + expect(typeof JSON.parse(json)).toBe('object'); + + const tokenB = FileBasedCancellationToken.createFromJSON(JSON.parse(json)); + expect(tokenA.isCancellationRequested()).toBe( + tokenB.isCancellationRequested() + ); + }); + + it('generates path in os.tmpdir() directory', () => { + const tokenA = new FileBasedCancellationToken(); + + expect(tokenA.toJSON().cancellationFilePath.indexOf(os.tmpdir())).toBe(0); + }); + + it('writes file in filesystem on requestCancellation', () => { + const tokenA = new FileBasedCancellationToken(); + tokenA.requestCancellation(); + + expect(tokenA.isCancellationRequested()).toBe(true); + expect(fs.existsSync(tokenA.toJSON().cancellationFilePath)).toBe(true); + }); + + it('cleanups file on cleanupCancellation', () => { + const tokenA = new FileBasedCancellationToken(); + tokenA.requestCancellation(); + tokenA.cleanupCancellation(); + + expect(tokenA.isCancellationRequested()).toBe(false); + expect(fs.existsSync(tokenA.toJSON().cancellationFilePath)).toBe(false); + + // make sure we can call it as many times as we want to + expect(() => tokenA.cleanupCancellation()).not.toThrowError(); + expect(tokenA.isCancellationRequested()).toBe(false); + }); + + it('not throws an error on cleanupCancellation with no file exists', () => { + const tokenA = new FileBasedCancellationToken( + 'some_file_that_doesnt_exists', + true + ); + + expect(() => tokenA.cleanupCancellation()).not.toThrowError(); + expect(() => tokenA.cleanupCancellation()).not.toThrowError(); + }); + + it('throttles check for 20ms', done => { + const tokenA = new FileBasedCancellationToken(); + const tokenB = FileBasedCancellationToken.createFromJSON(tokenA.toJSON()); + + expect(tokenA.isCancellationRequested()).toBe(false); + expect(tokenB.isCancellationRequested()).toBe(false); + + tokenA.requestCancellation(); + expect(tokenB.isCancellationRequested()).toBe(false); + expect(tokenA.isCancellationRequested()).toBe(true); + + setTimeout(() => { + expect(tokenB.isCancellationRequested()).toBe(true); + done(); + }, 50); + }); +}); diff --git a/test/unit/cancellation/typescript/TypeScriptCancellationToken.spec.ts b/test/unit/cancellation/typescript/TypeScriptCancellationToken.spec.ts new file mode 100644 index 00000000..3bf2670d --- /dev/null +++ b/test/unit/cancellation/typescript/TypeScriptCancellationToken.spec.ts @@ -0,0 +1,61 @@ +import { + CancellationToken, + TypeScriptCancellationToken +} from '../../../../lib/cancellation'; +import * as ts from 'typescript'; + +class OperationCanceledException {} + +describe('[UNIT] cancellation/typescript/FileBasedCancellationToken', () => { + let cancellationRequested: boolean; + let typescript: typeof ts; + let sourceToken: CancellationToken; + let token: TypeScriptCancellationToken; + + beforeEach(() => { + cancellationRequested = true; + sourceToken = { + isCancellationRequested: jest.fn(() => cancellationRequested), + requestCancellation: jest.fn(), + cleanupCancellation: jest.fn() + }; + typescript = ({ + OperationCanceledException + } as unknown) as typeof ts; + token = new TypeScriptCancellationToken(typescript, sourceToken); + }); + + it('proxies CancellationToken methods', () => { + cancellationRequested = false; + expect(token.isCancellationRequested()).toEqual(false); + expect(sourceToken.isCancellationRequested).toHaveBeenCalledTimes(1); + expect(sourceToken.requestCancellation).toHaveBeenCalledTimes(0); + expect(sourceToken.cleanupCancellation).toHaveBeenCalledTimes(0); + + cancellationRequested = true; + expect(token.isCancellationRequested()).toEqual(true); + expect(sourceToken.isCancellationRequested).toHaveBeenCalledTimes(2); + expect(sourceToken.requestCancellation).toHaveBeenCalledTimes(0); + expect(sourceToken.cleanupCancellation).toHaveBeenCalledTimes(0); + + expect(token.requestCancellation()).toBeUndefined(); + expect(sourceToken.isCancellationRequested).toHaveBeenCalledTimes(2); + expect(sourceToken.requestCancellation).toHaveBeenCalledTimes(1); + expect(sourceToken.cleanupCancellation).toHaveBeenCalledTimes(0); + + expect(token.cleanupCancellation()).toBeUndefined(); + expect(sourceToken.isCancellationRequested).toHaveBeenCalledTimes(2); + expect(sourceToken.requestCancellation).toHaveBeenCalledTimes(1); + expect(sourceToken.cleanupCancellation).toHaveBeenCalledTimes(1); + }); + + it('throws a TypeScript specific error', () => { + cancellationRequested = false; + expect(() => token.throwIfCancellationRequested()).not.toThrowError(); + + cancellationRequested = true; + expect(() => token.throwIfCancellationRequested()).toThrowError( + typescript.OperationCanceledException + ); + }); +}); diff --git a/tsconfig.json b/tsconfig.json index 6d7ccf34..24f93451 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,6 +5,7 @@ "skipLibCheck": true, "strict": true, "lib": ["es2015"], + "importHelpers": true, "module": "commonjs", "moduleResolution": "node", "sourceMap": true diff --git a/yarn.lock b/yarn.lock index 6a0803db..505fb550 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4742,8 +4742,9 @@ mocha@^6.0.2: yargs-unparser "1.5.0" mock-fs@^4.3.0: - version "4.7.0" - resolved "https://registry.yarnpkg.com/mock-fs/-/mock-fs-4.7.0.tgz#9f17e219cacb8094f4010e0a8c38589e2b33c299" + version "4.10.4" + resolved "https://registry.yarnpkg.com/mock-fs/-/mock-fs-4.10.4.tgz#4eaa3d6f7da2f44e1f3dd6b462cbbcb7b082e3d4" + integrity sha512-gDfZDLaPIvtOusbusLinfx6YSe2YpQsDT8qdP41P47dQ/NQggtkHukz7hwqgt8QvMBmAv+Z6DGmXPyb5BWX2nQ== mock-require@^3.0.2: version "3.0.2" @@ -6923,6 +6924,11 @@ ts-loader@^5.0.0: micromatch "^3.1.4" semver "^5.0.1" +tslib@^1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" + integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== + tslib@^1.8.1, tslib@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" From 2a356d2a2059b646b19499848ddd20c472f37fe8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ole=C5=9B?= Date: Mon, 3 Feb 2020 23:38:03 +0100 Subject: [PATCH 04/29] feat: initial implementation of the new architecture --- .DS_Store | Bin 0 -> 10244 bytes .github/.DS_Store | Bin 0 -> 6148 bytes .prettierrc | 5 +- package.json | 94 +- src/ApiIncrementalChecker.ts | 103 - src/CompilerHost.ts | 442 -- src/FilesRegister.ts | 76 - src/ForkTsCheckerWebpackPlugin.ts | 65 + ...ForkTsCheckerWebpackPluginConfiguration.ts | 41 + src/ForkTsCheckerWebpackPluginOptions.json | 265 + src/ForkTsCheckerWebpackPluginOptions.ts | 16 + src/ForkTsCheckerWebpackPluginState.ts | 19 + src/FsHelper.ts | 15 - src/IncrementalChecker.ts | 317 - src/IncrementalCheckerInterface.ts | 28 - src/LinkedList.ts | 107 - src/Message.ts | 6 - src/RpcTypes.ts | 9 - src/VueProgram.ts | 365 -- src/cancellation/CancellationToken.ts | 7 - src/cancellation/CancelledError.ts | 9 - .../FileBasedCancellationToken.ts | 78 - src/cancellation/index.ts | 5 - .../typescript/TypeScriptCancellationToken.ts | 31 - src/cancellation/typescript/index.ts | 1 - src/createEslinter.ts | 38 - src/error/OperationCancelledError.ts | 11 + .../EsLintReporterConfiguration.ts | 28 + src/eslint-reporter/EsLintReporterOptions.ts | 9 + src/eslint-reporter/assertEsLintSupport.ts | 31 + src/eslint-reporter/issue/EsLintIssue.ts | 40 + .../reporter/EsLintReporter.ts | 60 + .../reporter/EsLintReporterRpcClient.ts | 17 + .../reporter/EsLintReporterRpcService.ts | 12 + .../reporter/EsLintReporterState.ts | 17 + src/eslint-reporter/types/eslint.ts | 31 + src/formatter/BasicFormatter.ts | 10 + src/formatter/CodeframeFormatter.ts | 77 +- src/formatter/DefaultFormatter.ts | 35 - src/formatter/FormatterConfiguration.ts | 18 + src/formatter/FormatterFactory.ts | 65 +- src/formatter/FormatterOptions.ts | 10 + src/formatter/InternalFormatter.ts | 34 - src/formatter/RawFormatter.ts | 13 - src/formatter/WebpackFormatter.ts | 22 + src/formatter/index.ts | 4 +- src/hooks.ts | 42 - src/hooks/getDeletedFiles.ts | 9 + src/hooks/getReportProgress.ts | 8 + src/hooks/pluginHooks.ts | 58 + src/hooks/tapDoneToAsyncGetIssues.ts | 70 + src/hooks/tapEmitToGetIssues.ts | 69 + src/hooks/tapInvalidToUpdateState.ts | 20 + src/hooks/tapStartToConnectAndRunReporter.ts | 53 + src/hooks/tapStopToDisconnectReporter.ts | 46 + src/index.ts | 725 +-- src/issue/Issue.ts | 48 +- src/issue/IssueConfiguration.ts | 53 + src/issue/IssueLocation.ts | 23 + src/issue/IssueMatch.ts | 21 + src/issue/IssueOptions.ts | 11 + src/issue/IssueOrigin.ts | 28 - src/issue/IssuePosition.ts | 20 + src/issue/IssuePredicate.ts | 13 + src/issue/IssueSeverity.ts | 21 +- src/issue/IssueWebpackError.ts | 53 + src/issue/eslint/EsLintIssueFactory.ts | 65 - src/issue/eslint/FileAwareEsLintMessage.ts | 11 - src/issue/eslint/index.ts | 2 - src/issue/index.ts | 6 +- src/issue/internal/InternalIssueFactory.ts | 24 - src/issue/internal/index.ts | 1 - .../typescript/TypeScriptIssueFactory.ts | 54 - src/issue/typescript/index.ts | 1 - src/logger/Logger.ts | 7 + src/logger/LoggerConfiguration.ts | 21 + src/logger/LoggerFactory.ts | 29 + src/logger/LoggerOptions.ts | 9 + src/logger/PartialLogger.ts | 13 + src/logger/WebpackInfrastructureLogger.ts | 21 + src/patchTypescript.ts | 65 - src/reporter/AggregatedReporter.ts | 48 + src/reporter/FilesChange.ts | 39 + src/reporter/FilesState.ts | 30 + src/reporter/Report.ts | 5 + src/reporter/Reporter.ts | 8 + src/reporter/index.ts | 9 + .../reporter-rpc/ReporterRpcClient.ts | 54 + .../reporter-rpc/ReporterRpcProcedure.ts | 8 + .../reporter-rpc/ReporterRpcService.ts | 56 + src/resolution.ts | 58 - src/rpc/RpcClient.ts | 76 + src/rpc/RpcHost.ts | 8 + src/rpc/RpcMessage.ts | 98 + src/rpc/RpcMessageChannel.ts | 55 + src/rpc/RpcMessagePort.ts | 12 + src/rpc/RpcProcedure.ts | 15 + src/rpc/RpcService.ts | 78 + src/rpc/error/RpcMessagePortClosedError.ts | 9 + src/rpc/index.ts | 7 + .../RpcEventEmitterMessageChannel.ts | 33 + .../RpcEventEmitterMessagePort.ts | 30 + src/rpc/rpc-event-emitter/index.ts | 2 + src/rpc/rpc-ipc/ProcessLike.ts | 20 + src/rpc/rpc-ipc/RpcIpcMessageChannel.ts | 11 + src/rpc/rpc-ipc/RpcIpcMessagePort.ts | 109 + .../error/RpcIpcMessagePortClosedError.ts | 15 + src/rpc/rpc-ipc/index.ts | 2 + src/service.ts | 119 - src/tsconfig.json | 9 - src/types/vue-options.ts | 4 - src/types/vue-template-compiler.d.ts | 232 - .../TypeScriptDiagnosticsOptions.ts | 8 + .../TypeScriptReporterConfiguration.ts | 64 + .../TypeScriptReporterOptions.ts | 20 + .../assertTypeScriptSupport.ts | 46 + .../extension/TypeScriptEmbeddedExtension.ts | 152 + .../extension/TypeScriptExtension.ts | 31 + .../extension/pnp/TypeScriptPnpExtension.ts | 52 + .../TypeScriptPnpExtensionConfiguration.ts | 15 + .../pnp/TypeScriptPnpExtensionOptions.ts | 3 + .../extension/pnp/assertPnpSupport.ts | 12 + .../extension/vue/TypeScriptVueExtension.ts | 104 + .../TypeScriptVueExtensionConfiguration.ts | 18 + .../vue/TypeScriptVueExtensionOptions.ts | 8 + .../extension/vue/assertVueSupport.ts | 17 + .../vue/types/vue-template-compiler.d.ts | 30 + .../issue/TypeScriptIssueFactory.ts | 50 + .../reporter/ControlledWatchCompilerHost.ts | 181 + .../reporter/ControlledWatchHost.ts | 7 + .../ControlledWatchSolutionBuilderHost.ts | 107 + .../reporter/TypeScriptReporter.ts | 161 + .../reporter/TypeScriptReporterRpcClient.ts | 36 + .../reporter/TypeScriptReporterRpcService.ts | 12 + .../reporter/TypeScriptReporterState.ts | 28 + src/utils/array/flatten.ts | 5 + src/utils/array/intersect.ts | 5 + src/utils/array/substract.ts | 5 + src/utils/array/unique.ts | 5 + src/utils/async/isPending.ts | 8 + src/utils/async/wait.ts | 5 + src/utils/fs/isFileJustCreated.ts | 9 + test/.DS_Store | Bin 0 -> 6148 bytes test/fixtures/.DS_Store | Bin 0 -> 6148 bytes test/integration/helpers/rpc.js | 2 +- tsconfig.json | 13 +- yarn.lock | 5336 +++++++++-------- 147 files changed, 6318 insertions(+), 5902 deletions(-) create mode 100644 .DS_Store create mode 100644 .github/.DS_Store delete mode 100644 src/ApiIncrementalChecker.ts delete mode 100644 src/CompilerHost.ts delete mode 100644 src/FilesRegister.ts create mode 100644 src/ForkTsCheckerWebpackPlugin.ts create mode 100644 src/ForkTsCheckerWebpackPluginConfiguration.ts create mode 100644 src/ForkTsCheckerWebpackPluginOptions.json create mode 100644 src/ForkTsCheckerWebpackPluginOptions.ts create mode 100644 src/ForkTsCheckerWebpackPluginState.ts delete mode 100644 src/FsHelper.ts delete mode 100644 src/IncrementalChecker.ts delete mode 100644 src/IncrementalCheckerInterface.ts delete mode 100644 src/LinkedList.ts delete mode 100644 src/Message.ts delete mode 100644 src/RpcTypes.ts delete mode 100644 src/VueProgram.ts delete mode 100644 src/cancellation/CancellationToken.ts delete mode 100644 src/cancellation/CancelledError.ts delete mode 100644 src/cancellation/FileBasedCancellationToken.ts delete mode 100644 src/cancellation/index.ts delete mode 100644 src/cancellation/typescript/TypeScriptCancellationToken.ts delete mode 100644 src/cancellation/typescript/index.ts delete mode 100644 src/createEslinter.ts create mode 100644 src/error/OperationCancelledError.ts create mode 100644 src/eslint-reporter/EsLintReporterConfiguration.ts create mode 100644 src/eslint-reporter/EsLintReporterOptions.ts create mode 100644 src/eslint-reporter/assertEsLintSupport.ts create mode 100644 src/eslint-reporter/issue/EsLintIssue.ts create mode 100644 src/eslint-reporter/reporter/EsLintReporter.ts create mode 100644 src/eslint-reporter/reporter/EsLintReporterRpcClient.ts create mode 100644 src/eslint-reporter/reporter/EsLintReporterRpcService.ts create mode 100644 src/eslint-reporter/reporter/EsLintReporterState.ts create mode 100644 src/eslint-reporter/types/eslint.ts create mode 100644 src/formatter/BasicFormatter.ts delete mode 100644 src/formatter/DefaultFormatter.ts create mode 100644 src/formatter/FormatterConfiguration.ts create mode 100644 src/formatter/FormatterOptions.ts delete mode 100644 src/formatter/InternalFormatter.ts delete mode 100644 src/formatter/RawFormatter.ts create mode 100644 src/formatter/WebpackFormatter.ts delete mode 100644 src/hooks.ts create mode 100644 src/hooks/getDeletedFiles.ts create mode 100644 src/hooks/getReportProgress.ts create mode 100644 src/hooks/pluginHooks.ts create mode 100644 src/hooks/tapDoneToAsyncGetIssues.ts create mode 100644 src/hooks/tapEmitToGetIssues.ts create mode 100644 src/hooks/tapInvalidToUpdateState.ts create mode 100644 src/hooks/tapStartToConnectAndRunReporter.ts create mode 100644 src/hooks/tapStopToDisconnectReporter.ts create mode 100644 src/issue/IssueConfiguration.ts create mode 100644 src/issue/IssueLocation.ts create mode 100644 src/issue/IssueMatch.ts create mode 100644 src/issue/IssueOptions.ts delete mode 100644 src/issue/IssueOrigin.ts create mode 100644 src/issue/IssuePosition.ts create mode 100644 src/issue/IssuePredicate.ts create mode 100644 src/issue/IssueWebpackError.ts delete mode 100644 src/issue/eslint/EsLintIssueFactory.ts delete mode 100644 src/issue/eslint/FileAwareEsLintMessage.ts delete mode 100644 src/issue/eslint/index.ts delete mode 100644 src/issue/internal/InternalIssueFactory.ts delete mode 100644 src/issue/internal/index.ts delete mode 100644 src/issue/typescript/TypeScriptIssueFactory.ts delete mode 100644 src/issue/typescript/index.ts create mode 100644 src/logger/Logger.ts create mode 100644 src/logger/LoggerConfiguration.ts create mode 100644 src/logger/LoggerFactory.ts create mode 100644 src/logger/LoggerOptions.ts create mode 100644 src/logger/PartialLogger.ts create mode 100644 src/logger/WebpackInfrastructureLogger.ts delete mode 100644 src/patchTypescript.ts create mode 100644 src/reporter/AggregatedReporter.ts create mode 100644 src/reporter/FilesChange.ts create mode 100644 src/reporter/FilesState.ts create mode 100644 src/reporter/Report.ts create mode 100644 src/reporter/Reporter.ts create mode 100644 src/reporter/index.ts create mode 100644 src/reporter/reporter-rpc/ReporterRpcClient.ts create mode 100644 src/reporter/reporter-rpc/ReporterRpcProcedure.ts create mode 100644 src/reporter/reporter-rpc/ReporterRpcService.ts delete mode 100644 src/resolution.ts create mode 100644 src/rpc/RpcClient.ts create mode 100644 src/rpc/RpcHost.ts create mode 100644 src/rpc/RpcMessage.ts create mode 100644 src/rpc/RpcMessageChannel.ts create mode 100644 src/rpc/RpcMessagePort.ts create mode 100644 src/rpc/RpcProcedure.ts create mode 100644 src/rpc/RpcService.ts create mode 100644 src/rpc/error/RpcMessagePortClosedError.ts create mode 100644 src/rpc/index.ts create mode 100644 src/rpc/rpc-event-emitter/RpcEventEmitterMessageChannel.ts create mode 100644 src/rpc/rpc-event-emitter/RpcEventEmitterMessagePort.ts create mode 100644 src/rpc/rpc-event-emitter/index.ts create mode 100644 src/rpc/rpc-ipc/ProcessLike.ts create mode 100644 src/rpc/rpc-ipc/RpcIpcMessageChannel.ts create mode 100644 src/rpc/rpc-ipc/RpcIpcMessagePort.ts create mode 100644 src/rpc/rpc-ipc/error/RpcIpcMessagePortClosedError.ts create mode 100644 src/rpc/rpc-ipc/index.ts delete mode 100644 src/service.ts delete mode 100644 src/tsconfig.json delete mode 100644 src/types/vue-options.ts delete mode 100644 src/types/vue-template-compiler.d.ts create mode 100644 src/typescript-reporter/TypeScriptDiagnosticsOptions.ts create mode 100644 src/typescript-reporter/TypeScriptReporterConfiguration.ts create mode 100644 src/typescript-reporter/TypeScriptReporterOptions.ts create mode 100644 src/typescript-reporter/assertTypeScriptSupport.ts create mode 100644 src/typescript-reporter/extension/TypeScriptEmbeddedExtension.ts create mode 100644 src/typescript-reporter/extension/TypeScriptExtension.ts create mode 100644 src/typescript-reporter/extension/pnp/TypeScriptPnpExtension.ts create mode 100644 src/typescript-reporter/extension/pnp/TypeScriptPnpExtensionConfiguration.ts create mode 100644 src/typescript-reporter/extension/pnp/TypeScriptPnpExtensionOptions.ts create mode 100644 src/typescript-reporter/extension/pnp/assertPnpSupport.ts create mode 100644 src/typescript-reporter/extension/vue/TypeScriptVueExtension.ts create mode 100644 src/typescript-reporter/extension/vue/TypeScriptVueExtensionConfiguration.ts create mode 100644 src/typescript-reporter/extension/vue/TypeScriptVueExtensionOptions.ts create mode 100644 src/typescript-reporter/extension/vue/assertVueSupport.ts create mode 100644 src/typescript-reporter/extension/vue/types/vue-template-compiler.d.ts create mode 100644 src/typescript-reporter/issue/TypeScriptIssueFactory.ts create mode 100644 src/typescript-reporter/reporter/ControlledWatchCompilerHost.ts create mode 100644 src/typescript-reporter/reporter/ControlledWatchHost.ts create mode 100644 src/typescript-reporter/reporter/ControlledWatchSolutionBuilderHost.ts create mode 100644 src/typescript-reporter/reporter/TypeScriptReporter.ts create mode 100644 src/typescript-reporter/reporter/TypeScriptReporterRpcClient.ts create mode 100644 src/typescript-reporter/reporter/TypeScriptReporterRpcService.ts create mode 100644 src/typescript-reporter/reporter/TypeScriptReporterState.ts create mode 100644 src/utils/array/flatten.ts create mode 100644 src/utils/array/intersect.ts create mode 100644 src/utils/array/substract.ts create mode 100644 src/utils/array/unique.ts create mode 100644 src/utils/async/isPending.ts create mode 100644 src/utils/async/wait.ts create mode 100644 src/utils/fs/isFileJustCreated.ts create mode 100644 test/.DS_Store create mode 100644 test/fixtures/.DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..d79358b84366367d10c403ba8029e8b1a517643f GIT binary patch literal 10244 zcmeHM+invv5FNLHZc2LLBEjPd35f@YQfTP|LJDaERN^L5E)t-!xzH@6yVYisQc6%> z_y^z*_!Ia7et~yB0M6J;WN#8cAS5c;kv(4T9AD0iXJvAaaSwL1sChLop)p zd(J~?B564ZDS#)cQAh#BBS_UiwmVp5S z93Na{mc>N&m6V|ag**a4X3#7X>Np2TjGM?}BKt~8DEd^V2a!NUa>Nh{j`uFBLlzU+ zS5m=AC^(5^WRaXugd80>SE`dJDrrm0fMsBqfs<&Op*+>8L0#kg9-t*!YlXFHE386` zH`Ybu)8Ax5O(7f9rWVfoeD3#Y6EdWT8Y$$56f%b~b!3FG^Yo0`CQckr;WE(L#5i$E z?@dZ?_JONMb9^spmoY9<|gmyOk(tg~2Ankf#Tf{oDm~;tl}g zOULs}ilxzY&4bVk;GSDBV=bl2hSzoHpu5cuD9!G(6OVUG!KT;Ihen`>#$*=|PRa$k z*am$4g^gs+kl^};_8c71LvCQ(k4`A>^-n0ZT?NIa;A> zbeV3_RVveUx&@gBzjbr&%#VRP0^BWH1!e>C3QB&yiI%<&i$Mvh_k^Yc9d8(;Zr) z5|HbVJd+VKknHJbM>5uxcJ-Kp)Qk}@gswk}pu&MB{!Ny2?4%5AsQ@53(Y2<)-x}6b z#u_SAHs>Q(|3zDUP6kL0w;SM_{iTCZhJun@w~5<^)ob(|C0kzl3h;qB9`7BY*W*7Zcf6Qo_+L j;gIS!|KI-^z;`CYmyLW9)=&2K{BO_ygcQ2A2_ExY4pQ|dPE|~K{E+OB-}|AB zBEUzE0ufS-aUW+mMtXtqb%jwvVS@K~ODu&F`7%Rn{GAb(`HB5k-{O-r$%}UTyQr7YU%0SN2Vtc_y+Ok|F<7+9U-f{k8a8Ctt&Ujd#xltBxmEi%HTPL0=*SeE^oz~=6.11.5", diff --git a/src/ApiIncrementalChecker.ts b/src/ApiIncrementalChecker.ts deleted file mode 100644 index fd45b0d8..00000000 --- a/src/ApiIncrementalChecker.ts +++ /dev/null @@ -1,103 +0,0 @@ -import * as ts from 'typescript'; // used for types only -import { - IncrementalCheckerInterface, - IncrementalCheckerParams -} from './IncrementalCheckerInterface'; -import { CancellationToken, CancelledError } from './cancellation'; -import { CompilerHost } from './CompilerHost'; -import { createEslinter } from './createEslinter'; -import { - createIssuesFromTsDiagnostics, - createIssuesFromEsLintReports -} from './issue'; -import { LintReport } from './types/eslint'; - -export class ApiIncrementalChecker implements IncrementalCheckerInterface { - protected readonly tsIncrementalCompiler: CompilerHost; - protected readonly typescript: typeof ts; - - private currentEsLintErrors = new Map(); - private lastUpdatedFiles: string[] = []; - private lastRemovedFiles: string[] = []; - - private readonly eslinter: ReturnType | undefined; - - constructor({ - typescript, - programConfigFile, - compilerOptions, - eslinter, - vue, - checkSyntacticErrors = false, - resolveModuleName, - resolveTypeReferenceDirective - }: IncrementalCheckerParams) { - this.eslinter = eslinter; - - this.tsIncrementalCompiler = new CompilerHost( - typescript, - vue, - programConfigFile, - compilerOptions, - checkSyntacticErrors, - resolveModuleName, - resolveTypeReferenceDirective - ); - - this.typescript = typescript; - } - - public hasEsLinter(): boolean { - return this.eslinter !== undefined; - } - - public isFileExcluded(filePath: string): boolean { - return filePath.endsWith('.d.ts'); - } - - public nextIteration() { - // do nothing - } - - public async getTypeScriptIssues() { - const tsDiagnostics = await this.tsIncrementalCompiler.processChanges(); - this.lastUpdatedFiles = tsDiagnostics.updatedFiles; - this.lastRemovedFiles = tsDiagnostics.removedFiles; - - return createIssuesFromTsDiagnostics( - tsDiagnostics.results, - this.typescript - ); - } - - public async getEsLintIssues(cancellationToken: CancellationToken) { - if (!this.eslinter) { - throw new Error('EsLint is not enabled in the plugin.'); - } - - for (const removedFile of this.lastRemovedFiles) { - this.currentEsLintErrors.delete(removedFile); - } - - for (const updatedFile of this.lastUpdatedFiles) { - if (cancellationToken.isCancellationRequested()) { - throw new CancelledError(); - } - - if (this.isFileExcluded(updatedFile)) { - continue; - } - - const report = this.eslinter.getReport(updatedFile); - - if (report !== undefined) { - this.currentEsLintErrors.set(updatedFile, report); - } else if (this.currentEsLintErrors.has(updatedFile)) { - this.currentEsLintErrors.delete(updatedFile); - } - } - - const reports = Array.from(this.currentEsLintErrors.values()); - return createIssuesFromEsLintReports(reports); - } -} diff --git a/src/CompilerHost.ts b/src/CompilerHost.ts deleted file mode 100644 index 634b66bd..00000000 --- a/src/CompilerHost.ts +++ /dev/null @@ -1,442 +0,0 @@ -import * as ts from 'typescript'; // Imported for types alone - -import { LinkedList } from './LinkedList'; -import { VueProgram } from './VueProgram'; -import { ResolveModuleName, ResolveTypeReferenceDirective } from './resolution'; -import { VueOptions } from './types/vue-options'; - -interface DirectoryWatchDelaySlot { - events: { fileName: string }[]; - callback: ts.DirectoryWatcherCallback; -} - -interface FileWatchDelaySlot { - events: { fileName: string; eventKind: ts.FileWatcherEventKind }[]; - callback: ts.FileWatcherCallback; -} - -export class CompilerHost - implements - ts.WatchCompilerHostOfConfigFile< - ts.EmitAndSemanticDiagnosticsBuilderProgram - > { - private program?: ts.WatchOfConfigFile< - ts.EmitAndSemanticDiagnosticsBuilderProgram - >; - - public getProgram(): ts.Program { - if (!this.program) { - throw new Error('Program is not created yet.'); - } - - return this.program.getProgram().getProgram(); - } - - public getAllKnownFiles() { - return this.knownFiles; - } - - public configFileName: string; - public optionsToExtend: ts.CompilerOptions; - - // intercept all watch events and collect them until we get notification to start compilation - private directoryWatchers = new LinkedList(); - private fileWatchers = new LinkedList(); - - private knownFiles = new Set(); - - private gatheredDiagnostic: ts.Diagnostic[] = []; - private afterCompile = () => { - /* do nothing */ - }; - - private readonly tsHost: ts.WatchCompilerHostOfConfigFile< - ts.EmitAndSemanticDiagnosticsBuilderProgram - >; - protected lastProcessing?: Promise; - - private compilationStarted = false; - - public resolveModuleNames: - | (( - moduleNames: string[], - containingFile: string, - reusedNames?: string[] | undefined, - redirectedReference?: ts.ResolvedProjectReference | undefined - ) => (ts.ResolvedModule | undefined)[]) - | undefined; - public resolveTypeReferenceDirectives: - | (( - typeReferenceDirectiveNames: string[], - containingFile: string, - redirectedReference?: ts.ResolvedProjectReference | undefined - ) => (ts.ResolvedTypeReferenceDirective | undefined)[]) - | undefined; - - constructor( - private typescript: typeof ts, - private vueOptions: VueOptions, - programConfigFile: string, - compilerOptions: ts.CompilerOptions, - checkSyntacticErrors: boolean, - userResolveModuleName?: ResolveModuleName, - userResolveTypeReferenceDirective?: ResolveTypeReferenceDirective - ) { - this.tsHost = typescript.createWatchCompilerHost( - programConfigFile, - compilerOptions, - typescript.sys, - typescript.createEmitAndSemanticDiagnosticsBuilderProgram, - (diag: ts.Diagnostic) => { - if ( - !checkSyntacticErrors && - diag.code >= 1000 && - diag.code < 2000 && - diag.file // if diag.file is undefined, this is not a syntactic error, but a global error that should be emitted - ) { - return; - } - this.gatheredDiagnostic.push(diag); - }, - () => { - // do nothing - } - ); - - this.configFileName = this.tsHost.configFileName; - this.optionsToExtend = this.tsHost.optionsToExtend || {}; - - if (userResolveModuleName) { - this.resolveModuleNames = ( - moduleNames: string[], - containingFile: string - ) => { - return moduleNames.map(moduleName => { - return userResolveModuleName( - this.typescript, - moduleName, - containingFile, - this.optionsToExtend, - this - ).resolvedModule; - }); - }; - } - - if (userResolveTypeReferenceDirective) { - this.resolveTypeReferenceDirectives = ( - typeDirectiveNames: string[], - containingFile: string - ) => { - return typeDirectiveNames.map(typeDirectiveName => { - return userResolveTypeReferenceDirective( - this.typescript, - typeDirectiveName, - containingFile, - this.optionsToExtend, - this - ).resolvedTypeReferenceDirective; - }); - }; - } - } - - public async processChanges(): Promise<{ - results: ts.Diagnostic[]; - updatedFiles: string[]; - removedFiles: string[]; - }> { - if (!this.lastProcessing) { - const initialCompile = new Promise(resolve => { - this.afterCompile = () => { - resolve(this.gatheredDiagnostic); - this.afterCompile = () => { - /* do nothing */ - }; - this.compilationStarted = false; - }; - }); - this.lastProcessing = initialCompile; - this.program = this.typescript.createWatchProgram(this); - const errors = await initialCompile; - return { - results: errors, - updatedFiles: Array.from(this.knownFiles), - removedFiles: [] - }; - } - - // since we do not have a way to pass cancellation token to typescript, - // we just wait until previous compilation finishes. - await this.lastProcessing; - - const previousDiagnostic = this.gatheredDiagnostic; - this.gatheredDiagnostic = []; - const resultPromise = new Promise(resolve => { - this.afterCompile = () => { - resolve(this.gatheredDiagnostic); - this.afterCompile = () => { - /* do nothing */ - }; - this.compilationStarted = false; - }; - }); - this.lastProcessing = resultPromise; - - const files = []; - - this.directoryWatchers.forEach(item => { - for (const e of item.events) { - item.callback(e.fileName); - } - item.events.length = 0; - }); - - const updatedFiles: string[] = []; - const removedFiles: string[] = []; - this.fileWatchers.forEach(item => { - for (const e of item.events) { - item.callback(e.fileName, e.eventKind); - files.push(e.fileName); - if ( - e.eventKind === this.typescript.FileWatcherEventKind.Created || - e.eventKind === this.typescript.FileWatcherEventKind.Changed - ) { - updatedFiles.push(e.fileName); - } else if ( - e.eventKind === this.typescript.FileWatcherEventKind.Deleted - ) { - removedFiles.push(e.fileName); - } - } - item.events.length = 0; - }); - - // if the files are not relevant to typescript it may choose not to compile - // in this case we need to trigger promise resolution from here - if (!this.compilationStarted) { - // keep diagnostic from previous run - this.gatheredDiagnostic = previousDiagnostic; - this.afterCompile(); - return { - results: this.gatheredDiagnostic, - updatedFiles: [], - removedFiles: [] - }; - } - - const results = await resultPromise; - return { results, updatedFiles, removedFiles }; - } - - public setTimeout( - // eslint-disable-next-line @typescript-eslint/no-explicit-any - callback: (...args: any[]) => void, - ms: number, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - ...args: any[] - ) { - // There are 2 things we are hacking here: - // 1. This method only called from watch program to wait until all files - // are written to filesystem (for example, when doing 'save all') - // We are intercepting all change notifications, and letting - // them through only when webpack starts processing changes. - // Therefore, at this point normally files are already all saved, - // so we do not need to waste another 250 ms (hardcoded in TypeScript). - // On the other hand there may be occasional glitch, when our incremental - // compiler will receive the notification too late, and process it when - // next compilation would start. - // 2. It seems to be only reliable way to intercept a moment when TypeScript - // actually starts compilation. - // - // Ideally we probably should not let TypeScript call all those watching - // methods by itself, and instead forward changes from webpack. - // Unfortunately, at the moment TypeScript incremental API is quite - // immature (for example, minor changes in how you use it cause - // dramatic compilation time increase), so we have to stick with these - // hacks for now. - this.compilationStarted = true; - - return (this.typescript.sys.setTimeout || setTimeout)(callback, 1, args); - } - - // eslint-disable-next-line @typescript-eslint/no-explicit-any - public clearTimeout(timeoutId: any): void { - (this.typescript.sys.clearTimeout || clearTimeout)(timeoutId); - } - - public onWatchStatusChange(): void { - // do nothing - } - - public watchDirectory( - path: string, - callback: ts.DirectoryWatcherCallback, - recursive?: boolean - ): ts.FileWatcher { - const slot: DirectoryWatchDelaySlot = { callback, events: [] }; - const node = this.directoryWatchers.add(slot); - this.tsHost.watchDirectory( - path, - fileName => { - slot.events.push({ fileName }); - }, - recursive - ); - return { - close: () => { - node.detachSelf(); - } - }; - } - - public watchFile( - path: string, - callback: ts.FileWatcherCallback, - pollingInterval?: number - ): ts.FileWatcher { - const slot: FileWatchDelaySlot = { callback, events: [] }; - const node = this.fileWatchers.add(slot); - this.knownFiles.add(path); - this.tsHost.watchFile( - path, - (fileName, eventKind) => { - if (eventKind === this.typescript.FileWatcherEventKind.Created) { - this.knownFiles.add(fileName); - } else if (eventKind === this.typescript.FileWatcherEventKind.Deleted) { - this.knownFiles.delete(fileName); - } - slot.events.push({ fileName, eventKind }); - }, - pollingInterval - ); - return { - close: () => { - node.detachSelf(); - } - }; - } - - public fileExists(path: string): boolean { - return this.tsHost.fileExists(path); - } - - public readFile(path: string, encoding?: string) { - const content = this.tsHost.readFile(path, encoding); - - // get typescript contents from Vue file - if (content && VueProgram.isVue(path)) { - const resolved = VueProgram.resolveScriptBlock( - this.typescript, - content, - this.vueOptions.compiler - ); - return resolved.content; - } - - return content; - } - - public directoryExists(path: string): boolean { - return ( - (this.tsHost.directoryExists && this.tsHost.directoryExists(path)) || - false - ); - } - - public getDirectories(path: string): string[] { - return ( - (this.tsHost.getDirectories && this.tsHost.getDirectories(path)) || [] - ); - } - - public readDirectory( - path: string, - extensions?: ReadonlyArray, - exclude?: ReadonlyArray, - include?: ReadonlyArray, - depth?: number - ): string[] { - return this.typescript.sys.readDirectory( - path, - extensions, - exclude, - include, - depth - ); - } - - public createProgram = this.typescript - .createEmitAndSemanticDiagnosticsBuilderProgram; - - public getCurrentDirectory(): string { - return this.tsHost.getCurrentDirectory(); - } - - public getDefaultLibFileName(options: ts.CompilerOptions): string { - return this.tsHost.getDefaultLibFileName(options); - } - - public getEnvironmentVariable(name: string): string | undefined { - return ( - this.tsHost.getEnvironmentVariable && - this.tsHost.getEnvironmentVariable(name) - ); - } - - public getNewLine(): string { - return this.tsHost.getNewLine(); - } - - public realpath(path: string): string { - if (!this.tsHost.realpath) { - throw new Error( - 'The realpath function is not supported by the CompilerHost.' - ); - } - - return this.tsHost.realpath(path); - } - - public trace(s: string): void { - if (this.tsHost.trace) { - this.tsHost.trace(s); - } - } - - public useCaseSensitiveFileNames(): boolean { - return this.tsHost.useCaseSensitiveFileNames(); - } - - public onUnRecoverableConfigFileDiagnostic() { - // do nothing - } - - public afterProgramCreate( - program: ts.EmitAndSemanticDiagnosticsBuilderProgram - ): void { - // all actual diagnostics happens here - if (this.tsHost.afterProgramCreate) { - this.tsHost.afterProgramCreate(program); - } - - this.afterCompile(); - } - - // the functions below are use internally by typescript. we cannot use non-emitting version of incremental watching API - // because it is - // - much slower for some reason, - // - writes files anyway (o_O) - // - has different way of providing diagnostics. (with this version we can at least reliably get it from afterProgramCreate) - public createDirectory(): void { - // pretend everything was ok - } - - public writeFile(): void { - // pretend everything was ok - } - - public onCachedDirectoryStructureHostCreate?(): void { - // pretend everything was ok - } -} diff --git a/src/FilesRegister.ts b/src/FilesRegister.ts deleted file mode 100644 index 8dd945b0..00000000 --- a/src/FilesRegister.ts +++ /dev/null @@ -1,76 +0,0 @@ -import * as ts from 'typescript'; // import for types alone -import { LintReport } from './types/eslint'; - -export interface DataShape { - source?: ts.SourceFile; - linted: boolean; - eslints: LintReport[]; -} - -export class FilesRegister { - private files: { [filePath: string]: { mtime?: number; data: DataShape } }; - - constructor(private dataFactory: (_data?: DataShape) => DataShape) { - this.files = {}; - this.dataFactory = dataFactory; - } - - public keys() { - return Object.keys(this.files); - } - - public add(filePath: string) { - this.files[filePath] = { - mtime: undefined, - data: this.dataFactory(undefined) - }; - } - - public remove(filePath: string) { - if (this.has(filePath)) { - delete this.files[filePath]; - } - } - - public has(filePath: string) { - return this.files.hasOwnProperty(filePath); - } - - public get(filePath: string) { - if (!this.has(filePath)) { - throw new Error('File "' + filePath + '" not found in register.'); - } - - return this.files[filePath]; - } - - public ensure(filePath: string) { - if (!this.has(filePath)) { - this.add(filePath); - } - } - - public getData(filePath: string) { - return this.get(filePath).data; - } - - public mutateData(filePath: string, mutator: (data: DataShape) => void) { - this.ensure(filePath); - - mutator(this.files[filePath].data); - } - - public getMtime(filePath: string) { - return this.get(filePath).mtime; - } - - public setMtime(filePath: string, mtime: number) { - this.ensure(filePath); - - if (this.files[filePath].mtime !== mtime) { - this.files[filePath].mtime = mtime; - // file has been changed - we have to reset data - this.files[filePath].data = this.dataFactory(this.files[filePath].data); - } - } -} diff --git a/src/ForkTsCheckerWebpackPlugin.ts b/src/ForkTsCheckerWebpackPlugin.ts new file mode 100644 index 00000000..117e2375 --- /dev/null +++ b/src/ForkTsCheckerWebpackPlugin.ts @@ -0,0 +1,65 @@ +import webpack from 'webpack'; +import validateOptions from 'schema-utils'; +import schema from './ForkTsCheckerWebpackPluginOptions.json'; +import { ForkTsCheckerWebpackPluginOptions } from './ForkTsCheckerWebpackPluginOptions'; +import { createForkTsCheckerWebpackPluginConfiguration } from './ForkTsCheckerWebpackPluginConfiguration'; +import { createForkTsCheckerWebpackPluginState } from './ForkTsCheckerWebpackPluginState'; +import { composeReporterRpcClients, createAggregatedReporter, ReporterRpcClient } from './reporter'; +import { assertTypeScriptSupport } from './typescript-reporter/assertTypeScriptSupport'; +import { + createTypeScriptReporterRpcClient, + createTypeScriptReporterSameProcessRpcClient, +} from './typescript-reporter/reporter/TypeScriptReporterRpcClient'; +import { assertEsLintSupport } from './eslint-reporter/assertEsLintSupport'; +import { createEsLintReporterRpcClient } from './eslint-reporter/reporter/EsLintReporterRpcClient'; +import { tapDoneToAsyncGetIssues } from './hooks/tapDoneToAsyncGetIssues'; +import { tapInvalidToUpdateState } from './hooks/tapInvalidToUpdateState'; +import { tapStartToConnectAndRunReporter } from './hooks/tapStartToConnectAndRunReporter'; +import { tapStopToDisconnectReporter } from './hooks/tapStopToDisconnectReporter'; +import { tapEmitToGetIssues } from './hooks/tapEmitToGetIssues'; +import { getForkTsCheckerWebpackPluginHooks } from './hooks/pluginHooks'; + +class ForkTsCheckerWebpackPlugin implements webpack.Plugin { + constructor(private readonly options: ForkTsCheckerWebpackPluginOptions = {}) { + validateOptions(schema, options, 'ForkTsCheckerWebpackPlugin'); + } + + public static getCompilerHooks(compiler: webpack.Compiler) { + return getForkTsCheckerWebpackPluginHooks(compiler); + } + + apply(compiler: webpack.Compiler) { + const configuration = createForkTsCheckerWebpackPluginConfiguration(compiler, this.options); + const state = createForkTsCheckerWebpackPluginState(); + const reporters: ReporterRpcClient[] = []; + + if (configuration.typescript.enabled) { + assertTypeScriptSupport(configuration.typescript); + reporters.push(createTypeScriptReporterRpcClient(configuration.typescript)); + } + + if (configuration.eslint.enabled) { + assertEsLintSupport(configuration.eslint); + reporters.push(createEsLintReporterRpcClient(configuration.eslint)); + } + + if (reporters.length) { + const reporter = createAggregatedReporter(composeReporterRpcClients(reporters)); + + tapInvalidToUpdateState(compiler, configuration, state); + tapStartToConnectAndRunReporter(compiler, reporter, configuration, state); + tapStopToDisconnectReporter(compiler, reporter, configuration, state); + if (configuration.async) { + tapDoneToAsyncGetIssues(compiler, configuration, state); + } else { + tapEmitToGetIssues(compiler, configuration, state); + } + } else { + configuration.logger.infrastructure.error( + `ForkTsCheckerWebpackPlugin is configured to not use any issue reporter. It's probably a configuration issue.` + ); + } + } +} + +export { ForkTsCheckerWebpackPlugin }; diff --git a/src/ForkTsCheckerWebpackPluginConfiguration.ts b/src/ForkTsCheckerWebpackPluginConfiguration.ts new file mode 100644 index 00000000..ce30c5d6 --- /dev/null +++ b/src/ForkTsCheckerWebpackPluginConfiguration.ts @@ -0,0 +1,41 @@ +import webpack from 'webpack'; +import { ForkTsCheckerWebpackPluginOptions } from './ForkTsCheckerWebpackPluginOptions'; +import { createIssueConfiguration, IssueConfiguration } from './issue/IssueConfiguration'; +import { + createFormatterConfiguration, + FormatterConfiguration, +} from './formatter/FormatterConfiguration'; +import { + createTypeScriptReporterConfiguration, + TypeScriptReporterConfiguration, +} from './typescript-reporter/TypeScriptReporterConfiguration'; +import { + createEsLintReporterConfiguration, + EsLintReporterConfiguration, +} from './eslint-reporter/EsLintReporterConfiguration'; +import { createLoggerConfiguration, LoggerConfiguration } from './logger/LoggerConfiguration'; + +interface ForkTsCheckerWebpackPluginConfiguration { + async: boolean; + typescript: TypeScriptReporterConfiguration; + eslint: EsLintReporterConfiguration; + formatter: FormatterConfiguration; + issue: IssueConfiguration; + logger: LoggerConfiguration; +} + +function createForkTsCheckerWebpackPluginConfiguration( + compiler: webpack.Compiler, + options: ForkTsCheckerWebpackPluginOptions = {} +): ForkTsCheckerWebpackPluginConfiguration { + return { + async: options.async === true, + typescript: createTypeScriptReporterConfiguration(compiler, options.typescript), + eslint: createEsLintReporterConfiguration(compiler, options.eslint), + formatter: createFormatterConfiguration(options.formatter), + issue: createIssueConfiguration(compiler, options.issue), + logger: createLoggerConfiguration(compiler, options.logger), + }; +} + +export { ForkTsCheckerWebpackPluginConfiguration, createForkTsCheckerWebpackPluginConfiguration }; diff --git a/src/ForkTsCheckerWebpackPluginOptions.json b/src/ForkTsCheckerWebpackPluginOptions.json new file mode 100644 index 00000000..85271092 --- /dev/null +++ b/src/ForkTsCheckerWebpackPluginOptions.json @@ -0,0 +1,265 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "async": { + "type": "boolean", + "description": "When true, plugin will not block compilation to finish issues checking" + }, + "typescript": { + "$ref": "#/definitions/TypeScriptReporterOptions" + }, + "eslint": { + "$ref": "#/definitions/EsLintReporterOptions" + }, + "formatter": { + "$ref": "#/definitions/FormatterOptions" + }, + "issue": { + "$ref": "#/definitions/IssueOptions" + }, + "logger": { + "$ref": "#/definitions/LoggerOptions" + } + }, + "additionalProperties": false, + "definitions": { + "Formatter": { + "instanceof": "Function" + }, + "ComplexFormatterPreferences": { + "type": "object", + "properties": { + "type": { + "$ref": "#/definitions/FormatterType" + }, + "options": { + "type": "object", + "additionalProperties": true + } + }, + "required": ["type"] + }, + "FormatterType": { + "type": "string", + "enum": ["basic", "codeframe"] + }, + "IssueMatch": { + "type": "object", + "properties": { + "origin": { + "type": "string", + "enum": ["typescript", "eslint"] + }, + "severity": { + "type": "string", + "enum": ["error", "warning"] + }, + "code": { + "type": "string" + }, + "file": { + "type": "string" + } + } + }, + "IssuePredicate": { + "instanceof": "Function" + }, + "IssuePredicateOption": { + "oneOf": [ + { + "$ref": "#/definitions/IssuePredicate" + }, + { + "$ref": "#/definitions/IssueMatch" + }, + { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/definitions/IssuePredicate" + }, + { + "$ref": "#/definitions/IssueMatch" + } + ] + } + } + ] + }, + "LoggerType": { + "type": "string", + "enum": ["console", "webpack-infrastructure", "silent"] + }, + "Logger": { + "instanceof": "Function" + }, + "TypeScriptReporterOptions": { + "oneOf": [ + { + "type": "boolean", + "description": "Enable TypeScript reporter." + }, + { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enable TypeScript reporter." + }, + "memoryLimit": { + "type": "number", + "description": "Memory limit for TypeScript reporter process." + }, + "tsconfig": { + "type": "string", + "description": "Path to tsconfig.json. By default plugin uses context or process.cwd() to localize tsconfig.json file." + }, + "build": { + "type": "boolean", + "description": "The equivalent of the `--build` flag from the `tsc`." + }, + "compilerOptions": { + "type": "object", + "description": "Custom compilerOptions to be passed to the TypeScript compiler.", + "additionalProperties": true + }, + "diagnosticOptions": { + "type": "object", + "description": "Types of diagnostics to be reported.", + "properties": { + "syntactic": { + "type": "boolean" + }, + "semantic": { + "type": "boolean" + }, + "declaration": { + "type": "boolean" + }, + "global": { + "type": "boolean" + } + } + }, + "extensions": { + "type": "object", + "properties": { + "vue": { + "$ref": "#/definitions/TypeScriptVueExtensionOptions" + }, + "pnp": { + "$ref": "#/definitions/TypeScriptPnpExtensionOptions" + } + } + } + } + } + ] + }, + "TypeScriptVueExtensionOptions": { + "oneOf": [ + { + "type": "boolean", + "description": "Enable TypeScript Vue extension." + }, + { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enable TypeScript Vue extension." + }, + "compiler": { + "type": "string", + "description": "Custom vue-template-compiler package" + } + } + } + ] + }, + "TypeScriptPnpExtensionOptions": { + "type": "boolean", + "description": "Enable TypeScript PnP extension." + }, + "EsLintReporterOptions": { + "type": "object", + "properties": { + "files": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1, + "uniqueItems": true, + "description": "List of glob patterns of files to be linted." + }, + "enabled": { + "type": "boolean", + "description": "Enable EsLint reporter." + }, + "memoryLimit": { + "type": "number", + "description": "Memory limit for EsLint reporter process." + }, + "options": { + "type": "object", + "description": "Custom options to be passed to the EsLint engine.", + "additionalProperties": true + } + }, + "required": ["files"] + }, + "FormatterOptions": { + "oneOf": [ + { + "$ref": "#/definitions/FormatterType" + }, + { + "$ref": "#/definitions/ComplexFormatterPreferences" + }, + { + "$ref": "#/definitions/Formatter" + } + ] + }, + "IssueOptions": { + "type": "object", + "properties": { + "include": { + "$ref": "#/definitions/IssuePredicateOption" + }, + "exclude": { + "$ref": "#/definitions/IssuePredicateOption" + } + } + }, + "LoggerOptions": { + "type": "object", + "properties": { + "infrastructure": { + "oneOf": [ + { + "$ref": "#/definitions/LoggerType" + }, + { + "$ref": "#/definitions/Logger" + } + ] + }, + "issues": { + "oneOf": [ + { + "$ref": "#/definitions/LoggerType" + }, + { + "$ref": "#/definitions/Logger" + } + ] + } + } + } + } +} diff --git a/src/ForkTsCheckerWebpackPluginOptions.ts b/src/ForkTsCheckerWebpackPluginOptions.ts new file mode 100644 index 00000000..6b83c48e --- /dev/null +++ b/src/ForkTsCheckerWebpackPluginOptions.ts @@ -0,0 +1,16 @@ +import { TypeScriptReporterOptions } from './typescript-reporter/TypeScriptReporterOptions'; +import { EsLintReporterOptions } from './eslint-reporter/EsLintReporterOptions'; +import { IssueOptions } from './issue/IssueOptions'; +import { FormatterOptions } from './formatter/FormatterOptions'; +import LoggerOptions from './logger/LoggerOptions'; + +interface ForkTsCheckerWebpackPluginOptions { + async?: boolean; + typescript?: TypeScriptReporterOptions; + eslint?: EsLintReporterOptions; + formatter?: FormatterOptions; + issue?: IssueOptions; + logger?: LoggerOptions; +} + +export { ForkTsCheckerWebpackPluginOptions }; diff --git a/src/ForkTsCheckerWebpackPluginState.ts b/src/ForkTsCheckerWebpackPluginState.ts new file mode 100644 index 00000000..a0a932f9 --- /dev/null +++ b/src/ForkTsCheckerWebpackPluginState.ts @@ -0,0 +1,19 @@ +import { Issue } from './issue'; + +interface ForkTsCheckerWebpackPluginState { + report: Promise; + isWatching: boolean; + createdFiles: string[]; + changedFiles: string[]; +} + +function createForkTsCheckerWebpackPluginState(): ForkTsCheckerWebpackPluginState { + return { + report: Promise.resolve([]), + isWatching: false, + createdFiles: [], + changedFiles: [], + }; +} + +export { ForkTsCheckerWebpackPluginState, createForkTsCheckerWebpackPluginState }; diff --git a/src/FsHelper.ts b/src/FsHelper.ts deleted file mode 100644 index 5e3d054f..00000000 --- a/src/FsHelper.ts +++ /dev/null @@ -1,15 +0,0 @@ -import * as fs from 'fs'; - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export function throwIfIsInvalidSourceFileError(filepath: string, error: any) { - if ( - fs.existsSync(filepath) && - // check the error type due to file system lag - !(error instanceof Error) && - !(error.constructor.name === 'FatalError') && - !(error.message && error.message.trim().startsWith('Invalid source file')) - ) { - // it's not because file doesn't exist - throw error - throw error; - } -} diff --git a/src/IncrementalChecker.ts b/src/IncrementalChecker.ts deleted file mode 100644 index 64669dd9..00000000 --- a/src/IncrementalChecker.ts +++ /dev/null @@ -1,317 +0,0 @@ -import * as fs from 'fs'; -import * as path from 'path'; -import * as ts from 'typescript'; // Imported for types alone; actual requires take place in methods below - -import { FilesRegister } from './FilesRegister'; -import { - CancellationToken, - CancelledError, - TypeScriptCancellationToken -} from './cancellation'; -import { - ResolveModuleName, - ResolveTypeReferenceDirective, - makeResolutionFunctions -} from './resolution'; -import { VueProgram } from './VueProgram'; -import { - IncrementalCheckerInterface, - IncrementalCheckerParams -} from './IncrementalCheckerInterface'; -import { createEslinter } from './createEslinter'; -import { VueOptions } from './types/vue-options'; -import { - Issue, - createIssuesFromEsLintReports, - createIssuesFromTsDiagnostics -} from './issue'; -import { LintReport } from './types/eslint'; - -export class IncrementalChecker implements IncrementalCheckerInterface { - private files = new FilesRegister(() => ({ - // data shape - source: undefined, - linted: false, - eslints: [] - })); - - protected program?: ts.Program; - protected programConfig?: ts.ParsedCommandLine; - - private readonly typescript: typeof ts; - private readonly programConfigFile: string; - private readonly compilerOptions: object; - private readonly eslinter: ReturnType | undefined; - private readonly vue: VueOptions; - private readonly checkSyntacticErrors: boolean; - private readonly resolveModuleName: ResolveModuleName | undefined; - private readonly resolveTypeReferenceDirective: - | ResolveTypeReferenceDirective - | undefined; - - constructor({ - typescript, - programConfigFile, - compilerOptions, - eslinter, - vue, - checkSyntacticErrors = false, - resolveModuleName, - resolveTypeReferenceDirective - }: IncrementalCheckerParams) { - this.typescript = typescript; - this.programConfigFile = programConfigFile; - this.compilerOptions = compilerOptions; - this.eslinter = eslinter; - this.vue = vue; - this.checkSyntacticErrors = checkSyntacticErrors; - this.resolveModuleName = resolveModuleName; - this.resolveTypeReferenceDirective = resolveTypeReferenceDirective; - } - - public static loadProgramConfig( - typescript: typeof ts, - configFile: string, - compilerOptions: object - ) { - const tsconfig = typescript.readConfigFile( - configFile, - typescript.sys.readFile - ).config; - - tsconfig.compilerOptions = tsconfig.compilerOptions || {}; - tsconfig.compilerOptions = { - ...tsconfig.compilerOptions, - ...compilerOptions - }; - - const parsed = typescript.parseJsonConfigFileContent( - tsconfig, - typescript.sys, - path.dirname(configFile) - ); - - return parsed; - } - - private static createProgram( - typescript: typeof ts, - programConfig: ts.ParsedCommandLine, - files: FilesRegister, - oldProgram: ts.Program | undefined, - userResolveModuleName: ResolveModuleName | undefined, - userResolveTypeReferenceDirective: ResolveTypeReferenceDirective | undefined - ) { - const host = typescript.createCompilerHost(programConfig.options); - const realGetSourceFile = host.getSourceFile; - - const { - resolveModuleName, - resolveTypeReferenceDirective - } = makeResolutionFunctions( - userResolveModuleName, - userResolveTypeReferenceDirective - ); - - host.resolveModuleNames = (moduleNames, containingFile) => { - return moduleNames.map(moduleName => { - return resolveModuleName( - typescript, - moduleName, - containingFile, - programConfig.options, - host - ).resolvedModule; - }); - }; - - host.resolveTypeReferenceDirectives = ( - typeDirectiveNames, - containingFile - ) => { - return typeDirectiveNames.map(typeDirectiveName => { - return resolveTypeReferenceDirective( - typescript, - typeDirectiveName, - containingFile, - programConfig.options, - host - ).resolvedTypeReferenceDirective; - }); - }; - - host.getSourceFile = (filePath, languageVersion, onError) => { - try { - const stats = fs.statSync(filePath); - - files.setMtime(filePath, stats.mtime.valueOf()); - } catch (e) { - // probably file does not exists - files.remove(filePath); - } - - // get source file only if there is no source in files register - if (!files.has(filePath) || !files.getData(filePath).source) { - files.mutateData(filePath, data => { - data.source = realGetSourceFile(filePath, languageVersion, onError); - }); - } - - return files.getData(filePath).source; - }; - - return typescript.createProgram( - programConfig.fileNames, - programConfig.options, - host, - oldProgram // re-use old program - ); - } - - public hasEsLinter(): boolean { - return this.eslinter !== undefined; - } - - public static isFileExcluded(filePath: string): boolean { - return filePath.endsWith('.d.ts'); - } - - public nextIteration() { - this.program = this.vue.enabled - ? this.loadVueProgram(this.vue) - : this.loadDefaultProgram(); - } - - private loadVueProgram(vueOptions: VueOptions) { - this.programConfig = - this.programConfig || - VueProgram.loadProgramConfig( - this.typescript, - this.programConfigFile, - this.compilerOptions - ); - - return VueProgram.createProgram( - this.typescript, - this.programConfig, - path.dirname(this.programConfigFile), - this.files, - this.program, - this.resolveModuleName, - this.resolveTypeReferenceDirective, - vueOptions - ); - } - - private loadDefaultProgram() { - this.programConfig = - this.programConfig || - IncrementalChecker.loadProgramConfig( - this.typescript, - this.programConfigFile, - this.compilerOptions - ); - - return IncrementalChecker.createProgram( - this.typescript, - this.programConfig, - this.files, - this.program, - this.resolveModuleName, - this.resolveTypeReferenceDirective - ); - } - - public async getTypeScriptIssues( - cancellationToken: CancellationToken - ): Promise { - const { program } = this; - if (!program) { - throw new Error('Invoked called before program initialized'); - } - const tsDiagnostics: ts.Diagnostic[] = []; - // select files to check (it's semantic check - we have to include all files :/) - const filesToCheck = program.getSourceFiles(); - const tsCancellationToken = cancellationToken - ? new TypeScriptCancellationToken(this.typescript, cancellationToken) - : undefined; - - filesToCheck.forEach(sourceFile => { - if (cancellationToken.isCancellationRequested()) { - throw new CancelledError(); - } - - try { - const tsDiagnosticsToRegister: ReadonlyArray = this - .checkSyntacticErrors - ? program - .getSemanticDiagnostics(sourceFile, tsCancellationToken) - .concat( - program.getSyntacticDiagnostics(sourceFile, tsCancellationToken) - ) - : program.getSemanticDiagnostics(sourceFile, tsCancellationToken); - - tsDiagnostics.push(...tsDiagnosticsToRegister); - } catch (error) { - if (error instanceof this.typescript.OperationCanceledException) { - throw new CancelledError(); - } - - throw error; - } - }); - - return createIssuesFromTsDiagnostics(tsDiagnostics, this.typescript); - } - - public async getEsLintIssues( - cancellationToken: CancellationToken - ): Promise { - // select files to lint - const filesToLint = this.files - .keys() - .filter( - filePath => - !this.files.getData(filePath).linted && - !IncrementalChecker.isFileExcluded(filePath) - ); - - const currentEsLintErrors = new Map(); - filesToLint.forEach(fileName => { - if (cancellationToken.isCancellationRequested()) { - throw new CancelledError(); - } - - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const report = this.eslinter!.getReport(fileName); - if (report !== undefined) { - currentEsLintErrors.set(fileName, report); - } - }); - - // set lints in files register - currentEsLintErrors.forEach((lint, filePath) => { - this.files.mutateData(filePath, data => { - data.linted = true; - data.eslints.push(lint); - }); - }); - - // set all files as linted - this.files.keys().forEach(filePath => { - this.files.mutateData(filePath, data => { - data.linted = true; - }); - }); - - const reports = this.files - .keys() - .reduce( - (innerLints, filePath) => - innerLints.concat(this.files.getData(filePath).eslints), - [] - ); - - return createIssuesFromEsLintReports(reports); - } -} diff --git a/src/IncrementalCheckerInterface.ts b/src/IncrementalCheckerInterface.ts deleted file mode 100644 index fa908227..00000000 --- a/src/IncrementalCheckerInterface.ts +++ /dev/null @@ -1,28 +0,0 @@ -import * as ts from 'typescript'; // imported for types alone - -import { CancellationToken } from './cancellation'; -import { ResolveTypeReferenceDirective, ResolveModuleName } from './resolution'; -import { createEslinter } from './createEslinter'; -import { Issue } from './issue'; -import { VueOptions } from './types/vue-options'; - -export interface IncrementalCheckerInterface { - nextIteration(): void; - - hasEsLinter(): boolean; - - getTypeScriptIssues(cancellationToken: CancellationToken): Promise; - getEsLintIssues(cancellationToken: CancellationToken): Promise; -} - -export interface IncrementalCheckerParams { - typescript: typeof ts; - context: string; - programConfigFile: string; - compilerOptions: ts.CompilerOptions; - eslinter: ReturnType | undefined; - checkSyntacticErrors: boolean; - resolveModuleName: ResolveModuleName | undefined; - resolveTypeReferenceDirective: ResolveTypeReferenceDirective | undefined; - vue: VueOptions; -} diff --git a/src/LinkedList.ts b/src/LinkedList.ts deleted file mode 100644 index 356b83f4..00000000 --- a/src/LinkedList.ts +++ /dev/null @@ -1,107 +0,0 @@ -export class HeadNode { - public next: LinkedListNode | TailNode; - - constructor() { - // eslint-disable-next-line @typescript-eslint/no-use-before-define - this.next = new TailNode(this); - } -} - -export class TailNode { - public previous: LinkedListNode | HeadNode; - - constructor(head: HeadNode) { - this.previous = head; - } -} -export class LinkedListNode { - public next: LinkedListNode | TailNode | null = null; - public previous: LinkedListNode | HeadNode | null = null; - public readonly item: T; - - constructor(item: T) { - this.item = item; - } - - public detachSelf() { - if (!this.next && !this.previous) { - throw new Error('node is not attached'); - } - if (this.next) { - this.next.previous = this.previous; - } - if (this.previous) { - this.previous.next = this.next; - } - this.next = null; - this.previous = null; - } - - public attachAfter(node: LinkedListNode | HeadNode) { - if (this.next || this.previous) { - throw new Error('Node is inserted elsewhere'); - } - - this.next = node.next; - this.previous = node; - - if (node.next) { - node.next.previous = this; - } - node.next = this; - } - - public attachBefore(node: LinkedListNode | TailNode) { - if (!node.previous) { - throw new Error('no previous node found.'); - } - this.attachAfter(node.previous); - } -} -export class LinkedList { - public head: HeadNode; - public tail: TailNode; - - constructor() { - this.head = new HeadNode(); - this.tail = this.head.next as TailNode; - } - - public add(item: T): LinkedListNode { - const newNode = new LinkedListNode(item); - newNode.attachAfter(this.tail.previous); - return newNode; - } - - public getItems(): T[] { - const result: T[] = []; - this.forEach(item => { - result.push(item); - }); - return result; - } - - public forEach(callback: (item: T, node: LinkedListNode) => void) { - let current = this.head.next; - while (current !== this.tail) { - // if item is not tail it is always a node - const item = current as LinkedListNode; - callback(item.item, item); - if (!item.next) { - throw new Error('badly attached item found.'); - } - current = item.next; - } - } - - public hasItems() { - return this.head.next !== this.tail; - } - - public getLastItem() { - if (!this.hasItems()) { - throw new Error('no items in list.'); - } - return this.head.next as LinkedListNode; - } -} diff --git a/src/Message.ts b/src/Message.ts deleted file mode 100644 index 80992233..00000000 --- a/src/Message.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Issue } from './issue'; - -export interface Message { - diagnostics: Issue[]; - lints: Issue[]; -} diff --git a/src/RpcTypes.ts b/src/RpcTypes.ts deleted file mode 100644 index 164b19de..00000000 --- a/src/RpcTypes.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { FileBasedCancellationTokenJSON } from './cancellation'; -import { Message } from './Message'; - -export const RUN = 'run'; -export type RunPayload = FileBasedCancellationTokenJSON; -export type RunResult = - | Message - // when run was cancelled via CancellationToken, undefined is returned - | undefined; diff --git a/src/VueProgram.ts b/src/VueProgram.ts deleted file mode 100644 index 6cce2aaf..00000000 --- a/src/VueProgram.ts +++ /dev/null @@ -1,365 +0,0 @@ -import * as fs from 'fs'; -import * as path from 'path'; -import * as ts from 'typescript'; // import for types alone -import { FilesRegister } from './FilesRegister'; -import { - ResolveModuleName, - ResolveTypeReferenceDirective, - makeResolutionFunctions -} from './resolution'; -import * as vueCompiler from 'vue-template-compiler'; -import { VueOptions } from './types/vue-options'; - -interface ResolvedScript { - scriptKind: ts.ScriptKind; - content: string; -} - -export class VueProgram { - public static loadProgramConfig( - typescript: typeof ts, - configFile: string, - compilerOptions: object - ) { - const extraExtensions = ['vue']; - - const parseConfigHost: ts.ParseConfigHost = { - fileExists: typescript.sys.fileExists, - readFile: typescript.sys.readFile, - useCaseSensitiveFileNames: typescript.sys.useCaseSensitiveFileNames, - readDirectory: (rootDir, extensions, excludes, includes, depth) => { - return typescript.sys.readDirectory( - rootDir, - extensions.concat(extraExtensions), - excludes, - includes, - depth - ); - } - }; - - const tsconfig = typescript.readConfigFile( - configFile, - typescript.sys.readFile - ).config; - - tsconfig.compilerOptions = tsconfig.compilerOptions || {}; - tsconfig.compilerOptions = { - ...tsconfig.compilerOptions, - ...compilerOptions - }; - - const parsed = typescript.parseJsonConfigFileContent( - tsconfig, - parseConfigHost, - path.dirname(configFile) - ); - - parsed.options.allowNonTsExtensions = true; - - return parsed; - } - - /** - * Search for default wildcard or wildcard from options, we only search for that in tsconfig CompilerOptions.paths. - * The path is resolved with thie given substitution and includes the CompilerOptions.baseUrl (if given). - * If no paths given in tsconfig, then the default substitution is '[tsconfig directory]/src'. - * (This is a fast, simplified inspiration of what's described here: https://github.com/Microsoft/TypeScript/issues/5039) - */ - public static resolveNonTsModuleName( - moduleName: string, - containingFile: string, - basedir: string, - options: ts.CompilerOptions - ) { - const baseUrl = options.baseUrl ? options.baseUrl : basedir; - const discardedSymbols = ['.', '..', '/']; - const wildcards: string[] = []; - - if (options.paths) { - Object.keys(options.paths).forEach(key => { - const pathSymbol = key[0]; - if ( - discardedSymbols.indexOf(pathSymbol) < 0 && - wildcards.indexOf(pathSymbol) < 0 - ) { - wildcards.push(pathSymbol); - } - }); - } else { - wildcards.push('@'); - } - - const isRelative = !path.isAbsolute(moduleName); - let correctWildcard; - - wildcards.forEach(wildcard => { - if (moduleName.substr(0, 2) === `${wildcard}/`) { - correctWildcard = wildcard; - } - }); - - if (correctWildcard) { - const pattern = options.paths - ? options.paths[`${correctWildcard}/*`] - : undefined; - const substitution = pattern - ? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - options.paths![`${correctWildcard}/*`][0].replace('*', '') - : 'src'; - moduleName = path.resolve(baseUrl, substitution, moduleName.substr(2)); - } else if (isRelative) { - moduleName = path.resolve(path.dirname(containingFile), moduleName); - } - return moduleName; - } - - public static isVue(filePath: string) { - return path.extname(filePath) === '.vue'; - } - - public static createProgram( - typescript: typeof ts, - programConfig: ts.ParsedCommandLine, - basedir: string, - files: FilesRegister, - oldProgram: ts.Program | undefined, - userResolveModuleName: ResolveModuleName | undefined, - userResolveTypeReferenceDirective: - | ResolveTypeReferenceDirective - | undefined, - vueOptions: VueOptions - ) { - const host = typescript.createCompilerHost(programConfig.options); - const realGetSourceFile = host.getSourceFile; - - const { - resolveModuleName, - resolveTypeReferenceDirective - } = makeResolutionFunctions( - userResolveModuleName, - userResolveTypeReferenceDirective - ); - - host.resolveModuleNames = (moduleNames, containingFile) => { - return moduleNames.map(moduleName => { - return resolveModuleName( - typescript, - moduleName, - containingFile, - programConfig.options, - host - ).resolvedModule; - }); - }; - - host.resolveTypeReferenceDirectives = ( - typeDirectiveNames, - containingFile - ) => { - return typeDirectiveNames.map(typeDirectiveName => { - return resolveTypeReferenceDirective( - typescript, - typeDirectiveName, - containingFile, - programConfig.options, - host - ).resolvedTypeReferenceDirective; - }); - }; - - // We need a host that can parse Vue SFCs (single file components). - host.getSourceFile = (filePath, languageVersion, onError) => { - try { - const stats = fs.statSync(filePath); - - files.setMtime(filePath, stats.mtime.valueOf()); - } catch (e) { - // probably file does not exists - files.remove(filePath); - } - - // get source file only if there is no source in files register - if (!files.has(filePath) || !files.getData(filePath).source) { - files.mutateData(filePath, data => { - data.source = realGetSourceFile(filePath, languageVersion, onError); - }); - } - - let source = files.getData(filePath).source; - - // get typescript contents from Vue file - if (source && VueProgram.isVue(filePath)) { - const resolved = VueProgram.resolveScriptBlock( - typescript, - source.text, - vueOptions.compiler - ); - source = typescript.createSourceFile( - filePath, - resolved.content, - languageVersion, - true, - resolved.scriptKind - ); - } - - return source; - }; - - // We need a host with special module resolution for Vue files. - host.resolveModuleNames = (moduleNames, containingFile) => { - const resolvedModules: ts.ResolvedModule[] = []; - - for (const moduleName of moduleNames) { - // Try to use standard resolution. - const { resolvedModule } = typescript.resolveModuleName( - moduleName, - containingFile, - programConfig.options, - { - fileExists(fileName) { - if (fileName.endsWith('.vue.ts')) { - return ( - host.fileExists(fileName.slice(0, -3)) || - host.fileExists(fileName) - ); - } else { - return host.fileExists(fileName); - } - }, - readFile(fileName) { - // This implementation is not necessary. Just for consistent behavior. - if (fileName.endsWith('.vue.ts') && !host.fileExists(fileName)) { - return host.readFile(fileName.slice(0, -3)); - } else { - return host.readFile(fileName); - } - } - } - ); - - if (resolvedModule) { - if ( - resolvedModule.resolvedFileName.endsWith('.vue.ts') && - !host.fileExists(resolvedModule.resolvedFileName) - ) { - resolvedModule.resolvedFileName = resolvedModule.resolvedFileName.slice( - 0, - -3 - ); - } - resolvedModules.push(resolvedModule); - } else { - // For non-ts extensions. - const absolutePath = VueProgram.resolveNonTsModuleName( - moduleName, - containingFile, - basedir, - programConfig.options - ); - - if (VueProgram.isVue(moduleName)) { - resolvedModules.push({ - resolvedFileName: absolutePath, - extension: '.ts' - } as ts.ResolvedModuleFull); - } else { - resolvedModules.push({ - // If the file does exist, return an empty string (because we assume user has provided a ".d.ts" file for it). - resolvedFileName: host.fileExists(absolutePath) - ? '' - : absolutePath, - extension: '.ts' - } as ts.ResolvedModuleFull); - } - } - } - - return resolvedModules; - }; - - return typescript.createProgram( - programConfig.fileNames, - programConfig.options, - host, - oldProgram // re-use old program - ); - } - - private static getScriptKindByLang(typescript: typeof ts, lang?: string) { - if (lang === 'ts') { - return typescript.ScriptKind.TS; - } else if (lang === 'tsx') { - return typescript.ScriptKind.TSX; - } else if (lang === 'jsx') { - return typescript.ScriptKind.JSX; - } else { - // when lang is "js" or no lang specified - return typescript.ScriptKind.JS; - } - } - - public static resolveScriptBlock( - typescript: typeof ts, - content: string, - compiler: string - ): ResolvedScript { - // We need to import template compiler for vue lazily because it cannot be included it - // as direct dependency because it is an optional dependency of fork-ts-checker-webpack-plugin. - // Since its version must not mismatch with user-installed Vue.js, - // we should let the users install template compiler for vue by themselves. - let parser: typeof vueCompiler; - try { - parser = require(compiler); - } catch (err) { - throw new Error( - 'When you use `vue` option, make sure to install `' + compiler + '`.' - ); - } - - const { script } = parser.parseComponent(content, { - pad: 'space' - }); - - // No block + // pad blank lines to retain diagnostics location + const lineOffset = vueSourceText.slice(0, script.start).split(/\r?\n/g).length; + const paddedSourceText = + Array(lineOffset).join('\n') + vueSourceText.slice(script.start, script.end); + + return createVueInlineScriptEmbeddedSource(paddedSourceText, script.attrs.lang); + } + } + + return createTypeScriptEmbeddedExtension({ + embeddedExtensions: ['.vue'], + getEmbeddedSource: getVueEmbeddedSource, + }); +} + +export { createTypeScriptVueExtension }; diff --git a/src/typescript-reporter/extension/vue/TypeScriptVueExtensionConfiguration.ts b/src/typescript-reporter/extension/vue/TypeScriptVueExtensionConfiguration.ts new file mode 100644 index 00000000..51a467dd --- /dev/null +++ b/src/typescript-reporter/extension/vue/TypeScriptVueExtensionConfiguration.ts @@ -0,0 +1,18 @@ +import { TypeScriptVueExtensionOptions } from './TypeScriptVueExtensionOptions'; + +interface TypeScriptVueExtensionConfiguration { + enabled: boolean; + compiler: string; +} + +function createTypeScriptVueExtensionConfiguration( + options: TypeScriptVueExtensionOptions | undefined +): TypeScriptVueExtensionConfiguration { + return { + enabled: options === true, + compiler: 'vue-template-compiler', + ...(typeof options === 'object' ? options : {}), + }; +} + +export { TypeScriptVueExtensionConfiguration, createTypeScriptVueExtensionConfiguration }; diff --git a/src/typescript-reporter/extension/vue/TypeScriptVueExtensionOptions.ts b/src/typescript-reporter/extension/vue/TypeScriptVueExtensionOptions.ts new file mode 100644 index 00000000..d92beff4 --- /dev/null +++ b/src/typescript-reporter/extension/vue/TypeScriptVueExtensionOptions.ts @@ -0,0 +1,8 @@ +type TypeScriptVueExtensionOptions = + | boolean + | { + enabled?: boolean; + compiler?: string; + }; + +export { TypeScriptVueExtensionOptions }; diff --git a/src/typescript-reporter/extension/vue/assertVueSupport.ts b/src/typescript-reporter/extension/vue/assertVueSupport.ts new file mode 100644 index 00000000..966127da --- /dev/null +++ b/src/typescript-reporter/extension/vue/assertVueSupport.ts @@ -0,0 +1,17 @@ +import { TypeScriptVueExtensionConfiguration } from './TypeScriptVueExtensionConfiguration'; + +function assertVueSupport(configuration: TypeScriptVueExtensionConfiguration) { + // We need to import template compiler for vue lazily because it cannot be included it + // as direct dependency because it is an optional dependency of fork-ts-checker-webpack-plugin. + // Since its version must not mismatch with user-installed Vue.js, + // we should let the users install template compiler for vue by themselves. + const compilerName = configuration.compiler; + + try { + require(compilerName); + } catch (err) { + throw new Error('When you use `vue` option, make sure to install `' + compilerName + '`.'); + } +} + +export { assertVueSupport }; diff --git a/src/typescript-reporter/extension/vue/types/vue-template-compiler.d.ts b/src/typescript-reporter/extension/vue/types/vue-template-compiler.d.ts new file mode 100644 index 00000000..92d1ac9d --- /dev/null +++ b/src/typescript-reporter/extension/vue/types/vue-template-compiler.d.ts @@ -0,0 +1,30 @@ +/** + * This declaration is copied from https://github.com/vuejs/vue/pull/7918 + * which may included vue-template-compiler v2.6.0. + */ +declare module 'vue-template-compiler' { + interface SFCParserOptions { + pad?: true | 'line' | 'space'; + } + + export interface SFCBlock { + type: string; + content: string; + attrs: Record; + start?: number; + end?: number; + lang?: string; + src?: string; + scoped?: boolean; + module?: string | boolean; + } + + export interface SFCDescriptor { + template: SFCBlock | undefined; + script: SFCBlock | undefined; + styles: SFCBlock[]; + customBlocks: SFCBlock[]; + } + + export function parseComponent(file: string, options?: SFCParserOptions): SFCDescriptor; +} diff --git a/src/typescript-reporter/issue/TypeScriptIssueFactory.ts b/src/typescript-reporter/issue/TypeScriptIssueFactory.ts new file mode 100644 index 00000000..6dfb8506 --- /dev/null +++ b/src/typescript-reporter/issue/TypeScriptIssueFactory.ts @@ -0,0 +1,50 @@ +import * as ts from 'typescript'; +import * as os from 'os'; +import { deduplicateAndSortIssues, Issue, IssueLocation } from '../../issue'; + +function createIssueFromTsDiagnostic(diagnostic: ts.Diagnostic): Issue { + let file: string | undefined; + let location: IssueLocation | undefined; + + if (diagnostic.file) { + file = diagnostic.file.fileName; + + if (diagnostic.start && diagnostic.length) { + const { + line: startLine, + character: startCharacter, + } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start); + const { + line: endLine, + character: endCharacter, + } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start + diagnostic.length); + + location = { + start: { + line: startLine + 1, + column: startCharacter + 1, + }, + end: { + line: endLine + 1, + column: endCharacter + 1, + }, + }; + } + } + + return { + origin: 'typescript', + code: 'TS' + String(diagnostic.code), + // we don't handle Suggestion and Message diagnostics + severity: diagnostic.category === 0 ? 'warning' : 'error', + message: ts.flattenDiagnosticMessageText(diagnostic.messageText, os.EOL), + file, + location, + }; +} + +function createIssuesFromTsDiagnostics(diagnostic: ts.Diagnostic[]): Issue[] { + return deduplicateAndSortIssues(diagnostic.map(createIssueFromTsDiagnostic)); +} + +export { createIssuesFromTsDiagnostics }; diff --git a/src/typescript-reporter/reporter/ControlledWatchCompilerHost.ts b/src/typescript-reporter/reporter/ControlledWatchCompilerHost.ts new file mode 100644 index 00000000..36a9a86d --- /dev/null +++ b/src/typescript-reporter/reporter/ControlledWatchCompilerHost.ts @@ -0,0 +1,181 @@ +import { dirname } from 'path'; +import * as ts from 'typescript'; +import { TypeScriptHostExtension } from '../extension/TypeScriptExtension'; +import { ControlledWatchHost } from './ControlledWatchHost'; + +interface ControlledWatchCompilerHost + extends ts.WatchCompilerHostOfConfigFile, + ControlledWatchHost {} + +function createControlledWatchCompilerHost( + configFileName: string, + optionsToExtend: ts.CompilerOptions | undefined, + system: ts.System, + createProgram?: ts.CreateProgram, + reportDiagnostic?: ts.DiagnosticReporter, + reportWatchStatus?: ts.WatchStatusReporter, + afterProgramCreate?: (program: TProgram) => void, + hostExtensions: TypeScriptHostExtension[] = [] +): ControlledWatchCompilerHost { + const watchCompilerHost = ts.createWatchCompilerHost( + configFileName, + optionsToExtend, + system, + createProgram, + reportDiagnostic, + reportWatchStatus + ); + + const fileWatchers = new Map(); + const directoryWatchers = new Map(); + const recursiveDirectoryWatchers = new Map(); + const sourceFileCache = new Map(); + + const parsedCommendLine = ts.getParsedCommandLineOfConfigFile( + configFileName, + optionsToExtend || {}, + { + fileExists: watchCompilerHost.fileExists, + readFile: watchCompilerHost.readFile, + readDirectory: watchCompilerHost.readDirectory, + useCaseSensitiveFileNames: watchCompilerHost.useCaseSensitiveFileNames(), + getCurrentDirectory: watchCompilerHost.getCurrentDirectory, + trace: watchCompilerHost.trace, + // it's already registered in the watchCompilerHost + onUnRecoverableConfigFileDiagnostic: () => null, + } + ); + + const invokeFileWatchers = (path: string, event: ts.FileWatcherEventKind) => { + const fileWatcher = fileWatchers.get(path); + + if (fileWatcher) { + fileWatcher(path, event); + } + }; + + const invokeDirectoryWatchers = (path: string) => { + let key = dirname(path.toLowerCase()); + + const directoryWatcher = directoryWatchers.get(key); + if (directoryWatcher) { + directoryWatcher(path); + } + + while (key !== dirname(key)) { + const recursiveDirectoryWatcher = recursiveDirectoryWatchers.get(key); + if (recursiveDirectoryWatcher) { + recursiveDirectoryWatcher(path); + } + + key = dirname(key); + } + }; + + let controlledWatchCompilerHost: ControlledWatchCompilerHost = { + ...watchCompilerHost, + createProgram( + rootNames: ReadonlyArray | undefined, + options: ts.CompilerOptions | undefined, + compilerHost?: ts.CompilerHost, + oldProgram?: TProgram, + configFileParsingDiagnostics?: ReadonlyArray, + projectReferences?: ReadonlyArray | undefined + ): TProgram { + // as compilerHost is optional, ensure that we have it + if (!compilerHost) { + if (!options) { + options = parsedCommendLine ? parsedCommendLine.options : undefined; + } + + if (options) { + compilerHost = ts.createCompilerHost(options); + } + } + + hostExtensions.forEach((hostExtension) => { + if (compilerHost && hostExtension.extendCompilerHost) { + compilerHost = hostExtension.extendCompilerHost(compilerHost, parsedCommendLine); + } + }); + + return watchCompilerHost.createProgram( + rootNames, + options, + compilerHost, + oldProgram, + configFileParsingDiagnostics, + projectReferences + ); + }, + onWatchStatusChange(): void { + // do nothing + }, + afterProgramCreate(program) { + if (afterProgramCreate) { + afterProgramCreate(program); + } + }, + watchFile(path: string, callback: ts.FileWatcherCallback): ts.FileWatcher { + const key = path.toLowerCase(); + fileWatchers.set(key, callback); + + return { + close: () => fileWatchers.delete(key), + }; + }, + watchDirectory( + path: string, + callback: ts.DirectoryWatcherCallback, + recursive = false + ): ts.FileWatcher { + const key = path.toLowerCase(); + + if (recursive) { + recursiveDirectoryWatchers.set(key, callback); + return { + close: () => recursiveDirectoryWatchers.delete(key), + }; + } else { + directoryWatchers.set(key, callback); + return { + close: () => directoryWatchers.delete(key), + }; + } + }, + // use immediate instead of timeout to avoid waiting 250ms for batching files changes + setTimeout: (callback, timeout, ...args) => setImmediate(() => callback(...args)), + clearTimeout: (timeoutId) => clearImmediate(timeoutId), + invokeFileCreated(path: string) { + sourceFileCache.delete(path); + + invokeDirectoryWatchers(path); + invokeFileWatchers(path, ts.FileWatcherEventKind.Created); + }, + invokeFileChanged(path: string) { + sourceFileCache.delete(path); + + invokeDirectoryWatchers(path); + invokeFileWatchers(path, ts.FileWatcherEventKind.Changed); + }, + invokeFileDeleted(path: string) { + sourceFileCache.delete(path); + + invokeDirectoryWatchers(path); + invokeFileWatchers(path, ts.FileWatcherEventKind.Deleted); + }, + }; + + hostExtensions.forEach((hostExtension) => { + if (hostExtension.extendWatchCompilerHost) { + controlledWatchCompilerHost = hostExtension.extendWatchCompilerHost< + TProgram, + ControlledWatchCompilerHost + >(controlledWatchCompilerHost, parsedCommendLine); + } + }); + + return controlledWatchCompilerHost; +} + +export { createControlledWatchCompilerHost, ControlledWatchCompilerHost }; diff --git a/src/typescript-reporter/reporter/ControlledWatchHost.ts b/src/typescript-reporter/reporter/ControlledWatchHost.ts new file mode 100644 index 00000000..d6d96265 --- /dev/null +++ b/src/typescript-reporter/reporter/ControlledWatchHost.ts @@ -0,0 +1,7 @@ +interface ControlledWatchHost { + invokeFileCreated: (path: string) => void; + invokeFileChanged: (path: string) => void; + invokeFileDeleted: (path: string) => void; +} + +export { ControlledWatchHost }; diff --git a/src/typescript-reporter/reporter/ControlledWatchSolutionBuilderHost.ts b/src/typescript-reporter/reporter/ControlledWatchSolutionBuilderHost.ts new file mode 100644 index 00000000..fb78fb93 --- /dev/null +++ b/src/typescript-reporter/reporter/ControlledWatchSolutionBuilderHost.ts @@ -0,0 +1,107 @@ +import * as ts from 'typescript'; +import fs from 'graceful-fs'; +import { createControlledWatchCompilerHost } from './ControlledWatchCompilerHost'; +import { ControlledWatchHost } from './ControlledWatchHost'; +import { TypeScriptHostExtension } from '../extension/TypeScriptExtension'; + +interface ControlledWatchSolutionBuilderHost + extends ts.SolutionBuilderWithWatchHost, + ControlledWatchHost {} + +function createControlledWatchSolutionBuilderHost( + configFileName: string, + optionsToExtend: ts.CompilerOptions | undefined, + system: ts.System, + createProgram?: ts.CreateProgram, + reportDiagnostic?: ts.DiagnosticReporter, + reportWatchStatus?: ts.WatchStatusReporter, + reportSolutionBuilderStatus?: (diagnostic: ts.Diagnostic) => void, + afterProgramCreate?: (program: TProgram) => void, + afterProgramEmitAndDiagnostics?: (program: TProgram) => void, + hostExtensions: TypeScriptHostExtension[] = [] +): ControlledWatchSolutionBuilderHost { + const controlledWatchCompilerHost = createControlledWatchCompilerHost( + configFileName, + optionsToExtend, + system, + createProgram, + reportDiagnostic, + reportWatchStatus, + afterProgramCreate, + hostExtensions + ); + + let controlledWatchSolutionBuilderHost: ControlledWatchSolutionBuilderHost = { + ...controlledWatchCompilerHost, + writeFile(path: string, data: string, writeByteOrderMark?: boolean): void { + // return ts.sys.writeFile(fileName, data, writeByteOrderMark); + }, + deleteFile(path: string): void { + // if (ts.sys.deleteFile) { + // ts.sys.deleteFile(fileName); + // } else { + // fs.unlinkSync(fileName); + // } + }, + createDirectory(path: string): void { + // do nothing + }, + getModifiedTime(fileName: string): Date | undefined { + if (ts.sys.getModifiedTime) { + return ts.sys.getModifiedTime(fileName); + } else { + return fs.statSync(fileName).mtime; + } + }, + setModifiedTime(path: string, date: Date): void { + // if (ts.sys.setModifiedTime) { + // ts.sys.setModifiedTime(fileName, date); + // } else { + // fs.utimesSync(fileName, date, date); + // } + }, + reportDiagnostic(diagnostic: ts.Diagnostic): void { + if (reportDiagnostic) { + reportDiagnostic(diagnostic); + } + }, + reportSolutionBuilderStatus(diagnostic: ts.Diagnostic): void { + if (reportSolutionBuilderStatus) { + reportSolutionBuilderStatus(diagnostic); + } + }, + afterProgramEmitAndDiagnostics(program): void { + if (afterProgramEmitAndDiagnostics) { + afterProgramEmitAndDiagnostics(program); + } + }, + }; + + const parsedCommendLine = ts.getParsedCommandLineOfConfigFile( + configFileName, + optionsToExtend || {}, + { + fileExists: controlledWatchCompilerHost.fileExists, + readFile: controlledWatchCompilerHost.readFile, + readDirectory: controlledWatchCompilerHost.readDirectory, + useCaseSensitiveFileNames: controlledWatchCompilerHost.useCaseSensitiveFileNames(), + getCurrentDirectory: controlledWatchCompilerHost.getCurrentDirectory, + trace: controlledWatchCompilerHost.trace, + // it's already registered in the watchCompilerHost + onUnRecoverableConfigFileDiagnostic: () => null, + } + ); + + hostExtensions.forEach((hostExtension) => { + if (hostExtension.extendWatchSolutionBuilderHost) { + controlledWatchSolutionBuilderHost = hostExtension.extendWatchSolutionBuilderHost< + TProgram, + ControlledWatchSolutionBuilderHost + >(controlledWatchSolutionBuilderHost, parsedCommendLine); + } + }); + + return controlledWatchSolutionBuilderHost; +} + +export { ControlledWatchSolutionBuilderHost, createControlledWatchSolutionBuilderHost }; diff --git a/src/typescript-reporter/reporter/TypeScriptReporter.ts b/src/typescript-reporter/reporter/TypeScriptReporter.ts new file mode 100644 index 00000000..11b016f7 --- /dev/null +++ b/src/typescript-reporter/reporter/TypeScriptReporter.ts @@ -0,0 +1,161 @@ +import * as ts from 'typescript'; +import { FilesChange, Reporter } from '../../reporter'; +import { createIssuesFromTsDiagnostics } from '../issue/TypeScriptIssueFactory'; +import { TypeScriptReporterConfiguration } from '../TypeScriptReporterConfiguration'; +import { createControlledWatchCompilerHost } from './ControlledWatchCompilerHost'; +import { TypeScriptExtension } from '../extension/TypeScriptExtension'; +import { createTypeScriptReporterState, TypeScriptReporterState } from './TypeScriptReporterState'; +import { createTypeScriptVueExtension } from '../extension/vue/TypeScriptVueExtension'; +import { createTypeScriptPnpExtension } from '../extension/pnp/TypeScriptPnpExtension'; +import { createControlledWatchSolutionBuilderHost } from './ControlledWatchSolutionBuilderHost'; +import { ControlledWatchHost } from './ControlledWatchHost'; + +function createTypeScriptReporter(configuration: TypeScriptReporterConfiguration): Reporter { + const extensions: TypeScriptExtension[] = []; + const state: TypeScriptReporterState = createTypeScriptReporterState(); + + if (configuration.extensions.vue.enabled) { + extensions.push(createTypeScriptVueExtension(configuration.extensions.vue)); + } + if (configuration.extensions.pnp.enabled) { + extensions.push(createTypeScriptPnpExtension()); + } + + function getProjectNameOfBuilderProgram(builderProgram: ts.BuilderProgram): string { + // TODO: it's not a public API - ensure support on different TypeScript versions + return (builderProgram.getProgram().getCompilerOptions().configFilePath as unknown) as string; + } + + function getDiagnosticsOfBuilderProgram(builderProgram: ts.BuilderProgram) { + const diagnostics: ts.Diagnostic[] = []; + + diagnostics.push(...builderProgram.getConfigFileParsingDiagnostics()); + if (configuration.diagnosticOptions.syntactic) { + diagnostics.push(...builderProgram.getSyntacticDiagnostics()); + } + if (configuration.diagnosticOptions.semantic) { + diagnostics.push(...builderProgram.getSemanticDiagnostics()); + } + if (configuration.diagnosticOptions.declaration) { + diagnostics.push(...builderProgram.getDeclarationDiagnostics()); + } + if (configuration.diagnosticOptions.global) { + diagnostics.push(...builderProgram.getGlobalDiagnostics()); + } + + return diagnostics; + } + + async function invokeFilesChangeOnControlledHost( + controlledHost: ControlledWatchHost, + { createdFiles = [], changedFiles = [], deletedFiles = [] }: FilesChange + ) { + createdFiles.forEach((createdFile) => { + controlledHost.invokeFileCreated(createdFile); + }); + changedFiles.forEach((changedFile) => { + controlledHost.invokeFileChanged(changedFile); + }); + deletedFiles.forEach((removedFile) => { + controlledHost.invokeFileDeleted(removedFile); + }); + + // wait for watch events to be propagated + await new Promise((resolve) => setImmediate(resolve)); + } + + return { + getReport: async (filesChange) => { + if (configuration.build) { + // solution builder case + // ensure watch solution builder host exists + if (!state.watchSolutionBuilderHost) { + state.watchSolutionBuilderHost = createControlledWatchSolutionBuilderHost( + configuration.tsconfig, + configuration.compilerOptions as ts.CompilerOptions, // assume that these are valid ts.CompilerOptions + ts.sys, + ts.createSemanticDiagnosticsBuilderProgram, + undefined, + undefined, + undefined, + undefined, + (builderProgram) => { + const projectName = getProjectNameOfBuilderProgram(builderProgram); + const diagnostics = getDiagnosticsOfBuilderProgram(builderProgram); + + // update diagnostics + state.diagnosticsPreProject[projectName] = diagnostics; + }, + extensions + ); + state.solutionBuilder = undefined; + } + + // ensure solution builder exists + if (!state.solutionBuilder) { + state.solutionBuilder = ts.createSolutionBuilderWithWatch( + state.watchSolutionBuilderHost, + [configuration.tsconfig], + { + incremental: true, + verbose: true, + } + ); + state.solutionBuilder.build(); + } + + // invoke files changes on the host + await invokeFilesChangeOnControlledHost(state.watchSolutionBuilderHost, filesChange); + + // await new Promise((resolve) => setTimeout(resolve, 200)); + } else { + // watch compiler case + // ensure watch compiler host exists + if (!state.watchCompilerHost) { + state.watchCompilerHost = createControlledWatchCompilerHost( + configuration.tsconfig, + configuration.compilerOptions as ts.CompilerOptions, // assume that these are valid ts.CompilerOptions + ts.sys, + ts.createSemanticDiagnosticsBuilderProgram, + undefined, + undefined, + (builderProgram) => { + const projectName = getProjectNameOfBuilderProgram(builderProgram); + const diagnostics = getDiagnosticsOfBuilderProgram(builderProgram); + + // update diagnostics + state.diagnosticsPreProject[projectName] = diagnostics; + }, + extensions + ); + state.watchProgram = undefined; + } + + // ensure watch program exists + if (!state.watchProgram) { + state.watchProgram = ts.createWatchProgram(state.watchCompilerHost); + } + + // invoke files changes on the host + await invokeFilesChangeOnControlledHost(state.watchCompilerHost, filesChange); + } + + // aggregate all diagnostics and map them to issues + const diagnostics = Object.keys(state.diagnosticsPreProject).reduce( + (allDiagnostics, project) => [...allDiagnostics, ...state.diagnosticsPreProject[project]], + [] + ); + let issues = createIssuesFromTsDiagnostics(diagnostics); + + extensions.forEach((extension) => { + if (extension.extendIssues) { + issues = extension.extendIssues(issues); + } + }); + + return issues; + }, + }; +} + +export { createTypeScriptReporter }; diff --git a/src/typescript-reporter/reporter/TypeScriptReporterRpcClient.ts b/src/typescript-reporter/reporter/TypeScriptReporterRpcClient.ts new file mode 100644 index 00000000..8e7778e0 --- /dev/null +++ b/src/typescript-reporter/reporter/TypeScriptReporterRpcClient.ts @@ -0,0 +1,36 @@ +import * as path from 'path'; +import { TypeScriptReporterConfiguration } from '../TypeScriptReporterConfiguration'; +import { + createReporterRpcClient, + registerReporterRpcService, + ReporterRpcClient, +} from '../../reporter'; +import { createRpcIpcMessageChannel } from '../../rpc/rpc-ipc'; +import { createRpcEventEmitterMessageChannel } from '../../rpc/rpc-event-emitter'; +import { createTypeScriptReporter } from './TypeScriptReporter'; + +function createTypeScriptReporterRpcClient( + configuration: TypeScriptReporterConfiguration +): ReporterRpcClient { + const channel = createRpcIpcMessageChannel( + path.resolve(__dirname, './TypeScriptReporterRpcService.js'), + configuration.memoryLimit + ); + + return createReporterRpcClient(channel, configuration); +} + +function createTypeScriptReporterSameProcessRpcClient( + configuration: TypeScriptReporterConfiguration +): ReporterRpcClient { + const channel = createRpcEventEmitterMessageChannel(); + const service = registerReporterRpcService( + channel.servicePort, + (configuration) => createTypeScriptReporter(configuration) + ); + service.open(); + + return createReporterRpcClient(channel, configuration); +} + +export { createTypeScriptReporterRpcClient, createTypeScriptReporterSameProcessRpcClient }; diff --git a/src/typescript-reporter/reporter/TypeScriptReporterRpcService.ts b/src/typescript-reporter/reporter/TypeScriptReporterRpcService.ts new file mode 100644 index 00000000..2fcb0a82 --- /dev/null +++ b/src/typescript-reporter/reporter/TypeScriptReporterRpcService.ts @@ -0,0 +1,12 @@ +import process from 'process'; +import { createTypeScriptReporter } from './TypeScriptReporter'; +import { TypeScriptReporterConfiguration } from '../TypeScriptReporterConfiguration'; +import { createRpcIpcMessagePort } from '../../rpc/rpc-ipc'; +import { registerReporterRpcService } from '../../reporter'; + +const service = registerReporterRpcService( + createRpcIpcMessagePort(process), + createTypeScriptReporter +); + +service.open(); diff --git a/src/typescript-reporter/reporter/TypeScriptReporterState.ts b/src/typescript-reporter/reporter/TypeScriptReporterState.ts new file mode 100644 index 00000000..f1662cc1 --- /dev/null +++ b/src/typescript-reporter/reporter/TypeScriptReporterState.ts @@ -0,0 +1,28 @@ +import * as ts from 'typescript'; +import { ControlledWatchCompilerHost } from './ControlledWatchCompilerHost'; +import { ControlledWatchSolutionBuilderHost } from './ControlledWatchSolutionBuilderHost'; + +/** + * Contains all information that are passed between `run` calls + */ +interface TypeScriptReporterState { + watchCompilerHost?: ControlledWatchCompilerHost; + watchSolutionBuilderHost?: ControlledWatchSolutionBuilderHost< + ts.SemanticDiagnosticsBuilderProgram + >; + watchProgram?: ts.WatchOfConfigFile; + solutionBuilder?: ts.SolutionBuilder; + diagnosticsPreProject: Record; +} + +function createTypeScriptReporterState(): TypeScriptReporterState { + return { + watchCompilerHost: undefined, + watchSolutionBuilderHost: undefined, + watchProgram: undefined, + solutionBuilder: undefined, + diagnosticsPreProject: {}, + }; +} + +export { TypeScriptReporterState, createTypeScriptReporterState }; diff --git a/src/utils/array/flatten.ts b/src/utils/array/flatten.ts new file mode 100644 index 00000000..47c7214d --- /dev/null +++ b/src/utils/array/flatten.ts @@ -0,0 +1,5 @@ +function flatten(matrix: T[][]): T[] { + return matrix.reduce((flatten, array) => flatten.concat(array), []); +} + +export default flatten; diff --git a/src/utils/array/intersect.ts b/src/utils/array/intersect.ts new file mode 100644 index 00000000..de997cdc --- /dev/null +++ b/src/utils/array/intersect.ts @@ -0,0 +1,5 @@ +function intersect(arrayA: T[] = [], arrayB: T[] = []): T[] { + return arrayA.filter((item) => arrayB.includes(item)); +} + +export default intersect; diff --git a/src/utils/array/substract.ts b/src/utils/array/substract.ts new file mode 100644 index 00000000..2927c00d --- /dev/null +++ b/src/utils/array/substract.ts @@ -0,0 +1,5 @@ +function subtract(arrayA: T[] = [], arrayB: T[] = []): T[] { + return arrayA.filter((item) => !arrayB.includes(item)); +} + +export default subtract; diff --git a/src/utils/array/unique.ts b/src/utils/array/unique.ts new file mode 100644 index 00000000..3091fd5f --- /dev/null +++ b/src/utils/array/unique.ts @@ -0,0 +1,5 @@ +function unique(array: T[]): T[] { + return Array.from(new Set(array)); +} + +export default unique; diff --git a/src/utils/async/isPending.ts b/src/utils/async/isPending.ts new file mode 100644 index 00000000..ae333d87 --- /dev/null +++ b/src/utils/async/isPending.ts @@ -0,0 +1,8 @@ +function isPending(promise: Promise, timeout = 100) { + return Promise.race([ + promise.then(() => false).catch(() => false), + new Promise((resolve) => setTimeout(() => resolve(true), timeout)), + ]); +} + +export default isPending; diff --git a/src/utils/async/wait.ts b/src/utils/async/wait.ts new file mode 100644 index 00000000..7af1d6fa --- /dev/null +++ b/src/utils/async/wait.ts @@ -0,0 +1,5 @@ +function wait(timeout: number) { + return new Promise((resolve) => setTimeout(resolve, timeout)); +} + +export default wait; diff --git a/src/utils/fs/isFileJustCreated.ts b/src/utils/fs/isFileJustCreated.ts new file mode 100644 index 00000000..4d67f3ef --- /dev/null +++ b/src/utils/fs/isFileJustCreated.ts @@ -0,0 +1,9 @@ +import fs from 'graceful-fs'; + +function isFileJustCreated(fileName: string): boolean { + const stat = fs.statSync(fileName); + + return stat.birthtimeMs === stat.mtimeMs; +} + +export default isFileJustCreated; diff --git a/test/.DS_Store b/test/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..2d83471ac54550b2779cbe9f6dbb2a2b2d43bc33 GIT binary patch literal 6148 zcmeHK!EVz)5S?vY*rY<_fYcs+LE=!Mlma;*BrB9dZ%9UP0My#Vw3gi6D0T=X1o^^0 z0Dr)z@CAGb9{_K57l;$Ma6l;9k!Ig`_s!b-9M5KnNDL;!J)$lVNjPKBLGv5qarPD4 za6LRI%p4OMQ%2=sp`Wj?eTP@TEAYQ5U_b5`l+!D!XyN-!3!UO&xiH*;U;AdvJieqQ zemX5jj{i9w6?s|pdSApwE7-hnQOb_&T8lJOJ1dXQA7sf!$ z!&$%IL%e@`K5xtIt9y43kI&9u&)&@6elSZRfx>0%vcn(n5y8qrU&doqXmx@y&f9`) z3bJK%g2I;|%1M*r^0y%0Cor4xmB?VRM|2%%%H=P<*k0ndz&WE)b5`+giM0vVIc9X_ zcVWJ-OUwXwR(R5?Iiq>a?-yP((!8y+0`8|Tx7K-)er;X>ufSg^!1W=7Ge!<;i>7p- zF-HJkfNo=m`7Z7JP74Ql)6=>PZF7N;M|9t*$CiyF`fLCCx6cE8dd@#V0+}^sfINobR_%WP~ od9_88g2rvfCg81j2W|{wAqT+7VQmpTF#kuu$lx2Vz&};sJDBI6ivR!s literal 0 HcmV?d00001 diff --git a/test/fixtures/.DS_Store b/test/fixtures/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5c757dffb436bbd4b73c69cf7467da446192b94e GIT binary patch literal 6148 zcmeHK&2AGh5FRI?b%JPfsMH?!g2bVRl>X#^kXC6q^j2vR8~~-e$%<~ZT}RnXBS?ex z!b89t@F+Y1j{~3WNkx)|BdWk7jlc1D#`b>Rwbw)>I-~v`QIm)yRAZ%%;ttX6T9>54 zo;9E_eFPL!MmZ%^EJZuVePlqd-4^vI#Hz*g`}!qx4bK@3Nzo;&9u=pl>P4xFkfUFi zXV51%tuofW8{?L-N_b5659*8Rm^Qf@%((m=ewh#aX#Q#e~$)f zk{7Mk4^gSs9;~fP*^rG#jd#I?8V5yKjPg!6e4}e;VQ~?${Zgs))()drNj&a0w~kd- zgh>_;O>)wY5%TtRlJ(WNqefXjH~j>*LCU(Ucbhwt$$q=N>m58jobGy)cDn_8|7bd` z%k9T|&ri>qUTmKM1$CVauQ(%~*7_s^&-hmo{-_r)rXDltk193kB Nh6YzS2L37ozX0%Vhq?d& literal 0 HcmV?d00001 diff --git a/test/integration/helpers/rpc.js b/test/integration/helpers/rpc.js index 582e7750..15aaac60 100644 --- a/test/integration/helpers/rpc.js +++ b/test/integration/helpers/rpc.js @@ -22,7 +22,7 @@ exports.getRpcProvider = () => { return process.send(message); } }); - process.on('message', message => rpc.dispatch(message)); + process.on('message', message => rpc.dispatchCall(message)); } return rpc; diff --git a/tsconfig.json b/tsconfig.json index 24f93451..baa9de85 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,13 +1,18 @@ { "compilerOptions": { "target": "es5", + "module": "commonjs", "esModuleInterop": true, "skipLibCheck": true, + "skipDefaultLibCheck": true, "strict": true, + "declaration": true, + "resolveJsonModule": true, "lib": ["es2015"], - "importHelpers": true, - "module": "commonjs", "moduleResolution": "node", - "sourceMap": true - } + "sourceMap": true, + "baseUrl": "./src", + "outDir": "./lib" + }, + "include": ["./src"] } diff --git a/yarn.lock b/yarn.lock index 505fb550..16a0890e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8,13 +8,34 @@ dependencies: "@babel/highlight" "^7.0.0" -"@babel/code-frame@^7.5.5": +"@babel/code-frame@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e" integrity sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g== dependencies: "@babel/highlight" "^7.8.3" +"@babel/core@7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.8.4.tgz#d496799e5c12195b3602d0fddd77294e3e38e80e" + integrity sha512-0LiLrB2PwrVI+a2/IEskBopDYSd8BCb3rOvH7D5tzoWd696TBEduBvuLVm4Nx6rltrLZqvI3MCalB2K2aVzQjA== + dependencies: + "@babel/code-frame" "^7.8.3" + "@babel/generator" "^7.8.4" + "@babel/helpers" "^7.8.4" + "@babel/parser" "^7.8.4" + "@babel/template" "^7.8.3" + "@babel/traverse" "^7.8.4" + "@babel/types" "^7.8.3" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.1" + json5 "^2.1.0" + lodash "^4.17.13" + resolve "^1.3.2" + semver "^5.4.1" + source-map "^0.5.0" + "@babel/core@^7.1.0": version "7.4.4" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.4.4.tgz#84055750b05fcd50f9915a826b44fa347a825250" @@ -35,7 +56,29 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.0.0", "@babel/generator@^7.4.4": +"@babel/core@^7.7.5": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.9.0.tgz#ac977b538b77e132ff706f3b8a4dbad09c03c56e" + integrity sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w== + dependencies: + "@babel/code-frame" "^7.8.3" + "@babel/generator" "^7.9.0" + "@babel/helper-module-transforms" "^7.9.0" + "@babel/helpers" "^7.9.0" + "@babel/parser" "^7.9.0" + "@babel/template" "^7.8.6" + "@babel/traverse" "^7.9.0" + "@babel/types" "^7.9.0" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.1" + json5 "^2.1.2" + lodash "^4.17.13" + resolve "^1.3.2" + semver "^5.4.1" + source-map "^0.5.0" + +"@babel/generator@^7.4.4": version "7.4.4" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.4.4.tgz#174a215eb843fc392c7edcaabeaa873de6e8f041" integrity sha512-53UOLK6TVNqKxf7RUh8NE851EHRxOOeVXKbK2bivdb+iziMyk03Sr4eaE9OELCbyZAAafAKPDwF2TPUES5QbxQ== @@ -46,6 +89,26 @@ source-map "^0.5.0" trim-right "^1.0.1" +"@babel/generator@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.8.4.tgz#35bbc74486956fe4251829f9f6c48330e8d0985e" + integrity sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA== + dependencies: + "@babel/types" "^7.8.3" + jsesc "^2.5.1" + lodash "^4.17.13" + source-map "^0.5.0" + +"@babel/generator@^7.9.0", "@babel/generator@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.9.5.tgz#27f0917741acc41e6eaaced6d68f96c3fa9afaf9" + integrity sha512-GbNIxVB3ZJe3tLeDm1HSn2AhuD/mVcyLDpgtLXa5tplmWrJdF/elxB56XNqCuD6szyNkDi6wuoKXln3QeBmCHQ== + dependencies: + "@babel/types" "^7.9.5" + jsesc "^2.5.1" + lodash "^4.17.13" + source-map "^0.5.0" + "@babel/helper-function-name@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz#a0ceb01685f73355d4360c1247f582bfafc8ff53" @@ -55,6 +118,24 @@ "@babel/template" "^7.1.0" "@babel/types" "^7.0.0" +"@babel/helper-function-name@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz#eeeb665a01b1f11068e9fb86ad56a1cb1a824cca" + integrity sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA== + dependencies: + "@babel/helper-get-function-arity" "^7.8.3" + "@babel/template" "^7.8.3" + "@babel/types" "^7.8.3" + +"@babel/helper-function-name@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz#2b53820d35275120e1874a82e5aabe1376920a5c" + integrity sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw== + dependencies: + "@babel/helper-get-function-arity" "^7.8.3" + "@babel/template" "^7.8.3" + "@babel/types" "^7.9.5" + "@babel/helper-get-function-arity@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz#83572d4320e2a4657263734113c42868b64e49c3" @@ -62,11 +143,75 @@ dependencies: "@babel/types" "^7.0.0" +"@babel/helper-get-function-arity@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz#b894b947bd004381ce63ea1db9f08547e920abd5" + integrity sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-member-expression-to-functions@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz#659b710498ea6c1d9907e0c73f206eee7dadc24c" + integrity sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-module-imports@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz#7fe39589b39c016331b6b8c3f441e8f0b1419498" + integrity sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-module-transforms@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz#43b34dfe15961918707d247327431388e9fe96e5" + integrity sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA== + dependencies: + "@babel/helper-module-imports" "^7.8.3" + "@babel/helper-replace-supers" "^7.8.6" + "@babel/helper-simple-access" "^7.8.3" + "@babel/helper-split-export-declaration" "^7.8.3" + "@babel/template" "^7.8.6" + "@babel/types" "^7.9.0" + lodash "^4.17.13" + +"@babel/helper-optimise-call-expression@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz#7ed071813d09c75298ef4f208956006b6111ecb9" + integrity sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-plugin-utils@7.8.3", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz#9ea293be19babc0f52ff8ca88b34c3611b208670" + integrity sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ== + "@babel/helper-plugin-utils@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz#bbb3fbee98661c569034237cc03967ba99b4f250" integrity sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA== +"@babel/helper-replace-supers@^7.8.6": + version "7.8.6" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.8.6.tgz#5ada744fd5ad73203bf1d67459a27dcba67effc8" + integrity sha512-PeMArdA4Sv/Wf4zXwBKPqVj7n9UF/xg6slNRtZW84FM7JpE1CbG8B612FyM4cxrf4fMAMGO0kR7voy1ForHHFA== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.8.3" + "@babel/helper-optimise-call-expression" "^7.8.3" + "@babel/traverse" "^7.8.6" + "@babel/types" "^7.8.6" + +"@babel/helper-simple-access@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz#7f8109928b4dab4654076986af575231deb639ae" + integrity sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw== + dependencies: + "@babel/template" "^7.8.3" + "@babel/types" "^7.8.3" + "@babel/helper-split-export-declaration@^7.4.4": version "7.4.4" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz#ff94894a340be78f53f06af038b205c49d993677" @@ -74,7 +219,14 @@ dependencies: "@babel/types" "^7.4.4" -"@babel/helper-validator-identifier@^7.9.0": +"@babel/helper-split-export-declaration@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz#31a9f30070f91368a7182cf05f831781065fc7a9" + integrity sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-validator-identifier@^7.9.5": version "7.9.5" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz#90977a8e6fbf6b431a7dc31752eee233bf052d80" integrity sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g== @@ -88,6 +240,15 @@ "@babel/traverse" "^7.4.4" "@babel/types" "^7.4.4" +"@babel/helpers@^7.8.4", "@babel/helpers@^7.9.0": + version "7.9.2" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.9.2.tgz#b42a81a811f1e7313b88cba8adc66b3d9ae6c09f" + integrity sha512-JwLvzlXVPjO8eU9c/wF9/zOIN7X6h8DYf7mG4CiFRZRvZNKEF5dQ3H3V+ASkHoIB3mWhatgl5ONhyqHRI6MppA== + dependencies: + "@babel/template" "^7.8.3" + "@babel/traverse" "^7.9.0" + "@babel/types" "^7.9.0" + "@babel/highlight@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0.tgz#f710c38c8d458e6dd9a201afb637fcb781ce99e4" @@ -97,27 +258,122 @@ js-tokens "^4.0.0" "@babel/highlight@^7.8.3": - version "7.9.0" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.9.0.tgz#4e9b45ccb82b79607271b2979ad82c7b68163079" - integrity sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ== + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.8.3.tgz#28f173d04223eaaa59bc1d439a3836e6d1265797" + integrity sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg== dependencies: - "@babel/helper-validator-identifier" "^7.9.0" chalk "^2.0.0" + esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.4": +"@babel/parser@^7.1.0", "@babel/parser@^7.4.4": version "7.4.4" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.4.4.tgz#5977129431b8fe33471730d255ce8654ae1250b6" integrity sha512-5pCS4mOsL+ANsFZGdvNLybx4wtqAZJ0MJjMHxvzI3bvIsz6sQvzW8XX92EYIkiPtIvcfG3Aj+Ir5VNyjnZhP7w== -"@babel/plugin-syntax-object-rest-spread@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz#3b7a3e733510c57e820b9142a6579ac8b0dfad2e" - integrity sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA== +"@babel/parser@^7.7.5", "@babel/parser@^7.8.6", "@babel/parser@^7.9.0": + version "7.9.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.9.4.tgz#68a35e6b0319bbc014465be43828300113f2f2e8" + integrity sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA== + +"@babel/parser@^7.8.3", "@babel/parser@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.8.4.tgz#d1dbe64691d60358a974295fa53da074dd2ce8e8" + integrity sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw== + +"@babel/plugin-proposal-object-rest-spread@7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.8.3.tgz#eb5ae366118ddca67bed583b53d7554cad9951bb" + integrity sha512-8qvuPwU/xxUCt78HocNlv0mXXo0wdh9VT1R04WU8HGOfaOob26pF+9P5/lYjN/q7DHOX1bvX60hnhOvuQUJdbA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-object-rest-spread" "^7.8.0" + +"@babel/plugin-syntax-async-generators@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-bigint@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" + integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.8.3.tgz#6cb933a8872c8d359bfde69bbeaae5162fd1e8f7" + integrity sha512-UcAyQWg2bAN647Q+O811tG9MrJ38Z10jjhQdKNAL8fsyPzE3cCN/uT+f55cFVY4aGO4jqJAvmqsuY3GQDwAoXg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" -"@babel/template@^7.0.0", "@babel/template@^7.1.0", "@babel/template@^7.4.4": +"@babel/plugin-syntax-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-jsx@7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.8.3.tgz#521b06c83c40480f1e58b4fd33b92eceb1d6ea94" + integrity sha512-WxdW9xyLgBdefoo0Ynn3MRSkhe5tFVxxKNVdnZSh318WrG2e2jH+E9wd/++JsqcLJZPfz87njQJ8j2Upjm0M0A== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-logical-assignment-operators@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.8.3.tgz#3995d7d7ffff432f6ddc742b47e730c054599897" + integrity sha512-Zpg2Sgc++37kuFl6ppq2Q7Awc6E6AIW671x5PY8E/f7MCIyPPGK/EoeZXvvY3P42exZ3Q4/t3YOzP/HiN79jDg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.8.3.tgz#0e3fb63e09bea1b11e96467271c8308007e7c41f" + integrity sha512-H7dCMAdN83PcCmqmkHB5dtp+Xa9a6LKSvA2hiFBC/5alSHxM5VgWZXFqDi0YFe8XNGT6iCa+z4V4zSt/PdZ7Dw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-object-rest-spread@7.8.3", "@babel/plugin-syntax-object-rest-spread@^7.8.0", "@babel/plugin-syntax-object-rest-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/runtime@^7.8.7": + version "7.9.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.2.tgz#d90df0583a3a252f09aaa619665367bae518db06" + integrity sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/template@^7.1.0", "@babel/template@^7.4.4": version "7.4.4" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.4.4.tgz#f4b88d1225689a08f5bc3a17483545be9e4ed237" integrity sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw== @@ -126,7 +382,25 @@ "@babel/parser" "^7.4.4" "@babel/types" "^7.4.4" -"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.4": +"@babel/template@^7.7.4", "@babel/template@^7.8.6": + version "7.8.6" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.6.tgz#86b22af15f828dfb086474f964dcc3e39c43ce2b" + integrity sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg== + dependencies: + "@babel/code-frame" "^7.8.3" + "@babel/parser" "^7.8.6" + "@babel/types" "^7.8.6" + +"@babel/template@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.3.tgz#e02ad04fe262a657809327f578056ca15fd4d1b8" + integrity sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ== + dependencies: + "@babel/code-frame" "^7.8.3" + "@babel/parser" "^7.8.3" + "@babel/types" "^7.8.3" + +"@babel/traverse@^7.1.0", "@babel/traverse@^7.4.4": version "7.4.4" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.4.4.tgz#0776f038f6d78361860b6823887d4f3937133fe8" integrity sha512-Gw6qqkw/e6AGzlyj9KnkabJX7VcubqPtkUQVAwkc0wUMldr3A/hezNB3Rc5eIvId95iSGkGIOe5hh1kMKf951A== @@ -141,6 +415,36 @@ globals "^11.1.0" lodash "^4.17.11" +"@babel/traverse@^7.7.4", "@babel/traverse@^7.8.6", "@babel/traverse@^7.9.0": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.9.5.tgz#6e7c56b44e2ac7011a948c21e283ddd9d9db97a2" + integrity sha512-c4gH3jsvSuGUezlP6rzSJ6jf8fYjLj3hsMZRx/nX0h+fmHN0w+ekubRrHPqnMec0meycA2nwCsJ7dC8IPem2FQ== + dependencies: + "@babel/code-frame" "^7.8.3" + "@babel/generator" "^7.9.5" + "@babel/helper-function-name" "^7.9.5" + "@babel/helper-split-export-declaration" "^7.8.3" + "@babel/parser" "^7.9.0" + "@babel/types" "^7.9.5" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.13" + +"@babel/traverse@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.8.4.tgz#f0845822365f9d5b0e312ed3959d3f827f869e3c" + integrity sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg== + dependencies: + "@babel/code-frame" "^7.8.3" + "@babel/generator" "^7.8.4" + "@babel/helper-function-name" "^7.8.3" + "@babel/helper-split-export-declaration" "^7.8.3" + "@babel/parser" "^7.8.4" + "@babel/types" "^7.8.3" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.13" + "@babel/types@^7.0.0", "@babel/types@^7.3.0", "@babel/types@^7.4.4": version "7.4.4" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.4.4.tgz#8db9e9a629bb7c29370009b4b779ed93fe57d5f0" @@ -150,6 +454,29 @@ lodash "^4.17.11" to-fast-properties "^2.0.0" +"@babel/types@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.8.3.tgz#5a383dffa5416db1b73dedffd311ffd0788fb31c" + integrity sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg== + dependencies: + esutils "^2.0.2" + lodash "^4.17.13" + to-fast-properties "^2.0.0" + +"@babel/types@^7.8.6", "@babel/types@^7.9.0", "@babel/types@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.9.5.tgz#89231f82915a8a566a703b3b20133f73da6b9444" + integrity sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg== + dependencies: + "@babel/helper-validator-identifier" "^7.9.5" + lodash "^4.17.13" + to-fast-properties "^2.0.0" + +"@bcoe/v8-coverage@^0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" + integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== + "@cnakazawa/watch@^1.0.3": version "1.0.3" resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.3.tgz#099139eaec7ebf07a27c1786a3ff64f39464d2ef" @@ -158,293 +485,306 @@ exec-sh "^0.3.2" minimist "^1.2.0" -"@commitlint/cli@^7.5.2": - version "7.5.2" - resolved "https://registry.yarnpkg.com/@commitlint/cli/-/cli-7.5.2.tgz#2475cd8f7ed3b2f9c2ab96c06bc24d61d23f8716" - integrity sha512-UQdW/wNb+XeANoYYLyuKEDIfWKSzdhJkPQZ8ie/IjfMNnsP+B23bkX4Ati+6U8zgz0yyngoxWl+3lfExiIL4hQ== +"@commitlint/cli@^8.3.5": + version "8.3.5" + resolved "https://registry.yarnpkg.com/@commitlint/cli/-/cli-8.3.5.tgz#6d93a3a8b2437fa978999d3f6a336bcc70be3fd3" + integrity sha512-6+L0vbw55UEdht71pgWOE55SRgb+8OHcEwGDB234VlIBFGK9P2QOBU7MHiYJ5cjdjCQ0rReNrGjOHmJ99jwf0w== dependencies: - "@commitlint/format" "^7.5.0" - "@commitlint/lint" "^7.5.2" - "@commitlint/load" "^7.5.0" - "@commitlint/read" "^7.5.0" + "@commitlint/format" "^8.3.4" + "@commitlint/lint" "^8.3.5" + "@commitlint/load" "^8.3.5" + "@commitlint/read" "^8.3.4" babel-polyfill "6.26.0" - chalk "2.3.1" - get-stdin "5.0.1" - lodash "4.17.11" + chalk "2.4.2" + get-stdin "7.0.0" + lodash "4.17.15" meow "5.0.0" - resolve-from "4.0.0" - resolve-global "0.1.0" + resolve-from "5.0.0" + resolve-global "1.0.0" -"@commitlint/config-conventional@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@commitlint/config-conventional/-/config-conventional-7.5.0.tgz#3afd4e3e34e5c2f6ec6af03e78ae924fed883ce7" - integrity sha512-odLgBfQ5xntFAmMfAmDY2C4EWhW+cSTbvbsRS7seb55DCa3IaxxSHHC9eXrR+hN/BdUT5vqAxdX1PkR996sq9Q== - -"@commitlint/ensure@^7.5.2": - version "7.5.2" - resolved "https://registry.yarnpkg.com/@commitlint/ensure/-/ensure-7.5.2.tgz#57bb7dcbf1e9913e27c3b294325d0d68dd14cebf" - integrity sha512-ZMJKHhSJC789chKy0kWp8EWbCpLPy6vKa+fopUVx+tWL7H8AeBbibXlqAnybg+HWNcb/RD7ORROx0IsgrK4IYA== +"@commitlint/config-conventional@^8.3.4": + version "8.3.4" + resolved "https://registry.yarnpkg.com/@commitlint/config-conventional/-/config-conventional-8.3.4.tgz#fed13b3711690663b176c1f6b39c205a565618d2" + integrity sha512-w0Yc5+aVAjZgjYqx29igBOnVCj8O22gy3Vo6Fyp7PwoS7+AYS1x3sN7IBq6i7Ae15Mv5P+rEx1pkxXo5zOMe4g== dependencies: - lodash "4.17.11" + conventional-changelog-conventionalcommits "4.2.1" -"@commitlint/execute-rule@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@commitlint/execute-rule/-/execute-rule-7.5.0.tgz#c9cfbab71eb962e1c46e78d76375e32754ab1e38" - integrity sha512-K66aoly8mxSHmBA/Y8bKSPPcCAR4GpJEsvHaLDYOG7GsyChu8NgCD53L8GUqPW8lBCWwnmCiSL+RlOkNHJ0Gag== +"@commitlint/ensure@^8.3.4": + version "8.3.4" + resolved "https://registry.yarnpkg.com/@commitlint/ensure/-/ensure-8.3.4.tgz#6931677e4ca0fde71686ae3b7a367261647a341d" + integrity sha512-8NW77VxviLhD16O3EUd02lApMFnrHexq10YS4F4NftNoErKbKaJ0YYedktk2boKrtNRf/gQHY/Qf65edPx4ipw== dependencies: - babel-runtime "6.26.0" + lodash "4.17.15" + +"@commitlint/execute-rule@^8.3.4": + version "8.3.4" + resolved "https://registry.yarnpkg.com/@commitlint/execute-rule/-/execute-rule-8.3.4.tgz#1b63f0713b197889d90b76f9eea1abc010d256b1" + integrity sha512-f4HigYjeIBn9f7OuNv5zh2y5vWaAhNFrfeul8CRJDy82l3Y+09lxOTGxfF3uMXKrZq4LmuK6qvvRCZ8mUrVvzQ== -"@commitlint/format@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@commitlint/format/-/format-7.5.0.tgz#57a2b92dc58a3409b2be67c4c8c10bd1b28e9fe8" - integrity sha512-DEeQXfTLUm9kARliCBfw3SlQRAYjK2aXeRAUMs1HPhLA2tjNFFGv6LOpFFNdiu/WV+o1ojcgIvBBjpHaVT+Tvw== +"@commitlint/format@^8.3.4": + version "8.3.4" + resolved "https://registry.yarnpkg.com/@commitlint/format/-/format-8.3.4.tgz#7cd1f0ba5a3289c8d14d7dac29ee1fc1597fe1d9" + integrity sha512-809wlQ/ND6CLZON+w2Rb3YM2TLNDfU2xyyqpZeqzf2reJNpySMSUAeaO/fNDJSOKIsOsR3bI01rGu6hv28k+Nw== dependencies: - babel-runtime "^6.23.0" chalk "^2.0.1" -"@commitlint/is-ignored@^7.5.1": - version "7.5.1" - resolved "https://registry.yarnpkg.com/@commitlint/is-ignored/-/is-ignored-7.5.1.tgz#c4f7ffc1c8b4cf9dc3204d22ef8e78ff82536d67" - integrity sha512-8JZCgy6bWSnjOT5cTTiyEAGp+Y4+5CUknhVbyiPxTRbjy6yF0aMKs1gMTfHrNHTKsasgmkCyPQd4C2eOPceuKA== +"@commitlint/is-ignored@^8.3.5": + version "8.3.5" + resolved "https://registry.yarnpkg.com/@commitlint/is-ignored/-/is-ignored-8.3.5.tgz#e6f59496e1b1ce58020d519cd578ad0f43169199" + integrity sha512-Zo+8a6gJLFDTqyNRx53wQi/XTiz8mncvmWf/4oRG+6WRcBfjSSHY7KPVj5Y6UaLy2EgZ0WQ2Tt6RdTDeQiQplA== dependencies: - semver "5.6.0" + semver "6.3.0" -"@commitlint/lint@^7.5.2": - version "7.5.2" - resolved "https://registry.yarnpkg.com/@commitlint/lint/-/lint-7.5.2.tgz#26cb819c74f8770413c4f6ef1e7abf1b739eda77" - integrity sha512-DY/UfGFDquMno+5c6+tE50rMxpjdQK3CRG+nktgYlVz1UAqeUD+bRc3pvX5HwAsuGvyDrWAjtszHtEDeYJKcjw== +"@commitlint/lint@^8.3.5": + version "8.3.5" + resolved "https://registry.yarnpkg.com/@commitlint/lint/-/lint-8.3.5.tgz#627e75adb1cc803cc723e33cc2ba4aa27cbb9f0c" + integrity sha512-02AkI0a6PU6rzqUvuDkSi6rDQ2hUgkq9GpmdJqfai5bDbxx2939mK4ZO+7apbIh4H6Pae7EpYi7ffxuJgm+3hQ== dependencies: - "@commitlint/is-ignored" "^7.5.1" - "@commitlint/parse" "^7.5.0" - "@commitlint/rules" "^7.5.2" + "@commitlint/is-ignored" "^8.3.5" + "@commitlint/parse" "^8.3.4" + "@commitlint/rules" "^8.3.4" babel-runtime "^6.23.0" - lodash "4.17.11" + lodash "4.17.15" -"@commitlint/load@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@commitlint/load/-/load-7.5.0.tgz#2b225b97d631c2235d8b2084bc2fefb4d4d66719" - integrity sha512-fhBER/rzPsteM6zq5qqMiOi+A2bHKCE/0PKmOzYgaqTKcG9c1SsOle9phPemW85to8Gxd2YgUOVLsZkCMltLtA== +"@commitlint/load@^8.3.5": + version "8.3.5" + resolved "https://registry.yarnpkg.com/@commitlint/load/-/load-8.3.5.tgz#3f059225ede92166ba94cf4c48e3d67c8b08b18a" + integrity sha512-poF7R1CtQvIXRmVIe63FjSQmN9KDqjRtU5A6hxqXBga87yB2VUJzic85TV6PcQc+wStk52cjrMI+g0zFx+Zxrw== dependencies: - "@commitlint/execute-rule" "^7.5.0" - "@commitlint/resolve-extends" "^7.5.0" + "@commitlint/execute-rule" "^8.3.4" + "@commitlint/resolve-extends" "^8.3.5" babel-runtime "^6.23.0" - cosmiconfig "^4.0.0" - lodash "4.17.11" - resolve-from "^4.0.0" + chalk "2.4.2" + cosmiconfig "^5.2.0" + lodash "4.17.15" + resolve-from "^5.0.0" -"@commitlint/message@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@commitlint/message/-/message-7.5.0.tgz#2572fad648c769dd210374c8b95fb37124302bc5" - integrity sha512-5YOhsqy/MgHH7vyDsmmzO6Jr3ygr1pXbCm9NR3XB51wjg55Kd6/6dVlkhS/FmDp99pfwTdHb0TyeDFEjP98waw== +"@commitlint/message@^8.3.4": + version "8.3.4" + resolved "https://registry.yarnpkg.com/@commitlint/message/-/message-8.3.4.tgz#b4e50d14aa6e15a5ad0767b952a7953f3681d768" + integrity sha512-nEj5tknoOKXqBsaQtCtgPcsAaf5VCg3+fWhss4Vmtq40633xLq0irkdDdMEsYIx8rGR0XPBTukqzln9kAWCkcA== -"@commitlint/parse@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@commitlint/parse/-/parse-7.5.0.tgz#d9374266493e5229ec61d92316d28e02419c600f" - integrity sha512-hWASM8SBFTBtlFkKrEtD1qW6yTe2BsfoRiMKuYyRCTd+739TUF17og5vgQVuWttbGP0gXaciW44NygS2YjZmfA== +"@commitlint/parse@^8.3.4": + version "8.3.4" + resolved "https://registry.yarnpkg.com/@commitlint/parse/-/parse-8.3.4.tgz#d741f8b9104b35d0f4c10938165b20cbf167f81e" + integrity sha512-b3uQvpUQWC20EBfKSfMRnyx5Wc4Cn778bVeVOFErF/cXQK725L1bYFvPnEjQO/GT8yGVzq2wtLaoEqjm1NJ/Bw== dependencies: conventional-changelog-angular "^1.3.3" - conventional-commits-parser "^2.1.0" + conventional-commits-parser "^3.0.0" lodash "^4.17.11" -"@commitlint/read@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@commitlint/read/-/read-7.5.0.tgz#35d563b0f3075da2ce6945978996b16fb4acb0f8" - integrity sha512-uqGFCKZGnBUCTkxoCCJp4MfWUkegXkyT0T0RVM9diyG6uNWPWlMH1509sjLFlyeJKG+cSyYGG/d6T103ScMb4Q== +"@commitlint/read@^8.3.4": + version "8.3.4" + resolved "https://registry.yarnpkg.com/@commitlint/read/-/read-8.3.4.tgz#81a34283d8cd7b2acdf57829a91761e9c7791455" + integrity sha512-FKv1kHPrvcAG5j+OSbd41IWexsbLhfIXpxVC/YwQZO+FR0EHmygxQNYs66r+GnhD1EfYJYM4WQIqd5bJRx6OIw== dependencies: - "@commitlint/top-level" "^7.5.0" + "@commitlint/top-level" "^8.3.4" "@marionebl/sander" "^0.6.0" babel-runtime "^6.23.0" - git-raw-commits "^1.3.0" + git-raw-commits "^2.0.0" -"@commitlint/resolve-extends@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@commitlint/resolve-extends/-/resolve-extends-7.5.0.tgz#d95a3058e83ddbaef5e3045835b9a3a1fba3422c" - integrity sha512-FRIyPuqGvGa03OT4VgOHakizcw8YR5rdm77JsZff1rSnpxk6i+025I6qMeHqCIr5FaVIA0kR3FlC+MJFUs165A== +"@commitlint/resolve-extends@^8.3.5": + version "8.3.5" + resolved "https://registry.yarnpkg.com/@commitlint/resolve-extends/-/resolve-extends-8.3.5.tgz#8fff800f292ac217ae30b1862f5f9a84b278310a" + integrity sha512-nHhFAK29qiXNe6oH6uG5wqBnCR+BQnxlBW/q5fjtxIaQALgfoNLHwLS9exzbIRFqwJckpR6yMCfgMbmbAOtklQ== dependencies: - babel-runtime "6.26.0" import-fresh "^3.0.0" - lodash "4.17.11" - resolve-from "^4.0.0" - resolve-global "^0.1.0" - -"@commitlint/rules@^7.5.2": - version "7.5.2" - resolved "https://registry.yarnpkg.com/@commitlint/rules/-/rules-7.5.2.tgz#da03d754625b2e67c0a6b8b9ab89eae1952a4f2e" - integrity sha512-eDN1UFPcBOjdnlI3syuo7y99SjGH/dUV6S9NvBocAye8ln5dfKiI2shhWochJhl36r/kYWU8Wrvl2NZJL3c52g== - dependencies: - "@commitlint/ensure" "^7.5.2" - "@commitlint/message" "^7.5.0" - "@commitlint/to-lines" "^7.5.0" + lodash "4.17.15" + resolve-from "^5.0.0" + resolve-global "^1.0.0" + +"@commitlint/rules@^8.3.4": + version "8.3.4" + resolved "https://registry.yarnpkg.com/@commitlint/rules/-/rules-8.3.4.tgz#41da7e16c6b89af268fe81c87a158c1fd2ac82b1" + integrity sha512-xuC9dlqD5xgAoDFgnbs578cJySvwOSkMLQyZADb1xD5n7BNcUJfP8WjT9W1Aw8K3Wf8+Ym/ysr9FZHXInLeaRg== + dependencies: + "@commitlint/ensure" "^8.3.4" + "@commitlint/message" "^8.3.4" + "@commitlint/to-lines" "^8.3.4" babel-runtime "^6.23.0" -"@commitlint/to-lines@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@commitlint/to-lines/-/to-lines-7.5.0.tgz#a24410d25bb85a5fff3b8d610277b3145f899766" - integrity sha512-ZQ3LxPNuQ/J7q42hkiPWN5fUIjWae85H2HHoBB+/Rw1fo+oehvr4Xyt+Oa9Mx5WbBnev/wXnUFjXgoadv1RZ5A== +"@commitlint/to-lines@^8.3.4": + version "8.3.4" + resolved "https://registry.yarnpkg.com/@commitlint/to-lines/-/to-lines-8.3.4.tgz#ce24963b6d86dbe51d88d5e3028ab28f38562e2e" + integrity sha512-5AvcdwRsMIVq0lrzXTwpbbG5fKRTWcHkhn/hCXJJ9pm1JidsnidS1y0RGkb3O50TEHGewhXwNoavxW9VToscUA== -"@commitlint/top-level@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@commitlint/top-level/-/top-level-7.5.0.tgz#01e740167e3d15110794192cd754f49f27d4a16d" - integrity sha512-oTu185GufTYHjTXPHu6k6HL7iuASOvDOtQizZWRSxj0VXuoki6e0HzvGZsRsycDTOn04Q9hVu+PhF83IUwRpeg== +"@commitlint/top-level@^8.3.4": + version "8.3.4" + resolved "https://registry.yarnpkg.com/@commitlint/top-level/-/top-level-8.3.4.tgz#803fc6e8f5be5efa5f3551761acfca961f1d8685" + integrity sha512-nOaeLBbAqSZNpKgEtO6NAxmui1G8ZvLG+0wb4rvv6mWhPDzK1GNZkCd8FUZPahCoJ1iHDoatw7F8BbJLg4nDjg== dependencies: - find-up "^2.1.0" + find-up "^4.0.0" -"@iamstarkov/listr-update-renderer@0.4.1": - version "0.4.1" - resolved "https://registry.yarnpkg.com/@iamstarkov/listr-update-renderer/-/listr-update-renderer-0.4.1.tgz#d7c48092a2dcf90fd672b6c8b458649cb350c77e" +"@istanbuljs/load-nyc-config@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.0.0.tgz#10602de5570baea82f8afbfa2630b24e7a8cfe5b" + integrity sha512-ZR0rq/f/E4f4XcgnDvtMWXCUJpi8eO0rssVhmztsZqLIEFA9UUP9zmpE0VxlM+kv/E1ul2I876Fwil2ayptDVg== dependencies: - chalk "^1.1.3" - cli-truncate "^0.2.1" - elegant-spinner "^1.0.1" - figures "^1.7.0" - indent-string "^3.0.0" - log-symbols "^1.0.2" - log-update "^2.3.0" - strip-ansi "^3.0.1" + camelcase "^5.3.1" + find-up "^4.1.0" + js-yaml "^3.13.1" + resolve-from "^5.0.0" -"@jest/console@^24.7.1": - version "24.7.1" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.7.1.tgz#32a9e42535a97aedfe037e725bd67e954b459545" - integrity sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg== - dependencies: - "@jest/source-map" "^24.3.0" - chalk "^2.0.1" - slash "^2.0.0" - -"@jest/core@^24.7.1": - version "24.7.1" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-24.7.1.tgz#6707f50db238d0c5988860680e2e414df0032024" - integrity sha512-ivlZ8HX/FOASfHcb5DJpSPFps8ydfUYzLZfgFFqjkLijYysnIEOieg72YRhO4ZUB32xu40hsSMmaw+IGYeKONA== - dependencies: - "@jest/console" "^24.7.1" - "@jest/reporters" "^24.7.1" - "@jest/test-result" "^24.7.1" - "@jest/transform" "^24.7.1" - "@jest/types" "^24.7.0" - ansi-escapes "^3.0.0" - chalk "^2.0.1" +"@istanbuljs/schema@^0.1.2": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.2.tgz#26520bf09abe4a5644cd5414e37125a8954241dd" + integrity sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw== + +"@jest/console@^25.3.0": + version "25.3.0" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-25.3.0.tgz#33b56b81238427bf3ebe3f7b3378d2f79cdbd409" + integrity sha512-LvSDNqpmZIZyweFaEQ6wKY7CbexPitlsLHGJtcooNECo0An/w49rFhjCJzu6efeb6+a3ee946xss1Jcd9r03UQ== + dependencies: + "@jest/source-map" "^25.2.6" + chalk "^3.0.0" + jest-util "^25.3.0" + slash "^3.0.0" + +"@jest/core@^25.3.0": + version "25.3.0" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-25.3.0.tgz#80f97a7a8b59dde741a24f30871cc26d0197d426" + integrity sha512-+D5a/tFf6pA/Gqft2DLBp/yeSRgXhlJ+Wpst0X/ZkfTRP54qDR3C61VfHwaex+GzZBiTcE9vQeoZ2v5T10+Mqw== + dependencies: + "@jest/console" "^25.3.0" + "@jest/reporters" "^25.3.0" + "@jest/test-result" "^25.3.0" + "@jest/transform" "^25.3.0" + "@jest/types" "^25.3.0" + ansi-escapes "^4.2.1" + chalk "^3.0.0" exit "^0.1.2" - graceful-fs "^4.1.15" - jest-changed-files "^24.7.0" - jest-config "^24.7.1" - jest-haste-map "^24.7.1" - jest-message-util "^24.7.1" - jest-regex-util "^24.3.0" - jest-resolve-dependencies "^24.7.1" - jest-runner "^24.7.1" - jest-runtime "^24.7.1" - jest-snapshot "^24.7.1" - jest-util "^24.7.1" - jest-validate "^24.7.0" - jest-watcher "^24.7.1" - micromatch "^3.1.10" - p-each-series "^1.0.0" - pirates "^4.0.1" - realpath-native "^1.1.0" - rimraf "^2.5.4" - strip-ansi "^5.0.0" - -"@jest/environment@^24.7.1": - version "24.7.1" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-24.7.1.tgz#9b9196bc737561f67ac07817d4c5ece772e33135" - integrity sha512-wmcTTYc4/KqA+U5h1zQd5FXXynfa7VGP2NfF+c6QeGJ7c+2nStgh65RQWNX62SC716dTtqheTRrZl0j+54oGHw== - dependencies: - "@jest/fake-timers" "^24.7.1" - "@jest/transform" "^24.7.1" - "@jest/types" "^24.7.0" - jest-mock "^24.7.0" - -"@jest/fake-timers@^24.7.1": - version "24.7.1" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.7.1.tgz#56e5d09bdec09ee81050eaff2794b26c71d19db2" - integrity sha512-4vSQJDKfR2jScOe12L9282uiwuwQv9Lk7mgrCSZHA9evB9efB/qx8i0KJxsAKtp8fgJYBJdYY7ZU6u3F4/pyjA== - dependencies: - "@jest/types" "^24.7.0" - jest-message-util "^24.7.1" - jest-mock "^24.7.0" - -"@jest/reporters@^24.7.1": - version "24.7.1" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-24.7.1.tgz#38ac0b096cd691bbbe3051ddc25988d42e37773a" - integrity sha512-bO+WYNwHLNhrjB9EbPL4kX/mCCG4ZhhfWmO3m4FSpbgr7N83MFejayz30kKjgqr7smLyeaRFCBQMbXpUgnhAJw== - dependencies: - "@jest/environment" "^24.7.1" - "@jest/test-result" "^24.7.1" - "@jest/transform" "^24.7.1" - "@jest/types" "^24.7.0" - chalk "^2.0.1" + graceful-fs "^4.2.3" + jest-changed-files "^25.3.0" + jest-config "^25.3.0" + jest-haste-map "^25.3.0" + jest-message-util "^25.3.0" + jest-regex-util "^25.2.6" + jest-resolve "^25.3.0" + jest-resolve-dependencies "^25.3.0" + jest-runner "^25.3.0" + jest-runtime "^25.3.0" + jest-snapshot "^25.3.0" + jest-util "^25.3.0" + jest-validate "^25.3.0" + jest-watcher "^25.3.0" + micromatch "^4.0.2" + p-each-series "^2.1.0" + realpath-native "^2.0.0" + rimraf "^3.0.0" + slash "^3.0.0" + strip-ansi "^6.0.0" + +"@jest/environment@^25.3.0": + version "25.3.0" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-25.3.0.tgz#587f28ddb4b0dfe97404d3d4a4c9dbfa0245fb2e" + integrity sha512-vgooqwJTHLLak4fE+TaCGeYP7Tz1Y3CKOsNxR1sE0V3nx3KRUHn3NUnt+wbcfd5yQWKZQKAfW6wqbuwQLrXo3g== + dependencies: + "@jest/fake-timers" "^25.3.0" + "@jest/types" "^25.3.0" + jest-mock "^25.3.0" + +"@jest/fake-timers@^25.3.0": + version "25.3.0" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-25.3.0.tgz#995aad36d5c8984165ca5db12e740ab8dbf7042a" + integrity sha512-NHAj7WbsyR3qBJPpBwSwqaq2WluIvUQsyzpJTN7XDVk7VnlC/y1BAnaYZL3vbPIP8Nhm0Ae5DJe0KExr/SdMJQ== + dependencies: + "@jest/types" "^25.3.0" + jest-message-util "^25.3.0" + jest-mock "^25.3.0" + jest-util "^25.3.0" + lolex "^5.0.0" + +"@jest/reporters@^25.3.0": + version "25.3.0" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-25.3.0.tgz#7f39f0e6911561cc5112a1b54656de18faee269b" + integrity sha512-1u0ZBygs0C9DhdYgLCrRfZfNKQa+9+J7Uo+Z9z0RWLHzgsxhoG32lrmMOtUw48yR6bLNELdvzormwUqSk4H4Vg== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@jest/console" "^25.3.0" + "@jest/test-result" "^25.3.0" + "@jest/transform" "^25.3.0" + "@jest/types" "^25.3.0" + chalk "^3.0.0" + collect-v8-coverage "^1.0.0" exit "^0.1.2" glob "^7.1.2" - istanbul-api "^2.1.1" - istanbul-lib-coverage "^2.0.2" - istanbul-lib-instrument "^3.0.1" - istanbul-lib-source-maps "^3.0.1" - jest-haste-map "^24.7.1" - jest-resolve "^24.7.1" - jest-runtime "^24.7.1" - jest-util "^24.7.1" - jest-worker "^24.6.0" - node-notifier "^5.2.1" - slash "^2.0.0" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-instrument "^4.0.0" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.0" + istanbul-reports "^3.0.2" + jest-haste-map "^25.3.0" + jest-resolve "^25.3.0" + jest-util "^25.3.0" + jest-worker "^25.2.6" + slash "^3.0.0" source-map "^0.6.0" - string-length "^2.0.0" + string-length "^3.1.0" + terminal-link "^2.0.0" + v8-to-istanbul "^4.0.1" + optionalDependencies: + node-notifier "^6.0.0" -"@jest/source-map@^24.3.0": - version "24.3.0" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-24.3.0.tgz#563be3aa4d224caf65ff77edc95cd1ca4da67f28" - integrity sha512-zALZt1t2ou8le/crCeeiRYzvdnTzaIlpOWaet45lNSqNJUnXbppUUFR4ZUAlzgDmKee4Q5P/tKXypI1RiHwgag== +"@jest/source-map@^25.2.6": + version "25.2.6" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-25.2.6.tgz#0ef2209514c6d445ebccea1438c55647f22abb4c" + integrity sha512-VuIRZF8M2zxYFGTEhkNSvQkUKafQro4y+mwUxy5ewRqs5N/ynSFUODYp3fy1zCnbCMy1pz3k+u57uCqx8QRSQQ== dependencies: callsites "^3.0.0" - graceful-fs "^4.1.15" + graceful-fs "^4.2.3" source-map "^0.6.0" -"@jest/test-result@^24.7.1": - version "24.7.1" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.7.1.tgz#19eacdb29a114300aed24db651e5d975f08b6bbe" - integrity sha512-3U7wITxstdEc2HMfBX7Yx3JZgiNBubwDqQMh+BXmZXHa3G13YWF3p6cK+5g0hGkN3iufg/vGPl3hLxQXD74Npg== +"@jest/test-result@^25.3.0": + version "25.3.0" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-25.3.0.tgz#137fab5e5c6fed36e5d40735d1eb029325e3bf06" + integrity sha512-mqrGuiiPXl1ap09Mydg4O782F3ouDQfsKqtQzIjitpwv3t1cHDwCto21jThw6WRRE+dKcWQvLG70GpyLJICfGw== dependencies: - "@jest/console" "^24.7.1" - "@jest/types" "^24.7.0" + "@jest/console" "^25.3.0" + "@jest/types" "^25.3.0" "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^24.7.1": - version "24.7.1" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-24.7.1.tgz#9c18e428e1ad945fa74f6233a9d35745ca0e63e0" - integrity sha512-84HQkCpVZI/G1zq53gHJvSmhUer4aMYp9tTaffW28Ih5OxfCg8hGr3nTSbL1OhVDRrFZwvF+/R9gY6JRkDUpUA== +"@jest/test-sequencer@^25.3.0": + version "25.3.0" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-25.3.0.tgz#271ad5f2b8f8137d092ccedc87e16a50f8676209" + integrity sha512-Xvns3xbji7JCvVcDGvqJ/pf4IpmohPODumoPEZJ0/VgC5gI4XaNVIBET2Dq5Czu6Gk3xFcmhtthh/MBOTljdNg== dependencies: - "@jest/test-result" "^24.7.1" - jest-haste-map "^24.7.1" - jest-runner "^24.7.1" - jest-runtime "^24.7.1" + "@jest/test-result" "^25.3.0" + jest-haste-map "^25.3.0" + jest-runner "^25.3.0" + jest-runtime "^25.3.0" -"@jest/transform@^24.7.1": - version "24.7.1" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-24.7.1.tgz#872318f125bcfab2de11f53b465ab1aa780789c2" - integrity sha512-EsOUqP9ULuJ66IkZQhI5LufCHlTbi7hrcllRMUEV/tOgqBVQi93+9qEvkX0n8mYpVXQ8VjwmICeRgg58mrtIEw== +"@jest/transform@^25.3.0": + version "25.3.0" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-25.3.0.tgz#083c5447d5307d9b9494d6968115b647460e71f1" + integrity sha512-W01p8kTDvvEX6kd0tJc7Y5VdYyFaKwNWy1HQz6Jqlhu48z/8Gxp+yFCDVj+H8Rc7ezl3Mg0hDaGuFVkmHOqirg== dependencies: "@babel/core" "^7.1.0" - "@jest/types" "^24.7.0" - babel-plugin-istanbul "^5.1.0" - chalk "^2.0.1" + "@jest/types" "^25.3.0" + babel-plugin-istanbul "^6.0.0" + chalk "^3.0.0" convert-source-map "^1.4.0" fast-json-stable-stringify "^2.0.0" - graceful-fs "^4.1.15" - jest-haste-map "^24.7.1" - jest-regex-util "^24.3.0" - jest-util "^24.7.1" - micromatch "^3.1.10" - realpath-native "^1.1.0" - slash "^2.0.0" + graceful-fs "^4.2.3" + jest-haste-map "^25.3.0" + jest-regex-util "^25.2.6" + jest-util "^25.3.0" + micromatch "^4.0.2" + pirates "^4.0.1" + realpath-native "^2.0.0" + slash "^3.0.0" source-map "^0.6.1" - write-file-atomic "2.4.1" + write-file-atomic "^3.0.0" -"@jest/types@^24.7.0": - version "24.7.0" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.7.0.tgz#c4ec8d1828cdf23234d9b4ee31f5482a3f04f48b" - integrity sha512-ipJUa2rFWiKoBqMKP63Myb6h9+iT3FHRTF2M8OR6irxWzItisa8i4dcSg14IbvmXUnBlHBlUQPYUHWyX3UPpYA== +"@jest/types@^25.3.0": + version "25.3.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.3.0.tgz#88f94b277a1d028fd7117bc1f74451e0fc2131e7" + integrity sha512-UkaDNewdqXAmCDbN2GlUM6amDKS78eCqiw/UmF5nE0mmLTd6moJkiZJML/X52Ke3LH7Swhw883IRXq8o9nWjVw== dependencies: "@types/istanbul-lib-coverage" "^2.0.0" - "@types/yargs" "^12.0.9" + "@types/istanbul-reports" "^1.1.1" + "@types/yargs" "^15.0.0" + chalk "^3.0.0" "@marionebl/sander@^0.6.0": version "0.6.1" @@ -455,12 +795,48 @@ mkdirp "^0.5.1" rimraf "^2.5.2" +"@mdx-js/mdx@^1.5.8": + version "1.5.8" + resolved "https://registry.yarnpkg.com/@mdx-js/mdx/-/mdx-1.5.8.tgz#40740eaf0b0007b461cee8df13a7ae5a1af8064a" + integrity sha512-OzanPTN0p9GZOEVeEuEa8QsjxxGyfFOOnI/+V1oC1su9UIN4KUg1k4n/hWTZC+VZhdW1Lfj6+Ho8nIs6L+pbDA== + dependencies: + "@babel/core" "7.8.4" + "@babel/plugin-syntax-jsx" "7.8.3" + "@babel/plugin-syntax-object-rest-spread" "7.8.3" + "@mdx-js/util" "^1.5.8" + babel-plugin-apply-mdx-type-prop "^1.5.8" + babel-plugin-extract-import-names "^1.5.8" + camelcase-css "2.0.1" + detab "2.0.3" + hast-util-raw "5.0.2" + lodash.uniq "4.5.0" + mdast-util-to-hast "7.0.0" + remark-mdx "^1.5.8" + remark-parse "7.0.2" + remark-squeeze-paragraphs "3.0.4" + style-to-object "0.3.0" + unified "8.4.2" + unist-builder "2.0.3" + unist-util-visit "2.0.2" + +"@mdx-js/util@^1.5.8": + version "1.5.8" + resolved "https://registry.yarnpkg.com/@mdx-js/util/-/util-1.5.8.tgz#cbadda0378af899c17ce1aa69c677015cab28448" + integrity sha512-a7Gjjw8bfBSertA/pTWBA/9WKEhgaSxvQE2NTSUzaknrzGFOhs4alZSHh3RHmSFdSWv5pUuzAgsWseMLhWEVkQ== + "@samverschueren/stream-to-observable@^0.3.0": version "0.3.0" resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f" dependencies: any-observable "^0.3.0" +"@sinonjs/commons@^1.7.0": + version "1.7.2" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.7.2.tgz#505f55c74e0272b43f6c52d81946bed7058fc0e2" + integrity sha512-+DUO6pnp3udV/v2VfUWgaY5BIE1IfT7lLfeDzPVeMT1XKkaAp9LgSI9x5RtrFQoZ9Oi0PgXQQHPaoKu7dCjVxw== + dependencies: + type-detect "4.0.8" + "@types/anymatch@*": version "1.3.0" resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.0.tgz#d1d55958d1fccc5527d4aba29fc9c4b942f563ff" @@ -470,10 +846,10 @@ resolved "https://registry.yarnpkg.com/@types/babel__code-frame/-/babel__code-frame-7.0.1.tgz#baf2529c4abbfb5e4008c845efcfe39a187e2f99" integrity sha512-FFfbQozKxYmOnCKFYV+EQprjBI7u2yaNc2ly/K9AhzyC8MzXtCtSRqptpw+HUJxhwCOo5mLwf1ATmzyhOaVbDg== -"@types/babel__core@^7.1.0": - version "7.1.1" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.1.tgz#ce9a9e5d92b7031421e1d0d74ae59f572ba48be6" - integrity sha512-+hjBtgcFPYyCTo0A15+nxrCVJL7aC6Acg87TXd5OW3QhHswdrOLoles+ldL2Uk8q++7yIfl4tURtztccdeeyOw== +"@types/babel__core@^7.1.7": + version "7.1.7" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.7.tgz#1dacad8840364a57c98d0dd4855c6dd3752c6b89" + integrity sha512-RL62NqSFPCDK2FM1pSDH0scHpJvsXtZNiYlMB73DgPBaG1E38ZYVL+ei5EkWRbr+KC4YNiAUNBnRj+bgwpgjMw== dependencies: "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" @@ -503,15 +879,29 @@ dependencies: "@babel/types" "^7.3.0" -"@types/braces@*": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@types/braces/-/braces-2.3.0.tgz#d00ec0a76562b2acb6f29330be33a093e33ed25c" +"@types/color-name@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" + integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== "@types/eslint-visitor-keys@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag== +"@types/eslint@^6.8.0": + version "6.8.0" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-6.8.0.tgz#5f2289b9f01316da7cf31c9e63109a10602a23cb" + integrity sha512-hqzmggoxkOubpgTdcOltkfc5N8IftRJqU70d1jbOISjjZVPvjcr+CLi2CI70hx1SUIRkLgpglTy9w28nGe2Hsw== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*": + version "0.0.39" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" + integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== + "@types/events@*": version "1.2.0" resolved "https://registry.yarnpkg.com/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86" @@ -525,38 +915,50 @@ "@types/minimatch" "*" "@types/node" "*" -"@types/istanbul-lib-coverage@^2.0.0": +"@types/graceful-fs@^4.1.3": + version "4.1.3" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.3.tgz#039af35fe26bec35003e8d86d2ee9c586354348f" + integrity sha512-AiHRaEB50LQg0pZmm659vNBb9f4SJ0qrAnteuzhSeAUcJKxoYgEnprg/83kppCnc2zvtCKbdZry1a5pVY3lOTQ== + dependencies: + "@types/node" "*" + +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": version "2.0.1" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff" integrity sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg== -"@types/jest-diff@*": - version "20.0.1" - resolved "https://registry.yarnpkg.com/@types/jest-diff/-/jest-diff-20.0.1.tgz#35cc15b9c4f30a18ef21852e255fdb02f6d59b89" - integrity sha512-yALhelO3i0hqZwhjtcr6dYyaLoCHbAMshwtj6cGxTvHZAKXHsYGdff6E8EPw3xLKY0ELUTQ69Q1rQiJENnccMA== +"@types/istanbul-lib-report@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" + integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== + dependencies: + "@types/istanbul-lib-coverage" "*" -"@types/jest@^24.0.11": - version "24.0.11" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-24.0.11.tgz#1f099bea332c228ea6505a88159bfa86a5858340" - integrity sha512-2kLuPC5FDnWIDvaJBzsGTBQaBbnDweznicvK7UGYzlIJP4RJR2a4A/ByLUXEyEgag6jz8eHdlWExGDtH3EYUXQ== +"@types/istanbul-reports@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz#7a8cbf6a406f36c8add871625b278eaf0b0d255a" + integrity sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA== + dependencies: + "@types/istanbul-lib-coverage" "*" + "@types/istanbul-lib-report" "*" + +"@types/jest@^25.2.1": + version "25.2.1" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-25.2.1.tgz#9544cd438607955381c1bdbdb97767a249297db5" + integrity sha512-msra1bCaAeEdkSyA0CZ6gW1ukMIvZ5YoJkdXw/qhQdsuuDlFTcEUrUw8CLCPt2rVRUfXlClVvK2gvPs9IokZaA== dependencies: - "@types/jest-diff" "*" + jest-diff "^25.2.1" + pretty-format "^25.2.1" -"@types/json-schema@^7.0.3": +"@types/json-schema@*", "@types/json-schema@^7.0.3": version "7.0.3" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.3.tgz#bdfd69d61e464dcc81b25159c270d75a73c1a636" integrity sha512-Il2DtDVRGDcqjDtE+rF8iqg1CArehSK84HZJCT7AMITlyXRBpuPhqGLDQMowraqqu1coEaimg4ZOqggt6L6L+A== -"@types/lodash@^4.14.134": - version "4.14.134" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.134.tgz#9032b440122db3a2a56200e91191996161dde5b9" - integrity sha512-2/O0khFUCFeDlbi7sZ7ZFRCcT812fAeOLm7Ev4KbwASkZ575TDrDcY7YyaoHdTOzKcNbfiwLYZqPmoC4wadrsw== - -"@types/micromatch@^3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@types/micromatch/-/micromatch-3.1.0.tgz#514c8a3d24b2680a9b838eeb80e6d7d724545433" - dependencies: - "@types/braces" "*" +"@types/lodash@^4.14.149": + version "4.14.149" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.149.tgz#1342d63d948c6062838fbf961012f74d4e638440" + integrity sha512-ijGqzZt/b7BfzcK9vTrS6MFljQRPn5BFWOx8oE0GYxribu6uV+aA9zZuXI1zc/etK9E8nrgdoF2+LgUw7+9tJQ== "@types/minimatch@*", "@types/minimatch@^3.0.1": version "3.0.3" @@ -580,22 +982,50 @@ version "10.12.18" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67" -"@types/node@^11.0.0": - version "11.13.17" - resolved "https://registry.yarnpkg.com/@types/node/-/node-11.13.17.tgz#2e7efbfe5253561087812571e5e6a1e4b1d6295b" - integrity sha512-7W3kSMa8diVH6s24a8Qrmvwu+vG3ahOC/flMHFdWSdnPYoQI0yPO84h5zOWYXAha2Npn3Pw3SSuQSwBUfaniyQ== +"@types/node@^13.11.1": + version "13.11.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-13.11.1.tgz#49a2a83df9d26daacead30d0ccc8762b128d53c7" + integrity sha512-eWQGP3qtxwL8FGneRrC5DwrJLGN4/dH1clNTuLfN81HCrxVtxRjygDTUoZJ5ASlDEeo0ppYFQjQIlXhtXpOn6g== -"@types/rimraf@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@types/rimraf/-/rimraf-2.0.2.tgz#7f0fc3cf0ff0ad2a99bb723ae1764f30acaf8b6e" - integrity sha512-Hm/bnWq0TCy7jmjeN5bKYij9vw5GrDFWME4IuxV08278NtU/VdGbzsBohcCUJ7+QMqmUq5hpRKB39HeQWJjztQ== +"@types/normalize-package-data@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" + integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA== + +"@types/parse-json@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" + integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== + +"@types/prettier@^1.19.0": + version "1.19.1" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-1.19.1.tgz#33509849f8e679e4add158959fdb086440e9553f" + integrity sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ== + +"@types/rimraf@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/rimraf/-/rimraf-3.0.0.tgz#b9d03f090ece263671898d57bb7bb007023ac19f" + integrity sha512-7WhJ0MdpFgYQPXlF4Dx+DhgvlPCfz/x5mHaeDQAKhcenvQP1KCpLQ18JklAqeGMYSAT2PxLpzd0g2/HE7fj7hQ== dependencies: "@types/glob" "*" "@types/node" "*" -"@types/semver@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-5.5.0.tgz#146c2a29ee7d3bae4bf2fcb274636e264c813c45" +"@types/schema-utils@1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/schema-utils/-/schema-utils-1.0.0.tgz#295d36f01e2cb8bc3207ca1d9a68e210db6b40cb" + integrity sha512-YesPanU1+WCigC/Aj1Mga8UCOjHIfMNHZ3zzDsUY7lI8GlKnh/Kv2QwJOQ+jNQ36Ru7IfzSedlG14hppYaN13A== + +"@types/semver@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.1.0.tgz#c8c630d4c18cd326beff77404887596f96408408" + integrity sha512-pOKLaubrAEMUItGNpgwl0HMFPrSAFic8oSVIvfu1UwcgGNmNyK9gyhBHKmBnUTwwVvpZfkzUC0GaMgnL6P86uA== + dependencies: + "@types/node" "*" + +"@types/source-list-map@*": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9" + integrity sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA== "@types/stack-utils@^1.0.1": version "1.0.1" @@ -612,222 +1042,246 @@ dependencies: source-map "^0.6.1" -"@types/webpack@^4.4.19": - version "4.4.22" - resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.4.22.tgz#c4a5ea8b74a31b579537515bcfe86d2b2a34382c" +"@types/unist@^2.0.0", "@types/unist@^2.0.2": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e" + integrity sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ== + +"@types/webpack-sources@*": + version "0.1.7" + resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-0.1.7.tgz#0a330a9456113410c74a5d64180af0cbca007141" + integrity sha512-XyaHrJILjK1VHVC4aVlKsdNN5KBTwufMb43cQs+flGxtPAf/1Qwl8+Q0tp5BwEGaI8D6XT1L+9bSWXckgkjTLw== + dependencies: + "@types/node" "*" + "@types/source-list-map" "*" + source-map "^0.6.1" + +"@types/webpack@^4.41.11": + version "4.41.11" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.11.tgz#7b7f725397d3b630bede05415d34e9ff30d9771f" + integrity sha512-PtEZISfBMWL05qOpZN19hztZPt0rPuGQh5sbBP3bB4RrJgzdb0SScn47hdcMaoN1IgaU7NZWeDO6reFcKTK2iQ== dependencies: "@types/anymatch" "*" "@types/node" "*" "@types/tapable" "*" "@types/uglify-js" "*" + "@types/webpack-sources" "*" source-map "^0.6.0" -"@types/yargs@^12.0.2", "@types/yargs@^12.0.9": - version "12.0.12" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-12.0.12.tgz#45dd1d0638e8c8f153e87d296907659296873916" - integrity sha512-SOhuU4wNBxhhTHxYaiG5NY4HBhDIDnJF60GU+2LqHAdKKer86//e4yg69aENCtQ04n0ovz+tq2YPME5t5yp4pw== +"@types/yargs-parser@*": + version "15.0.0" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-15.0.0.tgz#cb3f9f741869e20cce330ffbeb9271590483882d" + integrity sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw== -"@typescript-eslint/eslint-plugin@^2.12.0": - version "2.12.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.12.0.tgz#0da7cbca7b24f4c6919e9eb31c704bfb126f90ad" - integrity sha512-1t4r9rpLuEwl3hgt90jY18wJHSyb0E3orVL3DaqwmpiSDHmHiSspVsvsFF78BJ/3NNG3qmeso836jpuBWYziAA== +"@types/yargs@^15.0.0": + version "15.0.4" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.4.tgz#7e5d0f8ca25e9d5849f2ea443cf7c402decd8299" + integrity sha512-9T1auFmbPZoxHz0enUFlUuKRy3it01R+hlggyVUMtnCTQRunsQYifnSGb8hET4Xo8yiC0o0r1paW3ud5+rbURg== dependencies: - "@typescript-eslint/experimental-utils" "2.12.0" - eslint-utils "^1.4.3" + "@types/yargs-parser" "*" + +"@typescript-eslint/eslint-plugin@^2.27.0": + version "2.27.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.27.0.tgz#e479cdc4c9cf46f96b4c287755733311b0d0ba4b" + integrity sha512-/my+vVHRN7zYgcp0n4z5A6HAK7bvKGBiswaM5zIlOQczsxj/aiD7RcgD+dvVFuwFaGh5+kM7XA6Q6PN0bvb1tw== + dependencies: + "@typescript-eslint/experimental-utils" "2.27.0" functional-red-black-tree "^1.0.1" regexpp "^3.0.0" tsutils "^3.17.1" -"@typescript-eslint/experimental-utils@2.12.0": - version "2.12.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.12.0.tgz#e0a76ffb6293e058748408a191921e453c31d40d" - integrity sha512-jv4gYpw5N5BrWF3ntROvCuLe1IjRenLy5+U57J24NbPGwZFAjhnM45qpq0nDH1y/AZMb3Br25YiNVwyPbz6RkA== +"@typescript-eslint/experimental-utils@2.27.0": + version "2.27.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.27.0.tgz#801a952c10b58e486c9a0b36cf21e2aab1e9e01a" + integrity sha512-vOsYzjwJlY6E0NJRXPTeCGqjv5OHgRU1kzxHKWJVPjDYGbPgLudBXjIlc+OD1hDBZ4l1DLbOc5VjofKahsu9Jw== dependencies: "@types/json-schema" "^7.0.3" - "@typescript-eslint/typescript-estree" "2.12.0" + "@typescript-eslint/typescript-estree" "2.27.0" eslint-scope "^5.0.0" + eslint-utils "^2.0.0" -"@typescript-eslint/parser@^2.12.0": - version "2.12.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.12.0.tgz#393f1604943a4ca570bb1a45bc8834e9b9158884" - integrity sha512-lPdkwpdzxEfjI8TyTzZqPatkrswLSVu4bqUgnB03fHSOwpC7KSerPgJRgIAf11UGNf7HKjJV6oaPZI4AghLU6g== +"@typescript-eslint/parser@^2.27.0": + version "2.27.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.27.0.tgz#d91664335b2c46584294e42eb4ff35838c427287" + integrity sha512-HFUXZY+EdwrJXZo31DW4IS1ujQW3krzlRjBrFRrJcMDh0zCu107/nRfhk/uBasO8m0NVDbBF5WZKcIUMRO7vPg== dependencies: "@types/eslint-visitor-keys" "^1.0.0" - "@typescript-eslint/experimental-utils" "2.12.0" - "@typescript-eslint/typescript-estree" "2.12.0" + "@typescript-eslint/experimental-utils" "2.27.0" + "@typescript-eslint/typescript-estree" "2.27.0" eslint-visitor-keys "^1.1.0" -"@typescript-eslint/typescript-estree@2.12.0": - version "2.12.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.12.0.tgz#bd9e547ccffd17dfab0c3ab0947c80c8e2eb914c" - integrity sha512-rGehVfjHEn8Frh9UW02ZZIfJs6SIIxIu/K1bbci8rFfDE/1lQ8krIJy5OXOV3DVnNdDPtoiPOdEANkLMrwXbiQ== +"@typescript-eslint/typescript-estree@2.27.0": + version "2.27.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.27.0.tgz#a288e54605412da8b81f1660b56c8b2e42966ce8" + integrity sha512-t2miCCJIb/FU8yArjAvxllxbTiyNqaXJag7UOpB5DVoM3+xnjeOngtqlJkLRnMtzaRcJhe3CIR9RmL40omubhg== dependencies: debug "^4.1.1" eslint-visitor-keys "^1.1.0" glob "^7.1.6" is-glob "^4.0.1" - lodash.unescape "4.0.1" + lodash "^4.17.15" semver "^6.3.0" tsutils "^3.17.1" -"@vue/component-compiler-utils@^2.4.0": - version "2.5.0" - resolved "https://registry.yarnpkg.com/@vue/component-compiler-utils/-/component-compiler-utils-2.5.0.tgz#411846d582d393f701f747517ddd29275ce64ca4" +"@vue/component-compiler-utils@^3.1.0": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@vue/component-compiler-utils/-/component-compiler-utils-3.1.2.tgz#8213a5ff3202f9f2137fe55370f9e8b9656081c3" + integrity sha512-QLq9z8m79mCinpaEeSURhnNCN6djxpHw0lpP/bodMlt5kALfONpryMthvnrQOlTcIKoF+VoPi+lPHUYeDFPXug== dependencies: consolidate "^0.15.1" hash-sum "^1.0.2" lru-cache "^4.1.2" merge-source-map "^1.1.0" - postcss "^7.0.7" - postcss-selector-parser "^5.0.0" - prettier "1.13.7" - source-map "^0.7.3" - vue-template-es2015-compiler "^1.6.0" - -"@webassemblyjs/ast@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359" - integrity sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ== - dependencies: - "@webassemblyjs/helper-module-context" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/wast-parser" "1.8.5" - -"@webassemblyjs/floating-point-hex-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz#1ba926a2923613edce496fd5b02e8ce8a5f49721" - integrity sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ== - -"@webassemblyjs/helper-api-error@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz#c49dad22f645227c5edb610bdb9697f1aab721f7" - integrity sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA== - -"@webassemblyjs/helper-buffer@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz#fea93e429863dd5e4338555f42292385a653f204" - integrity sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q== - -"@webassemblyjs/helper-code-frame@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz#9a740ff48e3faa3022b1dff54423df9aa293c25e" - integrity sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ== - dependencies: - "@webassemblyjs/wast-printer" "1.8.5" - -"@webassemblyjs/helper-fsm@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz#ba0b7d3b3f7e4733da6059c9332275d860702452" - integrity sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow== - -"@webassemblyjs/helper-module-context@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz#def4b9927b0101dc8cbbd8d1edb5b7b9c82eb245" - integrity sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g== - dependencies: - "@webassemblyjs/ast" "1.8.5" - mamacro "^0.0.3" - -"@webassemblyjs/helper-wasm-bytecode@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz#537a750eddf5c1e932f3744206551c91c1b93e61" - integrity sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ== - -"@webassemblyjs/helper-wasm-section@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz#74ca6a6bcbe19e50a3b6b462847e69503e6bfcbf" - integrity sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - -"@webassemblyjs/ieee754@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz#712329dbef240f36bf57bd2f7b8fb9bf4154421e" - integrity sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g== + postcss "^7.0.14" + postcss-selector-parser "^6.0.2" + source-map "~0.6.1" + vue-template-es2015-compiler "^1.9.0" + optionalDependencies: + prettier "^1.18.2" + +"@webassemblyjs/ast@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" + integrity sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA== + dependencies: + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" + +"@webassemblyjs/floating-point-hex-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz#3c3d3b271bddfc84deb00f71344438311d52ffb4" + integrity sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA== + +"@webassemblyjs/helper-api-error@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz#203f676e333b96c9da2eeab3ccef33c45928b6a2" + integrity sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw== + +"@webassemblyjs/helper-buffer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz#a1442d269c5feb23fcbc9ef759dac3547f29de00" + integrity sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA== + +"@webassemblyjs/helper-code-frame@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz#647f8892cd2043a82ac0c8c5e75c36f1d9159f27" + integrity sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA== + dependencies: + "@webassemblyjs/wast-printer" "1.9.0" + +"@webassemblyjs/helper-fsm@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz#c05256b71244214671f4b08ec108ad63b70eddb8" + integrity sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw== + +"@webassemblyjs/helper-module-context@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz#25d8884b76839871a08a6c6f806c3979ef712f07" + integrity sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g== + dependencies: + "@webassemblyjs/ast" "1.9.0" + +"@webassemblyjs/helper-wasm-bytecode@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz#4fed8beac9b8c14f8c58b70d124d549dd1fe5790" + integrity sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw== + +"@webassemblyjs/helper-wasm-section@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz#5a4138d5a6292ba18b04c5ae49717e4167965346" + integrity sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + +"@webassemblyjs/ieee754@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz#15c7a0fbaae83fb26143bbacf6d6df1702ad39e4" + integrity sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg== dependencies: "@xtuc/ieee754" "^1.2.0" -"@webassemblyjs/leb128@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.8.5.tgz#044edeb34ea679f3e04cd4fd9824d5e35767ae10" - integrity sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A== +"@webassemblyjs/leb128@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.9.0.tgz#f19ca0b76a6dc55623a09cffa769e838fa1e1c95" + integrity sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw== dependencies: "@xtuc/long" "4.2.2" -"@webassemblyjs/utf8@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.8.5.tgz#a8bf3b5d8ffe986c7c1e373ccbdc2a0915f0cedc" - integrity sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw== - -"@webassemblyjs/wasm-edit@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz#962da12aa5acc1c131c81c4232991c82ce56e01a" - integrity sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/helper-wasm-section" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - "@webassemblyjs/wasm-opt" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - "@webassemblyjs/wast-printer" "1.8.5" - -"@webassemblyjs/wasm-gen@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz#54840766c2c1002eb64ed1abe720aded714f98bc" - integrity sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/ieee754" "1.8.5" - "@webassemblyjs/leb128" "1.8.5" - "@webassemblyjs/utf8" "1.8.5" - -"@webassemblyjs/wasm-opt@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz#b24d9f6ba50394af1349f510afa8ffcb8a63d264" - integrity sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - -"@webassemblyjs/wasm-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz#21576f0ec88b91427357b8536383668ef7c66b8d" - integrity sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-api-error" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/ieee754" "1.8.5" - "@webassemblyjs/leb128" "1.8.5" - "@webassemblyjs/utf8" "1.8.5" - -"@webassemblyjs/wast-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz#e10eecd542d0e7bd394f6827c49f3df6d4eefb8c" - integrity sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/floating-point-hex-parser" "1.8.5" - "@webassemblyjs/helper-api-error" "1.8.5" - "@webassemblyjs/helper-code-frame" "1.8.5" - "@webassemblyjs/helper-fsm" "1.8.5" +"@webassemblyjs/utf8@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.9.0.tgz#04d33b636f78e6a6813227e82402f7637b6229ab" + integrity sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w== + +"@webassemblyjs/wasm-edit@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz#3fe6d79d3f0f922183aa86002c42dd256cfee9cf" + integrity sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/helper-wasm-section" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-opt" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + "@webassemblyjs/wast-printer" "1.9.0" + +"@webassemblyjs/wasm-gen@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz#50bc70ec68ded8e2763b01a1418bf43491a7a49c" + integrity sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" + +"@webassemblyjs/wasm-opt@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz#2211181e5b31326443cc8112eb9f0b9028721a61" + integrity sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + +"@webassemblyjs/wasm-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz#9d48e44826df4a6598294aa6c87469d642fff65e" + integrity sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" + +"@webassemblyjs/wast-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz#3031115d79ac5bd261556cecc3fa90a3ef451914" + integrity sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/floating-point-hex-parser" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-code-frame" "1.9.0" + "@webassemblyjs/helper-fsm" "1.9.0" "@xtuc/long" "4.2.2" -"@webassemblyjs/wast-printer@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz#114bbc481fd10ca0e23b3560fa812748b0bae5bc" - integrity sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg== +"@webassemblyjs/wast-printer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz#4935d54c85fef637b00ce9f52377451d00d47899" + integrity sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA== dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/wast-parser" "1.8.5" + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" "@xtuc/long" "4.2.2" "@xtuc/ieee754@^1.2.0": @@ -857,10 +1311,10 @@ abbrev@1: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== -acorn-globals@^4.1.0: - version "4.3.2" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.2.tgz#4e2c2313a597fd589720395f6354b41cd5ec8006" - integrity sha512-BbzvZhVtZP+Bs1J1HcwrQe8ycfO0wStkSGxuul3He3GkHOIZ6eTqOkPuw9IP1X3+IkOo4wiJmwkobzXYz4wewQ== +acorn-globals@^4.3.2: + version "4.3.4" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7" + integrity sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A== dependencies: acorn "^6.0.1" acorn-walk "^6.0.1" @@ -875,12 +1329,12 @@ acorn-walk@^6.0.1: resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.1.1.tgz#d363b66f5fac5f018ff9c3a1e7b6f8e310cc3913" integrity sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw== -acorn@^5.5.3: - version "5.7.4" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.4.tgz#3e8d8a9947d0599a1796d10225d7432f4a4acf5e" - integrity sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg== +acorn@^6.0.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.1.1.tgz#7d25ae05bb8ad1f9b699108e1094ecd7884adc1f" + integrity sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA== -acorn@^6.0.1, acorn@^6.2.1: +acorn@^6.2.1: version "6.4.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.0.tgz#b659d2ffbafa24baf5db1cdbb2c94a983ecd2784" integrity sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw== @@ -932,14 +1386,15 @@ ajv@^6.10.2: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -alphanum-sort@^1.0.1, alphanum-sort@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" - -ansi-colors@3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.3.tgz#57d35b8686e851e2cc04c403f1c00203976a1813" - integrity sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw== +ajv@^6.12.0: + version "6.12.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.0.tgz#06d60b96d87b8454a5adaba86e7854da629db4b7" + integrity sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" ansi-escapes@^3.0.0: version "3.1.0" @@ -962,10 +1417,6 @@ ansi-regex@^3.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= -ansi-regex@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.0.0.tgz#70de791edf021404c3fd615aa89118ae0432e5a9" - ansi-regex@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" @@ -986,6 +1437,14 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" + integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA== + dependencies: + "@types/color-name" "^1.1.1" + color-convert "^2.0.1" + any-observable@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/any-observable/-/any-observable-0.3.0.tgz#af933475e5806a67d0d7df090dd5e8bef65d119b" @@ -998,12 +1457,13 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" -append-transform@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-1.0.0.tgz#046a52ae582a228bd72f58acfbe2967c678759ab" - integrity sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw== +anymatch@^3.0.3: + version "3.1.1" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" + integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== dependencies: - default-require-extensions "^2.0.0" + normalize-path "^3.0.0" + picomatch "^2.0.4" aproba@^1.0.3, aproba@^1.1.1: version "1.2.0" @@ -1051,18 +1511,8 @@ array-find-index@^1.0.1: array-ify@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" - integrity sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4= - -array-union@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" - dependencies: - array-uniq "^1.0.1" - -array-uniq@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" + integrity sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4= array-unique@^0.3.2: version "0.3.2" @@ -1116,18 +1566,6 @@ async-each@^1.0.1: resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== -async-limiter@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" - integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg== - -async@^2.6.1: - version "2.6.2" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.2.tgz#18330ea7e6e313887f5d2f2a904bac6fe4dd5381" - integrity sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg== - dependencies: - lodash "^4.17.11" - asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -1138,17 +1576,6 @@ atob@^2.1.1: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== -autoprefixer@^6.3.1: - version "6.7.7" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-6.7.7.tgz#1dbd1c835658e35ce3f9984099db00585c782014" - dependencies: - browserslist "^1.7.6" - caniuse-db "^1.0.30000634" - normalize-range "^0.1.2" - num2fraction "^1.2.2" - postcss "^5.2.16" - postcss-value-parser "^3.2.3" - aws-sign2@~0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" @@ -1159,40 +1586,49 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== -babel-code-frame@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" +babel-jest@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-25.3.0.tgz#999d0c19e8427f66b796bf9ea233eedf087b957c" + integrity sha512-qiXeX1Cmw4JZ5yQ4H57WpkO0MZ61Qj+YnsVUwAMnDV5ls+yHon11XjarDdgP7H8lTmiEi6biiZA8y3Tmvx6pCg== dependencies: - chalk "^1.1.3" - esutils "^2.0.2" - js-tokens "^3.0.2" - -babel-jest@^24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.7.1.tgz#73902c9ff15a7dfbdc9994b0b17fcefd96042178" - integrity sha512-GPnLqfk8Mtt0i4OemjWkChi73A3ALs4w2/QbG64uAj8b5mmwzxc7jbJVRZt8NJkxi6FopVHog9S3xX6UJKb2qg== - dependencies: - "@jest/transform" "^24.7.1" - "@jest/types" "^24.7.0" - "@types/babel__core" "^7.1.0" - babel-plugin-istanbul "^5.1.0" - babel-preset-jest "^24.6.0" - chalk "^2.4.2" - slash "^2.0.0" + "@jest/transform" "^25.3.0" + "@jest/types" "^25.3.0" + "@types/babel__core" "^7.1.7" + babel-plugin-istanbul "^6.0.0" + babel-preset-jest "^25.3.0" + chalk "^3.0.0" + slash "^3.0.0" -babel-plugin-istanbul@^5.1.0: - version "5.1.3" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-5.1.3.tgz#202d20ffc96a821c68a3964412de75b9bdeb48c7" - integrity sha512-IFyehbvRRwdBlI1lDp+FaMsWNnEndEk7065IB8NhzBX+ZKLPwPodgk4I5Gobw/8SNUUzso2Dv3hbqRh88eiSCQ== +babel-plugin-apply-mdx-type-prop@^1.5.8: + version "1.5.8" + resolved "https://registry.yarnpkg.com/babel-plugin-apply-mdx-type-prop/-/babel-plugin-apply-mdx-type-prop-1.5.8.tgz#f5ff6d9d7a7fcde0e5f5bd02d3d3cd10e5cca5bf" + integrity sha512-xYp5F9mAnZdDRFSd1vF3XQ0GQUbIulCpnuht2jCmK30GAHL8szVL7TgzwhEGamQ6yJmP/gEyYNM9OR5D2n26eA== dependencies: - find-up "^3.0.0" - istanbul-lib-instrument "^3.2.0" - test-exclude "^5.2.2" + "@babel/helper-plugin-utils" "7.8.3" + "@mdx-js/util" "^1.5.8" + +babel-plugin-extract-import-names@^1.5.8: + version "1.5.8" + resolved "https://registry.yarnpkg.com/babel-plugin-extract-import-names/-/babel-plugin-extract-import-names-1.5.8.tgz#418057261346451d689dff5036168567036b8cf6" + integrity sha512-LcLfP8ZRBZMdMAXHLugyvvd5PY0gMmLMWFogWAUsG32X6TYW2Eavx+il2bw73KDbW+UdCC1bAJ3NuU25T1MI3g== + dependencies: + "@babel/helper-plugin-utils" "7.8.3" + +babel-plugin-istanbul@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz#e159ccdc9af95e0b570c75b4573b7c34d671d765" + integrity sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-instrument "^4.0.0" + test-exclude "^6.0.0" -babel-plugin-jest-hoist@^24.6.0: - version "24.6.0" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.6.0.tgz#f7f7f7ad150ee96d7a5e8e2c5da8319579e78019" - integrity sha512-3pKNH6hMt9SbOv0F3WVmy5CWQ4uogS3k0GY5XLyQHJ9EGpAT9XWkFd2ZiXXtkwFHdAHa5j7w7kfxSP5lAIwu7w== +babel-plugin-jest-hoist@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.2.6.tgz#2af07632b8ac7aad7d414c1e58425d5fc8e84909" + integrity sha512-qE2xjMathybYxjiGFJg0mLFrz0qNp83aNZycWDY/SuHiZNq+vQfRQtuINqyXyue1ELd8Rd+1OhFSLjms8msMbw== dependencies: "@types/babel__traverse" "^7.0.6" @@ -1205,15 +1641,31 @@ babel-polyfill@6.26.0: core-js "^2.5.0" regenerator-runtime "^0.10.5" -babel-preset-jest@^24.6.0: - version "24.6.0" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-24.6.0.tgz#66f06136eefce87797539c0d63f1769cc3915984" - integrity sha512-pdZqLEdmy1ZK5kyRUfvBb2IfTPb2BUvIJczlPspS8fWmBQslNNDBqVfh7BW5leOVJMDZKzjD8XEyABTk6gQ5yw== - dependencies: - "@babel/plugin-syntax-object-rest-spread" "^7.0.0" - babel-plugin-jest-hoist "^24.6.0" - -babel-runtime@6.26.0, babel-runtime@^6.23.0, babel-runtime@^6.26.0: +babel-preset-current-node-syntax@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.2.tgz#fb4a4c51fe38ca60fede1dc74ab35eb843cb41d6" + integrity sha512-u/8cS+dEiK1SFILbOC8/rUI3ml9lboKuuMvZ/4aQnQmhecQAgPw5ew066C1ObnEAUmlx7dv/s2z52psWEtLNiw== + dependencies: + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-bigint" "^7.8.3" + "@babel/plugin-syntax-class-properties" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.8.3" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + +babel-preset-jest@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-25.3.0.tgz#9ab40aee52a19bdc52b8b1ec2403d5914ac3d86b" + integrity sha512-tjdvLKNMwDI9r+QWz9sZUQGTq1dpoxjUqFUpEasAc7MOtHg9XuLT2fx0udFG+k1nvMV0WvHHVAN7VmCZ+1Zxbw== + dependencies: + babel-plugin-jest-hoist "^25.2.6" + babel-preset-current-node-syntax "^0.1.2" + +babel-runtime@^6.23.0, babel-runtime@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= @@ -1221,9 +1673,10 @@ babel-runtime@6.26.0, babel-runtime@^6.23.0, babel-runtime@^6.26.0: core-js "^2.4.0" regenerator-runtime "^0.11.0" -balanced-match@^0.4.2: - version "0.4.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" +bail@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.5.tgz#b6fa133404a392cbc1f8c4bf63f5953351e7a776" + integrity sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ== balanced-match@^1.0.0: version "1.0.0" @@ -1302,6 +1755,13 @@ braces@^2.3.1, braces@^2.3.2: split-string "^3.0.2" to-regex "^3.0.1" +braces@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + brorand@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" @@ -1319,10 +1779,6 @@ browser-resolve@^1.11.3: dependencies: resolve "1.1.7" -browser-stdout@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" - browserify-aes@^1.0.0, browserify-aes@^1.0.4: version "1.2.0" resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" @@ -1382,13 +1838,6 @@ browserify-zlib@^0.2.0: dependencies: pako "~1.0.5" -browserslist@^1.3.6, browserslist@^1.5.2, browserslist@^1.7.6: - version "1.7.7" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-1.7.7.tgz#0bd76704258be829b2398bb50e4b62d1a166b0b9" - dependencies: - caniuse-db "^1.0.30000639" - electron-to-chromium "^1.2.7" - bs-logger@0.x: version "0.2.6" resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" @@ -1486,6 +1935,11 @@ callsites@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.0.0.tgz#fb7eb569b72ad7a45812f93fd9430a3e410b3dd3" +camelcase-css@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5" + integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== + camelcase-keys@^4.0.0: version "4.2.0" resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-4.2.0.tgz#a2aa5fb1af688758259c32c141426d78923b9b77" @@ -1500,24 +1954,11 @@ camelcase@^4.1.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= -camelcase@^5.0.0: +camelcase@^5.0.0, camelcase@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -caniuse-api@^1.5.2: - version "1.6.1" - resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-1.6.1.tgz#b534e7c734c4f81ec5fbe8aca2ad24354b962c6c" - dependencies: - browserslist "^1.3.6" - caniuse-db "^1.0.30000529" - lodash.memoize "^4.1.2" - lodash.uniq "^4.5.0" - -caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639: - version "1.0.30000928" - resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000928.tgz#2e83d2b14276442da239511615eb7c62fed0cfa7" - capture-exit@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" @@ -1530,14 +1971,18 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= -chalk@2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.1.tgz#523fe2678aec7b04e8041909292fe8b17059b796" - integrity sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g== +ccount@^1.0.3: + version "1.0.5" + resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.0.5.tgz#ac82a944905a65ce204eb03023157edf29425c17" + integrity sha512-MOli1W+nfbPLlKEhInaxhRdp7KVLFxLN5ykwzHgLsLI3H3gs5jjFAK4Eoj3OzzcxCtumDaI8onoVDeQyWaNTkw== + +chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" dependencies: - ansi-styles "^3.2.0" + ansi-styles "^3.2.1" escape-string-regexp "^1.0.5" - supports-color "^5.2.0" + supports-color "^5.3.0" chalk@^1.0.0, chalk@^1.1.3: version "1.1.3" @@ -1549,13 +1994,36 @@ chalk@^1.0.0, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.3.1, chalk@^2.4.1, chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" +chalk@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" + integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chalk@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.0.0.tgz#6e98081ed2d17faab615eb52ac66ec1fe6209e72" + integrity sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +character-entities-legacy@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz#94bc1845dce70a5bb9d2ecc748725661293d8fc1" + integrity sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA== + +character-entities@^1.0.0: + version "1.2.4" + resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.2.4.tgz#e12c3939b7eaf4e5b15e7ad4c5e28e1d48c5b16b" + integrity sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw== + +character-reference-invalid@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz#083329cda0eae272ab3dbbf37e9a382c13af1560" + integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg== chardet@^0.7.0: version "0.7.0" @@ -1604,12 +2072,6 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: inherits "^2.0.1" safe-buffer "^5.0.1" -clap@^1.0.9: - version "1.2.3" - resolved "https://registry.yarnpkg.com/clap/-/clap-1.2.3.tgz#4f36745b32008492557f46412d66d50cb99bce51" - dependencies: - chalk "^1.1.3" - class-utils@^0.3.5: version "0.3.6" resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" @@ -1644,35 +2106,35 @@ cli-width@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" -cliui@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" - integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ== +cliui@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" + integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ== dependencies: - string-width "^2.1.1" - strip-ansi "^4.0.0" - wrap-ansi "^2.0.0" - -clone@^1.0.2: - version "1.0.4" - resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^6.2.0" co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= -coa@~1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/coa/-/coa-1.0.4.tgz#a9ef153660d6a86a8bdec0289a5c684d217432fd" - dependencies: - q "^1.1.2" - code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= +collapse-white-space@^1.0.0, collapse-white-space@^1.0.2: + version "1.0.6" + resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.6.tgz#e63629c0016665792060dbbeb79c42239d2c5287" + integrity sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ== + +collect-v8-coverage@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" + integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== + collection-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" @@ -1681,45 +2143,27 @@ collection-visit@^1.0.0: map-visit "^1.0.0" object-visit "^1.0.0" -color-convert@^1.3.0, color-convert@^1.9.0: +color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" dependencies: color-name "1.1.3" +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" -color-name@^1.0.0: +color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - -color-string@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/color-string/-/color-string-0.3.0.tgz#27d46fb67025c5c2fa25993bfbf579e47841b991" - dependencies: - color-name "^1.0.0" - -color@^0.11.0: - version "0.11.4" - resolved "https://registry.yarnpkg.com/color/-/color-0.11.4.tgz#6d7b5c74fb65e841cd48792ad1ed5e07b904d764" - dependencies: - clone "^1.0.2" - color-convert "^1.3.0" - color-string "^0.3.0" - -colormin@^1.0.5: - version "1.1.2" - resolved "https://registry.yarnpkg.com/colormin/-/colormin-1.1.2.tgz#ea2f7420a72b96881a38aae59ec124a6f7298133" - dependencies: - color "^0.11.0" - css-color-names "0.0.4" - has "^1.0.1" - -colors@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== combined-stream@^1.0.6, combined-stream@~1.0.6: version "1.0.7" @@ -1728,23 +2172,29 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -commander@^2.14.1, commander@^2.9.0: - version "2.19.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" +comma-separated-tokens@^1.0.0: + version "1.0.8" + resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz#632b80b6117867a158f1080ad498b2fbe7e3f5ea" + integrity sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw== -commander@^2.20.0, commander@~2.20.3: +commander@^2.20.0: 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== -commitlint@^7.5.2: - version "7.5.2" - resolved "https://registry.yarnpkg.com/commitlint/-/commitlint-7.5.2.tgz#75ebee72175e451f37132113d410f095ea24c56c" - integrity sha512-AnLHmX0E8Y+MulPGOWFwSPG02kKd3GI0daQ7GeJ8blKo+2OrgBRPbnU70vV6rcdz2lwe5pE+shlu8Dx9ftIoxA== +commander@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== + +commitlint@^8.3.5: + version "8.3.5" + resolved "https://registry.yarnpkg.com/commitlint/-/commitlint-8.3.5.tgz#a8fd4aeadf1bac76976bac14127cbfbd666e0aa6" + integrity sha512-vsJr4azgWgwQcBtQOJEMUH5m7yzhD6p09dss7XNs4a88ksBtWAHKXoCKaBCt9ISS1yWcxFRUwnNy7zZhjmnXdg== dependencies: - "@commitlint/cli" "^7.5.2" - read-pkg "3.0.0" - resolve-pkg "1.0.0" + "@commitlint/cli" "^8.3.5" + read-pkg "5.2.0" + resolve-pkg "2.0.0" commondir@^1.0.1: version "1.0.1" @@ -1758,10 +2208,10 @@ compare-func@^1.3.1: array-ify "^1.0.0" dot-prop "^3.0.0" -compare-versions@^3.2.1: - version "3.4.0" - resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.4.0.tgz#e0747df5c9cb7f054d6d3dc3e1dbc444f9e92b26" - integrity sha512-tK69D7oNXXqUW3ZNo/z7NXTEz22TCF0pTE+YF9cxvaAM9XnkLo1fV621xCLrRR6aevJlKxExkss0vWqUCUpqdg== +compare-versions@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.6.0.tgz#1a5689913685e5a87637b8d3ffca75514ec41d62" + integrity sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA== component-emitter@^1.2.1: version "1.3.0" @@ -1811,17 +2261,26 @@ conventional-changelog-angular@^1.3.3: compare-func "^1.3.1" q "^1.5.1" -conventional-commits-parser@^2.1.0: - version "2.1.7" - resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-2.1.7.tgz#eca45ed6140d72ba9722ee4132674d639e644e8e" - integrity sha512-BoMaddIEJ6B4QVMSDu9IkVImlGOSGA1I2BQyOZHeLQ6qVOJLcLKn97+fL6dGbzWEiqDzfH4OkcveULmeq2MHFQ== +conventional-changelog-conventionalcommits@4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.2.1.tgz#d6cb2e2c5d7bfca044a08b9dba84b4082e1a1bd9" + integrity sha512-vC02KucnkNNap+foDKFm7BVUSDAXktXrUJqGszUuYnt6T0J2azsbYz/w9TDc3VsrW2v6JOtiQWVcgZnporHr4Q== + dependencies: + compare-func "^1.3.1" + lodash "^4.2.1" + q "^1.5.1" + +conventional-commits-parser@^3.0.0: + version "3.0.8" + resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-3.0.8.tgz#23310a9bda6c93c874224375e72b09fb275fe710" + integrity sha512-YcBSGkZbYp7d+Cr3NWUeXbPDFUN6g3SaSIzOybi8bjHL5IJ5225OSCxJJ4LgziyEJ7AaJtE9L2/EU6H7Nt/DDQ== dependencies: JSONStream "^1.0.4" - is-text-path "^1.0.0" - lodash "^4.2.1" - meow "^4.0.0" + is-text-path "^1.0.1" + lodash "^4.17.15" + meow "^5.0.0" split2 "^2.0.0" - through2 "^2.0.0" + through2 "^3.0.0" trim-off-newlines "^1.0.0" convert-source-map@^1.1.0, convert-source-map@^1.4.0: @@ -1831,6 +2290,13 @@ convert-source-map@^1.1.0, convert-source-map@^1.4.0: dependencies: safe-buffer "~5.1.1" +convert-source-map@^1.6.0, convert-source-map@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" + integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== + dependencies: + safe-buffer "~5.1.1" + copy-concurrently@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" @@ -1848,12 +2314,10 @@ copy-descriptor@^0.1.0: resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= -copy-dir@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/copy-dir/-/copy-dir-0.4.0.tgz#bb7f603890ec20bf14678cbd6735fa46fc156be7" - integrity sha512-mIefrD97nE1XX2th570tR5UQvW6/92czEPGe+oTtrxPAJl+KOKLpzcRa+e38WEpmt/IUN1n65KvRMzPblR+fDQ== - dependencies: - mkdir-p "~0.0.4" +copy-dir@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/copy-dir/-/copy-dir-1.2.0.tgz#d2634378186d8762769285b36efb307a7945964e" + integrity sha512-UeaUFUIHqGV4brjQ9bY2mHll/hoxyCak2emgmYG72LkGKABHBdBDKFw0H5nTKt5OzVBkBhkxCwnniJBAE7EGEw== core-js@^2.4.0, core-js@^2.5.0: version "2.6.5" @@ -1865,32 +2329,26 @@ core-util-is@1.0.2, core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= -cosmiconfig@5.0.6: - version "5.0.6" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.0.6.tgz#dca6cf680a0bd03589aff684700858c81abeeb39" - dependencies: - is-directory "^0.3.1" - js-yaml "^3.9.0" - parse-json "^4.0.0" - -cosmiconfig@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-4.0.0.tgz#760391549580bbd2df1e562bc177b13c290972dc" - integrity sha512-6e5vDdrXZD+t5v0L8CrurPeybg4Fmf+FCSYxXKYVAqLUtyCSbuyqE059d0kDthTNRzKVjL7QMgNpEUlsoYH3iQ== +cosmiconfig@^5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" + integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA== dependencies: + import-fresh "^2.0.0" is-directory "^0.3.1" - js-yaml "^3.9.0" + js-yaml "^3.13.1" parse-json "^4.0.0" - require-from-string "^2.0.1" -cosmiconfig@^5.0.7: - version "5.0.7" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.0.7.tgz#39826b292ee0d78eda137dfa3173bd1c21a43b04" +cosmiconfig@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" + integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg== dependencies: - import-fresh "^2.0.0" - is-directory "^0.3.1" - js-yaml "^3.9.0" - parse-json "^4.0.0" + "@types/parse-json" "^4.0.0" + import-fresh "^3.1.0" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.7.2" create-ecdh@^4.0.0: version "4.0.3" @@ -1933,6 +2391,15 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" +cross-spawn@^7.0.0: + version "7.0.2" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.2.tgz#d0d7dcfa74e89115c7619f4f721a94e1fdb716d6" + integrity sha512-PD6G8QG3S4FK/XCGFbEQrDqO2AnMMsy0meR7lerlIOHAAbkuavGU/pOqprrlvfTNjvowivTeBsjebAL0NSoMxw== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + crypto-browserify@^3.11.0: version "3.12.0" resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" @@ -1950,100 +2417,46 @@ crypto-browserify@^3.11.0: randombytes "^2.0.0" randomfill "^1.0.3" -css-color-names@0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" - -css-loader@0.28.11: - version "0.28.11" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.28.11.tgz#c3f9864a700be2711bb5a2462b2389b1a392dab7" - dependencies: - babel-code-frame "^6.26.0" - css-selector-tokenizer "^0.7.0" - cssnano "^3.10.0" - icss-utils "^2.1.0" - loader-utils "^1.0.2" - lodash.camelcase "^4.3.0" - object-assign "^4.1.1" - postcss "^5.0.6" - postcss-modules-extract-imports "^1.2.0" - postcss-modules-local-by-default "^1.2.0" - postcss-modules-scope "^1.1.0" - postcss-modules-values "^1.3.0" - postcss-value-parser "^3.3.0" - source-list-map "^2.0.0" - -css-selector-tokenizer@^0.7.0: - version "0.7.1" - resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.7.1.tgz#a177271a8bca5019172f4f891fc6eed9cbf68d5d" +css-loader@3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.5.2.tgz#6483ae56f48a7f901fbe07dde2fc96b01eafab3c" + integrity sha512-hDL0DPopg6zQQSRlZm0hyeaqIRnL0wbWjay9BZxoiJBpbfOW4WHfbaYQhwnDmEa0kZUc1CJ3IFo15ot1yULMIQ== dependencies: - cssesc "^0.1.0" - fastparse "^1.1.1" - regexpu-core "^1.0.0" + camelcase "^5.3.1" + cssesc "^3.0.0" + icss-utils "^4.1.1" + loader-utils "^1.2.3" + normalize-path "^3.0.0" + postcss "^7.0.27" + postcss-modules-extract-imports "^2.0.0" + postcss-modules-local-by-default "^3.0.2" + postcss-modules-scope "^2.2.0" + postcss-modules-values "^3.0.0" + postcss-value-parser "^4.0.3" + schema-utils "^2.6.5" + semver "^6.3.0" -cssesc@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-0.1.0.tgz#c814903e45623371a0477b40109aaafbeeaddbb4" +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== -cssesc@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-2.0.0.tgz#3b13bd1bb1cb36e1bcb5a4dcd27f54c5dcb35703" - -cssnano@^3.10.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-3.10.0.tgz#4f38f6cea2b9b17fa01490f23f1dc68ea65c1c38" - dependencies: - autoprefixer "^6.3.1" - decamelize "^1.1.2" - defined "^1.0.0" - has "^1.0.1" - object-assign "^4.0.1" - postcss "^5.0.14" - postcss-calc "^5.2.0" - postcss-colormin "^2.1.8" - postcss-convert-values "^2.3.4" - postcss-discard-comments "^2.0.4" - postcss-discard-duplicates "^2.0.1" - postcss-discard-empty "^2.0.1" - postcss-discard-overridden "^0.1.1" - postcss-discard-unused "^2.2.1" - postcss-filter-plugins "^2.0.0" - postcss-merge-idents "^2.1.5" - postcss-merge-longhand "^2.0.1" - postcss-merge-rules "^2.0.3" - postcss-minify-font-values "^1.0.2" - postcss-minify-gradients "^1.0.1" - postcss-minify-params "^1.0.4" - postcss-minify-selectors "^2.0.4" - postcss-normalize-charset "^1.1.0" - postcss-normalize-url "^3.0.7" - postcss-ordered-values "^2.1.0" - postcss-reduce-idents "^2.2.2" - postcss-reduce-initial "^1.0.0" - postcss-reduce-transforms "^1.0.3" - postcss-svgo "^2.1.1" - postcss-unique-selectors "^2.0.2" - postcss-value-parser "^3.2.3" - postcss-zindex "^2.0.1" - -csso@~2.3.1: - version "2.3.2" - resolved "https://registry.yarnpkg.com/csso/-/csso-2.3.2.tgz#ddd52c587033f49e94b71fc55569f252e8ff5f85" - dependencies: - clap "^1.0.9" - source-map "^0.5.3" +cssom@^0.4.1: + version "0.4.4" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" + integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== -cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": - version "0.3.6" - resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.6.tgz#f85206cee04efa841f3c5982a74ba96ab20d65ad" - integrity sha512-DtUeseGk9/GBW0hl0vVPpU22iHL6YB5BUX7ml1hB+GMpo0NX5G4voX3kdWiMSEguFtcW3Vh3djqNF4aIe6ne0A== +cssom@~0.3.6: + version "0.3.8" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" + integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== -cssstyle@^1.0.0: - version "1.2.2" - resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.2.2.tgz#427ea4d585b18624f6fdbf9de7a2a1a3ba713077" - integrity sha512-43wY3kl1CVQSvL7wUY1qXkxVGkStjpkDmVjiIKX8R97uhajy8Bybay78uOtqvh7Q5GK75dNPfW0geWjE6qQQow== +cssstyle@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.2.0.tgz#e4c44debccd6b7911ed617a4395e5754bba59992" + integrity sha512-sEb3XFPx3jNnCAMtqrXPDeSgQr+jojtCeNf8cvMNMh1cG970+lljssvQDzPq6lmmJu2Vhqood/gtEomBiHOGnA== dependencies: - cssom "0.3.x" + cssom "~0.3.6" currently-unhandled@^0.4.1: version "0.4.1" @@ -2070,7 +2483,7 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" -data-urls@^1.0.0: +data-urls@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.1.0.tgz#15ee0582baa5e22bb59c77140da8f9c76963bbfe" integrity sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ== @@ -2087,12 +2500,6 @@ de-indent@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d" -debug@3.2.6, debug@^3.1.0, debug@^3.2.6: - version "3.2.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - dependencies: - ms "^2.1.1" - debug@^2.2.0, debug@^2.3.3: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -2100,6 +2507,12 @@ debug@^2.2.0, debug@^2.3.3: dependencies: ms "2.0.0" +debug@^3.2.6: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + dependencies: + ms "^2.1.1" + debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" @@ -2114,7 +2527,7 @@ decamelize-keys@^1.0.0: decamelize "^1.1.0" map-obj "^1.0.0" -decamelize@^1.1.0, decamelize@^1.1.2, decamelize@^1.2.0: +decamelize@^1.1.0, decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -2136,19 +2549,10 @@ deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" -default-require-extensions@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-2.0.0.tgz#f5f8fbb18a7d6d50b21f641f649ebb522cfe24f7" - integrity sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc= - dependencies: - strip-bom "^3.0.0" - -define-properties@^1.1.2: - 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" +deepmerge@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" + integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== define-property@^0.2.5: version "0.2.5" @@ -2172,21 +2576,6 @@ define-property@^2.0.2: is-descriptor "^1.0.2" isobject "^3.0.1" -defined@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" - -del@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/del/-/del-3.0.0.tgz#53ecf699ffcbcb39637691ab13baf160819766e5" - dependencies: - globby "^6.1.0" - is-path-cwd "^1.0.0" - is-path-in-cwd "^1.0.0" - p-map "^1.1.1" - pify "^3.0.0" - rimraf "^2.2.8" - delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -2205,24 +2594,27 @@ des.js@^1.0.0: inherits "^2.0.1" minimalistic-assert "^1.0.0" +detab@2.0.3, detab@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/detab/-/detab-2.0.3.tgz#33e5dd74d230501bd69985a0d2b9a3382699a130" + integrity sha512-Up8P0clUVwq0FnFjDclzZsy9PadzRn5FFxrr47tQQvMHqyiFYVbpH8oXDzWtF0Q7pYy3l+RPmtBl+BsFF6wH0A== + dependencies: + repeat-string "^1.5.4" + detect-libc@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= -detect-newline@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" - integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I= - -diff-sequences@^24.3.0: - version "24.3.0" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.3.0.tgz#0f20e8a1df1abddaf4d9c226680952e64118b975" - integrity sha512-xLqpez+Zj9GKSnPWS0WZw1igGocZ+uua8+y+5dDNTT934N3QuY1sp2LkHzwiaYQGz60hMq0pjAshdeXm5VUOEw== +detect-newline@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" + integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== -diff@3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" +diff-sequences@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.2.6.tgz#5f467c00edd35352b7bca46d7927d60e687a76dd" + integrity sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg== diffie-hellman@^5.0.0: version "5.0.3" @@ -2240,11 +2632,6 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" -dom-walk@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018" - integrity sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg= - domain-browser@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" @@ -2281,10 +2668,6 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" -electron-to-chromium@^1.2.7: - version "1.3.102" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.102.tgz#3ac43a037c8a63bca3dfa189eb3d90f097196787" - elegant-spinner@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e" @@ -2342,74 +2725,53 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.5.1: - version "1.13.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.13.0.tgz#ac86145fdd5099d8dd49558ccba2eaf9b88e24e9" - integrity sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg== - dependencies: - es-to-primitive "^1.2.0" - function-bind "^1.1.1" - has "^1.0.3" - is-callable "^1.1.4" - is-regex "^1.0.4" - object-keys "^1.0.12" - -es-to-primitive@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" - integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.4, escape-string-regexp@^1.0.5: +escape-string-regexp@^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" -escodegen@^1.9.1: - version "1.11.1" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.11.1.tgz#c485ff8d6b4cdb89e27f4a856e91f118401ca510" - integrity sha512-JwiqFD9KdGVVpeuRa68yU3zZnBEOcPs0nKW7wZzXky8Z7tffdYUHbe11bPCV5jYlK6DVdKLWLm0f5I/QlL0Kmw== +escodegen@^1.11.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.1.tgz#ba01d0c8278b5e95a9a45350142026659027a457" + integrity sha512-Bmt7NcRySdIfNPfU2ZoXDrrXsG9ZjvDxcAlMfDUgRBjLOWTuIACXPBFJH7Z+cLb40JeQco5toikyc9t9P8E9SQ== dependencies: - esprima "^3.1.3" + esprima "^4.0.1" estraverse "^4.2.0" esutils "^2.0.2" optionator "^0.8.1" optionalDependencies: source-map "~0.6.1" -eslint-config-prettier@^6.7.0: - version "6.7.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.7.0.tgz#9a876952e12df2b284adbd3440994bf1f39dfbb9" - integrity sha512-FamQVKM3jjUVwhG4hEMnbtsq7xOIDm+SY5iBPfR8gKsJoAB2IQnNF+bk1+8Fy44Nq7PPJaLvkRxILYdJWoguKQ== +eslint-config-prettier@^6.10.1: + version "6.10.1" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.10.1.tgz#129ef9ec575d5ddc0e269667bf09defcd898642a" + integrity sha512-svTy6zh1ecQojvpbJSgH3aei/Rt7C6i090l5f2WQ4aB05lYHeZIR1qL4wZyyILTbtmnbHP5Yn8MrsOJMGa8RkQ== dependencies: get-stdin "^6.0.0" -eslint-plugin-es@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-2.0.0.tgz#0f5f5da5f18aa21989feebe8a73eadefb3432976" - integrity sha512-f6fceVtg27BR02EYnBhgWLFQfK6bN4Ll0nQFrBHOlCsAyxeZkn0NHns5O0YZOPrV1B3ramd6cgFwaoFLcSkwEQ== +eslint-plugin-es@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-3.0.0.tgz#98cb1bc8ab0aa807977855e11ad9d1c9422d014b" + integrity sha512-6/Jb/J/ZvSebydwbBJO1R9E5ky7YeElfK56Veh7e4QGFHCXoIXGH9HhVz+ibJLM3XJ1XjP+T7rKBLUa/Y7eIng== dependencies: - eslint-utils "^1.4.2" + eslint-utils "^2.0.0" regexpp "^3.0.0" -eslint-plugin-node@^10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-10.0.0.tgz#fd1adbc7a300cf7eb6ac55cf4b0b6fc6e577f5a6" - integrity sha512-1CSyM/QCjs6PXaT18+zuAXsjXGIGo5Rw630rSKwokSs2jrYURQc4R5JZpoanNCqwNmepg+0eZ9L7YiRUJb8jiQ== +eslint-plugin-node@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz#c95544416ee4ada26740a30474eefc5402dc671d" + integrity sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g== dependencies: - eslint-plugin-es "^2.0.0" - eslint-utils "^1.4.2" + eslint-plugin-es "^3.0.0" + eslint-utils "^2.0.0" ignore "^5.1.1" minimatch "^3.0.4" resolve "^1.10.1" semver "^6.1.0" -eslint-plugin-prettier@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.2.tgz#432e5a667666ab84ce72f945c72f77d996a5c9ba" - integrity sha512-GlolCC9y3XZfv3RQfwGew7NnuFDKsfI4lbvRK+PIIo23SFH+LemGs4cKwzAaRa+Mdb+lQO/STaIayno8T5sJJA== +eslint-plugin-prettier@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.3.tgz#ae116a0fc0e598fdae48743a4430903de5b4e6ca" + integrity sha512-+HG5jmu/dN3ZV3T6eCD7a4BlAySdN7mLIbJYo0z1cFQuI+r2DiTJEFeF68ots93PsnrMxbzIZ2S/ieX+mkrBeQ== dependencies: prettier-linter-helpers "^1.0.0" @@ -2429,13 +2791,20 @@ eslint-scope@^5.0.0: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-utils@^1.4.2, eslint-utils@^1.4.3: +eslint-utils@^1.4.3: version "1.4.3" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== dependencies: eslint-visitor-keys "^1.1.0" +eslint-utils@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.0.0.tgz#7be1cc70f27a72a76cd14aa698bcabed6890e1cd" + integrity sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA== + dependencies: + eslint-visitor-keys "^1.1.0" + eslint-visitor-keys@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" @@ -2493,16 +2862,7 @@ espree@^6.1.2: acorn-jsx "^5.1.0" eslint-visitor-keys "^1.1.0" -esprima@^2.6.0: - version "2.7.3" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" - -esprima@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" - integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM= - -esprima@^4.0.0: +esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" @@ -2555,6 +2915,22 @@ execa@^1.0.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +execa@^3.2.0, execa@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-3.4.0.tgz#c08ed4550ef65d858fac269ffc8572446f37eb89" + integrity sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g== + dependencies: + cross-spawn "^7.0.0" + get-stream "^5.0.0" + human-signals "^1.1.1" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.0" + onetime "^5.1.0" + p-finally "^2.0.0" + signal-exit "^3.0.2" + strip-final-newline "^2.0.0" + exit@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" @@ -2573,17 +2949,17 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" -expect@^24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/expect/-/expect-24.7.1.tgz#d91defbab4e627470a152feaf35b3c31aa1c7c14" - integrity sha512-mGfvMTPduksV3xoI0xur56pQsg2vJjNf5+a+bXOjqCkiCBbmCayrBbHS/75y9K430cfqyocPr2ZjiNiRx4SRKw== +expect@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-25.3.0.tgz#5fd36e51befd05afb7184bc954f8a4792d184c71" + integrity sha512-buboTXML2h/L0Kh44Ys2Cx49mX20ISc5KDirkxIs3Q9AJv0kazweUAbukegr+nHDOvFRKmxdojjIHCjqAceYfg== dependencies: - "@jest/types" "^24.7.0" - ansi-styles "^3.2.0" - jest-get-type "^24.3.0" - jest-matcher-utils "^24.7.0" - jest-message-util "^24.7.1" - jest-regex-util "^24.3.0" + "@jest/types" "^25.3.0" + ansi-styles "^4.0.0" + jest-get-type "^25.2.6" + jest-matcher-utils "^25.3.0" + jest-message-util "^25.3.0" + jest-regex-util "^25.2.6" extend-shallow@^2.0.1: version "2.0.1" @@ -2600,7 +2976,7 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: assign-symbols "^1.0.0" is-extendable "^1.0.1" -extend@~3.0.2: +extend@^3.0.0, extend@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== @@ -2642,6 +3018,11 @@ fast-deep-equal@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" +fast-deep-equal@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" + integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== + fast-diff@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" @@ -2660,10 +3041,6 @@ fast-levenshtein@~2.0.4, fast-levenshtein@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" -fastparse@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.2.tgz#91728c5a5942eced8531283c79441ee4122c35a9" - fb-watchman@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.0.tgz#54e9abf7dfa2f26cd9b1636c588c1afc05de5d58" @@ -2702,14 +3079,6 @@ file-entry-cache@^5.0.1: dependencies: flat-cache "^2.0.1" -fileset@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/fileset/-/fileset-2.0.3.tgz#8e7548a96d3cc2327ee5e674168723a333bba2a0" - integrity sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA= - dependencies: - glob "^7.0.3" - minimatch "^3.0.3" - fill-range@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" @@ -2720,6 +3089,13 @@ fill-range@^4.0.0: repeat-string "^1.6.1" to-regex-range "^2.1.0" +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + find-cache-dir@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" @@ -2729,22 +3105,33 @@ find-cache-dir@^2.1.0: make-dir "^2.0.0" pkg-dir "^3.0.0" -find-parent-dir@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/find-parent-dir/-/find-parent-dir-0.3.0.tgz#33c44b429ab2b2f0646299c5f9f718f376ff8d54" +find-up@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= + dependencies: + locate-path "^2.0.0" -find-up@3.0.0, find-up@^3.0.0: +find-up@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" dependencies: locate-path "^3.0.0" -find-up@^2.0.0, find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= +find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== dependencies: - locate-path "^2.0.0" + locate-path "^5.0.0" + path-exists "^4.0.0" + +find-versions@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/find-versions/-/find-versions-3.2.0.tgz#10297f98030a786829681690545ef659ed1d254e" + integrity sha512-P8WRou2S+oe222TOCHitLy8zj+SIsVJh52VP4lvXkaFVnOFFdoWv1H1Jjvel1aI6NCFOAaeAVm8qrI0odiLcww== + dependencies: + semver-regex "^2.0.0" flat-cache@^2.0.1: version "2.0.1" @@ -2755,22 +3142,11 @@ flat-cache@^2.0.1: rimraf "2.6.3" write "1.0.3" -flat@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/flat/-/flat-4.1.0.tgz#090bec8b05e39cba309747f1d588f04dbaf98db2" - integrity sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw== - dependencies: - is-buffer "~2.0.3" - flatted@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.1.tgz#69e57caa8f0eacbc281d2e2cb458d46fdb449e08" integrity sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg== -flatten@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782" - flush-write-stream@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.3.tgz#c5d586ef38af6097650b49bc41b55fabb19f35bd" @@ -2840,22 +3216,15 @@ fsevents@^1.2.7: nan "^2.12.1" node-pre-gyp "^0.12.0" -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" +fsevents@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.2.tgz#4c0a1fb34bc68e543b4b82a9ec392bfbda840805" + integrity sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA== functional-red-black-tree@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" -g-status@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/g-status/-/g-status-2.0.2.tgz#270fd32119e8fc9496f066fe5fe88e0a6bc78b97" - dependencies: - arrify "^1.0.1" - matcher "^1.0.0" - simple-git "^1.85.0" - gauge@~2.7.3: version "2.7.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" @@ -2870,7 +3239,12 @@ gauge@~2.7.3: strip-ansi "^3.0.1" wide-align "^1.1.0" -get-caller-file@^1.0.1, get-caller-file@^1.0.2: +gensync@^1.0.0-beta.1: + version "1.0.0-beta.1" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" + integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg== + +get-caller-file@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" @@ -2883,10 +3257,10 @@ get-own-enumerable-property-symbols@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.0.tgz#b877b49a5c16aefac3655f2ed2ea5b684df8d203" -get-stdin@5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398" - integrity sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g= +get-stdin@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-7.0.0.tgz#8d5de98f15171a125c5e516643c7a6d0ea8a96f6" + integrity sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ== get-stdin@^6.0.0: version "6.0.0" @@ -2898,6 +3272,13 @@ get-stream@^4.0.0: dependencies: pump "^3.0.0" +get-stream@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.1.0.tgz#01203cdc92597f9b909067c3e656cc1f4d3c4dc9" + integrity sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw== + dependencies: + pump "^3.0.0" + get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" @@ -2910,24 +3291,21 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" -git-cz@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/git-cz/-/git-cz-3.0.1.tgz#c58b3d8a36697076027b533a431d71a338be9f9c" - integrity sha512-evPRpD+aWSBvsJEcfZPNN6yjDYeCPuG+dKoqFXDJ0pTdQdE4ZqR83+ierTStKmNbk4WxiF5p5Zhj+8TB4dZujg== - dependencies: - global "^4.3.2" - mocha "^6.0.2" +git-cz@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/git-cz/-/git-cz-4.3.1.tgz#1a1a462c2730c17c9fcbfa023beee98fd7659934" + integrity sha512-z+mbD76lbra8ml2nMoOoFkQPJ2OQvg6vpZa8d9VzNEvygEQNysgMkzGPBxqFKw1VIwZ/PHoQgAf70BPp9uElJw== -git-raw-commits@^1.3.0: - version "1.3.6" - resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-1.3.6.tgz#27c35a32a67777c1ecd412a239a6c19d71b95aff" - integrity sha512-svsK26tQ8vEKnMshTDatSIQSMDdz8CxIIqKsvPqbtV23Etmw6VNaFAitu8zwZ0VrOne7FztwPyRLxK7/DIUTQg== +git-raw-commits@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-2.0.3.tgz#f040e67b8445962d4d168903a9e84c4240c17655" + integrity sha512-SoSsFL5lnixVzctGEi2uykjA7B5I0AhO9x6kdzvGRHbxsa6JSEgrgy1esRKsfOKE1cgyOJ/KDR2Trxu157sb8w== dependencies: dargs "^4.0.1" lodash.template "^4.0.2" - meow "^4.0.0" + meow "^5.0.0" split2 "^2.0.0" - through2 "^2.0.0" + through2 "^3.0.0" glob-parent@^3.1.0: version "3.1.0" @@ -2944,7 +3322,7 @@ glob-parent@^5.0.0: dependencies: is-glob "^4.0.1" -glob@7.1.3, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2: +glob@^7.1.1, glob@^7.1.2: version "7.1.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" dependencies: @@ -2967,21 +3345,13 @@ glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: once "^1.3.0" path-is-absolute "^1.0.0" -global-dirs@^0.1.0: +global-dirs@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" integrity sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU= dependencies: ini "^1.3.4" -global@^4.3.2: - version "4.3.2" - resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f" - integrity sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8= - dependencies: - min-document "^2.19.0" - process "~0.5.1" - globals@^11.1.0: version "11.11.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.11.0.tgz#dcf93757fa2de5486fbeed7118538adf789e9c2e" @@ -2994,17 +3364,7 @@ globals@^12.1.0: dependencies: type-fest "^0.8.1" -globby@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" - dependencies: - array-union "^1.0.1" - glob "^7.0.3" - object-assign "^4.0.1" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -graceful-fs@^4.1.11: +graceful-fs@^4.1.11, graceful-fs@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== @@ -3013,32 +3373,17 @@ graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.3: version "4.1.15" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" -growl@1.10.5: - version "1.10.5" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" - growly@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" - integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= - -handlebars@^4.1.0: - version "4.7.2" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.2.tgz#01127b3840156a0927058779482031afe0e730d7" - integrity sha512-4PwqDL2laXtTWZghzzCtunQUTLbo31pcCJrd/B/9JP8XbhVzpS5ZXuKqlOzsd1rtcaLo4KqAn8nl8mkknS4MHw== - dependencies: - neo-async "^2.6.0" - optimist "^0.6.1" - source-map "^0.6.1" - optionalDependencies: - uglify-js "^3.1.4" + integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= har-schema@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= -har-validator@~5.1.0: +har-validator@~5.1.3: version "5.1.3" resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== @@ -3052,18 +3397,14 @@ has-ansi@^2.0.0: dependencies: ansi-regex "^2.0.0" -has-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" - has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" -has-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" - integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q= +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== has-unicode@^2.0.0: version "2.0.1" @@ -3101,12 +3442,6 @@ has-values@^1.0.0: is-number "^3.0.0" kind-of "^4.0.0" -has@^1.0.1, has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - dependencies: - function-bind "^1.1.1" - hash-base@^3.0.0: version "3.0.4" resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" @@ -3127,7 +3462,70 @@ hash.js@^1.0.0, hash.js@^1.0.3: inherits "^2.0.3" minimalistic-assert "^1.0.1" -he@1.2.0, he@^1.1.0: +hast-to-hyperscript@^7.0.0: + version "7.0.4" + resolved "https://registry.yarnpkg.com/hast-to-hyperscript/-/hast-to-hyperscript-7.0.4.tgz#7c4c037d9a8ea19b0a3fdb676a26448ad922353d" + integrity sha512-vmwriQ2H0RPS9ho4Kkbf3n3lY436QKLq6VaGA1pzBh36hBi3tm1DO9bR+kaJIbpT10UqaANDkMjxvjVfr+cnOA== + dependencies: + comma-separated-tokens "^1.0.0" + property-information "^5.3.0" + space-separated-tokens "^1.0.0" + style-to-object "^0.2.1" + unist-util-is "^3.0.0" + web-namespaces "^1.1.2" + +hast-util-from-parse5@^5.0.0: + version "5.0.2" + resolved "https://registry.yarnpkg.com/hast-util-from-parse5/-/hast-util-from-parse5-5.0.2.tgz#afeadc6aab41e6acfe038645bbefd4005c56a475" + integrity sha512-YXFjoRS7ES7PEoLx6uihtSfKTO1s3z/tzGiV5cVpsUiihduogFXubNRCzTIW3yOOGO1nws9CxPq4MbwD39Uo+w== + dependencies: + ccount "^1.0.3" + hastscript "^5.0.0" + property-information "^5.0.0" + web-namespaces "^1.1.2" + xtend "^4.0.1" + +hast-util-parse-selector@^2.0.0: + version "2.2.3" + resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-2.2.3.tgz#57edd449103900c7f63fd9e6f694ffd7e4634719" + integrity sha512-nxbeqjQNxsvo/uYYAw9kij6td05YVUlf1qti09rVfbWSLT5H6wo3c+USIwX6nzXWk5kFZzXnEqO82856r0aM2Q== + +hast-util-raw@5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/hast-util-raw/-/hast-util-raw-5.0.2.tgz#62288f311ec2f35e066a30d5e0277f963ad43a67" + integrity sha512-3ReYQcIHmzSgMq8UrDZHFL0oGlbuVGdLKs8s/Fe8BfHFAyZDrdv1fy/AGn+Fim8ZuvAHcJ61NQhVMtyfHviT/g== + dependencies: + hast-util-from-parse5 "^5.0.0" + hast-util-to-parse5 "^5.0.0" + html-void-elements "^1.0.0" + parse5 "^5.0.0" + unist-util-position "^3.0.0" + web-namespaces "^1.0.0" + xtend "^4.0.0" + zwitch "^1.0.0" + +hast-util-to-parse5@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/hast-util-to-parse5/-/hast-util-to-parse5-5.1.1.tgz#cabf2dbe9ed988a5128fc708457b37cdf535a2e8" + integrity sha512-ivCeAd5FCXr7bapJIVsWMnx/EmbjkkW2TU2hd1prq+jGwiaUoK+FcpjyPNwsC5ogzCwWO669tOqIovGeLc/ntg== + dependencies: + hast-to-hyperscript "^7.0.0" + property-information "^5.0.0" + web-namespaces "^1.0.0" + xtend "^4.0.1" + zwitch "^1.0.0" + +hastscript@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-5.1.1.tgz#71726ee1e97220575d1f29a8e937387d99d48275" + integrity sha512-xHo1Hkcqd0LlWNuDL3/BxwhgAGp3d7uEvCMgCTrBY+zsOooPPH+8KAvW8PCgl+GB8H3H44nfSaF0A4BQ+4xlYg== + dependencies: + comma-separated-tokens "^1.0.0" + hast-util-parse-selector "^2.0.0" + property-information "^5.0.0" + space-separated-tokens "^1.0.0" + +he@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" @@ -3144,10 +3542,6 @@ hosted-git-info@^2.1.4: version "2.7.1" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" -html-comment-regex@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7" - html-encoding-sniffer@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" @@ -3155,6 +3549,16 @@ html-encoding-sniffer@^1.0.2: dependencies: whatwg-encoding "^1.0.1" +html-escaper@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== + +html-void-elements@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-1.0.5.tgz#ce9159494e86d95e45795b166c2021c2cfca4483" + integrity sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w== + http-signature@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" @@ -3169,20 +3573,26 @@ https-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= -husky@^1.1.4: - version "1.3.1" - resolved "https://registry.yarnpkg.com/husky/-/husky-1.3.1.tgz#26823e399300388ca2afff11cfa8a86b0033fae0" +human-signals@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" + integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== + +husky@^4.2.5: + version "4.2.5" + resolved "https://registry.yarnpkg.com/husky/-/husky-4.2.5.tgz#2b4f7622673a71579f901d9885ed448394b5fa36" + integrity sha512-SYZ95AjKcX7goYVZtVZF2i6XiZcHknw50iXvY7b0MiGoj5RwdgRQNEHdb+gPDPCXKlzwrybjFjkL6FOj8uRhZQ== dependencies: - cosmiconfig "^5.0.7" - execa "^1.0.0" - find-up "^3.0.0" - get-stdin "^6.0.0" - is-ci "^2.0.0" - pkg-dir "^3.0.0" - please-upgrade-node "^3.1.1" - read-pkg "^4.0.1" - run-node "^1.0.0" - slash "^2.0.0" + chalk "^4.0.0" + ci-info "^2.0.0" + compare-versions "^3.6.0" + cosmiconfig "^6.0.0" + find-versions "^3.2.0" + opencollective-postinstall "^2.0.2" + pkg-dir "^4.2.0" + please-upgrade-node "^3.2.0" + slash "^3.0.0" + which-pm-runs "^1.0.0" iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4: version "0.4.24" @@ -3190,15 +3600,12 @@ iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4: dependencies: safer-buffer ">= 2.1.2 < 3" -icss-replace-symbols@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded" - -icss-utils@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-2.1.0.tgz#83f0a0ec378bf3246178b6c2ad9136f135b1c962" +icss-utils@^4.0.0, icss-utils@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467" + integrity sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA== dependencies: - postcss "^6.0.1" + postcss "^7.0.14" ieee754@^1.1.4: version "1.1.13" @@ -3239,13 +3646,21 @@ import-fresh@^3.0.0: parent-module "^1.0.0" resolve-from "^4.0.0" -import-local@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" - integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ== +import-fresh@^3.1.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" + integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== dependencies: - pkg-dir "^3.0.0" - resolve-cwd "^2.0.0" + parent-module "^1.0.0" + resolve-from "^4.0.0" + +import-local@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.0.2.tgz#a8cfd0431d1de4a2199703d003e3e62364fa6db6" + integrity sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" imurmurhash@^0.1.4: version "0.1.4" @@ -3272,7 +3687,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.1, inherits@~2.0.3: +inherits@2, inherits@^2.0.0, inherits@^2.0.1, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -3290,6 +3705,11 @@ ini@^1.3.4, ini@~1.3.0: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" +inline-style-parser@0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.1.1.tgz#ec8a3b429274e9c0a1f1c4ffa9453a7fef72cea1" + integrity sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q== + inquirer@^7.0.0: version "7.0.1" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.0.1.tgz#13f7980eedc73c689feff3994b109c4e799c6ebb" @@ -3309,21 +3729,10 @@ inquirer@^7.0.0: strip-ansi "^5.1.0" through "^2.3.6" -invariant@^2.2.4: - version "2.2.4" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" - integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== - dependencies: - loose-envify "^1.0.0" - -invert-kv@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" - integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== - -is-absolute-url@^2.0.0: +ip-regex@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" + integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= is-accessor-descriptor@^0.1.6: version "0.1.6" @@ -3339,6 +3748,19 @@ is-accessor-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" +is-alphabetical@1.0.4, is-alphabetical@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.4.tgz#9e7d6b94916be22153745d184c298cbf986a686d" + integrity sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg== + +is-alphanumerical@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz#7eb9a2431f855f6b1ef1a78e326df515696c4dbf" + integrity sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A== + dependencies: + is-alphabetical "^1.0.0" + is-decimal "^1.0.0" + is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" @@ -3355,10 +3777,10 @@ is-buffer@^1.1.5: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== -is-buffer@~2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.3.tgz#4ecf3fcf749cbd1e472689e109ac66261a25e725" - integrity sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw== +is-buffer@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623" + integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A== is-builtin-module@^1.0.0: version "1.0.0" @@ -3366,11 +3788,6 @@ is-builtin-module@^1.0.0: dependencies: builtin-modules "^1.0.0" -is-callable@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" - integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== - is-ci@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" @@ -3391,10 +3808,10 @@ is-data-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" -is-date-object@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" - integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY= +is-decimal@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.4.tgz#65a3a5958a1c5b63a706e1b333d7cd9f630d3fa5" + integrity sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw== is-descriptor@^0.1.0: version "0.1.6" @@ -3471,6 +3888,11 @@ is-glob@^4.0.0, is-glob@^4.0.1: dependencies: is-extglob "^2.1.1" +is-hexadecimal@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7" + integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw== + is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" @@ -3478,6 +3900,11 @@ is-number@^3.0.0: dependencies: kind-of "^3.0.2" +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + is-obj@^1.0.0, is-obj@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" @@ -3488,26 +3915,15 @@ is-observable@^1.1.0: dependencies: symbol-observable "^1.1.0" -is-path-cwd@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" - -is-path-in-cwd@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz#5ac48b345ef675339bd6c7a48a912110b241cf52" - dependencies: - is-path-inside "^1.0.0" - -is-path-inside@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" - dependencies: - path-is-inside "^1.0.1" - -is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: +is-plain-obj@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" +is-plain-obj@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" @@ -3519,13 +3935,6 @@ is-promise@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" -is-regex@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" - integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE= - dependencies: - has "^1.0.1" - is-regexp@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" @@ -3534,41 +3943,48 @@ is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" -is-svg@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-2.1.0.tgz#cf61090da0d9efbcab8722deba6f032208dbb0e9" - dependencies: - html-comment-regex "^1.1.0" - -is-symbol@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" - integrity sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw== - dependencies: - has-symbols "^1.0.0" +is-stream@^2.0.0: + version "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-text-path@^1.0.0: +is-text-path@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-text-path/-/is-text-path-1.0.1.tgz#4e1aa0fb51bfbcb3e92688001397202c1775b66e" integrity sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4= dependencies: text-extensions "^1.0.0" -is-typedarray@~1.0.0: +is-typedarray@^1.0.0, is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= +is-whitespace-character@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz#0858edd94a95594c7c9dd0b5c174ec6e45ee4aa7" + integrity sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w== + is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== +is-word-character@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-word-character/-/is-word-character-1.0.4.tgz#ce0e73216f98599060592f62ff31354ddbeb0230" + integrity sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA== + is-wsl@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= +is-wsl@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.1.1.tgz#4a1c152d429df3d441669498e2486d3596ebaf1d" + integrity sha512-umZHcSrwlDHo2TGMXv0DZ8dIUGunZ2Iv68YZnrmCiBPkZ4aaOhtv7pXJKeki9k3qJ3RJr0cDyitcl5wEH3AYog== + isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -3595,455 +4011,407 @@ isstream@~0.1.2: resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= -istanbul-api@^2.1.1: - version "2.1.5" - resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-2.1.5.tgz#697b95ec69856c278aacafc0f86ee7392338d5b5" - integrity sha512-meYk1BwDp59Pfse1TvPrkKYgVqAufbdBLEVoqvu/hLLKSaQ054ZTksbNepyc223tMnWdm6AdK2URIJJRqdP87g== - dependencies: - async "^2.6.1" - compare-versions "^3.2.1" - fileset "^2.0.3" - istanbul-lib-coverage "^2.0.4" - istanbul-lib-hook "^2.0.6" - istanbul-lib-instrument "^3.2.0" - istanbul-lib-report "^2.0.7" - istanbul-lib-source-maps "^3.0.5" - istanbul-reports "^2.2.3" - js-yaml "^3.13.0" - make-dir "^2.1.0" - minimatch "^3.0.4" - once "^1.4.0" - -istanbul-lib-coverage@^2.0.2, istanbul-lib-coverage@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#927a354005d99dd43a24607bb8b33fd4e9aca1ad" - integrity sha512-LXTBICkMARVgo579kWDm8SqfB6nvSDKNqIOBEjmJRnL04JvoMHCYGWaMddQnseJYtkEuEvO/sIcOxPLk9gERug== - -istanbul-lib-hook@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-2.0.6.tgz#5baa6067860a38290aef038b389068b225b01b7d" - integrity sha512-829DKONApZ7UCiPXcOYWSgkFXa4+vNYoNOt3F+4uDJLKL1OotAoVwvThoEj1i8jmOj7odbYcR3rnaHu+QroaXg== - dependencies: - append-transform "^1.0.0" +istanbul-lib-coverage@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz#f5944a37c70b550b02a78a5c3b2055b280cec8ec" + integrity sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg== -istanbul-lib-instrument@^3.0.1, istanbul-lib-instrument@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.2.0.tgz#c549208da8a793f6622257a2da83e0ea96ae6a93" - integrity sha512-06IM3xShbNW4NgZv5AP4QH0oHqf1/ivFo8eFys0ZjPXHGldHJQWb3riYOKXqmOqfxXBfxu4B+g/iuhOPZH0RJg== - dependencies: - "@babel/generator" "^7.0.0" - "@babel/parser" "^7.0.0" - "@babel/template" "^7.0.0" - "@babel/traverse" "^7.0.0" - "@babel/types" "^7.0.0" - istanbul-lib-coverage "^2.0.4" - semver "^6.0.0" +istanbul-lib-instrument@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.1.tgz#61f13ac2c96cfefb076fe7131156cc05907874e6" + integrity sha512-imIchxnodll7pvQBYOqUu88EufLCU56LMeFPZZM/fJZ1irYcYdqroaV+ACK1Ila8ls09iEYArp+nqyC6lW1Vfg== + dependencies: + "@babel/core" "^7.7.5" + "@babel/parser" "^7.7.5" + "@babel/template" "^7.7.4" + "@babel/traverse" "^7.7.4" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.0.0" + semver "^6.3.0" -istanbul-lib-report@^2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.7.tgz#370d80d433c4dbc7f58de63618f49599c74bd954" - integrity sha512-wLH6beJBFbRBLiTlMOBxmb85cnVM1Vyl36N48e4e/aTKSM3WbOx7zbVIH1SQ537fhhsPbX0/C5JB4qsmyRXXyA== +istanbul-lib-report@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" + integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== dependencies: - istanbul-lib-coverage "^2.0.4" - make-dir "^2.1.0" - supports-color "^6.0.0" + istanbul-lib-coverage "^3.0.0" + make-dir "^3.0.0" + supports-color "^7.1.0" -istanbul-lib-source-maps@^3.0.1, istanbul-lib-source-maps@^3.0.5: - version "3.0.5" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.5.tgz#1d9ee9d94d2633f15611ee7aae28f9cac6d1aeb9" - integrity sha512-eDhZ7r6r1d1zQPVZehLc3D0K14vRba/eBYkz3rw16DLOrrTzve9RmnkcwrrkWVgO1FL3EK5knujVe5S8QHE9xw== +istanbul-lib-source-maps@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz#75743ce6d96bb86dc7ee4352cf6366a23f0b1ad9" + integrity sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg== dependencies: debug "^4.1.1" - istanbul-lib-coverage "^2.0.4" - make-dir "^2.1.0" - rimraf "^2.6.2" + istanbul-lib-coverage "^3.0.0" source-map "^0.6.1" -istanbul-reports@^2.2.3: - version "2.2.3" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.2.3.tgz#14e0d00ecbfa9387757999cf36599b88e9f2176e" - integrity sha512-T6EbPuc8Cb620LWAYyZ4D8SSn06dY9i1+IgUX2lTH8gbwflMc9Obd33zHTyNX653ybjpamAHS9toKS3E6cGhTw== - dependencies: - handlebars "^4.1.0" - -jest-changed-files@^24.7.0: - version "24.7.0" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-24.7.0.tgz#39d723a11b16ed7b373ac83adc76a69464b0c4fa" - integrity sha512-33BgewurnwSfJrW7T5/ZAXGE44o7swLslwh8aUckzq2e17/2Os1V0QU506ZNik3hjs8MgnEMKNkcud442NCDTw== - dependencies: - "@jest/types" "^24.7.0" - execa "^1.0.0" - throat "^4.0.0" - -jest-cli@^24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-24.7.1.tgz#6093a539073b6f4953145abeeb9709cd621044f1" - integrity sha512-32OBoSCVPzcTslGFl6yVCMzB2SqX3IrWwZCY5mZYkb0D2WsogmU3eV2o8z7+gRQa4o4sZPX/k7GU+II7CxM6WQ== - dependencies: - "@jest/core" "^24.7.1" - "@jest/test-result" "^24.7.1" - "@jest/types" "^24.7.0" - chalk "^2.0.1" +istanbul-reports@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.0.2.tgz#d593210e5000683750cb09fc0644e4b6e27fd53b" + integrity sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw== + dependencies: + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" + +jest-changed-files@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-25.3.0.tgz#85d8de6f4bd13dafda9d7f1e3f2565fc0e183c78" + integrity sha512-eqd5hyLbUjIVvLlJ3vQ/MoPxsxfESVXG9gvU19XXjKzxr+dXmZIqCXiY0OiYaibwlHZBJl2Vebkc0ADEMzCXew== + dependencies: + "@jest/types" "^25.3.0" + execa "^3.2.0" + throat "^5.0.0" + +jest-cli@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-25.3.0.tgz#d9e11f5700cc5946583cf0d01a9bdebceed448d2" + integrity sha512-XpNQPlW1tzpP7RGG8dxpkRegYDuLjzSiENu92+CYM87nEbmEPb3b4+yo8xcsHOnj0AG7DUt9b3uG8LuHI3MDzw== + dependencies: + "@jest/core" "^25.3.0" + "@jest/test-result" "^25.3.0" + "@jest/types" "^25.3.0" + chalk "^3.0.0" exit "^0.1.2" - import-local "^2.0.0" + import-local "^3.0.2" is-ci "^2.0.0" - jest-config "^24.7.1" - jest-util "^24.7.1" - jest-validate "^24.7.0" + jest-config "^25.3.0" + jest-util "^25.3.0" + jest-validate "^25.3.0" prompts "^2.0.1" - realpath-native "^1.1.0" - yargs "^12.0.2" + realpath-native "^2.0.0" + yargs "^15.3.1" -jest-config@^24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-24.7.1.tgz#6c1dd4db82a89710a3cf66bdba97827c9a1cf052" - integrity sha512-8FlJNLI+X+MU37j7j8RE4DnJkvAghXmBWdArVzypW6WxfGuxiL/CCkzBg0gHtXhD2rxla3IMOSUAHylSKYJ83g== +jest-config@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-25.3.0.tgz#112b5e2f2e57dec4501dd2fe979044c06fb1317e" + integrity sha512-CmF1JnNWFmoCSPC4tnU52wnVBpuxHjilA40qH/03IHxIevkjUInSMwaDeE6ACfxMPTLidBGBCO3EbxvzPbo8wA== dependencies: "@babel/core" "^7.1.0" - "@jest/test-sequencer" "^24.7.1" - "@jest/types" "^24.7.0" - babel-jest "^24.7.1" - chalk "^2.0.1" + "@jest/test-sequencer" "^25.3.0" + "@jest/types" "^25.3.0" + babel-jest "^25.3.0" + chalk "^3.0.0" + deepmerge "^4.2.2" glob "^7.1.1" - jest-environment-jsdom "^24.7.1" - jest-environment-node "^24.7.1" - jest-get-type "^24.3.0" - jest-jasmine2 "^24.7.1" - jest-regex-util "^24.3.0" - jest-resolve "^24.7.1" - jest-util "^24.7.1" - jest-validate "^24.7.0" - micromatch "^3.1.10" - pretty-format "^24.7.0" - realpath-native "^1.1.0" - -jest-diff@^24.7.0: - version "24.7.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.7.0.tgz#5d862899be46249754806f66e5729c07fcb3580f" - integrity sha512-ULQZ5B1lWpH70O4xsANC4tf4Ko6RrpwhE3PtG6ERjMg1TiYTC2Wp4IntJVGro6a8HG9luYHhhmF4grF0Pltckg== - dependencies: - chalk "^2.0.1" - diff-sequences "^24.3.0" - jest-get-type "^24.3.0" - pretty-format "^24.7.0" + jest-environment-jsdom "^25.3.0" + jest-environment-node "^25.3.0" + jest-get-type "^25.2.6" + jest-jasmine2 "^25.3.0" + jest-regex-util "^25.2.6" + jest-resolve "^25.3.0" + jest-util "^25.3.0" + jest-validate "^25.3.0" + micromatch "^4.0.2" + pretty-format "^25.3.0" + realpath-native "^2.0.0" + +jest-diff@^25.2.1, jest-diff@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-25.3.0.tgz#0d7d6f5d6171e5dacde9e05be47b3615e147c26f" + integrity sha512-vyvs6RPoVdiwARwY4kqFWd4PirPLm2dmmkNzKqo38uZOzJvLee87yzDjIZLmY1SjM3XR5DwsUH+cdQ12vgqi1w== + dependencies: + chalk "^3.0.0" + diff-sequences "^25.2.6" + jest-get-type "^25.2.6" + pretty-format "^25.3.0" + +jest-docblock@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-25.3.0.tgz#8b777a27e3477cd77a168c05290c471a575623ef" + integrity sha512-aktF0kCar8+zxRHxQZwxMy70stc9R1mOmrLsT5VO3pIT0uzGRSDAXxSlz4NqQWpuLjPpuMhPRl7H+5FRsvIQAg== + dependencies: + detect-newline "^3.0.0" + +jest-each@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-25.3.0.tgz#a319eecf1f6076164ab86f99ca166a55b96c0bd4" + integrity sha512-aBfS4VOf/Qs95yUlX6d6WBv0szvOcTkTTyCIaLuQGj4bSHsT+Wd9dDngVHrCe5uytxpN8VM+NAloI6nbPjXfXw== + dependencies: + "@jest/types" "^25.3.0" + chalk "^3.0.0" + jest-get-type "^25.2.6" + jest-util "^25.3.0" + pretty-format "^25.3.0" + +jest-environment-jsdom@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-25.3.0.tgz#c493ab8c41f28001520c70ef67dd88b88be6af05" + integrity sha512-jdE4bQN+k2QEZ9sWOxsqDJvMzbdFSCN/4tw8X0TQaCqyzKz58PyEf41oIr4WO7ERdp7WaJGBSUKF7imR3UW1lg== + dependencies: + "@jest/environment" "^25.3.0" + "@jest/fake-timers" "^25.3.0" + "@jest/types" "^25.3.0" + jest-mock "^25.3.0" + jest-util "^25.3.0" + jsdom "^15.2.1" + +jest-environment-node@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-25.3.0.tgz#9845f0e63991e8498448cb0ae804935689533db9" + integrity sha512-XO09S29Nx1NU7TiMPHMoDIkxoGBuKSTbE+sHp0gXbeLDXhIdhysUI25kOqFFSD9AuDgvPvxWCXrvNqiFsOH33g== + dependencies: + "@jest/environment" "^25.3.0" + "@jest/fake-timers" "^25.3.0" + "@jest/types" "^25.3.0" + jest-mock "^25.3.0" + jest-util "^25.3.0" + semver "^6.3.0" -jest-docblock@^24.3.0: - version "24.3.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-24.3.0.tgz#b9c32dac70f72e4464520d2ba4aec02ab14db5dd" - integrity sha512-nlANmF9Yq1dufhFlKG9rasfQlrY7wINJbo3q01tu56Jv5eBU5jirylhF2O5ZBnLxzOVBGRDz/9NAwNyBtG4Nyg== - dependencies: - detect-newline "^2.1.0" +jest-get-type@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-25.2.6.tgz#0b0a32fab8908b44d508be81681487dbabb8d877" + integrity sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig== -jest-each@^24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-24.7.1.tgz#fcc7dda4147c28430ad9fb6dc7211cd17ab54e74" - integrity sha512-4fsS8fEfLa3lfnI1Jw6NxjhyRTgfpuOVTeUZZFyVYqeTa4hPhr2YkToUhouuLTrL2eMGOfpbdMyRx0GQ/VooKA== +jest-haste-map@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-25.3.0.tgz#b7683031c9c9ddc0521d311564108b244b11e4c6" + integrity sha512-LjXaRa+F8wwtSxo9G+hHD/Cp63PPQzvaBL9XCVoJD2rrcJO0Zr2+YYzAFWWYJ5GlPUkoaJFJtOuk0sL6MJY80A== dependencies: - "@jest/types" "^24.7.0" - chalk "^2.0.1" - jest-get-type "^24.3.0" - jest-util "^24.7.1" - pretty-format "^24.7.0" - -jest-environment-jsdom@^24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-24.7.1.tgz#a40e004b4458ebeb8a98082df135fd501b9fbbd6" - integrity sha512-Gnhb+RqE2JuQGb3kJsLF8vfqjt3PHKSstq4Xc8ic+ax7QKo4Z0RWGucU3YV+DwKR3T9SYc+3YCUQEJs8r7+Jxg== - dependencies: - "@jest/environment" "^24.7.1" - "@jest/fake-timers" "^24.7.1" - "@jest/types" "^24.7.0" - jest-mock "^24.7.0" - jest-util "^24.7.1" - jsdom "^11.5.1" - -jest-environment-node@^24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-24.7.1.tgz#fa2c047a31522a48038d26ee4f7c8fd9c1ecfe12" - integrity sha512-GJJQt1p9/C6aj6yNZMvovZuxTUd+BEJprETdvTKSb4kHcw4mFj8777USQV0FJoJ4V3djpOwA5eWyPwfq//PFBA== - dependencies: - "@jest/environment" "^24.7.1" - "@jest/fake-timers" "^24.7.1" - "@jest/types" "^24.7.0" - jest-mock "^24.7.0" - jest-util "^24.7.1" - -jest-get-type@^22.1.0: - version "22.4.3" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.4.3.tgz#e3a8504d8479342dd4420236b322869f18900ce4" - -jest-get-type@^24.3.0: - version "24.3.0" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.3.0.tgz#582cfd1a4f91b5cdad1d43d2932f816d543c65da" - integrity sha512-HYF6pry72YUlVcvUx3sEpMRwXEWGEPlJ0bSPVnB3b3n++j4phUEoSPcS6GC0pPJ9rpyPSe4cb5muFo6D39cXow== - -jest-haste-map@^24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.7.1.tgz#772e215cd84080d4bbcb759cfb668ad649a21471" - integrity sha512-g0tWkzjpHD2qa03mTKhlydbmmYiA2KdcJe762SbfFo/7NIMgBWAA0XqQlApPwkWOF7Cxoi/gUqL0i6DIoLpMBw== - dependencies: - "@jest/types" "^24.7.0" - anymatch "^2.0.0" + "@jest/types" "^25.3.0" + anymatch "^3.0.3" fb-watchman "^2.0.0" - graceful-fs "^4.1.15" - invariant "^2.2.4" - jest-serializer "^24.4.0" - jest-util "^24.7.1" - jest-worker "^24.6.0" - micromatch "^3.1.10" + graceful-fs "^4.2.3" + jest-serializer "^25.2.6" + jest-util "^25.3.0" + jest-worker "^25.2.6" + micromatch "^4.0.2" sane "^4.0.3" walker "^1.0.7" + which "^2.0.2" optionalDependencies: - fsevents "^1.2.7" + fsevents "^2.1.2" -jest-jasmine2@^24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-24.7.1.tgz#01398686dabe46553716303993f3be62e5d9d818" - integrity sha512-Y/9AOJDV1XS44wNwCaThq4Pw3gBPiOv/s6NcbOAkVRRUEPu+36L2xoPsqQXsDrxoBerqeyslpn2TpCI8Zr6J2w== +jest-jasmine2@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-25.3.0.tgz#16ae4f68adef65fb45001b26c864bcbcbf972830" + integrity sha512-NCYOGE6+HNzYFSui52SefgpsnIzvxjn6KAgqw66BdRp37xpMD/4kujDHLNW5bS5i53os5TcMn6jYrzQRO8VPrQ== dependencies: "@babel/traverse" "^7.1.0" - "@jest/environment" "^24.7.1" - "@jest/test-result" "^24.7.1" - "@jest/types" "^24.7.0" - chalk "^2.0.1" + "@jest/environment" "^25.3.0" + "@jest/source-map" "^25.2.6" + "@jest/test-result" "^25.3.0" + "@jest/types" "^25.3.0" + chalk "^3.0.0" co "^4.6.0" - expect "^24.7.1" + expect "^25.3.0" is-generator-fn "^2.0.0" - jest-each "^24.7.1" - jest-matcher-utils "^24.7.0" - jest-message-util "^24.7.1" - jest-runtime "^24.7.1" - jest-snapshot "^24.7.1" - jest-util "^24.7.1" - pretty-format "^24.7.0" - throat "^4.0.0" - -jest-leak-detector@^24.7.0: - version "24.7.0" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-24.7.0.tgz#323ff93ed69be12e898f5b040952f08a94288ff9" - integrity sha512-zV0qHKZGXtmPVVzT99CVEcHE9XDf+8LwiE0Ob7jjezERiGVljmqKFWpV2IkG+rkFIEUHFEkMiICu7wnoPM/RoQ== - dependencies: - pretty-format "^24.7.0" - -jest-matcher-utils@^24.7.0: - version "24.7.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.7.0.tgz#bbee1ff37bc8b2e4afcaabc91617c1526af4bcd4" - integrity sha512-158ieSgk3LNXeUhbVJYRXyTPSCqNgVXOp/GT7O94mYd3pk/8+odKTyR1JLtNOQSPzNi8NFYVONtvSWA/e1RDXg== - dependencies: - chalk "^2.0.1" - jest-diff "^24.7.0" - jest-get-type "^24.3.0" - pretty-format "^24.7.0" - -jest-message-util@^24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.7.1.tgz#f1dc3a6c195647096a99d0f1dadbc447ae547018" - integrity sha512-dk0gqVtyqezCHbcbk60CdIf+8UHgD+lmRHifeH3JRcnAqh4nEyPytSc9/L1+cQyxC+ceaeP696N4ATe7L+omcg== + jest-each "^25.3.0" + jest-matcher-utils "^25.3.0" + jest-message-util "^25.3.0" + jest-runtime "^25.3.0" + jest-snapshot "^25.3.0" + jest-util "^25.3.0" + pretty-format "^25.3.0" + throat "^5.0.0" + +jest-leak-detector@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-25.3.0.tgz#5b6bf04903b35be56038915a55f47291771f769f" + integrity sha512-jk7k24dMIfk8LUSQQGN8PyOy9+J0NAfHZWiDmUDYVMctY8FLJQ1eQ8+PjMoN8PgwhLIggUqgYJnyRFvUz3jLRw== + dependencies: + jest-get-type "^25.2.6" + pretty-format "^25.3.0" + +jest-matcher-utils@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-25.3.0.tgz#76765788a26edaa8bc5f0100aea52ae383559648" + integrity sha512-ZBUJ2fchNIZt+fyzkuCFBb8SKaU//Rln45augfUtbHaGyVxCO++ANARdBK9oPGXU3hEDgyy7UHnOP/qNOJXFUg== + dependencies: + chalk "^3.0.0" + jest-diff "^25.3.0" + jest-get-type "^25.2.6" + pretty-format "^25.3.0" + +jest-message-util@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-25.3.0.tgz#e3836826fe5ca538a337b87d9bd2648190867f85" + integrity sha512-5QNy9Id4WxJbRITEbA1T1kem9bk7y2fD0updZMSTNHtbEDnYOGLDPAuFBhFgVmOZpv0n6OMdVkK+WhyXEPCcOw== dependencies: "@babel/code-frame" "^7.0.0" - "@jest/test-result" "^24.7.1" - "@jest/types" "^24.7.0" + "@jest/types" "^25.3.0" "@types/stack-utils" "^1.0.1" - chalk "^2.0.1" - micromatch "^3.1.10" - slash "^2.0.0" + chalk "^3.0.0" + micromatch "^4.0.2" + slash "^3.0.0" stack-utils "^1.0.1" -jest-mock@^24.7.0: - version "24.7.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.7.0.tgz#e49ce7262c12d7f5897b0d8af77f6db8e538023b" - integrity sha512-6taW4B4WUcEiT2V9BbOmwyGuwuAFT2G8yghF7nyNW1/2gq5+6aTqSPcS9lS6ArvEkX55vbPAS/Jarx5LSm4Fng== +jest-mock@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-25.3.0.tgz#d72644509e40987a732a9a2534a1054f4649402c" + integrity sha512-yRn6GbuqB4j3aYu+Z1ezwRiZfp0o9om5uOcBovVtkcRLeBCNP5mT0ysdenUsxAHnQUgGwPOE1wwhtQYe6NKirQ== dependencies: - "@jest/types" "^24.7.0" + "@jest/types" "^25.3.0" jest-pnp-resolver@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz#ecdae604c077a7fbc70defb6d517c3c1c898923a" integrity sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ== -jest-regex-util@^24.3.0: - version "24.3.0" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.3.0.tgz#d5a65f60be1ae3e310d5214a0307581995227b36" - integrity sha512-tXQR1NEOyGlfylyEjg1ImtScwMq8Oh3iJbGTjN7p0J23EuVX1MA8rwU69K4sLbCmwzgCUbVkm0FkSF9TdzOhtg== +jest-regex-util@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-25.2.6.tgz#d847d38ba15d2118d3b06390056028d0f2fd3964" + integrity sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw== -jest-resolve-dependencies@^24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-24.7.1.tgz#cf93bbef26999488a96a2b2012f9fe7375aa378f" - integrity sha512-2Eyh5LJB2liNzfk4eo7bD1ZyBbqEJIyyrFtZG555cSWW9xVHxII2NuOkSl1yUYTAYCAmM2f2aIT5A7HzNmubyg== +jest-resolve-dependencies@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-25.3.0.tgz#b0e4ae053dd44ddacc18c6ee12b5b7c28e445a90" + integrity sha512-bDUlLYmHW+f7J7KgcY2lkq8EMRqKonRl0XoD4Wp5SJkgAxKJnsaIOlrrVNTfXYf+YOu3VCjm/Ac2hPF2nfsCIA== dependencies: - "@jest/types" "^24.7.0" - jest-regex-util "^24.3.0" - jest-snapshot "^24.7.1" + "@jest/types" "^25.3.0" + jest-regex-util "^25.2.6" + jest-snapshot "^25.3.0" -jest-resolve@^24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-24.7.1.tgz#e4150198299298380a75a9fd55043fa3b9b17fde" - integrity sha512-Bgrc+/UUZpGJ4323sQyj85hV9d+ANyPNu6XfRDUcyFNX1QrZpSoM0kE4Mb2vZMAYTJZsBFzYe8X1UaOkOELSbw== +jest-resolve@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-25.3.0.tgz#cb90a5bbea54a02eccdbbf4126a819595dcf91d6" + integrity sha512-IHoQAAybulsJ+ZgWis+ekYKDAoFkVH5Nx/znpb41zRtpxj4fr2WNV9iDqavdSm8GIpMlsfZxbC/fV9DhW0q9VQ== dependencies: - "@jest/types" "^24.7.0" + "@jest/types" "^25.3.0" browser-resolve "^1.11.3" - chalk "^2.0.1" + chalk "^3.0.0" jest-pnp-resolver "^1.2.1" - realpath-native "^1.1.0" - -jest-runner@^24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-24.7.1.tgz#41c8a02a06aa23ea82d8bffd69d7fa98d32f85bf" - integrity sha512-aNFc9liWU/xt+G9pobdKZ4qTeG/wnJrJna3VqunziDNsWT3EBpmxXZRBMKCsNMyfy+A/XHiV+tsMLufdsNdgCw== - dependencies: - "@jest/console" "^24.7.1" - "@jest/environment" "^24.7.1" - "@jest/test-result" "^24.7.1" - "@jest/types" "^24.7.0" - chalk "^2.4.2" + realpath-native "^2.0.0" + resolve "^1.15.1" + +jest-runner@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-25.3.0.tgz#673ef2ac79d2810eb6b2c1a3f82398375a3d1174" + integrity sha512-csDqSC9qGHYWDrzrElzEgFbteztFeZJmKhSgY5jlCIcN0+PhActzRNku0DA1Xa1HxGOb0/AfbP1EGJlP4fGPtA== + dependencies: + "@jest/console" "^25.3.0" + "@jest/environment" "^25.3.0" + "@jest/test-result" "^25.3.0" + "@jest/types" "^25.3.0" + chalk "^3.0.0" exit "^0.1.2" - graceful-fs "^4.1.15" - jest-config "^24.7.1" - jest-docblock "^24.3.0" - jest-haste-map "^24.7.1" - jest-jasmine2 "^24.7.1" - jest-leak-detector "^24.7.0" - jest-message-util "^24.7.1" - jest-resolve "^24.7.1" - jest-runtime "^24.7.1" - jest-util "^24.7.1" - jest-worker "^24.6.0" + graceful-fs "^4.2.3" + jest-config "^25.3.0" + jest-docblock "^25.3.0" + jest-haste-map "^25.3.0" + jest-jasmine2 "^25.3.0" + jest-leak-detector "^25.3.0" + jest-message-util "^25.3.0" + jest-resolve "^25.3.0" + jest-runtime "^25.3.0" + jest-util "^25.3.0" + jest-worker "^25.2.6" source-map-support "^0.5.6" - throat "^4.0.0" - -jest-runtime@^24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-24.7.1.tgz#2ffd70b22dd03a5988c0ab9465c85cdf5d25c597" - integrity sha512-0VAbyBy7tll3R+82IPJpf6QZkokzXPIS71aDeqh+WzPRXRCNz6StQ45otFariPdJ4FmXpDiArdhZrzNAC3sj6A== - dependencies: - "@jest/console" "^24.7.1" - "@jest/environment" "^24.7.1" - "@jest/source-map" "^24.3.0" - "@jest/transform" "^24.7.1" - "@jest/types" "^24.7.0" - "@types/yargs" "^12.0.2" - chalk "^2.0.1" + throat "^5.0.0" + +jest-runtime@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-25.3.0.tgz#af4d40dbcc590fa5de9910cb6a120a13d131050b" + integrity sha512-gn5KYB1wxXRM3nfw8fVpthFu60vxQUCr+ShGq41+ZBFF3DRHZRKj3HDWVAVB4iTNBj2y04QeAo5cZ/boYaPg0w== + dependencies: + "@jest/console" "^25.3.0" + "@jest/environment" "^25.3.0" + "@jest/source-map" "^25.2.6" + "@jest/test-result" "^25.3.0" + "@jest/transform" "^25.3.0" + "@jest/types" "^25.3.0" + "@types/yargs" "^15.0.0" + chalk "^3.0.0" + collect-v8-coverage "^1.0.0" exit "^0.1.2" glob "^7.1.3" - graceful-fs "^4.1.15" - jest-config "^24.7.1" - jest-haste-map "^24.7.1" - jest-message-util "^24.7.1" - jest-mock "^24.7.0" - jest-regex-util "^24.3.0" - jest-resolve "^24.7.1" - jest-snapshot "^24.7.1" - jest-util "^24.7.1" - jest-validate "^24.7.0" - realpath-native "^1.1.0" - slash "^2.0.0" - strip-bom "^3.0.0" - yargs "^12.0.2" - -jest-serializer@^24.4.0: - version "24.4.0" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.4.0.tgz#f70c5918c8ea9235ccb1276d232e459080588db3" - integrity sha512-k//0DtglVstc1fv+GY/VHDIjrtNjdYvYjMlbLUed4kxrE92sIUewOi5Hj3vrpB8CXfkJntRPDRjCrCvUhBdL8Q== - -jest-snapshot@^24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.7.1.tgz#bd5a35f74aedff070975e9e9c90024f082099568" - integrity sha512-8Xk5O4p+JsZZn4RCNUS3pxA+ORKpEKepE+a5ejIKrId9CwrVN0NY+vkqEkXqlstA5NMBkNahXkR/4qEBy0t5yA== + graceful-fs "^4.2.3" + jest-config "^25.3.0" + jest-haste-map "^25.3.0" + jest-message-util "^25.3.0" + jest-mock "^25.3.0" + jest-regex-util "^25.2.6" + jest-resolve "^25.3.0" + jest-snapshot "^25.3.0" + jest-util "^25.3.0" + jest-validate "^25.3.0" + realpath-native "^2.0.0" + slash "^3.0.0" + strip-bom "^4.0.0" + yargs "^15.3.1" + +jest-serializer@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-25.2.6.tgz#3bb4cc14fe0d8358489dbbefbb8a4e708ce039b7" + integrity sha512-RMVCfZsezQS2Ww4kB5HJTMaMJ0asmC0BHlnobQC6yEtxiFKIxohFA4QSXSabKwSggaNkqxn6Z2VwdFCjhUWuiQ== + +jest-snapshot@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-25.3.0.tgz#d4feb457494f4aaedcc83fbbf1ca21808fc3df71" + integrity sha512-GGpR6Oro2htJPKh5RX4PR1xwo5jCEjtvSPLW1IS7N85y+2bWKbiknHpJJRKSdGXghElb5hWaeQASJI4IiRayGg== dependencies: "@babel/types" "^7.0.0" - "@jest/types" "^24.7.0" - chalk "^2.0.1" - expect "^24.7.1" - jest-diff "^24.7.0" - jest-matcher-utils "^24.7.0" - jest-message-util "^24.7.1" - jest-resolve "^24.7.1" - mkdirp "^0.5.1" + "@jest/types" "^25.3.0" + "@types/prettier" "^1.19.0" + chalk "^3.0.0" + expect "^25.3.0" + jest-diff "^25.3.0" + jest-get-type "^25.2.6" + jest-matcher-utils "^25.3.0" + jest-message-util "^25.3.0" + jest-resolve "^25.3.0" + make-dir "^3.0.0" natural-compare "^1.4.0" - pretty-format "^24.7.0" - semver "^5.5.0" + pretty-format "^25.3.0" + semver "^6.3.0" -jest-util@^24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.7.1.tgz#b4043df57b32a23be27c75a2763d8faf242038ff" - integrity sha512-/KilOue2n2rZ5AnEBYoxOXkeTu6vi7cjgQ8MXEkih0oeAXT6JkS3fr7/j8+engCjciOU1Nq5loMSKe0A1oeX0A== +jest-util@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-25.3.0.tgz#e3b0064165818f10d78514696fd25efba82cf049" + integrity sha512-dc625P/KS/CpWTJJJxKc4bA3A6c+PJGBAqS8JTJqx4HqPoKNqXg/Ec8biL2Z1TabwK7E7Ilf0/ukSEXM1VwzNA== dependencies: - "@jest/console" "^24.7.1" - "@jest/fake-timers" "^24.7.1" - "@jest/source-map" "^24.3.0" - "@jest/test-result" "^24.7.1" - "@jest/types" "^24.7.0" - callsites "^3.0.0" - chalk "^2.0.1" - graceful-fs "^4.1.15" + "@jest/types" "^25.3.0" + chalk "^3.0.0" is-ci "^2.0.0" - mkdirp "^0.5.1" - slash "^2.0.0" - source-map "^0.6.0" - -jest-validate@^23.5.0: - version "23.6.0" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-23.6.0.tgz#36761f99d1ed33fcd425b4e4c5595d62b6597474" - dependencies: - chalk "^2.0.1" - jest-get-type "^22.1.0" - leven "^2.1.0" - pretty-format "^23.6.0" - -jest-validate@^24.7.0: - version "24.7.0" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.7.0.tgz#70007076f338528ee1b1c8a8258b1b0bb982508d" - integrity sha512-cgai/gts9B2chz1rqVdmLhzYxQbgQurh1PEQSvSgPZ8KGa1AqXsqC45W5wKEwzxKrWqypuQrQxnF4+G9VejJJA== - dependencies: - "@jest/types" "^24.7.0" - camelcase "^5.0.0" - chalk "^2.0.1" - jest-get-type "^24.3.0" - leven "^2.1.0" - pretty-format "^24.7.0" - -jest-watcher@^24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-24.7.1.tgz#e161363d7f3f4e1ef3d389b7b3a0aad247b673f5" - integrity sha512-Wd6TepHLRHVKLNPacEsBwlp9raeBIO+01xrN24Dek4ggTS8HHnOzYSFnvp+6MtkkJ3KfMzy220KTi95e2rRkrw== - dependencies: - "@jest/test-result" "^24.7.1" - "@jest/types" "^24.7.0" - "@types/yargs" "^12.0.9" - ansi-escapes "^3.0.0" - chalk "^2.0.1" - jest-util "^24.7.1" - string-length "^2.0.0" + make-dir "^3.0.0" + +jest-validate@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-25.3.0.tgz#eb95fdee0039647bcd5d4be641b21e4a142a880c" + integrity sha512-3WuXgIZ4HXUvW6gk9twFFkT9j6zUorKnF2oEY8VEsHb7x5LGvVlN3WUsbqazVKuyXwvikO2zFJ/YTySMsMje2w== + dependencies: + "@jest/types" "^25.3.0" + camelcase "^5.3.1" + chalk "^3.0.0" + jest-get-type "^25.2.6" + leven "^3.1.0" + pretty-format "^25.3.0" + +jest-watcher@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-25.3.0.tgz#fd03fd5ca52f02bd3161ab177466bf1bfdd34e5c" + integrity sha512-dtFkfidFCS9Ucv8azOg2hkiY3sgJEHeTLtGFHS+jfBEE7eRtrO6+2r1BokyDkaG2FOD7485r/SgpC1MFAENfeA== + dependencies: + "@jest/test-result" "^25.3.0" + "@jest/types" "^25.3.0" + ansi-escapes "^4.2.1" + chalk "^3.0.0" + jest-util "^25.3.0" + string-length "^3.1.0" -jest-worker@^24.6.0: - version "24.6.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.6.0.tgz#7f81ceae34b7cde0c9827a6980c35b7cdc0161b3" - integrity sha512-jDwgW5W9qGNvpI1tNnvajh0a5IE/PuGLFmHk6aR/BZFz8tSgGw17GsDPXAJ6p91IvYDjOw8GpFbvvZGAK+DPQQ== +jest-worker@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-25.2.6.tgz#d1292625326794ce187c38f51109faced3846c58" + integrity sha512-FJn9XDUSxcOR4cwDzRfL1z56rUofNTFs539FGASpd50RHdb6EVkhxQqktodW2mI49l+W3H+tFJDotCHUQF6dmA== dependencies: - merge-stream "^1.0.1" - supports-color "^6.1.0" + merge-stream "^2.0.0" + supports-color "^7.0.0" -jest@^24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/jest/-/jest-24.7.1.tgz#0d94331cf510c75893ee32f87d7321d5bf8f2501" - integrity sha512-AbvRar5r++izmqo5gdbAjTeA6uNRGoNRuj5vHB0OnDXo2DXWZJVuaObiGgtlvhKb+cWy2oYbQSfxv7Q7GjnAtA== +jest@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-25.3.0.tgz#7a5e59741d94b8662664c77a9f346246d6bf228b" + integrity sha512-iKd5ShQSHzFT5IL/6h5RZJhApgqXSoPxhp5HEi94v6OAw9QkF8T7X+liEU2eEHJ1eMFYTHmeWLrpBWulsDpaUg== dependencies: - import-local "^2.0.0" - jest-cli "^24.7.1" + "@jest/core" "^25.3.0" + import-local "^3.0.2" + jest-cli "^25.3.0" -js-base64@^2.1.9: - version "2.5.0" - resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.5.0.tgz#42255ba183ab67ce59a0dee640afdc00ab5ae93e" - -"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: +js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" -js-tokens@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" - -js-yaml@3.13.1, js-yaml@^3.13.0, js-yaml@^3.13.1: +js-yaml@^3.13.1: version "3.13.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== @@ -4051,55 +4419,41 @@ js-yaml@3.13.1, js-yaml@^3.13.0, js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" -js-yaml@^3.9.0: - version "3.12.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.1.tgz#295c8632a18a23e054cf5c9d3cecafe678167600" - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -js-yaml@~3.7.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.7.0.tgz#5c967ddd837a9bfdca5f2de84253abe8a1c03b80" - dependencies: - argparse "^1.0.7" - esprima "^2.6.0" - jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= -jsdom@^11.5.1: - version "11.12.0" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.12.0.tgz#1a80d40ddd378a1de59656e9e6dc5a3ba8657bc8" - integrity sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw== +jsdom@^15.2.1: + version "15.2.1" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-15.2.1.tgz#d2feb1aef7183f86be521b8c6833ff5296d07ec5" + integrity sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g== dependencies: abab "^2.0.0" - acorn "^5.5.3" - acorn-globals "^4.1.0" + acorn "^7.1.0" + acorn-globals "^4.3.2" array-equal "^1.0.0" - cssom ">= 0.3.2 < 0.4.0" - cssstyle "^1.0.0" - data-urls "^1.0.0" + cssom "^0.4.1" + cssstyle "^2.0.0" + data-urls "^1.1.0" domexception "^1.0.1" - escodegen "^1.9.1" + escodegen "^1.11.1" html-encoding-sniffer "^1.0.2" - left-pad "^1.3.0" - nwsapi "^2.0.7" - parse5 "4.0.0" + nwsapi "^2.2.0" + parse5 "5.1.0" pn "^1.1.0" - request "^2.87.0" - request-promise-native "^1.0.5" - sax "^1.2.4" + request "^2.88.0" + request-promise-native "^1.0.7" + saxes "^3.1.9" symbol-tree "^3.2.2" - tough-cookie "^2.3.4" + tough-cookie "^3.0.1" w3c-hr-time "^1.0.1" + w3c-xmlserializer "^1.1.2" webidl-conversions "^4.0.2" - whatwg-encoding "^1.0.3" - whatwg-mimetype "^2.1.0" - whatwg-url "^6.4.1" - ws "^5.2.0" + whatwg-encoding "^1.0.5" + whatwg-mimetype "^2.3.0" + whatwg-url "^7.0.0" + ws "^7.0.0" xml-name-validator "^3.0.0" jsesc@^2.5.1: @@ -4107,10 +4461,6 @@ jsesc@^2.5.1: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== -jsesc@~0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" - json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" @@ -4153,6 +4503,13 @@ json5@^2.1.0: dependencies: minimist "^1.2.0" +json5@^2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" + integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== + dependencies: + minimist "^1.2.5" + jsonparse@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" @@ -4197,21 +4554,10 @@ kleur@^3.0.2: resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== -lcid@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" - integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== - dependencies: - invert-kv "^2.0.0" - -left-pad@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e" - integrity sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA== - -leven@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== levn@^0.3.0, levn@~0.3.0: version "0.3.0" @@ -4220,35 +4566,29 @@ levn@^0.3.0, levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" -lint-staged@^8.0.5: - version "8.1.0" - resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-8.1.0.tgz#dbc3ae2565366d8f20efb9f9799d076da64863f2" +lines-and-columns@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" + integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= + +lint-staged@^10.1.3: + version "10.1.3" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-10.1.3.tgz#da27713d3ac519da305381b4de87d5f866b1d2f1" + integrity sha512-o2OkLxgVns5RwSC5QF7waeAjJA5nz5gnUfqL311LkZcFipKV7TztrSlhNUK5nQX9H0E5NELAdduMQ+M/JPT7RQ== dependencies: - "@iamstarkov/listr-update-renderer" "0.4.1" - chalk "^2.3.1" - commander "^2.14.1" - cosmiconfig "5.0.6" - debug "^3.1.0" + chalk "^3.0.0" + commander "^4.0.1" + cosmiconfig "^6.0.0" + debug "^4.1.1" dedent "^0.7.0" - del "^3.0.0" - execa "^1.0.0" - find-parent-dir "^0.3.0" - g-status "^2.0.2" - is-glob "^4.0.0" - is-windows "^1.0.2" - jest-validate "^23.5.0" - listr "^0.14.2" - lodash "^4.17.5" - log-symbols "^2.2.0" - micromatch "^3.1.8" - npm-which "^3.0.1" - p-map "^1.1.1" - path-is-inside "^1.0.2" - pify "^3.0.0" - please-upgrade-node "^3.0.2" - staged-git-files "1.1.2" - string-argv "^0.0.2" - stringify-object "^3.2.2" + execa "^3.4.0" + listr "^0.14.3" + log-symbols "^3.0.0" + micromatch "^4.0.2" + normalize-path "^3.0.0" + please-upgrade-node "^3.2.0" + string-argv "0.3.1" + stringify-object "^3.3.0" listr-silent-renderer@^1.1.1: version "1.1.1" @@ -4276,9 +4616,10 @@ listr-verbose-renderer@^0.5.0: date-fns "^1.27.2" figures "^2.0.0" -listr@^0.14.2: +listr@^0.14.3: version "0.14.3" resolved "https://registry.yarnpkg.com/listr/-/listr-0.14.3.tgz#2fea909604e434be464c50bddba0d496928fa586" + integrity sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA== dependencies: "@samverschueren/stream-to-observable" "^0.3.0" is-observable "^1.1.0" @@ -4328,16 +4669,19 @@ locate-path@^3.0.0: p-locate "^3.0.0" path-exists "^3.0.0" +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + lodash._reinterpolate@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= -lodash.camelcase@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" - -lodash.memoize@4.x, lodash.memoize@^4.1.2: +lodash.memoize@4.x: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" @@ -4361,34 +4705,19 @@ lodash.templatesettings@^4.0.0: dependencies: lodash._reinterpolate "^3.0.0" -lodash.unescape@4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/lodash.unescape/-/lodash.unescape-4.0.1.tgz#bf2249886ce514cda112fae9218cdc065211fc9c" - integrity sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw= - -lodash.uniq@^4.5.0: +lodash.uniq@4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" -lodash@4.17.11: - version "4.17.11" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" - -lodash@^4.17.11, lodash@^4.17.5, lodash@^4.2.1: - version "4.17.13" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.13.tgz#0bdc3a6adc873d2f4e0c4bac285df91b64fc7b93" - integrity sha512-vm3/XWXfWtRua0FkUyEHBZy8kCPjErNBT9fJx8Zvs+U6zjqPbTUOpkaoum3O5uiA8sm+yNMHXfYkTUHFoMxFNA== - -lodash@^4.17.14, lodash@^4.17.15: +lodash@4.17.15, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== -log-symbols@2.2.0, log-symbols@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" - dependencies: - chalk "^2.0.1" +lodash@^4.17.11, lodash@^4.2.1: + version "4.17.13" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.13.tgz#0bdc3a6adc873d2f4e0c4bac285df91b64fc7b93" + integrity sha512-vm3/XWXfWtRua0FkUyEHBZy8kCPjErNBT9fJx8Zvs+U6zjqPbTUOpkaoum3O5uiA8sm+yNMHXfYkTUHFoMxFNA== log-symbols@^1.0.2: version "1.0.2" @@ -4396,6 +4725,13 @@ log-symbols@^1.0.2: dependencies: chalk "^1.0.0" +log-symbols@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-3.0.0.tgz#f3a08516a5dea893336a7dee14d18a1cfdab77c4" + integrity sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ== + dependencies: + chalk "^2.4.2" + log-update@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/log-update/-/log-update-2.3.0.tgz#88328fd7d1ce7938b29283746f0b1bc126b24708" @@ -4404,12 +4740,12 @@ log-update@^2.3.0: cli-cursor "^2.0.0" wrap-ansi "^3.0.1" -loose-envify@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== +lolex@^5.0.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/lolex/-/lolex-5.1.2.tgz#953694d098ce7c07bc5ed6d0e42bc6c0c6d5a367" + integrity sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A== dependencies: - js-tokens "^3.0.0 || ^4.0.0" + "@sinonjs/commons" "^1.7.0" loud-rejection@^1.0.0: version "1.6.0" @@ -4432,7 +4768,7 @@ lru-cache@^5.1.1: dependencies: yallist "^3.0.2" -make-dir@^2.0.0, make-dir@^2.1.0: +make-dir@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== @@ -4440,6 +4776,13 @@ make-dir@^2.0.0, make-dir@^2.1.0: pify "^4.0.1" semver "^5.6.0" +make-dir@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.0.2.tgz#04a1acbf22221e1d6ef43559f43e05a90dbb4392" + integrity sha512-rYKABKutXa6vXTXhoV18cBE7PaewPXHe/Bdq4v+ZLMhxbWApkFFplT0LcbMW+6BbjnQXzZ/sAvSE/JdguApG5w== + dependencies: + semver "^6.0.0" + make-error@1.x: version "1.3.5" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.5.tgz#efe4e81f6db28cadd605c70f29c831b58ef776c8" @@ -4452,18 +4795,6 @@ makeerror@1.0.x: dependencies: tmpl "1.0.x" -mamacro@^0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/mamacro/-/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4" - integrity sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA== - -map-age-cleaner@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" - integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== - dependencies: - p-defer "^1.0.0" - map-cache@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" @@ -4486,15 +4817,10 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" -matcher@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/matcher/-/matcher-1.1.1.tgz#51d8301e138f840982b338b116bb0c09af62c1c2" - dependencies: - escape-string-regexp "^1.0.4" - -math-expression-evaluator@^1.2.14: - version "1.2.17" - resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz#de819fdbcd84dccd8fae59c6aeb79615b9d266ac" +markdown-escapes@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/markdown-escapes/-/markdown-escapes-1.0.4.tgz#c95415ef451499d7602b91095f3c8e8975f78535" + integrity sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg== md5.js@^1.3.4: version "1.3.5" @@ -4505,14 +4831,39 @@ md5.js@^1.3.4: inherits "^2.0.1" safe-buffer "^5.1.2" -mem@^4.0.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" - integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== +mdast-squeeze-paragraphs@^3.0.0: + version "3.0.5" + resolved "https://registry.yarnpkg.com/mdast-squeeze-paragraphs/-/mdast-squeeze-paragraphs-3.0.5.tgz#f428b6b944f8faef454db9b58f170c4183cb2e61" + integrity sha512-xX6Vbe348Y/rukQlG4W3xH+7v4ZlzUbSY4HUIQCuYrF2DrkcHx584mCaFxkWoDZKNUfyLZItHC9VAqX3kIP7XA== dependencies: - map-age-cleaner "^0.1.1" - mimic-fn "^2.0.0" - p-is-promise "^2.0.0" + unist-util-remove "^1.0.0" + +mdast-util-definitions@^1.2.0: + version "1.2.5" + resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-1.2.5.tgz#3fe622a4171c774ebd06f11e9f8af7ec53ea5c74" + integrity sha512-CJXEdoLfiISCDc2JB6QLb79pYfI6+GcIH+W2ox9nMc7od0Pz+bovcHsiq29xAQY6ayqe/9CsK2VzkSJdg1pFYA== + dependencies: + unist-util-visit "^1.0.0" + +mdast-util-to-hast@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-7.0.0.tgz#589b562ce1ae0a7849e6c38536a9e7bc4f415e54" + integrity sha512-vxnXKSZgvPG2grZM3kxaF052pxsLtq8TPAkiMkqYj1nFTOazYUPXt3LFYIEB6Ws/IX7Uyvljzk64kD6DwZl/wQ== + dependencies: + collapse-white-space "^1.0.0" + detab "^2.0.0" + mdast-util-definitions "^1.2.0" + mdurl "^1.0.1" + trim-lines "^1.0.0" + unist-builder "^2.0.0" + unist-util-generated "^1.0.0" + unist-util-position "^3.0.0" + unist-util-visit "^2.0.0" + +mdurl@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" + integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4= memory-fs@^0.4.0, memory-fs@^0.4.1: version "0.4.1" @@ -4521,35 +4872,20 @@ memory-fs@^0.4.0, memory-fs@^0.4.1: errno "^0.1.3" readable-stream "^2.0.1" -meow@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/meow/-/meow-5.0.0.tgz#dfc73d63a9afc714a5e371760eb5c88b91078aa4" - integrity sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig== - dependencies: - camelcase-keys "^4.0.0" - decamelize-keys "^1.0.0" - loud-rejection "^1.0.0" - minimist-options "^3.0.1" - normalize-package-data "^2.3.4" - read-pkg-up "^3.0.0" - redent "^2.0.0" - trim-newlines "^2.0.0" - yargs-parser "^10.0.0" - -meow@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/meow/-/meow-4.0.1.tgz#d48598f6f4b1472f35bf6317a95945ace347f975" - integrity sha512-xcSBHD5Z86zaOc+781KrupuHAzeGXSLtiAOmBsiLDiPSaYSB6hdew2ng9EBAnZ62jagG9MHAOdxpDi/lWBFJ/A== +meow@5.0.0, meow@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-5.0.0.tgz#dfc73d63a9afc714a5e371760eb5c88b91078aa4" + integrity sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig== dependencies: camelcase-keys "^4.0.0" decamelize-keys "^1.0.0" loud-rejection "^1.0.0" - minimist "^1.1.3" minimist-options "^3.0.1" normalize-package-data "^2.3.4" read-pkg-up "^3.0.0" redent "^2.0.0" trim-newlines "^2.0.0" + yargs-parser "^10.0.0" merge-source-map@^1.1.0: version "1.1.0" @@ -4557,18 +4893,20 @@ merge-source-map@^1.1.0: dependencies: source-map "^0.6.1" -merge-stream@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-1.0.1.tgz#4041202d508a342ba00174008df0c251b8c135e1" - integrity sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE= - dependencies: - readable-stream "^2.0.1" +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== -microevent.ts@~0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/microevent.ts/-/microevent.ts-0.1.0.tgz#390748b8a515083e6b63cd5112a3f18c2fe0eba8" +micromatch@4.x, micromatch@^4.0.0, micromatch@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" + integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== + dependencies: + braces "^3.0.1" + picomatch "^2.0.5" -micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8: +micromatch@^3.1.10, micromatch@^3.1.4: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" dependencies: @@ -4610,18 +4948,11 @@ mimic-fn@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" -mimic-fn@^2.0.0, mimic-fn@^2.1.0: +mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== -min-document@^2.19.0: - version "2.19.0" - resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" - integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU= - dependencies: - dom-walk "^0.1.0" - minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" @@ -4632,7 +4963,7 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= -minimatch@3.0.4, minimatch@^3.0.3, minimatch@^3.0.4: +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== @@ -4652,15 +4983,15 @@ minimist@0.0.8: resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= -minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0: +minimist@^1.1.1, minimist@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= -minimist@~0.0.1: - version "0.0.10" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" - integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= +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== minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0: version "2.9.0" @@ -4700,55 +5031,34 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -mkdir-p@~0.0.4: - version "0.0.7" - resolved "https://registry.yarnpkg.com/mkdir-p/-/mkdir-p-0.0.7.tgz#24c5dbe26da3a99ef158a1eef9a5c2dd9de5683c" - integrity sha1-JMXb4m2jqZ7xWKHu+aXC3Z3laDw= +mkdirp@1.x: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== -mkdirp@0.5.1, mkdirp@0.x, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: +mkdirp@^0.5.0, mkdirp@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= dependencies: minimist "0.0.8" -mocha@^6.0.2: - version "6.1.4" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-6.1.4.tgz#e35fada242d5434a7e163d555c705f6875951640" - integrity sha512-PN8CIy4RXsIoxoFJzS4QNnCH4psUCPWc4/rPrst/ecSJJbLBkubMiyGCP2Kj/9YnWbotFqAoeXyXMucj7gwCFg== - dependencies: - ansi-colors "3.2.3" - browser-stdout "1.3.1" - debug "3.2.6" - diff "3.5.0" - escape-string-regexp "1.0.5" - find-up "3.0.0" - glob "7.1.3" - growl "1.10.5" - he "1.2.0" - js-yaml "3.13.1" - log-symbols "2.2.0" - minimatch "3.0.4" - mkdirp "0.5.1" - ms "2.1.1" - node-environment-flags "1.0.5" - object.assign "4.1.0" - strip-json-comments "2.0.1" - supports-color "6.0.0" - which "1.3.1" - wide-align "1.1.3" - yargs "13.2.2" - yargs-parser "13.0.0" - yargs-unparser "1.5.0" - -mock-fs@^4.3.0: - version "4.10.4" - resolved "https://registry.yarnpkg.com/mock-fs/-/mock-fs-4.10.4.tgz#4eaa3d6f7da2f44e1f3dd6b462cbbcb7b082e3d4" - integrity sha512-gDfZDLaPIvtOusbusLinfx6YSe2YpQsDT8qdP41P47dQ/NQggtkHukz7hwqgt8QvMBmAv+Z6DGmXPyb5BWX2nQ== - -mock-require@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/mock-require/-/mock-require-3.0.2.tgz#7ce759b559e3b194be5f20a5b1cece0eb363f53d" +mkdirp@^0.5.3: + 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" + +mock-fs@^4.11.0: + version "4.11.0" + resolved "https://registry.yarnpkg.com/mock-fs/-/mock-fs-4.11.0.tgz#0828107e4b843a6ba855ecebfe3c6e073b69db92" + integrity sha512-Yp4o3/ZA15wsXqJTT+R+9w2AYIkD1i80Lds47wDbuUhOvQvm+O2EfjFZSz0pMgZZSPHRhGxgcd2+GL4+jZMtdw== + +mock-require@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/mock-require/-/mock-require-3.0.3.tgz#ccd544d9eae81dd576b3f219f69ec867318a1946" + integrity sha512-lLzfLHcyc10MKQnNUCv7dMcoY/2Qxd6wJfbqCcVk3LDb8An4hF6ohk5AztrvgKhJCqj36uyzi/p5se+tvyD+Wg== dependencies: get-caller-file "^1.0.2" normalize-path "^2.1.1" @@ -4769,7 +5079,7 @@ ms@2.0.0: resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= -ms@2.1.1, ms@^2.1.1: +ms@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" @@ -4800,10 +5110,10 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" -nativescript-vue-template-compiler@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/nativescript-vue-template-compiler/-/nativescript-vue-template-compiler-2.4.0.tgz#af77f127c611aa9e32c98a15a2403633995d6f57" - integrity sha512-EPkYmPkfh/UvkcJ4aXvNaj5c7NK1LqvdSW3rs6qaUyLJJuIvMZm3vPPQen6Mn8TGDIZQzwykA+HLniObVV4CJA== +nativescript-vue-template-compiler@^2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/nativescript-vue-template-compiler/-/nativescript-vue-template-compiler-2.5.1.tgz#7e4cdd28b75572e8c8b146f28fae9d8f719f3036" + integrity sha512-kbakGg71aTytDTa5M12rie8/5AdNkN1NpcnQMPiZY/CxQ2Tf2NUVnu0EFbBGcO7gS+TeKiYIKiA28R1e6YCLqQ== dependencies: de-indent "^1.0.2" he "^1.1.0" @@ -4821,7 +5131,7 @@ needle@^2.2.1: iconv-lite "^0.4.4" sax "^1.2.4" -neo-async@^2.5.0, neo-async@^2.6.0, neo-async@^2.6.1: +neo-async@^2.5.0, neo-async@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== @@ -4830,14 +5140,6 @@ nice-try@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" -node-environment-flags@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/node-environment-flags/-/node-environment-flags-1.0.5.tgz#fa930275f5bf5dae188d6192b24b4c8bbac3d76a" - integrity sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ== - dependencies: - object.getownpropertydescriptors "^2.0.3" - semver "^5.7.0" - node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -4877,16 +5179,16 @@ node-modules-regexp@^1.0.0: resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= -node-notifier@^5.2.1: - version "5.4.0" - resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.4.0.tgz#7b455fdce9f7de0c63538297354f3db468426e6a" - integrity sha512-SUDEb+o71XR5lXSTyivXd9J7fCloE3SyP4lSgt3lU2oSANiox+SxlNRGPjDKrwU1YN3ix2KN/VGGCg0t01rttQ== +node-notifier@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-6.0.0.tgz#cea319e06baa16deec8ce5cd7f133c4a46b68e12" + integrity sha512-SVfQ/wMw+DesunOm5cKqr6yDcvUTDl/yc97ybGHMrteNEY6oekXpNpS3lZwgLlwz0FLgHoiW28ZpmBHUDg37cw== dependencies: growly "^1.3.0" - is-wsl "^1.1.0" - semver "^5.5.0" + is-wsl "^2.1.1" + semver "^6.3.0" shellwords "^0.1.1" - which "^1.3.0" + which "^1.3.1" node-pre-gyp@^0.12.0: version "0.12.0" @@ -4921,7 +5223,7 @@ normalize-package-data@^2.3.2: semver "2 || 3 || 4 || 5" validate-npm-package-license "^3.0.1" -normalize-package-data@^2.3.4: +normalize-package-data@^2.3.4, normalize-package-data@^2.5.0: 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== @@ -4943,19 +5245,6 @@ normalize-path@^3.0.0: resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -normalize-range@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" - -normalize-url@^1.4.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-1.9.1.tgz#2cc0d66b31ea23036458436e3620d85954c66c3c" - dependencies: - object-assign "^4.0.1" - prepend-http "^1.0.0" - query-string "^4.1.0" - sort-keys "^1.0.0" - npm-bundled@^1.0.1: version "1.0.6" resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.6.tgz#e7ba9aadcef962bb61248f91721cd932b3fe6bdd" @@ -4969,25 +5258,18 @@ npm-packlist@^1.1.6: ignore-walk "^3.0.1" npm-bundled "^1.0.1" -npm-path@^2.0.2: - version "2.0.4" - resolved "https://registry.yarnpkg.com/npm-path/-/npm-path-2.0.4.tgz#c641347a5ff9d6a09e4d9bce5580c4f505278e64" - dependencies: - which "^1.2.10" - 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" dependencies: path-key "^2.0.0" -npm-which@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/npm-which/-/npm-which-3.0.1.tgz#9225f26ec3a285c209cae67c3b11a6b4ab7140aa" +npm-run-path@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== dependencies: - commander "^2.9.0" - npm-path "^2.0.2" - which "^1.2.10" + path-key "^3.0.0" npmlog@^4.0.2: version "4.1.2" @@ -4999,26 +5281,22 @@ npmlog@^4.0.2: gauge "~2.7.3" set-blocking "~2.0.0" -num2fraction@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" - number-is-nan@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= -nwsapi@^2.0.7: - version "2.1.3" - resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.1.3.tgz#25f3a5cec26c654f7376df6659cdf84b99df9558" - integrity sha512-RowAaJGEgYXEZfQ7tvvdtAQUKPyTR6T6wNu0fwlNsGQYr/h3yQc6oI8WnVZh3Y/Sylwc+dtAlvPqfFZjhTyk3A== +nwsapi@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" + integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== oauth-sign@~0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== -object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: +object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -5031,11 +5309,6 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" -object-keys@^1.0.11, object-keys@^1.0.12: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - object-visit@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" @@ -5043,24 +5316,6 @@ object-visit@^1.0.0: dependencies: isobject "^3.0.0" -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" - -object.getownpropertydescriptors@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" - integrity sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY= - dependencies: - define-properties "^1.1.2" - es-abstract "^1.5.1" - object.pick@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" @@ -5088,13 +5343,10 @@ onetime@^5.1.0: dependencies: mimic-fn "^2.1.0" -optimist@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" - integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY= - dependencies: - minimist "~0.0.1" - wordwrap "~0.0.2" +opencollective-postinstall@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz#5657f1bede69b6e33a45939b061eb53d3c6c3a89" + integrity sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw== optionator@^0.8.1: version "0.8.2" @@ -5129,15 +5381,6 @@ os-homedir@^1.0.0: resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= -os-locale@^3.0.0, os-locale@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" - integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== - dependencies: - execa "^1.0.0" - lcid "^2.0.0" - mem "^4.0.0" - os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" @@ -5150,26 +5393,19 @@ osenv@^0.1.4: os-homedir "^1.0.0" os-tmpdir "^1.0.0" -p-defer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" - integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= - -p-each-series@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-1.0.0.tgz#930f3d12dd1f50e7434457a22cd6f04ac6ad7f71" - integrity sha1-kw89Et0fUOdDRFeiLNbwSsatf3E= - dependencies: - p-reduce "^1.0.0" +p-each-series@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-2.1.0.tgz#961c8dd3f195ea96c747e636b262b800a6b1af48" + integrity sha512-ZuRs1miPT4HrjFa+9fRfOFXxGJfORgelKV9f9nNOWw2gl6gVsRaVDOQP0+MI0G0wGKns1Yacsu0GjOFbTK0JFQ== p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" -p-is-promise@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" - integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== +p-finally@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-2.0.1.tgz#bd6fcaa9c559a096b680806f4d657b3f0f240561" + integrity sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw== p-limit@^1.1.0: version "1.3.0" @@ -5184,6 +5420,13 @@ p-limit@^2.0.0: dependencies: p-try "^2.0.0" +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + p-locate@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" @@ -5197,19 +5440,17 @@ p-locate@^3.0.0: dependencies: p-limit "^2.0.0" -p-map@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" p-map@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.0.0.tgz#be18c5a5adeb8e156460651421aceca56c213a50" -p-reduce@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" - integrity sha1-GMKw3ZNqRpClKfgjH1ig/bakffo= - p-try@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" @@ -5250,6 +5491,18 @@ parse-asn1@^5.0.0: pbkdf2 "^3.0.3" safe-buffer "^5.1.1" +parse-entities@^1.1.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-1.2.2.tgz#c31bf0f653b6661354f8973559cb86dd1d5edf50" + integrity sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg== + dependencies: + character-entities "^1.0.0" + character-entities-legacy "^1.0.0" + character-reference-invalid "^1.0.0" + is-alphanumerical "^1.0.0" + is-decimal "^1.0.0" + is-hexadecimal "^1.0.0" + parse-json@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" @@ -5257,10 +5510,25 @@ parse-json@^4.0.0: error-ex "^1.3.1" json-parse-better-errors "^1.0.1" -parse5@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" - integrity sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA== +parse-json@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.0.0.tgz#73e5114c986d143efa3712d4ea24db9a4266f60f" + integrity sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + lines-and-columns "^1.1.6" + +parse5@5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.0.tgz#c59341c9723f414c452975564c7c00a68d58acd2" + integrity sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ== + +parse5@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178" + integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug== pascalcase@^0.1.1: version "0.1.1" @@ -5281,19 +5549,25 @@ path-exists@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + 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-is-inside@^1.0.1, path-is-inside@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" - 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" +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + path-parse@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" @@ -5305,6 +5579,11 @@ path-type@^3.0.0: dependencies: pify "^3.0.0" +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + pbkdf2@^3.0.3: version "3.0.17" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" @@ -5321,9 +5600,10 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= -pify@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" +picomatch@^2.0.4, picomatch@^2.0.5: + version "2.2.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" + integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== pify@^3.0.0: version "3.0.0" @@ -5334,16 +5614,6 @@ pify@^4.0.1: resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - dependencies: - pinkie "^2.0.0" - -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - pirates@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" @@ -5357,9 +5627,17 @@ pkg-dir@^3.0.0: dependencies: find-up "^3.0.0" -please-upgrade-node@^3.0.2, please-upgrade-node@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.1.1.tgz#ed320051dfcc5024fae696712c8288993595e8ac" +pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +please-upgrade-node@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942" + integrity sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg== dependencies: semver-compare "^1.0.0" @@ -5373,262 +5651,57 @@ posix-character-classes@^0.1.0: resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= -postcss-calc@^5.2.0: - version "5.3.1" - resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-5.3.1.tgz#77bae7ca928ad85716e2fda42f261bf7c1d65b5e" - dependencies: - postcss "^5.0.2" - postcss-message-helpers "^2.0.0" - reduce-css-calc "^1.2.6" - -postcss-colormin@^2.1.8: - version "2.2.2" - resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-2.2.2.tgz#6631417d5f0e909a3d7ec26b24c8a8d1e4f96e4b" - dependencies: - colormin "^1.0.5" - postcss "^5.0.13" - postcss-value-parser "^3.2.3" - -postcss-convert-values@^2.3.4: - version "2.6.1" - resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-2.6.1.tgz#bbd8593c5c1fd2e3d1c322bb925dcae8dae4d62d" - dependencies: - postcss "^5.0.11" - postcss-value-parser "^3.1.2" - -postcss-discard-comments@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz#befe89fafd5b3dace5ccce51b76b81514be00e3d" - dependencies: - postcss "^5.0.14" - -postcss-discard-duplicates@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-2.1.0.tgz#b9abf27b88ac188158a5eb12abcae20263b91932" - dependencies: - postcss "^5.0.4" - -postcss-discard-empty@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz#d2b4bd9d5ced5ebd8dcade7640c7d7cd7f4f92b5" - dependencies: - postcss "^5.0.14" - -postcss-discard-overridden@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz#8b1eaf554f686fb288cd874c55667b0aa3668d58" - dependencies: - postcss "^5.0.16" - -postcss-discard-unused@^2.2.1: - version "2.2.3" - resolved "https://registry.yarnpkg.com/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz#bce30b2cc591ffc634322b5fb3464b6d934f4433" - dependencies: - postcss "^5.0.14" - uniqs "^2.0.0" - -postcss-filter-plugins@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/postcss-filter-plugins/-/postcss-filter-plugins-2.0.3.tgz#82245fdf82337041645e477114d8e593aa18b8ec" - dependencies: - postcss "^5.0.4" - -postcss-merge-idents@^2.1.5: - version "2.1.7" - resolved "https://registry.yarnpkg.com/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz#4c5530313c08e1d5b3bbf3d2bbc747e278eea270" - dependencies: - has "^1.0.1" - postcss "^5.0.10" - postcss-value-parser "^3.1.1" - -postcss-merge-longhand@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-2.0.2.tgz#23d90cd127b0a77994915332739034a1a4f3d658" - dependencies: - postcss "^5.0.4" - -postcss-merge-rules@^2.0.3: - version "2.1.2" - resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-2.1.2.tgz#d1df5dfaa7b1acc3be553f0e9e10e87c61b5f721" - dependencies: - browserslist "^1.5.2" - caniuse-api "^1.5.2" - postcss "^5.0.4" - postcss-selector-parser "^2.2.2" - vendors "^1.0.0" - -postcss-message-helpers@^2.0.0: +postcss-modules-extract-imports@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz#a4f2f4fab6e4fe002f0aed000478cdf52f9ba60e" - -postcss-minify-font-values@^1.0.2: - version "1.0.5" - resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz#4b58edb56641eba7c8474ab3526cafd7bbdecb69" - dependencies: - object-assign "^4.0.1" - postcss "^5.0.4" - postcss-value-parser "^3.0.2" - -postcss-minify-gradients@^1.0.1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz#5dbda11373703f83cfb4a3ea3881d8d75ff5e6e1" - dependencies: - postcss "^5.0.12" - postcss-value-parser "^3.3.0" - -postcss-minify-params@^1.0.4: - version "1.2.2" - resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz#ad2ce071373b943b3d930a3fa59a358c28d6f1f3" - dependencies: - alphanum-sort "^1.0.1" - postcss "^5.0.2" - postcss-value-parser "^3.0.2" - uniqs "^2.0.0" - -postcss-minify-selectors@^2.0.4: - version "2.1.1" - resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz#b2c6a98c0072cf91b932d1a496508114311735bf" - dependencies: - alphanum-sort "^1.0.2" - has "^1.0.1" - postcss "^5.0.14" - postcss-selector-parser "^2.0.0" - -postcss-modules-extract-imports@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2.1.tgz#dc87e34148ec7eab5f791f7cd5849833375b741a" - dependencies: - postcss "^6.0.1" - -postcss-modules-local-by-default@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz#f7d80c398c5a393fa7964466bd19500a7d61c069" - dependencies: - css-selector-tokenizer "^0.7.0" - postcss "^6.0.1" - -postcss-modules-scope@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz#d6ea64994c79f97b62a72b426fbe6056a194bb90" - dependencies: - css-selector-tokenizer "^0.7.0" - postcss "^6.0.1" - -postcss-modules-values@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz#ecffa9d7e192518389f42ad0e83f72aec456ea20" - dependencies: - icss-replace-symbols "^1.1.0" - postcss "^6.0.1" - -postcss-normalize-charset@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz#ef9ee71212d7fe759c78ed162f61ed62b5cb93f1" - dependencies: - postcss "^5.0.5" - -postcss-normalize-url@^3.0.7: - version "3.0.8" - resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz#108f74b3f2fcdaf891a2ffa3ea4592279fc78222" - dependencies: - is-absolute-url "^2.0.0" - normalize-url "^1.4.0" - postcss "^5.0.14" - postcss-value-parser "^3.2.3" - -postcss-ordered-values@^2.1.0: - version "2.2.3" - resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-2.2.3.tgz#eec6c2a67b6c412a8db2042e77fe8da43f95c11d" - dependencies: - postcss "^5.0.4" - postcss-value-parser "^3.0.1" - -postcss-reduce-idents@^2.2.2: - version "2.4.0" - resolved "https://registry.yarnpkg.com/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz#c2c6d20cc958284f6abfbe63f7609bf409059ad3" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz#818719a1ae1da325f9832446b01136eeb493cd7e" + integrity sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ== dependencies: - postcss "^5.0.4" - postcss-value-parser "^3.0.2" + postcss "^7.0.5" -postcss-reduce-initial@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz#68f80695f045d08263a879ad240df8dd64f644ea" +postcss-modules-local-by-default@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.2.tgz#e8a6561be914aaf3c052876377524ca90dbb7915" + integrity sha512-jM/V8eqM4oJ/22j0gx4jrp63GSvDH6v86OqyTHHUvk4/k1vceipZsaymiZ5PvocqZOl5SFHiFJqjs3la0wnfIQ== dependencies: - postcss "^5.0.4" + icss-utils "^4.1.1" + postcss "^7.0.16" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.0.0" -postcss-reduce-transforms@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz#ff76f4d8212437b31c298a42d2e1444025771ae1" +postcss-modules-scope@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz#385cae013cc7743f5a7d7602d1073a89eaae62ee" + integrity sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ== dependencies: - has "^1.0.1" - postcss "^5.0.8" - postcss-value-parser "^3.0.1" + postcss "^7.0.6" + postcss-selector-parser "^6.0.0" -postcss-selector-parser@^2.0.0, postcss-selector-parser@^2.2.2: - version "2.2.3" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz#f9437788606c3c9acee16ffe8d8b16297f27bb90" +postcss-modules-values@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz#5b5000d6ebae29b4255301b4a3a54574423e7f10" + integrity sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg== dependencies: - flatten "^1.0.2" - indexes-of "^1.0.1" - uniq "^1.0.1" + icss-utils "^4.0.0" + postcss "^7.0.6" -postcss-selector-parser@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz#249044356697b33b64f1a8f7c80922dddee7195c" +postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz#934cf799d016c83411859e09dcecade01286ec5c" + integrity sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg== dependencies: - cssesc "^2.0.0" + cssesc "^3.0.0" indexes-of "^1.0.1" uniq "^1.0.1" -postcss-svgo@^2.1.1: - version "2.1.6" - resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-2.1.6.tgz#b6df18aa613b666e133f08adb5219c2684ac108d" - dependencies: - is-svg "^2.0.0" - postcss "^5.0.14" - postcss-value-parser "^3.2.3" - svgo "^0.7.0" - -postcss-unique-selectors@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz#981d57d29ddcb33e7b1dfe1fd43b8649f933ca1d" - dependencies: - alphanum-sort "^1.0.1" - postcss "^5.0.4" - uniqs "^2.0.0" - -postcss-value-parser@^3.0.1, postcss-value-parser@^3.0.2, postcss-value-parser@^3.1.1, postcss-value-parser@^3.1.2, postcss-value-parser@^3.2.3, postcss-value-parser@^3.3.0: - version "3.3.1" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" - -postcss-zindex@^2.0.1: - version "2.2.0" - resolved "https://registry.yarnpkg.com/postcss-zindex/-/postcss-zindex-2.2.0.tgz#d2109ddc055b91af67fc4cb3b025946639d2af22" - dependencies: - has "^1.0.1" - postcss "^5.0.4" - uniqs "^2.0.0" - -postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0.14, postcss@^5.0.16, postcss@^5.0.2, postcss@^5.0.4, postcss@^5.0.5, postcss@^5.0.6, postcss@^5.0.8, postcss@^5.2.16: - version "5.2.18" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.18.tgz#badfa1497d46244f6390f58b319830d9107853c5" - dependencies: - chalk "^1.1.3" - js-base64 "^2.1.9" - source-map "^0.5.6" - supports-color "^3.2.3" - -postcss@^6.0.1: - version "6.0.23" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324" - dependencies: - chalk "^2.4.1" - source-map "^0.6.1" - supports-color "^5.4.0" +postcss-value-parser@^4.0.0, postcss-value-parser@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.3.tgz#651ff4593aa9eda8d5d0d66593a2417aeaeb325d" + integrity sha512-N7h4pG+Nnu5BEIzyeaaIYWs0LI5XC40OrRh5L60z0QjFsqGWcHcbkBvpe1WYpcIS9yQ8sOi/vIPt1ejQCrMVrg== -postcss@^7.0.7: - version "7.0.11" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.11.tgz#f63c513b78026d66263bb2ca995bf02e3d1a697d" +postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.27, postcss@^7.0.5, postcss@^7.0.6: + version "7.0.27" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.27.tgz#cc67cdc6b0daa375105b7c424a85567345fc54d9" + integrity sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ== dependencies: chalk "^2.4.2" source-map "^0.6.1" @@ -5638,10 +5711,6 @@ prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" -prepend-http@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" - prettier-linter-helpers@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" @@ -5649,30 +5718,25 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" -prettier@1.13.7: - version "1.13.7" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.13.7.tgz#850f3b8af784a49a6ea2d2eaa7ed1428a34b7281" - -prettier@^1.14.3: - version "1.15.3" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.15.3.tgz#1feaac5bdd181237b54dbe65d874e02a1472786a" +prettier@^1.18.2: + version "1.19.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" + integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== -pretty-format@^23.6.0: - version "23.6.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-23.6.0.tgz#5eaac8eeb6b33b987b7fe6097ea6a8a146ab5760" - dependencies: - ansi-regex "^3.0.0" - ansi-styles "^3.2.0" +prettier@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.4.tgz#2d1bae173e355996ee355ec9830a7a1ee05457ef" + integrity sha512-SVJIQ51spzFDvh4fIbCLvciiDMCrRhlN3mbZvv/+ycjvmF5E73bKdGfU8QDLNmjYJf+lsGnDBC4UUnvTe5OO0w== -pretty-format@^24.7.0: - version "24.7.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.7.0.tgz#d23106bc2edcd776079c2daa5da02bcb12ed0c10" - integrity sha512-apen5cjf/U4dj7tHetpC7UEFCvtAgnNZnBDkfPv3fokzIqyOJckAG9OlAPC1BlFALnqT/lGB2tl9EJjlK6eCsA== +pretty-format@^25.2.1, pretty-format@^25.3.0: + version "25.3.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-25.3.0.tgz#d0a4f988ff4a6cd350342fdabbb809aeb4d49ad5" + integrity sha512-wToHwF8bkQknIcFkBqNfKu4+UZqnrLn/Vr+wwKQwwvPzkBfDDKp/qIabFqdgtoi5PEnM8LFByVsOrHoa3SpTVA== dependencies: - "@jest/types" "^24.7.0" - ansi-regex "^4.0.0" - ansi-styles "^3.2.0" - react-is "^16.8.4" + "@jest/types" "^25.3.0" + ansi-regex "^5.0.0" + ansi-styles "^4.0.0" + react-is "^16.12.0" process-nextick-args@~2.0.0: version "2.0.1" @@ -5684,11 +5748,6 @@ process@^0.11.10: resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= -process@~0.5.1: - version "0.5.2" - resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf" - integrity sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8= - progress@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" @@ -5705,6 +5764,13 @@ prompts@^2.0.1: kleur "^3.0.2" sisteransi "^1.0.0" +property-information@^5.0.0, property-information@^5.3.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/property-information/-/property-information-5.4.0.tgz#16e08f13f4e5c4a7be2e4ec431c01c4f8dba869a" + integrity sha512-nmMWAm/3vKFGmmOWOcdLjgq/Hlxa+hsuR/px1Lp/UGEyc5A22A6l78Shc2C0E71sPmAqglni+HrS7L7VJ7AUCA== + dependencies: + xtend "^4.0.0" + prr@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" @@ -5713,7 +5779,7 @@ pseudomap@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" -psl@^1.1.24, psl@^1.1.28: +psl@^1.1.28: version "1.1.31" resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.31.tgz#e9aa86d0101b5b105cbe93ac6b784cd547276184" integrity sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw== @@ -5757,7 +5823,7 @@ punycode@1.3.2: resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= -punycode@^1.2.4, punycode@^1.4.1: +punycode@^1.2.4: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= @@ -5766,7 +5832,7 @@ punycode@^2.1.0, punycode@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" -q@^1.1.2, q@^1.5.1: +q@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" @@ -5775,13 +5841,6 @@ qs@~6.5.2: resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== -query-string@^4.1.0: - version "4.3.4" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb" - dependencies: - object-assign "^4.1.0" - strict-uri-encode "^1.0.0" - querystring-es3@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" @@ -5822,10 +5881,10 @@ rc@^1.2.7: minimist "^1.2.0" strip-json-comments "~2.0.1" -react-is@^16.8.4: - version "16.8.6" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16" - integrity sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA== +react-is@^16.12.0: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== read-pkg-up@^3.0.0: version "3.0.0" @@ -5835,15 +5894,17 @@ read-pkg-up@^3.0.0: find-up "^2.0.0" read-pkg "^3.0.0" -read-pkg-up@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-4.0.0.tgz#1b221c6088ba7799601c808f91161c66e58f8978" - integrity sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA== +read-pkg@5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" + integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg== dependencies: - find-up "^3.0.0" - read-pkg "^3.0.0" + "@types/normalize-package-data" "^2.4.0" + normalize-package-data "^2.5.0" + parse-json "^5.0.0" + type-fest "^0.6.0" -read-pkg@3.0.0, read-pkg@^3.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" integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= @@ -5852,14 +5913,6 @@ read-pkg@3.0.0, read-pkg@^3.0.0: normalize-package-data "^2.3.2" path-type "^3.0.0" -read-pkg@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-4.0.1.tgz#963625378f3e1c4d48c85872b5a6ec7d5d093237" - dependencies: - normalize-package-data "^2.3.2" - parse-json "^4.0.0" - pify "^3.0.0" - "readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" @@ -5872,6 +5925,15 @@ read-pkg@^4.0.1: string_decoder "~1.1.1" util-deprecate "~1.0.1" +"readable-stream@2 || 3": + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + readdirp@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" @@ -5881,12 +5943,10 @@ readdirp@^2.2.1: micromatch "^3.1.10" readable-stream "^2.0.2" -realpath-native@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.1.0.tgz#2003294fea23fb0672f2476ebe22fcf498a2d65c" - integrity sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA== - dependencies: - util.promisify "^1.0.0" +realpath-native@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-2.0.0.tgz#7377ac429b6e1fd599dc38d08ed942d0d7beb866" + integrity sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q== redent@^2.0.0: version "2.0.0" @@ -5896,24 +5956,6 @@ redent@^2.0.0: indent-string "^3.0.0" strip-indent "^2.0.0" -reduce-css-calc@^1.2.6: - version "1.3.0" - resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz#747c914e049614a4c9cfbba629871ad1d2927716" - dependencies: - balanced-match "^0.4.2" - math-expression-evaluator "^1.2.14" - reduce-function-call "^1.0.1" - -reduce-function-call@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/reduce-function-call/-/reduce-function-call-1.0.2.tgz#5a200bf92e0e37751752fe45b0ab330fd4b6be99" - dependencies: - balanced-match "^0.4.2" - -regenerate@^1.2.1: - version "1.4.0" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" - regenerator-runtime@^0.10.5: version "0.10.5" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" @@ -5924,6 +5966,11 @@ regenerator-runtime@^0.11.0: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== +regenerator-runtime@^0.13.4: + version "0.13.5" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz#d878a1d094b4306d10b9096484b33ebd55e26697" + integrity sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA== + regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" @@ -5941,23 +5988,47 @@ regexpp@^3.0.0: resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.0.0.tgz#dd63982ee3300e67b41c1956f850aa680d9d330e" integrity sha512-Z+hNr7RAVWxznLPuA7DIh8UNX1j9CDrUQxskw9IrBE1Dxue2lyXT+shqEIeLUjrokxIP8CMy1WkjgG3rTsd5/g== -regexpu-core@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-1.0.0.tgz#86a763f58ee4d7c2f6b102e4764050de7ed90c6b" - dependencies: - regenerate "^1.2.1" - regjsgen "^0.2.0" - regjsparser "^0.1.4" - -regjsgen@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" - -regjsparser@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" +remark-mdx@^1.5.8: + version "1.5.8" + resolved "https://registry.yarnpkg.com/remark-mdx/-/remark-mdx-1.5.8.tgz#81fd9085e56ea534b977d08d6f170899138b3f38" + integrity sha512-wtqqsDuO/mU/ucEo/CDp0L8SPdS2oOE6PRsMm+lQ9TLmqgep4MBmyH8bLpoc8Wf7yjNmae/5yBzUN1YUvR/SsQ== + dependencies: + "@babel/core" "7.8.4" + "@babel/helper-plugin-utils" "7.8.3" + "@babel/plugin-proposal-object-rest-spread" "7.8.3" + "@babel/plugin-syntax-jsx" "7.8.3" + "@mdx-js/util" "^1.5.8" + is-alphabetical "1.0.4" + remark-parse "7.0.2" + unified "8.4.2" + +remark-parse@7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-7.0.2.tgz#41e7170d9c1d96c3d32cf1109600a9ed50dba7cf" + integrity sha512-9+my0lQS80IQkYXsMA8Sg6m9QfXYJBnXjWYN5U+kFc5/n69t+XZVXU/ZBYr3cYH8FheEGf1v87rkFDhJ8bVgMA== + dependencies: + collapse-white-space "^1.0.2" + is-alphabetical "^1.0.0" + is-decimal "^1.0.0" + is-whitespace-character "^1.0.0" + is-word-character "^1.0.0" + markdown-escapes "^1.0.0" + parse-entities "^1.1.0" + repeat-string "^1.5.4" + state-toggle "^1.0.0" + trim "0.0.1" + trim-trailing-lines "^1.0.0" + unherit "^1.0.4" + unist-util-remove-position "^1.0.0" + vfile-location "^2.0.0" + xtend "^4.0.1" + +remark-squeeze-paragraphs@3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/remark-squeeze-paragraphs/-/remark-squeeze-paragraphs-3.0.4.tgz#9fe50c3bf3b572dd88754cd426ada007c0b8dc5f" + integrity sha512-Wmz5Yj9q+W1oryo8BV17JrOXZgUKVcpJ2ApE2pwnoHwhFKSk4Wp2PmFNbmJMgYSqAdFwfkoe+TSYop5Fy8wMgA== dependencies: - jsesc "~0.5.0" + mdast-squeeze-paragraphs "^3.0.0" remove-trailing-separator@^1.0.1: version "1.1.0" @@ -5969,31 +6040,36 @@ repeat-element@^1.1.2: resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== -repeat-string@^1.6.1: +repeat-string@^1.5.4, repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= -request-promise-core@1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.2.tgz#339f6aababcafdb31c799ff158700336301d3346" - integrity sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag== +replace-ext@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" + integrity sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs= + +request-promise-core@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.3.tgz#e9a3c081b51380dfea677336061fea879a829ee9" + integrity sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ== dependencies: - lodash "^4.17.11" + lodash "^4.17.15" -request-promise-native@^1.0.5: - version "1.0.7" - resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.7.tgz#a49868a624bdea5069f1251d0a836e0d89aa2c59" - integrity sha512-rIMnbBdgNViL37nZ1b3L/VfPOpSi0TqVDQPAvO6U14lMzOLrt5nilxCQqtDKhZeDiW0/hkCXGoQjhgJd/tCh6w== +request-promise-native@^1.0.7: + version "1.0.8" + resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.8.tgz#a455b960b826e44e2bf8999af64dff2bfe58cb36" + integrity sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ== dependencies: - request-promise-core "1.1.2" + request-promise-core "1.1.3" stealthy-require "^1.1.1" tough-cookie "^2.3.3" -request@^2.87.0: - version "2.88.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" - integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== +request@^2.88.0: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== dependencies: aws-sign2 "~0.7.0" aws4 "^1.8.0" @@ -6002,7 +6078,7 @@ request@^2.87.0: extend "~3.0.2" forever-agent "~0.6.1" form-data "~2.3.2" - har-validator "~5.1.0" + har-validator "~5.1.3" http-signature "~1.2.0" is-typedarray "~1.0.0" isstream "~0.1.2" @@ -6012,7 +6088,7 @@ request@^2.87.0: performance-now "^2.1.0" qs "~6.5.2" safe-buffer "^5.1.2" - tough-cookie "~2.4.3" + tough-cookie "~2.5.0" tunnel-agent "^0.6.0" uuid "^3.3.2" @@ -6021,54 +6097,44 @@ require-directory@^2.1.1: resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= -require-from-string@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" - integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== - -require-main-filename@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" - integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= - require-main-filename@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== -resolve-cwd@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" - integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== dependencies: - resolve-from "^3.0.0" - -resolve-from@4.0.0, resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + resolve-from "^5.0.0" -resolve-from@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57" - integrity sha1-lICrIOlP+h2egKgEx+oUdhGWa1c= +resolve-from@5.0.0, resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== resolve-from@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" -resolve-global@0.1.0, resolve-global@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/resolve-global/-/resolve-global-0.1.0.tgz#8fb02cfd5b7db20118e886311f15af95bd15fbd9" - integrity sha1-j7As/Vt9sgEY6IYxHxWvlb0V+9k= - dependencies: - global-dirs "^0.1.0" +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" -resolve-pkg@1.0.0: +resolve-global@1.0.0, resolve-global@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/resolve-pkg/-/resolve-pkg-1.0.0.tgz#e19a15e78aca2e124461dc92b2e3943ef93494d9" - integrity sha1-4ZoV54rKLhJEYdySsuOUPvk0lNk= + resolved "https://registry.yarnpkg.com/resolve-global/-/resolve-global-1.0.0.tgz#a2a79df4af2ca3f49bf77ef9ddacd322dad19255" + integrity sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw== + dependencies: + global-dirs "^0.1.1" + +resolve-pkg@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-pkg/-/resolve-pkg-2.0.0.tgz#ac06991418a7623edc119084edc98b0e6bf05a41" + integrity sha512-+1lzwXehGCXSeryaISr6WujZzowloigEofRB+dj75y9RRa/obVcYgbHJd53tdYw8pvZj8GojXaaENws8Ktw/hQ== dependencies: - resolve-from "^2.0.0" + resolve-from "^5.0.0" resolve-url@^0.2.1: version "0.2.1" @@ -6093,6 +6159,13 @@ resolve@^1.10.0: dependencies: path-parse "^1.0.6" +resolve@^1.15.1: + version "1.15.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8" + integrity sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w== + dependencies: + path-parse "^1.0.6" + resolve@^1.3.2: version "1.9.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.9.0.tgz#a14c6fdfa8f92a7df1d996cb7105fa744658ea06" @@ -6119,7 +6192,7 @@ ret@~0.1.10: resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== -rimraf@2.6.3, rimraf@^2.2.8, rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.2: +rimraf@2.6.3, rimraf@^2.5.2, rimraf@^2.5.4: version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" dependencies: @@ -6139,6 +6212,13 @@ rimraf@^3.0.0: dependencies: glob "^7.1.3" +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + ripemd160@^2.0.0, ripemd160@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" @@ -6158,10 +6238,6 @@ run-async@^2.2.0: dependencies: is-promise "^2.1.0" -run-node@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/run-node/-/run-node-1.0.0.tgz#46b50b946a2aa2d4947ae1d886e9856fd9cabe5e" - run-queue@^1.0.0, run-queue@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" @@ -6218,11 +6294,18 @@ sane@^4.0.3: minimist "^1.1.1" walker "~1.0.5" -sax@^1.2.4, sax@~1.2.1: +sax@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" -schema-utils@^1.0.0: +saxes@^3.1.9: + version "3.1.11" + resolved "https://registry.yarnpkg.com/saxes/-/saxes-3.1.11.tgz#d59d1fd332ec92ad98a2e0b2ee644702384b1c5b" + integrity sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g== + dependencies: + xmlchars "^2.1.1" + +schema-utils@1.0.0, schema-utils@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" dependencies: @@ -6230,20 +6313,38 @@ schema-utils@^1.0.0: ajv-errors "^1.0.0" ajv-keywords "^3.1.0" +schema-utils@^2.6.5: + version "2.6.5" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.6.5.tgz#c758f0a7e624263073d396e29cd40aa101152d8a" + integrity sha512-5KXuwKziQrTVHh8j/Uxz+QUbxkaLW9X/86NBlx/gnKgtsZA2GIVMUn17qWhRFwF8jdYb3Dig5hRO/W5mZqy6SQ== + dependencies: + ajv "^6.12.0" + ajv-keywords "^3.4.1" + semver-compare@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" -"semver@2 || 3 || 4 || 5", semver@5.6.0, semver@^5.0.1, semver@^5.5.0, semver@^5.6.0: +semver-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-2.0.0.tgz#a93c2c5844539a770233379107b38c7b4ac9d338" + integrity sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw== + +"semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.6.0: version "5.6.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" -semver@^5.3.0, semver@^5.5: +semver@6.3.0, semver@6.x, semver@^6.1.0, semver@^6.1.2, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@^5.3.0: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -semver@^5.4.1, semver@^5.7.0: +semver@^5.4.1: version "5.7.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== @@ -6253,11 +6354,6 @@ semver@^6.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.0.0.tgz#05e359ee571e5ad7ed641a6eec1e547ba52dea65" integrity sha512-0UewU+9rFapKFnlbirLi3byoOuhrSsli/z/ihNnvM24vgF+8sNBiI1LZPBSH9wJKUwaUbw+s3hToDLCXkrghrQ== -semver@^6.1.0, semver@^6.1.2, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== - serialize-javascript@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.2.tgz#ecec53b0e0317bdc95ef76ab7074b7384785fa61" @@ -6296,10 +6392,22 @@ shebang-command@^1.2.0: dependencies: shebang-regex "^1.0.0" +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.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" +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + shellwords@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" @@ -6310,20 +6418,15 @@ signal-exit@^3.0.0, signal-exit@^3.0.2: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= -simple-git@^1.85.0: - version "1.107.0" - resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-1.107.0.tgz#12cffaf261c14d6f450f7fdb86c21ccee968b383" - dependencies: - debug "^4.0.1" - sisteransi@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.0.tgz#77d9622ff909080f1c19e5f4a1df0c1b0a27b88c" integrity sha512-N+z4pHB4AmUv0SjveWRd6q1Nj5w62m5jodv+GD8lvmbY/83T/rpbJGZOnK5T149OldDj4Db07BSv9xY4K6NTPQ== -slash@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== slice-ansi@0.0.4: version "0.0.4" @@ -6368,12 +6471,6 @@ snapdragon@^0.8.1: source-map-resolve "^0.5.0" use "^3.1.0" -sort-keys@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" - dependencies: - is-plain-obj "^1.0.0" - source-list-map@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" @@ -6410,7 +6507,7 @@ source-map-url@^0.4.0: resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= -source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6: +source-map@^0.5.0, source-map@^0.5.6: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= @@ -6423,6 +6520,11 @@ source-map@^0.7.3: version "0.7.3" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" +space-separated-tokens@^1.0.0: + version "1.1.5" + resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz#85f32c3d10d9682007e917414ddc5c26d1aa6899" + integrity sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA== + spdx-correct@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" @@ -6489,9 +6591,10 @@ stack-utils@^1.0.1: resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8" integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA== -staged-git-files@1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/staged-git-files/-/staged-git-files-1.1.2.tgz#4326d33886dc9ecfa29a6193bf511ba90a46454b" +state-toggle@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.3.tgz#e123b16a88e143139b09c6852221bc9815917dfe" + integrity sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ== static-extend@^0.1.1: version "0.1.2" @@ -6536,21 +6639,18 @@ stream-shift@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" -strict-uri-encode@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" - -string-argv@^0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.0.2.tgz#dac30408690c21f3c3630a3ff3a05877bdcbd736" +string-argv@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" + integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== -string-length@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed" - integrity sha1-1A27aGo6zpYMHP/KVivyxF+DY+0= +string-length@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-3.1.0.tgz#107ef8c23456e187a8abd4a61162ff4ac6e25837" + integrity sha512-Ttp5YvkGm5v9Ijagtaz1BnN+k9ObpvS0eIBblPMp2YWL8FBmi9qblQ9fexc2k/CXFgrTIteU3jAw3payCnwSTA== dependencies: astral-regex "^1.0.0" - strip-ansi "^4.0.0" + strip-ansi "^5.2.0" string-width@^1.0.1: version "1.0.2" @@ -6561,7 +6661,7 @@ string-width@^1.0.1: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.1: +"string-width@^1.0.2 || 2", string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" dependencies: @@ -6577,7 +6677,7 @@ string-width@^3.0.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^5.1.0" -string-width@^4.1.0: +string-width@^4.1.0, string-width@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== @@ -6586,7 +6686,7 @@ string-width@^4.1.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.0" -string_decoder@^1.0.0: +string_decoder@^1.0.0, string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== @@ -6600,9 +6700,10 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -stringify-object@^3.2.2: +stringify-object@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" + integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== dependencies: get-own-enumerable-property-symbols "^3.0.0" is-obj "^1.0.1" @@ -6622,12 +6723,6 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" -strip-ansi@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.0.0.tgz#f78f68b5d0866c20b2c9b8c61b5298508dc8756f" - dependencies: - ansi-regex "^4.0.0" - strip-ansi@^5.1.0, strip-ansi@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" @@ -6647,64 +6742,78 @@ strip-bom@^3.0.0: resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= +strip-bom@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" + integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== + strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + strip-indent@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" integrity sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g= -strip-json-comments@2.0.1, strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - strip-json-comments@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.0.1.tgz#85713975a91fb87bf1b305cca77395e40d2a64a7" integrity sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw== -supports-color@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.0.0.tgz#76cfe742cf1f41bb9b1c29ad03068c05b4c0e40a" - integrity sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg== +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + +style-to-object@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.3.0.tgz#b1b790d205991cc783801967214979ee19a76e46" + integrity sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA== dependencies: - has-flag "^3.0.0" + inline-style-parser "0.1.1" + +style-to-object@^0.2.1: + version "0.2.3" + resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.2.3.tgz#afcf42bc03846b1e311880c55632a26ad2780bcb" + integrity sha512-1d/k4EY2N7jVLOqf2j04dTc37TPOv/hHxZmvpg8Pdh8UYydxeu/C1W1U4vD8alzf5V2Gt7rLsmkr4dxAlDm9ng== + dependencies: + inline-style-parser "0.1.1" supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" -supports-color@^3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" - dependencies: - has-flag "^1.0.0" - -supports-color@^5.2.0, supports-color@^5.3.0, supports-color@^5.4.0: +supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" dependencies: has-flag "^3.0.0" -supports-color@^6.0.0, supports-color@^6.1.0: +supports-color@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" dependencies: has-flag "^3.0.0" -svgo@^0.7.0: - version "0.7.2" - resolved "https://registry.yarnpkg.com/svgo/-/svgo-0.7.2.tgz#9f5772413952135c6fefbf40afe6a4faa88b4bb5" +supports-color@^7.0.0, supports-color@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" + integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g== + dependencies: + has-flag "^4.0.0" + +supports-hyperlinks@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz#f663df252af5f37c5d49bbd7eeefa9e0b9e59e47" + integrity sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA== dependencies: - coa "~1.0.1" - colors "~1.1.2" - csso "~2.3.1" - js-yaml "~3.7.0" - mkdirp "~0.5.1" - sax "~1.2.1" - whet.extend "~0.9.9" + has-flag "^4.0.0" + supports-color "^7.0.0" symbol-observable@^1.1.0: version "1.2.0" @@ -6747,7 +6856,15 @@ tar@^4: safe-buffer "^5.1.2" yallist "^3.0.3" -terser-webpack-plugin@^1.4.1: +terminal-link@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" + integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ== + dependencies: + ansi-escapes "^4.2.1" + supports-hyperlinks "^2.0.0" + +terser-webpack-plugin@^1.4.3: version "1.4.3" resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz#5ecaf2dbdc5fb99745fd06791f46fc9ddb1c9a7c" integrity sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA== @@ -6771,15 +6888,14 @@ terser@^4.1.2: source-map "~0.6.1" source-map-support "~0.5.12" -test-exclude@^5.2.2: - version "5.2.2" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.2.2.tgz#7322f8ab037b0b93ad2aab35fe9068baf997a4c4" - integrity sha512-N2pvaLpT8guUpb5Fe1GJlmvmzH3x+DAKmmyEQmFP792QcLYoGE1syxztSvPD1V8yPe6VrcCt6YGQVjSRjCASsA== +test-exclude@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" + integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== dependencies: - glob "^7.1.3" + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" minimatch "^3.0.4" - read-pkg-up "^4.0.0" - require-main-filename "^2.0.0" text-extensions@^1.0.0: version "1.9.0" @@ -6790,10 +6906,10 @@ text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" -throat@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" - integrity sha1-iQN8vJLFarGJJua6TLsgDhVnKmo= +throat@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b" + integrity sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA== through2@^2.0.0, through2@^2.0.2: version "2.0.5" @@ -6802,6 +6918,13 @@ through2@^2.0.0, through2@^2.0.2: readable-stream "~2.3.6" xtend "~4.0.1" +through2@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/through2/-/through2-3.0.1.tgz#39276e713c3302edf9e388dd9c812dd3b825bd5a" + integrity sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww== + dependencies: + readable-stream "2 || 3" + "through@>=2.2.7 <3", through@^2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" @@ -6849,6 +6972,13 @@ to-regex-range@^2.1.0: is-number "^3.0.0" repeat-string "^1.6.1" +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + to-regex@^3.0.1, to-regex@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" @@ -6859,7 +6989,7 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" -tough-cookie@^2.3.3, tough-cookie@^2.3.4: +tough-cookie@^2.3.3, tough-cookie@~2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== @@ -6867,13 +6997,14 @@ tough-cookie@^2.3.3, tough-cookie@^2.3.4: psl "^1.1.28" punycode "^2.1.1" -tough-cookie@~2.4.3: - version "2.4.3" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" - integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ== +tough-cookie@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-3.0.1.tgz#9df4f57e739c26930a018184887f4adb7dca73b2" + integrity sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg== dependencies: - psl "^1.1.24" - punycode "^1.4.1" + ip-regex "^2.1.0" + psl "^1.1.28" + punycode "^2.1.1" tr46@^1.0.1: version "1.0.1" @@ -6882,6 +7013,11 @@ tr46@^1.0.1: dependencies: punycode "^2.1.0" +trim-lines@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/trim-lines/-/trim-lines-1.1.3.tgz#839514be82428fd9e7ec89e35081afe8f6f93115" + integrity sha512-E0ZosSWYK2mkSu+KEtQ9/KqarVjA9HztOSX+9FDdNacRAq29RRV6ZQNgob3iuW8Htar9vAfEa6yyt5qBAHZDBA== + trim-newlines@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-2.0.0.tgz#b403d0b91be50c331dfc4b82eeceb22c3de16d20" @@ -6897,10 +7033,25 @@ trim-right@^1.0.1: resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= -ts-jest@^24.2.0: - version "24.2.0" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-24.2.0.tgz#7abca28c2b4b0a1fdd715cd667d65d047ea4e768" - integrity sha512-Yc+HLyldlIC9iIK8xEN7tV960Or56N49MDP7hubCZUeI7EbIOTsas6rXCMB4kQjLACJ7eDOF4xWEO5qumpKsag== +trim-trailing-lines@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.1.3.tgz#7f0739881ff76657b7776e10874128004b625a94" + integrity sha512-4ku0mmjXifQcTVfYDfR5lpgV7zVqPg6zV9rdZmwOPqq0+Zq19xDqEgagqVbc4pOOShbncuAOIs59R3+3gcF3ZA== + +trim@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd" + integrity sha1-WFhUf2spB1fulczMZm+1AITEYN0= + +trough@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406" + integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA== + +ts-jest@^25.3.1: + version "25.3.1" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-25.3.1.tgz#58e2ed3506e4e4487c0b9b532846a5cade9656ba" + integrity sha512-O53FtKguoMUByalAJW+NWEv7c4tus5ckmhfa7/V0jBb2z8v5rDSLFC1Ate7wLknYPC1euuhY6eJjQq4FtOZrkg== dependencies: bs-logger "0.x" buffer-from "1.x" @@ -6908,26 +7059,22 @@ ts-jest@^24.2.0: json5 "2.x" lodash.memoize "4.x" make-error "1.x" - mkdirp "0.x" + micromatch "4.x" + mkdirp "1.x" resolve "1.x" - semver "^5.5" - yargs-parser "10.x" + semver "6.x" + yargs-parser "18.x" -ts-loader@^5.0.0: - version "5.3.3" - resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-5.3.3.tgz#8b4af042e773132d86b3c99ef0acf3b4d325f473" - integrity sha512-KwF1SplmOJepnoZ4eRIloH/zXL195F51skt7reEsS6jvDqzgc/YSbz9b8E07GxIUwLXdcD4ssrJu6v8CwaTafA== +ts-loader@^6.2.2: + version "6.2.2" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-6.2.2.tgz#dffa3879b01a1a1e0a4b85e2b8421dc0dfff1c58" + integrity sha512-HDo5kXZCBml3EUPcc7RlZOV/JGlLHwppTLEHb3SHnr5V7NXD4klMEkrhJe5wgRbaWsSXi+Y1SIBN/K9B6zWGWQ== dependencies: chalk "^2.3.0" enhanced-resolve "^4.0.0" loader-utils "^1.0.2" - micromatch "^3.1.4" - semver "^5.0.1" - -tslib@^1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" - integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== + micromatch "^4.0.0" + semver "^6.0.0" tslib@^1.8.1, tslib@^1.9.0: version "1.9.3" @@ -6963,27 +7110,55 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" +type-detect@4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + +type-fest@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" + integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== + type-fest@^0.8.1: version "0.8.1" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" -typescript@^3.0.1: - version "3.5.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.5.2.tgz#a09e1dc69bc9551cadf17dba10ee42cf55e5d56c" - integrity sha512-7KxJovlYhTX5RaRbUdkAXN1KUZ8PwWlTzQdHV6xNqvuFOs7+WBo10TQUqT19Q/Jz2hk5v9TQDIhyLhhJY4p5AA== +typescript@^3.8.3: + version "3.8.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.8.3.tgz#409eb8544ea0335711205869ec458ab109ee1061" + integrity sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w== -uglify-js@^3.1.4: - version "3.7.6" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.7.6.tgz#0783daa867d4bc962a37cc92f67f6e3238c47485" - integrity sha512-yYqjArOYSxvqeeiYH2VGjZOqq6SVmhxzaPjJC1W2F9e+bqvFL9QXQ2osQuKUFjM2hGjKG2YclQnRKWQSt/nOTQ== +unherit@^1.0.4: + version "1.1.3" + resolved "https://registry.yarnpkg.com/unherit/-/unherit-1.1.3.tgz#6c9b503f2b41b262330c80e91c8614abdaa69c22" + integrity sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ== dependencies: - commander "~2.20.3" - source-map "~0.6.1" + inherits "^2.0.0" + xtend "^4.0.0" + +unified@8.4.2: + version "8.4.2" + resolved "https://registry.yarnpkg.com/unified/-/unified-8.4.2.tgz#13ad58b4a437faa2751a4a4c6a16f680c500fff1" + integrity sha512-JCrmN13jI4+h9UAyKEoGcDZV+i1E7BLFuG7OsaDvTXI5P0qhHX+vZO/kOhz9jn8HGENDKbwSeB0nVOg4gVStGA== + dependencies: + bail "^1.0.0" + extend "^3.0.0" + is-plain-obj "^2.0.0" + trough "^1.0.0" + vfile "^4.0.0" union-value@^1.0.0: version "1.0.1" @@ -6999,10 +7174,6 @@ uniq@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" -uniqs@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" - unique-filename@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" @@ -7015,6 +7186,83 @@ unique-slug@^2.0.0: dependencies: imurmurhash "^0.1.4" +unist-builder@2.0.3, unist-builder@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/unist-builder/-/unist-builder-2.0.3.tgz#77648711b5d86af0942f334397a33c5e91516436" + integrity sha512-f98yt5pnlMWlzP539tPc4grGMsFaQQlP/vM396b00jngsiINumNmsY8rkXjfoi1c6QaM8nQ3vaGDuoKWbe/1Uw== + +unist-util-generated@^1.0.0: + version "1.1.5" + resolved "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-1.1.5.tgz#1e903e68467931ebfaea386dae9ea253628acd42" + integrity sha512-1TC+NxQa4N9pNdayCYA1EGUOCAO0Le3fVp7Jzns6lnua/mYgwHo0tz5WUAfrdpNch1RZLHc61VZ1SDgrtNXLSw== + +unist-util-is@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-3.0.0.tgz#d9e84381c2468e82629e4a5be9d7d05a2dd324cd" + integrity sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A== + +unist-util-is@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-4.0.1.tgz#ae3e39b9ad1b138c8e3b9d2f4658ad0031be4610" + integrity sha512-7NYjErP4LJtkEptPR22wO5RsCPnHZZrop7t2SoQzjvpFedCFer4WW8ujj9GI5DkUX7yVcffXLjoURf6h2QUv6Q== + +unist-util-position@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-3.1.0.tgz#1c42ee6301f8d52f47d14f62bbdb796571fa2d47" + integrity sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA== + +unist-util-remove-position@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/unist-util-remove-position/-/unist-util-remove-position-1.1.4.tgz#ec037348b6102c897703eee6d0294ca4755a2020" + integrity sha512-tLqd653ArxJIPnKII6LMZwH+mb5q+n/GtXQZo6S6csPRs5zB0u79Yw8ouR3wTw8wxvdJFhpP6Y7jorWdCgLO0A== + dependencies: + unist-util-visit "^1.1.0" + +unist-util-remove@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/unist-util-remove/-/unist-util-remove-1.0.3.tgz#58ec193dfa84b52d5a055ffbc58e5444eb8031a3" + integrity sha512-mB6nCHCQK0pQffUAcCVmKgIWzG/AXs/V8qpS8K72tMPtOSCMSjDeMc5yN+Ye8rB0FhcE+JvW++o1xRNc0R+++g== + dependencies: + unist-util-is "^3.0.0" + +unist-util-stringify-position@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-2.0.2.tgz#5a3866e7138d55974b640ec69a94bc19e0f3fa12" + integrity sha512-nK5n8OGhZ7ZgUwoUbL8uiVRwAbZyzBsB/Ddrlbu6jwwubFza4oe15KlyEaLNMXQW1svOQq4xesUeqA85YrIUQA== + dependencies: + "@types/unist" "^2.0.2" + +unist-util-visit-parents@^2.0.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz#25e43e55312166f3348cae6743588781d112c1e9" + integrity sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g== + dependencies: + unist-util-is "^3.0.0" + +unist-util-visit-parents@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-3.0.1.tgz#666883dc8684c6eec04a7e9781cdcd8b4888319f" + integrity sha512-umEOTkm6/y1gIqPrqet55mYqlvGXCia/v1FSc5AveLAI7jFmOAIbqiwcHcviLcusAkEQt1bq2hixCKO9ltMb2Q== + dependencies: + "@types/unist" "^2.0.0" + unist-util-is "^4.0.0" + +unist-util-visit@2.0.2, unist-util-visit@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-2.0.2.tgz#3843782a517de3d2357b4c193b24af2d9366afb7" + integrity sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ== + dependencies: + "@types/unist" "^2.0.0" + unist-util-is "^4.0.0" + unist-util-visit-parents "^3.0.0" + +unist-util-visit@^1.0.0, unist-util-visit@^1.1.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-1.4.1.tgz#4724aaa8486e6ee6e26d7ff3c8685960d560b1e3" + integrity sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw== + dependencies: + unist-util-visit-parents "^2.0.0" + unixify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unixify/-/unixify-1.0.0.tgz#3a641c8c2ffbce4da683a5c70f03a462940c2090" @@ -7059,19 +7307,11 @@ use@^3.1.0: resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== -util-deprecate@~1.0.1: +util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= -util.promisify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" - integrity sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA== - dependencies: - define-properties "^1.1.2" - object.getownpropertydescriptors "^2.0.3" - util@0.10.3: version "0.10.3" resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" @@ -7096,6 +7336,15 @@ v8-compile-cache@^2.0.3: resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz#e14de37b31a6d194f5690d67efc4e7f6fc6ab30e" integrity sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g== +v8-to-istanbul@^4.0.1: + version "4.1.3" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-4.1.3.tgz#22fe35709a64955f49a08a7c7c959f6520ad6f20" + integrity sha512-sAjOC+Kki6aJVbUOXJbcR0MnbfjvBzwKZazEJymA2IX49uoOdEdk+4fBq5cXgYgiyKtAyrrJNtBZdOeDIF+Fng== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^1.6.0" + source-map "^0.7.3" + 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" @@ -7103,10 +7352,6 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" -vendors@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.2.tgz#7fcb5eef9f5623b156bcea89ec37d63676f21801" - verror@1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" @@ -7116,24 +7361,50 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" +vfile-location@^2.0.0: + version "2.0.6" + resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-2.0.6.tgz#8a274f39411b8719ea5728802e10d9e0dff1519e" + integrity sha512-sSFdyCP3G6Ka0CEmN83A2YCMKIieHx0EDaj5IDP4g1pa5ZJ4FJDvpO0WODLxo4LUX4oe52gmSCK7Jw4SBghqxA== + +vfile-message@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-2.0.2.tgz#75ba05090ec758fa8420f2c11ce049bcddd8cf3e" + integrity sha512-gNV2Y2fDvDOOqq8bEe7cF3DXU6QgV4uA9zMR2P8tix11l1r7zju3zry3wZ8sx+BEfuO6WQ7z2QzfWTvqHQiwsA== + dependencies: + "@types/unist" "^2.0.0" + unist-util-stringify-position "^2.0.0" + +vfile@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/vfile/-/vfile-4.0.2.tgz#71af004d4a710b0e6be99c894655bc56126d5d56" + integrity sha512-yhoTU5cDMSsaeaMfJ5g0bUKYkYmZhAh9fn9TZicxqn+Cw4Z439il2v3oT9S0yjlpqlI74aFOQCt3nOV+pxzlkw== + dependencies: + "@types/unist" "^2.0.0" + is-buffer "^2.0.0" + replace-ext "1.0.0" + unist-util-stringify-position "^2.0.0" + vfile-message "^2.0.0" + vm-browserify@^1.0.1: version "1.1.2" resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== -vue-class-component@^6.1.1: - version "6.3.2" - resolved "https://registry.yarnpkg.com/vue-class-component/-/vue-class-component-6.3.2.tgz#e6037e84d1df2af3bde4f455e50ca1b9eec02be6" +vue-class-component@^7.2.3: + version "7.2.3" + resolved "https://registry.yarnpkg.com/vue-class-component/-/vue-class-component-7.2.3.tgz#a5b1abd53513a72ad51098752e2dedd499807cca" + integrity sha512-oEqYpXKaFN+TaXU+mRLEx8dX0ah85aAJEe61mpdoUrq0Bhe/6sWhyZX1JjMQLhVsHAkncyhedhmCdDVSasUtDw== vue-hot-reload-api@^2.3.0: version "2.3.1" resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.1.tgz#b2d3d95402a811602380783ea4f566eb875569a2" -vue-loader@^15.2.4: - version "15.5.1" - resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-15.5.1.tgz#e005d5fc2481a55a19910f0dcf434206d68acc2a" +vue-loader@^15.9.1: + version "15.9.1" + resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-15.9.1.tgz#bd2ab8f3d281e51d7b81d15390a58424d142243e" + integrity sha512-IaPU2KOPjs/QjMlxFs/TiTtQUSbftQ7lsAvoxe21rtcQohsMhx+1AltXCNhZIpIn46PtODiAgz+o8RbMpKtmJw== dependencies: - "@vue/component-compiler-utils" "^2.4.0" + "@vue/component-compiler-utils" "^3.1.0" hash-sum "^1.0.2" loader-utils "^1.1.0" vue-hot-reload-api "^2.3.0" @@ -7146,20 +7417,23 @@ vue-style-loader@^4.1.0: hash-sum "^1.0.2" loader-utils "^1.0.2" -vue-template-compiler@^2.5.16: - version "2.5.22" - resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.5.22.tgz#c3d3c02c65f1908205c4fbd3b0ef579e51239955" +vue-template-compiler@^2.6.11: + version "2.6.11" + resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.6.11.tgz#c04704ef8f498b153130018993e56309d4698080" + integrity sha512-KIq15bvQDrcCjpGjrAhx4mUlyyHfdmTaoNfeoATHLAiWB+MU3cx4lOzMwrnUh9cCxy0Lt1T11hAFY6TQgroUAA== dependencies: de-indent "^1.0.2" he "^1.1.0" -vue-template-es2015-compiler@^1.6.0: - version "1.8.1" - resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.8.1.tgz#e2ec4f42d16b6c712e61899c6b20bcdb1df128ca" +vue-template-es2015-compiler@^1.9.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825" + integrity sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw== -vue@^2.5.16: - version "2.5.22" - resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.22.tgz#3bf88041af08b8539c37b268b70ca79245e9cc30" +vue@^2.6.11: + version "2.6.11" + resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.11.tgz#76594d877d4b12234406e84e35275c6d514125c5" + integrity sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ== w3c-hr-time@^1.0.1: version "1.0.1" @@ -7168,6 +7442,15 @@ w3c-hr-time@^1.0.1: dependencies: browser-process-hrtime "^0.1.2" +w3c-xmlserializer@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz#30485ca7d70a6fd052420a3d12fd90e6339ce794" + integrity sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg== + dependencies: + domexception "^1.0.1" + webidl-conversions "^4.0.2" + xml-name-validator "^3.0.0" + walker@^1.0.7, walker@~1.0.5: version "1.0.7" resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" @@ -7184,6 +7467,11 @@ watchpack@^1.6.0: graceful-fs "^4.1.2" neo-async "^2.5.0" +web-namespaces@^1.0.0, web-namespaces@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.4.tgz#bc98a3de60dadd7faefc403d1076d529f5e030ec" + integrity sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw== + webidl-conversions@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" @@ -7197,15 +7485,15 @@ webpack-sources@^1.4.0, webpack-sources@^1.4.1: source-list-map "^2.0.0" source-map "~0.6.1" -webpack@^4.0.0: - version "4.41.2" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.41.2.tgz#c34ec76daa3a8468c9b61a50336d8e3303dce74e" - integrity sha512-Zhw69edTGfbz9/8JJoyRQ/pq8FYUoY0diOXqW0T6yhgdhCv6wr0hra5DwwWexNRns2Z2+gsnrNcbe9hbGBgk/A== +webpack@^4.42.1: + version "4.42.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.42.1.tgz#ae707baf091f5ca3ef9c38b884287cfe8f1983ef" + integrity sha512-SGfYMigqEfdGchGhFFJ9KyRpQKnipvEvjc1TwrXEPCM6H5Wywu10ka8o3KGrMzSMxMQKt8aCHUFh5DaQ9UmyRg== dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-module-context" "1.8.5" - "@webassemblyjs/wasm-edit" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/wasm-edit" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" acorn "^6.2.1" ajv "^6.10.2" ajv-keywords "^3.4.1" @@ -7217,36 +7505,27 @@ webpack@^4.0.0: loader-utils "^1.2.3" memory-fs "^0.4.1" micromatch "^3.1.10" - mkdirp "^0.5.1" + mkdirp "^0.5.3" neo-async "^2.6.1" node-libs-browser "^2.2.1" schema-utils "^1.0.0" tapable "^1.1.3" - terser-webpack-plugin "^1.4.1" + terser-webpack-plugin "^1.4.3" watchpack "^1.6.0" webpack-sources "^1.4.1" -whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: +whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== dependencies: iconv-lite "0.4.24" -whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0: +whatwg-mimetype@^2.2.0, whatwg-mimetype@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== -whatwg-url@^6.4.1: - version "6.5.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.5.0.tgz#f2df02bff176fd65070df74ad5ccbb5a199965a8" - integrity sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ== - dependencies: - lodash.sortby "^4.7.0" - tr46 "^1.0.1" - webidl-conversions "^4.0.2" - whatwg-url@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.0.0.tgz#fde926fa54a599f3adf82dff25a9f7be02dc6edd" @@ -7256,22 +7535,30 @@ whatwg-url@^7.0.0: tr46 "^1.0.1" webidl-conversions "^4.0.2" -whet.extend@~0.9.9: - version "0.9.9" - resolved "https://registry.yarnpkg.com/whet.extend/-/whet.extend-0.9.9.tgz#f877d5bf648c97e5aa542fadc16d6a259b9c11a1" - which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which@1.3.1, which@^1.2.10, which@^1.2.9, which@^1.3.0: +which-pm-runs@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-pm-runs/-/which-pm-runs-1.0.0.tgz#670b3afbc552e0b55df6b7780ca74615f23ad1cb" + integrity sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs= + +which@^1.2.9, which@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" dependencies: isexe "^2.0.0" -wide-align@1.1.3, wide-align@^1.1.0: +which@^2.0.1, which@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: version "1.1.3" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" dependencies: @@ -7282,11 +7569,6 @@ word-wrap@~1.2.3: resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== -wordwrap@~0.0.2: - version "0.0.3" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" - integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= - wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" @@ -7298,20 +7580,6 @@ worker-farm@^1.7.0: dependencies: errno "~0.1.7" -worker-rpc@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/worker-rpc/-/worker-rpc-0.1.0.tgz#5f1258dca3d617cd18ca86587f8a05ac0eebd834" - dependencies: - microevent.ts "~0.1.0" - -wrap-ansi@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" - integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - wrap-ansi@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-3.0.1.tgz#288a04d87eda5c286e060dfe8f135ce8d007f8ba" @@ -7319,19 +7587,29 @@ wrap-ansi@^3.0.1: string-width "^2.1.1" strip-ansi "^4.0.0" +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -write-file-atomic@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.1.tgz#d0b05463c188ae804396fd5ab2a370062af87529" - integrity sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg== +write-file-atomic@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" + integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== dependencies: - graceful-fs "^4.1.11" imurmurhash "^0.1.4" + is-typedarray "^1.0.0" signal-exit "^3.0.2" + typedarray-to-buffer "^3.1.5" write@1.0.3: version "1.0.3" @@ -7340,19 +7618,22 @@ write@1.0.3: dependencies: mkdirp "^0.5.1" -ws@^5.2.0: - version "5.2.2" - resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" - integrity sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA== - dependencies: - async-limiter "~1.0.0" +ws@^7.0.0: + version "7.2.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.2.3.tgz#a5411e1fb04d5ed0efee76d26d5c46d830c39b46" + integrity sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ== xml-name-validator@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== -xtend@^4.0.0: +xmlchars@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" + integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== + +xtend@^4.0.0, xtend@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== @@ -7361,7 +7642,7 @@ xtend@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" -"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: +y18n@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" @@ -7374,69 +7655,46 @@ yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3: resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== -yargs-parser@10.x, yargs-parser@^10.0.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" - integrity sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ== - dependencies: - camelcase "^4.1.0" - -yargs-parser@13.0.0, yargs-parser@^13.0.0: - version "13.0.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.0.0.tgz#3fc44f3e76a8bdb1cc3602e860108602e5ccde8b" - integrity sha512-w2LXjoL8oRdRQN+hOyppuXs+V/fVAYtpcrRxZuF7Kt/Oc+Jr2uAcVntaUTNT6w5ihoWfFDpNY8CPx1QskxZ/pw== +yaml@^1.7.2: + version "1.8.3" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.8.3.tgz#2f420fca58b68ce3a332d0ca64be1d191dd3f87a" + integrity sha512-X/v7VDnK+sxbQ2Imq4Jt2PRUsRsP7UcpSl3Llg6+NRRqWLIvxkMFYtH1FmvwNGYRKKPa+EPA4qDBlI9WVG1UKw== dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" + "@babel/runtime" "^7.8.7" -yargs-parser@^11.1.1: - version "11.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4" - integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ== +yargs-parser@18.x, yargs-parser@^18.1.1: + version "18.1.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.2.tgz#2f482bea2136dbde0861683abea7756d30b504f1" + integrity sha512-hlIPNR3IzC1YuL1c2UwwDKpXlNFBqD1Fswwh1khz5+d8Cq/8yc/Mn0i+rQXduu8hcrFKvO7Eryk+09NecTQAAQ== dependencies: camelcase "^5.0.0" decamelize "^1.2.0" -yargs-unparser@1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-1.5.0.tgz#f2bb2a7e83cbc87bb95c8e572828a06c9add6e0d" - integrity sha512-HK25qidFTCVuj/D1VfNiEndpLIeJN78aqgR23nL3y4N0U/91cOAzqfHlF8n2BvoNDcZmJKin3ddNSvOxSr8flw== +yargs-parser@^10.0.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" + integrity sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ== dependencies: - flat "^4.1.0" - lodash "^4.17.11" - yargs "^12.0.5" + camelcase "^4.1.0" -yargs@13.2.2: - version "13.2.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.2.tgz#0c101f580ae95cea7f39d927e7770e3fdc97f993" - integrity sha512-WyEoxgyTD3w5XRpAQNYUB9ycVH/PQrToaTXdYXRdOXvEy1l19br+VJsc0vcO8PTGg5ro/l/GY7F/JMEBmI0BxA== +yargs@^15.3.1: + version "15.3.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.3.1.tgz#9505b472763963e54afe60148ad27a330818e98b" + integrity sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA== dependencies: - cliui "^4.0.0" - find-up "^3.0.0" + cliui "^6.0.0" + decamelize "^1.2.0" + find-up "^4.1.0" get-caller-file "^2.0.1" - os-locale "^3.1.0" require-directory "^2.1.1" require-main-filename "^2.0.0" set-blocking "^2.0.0" - string-width "^3.0.0" + string-width "^4.2.0" which-module "^2.0.0" y18n "^4.0.0" - yargs-parser "^13.0.0" + yargs-parser "^18.1.1" -yargs@^12.0.2, yargs@^12.0.5: - version "12.0.5" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" - integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== - dependencies: - cliui "^4.0.0" - decamelize "^1.2.0" - find-up "^3.0.0" - get-caller-file "^1.0.1" - os-locale "^3.0.0" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^2.0.0" - which-module "^2.0.0" - y18n "^3.2.1 || ^4.0.0" - yargs-parser "^11.1.1" +zwitch@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920" + integrity sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw== From f539ecbb34175ccf87b23439b50f2c4145b33b68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ole=C5=9B?= Date: Sat, 18 Apr 2020 12:13:35 +0200 Subject: [PATCH 05/29] fix: use 'afterCompile' hook to fix regression described in #57 --- src/ForkTsCheckerWebpackPlugin.ts | 9 +++------ ...pEmitToGetIssues.ts => tapAfterCompileToGetIssues.ts} | 6 +++--- 2 files changed, 6 insertions(+), 9 deletions(-) rename src/hooks/{tapEmitToGetIssues.ts => tapAfterCompileToGetIssues.ts} (94%) diff --git a/src/ForkTsCheckerWebpackPlugin.ts b/src/ForkTsCheckerWebpackPlugin.ts index 117e2375..c1a4806e 100644 --- a/src/ForkTsCheckerWebpackPlugin.ts +++ b/src/ForkTsCheckerWebpackPlugin.ts @@ -6,17 +6,14 @@ import { createForkTsCheckerWebpackPluginConfiguration } from './ForkTsCheckerWe import { createForkTsCheckerWebpackPluginState } from './ForkTsCheckerWebpackPluginState'; import { composeReporterRpcClients, createAggregatedReporter, ReporterRpcClient } from './reporter'; import { assertTypeScriptSupport } from './typescript-reporter/assertTypeScriptSupport'; -import { - createTypeScriptReporterRpcClient, - createTypeScriptReporterSameProcessRpcClient, -} from './typescript-reporter/reporter/TypeScriptReporterRpcClient'; +import { createTypeScriptReporterRpcClient } from './typescript-reporter/reporter/TypeScriptReporterRpcClient'; import { assertEsLintSupport } from './eslint-reporter/assertEsLintSupport'; import { createEsLintReporterRpcClient } from './eslint-reporter/reporter/EsLintReporterRpcClient'; import { tapDoneToAsyncGetIssues } from './hooks/tapDoneToAsyncGetIssues'; import { tapInvalidToUpdateState } from './hooks/tapInvalidToUpdateState'; import { tapStartToConnectAndRunReporter } from './hooks/tapStartToConnectAndRunReporter'; import { tapStopToDisconnectReporter } from './hooks/tapStopToDisconnectReporter'; -import { tapEmitToGetIssues } from './hooks/tapEmitToGetIssues'; +import { tapAfterCompileToGetIssues } from './hooks/tapAfterCompileToGetIssues'; import { getForkTsCheckerWebpackPluginHooks } from './hooks/pluginHooks'; class ForkTsCheckerWebpackPlugin implements webpack.Plugin { @@ -52,7 +49,7 @@ class ForkTsCheckerWebpackPlugin implements webpack.Plugin { if (configuration.async) { tapDoneToAsyncGetIssues(compiler, configuration, state); } else { - tapEmitToGetIssues(compiler, configuration, state); + tapAfterCompileToGetIssues(compiler, configuration, state); } } else { configuration.logger.infrastructure.error( diff --git a/src/hooks/tapEmitToGetIssues.ts b/src/hooks/tapAfterCompileToGetIssues.ts similarity index 94% rename from src/hooks/tapEmitToGetIssues.ts rename to src/hooks/tapAfterCompileToGetIssues.ts index cfe3d0f8..1500ae74 100644 --- a/src/hooks/tapEmitToGetIssues.ts +++ b/src/hooks/tapAfterCompileToGetIssues.ts @@ -8,14 +8,14 @@ import { Tap } from 'tapable'; import { getReportProgress } from './getReportProgress'; import { Issue } from '../issue'; -function tapEmitToGetIssues( +function tapAfterCompileToGetIssues( compiler: webpack.Compiler, configuration: ForkTsCheckerWebpackPluginConfiguration, state: ForkTsCheckerWebpackPluginState ) { const hooks = getForkTsCheckerWebpackPluginHooks(compiler); - compiler.hooks.emit.tapPromise( + compiler.hooks.afterCompile.tapPromise( { name: 'ForkTsCheckerWebpackPlugin', context: true, @@ -66,4 +66,4 @@ function tapEmitToGetIssues( ); } -export { tapEmitToGetIssues }; +export { tapAfterCompileToGetIssues }; From 931ab1491a87a391122fd64685ba094dd389af27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ole=C5=9B?= Date: Sat, 18 Apr 2020 17:54:01 +0200 Subject: [PATCH 06/29] refactor: code-review requested changes --- .eslintrc.js | 2 +- src/hooks/tapAfterCompileToGetIssues.ts | 8 ++-- src/hooks/tapDoneToAsyncGetIssues.ts | 10 ++-- src/reporter/FilesChange.ts | 62 +++++++++++++++---------- src/reporter/FilesInitialState.ts | 37 +++++++++++++++ src/reporter/FilesState.ts | 30 ------------ src/reporter/index.ts | 1 - src/rpc/rpc-ipc/RpcIpcMessagePort.ts | 2 - 8 files changed, 84 insertions(+), 68 deletions(-) create mode 100644 src/reporter/FilesInitialState.ts delete mode 100644 src/reporter/FilesState.ts diff --git a/.eslintrc.js b/.eslintrc.js index a609a445..977a4fb9 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -24,7 +24,7 @@ module.exports = { ], rules: { '@typescript-eslint/explicit-function-return-type': 'off', - '@typescript-eslint/no-namespace': 'off' // maybe we should consider enabling it in the future + '@typescript-eslint/no-use-before-define': 'off' } } ] diff --git a/src/hooks/tapAfterCompileToGetIssues.ts b/src/hooks/tapAfterCompileToGetIssues.ts index 1500ae74..d4ad3cc8 100644 --- a/src/hooks/tapAfterCompileToGetIssues.ts +++ b/src/hooks/tapAfterCompileToGetIssues.ts @@ -2,7 +2,7 @@ import webpack from 'webpack'; import { ForkTsCheckerWebpackPluginConfiguration } from '../ForkTsCheckerWebpackPluginConfiguration'; import { ForkTsCheckerWebpackPluginState } from '../ForkTsCheckerWebpackPluginState'; import { getForkTsCheckerWebpackPluginHooks } from './pluginHooks'; -import { OperationCancelledError } from '../reporter'; +import { OperationCancelledError } from '../error/OperationCancelledError'; import { IssueWebpackError } from '../issue/IssueWebpackError'; import { Tap } from 'tapable'; import { getReportProgress } from './getReportProgress'; @@ -31,10 +31,10 @@ function tapAfterCompileToGetIssues( issues = await state.report; } catch (error) { - if (!(error instanceof OperationCancelledError)) { - hooks.error.call(error, compilation); - } else { + if (error instanceof OperationCancelledError) { hooks.cancelled.call(compilation); + } else { + hooks.error.call(error, compilation); } return; } finally { diff --git a/src/hooks/tapDoneToAsyncGetIssues.ts b/src/hooks/tapDoneToAsyncGetIssues.ts index 5636e538..82439e6b 100644 --- a/src/hooks/tapDoneToAsyncGetIssues.ts +++ b/src/hooks/tapDoneToAsyncGetIssues.ts @@ -1,8 +1,8 @@ -import webpack, { compilation } from 'webpack'; +import webpack from 'webpack'; import { ForkTsCheckerWebpackPluginConfiguration } from '../ForkTsCheckerWebpackPluginConfiguration'; import { ForkTsCheckerWebpackPluginState } from '../ForkTsCheckerWebpackPluginState'; import { getForkTsCheckerWebpackPluginHooks } from './pluginHooks'; -import { OperationCancelledError } from '../reporter'; +import { OperationCancelledError } from '../error/OperationCancelledError'; import { createWebpackFormatter } from '../formatter/WebpackFormatter'; import { Issue } from '../issue'; import isPending from '../utils/async/isPending'; @@ -31,10 +31,10 @@ function tapDoneToAsyncGetIssues( issues = await report; } catch (error) { - if (!(error instanceof OperationCancelledError)) { - hooks.error.call(error, stats.compilation); - } else { + if (error instanceof OperationCancelledError) { hooks.cancelled.call(stats.compilation); + } else { + hooks.error.call(error, stats.compilation); } return; } diff --git a/src/reporter/FilesChange.ts b/src/reporter/FilesChange.ts index 43085a57..e8d05d35 100644 --- a/src/reporter/FilesChange.ts +++ b/src/reporter/FilesChange.ts @@ -1,7 +1,7 @@ import subtract from '../utils/array/substract'; import unique from '../utils/array/unique'; import intersect from '../utils/array/intersect'; -import { aggregateFilesState } from './FilesState'; +import { getFilesInitialState } from './FilesInitialState'; interface FilesChange { createdFiles?: string[]; @@ -9,31 +9,43 @@ interface FilesChange { deletedFiles?: string[]; } +/** + * Computes aggregated files change based on the subsequent files changes. + * + * @param changes List of subsequent files changes + * @returns Files change that represents all subsequent changes as a one event + */ function aggregateFilesChanges(changes: FilesChange[]): FilesChange { - const { nonExistedFiles, existedFiles } = aggregateFilesState(changes); - - return changes.reduce( - (aggregated, change) => ({ - createdFiles: unique([ - ...subtract(aggregated.createdFiles, change.deletedFiles), - ...intersect(change.createdFiles, nonExistedFiles), - ]), - changedFiles: unique([ - ...subtract(aggregated.changedFiles, change.deletedFiles), - ...intersect(change.changedFiles, existedFiles), - ...intersect(change.createdFiles, existedFiles), - ]), - deletedFiles: unique([ - ...subtract(aggregated.deletedFiles, change.createdFiles), - ...intersect(change.deletedFiles, existedFiles), - ]), - }), - { - createdFiles: [], - changedFiles: [], - deletedFiles: [], - } - ); + const { filesThatDidntExist, filesThatDidExist } = getFilesInitialState(changes); + + let createdFiles: string[] = []; + let changedFiles: string[] = []; + let deletedFiles: string[] = []; + + for (const change of changes) { + // subtract deleted files from created files + createdFiles = subtract(createdFiles, change.deletedFiles); + // add new created files if didn't exist before + createdFiles.push(...intersect(change.createdFiles, filesThatDidntExist)); + + // subtract deleted files from changed files + changedFiles = subtract(changedFiles, change.deletedFiles); + // add new created files if did exist before + changedFiles.push(...intersect(change.createdFiles, filesThatDidExist)); + // add new changed files if did exist before + changedFiles.push(...intersect(change.changedFiles, filesThatDidExist)); + + // subtract created files from deleted files + deletedFiles = subtract(deletedFiles, change.createdFiles); + // add new deleted files if did exist before + deletedFiles.push(...intersect(change.deletedFiles, filesThatDidExist)); + } + + return { + createdFiles: unique(createdFiles), + changedFiles: unique(changedFiles), + deletedFiles: unique(deletedFiles), + }; } export { FilesChange, aggregateFilesChanges }; diff --git a/src/reporter/FilesInitialState.ts b/src/reporter/FilesInitialState.ts new file mode 100644 index 00000000..172b8183 --- /dev/null +++ b/src/reporter/FilesInitialState.ts @@ -0,0 +1,37 @@ +import unique from '../utils/array/unique'; +import subtract from '../utils/array/substract'; +import { FilesChange } from './FilesChange'; + +interface FilesInitialState { + filesThatDidExist: string[]; + filesThatDidntExist: string[]; +} + +/** + * Computes initial state of files based on the list of subsequent files changes + * + * @param changes List of subsequent files changes + * @returns Initial state of files that were created, changed or deleted + */ +function getFilesInitialState(changes: FilesChange[]): FilesInitialState { + // list of files that did exist before + const filesThatDidExist: string[] = []; + // list of files that didn't exist before + const filesThatDidntExist: string[] = []; + + // once the file is categorized, it can't be moved to a different category + for (const change of changes) { + // add changed and deleted files that were not registered as files that didn't exist + filesThatDidExist.push(...subtract(change.changedFiles, filesThatDidntExist)); + filesThatDidExist.push(...subtract(change.deletedFiles, filesThatDidntExist)); + // add created files that were not registered as files that did exist + filesThatDidntExist.push(...subtract(change.createdFiles, filesThatDidExist)); + } + + return { + filesThatDidExist: unique(filesThatDidExist), + filesThatDidntExist: unique(filesThatDidntExist), + }; +} + +export { getFilesInitialState, FilesInitialState }; diff --git a/src/reporter/FilesState.ts b/src/reporter/FilesState.ts deleted file mode 100644 index c93287d1..00000000 --- a/src/reporter/FilesState.ts +++ /dev/null @@ -1,30 +0,0 @@ -import unique from '../utils/array/unique'; -import subtract from '../utils/array/substract'; -import { FilesChange } from './FilesChange'; - -interface FilesState { - nonExistedFiles: string[]; - existedFiles: string[]; -} - -function aggregateFilesState(changes: FilesChange[]): FilesState { - return changes.reduce( - ({ nonExistedFiles, existedFiles }, increment) => ({ - nonExistedFiles: unique([ - ...nonExistedFiles, - ...subtract(increment.createdFiles, existedFiles), - ]), - existedFiles: unique([ - ...existedFiles, - ...(increment.changedFiles || []), - ...(increment.deletedFiles || []), - ]), - }), - { - nonExistedFiles: [], - existedFiles: [], - } - ); -} - -export { aggregateFilesState, FilesState }; diff --git a/src/reporter/index.ts b/src/reporter/index.ts index 59e7402b..0b1140af 100644 --- a/src/reporter/index.ts +++ b/src/reporter/index.ts @@ -2,7 +2,6 @@ export * from './Reporter'; export * from './AggregatedReporter'; export * from './Report'; -export * from '../error/OperationCancelledError'; export * from './FilesChange'; export * from './reporter-rpc/ReporterRpcClient'; diff --git a/src/rpc/rpc-ipc/RpcIpcMessagePort.ts b/src/rpc/rpc-ipc/RpcIpcMessagePort.ts index d2eb11b8..1849bc12 100644 --- a/src/rpc/rpc-ipc/RpcIpcMessagePort.ts +++ b/src/rpc/rpc-ipc/RpcIpcMessagePort.ts @@ -8,7 +8,6 @@ function createRpcIpcMessagePort(process: ProcessLike): RpcMessagePort { let closedError: Error | undefined; const handleExit = async (code: string | number | null, signal: string | null) => { - // eslint-disable-next-line @typescript-eslint/no-use-before-define await port.close(); closedError = new RpcIpcMessagePortClosedError( @@ -18,7 +17,6 @@ function createRpcIpcMessagePort(process: ProcessLike): RpcMessagePort { ); }; const handleDisconnect = async () => { - // eslint-disable-next-line @typescript-eslint/no-use-before-define await port.close(); closedError = new RpcIpcMessagePortClosedError( From 5e59c92c222aed3e6b0ff8392b8aab6805cdbfd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ole=C5=9B?= Date: Sun, 19 Apr 2020 18:03:19 +0200 Subject: [PATCH 07/29] feat: upgrade min node version to 8 As Node 6 support ended in April 2019 and Node 8 ended in January 2020 we decided to drop support for Node 6 BREAKING CHANGE: Dropped support for Node 6 --- .eslintrc.js | 8 ++------ package.json | 2 +- src/error/OperationCancelledError.ts | 6 ------ src/issue/IssueWebpackError.ts | 2 -- src/reporter/AggregatedReporter.ts | 9 ++++++--- src/rpc/error/RpcMessagePortClosedError.ts | 8 +------- tsconfig.json | 8 ++++---- 7 files changed, 14 insertions(+), 29 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 977a4fb9..3307a73c 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -10,11 +10,6 @@ module.exports = { tryExtensions: ['.js', '.json', '.ts', '.d.ts'] } }, - rules: { - 'no-process-exit': 'off', // to investigate if we should throw an error instead of process.exit() - 'node/no-unsupported-features/es-builtins': 'off', - 'node/no-unsupported-features/es-syntax': 'off' - }, overrides: [ { files: ['*.ts'], @@ -24,7 +19,8 @@ module.exports = { ], rules: { '@typescript-eslint/explicit-function-return-type': 'off', - '@typescript-eslint/no-use-before-define': 'off' + '@typescript-eslint/no-use-before-define': 'off', + 'node/no-unsupported-features/es-syntax': 'off' } } ] diff --git a/package.json b/package.json index 8740457f..3a5de652 100644 --- a/package.json +++ b/package.json @@ -118,7 +118,7 @@ "webpack": "^4.42.1" }, "engines": { - "node": ">=6.11.5", + "node": ">=8", "yarn": ">=1.0.0" } } diff --git a/src/error/OperationCancelledError.ts b/src/error/OperationCancelledError.ts index d7425b0c..6f559f61 100644 --- a/src/error/OperationCancelledError.ts +++ b/src/error/OperationCancelledError.ts @@ -1,11 +1,5 @@ class OperationCancelledError extends Error { readonly cancelled = true; - - constructor(message: string) { - super(message); - - Object.setPrototypeOf(this, OperationCancelledError.prototype); - } } export { OperationCancelledError }; diff --git a/src/issue/IssueWebpackError.ts b/src/issue/IssueWebpackError.ts index 237f3812..85cf0fcb 100644 --- a/src/issue/IssueWebpackError.ts +++ b/src/issue/IssueWebpackError.ts @@ -44,8 +44,6 @@ class IssueWebpackError extends Error { this.file = parts.join(' '); } - Object.setPrototypeOf(this, IssueWebpackError.prototype); - Error.captureStackTrace(this, this.constructor); } } diff --git a/src/reporter/AggregatedReporter.ts b/src/reporter/AggregatedReporter.ts index d988b0eb..0336c612 100644 --- a/src/reporter/AggregatedReporter.ts +++ b/src/reporter/AggregatedReporter.ts @@ -16,10 +16,13 @@ function createAggregatedReporter(reporter: TReporte if (!pendingReportPromise) { const reportPromise = reporter.getReport(change); pendingReportPromise = reportPromise + .then(() => { + // remove current pending - .finally() is supported starting from Node 10 + pendingReportPromise = undefined; + }) // ignore previous errors - .catch(() => undefined) - // remove current pending - .finally(() => { + .catch(() => { + // remove current pending - .finally() is supported starting from Node 10 pendingReportPromise = undefined; }); diff --git a/src/rpc/error/RpcMessagePortClosedError.ts b/src/rpc/error/RpcMessagePortClosedError.ts index f186e2b4..4c307dfb 100644 --- a/src/rpc/error/RpcMessagePortClosedError.ts +++ b/src/rpc/error/RpcMessagePortClosedError.ts @@ -1,9 +1,3 @@ -class RpcMessagePortClosedError extends Error { - constructor(message: string) { - super(message); - - Object.setPrototypeOf(this, RpcMessagePortClosedError.prototype); - } -} +class RpcMessagePortClosedError extends Error {} export { RpcMessagePortClosedError }; diff --git a/tsconfig.json b/tsconfig.json index baa9de85..cd6ab032 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,15 +1,15 @@ { "compilerOptions": { - "target": "es5", + "target": "es6", "module": "commonjs", + "lib": ["ES6"], + "moduleResolution": "node", + "resolveJsonModule": true, "esModuleInterop": true, "skipLibCheck": true, "skipDefaultLibCheck": true, "strict": true, "declaration": true, - "resolveJsonModule": true, - "lib": ["es2015"], - "moduleResolution": "node", "sourceMap": true, "baseUrl": "./src", "outDir": "./lib" From f80bda7d052697cfd459fe65e21b5416fd6f4f81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ole=C5=9B?= Date: Mon, 20 Apr 2020 18:50:18 +0200 Subject: [PATCH 08/29] test: make existing unit tests work again --- .github/workflows/main.yml | 84 ++++- src/ForkTsCheckerWebpackPlugin.ts | 2 +- ...ForkTsCheckerWebpackPluginConfiguration.ts | 5 +- src/ForkTsCheckerWebpackPluginOptions.ts | 2 +- .../{EsLintIssue.ts => EsLintIssueFactory.ts} | 0 .../reporter/EsLintReporter.ts | 2 +- src/formatter/FormatterFactory.ts | 19 +- src/formatter/WebpackFormatter.ts | 8 +- src/formatter/index.ts | 3 + src/issue/Issue.ts | 2 - src/issue/IssueLocation.ts | 15 +- src/issue/IssuePosition.ts | 4 + src/issue/IssueWebpackError.ts | 30 +- .../assertTypeScriptSupport.ts | 23 +- test/unit/FileRegister.spec.ts | 111 ------ test/unit/ForkTsCheckerWebpackPlugin.spec.ts | 15 + test/unit/IncrementalChecker.spec.ts | 48 --- test/unit/VueProgram.spec.ts | 218 ----------- test/unit/cancellation/CancelledError.spec.ts | 16 - .../FileBasedCancellationToken.spec.ts | 108 ------ .../TypeScriptCancellationToken.spec.ts | 61 ---- .../issue}/EsLintIssueFactory.spec.ts | 47 +-- .../EsLintIssueFactory.spec.ts.snap | 57 +++ test/unit/formatter/BasicFormatter.spec.ts | 53 +++ .../unit/formatter/CodeframeFormatter.spec.ts | 139 ++++--- test/unit/formatter/DefaultFormatter.spec.ts | 53 --- .../formatter/FormatterConfiguration.spec.ts | 75 ++++ test/unit/formatter/FormatterFactory.spec.ts | 54 +-- test/unit/formatter/InternalFormatter.spec.ts | 66 ---- test/unit/formatter/RawFormatter.spec.ts | 37 -- test/unit/formatter/WebpackFormatter.spec.ts | 58 +++ test/unit/formatter/__mocks__/chalk.js | 27 +- test/unit/index.spec.ts | 138 ------- test/unit/issue/Issue.spec.ts | 341 ++++++++---------- test/unit/issue/IssueOrigin.spec.ts | 49 --- test/unit/issue/IssueSeverity.spec.ts | 42 --- .../__snapshots__/IssueOrigin.spec.ts.snap | 9 - .../__snapshots__/IssueSeverity.spec.ts.snap | 8 - .../EsLintIssueFactory.spec.ts.snap | 33 -- .../internal/InternalIssueFactory.spec.ts | 29 -- .../InternalIssueFactory.spec.ts.snap | 31 -- .../typescript/TypeScriptIssueFactory.spec.ts | 129 ------- .../TypeScriptIssueFactory.spec.ts.snap | 94 ----- .../issue/TypeScriptIssueFactory.spec.ts | 50 +++ .../TypeScriptIssueFactory.spec.ts.snap | 48 +++ 45 files changed, 768 insertions(+), 1675 deletions(-) rename src/eslint-reporter/issue/{EsLintIssue.ts => EsLintIssueFactory.ts} (100%) delete mode 100644 test/unit/FileRegister.spec.ts create mode 100644 test/unit/ForkTsCheckerWebpackPlugin.spec.ts delete mode 100644 test/unit/IncrementalChecker.spec.ts delete mode 100644 test/unit/VueProgram.spec.ts delete mode 100644 test/unit/cancellation/CancelledError.spec.ts delete mode 100644 test/unit/cancellation/FileBasedCancellationToken.spec.ts delete mode 100644 test/unit/cancellation/typescript/TypeScriptCancellationToken.spec.ts rename test/unit/{issue/eslint => eslint-reporter/issue}/EsLintIssueFactory.spec.ts (50%) create mode 100644 test/unit/eslint-reporter/issue/__snapshots__/EsLintIssueFactory.spec.ts.snap create mode 100644 test/unit/formatter/BasicFormatter.spec.ts delete mode 100644 test/unit/formatter/DefaultFormatter.spec.ts create mode 100644 test/unit/formatter/FormatterConfiguration.spec.ts delete mode 100644 test/unit/formatter/InternalFormatter.spec.ts delete mode 100644 test/unit/formatter/RawFormatter.spec.ts create mode 100644 test/unit/formatter/WebpackFormatter.spec.ts delete mode 100644 test/unit/index.spec.ts delete mode 100644 test/unit/issue/IssueOrigin.spec.ts delete mode 100644 test/unit/issue/IssueSeverity.spec.ts delete mode 100644 test/unit/issue/__snapshots__/IssueOrigin.spec.ts.snap delete mode 100644 test/unit/issue/__snapshots__/IssueSeverity.spec.ts.snap delete mode 100644 test/unit/issue/eslint/__snapshots__/EsLintIssueFactory.spec.ts.snap delete mode 100644 test/unit/issue/internal/InternalIssueFactory.spec.ts delete mode 100644 test/unit/issue/internal/__snapshots__/InternalIssueFactory.spec.ts.snap delete mode 100644 test/unit/issue/typescript/TypeScriptIssueFactory.spec.ts delete mode 100644 test/unit/issue/typescript/__snapshots__/TypeScriptIssueFactory.spec.ts.snap create mode 100644 test/unit/typescript-reporter/issue/TypeScriptIssueFactory.spec.ts create mode 100644 test/unit/typescript-reporter/issue/__snapshots__/TypeScriptIssueFactory.spec.ts.snap diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1df6f379..843c0732 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,5 +1,5 @@ name: CI/CD -on: [push, pull_request] +on: [pull_request] jobs: build: runs-on: ubuntu-latest @@ -39,21 +39,64 @@ jobs: needs: build strategy: matrix: - os: - - ubuntu-latest - - macos-latest - - windows-latest - node: - - '6' - - '8' - - '10' - - '12' - packages: - - webpack@5.0.0-alpha.5 ts-loader@^5.0.0 vue-loader@^15.2.4 - - webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.4 - exclude: - - node: '6' - packages: 'webpack@5.0.0-alpha.5 ts-loader@^5.0.0 vue-loader@^15.2.4' + include: + # test different typescript versions + - os: ubuntu-latest + node: 12 + packages: typescript@2.7.0 webpack@^4.0.0 ts-loader@5.0.0 vue-loader@15.2.0 + + - os: ubuntu-latest + node: 12 + packages: typescript@^3.0.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 + + - os: ubuntu-latest + node: 12 + packages: typescript@^3.6.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 + + - os: ubuntu-latest + node: 12 + packages: typescript@latest webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 + + # test different webpack versions + - os: ubuntu-latest + node: 12 + packages: webpack@^5.0.0-beta.14 ts-loader@^5.0.0 vue-loader@^15.2.0 + + # test different operating systems and node versions + # macos + - os: macos-latest + node: 8 + packages: typescript@^3.6.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 + + - os: macos-latest + node: 10 + packages: typescript@^3.6.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 + + - os: macos-latest + node: 12 + packages: typescript@^3.6.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 + + # windows + - os: windows-latest + node: 8 + packages: typescript@^3.6.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 + + - os: windows-latest + node: 10 + packages: typescript@^3.6.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 + + - os: windows-latest + node: 12 + packages: typescript@^3.6.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 + + # ubuntu + - os: ubuntu-latest + node: 8 + packages: typescript@^3.6.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 + + - os: ubuntu-latest + node: 10 + packages: typescript@^3.6.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 steps: - uses: actions/checkout@v1 @@ -86,9 +129,10 @@ jobs: - name: Run unit tests run: yarn test:unit - - - name: Run integration tests - run: yarn test:integration + + # TODO: uncomment, when integration tests will work again + # - name: Run integration tests + # run: yarn test:integration release: runs-on: ubuntu-latest @@ -96,7 +140,7 @@ jobs: GH_TOKEN: ${{ secrets.GH_PERSONAL_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} needs: [build, test] - if: github.event_name == 'push' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/beta') + if: github.event_name == 'push' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/alpha' || github.ref == 'refs/heads/beta') steps: - uses: actions/checkout@v1 diff --git a/src/ForkTsCheckerWebpackPlugin.ts b/src/ForkTsCheckerWebpackPlugin.ts index c1a4806e..208959e6 100644 --- a/src/ForkTsCheckerWebpackPlugin.ts +++ b/src/ForkTsCheckerWebpackPlugin.ts @@ -52,7 +52,7 @@ class ForkTsCheckerWebpackPlugin implements webpack.Plugin { tapAfterCompileToGetIssues(compiler, configuration, state); } } else { - configuration.logger.infrastructure.error( + throw new Error( `ForkTsCheckerWebpackPlugin is configured to not use any issue reporter. It's probably a configuration issue.` ); } diff --git a/src/ForkTsCheckerWebpackPluginConfiguration.ts b/src/ForkTsCheckerWebpackPluginConfiguration.ts index ce30c5d6..2171da5f 100644 --- a/src/ForkTsCheckerWebpackPluginConfiguration.ts +++ b/src/ForkTsCheckerWebpackPluginConfiguration.ts @@ -1,10 +1,7 @@ import webpack from 'webpack'; import { ForkTsCheckerWebpackPluginOptions } from './ForkTsCheckerWebpackPluginOptions'; import { createIssueConfiguration, IssueConfiguration } from './issue/IssueConfiguration'; -import { - createFormatterConfiguration, - FormatterConfiguration, -} from './formatter/FormatterConfiguration'; +import { createFormatterConfiguration, FormatterConfiguration } from './formatter'; import { createTypeScriptReporterConfiguration, TypeScriptReporterConfiguration, diff --git a/src/ForkTsCheckerWebpackPluginOptions.ts b/src/ForkTsCheckerWebpackPluginOptions.ts index 6b83c48e..ee829996 100644 --- a/src/ForkTsCheckerWebpackPluginOptions.ts +++ b/src/ForkTsCheckerWebpackPluginOptions.ts @@ -1,7 +1,7 @@ import { TypeScriptReporterOptions } from './typescript-reporter/TypeScriptReporterOptions'; import { EsLintReporterOptions } from './eslint-reporter/EsLintReporterOptions'; import { IssueOptions } from './issue/IssueOptions'; -import { FormatterOptions } from './formatter/FormatterOptions'; +import { FormatterOptions } from './formatter'; import LoggerOptions from './logger/LoggerOptions'; interface ForkTsCheckerWebpackPluginOptions { diff --git a/src/eslint-reporter/issue/EsLintIssue.ts b/src/eslint-reporter/issue/EsLintIssueFactory.ts similarity index 100% rename from src/eslint-reporter/issue/EsLintIssue.ts rename to src/eslint-reporter/issue/EsLintIssueFactory.ts diff --git a/src/eslint-reporter/reporter/EsLintReporter.ts b/src/eslint-reporter/reporter/EsLintReporter.ts index 809830af..84779962 100644 --- a/src/eslint-reporter/reporter/EsLintReporter.ts +++ b/src/eslint-reporter/reporter/EsLintReporter.ts @@ -1,6 +1,6 @@ import { LintReport } from '../types/eslint'; import { createEsLintReporterState, EsLintReporterState } from './EsLintReporterState'; -import { createIssuesFromEsLintResults } from '../issue/EsLintIssue'; +import { createIssuesFromEsLintResults } from '../issue/EsLintIssueFactory'; import { EsLintReporterConfiguration } from '../EsLintReporterConfiguration'; import { Reporter } from '../../reporter'; diff --git a/src/formatter/FormatterFactory.ts b/src/formatter/FormatterFactory.ts index 9804d482..b30b61a4 100644 --- a/src/formatter/FormatterFactory.ts +++ b/src/formatter/FormatterFactory.ts @@ -3,17 +3,14 @@ import { BabelCodeFrameOptions, createCodeframeFormatter } from './CodeframeForm import { createBasicFormatter } from './BasicFormatter'; type NotConfigurableFormatterType = undefined | 'basic' | Formatter; -type ConfigurableFormatterOptionTypes = { +type ConfigurableFormatterType = 'codeframe'; +type FormatterType = NotConfigurableFormatterType | ConfigurableFormatterType; + +type ConfigurableFormatterOptions = { codeframe: BabelCodeFrameOptions; }; -type ConfigurableFormatterType = keyof ConfigurableFormatterOptionTypes; -type ConfigurableFormatterOptions< - T extends ConfigurableFormatterType -> = ConfigurableFormatterOptionTypes[T]; - -type FormatterType = NotConfigurableFormatterType | ConfigurableFormatterType; type ComplexFormatterOptions = T extends ConfigurableFormatterType - ? ConfigurableFormatterOptions + ? ConfigurableFormatterOptions[T] : never; // for not-configurable formatter type, provide single declaration @@ -21,7 +18,7 @@ function createFormatter(type?: T): Form // for each configurable formatter type, provide declaration with related configuration type function createFormatter( type: T, - options?: ConfigurableFormatterOptions + options?: ConfigurableFormatterOptions[T] ): Formatter; // for general use-case provide single declaration @@ -41,7 +38,9 @@ function createFormatter(type?: FormatterType, options?: object): Formatter { return createCodeframeFormatter(options); default: - throw new Error('Unknown "' + type + '" formatter. Available types are: basic, codeframe.'); + throw new Error( + `Unknown "${type}" formatter. Available types are: basic, codeframe, Function.` + ); } } diff --git a/src/formatter/WebpackFormatter.ts b/src/formatter/WebpackFormatter.ts index 0ef60647..e16ba9ff 100644 --- a/src/formatter/WebpackFormatter.ts +++ b/src/formatter/WebpackFormatter.ts @@ -1,17 +1,13 @@ import { Formatter } from './Formatter'; import os from 'os'; import chalk from 'chalk'; +import { formatIssueLocation } from '../issue'; function createWebpackFormatter(formatter: Formatter): Formatter { return function webpackFormatter(issue) { const severity = issue.severity.toUpperCase(); const file = issue.file; - const location = issue.location - ? [ - `${issue.location.start.line}:${issue.location.start.column}`, - `${issue.location.end.line}:${issue.location.end.column}`, - ].join('-') - : undefined; + const location = issue.location ? formatIssueLocation(issue.location) : undefined; const color = issue.severity === 'warning' ? chalk.yellow : chalk.red; const header = [severity, 'in', file].concat(location ? [location] : []).join(' '); diff --git a/src/formatter/index.ts b/src/formatter/index.ts index d1a929e0..63840699 100644 --- a/src/formatter/index.ts +++ b/src/formatter/index.ts @@ -1,4 +1,7 @@ export * from './Formatter'; export * from './BasicFormatter'; export * from './CodeframeFormatter'; +export * from './WebpackFormatter'; export * from './FormatterFactory'; +export * from './FormatterOptions'; +export * from './FormatterConfiguration'; diff --git a/src/issue/Issue.ts b/src/issue/Issue.ts index 3e2c0231..b3d5929e 100644 --- a/src/issue/Issue.ts +++ b/src/issue/Issue.ts @@ -8,7 +8,6 @@ interface Issue { message: string; file?: string; location?: IssueLocation; - stack?: string; } function isIssue(value: unknown): value is Issue { @@ -45,7 +44,6 @@ function compareIssues(issueA: Issue, issueB: Issue) { compareIssueLocations(issueA.location, issueB.location) || compareStrings(issueA.code, issueB.code) || compareStrings(issueA.message, issueB.message) || - compareStrings(issueA.stack, issueB.stack) || 0 /* EqualTo */ ); } diff --git a/src/issue/IssueLocation.ts b/src/issue/IssueLocation.ts index d9ee941b..ac5177af 100644 --- a/src/issue/IssueLocation.ts +++ b/src/issue/IssueLocation.ts @@ -6,6 +6,10 @@ interface IssueLocation { } function compareIssueLocations(locationA?: IssueLocation, locationB?: IssueLocation) { + if (locationA === locationB) { + return 0; + } + if (!locationA) { return -1; } @@ -20,4 +24,13 @@ function compareIssueLocations(locationA?: IssueLocation, locationB?: IssueLocat ); } -export { IssueLocation, compareIssueLocations }; +function formatIssueLocation(location: IssueLocation) { + return [ + `${location.start.line}:${location.start.column}`, + location.start.line !== location.end.line + ? `${location.end.line}:${location.end.column}` + : `${location.end.column}`, + ].join('-'); +} + +export { IssueLocation, compareIssueLocations, formatIssueLocation }; diff --git a/src/issue/IssuePosition.ts b/src/issue/IssuePosition.ts index bb3e6153..1bc7a179 100644 --- a/src/issue/IssuePosition.ts +++ b/src/issue/IssuePosition.ts @@ -4,6 +4,10 @@ interface IssuePosition { } function compareIssuePositions(positionA?: IssuePosition, positionB?: IssuePosition) { + if (positionA === positionB) { + return 0; + } + if (!positionA) { return -1; } diff --git a/src/issue/IssueWebpackError.ts b/src/issue/IssueWebpackError.ts index 85cf0fcb..24d680ac 100644 --- a/src/issue/IssueWebpackError.ts +++ b/src/issue/IssueWebpackError.ts @@ -1,30 +1,6 @@ import { relative } from 'path'; import { Issue } from './Issue'; -import { IssueLocation } from './IssueLocation'; - -interface IssueWebpackErrorLoc { - start: { - line: number; - column: number; - }; - end: { - line: number; - column: number; - }; -} - -function formatFile(file: string, context: string) { - return relative(context, file); -} - -function formatLocation(location: IssueLocation) { - return [ - `${location.start.line}:${location.start.column}`, - location.start.line !== location.end.line - ? `${location.end.line}:${location.end.column}` - : `${location.end.column}`, - ].join('-'); -} +import { formatIssueLocation } from './IssueLocation'; class IssueWebpackError extends Error { readonly hideStack = true; @@ -37,9 +13,9 @@ class IssueWebpackError extends Error { // should be a NormalModule instance. // to avoid such a dependency, we do a workaround - error.file will contain formatted location instead if (issue.file) { - const parts = [formatFile(issue.file, context)]; + const parts = [relative(context, issue.file)]; if (issue.location) { - parts.push(formatLocation(issue.location)); + parts.push(formatIssueLocation(issue.location)); } this.file = parts.join(' '); } diff --git a/src/typescript-reporter/assertTypeScriptSupport.ts b/src/typescript-reporter/assertTypeScriptSupport.ts index fc7c868a..a96beb56 100644 --- a/src/typescript-reporter/assertTypeScriptSupport.ts +++ b/src/typescript-reporter/assertTypeScriptSupport.ts @@ -12,23 +12,36 @@ function assertTypeScriptSupport(configuration: TypeScriptReporterConfiguration) typescriptVersion = require('typescript').version; } catch (error) { throw new Error( - 'When you use this plugin with typescript reporter enabled, you must install `typescript`.' + 'When you use ForkTsCheckerWebpackPlugin with typescript reporter enabled, you must install `typescript` package.' ); } - if (semver.lt(typescriptVersion, '2.1.0')) { + if (semver.lt(typescriptVersion, '2.7.0')) { throw new Error( - `Cannot use current typescript version of ${typescriptVersion}, the minimum required version is 2.1.0` + [ + `ForkTsCheckerWebpackPlugin cannot use the current typescript version of ${typescriptVersion}.`, + 'The minimum required version is 2.7.0.', + ].join(os.EOL) + ); + } + + if (configuration.build && semver.lt(typescriptVersion, '3.6.0')) { + throw new Error( + [ + `ForkTsCheckerWebpackPlugin cannot use the current typescript version of ${typescriptVersion} because of the "build" option enabled.`, + 'The minimum version that supports "build" option is 3.6.0.', + 'Consider upgrading `typescript` or disabling "build" option.', + ].join(os.EOL) ); } if (!fs.existsSync(configuration.tsconfig)) { throw new Error( [ - `Cannot find "${configuration.tsconfig}" file.`, + `Cannot find the "${configuration.tsconfig}" file.`, `Please check webpack and ForkTsCheckerWebpackPlugin configuration.`, `Possible errors:`, - ' - wrong `context` directory in webpack configuration (if `tsconfig` is not set or is a relative path in fork plugin configuration)', + ' - wrong `context` directory in webpack configuration (if `tsconfig` is not set or is a relative path in the fork plugin configuration)', ' - wrong `typescript.tsconfig` path in the plugin configuration (should be a relative or absolute path)', ].join(os.EOL) ); diff --git a/test/unit/FileRegister.spec.ts b/test/unit/FileRegister.spec.ts deleted file mode 100644 index 6a081bf3..00000000 --- a/test/unit/FileRegister.spec.ts +++ /dev/null @@ -1,111 +0,0 @@ -import { FilesRegister } from '../../lib/FilesRegister'; - -describe('[UNIT] FilesRegister', () => { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - let register: any; - beforeEach(() => { - register = new FilesRegister( - () => - ({ - test: true - // eslint-disable-next-line @typescript-eslint/no-explicit-any - } as any) - ); - }); - - it('should add and remove files', () => { - register.add('/test'); - register.add('/test2'); - expect(register.has('/test')).toBe(true); - expect(register.has('/test2')).toBe(true); - register.remove('/test'); - expect(register.has('/test')).toBe(false); - expect(register.has('/test2')).toBe(true); - - expect(function() { - register.remove('/test'); - }).not.toThrowError(); - register.remove('/test2'); - expect(register.has('/test')).toBe(false); - expect(register.has('/test2')).toBe(false); - }); - - it('should get file that exists in register', () => { - register.add('/test'); - expect(function() { - register.get('/test'); - }).not.toThrowError(); - expect(function() { - register.get('/test2'); - }).toThrowError(); - expect(typeof register.get('/test')).toBe('object'); - expect(Object.keys(register.get('/test'))).toEqual(['mtime', 'data']); - }); - - it('should list all keys in register', () => { - register.add('/test'); - register.add('/test/foo'); - register.add('/test/foo/bar'); - expect(register.keys()).toEqual(['/test', '/test/foo', '/test/foo/bar']); - - register.remove('/test'); - expect(register.keys()).toEqual(['/test/foo', '/test/foo/bar']); - }); - - it('should get data from file', () => { - register.add('/test'); - expect(register.getData('/test')).toEqual({ test: true }); - expect(function() { - register.getData('/test2'); - }).toThrowError(Error); - }); - - it('should ensure if file exists', () => { - expect(register.has('/test')).toBe(false); - register.ensure('/test'); - expect(register.has('/test')).toBe(true); - - const reference = register.get('/test'); - register.ensure('/test'); - expect(reference).toBe(register.get('/test')); - }); - - it('should mutate existing data', () => { - register.add('/test'); - const dataReference = register.getData('/test'); - expect(dataReference.test).toBe(true); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - register.mutateData('/test', function(data: any) { - data.test = false; - }); - expect(dataReference).toBe(register.getData('/test')); - expect(dataReference.test).toBe(false); - }); - - it('should set mtime and reset data if mtime changes', () => { - register.add('/test'); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - register.mutateData('/test', function(data: any) { - data.test = false; - }); - expect(register.getData('/test').test).toBe(false); - expect(register.getMtime('/test')).toBeUndefined(); - - register.setMtime('/test', 1000); - expect(register.getMtime('/test')).toBe(1000); - expect(register.getData('/test').test).toBe(true); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - register.mutateData('/test', function(data: any) { - data.test = false; - }); - expect(register.getData('/test').test).toBe(false); - - register.setMtime('/test', 1000); - expect(register.getMtime('/test')).toBe(1000); - expect(register.getData('/test').test).toBe(false); - - register.setMtime('/test', 1001); - expect(register.getMtime('/test')).toBe(1001); - expect(register.getData('/test').test).toBe(true); - }); -}); diff --git a/test/unit/ForkTsCheckerWebpackPlugin.spec.ts b/test/unit/ForkTsCheckerWebpackPlugin.spec.ts new file mode 100644 index 00000000..5a2e951a --- /dev/null +++ b/test/unit/ForkTsCheckerWebpackPlugin.spec.ts @@ -0,0 +1,15 @@ +import { ForkTsCheckerWebpackPlugin } from '../../lib/ForkTsCheckerWebpackPlugin'; + +describe('ForkTsCheckerWebpackPlugin', () => { + it.each([{ invalid: true }, false, null, 'unknown string', { typescript: 'invalid option' }])( + 'throws an error for invalid options %p', + (options) => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + expect(() => new ForkTsCheckerWebpackPlugin(options as any)).toThrowError(); + } + ); + + it("doesn't throw an error for empty options", () => { + expect(() => new ForkTsCheckerWebpackPlugin()).not.toThrowError(); + }); +}); diff --git a/test/unit/IncrementalChecker.spec.ts b/test/unit/IncrementalChecker.spec.ts deleted file mode 100644 index d426fafc..00000000 --- a/test/unit/IncrementalChecker.spec.ts +++ /dev/null @@ -1,48 +0,0 @@ -import * as typescript from 'typescript'; -import { IncrementalChecker } from '../../lib/IncrementalChecker'; - -jest.mock('typescript', () => ({ - parseJsonConfigFileContent: jest.fn(function(tsconfig) { - return { - options: tsconfig.compilerOptions - }; - }), - readConfigFile() { - return { - config: { - compilerOptions: { - foo: true - } - } - }; - }, - - sys: {} -})); - -describe('[UNIT] IncrementalChecker', () => { - describe('loadProgramConfig', () => { - it('merges compilerOptions into config file options', () => { - IncrementalChecker.loadProgramConfig( - // eslint-disable-next-line @typescript-eslint/no-var-requires - require('typescript'), - 'tsconfig.foo.json', - { - bar: false - } - ); - - expect(typescript.parseJsonConfigFileContent).toHaveBeenCalledTimes(1); - expect(typescript.parseJsonConfigFileContent).toHaveBeenLastCalledWith( - { - compilerOptions: { - foo: true, - bar: false - } - }, - expect.anything(), - expect.anything() - ); - }); - }); -}); diff --git a/test/unit/VueProgram.spec.ts b/test/unit/VueProgram.spec.ts deleted file mode 100644 index 9deeaa47..00000000 --- a/test/unit/VueProgram.spec.ts +++ /dev/null @@ -1,218 +0,0 @@ -import unixify from 'unixify'; -import * as ts from 'typescript'; -import { VueProgram } from '../../lib/VueProgram'; -import ForkTsCheckerWebpackPlugin from '../../lib/index'; - -const templateCompilers = [ - 'vue-template-compiler', - 'nativescript-vue-template-compiler' -]; - -jest.mock('typescript', () => { - const originalTs = jest.requireActual('typescript'); - return { - parseJsonConfigFileContent: jest.fn(tsconfig => ({ - options: tsconfig.compilerOptions - })), - readConfigFile: () => ({ - config: { - compilerOptions: { - foo: true - } - } - }), - sys: {}, - ScriptKind: originalTs.ScriptKind - }; -}); - -describe('[UNIT] VueProgram', () => { - it('should determine if file is a Vue file', () => { - expect(VueProgram.isVue('./test.vue')).toBe(true); - expect(VueProgram.isVue('../test.vue')).toBe(true); - expect(VueProgram.isVue('../../test.vue')).toBe(true); - expect(VueProgram.isVue('@/test.vue')).toBe(true); - expect(VueProgram.isVue('~/test.vue')).toBe(true); - expect(VueProgram.isVue('../../.vue')).toBe(false); - expect(VueProgram.isVue('./test.css')).toBe(false); - expect(VueProgram.isVue('./')).toBe(false); - }); - - it('should properly resolve relative module names', () => { - const basedir = '/base/dir'; - const containingFile = '/con/tain/ing/main.ts'; - const options: ts.CompilerOptions = { - baseUrl: '/baseurl', - paths: { - '@/*': ['src/*'] - } - }; - const moduleNames = ['./test.vue', '../test.vue', '../../test.vue']; - - const resolvedModuleNames = moduleNames.map(function(moduleName) { - return VueProgram.resolveNonTsModuleName( - moduleName, - containingFile, - basedir, - options - ); - }); - - expect(unixify(resolvedModuleNames[0])).toBe('/con/tain/ing/test.vue'); - expect(unixify(resolvedModuleNames[1])).toBe('/con/tain/test.vue'); - expect(unixify(resolvedModuleNames[2])).toBe('/con/test.vue'); - }); - - it('should properly resolve wildcard module names', () => { - const basedir = '/base/dir'; - const containingFile = '/con/tain/ing/main.ts'; - const options: ts.CompilerOptions = {}; - const moduleName = '@/test.vue'; - - let resolvedModuleName = VueProgram.resolveNonTsModuleName( - moduleName, - containingFile, - basedir, - options - ); - expect(unixify(resolvedModuleName)).toBe('/base/dir/src/test.vue'); - - options.baseUrl = '/baseurl1'; - resolvedModuleName = VueProgram.resolveNonTsModuleName( - moduleName, - containingFile, - basedir, - options - ); - expect(unixify(resolvedModuleName)).toBe('/baseurl1/src/test.vue'); - - options.baseUrl = '/baseurl2'; - options.paths = { '@/*': ['src1/*'] }; - resolvedModuleName = VueProgram.resolveNonTsModuleName( - moduleName, - containingFile, - basedir, - options - ); - expect(unixify(resolvedModuleName)).toBe('/baseurl2/src1/test.vue'); - - options.baseUrl = '/baseurl3'; - options.paths = { '@/*': ['src1/src2/*'] }; - resolvedModuleName = VueProgram.resolveNonTsModuleName( - moduleName, - containingFile, - basedir, - options - ); - expect(unixify(resolvedModuleName)).toBe('/baseurl3/src1/src2/test.vue'); - }); - - const vueOptionsVariants = [ - void 0, - true, - false, - {}, - { enabled: true }, - { enabled: false }, - { compiler: 'vue-template-compiler' } - ]; - - it.each(vueOptionsVariants)( - 'should init valid vue options with: %p', - option => { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const result = (ForkTsCheckerWebpackPlugin as any).prepareVueOptions( - option - ); - expect(typeof result.enabled).toBe('boolean'); - expect(typeof result.compiler).toBe('string'); - } - ); - - it.each(templateCompilers)( - 'should extract script block with compiler=%s', - templateCompiler => { - const content = [ - '' - ].join('\n'); - - const result = VueProgram.resolveScriptBlock( - ts, - content, - templateCompiler - ); - - expect(result.scriptKind).toBe(ts.ScriptKind.TS); - expect(result.content).toBe( - [ - '', - 'import Vue from "vue";', - 'export default Vue.extend({});', - '' - ].join('\n') - ); - } - ); - - it.each(templateCompilers)('should pad lines with %s', templateCompiler => { - const content = [ - '', - '', - '' - ].join('\n'); - - const result = VueProgram.resolveScriptBlock(ts, content, templateCompiler); - expect(result.content).toBe( - [ - '//', - '//', - '//', - '//', - '', - 'import Vue from "vue";', - 'export default Vue.extend({});', - '' - ].join('\n') - ); - }); - - describe('loadProgramConfig', () => { - it('sets allowNonTsExtensions to true on returned options', () => { - const result = VueProgram.loadProgramConfig( - // eslint-disable-next-line @typescript-eslint/no-var-requires - require('typescript'), - 'tsconfig.foo.json', - {} - ); - - expect(result.options.allowNonTsExtensions).toBe(true); - }); - - it('merges compilerOptions into config file options', () => { - // eslint-disable-next-line @typescript-eslint/no-var-requires - VueProgram.loadProgramConfig(require('typescript'), 'tsconfig.foo.json', { - bar: false - }); - - expect(ts.parseJsonConfigFileContent).toHaveBeenLastCalledWith( - { - compilerOptions: { - allowNonTsExtensions: true, - foo: true, - bar: false - } - }, - expect.anything(), - expect.anything() - ); - }); - }); -}); diff --git a/test/unit/cancellation/CancelledError.spec.ts b/test/unit/cancellation/CancelledError.spec.ts deleted file mode 100644 index e261bab7..00000000 --- a/test/unit/cancellation/CancelledError.spec.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { CancelledError } from '../../../lib/cancellation'; - -describe('[UNIT] cancellation/CancelledError', () => { - it('defines CancelledError with default message', () => { - const error = new CancelledError(); - - expect(error).toBeInstanceOf(Error); - expect(error.message).toEqual('Operation has been cancelled.'); - }); - - it('allows to pass custom message', () => { - const error = new CancelledError('Fetching has been cancelled.'); - - expect(error.message).toEqual('Fetching has been cancelled.'); - }); -}); diff --git a/test/unit/cancellation/FileBasedCancellationToken.spec.ts b/test/unit/cancellation/FileBasedCancellationToken.spec.ts deleted file mode 100644 index 3ed37d46..00000000 --- a/test/unit/cancellation/FileBasedCancellationToken.spec.ts +++ /dev/null @@ -1,108 +0,0 @@ -import * as os from 'os'; -import * as path from 'path'; -import * as fs from 'fs'; -import mockFs from 'mock-fs'; - -import { FileBasedCancellationToken } from '../../../lib/cancellation'; - -describe('[UNIT] cancellation/FileBasedCancellationToken', () => { - beforeEach(() => { - mockFs({ - [os.tmpdir()]: mockFs.directory() - }); - }); - - afterEach(() => { - mockFs.restore(); - }); - - it('creates valid cancellation token', () => { - const tokenA = new FileBasedCancellationToken(); - expect(tokenA.isCancellationRequested()).toBe(false); - - const tokenB = new FileBasedCancellationToken( - path.join(os.tmpdir(), 'FA#FERgSERgRT$rA$#rA#Ea@RweFRgERG') - ); - expect(tokenB.isCancellationRequested()).toBe(false); - - const tokenC = new FileBasedCancellationToken( - path.join(os.tmpdir(), 'GFERWgEgeF#R2erwreWrweWER'), - false - ); - expect(tokenC.isCancellationRequested()).toBe(false); - - const tokenD = new FileBasedCancellationToken( - path.join(os.tmpdir(), 'REGg$#R2$#@r@#R$#T43T$#t43t'), - true - ); - expect(tokenD.isCancellationRequested()).toBe(true); - }); - - it('serializes to JSON', () => { - const tokenA = new FileBasedCancellationToken(); - const json = JSON.stringify(tokenA); - - expect(typeof json).toBe('string'); - expect(() => JSON.parse(json)).not.toThrowError(); - expect(typeof JSON.parse(json)).toBe('object'); - - const tokenB = FileBasedCancellationToken.createFromJSON(JSON.parse(json)); - expect(tokenA.isCancellationRequested()).toBe( - tokenB.isCancellationRequested() - ); - }); - - it('generates path in os.tmpdir() directory', () => { - const tokenA = new FileBasedCancellationToken(); - - expect(tokenA.toJSON().cancellationFilePath.indexOf(os.tmpdir())).toBe(0); - }); - - it('writes file in filesystem on requestCancellation', () => { - const tokenA = new FileBasedCancellationToken(); - tokenA.requestCancellation(); - - expect(tokenA.isCancellationRequested()).toBe(true); - expect(fs.existsSync(tokenA.toJSON().cancellationFilePath)).toBe(true); - }); - - it('cleanups file on cleanupCancellation', () => { - const tokenA = new FileBasedCancellationToken(); - tokenA.requestCancellation(); - tokenA.cleanupCancellation(); - - expect(tokenA.isCancellationRequested()).toBe(false); - expect(fs.existsSync(tokenA.toJSON().cancellationFilePath)).toBe(false); - - // make sure we can call it as many times as we want to - expect(() => tokenA.cleanupCancellation()).not.toThrowError(); - expect(tokenA.isCancellationRequested()).toBe(false); - }); - - it('not throws an error on cleanupCancellation with no file exists', () => { - const tokenA = new FileBasedCancellationToken( - 'some_file_that_doesnt_exists', - true - ); - - expect(() => tokenA.cleanupCancellation()).not.toThrowError(); - expect(() => tokenA.cleanupCancellation()).not.toThrowError(); - }); - - it('throttles check for 20ms', done => { - const tokenA = new FileBasedCancellationToken(); - const tokenB = FileBasedCancellationToken.createFromJSON(tokenA.toJSON()); - - expect(tokenA.isCancellationRequested()).toBe(false); - expect(tokenB.isCancellationRequested()).toBe(false); - - tokenA.requestCancellation(); - expect(tokenB.isCancellationRequested()).toBe(false); - expect(tokenA.isCancellationRequested()).toBe(true); - - setTimeout(() => { - expect(tokenB.isCancellationRequested()).toBe(true); - done(); - }, 50); - }); -}); diff --git a/test/unit/cancellation/typescript/TypeScriptCancellationToken.spec.ts b/test/unit/cancellation/typescript/TypeScriptCancellationToken.spec.ts deleted file mode 100644 index 3bf2670d..00000000 --- a/test/unit/cancellation/typescript/TypeScriptCancellationToken.spec.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { - CancellationToken, - TypeScriptCancellationToken -} from '../../../../lib/cancellation'; -import * as ts from 'typescript'; - -class OperationCanceledException {} - -describe('[UNIT] cancellation/typescript/FileBasedCancellationToken', () => { - let cancellationRequested: boolean; - let typescript: typeof ts; - let sourceToken: CancellationToken; - let token: TypeScriptCancellationToken; - - beforeEach(() => { - cancellationRequested = true; - sourceToken = { - isCancellationRequested: jest.fn(() => cancellationRequested), - requestCancellation: jest.fn(), - cleanupCancellation: jest.fn() - }; - typescript = ({ - OperationCanceledException - } as unknown) as typeof ts; - token = new TypeScriptCancellationToken(typescript, sourceToken); - }); - - it('proxies CancellationToken methods', () => { - cancellationRequested = false; - expect(token.isCancellationRequested()).toEqual(false); - expect(sourceToken.isCancellationRequested).toHaveBeenCalledTimes(1); - expect(sourceToken.requestCancellation).toHaveBeenCalledTimes(0); - expect(sourceToken.cleanupCancellation).toHaveBeenCalledTimes(0); - - cancellationRequested = true; - expect(token.isCancellationRequested()).toEqual(true); - expect(sourceToken.isCancellationRequested).toHaveBeenCalledTimes(2); - expect(sourceToken.requestCancellation).toHaveBeenCalledTimes(0); - expect(sourceToken.cleanupCancellation).toHaveBeenCalledTimes(0); - - expect(token.requestCancellation()).toBeUndefined(); - expect(sourceToken.isCancellationRequested).toHaveBeenCalledTimes(2); - expect(sourceToken.requestCancellation).toHaveBeenCalledTimes(1); - expect(sourceToken.cleanupCancellation).toHaveBeenCalledTimes(0); - - expect(token.cleanupCancellation()).toBeUndefined(); - expect(sourceToken.isCancellationRequested).toHaveBeenCalledTimes(2); - expect(sourceToken.requestCancellation).toHaveBeenCalledTimes(1); - expect(sourceToken.cleanupCancellation).toHaveBeenCalledTimes(1); - }); - - it('throws a TypeScript specific error', () => { - cancellationRequested = false; - expect(() => token.throwIfCancellationRequested()).not.toThrowError(); - - cancellationRequested = true; - expect(() => token.throwIfCancellationRequested()).toThrowError( - typescript.OperationCanceledException - ); - }); -}); diff --git a/test/unit/issue/eslint/EsLintIssueFactory.spec.ts b/test/unit/eslint-reporter/issue/EsLintIssueFactory.spec.ts similarity index 50% rename from test/unit/issue/eslint/EsLintIssueFactory.spec.ts rename to test/unit/eslint-reporter/issue/EsLintIssueFactory.spec.ts index 346ee803..8cf50d39 100644 --- a/test/unit/issue/eslint/EsLintIssueFactory.spec.ts +++ b/test/unit/eslint-reporter/issue/EsLintIssueFactory.spec.ts @@ -1,11 +1,7 @@ -import { createIssuesFromEsLintReports } from '../../../../lib/issue'; -import { - LintMessage, - LintReport, - LintResult -} from '../../../../lib/types/eslint'; +import { LintMessage, LintResult } from '../../../../lib/types/eslint'; +import { createIssuesFromEsLintResults } from '../../../../lib/eslint-reporter/issue/EsLintIssueFactory'; -describe('[UNIT] issue/eslint/EsLintIssueFactory', () => { +describe('eslint-reporter/issue/EsLintIssueFactory', () => { const ES_LINT_MESSAGE_ERROR: LintMessage = { column: 0, line: 13, @@ -15,7 +11,7 @@ describe('[UNIT] issue/eslint/EsLintIssueFactory', () => { message: `'y' is assigned a value but never used.`, nodeType: '', severity: 0, - source: null + source: null, }; const ES_LINT_MESSAGE_WARNING: LintMessage = { column: 10, @@ -24,7 +20,7 @@ describe('[UNIT] issue/eslint/EsLintIssueFactory', () => { message: `'y' is assigned a value but never used.`, nodeType: '', severity: 1, - source: null + source: null, }; const ES_LINT_RESULT_INDEX: LintResult = { filePath: 'src/index.ts', @@ -32,7 +28,7 @@ describe('[UNIT] issue/eslint/EsLintIssueFactory', () => { errorCount: 1, warningCount: 0, fixableErrorCount: 0, - fixableWarningCount: 0 + fixableWarningCount: 0, }; const ES_LINT_RESULT_ANOTHER: LintResult = { filePath: 'src/another.ts', @@ -40,7 +36,7 @@ describe('[UNIT] issue/eslint/EsLintIssueFactory', () => { errorCount: 0, warningCount: 1, fixableErrorCount: 0, - fixableWarningCount: 0 + fixableWarningCount: 0, }; const ES_LINT_RESULT_ADDITIONAL: LintResult = { filePath: 'src/additional.ts', @@ -48,30 +44,13 @@ describe('[UNIT] issue/eslint/EsLintIssueFactory', () => { errorCount: 1, warningCount: 0, fixableErrorCount: 0, - fixableWarningCount: 0 + fixableWarningCount: 0, }; - const ES_LINT_REPORT_A: LintReport = { - results: [ES_LINT_RESULT_INDEX, ES_LINT_RESULT_ANOTHER], - errorCount: 1, - warningCount: 1, - fixableErrorCount: 0, - fixableWarningCount: 0 - }; - const ES_LINT_REPORT_B: LintReport = { - results: [ES_LINT_RESULT_ADDITIONAL], - errorCount: 1, - warningCount: 1, - fixableErrorCount: 0, - fixableWarningCount: 0 - }; - const ES_LINT_REPORTS = [ES_LINT_REPORT_A, ES_LINT_REPORT_B]; + const ES_LINT_RESULTS = [ES_LINT_RESULT_INDEX, ES_LINT_RESULT_ANOTHER, ES_LINT_RESULT_ADDITIONAL]; - it.each([[ES_LINT_REPORTS]])( - 'creates Issues from EsLint Reports: %p', - reports => { - const issues = createIssuesFromEsLintReports(reports); + it.each([[ES_LINT_RESULTS]])('creates Issues from EsLint Results: %p', (results) => { + const issues = createIssuesFromEsLintResults(results); - expect(issues).toMatchSnapshot(); - } - ); + expect(issues).toMatchSnapshot(); + }); }); diff --git a/test/unit/eslint-reporter/issue/__snapshots__/EsLintIssueFactory.spec.ts.snap b/test/unit/eslint-reporter/issue/__snapshots__/EsLintIssueFactory.spec.ts.snap new file mode 100644 index 00000000..65b45e85 --- /dev/null +++ b/test/unit/eslint-reporter/issue/__snapshots__/EsLintIssueFactory.spec.ts.snap @@ -0,0 +1,57 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`eslint-reporter/issue/EsLintIssueFactory creates Issues from EsLint Results: [[Object], [Object], [Object]] 1`] = ` +Array [ + Object { + "code": "no-unused-vars", + "file": "src/index.ts", + "location": Object { + "end": Object { + "column": 5, + "line": 13, + }, + "start": Object { + "column": 0, + "line": 13, + }, + }, + "message": "'y' is assigned a value but never used.", + "origin": "eslint", + "severity": "error", + }, + Object { + "code": "no-unused-vars", + "file": "src/another.ts", + "location": Object { + "end": Object { + "column": 10, + "line": 15, + }, + "start": Object { + "column": 10, + "line": 15, + }, + }, + "message": "'y' is assigned a value but never used.", + "origin": "eslint", + "severity": "warning", + }, + Object { + "code": "no-unused-vars", + "file": "src/additional.ts", + "location": Object { + "end": Object { + "column": 5, + "line": 13, + }, + "start": Object { + "column": 0, + "line": 13, + }, + }, + "message": "'y' is assigned a value but never used.", + "origin": "eslint", + "severity": "error", + }, +] +`; diff --git a/test/unit/formatter/BasicFormatter.spec.ts b/test/unit/formatter/BasicFormatter.spec.ts new file mode 100644 index 00000000..b7498e66 --- /dev/null +++ b/test/unit/formatter/BasicFormatter.spec.ts @@ -0,0 +1,53 @@ +import { Issue } from '../../../lib/issue'; +import { createBasicFormatter } from '../../../lib/formatter'; + +describe('formatter/BasicFormatter', () => { + it.each([ + [ + { + origin: 'typescript', + severity: 'error', + code: 'TS2322', + message: `Type '"1"' is not assignable to type 'number'.`, + file: 'src/index.ts', + location: { + start: { + line: 10, + column: 4, + }, + end: { + line: 10, + column: 6, + }, + }, + }, + `TS2322: Type '"1"' is not assignable to type 'number'.`, + ], + [ + { + origin: 'eslint', + severity: 'warning', + code: 'no-unused-vars', + message: `'x' is assigned a value but never used.`, + file: 'src/index.ts', + location: { + start: { + line: 12, + column: 8, + }, + end: { + line: 12, + column: 9, + }, + }, + }, + `no-unused-vars: 'x' is assigned a value but never used.`, + ], + ])('formats issue message "%p" to "%p"', (...args) => { + const [issue, expectedFormatted] = args as [Issue, string]; + const formatter = createBasicFormatter(); + const formatted = formatter(issue); + + expect(formatted).toEqual(expectedFormatted); + }); +}); diff --git a/test/unit/formatter/CodeframeFormatter.spec.ts b/test/unit/formatter/CodeframeFormatter.spec.ts index 1616fafb..3e59bb48 100644 --- a/test/unit/formatter/CodeframeFormatter.spec.ts +++ b/test/unit/formatter/CodeframeFormatter.spec.ts @@ -1,21 +1,21 @@ import * as os from 'os'; import mockFs from 'mock-fs'; -import { Issue, IssueOrigin, IssueSeverity } from '../../../lib/issue'; +import { Issue } from '../../../lib/issue'; import { createCodeframeFormatter } from '../../../lib/formatter'; -describe('[UNIT] formatter/CodeframeFormatter', () => { +describe('formatter/CodeframeFormatter', () => { beforeEach(() => { mockFs({ src: { 'index.ts': [ - 'const y: number = "1";', - 'const x = 1;', + 'const foo: number = "1";', + 'const bar = 1;', '', - 'function z() {', - ' console.log(y);', - '}' - ].join('\n') - } + 'function baz() {', + ' console.log(baz);', + '}', + ].join('\n'), + }, }); }); @@ -26,70 +26,111 @@ describe('[UNIT] formatter/CodeframeFormatter', () => { it.each([ [ { - origin: IssueOrigin.TYPESCRIPT, - severity: IssueSeverity.ERROR, - code: '2322', + origin: 'typescript', + severity: 'error', + code: 'TS2322', message: `Type '"1"' is not assignable to type 'number'.`, file: 'src/index.ts', - line: 1, - character: 7 + location: { + start: { + line: 1, + column: 7, + }, + end: { + line: 1, + column: 10, + }, + }, }, [ - `ERROR in src/index.ts(1,7):`, - `1:7 Type '"1"' is not assignable to type 'number'.`, - ' > 1 | const y: number = "1";', - ' | ^', - ' 2 | const x = 1;' - ].join(os.EOL) + `TS2322: Type '"1"' is not assignable to type 'number'.`, + ' > 1 | const foo: number = "1";', + ' | ^^^', + ' 2 | const bar = 1;', + ].join(os.EOL), ], [ { - origin: IssueOrigin.TYPESCRIPT, - severity: IssueSeverity.ERROR, - code: '2322', + origin: 'typescript', + severity: 'error', + code: 'TS2322', message: `Type '"1"' is not assignable to type 'number'.`, - file: 'src/not-existing.ts', - line: 1, - character: 7 + file: 'src/index.ts', }, - [ - `ERROR in src/not-existing.ts(1,7):`, - `1:7 Type '"1"' is not assignable to type 'number'.` - ].join(os.EOL) + `TS2322: Type '"1"' is not assignable to type 'number'.`, ], [ { - origin: IssueOrigin.ESLINT, - severity: IssueSeverity.WARNING, - code: 'no-unused-vars', - message: `'x' is assigned a value but never used.`, + origin: 'typescript', + severity: 'error', + code: 'TS2322', + message: `Type '"1"' is not assignable to type 'number'.`, file: 'src/index.ts', - line: 2, - character: 7 + location: { + start: { + line: 1, + column: 7, + }, + }, }, [ - `WARNING in src/index.ts(2,7):`, - `2:7 'x' is assigned a value but never used.`, - ' 1 | const y: number = "1";', - ' > 2 | const x = 1;', + `TS2322: Type '"1"' is not assignable to type 'number'.`, + ' > 1 | const foo: number = "1";', ' | ^', - ' 3 | ' - ].join(os.EOL) + ' 2 | const bar = 1;', + ].join(os.EOL), ], [ { - origin: IssueOrigin.INTERNAL, - severity: IssueSeverity.ERROR, - code: 'INTERNAL', - message: `Stack overflow - out of memory` + origin: 'typescript', + severity: 'error', + code: 'TS2322', + message: `Type '"1"' is not assignable to type 'number'.`, + file: 'src/not-existing.ts', + location: { + start: { + line: 1, + column: 7, + }, + end: { + line: 1, + column: 10, + }, + }, }, - 'INTERNAL ERROR: Stack overflow - out of memory' - ] + `TS2322: Type '"1"' is not assignable to type 'number'.`, + ], + [ + { + origin: 'eslint', + severity: 'warning', + code: 'no-unused-vars', + message: `'bar' is assigned a value but never used.`, + file: 'src/index.ts', + location: { + start: { + line: 2, + column: 7, + }, + end: { + line: 2, + column: 10, + }, + }, + }, + [ + `no-unused-vars: 'bar' is assigned a value but never used.`, + ' 1 | const foo: number = "1";', + ' > 2 | const bar = 1;', + ' | ^^^', + ' 3 | ', + ].join(os.EOL), + ], ])('formats issue message "%p" to "%p"', (...args) => { const [issue, expectedFormatted] = args as [Issue, string]; const formatter = createCodeframeFormatter({ linesAbove: 1, - linesBelow: 1 + linesBelow: 1, }); const formatted = formatter(issue); diff --git a/test/unit/formatter/DefaultFormatter.spec.ts b/test/unit/formatter/DefaultFormatter.spec.ts deleted file mode 100644 index 813d60d4..00000000 --- a/test/unit/formatter/DefaultFormatter.spec.ts +++ /dev/null @@ -1,53 +0,0 @@ -import * as os from 'os'; -import { Issue, IssueOrigin, IssueSeverity } from '../../../lib/issue'; -import { createDefaultFormatter } from '../../../lib/formatter'; - -describe('[UNIT] formatter/DefaultFormatter', () => { - it.each([ - [ - { - origin: IssueOrigin.TYPESCRIPT, - severity: IssueSeverity.ERROR, - code: '2322', - message: `Type '"1"' is not assignable to type 'number'.`, - file: 'src/index.ts', - line: 1, - character: 7 - }, - [ - `ERROR in src/index.ts(1,7):`, - `TS2322: Type '"1"' is not assignable to type 'number'.` - ].join(os.EOL) - ], - [ - { - origin: IssueOrigin.ESLINT, - severity: IssueSeverity.WARNING, - code: 'no-unused-vars', - message: `'x' is assigned a value but never used.`, - file: 'src/index.ts', - line: 2, - character: 10 - }, - [ - `WARNING in src/index.ts(2,10):`, - `no-unused-vars: 'x' is assigned a value but never used.` - ].join(os.EOL) - ], - [ - { - origin: IssueOrigin.INTERNAL, - severity: IssueSeverity.ERROR, - code: 'INTERNAL', - message: `Stack overflow - out of memory` - }, - 'INTERNAL ERROR: Stack overflow - out of memory' - ] - ])('formats issue message "%p" to "%p"', (...args) => { - const [issue, expectedFormatted] = args as [Issue, string]; - const formatter = createDefaultFormatter(); - const formatted = formatter(issue); - - expect(formatted).toEqual(expectedFormatted); - }); -}); diff --git a/test/unit/formatter/FormatterConfiguration.spec.ts b/test/unit/formatter/FormatterConfiguration.spec.ts new file mode 100644 index 00000000..065b5d6c --- /dev/null +++ b/test/unit/formatter/FormatterConfiguration.spec.ts @@ -0,0 +1,75 @@ +import os from 'os'; +import mockFs from 'mock-fs'; +import { createFormatterConfiguration, Formatter, FormatterOptions } from '../../../lib/formatter'; +import { Issue } from '../../../lib/issue'; + +describe('formatter/FormatterConfiguration', () => { + beforeEach(() => { + mockFs({ + src: { + 'index.ts': [ + 'const foo: number = "1";', + 'const bar = 1;', + '', + 'function baz() {', + ' console.log(baz);', + '}', + ].join('\n'), + }, + }); + }); + + afterEach(() => { + mockFs.restore(); + }); + + const issue: Issue = { + origin: 'typescript', + severity: 'error', + code: 'TS2322', + message: `Type '"1"' is not assignable to type 'number'.`, + file: 'src/index.ts', + location: { + start: { + line: 1, + column: 7, + }, + end: { + line: 1, + column: 10, + }, + }, + }; + const customFormatter: Formatter = (issue) => issue.origin.toUpperCase(); + + const BASIC_FORMATTER_OUTPUT = `TS2322: Type '"1"' is not assignable to type 'number'.`; + const CODEFRAME_FORMATTER_OUTPUT = [ + BASIC_FORMATTER_OUTPUT, + ' > 1 | const foo: number = "1";', + ' | ^^^', + ' 2 | const bar = 1;', + ' 3 | ', + ' 4 | function baz() {', + ].join(os.EOL); + const CUSTOM_CODEFRAME_FORMATTER_OUTPUT = [ + BASIC_FORMATTER_OUTPUT, + ' > 1 | const foo: number = "1";', + ' | ^^^', + ' 2 | const bar = 1;', + ].join(os.EOL); + const CUSTOM_FORMATTER_OUTPUT = 'TYPESCRIPT'; + + it.each([ + [undefined, CODEFRAME_FORMATTER_OUTPUT], + ['basic', BASIC_FORMATTER_OUTPUT], + ['codeframe', CODEFRAME_FORMATTER_OUTPUT], + [customFormatter, CUSTOM_FORMATTER_OUTPUT], + [{ type: 'basic' }, BASIC_FORMATTER_OUTPUT], + [{ type: 'codeframe' }, CODEFRAME_FORMATTER_OUTPUT], + [{ type: 'codeframe', options: { linesBelow: 1 } }, CUSTOM_CODEFRAME_FORMATTER_OUTPUT], + ])('creates configuration from options', (options, expectedFormat) => { + const formatter = createFormatterConfiguration(options as FormatterOptions); + + expect(formatter(issue)).toEqual(expectedFormat); + }); +}); diff --git a/test/unit/formatter/FormatterFactory.spec.ts b/test/unit/formatter/FormatterFactory.spec.ts index 2758592d..d5e9136e 100644 --- a/test/unit/formatter/FormatterFactory.spec.ts +++ b/test/unit/formatter/FormatterFactory.spec.ts @@ -1,9 +1,9 @@ import * as os from 'os'; import mockFs from 'mock-fs'; import { createFormatter, FormatterType } from '../../../lib/formatter'; -import { Issue, IssueOrigin, IssueSeverity } from '../../../lib/issue'; +import { Issue } from '../../../lib/issue'; -describe('[UNIT] formatter/FormatterFactory', () => { +describe('formatter/FormatterFactory', () => { beforeEach(() => { mockFs({ some: { @@ -13,9 +13,9 @@ describe('[UNIT] formatter/FormatterFactory', () => { ' constructor() {', " console.log('anything special');", ' }', - '}' - ].join('\n') - } + '}', + ].join('\n'), + }, }); }); @@ -24,22 +24,28 @@ describe('[UNIT] formatter/FormatterFactory', () => { }); const issue: Issue = { - origin: IssueOrigin.TYPESCRIPT, - severity: IssueSeverity.ERROR, - code: '123', + origin: 'typescript', + severity: 'error', + code: 'TS123', message: 'Some issue content', file: 'some/file.ts', - line: 1, - character: 7 + location: { + start: { + line: 1, + column: 7, + }, + end: { + line: 1, + column: 16, + }, + }, }; - it.each(['default', undefined])('creates default formatter', type => { + it.each(['basic', undefined])('creates basic formatter', (type) => { const formatter = createFormatter(type as FormatterType); const formattedMessage = formatter(issue); - expect(formattedMessage).toEqual( - ['ERROR in some/file.ts(1,7):', 'TS123: Some issue content'].join(os.EOL) - ); + expect(formattedMessage).toEqual('TS123: Some issue content'); }); it('creates codeframe formatter', () => { @@ -48,13 +54,12 @@ describe('[UNIT] formatter/FormatterFactory', () => { expect(formattedMessage).toEqual( [ - 'ERROR in some/file.ts(1,7):', - '1:7 Some issue content', + 'TS123: Some issue content', ' > 1 | class SomeClass {', - ' | ^', + ' | ^^^^^^^^^', ' 2 | private someProperty: boolean;', ' 3 | constructor() {', - " 4 | console.log('anything special');" + " 4 | console.log('anything special');", ].join(os.EOL) ); }); @@ -62,23 +67,22 @@ describe('[UNIT] formatter/FormatterFactory', () => { it('creates codeframe formatter with custom options', () => { const formatter = createFormatter('codeframe', { linesAbove: 1, - linesBelow: 1 + linesBelow: 1, }); const formattedMessage = formatter(issue); expect(formattedMessage).toEqual( [ - 'ERROR in some/file.ts(1,7):', - '1:7 Some issue content', + 'TS123: Some issue content', ' > 1 | class SomeClass {', - ' | ^', - ' 2 | private someProperty: boolean;' + ' | ^^^^^^^^^', + ' 2 | private someProperty: boolean;', ].join(os.EOL) ); }); it('forwards already created formatter', () => { - const formatter = createFormatter(issue => issue.message); + const formatter = createFormatter((issue) => issue.message); const formattedMessage = formatter(issue); expect(formattedMessage).toEqual('Some issue content'); @@ -87,7 +91,7 @@ describe('[UNIT] formatter/FormatterFactory', () => { it('throws an error on unknown formatter type', () => { // eslint-disable-next-line @typescript-eslint/no-explicit-any expect(() => createFormatter('unknown-type' as any)).toThrowError( - `Unknown "unknown-type" formatter. Available types are: default, codeframe.` + `Unknown "unknown-type" formatter. Available types are: basic, codeframe, Function.` ); }); }); diff --git a/test/unit/formatter/InternalFormatter.spec.ts b/test/unit/formatter/InternalFormatter.spec.ts deleted file mode 100644 index 8fd8a56d..00000000 --- a/test/unit/formatter/InternalFormatter.spec.ts +++ /dev/null @@ -1,66 +0,0 @@ -import * as os from 'os'; -import { Issue, IssueSeverity, IssueOrigin } from '../../../lib/issue'; -import { createInternalFormatter } from '../../../lib/formatter'; - -describe('[UNIT] formatter/InternalFormatter', () => { - it.each([ - [ - { - origin: IssueOrigin.INTERNAL, - severity: IssueSeverity.ERROR, - code: 'INTERNAL', - message: `Stack overflow - out of memory` - }, - 'INTERNAL ERROR: Stack overflow - out of memory' - ], - [ - { - origin: IssueOrigin.INTERNAL, - severity: IssueSeverity.ERROR, - code: 'INTERNAL', - message: `Stack overflow - out of memory`, - stack: [ - `Security context: 0x35903c44a49 `, - `1: walkFunctionDeclaration [/node_modules/webpack/lib/Parser.js:~443] [pc=0xa07a14ec8ee] (this=0x59f67991119 ,statement=0x3507a80af661 )`, - `2: walkStatement [/node_modules/webpack/lib/Parser.js:~348] [pc=0xa07a06dfc10] (this=0x59f6799111...`, - ``, - `FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory`, - `Abort trap: 6` - ].join(os.EOL) - }, - [ - 'INTERNAL ERROR: Stack overflow - out of memory', - 'stack trace:', - `Security context: 0x35903c44a49 `, - `1: walkFunctionDeclaration [/node_modules/webpack/lib/Parser.js:~443] [pc=0xa07a14ec8ee] (this=0x59f67991119 ,statement=0x3507a80af661 )`, - `2: walkStatement [/node_modules/webpack/lib/Parser.js:~348] [pc=0xa07a06dfc10] (this=0x59f6799111...`, - ``, - `FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory`, - `Abort trap: 6` - ].join(os.EOL) - ] - ])('formats issue message "%p" to "%p"', (...args) => { - const [issue, expectedFormatted] = args as [Issue, string]; - const formatter = createInternalFormatter(); - const formatted = formatter(issue); - - expect(formatted).toEqual(expectedFormatted); - }); - - it('throws an error on non-internal issue format', () => { - const formatter = createInternalFormatter(); - const issue = { - origin: IssueOrigin.TYPESCRIPT, - severity: IssueSeverity.ERROR, - code: '2322', - message: `Type '"1"' is not assignable to type 'number'.`, - file: 'src/index.ts', - line: 1, - character: 7 - }; - - expect(() => formatter(issue)).toThrowError( - `Not supported "${IssueOrigin.TYPESCRIPT}" issue origin.` - ); - }); -}); diff --git a/test/unit/formatter/RawFormatter.spec.ts b/test/unit/formatter/RawFormatter.spec.ts deleted file mode 100644 index df161a82..00000000 --- a/test/unit/formatter/RawFormatter.spec.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Issue, IssueOrigin, IssueSeverity } from '../../../lib/issue'; -import { createRawFormatter } from '../../../lib/formatter'; - -describe('[UNIT] formatter/RawFormatter', () => { - it.each([ - [ - { - origin: IssueOrigin.TYPESCRIPT, - severity: IssueSeverity.ERROR, - code: '2322', - message: `Type '"1"' is not assignable to type 'number'.`, - file: 'src/index.ts', - line: 1, - character: 7 - }, - `ERROR TS2322: Type '"1"' is not assignable to type 'number'.` - ], - [ - { - origin: IssueOrigin.ESLINT, - severity: IssueSeverity.WARNING, - code: 'no-unused-vars', - message: `'x' is assigned a value but never used.`, - file: 'src/index.ts', - line: 2, - character: 10 - }, - `WARNING no-unused-vars: 'x' is assigned a value but never used.` - ] - ])('formats issue message "%p" to "%p"', (...args) => { - const [issue, expectedFormatted] = args as [Issue, string]; - const formatter = createRawFormatter(); - const formatted = formatter(issue); - - expect(formatted).toEqual(expectedFormatted); - }); -}); diff --git a/test/unit/formatter/WebpackFormatter.spec.ts b/test/unit/formatter/WebpackFormatter.spec.ts new file mode 100644 index 00000000..24c5370a --- /dev/null +++ b/test/unit/formatter/WebpackFormatter.spec.ts @@ -0,0 +1,58 @@ +import os from 'os'; +import { Issue } from '../../../lib/issue'; +import { createBasicFormatter, createWebpackFormatter, Formatter } from '../../../lib/formatter'; + +describe('formatter/WebpackFormatter', () => { + const issue: Issue = { + origin: 'typescript', + severity: 'error', + code: 'TS123', + message: 'Some issue content', + file: 'some/file.ts', + location: { + start: { + line: 1, + column: 7, + }, + end: { + line: 1, + column: 16, + }, + }, + }; + + let formatter: Formatter; + + beforeEach(() => { + formatter = createWebpackFormatter(createBasicFormatter()); + }); + + it('decorates existing formatter', () => { + expect(formatter(issue)).toContain('TS123: Some issue content'); + }); + + it('formats issue severity', () => { + expect(formatter({ ...issue, severity: 'error' })).toContain('ERROR'); + expect(formatter({ ...issue, severity: 'warning' })).toContain('WARNING'); + }); + + it('formats issue file', () => { + expect(formatter(issue)).toContain('some/file.ts'); + }); + + it('formats location', () => { + expect(formatter(issue)).toContain('1:7-16'); + expect( + formatter({ + ...issue, + location: { start: { line: 1, column: 7 }, end: { line: 10, column: 16 } }, + }) + ).toContain('1:7-10:16'); + }); + + it('formats issue header like webpack', () => { + expect(formatter(issue)).toEqual( + ['ERROR in some/file.ts 1:7-16', 'TS123: Some issue content', ''].join(os.EOL) + ); + }); +}); diff --git a/test/unit/formatter/__mocks__/chalk.js b/test/unit/formatter/__mocks__/chalk.js index fe974613..1a9d37ea 100644 --- a/test/unit/formatter/__mocks__/chalk.js +++ b/test/unit/formatter/__mocks__/chalk.js @@ -12,7 +12,7 @@ const modifiers = [ 'inverse', 'hidden', 'strikethrough', - 'visible' + 'visible', ]; const colors = [ 'black', @@ -32,7 +32,7 @@ const colors = [ 'blueBright', 'magentaBright', 'cyanBright', - 'whiteBright' + 'whiteBright', ]; const bgColors = [ 'bgBlack', @@ -52,28 +52,19 @@ const bgColors = [ 'bgBlueBright', 'bgMagentaBright', 'bgCyanBright', - 'bgWhiteBright' -]; -const models = [ - 'rgb', - 'hex', - 'keyword', - 'hsl', - 'hsv', - 'hwb', - 'ansi', - 'ansi256' + 'bgWhiteBright', ]; +const models = ['rgb', 'hex', 'keyword', 'hsl', 'hsv', 'hwb', 'ansi', 'ansi256']; const styleMethods = [...modifiers, ...colors, ...bgColors]; const modelMethods = models; // register all style methods as a chain methods -styleMethods.forEach(method => { +styleMethods.forEach((method) => { style[method] = style; }); // register all model methods as a chain methods -modelMethods.forEach(method => { +modelMethods.forEach((method) => { style[method] = () => style; }); @@ -84,15 +75,15 @@ function Chalk() { level: 0, hasBasic: false, has256: false, - has16m: false + has16m: false, }; // register all style methods as a chalk API - styleMethods.forEach(method => { + styleMethods.forEach((method) => { this[method] = style; }); // register all model methods as a chalk API - modelMethods.forEach(method => { + modelMethods.forEach((method) => { this[method] = () => style; }); } diff --git a/test/unit/index.spec.ts b/test/unit/index.spec.ts deleted file mode 100644 index cfaea897..00000000 --- a/test/unit/index.spec.ts +++ /dev/null @@ -1,138 +0,0 @@ -/* eslint-disable @typescript-eslint/no-var-requires */ -import * as semver from 'semver'; - -describe('[UNIT] ForkTsCheckerWebpackPlugin', () => { - beforeEach(() => { - jest.resetModules(); - }); - - describe('typescript', () => { - it('should throw if typescript not present', () => { - jest.setMock('typescript', () => undefined); - const ForkTsCheckerWebpackPlugin = require('../../lib/index'); - - expect(function() { - new ForkTsCheckerWebpackPlugin(); - }).toThrowError(Error); - }); - - it('should not throw if typescript version >= 2.1.0', () => { - jest.setMock('typescript', { version: '2.1.0' }); - const ForkTsCheckerWebpackPlugin = require('../../lib/index'); - - expect(function() { - new ForkTsCheckerWebpackPlugin(); - }).not.toThrowError(); - }); - - it('should throw if typescript version < 2.1.0', () => { - jest.setMock('typescript', { version: '2.0.8' }); - const ForkTsCheckerWebpackPlugin = require('../../lib/index'); - - expect(function() { - new ForkTsCheckerWebpackPlugin(); - }).toThrowError(Error); - }); - }); - - describe('eslint', () => { - const ifNodeGte8It = semver.lt(process.version, '8.10.0') ? it.skip : it; - const ifNodeLt8It = semver.lt(process.version, '8.10.0') ? it : it.skip; - - it('should throw if eslint not present', () => { - jest.setMock('typescript', { version: '2.1.0' }); - jest.setMock('eslint', undefined); - const ForkTsCheckerWebpackPlugin = require('../../lib/index'); - - expect(function() { - new ForkTsCheckerWebpackPlugin({ eslint: true }); - }).toThrowError(Error); - }); - - ifNodeGte8It( - 'should not throw if eslint is present and Node.js version >= 8.10.0', - () => { - jest.setMock('typescript', { version: '2.1.0' }); - jest.setMock('eslint', { Linter: { VERSION: '5.7.0' } }); - const ForkTsCheckerWebpackPlugin = require('../../lib/index'); - - expect(function() { - new ForkTsCheckerWebpackPlugin({ eslint: true }); - }).not.toThrowError(); - } - ); - - ifNodeLt8It( - 'should throw if eslint is present and Node.js version < 8.10.0', - () => { - jest.setMock('typescript', { version: '2.1.0' }); - jest.setMock('eslint', { Linter: { VERSION: '5.7.0' } }); - const ForkTsCheckerWebpackPlugin = require('../../lib/index'); - - expect(function() { - new ForkTsCheckerWebpackPlugin({ eslint: true }); - }).toThrowError(); - } - ); - }); - - describe('useTypescriptIncrementalApi', () => { - it('should be true if useTypescriptIncrementalApi: true supplied', () => { - jest.setMock('typescript', { version: '2.1.0' }); - const ForkTsCheckerWebpackPlugin = require('../../lib/index'); - - expect( - new ForkTsCheckerWebpackPlugin({ useTypescriptIncrementalApi: true }) - .useTypescriptIncrementalApi - ).toBe(true); - }); - - it('should be true if useTypescriptIncrementalApi: false supplied', () => { - jest.setMock('typescript', { version: '3.0.0' }); - const ForkTsCheckerWebpackPlugin = require('../../lib/index'); - - expect( - new ForkTsCheckerWebpackPlugin({ useTypescriptIncrementalApi: false }) - .useTypescriptIncrementalApi - ).toBe(false); - }); - - it('should be false if useTypescriptIncrementalApi not supplied and typescript version < 3.0.0', () => { - jest.setMock('typescript', { version: '2.1.0' }); - const ForkTsCheckerWebpackPlugin = require('../../lib/index'); - - expect(new ForkTsCheckerWebpackPlugin().useTypescriptIncrementalApi).toBe( - false - ); - }); - - it('should be true if useTypescriptIncrementalApi not supplied and typescript version >= 3.0.0', () => { - jest.setMock('typescript', { version: '3.0.0' }); - const ForkTsCheckerWebpackPlugin = require('../../lib/index'); - - expect(new ForkTsCheckerWebpackPlugin().useTypescriptIncrementalApi).toBe( - true - ); - }); - - it('should be false if useTypescriptIncrementalApi not supplied and typescript version < 3.0.0 and vue is true', () => { - jest.setMock('typescript', { version: '2.1.0' }); - const ForkTsCheckerWebpackPlugin = require('../../lib/index'); - - expect( - new ForkTsCheckerWebpackPlugin({ vue: true }) - .useTypescriptIncrementalApi - ).toBe(false); - }); - - it('should be false if useTypescriptIncrementalApi not supplied and typescript version >= 3.0.0 and vue is true', () => { - jest.setMock('typescript', { version: '3.0.0' }); - const ForkTsCheckerWebpackPlugin = require('../../lib/index'); - - expect( - new ForkTsCheckerWebpackPlugin({ vue: true }) - .useTypescriptIncrementalApi - ).toBe(false); - }); - }); -}); diff --git a/test/unit/issue/Issue.spec.ts b/test/unit/issue/Issue.spec.ts index 09469303..ee17bdf6 100644 --- a/test/unit/issue/Issue.spec.ts +++ b/test/unit/issue/Issue.spec.ts @@ -1,47 +1,29 @@ -import { - IssueSeverity, - IssueOrigin, - isIssue, - deduplicateAndSortIssues, - Issue -} from '../../../lib/issue'; +import { isIssue, deduplicateAndSortIssues, Issue } from '../../../lib/issue'; -function omit( - object: TObject, - keys: (keyof TObject)[] -) { +function omit(object: TObject, keys: (keyof TObject)[]) { const omittedObject = Object.assign({}, object); - keys.forEach(key => delete omittedObject[key]); + keys.forEach((key) => delete omittedObject[key]); return omittedObject; } -describe('[UNIT] issue/Issue', () => { - const BASIC_INTERNAL_ISSUE = { - origin: IssueOrigin.INTERNAL, - severity: IssueSeverity.ERROR, - code: 'INTERNAL', - message: 'Out of memory' - }; +describe('issue/Issue', () => { const BASIC_TYPESCRIPT_ISSUE = { - origin: IssueOrigin.TYPESCRIPT, - severity: IssueSeverity.ERROR, - code: '4221', - message: 'Cannot assign string to the number type' + origin: 'typescript', + severity: 'error', + code: 'TS4221', + message: 'Cannot assign string to the number type', }; const BASIC_ESLINT_ISSUE = { - origin: IssueOrigin.ESLINT, - severity: IssueSeverity.ERROR, + origin: 'eslint', + severity: 'error', code: 'white-space', - message: 'Missing space between function brackets' + message: 'Missing space between function brackets', }; - it.each([BASIC_INTERNAL_ISSUE, BASIC_TYPESCRIPT_ISSUE, BASIC_ESLINT_ISSUE])( - "checks if '%p' is a Issue", - issue => { - expect(isIssue(issue)).toEqual(true); - } - ); + it.each([BASIC_TYPESCRIPT_ISSUE, BASIC_ESLINT_ISSUE])("checks if '%p' is a Issue", (issue) => { + expect(isIssue(issue)).toEqual(true); + }); it.each([ null, @@ -53,299 +35,276 @@ describe('[UNIT] issue/Issue', () => { new Date(), true, false, - omit(BASIC_INTERNAL_ISSUE, ['origin']), omit(BASIC_TYPESCRIPT_ISSUE, ['severity']), omit(BASIC_ESLINT_ISSUE, ['code']), - omit(BASIC_TYPESCRIPT_ISSUE, ['origin', 'message']) - ])("checks if '%p' isn't a Issue", issue => { + omit(BASIC_TYPESCRIPT_ISSUE, ['origin', 'message']), + ])("checks if '%p' isn't a Issue", (issue) => { expect(isIssue(issue)).toEqual(false); }); it.each([ [ // compare origin - [ - BASIC_ESLINT_ISSUE, - BASIC_TYPESCRIPT_ISSUE, - BASIC_ESLINT_ISSUE, - BASIC_INTERNAL_ISSUE, - BASIC_INTERNAL_ISSUE, - BASIC_ESLINT_ISSUE - ], - [BASIC_INTERNAL_ISSUE, BASIC_TYPESCRIPT_ISSUE, BASIC_ESLINT_ISSUE] + [BASIC_ESLINT_ISSUE, BASIC_TYPESCRIPT_ISSUE, BASIC_ESLINT_ISSUE, BASIC_ESLINT_ISSUE], + [BASIC_ESLINT_ISSUE, BASIC_TYPESCRIPT_ISSUE], ], [ // compare file [ { - ...BASIC_INTERNAL_ISSUE, - file: 'src/index.ts' + ...BASIC_TYPESCRIPT_ISSUE, + file: 'src/index.ts', }, - BASIC_INTERNAL_ISSUE, + BASIC_TYPESCRIPT_ISSUE, { - ...BASIC_INTERNAL_ISSUE, - file: 'src/different.ts' + ...BASIC_TYPESCRIPT_ISSUE, + file: 'src/different.ts', }, { - ...BASIC_INTERNAL_ISSUE, - file: 'src/another.ts' + ...BASIC_TYPESCRIPT_ISSUE, + file: 'src/another.ts', }, { - ...BASIC_INTERNAL_ISSUE, - file: 'src/different.ts' - } + ...BASIC_TYPESCRIPT_ISSUE, + file: 'src/different.ts', + }, ], [ - BASIC_INTERNAL_ISSUE, + BASIC_TYPESCRIPT_ISSUE, { - ...BASIC_INTERNAL_ISSUE, - file: 'src/another.ts' + ...BASIC_TYPESCRIPT_ISSUE, + file: 'src/another.ts', }, { - ...BASIC_INTERNAL_ISSUE, - file: 'src/different.ts' + ...BASIC_TYPESCRIPT_ISSUE, + file: 'src/different.ts', }, { - ...BASIC_INTERNAL_ISSUE, - file: 'src/index.ts' - } - ] + ...BASIC_TYPESCRIPT_ISSUE, + file: 'src/index.ts', + }, + ], ], [ // compare severity [ { ...BASIC_ESLINT_ISSUE, - severity: IssueSeverity.WARNING + severity: 'warning', }, { ...BASIC_ESLINT_ISSUE, - severity: IssueSeverity.ERROR + severity: 'error', }, { ...BASIC_ESLINT_ISSUE, - severity: IssueSeverity.WARNING - } + severity: 'warning', + }, ], [ { ...BASIC_ESLINT_ISSUE, - severity: IssueSeverity.ERROR + severity: 'error', }, { ...BASIC_ESLINT_ISSUE, - severity: IssueSeverity.WARNING - } - ] - ], - [ - // compare line - [ - { - ...BASIC_TYPESCRIPT_ISSUE, - line: 15 + severity: 'warning', }, - { - ...BASIC_TYPESCRIPT_ISSUE, - line: 5 - }, - BASIC_TYPESCRIPT_ISSUE, - { - ...BASIC_TYPESCRIPT_ISSUE, - line: 10 - }, - { - ...BASIC_TYPESCRIPT_ISSUE, - line: 10 - } ], - [ - BASIC_TYPESCRIPT_ISSUE, - { - ...BASIC_TYPESCRIPT_ISSUE, - line: 5 - }, - { - ...BASIC_TYPESCRIPT_ISSUE, - line: 10 - }, - { - ...BASIC_TYPESCRIPT_ISSUE, - line: 15 - } - ] ], [ - // compare character + // compare location [ { ...BASIC_TYPESCRIPT_ISSUE, - line: 10, - character: 3 + location: { + start: { + line: 10, + column: 3, + }, + end: { + line: 10, + column: 5, + }, + }, }, + BASIC_TYPESCRIPT_ISSUE, { ...BASIC_TYPESCRIPT_ISSUE, - line: 10 + location: { + start: { + line: 10, + column: 6, + }, + end: { + line: 10, + column: 9, + }, + }, }, { ...BASIC_TYPESCRIPT_ISSUE, - line: 10, - character: 6 + location: { + start: { + line: 10, + column: 6, + }, + end: { + line: 10, + column: 7, + }, + }, }, { ...BASIC_TYPESCRIPT_ISSUE, - line: 10, - character: 1 + location: { + start: { + line: 9, + column: 6, + }, + end: { + line: 10, + column: 7, + }, + }, }, - { - ...BASIC_TYPESCRIPT_ISSUE, - line: 10, - character: 6 - } ], [ + BASIC_TYPESCRIPT_ISSUE, { ...BASIC_TYPESCRIPT_ISSUE, - line: 10 + location: { + start: { + line: 9, + column: 6, + }, + end: { + line: 10, + column: 7, + }, + }, }, { ...BASIC_TYPESCRIPT_ISSUE, - line: 10, - character: 1 + location: { + start: { + line: 10, + column: 3, + }, + end: { + line: 10, + column: 5, + }, + }, }, { ...BASIC_TYPESCRIPT_ISSUE, - line: 10, - character: 3 + location: { + start: { + line: 10, + column: 6, + }, + end: { + line: 10, + column: 7, + }, + }, }, { ...BASIC_TYPESCRIPT_ISSUE, - line: 10, - character: 6 - } - ] + location: { + start: { + line: 10, + column: 6, + }, + end: { + line: 10, + column: 9, + }, + }, + }, + ], ], [ // compare code [ { ...BASIC_TYPESCRIPT_ISSUE, - code: '1500' + code: 'TS1500', }, { ...BASIC_TYPESCRIPT_ISSUE, - code: '1000' + code: 'TS1000', }, { ...BASIC_TYPESCRIPT_ISSUE, - code: '2000' + code: 'TS2000', }, { ...BASIC_TYPESCRIPT_ISSUE, - code: '1000' - } + code: 'TS1000', + }, ], [ { ...BASIC_TYPESCRIPT_ISSUE, - code: '1000' + code: 'TS1000', }, { ...BASIC_TYPESCRIPT_ISSUE, - code: '1500' + code: 'TS1500', }, { ...BASIC_TYPESCRIPT_ISSUE, - code: '2000' - } - ] + code: 'TS2000', + }, + ], ], [ // compare message [ { ...BASIC_TYPESCRIPT_ISSUE, - message: 'B' + message: 'B', }, { ...BASIC_TYPESCRIPT_ISSUE, - message: 'C' + message: 'C', }, { ...BASIC_TYPESCRIPT_ISSUE, - message: 'A' + message: 'A', }, { ...BASIC_TYPESCRIPT_ISSUE, - message: 'B' - } + message: 'B', + }, ], [ { ...BASIC_TYPESCRIPT_ISSUE, - message: 'A' + message: 'A', }, { ...BASIC_TYPESCRIPT_ISSUE, - message: 'B' + message: 'B', }, { ...BASIC_TYPESCRIPT_ISSUE, - message: 'C' - } - ] - ], - [ - // stack - [ - { - ...BASIC_INTERNAL_ISSUE, - stack: 'A' - }, - { - ...BASIC_INTERNAL_ISSUE, - stack: 'C' + message: 'C', }, - BASIC_INTERNAL_ISSUE, - { - ...BASIC_INTERNAL_ISSUE, - stack: 'A' - }, - { - ...BASIC_INTERNAL_ISSUE, - stack: 'B' - } ], - [ - BASIC_INTERNAL_ISSUE, - { - ...BASIC_INTERNAL_ISSUE, - stack: 'A' - }, - { - ...BASIC_INTERNAL_ISSUE, - stack: 'B' - }, - { - ...BASIC_INTERNAL_ISSUE, - stack: 'C' - } - ] ], [ // empty [], - [] + [], ], [ - [ - BASIC_ESLINT_ISSUE, - omit(BASIC_ESLINT_ISSUE, ['message']), - BASIC_ESLINT_ISSUE - ], - [BASIC_ESLINT_ISSUE] + [BASIC_ESLINT_ISSUE, omit(BASIC_ESLINT_ISSUE, ['message']), BASIC_ESLINT_ISSUE], + [BASIC_ESLINT_ISSUE], ], - [[omit(BASIC_ESLINT_ISSUE, ['message'])], []] + [[omit(BASIC_ESLINT_ISSUE, ['message'])], []], ])('deduplicates issues %p to %p', (...args) => { const [issues, deduplicatedIssues] = args as [Issue[], Issue[]]; expect(deduplicateAndSortIssues(issues)).toEqual(deduplicatedIssues); diff --git a/test/unit/issue/IssueOrigin.spec.ts b/test/unit/issue/IssueOrigin.spec.ts deleted file mode 100644 index 96d06efb..00000000 --- a/test/unit/issue/IssueOrigin.spec.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { - IssueOrigin, - isIssueOrigin, - compareIssueOrigins -} from '../../../lib/issue'; - -describe('[UNIT] issue/IssueOrigin', () => { - it('defines issue origin enum', () => { - expect(IssueOrigin).toMatchSnapshot(); - }); - - it.each([IssueOrigin.INTERNAL, IssueOrigin.TYPESCRIPT, IssueOrigin.ESLINT])( - "checks if '%p' is a IssueOrigin", - origin => { - expect(isIssueOrigin(origin)).toEqual(true); - } - ); - - it.each([null, undefined, '', 'test', 1, {}, new Date(), true, false])( - "checks if '%p' isn't a IssueOrigin", - origin => { - expect(isIssueOrigin(origin)).toEqual(false); - } - ); - - it.each([ - // INTERNAL - [IssueOrigin.INTERNAL, IssueOrigin.INTERNAL, 0], - [IssueOrigin.INTERNAL, IssueOrigin.TYPESCRIPT, -1], - [IssueOrigin.INTERNAL, IssueOrigin.ESLINT, -1], - - // TYPESCRIPT - [IssueOrigin.TYPESCRIPT, IssueOrigin.INTERNAL, 1], - [IssueOrigin.TYPESCRIPT, IssueOrigin.TYPESCRIPT, 0], - [IssueOrigin.TYPESCRIPT, IssueOrigin.ESLINT, -1], - - // ESLINT - [IssueOrigin.ESLINT, IssueOrigin.INTERNAL, 1], - [IssueOrigin.ESLINT, IssueOrigin.TYPESCRIPT, 1], - [IssueOrigin.ESLINT, IssueOrigin.ESLINT, 0] - ])("compares issue origin '%p' with '%p' and returns '%p'", (...args) => { - const [originA, originB, result] = args as [ - IssueOrigin, - IssueOrigin, - number - ]; - expect(compareIssueOrigins(originA, originB)).toEqual(result); - }); -}); diff --git a/test/unit/issue/IssueSeverity.spec.ts b/test/unit/issue/IssueSeverity.spec.ts deleted file mode 100644 index 9f4ba0f8..00000000 --- a/test/unit/issue/IssueSeverity.spec.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { - IssueSeverity, - isIssueSeverity, - compareIssueSeverities -} from '../../../lib/issue'; - -describe('[UNIT] issue/IssueSeverity', () => { - it('defines issue severity enum', () => { - expect(IssueSeverity).toMatchSnapshot(); - }); - - it.each([IssueSeverity.ERROR, IssueSeverity.WARNING])( - "checks if '%p' is a IssueSeverity", - severity => { - expect(isIssueSeverity(severity)).toEqual(true); - } - ); - - it.each([null, undefined, '', 'test', 1, {}, new Date(), true, false])( - "checks if '%p' isn't a IssueSeverity", - severity => { - expect(isIssueSeverity(severity)).toEqual(false); - } - ); - - it.each([ - // ERROR - [IssueSeverity.ERROR, IssueSeverity.ERROR, 0], - [IssueSeverity.ERROR, IssueSeverity.WARNING, -1], - - // WARNING - [IssueSeverity.WARNING, IssueSeverity.ERROR, 1], - [IssueSeverity.WARNING, IssueSeverity.WARNING, 0] - ])("compares issue severity '%p' with '%p' and returns '%p'", (...args) => { - const [severityA, severityB, result] = args as [ - IssueSeverity, - IssueSeverity, - number - ]; - expect(compareIssueSeverities(severityA, severityB)).toEqual(result); - }); -}); diff --git a/test/unit/issue/__snapshots__/IssueOrigin.spec.ts.snap b/test/unit/issue/__snapshots__/IssueOrigin.spec.ts.snap deleted file mode 100644 index 6f798fde..00000000 --- a/test/unit/issue/__snapshots__/IssueOrigin.spec.ts.snap +++ /dev/null @@ -1,9 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`[UNIT] issue/IssueOrigin defines issue origin enum 1`] = ` -Object { - "ESLINT": "eslint", - "INTERNAL": "internal", - "TYPESCRIPT": "typescript", -} -`; diff --git a/test/unit/issue/__snapshots__/IssueSeverity.spec.ts.snap b/test/unit/issue/__snapshots__/IssueSeverity.spec.ts.snap deleted file mode 100644 index bbdaf90d..00000000 --- a/test/unit/issue/__snapshots__/IssueSeverity.spec.ts.snap +++ /dev/null @@ -1,8 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`[UNIT] issue/IssueSeverity defines issue severity enum 1`] = ` -Object { - "ERROR": "error", - "WARNING": "warning", -} -`; diff --git a/test/unit/issue/eslint/__snapshots__/EsLintIssueFactory.spec.ts.snap b/test/unit/issue/eslint/__snapshots__/EsLintIssueFactory.spec.ts.snap deleted file mode 100644 index 75d35833..00000000 --- a/test/unit/issue/eslint/__snapshots__/EsLintIssueFactory.spec.ts.snap +++ /dev/null @@ -1,33 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`[UNIT] issue/eslint/EsLintIssueFactory creates Issues from EsLint Reports: [[Object], [Object]] 1`] = ` -Array [ - Object { - "character": 0, - "code": "no-unused-vars", - "file": "src/additional.ts", - "line": 13, - "message": "'y' is assigned a value but never used.", - "origin": "eslint", - "severity": "error", - }, - Object { - "character": 10, - "code": "no-unused-vars", - "file": "src/another.ts", - "line": 15, - "message": "'y' is assigned a value but never used.", - "origin": "eslint", - "severity": "warning", - }, - Object { - "character": 0, - "code": "no-unused-vars", - "file": "src/index.ts", - "line": 13, - "message": "'y' is assigned a value but never used.", - "origin": "eslint", - "severity": "error", - }, -] -`; diff --git a/test/unit/issue/internal/InternalIssueFactory.spec.ts b/test/unit/issue/internal/InternalIssueFactory.spec.ts deleted file mode 100644 index 99c9eec4..00000000 --- a/test/unit/issue/internal/InternalIssueFactory.spec.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { createIssueFromInternalError } from '../../../../lib/issue'; - -describe('[UNIT] issue/internal/InternalIssueFactory', () => { - const ERROR_WITH_MESSAGE_AND_STACK = { - message: 'Stack overflow - out of memory', - stack: [ - `Security context: 0x35903c44a49 `, - `1: walkFunctionDeclaration [/node_modules/webpack/lib/Parser.js:~443] [pc=0xa07a14ec8ee] (this=0x59f67991119 ,statement=0x3507a80af661 )`, - `2: walkStatement [/node_modules/webpack/lib/Parser.js:~348] [pc=0xa07a06dfc10] (this=0x59f6799111...`, - ``, - `FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory`, - `Abort trap: 6` - ].join('\n') - }; - const ERROR_WITHOUT_MESSAGE_AND_STACK = { - toString() { - return 'Error: Stack overflow - out of memory'; - } - }; - - it.each([[ERROR_WITH_MESSAGE_AND_STACK], [ERROR_WITHOUT_MESSAGE_AND_STACK]])( - 'creates Issue from Internal Error: %p', - error => { - const issue = createIssueFromInternalError(error); - - expect(issue).toMatchSnapshot(); - } - ); -}); diff --git a/test/unit/issue/internal/__snapshots__/InternalIssueFactory.spec.ts.snap b/test/unit/issue/internal/__snapshots__/InternalIssueFactory.spec.ts.snap deleted file mode 100644 index a146c701..00000000 --- a/test/unit/issue/internal/__snapshots__/InternalIssueFactory.spec.ts.snap +++ /dev/null @@ -1,31 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`[UNIT] issue/internal/InternalIssueFactory creates Issue from Internal Error: {"message": "Stack overflow - out of memory", "stack": "Security context: 0x35903c44a49 -1: walkFunctionDeclaration [/node_modules/webpack/lib/Parser.js:~443] [pc=0xa07a14ec8ee] (this=0x59f67991119 ,statement=0x3507a80af661 ) -2: walkStatement [/node_modules/webpack/lib/Parser.js:~348] [pc=0xa07a06dfc10] (this=0x59f6799111... - -FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory -Abort trap: 6"} 1`] = ` -Object { - "code": "INTERNAL", - "message": "Stack overflow - out of memory", - "origin": "internal", - "severity": "error", - "stack": "Security context: 0x35903c44a49 -1: walkFunctionDeclaration [/node_modules/webpack/lib/Parser.js:~443] [pc=0xa07a14ec8ee] (this=0x59f67991119 ,statement=0x3507a80af661 ) -2: walkStatement [/node_modules/webpack/lib/Parser.js:~348] [pc=0xa07a06dfc10] (this=0x59f6799111... - -FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory -Abort trap: 6", -} -`; - -exports[`[UNIT] issue/internal/InternalIssueFactory creates Issue from Internal Error: {"toString": [Function toString]} 1`] = ` -Object { - "code": "INTERNAL", - "message": "Error: Stack overflow - out of memory", - "origin": "internal", - "severity": "error", - "stack": undefined, -} -`; diff --git a/test/unit/issue/typescript/TypeScriptIssueFactory.spec.ts b/test/unit/issue/typescript/TypeScriptIssueFactory.spec.ts deleted file mode 100644 index 9a3fa575..00000000 --- a/test/unit/issue/typescript/TypeScriptIssueFactory.spec.ts +++ /dev/null @@ -1,129 +0,0 @@ -import { - createIssueFromTsDiagnostic, - createIssuesFromTsDiagnostics -} from '../../../../lib/issue'; -import * as ts from 'typescript'; - -function makeDiagnosticMessageChainTestCase(): ts.Diagnostic { - const version: number = Number.parseFloat(ts.versionMajorMinor); - if (version <= 3.5) { - return ({ - start: 12, - code: 1221, - category: 0, - length: 3, - file: undefined, - messageText: { - messageText: 'Cannot assign object to the string type', - category: 0, - code: 1221, - next: { - messageText: 'Another ident message', - category: 0, - code: 1221, - next: { - messageText: 'The most ident message', - category: 0, - code: 1221 - } - } - } - } as unknown) as ts.Diagnostic; - } else { - // newer versions of typescript have the |next| property as an array - return ({ - start: 12, - code: 1221, - category: 0, - length: 3, - file: undefined, - messageText: { - messageText: 'Cannot assign object to the string type', - category: 0, - code: 1221, - next: [ - { - messageText: 'Another ident message', - category: 0, - code: 1221, - next: [ - { - messageText: 'The most ident message', - category: 0, - code: 1221 - } - ] - } - ] - } - } as unknown) as ts.Diagnostic; - } -} - -describe('[UNIT] issue/typescript/TypeScriptIssueFactory', () => { - const TS_DIAGNOSTIC_WARNING: ts.Diagnostic = { - start: 100, - code: 4221, - category: 1, - messageText: 'Cannot assign string to the number type', - length: 1, - file: { - fileName: 'src/test.ts', - getLineAndCharacterOfPosition: () => ({ - line: 2, - character: 2 - }) - // eslint-disable-next-line @typescript-eslint/no-explicit-any - } as any - }; - const TS_DIAGNOSTIC_ERROR: ts.Diagnostic = { - start: 12, - code: 1221, - category: 0, - messageText: 'Cannot assign object to the string type', - length: 1, - file: { - fileName: 'src/index.ts', - getLineAndCharacterOfPosition: () => ({ - line: 5, - character: 10 - }) - // eslint-disable-next-line @typescript-eslint/no-explicit-any - } as any - }; - const TS_DIAGNOSTIC_WITHOUT_FILE: ts.Diagnostic = { - start: 12, - code: 1221, - category: 0, - length: 1, - messageText: 'Cannot assign object to the string type', - file: undefined - }; - const TS_DIAGNOSTIC_MESSAGE_CHAIN: ts.Diagnostic = makeDiagnosticMessageChainTestCase(); - - it.each([ - [TS_DIAGNOSTIC_WARNING], - [TS_DIAGNOSTIC_ERROR], - [TS_DIAGNOSTIC_WITHOUT_FILE], - [TS_DIAGNOSTIC_MESSAGE_CHAIN] - ])('creates Issue from TsDiagnostic: %p', tsDiagnostic => { - const issue = createIssueFromTsDiagnostic(tsDiagnostic, ts); - - expect(issue).toMatchSnapshot(); - }); - - it.each([ - [ - [ - TS_DIAGNOSTIC_WARNING, - TS_DIAGNOSTIC_ERROR, - TS_DIAGNOSTIC_WITHOUT_FILE, - TS_DIAGNOSTIC_MESSAGE_CHAIN - ] - ] - ])('creates Issues from TsDiagnostics: %p', tsDiagnostics => { - const issues = createIssuesFromTsDiagnostics(tsDiagnostics, ts); - - expect(issues).toMatchSnapshot(); - }); -}); diff --git a/test/unit/issue/typescript/__snapshots__/TypeScriptIssueFactory.spec.ts.snap b/test/unit/issue/typescript/__snapshots__/TypeScriptIssueFactory.spec.ts.snap deleted file mode 100644 index 92c544d4..00000000 --- a/test/unit/issue/typescript/__snapshots__/TypeScriptIssueFactory.spec.ts.snap +++ /dev/null @@ -1,94 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`[UNIT] issue/typescript/TypeScriptIssueFactory creates Issue from TsDiagnostic: {"category": 0, "code": 1221, "file": [Object], "length": 1, "messageText": "Cannot assign object to the string type", "start": 12} 1`] = ` -Object { - "character": 11, - "code": "1221", - "file": "src/index.ts", - "line": 6, - "message": "Cannot assign object to the string type", - "origin": "typescript", - "severity": "warning", -} -`; - -exports[`[UNIT] issue/typescript/TypeScriptIssueFactory creates Issue from TsDiagnostic: {"category": 0, "code": 1221, "file": undefined, "length": 1, "messageText": "Cannot assign object to the string type", "start": 12} 1`] = ` -Object { - "character": undefined, - "code": "1221", - "file": undefined, - "line": undefined, - "message": "Cannot assign object to the string type", - "origin": "typescript", - "severity": "warning", -} -`; - -exports[`[UNIT] issue/typescript/TypeScriptIssueFactory creates Issue from TsDiagnostic: {"category": 0, "code": 1221, "file": undefined, "length": 3, "messageText": [Object], "start": 12} 1`] = ` -Object { - "character": undefined, - "code": "1221", - "file": undefined, - "line": undefined, - "message": "Cannot assign object to the string type - Another ident message - The most ident message", - "origin": "typescript", - "severity": "warning", -} -`; - -exports[`[UNIT] issue/typescript/TypeScriptIssueFactory creates Issue from TsDiagnostic: {"category": 1, "code": 4221, "file": [Object], "length": 1, "messageText": "Cannot assign string to the number type", "start": 100} 1`] = ` -Object { - "character": 3, - "code": "4221", - "file": "src/test.ts", - "line": 3, - "message": "Cannot assign string to the number type", - "origin": "typescript", - "severity": "error", -} -`; - -exports[`[UNIT] issue/typescript/TypeScriptIssueFactory creates Issues from TsDiagnostics: [[Object], [Object], [Object], [Object]] 1`] = ` -Array [ - Object { - "character": undefined, - "code": "1221", - "file": undefined, - "line": undefined, - "message": "Cannot assign object to the string type", - "origin": "typescript", - "severity": "warning", - }, - Object { - "character": undefined, - "code": "1221", - "file": undefined, - "line": undefined, - "message": "Cannot assign object to the string type - Another ident message - The most ident message", - "origin": "typescript", - "severity": "warning", - }, - Object { - "character": 11, - "code": "1221", - "file": "src/index.ts", - "line": 6, - "message": "Cannot assign object to the string type", - "origin": "typescript", - "severity": "warning", - }, - Object { - "character": 3, - "code": "4221", - "file": "src/test.ts", - "line": 3, - "message": "Cannot assign string to the number type", - "origin": "typescript", - "severity": "error", - }, -] -`; \ No newline at end of file diff --git a/test/unit/typescript-reporter/issue/TypeScriptIssueFactory.spec.ts b/test/unit/typescript-reporter/issue/TypeScriptIssueFactory.spec.ts new file mode 100644 index 00000000..f2e489f9 --- /dev/null +++ b/test/unit/typescript-reporter/issue/TypeScriptIssueFactory.spec.ts @@ -0,0 +1,50 @@ +import * as ts from 'typescript'; +import { createIssuesFromTsDiagnostics } from '../../../../lib/typescript-reporter/issue/TypeScriptIssueFactory'; + +describe('typescript-reporter/issue/TypeScriptIssueFactory', () => { + const TS_DIAGNOSTIC_WARNING = { + start: 100, + code: 4221, + category: 1, + messageText: 'Cannot assign string to the number type', + length: 5, + file: { + fileName: 'src/test.ts', + getLineAndCharacterOfPosition: (position: number) => ({ + line: 2, + character: 2 + Math.max(0, position - 100), + }), + }, + }; + const TS_DIAGNOSTIC_ERROR = { + start: 12, + code: 1221, + category: 0, + messageText: 'Cannot assign object to the string type', + length: 1, + file: { + fileName: 'src/index.ts', + getLineAndCharacterOfPosition: (position: number) => ({ + line: 5 + Math.max(0, position - 12), + character: 10 + Math.max(0, position - 12), + }), + }, + }; + const TS_DIAGNOSTIC_WITHOUT_FILE = { + start: 12, + code: 1221, + category: 0, + length: 4, + messageText: 'Cannot assign object to the string type', + file: undefined, + }; + + it.each([[[TS_DIAGNOSTIC_WARNING, TS_DIAGNOSTIC_ERROR, TS_DIAGNOSTIC_WITHOUT_FILE]]])( + 'creates Issues from TsDiagnostics: %p', + (tsDiagnostics) => { + const issues = createIssuesFromTsDiagnostics(tsDiagnostics as ts.Diagnostic[]); + + expect(issues).toMatchSnapshot(); + } + ); +}); diff --git a/test/unit/typescript-reporter/issue/__snapshots__/TypeScriptIssueFactory.spec.ts.snap b/test/unit/typescript-reporter/issue/__snapshots__/TypeScriptIssueFactory.spec.ts.snap new file mode 100644 index 00000000..3bd4f615 --- /dev/null +++ b/test/unit/typescript-reporter/issue/__snapshots__/TypeScriptIssueFactory.spec.ts.snap @@ -0,0 +1,48 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`typescript-reporter/issue/TypeScriptIssueFactory creates Issues from TsDiagnostics: [[Object], [Object], [Object]] 1`] = ` +Array [ + Object { + "code": "TS4221", + "file": "src/test.ts", + "location": Object { + "end": Object { + "column": 8, + "line": 3, + }, + "start": Object { + "column": 3, + "line": 3, + }, + }, + "message": "Cannot assign string to the number type", + "origin": "typescript", + "severity": "error", + }, + Object { + "code": "TS1221", + "file": undefined, + "location": undefined, + "message": "Cannot assign object to the string type", + "origin": "typescript", + "severity": "warning", + }, + Object { + "code": "TS1221", + "file": "src/index.ts", + "location": Object { + "end": Object { + "column": 12, + "line": 7, + }, + "start": Object { + "column": 11, + "line": 6, + }, + }, + "message": "Cannot assign object to the string type", + "origin": "typescript", + "severity": "warning", + }, +] +`; From 2ae85ef53e3d082e1ff7d998fd0b5c6cbef123d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ole=C5=9B?= Date: Mon, 20 Apr 2020 18:55:06 +0200 Subject: [PATCH 09/29] chore: change typescript version from 2.7.0 to 2.7.1 In the CI test matrix I had to change typescript version to 2.7.1 because 2.7.0 is not published on the npm --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 843c0732..4cd176e2 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -43,7 +43,7 @@ jobs: # test different typescript versions - os: ubuntu-latest node: 12 - packages: typescript@2.7.0 webpack@^4.0.0 ts-loader@5.0.0 vue-loader@15.2.0 + packages: typescript@2.7.1 webpack@^4.0.0 ts-loader@5.0.0 vue-loader@15.2.0 - os: ubuntu-latest node: 12 From b4e92daff6f6a616bc5bba7b9e615d870ca12793 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ole=C5=9B?= Date: Mon, 20 Apr 2020 19:16:44 +0200 Subject: [PATCH 10/29] test: modify tests to be able to run them on typescript 2.7.1 --- jest.config.js | 7 ++++++- test/json.d.ts | 4 ++++ test/tsconfig.json | 13 +++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 test/json.d.ts create mode 100644 test/tsconfig.json diff --git a/jest.config.js b/jest.config.js index 83d20440..bc7d1d82 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,5 +1,10 @@ module.exports = { preset: 'ts-jest', testEnvironment: 'node', - setupFilesAfterEnv: ['./test/setup.ts'] + setupFilesAfterEnv: ['./test/setup.ts'], + globals: { + 'ts-jest': { + tsConfig: './test/tsconfig.json' + }, + }, }; diff --git a/test/json.d.ts b/test/json.d.ts new file mode 100644 index 00000000..bbab69d2 --- /dev/null +++ b/test/json.d.ts @@ -0,0 +1,4 @@ +declare module '*.json' { + const value: any; + export default value; +} diff --git a/test/tsconfig.json b/test/tsconfig.json new file mode 100644 index 00000000..e5d93331 --- /dev/null +++ b/test/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "target": "es6", + "module": "commonjs", + "lib": ["ES6"], + "moduleResolution": "node", + "esModuleInterop": true, + "skipLibCheck": true, + "skipDefaultLibCheck": true, + "baseUrl": "../src" + }, + "include": ["../src", "."] +} From d10853b5a2e36b2cfa0d5b49ca55685b9fbe121e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ole=C5=9B?= Date: Mon, 20 Apr 2020 19:22:56 +0200 Subject: [PATCH 11/29] chore: select patch version instead of major for typescript --- .github/workflows/main.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4cd176e2..3bf928b2 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -47,11 +47,11 @@ jobs: - os: ubuntu-latest node: 12 - packages: typescript@^3.0.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 + packages: typescript@~3.0.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 - os: ubuntu-latest node: 12 - packages: typescript@^3.6.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 + packages: typescript@~3.6.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 - os: ubuntu-latest node: 12 @@ -66,37 +66,37 @@ jobs: # macos - os: macos-latest node: 8 - packages: typescript@^3.6.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 + packages: typescript@~3.6.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 - os: macos-latest node: 10 - packages: typescript@^3.6.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 + packages: typescript@~3.6.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 - os: macos-latest node: 12 - packages: typescript@^3.6.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 + packages: typescript@~3.6.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 # windows - os: windows-latest node: 8 - packages: typescript@^3.6.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 + packages: typescript@~3.6.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 - os: windows-latest node: 10 - packages: typescript@^3.6.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 + packages: typescript@~3.6.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 - os: windows-latest node: 12 - packages: typescript@^3.6.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 + packages: typescript@~3.6.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 # ubuntu - os: ubuntu-latest node: 8 - packages: typescript@^3.6.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 + packages: typescript@~3.6.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 - os: ubuntu-latest node: 10 - packages: typescript@^3.6.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 + packages: typescript@~3.6.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 steps: - uses: actions/checkout@v1 From 9336dd0690c357db995b4967d828cc14cb6f2685 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ole=C5=9B?= Date: Tue, 21 Apr 2020 21:25:10 +0200 Subject: [PATCH 12/29] test: add test and codeclimate configuration --- .eslintrc.js | 6 + .github/workflows/main.yml | 38 +++++ src/ForkTsCheckerWebpackPlugin.ts | 2 +- ...eScriptSupport.ts => TypeScriptSupport.ts} | 14 +- ...rt.ts => TypeScriptPnpExtensionSupport.ts} | 4 +- ...rt.ts => TypeScriptVueExtensionSupport.ts} | 4 +- .../TypeScriptSupport.spec.ts | 152 ++++++++++++++++++ 7 files changed, 209 insertions(+), 11 deletions(-) rename src/typescript-reporter/{assertTypeScriptSupport.ts => TypeScriptSupport.ts} (81%) rename src/typescript-reporter/extension/pnp/{assertPnpSupport.ts => TypeScriptPnpExtensionSupport.ts} (71%) rename src/typescript-reporter/extension/vue/{assertVueSupport.ts => TypeScriptVueExtensionSupport.ts} (81%) create mode 100644 test/unit/typescript-reporter/TypeScriptSupport.spec.ts diff --git a/.eslintrc.js b/.eslintrc.js index 3307a73c..baba041d 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -22,6 +22,12 @@ module.exports = { '@typescript-eslint/no-use-before-define': 'off', 'node/no-unsupported-features/es-syntax': 'off' } + }, + { + files: ['*.spec.ts'], + rules: { + '@typescript-eslint/no-var-requires': 'off' + } } ] }; diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3bf928b2..bf9404cb 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -133,6 +133,44 @@ jobs: # TODO: uncomment, when integration tests will work again # - name: Run integration tests # run: yarn test:integration + + coverage: + runs-on: ubuntu-latest + needs: test + steps: + - uses: actions/checkout@v1 + + - name: Setup node + uses: actions/setup-node@v1 + with: + node-version: 12 + + - name: Get yarn cache + id: yarn-cache + run: echo "::set-output name=dir::$(yarn cache dir)" + + - uses: actions/cache@v1 + with: + path: ${{ steps.yarn-cache.outputs.dir }} + key: ${{ runner.os }}-node-${{ matrix.node }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-node-${{ matrix.node }}-yarn- + + - name: Install dependencies + run: yarn install --frozen-lockfile + + - name: Download build artifact + uses: actions/download-artifact@v1 + with: + name: lib + + - name: Test & publish code coverage + uses: paambaati/codeclimate-action@v2.5.7 + env: + CC_TEST_REPORTER_ID: 49901d62e1528b4c2379a4618254376692e87b2e9a749b94bcc4c17daab1ca4f + with: + coverageCommand: yarn test:unit --coverage + debug: true release: runs-on: ubuntu-latest diff --git a/src/ForkTsCheckerWebpackPlugin.ts b/src/ForkTsCheckerWebpackPlugin.ts index 208959e6..99f038a8 100644 --- a/src/ForkTsCheckerWebpackPlugin.ts +++ b/src/ForkTsCheckerWebpackPlugin.ts @@ -5,7 +5,7 @@ import { ForkTsCheckerWebpackPluginOptions } from './ForkTsCheckerWebpackPluginO import { createForkTsCheckerWebpackPluginConfiguration } from './ForkTsCheckerWebpackPluginConfiguration'; import { createForkTsCheckerWebpackPluginState } from './ForkTsCheckerWebpackPluginState'; import { composeReporterRpcClients, createAggregatedReporter, ReporterRpcClient } from './reporter'; -import { assertTypeScriptSupport } from './typescript-reporter/assertTypeScriptSupport'; +import { assertTypeScriptSupport } from './typescript-reporter/TypeScriptSupport'; import { createTypeScriptReporterRpcClient } from './typescript-reporter/reporter/TypeScriptReporterRpcClient'; import { assertEsLintSupport } from './eslint-reporter/assertEsLintSupport'; import { createEsLintReporterRpcClient } from './eslint-reporter/reporter/EsLintReporterRpcClient'; diff --git a/src/typescript-reporter/assertTypeScriptSupport.ts b/src/typescript-reporter/TypeScriptSupport.ts similarity index 81% rename from src/typescript-reporter/assertTypeScriptSupport.ts rename to src/typescript-reporter/TypeScriptSupport.ts index a96beb56..e0e81c8d 100644 --- a/src/typescript-reporter/assertTypeScriptSupport.ts +++ b/src/typescript-reporter/TypeScriptSupport.ts @@ -2,15 +2,17 @@ import * as semver from 'semver'; import * as fs from 'graceful-fs'; import * as os from 'os'; import { TypeScriptReporterConfiguration } from './TypeScriptReporterConfiguration'; -import { assertPnpSupport } from './extension/pnp/assertPnpSupport'; -import { assertVueSupport } from './extension/vue/assertVueSupport'; +import { assertTypeScriptPnpExtensionSupport } from './extension/pnp/TypeScriptPnpExtensionSupport'; +import { assertTypeScriptVueExtensionSupport } from './extension/vue/TypeScriptVueExtensionSupport'; function assertTypeScriptSupport(configuration: TypeScriptReporterConfiguration) { - let typescriptVersion: string; + let typescriptVersion: string | undefined; try { typescriptVersion = require('typescript').version; - } catch (error) { + } catch (error) {} + + if (!typescriptVersion) { throw new Error( 'When you use ForkTsCheckerWebpackPlugin with typescript reporter enabled, you must install `typescript` package.' ); @@ -48,11 +50,11 @@ function assertTypeScriptSupport(configuration: TypeScriptReporterConfiguration) } if (configuration.extensions.vue.enabled) { - assertVueSupport(configuration.extensions.vue); + assertTypeScriptVueExtensionSupport(configuration.extensions.vue); } if (configuration.extensions.pnp.enabled) { - assertPnpSupport(); + assertTypeScriptPnpExtensionSupport(); } } diff --git a/src/typescript-reporter/extension/pnp/assertPnpSupport.ts b/src/typescript-reporter/extension/pnp/TypeScriptPnpExtensionSupport.ts similarity index 71% rename from src/typescript-reporter/extension/pnp/assertPnpSupport.ts rename to src/typescript-reporter/extension/pnp/TypeScriptPnpExtensionSupport.ts index af99b047..070ed93f 100644 --- a/src/typescript-reporter/extension/pnp/assertPnpSupport.ts +++ b/src/typescript-reporter/extension/pnp/TypeScriptPnpExtensionSupport.ts @@ -1,4 +1,4 @@ -function assertPnpSupport() { +function assertTypeScriptPnpExtensionSupport() { try { // eslint-disable-next-line node/no-missing-require require('ts-pnp'); @@ -9,4 +9,4 @@ function assertPnpSupport() { } } -export { assertPnpSupport }; +export { assertTypeScriptPnpExtensionSupport }; diff --git a/src/typescript-reporter/extension/vue/assertVueSupport.ts b/src/typescript-reporter/extension/vue/TypeScriptVueExtensionSupport.ts similarity index 81% rename from src/typescript-reporter/extension/vue/assertVueSupport.ts rename to src/typescript-reporter/extension/vue/TypeScriptVueExtensionSupport.ts index 966127da..8940fbcf 100644 --- a/src/typescript-reporter/extension/vue/assertVueSupport.ts +++ b/src/typescript-reporter/extension/vue/TypeScriptVueExtensionSupport.ts @@ -1,6 +1,6 @@ import { TypeScriptVueExtensionConfiguration } from './TypeScriptVueExtensionConfiguration'; -function assertVueSupport(configuration: TypeScriptVueExtensionConfiguration) { +function assertTypeScriptVueExtensionSupport(configuration: TypeScriptVueExtensionConfiguration) { // We need to import template compiler for vue lazily because it cannot be included it // as direct dependency because it is an optional dependency of fork-ts-checker-webpack-plugin. // Since its version must not mismatch with user-installed Vue.js, @@ -14,4 +14,4 @@ function assertVueSupport(configuration: TypeScriptVueExtensionConfiguration) { } } -export { assertVueSupport }; +export { assertTypeScriptVueExtensionSupport }; diff --git a/test/unit/typescript-reporter/TypeScriptSupport.spec.ts b/test/unit/typescript-reporter/TypeScriptSupport.spec.ts new file mode 100644 index 00000000..440c7115 --- /dev/null +++ b/test/unit/typescript-reporter/TypeScriptSupport.spec.ts @@ -0,0 +1,152 @@ +import { TypeScriptReporterConfiguration } from '../../../lib/typescript-reporter/TypeScriptReporterConfiguration'; +import os from 'os'; + +describe('typescript-reporter/TypeScriptSupport', () => { + let configuration: TypeScriptReporterConfiguration; + + beforeEach(() => { + jest.resetModules(); + + configuration = { + tsconfig: './tsconfig.json', + compilerOptions: {}, + build: false, + diagnosticOptions: { + declaration: false, + global: true, + semantic: true, + syntactic: false, + }, + enabled: true, + extensions: { + pnp: { + enabled: false, + }, + vue: { + enabled: false, + compiler: 'vue-template-compiler', + }, + }, + memoryLimit: 2048, + }; + }); + + it('throws error if typescript is not installed', () => { + jest.setMock('typescript', undefined); + + const { + assertTypeScriptSupport, + } = require('../../../lib/typescript-reporter/TypeScriptSupport'); + + expect(() => assertTypeScriptSupport(configuration)).toThrowError( + 'When you use ForkTsCheckerWebpackPlugin with typescript reporter enabled, you must install `typescript` package.' + ); + }); + + it('throws error if typescript version is lower then 2.7.0', () => { + jest.setMock('typescript', { version: '2.6.9' }); + + const { + assertTypeScriptSupport, + } = require('../../../lib/typescript-reporter/TypeScriptSupport'); + + expect(() => assertTypeScriptSupport(configuration)).toThrowError( + [ + `ForkTsCheckerWebpackPlugin cannot use the current typescript version of 2.6.9.`, + 'The minimum required version is 2.7.0.', + ].join(os.EOL) + ); + }); + + it("doesn't throw error if typescript version is greater or equal 2.7.0", () => { + jest.setMock('typescript', { version: '2.7.0' }); + jest.setMock('graceful-fs', { existsSync: () => true }); + + const { + assertTypeScriptSupport, + } = require('../../../lib/typescript-reporter/TypeScriptSupport'); + + expect(() => assertTypeScriptSupport(configuration)).not.toThrowError(); + }); + + it('throws error if typescript version is lower then 3.6.0 and configuration has enabled build option', () => { + jest.setMock('typescript', { version: '3.5.9' }); + + const { + assertTypeScriptSupport, + } = require('../../../lib/typescript-reporter/TypeScriptSupport'); + + expect(() => assertTypeScriptSupport({ ...configuration, build: true })).toThrowError( + [ + `ForkTsCheckerWebpackPlugin cannot use the current typescript version of 3.5.9 because of the "build" option enabled.`, + 'The minimum version that supports "build" option is 3.6.0.', + 'Consider upgrading `typescript` or disabling "build" option.', + ].join(os.EOL) + ); + }); + + it("doesn't throw error if typescript version is greater or equal 3.6.0 and configuration has enabled build option", () => { + jest.setMock('typescript', { version: '3.6.0' }); + jest.setMock('graceful-fs', { existsSync: () => true }); + + const { + assertTypeScriptSupport, + } = require('../../../lib/typescript-reporter/TypeScriptSupport'); + + expect(() => assertTypeScriptSupport(configuration)).not.toThrowError(); + }); + + it('throws error if there is no tsconfig.json file', () => { + jest.setMock('typescript', { version: '3.8.0' }); + jest.setMock('graceful-fs', { existsSync: () => false }); + const { + assertTypeScriptSupport, + } = require('../../../lib/typescript-reporter/TypeScriptSupport'); + + expect(() => assertTypeScriptSupport(configuration)).toThrowError( + [ + `Cannot find the "./tsconfig.json" file.`, + `Please check webpack and ForkTsCheckerWebpackPlugin configuration.`, + `Possible errors:`, + ' - wrong `context` directory in webpack configuration (if `tsconfig` is not set or is a relative path in the fork plugin configuration)', + ' - wrong `typescript.tsconfig` path in the plugin configuration (should be a relative or absolute path)', + ].join(os.EOL) + ); + }); + + it('checks for pnp support if pnp extension is enabled', () => { + jest.setMock('typescript', { version: '3.8.0' }); + jest.setMock('graceful-fs', { existsSync: () => true }); + jest.setMock('../../../lib/typescript-reporter/extension/pnp/TypeScriptPnpExtensionSupport', { + assertTypeScriptPnpExtensionSupport: () => { + throw new Error('Error from PnP Extension.'); + }, + }); + + const { + assertTypeScriptSupport, + } = require('../../../lib/typescript-reporter/TypeScriptSupport'); + + configuration.extensions.pnp.enabled = true; + + expect(() => assertTypeScriptSupport(configuration)).toThrowError('Error from PnP Extension.'); + }); + + it('checks for pnp support if vue extension is enabled', () => { + jest.setMock('typescript', { version: '3.8.0' }); + jest.setMock('graceful-fs', { existsSync: () => true }); + jest.setMock('../../../lib/typescript-reporter/extension/vue/TypeScriptVueExtensionSupport', { + assertTypeScriptVueExtensionSupport: () => { + throw new Error('Error from Vue Extension.'); + }, + }); + + const { + assertTypeScriptSupport, + } = require('../../../lib/typescript-reporter/TypeScriptSupport'); + + configuration.extensions.vue.enabled = true; + + expect(() => assertTypeScriptSupport(configuration)).toThrowError('Error from Vue Extension.'); + }); +}); From 58a5c24ba5b0989b63155ec18138d3fee41fa91f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ole=C5=9B?= Date: Fri, 15 May 2020 23:38:13 +0200 Subject: [PATCH 13/29] fix: make project-references really working + e2e tests --- .DS_Store | Bin 10244 -> 10244 bytes .eslintrc.js | 3 +- .github/workflows/main.yml | 106 +---- .gitignore | 1 + jest.config.js | 6 +- package.json | 30 +- src/ForkTsCheckerWebpackPlugin.ts | 4 +- src/ForkTsCheckerWebpackPluginOptions.json | 21 +- src/ForkTsCheckerWebpackPluginState.ts | 8 +- .../EsLintReporterConfiguration.ts | 12 +- src/eslint-reporter/EsLintReporterOptions.ts | 2 +- .../reporter/EsLintReporter.ts | 44 +-- .../reporter/EsLintReporterState.ts | 17 - src/formatter/CodeframeFormatter.ts | 4 +- src/formatter/WebpackFormatter.ts | 7 +- src/hooks/getChangedFiles.ts | 18 + src/hooks/getDeletedFiles.ts | 17 +- src/hooks/getWatcher.ts | 14 + src/hooks/tapDoneToAsyncGetIssues.ts | 10 +- .../tapDoneToCollectChangedAndRemoved.ts | 35 ++ src/hooks/tapInvalidToUpdateState.ts | 20 - src/hooks/tapStartToConnectAndRunReporter.ts | 10 +- src/hooks/tapStopToDisconnectReporter.ts | 16 +- src/reporter/FilesChange.ts | 33 +- src/reporter/FilesInitialState.ts | 37 -- src/rpc/RpcClient.ts | 30 +- src/rpc/RpcMessage.ts | 38 +- src/rpc/RpcMessagePort.ts | 10 +- src/rpc/RpcService.ts | 9 +- src/rpc/error/RpcRemoteError.ts | 15 + .../RpcEventEmitterMessageChannel.ts | 33 -- .../RpcEventEmitterMessagePort.ts | 30 -- src/rpc/rpc-event-emitter/index.ts | 2 - src/rpc/rpc-ipc/RpcIpcMessagePort.ts | 113 ++++-- .../error/RpcIpcMessagePortClosedError.ts | 3 +- src/typescript-reporter/TypeScriptSupport.ts | 4 +- .../extension/vue/TypeScriptVueExtension.ts | 6 +- .../reporter/ControlledTypeScriptSystem.ts | 214 ++++++++++ .../reporter/ControlledWatchCompilerHost.ts | 127 ++---- .../reporter/ControlledWatchHost.ts | 7 - .../ControlledWatchSolutionBuilderHost.ts | 61 ++- .../reporter/PassiveFileSystem.ts | 231 +++++++++++ .../reporter/TypeScriptReporter.ts | 118 +++--- .../reporter/TypeScriptReporterRpcClient.ts | 23 +- .../reporter/TypeScriptReporterState.ts | 28 -- src/utils/fs/isFileJustCreated.ts | 9 - test/e2e/EsLint.spec.ts | 124 ++++++ test/e2e/PluginOutOfMemory.spec.ts | 72 ++++ test/e2e/TypeScriptSolutionBuilderApi.spec.ts | 105 +++++ test/e2e/TypeScriptWatchApi.spec.ts | 308 +++++++++++++++ test/e2e/fixtures/eslint-basic.fixture | 176 +++++++++ test/e2e/fixtures/typescript-basic.fixture | 157 ++++++++ .../typescript-project-references.fixture | 184 +++++++++ test/e2e/sandbox/Fixture.ts | 67 ++++ test/e2e/sandbox/GenericProcessDriver.ts | 87 +++++ test/e2e/sandbox/Listener.ts | 6 + test/e2e/sandbox/Sandbox.ts | 193 +++++++++ test/e2e/sandbox/WebpackDevServerDriver.ts | 134 +++++++ test/e2e/sandbox/WebpackErrorsExtractor.ts | 35 ++ test/fixtures/.DS_Store | Bin 6148 -> 0 bytes .../caseSensitiveProject/src/index.ts | 3 - test/fixtures/caseSensitiveProject/src/lib.ts | 1 - .../caseSensitiveProject/tsconfig.json | 7 - test/fixtures/project/src/defs.d.ts | 1 - test/fixtures/project/src/export.ts | 1 - test/fixtures/project/src/index.ts | 2 - test/fixtures/project/src/pathResolutions.ts | 1 - test/fixtures/project/src/syntacticError.ts | 2 - test/fixtures/project/src/weirdResolutions.ts | 5 - .../project/tsconfig-semantic-error-only.json | 8 - ...tsconfig-weird-resolutions-with-paths.json | 9 - .../project/tsconfig-weird-resolutions.json | 8 - test/fixtures/project/tsconfig.json | 6 - test/fixtures/project/tslint.autofix.json | 14 - test/fixtures/project/tslint.json | 9 - test/fixtures/project/weirdResolver.js | 11 - test/fixtures/project_eslint/src/.eslintrc.js | 10 - test/fixtures/project_eslint/src/index.ts | 10 - .../project_eslint/src/lib/.eslintrc.js | 8 - test/fixtures/project_eslint/src/lib/func.ts | 3 - .../project_eslint/src/lib/otherFunc.js | 6 - test/fixtures/project_eslint/tsconfig.json | 6 - test/fixtures/vue/src/attrs/NotFound.vue | 5 - test/fixtures/vue/src/attrs/Test.vue | 1 - test/fixtures/vue/src/attrs/test.ts | 2 - test/fixtures/vue/src/css.d.ts | 5 - test/fixtures/vue/src/example-wild.vue | 24 -- test/fixtures/vue/src/example.css | 3 - test/fixtures/vue/src/example.vue | 24 -- test/fixtures/vue/src/imports/Component1.vue | 3 - test/fixtures/vue/src/imports/Component2.vue | 3 - test/fixtures/vue/src/imports/Component3.vue | 3 - test/fixtures/vue/src/imports/Test.vue | 31 -- test/fixtures/vue/src/imports/foo1/Foo1.vue | 3 - test/fixtures/vue/src/imports/foo2/Foo2.vue | 3 - test/fixtures/vue/src/index.ts | 8 - test/fixtures/vue/src/langs/example-js.vue | 17 - test/fixtures/vue/src/langs/example-jsx.vue | 11 - .../fixtures/vue/src/langs/example-nolang.vue | 17 - .../vue/src/langs/example-ts-with-errors.vue | 8 - test/fixtures/vue/src/langs/example-ts.vue | 18 - test/fixtures/vue/src/langs/example-tsx.vue | 11 - test/fixtures/vue/src/langs/index.ts | 6 - test/fixtures/vue/src/syntacticError.ts | 2 - test/fixtures/vue/tsconfig-attrs.json | 12 - test/fixtures/vue/tsconfig-imports.json | 13 - test/fixtures/vue/tsconfig-langs-strict.json | 14 - test/fixtures/vue/tsconfig-langs.json | 13 - test/fixtures/vue/tsconfig.json | 13 - test/integration/general.spec.ts | 368 ------------------ test/integration/helpers/createCompiler.ts | 181 --------- test/integration/helpers/createVueCompiler.ts | 104 ----- test/integration/helpers/index.ts | 13 - test/integration/helpers/rpc.js | 29 -- test/integration/incrementalApi.spec.ts | 89 ----- .../mocks/ApiIncrementalCheckerWithRpc.js | 53 --- .../mocks/IncrementalCheckerWithError.js | 9 - .../mocks/IncrementalCheckerWithRpc.js | 35 -- test/integration/nonIncrementalApi.spec.ts | 68 ---- test/integration/tsconfig.json | 11 - test/integration/vue.spec.ts | 360 ----------------- test/json.d.ts | 4 - test/tsconfig.json | 5 +- test/types/copy-dir.d.ts | 13 - test/types/unixify.d.ts | 4 - test/types/vue-loader.d.ts | 1 - test/unit/ForkTsCheckerWebpackPlugin.spec.ts | 2 +- test/unit/formatter/BasicFormatter.spec.ts | 4 +- .../unit/formatter/CodeframeFormatter.spec.ts | 4 +- .../formatter/FormatterConfiguration.spec.ts | 4 +- test/unit/formatter/FormatterFactory.spec.ts | 4 +- test/unit/formatter/WebpackFormatter.spec.ts | 9 +- test/unit/issue/Issue.spec.ts | 2 +- .../TypeScriptReporterConfiguration.spec.ts | 131 +++++++ .../TypeScriptSupport.spec.ts | 65 ++-- .../issue/TypeScriptIssueFactory.spec.ts | 2 +- tsconfig.json | 4 +- yarn.lock | 180 +++------ 138 files changed, 2794 insertions(+), 2602 deletions(-) delete mode 100644 src/eslint-reporter/reporter/EsLintReporterState.ts create mode 100644 src/hooks/getChangedFiles.ts create mode 100644 src/hooks/getWatcher.ts create mode 100644 src/hooks/tapDoneToCollectChangedAndRemoved.ts delete mode 100644 src/hooks/tapInvalidToUpdateState.ts delete mode 100644 src/reporter/FilesInitialState.ts create mode 100644 src/rpc/error/RpcRemoteError.ts delete mode 100644 src/rpc/rpc-event-emitter/RpcEventEmitterMessageChannel.ts delete mode 100644 src/rpc/rpc-event-emitter/RpcEventEmitterMessagePort.ts delete mode 100644 src/rpc/rpc-event-emitter/index.ts create mode 100644 src/typescript-reporter/reporter/ControlledTypeScriptSystem.ts delete mode 100644 src/typescript-reporter/reporter/ControlledWatchHost.ts create mode 100644 src/typescript-reporter/reporter/PassiveFileSystem.ts delete mode 100644 src/typescript-reporter/reporter/TypeScriptReporterState.ts delete mode 100644 src/utils/fs/isFileJustCreated.ts create mode 100644 test/e2e/EsLint.spec.ts create mode 100644 test/e2e/PluginOutOfMemory.spec.ts create mode 100644 test/e2e/TypeScriptSolutionBuilderApi.spec.ts create mode 100644 test/e2e/TypeScriptWatchApi.spec.ts create mode 100644 test/e2e/fixtures/eslint-basic.fixture create mode 100644 test/e2e/fixtures/typescript-basic.fixture create mode 100644 test/e2e/fixtures/typescript-project-references.fixture create mode 100644 test/e2e/sandbox/Fixture.ts create mode 100644 test/e2e/sandbox/GenericProcessDriver.ts create mode 100644 test/e2e/sandbox/Listener.ts create mode 100644 test/e2e/sandbox/Sandbox.ts create mode 100644 test/e2e/sandbox/WebpackDevServerDriver.ts create mode 100644 test/e2e/sandbox/WebpackErrorsExtractor.ts delete mode 100644 test/fixtures/.DS_Store delete mode 100644 test/fixtures/caseSensitiveProject/src/index.ts delete mode 100644 test/fixtures/caseSensitiveProject/src/lib.ts delete mode 100644 test/fixtures/caseSensitiveProject/tsconfig.json delete mode 100644 test/fixtures/project/src/defs.d.ts delete mode 100644 test/fixtures/project/src/export.ts delete mode 100644 test/fixtures/project/src/index.ts delete mode 100644 test/fixtures/project/src/pathResolutions.ts delete mode 100644 test/fixtures/project/src/syntacticError.ts delete mode 100644 test/fixtures/project/src/weirdResolutions.ts delete mode 100644 test/fixtures/project/tsconfig-semantic-error-only.json delete mode 100644 test/fixtures/project/tsconfig-weird-resolutions-with-paths.json delete mode 100644 test/fixtures/project/tsconfig-weird-resolutions.json delete mode 100644 test/fixtures/project/tsconfig.json delete mode 100644 test/fixtures/project/tslint.autofix.json delete mode 100644 test/fixtures/project/tslint.json delete mode 100644 test/fixtures/project/weirdResolver.js delete mode 100644 test/fixtures/project_eslint/src/.eslintrc.js delete mode 100644 test/fixtures/project_eslint/src/index.ts delete mode 100644 test/fixtures/project_eslint/src/lib/.eslintrc.js delete mode 100644 test/fixtures/project_eslint/src/lib/func.ts delete mode 100644 test/fixtures/project_eslint/src/lib/otherFunc.js delete mode 100644 test/fixtures/project_eslint/tsconfig.json delete mode 100644 test/fixtures/vue/src/attrs/NotFound.vue delete mode 100644 test/fixtures/vue/src/attrs/Test.vue delete mode 100644 test/fixtures/vue/src/attrs/test.ts delete mode 100644 test/fixtures/vue/src/css.d.ts delete mode 100644 test/fixtures/vue/src/example-wild.vue delete mode 100644 test/fixtures/vue/src/example.css delete mode 100644 test/fixtures/vue/src/example.vue delete mode 100644 test/fixtures/vue/src/imports/Component1.vue delete mode 100644 test/fixtures/vue/src/imports/Component2.vue delete mode 100644 test/fixtures/vue/src/imports/Component3.vue delete mode 100644 test/fixtures/vue/src/imports/Test.vue delete mode 100644 test/fixtures/vue/src/imports/foo1/Foo1.vue delete mode 100644 test/fixtures/vue/src/imports/foo2/Foo2.vue delete mode 100644 test/fixtures/vue/src/index.ts delete mode 100644 test/fixtures/vue/src/langs/example-js.vue delete mode 100644 test/fixtures/vue/src/langs/example-jsx.vue delete mode 100644 test/fixtures/vue/src/langs/example-nolang.vue delete mode 100644 test/fixtures/vue/src/langs/example-ts-with-errors.vue delete mode 100644 test/fixtures/vue/src/langs/example-ts.vue delete mode 100644 test/fixtures/vue/src/langs/example-tsx.vue delete mode 100644 test/fixtures/vue/src/langs/index.ts delete mode 100644 test/fixtures/vue/src/syntacticError.ts delete mode 100644 test/fixtures/vue/tsconfig-attrs.json delete mode 100644 test/fixtures/vue/tsconfig-imports.json delete mode 100644 test/fixtures/vue/tsconfig-langs-strict.json delete mode 100644 test/fixtures/vue/tsconfig-langs.json delete mode 100644 test/fixtures/vue/tsconfig.json delete mode 100644 test/integration/general.spec.ts delete mode 100644 test/integration/helpers/createCompiler.ts delete mode 100644 test/integration/helpers/createVueCompiler.ts delete mode 100644 test/integration/helpers/index.ts delete mode 100644 test/integration/helpers/rpc.js delete mode 100644 test/integration/incrementalApi.spec.ts delete mode 100644 test/integration/mocks/ApiIncrementalCheckerWithRpc.js delete mode 100644 test/integration/mocks/IncrementalCheckerWithError.js delete mode 100644 test/integration/mocks/IncrementalCheckerWithRpc.js delete mode 100644 test/integration/nonIncrementalApi.spec.ts delete mode 100644 test/integration/tsconfig.json delete mode 100644 test/integration/vue.spec.ts delete mode 100644 test/json.d.ts delete mode 100644 test/types/copy-dir.d.ts delete mode 100644 test/types/unixify.d.ts delete mode 100644 test/types/vue-loader.d.ts create mode 100644 test/unit/typescript-reporter/TypeScriptReporterConfiguration.spec.ts diff --git a/.DS_Store b/.DS_Store index d79358b84366367d10c403ba8029e8b1a517643f..9903b22052f1cb70a52d98026046b4714e06000a 100644 GIT binary patch delta 192 zcmZn(XbG6$gHU^hRb@@5`^2P~0F3~3Dc3`Gpt47v;@48=e)nIVHA6-Z_S$s!=X z97rcI6fh)$#dLwJ9EMVcbcRfZJO(|Wo^*yP&z$_^q@4UD1_lNJ1_s8@3=B*Wn;(iC R;@Zrv@SDY%I;QPs0ssvIEiM26 delta 41 xcmZn(XbG6$I9U^hRb(q@;ouI%{8KLm;f~}4*~!H diff --git a/.eslintrc.js b/.eslintrc.js index baba041d..52a8beb7 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -26,7 +26,8 @@ module.exports = { { files: ['*.spec.ts'], rules: { - '@typescript-eslint/no-var-requires': 'off' + '@typescript-eslint/no-var-requires': 'off', + 'node/no-missing-import': 'off' } } ] diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index bf9404cb..b30bed65 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -39,64 +39,8 @@ jobs: needs: build strategy: matrix: - include: - # test different typescript versions - - os: ubuntu-latest - node: 12 - packages: typescript@2.7.1 webpack@^4.0.0 ts-loader@5.0.0 vue-loader@15.2.0 - - - os: ubuntu-latest - node: 12 - packages: typescript@~3.0.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 - - - os: ubuntu-latest - node: 12 - packages: typescript@~3.6.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 - - - os: ubuntu-latest - node: 12 - packages: typescript@latest webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 - - # test different webpack versions - - os: ubuntu-latest - node: 12 - packages: webpack@^5.0.0-beta.14 ts-loader@^5.0.0 vue-loader@^15.2.0 - - # test different operating systems and node versions - # macos - - os: macos-latest - node: 8 - packages: typescript@~3.6.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 - - - os: macos-latest - node: 10 - packages: typescript@~3.6.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 - - - os: macos-latest - node: 12 - packages: typescript@~3.6.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 - - # windows - - os: windows-latest - node: 8 - packages: typescript@~3.6.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 - - - os: windows-latest - node: 10 - packages: typescript@~3.6.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 - - - os: windows-latest - node: 12 - packages: typescript@~3.6.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 - - # ubuntu - - os: ubuntu-latest - node: 8 - packages: typescript@~3.6.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 - - - os: ubuntu-latest - node: 10 - packages: typescript@~3.6.0 webpack@^4.0.0 ts-loader@^5.0.0 vue-loader@^15.2.0 + node: [8, 10, 12] + os: [ubuntu-latest, macos-latest, windows-latest] steps: - uses: actions/checkout@v1 @@ -119,9 +63,6 @@ jobs: - name: Install dependencies run: yarn install --frozen-lockfile --ignore-engines - - name: Replace dependencies - run: yarn add ${{ matrix.packages }} -D --ignore-engines - - name: Download build artifact uses: actions/download-artifact@v1 with: @@ -130,47 +71,8 @@ jobs: - name: Run unit tests run: yarn test:unit - # TODO: uncomment, when integration tests will work again - # - name: Run integration tests - # run: yarn test:integration - - coverage: - runs-on: ubuntu-latest - needs: test - steps: - - uses: actions/checkout@v1 - - - name: Setup node - uses: actions/setup-node@v1 - with: - node-version: 12 - - - name: Get yarn cache - id: yarn-cache - run: echo "::set-output name=dir::$(yarn cache dir)" - - - uses: actions/cache@v1 - with: - path: ${{ steps.yarn-cache.outputs.dir }} - key: ${{ runner.os }}-node-${{ matrix.node }}-yarn-${{ hashFiles('**/yarn.lock') }} - restore-keys: | - ${{ runner.os }}-node-${{ matrix.node }}-yarn- - - - name: Install dependencies - run: yarn install --frozen-lockfile - - - name: Download build artifact - uses: actions/download-artifact@v1 - with: - name: lib - - - name: Test & publish code coverage - uses: paambaati/codeclimate-action@v2.5.7 - env: - CC_TEST_REPORTER_ID: 49901d62e1528b4c2379a4618254376692e87b2e9a749b94bcc4c17daab1ca4f - with: - coverageCommand: yarn test:unit --coverage - debug: true + - name: Run e2e tests + run: yarn test:e2e release: runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index 99d76db3..13388e8b 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ npm-debug.log* lib !test/**/lib +fork-ts-checker-webpack-plugin.tgz # Coverage directory used by tools like istanbul coverage diff --git a/jest.config.js b/jest.config.js index bc7d1d82..58038ec5 100644 --- a/jest.config.js +++ b/jest.config.js @@ -2,9 +2,13 @@ module.exports = { preset: 'ts-jest', testEnvironment: 'node', setupFilesAfterEnv: ['./test/setup.ts'], + rootDir: '.', + moduleNameMapper: { + '^lib/(.*)$': '/lib/$1', + }, globals: { 'ts-jest': { - tsConfig: './test/tsconfig.json' + tsConfig: './test/tsconfig.json', }, }, }; diff --git a/package.json b/package.json index 3a5de652..97a0a8b9 100644 --- a/package.json +++ b/package.json @@ -3,19 +3,14 @@ "version": "0.0.0-semantic-release", "description": "Runs typescript type checker and linter on separate process.", "keywords": [ - "awesome-typescript-loader", - "checker", "fast", "fork", - "increment", "linter", + "webpack", "plugin", - "speed", "ts-loader", - "type", "typescript", - "webpack", - "webpack-plugin" + "webpack" ], "bugs": { "url": "https://github.com/TypeStrong/fork-ts-checker-webpack-plugin/issues" @@ -31,16 +26,16 @@ "John Reilly (https://blog.johnnyreilly.com)" ], "files": [ - "lib" + "./lib" ], "main": "lib/index.js", "types": "lib/index.d.ts", "scripts": { "build": "rimraf lib && tsc --version && tsc", - "lint": "eslint ./src ./test --ext .ts --ext .js --ignore-pattern '/test/fixtures/**' --ignore-pattern '/test/tmp/**'", - "test": "yarn build && yarn test:unit && yarn test:integration", + "lint": "eslint ./src ./test --ext .ts", + "test": "yarn build && yarn test:unit && yarn test:e2e", "test:unit": "jest unit", - "test:integration": "jest integration && rimraf tmp", + "test:e2e": "yarn pack --filename fork-ts-checker-webpack-plugin.tgz && jest e2e --runInBand", "precommit": "lint-staged && yarn build && yarn test:unit", "commit": "./node_modules/.bin/git-cz" }, @@ -66,7 +61,8 @@ "dependencies": { "@babel/code-frame": "^7.8.3", "chalk": "^2.4.1", - "graceful-fs": "^4.2.3", + "fs-extra": "^9.0.0", + "memfs": "^3.1.2", "minimatch": "^3.0.4", "schema-utils": "1.0.0", "semver": "^5.6.0", @@ -77,12 +73,10 @@ "@mdx-js/mdx": "^1.5.8", "@types/babel__code-frame": "^7.0.1", "@types/eslint": "^6.8.0", - "@types/graceful-fs": "^4.1.3", + "@types/fs-extra": "^8.1.0", "@types/jest": "^25.2.1", - "@types/lodash": "^4.14.149", "@types/minimatch": "^3.0.1", "@types/mock-fs": "^4.10.0", - "@types/mock-require": "^2.0.0", "@types/node": "^13.11.1", "@types/rimraf": "^3.0.0", "@types/schema-utils": "1.0.0", @@ -91,8 +85,6 @@ "@typescript-eslint/eslint-plugin": "^2.27.0", "@typescript-eslint/parser": "^2.27.0", "commitlint": "^8.3.5", - "copy-dir": "^1.2.0", - "css-loader": "3.5.2", "eslint": "^6.8.0", "eslint-config-prettier": "^6.10.1", "eslint-plugin-node": "^11.1.0", @@ -101,16 +93,14 @@ "husky": "^4.2.5", "jest": "^25.3.0", "lint-staged": "^10.1.3", - "lodash": "^4.17.15", "mock-fs": "^4.11.0", - "mock-require": "^3.0.3", "nativescript-vue-template-compiler": "^2.5.1", "prettier": "^2.0.4", "rimraf": "^3.0.2", + "strip-ansi": "^6.0.0", "ts-jest": "^25.3.1", "ts-loader": "^6.2.2", "typescript": "^3.8.3", - "unixify": "^1.0.0", "vue": "^2.6.11", "vue-class-component": "^7.2.3", "vue-loader": "^15.9.1", diff --git a/src/ForkTsCheckerWebpackPlugin.ts b/src/ForkTsCheckerWebpackPlugin.ts index 99f038a8..615af678 100644 --- a/src/ForkTsCheckerWebpackPlugin.ts +++ b/src/ForkTsCheckerWebpackPlugin.ts @@ -10,11 +10,11 @@ import { createTypeScriptReporterRpcClient } from './typescript-reporter/reporte import { assertEsLintSupport } from './eslint-reporter/assertEsLintSupport'; import { createEsLintReporterRpcClient } from './eslint-reporter/reporter/EsLintReporterRpcClient'; import { tapDoneToAsyncGetIssues } from './hooks/tapDoneToAsyncGetIssues'; -import { tapInvalidToUpdateState } from './hooks/tapInvalidToUpdateState'; import { tapStartToConnectAndRunReporter } from './hooks/tapStartToConnectAndRunReporter'; import { tapStopToDisconnectReporter } from './hooks/tapStopToDisconnectReporter'; import { tapAfterCompileToGetIssues } from './hooks/tapAfterCompileToGetIssues'; import { getForkTsCheckerWebpackPluginHooks } from './hooks/pluginHooks'; +import { tapDoneToCollectChangedAndRemoved } from './hooks/tapDoneToCollectChangedAndRemoved'; class ForkTsCheckerWebpackPlugin implements webpack.Plugin { constructor(private readonly options: ForkTsCheckerWebpackPluginOptions = {}) { @@ -43,8 +43,8 @@ class ForkTsCheckerWebpackPlugin implements webpack.Plugin { if (reporters.length) { const reporter = createAggregatedReporter(composeReporterRpcClients(reporters)); - tapInvalidToUpdateState(compiler, configuration, state); tapStartToConnectAndRunReporter(compiler, reporter, configuration, state); + tapDoneToCollectChangedAndRemoved(compiler, configuration, state); tapStopToDisconnectReporter(compiler, reporter, configuration, state); if (configuration.async) { tapDoneToAsyncGetIssues(compiler, configuration, state); diff --git a/src/ForkTsCheckerWebpackPluginOptions.json b/src/ForkTsCheckerWebpackPluginOptions.json index 85271092..4915a01a 100644 --- a/src/ForkTsCheckerWebpackPluginOptions.json +++ b/src/ForkTsCheckerWebpackPluginOptions.json @@ -188,13 +188,20 @@ "type": "object", "properties": { "files": { - "type": "array", - "items": { - "type": "string" - }, - "minItems": 1, - "uniqueItems": true, - "description": "List of glob patterns of files to be linted." + "oneOf": [ + { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1, + "uniqueItems": true + }, + { + "type": "string" + } + ], + "description": "List of glob patterns or files to be linted." }, "enabled": { "type": "boolean", diff --git a/src/ForkTsCheckerWebpackPluginState.ts b/src/ForkTsCheckerWebpackPluginState.ts index a0a932f9..c100799b 100644 --- a/src/ForkTsCheckerWebpackPluginState.ts +++ b/src/ForkTsCheckerWebpackPluginState.ts @@ -2,17 +2,17 @@ import { Issue } from './issue'; interface ForkTsCheckerWebpackPluginState { report: Promise; - isWatching: boolean; - createdFiles: string[]; changedFiles: string[]; + removedFiles: string[]; + isWatching: boolean; } function createForkTsCheckerWebpackPluginState(): ForkTsCheckerWebpackPluginState { return { report: Promise.resolve([]), - isWatching: false, - createdFiles: [], changedFiles: [], + removedFiles: [], + isWatching: false, }; } diff --git a/src/eslint-reporter/EsLintReporterConfiguration.ts b/src/eslint-reporter/EsLintReporterConfiguration.ts index 454c463e..5f95d8a6 100644 --- a/src/eslint-reporter/EsLintReporterConfiguration.ts +++ b/src/eslint-reporter/EsLintReporterConfiguration.ts @@ -8,6 +8,16 @@ interface EsLintReporterConfiguration { files: string[]; } +function castToArray(value: T | T[] | undefined): T[] { + if (!value) { + return []; + } else if (!Array.isArray(value)) { + return [value]; + } else { + return value; + } +} + function createEsLintReporterConfiguration( compiler: webpack.Compiler, options: EsLintReporterOptions | undefined @@ -15,8 +25,8 @@ function createEsLintReporterConfiguration( return { enabled: !!(options && options.enabled === true), memoryLimit: 2048, - files: [], ...(typeof options === 'object' ? options : {}), + files: typeof options === 'object' ? castToArray(options.files) : [], options: { cwd: compiler.options.context || process.cwd(), extensions: ['.js', '.ts', '.tsx'], diff --git a/src/eslint-reporter/EsLintReporterOptions.ts b/src/eslint-reporter/EsLintReporterOptions.ts index 163552b4..65868e9d 100644 --- a/src/eslint-reporter/EsLintReporterOptions.ts +++ b/src/eslint-reporter/EsLintReporterOptions.ts @@ -1,5 +1,5 @@ type EsLintReporterOptions = { - files: string[]; + files: string | string[]; enabled?: boolean; memoryLimit?: number; // it's not typed because we don't want to have direct dependency to eslint from this plugin diff --git a/src/eslint-reporter/reporter/EsLintReporter.ts b/src/eslint-reporter/reporter/EsLintReporter.ts index 84779962..5e342e5f 100644 --- a/src/eslint-reporter/reporter/EsLintReporter.ts +++ b/src/eslint-reporter/reporter/EsLintReporter.ts @@ -1,56 +1,52 @@ -import { LintReport } from '../types/eslint'; -import { createEsLintReporterState, EsLintReporterState } from './EsLintReporterState'; +import { CLIEngine, LintReport, LintResult } from '../types/eslint'; import { createIssuesFromEsLintResults } from '../issue/EsLintIssueFactory'; import { EsLintReporterConfiguration } from '../EsLintReporterConfiguration'; import { Reporter } from '../../reporter'; function createEsLintReporter(configuration: EsLintReporterConfiguration): Reporter { - const state: EsLintReporterState = createEsLintReporterState(); + let engine: CLIEngine; + let isInitialRun = true; + const lintResults = new Map(); + return { - getReport: async ({ createdFiles = [], changedFiles = [], deletedFiles = [] }) => { - if (!state.engine) { + getReport: async ({ changedFiles = [], deletedFiles = [] }) => { + if (!engine) { // eslint-disable-next-line @typescript-eslint/no-var-requires const { CLIEngine } = require('eslint'); - state.engine = new CLIEngine(configuration.options); + engine = new CLIEngine(configuration.options); + isInitialRun = true; } - createdFiles.forEach((createdFile) => { - state.lintResults.delete(createdFile); - }); changedFiles.forEach((changedFile) => { - state.lintResults.delete(changedFile); + lintResults.delete(changedFile); }); deletedFiles.forEach((removedFile) => { - state.lintResults.delete(removedFile); + lintResults.delete(removedFile); }); - if (!state.engine) { - throw new Error('Assert error - state.engine should be defined'); - } - // get reports const lintReports: LintReport[] = []; - if (state.isInitialRun) { + if (isInitialRun) { lintReports.push( - state.engine.executeOnFiles(state.engine.resolveFileGlobPatterns(configuration.files)) + engine.executeOnFiles(engine.resolveFileGlobPatterns(configuration.files)) ); - state.isInitialRun = false; - } - - if (changedFiles.length) { - lintReports.push(state.engine.executeOnFiles(changedFiles)); + isInitialRun = false; + } else { + if (changedFiles.length) { + lintReports.push(engine.executeOnFiles(changedFiles)); + } } // store results in the state lintReports.forEach((lintReport) => { lintReport.results.forEach((lintResult) => { - state.lintResults.set(lintResult.filePath, lintResult); + lintResults.set(lintResult.filePath, lintResult); }); }); // get actual list of previous and current reports - const results = Array.from(state.lintResults.values()); + const results = Array.from(lintResults.values()); return createIssuesFromEsLintResults(results); }, diff --git a/src/eslint-reporter/reporter/EsLintReporterState.ts b/src/eslint-reporter/reporter/EsLintReporterState.ts deleted file mode 100644 index a3c8884e..00000000 --- a/src/eslint-reporter/reporter/EsLintReporterState.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { CLIEngine, LintResult } from '../types/eslint'; - -interface EsLintReporterState { - engine: CLIEngine | undefined; - lintResults: Map; - isInitialRun: boolean; -} - -function createEsLintReporterState(): EsLintReporterState { - return { - engine: undefined, - lintResults: new Map(), - isInitialRun: true, - }; -} - -export { EsLintReporterState, createEsLintReporterState }; diff --git a/src/formatter/CodeframeFormatter.ts b/src/formatter/CodeframeFormatter.ts index 7bc16052..3e5dc842 100644 --- a/src/formatter/CodeframeFormatter.ts +++ b/src/formatter/CodeframeFormatter.ts @@ -1,5 +1,5 @@ -import * as os from 'os'; -import * as fs from 'graceful-fs'; +import os from 'os'; +import fs from 'fs-extra'; import { codeFrameColumns, BabelCodeFrameOptions } from '@babel/code-frame'; import { Formatter } from './Formatter'; import { createBasicFormatter } from './BasicFormatter'; diff --git a/src/formatter/WebpackFormatter.ts b/src/formatter/WebpackFormatter.ts index e16ba9ff..9ab6b8c8 100644 --- a/src/formatter/WebpackFormatter.ts +++ b/src/formatter/WebpackFormatter.ts @@ -1,12 +1,13 @@ -import { Formatter } from './Formatter'; import os from 'os'; import chalk from 'chalk'; +import { relative } from 'path'; +import { Formatter } from './Formatter'; import { formatIssueLocation } from '../issue'; -function createWebpackFormatter(formatter: Formatter): Formatter { +function createWebpackFormatter(formatter: Formatter, context: string): Formatter { return function webpackFormatter(issue) { const severity = issue.severity.toUpperCase(); - const file = issue.file; + const file = issue.file ? relative(context, issue.file) : undefined; const location = issue.location ? formatIssueLocation(issue.location) : undefined; const color = issue.severity === 'warning' ? chalk.yellow : chalk.red; const header = [severity, 'in', file].concat(location ? [location] : []).join(' '); diff --git a/src/hooks/getChangedFiles.ts b/src/hooks/getChangedFiles.ts new file mode 100644 index 00000000..68c1b7f3 --- /dev/null +++ b/src/hooks/getChangedFiles.ts @@ -0,0 +1,18 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import webpack from 'webpack'; +import { ForkTsCheckerWebpackPluginState } from '../ForkTsCheckerWebpackPluginState'; + +function getChangedFiles( + compiler: webpack.Compiler, + state: ForkTsCheckerWebpackPluginState +): string[] { + if ((compiler as any).modifiedFiles) { + // webpack 5+ + return Array.from((compiler as any).modifiedFiles); + } else { + // webpack 4 + return state.changedFiles; + } +} + +export { getChangedFiles }; diff --git a/src/hooks/getDeletedFiles.ts b/src/hooks/getDeletedFiles.ts index bbd74958..72995848 100644 --- a/src/hooks/getDeletedFiles.ts +++ b/src/hooks/getDeletedFiles.ts @@ -1,9 +1,18 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import webpack from 'webpack'; +import { ForkTsCheckerWebpackPluginState } from '../ForkTsCheckerWebpackPluginState'; -function getDeletedFiles(compiler: webpack.Compiler): string[] { - // TODO: investigate webpack version support for this method - // eslint-disable-next-line @typescript-eslint/no-explicit-any - return Array.from((compiler as any).removedFiles) || []; +function getDeletedFiles( + compiler: webpack.Compiler, + state: ForkTsCheckerWebpackPluginState +): string[] { + if ((compiler as any).removedFiles) { + // webpack 5+ + return Array.from((compiler as any).removedFiles || []); + } else { + // webpack 4 + return state.removedFiles; + } } export { getDeletedFiles }; diff --git a/src/hooks/getWatcher.ts b/src/hooks/getWatcher.ts new file mode 100644 index 00000000..17b091cd --- /dev/null +++ b/src/hooks/getWatcher.ts @@ -0,0 +1,14 @@ +import webpack from 'webpack'; +import { EventEmitter } from 'events'; + +type Watcher = EventEmitter; + +function getWatcher(compiler: webpack.Compiler): Watcher | undefined { + // webpack 4 + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const { watchFileSystem } = compiler as any; + + return watchFileSystem.watcher || (watchFileSystem.wfs && watchFileSystem.wfs.watcher); +} + +export { getWatcher, Watcher }; diff --git a/src/hooks/tapDoneToAsyncGetIssues.ts b/src/hooks/tapDoneToAsyncGetIssues.ts index 82439e6b..11122940 100644 --- a/src/hooks/tapDoneToAsyncGetIssues.ts +++ b/src/hooks/tapDoneToAsyncGetIssues.ts @@ -50,12 +50,12 @@ function tapDoneToAsyncGetIssues( // modify list of issues in the plugin hooks issues = hooks.issues.call(issues); - const formatter = createWebpackFormatter(configuration.formatter); - issues.forEach((issue) => { - configuration.logger.issues.log(formatter(issue)); - }); + const formatter = createWebpackFormatter(configuration.formatter, compiler.context); - if (!issues.length) { + if (issues.length) { + // follow webpack's approach - one process.write to stderr with all errors and warnings + configuration.logger.issues.error(issues.map((issue) => formatter(issue)).join('\n')); + } else { configuration.logger.issues.log(chalk.green('No issues found.')); } diff --git a/src/hooks/tapDoneToCollectChangedAndRemoved.ts b/src/hooks/tapDoneToCollectChangedAndRemoved.ts new file mode 100644 index 00000000..3844ac50 --- /dev/null +++ b/src/hooks/tapDoneToCollectChangedAndRemoved.ts @@ -0,0 +1,35 @@ +import webpack from 'webpack'; +import { ForkTsCheckerWebpackPluginConfiguration } from '../ForkTsCheckerWebpackPluginConfiguration'; +import { ForkTsCheckerWebpackPluginState } from '../ForkTsCheckerWebpackPluginState'; +import { getWatcher } from './getWatcher'; + +function tapDoneToCollectChangedAndRemoved( + compiler: webpack.Compiler, + configuration: ForkTsCheckerWebpackPluginConfiguration, + state: ForkTsCheckerWebpackPluginState +) { + compiler.hooks.done.tap('ForkTsCheckerWebpackPlugin', (stats) => { + state.changedFiles = []; + state.removedFiles = []; + + // the new watcher is defined after done hook + // we need this for webpack < 5, because modifiedFiles and removedFiles set is not provided + // this hook can be removed when we drop support for webpack 4 + setImmediate(() => { + const compiler = stats.compilation.compiler; + const watcher = getWatcher(compiler); + + if (watcher) { + watcher.on('change', (filePath: string) => { + state.changedFiles.push(filePath); + }); + watcher.on('remove', (filePath: string) => { + state.removedFiles.push(filePath); + }); + // webpack will automatically clean-up listeners + } + }); + }); +} + +export { tapDoneToCollectChangedAndRemoved }; diff --git a/src/hooks/tapInvalidToUpdateState.ts b/src/hooks/tapInvalidToUpdateState.ts deleted file mode 100644 index c86b3ac5..00000000 --- a/src/hooks/tapInvalidToUpdateState.ts +++ /dev/null @@ -1,20 +0,0 @@ -import webpack from 'webpack'; -import { ForkTsCheckerWebpackPluginConfiguration } from '../ForkTsCheckerWebpackPluginConfiguration'; -import { ForkTsCheckerWebpackPluginState } from '../ForkTsCheckerWebpackPluginState'; -import isFileJustCreated from '../utils/fs/isFileJustCreated'; - -function tapInvalidToUpdateState( - compiler: webpack.Compiler, - configuration: ForkTsCheckerWebpackPluginConfiguration, - state: ForkTsCheckerWebpackPluginState -) { - compiler.hooks.invalid.tap('ForkTsCheckerWebpackPlugin', (fileName) => { - if (isFileJustCreated(fileName)) { - state.createdFiles.push(fileName); - } else { - state.changedFiles.push(fileName); - } - }); -} - -export { tapInvalidToUpdateState }; diff --git a/src/hooks/tapStartToConnectAndRunReporter.ts b/src/hooks/tapStartToConnectAndRunReporter.ts index a977f47f..3bc8e25f 100644 --- a/src/hooks/tapStartToConnectAndRunReporter.ts +++ b/src/hooks/tapStartToConnectAndRunReporter.ts @@ -4,6 +4,7 @@ import { ForkTsCheckerWebpackPluginState } from '../ForkTsCheckerWebpackPluginSt import { getForkTsCheckerWebpackPluginHooks } from './pluginHooks'; import { getDeletedFiles } from './getDeletedFiles'; import { FilesChange, ReporterRpcClient } from '../reporter'; +import { getChangedFiles } from './getChangedFiles'; function tapStartToConnectAndRunReporter( compiler: webpack.Compiler, @@ -27,20 +28,15 @@ function tapStartToConnectAndRunReporter( state.isWatching = true; let change: FilesChange = { - createdFiles: state.createdFiles, - changedFiles: state.changedFiles, - deletedFiles: getDeletedFiles(compiler), + changedFiles: getChangedFiles(compiler, state), + deletedFiles: getDeletedFiles(compiler, state), }; - state.createdFiles = []; - state.changedFiles = []; - change = hooks.runWatch.call(change, compiler); configuration.logger.infrastructure.info( [ 'Calling reporter service for incremental check.', - ` Created files: ${JSON.stringify(change.createdFiles)}`, ` Changed files: ${JSON.stringify(change.changedFiles)}`, ` Deleted files: ${JSON.stringify(change.deletedFiles)}`, ].join('\n') diff --git a/src/hooks/tapStopToDisconnectReporter.ts b/src/hooks/tapStopToDisconnectReporter.ts index e6c111b2..5494c9cc 100644 --- a/src/hooks/tapStopToDisconnectReporter.ts +++ b/src/hooks/tapStopToDisconnectReporter.ts @@ -4,6 +4,7 @@ import { ForkTsCheckerWebpackPluginState } from '../ForkTsCheckerWebpackPluginSt import { ReporterRpcClient } from '../reporter'; import { getForkTsCheckerWebpackPluginHooks } from './pluginHooks'; import { RpcIpcMessagePortClosedError } from '../rpc/rpc-ipc/error/RpcIpcMessagePortClosedError'; +import chalk from 'chalk'; function tapStopToDisconnectReporter( compiler: webpack.Compiler, @@ -29,14 +30,19 @@ function tapStopToDisconnectReporter( if (error instanceof RpcIpcMessagePortClosedError) { if (error.signal === 'SIGINT') { configuration.logger.issues.error( - 'Type checking and linting interrupted - If running in a docker container, this may be caused ' + - "by the container running out of memory. If so, try increasing the container's memory limit " + - 'or lowering the memoryLimit value in the ForkTsCheckerWebpackPlugin configuration.' + chalk.red( + 'Issues checking service interrupted - If running in a docker container, this may be caused ' + + "by the container running out of memory. If so, try increasing the container's memory limit " + + 'or lowering the `memoryLimit` value in the ForkTsCheckerWebpackPlugin configuration.' + ) ); } else if (error.signal === 'SIGABRT') { configuration.logger.issues.error( - 'Type checking and linting aborted - probably out of memory. ' + - 'Check `memoryLimit` option in ForkTsCheckerWebpackPlugin configuration.' + chalk.red( + 'Issues checking service aborted - probably out of memory. ' + + 'Check the `memoryLimit` option in the ForkTsCheckerWebpackPlugin configuration.\n' + + "If increasing the memory doesn't solve the issue, it's most probably a bug in the TypeScript or EsLint." + ) ); } } diff --git a/src/reporter/FilesChange.ts b/src/reporter/FilesChange.ts index e8d05d35..6dbdf801 100644 --- a/src/reporter/FilesChange.ts +++ b/src/reporter/FilesChange.ts @@ -1,10 +1,7 @@ import subtract from '../utils/array/substract'; import unique from '../utils/array/unique'; -import intersect from '../utils/array/intersect'; -import { getFilesInitialState } from './FilesInitialState'; interface FilesChange { - createdFiles?: string[]; changedFiles?: string[]; deletedFiles?: string[]; } @@ -16,35 +13,21 @@ interface FilesChange { * @returns Files change that represents all subsequent changes as a one event */ function aggregateFilesChanges(changes: FilesChange[]): FilesChange { - const { filesThatDidntExist, filesThatDidExist } = getFilesInitialState(changes); - - let createdFiles: string[] = []; let changedFiles: string[] = []; let deletedFiles: string[] = []; for (const change of changes) { - // subtract deleted files from created files - createdFiles = subtract(createdFiles, change.deletedFiles); - // add new created files if didn't exist before - createdFiles.push(...intersect(change.createdFiles, filesThatDidntExist)); - - // subtract deleted files from changed files - changedFiles = subtract(changedFiles, change.deletedFiles); - // add new created files if did exist before - changedFiles.push(...intersect(change.createdFiles, filesThatDidExist)); - // add new changed files if did exist before - changedFiles.push(...intersect(change.changedFiles, filesThatDidExist)); - - // subtract created files from deleted files - deletedFiles = subtract(deletedFiles, change.createdFiles); - // add new deleted files if did exist before - deletedFiles.push(...intersect(change.deletedFiles, filesThatDidExist)); + changedFiles = unique( + subtract(changedFiles, change.deletedFiles).concat(change.changedFiles || []) + ); + deletedFiles = unique( + subtract(deletedFiles, change.changedFiles).concat(change.deletedFiles || []) + ); } return { - createdFiles: unique(createdFiles), - changedFiles: unique(changedFiles), - deletedFiles: unique(deletedFiles), + changedFiles, + deletedFiles, }; } diff --git a/src/reporter/FilesInitialState.ts b/src/reporter/FilesInitialState.ts deleted file mode 100644 index 172b8183..00000000 --- a/src/reporter/FilesInitialState.ts +++ /dev/null @@ -1,37 +0,0 @@ -import unique from '../utils/array/unique'; -import subtract from '../utils/array/substract'; -import { FilesChange } from './FilesChange'; - -interface FilesInitialState { - filesThatDidExist: string[]; - filesThatDidntExist: string[]; -} - -/** - * Computes initial state of files based on the list of subsequent files changes - * - * @param changes List of subsequent files changes - * @returns Initial state of files that were created, changed or deleted - */ -function getFilesInitialState(changes: FilesChange[]): FilesInitialState { - // list of files that did exist before - const filesThatDidExist: string[] = []; - // list of files that didn't exist before - const filesThatDidntExist: string[] = []; - - // once the file is categorized, it can't be moved to a different category - for (const change of changes) { - // add changed and deleted files that were not registered as files that didn't exist - filesThatDidExist.push(...subtract(change.changedFiles, filesThatDidntExist)); - filesThatDidExist.push(...subtract(change.deletedFiles, filesThatDidntExist)); - // add created files that were not registered as files that did exist - filesThatDidntExist.push(...subtract(change.createdFiles, filesThatDidExist)); - } - - return { - filesThatDidExist: unique(filesThatDidExist), - filesThatDidntExist: unique(filesThatDidntExist), - }; -} - -export { getFilesInitialState, FilesInitialState }; diff --git a/src/rpc/RpcClient.ts b/src/rpc/RpcClient.ts index b763550f..5608d889 100644 --- a/src/rpc/RpcClient.ts +++ b/src/rpc/RpcClient.ts @@ -1,6 +1,12 @@ import { RpcProcedure, RpcProcedurePayload, RpcProcedureResult } from './RpcProcedure'; import { RpcMessagePort } from './RpcMessagePort'; -import { createRpcCall, getRpcMessageKey, isRpcMessage } from './RpcMessage'; +import { + createRpcCall, + getRpcMessageKey, + isRpcReturnMessage, + isRpcThrowMessage, +} from './RpcMessage'; +import { RpcRemoteError } from './error/RpcRemoteError'; interface RpcClient { readonly isConnected: () => boolean; @@ -25,15 +31,31 @@ function createRpcClient(port: RpcMessagePort): RpcClient { let isListenerRegistered = false; const returnOrThrowListener = async (message: unknown) => { - if (isRpcMessage(message) && (message.type === 'return' || message.type === 'throw')) { + if (isRpcReturnMessage(message)) { const key = getRpcMessageKey(message); const callback = callbacks.get(key); if (callback) { - callback[message.type](message.payload); + callback.return(message.payload); callbacks.delete(key); } } + if (isRpcThrowMessage(message)) { + const key = getRpcMessageKey(message); + const callback = callbacks.get(key); + + if (callback) { + callback.throw(new RpcRemoteError(message.payload.message, message.payload.stack)); + callbacks.delete(key); + } + } + }; + + const errorListener = async (error: Error) => { + callbacks.forEach((callback, key) => { + callback.throw(error); + callbacks.delete(key); + }); }; return { @@ -45,12 +67,14 @@ function createRpcClient(port: RpcMessagePort): RpcClient { if (!isListenerRegistered) { port.addMessageListener(returnOrThrowListener); + port.addErrorListener(errorListener); isListenerRegistered = true; } }, disconnect: async () => { if (isListenerRegistered) { port.removeMessageListener(returnOrThrowListener); + port.removeErrorListener(errorListener); isListenerRegistered = false; } diff --git a/src/rpc/RpcMessage.ts b/src/rpc/RpcMessage.ts index d7fed9f2..3a97c586 100644 --- a/src/rpc/RpcMessage.ts +++ b/src/rpc/RpcMessage.ts @@ -12,6 +12,10 @@ interface RpcMessage< payload: TPayload; source?: string; } +interface RpcRemoteError { + message: string; + stack?: string; +} type RpcCall = RpcMessage< 'call', TProcedure, @@ -22,11 +26,7 @@ type RpcReturn = RpcMessage< TProcedure, RpcProcedureResult >; -type RpcThrow = RpcMessage< - 'throw', - TProcedure, - TError ->; +type RpcThrow = RpcMessage<'throw', TProcedure, RpcRemoteError>; function createRpcMessage< TType extends string = string, @@ -68,8 +68,8 @@ function createRpcReturn( function createRpcThrow( procedure: TProcedure, index: number, - payload: TError -): RpcThrow { + payload: RpcRemoteError +): RpcThrow { return createRpcMessage(procedure, index, 'throw', payload); } @@ -80,6 +80,27 @@ function isRpcMessage< return !!(typeof candidate === 'object' && candidate && (candidate as { rpc: boolean }).rpc); } +function isRpcCallMessage< + TType extends string = string, + TProcedure extends RpcProcedure = RpcProcedure +>(candidate: unknown): candidate is RpcCall { + return isRpcMessage(candidate) && candidate.type === 'call'; +} + +function isRpcReturnMessage< + TType extends string = string, + TProcedure extends RpcProcedure = RpcProcedure +>(candidate: unknown): candidate is RpcReturn { + return isRpcMessage(candidate) && candidate.type === 'return'; +} + +function isRpcThrowMessage< + TType extends string = string, + TProcedure extends RpcProcedure = RpcProcedure +>(candidate: unknown): candidate is RpcThrow { + return isRpcMessage(candidate) && candidate.type === 'throw'; +} + function getRpcMessageKey(message: RpcMessage) { return `${message.procedure}_${message.id}`; } @@ -94,5 +115,8 @@ export { createRpcReturn, createRpcThrow, isRpcMessage, + isRpcCallMessage, + isRpcReturnMessage, + isRpcThrowMessage, getRpcMessageKey, }; diff --git a/src/rpc/RpcMessagePort.ts b/src/rpc/RpcMessagePort.ts index 2b61445f..2e4167d6 100644 --- a/src/rpc/RpcMessagePort.ts +++ b/src/rpc/RpcMessagePort.ts @@ -1,12 +1,16 @@ type RpcMessageDispatch = (message: TMessage) => Promise; +type RpcMessageListener = RpcMessageDispatch; +type RpcErrorListener = (error: Error) => void; interface RpcMessagePort { readonly dispatchMessage: RpcMessageDispatch; - readonly addMessageListener: (listener: RpcMessageDispatch) => void; - readonly removeMessageListener: (listener: RpcMessageDispatch) => void; + readonly addMessageListener: (listener: RpcMessageListener) => void; + readonly removeMessageListener: (listener: RpcMessageListener) => void; + readonly addErrorListener: (listener: RpcErrorListener) => void; + readonly removeErrorListener: (listener: RpcErrorListener) => void; readonly isOpen: () => boolean; readonly open: () => Promise; readonly close: () => Promise; } -export { RpcMessagePort, RpcMessageDispatch }; +export { RpcMessagePort, RpcMessageDispatch, RpcMessageListener, RpcErrorListener }; diff --git a/src/rpc/RpcService.ts b/src/rpc/RpcService.ts index 3600d7ef..8471a44e 100644 --- a/src/rpc/RpcService.ts +++ b/src/rpc/RpcService.ts @@ -1,6 +1,6 @@ import { RpcProcedure } from './RpcProcedure'; import { RpcMessagePort } from './RpcMessagePort'; -import { createRpcReturn, createRpcThrow, isRpcMessage } from './RpcMessage'; +import { createRpcReturn, createRpcThrow, isRpcCallMessage } from './RpcMessage'; // eslint-disable-next-line @typescript-eslint/no-explicit-any type RpcCallHandler = (payload: TPayload) => Promise; @@ -23,7 +23,7 @@ function createRpcService(port: RpcMessagePort): RpcService { let isListenerRegistered = false; const callListener = async (message: unknown) => { - if (isRpcMessage(message) && message.type === 'call') { + if (isRpcCallMessage(message)) { const handler = handlers.get(message.procedure); try { @@ -36,7 +36,10 @@ function createRpcService(port: RpcMessagePort): RpcService { await port.dispatchMessage(createRpcReturn(message.procedure, message.id, result)); } catch (error) { await port.dispatchMessage( - createRpcThrow(message.procedure, message.id, { ...error, message: error.toString() }) + createRpcThrow(message.procedure, message.id, { + message: error.toString(), + stack: error.stack, + }) ); } } diff --git a/src/rpc/error/RpcRemoteError.ts b/src/rpc/error/RpcRemoteError.ts new file mode 100644 index 00000000..5d9a17ec --- /dev/null +++ b/src/rpc/error/RpcRemoteError.ts @@ -0,0 +1,15 @@ +class RpcRemoteError extends Error { + constructor(message: string, readonly stack?: string) { + super(message); + } + + toString() { + if (this.stack) { + return [this.message, this.stack].join('\n'); + } else { + return this.message; + } + } +} + +export { RpcRemoteError }; diff --git a/src/rpc/rpc-event-emitter/RpcEventEmitterMessageChannel.ts b/src/rpc/rpc-event-emitter/RpcEventEmitterMessageChannel.ts deleted file mode 100644 index df8b733c..00000000 --- a/src/rpc/rpc-event-emitter/RpcEventEmitterMessageChannel.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { createRpcMessageChannel, RpcMessageChannel } from '../index'; -import { createRpcEventEmitterMessagePort } from './RpcEventEmitterMessagePort'; -import { EventEmitter } from 'events'; - -function createRpcEventEmitterMessageChannel(): RpcMessageChannel { - const serviceEmitter = new EventEmitter(); - const clientEmitter = new EventEmitter(); - - const serviceToClientForwarder = (message: unknown) => { - clientEmitter.emit('message', message); - }; - const clientToServiceForwarder = (message: unknown) => { - serviceEmitter.emit('message', message); - }; - - const servicePort = createRpcEventEmitterMessagePort(serviceEmitter); - const clientPort = createRpcEventEmitterMessagePort(clientEmitter); - - return createRpcMessageChannel( - servicePort, - clientPort, - async () => { - serviceEmitter.on('dispatch_message', serviceToClientForwarder); - clientEmitter.on('dispatch_message', clientToServiceForwarder); - }, - async () => { - serviceEmitter.off('dispatch_message', serviceToClientForwarder); - clientEmitter.off('dispatch_message', clientToServiceForwarder); - } - ); -} - -export { createRpcEventEmitterMessageChannel }; diff --git a/src/rpc/rpc-event-emitter/RpcEventEmitterMessagePort.ts b/src/rpc/rpc-event-emitter/RpcEventEmitterMessagePort.ts deleted file mode 100644 index 6ae336b6..00000000 --- a/src/rpc/rpc-event-emitter/RpcEventEmitterMessagePort.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { RpcMessageDispatch, RpcMessagePort } from '../index'; -import { EventEmitter } from 'events'; - -function createRpcEventEmitterMessagePort(emitter: EventEmitter): RpcMessagePort { - const listeners = new Set(); - - return { - dispatchMessage: async (message) => { - emitter.emit('dispatch_message', JSON.parse(JSON.stringify(message))); - }, - addMessageListener: (listener) => { - listeners.add(listener); - emitter.on('message', listener); - }, - removeMessageListener: (listener) => { - listeners.delete(listener); - emitter.off('message', listener); - }, - isOpen: () => true, - open: async () => undefined, - close: async () => { - listeners.forEach((listener) => { - emitter.off('message', listener); - listeners.delete(listener); - }); - }, - }; -} - -export { createRpcEventEmitterMessagePort }; diff --git a/src/rpc/rpc-event-emitter/index.ts b/src/rpc/rpc-event-emitter/index.ts deleted file mode 100644 index 6c720f2e..00000000 --- a/src/rpc/rpc-event-emitter/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './RpcEventEmitterMessagePort'; -export * from './RpcEventEmitterMessageChannel'; diff --git a/src/rpc/rpc-ipc/RpcIpcMessagePort.ts b/src/rpc/rpc-ipc/RpcIpcMessagePort.ts index 1849bc12..cd9499c5 100644 --- a/src/rpc/rpc-ipc/RpcIpcMessagePort.ts +++ b/src/rpc/rpc-ipc/RpcIpcMessagePort.ts @@ -1,32 +1,36 @@ import { ProcessLike } from './ProcessLike'; -import { RpcMessageDispatch, RpcMessagePort } from '../index'; +import { RpcMessagePort, RpcMessageListener, RpcErrorListener } from '../index'; import { ChildProcess, fork } from 'child_process'; import { RpcIpcMessagePortClosedError } from './error/RpcIpcMessagePortClosedError'; function createRpcIpcMessagePort(process: ProcessLike): RpcMessagePort { - const listeners = new Set(); - + const messageListeners = new Set(); + const errorListeners = new Set(); let closedError: Error | undefined; - const handleExit = async (code: string | number | null, signal: string | null) => { - await port.close(); + const handleExit = async (code: string | number | null, signal: string | null) => { closedError = new RpcIpcMessagePortClosedError( - `Process ${process.pid} exited with code ${code}.`, + code + ? `Process ${process.pid} exited with code "${code}" [${signal}]` + : `Process ${process.pid} exited [${signal}].`, code, signal ); - }; - const handleDisconnect = async () => { - await port.close(); + errorListeners.forEach((listener) => { + if (closedError) { + listener(closedError); + } + }); - closedError = new RpcIpcMessagePortClosedError( - `Process ${process.pid} has been disconnected.`, - null, - null - ); + await port.close(); + }; + const handleMessage = (message: unknown) => { + messageListeners.forEach((listener) => { + listener(message); + }); }; + process.on('message', handleMessage); process.on('exit', handleExit); - process.on('disconnect', handleDisconnect); const port: RpcMessagePort = { dispatchMessage: async (message) => @@ -48,12 +52,16 @@ function createRpcIpcMessagePort(process: ProcessLike): RpcMessagePort { } }), addMessageListener: (listener) => { - listeners.add(listener); - process.on('message', listener); + messageListeners.add(listener); }, removeMessageListener: (listener) => { - listeners.delete(listener); - process.off('message', listener); + messageListeners.delete(listener); + }, + addErrorListener: (listener) => { + errorListeners.add(listener); + }, + removeErrorListener: (listener) => { + errorListeners.delete(listener); }, isOpen: () => !!process.connected, open: async () => { @@ -64,13 +72,11 @@ function createRpcIpcMessagePort(process: ProcessLike): RpcMessagePort { } }, close: async () => { - listeners.forEach((listener) => { - process.off('message', listener); - listeners.delete(listener); - }); - + process.off('message', handleMessage); process.off('exit', handleExit); - process.off('disconnect', handleDisconnect); + + messageListeners.clear(); + errorListeners.clear(); if (process.disconnect && process.connected) { process.disconnect(); @@ -83,19 +89,62 @@ function createRpcIpcMessagePort(process: ProcessLike): RpcMessagePort { function createRpcIpcForkedProcessMessagePort( filePath: string, - memoryLimit = 2048 + memoryLimit = 2048, + autoRecreate = true ): RpcMessagePort { - let childProcess: ChildProcess | undefined = fork(filePath, [], { - execArgv: [`--max-old-space-size=${memoryLimit}`], - stdio: ['inherit', 'inherit', 'inherit', 'ipc'], - }); - const port = createRpcIpcMessagePort(childProcess); + function createChildProcess(): ChildProcess { + return fork(filePath, [], { + execArgv: [`--max-old-space-size=${memoryLimit}`], + stdio: ['inherit', 'inherit', 'inherit', 'ipc'], + }); + } + const messageListeners = new Set(); + const errorListeners = new Set(); + + let childProcess: ChildProcess | undefined = createChildProcess(); + let port = createRpcIpcMessagePort(childProcess); return { - ...port, + dispatchMessage: (message) => port.dispatchMessage(message), + addMessageListener: (listener) => { + messageListeners.add(listener); + return port.addMessageListener(listener); + }, + removeMessageListener: (listener) => { + messageListeners.delete(listener); + return port.removeMessageListener(listener); + }, + addErrorListener: (listener) => { + errorListeners.add(listener); + return port.addErrorListener(listener); + }, + removeErrorListener: (listener) => { + errorListeners.delete(listener); + return port.removeErrorListener(listener); + }, + isOpen: () => port.isOpen(), + open: async () => { + if (!port.isOpen() && autoRecreate) { + // recreate the process and add existing message listeners + childProcess = createChildProcess(); + port = createRpcIpcMessagePort(childProcess); + + messageListeners.forEach((listener) => { + port.addMessageListener(listener); + }); + errorListeners.forEach((listener) => { + port.addErrorListener(listener); + }); + } else { + return port.open(); + } + }, close: async () => { await port.close(); + messageListeners.clear(); + errorListeners.clear(); + if (childProcess) { childProcess.kill('SIGTERM'); childProcess = undefined; diff --git a/src/rpc/rpc-ipc/error/RpcIpcMessagePortClosedError.ts b/src/rpc/rpc-ipc/error/RpcIpcMessagePortClosedError.ts index 5cbe6e46..27c9284f 100644 --- a/src/rpc/rpc-ipc/error/RpcIpcMessagePortClosedError.ts +++ b/src/rpc/rpc-ipc/error/RpcIpcMessagePortClosedError.ts @@ -7,8 +7,7 @@ class RpcIpcMessagePortClosedError extends RpcMessagePortClosedError { readonly signal: string | null ) { super(message); - - Object.setPrototypeOf(this, RpcIpcMessagePortClosedError.prototype); + this.name = 'RpcIpcMessagePortClosedError'; } } diff --git a/src/typescript-reporter/TypeScriptSupport.ts b/src/typescript-reporter/TypeScriptSupport.ts index e0e81c8d..afbecaf6 100644 --- a/src/typescript-reporter/TypeScriptSupport.ts +++ b/src/typescript-reporter/TypeScriptSupport.ts @@ -1,6 +1,6 @@ import * as semver from 'semver'; -import * as fs from 'graceful-fs'; -import * as os from 'os'; +import fs from 'fs-extra'; +import os from 'os'; import { TypeScriptReporterConfiguration } from './TypeScriptReporterConfiguration'; import { assertTypeScriptPnpExtensionSupport } from './extension/pnp/TypeScriptPnpExtensionSupport'; import { assertTypeScriptVueExtensionSupport } from './extension/vue/TypeScriptVueExtensionSupport'; diff --git a/src/typescript-reporter/extension/vue/TypeScriptVueExtension.ts b/src/typescript-reporter/extension/vue/TypeScriptVueExtension.ts index 6169d1d6..2151c3c5 100644 --- a/src/typescript-reporter/extension/vue/TypeScriptVueExtension.ts +++ b/src/typescript-reporter/extension/vue/TypeScriptVueExtension.ts @@ -3,7 +3,7 @@ import { TypeScriptEmbeddedSource, } from '../TypeScriptEmbeddedExtension'; import * as vueCompiler from 'vue-template-compiler'; -import { readFileSync, existsSync } from 'fs'; +import fs from 'fs-extra'; import { TypeScriptExtension } from '../TypeScriptExtension'; import { TypeScriptVueExtensionConfiguration } from './TypeScriptVueExtensionConfiguration'; @@ -67,12 +67,12 @@ function createTypeScriptVueExtension( } function getVueEmbeddedSource(fileName: string): TypeScriptEmbeddedSource | undefined { - if (!existsSync(fileName)) { + if (!fs.existsSync(fileName)) { return undefined; } const compiler = loadVueCompiler(); - const vueSourceText = readFileSync(fileName, { encoding: 'utf-8' }); + const vueSourceText = fs.readFileSync(fileName, { encoding: 'utf-8' }); const { script } = compiler.parseComponent(vueSourceText, { pad: 'space', diff --git a/src/typescript-reporter/reporter/ControlledTypeScriptSystem.ts b/src/typescript-reporter/reporter/ControlledTypeScriptSystem.ts new file mode 100644 index 00000000..2b0da00a --- /dev/null +++ b/src/typescript-reporter/reporter/ControlledTypeScriptSystem.ts @@ -0,0 +1,214 @@ +import * as ts from 'typescript'; +import { posix } from 'path'; +import { createPassiveFileSystem } from './PassiveFileSystem'; + +interface ControlledTypeScriptSystem extends ts.System { + // control watcher + invokeFileChanged(path: string): void; + invokeFileDeleted(path: string): void; + // control cache + clearCache(): void; + // mark these methods as defined - not optional + getFileSize(path: string): number; + watchFile( + path: string, + callback: ts.FileWatcherCallback, + pollingInterval?: number, + options?: ts.WatchOptions + ): ts.FileWatcher; + watchDirectory( + path: string, + callback: ts.DirectoryWatcherCallback, + recursive?: boolean, + options?: ts.WatchOptions + ): ts.FileWatcher; + getModifiedTime(path: string): Date | undefined; + setModifiedTime(path: string, time: Date): void; + deleteFile(path: string): void; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): any; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + clearTimeout(timeoutId: any): void; + // detect when all tasks scheduled by `setTimeout` finished + waitForQueued(): Promise; +} + +function createControlledTypeScriptSystem(): ControlledTypeScriptSystem { + // watchers + const fileWatchersMap = new Map(); + const directoryWatchersMap = new Map(); + const recursiveDirectoryWatchersMap = new Map(); + const deletedFiles = new Map(); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const timeoutCallbacks = new Set(); + const caseSensitive = ts.sys.useCaseSensitiveFileNames; + const fileSystem = createPassiveFileSystem(caseSensitive); + + function createWatcher( + watchersMap: Map, + path: string, + callback: TCallback + ) { + const watchers = watchersMap.get(path) || []; + const nextWatchers = [...watchers, callback]; + watchersMap.set(path, nextWatchers); + + return { + close: () => { + const watchers = watchersMap.get(path) || []; + const nextWatchers = watchers.filter((watcher) => watcher !== callback); + + if (nextWatchers.length > 0) { + watchersMap.set(path, nextWatchers); + } else { + watchersMap.delete(path); + } + }, + }; + } + + const invokeFileWatchers = (path: string, event: ts.FileWatcherEventKind) => { + const fileWatchers = fileWatchersMap.get(path); + if (fileWatchers) { + fileWatchers.forEach((fileWatcher) => fileWatcher(path, event)); + } + }; + + const invokeDirectoryWatchers = (path: string) => { + let directory = posix.dirname(path); + + const directoryWatchers = directoryWatchersMap.get(directory); + if (directoryWatchers) { + directoryWatchers.forEach((directoryWatcher) => directoryWatcher(path)); + } + + while (directory !== posix.dirname(directory)) { + const recursiveDirectoryWatchers = recursiveDirectoryWatchersMap.get(directory); + if (recursiveDirectoryWatchers) { + recursiveDirectoryWatchers.forEach((recursiveDirectoryWatcher) => + recursiveDirectoryWatcher(path) + ); + } + + directory = posix.dirname(directory); + } + }; + + const controlledSystem: ControlledTypeScriptSystem = { + ...ts.sys, + useCaseSensitiveFileNames: caseSensitive, + fileExists(path: string): boolean { + const stats = fileSystem.readStats(path); + + return !!stats && stats.isFile(); + }, + readFile(path: string, encoding?: string): string | undefined { + return fileSystem.readFile(path, encoding); + }, + getFileSize(path: string): number { + const stats = fileSystem.readStats(path); + + return stats ? stats.size : 0; + }, + writeFile(path: string, data: string): void { + fileSystem.writeFile(path, data); + + controlledSystem.invokeFileChanged(path); + }, + deleteFile(path: string): void { + fileSystem.deleteFile(path); + + controlledSystem.invokeFileDeleted(path); + }, + directoryExists(path: string): boolean { + const stats = fileSystem.readStats(path); + + return !!stats && stats.isDirectory(); + }, + createDirectory(path: string): void { + fileSystem.createDir(path); + + invokeDirectoryWatchers(fileSystem.normalizePath(path)); + }, + getDirectories(path: string): string[] { + const dirents = fileSystem.readDir(path); + + return dirents.filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name); + }, + getModifiedTime(path: string): Date | undefined { + const stats = fileSystem.readStats(path); + + if (stats) { + return stats.mtime; + } + }, + setModifiedTime(path: string, date: Date): void { + fileSystem.updateTimes(path, date, date); + + invokeDirectoryWatchers(fileSystem.normalizePath(path)); + invokeFileWatchers(fileSystem.normalizePath(path), ts.FileWatcherEventKind.Changed); + }, + watchFile(path: string, callback: ts.FileWatcherCallback): ts.FileWatcher { + return createWatcher(fileWatchersMap, fileSystem.normalizePath(path), callback); + }, + watchDirectory( + path: string, + callback: ts.DirectoryWatcherCallback, + recursive = false + ): ts.FileWatcher { + return createWatcher( + recursive ? recursiveDirectoryWatchersMap : directoryWatchersMap, + fileSystem.normalizePath(path), + callback + ); + }, + // use immediate instead of timeout to avoid waiting 250ms for batching files changes + setTimeout: (callback, timeout, ...args) => { + const timeoutId = setImmediate(() => { + callback(...args); + timeoutCallbacks.delete(timeoutId); + }); + timeoutCallbacks.add(timeoutId); + + return timeoutId; + }, + clearTimeout: (timeoutId) => { + clearImmediate(timeoutId); + timeoutCallbacks.delete(timeoutId); + }, + async waitForQueued(): Promise { + while (timeoutCallbacks.size > 0) { + await new Promise((resolve) => setImmediate(resolve)); + } + }, + invokeFileChanged(path: string) { + const normalizedPath = fileSystem.normalizePath(path); + + invokeDirectoryWatchers(normalizedPath); + + if (deletedFiles.get(normalizedPath)) { + invokeFileWatchers(normalizedPath, ts.FileWatcherEventKind.Created); + deletedFiles.set(normalizedPath, false); + } else { + invokeFileWatchers(normalizedPath, ts.FileWatcherEventKind.Changed); + } + }, + invokeFileDeleted(path: string) { + const normalizedPath = fileSystem.normalizePath(path); + + if (!deletedFiles.get(normalizedPath)) { + invokeDirectoryWatchers(normalizedPath); + invokeFileWatchers(normalizedPath, ts.FileWatcherEventKind.Deleted); + + deletedFiles.set(normalizedPath, true); + } + }, + clearCache() { + fileSystem.clearCache(); + }, + }; + + return controlledSystem; +} + +export { createControlledTypeScriptSystem, ControlledTypeScriptSystem }; diff --git a/src/typescript-reporter/reporter/ControlledWatchCompilerHost.ts b/src/typescript-reporter/reporter/ControlledWatchCompilerHost.ts index 36a9a86d..0dd8493e 100644 --- a/src/typescript-reporter/reporter/ControlledWatchCompilerHost.ts +++ b/src/typescript-reporter/reporter/ControlledWatchCompilerHost.ts @@ -1,23 +1,18 @@ -import { dirname } from 'path'; import * as ts from 'typescript'; import { TypeScriptHostExtension } from '../extension/TypeScriptExtension'; -import { ControlledWatchHost } from './ControlledWatchHost'; - -interface ControlledWatchCompilerHost - extends ts.WatchCompilerHostOfConfigFile, - ControlledWatchHost {} +import { ControlledTypeScriptSystem } from './ControlledTypeScriptSystem'; function createControlledWatchCompilerHost( configFileName: string, optionsToExtend: ts.CompilerOptions | undefined, - system: ts.System, + system: ControlledTypeScriptSystem, createProgram?: ts.CreateProgram, reportDiagnostic?: ts.DiagnosticReporter, reportWatchStatus?: ts.WatchStatusReporter, afterProgramCreate?: (program: TProgram) => void, hostExtensions: TypeScriptHostExtension[] = [] -): ControlledWatchCompilerHost { - const watchCompilerHost = ts.createWatchCompilerHost( +): ts.WatchCompilerHostOfConfigFile { + const baseWatchCompilerHost = ts.createWatchCompilerHost( configFileName, optionsToExtend, system, @@ -26,54 +21,23 @@ function createControlledWatchCompilerHost( reportWatchStatus ); - const fileWatchers = new Map(); - const directoryWatchers = new Map(); - const recursiveDirectoryWatchers = new Map(); - const sourceFileCache = new Map(); - const parsedCommendLine = ts.getParsedCommandLineOfConfigFile( configFileName, optionsToExtend || {}, { - fileExists: watchCompilerHost.fileExists, - readFile: watchCompilerHost.readFile, - readDirectory: watchCompilerHost.readDirectory, - useCaseSensitiveFileNames: watchCompilerHost.useCaseSensitiveFileNames(), - getCurrentDirectory: watchCompilerHost.getCurrentDirectory, - trace: watchCompilerHost.trace, + fileExists: baseWatchCompilerHost.fileExists, + readFile: baseWatchCompilerHost.readFile, + readDirectory: baseWatchCompilerHost.readDirectory, + useCaseSensitiveFileNames: baseWatchCompilerHost.useCaseSensitiveFileNames(), + getCurrentDirectory: baseWatchCompilerHost.getCurrentDirectory, + trace: baseWatchCompilerHost.trace, // it's already registered in the watchCompilerHost onUnRecoverableConfigFileDiagnostic: () => null, } ); - const invokeFileWatchers = (path: string, event: ts.FileWatcherEventKind) => { - const fileWatcher = fileWatchers.get(path); - - if (fileWatcher) { - fileWatcher(path, event); - } - }; - - const invokeDirectoryWatchers = (path: string) => { - let key = dirname(path.toLowerCase()); - - const directoryWatcher = directoryWatchers.get(key); - if (directoryWatcher) { - directoryWatcher(path); - } - - while (key !== dirname(key)) { - const recursiveDirectoryWatcher = recursiveDirectoryWatchers.get(key); - if (recursiveDirectoryWatcher) { - recursiveDirectoryWatcher(path); - } - - key = dirname(key); - } - }; - - let controlledWatchCompilerHost: ControlledWatchCompilerHost = { - ...watchCompilerHost, + let controlledWatchCompilerHost: ts.WatchCompilerHostOfConfigFile = { + ...baseWatchCompilerHost, createProgram( rootNames: ReadonlyArray | undefined, options: ts.CompilerOptions | undefined, @@ -99,7 +63,7 @@ function createControlledWatchCompilerHost( } }); - return watchCompilerHost.createProgram( + return baseWatchCompilerHost.createProgram( rootNames, options, compilerHost, @@ -108,69 +72,30 @@ function createControlledWatchCompilerHost( projectReferences ); }, - onWatchStatusChange(): void { - // do nothing - }, afterProgramCreate(program) { if (afterProgramCreate) { afterProgramCreate(program); } }, - watchFile(path: string, callback: ts.FileWatcherCallback): ts.FileWatcher { - const key = path.toLowerCase(); - fileWatchers.set(key, callback); - - return { - close: () => fileWatchers.delete(key), - }; - }, - watchDirectory( - path: string, - callback: ts.DirectoryWatcherCallback, - recursive = false - ): ts.FileWatcher { - const key = path.toLowerCase(); - - if (recursive) { - recursiveDirectoryWatchers.set(key, callback); - return { - close: () => recursiveDirectoryWatchers.delete(key), - }; - } else { - directoryWatchers.set(key, callback); - return { - close: () => directoryWatchers.delete(key), - }; - } - }, - // use immediate instead of timeout to avoid waiting 250ms for batching files changes - setTimeout: (callback, timeout, ...args) => setImmediate(() => callback(...args)), - clearTimeout: (timeoutId) => clearImmediate(timeoutId), - invokeFileCreated(path: string) { - sourceFileCache.delete(path); - - invokeDirectoryWatchers(path); - invokeFileWatchers(path, ts.FileWatcherEventKind.Created); - }, - invokeFileChanged(path: string) { - sourceFileCache.delete(path); - - invokeDirectoryWatchers(path); - invokeFileWatchers(path, ts.FileWatcherEventKind.Changed); - }, - invokeFileDeleted(path: string) { - sourceFileCache.delete(path); - - invokeDirectoryWatchers(path); - invokeFileWatchers(path, ts.FileWatcherEventKind.Deleted); + onWatchStatusChange(): void { + // do nothing }, + watchFile: system.watchFile, + watchDirectory: system.watchDirectory, + setTimeout: system.setTimeout, + clearTimeout: system.clearTimeout, + fileExists: system.fileExists, + readFile: system.readFile, + directoryExists: system.directoryExists, + getDirectories: system.getDirectories, + realpath: system.realpath, }; hostExtensions.forEach((hostExtension) => { if (hostExtension.extendWatchCompilerHost) { controlledWatchCompilerHost = hostExtension.extendWatchCompilerHost< TProgram, - ControlledWatchCompilerHost + ts.WatchCompilerHostOfConfigFile >(controlledWatchCompilerHost, parsedCommendLine); } }); @@ -178,4 +103,4 @@ function createControlledWatchCompilerHost( return controlledWatchCompilerHost; } -export { createControlledWatchCompilerHost, ControlledWatchCompilerHost }; +export { createControlledWatchCompilerHost }; diff --git a/src/typescript-reporter/reporter/ControlledWatchHost.ts b/src/typescript-reporter/reporter/ControlledWatchHost.ts deleted file mode 100644 index d6d96265..00000000 --- a/src/typescript-reporter/reporter/ControlledWatchHost.ts +++ /dev/null @@ -1,7 +0,0 @@ -interface ControlledWatchHost { - invokeFileCreated: (path: string) => void; - invokeFileChanged: (path: string) => void; - invokeFileDeleted: (path: string) => void; -} - -export { ControlledWatchHost }; diff --git a/src/typescript-reporter/reporter/ControlledWatchSolutionBuilderHost.ts b/src/typescript-reporter/reporter/ControlledWatchSolutionBuilderHost.ts index fb78fb93..a1ccddc9 100644 --- a/src/typescript-reporter/reporter/ControlledWatchSolutionBuilderHost.ts +++ b/src/typescript-reporter/reporter/ControlledWatchSolutionBuilderHost.ts @@ -1,17 +1,12 @@ import * as ts from 'typescript'; -import fs from 'graceful-fs'; import { createControlledWatchCompilerHost } from './ControlledWatchCompilerHost'; -import { ControlledWatchHost } from './ControlledWatchHost'; import { TypeScriptHostExtension } from '../extension/TypeScriptExtension'; - -interface ControlledWatchSolutionBuilderHost - extends ts.SolutionBuilderWithWatchHost, - ControlledWatchHost {} +import { ControlledTypeScriptSystem } from './ControlledTypeScriptSystem'; function createControlledWatchSolutionBuilderHost( configFileName: string, optionsToExtend: ts.CompilerOptions | undefined, - system: ts.System, + system: ControlledTypeScriptSystem, createProgram?: ts.CreateProgram, reportDiagnostic?: ts.DiagnosticReporter, reportWatchStatus?: ts.WatchStatusReporter, @@ -19,7 +14,7 @@ function createControlledWatchSolutionBuilderHost void, afterProgramEmitAndDiagnostics?: (program: TProgram) => void, hostExtensions: TypeScriptHostExtension[] = [] -): ControlledWatchSolutionBuilderHost { +): ts.SolutionBuilderWithWatchHost { const controlledWatchCompilerHost = createControlledWatchCompilerHost( configFileName, optionsToExtend, @@ -31,35 +26,8 @@ function createControlledWatchSolutionBuilderHost = { + let controlledWatchSolutionBuilderHost: ts.SolutionBuilderWithWatchHost = { ...controlledWatchCompilerHost, - writeFile(path: string, data: string, writeByteOrderMark?: boolean): void { - // return ts.sys.writeFile(fileName, data, writeByteOrderMark); - }, - deleteFile(path: string): void { - // if (ts.sys.deleteFile) { - // ts.sys.deleteFile(fileName); - // } else { - // fs.unlinkSync(fileName); - // } - }, - createDirectory(path: string): void { - // do nothing - }, - getModifiedTime(fileName: string): Date | undefined { - if (ts.sys.getModifiedTime) { - return ts.sys.getModifiedTime(fileName); - } else { - return fs.statSync(fileName).mtime; - } - }, - setModifiedTime(path: string, date: Date): void { - // if (ts.sys.setModifiedTime) { - // ts.sys.setModifiedTime(fileName, date); - // } else { - // fs.utimesSync(fileName, date, date); - // } - }, reportDiagnostic(diagnostic: ts.Diagnostic): void { if (reportDiagnostic) { reportDiagnostic(diagnostic); @@ -75,6 +43,21 @@ function createControlledWatchSolutionBuilderHost null, } ); @@ -96,7 +79,7 @@ function createControlledWatchSolutionBuilderHost + ts.SolutionBuilderWithWatchHost >(controlledWatchSolutionBuilderHost, parsedCommendLine); } }); @@ -104,4 +87,4 @@ function createControlledWatchSolutionBuilderHost(); + const fsReadStatsCache = new Map(); + const fsReadFileCache = new Map(); + const fsReadDirCache = new Map(); + const fsRealPathCache = new Map(); + + function normalizePath(path: string): string { + return caseSensitive ? normalize(path) : normalize(path).toLowerCase(); + } + + // read methods + function fsExists(path: string): boolean { + if (!fsExistsCache.has(path)) { + fsExistsCache.set(path, fs.existsSync(path)); + } + + return !!fsExistsCache.get(path); + } + + function memExists(path: string): boolean { + return mem.existsSync(normalizePath(path)); + } + + function fsReadStats(path: string): Stats | undefined { + if (!fsReadStatsCache.has(path)) { + if (fsExists(path)) { + fsReadStatsCache.set(path, fs.statSync(path)); + } + } + + return fsReadStatsCache.get(path); + } + + function memReadStats(path: string): Stats | undefined { + return memExists(path) ? mem.statSync(normalizePath(path)) : undefined; + } + + function fsReadFile(path: string, encoding?: string): string | undefined { + if (!fsReadFileCache.has(path)) { + if (fsExists(path)) { + fsReadFileCache.set(path, fs.readFileSync(path, { encoding }).toString()); + } else { + fsReadFileCache.set(path, undefined); + } + } + + return fsReadFileCache.get(path); + } + + function memReadFile(path: string, encoding?: string): string | undefined { + if (memExists(path)) { + return mem + .readFileSync(normalizePath(path), { encoding: encoding as BufferEncoding }) + .toString(); + } + } + + function fsReadDir(path: string): Dirent[] { + if (!fsReadDirCache.has(path)) { + if (fsExists(path)) { + fsReadDirCache.set(path, fs.readdirSync(path, { withFileTypes: true })); + } else { + fsReadDirCache.set(path, []); + } + } + + return fsReadDirCache.get(path) || []; + } + + function memReadDir(path: string): Dirent[] { + if (memExists(path)) { + return mem.readdirSync(normalizePath(path), { withFileTypes: true }) as Dirent[]; + } + + return []; + } + + function exists(path: string) { + return fsExists(path) || memExists(path); + } + + function readFile(path: string, encoding?: string) { + const fsStats = fsReadStats(path); + const memStats = memReadStats(path); + + if (fsStats && memStats) { + return fsStats.mtimeMs > memStats.mtimeMs + ? fsReadFile(path, encoding) + : memReadFile(path, encoding); + } else if (fsStats) { + return fsReadFile(path, encoding); + } else if (memStats) { + return memReadFile(path, encoding); + } + } + + function readDir(path: string) { + const fsDirents = fsReadDir(path); + const memDirents = memReadDir(path); + + // merge list of dirents from fs and mem + return fsDirents + .filter((fsDirent) => !memDirents.some((memDirent) => memDirent.name === fsDirent.name)) + .concat(memDirents); + } + + function readStats(path: string) { + const fsStats = fsReadStats(path); + const memStats = memReadStats(path); + + if (fsStats && memStats) { + return fsStats.mtimeMs > memStats.mtimeMs ? fsStats : memStats; + } else if (fsStats) { + return fsStats; + } else if (memStats) { + return memStats; + } + } + + function getRealPath(path: string) { + if (!fsRealPathCache.has(path)) { + let base = path; + let nested = ''; + + while (base !== dirname(base)) { + if (fsExists(base)) { + fsRealPathCache.set(path, join(fs.realpathSync(base), nested)); + break; + } + + nested = join(basename(base), nested); + base = dirname(base); + } + } + + return fsRealPathCache.get(path) || path; + } + + function createDir(path: string) { + mem.mkdirSync(normalizePath(path), { recursive: true }); + } + + function writeFile(path: string, data: string) { + if (!memExists(dirname(path))) { + createDir(dirname(path)); + } + + mem.writeFileSync(normalizePath(path), data); + } + + function deleteFile(path: string) { + if (memExists(path)) { + mem.unlinkSync(normalizePath(path)); + } + } + + function updateTimes(path: string, atime: Date, mtime: Date) { + if (memExists(path)) { + mem.utimesSync(normalizePath(path), atime, mtime); + } + } + + return { + exists(path: string) { + return exists(getRealPath(path)); + }, + readFile(path: string, encoding?: string) { + return readFile(getRealPath(path), encoding); + }, + readDir(path: string) { + return readDir(getRealPath(path)); + }, + readStats(path: string) { + return readStats(getRealPath(path)); + }, + realPath(path: string) { + return getRealPath(path); + }, + normalizePath(path: string) { + return normalizePath(path); + }, + writeFile(path: string, data: string) { + writeFile(getRealPath(path), data); + }, + deleteFile(path: string) { + deleteFile(getRealPath(path)); + }, + createDir(path: string) { + createDir(getRealPath(path)); + }, + updateTimes(path: string, atime: Date, mtime: Date) { + updateTimes(getRealPath(path), atime, mtime); + }, + clearCache() { + fsExistsCache.clear(); + fsReadStatsCache.clear(); + fsReadFileCache.clear(); + fsReadDirCache.clear(); + fsRealPathCache.clear(); + }, + }; +} + +export { createPassiveFileSystem, PassiveFileSystem }; diff --git a/src/typescript-reporter/reporter/TypeScriptReporter.ts b/src/typescript-reporter/reporter/TypeScriptReporter.ts index 11b016f7..86ba38ba 100644 --- a/src/typescript-reporter/reporter/TypeScriptReporter.ts +++ b/src/typescript-reporter/reporter/TypeScriptReporter.ts @@ -4,15 +4,28 @@ import { createIssuesFromTsDiagnostics } from '../issue/TypeScriptIssueFactory'; import { TypeScriptReporterConfiguration } from '../TypeScriptReporterConfiguration'; import { createControlledWatchCompilerHost } from './ControlledWatchCompilerHost'; import { TypeScriptExtension } from '../extension/TypeScriptExtension'; -import { createTypeScriptReporterState, TypeScriptReporterState } from './TypeScriptReporterState'; import { createTypeScriptVueExtension } from '../extension/vue/TypeScriptVueExtension'; import { createTypeScriptPnpExtension } from '../extension/pnp/TypeScriptPnpExtension'; import { createControlledWatchSolutionBuilderHost } from './ControlledWatchSolutionBuilderHost'; -import { ControlledWatchHost } from './ControlledWatchHost'; +import { + ControlledTypeScriptSystem, + createControlledTypeScriptSystem, +} from './ControlledTypeScriptSystem'; function createTypeScriptReporter(configuration: TypeScriptReporterConfiguration): Reporter { const extensions: TypeScriptExtension[] = []; - const state: TypeScriptReporterState = createTypeScriptReporterState(); + + let system: ControlledTypeScriptSystem | undefined; + let watchCompilerHost: + | ts.WatchCompilerHostOfConfigFile + | undefined; + let watchSolutionBuilderHost: + | ts.SolutionBuilderWithWatchHost + | undefined; + let watchProgram: ts.WatchOfConfigFile | undefined; + let solutionBuilder: ts.SolutionBuilder | undefined; + + const diagnosticsPerProject = new Map(); if (configuration.extensions.vue.enabled) { extensions.push(createTypeScriptVueExtension(configuration.extensions.vue)); @@ -22,14 +35,19 @@ function createTypeScriptReporter(configuration: TypeScriptReporterConfiguration } function getProjectNameOfBuilderProgram(builderProgram: ts.BuilderProgram): string { - // TODO: it's not a public API - ensure support on different TypeScript versions return (builderProgram.getProgram().getCompilerOptions().configFilePath as unknown) as string; } function getDiagnosticsOfBuilderProgram(builderProgram: ts.BuilderProgram) { const diagnostics: ts.Diagnostic[] = []; - diagnostics.push(...builderProgram.getConfigFileParsingDiagnostics()); + if (typeof builderProgram.getConfigFileParsingDiagnostics === 'function') { + diagnostics.push(...builderProgram.getConfigFileParsingDiagnostics()); + } + if (typeof builderProgram.getOptionsDiagnostics === 'function') { + diagnostics.push(...builderProgram.getOptionsDiagnostics()); + } + if (configuration.diagnosticOptions.syntactic) { diagnostics.push(...builderProgram.getSyntacticDiagnostics()); } @@ -46,34 +64,23 @@ function createTypeScriptReporter(configuration: TypeScriptReporterConfiguration return diagnostics; } - async function invokeFilesChangeOnControlledHost( - controlledHost: ControlledWatchHost, - { createdFiles = [], changedFiles = [], deletedFiles = [] }: FilesChange - ) { - createdFiles.forEach((createdFile) => { - controlledHost.invokeFileCreated(createdFile); - }); - changedFiles.forEach((changedFile) => { - controlledHost.invokeFileChanged(changedFile); - }); - deletedFiles.forEach((removedFile) => { - controlledHost.invokeFileDeleted(removedFile); - }); - - // wait for watch events to be propagated - await new Promise((resolve) => setImmediate(resolve)); - } - return { - getReport: async (filesChange) => { + getReport: async ({ changedFiles = [], deletedFiles = [] }: FilesChange) => { + if (!system) { + system = createControlledTypeScriptSystem(); + } + + // clear cache to be ready for next iteration and to free memory + system.clearCache(); + if (configuration.build) { // solution builder case // ensure watch solution builder host exists - if (!state.watchSolutionBuilderHost) { - state.watchSolutionBuilderHost = createControlledWatchSolutionBuilderHost( + if (!watchSolutionBuilderHost) { + watchSolutionBuilderHost = createControlledWatchSolutionBuilderHost( configuration.tsconfig, configuration.compilerOptions as ts.CompilerOptions, // assume that these are valid ts.CompilerOptions - ts.sys, + system, ts.createSemanticDiagnosticsBuilderProgram, undefined, undefined, @@ -84,38 +91,32 @@ function createTypeScriptReporter(configuration: TypeScriptReporterConfiguration const diagnostics = getDiagnosticsOfBuilderProgram(builderProgram); // update diagnostics - state.diagnosticsPreProject[projectName] = diagnostics; + diagnosticsPerProject.set(projectName, diagnostics); }, extensions ); - state.solutionBuilder = undefined; + solutionBuilder = undefined; } // ensure solution builder exists - if (!state.solutionBuilder) { - state.solutionBuilder = ts.createSolutionBuilderWithWatch( - state.watchSolutionBuilderHost, + if (!solutionBuilder) { + solutionBuilder = ts.createSolutionBuilderWithWatch( + watchSolutionBuilderHost, [configuration.tsconfig], { incremental: true, - verbose: true, } ); - state.solutionBuilder.build(); + solutionBuilder.build(); } - - // invoke files changes on the host - await invokeFilesChangeOnControlledHost(state.watchSolutionBuilderHost, filesChange); - - // await new Promise((resolve) => setTimeout(resolve, 200)); } else { // watch compiler case // ensure watch compiler host exists - if (!state.watchCompilerHost) { - state.watchCompilerHost = createControlledWatchCompilerHost( + if (!watchCompilerHost) { + watchCompilerHost = createControlledWatchCompilerHost( configuration.tsconfig, configuration.compilerOptions as ts.CompilerOptions, // assume that these are valid ts.CompilerOptions - ts.sys, + system, ts.createSemanticDiagnosticsBuilderProgram, undefined, undefined, @@ -124,27 +125,38 @@ function createTypeScriptReporter(configuration: TypeScriptReporterConfiguration const diagnostics = getDiagnosticsOfBuilderProgram(builderProgram); // update diagnostics - state.diagnosticsPreProject[projectName] = diagnostics; + diagnosticsPerProject.set(projectName, diagnostics); }, extensions ); - state.watchProgram = undefined; + watchProgram = undefined; } // ensure watch program exists - if (!state.watchProgram) { - state.watchProgram = ts.createWatchProgram(state.watchCompilerHost); + if (!watchProgram) { + watchProgram = ts.createWatchProgram(watchCompilerHost); } - - // invoke files changes on the host - await invokeFilesChangeOnControlledHost(state.watchCompilerHost, filesChange); } + changedFiles.forEach((changedFile) => { + if (system) { + system.invokeFileChanged(changedFile); + } + }); + deletedFiles.forEach((removedFile) => { + if (system) { + system.invokeFileDeleted(removedFile); + } + }); + + // wait for all queued events to be processed + await system.waitForQueued(); + // aggregate all diagnostics and map them to issues - const diagnostics = Object.keys(state.diagnosticsPreProject).reduce( - (allDiagnostics, project) => [...allDiagnostics, ...state.diagnosticsPreProject[project]], - [] - ); + const diagnostics: ts.Diagnostic[] = []; + diagnosticsPerProject.forEach((projectDiagnostics) => { + diagnostics.push(...projectDiagnostics); + }); let issues = createIssuesFromTsDiagnostics(diagnostics); extensions.forEach((extension) => { diff --git a/src/typescript-reporter/reporter/TypeScriptReporterRpcClient.ts b/src/typescript-reporter/reporter/TypeScriptReporterRpcClient.ts index 8e7778e0..9712b7cf 100644 --- a/src/typescript-reporter/reporter/TypeScriptReporterRpcClient.ts +++ b/src/typescript-reporter/reporter/TypeScriptReporterRpcClient.ts @@ -1,13 +1,7 @@ import * as path from 'path'; import { TypeScriptReporterConfiguration } from '../TypeScriptReporterConfiguration'; -import { - createReporterRpcClient, - registerReporterRpcService, - ReporterRpcClient, -} from '../../reporter'; +import { createReporterRpcClient, ReporterRpcClient } from '../../reporter'; import { createRpcIpcMessageChannel } from '../../rpc/rpc-ipc'; -import { createRpcEventEmitterMessageChannel } from '../../rpc/rpc-event-emitter'; -import { createTypeScriptReporter } from './TypeScriptReporter'; function createTypeScriptReporterRpcClient( configuration: TypeScriptReporterConfiguration @@ -20,17 +14,4 @@ function createTypeScriptReporterRpcClient( return createReporterRpcClient(channel, configuration); } -function createTypeScriptReporterSameProcessRpcClient( - configuration: TypeScriptReporterConfiguration -): ReporterRpcClient { - const channel = createRpcEventEmitterMessageChannel(); - const service = registerReporterRpcService( - channel.servicePort, - (configuration) => createTypeScriptReporter(configuration) - ); - service.open(); - - return createReporterRpcClient(channel, configuration); -} - -export { createTypeScriptReporterRpcClient, createTypeScriptReporterSameProcessRpcClient }; +export { createTypeScriptReporterRpcClient }; diff --git a/src/typescript-reporter/reporter/TypeScriptReporterState.ts b/src/typescript-reporter/reporter/TypeScriptReporterState.ts deleted file mode 100644 index f1662cc1..00000000 --- a/src/typescript-reporter/reporter/TypeScriptReporterState.ts +++ /dev/null @@ -1,28 +0,0 @@ -import * as ts from 'typescript'; -import { ControlledWatchCompilerHost } from './ControlledWatchCompilerHost'; -import { ControlledWatchSolutionBuilderHost } from './ControlledWatchSolutionBuilderHost'; - -/** - * Contains all information that are passed between `run` calls - */ -interface TypeScriptReporterState { - watchCompilerHost?: ControlledWatchCompilerHost; - watchSolutionBuilderHost?: ControlledWatchSolutionBuilderHost< - ts.SemanticDiagnosticsBuilderProgram - >; - watchProgram?: ts.WatchOfConfigFile; - solutionBuilder?: ts.SolutionBuilder; - diagnosticsPreProject: Record; -} - -function createTypeScriptReporterState(): TypeScriptReporterState { - return { - watchCompilerHost: undefined, - watchSolutionBuilderHost: undefined, - watchProgram: undefined, - solutionBuilder: undefined, - diagnosticsPreProject: {}, - }; -} - -export { TypeScriptReporterState, createTypeScriptReporterState }; diff --git a/src/utils/fs/isFileJustCreated.ts b/src/utils/fs/isFileJustCreated.ts deleted file mode 100644 index 4d67f3ef..00000000 --- a/src/utils/fs/isFileJustCreated.ts +++ /dev/null @@ -1,9 +0,0 @@ -import fs from 'graceful-fs'; - -function isFileJustCreated(fileName: string): boolean { - const stat = fs.statSync(fileName); - - return stat.birthtimeMs === stat.mtimeMs; -} - -export default isFileJustCreated; diff --git a/test/e2e/EsLint.spec.ts b/test/e2e/EsLint.spec.ts new file mode 100644 index 00000000..ccd136ad --- /dev/null +++ b/test/e2e/EsLint.spec.ts @@ -0,0 +1,124 @@ +import { join } from 'path'; +import { readFixture } from './sandbox/Fixture'; +import { Sandbox, createSandbox, FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION } from './sandbox/Sandbox'; +import { + createWebpackDevServerDriver, + WEBPACK_CLI_VERSION, + WEBPACK_DEV_SERVER_VERSION, +} from './sandbox/WebpackDevServerDriver'; + +describe('EsLint', () => { + let sandbox: Sandbox; + + beforeAll(async () => { + sandbox = await createSandbox(); + }); + + beforeEach(async () => { + await sandbox.reset(); + }); + + afterAll(async () => { + await sandbox.cleanup(); + }); + + it.each([ + { async: false, webpack: '4.0.0' }, + { async: true, webpack: '^4.0.0' }, + { async: false, webpack: '^5.0.0-beta.16' }, + { async: true, webpack: '^5.0.0-beta.16' }, + ])('reports lint error for %p', async ({ async, webpack }) => { + await sandbox.load( + await readFixture(join(__dirname, 'fixtures/eslint-basic.fixture'), { + FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION, + TS_LOADER_VERSION: '^5.0.0', + TYPESCRIPT_VERSION: '~3.8.0', + WEBPACK_VERSION: webpack, + WEBPACK_CLI_VERSION, + WEBPACK_DEV_SERVER_VERSION, + ASYNC: async ? 'true' : 'false', + }) + ); + + const driver = createWebpackDevServerDriver( + sandbox.spawn('yarn exec webpack-dev-server'), + async + ); + let errors: string[]; + + // first compilation contains 2 warnings + errors = await driver.waitForErrors(); + expect(errors).toEqual([ + [ + 'WARNING in src/authenticate.ts 14:34-37', + '@typescript-eslint/no-explicit-any: Unexpected any. Specify a different type.', + ' 12 | }', + ' 13 | ', + ' > 14 | async function logout(): Promise {', + ' | ^^^', + ' 15 | const response = await fetch(', + " 16 | '/logout',", + ' 17 | {', + ].join('\n'), + [ + 'WARNING in src/index.ts 31:44-49', + "@typescript-eslint/no-unused-vars: 'event' is defined but never used.", + ' 29 | }', + ' 30 | });', + " > 31 | loginForm.addEventListener('submit', async event => {", + ' | ^^^^^', + ' 32 | const user = await login(email, password);', + ' 33 | ', + " 34 | if (user.role === 'admin') {", + ].join('\n'), + ]); + + // fix these issues + await sandbox.patch( + 'src/authenticate.ts', + 'async function logout(): Promise {', + 'async function logout(): Promise {' + ); + await sandbox.patch( + 'src/index.ts', + "loginForm.addEventListener('submit', async event => {", + "loginForm.addEventListener('submit', async () => {" + ); + + // next iteration should have no errors + await driver.waitForNoErrors(); + + // add a new error + await sandbox.patch( + 'src/index.ts', + "let password = '';", + "let password = ''\nlet temporary: any;" + ); + + errors = await driver.waitForErrors(); + expect(errors).toEqual([ + [ + 'WARNING in src/index.ts 20:5-19', + "@typescript-eslint/no-unused-vars: 'temporary' is defined but never used.", + " 18 | let email = '';", + " 19 | let password = ''", + ' > 20 | let temporary: any;', + ' | ^^^^^^^^^^^^^^', + ' 21 | ', + " 22 | emailInput.addEventListener('change', event => {", + ' 23 | if (event.target instanceof HTMLInputElement) {', + ].join('\n'), + [ + 'WARNING in src/index.ts 20:16-19', + '@typescript-eslint/no-explicit-any: Unexpected any. Specify a different type.', + " 18 | let email = '';", + " 19 | let password = ''", + ' > 20 | let temporary: any;', + ' | ^^^', + ' 21 | ', + " 22 | emailInput.addEventListener('change', event => {", + ' 23 | if (event.target instanceof HTMLInputElement) {', + ].join('\n'), + ]); + }); +}); diff --git a/test/e2e/PluginOutOfMemory.spec.ts b/test/e2e/PluginOutOfMemory.spec.ts new file mode 100644 index 00000000..21bb6b5a --- /dev/null +++ b/test/e2e/PluginOutOfMemory.spec.ts @@ -0,0 +1,72 @@ +import { join } from 'path'; +import { createSandbox, FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION, Sandbox } from './sandbox/Sandbox'; +import { readFixture } from './sandbox/Fixture'; +import { createGenericProcessDriver } from './sandbox/GenericProcessDriver'; + +describe('ForkTsCheckerWebpackPlugin Out Of Memory', () => { + let sandbox: Sandbox; + + beforeAll(async () => { + sandbox = await createSandbox(); + }); + + beforeEach(async () => { + await sandbox.reset(); + }); + + afterAll(async () => { + await sandbox.cleanup(); + }); + + it.each([ + { async: false, webpack: '4.0.0' }, + { async: true, webpack: '^4.0.0' }, + { async: false, webpack: '^5.0.0-beta.16' }, + { async: true, webpack: '^5.0.0-beta.16' }, + ])('handles out of memory for %p', async ({ async, webpack }) => { + await sandbox.load( + await readFixture(join(__dirname, 'fixtures/typescript-basic.fixture'), { + FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION, + TS_LOADER_VERSION: '^5.0.0', + TYPESCRIPT_VERSION: '~3.8.0', + WEBPACK_VERSION: webpack, + WEBPACK_CLI_VERSION: '^3.3.11', + WEBPACK_DEV_SERVER_VERSION: '^3.10.3', + ASYNC: async ? 'true' : 'false', + }) + ); + + await sandbox.patch( + 'webpack.config.js', + ' new ForkTsCheckerWebpackPlugin({', + [ + ' new ForkTsCheckerWebpackPlugin({', + ' typescript: {', + ' enabled: true,', + ' memoryLimit: 10,', + ' },', + ].join('\n') + ); + + const driver = createGenericProcessDriver(sandbox.spawn('yarn exec webpack-dev-server')); + + // we should see an error message about out of memory + await driver.waitForStderrIncludes( + 'Issues checking service aborted - probably out of memory. Check the `memoryLimit` option in the ForkTsCheckerWebpackPlugin configuration.\n' + + "If increasing the memory doesn't solve the issue, it's most probably a bug in the TypeScript or EsLint." + ); + + // let's modify one file to check if plugin will try to restart the service + await sandbox.patch( + 'src/index.ts', + "import { getUserName } from './model/User';", + "import { getUserName } from './model/User';\n" + ); + + // we should see an error message about out of memory again + await driver.waitForStderrIncludes( + 'Issues checking service aborted - probably out of memory. Check the `memoryLimit` option in the ForkTsCheckerWebpackPlugin configuration.\n' + + "If increasing the memory doesn't solve the issue, it's most probably a bug in the TypeScript or EsLint." + ); + }); +}); diff --git a/test/e2e/TypeScriptSolutionBuilderApi.spec.ts b/test/e2e/TypeScriptSolutionBuilderApi.spec.ts new file mode 100644 index 00000000..8e5e1e56 --- /dev/null +++ b/test/e2e/TypeScriptSolutionBuilderApi.spec.ts @@ -0,0 +1,105 @@ +import { join } from 'path'; +import { readFixture } from './sandbox/Fixture'; +import { Sandbox, createSandbox, FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION } from './sandbox/Sandbox'; +import { + createWebpackDevServerDriver, + WEBPACK_CLI_VERSION, + WEBPACK_DEV_SERVER_VERSION, +} from './sandbox/WebpackDevServerDriver'; + +describe('TypeScript SolutionBuilder API', () => { + describe('semantic error', () => { + let sandbox: Sandbox; + + beforeAll(async () => { + sandbox = await createSandbox(); + }); + + beforeEach(async () => { + await sandbox.reset(); + }); + + afterAll(async () => { + await sandbox.cleanup(); + }); + + it.each([{ async: false }, { async: true }])( + 'reports semantic error for %p', + async ({ async }) => { + await sandbox.load( + await readFixture(join(__dirname, 'fixtures/typescript-project-references.fixture'), { + FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION, + TS_LOADER_VERSION: '^7.0.1', + TYPESCRIPT_VERSION: '~3.8.0', + WEBPACK_VERSION: '^4.0.0', + WEBPACK_CLI_VERSION, + WEBPACK_DEV_SERVER_VERSION, + ASYNC: async ? 'true' : 'false', + }) + ); + + const driver = createWebpackDevServerDriver( + sandbox.spawn('yarn exec webpack-dev-server'), + async + ); + let errors: string[]; + + // initial compilation should be successful + await driver.waitForNoErrors(); + + // create semantic error in shared package + await sandbox.patch('packages/shared/src/intersect.ts', 'arrayB: T[] = []', 'arrayB: T'); + + // this compilation should contain semantic error in the shared project + // (there is also an error in the client project but as its dependency is not built, it will not be processed) + errors = await driver.waitForErrors(); + expect(errors).toEqual([ + [ + 'ERROR in packages/shared/src/intersect.ts 2:41-49', + "TS2339: Property 'includes' does not exist on type 'T'.", + ' 1 | function intersect(arrayA: T[] = [], arrayB: T): T[] {', + ' > 2 | return arrayA.filter((item) => arrayB.includes(item));', + ' | ^^^^^^^^', + ' 3 | }', + ' 4 | ', + ' 5 | export default intersect;', + ].join('\n'), + ]); + + // fix semantic error in the shared package + await sandbox.patch( + 'packages/shared/src/intersect.ts', + 'return arrayA.filter((item) => arrayB.includes(item));', + 'return arrayA.filter((item) => item && arrayB);' + ); + + // this compilation should contain semantic error in the client project + errors = await driver.waitForErrors(); + expect(errors).toEqual([ + [ + 'ERROR in packages/client/src/index.ts 4:42-48', + "TS2345: Argument of type 'T[]' is not assignable to parameter of type 'T'.", + " 'T[]' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'.", + ' 2 | ', + ' 3 | function compute(arrayA: T[], arrayB: T[]) {', + ' > 4 | const intersection = intersect(arrayA, arrayB);', + ' | ^^^^^^', + ' 5 | const difference = subtract(arrayA, arrayB);', + ' 6 | ', + ' 7 | return {', + ].join('\n'), + ]); + + // fix semantic error in the client package + await sandbox.patch( + 'packages/client/src/index.ts', + 'const intersection = intersect(arrayA, arrayB);', + 'const intersection = intersect(arrayA, arrayB[0]);' + ); + + // this compilation should be successful + await driver.waitForNoErrors(); + } + ); + }); +}); diff --git a/test/e2e/TypeScriptWatchApi.spec.ts b/test/e2e/TypeScriptWatchApi.spec.ts new file mode 100644 index 00000000..5ccfebda --- /dev/null +++ b/test/e2e/TypeScriptWatchApi.spec.ts @@ -0,0 +1,308 @@ +import { join } from 'path'; +import { readFixture } from './sandbox/Fixture'; +import { Sandbox, createSandbox, FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION } from './sandbox/Sandbox'; +import { + createWebpackDevServerDriver, + WEBPACK_CLI_VERSION, + WEBPACK_DEV_SERVER_VERSION, +} from './sandbox/WebpackDevServerDriver'; + +describe('TypeScript Watch API', () => { + describe('semantic error', () => { + let sandbox: Sandbox; + + beforeAll(async () => { + sandbox = await createSandbox(); + }); + + beforeEach(async () => { + await sandbox.reset(); + }); + + afterAll(async () => { + await sandbox.cleanup(); + }); + + it.each([ + { async: false, webpack: '4.0.0' }, + { async: true, webpack: '^4.0.0' }, + { async: false, webpack: '^5.0.0-beta.16' }, + { async: true, webpack: '^5.0.0-beta.16' }, + ])( + 'reports semantic error for %p with importsNotUsedAsValues configuration', + async ({ async, webpack }) => { + await sandbox.load( + await readFixture(join(__dirname, 'fixtures/typescript-basic.fixture'), { + FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION, + TS_LOADER_VERSION: '^5.0.0', + TYPESCRIPT_VERSION: '~3.8.0', + WEBPACK_VERSION: webpack, + WEBPACK_CLI_VERSION, + WEBPACK_DEV_SERVER_VERSION, + ASYNC: async ? 'true' : 'false', + }) + ); + + // add importsNotUsedAsValues which is supported from TypeScript 3.8.0+ + // this option is required for proper watching of type-only files in the `transpileOnly: true` mode + await sandbox.patch( + './tsconfig.json', + ' "outDir": "./dist"', + [' "outDir": "./dist",', ' "importsNotUsedAsValues": "preserve"'].join('\n') + ); + + const driver = createWebpackDevServerDriver( + sandbox.spawn('yarn exec webpack-dev-server'), + async + ); + let errors: string[]; + + // first compilation is successful + await driver.waitForNoErrors(); + + // then we introduce semantic error by removing "admin" role + await sandbox.patch( + 'src/model/Role.ts', + 'type Role = "admin" | "client" | "provider";', + 'type Role = "client" | "provider";' + ); + + // we should receive only one semantic error + errors = await driver.waitForErrors(); + expect(errors).toEqual([ + [ + 'ERROR in src/index.ts 34:7-28', + `TS2367: This condition will always return 'false' since the types 'Role' and '"admin"' have no overlap.`, + ' 32 | const user = await login(email, password);', + ' 33 | ', + ` > 34 | if (user.role === 'admin') {`, + ' | ^^^^^^^^^^^^^^^^^^^^^', + ' 35 | console.log(`Logged in as ${getUserName(user)} [admin].`);', + ' 36 | } else {', + ' 37 | console.log(`Logged in as ${getUserName(user)}`);', + ].join('\n'), + ]); + + // fix the semantic error by changing condition branch related to the "admin" role + await sandbox.patch( + 'src/index.ts', + [ + " if (user.role === 'admin') {", + ' console.log(`Logged in as ${getUserName(user)} [admin].`);', + ' } else {', + ' console.log(`Logged in as ${getUserName(user)}`);', + ' }', + ].join('\n'), + [ + " if (user.role === 'provider') {", + ' console.log(`Logged in as ${getUserName(user)} [provider].`);', + ' } else {', + ' console.log(`Logged in as ${getUserName(user)}`);', + ' }', + ].join('\n') + ); + + await driver.waitForNoErrors(); + + // delete module to trigger another error + await sandbox.remove('src/model/Role.ts'); + + // filter-out ts-loader related errors + errors = (await driver.waitForErrors()).filter( + (error) => !error.includes('Module build failed') + ); + expect(errors).toEqual([ + [ + 'ERROR in src/model/User.ts 1:22-30', + "TS2307: Cannot find module './Role'.", + " > 1 | import { Role } from './Role';", + ' | ^^^^^^^^', + ' 2 | ', + ' 3 | type User = {', + ' 4 | id: string;', + ].join('\n'), + ]); + + // re-create deleted module + await sandbox.write( + 'src/model/Role.ts', + ['type Role = "admin" | "client";', '', 'export { Role };'].join('\n') + ); + + // we should receive again the one semantic error but now for "provider" role + errors = await driver.waitForErrors(); + expect(errors).toEqual([ + [ + 'ERROR in src/index.ts 34:7-31', + "TS2367: This condition will always return 'false' since the types 'Role' and '\"provider\"' have no overlap.", + ' 32 | const user = await login(email, password);', + ' 33 | ', + " > 34 | if (user.role === 'provider') {", + ' | ^^^^^^^^^^^^^^^^^^^^^^^^', + ' 35 | console.log(`Logged in as ${getUserName(user)} [provider].`);', + ' 36 | } else {', + ' 37 | console.log(`Logged in as ${getUserName(user)}`);', + ].join('\n'), + ]); + } + ); + + it.each([ + { async: true, webpack: '^4.0.0', typescript: '2.7.1', tsloader: '^5.0.0' }, + { async: false, webpack: '^4.0.0', typescript: '~3.0.0', tsloader: '^6.0.0' }, + { async: true, webpack: '^4.0.0', typescript: '~3.6.0', tsloader: '^7.0.0' }, + { async: false, webpack: '^4.0.0', typescript: '~3.8.0', tsloader: '^6.0.0' }, + ])('reports semantic error for %p', async ({ async, webpack, typescript, tsloader }) => { + await sandbox.load( + await readFixture(join(__dirname, 'fixtures/typescript-basic.fixture'), { + FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION, + TS_LOADER_VERSION: tsloader, + TYPESCRIPT_VERSION: typescript, + WEBPACK_VERSION: webpack, + WEBPACK_CLI_VERSION, + WEBPACK_DEV_SERVER_VERSION, + ASYNC: async ? 'true' : 'false', + }) + ); + + const driver = createWebpackDevServerDriver( + sandbox.spawn('yarn exec webpack-dev-server'), + async + ); + let errors: string[]; + + // first compilation is successful + await driver.waitForNoErrors(); + + // then we introduce semantic error by removing "firstName" and "lastName" from the User model + await sandbox.patch( + 'src/model/User.ts', + [' firstName?: string;', ' lastName?: string;'].join('\n'), + '' + ); + + // we should receive 2 semantic errors + errors = await driver.waitForErrors(); + expect(errors).toEqual([ + [ + "ERROR in src/model/User.ts 11:16-25\nTS2339: Property 'firstName' does not exist on type 'User'.", + ' 9 | ', + ' 10 | function getUserName(user: User): string {', + ' > 11 | return [user.firstName, user.lastName]', + ' | ^^^^^^^^^', + ' 12 | .filter(name => name !== undefined)', + " 13 | .join(' ');", + ' 14 | }', + ].join('\n'), + [ + 'ERROR in src/model/User.ts 11:32-40', + "TS2339: Property 'lastName' does not exist on type 'User'.", + ' 9 | ', + ' 10 | function getUserName(user: User): string {', + ' > 11 | return [user.firstName, user.lastName]', + ' | ^^^^^^^^', + ' 12 | .filter(name => name !== undefined)', + " 13 | .join(' ');", + ' 14 | }', + ].join('\n'), + ]); + + // fix the semantic error + await sandbox.patch( + 'src/model/User.ts', + [ + ' return [user.firstName, user.lastName]', + ' .filter(name => name !== undefined)', + " .join(' ');", + ].join('\n'), + ` return user.email;` + ); + + await driver.waitForNoErrors(); + + // delete module to trigger another error + await sandbox.remove('src/authenticate.ts'); + + errors = await driver.waitForErrors(); + expect(errors).toEqual([ + [ + 'ERROR in src/index.ts 1:23-39', + "TS2307: Cannot find module './authenticate'.", + " > 1 | import { login } from './authenticate';", + ' | ^^^^^^^^^^^^^^^^', + " 2 | import { getUserName } from './model/User';", + ' 3 | ', + " 4 | const emailInput = document.getElementById('email');", + ].join('\n'), + ]); + + // re-create deleted module + await sandbox.write( + 'src/authenticate.ts', + [ + "import { User } from './model/User';", + '', + 'async function login(email: string, password: string): Promise {', + ' await fetch(', + " '/login',", + ' {', + " method: 'POST',", + ' body: JSON.stringify({ email, password })', + ' }', + ' );', + '}', + '', + 'async function logout(): Promise {', + ' const response = await fetch(', + " '/logout',", + ' {', + " method: 'POST'", + ' }', + ' );', + ' return response.json();', + '}', + '', + 'export { login, logout };', + ].join('\n') + ); + + // we should receive again 3 semantic errors + errors = await driver.waitForErrors(); + expect(errors).toEqual([ + [ + 'ERROR in src/index.ts 34:12-16', + "TS2339: Property 'role' does not exist on type 'void'.", + ' 32 | const user = await login(email, password);', + ' 33 | ', + " > 34 | if (user.role === 'admin') {", + ' | ^^^^', + ' 35 | console.log(`Logged in as ${getUserName(user)} [admin].`);', + ' 36 | } else {', + ' 37 | console.log(`Logged in as ${getUserName(user)}`);', + ].join('\n'), + [ + 'ERROR in src/index.ts 35:45-49', + "TS2345: Argument of type 'void' is not assignable to parameter of type 'User'.", + ' 33 | ', + " 34 | if (user.role === 'admin') {", + ' > 35 | console.log(`Logged in as ${getUserName(user)} [admin].`);', + ' | ^^^^', + ' 36 | } else {', + ' 37 | console.log(`Logged in as ${getUserName(user)}`);', + ' 38 | }', + ].join('\n'), + [ + 'ERROR in src/index.ts 37:45-49', + "TS2345: Argument of type 'void' is not assignable to parameter of type 'User'.", + ' 35 | console.log(`Logged in as ${getUserName(user)} [admin].`);', + ' 36 | } else {', + ' > 37 | console.log(`Logged in as ${getUserName(user)}`);', + ' | ^^^^', + ' 38 | }', + ' 39 | });', + ' 40 | ', + ].join('\n'), + ]); + }); + }); +}); diff --git a/test/e2e/fixtures/eslint-basic.fixture b/test/e2e/fixtures/eslint-basic.fixture new file mode 100644 index 00000000..366cae2f --- /dev/null +++ b/test/e2e/fixtures/eslint-basic.fixture @@ -0,0 +1,176 @@ +/// package.json +{ + "name": "eslint-basic-fixture", + "version": "1.0.0", + "main": "dist/index.js", + "license": "MIT", + "devDependencies": { + "@types/eslint": "^6.8.0", + "@typescript-eslint/eslint-plugin": "^2.27.0", + "@typescript-eslint/parser": "^2.27.0", + "eslint": "^6.8.0", + "fork-ts-checker-webpack-plugin": "${FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION}", + "ts-loader": "${TS_LOADER_VERSION}", + "typescript": "${TYPESCRIPT_VERSION}", + "webpack": "${WEBPACK_VERSION}", + "webpack-cli": "${WEBPACK_CLI_VERSION}", + "webpack-dev-server": "${WEBPACK_DEV_SERVER_VERSION}" + } +} +/// tsconfig.json +{ + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "lib": ["ES6", "DOM"], + "moduleResolution": "node", + "esModuleInterop": true, + "skipLibCheck": true, + "skipDefaultLibCheck": true, + "strict": true, + "baseUrl": "./src", + "outDir": "./dist" + }, + "include": ["./src"], + "exclude": ["node_modules"] +} +/// .eslintrc.js +module.exports = { + parser: '@typescript-eslint/parser', + parserOptions: { + ecmaVersion: 2018, + sourceType: 'module' + }, + extends: ['plugin:@typescript-eslint/recommended'] +}; + + +/// webpack.config.js +const path = require('path'); +const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); + +module.exports = { + entry: './src/index.ts', + output: { + filename: 'index.js', + path: path.resolve(__dirname, 'dist'), + }, + module: { + rules: [ + { + test: /\.tsx?$/, + loader: 'ts-loader', + exclude: /node_modules/, + options: { + transpileOnly: true + } + }, + ], + }, + resolve: { + extensions: ['.tsx', '.ts', '.js'], + }, + plugins: [ + new ForkTsCheckerWebpackPlugin({ + async: ${ASYNC}, + eslint: { + enabled: true, + files: './src/**/*.ts' + }, + logger: { + infrastructure: "console" + } + }) + ] +}; + +/// src/index.ts +import { login } from './authenticate'; +import { getUserName } from './model/User'; + +const emailInput = document.getElementById('email'); +const passwordInput = document.getElementById('password'); +const loginForm = document.getElementById('login'); + +if (!emailInput) { + throw new Error("Cannot find #email input."); +} +if (!passwordInput) { + throw new Error("Cannot find #password input."); +} +if (!loginForm) { + throw new Error("Cannot find #login form."); +} + +let email = ''; +let password = ''; + +emailInput.addEventListener('change', event => { + if (event.target instanceof HTMLInputElement) { + email = event.target.value; + } +}); +passwordInput.addEventListener('change', event => { + if (event.target instanceof HTMLInputElement) { + password = event.target.value; + } +}); +loginForm.addEventListener('submit', async event => { + const user = await login(email, password); + + if (user.role === 'admin') { + console.log(`Logged in as ${getUserName(user)} [admin].`); + } else { + console.log(`Logged in as ${getUserName(user)}`); + } +}); + +/// src/authenticate.ts +import { User } from './model/User'; + +async function login(email: string, password: string): Promise { + const response = await fetch( + '/login', + { + method: 'POST', + body: JSON.stringify({ email, password }) + } + ); + return response.json(); +} + +async function logout(): Promise { + const response = await fetch( + '/logout', + { + method: 'POST' + } + ); + return response.json(); +} + +export { login, logout }; + +/// src/model/User.ts +import { Role } from './Role'; + +type User = { + id: string; + email: string; + role: Role; + firstName?: string; + lastName?: string; +} + +function getUserName(user: User): string { + return [user.firstName, user.lastName] + .filter(name => name !== undefined) + .join(' '); +} + +export { User, getUserName }; + +/// src/model/Role.ts +type Role = "admin" | "client" | "provider"; + +export { Role }; diff --git a/test/e2e/fixtures/typescript-basic.fixture b/test/e2e/fixtures/typescript-basic.fixture new file mode 100644 index 00000000..d1f79dc6 --- /dev/null +++ b/test/e2e/fixtures/typescript-basic.fixture @@ -0,0 +1,157 @@ +/// package.json +{ + "name": "typescript-basic-fixture", + "version": "1.0.0", + "main": "dist/index.js", + "license": "MIT", + "devDependencies": { + "fork-ts-checker-webpack-plugin": "${FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION}", + "ts-loader": "${TS_LOADER_VERSION}", + "typescript": "${TYPESCRIPT_VERSION}", + "webpack": "${WEBPACK_VERSION}", + "webpack-cli": "${WEBPACK_CLI_VERSION}", + "webpack-dev-server": "${WEBPACK_DEV_SERVER_VERSION}" + } +} +/// tsconfig.json +{ + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "lib": ["ES6", "DOM"], + "moduleResolution": "node", + "esModuleInterop": true, + "skipLibCheck": true, + "skipDefaultLibCheck": true, + "strict": true, + "baseUrl": "./src", + "outDir": "./dist" + }, + "include": ["./src"], + "exclude": ["node_modules"] +} +/// webpack.config.js +const path = require('path'); +const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); + +module.exports = { + entry: './src/index.ts', + output: { + filename: 'index.js', + path: path.resolve(__dirname, 'dist'), + }, + module: { + rules: [ + { + test: /\.tsx?$/, + loader: 'ts-loader', + exclude: /node_modules/, + options: { + transpileOnly: true + } + }, + ], + }, + resolve: { + extensions: ['.tsx', '.ts', '.js'], + }, + plugins: [ + new ForkTsCheckerWebpackPlugin({ + async: ${ASYNC}, + logger: { + infrastructure: "console" + } + }) + ] +}; + +/// src/index.ts +import { login } from './authenticate'; +import { getUserName } from './model/User'; + +const emailInput = document.getElementById('email'); +const passwordInput = document.getElementById('password'); +const loginForm = document.getElementById('login'); + +if (!emailInput) { + throw new Error("Cannot find #email input."); +} +if (!passwordInput) { + throw new Error("Cannot find #password input."); +} +if (!loginForm) { + throw new Error("Cannot find #login form."); +} + +let email = ''; +let password = ''; + +emailInput.addEventListener('change', event => { + if (event.target instanceof HTMLInputElement) { + email = event.target.value; + } +}); +passwordInput.addEventListener('change', event => { + if (event.target instanceof HTMLInputElement) { + password = event.target.value; + } +}); +loginForm.addEventListener('submit', async event => { + const user = await login(email, password); + + if (user.role === 'admin') { + console.log(`Logged in as ${getUserName(user)} [admin].`); + } else { + console.log(`Logged in as ${getUserName(user)}`); + } +}); + +/// src/authenticate.ts +import { User } from './model/User'; + +async function login(email: string, password: string): Promise { + const response = await fetch( + '/login', + { + method: 'POST', + body: JSON.stringify({ email, password }) + } + ); + return response.json(); +} + +async function logout(): Promise { + const response = await fetch( + '/logout', + { + method: 'POST' + } + ); + return response.json(); +} + +export { login, logout }; + +/// src/model/User.ts +import { Role } from './Role'; + +type User = { + id: string; + email: string; + role: Role; + firstName?: string; + lastName?: string; +} + +function getUserName(user: User): string { + return [user.firstName, user.lastName] + .filter(name => name !== undefined) + .join(' '); +} + +export { User, getUserName }; + +/// src/model/Role.ts +type Role = "admin" | "client" | "provider"; + +export { Role }; diff --git a/test/e2e/fixtures/typescript-project-references.fixture b/test/e2e/fixtures/typescript-project-references.fixture new file mode 100644 index 00000000..3837b273 --- /dev/null +++ b/test/e2e/fixtures/typescript-project-references.fixture @@ -0,0 +1,184 @@ +/// package.json +{ + "name": "typescript-project-references-fixture", + "version": "1.0.0", + "license": "MIT", + "private": true, + "workspaces": [ + "packages/*" + ], + "devDependencies": { + "fork-ts-checker-webpack-plugin": "${FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION}", + "ts-loader": "${TS_LOADER_VERSION}", + "typescript": "${TYPESCRIPT_VERSION}", + "webpack": "${WEBPACK_VERSION}", + "webpack-cli": "${WEBPACK_CLI_VERSION}", + "webpack-dev-server": "${WEBPACK_DEV_SERVER_VERSION}" + } +} + +/// tsconfig.json +{ + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "lib": ["es5", "scripthost"], + "moduleResolution": "node", + "esModuleInterop": true, + "importHelpers": false, + "skipLibCheck": true, + "skipDefaultLibCheck": true, + "strict": true, + "baseUrl": ".", + "composite": true, + "incremental": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "rootDir": "./packages" + }, + "files": [], + "references": [ + { "path": "./packages/shared" }, + { "path": "./packages/client" } + ] +} + +/// webpack.config.js +const path = require('path'); +const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); + +module.exports = { + entry: './packages/client/src/index.ts', + output: { + filename: 'index.js', + path: path.resolve(__dirname, 'dist'), + }, + module: { + rules: [ + { + test: /\.tsx?$/, + loader: 'ts-loader', + exclude: /node_modules/, + options: { + transpileOnly: true, + projectReferences: true + } + }, + ], + }, + resolve: { + extensions: ['.tsx', '.ts', '.js'], + // as ts-loader doesn't fully support project references we put an alias to resolve package + // and to not pollute output with ts-loader errors + alias: { + "@project-references-fixture/shared": path.resolve(__dirname, "packages/shared/src") + } + }, + plugins: [ + new ForkTsCheckerWebpackPlugin({ + async: ${ASYNC}, + typescript: { + build: true + } + }) + ] +}; + + +/// packages/shared/package.json +{ + "name": "@project-references-fixture/shared", + "license": "MIT", + "version": "1.0.0", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "files": [ + "lib" + ] +} + +/// packages/shared/tsconfig.json +{ + "extends": "../../tsconfig", + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib", + "sourceRoot": "./src", + "baseUrl": "./src" + }, + "include": ["src"], + "exclude": ["node_modules", "lib"] +} + +/// packages/shared/src/intersect.ts +function intersect(arrayA: T[] = [], arrayB: T[] = []): T[] { + return arrayA.filter((item) => arrayB.includes(item)); +} + +export default intersect; + +/// packages/shared/src/subtract.ts +function subtract(arrayA: T[] = [], arrayB: T[] = []): T[] { + return arrayA.filter((item) => !arrayB.includes(item)); +} + +export default subtract; + +/// packages/shared/src/index.ts +import intersect from "./intersect"; +import subtract from "./subtract"; + +export { + intersect, + subtract +} + +/// packages/client/package.json +{ + "name": "@project-references-fixture/client", + "license": "MIT", + "version": "1.0.0", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "files": [ + "lib" + ], + "dependencies": { + "@project-references-fixture/shared": "1.0.0" + } +} + +/// packages/client/tsconfig.json +{ + "extends": "../../tsconfig", + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib", + "sourceRoot": "./src", + "baseUrl": "./src" + }, + "references": [{ "path": "../shared" }], + "include": ["src"], + "exclude": ["node_modules", "lib"] +} + + +/// packages/client/src/index.ts +import { intersect, subtract } from "@project-references-fixture/shared"; + +function compute(arrayA: T[], arrayB: T[]) { + const intersection = intersect(arrayA, arrayB); + const difference = subtract(arrayA, arrayB); + + return { + intersection, + difference + } +} + +const { intersection, difference } = compute(['a', 'b', 'c'], ['a', 'd', 'a']); + +console.log(`Intersection: ${JSON.stringify(intersection)}`); +console.log(`Difference: ${JSON.stringify(difference)}`); + diff --git a/test/e2e/sandbox/Fixture.ts b/test/e2e/sandbox/Fixture.ts new file mode 100644 index 00000000..1c543279 --- /dev/null +++ b/test/e2e/sandbox/Fixture.ts @@ -0,0 +1,67 @@ +import fs from 'fs-extra'; + +type FixtureFilePath = string; +type FixtureFileContent = string; + +type Fixture = Record; +const INTERPOLATION_REGEXP = /\${([a-zA-Z0-9_]+)}/; + +/** + * Parses string to the Fixture object which represents a filesystem subtree + */ +function parseFixture(content: string, params: Record = {}): Fixture { + const draft: Record = {}; + const lines = content.split('\n'); + let currentPath: string | undefined; + + for (let line of lines) { + if (line.startsWith('///')) { + currentPath = line.slice(3).trim(); + draft[currentPath] = []; + continue; + } + + if (currentPath) { + const match = INTERPOLATION_REGEXP.exec(line); + if (match) { + const interpolation = match[0]; + const name = match[1]; + + if (params[name]) { + line = line.replace(interpolation, params[name]); + } else { + throw new Error( + `Unknown variable ${interpolation} in ${currentPath} at line ${ + draft[currentPath].length + 1 + }` + ); + } + } + + draft[currentPath].push(line); + } + } + + const fixture: Fixture = {}; + + for (const path in draft) { + fixture[path] = draft[path].join('\n'); + } + + return fixture; +} + +/** + * Reads fixture from a file + */ +async function readFixture(path: string, params: Record = {}): Promise { + const content = await fs.readFile(path, 'utf-8'); + + try { + return parseFixture(content, params); + } catch (error) { + throw new Error(`Error during parsing ${path}.\n${error.message}`); + } +} + +export { Fixture, parseFixture, readFixture }; diff --git a/test/e2e/sandbox/GenericProcessDriver.ts b/test/e2e/sandbox/GenericProcessDriver.ts new file mode 100644 index 00000000..73240f21 --- /dev/null +++ b/test/e2e/sandbox/GenericProcessDriver.ts @@ -0,0 +1,87 @@ +import { ChildProcess } from 'child_process'; +import { Listener } from './Listener'; +import stripAnsi from 'strip-ansi'; + +interface GenericProcessDriver { + waitForStdoutIncludes: (string: string, timeout?: number) => Promise; + waitForStderrIncludes: (string: string, timeout?: number) => Promise; + close: () => Promise; +} + +interface StringListener extends Listener { + string: string; +} + +function createGenericProcessDriver( + process: ChildProcess, + defaultTimeout = 30000 +): GenericProcessDriver { + let stdoutListener: StringListener | undefined = undefined; + let stderrListener: StringListener | undefined = undefined; + + if (process.stdout) { + process.stdout.on('data', (data) => { + const content = stripAnsi(data.toString()); + + if (stdoutListener && content.includes(stdoutListener.string)) { + stdoutListener.resolve(); + } + }); + } + + if (process.stderr) { + process.stderr.on('data', (data) => { + const content = stripAnsi(data.toString()); + + if (stderrListener && content.includes(stderrListener.string)) { + stderrListener.resolve(); + } + }); + } + + return { + waitForStdoutIncludes: (string, timeout = defaultTimeout) => + new Promise((resolve, reject) => { + const timeoutId = setTimeout(() => { + reject(new Error(`Exceeded time on waiting for "${string}" to appear in the stdout.`)); + }, timeout); + + stdoutListener = { + resolve: () => { + clearTimeout(timeoutId); + stdoutListener = undefined; + resolve(); + }, + reject: (error) => { + clearTimeout(timeoutId); + stdoutListener = undefined; + reject(error); + }, + string, + }; + }), + waitForStderrIncludes: (string, timeout = defaultTimeout) => + new Promise((resolve, reject) => { + const timeoutId = setTimeout(() => { + reject(new Error(`Exceeded time on waiting for "${string}" to appear in the stderr.`)); + }, timeout); + + stderrListener = { + resolve: () => { + clearTimeout(timeoutId); + stderrListener = undefined; + resolve(); + }, + reject: (error) => { + clearTimeout(timeoutId); + stderrListener = undefined; + reject(error); + }, + string, + }; + }), + close: async () => process.kill(), + }; +} + +export { createGenericProcessDriver }; diff --git a/test/e2e/sandbox/Listener.ts b/test/e2e/sandbox/Listener.ts new file mode 100644 index 00000000..bf7e90eb --- /dev/null +++ b/test/e2e/sandbox/Listener.ts @@ -0,0 +1,6 @@ +interface Listener { + resolve: (value: T) => void; + reject: (error: unknown) => void; +} + +export { Listener }; diff --git a/test/e2e/sandbox/Sandbox.ts b/test/e2e/sandbox/Sandbox.ts new file mode 100644 index 00000000..d0d299fc --- /dev/null +++ b/test/e2e/sandbox/Sandbox.ts @@ -0,0 +1,193 @@ +import { join, resolve, dirname } from 'path'; +import fs from 'fs-extra'; +import os from 'os'; +import chalk from 'chalk'; +import { exec, spawn, ChildProcess } from 'child_process'; +import { Fixture } from './Fixture'; +import stripAnsi from 'strip-ansi'; + +interface Sandbox { + context: string; + children: ChildProcess[]; + load: (fixture: Fixture) => Promise; + reset: () => Promise; + cleanup: () => Promise; + write: (path: string, content: string) => Promise; + read: (path: string) => Promise; + exists: (path: string) => Promise; + remove: (path: string) => Promise; + patch: (path: string, search: string, replacement: string) => Promise; + exec: (command: string, env?: Record) => Promise; + spawn: (command: string, env?: Record) => ChildProcess; +} + +async function createSandbox(): Promise { + const context = await fs.mkdtemp(join(os.tmpdir(), 'fork-ts-checker-sandbox-')); + let written: string[] = []; + + process.stdout.write(`Sandbox directory: ${context}\n`); + + const sandbox: Sandbox = { + context, + children: [], + load: async (fixture) => { + await Promise.all(Object.keys(fixture).map((path) => sandbox.write(path, fixture[path]))); + process.stdout.write(chalk.green('Fixture initialized.\n')); + + process.stdout.write(chalk.blue('Installing dependencies...\n')); + // use custom directory to not use cached version of the plugin + const YARN_CACHE_FOLDER = join(sandbox.context, '.yarn'); + await sandbox.exec('yarn install', { + YARN_CACHE_FOLDER, + }); + process.stdout.write(chalk.green('The sandbox initialized successfully.\n')); + + written = []; + }, + reset: async () => { + process.stdout.write('Resetting the sandbox\n'); + + for (const child of sandbox.children) { + if (!child.killed) { + process.stdout.write(`Killing child process ${child.pid}\n`); + child.kill(); + } + } + + process.stdout.write(`Resetting sandbox directory: ${context}\n`); + await Promise.all(written.map((path) => sandbox.remove(path))); + written = []; + }, + cleanup: async () => { + process.stdout.write('Cleaning up the sandbox\n'); + + for (const child of sandbox.children) { + if (!child.killed) { + process.stdout.write(`Killing child process ${child.pid}\n`); + child.kill(); + } + } + + process.stdout.write(`Removing sandbox directory: ${context}\n`); + await fs.remove(context); + + process.stdout.write('Sandbox cleaned up.\n'); + }, + write: async (path: string, content: string) => { + process.stdout.write(`Writing file ${path}...\n`); + const realPath = join(context, path); + const dirPath = dirname(realPath); + + if (!written.includes(path) && !(await fs.pathExists(realPath))) { + written.push(path); + } + + if (!(await fs.pathExists(dirPath))) { + await fs.mkdirp(dirPath); + } + + // wait to avoid race conditions + await new Promise((resolve) => setTimeout(resolve, 100)); + + return fs.writeFile(realPath, content); + }, + read: (path: string) => { + process.stdout.write(`Reading file ${path}...\n`); + const realPath = join(context, path); + + return fs.readFile(realPath, 'utf-8'); + }, + exists: (path: string) => { + const realPath = join(context, path); + + return fs.pathExists(realPath); + }, + remove: async (path: string) => { + process.stdout.write(`Removing file ${path}...\n`); + const realPath = join(context, path); + + // wait to avoid race conditions + await new Promise((resolve) => setTimeout(resolve, 100)); + + return fs.remove(realPath); + }, + patch: async (path: string, search: string, replacement: string) => { + process.stdout.write( + `Patching file ${path} - replacing ${search} with "${replacement}"...\n` + ); + const realPath = join(context, path); + const content = await fs.readFile(realPath, 'utf-8'); + + if (!content.includes(search)) { + throw new Error(`Cannot find "${search}" in the ${path}. The file content:\n${content}.`); + } + + // wait to avoid race conditions + await new Promise((resolve) => setTimeout(resolve, 100)); + + return fs.writeFile(realPath, content.replace(search, replacement)); + }, + exec: (command: string, env = {}) => + new Promise((resolve, reject) => { + process.stdout.write(`Executing "${command}" command...\n`); + + const child = exec( + command, + { + cwd: context, + env: { + ...process.env, + ...env, + }, + }, + (error, output) => { + if (error) { + reject(error); + } else { + resolve(output); + } + } + ); + + child.stdout.on('data', (data) => process.stdout.write(stripAnsi(data.toString()))); + child.stderr.on('data', (data) => process.stdout.write(stripAnsi(data.toString()))); + + sandbox.children.push(child); + }), + spawn: (command: string, env = {}) => { + process.stdout.write(`Spawning "${command}" command...\n`); + + const [spawnCommand, ...args] = command.split(' '); + + const child = spawn(spawnCommand, args, { + cwd: context, + env: { + ...process.env, + ...env, + }, + }); + + child.stdout.on('data', (data) => process.stdout.write(stripAnsi(data.toString()))); + child.stderr.on('data', (data) => process.stdout.write(stripAnsi(data.toString()))); + + sandbox.children.push(child); + + return child; + }, + }; + + return sandbox; +} + +const FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION = join( + resolve(__dirname, '../../..'), + 'fork-ts-checker-webpack-plugin.tgz' +); + +if (!fs.pathExistsSync(FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION)) { + throw new Error( + `Cannot find ${FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION} file. To run e2e test, execute "yarn pack --filename fork-ts-checker-webpack-plugin.tgz" command before.` + ); +} + +export { Sandbox, createSandbox, FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION }; diff --git a/test/e2e/sandbox/WebpackDevServerDriver.ts b/test/e2e/sandbox/WebpackDevServerDriver.ts new file mode 100644 index 00000000..6ad33f32 --- /dev/null +++ b/test/e2e/sandbox/WebpackDevServerDriver.ts @@ -0,0 +1,134 @@ +import { ChildProcess } from 'child_process'; +import stripAnsi from 'strip-ansi'; +import { extractWebpackErrors } from './WebpackErrorsExtractor'; +import { Listener } from './Listener'; + +interface WebpackDevServerDriver { + waitForErrors: (timeout?: number) => Promise; + waitForNoErrors: (timeout?: number) => Promise; + close: () => Promise; +} + +interface ActivatableListener extends Listener { + active: boolean; +} + +function createWebpackDevServerDriver( + process: ChildProcess, + async: boolean, + defaultTimeout = 30000 +): WebpackDevServerDriver { + let errorsListener: ActivatableListener | undefined = undefined; + let noErrorsListener: ActivatableListener | undefined = undefined; + let errors: string[] = []; + + function nextIteration() { + noErrorsListener = undefined; + errorsListener = undefined; + errors = []; + } + + function activateListeners() { + if (noErrorsListener) { + noErrorsListener.active = true; + } + if (errorsListener) { + errorsListener.active = true; + } + } + + if (process.stdout) { + process.stdout.on('data', (data) => { + const content = stripAnsi(data.toString()); + + if ( + async && + content.includes('No issues found.') && + noErrorsListener && + noErrorsListener.active + ) { + noErrorsListener.resolve(); + } + + if (content.includes('Compiled successfully.')) { + if (!async && noErrorsListener) { + noErrorsListener.resolve(); + } else if (async) { + activateListeners(); + } + } + + if (content.includes('Failed to compile.') || content.includes('Compiled with warnings.')) { + if (!async && errorsListener) { + errorsListener.resolve(errors); + } else if (async) { + activateListeners(); + } + } + }); + } + + if (process.stderr) { + process.stderr.on('data', (data) => { + const content = stripAnsi(data.toString()); + const extracted = extractWebpackErrors(content); + errors.push(...extracted); + + if (async && errors.length && errorsListener && errorsListener.active) { + errorsListener.resolve(errors); + } + }); + } + + return { + waitForErrors: (timeout = defaultTimeout) => + new Promise((resolve, reject) => { + const timeoutId = setTimeout(() => { + reject(new Error('Exceeded time on waiting for errors to appear.')); + nextIteration(); + }, timeout); + + errorsListener = { + resolve: (results) => { + clearTimeout(timeoutId); + nextIteration(); + resolve(results); + }, + reject: (error) => { + clearTimeout(timeoutId); + nextIteration(); + reject(error); + }, + active: !async, // for async, we need to activate listener manually + }; + }), + waitForNoErrors: (timeout = defaultTimeout) => + new Promise((resolve, reject) => { + const timeoutId = setTimeout(() => { + reject(new Error('Exceeded time on waiting for no errors message to appear.')); + nextIteration(); + }, timeout); + + noErrorsListener = { + resolve: () => { + clearTimeout(timeoutId); + nextIteration(); + resolve(); + }, + reject: (error) => { + clearTimeout(timeoutId); + nextIteration(); + reject(error); + }, + active: !async, // for async, we need to activate listener manually + }; + }), + close: async () => process.kill(), + }; +} + +// supported versions +const WEBPACK_CLI_VERSION = '^3.3.11'; +const WEBPACK_DEV_SERVER_VERSION = '^3.10.3'; + +export { createWebpackDevServerDriver, WEBPACK_CLI_VERSION, WEBPACK_DEV_SERVER_VERSION }; diff --git a/test/e2e/sandbox/WebpackErrorsExtractor.ts b/test/e2e/sandbox/WebpackErrorsExtractor.ts new file mode 100644 index 00000000..4140f3c8 --- /dev/null +++ b/test/e2e/sandbox/WebpackErrorsExtractor.ts @@ -0,0 +1,35 @@ +function isLineRelatedToTsLoader(line: string) { + return line.includes('[tsl]') || line.includes('ts-loader'); +} + +function extractWebpackErrors(content: string): string[] { + const lines = content.split('\n'); + const errors: string[] = []; + let currentError: string | undefined = undefined; + + for (const line of lines) { + if (currentError) { + if (line === '') { + errors.push(currentError); + currentError = undefined; + } else { + if (isLineRelatedToTsLoader(line)) { + currentError = undefined; + } else { + currentError += '\n' + line; + } + } + } else { + if ( + (line.startsWith('ERROR') || line.startsWith('WARNING')) && + !isLineRelatedToTsLoader(line) + ) { + currentError = line; + } + } + } + + return errors; +} + +export { extractWebpackErrors }; diff --git a/test/fixtures/.DS_Store b/test/fixtures/.DS_Store deleted file mode 100644 index 5c757dffb436bbd4b73c69cf7467da446192b94e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK&2AGh5FRI?b%JPfsMH?!g2bVRl>X#^kXC6q^j2vR8~~-e$%<~ZT}RnXBS?ex z!b89t@F+Y1j{~3WNkx)|BdWk7jlc1D#`b>Rwbw)>I-~v`QIm)yRAZ%%;ttX6T9>54 zo;9E_eFPL!MmZ%^EJZuVePlqd-4^vI#Hz*g`}!qx4bK@3Nzo;&9u=pl>P4xFkfUFi zXV51%tuofW8{?L-N_b5659*8Rm^Qf@%((m=ewh#aX#Q#e~$)f zk{7Mk4^gSs9;~fP*^rG#jd#I?8V5yKjPg!6e4}e;VQ~?${Zgs))()drNj&a0w~kd- zgh>_;O>)wY5%TtRlJ(WNqefXjH~j>*LCU(Ucbhwt$$q=N>m58jobGy)cDn_8|7bd` z%k9T|&ri>qUTmKM1$CVauQ(%~*7_s^&-hmo{-_r)rXDltk193kB Nh6YzS2L37ozX0%Vhq?d& diff --git a/test/fixtures/caseSensitiveProject/src/index.ts b/test/fixtures/caseSensitiveProject/src/index.ts deleted file mode 100644 index cb44d983..00000000 --- a/test/fixtures/caseSensitiveProject/src/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import y from './Lib'; - -console.log(y); diff --git a/test/fixtures/caseSensitiveProject/src/lib.ts b/test/fixtures/caseSensitiveProject/src/lib.ts deleted file mode 100644 index 2ea08409..00000000 --- a/test/fixtures/caseSensitiveProject/src/lib.ts +++ /dev/null @@ -1 +0,0 @@ -export default 'test'; diff --git a/test/fixtures/caseSensitiveProject/tsconfig.json b/test/fixtures/caseSensitiveProject/tsconfig.json deleted file mode 100644 index ae7609b4..00000000 --- a/test/fixtures/caseSensitiveProject/tsconfig.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "compilerOptions": { - "lib": ["es2016"], - "forceConsistentCasingInFileNames": true - }, - "import": ["./src/**/*"] -} diff --git a/test/fixtures/project/src/defs.d.ts b/test/fixtures/project/src/defs.d.ts deleted file mode 100644 index 5bc7fee2..00000000 --- a/test/fixtures/project/src/defs.d.ts +++ /dev/null @@ -1 +0,0 @@ -declare function helloWorld(): void; diff --git a/test/fixtures/project/src/export.ts b/test/fixtures/project/src/export.ts deleted file mode 100644 index 9d0bfc44..00000000 --- a/test/fixtures/project/src/export.ts +++ /dev/null @@ -1 +0,0 @@ -export const fortyTwo = 42; diff --git a/test/fixtures/project/src/index.ts b/test/fixtures/project/src/index.ts deleted file mode 100644 index 5fc46b55..00000000 --- a/test/fixtures/project/src/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -// Semantic error -const x: number = '1'; diff --git a/test/fixtures/project/src/pathResolutions.ts b/test/fixtures/project/src/pathResolutions.ts deleted file mode 100644 index 328c3a21..00000000 --- a/test/fixtures/project/src/pathResolutions.ts +++ /dev/null @@ -1 +0,0 @@ -import 'surprise'; diff --git a/test/fixtures/project/src/syntacticError.ts b/test/fixtures/project/src/syntacticError.ts deleted file mode 100644 index 1655a39e..00000000 --- a/test/fixtures/project/src/syntacticError.ts +++ /dev/null @@ -1,2 +0,0 @@ -// Syntactic error -const array = [{} {}]; diff --git a/test/fixtures/project/src/weirdResolutions.ts b/test/fixtures/project/src/weirdResolutions.ts deleted file mode 100644 index ed316416..00000000 --- a/test/fixtures/project/src/weirdResolutions.ts +++ /dev/null @@ -1,5 +0,0 @@ -/// - -import { fortyTwo } from 'please-find-my-export'; - -helloWorld(); diff --git a/test/fixtures/project/tsconfig-semantic-error-only.json b/test/fixtures/project/tsconfig-semantic-error-only.json deleted file mode 100644 index 2d2cf0ab..00000000 --- a/test/fixtures/project/tsconfig-semantic-error-only.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "compilerOptions": { - "lib": ["es2016"], - }, - "include": [ - "src/index.ts" - ] -} diff --git a/test/fixtures/project/tsconfig-weird-resolutions-with-paths.json b/test/fixtures/project/tsconfig-weird-resolutions-with-paths.json deleted file mode 100644 index d88e9aa2..00000000 --- a/test/fixtures/project/tsconfig-weird-resolutions-with-paths.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "compilerOptions": { - "lib": ["es2016"], - "paths": { - "surprise": "./index.ts" - } - }, - "include": ["src/pathResolutions.ts", "src/weirdResolutions.ts"] -} diff --git a/test/fixtures/project/tsconfig-weird-resolutions.json b/test/fixtures/project/tsconfig-weird-resolutions.json deleted file mode 100644 index 057019f2..00000000 --- a/test/fixtures/project/tsconfig-weird-resolutions.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "compilerOptions": { - "lib": ["es2016"], - }, - "include": [ - "src/weirdResolutions.ts" - ] -} diff --git a/test/fixtures/project/tsconfig.json b/test/fixtures/project/tsconfig.json deleted file mode 100644 index dc828cf0..00000000 --- a/test/fixtures/project/tsconfig.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "compilerOptions": { - "lib": ["es2016"] - }, - "exclude": ["src/pathResolutions.ts", "src/weirdResolutions.ts"] -} diff --git a/test/fixtures/project/tslint.autofix.json b/test/fixtures/project/tslint.autofix.json deleted file mode 100644 index 8ff4101b..00000000 --- a/test/fixtures/project/tslint.autofix.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "defaultSeverity": "warning", - "extends": [ - "tslint:recommended" - ], - "linterOptions": { - "exclude": [ - "src/index.ts" - ] - }, - "jsRules": {}, - "rules": {}, - "rulesDirectory": [] -} diff --git a/test/fixtures/project/tslint.json b/test/fixtures/project/tslint.json deleted file mode 100644 index bfb99eca..00000000 --- a/test/fixtures/project/tslint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "defaultSeverity": "warning", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": {}, - "rulesDirectory": [] -} diff --git a/test/fixtures/project/weirdResolver.js b/test/fixtures/project/weirdResolver.js deleted file mode 100644 index 5cb1e55d..00000000 --- a/test/fixtures/project/weirdResolver.js +++ /dev/null @@ -1,11 +0,0 @@ -exports.resolveModuleName = function() { - return { resolvedModule: { resolvedFileName: `${__dirname}/src/export.ts` } }; -}; - -exports.resolveTypeReferenceDirective = function() { - return { - resolvedTypeReferenceDirective: { - resolvedFileName: `${__dirname}/src/defs.d.ts` - } - }; -}; diff --git a/test/fixtures/project_eslint/src/.eslintrc.js b/test/fixtures/project_eslint/src/.eslintrc.js deleted file mode 100644 index 272ff3c2..00000000 --- a/test/fixtures/project_eslint/src/.eslintrc.js +++ /dev/null @@ -1,10 +0,0 @@ -module.exports = { - parser: '@typescript-eslint/parser', - plugins: ['@typescript-eslint'], - parserOptions: { - sourceType: 'module' - }, - rules: { - '@typescript-eslint/array-type': 'error' - } -}; diff --git a/test/fixtures/project_eslint/src/index.ts b/test/fixtures/project_eslint/src/index.ts deleted file mode 100644 index 1b4445cf..00000000 --- a/test/fixtures/project_eslint/src/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { arrayOfStringTriggeringError } from './lib/func'; -import { y } from './lib/otherFunc'; - -// This code should trigger no error as it has a different `.eslintrc.js` to `func.ts` -export const arrayOfStringButNoComplaint: Array = [ - ...arrayOfStringTriggeringError -]; - -let x = y; -console.log(x); diff --git a/test/fixtures/project_eslint/src/lib/.eslintrc.js b/test/fixtures/project_eslint/src/lib/.eslintrc.js deleted file mode 100644 index 7941379e..00000000 --- a/test/fixtures/project_eslint/src/lib/.eslintrc.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = { - parser: '@typescript-eslint/parser', - plugins: ['@typescript-eslint'], - rules: { - '@typescript-eslint/array-type': 'warn', - '@typescript-eslint/no-unused-vars': 'warn' - } -}; diff --git a/test/fixtures/project_eslint/src/lib/func.ts b/test/fixtures/project_eslint/src/lib/func.ts deleted file mode 100644 index 6c80fe38..00000000 --- a/test/fixtures/project_eslint/src/lib/func.ts +++ /dev/null @@ -1,3 +0,0 @@ -// This code should trigger this error -// Array type using 'Array' is forbidden. Use 'string[]' instead.eslint(@typescript-eslint/array-type) -export const arrayOfStringTriggeringError: Array = []; diff --git a/test/fixtures/project_eslint/src/lib/otherFunc.js b/test/fixtures/project_eslint/src/lib/otherFunc.js deleted file mode 100644 index 3d3db9d6..00000000 --- a/test/fixtures/project_eslint/src/lib/otherFunc.js +++ /dev/null @@ -1,6 +0,0 @@ -// This code should trigger this error -// 'i' is assigned a value but never used.eslint(@typescript-eslint/no-unused-vars) - -let i = ''; - -export const y = 1; diff --git a/test/fixtures/project_eslint/tsconfig.json b/test/fixtures/project_eslint/tsconfig.json deleted file mode 100644 index ef19c57b..00000000 --- a/test/fixtures/project_eslint/tsconfig.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "compilerOptions": { - "lib": ["es2016"], - "allowJs": true - } -} diff --git a/test/fixtures/vue/src/attrs/NotFound.vue b/test/fixtures/vue/src/attrs/NotFound.vue deleted file mode 100644 index 1ad5a262..00000000 --- a/test/fixtures/vue/src/attrs/NotFound.vue +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/test/fixtures/vue/src/attrs/Test.vue b/test/fixtures/vue/src/attrs/Test.vue deleted file mode 100644 index 046d2f23..00000000 --- a/test/fixtures/vue/src/attrs/Test.vue +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test/fixtures/vue/src/attrs/test.ts b/test/fixtures/vue/src/attrs/test.ts deleted file mode 100644 index 14b2a9f6..00000000 --- a/test/fixtures/vue/src/attrs/test.ts +++ /dev/null @@ -1,2 +0,0 @@ -const a: number = ''; -export default { a }; diff --git a/test/fixtures/vue/src/css.d.ts b/test/fixtures/vue/src/css.d.ts deleted file mode 100644 index 130a52e2..00000000 --- a/test/fixtures/vue/src/css.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -declare module '*.css' { - const css = ''; - - export default css; -} diff --git a/test/fixtures/vue/src/example-wild.vue b/test/fixtures/vue/src/example-wild.vue deleted file mode 100644 index 37bf9981..00000000 --- a/test/fixtures/vue/src/example-wild.vue +++ /dev/null @@ -1,24 +0,0 @@ - - - - - diff --git a/test/fixtures/vue/src/example.css b/test/fixtures/vue/src/example.css deleted file mode 100644 index da5d2635..00000000 --- a/test/fixtures/vue/src/example.css +++ /dev/null @@ -1,3 +0,0 @@ -.test { - background-color: blue; -} \ No newline at end of file diff --git a/test/fixtures/vue/src/example.vue b/test/fixtures/vue/src/example.vue deleted file mode 100644 index 4892c15d..00000000 --- a/test/fixtures/vue/src/example.vue +++ /dev/null @@ -1,24 +0,0 @@ - - - - - diff --git a/test/fixtures/vue/src/imports/Component1.vue b/test/fixtures/vue/src/imports/Component1.vue deleted file mode 100644 index 66f2bb1a..00000000 --- a/test/fixtures/vue/src/imports/Component1.vue +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/test/fixtures/vue/src/imports/Component2.vue b/test/fixtures/vue/src/imports/Component2.vue deleted file mode 100644 index 0f7565a8..00000000 --- a/test/fixtures/vue/src/imports/Component2.vue +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/test/fixtures/vue/src/imports/Component3.vue b/test/fixtures/vue/src/imports/Component3.vue deleted file mode 100644 index d9311cb1..00000000 --- a/test/fixtures/vue/src/imports/Component3.vue +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/test/fixtures/vue/src/imports/Test.vue b/test/fixtures/vue/src/imports/Test.vue deleted file mode 100644 index ec8214df..00000000 --- a/test/fixtures/vue/src/imports/Test.vue +++ /dev/null @@ -1,31 +0,0 @@ - - diff --git a/test/fixtures/vue/src/imports/foo1/Foo1.vue b/test/fixtures/vue/src/imports/foo1/Foo1.vue deleted file mode 100644 index 5cb43deb..00000000 --- a/test/fixtures/vue/src/imports/foo1/Foo1.vue +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/test/fixtures/vue/src/imports/foo2/Foo2.vue b/test/fixtures/vue/src/imports/foo2/Foo2.vue deleted file mode 100644 index dac00be5..00000000 --- a/test/fixtures/vue/src/imports/foo2/Foo2.vue +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/test/fixtures/vue/src/index.ts b/test/fixtures/vue/src/index.ts deleted file mode 100644 index 829d0577..00000000 --- a/test/fixtures/vue/src/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -import ExampleWild from '@/example-wild.vue'; -import Example from './example.vue'; - -const foo = new Example(); -foo.msg = 'foo'; - -const bar = new ExampleWild(); -bar.msg = 'bar'; diff --git a/test/fixtures/vue/src/langs/example-js.vue b/test/fixtures/vue/src/langs/example-js.vue deleted file mode 100644 index 3d6e5c5a..00000000 --- a/test/fixtures/vue/src/langs/example-js.vue +++ /dev/null @@ -1,17 +0,0 @@ - - - - diff --git a/test/fixtures/vue/src/langs/example-jsx.vue b/test/fixtures/vue/src/langs/example-jsx.vue deleted file mode 100644 index ed43c6d3..00000000 --- a/test/fixtures/vue/src/langs/example-jsx.vue +++ /dev/null @@ -1,11 +0,0 @@ - diff --git a/test/fixtures/vue/src/langs/example-nolang.vue b/test/fixtures/vue/src/langs/example-nolang.vue deleted file mode 100644 index bc9e1152..00000000 --- a/test/fixtures/vue/src/langs/example-nolang.vue +++ /dev/null @@ -1,17 +0,0 @@ - - - - diff --git a/test/fixtures/vue/src/langs/example-ts-with-errors.vue b/test/fixtures/vue/src/langs/example-ts-with-errors.vue deleted file mode 100644 index 9912fb15..00000000 --- a/test/fixtures/vue/src/langs/example-ts-with-errors.vue +++ /dev/null @@ -1,8 +0,0 @@ - - - - diff --git a/test/fixtures/vue/src/langs/example-ts.vue b/test/fixtures/vue/src/langs/example-ts.vue deleted file mode 100644 index 6d81736e..00000000 --- a/test/fixtures/vue/src/langs/example-ts.vue +++ /dev/null @@ -1,18 +0,0 @@ - - - - diff --git a/test/fixtures/vue/src/langs/example-tsx.vue b/test/fixtures/vue/src/langs/example-tsx.vue deleted file mode 100644 index a2f6b2d4..00000000 --- a/test/fixtures/vue/src/langs/example-tsx.vue +++ /dev/null @@ -1,11 +0,0 @@ - diff --git a/test/fixtures/vue/src/langs/index.ts b/test/fixtures/vue/src/langs/index.ts deleted file mode 100644 index 70eec88f..00000000 --- a/test/fixtures/vue/src/langs/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -import Vue from 'vue'; -import ExampleTsx from './example-tsx.vue'; - -new Vue({ - components: { ExampleTsx } -}); diff --git a/test/fixtures/vue/src/syntacticError.ts b/test/fixtures/vue/src/syntacticError.ts deleted file mode 100644 index 1655a39e..00000000 --- a/test/fixtures/vue/src/syntacticError.ts +++ /dev/null @@ -1,2 +0,0 @@ -// Syntactic error -const array = [{} {}]; diff --git a/test/fixtures/vue/tsconfig-attrs.json b/test/fixtures/vue/tsconfig-attrs.json deleted file mode 100644 index b2b14d93..00000000 --- a/test/fixtures/vue/tsconfig-attrs.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "compilerOptions": { - "lib": ["es2016", "dom"] - }, - "include": [ - "src/attrs/Test.vue", - "src/attrs/NotFound.vue" - ], - "exclude": [ - "node_modules" - ] -} diff --git a/test/fixtures/vue/tsconfig-imports.json b/test/fixtures/vue/tsconfig-imports.json deleted file mode 100644 index c4205687..00000000 --- a/test/fixtures/vue/tsconfig-imports.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "compilerOptions": { - "baseUrl": "./src", - "moduleResolution": "node", - "paths": { - "@/*": ["imports/*"], - "foo/*": ["imports/foo1/*", "imports/foo2/*"] - }, - "lib": ["es2016", "dom"] - }, - "include": ["src/imports/Test.vue"], - "exclude": ["node_modules"] -} diff --git a/test/fixtures/vue/tsconfig-langs-strict.json b/test/fixtures/vue/tsconfig-langs-strict.json deleted file mode 100644 index bd400ff0..00000000 --- a/test/fixtures/vue/tsconfig-langs-strict.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - "jsx": "preserve", - "noUnusedLocals": true, - "lib": ["es2016", "dom"] - }, - "include": [ - "src/langs/*.ts", - "src/langs/*.vue" - ], - "exclude": [ - "node_modules" - ] -} diff --git a/test/fixtures/vue/tsconfig-langs.json b/test/fixtures/vue/tsconfig-langs.json deleted file mode 100644 index 81a5950c..00000000 --- a/test/fixtures/vue/tsconfig-langs.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "compilerOptions": { - "jsx": "preserve", - "lib": ["es2016", "dom"] - }, - "include": [ - "src/langs/*.ts", - "src/langs/*.vue" - ], - "exclude": [ - "node_modules" - ] -} diff --git a/test/fixtures/vue/tsconfig.json b/test/fixtures/vue/tsconfig.json deleted file mode 100644 index a316bbd2..00000000 --- a/test/fixtures/vue/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "compilerOptions": { - "experimentalDecorators": true, - "lib": ["es2016", "dom"] - }, - "include": [ - "src/*.ts", - "src/*.vue" - ], - "exclude": [ - "node_modules" - ] -} diff --git a/test/integration/general.spec.ts b/test/integration/general.spec.ts deleted file mode 100644 index f9688006..00000000 --- a/test/integration/general.spec.ts +++ /dev/null @@ -1,368 +0,0 @@ -import path from 'path'; -import ForkTsCheckerWebpackPlugin from '../../lib/index'; -import * as helpers from './helpers'; -import { cloneDeep } from 'lodash'; -import unixify from 'unixify'; -import * as semver from 'semver'; - -describe.each([[true], [false]])( - '[INTEGRATION] common tests - useTypescriptIncrementalApi: %s', - useTypescriptIncrementalApi => { - let compilerPlugin: ForkTsCheckerWebpackPlugin; - - const overrideOptions = { useTypescriptIncrementalApi }; - - function createCompiler( - options: Partial = {} - ) { - const compiler = helpers.createCompiler({ - ...options, - pluginOptions: { ...options.pluginOptions, ...overrideOptions } - }); - compilerPlugin = compiler.plugin; - return compiler.compiler; - } - - const ifNotIncrementalIt = useTypescriptIncrementalApi ? it.skip : it; - const ifNodeGte8It = semver.lt(process.version, '8.10.0') ? it.skip : it; - const ifNodeLt8It = semver.lt(process.version, '8.10.0') ? it : it.skip; - - /** - * Implicitly check whether killService was called by checking that - * the service property was set to undefined. - * @returns [boolean] true if killService was called - */ - function killServiceWasCalled() { - return compilerPlugin['service'] === undefined; - } - - it('should allow to pass no options', () => { - expect(() => { - new ForkTsCheckerWebpackPlugin(); - }).not.toThrowError(); - }); - - it('should detect paths', () => { - const plugin = new ForkTsCheckerWebpackPlugin({}); - - expect(plugin['tsconfig']).toBe('./tsconfig.json'); - }); - - it('should set logger to console by default', () => { - const plugin = new ForkTsCheckerWebpackPlugin({}); - - expect(plugin['logger']).toBe(console); - }); - - it('should find semantic errors', callback => { - const compiler = createCompiler({ - pluginOptions: { - tsconfig: 'tsconfig-semantic-error-only.json' - } - }); - - compiler.run((err, stats) => { - expect(stats.compilation.errors.length).toBeGreaterThanOrEqual(1); - callback(); - }); - }); - - it('should support custom resolution', callback => { - const compiler = createCompiler({ - pluginOptions: { - tsconfig: 'tsconfig-weird-resolutions.json', - resolveModuleNameModule: path.resolve( - __dirname, - '../fixtures/project/', - 'weirdResolver.js' - ), - resolveTypeReferenceDirectiveModule: path.resolve( - __dirname, - '../fixtures/project/', - 'weirdResolver.js' - ) - } - }); - - compiler.run((err, stats) => { - expect(stats.compilation.errors.length).toBe(0); - callback(); - }); - }); - - ifNotIncrementalIt( - 'should support custom resolution w/ "paths"', - callback => { - const compiler = createCompiler({ - pluginOptions: { - tsconfig: 'tsconfig-weird-resolutions-with-paths.json', - resolveModuleNameModule: path.resolve( - __dirname, - '../fixtures/project/', - 'weirdResolver.js' - ), - resolveTypeReferenceDirectiveModule: path.resolve( - __dirname, - '../fixtures/project/', - 'weirdResolver.js' - ) - } - }); - - compiler.run((err, stats) => { - expect(stats.compilation.errors.length).toBe(0); - callback(); - }); - } - ); - - ifNodeGte8It('should detect eslints', callback => { - const compiler = createCompiler({ - context: './project_eslint', - entryPoint: './src/index.ts', - pluginOptions: { eslint: true } - }); - - compiler.run((err, stats) => { - const { warnings, errors } = stats.compilation; - expect(warnings.length).toBe(2); - - const [warning, warning2] = warnings; - const actualFile = unixify(warning.file); - const expectedFile = unixify('src/lib/func.ts'); - expect(actualFile).toContain(expectedFile); - expect(warning.rawMessage).toContain('WARNING'); - expect(warning.rawMessage).toContain('@typescript-eslint/array-type'); - expect(warning.rawMessage).toContain( - "Array type using 'Array' is forbidden. Use 'string[]' instead." - ); - expect(warning.location).toEqual({ - character: 44, - line: 3 - }); - - const actualFile2 = unixify(warning2.file); - const expectedFile2 = unixify('src/lib/otherFunc.js'); - expect(actualFile2).toContain(expectedFile2); - expect(warning2.rawMessage).toContain('WARNING'); - expect(warning2.rawMessage).toContain( - '@typescript-eslint/no-unused-vars' - ); - expect(warning2.rawMessage).toContain( - "'i' is assigned a value but never used." - ); - expect(warning2.location).toEqual({ - character: 5, - line: 4 - }); - - const error = errors.find(err => - err.rawMessage.includes('@typescript-eslint/array-type') - ); - const actualErrorFile = unixify(error.file); - const expectedErrorFile = unixify('src/index.ts'); - expect(actualErrorFile).toContain(expectedErrorFile); - expect(error.rawMessage).toContain('ERROR'); - expect(error.rawMessage).toContain('@typescript-eslint/array-type'); - expect(error.rawMessage).toContain( - "Array type using 'Array' is forbidden. Use 'string[]' instead." - ); - expect(error.location).toEqual({ - character: 43, - line: 5 - }); - - callback(); - }); - }); - - ifNodeLt8It( - 'throws an error about Node.js version required for `eslint` option', - () => { - expect(() => { - createCompiler({ - context: './project_eslint', - entryPoint: './src/index.ts', - pluginOptions: { eslint: true } - }); - }).toThrowError( - `To use 'eslint' option, please update to Node.js >= v8.10.0 ` + - `(current version is ${process.version})` - ); - } - ); - - it('should block emit on build mode', callback => { - const compiler = createCompiler(); - - const forkTsCheckerHooks = ForkTsCheckerWebpackPlugin.getCompilerHooks( - compiler - ); - forkTsCheckerHooks.emit.tap('should block emit on build mode', () => { - expect(true).toBe(true); - callback(); - }); - - compiler.run(() => { - /**/ - }); - }); - - it('should not block emit on watch mode', callback => { - const compiler = createCompiler(); - const watching = compiler.watch({}, () => { - /**/ - }); - - const forkTsCheckerHooks = ForkTsCheckerWebpackPlugin.getCompilerHooks( - compiler - ); - forkTsCheckerHooks.done.tap('should not block emit on watch mode', () => { - watching.close(() => { - expect(true).toBe(true); - callback(); - }); - }); - }); - - it('should block emit if async flag is false', callback => { - const compiler = createCompiler({ pluginOptions: { async: false } }); - const watching = compiler.watch({}, () => { - /**/ - }); - - const forkTsCheckerHooks = ForkTsCheckerWebpackPlugin.getCompilerHooks( - compiler - ); - forkTsCheckerHooks.emit.tap( - 'should block emit if async flag is false', - () => { - watching.close(() => { - expect(true).toBe(true); - callback(); - }); - } - ); - }); - - it('kills the service when the watch is done', done => { - const compiler = createCompiler(); - const watching = compiler.watch({}, () => { - /**/ - }); - - const forkTsCheckerHooks = ForkTsCheckerWebpackPlugin.getCompilerHooks( - compiler - ); - forkTsCheckerHooks.done.tap( - 'kills the service when the watch is done', - () => { - watching.close(() => { - expect(killServiceWasCalled()).toBe(true); - done(); - }); - } - ); - }); - - it('should throw error if config container wrong tsconfig.json path', () => { - expect(() => { - createCompiler({ - pluginOptions: { - tsconfig: '/some/path/that/not/exists/tsconfig.json' - } - }); - }).toThrowError(); - }); - - it('should allow delaying service-start', callback => { - const compiler = createCompiler(); - let delayed = false; - - const forkTsCheckerHooks = ForkTsCheckerWebpackPlugin.getCompilerHooks( - compiler - ); - forkTsCheckerHooks.serviceBeforeStart.tapAsync( - 'should allow delaying service-start', - (cb: () => void) => { - setTimeout(() => { - delayed = true; - - cb(); - }, 0); - } - ); - - forkTsCheckerHooks.serviceBeforeStart.tap( - 'should allow delaying service-start', - () => { - expect(delayed).toBe(true); - callback(); - } - ); - - compiler.run(() => { - /** */ - }); - }); - - it('should not find syntactic errors when checkSyntacticErrors is false', callback => { - const compiler = createCompiler({ - pluginOptions: { checkSyntacticErrors: false }, - happyPackMode: true - }); - - compiler.run((_error, stats) => { - const syntacticErrorNotFoundInStats = stats.compilation.errors.every( - error => - !error.rawMessage.includes( - helpers.expectedErrorCodes.expectedSyntacticErrorCode - ) - ); - expect(syntacticErrorNotFoundInStats).toBe(true); - callback(); - }); - }); - - it('should find syntactic errors when checkSyntacticErrors is true', callback => { - const compiler = createCompiler({ - pluginOptions: { checkSyntacticErrors: true }, - happyPackMode: true - }); - - compiler.run((_error, stats) => { - const syntacticErrorFoundInStats = stats.compilation.errors.some( - error => - error.rawMessage.includes( - helpers.expectedErrorCodes.expectedSyntacticErrorCode - ) - ); - expect(syntacticErrorFoundInStats).toBe(true); - callback(); - }); - }); - - /** - * regression test for #267, #299 - */ - it('should work even when the plugin has been deep-cloned', callback => { - const compiler = createCompiler({ - pluginOptions: { - tsconfig: 'tsconfig-semantic-error-only.json' - }, - prepareWebpackConfig({ plugins, ...config }) { - return { ...config, plugins: cloneDeep(plugins) }; - } - }); - - compiler.run((err, stats) => { - expect(stats.compilation.errors).toEqual([ - expect.objectContaining({ - message: expect.stringContaining('TS2322') - }) - ]); - callback(); - }); - }); - } -); diff --git a/test/integration/helpers/createCompiler.ts b/test/integration/helpers/createCompiler.ts deleted file mode 100644 index 774d6787..00000000 --- a/test/integration/helpers/createCompiler.ts +++ /dev/null @@ -1,181 +0,0 @@ -import webpack from 'webpack'; -import * as path from 'path'; -import * as fs from 'fs'; -import * as copyDir from 'copy-dir'; -import * as rimraf from 'rimraf'; -import { ForkTsCheckerWebpackPlugin } from './'; - -if (!beforeAll || !afterAll) { - throw new Error('file should not be included outside of jest!'); -} - -const baseTmpDir = path.resolve(__dirname, '../../tmp'); -/** - * parent folder to create all files for integration tests in - * needs to be a random folder so that jest may execute multiple tests in parallel without conflicts - * will be set in beforeAll callback - */ -let tmpDirParent: string; -let lastInstantiatedPlugin: ForkTsCheckerWebpackPlugin | undefined; - -beforeAll(function init() { - if (!fs.existsSync(baseTmpDir)) { - fs.mkdirSync(baseTmpDir); - } - - tmpDirParent = fs.mkdtempSync( - path.join(baseTmpDir, 'fork-ts-checker-webpack-plugin-test') - ); -}); - -afterAll(function cleanUp() { - rimraf.sync(tmpDirParent); -}); - -afterEach(function killPlugin() { - if (lastInstantiatedPlugin && lastInstantiatedPlugin['service']) { - lastInstantiatedPlugin['killService'](); - } -}); - -export interface CreateCompilerOptions { - entryPoint: string; - context: string; - happyPackMode: boolean; - pluginOptions: Partial; - prepareWebpackConfig(config: webpack.Configuration): webpack.Configuration; - nodeRequires: string[]; - normalizeDiagnosticsPaths: boolean; -} - -const defaultOptions: Partial = { - silent: true -}; - -interface CreateCompilerResults { - compiler: webpack.Compiler; - readonly compilerConfig: webpack.Configuration; - plugin: ForkTsCheckerWebpackPlugin; - contextDir: string; - outDir: string; - tmpDir: string; -} - -/** - * prepares a directory to run an integration test in by - * * creating a new temporary folder below `tmpDirParent` - * * copying the contents of the passed `context` directory (relative to ../../fixtures) over - * * returning the name of the newly created temporary folder - */ -function prepareDirectory({ context }: { context: string }) { - if (!fs.existsSync(tmpDirParent)) { - fs.mkdirSync(tmpDirParent); - } - const tmpDir = fs.mkdtempSync(path.join(tmpDirParent, 'test')); - const contextDir = path.resolve(tmpDir, context); - const outDir = path.resolve(tmpDir, 'out'); - fs.mkdirSync(contextDir); - fs.mkdirSync(outDir); - copyDir.sync(path.resolve(__dirname, '../../fixtures/', context), contextDir); - return { contextDir, outDir, tmpDir }; -} - -/** - * removes the "temporary folder" part from all diagnostics' paths and replaces it with "/test-context" - */ -function normalizeDiagnosticsPaths( - diagnostics: { - rawMessage: string; - message: string; - file: string; - }[], - contextDir: string -) { - contextDir = contextDir.replace(/\/$/, ''); - return diagnostics.map(diagnostic => ({ - ...diagnostic, - file: - diagnostic.file && diagnostic.file.replace(contextDir, '/test-context'), - message: - diagnostic.message && - diagnostic.message.replace(contextDir, '/test-context'), - rawMessage: - diagnostic.message && - diagnostic.message.replace(contextDir, '/test-context') - })); -} - -export function createCompiler({ - pluginOptions = {}, - happyPackMode = false, - entryPoint = './src/index.ts', - context = './project', - prepareWebpackConfig = config => config, - nodeRequires = [], - normalizeDiagnosticsPaths: normalizePaths = true -}: Partial = {}): CreateCompilerResults { - const { contextDir, outDir, tmpDir } = prepareDirectory({ context }); - - pluginOptions = { ...defaultOptions, ...pluginOptions }; - - const plugin = new ForkTsCheckerWebpackPlugin(pluginOptions); - plugin['nodeArgs'] = nodeRequires.reduce((acc, fileName) => { - acc.push('--require', `${path.resolve(__dirname, fileName)}`); - return acc; - }, []); - lastInstantiatedPlugin = plugin; - - const tsLoaderOptions = happyPackMode - ? { happyPackMode: true, silent: true } - : { transpileOnly: true, silent: true }; - - const compilerConfig = prepareWebpackConfig({ - mode: 'development', - context: contextDir, - entry: entryPoint, - output: { - path: outDir - }, - resolve: { - extensions: ['.ts', '.js', '.tsx', '.json'] - }, - module: { - rules: [ - { - test: /\.tsx?$/, - loader: 'ts-loader', - options: tsLoaderOptions - } - ] - }, - plugins: [plugin] - }); - - const compiler = webpack(compilerConfig); - - if (normalizePaths) { - const originalRun = compiler.run; - compiler.run = handler => { - originalRun.call(compiler, (error: Error, stats: webpack.Stats) => { - stats.compilation.errors = normalizeDiagnosticsPaths( - stats.compilation.errors, - contextDir - ); - stats.compilation.warnings = normalizeDiagnosticsPaths( - stats.compilation.warnings, - contextDir - ); - return handler(error, stats); - }); - }; - } - - return { - compiler, - plugin, - compilerConfig, - contextDir, - outDir, - tmpDir - }; -} diff --git a/test/integration/helpers/createVueCompiler.ts b/test/integration/helpers/createVueCompiler.ts deleted file mode 100644 index 0ace739f..00000000 --- a/test/integration/helpers/createVueCompiler.ts +++ /dev/null @@ -1,104 +0,0 @@ -import * as VueLoader from 'vue-loader'; // import for types alone -import * as path from 'path'; -import { RpcProvider } from 'worker-rpc'; - -// eslint-disable-next-line @typescript-eslint/ban-ts-ignore -// @ts-ignore -import { rpcMethods } from './rpc'; -import { CreateCompilerOptions, createCompiler } from '.'; - -let VueLoaderPlugin: typeof VueLoader.VueLoaderPlugin; -try { - VueLoaderPlugin = require('vue-loader/lib/plugin'); -} catch { - /** older versions of vue-loader come without that import - that's fine. */ -} - -export async function createVueCompiler({ - context = './vue', - nodeRequires = [], - prepareWebpackConfig = x => x, - ...otherOptions -}: Partial = {}) { - const results = createCompiler({ - ...otherOptions, - context, - nodeRequires: [ - ...nodeRequires, - '../mocks/IncrementalCheckerWithRpc.js', - '../mocks/ApiIncrementalCheckerWithRpc.js' - ], - prepareWebpackConfig(config) { - return prepareWebpackConfig({ - ...config, - resolve: { - extensions: ['.ts', '.js', '.vue', '.json'], - alias: { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - '@': path.resolve(config.context!, './src'), - surprise: './src/index.ts' - } - }, - module: { - rules: [ - { - test: /\.vue$/, - loader: 'vue-loader' - }, - { - test: /\.ts$/, - loader: 'ts-loader', - options: { - appendTsSuffixTo: [/\.vue$/], - transpileOnly: true, - silent: true - } - }, - { - test: /\.css$/, - loader: 'css-loader' - } - ] - }, - plugins: [ - ...(config.plugins || []), - ...(!!VueLoaderPlugin ? [new VueLoaderPlugin()] : []) - ] - }); - } - }); - - const { compilerConfig, plugin } = results; - - const files = { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - 'example.vue': path.resolve(compilerConfig.context!, 'src/example.vue'), - 'syntacticError.ts': path.resolve( - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - compilerConfig.context!, - 'src/syntacticError.ts' - ) - }; - - plugin['spawnService'](); - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const rpcProvider: RpcProvider = plugin['serviceRpc']!; - await rpcProvider.rpc(rpcMethods.nextIteration); - - return { - ...results, - files, - rpcProvider, - getKnownFileNames(): Promise { - return rpcProvider.rpc(rpcMethods.getKnownFileNames); - }, - getSourceFile(fileName: string): Promise<{ text: string } | undefined> { - return rpcProvider.rpc(rpcMethods.getSourceFile, fileName); - }, - getSyntacticDiagnostics(): Promise< - { start: number; length: number; file: { text: string } }[] | undefined - > { - return rpcProvider.rpc(rpcMethods.getSyntacticDiagnostics); - } - }; -} diff --git a/test/integration/helpers/index.ts b/test/integration/helpers/index.ts deleted file mode 100644 index 769823fd..00000000 --- a/test/integration/helpers/index.ts +++ /dev/null @@ -1,13 +0,0 @@ -import ForkTsCheckerWebpackPlugin from '../../../lib'; -export { ForkTsCheckerWebpackPlugin }; -export { createCompiler, CreateCompilerOptions } from './createCompiler'; -export { createVueCompiler } from './createVueCompiler'; -// eslint-disable-next-line @typescript-eslint/ban-ts-ignore -// @ts-ignore -export { getRpcProvider, rpcMethods } from './rpc'; - -export const expectedErrorCodes = { - expectedSyntacticErrorCode: 'TS1005', - expectedSemanticErrorCode: 'TS2322', - expectedGlobalErrorCode: 'TS1149' -}; diff --git a/test/integration/helpers/rpc.js b/test/integration/helpers/rpc.js deleted file mode 100644 index 15aaac60..00000000 --- a/test/integration/helpers/rpc.js +++ /dev/null @@ -1,29 +0,0 @@ -const RpcProvider = require('worker-rpc').RpcProvider; - -/** - * this file needs to be JavaScript because it is directly required from files - * that are injected into node using --require - */ - -exports.rpcMethods = { - nextIteration: 'checker_nextIteration', - getKnownFileNames: 'checker_getKnownFileNames', - getSourceFile: 'checker_getSourceFile', - getSyntacticDiagnostics: 'checker_getSyntacticDiagnostics' -}; - -/** @type {RpcProvider} */ -let rpc; - -exports.getRpcProvider = () => { - if (!rpc) { - rpc = new RpcProvider(message => { - if (process && process.send) { - return process.send(message); - } - }); - process.on('message', message => rpc.dispatchCall(message)); - } - - return rpc; -}; diff --git a/test/integration/incrementalApi.spec.ts b/test/integration/incrementalApi.spec.ts deleted file mode 100644 index 6c2f7235..00000000 --- a/test/integration/incrementalApi.spec.ts +++ /dev/null @@ -1,89 +0,0 @@ -/* - * This file includes tests related to useTypescriptIncrementalApi flag. - * Since we are using different compiler API in that case, we cannot - * force exactly same behavior, hence the differences between same cases - * here vs. other files. - * - * */ -import fs from 'fs'; -import * as helpers from './helpers'; - -describe('[INTEGRATION] specific tests for useTypescriptIncrementalApi: true', () => { - function createCompiler(options: Partial) { - const { compiler } = helpers.createCompiler({ - ...options, - pluginOptions: { - ...options.pluginOptions, - useTypescriptIncrementalApi: true - } - }); - return compiler; - } - - function createVueCompiler(options: Partial) { - return helpers.createVueCompiler({ - ...options, - pluginOptions: { - ...options.pluginOptions, - useTypescriptIncrementalApi: true, - vue: true - } - }); - } - - it('should get syntactic diagnostics from Vue program', callback => { - createVueCompiler({ pluginOptions: { checkSyntacticErrors: true } }).then( - ({ compiler }) => - compiler.run((_error, stats) => { - const syntacticErrorFoundInStats = stats.compilation.errors.some( - error => - error.rawMessage.includes( - helpers.expectedErrorCodes.expectedSyntacticErrorCode - ) - ); - expect(syntacticErrorFoundInStats).toBe(true); - callback(); - }) - ); - }); - - it('should not find syntactic errors in Vue program when checkSyntacticErrors is false', callback => { - createVueCompiler({ pluginOptions: { checkSyntacticErrors: false } }).then( - ({ compiler }) => - compiler.run((_error, stats) => { - const syntacticErrorNotFoundInStats = stats.compilation.errors.every( - error => - !error.rawMessage.includes( - helpers.expectedErrorCodes.expectedSyntacticErrorCode - ) - ); - expect(syntacticErrorNotFoundInStats).toBe(true); - callback(); - }) - ); - }); - - const isCaseInsensitiveFilesystem = fs.existsSync( - __dirname + '/../fixtures/caseSensitiveProject/src/Lib.ts' - ); - - (isCaseInsensitiveFilesystem ? it : it.skip)( - 'should find global errors even when checkSyntacticErrors is false (can only be tested on case-insensitive file systems)', - callback => { - const compiler = createCompiler({ - context: './caseSensitiveProject', - pluginOptions: { checkSyntacticErrors: false } - }); - - compiler.run((_error, stats) => { - const globalErrorFoundInStats = stats.compilation.errors.some(error => - error.rawMessage.includes( - helpers.expectedErrorCodes.expectedGlobalErrorCode - ) - ); - expect(globalErrorFoundInStats).toBe(true); - callback(); - }); - } - ); -}); diff --git a/test/integration/mocks/ApiIncrementalCheckerWithRpc.js b/test/integration/mocks/ApiIncrementalCheckerWithRpc.js deleted file mode 100644 index 886f7fa6..00000000 --- a/test/integration/mocks/ApiIncrementalCheckerWithRpc.js +++ /dev/null @@ -1,53 +0,0 @@ -const mock = require('mock-require'); -const origImport = require('../../../lib/ApiIncrementalChecker'); -const { rpcMethods, getRpcProvider } = require('../helpers/rpc'); - -mock('../../../lib/ApiIncrementalChecker', { - ApiIncrementalChecker: class extends origImport.ApiIncrementalChecker { - constructor(...args) { - super(...args); - - const rpc = getRpcProvider(); - - const init = () => { - return ( - this.tsIncrementalCompiler.lastProcessing || - this.tsIncrementalCompiler.processChanges() - ); - }; - - rpc.registerRpcHandler(rpcMethods.nextIteration, () => { - return this.nextIteration(); - }); - - rpc.registerRpcHandler(rpcMethods.getKnownFileNames, () => { - return init().then(() => - Array.from(this.tsIncrementalCompiler.getAllKnownFiles()) - ); - }); - - rpc.registerRpcHandler(rpcMethods.getSourceFile, fileName => { - return init().then(() => { - const result = this.tsIncrementalCompiler - .getProgram() - .getSourceFile(fileName); - - return !result ? undefined : { text: result.text }; - }); - }); - - rpc.registerRpcHandler(rpcMethods.getSyntacticDiagnostics, () => { - return init().then(() => { - const result = this.tsIncrementalCompiler - .getProgram() - .getSyntacticDiagnostics(); - return result.map(({ start, length, file }) => ({ - start, - length, - file: { text: file.text } - })); - }); - }); - } - } -}); diff --git a/test/integration/mocks/IncrementalCheckerWithError.js b/test/integration/mocks/IncrementalCheckerWithError.js deleted file mode 100644 index 82d6a1e1..00000000 --- a/test/integration/mocks/IncrementalCheckerWithError.js +++ /dev/null @@ -1,9 +0,0 @@ -const mock = require('mock-require'); - -mock('../../../lib/IncrementalChecker', { - IncrementalChecker: class { - nextIteration() { - throw new Error("I'm an error!"); - } - } -}); diff --git a/test/integration/mocks/IncrementalCheckerWithRpc.js b/test/integration/mocks/IncrementalCheckerWithRpc.js deleted file mode 100644 index 039c963e..00000000 --- a/test/integration/mocks/IncrementalCheckerWithRpc.js +++ /dev/null @@ -1,35 +0,0 @@ -const mock = require('mock-require'); -const origImport = require('../../../lib/IncrementalChecker'); -const { rpcMethods, getRpcProvider } = require('../helpers/rpc'); - -mock('../../../lib/IncrementalChecker', { - IncrementalChecker: class extends origImport.IncrementalChecker { - constructor(...args) { - super(...args); - - const rpc = getRpcProvider(); - - rpc.registerRpcHandler(rpcMethods.nextIteration, () => { - return this.nextIteration(); - }); - - rpc.registerRpcHandler(rpcMethods.getKnownFileNames, () => { - return this.programConfig.fileNames; - }); - - rpc.registerRpcHandler(rpcMethods.getSourceFile, fileName => { - const result = this.program.getSourceFile(fileName); - return !result ? undefined : { text: result.text }; - }); - - rpc.registerRpcHandler(rpcMethods.getSyntacticDiagnostics, () => { - const result = this.program.getSyntacticDiagnostics(); - return result.map(({ start, length, file }) => ({ - start, - length, - file: { text: file.text } - })); - }); - } - } -}); diff --git a/test/integration/nonIncrementalApi.spec.ts b/test/integration/nonIncrementalApi.spec.ts deleted file mode 100644 index a2436ad8..00000000 --- a/test/integration/nonIncrementalApi.spec.ts +++ /dev/null @@ -1,68 +0,0 @@ -import path from 'path'; -import * as helpers from './helpers'; - -describe('[INTEGRATION] specific tests for useTypescriptIncrementalApi: false', () => { - let plugin: helpers.ForkTsCheckerWebpackPlugin; - - function createCompiler( - options: Partial = {} - ) { - const compiler = helpers.createCompiler({ - ...options, - pluginOptions: { - ...options.pluginOptions, - useTypescriptIncrementalApi: false - } - }); - plugin = compiler.plugin; - return compiler.compiler; - } - - it('should work without configuration', callback => { - const compiler = createCompiler(); - - compiler.run((err, stats) => { - expect(stats.compilation.errors.length).toBeGreaterThanOrEqual(1); - callback(); - }); - }); - - it('should only show errors matching paths specified in reportFiles when provided', callback => { - const compiler = createCompiler({ - pluginOptions: { - checkSyntacticErrors: true, - reportFiles: ['**/index.ts'] - }, - happyPackMode: true - }); - - // this test doesn't make as much sense in the context of using the incremental API - // as in that case the compiler will stop looking for further errors when it finds one - // see https://github.com/TypeStrong/fork-ts-checker-webpack-plugin/pull/198#issuecomment-453790649 for details - compiler.run((error, stats) => { - expect(stats.compilation.errors.length).toBe(1); - expect(stats.compilation.errors[0]).toEqual( - expect.objectContaining({ file: expect.stringMatching(/index.ts$/) }) - ); - callback(); - }); - }); - - it('should handle errors within the IncrementalChecker gracefully as diagnostic', callback => { - const compiler = createCompiler(); - plugin['nodeArgs'] = [ - `--require`, - `${path.resolve(__dirname, './mocks/IncrementalCheckerWithError.js')}` - ]; - - compiler.run((error, stats) => { - expect(stats.compilation.errors.length).toBe(1); - expect(stats.compilation.errors[0]).toEqual( - expect.objectContaining({ - message: expect.stringContaining("I'm an error!") - }) - ); - callback(); - }); - }); -}); diff --git a/test/integration/tsconfig.json b/test/integration/tsconfig.json deleted file mode 100644 index f6e3b427..00000000 --- a/test/integration/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "compilerOptions": { - "target": "es2015", - "module": "commonjs", - "allowJs": true, - "checkJs": true, - "strict": true, - "esModuleInterop": true - }, - "include": ["../types/**.d.ts", "./**/*.ts"] -} diff --git a/test/integration/vue.spec.ts b/test/integration/vue.spec.ts deleted file mode 100644 index cebb8318..00000000 --- a/test/integration/vue.spec.ts +++ /dev/null @@ -1,360 +0,0 @@ -import path from 'path'; -import unixify from 'unixify'; -import { - createVueCompiler, - expectedErrorCodes, - CreateCompilerOptions -} from './helpers'; - -interface Error { - file: string; - rawMessage: string; -} - -const vueTplCompilers = [ - 'vue-template-compiler', - 'nativescript-vue-template-compiler' -] as const; - -const useTypescriptIncrementalApiOptions = [ - /* true, */ - false -] as const; - -// eslint-disable-next-line @typescript-eslint/array-type -function mixLists(list1: ReadonlyArray, list2: ReadonlyArray) { - return list1.reduce( - (acc, item1) => acc.concat(list2.map(item2 => [item1, item2])), - [] as [T1, T2][] - ); -} - -describe.each(mixLists(useTypescriptIncrementalApiOptions, vueTplCompilers))( - '[INTEGRATION] vue tests - useTypescriptIncrementalApi: %s, vue tpl compiler: %s', - (useTypescriptIncrementalApi, vueTplCompiler) => { - const vueEnabledOption = { enabled: true, compiler: vueTplCompiler }; - const testOnlyFirstVueTplCompiler = - vueEnabledOption.compiler !== vueTplCompilers[0] ? it.skip : it; - - const createCompiler = (options: Partial = {}) => - createVueCompiler({ - ...options, - pluginOptions: { ...options.pluginOptions, useTypescriptIncrementalApi } - }); - - it('should require valid template compiler: %s', async () => { - const tplCompiler = vueEnabledOption.compiler; - const bannedMocks = vueTplCompilers - .filter(dep => dep !== tplCompiler) - .map(bannedDep => { - const bannedMock = jest.fn(() => jest.requireActual(bannedDep)); - jest.doMock(bannedDep, bannedMock); - return bannedMock; - }); - const requiredMock = jest.fn(() => jest.requireActual(tplCompiler)); - jest.doMock(tplCompiler, requiredMock); - - const { compiler } = await createCompiler({ - pluginOptions: { vue: { enabled: true, compiler: tplCompiler } } - }); - - compiler.run(() => { - expect(requiredMock).toBeCalled(); - bannedMocks.forEach(bannedMock => { - expect(bannedMock).not.toBeCalled(); - }); - }); - }); - - it('should create a Vue program config if vue is enabled', async () => { - const { getKnownFileNames, files } = await createCompiler({ - pluginOptions: { vue: vueEnabledOption } - }); - - const fileNames = await getKnownFileNames(); - - let fileFound; - let fileWeWant = unixify(files['example.vue']); - fileFound = fileNames.some(filename => unixify(filename) === fileWeWant); - expect(fileFound).toBe(true); - - fileWeWant = unixify(files['syntacticError.ts']); - fileFound = fileNames.some(filename => unixify(filename) === fileWeWant); - expect(fileFound).toBe(true); - }); - - testOnlyFirstVueTplCompiler( - 'should not create a Vue program config if vue is disabled', - async () => { - const { getKnownFileNames, files } = await createCompiler(); - - const fileNames = await getKnownFileNames(); - - let fileFound; - let fileWeWant = unixify(files['example.vue']); - - fileFound = fileNames.some( - filename => unixify(filename) === fileWeWant - ); - expect(fileFound).toBe(false); - - fileWeWant = unixify(files['syntacticError.ts']); - fileFound = fileNames.some( - filename => unixify(filename) === fileWeWant - ); - expect(fileFound).toBe(true); - } - ); - - it('should create a Vue program if vue is enabled', async () => { - const { getSourceFile, files } = await createCompiler({ - pluginOptions: { vue: vueEnabledOption } - }); - - let source; - - source = await getSourceFile(files['example.vue']); - expect(source).toBeDefined(); - - source = await getSourceFile(files['syntacticError.ts']); - expect(source).toBeDefined(); - }); - - testOnlyFirstVueTplCompiler( - 'should not create a Vue program if vue is disabled', - async () => { - const { getSourceFile, files } = await createCompiler(); - - let source; - - source = await getSourceFile(files['example.vue']); - expect(source).toBeUndefined(); - - source = await getSourceFile(files['syntacticError.ts']); - expect(source).toBeDefined(); - } - ); - - it('should get syntactic diagnostics from Vue program', async () => { - const { getSyntacticDiagnostics } = await createCompiler({ - pluginOptions: { vue: vueEnabledOption } - }); - - const diagnostics = await getSyntacticDiagnostics(); - expect(diagnostics).toBeDefined(); - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - expect(diagnostics!.length).toBe(1); - }); - - it('should not find syntactic errors when checkSyntacticErrors is false', callback => { - createCompiler({ pluginOptions: { vue: true } }).then(({ compiler }) => - compiler.run((_error, stats) => { - const syntacticErrorNotFoundInStats = stats.compilation.errors.every( - error => - !error.rawMessage.includes( - expectedErrorCodes.expectedSyntacticErrorCode - ) - ); - expect(syntacticErrorNotFoundInStats).toBe(true); - callback(); - }) - ); - }); - - it('should find syntactic errors when checkSyntacticErrors is true', callback => { - createCompiler({ - pluginOptions: { - vue: true, - checkSyntacticErrors: true - } - }).then(({ compiler }) => - compiler.run((_error, stats) => { - const syntacticErrorFoundInStats = stats.compilation.errors.some( - error => - error.rawMessage.includes( - expectedErrorCodes.expectedSyntacticErrorCode - ) - ); - expect(syntacticErrorFoundInStats).toBe(true); - callback(); - }) - ); - }); - - it('should resolve src attribute but not report not found error', callback => { - createCompiler({ - pluginOptions: { - vue: vueEnabledOption, - tsconfig: 'tsconfig-attrs.json' - } - }).then(({ compiler }) => - compiler.run((error, stats) => { - const errors = stats.compilation.errors; - expect(errors.length).toBe(1); - expect(errors[0].file).toContain('/src/attrs/test.ts'); - callback(); - }) - ); - }); - - it.each([ - 'example-ts.vue', - 'example-tsx.vue', - 'example-js.vue', - 'example-jsx.vue', - 'example-nolang.vue' - ])('should be able to extract script from %s', async fileName => { - const { getSourceFile, contextDir } = await createCompiler({ - pluginOptions: { - vue: vueEnabledOption, - tsconfig: 'tsconfig-langs.json' - } - }); - const sourceFilePath = path.resolve(contextDir, 'src/langs/' + fileName); - const source = await getSourceFile(sourceFilePath); - expect(source).toBeDefined(); - // remove padding lines - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const text = source!.text.replace(/^\s*\/\/.*$\r*\n/gm, '').trim(); - expect(text.startsWith('/* OK */')).toBe(true); - }); - - function groupByFileName(errors: Error[]) { - const ret: { [key: string]: Error[] } = { - 'index.ts': [], - 'example-ts.vue': [], - 'example-tsx.vue': [], - 'example-js.vue': [], - 'example-jsx.vue': [], - 'example-nolang.vue': [], - 'example-ts-with-errors.vue': [] - }; - for (const error of errors) { - ret[path.basename(error.file)].push(error); - } - return ret; - } - - describe('should be able to compile *.vue with each lang', () => { - let errors: { [key: string]: Error[] } = {}; - beforeAll(callback => { - createCompiler({ - pluginOptions: { - vue: vueEnabledOption, - tsconfig: 'tsconfig-langs.json' - } - }).then(({ compiler }) => - compiler.run((error, stats) => { - errors = groupByFileName(stats.compilation.errors); - callback(); - }) - ); - }); - it('lang=ts', () => { - expect(errors['example-ts.vue'].length).toBe(0); - }); - it('lang=tsx', () => { - expect(errors['example-tsx.vue'].length).toBe(0); - }); - it('lang=js', () => { - expect(errors['example-js.vue'].length).toBe(0); - }); - it('lang=jsx', () => { - expect(errors['example-jsx.vue'].length).toBe(0); - }); - it('no lang', () => { - expect(errors['example-nolang.vue'].length).toBe(0); - }); - it('counter check - invalid code produces errors', () => { - expect(errors['example-ts-with-errors.vue'].length).toBeGreaterThan(0); - }); - }); - - describe('should be able to detect errors in *.vue', () => { - let errors: { [key: string]: Error[] } = {}; - beforeAll(callback => { - // tsconfig-langs-strict.json === tsconfig-langs.json + noUnusedLocals - createCompiler({ - pluginOptions: { - vue: vueEnabledOption, - tsconfig: 'tsconfig-langs-strict.json' - } - }).then(({ compiler }) => - compiler.run((error, stats) => { - errors = groupByFileName(stats.compilation.errors); - callback(); - }) - ); - }); - it('lang=ts', () => { - expect(errors['example-ts.vue'].length).toBe(1); - expect(errors['example-ts.vue'][0].rawMessage).toMatch( - /'a' is declared but/ - ); - }); - it('lang=tsx', () => { - expect(errors['example-tsx.vue'].length).toBe(1); - expect(errors['example-tsx.vue'][0].rawMessage).toMatch( - /'a' is declared but/ - ); - }); - it('lang=js', () => { - expect(errors['example-js.vue'].length).toBe(0); - }); - it('lang=jsx', () => { - expect(errors['example-jsx.vue'].length).toBe(0); - }); - it('no lang', () => { - expect(errors['example-nolang.vue'].length).toBe(0); - }); - }); - - describe('should resolve *.vue in the same way as TypeScript', () => { - let errors: Error[] = []; - beforeAll(callback => { - createCompiler({ - pluginOptions: { - vue: vueEnabledOption, - tsconfig: 'tsconfig-imports.json' - } - }).then(({ compiler }) => - compiler.run((error, stats) => { - errors = stats.compilation.errors; - callback(); - }) - ); - }); - - it('should be able to import by relative path', () => { - expect( - errors.filter(e => e.rawMessage.indexOf('./Component1.vue') >= 0) - .length - ).toBe(0); - }); - it('should be able to import by path from baseUrl', () => { - expect( - errors.filter( - e => e.rawMessage.indexOf('imports/Component2.vue') >= 0 - ).length - ).toBe(0); - }); - it('should be able to import by compilerOptions.paths setting', () => { - expect( - errors.filter(e => e.rawMessage.indexOf('@/Component3.vue') >= 0) - .length - ).toBe(0); - }); - it('should be able to import by compilerOptions.paths setting (by array)', () => { - expect( - errors.filter(e => e.rawMessage.indexOf('foo/Foo1.vue') >= 0).length - ).toBe(0); - expect( - errors.filter(e => e.rawMessage.indexOf('foo/Foo2.vue') >= 0).length - ).toBe(0); - }); - it('counter check - should report report one generic compilation error', () => { - expect(errors.length).toBe(1); - }); - }); - } -); diff --git a/test/json.d.ts b/test/json.d.ts deleted file mode 100644 index bbab69d2..00000000 --- a/test/json.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -declare module '*.json' { - const value: any; - export default value; -} diff --git a/test/tsconfig.json b/test/tsconfig.json index e5d93331..96c07217 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -7,7 +7,8 @@ "esModuleInterop": true, "skipLibCheck": true, "skipDefaultLibCheck": true, - "baseUrl": "../src" + "baseUrl": "../" }, - "include": ["../src", "."] + "include": ["../lib", "**/*.spec.ts"], + "exclude": ["node_modules"] } diff --git a/test/types/copy-dir.d.ts b/test/types/copy-dir.d.ts deleted file mode 100644 index e3542ac9..00000000 --- a/test/types/copy-dir.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -declare module 'copy-dir' { - const copydir: { - (from: string, to: string, callback: (err: Error) => void): void; - ( - from: string, - to: string, - filter: Function, - callback: (err: Error) => void - ): void; - sync(from: string, to: string, filter?: Function): void; - }; - export = copydir; -} diff --git a/test/types/unixify.d.ts b/test/types/unixify.d.ts deleted file mode 100644 index 91f6b67b..00000000 --- a/test/types/unixify.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -declare module 'unixify' { - function unixify(filePath: string, stripTrailingSlash?: boolean): string; - export = unixify; -} diff --git a/test/types/vue-loader.d.ts b/test/types/vue-loader.d.ts deleted file mode 100644 index 45d6411e..00000000 --- a/test/types/vue-loader.d.ts +++ /dev/null @@ -1 +0,0 @@ -declare module 'vue-loader/lib/plugin'; diff --git a/test/unit/ForkTsCheckerWebpackPlugin.spec.ts b/test/unit/ForkTsCheckerWebpackPlugin.spec.ts index 5a2e951a..18684bbf 100644 --- a/test/unit/ForkTsCheckerWebpackPlugin.spec.ts +++ b/test/unit/ForkTsCheckerWebpackPlugin.spec.ts @@ -1,4 +1,4 @@ -import { ForkTsCheckerWebpackPlugin } from '../../lib/ForkTsCheckerWebpackPlugin'; +import { ForkTsCheckerWebpackPlugin } from 'lib/ForkTsCheckerWebpackPlugin'; describe('ForkTsCheckerWebpackPlugin', () => { it.each([{ invalid: true }, false, null, 'unknown string', { typescript: 'invalid option' }])( diff --git a/test/unit/formatter/BasicFormatter.spec.ts b/test/unit/formatter/BasicFormatter.spec.ts index b7498e66..65826c3f 100644 --- a/test/unit/formatter/BasicFormatter.spec.ts +++ b/test/unit/formatter/BasicFormatter.spec.ts @@ -1,5 +1,5 @@ -import { Issue } from '../../../lib/issue'; -import { createBasicFormatter } from '../../../lib/formatter'; +import { Issue } from 'lib/issue'; +import { createBasicFormatter } from 'lib/formatter'; describe('formatter/BasicFormatter', () => { it.each([ diff --git a/test/unit/formatter/CodeframeFormatter.spec.ts b/test/unit/formatter/CodeframeFormatter.spec.ts index 3e59bb48..f9a59bd5 100644 --- a/test/unit/formatter/CodeframeFormatter.spec.ts +++ b/test/unit/formatter/CodeframeFormatter.spec.ts @@ -1,7 +1,7 @@ import * as os from 'os'; import mockFs from 'mock-fs'; -import { Issue } from '../../../lib/issue'; -import { createCodeframeFormatter } from '../../../lib/formatter'; +import { Issue } from 'lib/issue'; +import { createCodeframeFormatter } from 'lib/formatter'; describe('formatter/CodeframeFormatter', () => { beforeEach(() => { diff --git a/test/unit/formatter/FormatterConfiguration.spec.ts b/test/unit/formatter/FormatterConfiguration.spec.ts index 065b5d6c..57fccd27 100644 --- a/test/unit/formatter/FormatterConfiguration.spec.ts +++ b/test/unit/formatter/FormatterConfiguration.spec.ts @@ -1,7 +1,7 @@ import os from 'os'; import mockFs from 'mock-fs'; -import { createFormatterConfiguration, Formatter, FormatterOptions } from '../../../lib/formatter'; -import { Issue } from '../../../lib/issue'; +import { Issue } from 'lib/issue'; +import { createFormatterConfiguration, Formatter, FormatterOptions } from 'lib/formatter'; describe('formatter/FormatterConfiguration', () => { beforeEach(() => { diff --git a/test/unit/formatter/FormatterFactory.spec.ts b/test/unit/formatter/FormatterFactory.spec.ts index d5e9136e..33b0811c 100644 --- a/test/unit/formatter/FormatterFactory.spec.ts +++ b/test/unit/formatter/FormatterFactory.spec.ts @@ -1,7 +1,7 @@ import * as os from 'os'; import mockFs from 'mock-fs'; -import { createFormatter, FormatterType } from '../../../lib/formatter'; -import { Issue } from '../../../lib/issue'; +import { Issue } from 'lib/issue'; +import { createFormatter, FormatterType } from 'lib/formatter'; describe('formatter/FormatterFactory', () => { beforeEach(() => { diff --git a/test/unit/formatter/WebpackFormatter.spec.ts b/test/unit/formatter/WebpackFormatter.spec.ts index 24c5370a..cba6998a 100644 --- a/test/unit/formatter/WebpackFormatter.spec.ts +++ b/test/unit/formatter/WebpackFormatter.spec.ts @@ -1,6 +1,7 @@ import os from 'os'; -import { Issue } from '../../../lib/issue'; -import { createBasicFormatter, createWebpackFormatter, Formatter } from '../../../lib/formatter'; +import { join } from 'path'; +import { Issue } from 'lib/issue'; +import { createBasicFormatter, createWebpackFormatter, Formatter } from 'lib/formatter'; describe('formatter/WebpackFormatter', () => { const issue: Issue = { @@ -8,7 +9,7 @@ describe('formatter/WebpackFormatter', () => { severity: 'error', code: 'TS123', message: 'Some issue content', - file: 'some/file.ts', + file: join(__dirname, 'some/file.ts'), location: { start: { line: 1, @@ -24,7 +25,7 @@ describe('formatter/WebpackFormatter', () => { let formatter: Formatter; beforeEach(() => { - formatter = createWebpackFormatter(createBasicFormatter()); + formatter = createWebpackFormatter(createBasicFormatter(), __dirname); }); it('decorates existing formatter', () => { diff --git a/test/unit/issue/Issue.spec.ts b/test/unit/issue/Issue.spec.ts index ee17bdf6..0d760921 100644 --- a/test/unit/issue/Issue.spec.ts +++ b/test/unit/issue/Issue.spec.ts @@ -1,4 +1,4 @@ -import { isIssue, deduplicateAndSortIssues, Issue } from '../../../lib/issue'; +import { isIssue, deduplicateAndSortIssues, Issue } from 'lib/issue'; function omit(object: TObject, keys: (keyof TObject)[]) { const omittedObject = Object.assign({}, object); diff --git a/test/unit/typescript-reporter/TypeScriptReporterConfiguration.spec.ts b/test/unit/typescript-reporter/TypeScriptReporterConfiguration.spec.ts new file mode 100644 index 00000000..0d595d76 --- /dev/null +++ b/test/unit/typescript-reporter/TypeScriptReporterConfiguration.spec.ts @@ -0,0 +1,131 @@ +import webpack from 'webpack'; +import { TypeScriptReporterConfiguration } from 'lib/typescript-reporter/TypeScriptReporterConfiguration'; +import { TypeScriptReporterOptions } from 'lib/typescript-reporter/TypeScriptReporterOptions'; + +describe('typescript-reporter/TypeScriptsReporterConfiguration', () => { + let compiler: webpack.Compiler; + let createTypeScriptVueExtensionConfiguration: jest.Mock; + let createTypeScriptPnpExtensionConfiguration: jest.Mock; + + const configuration: TypeScriptReporterConfiguration = { + enabled: true, + memoryLimit: 2048, + tsconfig: '/webpack/context/tsconfig.json', + build: false, + compilerOptions: {}, + diagnosticOptions: { + semantic: true, + syntactic: false, + declaration: false, + global: false, + }, + extensions: { + vue: { + enabled: false, + compiler: 'vue-template-compiler', + }, + pnp: { + enabled: false, + }, + }, + }; + + beforeEach(() => { + compiler = { + options: { + context: '/webpack/context', + }, + } as webpack.Compiler; + createTypeScriptVueExtensionConfiguration = jest.fn(() => ({ + enabled: false, + compiler: 'vue-template-compiler', + })); + createTypeScriptPnpExtensionConfiguration = jest.fn(() => ({ + enabled: false, + })); + jest.setMock('lib/typescript-reporter/extension/vue/TypeScriptVueExtensionConfiguration', { + createTypeScriptVueExtensionConfiguration, + }); + jest.setMock('lib/typescript-reporter/extension/pnp/TypeScriptPnpExtensionConfiguration', { + createTypeScriptPnpExtensionConfiguration, + }); + }); + afterEach(() => { + jest.resetModules(); + }); + + it.each([ + [undefined, configuration], + [{}, configuration], + [true, configuration], + [false, { ...configuration, enabled: false }], + [{ enabled: false }, { ...configuration, enabled: false }], + [{ memoryLimit: 512 }, { ...configuration, memoryLimit: 512 }], + [ + { tsconfig: 'tsconfig.another.json' }, + { ...configuration, tsconfig: '/webpack/context/tsconfig.another.json' }, + ], + [{ build: true }, { ...configuration, build: true }], + [ + { compilerOptions: { strict: true } }, + { ...configuration, compilerOptions: { strict: true } }, + ], + [{ diagnosticOptions: {} }, configuration], + [ + { diagnosticOptions: { syntactic: true, semantic: false } }, + { + ...configuration, + diagnosticOptions: { semantic: false, syntactic: true, declaration: false, global: false }, + }, + ], + ])('creates configuration from options %p', async (options, expectedConfiguration) => { + const { createTypeScriptReporterConfiguration } = await import( + 'lib/typescript-reporter/TypeScriptReporterConfiguration' + ); + const configuration = createTypeScriptReporterConfiguration( + compiler, + options as TypeScriptReporterOptions + ); + + expect(configuration).toEqual(expectedConfiguration); + }); + + it('passes vue options to the vue extension', async () => { + createTypeScriptVueExtensionConfiguration.mockImplementation( + () => 'returned from vue extension' + ); + const { createTypeScriptReporterConfiguration } = await import( + 'lib/typescript-reporter/TypeScriptReporterConfiguration' + ); + + const vueOptions = { + enabled: true, + compiler: 'test-compiler', + }; + + const configuration = createTypeScriptReporterConfiguration(compiler, { + extensions: { vue: vueOptions }, + }); + + expect(createTypeScriptVueExtensionConfiguration).toHaveBeenCalledWith(vueOptions); + expect(configuration.extensions.vue).toEqual('returned from vue extension'); + }); + + it('passes pnp options to the pnp extension', async () => { + createTypeScriptPnpExtensionConfiguration.mockImplementation( + () => 'returned from pnp extension' + ); + const { createTypeScriptReporterConfiguration } = await import( + 'lib/typescript-reporter/TypeScriptReporterConfiguration' + ); + + const pnpOptions = true; + + const configuration = createTypeScriptReporterConfiguration(compiler, { + extensions: { pnp: pnpOptions }, + }); + + expect(createTypeScriptPnpExtensionConfiguration).toHaveBeenCalledWith(pnpOptions); + expect(configuration.extensions.pnp).toEqual('returned from pnp extension'); + }); +}); diff --git a/test/unit/typescript-reporter/TypeScriptSupport.spec.ts b/test/unit/typescript-reporter/TypeScriptSupport.spec.ts index 440c7115..9b1698a8 100644 --- a/test/unit/typescript-reporter/TypeScriptSupport.spec.ts +++ b/test/unit/typescript-reporter/TypeScriptSupport.spec.ts @@ -1,4 +1,4 @@ -import { TypeScriptReporterConfiguration } from '../../../lib/typescript-reporter/TypeScriptReporterConfiguration'; +import { TypeScriptReporterConfiguration } from 'lib/typescript-reporter/TypeScriptReporterConfiguration'; import os from 'os'; describe('typescript-reporter/TypeScriptSupport', () => { @@ -31,24 +31,20 @@ describe('typescript-reporter/TypeScriptSupport', () => { }; }); - it('throws error if typescript is not installed', () => { + it('throws error if typescript is not installed', async () => { jest.setMock('typescript', undefined); - const { - assertTypeScriptSupport, - } = require('../../../lib/typescript-reporter/TypeScriptSupport'); + const { assertTypeScriptSupport } = await import('lib/typescript-reporter/TypeScriptSupport'); expect(() => assertTypeScriptSupport(configuration)).toThrowError( 'When you use ForkTsCheckerWebpackPlugin with typescript reporter enabled, you must install `typescript` package.' ); }); - it('throws error if typescript version is lower then 2.7.0', () => { + it('throws error if typescript version is lower then 2.7.0', async () => { jest.setMock('typescript', { version: '2.6.9' }); - const { - assertTypeScriptSupport, - } = require('../../../lib/typescript-reporter/TypeScriptSupport'); + const { assertTypeScriptSupport } = await import('lib/typescript-reporter/TypeScriptSupport'); expect(() => assertTypeScriptSupport(configuration)).toThrowError( [ @@ -58,23 +54,19 @@ describe('typescript-reporter/TypeScriptSupport', () => { ); }); - it("doesn't throw error if typescript version is greater or equal 2.7.0", () => { + it("doesn't throw error if typescript version is greater or equal 2.7.0", async () => { jest.setMock('typescript', { version: '2.7.0' }); - jest.setMock('graceful-fs', { existsSync: () => true }); + jest.setMock('fs-extra', { existsSync: () => true }); - const { - assertTypeScriptSupport, - } = require('../../../lib/typescript-reporter/TypeScriptSupport'); + const { assertTypeScriptSupport } = await import('lib/typescript-reporter/TypeScriptSupport'); expect(() => assertTypeScriptSupport(configuration)).not.toThrowError(); }); - it('throws error if typescript version is lower then 3.6.0 and configuration has enabled build option', () => { + it('throws error if typescript version is lower then 3.6.0 and configuration has enabled build option', async () => { jest.setMock('typescript', { version: '3.5.9' }); - const { - assertTypeScriptSupport, - } = require('../../../lib/typescript-reporter/TypeScriptSupport'); + const { assertTypeScriptSupport } = await import('lib/typescript-reporter/TypeScriptSupport'); expect(() => assertTypeScriptSupport({ ...configuration, build: true })).toThrowError( [ @@ -85,23 +77,20 @@ describe('typescript-reporter/TypeScriptSupport', () => { ); }); - it("doesn't throw error if typescript version is greater or equal 3.6.0 and configuration has enabled build option", () => { + it("doesn't throw error if typescript version is greater or equal 3.6.0 and configuration has enabled build option", async () => { jest.setMock('typescript', { version: '3.6.0' }); - jest.setMock('graceful-fs', { existsSync: () => true }); + jest.setMock('fs-extra', { existsSync: () => true }); - const { - assertTypeScriptSupport, - } = require('../../../lib/typescript-reporter/TypeScriptSupport'); + const { assertTypeScriptSupport } = await import('lib/typescript-reporter/TypeScriptSupport'); expect(() => assertTypeScriptSupport(configuration)).not.toThrowError(); }); - it('throws error if there is no tsconfig.json file', () => { + it('throws error if there is no tsconfig.json file', async () => { jest.setMock('typescript', { version: '3.8.0' }); - jest.setMock('graceful-fs', { existsSync: () => false }); - const { - assertTypeScriptSupport, - } = require('../../../lib/typescript-reporter/TypeScriptSupport'); + jest.setMock('fs-extra', { existsSync: () => false }); + + const { assertTypeScriptSupport } = await import('lib/typescript-reporter/TypeScriptSupport'); expect(() => assertTypeScriptSupport(configuration)).toThrowError( [ @@ -114,36 +103,32 @@ describe('typescript-reporter/TypeScriptSupport', () => { ); }); - it('checks for pnp support if pnp extension is enabled', () => { + it('checks for pnp support if pnp extension is enabled', async () => { jest.setMock('typescript', { version: '3.8.0' }); - jest.setMock('graceful-fs', { existsSync: () => true }); - jest.setMock('../../../lib/typescript-reporter/extension/pnp/TypeScriptPnpExtensionSupport', { + jest.setMock('fs-extra', { existsSync: () => true }); + jest.setMock('lib/typescript-reporter/extension/pnp/TypeScriptPnpExtensionSupport', { assertTypeScriptPnpExtensionSupport: () => { throw new Error('Error from PnP Extension.'); }, }); - const { - assertTypeScriptSupport, - } = require('../../../lib/typescript-reporter/TypeScriptSupport'); + const { assertTypeScriptSupport } = await import('lib/typescript-reporter/TypeScriptSupport'); configuration.extensions.pnp.enabled = true; expect(() => assertTypeScriptSupport(configuration)).toThrowError('Error from PnP Extension.'); }); - it('checks for pnp support if vue extension is enabled', () => { + it('checks for pnp support if vue extension is enabled', async () => { jest.setMock('typescript', { version: '3.8.0' }); - jest.setMock('graceful-fs', { existsSync: () => true }); - jest.setMock('../../../lib/typescript-reporter/extension/vue/TypeScriptVueExtensionSupport', { + jest.setMock('fs-extra', { existsSync: () => true }); + jest.setMock('lib/typescript-reporter/extension/vue/TypeScriptVueExtensionSupport', { assertTypeScriptVueExtensionSupport: () => { throw new Error('Error from Vue Extension.'); }, }); - const { - assertTypeScriptSupport, - } = require('../../../lib/typescript-reporter/TypeScriptSupport'); + const { assertTypeScriptSupport } = await import('lib/typescript-reporter/TypeScriptSupport'); configuration.extensions.vue.enabled = true; diff --git a/test/unit/typescript-reporter/issue/TypeScriptIssueFactory.spec.ts b/test/unit/typescript-reporter/issue/TypeScriptIssueFactory.spec.ts index f2e489f9..8831a4e0 100644 --- a/test/unit/typescript-reporter/issue/TypeScriptIssueFactory.spec.ts +++ b/test/unit/typescript-reporter/issue/TypeScriptIssueFactory.spec.ts @@ -1,5 +1,5 @@ import * as ts from 'typescript'; -import { createIssuesFromTsDiagnostics } from '../../../../lib/typescript-reporter/issue/TypeScriptIssueFactory'; +import { createIssuesFromTsDiagnostics } from 'lib/typescript-reporter/issue/TypeScriptIssueFactory'; describe('typescript-reporter/issue/TypeScriptIssueFactory', () => { const TS_DIAGNOSTIC_WARNING = { diff --git a/tsconfig.json b/tsconfig.json index cd6ab032..87fa7ff9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,9 +10,9 @@ "skipDefaultLibCheck": true, "strict": true, "declaration": true, - "sourceMap": true, "baseUrl": "./src", "outDir": "./lib" }, - "include": ["./src"] + "include": ["./src"], + "exclude": ["node_modules", "test", "lib"] } diff --git a/yarn.lock b/yarn.lock index 16a0890e..b1155a9b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -906,6 +906,13 @@ version "1.2.0" resolved "https://registry.yarnpkg.com/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86" +"@types/fs-extra@^8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-8.1.0.tgz#1114834b53c3914806cd03b3304b37b3bd221a4d" + integrity sha512-UoOfVEzAUpeSPmjm7h1uk5MH6KZma2z2O7a75onTGjnNvAvMVrPzPL/vBbT65iIGHWj6rokwfmYcmxmlSf2uwg== + dependencies: + "@types/node" "*" + "@types/glob@*": version "7.1.1" resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575" @@ -915,13 +922,6 @@ "@types/minimatch" "*" "@types/node" "*" -"@types/graceful-fs@^4.1.3": - version "4.1.3" - resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.3.tgz#039af35fe26bec35003e8d86d2ee9c586354348f" - integrity sha512-AiHRaEB50LQg0pZmm659vNBb9f4SJ0qrAnteuzhSeAUcJKxoYgEnprg/83kppCnc2zvtCKbdZry1a5pVY3lOTQ== - dependencies: - "@types/node" "*" - "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": version "2.0.1" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff" @@ -955,11 +955,6 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.3.tgz#bdfd69d61e464dcc81b25159c270d75a73c1a636" integrity sha512-Il2DtDVRGDcqjDtE+rF8iqg1CArehSK84HZJCT7AMITlyXRBpuPhqGLDQMowraqqu1coEaimg4ZOqggt6L6L+A== -"@types/lodash@^4.14.149": - version "4.14.149" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.149.tgz#1342d63d948c6062838fbf961012f74d4e638440" - integrity sha512-ijGqzZt/b7BfzcK9vTrS6MFljQRPn5BFWOx8oE0GYxribu6uV+aA9zZuXI1zc/etK9E8nrgdoF2+LgUw7+9tJQ== - "@types/minimatch@*", "@types/minimatch@^3.0.1": version "3.0.3" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" @@ -971,13 +966,6 @@ dependencies: "@types/node" "*" -"@types/mock-require@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@types/mock-require/-/mock-require-2.0.0.tgz#57a4f0db0b4b6274f610a2d2c20beb3c842181e1" - integrity sha512-nOgjoE5bBiDeiA+z41i95makyHUSMWQMOPocP+J67Pqx/68HAXaeWN1NFtrAYYV6LrISIZZ8vKHm/a50k0f6Sg== - dependencies: - "@types/node" "*" - "@types/node@*": version "10.12.18" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67" @@ -1386,16 +1374,6 @@ ajv@^6.10.2: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^6.12.0: - version "6.12.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.0.tgz#06d60b96d87b8454a5adaba86e7854da629db4b7" - integrity sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - ansi-escapes@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" @@ -1571,6 +1549,11 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= +at-least-node@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" + integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== + atob@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" @@ -2314,11 +2297,6 @@ copy-descriptor@^0.1.0: resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= -copy-dir@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/copy-dir/-/copy-dir-1.2.0.tgz#d2634378186d8762769285b36efb307a7945964e" - integrity sha512-UeaUFUIHqGV4brjQ9bY2mHll/hoxyCak2emgmYG72LkGKABHBdBDKFw0H5nTKt5OzVBkBhkxCwnniJBAE7EGEw== - core-js@^2.4.0, core-js@^2.5.0: version "2.6.5" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.5.tgz#44bc8d249e7fb2ff5d00e0341a7ffb94fbf67895" @@ -2417,25 +2395,6 @@ crypto-browserify@^3.11.0: randombytes "^2.0.0" randomfill "^1.0.3" -css-loader@3.5.2: - version "3.5.2" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.5.2.tgz#6483ae56f48a7f901fbe07dde2fc96b01eafab3c" - integrity sha512-hDL0DPopg6zQQSRlZm0hyeaqIRnL0wbWjay9BZxoiJBpbfOW4WHfbaYQhwnDmEa0kZUc1CJ3IFo15ot1yULMIQ== - dependencies: - camelcase "^5.3.1" - cssesc "^3.0.0" - icss-utils "^4.1.1" - loader-utils "^1.2.3" - normalize-path "^3.0.0" - postcss "^7.0.27" - postcss-modules-extract-imports "^2.0.0" - postcss-modules-local-by-default "^3.0.2" - postcss-modules-scope "^2.2.0" - postcss-modules-values "^3.0.0" - postcss-value-parser "^4.0.3" - schema-utils "^2.6.5" - semver "^6.3.0" - cssesc@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" @@ -3018,11 +2977,6 @@ fast-deep-equal@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" -fast-deep-equal@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" - integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== - fast-diff@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" @@ -3187,6 +3141,16 @@ from2@^2.1.0: inherits "^2.0.1" readable-stream "^2.0.0" +fs-extra@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.0.0.tgz#b6afc31036e247b2466dc99c29ae797d5d4580a3" + integrity sha512-pmEYSk3vYsG/bF651KPUXZ+hvjpgWYw/Gc7W9NFUe3ZVLczKKWIij3IKpOrQcdw4TILtibFslZ0UmR8Vvzig4g== + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^1.0.0" + fs-minipass@^1.2.5: version "1.2.7" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" @@ -3194,6 +3158,11 @@ fs-minipass@^1.2.5: dependencies: minipass "^2.6.0" +fs-monkey@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.0.tgz#b1fe36b2d8a78463fd0b8fd1463b355952743bd0" + integrity sha512-nxkkzQ5Ga+ETriXxIof4TncyMSzrV9jFIF+kGN16nw5CiAdWAnG/2FgM7CHhRenW1EBiDx+r1tf/P78HGKCgnA== + fs-write-stream-atomic@^1.0.8: version "1.0.10" resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" @@ -3244,10 +3213,6 @@ gensync@^1.0.0-beta.1: resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg== -get-caller-file@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" - get-caller-file@^2.0.1: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" @@ -3364,7 +3329,7 @@ globals@^12.1.0: dependencies: type-fest "^0.8.1" -graceful-fs@^4.1.11, graceful-fs@^4.2.3: +graceful-fs@^4.1.11, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== @@ -3600,13 +3565,6 @@ iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4: dependencies: safer-buffer ">= 2.1.2 < 3" -icss-utils@^4.0.0, icss-utils@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467" - integrity sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA== - dependencies: - postcss "^7.0.14" - ieee754@^1.1.4: version "1.1.13" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" @@ -4510,6 +4468,15 @@ json5@^2.1.2: dependencies: minimist "^1.2.5" +jsonfile@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.0.1.tgz#98966cba214378c8c84b82e085907b40bf614179" + integrity sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg== + dependencies: + universalify "^1.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + jsonparse@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" @@ -4865,6 +4832,13 @@ mdurl@^1.0.1: resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4= +memfs@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.1.2.tgz#2bb51600dacec67ed35677b1185abb708b7d2ad6" + integrity sha512-YubKuE+RGSdpZcRq2Nih8HcHj3LrqndsDFNB9IFjrgwzdM4eq+fImlDMfNm/HdRhYRkLdUecHGIpdz+wyrqlDg== + dependencies: + fs-monkey "1.0.0" + memory-fs@^0.4.0, memory-fs@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" @@ -5055,14 +5029,6 @@ mock-fs@^4.11.0: resolved "https://registry.yarnpkg.com/mock-fs/-/mock-fs-4.11.0.tgz#0828107e4b843a6ba855ecebfe3c6e073b69db92" integrity sha512-Yp4o3/ZA15wsXqJTT+R+9w2AYIkD1i80Lds47wDbuUhOvQvm+O2EfjFZSz0pMgZZSPHRhGxgcd2+GL4+jZMtdw== -mock-require@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/mock-require/-/mock-require-3.0.3.tgz#ccd544d9eae81dd576b3f219f69ec867318a1946" - integrity sha512-lLzfLHcyc10MKQnNUCv7dMcoY/2Qxd6wJfbqCcVk3LDb8An4hF6ohk5AztrvgKhJCqj36uyzi/p5se+tvyD+Wg== - dependencies: - get-caller-file "^1.0.2" - normalize-path "^2.1.1" - move-concurrently@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" @@ -5651,40 +5617,7 @@ posix-character-classes@^0.1.0: resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= -postcss-modules-extract-imports@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz#818719a1ae1da325f9832446b01136eeb493cd7e" - integrity sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ== - dependencies: - postcss "^7.0.5" - -postcss-modules-local-by-default@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.2.tgz#e8a6561be914aaf3c052876377524ca90dbb7915" - integrity sha512-jM/V8eqM4oJ/22j0gx4jrp63GSvDH6v86OqyTHHUvk4/k1vceipZsaymiZ5PvocqZOl5SFHiFJqjs3la0wnfIQ== - dependencies: - icss-utils "^4.1.1" - postcss "^7.0.16" - postcss-selector-parser "^6.0.2" - postcss-value-parser "^4.0.0" - -postcss-modules-scope@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz#385cae013cc7743f5a7d7602d1073a89eaae62ee" - integrity sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ== - dependencies: - postcss "^7.0.6" - postcss-selector-parser "^6.0.0" - -postcss-modules-values@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz#5b5000d6ebae29b4255301b4a3a54574423e7f10" - integrity sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg== - dependencies: - icss-utils "^4.0.0" - postcss "^7.0.6" - -postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2: +postcss-selector-parser@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz#934cf799d016c83411859e09dcecade01286ec5c" integrity sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg== @@ -5693,12 +5626,7 @@ postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2: indexes-of "^1.0.1" uniq "^1.0.1" -postcss-value-parser@^4.0.0, postcss-value-parser@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.3.tgz#651ff4593aa9eda8d5d0d66593a2417aeaeb325d" - integrity sha512-N7h4pG+Nnu5BEIzyeaaIYWs0LI5XC40OrRh5L60z0QjFsqGWcHcbkBvpe1WYpcIS9yQ8sOi/vIPt1ejQCrMVrg== - -postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.27, postcss@^7.0.5, postcss@^7.0.6: +postcss@^7.0.14: version "7.0.27" resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.27.tgz#cc67cdc6b0daa375105b7c424a85567345fc54d9" integrity sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ== @@ -6313,14 +6241,6 @@ schema-utils@1.0.0, schema-utils@^1.0.0: ajv-errors "^1.0.0" ajv-keywords "^3.1.0" -schema-utils@^2.6.5: - version "2.6.5" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.6.5.tgz#c758f0a7e624263073d396e29cd40aa101152d8a" - integrity sha512-5KXuwKziQrTVHh8j/Uxz+QUbxkaLW9X/86NBlx/gnKgtsZA2GIVMUn17qWhRFwF8jdYb3Dig5hRO/W5mZqy6SQ== - dependencies: - ajv "^6.12.0" - ajv-keywords "^3.4.1" - semver-compare@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" @@ -7263,12 +7183,10 @@ unist-util-visit@^1.0.0, unist-util-visit@^1.1.0: dependencies: unist-util-visit-parents "^2.0.0" -unixify@^1.0.0: +universalify@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/unixify/-/unixify-1.0.0.tgz#3a641c8c2ffbce4da683a5c70f03a462940c2090" - integrity sha1-OmQcjC/7zk2mg6XHDwOkYpQMIJA= - dependencies: - normalize-path "^2.1.1" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-1.0.0.tgz#b61a1da173e8435b2fe3c67d29b9adf8594bd16d" + integrity sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug== unset-value@^1.0.0: version "1.0.0" From 6004b9bb799297273356c38f1d9ae6f5428a1cf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ole=C5=9B?= Date: Fri, 15 May 2020 23:54:11 +0200 Subject: [PATCH 14/29] feat: drop support for Node 8 and add Node 14 to the matrix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Node 8 is no longer maintained and we want to limit the number of supported environments as it adds maintanance cost. BREAKING CHANGE: ๐Ÿงจ Dropped support for the Node 8 --- .github/workflows/main.yml | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b30bed65..a0fea3bc 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -39,7 +39,7 @@ jobs: needs: build strategy: matrix: - node: [8, 10, 12] + node: [10, 12, 14] os: [ubuntu-latest, macos-latest, windows-latest] steps: - uses: actions/checkout@v1 @@ -61,7 +61,7 @@ jobs: ${{ runner.os }}-node-${{ matrix.node }}-yarn- - name: Install dependencies - run: yarn install --frozen-lockfile --ignore-engines + run: yarn install --frozen-lockfile - name: Download build artifact uses: actions/download-artifact@v1 diff --git a/package.json b/package.json index 97a0a8b9..b9700485 100644 --- a/package.json +++ b/package.json @@ -108,7 +108,7 @@ "webpack": "^4.42.1" }, "engines": { - "node": ">=8", + "node": ">=10", "yarn": ">=1.0.0" } } From bd4dddb25d76dc78a9a072fc15148e7bca2ac9d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ole=C5=9B?= Date: Sat, 16 May 2020 00:10:48 +0200 Subject: [PATCH 15/29] test: update tests for compatibility with windows --- package.json | 3 + src/ForkTsCheckerWebpackPluginState.ts | 4 +- src/hooks/getReportProgress.ts | 8 -- src/hooks/pluginHooks.ts | 4 +- src/hooks/tapAfterCompileToGetIssues.ts | 75 +++++++------------ src/hooks/tapDoneToAsyncGetIssues.ts | 14 ++-- src/hooks/tapStartToConnectAndRunReporter.ts | 22 +++++- src/hooks/tapStopToDisconnectReporter.ts | 2 +- test/e2e/EsLint.spec.ts | 18 +++-- test/e2e/PluginOutOfMemory.spec.ts | 20 +++-- test/e2e/TypeScriptSolutionBuilderApi.spec.ts | 18 +++-- test/e2e/TypeScriptWatchApi.spec.ts | 36 +++++---- test/e2e/fixtures/eslint-basic.fixture | 12 +-- test/e2e/fixtures/typescript-basic.fixture | 12 +-- .../typescript-project-references.fixture | 12 +-- test/e2e/sandbox/Sandbox.ts | 35 ++++++--- test/unit/formatter/WebpackFormatter.spec.ts | 6 +- .../TypeScriptReporterConfiguration.spec.ts | 5 +- yarn.lock | 16 +++- 19 files changed, 181 insertions(+), 141 deletions(-) delete mode 100644 src/hooks/getReportProgress.ts diff --git a/package.json b/package.json index b9700485..31c248b1 100644 --- a/package.json +++ b/package.json @@ -72,6 +72,7 @@ "@commitlint/config-conventional": "^8.3.4", "@mdx-js/mdx": "^1.5.8", "@types/babel__code-frame": "^7.0.1", + "@types/cross-spawn": "^6.0.2", "@types/eslint": "^6.8.0", "@types/fs-extra": "^8.1.0", "@types/jest": "^25.2.1", @@ -85,6 +86,7 @@ "@typescript-eslint/eslint-plugin": "^2.27.0", "@typescript-eslint/parser": "^2.27.0", "commitlint": "^8.3.5", + "cross-spawn": "^7.0.2", "eslint": "^6.8.0", "eslint-config-prettier": "^6.10.1", "eslint-plugin-node": "^11.1.0", @@ -101,6 +103,7 @@ "ts-jest": "^25.3.1", "ts-loader": "^6.2.2", "typescript": "^3.8.3", + "unixify": "^1.0.0", "vue": "^2.6.11", "vue-class-component": "^7.2.3", "vue-loader": "^15.9.1", diff --git a/src/ForkTsCheckerWebpackPluginState.ts b/src/ForkTsCheckerWebpackPluginState.ts index c100799b..7e194630 100644 --- a/src/ForkTsCheckerWebpackPluginState.ts +++ b/src/ForkTsCheckerWebpackPluginState.ts @@ -1,7 +1,7 @@ -import { Issue } from './issue'; +import { Report } from './reporter'; interface ForkTsCheckerWebpackPluginState { - report: Promise; + report: Promise; changedFiles: string[]; removedFiles: string[]; isWatching: boolean; diff --git a/src/hooks/getReportProgress.ts b/src/hooks/getReportProgress.ts deleted file mode 100644 index 50b91f04..00000000 --- a/src/hooks/getReportProgress.ts +++ /dev/null @@ -1,8 +0,0 @@ -type ReportProgress = (progress: number, message: string) => void; - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function getReportProgress(context: any): ReportProgress | undefined { - return context && context.reportProgress; -} - -export { getReportProgress }; diff --git a/src/hooks/pluginHooks.ts b/src/hooks/pluginHooks.ts index 5f94db01..0d4c2514 100644 --- a/src/hooks/pluginHooks.ts +++ b/src/hooks/pluginHooks.ts @@ -13,8 +13,8 @@ function createForkTsCheckerWebpackPluginHooks() { run: new SyncHook(['compiler']), runWatch: new SyncWaterfallHook(['change', 'compiler']), waiting: new SyncHook(['compilation']), - cancelled: new SyncHook(['compilation']), - error: new SyncHook(['error', 'compilation']), + cancelled: new SyncHook(['compiler']), + error: new SyncHook(['error', 'compiler']), issues: new SyncWaterfallHook([ 'issues', 'compilation', diff --git a/src/hooks/tapAfterCompileToGetIssues.ts b/src/hooks/tapAfterCompileToGetIssues.ts index d4ad3cc8..f1e3c45b 100644 --- a/src/hooks/tapAfterCompileToGetIssues.ts +++ b/src/hooks/tapAfterCompileToGetIssues.ts @@ -2,10 +2,7 @@ import webpack from 'webpack'; import { ForkTsCheckerWebpackPluginConfiguration } from '../ForkTsCheckerWebpackPluginConfiguration'; import { ForkTsCheckerWebpackPluginState } from '../ForkTsCheckerWebpackPluginState'; import { getForkTsCheckerWebpackPluginHooks } from './pluginHooks'; -import { OperationCancelledError } from '../error/OperationCancelledError'; import { IssueWebpackError } from '../issue/IssueWebpackError'; -import { Tap } from 'tapable'; -import { getReportProgress } from './getReportProgress'; import { Issue } from '../issue'; function tapAfterCompileToGetIssues( @@ -15,55 +12,41 @@ function tapAfterCompileToGetIssues( ) { const hooks = getForkTsCheckerWebpackPluginHooks(compiler); - compiler.hooks.afterCompile.tapPromise( - { - name: 'ForkTsCheckerWebpackPlugin', - context: true, - } as Tap, - async (context, compilation) => { - const reportProgress = getReportProgress(context); - let issues: Issue[] = []; + compiler.hooks.afterCompile.tapPromise('ForkTsCheckerWebpackPlugin', async (compilation) => { + let issues: Issue[] | undefined = []; - try { - if (reportProgress) { - reportProgress(0.95, 'Issues checking in progress'); - } + try { + issues = await state.report; + } catch (error) { + hooks.error.call(error, compilation.compiler); + return; + } - issues = await state.report; - } catch (error) { - if (error instanceof OperationCancelledError) { - hooks.cancelled.call(compilation); - } else { - hooks.error.call(error, compilation); - } - return; - } finally { - if (reportProgress) { - reportProgress(0.95, 'Issues checked'); - } - } + if (!issues) { + // some error has been thrown or it was cancelled + return; + } - // filter list of issues by provided issue predicate - issues = issues.filter(configuration.issue.predicate); + // filter list of issues by provided issue predicate + issues = issues.filter(configuration.issue.predicate); - // modify list of issues in the plugin hooks - issues = hooks.issues.call(issues, compilation); + // modify list of issues in the plugin hooks + issues = hooks.issues.call(issues, compilation); - issues.forEach((issue) => { - const error = new IssueWebpackError( - configuration.formatter(issue), - compiler.options.context || process.cwd(), - issue - ); + issues.forEach((issue) => { + const error = new IssueWebpackError( + configuration.formatter(issue), + compiler.options.context || process.cwd(), + issue + ); - if (issue.severity === 'warning') { - compilation.warnings.push(error); - } else { - compilation.errors.push(error); - } - }); - } - ); + if (issue.severity === 'warning') { + compilation.warnings.push(error); + } else { + compilation.errors.push(error); + } + }); + }); } export { tapAfterCompileToGetIssues }; diff --git a/src/hooks/tapDoneToAsyncGetIssues.ts b/src/hooks/tapDoneToAsyncGetIssues.ts index 11122940..9c96ec2d 100644 --- a/src/hooks/tapDoneToAsyncGetIssues.ts +++ b/src/hooks/tapDoneToAsyncGetIssues.ts @@ -2,7 +2,6 @@ import webpack from 'webpack'; import { ForkTsCheckerWebpackPluginConfiguration } from '../ForkTsCheckerWebpackPluginConfiguration'; import { ForkTsCheckerWebpackPluginState } from '../ForkTsCheckerWebpackPluginState'; import { getForkTsCheckerWebpackPluginHooks } from './pluginHooks'; -import { OperationCancelledError } from '../error/OperationCancelledError'; import { createWebpackFormatter } from '../formatter/WebpackFormatter'; import { Issue } from '../issue'; import isPending from '../utils/async/isPending'; @@ -18,7 +17,7 @@ function tapDoneToAsyncGetIssues( compiler.hooks.done.tap('ForkTsCheckerWebpackPlugin', async (stats) => { const report = state.report; - let issues: Issue[]; + let issues: Issue[] | undefined; try { if (await isPending(report)) { @@ -31,11 +30,12 @@ function tapDoneToAsyncGetIssues( issues = await report; } catch (error) { - if (error instanceof OperationCancelledError) { - hooks.cancelled.call(stats.compilation); - } else { - hooks.error.call(error, stats.compilation); - } + hooks.error.call(error, stats.compilation.compiler); + return; + } + + if (!issues) { + // some error has been thrown or it was cancelled return; } diff --git a/src/hooks/tapStartToConnectAndRunReporter.ts b/src/hooks/tapStartToConnectAndRunReporter.ts index 3bc8e25f..59f4f382 100644 --- a/src/hooks/tapStartToConnectAndRunReporter.ts +++ b/src/hooks/tapStartToConnectAndRunReporter.ts @@ -5,6 +5,7 @@ import { getForkTsCheckerWebpackPluginHooks } from './pluginHooks'; import { getDeletedFiles } from './getDeletedFiles'; import { FilesChange, ReporterRpcClient } from '../reporter'; import { getChangedFiles } from './getChangedFiles'; +import { OperationCancelledError } from '../error/OperationCancelledError'; function tapStartToConnectAndRunReporter( compiler: webpack.Compiler, @@ -21,7 +22,13 @@ function tapStartToConnectAndRunReporter( hooks.run.call(compiler); - state.report = reporter.connect().then(() => reporter.getReport({})); + state.report = reporter + .connect() + .then(() => reporter.getReport({})) + .catch((error) => { + hooks.error.call(error, compiler); + return undefined; + }); }); compiler.hooks.watchRun.tap('ForkTsCheckerWebpackPlugin', async (compiler) => { @@ -42,7 +49,18 @@ function tapStartToConnectAndRunReporter( ].join('\n') ); - state.report = reporter.connect().then(() => reporter.getReport(change)); + state.report = reporter + .connect() + .then(() => reporter.getReport(change)) + .catch((error) => { + if (error instanceof OperationCancelledError) { + hooks.cancelled.call(compiler); + } else { + hooks.error.call(error, compiler); + } + + return undefined; + }); }); } diff --git a/src/hooks/tapStopToDisconnectReporter.ts b/src/hooks/tapStopToDisconnectReporter.ts index 5494c9cc..47a0eb03 100644 --- a/src/hooks/tapStopToDisconnectReporter.ts +++ b/src/hooks/tapStopToDisconnectReporter.ts @@ -36,7 +36,7 @@ function tapStopToDisconnectReporter( 'or lowering the `memoryLimit` value in the ForkTsCheckerWebpackPlugin configuration.' ) ); - } else if (error.signal === 'SIGABRT') { + } else { configuration.logger.issues.error( chalk.red( 'Issues checking service aborted - probably out of memory. ' + diff --git a/test/e2e/EsLint.spec.ts b/test/e2e/EsLint.spec.ts index ccd136ad..f1ae39b0 100644 --- a/test/e2e/EsLint.spec.ts +++ b/test/e2e/EsLint.spec.ts @@ -30,18 +30,20 @@ describe('EsLint', () => { ])('reports lint error for %p', async ({ async, webpack }) => { await sandbox.load( await readFixture(join(__dirname, 'fixtures/eslint-basic.fixture'), { - FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION, - TS_LOADER_VERSION: '^5.0.0', - TYPESCRIPT_VERSION: '~3.8.0', - WEBPACK_VERSION: webpack, - WEBPACK_CLI_VERSION, - WEBPACK_DEV_SERVER_VERSION, - ASYNC: async ? 'true' : 'false', + FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION: JSON.stringify( + FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION + ), + TS_LOADER_VERSION: JSON.stringify('^5.0.0'), + TYPESCRIPT_VERSION: JSON.stringify('~3.8.0'), + WEBPACK_VERSION: JSON.stringify(webpack), + WEBPACK_CLI_VERSION: JSON.stringify(WEBPACK_CLI_VERSION), + WEBPACK_DEV_SERVER_VERSION: JSON.stringify(WEBPACK_DEV_SERVER_VERSION), + ASYNC: JSON.stringify(async), }) ); const driver = createWebpackDevServerDriver( - sandbox.spawn('yarn exec webpack-dev-server'), + sandbox.spawn('./node_modules/.bin/webpack-dev-server'), async ); let errors: string[]; diff --git a/test/e2e/PluginOutOfMemory.spec.ts b/test/e2e/PluginOutOfMemory.spec.ts index 21bb6b5a..c176942d 100644 --- a/test/e2e/PluginOutOfMemory.spec.ts +++ b/test/e2e/PluginOutOfMemory.spec.ts @@ -26,13 +26,15 @@ describe('ForkTsCheckerWebpackPlugin Out Of Memory', () => { ])('handles out of memory for %p', async ({ async, webpack }) => { await sandbox.load( await readFixture(join(__dirname, 'fixtures/typescript-basic.fixture'), { - FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION, - TS_LOADER_VERSION: '^5.0.0', - TYPESCRIPT_VERSION: '~3.8.0', - WEBPACK_VERSION: webpack, - WEBPACK_CLI_VERSION: '^3.3.11', - WEBPACK_DEV_SERVER_VERSION: '^3.10.3', - ASYNC: async ? 'true' : 'false', + FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION: JSON.stringify( + FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION + ), + TS_LOADER_VERSION: JSON.stringify('^5.0.0'), + TYPESCRIPT_VERSION: JSON.stringify('~3.8.0'), + WEBPACK_VERSION: JSON.stringify(webpack), + WEBPACK_CLI_VERSION: JSON.stringify('^3.3.11'), + WEBPACK_DEV_SERVER_VERSION: JSON.stringify('^3.10.3'), + ASYNC: JSON.stringify(async), }) ); @@ -48,7 +50,9 @@ describe('ForkTsCheckerWebpackPlugin Out Of Memory', () => { ].join('\n') ); - const driver = createGenericProcessDriver(sandbox.spawn('yarn exec webpack-dev-server')); + const driver = createGenericProcessDriver( + sandbox.spawn('./node_modules/.bin/webpack-dev-server') + ); // we should see an error message about out of memory await driver.waitForStderrIncludes( diff --git a/test/e2e/TypeScriptSolutionBuilderApi.spec.ts b/test/e2e/TypeScriptSolutionBuilderApi.spec.ts index 8e5e1e56..45e18d6c 100644 --- a/test/e2e/TypeScriptSolutionBuilderApi.spec.ts +++ b/test/e2e/TypeScriptSolutionBuilderApi.spec.ts @@ -28,18 +28,20 @@ describe('TypeScript SolutionBuilder API', () => { async ({ async }) => { await sandbox.load( await readFixture(join(__dirname, 'fixtures/typescript-project-references.fixture'), { - FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION, - TS_LOADER_VERSION: '^7.0.1', - TYPESCRIPT_VERSION: '~3.8.0', - WEBPACK_VERSION: '^4.0.0', - WEBPACK_CLI_VERSION, - WEBPACK_DEV_SERVER_VERSION, - ASYNC: async ? 'true' : 'false', + FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION: JSON.stringify( + FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION + ), + TS_LOADER_VERSION: JSON.stringify('^7.0.1'), + TYPESCRIPT_VERSION: JSON.stringify('~3.8.0'), + WEBPACK_VERSION: JSON.stringify('^4.0.0'), + WEBPACK_CLI_VERSION: JSON.stringify(WEBPACK_CLI_VERSION), + WEBPACK_DEV_SERVER_VERSION: JSON.stringify(WEBPACK_DEV_SERVER_VERSION), + ASYNC: JSON.stringify(async), }) ); const driver = createWebpackDevServerDriver( - sandbox.spawn('yarn exec webpack-dev-server'), + sandbox.spawn('./node_modules/.bin/webpack-dev-server'), async ); let errors: string[]; diff --git a/test/e2e/TypeScriptWatchApi.spec.ts b/test/e2e/TypeScriptWatchApi.spec.ts index 5ccfebda..1a0fdd0c 100644 --- a/test/e2e/TypeScriptWatchApi.spec.ts +++ b/test/e2e/TypeScriptWatchApi.spec.ts @@ -33,13 +33,15 @@ describe('TypeScript Watch API', () => { async ({ async, webpack }) => { await sandbox.load( await readFixture(join(__dirname, 'fixtures/typescript-basic.fixture'), { - FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION, - TS_LOADER_VERSION: '^5.0.0', - TYPESCRIPT_VERSION: '~3.8.0', - WEBPACK_VERSION: webpack, - WEBPACK_CLI_VERSION, - WEBPACK_DEV_SERVER_VERSION, - ASYNC: async ? 'true' : 'false', + FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION: JSON.stringify( + FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION + ), + TS_LOADER_VERSION: JSON.stringify('^5.0.0'), + TYPESCRIPT_VERSION: JSON.stringify('~3.8.0'), + WEBPACK_VERSION: JSON.stringify(webpack), + WEBPACK_CLI_VERSION: JSON.stringify(WEBPACK_CLI_VERSION), + WEBPACK_DEV_SERVER_VERSION: JSON.stringify(WEBPACK_DEV_SERVER_VERSION), + ASYNC: JSON.stringify(async), }) ); @@ -52,7 +54,7 @@ describe('TypeScript Watch API', () => { ); const driver = createWebpackDevServerDriver( - sandbox.spawn('yarn exec webpack-dev-server'), + sandbox.spawn('./node_modules/.bin/webpack-dev-server'), async ); let errors: string[]; @@ -155,18 +157,20 @@ describe('TypeScript Watch API', () => { ])('reports semantic error for %p', async ({ async, webpack, typescript, tsloader }) => { await sandbox.load( await readFixture(join(__dirname, 'fixtures/typescript-basic.fixture'), { - FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION, - TS_LOADER_VERSION: tsloader, - TYPESCRIPT_VERSION: typescript, - WEBPACK_VERSION: webpack, - WEBPACK_CLI_VERSION, - WEBPACK_DEV_SERVER_VERSION, - ASYNC: async ? 'true' : 'false', + FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION: JSON.stringify( + FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION + ), + TS_LOADER_VERSION: JSON.stringify(tsloader), + TYPESCRIPT_VERSION: JSON.stringify(typescript), + WEBPACK_VERSION: JSON.stringify(webpack), + WEBPACK_CLI_VERSION: JSON.stringify(WEBPACK_CLI_VERSION), + WEBPACK_DEV_SERVER_VERSION: JSON.stringify(WEBPACK_DEV_SERVER_VERSION), + ASYNC: JSON.stringify(async), }) ); const driver = createWebpackDevServerDriver( - sandbox.spawn('yarn exec webpack-dev-server'), + sandbox.spawn('./node_modules/.bin/webpack-dev-server'), async ); let errors: string[]; diff --git a/test/e2e/fixtures/eslint-basic.fixture b/test/e2e/fixtures/eslint-basic.fixture index 366cae2f..137ac822 100644 --- a/test/e2e/fixtures/eslint-basic.fixture +++ b/test/e2e/fixtures/eslint-basic.fixture @@ -9,12 +9,12 @@ "@typescript-eslint/eslint-plugin": "^2.27.0", "@typescript-eslint/parser": "^2.27.0", "eslint": "^6.8.0", - "fork-ts-checker-webpack-plugin": "${FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION}", - "ts-loader": "${TS_LOADER_VERSION}", - "typescript": "${TYPESCRIPT_VERSION}", - "webpack": "${WEBPACK_VERSION}", - "webpack-cli": "${WEBPACK_CLI_VERSION}", - "webpack-dev-server": "${WEBPACK_DEV_SERVER_VERSION}" + "fork-ts-checker-webpack-plugin": ${FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION}, + "ts-loader": ${TS_LOADER_VERSION}, + "typescript": ${TYPESCRIPT_VERSION}, + "webpack": ${WEBPACK_VERSION}, + "webpack-cli": ${WEBPACK_CLI_VERSION}, + "webpack-dev-server": ${WEBPACK_DEV_SERVER_VERSION} } } /// tsconfig.json diff --git a/test/e2e/fixtures/typescript-basic.fixture b/test/e2e/fixtures/typescript-basic.fixture index d1f79dc6..fd89fcc3 100644 --- a/test/e2e/fixtures/typescript-basic.fixture +++ b/test/e2e/fixtures/typescript-basic.fixture @@ -5,12 +5,12 @@ "main": "dist/index.js", "license": "MIT", "devDependencies": { - "fork-ts-checker-webpack-plugin": "${FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION}", - "ts-loader": "${TS_LOADER_VERSION}", - "typescript": "${TYPESCRIPT_VERSION}", - "webpack": "${WEBPACK_VERSION}", - "webpack-cli": "${WEBPACK_CLI_VERSION}", - "webpack-dev-server": "${WEBPACK_DEV_SERVER_VERSION}" + "fork-ts-checker-webpack-plugin": ${FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION}, + "ts-loader": ${TS_LOADER_VERSION}, + "typescript": ${TYPESCRIPT_VERSION}, + "webpack": ${WEBPACK_VERSION}, + "webpack-cli": ${WEBPACK_CLI_VERSION}, + "webpack-dev-server": ${WEBPACK_DEV_SERVER_VERSION} } } /// tsconfig.json diff --git a/test/e2e/fixtures/typescript-project-references.fixture b/test/e2e/fixtures/typescript-project-references.fixture index 3837b273..1fbc1f97 100644 --- a/test/e2e/fixtures/typescript-project-references.fixture +++ b/test/e2e/fixtures/typescript-project-references.fixture @@ -8,12 +8,12 @@ "packages/*" ], "devDependencies": { - "fork-ts-checker-webpack-plugin": "${FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION}", - "ts-loader": "${TS_LOADER_VERSION}", - "typescript": "${TYPESCRIPT_VERSION}", - "webpack": "${WEBPACK_VERSION}", - "webpack-cli": "${WEBPACK_CLI_VERSION}", - "webpack-dev-server": "${WEBPACK_DEV_SERVER_VERSION}" + "fork-ts-checker-webpack-plugin": ${FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION}, + "ts-loader": ${TS_LOADER_VERSION}, + "typescript": ${TYPESCRIPT_VERSION}, + "webpack": ${WEBPACK_VERSION}, + "webpack-cli": ${WEBPACK_CLI_VERSION}, + "webpack-dev-server": ${WEBPACK_DEV_SERVER_VERSION} } } diff --git a/test/e2e/sandbox/Sandbox.ts b/test/e2e/sandbox/Sandbox.ts index d0d299fc..6070a334 100644 --- a/test/e2e/sandbox/Sandbox.ts +++ b/test/e2e/sandbox/Sandbox.ts @@ -2,7 +2,8 @@ import { join, resolve, dirname } from 'path'; import fs from 'fs-extra'; import os from 'os'; import chalk from 'chalk'; -import { exec, spawn, ChildProcess } from 'child_process'; +import { exec, ChildProcess } from 'child_process'; +import spawn from 'cross-spawn'; import { Fixture } from './Fixture'; import stripAnsi from 'strip-ansi'; @@ -21,6 +22,10 @@ interface Sandbox { spawn: (command: string, env?: Record) => ChildProcess; } +function wait(timeout = 250) { + return new Promise((resolve) => setTimeout(resolve, timeout)); +} + async function createSandbox(): Promise { const context = await fs.mkdtemp(join(os.tmpdir(), 'fork-ts-checker-sandbox-')); let written: string[] = []; @@ -37,7 +42,9 @@ async function createSandbox(): Promise { process.stdout.write(chalk.blue('Installing dependencies...\n')); // use custom directory to not use cached version of the plugin const YARN_CACHE_FOLDER = join(sandbox.context, '.yarn'); - await sandbox.exec('yarn install', { + // use --ignore-optional to speedup the installation and to omit `fsevents` as + // webpack 4 uses old version which sometimes behave non-deterministic + await sandbox.exec('yarn install --ignore-optional', { YARN_CACHE_FOLDER, }); process.stdout.write(chalk.green('The sandbox initialized successfully.\n')); @@ -50,13 +57,18 @@ async function createSandbox(): Promise { for (const child of sandbox.children) { if (!child.killed) { process.stdout.write(`Killing child process ${child.pid}\n`); - child.kill(); + child.kill('SIGKILL'); } } + // wait for processes to be killed + await wait(); + process.stdout.write(`Resetting sandbox directory: ${context}\n`); await Promise.all(written.map((path) => sandbox.remove(path))); written = []; + + process.stdout.write(`Sandbox resetted\n\n`); }, cleanup: async () => { process.stdout.write('Cleaning up the sandbox\n'); @@ -64,14 +76,17 @@ async function createSandbox(): Promise { for (const child of sandbox.children) { if (!child.killed) { process.stdout.write(`Killing child process ${child.pid}\n`); - child.kill(); + child.kill('SIGKILL'); } } + // wait for processes to be killed + await wait(); + process.stdout.write(`Removing sandbox directory: ${context}\n`); await fs.remove(context); - process.stdout.write('Sandbox cleaned up.\n'); + process.stdout.write('Sandbox cleaned up.\n\n'); }, write: async (path: string, content: string) => { process.stdout.write(`Writing file ${path}...\n`); @@ -106,14 +121,14 @@ async function createSandbox(): Promise { process.stdout.write(`Removing file ${path}...\n`); const realPath = join(context, path); - // wait to avoid race conditions - await new Promise((resolve) => setTimeout(resolve, 100)); + // wait for fs events to be propagated + await wait(); return fs.remove(realPath); }, patch: async (path: string, search: string, replacement: string) => { process.stdout.write( - `Patching file ${path} - replacing ${search} with "${replacement}"...\n` + `Patching file ${path} - replacing "${search}" with "${replacement}"...\n` ); const realPath = join(context, path); const content = await fs.readFile(realPath, 'utf-8'); @@ -122,8 +137,8 @@ async function createSandbox(): Promise { throw new Error(`Cannot find "${search}" in the ${path}. The file content:\n${content}.`); } - // wait to avoid race conditions - await new Promise((resolve) => setTimeout(resolve, 100)); + // wait for fs events to be propagated + await wait(); return fs.writeFile(realPath, content.replace(search, replacement)); }, diff --git a/test/unit/formatter/WebpackFormatter.spec.ts b/test/unit/formatter/WebpackFormatter.spec.ts index cba6998a..20718426 100644 --- a/test/unit/formatter/WebpackFormatter.spec.ts +++ b/test/unit/formatter/WebpackFormatter.spec.ts @@ -1,5 +1,5 @@ import os from 'os'; -import { join } from 'path'; +import { join, sep } from 'path'; import { Issue } from 'lib/issue'; import { createBasicFormatter, createWebpackFormatter, Formatter } from 'lib/formatter'; @@ -38,7 +38,7 @@ describe('formatter/WebpackFormatter', () => { }); it('formats issue file', () => { - expect(formatter(issue)).toContain('some/file.ts'); + expect(formatter(issue)).toContain(`some${sep}file.ts`); }); it('formats location', () => { @@ -53,7 +53,7 @@ describe('formatter/WebpackFormatter', () => { it('formats issue header like webpack', () => { expect(formatter(issue)).toEqual( - ['ERROR in some/file.ts 1:7-16', 'TS123: Some issue content', ''].join(os.EOL) + [`ERROR in some${sep}file.ts 1:7-16`, 'TS123: Some issue content', ''].join(os.EOL) ); }); }); diff --git a/test/unit/typescript-reporter/TypeScriptReporterConfiguration.spec.ts b/test/unit/typescript-reporter/TypeScriptReporterConfiguration.spec.ts index 0d595d76..ebe14518 100644 --- a/test/unit/typescript-reporter/TypeScriptReporterConfiguration.spec.ts +++ b/test/unit/typescript-reporter/TypeScriptReporterConfiguration.spec.ts @@ -1,4 +1,5 @@ import webpack from 'webpack'; +import unixify from 'unixify'; import { TypeScriptReporterConfiguration } from 'lib/typescript-reporter/TypeScriptReporterConfiguration'; import { TypeScriptReporterOptions } from 'lib/typescript-reporter/TypeScriptReporterOptions'; @@ -87,7 +88,9 @@ describe('typescript-reporter/TypeScriptsReporterConfiguration', () => { options as TypeScriptReporterOptions ); - expect(configuration).toEqual(expectedConfiguration); + expect({ ...configuration, tsconfig: unixify(configuration.tsconfig) }).toEqual( + expectedConfiguration + ); }); it('passes vue options to the vue extension', async () => { diff --git a/yarn.lock b/yarn.lock index b1155a9b..9c8e32ac 100644 --- a/yarn.lock +++ b/yarn.lock @@ -884,6 +884,13 @@ resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== +"@types/cross-spawn@^6.0.2": + version "6.0.2" + resolved "https://registry.yarnpkg.com/@types/cross-spawn/-/cross-spawn-6.0.2.tgz#168309de311cd30a2b8ae720de6475c2fbf33ac7" + integrity sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw== + dependencies: + "@types/node" "*" + "@types/eslint-visitor-keys@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" @@ -2369,7 +2376,7 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^7.0.0: +cross-spawn@^7.0.0, cross-spawn@^7.0.2: version "7.0.2" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.2.tgz#d0d7dcfa74e89115c7619f4f721a94e1fdb716d6" integrity sha512-PD6G8QG3S4FK/XCGFbEQrDqO2AnMMsy0meR7lerlIOHAAbkuavGU/pOqprrlvfTNjvowivTeBsjebAL0NSoMxw== @@ -7188,6 +7195,13 @@ universalify@^1.0.0: resolved "https://registry.yarnpkg.com/universalify/-/universalify-1.0.0.tgz#b61a1da173e8435b2fe3c67d29b9adf8594bd16d" integrity sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug== +unixify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unixify/-/unixify-1.0.0.tgz#3a641c8c2ffbce4da683a5c70f03a462940c2090" + integrity sha1-OmQcjC/7zk2mg6XHDwOkYpQMIJA= + dependencies: + normalize-path "^2.1.1" + unset-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" From 6974ed231230a5001710039d052175b9782bd8c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ole=C5=9B?= Date: Sun, 17 May 2020 17:39:54 +0200 Subject: [PATCH 16/29] test: stabilize e2e tests on linux and mac --- .github/workflows/main.yml | 4 +- package.json | 2 +- src/ForkTsCheckerWebpackPlugin.ts | 4 +- src/ForkTsCheckerWebpackPluginState.ts | 2 - .../EsLintReporterConfiguration.ts | 5 +- src/eslint-reporter/EsLintReporterOptions.ts | 5 +- .../reporter/EsLintReporter.ts | 35 ++-- src/eslint-reporter/types/eslint.ts | 8 + src/hooks/getChangedFiles.ts | 10 +- src/hooks/getDeletedFiles.ts | 2 +- src/hooks/getWatcher.ts | 4 +- ...dRemoved.ts => tapDoneToCollectRemoved.ts} | 10 +- src/hooks/tapStartToConnectAndRunReporter.ts | 2 +- src/rpc/rpc-ipc/RpcIpcMessagePort.ts | 23 ++- .../error/RpcIpcMessagePortClosedError.ts | 4 +- test/e2e/.DS_Store | Bin 0 -> 6148 bytes test/e2e/EsLint.spec.ts | 22 +-- test/e2e/fixtures/.DS_Store | Bin 0 -> 6148 bytes .../typescript-project-references.fixture | 14 +- test/e2e/sandbox/GenericProcessDriver.ts | 66 +++++--- test/e2e/sandbox/Listener.ts | 62 ++++++- test/e2e/sandbox/Sandbox.ts | 158 +++++++++++------- test/e2e/sandbox/WebpackDevServerDriver.ts | 62 ++++--- test/setup.ts | 3 +- 24 files changed, 334 insertions(+), 173 deletions(-) rename src/hooks/{tapDoneToCollectChangedAndRemoved.ts => tapDoneToCollectRemoved.ts} (74%) create mode 100644 test/e2e/.DS_Store create mode 100644 test/e2e/fixtures/.DS_Store diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a0fea3bc..90efed32 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -39,8 +39,8 @@ jobs: needs: build strategy: matrix: - node: [10, 12, 14] - os: [ubuntu-latest, macos-latest, windows-latest] + node: [10, 12] # add 14 when we drop support for webpack 4 as fsevents 1 is not compatible with node 14 + os: [ubuntu-latest, macos-latest] # add windows-latest when e2e tests on other platforms will be stable steps: - uses: actions/checkout@v1 diff --git a/package.json b/package.json index 31c248b1..60ffd529 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "lint": "eslint ./src ./test --ext .ts", "test": "yarn build && yarn test:unit && yarn test:e2e", "test:unit": "jest unit", - "test:e2e": "yarn pack --filename fork-ts-checker-webpack-plugin.tgz && jest e2e --runInBand", + "test:e2e": "yarn pack --filename fork-ts-checker-webpack-plugin.tgz && jest e2e --ci --runInBand --bail --verbose", "precommit": "lint-staged && yarn build && yarn test:unit", "commit": "./node_modules/.bin/git-cz" }, diff --git a/src/ForkTsCheckerWebpackPlugin.ts b/src/ForkTsCheckerWebpackPlugin.ts index 615af678..55bfbaa0 100644 --- a/src/ForkTsCheckerWebpackPlugin.ts +++ b/src/ForkTsCheckerWebpackPlugin.ts @@ -14,7 +14,7 @@ import { tapStartToConnectAndRunReporter } from './hooks/tapStartToConnectAndRun import { tapStopToDisconnectReporter } from './hooks/tapStopToDisconnectReporter'; import { tapAfterCompileToGetIssues } from './hooks/tapAfterCompileToGetIssues'; import { getForkTsCheckerWebpackPluginHooks } from './hooks/pluginHooks'; -import { tapDoneToCollectChangedAndRemoved } from './hooks/tapDoneToCollectChangedAndRemoved'; +import { tapDoneToCollectRemoved } from './hooks/tapDoneToCollectRemoved'; class ForkTsCheckerWebpackPlugin implements webpack.Plugin { constructor(private readonly options: ForkTsCheckerWebpackPluginOptions = {}) { @@ -44,7 +44,7 @@ class ForkTsCheckerWebpackPlugin implements webpack.Plugin { const reporter = createAggregatedReporter(composeReporterRpcClients(reporters)); tapStartToConnectAndRunReporter(compiler, reporter, configuration, state); - tapDoneToCollectChangedAndRemoved(compiler, configuration, state); + tapDoneToCollectRemoved(compiler, configuration, state); tapStopToDisconnectReporter(compiler, reporter, configuration, state); if (configuration.async) { tapDoneToAsyncGetIssues(compiler, configuration, state); diff --git a/src/ForkTsCheckerWebpackPluginState.ts b/src/ForkTsCheckerWebpackPluginState.ts index 7e194630..eca8e828 100644 --- a/src/ForkTsCheckerWebpackPluginState.ts +++ b/src/ForkTsCheckerWebpackPluginState.ts @@ -2,7 +2,6 @@ import { Report } from './reporter'; interface ForkTsCheckerWebpackPluginState { report: Promise; - changedFiles: string[]; removedFiles: string[]; isWatching: boolean; } @@ -10,7 +9,6 @@ interface ForkTsCheckerWebpackPluginState { function createForkTsCheckerWebpackPluginState(): ForkTsCheckerWebpackPluginState { return { report: Promise.resolve([]), - changedFiles: [], removedFiles: [], isWatching: false, }; diff --git a/src/eslint-reporter/EsLintReporterConfiguration.ts b/src/eslint-reporter/EsLintReporterConfiguration.ts index 5f95d8a6..fe5e5e0d 100644 --- a/src/eslint-reporter/EsLintReporterConfiguration.ts +++ b/src/eslint-reporter/EsLintReporterConfiguration.ts @@ -1,11 +1,13 @@ import webpack from 'webpack'; import { EsLintReporterOptions } from './EsLintReporterOptions'; +import { CLIEngineOptions } from './types/eslint'; interface EsLintReporterConfiguration { enabled: boolean; memoryLimit: number; - options: object; + options: CLIEngineOptions; files: string[]; + cwd: string; } function castToArray(value: T | T[] | undefined): T[] { @@ -27,6 +29,7 @@ function createEsLintReporterConfiguration( memoryLimit: 2048, ...(typeof options === 'object' ? options : {}), files: typeof options === 'object' ? castToArray(options.files) : [], + cwd: compiler.options.context || process.cwd(), options: { cwd: compiler.options.context || process.cwd(), extensions: ['.js', '.ts', '.tsx'], diff --git a/src/eslint-reporter/EsLintReporterOptions.ts b/src/eslint-reporter/EsLintReporterOptions.ts index 65868e9d..6e61450c 100644 --- a/src/eslint-reporter/EsLintReporterOptions.ts +++ b/src/eslint-reporter/EsLintReporterOptions.ts @@ -1,9 +1,10 @@ +import { CLIEngineOptions } from './types/eslint'; + type EsLintReporterOptions = { files: string | string[]; enabled?: boolean; memoryLimit?: number; - // it's not typed because we don't want to have direct dependency to eslint from this plugin - options?: object; + options?: CLIEngineOptions; }; export { EsLintReporterOptions }; diff --git a/src/eslint-reporter/reporter/EsLintReporter.ts b/src/eslint-reporter/reporter/EsLintReporter.ts index 5e342e5f..39470860 100644 --- a/src/eslint-reporter/reporter/EsLintReporter.ts +++ b/src/eslint-reporter/reporter/EsLintReporter.ts @@ -1,23 +1,23 @@ +// eslint-disable-next-line @typescript-eslint/no-unused-vars import { CLIEngine, LintReport, LintResult } from '../types/eslint'; import { createIssuesFromEsLintResults } from '../issue/EsLintIssueFactory'; import { EsLintReporterConfiguration } from '../EsLintReporterConfiguration'; import { Reporter } from '../../reporter'; +import minimatch from 'minimatch'; +import { join } from 'path'; function createEsLintReporter(configuration: EsLintReporterConfiguration): Reporter { - let engine: CLIEngine; + // eslint-disable-next-line @typescript-eslint/no-var-requires + const { CLIEngine } = require('eslint'); + const engine: CLIEngine = new CLIEngine(configuration.options); + let isInitialRun = true; const lintResults = new Map(); + const includedFilesPatterns = engine.resolveFileGlobPatterns(configuration.files); return { getReport: async ({ changedFiles = [], deletedFiles = [] }) => { - if (!engine) { - // eslint-disable-next-line @typescript-eslint/no-var-requires - const { CLIEngine } = require('eslint'); - - engine = new CLIEngine(configuration.options); - isInitialRun = true; - } - + // cleanup old results changedFiles.forEach((changedFile) => { lintResults.delete(changedFile); }); @@ -27,18 +27,23 @@ function createEsLintReporter(configuration: EsLintReporterConfiguration): Repor // get reports const lintReports: LintReport[] = []; + if (isInitialRun) { - lintReports.push( - engine.executeOnFiles(engine.resolveFileGlobPatterns(configuration.files)) - ); + lintReports.push(engine.executeOnFiles(includedFilesPatterns)); isInitialRun = false; } else { - if (changedFiles.length) { - lintReports.push(engine.executeOnFiles(changedFiles)); + const changedAndIncludedFiles = changedFiles.filter((changedFile) => + includedFilesPatterns.some((includedFilesPattern) => + minimatch(changedFile, join(configuration.cwd, includedFilesPattern)) + ) + ); + + if (changedAndIncludedFiles.length) { + lintReports.push(engine.executeOnFiles(changedAndIncludedFiles)); } } - // store results in the state + // store results lintReports.forEach((lintReport) => { lintReport.results.forEach((lintResult) => { lintResults.set(lintResult.filePath, lintResult); diff --git a/src/eslint-reporter/types/eslint.ts b/src/eslint-reporter/types/eslint.ts index 1b91e61a..bc4d811b 100644 --- a/src/eslint-reporter/types/eslint.ts +++ b/src/eslint-reporter/types/eslint.ts @@ -28,4 +28,12 @@ export interface CLIEngine { version: string; executeOnFiles(filesPatterns: string[]): LintReport; resolveFileGlobPatterns(filesPatterns: string[]): string[]; + isPathIgnored(filePath: string): boolean; +} + +export interface CLIEngineOptions { + cwd?: string; + extensions?: string[]; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + [key: string]: any; } diff --git a/src/hooks/getChangedFiles.ts b/src/hooks/getChangedFiles.ts index 68c1b7f3..07115e0c 100644 --- a/src/hooks/getChangedFiles.ts +++ b/src/hooks/getChangedFiles.ts @@ -1,17 +1,15 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import webpack from 'webpack'; -import { ForkTsCheckerWebpackPluginState } from '../ForkTsCheckerWebpackPluginState'; +import { getWatcher } from './getWatcher'; -function getChangedFiles( - compiler: webpack.Compiler, - state: ForkTsCheckerWebpackPluginState -): string[] { +function getChangedFiles(compiler: webpack.Compiler): string[] { if ((compiler as any).modifiedFiles) { // webpack 5+ return Array.from((compiler as any).modifiedFiles); } else { + const watcher = getWatcher(compiler); // webpack 4 - return state.changedFiles; + return Object.keys((watcher && watcher.mtimes) || {}); } } diff --git a/src/hooks/getDeletedFiles.ts b/src/hooks/getDeletedFiles.ts index 72995848..b202a1a4 100644 --- a/src/hooks/getDeletedFiles.ts +++ b/src/hooks/getDeletedFiles.ts @@ -11,7 +11,7 @@ function getDeletedFiles( return Array.from((compiler as any).removedFiles || []); } else { // webpack 4 - return state.removedFiles; + return [...state.removedFiles]; } } diff --git a/src/hooks/getWatcher.ts b/src/hooks/getWatcher.ts index 17b091cd..e0bd3dce 100644 --- a/src/hooks/getWatcher.ts +++ b/src/hooks/getWatcher.ts @@ -1,7 +1,9 @@ import webpack from 'webpack'; import { EventEmitter } from 'events'; -type Watcher = EventEmitter; +interface Watcher extends EventEmitter { + mtimes: Record; +} function getWatcher(compiler: webpack.Compiler): Watcher | undefined { // webpack 4 diff --git a/src/hooks/tapDoneToCollectChangedAndRemoved.ts b/src/hooks/tapDoneToCollectRemoved.ts similarity index 74% rename from src/hooks/tapDoneToCollectChangedAndRemoved.ts rename to src/hooks/tapDoneToCollectRemoved.ts index 3844ac50..1aee5e65 100644 --- a/src/hooks/tapDoneToCollectChangedAndRemoved.ts +++ b/src/hooks/tapDoneToCollectRemoved.ts @@ -3,26 +3,22 @@ import { ForkTsCheckerWebpackPluginConfiguration } from '../ForkTsCheckerWebpack import { ForkTsCheckerWebpackPluginState } from '../ForkTsCheckerWebpackPluginState'; import { getWatcher } from './getWatcher'; -function tapDoneToCollectChangedAndRemoved( +function tapDoneToCollectRemoved( compiler: webpack.Compiler, configuration: ForkTsCheckerWebpackPluginConfiguration, state: ForkTsCheckerWebpackPluginState ) { compiler.hooks.done.tap('ForkTsCheckerWebpackPlugin', (stats) => { - state.changedFiles = []; state.removedFiles = []; // the new watcher is defined after done hook - // we need this for webpack < 5, because modifiedFiles and removedFiles set is not provided + // we need this for webpack < 5, because removedFiles set is not provided // this hook can be removed when we drop support for webpack 4 setImmediate(() => { const compiler = stats.compilation.compiler; const watcher = getWatcher(compiler); if (watcher) { - watcher.on('change', (filePath: string) => { - state.changedFiles.push(filePath); - }); watcher.on('remove', (filePath: string) => { state.removedFiles.push(filePath); }); @@ -32,4 +28,4 @@ function tapDoneToCollectChangedAndRemoved( }); } -export { tapDoneToCollectChangedAndRemoved }; +export { tapDoneToCollectRemoved }; diff --git a/src/hooks/tapStartToConnectAndRunReporter.ts b/src/hooks/tapStartToConnectAndRunReporter.ts index 59f4f382..5cd89a00 100644 --- a/src/hooks/tapStartToConnectAndRunReporter.ts +++ b/src/hooks/tapStartToConnectAndRunReporter.ts @@ -35,7 +35,7 @@ function tapStartToConnectAndRunReporter( state.isWatching = true; let change: FilesChange = { - changedFiles: getChangedFiles(compiler, state), + changedFiles: getChangedFiles(compiler), deletedFiles: getDeletedFiles(compiler, state), }; diff --git a/src/rpc/rpc-ipc/RpcIpcMessagePort.ts b/src/rpc/rpc-ipc/RpcIpcMessagePort.ts index cd9499c5..eb9deecc 100644 --- a/src/rpc/rpc-ipc/RpcIpcMessagePort.ts +++ b/src/rpc/rpc-ipc/RpcIpcMessagePort.ts @@ -36,19 +36,31 @@ function createRpcIpcMessagePort(process: ProcessLike): RpcMessagePort { dispatchMessage: async (message) => new Promise((resolve, reject) => { if (!process.connected) { - reject(closedError || new Error(`Process ${process.pid} doesn't have open IPC channels`)); + reject( + closedError || + new RpcIpcMessagePortClosedError( + `Process ${process.pid} doesn't have open IPC channels` + ) + ); } if (process.send) { process.send({ ...message, source: process.pid }, undefined, undefined, (sendError) => { if (sendError) { - reject(closedError || sendError); + if (!closedError) { + closedError = new RpcIpcMessagePortClosedError( + `Cannot send the message - the message port has been closed for the process ${process.pid}.` + ); + } + reject(closedError); } else { resolve(); } }); } else { - reject(new Error(`Process ${process.pid} doesn't have IPC channels`)); + reject( + new RpcIpcMessagePortClosedError(`Process ${process.pid} doesn't have IPC channels`) + ); } }), addMessageListener: (listener) => { @@ -67,7 +79,10 @@ function createRpcIpcMessagePort(process: ProcessLike): RpcMessagePort { open: async () => { if (!process.connected || closedError) { throw ( - closedError || new Error(`Cannot open closed IPC channel for process ${process.pid}.`) + closedError || + new RpcIpcMessagePortClosedError( + `Cannot open closed IPC channel for process ${process.pid}.` + ) ); } }, diff --git a/src/rpc/rpc-ipc/error/RpcIpcMessagePortClosedError.ts b/src/rpc/rpc-ipc/error/RpcIpcMessagePortClosedError.ts index 27c9284f..5654bbfa 100644 --- a/src/rpc/rpc-ipc/error/RpcIpcMessagePortClosedError.ts +++ b/src/rpc/rpc-ipc/error/RpcIpcMessagePortClosedError.ts @@ -3,8 +3,8 @@ import { RpcMessagePortClosedError } from '../../error/RpcMessagePortClosedError class RpcIpcMessagePortClosedError extends RpcMessagePortClosedError { constructor( message: string, - readonly code: string | number | null, - readonly signal: string | null + readonly code?: string | number | null, + readonly signal?: string | null ) { super(message); this.name = 'RpcIpcMessagePortClosedError'; diff --git a/test/e2e/.DS_Store b/test/e2e/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..c339219d14259f097e2ed0ae090a03ea170cf858 GIT binary patch literal 6148 zcmeHK-D(p-6h6~NyNRf|5L&(33k5HNG=!Fj2-~&2C@3v#u@@@sZZ zH@<`V20n^U;Dh)8`pu6ee^Q|!Qs%(ScXsCd%zm>ovqMD8@5ObZDiJv-5=#|Sb42#b zG9wG7MRqb3BO^hNsGu&jXRK|5Wxz70=ZP5f_BH%$t$y84|hES9caUviv^Q@L4r z6Lfe#5TWQ5ewe?KPrIS$L`L7^JU!RL=w;IGA5`x=Lw-1lc-VNRlKYUiN zP7Ir#lG_Gm^jEhJKsv@P6b;= zl<}!p!X$>6!k8lXpH5C3`#5ENpZ1VJZqxy_kS&2OpmQ}UfoG0bKE{=xC5By28?Z?( z7}bxdJoo12*~dr)@^=0vruyhUjeT@TVde4+n9tX_arsa-f@Q!maK#vq`-6)j(K9&G zsJ0GN>IwiXp;-xZ`I{hpT!Ws$kw)}Dn05tfS7xplOuM7qHFloCkw)!K%v?U0$;`|R zg{ka_?<#X*o<>_+1}p=U3@qx$syzR<{(S$Rbh1yD0n5OZVt|!4gH0c=WX{%^my>6$ ui*kq}McR!tDi>7dI97^0idRsSpwE>G&@(vFh!%+b5l}SP$};dz8TbX;3A_vd literal 0 HcmV?d00001 diff --git a/test/e2e/EsLint.spec.ts b/test/e2e/EsLint.spec.ts index f1ae39b0..49d04fdb 100644 --- a/test/e2e/EsLint.spec.ts +++ b/test/e2e/EsLint.spec.ts @@ -76,16 +76,18 @@ describe('EsLint', () => { ]); // fix these issues - await sandbox.patch( - 'src/authenticate.ts', - 'async function logout(): Promise {', - 'async function logout(): Promise {' - ); - await sandbox.patch( - 'src/index.ts', - "loginForm.addEventListener('submit', async event => {", - "loginForm.addEventListener('submit', async () => {" - ); + await Promise.all([ + sandbox.patch( + 'src/authenticate.ts', + 'async function logout(): Promise {', + 'async function logout(): Promise {' + ), + sandbox.patch( + 'src/index.ts', + "loginForm.addEventListener('submit', async event => {", + "loginForm.addEventListener('submit', async () => {" + ), + ]); // next iteration should have no errors await driver.waitForNoErrors(); diff --git a/test/e2e/fixtures/.DS_Store b/test/e2e/fixtures/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..c08e33d73212f2b84e90c7ee2e11fb35cc1ddc7f GIT binary patch literal 6148 zcmeHK&2AGh5FWRoY=RIuL~4$Esl*|mMp3IEgtQ9f&|9TNZ~&CBS{gBD5D`M>}!lUOjR#V zRSX|KFdjqi|Ih;K8gb%jHnMTP#iKOI^4;C#(YwNb>RlLgG%A0VgrePlCldKbs zUvcdy%7?MFpDUIAwxjq(GMIL&wWmtvQ6dLp?VR)n81njMBKvCEQ4`tEbezz1cwX5n zcdPZ;tkv9a_ZnYbJtGzd$m%Z(s=99zY_vasGALpOG=qZxGL8s-O#b0m% z1(9mW-qIa11A~ zuMtmdFU8xrBHjqG6}>~Ao{rB4{t1*(qK)(a^_Pp!OPNr0vTg?KU)j5}?!+#iW56+R z;~C)d!G|&i77K&==s=;L0KgKOwZP_21NQMP1{Mp0=z$313N)_5J~4!GN4syw1r`f~ z#+`(Hd*%9B@!$|}NUFjHb3@kFRX{uGe|DRp`{$F%*HOGKs;J;!(ln%m! z4yI)9)|JWeUF$=Sp)5SEFsNNn*y~sud==NBTF~dS0Sqh_2GIg>9|D>NS2zaN%D_)< C^sMdx literal 0 HcmV?d00001 diff --git a/test/e2e/fixtures/typescript-project-references.fixture b/test/e2e/fixtures/typescript-project-references.fixture index 1fbc1f97..c403706a 100644 --- a/test/e2e/fixtures/typescript-project-references.fixture +++ b/test/e2e/fixtures/typescript-project-references.fixture @@ -4,10 +4,11 @@ "version": "1.0.0", "license": "MIT", "private": true, - "workspaces": [ - "packages/*" - ], + "scripts": { + "postinstall": "lerna bootstrap" + }, "devDependencies": { + "lerna": "^3.0.0", "fork-ts-checker-webpack-plugin": ${FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION}, "ts-loader": ${TS_LOADER_VERSION}, "typescript": ${TYPESCRIPT_VERSION}, @@ -17,6 +18,13 @@ } } +/// lerna.json +{ + "version": "1.0.0", + "npmClient": "npm", + "packages": ["packages/*"] +} + /// tsconfig.json { "compilerOptions": { diff --git a/test/e2e/sandbox/GenericProcessDriver.ts b/test/e2e/sandbox/GenericProcessDriver.ts index 73240f21..c4739419 100644 --- a/test/e2e/sandbox/GenericProcessDriver.ts +++ b/test/e2e/sandbox/GenericProcessDriver.ts @@ -1,5 +1,5 @@ import { ChildProcess } from 'child_process'; -import { Listener } from './Listener'; +import { createQueuedListener, Listener, QueuedListener } from './Listener'; import stripAnsi from 'strip-ansi'; interface GenericProcessDriver { @@ -9,33 +9,59 @@ interface GenericProcessDriver { } interface StringListener extends Listener { - string: string; + ingest(input: string): void; + string?: string; +} + +interface QueuedStringListener extends StringListener, QueuedListener { + apply(listener: Omit): void; +} + +function createQueuedStringListener(): QueuedStringListener { + let buffer = ''; + + const queuedListener = createQueuedListener(); + const stringListener: QueuedStringListener = { + ...queuedListener, + apply(listener) { + queuedListener.apply(listener); + stringListener.string = listener.string; + + if (buffer.includes(stringListener.string)) { + stringListener.resolve(); + } + }, + ingest(input) { + if (stringListener.string === undefined) { + buffer += input; + } else if (input.includes(stringListener.string)) { + stringListener.resolve(); + } + }, + string: undefined, + }; + + return stringListener; } function createGenericProcessDriver( process: ChildProcess, defaultTimeout = 30000 ): GenericProcessDriver { - let stdoutListener: StringListener | undefined = undefined; - let stderrListener: StringListener | undefined = undefined; + let stdoutListener = createQueuedStringListener(); + let stderrListener = createQueuedStringListener(); if (process.stdout) { process.stdout.on('data', (data) => { const content = stripAnsi(data.toString()); - - if (stdoutListener && content.includes(stdoutListener.string)) { - stdoutListener.resolve(); - } + stdoutListener.ingest(content); }); } if (process.stderr) { process.stderr.on('data', (data) => { const content = stripAnsi(data.toString()); - - if (stderrListener && content.includes(stderrListener.string)) { - stderrListener.resolve(); - } + stderrListener.ingest(content); }); } @@ -46,19 +72,19 @@ function createGenericProcessDriver( reject(new Error(`Exceeded time on waiting for "${string}" to appear in the stdout.`)); }, timeout); - stdoutListener = { + stdoutListener.apply({ resolve: () => { clearTimeout(timeoutId); - stdoutListener = undefined; + stdoutListener = createQueuedStringListener(); resolve(); }, reject: (error) => { clearTimeout(timeoutId); - stdoutListener = undefined; + stdoutListener = createQueuedStringListener(); reject(error); }, string, - }; + }); }), waitForStderrIncludes: (string, timeout = defaultTimeout) => new Promise((resolve, reject) => { @@ -66,19 +92,19 @@ function createGenericProcessDriver( reject(new Error(`Exceeded time on waiting for "${string}" to appear in the stderr.`)); }, timeout); - stderrListener = { + stderrListener.apply({ resolve: () => { clearTimeout(timeoutId); - stderrListener = undefined; + stderrListener = createQueuedStringListener(); resolve(); }, reject: (error) => { clearTimeout(timeoutId); - stderrListener = undefined; + stderrListener = createQueuedStringListener(); reject(error); }, string, - }; + }); }), close: async () => process.kill(), }; diff --git a/test/e2e/sandbox/Listener.ts b/test/e2e/sandbox/Listener.ts index bf7e90eb..8977485a 100644 --- a/test/e2e/sandbox/Listener.ts +++ b/test/e2e/sandbox/Listener.ts @@ -1,6 +1,60 @@ -interface Listener { - resolve: (value: T) => void; - reject: (error: unknown) => void; +interface Listener { + resolve(value: TValue): void; + reject(error: unknown): void; } -export { Listener }; +interface QueuedListener extends Listener { + apply(listener: Listener): void; + resolved: TValue | undefined; + rejected: unknown | undefined; + status: 'pending' | 'resolved' | 'rejected'; +} + +function createQueuedListener(): QueuedListener { + let resolve: (value: TValue) => void | undefined; + let reject: (error: unknown) => void | undefined; + + const queuedListener: QueuedListener = { + resolve(value) { + if (queuedListener.status === 'pending') { + queuedListener.resolved = value; + queuedListener.status = 'resolved'; + + if (resolve) { + resolve(value); + } + } + }, + reject(error) { + if (queuedListener.status === 'pending') { + queuedListener.rejected = error; + queuedListener.status = 'rejected'; + + if (reject) { + reject(error); + } + } + }, + apply(listener) { + switch (queuedListener.status) { + case 'resolved': + listener.resolve(queuedListener.resolved); + break; + case 'rejected': + listener.reject(queuedListener.rejected); + break; + case 'pending': + resolve = listener.resolve; + reject = listener.reject; + break; + } + }, + resolved: undefined, + rejected: undefined, + status: 'pending', + }; + + return queuedListener; +} + +export { Listener, QueuedListener, createQueuedListener }; diff --git a/test/e2e/sandbox/Sandbox.ts b/test/e2e/sandbox/Sandbox.ts index 6070a334..9931e308 100644 --- a/test/e2e/sandbox/Sandbox.ts +++ b/test/e2e/sandbox/Sandbox.ts @@ -1,7 +1,6 @@ import { join, resolve, dirname } from 'path'; import fs from 'fs-extra'; import os from 'os'; -import chalk from 'chalk'; import { exec, ChildProcess } from 'child_process'; import spawn from 'cross-spawn'; import { Fixture } from './Fixture'; @@ -9,7 +8,6 @@ import stripAnsi from 'strip-ansi'; interface Sandbox { context: string; - children: ChildProcess[]; load: (fixture: Fixture) => Promise; reset: () => Promise; cleanup: () => Promise; @@ -26,62 +24,94 @@ function wait(timeout = 250) { return new Promise((resolve) => setTimeout(resolve, timeout)); } +/** + * The IO effects sometimes fail due to different external issues - for example, network or filesystem. + * To make these tests more reliable, we can wrap these effects in the `retry` function. + * + * @param effect + * @param retries + * @param delay + */ +async function retry(effect: () => Promise, retries = 3, delay = 250): Promise { + let lastError: unknown; + + for (let retry = 1; retry <= retries; ++retry) { + try { + return await effect(); + } catch (error) { + console.log(`${error.toString()}.\nRetry ${retry} of ${retries}.`); + lastError = error; + await wait(delay); + } + } + + throw lastError; +} + +// create cache directory to speed-up the testing +const CACHE_DIR = fs.mkdtempSync(join(os.tmpdir(), 'fork-ts-checker-cache-')); +const NPM_CACHE_DIR = join(CACHE_DIR, 'npm'); + async function createSandbox(): Promise { const context = await fs.mkdtemp(join(os.tmpdir(), 'fork-ts-checker-sandbox-')); - let written: string[] = []; + + let createdFiles: string[] = []; + let childProcesses: ChildProcess[] = []; + + async function removeCreatedFiles() { + await Promise.all(createdFiles.map((path) => sandbox.remove(path))); + createdFiles = []; + + await wait(); + } + + async function killChildProcesses() { + for (const childProcess of childProcesses) { + if (!childProcess.killed) { + process.stdout.write(`Killing child process ${childProcess.pid}\n`); + childProcess.kill('SIGKILL'); + } + } + childProcesses = []; + + await wait(); + } process.stdout.write(`Sandbox directory: ${context}\n`); const sandbox: Sandbox = { context, - children: [], load: async (fixture) => { + // write files await Promise.all(Object.keys(fixture).map((path) => sandbox.write(path, fixture[path]))); - process.stdout.write(chalk.green('Fixture initialized.\n')); - - process.stdout.write(chalk.blue('Installing dependencies...\n')); - // use custom directory to not use cached version of the plugin - const YARN_CACHE_FOLDER = join(sandbox.context, '.yarn'); - // use --ignore-optional to speedup the installation and to omit `fsevents` as - // webpack 4 uses old version which sometimes behave non-deterministic - await sandbox.exec('yarn install --ignore-optional', { - YARN_CACHE_FOLDER, - }); - process.stdout.write(chalk.green('The sandbox initialized successfully.\n')); + process.stdout.write('Fixture initialized.\n'); - written = []; - }, - reset: async () => { - process.stdout.write('Resetting the sandbox\n'); + process.stdout.write('Installing dependencies...\n'); - for (const child of sandbox.children) { - if (!child.killed) { - process.stdout.write(`Killing child process ${child.pid}\n`); - child.kill('SIGKILL'); - } - } + await retry(() => + sandbox.exec('npm install', { + // eslint-disable-next-line @typescript-eslint/camelcase + npm_config_cache: NPM_CACHE_DIR, + }) + ); + process.stdout.write('The sandbox initialized successfully.\n'); + + createdFiles = []; - // wait for processes to be killed await wait(); + }, + reset: async () => { + process.stdout.write('Resetting the sandbox...\n'); - process.stdout.write(`Resetting sandbox directory: ${context}\n`); - await Promise.all(written.map((path) => sandbox.remove(path))); - written = []; + await killChildProcesses(); + await removeCreatedFiles(); - process.stdout.write(`Sandbox resetted\n\n`); + process.stdout.write(`Sandbox resetted.\n\n`); }, cleanup: async () => { - process.stdout.write('Cleaning up the sandbox\n'); + process.stdout.write('Cleaning up the sandbox...\n'); - for (const child of sandbox.children) { - if (!child.killed) { - process.stdout.write(`Killing child process ${child.pid}\n`); - child.kill('SIGKILL'); - } - } - - // wait for processes to be killed - await wait(); + await killChildProcesses(); process.stdout.write(`Removing sandbox directory: ${context}\n`); await fs.remove(context); @@ -93,24 +123,26 @@ async function createSandbox(): Promise { const realPath = join(context, path); const dirPath = dirname(realPath); - if (!written.includes(path) && !(await fs.pathExists(realPath))) { - written.push(path); + if (!createdFiles.includes(path) && !(await fs.pathExists(realPath))) { + createdFiles.push(path); } - if (!(await fs.pathExists(dirPath))) { - await fs.mkdirp(dirPath); - } + await retry(async () => { + if (!(await fs.pathExists(dirPath))) { + await fs.mkdirp(dirPath); + } + }); // wait to avoid race conditions - await new Promise((resolve) => setTimeout(resolve, 100)); + await wait(); - return fs.writeFile(realPath, content); + return retry(() => fs.writeFile(realPath, content)); }, read: (path: string) => { process.stdout.write(`Reading file ${path}...\n`); const realPath = join(context, path); - return fs.readFile(realPath, 'utf-8'); + return retry(() => fs.readFile(realPath, 'utf-8')); }, exists: (path: string) => { const realPath = join(context, path); @@ -124,14 +156,14 @@ async function createSandbox(): Promise { // wait for fs events to be propagated await wait(); - return fs.remove(realPath); + return retry(() => fs.remove(realPath)); }, patch: async (path: string, search: string, replacement: string) => { process.stdout.write( `Patching file ${path} - replacing "${search}" with "${replacement}"...\n` ); const realPath = join(context, path); - const content = await fs.readFile(realPath, 'utf-8'); + const content = await retry(() => fs.readFile(realPath, 'utf-8')); if (!content.includes(search)) { throw new Error(`Cannot find "${search}" in the ${path}. The file content:\n${content}.`); @@ -140,13 +172,13 @@ async function createSandbox(): Promise { // wait for fs events to be propagated await wait(); - return fs.writeFile(realPath, content.replace(search, replacement)); + return retry(() => fs.writeFile(realPath, content.replace(search, replacement))); }, exec: (command: string, env = {}) => new Promise((resolve, reject) => { process.stdout.write(`Executing "${command}" command...\n`); - const child = exec( + const childProcess = exec( command, { cwd: context, @@ -161,20 +193,23 @@ async function createSandbox(): Promise { } else { resolve(output); } + childProcesses = childProcesses.filter( + (aChildProcess) => aChildProcess !== childProcess + ); } ); - child.stdout.on('data', (data) => process.stdout.write(stripAnsi(data.toString()))); - child.stderr.on('data', (data) => process.stdout.write(stripAnsi(data.toString()))); + childProcess.stdout.on('data', (data) => process.stdout.write(stripAnsi(data.toString()))); + childProcess.stderr.on('data', (data) => process.stdout.write(stripAnsi(data.toString()))); - sandbox.children.push(child); + childProcesses.push(childProcess); }), spawn: (command: string, env = {}) => { process.stdout.write(`Spawning "${command}" command...\n`); const [spawnCommand, ...args] = command.split(' '); - const child = spawn(spawnCommand, args, { + const childProcess = spawn(spawnCommand, args, { cwd: context, env: { ...process.env, @@ -182,12 +217,15 @@ async function createSandbox(): Promise { }, }); - child.stdout.on('data', (data) => process.stdout.write(stripAnsi(data.toString()))); - child.stderr.on('data', (data) => process.stdout.write(stripAnsi(data.toString()))); + childProcess.stdout.on('data', (data) => process.stdout.write(stripAnsi(data.toString()))); + childProcess.stderr.on('data', (data) => process.stdout.write(stripAnsi(data.toString()))); + childProcess.on('exit', () => { + childProcesses = childProcesses.filter((aChildProcess) => aChildProcess !== childProcess); + }); - sandbox.children.push(child); + childProcesses.push(childProcess); - return child; + return childProcess; }, }; diff --git a/test/e2e/sandbox/WebpackDevServerDriver.ts b/test/e2e/sandbox/WebpackDevServerDriver.ts index 6ad33f32..f4cdf2e6 100644 --- a/test/e2e/sandbox/WebpackDevServerDriver.ts +++ b/test/e2e/sandbox/WebpackDevServerDriver.ts @@ -1,7 +1,7 @@ import { ChildProcess } from 'child_process'; import stripAnsi from 'strip-ansi'; import { extractWebpackErrors } from './WebpackErrorsExtractor'; -import { Listener } from './Listener'; +import { createQueuedListener, Listener, QueuedListener } from './Listener'; interface WebpackDevServerDriver { waitForErrors: (timeout?: number) => Promise; @@ -9,59 +9,67 @@ interface WebpackDevServerDriver { close: () => Promise; } -interface ActivatableListener extends Listener { +interface AsyncListener extends Listener { active: boolean; } +interface QueuedAsyncListener extends AsyncListener, QueuedListener { + apply(listener: AsyncListener): void; +} + +function createQueuedAsyncListener(active = false): QueuedAsyncListener { + const queuedListener = createQueuedListener(); + const asyncListener: QueuedAsyncListener = { + ...queuedListener, + apply(listener) { + queuedListener.apply(listener); + asyncListener.active = listener.active; + }, + active, + }; + + return asyncListener; +} function createWebpackDevServerDriver( process: ChildProcess, async: boolean, defaultTimeout = 30000 ): WebpackDevServerDriver { - let errorsListener: ActivatableListener | undefined = undefined; - let noErrorsListener: ActivatableListener | undefined = undefined; + let errorsListener = createQueuedAsyncListener(); + let noErrorsListener = createQueuedAsyncListener(); let errors: string[] = []; function nextIteration() { - noErrorsListener = undefined; - errorsListener = undefined; + errorsListener = createQueuedAsyncListener(); + noErrorsListener = createQueuedAsyncListener(); errors = []; } function activateListeners() { - if (noErrorsListener) { - noErrorsListener.active = true; - } - if (errorsListener) { - errorsListener.active = true; - } + noErrorsListener.active = true; + errorsListener.active = true; } if (process.stdout) { process.stdout.on('data', (data) => { const content = stripAnsi(data.toString()); - if ( - async && - content.includes('No issues found.') && - noErrorsListener && - noErrorsListener.active - ) { + if (async && content.includes('No issues found.')) { noErrorsListener.resolve(); } if (content.includes('Compiled successfully.')) { - if (!async && noErrorsListener) { + if (!async) { noErrorsListener.resolve(); - } else if (async) { + } else { activateListeners(); } } if (content.includes('Failed to compile.') || content.includes('Compiled with warnings.')) { - if (!async && errorsListener) { + if (!async) { errorsListener.resolve(errors); - } else if (async) { + } else { activateListeners(); } } @@ -74,7 +82,7 @@ function createWebpackDevServerDriver( const extracted = extractWebpackErrors(content); errors.push(...extracted); - if (async && errors.length && errorsListener && errorsListener.active) { + if (async && errors.length && errorsListener.active) { errorsListener.resolve(errors); } }); @@ -88,7 +96,7 @@ function createWebpackDevServerDriver( nextIteration(); }, timeout); - errorsListener = { + errorsListener.apply({ resolve: (results) => { clearTimeout(timeoutId); nextIteration(); @@ -100,7 +108,7 @@ function createWebpackDevServerDriver( reject(error); }, active: !async, // for async, we need to activate listener manually - }; + }); }), waitForNoErrors: (timeout = defaultTimeout) => new Promise((resolve, reject) => { @@ -109,7 +117,7 @@ function createWebpackDevServerDriver( nextIteration(); }, timeout); - noErrorsListener = { + noErrorsListener.apply({ resolve: () => { clearTimeout(timeoutId); nextIteration(); @@ -121,7 +129,7 @@ function createWebpackDevServerDriver( reject(error); }, active: !async, // for async, we need to activate listener manually - }; + }); }), close: async () => process.kill(), }; diff --git a/test/setup.ts b/test/setup.ts index 0c52c857..78c5eb60 100644 --- a/test/setup.ts +++ b/test/setup.ts @@ -1,2 +1 @@ -jest.setTimeout(60000); -require('events').EventEmitter.defaultMaxListeners = 100; +jest.setTimeout(300000); From 61788c6eebee70f3ef3b7ca456515eceb906e631 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ole=C5=9B?= Date: Tue, 19 May 2020 11:26:08 +0200 Subject: [PATCH 17/29] test: stabilize e2e tests on windows --- .github/workflows/main.yml | 2 +- package.json | 22 +- src/formatter/WebpackFormatter.ts | 3 +- src/hooks/getChangedFiles.ts | 19 +- src/hooks/getDeletedFiles.ts | 19 +- src/issue/IssueWebpackError.ts | 3 +- .../TypeScriptReporterConfiguration.ts | 11 +- .../extension/vue/TypeScriptVueExtension.ts | 4 +- .../vue/types/vue-template-compiler.d.ts | 44 +- .../reporter/ControlledTypeScriptSystem.ts | 53 +- .../reporter/PassiveFileSystem.ts | 59 +- src/utils/path/normalizeSlash.ts | 9 + test/e2e/.DS_Store | Bin 6148 -> 6148 bytes test/e2e/TypeScriptWatchApi.spec.ts | 3 +- test/e2e/sandbox/Sandbox.ts | 27 +- test/e2e/sandbox/WebpackErrorsExtractor.ts | 2 +- test/unit/formatter/WebpackFormatter.spec.ts | 6 +- yarn.lock | 779 +----------------- 18 files changed, 210 insertions(+), 855 deletions(-) create mode 100644 src/utils/path/normalizeSlash.ts diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 90efed32..b55283f9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -40,7 +40,7 @@ jobs: strategy: matrix: node: [10, 12] # add 14 when we drop support for webpack 4 as fsevents 1 is not compatible with node 14 - os: [ubuntu-latest, macos-latest] # add windows-latest when e2e tests on other platforms will be stable + os: [ubuntu-latest, macos-latest, windows-latest] steps: - uses: actions/checkout@v1 diff --git a/package.json b/package.json index 60ffd529..e758eadf 100644 --- a/package.json +++ b/package.json @@ -31,13 +31,14 @@ "main": "lib/index.js", "types": "lib/index.d.ts", "scripts": { - "build": "rimraf lib && tsc --version && tsc", - "lint": "eslint ./src ./test --ext .ts", + "build": "cross-env rimraf lib && cross-env tsc --version && cross-env tsc", + "lint": "cross-env eslint ./src ./test --ext .ts", "test": "yarn build && yarn test:unit && yarn test:e2e", - "test:unit": "jest unit", - "test:e2e": "yarn pack --filename fork-ts-checker-webpack-plugin.tgz && jest e2e --ci --runInBand --bail --verbose", - "precommit": "lint-staged && yarn build && yarn test:unit", - "commit": "./node_modules/.bin/git-cz" + "test:unit": "cross-env jest unit", + "test:pack": "yarn pack --filename fork-ts-checker-webpack-plugin.tgz", + "test:e2e": "yarn test:pack && cross-env jest e2e --ci --runInBand --bail --verbose", + "precommit": "cross-env lint-staged && yarn build && yarn test:unit", + "commit": "cross-env git-cz" }, "husky": { "hooks": { @@ -70,7 +71,6 @@ }, "devDependencies": { "@commitlint/config-conventional": "^8.3.4", - "@mdx-js/mdx": "^1.5.8", "@types/babel__code-frame": "^7.0.1", "@types/cross-spawn": "^6.0.2", "@types/eslint": "^6.8.0", @@ -86,6 +86,7 @@ "@typescript-eslint/eslint-plugin": "^2.27.0", "@typescript-eslint/parser": "^2.27.0", "commitlint": "^8.3.5", + "cross-env": "^7.0.2", "cross-spawn": "^7.0.2", "eslint": "^6.8.0", "eslint-config-prettier": "^6.10.1", @@ -96,18 +97,13 @@ "jest": "^25.3.0", "lint-staged": "^10.1.3", "mock-fs": "^4.11.0", - "nativescript-vue-template-compiler": "^2.5.1", "prettier": "^2.0.4", "rimraf": "^3.0.2", "strip-ansi": "^6.0.0", + "tree-kill": "^1.2.2", "ts-jest": "^25.3.1", - "ts-loader": "^6.2.2", "typescript": "^3.8.3", "unixify": "^1.0.0", - "vue": "^2.6.11", - "vue-class-component": "^7.2.3", - "vue-loader": "^15.9.1", - "vue-template-compiler": "^2.6.11", "webpack": "^4.42.1" }, "engines": { diff --git a/src/formatter/WebpackFormatter.ts b/src/formatter/WebpackFormatter.ts index 9ab6b8c8..21244318 100644 --- a/src/formatter/WebpackFormatter.ts +++ b/src/formatter/WebpackFormatter.ts @@ -3,11 +3,12 @@ import chalk from 'chalk'; import { relative } from 'path'; import { Formatter } from './Formatter'; import { formatIssueLocation } from '../issue'; +import normalizeSlash from '../utils/path/normalizeSlash'; function createWebpackFormatter(formatter: Formatter, context: string): Formatter { return function webpackFormatter(issue) { const severity = issue.severity.toUpperCase(); - const file = issue.file ? relative(context, issue.file) : undefined; + const file = issue.file ? normalizeSlash(relative(context, issue.file)) : undefined; const location = issue.location ? formatIssueLocation(issue.location) : undefined; const color = issue.severity === 'warning' ? chalk.yellow : chalk.red; const header = [severity, 'in', file].concat(location ? [location] : []).join(' '); diff --git a/src/hooks/getChangedFiles.ts b/src/hooks/getChangedFiles.ts index 07115e0c..669a08ea 100644 --- a/src/hooks/getChangedFiles.ts +++ b/src/hooks/getChangedFiles.ts @@ -1,16 +1,31 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import webpack from 'webpack'; +import path from 'path'; import { getWatcher } from './getWatcher'; function getChangedFiles(compiler: webpack.Compiler): string[] { + let changedFiles: string[] = []; + if ((compiler as any).modifiedFiles) { // webpack 5+ - return Array.from((compiler as any).modifiedFiles); + changedFiles = Array.from((compiler as any).modifiedFiles); } else { const watcher = getWatcher(compiler); // webpack 4 - return Object.keys((watcher && watcher.mtimes) || {}); + changedFiles = Object.keys((watcher && watcher.mtimes) || {}); } + + return ( + changedFiles + // normalize paths + .map((changedFile) => path.normalize(changedFile)) + // check if path is inside the context to filer-out some trash from fs + .filter( + (changedFile) => + !compiler.options.context || + changedFile.startsWith(path.normalize(compiler.options.context)) + ) + ); } export { getChangedFiles }; diff --git a/src/hooks/getDeletedFiles.ts b/src/hooks/getDeletedFiles.ts index b202a1a4..8e5dd74c 100644 --- a/src/hooks/getDeletedFiles.ts +++ b/src/hooks/getDeletedFiles.ts @@ -1,18 +1,33 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import webpack from 'webpack'; +import path from 'path'; import { ForkTsCheckerWebpackPluginState } from '../ForkTsCheckerWebpackPluginState'; function getDeletedFiles( compiler: webpack.Compiler, state: ForkTsCheckerWebpackPluginState ): string[] { + let deletedFiles: string[] = []; + if ((compiler as any).removedFiles) { // webpack 5+ - return Array.from((compiler as any).removedFiles || []); + deletedFiles = Array.from((compiler as any).removedFiles || []); } else { // webpack 4 - return [...state.removedFiles]; + deletedFiles = [...state.removedFiles]; } + + return ( + deletedFiles + // normalize paths + .map((changedFile) => path.normalize(changedFile)) + // check if path is inside the context to filer-out some trash from fs + .filter( + (changedFile) => + !compiler.options.context || + changedFile.startsWith(path.normalize(compiler.options.context)) + ) + ); } export { getDeletedFiles }; diff --git a/src/issue/IssueWebpackError.ts b/src/issue/IssueWebpackError.ts index 24d680ac..98e61b04 100644 --- a/src/issue/IssueWebpackError.ts +++ b/src/issue/IssueWebpackError.ts @@ -1,6 +1,7 @@ import { relative } from 'path'; import { Issue } from './Issue'; import { formatIssueLocation } from './IssueLocation'; +import normalizeSlash from '../utils/path/normalizeSlash'; class IssueWebpackError extends Error { readonly hideStack = true; @@ -13,7 +14,7 @@ class IssueWebpackError extends Error { // should be a NormalModule instance. // to avoid such a dependency, we do a workaround - error.file will contain formatted location instead if (issue.file) { - const parts = [relative(context, issue.file)]; + const parts = [normalizeSlash(relative(context, issue.file))]; if (issue.location) { parts.push(formatIssueLocation(issue.location)); } diff --git a/src/typescript-reporter/TypeScriptReporterConfiguration.ts b/src/typescript-reporter/TypeScriptReporterConfiguration.ts index d16128f2..dbcb5eea 100644 --- a/src/typescript-reporter/TypeScriptReporterConfiguration.ts +++ b/src/typescript-reporter/TypeScriptReporterConfiguration.ts @@ -11,6 +11,7 @@ import { createTypeScriptPnpExtensionConfiguration, TypeScriptPnpExtensionConfiguration, } from './extension/pnp/TypeScriptPnpExtensionConfiguration'; +import normalizeSlash from '../utils/path/normalizeSlash'; interface TypeScriptReporterConfiguration { enabled: boolean; @@ -53,10 +54,12 @@ function createTypeScriptReporterConfiguration( }, }; - // ensure that `typescript.tsconfig` is an absolute path - configuration.tsconfig = path.isAbsolute(configuration.tsconfig) - ? configuration.tsconfig - : path.resolve(compiler.options.context || process.cwd(), configuration.tsconfig); + // ensure that `typescript.tsconfig` is an absolute path with normalized slash + configuration.tsconfig = normalizeSlash( + path.isAbsolute(configuration.tsconfig) + ? configuration.tsconfig + : path.resolve(compiler.options.context || process.cwd(), configuration.tsconfig) + ); return configuration; } diff --git a/src/typescript-reporter/extension/vue/TypeScriptVueExtension.ts b/src/typescript-reporter/extension/vue/TypeScriptVueExtension.ts index 2151c3c5..bec13896 100644 --- a/src/typescript-reporter/extension/vue/TypeScriptVueExtension.ts +++ b/src/typescript-reporter/extension/vue/TypeScriptVueExtension.ts @@ -2,15 +2,15 @@ import { createTypeScriptEmbeddedExtension, TypeScriptEmbeddedSource, } from '../TypeScriptEmbeddedExtension'; -import * as vueCompiler from 'vue-template-compiler'; import fs from 'fs-extra'; import { TypeScriptExtension } from '../TypeScriptExtension'; import { TypeScriptVueExtensionConfiguration } from './TypeScriptVueExtensionConfiguration'; +import { VueTemplateCompiler } from './types/vue-template-compiler'; function createTypeScriptVueExtension( configuration: TypeScriptVueExtensionConfiguration ): TypeScriptExtension { - function loadVueCompiler(): typeof vueCompiler { + function loadVueCompiler(): VueTemplateCompiler { return require(configuration.compiler); } diff --git a/src/typescript-reporter/extension/vue/types/vue-template-compiler.d.ts b/src/typescript-reporter/extension/vue/types/vue-template-compiler.d.ts index 92d1ac9d..86c53111 100644 --- a/src/typescript-reporter/extension/vue/types/vue-template-compiler.d.ts +++ b/src/typescript-reporter/extension/vue/types/vue-template-compiler.d.ts @@ -2,29 +2,29 @@ * This declaration is copied from https://github.com/vuejs/vue/pull/7918 * which may included vue-template-compiler v2.6.0. */ -declare module 'vue-template-compiler' { - interface SFCParserOptions { - pad?: true | 'line' | 'space'; - } +interface SFCParserOptions { + pad?: true | 'line' | 'space'; +} - export interface SFCBlock { - type: string; - content: string; - attrs: Record; - start?: number; - end?: number; - lang?: string; - src?: string; - scoped?: boolean; - module?: string | boolean; - } +export interface SFCBlock { + type: string; + content: string; + attrs: Record; + start?: number; + end?: number; + lang?: string; + src?: string; + scoped?: boolean; + module?: string | boolean; +} - export interface SFCDescriptor { - template: SFCBlock | undefined; - script: SFCBlock | undefined; - styles: SFCBlock[]; - customBlocks: SFCBlock[]; - } +export interface SFCDescriptor { + template: SFCBlock | undefined; + script: SFCBlock | undefined; + styles: SFCBlock[]; + customBlocks: SFCBlock[]; +} - export function parseComponent(file: string, options?: SFCParserOptions): SFCDescriptor; +export interface VueTemplateCompiler { + parseComponent(file: string, options?: SFCParserOptions): SFCDescriptor; } diff --git a/src/typescript-reporter/reporter/ControlledTypeScriptSystem.ts b/src/typescript-reporter/reporter/ControlledTypeScriptSystem.ts index 2b0da00a..4802491a 100644 --- a/src/typescript-reporter/reporter/ControlledTypeScriptSystem.ts +++ b/src/typescript-reporter/reporter/ControlledTypeScriptSystem.ts @@ -1,6 +1,7 @@ import * as ts from 'typescript'; -import { posix } from 'path'; +import { dirname } from 'path'; import { createPassiveFileSystem } from './PassiveFileSystem'; +import normalizeSlash from '../../utils/path/normalizeSlash'; interface ControlledTypeScriptSystem extends ts.System { // control watcher @@ -49,48 +50,56 @@ function createControlledTypeScriptSystem(): ControlledTypeScriptSystem { path: string, callback: TCallback ) { - const watchers = watchersMap.get(path) || []; + const normalizedPath = fileSystem.normalizePath(path); + + const watchers = watchersMap.get(normalizedPath) || []; const nextWatchers = [...watchers, callback]; - watchersMap.set(path, nextWatchers); + watchersMap.set(normalizedPath, nextWatchers); return { close: () => { - const watchers = watchersMap.get(path) || []; + const watchers = watchersMap.get(normalizedPath) || []; const nextWatchers = watchers.filter((watcher) => watcher !== callback); if (nextWatchers.length > 0) { - watchersMap.set(path, nextWatchers); + watchersMap.set(normalizedPath, nextWatchers); } else { - watchersMap.delete(path); + watchersMap.delete(normalizedPath); } }, }; } const invokeFileWatchers = (path: string, event: ts.FileWatcherEventKind) => { - const fileWatchers = fileWatchersMap.get(path); + const normalizedPath = fileSystem.normalizePath(path); + + const fileWatchers = fileWatchersMap.get(normalizedPath); if (fileWatchers) { - fileWatchers.forEach((fileWatcher) => fileWatcher(path, event)); + // typescript expects normalized paths with posix forward slash + fileWatchers.forEach((fileWatcher) => fileWatcher(normalizeSlash(normalizedPath), event)); } }; const invokeDirectoryWatchers = (path: string) => { - let directory = posix.dirname(path); + const normalizedPath = fileSystem.normalizePath(path); + let directory = dirname(normalizedPath); const directoryWatchers = directoryWatchersMap.get(directory); if (directoryWatchers) { - directoryWatchers.forEach((directoryWatcher) => directoryWatcher(path)); + directoryWatchers.forEach((directoryWatcher) => + directoryWatcher(normalizeSlash(normalizedPath)) + ); } - while (directory !== posix.dirname(directory)) { + while (directory !== dirname(directory)) { const recursiveDirectoryWatchers = recursiveDirectoryWatchersMap.get(directory); if (recursiveDirectoryWatchers) { recursiveDirectoryWatchers.forEach((recursiveDirectoryWatcher) => - recursiveDirectoryWatcher(path) + recursiveDirectoryWatcher(normalizeSlash(normalizedPath)) ); } - directory = posix.dirname(directory); + directory = dirname(directory); } }; @@ -128,7 +137,7 @@ function createControlledTypeScriptSystem(): ControlledTypeScriptSystem { createDirectory(path: string): void { fileSystem.createDir(path); - invokeDirectoryWatchers(fileSystem.normalizePath(path)); + invokeDirectoryWatchers(path); }, getDirectories(path: string): string[] { const dirents = fileSystem.readDir(path); @@ -145,11 +154,11 @@ function createControlledTypeScriptSystem(): ControlledTypeScriptSystem { setModifiedTime(path: string, date: Date): void { fileSystem.updateTimes(path, date, date); - invokeDirectoryWatchers(fileSystem.normalizePath(path)); - invokeFileWatchers(fileSystem.normalizePath(path), ts.FileWatcherEventKind.Changed); + invokeDirectoryWatchers(path); + invokeFileWatchers(path, ts.FileWatcherEventKind.Changed); }, watchFile(path: string, callback: ts.FileWatcherCallback): ts.FileWatcher { - return createWatcher(fileWatchersMap, fileSystem.normalizePath(path), callback); + return createWatcher(fileWatchersMap, path, callback); }, watchDirectory( path: string, @@ -158,7 +167,7 @@ function createControlledTypeScriptSystem(): ControlledTypeScriptSystem { ): ts.FileWatcher { return createWatcher( recursive ? recursiveDirectoryWatchersMap : directoryWatchersMap, - fileSystem.normalizePath(path), + path, callback ); }, @@ -187,18 +196,18 @@ function createControlledTypeScriptSystem(): ControlledTypeScriptSystem { invokeDirectoryWatchers(normalizedPath); if (deletedFiles.get(normalizedPath)) { - invokeFileWatchers(normalizedPath, ts.FileWatcherEventKind.Created); + invokeFileWatchers(path, ts.FileWatcherEventKind.Created); deletedFiles.set(normalizedPath, false); } else { - invokeFileWatchers(normalizedPath, ts.FileWatcherEventKind.Changed); + invokeFileWatchers(path, ts.FileWatcherEventKind.Changed); } }, invokeFileDeleted(path: string) { const normalizedPath = fileSystem.normalizePath(path); if (!deletedFiles.get(normalizedPath)) { - invokeDirectoryWatchers(normalizedPath); - invokeFileWatchers(normalizedPath, ts.FileWatcherEventKind.Deleted); + invokeDirectoryWatchers(path); + invokeFileWatchers(path, ts.FileWatcherEventKind.Deleted); deletedFiles.set(normalizedPath, true); } diff --git a/src/typescript-reporter/reporter/PassiveFileSystem.ts b/src/typescript-reporter/reporter/PassiveFileSystem.ts index fae2b5c7..a46e1338 100644 --- a/src/typescript-reporter/reporter/PassiveFileSystem.ts +++ b/src/typescript-reporter/reporter/PassiveFileSystem.ts @@ -1,4 +1,4 @@ -import { posix } from 'path'; +import { dirname, basename, join, normalize } from 'path'; import fs, { Stats, Dirent } from 'fs-extra'; import { fs as mem } from 'memfs'; @@ -22,8 +22,6 @@ interface PassiveFileSystem { } function createPassiveFileSystem(caseSensitive = false): PassiveFileSystem { - const { dirname, basename, join, normalize } = posix; - // read cache const fsExistsCache = new Map(); const fsReadStatsCache = new Map(); @@ -37,11 +35,13 @@ function createPassiveFileSystem(caseSensitive = false): PassiveFileSystem { // read methods function fsExists(path: string): boolean { - if (!fsExistsCache.has(path)) { - fsExistsCache.set(path, fs.existsSync(path)); + const normalizedPath = normalizePath(path); + + if (!fsExistsCache.has(normalizedPath)) { + fsExistsCache.set(normalizedPath, fs.existsSync(normalizedPath)); } - return !!fsExistsCache.get(path); + return !!fsExistsCache.get(normalizedPath); } function memExists(path: string): boolean { @@ -49,13 +49,15 @@ function createPassiveFileSystem(caseSensitive = false): PassiveFileSystem { } function fsReadStats(path: string): Stats | undefined { - if (!fsReadStatsCache.has(path)) { - if (fsExists(path)) { - fsReadStatsCache.set(path, fs.statSync(path)); + const normalizedPath = normalizePath(path); + + if (!fsReadStatsCache.has(normalizedPath)) { + if (fsExists(normalizedPath)) { + fsReadStatsCache.set(normalizedPath, fs.statSync(normalizedPath)); } } - return fsReadStatsCache.get(path); + return fsReadStatsCache.get(normalizedPath); } function memReadStats(path: string): Stats | undefined { @@ -63,15 +65,20 @@ function createPassiveFileSystem(caseSensitive = false): PassiveFileSystem { } function fsReadFile(path: string, encoding?: string): string | undefined { - if (!fsReadFileCache.has(path)) { - if (fsExists(path)) { - fsReadFileCache.set(path, fs.readFileSync(path, { encoding }).toString()); + const normalizedPath = normalizePath(path); + + if (!fsReadFileCache.has(normalizedPath)) { + if (fsExists(normalizedPath)) { + fsReadFileCache.set( + normalizedPath, + fs.readFileSync(normalizedPath, { encoding }).toString() + ); } else { - fsReadFileCache.set(path, undefined); + fsReadFileCache.set(normalizedPath, undefined); } } - return fsReadFileCache.get(path); + return fsReadFileCache.get(normalizedPath); } function memReadFile(path: string, encoding?: string): string | undefined { @@ -83,15 +90,17 @@ function createPassiveFileSystem(caseSensitive = false): PassiveFileSystem { } function fsReadDir(path: string): Dirent[] { - if (!fsReadDirCache.has(path)) { - if (fsExists(path)) { - fsReadDirCache.set(path, fs.readdirSync(path, { withFileTypes: true })); + const normalizedPath = normalizePath(path); + + if (!fsReadDirCache.has(normalizedPath)) { + if (fsExists(normalizedPath)) { + fsReadDirCache.set(normalizedPath, fs.readdirSync(normalizedPath, { withFileTypes: true })); } else { - fsReadDirCache.set(path, []); + fsReadDirCache.set(normalizedPath, []); } } - return fsReadDirCache.get(path) || []; + return fsReadDirCache.get(normalizedPath) || []; } function memReadDir(path: string): Dirent[] { @@ -145,13 +154,15 @@ function createPassiveFileSystem(caseSensitive = false): PassiveFileSystem { } function getRealPath(path: string) { - if (!fsRealPathCache.has(path)) { - let base = path; + const normalizedPath = normalizePath(path); + + if (!fsRealPathCache.has(normalizedPath)) { + let base = normalizedPath; let nested = ''; while (base !== dirname(base)) { if (fsExists(base)) { - fsRealPathCache.set(path, join(fs.realpathSync(base), nested)); + fsRealPathCache.set(normalizedPath, normalizePath(join(fs.realpathSync(base), nested))); break; } @@ -160,7 +171,7 @@ function createPassiveFileSystem(caseSensitive = false): PassiveFileSystem { } } - return fsRealPathCache.get(path) || path; + return fsRealPathCache.get(normalizedPath) || normalizedPath; } function createDir(path: string) { diff --git a/src/utils/path/normalizeSlash.ts b/src/utils/path/normalizeSlash.ts new file mode 100644 index 00000000..ea96c69e --- /dev/null +++ b/src/utils/path/normalizeSlash.ts @@ -0,0 +1,9 @@ +/** + * Replaces backslashes with one forward slash + * @param path + */ +function normalizeSlash(path: string): string { + return path.replace(/\\+/g, '/'); +} + +export default normalizeSlash; diff --git a/test/e2e/.DS_Store b/test/e2e/.DS_Store index c339219d14259f097e2ed0ae090a03ea170cf858..a4332c632dd894007ff51b754ebb42fff3c7edb7 100644 GIT binary patch delta 21 ccmZoMXffCz&B|e9Xs)ARW@5Zqnf0L%06sSbk^lez delta 21 ccmZoMXffCz&B|eHXr`lJYH7Avnf0L%06t~~nE(I) diff --git a/test/e2e/TypeScriptWatchApi.spec.ts b/test/e2e/TypeScriptWatchApi.spec.ts index 1a0fdd0c..fc9b34ae 100644 --- a/test/e2e/TypeScriptWatchApi.spec.ts +++ b/test/e2e/TypeScriptWatchApi.spec.ts @@ -189,7 +189,8 @@ describe('TypeScript Watch API', () => { errors = await driver.waitForErrors(); expect(errors).toEqual([ [ - "ERROR in src/model/User.ts 11:16-25\nTS2339: Property 'firstName' does not exist on type 'User'.", + 'ERROR in src/model/User.ts 11:16-25', + "TS2339: Property 'firstName' does not exist on type 'User'.", ' 9 | ', ' 10 | function getUserName(user: User): string {', ' > 11 | return [user.firstName, user.lastName]', diff --git a/test/e2e/sandbox/Sandbox.ts b/test/e2e/sandbox/Sandbox.ts index 9931e308..88cbf666 100644 --- a/test/e2e/sandbox/Sandbox.ts +++ b/test/e2e/sandbox/Sandbox.ts @@ -5,6 +5,7 @@ import { exec, ChildProcess } from 'child_process'; import spawn from 'cross-spawn'; import { Fixture } from './Fixture'; import stripAnsi from 'strip-ansi'; +import kill from 'tree-kill'; interface Sandbox { context: string; @@ -68,8 +69,20 @@ async function createSandbox(): Promise { async function killChildProcesses() { for (const childProcess of childProcesses) { if (!childProcess.killed) { - process.stdout.write(`Killing child process ${childProcess.pid}\n`); - childProcess.kill('SIGKILL'); + process.stdout.write(`Killing child process ${childProcess.pid}...\n`); + await retry( + () => + new Promise((resolve, reject) => + kill(childProcess.pid, 'SIGKILL', (error) => { + if (error) { + reject(error); + } else { + resolve(); + } + }) + ) + ); + process.stdout.write(`Child process ${childProcess.pid} killed.\n`); } } childProcesses = []; @@ -77,6 +90,10 @@ async function createSandbox(): Promise { await wait(); } + function normalizeEol(content: string): string { + return content.split(/\r\n?|\n/).join('\n'); + } + process.stdout.write(`Sandbox directory: ${context}\n`); const sandbox: Sandbox = { @@ -136,13 +153,13 @@ async function createSandbox(): Promise { // wait to avoid race conditions await wait(); - return retry(() => fs.writeFile(realPath, content)); + return retry(() => fs.writeFile(realPath, normalizeEol(content))); }, read: (path: string) => { process.stdout.write(`Reading file ${path}...\n`); const realPath = join(context, path); - return retry(() => fs.readFile(realPath, 'utf-8')); + return retry(() => fs.readFile(realPath, 'utf-8').then(normalizeEol)); }, exists: (path: string) => { const realPath = join(context, path); @@ -163,7 +180,7 @@ async function createSandbox(): Promise { `Patching file ${path} - replacing "${search}" with "${replacement}"...\n` ); const realPath = join(context, path); - const content = await retry(() => fs.readFile(realPath, 'utf-8')); + const content = await retry(() => fs.readFile(realPath, 'utf-8').then(normalizeEol)); if (!content.includes(search)) { throw new Error(`Cannot find "${search}" in the ${path}. The file content:\n${content}.`); diff --git a/test/e2e/sandbox/WebpackErrorsExtractor.ts b/test/e2e/sandbox/WebpackErrorsExtractor.ts index 4140f3c8..e972544c 100644 --- a/test/e2e/sandbox/WebpackErrorsExtractor.ts +++ b/test/e2e/sandbox/WebpackErrorsExtractor.ts @@ -3,7 +3,7 @@ function isLineRelatedToTsLoader(line: string) { } function extractWebpackErrors(content: string): string[] { - const lines = content.split('\n'); + const lines = content.split(/\r\n?|\n/); const errors: string[] = []; let currentError: string | undefined = undefined; diff --git a/test/unit/formatter/WebpackFormatter.spec.ts b/test/unit/formatter/WebpackFormatter.spec.ts index 20718426..2c8a801a 100644 --- a/test/unit/formatter/WebpackFormatter.spec.ts +++ b/test/unit/formatter/WebpackFormatter.spec.ts @@ -1,5 +1,5 @@ import os from 'os'; -import { join, sep } from 'path'; +import { join } from 'path'; import { Issue } from 'lib/issue'; import { createBasicFormatter, createWebpackFormatter, Formatter } from 'lib/formatter'; @@ -38,7 +38,7 @@ describe('formatter/WebpackFormatter', () => { }); it('formats issue file', () => { - expect(formatter(issue)).toContain(`some${sep}file.ts`); + expect(formatter(issue)).toContain(`some/file.ts`); }); it('formats location', () => { @@ -53,7 +53,7 @@ describe('formatter/WebpackFormatter', () => { it('formats issue header like webpack', () => { expect(formatter(issue)).toEqual( - [`ERROR in some${sep}file.ts 1:7-16`, 'TS123: Some issue content', ''].join(os.EOL) + [`ERROR in some/file.ts 1:7-16`, 'TS123: Some issue content', ''].join(os.EOL) ); }); }); diff --git a/yarn.lock b/yarn.lock index 9c8e32ac..5dcd2c1d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15,27 +15,6 @@ dependencies: "@babel/highlight" "^7.8.3" -"@babel/core@7.8.4": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.8.4.tgz#d496799e5c12195b3602d0fddd77294e3e38e80e" - integrity sha512-0LiLrB2PwrVI+a2/IEskBopDYSd8BCb3rOvH7D5tzoWd696TBEduBvuLVm4Nx6rltrLZqvI3MCalB2K2aVzQjA== - dependencies: - "@babel/code-frame" "^7.8.3" - "@babel/generator" "^7.8.4" - "@babel/helpers" "^7.8.4" - "@babel/parser" "^7.8.4" - "@babel/template" "^7.8.3" - "@babel/traverse" "^7.8.4" - "@babel/types" "^7.8.3" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.1" - json5 "^2.1.0" - lodash "^4.17.13" - resolve "^1.3.2" - semver "^5.4.1" - source-map "^0.5.0" - "@babel/core@^7.1.0": version "7.4.4" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.4.4.tgz#84055750b05fcd50f9915a826b44fa347a825250" @@ -89,16 +68,6 @@ source-map "^0.5.0" trim-right "^1.0.1" -"@babel/generator@^7.8.4": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.8.4.tgz#35bbc74486956fe4251829f9f6c48330e8d0985e" - integrity sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA== - dependencies: - "@babel/types" "^7.8.3" - jsesc "^2.5.1" - lodash "^4.17.13" - source-map "^0.5.0" - "@babel/generator@^7.9.0", "@babel/generator@^7.9.5": version "7.9.5" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.9.5.tgz#27f0917741acc41e6eaaced6d68f96c3fa9afaf9" @@ -118,15 +87,6 @@ "@babel/template" "^7.1.0" "@babel/types" "^7.0.0" -"@babel/helper-function-name@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz#eeeb665a01b1f11068e9fb86ad56a1cb1a824cca" - integrity sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA== - dependencies: - "@babel/helper-get-function-arity" "^7.8.3" - "@babel/template" "^7.8.3" - "@babel/types" "^7.8.3" - "@babel/helper-function-name@^7.9.5": version "7.9.5" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz#2b53820d35275120e1874a82e5aabe1376920a5c" @@ -184,16 +144,16 @@ dependencies: "@babel/types" "^7.8.3" -"@babel/helper-plugin-utils@7.8.3", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz#9ea293be19babc0f52ff8ca88b34c3611b208670" - integrity sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ== - "@babel/helper-plugin-utils@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz#bbb3fbee98661c569034237cc03967ba99b4f250" integrity sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA== +"@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz#9ea293be19babc0f52ff8ca88b34c3611b208670" + integrity sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ== + "@babel/helper-replace-supers@^7.8.6": version "7.8.6" resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.8.6.tgz#5ada744fd5ad73203bf1d67459a27dcba67effc8" @@ -240,7 +200,7 @@ "@babel/traverse" "^7.4.4" "@babel/types" "^7.4.4" -"@babel/helpers@^7.8.4", "@babel/helpers@^7.9.0": +"@babel/helpers@^7.9.0": version "7.9.2" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.9.2.tgz#b42a81a811f1e7313b88cba8adc66b3d9ae6c09f" integrity sha512-JwLvzlXVPjO8eU9c/wF9/zOIN7X6h8DYf7mG4CiFRZRvZNKEF5dQ3H3V+ASkHoIB3mWhatgl5ONhyqHRI6MppA== @@ -276,19 +236,11 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.9.4.tgz#68a35e6b0319bbc014465be43828300113f2f2e8" integrity sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA== -"@babel/parser@^7.8.3", "@babel/parser@^7.8.4": +"@babel/parser@^7.8.3": version "7.8.4" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.8.4.tgz#d1dbe64691d60358a974295fa53da074dd2ce8e8" integrity sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw== -"@babel/plugin-proposal-object-rest-spread@7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.8.3.tgz#eb5ae366118ddca67bed583b53d7554cad9951bb" - integrity sha512-8qvuPwU/xxUCt78HocNlv0mXXo0wdh9VT1R04WU8HGOfaOob26pF+9P5/lYjN/q7DHOX1bvX60hnhOvuQUJdbA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/plugin-syntax-object-rest-spread" "^7.8.0" - "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" @@ -317,13 +269,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-jsx@7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.8.3.tgz#521b06c83c40480f1e58b4fd33b92eceb1d6ea94" - integrity sha512-WxdW9xyLgBdefoo0Ynn3MRSkhe5tFVxxKNVdnZSh318WrG2e2jH+E9wd/++JsqcLJZPfz87njQJ8j2Upjm0M0A== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/plugin-syntax-logical-assignment-operators@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.8.3.tgz#3995d7d7ffff432f6ddc742b47e730c054599897" @@ -345,7 +290,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-syntax-object-rest-spread@7.8.3", "@babel/plugin-syntax-object-rest-spread@^7.8.0", "@babel/plugin-syntax-object-rest-spread@^7.8.3": +"@babel/plugin-syntax-object-rest-spread@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== @@ -430,21 +375,6 @@ globals "^11.1.0" lodash "^4.17.13" -"@babel/traverse@^7.8.4": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.8.4.tgz#f0845822365f9d5b0e312ed3959d3f827f869e3c" - integrity sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg== - dependencies: - "@babel/code-frame" "^7.8.3" - "@babel/generator" "^7.8.4" - "@babel/helper-function-name" "^7.8.3" - "@babel/helper-split-export-declaration" "^7.8.3" - "@babel/parser" "^7.8.4" - "@babel/types" "^7.8.3" - debug "^4.1.0" - globals "^11.1.0" - lodash "^4.17.13" - "@babel/types@^7.0.0", "@babel/types@^7.3.0", "@babel/types@^7.4.4": version "7.4.4" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.4.4.tgz#8db9e9a629bb7c29370009b4b779ed93fe57d5f0" @@ -795,35 +725,6 @@ mkdirp "^0.5.1" rimraf "^2.5.2" -"@mdx-js/mdx@^1.5.8": - version "1.5.8" - resolved "https://registry.yarnpkg.com/@mdx-js/mdx/-/mdx-1.5.8.tgz#40740eaf0b0007b461cee8df13a7ae5a1af8064a" - integrity sha512-OzanPTN0p9GZOEVeEuEa8QsjxxGyfFOOnI/+V1oC1su9UIN4KUg1k4n/hWTZC+VZhdW1Lfj6+Ho8nIs6L+pbDA== - dependencies: - "@babel/core" "7.8.4" - "@babel/plugin-syntax-jsx" "7.8.3" - "@babel/plugin-syntax-object-rest-spread" "7.8.3" - "@mdx-js/util" "^1.5.8" - babel-plugin-apply-mdx-type-prop "^1.5.8" - babel-plugin-extract-import-names "^1.5.8" - camelcase-css "2.0.1" - detab "2.0.3" - hast-util-raw "5.0.2" - lodash.uniq "4.5.0" - mdast-util-to-hast "7.0.0" - remark-mdx "^1.5.8" - remark-parse "7.0.2" - remark-squeeze-paragraphs "3.0.4" - style-to-object "0.3.0" - unified "8.4.2" - unist-builder "2.0.3" - unist-util-visit "2.0.2" - -"@mdx-js/util@^1.5.8": - version "1.5.8" - resolved "https://registry.yarnpkg.com/@mdx-js/util/-/util-1.5.8.tgz#cbadda0378af899c17ce1aa69c677015cab28448" - integrity sha512-a7Gjjw8bfBSertA/pTWBA/9WKEhgaSxvQE2NTSUzaknrzGFOhs4alZSHh3RHmSFdSWv5pUuzAgsWseMLhWEVkQ== - "@samverschueren/stream-to-observable@^0.3.0": version "0.3.0" resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f" @@ -1037,11 +938,6 @@ dependencies: source-map "^0.6.1" -"@types/unist@^2.0.0", "@types/unist@^2.0.2": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e" - integrity sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ== - "@types/webpack-sources@*": version "0.1.7" resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-0.1.7.tgz#0a330a9456113410c74a5d64180af0cbca007141" @@ -1118,22 +1014,6 @@ semver "^6.3.0" tsutils "^3.17.1" -"@vue/component-compiler-utils@^3.1.0": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@vue/component-compiler-utils/-/component-compiler-utils-3.1.2.tgz#8213a5ff3202f9f2137fe55370f9e8b9656081c3" - integrity sha512-QLq9z8m79mCinpaEeSURhnNCN6djxpHw0lpP/bodMlt5kALfONpryMthvnrQOlTcIKoF+VoPi+lPHUYeDFPXug== - dependencies: - consolidate "^0.15.1" - hash-sum "^1.0.2" - lru-cache "^4.1.2" - merge-source-map "^1.1.0" - postcss "^7.0.14" - postcss-selector-parser "^6.0.2" - source-map "~0.6.1" - vue-template-es2015-compiler "^1.9.0" - optionalDependencies: - prettier "^1.18.2" - "@webassemblyjs/ast@1.9.0": version "1.9.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" @@ -1589,21 +1469,6 @@ babel-jest@^25.3.0: chalk "^3.0.0" slash "^3.0.0" -babel-plugin-apply-mdx-type-prop@^1.5.8: - version "1.5.8" - resolved "https://registry.yarnpkg.com/babel-plugin-apply-mdx-type-prop/-/babel-plugin-apply-mdx-type-prop-1.5.8.tgz#f5ff6d9d7a7fcde0e5f5bd02d3d3cd10e5cca5bf" - integrity sha512-xYp5F9mAnZdDRFSd1vF3XQ0GQUbIulCpnuht2jCmK30GAHL8szVL7TgzwhEGamQ6yJmP/gEyYNM9OR5D2n26eA== - dependencies: - "@babel/helper-plugin-utils" "7.8.3" - "@mdx-js/util" "^1.5.8" - -babel-plugin-extract-import-names@^1.5.8: - version "1.5.8" - resolved "https://registry.yarnpkg.com/babel-plugin-extract-import-names/-/babel-plugin-extract-import-names-1.5.8.tgz#418057261346451d689dff5036168567036b8cf6" - integrity sha512-LcLfP8ZRBZMdMAXHLugyvvd5PY0gMmLMWFogWAUsG32X6TYW2Eavx+il2bw73KDbW+UdCC1bAJ3NuU25T1MI3g== - dependencies: - "@babel/helper-plugin-utils" "7.8.3" - babel-plugin-istanbul@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz#e159ccdc9af95e0b570c75b4573b7c34d671d765" @@ -1663,11 +1528,6 @@ babel-runtime@^6.23.0, babel-runtime@^6.26.0: core-js "^2.4.0" regenerator-runtime "^0.11.0" -bail@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.5.tgz#b6fa133404a392cbc1f8c4bf63f5953351e7a776" - integrity sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ== - balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" @@ -1707,10 +1567,6 @@ binary-extensions@^1.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== -bluebird@^3.1.1: - version "3.5.3" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.3.tgz#7d01c6f9616c9a51ab0f8c549a79dfe6ec33efa7" - bluebird@^3.5.5: version "3.7.2" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" @@ -1925,11 +1781,6 @@ callsites@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.0.0.tgz#fb7eb569b72ad7a45812f93fd9430a3e410b3dd3" -camelcase-css@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5" - integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== - camelcase-keys@^4.0.0: version "4.2.0" resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-4.2.0.tgz#a2aa5fb1af688758259c32c141426d78923b9b77" @@ -1961,12 +1812,7 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= -ccount@^1.0.3: - version "1.0.5" - resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.0.5.tgz#ac82a944905a65ce204eb03023157edf29425c17" - integrity sha512-MOli1W+nfbPLlKEhInaxhRdp7KVLFxLN5ykwzHgLsLI3H3gs5jjFAK4Eoj3OzzcxCtumDaI8onoVDeQyWaNTkw== - -chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: +chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" dependencies: @@ -2000,21 +1846,6 @@ chalk@^4.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -character-entities-legacy@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz#94bc1845dce70a5bb9d2ecc748725661293d8fc1" - integrity sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA== - -character-entities@^1.0.0: - version "1.2.4" - resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.2.4.tgz#e12c3939b7eaf4e5b15e7ad4c5e28e1d48c5b16b" - integrity sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw== - -character-reference-invalid@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz#083329cda0eae272ab3dbbf37e9a382c13af1560" - integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg== - chardet@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" @@ -2115,11 +1946,6 @@ code-point-at@^1.0.0: resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= -collapse-white-space@^1.0.0, collapse-white-space@^1.0.2: - version "1.0.6" - resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.6.tgz#e63629c0016665792060dbbeb79c42239d2c5287" - integrity sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ== - collect-v8-coverage@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" @@ -2162,11 +1988,6 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -comma-separated-tokens@^1.0.0: - version "1.0.8" - resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz#632b80b6117867a158f1080ad498b2fbe7e3f5ea" - integrity sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw== - commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -2232,12 +2053,6 @@ console-control-strings@^1.0.0, console-control-strings@~1.1.0: resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= -consolidate@^0.15.1: - version "0.15.1" - resolved "https://registry.yarnpkg.com/consolidate/-/consolidate-0.15.1.tgz#21ab043235c71a07d45d9aad98593b0dba56bab7" - dependencies: - bluebird "^3.1.1" - constants-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" @@ -2366,6 +2181,13 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: safe-buffer "^5.0.1" sha.js "^2.4.8" +cross-env@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.2.tgz#bd5ed31339a93a3418ac4f3ca9ca3403082ae5f9" + integrity sha512-KZP/bMEOJEDCkDQAyRhu3RL2ZO/SUVrxQVI0G3YEQ+OLbRA3c6zgixe8Mq8a/z7+HKlNEjo8oiLUs8iRijY2Rw== + dependencies: + cross-spawn "^7.0.1" + cross-spawn@^6.0.0, cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" @@ -2376,7 +2198,7 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^7.0.0, cross-spawn@^7.0.2: +cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2: version "7.0.2" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.2.tgz#d0d7dcfa74e89115c7619f4f721a94e1fdb716d6" integrity sha512-PD6G8QG3S4FK/XCGFbEQrDqO2AnMMsy0meR7lerlIOHAAbkuavGU/pOqprrlvfTNjvowivTeBsjebAL0NSoMxw== @@ -2402,11 +2224,6 @@ crypto-browserify@^3.11.0: randombytes "^2.0.0" randomfill "^1.0.3" -cssesc@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" - integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== - cssom@^0.4.1: version "0.4.4" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" @@ -2462,10 +2279,6 @@ date-fns@^1.27.2: version "1.30.1" resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c" -de-indent@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d" - debug@^2.2.0, debug@^2.3.3: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -2560,13 +2373,6 @@ des.js@^1.0.0: inherits "^2.0.1" minimalistic-assert "^1.0.0" -detab@2.0.3, detab@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/detab/-/detab-2.0.3.tgz#33e5dd74d230501bd69985a0d2b9a3382699a130" - integrity sha512-Up8P0clUVwq0FnFjDclzZsy9PadzRn5FFxrr47tQQvMHqyiFYVbpH8oXDzWtF0Q7pYy3l+RPmtBl+BsFF6wH0A== - dependencies: - repeat-string "^1.5.4" - detect-libc@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" @@ -2671,7 +2477,7 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0: dependencies: once "^1.4.0" -enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0: +enhanced-resolve@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz#41c7e0bfdfe74ac1ffe1e57ad6a5c6c9f3742a7f" dependencies: @@ -2942,7 +2748,7 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: assign-symbols "^1.0.0" is-extendable "^1.0.1" -extend@^3.0.0, extend@~3.0.2: +extend@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== @@ -3422,10 +3228,6 @@ hash-base@^3.0.0: inherits "^2.0.1" safe-buffer "^5.0.1" -hash-sum@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/hash-sum/-/hash-sum-1.0.2.tgz#33b40777754c6432573c120cc3808bbd10d47f04" - hash.js@^1.0.0, hash.js@^1.0.3: version "1.1.7" resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" @@ -3434,73 +3236,6 @@ hash.js@^1.0.0, hash.js@^1.0.3: inherits "^2.0.3" minimalistic-assert "^1.0.1" -hast-to-hyperscript@^7.0.0: - version "7.0.4" - resolved "https://registry.yarnpkg.com/hast-to-hyperscript/-/hast-to-hyperscript-7.0.4.tgz#7c4c037d9a8ea19b0a3fdb676a26448ad922353d" - integrity sha512-vmwriQ2H0RPS9ho4Kkbf3n3lY436QKLq6VaGA1pzBh36hBi3tm1DO9bR+kaJIbpT10UqaANDkMjxvjVfr+cnOA== - dependencies: - comma-separated-tokens "^1.0.0" - property-information "^5.3.0" - space-separated-tokens "^1.0.0" - style-to-object "^0.2.1" - unist-util-is "^3.0.0" - web-namespaces "^1.1.2" - -hast-util-from-parse5@^5.0.0: - version "5.0.2" - resolved "https://registry.yarnpkg.com/hast-util-from-parse5/-/hast-util-from-parse5-5.0.2.tgz#afeadc6aab41e6acfe038645bbefd4005c56a475" - integrity sha512-YXFjoRS7ES7PEoLx6uihtSfKTO1s3z/tzGiV5cVpsUiihduogFXubNRCzTIW3yOOGO1nws9CxPq4MbwD39Uo+w== - dependencies: - ccount "^1.0.3" - hastscript "^5.0.0" - property-information "^5.0.0" - web-namespaces "^1.1.2" - xtend "^4.0.1" - -hast-util-parse-selector@^2.0.0: - version "2.2.3" - resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-2.2.3.tgz#57edd449103900c7f63fd9e6f694ffd7e4634719" - integrity sha512-nxbeqjQNxsvo/uYYAw9kij6td05YVUlf1qti09rVfbWSLT5H6wo3c+USIwX6nzXWk5kFZzXnEqO82856r0aM2Q== - -hast-util-raw@5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/hast-util-raw/-/hast-util-raw-5.0.2.tgz#62288f311ec2f35e066a30d5e0277f963ad43a67" - integrity sha512-3ReYQcIHmzSgMq8UrDZHFL0oGlbuVGdLKs8s/Fe8BfHFAyZDrdv1fy/AGn+Fim8ZuvAHcJ61NQhVMtyfHviT/g== - dependencies: - hast-util-from-parse5 "^5.0.0" - hast-util-to-parse5 "^5.0.0" - html-void-elements "^1.0.0" - parse5 "^5.0.0" - unist-util-position "^3.0.0" - web-namespaces "^1.0.0" - xtend "^4.0.0" - zwitch "^1.0.0" - -hast-util-to-parse5@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/hast-util-to-parse5/-/hast-util-to-parse5-5.1.1.tgz#cabf2dbe9ed988a5128fc708457b37cdf535a2e8" - integrity sha512-ivCeAd5FCXr7bapJIVsWMnx/EmbjkkW2TU2hd1prq+jGwiaUoK+FcpjyPNwsC5ogzCwWO669tOqIovGeLc/ntg== - dependencies: - hast-to-hyperscript "^7.0.0" - property-information "^5.0.0" - web-namespaces "^1.0.0" - xtend "^4.0.1" - zwitch "^1.0.0" - -hastscript@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-5.1.1.tgz#71726ee1e97220575d1f29a8e937387d99d48275" - integrity sha512-xHo1Hkcqd0LlWNuDL3/BxwhgAGp3d7uEvCMgCTrBY+zsOooPPH+8KAvW8PCgl+GB8H3H44nfSaF0A4BQ+4xlYg== - dependencies: - comma-separated-tokens "^1.0.0" - hast-util-parse-selector "^2.0.0" - property-information "^5.0.0" - space-separated-tokens "^1.0.0" - -he@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" - hmac-drbg@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" @@ -3526,11 +3261,6 @@ html-escaper@^2.0.0: resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== -html-void-elements@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-1.0.5.tgz#ce9159494e86d95e45795b166c2021c2cfca4483" - integrity sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w== - http-signature@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" @@ -3635,10 +3365,6 @@ indent-string@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" -indexes-of@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" - infer-owner@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" @@ -3652,7 +3378,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.0, inherits@^2.0.1, inherits@~2.0.3: +inherits@2, inherits@^2.0.1, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -3670,11 +3396,6 @@ ini@^1.3.4, ini@~1.3.0: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" -inline-style-parser@0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.1.1.tgz#ec8a3b429274e9c0a1f1c4ffa9453a7fef72cea1" - integrity sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q== - inquirer@^7.0.0: version "7.0.1" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.0.1.tgz#13f7980eedc73c689feff3994b109c4e799c6ebb" @@ -3713,19 +3434,6 @@ is-accessor-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" -is-alphabetical@1.0.4, is-alphabetical@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.4.tgz#9e7d6b94916be22153745d184c298cbf986a686d" - integrity sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg== - -is-alphanumerical@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz#7eb9a2431f855f6b1ef1a78e326df515696c4dbf" - integrity sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A== - dependencies: - is-alphabetical "^1.0.0" - is-decimal "^1.0.0" - is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" @@ -3742,11 +3450,6 @@ is-buffer@^1.1.5: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== -is-buffer@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623" - integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A== - is-builtin-module@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" @@ -3773,11 +3476,6 @@ is-data-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" -is-decimal@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.4.tgz#65a3a5958a1c5b63a706e1b333d7cd9f630d3fa5" - integrity sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw== - is-descriptor@^0.1.0: version "0.1.6" resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" @@ -3853,11 +3551,6 @@ is-glob@^4.0.0, is-glob@^4.0.1: dependencies: is-extglob "^2.1.1" -is-hexadecimal@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7" - integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw== - is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" @@ -3884,11 +3577,6 @@ is-plain-obj@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" -is-plain-obj@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" - integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== - is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" @@ -3925,21 +3613,11 @@ is-typedarray@^1.0.0, is-typedarray@~1.0.0: resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= -is-whitespace-character@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz#0858edd94a95594c7c9dd0b5c174ec6e45ee4aa7" - integrity sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w== - is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== -is-word-character@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-word-character/-/is-word-character-1.0.4.tgz#ce0e73216f98599060592f62ff31354ddbeb0230" - integrity sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA== - is-wsl@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" @@ -4620,7 +4298,7 @@ loader-runner@^2.4.0: resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== -loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3: +loader-utils@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" dependencies: @@ -4679,10 +4357,6 @@ lodash.templatesettings@^4.0.0: dependencies: lodash._reinterpolate "^3.0.0" -lodash.uniq@4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" - lodash@4.17.15, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" @@ -4729,13 +4403,6 @@ loud-rejection@^1.0.0: currently-unhandled "^0.4.1" signal-exit "^3.0.0" -lru-cache@^4.1.2: - version "4.1.5" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -4791,11 +4458,6 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" -markdown-escapes@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/markdown-escapes/-/markdown-escapes-1.0.4.tgz#c95415ef451499d7602b91095f3c8e8975f78535" - integrity sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg== - md5.js@^1.3.4: version "1.3.5" resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" @@ -4805,40 +4467,6 @@ md5.js@^1.3.4: inherits "^2.0.1" safe-buffer "^5.1.2" -mdast-squeeze-paragraphs@^3.0.0: - version "3.0.5" - resolved "https://registry.yarnpkg.com/mdast-squeeze-paragraphs/-/mdast-squeeze-paragraphs-3.0.5.tgz#f428b6b944f8faef454db9b58f170c4183cb2e61" - integrity sha512-xX6Vbe348Y/rukQlG4W3xH+7v4ZlzUbSY4HUIQCuYrF2DrkcHx584mCaFxkWoDZKNUfyLZItHC9VAqX3kIP7XA== - dependencies: - unist-util-remove "^1.0.0" - -mdast-util-definitions@^1.2.0: - version "1.2.5" - resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-1.2.5.tgz#3fe622a4171c774ebd06f11e9f8af7ec53ea5c74" - integrity sha512-CJXEdoLfiISCDc2JB6QLb79pYfI6+GcIH+W2ox9nMc7od0Pz+bovcHsiq29xAQY6ayqe/9CsK2VzkSJdg1pFYA== - dependencies: - unist-util-visit "^1.0.0" - -mdast-util-to-hast@7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-7.0.0.tgz#589b562ce1ae0a7849e6c38536a9e7bc4f415e54" - integrity sha512-vxnXKSZgvPG2grZM3kxaF052pxsLtq8TPAkiMkqYj1nFTOazYUPXt3LFYIEB6Ws/IX7Uyvljzk64kD6DwZl/wQ== - dependencies: - collapse-white-space "^1.0.0" - detab "^2.0.0" - mdast-util-definitions "^1.2.0" - mdurl "^1.0.1" - trim-lines "^1.0.0" - unist-builder "^2.0.0" - unist-util-generated "^1.0.0" - unist-util-position "^3.0.0" - unist-util-visit "^2.0.0" - -mdurl@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" - integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4= - memfs@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.1.2.tgz#2bb51600dacec67ed35677b1185abb708b7d2ad6" @@ -4868,18 +4496,12 @@ meow@5.0.0, meow@^5.0.0: trim-newlines "^2.0.0" yargs-parser "^10.0.0" -merge-source-map@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.1.0.tgz#2fdde7e6020939f70906a68f2d7ae685e4c8c646" - dependencies: - source-map "^0.6.1" - merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== -micromatch@4.x, micromatch@^4.0.0, micromatch@^4.0.2: +micromatch@4.x, micromatch@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== @@ -5083,14 +4705,6 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" -nativescript-vue-template-compiler@^2.5.1: - version "2.5.1" - resolved "https://registry.yarnpkg.com/nativescript-vue-template-compiler/-/nativescript-vue-template-compiler-2.5.1.tgz#7e4cdd28b75572e8c8b146f28fae9d8f719f3036" - integrity sha512-kbakGg71aTytDTa5M12rie8/5AdNkN1NpcnQMPiZY/CxQ2Tf2NUVnu0EFbBGcO7gS+TeKiYIKiA28R1e6YCLqQ== - dependencies: - de-indent "^1.0.2" - he "^1.1.0" - natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -5464,18 +5078,6 @@ parse-asn1@^5.0.0: pbkdf2 "^3.0.3" safe-buffer "^5.1.1" -parse-entities@^1.1.0: - version "1.2.2" - resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-1.2.2.tgz#c31bf0f653b6661354f8973559cb86dd1d5edf50" - integrity sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg== - dependencies: - character-entities "^1.0.0" - character-entities-legacy "^1.0.0" - character-reference-invalid "^1.0.0" - is-alphanumerical "^1.0.0" - is-decimal "^1.0.0" - is-hexadecimal "^1.0.0" - parse-json@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" @@ -5498,11 +5100,6 @@ parse5@5.1.0: resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.0.tgz#c59341c9723f414c452975564c7c00a68d58acd2" integrity sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ== -parse5@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178" - integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug== - pascalcase@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" @@ -5624,24 +5221,6 @@ posix-character-classes@^0.1.0: resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= -postcss-selector-parser@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz#934cf799d016c83411859e09dcecade01286ec5c" - integrity sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg== - dependencies: - cssesc "^3.0.0" - indexes-of "^1.0.1" - uniq "^1.0.1" - -postcss@^7.0.14: - version "7.0.27" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.27.tgz#cc67cdc6b0daa375105b7c424a85567345fc54d9" - integrity sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ== - dependencies: - chalk "^2.4.2" - source-map "^0.6.1" - supports-color "^6.1.0" - prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" @@ -5653,11 +5232,6 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" -prettier@^1.18.2: - version "1.19.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" - integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== - prettier@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.4.tgz#2d1bae173e355996ee355ec9830a7a1ee05457ef" @@ -5699,21 +5273,10 @@ prompts@^2.0.1: kleur "^3.0.2" sisteransi "^1.0.0" -property-information@^5.0.0, property-information@^5.3.0: - version "5.4.0" - resolved "https://registry.yarnpkg.com/property-information/-/property-information-5.4.0.tgz#16e08f13f4e5c4a7be2e4ec431c01c4f8dba869a" - integrity sha512-nmMWAm/3vKFGmmOWOcdLjgq/Hlxa+hsuR/px1Lp/UGEyc5A22A6l78Shc2C0E71sPmAqglni+HrS7L7VJ7AUCA== - dependencies: - xtend "^4.0.0" - prr@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - psl@^1.1.28: version "1.1.31" resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.31.tgz#e9aa86d0101b5b105cbe93ac6b784cd547276184" @@ -5923,48 +5486,6 @@ regexpp@^3.0.0: resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.0.0.tgz#dd63982ee3300e67b41c1956f850aa680d9d330e" integrity sha512-Z+hNr7RAVWxznLPuA7DIh8UNX1j9CDrUQxskw9IrBE1Dxue2lyXT+shqEIeLUjrokxIP8CMy1WkjgG3rTsd5/g== -remark-mdx@^1.5.8: - version "1.5.8" - resolved "https://registry.yarnpkg.com/remark-mdx/-/remark-mdx-1.5.8.tgz#81fd9085e56ea534b977d08d6f170899138b3f38" - integrity sha512-wtqqsDuO/mU/ucEo/CDp0L8SPdS2oOE6PRsMm+lQ9TLmqgep4MBmyH8bLpoc8Wf7yjNmae/5yBzUN1YUvR/SsQ== - dependencies: - "@babel/core" "7.8.4" - "@babel/helper-plugin-utils" "7.8.3" - "@babel/plugin-proposal-object-rest-spread" "7.8.3" - "@babel/plugin-syntax-jsx" "7.8.3" - "@mdx-js/util" "^1.5.8" - is-alphabetical "1.0.4" - remark-parse "7.0.2" - unified "8.4.2" - -remark-parse@7.0.2: - version "7.0.2" - resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-7.0.2.tgz#41e7170d9c1d96c3d32cf1109600a9ed50dba7cf" - integrity sha512-9+my0lQS80IQkYXsMA8Sg6m9QfXYJBnXjWYN5U+kFc5/n69t+XZVXU/ZBYr3cYH8FheEGf1v87rkFDhJ8bVgMA== - dependencies: - collapse-white-space "^1.0.2" - is-alphabetical "^1.0.0" - is-decimal "^1.0.0" - is-whitespace-character "^1.0.0" - is-word-character "^1.0.0" - markdown-escapes "^1.0.0" - parse-entities "^1.1.0" - repeat-string "^1.5.4" - state-toggle "^1.0.0" - trim "0.0.1" - trim-trailing-lines "^1.0.0" - unherit "^1.0.4" - unist-util-remove-position "^1.0.0" - vfile-location "^2.0.0" - xtend "^4.0.1" - -remark-squeeze-paragraphs@3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/remark-squeeze-paragraphs/-/remark-squeeze-paragraphs-3.0.4.tgz#9fe50c3bf3b572dd88754cd426ada007c0b8dc5f" - integrity sha512-Wmz5Yj9q+W1oryo8BV17JrOXZgUKVcpJ2ApE2pwnoHwhFKSk4Wp2PmFNbmJMgYSqAdFwfkoe+TSYop5Fy8wMgA== - dependencies: - mdast-squeeze-paragraphs "^3.0.0" - remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" @@ -5975,16 +5496,11 @@ repeat-element@^1.1.2: resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== -repeat-string@^1.5.4, repeat-string@^1.6.1: +repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= -replace-ext@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" - integrity sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs= - request-promise-core@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.3.tgz#e9a3c081b51380dfea677336061fea879a829ee9" @@ -6447,11 +5963,6 @@ source-map@^0.7.3: version "0.7.3" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" -space-separated-tokens@^1.0.0: - version "1.1.5" - resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz#85f32c3d10d9682007e917414ddc5c26d1aa6899" - integrity sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA== - spdx-correct@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" @@ -6518,11 +6029,6 @@ stack-utils@^1.0.1: resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8" integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA== -state-toggle@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.3.tgz#e123b16a88e143139b09c6852221bc9815917dfe" - integrity sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ== - static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" @@ -6697,20 +6203,6 @@ strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" -style-to-object@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.3.0.tgz#b1b790d205991cc783801967214979ee19a76e46" - integrity sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA== - dependencies: - inline-style-parser "0.1.1" - -style-to-object@^0.2.1: - version "0.2.3" - resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.2.3.tgz#afcf42bc03846b1e311880c55632a26ad2780bcb" - integrity sha512-1d/k4EY2N7jVLOqf2j04dTc37TPOv/hHxZmvpg8Pdh8UYydxeu/C1W1U4vD8alzf5V2Gt7rLsmkr4dxAlDm9ng== - dependencies: - inline-style-parser "0.1.1" - supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" @@ -6721,12 +6213,6 @@ supports-color@^5.3.0: dependencies: has-flag "^3.0.0" -supports-color@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" - dependencies: - has-flag "^3.0.0" - supports-color@^7.0.0, supports-color@^7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" @@ -6940,10 +6426,10 @@ tr46@^1.0.1: dependencies: punycode "^2.1.0" -trim-lines@^1.0.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/trim-lines/-/trim-lines-1.1.3.tgz#839514be82428fd9e7ec89e35081afe8f6f93115" - integrity sha512-E0ZosSWYK2mkSu+KEtQ9/KqarVjA9HztOSX+9FDdNacRAq29RRV6ZQNgob3iuW8Htar9vAfEa6yyt5qBAHZDBA== +tree-kill@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" + integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== trim-newlines@^2.0.0: version "2.0.0" @@ -6960,21 +6446,6 @@ trim-right@^1.0.1: resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= -trim-trailing-lines@^1.0.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.1.3.tgz#7f0739881ff76657b7776e10874128004b625a94" - integrity sha512-4ku0mmjXifQcTVfYDfR5lpgV7zVqPg6zV9rdZmwOPqq0+Zq19xDqEgagqVbc4pOOShbncuAOIs59R3+3gcF3ZA== - -trim@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd" - integrity sha1-WFhUf2spB1fulczMZm+1AITEYN0= - -trough@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406" - integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA== - ts-jest@^25.3.1: version "25.3.1" resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-25.3.1.tgz#58e2ed3506e4e4487c0b9b532846a5cade9656ba" @@ -6992,17 +6463,6 @@ ts-jest@^25.3.1: semver "6.x" yargs-parser "18.x" -ts-loader@^6.2.2: - version "6.2.2" - resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-6.2.2.tgz#dffa3879b01a1a1e0a4b85e2b8421dc0dfff1c58" - integrity sha512-HDo5kXZCBml3EUPcc7RlZOV/JGlLHwppTLEHb3SHnr5V7NXD4klMEkrhJe5wgRbaWsSXi+Y1SIBN/K9B6zWGWQ== - dependencies: - chalk "^2.3.0" - enhanced-resolve "^4.0.0" - loader-utils "^1.0.2" - micromatch "^4.0.0" - semver "^6.0.0" - tslib@^1.8.1, tslib@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" @@ -7068,25 +6528,6 @@ typescript@^3.8.3: resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.8.3.tgz#409eb8544ea0335711205869ec458ab109ee1061" integrity sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w== -unherit@^1.0.4: - version "1.1.3" - resolved "https://registry.yarnpkg.com/unherit/-/unherit-1.1.3.tgz#6c9b503f2b41b262330c80e91c8614abdaa69c22" - integrity sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ== - dependencies: - inherits "^2.0.0" - xtend "^4.0.0" - -unified@8.4.2: - version "8.4.2" - resolved "https://registry.yarnpkg.com/unified/-/unified-8.4.2.tgz#13ad58b4a437faa2751a4a4c6a16f680c500fff1" - integrity sha512-JCrmN13jI4+h9UAyKEoGcDZV+i1E7BLFuG7OsaDvTXI5P0qhHX+vZO/kOhz9jn8HGENDKbwSeB0nVOg4gVStGA== - dependencies: - bail "^1.0.0" - extend "^3.0.0" - is-plain-obj "^2.0.0" - trough "^1.0.0" - vfile "^4.0.0" - union-value@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" @@ -7097,10 +6538,6 @@ union-value@^1.0.0: is-extendable "^0.1.1" set-value "^2.0.1" -uniq@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" - unique-filename@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" @@ -7113,83 +6550,6 @@ unique-slug@^2.0.0: dependencies: imurmurhash "^0.1.4" -unist-builder@2.0.3, unist-builder@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/unist-builder/-/unist-builder-2.0.3.tgz#77648711b5d86af0942f334397a33c5e91516436" - integrity sha512-f98yt5pnlMWlzP539tPc4grGMsFaQQlP/vM396b00jngsiINumNmsY8rkXjfoi1c6QaM8nQ3vaGDuoKWbe/1Uw== - -unist-util-generated@^1.0.0: - version "1.1.5" - resolved "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-1.1.5.tgz#1e903e68467931ebfaea386dae9ea253628acd42" - integrity sha512-1TC+NxQa4N9pNdayCYA1EGUOCAO0Le3fVp7Jzns6lnua/mYgwHo0tz5WUAfrdpNch1RZLHc61VZ1SDgrtNXLSw== - -unist-util-is@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-3.0.0.tgz#d9e84381c2468e82629e4a5be9d7d05a2dd324cd" - integrity sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A== - -unist-util-is@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-4.0.1.tgz#ae3e39b9ad1b138c8e3b9d2f4658ad0031be4610" - integrity sha512-7NYjErP4LJtkEptPR22wO5RsCPnHZZrop7t2SoQzjvpFedCFer4WW8ujj9GI5DkUX7yVcffXLjoURf6h2QUv6Q== - -unist-util-position@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-3.1.0.tgz#1c42ee6301f8d52f47d14f62bbdb796571fa2d47" - integrity sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA== - -unist-util-remove-position@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/unist-util-remove-position/-/unist-util-remove-position-1.1.4.tgz#ec037348b6102c897703eee6d0294ca4755a2020" - integrity sha512-tLqd653ArxJIPnKII6LMZwH+mb5q+n/GtXQZo6S6csPRs5zB0u79Yw8ouR3wTw8wxvdJFhpP6Y7jorWdCgLO0A== - dependencies: - unist-util-visit "^1.1.0" - -unist-util-remove@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/unist-util-remove/-/unist-util-remove-1.0.3.tgz#58ec193dfa84b52d5a055ffbc58e5444eb8031a3" - integrity sha512-mB6nCHCQK0pQffUAcCVmKgIWzG/AXs/V8qpS8K72tMPtOSCMSjDeMc5yN+Ye8rB0FhcE+JvW++o1xRNc0R+++g== - dependencies: - unist-util-is "^3.0.0" - -unist-util-stringify-position@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-2.0.2.tgz#5a3866e7138d55974b640ec69a94bc19e0f3fa12" - integrity sha512-nK5n8OGhZ7ZgUwoUbL8uiVRwAbZyzBsB/Ddrlbu6jwwubFza4oe15KlyEaLNMXQW1svOQq4xesUeqA85YrIUQA== - dependencies: - "@types/unist" "^2.0.2" - -unist-util-visit-parents@^2.0.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz#25e43e55312166f3348cae6743588781d112c1e9" - integrity sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g== - dependencies: - unist-util-is "^3.0.0" - -unist-util-visit-parents@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-3.0.1.tgz#666883dc8684c6eec04a7e9781cdcd8b4888319f" - integrity sha512-umEOTkm6/y1gIqPrqet55mYqlvGXCia/v1FSc5AveLAI7jFmOAIbqiwcHcviLcusAkEQt1bq2hixCKO9ltMb2Q== - dependencies: - "@types/unist" "^2.0.0" - unist-util-is "^4.0.0" - -unist-util-visit@2.0.2, unist-util-visit@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-2.0.2.tgz#3843782a517de3d2357b4c193b24af2d9366afb7" - integrity sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ== - dependencies: - "@types/unist" "^2.0.0" - unist-util-is "^4.0.0" - unist-util-visit-parents "^3.0.0" - -unist-util-visit@^1.0.0, unist-util-visit@^1.1.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-1.4.1.tgz#4724aaa8486e6ee6e26d7ff3c8685960d560b1e3" - integrity sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw== - dependencies: - unist-util-visit-parents "^2.0.0" - universalify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/universalify/-/universalify-1.0.0.tgz#b61a1da173e8435b2fe3c67d29b9adf8594bd16d" @@ -7293,80 +6653,11 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" -vfile-location@^2.0.0: - version "2.0.6" - resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-2.0.6.tgz#8a274f39411b8719ea5728802e10d9e0dff1519e" - integrity sha512-sSFdyCP3G6Ka0CEmN83A2YCMKIieHx0EDaj5IDP4g1pa5ZJ4FJDvpO0WODLxo4LUX4oe52gmSCK7Jw4SBghqxA== - -vfile-message@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-2.0.2.tgz#75ba05090ec758fa8420f2c11ce049bcddd8cf3e" - integrity sha512-gNV2Y2fDvDOOqq8bEe7cF3DXU6QgV4uA9zMR2P8tix11l1r7zju3zry3wZ8sx+BEfuO6WQ7z2QzfWTvqHQiwsA== - dependencies: - "@types/unist" "^2.0.0" - unist-util-stringify-position "^2.0.0" - -vfile@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/vfile/-/vfile-4.0.2.tgz#71af004d4a710b0e6be99c894655bc56126d5d56" - integrity sha512-yhoTU5cDMSsaeaMfJ5g0bUKYkYmZhAh9fn9TZicxqn+Cw4Z439il2v3oT9S0yjlpqlI74aFOQCt3nOV+pxzlkw== - dependencies: - "@types/unist" "^2.0.0" - is-buffer "^2.0.0" - replace-ext "1.0.0" - unist-util-stringify-position "^2.0.0" - vfile-message "^2.0.0" - vm-browserify@^1.0.1: version "1.1.2" resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== -vue-class-component@^7.2.3: - version "7.2.3" - resolved "https://registry.yarnpkg.com/vue-class-component/-/vue-class-component-7.2.3.tgz#a5b1abd53513a72ad51098752e2dedd499807cca" - integrity sha512-oEqYpXKaFN+TaXU+mRLEx8dX0ah85aAJEe61mpdoUrq0Bhe/6sWhyZX1JjMQLhVsHAkncyhedhmCdDVSasUtDw== - -vue-hot-reload-api@^2.3.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.1.tgz#b2d3d95402a811602380783ea4f566eb875569a2" - -vue-loader@^15.9.1: - version "15.9.1" - resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-15.9.1.tgz#bd2ab8f3d281e51d7b81d15390a58424d142243e" - integrity sha512-IaPU2KOPjs/QjMlxFs/TiTtQUSbftQ7lsAvoxe21rtcQohsMhx+1AltXCNhZIpIn46PtODiAgz+o8RbMpKtmJw== - dependencies: - "@vue/component-compiler-utils" "^3.1.0" - hash-sum "^1.0.2" - loader-utils "^1.1.0" - vue-hot-reload-api "^2.3.0" - vue-style-loader "^4.1.0" - -vue-style-loader@^4.1.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/vue-style-loader/-/vue-style-loader-4.1.2.tgz#dedf349806f25ceb4e64f3ad7c0a44fba735fcf8" - dependencies: - hash-sum "^1.0.2" - loader-utils "^1.0.2" - -vue-template-compiler@^2.6.11: - version "2.6.11" - resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.6.11.tgz#c04704ef8f498b153130018993e56309d4698080" - integrity sha512-KIq15bvQDrcCjpGjrAhx4mUlyyHfdmTaoNfeoATHLAiWB+MU3cx4lOzMwrnUh9cCxy0Lt1T11hAFY6TQgroUAA== - dependencies: - de-indent "^1.0.2" - he "^1.1.0" - -vue-template-es2015-compiler@^1.9.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825" - integrity sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw== - -vue@^2.6.11: - version "2.6.11" - resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.11.tgz#76594d877d4b12234406e84e35275c6d514125c5" - integrity sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ== - w3c-hr-time@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz#82ac2bff63d950ea9e3189a58a65625fedf19045" @@ -7399,11 +6690,6 @@ watchpack@^1.6.0: graceful-fs "^4.1.2" neo-async "^2.5.0" -web-namespaces@^1.0.0, web-namespaces@^1.1.2: - version "1.1.4" - resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.4.tgz#bc98a3de60dadd7faefc403d1076d529f5e030ec" - integrity sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw== - webidl-conversions@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" @@ -7565,7 +6851,7 @@ xmlchars@^2.1.1: resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== -xtend@^4.0.0, xtend@^4.0.1: +xtend@^4.0.0: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== @@ -7578,10 +6864,6 @@ y18n@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3: version "3.1.1" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" @@ -7625,8 +6907,3 @@ yargs@^15.3.1: which-module "^2.0.0" y18n "^4.0.0" yargs-parser "^18.1.1" - -zwitch@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920" - integrity sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw== From 8d6d1ec1de08feab6c539c34da81c06d57e19020 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ole=C5=9B?= Date: Wed, 20 May 2020 23:38:44 +0200 Subject: [PATCH 18/29] test: add tests for vue and pnp typescript extension --- test/e2e/TypeScriptPnpExtension.spec.ts | 188 +++++++ test/e2e/TypeScriptSolutionBuilderApi.spec.ts | 166 +++--- test/e2e/TypeScriptVueExtension.spec.ts | 53 ++ test/e2e/TypeScriptWatchApi.spec.ts | 478 +++++++++--------- test/e2e/fixtures/typescript-pnp.fixture | 180 +++++++ test/e2e/fixtures/typescript-vue.fixture | 258 ++++++++++ test/e2e/sandbox/Sandbox.ts | 40 +- 7 files changed, 1029 insertions(+), 334 deletions(-) create mode 100644 test/e2e/TypeScriptPnpExtension.spec.ts create mode 100644 test/e2e/TypeScriptVueExtension.spec.ts create mode 100644 test/e2e/fixtures/typescript-pnp.fixture create mode 100644 test/e2e/fixtures/typescript-vue.fixture diff --git a/test/e2e/TypeScriptPnpExtension.spec.ts b/test/e2e/TypeScriptPnpExtension.spec.ts new file mode 100644 index 00000000..edcac03c --- /dev/null +++ b/test/e2e/TypeScriptPnpExtension.spec.ts @@ -0,0 +1,188 @@ +import { + createSandbox, + FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION, + Sandbox, + yarnInstaller, +} from './sandbox/Sandbox'; +import { readFixture } from './sandbox/Fixture'; +import { join } from 'path'; +import { + createWebpackDevServerDriver, + WEBPACK_CLI_VERSION, + WEBPACK_DEV_SERVER_VERSION, +} from './sandbox/WebpackDevServerDriver'; + +describe('TypeScript PnP Extension', () => { + let sandbox: Sandbox; + + beforeAll(async () => { + sandbox = await createSandbox(); + }); + + beforeEach(async () => { + await sandbox.reset(); + }); + + afterAll(async () => { + await sandbox.cleanup(); + }); + + it.each([ + { async: true, webpack: '^4.0.0', typescript: '2.7.1', tsloader: '^5.0.0' }, + { async: false, webpack: '^4.0.0', typescript: '~3.0.0', tsloader: '^6.0.0' }, + { async: true, webpack: '^4.0.0', typescript: '~3.6.0', tsloader: '^7.0.0' }, + { async: false, webpack: '^4.0.0', typescript: '~3.8.0', tsloader: '^6.0.0' }, + ])('reports semantic error for %p', async ({ async, webpack, typescript, tsloader }) => { + await sandbox.load( + await readFixture(join(__dirname, 'fixtures/typescript-pnp.fixture'), { + FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION: JSON.stringify( + FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION + ), + TS_LOADER_VERSION: JSON.stringify(tsloader), + TYPESCRIPT_VERSION: JSON.stringify(typescript), + WEBPACK_VERSION: JSON.stringify(webpack), + WEBPACK_CLI_VERSION: JSON.stringify(WEBPACK_CLI_VERSION), + WEBPACK_DEV_SERVER_VERSION: JSON.stringify(WEBPACK_DEV_SERVER_VERSION), + ASYNC: JSON.stringify(async), + }), + yarnInstaller + ); + + const driver = createWebpackDevServerDriver(sandbox.spawn('yarn webpack-dev-server'), async); + let errors: string[]; + + // first compilation is successful + await driver.waitForNoErrors(); + + // then we introduce semantic error by removing "firstName" and "lastName" from the User model + await sandbox.patch( + 'src/model/User.ts', + [' firstName?: string;', ' lastName?: string;'].join('\n'), + '' + ); + + // we should receive 2 semantic errors + errors = await driver.waitForErrors(); + expect(errors).toEqual([ + [ + 'ERROR in src/model/User.ts 11:16-25', + "TS2339: Property 'firstName' does not exist on type 'User'.", + ' 9 | ', + ' 10 | function getUserName(user: User): string {', + ' > 11 | return [user.firstName, user.lastName]', + ' | ^^^^^^^^^', + ' 12 | .filter(name => name !== undefined)', + " 13 | .join(' ');", + ' 14 | }', + ].join('\n'), + [ + 'ERROR in src/model/User.ts 11:32-40', + "TS2339: Property 'lastName' does not exist on type 'User'.", + ' 9 | ', + ' 10 | function getUserName(user: User): string {', + ' > 11 | return [user.firstName, user.lastName]', + ' | ^^^^^^^^', + ' 12 | .filter(name => name !== undefined)', + " 13 | .join(' ');", + ' 14 | }', + ].join('\n'), + ]); + + // fix the semantic error + await sandbox.patch( + 'src/model/User.ts', + [ + ' return [user.firstName, user.lastName]', + ' .filter(name => name !== undefined)', + " .join(' ');", + ].join('\n'), + ` return user.email;` + ); + + await driver.waitForNoErrors(); + + // delete module to trigger another error + await sandbox.remove('src/authenticate.ts'); + + errors = await driver.waitForErrors(); + expect(errors).toEqual([ + [ + 'ERROR in src/index.ts 1:23-39', + "TS2307: Cannot find module './authenticate'.", + " > 1 | import { login } from './authenticate';", + ' | ^^^^^^^^^^^^^^^^', + " 2 | import { getUserName } from './model/User';", + ' 3 | ', + " 4 | const emailInput = document.getElementById('email');", + ].join('\n'), + ]); + + // re-create deleted module + await sandbox.write( + 'src/authenticate.ts', + [ + "import { User } from './model/User';", + '', + 'async function login(email: string, password: string): Promise {', + ' await fetch(', + " '/login',", + ' {', + " method: 'POST',", + ' body: JSON.stringify({ email, password })', + ' }', + ' );', + '}', + '', + 'async function logout(): Promise {', + ' const response = await fetch(', + " '/logout',", + ' {', + " method: 'POST'", + ' }', + ' );', + ' return response.json();', + '}', + '', + 'export { login, logout };', + ].join('\n') + ); + + // we should receive again 3 semantic errors + errors = await driver.waitForErrors(); + expect(errors).toEqual([ + [ + 'ERROR in src/index.ts 34:12-16', + "TS2339: Property 'role' does not exist on type 'void'.", + ' 32 | const user = await login(email, password);', + ' 33 | ', + " > 34 | if (user.role === 'admin') {", + ' | ^^^^', + ' 35 | console.log(`Logged in as ${getUserName(user)} [admin].`);', + ' 36 | } else {', + ' 37 | console.log(`Logged in as ${getUserName(user)}`);', + ].join('\n'), + [ + 'ERROR in src/index.ts 35:45-49', + "TS2345: Argument of type 'void' is not assignable to parameter of type 'User'.", + ' 33 | ', + " 34 | if (user.role === 'admin') {", + ' > 35 | console.log(`Logged in as ${getUserName(user)} [admin].`);', + ' | ^^^^', + ' 36 | } else {', + ' 37 | console.log(`Logged in as ${getUserName(user)}`);', + ' 38 | }', + ].join('\n'), + [ + 'ERROR in src/index.ts 37:45-49', + "TS2345: Argument of type 'void' is not assignable to parameter of type 'User'.", + ' 35 | console.log(`Logged in as ${getUserName(user)} [admin].`);', + ' 36 | } else {', + ' > 37 | console.log(`Logged in as ${getUserName(user)}`);', + ' | ^^^^', + ' 38 | }', + ' 39 | });', + ' 40 | ', + ].join('\n'), + ]); + }); +}); diff --git a/test/e2e/TypeScriptSolutionBuilderApi.spec.ts b/test/e2e/TypeScriptSolutionBuilderApi.spec.ts index 45e18d6c..4d08d0ac 100644 --- a/test/e2e/TypeScriptSolutionBuilderApi.spec.ts +++ b/test/e2e/TypeScriptSolutionBuilderApi.spec.ts @@ -8,100 +8,98 @@ import { } from './sandbox/WebpackDevServerDriver'; describe('TypeScript SolutionBuilder API', () => { - describe('semantic error', () => { - let sandbox: Sandbox; + let sandbox: Sandbox; - beforeAll(async () => { - sandbox = await createSandbox(); - }); + beforeAll(async () => { + sandbox = await createSandbox(); + }); - beforeEach(async () => { - await sandbox.reset(); - }); + beforeEach(async () => { + await sandbox.reset(); + }); - afterAll(async () => { - await sandbox.cleanup(); - }); + afterAll(async () => { + await sandbox.cleanup(); + }); - it.each([{ async: false }, { async: true }])( - 'reports semantic error for %p', - async ({ async }) => { - await sandbox.load( - await readFixture(join(__dirname, 'fixtures/typescript-project-references.fixture'), { - FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION: JSON.stringify( - FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION - ), - TS_LOADER_VERSION: JSON.stringify('^7.0.1'), - TYPESCRIPT_VERSION: JSON.stringify('~3.8.0'), - WEBPACK_VERSION: JSON.stringify('^4.0.0'), - WEBPACK_CLI_VERSION: JSON.stringify(WEBPACK_CLI_VERSION), - WEBPACK_DEV_SERVER_VERSION: JSON.stringify(WEBPACK_DEV_SERVER_VERSION), - ASYNC: JSON.stringify(async), - }) - ); + it.each([{ async: false }, { async: true }])( + 'reports semantic error for %p', + async ({ async }) => { + await sandbox.load( + await readFixture(join(__dirname, 'fixtures/typescript-project-references.fixture'), { + FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION: JSON.stringify( + FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION + ), + TS_LOADER_VERSION: JSON.stringify('^7.0.1'), + TYPESCRIPT_VERSION: JSON.stringify('~3.8.0'), + WEBPACK_VERSION: JSON.stringify('^4.0.0'), + WEBPACK_CLI_VERSION: JSON.stringify(WEBPACK_CLI_VERSION), + WEBPACK_DEV_SERVER_VERSION: JSON.stringify(WEBPACK_DEV_SERVER_VERSION), + ASYNC: JSON.stringify(async), + }) + ); - const driver = createWebpackDevServerDriver( - sandbox.spawn('./node_modules/.bin/webpack-dev-server'), - async - ); - let errors: string[]; + const driver = createWebpackDevServerDriver( + sandbox.spawn('./node_modules/.bin/webpack-dev-server'), + async + ); + let errors: string[]; - // initial compilation should be successful - await driver.waitForNoErrors(); + // initial compilation should be successful + await driver.waitForNoErrors(); - // create semantic error in shared package - await sandbox.patch('packages/shared/src/intersect.ts', 'arrayB: T[] = []', 'arrayB: T'); + // create semantic error in shared package + await sandbox.patch('packages/shared/src/intersect.ts', 'arrayB: T[] = []', 'arrayB: T'); - // this compilation should contain semantic error in the shared project - // (there is also an error in the client project but as its dependency is not built, it will not be processed) - errors = await driver.waitForErrors(); - expect(errors).toEqual([ - [ - 'ERROR in packages/shared/src/intersect.ts 2:41-49', - "TS2339: Property 'includes' does not exist on type 'T'.", - ' 1 | function intersect(arrayA: T[] = [], arrayB: T): T[] {', - ' > 2 | return arrayA.filter((item) => arrayB.includes(item));', - ' | ^^^^^^^^', - ' 3 | }', - ' 4 | ', - ' 5 | export default intersect;', - ].join('\n'), - ]); + // this compilation should contain semantic error in the shared project + // (there is also an error in the client project but as its dependency is not built, it will not be processed) + errors = await driver.waitForErrors(); + expect(errors).toEqual([ + [ + 'ERROR in packages/shared/src/intersect.ts 2:41-49', + "TS2339: Property 'includes' does not exist on type 'T'.", + ' 1 | function intersect(arrayA: T[] = [], arrayB: T): T[] {', + ' > 2 | return arrayA.filter((item) => arrayB.includes(item));', + ' | ^^^^^^^^', + ' 3 | }', + ' 4 | ', + ' 5 | export default intersect;', + ].join('\n'), + ]); - // fix semantic error in the shared package - await sandbox.patch( - 'packages/shared/src/intersect.ts', - 'return arrayA.filter((item) => arrayB.includes(item));', - 'return arrayA.filter((item) => item && arrayB);' - ); + // fix semantic error in the shared package + await sandbox.patch( + 'packages/shared/src/intersect.ts', + 'return arrayA.filter((item) => arrayB.includes(item));', + 'return arrayA.filter((item) => item && arrayB);' + ); - // this compilation should contain semantic error in the client project - errors = await driver.waitForErrors(); - expect(errors).toEqual([ - [ - 'ERROR in packages/client/src/index.ts 4:42-48', - "TS2345: Argument of type 'T[]' is not assignable to parameter of type 'T'.", - " 'T[]' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'.", - ' 2 | ', - ' 3 | function compute(arrayA: T[], arrayB: T[]) {', - ' > 4 | const intersection = intersect(arrayA, arrayB);', - ' | ^^^^^^', - ' 5 | const difference = subtract(arrayA, arrayB);', - ' 6 | ', - ' 7 | return {', - ].join('\n'), - ]); + // this compilation should contain semantic error in the client project + errors = await driver.waitForErrors(); + expect(errors).toEqual([ + [ + 'ERROR in packages/client/src/index.ts 4:42-48', + "TS2345: Argument of type 'T[]' is not assignable to parameter of type 'T'.", + " 'T[]' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'.", + ' 2 | ', + ' 3 | function compute(arrayA: T[], arrayB: T[]) {', + ' > 4 | const intersection = intersect(arrayA, arrayB);', + ' | ^^^^^^', + ' 5 | const difference = subtract(arrayA, arrayB);', + ' 6 | ', + ' 7 | return {', + ].join('\n'), + ]); - // fix semantic error in the client package - await sandbox.patch( - 'packages/client/src/index.ts', - 'const intersection = intersect(arrayA, arrayB);', - 'const intersection = intersect(arrayA, arrayB[0]);' - ); + // fix semantic error in the client package + await sandbox.patch( + 'packages/client/src/index.ts', + 'const intersection = intersect(arrayA, arrayB);', + 'const intersection = intersect(arrayA, arrayB[0]);' + ); - // this compilation should be successful - await driver.waitForNoErrors(); - } - ); - }); + // this compilation should be successful + await driver.waitForNoErrors(); + } + ); }); diff --git a/test/e2e/TypeScriptVueExtension.spec.ts b/test/e2e/TypeScriptVueExtension.spec.ts new file mode 100644 index 00000000..7b0db8a9 --- /dev/null +++ b/test/e2e/TypeScriptVueExtension.spec.ts @@ -0,0 +1,53 @@ +import { createSandbox, FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION, Sandbox } from './sandbox/Sandbox'; +import { readFixture } from './sandbox/Fixture'; +import { join } from 'path'; +import { + createWebpackDevServerDriver, + WEBPACK_CLI_VERSION, + WEBPACK_DEV_SERVER_VERSION, +} from './sandbox/WebpackDevServerDriver'; + +describe('TypeScript Vue Extension', () => { + let sandbox: Sandbox; + + beforeAll(async () => { + sandbox = await createSandbox(); + }); + + beforeEach(async () => { + await sandbox.reset(); + }); + + afterAll(async () => { + await sandbox.cleanup(); + }); + + it.each([{ async: true, webpack: '^4.0.0', typescript: '2.7.1', tsloader: '^5.0.0' }])( + 'reports semantic error for %p', + async ({ async, webpack, typescript, tsloader }) => { + await sandbox.load( + await readFixture(join(__dirname, 'fixtures/typescript-vue.fixture'), { + FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION: JSON.stringify( + FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION + ), + TS_LOADER_VERSION: JSON.stringify(tsloader), + TYPESCRIPT_VERSION: JSON.stringify(typescript), + WEBPACK_VERSION: JSON.stringify(webpack), + WEBPACK_CLI_VERSION: JSON.stringify(WEBPACK_CLI_VERSION), + WEBPACK_DEV_SERVER_VERSION: JSON.stringify(WEBPACK_DEV_SERVER_VERSION), + ASYNC: JSON.stringify(async), + }) + ); + + const driver = createWebpackDevServerDriver( + sandbox.spawn('./node_modules/.bin/webpack-dev-server'), + async + ); + + // first compilation is successful + await driver.waitForNoErrors(); + + // TODO: it seems that single-file components are broken on the ts-loader/typescript side + } + ); +}); diff --git a/test/e2e/TypeScriptWatchApi.spec.ts b/test/e2e/TypeScriptWatchApi.spec.ts index fc9b34ae..c3c04d46 100644 --- a/test/e2e/TypeScriptWatchApi.spec.ts +++ b/test/e2e/TypeScriptWatchApi.spec.ts @@ -8,160 +8,35 @@ import { } from './sandbox/WebpackDevServerDriver'; describe('TypeScript Watch API', () => { - describe('semantic error', () => { - let sandbox: Sandbox; + let sandbox: Sandbox; - beforeAll(async () => { - sandbox = await createSandbox(); - }); - - beforeEach(async () => { - await sandbox.reset(); - }); - - afterAll(async () => { - await sandbox.cleanup(); - }); - - it.each([ - { async: false, webpack: '4.0.0' }, - { async: true, webpack: '^4.0.0' }, - { async: false, webpack: '^5.0.0-beta.16' }, - { async: true, webpack: '^5.0.0-beta.16' }, - ])( - 'reports semantic error for %p with importsNotUsedAsValues configuration', - async ({ async, webpack }) => { - await sandbox.load( - await readFixture(join(__dirname, 'fixtures/typescript-basic.fixture'), { - FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION: JSON.stringify( - FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION - ), - TS_LOADER_VERSION: JSON.stringify('^5.0.0'), - TYPESCRIPT_VERSION: JSON.stringify('~3.8.0'), - WEBPACK_VERSION: JSON.stringify(webpack), - WEBPACK_CLI_VERSION: JSON.stringify(WEBPACK_CLI_VERSION), - WEBPACK_DEV_SERVER_VERSION: JSON.stringify(WEBPACK_DEV_SERVER_VERSION), - ASYNC: JSON.stringify(async), - }) - ); - - // add importsNotUsedAsValues which is supported from TypeScript 3.8.0+ - // this option is required for proper watching of type-only files in the `transpileOnly: true` mode - await sandbox.patch( - './tsconfig.json', - ' "outDir": "./dist"', - [' "outDir": "./dist",', ' "importsNotUsedAsValues": "preserve"'].join('\n') - ); - - const driver = createWebpackDevServerDriver( - sandbox.spawn('./node_modules/.bin/webpack-dev-server'), - async - ); - let errors: string[]; - - // first compilation is successful - await driver.waitForNoErrors(); - - // then we introduce semantic error by removing "admin" role - await sandbox.patch( - 'src/model/Role.ts', - 'type Role = "admin" | "client" | "provider";', - 'type Role = "client" | "provider";' - ); - - // we should receive only one semantic error - errors = await driver.waitForErrors(); - expect(errors).toEqual([ - [ - 'ERROR in src/index.ts 34:7-28', - `TS2367: This condition will always return 'false' since the types 'Role' and '"admin"' have no overlap.`, - ' 32 | const user = await login(email, password);', - ' 33 | ', - ` > 34 | if (user.role === 'admin') {`, - ' | ^^^^^^^^^^^^^^^^^^^^^', - ' 35 | console.log(`Logged in as ${getUserName(user)} [admin].`);', - ' 36 | } else {', - ' 37 | console.log(`Logged in as ${getUserName(user)}`);', - ].join('\n'), - ]); - - // fix the semantic error by changing condition branch related to the "admin" role - await sandbox.patch( - 'src/index.ts', - [ - " if (user.role === 'admin') {", - ' console.log(`Logged in as ${getUserName(user)} [admin].`);', - ' } else {', - ' console.log(`Logged in as ${getUserName(user)}`);', - ' }', - ].join('\n'), - [ - " if (user.role === 'provider') {", - ' console.log(`Logged in as ${getUserName(user)} [provider].`);', - ' } else {', - ' console.log(`Logged in as ${getUserName(user)}`);', - ' }', - ].join('\n') - ); - - await driver.waitForNoErrors(); - - // delete module to trigger another error - await sandbox.remove('src/model/Role.ts'); - - // filter-out ts-loader related errors - errors = (await driver.waitForErrors()).filter( - (error) => !error.includes('Module build failed') - ); - expect(errors).toEqual([ - [ - 'ERROR in src/model/User.ts 1:22-30', - "TS2307: Cannot find module './Role'.", - " > 1 | import { Role } from './Role';", - ' | ^^^^^^^^', - ' 2 | ', - ' 3 | type User = {', - ' 4 | id: string;', - ].join('\n'), - ]); + beforeAll(async () => { + sandbox = await createSandbox(); + }); - // re-create deleted module - await sandbox.write( - 'src/model/Role.ts', - ['type Role = "admin" | "client";', '', 'export { Role };'].join('\n') - ); + beforeEach(async () => { + await sandbox.reset(); + }); - // we should receive again the one semantic error but now for "provider" role - errors = await driver.waitForErrors(); - expect(errors).toEqual([ - [ - 'ERROR in src/index.ts 34:7-31', - "TS2367: This condition will always return 'false' since the types 'Role' and '\"provider\"' have no overlap.", - ' 32 | const user = await login(email, password);', - ' 33 | ', - " > 34 | if (user.role === 'provider') {", - ' | ^^^^^^^^^^^^^^^^^^^^^^^^', - ' 35 | console.log(`Logged in as ${getUserName(user)} [provider].`);', - ' 36 | } else {', - ' 37 | console.log(`Logged in as ${getUserName(user)}`);', - ].join('\n'), - ]); - } - ); + afterAll(async () => { + await sandbox.cleanup(); + }); - it.each([ - { async: true, webpack: '^4.0.0', typescript: '2.7.1', tsloader: '^5.0.0' }, - { async: false, webpack: '^4.0.0', typescript: '~3.0.0', tsloader: '^6.0.0' }, - { async: true, webpack: '^4.0.0', typescript: '~3.6.0', tsloader: '^7.0.0' }, - { async: false, webpack: '^4.0.0', typescript: '~3.8.0', tsloader: '^6.0.0' }, - ])('reports semantic error for %p', async ({ async, webpack, typescript, tsloader }) => { + it.each([ + { async: false, webpack: '4.0.0' }, + { async: true, webpack: '^4.0.0' }, + { async: false, webpack: '^5.0.0-beta.16' }, + { async: true, webpack: '^5.0.0-beta.16' }, + ])( + 'reports semantic error for %p with importsNotUsedAsValues configuration', + async ({ async, webpack }) => { await sandbox.load( await readFixture(join(__dirname, 'fixtures/typescript-basic.fixture'), { FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION: JSON.stringify( FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION ), - TS_LOADER_VERSION: JSON.stringify(tsloader), - TYPESCRIPT_VERSION: JSON.stringify(typescript), + TS_LOADER_VERSION: JSON.stringify('^5.0.0'), + TYPESCRIPT_VERSION: JSON.stringify('~3.8.0'), WEBPACK_VERSION: JSON.stringify(webpack), WEBPACK_CLI_VERSION: JSON.stringify(WEBPACK_CLI_VERSION), WEBPACK_DEV_SERVER_VERSION: JSON.stringify(WEBPACK_DEV_SERVER_VERSION), @@ -169,6 +44,14 @@ describe('TypeScript Watch API', () => { }) ); + // add importsNotUsedAsValues which is supported from TypeScript 3.8.0+ + // this option is required for proper watching of type-only files in the `transpileOnly: true` mode + await sandbox.patch( + './tsconfig.json', + ' "outDir": "./dist"', + [' "outDir": "./dist",', ' "importsNotUsedAsValues": "preserve"'].join('\n') + ); + const driver = createWebpackDevServerDriver( sandbox.spawn('./node_modules/.bin/webpack-dev-server'), async @@ -178,136 +61,251 @@ describe('TypeScript Watch API', () => { // first compilation is successful await driver.waitForNoErrors(); - // then we introduce semantic error by removing "firstName" and "lastName" from the User model + // then we introduce semantic error by removing "admin" role await sandbox.patch( - 'src/model/User.ts', - [' firstName?: string;', ' lastName?: string;'].join('\n'), - '' + 'src/model/Role.ts', + 'type Role = "admin" | "client" | "provider";', + 'type Role = "client" | "provider";' ); - // we should receive 2 semantic errors + // we should receive only one semantic error errors = await driver.waitForErrors(); expect(errors).toEqual([ [ - 'ERROR in src/model/User.ts 11:16-25', - "TS2339: Property 'firstName' does not exist on type 'User'.", - ' 9 | ', - ' 10 | function getUserName(user: User): string {', - ' > 11 | return [user.firstName, user.lastName]', - ' | ^^^^^^^^^', - ' 12 | .filter(name => name !== undefined)', - " 13 | .join(' ');", - ' 14 | }', - ].join('\n'), - [ - 'ERROR in src/model/User.ts 11:32-40', - "TS2339: Property 'lastName' does not exist on type 'User'.", - ' 9 | ', - ' 10 | function getUserName(user: User): string {', - ' > 11 | return [user.firstName, user.lastName]', - ' | ^^^^^^^^', - ' 12 | .filter(name => name !== undefined)', - " 13 | .join(' ');", - ' 14 | }', + 'ERROR in src/index.ts 34:7-28', + `TS2367: This condition will always return 'false' since the types 'Role' and '"admin"' have no overlap.`, + ' 32 | const user = await login(email, password);', + ' 33 | ', + ` > 34 | if (user.role === 'admin') {`, + ' | ^^^^^^^^^^^^^^^^^^^^^', + ' 35 | console.log(`Logged in as ${getUserName(user)} [admin].`);', + ' 36 | } else {', + ' 37 | console.log(`Logged in as ${getUserName(user)}`);', ].join('\n'), ]); - // fix the semantic error + // fix the semantic error by changing condition branch related to the "admin" role await sandbox.patch( - 'src/model/User.ts', + 'src/index.ts', [ - ' return [user.firstName, user.lastName]', - ' .filter(name => name !== undefined)', - " .join(' ');", + " if (user.role === 'admin') {", + ' console.log(`Logged in as ${getUserName(user)} [admin].`);', + ' } else {', + ' console.log(`Logged in as ${getUserName(user)}`);', + ' }', ].join('\n'), - ` return user.email;` + [ + " if (user.role === 'provider') {", + ' console.log(`Logged in as ${getUserName(user)} [provider].`);', + ' } else {', + ' console.log(`Logged in as ${getUserName(user)}`);', + ' }', + ].join('\n') ); await driver.waitForNoErrors(); // delete module to trigger another error - await sandbox.remove('src/authenticate.ts'); + await sandbox.remove('src/model/Role.ts'); - errors = await driver.waitForErrors(); + // filter-out ts-loader related errors + errors = (await driver.waitForErrors()).filter( + (error) => !error.includes('Module build failed') + ); expect(errors).toEqual([ [ - 'ERROR in src/index.ts 1:23-39', - "TS2307: Cannot find module './authenticate'.", - " > 1 | import { login } from './authenticate';", - ' | ^^^^^^^^^^^^^^^^', - " 2 | import { getUserName } from './model/User';", - ' 3 | ', - " 4 | const emailInput = document.getElementById('email');", + 'ERROR in src/model/User.ts 1:22-30', + "TS2307: Cannot find module './Role'.", + " > 1 | import { Role } from './Role';", + ' | ^^^^^^^^', + ' 2 | ', + ' 3 | type User = {', + ' 4 | id: string;', ].join('\n'), ]); // re-create deleted module await sandbox.write( - 'src/authenticate.ts', - [ - "import { User } from './model/User';", - '', - 'async function login(email: string, password: string): Promise {', - ' await fetch(', - " '/login',", - ' {', - " method: 'POST',", - ' body: JSON.stringify({ email, password })', - ' }', - ' );', - '}', - '', - 'async function logout(): Promise {', - ' const response = await fetch(', - " '/logout',", - ' {', - " method: 'POST'", - ' }', - ' );', - ' return response.json();', - '}', - '', - 'export { login, logout };', - ].join('\n') + 'src/model/Role.ts', + ['type Role = "admin" | "client";', '', 'export { Role };'].join('\n') ); - // we should receive again 3 semantic errors + // we should receive again the one semantic error but now for "provider" role errors = await driver.waitForErrors(); expect(errors).toEqual([ [ - 'ERROR in src/index.ts 34:12-16', - "TS2339: Property 'role' does not exist on type 'void'.", + 'ERROR in src/index.ts 34:7-31', + "TS2367: This condition will always return 'false' since the types 'Role' and '\"provider\"' have no overlap.", ' 32 | const user = await login(email, password);', ' 33 | ', - " > 34 | if (user.role === 'admin') {", - ' | ^^^^', - ' 35 | console.log(`Logged in as ${getUserName(user)} [admin].`);', + " > 34 | if (user.role === 'provider') {", + ' | ^^^^^^^^^^^^^^^^^^^^^^^^', + ' 35 | console.log(`Logged in as ${getUserName(user)} [provider].`);', ' 36 | } else {', ' 37 | console.log(`Logged in as ${getUserName(user)}`);', ].join('\n'), - [ - 'ERROR in src/index.ts 35:45-49', - "TS2345: Argument of type 'void' is not assignable to parameter of type 'User'.", - ' 33 | ', - " 34 | if (user.role === 'admin') {", - ' > 35 | console.log(`Logged in as ${getUserName(user)} [admin].`);', - ' | ^^^^', - ' 36 | } else {', - ' 37 | console.log(`Logged in as ${getUserName(user)}`);', - ' 38 | }', - ].join('\n'), - [ - 'ERROR in src/index.ts 37:45-49', - "TS2345: Argument of type 'void' is not assignable to parameter of type 'User'.", - ' 35 | console.log(`Logged in as ${getUserName(user)} [admin].`);', - ' 36 | } else {', - ' > 37 | console.log(`Logged in as ${getUserName(user)}`);', - ' | ^^^^', - ' 38 | }', - ' 39 | });', - ' 40 | ', - ].join('\n'), ]); - }); + } + ); + + it.each([ + { async: true, webpack: '^4.0.0', typescript: '2.7.1', tsloader: '^5.0.0' }, + { async: false, webpack: '^4.0.0', typescript: '~3.0.0', tsloader: '^6.0.0' }, + { async: true, webpack: '^4.0.0', typescript: '~3.6.0', tsloader: '^7.0.0' }, + { async: false, webpack: '^4.0.0', typescript: '~3.8.0', tsloader: '^6.0.0' }, + ])('reports semantic error for %p', async ({ async, webpack, typescript, tsloader }) => { + await sandbox.load( + await readFixture(join(__dirname, 'fixtures/typescript-basic.fixture'), { + FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION: JSON.stringify( + FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION + ), + TS_LOADER_VERSION: JSON.stringify(tsloader), + TYPESCRIPT_VERSION: JSON.stringify(typescript), + WEBPACK_VERSION: JSON.stringify(webpack), + WEBPACK_CLI_VERSION: JSON.stringify(WEBPACK_CLI_VERSION), + WEBPACK_DEV_SERVER_VERSION: JSON.stringify(WEBPACK_DEV_SERVER_VERSION), + ASYNC: JSON.stringify(async), + }) + ); + + const driver = createWebpackDevServerDriver( + sandbox.spawn('./node_modules/.bin/webpack-dev-server'), + async + ); + let errors: string[]; + + // first compilation is successful + await driver.waitForNoErrors(); + + // then we introduce semantic error by removing "firstName" and "lastName" from the User model + await sandbox.patch( + 'src/model/User.ts', + [' firstName?: string;', ' lastName?: string;'].join('\n'), + '' + ); + + // we should receive 2 semantic errors + errors = await driver.waitForErrors(); + expect(errors).toEqual([ + [ + 'ERROR in src/model/User.ts 11:16-25', + "TS2339: Property 'firstName' does not exist on type 'User'.", + ' 9 | ', + ' 10 | function getUserName(user: User): string {', + ' > 11 | return [user.firstName, user.lastName]', + ' | ^^^^^^^^^', + ' 12 | .filter(name => name !== undefined)', + " 13 | .join(' ');", + ' 14 | }', + ].join('\n'), + [ + 'ERROR in src/model/User.ts 11:32-40', + "TS2339: Property 'lastName' does not exist on type 'User'.", + ' 9 | ', + ' 10 | function getUserName(user: User): string {', + ' > 11 | return [user.firstName, user.lastName]', + ' | ^^^^^^^^', + ' 12 | .filter(name => name !== undefined)', + " 13 | .join(' ');", + ' 14 | }', + ].join('\n'), + ]); + + // fix the semantic error + await sandbox.patch( + 'src/model/User.ts', + [ + ' return [user.firstName, user.lastName]', + ' .filter(name => name !== undefined)', + " .join(' ');", + ].join('\n'), + ` return user.email;` + ); + + await driver.waitForNoErrors(); + + // delete module to trigger another error + await sandbox.remove('src/authenticate.ts'); + + errors = await driver.waitForErrors(); + expect(errors).toEqual([ + [ + 'ERROR in src/index.ts 1:23-39', + "TS2307: Cannot find module './authenticate'.", + " > 1 | import { login } from './authenticate';", + ' | ^^^^^^^^^^^^^^^^', + " 2 | import { getUserName } from './model/User';", + ' 3 | ', + " 4 | const emailInput = document.getElementById('email');", + ].join('\n'), + ]); + + // re-create deleted module + await sandbox.write( + 'src/authenticate.ts', + [ + "import { User } from './model/User';", + '', + 'async function login(email: string, password: string): Promise {', + ' await fetch(', + " '/login',", + ' {', + " method: 'POST',", + ' body: JSON.stringify({ email, password })', + ' }', + ' );', + '}', + '', + 'async function logout(): Promise {', + ' const response = await fetch(', + " '/logout',", + ' {', + " method: 'POST'", + ' }', + ' );', + ' return response.json();', + '}', + '', + 'export { login, logout };', + ].join('\n') + ); + + // we should receive again 3 semantic errors + errors = await driver.waitForErrors(); + expect(errors).toEqual([ + [ + 'ERROR in src/index.ts 34:12-16', + "TS2339: Property 'role' does not exist on type 'void'.", + ' 32 | const user = await login(email, password);', + ' 33 | ', + " > 34 | if (user.role === 'admin') {", + ' | ^^^^', + ' 35 | console.log(`Logged in as ${getUserName(user)} [admin].`);', + ' 36 | } else {', + ' 37 | console.log(`Logged in as ${getUserName(user)}`);', + ].join('\n'), + [ + 'ERROR in src/index.ts 35:45-49', + "TS2345: Argument of type 'void' is not assignable to parameter of type 'User'.", + ' 33 | ', + " 34 | if (user.role === 'admin') {", + ' > 35 | console.log(`Logged in as ${getUserName(user)} [admin].`);', + ' | ^^^^', + ' 36 | } else {', + ' 37 | console.log(`Logged in as ${getUserName(user)}`);', + ' 38 | }', + ].join('\n'), + [ + 'ERROR in src/index.ts 37:45-49', + "TS2345: Argument of type 'void' is not assignable to parameter of type 'User'.", + ' 35 | console.log(`Logged in as ${getUserName(user)} [admin].`);', + ' 36 | } else {', + ' > 37 | console.log(`Logged in as ${getUserName(user)}`);', + ' | ^^^^', + ' 38 | }', + ' 39 | });', + ' 40 | ', + ].join('\n'), + ]); }); }); diff --git a/test/e2e/fixtures/typescript-pnp.fixture b/test/e2e/fixtures/typescript-pnp.fixture new file mode 100644 index 00000000..0855cf89 --- /dev/null +++ b/test/e2e/fixtures/typescript-pnp.fixture @@ -0,0 +1,180 @@ +/// package.json +{ + "name": "typescript-basic-fixture", + "version": "1.0.0", + "main": "dist/index.js", + "license": "MIT", + "scripts": { + "webpack-dev-server": "webpack-dev-server" + }, + "devDependencies": { + "fork-ts-checker-webpack-plugin": ${FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION}, + "pnp-webpack-plugin": "^1.6.4", + "ts-loader": ${TS_LOADER_VERSION}, + "ts-pnp": "^1.2.0", + "typescript": ${TYPESCRIPT_VERSION}, + "webpack": ${WEBPACK_VERSION}, + "webpack-cli": ${WEBPACK_CLI_VERSION}, + "webpack-dev-server": ${WEBPACK_DEV_SERVER_VERSION} + }, + "installConfig": { + "pnp": true + } +} +/// tsconfig.json +{ + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "lib": ["ES6", "DOM"], + "moduleResolution": "node", + "esModuleInterop": true, + "skipLibCheck": true, + "skipDefaultLibCheck": true, + "strict": true, + "baseUrl": "./src", + "outDir": "./dist" + }, + "include": ["./src"], + "exclude": ["node_modules"] +} +/// webpack.config.js +const path = require('path'); +const PnpWebpackPlugin = require(`pnp-webpack-plugin`); +const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); + +module.exports = { + entry: './src/index.ts', + output: { + filename: 'index.js', + path: path.resolve(__dirname, 'dist'), + }, + module: { + rules: [ + { + test: /\.tsx?$/, + loader: 'ts-loader', + exclude: /node_modules/, + options: { + ...PnpWebpackPlugin.tsLoaderOptions(), + transpileOnly: true + } + }, + ], + }, + resolve: { + extensions: ['.tsx', '.ts', '.js'], + plugins: [ + PnpWebpackPlugin, + ] + }, + resolveLoader: { + plugins: [ + PnpWebpackPlugin.moduleLoader(module), + ], + }, + plugins: [ + new ForkTsCheckerWebpackPlugin({ + async: ${ASYNC}, + typescript: { + extensions: { + pnp: true + } + }, + logger: { + infrastructure: "console" + } + }) + ] +}; + +/// src/index.ts +import { login } from './authenticate'; +import { getUserName } from './model/User'; + +const emailInput = document.getElementById('email'); +const passwordInput = document.getElementById('password'); +const loginForm = document.getElementById('login'); + +if (!emailInput) { + throw new Error("Cannot find #email input."); +} +if (!passwordInput) { + throw new Error("Cannot find #password input."); +} +if (!loginForm) { + throw new Error("Cannot find #login form."); +} + +let email = ''; +let password = ''; + +emailInput.addEventListener('change', event => { + if (event.target instanceof HTMLInputElement) { + email = event.target.value; + } +}); +passwordInput.addEventListener('change', event => { + if (event.target instanceof HTMLInputElement) { + password = event.target.value; + } +}); +loginForm.addEventListener('submit', async event => { + const user = await login(email, password); + + if (user.role === 'admin') { + console.log(`Logged in as ${getUserName(user)} [admin].`); + } else { + console.log(`Logged in as ${getUserName(user)}`); + } +}); + +/// src/authenticate.ts +import { User } from './model/User'; + +async function login(email: string, password: string): Promise { + const response = await fetch( + '/login', + { + method: 'POST', + body: JSON.stringify({ email, password }) + } + ); + return response.json(); +} + +async function logout(): Promise { + const response = await fetch( + '/logout', + { + method: 'POST' + } + ); + return response.json(); +} + +export { login, logout }; + +/// src/model/User.ts +import { Role } from './Role'; + +type User = { + id: string; + email: string; + role: Role; + firstName?: string; + lastName?: string; +} + +function getUserName(user: User): string { + return [user.firstName, user.lastName] + .filter(name => name !== undefined) + .join(' '); +} + +export { User, getUserName }; + +/// src/model/Role.ts +type Role = "admin" | "client" | "provider"; + +export { Role }; diff --git a/test/e2e/fixtures/typescript-vue.fixture b/test/e2e/fixtures/typescript-vue.fixture new file mode 100644 index 00000000..301fa3fe --- /dev/null +++ b/test/e2e/fixtures/typescript-vue.fixture @@ -0,0 +1,258 @@ +/// package.json +{ + "name": "typescript-vue-fixture", + "version": "1.0.0", + "main": "dist/index.js", + "license": "MIT", + "dependencies": { + "vue": "^2.6.11", + "vue-class-component": "^7.2.2" + }, + "devDependencies": { + "css-loader": "^3.4.2", + "fork-ts-checker-webpack-plugin": ${FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION}, + "ts-loader": ${TS_LOADER_VERSION}, + "typescript": ${TYPESCRIPT_VERSION}, + "vue-loader": "^15.8.3", + "vue-template-compiler": "^2.6.11", + "webpack": ${WEBPACK_VERSION}, + "webpack-cli": ${WEBPACK_CLI_VERSION}, + "webpack-dev-server": ${WEBPACK_DEV_SERVER_VERSION} + } +} +/// tsconfig.json +{ + "compilerOptions": { + "experimentalDecorators": true, + "jsx": "preserve", + "target": "ES5", + "lib": ["ES6", "DOM"], + "baseUrl": ".", + "paths": { + "@/*": ["src/*"], + "~/*": ["src/*"] + }, + "sourceMap": true + }, + "include": [ + "src/**/*.ts", + "src/**/*.vue" + ], + "exclude": [ + "node_modules" + ] +} + +/// webpack.config.js +const path = require('path'); +const VueLoaderPlugin = require('vue-loader/lib/plugin'); +const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); + +module.exports = { + entry: './src/index.ts', + output: { + filename: 'index.js', + path: path.resolve(__dirname, 'dist'), + }, + module: { + rules: [ + { + test: /\.vue$/, + loader: 'vue-loader' + }, + { + test: /\.ts$/, + loader: 'ts-loader', + exclude: /node_modules/, + options: { + appendTsSuffixTo: [/\.vue$/] + } + }, + ], + }, + resolve: { + extensions: ['.ts', '.js', '.vue', '.json'], + alias: { + '@': path.resolve(__dirname, './src'), + '~': path.resolve(__dirname, './src'), + } + }, + plugins: [ + new VueLoaderPlugin(), + new ForkTsCheckerWebpackPlugin({ + async: ${ASYNC}, + typescript: { + extensions: { + vue: true + } + }, + logger: { + infrastructure: "console" + } + }) + ] +}; + +/// src/index.ts +import Vue from 'vue' +import App from './App.vue' + +new Vue({ + render: h => h(App) +}).$mount('#app') + +/// src/App.vue + + + + +/// src/component/LoginForm.vue + + + + + + +/// src/component/LoggedIn.vue + + + + + + +/// src/model/User.ts +import Role from './Role'; + +type User = { + id: string; + email: string; + role: Role; + firstName?: string; + lastName?: string; +} + +function getUserName(user: User): string { + return [user.firstName, user.lastName] + .filter(name => name !== undefined) + .join(' '); +} + +export default User; +export { getUserName }; + +/// src/model/Role.ts +type Role = "admin" | "client" | "provider"; + +export default Role; diff --git a/test/e2e/sandbox/Sandbox.ts b/test/e2e/sandbox/Sandbox.ts index 88cbf666..35bed731 100644 --- a/test/e2e/sandbox/Sandbox.ts +++ b/test/e2e/sandbox/Sandbox.ts @@ -9,7 +9,7 @@ import kill from 'tree-kill'; interface Sandbox { context: string; - load: (fixture: Fixture) => Promise; + load: (fixture: Fixture, installer?: (sandbox: Sandbox) => Promise) => Promise; reset: () => Promise; cleanup: () => Promise; write: (path: string, content: string) => Promise; @@ -52,6 +52,24 @@ async function retry(effect: () => Promise, retries = 3, delay = 250): Pro // create cache directory to speed-up the testing const CACHE_DIR = fs.mkdtempSync(join(os.tmpdir(), 'fork-ts-checker-cache-')); const NPM_CACHE_DIR = join(CACHE_DIR, 'npm'); +const YARN_CACHE_DIR = join(CACHE_DIR, 'yarn'); + +async function npmInstaller(sandbox: Sandbox) { + await retry(() => + sandbox.exec('npm install', { + // eslint-disable-next-line @typescript-eslint/camelcase + npm_config_cache: NPM_CACHE_DIR, + }) + ); +} + +async function yarnInstaller(sandbox: Sandbox) { + await retry(() => + sandbox.exec('yarn install', { + YARN_CACHE_FOLDER: YARN_CACHE_DIR, + }) + ); +} async function createSandbox(): Promise { const context = await fs.mkdtemp(join(os.tmpdir(), 'fork-ts-checker-sandbox-')); @@ -98,19 +116,13 @@ async function createSandbox(): Promise { const sandbox: Sandbox = { context, - load: async (fixture) => { + load: async (fixture, installer = npmInstaller) => { // write files await Promise.all(Object.keys(fixture).map((path) => sandbox.write(path, fixture[path]))); process.stdout.write('Fixture initialized.\n'); process.stdout.write('Installing dependencies...\n'); - - await retry(() => - sandbox.exec('npm install', { - // eslint-disable-next-line @typescript-eslint/camelcase - npm_config_cache: NPM_CACHE_DIR, - }) - ); + await installer(sandbox); process.stdout.write('The sandbox initialized successfully.\n'); createdFiles = []; @@ -260,4 +272,12 @@ if (!fs.pathExistsSync(FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION)) { ); } -export { Sandbox, createSandbox, FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION }; +export { + Sandbox, + createSandbox, + npmInstaller, + yarnInstaller, + NPM_CACHE_DIR, + YARN_CACHE_DIR, + FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION, +}; From 3eb48e8465a3762c5adcb996e739818141778818 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ole=C5=9B?= Date: Thu, 21 May 2020 15:54:35 +0200 Subject: [PATCH 19/29] docs: update README.md to reflect new API --- README.md | 487 +++++++----------- src/ForkTsCheckerWebpackPlugin.ts | 7 - ...ForkTsCheckerWebpackPluginConfiguration.ts | 6 +- src/ForkTsCheckerWebpackPluginState.ts | 6 +- src/error/OperationCanceledError.ts | 5 + src/error/OperationCancelledError.ts | 5 - src/formatter/FormatterConfiguration.ts | 6 +- src/formatter/FormatterFactory.ts | 10 +- src/formatter/FormatterOptions.ts | 3 +- src/hooks/pluginHooks.ts | 16 +- src/hooks/tapAfterCompileToGetIssues.ts | 4 +- src/hooks/tapDoneToAsyncGetIssues.ts | 4 +- src/hooks/tapStartToConnectAndRunReporter.ts | 68 ++- src/hooks/tapStopToDisconnectReporter.ts | 2 +- src/issue/IssueMatch.ts | 4 +- src/reporter/AggregatedReporter.ts | 4 +- test/e2e/fixtures/typescript-pnp.fixture | 5 +- .../formatter/FormatterConfiguration.spec.ts | 5 +- test/unit/formatter/FormatterFactory.spec.ts | 9 +- 19 files changed, 254 insertions(+), 402 deletions(-) create mode 100644 src/error/OperationCanceledError.ts delete mode 100644 src/error/OperationCancelledError.ts diff --git a/README.md b/README.md index 3105eb1a..c0be2c1d 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,6 @@

Webpack plugin that runs TypeScript type checker on a separate process.

[![npm version](https://img.shields.io/npm/v/fork-ts-checker-webpack-plugin.svg)](https://www.npmjs.com/package/fork-ts-checker-webpack-plugin) -[![npm beta version](https://img.shields.io/npm/v/fork-ts-checker-webpack-plugin/beta.svg)](https://www.npmjs.com/package/fork-ts-checker-webpack-plugin) [![build status](https://github.com/TypeStrong/fork-ts-checker-webpack-plugin/workflows/CI/CD/badge.svg?branch=master&event=push)](https://github.com/TypeStrong/fork-ts-checker-webpack-plugin/actions?query=branch%3Amaster+event%3Apush) [![downloads](http://img.shields.io/npm/dm/fork-ts-checker-webpack-plugin.svg)](https://npmjs.org/package/fork-ts-checker-webpack-plugin) [![commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/) @@ -13,12 +12,19 @@ -## Installation +## Features + + * Faster [TypeScript](https://github.com/Microsoft/TypeScript) type checking and [ESLint](https://eslint.org/) linting (each on a separate process) ๐ŸŽ + * Support for modern TypeScript features like [project references](https://www.typescriptlang.org/docs/handbook/project-references.html) and [incremental mode](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#faster-subsequent-builds-with-the---incremental-flag) โœจ + * Support for [Yarn PnP](https://classic.yarnpkg.com/en/docs/pnp/) ๐Ÿงถ + * Nice errors reporting with the [code frame](https://babeljs.io/docs/en/next/babel-code-frame.html) formatter ๐ŸŒˆ -This plugin requires minimum **Node.js 6.11.5**, **webpack 4**, **TypeScript 2.1** and optionally **ESLint 6** (which itself requires minimum **Node.js 8.10.0**) +## Installation -If you depend on **webpack 2**, **webpack 3**, or **tslint 4**, please use [older version](https://github.com/TypeStrong/fork-ts-checker-webpack-plugin/tree/v3.1.1) of the plugin. +This plugin requires minimum **Node.js 10**, **Webpack 4**, **TypeScript 2.7** and optionally **ESLint 6** +* If you depend on **Webpack 2**, **Webpack 3**, or **TSLint 4**, please use [version 3](https://github.com/TypeStrong/fork-ts-checker-webpack-plugin/tree/v3.1.1) of the plugin. +* If you depend on **TypeScript >= 2.1** and **< 2.7** or you can't update to **Node 10**, please use [version 4](https://github.com/TypeStrong/fork-ts-checker-webpack-plugin/tree/v4.1.4) of the plugin. ```sh # with npm npm install --save-dev fork-ts-checker-webpack-plugin @@ -27,14 +33,18 @@ npm install --save-dev fork-ts-checker-webpack-plugin yarn add --dev fork-ts-checker-webpack-plugin ``` -Basic webpack config (with [ts-loader](https://github.com/TypeStrong/ts-loader)) +The minimal webpack config (with [ts-loader](https://github.com/TypeStrong/ts-loader)) ```js +// webpack.config.js const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); -const webpackConfig = { +module.exports = { context: __dirname, // to automatically find tsconfig.json entry: './src/index.ts', + resolve: { + extensions: [".ts", ".tsx", ".js"], + }, module: { rules: [ { @@ -51,379 +61,232 @@ const webpackConfig = { }; ``` -## Motivation - -There was already similar solution - [awesome-typescript-loader](https://github.com/s-panferov/awesome-typescript-loader). You can -add `CheckerPlugin` and delegate checker to the separate process. The problem with `awesome-typescript-loader` was that, in our case, -it was a lot slower than [ts-loader](https://github.com/TypeStrong/ts-loader) on an incremental build (~20s vs ~3s). -Secondly, we used [tslint](https://palantir.github.io/tslint) and we wanted to run this, along with type checker, in a separate process. -This is why this plugin was created. To provide better performance, the plugin reuses Abstract Syntax Trees between compilations and shares -these trees with TSLint. +If you are using **TypeScript >= 2.8.0**, it's recommended to set `"importsNotUsedAsValues": "preserve"` [compiler option](https://www.typescriptlang.org/docs/handbook/compiler-options.html) +in the `tsconfig.json`. [Here is an explanation.](#type-only-modules-watching) ## Modules resolution It's very important to be aware that **this plugin uses [TypeScript](https://github.com/Microsoft/TypeScript)'s, not -[webpack](https://github.com/webpack/webpack)'s modules resolution**. It means that you have to setup `tsconfig.json` correctly. For example -if you set `files: ['./src/someFile.ts']` in `tsconfig.json`, this plugin will check only `someFile.ts` for semantic errors. It's because -of performance. The goal of this plugin is to be _as fast as possible_. With TypeScript's module resolution we don't have to wait for webpack -to compile files (which traverses dependency graph during compilation) - we have a full list of files from the begin. +[webpack](https://github.com/webpack/webpack)'s modules resolution**. It means that you have to setup `tsconfig.json` correctly. +For example if you set `files: ['./src/index.ts']` in `tsconfig.json`, this plugin will check only `index.ts` for errors. -To debug TypeScript's modules resolution, you can use `tsc --traceResolution` command. +> It's because of the performance - with TypeScript's module resolution we don't have to wait for webpack to compile files. +> +> To debug TypeScript's modules resolution, you can use `tsc --traceResolution` command. ## ESLint -[ESLint is the future of linting in the TypeScript world.](https://eslint.org/blog/2019/01/future-typescript-eslint) If you'd like to use eslint with the plugin, supply this option: `eslint: true` and ensure you have the relevant dependencies installed: +If you'd like to use ESLint with the plugin, ensure you have the relevant dependencies installed: + +```sh +# with npm +npm install --save-dev eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin + +# with yarn +yarn add --dev eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin +``` + +Then set up ESLint in the plugin. This is the minimal configuration: +```js +// webpack.config.js +const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); -`yarn add eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin --dev` +module.exports = { + // ...the webpack configuration + plugins: [ + new ForkTsCheckerWebpackPlugin({ + eslint: { + files: './src/**/*.ts' // required - same as command `eslint ./src/**/*.ts` + } + }) + ] +}; +``` -You should have an ESLint configuration file in your root project directory. Here is a sample `.eslintrc.js` configuration for a TypeScript project: +You should also have an ESLint configuration file in your root project directory. +Here is a sample `.eslintrc.js` configuration for a TypeScript project: ```js const path = require('path'); + module.exports = { - parser: '@typescript-eslint/parser', // Specifies the ESLint parser + parser: '@typescript-eslint/parser', // specifies the ESLint parser extends: [ - 'plugin:@typescript-eslint/recommended' // Uses the recommended rules from the @typescript-eslint/eslint-plugin + 'plugin:@typescript-eslint/recommended' // uses the recommended rules from the @typescript-eslint/eslint-plugin ], parserOptions: { project: path.resolve(__dirname, './tsconfig.json'), tsconfigRootDir: __dirname, - ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features - sourceType: 'module', // Allows for the use of imports + ecmaVersion: 2018, // allows for the parsing of modern ECMAScript features + sourceType: 'module', // allows for the use of imports }, rules: { - // Place to specify ESLint rules. Can be used to overwrite rules specified from the extended configs + // place to specify ESLint rules - can be used to overwrite rules specified from the extended configs // e.g. "@typescript-eslint/explicit-function-return-type": "off", } }; ``` -There's a good explanation on setting up TypeScript ESLint support by Robert Cooper [here](https://dev.to/robertcoopercode/using-eslint-and-prettier-in-a-typescript-project-53jb). +There's a [good explanation on setting up TypeScript ESLint support by Robert Cooper](https://dev.to/robertcoopercode/using-eslint-and-prettier-in-a-typescript-project-53jb). ## Options -- **tsconfig** `string`: - Path to _tsconfig.json_ file. Default: `path.resolve(compiler.options.context, './tsconfig.json')`. - -- **compilerOptions** `object`: - Allows overriding TypeScript options. Should be specified in the same format as you would do for the `compilerOptions` property in tsconfig.json. Default: `{}`. - -- **eslint** `true | undefined`: +The top-level plugin options. - - If `true`, this activates eslint support. +| Name | Type | Default value | Description | +| ----------------- | --------------------- | ------------------------------------------------ | ----------- | +| `async` | `boolean` | `compiler.options.mode === 'development'` | If `true`, reports issues **after** webpack's compilation is done. Thanks to that it doesn't block the compilation. Used only in the `watch` mode. | +| `typescript` | `object` or `boolean` | `true` | If a `boolean`, it enables/disables TypeScript checker. If an `object`, see [TypeScript options](#typescript-options). | +| `eslint` | `object` | `undefined` | If `undefined`, it disables ESLint linter. If an `object`, see [ESLint options](#eslint-options). | +| `issue` | `object` | `{}` | See [Issues options](#issues-options). | +| `formatter` | `string` or `object` | `codeframe` | Available formatters are `basic` and `codeframe`. To [configure](https://babeljs.io/docs/en/babel-code-frame#options) `codeframe` formatter, pass object: `{ type: 'codeframe', options: { } }`. | +| `logger` | `object` | `{ infastructure: 'silent', issues: 'console' }` | Available loggers are `silent`, `console`, and `webpack-infrastructure`. Infrastructure logger prints additional information, issue logger prints `issues` in the `async` mode. | -- **eslintOptions** `object`: +### TypeScript options - - Options that can be used to initialise ESLint. See https://eslint.org/docs/developer-guide/nodejs-api#cliengine - -- **async** `boolean`: - True by default - `async: false` can block webpack's emit to wait for type checker/linter and to add errors to the webpack's compilation. - We recommend to set this to `false` in projects where type checking is faster than webpack's build - it's better for integration with other plugins. Another scenario where you might want to set this to `false` is if you use the `overlay` functionality of `webpack-dev-server`. +Options for the TypeScript checker (`typescript` option object). -- **ignoreDiagnostics** `number[]`: - List of TypeScript diagnostic codes to ignore. +| Name | Type | Default value | Description | +| -------------------- | --------- | ------------------------------------------------------------------------- | ----------- | +| `enabled` | `boolean` | `true` | If `true`, it enables TypeScript checker. | +| `memoryLimit` | `number` | `2048` | Memory limit for the checker process in MB. If the process exits with the allocation failed error, try to increase this number. | +| `tsconfig` | `string` | `'tsconfig.json'` | Path to the `tsconfig.json` file (path relative to the `compiler.options.context` or absolute path) | +| `build` | `boolean` | `false` | The equivalent of the `--build` flag for the `tsc` command. | +| `compilerOptions` | `object` | `{}` | These options will overwrite compiler options from the `tsconfig.json` file. | +| `diagnosticsOptions` | `object` | `{ syntactic: false, semantic: true, declaration: false, global: false }` | Settings to select which diagnostics do we want to perform. | +| `extensions` | `object` | `{}` | See [TypeScript extensions options](#typescript-extensions-options). | -- **ignoreLints** `string[]`: - List of eslint rule names to ignore. +#### TypeScript extensions options -- **ignoreLintWarnings** `boolean`: - If true, will ignore all lint warnings. +Options for the TypeScript checker extensions (`typescript.extensions` option object). -- **reportFiles** `string[]`: - Only report errors on files matching these glob patterns. This can be useful when certain types definitions have errors that are not fatal to your application. Default: `[]`. Please note that this may behave unexpectedly if using the incremental API as the incremental API doesn't look for global and semantic errors [if it has already found syntactic errors](https://github.com/Microsoft/TypeScript/blob/89386ddda7dafc63cb35560e05412487f47cc267/src/compiler/watch.ts#L141). +| Name | Type | Default value | Description | +| -------------------- | --------------------- | ------------------------- | ----------- | +| `pnp` | `boolean` | `false` | If `true`, it enables Yarn PnP support (requires [`ts-pnp`](https://github.com/arcanis/ts-pnp) package to be installed). | +| `vue` | `object` or `boolean` | `false` | If `true`, it enables Vue [Single File Component](https://vuejs.org/v2/guide/single-file-components.html) support. | +| `vue.enabled` | `boolean` | `false` | Same as the `vue` option | +| `vue.compiler` | `string` | `'vue-template-compiler'` | The package name of the compiler that will be used to parse `.vue` files. You can use `'nativescript-vue-template-compiler'` if you use [nativescript-vue](https://github.com/nativescript-vue/nativescript-vue) | -```js -// in webpack.config.js -new ForkTsCheckerWebpackPlugin({ - reportFiles: ['src/**/*.{ts,tsx}', '!src/skip.ts'] -}); -``` +### ESLint options -- **logger** `object`: - Logger instance. It should be object that implements method: `error`, `warn`, `info`. Default: `console`. +Options for the ESLint linter (`eslint` option object). -- **formatter** `'default' | 'codeframe' | (issue: Issue) => string)`: - Formatter for issues and lints. By default uses `default` formatter. You can also pass your own formatter as a function - (see `src/issue/` and `src/formatter/` for API reference). +| Name | Type | Default value | Description | +| -------------------- | ---------------------- | ------------------------- | ----------- | +| `enabled` | `boolean` | `true` | If `true`, it enables ESLint linter. | +| `files` | `string` or `string[]` | This value is required | One or more [glob patterns](https://en.wikipedia.org/wiki/Glob_(programming)) to the files that should be linted. Works the same as the `eslint` command. | +| `memoryLimit` | `number` | `2048` | Memory limit for the linter process in MB. If the process exits with the allocation failed error, try to increase this number. | +| `options` | `object` | `{}` | [Options](https://eslint.org/docs/developer-guide/nodejs-api#cliengine) that can be used to initialize ESLint. | -- **formatterOptions** `object`: - Options passed to formatters (currently only `codeframe` - see [available options](https://babeljs.io/docs/en/next/babel-code-frame.html#options)) +### Issues options -- **silent** `boolean`: - If `true`, logger will not be used. Default: `false`. +Options for the issues filtering (`issues` option object). -- **checkSyntacticErrors** `boolean`: - This option is useful if you're using ts-loader in `happyPackMode` with [HappyPack](https://github.com/amireh/happypack) or [thread-loader](https://github.com/webpack-contrib/thread-loader) to parallelise your builds. If `true` it will ensure that the plugin checks for _both_ syntactic errors (eg `const array = [{} {}];`) and semantic errors (eg `const x: number = '1';`). By default the plugin only checks for semantic errors. This is because when ts-loader is used in `transpileOnly` mode, ts-loader will still report syntactic errors. When used in `happyPackMode` it does not. Default: `false`. +| Name | Type | Default value | Description | +| --------- | --------------------------------- | ------------- | ----------- | +| `include` | `object` or `function` or `array` | `undefined` | If `object`, defines issue properties that should be [matched](./src/issue/IssueMatch.ts). If `function`, acts as a predicate where `issue` is an argument. | +| `exclude` | `object` or `function` or `array` | `undefined` | Same as `include` but issues that match this predicate will be excluded. | -- **memoryLimit** `number`: - Memory limit for service process in MB. If service exits with allocation failed error, increase this number. Default: `2048`. +## Yarn PnP -- **vue** `boolean | { enabled: boolean, compiler: string }`: - If `true` or `enabled: true`, the linter and compiler will process VueJs single-file-component (.vue) files. See the - [Vue section](https://github.com/TypeStrong/fork-ts-checker-webpack-plugin#vue) further down for information on how to correctly setup your project. +To enable Yarn PnP, you have to install [`ts-pnp`](https://github.com/arcanis/ts-pnp) and [`pnp-webpack-plugin`](https://github.com/arcanis/pnp-webpack-plugin) package: -- **useTypescriptIncrementalApi** `boolean`: - If true, the plugin will use incremental compilation API introduced in TypeScript 2.7. Defaults to `true` when working with TypeScript 3+ and `false` when below 3. The default can be overridden by directly specifying a value. - Don't use it together with VueJs enabled - it's not supported yet. - -- **measureCompilationTime** `boolean`: - If true, the plugin will measure the time spent inside the compilation code. This may be useful to compare modes, - especially if there are other loaders/plugins involved in the compilation. **requires Node.js >= 8.5.0** - -- **typescript** `string`: - If supplied this is a custom path where `typescript` can be found. Defaults to `require.resolve('typescript')`. - -- **resolveModuleNameModule** and **resolveTypeReferenceDirectiveModule** `string`: - Both of those options refer to files on the disk that respectively export a `resolveModuleName` or a `resolveTypeReferenceDirectiveModule` function. These functions will be used to resolve the import statements and the `` directives instead of the default TypeScript implementation. Check the following code for an example of what those functions should look like: - -
- Code sample - - ```js - const { resolveModuleName } = require(`ts-pnp`); - - exports.resolveModuleName = ( - typescript, - moduleName, - containingFile, - compilerOptions, - resolutionHost - ) => { - return resolveModuleName( - moduleName, - containingFile, - compilerOptions, - resolutionHost, - typescript.resolveModuleName - ); - }; - - exports.resolveTypeReferenceDirective = ( - typescript, - moduleName, - containingFile, - compilerOptions, - resolutionHost - ) => { - return resolveModuleName( - moduleName, - containingFile, - compilerOptions, - resolutionHost, - typescript.resolveTypeReferenceDirective - ); - }; - ``` - -
- -## Different behaviour in watch mode - -If you turn on [webpacks watch mode](https://webpack.js.org/configuration/watch/#watch) the `fork-ts-checker-notifier-webpack-plugin` will take care of logging type errors, _not_ webpack itself. That means if you set `silent: true` you won't see type errors in your console in watch mode. - -You can either set `silent: false` to show the logging from `fork-ts-checker-notifier-webpack-plugin` _or_ set `async: false`. Now webpack itself will log type errors again, but note that this can slow down your builds depending on the size of your project. - -## Notifier - -You may already be using the excellent [webpack-notifier](https://github.com/Turbo87/webpack-notifier) plugin to make build failures more obvious in the form of system notifications. There's an equivalent notifier plugin designed to work with the `fork-ts-checker-webpack-plugin`. It is the `fork-ts-checker-notifier-webpack-plugin` and can be found [here](https://github.com/johnnyreilly/fork-ts-checker-notifier-webpack-plugin). This notifier deliberately has a similar API as the `webpack-notifier` plugin to make migration easier. - -## Known Issue Watching Non-Emitting Files - -At present there is an issue with the plugin regarding the triggering of type-checking when a change is made in a source file that will not emit js. If you have a file which contains only `interface`s and / or `type`s then changes to it will **not** trigger the type checker whilst in watch mode. Sorry about that. - -We hope this will be resolved in future; the issue can be tracked [here](https://github.com/TypeStrong/fork-ts-checker-webpack-plugin/issues/36). - -## Plugin Hooks - -This plugin provides some custom webpack hooks (all are sync): - -| Hook Access Key | Description | Params | -| -------------------- | ------------------------------------------------------------------------------ | --------------------------------- | -| `cancel` | Cancellation has been requested | `cancellationToken` | -| `waiting` | Waiting for results | - | -| `serviceBeforeStart` | Async plugin that can be used for delaying `fork-ts-checker-service-start` | - | -| `serviceStart` | Service will be started | `tsconfigPath`, `memoryLimit` | -| `serviceStartError` | Cannot start service | `error` | -| `serviceOutOfMemory` | Service is out of memory | - | -| `receive` | Plugin receives diagnostics and lints from service | `diagnostics`, `lints` | -| `emit` | Service will add errors and warnings to webpack compilation ('build' mode) | `diagnostics`, `lints`, `elapsed` | -| `done` | Service finished type checking and webpack finished compilation ('watch' mode) | `diagnostics`, `lints`, `elapsed` | - -### Accessing plugin hooks - -To access plugin hooks and tap into the event, we need to use -the `getCompilerHooks` static method. When we call this method with a [webpack compiler instance](https://webpack.js.org/api/node/), -it returns the series of [tapable](https://github.com/webpack/tapable) -hooks where you can pass in your callbacks. +```sh +# with npm +npm install --save-dev ts-pnp pnp-webpack-plugin -```js -// require the plugin -const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); -// setup compiler with the plugin -const compiler = webpack({ - // .. webpack config -}); -// Optionally add the plugin to the compiler -// **Don't do this if already added through configuration** -new ForkTsCheckerWebpackPlugin({ - silent: true, - async: true -}).apply(compiler); -// Now get the plugin hooks from compiler -const tsCheckerHooks = ForkTsCheckerWebpackPlugin.getCompilerHooks(compiler); -// These hooks provide access to different events -// =================================================== // -// The properties of tsCheckerHooks corresponds to the // -// Hook Access Key of the table above. // -// =================================================== // -// Example, if we want to run some code when plugin has received diagnostics -// and lint -tsCheckerHooks.receive.tap('yourListenerName', (diagnostics, lint) => { - // do something with diagnostics, perhaps show custom message - console.log(diagnostics); -}); -// Say we want to show some message when plugin is waiting for typecheck results -tsCheckerHooks.waiting.tap('yourListenerName', () => { - console.log('waiting for typecheck results'); -}); +# with yarn +yarn add --dev ts-pnp pnp-webpack-plugin ``` -Calling `.tap()` on any hooks, requires two arguments. - -##### `name` (`string`) - -The first argument passed to `.tap` is the name of your listener callback (`yourListenerName`). -It doesn't need to correspond to anything special. It is intended to be used -[internally](https://github.com/webpack/tapable#interception) as the `name` of -the hook. - -##### `callback` (`function`) - -The second argument is the callback function. Depending on the hook you are -tapping into, several arguments are passed to the function. Do check the table -above to find out which arguments are passed to which hooks. - -### Accessing hooks on Webpack Multi-Compiler instance - -The above method will not work on webpack [multi compiler](https://webpack.js.org/api/node/#multicompiler) -instance. The reason is `getCompilerHooks` expects (at lease as of now) the same -compiler instance to be passed where the plugin was attached. So in case of -multi compiler, we need to access individual compiler instances. - +Then you have to enable it in the configuration: ```js +// webpack.config.js const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); -// setup multi compiler with the plugin -const compiler = webpack([ - { - // .. webpack config +const PnpWebpackPlugin = require(`pnp-webpack-plugin`); + +module.exports = { + context: __dirname, + entry: './src/index.ts', + module: { + rules: [ + { + test: /\.tsx?$/, + loader: 'ts-loader', + options: PnpWebpackPlugin.tsLoaderOptions({ + transpileOnly: true + }) + } + ] }, - { - // .. webpack config - } -]); - -// safely determine if instance is multi-compiler -if ('compilers' in compiler) { - compiler.compilers.forEach(singleCompiler => { - // get plugin hooks from the single compiler instance - const tsCheckerHooks = ForkTsCheckerWebpackPlugin.getCompilerHooks( - singleCompiler - ); - // now access hooks just like before - tsCheckerHooks.waiting.tap('yourListenerName', () => { - console.log('waiting for typecheck results'); - }); - }); -} + resolve: { + extensions: [".ts", ".tsx", ".js"], + plugins: [PnpWebpackPlugin] + }, + resolveLoader: { + plugins: [PnpWebpackPlugin.moduleLoader(module)], + }, + plugins: [ + new ForkTsCheckerWebpackPlugin({ + typescript: { + extensions: { + pnp: true + } + } + }) + ] +}; ``` -## Vue +## Type-Only modules watching -1. Turn on the vue option in the plugin in your webpack config: +At present there is an issue with the `transpileOnly` mode regarding the triggering of type-checking when a change is made in a source file that will not emit js. +If you have a file that contains only `interface`s and/or `type`s then, by default, changes to it will **not** trigger the type checker whilst in watch mode. -```js -new ForkTsCheckerWebpackPlugin({ - vue: true -}); -``` -Optionally change default [vue-template-compiler](https://github.com/vuejs/vue/tree/dev/packages/vue-template-compiler) to [nativescript-vue-template-compiler](https://github.com/nativescript-vue/nativescript-vue/tree/master/packages/nativescript-vue-template-compiler) if you use [nativescript-vue](https://github.com/nativescript-vue/nativescript-vue) -``` -new ForkTsCheckerWebpackPlugin({ - vue: { enabled: true, compiler: 'nativescript-vue-template-compiler' } -}); -``` +If you use **TypeScript >=3.8.0**, you can fix it by passing `"importsNotUsedAsValues": "preserve"` option to the compiler options in the `tsconfig.json`. -2. To activate TypeScript in your `.vue` files, you need to ensure your script tag's language attribute is set - to `ts` or `tsx` (also make sure you include the `.vue` extension in all your import statements as shown below): +## Plugin hooks -```html - -``` +| Hook key | Type | Params | Description | +| ---------- | ------------------- | --------------------- | ----------- | +| `start` | `SyncWaterfallHook` | `change, compilation` | Starts issues checking for a compilation. It's a waterfall hook, so you can modify the list of changed and removed files. | +| `waiting` | `SyncHook` | `compilation` | Waiting for the issues checking. | +| `canceled` | `SyncHook` | `compilation` | Issues checking for the compilation has been canceled. | +| `error` | `SyncHook` | `compilation` | An error occurred during issues checking. | +| `issues` | `SyncWaterfallHook` | `issues, compilation` | Issues have been received and will be reported. It's a waterfall hook, so you can modify the list of received issues. | -3. Ideally you are also using `ts-loader` (in transpileOnly mode). Your Webpack config rules may look something like this: +To access plugin hooks and tap into the event, we need to use the `getCompilerHooks` static method. +When we call this method with a [webpack compiler instance](https://webpack.js.org/api/node/), it returns the object with +[tapable](https://github.com/webpack/tapable) hooks where you can pass in your callbacks. ```js -{ - test: /\.ts$/, - loader: 'ts-loader', - include: [resolve('src'), resolve('test')], - options: { - appendTsSuffixTo: [/\.vue$/], - transpileOnly: true - } -}, -{ - test: /\.vue$/, - loader: 'vue-loader', - options: vueLoaderConfig -}, -``` - -4. Ensure your `tsconfig.json` includes .vue files: +const webpack = require('webpack'); +const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); -```js -// tsconfig.json -{ - "include": [ - "src/**/*.ts", - "src/**/*.vue" - ], - "exclude": [ - "node_modules" - ] -} -``` +const compiler = webpack({ + // ... webpack config +}); -5. It accepts any wildcard in your TypeScript configuration: +// optionally add the plugin to the compiler +// **don't do this if already added through configuration** +new ForkTsCheckerWebpackPlugin().apply(compiler); -```js -// tsconfig.json -{ - "compilerOptions": { - - // ... - - "baseUrl": ".", - "paths": { - "@/*": [ - "src/*" - ], - "~/*": [ - "src/*" - ] - } - } -} +// now get the plugin hooks from compiler +const hooks = ForkTsCheckerWebpackPlugin.getCompilerHooks(compiler); -// In a .ts or .vue file... -import Hello from '@/components/hello.vue' +// say we want to show some message when plugin is waiting for issues results +hooks.waiting.tap('yourListenerName', () => { + console.log('waiting for issues'); +}); ``` -6. If you are working in **VSCode**, you can get the [Vetur](https://marketplace.visualstudio.com/items?itemName=octref.vetur) extension to complete the developer workflow. +## Related projects + + * [`ts-loader`](https://github.com/TypeStrong/ts-loader) - TypeScript loader for webpack. + * [`babel-loader`](https://github.com/babel/babel-loader) - Alternative TypeScript loader for webpack. + * [`fork-ts-checker-notifier-webpack-plugin`](https://github.com/johnnyreilly/fork-ts-checker-notifier-webpack-plugin) - Notifies about build status using system notifications (similar to the [webpack-notifier](https://github.com/Turbo87/webpack-notifier)). ## Credits diff --git a/src/ForkTsCheckerWebpackPlugin.ts b/src/ForkTsCheckerWebpackPlugin.ts index 55bfbaa0..755e1c42 100644 --- a/src/ForkTsCheckerWebpackPlugin.ts +++ b/src/ForkTsCheckerWebpackPlugin.ts @@ -9,10 +9,8 @@ import { assertTypeScriptSupport } from './typescript-reporter/TypeScriptSupport import { createTypeScriptReporterRpcClient } from './typescript-reporter/reporter/TypeScriptReporterRpcClient'; import { assertEsLintSupport } from './eslint-reporter/assertEsLintSupport'; import { createEsLintReporterRpcClient } from './eslint-reporter/reporter/EsLintReporterRpcClient'; -import { tapDoneToAsyncGetIssues } from './hooks/tapDoneToAsyncGetIssues'; import { tapStartToConnectAndRunReporter } from './hooks/tapStartToConnectAndRunReporter'; import { tapStopToDisconnectReporter } from './hooks/tapStopToDisconnectReporter'; -import { tapAfterCompileToGetIssues } from './hooks/tapAfterCompileToGetIssues'; import { getForkTsCheckerWebpackPluginHooks } from './hooks/pluginHooks'; import { tapDoneToCollectRemoved } from './hooks/tapDoneToCollectRemoved'; @@ -46,11 +44,6 @@ class ForkTsCheckerWebpackPlugin implements webpack.Plugin { tapStartToConnectAndRunReporter(compiler, reporter, configuration, state); tapDoneToCollectRemoved(compiler, configuration, state); tapStopToDisconnectReporter(compiler, reporter, configuration, state); - if (configuration.async) { - tapDoneToAsyncGetIssues(compiler, configuration, state); - } else { - tapAfterCompileToGetIssues(compiler, configuration, state); - } } else { throw new Error( `ForkTsCheckerWebpackPlugin is configured to not use any issue reporter. It's probably a configuration issue.` diff --git a/src/ForkTsCheckerWebpackPluginConfiguration.ts b/src/ForkTsCheckerWebpackPluginConfiguration.ts index 2171da5f..af374010 100644 --- a/src/ForkTsCheckerWebpackPluginConfiguration.ts +++ b/src/ForkTsCheckerWebpackPluginConfiguration.ts @@ -16,8 +16,8 @@ interface ForkTsCheckerWebpackPluginConfiguration { async: boolean; typescript: TypeScriptReporterConfiguration; eslint: EsLintReporterConfiguration; - formatter: FormatterConfiguration; issue: IssueConfiguration; + formatter: FormatterConfiguration; logger: LoggerConfiguration; } @@ -26,11 +26,11 @@ function createForkTsCheckerWebpackPluginConfiguration( options: ForkTsCheckerWebpackPluginOptions = {} ): ForkTsCheckerWebpackPluginConfiguration { return { - async: options.async === true, + async: options.async === undefined ? compiler.options.mode === 'development' : options.async, typescript: createTypeScriptReporterConfiguration(compiler, options.typescript), eslint: createEsLintReporterConfiguration(compiler, options.eslint), - formatter: createFormatterConfiguration(options.formatter), issue: createIssueConfiguration(compiler, options.issue), + formatter: createFormatterConfiguration(options.formatter), logger: createLoggerConfiguration(compiler, options.logger), }; } diff --git a/src/ForkTsCheckerWebpackPluginState.ts b/src/ForkTsCheckerWebpackPluginState.ts index eca8e828..52ff6963 100644 --- a/src/ForkTsCheckerWebpackPluginState.ts +++ b/src/ForkTsCheckerWebpackPluginState.ts @@ -3,14 +3,16 @@ import { Report } from './reporter'; interface ForkTsCheckerWebpackPluginState { report: Promise; removedFiles: string[]; - isWatching: boolean; + watching: boolean; + initialized: boolean; } function createForkTsCheckerWebpackPluginState(): ForkTsCheckerWebpackPluginState { return { report: Promise.resolve([]), removedFiles: [], - isWatching: false, + watching: false, + initialized: false, }; } diff --git a/src/error/OperationCanceledError.ts b/src/error/OperationCanceledError.ts new file mode 100644 index 00000000..1de63a5b --- /dev/null +++ b/src/error/OperationCanceledError.ts @@ -0,0 +1,5 @@ +class OperationCanceledError extends Error { + readonly canceled = true; +} + +export { OperationCanceledError }; diff --git a/src/error/OperationCancelledError.ts b/src/error/OperationCancelledError.ts deleted file mode 100644 index 6f559f61..00000000 --- a/src/error/OperationCancelledError.ts +++ /dev/null @@ -1,5 +0,0 @@ -class OperationCancelledError extends Error { - readonly cancelled = true; -} - -export { OperationCancelledError }; diff --git a/src/formatter/FormatterConfiguration.ts b/src/formatter/FormatterConfiguration.ts index 630be734..264a4138 100644 --- a/src/formatter/FormatterConfiguration.ts +++ b/src/formatter/FormatterConfiguration.ts @@ -6,11 +6,7 @@ type FormatterConfiguration = Formatter; function createFormatterConfiguration(options: FormatterOptions | undefined) { return createFormatter( - options - ? typeof options === 'string' || typeof options === 'function' - ? options - : options.type || 'codeframe' - : 'codeframe', + options ? (typeof options === 'string' ? options : options.type || 'codeframe') : 'codeframe', options && typeof options === 'object' ? options.options || {} : {} ); } diff --git a/src/formatter/FormatterFactory.ts b/src/formatter/FormatterFactory.ts index b30b61a4..626bec64 100644 --- a/src/formatter/FormatterFactory.ts +++ b/src/formatter/FormatterFactory.ts @@ -2,7 +2,7 @@ import { Formatter } from './Formatter'; import { BabelCodeFrameOptions, createCodeframeFormatter } from './CodeframeFormatter'; import { createBasicFormatter } from './BasicFormatter'; -type NotConfigurableFormatterType = undefined | 'basic' | Formatter; +type NotConfigurableFormatterType = undefined | 'basic'; type ConfigurableFormatterType = 'codeframe'; type FormatterType = NotConfigurableFormatterType | ConfigurableFormatterType; @@ -25,10 +25,6 @@ function createFormatter( function createFormatter(type: T, options?: object): Formatter; // declare function implementation function createFormatter(type?: FormatterType, options?: object): Formatter { - if (typeof type === 'function') { - return type; - } - switch (type) { case 'basic': case undefined: @@ -38,9 +34,7 @@ function createFormatter(type?: FormatterType, options?: object): Formatter { return createCodeframeFormatter(options); default: - throw new Error( - `Unknown "${type}" formatter. Available types are: basic, codeframe, Function.` - ); + throw new Error(`Unknown "${type}" formatter. Available types are: basic, codeframe.`); } } diff --git a/src/formatter/FormatterOptions.ts b/src/formatter/FormatterOptions.ts index 696ff583..4b2b3de8 100644 --- a/src/formatter/FormatterOptions.ts +++ b/src/formatter/FormatterOptions.ts @@ -1,7 +1,6 @@ import { ComplexFormatterOptions, FormatterType } from './FormatterFactory'; -type ComplexFormatterType = Exclude; -type ComplexFormatterPreferences = { +type ComplexFormatterPreferences = { type: T; options?: ComplexFormatterOptions; }; diff --git a/src/hooks/pluginHooks.ts b/src/hooks/pluginHooks.ts index 0d4c2514..90147902 100644 --- a/src/hooks/pluginHooks.ts +++ b/src/hooks/pluginHooks.ts @@ -10,11 +10,13 @@ const compilerHookMap = new WeakMap< function createForkTsCheckerWebpackPluginHooks() { return { - run: new SyncHook(['compiler']), - runWatch: new SyncWaterfallHook(['change', 'compiler']), + start: new SyncWaterfallHook([ + 'change', + 'compilation', + ]), waiting: new SyncHook(['compilation']), - cancelled: new SyncHook(['compiler']), - error: new SyncHook(['error', 'compiler']), + canceled: new SyncHook(['compilation']), + error: new SyncHook(['error', 'compilation']), issues: new SyncWaterfallHook([ 'issues', 'compilation', @@ -28,10 +30,10 @@ function forwardForkTsCheckerWebpackPluginHooks( source: ForkTsCheckerWebpackPluginHooks, target: ForkTsCheckerWebpackPluginHooks ) { - source.run.tap('ForkTsCheckerWebpackPlugin', target.run.call); - source.runWatch.tap('ForkTsCheckerWebpackPlugin', target.runWatch.call); + source.start.tap('ForkTsCheckerWebpackPlugin', target.start.call); source.waiting.tap('ForkTsCheckerWebpackPlugin', target.waiting.call); - source.cancelled.tap('ForkTsCheckerWebpackPlugin', target.cancelled.call); + source.canceled.tap('ForkTsCheckerWebpackPlugin', target.canceled.call); + source.error.tap('ForkTsCheckerWebpackPlugin', target.error.call); source.issues.tap('ForkTsCheckerWebpackPlugin', target.issues.call); } diff --git a/src/hooks/tapAfterCompileToGetIssues.ts b/src/hooks/tapAfterCompileToGetIssues.ts index f1e3c45b..a3e79b9a 100644 --- a/src/hooks/tapAfterCompileToGetIssues.ts +++ b/src/hooks/tapAfterCompileToGetIssues.ts @@ -18,12 +18,12 @@ function tapAfterCompileToGetIssues( try { issues = await state.report; } catch (error) { - hooks.error.call(error, compilation.compiler); + hooks.error.call(error, compilation); return; } if (!issues) { - // some error has been thrown or it was cancelled + // some error has been thrown or it was canceled return; } diff --git a/src/hooks/tapDoneToAsyncGetIssues.ts b/src/hooks/tapDoneToAsyncGetIssues.ts index 9c96ec2d..c3f214b9 100644 --- a/src/hooks/tapDoneToAsyncGetIssues.ts +++ b/src/hooks/tapDoneToAsyncGetIssues.ts @@ -30,12 +30,12 @@ function tapDoneToAsyncGetIssues( issues = await report; } catch (error) { - hooks.error.call(error, stats.compilation.compiler); + hooks.error.call(error, stats.compilation); return; } if (!issues) { - // some error has been thrown or it was cancelled + // some error has been thrown or it was canceled return; } diff --git a/src/hooks/tapStartToConnectAndRunReporter.ts b/src/hooks/tapStartToConnectAndRunReporter.ts index 5cd89a00..94297b79 100644 --- a/src/hooks/tapStartToConnectAndRunReporter.ts +++ b/src/hooks/tapStartToConnectAndRunReporter.ts @@ -5,7 +5,9 @@ import { getForkTsCheckerWebpackPluginHooks } from './pluginHooks'; import { getDeletedFiles } from './getDeletedFiles'; import { FilesChange, ReporterRpcClient } from '../reporter'; import { getChangedFiles } from './getChangedFiles'; -import { OperationCancelledError } from '../error/OperationCancelledError'; +import { OperationCanceledError } from '../error/OperationCanceledError'; +import { tapDoneToAsyncGetIssues } from './tapDoneToAsyncGetIssues'; +import { tapAfterCompileToGetIssues } from './tapAfterCompileToGetIssues'; function tapStartToConnectAndRunReporter( compiler: webpack.Compiler, @@ -16,47 +18,57 @@ function tapStartToConnectAndRunReporter( const hooks = getForkTsCheckerWebpackPluginHooks(compiler); compiler.hooks.run.tap('ForkTsCheckerWebpackPlugin', (compiler) => { - state.isWatching = false; + if (!state.initialized) { + state.initialized = true; - configuration.logger.infrastructure.info('Calling reporter service for single check.'); + state.watching = false; + tapAfterCompileToGetIssues(compiler, configuration, state); + } + }); - hooks.run.call(compiler); + compiler.hooks.watchRun.tap('ForkTsCheckerWebpackPlugin', async (compiler) => { + if (!state.initialized) { + state.initialized = true; - state.report = reporter - .connect() - .then(() => reporter.getReport({})) - .catch((error) => { - hooks.error.call(error, compiler); - return undefined; - }); + state.watching = true; + if (configuration.async) { + tapDoneToAsyncGetIssues(compiler, configuration, state); + } else { + tapAfterCompileToGetIssues(compiler, configuration, state); + } + } }); - compiler.hooks.watchRun.tap('ForkTsCheckerWebpackPlugin', async (compiler) => { - state.isWatching = true; + compiler.hooks.compilation.tap('ForkTsCheckerWebpackPlugin', async (compilation) => { + let change: FilesChange = {}; - let change: FilesChange = { - changedFiles: getChangedFiles(compiler), - deletedFiles: getDeletedFiles(compiler, state), - }; + if (state.watching) { + change = { + changedFiles: getChangedFiles(compilation.compiler), + deletedFiles: getDeletedFiles(compilation.compiler, state), + }; - change = hooks.runWatch.call(change, compiler); + configuration.logger.infrastructure.info( + [ + 'Calling reporter service for incremental check.', + ` Changed files: ${JSON.stringify(change.changedFiles)}`, + ` Deleted files: ${JSON.stringify(change.deletedFiles)}`, + ].join('\n') + ); + } else { + configuration.logger.infrastructure.info('Calling reporter service for single check.'); + } - configuration.logger.infrastructure.info( - [ - 'Calling reporter service for incremental check.', - ` Changed files: ${JSON.stringify(change.changedFiles)}`, - ` Deleted files: ${JSON.stringify(change.deletedFiles)}`, - ].join('\n') - ); + change = hooks.start.call(change, compilation); state.report = reporter .connect() .then(() => reporter.getReport(change)) .catch((error) => { - if (error instanceof OperationCancelledError) { - hooks.cancelled.call(compiler); + if (error instanceof OperationCanceledError) { + hooks.canceled.call(compilation); } else { - hooks.error.call(error, compiler); + hooks.error.call(error, compilation); } return undefined; diff --git a/src/hooks/tapStopToDisconnectReporter.ts b/src/hooks/tapStopToDisconnectReporter.ts index 47a0eb03..12c769ef 100644 --- a/src/hooks/tapStopToDisconnectReporter.ts +++ b/src/hooks/tapStopToDisconnectReporter.ts @@ -17,7 +17,7 @@ function tapStopToDisconnectReporter( }); compiler.hooks.done.tap('ForkTsCheckerWebpackPlugin', async () => { - if (!state.isWatching) { + if (!state.watching) { await reporter.disconnect(); } }); diff --git a/src/issue/IssueMatch.ts b/src/issue/IssueMatch.ts index e4cdf36c..0d40e05c 100644 --- a/src/issue/IssueMatch.ts +++ b/src/issue/IssueMatch.ts @@ -2,6 +2,7 @@ import { Issue } from './index'; import { IssuePredicate } from './IssuePredicate'; import minimatch from 'minimatch'; import path from 'path'; +import normalizeSlash from '../utils/path/normalizeSlash'; type IssueMatch = Partial>; @@ -12,7 +13,8 @@ function createIssuePredicateFromIssueMatch(context: string, match: IssueMatch): const matchesCode = !match.code || match.code === issue.code; const matchesFile = !issue.file || - (!!issue.file && (!match.file || minimatch(path.relative(context, issue.file), match.file))); + (!!issue.file && + (!match.file || minimatch(normalizeSlash(path.relative(context, issue.file)), match.file))); return matchesOrigin && matchesSeverity && matchesCode && matchesFile; }; diff --git a/src/reporter/AggregatedReporter.ts b/src/reporter/AggregatedReporter.ts index 0336c612..979f9f5c 100644 --- a/src/reporter/AggregatedReporter.ts +++ b/src/reporter/AggregatedReporter.ts @@ -1,5 +1,5 @@ import { Reporter } from './Reporter'; -import { OperationCancelledError } from '../error/OperationCancelledError'; +import { OperationCanceledError } from '../error/OperationCanceledError'; import { aggregateFilesChanges, FilesChange } from './FilesChange'; /** @@ -38,7 +38,7 @@ function createAggregatedReporter(reporter: TReporte return aggregatedReporter.getReport(change); } else { - throw new OperationCancelledError('getIssues cancelled - new report requested.'); + throw new OperationCanceledError('getIssues canceled - new report requested.'); } }); } diff --git a/test/e2e/fixtures/typescript-pnp.fixture b/test/e2e/fixtures/typescript-pnp.fixture index 0855cf89..e2525279 100644 --- a/test/e2e/fixtures/typescript-pnp.fixture +++ b/test/e2e/fixtures/typescript-pnp.fixture @@ -55,10 +55,9 @@ module.exports = { test: /\.tsx?$/, loader: 'ts-loader', exclude: /node_modules/, - options: { - ...PnpWebpackPlugin.tsLoaderOptions(), + options: PnpWebpackPlugin.tsLoaderOptions({ transpileOnly: true - } + }) }, ], }, diff --git a/test/unit/formatter/FormatterConfiguration.spec.ts b/test/unit/formatter/FormatterConfiguration.spec.ts index 57fccd27..6ab4199d 100644 --- a/test/unit/formatter/FormatterConfiguration.spec.ts +++ b/test/unit/formatter/FormatterConfiguration.spec.ts @@ -1,7 +1,7 @@ import os from 'os'; import mockFs from 'mock-fs'; import { Issue } from 'lib/issue'; -import { createFormatterConfiguration, Formatter, FormatterOptions } from 'lib/formatter'; +import { createFormatterConfiguration, FormatterOptions } from 'lib/formatter'; describe('formatter/FormatterConfiguration', () => { beforeEach(() => { @@ -40,7 +40,6 @@ describe('formatter/FormatterConfiguration', () => { }, }, }; - const customFormatter: Formatter = (issue) => issue.origin.toUpperCase(); const BASIC_FORMATTER_OUTPUT = `TS2322: Type '"1"' is not assignable to type 'number'.`; const CODEFRAME_FORMATTER_OUTPUT = [ @@ -57,13 +56,11 @@ describe('formatter/FormatterConfiguration', () => { ' | ^^^', ' 2 | const bar = 1;', ].join(os.EOL); - const CUSTOM_FORMATTER_OUTPUT = 'TYPESCRIPT'; it.each([ [undefined, CODEFRAME_FORMATTER_OUTPUT], ['basic', BASIC_FORMATTER_OUTPUT], ['codeframe', CODEFRAME_FORMATTER_OUTPUT], - [customFormatter, CUSTOM_FORMATTER_OUTPUT], [{ type: 'basic' }, BASIC_FORMATTER_OUTPUT], [{ type: 'codeframe' }, CODEFRAME_FORMATTER_OUTPUT], [{ type: 'codeframe', options: { linesBelow: 1 } }, CUSTOM_CODEFRAME_FORMATTER_OUTPUT], diff --git a/test/unit/formatter/FormatterFactory.spec.ts b/test/unit/formatter/FormatterFactory.spec.ts index 33b0811c..b8491dfc 100644 --- a/test/unit/formatter/FormatterFactory.spec.ts +++ b/test/unit/formatter/FormatterFactory.spec.ts @@ -81,17 +81,10 @@ describe('formatter/FormatterFactory', () => { ); }); - it('forwards already created formatter', () => { - const formatter = createFormatter((issue) => issue.message); - const formattedMessage = formatter(issue); - - expect(formattedMessage).toEqual('Some issue content'); - }); - it('throws an error on unknown formatter type', () => { // eslint-disable-next-line @typescript-eslint/no-explicit-any expect(() => createFormatter('unknown-type' as any)).toThrowError( - `Unknown "unknown-type" formatter. Available types are: basic, codeframe, Function.` + `Unknown "unknown-type" formatter. Available types are: basic, codeframe.` ); }); }); From 1342ae8ca93cba804e11471f2ce4d2c90c2947c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ole=C5=9B?= Date: Thu, 21 May 2020 16:42:09 +0200 Subject: [PATCH 20/29] feat: add skipLibCheck compiler option as a default one In order to improve developer experience, we set `skipDefaultLibCheck` and `skipLibCheck` to true. It will improve type checking time. --- README.md | 2 +- .../TypeScriptReporterConfiguration.ts | 6 +++++- .../TypeScriptReporterConfiguration.spec.ts | 10 ++++++++-- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c0be2c1d..b5bb7317 100644 --- a/README.md +++ b/README.md @@ -152,7 +152,7 @@ Options for the TypeScript checker (`typescript` option object). | `memoryLimit` | `number` | `2048` | Memory limit for the checker process in MB. If the process exits with the allocation failed error, try to increase this number. | | `tsconfig` | `string` | `'tsconfig.json'` | Path to the `tsconfig.json` file (path relative to the `compiler.options.context` or absolute path) | | `build` | `boolean` | `false` | The equivalent of the `--build` flag for the `tsc` command. | -| `compilerOptions` | `object` | `{}` | These options will overwrite compiler options from the `tsconfig.json` file. | +| `compilerOptions` | `object` | `{ skipLibCheck: true, skipDefaultLibCheck: true }` | These options will overwrite compiler options from the `tsconfig.json` file. | | `diagnosticsOptions` | `object` | `{ syntactic: false, semantic: true, declaration: false, global: false }` | Settings to select which diagnostics do we want to perform. | | `extensions` | `object` | `{}` | See [TypeScript extensions options](#typescript-extensions-options). | diff --git a/src/typescript-reporter/TypeScriptReporterConfiguration.ts b/src/typescript-reporter/TypeScriptReporterConfiguration.ts index dbcb5eea..e14dae73 100644 --- a/src/typescript-reporter/TypeScriptReporterConfiguration.ts +++ b/src/typescript-reporter/TypeScriptReporterConfiguration.ts @@ -35,8 +35,12 @@ function createTypeScriptReporterConfiguration( memoryLimit: 2048, tsconfig: 'tsconfig.json', build: false, - compilerOptions: {}, ...(typeof options === 'object' ? options : {}), + compilerOptions: { + skipDefaultLibCheck: true, + skipLibCheck: true, + ...(typeof options === 'object' ? options.compilerOptions || {} : {}), + }, extensions: { vue: createTypeScriptVueExtensionConfiguration( typeof options === 'object' && options.extensions ? options.extensions.vue : undefined diff --git a/test/unit/typescript-reporter/TypeScriptReporterConfiguration.spec.ts b/test/unit/typescript-reporter/TypeScriptReporterConfiguration.spec.ts index ebe14518..36ac8fcb 100644 --- a/test/unit/typescript-reporter/TypeScriptReporterConfiguration.spec.ts +++ b/test/unit/typescript-reporter/TypeScriptReporterConfiguration.spec.ts @@ -13,7 +13,10 @@ describe('typescript-reporter/TypeScriptsReporterConfiguration', () => { memoryLimit: 2048, tsconfig: '/webpack/context/tsconfig.json', build: false, - compilerOptions: {}, + compilerOptions: { + skipDefaultLibCheck: true, + skipLibCheck: true, + }, diagnosticOptions: { semantic: true, syntactic: false, @@ -69,7 +72,10 @@ describe('typescript-reporter/TypeScriptsReporterConfiguration', () => { [{ build: true }, { ...configuration, build: true }], [ { compilerOptions: { strict: true } }, - { ...configuration, compilerOptions: { strict: true } }, + { + ...configuration, + compilerOptions: { skipDefaultLibCheck: true, skipLibCheck: true, strict: true }, + }, ], [{ diagnosticOptions: {} }, configuration], [ From 971a3edfaab4cc967486e0ba1f67effbd67a5e8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ole=C5=9B?= Date: Thu, 21 May 2020 18:20:57 +0200 Subject: [PATCH 21/29] test: add type definitions test --- test/e2e/EsLint.spec.ts | 14 +- test/e2e/PluginOutOfMemory.spec.ts | 13 +- test/e2e/TypeDefinitions.spec.ts | 37 ++++ test/e2e/TypeScriptPnpExtension.spec.ts | 25 ++- test/e2e/TypeScriptSolutionBuilderApi.spec.ts | 11 +- test/e2e/TypeScriptVueExtension.spec.ts | 11 +- test/e2e/TypeScriptWatchApi.spec.ts | 25 ++- .../fixtures/environment/eslint-basic.fixture | 89 ++++++++ .../environment/typescript-basic.fixture | 71 +++++++ .../environment/typescript-monorepo.fixture | 95 +++++++++ .../environment/typescript-pnp.fixture | 90 ++++++++ .../environment/typescript-vue.fixture | 98 +++++++++ test/e2e/fixtures/eslint-basic.fixture | 176 ---------------- .../typescript-basic.fixture | 67 ------ .../typescript-monorepo.fixture | 96 +++++++++ .../typescript-vue.fixture | 95 --------- test/e2e/fixtures/type-definitions.fixture | 43 ++++ test/e2e/fixtures/typescript-pnp.fixture | 179 ---------------- .../typescript-project-references.fixture | 192 ------------------ test/e2e/sandbox/Sandbox.ts | 26 ++- 20 files changed, 688 insertions(+), 765 deletions(-) create mode 100644 test/e2e/TypeDefinitions.spec.ts create mode 100644 test/e2e/fixtures/environment/eslint-basic.fixture create mode 100644 test/e2e/fixtures/environment/typescript-basic.fixture create mode 100644 test/e2e/fixtures/environment/typescript-monorepo.fixture create mode 100644 test/e2e/fixtures/environment/typescript-pnp.fixture create mode 100644 test/e2e/fixtures/environment/typescript-vue.fixture delete mode 100644 test/e2e/fixtures/eslint-basic.fixture rename test/e2e/fixtures/{ => implementation}/typescript-basic.fixture (56%) create mode 100644 test/e2e/fixtures/implementation/typescript-monorepo.fixture rename test/e2e/fixtures/{ => implementation}/typescript-vue.fixture (59%) create mode 100644 test/e2e/fixtures/type-definitions.fixture delete mode 100644 test/e2e/fixtures/typescript-pnp.fixture delete mode 100644 test/e2e/fixtures/typescript-project-references.fixture diff --git a/test/e2e/EsLint.spec.ts b/test/e2e/EsLint.spec.ts index 49d04fdb..27a20547 100644 --- a/test/e2e/EsLint.spec.ts +++ b/test/e2e/EsLint.spec.ts @@ -28,8 +28,8 @@ describe('EsLint', () => { { async: false, webpack: '^5.0.0-beta.16' }, { async: true, webpack: '^5.0.0-beta.16' }, ])('reports lint error for %p', async ({ async, webpack }) => { - await sandbox.load( - await readFixture(join(__dirname, 'fixtures/eslint-basic.fixture'), { + await sandbox.load([ + await readFixture(join(__dirname, 'fixtures/environment/eslint-basic.fixture'), { FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION: JSON.stringify( FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION ), @@ -39,13 +39,11 @@ describe('EsLint', () => { WEBPACK_CLI_VERSION: JSON.stringify(WEBPACK_CLI_VERSION), WEBPACK_DEV_SERVER_VERSION: JSON.stringify(WEBPACK_DEV_SERVER_VERSION), ASYNC: JSON.stringify(async), - }) - ); + }), + await readFixture(join(__dirname, 'fixtures/implementation/typescript-basic.fixture')), + ]); - const driver = createWebpackDevServerDriver( - sandbox.spawn('./node_modules/.bin/webpack-dev-server'), - async - ); + const driver = createWebpackDevServerDriver(sandbox.spawn('npm run webpack-dev-server'), async); let errors: string[]; // first compilation contains 2 warnings diff --git a/test/e2e/PluginOutOfMemory.spec.ts b/test/e2e/PluginOutOfMemory.spec.ts index c176942d..cb114ef7 100644 --- a/test/e2e/PluginOutOfMemory.spec.ts +++ b/test/e2e/PluginOutOfMemory.spec.ts @@ -24,8 +24,8 @@ describe('ForkTsCheckerWebpackPlugin Out Of Memory', () => { { async: false, webpack: '^5.0.0-beta.16' }, { async: true, webpack: '^5.0.0-beta.16' }, ])('handles out of memory for %p', async ({ async, webpack }) => { - await sandbox.load( - await readFixture(join(__dirname, 'fixtures/typescript-basic.fixture'), { + await sandbox.load([ + await readFixture(join(__dirname, 'fixtures/environment/typescript-basic.fixture'), { FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION: JSON.stringify( FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION ), @@ -35,8 +35,9 @@ describe('ForkTsCheckerWebpackPlugin Out Of Memory', () => { WEBPACK_CLI_VERSION: JSON.stringify('^3.3.11'), WEBPACK_DEV_SERVER_VERSION: JSON.stringify('^3.10.3'), ASYNC: JSON.stringify(async), - }) - ); + }), + await readFixture(join(__dirname, 'fixtures/implementation/typescript-basic.fixture')), + ]); await sandbox.patch( 'webpack.config.js', @@ -50,9 +51,7 @@ describe('ForkTsCheckerWebpackPlugin Out Of Memory', () => { ].join('\n') ); - const driver = createGenericProcessDriver( - sandbox.spawn('./node_modules/.bin/webpack-dev-server') - ); + const driver = createGenericProcessDriver(sandbox.spawn('npm run webpack-dev-server')); // we should see an error message about out of memory await driver.waitForStderrIncludes( diff --git a/test/e2e/TypeDefinitions.spec.ts b/test/e2e/TypeDefinitions.spec.ts new file mode 100644 index 00000000..88c1824f --- /dev/null +++ b/test/e2e/TypeDefinitions.spec.ts @@ -0,0 +1,37 @@ +import { createSandbox, FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION, Sandbox } from './sandbox/Sandbox'; +import { readFixture } from './sandbox/Fixture'; +import { join } from 'path'; + +describe('Type Definitions', () => { + let sandbox: Sandbox; + + beforeAll(async () => { + sandbox = await createSandbox(); + }); + + beforeEach(async () => { + await sandbox.reset(); + }); + + afterAll(async () => { + await sandbox.cleanup(); + }); + + it('provides valid type definitions', async () => { + await sandbox.load( + await readFixture(join(__dirname, 'fixtures/type-definitions.fixture'), { + FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION: JSON.stringify( + FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION + ), + }) + ); + + expect(await sandbox.exec('npm run tsc').catch((error) => error)).toContain( + "webpack.config.ts(7,7): error TS2322: Type 'string' is not assignable to type 'boolean | undefined'." + ); + + await sandbox.patch('webpack.config.ts', "async: 'invalid_value'", 'async: true'); + + expect(await sandbox.exec('npm run tsc')).not.toContain('error TS'); + }); +}); diff --git a/test/e2e/TypeScriptPnpExtension.spec.ts b/test/e2e/TypeScriptPnpExtension.spec.ts index edcac03c..07083f3c 100644 --- a/test/e2e/TypeScriptPnpExtension.spec.ts +++ b/test/e2e/TypeScriptPnpExtension.spec.ts @@ -34,17 +34,20 @@ describe('TypeScript PnP Extension', () => { { async: false, webpack: '^4.0.0', typescript: '~3.8.0', tsloader: '^6.0.0' }, ])('reports semantic error for %p', async ({ async, webpack, typescript, tsloader }) => { await sandbox.load( - await readFixture(join(__dirname, 'fixtures/typescript-pnp.fixture'), { - FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION: JSON.stringify( - FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION - ), - TS_LOADER_VERSION: JSON.stringify(tsloader), - TYPESCRIPT_VERSION: JSON.stringify(typescript), - WEBPACK_VERSION: JSON.stringify(webpack), - WEBPACK_CLI_VERSION: JSON.stringify(WEBPACK_CLI_VERSION), - WEBPACK_DEV_SERVER_VERSION: JSON.stringify(WEBPACK_DEV_SERVER_VERSION), - ASYNC: JSON.stringify(async), - }), + [ + await readFixture(join(__dirname, 'fixtures/environment/typescript-pnp.fixture'), { + FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION: JSON.stringify( + FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION + ), + TS_LOADER_VERSION: JSON.stringify(tsloader), + TYPESCRIPT_VERSION: JSON.stringify(typescript), + WEBPACK_VERSION: JSON.stringify(webpack), + WEBPACK_CLI_VERSION: JSON.stringify(WEBPACK_CLI_VERSION), + WEBPACK_DEV_SERVER_VERSION: JSON.stringify(WEBPACK_DEV_SERVER_VERSION), + ASYNC: JSON.stringify(async), + }), + await readFixture(join(__dirname, 'fixtures/implementation/typescript-basic.fixture')), + ], yarnInstaller ); diff --git a/test/e2e/TypeScriptSolutionBuilderApi.spec.ts b/test/e2e/TypeScriptSolutionBuilderApi.spec.ts index 4d08d0ac..af21def0 100644 --- a/test/e2e/TypeScriptSolutionBuilderApi.spec.ts +++ b/test/e2e/TypeScriptSolutionBuilderApi.spec.ts @@ -25,8 +25,8 @@ describe('TypeScript SolutionBuilder API', () => { it.each([{ async: false }, { async: true }])( 'reports semantic error for %p', async ({ async }) => { - await sandbox.load( - await readFixture(join(__dirname, 'fixtures/typescript-project-references.fixture'), { + await sandbox.load([ + await readFixture(join(__dirname, 'fixtures/environment/typescript-monorepo.fixture'), { FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION: JSON.stringify( FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION ), @@ -36,11 +36,12 @@ describe('TypeScript SolutionBuilder API', () => { WEBPACK_CLI_VERSION: JSON.stringify(WEBPACK_CLI_VERSION), WEBPACK_DEV_SERVER_VERSION: JSON.stringify(WEBPACK_DEV_SERVER_VERSION), ASYNC: JSON.stringify(async), - }) - ); + }), + await readFixture(join(__dirname, 'fixtures/implementation/typescript-monorepo.fixture')), + ]); const driver = createWebpackDevServerDriver( - sandbox.spawn('./node_modules/.bin/webpack-dev-server'), + sandbox.spawn('npm run webpack-dev-server'), async ); let errors: string[]; diff --git a/test/e2e/TypeScriptVueExtension.spec.ts b/test/e2e/TypeScriptVueExtension.spec.ts index 7b0db8a9..a5c3d4c9 100644 --- a/test/e2e/TypeScriptVueExtension.spec.ts +++ b/test/e2e/TypeScriptVueExtension.spec.ts @@ -25,8 +25,8 @@ describe('TypeScript Vue Extension', () => { it.each([{ async: true, webpack: '^4.0.0', typescript: '2.7.1', tsloader: '^5.0.0' }])( 'reports semantic error for %p', async ({ async, webpack, typescript, tsloader }) => { - await sandbox.load( - await readFixture(join(__dirname, 'fixtures/typescript-vue.fixture'), { + await sandbox.load([ + await readFixture(join(__dirname, 'fixtures/environment/typescript-vue.fixture'), { FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION: JSON.stringify( FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION ), @@ -36,11 +36,12 @@ describe('TypeScript Vue Extension', () => { WEBPACK_CLI_VERSION: JSON.stringify(WEBPACK_CLI_VERSION), WEBPACK_DEV_SERVER_VERSION: JSON.stringify(WEBPACK_DEV_SERVER_VERSION), ASYNC: JSON.stringify(async), - }) - ); + }), + await readFixture(join(__dirname, 'fixtures/implementation/typescript-vue.fixture')), + ]); const driver = createWebpackDevServerDriver( - sandbox.spawn('./node_modules/.bin/webpack-dev-server'), + sandbox.spawn('npm run webpack-dev-server'), async ); diff --git a/test/e2e/TypeScriptWatchApi.spec.ts b/test/e2e/TypeScriptWatchApi.spec.ts index c3c04d46..16058e63 100644 --- a/test/e2e/TypeScriptWatchApi.spec.ts +++ b/test/e2e/TypeScriptWatchApi.spec.ts @@ -30,8 +30,8 @@ describe('TypeScript Watch API', () => { ])( 'reports semantic error for %p with importsNotUsedAsValues configuration', async ({ async, webpack }) => { - await sandbox.load( - await readFixture(join(__dirname, 'fixtures/typescript-basic.fixture'), { + await sandbox.load([ + await readFixture(join(__dirname, 'fixtures/environment/typescript-basic.fixture'), { FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION: JSON.stringify( FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION ), @@ -41,8 +41,9 @@ describe('TypeScript Watch API', () => { WEBPACK_CLI_VERSION: JSON.stringify(WEBPACK_CLI_VERSION), WEBPACK_DEV_SERVER_VERSION: JSON.stringify(WEBPACK_DEV_SERVER_VERSION), ASYNC: JSON.stringify(async), - }) - ); + }), + await readFixture(join(__dirname, 'fixtures/implementation/typescript-basic.fixture')), + ]); // add importsNotUsedAsValues which is supported from TypeScript 3.8.0+ // this option is required for proper watching of type-only files in the `transpileOnly: true` mode @@ -53,7 +54,7 @@ describe('TypeScript Watch API', () => { ); const driver = createWebpackDevServerDriver( - sandbox.spawn('./node_modules/.bin/webpack-dev-server'), + sandbox.spawn('npm run webpack-dev-server'), async ); let errors: string[]; @@ -154,8 +155,8 @@ describe('TypeScript Watch API', () => { { async: true, webpack: '^4.0.0', typescript: '~3.6.0', tsloader: '^7.0.0' }, { async: false, webpack: '^4.0.0', typescript: '~3.8.0', tsloader: '^6.0.0' }, ])('reports semantic error for %p', async ({ async, webpack, typescript, tsloader }) => { - await sandbox.load( - await readFixture(join(__dirname, 'fixtures/typescript-basic.fixture'), { + await sandbox.load([ + await readFixture(join(__dirname, 'fixtures/environment/typescript-basic.fixture'), { FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION: JSON.stringify( FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION ), @@ -165,13 +166,11 @@ describe('TypeScript Watch API', () => { WEBPACK_CLI_VERSION: JSON.stringify(WEBPACK_CLI_VERSION), WEBPACK_DEV_SERVER_VERSION: JSON.stringify(WEBPACK_DEV_SERVER_VERSION), ASYNC: JSON.stringify(async), - }) - ); + }), + await readFixture(join(__dirname, 'fixtures/implementation/typescript-basic.fixture')), + ]); - const driver = createWebpackDevServerDriver( - sandbox.spawn('./node_modules/.bin/webpack-dev-server'), - async - ); + const driver = createWebpackDevServerDriver(sandbox.spawn('npm run webpack-dev-server'), async); let errors: string[]; // first compilation is successful diff --git a/test/e2e/fixtures/environment/eslint-basic.fixture b/test/e2e/fixtures/environment/eslint-basic.fixture new file mode 100644 index 00000000..ecf6bfcc --- /dev/null +++ b/test/e2e/fixtures/environment/eslint-basic.fixture @@ -0,0 +1,89 @@ +/// package.json +{ + "name": "eslint-basic-fixture", + "version": "1.0.0", + "main": "dist/index.js", + "license": "MIT", + "scripts": { + "webpack-dev-server": "webpack-dev-server" + }, + "devDependencies": { + "@types/eslint": "^6.8.0", + "@typescript-eslint/eslint-plugin": "^2.27.0", + "@typescript-eslint/parser": "^2.27.0", + "eslint": "^6.8.0", + "fork-ts-checker-webpack-plugin": ${FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION}, + "ts-loader": ${TS_LOADER_VERSION}, + "typescript": ${TYPESCRIPT_VERSION}, + "webpack": ${WEBPACK_VERSION}, + "webpack-cli": ${WEBPACK_CLI_VERSION}, + "webpack-dev-server": ${WEBPACK_DEV_SERVER_VERSION} + } +} + +/// tsconfig.json +{ + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "lib": ["ES6", "DOM"], + "moduleResolution": "node", + "esModuleInterop": true, + "skipLibCheck": true, + "skipDefaultLibCheck": true, + "strict": true, + "baseUrl": "./src", + "outDir": "./dist" + }, + "include": ["./src"], + "exclude": ["node_modules"] +} + +/// .eslintrc.js +module.exports = { + parser: '@typescript-eslint/parser', + parserOptions: { + ecmaVersion: 2018, + sourceType: 'module' + }, + extends: ['plugin:@typescript-eslint/recommended'] +}; + +/// webpack.config.js +const path = require('path'); +const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); + +module.exports = { + entry: './src/index.ts', + output: { + filename: 'index.js', + path: path.resolve(__dirname, 'dist'), + }, + module: { + rules: [ + { + test: /\.tsx?$/, + loader: 'ts-loader', + exclude: /node_modules/, + options: { + transpileOnly: true + } + }, + ], + }, + resolve: { + extensions: ['.tsx', '.ts', '.js'], + }, + plugins: [ + new ForkTsCheckerWebpackPlugin({ + async: ${ASYNC}, + eslint: { + enabled: true, + files: './src/**/*.ts' + }, + logger: { + infrastructure: "console" + } + }) + ] +}; diff --git a/test/e2e/fixtures/environment/typescript-basic.fixture b/test/e2e/fixtures/environment/typescript-basic.fixture new file mode 100644 index 00000000..0c59cf76 --- /dev/null +++ b/test/e2e/fixtures/environment/typescript-basic.fixture @@ -0,0 +1,71 @@ +/// package.json +{ + "name": "typescript-basic-fixture", + "version": "1.0.0", + "main": "dist/index.js", + "license": "MIT", + "scripts": { + "webpack-dev-server": "webpack-dev-server" + }, + "devDependencies": { + "fork-ts-checker-webpack-plugin": ${FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION}, + "ts-loader": ${TS_LOADER_VERSION}, + "typescript": ${TYPESCRIPT_VERSION}, + "webpack": ${WEBPACK_VERSION}, + "webpack-cli": ${WEBPACK_CLI_VERSION}, + "webpack-dev-server": ${WEBPACK_DEV_SERVER_VERSION} + } +} + +/// tsconfig.json +{ + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "lib": ["ES6", "DOM"], + "moduleResolution": "node", + "esModuleInterop": true, + "skipLibCheck": true, + "skipDefaultLibCheck": true, + "strict": true, + "baseUrl": "./src", + "outDir": "./dist" + }, + "include": ["./src"], + "exclude": ["node_modules"] +} + +/// webpack.config.js +const path = require('path'); +const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); + +module.exports = { + entry: './src/index.ts', + output: { + filename: 'index.js', + path: path.resolve(__dirname, 'dist'), + }, + module: { + rules: [ + { + test: /\.tsx?$/, + loader: 'ts-loader', + exclude: /node_modules/, + options: { + transpileOnly: true + } + }, + ], + }, + resolve: { + extensions: ['.tsx', '.ts', '.js'], + }, + plugins: [ + new ForkTsCheckerWebpackPlugin({ + async: ${ASYNC}, + logger: { + infrastructure: "console" + } + }) + ] +}; diff --git a/test/e2e/fixtures/environment/typescript-monorepo.fixture b/test/e2e/fixtures/environment/typescript-monorepo.fixture new file mode 100644 index 00000000..d169d2cd --- /dev/null +++ b/test/e2e/fixtures/environment/typescript-monorepo.fixture @@ -0,0 +1,95 @@ +/// package.json +{ + "name": "typescript-monorepo-fixture", + "version": "1.0.0", + "license": "MIT", + "private": true, + "scripts": { + "postinstall": "lerna bootstrap", + "webpack-dev-server": "webpack-dev-server" + }, + "devDependencies": { + "lerna": "^3.0.0", + "fork-ts-checker-webpack-plugin": ${FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION}, + "ts-loader": ${TS_LOADER_VERSION}, + "typescript": ${TYPESCRIPT_VERSION}, + "webpack": ${WEBPACK_VERSION}, + "webpack-cli": ${WEBPACK_CLI_VERSION}, + "webpack-dev-server": ${WEBPACK_DEV_SERVER_VERSION} + } +} + +/// lerna.json +{ + "version": "1.0.0", + "npmClient": "npm", + "packages": ["packages/*"] +} + +/// tsconfig.json +{ + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "lib": ["es5", "scripthost"], + "moduleResolution": "node", + "esModuleInterop": true, + "importHelpers": false, + "skipLibCheck": true, + "skipDefaultLibCheck": true, + "strict": true, + "baseUrl": ".", + "composite": true, + "incremental": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "rootDir": "./packages" + }, + "files": [], + "references": [ + { "path": "./packages/shared" }, + { "path": "./packages/client" } + ] +} + +/// webpack.config.js +const path = require('path'); +const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); + +module.exports = { + entry: './packages/client/src/index.ts', + output: { + filename: 'index.js', + path: path.resolve(__dirname, 'dist'), + }, + module: { + rules: [ + { + test: /\.tsx?$/, + loader: 'ts-loader', + exclude: /node_modules/, + options: { + transpileOnly: true, + projectReferences: true + } + }, + ], + }, + resolve: { + extensions: ['.tsx', '.ts', '.js'], + // as ts-loader doesn't fully support project references we put an alias to resolve package + // and to not pollute output with ts-loader errors + alias: { + "@project-references-fixture/shared": path.resolve(__dirname, "packages/shared/src") + } + }, + plugins: [ + new ForkTsCheckerWebpackPlugin({ + async: ${ASYNC}, + typescript: { + build: true + } + }) + ] +}; diff --git a/test/e2e/fixtures/environment/typescript-pnp.fixture b/test/e2e/fixtures/environment/typescript-pnp.fixture new file mode 100644 index 00000000..aedee360 --- /dev/null +++ b/test/e2e/fixtures/environment/typescript-pnp.fixture @@ -0,0 +1,90 @@ +/// package.json +{ + "name": "typescript-basic-fixture", + "version": "1.0.0", + "main": "dist/index.js", + "license": "MIT", + "scripts": { + "webpack-dev-server": "webpack-dev-server" + }, + "devDependencies": { + "fork-ts-checker-webpack-plugin": ${FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION}, + "pnp-webpack-plugin": "^1.6.4", + "ts-loader": ${TS_LOADER_VERSION}, + "ts-pnp": "^1.2.0", + "typescript": ${TYPESCRIPT_VERSION}, + "webpack": ${WEBPACK_VERSION}, + "webpack-cli": ${WEBPACK_CLI_VERSION}, + "webpack-dev-server": ${WEBPACK_DEV_SERVER_VERSION} + }, + "installConfig": { + "pnp": true + } +} + +/// tsconfig.json +{ + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "lib": ["ES6", "DOM"], + "moduleResolution": "node", + "esModuleInterop": true, + "skipLibCheck": true, + "skipDefaultLibCheck": true, + "strict": true, + "baseUrl": "./src", + "outDir": "./dist" + }, + "include": ["./src"], + "exclude": ["node_modules"] +} + +/// webpack.config.js +const path = require('path'); +const PnpWebpackPlugin = require(`pnp-webpack-plugin`); +const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); + +module.exports = { + entry: './src/index.ts', + output: { + filename: 'index.js', + path: path.resolve(__dirname, 'dist'), + }, + module: { + rules: [ + { + test: /\.tsx?$/, + loader: 'ts-loader', + exclude: /node_modules/, + options: PnpWebpackPlugin.tsLoaderOptions({ + transpileOnly: true + }) + }, + ], + }, + resolve: { + extensions: ['.tsx', '.ts', '.js'], + plugins: [ + PnpWebpackPlugin, + ] + }, + resolveLoader: { + plugins: [ + PnpWebpackPlugin.moduleLoader(module), + ], + }, + plugins: [ + new ForkTsCheckerWebpackPlugin({ + async: ${ASYNC}, + typescript: { + extensions: { + pnp: true + } + }, + logger: { + infrastructure: "console" + } + }) + ] +}; diff --git a/test/e2e/fixtures/environment/typescript-vue.fixture b/test/e2e/fixtures/environment/typescript-vue.fixture new file mode 100644 index 00000000..8b232c98 --- /dev/null +++ b/test/e2e/fixtures/environment/typescript-vue.fixture @@ -0,0 +1,98 @@ +/// package.json +{ + "name": "typescript-vue-fixture", + "version": "1.0.0", + "main": "dist/index.js", + "license": "MIT", + "scripts": { + "webpack-dev-server": "webpack-dev-server" + }, + "dependencies": { + "vue": "^2.6.11", + "vue-class-component": "^7.2.2" + }, + "devDependencies": { + "css-loader": "^3.4.2", + "fork-ts-checker-webpack-plugin": ${FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION}, + "ts-loader": ${TS_LOADER_VERSION}, + "typescript": ${TYPESCRIPT_VERSION}, + "vue-loader": "^15.8.3", + "vue-template-compiler": "^2.6.11", + "webpack": ${WEBPACK_VERSION}, + "webpack-cli": ${WEBPACK_CLI_VERSION}, + "webpack-dev-server": ${WEBPACK_DEV_SERVER_VERSION} + } +} + +/// tsconfig.json +{ + "compilerOptions": { + "experimentalDecorators": true, + "jsx": "preserve", + "target": "ES5", + "lib": ["ES6", "DOM"], + "baseUrl": ".", + "paths": { + "@/*": ["src/*"], + "~/*": ["src/*"] + }, + "sourceMap": true + }, + "include": [ + "src/**/*.ts", + "src/**/*.vue" + ], + "exclude": [ + "node_modules" + ] +} + +/// webpack.config.js +const path = require('path'); +const VueLoaderPlugin = require('vue-loader/lib/plugin'); +const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); + +module.exports = { + entry: './src/index.ts', + output: { + filename: 'index.js', + path: path.resolve(__dirname, 'dist'), + }, + module: { + rules: [ + { + test: /\.vue$/, + loader: 'vue-loader' + }, + { + test: /\.ts$/, + loader: 'ts-loader', + exclude: /node_modules/, + options: { + appendTsSuffixTo: [/\.vue$/] + } + }, + ], + }, + resolve: { + extensions: ['.ts', '.js', '.vue', '.json'], + alias: { + '@': path.resolve(__dirname, './src'), + '~': path.resolve(__dirname, './src'), + } + }, + plugins: [ + new VueLoaderPlugin(), + new ForkTsCheckerWebpackPlugin({ + async: ${ASYNC}, + typescript: { + extensions: { + vue: true + } + }, + logger: { + infrastructure: "console" + } + }) + ] +}; diff --git a/test/e2e/fixtures/eslint-basic.fixture b/test/e2e/fixtures/eslint-basic.fixture deleted file mode 100644 index 137ac822..00000000 --- a/test/e2e/fixtures/eslint-basic.fixture +++ /dev/null @@ -1,176 +0,0 @@ -/// package.json -{ - "name": "eslint-basic-fixture", - "version": "1.0.0", - "main": "dist/index.js", - "license": "MIT", - "devDependencies": { - "@types/eslint": "^6.8.0", - "@typescript-eslint/eslint-plugin": "^2.27.0", - "@typescript-eslint/parser": "^2.27.0", - "eslint": "^6.8.0", - "fork-ts-checker-webpack-plugin": ${FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION}, - "ts-loader": ${TS_LOADER_VERSION}, - "typescript": ${TYPESCRIPT_VERSION}, - "webpack": ${WEBPACK_VERSION}, - "webpack-cli": ${WEBPACK_CLI_VERSION}, - "webpack-dev-server": ${WEBPACK_DEV_SERVER_VERSION} - } -} -/// tsconfig.json -{ - "compilerOptions": { - "target": "es5", - "module": "commonjs", - "lib": ["ES6", "DOM"], - "moduleResolution": "node", - "esModuleInterop": true, - "skipLibCheck": true, - "skipDefaultLibCheck": true, - "strict": true, - "baseUrl": "./src", - "outDir": "./dist" - }, - "include": ["./src"], - "exclude": ["node_modules"] -} -/// .eslintrc.js -module.exports = { - parser: '@typescript-eslint/parser', - parserOptions: { - ecmaVersion: 2018, - sourceType: 'module' - }, - extends: ['plugin:@typescript-eslint/recommended'] -}; - - -/// webpack.config.js -const path = require('path'); -const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); - -module.exports = { - entry: './src/index.ts', - output: { - filename: 'index.js', - path: path.resolve(__dirname, 'dist'), - }, - module: { - rules: [ - { - test: /\.tsx?$/, - loader: 'ts-loader', - exclude: /node_modules/, - options: { - transpileOnly: true - } - }, - ], - }, - resolve: { - extensions: ['.tsx', '.ts', '.js'], - }, - plugins: [ - new ForkTsCheckerWebpackPlugin({ - async: ${ASYNC}, - eslint: { - enabled: true, - files: './src/**/*.ts' - }, - logger: { - infrastructure: "console" - } - }) - ] -}; - -/// src/index.ts -import { login } from './authenticate'; -import { getUserName } from './model/User'; - -const emailInput = document.getElementById('email'); -const passwordInput = document.getElementById('password'); -const loginForm = document.getElementById('login'); - -if (!emailInput) { - throw new Error("Cannot find #email input."); -} -if (!passwordInput) { - throw new Error("Cannot find #password input."); -} -if (!loginForm) { - throw new Error("Cannot find #login form."); -} - -let email = ''; -let password = ''; - -emailInput.addEventListener('change', event => { - if (event.target instanceof HTMLInputElement) { - email = event.target.value; - } -}); -passwordInput.addEventListener('change', event => { - if (event.target instanceof HTMLInputElement) { - password = event.target.value; - } -}); -loginForm.addEventListener('submit', async event => { - const user = await login(email, password); - - if (user.role === 'admin') { - console.log(`Logged in as ${getUserName(user)} [admin].`); - } else { - console.log(`Logged in as ${getUserName(user)}`); - } -}); - -/// src/authenticate.ts -import { User } from './model/User'; - -async function login(email: string, password: string): Promise { - const response = await fetch( - '/login', - { - method: 'POST', - body: JSON.stringify({ email, password }) - } - ); - return response.json(); -} - -async function logout(): Promise { - const response = await fetch( - '/logout', - { - method: 'POST' - } - ); - return response.json(); -} - -export { login, logout }; - -/// src/model/User.ts -import { Role } from './Role'; - -type User = { - id: string; - email: string; - role: Role; - firstName?: string; - lastName?: string; -} - -function getUserName(user: User): string { - return [user.firstName, user.lastName] - .filter(name => name !== undefined) - .join(' '); -} - -export { User, getUserName }; - -/// src/model/Role.ts -type Role = "admin" | "client" | "provider"; - -export { Role }; diff --git a/test/e2e/fixtures/typescript-basic.fixture b/test/e2e/fixtures/implementation/typescript-basic.fixture similarity index 56% rename from test/e2e/fixtures/typescript-basic.fixture rename to test/e2e/fixtures/implementation/typescript-basic.fixture index fd89fcc3..25639245 100644 --- a/test/e2e/fixtures/typescript-basic.fixture +++ b/test/e2e/fixtures/implementation/typescript-basic.fixture @@ -1,70 +1,3 @@ -/// package.json -{ - "name": "typescript-basic-fixture", - "version": "1.0.0", - "main": "dist/index.js", - "license": "MIT", - "devDependencies": { - "fork-ts-checker-webpack-plugin": ${FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION}, - "ts-loader": ${TS_LOADER_VERSION}, - "typescript": ${TYPESCRIPT_VERSION}, - "webpack": ${WEBPACK_VERSION}, - "webpack-cli": ${WEBPACK_CLI_VERSION}, - "webpack-dev-server": ${WEBPACK_DEV_SERVER_VERSION} - } -} -/// tsconfig.json -{ - "compilerOptions": { - "target": "es5", - "module": "commonjs", - "lib": ["ES6", "DOM"], - "moduleResolution": "node", - "esModuleInterop": true, - "skipLibCheck": true, - "skipDefaultLibCheck": true, - "strict": true, - "baseUrl": "./src", - "outDir": "./dist" - }, - "include": ["./src"], - "exclude": ["node_modules"] -} -/// webpack.config.js -const path = require('path'); -const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); - -module.exports = { - entry: './src/index.ts', - output: { - filename: 'index.js', - path: path.resolve(__dirname, 'dist'), - }, - module: { - rules: [ - { - test: /\.tsx?$/, - loader: 'ts-loader', - exclude: /node_modules/, - options: { - transpileOnly: true - } - }, - ], - }, - resolve: { - extensions: ['.tsx', '.ts', '.js'], - }, - plugins: [ - new ForkTsCheckerWebpackPlugin({ - async: ${ASYNC}, - logger: { - infrastructure: "console" - } - }) - ] -}; - /// src/index.ts import { login } from './authenticate'; import { getUserName } from './model/User'; diff --git a/test/e2e/fixtures/implementation/typescript-monorepo.fixture b/test/e2e/fixtures/implementation/typescript-monorepo.fixture new file mode 100644 index 00000000..545bfd9e --- /dev/null +++ b/test/e2e/fixtures/implementation/typescript-monorepo.fixture @@ -0,0 +1,96 @@ +/// packages/shared/package.json +{ + "name": "@project-references-fixture/shared", + "license": "MIT", + "version": "1.0.0", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "files": [ + "lib" + ] +} + +/// packages/shared/tsconfig.json +{ + "extends": "../../tsconfig", + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib", + "sourceRoot": "./src", + "baseUrl": "./src" + }, + "include": ["src"], + "exclude": ["node_modules", "lib"] +} + +/// packages/shared/src/intersect.ts +function intersect(arrayA: T[] = [], arrayB: T[] = []): T[] { + return arrayA.filter((item) => arrayB.includes(item)); +} + +export default intersect; + +/// packages/shared/src/subtract.ts +function subtract(arrayA: T[] = [], arrayB: T[] = []): T[] { + return arrayA.filter((item) => !arrayB.includes(item)); +} + +export default subtract; + +/// packages/shared/src/index.ts +import intersect from "./intersect"; +import subtract from "./subtract"; + +export { + intersect, + subtract +} + +/// packages/client/package.json +{ + "name": "@project-references-fixture/client", + "license": "MIT", + "version": "1.0.0", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "files": [ + "lib" + ], + "dependencies": { + "@project-references-fixture/shared": "1.0.0" + } +} + +/// packages/client/tsconfig.json +{ + "extends": "../../tsconfig", + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib", + "sourceRoot": "./src", + "baseUrl": "./src" + }, + "references": [{ "path": "../shared" }], + "include": ["src"], + "exclude": ["node_modules", "lib"] +} + + +/// packages/client/src/index.ts +import { intersect, subtract } from "@project-references-fixture/shared"; + +function compute(arrayA: T[], arrayB: T[]) { + const intersection = intersect(arrayA, arrayB); + const difference = subtract(arrayA, arrayB); + + return { + intersection, + difference + } +} + +const { intersection, difference } = compute(['a', 'b', 'c'], ['a', 'd', 'a']); + +console.log(`Intersection: ${JSON.stringify(intersection)}`); +console.log(`Difference: ${JSON.stringify(difference)}`); + diff --git a/test/e2e/fixtures/typescript-vue.fixture b/test/e2e/fixtures/implementation/typescript-vue.fixture similarity index 59% rename from test/e2e/fixtures/typescript-vue.fixture rename to test/e2e/fixtures/implementation/typescript-vue.fixture index 301fa3fe..8272fb15 100644 --- a/test/e2e/fixtures/typescript-vue.fixture +++ b/test/e2e/fixtures/implementation/typescript-vue.fixture @@ -1,98 +1,3 @@ -/// package.json -{ - "name": "typescript-vue-fixture", - "version": "1.0.0", - "main": "dist/index.js", - "license": "MIT", - "dependencies": { - "vue": "^2.6.11", - "vue-class-component": "^7.2.2" - }, - "devDependencies": { - "css-loader": "^3.4.2", - "fork-ts-checker-webpack-plugin": ${FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION}, - "ts-loader": ${TS_LOADER_VERSION}, - "typescript": ${TYPESCRIPT_VERSION}, - "vue-loader": "^15.8.3", - "vue-template-compiler": "^2.6.11", - "webpack": ${WEBPACK_VERSION}, - "webpack-cli": ${WEBPACK_CLI_VERSION}, - "webpack-dev-server": ${WEBPACK_DEV_SERVER_VERSION} - } -} -/// tsconfig.json -{ - "compilerOptions": { - "experimentalDecorators": true, - "jsx": "preserve", - "target": "ES5", - "lib": ["ES6", "DOM"], - "baseUrl": ".", - "paths": { - "@/*": ["src/*"], - "~/*": ["src/*"] - }, - "sourceMap": true - }, - "include": [ - "src/**/*.ts", - "src/**/*.vue" - ], - "exclude": [ - "node_modules" - ] -} - -/// webpack.config.js -const path = require('path'); -const VueLoaderPlugin = require('vue-loader/lib/plugin'); -const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); - -module.exports = { - entry: './src/index.ts', - output: { - filename: 'index.js', - path: path.resolve(__dirname, 'dist'), - }, - module: { - rules: [ - { - test: /\.vue$/, - loader: 'vue-loader' - }, - { - test: /\.ts$/, - loader: 'ts-loader', - exclude: /node_modules/, - options: { - appendTsSuffixTo: [/\.vue$/] - } - }, - ], - }, - resolve: { - extensions: ['.ts', '.js', '.vue', '.json'], - alias: { - '@': path.resolve(__dirname, './src'), - '~': path.resolve(__dirname, './src'), - } - }, - plugins: [ - new VueLoaderPlugin(), - new ForkTsCheckerWebpackPlugin({ - async: ${ASYNC}, - typescript: { - extensions: { - vue: true - } - }, - logger: { - infrastructure: "console" - } - }) - ] -}; - /// src/index.ts import Vue from 'vue' import App from './App.vue' diff --git a/test/e2e/fixtures/type-definitions.fixture b/test/e2e/fixtures/type-definitions.fixture new file mode 100644 index 00000000..5d1c1ea9 --- /dev/null +++ b/test/e2e/fixtures/type-definitions.fixture @@ -0,0 +1,43 @@ +/// package.json +{ + "name": "type-definitions-fixture", + "version": "1.0.0", + "main": "dist/index.js", + "license": "MIT", + "scripts": { + "tsc": "tsc" + }, + "devDependencies": { + "fork-ts-checker-webpack-plugin": ${FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION}, + "typescript": "~3.8.0" + } +} + +/// tsconfig.json +{ + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "lib": ["ES6", "DOM"], + "moduleResolution": "node", + "esModuleInterop": true, + "skipLibCheck": true, + "skipDefaultLibCheck": true, + "strict": true, + "baseUrl": "./" + }, + "include": ["./"], + "exclude": ["node_modules"] +} + +/// webpack.config.ts +import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin'; + +const config = { + entry: './src/index.ts', + plugins: [ + new ForkTsCheckerWebpackPlugin({ + async: 'invalid_value' + }) + ] +}; diff --git a/test/e2e/fixtures/typescript-pnp.fixture b/test/e2e/fixtures/typescript-pnp.fixture deleted file mode 100644 index e2525279..00000000 --- a/test/e2e/fixtures/typescript-pnp.fixture +++ /dev/null @@ -1,179 +0,0 @@ -/// package.json -{ - "name": "typescript-basic-fixture", - "version": "1.0.0", - "main": "dist/index.js", - "license": "MIT", - "scripts": { - "webpack-dev-server": "webpack-dev-server" - }, - "devDependencies": { - "fork-ts-checker-webpack-plugin": ${FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION}, - "pnp-webpack-plugin": "^1.6.4", - "ts-loader": ${TS_LOADER_VERSION}, - "ts-pnp": "^1.2.0", - "typescript": ${TYPESCRIPT_VERSION}, - "webpack": ${WEBPACK_VERSION}, - "webpack-cli": ${WEBPACK_CLI_VERSION}, - "webpack-dev-server": ${WEBPACK_DEV_SERVER_VERSION} - }, - "installConfig": { - "pnp": true - } -} -/// tsconfig.json -{ - "compilerOptions": { - "target": "es5", - "module": "commonjs", - "lib": ["ES6", "DOM"], - "moduleResolution": "node", - "esModuleInterop": true, - "skipLibCheck": true, - "skipDefaultLibCheck": true, - "strict": true, - "baseUrl": "./src", - "outDir": "./dist" - }, - "include": ["./src"], - "exclude": ["node_modules"] -} -/// webpack.config.js -const path = require('path'); -const PnpWebpackPlugin = require(`pnp-webpack-plugin`); -const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); - -module.exports = { - entry: './src/index.ts', - output: { - filename: 'index.js', - path: path.resolve(__dirname, 'dist'), - }, - module: { - rules: [ - { - test: /\.tsx?$/, - loader: 'ts-loader', - exclude: /node_modules/, - options: PnpWebpackPlugin.tsLoaderOptions({ - transpileOnly: true - }) - }, - ], - }, - resolve: { - extensions: ['.tsx', '.ts', '.js'], - plugins: [ - PnpWebpackPlugin, - ] - }, - resolveLoader: { - plugins: [ - PnpWebpackPlugin.moduleLoader(module), - ], - }, - plugins: [ - new ForkTsCheckerWebpackPlugin({ - async: ${ASYNC}, - typescript: { - extensions: { - pnp: true - } - }, - logger: { - infrastructure: "console" - } - }) - ] -}; - -/// src/index.ts -import { login } from './authenticate'; -import { getUserName } from './model/User'; - -const emailInput = document.getElementById('email'); -const passwordInput = document.getElementById('password'); -const loginForm = document.getElementById('login'); - -if (!emailInput) { - throw new Error("Cannot find #email input."); -} -if (!passwordInput) { - throw new Error("Cannot find #password input."); -} -if (!loginForm) { - throw new Error("Cannot find #login form."); -} - -let email = ''; -let password = ''; - -emailInput.addEventListener('change', event => { - if (event.target instanceof HTMLInputElement) { - email = event.target.value; - } -}); -passwordInput.addEventListener('change', event => { - if (event.target instanceof HTMLInputElement) { - password = event.target.value; - } -}); -loginForm.addEventListener('submit', async event => { - const user = await login(email, password); - - if (user.role === 'admin') { - console.log(`Logged in as ${getUserName(user)} [admin].`); - } else { - console.log(`Logged in as ${getUserName(user)}`); - } -}); - -/// src/authenticate.ts -import { User } from './model/User'; - -async function login(email: string, password: string): Promise { - const response = await fetch( - '/login', - { - method: 'POST', - body: JSON.stringify({ email, password }) - } - ); - return response.json(); -} - -async function logout(): Promise { - const response = await fetch( - '/logout', - { - method: 'POST' - } - ); - return response.json(); -} - -export { login, logout }; - -/// src/model/User.ts -import { Role } from './Role'; - -type User = { - id: string; - email: string; - role: Role; - firstName?: string; - lastName?: string; -} - -function getUserName(user: User): string { - return [user.firstName, user.lastName] - .filter(name => name !== undefined) - .join(' '); -} - -export { User, getUserName }; - -/// src/model/Role.ts -type Role = "admin" | "client" | "provider"; - -export { Role }; diff --git a/test/e2e/fixtures/typescript-project-references.fixture b/test/e2e/fixtures/typescript-project-references.fixture deleted file mode 100644 index c403706a..00000000 --- a/test/e2e/fixtures/typescript-project-references.fixture +++ /dev/null @@ -1,192 +0,0 @@ -/// package.json -{ - "name": "typescript-project-references-fixture", - "version": "1.0.0", - "license": "MIT", - "private": true, - "scripts": { - "postinstall": "lerna bootstrap" - }, - "devDependencies": { - "lerna": "^3.0.0", - "fork-ts-checker-webpack-plugin": ${FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION}, - "ts-loader": ${TS_LOADER_VERSION}, - "typescript": ${TYPESCRIPT_VERSION}, - "webpack": ${WEBPACK_VERSION}, - "webpack-cli": ${WEBPACK_CLI_VERSION}, - "webpack-dev-server": ${WEBPACK_DEV_SERVER_VERSION} - } -} - -/// lerna.json -{ - "version": "1.0.0", - "npmClient": "npm", - "packages": ["packages/*"] -} - -/// tsconfig.json -{ - "compilerOptions": { - "target": "es5", - "module": "commonjs", - "lib": ["es5", "scripthost"], - "moduleResolution": "node", - "esModuleInterop": true, - "importHelpers": false, - "skipLibCheck": true, - "skipDefaultLibCheck": true, - "strict": true, - "baseUrl": ".", - "composite": true, - "incremental": true, - "declaration": true, - "declarationMap": true, - "sourceMap": true, - "rootDir": "./packages" - }, - "files": [], - "references": [ - { "path": "./packages/shared" }, - { "path": "./packages/client" } - ] -} - -/// webpack.config.js -const path = require('path'); -const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); - -module.exports = { - entry: './packages/client/src/index.ts', - output: { - filename: 'index.js', - path: path.resolve(__dirname, 'dist'), - }, - module: { - rules: [ - { - test: /\.tsx?$/, - loader: 'ts-loader', - exclude: /node_modules/, - options: { - transpileOnly: true, - projectReferences: true - } - }, - ], - }, - resolve: { - extensions: ['.tsx', '.ts', '.js'], - // as ts-loader doesn't fully support project references we put an alias to resolve package - // and to not pollute output with ts-loader errors - alias: { - "@project-references-fixture/shared": path.resolve(__dirname, "packages/shared/src") - } - }, - plugins: [ - new ForkTsCheckerWebpackPlugin({ - async: ${ASYNC}, - typescript: { - build: true - } - }) - ] -}; - - -/// packages/shared/package.json -{ - "name": "@project-references-fixture/shared", - "license": "MIT", - "version": "1.0.0", - "main": "lib/index.js", - "types": "lib/index.d.ts", - "files": [ - "lib" - ] -} - -/// packages/shared/tsconfig.json -{ - "extends": "../../tsconfig", - "compilerOptions": { - "rootDir": "./src", - "outDir": "./lib", - "sourceRoot": "./src", - "baseUrl": "./src" - }, - "include": ["src"], - "exclude": ["node_modules", "lib"] -} - -/// packages/shared/src/intersect.ts -function intersect(arrayA: T[] = [], arrayB: T[] = []): T[] { - return arrayA.filter((item) => arrayB.includes(item)); -} - -export default intersect; - -/// packages/shared/src/subtract.ts -function subtract(arrayA: T[] = [], arrayB: T[] = []): T[] { - return arrayA.filter((item) => !arrayB.includes(item)); -} - -export default subtract; - -/// packages/shared/src/index.ts -import intersect from "./intersect"; -import subtract from "./subtract"; - -export { - intersect, - subtract -} - -/// packages/client/package.json -{ - "name": "@project-references-fixture/client", - "license": "MIT", - "version": "1.0.0", - "main": "lib/index.js", - "types": "lib/index.d.ts", - "files": [ - "lib" - ], - "dependencies": { - "@project-references-fixture/shared": "1.0.0" - } -} - -/// packages/client/tsconfig.json -{ - "extends": "../../tsconfig", - "compilerOptions": { - "rootDir": "./src", - "outDir": "./lib", - "sourceRoot": "./src", - "baseUrl": "./src" - }, - "references": [{ "path": "../shared" }], - "include": ["src"], - "exclude": ["node_modules", "lib"] -} - - -/// packages/client/src/index.ts -import { intersect, subtract } from "@project-references-fixture/shared"; - -function compute(arrayA: T[], arrayB: T[]) { - const intersection = intersect(arrayA, arrayB); - const difference = subtract(arrayA, arrayB); - - return { - intersection, - difference - } -} - -const { intersection, difference } = compute(['a', 'b', 'c'], ['a', 'd', 'a']); - -console.log(`Intersection: ${JSON.stringify(intersection)}`); -console.log(`Difference: ${JSON.stringify(difference)}`); - diff --git a/test/e2e/sandbox/Sandbox.ts b/test/e2e/sandbox/Sandbox.ts index 35bed731..ed84c558 100644 --- a/test/e2e/sandbox/Sandbox.ts +++ b/test/e2e/sandbox/Sandbox.ts @@ -6,10 +6,14 @@ import spawn from 'cross-spawn'; import { Fixture } from './Fixture'; import stripAnsi from 'strip-ansi'; import kill from 'tree-kill'; +import flatten from '../../../src/utils/array/flatten'; interface Sandbox { context: string; - load: (fixture: Fixture, installer?: (sandbox: Sandbox) => Promise) => Promise; + load: ( + fixtures: Fixture | Fixture[], + installer?: (sandbox: Sandbox) => Promise + ) => Promise; reset: () => Promise; cleanup: () => Promise; write: (path: string, content: string) => Promise; @@ -86,7 +90,7 @@ async function createSandbox(): Promise { async function killChildProcesses() { for (const childProcess of childProcesses) { - if (!childProcess.killed) { + if (!childProcess.killed && childProcess.pid) { process.stdout.write(`Killing child process ${childProcess.pid}...\n`); await retry( () => @@ -117,9 +121,17 @@ async function createSandbox(): Promise { const sandbox: Sandbox = { context, load: async (fixture, installer = npmInstaller) => { + const fixtures = Array.isArray(fixture) ? fixture : [fixture]; + // write files - await Promise.all(Object.keys(fixture).map((path) => sandbox.write(path, fixture[path]))); - process.stdout.write('Fixture initialized.\n'); + await Promise.all( + flatten( + fixtures.map((fixture) => + Object.keys(fixture).map((path) => sandbox.write(path, fixture[path])) + ) + ) + ); + process.stdout.write('Fixtures initialized.\n'); process.stdout.write('Installing dependencies...\n'); await installer(sandbox); @@ -216,11 +228,11 @@ async function createSandbox(): Promise { ...env, }, }, - (error, output) => { + (error, stdout, stderr) => { if (error) { - reject(error); + reject(stdout + stderr); } else { - resolve(output); + resolve(stdout + stderr); } childProcesses = childProcesses.filter( (aChildProcess) => aChildProcess !== childProcess From 9584c02f058bc48b3eaaf4cde49555940a858798 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ole=C5=9B?= Date: Thu, 21 May 2020 21:23:52 +0200 Subject: [PATCH 22/29] feat: add support for cosmiconfig --- README.md | 8 +++++++- package.json | 2 ++ src/ForkTsCheckerWebpackPlugin.ts | 15 ++++++++++++++- ....spec.ts => OutOfMemoryAndCosmiconfig.spec.ts} | 15 ++++----------- test/e2e/fixtures/type-definitions.fixture | 5 ++++- 5 files changed, 31 insertions(+), 14 deletions(-) rename test/e2e/{PluginOutOfMemory.spec.ts => OutOfMemoryAndCosmiconfig.spec.ts} (87%) diff --git a/README.md b/README.md index b5bb7317..af1e61a2 100644 --- a/README.md +++ b/README.md @@ -131,7 +131,13 @@ There's a [good explanation on setting up TypeScript ESLint support by Robert Co ## Options -The top-level plugin options. +This plugin uses [`cosmiconfig`](https://github.com/davidtheclark/cosmiconfig). This means that besides the plugin constructor, +you can place your configuration in the: + * `"fork-ts-checker"` field in the `package.json` + * `.fork-ts-checkerrc` file in JSON or YAML format + * `fork-ts-checker.config.js` file exporting a JS object + +Options passed to the plugin constructor will overwrite options from the cosmiconfig (using [deepmerge](https://github.com/TehShrike/deepmerge)). | Name | Type | Default value | Description | | ----------------- | --------------------- | ------------------------------------------------ | ----------- | diff --git a/package.json b/package.json index e758eadf..8f6a5bfa 100644 --- a/package.json +++ b/package.json @@ -62,6 +62,8 @@ "dependencies": { "@babel/code-frame": "^7.8.3", "chalk": "^2.4.1", + "cosmiconfig": "^6.0.0", + "deepmerge": "^4.2.2", "fs-extra": "^9.0.0", "memfs": "^3.1.2", "minimatch": "^3.0.4", diff --git a/src/ForkTsCheckerWebpackPlugin.ts b/src/ForkTsCheckerWebpackPlugin.ts index 755e1c42..6243c4ff 100644 --- a/src/ForkTsCheckerWebpackPlugin.ts +++ b/src/ForkTsCheckerWebpackPlugin.ts @@ -1,5 +1,7 @@ import webpack from 'webpack'; import validateOptions from 'schema-utils'; +import { cosmiconfigSync } from 'cosmiconfig'; +import merge from 'deepmerge'; import schema from './ForkTsCheckerWebpackPluginOptions.json'; import { ForkTsCheckerWebpackPluginOptions } from './ForkTsCheckerWebpackPluginOptions'; import { createForkTsCheckerWebpackPluginConfiguration } from './ForkTsCheckerWebpackPluginConfiguration'; @@ -15,8 +17,19 @@ import { getForkTsCheckerWebpackPluginHooks } from './hooks/pluginHooks'; import { tapDoneToCollectRemoved } from './hooks/tapDoneToCollectRemoved'; class ForkTsCheckerWebpackPlugin implements webpack.Plugin { - constructor(private readonly options: ForkTsCheckerWebpackPluginOptions = {}) { + private readonly options: ForkTsCheckerWebpackPluginOptions; + + constructor(options: ForkTsCheckerWebpackPluginOptions = {}) { + const explorerSync = cosmiconfigSync('fork-ts-checker'); + const { config: externalOptions } = explorerSync.search() || {}; + + // first validate options directly passed to the constructor validateOptions(schema, options, 'ForkTsCheckerWebpackPlugin'); + + this.options = merge(externalOptions || {}, options || {}); + + // then validate merged options + validateOptions(schema, this.options, 'ForkTsCheckerWebpackPlugin'); } public static getCompilerHooks(compiler: webpack.Compiler) { diff --git a/test/e2e/PluginOutOfMemory.spec.ts b/test/e2e/OutOfMemoryAndCosmiconfig.spec.ts similarity index 87% rename from test/e2e/PluginOutOfMemory.spec.ts rename to test/e2e/OutOfMemoryAndCosmiconfig.spec.ts index cb114ef7..6bc48105 100644 --- a/test/e2e/PluginOutOfMemory.spec.ts +++ b/test/e2e/OutOfMemoryAndCosmiconfig.spec.ts @@ -3,7 +3,7 @@ import { createSandbox, FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION, Sandbox } from ' import { readFixture } from './sandbox/Fixture'; import { createGenericProcessDriver } from './sandbox/GenericProcessDriver'; -describe('ForkTsCheckerWebpackPlugin Out Of Memory', () => { +describe('ForkTsCheckerWebpackPlugin Out Of Memory and Cosmiconfig', () => { let sandbox: Sandbox; beforeAll(async () => { @@ -39,16 +39,9 @@ describe('ForkTsCheckerWebpackPlugin Out Of Memory', () => { await readFixture(join(__dirname, 'fixtures/implementation/typescript-basic.fixture')), ]); - await sandbox.patch( - 'webpack.config.js', - ' new ForkTsCheckerWebpackPlugin({', - [ - ' new ForkTsCheckerWebpackPlugin({', - ' typescript: {', - ' enabled: true,', - ' memoryLimit: 10,', - ' },', - ].join('\n') + await sandbox.write( + 'fork-ts-checker.config.js', + `module.exports = { typescript: { memoryLimit: 10 } };` ); const driver = createGenericProcessDriver(sandbox.spawn('npm run webpack-dev-server')); diff --git a/test/e2e/fixtures/type-definitions.fixture b/test/e2e/fixtures/type-definitions.fixture index 5d1c1ea9..3913d6a5 100644 --- a/test/e2e/fixtures/type-definitions.fixture +++ b/test/e2e/fixtures/type-definitions.fixture @@ -37,7 +37,10 @@ const config = { entry: './src/index.ts', plugins: [ new ForkTsCheckerWebpackPlugin({ - async: 'invalid_value' + async: 'invalid_value', + typescript: { + enabled: true + } }) ] }; From 44798648ac19764d402565b125daa824bf16b467 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ole=C5=9B?= Date: Thu, 21 May 2020 21:43:24 +0200 Subject: [PATCH 23/29] chore: add alpha branch to pre-release channels --- .eslintignore | 1 - .gitignore | 17 +++-------------- .nvmrc | 2 +- babel.config.js | 7 ------- changelog.config.js | 18 +++++++++--------- release.config.js | 18 +++++++++++------- src/types/eslint.ts | 1 + 7 files changed, 25 insertions(+), 39 deletions(-) delete mode 100644 babel.config.js diff --git a/.eslintignore b/.eslintignore index fc84a655..d96aa3d0 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,2 +1 @@ -/src/types/** /lib/** diff --git a/.gitignore b/.gitignore index 13388e8b..e8a005ce 100644 --- a/.gitignore +++ b/.gitignore @@ -1,28 +1,17 @@ # Logs -logs *.log -npm-debug.log* +# Package artifacts lib -!test/**/lib + +# Package archive used by e2e tests fork-ts-checker-webpack-plugin.tgz # Coverage directory used by tools like istanbul coverage -# Tmp directory for integration test -tmp - # Dependency directories node_modules -jspm_packages - -# Optional npm cache directory -.npm -package-lock.json - -# Optional REPL history -.node_repl_history # Editor directories and files .idea diff --git a/.nvmrc b/.nvmrc index 7d70dc47..f599e28b 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -6.9.11 +10 diff --git a/babel.config.js b/babel.config.js deleted file mode 100644 index 0b91385f..00000000 --- a/babel.config.js +++ /dev/null @@ -1,7 +0,0 @@ -// babel.config.js -module.exports = { - presets: [ - ['@babel/preset-env', { targets: { node: 'current' } }], - '@babel/preset-typescript' - ] -}; diff --git a/changelog.config.js b/changelog.config.js index 96465efc..2c27657a 100644 --- a/changelog.config.js +++ b/changelog.config.js @@ -6,31 +6,31 @@ module.exports = { types: { feat: { description: 'A new feature', - value: 'feat' + value: 'feat', }, fix: { description: 'A bug fix', - value: 'fix' + value: 'fix', }, refactor: { description: 'A code change that neither adds a feature or fixes a bug', - value: 'refactor' + value: 'refactor', }, perf: { description: 'A code change that improves performance', - value: 'perf' + value: 'perf', }, test: { description: 'Adding missing tests', - value: 'test' + value: 'test', }, chore: { description: 'Build process, CI or auxiliary tool changes', - value: 'chore' + value: 'chore', }, docs: { description: 'Documentation only changes', - value: 'docs' - } - } + value: 'docs', + }, + }, }; diff --git a/release.config.js b/release.config.js index c881cc04..c0f88d55 100644 --- a/release.config.js +++ b/release.config.js @@ -1,10 +1,14 @@ module.exports = { branches: [ 'master', + { + name: 'alpha', + prerelease: true, + }, { name: 'beta', - prerelease: true - } + prerelease: true, + }, ], plugins: [ [ @@ -18,12 +22,12 @@ module.exports = { { type: 'fix', release: 'patch' }, { type: 'perf', release: 'patch' }, { type: 'refactor', release: 'patch' }, - { type: 'docs', release: 'patch' } - ] - } + { type: 'docs', release: 'patch' }, + ], + }, ], '@semantic-release/release-notes-generator', '@semantic-release/npm', - '@semantic-release/github' - ] + '@semantic-release/github', + ], }; diff --git a/src/types/eslint.ts b/src/types/eslint.ts index 2ba6a18c..930d272c 100644 --- a/src/types/eslint.ts +++ b/src/types/eslint.ts @@ -42,5 +42,6 @@ export interface Options { // directly used by this package and are instead just passed to eslint. // We do this in order to avoid a dependency on @types/eslint (since the use // of eslint is optional) and to avoid copying types from @types/eslint. + // eslint-disable-next-line @typescript-eslint/no-explicit-any [key: string]: any; } From 0582b0049068416904451cb3f7f8f81c1456432a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ole=C5=9B?= Date: Thu, 21 May 2020 22:15:18 +0200 Subject: [PATCH 24/29] feat: use developer-friendly compilerOptions --- .../TypeScriptReporterConfiguration.ts | 47 ++++++++------ .../TypeScriptReporterOptions.ts | 3 +- test/e2e/TypeScriptCompilerOptions.spec.ts | 63 +++++++++++++++++++ tsconfig.json | 2 +- 4 files changed, 94 insertions(+), 21 deletions(-) create mode 100644 test/e2e/TypeScriptCompilerOptions.spec.ts diff --git a/src/typescript-reporter/TypeScriptReporterConfiguration.ts b/src/typescript-reporter/TypeScriptReporterConfiguration.ts index e14dae73..1b6b0eb3 100644 --- a/src/typescript-reporter/TypeScriptReporterConfiguration.ts +++ b/src/typescript-reporter/TypeScriptReporterConfiguration.ts @@ -1,6 +1,6 @@ import webpack from 'webpack'; import path from 'path'; -import { CompilerOptions as TypeScriptCompilerOptions } from 'typescript'; +import ts from 'typescript'; import { TypeScriptDiagnosticsOptions } from './TypeScriptDiagnosticsOptions'; import { TypeScriptReporterOptions } from './TypeScriptReporterOptions'; import { @@ -18,7 +18,7 @@ interface TypeScriptReporterConfiguration { memoryLimit: number; tsconfig: string; build: boolean; - compilerOptions: Partial; + compilerOptions: Partial; diagnosticOptions: TypeScriptDiagnosticsOptions; extensions: { vue: TypeScriptVueExtensionConfiguration; @@ -30,17 +30,37 @@ function createTypeScriptReporterConfiguration( compiler: webpack.Compiler, options: TypeScriptReporterOptions | undefined ): TypeScriptReporterConfiguration { - const configuration: TypeScriptReporterConfiguration = { - enabled: options !== false, - memoryLimit: 2048, - tsconfig: 'tsconfig.json', - build: false, - ...(typeof options === 'object' ? options : {}), - compilerOptions: { + let tsconfig: string = + typeof options === 'object' ? options.tsconfig || 'tsconfig.json' : 'tsconfig.json'; + + // ensure that `tsconfig` is an absolute path with normalized slash + tsconfig = normalizeSlash( + path.isAbsolute(tsconfig) + ? tsconfig + : path.resolve(compiler.options.context || process.cwd(), tsconfig) + ); + + // convert json compilerOptions to ts.CompilerOptions + const convertResults = ts.convertCompilerOptionsFromJson( + { skipDefaultLibCheck: true, skipLibCheck: true, ...(typeof options === 'object' ? options.compilerOptions || {} : {}), }, + compiler.options.context || process.cwd(), + tsconfig + ); + const convertedOptions = convertResults.options || {}; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { configFilePath, ...compilerOptions } = convertedOptions; + + return { + enabled: options !== false, + memoryLimit: 2048, + build: false, + ...(typeof options === 'object' ? options : {}), + tsconfig: tsconfig, + compilerOptions: compilerOptions, extensions: { vue: createTypeScriptVueExtensionConfiguration( typeof options === 'object' && options.extensions ? options.extensions.vue : undefined @@ -57,15 +77,6 @@ function createTypeScriptReporterConfiguration( ...((typeof options === 'object' && options.diagnosticOptions) || {}), }, }; - - // ensure that `typescript.tsconfig` is an absolute path with normalized slash - configuration.tsconfig = normalizeSlash( - path.isAbsolute(configuration.tsconfig) - ? configuration.tsconfig - : path.resolve(compiler.options.context || process.cwd(), configuration.tsconfig) - ); - - return configuration; } export { createTypeScriptReporterConfiguration, TypeScriptReporterConfiguration }; diff --git a/src/typescript-reporter/TypeScriptReporterOptions.ts b/src/typescript-reporter/TypeScriptReporterOptions.ts index f699fd90..989bf124 100644 --- a/src/typescript-reporter/TypeScriptReporterOptions.ts +++ b/src/typescript-reporter/TypeScriptReporterOptions.ts @@ -1,4 +1,3 @@ -import { CompilerOptions as TypeScriptCompilerOptions } from 'typescript'; import { TypeScriptDiagnosticsOptions } from './TypeScriptDiagnosticsOptions'; import { TypeScriptVueExtensionOptions } from './extension/vue/TypeScriptVueExtensionOptions'; import { TypeScriptPnpExtensionOptions } from './extension/pnp/TypeScriptPnpExtensionOptions'; @@ -9,7 +8,7 @@ type TypeScriptReporterOptions = enabled?: boolean; memoryLimit?: number; tsconfig?: string; - compilerOptions?: Partial; + compilerOptions?: object; diagnosticOptions?: Partial; extensions?: { vue?: TypeScriptVueExtensionOptions; diff --git a/test/e2e/TypeScriptCompilerOptions.spec.ts b/test/e2e/TypeScriptCompilerOptions.spec.ts new file mode 100644 index 00000000..c5e245f0 --- /dev/null +++ b/test/e2e/TypeScriptCompilerOptions.spec.ts @@ -0,0 +1,63 @@ +import { createSandbox, FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION, Sandbox } from './sandbox/Sandbox'; +import { readFixture } from './sandbox/Fixture'; +import { join } from 'path'; +import { + createWebpackDevServerDriver, + WEBPACK_CLI_VERSION, + WEBPACK_DEV_SERVER_VERSION, +} from './sandbox/WebpackDevServerDriver'; + +describe('TypeScript Compiler Options parsing', () => { + let sandbox: Sandbox; + + beforeAll(async () => { + sandbox = await createSandbox(); + }); + + beforeEach(async () => { + await sandbox.reset(); + }); + + afterAll(async () => { + await sandbox.cleanup(); + }); + + it.each([ + { typescript: '2.7.1' }, + { typescript: '~3.0.0' }, + { typescript: '~3.6.0' }, + { typescript: '^3.8.0' }, + ])( + 'reports errors because of the misconfiguration of "compilerOptions"', + async ({ typescript }) => { + await sandbox.load([ + await readFixture(join(__dirname, 'fixtures/environment/typescript-basic.fixture'), { + FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION: JSON.stringify( + FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION + ), + TS_LOADER_VERSION: JSON.stringify('^5.0.0'), + TYPESCRIPT_VERSION: JSON.stringify(typescript), + WEBPACK_VERSION: JSON.stringify('^4.0.0'), + WEBPACK_CLI_VERSION: JSON.stringify(WEBPACK_CLI_VERSION), + WEBPACK_DEV_SERVER_VERSION: JSON.stringify(WEBPACK_DEV_SERVER_VERSION), + ASYNC: JSON.stringify(false), + }), + await readFixture(join(__dirname, 'fixtures/implementation/typescript-basic.fixture')), + ]); + + await sandbox.write( + 'fork-ts-checker.config.js', + 'module.exports = { typescript: { compilerOptions: { target: "ES3", "lib": ["ES3"] } } };' + ); + + const driver = createWebpackDevServerDriver( + sandbox.spawn('npm run webpack-dev-server'), + false + ); + + const errors = await driver.waitForErrors(); + + expect(errors.length).toBeGreaterThan(0); + } + ); +}); diff --git a/tsconfig.json b/tsconfig.json index 87fa7ff9..44f294f4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "es6", + "target": "ES6", "module": "commonjs", "lib": ["ES6"], "moduleResolution": "node", From f8c47dfe387636ed107fc90fca4a885c3afd9669 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ole=C5=9B?= Date: Thu, 21 May 2020 22:25:54 +0200 Subject: [PATCH 25/29] feat: improve support for the `incremental` mode --- README.md | 2 +- src/ForkTsCheckerWebpackPluginOptions.json | 4 + .../TypeScriptReporterOptions.ts | 1 + .../reporter/TypeScriptReporter.ts | 4 +- test/e2e/TypeScriptSolutionBuilderApi.spec.ts | 143 +++++++++--------- 5 files changed, 77 insertions(+), 77 deletions(-) diff --git a/README.md b/README.md index af1e61a2..83908141 100644 --- a/README.md +++ b/README.md @@ -157,7 +157,7 @@ Options for the TypeScript checker (`typescript` option object). | `enabled` | `boolean` | `true` | If `true`, it enables TypeScript checker. | | `memoryLimit` | `number` | `2048` | Memory limit for the checker process in MB. If the process exits with the allocation failed error, try to increase this number. | | `tsconfig` | `string` | `'tsconfig.json'` | Path to the `tsconfig.json` file (path relative to the `compiler.options.context` or absolute path) | -| `build` | `boolean` | `false` | The equivalent of the `--build` flag for the `tsc` command. | +| `build` | `boolean` | `false` | The equivalent of the `--build` flag for the `tsc` command. To enable `incremental` mode, set it in the `tsconfig.json` file. _Note that this plugin doesn't emit any files even in the `build` mode._ | | `compilerOptions` | `object` | `{ skipLibCheck: true, skipDefaultLibCheck: true }` | These options will overwrite compiler options from the `tsconfig.json` file. | | `diagnosticsOptions` | `object` | `{ syntactic: false, semantic: true, declaration: false, global: false }` | Settings to select which diagnostics do we want to perform. | | `extensions` | `object` | `{}` | See [TypeScript extensions options](#typescript-extensions-options). | diff --git a/src/ForkTsCheckerWebpackPluginOptions.json b/src/ForkTsCheckerWebpackPluginOptions.json index 4915a01a..1bcf3c3f 100644 --- a/src/ForkTsCheckerWebpackPluginOptions.json +++ b/src/ForkTsCheckerWebpackPluginOptions.json @@ -121,6 +121,10 @@ "type": "boolean", "description": "The equivalent of the `--build` flag from the `tsc`." }, + "incremental": { + "type": "boolean", + "description": "The equivalent of the `--incremental` flag from the `tsc`." + }, "compilerOptions": { "type": "object", "description": "Custom compilerOptions to be passed to the TypeScript compiler.", diff --git a/src/typescript-reporter/TypeScriptReporterOptions.ts b/src/typescript-reporter/TypeScriptReporterOptions.ts index 989bf124..e088956c 100644 --- a/src/typescript-reporter/TypeScriptReporterOptions.ts +++ b/src/typescript-reporter/TypeScriptReporterOptions.ts @@ -8,6 +8,7 @@ type TypeScriptReporterOptions = enabled?: boolean; memoryLimit?: number; tsconfig?: string; + build?: boolean; compilerOptions?: object; diagnosticOptions?: Partial; extensions?: { diff --git a/src/typescript-reporter/reporter/TypeScriptReporter.ts b/src/typescript-reporter/reporter/TypeScriptReporter.ts index 86ba38ba..18f6ed3d 100644 --- a/src/typescript-reporter/reporter/TypeScriptReporter.ts +++ b/src/typescript-reporter/reporter/TypeScriptReporter.ts @@ -103,9 +103,7 @@ function createTypeScriptReporter(configuration: TypeScriptReporterConfiguration solutionBuilder = ts.createSolutionBuilderWithWatch( watchSolutionBuilderHost, [configuration.tsconfig], - { - incremental: true, - } + {} ); solutionBuilder.build(); } diff --git a/test/e2e/TypeScriptSolutionBuilderApi.spec.ts b/test/e2e/TypeScriptSolutionBuilderApi.spec.ts index af21def0..162ca439 100644 --- a/test/e2e/TypeScriptSolutionBuilderApi.spec.ts +++ b/test/e2e/TypeScriptSolutionBuilderApi.spec.ts @@ -22,85 +22,82 @@ describe('TypeScript SolutionBuilder API', () => { await sandbox.cleanup(); }); - it.each([{ async: false }, { async: true }])( - 'reports semantic error for %p', - async ({ async }) => { - await sandbox.load([ - await readFixture(join(__dirname, 'fixtures/environment/typescript-monorepo.fixture'), { - FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION: JSON.stringify( - FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION - ), - TS_LOADER_VERSION: JSON.stringify('^7.0.1'), - TYPESCRIPT_VERSION: JSON.stringify('~3.8.0'), - WEBPACK_VERSION: JSON.stringify('^4.0.0'), - WEBPACK_CLI_VERSION: JSON.stringify(WEBPACK_CLI_VERSION), - WEBPACK_DEV_SERVER_VERSION: JSON.stringify(WEBPACK_DEV_SERVER_VERSION), - ASYNC: JSON.stringify(async), - }), - await readFixture(join(__dirname, 'fixtures/implementation/typescript-monorepo.fixture')), - ]); + it.each([ + { async: false, typescript: '~3.6.0' }, + { async: true, typescript: '~3.8.0' }, + ])('reports semantic error for %p', async ({ async, typescript }) => { + await sandbox.load([ + await readFixture(join(__dirname, 'fixtures/environment/typescript-monorepo.fixture'), { + FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION: JSON.stringify( + FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION + ), + TS_LOADER_VERSION: JSON.stringify('^7.0.1'), + TYPESCRIPT_VERSION: JSON.stringify(typescript), + WEBPACK_VERSION: JSON.stringify('^4.0.0'), + WEBPACK_CLI_VERSION: JSON.stringify(WEBPACK_CLI_VERSION), + WEBPACK_DEV_SERVER_VERSION: JSON.stringify(WEBPACK_DEV_SERVER_VERSION), + ASYNC: JSON.stringify(async), + }), + await readFixture(join(__dirname, 'fixtures/implementation/typescript-monorepo.fixture')), + ]); - const driver = createWebpackDevServerDriver( - sandbox.spawn('npm run webpack-dev-server'), - async - ); - let errors: string[]; + const driver = createWebpackDevServerDriver(sandbox.spawn('npm run webpack-dev-server'), async); + let errors: string[]; - // initial compilation should be successful - await driver.waitForNoErrors(); + // initial compilation should be successful + await driver.waitForNoErrors(); - // create semantic error in shared package - await sandbox.patch('packages/shared/src/intersect.ts', 'arrayB: T[] = []', 'arrayB: T'); + // create semantic error in shared package + await sandbox.patch('packages/shared/src/intersect.ts', 'arrayB: T[] = []', 'arrayB: T'); - // this compilation should contain semantic error in the shared project - // (there is also an error in the client project but as its dependency is not built, it will not be processed) - errors = await driver.waitForErrors(); - expect(errors).toEqual([ - [ - 'ERROR in packages/shared/src/intersect.ts 2:41-49', - "TS2339: Property 'includes' does not exist on type 'T'.", - ' 1 | function intersect(arrayA: T[] = [], arrayB: T): T[] {', - ' > 2 | return arrayA.filter((item) => arrayB.includes(item));', - ' | ^^^^^^^^', - ' 3 | }', - ' 4 | ', - ' 5 | export default intersect;', - ].join('\n'), - ]); + // this compilation should contain semantic error in the shared project + // (there is also an error in the client project but as its dependency is not built, it will not be processed) + errors = await driver.waitForErrors(); + expect(errors).toEqual([ + [ + 'ERROR in packages/shared/src/intersect.ts 2:41-49', + "TS2339: Property 'includes' does not exist on type 'T'.", + ' 1 | function intersect(arrayA: T[] = [], arrayB: T): T[] {', + ' > 2 | return arrayA.filter((item) => arrayB.includes(item));', + ' | ^^^^^^^^', + ' 3 | }', + ' 4 | ', + ' 5 | export default intersect;', + ].join('\n'), + ]); - // fix semantic error in the shared package - await sandbox.patch( - 'packages/shared/src/intersect.ts', - 'return arrayA.filter((item) => arrayB.includes(item));', - 'return arrayA.filter((item) => item && arrayB);' - ); + // fix semantic error in the shared package + await sandbox.patch( + 'packages/shared/src/intersect.ts', + 'return arrayA.filter((item) => arrayB.includes(item));', + 'return arrayA.filter((item) => item && arrayB);' + ); - // this compilation should contain semantic error in the client project - errors = await driver.waitForErrors(); - expect(errors).toEqual([ - [ - 'ERROR in packages/client/src/index.ts 4:42-48', - "TS2345: Argument of type 'T[]' is not assignable to parameter of type 'T'.", - " 'T[]' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'.", - ' 2 | ', - ' 3 | function compute(arrayA: T[], arrayB: T[]) {', - ' > 4 | const intersection = intersect(arrayA, arrayB);', - ' | ^^^^^^', - ' 5 | const difference = subtract(arrayA, arrayB);', - ' 6 | ', - ' 7 | return {', - ].join('\n'), - ]); + // this compilation should contain semantic error in the client project + errors = await driver.waitForErrors(); + expect(errors).toEqual([ + [ + 'ERROR in packages/client/src/index.ts 4:42-48', + "TS2345: Argument of type 'T[]' is not assignable to parameter of type 'T'.", + " 'T[]' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'.", + ' 2 | ', + ' 3 | function compute(arrayA: T[], arrayB: T[]) {', + ' > 4 | const intersection = intersect(arrayA, arrayB);', + ' | ^^^^^^', + ' 5 | const difference = subtract(arrayA, arrayB);', + ' 6 | ', + ' 7 | return {', + ].join('\n'), + ]); - // fix semantic error in the client package - await sandbox.patch( - 'packages/client/src/index.ts', - 'const intersection = intersect(arrayA, arrayB);', - 'const intersection = intersect(arrayA, arrayB[0]);' - ); + // fix semantic error in the client package + await sandbox.patch( + 'packages/client/src/index.ts', + 'const intersection = intersect(arrayA, arrayB);', + 'const intersection = intersect(arrayA, arrayB[0]);' + ); - // this compilation should be successful - await driver.waitForNoErrors(); - } - ); + // this compilation should be successful + await driver.waitForNoErrors(); + }); }); From 9fe78527693b7ea523fa4cf64f1483759dc85158 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ole=C5=9B?= Date: Fri, 22 May 2020 10:16:19 +0200 Subject: [PATCH 26/29] feat: support webpack-dev-server errors for async mode Thanks @ypresto for the implementation of https://github.com/ypresto/fork-ts-checker-async-overlay-webpack-plugin - it was integrated with the plugin in this commit. --- src/ForkTsCheckerWebpackPluginState.ts | 3 +++ src/hooks/getWatcher.ts | 4 +++- .../interceptDoneToGetWebpackDevServerTap.ts | 21 +++++++++++++++++++ src/hooks/tapDoneToAsyncGetIssues.ts | 19 +++++++++++++++++ src/hooks/tapStartToConnectAndRunReporter.ts | 2 ++ 5 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 src/hooks/interceptDoneToGetWebpackDevServerTap.ts diff --git a/src/ForkTsCheckerWebpackPluginState.ts b/src/ForkTsCheckerWebpackPluginState.ts index 52ff6963..3938e8e7 100644 --- a/src/ForkTsCheckerWebpackPluginState.ts +++ b/src/ForkTsCheckerWebpackPluginState.ts @@ -1,10 +1,12 @@ import { Report } from './reporter'; +import { Tap } from 'tapable'; interface ForkTsCheckerWebpackPluginState { report: Promise; removedFiles: string[]; watching: boolean; initialized: boolean; + webpackDevServerDoneTap: Tap | undefined; } function createForkTsCheckerWebpackPluginState(): ForkTsCheckerWebpackPluginState { @@ -13,6 +15,7 @@ function createForkTsCheckerWebpackPluginState(): ForkTsCheckerWebpackPluginStat removedFiles: [], watching: false, initialized: false, + webpackDevServerDoneTap: undefined, }; } diff --git a/src/hooks/getWatcher.ts b/src/hooks/getWatcher.ts index e0bd3dce..ffde307d 100644 --- a/src/hooks/getWatcher.ts +++ b/src/hooks/getWatcher.ts @@ -10,7 +10,9 @@ function getWatcher(compiler: webpack.Compiler): Watcher | undefined { // eslint-disable-next-line @typescript-eslint/no-explicit-any const { watchFileSystem } = compiler as any; - return watchFileSystem.watcher || (watchFileSystem.wfs && watchFileSystem.wfs.watcher); + if (watchFileSystem) { + return watchFileSystem.watcher || (watchFileSystem.wfs && watchFileSystem.wfs.watcher); + } } export { getWatcher, Watcher }; diff --git a/src/hooks/interceptDoneToGetWebpackDevServerTap.ts b/src/hooks/interceptDoneToGetWebpackDevServerTap.ts new file mode 100644 index 00000000..e23bb10c --- /dev/null +++ b/src/hooks/interceptDoneToGetWebpackDevServerTap.ts @@ -0,0 +1,21 @@ +import webpack from 'webpack'; +import { ForkTsCheckerWebpackPluginConfiguration } from '../ForkTsCheckerWebpackPluginConfiguration'; +import { ForkTsCheckerWebpackPluginState } from '../ForkTsCheckerWebpackPluginState'; + +function interceptDoneToGetWebpackDevServerTap( + compiler: webpack.Compiler, + configuration: ForkTsCheckerWebpackPluginConfiguration, + state: ForkTsCheckerWebpackPluginState +) { + // inspired by https://github.com/ypresto/fork-ts-checker-async-overlay-webpack-plugin + compiler.hooks.done.intercept({ + register: (tap) => { + if (tap.name === 'webpack-dev-server' && tap.type === 'sync') { + state.webpackDevServerDoneTap = tap; + } + return tap; + }, + }); +} + +export { interceptDoneToGetWebpackDevServerTap }; diff --git a/src/hooks/tapDoneToAsyncGetIssues.ts b/src/hooks/tapDoneToAsyncGetIssues.ts index c3f214b9..ee4fdcb5 100644 --- a/src/hooks/tapDoneToAsyncGetIssues.ts +++ b/src/hooks/tapDoneToAsyncGetIssues.ts @@ -4,6 +4,7 @@ import { ForkTsCheckerWebpackPluginState } from '../ForkTsCheckerWebpackPluginSt import { getForkTsCheckerWebpackPluginHooks } from './pluginHooks'; import { createWebpackFormatter } from '../formatter/WebpackFormatter'; import { Issue } from '../issue'; +import { IssueWebpackError } from '../issue/IssueWebpackError'; import isPending from '../utils/async/isPending'; import wait from '../utils/async/wait'; import chalk from 'chalk'; @@ -59,6 +60,24 @@ function tapDoneToAsyncGetIssues( configuration.logger.issues.log(chalk.green('No issues found.')); } + if (state.webpackDevServerDoneTap) { + issues.forEach((issue) => { + const error = new IssueWebpackError( + configuration.formatter(issue), + compiler.options.context || process.cwd(), + issue + ); + + if (issue.severity === 'warning') { + stats.compilation.warnings.push(error); + } else { + stats.compilation.errors.push(error); + } + }); + + state.webpackDevServerDoneTap.fn(stats); + } + if (stats.startTime) { configuration.logger.infrastructure.info( `Time: ${Math.round(Date.now() - stats.startTime).toString()} ms` diff --git a/src/hooks/tapStartToConnectAndRunReporter.ts b/src/hooks/tapStartToConnectAndRunReporter.ts index 94297b79..11a3bf42 100644 --- a/src/hooks/tapStartToConnectAndRunReporter.ts +++ b/src/hooks/tapStartToConnectAndRunReporter.ts @@ -8,6 +8,7 @@ import { getChangedFiles } from './getChangedFiles'; import { OperationCanceledError } from '../error/OperationCanceledError'; import { tapDoneToAsyncGetIssues } from './tapDoneToAsyncGetIssues'; import { tapAfterCompileToGetIssues } from './tapAfterCompileToGetIssues'; +import { interceptDoneToGetWebpackDevServerTap } from './interceptDoneToGetWebpackDevServerTap'; function tapStartToConnectAndRunReporter( compiler: webpack.Compiler, @@ -33,6 +34,7 @@ function tapStartToConnectAndRunReporter( state.watching = true; if (configuration.async) { tapDoneToAsyncGetIssues(compiler, configuration, state); + interceptDoneToGetWebpackDevServerTap(compiler, configuration, state); } else { tapAfterCompileToGetIssues(compiler, configuration, state); } From 8b383dfaa3b3a049dcc2d194da078f3573e2bdd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ole=C5=9B?= Date: Fri, 22 May 2020 11:35:30 +0200 Subject: [PATCH 27/29] feat: add support for eslint fix in the new codebase --- .../reporter/EsLintReporter.ts | 5 ++ src/eslint-reporter/types/eslint.ts | 1 + test/e2e/EsLint.spec.ts | 51 +++++++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/src/eslint-reporter/reporter/EsLintReporter.ts b/src/eslint-reporter/reporter/EsLintReporter.ts index 39470860..36766ab3 100644 --- a/src/eslint-reporter/reporter/EsLintReporter.ts +++ b/src/eslint-reporter/reporter/EsLintReporter.ts @@ -43,6 +43,11 @@ function createEsLintReporter(configuration: EsLintReporterConfiguration): Repor } } + // output fixes if `fix` option is provided + if (configuration.options.fix) { + await Promise.all(lintReports.map((lintReport) => CLIEngine.outputFixes(lintReport))); + } + // store results lintReports.forEach((lintReport) => { lintReport.results.forEach((lintResult) => { diff --git a/src/eslint-reporter/types/eslint.ts b/src/eslint-reporter/types/eslint.ts index bc4d811b..058fc8f5 100644 --- a/src/eslint-reporter/types/eslint.ts +++ b/src/eslint-reporter/types/eslint.ts @@ -34,6 +34,7 @@ export interface CLIEngine { export interface CLIEngineOptions { cwd?: string; extensions?: string[]; + fix?: boolean; // eslint-disable-next-line @typescript-eslint/no-explicit-any [key: string]: any; } diff --git a/test/e2e/EsLint.spec.ts b/test/e2e/EsLint.spec.ts index 27a20547..3fbb737b 100644 --- a/test/e2e/EsLint.spec.ts +++ b/test/e2e/EsLint.spec.ts @@ -123,4 +123,55 @@ describe('EsLint', () => { ].join('\n'), ]); }); + + it('fixes errors with `fix: true` option', async () => { + await sandbox.load([ + await readFixture(join(__dirname, 'fixtures/environment/eslint-basic.fixture'), { + FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION: JSON.stringify( + FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION + ), + TS_LOADER_VERSION: JSON.stringify('^5.0.0'), + TYPESCRIPT_VERSION: JSON.stringify('~3.8.0'), + WEBPACK_VERSION: JSON.stringify('^4.0.0'), + WEBPACK_CLI_VERSION: JSON.stringify(WEBPACK_CLI_VERSION), + WEBPACK_DEV_SERVER_VERSION: JSON.stringify(WEBPACK_DEV_SERVER_VERSION), + ASYNC: JSON.stringify(false), + }), + await readFixture(join(__dirname, 'fixtures/implementation/typescript-basic.fixture')), + ]); + + // fix initial issues + await sandbox.patch( + 'src/authenticate.ts', + 'async function logout(): Promise {', + 'async function logout(): Promise {' + ); + await sandbox.patch( + 'src/index.ts', + "loginForm.addEventListener('submit', async event => {", + "loginForm.addEventListener('submit', async () => {" + ); + + // set fix option for the eslint + await sandbox.write( + 'fork-ts-checker.config.js', + 'module.exports = { eslint: { enabled: true, options: { fix: true } } };' + ); + + // add fixable issue + await sandbox.patch( + 'src/authenticate.ts', + 'const response = await fetch(', + 'let response = await fetch(' + ); + + const driver = createWebpackDevServerDriver(sandbox.spawn('npm run webpack-dev-server'), false); + + // it should be automatically fixed + await driver.waitForNoErrors(); + + // check if issue has been fixed + const content = await sandbox.read('src/authenticate.ts'); + expect(content).not.toContain('let response = await fetch('); + }); }); From 8247ef852c1ade3a9b0728cc1bd630c7bbf8d52b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ole=C5=9B?= Date: Sat, 23 May 2020 11:16:35 +0200 Subject: [PATCH 28/29] fix: resolve vue.js cache bug and add e2e tests --- README.md | 127 +++++++++++++++++- .../extension/TypeScriptEmbeddedExtension.ts | 2 +- test/e2e/TypeScriptVueExtension.spec.ts | 69 +++++++++- .../environment/typescript-vue.fixture | 16 ++- 4 files changed, 203 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 83908141..9f922cbf 100644 --- a/README.md +++ b/README.md @@ -14,10 +14,11 @@ ## Features - * Faster [TypeScript](https://github.com/Microsoft/TypeScript) type checking and [ESLint](https://eslint.org/) linting (each on a separate process) ๐ŸŽ - * Support for modern TypeScript features like [project references](https://www.typescriptlang.org/docs/handbook/project-references.html) and [incremental mode](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#faster-subsequent-builds-with-the---incremental-flag) โœจ - * Support for [Yarn PnP](https://classic.yarnpkg.com/en/docs/pnp/) ๐Ÿงถ - * Nice errors reporting with the [code frame](https://babeljs.io/docs/en/next/babel-code-frame.html) formatter ๐ŸŒˆ + * Speeds up [TypeScript](https://github.com/Microsoft/TypeScript) type checking and [ESLint](https://eslint.org/) linting (by moving each to a separate process) ๐ŸŽ + * Supports modern TypeScript features like [project references](https://www.typescriptlang.org/docs/handbook/project-references.html) and [incremental mode](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#faster-subsequent-builds-with-the---incremental-flag) โœจ + * Supports [Yarn PnP](https://classic.yarnpkg.com/en/docs/pnp/) ๐Ÿงถ + * Supports [Vue Single File Component](https://vuejs.org/v2/guide/single-file-components.html) โœ…ย  + * Displays nice error messages with the [code frame](https://babeljs.io/docs/en/next/babel-code-frame.html) formatter ๐ŸŒˆ ## Installation @@ -194,6 +195,10 @@ Options for the issues filtering (`issues` option object). | `exclude` | `object` or `function` or `array` | `undefined` | Same as `include` but issues that match this predicate will be excluded. | ## Yarn PnP +To enable Yarn PnP support, follow these steps: + +
+Expand Yarn PnP set up instruction To enable Yarn PnP, you have to install [`ts-pnp`](https://github.com/arcanis/ts-pnp) and [`pnp-webpack-plugin`](https://github.com/arcanis/pnp-webpack-plugin) package: @@ -243,6 +248,120 @@ module.exports = { ] }; ``` +
+ +## Vue.js + +โš ๏ธ There are additional **constraints** regarding Vue.js Single File Component support: โš ๏ธ + * It requires **TypeScript >= 3.8.0** and `"importsNotUsedAsValues": "preserve"` option in the `tsconfig.json` (it's a limitation of the `transpileOnly` mode from `ts-loader`) + * It doesn't work with the `build` mode (project references) + +To enable Vue.js support, follow these steps: + +
+Expand Vue.js set up instruction + +1. Ensure you have all required packages installed: +```sh +# with npm +npm install --save vue vue-class-component +npm install --save-dev vue-loader ts-loader css-loader vue-template-compiler + +# with yarn +yarn add vue vue-class-component +yarn add --dev vue-loader ts-loader css-loader vue-template-compiler +``` + +2. Add `tsconfig.json` configuration: +```json +{ + "compilerOptions": { + "experimentalDecorators": true, + "jsx": "preserve", + "target": "ES5", + "lib": ["ES6", "DOM"], + "baseUrl": ".", + "paths": { + "@/*": ["src/*"], + "~/*": ["src/*"] + }, + "sourceMap": true, + "importsNotUsedAsValues": "preserve" + }, + "include": [ + "src/**/*.ts", + "src/**/*.vue" + ], + "exclude": [ + "node_modules" + ] +} +``` + +3. Add `webpack.config.js` configuration: +```js +const path = require('path'); +const VueLoaderPlugin = require('vue-loader/lib/plugin'); +const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); + +module.exports = { + entry: './src/index.ts', + output: { + filename: 'index.js', + path: path.resolve(__dirname, 'dist'), + }, + module: { + rules: [ + { + test: /\.vue$/, + loader: 'vue-loader' + }, + { + test: /\.ts$/, + loader: 'ts-loader', + exclude: /node_modules/, + options: { + appendTsSuffixTo: [/\.vue$/], + transpileOnly: true + } + }, + { + test: /\.css$/, + loader: 'css-loader' + }, + ], + }, + resolve: { + extensions: ['.ts', '.js', '.vue', '.json'], + alias: { + '@': path.resolve(__dirname, './src'), + '~': path.resolve(__dirname, './src'), + } + }, + plugins: [ + new VueLoaderPlugin(), + new ForkTsCheckerWebpackPlugin({ + typescript: { + extensions: { + vue: true + } + } + }) + ] +}; +``` + +4. Add `src/types/vue.d.ts` file to shim `.vue` modules: +```typescript +declare module "*.vue" { + import Vue from "vue"; + export default Vue; +} +``` + +5. If you are working in VSCode, you can get the [Vetur](https://marketplace.visualstudio.com/items?itemName=octref.vetur) extension to complete the developer workflow. + +
## Type-Only modules watching diff --git a/src/typescript-reporter/extension/TypeScriptEmbeddedExtension.ts b/src/typescript-reporter/extension/TypeScriptEmbeddedExtension.ts index ac5b4b34..fc5f630f 100644 --- a/src/typescript-reporter/extension/TypeScriptEmbeddedExtension.ts +++ b/src/typescript-reporter/extension/TypeScriptEmbeddedExtension.ts @@ -122,7 +122,7 @@ function createTypeScriptEmbeddedExtension({ return host.watchFile( embeddedFileName, (innerFileName: string, eventKind: ts.FileWatcherEventKind) => { - embeddedSourceCache.delete(innerFileName); + embeddedSourceCache.delete(embeddedFileName); return callback(fileName, eventKind); }, poolingInterval diff --git a/test/e2e/TypeScriptVueExtension.spec.ts b/test/e2e/TypeScriptVueExtension.spec.ts index a5c3d4c9..c81352f0 100644 --- a/test/e2e/TypeScriptVueExtension.spec.ts +++ b/test/e2e/TypeScriptVueExtension.spec.ts @@ -22,9 +22,9 @@ describe('TypeScript Vue Extension', () => { await sandbox.cleanup(); }); - it.each([{ async: true, webpack: '^4.0.0', typescript: '2.7.1', tsloader: '^5.0.0' }])( + it.each([{ async: false, typescript: '^3.8.0', tsloader: '^7.0.0' }])( 'reports semantic error for %p', - async ({ async, webpack, typescript, tsloader }) => { + async ({ async, typescript, tsloader }) => { await sandbox.load([ await readFixture(join(__dirname, 'fixtures/environment/typescript-vue.fixture'), { FORK_TS_CHECKER_WEBPACK_PLUGIN_VERSION: JSON.stringify( @@ -32,7 +32,7 @@ describe('TypeScript Vue Extension', () => { ), TS_LOADER_VERSION: JSON.stringify(tsloader), TYPESCRIPT_VERSION: JSON.stringify(typescript), - WEBPACK_VERSION: JSON.stringify(webpack), + WEBPACK_VERSION: JSON.stringify('^4.0.0'), WEBPACK_CLI_VERSION: JSON.stringify(WEBPACK_CLI_VERSION), WEBPACK_DEV_SERVER_VERSION: JSON.stringify(WEBPACK_DEV_SERVER_VERSION), ASYNC: JSON.stringify(async), @@ -44,11 +44,72 @@ describe('TypeScript Vue Extension', () => { sandbox.spawn('npm run webpack-dev-server'), async ); + let errors: string[] = []; // first compilation is successful await driver.waitForNoErrors(); - // TODO: it seems that single-file components are broken on the ts-loader/typescript side + // let's modify user model file + await sandbox.patch( + 'src/component/LoggedIn.vue', + "import User, { getUserName } from '@/model/User';", + "import User from '@/model/User';" + ); + + // next compilation should have missing function error + errors = await driver.waitForErrors(); + expect(errors).toEqual([ + [ + 'ERROR in src/component/LoggedIn.vue 28:24-35', + "TS2304: Cannot find name 'getUserName'.", + ' 26 | ', + ' 27 | get userName() {', + " > 28 | return this.user ? getUserName(this.user) : '';", + ' | ^^^^^^^^^^^', + ' 29 | }', + ' 30 | ', + ' 31 | async logout() {', + ].join('\n'), + ]); + + // let's fix it + await sandbox.patch( + 'src/component/LoggedIn.vue', + "return this.user ? getUserName(this.user) : '';", + "return this.user ? `${this.user.firstName} ${this.user.lastName}` : '';" + ); + + await driver.waitForNoErrors(); + + // let's modify user model file again + await sandbox.patch('src/model/User.ts', ' firstName?: string;\n', ''); + + // not we should have an error about missing firstName property + errors = await driver.waitForErrors(); + expect(errors).toEqual([ + [ + 'ERROR in src/component/LoggedIn.vue 28:37-46', + "TS2339: Property 'firstName' does not exist on type 'User'.", + ' 26 | ', + ' 27 | get userName() {', + " > 28 | return this.user ? `${this.user.firstName} ${this.user.lastName}` : '';", + ' | ^^^^^^^^^', + ' 29 | }', + ' 30 | ', + ' 31 | async logout() {', + ].join('\n'), + [ + 'ERROR in src/model/User.ts 11:16-25', + "TS2339: Property 'firstName' does not exist on type 'User'.", + ' 9 | ', + ' 10 | function getUserName(user: User): string {', + ' > 11 | return [user.firstName, user.lastName]', + ' | ^^^^^^^^^', + ' 12 | .filter(name => name !== undefined)', + " 13 | .join(' ');", + ' 14 | }', + ].join('\n'), + ]); } ); }); diff --git a/test/e2e/fixtures/environment/typescript-vue.fixture b/test/e2e/fixtures/environment/typescript-vue.fixture index 8b232c98..d20ff861 100644 --- a/test/e2e/fixtures/environment/typescript-vue.fixture +++ b/test/e2e/fixtures/environment/typescript-vue.fixture @@ -36,7 +36,8 @@ "@/*": ["src/*"], "~/*": ["src/*"] }, - "sourceMap": true + "sourceMap": true, + "importsNotUsedAsValues": "preserve" }, "include": [ "src/**/*.ts", @@ -69,9 +70,14 @@ module.exports = { loader: 'ts-loader', exclude: /node_modules/, options: { - appendTsSuffixTo: [/\.vue$/] + appendTsSuffixTo: [/\.vue$/], + transpileOnly: true } }, + { + test: /\.css$/, + loader: 'css-loader' + }, ], }, resolve: { @@ -96,3 +102,9 @@ module.exports = { }) ] }; + +/// src/vue-shim.d.ts +declare module "*.vue" { + import Vue from "vue"; + export default Vue; +} From d8ccc154e23286fd0b8d81dfde196c2b38efb098 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ole=C5=9B?= Date: Sat, 23 May 2020 12:00:00 +0200 Subject: [PATCH 29/29] feat: improve message for vue.js compiler loading error --- .../extension/vue/TypeScriptVueExtensionSupport.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/typescript-reporter/extension/vue/TypeScriptVueExtensionSupport.ts b/src/typescript-reporter/extension/vue/TypeScriptVueExtensionSupport.ts index 8940fbcf..69d61536 100644 --- a/src/typescript-reporter/extension/vue/TypeScriptVueExtensionSupport.ts +++ b/src/typescript-reporter/extension/vue/TypeScriptVueExtensionSupport.ts @@ -9,8 +9,13 @@ function assertTypeScriptVueExtensionSupport(configuration: TypeScriptVueExtensi try { require(compilerName); - } catch (err) { - throw new Error('When you use `vue` option, make sure to install `' + compilerName + '`.'); + } catch (error) { + throw new Error( + [ + `Could not initialize '${compilerName}'. When you use 'typescript.extensions.vue' option, make sure to install '${compilerName}' and that the version matches that of 'vue'.`, + `Error details: ${error.message}`, + ].join('\n') + ); } }