From 003c3b855ee179eb25b9b483415cba3c37e39964 Mon Sep 17 00:00:00 2001 From: Josh Dover Date: Thu, 3 Oct 2019 16:53:30 -0500 Subject: [PATCH] [7.x] Simplify generics for IContextContainer (#46538) (#47266) --- ...c.applicationsetup.registermountcontext.md | 4 +- ...c.applicationstart.registermountcontext.md | 4 +- ...lic.contextsetup.createcontextcontainer.md | 4 +- ...kibana-plugin-public.handlercontexttype.md | 13 ++ .../kibana-plugin-public.handlerfunction.md | 13 ++ .../kibana-plugin-public.handlerparameters.md | 13 ++ ...-public.icontextcontainer.createhandler.md | 6 +- .../kibana-plugin-public.icontextcontainer.md | 2 +- ...ublic.icontextcontainer.registercontext.md | 4 +- .../kibana-plugin-public.icontexthandler.md | 18 --- .../kibana-plugin-public.icontextprovider.md | 2 +- .../core/public/kibana-plugin-public.md | 4 +- .../kibana-plugin-server.basepath.get.md | 2 +- .../server/kibana-plugin-server.basepath.md | 4 +- .../kibana-plugin-server.basepath.set.md | 2 +- ...ver.contextsetup.createcontextcontainer.md | 4 +- .../kibana-plugin-server.coresetup.http.md | 2 +- .../server/kibana-plugin-server.coresetup.md | 2 +- ...kibana-plugin-server.handlercontexttype.md | 13 ++ .../kibana-plugin-server.handlerfunction.md | 13 ++ .../kibana-plugin-server.handlerparameters.md | 13 ++ .../kibana-plugin-server.httpservicesetup.md | 2 +- ...-server.icontextcontainer.createhandler.md | 6 +- .../kibana-plugin-server.icontextcontainer.md | 2 +- ...erver.icontextcontainer.registercontext.md | 4 +- .../kibana-plugin-server.icontexthandler.md | 18 --- .../kibana-plugin-server.icontextprovider.md | 2 +- .../core/server/kibana-plugin-server.md | 6 +- ...n-server.requesthandlercontextcontainer.md | 2 +- ...in-server.requesthandlercontextprovider.md | 2 +- ...bana-plugin-server.requesthandlerparams.md | 13 -- ...bana-plugin-server.requesthandlerreturn.md | 13 -- .../application/application_service.tsx | 11 +- src/core/public/application/types.ts | 8 +- src/core/public/context/context_service.ts | 19 +-- src/core/public/context/index.ts | 8 +- src/core/public/index.ts | 13 +- src/core/public/public.api.md | 27 +++-- src/core/server/context/context_service.ts | 19 +-- src/core/server/context/index.ts | 8 +- src/core/server/http/http_service.ts | 8 +- src/core/server/http/types.ts | 30 ++--- src/core/server/index.ts | 14 ++- src/core/server/server.api.md | 41 +++---- src/core/utils/context.mock.ts | 2 +- src/core/utils/context.test.ts | 52 +++++--- src/core/utils/context.ts | 112 ++++++++++-------- .../licensing_route_handler_context.test.ts | 4 +- .../server/licensing_route_handler_context.ts | 4 +- x-pack/plugins/licensing/server/plugin.ts | 8 ++ 50 files changed, 322 insertions(+), 278 deletions(-) create mode 100644 docs/development/core/public/kibana-plugin-public.handlercontexttype.md create mode 100644 docs/development/core/public/kibana-plugin-public.handlerfunction.md create mode 100644 docs/development/core/public/kibana-plugin-public.handlerparameters.md delete mode 100644 docs/development/core/public/kibana-plugin-public.icontexthandler.md create mode 100644 docs/development/core/server/kibana-plugin-server.handlercontexttype.md create mode 100644 docs/development/core/server/kibana-plugin-server.handlerfunction.md create mode 100644 docs/development/core/server/kibana-plugin-server.handlerparameters.md delete mode 100644 docs/development/core/server/kibana-plugin-server.icontexthandler.md delete mode 100644 docs/development/core/server/kibana-plugin-server.requesthandlerparams.md delete mode 100644 docs/development/core/server/kibana-plugin-server.requesthandlerreturn.md diff --git a/docs/development/core/public/kibana-plugin-public.applicationsetup.registermountcontext.md b/docs/development/core/public/kibana-plugin-public.applicationsetup.registermountcontext.md index 0b5bd8eeb36ec..f264ba500ed6e 100644 --- a/docs/development/core/public/kibana-plugin-public.applicationsetup.registermountcontext.md +++ b/docs/development/core/public/kibana-plugin-public.applicationsetup.registermountcontext.md @@ -9,7 +9,7 @@ Register a context provider for application mounting. Will only be available to Signature: ```typescript -registerMountContext(contextName: T, provider: IContextProvider): void; +registerMountContext(contextName: T, provider: IContextProvider): void; ``` ## Parameters @@ -17,7 +17,7 @@ registerMountContext(contextName: T, provider: | Parameter | Type | Description | | --- | --- | --- | | contextName | T | The key of [AppMountContext](./kibana-plugin-public.appmountcontext.md) this provider's return value should be attached to. | -| provider | IContextProvider<AppMountContext, T> | A [IContextProvider](./kibana-plugin-public.icontextprovider.md) function | +| provider | IContextProvider<App['mount'], T> | A [IContextProvider](./kibana-plugin-public.icontextprovider.md) function | Returns: diff --git a/docs/development/core/public/kibana-plugin-public.applicationstart.registermountcontext.md b/docs/development/core/public/kibana-plugin-public.applicationstart.registermountcontext.md index fc86aaf658b68..62821fcbb92ba 100644 --- a/docs/development/core/public/kibana-plugin-public.applicationstart.registermountcontext.md +++ b/docs/development/core/public/kibana-plugin-public.applicationstart.registermountcontext.md @@ -9,7 +9,7 @@ Register a context provider for application mounting. Will only be available to Signature: ```typescript -registerMountContext(contextName: T, provider: IContextProvider): void; +registerMountContext(contextName: T, provider: IContextProvider): void; ``` ## Parameters @@ -17,7 +17,7 @@ registerMountContext(contextName: T, provider: | Parameter | Type | Description | | --- | --- | --- | | contextName | T | The key of [AppMountContext](./kibana-plugin-public.appmountcontext.md) this provider's return value should be attached to. | -| provider | IContextProvider<AppMountContext, T> | A [IContextProvider](./kibana-plugin-public.icontextprovider.md) function | +| provider | IContextProvider<App['mount'], T> | A [IContextProvider](./kibana-plugin-public.icontextprovider.md) function | Returns: diff --git a/docs/development/core/public/kibana-plugin-public.contextsetup.createcontextcontainer.md b/docs/development/core/public/kibana-plugin-public.contextsetup.createcontextcontainer.md index 2644596354e38..5334eee842577 100644 --- a/docs/development/core/public/kibana-plugin-public.contextsetup.createcontextcontainer.md +++ b/docs/development/core/public/kibana-plugin-public.contextsetup.createcontextcontainer.md @@ -9,9 +9,9 @@ Creates a new [IContextContainer](./kibana-plugin-public.icontextcontainer.md) f Signature: ```typescript -createContextContainer(): IContextContainer; +createContextContainer>(): IContextContainer; ``` Returns: -`IContextContainer` +`IContextContainer` diff --git a/docs/development/core/public/kibana-plugin-public.handlercontexttype.md b/docs/development/core/public/kibana-plugin-public.handlercontexttype.md new file mode 100644 index 0000000000000..b083449d2b703 --- /dev/null +++ b/docs/development/core/public/kibana-plugin-public.handlercontexttype.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [HandlerContextType](./kibana-plugin-public.handlercontexttype.md) + +## HandlerContextType type + +Extracts the type of the first argument of a [HandlerFunction](./kibana-plugin-public.handlerfunction.md) to represent the type of the context. + +Signature: + +```typescript +export declare type HandlerContextType> = T extends HandlerFunction ? U : never; +``` diff --git a/docs/development/core/public/kibana-plugin-public.handlerfunction.md b/docs/development/core/public/kibana-plugin-public.handlerfunction.md new file mode 100644 index 0000000000000..98c342c17691d --- /dev/null +++ b/docs/development/core/public/kibana-plugin-public.handlerfunction.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [HandlerFunction](./kibana-plugin-public.handlerfunction.md) + +## HandlerFunction type + +A function that accepts a context object and an optional number of additional arguments. Used for the generic types in [IContextContainer](./kibana-plugin-public.icontextcontainer.md) + +Signature: + +```typescript +export declare type HandlerFunction = (context: T, ...args: any[]) => any; +``` diff --git a/docs/development/core/public/kibana-plugin-public.handlerparameters.md b/docs/development/core/public/kibana-plugin-public.handlerparameters.md new file mode 100644 index 0000000000000..f46c4b649e943 --- /dev/null +++ b/docs/development/core/public/kibana-plugin-public.handlerparameters.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [HandlerParameters](./kibana-plugin-public.handlerparameters.md) + +## HandlerParameters type + +Extracts the types of the additional arguments of a [HandlerFunction](./kibana-plugin-public.handlerfunction.md), excluding the [HandlerContextType](./kibana-plugin-public.handlercontexttype.md). + +Signature: + +```typescript +export declare type HandlerParameters> = T extends (context: any, ...args: infer U) => any ? U : never; +``` diff --git a/docs/development/core/public/kibana-plugin-public.icontextcontainer.createhandler.md b/docs/development/core/public/kibana-plugin-public.icontextcontainer.createhandler.md index 2a995df45757f..af3b5e3fc2eb6 100644 --- a/docs/development/core/public/kibana-plugin-public.icontextcontainer.createhandler.md +++ b/docs/development/core/public/kibana-plugin-public.icontextcontainer.createhandler.md @@ -9,7 +9,7 @@ Create a new handler function pre-wired to context for the plugin. Signature: ```typescript -createHandler(pluginOpaqueId: PluginOpaqueId, handler: IContextHandler): (...rest: THandlerParameters) => THandlerReturn extends Promise ? THandlerReturn : Promise; +createHandler(pluginOpaqueId: PluginOpaqueId, handler: THandler): (...rest: HandlerParameters) => ShallowPromise>; ``` ## Parameters @@ -17,11 +17,11 @@ createHandler(pluginOpaqueId: PluginOpaqueId, handler: IContextHandlerPluginOpaqueId | The plugin opaque ID for the plugin that registers this handler. | -| handler | IContextHandler<TContext, THandlerReturn, THandlerParameters> | Handler function to pass context object to. | +| handler | THandler | Handler function to pass context object to. | Returns: -`(...rest: THandlerParameters) => THandlerReturn extends Promise ? THandlerReturn : Promise` +`(...rest: HandlerParameters) => ShallowPromise>` A function that takes `THandlerParameters`, calls `handler` with a new context, and returns a Promise of the `handler` return value. diff --git a/docs/development/core/public/kibana-plugin-public.icontextcontainer.md b/docs/development/core/public/kibana-plugin-public.icontextcontainer.md index 0bc7c8f3808d1..f16c07b3d7906 100644 --- a/docs/development/core/public/kibana-plugin-public.icontextcontainer.md +++ b/docs/development/core/public/kibana-plugin-public.icontextcontainer.md @@ -9,7 +9,7 @@ An object that handles registration of context providers and configuring handler Signature: ```typescript -export interface IContextContainer +export interface IContextContainer> ``` ## Methods diff --git a/docs/development/core/public/kibana-plugin-public.icontextcontainer.registercontext.md b/docs/development/core/public/kibana-plugin-public.icontextcontainer.registercontext.md index 2cf10a6ec841d..775f95bd7affa 100644 --- a/docs/development/core/public/kibana-plugin-public.icontextcontainer.registercontext.md +++ b/docs/development/core/public/kibana-plugin-public.icontextcontainer.registercontext.md @@ -9,7 +9,7 @@ Register a new context provider. Signature: ```typescript -registerContext(pluginOpaqueId: PluginOpaqueId, contextName: TContextName, provider: IContextProvider): this; +registerContext>(pluginOpaqueId: PluginOpaqueId, contextName: TContextName, provider: IContextProvider): this; ``` ## Parameters @@ -18,7 +18,7 @@ registerContext(pluginOpaqueId: PluginOpaqu | --- | --- | --- | | pluginOpaqueId | PluginOpaqueId | The plugin opaque ID for the plugin that registers this context. | | contextName | TContextName | The key of the TContext object this provider supplies the value for. | -| provider | IContextProvider<TContext, TContextName, THandlerParameters> | A [IContextProvider](./kibana-plugin-public.icontextprovider.md) to be called each time a new context is created. | +| provider | IContextProvider<THandler, TContextName> | A [IContextProvider](./kibana-plugin-public.icontextprovider.md) to be called each time a new context is created. | Returns: diff --git a/docs/development/core/public/kibana-plugin-public.icontexthandler.md b/docs/development/core/public/kibana-plugin-public.icontexthandler.md deleted file mode 100644 index 2251b1131c313..0000000000000 --- a/docs/development/core/public/kibana-plugin-public.icontexthandler.md +++ /dev/null @@ -1,18 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [IContextHandler](./kibana-plugin-public.icontexthandler.md) - -## IContextHandler type - -A function registered by a plugin to perform some action. - -Signature: - -```typescript -export declare type IContextHandler = (context: TContext, ...rest: THandlerParameters) => TReturn; -``` - -## Remarks - -A new `TContext` will be built for each handler before invoking. - diff --git a/docs/development/core/public/kibana-plugin-public.icontextprovider.md b/docs/development/core/public/kibana-plugin-public.icontextprovider.md index a84917d6e1442..40f0ee3782f6d 100644 --- a/docs/development/core/public/kibana-plugin-public.icontextprovider.md +++ b/docs/development/core/public/kibana-plugin-public.icontextprovider.md @@ -9,7 +9,7 @@ A function that returns a context value for a specific key of given context type Signature: ```typescript -export declare type IContextProvider, TContextName extends keyof TContext, TProviderParameters extends any[] = []> = (context: Partial, ...rest: TProviderParameters) => Promise | TContext[TContextName]; +export declare type IContextProvider, TContextName extends keyof HandlerContextType> = (context: Partial>, ...rest: HandlerParameters) => Promise[TContextName]> | HandlerContextType[TContextName]; ``` ## Remarks diff --git a/docs/development/core/public/kibana-plugin-public.md b/docs/development/core/public/kibana-plugin-public.md index e2ef807a75018..7531cf9a06333 100644 --- a/docs/development/core/public/kibana-plugin-public.md +++ b/docs/development/core/public/kibana-plugin-public.md @@ -91,11 +91,13 @@ The plugin integrates with the core system via lifecycle events: `setup` | [AppUnmount](./kibana-plugin-public.appunmount.md) | A function called when an application should be unmounted from the page. This function should be synchronous. | | [ChromeHelpExtension](./kibana-plugin-public.chromehelpextension.md) | | | [ChromeNavLinkUpdateableFields](./kibana-plugin-public.chromenavlinkupdateablefields.md) | | +| [HandlerContextType](./kibana-plugin-public.handlercontexttype.md) | Extracts the type of the first argument of a [HandlerFunction](./kibana-plugin-public.handlerfunction.md) to represent the type of the context. | +| [HandlerFunction](./kibana-plugin-public.handlerfunction.md) | A function that accepts a context object and an optional number of additional arguments. Used for the generic types in [IContextContainer](./kibana-plugin-public.icontextcontainer.md) | +| [HandlerParameters](./kibana-plugin-public.handlerparameters.md) | Extracts the types of the additional arguments of a [HandlerFunction](./kibana-plugin-public.handlerfunction.md), excluding the [HandlerContextType](./kibana-plugin-public.handlercontexttype.md). | | [HttpBody](./kibana-plugin-public.httpbody.md) | | | [HttpHandler](./kibana-plugin-public.httphandler.md) | | | [HttpSetup](./kibana-plugin-public.httpsetup.md) | | | [HttpStart](./kibana-plugin-public.httpstart.md) | | -| [IContextHandler](./kibana-plugin-public.icontexthandler.md) | A function registered by a plugin to perform some action. | | [IContextProvider](./kibana-plugin-public.icontextprovider.md) | A function that returns a context value for a specific key of given context type. | | [OverlayBannerMount](./kibana-plugin-public.overlaybannermount.md) | A function that will mount the banner inside the provided element. | | [OverlayBannerUnmount](./kibana-plugin-public.overlaybannerunmount.md) | A function that will unmount the banner from the element. | diff --git a/docs/development/core/server/kibana-plugin-server.basepath.get.md b/docs/development/core/server/kibana-plugin-server.basepath.get.md index 2b3b6c899e8de..04feca7ccc5a8 100644 --- a/docs/development/core/server/kibana-plugin-server.basepath.get.md +++ b/docs/development/core/server/kibana-plugin-server.basepath.get.md @@ -9,5 +9,5 @@ returns `basePath` value, specific for an incoming request. Signature: ```typescript -get: (request: KibanaRequest | LegacyRequest) => string; +get: (request: LegacyRequest | KibanaRequest) => string; ``` diff --git a/docs/development/core/server/kibana-plugin-server.basepath.md b/docs/development/core/server/kibana-plugin-server.basepath.md index 45fb697b329f8..bfa1ea02aec17 100644 --- a/docs/development/core/server/kibana-plugin-server.basepath.md +++ b/docs/development/core/server/kibana-plugin-server.basepath.md @@ -16,11 +16,11 @@ export declare class BasePath | Property | Modifiers | Type | Description | | --- | --- | --- | --- | -| [get](./kibana-plugin-server.basepath.get.md) | | (request: KibanaRequest<unknown, unknown, unknown> | LegacyRequest) => string | returns basePath value, specific for an incoming request. | +| [get](./kibana-plugin-server.basepath.get.md) | | (request: LegacyRequest | KibanaRequest<unknown, unknown, unknown>) => string | returns basePath value, specific for an incoming request. | | [prepend](./kibana-plugin-server.basepath.prepend.md) | | (path: string) => string | returns a new basePath value, prefixed with passed url. | | [remove](./kibana-plugin-server.basepath.remove.md) | | (path: string) => string | returns a new basePath value, cleaned up from passed url. | | [serverBasePath](./kibana-plugin-server.basepath.serverbasepath.md) | | string | returns the server's basePathSee [BasePath.get](./kibana-plugin-server.basepath.get.md) for getting the basePath value for a specific request | -| [set](./kibana-plugin-server.basepath.set.md) | | (request: KibanaRequest<unknown, unknown, unknown> | LegacyRequest, requestSpecificBasePath: string) => void | sets basePath value, specific for an incoming request. | +| [set](./kibana-plugin-server.basepath.set.md) | | (request: LegacyRequest | KibanaRequest<unknown, unknown, unknown>, requestSpecificBasePath: string) => void | sets basePath value, specific for an incoming request. | ## Remarks diff --git a/docs/development/core/server/kibana-plugin-server.basepath.set.md b/docs/development/core/server/kibana-plugin-server.basepath.set.md index 1272a134ef5c4..cec70ee853bfa 100644 --- a/docs/development/core/server/kibana-plugin-server.basepath.set.md +++ b/docs/development/core/server/kibana-plugin-server.basepath.set.md @@ -9,5 +9,5 @@ sets `basePath` value, specific for an incoming request. Signature: ```typescript -set: (request: KibanaRequest | LegacyRequest, requestSpecificBasePath: string) => void; +set: (request: LegacyRequest | KibanaRequest, requestSpecificBasePath: string) => void; ``` diff --git a/docs/development/core/server/kibana-plugin-server.contextsetup.createcontextcontainer.md b/docs/development/core/server/kibana-plugin-server.contextsetup.createcontextcontainer.md index f44e6a3d7640b..7096bfc43a520 100644 --- a/docs/development/core/server/kibana-plugin-server.contextsetup.createcontextcontainer.md +++ b/docs/development/core/server/kibana-plugin-server.contextsetup.createcontextcontainer.md @@ -9,9 +9,9 @@ Creates a new [IContextContainer](./kibana-plugin-server.icontextcontainer.md) f Signature: ```typescript -createContextContainer(): IContextContainer; +createContextContainer>(): IContextContainer; ``` Returns: -`IContextContainer` +`IContextContainer` diff --git a/docs/development/core/server/kibana-plugin-server.coresetup.http.md b/docs/development/core/server/kibana-plugin-server.coresetup.http.md index 254f2728abef1..8474f4ef940dc 100644 --- a/docs/development/core/server/kibana-plugin-server.coresetup.http.md +++ b/docs/development/core/server/kibana-plugin-server.coresetup.http.md @@ -14,7 +14,7 @@ http: { registerOnPostAuth: HttpServiceSetup['registerOnPostAuth']; basePath: HttpServiceSetup['basePath']; isTlsEnabled: HttpServiceSetup['isTlsEnabled']; - registerRouteHandlerContext: (name: T, provider: RequestHandlerContextProvider) => RequestHandlerContextContainer; + registerRouteHandlerContext: (name: T, provider: RequestHandlerContextProvider) => RequestHandlerContextContainer; createRouter: () => IRouter; }; ``` diff --git a/docs/development/core/server/kibana-plugin-server.coresetup.md b/docs/development/core/server/kibana-plugin-server.coresetup.md index ed487a570f286..528557e91bd17 100644 --- a/docs/development/core/server/kibana-plugin-server.coresetup.md +++ b/docs/development/core/server/kibana-plugin-server.coresetup.md @@ -18,5 +18,5 @@ export interface CoreSetup | --- | --- | --- | | [context](./kibana-plugin-server.coresetup.context.md) | {
createContextContainer: ContextSetup['createContextContainer'];
} | | | [elasticsearch](./kibana-plugin-server.coresetup.elasticsearch.md) | {
adminClient$: Observable<ClusterClient>;
dataClient$: Observable<ClusterClient>;
createClient: (type: string, clientConfig?: Partial<ElasticsearchClientConfig>) => ClusterClient;
} | | -| [http](./kibana-plugin-server.coresetup.http.md) | {
createCookieSessionStorageFactory: HttpServiceSetup['createCookieSessionStorageFactory'];
registerOnPreAuth: HttpServiceSetup['registerOnPreAuth'];
registerAuth: HttpServiceSetup['registerAuth'];
registerOnPostAuth: HttpServiceSetup['registerOnPostAuth'];
basePath: HttpServiceSetup['basePath'];
isTlsEnabled: HttpServiceSetup['isTlsEnabled'];
registerRouteHandlerContext: <T extends keyof RequestHandlerContext>(name: T, provider: RequestHandlerContextProvider<RequestHandlerContext>) => RequestHandlerContextContainer<RequestHandlerContext>;
createRouter: () => IRouter;
} | | +| [http](./kibana-plugin-server.coresetup.http.md) | {
createCookieSessionStorageFactory: HttpServiceSetup['createCookieSessionStorageFactory'];
registerOnPreAuth: HttpServiceSetup['registerOnPreAuth'];
registerAuth: HttpServiceSetup['registerAuth'];
registerOnPostAuth: HttpServiceSetup['registerOnPostAuth'];
basePath: HttpServiceSetup['basePath'];
isTlsEnabled: HttpServiceSetup['isTlsEnabled'];
registerRouteHandlerContext: <T extends keyof RequestHandlerContext>(name: T, provider: RequestHandlerContextProvider<T>) => RequestHandlerContextContainer;
createRouter: () => IRouter;
} | | diff --git a/docs/development/core/server/kibana-plugin-server.handlercontexttype.md b/docs/development/core/server/kibana-plugin-server.handlercontexttype.md new file mode 100644 index 0000000000000..e8f1f346e8b8e --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.handlercontexttype.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [HandlerContextType](./kibana-plugin-server.handlercontexttype.md) + +## HandlerContextType type + +Extracts the type of the first argument of a [HandlerFunction](./kibana-plugin-server.handlerfunction.md) to represent the type of the context. + +Signature: + +```typescript +export declare type HandlerContextType> = T extends HandlerFunction ? U : never; +``` diff --git a/docs/development/core/server/kibana-plugin-server.handlerfunction.md b/docs/development/core/server/kibana-plugin-server.handlerfunction.md new file mode 100644 index 0000000000000..97acd37946fc9 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.handlerfunction.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [HandlerFunction](./kibana-plugin-server.handlerfunction.md) + +## HandlerFunction type + +A function that accepts a context object and an optional number of additional arguments. Used for the generic types in [IContextContainer](./kibana-plugin-server.icontextcontainer.md) + +Signature: + +```typescript +export declare type HandlerFunction = (context: T, ...args: any[]) => any; +``` diff --git a/docs/development/core/server/kibana-plugin-server.handlerparameters.md b/docs/development/core/server/kibana-plugin-server.handlerparameters.md new file mode 100644 index 0000000000000..3dd7998a71a1f --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.handlerparameters.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [HandlerParameters](./kibana-plugin-server.handlerparameters.md) + +## HandlerParameters type + +Extracts the types of the additional arguments of a [HandlerFunction](./kibana-plugin-server.handlerfunction.md), excluding the [HandlerContextType](./kibana-plugin-server.handlercontexttype.md). + +Signature: + +```typescript +export declare type HandlerParameters> = T extends (context: any, ...args: infer U) => any ? U : never; +``` diff --git a/docs/development/core/server/kibana-plugin-server.httpservicesetup.md b/docs/development/core/server/kibana-plugin-server.httpservicesetup.md index 92bf158ad3312..eec63cf5c8093 100644 --- a/docs/development/core/server/kibana-plugin-server.httpservicesetup.md +++ b/docs/development/core/server/kibana-plugin-server.httpservicesetup.md @@ -10,6 +10,6 @@ ```typescript export declare type HttpServiceSetup = Omit & { createRouter: (path: string, plugin?: PluginOpaqueId) => IRouter; - registerRouteHandlerContext: (pluginOpaqueId: PluginOpaqueId, contextName: T, provider: RequestHandlerContextProvider) => RequestHandlerContextContainer; + registerRouteHandlerContext: (pluginOpaqueId: PluginOpaqueId, contextName: T, provider: RequestHandlerContextProvider) => RequestHandlerContextContainer; }; ``` diff --git a/docs/development/core/server/kibana-plugin-server.icontextcontainer.createhandler.md b/docs/development/core/server/kibana-plugin-server.icontextcontainer.createhandler.md index c5549ab017e53..09a9e28d6d0fe 100644 --- a/docs/development/core/server/kibana-plugin-server.icontextcontainer.createhandler.md +++ b/docs/development/core/server/kibana-plugin-server.icontextcontainer.createhandler.md @@ -9,7 +9,7 @@ Create a new handler function pre-wired to context for the plugin. Signature: ```typescript -createHandler(pluginOpaqueId: PluginOpaqueId, handler: IContextHandler): (...rest: THandlerParameters) => THandlerReturn extends Promise ? THandlerReturn : Promise; +createHandler(pluginOpaqueId: PluginOpaqueId, handler: THandler): (...rest: HandlerParameters) => ShallowPromise>; ``` ## Parameters @@ -17,11 +17,11 @@ createHandler(pluginOpaqueId: PluginOpaqueId, handler: IContextHandlerPluginOpaqueId | The plugin opaque ID for the plugin that registers this handler. | -| handler | IContextHandler<TContext, THandlerReturn, THandlerParameters> | Handler function to pass context object to. | +| handler | THandler | Handler function to pass context object to. | Returns: -`(...rest: THandlerParameters) => THandlerReturn extends Promise ? THandlerReturn : Promise` +`(...rest: HandlerParameters) => ShallowPromise>` A function that takes `THandlerParameters`, calls `handler` with a new context, and returns a Promise of the `handler` return value. diff --git a/docs/development/core/server/kibana-plugin-server.icontextcontainer.md b/docs/development/core/server/kibana-plugin-server.icontextcontainer.md index 1ab699be105b4..114da31442ff9 100644 --- a/docs/development/core/server/kibana-plugin-server.icontextcontainer.md +++ b/docs/development/core/server/kibana-plugin-server.icontextcontainer.md @@ -9,7 +9,7 @@ An object that handles registration of context providers and configuring handler Signature: ```typescript -export interface IContextContainer +export interface IContextContainer> ``` ## Methods diff --git a/docs/development/core/server/kibana-plugin-server.icontextcontainer.registercontext.md b/docs/development/core/server/kibana-plugin-server.icontextcontainer.registercontext.md index 1a63f63dc91b4..30d3fc154d1e9 100644 --- a/docs/development/core/server/kibana-plugin-server.icontextcontainer.registercontext.md +++ b/docs/development/core/server/kibana-plugin-server.icontextcontainer.registercontext.md @@ -9,7 +9,7 @@ Register a new context provider. Signature: ```typescript -registerContext(pluginOpaqueId: PluginOpaqueId, contextName: TContextName, provider: IContextProvider): this; +registerContext>(pluginOpaqueId: PluginOpaqueId, contextName: TContextName, provider: IContextProvider): this; ``` ## Parameters @@ -18,7 +18,7 @@ registerContext(pluginOpaqueId: PluginOpaqu | --- | --- | --- | | pluginOpaqueId | PluginOpaqueId | The plugin opaque ID for the plugin that registers this context. | | contextName | TContextName | The key of the TContext object this provider supplies the value for. | -| provider | IContextProvider<TContext, TContextName, THandlerParameters> | A [IContextProvider](./kibana-plugin-server.icontextprovider.md) to be called each time a new context is created. | +| provider | IContextProvider<THandler, TContextName> | A [IContextProvider](./kibana-plugin-server.icontextprovider.md) to be called each time a new context is created. | Returns: diff --git a/docs/development/core/server/kibana-plugin-server.icontexthandler.md b/docs/development/core/server/kibana-plugin-server.icontexthandler.md deleted file mode 100644 index c1f5acc22734a..0000000000000 --- a/docs/development/core/server/kibana-plugin-server.icontexthandler.md +++ /dev/null @@ -1,18 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [IContextHandler](./kibana-plugin-server.icontexthandler.md) - -## IContextHandler type - -A function registered by a plugin to perform some action. - -Signature: - -```typescript -export declare type IContextHandler = (context: TContext, ...rest: THandlerParameters) => TReturn; -``` - -## Remarks - -A new `TContext` will be built for each handler before invoking. - diff --git a/docs/development/core/server/kibana-plugin-server.icontextprovider.md b/docs/development/core/server/kibana-plugin-server.icontextprovider.md index 250e6a2be3f6a..39ace8b9bc57e 100644 --- a/docs/development/core/server/kibana-plugin-server.icontextprovider.md +++ b/docs/development/core/server/kibana-plugin-server.icontextprovider.md @@ -9,7 +9,7 @@ A function that returns a context value for a specific key of given context type Signature: ```typescript -export declare type IContextProvider, TContextName extends keyof TContext, TProviderParameters extends any[] = []> = (context: Partial, ...rest: TProviderParameters) => Promise | TContext[TContextName]; +export declare type IContextProvider, TContextName extends keyof HandlerContextType> = (context: Partial>, ...rest: HandlerParameters) => Promise[TContextName]> | HandlerContextType[TContextName]; ``` ## Remarks diff --git a/docs/development/core/server/kibana-plugin-server.md b/docs/development/core/server/kibana-plugin-server.md index d943228bbea06..3c01e7aeef325 100644 --- a/docs/development/core/server/kibana-plugin-server.md +++ b/docs/development/core/server/kibana-plugin-server.md @@ -116,11 +116,13 @@ The plugin integrates with the core system via lifecycle events: `setup` | [ElasticsearchClientConfig](./kibana-plugin-server.elasticsearchclientconfig.md) | | | [GetAuthHeaders](./kibana-plugin-server.getauthheaders.md) | Get headers to authenticate a user against Elasticsearch. | | [GetAuthState](./kibana-plugin-server.getauthstate.md) | Get authentication state for a request. Returned by auth interceptor. | +| [HandlerContextType](./kibana-plugin-server.handlercontexttype.md) | Extracts the type of the first argument of a [HandlerFunction](./kibana-plugin-server.handlerfunction.md) to represent the type of the context. | +| [HandlerFunction](./kibana-plugin-server.handlerfunction.md) | A function that accepts a context object and an optional number of additional arguments. Used for the generic types in [IContextContainer](./kibana-plugin-server.icontextcontainer.md) | +| [HandlerParameters](./kibana-plugin-server.handlerparameters.md) | Extracts the types of the additional arguments of a [HandlerFunction](./kibana-plugin-server.handlerfunction.md), excluding the [HandlerContextType](./kibana-plugin-server.handlercontexttype.md). | | [Headers](./kibana-plugin-server.headers.md) | Http request headers to read. | | [HttpResponsePayload](./kibana-plugin-server.httpresponsepayload.md) | Data send to the client as a response payload. | | [HttpServiceSetup](./kibana-plugin-server.httpservicesetup.md) | | | [IBasePath](./kibana-plugin-server.ibasepath.md) | Access or manipulate the Kibana base path[BasePath](./kibana-plugin-server.basepath.md) | -| [IContextHandler](./kibana-plugin-server.icontexthandler.md) | A function registered by a plugin to perform some action. | | [IContextProvider](./kibana-plugin-server.icontextprovider.md) | A function that returns a context value for a specific key of given context type. | | [IsAuthenticated](./kibana-plugin-server.isauthenticated.md) | Return authentication status for a request. | | [KibanaResponseFactory](./kibana-plugin-server.kibanaresponsefactory.md) | Creates an object containing request response payload, HTTP headers, error details, and other data transmitted to the client. | @@ -136,8 +138,6 @@ The plugin integrates with the core system via lifecycle events: `setup` | [RequestHandler](./kibana-plugin-server.requesthandler.md) | A function executed when route path matched requested resource path. Request handler is expected to return a result of one of [KibanaResponseFactory](./kibana-plugin-server.kibanaresponsefactory.md) functions. | | [RequestHandlerContextContainer](./kibana-plugin-server.requesthandlercontextcontainer.md) | An object that handles registration of http request context providers. | | [RequestHandlerContextProvider](./kibana-plugin-server.requesthandlercontextprovider.md) | Context provider for request handler. Extends request context object with provided functionality or data. | -| [RequestHandlerParams](./kibana-plugin-server.requesthandlerparams.md) | Parameters passed to the request handler function. | -| [RequestHandlerReturn](./kibana-plugin-server.requesthandlerreturn.md) | Expected outcome the request handler function. | | [ResponseError](./kibana-plugin-server.responseerror.md) | Error message and optional data send to the client in case of error. | | [ResponseErrorAttributes](./kibana-plugin-server.responseerrorattributes.md) | Additional data to provide error details. | | [ResponseHeaders](./kibana-plugin-server.responseheaders.md) | Http response headers to set. | diff --git a/docs/development/core/server/kibana-plugin-server.requesthandlercontextcontainer.md b/docs/development/core/server/kibana-plugin-server.requesthandlercontextcontainer.md index afdb488597069..b76a9ce7d235c 100644 --- a/docs/development/core/server/kibana-plugin-server.requesthandlercontextcontainer.md +++ b/docs/development/core/server/kibana-plugin-server.requesthandlercontextcontainer.md @@ -9,5 +9,5 @@ An object that handles registration of http request context providers. Signature: ```typescript -export declare type RequestHandlerContextContainer = IContextContainer, RequestHandlerParams>; +export declare type RequestHandlerContextContainer = IContextContainer>; ``` diff --git a/docs/development/core/server/kibana-plugin-server.requesthandlercontextprovider.md b/docs/development/core/server/kibana-plugin-server.requesthandlercontextprovider.md index 0d9cc6b70b80c..ea7294b721aab 100644 --- a/docs/development/core/server/kibana-plugin-server.requesthandlercontextprovider.md +++ b/docs/development/core/server/kibana-plugin-server.requesthandlercontextprovider.md @@ -9,5 +9,5 @@ Context provider for request handler. Extends request context object with provid Signature: ```typescript -export declare type RequestHandlerContextProvider = IContextProvider; +export declare type RequestHandlerContextProvider = IContextProvider, TContextName>; ``` diff --git a/docs/development/core/server/kibana-plugin-server.requesthandlerparams.md b/docs/development/core/server/kibana-plugin-server.requesthandlerparams.md deleted file mode 100644 index 7f466845b4d46..0000000000000 --- a/docs/development/core/server/kibana-plugin-server.requesthandlerparams.md +++ /dev/null @@ -1,13 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [RequestHandlerParams](./kibana-plugin-server.requesthandlerparams.md) - -## RequestHandlerParams type - -Parameters passed to the request handler function. - -Signature: - -```typescript -export declare type RequestHandlerParams = [KibanaRequest, KibanaResponseFactory]; -``` diff --git a/docs/development/core/server/kibana-plugin-server.requesthandlerreturn.md b/docs/development/core/server/kibana-plugin-server.requesthandlerreturn.md deleted file mode 100644 index 6c01e21b6ecbe..0000000000000 --- a/docs/development/core/server/kibana-plugin-server.requesthandlerreturn.md +++ /dev/null @@ -1,13 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [RequestHandlerReturn](./kibana-plugin-server.requesthandlerreturn.md) - -## RequestHandlerReturn type - -Expected outcome the request handler function. - -Signature: - -```typescript -export declare type RequestHandlerReturn = KibanaResponse; -``` diff --git a/src/core/public/application/application_service.tsx b/src/core/public/application/application_service.tsx index d1855a0370f00..935844baddf86 100644 --- a/src/core/public/application/application_service.tsx +++ b/src/core/public/application/application_service.tsx @@ -27,12 +27,9 @@ import { AppRouter } from './ui'; import { HttpStart } from '../http'; import { ContextSetup, IContextContainer } from '../context'; import { - AppMountContext, App, LegacyApp, AppMounter, - AppUnmount, - AppMountParameters, InternalApplicationSetup, InternalApplicationStart, } from './types'; @@ -64,11 +61,7 @@ export class ApplicationService { private readonly apps$ = new BehaviorSubject>(new Map()); private readonly legacyApps$ = new BehaviorSubject>(new Map()); private readonly capabilities = new CapabilitiesService(); - private mountContext?: IContextContainer< - AppMountContext, - AppUnmount | Promise, - [AppMountParameters] - >; + private mountContext?: IContextContainer; public setup({ context }: SetupDeps): InternalApplicationSetup { this.mountContext = context.createContextContainer(); @@ -98,7 +91,7 @@ export class ApplicationService { this.legacyApps$.next(new Map([...this.legacyApps$.value.entries(), [app.id, app]])); }, - registerMountContext: this.mountContext.registerContext, + registerMountContext: this.mountContext!.registerContext, }; } diff --git a/src/core/public/application/types.ts b/src/core/public/application/types.ts index 018d7569ce411..b2d0aff26b8b0 100644 --- a/src/core/public/application/types.ts +++ b/src/core/public/application/types.ts @@ -193,7 +193,7 @@ export interface ApplicationSetup { */ registerMountContext( contextName: T, - provider: IContextProvider + provider: IContextProvider ): void; } @@ -224,7 +224,7 @@ export interface InternalApplicationSetup { registerMountContext( pluginOpaqueId: PluginOpaqueId, contextName: T, - provider: IContextProvider + provider: IContextProvider ): void; } @@ -261,7 +261,7 @@ export interface ApplicationStart { */ registerMountContext( contextName: T, - provider: IContextProvider + provider: IContextProvider ): void; } @@ -291,7 +291,7 @@ export interface InternalApplicationStart registerMountContext( pluginOpaqueId: PluginOpaqueId, contextName: T, - provider: IContextProvider + provider: IContextProvider ): void; // Internal APIs diff --git a/src/core/public/context/context_service.ts b/src/core/public/context/context_service.ts index 704524d838636..dadc509c97821 100644 --- a/src/core/public/context/context_service.ts +++ b/src/core/public/context/context_service.ts @@ -18,7 +18,7 @@ */ import { PluginOpaqueId } from '../../server'; -import { IContextContainer, ContextContainer } from '../../utils/context'; +import { IContextContainer, ContextContainer, HandlerFunction } from '../../utils/context'; import { CoreContext } from '../core_system'; interface StartDeps { @@ -31,15 +31,8 @@ export class ContextService { public setup({ pluginDependencies }: StartDeps): ContextSetup { return { - createContextContainer: < - TContext extends {}, - THandlerReturn, - THandlerParameters extends any[] = [] - >() => - new ContextContainer( - pluginDependencies, - this.core.coreId - ), + createContextContainer: >() => + new ContextContainer(pluginDependencies, this.core.coreId), }; } } @@ -111,9 +104,5 @@ export interface ContextSetup { /** * Creates a new {@link IContextContainer} for a service owner. */ - createContextContainer< - TContext extends {}, - THandlerReturn, - THandlerParmaters extends any[] = [] - >(): IContextContainer; + createContextContainer>(): IContextContainer; } diff --git a/src/core/public/context/index.ts b/src/core/public/context/index.ts index 28b2641b2a5a7..f22c4168d7544 100644 --- a/src/core/public/context/index.ts +++ b/src/core/public/context/index.ts @@ -18,4 +18,10 @@ */ export { ContextService, ContextSetup } from './context_service'; -export { IContextContainer, IContextProvider, IContextHandler } from '../../utils/context'; +export { + IContextContainer, + IContextProvider, + HandlerFunction, + HandlerContextType, + HandlerParameters, +} from '../../utils/context'; diff --git a/src/core/public/index.ts b/src/core/public/index.ts index d0316604a0d37..82b87a69b57d7 100644 --- a/src/core/public/index.ts +++ b/src/core/public/index.ts @@ -67,7 +67,14 @@ import { UiSettingsClient, UiSettingsState, UiSettingsClientContract } from './u import { ApplicationSetup, Capabilities, ApplicationStart } from './application'; import { DocLinksStart } from './doc_links'; import { SavedObjectsStart } from './saved_objects'; -import { IContextContainer, IContextProvider, ContextSetup, IContextHandler } from './context'; +import { + IContextContainer, + IContextProvider, + ContextSetup, + HandlerFunction, + HandlerContextType, + HandlerParameters, +} from './context'; /** @interal */ export { CoreContext, CoreSystem } from './core_system'; @@ -218,7 +225,9 @@ export { ChromeRecentlyAccessedHistoryItem, ChromeStart, IContextContainer, - IContextHandler, + HandlerFunction, + HandlerContextType, + HandlerParameters, IContextProvider, ContextSetup, DocLinksStart, diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index 102e77b564a6d..e6c8f116e5782 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -9,6 +9,7 @@ import { MouseEventHandler } from 'react'; import { Observable } from 'rxjs'; import React from 'react'; import * as Rx from 'rxjs'; +import { ShallowPromise } from '@kbn/utility-types'; import { EuiGlobalToastListToast as Toast } from '@elastic/eui'; // @public @@ -31,7 +32,7 @@ export interface AppBase { // @public (undocumented) export interface ApplicationSetup { register(app: App): void; - registerMountContext(contextName: T, provider: IContextProvider): void; + registerMountContext(contextName: T, provider: IContextProvider): void; } // @public (undocumented) @@ -44,7 +45,7 @@ export interface ApplicationStart { path?: string; state?: any; }): void; - registerMountContext(contextName: T, provider: IContextProvider): void; + registerMountContext(contextName: T, provider: IContextProvider): void; } // @public @@ -213,7 +214,7 @@ export interface ChromeStart { // @public export interface ContextSetup { - createContextContainer(): IContextContainer; + createContextContainer>(): IContextContainer; } // @internal (undocumented) @@ -389,6 +390,15 @@ export interface FatalErrorsSetup { get$: () => Rx.Observable; } +// @public +export type HandlerContextType> = T extends HandlerFunction ? U : never; + +// @public +export type HandlerFunction = (context: T, ...args: any[]) => any; + +// @public +export type HandlerParameters> = T extends (context: any, ...args: infer U) => any ? U : never; + // @public (undocumented) export type HttpBody = BodyInit | null | any; @@ -551,16 +561,13 @@ export interface I18nStart { } // @public -export interface IContextContainer { - createHandler(pluginOpaqueId: PluginOpaqueId, handler: IContextHandler): (...rest: THandlerParameters) => THandlerReturn extends Promise ? THandlerReturn : Promise; - registerContext(pluginOpaqueId: PluginOpaqueId, contextName: TContextName, provider: IContextProvider): this; +export interface IContextContainer> { + createHandler(pluginOpaqueId: PluginOpaqueId, handler: THandler): (...rest: HandlerParameters) => ShallowPromise>; + registerContext>(pluginOpaqueId: PluginOpaqueId, contextName: TContextName, provider: IContextProvider): this; } // @public -export type IContextHandler = (context: TContext, ...rest: THandlerParameters) => TReturn; - -// @public -export type IContextProvider, TContextName extends keyof TContext, TProviderParameters extends any[] = []> = (context: Partial, ...rest: TProviderParameters) => Promise | TContext[TContextName]; +export type IContextProvider, TContextName extends keyof HandlerContextType> = (context: Partial>, ...rest: HandlerParameters) => Promise[TContextName]> | HandlerContextType[TContextName]; // @public @deprecated export interface LegacyCoreSetup extends CoreSetup { diff --git a/src/core/server/context/context_service.ts b/src/core/server/context/context_service.ts index 80935840c5536..1c5bd41a01f0f 100644 --- a/src/core/server/context/context_service.ts +++ b/src/core/server/context/context_service.ts @@ -18,7 +18,7 @@ */ import { PluginOpaqueId } from '../../server'; -import { IContextContainer, ContextContainer } from '../../utils/context'; +import { IContextContainer, ContextContainer, HandlerFunction } from '../../utils/context'; import { CoreContext } from '../core_context'; interface SetupDeps { @@ -31,15 +31,8 @@ export class ContextService { public setup({ pluginDependencies }: SetupDeps): ContextSetup { return { - createContextContainer: < - TContext extends {}, - THandlerReturn, - THandlerParameters extends any[] = [] - >() => { - return new ContextContainer( - pluginDependencies, - this.core.coreId - ); + createContextContainer: >() => { + return new ContextContainer(pluginDependencies, this.core.coreId); }, }; } @@ -112,9 +105,5 @@ export interface ContextSetup { /** * Creates a new {@link IContextContainer} for a service owner. */ - createContextContainer< - TContext extends {}, - THandlerReturn, - THandlerParmaters extends any[] = [] - >(): IContextContainer; + createContextContainer>(): IContextContainer; } diff --git a/src/core/server/context/index.ts b/src/core/server/context/index.ts index 28b2641b2a5a7..f22c4168d7544 100644 --- a/src/core/server/context/index.ts +++ b/src/core/server/context/index.ts @@ -18,4 +18,10 @@ */ export { ContextService, ContextSetup } from './context_service'; -export { IContextContainer, IContextProvider, IContextHandler } from '../../utils/context'; +export { + IContextContainer, + IContextProvider, + HandlerFunction, + HandlerContextType, + HandlerParameters, +} from '../../utils/context'; diff --git a/src/core/server/http/http_service.ts b/src/core/server/http/http_service.ts index 5814991a2dd27..0ac5ad9276353 100644 --- a/src/core/server/http/http_service.ts +++ b/src/core/server/http/http_service.ts @@ -83,8 +83,8 @@ export type HttpServiceSetup = Omit & { registerRouteHandlerContext: ( pluginOpaqueId: PluginOpaqueId, contextName: T, - provider: RequestHandlerContextProvider - ) => RequestHandlerContextContainer; + provider: RequestHandlerContextProvider + ) => RequestHandlerContextContainer; }; /** @public */ @@ -103,7 +103,7 @@ export class HttpService implements CoreService; + private requestHandlerContext?: RequestHandlerContextContainer; constructor(private readonly coreContext: CoreContext) { this.logger = coreContext.logger; @@ -150,7 +150,7 @@ export class HttpService implements CoreService( pluginOpaqueId: PluginOpaqueId, contextName: T, - provider: RequestHandlerContextProvider + provider: RequestHandlerContextProvider ) => this.requestHandlerContext!.registerContext(pluginOpaqueId, contextName, provider), }; diff --git a/src/core/server/http/types.ts b/src/core/server/http/types.ts index a391b2e2e5d45..cade4ea4d4f2c 100644 --- a/src/core/server/http/types.ts +++ b/src/core/server/http/types.ts @@ -16,30 +16,16 @@ * specific language governing permissions and limitations * under the License. */ -import { IContextProvider, IContextContainer } from '../context'; -import { KibanaRequest, KibanaResponseFactory, KibanaResponse } from './router'; - -/** - * Parameters passed to the request handler function. - * @public - */ -export type RequestHandlerParams = [KibanaRequest, KibanaResponseFactory]; -/** - * Expected outcome the request handler function. - * @public - */ -export type RequestHandlerReturn = KibanaResponse; +import { IContextProvider, IContextContainer } from '../context'; +import { RequestHandler } from './router'; +import { RequestHandlerContext } from '..'; /** * An object that handles registration of http request context providers. * @public */ -export type RequestHandlerContextContainer = IContextContainer< - TContext, - RequestHandlerReturn | Promise, - RequestHandlerParams ->; +export type RequestHandlerContextContainer = IContextContainer>; /** * Context provider for request handler. @@ -47,8 +33,6 @@ export type RequestHandlerContextContainer = IContextContainer< * * @public */ -export type RequestHandlerContextProvider = IContextProvider< - TContext, - keyof TContext, - RequestHandlerParams ->; +export type RequestHandlerContextProvider< + TContextName extends keyof RequestHandlerContext +> = IContextProvider, TContextName>; diff --git a/src/core/server/index.ts b/src/core/server/index.ts index d3fe64ddc1e0d..ca497e0f2d32d 100644 --- a/src/core/server/index.ts +++ b/src/core/server/index.ts @@ -59,7 +59,13 @@ import { SavedObjectsServiceStart } from './saved_objects'; export { bootstrap } from './bootstrap'; export { ConfigPath, ConfigService } from './config'; -export { IContextContainer, IContextProvider, IContextHandler } from './context'; +export { + IContextContainer, + IContextProvider, + HandlerFunction, + HandlerContextType, + HandlerParameters, +} from './context'; export { CoreId } from './core_context'; export { CallAPIOptions, @@ -102,8 +108,6 @@ export { RequestHandler, RequestHandlerContextContainer, RequestHandlerContextProvider, - RequestHandlerParams, - RequestHandlerReturn, ResponseError, ResponseErrorAttributes, ResponseHeaders, @@ -212,8 +216,8 @@ export interface CoreSetup { isTlsEnabled: HttpServiceSetup['isTlsEnabled']; registerRouteHandlerContext: ( name: T, - provider: RequestHandlerContextProvider - ) => RequestHandlerContextContainer; + provider: RequestHandlerContextProvider + ) => RequestHandlerContextContainer; createRouter: () => IRouter; }; } diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index ae839644fc2e2..6451e2b9b7153 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -21,6 +21,7 @@ import { Request } from 'hapi'; import { ResponseObject } from 'hapi'; import { ResponseToolkit } from 'hapi'; import { Server } from 'hapi'; +import { ShallowPromise } from '@kbn/utility-types'; import { Stream } from 'stream'; import { Type } from '@kbn/config-schema'; import { TypeOf } from '@kbn/config-schema'; @@ -61,11 +62,11 @@ export interface AuthToolkit { export class BasePath { // @internal constructor(serverBasePath?: string); - get: (request: KibanaRequest | LegacyRequest) => string; + get: (request: LegacyRequest | KibanaRequest) => string; prepend: (path: string) => string; remove: (path: string) => string; readonly serverBasePath: string; - set: (request: KibanaRequest | LegacyRequest, requestSpecificBasePath: string) => void; + set: (request: LegacyRequest | KibanaRequest, requestSpecificBasePath: string) => void; } // Warning: (ae-forgotten-export) The symbol "BootstrapArgs" needs to be exported by the entry point index.d.ts @@ -109,7 +110,7 @@ export class ConfigService { // @public export interface ContextSetup { - createContextContainer(): IContextContainer; + createContextContainer>(): IContextContainer; } // @internal (undocumented) @@ -135,7 +136,7 @@ export interface CoreSetup { registerOnPostAuth: HttpServiceSetup['registerOnPostAuth']; basePath: HttpServiceSetup['basePath']; isTlsEnabled: HttpServiceSetup['isTlsEnabled']; - registerRouteHandlerContext: (name: T, provider: RequestHandlerContextProvider) => RequestHandlerContextContainer; + registerRouteHandlerContext: (name: T, provider: RequestHandlerContextProvider) => RequestHandlerContextContainer; createRouter: () => IRouter; }; } @@ -219,6 +220,15 @@ export type GetAuthState = (request: KibanaRequest | LegacyRequest) => { state: unknown; }; +// @public +export type HandlerContextType> = T extends HandlerFunction ? U : never; + +// @public +export type HandlerFunction = (context: T, ...args: any[]) => any; + +// @public +export type HandlerParameters> = T extends (context: any, ...args: infer U) => any ? U : never; + // @public export type Headers = { [header in KnownHeaders]?: string | string[] | undefined; @@ -258,7 +268,7 @@ export interface HttpServerSetup { // @public (undocumented) export type HttpServiceSetup = Omit & { createRouter: (path: string, plugin?: PluginOpaqueId) => IRouter; - registerRouteHandlerContext: (pluginOpaqueId: PluginOpaqueId, contextName: T, provider: RequestHandlerContextProvider) => RequestHandlerContextContainer; + registerRouteHandlerContext: (pluginOpaqueId: PluginOpaqueId, contextName: T, provider: RequestHandlerContextProvider) => RequestHandlerContextContainer; }; // @public (undocumented) @@ -270,16 +280,13 @@ export interface HttpServiceStart { export type IBasePath = Pick; // @public -export interface IContextContainer { - createHandler(pluginOpaqueId: PluginOpaqueId, handler: IContextHandler): (...rest: THandlerParameters) => THandlerReturn extends Promise ? THandlerReturn : Promise; - registerContext(pluginOpaqueId: PluginOpaqueId, contextName: TContextName, provider: IContextProvider): this; +export interface IContextContainer> { + createHandler(pluginOpaqueId: PluginOpaqueId, handler: THandler): (...rest: HandlerParameters) => ShallowPromise>; + registerContext>(pluginOpaqueId: PluginOpaqueId, contextName: TContextName, provider: IContextProvider): this; } // @public -export type IContextHandler = (context: TContext, ...rest: THandlerParameters) => TReturn; - -// @public -export type IContextProvider, TContextName extends keyof TContext, TProviderParameters extends any[] = []> = (context: Partial, ...rest: TProviderParameters) => Promise | TContext[TContextName]; +export type IContextProvider, TContextName extends keyof HandlerContextType> = (context: Partial>, ...rest: HandlerParameters) => Promise[TContextName]> | HandlerContextType[TContextName]; // @public export interface IKibanaSocket { @@ -602,16 +609,10 @@ export interface RequestHandlerContext { } // @public -export type RequestHandlerContextContainer = IContextContainer, RequestHandlerParams>; - -// @public -export type RequestHandlerContextProvider = IContextProvider; - -// @public -export type RequestHandlerParams = [KibanaRequest, KibanaResponseFactory]; +export type RequestHandlerContextContainer = IContextContainer>; // @public -export type RequestHandlerReturn = KibanaResponse; +export type RequestHandlerContextProvider = IContextProvider, TContextName>; // @public export type ResponseError = string | Error | { diff --git a/src/core/utils/context.mock.ts b/src/core/utils/context.mock.ts index 4d91c11542b2f..de844f3f0f07d 100644 --- a/src/core/utils/context.mock.ts +++ b/src/core/utils/context.mock.ts @@ -19,7 +19,7 @@ import { IContextContainer } from './context'; -export type ContextContainerMock = jest.Mocked>; +export type ContextContainerMock = jest.Mocked>; const createContextMock = () => { const contextMock: ContextContainerMock = { diff --git a/src/core/utils/context.test.ts b/src/core/utils/context.test.ts index 1249c14736fb5..4bfeddc2e08c9 100644 --- a/src/core/utils/context.test.ts +++ b/src/core/utils/context.test.ts @@ -44,7 +44,7 @@ const coreId = Symbol(); describe('ContextContainer', () => { it('does not allow the same context to be registered twice', () => { - const contextContainer = new ContextContainer(plugins, coreId); + const contextContainer = new ContextContainer<(context: MyContext) => string>(plugins, coreId); contextContainer.registerContext(coreId, 'ctxFromA', () => 'aString'); expect(() => @@ -56,7 +56,10 @@ describe('ContextContainer', () => { describe('registerContext', () => { it('throws error if called with an unknown symbol', async () => { - const contextContainer = new ContextContainer(plugins, coreId); + const contextContainer = new ContextContainer<(context: MyContext) => string>( + plugins, + coreId + ); await expect(() => contextContainer.registerContext(Symbol('unknown'), 'ctxFromA', jest.fn()) ).toThrowErrorMatchingInlineSnapshot( @@ -67,7 +70,10 @@ describe('ContextContainer', () => { describe('context building', () => { it('resolves dependencies', async () => { - const contextContainer = new ContextContainer(plugins, coreId); + const contextContainer = new ContextContainer<(context: MyContext) => string>( + plugins, + coreId + ); expect.assertions(8); contextContainer.registerContext(coreId, 'core1', context => { expect(context).toEqual({}); @@ -118,7 +124,10 @@ describe('ContextContainer', () => { it('exposes all core context to all providers regardless of registration order', async () => { expect.assertions(4); - const contextContainer = new ContextContainer(plugins, coreId); + const contextContainer = new ContextContainer<(context: MyContext) => string>( + plugins, + coreId + ); contextContainer .registerContext(pluginA, 'ctxFromA', context => { expect(context).toEqual({ core1: 'core', core2: 101 }); @@ -146,7 +155,10 @@ describe('ContextContainer', () => { it('exposes all core context to core providers', async () => { expect.assertions(4); - const contextContainer = new ContextContainer(plugins, coreId); + const contextContainer = new ContextContainer<(context: MyContext) => string>( + plugins, + coreId + ); contextContainer .registerContext(coreId, 'core1', context => { @@ -171,7 +183,10 @@ describe('ContextContainer', () => { }); it('does not expose plugin contexts to core handler', async () => { - const contextContainer = new ContextContainer(plugins, coreId); + const contextContainer = new ContextContainer<(context: MyContext) => string>( + plugins, + coreId + ); contextContainer .registerContext(coreId, 'core1', context => 'core') @@ -189,10 +204,9 @@ describe('ContextContainer', () => { it('passes additional arguments to providers', async () => { expect.assertions(6); - const contextContainer = new ContextContainer( - plugins, - coreId - ); + const contextContainer = new ContextContainer< + (context: MyContext, arg1: string, arg2: number) => string + >(plugins, coreId); contextContainer.registerContext(coreId, 'core1', (context, str, num) => { expect(str).toEqual('passed string'); @@ -228,7 +242,10 @@ describe('ContextContainer', () => { describe('createHandler', () => { it('throws error if called with an unknown symbol', async () => { - const contextContainer = new ContextContainer(plugins, coreId); + const contextContainer = new ContextContainer<(context: MyContext) => string>( + plugins, + coreId + ); await expect(() => contextContainer.createHandler(Symbol('unknown'), jest.fn()) ).toThrowErrorMatchingInlineSnapshot( @@ -237,8 +254,10 @@ describe('ContextContainer', () => { }); it('returns value from original handler', async () => { - const contextContainer = new ContextContainer(plugins, coreId); - + const contextContainer = new ContextContainer<(context: MyContext) => string>( + plugins, + coreId + ); const rawHandler1 = jest.fn(() => 'handler1'); const handler1 = contextContainer.createHandler(pluginA, rawHandler1); @@ -246,10 +265,9 @@ describe('ContextContainer', () => { }); it('passes additional arguments to handlers', async () => { - const contextContainer = new ContextContainer( - plugins, - coreId - ); + const contextContainer = new ContextContainer< + (context: MyContext, arg1: string, arg2: number) => string + >(plugins, coreId); const rawHandler1 = jest.fn(() => 'handler1'); const handler1 = contextContainer.createHandler(pluginA, rawHandler1); diff --git a/src/core/utils/context.ts b/src/core/utils/context.ts index 6d1732ea06b0e..022c3e4330032 100644 --- a/src/core/utils/context.ts +++ b/src/core/utils/context.ts @@ -18,6 +18,7 @@ */ import { flatten } from 'lodash'; +import { ShallowPromise } from '@kbn/utility-types'; import { pick } from '.'; import { CoreId, PluginOpaqueId } from '../server'; @@ -35,26 +36,44 @@ import { CoreId, PluginOpaqueId } from '../server'; * @public */ export type IContextProvider< - TContext extends Record, - TContextName extends keyof TContext, - TProviderParameters extends any[] = [] + THandler extends HandlerFunction, + TContextName extends keyof HandlerContextType > = ( - context: Partial, - ...rest: TProviderParameters -) => Promise | TContext[TContextName]; + context: Partial>, + ...rest: HandlerParameters +) => + | Promise[TContextName]> + | HandlerContextType[TContextName]; /** - * A function registered by a plugin to perform some action. + * A function that accepts a context object and an optional number of additional arguments. Used for the generic types + * in {@link IContextContainer} * - * @remarks - * A new `TContext` will be built for each handler before invoking. + * @public + */ +export type HandlerFunction = (context: T, ...args: any[]) => any; + +/** + * Extracts the type of the first argument of a {@link HandlerFunction} to represent the type of the context. * * @public */ -export type IContextHandler = ( - context: TContext, - ...rest: THandlerParameters -) => TReturn; +export type HandlerContextType> = T extends HandlerFunction + ? U + : never; + +/** + * Extracts the types of the additional arguments of a {@link HandlerFunction}, excluding the + * {@link HandlerContextType}. + * + * @public + */ +export type HandlerParameters> = T extends ( + context: any, + ...args: infer U +) => any + ? U + : never; /** * An object that handles registration of context providers and configuring handlers with context. @@ -123,13 +142,12 @@ export type IContextHandler { +export interface IContextContainer> { /** * Register a new context provider. * @@ -144,10 +162,10 @@ export interface IContextContainer< * @param provider - A {@link IContextProvider} to be called each time a new context is created. * @returns The {@link IContextContainer} for method chaining. */ - registerContext( + registerContext>( pluginOpaqueId: PluginOpaqueId, contextName: TContextName, - provider: IContextProvider + provider: IContextProvider ): this; /** @@ -160,31 +178,26 @@ export interface IContextContainer< */ createHandler( pluginOpaqueId: PluginOpaqueId, - handler: IContextHandler - ): ( - ...rest: THandlerParameters - ) => THandlerReturn extends Promise ? THandlerReturn : Promise; + handler: THandler + ): (...rest: HandlerParameters) => ShallowPromise>; } /** @internal */ -export class ContextContainer< - TContext extends Record, - THandlerReturn, - THandlerParameters extends any[] = [] -> implements IContextContainer { +export class ContextContainer> + implements IContextContainer { /** * Used to map contexts to their providers and associated plugin. In registration order which is tightly coupled to * plugin load order. */ private readonly contextProviders = new Map< - keyof TContext, + keyof HandlerContextType, { - provider: IContextProvider; + provider: IContextProvider>; source: symbol; } >(); /** Used to keep track of which plugins registered which contexts for dependency resolution. */ - private readonly contextNamesBySource: Map>; + private readonly contextNamesBySource: Map>>; /** * @param pluginDependencies - A map of plugins to an array of their dependencies. @@ -193,13 +206,15 @@ export class ContextContainer< private readonly pluginDependencies: ReadonlyMap, private readonly coreId: CoreId ) { - this.contextNamesBySource = new Map>([[coreId, []]]); + this.contextNamesBySource = new Map>>([ + [coreId, []], + ]); } - public registerContext = ( + public registerContext = >( source: symbol, contextName: TContextName, - provider: IContextProvider + provider: IContextProvider ): this => { if (this.contextProviders.has(contextName)) { throw new Error(`Context provider for ${contextName} has already been registered.`); @@ -217,27 +232,22 @@ export class ContextContainer< return this; }; - public createHandler = ( - source: symbol, - handler: IContextHandler - ) => { + public createHandler = (source: symbol, handler: THandler) => { if (source !== this.coreId && !this.pluginDependencies.has(source)) { throw new Error(`Cannot create handler for unknown plugin: ${source.toString()}`); } - return (async (...args: THandlerParameters) => { + return (async (...args: HandlerParameters) => { const context = await this.buildContext(source, ...args); return handler(context, ...args); - }) as ( - ...args: THandlerParameters - ) => THandlerReturn extends Promise ? THandlerReturn : Promise; + }) as (...args: HandlerParameters) => ShallowPromise>; }; private async buildContext( source: symbol, - ...contextArgs: THandlerParameters - ): Promise { - const contextsToBuild: ReadonlySet = new Set( + ...contextArgs: HandlerParameters + ): Promise> { + const contextsToBuild: ReadonlySet> = new Set( this.getContextNamesForSource(source) ); @@ -252,18 +262,20 @@ export class ContextContainer< // registered that provider. const exposedContext = pick(resolvedContext, [ ...this.getContextNamesForSource(providerSource), - ]); + ]) as Partial>; return { ...resolvedContext, - [contextName]: await provider(exposedContext as Partial, ...contextArgs), + [contextName]: await provider(exposedContext, ...contextArgs), }; }, - Promise.resolve({}) as Promise + Promise.resolve({}) as Promise> ); } - private getContextNamesForSource(source: symbol): ReadonlySet { + private getContextNamesForSource( + source: symbol + ): ReadonlySet> { if (source === this.coreId) { return this.getContextNamesForCore(); } else { diff --git a/x-pack/plugins/licensing/server/licensing_route_handler_context.test.ts b/x-pack/plugins/licensing/server/licensing_route_handler_context.test.ts index 2642cbb57ddd2..81ad9715da784 100644 --- a/x-pack/plugins/licensing/server/licensing_route_handler_context.test.ts +++ b/x-pack/plugins/licensing/server/licensing_route_handler_context.test.ts @@ -15,7 +15,7 @@ describe('licensingRouteHandlerContext', () => { const context = createRouteHandlerContext(license$); - const { license: contextResult } = await context({}); + const { license: contextResult } = await context({}, {} as any, {} as any); expect(contextResult).toBe(license); }); @@ -29,7 +29,7 @@ describe('licensingRouteHandlerContext', () => { const latestLicense = (Symbol() as unknown) as ILicense; license$.next(latestLicense); - const { license: contextResult } = await context({}); + const { license: contextResult } = await context({}, {} as any, {} as any); expect(contextResult).toBe(latestLicense); }); diff --git a/x-pack/plugins/licensing/server/licensing_route_handler_context.ts b/x-pack/plugins/licensing/server/licensing_route_handler_context.ts index 4705a6705da01..8ee49e9aa084f 100644 --- a/x-pack/plugins/licensing/server/licensing_route_handler_context.ts +++ b/x-pack/plugins/licensing/server/licensing_route_handler_context.ts @@ -4,14 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ -import { RequestHandlerContext, IContextProvider } from 'src/core/server'; +import { IContextProvider, RequestHandler } from 'src/core/server'; import { Observable } from 'rxjs'; import { take } from 'rxjs/operators'; import { ILicense } from './types'; export function createRouteHandlerContext( license$: Observable -): IContextProvider { +): IContextProvider, 'licensing'> { return async function licensingRouteHandlerContext() { const license = await license$.pipe(take(1)).toPromise(); return { license }; diff --git a/x-pack/plugins/licensing/server/plugin.ts b/x-pack/plugins/licensing/server/plugin.ts index 32add24cbb237..4cd40379b8592 100644 --- a/x-pack/plugins/licensing/server/plugin.ts +++ b/x-pack/plugins/licensing/server/plugin.ts @@ -20,6 +20,14 @@ import { LicensingConfig } from './licensing_config'; import { License } from './license'; import { createRouteHandlerContext } from './licensing_route_handler_context'; +declare module 'src/core/server' { + interface RequestHandlerContext { + licensing: { + license: ILicense; + }; + } +} + export class Plugin implements CorePlugin { private readonly logger: Logger; private readonly config$: Observable;