[6.x] [tslint] lint typescript code (#19105) (#19331)

Backports the following commits to 6.x:
 - [tslint] lint typescript code  (#19105)
This commit is contained in:
Spencer 2018-05-22 15:27:06 -07:00 committed by GitHub
parent 96ba61a84d
commit 37487a8472
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 588 additions and 75 deletions

View file

@ -59,8 +59,8 @@
"start": "sh ./bin/kibana --dev", "start": "sh ./bin/kibana --dev",
"precommit": "node scripts/precommit_hook", "precommit": "node scripts/precommit_hook",
"karma": "karma start", "karma": "karma start",
"lint": "echo 'use `node scripts/eslint`' && false", "lint": "echo 'use `node scripts/eslint` and/or `node scripts/tslint`' && false",
"lintroller": "echo 'use `node scripts/eslint --fix`' && false", "lintroller": "echo 'use `node scripts/eslint --fix` and/or `node scripts/tslint --fix`' && false",
"makelogs": "echo 'use `node scripts/makelogs`' && false", "makelogs": "echo 'use `node scripts/makelogs`' && false",
"mocha": "echo 'use `node scripts/mocha`' && false", "mocha": "echo 'use `node scripts/mocha`' && false",
"sterilize": "grunt sterilize", "sterilize": "grunt sterilize",
@ -225,7 +225,11 @@
"@kbn/eslint-plugin-license-header": "link:packages/kbn-eslint-plugin-license-header", "@kbn/eslint-plugin-license-header": "link:packages/kbn-eslint-plugin-license-header",
"@kbn/plugin-generator": "link:packages/kbn-plugin-generator", "@kbn/plugin-generator": "link:packages/kbn-plugin-generator",
"@kbn/test": "link:packages/kbn-test", "@kbn/test": "link:packages/kbn-test",
"@types/globby": "^6.1.0", "@types/eslint": "^4.16.2",
"@types/execa": "^0.9.0",
"@types/getopts": "^2.0.0",
"@types/glob": "^5.0.35",
"@types/listr": "^0.13.0",
"@types/minimatch": "^2.0.29", "@types/minimatch": "^2.0.29",
"angular-mocks": "1.4.7", "angular-mocks": "1.4.7",
"babel-eslint": "8.1.2", "babel-eslint": "8.1.2",
@ -281,6 +285,7 @@
"karma-safari-launcher": "1.0.0", "karma-safari-launcher": "1.0.0",
"leadfoot": "1.7.1", "leadfoot": "1.7.1",
"license-checker": "^16.0.0", "license-checker": "^16.0.0",
"listr": "^0.14.1",
"load-grunt-config": "0.19.2", "load-grunt-config": "0.19.2",
"makelogs": "^4.0.4", "makelogs": "^4.0.4",
"marked-text-renderer": "0.1.0", "marked-text-renderer": "0.1.0",
@ -303,6 +308,9 @@
"ts-jest": "^22.4.6", "ts-jest": "^22.4.6",
"ts-loader": "^3.5.0", "ts-loader": "^3.5.0",
"ts-node": "^6.0.3", "ts-node": "^6.0.3",
"tslint": "^5.10.0",
"tslint-config-prettier": "^1.12.0",
"tslint-plugin-prettier": "^1.3.0",
"typescript": "^2.8.3", "typescript": "^2.8.3",
"vinyl-fs": "^3.0.2", "vinyl-fs": "^3.0.2",
"xml2js": "^0.4.19", "xml2js": "^0.4.19",

18
packages/kbn-dev-utils/index.d.ts vendored Normal file
View file

@ -0,0 +1,18 @@
import { Readable } from 'stream';
type LogLevel = 'silent' | 'error' | 'warning' | 'info' | 'debug' | 'verbose';
export class ToolingLog extends Readable {
public verbose(...args: any[]): void;
public debug(...args: any[]): void;
public info(...args: any[]): void;
public success(...args: any[]): void;
public warning(...args: any[]): void;
public error(errOrMsg: string | Error): void;
public write(...args: any[]): void;
public indent(spaces: number): void;
public getLevel(): LogLevel;
public setLevel(level: LogLevel): void;
}
export function createToolingLog(level?: LogLevel): ToolingLog;

View file

@ -0,0 +1,6 @@
{
"extends": "../../tsconfig.json",
"include": [
"index.d.ts"
],
}

View file

@ -0,0 +1,19 @@
extends: ../../tslint.yaml
rules:
max-classes-per-file: false
interface-name: false
variable-name: false
no-empty: false
object-literal-sort-keys: false
member-ordering: false
no-console: false
only-arrow-functions: false
no-shadowed-variable: false
no-empty-interface: false
ordered-imports: false
interface-over-type-literal: false
prettier: false
prefer-const: false
member-access: false
no-unused-variable: false

View file

@ -0,0 +1,14 @@
extends: ../../tslint.yaml
rules:
max-classes-per-file: false
interface-name: false
variable-name: false
no-empty: false
object-literal-sort-keys: false
member-ordering: false
member-access: false
ordered-imports: false
interface-over-type-literal: false
array-type: false
prefer-const: false

2
scripts/tslint.js Normal file
View file

@ -0,0 +1,2 @@
require('../src/babel-register');
require('../src/dev/tslint').runTslintCli();

View file

@ -25,10 +25,10 @@ export function lintFiles(log, files) {
if (report.warningCount > 0) failTypes.push('warning'); if (report.warningCount > 0) failTypes.push('warning');
if (!failTypes.length) { if (!failTypes.length) {
log.success('%d files linted successfully', files.length); log.success('[eslint] %d files linted successfully', files.length);
return; return;
} }
log.error(cli.getFormatter()(report.results)); log.error(cli.getFormatter()(report.results));
throw createFailError(`eslint ${failTypes.join(' & ')}`, 1); throw createFailError(`[eslint] ${failTypes.join(' & ')}`, 1);
} }

View file

@ -18,11 +18,11 @@ export function pickFilesToLint(log, files) {
const path = file.getRelativePath(); const path = file.getRelativePath();
if (cli.isPathIgnored(path)) { if (cli.isPathIgnored(path)) {
log.warning(`%j ignored by .eslintignore`, file); log.warning(`[eslint] %j ignored by .eslintignore`, file);
return false; return false;
} }
log.debug('linting %j', file); log.debug('[eslint] linting %j', file);
return true; return true;
}); });
} }

View file

@ -1,8 +1,7 @@
import { getCacheKey, install, process } from 'ts-jest'; import { getCacheKey, install, process } from 'ts-jest';
import { JestConfig, TransformOptions } from 'ts-jest/dist/jest-types'; import { JestConfig, TransformOptions } from 'ts-jest/dist/jest-types';
import { transform } from 'typescript'; import { getTsProjectForAbsolutePath } from '../typescript';
import { findProjectForAbsolutePath } from '../typescript';
function extendJestConfigJSON(jestConfigJSON: string, filePath: string) { function extendJestConfigJSON(jestConfigJSON: string, filePath: string) {
const jestConfig = JSON.parse(jestConfigJSON) as JestConfig; const jestConfig = JSON.parse(jestConfigJSON) as JestConfig;
@ -15,20 +14,30 @@ function extendJestConfig(jestConfig: JestConfig, filePath: string) {
globals: { globals: {
...(jestConfig.globals || {}), ...(jestConfig.globals || {}),
'ts-jest': { 'ts-jest': {
tsConfigFile: findProjectForAbsolutePath(filePath).getTsConfigPath(),
skipBabel: true, skipBabel: true,
tsConfigFile: getTsProjectForAbsolutePath(filePath).tsConfigPath,
}, },
}, },
}; };
} }
module.exports = { module.exports = {
process(src: string, filePath: string, jestConfig: JestConfig, transformOptions: TransformOptions) { process(
src: string,
filePath: string,
jestConfig: JestConfig,
transformOptions: TransformOptions
) {
const extendedConfig = extendJestConfig(jestConfig, filePath); const extendedConfig = extendJestConfig(jestConfig, filePath);
return process(src, filePath, extendedConfig, transformOptions); return process(src, filePath, extendedConfig, transformOptions);
}, },
getCacheKey(src: string, filePath: string, jestConfigJSON: string, transformOptions: TransformOptions) { getCacheKey(
src: string,
filePath: string,
jestConfigJSON: string,
transformOptions: TransformOptions
) {
const extendedConfigJSON = extendJestConfigJSON(jestConfigJSON, filePath); const extendedConfigJSON = extendJestConfigJSON(jestConfigJSON, filePath);
return getCacheKey(src, filePath, extendedConfigJSON, transformOptions); return getCacheKey(src, filePath, extendedConfigJSON, transformOptions);
}, },

View file

@ -19,6 +19,7 @@ export const IGNORE_FILE_GLOBS = [
'x-pack/plugins/apm/**/*', 'x-pack/plugins/apm/**/*',
'**/.*', '**/.*',
'**/{webpackShims,__mocks__}/**/*', '**/{webpackShims,__mocks__}/**/*',
'src/dev/tslint/rules/*',
]; ];

1
src/dev/run/index.d.ts vendored Normal file
View file

@ -0,0 +1 @@
export function createFailError(msg: string, exitCode: number): Error;

View file

@ -1,10 +1,17 @@
import { run } from './run'; import { run } from './run';
import { lintFiles, pickFilesToLint } from './eslint'; import * as Eslint from './eslint';
import * as Tslint from './tslint';
import { getFilesForCommit, checkFileCasing } from './precommit_hook'; import { getFilesForCommit, checkFileCasing } from './precommit_hook';
run(async ({ log }) => { run(async ({ log }) => {
const files = await getFilesForCommit(); const files = await getFilesForCommit();
await checkFileCasing(log, files); await checkFileCasing(log, files);
await lintFiles(log, pickFilesToLint(log, files));
for (const Linter of [Eslint, Tslint]) {
const filesToLint = Linter.pickFilesToLint(log, files);
if (filesToLint.length > 0) {
await Linter.lintFiles(log, filesToLint);
}
}
}); });

3
src/dev/tslint/index.ts Normal file
View file

@ -0,0 +1,3 @@
export { runTslintCli } from './run_tslint_cli';
export { lintFiles } from './lint_files';
export { pickFilesToLint } from './pick_files_to_lint';

View file

@ -0,0 +1,63 @@
import { run } from 'tslint/lib/runner';
import { ToolingLog } from '@kbn/dev-utils';
import { File } from '../file';
import { createFailError } from '../run';
import { getTsProjectForAbsolutePath, Project } from '../typescript';
function groupFilesByProject(files: File[]) {
const filesByProject: Map<Project, File[]> = new Map();
files.forEach(file => {
const project = getTsProjectForAbsolutePath(file.getAbsolutePath());
const filesForProject = filesByProject.get(project);
if (!filesForProject) {
filesByProject.set(project, [file]);
} else {
filesForProject.push(file);
}
});
return filesByProject;
}
/**
* Lints a list of files with eslint. eslint reports are written to the log
* and a FailError is thrown when linting errors occur.
*
* @param {ToolingLog} log
* @param {Array<File>} files
* @return {undefined}
*/
export async function lintFiles(log: ToolingLog, files: File[]) {
for (const [project, filesInProject] of groupFilesByProject(files)) {
const exitCode = await run(
{
exclude: [],
files: filesInProject.map(f => f.getAbsolutePath()),
fix: false,
format: 'stylish',
project: project.tsConfigPath,
},
{
log(m: string) {
log.write(m);
},
error(m: string) {
log.error(m);
},
}
);
if (exitCode > 0) {
throw createFailError(`[tslint] failure`, 1);
} else {
log.success(
'[tslint/%s] %d files linted successfully',
project.name,
files.length
);
}
}
}

View file

@ -0,0 +1,7 @@
import { ToolingLog } from '@kbn/dev-utils';
import { File } from '../file';
export function pickFilesToLint(log: ToolingLog, files: File[]) {
return files.filter(file => file.isTypescript());
}

View file

@ -0,0 +1,29 @@
const Lint = require('tslint');
const FAILURE_STRING = 'File must start with a license header';
const RULE_NAME = 'require-license-header';
exports.Rule = class extends Lint.Rules.AbstractRule {
apply(sourceFile) {
const [headerText] = this.getOptions().ruleArguments;
if (!headerText) {
throw new Error(`${RULE_NAME} requires a single argument containing the header text`);
}
if (sourceFile.text.startsWith(headerText)) {
return [];
}
return [
new Lint.RuleFailure(
sourceFile,
0,
0,
FAILURE_STRING,
RULE_NAME,
new Lint.Replacement(0, 0, `${headerText}\n\n`)
)
];
}
};

View file

@ -0,0 +1,69 @@
import { resolve } from 'path';
import { createToolingLog } from '@kbn/dev-utils';
import chalk from 'chalk';
import execa from 'execa';
import getopts from 'getopts';
import Listr from 'listr';
import { Project, PROJECTS } from '../typescript';
class LintFailure {
constructor(public project: Project, public error: execa.ExecaError) {}
}
export function runTslintCli() {
const log = createToolingLog('info');
log.pipe(process.stdout);
const opts = getopts(process.argv.slice(2));
if (!opts.format) {
process.argv.push('--format', 'stylish');
}
const list = new Listr(
PROJECTS.filter(project => {
if (!opts.project) {
return true;
}
return resolve(opts.project) === project.tsConfigPath;
}).map(project => ({
task: () =>
execa(
'tslint',
[...process.argv.slice(2), '--project', project.tsConfigPath],
{
cwd: project.directory,
env: chalk.enabled ? { FORCE_COLOR: 'true' } : {},
stdio: ['ignore', 'pipe', 'pipe'],
}
).catch(error => {
throw new LintFailure(project, error);
}),
title: project.name,
})),
{
concurrent: true,
exitOnError: false,
}
);
list.run().catch((error: any) => {
if (!error.errors) {
log.error('Unhandled execption!');
log.error(error);
process.exit(1);
}
for (const e of error.errors) {
if (e instanceof LintFailure) {
log.write('');
log.error(`${e.project.name} failed\n${e.error.stdout}`);
} else {
log.error(e);
}
}
});
}

View file

@ -0,0 +1,40 @@
import { relative } from 'path';
import { REPO_ROOT } from '../constants';
import { PROJECTS } from './projects';
/**
* Finds the `tsconfig.json` Project object for a specific path by looking through
* Project instances defined in `src/dev/typescript/projects.ts`. If there isn't exactly one project
* that includes the path an error is thrown with, hopefully, a helpful error
* message that aims to help developers know how to fix the situation and ensure
* that each TypeScript file maps to only a single `tsconfig.json` file.
*
* @param path Absolute path to a .ts file
*/
export function getTsProjectForAbsolutePath(path: string) {
const relPath = relative(REPO_ROOT, path);
const projects = PROJECTS.filter(p => p.isAbsolutePathSelected(path));
if (!projects.length) {
throw new Error(
`Unable to find tsconfig.json file selecting "${relPath}". Ensure one exists and it is listed in "src/dev/typescript/projects.ts"`
);
}
if (projects.length !== 1) {
const configPaths = projects.map(
p => `"${relative(REPO_ROOT, p.tsConfigPath)}"`
);
const pathsMsg = `${configPaths.slice(0, -1).join(', ')} or ${
configPaths[configPaths.length - 1]
}`;
throw new Error(
`"${relPath}" is selected by multiple tsconfig.json files. This probably means the includes/excludes in ${pathsMsg} are too broad and include the code from multiple projects.`
);
}
return projects[0];
}

View file

@ -1 +1,5 @@
export { findProjectForAbsolutePath } from './project'; export { Project } from './project';
export { PROJECTS } from './projects';
export {
getTsProjectForAbsolutePath,
} from './get_ts_project_for_absolute_path';

View file

@ -1,73 +1,64 @@
import { readFileSync } from 'fs'; import { readFileSync } from 'fs';
import { basename, dirname, relative, resolve } from 'path'; import { basename, dirname, relative, resolve } from 'path';
import globby from 'globby';
import { IMinimatch, Minimatch } from 'minimatch'; import { IMinimatch, Minimatch } from 'minimatch';
import { parseConfigFileTextToJson } from 'typescript'; import { parseConfigFileTextToJson } from 'typescript';
import { File } from '../file'; import { REPO_ROOT } from '../constants';
const ROOT_DIR = resolve(__dirname, '../../../');
function makeMatchers(directory: string, patterns: string[]) { function makeMatchers(directory: string, patterns: string[]) {
return patterns.map(pattern => new Minimatch(resolve(directory, pattern), { return patterns.map(
dot: true, pattern =>
})); new Minimatch(resolve(directory, pattern), {
dot: true,
})
);
}
function parseTsConfig(path: string) {
const { error, config } = parseConfigFileTextToJson(
path,
readFileSync(path, 'utf8')
);
if (error) {
throw error;
}
const files: string[] | undefined = config.files;
const include: string[] | undefined = config.include;
const exclude: string[] | undefined = config.exclude;
return { files, include, exclude };
}
function testMatchers(matchers: IMinimatch[], path: string) {
return matchers.some(matcher => matcher.match(path));
} }
export class Project { export class Project {
public static fromConfig(path: string) { public directory: string;
const { error, config } = parseConfigFileTextToJson(path, readFileSync(path, 'utf8')); public name: string;
if (error) {
throw error;
}
return new Project(path, config.files, config.include, config.exclude);
}
private include: IMinimatch[]; private include: IMinimatch[];
private exclude: IMinimatch[]; private exclude: IMinimatch[];
constructor(private tsConfigPath: string, files?: string[], include?: string[], exclude: string[] = []) { constructor(public tsConfigPath: string) {
const { files, include, exclude = [] } = parseTsConfig(tsConfigPath);
if (files || !include) { if (files || !include) {
throw new Error( throw new Error(
'tsconfig.json files in the Kibana repo must use "include" keys and not "files"' 'tsconfig.json files in the Kibana repo must use "include" keys and not "files"'
); );
} }
this.include = makeMatchers(dirname(tsConfigPath), include); this.directory = dirname(this.tsConfigPath);
this.exclude = makeMatchers(dirname(tsConfigPath), exclude); this.name = relative(REPO_ROOT, this.directory) || basename(this.directory);
} this.include = makeMatchers(this.directory, include);
this.exclude = makeMatchers(this.directory, exclude);
public getTsConfigPath() {
return this.tsConfigPath;
} }
public isAbsolutePathSelected(path: string) { public isAbsolutePathSelected(path: string) {
return this.exclude.some(exc => exc.match(path)) return testMatchers(this.exclude, path)
? false ? false
: this.include.some(inc => inc.match(path)); : testMatchers(this.include, path);
} }
} }
export const TS_PROJECTS = globby.sync([
'packages/*/tsconfig.json',
'tsconfig.json',
'x-pack/tsconfig.json'
], {
cwd: ROOT_DIR,
absolute: true,
}).map(path => Project.fromConfig(path))
export function findProjectForAbsolutePath(path: string) {
const project = TS_PROJECTS.find(p => p.isAbsolutePathSelected(path));
if (!project) {
throw new Error(
`Unable to find tsconfig.json file selecting file "${path}". Ensure one exists and it is listed in "src/dev/typescript/projects.ts"`
);
}
return project
}

View file

@ -0,0 +1,14 @@
import glob from 'glob';
import { resolve } from 'path';
import { REPO_ROOT } from '../constants';
import { Project } from './project';
export const PROJECTS = [
'tsconfig.json',
'x-pack/tsconfig.json',
// NOTE: using glob.sync rather than glob-all or globby
// because it takes less than 10 ms, while the other modules
// both took closer to 1000ms.
...glob.sync('packages/*/tsconfig.json', { cwd: REPO_ROOT }),
].map(path => new Project(resolve(REPO_ROOT, path)));

View file

@ -73,6 +73,15 @@ module.exports = function (grunt) {
] ]
}, },
// used by the test and jenkins:unit tasks
// runs the tslint script to check for Typescript linting errors
tslint: {
cmd: process.execPath,
args: [
require.resolve('../../scripts/tslint')
]
},
// used by the test:server task // used by the test:server task
// runs all node.js/server mocha tests // runs all node.js/server mocha tests
mocha: { mocha: {

View file

@ -5,6 +5,7 @@ module.exports = function (grunt) {
grunt.registerTask('jenkins:unit', [ grunt.registerTask('jenkins:unit', [
'run:eslint', 'run:eslint',
'run:tslint',
'licenses', 'licenses',
'verifyDependencyVersions', 'verifyDependencyVersions',
'run:verifyNotice', 'run:verifyNotice',

View file

@ -100,6 +100,7 @@ module.exports = function (grunt) {
grunt.task.run(_.compact([ grunt.task.run(_.compact([
!grunt.option('quick') && 'run:eslint', !grunt.option('quick') && 'run:eslint',
!grunt.option('quick') && 'run:tslint',
'licenses', 'licenses',
'test:quick', 'test:quick',
'verifyTranslations', 'verifyTranslations',

10
tslint.yaml Normal file
View file

@ -0,0 +1,10 @@
extends:
- tslint:recommended
- tslint-config-prettier
rulesDirectory:
- tslint-plugin-prettier
rules:
prettier: true
no-unused-variable: true

14
x-pack/tslint.yaml Normal file
View file

@ -0,0 +1,14 @@
extends: ../tslint.yaml
rulesDirectory:
- ../src/dev/tslint/rules
rules:
require-license-header:
- true
- |-
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

199
yarn.lock
View file

@ -172,17 +172,44 @@
call-me-maybe "^1.0.1" call-me-maybe "^1.0.1"
glob-to-regexp "^0.3.0" glob-to-regexp "^0.3.0"
"@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/formatio@^2.0.0": "@sinonjs/formatio@^2.0.0":
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/@sinonjs/formatio/-/formatio-2.0.0.tgz#84db7e9eb5531df18a8c5e0bfb6e449e55e654b2" resolved "https://registry.yarnpkg.com/@sinonjs/formatio/-/formatio-2.0.0.tgz#84db7e9eb5531df18a8c5e0bfb6e449e55e654b2"
dependencies: dependencies:
samsam "1.3.0" samsam "1.3.0"
"@types/eslint@^4.16.2":
version "4.16.2"
resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-4.16.2.tgz#30f4f026019eb78a6ef12f276b75cd16ea2afb27"
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"
"@types/events@*": "@types/events@*":
version "1.2.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86" resolved "https://registry.yarnpkg.com/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86"
"@types/glob@*": "@types/execa@^0.9.0":
version "0.9.0"
resolved "https://registry.yarnpkg.com/@types/execa/-/execa-0.9.0.tgz#9b025d2755f17e80beaf9368c3f4f319d8b0fb93"
dependencies:
"@types/node" "*"
"@types/getopts@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@types/getopts/-/getopts-2.0.0.tgz#8a603370cb367d3192bd8012ad39ab2320b5b476"
"@types/glob@^5.0.35":
version "5.0.35" version "5.0.35"
resolved "https://registry.yarnpkg.com/@types/glob/-/glob-5.0.35.tgz#1ae151c802cece940443b5ac246925c85189f32a" resolved "https://registry.yarnpkg.com/@types/glob/-/glob-5.0.35.tgz#1ae151c802cece940443b5ac246925c85189f32a"
dependencies: dependencies:
@ -190,16 +217,20 @@
"@types/minimatch" "*" "@types/minimatch" "*"
"@types/node" "*" "@types/node" "*"
"@types/globby@^6.1.0": "@types/json-schema@*":
version "6.1.0" version "6.0.1"
resolved "https://registry.yarnpkg.com/@types/globby/-/globby-6.1.0.tgz#7c25b975512a89effea2a656ca8cf6db7fb29d11" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-6.0.1.tgz#a761975746f1c1b2579c62e3a4b5e88f986f7e2e"
dependencies:
"@types/glob" "*"
"@types/json-stable-stringify@^1.0.32": "@types/json-stable-stringify@^1.0.32":
version "1.0.32" version "1.0.32"
resolved "https://registry.yarnpkg.com/@types/json-stable-stringify/-/json-stable-stringify-1.0.32.tgz#121f6917c4389db3923640b2e68de5fa64dda88e" resolved "https://registry.yarnpkg.com/@types/json-stable-stringify/-/json-stable-stringify-1.0.32.tgz#121f6917c4389db3923640b2e68de5fa64dda88e"
"@types/listr@^0.13.0":
version "0.13.0"
resolved "https://registry.yarnpkg.com/@types/listr/-/listr-0.13.0.tgz#6250bc4a04123cafa24fc73d1b880653a6ae6721"
dependencies:
"@types/node" "*"
"@types/minimatch@*": "@types/minimatch@*":
version "3.0.3" version "3.0.3"
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
@ -442,7 +473,7 @@ ansi-colors@^1.0.1:
dependencies: dependencies:
ansi-wrap "^0.1.0" ansi-wrap "^0.1.0"
ansi-escapes@^1.1.0: ansi-escapes@^1.0.0, ansi-escapes@^1.1.0:
version "1.4.0" version "1.4.0"
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e"
@ -488,6 +519,10 @@ any-observable@^0.2.0:
version "0.2.0" version "0.2.0"
resolved "https://registry.yarnpkg.com/any-observable/-/any-observable-0.2.0.tgz#c67870058003579009083f54ac0abafb5c33d242" resolved "https://registry.yarnpkg.com/any-observable/-/any-observable-0.2.0.tgz#c67870058003579009083f54ac0abafb5c33d242"
any-observable@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/any-observable/-/any-observable-0.3.0.tgz#af933475e5806a67d0d7df090dd5e8bef65d119b"
anymatch@^1.3.0: anymatch@^1.3.0:
version "1.3.2" version "1.3.2"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a"
@ -2368,7 +2403,7 @@ cli-boxes@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143"
cli-cursor@^1.0.1: cli-cursor@^1.0.1, cli-cursor@^1.0.2:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987"
dependencies: dependencies:
@ -2380,10 +2415,21 @@ cli-cursor@^2.1.0:
dependencies: dependencies:
restore-cursor "^2.0.0" restore-cursor "^2.0.0"
cli-spinners@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-0.1.2.tgz#bb764d88e185fb9e1e6a2a1f19772318f605e31c"
cli-spinners@^1.0.1: cli-spinners@^1.0.1:
version "1.1.0" version "1.1.0"
resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-1.1.0.tgz#f1847b168844d917a671eb9d147e3df497c90d06" resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-1.1.0.tgz#f1847b168844d917a671eb9d147e3df497c90d06"
cli-truncate@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574"
dependencies:
slice-ansi "0.0.4"
string-width "^1.0.1"
cli-width@^1.0.1: cli-width@^1.0.1:
version "1.1.1" version "1.1.1"
resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-1.1.1.tgz#a4d293ef67ebb7b88d4a4d42c0ccf00c4d1e366d" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-1.1.1.tgz#a4d293ef67ebb7b88d4a4d42c0ccf00c4d1e366d"
@ -2555,7 +2601,7 @@ combined-stream@1.0.6, combined-stream@^1.0.5, combined-stream@~1.0.5:
dependencies: dependencies:
delayed-stream "~1.0.0" delayed-stream "~1.0.0"
commander@2: commander@2, commander@^2.12.1:
version "2.15.1" version "2.15.1"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f"
@ -3285,6 +3331,10 @@ dashdash@^1.12.0:
dependencies: dependencies:
assert-plus "^1.0.0" assert-plus "^1.0.0"
date-fns@^1.27.2:
version "1.29.0"
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.29.0.tgz#12e609cdcb935127311d04d33334e2960a2a54e6"
date-now@^0.1.4: date-now@^0.1.4:
version "0.1.4" version "0.1.4"
resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b"
@ -3782,6 +3832,10 @@ electron-to-chromium@^1.2.7:
version "1.3.39" version "1.3.39"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.39.tgz#d7a4696409ca0995e2750156da612c221afad84d" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.39.tgz#d7a4696409ca0995e2750156da612c221afad84d"
elegant-spinner@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e"
element-resize-detector@^1.1.12: element-resize-detector@^1.1.12:
version "1.1.14" version "1.1.14"
resolved "https://registry.yarnpkg.com/element-resize-detector/-/element-resize-detector-1.1.14.tgz#af064a0a618a820ad570a95c5eec5b77be0128c1" resolved "https://registry.yarnpkg.com/element-resize-detector/-/element-resize-detector-1.1.14.tgz#af064a0a618a820ad570a95c5eec5b77be0128c1"
@ -4158,7 +4212,7 @@ eslint-plugin-prefer-object-spread@1.2.1:
version "1.2.1" version "1.2.1"
resolved "https://registry.yarnpkg.com/eslint-plugin-prefer-object-spread/-/eslint-plugin-prefer-object-spread-1.2.1.tgz#27fb91853690cceb3ae6101d9c8aecc6a67a402c" resolved "https://registry.yarnpkg.com/eslint-plugin-prefer-object-spread/-/eslint-plugin-prefer-object-spread-1.2.1.tgz#27fb91853690cceb3ae6101d9c8aecc6a67a402c"
eslint-plugin-prettier@^2.6.0: eslint-plugin-prettier@^2.2.0, eslint-plugin-prettier@^2.6.0:
version "2.6.0" version "2.6.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-2.6.0.tgz#33e4e228bdb06142d03c560ce04ec23f6c767dd7" resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-2.6.0.tgz#33e4e228bdb06142d03c560ce04ec23f6c767dd7"
dependencies: dependencies:
@ -4654,7 +4708,7 @@ fetch-mock@^5.13.1:
node-fetch "^1.3.3" node-fetch "^1.3.3"
path-to-regexp "^1.7.0" path-to-regexp "^1.7.0"
figures@^1.3.5: figures@^1.3.5, figures@^1.7.0:
version "1.7.0" version "1.7.0"
resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e"
dependencies: dependencies:
@ -6403,6 +6457,12 @@ is-object@^1.0.1, is-object@~1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470"
is-observable@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-1.1.0.tgz#b3e986c8f44de950867cab5403f5a3465005975e"
dependencies:
symbol-observable "^1.1.0"
is-odd@^2.0.0: is-odd@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/is-odd/-/is-odd-2.0.0.tgz#7646624671fd7ea558ccd9a2795182f2958f1b24" resolved "https://registry.yarnpkg.com/is-odd/-/is-odd-2.0.0.tgz#7646624671fd7ea558ccd9a2795182f2958f1b24"
@ -7588,6 +7648,53 @@ linkify-it@^2.0.0:
dependencies: dependencies:
uc.micro "^1.0.1" uc.micro "^1.0.1"
listr-silent-renderer@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e"
listr-update-renderer@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.4.0.tgz#344d980da2ca2e8b145ba305908f32ae3f4cc8a7"
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 "^1.0.2"
strip-ansi "^3.0.1"
listr-verbose-renderer@^0.4.0:
version "0.4.1"
resolved "https://registry.yarnpkg.com/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz#8206f4cf6d52ddc5827e5fd14989e0e965933a35"
dependencies:
chalk "^1.1.3"
cli-cursor "^1.0.2"
date-fns "^1.27.2"
figures "^1.7.0"
listr@^0.14.1:
version "0.14.1"
resolved "https://registry.yarnpkg.com/listr/-/listr-0.14.1.tgz#8a7afa4a7135cee4c921d128e0b7dfc6e522d43d"
dependencies:
"@samverschueren/stream-to-observable" "^0.3.0"
cli-truncate "^0.2.1"
figures "^1.7.0"
indent-string "^2.1.0"
is-observable "^1.1.0"
is-promise "^2.1.0"
is-stream "^1.1.0"
listr-silent-renderer "^1.1.1"
listr-update-renderer "^0.4.0"
listr-verbose-renderer "^0.4.0"
log-symbols "^1.0.2"
log-update "^1.0.2"
ora "^0.2.3"
p-map "^1.1.1"
rxjs "^6.1.0"
strip-ansi "^3.0.1"
livereload-js@^2.2.0: livereload-js@^2.2.0:
version "2.3.0" version "2.3.0"
resolved "https://registry.yarnpkg.com/livereload-js/-/livereload-js-2.3.0.tgz#c3ab22e8aaf5bf3505d80d098cbad67726548c9a" resolved "https://registry.yarnpkg.com/livereload-js/-/livereload-js-2.3.0.tgz#c3ab22e8aaf5bf3505d80d098cbad67726548c9a"
@ -7961,12 +8068,25 @@ lodash@~4.3.0:
version "4.3.0" version "4.3.0"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.3.0.tgz#efd9c4a6ec53f3b05412429915c3e4824e4d25a4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.3.0.tgz#efd9c4a6ec53f3b05412429915c3e4824e4d25a4"
log-symbols@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18"
dependencies:
chalk "^1.0.0"
log-symbols@^2.1.0: log-symbols@^2.1.0:
version "2.2.0" version "2.2.0"
resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a"
dependencies: dependencies:
chalk "^2.0.1" chalk "^2.0.1"
log-update@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/log-update/-/log-update-1.0.2.tgz#19929f64c4093d2d2e7075a1dad8af59c296b8d1"
dependencies:
ansi-escapes "^1.0.0"
cli-cursor "^1.0.2"
log4js@^0.6.31: log4js@^0.6.31:
version "0.6.38" version "0.6.38"
resolved "https://registry.yarnpkg.com/log4js/-/log4js-0.6.38.tgz#2c494116695d6fb25480943d3fc872e662a522fd" resolved "https://registry.yarnpkg.com/log4js/-/log4js-0.6.38.tgz#2c494116695d6fb25480943d3fc872e662a522fd"
@ -8874,6 +8994,15 @@ options@>=0.0.5:
version "0.0.6" version "0.0.6"
resolved "https://registry.yarnpkg.com/options/-/options-0.0.6.tgz#ec22d312806bb53e731773e7cdaefcf1c643128f" resolved "https://registry.yarnpkg.com/options/-/options-0.0.6.tgz#ec22d312806bb53e731773e7cdaefcf1c643128f"
ora@^0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/ora/-/ora-0.2.3.tgz#37527d220adcd53c39b73571d754156d5db657a4"
dependencies:
chalk "^1.1.1"
cli-cursor "^1.0.2"
cli-spinners "^0.1.2"
object-assign "^4.0.1"
ora@^1.3.0: ora@^1.3.0:
version "1.4.0" version "1.4.0"
resolved "https://registry.yarnpkg.com/ora/-/ora-1.4.0.tgz#884458215b3a5d4097592285f93321bb7a79e2e5" resolved "https://registry.yarnpkg.com/ora/-/ora-1.4.0.tgz#884458215b3a5d4097592285f93321bb7a79e2e5"
@ -10695,7 +10824,7 @@ resolve@^1.1.5, resolve@^1.1.6, resolve@^1.1.7, resolve@^1.2.0, resolve@^1.5.0:
dependencies: dependencies:
path-parse "^1.0.5" path-parse "^1.0.5"
resolve@^1.7.1: resolve@^1.3.2, resolve@^1.7.1:
version "1.7.1" version "1.7.1"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.7.1.tgz#aadd656374fd298aee895bc026b8297418677fd3" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.7.1.tgz#aadd656374fd298aee895bc026b8297418677fd3"
dependencies: dependencies:
@ -10827,6 +10956,12 @@ rxjs@^5.4.3:
dependencies: dependencies:
symbol-observable "1.0.1" symbol-observable "1.0.1"
rxjs@^6.1.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.1.0.tgz#833447de4e4f6427b9cec3e5eb9f56415cd28315"
dependencies:
tslib "^1.9.0"
safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
version "5.1.1" version "5.1.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
@ -11716,7 +11851,7 @@ symbol-observable@1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4"
symbol-observable@^1.0.1, symbol-observable@^1.0.3: symbol-observable@^1.0.1, symbol-observable@^1.0.3, symbol-observable@^1.1.0:
version "1.2.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
@ -12154,10 +12289,48 @@ ts-node@^6.0.3:
source-map-support "^0.5.3" source-map-support "^0.5.3"
yn "^2.0.0" yn "^2.0.0"
tslib@^1.7.1, tslib@^1.8.0, tslib@^1.8.1:
version "1.9.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.1.tgz#a5d1f0532a49221c87755cfcc89ca37197242ba7"
tslib@^1.9.0: tslib@^1.9.0:
version "1.9.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.0.tgz#e37a86fda8cbbaf23a057f473c9f4dc64e5fc2e8" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.0.tgz#e37a86fda8cbbaf23a057f473c9f4dc64e5fc2e8"
tslint-config-prettier@^1.12.0:
version "1.12.0"
resolved "https://registry.yarnpkg.com/tslint-config-prettier/-/tslint-config-prettier-1.12.0.tgz#bc8504f286ecf42b906f3d1126a093114f5729cc"
tslint-plugin-prettier@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/tslint-plugin-prettier/-/tslint-plugin-prettier-1.3.0.tgz#7eb65d19ea786a859501a42491b78c5de2031a3f"
dependencies:
eslint-plugin-prettier "^2.2.0"
tslib "^1.7.1"
tslint@^5.10.0:
version "5.10.0"
resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.10.0.tgz#11e26bccb88afa02dd0d9956cae3d4540b5f54c3"
dependencies:
babel-code-frame "^6.22.0"
builtin-modules "^1.1.1"
chalk "^2.3.0"
commander "^2.12.1"
diff "^3.2.0"
glob "^7.1.1"
js-yaml "^3.7.0"
minimatch "^3.0.4"
resolve "^1.3.2"
semver "^5.3.0"
tslib "^1.8.0"
tsutils "^2.12.1"
tsutils@^2.12.1:
version "2.27.0"
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.27.0.tgz#9efb252b188eaa0ca3ade41dc410d6ce7eaab816"
dependencies:
tslib "^1.8.1"
tty-browserify@0.0.0: tty-browserify@0.0.0:
version "0.0.0" version "0.0.0"
resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6"