diff --git a/docs/development/plugin/development-plugin-resources.asciidoc b/docs/development/plugin/development-plugin-resources.asciidoc index c4a46cde0464f..ef05fad1b6027 100644 --- a/docs/development/plugin/development-plugin-resources.asciidoc +++ b/docs/development/plugin/development-plugin-resources.asciidoc @@ -51,4 +51,24 @@ The Kibana directory must be named `kibana`, and your plugin directory must be l If you're developing a plugin that has a user interface, take a look at our https://elastic.github.io/eui[Elastic UI Framework]. It documents the CSS and React components we use to build Kibana's user interface. -You're welcome to use these components, but be aware that they are rapidly evolving and we might introduce breaking changes that will disrupt your plugin's UI. \ No newline at end of file +You're welcome to use these components, but be aware that they are rapidly evolving and we might introduce breaking changes that will disrupt your plugin's UI. + +[float] +==== TypeScript Support +Plugin code can be written in http://www.typescriptlang.org/[TypeScript] if desired. To enable TypeScript support create a `tsconfig.json` file at the root of your plugin that looks something like this: + +["source","js"] +----------- +{ + // extend Kibana's tsconfig, or use your own settings + "extends": "../../kibana/tsconfig.json", + + // tell the TypeScript compiler where to find your source files + "include": [ + "server/**/*", + "public/**/*" + ] +} +----------- + +TypeScript code is automatically converted into JavaScript during development, but not in the distributable version of Kibana. If you use the {repo}blob/{branch}/packages/kbn-plugin-helpers[@kbn/plugin-helpers] to build your plugin then your `.ts` and `.tsx` files will be permanently transpiled before your plugin is archived. If you have your own build process, make sure to run the TypeScript compiler on your source files and ship the compilation output so that your plugin will work with the distributable version of Kibana. diff --git a/package.json b/package.json index 07ba20bf2e489..d2ecaf87af0d7 100644 --- a/package.json +++ b/package.json @@ -207,8 +207,8 @@ "validate-npm-package-name": "2.2.2", "vega-lib": "^3.3.1", "vega-lite": "^2.4.0", - "vega-tooltip": "^0.9.14", "vega-schema-url-parser": "1.0.0", + "vega-tooltip": "^0.9.14", "vision": "4.1.0", "webpack": "3.6.0", "webpack-merge": "4.1.0", @@ -225,6 +225,8 @@ "@kbn/eslint-plugin-license-header": "link:packages/kbn-eslint-plugin-license-header", "@kbn/plugin-generator": "link:packages/kbn-plugin-generator", "@kbn/test": "link:packages/kbn-test", + "@types/globby": "^6.1.0", + "@types/minimatch": "^2.0.29", "angular-mocks": "1.4.7", "babel-eslint": "8.1.2", "babel-jest": "^22.4.3", @@ -298,8 +300,10 @@ "supertest": "3.0.0", "supertest-as-promised": "4.0.2", "tree-kill": "^1.1.0", - "ts-jest": "^22.4.3", - "typescript": "^2.8.1", + "ts-jest": "^22.4.6", + "ts-loader": "^3.5.0", + "ts-node": "^6.0.3", + "typescript": "^2.8.3", "vinyl-fs": "^3.0.2", "xml2js": "^0.4.19", "xmlbuilder": "9.0.4" diff --git a/packages/kbn-dev-utils/package.json b/packages/kbn-dev-utils/package.json index aa824ced3710b..8ba55d6a4f572 100644 --- a/packages/kbn-dev-utils/package.json +++ b/packages/kbn-dev-utils/package.json @@ -1,6 +1,7 @@ { "name": "@kbn/dev-utils", "main": "./target/index.js", + "types": "./index.d.ts", "version": "1.0.0", "license": "Apache-2.0", "private": true, diff --git a/packages/kbn-eslint-import-resolver-kibana/import_resolver_kibana.js b/packages/kbn-eslint-import-resolver-kibana/import_resolver_kibana.js index 3e8525d495c4e..71212d113c998 100755 --- a/packages/kbn-eslint-import-resolver-kibana/import_resolver_kibana.js +++ b/packages/kbn-eslint-import-resolver-kibana/import_resolver_kibana.js @@ -37,8 +37,11 @@ function tryNodeResolver(importRequest, file, config) { return nodeResolver.resolve( importRequest, file, + // we use Object.assign so that this file is compatible with slightly older + // versions of node.js used by IDEs (eg. resolvers are run in the Electron + // process in Atom) Object.assign({}, config, { - extensions: ['.js', '.json'], + extensions: ['.js', '.json', '.ts', '.tsx'], isFile, }) ); diff --git a/packages/kbn-eslint-import-resolver-kibana/lib/get_webpack_config.js b/packages/kbn-eslint-import-resolver-kibana/lib/get_webpack_config.js index 4ae951713c293..36dc9a507bfdb 100755 --- a/packages/kbn-eslint-import-resolver-kibana/lib/get_webpack_config.js +++ b/packages/kbn-eslint-import-resolver-kibana/lib/get_webpack_config.js @@ -33,7 +33,7 @@ exports.getWebpackConfig = function(kibanaPath, projectRoot, config) { return { context: kibanaPath, resolve: { - extensions: ['.js', '.json'], + extensions: ['.js', '.json', '.ts', '.tsx'], mainFields: ['browser', 'main'], modules: [ 'webpackShims', diff --git a/packages/kbn-plugin-helpers/README.md b/packages/kbn-plugin-helpers/README.md index fd19d4829fe84..0a4e925b6b54a 100644 --- a/packages/kbn-plugin-helpers/README.md +++ b/packages/kbn-plugin-helpers/README.md @@ -76,3 +76,20 @@ Setting | Description `skipInstallDependencies` | Don't install dependencies defined in package.json into build output `buildVersion` | Version for the build output `kibanaVersion` | Kibana version for the build output (added to package.json) + +## TypeScript support + +Plugin code can be written in [TypeScript](http://www.typescriptlang.org/) if desired. To enable TypeScript support create a `tsconfig.json` file at the root of your plugin that looks something like this: + +```js +{ + // extend Kibana's tsconfig, or use your own settings + "extends": "../../kibana/tsconfig.json", + + // tell the TypeScript compiler where to find your source files + "include": [ + "server/**/*", + "public/**/*" + ] +} +``` diff --git a/packages/kbn-plugin-helpers/lib/plugin_config.js b/packages/kbn-plugin-helpers/lib/plugin_config.js index 2b7c274226196..60826b822e1f9 100644 --- a/packages/kbn-plugin-helpers/lib/plugin_config.js +++ b/packages/kbn-plugin-helpers/lib/plugin_config.js @@ -10,6 +10,7 @@ module.exports = function (root) { const buildSourcePatterns = [ 'yarn.lock', + 'tsconfig.json', 'package.json', 'index.js', '{lib,public,server,webpackShims,translations}/**/*', diff --git a/packages/kbn-plugin-helpers/tasks/build/create_build.js b/packages/kbn-plugin-helpers/tasks/build/create_build.js index 0848f9ffd26ee..4a4466bd470b1 100644 --- a/packages/kbn-plugin-helpers/tasks/build/create_build.js +++ b/packages/kbn-plugin-helpers/tasks/build/create_build.js @@ -1,6 +1,6 @@ const join = require('path').join; const relative = require('path').relative; -const unlinkSync = require('fs').unlinkSync; +const { readFileSync, writeFileSync, unlinkSync, existsSync } = require('fs'); const execFileSync = require('child_process').execFileSync; const del = require('del'); const vfs = require('vinyl-fs'); @@ -29,7 +29,29 @@ function removeSymlinkDependencies(root) { }); } -module.exports = function createBuild(plugin, buildTarget, buildVersion, kibanaVersion, files) { +// parse a ts config file +function parseTsconfig(pluginSourcePath, configPath) { + const ts = require(join(pluginSourcePath, 'node_modules', 'typescript')); + + const { error, config } = ts.parseConfigFileTextToJson( + configPath, + readFileSync(configPath, 'utf8') + ); + + if (error) { + throw error; + } + + return config; +} + +module.exports = function createBuild( + plugin, + buildTarget, + buildVersion, + kibanaVersion, + files +) { const buildSource = plugin.root; const buildRoot = join(buildTarget, 'kibana', plugin.id); @@ -65,6 +87,45 @@ module.exports = function createBuild(plugin, buildTarget, buildVersion, kibanaV execFileSync(winCmd('yarn'), ['install', '--production', '--pure-lockfile'], options); }) + .then(function () { + const buildConfigPath = join(buildRoot, 'tsconfig.json'); + + if (!existsSync(buildConfigPath)) { + return; + } + + if (!plugin.pkg.devDependencies.typescript) { + throw new Error( + 'Found tsconfig.json file in plugin but typescript is not a devDependency.' + ); + } + + // attempt to patch the extends path in the tsconfig file + const buildConfig = parseTsconfig(buildSource, buildConfigPath); + + if (buildConfig.extends) { + buildConfig.extends = join( + relative(buildRoot, buildSource), + buildConfig.extends + ); + + writeFileSync(buildConfigPath, JSON.stringify(buildConfig)); + } + + execFileSync( + join(buildSource, 'node_modules', '.bin', 'tsc'), + ['--pretty', 'true'], + { + cwd: buildRoot, + stdio: ['ignore', 'pipe', 'pipe'], + } + ); + + del.sync([ + join(buildRoot, '**', '*.{ts,tsx,d.ts}'), + join(buildRoot, 'tsconfig.json'), + ]); + }) .then(function () { const buildFiles = [relative(buildTarget, buildRoot) + '/**/*']; diff --git a/packages/kbn-pm/webpack.config.js b/packages/kbn-pm/webpack.config.js index 6030013a89b97..a654dee5950d1 100644 --- a/packages/kbn-pm/webpack.config.js +++ b/packages/kbn-pm/webpack.config.js @@ -26,6 +26,12 @@ module.exports = { }, { loader: 'ts-loader', + options: { + compilerOptions: { + // enable esnext modules so webpack can do its thing better + module: 'esnext', + }, + }, }, ], exclude: /node_modules/, diff --git a/packages/kbn-system-loader/tsconfig.json b/packages/kbn-system-loader/tsconfig.json index f9a3362e09934..c23b6635a5c19 100644 --- a/packages/kbn-system-loader/tsconfig.json +++ b/packages/kbn-system-loader/tsconfig.json @@ -1,8 +1,6 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "module": "commonjs", - "target": "es2017", "declaration": true, "outDir": "./target" }, diff --git a/src/babel-register/index.js b/src/babel-register/index.js index d10546d1f98a9..29fe6778accca 100644 --- a/src/babel-register/index.js +++ b/src/babel-register/index.js @@ -1,3 +1,13 @@ +// unless we are running a prebuilt/distributable version of +// kibana, automatically transpile typescript to js before babel +if (!global.__BUILT_WITH_BABEL__) { + const { resolve } = require('path'); + require('ts-node').register({ + transpileOnly: true, + cacheDirectory: resolve(__dirname, '../../optimize/.cache/ts-node') + }); +} + // register and polyfill need to happen in this // order and in separate files. Checkout each file // for a much more detailed explaination diff --git a/src/dev/build/build_distributables.js b/src/dev/build/build_distributables.js index 28983f13181f7..8a428a1ee7f11 100644 --- a/src/dev/build/build_distributables.js +++ b/src/dev/build/build_distributables.js @@ -6,6 +6,7 @@ import { CleanExtraBinScriptsTask, CleanExtraFilesFromModulesTask, CleanPackagesTask, + CleanTypescriptTask, CleanTask, CopySourceTask, CreateArchivesSourcesTask, @@ -21,7 +22,8 @@ import { InstallDependenciesTask, OptimizeBuildTask, RemovePackageJsonDepsTask, - TranspileSourceTask, + TranspileBabelTask, + TranspileTypescriptTask, UpdateLicenseFileTask, VerifyEnvTask, VerifyExistingNodeBuildsTask, @@ -76,10 +78,12 @@ export async function buildDistributables(options) { await run(CopySourceTask); await run(CreateEmptyDirsAndFilesTask); await run(CreateReadmeTask); - await run(TranspileSourceTask); + await run(TranspileBabelTask); + await run(TranspileTypescriptTask); await run(BuildPackagesTask); await run(CreatePackageJsonTask); await run(InstallDependenciesTask); + await run(CleanTypescriptTask); await run(CleanPackagesTask); await run(CreateNoticeFileTask); await run(UpdateLicenseFileTask); diff --git a/src/dev/build/lib/fs.js b/src/dev/build/lib/fs.js index 1391b0e0ac309..c7f960e98b2e1 100644 --- a/src/dev/build/lib/fs.js +++ b/src/dev/build/lib/fs.js @@ -2,10 +2,12 @@ import fs from 'fs'; import { createHash } from 'crypto'; import { resolve, dirname, isAbsolute } from 'path'; import { createGunzip } from 'zlib'; +import { inspect } from 'util'; import vfs from 'vinyl-fs'; import { promisify } from 'bluebird'; import mkdirpCb from 'mkdirp'; +import del from 'del'; import { createPromiseFromStreams, createMapStream } from '../../../utils'; import { Extract } from 'tar'; @@ -26,6 +28,12 @@ function assertAbsolute(path) { } } +function longInspect(value) { + return inspect(value, { + maxArrayLength: Infinity + }); +} + export async function mkdirp(path) { assertAbsolute(path); await mkdirpAsync(path); @@ -67,6 +75,22 @@ export async function copy(source, destination) { await chmodAsync(destination, stat.mode); } +export async function deleteAll(log, patterns) { + if (!Array.isArray(patterns)) { + throw new TypeError('Expected patterns to be an array'); + } + + log.debug('Deleting patterns:', longInspect(patterns)); + + for (const pattern of patterns) { + assertAbsolute(pattern.startsWith('!') ? pattern.slice(1) : pattern); + } + + const files = await del(patterns); + log.debug('Deleted %d files/directories', files.length); + log.verbose('Deleted:', longInspect(files)); +} + export async function copyAll(sourceDir, destination, options = {}) { const { select = ['**/*'], diff --git a/src/dev/build/lib/index.js b/src/dev/build/lib/index.js index b3fc50315af5f..7e4c3cbb23eaa 100644 --- a/src/dev/build/lib/index.js +++ b/src/dev/build/lib/index.js @@ -10,4 +10,5 @@ export { copyAll, getFileHash, untar, + deleteAll, } from './fs'; diff --git a/src/dev/build/tasks/clean_tasks.js b/src/dev/build/tasks/clean_tasks.js index d13f29191c847..64e72912ace1c 100644 --- a/src/dev/build/tasks/clean_tasks.js +++ b/src/dev/build/tasks/clean_tasks.js @@ -1,11 +1,11 @@ -import del from 'del'; +import { deleteAll } from '../lib'; export const CleanTask = { global: true, description: 'Cleaning artifacts from previous builds', - async run(config) { - await del([ + async run(config, log) { + await deleteAll(log, [ config.resolveFromRepo('build'), config.resolveFromRepo('target'), ]); @@ -16,7 +16,21 @@ export const CleanPackagesTask = { description: 'Cleaning source for packages that are now installed in node_modules', async run(config, log, build) { - await del([build.resolvePath('packages'), build.resolvePath('x-pack')]); + await deleteAll(log, [ + build.resolvePath('packages'), + build.resolvePath('x-pack') + ]); + }, +}; + +export const CleanTypescriptTask = { + description: 'Cleaning typescript source files that have been transpiled to JS', + + async run(config, log, build) { + await deleteAll(log, [ + build.resolvePath('**/*.{ts,tsx,d.ts}'), + build.resolvePath('**/tsconfig.json'), + ]); }, }; @@ -24,7 +38,7 @@ export const CleanExtraFilesFromModulesTask = { description: 'Cleaning tests, examples, docs, etc. from node_modules', async run(config, log, build) { - await del([ + await deleteAll(log, [ build.resolvePath('node_modules/**/test/**/*'), build.resolvePath('node_modules/**/tests/**/*'), build.resolvePath('node_modules/**/example/**/*'), @@ -38,10 +52,16 @@ export const CleanExtraBinScriptsTask = { async run(config, log, build) { for (const platform of config.getPlatforms()) { - const patterns = platform.isWindows() ? ['*', '!*.bat'] : ['*.bat']; - await del(patterns, { - cwd: build.resolvePathForPlatform(platform, 'bin') - }); + if (platform.isWindows()) { + await deleteAll(log, [ + build.resolvePathForPlatform(platform, 'bin', '*'), + `!${build.resolvePathForPlatform(platform, 'bin', '*.bat')}` + ]); + } else { + await deleteAll(log, [ + build.resolvePathForPlatform(platform, 'bin', '*.bat'), + ]); + } } } }; diff --git a/src/dev/build/tasks/copy_source_task.js b/src/dev/build/tasks/copy_source_task.js index 0f3b316287667..1847b87af79c2 100644 --- a/src/dev/build/tasks/copy_source_task.js +++ b/src/dev/build/tasks/copy_source_task.js @@ -9,7 +9,8 @@ export const CopySourceTask = { select: [ 'yarn.lock', 'src/**', - '!src/**/__tests__/**', + '!src/**/*.test.{js,ts,tsx}', + '!src/**/{__tests__,__snapshots__}/**', '!src/test_utils/**', '!src/fixtures/**', '!src/core_plugins/dev_mode/**', @@ -23,6 +24,7 @@ export const CopySourceTask = { 'bin/**', 'webpackShims/**', 'config/kibana.yml', + 'tsconfig.json', ], }); }, diff --git a/src/dev/build/tasks/index.js b/src/dev/build/tasks/index.js index 5a47fdc6ad5fe..5585106603298 100644 --- a/src/dev/build/tasks/index.js +++ b/src/dev/build/tasks/index.js @@ -13,6 +13,7 @@ export * from './nodejs'; export * from './notice_file_task'; export * from './optimize_task'; export * from './os_packages'; -export * from './transpile_source_task'; +export * from './transpile_babel_task'; +export * from './transpile_typescript_task'; export * from './verify_env_task'; export * from './write_sha_sums_task'; diff --git a/src/dev/build/tasks/optimize_task.js b/src/dev/build/tasks/optimize_task.js index 08deb806eae35..d762ec1da5d97 100644 --- a/src/dev/build/tasks/optimize_task.js +++ b/src/dev/build/tasks/optimize_task.js @@ -1,6 +1,4 @@ -import del from 'del'; - -import { copyAll, exec } from '../lib'; +import { deleteAll, copyAll, exec } from '../lib'; import { getNodeDownloadInfo } from './nodejs'; export const OptimizeBuildTask = { @@ -34,6 +32,6 @@ export const OptimizeBuildTask = { }); // clean up temporary node install - await del(tempNodeInstallDir); + await deleteAll(log, [tempNodeInstallDir]); }, }; diff --git a/src/dev/build/tasks/transpile_source_task.js b/src/dev/build/tasks/transpile_babel_task.js similarity index 94% rename from src/dev/build/tasks/transpile_source_task.js rename to src/dev/build/tasks/transpile_babel_task.js index c338abe1251f8..c8fd38fb19ba7 100644 --- a/src/dev/build/tasks/transpile_source_task.js +++ b/src/dev/build/tasks/transpile_babel_task.js @@ -3,7 +3,7 @@ import vfs from 'vinyl-fs'; import { createPromiseFromStreams } from '../../../utils'; -export const TranspileSourceTask = { +export const TranspileBabelTask = { description: 'Transpiling sources with babel', async run(config, log, build) { diff --git a/src/dev/build/tasks/transpile_typescript_task.js b/src/dev/build/tasks/transpile_typescript_task.js new file mode 100644 index 0000000000000..235f99c1ed027 --- /dev/null +++ b/src/dev/build/tasks/transpile_typescript_task.js @@ -0,0 +1,18 @@ +import { exec } from '../lib'; + +export const TranspileTypescriptTask = { + description: 'Transpiling sources with typescript compiler', + + async run(config, log, build) { + await exec( + log, + require.resolve('typescript/bin/tsc'), + [ + '--pretty', 'true' + ], + { + cwd: build.resolvePath(), + } + ); + }, +}; diff --git a/src/dev/constants.js b/src/dev/constants.ts similarity index 100% rename from src/dev/constants.js rename to src/dev/constants.ts diff --git a/src/dev/file.js b/src/dev/file.js deleted file mode 100644 index 970b7a7c4df65..0000000000000 --- a/src/dev/file.js +++ /dev/null @@ -1,46 +0,0 @@ -import { dirname, join, resolve, relative, extname } from 'path'; - -import { REPO_ROOT } from './constants'; - -export class File { - constructor(path) { - this._path = resolve(path); - this._relativePath = relative(REPO_ROOT, this._path); - this._ext = extname(this._path); - } - - getRelativePath() { - return this._relativePath; - } - - isJs() { - return this._ext === '.js'; - } - - getRelativeParentDirs() { - const parents = []; - - while (true) { - const parent = parents.length - // NOTE: resolve() produces absolute paths, so we have to use join() - ? join(parents[parents.length - 1], '..') - : dirname(this._relativePath); - - if (parent === '..' || parent === '.') { - break; - } else { - parents.push(parent); - } - } - - return parents; - } - - toString() { - return this._relativePath; - } - - toJSON() { - return this._relativePath; - } -} diff --git a/src/dev/file.ts b/src/dev/file.ts new file mode 100644 index 0000000000000..ece3ab44f73cb --- /dev/null +++ b/src/dev/file.ts @@ -0,0 +1,58 @@ +import { dirname, extname, join, relative, resolve } from 'path'; + +import { REPO_ROOT } from './constants'; + +export class File { + private path: string; + private relativePath: string; + private ext: string; + + constructor(path: string) { + this.path = resolve(path); + this.relativePath = relative(REPO_ROOT, this.path); + this.ext = extname(this.path); + } + + public getAbsolutePath() { + return this.path; + } + + public getRelativePath() { + return this.relativePath; + } + + public isJs() { + return this.ext === '.js'; + } + + public isTypescript() { + return this.ext === '.ts' || this.ext === '.tsx'; + } + + public getRelativeParentDirs() { + const parents: string[] = []; + + while (true) { + // NOTE: resolve() produces absolute paths, so we have to use join() + const parent = parents.length + ? join(parents[parents.length - 1], '..') + : dirname(this.relativePath); + + if (parent === '..' || parent === '.') { + break; + } else { + parents.push(parent); + } + } + + return parents; + } + + public toString() { + return this.relativePath; + } + + public toJSON() { + return this.relativePath; + } +} diff --git a/src/dev/jest/config.js b/src/dev/jest/config.js index 5468d75f2cfa7..84fac685e067e 100644 --- a/src/dev/jest/config.js +++ b/src/dev/jest/config.js @@ -35,7 +35,6 @@ export default { ], globals: { 'ts-jest': { - tsConfigFile: 'src/dev/jest/tsconfig.json', skipBabel: true, }, }, @@ -43,14 +42,14 @@ export default { 'js', 'json', 'ts', + 'tsx', ], modulePathIgnorePatterns: [ '__fixtures__/', 'target/', ], testMatch: [ - '**/*.test.js', - '**/*.test.ts', + '**/*.test.{js,ts,tsx}' ], testPathIgnorePatterns: [ '/packages/kbn-ui-framework/(dist|doc_site|generator-kui)/', @@ -59,7 +58,7 @@ export default { ], transform: { '^.+\\.js$': '/src/dev/jest/babel_transform.js', - '^.+\\.ts$': 'ts-jest', + '^.+\\.tsx?$': '/src/dev/jest/ts_transform.js', }, transformIgnorePatterns: [ '[/\\\\]node_modules[/\\\\].+\\.js$', diff --git a/src/dev/jest/ts_transform.js b/src/dev/jest/ts_transform.js new file mode 100644 index 0000000000000..e03e6636ba281 --- /dev/null +++ b/src/dev/jest/ts_transform.js @@ -0,0 +1,2 @@ +require('../../babel-register'); +module.exports = require('./ts_transform.ts'); diff --git a/src/dev/jest/ts_transform.ts b/src/dev/jest/ts_transform.ts new file mode 100644 index 0000000000000..d35a9d19a7630 --- /dev/null +++ b/src/dev/jest/ts_transform.ts @@ -0,0 +1,37 @@ +import { getCacheKey, install, process } from 'ts-jest'; +import { JestConfig, TransformOptions } from 'ts-jest/dist/jest-types'; + +import { transform } from 'typescript'; +import { findProjectForAbsolutePath } from '../typescript'; + +function extendJestConfigJSON(jestConfigJSON: string, filePath: string) { + const jestConfig = JSON.parse(jestConfigJSON) as JestConfig; + return JSON.stringify(extendJestConfig(jestConfig, filePath)); +} + +function extendJestConfig(jestConfig: JestConfig, filePath: string) { + return { + ...jestConfig, + globals: { + ...(jestConfig.globals || {}), + 'ts-jest': { + tsConfigFile: findProjectForAbsolutePath(filePath).getTsConfigPath(), + skipBabel: true, + }, + }, + }; +} + +module.exports = { + process(src: string, filePath: string, jestConfig: JestConfig, transformOptions: TransformOptions) { + const extendedConfig = extendJestConfig(jestConfig, filePath); + return process(src, filePath, extendedConfig, transformOptions); + }, + + getCacheKey(src: string, filePath: string, jestConfigJSON: string, transformOptions: TransformOptions) { + const extendedConfigJSON = extendJestConfigJSON(jestConfigJSON, filePath); + return getCacheKey(src, filePath, extendedConfigJSON, transformOptions); + }, + + install, +}; diff --git a/src/dev/jest/tsconfig.json b/src/dev/jest/tsconfig.json deleted file mode 100644 index 0bfce298942b0..0000000000000 --- a/src/dev/jest/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - // Specific changes to TS config needed to run the tests. - - "extends": "../../../tsconfig.json", - "compilerOptions": { - "module": "commonjs", - // In production we run the TS output through Babel or Webpack, so we can - // output `esnext` while the tests are ran directly on the TypeScript - // output. We therefore need to the target to match what is available when - // Jest is running. When upgrading Node.js versions we can therefore likely - // update the target to a newer version of EcmaScript. - "target": "es2015" - }, - "include": [ - "../../../**/*.ts" - ] -} diff --git a/src/dev/typescript/index.ts b/src/dev/typescript/index.ts new file mode 100644 index 0000000000000..028859cd52812 --- /dev/null +++ b/src/dev/typescript/index.ts @@ -0,0 +1 @@ +export { findProjectForAbsolutePath } from './project'; diff --git a/src/dev/typescript/project.ts b/src/dev/typescript/project.ts new file mode 100644 index 0000000000000..62bbe723aa4c6 --- /dev/null +++ b/src/dev/typescript/project.ts @@ -0,0 +1,73 @@ +import { readFileSync } from 'fs'; +import { basename, dirname, relative, resolve } from 'path'; +import globby from 'globby'; + +import { IMinimatch, Minimatch } from 'minimatch'; +import { parseConfigFileTextToJson } from 'typescript'; + +import { File } from '../file'; + +const ROOT_DIR = resolve(__dirname, '../../../'); + +function makeMatchers(directory: string, patterns: string[]) { + return patterns.map(pattern => new Minimatch(resolve(directory, pattern), { + dot: true, + })); +} + +export class Project { + public static fromConfig(path: string) { + const { error, config } = parseConfigFileTextToJson(path, readFileSync(path, 'utf8')); + + if (error) { + throw error; + } + + return new Project(path, config.files, config.include, config.exclude); + } + + private include: IMinimatch[]; + private exclude: IMinimatch[]; + + constructor(private tsConfigPath: string, files?: string[], include?: string[], exclude: string[] = []) { + if (files || !include) { + throw new Error( + 'tsconfig.json files in the Kibana repo must use "include" keys and not "files"' + ); + } + + this.include = makeMatchers(dirname(tsConfigPath), include); + this.exclude = makeMatchers(dirname(tsConfigPath), exclude); + } + + public getTsConfigPath() { + return this.tsConfigPath; + } + + public isAbsolutePathSelected(path: string) { + return this.exclude.some(exc => exc.match(path)) + ? false + : this.include.some(inc => inc.match(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 +} diff --git a/src/optimize/base_optimizer.js b/src/optimize/base_optimizer.js index a606f07a2c692..5d87e553d6e73 100644 --- a/src/optimize/base_optimizer.js +++ b/src/optimize/base_optimizer.js @@ -102,8 +102,8 @@ export default class BaseOptimizer { * files in optimize/.cache that are not necessary for distributable versions * of Kibana and just make compressing and extracting it more difficult. */ - function maybeAddCacheLoader(uiBundles, cacheName, loaders) { - if (!uiBundles.isDevMode()) { + const maybeAddCacheLoader = (cacheName, loaders) => { + if (!this.uiBundles.isDevMode()) { return loaders; } @@ -111,12 +111,30 @@ export default class BaseOptimizer { { loader: 'cache-loader', options: { - cacheDirectory: uiBundles.getCacheDirectory(cacheName) + cacheDirectory: this.uiBundles.getCacheDirectory(cacheName) } }, ...loaders ]; - } + }; + + /** + * Creates the selection rules for a loader that will only pass for + * source files that are eligible for automatic transpilation. + */ + const createSourceFileResourceSelector = (test) => { + return [ + { + test, + exclude: BABEL_EXCLUDE_RE.concat(this.uiBundles.getWebpackNoParseRules()), + }, + { + test, + include: /[\/\\]node_modules[\/\\]x-pack[\/\\]/, + exclude: /[\/\\]node_modules[\/\\]x-pack[\/\\]node_modules[\/\\]/, + } + ]; + }; const commonConfig = { node: { fs: 'empty' }, @@ -188,7 +206,7 @@ export default class BaseOptimizer { test: /\.less$/, use: getStyleLoaders( ['less-loader'], - maybeAddCacheLoader(this.uiBundles, 'less', []) + maybeAddCacheLoader('less', []) ), }, { @@ -213,18 +231,8 @@ export default class BaseOptimizer { loader: 'file-loader' }, { - resource: [ - { - test: /\.js$/, - exclude: BABEL_EXCLUDE_RE.concat(this.uiBundles.getWebpackNoParseRules()), - }, - { - test: /\.js$/, - include: /[\/\\]node_modules[\/\\]x-pack[\/\\]/, - exclude: /[\/\\]node_modules[\/\\]x-pack[\/\\]node_modules[\/\\]/, - } - ], - use: maybeAddCacheLoader(this.uiBundles, 'babel', [ + resource: createSourceFileResourceSelector(/\.js$/), + use: maybeAddCacheLoader('babel', [ { loader: 'babel-loader', options: { @@ -261,6 +269,44 @@ export default class BaseOptimizer { if (this.uiBundles.isDevMode()) { return webpackMerge(commonConfig, { + module: { + rules: [ + { + resource: createSourceFileResourceSelector(/\.tsx?$/), + use: maybeAddCacheLoader('typescript', [ + { + loader: 'ts-loader', + options: { + transpileOnly: true, + experimentalWatchApi: true, + onlyCompileBundledFiles: true, + compilerOptions: { + jsx: 'react', + sourceMap: Boolean(this.sourceMaps), + target: 'es5', + module: 'esnext', + } + } + } + ]), + } + ] + }, + + stats: { + // when typescript doesn't do a full type check, as we have the ts-loader + // configured here, it does not have enough information to determine + // whether an imported name is a type or not, so when the name is then + // exported, typescript has no choice but to emit the export. Fortunately, + // the extraneous export should not be harmful, so we just suppress these warnings + // https://github.com/TypeStrong/ts-loader#transpileonly-boolean-defaultfalse + warningsFilter: /export .* was not found in/ + }, + + resolve: { + extensions: ['.ts', '.tsx'], + }, + // In the test env we need to add react-addons (and a few other bits) for the // enzyme tests to work. // https://github.com/airbnb/enzyme/blob/master/docs/guides/webpack.md diff --git a/tasks/config/functional_test_runner.js b/tasks/config/functional_test_runner.js index d1f353a043fbd..6dd0301513329 100644 --- a/tasks/config/functional_test_runner.js +++ b/tasks/config/functional_test_runner.js @@ -1,13 +1,13 @@ export const functional = { options: { - logLevel: 'debug', + logLevel: 'verbose', configFile: require.resolve('../../test/functional/config.js') } }; export const apiIntegration = { options: { - logLevel: 'debug', + logLevel: 'verbose', configFile: require.resolve('../../test/api_integration/config.js') } }; diff --git a/tsconfig.json b/tsconfig.json index 4b2b96f4aa050..d66b58425f931 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,19 +1,25 @@ { "compilerOptions": { + "baseUrl": ".", + // Enables all strict type checking options. "strict": true, - // Library files to be included in the compilation. Basically which "core - // language features" TypeScript should enable. - "lib": ["es2015", "es2016", "es2017"], + // enables "core language features" + "lib": [ + // ESNext auto includes previous versions all the way back to es5 + "esnext", + // includes support for browser APIs + "dom" + ], - // Which version of EcmaScript TypeScript should transpile to. Because of - // how Babel and Webpack is set up we currently target `esnext`, and let - // Babel take care of transpiling it down. + // Node 8 should support everything output by esnext, we override this + // in webpack with loader-level compiler options "target": "esnext", - // Specifies module code generation. - "module": "esnext", + // Use commonjs for node, overriden in webpack to keep import statements + // to maintain support for things like `await import()` + "module": "commonjs", // Allows default imports from modules with no default export. This does not affect code emit, just type checking. // We have to enable this option explicitly since `esModuleInterop` doesn't enable it automatically when ES2015 or @@ -28,14 +34,9 @@ "moduleResolution": "node", // Disallow inconsistently-cased references to the same file. - "forceConsistentCasingInFileNames": true, - - // Generate an external source map. There's also an `--inlineSourceMap` for - // emitting a single file with source maps instead of having a separate file. - "sourceMap": true + "forceConsistentCasingInFileNames": true }, - - "exclude": [ - "node_modules" + "include": [ + "src/**/*" ] } diff --git a/x-pack/.kibana-plugin-helpers.json b/x-pack/.kibana-plugin-helpers.json index 6faacc9aa0a0a..5120016237f71 100644 --- a/x-pack/.kibana-plugin-helpers.json +++ b/x-pack/.kibana-plugin-helpers.json @@ -9,6 +9,7 @@ "NOTICE.txt", "package.json", "yarn.lock", + "tsconfig.json", "index.js", "plugins/reporting/.phantom/*", "plugins/reporting/.chromium/*", diff --git a/x-pack/dev-tools/jest/create_jest_config.js b/x-pack/dev-tools/jest/create_jest_config.js index 82e0a70c4c87b..b11980f23a171 100644 --- a/x-pack/dev-tools/jest/create_jest_config.js +++ b/x-pack/dev-tools/jest/create_jest_config.js @@ -15,7 +15,9 @@ export function createJestConfig({ ], moduleFileExtensions: [ "js", - "json" + "json", + "ts", + "tsx", ], moduleNameMapper: { "^ui/(.*)": `${kibanaDirectory}/src/ui/public/$1`, @@ -28,10 +30,11 @@ export function createJestConfig({ `/dev-tools/jest/setup/enzyme.js` ], testMatch: [ - "**/*.test.js" + "**/*.test.{js,ts,tsx}" ], transform: { - "^.+\\.js$": `${kibanaDirectory}/src/dev/jest/babel_transform.js` + "^.+\\.js$": `${kibanaDirectory}/src/dev/jest/babel_transform.js`, + "^.+\\.tsx?$": `${kibanaDirectory}/src/dev/jest/ts_transform.js`, }, transformIgnorePatterns: [ "[/\\\\]node_modules[/\\\\].+\\.js$" diff --git a/x-pack/package.json b/x-pack/package.json index 53dfc672d6ccd..bf411a3d2b82e 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -70,6 +70,7 @@ "supertest-as-promised": "4.0.2", "tmp": "0.0.31", "tree-kill": "^1.1.0", + "typescript": "^2.8.3", "vinyl-fs": "^3.0.2", "xml-crypto": "^0.10.1", "xml2js": "^0.4.19", diff --git a/x-pack/tsconfig.json b/x-pack/tsconfig.json new file mode 100644 index 0000000000000..a01f0127c96cb --- /dev/null +++ b/x-pack/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../tsconfig.json", + "include": [ + "common/**/*", + "server/**/*", + "plugins/**/*" + ] +} diff --git a/x-pack/yarn.lock b/x-pack/yarn.lock index e6be545cedead..26895be8f54ee 100644 --- a/x-pack/yarn.lock +++ b/x-pack/yarn.lock @@ -7188,6 +7188,10 @@ typedarray@^0.0.6, typedarray@~0.0.5: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" +typescript@^2.8.3: + version "2.8.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.8.3.tgz#5d817f9b6f31bb871835f4edf0089f21abe6c170" + ua-parser-js@^0.7.9: version "0.7.17" resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac" diff --git a/yarn.lock b/yarn.lock index e4e2ab3ebba4d..8165bf16b31b8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -172,10 +172,36 @@ call-me-maybe "^1.0.1" glob-to-regexp "^0.3.0" +"@types/events@*": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86" + +"@types/glob@*": + version "5.0.35" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-5.0.35.tgz#1ae151c802cece940443b5ac246925c85189f32a" + dependencies: + "@types/events" "*" + "@types/minimatch" "*" + "@types/node" "*" + +"@types/globby@^6.1.0": + version "6.1.0" + resolved "https://registry.yarnpkg.com/@types/globby/-/globby-6.1.0.tgz#7c25b975512a89effea2a656ca8cf6db7fb29d11" + dependencies: + "@types/glob" "*" + "@types/json-stable-stringify@^1.0.32": version "1.0.32" resolved "https://registry.yarnpkg.com/@types/json-stable-stringify/-/json-stable-stringify-1.0.32.tgz#121f6917c4389db3923640b2e68de5fa64dda88e" +"@types/minimatch@*": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" + +"@types/minimatch@^2.0.29": + version "2.0.29" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-2.0.29.tgz#5002e14f75e2d71e564281df0431c8c1b4a2a36a" + "@types/node@*": version "9.4.7" resolved "https://registry.yarnpkg.com/@types/node/-/node-9.4.7.tgz#57d81cd98719df2c9de118f2d5f3b1120dcd7275" @@ -816,6 +842,30 @@ babel-core@^6.0.0, babel-core@^6.18.0, babel-core@^6.26.0: slash "^1.0.0" source-map "^0.5.6" +babel-core@^6.26.3: + version "6.26.3" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" + dependencies: + babel-code-frame "^6.26.0" + babel-generator "^6.26.0" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + convert-source-map "^1.5.1" + debug "^2.6.9" + json5 "^0.5.1" + lodash "^4.17.4" + minimatch "^3.0.4" + path-is-absolute "^1.0.1" + private "^0.1.8" + slash "^1.0.0" + source-map "^0.5.7" + babel-eslint@8.1.2: version "8.1.2" resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.1.2.tgz#a39230b0c20ecbaa19a35d5633bf9b9ca2c8116f" @@ -980,7 +1030,7 @@ babel-plugin-check-es2015-constants@^6.22.0: dependencies: babel-runtime "^6.22.0" -babel-plugin-istanbul@^4.1.4, babel-plugin-istanbul@^4.1.5: +babel-plugin-istanbul@^4.1.5: version "4.1.5" resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.5.tgz#6760cdd977f411d3e175bb064f2bc327d99b2b6e" dependencies: @@ -988,9 +1038,14 @@ babel-plugin-istanbul@^4.1.4, babel-plugin-istanbul@^4.1.5: istanbul-lib-instrument "^1.7.5" test-exclude "^4.1.1" -babel-plugin-jest-hoist@^22.4.1: - version "22.4.1" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-22.4.1.tgz#d712fe5da8b6965f3191dacddbefdbdf4fb66d63" +babel-plugin-istanbul@^4.1.6: + version "4.1.6" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz#36c59b2192efce81c5b378321b74175add1c9a45" + dependencies: + babel-plugin-syntax-object-rest-spread "^6.13.0" + find-up "^2.1.0" + istanbul-lib-instrument "^1.10.1" + test-exclude "^4.2.1" babel-plugin-jest-hoist@^22.4.3: version "22.4.3" @@ -1144,7 +1199,7 @@ babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015 babel-runtime "^6.22.0" babel-template "^6.24.1" -babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1, babel-plugin-transform-es2015-modules-commonjs@^6.26.0: +babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz#0d8394029b7dc6abe1a97ef181e00758dd2e5d8a" dependencies: @@ -1153,6 +1208,15 @@ babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-e babel-template "^6.26.0" babel-types "^6.26.0" +babel-plugin-transform-es2015-modules-commonjs@^6.26.2: + version "6.26.2" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3" + dependencies: + babel-plugin-transform-strict-mode "^6.24.1" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-types "^6.26.0" + babel-plugin-transform-es2015-modules-systemjs@^6.23.0, babel-plugin-transform-es2015-modules-systemjs@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" @@ -1368,13 +1432,6 @@ babel-preset-flow@^6.23.0: dependencies: babel-plugin-transform-flow-strip-types "^6.22.0" -babel-preset-jest@^22.4.0: - version "22.4.1" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-22.4.1.tgz#efa2e5f5334242a9457a068452d7d09735db172a" - dependencies: - babel-plugin-jest-hoist "^22.4.1" - babel-plugin-syntax-object-rest-spread "^6.13.0" - babel-preset-jest@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-22.4.3.tgz#e92eef9813b7026ab4ca675799f37419b5a44156" @@ -1856,6 +1913,10 @@ buffer-equal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-1.0.0.tgz#59616b498304d556abd466966b22eeda3eca5fbe" +buffer-from@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.0.0.tgz#4cb8832d23612589b0406e9e2956c17f06fdf531" + buffer-xor@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" @@ -3484,7 +3545,7 @@ diff@3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9" -diff@^3.2.0: +diff@^3.1.0, diff@^3.2.0: version "3.5.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" @@ -3796,7 +3857,7 @@ engine.io@1.8.3: engine.io-parser "1.3.2" ws "1.1.2" -enhanced-resolve@^3.4.0: +enhanced-resolve@^3.0.0, enhanced-resolve@^3.4.0: version "3.4.1" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz#0421e339fd71419b3da13d129b3979040230476e" dependencies: @@ -4404,17 +4465,6 @@ expect.js@0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/expect.js/-/expect.js-0.3.1.tgz#b0a59a0d2eff5437544ebf0ceaa6015841d09b5b" -expect@^22.4.0: - version "22.4.0" - resolved "https://registry.yarnpkg.com/expect/-/expect-22.4.0.tgz#371edf1ae15b83b5bf5ec34b42f1584660a36c16" - dependencies: - ansi-styles "^3.2.0" - jest-diff "^22.4.0" - jest-get-type "^22.1.0" - jest-matcher-utils "^22.4.0" - jest-message-util "^22.4.0" - jest-regex-util "^22.1.0" - expect@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/expect/-/expect-22.4.3.tgz#d5a29d0a0e1fb2153557caef2674d4547e914674" @@ -4868,9 +4918,9 @@ fs-exists-sync@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz#982d6893af918e72d08dec9e8673ff2b5a8d6add" -fs-extra@4.0.3, fs-extra@^4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" +fs-extra@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-6.0.0.tgz#0f0afb290bb3deb87978da816fcd3c7797f3a817" dependencies: graceful-fs "^4.1.2" jsonfile "^4.0.0" @@ -4884,6 +4934,14 @@ fs-extra@^3.0.1: jsonfile "^3.0.0" universalify "^0.1.0" +fs-extra@^4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + fs-mkdirp-stream@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz#0b7815fc3201c6a69e14db98ce098c16935259eb" @@ -6723,22 +6781,6 @@ jest-cli@^22.4.3: which "^1.2.12" yargs "^10.0.3" -jest-config@^22.4.2: - version "22.4.2" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-22.4.2.tgz#580ba5819bf81a5e48f4fd470e8b81834f45c855" - dependencies: - chalk "^2.0.1" - glob "^7.1.1" - jest-environment-jsdom "^22.4.1" - jest-environment-node "^22.4.1" - jest-get-type "^22.1.0" - jest-jasmine2 "^22.4.2" - jest-regex-util "^22.1.0" - jest-resolve "^22.4.2" - jest-util "^22.4.1" - jest-validate "^22.4.2" - pretty-format "^22.4.0" - jest-config@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-22.4.3.tgz#0e9d57db267839ea31309119b41dc2fa31b76403" @@ -6755,15 +6797,6 @@ jest-config@^22.4.3: jest-validate "^22.4.3" pretty-format "^22.4.3" -jest-diff@^22.4.0: - version "22.4.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-22.4.0.tgz#384c2b78519ca44ca126382df53f134289232525" - dependencies: - chalk "^2.0.1" - diff "^3.2.0" - jest-get-type "^22.1.0" - pretty-format "^22.4.0" - jest-diff@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-22.4.3.tgz#e18cc3feff0aeef159d02310f2686d4065378030" @@ -6783,14 +6816,6 @@ jest-docblock@^22.4.3: dependencies: detect-newline "^2.1.0" -jest-environment-jsdom@^22.4.1: - version "22.4.1" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-22.4.1.tgz#754f408872441740100d3917e5ec40c74de6447f" - dependencies: - jest-mock "^22.2.0" - jest-util "^22.4.1" - jsdom "^11.5.1" - jest-environment-jsdom@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-22.4.3.tgz#d67daa4155e33516aecdd35afd82d4abf0fa8a1e" @@ -6799,13 +6824,6 @@ jest-environment-jsdom@^22.4.3: jest-util "^22.4.3" jsdom "^11.5.1" -jest-environment-node@^22.4.1: - version "22.4.1" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-22.4.1.tgz#418850eb654596b8d6e36c2021cbedbc23df8e16" - dependencies: - jest-mock "^22.2.0" - jest-util "^22.4.1" - jest-environment-node@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-22.4.3.tgz#54c4eaa374c83dd52a9da8759be14ebe1d0b9129" @@ -6813,10 +6831,6 @@ jest-environment-node@^22.4.3: jest-mock "^22.4.3" jest-util "^22.4.3" -jest-get-type@^22.1.0: - version "22.1.0" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.1.0.tgz#4e90af298ed6181edc85d2da500dbd2753e0d5a9" - jest-get-type@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.4.3.tgz#e3a8504d8479342dd4420236b322869f18900ce4" @@ -6833,22 +6847,6 @@ jest-haste-map@^22.4.3: micromatch "^2.3.11" sane "^2.0.0" -jest-jasmine2@^22.4.2: - version "22.4.2" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-22.4.2.tgz#dfd3d259579ed6f52510d8f1ab692808f0d40691" - dependencies: - chalk "^2.0.1" - co "^4.6.0" - expect "^22.4.0" - graceful-fs "^4.1.11" - is-generator-fn "^1.0.0" - jest-diff "^22.4.0" - jest-matcher-utils "^22.4.0" - jest-message-util "^22.4.0" - jest-snapshot "^22.4.0" - jest-util "^22.4.1" - source-map-support "^0.5.0" - jest-jasmine2@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-22.4.3.tgz#4daf64cd14c793da9db34a7c7b8dcfe52a745965" @@ -6871,14 +6869,6 @@ jest-leak-detector@^22.4.3: dependencies: pretty-format "^22.4.3" -jest-matcher-utils@^22.4.0: - version "22.4.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-22.4.0.tgz#d55f5faf2270462736bdf7c7485ee931c9d4b6a1" - dependencies: - chalk "^2.0.1" - jest-get-type "^22.1.0" - pretty-format "^22.4.0" - jest-matcher-utils@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-22.4.3.tgz#4632fe428ebc73ebc194d3c7b65d37b161f710ff" @@ -6887,16 +6877,6 @@ jest-matcher-utils@^22.4.3: jest-get-type "^22.4.3" pretty-format "^22.4.3" -jest-message-util@^22.4.0: - version "22.4.0" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-22.4.0.tgz#e3d861df16d2fee60cb2bc8feac2188a42579642" - dependencies: - "@babel/code-frame" "^7.0.0-beta.35" - chalk "^2.0.1" - micromatch "^2.3.11" - slash "^1.0.0" - stack-utils "^1.0.1" - jest-message-util@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-22.4.3.tgz#cf3d38aafe4befddbfc455e57d65d5239e399eb7" @@ -6907,18 +6887,10 @@ jest-message-util@^22.4.3: slash "^1.0.0" stack-utils "^1.0.1" -jest-mock@^22.2.0: - version "22.2.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-22.2.0.tgz#444b3f9488a7473adae09bc8a77294afded397a7" - jest-mock@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-22.4.3.tgz#f63ba2f07a1511772cdc7979733397df770aabc7" -jest-regex-util@^22.1.0: - version "22.1.0" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-22.1.0.tgz#5daf2fe270074b6da63e5d85f1c9acc866768f53" - jest-regex-util@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-22.4.3.tgz#a826eb191cdf22502198c5401a1fc04de9cef5af" @@ -6929,13 +6901,6 @@ jest-resolve-dependencies@^22.4.3: dependencies: jest-regex-util "^22.4.3" -jest-resolve@^22.4.2: - version "22.4.2" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-22.4.2.tgz#25d88aa4147462c9c1c6a1ba16250d3794c24d00" - dependencies: - browser-resolve "^1.11.2" - chalk "^2.0.1" - jest-resolve@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-22.4.3.tgz#0ce9d438c8438229aa9b916968ec6b05c1abb4ea" @@ -6988,17 +6953,6 @@ jest-serializer@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-22.4.3.tgz#a679b81a7f111e4766235f4f0c46d230ee0f7436" -jest-snapshot@^22.4.0: - version "22.4.0" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-22.4.0.tgz#03d3ce63f8fa7352388afc6a3c8b5ccc3a180ed7" - dependencies: - chalk "^2.0.1" - jest-diff "^22.4.0" - jest-matcher-utils "^22.4.0" - mkdirp "^0.5.1" - natural-compare "^1.4.0" - pretty-format "^22.4.0" - jest-snapshot@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-22.4.3.tgz#b5c9b42846ffb9faccb76b841315ba67887362d2" @@ -7010,18 +6964,6 @@ jest-snapshot@^22.4.3: natural-compare "^1.4.0" pretty-format "^22.4.3" -jest-util@^22.4.1: - version "22.4.1" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-22.4.1.tgz#dd17c3bdb067f8e90591563ec0c42bf847dc249f" - dependencies: - callsites "^2.0.0" - chalk "^2.0.1" - graceful-fs "^4.1.11" - is-ci "^1.0.10" - jest-message-util "^22.4.0" - mkdirp "^0.5.1" - source-map "^0.6.0" - jest-util@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-22.4.3.tgz#c70fec8eec487c37b10b0809dc064a7ecf6aafac" @@ -7034,16 +6976,6 @@ jest-util@^22.4.3: mkdirp "^0.5.1" source-map "^0.6.0" -jest-validate@^22.4.2: - version "22.4.2" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-22.4.2.tgz#e789a4e056173bf97fe797a2df2d52105c57d4f4" - dependencies: - chalk "^2.0.1" - jest-config "^22.4.2" - jest-get-type "^22.1.0" - leven "^2.1.0" - pretty-format "^22.4.0" - jest-validate@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-22.4.3.tgz#0780954a5a7daaeec8d3c10834b9280865976b30" @@ -8017,6 +7949,10 @@ lodash@^4.0.0, lodash@^4.0.1, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.15.0, lo version "4.17.5" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511" +lodash@^4.17.10: + version "4.17.10" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" + lodash@~4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.3.0.tgz#efd9c4a6ec53f3b05412429915c3e4824e4d25a4" @@ -8114,6 +8050,10 @@ make-dir@^1.0.0: dependencies: pify "^3.0.0" +make-error@^1.1.1: + version "1.3.4" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.4.tgz#19978ed575f9e9545d2ff8c13e33b5d18a67d535" + makeerror@1.0.x: version "1.0.11" resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" @@ -9659,13 +9599,6 @@ prettier@^1.12.1: version "1.12.1" resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.12.1.tgz#c1ad20e803e7749faf905a409d2367e06bbe7325" -pretty-format@^22.4.0: - version "22.4.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-22.4.0.tgz#237b1f7e1c50ed03bc65c03ccc29d7c8bb7beb94" - dependencies: - ansi-regex "^3.0.0" - ansi-styles "^3.2.0" - pretty-format@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-22.4.3.tgz#f873d780839a9c02e9664c8a082e9ee79eaac16f" @@ -9677,7 +9610,7 @@ prismjs@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-0.0.1.tgz#0fd50f4baf26e5cd33523b65bac2f0bc90f5503f" -private@^0.1.6, private@^0.1.7: +private@^0.1.6, private@^0.1.7, private@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" @@ -10979,7 +10912,7 @@ semver-diff@^2.0.0: dependencies: semver "^5.0.3" -"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0: +"semver@2 || 3 || 4 || 5", semver@^5.0.1, semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" @@ -11261,6 +11194,13 @@ source-map-support@^0.5.0: dependencies: source-map "^0.6.0" +source-map-support@^0.5.3, source-map-support@^0.5.5: + version "0.5.6" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.6.tgz#4435cee46b1aab62b8e8610ce60f788091c51c13" + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + source-map-url@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" @@ -11873,7 +11813,7 @@ term-size@^1.2.0: dependencies: execa "^0.7.0" -test-exclude@^4.1.1: +test-exclude@^4.1.1, test-exclude@^4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.2.1.tgz#dfa222f03480bca69207ca728b37d74b45f724fa" dependencies: @@ -12152,20 +12092,45 @@ trunc-text@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/trunc-text/-/trunc-text-1.0.2.tgz#b582bb3ddea9c9adc25017d737c48ebdd2157406" -ts-jest@^22.4.3: - version "22.4.3" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-22.4.3.tgz#5c06b89359e598d97f08802936ea400be555a9d1" +ts-jest@^22.4.6: + version "22.4.6" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-22.4.6.tgz#a5d7f5e8b809626d1f4143209d301287472ec344" dependencies: - babel-core "^6.26.0" - babel-plugin-istanbul "^4.1.4" - babel-plugin-transform-es2015-modules-commonjs "^6.26.0" - babel-preset-jest "^22.4.0" + babel-core "^6.26.3" + babel-plugin-istanbul "^4.1.6" + babel-plugin-transform-es2015-modules-commonjs "^6.26.2" + babel-preset-jest "^22.4.3" cpx "^1.5.0" - fs-extra "4.0.3" - jest-config "^22.4.2" + fs-extra "6.0.0" + jest-config "^22.4.3" + lodash "^4.17.10" pkg-dir "^2.0.0" + source-map-support "^0.5.5" yargs "^11.0.0" +ts-loader@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-3.5.0.tgz#151d004dcddb4cf8e381a3bf9d6b74c2d957a9c0" + dependencies: + chalk "^2.3.0" + enhanced-resolve "^3.0.0" + loader-utils "^1.0.2" + micromatch "^3.1.4" + semver "^5.0.1" + +ts-node@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-6.0.3.tgz#28bf74bcad134fad17f7469dad04638ece03f0f4" + dependencies: + arrify "^1.0.0" + chalk "^2.3.0" + diff "^3.1.0" + make-error "^1.1.1" + minimist "^1.2.0" + mkdirp "^0.5.1" + source-map-support "^0.5.3" + yn "^2.0.0" + tslib@^1.9.0: version "1.9.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.0.tgz#e37a86fda8cbbaf23a057f473c9f4dc64e5fc2e8" @@ -12215,9 +12180,9 @@ typedarray@^0.0.6, typedarray@~0.0.5: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" -typescript@^2.8.1: - version "2.8.1" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.8.1.tgz#6160e4f8f195d5ba81d4876f9c0cc1fbc0820624" +typescript@^2.8.3: + version "2.8.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.8.3.tgz#5d817f9b6f31bb871835f4edf0089f21abe6c170" ua-parser-js@^0.7.9: version "0.7.17" @@ -13432,6 +13397,10 @@ yeast@0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" +yn@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yn/-/yn-2.0.0.tgz#e5adabc8acf408f6385fc76495684c88e6af689a" + zlib@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/zlib/-/zlib-1.0.5.tgz#6e7c972fc371c645a6afb03ab14769def114fcc0"