diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a726929..a8ea4b6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -57,7 +57,7 @@ jobs: - name: Get GitHub OIDC Token if: github.repository == 'stainless-sdks/morphik-typescript' id: github-oidc - uses: actions/github-script@v6 + uses: actions/github-script@v8 with: script: core.setOutput('github_token', await core.getIDToken()); diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 4fcfdf7..2b6f978 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "1.9.0" + ".": "1.9.1" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 5caaf1c..3872ed5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # Changelog +## 1.9.1 (2026-02-06) + +Full Changelog: [v1.9.0...v1.9.1](https://github.com/morphik-org/morphik-ts/compare/v1.9.0...v1.9.1) + +### Bug Fixes + +* **client:** avoid memory leak with abort signals ([d4ab61c](https://github.com/morphik-org/morphik-ts/commit/d4ab61c33f1d02a5253e27841bb775a6ceea147d)) +* **client:** avoid removing abort listener too early ([a4fdb09](https://github.com/morphik-org/morphik-ts/commit/a4fdb095674574af92643d5212923579b73f84cc)) + + +### Chores + +* **ci:** upgrade `actions/github-script` ([8513ce5](https://github.com/morphik-org/morphik-ts/commit/8513ce589bdffbd702a3cc9fa868ad499f216969)) +* **client:** do not parse responses with empty content-length ([3169d51](https://github.com/morphik-org/morphik-ts/commit/3169d51148b52561338eea977226341cfb7c0831)) +* **client:** restructure abort controller binding ([b48b2b0](https://github.com/morphik-org/morphik-ts/commit/b48b2b0502d295c9a0cb4955437caddccc995bea)) + ## 1.9.0 (2026-01-22) Full Changelog: [v1.8.0...v1.9.0](https://github.com/morphik-org/morphik-ts/compare/v1.8.0...v1.9.0) diff --git a/package.json b/package.json index 9e99c8b..9be4e39 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "morphik", - "version": "1.9.0", + "version": "1.9.1", "description": "The official TypeScript library for the Morphik API", "author": "Morphik ", "types": "dist/index.d.ts", diff --git a/src/client.ts b/src/client.ts index 2cc8776..c093e2e 100644 --- a/src/client.ts +++ b/src/client.ts @@ -575,9 +575,10 @@ export class Morphik { controller: AbortController, ): Promise { const { signal, method, ...options } = init || {}; - if (signal) signal.addEventListener('abort', () => controller.abort()); + const abort = this._makeAbort(controller); + if (signal) signal.addEventListener('abort', abort, { once: true }); - const timeout = setTimeout(() => controller.abort(), ms); + const timeout = setTimeout(abort, ms); const isReadableBody = ((globalThis as any).ReadableStream && options.body instanceof (globalThis as any).ReadableStream) || @@ -744,6 +745,12 @@ export class Morphik { 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 7d779e9..c669569 100644 --- a/src/internal/parse.ts +++ b/src/internal/parse.ts @@ -29,6 +29,12 @@ export async function defaultParseResponse(client: Morphik, props: APIRespons 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 d6d803f..96219a4 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const VERSION = '1.9.0'; // x-release-please-version +export const VERSION = '1.9.1'; // x-release-please-version