import { ClientAuthToken, DeepReadonly } from '..'; import { RequestConfig, HTTPResponse, HTTPClient, HTTPRequestCompletionCallback, HTTPErrorHandler } from './types'; interface HevyAPIClientConfig { /** * How long before predicted token expiry to request a new token. We request * new tokens a little bit before they expire, so that we don't have to wait * for the backend to send us a 401 first. We do it pre-emptively so that we * wouldn't need to wait for requests to fail first, and then retry them. * * Optional. * * @default {1 minute} */ readonly tokenExpirySafetyThresholdMs?: number; /** * How long we expect the access token to be valid for. Used to override the * expiry time sent by the backend in case the client clock is in the future * and the client thinks that the token will expire sooner than it actually * will. Even if this assumption ever stops being correct, the client will be * able to self-correct by receiving an `AccessTokenExpired` 401 response. * * Optional. * * @default {15 minutes} */ readonly accessTokenMinimumValidAgeMs?: number; /** * Minimum time between successive calls to the `auth/refresh_token` endpoint * in case it doesn't return an error. Also used to deal with potential clock * issues on the client side, or some unforeseen issue on the backend, as the * last line of defence. No matter what may happen, we absolutely never ever * want to end up accidentally spamming this endpoint because it could have a * cascading clusterfuck effect on all the other requests. * * Optional. * * @default {20 seconds} */ readonly tokenRefreshThrottleMs?: number; /** * The API endpoint used to refresh the auth tokens using a refresh token. * The URL is relative to the backend base URL. * * Optional. * * @default {POST /auth/refresh_token} */ readonly refreshAuthTokenApiEndpoint?: { readonly method: 'post'; readonly url: string; }; /** * Callback to use when receiving a new auth token. Used to send it to the * consumer of the class to save the new token to its local storage. * * Required. */ onNewAuthToken(newAuthToken: ClientAuthToken, userContext: UserContext): void; /** * Defines an arbitrary object to be passed back to the `onNewAuthToken`. The * value is computed at the time when the request is made. Useful for passing * back state that may have gotten changed during the time while the request * was being processed, such as holding onto a userId across a logout action. * * Optional. */ getUserContext?(): UserContext; /** * Callback to use when receiving an HTTP error response from the backend, to * determine whether it is a response indicating that the token has expired. * * Optional. * * @default ... */ isAccessTokenExpiredResponse?(response: HTTPResponse): boolean; /** * Callback to use when receiving an HTTP error response from the backend, to * determine whether it is a response indicating that the token is invalid. * * Optional. * * @default ... */ isAccessTokenInvalidResponse?(response: HTTPResponse): boolean; } export declare class HevyAPIClient { private static readonly DEFAULT_TOKEN_EXPIRY_SAFETY_THRESHOLD_MS; private static readonly DEFAULT_ACCESS_TOKEN_MINIMUM_VALID_AGE_MS; private static readonly DEFAULT_TOKEN_REFRESH_THROTTLE_MS; private static readonly DEFAULT_REFRESH_AUTH_TOKEN_API_ENDPOINT; private readonly _config; private _requestCompletionCallbacks; private _errorHandlers; private _authTokenFactory; private _legacyAuthToken; private _httpClient; private _lastTokenRefresh; private _lastSessionDelete; constructor(httpClient: HTTPClient, config: HevyAPIClientConfig); private get _authToken(); private get _authHeaders(); private _addHeaders; private refreshExpiredAuthToken; private forceRefreshAuthToken; private waitForTokenRefresh; private get _isTokenRecentlyRefreshed(); private _refreshAuthToken; private _handleResponse; isAccessTokenExpiredResponse(response: HTTPResponse): boolean; isAccessTokenInvalidResponse(response: HTTPResponse): boolean; get refreshAuthTokenApiEndpoint(): { readonly method: "post"; readonly url: string; }; setAuthToken(newAuthToken: { authToken: DeepReadonly | null; legacyAuthToken: string | null; }): Promise; setAuthToken(newAuthToken: { getAuthToken: () => ClientAuthToken | null; legacyAuthToken: string | null; }): Promise; clearAuthToken(): Promise; get isAuthenticated(): boolean; markSessionDeleted(): void; /** * Adds a callback to be executed whenever a request has finished processing. * This means either that the request has received a response, or that there * was an error. In the case of an error, it may be either an HTTP error from * the server, or some other type of error, such as a network error. * * This is a lower level API than {@link attachErrorHandler} - prefer using * that one instead of this one if it's enough to suit your needs. */ attachRequestCompletionCallback(onResult: HTTPRequestCompletionCallback): void; removeRequestCompletionCallbacks(): void; /** * Adds a callback to be executed on receiving an HTTP error from the server. * This callback will not be executed for any other type of error, such as a * network error. For that and more, use {@link attachRequestCompletionCallback}. */ attachErrorHandler(onError: HTTPErrorHandler<{ willRetry: boolean; isTokenRefreshedAfterRequest: boolean; isPreviousSession: boolean; }>): void; removeErrorHandlers(): void; get(url: string, config?: RequestConfig): Promise>; delete(url: string, config?: RequestConfig): Promise>; head(url: string, config?: RequestConfig): Promise>; options(url: string, config?: RequestConfig): Promise>; post(url: string, data?: R, config?: RequestConfig): Promise>; put(url: string, data?: R, config?: RequestConfig): Promise>; patch(url: string, data?: R, config?: RequestConfig): Promise>; } export {};