Skip to content
Merged
4,507 changes: 2,253 additions & 2,254 deletions index.d.ts

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions lib/Helpers.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@
// See the LICENSE file in the project root for more information

import { Readable as ReadableStream } from 'stream'
import { TransportRequestOptions, ApiResponse, RequestBody, ResponseBody } from './Transport'
import { TransportRequestOptions, ApiResponse, RequestBody } from './Transport'
import { Search, Bulk } from '../api/requestParams'

export default class Helpers {
search<TRequestBody extends RequestBody, TDocument = unknown>(params: Search<TRequestBody>, options?: TransportRequestOptions): Promise<TDocument[]>
scrollSearch<TRequestBody extends RequestBody, TDocument = unknown, TResponse = ResponseBody, TContext = unknown>(params: Search<TRequestBody>, options?: TransportRequestOptions): AsyncIterable<ScrollSearchResponse<TDocument, TResponse, TContext>>
scrollDocuments<TRequestBody extends RequestBody, TDocument = unknown>(params: Search<TRequestBody>, options?: TransportRequestOptions): AsyncIterable<TDocument>
search<TDocument = unknown, TRequestBody extends RequestBody = Record<string, any>>(params: Search<TRequestBody>, options?: TransportRequestOptions): Promise<TDocument[]>
scrollSearch<TDocument = unknown, TResponse = Record<string, any>, TRequestBody extends RequestBody = Record<string, any>, TContext = unknown>(params: Search<TRequestBody>, options?: TransportRequestOptions): AsyncIterable<ScrollSearchResponse<TDocument, TResponse, TContext>>
scrollDocuments<TDocument = unknown, TRequestBody extends RequestBody = Record<string, any>>(params: Search<TRequestBody>, options?: TransportRequestOptions): AsyncIterable<TDocument>
bulk<TDocument = unknown>(options: BulkHelperOptions<TDocument>): BulkHelper<BulkStats>
}

export interface ScrollSearchResponse<TDocument = unknown, TResponse = ResponseBody, TContext = unknown> extends ApiResponse<TResponse, TContext> {
export interface ScrollSearchResponse<TDocument = unknown, TResponse = Record<string, any>, TContext = unknown> extends ApiResponse<TResponse, TContext> {
clear: () => Promise<void>
documents: TDocument[]
}
Expand Down
9 changes: 4 additions & 5 deletions lib/Transport.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ interface TransportOptions {
opaqueIdPrefix?: string;
}

export interface RequestEvent<TResponse = ResponseBody, TContext = unknown> {
export interface RequestEvent<TResponse = Record<string, any>, TContext = unknown> {
body: TResponse;
statusCode: number | null;
headers: Record<string, any> | null;
Expand All @@ -70,11 +70,10 @@ export interface RequestEvent<TResponse = ResponseBody, TContext = unknown> {

// ApiResponse and RequestEvent are the same thing
// we are doing this for have more clear names
export interface ApiResponse<TResponse = ResponseBody, TContext = unknown> extends RequestEvent<TResponse, TContext> {}
export interface ApiResponse<TResponse = Record<string, any>, TContext = unknown> extends RequestEvent<TResponse, TContext> {}

export type RequestBody<T = Record<string, any>> = T | string | Buffer | ReadableStream
export type RequestNDBody<T = Record<string, any>[]> = T | string[] | Buffer | ReadableStream
export type ResponseBody<T = Record<string, any>> = T | string | boolean | ReadableStream
export type RequestBody<T = Record<string, any>> = T | string | Buffer | ReadableStream
export type RequestNDBody<T = Record<string, any>[]> = T | string | string[] | Buffer | ReadableStream

export interface TransportRequestParams {
method: string;
Expand Down
24 changes: 12 additions & 12 deletions lib/errors.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,31 @@
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information

import { ApiResponse, ResponseBody } from './Transport'
import { ApiResponse } from './Transport'

export declare class ElasticsearchClientError extends Error {
name: string;
message: string;
}

export declare class TimeoutError extends ElasticsearchClientError {
export declare class TimeoutError<TResponse = Record<string, any>, TContext = unknown> extends ElasticsearchClientError {
name: string;
message: string;
meta: ApiResponse;
meta: ApiResponse<TResponse, TContext>;
constructor(message: string, meta: ApiResponse);
}

export declare class ConnectionError extends ElasticsearchClientError {
export declare class ConnectionError<TResponse = Record<string, any>, TContext = unknown> extends ElasticsearchClientError {
name: string;
message: string;
meta: ApiResponse;
meta: ApiResponse<TResponse, TContext>;
constructor(message: string, meta: ApiResponse);
}

export declare class NoLivingConnectionsError extends ElasticsearchClientError {
export declare class NoLivingConnectionsError<TResponse = Record<string, any>, TContext = unknown> extends ElasticsearchClientError {
name: string;
message: string;
meta: ApiResponse;
meta: ApiResponse<TResponse, TContext>;
constructor(message: string, meta: ApiResponse);
}

Expand All @@ -50,19 +50,19 @@ export declare class ConfigurationError extends ElasticsearchClientError {
constructor(message: string);
}

export declare class ResponseError extends ElasticsearchClientError {
export declare class ResponseError<TResponse = Record<string, any>, TContext = unknown> extends ElasticsearchClientError {
name: string;
message: string;
meta: ApiResponse;
body: ResponseBody;
meta: ApiResponse<TResponse, TContext>;
body: TResponse;
statusCode: number;
headers: Record<string, any>;
constructor(meta: ApiResponse);
}

export declare class RequestAbortedError extends ElasticsearchClientError {
export declare class RequestAbortedError<TResponse = Record<string, any>, TContext = unknown> extends ElasticsearchClientError {
name: string;
message: string;
meta: ApiResponse;
meta: ApiResponse<TResponse, TContext>;
constructor(message: string, meta: ApiResponse);
}
33 changes: 17 additions & 16 deletions scripts/utils/generateMain.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,36 +180,37 @@ function toPascalCase (str) {
function buildMethodDefinition (api, name, hasBody) {
const Name = toPascalCase(name)
const bodyType = ndjsonApiKey.includes(Name) ? 'RequestNDBody' : 'RequestBody'
const defaultBodyType = ndjsonApiKey.includes(Name) ? 'Record<string, any>[]' : 'Record<string, any>'

if (hasBody) {
let methods = [
{ key: `${api}<TRequestBody extends ${bodyType}, TResponse = ResponseBody, TContext = unknown>(params?: RequestParams.${Name}<TRequestBody>, options?: TransportRequestOptions)`, val: `TransportRequestPromise<ApiResponse<TResponse, TContext>>` },
{ key: `${api}<TRequestBody extends ${bodyType}, TResponse = ResponseBody, TContext = unknown>(callback: callbackFn<TResponse, TContext>)`, val: `TransportRequestCallback` },
{ key: `${api}<TRequestBody extends ${bodyType}, TResponse = ResponseBody, TContext = unknown>(params: RequestParams.${Name}<TRequestBody>, callback: callbackFn<TResponse, TContext>)`, val: `TransportRequestCallback` },
{ key: `${api}<TRequestBody extends ${bodyType}, TResponse = ResponseBody, TContext = unknown>(params: RequestParams.${Name}<TRequestBody>, options: TransportRequestOptions, callback: callbackFn<TResponse, TContext>)`, val: `TransportRequestCallback` }
{ key: `${api}<TResponse = Record<string, any>, TRequestBody extends ${bodyType} = ${defaultBodyType}, TContext = unknown>(params?: RequestParams.${Name}<TRequestBody>, options?: TransportRequestOptions)`, val: `TransportRequestPromise<ApiResponse<TResponse, TContext>>` },
{ key: `${api}<TResponse = Record<string, any>, TRequestBody extends ${bodyType} = ${defaultBodyType}, TContext = unknown>(callback: callbackFn<TResponse, TContext>)`, val: `TransportRequestCallback` },
{ key: `${api}<TResponse = Record<string, any>, TRequestBody extends ${bodyType} = ${defaultBodyType}, TContext = unknown>(params: RequestParams.${Name}<TRequestBody>, callback: callbackFn<TResponse, TContext>)`, val: `TransportRequestCallback` },
{ key: `${api}<TResponse = Record<string, any>, TRequestBody extends ${bodyType} = ${defaultBodyType}, TContext = unknown>(params: RequestParams.${Name}<TRequestBody>, options: TransportRequestOptions, callback: callbackFn<TResponse, TContext>)`, val: `TransportRequestCallback` }
]
if (isSnakeCased(api)) {
methods = methods.concat([
{ key: `${camelify(api)}<TRequestBody extends ${bodyType}, TResponse = ResponseBody, TContext = unknown>(params?: RequestParams.${Name}<TRequestBody>, options?: TransportRequestOptions)`, val: `TransportRequestPromise<ApiResponse<TResponse, TContext>>` },
{ key: `${camelify(api)}<TRequestBody extends ${bodyType}, TResponse = ResponseBody, TContext = unknown>(callback: callbackFn<TResponse, TContext>)`, val: `TransportRequestCallback` },
{ key: `${camelify(api)}<TRequestBody extends ${bodyType}, TResponse = ResponseBody, TContext = unknown>(params: RequestParams.${Name}<TRequestBody>, callback: callbackFn<TResponse, TContext>)`, val: `TransportRequestCallback` },
{ key: `${camelify(api)}<TRequestBody extends ${bodyType}, TResponse = ResponseBody, TContext = unknown>(params: RequestParams.${Name}<TRequestBody>, options: TransportRequestOptions, callback: callbackFn<TResponse, TContext>)`, val: `TransportRequestCallback` }
{ key: `${camelify(api)}<TResponse = Record<string, any>, TRequestBody extends ${bodyType} = ${defaultBodyType}, TContext = unknown>(params?: RequestParams.${Name}<TRequestBody>, options?: TransportRequestOptions)`, val: `TransportRequestPromise<ApiResponse<TResponse, TContext>>` },
{ key: `${camelify(api)}<TResponse = Record<string, any>, TRequestBody extends ${bodyType} = ${defaultBodyType}, TContext = unknown>(callback: callbackFn<TResponse, TContext>)`, val: `TransportRequestCallback` },
{ key: `${camelify(api)}<TResponse = Record<string, any>, TRequestBody extends ${bodyType} = ${defaultBodyType}, TContext = unknown>(params: RequestParams.${Name}<TRequestBody>, callback: callbackFn<TResponse, TContext>)`, val: `TransportRequestCallback` },
{ key: `${camelify(api)}<TResponse = Record<string, any>, TRequestBody extends ${bodyType} = ${defaultBodyType}, TContext = unknown>(params: RequestParams.${Name}<TRequestBody>, options: TransportRequestOptions, callback: callbackFn<TResponse, TContext>)`, val: `TransportRequestCallback` }
])
}
return methods
} else {
let methods = [
{ key: `${api}<TResponse = ResponseBody, TContext = unknown>(params?: RequestParams.${Name}, options?: TransportRequestOptions)`, val: `TransportRequestPromise<ApiResponse<TResponse, TContext>>` },
{ key: `${api}<TResponse = ResponseBody, TContext = unknown>(callback: callbackFn<TResponse, TContext>)`, val: `TransportRequestCallback` },
{ key: `${api}<TResponse = ResponseBody, TContext = unknown>(params: RequestParams.${Name}, callback: callbackFn<TResponse, TContext>)`, val: `TransportRequestCallback` },
{ key: `${api}<TResponse = ResponseBody, TContext = unknown>(params: RequestParams.${Name}, options: TransportRequestOptions, callback: callbackFn<TResponse, TContext>)`, val: `TransportRequestCallback` }
{ key: `${api}<TResponse = Record<string, any>, TContext = unknown>(params?: RequestParams.${Name}, options?: TransportRequestOptions)`, val: `TransportRequestPromise<ApiResponse<TResponse, TContext>>` },
{ key: `${api}<TResponse = Record<string, any>, TContext = unknown>(callback: callbackFn<TResponse, TContext>)`, val: `TransportRequestCallback` },
{ key: `${api}<TResponse = Record<string, any>, TContext = unknown>(params: RequestParams.${Name}, callback: callbackFn<TResponse, TContext>)`, val: `TransportRequestCallback` },
{ key: `${api}<TResponse = Record<string, any>, TContext = unknown>(params: RequestParams.${Name}, options: TransportRequestOptions, callback: callbackFn<TResponse, TContext>)`, val: `TransportRequestCallback` }
]
if (isSnakeCased(api)) {
methods = methods.concat([
{ key: `${camelify(api)}<TResponse = ResponseBody, TContext = unknown>(params?: RequestParams.${Name}, options?: TransportRequestOptions)`, val: `TransportRequestPromise<ApiResponse<TResponse, TContext>>` },
{ key: `${camelify(api)}<TResponse = ResponseBody, TContext = unknown>(callback: callbackFn<TResponse, TContext>)`, val: `TransportRequestCallback` },
{ key: `${camelify(api)}<TResponse = ResponseBody, TContext = unknown>(params: RequestParams.${Name}, callback: callbackFn<TResponse, TContext>)`, val: `TransportRequestCallback` },
{ key: `${camelify(api)}<TResponse = ResponseBody, TContext = unknown>(params: RequestParams.${Name}, options: TransportRequestOptions, callback: callbackFn<TResponse, TContext>)`, val: `TransportRequestCallback` }
{ key: `${camelify(api)}<TResponse = Record<string, any>, TContext = unknown>(params?: RequestParams.${Name}, options?: TransportRequestOptions)`, val: `TransportRequestPromise<ApiResponse<TResponse, TContext>>` },
{ key: `${camelify(api)}<TResponse = Record<string, any>, TContext = unknown>(callback: callbackFn<TResponse, TContext>)`, val: `TransportRequestCallback` },
{ key: `${camelify(api)}<TResponse = Record<string, any>, TContext = unknown>(params: RequestParams.${Name}, callback: callbackFn<TResponse, TContext>)`, val: `TransportRequestCallback` },
{ key: `${camelify(api)}<TResponse = Record<string, any>, TContext = unknown>(params: RequestParams.${Name}, options: TransportRequestOptions, callback: callbackFn<TResponse, TContext>)`, val: `TransportRequestCallback` }
])
}
return methods
Expand Down
165 changes: 153 additions & 12 deletions test/types/api-response-body.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
// See the LICENSE file in the project root for more information

import { expectType, expectError } from 'tsd'
import { ResponseBody } from '../../lib/Transport'
import { Client } from '../../'
import { Readable as ReadableStream } from 'stream';
import { TransportRequestCallback } from '../../lib/Transport'
import { Client, ApiError } from '../../'

const client = new Client({
node: 'http://localhost:9200'
Expand Down Expand Up @@ -59,15 +60,15 @@ interface Source {
foo: string
}

// Use a bad body
// body that does not respect the RequestBody constraint
expectError(
client.search({
index: 'hello',
body: 42
}).then(console.log)
)

// No generics
// No generics (promise style)
{
const response = await client.search({
index: 'test',
Expand All @@ -78,13 +79,13 @@ expectError(
}
})

expectType<ResponseBody>(response.body)
expectType<Record<string, any>>(response.body)
expectType<unknown>(response.meta.context)
}

// Define only the request body
// Define only the response body (promise style)
{
const response = await client.search<SearchBody>({
const response = await client.search<SearchResponse<Source>>({
Comment thread
delvedor marked this conversation as resolved.
index: 'test',
body: {
query: {
Expand All @@ -93,13 +94,13 @@ expectError(
}
})

expectType<ResponseBody>(response.body)
expectType<SearchResponse<Source>>(response.body)
expectType<unknown>(response.meta.context)
}

// Define request body and response body
// Define response body and request body (promise style)
{
const response = await client.search<SearchBody, SearchResponse<Source>>({
const response = await client.search<SearchResponse<Source>, SearchBody>({
index: 'test',
body: {
query: {
Expand All @@ -112,9 +113,9 @@ expectError(
expectType<unknown>(response.meta.context)
}

// Define request body, response body and the context
// Define response body, request body and the context (promise style)
{
const response = await client.search<SearchBody, SearchResponse<Source>, string>({
const response = await client.search<SearchResponse<Source>, SearchBody, string>({
index: 'test',
body: {
query: {
Expand All @@ -126,3 +127,143 @@ expectError(
expectType<SearchResponse<Source>>(response.body)
expectType<string>(response.meta.context)
}

// Send request body as string (promise style)
{
Comment thread
delvedor marked this conversation as resolved.
const response = await client.search({
index: 'test',
body: 'hello world'
})

expectType<Record<string, any>>(response.body)
expectType<unknown>(response.meta.context)
}

// Send request body as buffer (promise style)
{
const response = await client.search({
index: 'test',
body: Buffer.from('hello world')
})

expectType<Record<string, any>>(response.body)
expectType<unknown>(response.meta.context)
}

// Send request body as readable stream (promise style)
{
const response = await client.search({
index: 'test',
body: new ReadableStream()
})

expectType<Record<string, any>>(response.body)
expectType<unknown>(response.meta.context)
}

// No generics (callback style)
{
const result = client.search({
index: 'test',
body: {
query: {
match: { foo: 'bar' }
}
}
}, (err, response) => {
expectType<ApiError>(err)
expectType<Record<string, any>>(response.body)
expectType<unknown>(response.meta.context)
})
expectType<TransportRequestCallback>(result)
}

// Define only the response body (callback style)
{
const result = client.search<SearchResponse<Source>>({
index: 'test',
body: {
query: {
match: { foo: 'bar' }
}
}
}, (err, response) => {
expectType<ApiError>(err)
expectType<SearchResponse<Source>>(response.body)
expectType<unknown>(response.meta.context)
})
expectType<TransportRequestCallback>(result)
}

// Define response body and request body (callback style)
{
const result = client.search<SearchResponse<Source>, SearchBody>({
index: 'test',
body: {
query: {
match: { foo: 'bar' }
}
}
}, (err, response) => {
expectType<ApiError>(err)
expectType<SearchResponse<Source>>(response.body)
expectType<unknown>(response.meta.context)
})
expectType<TransportRequestCallback>(result)
}

// Define response body, request body and the context (callback style)
{
const result = client.search<SearchResponse<Source>, SearchBody, string>({
index: 'test',
body: {
query: {
match: { foo: 'bar' }
}
}
}, (err, response) => {
expectType<ApiError>(err)
expectType<SearchResponse<Source>>(response.body)
expectType<string>(response.meta.context)
})
expectType<TransportRequestCallback>(result)
}

// Send request body as string (callback style)
{
const result = client.search({
index: 'test',
body: 'hello world'
}, (err, response) => {
expectType<ApiError>(err)
expectType<Record<string, any>>(response.body)
expectType<unknown>(response.meta.context)
})
expectType<TransportRequestCallback>(result)
}

// Send request body as buffer (callback style)
{
const result = client.search({
index: 'test',
body: Buffer.from('hello world')
}, (err, response) => {
expectType<ApiError>(err)
expectType<Record<string, any>>(response.body)
expectType<unknown>(response.meta.context)
})
expectType<TransportRequestCallback>(result)
}

// Send request body as readable stream (callback style)
{
const result = client.search({
index: 'test',
body: new ReadableStream()
}, (err, response) => {
expectType<ApiError>(err)
expectType<Record<string, any>>(response.body)
expectType<unknown>(response.meta.context)
})
expectType<TransportRequestCallback>(result)
}
Loading