|
| 1 | +import type { AxiosRequestConfig } from 'axios' |
| 2 | +import type { Client } from './client.js' |
| 3 | +import type { SeamHttpRequestOptions } from './options.js' |
| 4 | +import { resolveActionAttempt } from './resolve-action-attempt.js' |
| 5 | +import { SeamHttpActionAttempts } from './index.js' |
| 6 | + |
| 7 | +export interface SeamApiRequestParent { |
| 8 | + readonly client: Client |
| 9 | + readonly defaults: Required<SeamHttpRequestOptions> |
| 10 | +} |
| 11 | + |
| 12 | +export type ResponseFromSeamApiRequest<T> = |
| 13 | + T extends SeamApiRequest<any, infer TResponse, infer TResourceKey> |
| 14 | + ? TResourceKey extends keyof TResponse |
| 15 | + ? TResponse[TResourceKey] |
| 16 | + : void |
| 17 | + : never |
| 18 | + |
| 19 | +export class SeamApiRequest< |
| 20 | + const TBody, |
| 21 | + const TResponse, |
| 22 | + const TResourceKey extends keyof TResponse | undefined, |
| 23 | +> implements |
| 24 | + PromiseLike< |
| 25 | + TResourceKey extends keyof TResponse ? TResponse[TResourceKey] : undefined |
| 26 | + > |
| 27 | +{ |
| 28 | + readonly parent: SeamApiRequestParent |
| 29 | + readonly requestConfig: AxiosRequestConfig<TBody> |
| 30 | + readonly resourceKey: TResourceKey |
| 31 | + readonly options: Pick<SeamHttpRequestOptions, 'waitForActionAttempt'> |
| 32 | + |
| 33 | + constructor( |
| 34 | + parent: SeamApiRequestParent, |
| 35 | + requestConfig: AxiosRequestConfig<TBody>, |
| 36 | + resourceKey: TResourceKey, |
| 37 | + options: Pick<SeamHttpRequestOptions, 'waitForActionAttempt'> = {}, |
| 38 | + ) { |
| 39 | + this.parent = parent |
| 40 | + this.requestConfig = requestConfig |
| 41 | + this.resourceKey = resourceKey |
| 42 | + this.options = options |
| 43 | + } |
| 44 | + |
| 45 | + async execute(): Promise< |
| 46 | + TResourceKey extends keyof TResponse ? TResponse[TResourceKey] : undefined |
| 47 | + > { |
| 48 | + const { client } = this.parent |
| 49 | + const response = await client.request(this.requestConfig) |
| 50 | + if (this.resourceKey === undefined) { |
| 51 | + return undefined as TResourceKey extends keyof TResponse |
| 52 | + ? TResponse[TResourceKey] |
| 53 | + : undefined |
| 54 | + } |
| 55 | + const data = response.data[this.resourceKey] |
| 56 | + if (this.resourceKey === 'action_attempt') { |
| 57 | + const waitForActionAttempt = |
| 58 | + this.options.waitForActionAttempt ?? |
| 59 | + this.parent.defaults.waitForActionAttempt |
| 60 | + if (waitForActionAttempt !== false) { |
| 61 | + return resolveActionAttempt( |
| 62 | + data, |
| 63 | + SeamHttpActionAttempts.fromClient(client, { |
| 64 | + ...this.parent.defaults, |
| 65 | + waitForActionAttempt: false, |
| 66 | + }), |
| 67 | + typeof waitForActionAttempt === 'boolean' ? {} : waitForActionAttempt, |
| 68 | + ) |
| 69 | + } |
| 70 | + } |
| 71 | + return data |
| 72 | + } |
| 73 | + |
| 74 | + then< |
| 75 | + TResult1 = TResourceKey extends keyof TResponse |
| 76 | + ? TResponse[TResourceKey] |
| 77 | + : undefined, |
| 78 | + TResult2 = never, |
| 79 | + >( |
| 80 | + onfulfilled?: |
| 81 | + | (( |
| 82 | + value: TResourceKey extends keyof TResponse |
| 83 | + ? TResponse[TResourceKey] |
| 84 | + : undefined, |
| 85 | + ) => TResult1 | PromiseLike<TResult1>) |
| 86 | + | null |
| 87 | + | undefined, |
| 88 | + onrejected?: |
| 89 | + | ((reason: any) => TResult2 | PromiseLike<TResult2>) |
| 90 | + | null |
| 91 | + | undefined, |
| 92 | + ): PromiseLike<TResult1 | TResult2> { |
| 93 | + return this.execute().then(onfulfilled, onrejected) |
| 94 | + } |
| 95 | +} |
0 commit comments