@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.
Files changed (103) hide show
  1. package/.dockerignore +5 -0
  2. package/LICENSE +202 -0
  3. package/README.md +232 -0
  4. package/api/api/async_search.js +141 -0
  5. package/api/api/autoscaling.js +147 -0
  6. package/api/api/bulk.js +70 -0
  7. package/api/api/cat.js +648 -0
  8. package/api/api/ccr.js +403 -0
  9. package/api/api/clear_scroll.js +55 -0
  10. package/api/api/close_point_in_time.js +50 -0
  11. package/api/api/cluster.js +420 -0
  12. package/api/api/count.js +64 -0
  13. package/api/api/create.js +69 -0
  14. package/api/api/dangling_indices.js +115 -0
  15. package/api/api/delete.js +65 -0
  16. package/api/api/delete_by_query.js +71 -0
  17. package/api/api/delete_by_query_rethrottle.js +60 -0
  18. package/api/api/delete_script.js +56 -0
  19. package/api/api/enrich.js +173 -0
  20. package/api/api/eql.js +150 -0
  21. package/api/api/exists.js +65 -0
  22. package/api/api/exists_source.js +74 -0
  23. package/api/api/explain.js +65 -0
  24. package/api/api/features.js +81 -0
  25. package/api/api/field_caps.js +55 -0
  26. package/api/api/fleet.js +65 -0
  27. package/api/api/get.js +65 -0
  28. package/api/api/get_script.js +56 -0
  29. package/api/api/get_script_context.js +50 -0
  30. package/api/api/get_script_languages.js +50 -0
  31. package/api/api/get_source.js +65 -0
  32. package/api/api/graph.js +72 -0
  33. package/api/api/ilm.js +317 -0
  34. package/api/api/index.js +71 -0
  35. package/api/api/indices.js +1753 -0
  36. package/api/api/info.js +50 -0
  37. package/api/api/ingest.js +200 -0
  38. package/api/api/license.js +188 -0
  39. package/api/api/logstash.js +125 -0
  40. package/api/api/mget.js +70 -0
  41. package/api/api/migration.js +60 -0
  42. package/api/api/ml.js +2010 -0
  43. package/api/api/monitoring.js +66 -0
  44. package/api/api/msearch.js +70 -0
  45. package/api/api/msearch_template.js +70 -0
  46. package/api/api/mtermvectors.js +64 -0
  47. package/api/api/nodes.js +268 -0
  48. package/api/api/open_point_in_time.js +56 -0
  49. package/api/api/ping.js +50 -0
  50. package/api/api/put_script.js +71 -0
  51. package/api/api/rank_eval.js +61 -0
  52. package/api/api/reindex.js +56 -0
  53. package/api/api/reindex_rethrottle.js +60 -0
  54. package/api/api/render_search_template.js +55 -0
  55. package/api/api/rollup.js +319 -0
  56. package/api/api/scripts_painless_execute.js +50 -0
  57. package/api/api/scroll.js +55 -0
  58. package/api/api/search.js +64 -0
  59. package/api/api/search_mvt.js +87 -0
  60. package/api/api/search_shards.js +55 -0
  61. package/api/api/search_template.js +70 -0
  62. package/api/api/searchable_snapshots.js +186 -0
  63. package/api/api/security.js +1261 -0
  64. package/api/api/shutdown.js +124 -0
  65. package/api/api/slm.js +256 -0
  66. package/api/api/snapshot.js +439 -0
  67. package/api/api/sql.js +203 -0
  68. package/api/api/ssl.js +55 -0
  69. package/api/api/tasks.js +108 -0
  70. package/api/api/terms_enum.js +56 -0
  71. package/api/api/termvectors.js +67 -0
  72. package/api/api/text_structure.js +65 -0
  73. package/api/api/transform.js +268 -0
  74. package/api/api/update.js +69 -0
  75. package/api/api/update_by_query.js +67 -0
  76. package/api/api/update_by_query_rethrottle.js +60 -0
  77. package/api/api/watcher.js +333 -0
  78. package/api/api/xpack.js +76 -0
  79. package/api/index.js +508 -0
  80. package/api/new.d.ts +1585 -0
  81. package/api/requestParams.d.ts +2920 -0
  82. package/api/types.d.ts +15420 -0
  83. package/api/utils.js +58 -0
  84. package/codecov.yml +14 -0
  85. package/index.d.ts +2991 -0
  86. package/index.js +349 -0
  87. package/index.mjs +29 -0
  88. package/lib/Connection.d.ts +99 -0
  89. package/lib/Connection.js +392 -0
  90. package/lib/Helpers.d.ts +124 -0
  91. package/lib/Helpers.js +770 -0
  92. package/lib/Serializer.d.ts +30 -0
  93. package/lib/Serializer.js +94 -0
  94. package/lib/Transport.d.ts +162 -0
  95. package/lib/Transport.js +689 -0
  96. package/lib/errors.d.ts +90 -0
  97. package/lib/errors.js +159 -0
  98. package/lib/pool/BaseConnectionPool.js +262 -0
  99. package/lib/pool/CloudConnectionPool.js +64 -0
  100. package/lib/pool/ConnectionPool.js +246 -0
  101. package/lib/pool/index.d.ts +220 -0
  102. package/lib/pool/index.js +30 -0
  103. 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 }
@@ -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
+ }