@elastic/elasticsearch 7.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.dockerignore +5 -0
- package/LICENSE +202 -0
- package/README.md +232 -0
- package/api/api/async_search.js +141 -0
- package/api/api/autoscaling.js +147 -0
- package/api/api/bulk.js +70 -0
- package/api/api/cat.js +648 -0
- package/api/api/ccr.js +403 -0
- package/api/api/clear_scroll.js +55 -0
- package/api/api/close_point_in_time.js +50 -0
- package/api/api/cluster.js +420 -0
- package/api/api/count.js +64 -0
- package/api/api/create.js +69 -0
- package/api/api/dangling_indices.js +115 -0
- package/api/api/delete.js +65 -0
- package/api/api/delete_by_query.js +71 -0
- package/api/api/delete_by_query_rethrottle.js +60 -0
- package/api/api/delete_script.js +56 -0
- package/api/api/enrich.js +173 -0
- package/api/api/eql.js +150 -0
- package/api/api/exists.js +65 -0
- package/api/api/exists_source.js +74 -0
- package/api/api/explain.js +65 -0
- package/api/api/features.js +81 -0
- package/api/api/field_caps.js +55 -0
- package/api/api/fleet.js +65 -0
- package/api/api/get.js +65 -0
- package/api/api/get_script.js +56 -0
- package/api/api/get_script_context.js +50 -0
- package/api/api/get_script_languages.js +50 -0
- package/api/api/get_source.js +65 -0
- package/api/api/graph.js +72 -0
- package/api/api/ilm.js +317 -0
- package/api/api/index.js +71 -0
- package/api/api/indices.js +1753 -0
- package/api/api/info.js +50 -0
- package/api/api/ingest.js +200 -0
- package/api/api/license.js +188 -0
- package/api/api/logstash.js +125 -0
- package/api/api/mget.js +70 -0
- package/api/api/migration.js +60 -0
- package/api/api/ml.js +2010 -0
- package/api/api/monitoring.js +66 -0
- package/api/api/msearch.js +70 -0
- package/api/api/msearch_template.js +70 -0
- package/api/api/mtermvectors.js +64 -0
- package/api/api/nodes.js +268 -0
- package/api/api/open_point_in_time.js +56 -0
- package/api/api/ping.js +50 -0
- package/api/api/put_script.js +71 -0
- package/api/api/rank_eval.js +61 -0
- package/api/api/reindex.js +56 -0
- package/api/api/reindex_rethrottle.js +60 -0
- package/api/api/render_search_template.js +55 -0
- package/api/api/rollup.js +319 -0
- package/api/api/scripts_painless_execute.js +50 -0
- package/api/api/scroll.js +55 -0
- package/api/api/search.js +64 -0
- package/api/api/search_mvt.js +87 -0
- package/api/api/search_shards.js +55 -0
- package/api/api/search_template.js +70 -0
- package/api/api/searchable_snapshots.js +186 -0
- package/api/api/security.js +1261 -0
- package/api/api/shutdown.js +124 -0
- package/api/api/slm.js +256 -0
- package/api/api/snapshot.js +439 -0
- package/api/api/sql.js +203 -0
- package/api/api/ssl.js +55 -0
- package/api/api/tasks.js +108 -0
- package/api/api/terms_enum.js +56 -0
- package/api/api/termvectors.js +67 -0
- package/api/api/text_structure.js +65 -0
- package/api/api/transform.js +268 -0
- package/api/api/update.js +69 -0
- package/api/api/update_by_query.js +67 -0
- package/api/api/update_by_query_rethrottle.js +60 -0
- package/api/api/watcher.js +333 -0
- package/api/api/xpack.js +76 -0
- package/api/index.js +508 -0
- package/api/new.d.ts +1585 -0
- package/api/requestParams.d.ts +2920 -0
- package/api/types.d.ts +15420 -0
- package/api/utils.js +58 -0
- package/codecov.yml +14 -0
- package/index.d.ts +2991 -0
- package/index.js +349 -0
- package/index.mjs +29 -0
- package/lib/Connection.d.ts +99 -0
- package/lib/Connection.js +392 -0
- package/lib/Helpers.d.ts +124 -0
- package/lib/Helpers.js +770 -0
- package/lib/Serializer.d.ts +30 -0
- package/lib/Serializer.js +94 -0
- package/lib/Transport.d.ts +162 -0
- package/lib/Transport.js +689 -0
- package/lib/errors.d.ts +90 -0
- package/lib/errors.js +159 -0
- package/lib/pool/BaseConnectionPool.js +262 -0
- package/lib/pool/CloudConnectionPool.js +64 -0
- package/lib/pool/ConnectionPool.js +246 -0
- package/lib/pool/index.d.ts +220 -0
- package/lib/pool/index.js +30 -0
- package/package.json +106 -0
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Licensed to Elasticsearch B.V. under one or more contributor
|
|
3
|
+
* license agreements. See the NOTICE file distributed with
|
|
4
|
+
* this work for additional information regarding copyright
|
|
5
|
+
* ownership. Elasticsearch B.V. licenses this file to you under
|
|
6
|
+
* the Apache License, Version 2.0 (the "License"); you may
|
|
7
|
+
* not use this file except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing,
|
|
13
|
+
* software distributed under the License is distributed on an
|
|
14
|
+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
15
|
+
* KIND, either express or implied. See the License for the
|
|
16
|
+
* specific language governing permissions and limitations
|
|
17
|
+
* under the License.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
'use strict'
|
|
21
|
+
|
|
22
|
+
const assert = require('assert')
|
|
23
|
+
const { inspect } = require('util')
|
|
24
|
+
const hpagent = require('hpagent')
|
|
25
|
+
const http = require('http')
|
|
26
|
+
const https = require('https')
|
|
27
|
+
const debug = require('debug')('elasticsearch')
|
|
28
|
+
const { pipeline } = require('stream')
|
|
29
|
+
const INVALID_PATH_REGEX = /[^\u0021-\u00ff]/
|
|
30
|
+
const {
|
|
31
|
+
ConnectionError,
|
|
32
|
+
RequestAbortedError,
|
|
33
|
+
TimeoutError,
|
|
34
|
+
ConfigurationError
|
|
35
|
+
} = require('./errors')
|
|
36
|
+
|
|
37
|
+
class Connection {
|
|
38
|
+
constructor (opts) {
|
|
39
|
+
this.url = opts.url
|
|
40
|
+
this.ssl = opts.ssl || null
|
|
41
|
+
this.id = opts.id || stripAuth(opts.url.href)
|
|
42
|
+
this.headers = prepareHeaders(opts.headers, opts.auth)
|
|
43
|
+
this.deadCount = 0
|
|
44
|
+
this.resurrectTimeout = 0
|
|
45
|
+
this.caFingerprint = opts.caFingerprint
|
|
46
|
+
|
|
47
|
+
this._openRequests = 0
|
|
48
|
+
this._status = opts.status || Connection.statuses.ALIVE
|
|
49
|
+
this.roles = Object.assign({}, defaultRoles, opts.roles)
|
|
50
|
+
|
|
51
|
+
if (!['http:', 'https:'].includes(this.url.protocol)) {
|
|
52
|
+
throw new ConfigurationError(`Invalid protocol: '${this.url.protocol}'`)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (typeof opts.agent === 'function') {
|
|
56
|
+
this.agent = opts.agent(opts)
|
|
57
|
+
} else if (opts.agent === false) {
|
|
58
|
+
this.agent = undefined
|
|
59
|
+
} else {
|
|
60
|
+
const agentOptions = Object.assign({}, {
|
|
61
|
+
keepAlive: true,
|
|
62
|
+
keepAliveMsecs: 1000,
|
|
63
|
+
maxSockets: 256,
|
|
64
|
+
maxFreeSockets: 256,
|
|
65
|
+
scheduling: 'lifo'
|
|
66
|
+
}, opts.agent)
|
|
67
|
+
if (opts.proxy) {
|
|
68
|
+
agentOptions.proxy = opts.proxy
|
|
69
|
+
this.agent = this.url.protocol === 'http:'
|
|
70
|
+
? new hpagent.HttpProxyAgent(agentOptions)
|
|
71
|
+
: new hpagent.HttpsProxyAgent(Object.assign({}, agentOptions, this.ssl))
|
|
72
|
+
} else {
|
|
73
|
+
this.agent = this.url.protocol === 'http:'
|
|
74
|
+
? new http.Agent(agentOptions)
|
|
75
|
+
: new https.Agent(Object.assign({}, agentOptions, this.ssl))
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
this.makeRequest = this.url.protocol === 'http:'
|
|
80
|
+
? http.request
|
|
81
|
+
: https.request
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
request (params, callback) {
|
|
85
|
+
this._openRequests++
|
|
86
|
+
let cleanedListeners = false
|
|
87
|
+
|
|
88
|
+
const requestParams = this.buildRequestObject(params)
|
|
89
|
+
// https://github.com/nodejs/node/commit/b961d9fd83
|
|
90
|
+
if (INVALID_PATH_REGEX.test(requestParams.path) === true) {
|
|
91
|
+
callback(new TypeError(`ERR_UNESCAPED_CHARACTERS: ${requestParams.path}`), null)
|
|
92
|
+
/* istanbul ignore next */
|
|
93
|
+
return { abort: () => {} }
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
debug('Starting a new request', params)
|
|
97
|
+
const request = this.makeRequest(requestParams)
|
|
98
|
+
|
|
99
|
+
const onResponse = response => {
|
|
100
|
+
cleanListeners()
|
|
101
|
+
this._openRequests--
|
|
102
|
+
callback(null, response)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const onTimeout = () => {
|
|
106
|
+
cleanListeners()
|
|
107
|
+
this._openRequests--
|
|
108
|
+
request.once('error', () => {}) // we need to catch the request aborted error
|
|
109
|
+
request.abort()
|
|
110
|
+
callback(new TimeoutError('Request timed out', params), null)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const onError = err => {
|
|
114
|
+
cleanListeners()
|
|
115
|
+
this._openRequests--
|
|
116
|
+
callback(new ConnectionError(err.message), null)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const onAbort = () => {
|
|
120
|
+
cleanListeners()
|
|
121
|
+
request.once('error', () => {}) // we need to catch the request aborted error
|
|
122
|
+
debug('Request aborted', params)
|
|
123
|
+
this._openRequests--
|
|
124
|
+
callback(new RequestAbortedError(), null)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const onSocket = socket => {
|
|
128
|
+
/* istanbul ignore else */
|
|
129
|
+
if (!socket.isSessionReused()) {
|
|
130
|
+
socket.once('secureConnect', () => {
|
|
131
|
+
const issuerCertificate = getIssuerCertificate(socket)
|
|
132
|
+
/* istanbul ignore next */
|
|
133
|
+
if (issuerCertificate == null) {
|
|
134
|
+
onError(new Error('Invalid or malformed certificate'))
|
|
135
|
+
request.once('error', () => {}) // we need to catch the request aborted error
|
|
136
|
+
return request.abort()
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Check if fingerprint matches
|
|
140
|
+
/* istanbul ignore else */
|
|
141
|
+
if (this.caFingerprint !== issuerCertificate.fingerprint256) {
|
|
142
|
+
onError(new Error('Server certificate CA fingerprint does not match the value configured in caFingerprint'))
|
|
143
|
+
request.once('error', () => {}) // we need to catch the request aborted error
|
|
144
|
+
return request.abort()
|
|
145
|
+
}
|
|
146
|
+
})
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
request.on('response', onResponse)
|
|
151
|
+
request.on('timeout', onTimeout)
|
|
152
|
+
request.on('error', onError)
|
|
153
|
+
request.on('abort', onAbort)
|
|
154
|
+
if (this.caFingerprint != null) {
|
|
155
|
+
request.on('socket', onSocket)
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Disables the Nagle algorithm
|
|
159
|
+
request.setNoDelay(true)
|
|
160
|
+
|
|
161
|
+
// starts the request
|
|
162
|
+
if (isStream(params.body) === true) {
|
|
163
|
+
pipeline(params.body, request, err => {
|
|
164
|
+
/* istanbul ignore if */
|
|
165
|
+
if (err != null && cleanedListeners === false) {
|
|
166
|
+
cleanListeners()
|
|
167
|
+
this._openRequests--
|
|
168
|
+
callback(err, null)
|
|
169
|
+
}
|
|
170
|
+
})
|
|
171
|
+
} else {
|
|
172
|
+
request.end(params.body)
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return request
|
|
176
|
+
|
|
177
|
+
function cleanListeners () {
|
|
178
|
+
request.removeListener('response', onResponse)
|
|
179
|
+
request.removeListener('timeout', onTimeout)
|
|
180
|
+
request.removeListener('error', onError)
|
|
181
|
+
request.removeListener('abort', onAbort)
|
|
182
|
+
request.removeListener('socket', onSocket)
|
|
183
|
+
cleanedListeners = true
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// TODO: write a better closing logic
|
|
188
|
+
close (callback = () => {}) {
|
|
189
|
+
debug('Closing connection', this.id)
|
|
190
|
+
if (this._openRequests > 0) {
|
|
191
|
+
setTimeout(() => this.close(callback), 1000)
|
|
192
|
+
} else {
|
|
193
|
+
if (this.agent !== undefined) {
|
|
194
|
+
this.agent.destroy()
|
|
195
|
+
}
|
|
196
|
+
callback()
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
setRole (role, enabled) {
|
|
201
|
+
if (validRoles.indexOf(role) === -1) {
|
|
202
|
+
throw new ConfigurationError(`Unsupported role: '${role}'`)
|
|
203
|
+
}
|
|
204
|
+
if (typeof enabled !== 'boolean') {
|
|
205
|
+
throw new ConfigurationError('enabled should be a boolean')
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
this.roles[role] = enabled
|
|
209
|
+
return this
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
get status () {
|
|
213
|
+
return this._status
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
set status (status) {
|
|
217
|
+
assert(
|
|
218
|
+
~validStatuses.indexOf(status),
|
|
219
|
+
`Unsupported status: '${status}'`
|
|
220
|
+
)
|
|
221
|
+
this._status = status
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
buildRequestObject (params) {
|
|
225
|
+
const url = this.url
|
|
226
|
+
const request = {
|
|
227
|
+
protocol: url.protocol,
|
|
228
|
+
hostname: url.hostname[0] === '['
|
|
229
|
+
? url.hostname.slice(1, -1)
|
|
230
|
+
: url.hostname,
|
|
231
|
+
hash: url.hash,
|
|
232
|
+
search: url.search,
|
|
233
|
+
pathname: url.pathname,
|
|
234
|
+
path: '',
|
|
235
|
+
href: url.href,
|
|
236
|
+
origin: url.origin,
|
|
237
|
+
// https://github.com/elastic/elasticsearch-js/issues/843
|
|
238
|
+
port: url.port !== '' ? url.port : undefined,
|
|
239
|
+
headers: this.headers,
|
|
240
|
+
agent: this.agent
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const paramsKeys = Object.keys(params)
|
|
244
|
+
for (let i = 0, len = paramsKeys.length; i < len; i++) {
|
|
245
|
+
const key = paramsKeys[i]
|
|
246
|
+
if (key === 'path') {
|
|
247
|
+
request.pathname = resolve(request.pathname, params[key])
|
|
248
|
+
} else if (key === 'querystring' && !!params[key] === true) {
|
|
249
|
+
if (request.search === '') {
|
|
250
|
+
request.search = '?' + params[key]
|
|
251
|
+
} else {
|
|
252
|
+
request.search += '&' + params[key]
|
|
253
|
+
}
|
|
254
|
+
} else if (key === 'headers') {
|
|
255
|
+
request.headers = Object.assign({}, request.headers, params.headers)
|
|
256
|
+
} else {
|
|
257
|
+
request[key] = params[key]
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
request.path = request.pathname + request.search
|
|
262
|
+
|
|
263
|
+
return request
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// Handles console.log and utils.inspect invocations.
|
|
267
|
+
// We want to hide `auth`, `agent` and `ssl` since they made
|
|
268
|
+
// the logs very hard to read. The user can still
|
|
269
|
+
// access them with `instance.agent` and `instance.ssl`.
|
|
270
|
+
[inspect.custom] (depth, options) {
|
|
271
|
+
const {
|
|
272
|
+
authorization,
|
|
273
|
+
...headers
|
|
274
|
+
} = this.headers
|
|
275
|
+
|
|
276
|
+
return {
|
|
277
|
+
url: stripAuth(this.url.toString()),
|
|
278
|
+
id: this.id,
|
|
279
|
+
headers,
|
|
280
|
+
deadCount: this.deadCount,
|
|
281
|
+
resurrectTimeout: this.resurrectTimeout,
|
|
282
|
+
_openRequests: this._openRequests,
|
|
283
|
+
status: this.status,
|
|
284
|
+
roles: this.roles
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
toJSON () {
|
|
289
|
+
const {
|
|
290
|
+
authorization,
|
|
291
|
+
...headers
|
|
292
|
+
} = this.headers
|
|
293
|
+
|
|
294
|
+
return {
|
|
295
|
+
url: stripAuth(this.url.toString()),
|
|
296
|
+
id: this.id,
|
|
297
|
+
headers,
|
|
298
|
+
deadCount: this.deadCount,
|
|
299
|
+
resurrectTimeout: this.resurrectTimeout,
|
|
300
|
+
_openRequests: this._openRequests,
|
|
301
|
+
status: this.status,
|
|
302
|
+
roles: this.roles
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
Connection.statuses = {
|
|
308
|
+
ALIVE: 'alive',
|
|
309
|
+
DEAD: 'dead'
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
Connection.roles = {
|
|
313
|
+
MASTER: 'master',
|
|
314
|
+
DATA: 'data',
|
|
315
|
+
INGEST: 'ingest',
|
|
316
|
+
ML: 'ml'
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
const defaultRoles = {
|
|
320
|
+
[Connection.roles.MASTER]: true,
|
|
321
|
+
[Connection.roles.DATA]: true,
|
|
322
|
+
[Connection.roles.INGEST]: true,
|
|
323
|
+
[Connection.roles.ML]: false
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
const validStatuses = Object.keys(Connection.statuses)
|
|
327
|
+
.map(k => Connection.statuses[k])
|
|
328
|
+
const validRoles = Object.keys(Connection.roles)
|
|
329
|
+
.map(k => Connection.roles[k])
|
|
330
|
+
|
|
331
|
+
function stripAuth (url) {
|
|
332
|
+
if (url.indexOf('@') === -1) return url
|
|
333
|
+
return url.slice(0, url.indexOf('//') + 2) + url.slice(url.indexOf('@') + 1)
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
function isStream (obj) {
|
|
337
|
+
return obj != null && typeof obj.pipe === 'function'
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
function resolve (host, path) {
|
|
341
|
+
const hostEndWithSlash = host[host.length - 1] === '/'
|
|
342
|
+
const pathStartsWithSlash = path[0] === '/'
|
|
343
|
+
|
|
344
|
+
if (hostEndWithSlash === true && pathStartsWithSlash === true) {
|
|
345
|
+
return host + path.slice(1)
|
|
346
|
+
} else if (hostEndWithSlash !== pathStartsWithSlash) {
|
|
347
|
+
return host + path
|
|
348
|
+
} else {
|
|
349
|
+
return host + '/' + path
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
function prepareHeaders (headers = {}, auth) {
|
|
354
|
+
if (auth != null && headers.authorization == null) {
|
|
355
|
+
/* istanbul ignore else */
|
|
356
|
+
if (auth.apiKey) {
|
|
357
|
+
if (typeof auth.apiKey === 'object') {
|
|
358
|
+
headers.authorization = 'ApiKey ' + Buffer.from(`${auth.apiKey.id}:${auth.apiKey.api_key}`).toString('base64')
|
|
359
|
+
} else {
|
|
360
|
+
headers.authorization = `ApiKey ${auth.apiKey}`
|
|
361
|
+
}
|
|
362
|
+
} else if (auth.bearer) {
|
|
363
|
+
headers.authorization = `Bearer ${auth.bearer}`
|
|
364
|
+
} else if (auth.username && auth.password) {
|
|
365
|
+
headers.authorization = 'Basic ' + Buffer.from(`${auth.username}:${auth.password}`).toString('base64')
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
return headers
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
function getIssuerCertificate (socket) {
|
|
372
|
+
let certificate = socket.getPeerCertificate(true)
|
|
373
|
+
while (certificate && Object.keys(certificate).length > 0) {
|
|
374
|
+
// invalid certificate
|
|
375
|
+
if (certificate.issuerCertificate == null) {
|
|
376
|
+
return null
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// We have reached the root certificate.
|
|
380
|
+
// In case of self-signed certificates, `issuerCertificate` may be a circular reference.
|
|
381
|
+
if (certificate.fingerprint256 === certificate.issuerCertificate.fingerprint256) {
|
|
382
|
+
break
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// continue the loop
|
|
386
|
+
certificate = certificate.issuerCertificate
|
|
387
|
+
}
|
|
388
|
+
return certificate
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
module.exports = Connection
|
|
392
|
+
module.exports.internals = { prepareHeaders, getIssuerCertificate }
|
package/lib/Helpers.d.ts
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Licensed to Elasticsearch B.V. under one or more contributor
|
|
3
|
+
* license agreements. See the NOTICE file distributed with
|
|
4
|
+
* this work for additional information regarding copyright
|
|
5
|
+
* ownership. Elasticsearch B.V. licenses this file to you under
|
|
6
|
+
* the Apache License, Version 2.0 (the "License"); you may
|
|
7
|
+
* not use this file except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing,
|
|
13
|
+
* software distributed under the License is distributed on an
|
|
14
|
+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
15
|
+
* KIND, either express or implied. See the License for the
|
|
16
|
+
* specific language governing permissions and limitations
|
|
17
|
+
* under the License.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { Readable as ReadableStream } from 'stream'
|
|
21
|
+
import { TransportRequestOptions, ApiError, ApiResponse, RequestBody, Context } from './Transport'
|
|
22
|
+
import { Search, Msearch, Bulk } from '../api/requestParams'
|
|
23
|
+
|
|
24
|
+
export default class Helpers {
|
|
25
|
+
search<TDocument = unknown, TRequestBody extends RequestBody = Record<string, any>>(params: Search<TRequestBody>, options?: TransportRequestOptions): Promise<TDocument[]>
|
|
26
|
+
scrollSearch<TDocument = unknown, TResponse = Record<string, any>, TRequestBody extends RequestBody = Record<string, any>, TContext = Context>(params: Search<TRequestBody>, options?: TransportRequestOptions): AsyncIterable<ScrollSearchResponse<TDocument, TResponse, TContext>>
|
|
27
|
+
scrollDocuments<TDocument = unknown, TRequestBody extends RequestBody = Record<string, any>>(params: Search<TRequestBody>, options?: TransportRequestOptions): AsyncIterable<TDocument>
|
|
28
|
+
msearch(options?: MsearchHelperOptions, reqOptions?: TransportRequestOptions): MsearchHelper
|
|
29
|
+
bulk<TDocument = unknown>(options: BulkHelperOptions<TDocument>, reqOptions?: TransportRequestOptions): BulkHelper<BulkStats>
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface ScrollSearchResponse<TDocument = unknown, TResponse = Record<string, any>, TContext = Context> extends ApiResponse<TResponse, TContext> {
|
|
33
|
+
clear: () => Promise<void>
|
|
34
|
+
documents: TDocument[]
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface BulkHelper<T> extends Promise<T> {
|
|
38
|
+
abort: () => BulkHelper<T>
|
|
39
|
+
readonly stats: BulkStats
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface BulkStats {
|
|
43
|
+
total: number
|
|
44
|
+
failed: number
|
|
45
|
+
retry: number
|
|
46
|
+
successful: number
|
|
47
|
+
noop: number
|
|
48
|
+
time: number
|
|
49
|
+
bytes: number
|
|
50
|
+
aborted: boolean
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
interface IndexAction {
|
|
54
|
+
index: {
|
|
55
|
+
_index: string
|
|
56
|
+
[key: string]: any
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
interface CreateAction {
|
|
61
|
+
create: {
|
|
62
|
+
_index: string
|
|
63
|
+
[key: string]: any
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
interface UpdateActionOperation {
|
|
68
|
+
update: {
|
|
69
|
+
_index: string
|
|
70
|
+
[key: string]: any
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
interface DeleteAction {
|
|
75
|
+
delete: {
|
|
76
|
+
_index: string
|
|
77
|
+
[key: string]: any
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
type UpdateAction = [UpdateActionOperation, Record<string, any>]
|
|
82
|
+
type Action = IndexAction | CreateAction | UpdateAction | DeleteAction
|
|
83
|
+
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
|
|
84
|
+
|
|
85
|
+
export interface BulkHelperOptions<TDocument = unknown> extends Omit<Bulk, 'body'> {
|
|
86
|
+
datasource: TDocument[] | Buffer | ReadableStream | AsyncIterator<TDocument>
|
|
87
|
+
onDocument: (doc: TDocument) => Action
|
|
88
|
+
flushBytes?: number
|
|
89
|
+
flushInterval?: number
|
|
90
|
+
concurrency?: number
|
|
91
|
+
retries?: number
|
|
92
|
+
wait?: number
|
|
93
|
+
onDrop?: (doc: OnDropDocument<TDocument>) => void
|
|
94
|
+
refreshOnCompletion?: boolean | string
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export interface OnDropDocument<TDocument = unknown> {
|
|
98
|
+
status: number
|
|
99
|
+
error: {
|
|
100
|
+
type: string,
|
|
101
|
+
reason: string,
|
|
102
|
+
caused_by: {
|
|
103
|
+
type: string,
|
|
104
|
+
reason: string
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
document: TDocument
|
|
108
|
+
retried: boolean
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export interface MsearchHelperOptions extends Omit<Msearch, 'body'> {
|
|
112
|
+
operations?: number
|
|
113
|
+
flushInterval?: number
|
|
114
|
+
concurrency?: number
|
|
115
|
+
retries?: number
|
|
116
|
+
wait?: number
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
declare type callbackFn<Response, Context> = (err: ApiError, result: ApiResponse<Response, Context>) => void;
|
|
120
|
+
export interface MsearchHelper extends Promise<void> {
|
|
121
|
+
stop(error?: Error): void
|
|
122
|
+
search<TResponse = Record<string, any>, TRequestBody extends RequestBody = Record<string, any>, TContext = Context>(header: Omit<Search, 'body'>, body: TRequestBody): Promise<ApiResponse<TResponse, TContext>>
|
|
123
|
+
search<TResponse = Record<string, any>, TRequestBody extends RequestBody = Record<string, any>, TContext = Context>(header: Omit<Search, 'body'>, body: TRequestBody, callback: callbackFn<TResponse, TContext>): void
|
|
124
|
+
}
|