From 28ffe4f56c47e3489fbb394a153084cc69bc0c6c Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 25 Sep 2024 18:41:55 +0000 Subject: [PATCH 1/2] chore(internal): codegen related update (#20) --- src/core.ts | 18 +++++++++++--- tests/index.test.ts | 58 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 3 deletions(-) diff --git a/src/core.ts b/src/core.ts index 2c5c7d4..59051ea 100644 --- a/src/core.ts +++ b/src/core.ts @@ -349,7 +349,11 @@ export abstract class APIClient { delete reqHeaders['content-type']; } - reqHeaders['x-stainless-retry-count'] = String(retryCount); + // Don't set the retry count header if it was already set or removed by the caller. We check `headers`, + // which can contain nulls, instead of `reqHeaders` to account for the removal case. + if (getHeader(headers, 'x-stainless-retry-count') === undefined) { + reqHeaders['x-stainless-retry-count'] = String(retryCount); + } this.validateHeaders(reqHeaders, headers); @@ -1128,7 +1132,15 @@ export const isHeadersProtocol = (headers: any): headers is HeadersProtocol => { return typeof headers?.get === 'function'; }; -export const getRequiredHeader = (headers: HeadersLike, header: string): string => { +export const getRequiredHeader = (headers: HeadersLike | Headers, header: string): string => { + const foundHeader = getHeader(headers, header); + if (foundHeader === undefined) { + throw new Error(`Could not find ${header} header`); + } + return foundHeader; +}; + +export const getHeader = (headers: HeadersLike | Headers, header: string): string | undefined => { const lowerCasedHeader = header.toLowerCase(); if (isHeadersProtocol(headers)) { // to deal with the case where the header looks like Stainless-Event-Id @@ -1154,7 +1166,7 @@ export const getRequiredHeader = (headers: HeadersLike, header: string): string } } - throw new Error(`Could not find ${header} header`); + return undefined; }; /** diff --git a/tests/index.test.ts b/tests/index.test.ts index 0508366..1987f1a 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -279,6 +279,64 @@ describe('retries', () => { expect(count).toEqual(3); }); + test('omit retry count header', async () => { + let count = 0; + let capturedRequest: RequestInit | undefined; + const testFetch = async (url: RequestInfo, init: RequestInit = {}): Promise => { + count++; + if (count <= 2) { + return new Response(undefined, { + status: 429, + headers: { + 'Retry-After': '0.1', + }, + }); + } + capturedRequest = init; + return new Response(JSON.stringify({ a: 1 }), { headers: { 'Content-Type': 'application/json' } }); + }; + const client = new Julep({ apiKey: 'My API Key', fetch: testFetch, maxRetries: 4 }); + + expect( + await client.request({ + path: '/foo', + method: 'get', + headers: { 'X-Stainless-Retry-Count': null }, + }), + ).toEqual({ a: 1 }); + + expect(capturedRequest!.headers as Headers).not.toHaveProperty('x-stainless-retry-count'); + }); + + test('overwrite retry count header', async () => { + let count = 0; + let capturedRequest: RequestInit | undefined; + const testFetch = async (url: RequestInfo, init: RequestInit = {}): Promise => { + count++; + if (count <= 2) { + return new Response(undefined, { + status: 429, + headers: { + 'Retry-After': '0.1', + }, + }); + } + capturedRequest = init; + return new Response(JSON.stringify({ a: 1 }), { headers: { 'Content-Type': 'application/json' } }); + }; + const client = new Julep({ apiKey: 'My API Key', fetch: testFetch, maxRetries: 4 }); + + expect( + await client.request({ + path: '/foo', + method: 'get', + headers: { 'X-Stainless-Retry-Count': '42' }, + }), + ).toEqual({ a: 1 }); + + expect((capturedRequest!.headers as Headers)['x-stainless-retry-count']).toBe('42'); + }); + test('retry on 429 with retry-after', async () => { let count = 0; const testFetch = async (url: RequestInfo, { signal }: RequestInit = {}): Promise => { From f9a80793fbbf93d839aafd34d741b9cb42483b3b Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 25 Sep 2024 18:42:10 +0000 Subject: [PATCH 2/2] release: 1.3.1 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 8 ++++++++ package.json | 2 +- src/version.ts | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 96f1cd9..9049e2f 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "1.3.0" + ".": "1.3.1" } diff --git a/CHANGELOG.md b/CHANGELOG.md index fd079b0..a3d496b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 1.3.1 (2024-09-25) + +Full Changelog: [v1.3.0...v1.3.1](https://github.com/julep-ai/node-sdk/compare/v1.3.0...v1.3.1) + +### Chores + +* **internal:** codegen related update ([#20](https://github.com/julep-ai/node-sdk/issues/20)) ([28ffe4f](https://github.com/julep-ai/node-sdk/commit/28ffe4f56c47e3489fbb394a153084cc69bc0c6c)) + ## 1.3.0 (2024-09-23) Full Changelog: [v1.2.1...v1.3.0](https://github.com/julep-ai/node-sdk/compare/v1.2.1...v1.3.0) diff --git a/package.json b/package.json index 530d38d..9217db8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@julep/sdk", - "version": "1.3.0", + "version": "1.3.1", "description": "The official TypeScript library for the Julep API", "author": "Julep ", "types": "dist/index.d.ts", diff --git a/src/version.ts b/src/version.ts index 39fa5bc..8d95974 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const VERSION = '1.3.0'; // x-release-please-version +export const VERSION = '1.3.1'; // x-release-please-version