@elastic/elasticsearch
Advanced tools
Comparing version 7.13.0 to 7.14.0
@@ -26,4 +26,4 @@ /* | ||
const { handleError, snakeCaseKeys, normalizeArguments, kConfigurationError } = require('../utils') | ||
const acceptedQuerystring = ['pretty', 'human', 'error_trace', 'source', 'filter_path', 'only_managed', 'only_errors'] | ||
const snakeCase = { errorTrace: 'error_trace', filterPath: 'filter_path', onlyManaged: 'only_managed', onlyErrors: 'only_errors' } | ||
const acceptedQuerystring = ['pretty', 'human', 'error_trace', 'source', 'filter_path', 'only_managed', 'only_errors', 'dry_run'] | ||
const snakeCase = { errorTrace: 'error_trace', filterPath: 'filter_path', onlyManaged: 'only_managed', onlyErrors: 'only_errors', dryRun: 'dry_run' } | ||
@@ -136,2 +136,23 @@ function IlmApi (transport, ConfigurationError) { | ||
IlmApi.prototype.migrateToDataTiers = function ilmMigrateToDataTiersApi (params, options, callback) { | ||
;[params, options, callback] = normalizeArguments(params, options, callback) | ||
let { method, body, ...querystring } = params | ||
querystring = snakeCaseKeys(acceptedQuerystring, snakeCase, querystring) | ||
let path = '' | ||
if (method == null) method = 'POST' | ||
path = '/' + '_ilm' + '/' + 'migrate_to_data_tiers' | ||
// build request object | ||
const request = { | ||
method, | ||
path, | ||
body: body || '', | ||
querystring | ||
} | ||
return this.transport.request(request, options, callback) | ||
} | ||
IlmApi.prototype.moveToStep = function ilmMoveToStepApi (params, options, callback) { | ||
@@ -292,2 +313,3 @@ ;[params, options, callback] = normalizeArguments(params, options, callback) | ||
get_status: { get () { return this.getStatus } }, | ||
migrate_to_data_tiers: { get () { return this.migrateToDataTiers } }, | ||
move_to_step: { get () { return this.moveToStep } }, | ||
@@ -294,0 +316,0 @@ put_lifecycle: { get () { return this.putLifecycle } }, |
@@ -1035,2 +1035,164 @@ /* | ||
SecurityApi.prototype.samlAuthenticate = function securitySamlAuthenticateApi (params, options, callback) { | ||
;[params, options, callback] = normalizeArguments(params, options, callback) | ||
// check required parameters | ||
if (params.body == null) { | ||
const err = new this[kConfigurationError]('Missing required parameter: body') | ||
return handleError(err, callback) | ||
} | ||
let { method, body, ...querystring } = params | ||
querystring = snakeCaseKeys(acceptedQuerystring, snakeCase, querystring) | ||
let path = '' | ||
if (method == null) method = 'POST' | ||
path = '/' + '_security' + '/' + 'saml' + '/' + 'authenticate' | ||
// build request object | ||
const request = { | ||
method, | ||
path, | ||
body: body || '', | ||
querystring | ||
} | ||
return this.transport.request(request, options, callback) | ||
} | ||
SecurityApi.prototype.samlCompleteLogout = function securitySamlCompleteLogoutApi (params, options, callback) { | ||
;[params, options, callback] = normalizeArguments(params, options, callback) | ||
// check required parameters | ||
if (params.body == null) { | ||
const err = new this[kConfigurationError]('Missing required parameter: body') | ||
return handleError(err, callback) | ||
} | ||
let { method, body, ...querystring } = params | ||
querystring = snakeCaseKeys(acceptedQuerystring, snakeCase, querystring) | ||
let path = '' | ||
if (method == null) method = 'POST' | ||
path = '/' + '_security' + '/' + 'saml' + '/' + 'complete_logout' | ||
// build request object | ||
const request = { | ||
method, | ||
path, | ||
body: body || '', | ||
querystring | ||
} | ||
return this.transport.request(request, options, callback) | ||
} | ||
SecurityApi.prototype.samlInvalidate = function securitySamlInvalidateApi (params, options, callback) { | ||
;[params, options, callback] = normalizeArguments(params, options, callback) | ||
// check required parameters | ||
if (params.body == null) { | ||
const err = new this[kConfigurationError]('Missing required parameter: body') | ||
return handleError(err, callback) | ||
} | ||
let { method, body, ...querystring } = params | ||
querystring = snakeCaseKeys(acceptedQuerystring, snakeCase, querystring) | ||
let path = '' | ||
if (method == null) method = 'POST' | ||
path = '/' + '_security' + '/' + 'saml' + '/' + 'invalidate' | ||
// build request object | ||
const request = { | ||
method, | ||
path, | ||
body: body || '', | ||
querystring | ||
} | ||
return this.transport.request(request, options, callback) | ||
} | ||
SecurityApi.prototype.samlLogout = function securitySamlLogoutApi (params, options, callback) { | ||
;[params, options, callback] = normalizeArguments(params, options, callback) | ||
// check required parameters | ||
if (params.body == null) { | ||
const err = new this[kConfigurationError]('Missing required parameter: body') | ||
return handleError(err, callback) | ||
} | ||
let { method, body, ...querystring } = params | ||
querystring = snakeCaseKeys(acceptedQuerystring, snakeCase, querystring) | ||
let path = '' | ||
if (method == null) method = 'POST' | ||
path = '/' + '_security' + '/' + 'saml' + '/' + 'logout' | ||
// build request object | ||
const request = { | ||
method, | ||
path, | ||
body: body || '', | ||
querystring | ||
} | ||
return this.transport.request(request, options, callback) | ||
} | ||
SecurityApi.prototype.samlPrepareAuthentication = function securitySamlPrepareAuthenticationApi (params, options, callback) { | ||
;[params, options, callback] = normalizeArguments(params, options, callback) | ||
// check required parameters | ||
if (params.body == null) { | ||
const err = new this[kConfigurationError]('Missing required parameter: body') | ||
return handleError(err, callback) | ||
} | ||
let { method, body, ...querystring } = params | ||
querystring = snakeCaseKeys(acceptedQuerystring, snakeCase, querystring) | ||
let path = '' | ||
if (method == null) method = 'POST' | ||
path = '/' + '_security' + '/' + 'saml' + '/' + 'prepare' | ||
// build request object | ||
const request = { | ||
method, | ||
path, | ||
body: body || '', | ||
querystring | ||
} | ||
return this.transport.request(request, options, callback) | ||
} | ||
SecurityApi.prototype.samlServiceProviderMetadata = function securitySamlServiceProviderMetadataApi (params, options, callback) { | ||
;[params, options, callback] = normalizeArguments(params, options, callback) | ||
// check required parameters | ||
if (params.realm_name == null && params.realmName == null) { | ||
const err = new this[kConfigurationError]('Missing required parameter: realm_name or realmName') | ||
return handleError(err, callback) | ||
} | ||
let { method, body, realmName, realm_name, ...querystring } = params | ||
querystring = snakeCaseKeys(acceptedQuerystring, snakeCase, querystring) | ||
let path = '' | ||
if (method == null) method = 'GET' | ||
path = '/' + '_security' + '/' + 'saml' + '/' + 'metadata' + '/' + encodeURIComponent(realm_name || realmName) | ||
// build request object | ||
const request = { | ||
method, | ||
path, | ||
body: null, | ||
querystring | ||
} | ||
return this.transport.request(request, options, callback) | ||
} | ||
Object.defineProperties(SecurityApi.prototype, { | ||
@@ -1069,5 +1231,11 @@ change_password: { get () { return this.changePassword } }, | ||
put_role_mapping: { get () { return this.putRoleMapping } }, | ||
put_user: { get () { return this.putUser } } | ||
put_user: { get () { return this.putUser } }, | ||
saml_authenticate: { get () { return this.samlAuthenticate } }, | ||
saml_complete_logout: { get () { return this.samlCompleteLogout } }, | ||
saml_invalidate: { get () { return this.samlInvalidate } }, | ||
saml_logout: { get () { return this.samlLogout } }, | ||
saml_prepare_authentication: { get () { return this.samlPrepareAuthentication } }, | ||
saml_service_provider_metadata: { get () { return this.samlServiceProviderMetadata } } | ||
}) | ||
module.exports = SecurityApi |
@@ -26,4 +26,4 @@ /* | ||
const { handleError, snakeCaseKeys, normalizeArguments, kConfigurationError } = require('../utils') | ||
const acceptedQuerystring = ['master_timeout', 'timeout', 'pretty', 'human', 'error_trace', 'source', 'filter_path', 'wait_for_completion', 'verify', 'ignore_unavailable', 'index_details', 'verbose', 'local'] | ||
const snakeCase = { masterTimeout: 'master_timeout', errorTrace: 'error_trace', filterPath: 'filter_path', waitForCompletion: 'wait_for_completion', ignoreUnavailable: 'ignore_unavailable', indexDetails: 'index_details' } | ||
const acceptedQuerystring = ['master_timeout', 'timeout', 'pretty', 'human', 'error_trace', 'source', 'filter_path', 'wait_for_completion', 'verify', 'ignore_unavailable', 'index_details', 'include_repository', 'verbose', 'local', 'blob_count', 'concurrency', 'read_node_count', 'early_read_node_count', 'seed', 'rare_action_probability', 'max_blob_size', 'max_total_data_size', 'detailed', 'rarely_abort_writes'] | ||
const snakeCase = { masterTimeout: 'master_timeout', errorTrace: 'error_trace', filterPath: 'filter_path', waitForCompletion: 'wait_for_completion', ignoreUnavailable: 'ignore_unavailable', indexDetails: 'index_details', includeRepository: 'include_repository', blobCount: 'blob_count', readNodeCount: 'read_node_count', earlyReadNodeCount: 'early_read_node_count', rareActionProbability: 'rare_action_probability', maxBlobSize: 'max_blob_size', maxTotalDataSize: 'max_total_data_size', rarelyAbortWrites: 'rarely_abort_writes' } | ||
@@ -305,2 +305,29 @@ function SnapshotApi (transport, ConfigurationError) { | ||
SnapshotApi.prototype.repositoryAnalyze = function snapshotRepositoryAnalyzeApi (params, options, callback) { | ||
;[params, options, callback] = normalizeArguments(params, options, callback) | ||
// check required parameters | ||
if (params.repository == null) { | ||
const err = new this[kConfigurationError]('Missing required parameter: repository') | ||
return handleError(err, callback) | ||
} | ||
let { method, body, repository, ...querystring } = params | ||
querystring = snakeCaseKeys(acceptedQuerystring, snakeCase, querystring) | ||
let path = '' | ||
if (method == null) method = 'POST' | ||
path = '/' + '_snapshot' + '/' + encodeURIComponent(repository) + '/' + '_analyze' | ||
// build request object | ||
const request = { | ||
method, | ||
path, | ||
body: body || '', | ||
querystring | ||
} | ||
return this.transport.request(request, options, callback) | ||
} | ||
SnapshotApi.prototype.restore = function snapshotRestoreApi (params, options, callback) { | ||
@@ -410,2 +437,3 @@ ;[params, options, callback] = normalizeArguments(params, options, callback) | ||
get_repository: { get () { return this.getRepository } }, | ||
repository_analyze: { get () { return this.repositoryAnalyze } }, | ||
verify_repository: { get () { return this.verifyRepository } } | ||
@@ -412,0 +440,0 @@ }) |
@@ -26,4 +26,4 @@ /* | ||
const { handleError, snakeCaseKeys, normalizeArguments, kConfigurationError } = require('../utils') | ||
const acceptedQuerystring = ['pretty', 'human', 'error_trace', 'source', 'filter_path', 'format'] | ||
const snakeCase = { errorTrace: 'error_trace', filterPath: 'filter_path' } | ||
const acceptedQuerystring = ['pretty', 'human', 'error_trace', 'source', 'filter_path', 'delimiter', 'format', 'keep_alive', 'wait_for_completion_timeout'] | ||
const snakeCase = { errorTrace: 'error_trace', filterPath: 'filter_path', keepAlive: 'keep_alive', waitForCompletionTimeout: 'wait_for_completion_timeout' } | ||
@@ -62,2 +62,83 @@ function SqlApi (transport, ConfigurationError) { | ||
SqlApi.prototype.deleteAsync = function sqlDeleteAsyncApi (params, options, callback) { | ||
;[params, options, callback] = normalizeArguments(params, options, callback) | ||
// check required parameters | ||
if (params.id == null) { | ||
const err = new this[kConfigurationError]('Missing required parameter: id') | ||
return handleError(err, callback) | ||
} | ||
let { method, body, id, ...querystring } = params | ||
querystring = snakeCaseKeys(acceptedQuerystring, snakeCase, querystring) | ||
let path = '' | ||
if (method == null) method = 'DELETE' | ||
path = '/' + '_sql' + '/' + 'async' + '/' + 'delete' + '/' + encodeURIComponent(id) | ||
// build request object | ||
const request = { | ||
method, | ||
path, | ||
body: body || '', | ||
querystring | ||
} | ||
return this.transport.request(request, options, callback) | ||
} | ||
SqlApi.prototype.getAsync = function sqlGetAsyncApi (params, options, callback) { | ||
;[params, options, callback] = normalizeArguments(params, options, callback) | ||
// check required parameters | ||
if (params.id == null) { | ||
const err = new this[kConfigurationError]('Missing required parameter: id') | ||
return handleError(err, callback) | ||
} | ||
let { method, body, id, ...querystring } = params | ||
querystring = snakeCaseKeys(acceptedQuerystring, snakeCase, querystring) | ||
let path = '' | ||
if (method == null) method = 'GET' | ||
path = '/' + '_sql' + '/' + 'async' + '/' + encodeURIComponent(id) | ||
// build request object | ||
const request = { | ||
method, | ||
path, | ||
body: null, | ||
querystring | ||
} | ||
return this.transport.request(request, options, callback) | ||
} | ||
SqlApi.prototype.getAsyncStatus = function sqlGetAsyncStatusApi (params, options, callback) { | ||
;[params, options, callback] = normalizeArguments(params, options, callback) | ||
// check required parameters | ||
if (params.id == null) { | ||
const err = new this[kConfigurationError]('Missing required parameter: id') | ||
return handleError(err, callback) | ||
} | ||
let { method, body, id, ...querystring } = params | ||
querystring = snakeCaseKeys(acceptedQuerystring, snakeCase, querystring) | ||
let path = '' | ||
if (method == null) method = 'GET' | ||
path = '/' + '_sql' + '/' + 'async' + '/' + 'status' + '/' + encodeURIComponent(id) | ||
// build request object | ||
const request = { | ||
method, | ||
path, | ||
body: null, | ||
querystring | ||
} | ||
return this.transport.request(request, options, callback) | ||
} | ||
SqlApi.prototype.query = function sqlQueryApi (params, options, callback) { | ||
@@ -118,5 +199,8 @@ ;[params, options, callback] = normalizeArguments(params, options, callback) | ||
Object.defineProperties(SqlApi.prototype, { | ||
clear_cursor: { get () { return this.clearCursor } } | ||
clear_cursor: { get () { return this.clearCursor } }, | ||
delete_async: { get () { return this.deleteAsync } }, | ||
get_async: { get () { return this.getAsync } }, | ||
get_async_status: { get () { return this.getAsyncStatus } } | ||
}) | ||
module.exports = SqlApi |
@@ -87,2 +87,3 @@ /* | ||
const TasksApi = require('./api/tasks') | ||
const termsEnumApi = require('./api/terms_enum') | ||
const termvectorsApi = require('./api/termvectors') | ||
@@ -205,2 +206,3 @@ const TextStructureApi = require('./api/text_structure') | ||
ESAPI.prototype.searchTemplate = searchTemplateApi | ||
ESAPI.prototype.termsEnum = termsEnumApi | ||
ESAPI.prototype.termvectors = termvectorsApi | ||
@@ -467,2 +469,3 @@ ESAPI.prototype.update = updateApi | ||
}, | ||
terms_enum: { get () { return this.termsEnum } }, | ||
textStructure: { | ||
@@ -469,0 +472,0 @@ get () { |
@@ -119,2 +119,6 @@ /* | ||
if (process.env.ELASTIC_CLIENT_APIVERSIONING === 'true') { | ||
options.headers = Object.assign({ accept: 'application/vnd.elasticsearch+json; compatible-with=7' }, options.headers) | ||
} | ||
this[kInitialOptions] = options | ||
@@ -255,2 +259,6 @@ this[kExtensions] = [] | ||
const client = new Client(options) | ||
// sync product check | ||
const tSymbol = Object.getOwnPropertySymbols(this.transport) | ||
.filter(symbol => symbol.description === 'product check')[0] | ||
client.transport[tSymbol] = this.transport[tSymbol] | ||
// Add parent extensions | ||
@@ -257,0 +265,0 @@ if (this[kExtensions].length > 0) { |
@@ -334,2 +334,4 @@ /* | ||
} | ||
} else if (auth.bearer) { | ||
headers.authorization = `Bearer ${auth.bearer}` | ||
} else if (auth.username && auth.password) { | ||
@@ -336,0 +338,0 @@ headers.authorization = 'Basic ' + Buffer.from(`${auth.username}:${auth.password}`).toString('base64') |
@@ -84,1 +84,8 @@ /* | ||
} | ||
export declare class ProductNotSupportedError<TResponse = Record<string, any>, TContext = Context> extends ElasticsearchClientError { | ||
name: string; | ||
message: string; | ||
meta: ApiResponse<TResponse, TContext>; | ||
constructor(meta: ApiResponse); | ||
} |
@@ -136,2 +136,12 @@ /* | ||
class ProductNotSupportedError extends ElasticsearchClientError { | ||
constructor (meta) { | ||
super('Product Not Supported Error') | ||
Error.captureStackTrace(this, ProductNotSupportedError) | ||
this.name = 'ProductNotSupportedError' | ||
this.message = 'The client noticed that the server is not Elasticsearch and we do not support this unknown product.' | ||
this.meta = meta | ||
} | ||
} | ||
module.exports = { | ||
@@ -146,3 +156,4 @@ ElasticsearchClientError, | ||
ResponseError, | ||
RequestAbortedError | ||
RequestAbortedError, | ||
ProductNotSupportedError | ||
} |
@@ -39,2 +39,3 @@ /* | ||
abort: () => BulkHelper<T> | ||
readonly stats: BulkStats | ||
} | ||
@@ -47,2 +48,3 @@ | ||
successful: number | ||
noop: number | ||
time: number | ||
@@ -49,0 +51,0 @@ bytes: number |
@@ -459,2 +459,3 @@ /* | ||
successful: 0, | ||
noop: 0, | ||
time: 0, | ||
@@ -467,2 +468,5 @@ bytes: 0, | ||
const helper = { | ||
get stats () { | ||
return stats | ||
}, | ||
then (onFulfilled, onRejected) { | ||
@@ -697,2 +701,7 @@ return p.then(onFulfilled, onRejected) | ||
stats.successful += body.items.length | ||
for (const item of body.items) { | ||
if (item.update && item.update.result === 'noop') { | ||
stats.noop++ | ||
} | ||
} | ||
return callback(null, []) | ||
@@ -699,0 +708,0 @@ } |
@@ -64,2 +64,6 @@ /* | ||
interface BearerAuth { | ||
bearer: string | ||
} | ||
interface resurrectOptions { | ||
@@ -208,2 +212,3 @@ now?: number; | ||
BasicAuth, | ||
BearerAuth, | ||
internals, | ||
@@ -210,0 +215,0 @@ resurrectOptions, |
@@ -29,3 +29,4 @@ /* | ||
errors.NoLivingConnectionsError | errors.ResponseError | | ||
errors.TimeoutError | errors.RequestAbortedError | ||
errors.TimeoutError | errors.RequestAbortedError | | ||
errors.ProductNotSupportedError | ||
@@ -32,0 +33,0 @@ export type Context = unknown |
@@ -27,2 +27,3 @@ /* | ||
const ms = require('ms') | ||
const { EventEmitter } = require('events') | ||
const { | ||
@@ -33,3 +34,4 @@ ConnectionError, | ||
ResponseError, | ||
ConfigurationError | ||
ConfigurationError, | ||
ProductNotSupportedError | ||
} = require('./errors') | ||
@@ -39,2 +41,3 @@ | ||
const productCheckEmitter = new EventEmitter() | ||
const clientVersion = require('../package.json').version | ||
@@ -44,2 +47,4 @@ const userAgent = `elasticsearch-js/${clientVersion} (${os.platform()} ${os.release()}-${os.arch()}; Node.js ${process.version})` | ||
const MAX_STRING_LENGTH = buffer.constants.MAX_STRING_LENGTH | ||
const kProductCheck = Symbol('product check') | ||
const kApiVersioning = Symbol('api versioning') | ||
@@ -71,2 +76,4 @@ class Transport { | ||
this.opaqueIdPrefix = opts.opaqueIdPrefix | ||
this[kProductCheck] = 0 // 0 = to be checked, 1 = checking, 2 = checked-ok, 3 checked-notok, 4 checked-nodefault | ||
this[kApiVersioning] = process.env.ELASTIC_CLIENT_APIVERSIONING === 'true' | ||
@@ -89,3 +96,7 @@ this.nodeFilter = opts.nodeFilter || defaultNodeFilter | ||
if (opts.sniffOnStart === true) { | ||
this.sniff({ reason: Transport.sniffReasons.SNIFF_ON_START }) | ||
// timer needed otherwise it will clash | ||
// with the product check testing | ||
setTimeout(() => { | ||
this.sniff({ reason: Transport.sniffReasons.SNIFF_ON_START }) | ||
}, 10) | ||
} | ||
@@ -304,3 +315,4 @@ } | ||
if (result.headers['content-type'] !== undefined && | ||
result.headers['content-type'].indexOf('application/json') > -1 && | ||
(result.headers['content-type'].indexOf('application/json') > -1 || | ||
result.headers['content-type'].indexOf('application/vnd.elasticsearch+json') > -1) && | ||
isHead === false && | ||
@@ -357,87 +369,126 @@ payload !== '' | ||
this.emit('serialization', null, result) | ||
const headers = Object.assign({}, this.headers, lowerCaseHeaders(options.headers)) | ||
const prepareRequest = () => { | ||
this.emit('serialization', null, result) | ||
const headers = Object.assign({}, this.headers, lowerCaseHeaders(options.headers)) | ||
if (options.opaqueId !== undefined) { | ||
headers['x-opaque-id'] = this.opaqueIdPrefix !== null | ||
? this.opaqueIdPrefix + options.opaqueId | ||
: options.opaqueId | ||
} | ||
if (options.opaqueId !== undefined) { | ||
headers['x-opaque-id'] = this.opaqueIdPrefix !== null | ||
? this.opaqueIdPrefix + options.opaqueId | ||
: options.opaqueId | ||
} | ||
// handle json body | ||
if (params.body != null) { | ||
if (shouldSerialize(params.body) === true) { | ||
try { | ||
params.body = this.serializer.serialize(params.body) | ||
} catch (err) { | ||
this.emit('request', err, result) | ||
process.nextTick(callback, err, result) | ||
return transportReturn | ||
// handle json body | ||
if (params.body != null) { | ||
if (shouldSerialize(params.body) === true) { | ||
try { | ||
params.body = this.serializer.serialize(params.body) | ||
} catch (err) { | ||
this.emit('request', err, result) | ||
process.nextTick(callback, err, result) | ||
return transportReturn | ||
} | ||
} | ||
if (params.body !== '') { | ||
headers['content-type'] = headers['content-type'] || (this[kApiVersioning] ? 'application/vnd.elasticsearch+json; compatible-with=7' : 'application/json') | ||
} | ||
// handle ndjson body | ||
} else if (params.bulkBody != null) { | ||
if (shouldSerialize(params.bulkBody) === true) { | ||
try { | ||
params.body = this.serializer.ndserialize(params.bulkBody) | ||
} catch (err) { | ||
this.emit('request', err, result) | ||
process.nextTick(callback, err, result) | ||
return transportReturn | ||
} | ||
} else { | ||
params.body = params.bulkBody | ||
} | ||
if (params.body !== '') { | ||
headers['content-type'] = headers['content-type'] || (this[kApiVersioning] ? 'application/vnd.elasticsearch+x-ndjson; compatible-with=7' : 'application/x-ndjson') | ||
} | ||
} | ||
if (params.body !== '') { | ||
headers['content-type'] = headers['content-type'] || 'application/json' | ||
params.headers = headers | ||
// serializes the querystring | ||
if (options.querystring == null) { | ||
params.querystring = this.serializer.qserialize(params.querystring) | ||
} else { | ||
params.querystring = this.serializer.qserialize( | ||
Object.assign({}, params.querystring, options.querystring) | ||
) | ||
} | ||
// handle ndjson body | ||
} else if (params.bulkBody != null) { | ||
if (shouldSerialize(params.bulkBody) === true) { | ||
try { | ||
params.body = this.serializer.ndserialize(params.bulkBody) | ||
} catch (err) { | ||
this.emit('request', err, result) | ||
process.nextTick(callback, err, result) | ||
return transportReturn | ||
// handles request timeout | ||
params.timeout = toMs(options.requestTimeout || this.requestTimeout) | ||
if (options.asStream === true) params.asStream = true | ||
meta.request.params = params | ||
meta.request.options = options | ||
// handle compression | ||
if (params.body !== '' && params.body != null) { | ||
if (isStream(params.body) === true) { | ||
if (compression === 'gzip') { | ||
params.headers['content-encoding'] = compression | ||
params.body = params.body.pipe(createGzip()) | ||
} | ||
makeRequest() | ||
} else if (compression === 'gzip') { | ||
gzip(params.body, (err, buffer) => { | ||
/* istanbul ignore next */ | ||
if (err) { | ||
this.emit('request', err, result) | ||
return callback(err, result) | ||
} | ||
params.headers['content-encoding'] = compression | ||
params.headers['content-length'] = '' + Buffer.byteLength(buffer) | ||
params.body = buffer | ||
makeRequest() | ||
}) | ||
} else { | ||
params.headers['content-length'] = '' + Buffer.byteLength(params.body) | ||
makeRequest() | ||
} | ||
} else { | ||
params.body = params.bulkBody | ||
makeRequest() | ||
} | ||
if (params.body !== '') { | ||
headers['content-type'] = headers['content-type'] || 'application/x-ndjson' | ||
} | ||
} | ||
params.headers = headers | ||
// serializes the querystring | ||
if (options.querystring == null) { | ||
params.querystring = this.serializer.qserialize(params.querystring) | ||
} else { | ||
params.querystring = this.serializer.qserialize( | ||
Object.assign({}, params.querystring, options.querystring) | ||
) | ||
} | ||
// handles request timeout | ||
params.timeout = toMs(options.requestTimeout || this.requestTimeout) | ||
if (options.asStream === true) params.asStream = true | ||
meta.request.params = params | ||
meta.request.options = options | ||
// handle compression | ||
if (params.body !== '' && params.body != null) { | ||
if (isStream(params.body) === true) { | ||
if (compression === 'gzip') { | ||
params.headers['content-encoding'] = compression | ||
params.body = params.body.pipe(createGzip()) | ||
} | ||
makeRequest() | ||
} else if (compression === 'gzip') { | ||
gzip(params.body, (err, buffer) => { | ||
/* istanbul ignore next */ | ||
if (err) { | ||
// still need to check the product or waiting for the check to finish | ||
if (this[kProductCheck] === 0 || this[kProductCheck] === 1) { | ||
// let pass info requests | ||
if (params.method === 'GET' && params.path === '/') { | ||
prepareRequest() | ||
} else { | ||
// wait for product check to finish | ||
productCheckEmitter.once('product-check', (error, status) => { | ||
if (status === false) { | ||
const err = error || new ProductNotSupportedError(result) | ||
if (this[kProductCheck] === 4) { | ||
err.message = 'The client noticed that the server is not a supported distribution of Elasticsearch' | ||
} | ||
this.emit('request', err, result) | ||
return callback(err, result) | ||
process.nextTick(callback, err, result) | ||
} else { | ||
prepareRequest() | ||
} | ||
params.headers['content-encoding'] = compression | ||
params.headers['content-length'] = '' + Buffer.byteLength(buffer) | ||
params.body = buffer | ||
makeRequest() | ||
}) | ||
} else { | ||
params.headers['content-length'] = '' + Buffer.byteLength(params.body) | ||
makeRequest() | ||
// the very first request triggers the product check | ||
if (this[kProductCheck] === 0) { | ||
this.productCheck() | ||
} | ||
} | ||
// the product check is finished and it's not Elasticsearch | ||
} else if (this[kProductCheck] === 3 || this[kProductCheck] === 4) { | ||
const err = new ProductNotSupportedError(result) | ||
if (this[kProductCheck] === 4) { | ||
err.message = 'The client noticed that the server is not a supported distribution of Elasticsearch' | ||
} | ||
this.emit('request', err, result) | ||
process.nextTick(callback, err, result) | ||
// the product check finished and it's Elasticsearch | ||
} else { | ||
makeRequest() | ||
prepareRequest() | ||
} | ||
@@ -502,2 +553,61 @@ | ||
} | ||
productCheck () { | ||
debug('Start product check') | ||
this[kProductCheck] = 1 | ||
this.request({ | ||
method: 'GET', | ||
path: '/' | ||
}, (err, result) => { | ||
this[kProductCheck] = 3 | ||
if (err) { | ||
debug('Product check failed', err) | ||
if (err.statusCode === 401 || err.statusCode === 403) { | ||
this[kProductCheck] = 2 | ||
process.emitWarning('The client is unable to verify that the server is Elasticsearch due to security privileges on the server side. Some functionality may not be compatible if the server is running an unsupported product.') | ||
productCheckEmitter.emit('product-check', null, true) | ||
} else { | ||
this[kProductCheck] = 0 | ||
productCheckEmitter.emit('product-check', err, false) | ||
} | ||
} else { | ||
debug('Checking elasticsearch version', result.body, result.headers) | ||
if (result.body.version == null || typeof result.body.version.number !== 'string') { | ||
debug('Can\'t access Elasticsearch version') | ||
return productCheckEmitter.emit('product-check', null, false) | ||
} | ||
const tagline = result.body.tagline | ||
const version = result.body.version.number.split('.') | ||
const major = Number(version[0]) | ||
const minor = Number(version[1]) | ||
if (major < 6) { | ||
return productCheckEmitter.emit('product-check', null, false) | ||
} else if (major >= 6 && major < 7) { | ||
if (tagline !== 'You Know, for Search') { | ||
debug('Bad tagline') | ||
return productCheckEmitter.emit('product-check', null, false) | ||
} | ||
} else if (major === 7 && minor < 14) { | ||
if (tagline !== 'You Know, for Search') { | ||
debug('Bad tagline') | ||
return productCheckEmitter.emit('product-check', null, false) | ||
} | ||
if (result.body.version.build_flavor !== 'default') { | ||
debug('Bad build_flavor') | ||
this[kProductCheck] = 4 | ||
return productCheckEmitter.emit('product-check', null, false) | ||
} | ||
} else { | ||
if (result.headers['x-elastic-product'] !== 'Elasticsearch') { | ||
debug('x-elastic-product not recognized') | ||
return productCheckEmitter.emit('product-check', null, false) | ||
} | ||
} | ||
debug('Valid Elasticsearch distribution') | ||
this[kProductCheck] = 2 | ||
productCheckEmitter.emit('product-check', null, true) | ||
} | ||
}) | ||
} | ||
} | ||
@@ -504,0 +614,0 @@ |
@@ -14,4 +14,4 @@ { | ||
"homepage": "http://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/index.html", | ||
"version": "7.13.0", | ||
"versionCanary": "7.13.0-canary.5", | ||
"version": "7.14.0", | ||
"versionCanary": "7.14.0-canary.7", | ||
"keywords": [ | ||
@@ -18,0 +18,0 @@ "elasticsearch", |
@@ -57,4 +57,6 @@ <img align="right" width="auto" height="auto" src="https://www.elastic.co/static-res/images/elastic-logo-200.png"> | ||
The library is compatible with all Elasticsearch versions since 5.x, and you should use the same major version of the Elasticsearch instance that you are using. | ||
Elastic language clients are guaranteed to be able to communicate with Elasticsearch or Elastic solutions running on the same major version and greater or equal minor version. | ||
Language clients are forward compatible; meaning that clients support communicating with greater minor versions of Elasticsearch. Elastic language clients are not guaranteed to be backwards compatible. | ||
| Elasticsearch Version | Client Version | | ||
@@ -61,0 +63,0 @@ | --------------------- |----------------| |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
104
35441
234
1902468
2