From 074e0484fc69cd9075dd30b2d51081568efca6f6 Mon Sep 17 00:00:00 2001 From: Kim Joar Bekkelund Date: Wed, 19 Jul 2017 14:54:59 +0200 Subject: [PATCH 1/7] Make core plugins use `kbn-types` --- package-lock.json | 9 +++++++ package.json | 1 + packages/@elastic/kbn-types/index.ts | 25 +++++++++++++++++-- packages/@elastic/kbn-types/lib.js | 3 +++ packages/@elastic/kbn-types/package.json | 1 + platform/plugins/pid/PidConfig.ts | 2 +- platform/plugins/pid/PidFile.ts | 3 +-- platform/plugins/pid/PidService.ts | 2 +- platform/plugins/pid/index.ts | 3 +-- platform/plugins/reporting/ReportingConfig.ts | 2 +- platform/plugins/reporting/index.ts | 2 +- .../savedObjects/SavedObjectsService.ts | 5 +--- platform/plugins/savedObjects/index.ts | 2 +- .../plugins/savedObjects/registerEndpoints.ts | 4 +-- platform/plugins/timelion/index.ts | 2 +- platform/plugins/timelionPluginA/index.ts | 2 +- platform/plugins/timelionPluginB/index.ts | 2 +- platform/plugins/xpack/XPackConfig.ts | 3 +-- platform/plugins/xpack/index.ts | 2 +- 19 files changed, 51 insertions(+), 24 deletions(-) create mode 100644 packages/@elastic/kbn-types/lib.js diff --git a/package-lock.json b/package-lock.json index 9fc693f73dabd..f0b209868bc1c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9347,6 +9347,15 @@ "integrity": "sha1-lpgqLMR9BmquccVTursoMZEVos4=", "dev": true }, + "kbn-types": { + "version": "file:packages/@elastic/kbn-types", + "dependencies": { + "typescript": { + "version": "2.4.1", + "bundled": true + } + } + }, "kew": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz", diff --git a/package.json b/package.json index fda48285ec030..2b6da586cd382 100644 --- a/package.json +++ b/package.json @@ -148,6 +148,7 @@ "json-loader": "0.5.3", "json-stringify-safe": "5.0.1", "jstimezonedetect": "1.0.5", + "kbn-types": "file:packages/@elastic/kbn-types", "leaflet": "0.7.5", "less": "2.7.1", "less-loader": "2.2.3", diff --git a/packages/@elastic/kbn-types/index.ts b/packages/@elastic/kbn-types/index.ts index 1f262edae0c43..10922903612d8 100644 --- a/packages/@elastic/kbn-types/index.ts +++ b/packages/@elastic/kbn-types/index.ts @@ -1,5 +1,26 @@ export { KibanaFunctionalPlugin, - KibanaPlugin + KibanaPlugin, + KibanaPluginFeatures } from '../../../platform/server/plugins/types'; -export { Logger } from '../../../platform/logging'; +export { Logger, LoggerFactory } from '../../../platform/logging'; +export { ElasticsearchService } from '../../../platform/server/elasticsearch'; +export { KibanaConfig } from '../../../platform/server/kibana'; +export { KibanaRequest, Router } from '../../../platform/server/http'; +export { KibanaError } from '../../../platform/lib/Errors'; +import * as schemaLib from '../../../platform/lib/schema'; + +export type Schema = typeof schemaLib; + +// TODO +// This _can't_ be part of the types, as it has to be available at runtime. +// It was the only way I was able to grab the return type of `createSchema` in +// the configs in a good way for the constructor. Relevant TS issues to solve +// this at the type level: +// https://github.com/Microsoft/TypeScript/issues/6606 +// https://github.com/Microsoft/TypeScript/issues/14400 +export function typeOfSchema( + fn: (...rest: any[]) => RT +): schemaLib.TypeOf { + return undefined; +} diff --git a/packages/@elastic/kbn-types/lib.js b/packages/@elastic/kbn-types/lib.js new file mode 100644 index 0000000000000..ae2f87cf16bf1 --- /dev/null +++ b/packages/@elastic/kbn-types/lib.js @@ -0,0 +1,3 @@ +export function typeOfSchema() { + return undefined; +} diff --git a/packages/@elastic/kbn-types/package.json b/packages/@elastic/kbn-types/package.json index 5cbe18ac3ed35..4c779ba75c5d5 100644 --- a/packages/@elastic/kbn-types/package.json +++ b/packages/@elastic/kbn-types/package.json @@ -1,6 +1,7 @@ { "name": "kbn-types", "version": "0.0.1", + "main": "./lib", "types": "./types/packages/@elastic/kbn-types/index.d.ts", "scripts": { "build": "tsc", diff --git a/platform/plugins/pid/PidConfig.ts b/platform/plugins/pid/PidConfig.ts index a13b6fe1191c9..ca82dc3931a4c 100644 --- a/platform/plugins/pid/PidConfig.ts +++ b/platform/plugins/pid/PidConfig.ts @@ -1,4 +1,4 @@ -import { Schema, typeOfSchema } from '../../types'; +import { Schema, typeOfSchema } from 'kbn-types'; const createPidSchema = (schema: Schema) => schema.object({ diff --git a/platform/plugins/pid/PidFile.ts b/platform/plugins/pid/PidFile.ts index b27edb3b77786..e4d80e6cd6008 100644 --- a/platform/plugins/pid/PidFile.ts +++ b/platform/plugins/pid/PidFile.ts @@ -1,8 +1,7 @@ import { writeFileSync, unlinkSync } from 'fs'; import { PidConfig } from './PidConfig'; -import { LoggerFactory, Logger } from '../../logging'; -import { KibanaError } from '../../lib/Errors'; +import { LoggerFactory, Logger, KibanaError } from 'kbn-types'; const FILE_ALREADY_EXISTS = 'EEXIST'; diff --git a/platform/plugins/pid/PidService.ts b/platform/plugins/pid/PidService.ts index 8ca41bc8add97..1a6f286a7dfb6 100644 --- a/platform/plugins/pid/PidService.ts +++ b/platform/plugins/pid/PidService.ts @@ -1,9 +1,9 @@ import { Observable, Subscription } from 'rxjs'; import { noop } from 'lodash'; +import { LoggerFactory } from 'kbn-types'; import { PidConfig } from './PidConfig'; import { PidFile } from './PidFile'; -import { LoggerFactory } from '../../logging'; export class PidService { private readonly pid$: Observable; diff --git a/platform/plugins/pid/index.ts b/platform/plugins/pid/index.ts index 88b6f0c306f37..4f3c60859700f 100644 --- a/platform/plugins/pid/index.ts +++ b/platform/plugins/pid/index.ts @@ -1,5 +1,4 @@ -import { KibanaPlugin, KibanaPluginFeatures } from '../../server/plugins/types'; -import { Logger } from '../../logging'; +import { KibanaPlugin, Logger, KibanaPluginFeatures } from 'kbn-types'; import { PidConfig } from './PidConfig'; import { PidService } from './PidService'; diff --git a/platform/plugins/reporting/ReportingConfig.ts b/platform/plugins/reporting/ReportingConfig.ts index d9602ca98610c..871227bfab153 100644 --- a/platform/plugins/reporting/ReportingConfig.ts +++ b/platform/plugins/reporting/ReportingConfig.ts @@ -1,4 +1,4 @@ -import { Schema, typeOfSchema } from '../../types'; +import { Schema, typeOfSchema } from 'kbn-types'; const createReportingSchema = (schema: Schema) => schema.object({ diff --git a/platform/plugins/reporting/index.ts b/platform/plugins/reporting/index.ts index b2e6d46e88d0e..34578e4cedf8a 100644 --- a/platform/plugins/reporting/index.ts +++ b/platform/plugins/reporting/index.ts @@ -1,4 +1,4 @@ -import { KibanaFunctionalPlugin } from '../../server/plugins/types'; +import { KibanaFunctionalPlugin } from 'kbn-types'; import { XPackPluginType } from '../xpack'; import { ReportingConfig } from './ReportingConfig'; diff --git a/platform/plugins/savedObjects/SavedObjectsService.ts b/platform/plugins/savedObjects/SavedObjectsService.ts index 565c65f87c6d1..6ffdc06b839e9 100644 --- a/platform/plugins/savedObjects/SavedObjectsService.ts +++ b/platform/plugins/savedObjects/SavedObjectsService.ts @@ -1,9 +1,6 @@ import { Observable } from 'rxjs'; -// TODO Change imports to some types file -import { ElasticsearchService } from '../../server/elasticsearch/ElasticsearchService'; -import { KibanaConfig } from '../../server/kibana'; -import { KibanaRequest } from '../../server/http'; +import { ElasticsearchService, KibanaConfig, KibanaRequest } from 'kbn-types'; export class SavedObjectsService { constructor( diff --git a/platform/plugins/savedObjects/index.ts b/platform/plugins/savedObjects/index.ts index 0b20a187a7aa8..431bda69cd093 100644 --- a/platform/plugins/savedObjects/index.ts +++ b/platform/plugins/savedObjects/index.ts @@ -1,4 +1,4 @@ -import { KibanaFunctionalPlugin } from '../../server/plugins/types'; +import { KibanaFunctionalPlugin } from 'kbn-types'; import { SavedObjectsService } from './SavedObjectsService'; import { registerEndpoints } from './registerEndpoints'; diff --git a/platform/plugins/savedObjects/registerEndpoints.ts b/platform/plugins/savedObjects/registerEndpoints.ts index b3f2ffd6bc5da..13e5f0209628c 100644 --- a/platform/plugins/savedObjects/registerEndpoints.ts +++ b/platform/plugins/savedObjects/registerEndpoints.ts @@ -1,6 +1,4 @@ -import { Router } from '../../server/http'; -import { LoggerFactory } from '../../logging'; -import { Schema } from '../../types'; +import { Router, LoggerFactory, Schema } from 'kbn-types'; import { SavedObjectsService } from './SavedObjectsService'; export function registerEndpoints( diff --git a/platform/plugins/timelion/index.ts b/platform/plugins/timelion/index.ts index da73d6b2cd0c8..d1b7fc0ef3c09 100644 --- a/platform/plugins/timelion/index.ts +++ b/platform/plugins/timelion/index.ts @@ -1,4 +1,4 @@ -import { KibanaFunctionalPlugin } from '../../server/plugins/types'; +import { KibanaFunctionalPlugin } from 'kbn-types'; import { XPackPluginType } from '../xpack'; export const configPath = undefined; diff --git a/platform/plugins/timelionPluginA/index.ts b/platform/plugins/timelionPluginA/index.ts index c0b87531830a6..dbdf55a5e3fb6 100644 --- a/platform/plugins/timelionPluginA/index.ts +++ b/platform/plugins/timelionPluginA/index.ts @@ -1,4 +1,4 @@ -import { KibanaFunctionalPlugin } from '../../server/plugins/types'; +import { KibanaFunctionalPlugin } from 'kbn-types'; import { TimelionPluginType } from '../timelion'; import { TimelionPluginBType } from '../timelionPluginB'; diff --git a/platform/plugins/timelionPluginB/index.ts b/platform/plugins/timelionPluginB/index.ts index 27e64cc458b11..ef77b6c4db7af 100644 --- a/platform/plugins/timelionPluginB/index.ts +++ b/platform/plugins/timelionPluginB/index.ts @@ -1,4 +1,4 @@ -import { KibanaFunctionalPlugin } from '../../server/plugins/types'; +import { KibanaFunctionalPlugin } from 'kbn-types'; import { TimelionPluginType } from '../timelion'; interface TimelionPluginBExports { diff --git a/platform/plugins/xpack/XPackConfig.ts b/platform/plugins/xpack/XPackConfig.ts index 10dc3c7475b74..8cfd102e7956d 100644 --- a/platform/plugins/xpack/XPackConfig.ts +++ b/platform/plugins/xpack/XPackConfig.ts @@ -1,6 +1,5 @@ import { Duration } from 'moment'; - -import { Schema, typeOfSchema } from '../../types'; +import { Schema, typeOfSchema } from 'kbn-types'; const createXPackConfig = (schema: Schema) => schema.object({ diff --git a/platform/plugins/xpack/index.ts b/platform/plugins/xpack/index.ts index 933e223045f47..8c46cd5c90cef 100644 --- a/platform/plugins/xpack/index.ts +++ b/platform/plugins/xpack/index.ts @@ -1,6 +1,6 @@ import { Observable } from 'rxjs'; -import { KibanaFunctionalPlugin } from '../../server/plugins/types'; +import { KibanaFunctionalPlugin } from 'kbn-types'; import { XPackConfig } from './XPackConfig'; export const configPath = ['xpack', 'xpack_main']; From d1036b1e22d833eceb479369a39cf73a9a46afe4 Mon Sep 17 00:00:00 2001 From: Kim Joar Bekkelund Date: Thu, 20 Jul 2017 12:39:54 +0200 Subject: [PATCH 2/7] Add note in readme about kbn-types --- platform/README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/platform/README.md b/platform/README.md index 93c199425b882..734f8e3968e7c 100644 --- a/platform/README.md +++ b/platform/README.md @@ -6,6 +6,17 @@ Make sure you're running the Node version specified in `../.node-version`. ## TypeScript +Both the platform and core plugins are built using TypeScript. + +First you need to build the `kbn-types` package, which is the "external types" +used by core plugins. + +Go to `../packages/@elastic/kbn-types` and build the types (see the readme in +that folder). + +Then, when `kbn-types` is built you can build the platform and core plugins +using: + ``` npm run ts:start ``` From 84b0d50b5fc0d10e4892b1acb0043b5c2270bca2 Mon Sep 17 00:00:00 2001 From: Kim Joar Bekkelund Date: Thu, 20 Jul 2017 13:14:07 +0200 Subject: [PATCH 3/7] fix types --- packages/@elastic/kbn-types/index.ts | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/packages/@elastic/kbn-types/index.ts b/packages/@elastic/kbn-types/index.ts index 10922903612d8..8b417f985e7a8 100644 --- a/packages/@elastic/kbn-types/index.ts +++ b/packages/@elastic/kbn-types/index.ts @@ -4,23 +4,8 @@ export { KibanaPluginFeatures } from '../../../platform/server/plugins/types'; export { Logger, LoggerFactory } from '../../../platform/logging'; +export { Schema, typeOfSchema } from '../../../platform/types'; export { ElasticsearchService } from '../../../platform/server/elasticsearch'; export { KibanaConfig } from '../../../platform/server/kibana'; export { KibanaRequest, Router } from '../../../platform/server/http'; export { KibanaError } from '../../../platform/lib/Errors'; -import * as schemaLib from '../../../platform/lib/schema'; - -export type Schema = typeof schemaLib; - -// TODO -// This _can't_ be part of the types, as it has to be available at runtime. -// It was the only way I was able to grab the return type of `createSchema` in -// the configs in a good way for the constructor. Relevant TS issues to solve -// this at the type level: -// https://github.com/Microsoft/TypeScript/issues/6606 -// https://github.com/Microsoft/TypeScript/issues/14400 -export function typeOfSchema( - fn: (...rest: any[]) => RT -): schemaLib.TypeOf { - return undefined; -} From f86bc84fda225fa9c388a063bf8ae2a49f2ba45f Mon Sep 17 00:00:00 2001 From: Kim Joar Bekkelund Date: Thu, 20 Jul 2017 13:17:16 +0200 Subject: [PATCH 4/7] add todo --- packages/@elastic/kbn-types/lib.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/@elastic/kbn-types/lib.js b/packages/@elastic/kbn-types/lib.js index ae2f87cf16bf1..99aa6f29403c3 100644 --- a/packages/@elastic/kbn-types/lib.js +++ b/packages/@elastic/kbn-types/lib.js @@ -1,3 +1,10 @@ +// TODO Strictly speaking it would be great to not include this function in +// the types package. However, it is needed because of how we inject `schema` +// into configs, so we don't have to specify the full type in the config +// constructors. +// Relevant TS issues for solving this at the type level: +// https://github.com/Microsoft/TypeScript/issues/6606 +// https://github.com/Microsoft/TypeScript/issues/14400 export function typeOfSchema() { return undefined; } From 3b655d526598966b814473d93840818e1b756df3 Mon Sep 17 00:00:00 2001 From: Kim Joar Bekkelund Date: Fri, 21 Jul 2017 00:00:43 +0200 Subject: [PATCH 5/7] extract pidplugin class --- packages/@elastic/kbn-types/index.ts | 5 ++++- platform/plugins/pid/PidPlugin.ts | 26 ++++++++++++++++++++++++++ platform/plugins/pid/index.ts | 27 ++------------------------- 3 files changed, 32 insertions(+), 26 deletions(-) create mode 100644 platform/plugins/pid/PidPlugin.ts diff --git a/packages/@elastic/kbn-types/index.ts b/packages/@elastic/kbn-types/index.ts index 8b417f985e7a8..e7425c1ed2895 100644 --- a/packages/@elastic/kbn-types/index.ts +++ b/packages/@elastic/kbn-types/index.ts @@ -4,7 +4,10 @@ export { KibanaPluginFeatures } from '../../../platform/server/plugins/types'; export { Logger, LoggerFactory } from '../../../platform/logging'; -export { Schema, typeOfSchema } from '../../../platform/types'; +export { + Schema, + typeOfSchema +} from '../../../platform/types'; export { ElasticsearchService } from '../../../platform/server/elasticsearch'; export { KibanaConfig } from '../../../platform/server/kibana'; export { KibanaRequest, Router } from '../../../platform/server/http'; diff --git a/platform/plugins/pid/PidPlugin.ts b/platform/plugins/pid/PidPlugin.ts new file mode 100644 index 0000000000000..4ebac5c405635 --- /dev/null +++ b/platform/plugins/pid/PidPlugin.ts @@ -0,0 +1,26 @@ +import { KibanaPlugin, Logger, KibanaPluginFeatures } from 'kbn-types'; + +import { PidConfig } from './PidConfig'; +import { PidService } from './PidService'; + +export class PidPlugin implements KibanaPlugin { + log: Logger; + pidService: PidService; + + constructor(kibana: KibanaPluginFeatures) { + this.log = kibana.logger.get(); + + const config$ = kibana.config.createIfExists(PidConfig); + this.pidService = new PidService(config$, kibana.logger); + } + + start() { + this.log.info('starting PidService'); + this.pidService.start(); + } + + stop() { + this.log.info('stopping PidService'); + this.pidService.stop(); + } +} diff --git a/platform/plugins/pid/index.ts b/platform/plugins/pid/index.ts index 4f3c60859700f..172b3af6662e6 100644 --- a/platform/plugins/pid/index.ts +++ b/platform/plugins/pid/index.ts @@ -1,30 +1,7 @@ -import { KibanaPlugin, Logger, KibanaPluginFeatures } from 'kbn-types'; - -import { PidConfig } from './PidConfig'; -import { PidService } from './PidService'; +import { PidPlugin } from './PidPlugin'; export const configPath = 'pid'; export const dependencies = []; -export const plugin = class implements KibanaPlugin { - log: Logger; - pidService: PidService; - - constructor(kibana: KibanaPluginFeatures) { - this.log = kibana.logger.get(); - - const config$ = kibana.config.createIfExists(PidConfig); - this.pidService = new PidService(config$, kibana.logger); - } - - start() { - this.log.info('starting PidService'); - this.pidService.start(); - } - - stop() { - this.log.info('stopping PidService'); - this.pidService.stop(); - } -}; +export const plugin = PidPlugin; From f878f4cb907ae3e811c008a6e2a363c687e0f6e9 Mon Sep 17 00:00:00 2001 From: Kim Joar Bekkelund Date: Fri, 21 Jul 2017 12:13:49 +0200 Subject: [PATCH 6/7] readme improvements in kbn-types --- packages/@elastic/kbn-types/README.md | 35 ++++++++++++++++++--------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/packages/@elastic/kbn-types/README.md b/packages/@elastic/kbn-types/README.md index d6decf6262d3b..baa4bda7dbb86 100644 --- a/packages/@elastic/kbn-types/README.md +++ b/packages/@elastic/kbn-types/README.md @@ -1,14 +1,7 @@ # External types for Kibana -``` -npm install -npm run build -``` - -This builds declaration files into `./types/packages/@elastic/kbn-types`, which -is specified as the "main" type file for this package in `./package.json`. - -Now external code can use this package, e.g. something like this: +This package contains external types for Kibana, which enables plugins to use +the types, e.g.: ```ts import { KibanaFunctionalPlugin } from 'kbn-types'; @@ -18,14 +11,32 @@ export const plugin: KibanaFunctionalPlugin<{}> = function(core) { } ``` +## Development + +During development this package is built separatly from the Kibana platform. + +First make sure you run `npm install`, then: + +``` +// to build once: +npm run build + +// to watch for changes: +npm start +``` + +This builds declaration files into `./types/packages/@elastic/kbn-types`, which +is specified as the "main" type file for this package in `./package.json`. + If you want to play around with an example, see the `./example` folder. ## Exposing types -Every type that should be directly `import`able must be exported in -`./index.ts`. +Every type that should be `import`able must be exported in `./index.ts`. + +## Caveats -## `@internal` +### `@internal` There is one gotcha related to these declaration files, which is how TypeScript handles imports when building them. If TypeScript needs to infer a type, but From 8628feb0e7d087f4e3b5ac0f9dfc6f02b5f25782 Mon Sep 17 00:00:00 2001 From: Kim Joar Bekkelund Date: Wed, 26 Jul 2017 12:28:40 +0200 Subject: [PATCH 7/7] decl files --- packages/@elastic/kbn-types/README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/@elastic/kbn-types/README.md b/packages/@elastic/kbn-types/README.md index baa4bda7dbb86..4706169c05ac2 100644 --- a/packages/@elastic/kbn-types/README.md +++ b/packages/@elastic/kbn-types/README.md @@ -62,3 +62,19 @@ There are two ways to fix this problem: For grep-ability, this is the error you'll likely see if hitting this problem: > has or is using name 'Foo' from external module "./bar" but cannot be named + +## Why expose declaration files instead of TypeScript files? + +This package builds TypeScript [declaration files][ts-decl] instead of just +including the TypeScript files themselves. There are a couple reasons for this: + +- If we shipped `.ts` files packages that depend on `kbn-types` would have to + use the same compiler options. That means we also need to find a way to share + that in a sane manner. However, if TypeScript adds the option of using + [`extends` with a package][tsconfig-extends] it might become easier. +- Tools like ts-loader [does not work nicely][ts-loader-node-modules] with `.ts` + files in `node_modules`. + +[ts-decl]: https://www.typescriptlang.org/docs/handbook/declaration-files/introduction.html +[tsconfig-extends]: https://github.com/Microsoft/TypeScript/issues/15984 +[ts-loader-node-modules]: https://github.com/TypeStrong/ts-loader/issues/278