mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
Expose core api types in /public and /server (#32746)
* Expose core api types in /public and /server * Export CoreStart from core/public * Export Server and Public from 'kibana' * Cast frozen object type back to original The exported type `InjectedMetadataStart` derives it's type from the returned values. Since it's internal state is frozen the type changes to `ReadOnly<`. However, consumers of the API shouldn't have to know or care about this type. * Be more selective with what gets exported * Fix type imports in tests * Fix type errors * Remove src/type_exports.ts * More remove src/type_exports.ts * Remove build:types * Fix bootstrap import * Expose internal API's at the top level Exposing the internal API's at the top level of core/public and core/server makes it obvious that these API's are consumed outside these modules. Marking these @internal ensures they don't get exported as part of the documentation. * Fix tests * Put core/{public/server} in their own namespaces
This commit is contained in:
parent
effebd8c05
commit
1ffb261788
20 changed files with 152 additions and 180 deletions
3
kibana.d.ts
vendored
3
kibana.d.ts
vendored
|
@ -20,7 +20,8 @@
|
|||
/**
|
||||
* All exports from TS source files (where the implementation is actually done in TS).
|
||||
*/
|
||||
export * from './target/types/type_exports';
|
||||
export { Public, Server } from 'src/core';
|
||||
|
||||
/**
|
||||
* All exports from TS ambient definitions (where types are added for JS source in a .d.ts file).
|
||||
*/
|
||||
|
|
|
@ -67,8 +67,7 @@
|
|||
"uiFramework:createComponent": "cd packages/kbn-ui-framework && yarn createComponent",
|
||||
"uiFramework:documentComponent": "cd packages/kbn-ui-framework && yarn documentComponent",
|
||||
"kbn:watch": "node scripts/kibana --dev --logging.json=false",
|
||||
"build:types": "tsc --p tsconfig.types.json",
|
||||
"kbn:bootstrap": "yarn build:types && node scripts/register_git_hook"
|
||||
"kbn:bootstrap": "node scripts/register_git_hook"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
|
23
src/core/index.ts
Normal file
23
src/core/index.ts
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import * as Public from './public';
|
||||
import * as Server from './server';
|
||||
|
||||
export { Public, Server };
|
|
@ -42,6 +42,8 @@ interface Params {
|
|||
* of Kibana in the UI, including the LegacyPlatform which is managed
|
||||
* by the LegacyPlatformService. As we migrate more things to the new
|
||||
* platform the CoreSystem will get many more Services.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
export class CoreSystem {
|
||||
private readonly fatalErrors: FatalErrorsService;
|
||||
|
|
|
@ -17,4 +17,24 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { BasePathStart } from './base_path';
|
||||
import { ChromeStart } from './chrome';
|
||||
import { FatalErrorsStart } from './fatal_errors';
|
||||
import { HttpStart } from './http';
|
||||
import { I18nStart } from './i18n';
|
||||
import { InjectedMetadataStart } from './injected_metadata';
|
||||
import { NotificationsStart } from './notifications';
|
||||
import { UiSettingsClient } from './ui_settings';
|
||||
|
||||
export { CoreSystem } from './core_system';
|
||||
|
||||
export interface CoreStart {
|
||||
i18n: I18nStart;
|
||||
injectedMetadata: InjectedMetadataStart;
|
||||
fatalErrors: FatalErrorsStart;
|
||||
notifications: NotificationsStart;
|
||||
http: HttpStart;
|
||||
basePath: BasePathStart;
|
||||
uiSettings: UiSettingsClient;
|
||||
chrome: ChromeStart;
|
||||
}
|
||||
|
|
|
@ -59,7 +59,9 @@ export interface InjectedMetadataParams {
|
|||
* and is read from the DOM in most cases.
|
||||
*/
|
||||
export class InjectedMetadataService {
|
||||
private state = deepFreeze(this.params.injectedMetadata);
|
||||
private state = deepFreeze(
|
||||
this.params.injectedMetadata
|
||||
) as InjectedMetadataParams['injectedMetadata'];
|
||||
|
||||
constructor(private readonly params: InjectedMetadataParams) {}
|
||||
|
||||
|
|
|
@ -18,25 +18,7 @@
|
|||
*/
|
||||
|
||||
import angular from 'angular';
|
||||
import { BasePathStart } from '../base_path';
|
||||
import { ChromeStart } from '../chrome';
|
||||
import { FatalErrorsStart } from '../fatal_errors';
|
||||
import { HttpStart } from '../http';
|
||||
import { I18nStart } from '../i18n';
|
||||
import { InjectedMetadataStart } from '../injected_metadata';
|
||||
import { NotificationsStart } from '../notifications';
|
||||
import { UiSettingsClient } from '../ui_settings';
|
||||
|
||||
interface Deps {
|
||||
i18n: I18nStart;
|
||||
injectedMetadata: InjectedMetadataStart;
|
||||
fatalErrors: FatalErrorsStart;
|
||||
notifications: NotificationsStart;
|
||||
http: HttpStart;
|
||||
basePath: BasePathStart;
|
||||
uiSettings: UiSettingsClient;
|
||||
chrome: ChromeStart;
|
||||
}
|
||||
import { CoreStart } from '../';
|
||||
|
||||
export interface LegacyPlatformParams {
|
||||
targetDomElement: HTMLElement;
|
||||
|
@ -54,7 +36,7 @@ export interface LegacyPlatformParams {
|
|||
export class LegacyPlatformService {
|
||||
constructor(private readonly params: LegacyPlatformParams) {}
|
||||
|
||||
public start(deps: Deps) {
|
||||
public start(core: CoreStart) {
|
||||
const {
|
||||
i18n,
|
||||
injectedMetadata,
|
||||
|
@ -64,10 +46,10 @@ export class LegacyPlatformService {
|
|||
basePath,
|
||||
uiSettings,
|
||||
chrome,
|
||||
} = deps;
|
||||
} = core;
|
||||
// Inject parts of the new platform into parts of the legacy platform
|
||||
// so that legacy APIs/modules can mimic their new platform counterparts
|
||||
require('ui/new_platform').__newPlatformInit__(deps);
|
||||
require('ui/new_platform').__newPlatformInit__(core);
|
||||
require('ui/metadata').__newPlatformInit__(injectedMetadata.getLegacyMetadata());
|
||||
require('ui/i18n').__newPlatformInit__(i18n.Context);
|
||||
require('ui/notify/fatal_error').__newPlatformInit__(fatalErrors);
|
||||
|
|
|
@ -47,6 +47,11 @@ interface BootstrapArgs {
|
|||
features: KibanaFeatures;
|
||||
}
|
||||
|
||||
/**
|
||||
* @interal
|
||||
*
|
||||
* @param options
|
||||
*/
|
||||
export async function bootstrap({
|
||||
configs,
|
||||
cliArgs,
|
||||
|
|
|
@ -17,67 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { PluginsModule } from './plugins';
|
||||
|
||||
export { bootstrap } from './bootstrap';
|
||||
|
||||
import { first } from 'rxjs/operators';
|
||||
import { ConfigService, Env } from './config';
|
||||
import { ElasticsearchModule } from './elasticsearch';
|
||||
import { HttpConfig, HttpModule, HttpServerInfo } from './http';
|
||||
import { LegacyCompatModule } from './legacy';
|
||||
import { Logger, LoggerFactory } from './logging';
|
||||
|
||||
export class Server {
|
||||
private readonly elasticsearch: ElasticsearchModule;
|
||||
private readonly http: HttpModule;
|
||||
private readonly plugins: PluginsModule;
|
||||
private readonly legacy: LegacyCompatModule;
|
||||
private readonly log: Logger;
|
||||
|
||||
constructor(configService: ConfigService, logger: LoggerFactory, private readonly env: Env) {
|
||||
this.log = logger.get('server');
|
||||
|
||||
this.http = new HttpModule(configService.atPath('server', HttpConfig), logger);
|
||||
|
||||
const core = { env, configService, logger };
|
||||
this.plugins = new PluginsModule(core);
|
||||
this.legacy = new LegacyCompatModule(core);
|
||||
this.elasticsearch = new ElasticsearchModule(core);
|
||||
}
|
||||
|
||||
public async start() {
|
||||
this.log.debug('starting server');
|
||||
|
||||
// We shouldn't start http service in two cases:
|
||||
// 1. If `server.autoListen` is explicitly set to `false`.
|
||||
// 2. When the process is run as dev cluster master in which case cluster manager
|
||||
// will fork a dedicated process where http service will be started instead.
|
||||
let httpStart: HttpServerInfo | undefined;
|
||||
const httpConfig = await this.http.config$.pipe(first()).toPromise();
|
||||
if (!this.env.isDevClusterMaster && httpConfig.autoListen) {
|
||||
httpStart = await this.http.service.start();
|
||||
}
|
||||
|
||||
const elasticsearchServiceStart = await this.elasticsearch.service.start();
|
||||
|
||||
const pluginsStart = await this.plugins.service.start({
|
||||
elasticsearch: elasticsearchServiceStart,
|
||||
});
|
||||
|
||||
await this.legacy.service.start({
|
||||
elasticsearch: elasticsearchServiceStart,
|
||||
http: httpStart,
|
||||
plugins: pluginsStart,
|
||||
});
|
||||
}
|
||||
|
||||
public async stop() {
|
||||
this.log.debug('stopping server');
|
||||
|
||||
await this.legacy.service.stop();
|
||||
await this.plugins.service.stop();
|
||||
await this.elasticsearch.service.stop();
|
||||
await this.http.service.stop();
|
||||
}
|
||||
}
|
||||
export { CallAPIOptions, ClusterClient } from './elasticsearch';
|
||||
export { Logger, LoggerFactory } from './logging';
|
||||
export { PluginInitializerContext, PluginName, PluginStartContext } from './plugins';
|
||||
|
|
|
@ -30,7 +30,7 @@ jest.mock('../config/config_service', () => ({
|
|||
}));
|
||||
|
||||
const mockServer = { start: jest.fn(), stop: jest.fn() };
|
||||
jest.mock('../', () => ({ Server: jest.fn(() => mockServer) }));
|
||||
jest.mock('../server', () => ({ Server: jest.fn(() => mockServer) }));
|
||||
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { filter, first } from 'rxjs/operators';
|
||||
|
|
|
@ -20,9 +20,9 @@
|
|||
import { ConnectableObservable, Observable, Subscription } from 'rxjs';
|
||||
import { first, map, publishReplay, switchMap, tap } from 'rxjs/operators';
|
||||
|
||||
import { Server } from '..';
|
||||
import { Config, ConfigService, Env } from '../config';
|
||||
import { Logger, LoggerFactory, LoggingConfig, LoggingService } from '../logging';
|
||||
import { Server } from '../server';
|
||||
|
||||
/**
|
||||
* Top-level entry point to kick off the app and start the Kibana server.
|
||||
|
|
|
@ -39,12 +39,12 @@ jest.mock('./legacy/legacy_service', () => ({
|
|||
}));
|
||||
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { Server } from '.';
|
||||
import { Env } from './config';
|
||||
import { getEnvOptions } from './config/__mocks__/env';
|
||||
import { loggingServiceMock } from './logging/logging_service.mock';
|
||||
import { Server } from './server';
|
||||
|
||||
import { getEnvOptions } from './config/__mocks__/env';
|
||||
import { configServiceMock } from './config/config_service.mock';
|
||||
import { loggingServiceMock } from './logging/logging_service.mock';
|
||||
|
||||
const configService = configServiceMock.create();
|
||||
const env = new Env('.', getEnvOptions());
|
80
src/core/server/server.ts
Normal file
80
src/core/server/server.ts
Normal file
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { first } from 'rxjs/operators';
|
||||
import { ConfigService, Env } from './config';
|
||||
import { ElasticsearchModule } from './elasticsearch';
|
||||
import { HttpConfig, HttpModule, HttpServerInfo } from './http';
|
||||
import { LegacyCompatModule } from './legacy';
|
||||
import { Logger, LoggerFactory } from './logging';
|
||||
import { PluginsModule } from './plugins';
|
||||
|
||||
export class Server {
|
||||
private readonly elasticsearch: ElasticsearchModule;
|
||||
private readonly http: HttpModule;
|
||||
private readonly plugins: PluginsModule;
|
||||
private readonly legacy: LegacyCompatModule;
|
||||
private readonly log: Logger;
|
||||
|
||||
constructor(configService: ConfigService, logger: LoggerFactory, private readonly env: Env) {
|
||||
this.log = logger.get('server');
|
||||
|
||||
this.http = new HttpModule(configService.atPath('server', HttpConfig), logger);
|
||||
|
||||
const core = { env, configService, logger };
|
||||
this.plugins = new PluginsModule(core);
|
||||
this.legacy = new LegacyCompatModule(core);
|
||||
this.elasticsearch = new ElasticsearchModule(core);
|
||||
}
|
||||
|
||||
public async start() {
|
||||
this.log.debug('starting server');
|
||||
|
||||
// We shouldn't start http service in two cases:
|
||||
// 1. If `server.autoListen` is explicitly set to `false`.
|
||||
// 2. When the process is run as dev cluster master in which case cluster manager
|
||||
// will fork a dedicated process where http service will be started instead.
|
||||
let httpStart: HttpServerInfo | undefined;
|
||||
const httpConfig = await this.http.config$.pipe(first()).toPromise();
|
||||
if (!this.env.isDevClusterMaster && httpConfig.autoListen) {
|
||||
httpStart = await this.http.service.start();
|
||||
}
|
||||
|
||||
const elasticsearchServiceStart = await this.elasticsearch.service.start();
|
||||
|
||||
const pluginsStart = await this.plugins.service.start({
|
||||
elasticsearch: elasticsearchServiceStart,
|
||||
});
|
||||
|
||||
await this.legacy.service.start({
|
||||
elasticsearch: elasticsearchServiceStart,
|
||||
http: httpStart,
|
||||
plugins: pluginsStart,
|
||||
});
|
||||
}
|
||||
|
||||
public async stop() {
|
||||
this.log.debug('stopping server');
|
||||
|
||||
await this.legacy.service.stop();
|
||||
await this.plugins.service.stop();
|
||||
await this.elasticsearch.service.stop();
|
||||
await this.http.service.stop();
|
||||
}
|
||||
}
|
|
@ -24,10 +24,6 @@ export const TranspileTypescriptTask = {
|
|||
description: 'Transpiling sources with typescript compiler',
|
||||
|
||||
async run(config, log, build) {
|
||||
// the types project is built inside the repo so x-pack can use it for it's in-repo build.
|
||||
const typesProjectRepo = new Project(config.resolveFromRepo('tsconfig.types.json'));
|
||||
const typesProjectBuild = new Project(build.resolvePath('tsconfig.types.json'));
|
||||
|
||||
// these projects are built in the build folder
|
||||
const defaultProject = new Project(build.resolvePath('tsconfig.json'));
|
||||
const browserProject = new Project(build.resolvePath('tsconfig.browser.json'));
|
||||
|
@ -52,8 +48,6 @@ export const TranspileTypescriptTask = {
|
|||
}));
|
||||
|
||||
const projects = [
|
||||
typesProjectRepo.tsConfigPath,
|
||||
typesProjectBuild.tsConfigPath,
|
||||
// Browser needs to be compiled before server code so that any shared code
|
||||
// is compiled to the lowest common denominator (server's CommonJS format)
|
||||
// which can be supported by both environments.
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
import { errors } from 'elasticsearch';
|
||||
import { CallAPIOptions, ClusterClient } from 'kibana';
|
||||
import { CallAPIOptions, ClusterClient } from 'kibana/server';
|
||||
|
||||
export class Cluster {
|
||||
public readonly errors = errors;
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
import { map, mergeMap } from 'rxjs/operators';
|
||||
|
||||
import { Logger, PluginInitializerContext, PluginName, PluginStartContext } from 'kibana';
|
||||
import { Logger, PluginInitializerContext, PluginName, PluginStartContext } from 'kibana/server';
|
||||
import { TestBedConfig } from './config';
|
||||
|
||||
class Plugin {
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This file re-exports only those Kibana types that we'd like plugins to have access to.
|
||||
*
|
||||
* Generated types are referenced from the `types` field of the Kibana's `package.json`, so
|
||||
* that plugins can just reference Kibana root folder to access all required types.
|
||||
*
|
||||
* Here is an example of how plugin can use these types assuming it is located
|
||||
* in one of the known plugin locations (kibana/plugins/* or kibana-extra/*):
|
||||
*
|
||||
* ```ts
|
||||
* import { Logger, PluginInitializerContext, PluginStartContext } from '../../kibana';
|
||||
*
|
||||
* export interface SomePlugin {
|
||||
* setValue: (val: string) => void;
|
||||
* }
|
||||
*
|
||||
* class Plugin {
|
||||
* private readonly log: Logger;
|
||||
*
|
||||
* constructor(private readonly initializerContext: PluginInitializerContext) {
|
||||
* this.log = initializerContext.logger.get();
|
||||
* }
|
||||
*
|
||||
* start(startContext: PluginStartContext, deps: Record<string, any>) {
|
||||
* this.log.info('Hello from plugin!');
|
||||
*
|
||||
* let value = 'Hello World!';
|
||||
*
|
||||
* const router = startContext.http.createAndRegisterRouter('/some-path');
|
||||
* router.get('/some-value', (req, res) => res.ok(value));
|
||||
*
|
||||
* return { setValue: (val: string) => { value = val; } };
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* export plugin = (initializerContext: PluginInitializerContext) => new Plugin(initializerContext));
|
||||
* ```
|
||||
*
|
||||
* **NOTE:** If the code is not needed in plugins, we can add a `at_internal` JSDoc
|
||||
* annotation to that code. And since we've specified the `stripInternal` compiler
|
||||
* option TypeScript will not emit declarations for this code.
|
||||
*/
|
||||
|
||||
export { CallAPIOptions, ClusterClient } from './core/server/elasticsearch';
|
||||
export { Logger, LoggerFactory } from './core/server/logging';
|
||||
export { PluginInitializerContext, PluginName, PluginStartContext } from './core/server/plugins';
|
|
@ -4,6 +4,8 @@
|
|||
"paths": {
|
||||
// Allows for importing from `kibana` package for the exported types.
|
||||
"kibana": ["./kibana"],
|
||||
"kibana/public": ["./src/core/public"],
|
||||
"kibana/server": ["./src/core/server"],
|
||||
"ui/*": [
|
||||
"src/legacy/ui/public/*"
|
||||
],
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
{
|
||||
"extends": "./tsconfig",
|
||||
"compilerOptions": {
|
||||
"declaration": true,
|
||||
"declarationDir": "./target/types",
|
||||
"stripInternal": true,
|
||||
"emitDeclarationOnly": true,
|
||||
"declarationMap": true
|
||||
},
|
||||
"include": [
|
||||
"./src/type_exports.ts"
|
||||
]
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue