Improve typings (#813)
The ApiResponse now accepts a generics that defaults to any, same for every API method that might need a body.
This commit is contained in:
committed by
GitHub
parent
2919f93b73
commit
a21281fc48
@ -29,10 +29,13 @@ function buildDataFrameGetDataFrameTransformStats (opts) {
|
|||||||
* Perform a [data_frame.get_data_frame_transform_stats](https://www.elastic.co/guide/en/elasticsearch/reference/current/get-data-frame-transform-stats.html) request
|
* Perform a [data_frame.get_data_frame_transform_stats](https://www.elastic.co/guide/en/elasticsearch/reference/current/get-data-frame-transform-stats.html) request
|
||||||
*
|
*
|
||||||
* @param {string} transform_id - The id of the transform for which to get stats. '_all' or '*' implies all transforms
|
* @param {string} transform_id - The id of the transform for which to get stats. '_all' or '*' implies all transforms
|
||||||
|
* @param {number} from - skips a number of transform stats, defaults to 0
|
||||||
|
* @param {number} size - specifies a max number of transform stats to get, defaults to 100
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const acceptedQuerystring = [
|
const acceptedQuerystring = [
|
||||||
|
'from',
|
||||||
|
'size'
|
||||||
]
|
]
|
||||||
|
|
||||||
const snakeCase = {
|
const snakeCase = {
|
||||||
|
|||||||
374
api/requestParams.d.ts
vendored
374
api/requestParams.d.ts
vendored
File diff suppressed because it is too large
Load Diff
@ -4352,6 +4352,12 @@ link:{ref}/get-data-frame-transform-stats.html[Reference]
|
|||||||
|`transform_id` or `transformId`
|
|`transform_id` or `transformId`
|
||||||
|`string` - The id of the transform for which to get stats. '_all' or '*' implies all transforms
|
|`string` - The id of the transform for which to get stats. '_all' or '*' implies all transforms
|
||||||
|
|
||||||
|
|`from`
|
||||||
|
|`number` - skips a number of transform stats, defaults to 0
|
||||||
|
|
||||||
|
|`size`
|
||||||
|
|`number` - specifies a max number of transform stats to get, defaults to 100
|
||||||
|
|
||||||
|===
|
|===
|
||||||
|
|
||||||
=== dataFrame.previewDataFrameTransform
|
=== dataFrame.previewDataFrameTransform
|
||||||
|
|||||||
@ -3,58 +3,146 @@
|
|||||||
|
|
||||||
The client offers a first-class support for TypeScript, since it ships the type definitions for every exposed API.
|
The client offers a first-class support for TypeScript, since it ships the type definitions for every exposed API.
|
||||||
|
|
||||||
While the client offers type definitions for Request parameters, Request bodies and responses are shipped with `any` because there is not an official spec that defines them, so we cannot make guarantees over them (but since they are shipped with `any`, you can easily override them with your own typing definitions).
|
|
||||||
|
|
||||||
NOTE: If you are using TypeScript you will be required to use _snake_case_ style to define the API parameters instead of _camelCase_.
|
NOTE: If you are using TypeScript you will be required to use _snake_case_ style to define the API parameters instead of _camelCase_.
|
||||||
|
|
||||||
=== How to extend the provided typings?
|
Other than the types for the surface API, the client offers the types for every request method, via the `RequestParams`, if you need the types for a search request for instance, you can access them via `RequestParams.Search`.
|
||||||
Extend the provided typings is very straightforward, you should declare a custom `.d.ts` file and then write inside your type extensions, following there is an example of how do it.
|
Every API that supports a body, accepts a https://www.typescriptlang.org/docs/handbook/generics.html[generics] which represents the type of the request body, if you don't configure anything, it will default to `any`.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
[source,ts]
|
[source,ts]
|
||||||
----
|
----
|
||||||
declare module '@elastic/elasticsearch' {
|
import { RequestParams } from '@elastic/elasticsearch'
|
||||||
export interface ShardsResponse {
|
|
||||||
total: number;
|
|
||||||
successful: number;
|
|
||||||
failed: number;
|
|
||||||
skipped: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Explanation {
|
interface SearchBody {
|
||||||
value: number;
|
query: {
|
||||||
description: string;
|
match: { foo: string }
|
||||||
details: Explanation[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SearchResponse<T> {
|
|
||||||
took: number;
|
|
||||||
timed_out: boolean;
|
|
||||||
_scroll_id?: string;
|
|
||||||
_shards: ShardsResponse;
|
|
||||||
hits: {
|
|
||||||
total: number;
|
|
||||||
max_score: number;
|
|
||||||
hits: Array<{
|
|
||||||
_index: string;
|
|
||||||
_type: string;
|
|
||||||
_id: string;
|
|
||||||
_score: number;
|
|
||||||
_source: T;
|
|
||||||
_version?: number;
|
|
||||||
_explanation?: Explanation;
|
|
||||||
fields?: any;
|
|
||||||
highlight?: any;
|
|
||||||
inner_hits?: any;
|
|
||||||
matched_queries?: string[];
|
|
||||||
sort?: string[];
|
|
||||||
}>;
|
|
||||||
};
|
|
||||||
aggregations?: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MSearchResponse<T> {
|
|
||||||
responses?: Array<SearchResponse<T>>;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export {};
|
const searchParams: RequestParams.Search<SearchBody> = {
|
||||||
|
index: 'test',
|
||||||
|
body: {
|
||||||
|
query: {
|
||||||
|
match: { foo: 'bar' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is valid as well
|
||||||
|
const searchParams: RequestParams.Search = {
|
||||||
|
index: 'test',
|
||||||
|
body: {
|
||||||
|
query: {
|
||||||
|
match: { foo: 'bar' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
----
|
||||||
|
|
||||||
|
You can find the type definiton of a response in `ApiResponse`, which accepts a generics as well if you want to specify the body type, otherwise it defaults to `any`.
|
||||||
|
|
||||||
|
[source,ts]
|
||||||
|
----
|
||||||
|
interface SearchResponse<T> {
|
||||||
|
hits: {
|
||||||
|
hits: Array<{
|
||||||
|
_source: T;
|
||||||
|
}>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define the intefrace of the source object
|
||||||
|
interface Source {
|
||||||
|
foo: string
|
||||||
|
}
|
||||||
|
|
||||||
|
client.search(searchParams)
|
||||||
|
.then((response: ApiResponse<SearchResponse<Source>>) => console.log(response))
|
||||||
|
.catch((err: Error) => {})
|
||||||
|
----
|
||||||
|
|
||||||
|
=== A complete example
|
||||||
|
|
||||||
|
[source,ts]
|
||||||
|
----
|
||||||
|
import {
|
||||||
|
Client,
|
||||||
|
// Object that contains the type definitions of every API method
|
||||||
|
RequestParams,
|
||||||
|
// Interface of the generic API response
|
||||||
|
ApiResponse,
|
||||||
|
} from '@elastic/elasticsearch'
|
||||||
|
|
||||||
|
const client = new Client({ node: 'http://localhost:9200' })
|
||||||
|
|
||||||
|
// Define the type of the body for the Search request
|
||||||
|
interface SearchBody {
|
||||||
|
query: {
|
||||||
|
match: { foo: string }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Complete definition of the Search response
|
||||||
|
interface ShardsResponse {
|
||||||
|
total: number;
|
||||||
|
successful: number;
|
||||||
|
failed: number;
|
||||||
|
skipped: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Explanation {
|
||||||
|
value: number;
|
||||||
|
description: string;
|
||||||
|
details: Explanation[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SearchResponse<T> {
|
||||||
|
took: number;
|
||||||
|
timed_out: boolean;
|
||||||
|
_scroll_id?: string;
|
||||||
|
_shards: ShardsResponse;
|
||||||
|
hits: {
|
||||||
|
total: number;
|
||||||
|
max_score: number;
|
||||||
|
hits: Array<{
|
||||||
|
_index: string;
|
||||||
|
_type: string;
|
||||||
|
_id: string;
|
||||||
|
_score: number;
|
||||||
|
_source: T;
|
||||||
|
_version?: number;
|
||||||
|
_explanation?: Explanation;
|
||||||
|
fields?: any;
|
||||||
|
highlight?: any;
|
||||||
|
inner_hits?: any;
|
||||||
|
matched_queries?: string[];
|
||||||
|
sort?: string[];
|
||||||
|
}>;
|
||||||
|
};
|
||||||
|
aggregations?: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define the intefrace of the source object
|
||||||
|
interface Source {
|
||||||
|
foo: string
|
||||||
|
}
|
||||||
|
|
||||||
|
async function run (): Promise<void> {
|
||||||
|
// Define the search parameters
|
||||||
|
const searchParams: RequestParams.Search<SearchBody> = {
|
||||||
|
index: 'test',
|
||||||
|
body: {
|
||||||
|
query: {
|
||||||
|
match: { foo: 'bar' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Craft the final type definition
|
||||||
|
const response: ApiResponse<SearchResponse<Source>> = await client.search(searchParams)
|
||||||
|
console.log(response.body)
|
||||||
|
}
|
||||||
|
|
||||||
|
run().catch(console.log)
|
||||||
----
|
----
|
||||||
|
|||||||
4
lib/Transport.d.ts
vendored
4
lib/Transport.d.ts
vendored
@ -49,7 +49,7 @@ interface TransportOptions {
|
|||||||
headers?: anyObject;
|
headers?: anyObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RequestEvent {
|
export interface RequestEvent<T = any> {
|
||||||
body: any;
|
body: any;
|
||||||
statusCode: number | null;
|
statusCode: number | null;
|
||||||
headers: anyObject | null;
|
headers: anyObject | null;
|
||||||
@ -71,7 +71,7 @@ export interface RequestEvent {
|
|||||||
|
|
||||||
// ApiResponse and RequestEvent are the same thing
|
// ApiResponse and RequestEvent are the same thing
|
||||||
// we are doing this for have more clear names
|
// we are doing this for have more clear names
|
||||||
export interface ApiResponse extends RequestEvent {}
|
export interface ApiResponse<T = any> extends RequestEvent<T> {}
|
||||||
|
|
||||||
declare type anyObject = {
|
declare type anyObject = {
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
|
|||||||
@ -74,10 +74,10 @@ export interface Generic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const code = `
|
const code = `
|
||||||
export interface ${name[0].toUpperCase() + name.slice(1)} extends Generic {
|
export interface ${name[0].toUpperCase() + name.slice(1)}${body ? '<T = any>' : ''} extends Generic {
|
||||||
${partsArr.map(genLine).join('\n ')}
|
${partsArr.map(genLine).join('\n ')}
|
||||||
${paramsArr.map(genLine).join('\n ')}
|
${paramsArr.map(genLine).join('\n ')}
|
||||||
${body ? `body${body.required ? '' : '?'}: any;` : ''}
|
${body ? `body${body.required ? '' : '?'}: T;` : ''}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
import {
|
import {
|
||||||
Client,
|
Client,
|
||||||
ApiResponse,
|
ApiResponse,
|
||||||
|
RequestParams,
|
||||||
RequestEvent,
|
RequestEvent,
|
||||||
ResurrectEvent,
|
ResurrectEvent,
|
||||||
events,
|
events,
|
||||||
@ -94,6 +95,40 @@ client.index({
|
|||||||
.then((result: ApiResponse) => {})
|
.then((result: ApiResponse) => {})
|
||||||
.catch((err: Error) => {})
|
.catch((err: Error) => {})
|
||||||
|
|
||||||
|
// --- Use generics ---
|
||||||
|
// Define the search parameters
|
||||||
|
interface SearchBody {
|
||||||
|
query: {
|
||||||
|
match: { foo: string }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const searchParams: RequestParams.Search<SearchBody> = {
|
||||||
|
index: 'test',
|
||||||
|
body: {
|
||||||
|
query: {
|
||||||
|
match: { foo: 'bar' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dewfine the interface of the search response
|
||||||
|
interface SearchResponse<T> {
|
||||||
|
hits: {
|
||||||
|
hits: Array<{
|
||||||
|
_source: T;
|
||||||
|
}>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define the intefrace of the source object
|
||||||
|
interface Source {
|
||||||
|
foo: string
|
||||||
|
}
|
||||||
|
|
||||||
|
client.search(searchParams)
|
||||||
|
.then((response: ApiResponse<SearchResponse<Source>>) => console.log(response))
|
||||||
|
.catch((err: Error) => {})
|
||||||
|
|
||||||
// extend client
|
// extend client
|
||||||
client.extend('namespace.method', (options: ClientExtendsCallbackOptions) => {
|
client.extend('namespace.method', (options: ClientExtendsCallbackOptions) => {
|
||||||
return function (params: any) {
|
return function (params: any) {
|
||||||
|
|||||||
Reference in New Issue
Block a user