diff --git a/src/lib/seam/connect/axios.ts b/src/lib/seam/connect/axios.ts new file mode 100644 index 00000000..d55336c0 --- /dev/null +++ b/src/lib/seam/connect/axios.ts @@ -0,0 +1,23 @@ +import axios, { type Axios } from 'axios' + +import { getAuthHeaders } from './auth.js' +import { + isSeamHttpOptionsWithClientSessionToken, + type SeamHttpOptions, +} from './client-options.js' + +export const createAxiosClient = ( + options: Required, +): Axios => { + // TODO: axiosRetry? Allow options to configure this if so + return axios.create({ + baseURL: options.endpoint, + withCredentials: isSeamHttpOptionsWithClientSessionToken(options), + ...options.axiosOptions, + headers: { + ...getAuthHeaders(options), + ...options.axiosOptions.headers, + // TODO: User-Agent + }, + }) +} diff --git a/src/lib/seam/connect/client.ts b/src/lib/seam/connect/client.ts index 11e6b43e..ca7c1d36 100644 --- a/src/lib/seam/connect/client.ts +++ b/src/lib/seam/connect/client.ts @@ -1,6 +1,6 @@ -import axios, { type Axios } from 'axios' +import type { Axios } from 'axios' -import { getAuthHeaders } from './auth.js' +import { createAxiosClient } from './axios.js' import { InvalidSeamHttpOptionsError, isSeamHttpOptionsWithApiKey, @@ -9,8 +9,9 @@ import { type SeamHttpOptionsWithApiKey, type SeamHttpOptionsWithClientSessionToken, } from './client-options.js' -import { LegacyWorkspaces } from './legacy/workspaces.js' -import { Workspaces } from './routes/workspaces.js' +import { LegacyWorkspacesHttp } from './legacy/workspaces.js' +import { parseOptions } from './parse-options.js' +import { WorkspacesHttp } from './routes/workspaces.js' export class SeamHttp { client: Axios @@ -20,18 +21,7 @@ export class SeamHttp { constructor(apiKeyOrOptions: string | SeamHttpOptions) { const options = parseOptions(apiKeyOrOptions) this.#legacy = options.enableLegacyMethodBehaivor - - // TODO: axiosRetry? Allow options to configure this if so - this.client = axios.create({ - baseURL: options.endpoint, - withCredentials: isSeamHttpOptionsWithClientSessionToken(options), - ...options.axiosOptions, - headers: { - ...getAuthHeaders(options), - ...options.axiosOptions.headers, - // TODO: User-Agent - }, - }) + this.client = createAxiosClient(options) } static fromApiKey( @@ -66,37 +56,8 @@ export class SeamHttp { // Better to implement error handling and wrapping in an error handler. // makeRequest - get workspaces(): Workspaces { - const workspaces = new Workspaces(this.client) - if (this.#legacy) return new LegacyWorkspaces(this.client) - return workspaces - } -} - -const parseOptions = ( - apiKeyOrOptions: string | SeamHttpOptions, -): Required => { - const options = - typeof apiKeyOrOptions === 'string' - ? { apiKey: apiKeyOrOptions } - : apiKeyOrOptions - - const endpoint = - options.endpoint ?? - globalThis.process?.env?.['SEAM_ENDPOINT'] ?? - globalThis.process?.env?.['SEAM_API_URL'] ?? - 'https://connect.getseam.com' - - const apiKey = - 'apiKey' in options - ? options.apiKey - : globalThis.process?.env?.['SEAM_API_KEY'] - - return { - ...options, - ...(apiKey != null ? { apiKey } : {}), - endpoint, - axiosOptions: options.axiosOptions ?? {}, - enableLegacyMethodBehaivor: false, + get workspaces(): WorkspacesHttp { + if (this.#legacy) return new LegacyWorkspacesHttp(this.client) + return new WorkspacesHttp(this.client) } } diff --git a/src/lib/seam/connect/legacy/workspaces.ts b/src/lib/seam/connect/legacy/workspaces.ts index be80de9f..c6909acd 100644 --- a/src/lib/seam/connect/legacy/workspaces.ts +++ b/src/lib/seam/connect/legacy/workspaces.ts @@ -1,9 +1,9 @@ import type { RouteRequestParams, RouteResponse } from '@seamapi/types/connect' import type { SetNonNullable } from 'type-fest' -import { Workspaces } from 'lib/seam/connect/routes/workspaces.js' +import { WorkspacesHttp } from 'lib/seam/connect/routes/workspaces.js' -export class LegacyWorkspaces extends Workspaces { +export class LegacyWorkspacesHttp extends WorkspacesHttp { override async get( params: WorkspacesGetParams = {}, ): Promise { diff --git a/src/lib/seam/connect/parse-options.ts b/src/lib/seam/connect/parse-options.ts new file mode 100644 index 00000000..47a84472 --- /dev/null +++ b/src/lib/seam/connect/parse-options.ts @@ -0,0 +1,28 @@ +import type { SeamHttpOptions } from './client-options.js' +export const parseOptions = ( + apiKeyOrOptions: string | SeamHttpOptions, +): Required => { + const options = + typeof apiKeyOrOptions === 'string' + ? { apiKey: apiKeyOrOptions } + : apiKeyOrOptions + + const endpoint = + options.endpoint ?? + globalThis.process?.env?.['SEAM_ENDPOINT'] ?? + globalThis.process?.env?.['SEAM_API_URL'] ?? + 'https://connect.getseam.com' + + const apiKey = + 'apiKey' in options + ? options.apiKey + : globalThis.process?.env?.['SEAM_API_KEY'] + + return { + ...options, + ...(apiKey != null ? { apiKey } : {}), + endpoint, + axiosOptions: options.axiosOptions ?? {}, + enableLegacyMethodBehaivor: false, + } +} diff --git a/src/lib/seam/connect/routes/workspaces.ts b/src/lib/seam/connect/routes/workspaces.ts index a8601b40..5e54330e 100644 --- a/src/lib/seam/connect/routes/workspaces.ts +++ b/src/lib/seam/connect/routes/workspaces.ts @@ -1,12 +1,22 @@ import type { RouteRequestParams, RouteResponse } from '@seamapi/types/connect' -import type { Axios } from 'axios' +import { Axios } from 'axios' import type { SetNonNullable } from 'type-fest' -export class Workspaces { +import { createAxiosClient } from 'lib/seam/connect/axios.js' +import type { SeamHttpOptions } from 'lib/seam/connect/client-options.js' +import { parseOptions } from 'lib/seam/connect/parse-options.js' + +export class WorkspacesHttp { client: Axios - constructor(client: Axios) { - this.client = client + constructor(apiKeyOrOptionsOrClient: Axios | string | SeamHttpOptions) { + if (apiKeyOrOptionsOrClient instanceof Axios) { + this.client = apiKeyOrOptionsOrClient + return + } + + const options = parseOptions(apiKeyOrOptionsOrClient) + this.client = createAxiosClient(options) } async get(