Refactored type definitions (#1119)

* Updated types generation script

* Refactored api method definitions

* Updated test
- Removed old test code
- Added tsd dev dependency
- Rewritten test with tsd

* Removed unused dependencies

* Fixed definition

* Updated test

* Updated docs

* Improved events type definitions

* Updated test

* Minor fixes in the type definitons

* More type test

* Improved Transport type definitions

* Updated test

* Addressed comments

* Code generation

* Use RequestBody, Response and Context everywhere, also default Context to unknown

* Updated test

* body -> hasBody

* Fixed conflicts

* Updated code generation

* Improved request body type definition

* Updated code generation

* Use BodyType for both request and reponses generics
- Use extends for defining the RequestBody generic to force the user
  following the same shape.
- BodyType and NDBodyType now accepts a generics to allow injecting
  more specific types in the future

* API generation

* Updated test

* Updated docs

* Use BodyType also in ReponseError

* Removed useless client generics

* Renamed generics and types
- prefixed all generics with a T
- BodyType => RequestBody
- NDBodyType => RequestNDBody
- Added ResponseBody

* Updated test

* Updated docs

* Test ResponseBody as well

* Simplify overloads

* API generation

* Updated test

* Updated error types
This commit is contained in:
Tomas Della Vedova
2020-03-23 11:38:18 +01:00
committed by GitHub
parent a80f510a9a
commit 6c82a4967e
23 changed files with 3838 additions and 955 deletions

226
api/requestParams.d.ts vendored
View File

@ -2,6 +2,8 @@
// 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 { RequestBody, RequestNDBody } from '../lib/Transport'
export interface Generic {
method?: string;
ignore?: number | number[];
@ -12,7 +14,7 @@ export interface Generic {
source?: string;
}
export interface Bulk<T = any> extends Generic {
export interface Bulk<T = RequestNDBody> extends Generic {
index?: string;
type?: string;
_source_exclude?: string | string[];
@ -249,12 +251,12 @@ export interface CatThreadPool extends Generic {
v?: boolean;
}
export interface ClearScroll<T = any> extends Generic {
export interface ClearScroll<T = RequestBody> extends Generic {
scroll_id?: string | string[];
body?: T;
}
export interface ClusterAllocationExplain<T = any> extends Generic {
export interface ClusterAllocationExplain<T = RequestBody> extends Generic {
include_yes_decisions?: boolean;
include_disk_info?: boolean;
body?: T;
@ -299,7 +301,7 @@ export interface ClusterPendingTasks extends Generic {
master_timeout?: string;
}
export interface ClusterPutComponentTemplate<T = any> extends Generic {
export interface ClusterPutComponentTemplate<T = RequestBody> extends Generic {
name: string;
create?: boolean;
timeout?: string;
@ -307,7 +309,7 @@ export interface ClusterPutComponentTemplate<T = any> extends Generic {
body: T;
}
export interface ClusterPutSettings<T = any> extends Generic {
export interface ClusterPutSettings<T = RequestBody> extends Generic {
flat_settings?: boolean;
master_timeout?: string;
timeout?: string;
@ -317,7 +319,7 @@ export interface ClusterPutSettings<T = any> extends Generic {
export interface ClusterRemoteInfo extends Generic {
}
export interface ClusterReroute<T = any> extends Generic {
export interface ClusterReroute<T = RequestBody> extends Generic {
dry_run?: boolean;
explain?: boolean;
retry_failed?: boolean;
@ -346,7 +348,7 @@ export interface ClusterStats extends Generic {
timeout?: string;
}
export interface Count<T = any> extends Generic {
export interface Count<T = RequestBody> extends Generic {
index?: string | string[];
ignore_unavailable?: boolean;
ignore_throttled?: boolean;
@ -365,7 +367,7 @@ export interface Count<T = any> extends Generic {
body?: T;
}
export interface Create<T = any> extends Generic {
export interface Create<T = RequestBody> extends Generic {
id: string;
index: string;
type?: string;
@ -393,7 +395,7 @@ export interface Delete extends Generic {
version_type?: 'internal' | 'external' | 'external_gte';
}
export interface DeleteByQuery<T = any> extends Generic {
export interface DeleteByQuery<T = RequestBody> extends Generic {
index: string | string[];
_source_exclude?: string | string[];
_source_include?: string | string[];
@ -477,7 +479,7 @@ export interface ExistsSource extends Generic {
version_type?: 'internal' | 'external' | 'external_gte';
}
export interface Explain<T = any> extends Generic {
export interface Explain<T = RequestBody> extends Generic {
id: string;
index: string;
_source_exclude?: string | string[];
@ -550,7 +552,7 @@ export interface GetSource extends Generic {
version_type?: 'internal' | 'external' | 'external_gte';
}
export interface Index<T = any> extends Generic {
export interface Index<T = RequestBody> extends Generic {
id?: string;
index: string;
wait_for_active_shards?: string;
@ -566,7 +568,7 @@ export interface Index<T = any> extends Generic {
body: T;
}
export interface IndicesAnalyze<T = any> extends Generic {
export interface IndicesAnalyze<T = RequestBody> extends Generic {
index?: string;
body?: T;
}
@ -582,7 +584,7 @@ export interface IndicesClearCache extends Generic {
request?: boolean;
}
export interface IndicesClone<T = any> extends Generic {
export interface IndicesClone<T = RequestBody> extends Generic {
index: string;
target: string;
timeout?: string;
@ -601,7 +603,7 @@ export interface IndicesClose extends Generic {
wait_for_active_shards?: string;
}
export interface IndicesCreate<T = any> extends Generic {
export interface IndicesCreate<T = RequestBody> extends Generic {
index: string;
wait_for_active_shards?: string;
timeout?: string;
@ -609,7 +611,7 @@ export interface IndicesCreate<T = any> extends Generic {
body?: T;
}
export interface IndicesCreateDataStream<T = any> extends Generic {
export interface IndicesCreateDataStream<T = RequestBody> extends Generic {
name: string;
body: T;
}
@ -773,7 +775,7 @@ export interface IndicesOpen extends Generic {
wait_for_active_shards?: string;
}
export interface IndicesPutAlias<T = any> extends Generic {
export interface IndicesPutAlias<T = RequestBody> extends Generic {
index: string | string[];
name: string;
timeout?: string;
@ -781,7 +783,7 @@ export interface IndicesPutAlias<T = any> extends Generic {
body?: T;
}
export interface IndicesPutMapping<T = any> extends Generic {
export interface IndicesPutMapping<T = RequestBody> extends Generic {
index: string | string[];
timeout?: string;
master_timeout?: string;
@ -791,7 +793,7 @@ export interface IndicesPutMapping<T = any> extends Generic {
body: T;
}
export interface IndicesPutSettings<T = any> extends Generic {
export interface IndicesPutSettings<T = RequestBody> extends Generic {
index?: string | string[];
master_timeout?: string;
timeout?: string;
@ -803,7 +805,7 @@ export interface IndicesPutSettings<T = any> extends Generic {
body: T;
}
export interface IndicesPutTemplate<T = any> extends Generic {
export interface IndicesPutTemplate<T = RequestBody> extends Generic {
name: string;
order?: number;
create?: boolean;
@ -824,7 +826,7 @@ export interface IndicesRefresh extends Generic {
expand_wildcards?: 'open' | 'closed' | 'hidden' | 'none' | 'all';
}
export interface IndicesRollover<T = any> extends Generic {
export interface IndicesRollover<T = RequestBody> extends Generic {
alias: string;
new_index?: string;
timeout?: string;
@ -850,7 +852,7 @@ export interface IndicesShardStores extends Generic {
expand_wildcards?: 'open' | 'closed' | 'hidden' | 'none' | 'all';
}
export interface IndicesShrink<T = any> extends Generic {
export interface IndicesShrink<T = RequestBody> extends Generic {
index: string;
target: string;
timeout?: string;
@ -859,7 +861,7 @@ export interface IndicesShrink<T = any> extends Generic {
body?: T;
}
export interface IndicesSplit<T = any> extends Generic {
export interface IndicesSplit<T = RequestBody> extends Generic {
index: string;
target: string;
timeout?: string;
@ -883,7 +885,7 @@ export interface IndicesStats extends Generic {
forbid_closed_indices?: boolean;
}
export interface IndicesUpdateAliases<T = any> extends Generic {
export interface IndicesUpdateAliases<T = RequestBody> extends Generic {
timeout?: string;
master_timeout?: string;
body: T;
@ -898,7 +900,7 @@ export interface IndicesUpgrade extends Generic {
only_ancient_segments?: boolean;
}
export interface IndicesValidateQuery<T = any> extends Generic {
export interface IndicesValidateQuery<T = RequestBody> extends Generic {
index?: string | string[];
type?: string | string[];
explain?: boolean;
@ -933,20 +935,20 @@ export interface IngestGetPipeline extends Generic {
export interface IngestProcessorGrok extends Generic {
}
export interface IngestPutPipeline<T = any> extends Generic {
export interface IngestPutPipeline<T = RequestBody> extends Generic {
id: string;
master_timeout?: string;
timeout?: string;
body: T;
}
export interface IngestSimulate<T = any> extends Generic {
export interface IngestSimulate<T = RequestBody> extends Generic {
id?: string;
verbose?: boolean;
body: T;
}
export interface Mget<T = any> extends Generic {
export interface Mget<T = RequestBody> extends Generic {
index?: string;
_source_exclude?: string | string[];
_source_include?: string | string[];
@ -961,7 +963,7 @@ export interface Mget<T = any> extends Generic {
body: T;
}
export interface Msearch<T = any> extends Generic {
export interface Msearch<T = RequestNDBody> extends Generic {
index?: string | string[];
search_type?: 'query_then_fetch' | 'query_and_fetch' | 'dfs_query_then_fetch' | 'dfs_query_and_fetch';
max_concurrent_searches?: number;
@ -973,7 +975,7 @@ export interface Msearch<T = any> extends Generic {
body: T;
}
export interface MsearchTemplate<T = any> extends Generic {
export interface MsearchTemplate<T = RequestNDBody> extends Generic {
index?: string | string[];
search_type?: 'query_then_fetch' | 'query_and_fetch' | 'dfs_query_then_fetch' | 'dfs_query_and_fetch';
typed_keys?: boolean;
@ -983,7 +985,7 @@ export interface MsearchTemplate<T = any> extends Generic {
body: T;
}
export interface Mtermvectors<T = any> extends Generic {
export interface Mtermvectors<T = RequestBody> extends Generic {
index?: string;
ids?: string | string[];
term_statistics?: boolean;
@ -1045,7 +1047,7 @@ export interface NodesUsage extends Generic {
export interface Ping extends Generic {
}
export interface PutScript<T = any> extends Generic {
export interface PutScript<T = RequestBody> extends Generic {
id: string;
context?: string;
timeout?: string;
@ -1053,7 +1055,7 @@ export interface PutScript<T = any> extends Generic {
body: T;
}
export interface RankEval<T = any> extends Generic {
export interface RankEval<T = RequestBody> extends Generic {
index?: string | string[];
ignore_unavailable?: boolean;
allow_no_indices?: boolean;
@ -1062,7 +1064,7 @@ export interface RankEval<T = any> extends Generic {
body: T;
}
export interface Reindex<T = any> extends Generic {
export interface Reindex<T = RequestBody> extends Generic {
refresh?: boolean;
timeout?: string;
wait_for_active_shards?: string;
@ -1079,23 +1081,23 @@ export interface ReindexRethrottle extends Generic {
requests_per_second: number;
}
export interface RenderSearchTemplate<T = any> extends Generic {
export interface RenderSearchTemplate<T = RequestBody> extends Generic {
id?: string;
body?: T;
}
export interface ScriptsPainlessExecute<T = any> extends Generic {
export interface ScriptsPainlessExecute<T = RequestBody> extends Generic {
body?: T;
}
export interface Scroll<T = any> extends Generic {
export interface Scroll<T = RequestBody> extends Generic {
scroll_id?: string;
scroll?: string;
rest_total_hits_as_int?: boolean;
body?: T;
}
export interface Search<T = any> extends Generic {
export interface Search<T = RequestBody> extends Generic {
index?: string | string[];
_source_exclude?: string | string[];
_source_include?: string | string[];
@ -1154,7 +1156,7 @@ export interface SearchShards extends Generic {
expand_wildcards?: 'open' | 'closed' | 'hidden' | 'none' | 'all';
}
export interface SearchTemplate<T = any> extends Generic {
export interface SearchTemplate<T = RequestBody> extends Generic {
index?: string | string[];
ignore_unavailable?: boolean;
ignore_throttled?: boolean;
@ -1172,14 +1174,14 @@ export interface SearchTemplate<T = any> extends Generic {
body: T;
}
export interface SnapshotCleanupRepository<T = any> extends Generic {
export interface SnapshotCleanupRepository<T = RequestBody> extends Generic {
repository: string;
master_timeout?: string;
timeout?: string;
body?: T;
}
export interface SnapshotCreate<T = any> extends Generic {
export interface SnapshotCreate<T = RequestBody> extends Generic {
repository: string;
snapshot: string;
master_timeout?: string;
@ -1187,7 +1189,7 @@ export interface SnapshotCreate<T = any> extends Generic {
body?: T;
}
export interface SnapshotCreateRepository<T = any> extends Generic {
export interface SnapshotCreateRepository<T = RequestBody> extends Generic {
repository: string;
master_timeout?: string;
timeout?: string;
@ -1221,7 +1223,7 @@ export interface SnapshotGetRepository extends Generic {
local?: boolean;
}
export interface SnapshotRestore<T = any> extends Generic {
export interface SnapshotRestore<T = RequestBody> extends Generic {
repository: string;
snapshot: string;
master_timeout?: string;
@ -1265,7 +1267,7 @@ export interface TasksList extends Generic {
timeout?: string;
}
export interface Termvectors<T = any> extends Generic {
export interface Termvectors<T = RequestBody> extends Generic {
index: string;
id?: string;
term_statistics?: boolean;
@ -1282,7 +1284,7 @@ export interface Termvectors<T = any> extends Generic {
body?: T;
}
export interface Update<T = any> extends Generic {
export interface Update<T = RequestBody> extends Generic {
id: string;
index: string;
type?: string;
@ -1302,7 +1304,7 @@ export interface Update<T = any> extends Generic {
body: T;
}
export interface UpdateByQuery<T = any> extends Generic {
export interface UpdateByQuery<T = RequestBody> extends Generic {
index: string | string[];
_source_exclude?: string | string[];
_source_include?: string | string[];
@ -1359,7 +1361,7 @@ export interface AsyncSearchGet extends Generic {
typed_keys?: boolean;
}
export interface AsyncSearchSubmit<T = any> extends Generic {
export interface AsyncSearchSubmit<T = RequestBody> extends Generic {
index?: string | string[];
_source_exclude?: string | string[];
_source_include?: string | string[];
@ -1463,7 +1465,7 @@ export interface CcrDeleteAutoFollowPattern extends Generic {
name: string;
}
export interface CcrFollow<T = any> extends Generic {
export interface CcrFollow<T = RequestBody> extends Generic {
index: string;
wait_for_active_shards?: string;
body: T;
@ -1477,7 +1479,7 @@ export interface CcrFollowStats extends Generic {
index: string | string[];
}
export interface CcrForgetFollower<T = any> extends Generic {
export interface CcrForgetFollower<T = RequestBody> extends Generic {
index: string;
body: T;
}
@ -1494,7 +1496,7 @@ export interface CcrPauseFollow extends Generic {
index: string;
}
export interface CcrPutAutoFollowPattern<T = any> extends Generic {
export interface CcrPutAutoFollowPattern<T = RequestBody> extends Generic {
name: string;
body: T;
}
@ -1503,7 +1505,7 @@ export interface CcrResumeAutoFollowPattern extends Generic {
name: string;
}
export interface CcrResumeFollow<T = any> extends Generic {
export interface CcrResumeFollow<T = RequestBody> extends Generic {
index: string;
body?: T;
}
@ -1534,11 +1536,11 @@ export interface DataFrameTransformDeprecatedGetTransformStats extends Generic {
allow_no_match?: boolean;
}
export interface DataFrameTransformDeprecatedPreviewTransform<T = any> extends Generic {
export interface DataFrameTransformDeprecatedPreviewTransform<T = RequestBody> extends Generic {
body: T;
}
export interface DataFrameTransformDeprecatedPutTransform<T = any> extends Generic {
export interface DataFrameTransformDeprecatedPutTransform<T = RequestBody> extends Generic {
transform_id: string;
defer_validation?: boolean;
body: T;
@ -1556,7 +1558,7 @@ export interface DataFrameTransformDeprecatedStopTransform extends Generic {
allow_no_match?: boolean;
}
export interface DataFrameTransformDeprecatedUpdateTransform<T = any> extends Generic {
export interface DataFrameTransformDeprecatedUpdateTransform<T = RequestBody> extends Generic {
transform_id: string;
defer_validation?: boolean;
body: T;
@ -1575,7 +1577,7 @@ export interface EnrichGetPolicy extends Generic {
name?: string | string[];
}
export interface EnrichPutPolicy<T = any> extends Generic {
export interface EnrichPutPolicy<T = RequestBody> extends Generic {
name: string;
body: T;
}
@ -1583,12 +1585,12 @@ export interface EnrichPutPolicy<T = any> extends Generic {
export interface EnrichStats extends Generic {
}
export interface EqlSearch<T = any> extends Generic {
export interface EqlSearch<T = RequestBody> extends Generic {
index: string;
body: T;
}
export interface GraphExplore<T = any> extends Generic {
export interface GraphExplore<T = RequestBody> extends Generic {
index: string | string[];
routing?: string;
timeout?: string;
@ -1612,12 +1614,12 @@ export interface IlmGetLifecycle extends Generic {
export interface IlmGetStatus extends Generic {
}
export interface IlmMoveToStep<T = any> extends Generic {
export interface IlmMoveToStep<T = RequestBody> extends Generic {
index: string;
body?: T;
}
export interface IlmPutLifecycle<T = any> extends Generic {
export interface IlmPutLifecycle<T = RequestBody> extends Generic {
policy: string;
body?: T;
}
@ -1677,7 +1679,7 @@ export interface LicenseGetBasicStatus extends Generic {
export interface LicenseGetTrialStatus extends Generic {
}
export interface LicensePost<T = any> extends Generic {
export interface LicensePost<T = RequestBody> extends Generic {
acknowledge?: boolean;
body?: T;
}
@ -1695,7 +1697,7 @@ export interface MigrationDeprecations extends Generic {
index?: string;
}
export interface MlCloseJob<T = any> extends Generic {
export interface MlCloseJob<T = RequestBody> extends Generic {
job_id: string;
allow_no_jobs?: boolean;
force?: boolean;
@ -1756,20 +1758,20 @@ export interface MlDeleteTrainedModel extends Generic {
model_id: string;
}
export interface MlEstimateModelMemory<T = any> extends Generic {
export interface MlEstimateModelMemory<T = RequestBody> extends Generic {
body: T;
}
export interface MlEvaluateDataFrame<T = any> extends Generic {
export interface MlEvaluateDataFrame<T = RequestBody> extends Generic {
body: T;
}
export interface MlExplainDataFrameAnalytics<T = any> extends Generic {
export interface MlExplainDataFrameAnalytics<T = RequestBody> extends Generic {
id?: string;
body?: T;
}
export interface MlFindFileStructure<T = any> extends Generic {
export interface MlFindFileStructure<T = RequestNDBody> extends Generic {
lines_to_sample?: number;
line_merge_size_limit?: number;
timeout?: string;
@ -1787,7 +1789,7 @@ export interface MlFindFileStructure<T = any> extends Generic {
body: T;
}
export interface MlFlushJob<T = any> extends Generic {
export interface MlFlushJob<T = RequestBody> extends Generic {
job_id: string;
calc_interim?: boolean;
start?: string;
@ -1803,7 +1805,7 @@ export interface MlForecast extends Generic {
expires_in?: string;
}
export interface MlGetBuckets<T = any> extends Generic {
export interface MlGetBuckets<T = RequestBody> extends Generic {
job_id: string;
timestamp?: string;
expand?: boolean;
@ -1827,14 +1829,14 @@ export interface MlGetCalendarEvents extends Generic {
size?: number;
}
export interface MlGetCalendars<T = any> extends Generic {
export interface MlGetCalendars<T = RequestBody> extends Generic {
calendar_id?: string;
from?: number;
size?: number;
body?: T;
}
export interface MlGetCategories<T = any> extends Generic {
export interface MlGetCategories<T = RequestBody> extends Generic {
job_id: string;
category_id?: number;
from?: number;
@ -1872,7 +1874,7 @@ export interface MlGetFilters extends Generic {
size?: number;
}
export interface MlGetInfluencers<T = any> extends Generic {
export interface MlGetInfluencers<T = RequestBody> extends Generic {
job_id: string;
exclude_interim?: boolean;
from?: number;
@ -1895,7 +1897,7 @@ export interface MlGetJobs extends Generic {
allow_no_jobs?: boolean;
}
export interface MlGetModelSnapshots<T = any> extends Generic {
export interface MlGetModelSnapshots<T = RequestBody> extends Generic {
job_id: string;
snapshot_id?: string;
from?: number;
@ -1907,7 +1909,7 @@ export interface MlGetModelSnapshots<T = any> extends Generic {
body?: T;
}
export interface MlGetOverallBuckets<T = any> extends Generic {
export interface MlGetOverallBuckets<T = RequestBody> extends Generic {
job_id: string;
top_n?: number;
bucket_span?: string;
@ -1919,7 +1921,7 @@ export interface MlGetOverallBuckets<T = any> extends Generic {
body?: T;
}
export interface MlGetRecords<T = any> extends Generic {
export interface MlGetRecords<T = RequestBody> extends Generic {
job_id: string;
exclude_interim?: boolean;
from?: number;
@ -1956,12 +1958,12 @@ export interface MlOpenJob extends Generic {
job_id: string;
}
export interface MlPostCalendarEvents<T = any> extends Generic {
export interface MlPostCalendarEvents<T = RequestBody> extends Generic {
calendar_id: string;
body: T;
}
export interface MlPostData<T = any> extends Generic {
export interface MlPostData<T = RequestBody> extends Generic {
job_id: string;
reset_start?: string;
reset_end?: string;
@ -1972,7 +1974,7 @@ export interface MlPreviewDatafeed extends Generic {
datafeed_id: string;
}
export interface MlPutCalendar<T = any> extends Generic {
export interface MlPutCalendar<T = RequestBody> extends Generic {
calendar_id: string;
body?: T;
}
@ -1982,12 +1984,12 @@ export interface MlPutCalendarJob extends Generic {
job_id: string;
}
export interface MlPutDataFrameAnalytics<T = any> extends Generic {
export interface MlPutDataFrameAnalytics<T = RequestBody> extends Generic {
id: string;
body: T;
}
export interface MlPutDatafeed<T = any> extends Generic {
export interface MlPutDatafeed<T = RequestBody> extends Generic {
datafeed_id: string;
ignore_unavailable?: boolean;
allow_no_indices?: boolean;
@ -1996,22 +1998,22 @@ export interface MlPutDatafeed<T = any> extends Generic {
body: T;
}
export interface MlPutFilter<T = any> extends Generic {
export interface MlPutFilter<T = RequestBody> extends Generic {
filter_id: string;
body: T;
}
export interface MlPutJob<T = any> extends Generic {
export interface MlPutJob<T = RequestBody> extends Generic {
job_id: string;
body: T;
}
export interface MlPutTrainedModel<T = any> extends Generic {
export interface MlPutTrainedModel<T = RequestBody> extends Generic {
model_id: string;
body: T;
}
export interface MlRevertModelSnapshot<T = any> extends Generic {
export interface MlRevertModelSnapshot<T = RequestBody> extends Generic {
job_id: string;
snapshot_id: string;
delete_intervening_results?: boolean;
@ -2023,13 +2025,13 @@ export interface MlSetUpgradeMode extends Generic {
timeout?: string;
}
export interface MlStartDataFrameAnalytics<T = any> extends Generic {
export interface MlStartDataFrameAnalytics<T = RequestBody> extends Generic {
id: string;
timeout?: string;
body?: T;
}
export interface MlStartDatafeed<T = any> extends Generic {
export interface MlStartDatafeed<T = RequestBody> extends Generic {
datafeed_id: string;
start?: string;
end?: string;
@ -2037,7 +2039,7 @@ export interface MlStartDatafeed<T = any> extends Generic {
body?: T;
}
export interface MlStopDataFrameAnalytics<T = any> extends Generic {
export interface MlStopDataFrameAnalytics<T = RequestBody> extends Generic {
id: string;
allow_no_match?: boolean;
force?: boolean;
@ -2052,7 +2054,7 @@ export interface MlStopDatafeed extends Generic {
timeout?: string;
}
export interface MlUpdateDatafeed<T = any> extends Generic {
export interface MlUpdateDatafeed<T = RequestBody> extends Generic {
datafeed_id: string;
ignore_unavailable?: boolean;
allow_no_indices?: boolean;
@ -2061,31 +2063,31 @@ export interface MlUpdateDatafeed<T = any> extends Generic {
body: T;
}
export interface MlUpdateFilter<T = any> extends Generic {
export interface MlUpdateFilter<T = RequestBody> extends Generic {
filter_id: string;
body: T;
}
export interface MlUpdateJob<T = any> extends Generic {
export interface MlUpdateJob<T = RequestBody> extends Generic {
job_id: string;
body: T;
}
export interface MlUpdateModelSnapshot<T = any> extends Generic {
export interface MlUpdateModelSnapshot<T = RequestBody> extends Generic {
job_id: string;
snapshot_id: string;
body: T;
}
export interface MlValidate<T = any> extends Generic {
export interface MlValidate<T = RequestBody> extends Generic {
body: T;
}
export interface MlValidateDetector<T = any> extends Generic {
export interface MlValidateDetector<T = RequestBody> extends Generic {
body: T;
}
export interface MonitoringBulk<T = any> extends Generic {
export interface MonitoringBulk<T = RequestNDBody> extends Generic {
type?: string;
system_id?: string;
system_api_version?: string;
@ -2109,12 +2111,12 @@ export interface RollupGetRollupIndexCaps extends Generic {
index: string;
}
export interface RollupPutJob<T = any> extends Generic {
export interface RollupPutJob<T = RequestBody> extends Generic {
id: string;
body: T;
}
export interface RollupRollupSearch<T = any> extends Generic {
export interface RollupRollupSearch<T = RequestBody> extends Generic {
index: string | string[];
type?: string;
typed_keys?: boolean;
@ -2135,7 +2137,7 @@ export interface RollupStopJob extends Generic {
export interface SecurityAuthenticate extends Generic {
}
export interface SecurityChangePassword<T = any> extends Generic {
export interface SecurityChangePassword<T = RequestBody> extends Generic {
username?: string;
refresh?: 'true' | 'false' | 'wait_for';
body: T;
@ -2150,7 +2152,7 @@ export interface SecurityClearCachedRoles extends Generic {
name: string | string[];
}
export interface SecurityCreateApiKey<T = any> extends Generic {
export interface SecurityCreateApiKey<T = RequestBody> extends Generic {
refresh?: 'true' | 'false' | 'wait_for';
body: T;
}
@ -2210,7 +2212,7 @@ export interface SecurityGetRoleMapping extends Generic {
name?: string;
}
export interface SecurityGetToken<T = any> extends Generic {
export interface SecurityGetToken<T = RequestBody> extends Generic {
body: T;
}
@ -2221,37 +2223,37 @@ export interface SecurityGetUser extends Generic {
export interface SecurityGetUserPrivileges extends Generic {
}
export interface SecurityHasPrivileges<T = any> extends Generic {
export interface SecurityHasPrivileges<T = RequestBody> extends Generic {
user?: string;
body: T;
}
export interface SecurityInvalidateApiKey<T = any> extends Generic {
export interface SecurityInvalidateApiKey<T = RequestBody> extends Generic {
body: T;
}
export interface SecurityInvalidateToken<T = any> extends Generic {
export interface SecurityInvalidateToken<T = RequestBody> extends Generic {
body: T;
}
export interface SecurityPutPrivileges<T = any> extends Generic {
export interface SecurityPutPrivileges<T = RequestBody> extends Generic {
refresh?: 'true' | 'false' | 'wait_for';
body: T;
}
export interface SecurityPutRole<T = any> extends Generic {
export interface SecurityPutRole<T = RequestBody> extends Generic {
name: string;
refresh?: 'true' | 'false' | 'wait_for';
body: T;
}
export interface SecurityPutRoleMapping<T = any> extends Generic {
export interface SecurityPutRoleMapping<T = RequestBody> extends Generic {
name: string;
refresh?: 'true' | 'false' | 'wait_for';
body: T;
}
export interface SecurityPutUser<T = any> extends Generic {
export interface SecurityPutUser<T = RequestBody> extends Generic {
username: string;
refresh?: 'true' | 'false' | 'wait_for';
body: T;
@ -2278,7 +2280,7 @@ export interface SlmGetStats extends Generic {
export interface SlmGetStatus extends Generic {
}
export interface SlmPutLifecycle<T = any> extends Generic {
export interface SlmPutLifecycle<T = RequestBody> extends Generic {
policy_id: string;
body?: T;
}
@ -2289,16 +2291,16 @@ export interface SlmStart extends Generic {
export interface SlmStop extends Generic {
}
export interface SqlClearCursor<T = any> extends Generic {
export interface SqlClearCursor<T = RequestBody> extends Generic {
body: T;
}
export interface SqlQuery<T = any> extends Generic {
export interface SqlQuery<T = RequestBody> extends Generic {
format?: string;
body: T;
}
export interface SqlTranslate<T = any> extends Generic {
export interface SqlTranslate<T = RequestBody> extends Generic {
body: T;
}
@ -2337,11 +2339,11 @@ export interface TransformGetTransformStats extends Generic {
allow_no_match?: boolean;
}
export interface TransformPreviewTransform<T = any> extends Generic {
export interface TransformPreviewTransform<T = RequestBody> extends Generic {
body: T;
}
export interface TransformPutTransform<T = any> extends Generic {
export interface TransformPutTransform<T = RequestBody> extends Generic {
transform_id: string;
defer_validation?: boolean;
body: T;
@ -2361,7 +2363,7 @@ export interface TransformStopTransform extends Generic {
wait_for_checkpoint?: boolean;
}
export interface TransformUpdateTransform<T = any> extends Generic {
export interface TransformUpdateTransform<T = RequestBody> extends Generic {
transform_id: string;
defer_validation?: boolean;
body: T;
@ -2384,7 +2386,7 @@ export interface WatcherDeleteWatch extends Generic {
id: string;
}
export interface WatcherExecuteWatch<T = any> extends Generic {
export interface WatcherExecuteWatch<T = RequestBody> extends Generic {
id?: string;
debug?: boolean;
body?: T;
@ -2394,7 +2396,7 @@ export interface WatcherGetWatch extends Generic {
id: string;
}
export interface WatcherPutWatch<T = any> extends Generic {
export interface WatcherPutWatch<T = RequestBody> extends Generic {
id: string;
active?: boolean;
version?: number;

View File

@ -13,7 +13,14 @@ request for instance, you can access them via `RequestParams.Search`.
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`.
will default to `RequestBody`. +
`RequestBody`, along with `RequestNDBody` and `ResponseBody` are defined inside the client, and it looks like this:
[source,ts]
----
type RequestBody<T = Record<string, any>> = T | string | Buffer | ReadableStream
type RequestNDBody<T = Record<string, any>[]> = T | string[] | Buffer | ReadableStream
type ResponseBody<T = Record<string, any>> = T | string | boolean | ReadableStream
----
For example:
@ -49,7 +56,7 @@ const searchParams: RequestParams.Search = {
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`.
`BodyType`.
[source,ts]
----
@ -137,19 +144,43 @@ interface Source {
foo: string
}
async function run (): Promise<void> {
// Define the search parameters
const searchParams: RequestParams.Search<SearchBody> = {
async function run () {
// All of the examples below are valid code, by default,
// the request body will be `RequestBody` and response will be `ResponseBody`.
const response = await client.search({
index: 'test',
body: {
query: {
match: { foo: 'bar' }
}
}
}
})
// body here is `ResponseBody`
console.log(response.body)
// Craft the final type definition
const response: ApiResponse<SearchResponse<Source>> = await client.search(searchParams)
// The first generic is the request body
const response = await client.search<SearchBody>({
index: 'test',
// Here the body must follow the `SearchBody` interface
body: {
query: {
match: { foo: 'bar' }
}
}
})
// body here is `ResponseBody`
console.log(response.body)
const response = await client.search<SearchBody, SearchResponse<Source>>({
index: 'test',
// Here the body must follow the `SearchBody` interface
body: {
query: {
match: { foo: 'bar' }
}
}
})
// Now you can have full type definition of the response
console.log(response.body)
}

2830
index.d.ts vendored

File diff suppressed because it is too large Load Diff

67
lib/Connection.d.ts vendored
View File

@ -5,10 +5,11 @@
/// <reference types="node" />
import { URL } from 'url';
import { inspect, InspectOptions } from 'util';
import { inspect, InspectOptions } from 'util'
import { Readable as ReadableStream } from 'stream';
import { ApiKeyAuth, BasicAuth } from './pool'
import * as http from 'http';
import { ConnectionOptions as TlsConnectionOptions } from 'tls';
import * as http from 'http'
import { ConnectionOptions as TlsConnectionOptions } from 'tls'
export declare type agentFn = () => any;
@ -16,24 +17,31 @@ interface ConnectionOptions {
url: URL;
ssl?: TlsConnectionOptions;
id?: string;
headers?: any;
headers?: Record<string, any>;
agent?: AgentOptions | agentFn;
status?: string;
roles?: any;
roles?: ConnectionRoles;
auth?: BasicAuth | ApiKeyAuth;
}
interface ConnectionRoles {
master?: boolean
data?: boolean
ingest?: boolean
ml?: boolean
}
interface RequestOptions extends http.ClientRequestArgs {
asStream?: boolean;
body?: any;
body?: string | Buffer | ReadableStream;
querystring?: string;
}
export interface AgentOptions {
keepAlive: boolean;
keepAliveMsecs: number;
maxSockets: number;
maxFreeSockets: number;
keepAlive?: boolean;
keepAliveMsecs?: number;
maxSockets?: number;
maxFreeSockets?: number;
}
export default class Connection {
@ -47,27 +55,26 @@ export default class Connection {
INGEST: string;
ML: string;
};
url: URL;
ssl: TlsConnectionOptions | null;
id: string;
headers: any;
deadCount: number;
resurrectTimeout: number;
statuses: any;
roles: any;
makeRequest: any;
_openRequests: number;
_status: string;
_agent: http.Agent;
constructor(opts?: ConnectionOptions);
request(params: RequestOptions, callback: (err: Error | null, response: http.IncomingMessage | null) => void): http.ClientRequest;
close(): Connection;
setRole(role: string, enabled: boolean): Connection;
status: string;
buildRequestObject(params: any): http.ClientRequestArgs;
url: URL
ssl: TlsConnectionOptions | null
id: string
headers: Record<string, any>
status: string
roles: ConnectionRoles
deadCount: number
resurrectTimeout: number
makeRequest: any
_openRequests: number
_status: string
_agent: http.Agent
constructor(opts?: ConnectionOptions)
request(params: RequestOptions, callback: (err: Error | null, response: http.IncomingMessage | null) => void): http.ClientRequest
close(): Connection
setRole(role: string, enabled: boolean): Connection
buildRequestObject(params: any): http.ClientRequestArgs
// @ts-ignore
[inspect.custom](object: any, options: InspectOptions): string;
toJSON(): any;
[inspect.custom](object: any, options: InspectOptions): string
toJSON(): any
}
export {};

60
lib/Transport.d.ts vendored
View File

@ -2,9 +2,16 @@
// 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 { Readable as ReadableStream } from 'stream';
import { ConnectionPool, CloudConnectionPool } from './pool';
import Connection from './Connection';
import Serializer from './Serializer';
import * as errors from './errors';
export type ApiError = errors.ConfigurationError | errors.ConnectionError |
errors.DeserializationError | errors.SerializationError |
errors.NoLivingConnectionsError | errors.ResponseError |
errors.TimeoutError
export interface nodeSelectorFn {
(connections: Connection[]): Connection;
@ -18,36 +25,33 @@ export interface generateRequestIdFn {
(params: TransportRequestParams, options: TransportRequestOptions): any;
}
declare type noopFn = (...args: any[]) => void;
declare type emitFn = (event: string | symbol, ...args: any[]) => boolean;
interface TransportOptions {
emit: emitFn & noopFn;
emit: (event: string | symbol, ...args: any[]) => boolean;
connectionPool: ConnectionPool | CloudConnectionPool;
serializer: Serializer;
maxRetries: number;
requestTimeout: number | string;
suggestCompression: boolean;
suggestCompression?: boolean;
compression?: 'gzip';
sniffInterval: number;
sniffOnConnectionFault: boolean;
sniffInterval?: number;
sniffOnConnectionFault?: boolean;
sniffEndpoint: string;
sniffOnStart: boolean;
sniffOnStart?: boolean;
nodeFilter?: nodeFilterFn;
nodeSelector?: string | nodeSelectorFn;
headers?: anyObject;
headers?: Record<string, any>;
generateRequestId?: generateRequestIdFn;
name: string;
name?: string;
opaqueIdPrefix?: string;
}
export interface RequestEvent<T = any, C = any> {
body: T;
export interface RequestEvent<TResponse = ResponseBody, TContext = unknown> {
body: TResponse;
statusCode: number | null;
headers: anyObject | null;
headers: Record<string, any> | null;
warnings: string[] | null;
meta: {
context: C;
context: TContext;
name: string;
request: {
params: TransportRequestParams;
@ -66,18 +70,18 @@ export interface RequestEvent<T = any, C = any> {
// ApiResponse and RequestEvent are the same thing
// we are doing this for have more clear names
export interface ApiResponse<T = any, C = any> extends RequestEvent<T, C> {}
export interface ApiResponse<TResponse = ResponseBody, TContext = unknown> extends RequestEvent<TResponse, TContext> {}
declare type anyObject = {
[key: string]: any;
};
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 interface TransportRequestParams {
method: string;
path: string;
body?: anyObject;
bulkBody?: anyObject;
querystring?: anyObject;
body?: RequestBody;
bulkBody?: RequestNDBody;
querystring?: Record<string, any>;
}
export interface TransportRequestOptions {
@ -85,12 +89,12 @@ export interface TransportRequestOptions {
requestTimeout?: number | string;
maxRetries?: number;
asStream?: boolean;
headers?: anyObject;
querystring?: anyObject;
compression?: string;
headers?: Record<string, any>;
querystring?: Record<string, any>;
compression?: 'gzip';
id?: any;
context?: any;
warnings?: [string];
warnings?: string[];
opaqueId?: string;
}
@ -114,7 +118,7 @@ export default class Transport {
SNIFF_ON_CONNECTION_FAULT: string;
DEFAULT: string;
};
emit: emitFn & noopFn;
emit: (event: string | symbol, ...args: any[]) => boolean;
connectionPool: ConnectionPool | CloudConnectionPool;
serializer: Serializer;
maxRetries: number;
@ -130,9 +134,7 @@ export default class Transport {
_isSniffing: boolean;
constructor(opts: TransportOptions);
request(params: TransportRequestParams, options?: TransportRequestOptions): Promise<ApiResponse>;
request(params: TransportRequestParams, options?: TransportRequestOptions, callback?: (err: Error | null, result: ApiResponse) => void): TransportRequestCallback;
request(params: TransportRequestParams, options?: TransportRequestOptions, callback?: (err: ApiError, result: ApiResponse) => void): TransportRequestCallback;
getConnection(opts: TransportGetConnectionOptions): Connection | null;
sniff(opts?: TransportSniffOptions, callback?: (...args: any[]) => void): void;
}
export {};

10
lib/errors.d.ts vendored
View File

@ -2,7 +2,7 @@
// 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 } from './Transport'
import { ApiResponse, ResponseBody } from './Transport'
export declare class ElasticsearchClientError extends Error {
name: string;
@ -33,8 +33,8 @@ export declare class NoLivingConnectionsError extends ElasticsearchClientError {
export declare class SerializationError extends ElasticsearchClientError {
name: string;
message: string;
data: object;
constructor(message: string, data: object);
data: any;
constructor(message: string, data: any);
}
export declare class DeserializationError extends ElasticsearchClientError {
@ -54,8 +54,8 @@ export declare class ResponseError extends ElasticsearchClientError {
name: string;
message: string;
meta: ApiResponse;
body: any;
body: ResponseBody;
statusCode: number;
headers: any;
headers: Record<string, any>;
constructor(meta: ApiResponse);
}

11
lib/pool/index.d.ts vendored
View File

@ -4,6 +4,7 @@
/// <reference types="node" />
import { URL } from 'url'
import { SecureContextOptions } from 'tls';
import Connection, { AgentOptions } from '../Connection';
import { nodeFilterFn, nodeSelectorFn } from '../Transport';
@ -13,14 +14,12 @@ interface BaseConnectionPoolOptions {
agent?: AgentOptions;
auth?: BasicAuth | ApiKeyAuth;
emit: (event: string | symbol, ...args: any[]) => boolean;
pingTimeout?: number;
Connection: typeof Connection;
resurrectStrategy?: string;
}
interface ConnectionPoolOptions extends BaseConnectionPoolOptions {
pingTimeout?: number;
resurrectStrategy?: string;
resurrectStrategy?: 'ping' | 'optimistic' | 'none';
sniffEnabled?: boolean;
}
@ -65,6 +64,8 @@ interface ResurrectEvent {
declare class BaseConnectionPool {
connections: Connection[];
size: number;
emit: (event: string | symbol, ...args: any[]) => boolean;
_ssl: SecureContextOptions | null;
_agent: AgentOptions | null;
auth: BasicAuth | ApiKeyAuth;
@ -137,7 +138,7 @@ declare class BaseConnectionPool {
* @param {string} url
* @returns {object} host
*/
urlToHost(url: string): any;
urlToHost(url: string): { url: URL };
}
declare class ConnectionPool extends BaseConnectionPool {
@ -167,7 +168,7 @@ declare class ConnectionPool extends BaseConnectionPool {
declare class CloudConnectionPool extends BaseConnectionPool {
cloudConnection: Connection | null
constructor(opts?: BaseConnectionPoolOptions);
getConnection(): Connection;
getConnection(): Connection | null;
}
declare function defaultNodeFilter(node: Connection): boolean;

View File

@ -20,7 +20,7 @@
"test:unit": "tap test/unit/*.test.js -t 300 --no-coverage",
"test:behavior": "tap test/behavior/*.test.js -t 300 --no-coverage",
"test:integration": "node test/integration/index.js",
"test:types": "tsc --project ./test/types/tsconfig.json",
"test:types": "tsd",
"test:coverage": "nyc tap test/unit/*.test.js test/behavior/*.test.js -t 300 && nyc report --reporter=text-lcov > coverage.lcov",
"lint": "standard",
"lint:fix": "standard --fix",
@ -58,7 +58,7 @@
"standard": "^13.0.2",
"stoppable": "^1.1.0",
"tap": "^14.4.1",
"typescript": "^3.4.5",
"tsd": "^0.11.0",
"workq": "^2.1.0"
},
"dependencies": {
@ -80,5 +80,8 @@
},
"engines": {
"node": ">=8"
},
"tsd": {
"directory": "test/types"
}
}

View File

@ -58,7 +58,7 @@ function start (opts) {
{ encoding: 'utf8' }
)
const { fn: factory, types } = genFactory(apiOutputFolder)
const { fn: factory, types } = genFactory(apiOutputFolder, [apiFolder, xPackFolder])
writeFileSync(
mainOutputFile,
factory,

View File

@ -543,3 +543,4 @@ function intersect (first, ...rest) {
}
module.exports = generate
module.exports.ndjsonApi = ndjsonApi

View File

@ -7,10 +7,20 @@
'use strict'
const { readdirSync } = require('fs')
const { join } = require('path')
const dedent = require('dedent')
const deepmerge = require('deepmerge')
const { ndjsonApi } = require('./generateApis')
function genFactory (folder) {
const ndjsonApiKey = ndjsonApi
.map(api => {
return api
.replace(/\.([a-z])/g, k => k[1].toUpperCase())
.replace(/_([a-z])/g, k => k[1].toUpperCase())
})
.map(toPascalCase)
function genFactory (folder, paths) {
// get all the API files
const apiFiles = readdirSync(folder)
const types = apiFiles
@ -25,15 +35,18 @@ function genFactory (folder) {
.split('.')
.reverse()
.reduce((acc, val) => {
const obj = {
[val]: acc === null
? `ApiMethod<RequestParams.${name[0].toUpperCase() + name.slice(1)}>`
: acc
const body = hasBody(paths, file.slice(0, -3))
const methods = acc === null ? buildMethodDefinition(val, name, body) : null
const obj = {}
if (methods) {
for (const m of methods) {
obj[m.key] = m.val
}
} else {
obj[val] = acc
if (isSnakeCased(val)) {
obj[camelify(val)] = acc === null
? `ApiMethod<RequestParams.${name[0].toUpperCase() + name.slice(1)}>`
: acc
obj[camelify(val)] = acc
}
}
return obj
}, null)
@ -83,7 +96,7 @@ function genFactory (folder) {
.join('\n')
// remove useless quotes and commas
.replace(/"/g, '')
.replace(/,/g, '')
.replace(/,$/gm, '')
const fn = dedent`
// Licensed to Elasticsearch B.V under one or more agreements.
@ -160,4 +173,64 @@ function isSnakeCased (str) {
return !!~str.indexOf('_')
}
function toPascalCase (str) {
return str[0].toUpperCase() + str.slice(1)
}
function buildMethodDefinition (api, name, hasBody) {
const Name = toPascalCase(name)
const bodyType = ndjsonApiKey.includes(Name) ? 'RequestNDBody' : 'RequestBody'
if (hasBody) {
let methods = [
{ key: `${api}<TRequestBody extends ${bodyType}, TResponse = ResponseBody, TContext = unknown>(params?: RequestParams.${Name}<TRequestBody>, options?: TransportRequestOptions)`, val: `Promise<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` }
]
if (isSnakeCased(api)) {
methods = methods.concat([
{ key: `${camelify(api)}<TRequestBody extends ${bodyType}, TResponse = ResponseBody, TContext = unknown>(params?: RequestParams.${Name}<TRequestBody>, options?: TransportRequestOptions)`, val: `Promise<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` }
])
}
return methods
} else {
let methods = [
{ key: `${api}<TResponse = ResponseBody, TContext = unknown>(params?: RequestParams.${Name}, options?: TransportRequestOptions)`, val: `Promise<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` }
]
if (isSnakeCased(api)) {
methods = methods.concat([
{ key: `${camelify(api)}<TResponse = ResponseBody, TContext = unknown>(params?: RequestParams.${Name}, options?: TransportRequestOptions)`, val: `Promise<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` }
])
}
return methods
}
}
function hasBody (paths, file) {
const spec = readSpec()
return !!spec[file].body
function readSpec () {
try {
return require(join(paths[0], file))
} catch (err) {}
try {
return require(join(paths[1], file))
} catch (err) {}
throw new Error(`Cannot read spec file ${file}`)
}
}
module.exports = genFactory

View File

@ -6,6 +6,15 @@
const semver = require('semver')
const deprecatedParameters = require('./patch.json')
const { ndjsonApi } = require('./generateApis')
const ndjsonApiKey = ndjsonApi
.map(api => {
return api
.replace(/\.([a-z])/g, k => k[1].toUpperCase())
.replace(/_([a-z])/g, k => k[1].toUpperCase())
})
.map(toPascalCase)
function generate (version, api) {
const release = semver.valid(version) ? semver.major(version) : version
@ -13,6 +22,8 @@ function generate (version, api) {
// 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 { RequestBody, RequestNDBody } from '../lib/Transport'
export interface Generic {
method?: string;
ignore?: number | number[];
@ -83,8 +94,10 @@ export interface Generic {
return `${e.key}${optional}: ${getType(e.value.type, e.value.options)};`
}
const bodyGeneric = ndjsonApiKey.includes(toPascalCase(name)) ? 'RequestNDBody' : 'RequestBody'
const code = `
export interface ${name[0].toUpperCase() + name.slice(1)}${body ? '<T = any>' : ''} extends Generic {
export interface ${toPascalCase(name)}${body ? `<T = ${bodyGeneric}>` : ''} extends Generic {
${partsArr.map(genLine).join('\n ')}
${paramsArr.map(genLine).join('\n ')}
${body ? `body${body.required ? '' : '?'}: T;` : ''}
@ -122,4 +135,8 @@ function intersect (first, ...rest) {
}, first)
}
function toPascalCase (str) {
return str[0].toUpperCase() + str.slice(1)
}
module.exports = generate

View File

@ -0,0 +1,128 @@
// Licensed to Elasticsearch B.V under one or more agreements.
// 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 { expectType, expectError } from 'tsd'
import { ResponseBody } from '../../lib/Transport'
import { Client } from '../../'
const client = new Client({
node: 'http://localhost:9200'
})
interface SearchBody {
query: {
match: { foo: string }
}
}
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;
}
interface Source {
foo: string
}
// Use a bad body
expectError(
client.search({
index: 'hello',
body: 42
}).then(console.log)
)
// No generics
{
const response = await client.search({
index: 'test',
body: {
query: {
match: { foo: 'bar' }
}
}
})
expectType<ResponseBody>(response.body)
expectType<unknown>(response.meta.context)
}
// Define only the request body
{
const response = await client.search<SearchBody>({
index: 'test',
body: {
query: {
match: { foo: 'bar' }
}
}
})
expectType<ResponseBody>(response.body)
expectType<unknown>(response.meta.context)
}
// Define request body and response body
{
const response = await client.search<SearchBody, SearchResponse<Source>>({
index: 'test',
body: {
query: {
match: { foo: 'bar' }
}
}
})
expectType<SearchResponse<Source>>(response.body)
expectType<unknown>(response.meta.context)
}
// Define request body, response body and the context
{
const response = await client.search<SearchBody, SearchResponse<Source>, string>({
index: 'test',
body: {
query: {
match: { foo: 'bar' }
}
}
})
expectType<SearchResponse<Source>>(response.body)
expectType<string>(response.meta.context)
}

View File

@ -0,0 +1,35 @@
// Licensed to Elasticsearch B.V under one or more agreements.
// 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 { expectType } from 'tsd'
import { ResponseBody } from '../../lib/Transport'
import { Client } from '../../'
const client = new Client({
node: 'http://localhost:9200'
})
// No generics
{
const response = await client.cat.count({ index: 'test' })
expectType<ResponseBody>(response.body)
expectType<unknown>(response.meta.context)
}
// Define only the request body
{
const response = await client.cat.count<string>({ index: 'test' })
expectType<string>(response.body)
expectType<unknown>(response.meta.context)
}
// Define request body and the context
{
const response = await client.cat.count<string, string>({ index: 'test' })
expectType<string>(response.body)
expectType<string>(response.meta.context)
}

View File

@ -0,0 +1,618 @@
// Licensed to Elasticsearch B.V under one or more agreements.
// 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 { URL } from 'url'
import { expectType, expectError } from 'tsd'
import { TransportGetConnectionOptions } from '../../lib/Transport'
import {
Client,
Serializer,
Connection,
ConnectionPool,
Transport,
errors
} from '../../'
/**
* `node` option
*/
expectType<Client>(
new Client({
node: 'http://localhost:9200'
})
)
expectType<Client>(
new Client({
nodes: ['http://localhost:9200', 'http://localhost:9200']
})
)
expectType<Client>(
new Client({
node: {
url: new URL('http://localhost:9200'),
id: 'my-node'
}
})
)
expectType<Client>(
new Client({
nodes: [{
url: new URL('http://localhost:9200'),
id: 'my-node-1'
}, {
url: new URL('http://localhost:9201'),
id: 'my-node-2'
}]
})
)
expectError<errors.ConfigurationError>(
new Client({
node: 42
})
)
expectError<errors.ConfigurationError>(
new Client({
node: {
url: 'http://localhost:9200',
id: 'my-node'
}
})
)
/**
* `maxRetries` option
*/
expectType<Client>(
new Client({
node: 'http://localhost:9200',
maxRetries: 5
})
)
expectError<errors.ConfigurationError>(
new Client({
node: 'http://localhost:9200',
maxRetries: 'five'
})
)
/**
* `requestTimeout` option
*/
expectType<Client>(
new Client({
node: 'http://localhost:9200',
requestTimeout: 5
})
)
expectError<errors.ConfigurationError>(
new Client({
node: 'http://localhost:9200',
requestTimeout: 'five'
})
)
/**
* `pingTimeout` option
*/
expectType<Client>(
new Client({
node: 'http://localhost:9200',
pingTimeout: 5
})
)
expectError<errors.ConfigurationError>(
new Client({
node: 'http://localhost:9200',
pingTimeout: 'five'
})
)
/**
* `sniffInterval` option
*/
expectType<Client>(
new Client({
node: 'http://localhost:9200',
sniffInterval: 5
})
)
expectType<Client>(
new Client({
node: 'http://localhost:9200',
sniffInterval: false
})
)
expectError<errors.ConfigurationError>(
new Client({
node: 'http://localhost:9200',
sniffInterval: 'five'
})
)
/**
* `sniffOnStart` option
*/
expectType<Client>(
new Client({
node: 'http://localhost:9200',
sniffOnStart: true
})
)
expectError<errors.ConfigurationError>(
new Client({
node: 'http://localhost:9200',
sniffOnStart: 'no'
})
)
/**
* `sniffEndpoint` option
*/
expectType<Client>(
new Client({
node: 'http://localhost:9200',
sniffEndpoint: '/custom'
})
)
expectError<errors.ConfigurationError>(
new Client({
node: 'http://localhost:9200',
sniffEndpoint: false
})
)
/**
* `sniffOnConnectionFault` option
*/
expectType<Client>(
new Client({
node: 'http://localhost:9200',
sniffOnConnectionFault: true
})
)
expectError<errors.ConfigurationError>(
new Client({
node: 'http://localhost:9200',
sniffOnConnectionFault: 'yes'
})
)
/**
* `resurrectStrategy` option
*/
expectType<Client>(
new Client({
node: 'http://localhost:9200',
resurrectStrategy: 'ping'
})
)
expectType<Client>(
new Client({
node: 'http://localhost:9200',
resurrectStrategy: 'optimistic'
})
)
expectType<Client>(
new Client({
node: 'http://localhost:9200',
resurrectStrategy: 'none'
})
)
expectError<errors.ConfigurationError>(
new Client({
node: 'http://localhost:9200',
resurrectStrategy: 'custom'
})
)
/**
* `suggestCompression` option
*/
expectType<Client>(
new Client({
node: 'http://localhost:9200',
suggestCompression: true
})
)
expectError<errors.ConfigurationError>(
new Client({
node: 'http://localhost:9200',
suggestCompression: 'no'
})
)
/**
* `compression` option
*/
expectType<Client>(
new Client({
node: 'http://localhost:9200',
compression: 'gzip'
})
)
expectError<errors.ConfigurationError>(
new Client({
node: 'http://localhost:9200',
compression: 'deflate'
})
)
/**
* `headers` option
*/
expectType<Client>(
new Client({
node: 'http://localhost:9200',
headers: { foo: 'bar' }
})
)
expectError<errors.ConfigurationError>(
new Client({
node: 'http://localhost:9200',
headers: 'foo=bar'
})
)
/**
* `opaqueIdPrefix` option
*/
expectType<Client>(
new Client({
node: 'http://localhost:9200',
opaqueIdPrefix: 'foo-'
})
)
expectError<errors.ConfigurationError>(
new Client({
node: 'http://localhost:9200',
opaqueIdPrefix: 42
})
)
/**
* `name` option
*/
expectType<Client>(
new Client({
node: 'http://localhost:9200',
name: 'foo'
})
)
expectError<errors.ConfigurationError>(
new Client({
node: 'http://localhost:9200',
name: 42
})
)
/**
* `auth` option
*/
expectType<Client>(
new Client({
node: 'http://localhost:9200',
auth: {
username: 'username',
password: 'password'
}
})
)
expectType<Client>(
new Client({
node: 'http://localhost:9200',
auth: {
apiKey: 'abcd'
}
})
)
expectType<Client>(
new Client({
node: 'http://localhost:9200',
auth: {
apiKey: {
api_key: 'foo',
id: 'bar'
}
}
})
)
expectError<errors.ConfigurationError>(
new Client({
node: 'http://localhost:9200',
auth: 'password'
})
)
/**
* `cloud` option
*/
expectType<Client>(
new Client({
cloud: {
id: 'localhost:9200'
}
})
)
expectError<errors.ConfigurationError>(
new Client({
cloud: {
id: 42
}
})
)
/**
* `agent` option
*/
expectType<Client>(
new Client({
node: 'http://localhost:9200',
agent: {
keepAlive: true,
keepAliveMsecs: 42,
maxSockets: 42,
maxFreeSockets: 42
}
})
)
expectError<errors.ConfigurationError>(
new Client({
node: 'http://localhost:9200',
agent: {
keepAlive: 'yes',
keepAliveMsecs: true,
maxSockets: 'all',
maxFreeSockets: null
}
})
)
/**
* `ssl` option
*/
expectType<Client>(
new Client({
node: 'http://localhost:9200',
ssl: {
ca: 'cert',
rejectUnauthorized: true
}
})
)
expectError<errors.ConfigurationError>(
new Client({
node: 'http://localhost:9200',
ssl: {
ca: 42,
rejectUnauthorized: 'yes'
}
})
)
/**
* `generateRequestId` option
*/
expectType<Client>(
new Client({
node: 'http://localhost:9200',
generateRequestId (params, options) {
return 'id'
}
})
)
expectError<errors.ConfigurationError>(
new Client({
node: 'http://localhost:9200',
generateRequestId: 'id'
})
)
/**
* `nodeSelector` option
*/
expectType<Client>(
new Client({
node: 'http://localhost:9200',
nodeSelector (connections) {
return connections[0]
}
})
)
expectType<Client>(
new Client({
node: 'http://localhost:9200',
nodeSelector: 'round-robin'
})
)
expectError<errors.ConfigurationError>(
new Client({
node: 'http://localhost:9200',
nodeSelector (connections) {
return 'id'
}
})
)
/**
* `nodeFilter` option
*/
expectType<Client>(
new Client({
node: 'http://localhost:9200',
nodeFilter (connection) {
return true
}
})
)
expectError<errors.ConfigurationError>(
new Client({
node: 'http://localhost:9200',
nodeFilter (connection) {
return 'id'
}
})
)
/**
* `Serializer` option
*/
{
class CustomSerializer extends Serializer {
deserialize (str: string) {
return super.deserialize(str)
}
}
expectType<Client>(
new Client({
node: 'http://localhost:9200',
Serializer: CustomSerializer
})
)
}
{
class CustomSerializer {
deserialize (str: string) {
return JSON.parse(str)
}
}
expectError<errors.ConfigurationError>(
new Client({
node: 'http://localhost:9200',
Serializer: CustomSerializer
})
)
}
/**
* `Connection` option
*/
{
class CustomConnection extends Connection {
close () {
return super.close()
}
}
expectType<Client>(
new Client({
node: 'http://localhost:9200',
Connection: CustomConnection
})
)
}
{
class CustomConnection {
close () {
return Promise.resolve()
}
}
expectError<errors.ConfigurationError>(
new Client({
node: 'http://localhost:9200',
Connection: CustomConnection
})
)
}
/**
* `ConnectionPool` option
*/
{
class CustomConnectionPool extends ConnectionPool {
empty () {
return super.empty()
}
}
expectType<Client>(
new Client({
node: 'http://localhost:9200',
ConnectionPool: CustomConnectionPool
})
)
}
{
class CustomConnectionPool {
empty () {
return this
}
}
expectError<errors.ConfigurationError>(
new Client({
node: 'http://localhost:9200',
ConnectionPool: CustomConnectionPool
})
)
}
/**
* `Transport` option
*/
{
class CustomTransport extends Transport {
getConnection (opts: TransportGetConnectionOptions) {
return super.getConnection(opts)
}
}
expectType<Client>(
new Client({
node: 'http://localhost:9200',
Transport: CustomTransport
})
)
}
{
class CustomTransport {
getConnection (opts: TransportGetConnectionOptions) {
return null
}
}
expectError<errors.ConfigurationError>(
new Client({
node: 'http://localhost:9200',
Transport: CustomTransport
})
)
}

114
test/types/client.test-d.ts Normal file
View File

@ -0,0 +1,114 @@
// Licensed to Elasticsearch B.V under one or more agreements.
// 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 { expectType } from 'tsd'
import { Client, ApiError, ApiResponse, RequestEvent, ResurrectEvent } from '../../'
import { TransportRequestCallback } from '../..//lib/Transport';
const client = new Client({
node: 'http://localhost:9200'
})
client.on('request', (err, meta) => {
expectType<ApiError>(err)
expectType<RequestEvent>(meta)
})
client.on('response', (err, meta) => {
expectType<ApiError>(err)
expectType<RequestEvent>(meta)
})
client.on('sniff', (err, meta) => {
expectType<ApiError>(err)
expectType<RequestEvent>(meta)
})
client.on('resurrect', (err, meta) => {
expectType<null>(err)
expectType<ResurrectEvent>(meta)
})
// Test all overloads
// Callbacks style
{
const result = client.info((err, result) => {
expectType<ApiError>(err)
expectType<ApiResponse>(result)
})
expectType<TransportRequestCallback>(result)
}
{
const result = client.info({ pretty: true }, (err, result) => {
expectType<ApiError>(err)
expectType<ApiResponse>(result)
})
expectType<TransportRequestCallback>(result)
}
{
const result = client.info({ pretty: true }, { ignore: [404] }, (err, result) => {
expectType<ApiError>(err)
expectType<ApiResponse>(result)
})
expectType<TransportRequestCallback>(result)
}
// Promise style
{
const promise = client.info()
expectType<Promise<ApiResponse>>(promise)
promise
.then(result => expectType<ApiResponse>(result))
.catch((err: ApiError) => expectType<ApiError>(err))
}
{
const promise = client.info({ pretty: true })
expectType<Promise<ApiResponse>>(promise)
promise
.then(result => expectType<ApiResponse>(result))
.catch((err: ApiError) => expectType<ApiError>(err))
}
{
const promise = client.info({ pretty: true }, { ignore: [404] })
expectType<Promise<ApiResponse>>(promise)
promise
.then(result => expectType<ApiResponse>(result))
.catch((err: ApiError) => expectType<ApiError>(err))
}
// Promise style with async await
{
const promise = client.info()
expectType<Promise<ApiResponse>>(promise)
try {
expectType<ApiResponse>(await promise)
} catch (err) {
expectType<any>(err)
}
}
{
const promise = client.info({ pretty: true })
expectType<Promise<ApiResponse>>(promise)
try {
expectType<ApiResponse>(await promise)
} catch (err) {
expectType<any>(err)
}
}
{
const promise = client.info({ pretty: true }, { ignore: [404] })
expectType<Promise<ApiResponse>>(promise)
try {
expectType<ApiResponse>(await promise)
} catch (err) {
expectType<any>(err)
}
}

View File

@ -0,0 +1,95 @@
// Licensed to Elasticsearch B.V under one or more agreements.
// 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 { expectType, expectAssignable } from 'tsd'
import { URL } from 'url'
import {
BaseConnectionPool,
ConnectionPool,
CloudConnectionPool,
Connection
} from '../../'
{
const pool = new BaseConnectionPool({
Connection: Connection,
ssl: { ca: 'stirng' },
emit: (event, ...args) => true,
agent: { keepAlive: true },
auth: { username: 'username', password: 'password' }
})
expectType<BaseConnectionPool>(pool)
expectType<Connection[]>(pool.connections)
expectType<number>(pool.size)
expectType<BaseConnectionPool>(pool.markAlive(new Connection()))
expectType<BaseConnectionPool>(pool.markDead(new Connection()))
expectType<Connection | null>(pool.getConnection({
filter (node) { return true },
selector (connections) { return connections[0] },
requestId: 'id',
name: 'name',
now: Date.now()
}))
expectType<Connection>(pool.addConnection({}))
expectType<BaseConnectionPool>(pool.removeConnection(new Connection()))
expectType<BaseConnectionPool>(pool.empty())
expectType<BaseConnectionPool>(pool.update([]))
expectType<any[]>(pool.nodesToHost([], 'https'))
expectType<{ url: URL }>(pool.urlToHost('url'))
}
{
const pool = new ConnectionPool({
Connection: Connection,
ssl: { ca: 'stirng' },
emit: (event, ...args) => true,
agent: { keepAlive: true },
auth: { username: 'username', password: 'password' },
pingTimeout: 1000,
resurrectStrategy: 'ping',
sniffEnabled: true
})
expectAssignable<ConnectionPool>(pool)
expectType<Connection[]>(pool.connections)
expectType<number>(pool.size)
expectType<string[]>(pool.dead)
expectAssignable<ConnectionPool>(pool.markAlive(new Connection()))
expectAssignable<ConnectionPool>(pool.markDead(new Connection()))
expectType<Connection | null>(pool.getConnection({
filter (node) { return true },
selector (connections) { return connections[0] },
requestId: 'id',
name: 'name',
now: Date.now()
}))
expectType<Connection>(pool.addConnection({}))
expectAssignable<ConnectionPool>(pool.removeConnection(new Connection()))
expectAssignable<ConnectionPool>(pool.empty())
expectAssignable<ConnectionPool>(pool.update([]))
expectType<any[]>(pool.nodesToHost([], 'https'))
expectType<{ url: URL }>(pool.urlToHost('url'))
expectType<void>(pool.resurrect({
now: Date.now(),
requestId: 'id',
name: 'name'
}))
}
{
const pool = new CloudConnectionPool({
Connection: Connection,
ssl: { ca: 'stirng' },
emit: (event, ...args) => true,
agent: { keepAlive: true },
auth: { username: 'username', password: 'password' }
})
expectAssignable<CloudConnectionPool>(pool)
expectType<Connection | null>(pool.cloudConnection)
expectType<Connection | null>(pool.getConnection())
}

View File

@ -0,0 +1,26 @@
// Licensed to Elasticsearch B.V under one or more agreements.
// 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 { expectType } from 'tsd'
import { URL } from 'url'
import { Connection } from '../../'
const conn = new Connection({
url: new URL('http://localhost:9200'),
ssl: { ca: 'string' },
id: 'id',
headers: {},
agent: { keepAlive: false },
status: 'alive',
roles: { master: true },
auth: { username: 'username', password: 'password' }
})
expectType<Connection>(conn)
expectType<URL>(conn.url)
expectType<string>(conn.id)
expectType<Record<string, any>>(conn.headers)
expectType<number>(conn.deadCount)
expectType<number>(conn.resurrectTimeout)
expectType<string>(conn.status)

View File

@ -0,0 +1,83 @@
// Licensed to Elasticsearch B.V under one or more agreements.
// 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 { expectType } from 'tsd'
import { errors, ApiResponse, Connection } from '../../'
import { ResponseBody } from '../../lib/Transport'
const response = {
body: {},
statusCode: 200,
headers: {},
warnings: null,
meta: {
context: {},
name: 'name',
request: {
params: { method: 'GET', path: '/' },
options: {},
id: 42
},
connection: new Connection(),
attempts: 0,
aborted: false,
}
}
{
const err = new errors.ElasticsearchClientError()
expectType<string>(err.name)
expectType<string>(err.message)
}
{
const err = new errors.TimeoutError('message', response)
expectType<string>(err.name)
expectType<string>(err.message)
expectType<ApiResponse>(err.meta)
}
{
const err = new errors.ConnectionError('message', response)
expectType<string>(err.name)
expectType<string>(err.message)
expectType<ApiResponse>(err.meta)
}
{
const err = new errors.NoLivingConnectionsError('message', response)
expectType<string>(err.name)
expectType<string>(err.message)
expectType<ApiResponse>(err.meta)
}
{
const err = new errors.SerializationError('message', {})
expectType<string>(err.name)
expectType<string>(err.message)
expectType<any>(err.data)
}
{
const err = new errors.DeserializationError('message', 'data')
expectType<string>(err.name)
expectType<string>(err.message)
expectType<string>(err.data)
}
{
const err = new errors.ConfigurationError('message')
expectType<string>(err.name)
expectType<string>(err.message)
}
{
const err = new errors.ResponseError(response)
expectType<string>(err.name)
expectType<string>(err.message)
expectType<ApiResponse>(err.meta)
expectType<ResponseBody>(err.body)
expectType<number>(err.statusCode)
expectType<Record<string, any>>(err.headers)
}

View File

@ -1,166 +0,0 @@
// Licensed to Elasticsearch B.V under one or more agreements.
// 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
'use strict'
import {
Client,
ApiResponse,
RequestParams,
RequestEvent,
ResurrectEvent,
events,
errors,
ClientExtendsCallbackOptions,
NodeOptions
} from '../../index'
import { TransportRequestParams, TransportRequestOptions } from '../../lib/Transport'
import { URL } from 'url'
const client = new Client({ node: 'http://localhost:9200' })
const nodeOpts: NodeOptions = {
url: new URL('http://localhost:9200'),
id: 'winteriscoming',
headers: { 'foo': 'bar' },
roles: {
master: false,
data: true,
ingest: false,
ml: false
}
}
const client2 = new Client({ node: nodeOpts })
const clientBasicAuth = new Client({
node: 'http://localhost:9200',
auth: { username: 'foo', password: 'bar' }
})
const clientApiKeyString = new Client({
node: 'http://localhost:9200',
auth: { apiKey: 'foobar' }
})
const clientApiKeyObject = new Client({
node: 'http://localhost:9200',
auth: {
apiKey: {
id: 'foo',
api_key: 'bar'
}
}
})
client.on(events.RESPONSE, (err: errors.ElasticsearchClientError | null, request: RequestEvent) => {
if (err) console.log(err)
const { body, statusCode } = request
const { params } = request.meta.request
console.log(params, body, statusCode)
})
client.on(events.RESURRECT, (err: errors.ElasticsearchClientError | null, meta: ResurrectEvent) => {})
// Callbacks
client.info((err: errors.ElasticsearchClientError | null, result: ApiResponse) => {})
client.index({
index: 'test',
id: 'test',
body: { hello: 'world' }
}, (err: errors.ElasticsearchClientError | null, result: ApiResponse) => {})
// request options
client.index({
index: 'test',
id: 'test',
body: { hello: 'world' }
}, {
maxRetries: 2,
ignore: [404],
requestTimeout: 2000,
headers: { foo: 'bar' },
querystring: { baz: 'faz' },
compression: 'gzip',
asStream: false
}, (err: errors.ElasticsearchClientError | null, result: ApiResponse) => {})
// Promises
client.info()
.then((result: ApiResponse) => {})
.catch((err: errors.ElasticsearchClientError) => {})
client.index({
index: 'test',
id: 'test',
body: { hello: 'world' }
})
.then((result: ApiResponse) => {})
.catch((err: errors.ElasticsearchClientError) => {})
// request options
client.index({
index: 'test',
id: 'test',
body: { hello: 'world' }
}, {
maxRetries: 2,
ignore: [404],
requestTimeout: 2000
})
.then((result: ApiResponse) => {})
.catch((err: errors.ElasticsearchClientError) => {})
// --- Use generics ---
// Define the search parameters
interface SearchBody {
query: {
match: { foo: string }
}
}
const searchParams: RequestParams.Search<SearchBody> = {
index: 'test',
body: {
query: {
match: { foo: 'bar' }
}
}
}
// Define the interface of the search response
interface SearchResponse<T> {
hits: {
hits: Array<{
_source: T;
}>
}
}
// Define the interface of the source object
interface Source {
foo: string
}
client.search(searchParams)
.then((response: ApiResponse<SearchResponse<Source>>) => console.log(response))
.catch((err: errors.ElasticsearchClientError) => {})
// extend client
client.extend('namespace.method', (options: ClientExtendsCallbackOptions) => {
return function (params: any) {
const requestParams: TransportRequestParams = {
method: 'GET',
path: '/',
querystring: {}
}
const requestOptions: TransportRequestOptions = {
ignore: [404],
maxRetries: 5
}
return options.makeRequest(requestParams, requestOptions)
}
})

View File

@ -0,0 +1,13 @@
// Licensed to Elasticsearch B.V under one or more agreements.
// 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 { expectType } from 'tsd'
import { Serializer } from '../../'
const serializer = new Serializer()
expectType<string>(serializer.serialize({}))
expectType<any>(serializer.deserialize(''))
expectType<string>(serializer.ndserialize([]))
expectType<string>(serializer.qserialize({}))

View File

@ -0,0 +1,129 @@
// Licensed to Elasticsearch B.V under one or more agreements.
// 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 { Readable as ReadableStream } from 'stream';
import { expectType, expectAssignable, expectError } from 'tsd'
import {
Transport,
Connection,
ConnectionPool,
Serializer
} from '../..'
import {
TransportRequestParams,
TransportRequestOptions,
TransportRequestCallback,
RequestEvent,
ApiError,
ApiResponse,
RequestBody,
RequestNDBody,
ResponseBody
} from '../../lib/Transport'
const params = {
method: 'POST',
path: '/search',
body: { foo: 'bar' },
querystring: { baz: 'faz' }
}
const options = {
ignore: [404],
requestTimeout: 5000,
maxRetries: 3,
asStream: false,
headers: {},
querystring: {},
id: 'id',
context: {},
warnings: ['warn'],
opaqueId: 'id'
}
const response = {
body: {},
statusCode: 200,
headers: {},
warnings: null,
meta: {
context: {},
name: 'name',
request: {
params,
options,
id: 'id'
},
connection: new Connection(),
attempts: 0,
aborted: false
}
}
expectAssignable<TransportRequestParams>(params)
expectAssignable<TransportRequestParams>({ method: 'GET', path: '/' })
expectAssignable<TransportRequestOptions>(options)
expectAssignable<RequestEvent>(response)
expectAssignable<ApiResponse>(response)
// verify that RequestBody, RequestNDBody and ResponseBody works as expected
interface TestBody { hello: string }
expectAssignable<RequestBody>({ foo: 'bar' })
expectAssignable<RequestBody<TestBody>>({ hello: 'world' })
expectError<RequestBody<TestBody>>({ foo: 'bar' })
expectAssignable<RequestBody>('string')
expectAssignable<RequestBody<TestBody>>('string')
expectAssignable<RequestBody>(Buffer.from('hello world'))
expectAssignable<RequestBody>(new ReadableStream())
expectAssignable<RequestNDBody>([{ foo: 'bar' }])
expectAssignable<RequestNDBody<TestBody>[]>([{ hello: 'world' }])
expectError<RequestNDBody>({ foo: 'bar' })
expectError<RequestNDBody<TestBody>[]>([{ foo: 'bar' }])
expectAssignable<RequestNDBody>(['string'])
expectAssignable<RequestNDBody>(Buffer.from('hello world'))
expectAssignable<RequestNDBody>(new ReadableStream())
expectAssignable<ResponseBody>({ foo: 'bar' })
expectAssignable<ResponseBody<TestBody>>({ hello: 'world' })
expectError<ResponseBody<TestBody>>({ foo: 'bar' })
expectAssignable<ResponseBody>('string')
expectAssignable<ResponseBody<TestBody>>('string')
expectAssignable<ResponseBody>(true)
expectAssignable<ResponseBody>(new ReadableStream())
const transport = new Transport({
emit: (event, ...args) => true,
serializer: new Serializer(),
connectionPool: new ConnectionPool(),
maxRetries: 5,
requestTimeout: 1000,
suggestCompression: true,
compression: 'gzip',
sniffInterval: 1000,
sniffOnConnectionFault: true,
sniffEndpoint: '/sniff',
sniffOnStart: false
})
expectType<Transport>(transport)
expectType<TransportRequestCallback>(transport.request(params, options, (err, result) => {}))
transport.request(params, options, (err, result) => {
expectType<ApiError>(err)
expectType<ApiResponse>(result)
})
const promise = transport.request(params, options)
expectType<Promise<ApiResponse>>(promise)
promise.then(result => expectType<ApiResponse>(result))
expectType<ApiResponse>(await promise)
expectError(
transport.request({
method: 'POST',
path: '/',
body: 42
})
)

View File

@ -1,11 +0,0 @@
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"noEmit": true,
"strict": true
},
"files": [
"./index.ts"
]
}