diff --git a/packages/node/src/__tests__/typedef-tests.ts b/packages/node/src/__tests__/typedef-tests.ts index c21f363e3..2f8e626f6 100644 --- a/packages/node/src/__tests__/typedef-tests.ts +++ b/packages/node/src/__tests__/typedef-tests.ts @@ -97,6 +97,13 @@ export default { new Analytics({ writeKey: 'foo', httpClient: globalThis.fetch }) }, + 'HTTPFetchFn options should be the expected type': () => { + type BadFetch = (url: string, requestInit: { _bad_object?: string }) => any + + // @ts-expect-error + new Analytics({ writeKey: 'foo', httpClient: {} as BadFetch }) + }, + 'httpClient setting should be compatible with axios': () => { new (class implements HTTPClient { async makeRequest(options: HTTPClientRequest) { diff --git a/packages/node/src/lib/__tests__/abort.test.ts b/packages/node/src/lib/__tests__/abort.test.ts index ecc4af764..54f350252 100644 --- a/packages/node/src/lib/__tests__/abort.test.ts +++ b/packages/node/src/lib/__tests__/abort.test.ts @@ -1,7 +1,9 @@ import { abortSignalAfterTimeout } from '../abort' import nock from 'nock' -import { fetch } from '../fetch' import { sleep } from '@segment/analytics-core' +import { fetch as _fetch } from '../fetch' + +const fetch = _fetch as typeof globalThis.fetch describe(abortSignalAfterTimeout, () => { const HOST = 'https://foo.com' diff --git a/packages/node/src/lib/http-client.ts b/packages/node/src/lib/http-client.ts index 87cd02465..3cc33f68d 100644 --- a/packages/node/src/lib/http-client.ts +++ b/packages/node/src/lib/http-client.ts @@ -15,10 +15,10 @@ export interface HTTPFetchFn { * @link https://developer.mozilla.org/en-US/docs/Web/API/Request */ export interface HTTPFetchRequest { - headers?: Record - body?: string - method?: HTTPClientRequest['method'] - signal?: any // AbortSignal type does not play nicely with node-fetch + headers: Record + body: string + method: HTTPClientRequest['method'] + signal: any // AbortSignal type does not play nicely with node-fetch } /** @@ -73,7 +73,16 @@ export interface HTTPClient { export class FetchHTTPClient implements HTTPClient { private _fetch: HTTPFetchFn constructor(fetchFn?: HTTPFetchFn) { - this._fetch = fetchFn ?? defaultFetch + const _fetch = fetchFn ?? defaultFetch + this._fetch = (url: string, requestInit: HTTPFetchRequest) => { + if (typeof url !== 'string') { + throw new Error('URL must be a string. Received: ' + url) + } + if (!requestInit.body || typeof requestInit.body !== 'string') { + throw new Error('Body must be a string. Received: ' + requestInit.body) + } + return _fetch(url, requestInit) + } } async makeRequest(options: HTTPClientRequest): Promise { const [signal, timeoutId] = abortSignalAfterTimeout(