From d4846cba1be0c544eb3971e19c760ff967e4e7ed Mon Sep 17 00:00:00 2001 From: Paulius Krutkis Date: Tue, 9 Jun 2026 11:18:21 +0300 Subject: [PATCH] Bump version to 2.1.2 and add integration header support to HttpClient - Updated package version in package.json. - Enhanced HttpClient to accept an optional integrationHeader in the configuration. - Added tests for default and custom integration headers in HttpClient. --- package.json | 2 +- src/client.ts | 2 ++ src/http.test.ts | 47 +++++++++++++++++++++++++++++++++++++++++++++++ src/http.ts | 5 ++++- 4 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 src/http.test.ts diff --git a/package.json b/package.json index 269c224..77a5b4a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@decodo/sdk-ts", - "version": "2.1.1", + "version": "2.1.2", "description": "Official TypeScript SDK for the Decodo APIs", "type": "module", "main": "./build/cjs/index.cjs", diff --git a/src/client.ts b/src/client.ts index 58b4daf..81b153e 100644 --- a/src/client.ts +++ b/src/client.ts @@ -9,6 +9,7 @@ const DEFAULT_TIMEOUT_MS = 180_000; export type DecodoConfig = { webScrapingApi?: { token: string; + integrationHeader?: string; }; timeoutMs?: number; schema?: DecodoSchema; @@ -34,6 +35,7 @@ export class DecodoClient { token: config.webScrapingApi.token, }, timeoutMs, + integrationHeader: config.webScrapingApi.integrationHeader, }), schema, ); diff --git a/src/http.test.ts b/src/http.test.ts new file mode 100644 index 0000000..257aa74 --- /dev/null +++ b/src/http.test.ts @@ -0,0 +1,47 @@ +import { afterEach, describe, expect, it, vi } from 'vitest'; +import { HttpClient } from './http.js'; +import { jsonResponse, mockFetch } from './schema/test-helpers.js'; + +const baseConfig = { + baseUrl: 'https://api.test', + auth: { type: 'basic' as const, token: 'test-token' }, + timeoutMs: 5000, +}; + +describe('HttpClient integration header', () => { + afterEach(() => { + vi.unstubAllGlobals(); + vi.restoreAllMocks(); + }); + + it('sends x-integration: sdk-ts by default', async () => { + let capturedHeaders: Record | undefined; + + mockFetch((_input, init) => { + capturedHeaders = init?.headers as Record; + return jsonResponse({ ok: true }); + }); + + const client = new HttpClient(baseConfig); + await client.get('/v3/task/1'); + + expect(capturedHeaders?.['x-integration']).toBe('sdk-ts'); + }); + + it('sends a custom x-integration header when configured', async () => { + let capturedHeaders: Record | undefined; + + mockFetch((_input, init) => { + capturedHeaders = init?.headers as Record; + return jsonResponse({ ok: true }); + }); + + const client = new HttpClient({ + ...baseConfig, + integrationHeader: 'cli', + }); + await client.get('/v3/task/1'); + + expect(capturedHeaders?.['x-integration']).toBe('cli'); + }); +}); diff --git a/src/http.ts b/src/http.ts index 2cc17bf..9ae56d2 100644 --- a/src/http.ts +++ b/src/http.ts @@ -21,16 +21,19 @@ export type HttpClientConfig = { baseUrl: string; auth: BasicAuth | ApiKeyAuth; timeoutMs: number; + integrationHeader?: string; }; export class HttpClient { private readonly baseUrl: string; private readonly authHeader: string; private readonly timeoutMs: number; + private readonly integrationHeader: string; constructor(config: HttpClientConfig) { this.baseUrl = config.baseUrl.replace(/\/+$/, ''); this.timeoutMs = config.timeoutMs; + this.integrationHeader = config.integrationHeader ?? 'sdk-ts'; if (config.auth.type === 'basic') { this.authHeader = `Basic ${config.auth.token}`; @@ -51,7 +54,7 @@ export class HttpClient { Authorization: this.authHeader, 'Content-Type': 'application/json', Accept: 'application/json', - 'x-integration': 'sdk-ts', + 'x-integration': this.integrationHeader, }, signal: controller.signal, };