From 06a8b77ad12d7687de273694499ce73c839a0d2d Mon Sep 17 00:00:00 2001 From: Chukwuemeka Date: Thu, 21 May 2026 16:29:09 +0200 Subject: [PATCH 1/4] feat(sdk-client-v3): pass custom headers to requests - pass custom headers to request headers --- packages/sdk-client-v3/src/types/types.d.ts | 1 + packages/sdk-client-v3/src/utils/executor.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/sdk-client-v3/src/types/types.d.ts b/packages/sdk-client-v3/src/types/types.d.ts index 27215f43e..57dcb8255 100644 --- a/packages/sdk-client-v3/src/types/types.d.ts +++ b/packages/sdk-client-v3/src/types/types.d.ts @@ -305,6 +305,7 @@ export type IClientOptions = { retryConfig?: RetryOptions maskSensitiveHeaderData?: boolean httpClientOptions?: object + request: MiddlewareRequest } export type HttpClientOptions = IClientOptions & Optional diff --git a/packages/sdk-client-v3/src/utils/executor.ts b/packages/sdk-client-v3/src/utils/executor.ts index eacb158ac..a0f666c32 100644 --- a/packages/sdk-client-v3/src/utils/executor.ts +++ b/packages/sdk-client-v3/src/utils/executor.ts @@ -57,7 +57,7 @@ export default async function executor(request: HttpClientConfig) { ...options, ...rest, headers: { - ...rest.headers, + ...Object.assign({}, rest.headers, rest.request?.headers ?? {}), }, // for axios From 502dc3d3e32bd0d3d90ff43388222859278d326a Mon Sep 17 00:00:00 2001 From: Chukwuemeka Date: Thu, 21 May 2026 16:47:32 +0200 Subject: [PATCH 2/4] feat(sdk-client-v3): pass custom headers to requests - pass custom headers to request headers - add tests to validate functionality --- .../tests/utils.test/executor.test.ts | 129 ++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 packages/sdk-client-v3/tests/utils.test/executor.test.ts diff --git a/packages/sdk-client-v3/tests/utils.test/executor.test.ts b/packages/sdk-client-v3/tests/utils.test/executor.test.ts new file mode 100644 index 000000000..95bc3d4e5 --- /dev/null +++ b/packages/sdk-client-v3/tests/utils.test/executor.test.ts @@ -0,0 +1,129 @@ +import executor from '../../src/utils/executor' +import { HttpClientConfig } from '../../src/types/types' + +const mockResponse = { + data: { ok: true }, + status: 200, + statusCode: 200, + headers: {}, +} + +function createExecutorConfig( + overrides: Partial & { + httpClient?: jest.Mock + } = {} +): HttpClientConfig { + const httpClient = + overrides.httpClient ?? jest.fn(() => Promise.resolve(mockResponse)) + + return { + url: 'https://api.example.com/test', + method: 'GET', + headers: {}, + request: { + uri: '/test', + method: 'GET', + body: null, + headers: {}, + }, + httpClient, + ...overrides, + } +} + +describe('executor', () => { + describe('request headers', () => { + test('passes rest.headers to httpClient', async () => { + const httpClient = jest.fn(() => Promise.resolve(mockResponse)) + + await executor( + createExecutorConfig({ + httpClient, + headers: { 'X-Client-Header': 'client-value' }, + }) + ) + + expect(httpClient).toHaveBeenCalledWith( + 'https://api.example.com/test', + expect.objectContaining({ + headers: { 'X-Client-Header': 'client-value' }, + }) + ) + }) + + test('merges rest.request.headers with rest.headers', async () => { + const httpClient = jest.fn(() => Promise.resolve(mockResponse)) + + await executor( + createExecutorConfig({ + httpClient, + headers: { 'X-Client-Header': 'client-value' }, + request: { + uri: '/test', + method: 'GET', + body: null, + headers: { 'X-Request-Header': 'request-value' }, + }, + }) + ) + + expect(httpClient).toHaveBeenCalledWith( + 'https://api.example.com/test', + expect.objectContaining({ + headers: { + 'X-Client-Header': 'client-value', + 'X-Request-Header': 'request-value', + }, + }) + ) + }) + + test('rest.request.headers override rest.headers on conflict', async () => { + const httpClient = jest.fn(() => Promise.resolve(mockResponse)) + + await executor( + createExecutorConfig({ + httpClient, + headers: { 'X-Shared-Header': 'client-value' }, + request: { + uri: '/test', + method: 'GET', + body: null, + headers: { 'X-Shared-Header': 'request-value' }, + }, + }) + ) + + expect(httpClient).toHaveBeenCalledWith( + 'https://api.example.com/test', + expect.objectContaining({ + headers: { 'X-Shared-Header': 'request-value' }, + }) + ) + }) + + test('uses only rest.headers when rest.request.headers is undefined', async () => { + const httpClient = jest.fn(() => Promise.resolve(mockResponse)) + + await executor( + createExecutorConfig({ + httpClient, + headers: { Authorization: 'Bearer token' }, + request: { + uri: '/test', + method: 'GET', + body: null, + headers: undefined as unknown as Record, + }, + }) + ) + + expect(httpClient).toHaveBeenCalledWith( + 'https://api.example.com/test', + expect.objectContaining({ + headers: { Authorization: 'Bearer token' }, + }) + ) + }) + }) +}) From 52a6a7cc155d86532b4966b305980ff1cbe2eb58 Mon Sep 17 00:00:00 2001 From: Ajima Chukwuemeka <32770340+ajimae@users.noreply.github.com> Date: Thu, 21 May 2026 16:50:11 +0200 Subject: [PATCH 3/4] Allow passing custom headers to HTTP requests Add support for custom headers in HTTP requests. --- .changeset/neat-wings-bow.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/neat-wings-bow.md diff --git a/.changeset/neat-wings-bow.md b/.changeset/neat-wings-bow.md new file mode 100644 index 000000000..a4f700cb0 --- /dev/null +++ b/.changeset/neat-wings-bow.md @@ -0,0 +1,5 @@ +--- +"@commercetools/ts-client": patch +--- + +[Feat][DEVX-793] Allow Passing Custom Headers to Http Requests From 004b122a8943580a177c0c597a00d664ebe1d6b0 Mon Sep 17 00:00:00 2001 From: Chukwuemeka Date: Thu, 21 May 2026 16:55:29 +0200 Subject: [PATCH 4/4] feat(sdk-client-v3): pass custom headers to requests - pass custom headers to request headers - add tests to validate functionality --- packages/sdk-client-v3/src/types/types.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/sdk-client-v3/src/types/types.d.ts b/packages/sdk-client-v3/src/types/types.d.ts index 57dcb8255..c1c5c0994 100644 --- a/packages/sdk-client-v3/src/types/types.d.ts +++ b/packages/sdk-client-v3/src/types/types.d.ts @@ -305,7 +305,7 @@ export type IClientOptions = { retryConfig?: RetryOptions maskSensitiveHeaderData?: boolean httpClientOptions?: object - request: MiddlewareRequest + request?: MiddlewareRequest } export type HttpClientOptions = IClientOptions & Optional