From 173bf931220cd5867b2c0b3f78b679404c4ce4b2 Mon Sep 17 00:00:00 2001 From: Josh Mock Date: Wed, 2 Jul 2025 16:05:20 -0500 Subject: [PATCH] Deep merge options on client instantiation --- src/client.ts | 13 +++++-------- test/unit/client.test.ts | 22 ++++++++++++++++++++++ 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/client.ts b/src/client.ts index f758553e2..7e303bd52 100644 --- a/src/client.ts +++ b/src/client.ts @@ -256,11 +256,13 @@ export default class Client extends API { } } - const headers: Record = { + const headers: Record = Object.assign({}, { 'user-agent': `elasticsearch-js/${clientVersion} (${os.platform()} ${os.release()}-${os.arch()}; Node.js ${nodeVersion}; Transport ${transportVersion})` - } + }, opts.headers ?? {}) if (opts.serverMode === 'serverless') headers['elastic-api-version'] = serverlessApiVersion + const redaction = Object.assign({}, { type: 'replace', additionalKeys: [] }, opts.redaction ?? {}) + const options: Required = Object.assign({}, { Connection: UndiciConnection, Transport: opts.serverMode === 'serverless' ? Transport : SniffingTransport, @@ -277,7 +279,6 @@ export default class Client extends API { tls: null, caFingerprint: null, agent: null, - headers, nodeFilter: null, generateRequestId: null, name: 'elasticsearch-js', @@ -288,12 +289,8 @@ export default class Client extends API { enableMetaHeader: true, maxResponseSize: null, maxCompressedResponseSize: null, - redaction: { - type: 'replace', - additionalKeys: [] - }, serverMode: 'stack' - }, opts) + }, opts, { headers, redaction }) if (options.caFingerprint != null && isHttpConnection(opts.node ?? opts.nodes)) { throw new errors.ConfigurationError('You can\'t configure the caFingerprint with a http connection') diff --git a/test/unit/client.test.ts b/test/unit/client.test.ts index fc4016a22..feffc373e 100644 --- a/test/unit/client.test.ts +++ b/test/unit/client.test.ts @@ -98,6 +98,28 @@ test('Custom headers', t => { t.end() }) +test('Custom headers should merge, not overwrite', t => { + const client = new Client({ + node: 'http://localhost:9200', + headers: { foo: 'bar' } + }) + t.ok(client.transport[symbols.kHeaders]['user-agent']?.startsWith('elasticsearch-js/')) + t.end() +}) + +test('Redaction options should merge, not overwrite', t => { + const client = new Client({ + node: 'http://localhost:9200', + // @ts-expect-error + redaction: { + additionalKeys: ['foo'], + } + }) + t.equal(client.transport[symbols.kRedaction].type, 'replace') + t.match(client.transport[symbols.kRedaction].additionalKeys, ['foo']) + t.end() +}) + test('Basic auth', async t => { t.plan(1)