Compare commits

...

6 Commits

Author SHA1 Message Date
3f1a15bc4e Bumped v6.8.0 2019-05-22 12:20:10 +02:00
06b3a1ceb7 Support for non-friendly chars in url username and password (#858)
* Support for non-friendly chars in url username and password
- Added auth option to Connection class
- Updated pool.addConnection

* Updated test
2019-05-20 17:10:31 +02:00
a83cf7b26f Patch #855 2019-05-17 09:07:40 -04:00
30c3afe150 API generation 2019-05-16 16:54:53 -04:00
0efa0df934 Patch deprecated parameters (#851)
* Updated code generation

* API generation

* API generation

* Updated code generation
2019-05-16 16:54:27 -04:00
b2fbcfd8e2 missing comma (#854) 2019-05-16 09:39:51 -04:00
22 changed files with 147 additions and 25 deletions

View File

@ -52,7 +52,9 @@ function buildBulk (opts) {
'fields',
'_source',
'_source_excludes',
'_source_exclude',
'_source_includes',
'_source_include',
'pipeline',
'pretty',
'human',
@ -64,7 +66,9 @@ function buildBulk (opts) {
const snakeCase = {
waitForActiveShards: 'wait_for_active_shards',
_sourceExcludes: '_source_excludes',
_sourceExclude: '_source_exclude',
_sourceIncludes: '_source_includes',
_sourceInclude: '_source_include',
errorTrace: 'error_trace',
filterPath: 'filter_path'
}

View File

@ -86,7 +86,9 @@ function buildDeleteByQuery (opts) {
'sort',
'_source',
'_source_excludes',
'_source_exclude',
'_source_includes',
'_source_include',
'terminate_after',
'stats',
'version',
@ -114,7 +116,9 @@ function buildDeleteByQuery (opts) {
searchType: 'search_type',
searchTimeout: 'search_timeout',
_sourceExcludes: '_source_excludes',
_sourceExclude: '_source_exclude',
_sourceIncludes: '_source_includes',
_sourceInclude: '_source_include',
terminateAfter: 'terminate_after',
requestCache: 'request_cache',
waitForActiveShards: 'wait_for_active_shards',

View File

@ -53,7 +53,9 @@ function buildExists (opts) {
'routing',
'_source',
'_source_excludes',
'_source_exclude',
'_source_includes',
'_source_include',
'version',
'version_type',
'pretty',
@ -66,7 +68,9 @@ function buildExists (opts) {
const snakeCase = {
storedFields: 'stored_fields',
_sourceExcludes: '_source_excludes',
_sourceExclude: '_source_exclude',
_sourceIncludes: '_source_includes',
_sourceInclude: '_source_include',
versionType: 'version_type',
errorTrace: 'error_trace',
filterPath: 'filter_path'

View File

@ -51,7 +51,9 @@ function buildExistsSource (opts) {
'routing',
'_source',
'_source_excludes',
'_source_exclude',
'_source_includes',
'_source_include',
'version',
'version_type',
'pretty',
@ -63,7 +65,9 @@ function buildExistsSource (opts) {
const snakeCase = {
_sourceExcludes: '_source_excludes',
_sourceExclude: '_source_exclude',
_sourceIncludes: '_source_includes',
_sourceInclude: '_source_include',
versionType: 'version_type',
errorTrace: 'error_trace',
filterPath: 'filter_path'

View File

@ -60,7 +60,9 @@ function buildExplain (opts) {
'routing',
'_source',
'_source_excludes',
'_source_exclude',
'_source_includes',
'_source_include',
'pretty',
'human',
'error_trace',
@ -73,7 +75,9 @@ function buildExplain (opts) {
defaultOperator: 'default_operator',
storedFields: 'stored_fields',
_sourceExcludes: '_source_excludes',
_sourceExclude: '_source_exclude',
_sourceIncludes: '_source_includes',
_sourceInclude: '_source_include',
errorTrace: 'error_trace',
filterPath: 'filter_path'
}

View File

@ -55,7 +55,9 @@ function buildGet (opts) {
'routing',
'_source',
'_source_excludes',
'_source_exclude',
'_source_includes',
'_source_include',
'_source_exclude',
'_source_include',
'version',
@ -70,8 +72,8 @@ function buildGet (opts) {
const snakeCase = {
storedFields: 'stored_fields',
_sourceExcludes: '_source_excludes',
_sourceIncludes: '_source_includes',
_sourceExclude: '_source_exclude',
_sourceIncludes: '_source_includes',
_sourceInclude: '_source_include',
versionType: 'version_type',
errorTrace: 'error_trace',

View File

@ -51,7 +51,9 @@ function buildGetSource (opts) {
'routing',
'_source',
'_source_excludes',
'_source_exclude',
'_source_includes',
'_source_include',
'version',
'version_type',
'pretty',
@ -63,7 +65,9 @@ function buildGetSource (opts) {
const snakeCase = {
_sourceExcludes: '_source_excludes',
_sourceExclude: '_source_exclude',
_sourceIncludes: '_source_includes',
_sourceInclude: '_source_include',
versionType: 'version_type',
errorTrace: 'error_trace',
filterPath: 'filter_path'

View File

@ -49,7 +49,9 @@ function buildMget (opts) {
'routing',
'_source',
'_source_excludes',
'_source_exclude',
'_source_includes',
'_source_include',
'pretty',
'human',
'error_trace',
@ -60,7 +62,9 @@ function buildMget (opts) {
const snakeCase = {
storedFields: 'stored_fields',
_sourceExcludes: '_source_excludes',
_sourceExclude: '_source_exclude',
_sourceIncludes: '_source_includes',
_sourceInclude: '_source_include',
errorTrace: 'error_trace',
filterPath: 'filter_path'
}

View File

@ -97,7 +97,9 @@ function buildSearch (opts) {
'sort',
'_source',
'_source_excludes',
'_source_exclude',
'_source_includes',
'_source_include',
'terminate_after',
'stats',
'suggest_field',
@ -134,7 +136,9 @@ function buildSearch (opts) {
expandWildcards: 'expand_wildcards',
searchType: 'search_type',
_sourceExcludes: '_source_excludes',
_sourceExclude: '_source_exclude',
_sourceIncludes: '_source_includes',
_sourceInclude: '_source_include',
terminateAfter: 'terminate_after',
suggestField: 'suggest_field',
suggestMode: 'suggest_mode',

View File

@ -54,7 +54,9 @@ function buildUpdate (opts) {
'fields',
'_source',
'_source_excludes',
'_source_exclude',
'_source_includes',
'_source_include',
'lang',
'parent',
'refresh',
@ -75,7 +77,9 @@ function buildUpdate (opts) {
const snakeCase = {
waitForActiveShards: 'wait_for_active_shards',
_sourceExcludes: '_source_excludes',
_sourceExclude: '_source_exclude',
_sourceIncludes: '_source_includes',
_sourceInclude: '_source_include',
retryOnConflict: 'retry_on_conflict',
ifSeqNo: 'if_seq_no',
ifPrimaryTerm: 'if_primary_term',

View File

@ -89,7 +89,9 @@ function buildUpdateByQuery (opts) {
'sort',
'_source',
'_source_excludes',
'_source_exclude',
'_source_includes',
'_source_include',
'terminate_after',
'stats',
'version',
@ -118,7 +120,9 @@ function buildUpdateByQuery (opts) {
searchType: 'search_type',
searchTimeout: 'search_timeout',
_sourceExcludes: '_source_excludes',
_sourceExclude: '_source_exclude',
_sourceIncludes: '_source_includes',
_sourceInclude: '_source_include',
terminateAfter: 'terminate_after',
versionType: 'version_type',
requestCache: 'request_cache',

View File

@ -30,6 +30,8 @@ export interface Generic {
export interface Bulk<T = any> extends Generic {
index?: string;
type?: string;
_source_exclude?: string | string[];
_source_include?: string | string[];
wait_for_active_shards?: string;
refresh?: 'true' | 'false' | 'wait_for';
routing?: string;
@ -387,6 +389,8 @@ export interface Delete extends Generic {
export interface DeleteByQuery<T = any> extends Generic {
index: string | string[];
type?: string | string[];
_source_exclude?: string | string[];
_source_include?: string | string[];
analyzer?: string;
analyze_wildcard?: boolean;
default_operator?: 'AND' | 'OR';
@ -437,6 +441,8 @@ export interface Exists extends Generic {
id: string;
index: string;
type: string;
_source_exclude?: string | string[];
_source_include?: string | string[];
stored_fields?: string | string[];
parent?: string;
preference?: string;
@ -454,6 +460,8 @@ export interface ExistsSource extends Generic {
id: string;
index: string;
type: string;
_source_exclude?: string | string[];
_source_include?: string | string[];
parent?: string;
preference?: string;
realtime?: boolean;
@ -470,6 +478,8 @@ export interface Explain<T = any> extends Generic {
id: string;
index: string;
type: string;
_source_exclude?: string | string[];
_source_include?: string | string[];
analyze_wildcard?: boolean;
analyzer?: string;
default_operator?: 'AND' | 'OR';
@ -499,6 +509,8 @@ export interface Get extends Generic {
id: string;
index: string;
type: string;
_source_exclude?: string | string[];
_source_include?: string | string[];
stored_fields?: string | string[];
parent?: string;
preference?: string;
@ -508,8 +520,6 @@ export interface Get extends Generic {
_source?: string | string[];
_source_excludes?: string | string[];
_source_includes?: string | string[];
_source_exclude?: string | string[];
_source_include?: string | string[];
version?: number;
version_type?: 'internal' | 'external' | 'external_gte' | 'force';
}
@ -523,6 +533,8 @@ export interface GetSource extends Generic {
id: string;
index: string;
type: string;
_source_exclude?: string | string[];
_source_include?: string | string[];
parent?: string;
preference?: string;
realtime?: boolean;
@ -936,6 +948,8 @@ export interface IngestSimulate<T = any> extends Generic {
export interface Mget<T = any> extends Generic {
index?: string;
type?: string;
_source_exclude?: string | string[];
_source_include?: string | string[];
stored_fields?: string | string[];
preference?: string;
realtime?: boolean;
@ -1083,6 +1097,8 @@ export interface Scroll<T = any> extends Generic {
export interface Search<T = any> extends Generic {
index?: string | string[];
type?: string | string[];
_source_exclude?: string | string[];
_source_include?: string | string[];
analyzer?: string;
analyze_wildcard?: boolean;
default_operator?: 'AND' | 'OR';
@ -1264,6 +1280,8 @@ export interface Update<T = any> extends Generic {
id: string;
index: string;
type: string;
_source_exclude?: string | string[];
_source_include?: string | string[];
wait_for_active_shards?: string;
fields?: string | string[];
_source?: string | string[];
@ -1285,6 +1303,8 @@ export interface Update<T = any> extends Generic {
export interface UpdateByQuery<T = any> extends Generic {
index: string | string[];
type?: string | string[];
_source_exclude?: string | string[];
_source_include?: string | string[];
analyzer?: string;
analyze_wildcard?: boolean;
default_operator?: 'AND' | 'OR';

View File

@ -8,7 +8,7 @@ The client is designed to be easily configured as you see fit for your needs, fo
const { Client } = require('@elastic/elasticsearch')
const client = new Client({
node: 'http://localhost:9200'
node: 'http://localhost:9200',
maxRetries: 5,
requestTimeout: 60000,
sniffOnStart: true

View File

@ -35,6 +35,7 @@ class Connection {
this.ssl = opts.ssl || null
this.id = opts.id || stripAuth(opts.url.href)
this.headers = opts.headers || null
this.auth = opts.auth || { username: null, password: null }
this.deadCount = 0
this.resurrectTimeout = 0
@ -180,6 +181,7 @@ class Connection {
buildRequestObject (params) {
const url = this.url
const { username, password } = this.auth
const request = {
protocol: url.protocol,
hostname: url.hostname[0] === '['
@ -194,8 +196,8 @@ class Connection {
// https://github.com/elastic/elasticsearch-js/issues/843
port: url.port !== '' ? url.port : undefined,
headers: this.headers,
auth: !!url.username === true || !!url.password === true
? `${url.username}:${url.password}`
auth: username != null && password != null
? `${username}:${password}`
: undefined,
agent: this.agent
}
@ -224,7 +226,7 @@ class Connection {
}
// Handles console.log and utils.inspect invocations.
// We want to hide `agent` and `ssl` since they made
// We want to hide `auth`, `agent` and `ssl` since they made
// the logs very hard to read. The user can still
// access them with `instance.agent` and `instance.ssl`.
[inspect.custom] (depth, options) {

View File

@ -222,21 +222,24 @@ class ConnectionPool {
// we can add it to them once the connection instance has been created
if (opts.url.username !== '' && opts.url.password !== '') {
this._auth = {
username: opts.url.username,
password: opts.url.password
username: decodeURIComponent(opts.url.username),
password: decodeURIComponent(opts.url.password)
}
opts.auth = this._auth
}
if (this._auth != null) {
if (opts.auth == null || (opts.auth.username == null && opts.auth.password == null)) {
opts.auth = this._auth
opts.url.username = this._auth.username
opts.url.password = this._auth.password
}
}
if (opts.ssl == null) opts.ssl = this._ssl
if (opts.agent == null) opts.agent = this._agent
const connection = new this.Connection(opts)
if (connection.url.username === '' &&
connection.url.password === '' &&
this._auth != null) {
connection.url.username = this._auth.username
connection.url.password = this._auth.password
}
debug('Adding a new connection', connection)
if (this.connections.has(connection.id)) {
throw new Error(`Connection with id '${connection.id}' is already present`)

View File

@ -4,7 +4,7 @@
"main": "index.js",
"types": "index.d.ts",
"homepage": "http://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/index.html",
"version": "6.7.1",
"version": "6.8.0",
"keywords": [
"elasticsearch",
"elastic",

View File

@ -69,7 +69,7 @@ function start (opts) {
writeFileSync(
requestParamsOutputFile,
generateRequestTypes(allSpec),
generateRequestTypes(opts.branch || opts.tag, allSpec),
{ encoding: 'utf8' }
)
@ -113,7 +113,7 @@ function start (opts) {
const spec = require(join(apiFolder, file))
allSpec.push(spec)
const code = generate(spec, common)
const code = generate(opts.branch || opts.tag, spec, common)
const filePath = join(apiOutputFolder, `${file.slice(0, file.lastIndexOf('.'))}.js`)
writeFileSync(filePath, code, { encoding: 'utf8' })

View File

@ -20,11 +20,16 @@
'use strict'
const dedent = require('dedent')
const semver = require('semver')
const allowedMethods = {
noBody: ['GET', 'HEAD', 'DELETE'],
body: ['POST', 'PUT', 'DELETE']
}
// if a parameter is depracted in a minor release
// we should be able to support it until the next major
const deprecatedParameters = require('./patch.json')
// list of apis that does not need any kind of validation
// because of how the url is built or the `type` handling in ES7
const noPathValidation = [
@ -59,7 +64,8 @@ const ndjsonApi = [
'xpack.monitoring.bulk'
]
function generate (spec, common) {
function generate (version, spec, common) {
const release = semver.valid(version) ? semver.major(version) : version
const api = Object.keys(spec)[0]
const name = api
.replace(/\.([a-z])/g, k => k[1].toUpperCase())
@ -80,7 +86,11 @@ function generate (spec, common) {
if (params[key].required) {
required.push(key)
}
acceptedQuerystring.push(key)
if (deprecatedParameters[release] && deprecatedParameters[release][key]) {
acceptedQuerystring.push(deprecatedParameters[release][key])
}
}
for (const key in spec[api]) {

View File

@ -19,7 +19,11 @@
'use strict'
function generate (api) {
const semver = require('semver')
const deprecatedParameters = require('./patch.json')
function generate (version, api) {
const release = semver.valid(version) ? semver.major(version) : version
var types = `/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
@ -64,9 +68,20 @@ export interface Generic {
const partsArr = Object.keys(parts)
.map(k => ({ key: k, value: parts[k] }))
const deprecatedParametersToAdd = []
const paramsArr = Object.keys(params)
.filter(k => !Object.keys(parts).includes(k))
.map(k => ({ key: k, value: params[k] }))
.map(k => {
if (deprecatedParameters[release] && deprecatedParameters[release][k]) {
deprecatedParametersToAdd.push({
key: deprecatedParameters[release][k],
value: params[k]
})
}
return { key: k, value: params[k] }
})
deprecatedParametersToAdd.forEach(k => partsArr.push(k))
const genLine = e => {
const optional = e.value.required ? '' : '?'

14
scripts/utils/patch.json Normal file
View File

@ -0,0 +1,14 @@
{
"6": {
"_source_includes": "_source_include",
"_source_excludes": "_source_exclude"
},
"7": {
"_source_includes": "_source_include",
"_source_excludes": "_source_exclude"
},
"master": {
"_source_includes": "_source_include",
"_source_excludes": "_source_exclude"
}
}

View File

@ -61,8 +61,23 @@ test('API', t => {
t.deepEqual(pool._auth, { username: 'foo', password: 'bar' })
pool.addConnection('http://localhost:9201')
t.strictEqual(pool.connections.get('http://localhost:9201/').url.username, 'foo')
t.strictEqual(pool.connections.get('http://localhost:9201/').url.password, 'bar')
const conn = pool.connections.get('http://localhost:9201/')
t.strictEqual(conn.url.username, 'foo')
t.strictEqual(conn.url.password, 'bar')
t.strictEqual(conn.auth.username, 'foo')
t.strictEqual(conn.auth.password, 'bar')
t.end()
})
t.test('addConnection should handle not-friendly url parameters for user and password', t => {
const pool = new ConnectionPool({ Connection })
const href = 'http://us"er:p@assword@localhost:9200/'
pool.addConnection(href)
const conn = pool.getConnection()
t.strictEqual(conn.url.username, 'us%22er')
t.strictEqual(conn.url.password, 'p%40assword')
t.strictEqual(conn.auth.username, 'us"er')
t.strictEqual(conn.auth.password, 'p@assword')
t.end()
})

View File

@ -526,7 +526,8 @@ test('Url with auth', t => {
buildServer(handler, ({ port }, server) => {
const connection = new Connection({
url: new URL(`http://foo:bar@localhost:${port}`)
url: new URL(`http://foo:bar@localhost:${port}`),
auth: { username: 'foo', password: 'bar' }
})
connection.request({
path: '/hello',