api-client: migrate session handler and response types

This commit is contained in:
dumbmoron 2024-09-11 20:23:06 +00:00
parent ab8650030b
commit 6cc1227288
No known key found for this signature in database
3 changed files with 138 additions and 8 deletions

View File

@ -0,0 +1,59 @@
import { CobaltSession, CobaltResponseType, CobaltSessionResponse } from "./types/response";
import { CobaltReachabilityError } from "./types/errors";
const currentTime = () => Math.floor(new Date().getTime() / 1000);
const EXPIRY_THRESHOLD_SECONDS = 2;
export default class CobaltSessionHandler {
#baseURL: string;
#session: CobaltSession | undefined;
constructor(baseURL: string) {
this.#baseURL = baseURL;
}
async #requestSession(turnstileResponse?: string): Promise<CobaltSessionResponse> {
const endpoint = new URL('/session', this.#baseURL);
const headers: Record<string, string> = {};
if (turnstileResponse) {
headers['cf-turnstile-response'] = turnstileResponse;
}
const response = await fetch(endpoint, {
method: 'POST',
redirect: 'manual',
signal: AbortSignal.timeout(10000),
headers
})
.then(r => r.json())
.catch((e) => {
const timedOut = e?.message?.includes("timed out");
return {
status: CobaltResponseType.Error,
error: {
code: timedOut
? CobaltReachabilityError.TimedOut
: CobaltReachabilityError.Unreachable
}
};
});
if ('token' in response && 'exp' in response) {
this.#session = {
token: response.token,
exp: currentTime() + response.exp
}
}
return response;
}
async getSession(turnstileResponse?: string): Promise<CobaltSessionResponse> {
if (this.#session && this.#session.exp - EXPIRY_THRESHOLD_SECONDS > currentTime()) {
return this.#session;
}
return this.#requestSession(turnstileResponse);
}
};

View File

@ -56,11 +56,11 @@ export enum CobaltYouTubeError {
TokenExpired = 'error.api.youtube.token_expired'
}
export type CobaltAPIError = CobaltAuthError
| CobaltReachabilityError
| CobaltGenericError
| CobaltServiceError
| CobaltLinkError
| CobaltProcessingError
| CobaltContentError
| CobaltYouTubeError;
export type CobaltAPIErrorCode = CobaltAuthError
| CobaltReachabilityError
| CobaltGenericError
| CobaltServiceError
| CobaltLinkError
| CobaltProcessingError
| CobaltContentError
| CobaltYouTubeError;

View File

@ -0,0 +1,71 @@
import { CobaltAPIErrorCode } from "./errors";
export enum CobaltResponseType {
Error = 'error',
Picker = 'picker',
Redirect = 'redirect',
Tunnel = 'tunnel',
}
export type CobaltErrorResponse = {
status: CobaltResponseType.Error,
error: {
code: CobaltAPIErrorCode,
context?: {
service?: string,
limit?: number,
}
},
};
type CobaltPartialURLResponse = {
url: string,
filename: string,
}
type CobaltPickerResponse = {
status: CobaltResponseType.Picker
picker: {
type: 'photo' | 'video' | 'gif',
url: string,
thumb?: string,
}[];
audio?: string,
audioFilename?: string,
};
type CobaltRedirectResponse = {
status: CobaltResponseType.Redirect,
} & CobaltPartialURLResponse;
type CobaltTunnelResponse = {
status: CobaltResponseType.Tunnel,
} & CobaltPartialURLResponse;
export type CobaltSession = {
token: string,
exp: number,
}
export type CobaltServerInfo = {
cobalt: {
version: string,
url: string,
startTime: string,
durationLimit: number,
services: string[]
},
git: {
branch: string,
commit: string,
remote: string,
}
}
export type CobaltSessionResponse = CobaltSession | CobaltErrorResponse;
export type CobaltServerInfoResponse = CobaltServerInfo | CobaltErrorResponse;
export type CobaltAPIResponse = CobaltErrorResponse
| CobaltPickerResponse
| CobaltRedirectResponse
| CobaltTunnelResponse;