diff --git a/.release-please-manifest.json b/.release-please-manifest.json index ea3a8f8..39773fd 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "3.6.1" + ".": "3.6.2" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 6967c16..74e39d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +## 3.6.2 (2026-02-06) + +Full Changelog: [v3.6.1...v3.6.2](https://github.com/moderation-api/sdk-typescript/compare/v3.6.1...v3.6.2) + +### Bug Fixes + +* **client:** avoid removing abort listener too early ([1d89cb2](https://github.com/moderation-api/sdk-typescript/commit/1d89cb27203faa83ff1709b03d0ec9b44003d510)) + + +### Chores + +* **client:** do not parse responses with empty content-length ([532f911](https://github.com/moderation-api/sdk-typescript/commit/532f9110239e90c4230ed122a89756719d588b66)) +* **client:** restructure abort controller binding ([78d4ba7](https://github.com/moderation-api/sdk-typescript/commit/78d4ba7ae247a74c4e275db1874249badb11dc02)) + ## 3.6.1 (2026-02-03) Full Changelog: [v3.6.0...v3.6.1](https://github.com/moderation-api/sdk-typescript/compare/v3.6.0...v3.6.1) diff --git a/package.json b/package.json index bb41bc8..34b8165 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@moderation-api/sdk", - "version": "3.6.1", + "version": "3.6.2", "description": "The official TypeScript library for the Moderation API API", "author": "Moderation API ", "types": "dist/index.d.ts", diff --git a/src/client.ts b/src/client.ts index 84bbb6a..e163f73 100644 --- a/src/client.ts +++ b/src/client.ts @@ -527,7 +527,7 @@ export class ModerationAPI { controller: AbortController, ): Promise { const { signal, method, ...options } = init || {}; - const abort = controller.abort.bind(controller); + const abort = this._makeAbort(controller); if (signal) signal.addEventListener('abort', abort, { once: true }); const timeout = setTimeout(abort, ms); @@ -697,6 +697,12 @@ export class ModerationAPI { return headers.values; } + private _makeAbort(controller: AbortController) { + // note: we can't just inline this method inside `fetchWithTimeout()` because then the closure + // would capture all request options, and cause a memory leak. + return () => controller.abort(); + } + private buildBody({ options: { body, headers: rawHeaders } }: { options: FinalRequestOptions }): { bodyHeaders: HeadersLike; body: BodyInit | undefined; diff --git a/src/internal/parse.ts b/src/internal/parse.ts index 0421f6c..cf13ec3 100644 --- a/src/internal/parse.ts +++ b/src/internal/parse.ts @@ -29,6 +29,12 @@ export async function defaultParseResponse(client: ModerationAPI, props: APIR const mediaType = contentType?.split(';')[0]?.trim(); const isJSON = mediaType?.includes('application/json') || mediaType?.endsWith('+json'); if (isJSON) { + const contentLength = response.headers.get('content-length'); + if (contentLength === '0') { + // if there is no content we can't do anything + return undefined as T; + } + const json = await response.json(); return json as T; } diff --git a/src/version.ts b/src/version.ts index 21793f0..0552af1 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const VERSION = '3.6.1'; // x-release-please-version +export const VERSION = '3.6.2'; // x-release-please-version