mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
parent
1b96001fc0
commit
5bbf2cfc59
65 changed files with 759 additions and 346 deletions
|
@ -1,11 +0,0 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [HttpErrorRequest](./kibana-plugin-public.httperrorrequest.md) > [error](./kibana-plugin-public.httperrorrequest.error.md)
|
||||
|
||||
## HttpErrorRequest.error property
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
error: Error;
|
||||
```
|
|
@ -1,20 +0,0 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [HttpErrorRequest](./kibana-plugin-public.httperrorrequest.md)
|
||||
|
||||
## HttpErrorRequest interface
|
||||
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
export interface HttpErrorRequest
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| [error](./kibana-plugin-public.httperrorrequest.error.md) | <code>Error</code> | |
|
||||
| [request](./kibana-plugin-public.httperrorrequest.request.md) | <code>Request</code> | |
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [HttpErrorRequest](./kibana-plugin-public.httperrorrequest.md) > [request](./kibana-plugin-public.httperrorrequest.request.md)
|
||||
|
||||
## HttpErrorRequest.request property
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
request: Request;
|
||||
```
|
|
@ -1,11 +0,0 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [HttpErrorResponse](./kibana-plugin-public.httperrorresponse.md) > [error](./kibana-plugin-public.httperrorresponse.error.md)
|
||||
|
||||
## HttpErrorResponse.error property
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
error: Error | IHttpFetchError;
|
||||
```
|
|
@ -1,19 +0,0 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [HttpErrorResponse](./kibana-plugin-public.httperrorresponse.md)
|
||||
|
||||
## HttpErrorResponse interface
|
||||
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
export interface HttpErrorResponse extends IHttpResponse
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| [error](./kibana-plugin-public.httperrorresponse.error.md) | <code>Error | IHttpFetchError</code> | |
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
## HttpFetchOptions.asResponse property
|
||||
|
||||
When `true` the return type of [HttpHandler](./kibana-plugin-public.httphandler.md) will be an [IHttpResponse](./kibana-plugin-public.ihttpresponse.md) with detailed request and response information. When `false`<!-- -->, the return type will just be the parsed response body. Defaults to `false`<!-- -->.
|
||||
When `true` the return type of [HttpHandler](./kibana-plugin-public.httphandler.md) will be an [HttpResponse](./kibana-plugin-public.httpresponse.md) with detailed request and response information. When `false`<!-- -->, the return type will just be the parsed response body. Defaults to `false`<!-- -->.
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [HttpFetchOptions](./kibana-plugin-public.httpfetchoptions.md) > [asSystemRequest](./kibana-plugin-public.httpfetchoptions.assystemrequest.md)
|
||||
|
||||
## HttpFetchOptions.asSystemRequest property
|
||||
|
||||
Whether or not the request should include the "system request" header to differentiate an end user request from Kibana internal request. Can be read on the server-side using KibanaRequest\#isSystemRequest. Defaults to `false`<!-- -->.
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
asSystemRequest?: boolean;
|
||||
```
|
|
@ -16,7 +16,8 @@ export interface HttpFetchOptions extends HttpRequestInit
|
|||
|
||||
| Property | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| [asResponse](./kibana-plugin-public.httpfetchoptions.asresponse.md) | <code>boolean</code> | When <code>true</code> the return type of [HttpHandler](./kibana-plugin-public.httphandler.md) will be an [IHttpResponse](./kibana-plugin-public.ihttpresponse.md) with detailed request and response information. When <code>false</code>, the return type will just be the parsed response body. Defaults to <code>false</code>. |
|
||||
| [asResponse](./kibana-plugin-public.httpfetchoptions.asresponse.md) | <code>boolean</code> | When <code>true</code> the return type of [HttpHandler](./kibana-plugin-public.httphandler.md) will be an [HttpResponse](./kibana-plugin-public.httpresponse.md) with detailed request and response information. When <code>false</code>, the return type will just be the parsed response body. Defaults to <code>false</code>. |
|
||||
| [asSystemRequest](./kibana-plugin-public.httpfetchoptions.assystemrequest.md) | <code>boolean</code> | Whether or not the request should include the "system request" header to differentiate an end user request from Kibana internal request. Can be read on the server-side using KibanaRequest\#isSystemRequest. Defaults to <code>false</code>. |
|
||||
| [headers](./kibana-plugin-public.httpfetchoptions.headers.md) | <code>HttpHeadersInit</code> | Headers to send with the request. See [HttpHeadersInit](./kibana-plugin-public.httpheadersinit.md)<!-- -->. |
|
||||
| [prependBasePath](./kibana-plugin-public.httpfetchoptions.prependbasepath.md) | <code>boolean</code> | Whether or not the request should automatically prepend the basePath. Defaults to <code>true</code>. |
|
||||
| [query](./kibana-plugin-public.httpfetchoptions.query.md) | <code>HttpFetchQuery</code> | The query string for an HTTP request. See [HttpFetchQuery](./kibana-plugin-public.httpfetchquery.md)<!-- -->. |
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [HttpFetchOptionsWithPath](./kibana-plugin-public.httpfetchoptionswithpath.md)
|
||||
|
||||
## HttpFetchOptionsWithPath interface
|
||||
|
||||
Similar to [HttpFetchOptions](./kibana-plugin-public.httpfetchoptions.md) but with the URL path included.
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
export interface HttpFetchOptionsWithPath extends HttpFetchOptions
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| [path](./kibana-plugin-public.httpfetchoptionswithpath.path.md) | <code>string</code> | |
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [HttpFetchOptionsWithPath](./kibana-plugin-public.httpfetchoptionswithpath.md) > [path](./kibana-plugin-public.httpfetchoptionswithpath.path.md)
|
||||
|
||||
## HttpFetchOptionsWithPath.path property
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
path: string;
|
||||
```
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
## HttpHandler interface
|
||||
|
||||
A function for making an HTTP requests to Kibana's backend. See [HttpFetchOptions](./kibana-plugin-public.httpfetchoptions.md) for options and [IHttpResponse](./kibana-plugin-public.ihttpresponse.md) for the response.
|
||||
A function for making an HTTP requests to Kibana's backend. See [HttpFetchOptions](./kibana-plugin-public.httpfetchoptions.md) for options and [HttpResponse](./kibana-plugin-public.httpresponse.md) for the response.
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
## HttpHeadersInit interface
|
||||
|
||||
Headers to append to the request. Any headers that begin with `kbn-` are considered private to Core and will cause [HttpHandler](./kibana-plugin-public.httphandler.md) to throw an error.
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ export interface HttpInterceptor
|
|||
|
||||
| Method | Description |
|
||||
| --- | --- |
|
||||
| [request(request, controller)](./kibana-plugin-public.httpinterceptor.request.md) | Define an interceptor to be executed before a request is sent. |
|
||||
| [request(fetchOptions, controller)](./kibana-plugin-public.httpinterceptor.request.md) | Define an interceptor to be executed before a request is sent. |
|
||||
| [requestError(httpErrorRequest, controller)](./kibana-plugin-public.httpinterceptor.requesterror.md) | Define an interceptor to be executed if a request interceptor throws an error or returns a rejected Promise. |
|
||||
| [response(httpResponse, controller)](./kibana-plugin-public.httpinterceptor.response.md) | Define an interceptor to be executed after a response is received. |
|
||||
| [responseError(httpErrorResponse, controller)](./kibana-plugin-public.httpinterceptor.responseerror.md) | Define an interceptor to be executed if a response interceptor throws an error or returns a rejected Promise. |
|
||||
|
|
|
@ -9,17 +9,17 @@ Define an interceptor to be executed before a request is sent.
|
|||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
request?(request: Request, controller: IHttpInterceptController): Promise<Request> | Request | void;
|
||||
request?(fetchOptions: Readonly<HttpFetchOptionsWithPath>, controller: IHttpInterceptController): MaybePromise<Partial<HttpFetchOptionsWithPath>> | void;
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| request | <code>Request</code> | |
|
||||
| fetchOptions | <code>Readonly<HttpFetchOptionsWithPath></code> | |
|
||||
| controller | <code>IHttpInterceptController</code> | |
|
||||
|
||||
<b>Returns:</b>
|
||||
|
||||
`Promise<Request> | Request | void`
|
||||
`MaybePromise<Partial<HttpFetchOptionsWithPath>> | void`
|
||||
|
||||
|
|
|
@ -9,17 +9,17 @@ Define an interceptor to be executed if a request interceptor throws an error or
|
|||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
requestError?(httpErrorRequest: HttpErrorRequest, controller: IHttpInterceptController): Promise<Request> | Request | void;
|
||||
requestError?(httpErrorRequest: HttpInterceptorRequestError, controller: IHttpInterceptController): MaybePromise<Partial<HttpFetchOptionsWithPath>> | void;
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| httpErrorRequest | <code>HttpErrorRequest</code> | |
|
||||
| httpErrorRequest | <code>HttpInterceptorRequestError</code> | |
|
||||
| controller | <code>IHttpInterceptController</code> | |
|
||||
|
||||
<b>Returns:</b>
|
||||
|
||||
`Promise<Request> | Request | void`
|
||||
`MaybePromise<Partial<HttpFetchOptionsWithPath>> | void`
|
||||
|
||||
|
|
|
@ -9,17 +9,17 @@ Define an interceptor to be executed after a response is received.
|
|||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
response?(httpResponse: IHttpResponse, controller: IHttpInterceptController): Promise<IHttpResponseInterceptorOverrides> | IHttpResponseInterceptorOverrides | void;
|
||||
response?(httpResponse: HttpResponse, controller: IHttpInterceptController): MaybePromise<IHttpResponseInterceptorOverrides> | void;
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| httpResponse | <code>IHttpResponse</code> | |
|
||||
| httpResponse | <code>HttpResponse</code> | |
|
||||
| controller | <code>IHttpInterceptController</code> | |
|
||||
|
||||
<b>Returns:</b>
|
||||
|
||||
`Promise<IHttpResponseInterceptorOverrides> | IHttpResponseInterceptorOverrides | void`
|
||||
`MaybePromise<IHttpResponseInterceptorOverrides> | void`
|
||||
|
||||
|
|
|
@ -9,17 +9,17 @@ Define an interceptor to be executed if a response interceptor throws an error o
|
|||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
responseError?(httpErrorResponse: HttpErrorResponse, controller: IHttpInterceptController): Promise<IHttpResponseInterceptorOverrides> | IHttpResponseInterceptorOverrides | void;
|
||||
responseError?(httpErrorResponse: HttpInterceptorResponseError, controller: IHttpInterceptController): MaybePromise<IHttpResponseInterceptorOverrides> | void;
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| httpErrorResponse | <code>HttpErrorResponse</code> | |
|
||||
| httpErrorResponse | <code>HttpInterceptorResponseError</code> | |
|
||||
| controller | <code>IHttpInterceptController</code> | |
|
||||
|
||||
<b>Returns:</b>
|
||||
|
||||
`Promise<IHttpResponseInterceptorOverrides> | IHttpResponseInterceptorOverrides | void`
|
||||
`MaybePromise<IHttpResponseInterceptorOverrides> | void`
|
||||
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [HttpInterceptorRequestError](./kibana-plugin-public.httpinterceptorrequesterror.md) > [error](./kibana-plugin-public.httpinterceptorrequesterror.error.md)
|
||||
|
||||
## HttpInterceptorRequestError.error property
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
error: Error;
|
||||
```
|
|
@ -0,0 +1,11 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [HttpInterceptorRequestError](./kibana-plugin-public.httpinterceptorrequesterror.md) > [fetchOptions](./kibana-plugin-public.httpinterceptorrequesterror.fetchoptions.md)
|
||||
|
||||
## HttpInterceptorRequestError.fetchOptions property
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
fetchOptions: Readonly<HttpFetchOptionsWithPath>;
|
||||
```
|
|
@ -0,0 +1,20 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [HttpInterceptorRequestError](./kibana-plugin-public.httpinterceptorrequesterror.md)
|
||||
|
||||
## HttpInterceptorRequestError interface
|
||||
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
export interface HttpInterceptorRequestError
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| [error](./kibana-plugin-public.httpinterceptorrequesterror.error.md) | <code>Error</code> | |
|
||||
| [fetchOptions](./kibana-plugin-public.httpinterceptorrequesterror.fetchoptions.md) | <code>Readonly<HttpFetchOptionsWithPath></code> | |
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [HttpInterceptorResponseError](./kibana-plugin-public.httpinterceptorresponseerror.md) > [error](./kibana-plugin-public.httpinterceptorresponseerror.error.md)
|
||||
|
||||
## HttpInterceptorResponseError.error property
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
error: Error | IHttpFetchError;
|
||||
```
|
|
@ -0,0 +1,20 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [HttpInterceptorResponseError](./kibana-plugin-public.httpinterceptorresponseerror.md)
|
||||
|
||||
## HttpInterceptorResponseError interface
|
||||
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
export interface HttpInterceptorResponseError extends HttpResponse
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| [error](./kibana-plugin-public.httpinterceptorresponseerror.error.md) | <code>Error | IHttpFetchError</code> | |
|
||||
| [request](./kibana-plugin-public.httpinterceptorresponseerror.request.md) | <code>Readonly<Request></code> | |
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [HttpInterceptorResponseError](./kibana-plugin-public.httpinterceptorresponseerror.md) > [request](./kibana-plugin-public.httpinterceptorresponseerror.request.md)
|
||||
|
||||
## HttpInterceptorResponseError.request property
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
request: Readonly<Request>;
|
||||
```
|
|
@ -1,8 +1,8 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [IHttpResponse](./kibana-plugin-public.ihttpresponse.md) > [body](./kibana-plugin-public.ihttpresponse.body.md)
|
||||
[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [HttpResponse](./kibana-plugin-public.httpresponse.md) > [body](./kibana-plugin-public.httpresponse.body.md)
|
||||
|
||||
## IHttpResponse.body property
|
||||
## HttpResponse.body property
|
||||
|
||||
Parsed body received, may be undefined if there was an error.
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [HttpResponse](./kibana-plugin-public.httpresponse.md) > [fetchOptions](./kibana-plugin-public.httpresponse.fetchoptions.md)
|
||||
|
||||
## HttpResponse.fetchOptions property
|
||||
|
||||
The original [HttpFetchOptionsWithPath](./kibana-plugin-public.httpfetchoptionswithpath.md) used to send this request.
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
readonly fetchOptions: Readonly<HttpFetchOptionsWithPath>;
|
||||
```
|
|
@ -0,0 +1,22 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [HttpResponse](./kibana-plugin-public.httpresponse.md)
|
||||
|
||||
## HttpResponse interface
|
||||
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
export interface HttpResponse<TResponseBody = any>
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| [body](./kibana-plugin-public.httpresponse.body.md) | <code>TResponseBody</code> | Parsed body received, may be undefined if there was an error. |
|
||||
| [fetchOptions](./kibana-plugin-public.httpresponse.fetchoptions.md) | <code>Readonly<HttpFetchOptionsWithPath></code> | The original [HttpFetchOptionsWithPath](./kibana-plugin-public.httpfetchoptionswithpath.md) used to send this request. |
|
||||
| [request](./kibana-plugin-public.httpresponse.request.md) | <code>Readonly<Request></code> | Raw request sent to Kibana server. |
|
||||
| [response](./kibana-plugin-public.httpresponse.response.md) | <code>Readonly<Response></code> | Raw response received, may be undefined if there was an error. |
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [IHttpResponse](./kibana-plugin-public.ihttpresponse.md) > [request](./kibana-plugin-public.ihttpresponse.request.md)
|
||||
[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [HttpResponse](./kibana-plugin-public.httpresponse.md) > [request](./kibana-plugin-public.httpresponse.request.md)
|
||||
|
||||
## IHttpResponse.request property
|
||||
## HttpResponse.request property
|
||||
|
||||
Raw request sent to Kibana server.
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [IHttpResponse](./kibana-plugin-public.ihttpresponse.md) > [response](./kibana-plugin-public.ihttpresponse.response.md)
|
||||
[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [HttpResponse](./kibana-plugin-public.httpresponse.md) > [response](./kibana-plugin-public.httpresponse.response.md)
|
||||
|
||||
## IHttpResponse.response property
|
||||
## HttpResponse.response property
|
||||
|
||||
Raw response received, may be undefined if there was an error.
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [IHttpResponse](./kibana-plugin-public.ihttpresponse.md)
|
||||
|
||||
## IHttpResponse interface
|
||||
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
export interface IHttpResponse<TResponseBody = any>
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
| Property | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| [body](./kibana-plugin-public.ihttpresponse.body.md) | <code>TResponseBody</code> | Parsed body received, may be undefined if there was an error. |
|
||||
| [request](./kibana-plugin-public.ihttpresponse.request.md) | <code>Readonly<Request></code> | Raw request sent to Kibana server. |
|
||||
| [response](./kibana-plugin-public.ihttpresponse.response.md) | <code>Readonly<Response></code> | Raw response received, may be undefined if there was an error. |
|
||||
|
|
@ -59,14 +59,16 @@ The plugin integrates with the core system via lifecycle events: `setup`<!-- -->
|
|||
| [ErrorToastOptions](./kibana-plugin-public.errortoastoptions.md) | Options available for [IToasts](./kibana-plugin-public.itoasts.md) APIs. |
|
||||
| [FatalErrorInfo](./kibana-plugin-public.fatalerrorinfo.md) | Represents the <code>message</code> and <code>stack</code> of a fatal Error |
|
||||
| [FatalErrorsSetup](./kibana-plugin-public.fatalerrorssetup.md) | FatalErrors stop the Kibana Public Core and displays a fatal error screen with details about the Kibana build and the error. |
|
||||
| [HttpErrorRequest](./kibana-plugin-public.httperrorrequest.md) | |
|
||||
| [HttpErrorResponse](./kibana-plugin-public.httperrorresponse.md) | |
|
||||
| [HttpFetchOptions](./kibana-plugin-public.httpfetchoptions.md) | All options that may be used with a [HttpHandler](./kibana-plugin-public.httphandler.md)<!-- -->. |
|
||||
| [HttpFetchOptionsWithPath](./kibana-plugin-public.httpfetchoptionswithpath.md) | Similar to [HttpFetchOptions](./kibana-plugin-public.httpfetchoptions.md) but with the URL path included. |
|
||||
| [HttpFetchQuery](./kibana-plugin-public.httpfetchquery.md) | |
|
||||
| [HttpHandler](./kibana-plugin-public.httphandler.md) | A function for making an HTTP requests to Kibana's backend. See [HttpFetchOptions](./kibana-plugin-public.httpfetchoptions.md) for options and [IHttpResponse](./kibana-plugin-public.ihttpresponse.md) for the response. |
|
||||
| [HttpHeadersInit](./kibana-plugin-public.httpheadersinit.md) | |
|
||||
| [HttpHandler](./kibana-plugin-public.httphandler.md) | A function for making an HTTP requests to Kibana's backend. See [HttpFetchOptions](./kibana-plugin-public.httpfetchoptions.md) for options and [HttpResponse](./kibana-plugin-public.httpresponse.md) for the response. |
|
||||
| [HttpHeadersInit](./kibana-plugin-public.httpheadersinit.md) | Headers to append to the request. Any headers that begin with <code>kbn-</code> are considered private to Core and will cause [HttpHandler](./kibana-plugin-public.httphandler.md) to throw an error. |
|
||||
| [HttpInterceptor](./kibana-plugin-public.httpinterceptor.md) | An object that may define global interceptor functions for different parts of the request and response lifecycle. See [IHttpInterceptController](./kibana-plugin-public.ihttpinterceptcontroller.md)<!-- -->. |
|
||||
| [HttpInterceptorRequestError](./kibana-plugin-public.httpinterceptorrequesterror.md) | |
|
||||
| [HttpInterceptorResponseError](./kibana-plugin-public.httpinterceptorresponseerror.md) | |
|
||||
| [HttpRequestInit](./kibana-plugin-public.httprequestinit.md) | Fetch API options available to [HttpHandler](./kibana-plugin-public.httphandler.md)<!-- -->s. |
|
||||
| [HttpResponse](./kibana-plugin-public.httpresponse.md) | |
|
||||
| [HttpSetup](./kibana-plugin-public.httpsetup.md) | |
|
||||
| [I18nStart](./kibana-plugin-public.i18nstart.md) | I18nStart.Context is required by any localizable React component from @<!-- -->kbn/i18n and @<!-- -->elastic/eui packages and is supposed to be used as the topmost component for any i18n-compatible React tree. |
|
||||
| [IAnonymousPaths](./kibana-plugin-public.ianonymouspaths.md) | APIs for denoting paths as not requiring authentication |
|
||||
|
@ -74,7 +76,6 @@ The plugin integrates with the core system via lifecycle events: `setup`<!-- -->
|
|||
| [IContextContainer](./kibana-plugin-public.icontextcontainer.md) | An object that handles registration of context providers and configuring handlers with context. |
|
||||
| [IHttpFetchError](./kibana-plugin-public.ihttpfetcherror.md) | |
|
||||
| [IHttpInterceptController](./kibana-plugin-public.ihttpinterceptcontroller.md) | Used to halt a request Promise chain in a [HttpInterceptor](./kibana-plugin-public.httpinterceptor.md)<!-- -->. |
|
||||
| [IHttpResponse](./kibana-plugin-public.ihttpresponse.md) | |
|
||||
| [IHttpResponseInterceptorOverrides](./kibana-plugin-public.ihttpresponseinterceptoroverrides.md) | Properties that can be returned by HttpInterceptor.request to override the response. |
|
||||
| [ImageValidation](./kibana-plugin-public.imagevalidation.md) | |
|
||||
| [IUiSettingsClient](./kibana-plugin-public.iuisettingsclient.md) | Client-side client that provides access to the advanced settings stored in elasticsearch. The settings provide control over the behavior of the Kibana application. For example, a user can specify how to display numeric or date fields. Users can adjust the settings via Management UI. [IUiSettingsClient](./kibana-plugin-public.iuisettingsclient.md) |
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [KibanaRequest](./kibana-plugin-server.kibanarequest.md) > [isSystemRequest](./kibana-plugin-server.kibanarequest.issystemrequest.md)
|
||||
|
||||
## KibanaRequest.isSystemRequest property
|
||||
|
||||
Whether or not the request is a "system request" rather than an application-level request. Can be set on the client using the `HttpFetchOptions#asSystemRequest` option.
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
readonly isSystemRequest: boolean;
|
||||
```
|
|
@ -25,6 +25,7 @@ export declare class KibanaRequest<Params = unknown, Query = unknown, Body = unk
|
|||
| [body](./kibana-plugin-server.kibanarequest.body.md) | | <code>Body</code> | |
|
||||
| [events](./kibana-plugin-server.kibanarequest.events.md) | | <code>KibanaRequestEvents</code> | Request events [KibanaRequestEvents](./kibana-plugin-server.kibanarequestevents.md) |
|
||||
| [headers](./kibana-plugin-server.kibanarequest.headers.md) | | <code>Headers</code> | Readonly copy of incoming request headers. |
|
||||
| [isSystemRequest](./kibana-plugin-server.kibanarequest.issystemrequest.md) | | <code>boolean</code> | Whether or not the request is a "system request" rather than an application-level request. Can be set on the client using the <code>HttpFetchOptions#asSystemRequest</code> option. |
|
||||
| [params](./kibana-plugin-server.kibanarequest.params.md) | | <code>Params</code> | |
|
||||
| [query](./kibana-plugin-server.kibanarequest.query.md) | | <code>Query</code> | |
|
||||
| [route](./kibana-plugin-server.kibanarequest.route.md) | | <code>RecursiveReadonly<KibanaRequestRoute<Method>></code> | matched route details |
|
||||
|
|
|
@ -21,7 +21,17 @@ import { PromiseType } from 'utility-types';
|
|||
export { $Values, Required, Optional, Class } from 'utility-types';
|
||||
|
||||
/**
|
||||
* Returns wrapped type of a promise.
|
||||
* A type that may or may not be a `Promise`.
|
||||
*/
|
||||
export type MaybePromise<T> = T | Promise<T>;
|
||||
|
||||
/**
|
||||
* Converts a type to a `Promise`, unless it is already a `Promise`. Useful when proxying the return value of a possibly async function.
|
||||
*/
|
||||
export type ShallowPromise<T> = T extends Promise<infer U> ? Promise<U> : Promise<T>;
|
||||
|
||||
/**
|
||||
* Returns wrapped type of a `Promise`.
|
||||
*/
|
||||
export type UnwrapPromise<T extends Promise<any>> = PromiseType<T>;
|
||||
|
||||
|
@ -39,11 +49,6 @@ export type UnwrapObservable<T extends ObservableLike<any>> = T extends Observab
|
|||
? U
|
||||
: never;
|
||||
|
||||
/**
|
||||
* Converts a type to a `Promise`, unless it is already a `Promise`. Useful when proxying the return value of a possibly async function.
|
||||
*/
|
||||
export type ShallowPromise<T> = T extends Promise<infer U> ? Promise<U> : Promise<T>;
|
||||
|
||||
/**
|
||||
* Ensures T is of type X.
|
||||
*/
|
||||
|
|
|
@ -24,7 +24,7 @@ import { join } from 'path';
|
|||
|
||||
import { Fetch } from './fetch';
|
||||
import { BasePath } from './base_path';
|
||||
import { IHttpResponse } from './types';
|
||||
import { HttpResponse, HttpFetchOptionsWithPath } from './types';
|
||||
|
||||
function delay<T>(duration: number) {
|
||||
return new Promise<T>(r => setTimeout(r, duration));
|
||||
|
@ -40,6 +40,19 @@ describe('Fetch', () => {
|
|||
});
|
||||
|
||||
describe('http requests', () => {
|
||||
it('should fail with invalid arguments', async () => {
|
||||
fetchMock.get('*', {});
|
||||
await expect(
|
||||
fetchInstance.fetch(
|
||||
// @ts-ignore
|
||||
{ path: '/', headers: { hello: 'world' } },
|
||||
{ headers: { hello: 'mars' } }
|
||||
)
|
||||
).rejects.toThrowErrorMatchingInlineSnapshot(
|
||||
`"Invalid fetch arguments, must either be (string, object) or (object, undefined), received (object, object)"`
|
||||
);
|
||||
});
|
||||
|
||||
it('should use supplied request method', async () => {
|
||||
fetchMock.post('*', {});
|
||||
await fetchInstance.fetch('/my/path', { method: 'POST' });
|
||||
|
@ -56,6 +69,15 @@ describe('Fetch', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should not set Content-Type if undefined', async () => {
|
||||
fetchMock.get('*', {});
|
||||
await fetchInstance.fetch('/my/path', { headers: { 'Content-Type': undefined } });
|
||||
|
||||
expect(fetchMock.lastOptions()!.headers).toMatchObject({
|
||||
'kbn-version': 'VERSION',
|
||||
});
|
||||
});
|
||||
|
||||
it('should use supplied pathname and querystring', async () => {
|
||||
fetchMock.get('*', {});
|
||||
await fetchInstance.fetch('/my/path', { query: { a: 'b' } });
|
||||
|
@ -69,13 +91,106 @@ describe('Fetch', () => {
|
|||
headers: { myHeader: 'foo' },
|
||||
});
|
||||
|
||||
expect(fetchMock.lastOptions()!.headers).toEqual({
|
||||
expect(fetchMock.lastOptions()!.headers).toMatchObject({
|
||||
'content-type': 'application/json',
|
||||
'kbn-version': 'VERSION',
|
||||
myheader: 'foo',
|
||||
});
|
||||
});
|
||||
|
||||
it('should not allow overwriting of kbn-version header', async () => {
|
||||
fetchMock.get('*', {});
|
||||
await expect(
|
||||
fetchInstance.fetch('/my/path', {
|
||||
headers: { myHeader: 'foo', 'kbn-version': 'CUSTOM!' },
|
||||
})
|
||||
).rejects.toThrowErrorMatchingInlineSnapshot(
|
||||
`"Invalid fetch headers, headers beginning with \\"kbn-\\" are not allowed: [kbn-version]"`
|
||||
);
|
||||
});
|
||||
|
||||
it('should not set kbn-system-request header by default', async () => {
|
||||
fetchMock.get('*', {});
|
||||
await fetchInstance.fetch('/my/path', {
|
||||
headers: { myHeader: 'foo' },
|
||||
});
|
||||
|
||||
expect(fetchMock.lastOptions()!.headers['kbn-system-request']).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should not set kbn-system-request header when asSystemRequest: false', async () => {
|
||||
fetchMock.get('*', {});
|
||||
await fetchInstance.fetch('/my/path', {
|
||||
headers: { myHeader: 'foo' },
|
||||
asSystemRequest: false,
|
||||
});
|
||||
|
||||
expect(fetchMock.lastOptions()!.headers['kbn-system-request']).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should set kbn-system-request header when asSystemRequest: true', async () => {
|
||||
fetchMock.get('*', {});
|
||||
await fetchInstance.fetch('/my/path', {
|
||||
headers: { myHeader: 'foo' },
|
||||
asSystemRequest: true,
|
||||
});
|
||||
|
||||
expect(fetchMock.lastOptions()!.headers).toMatchObject({
|
||||
'kbn-system-request': 'true',
|
||||
myheader: 'foo',
|
||||
});
|
||||
});
|
||||
|
||||
it('should not allow overwriting of kbn-system-request when asSystemRequest: true', async () => {
|
||||
fetchMock.get('*', {});
|
||||
await expect(
|
||||
fetchInstance.fetch('/my/path', {
|
||||
headers: { myHeader: 'foo', 'kbn-system-request': 'ANOTHER!' },
|
||||
asSystemRequest: true,
|
||||
})
|
||||
).rejects.toThrowErrorMatchingInlineSnapshot(
|
||||
`"Invalid fetch headers, headers beginning with \\"kbn-\\" are not allowed: [kbn-system-request]"`
|
||||
);
|
||||
});
|
||||
|
||||
it('should not allow overwriting of kbn-system-request when asSystemRequest: false', async () => {
|
||||
fetchMock.get('*', {});
|
||||
await expect(
|
||||
fetchInstance.fetch('/my/path', {
|
||||
headers: { myHeader: 'foo', 'kbn-system-request': 'ANOTHER!' },
|
||||
asSystemRequest: false,
|
||||
})
|
||||
).rejects.toThrowErrorMatchingInlineSnapshot(
|
||||
`"Invalid fetch headers, headers beginning with \\"kbn-\\" are not allowed: [kbn-system-request]"`
|
||||
);
|
||||
});
|
||||
|
||||
// Deprecated header used by legacy platform pre-7.7. Remove in 8.x.
|
||||
it('should not allow overwriting of kbn-system-api when asSystemRequest: true', async () => {
|
||||
fetchMock.get('*', {});
|
||||
await expect(
|
||||
fetchInstance.fetch('/my/path', {
|
||||
headers: { myHeader: 'foo', 'kbn-system-api': 'ANOTHER!' },
|
||||
asSystemRequest: true,
|
||||
})
|
||||
).rejects.toThrowErrorMatchingInlineSnapshot(
|
||||
`"Invalid fetch headers, headers beginning with \\"kbn-\\" are not allowed: [kbn-system-api]"`
|
||||
);
|
||||
});
|
||||
|
||||
// Deprecated header used by legacy platform pre-7.7. Remove in 8.x.
|
||||
it('should not allow overwriting of kbn-system-api when asSystemRequest: false', async () => {
|
||||
fetchMock.get('*', {});
|
||||
await expect(
|
||||
fetchInstance.fetch('/my/path', {
|
||||
headers: { myHeader: 'foo', 'kbn-system-api': 'ANOTHER!' },
|
||||
asSystemRequest: false,
|
||||
})
|
||||
).rejects.toThrowErrorMatchingInlineSnapshot(
|
||||
`"Invalid fetch headers, headers beginning with \\"kbn-\\" are not allowed: [kbn-system-api]"`
|
||||
);
|
||||
});
|
||||
|
||||
it('should return response', async () => {
|
||||
fetchMock.get('*', { foo: 'bar' });
|
||||
const json = await fetchInstance.fetch('/my/path');
|
||||
|
@ -121,11 +236,35 @@ describe('Fetch', () => {
|
|||
|
||||
const response = await fetchInstance.fetch('/my/path', { asResponse: true });
|
||||
|
||||
expect(response.fetchOptions).toMatchObject({
|
||||
path: '/my/path',
|
||||
asResponse: true,
|
||||
});
|
||||
expect(response.request).toBeInstanceOf(Request);
|
||||
expect(response.response).toBeInstanceOf(Response);
|
||||
expect(response.body).toEqual({ foo: 'bar' });
|
||||
});
|
||||
|
||||
it('should expose asSystemRequest: true on detailed response object when asResponse = true', async () => {
|
||||
fetchMock.get('*', { foo: 'bar' });
|
||||
|
||||
const response = await fetchInstance.fetch('/my/path', {
|
||||
asResponse: true,
|
||||
asSystemRequest: true,
|
||||
});
|
||||
expect(response.fetchOptions.asSystemRequest).toBe(true);
|
||||
});
|
||||
|
||||
it('should expose asSystemRequest: false on detailed response object when asResponse = true', async () => {
|
||||
fetchMock.get('*', { foo: 'bar' });
|
||||
|
||||
const response = await fetchInstance.fetch('/my/path', {
|
||||
asResponse: true,
|
||||
asSystemRequest: false,
|
||||
});
|
||||
expect(response.fetchOptions.asSystemRequest).toBe(false);
|
||||
});
|
||||
|
||||
it('should reject on network error', async () => {
|
||||
expect.assertions(1);
|
||||
fetchMock.get('*', { status: 500 });
|
||||
|
@ -245,13 +384,18 @@ describe('Fetch', () => {
|
|||
|
||||
it('should be able to manipulate request instance', async () => {
|
||||
fetchInstance.intercept({
|
||||
request(request) {
|
||||
request.headers.set('Content-Type', 'CustomContentType');
|
||||
request(options) {
|
||||
return {
|
||||
headers: {
|
||||
...options.headers,
|
||||
'Content-Type': 'CustomContentType',
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
fetchInstance.intercept({
|
||||
request(request) {
|
||||
return new Request('/my/route', request);
|
||||
request() {
|
||||
return { path: '/my/route' };
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -262,7 +406,7 @@ describe('Fetch', () => {
|
|||
expect(fetchMock.lastOptions()!.headers).toMatchObject({
|
||||
'content-type': 'CustomContentType',
|
||||
});
|
||||
expect(fetchMock.lastUrl()).toBe('/my/route');
|
||||
expect(fetchMock.lastUrl()).toBe('http://localhost/myBase/my/route');
|
||||
});
|
||||
|
||||
it('should call interceptors in correct order', async () => {
|
||||
|
@ -402,8 +546,8 @@ describe('Fetch', () => {
|
|||
|
||||
fetchInstance.intercept({
|
||||
request: unusedSpy,
|
||||
requestError({ request }) {
|
||||
return new Request('/my/route', request);
|
||||
requestError() {
|
||||
return { path: '/my/route' };
|
||||
},
|
||||
response: usedSpy,
|
||||
});
|
||||
|
@ -423,16 +567,16 @@ describe('Fetch', () => {
|
|||
|
||||
it('should accumulate request information', async () => {
|
||||
const routes = ['alpha', 'beta', 'gamma'];
|
||||
const createRequest = jest.fn(
|
||||
(request: Request) => new Request(`/api/${routes.shift()}`, request)
|
||||
);
|
||||
const createRequest = jest.fn((options: HttpFetchOptionsWithPath) => ({
|
||||
path: `/api/${routes.shift()}`,
|
||||
}));
|
||||
|
||||
fetchInstance.intercept({
|
||||
request: createRequest,
|
||||
});
|
||||
fetchInstance.intercept({
|
||||
requestError(httpErrorRequest) {
|
||||
return httpErrorRequest.request;
|
||||
return httpErrorRequest.fetchOptions;
|
||||
},
|
||||
});
|
||||
fetchInstance.intercept({
|
||||
|
@ -450,15 +594,15 @@ describe('Fetch', () => {
|
|||
await expect(fetchInstance.fetch('/my/route')).resolves.toEqual({ foo: 'bar' });
|
||||
expect(fetchMock.called()).toBe(true);
|
||||
expect(routes.length).toBe(0);
|
||||
expect(createRequest.mock.calls[0][0].url).toContain('/my/route');
|
||||
expect(createRequest.mock.calls[1][0].url).toContain('/api/alpha');
|
||||
expect(createRequest.mock.calls[2][0].url).toContain('/api/beta');
|
||||
expect(createRequest.mock.calls[0][0].path).toContain('/my/route');
|
||||
expect(createRequest.mock.calls[1][0].path).toContain('/api/alpha');
|
||||
expect(createRequest.mock.calls[2][0].path).toContain('/api/beta');
|
||||
expect(fetchMock.lastCall()!.request.url).toContain('/api/gamma');
|
||||
});
|
||||
|
||||
it('should accumulate response information', async () => {
|
||||
const bodies = ['alpha', 'beta', 'gamma'];
|
||||
const createResponse = jest.fn((httpResponse: IHttpResponse) => ({
|
||||
const createResponse = jest.fn((httpResponse: HttpResponse) => ({
|
||||
body: bodies.shift(),
|
||||
}));
|
||||
|
||||
|
@ -550,7 +694,7 @@ describe('Fetch', () => {
|
|||
|
||||
fetchInstance.intercept({
|
||||
requestError(httpErrorRequest) {
|
||||
return httpErrorRequest.request;
|
||||
return httpErrorRequest.fetchOptions;
|
||||
},
|
||||
response: usedSpy,
|
||||
});
|
||||
|
|
|
@ -20,10 +20,16 @@
|
|||
import { merge } from 'lodash';
|
||||
import { format } from 'url';
|
||||
|
||||
import { IBasePath, HttpInterceptor, HttpHandler, HttpFetchOptions, IHttpResponse } from './types';
|
||||
import {
|
||||
IBasePath,
|
||||
HttpInterceptor,
|
||||
HttpHandler,
|
||||
HttpFetchOptions,
|
||||
HttpResponse,
|
||||
HttpFetchOptionsWithPath,
|
||||
} from './types';
|
||||
import { HttpFetchError } from './http_fetch_error';
|
||||
import { HttpInterceptController } from './http_intercept_controller';
|
||||
import { HttpResponse } from './response';
|
||||
import { interceptRequest, interceptResponse } from './intercept';
|
||||
import { HttpInterceptHaltError } from './http_intercept_halt_error';
|
||||
|
||||
|
@ -60,29 +66,30 @@ export class Fetch {
|
|||
public readonly put = this.shorthand('PUT');
|
||||
|
||||
public fetch: HttpHandler = async <TResponseBody>(
|
||||
path: string,
|
||||
options: HttpFetchOptions = {}
|
||||
pathOrOptions: string | HttpFetchOptionsWithPath,
|
||||
options?: HttpFetchOptions
|
||||
) => {
|
||||
const initialRequest = this.createRequest(path, options);
|
||||
const optionsWithPath = validateFetchArguments(pathOrOptions, options);
|
||||
const controller = new HttpInterceptController();
|
||||
|
||||
// We wrap the interception in a separate promise to ensure that when
|
||||
// a halt is called we do not resolve or reject, halting handling of the promise.
|
||||
return new Promise<TResponseBody | IHttpResponse<TResponseBody>>(async (resolve, reject) => {
|
||||
return new Promise<TResponseBody | HttpResponse<TResponseBody>>(async (resolve, reject) => {
|
||||
try {
|
||||
const interceptedRequest = await interceptRequest(
|
||||
initialRequest,
|
||||
const interceptedOptions = await interceptRequest(
|
||||
optionsWithPath,
|
||||
this.interceptors,
|
||||
controller
|
||||
);
|
||||
const initialResponse = this.fetchResponse(interceptedRequest);
|
||||
const initialResponse = this.fetchResponse(interceptedOptions);
|
||||
const interceptedResponse = await interceptResponse(
|
||||
interceptedOptions,
|
||||
initialResponse,
|
||||
this.interceptors,
|
||||
controller
|
||||
);
|
||||
|
||||
if (options.asResponse) {
|
||||
if (optionsWithPath.asResponse) {
|
||||
resolve(interceptedResponse);
|
||||
} else {
|
||||
resolve(interceptedResponse.body);
|
||||
|
@ -95,38 +102,44 @@ export class Fetch {
|
|||
});
|
||||
};
|
||||
|
||||
private createRequest(path: string, options?: HttpFetchOptions): Request {
|
||||
private createRequest(options: HttpFetchOptionsWithPath): Request {
|
||||
// Merge and destructure options out that are not applicable to the Fetch API.
|
||||
const { query, prependBasePath: shouldPrependBasePath, asResponse, ...fetchOptions } = merge(
|
||||
const {
|
||||
query,
|
||||
prependBasePath: shouldPrependBasePath,
|
||||
asResponse,
|
||||
asSystemRequest,
|
||||
...fetchOptions
|
||||
} = merge(
|
||||
{
|
||||
method: 'GET',
|
||||
credentials: 'same-origin',
|
||||
prependBasePath: true,
|
||||
headers: {
|
||||
'kbn-version': this.params.kibanaVersion,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
},
|
||||
options || {}
|
||||
options,
|
||||
{
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
...options.headers,
|
||||
'kbn-version': this.params.kibanaVersion,
|
||||
},
|
||||
}
|
||||
);
|
||||
const url = format({
|
||||
pathname: shouldPrependBasePath ? this.params.basePath.prepend(path) : path,
|
||||
pathname: shouldPrependBasePath ? this.params.basePath.prepend(options.path) : options.path,
|
||||
query,
|
||||
});
|
||||
|
||||
if (
|
||||
options &&
|
||||
options.headers &&
|
||||
'Content-Type' in options.headers &&
|
||||
options.headers['Content-Type'] === undefined
|
||||
) {
|
||||
delete fetchOptions.headers['Content-Type'];
|
||||
// Make sure the system request header is only present if `asSystemRequest` is true.
|
||||
if (asSystemRequest) {
|
||||
fetchOptions.headers['kbn-system-request'] = 'true';
|
||||
}
|
||||
|
||||
return new Request(url, fetchOptions);
|
||||
}
|
||||
|
||||
private async fetchResponse(request: Request) {
|
||||
private async fetchResponse(fetchOptions: HttpFetchOptionsWithPath): Promise<HttpResponse<any>> {
|
||||
const request = this.createRequest(fetchOptions);
|
||||
let response: Response;
|
||||
let body = null;
|
||||
|
||||
|
@ -164,11 +177,46 @@ export class Fetch {
|
|||
throw new HttpFetchError(response.statusText, request, response, body);
|
||||
}
|
||||
|
||||
return new HttpResponse({ request, response, body });
|
||||
return { fetchOptions, request, response, body };
|
||||
}
|
||||
|
||||
private shorthand(method: string) {
|
||||
return (path: string, options: HttpFetchOptions = {}) =>
|
||||
this.fetch(path, { ...options, method });
|
||||
private shorthand(method: string): HttpHandler {
|
||||
return (pathOrOptions: string | HttpFetchOptionsWithPath, options?: HttpFetchOptions) => {
|
||||
const optionsWithPath = validateFetchArguments(pathOrOptions, options);
|
||||
return this.fetch({ ...optionsWithPath, method });
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that the overloaded arguments to `HttpHandler` are valid.
|
||||
*/
|
||||
const validateFetchArguments = (
|
||||
pathOrOptions: string | HttpFetchOptionsWithPath,
|
||||
options?: HttpFetchOptions
|
||||
): HttpFetchOptionsWithPath => {
|
||||
let fullOptions: HttpFetchOptionsWithPath;
|
||||
|
||||
if (typeof pathOrOptions === 'string' && (typeof options === 'object' || options === undefined)) {
|
||||
fullOptions = { ...options, path: pathOrOptions };
|
||||
} else if (typeof pathOrOptions === 'object' && options === undefined) {
|
||||
fullOptions = pathOrOptions;
|
||||
} else {
|
||||
throw new Error(
|
||||
`Invalid fetch arguments, must either be (string, object) or (object, undefined), received (${typeof pathOrOptions}, ${typeof options})`
|
||||
);
|
||||
}
|
||||
|
||||
const invalidHeaders = Object.keys(fullOptions.headers ?? {}).filter(headerName =>
|
||||
headerName.startsWith('kbn-')
|
||||
);
|
||||
if (invalidHeaders.length) {
|
||||
throw new Error(
|
||||
`Invalid fetch headers, headers beginning with "kbn-" are not allowed: [${invalidHeaders.join(
|
||||
','
|
||||
)}]`
|
||||
);
|
||||
}
|
||||
|
||||
return fullOptions;
|
||||
};
|
||||
|
|
|
@ -19,28 +19,31 @@
|
|||
|
||||
import { HttpInterceptController } from './http_intercept_controller';
|
||||
import { HttpInterceptHaltError } from './http_intercept_halt_error';
|
||||
import { HttpInterceptor, IHttpResponse } from './types';
|
||||
import { HttpResponse } from './response';
|
||||
import { HttpInterceptor, HttpResponse, HttpFetchOptionsWithPath } from './types';
|
||||
|
||||
export async function interceptRequest(
|
||||
request: Request,
|
||||
options: HttpFetchOptionsWithPath,
|
||||
interceptors: ReadonlySet<HttpInterceptor>,
|
||||
controller: HttpInterceptController
|
||||
): Promise<Request> {
|
||||
let next = request;
|
||||
): Promise<HttpFetchOptionsWithPath> {
|
||||
let current: HttpFetchOptionsWithPath;
|
||||
|
||||
return [...interceptors].reduceRight(
|
||||
(promise, interceptor) =>
|
||||
promise.then(
|
||||
async (current: Request) => {
|
||||
next = current;
|
||||
async fetchOptions => {
|
||||
current = fetchOptions;
|
||||
checkHalt(controller);
|
||||
|
||||
if (!interceptor.request) {
|
||||
return current;
|
||||
return fetchOptions;
|
||||
}
|
||||
|
||||
return (await interceptor.request(current, controller)) || current;
|
||||
const overrides = await interceptor.request(current, controller);
|
||||
return {
|
||||
...current,
|
||||
...overrides,
|
||||
};
|
||||
},
|
||||
async error => {
|
||||
checkHalt(controller, error);
|
||||
|
@ -49,26 +52,33 @@ export async function interceptRequest(
|
|||
throw error;
|
||||
}
|
||||
|
||||
const nextRequest = await interceptor.requestError({ error, request: next }, controller);
|
||||
const overrides = await interceptor.requestError(
|
||||
{ error, fetchOptions: current },
|
||||
controller
|
||||
);
|
||||
|
||||
if (!nextRequest) {
|
||||
if (!overrides) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
next = nextRequest;
|
||||
return next;
|
||||
current = {
|
||||
...current,
|
||||
...overrides,
|
||||
};
|
||||
return current;
|
||||
}
|
||||
),
|
||||
Promise.resolve(request)
|
||||
Promise.resolve(options)
|
||||
);
|
||||
}
|
||||
|
||||
export async function interceptResponse(
|
||||
responsePromise: Promise<IHttpResponse>,
|
||||
fetchOptions: HttpFetchOptionsWithPath,
|
||||
responsePromise: Promise<HttpResponse>,
|
||||
interceptors: ReadonlySet<HttpInterceptor>,
|
||||
controller: HttpInterceptController
|
||||
): Promise<IHttpResponse> {
|
||||
let current: IHttpResponse;
|
||||
): Promise<HttpResponse> {
|
||||
let current: HttpResponse;
|
||||
|
||||
return await [...interceptors].reduce(
|
||||
(promise, interceptor) =>
|
||||
|
@ -83,10 +93,10 @@ export async function interceptResponse(
|
|||
|
||||
const interceptorOverrides = (await interceptor.response(httpResponse, controller)) || {};
|
||||
|
||||
return new HttpResponse({
|
||||
return {
|
||||
...httpResponse,
|
||||
...interceptorOverrides,
|
||||
});
|
||||
};
|
||||
},
|
||||
async error => {
|
||||
const request = error.request || (current && current.request);
|
||||
|
@ -101,6 +111,7 @@ export async function interceptResponse(
|
|||
const next = await interceptor.responseError(
|
||||
{
|
||||
error,
|
||||
fetchOptions,
|
||||
request,
|
||||
response: error.response || (current && current.response),
|
||||
body: error.body || (current && current.body),
|
||||
|
@ -114,7 +125,7 @@ export async function interceptResponse(
|
|||
throw error;
|
||||
}
|
||||
|
||||
return new HttpResponse({ ...next, request });
|
||||
return { ...next, request, fetchOptions };
|
||||
} catch (err) {
|
||||
checkHalt(controller, err);
|
||||
throw err;
|
||||
|
|
|
@ -1,40 +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.
|
||||
*/
|
||||
|
||||
import { IHttpResponse } from './types';
|
||||
|
||||
export class HttpResponse<TResponseBody = any> implements IHttpResponse<TResponseBody> {
|
||||
public readonly request: Request;
|
||||
public readonly response?: Response;
|
||||
public readonly body?: TResponseBody;
|
||||
|
||||
constructor({
|
||||
request,
|
||||
response,
|
||||
body,
|
||||
}: {
|
||||
request: Request;
|
||||
response?: Response;
|
||||
body?: TResponseBody;
|
||||
}) {
|
||||
this.request = request;
|
||||
this.response = response;
|
||||
this.body = body;
|
||||
}
|
||||
}
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
import { MaybePromise } from '@kbn/utility-types';
|
||||
|
||||
/** @public */
|
||||
export interface HttpSetup {
|
||||
|
@ -110,7 +111,11 @@ export interface IAnonymousPaths {
|
|||
register(path: string): void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* Headers to append to the request. Any headers that begin with `kbn-` are considered private to Core and will cause
|
||||
* {@link HttpHandler} to throw an error.
|
||||
* @public
|
||||
*/
|
||||
export interface HttpHeadersInit {
|
||||
[name: string]: any;
|
||||
}
|
||||
|
@ -217,30 +222,54 @@ export interface HttpFetchOptions extends HttpRequestInit {
|
|||
headers?: HttpHeadersInit;
|
||||
|
||||
/**
|
||||
* When `true` the return type of {@link HttpHandler} will be an {@link IHttpResponse} with detailed request and
|
||||
* Whether or not the request should include the "system request" header to differentiate an end user request from
|
||||
* Kibana internal request.
|
||||
* Can be read on the server-side using KibanaRequest#isSystemRequest. Defaults to `false`.
|
||||
*/
|
||||
asSystemRequest?: boolean;
|
||||
|
||||
/**
|
||||
* When `true` the return type of {@link HttpHandler} will be an {@link HttpResponse} with detailed request and
|
||||
* response information. When `false`, the return type will just be the parsed response body. Defaults to `false`.
|
||||
*/
|
||||
asResponse?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to {@link HttpFetchOptions} but with the URL path included.
|
||||
* @public
|
||||
*/
|
||||
export interface HttpFetchOptionsWithPath extends HttpFetchOptions {
|
||||
/*
|
||||
* The path on the Kibana server to send the request to. Should not include the basePath.
|
||||
*/
|
||||
path: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* A function for making an HTTP requests to Kibana's backend. See {@link HttpFetchOptions} for options and
|
||||
* {@link IHttpResponse} for the response.
|
||||
* {@link HttpResponse} for the response.
|
||||
*
|
||||
* @param path the path on the Kibana server to send the request to. Should not include the basePath.
|
||||
* @param options {@link HttpFetchOptions}
|
||||
* @returns a Promise that resolves to a {@link IHttpResponse}
|
||||
* @returns a Promise that resolves to a {@link HttpResponse}
|
||||
* @public
|
||||
*/
|
||||
export interface HttpHandler {
|
||||
<TResponseBody = any>(path: string, options: HttpFetchOptions & { asResponse: true }): Promise<
|
||||
IHttpResponse<TResponseBody>
|
||||
HttpResponse<TResponseBody>
|
||||
>;
|
||||
<TResponseBody = any>(options: HttpFetchOptionsWithPath & { asResponse: true }): Promise<
|
||||
HttpResponse<TResponseBody>
|
||||
>;
|
||||
<TResponseBody = any>(path: string, options?: HttpFetchOptions): Promise<TResponseBody>;
|
||||
<TResponseBody = any>(options: HttpFetchOptionsWithPath): Promise<TResponseBody>;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export interface IHttpResponse<TResponseBody = any> {
|
||||
export interface HttpResponse<TResponseBody = any> {
|
||||
/** The original {@link HttpFetchOptionsWithPath} used to send this request. */
|
||||
readonly fetchOptions: Readonly<HttpFetchOptionsWithPath>;
|
||||
/** Raw request sent to Kibana server. */
|
||||
readonly request: Readonly<Request>;
|
||||
/** Raw response received, may be undefined if there was an error. */
|
||||
|
@ -276,12 +305,13 @@ export interface IHttpFetchError extends Error {
|
|||
}
|
||||
|
||||
/** @public */
|
||||
export interface HttpErrorResponse extends IHttpResponse {
|
||||
export interface HttpInterceptorResponseError extends HttpResponse {
|
||||
request: Readonly<Request>;
|
||||
error: Error | IHttpFetchError;
|
||||
}
|
||||
/** @public */
|
||||
export interface HttpErrorRequest {
|
||||
request: Request;
|
||||
export interface HttpInterceptorRequestError {
|
||||
fetchOptions: Readonly<HttpFetchOptionsWithPath>;
|
||||
error: Error;
|
||||
}
|
||||
|
||||
|
@ -298,39 +328,39 @@ export interface HttpInterceptor {
|
|||
* @param controller {@link IHttpInterceptController}
|
||||
*/
|
||||
request?(
|
||||
request: Request,
|
||||
fetchOptions: Readonly<HttpFetchOptionsWithPath>,
|
||||
controller: IHttpInterceptController
|
||||
): Promise<Request> | Request | void;
|
||||
): MaybePromise<Partial<HttpFetchOptionsWithPath>> | void;
|
||||
|
||||
/**
|
||||
* Define an interceptor to be executed if a request interceptor throws an error or returns a rejected Promise.
|
||||
* @param httpErrorRequest {@link HttpErrorRequest}
|
||||
* @param httpErrorRequest {@link HttpInterceptorRequestError}
|
||||
* @param controller {@link IHttpInterceptController}
|
||||
*/
|
||||
requestError?(
|
||||
httpErrorRequest: HttpErrorRequest,
|
||||
httpErrorRequest: HttpInterceptorRequestError,
|
||||
controller: IHttpInterceptController
|
||||
): Promise<Request> | Request | void;
|
||||
): MaybePromise<Partial<HttpFetchOptionsWithPath>> | void;
|
||||
|
||||
/**
|
||||
* Define an interceptor to be executed after a response is received.
|
||||
* @param httpResponse {@link IHttpResponse}
|
||||
* @param httpResponse {@link HttpResponse}
|
||||
* @param controller {@link IHttpInterceptController}
|
||||
*/
|
||||
response?(
|
||||
httpResponse: IHttpResponse,
|
||||
httpResponse: HttpResponse,
|
||||
controller: IHttpInterceptController
|
||||
): Promise<IHttpResponseInterceptorOverrides> | IHttpResponseInterceptorOverrides | void;
|
||||
): MaybePromise<IHttpResponseInterceptorOverrides> | void;
|
||||
|
||||
/**
|
||||
* Define an interceptor to be executed if a response interceptor throws an error or returns a rejected Promise.
|
||||
* @param httpErrorResponse {@link HttpErrorResponse}
|
||||
* @param httpErrorResponse {@link HttpInterceptorResponseError}
|
||||
* @param controller {@link IHttpInterceptController}
|
||||
*/
|
||||
responseError?(
|
||||
httpErrorResponse: HttpErrorResponse,
|
||||
httpErrorResponse: HttpInterceptorResponseError,
|
||||
controller: IHttpInterceptController
|
||||
): Promise<IHttpResponseInterceptorOverrides> | IHttpResponseInterceptorOverrides | void;
|
||||
): MaybePromise<IHttpResponseInterceptorOverrides> | void;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -144,11 +144,12 @@ export {
|
|||
HttpHeadersInit,
|
||||
HttpRequestInit,
|
||||
HttpFetchOptions,
|
||||
HttpFetchOptionsWithPath,
|
||||
HttpFetchQuery,
|
||||
HttpErrorResponse,
|
||||
HttpErrorRequest,
|
||||
HttpInterceptorResponseError,
|
||||
HttpInterceptorRequestError,
|
||||
HttpInterceptor,
|
||||
IHttpResponse,
|
||||
HttpResponse,
|
||||
HttpHandler,
|
||||
IBasePath,
|
||||
IAnonymousPaths,
|
||||
|
|
|
@ -9,6 +9,7 @@ import { EuiButtonEmptyProps } from '@elastic/eui';
|
|||
import { EuiGlobalToastListToast } from '@elastic/eui';
|
||||
import { ExclusiveUnion } from '@elastic/eui';
|
||||
import { IconType } from '@elastic/eui';
|
||||
import { MaybePromise } from '@kbn/utility-types';
|
||||
import { Observable } from 'rxjs';
|
||||
import React from 'react';
|
||||
import * as Rx from 'rxjs';
|
||||
|
@ -577,28 +578,21 @@ export type HandlerFunction<T extends object> = (context: T, ...args: any[]) =>
|
|||
// @public
|
||||
export type HandlerParameters<T extends HandlerFunction<any>> = T extends (context: any, ...args: infer U) => any ? U : never;
|
||||
|
||||
// @public (undocumented)
|
||||
export interface HttpErrorRequest {
|
||||
// (undocumented)
|
||||
error: Error;
|
||||
// (undocumented)
|
||||
request: Request;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export interface HttpErrorResponse extends IHttpResponse {
|
||||
// (undocumented)
|
||||
error: Error | IHttpFetchError;
|
||||
}
|
||||
|
||||
// @public
|
||||
export interface HttpFetchOptions extends HttpRequestInit {
|
||||
asResponse?: boolean;
|
||||
asSystemRequest?: boolean;
|
||||
headers?: HttpHeadersInit;
|
||||
prependBasePath?: boolean;
|
||||
query?: HttpFetchQuery;
|
||||
}
|
||||
|
||||
// @public
|
||||
export interface HttpFetchOptionsWithPath extends HttpFetchOptions {
|
||||
// (undocumented)
|
||||
path: string;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export interface HttpFetchQuery {
|
||||
// (undocumented)
|
||||
|
@ -610,12 +604,18 @@ export interface HttpHandler {
|
|||
// (undocumented)
|
||||
<TResponseBody = any>(path: string, options: HttpFetchOptions & {
|
||||
asResponse: true;
|
||||
}): Promise<IHttpResponse<TResponseBody>>;
|
||||
}): Promise<HttpResponse<TResponseBody>>;
|
||||
// (undocumented)
|
||||
<TResponseBody = any>(options: HttpFetchOptionsWithPath & {
|
||||
asResponse: true;
|
||||
}): Promise<HttpResponse<TResponseBody>>;
|
||||
// (undocumented)
|
||||
<TResponseBody = any>(path: string, options?: HttpFetchOptions): Promise<TResponseBody>;
|
||||
// (undocumented)
|
||||
<TResponseBody = any>(options: HttpFetchOptionsWithPath): Promise<TResponseBody>;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
// @public
|
||||
export interface HttpHeadersInit {
|
||||
// (undocumented)
|
||||
[name: string]: any;
|
||||
|
@ -623,10 +623,26 @@ export interface HttpHeadersInit {
|
|||
|
||||
// @public
|
||||
export interface HttpInterceptor {
|
||||
request?(request: Request, controller: IHttpInterceptController): Promise<Request> | Request | void;
|
||||
requestError?(httpErrorRequest: HttpErrorRequest, controller: IHttpInterceptController): Promise<Request> | Request | void;
|
||||
response?(httpResponse: IHttpResponse, controller: IHttpInterceptController): Promise<IHttpResponseInterceptorOverrides> | IHttpResponseInterceptorOverrides | void;
|
||||
responseError?(httpErrorResponse: HttpErrorResponse, controller: IHttpInterceptController): Promise<IHttpResponseInterceptorOverrides> | IHttpResponseInterceptorOverrides | void;
|
||||
request?(fetchOptions: Readonly<HttpFetchOptionsWithPath>, controller: IHttpInterceptController): MaybePromise<Partial<HttpFetchOptionsWithPath>> | void;
|
||||
requestError?(httpErrorRequest: HttpInterceptorRequestError, controller: IHttpInterceptController): MaybePromise<Partial<HttpFetchOptionsWithPath>> | void;
|
||||
response?(httpResponse: HttpResponse, controller: IHttpInterceptController): MaybePromise<IHttpResponseInterceptorOverrides> | void;
|
||||
responseError?(httpErrorResponse: HttpInterceptorResponseError, controller: IHttpInterceptController): MaybePromise<IHttpResponseInterceptorOverrides> | void;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export interface HttpInterceptorRequestError {
|
||||
// (undocumented)
|
||||
error: Error;
|
||||
// (undocumented)
|
||||
fetchOptions: Readonly<HttpFetchOptionsWithPath>;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export interface HttpInterceptorResponseError extends HttpResponse {
|
||||
// (undocumented)
|
||||
error: Error | IHttpFetchError;
|
||||
// (undocumented)
|
||||
request: Readonly<Request>;
|
||||
}
|
||||
|
||||
// @public
|
||||
|
@ -647,6 +663,14 @@ export interface HttpRequestInit {
|
|||
window?: null;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export interface HttpResponse<TResponseBody = any> {
|
||||
readonly body?: TResponseBody;
|
||||
readonly fetchOptions: Readonly<HttpFetchOptionsWithPath>;
|
||||
readonly request: Readonly<Request>;
|
||||
readonly response?: Readonly<Response>;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export interface HttpSetup {
|
||||
addLoadingCountSource(countSource$: Observable<number>): void;
|
||||
|
@ -718,13 +742,6 @@ export interface IHttpInterceptController {
|
|||
halted: boolean;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export interface IHttpResponse<TResponseBody = any> {
|
||||
readonly body?: TResponseBody;
|
||||
readonly request: Readonly<Request>;
|
||||
readonly response?: Readonly<Response>;
|
||||
}
|
||||
|
||||
// @public
|
||||
export interface IHttpResponseInterceptorOverrides<TResponseBody = any> {
|
||||
readonly body?: TResponseBody;
|
||||
|
|
|
@ -66,6 +66,57 @@ describe('KibanaRequest', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('isSytemApi property', () => {
|
||||
it('is false when no kbn-system-request header is set', () => {
|
||||
const request = httpServerMock.createRawRequest({
|
||||
headers: { custom: 'one' },
|
||||
});
|
||||
const kibanaRequest = KibanaRequest.from(request);
|
||||
expect(kibanaRequest.isSystemRequest).toBe(false);
|
||||
});
|
||||
|
||||
it('is true when kbn-system-request header is set to true', () => {
|
||||
const request = httpServerMock.createRawRequest({
|
||||
headers: { custom: 'one', 'kbn-system-request': 'true' },
|
||||
});
|
||||
const kibanaRequest = KibanaRequest.from(request);
|
||||
expect(kibanaRequest.isSystemRequest).toBe(true);
|
||||
});
|
||||
|
||||
it('is false when kbn-system-request header is set to false', () => {
|
||||
const request = httpServerMock.createRawRequest({
|
||||
headers: { custom: 'one', 'kbn-system-request': 'false' },
|
||||
});
|
||||
const kibanaRequest = KibanaRequest.from(request);
|
||||
expect(kibanaRequest.isSystemRequest).toBe(false);
|
||||
});
|
||||
|
||||
// Remove support for kbn-system-api header in 8.x. Only used by legacy platform.
|
||||
it('is false when no kbn-system-api header is set', () => {
|
||||
const request = httpServerMock.createRawRequest({
|
||||
headers: { custom: 'one' },
|
||||
});
|
||||
const kibanaRequest = KibanaRequest.from(request);
|
||||
expect(kibanaRequest.isSystemRequest).toBe(false);
|
||||
});
|
||||
|
||||
it('is true when kbn-system-api header is set to true', () => {
|
||||
const request = httpServerMock.createRawRequest({
|
||||
headers: { custom: 'one', 'kbn-system-api': 'true' },
|
||||
});
|
||||
const kibanaRequest = KibanaRequest.from(request);
|
||||
expect(kibanaRequest.isSystemRequest).toBe(true);
|
||||
});
|
||||
|
||||
it('is false when kbn-system-api header is set to false', () => {
|
||||
const request = httpServerMock.createRawRequest({
|
||||
headers: { custom: 'one', 'kbn-system-api': 'false' },
|
||||
});
|
||||
const kibanaRequest = KibanaRequest.from(request);
|
||||
expect(kibanaRequest.isSystemRequest).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('RouteSchema type inferring', () => {
|
||||
it('should work with config-schema', () => {
|
||||
const body = Buffer.from('body!');
|
||||
|
|
|
@ -127,6 +127,11 @@ export class KibanaRequest<
|
|||
* This property will contain a `filtered` copy of request headers.
|
||||
*/
|
||||
public readonly headers: Headers;
|
||||
/**
|
||||
* Whether or not the request is a "system request" rather than an application-level request.
|
||||
* Can be set on the client using the `HttpFetchOptions#asSystemRequest` option.
|
||||
*/
|
||||
public readonly isSystemRequest: boolean;
|
||||
|
||||
/** {@link IKibanaSocket} */
|
||||
public readonly socket: IKibanaSocket;
|
||||
|
@ -147,6 +152,10 @@ export class KibanaRequest<
|
|||
) {
|
||||
this.url = request.url;
|
||||
this.headers = deepFreeze({ ...request.headers });
|
||||
this.isSystemRequest =
|
||||
request.headers['kbn-system-request'] === 'true' ||
|
||||
// Remove support for `kbn-system-api` in 8.x. Used only by legacy platform.
|
||||
request.headers['kbn-system-api'] === 'true';
|
||||
|
||||
// prevent Symbol exposure via Object.getOwnPropertySymbols()
|
||||
Object.defineProperty(this, requestSymbol, {
|
||||
|
|
|
@ -888,6 +888,7 @@ export class KibanaRequest<Params = unknown, Query = unknown, Body = unknown, Me
|
|||
// @internal
|
||||
static from<P, Q, B>(req: Request, routeSchemas?: RouteValidator<P, Q, B> | RouteValidatorFullConfig<P, Q, B>, withoutSecretHeaders?: boolean): KibanaRequest<P, Q, B, any>;
|
||||
readonly headers: Headers;
|
||||
readonly isSystemRequest: boolean;
|
||||
// (undocumented)
|
||||
readonly params: Params;
|
||||
// (undocumented)
|
||||
|
|
|
@ -24,6 +24,7 @@ const SYSTEM_API_HEADER_NAME = 'kbn-system-api';
|
|||
*
|
||||
* @param request HAPI request object
|
||||
* @return true if request is a system API request; false, otherwise
|
||||
* @deprecated Use KibanaRequest#isSystemApi
|
||||
*/
|
||||
export function isSystemApiRequest(request) {
|
||||
return !!request.headers[SYSTEM_API_HEADER_NAME];
|
||||
|
|
|
@ -32,6 +32,7 @@ export interface KFetchQuery {
|
|||
export interface KFetchOptions extends HttpRequestInit {
|
||||
pathname: string;
|
||||
query?: KFetchQuery;
|
||||
asSystemRequest?: boolean;
|
||||
}
|
||||
|
||||
export interface KFetchKibanaOptions {
|
||||
|
|
|
@ -44,10 +44,8 @@ describe('Sync search strategy', () => {
|
|||
},
|
||||
{}
|
||||
);
|
||||
expect(mockCoreSetup.http.fetch.mock.calls[0][0]).toBe(
|
||||
`/internal/search/${SYNC_SEARCH_STRATEGY}`
|
||||
);
|
||||
expect(mockCoreSetup.http.fetch.mock.calls[0][1]).toEqual({
|
||||
expect(mockCoreSetup.http.fetch.mock.calls[0][0]).toEqual({
|
||||
path: `/internal/search/${SYNC_SEARCH_STRATEGY}`,
|
||||
body: JSON.stringify({
|
||||
serverStrategy: 'SYNC_SEARCH_STRATEGY',
|
||||
}),
|
||||
|
|
|
@ -36,14 +36,12 @@ export const syncSearchStrategyProvider: TSearchStrategyProvider<typeof SYNC_SEA
|
|||
request: ISyncSearchRequest,
|
||||
options: ISearchOptions = {}
|
||||
) => {
|
||||
const response: Promise<IKibanaSearchResponse> = context.core.http.fetch(
|
||||
`/internal/search/${request.serverStrategy}`,
|
||||
{
|
||||
method: 'POST',
|
||||
body: JSON.stringify(request),
|
||||
signal: options.signal,
|
||||
}
|
||||
);
|
||||
const response: Promise<IKibanaSearchResponse> = context.core.http.fetch({
|
||||
path: `/internal/search/${request.serverStrategy}`,
|
||||
method: 'POST',
|
||||
body: JSON.stringify(request),
|
||||
signal: options.signal,
|
||||
});
|
||||
|
||||
return from(response);
|
||||
};
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { CoreSetup, Plugin, PluginInitializerContext } from 'kibana/public';
|
||||
import { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from 'kibana/public';
|
||||
import { CorePluginAPluginSetup } from '../../core_plugin_a/public/plugin';
|
||||
|
||||
declare global {
|
||||
|
@ -52,7 +52,17 @@ export class CorePluginBPlugin
|
|||
};
|
||||
}
|
||||
|
||||
public start() {}
|
||||
public async start(core: CoreStart, deps: {}) {
|
||||
return {
|
||||
sendSystemRequest: async (asSystemRequest: boolean) => {
|
||||
const response = await core.http.post<string>('/core_plugin_b/system_request', {
|
||||
asSystemRequest,
|
||||
});
|
||||
return `/core_plugin_b/system_request says: "${response}"`;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public stop() {}
|
||||
}
|
||||
|
||||
|
|
|
@ -54,6 +54,16 @@ export class CorePluginBPlugin implements Plugin {
|
|||
return res.ok({ body: `ID: ${req.query.id} - ${req.body.bar.toUpperCase()}` });
|
||||
}
|
||||
);
|
||||
|
||||
router.post(
|
||||
{
|
||||
path: '/core_plugin_b/system_request',
|
||||
validate: false,
|
||||
},
|
||||
async (context, req, res) => {
|
||||
return res.ok({ body: `System request? ${req.isSystemRequest}` });
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public start() {}
|
||||
|
|
|
@ -54,5 +54,15 @@ export default function({ getService }: PluginFunctionalProviderContext) {
|
|||
statusCode: 400,
|
||||
});
|
||||
});
|
||||
|
||||
it('sets request.isSystemRequest when kbn-system-request header is set', async () => {
|
||||
await supertest
|
||||
.post('/core_plugin_b/system_request')
|
||||
.set('kbn-xsrf', 'anything')
|
||||
.set('kbn-system-request', 'true')
|
||||
.send()
|
||||
.expect(200)
|
||||
.expect('System request? true');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ export default function({ getService, getPageObjects }: PluginFunctionalProvider
|
|||
});
|
||||
});
|
||||
|
||||
describe('have env data provided', function describeIndexTests() {
|
||||
describe('have env data provided', () => {
|
||||
before(async () => {
|
||||
await PageObjects.common.navigateToApp('bar');
|
||||
});
|
||||
|
@ -75,5 +75,27 @@ export default function({ getService, getPageObjects }: PluginFunctionalProvider
|
|||
expect(envData.packageInfo.version).to.be.a('string');
|
||||
});
|
||||
});
|
||||
|
||||
describe('http fetching', () => {
|
||||
before(async () => {
|
||||
await PageObjects.common.navigateToApp('settings');
|
||||
});
|
||||
|
||||
it('should send kbn-system-request header when asSystemRequest: true', async () => {
|
||||
expect(
|
||||
await browser.executeAsync(async cb => {
|
||||
window.__coreProvider.start.plugins.core_plugin_b.sendSystemRequest(true).then(cb);
|
||||
})
|
||||
).to.be('/core_plugin_b/system_request says: "System request? true"');
|
||||
});
|
||||
|
||||
it('should not send kbn-system-request header when asSystemRequest: false', async () => {
|
||||
expect(
|
||||
await browser.executeAsync(async cb => {
|
||||
window.__coreProvider.start.plugins.core_plugin_b.sendSystemRequest(false).then(cb);
|
||||
})
|
||||
).to.be('/core_plugin_b/system_request says: "System request? false"');
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -278,8 +278,8 @@ describe('IndexPattern Data Panel', () => {
|
|||
|
||||
function testProps() {
|
||||
const setState = jest.fn();
|
||||
core.http.get.mockImplementation(async (url: string) => {
|
||||
const parts = url.split('/');
|
||||
core.http.get.mockImplementation(async ({ path }) => {
|
||||
const parts = path.split('/');
|
||||
const indexPatternTitle = parts[parts.length - 1];
|
||||
return {
|
||||
indexPatternTitle: `${indexPatternTitle}_testtitle`,
|
||||
|
@ -397,7 +397,8 @@ describe('IndexPattern Data Panel', () => {
|
|||
expect(setState).toHaveBeenCalledTimes(2);
|
||||
expect(core.http.get).toHaveBeenCalledTimes(2);
|
||||
|
||||
expect(core.http.get).toHaveBeenCalledWith('/api/lens/existing_fields/a', {
|
||||
expect(core.http.get).toHaveBeenCalledWith({
|
||||
path: '/api/lens/existing_fields/a',
|
||||
query: {
|
||||
fromDate: '2019-01-01',
|
||||
toDate: '2020-01-01',
|
||||
|
@ -405,7 +406,8 @@ describe('IndexPattern Data Panel', () => {
|
|||
},
|
||||
});
|
||||
|
||||
expect(core.http.get).toHaveBeenCalledWith('/api/lens/existing_fields/a', {
|
||||
expect(core.http.get).toHaveBeenCalledWith({
|
||||
path: '/api/lens/existing_fields/a',
|
||||
query: {
|
||||
fromDate: '2019-01-01',
|
||||
toDate: '2020-01-02',
|
||||
|
@ -436,7 +438,8 @@ describe('IndexPattern Data Panel', () => {
|
|||
|
||||
expect(setState).toHaveBeenCalledTimes(2);
|
||||
|
||||
expect(core.http.get).toHaveBeenCalledWith('/api/lens/existing_fields/a', {
|
||||
expect(core.http.get).toHaveBeenCalledWith({
|
||||
path: '/api/lens/existing_fields/a',
|
||||
query: {
|
||||
fromDate: '2019-01-01',
|
||||
toDate: '2020-01-01',
|
||||
|
@ -444,7 +447,8 @@ describe('IndexPattern Data Panel', () => {
|
|||
},
|
||||
});
|
||||
|
||||
expect(core.http.get).toHaveBeenCalledWith('/api/lens/existing_fields/b', {
|
||||
expect(core.http.get).toHaveBeenCalledWith({
|
||||
path: '/api/lens/existing_fields/b',
|
||||
query: {
|
||||
fromDate: '2019-01-01',
|
||||
toDate: '2020-01-01',
|
||||
|
@ -484,13 +488,13 @@ describe('IndexPattern Data Panel', () => {
|
|||
let overlapCount = 0;
|
||||
const props = testProps();
|
||||
|
||||
core.http.get.mockImplementation((url: string) => {
|
||||
core.http.get.mockImplementation(({ path }) => {
|
||||
if (queryCount) {
|
||||
++overlapCount;
|
||||
}
|
||||
++queryCount;
|
||||
|
||||
const parts = url.split('/');
|
||||
const parts = path.split('/');
|
||||
const indexPatternTitle = parts[parts.length - 1];
|
||||
const result = Promise.resolve({
|
||||
indexPatternTitle,
|
||||
|
|
|
@ -537,8 +537,8 @@ describe('loader', () => {
|
|||
describe('syncExistingFields', () => {
|
||||
it('should call once for each index pattern', async () => {
|
||||
const setState = jest.fn();
|
||||
const fetchJson = jest.fn(async (url: string) => {
|
||||
const indexPatternTitle = _.last(url.split('/'));
|
||||
const fetchJson = jest.fn(({ path }: { path: string }) => {
|
||||
const indexPatternTitle = _.last(path.split('/'));
|
||||
return {
|
||||
indexPatternTitle,
|
||||
existingFieldNames: ['field_1', 'field_2'].map(
|
||||
|
|
|
@ -235,7 +235,8 @@ export async function syncExistingFields({
|
|||
query.timeFieldName = pattern.timeFieldName;
|
||||
}
|
||||
|
||||
return fetchJson(`${BASE_API_URL}/existing_fields/${pattern.id}`, {
|
||||
return fetchJson({
|
||||
path: `${BASE_API_URL}/existing_fields/${pattern.id}`,
|
||||
query,
|
||||
}) as Promise<ExistingFields>;
|
||||
})
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
*/
|
||||
|
||||
import { kfetch } from 'ui/kfetch';
|
||||
// @ts-ignore
|
||||
import { addSystemApiHeader } from 'ui/system_api';
|
||||
|
||||
const API_BASE_URL = '/api/reporting/jobs';
|
||||
|
||||
|
@ -64,7 +62,7 @@ class JobQueueClient {
|
|||
method: 'GET',
|
||||
pathname: `${API_BASE_URL}/list`,
|
||||
query,
|
||||
headers: addSystemApiHeader({}),
|
||||
asSystemRequest: true,
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -72,7 +70,7 @@ class JobQueueClient {
|
|||
return kfetch({
|
||||
method: 'GET',
|
||||
pathname: `${API_BASE_URL}/count`,
|
||||
headers: addSystemApiHeader({}),
|
||||
asSystemRequest: true,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -80,7 +78,7 @@ class JobQueueClient {
|
|||
return kfetch({
|
||||
method: 'GET',
|
||||
pathname: `${API_BASE_URL}/output/${jobId}`,
|
||||
headers: addSystemApiHeader({}),
|
||||
asSystemRequest: true,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -88,7 +86,7 @@ class JobQueueClient {
|
|||
return kfetch({
|
||||
method: 'GET',
|
||||
pathname: `${API_BASE_URL}/info/${jobId}`,
|
||||
headers: addSystemApiHeader({}),
|
||||
asSystemRequest: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ const buildRequest = (path = '/app/kibana') => {
|
|||
return {
|
||||
path,
|
||||
route: { settings: {} },
|
||||
headers: {},
|
||||
raw: {
|
||||
req: {
|
||||
socket: {},
|
||||
|
|
|
@ -64,10 +64,8 @@ describe('licensing plugin', () => {
|
|||
|
||||
await refresh();
|
||||
|
||||
expect(coreSetup.http.get.mock.calls[0][1]).toMatchObject({
|
||||
headers: {
|
||||
'kbn-system-api': 'true',
|
||||
},
|
||||
expect(coreSetup.http.get.mock.calls[0][0]).toMatchObject({
|
||||
asSystemRequest: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -132,10 +132,9 @@ export class LicensingPlugin implements Plugin<LicensingPluginSetup> {
|
|||
|
||||
private fetchLicense = async (core: CoreSetup): Promise<ILicense> => {
|
||||
try {
|
||||
const response = await core.http.get(this.infoEndpoint, {
|
||||
headers: {
|
||||
'kbn-system-api': 'true',
|
||||
},
|
||||
const response = await core.http.get({
|
||||
path: this.infoEndpoint,
|
||||
asSystemRequest: true,
|
||||
});
|
||||
return new License({
|
||||
license: response.license,
|
||||
|
|
|
@ -23,7 +23,7 @@ export class AuthenticationService {
|
|||
return {
|
||||
async getCurrentUser() {
|
||||
return (await http.get('/internal/security/me', {
|
||||
headers: { 'kbn-system-api': true },
|
||||
asSystemRequest: true,
|
||||
})) as AuthenticatedUser;
|
||||
},
|
||||
};
|
||||
|
|
|
@ -155,7 +155,7 @@ function getProps({
|
|||
|
||||
const { fatalErrors } = coreMock.createSetup();
|
||||
const { http, docLinks, notifications } = coreMock.createStart();
|
||||
http.get.mockImplementation(async path => {
|
||||
http.get.mockImplementation(async (path: any) => {
|
||||
if (path === '/api/features') {
|
||||
return buildFeatures();
|
||||
}
|
||||
|
@ -509,7 +509,7 @@ describe('<EditRolePage />', () => {
|
|||
|
||||
it('can render if features are not available', async () => {
|
||||
const { http } = coreMock.createStart();
|
||||
http.get.mockImplementation(async path => {
|
||||
http.get.mockImplementation(async (path: any) => {
|
||||
if (path === '/api/features') {
|
||||
const error = { response: { status: 404 } };
|
||||
throw error;
|
||||
|
|
|
@ -16,7 +16,7 @@ describe('RolesAPIClient', () => {
|
|||
await rolesAPIClient.saveRole({ role, spacesEnabled });
|
||||
expect(httpMock.put).toHaveBeenCalledTimes(1);
|
||||
|
||||
return JSON.parse(httpMock.put.mock.calls[0][1]?.body as any);
|
||||
return JSON.parse((httpMock.put.mock.calls[0] as any)[1]?.body as any);
|
||||
}
|
||||
|
||||
describe('spaces disabled', () => {
|
||||
|
|
|
@ -104,9 +104,8 @@ export class SessionTimeout implements ISessionTimeout {
|
|||
*/
|
||||
private fetchSessionInfoAndResetTimers = async (extend = false) => {
|
||||
const method = extend ? 'POST' : 'GET';
|
||||
const headers = extend ? {} : { 'kbn-system-api': 'true' };
|
||||
try {
|
||||
const result = await this.http.fetch(SESSION_ROUTE, { method, headers });
|
||||
const result = await this.http.fetch(SESSION_ROUTE, { method, asSystemRequest: !extend });
|
||||
|
||||
this.handleSessionInfoAndResetTimers(result);
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ describe('response', () => {
|
|||
http.intercept(interceptor);
|
||||
fetchMock.mock('*', 200);
|
||||
|
||||
await http.fetch('/foo-api', { headers: { 'kbn-system-api': 'true' } });
|
||||
await http.fetch('/foo-api', { asSystemRequest: true });
|
||||
|
||||
expect(sessionTimeoutMock.extend).not.toHaveBeenCalled();
|
||||
});
|
||||
|
@ -99,9 +99,9 @@ describe('responseError', () => {
|
|||
http.intercept(interceptor);
|
||||
fetchMock.mock('*', 401);
|
||||
|
||||
await expect(
|
||||
http.fetch('/foo-api', { headers: { 'kbn-system-api': 'true' } })
|
||||
).rejects.toMatchInlineSnapshot(`[Error: Unauthorized]`);
|
||||
await expect(http.fetch('/foo-api', { asSystemRequest: true })).rejects.toMatchInlineSnapshot(
|
||||
`[Error: Unauthorized]`
|
||||
);
|
||||
|
||||
expect(sessionTimeoutMock.extend).not.toHaveBeenCalled();
|
||||
});
|
||||
|
|
|
@ -6,38 +6,34 @@
|
|||
|
||||
import {
|
||||
HttpInterceptor,
|
||||
HttpErrorResponse,
|
||||
IHttpResponse,
|
||||
HttpInterceptorResponseError,
|
||||
HttpResponse,
|
||||
IAnonymousPaths,
|
||||
} from 'src/core/public';
|
||||
|
||||
import { ISessionTimeout } from './session_timeout';
|
||||
|
||||
const isSystemAPIRequest = (request: Request) => {
|
||||
return request.headers.has('kbn-system-api');
|
||||
};
|
||||
|
||||
export class SessionTimeoutHttpInterceptor implements HttpInterceptor {
|
||||
constructor(private sessionTimeout: ISessionTimeout, private anonymousPaths: IAnonymousPaths) {}
|
||||
|
||||
response(httpResponse: IHttpResponse) {
|
||||
response(httpResponse: HttpResponse) {
|
||||
if (this.anonymousPaths.isAnonymous(window.location.pathname)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isSystemAPIRequest(httpResponse.request)) {
|
||||
if (httpResponse.fetchOptions.asSystemRequest) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.sessionTimeout.extend(httpResponse.request.url);
|
||||
}
|
||||
|
||||
responseError(httpErrorResponse: HttpErrorResponse) {
|
||||
responseError(httpErrorResponse: HttpInterceptorResponseError) {
|
||||
if (this.anonymousPaths.isAnonymous(window.location.pathname)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isSystemAPIRequest(httpErrorResponse.request)) {
|
||||
if (httpErrorResponse.fetchOptions.asSystemRequest) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
import {
|
||||
HttpInterceptor,
|
||||
HttpErrorResponse,
|
||||
HttpInterceptorResponseError,
|
||||
IHttpInterceptController,
|
||||
IAnonymousPaths,
|
||||
} from 'src/core/public';
|
||||
|
@ -16,7 +16,10 @@ import { SessionExpired } from './session_expired';
|
|||
export class UnauthorizedResponseHttpInterceptor implements HttpInterceptor {
|
||||
constructor(private sessionExpired: SessionExpired, private anonymousPaths: IAnonymousPaths) {}
|
||||
|
||||
responseError(httpErrorResponse: HttpErrorResponse, controller: IHttpInterceptController) {
|
||||
responseError(
|
||||
httpErrorResponse: HttpInterceptorResponseError,
|
||||
controller: IHttpInterceptController
|
||||
) {
|
||||
if (this.anonymousPaths.isAnonymous(window.location.pathname)) {
|
||||
return;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue