diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 54cfe49..47736a5 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.1.0-alpha.15" + ".": "0.1.0-alpha.16" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 648e014..719a2c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## 0.1.0-alpha.16 (2024-12-17) + +Full Changelog: [v0.1.0-alpha.15...v0.1.0-alpha.16](https://github.com/clear-street/studio-sdk-node/compare/v0.1.0-alpha.15...v0.1.0-alpha.16) + +### Chores + +* **internal:** codegen related update ([#75](https://github.com/clear-street/studio-sdk-node/issues/75)) ([8512182](https://github.com/clear-street/studio-sdk-node/commit/85121825823399954cdcba771f4d3757e739edac)) +* **internal:** codegen related update ([#76](https://github.com/clear-street/studio-sdk-node/issues/76)) ([2f50957](https://github.com/clear-street/studio-sdk-node/commit/2f509570c4480ecf015e78e5497d20de817d1b8a)) +* **internal:** remove unnecessary getRequestClient function ([#73](https://github.com/clear-street/studio-sdk-node/issues/73)) ([bc28efe](https://github.com/clear-street/studio-sdk-node/commit/bc28efeed973ea9104eaf4f5144877d0133eeecd)) + ## 0.1.0-alpha.15 (2024-12-09) Full Changelog: [v0.1.0-alpha.14...v0.1.0-alpha.15](https://github.com/clear-street/studio-sdk-node/compare/v0.1.0-alpha.14...v0.1.0-alpha.15) diff --git a/package.json b/package.json index 6695bc5..4d1d53d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@clear-street/studio-sdk", - "version": "0.1.0-alpha.15", + "version": "0.1.0-alpha.16", "description": "The official TypeScript library for the Studio SDK API", "author": "Studio SDK ", "types": "dist/index.d.ts", diff --git a/src/core.ts b/src/core.ts index d951d0c..135e1d0 100644 --- a/src/core.ts +++ b/src/core.ts @@ -163,7 +163,7 @@ export abstract class APIClient { maxRetries = 2, timeout = 60000, // 1 minute httpAgent, - fetch: overridenFetch, + fetch: overriddenFetch, }: { baseURL: string; maxRetries?: number | undefined; @@ -176,7 +176,7 @@ export abstract class APIClient { this.timeout = validatePositiveInteger('timeout', timeout); this.httpAgent = httpAgent; - this.fetch = overridenFetch ?? fetch; + this.fetch = overriddenFetch ?? fetch; } protected authHeaders(opts: FinalRequestOptions): Headers { @@ -523,19 +523,13 @@ export abstract class APIClient { const timeout = setTimeout(() => controller.abort(), ms); return ( - this.getRequestClient() - // use undefined this binding; fetch errors if bound to something else in browser/cloudflare - .fetch.call(undefined, url, { signal: controller.signal as any, ...options }) - .finally(() => { - clearTimeout(timeout); - }) + // use undefined this binding; fetch errors if bound to something else in browser/cloudflare + this.fetch.call(undefined, url, { signal: controller.signal as any, ...options }).finally(() => { + clearTimeout(timeout); + }) ); } - protected getRequestClient(): RequestClient { - return { fetch: this.fetch }; - } - private shouldRetry(response: Response): boolean { // Note this is not a standard header. const shouldRetryHeader = response.headers.get('x-should-retry'); @@ -976,8 +970,8 @@ export const safeJSON = (text: string) => { } }; -// https://stackoverflow.com/a/19709846 -const startsWithSchemeRegexp = new RegExp('^(?:[a-z]+:)?//', 'i'); +// https://url.spec.whatwg.org/#url-scheme-string +const startsWithSchemeRegexp = /^[a-z][a-z0-9+.-]*:/i; const isAbsoluteURL = (url: string): boolean => { return startsWithSchemeRegexp.test(url); }; diff --git a/src/error.ts b/src/error.ts index 33e5404..a12d521 100644 --- a/src/error.ts +++ b/src/error.ts @@ -4,17 +4,19 @@ import { castToError, Headers } from './core'; export class StudioSDKError extends Error {} -export class APIError extends StudioSDKError { - readonly status: number | undefined; - readonly headers: Headers | undefined; - readonly error: Object | undefined; - - constructor( - status: number | undefined, - error: Object | undefined, - message: string | undefined, - headers: Headers | undefined, - ) { +export class APIError< + TStatus extends number | undefined = number | undefined, + THeaders extends Headers | undefined = Headers | undefined, + TError extends Object | undefined = Object | undefined, +> extends StudioSDKError { + /** HTTP status for the response that caused the error */ + readonly status: TStatus; + /** HTTP headers for the response that caused the error */ + readonly headers: THeaders; + /** JSON body of the response that caused the error */ + readonly error: TError; + + constructor(status: TStatus, error: TError, message: string | undefined, headers: THeaders) { super(`${APIError.makeMessage(status, error, message)}`); this.status = status; this.headers = headers; @@ -48,7 +50,7 @@ export class APIError extends StudioSDKError { message: string | undefined, headers: Headers | undefined, ): APIError { - if (!status) { + if (!status || !headers) { return new APIConnectionError({ message, cause: castToError(errorResponse) }); } @@ -90,17 +92,13 @@ export class APIError extends StudioSDKError { } } -export class APIUserAbortError extends APIError { - override readonly status: undefined = undefined; - +export class APIUserAbortError extends APIError { constructor({ message }: { message?: string } = {}) { super(undefined, undefined, message || 'Request was aborted.', undefined); } } -export class APIConnectionError extends APIError { - override readonly status: undefined = undefined; - +export class APIConnectionError extends APIError { constructor({ message, cause }: { message?: string | undefined; cause?: Error | undefined }) { super(undefined, undefined, message || 'Connection error.', undefined); // in some environments the 'cause' property is already declared @@ -115,32 +113,18 @@ export class APIConnectionTimeoutError extends APIConnectionError { } } -export class BadRequestError extends APIError { - override readonly status: 400 = 400; -} +export class BadRequestError extends APIError<400, Headers> {} -export class AuthenticationError extends APIError { - override readonly status: 401 = 401; -} +export class AuthenticationError extends APIError<401, Headers> {} -export class PermissionDeniedError extends APIError { - override readonly status: 403 = 403; -} +export class PermissionDeniedError extends APIError<403, Headers> {} -export class NotFoundError extends APIError { - override readonly status: 404 = 404; -} +export class NotFoundError extends APIError<404, Headers> {} -export class ConflictError extends APIError { - override readonly status: 409 = 409; -} +export class ConflictError extends APIError<409, Headers> {} -export class UnprocessableEntityError extends APIError { - override readonly status: 422 = 422; -} +export class UnprocessableEntityError extends APIError<422, Headers> {} -export class RateLimitError extends APIError { - override readonly status: 429 = 429; -} +export class RateLimitError extends APIError<429, Headers> {} -export class InternalServerError extends APIError {} +export class InternalServerError extends APIError {} diff --git a/src/version.ts b/src/version.ts index 9872581..baebd9d 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const VERSION = '0.1.0-alpha.15'; // x-release-please-version +export const VERSION = '0.1.0-alpha.16'; // x-release-please-version diff --git a/tests/index.test.ts b/tests/index.test.ts index f215310..7bff557 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -200,7 +200,7 @@ describe('instantiate client', () => { expect(client.bearerToken).toBe('My Bearer Token'); }); - test('with overriden environment variable arguments', () => { + test('with overridden environment variable arguments', () => { // set options via env var process.env['STUDIO_SDK_BEARER_TOKEN'] = 'another My Bearer Token'; const client = new StudioSDK({ bearerToken: 'My Bearer Token' }); diff --git a/yarn.lock b/yarn.lock index bfd47d8..bb17942 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1370,9 +1370,9 @@ create-require@^1.1.0: integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== cross-spawn@^7.0.2, cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + version "7.0.6" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" + integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== dependencies: path-key "^3.1.0" shebang-command "^2.0.0"