better-trakt
Version:
A Trakt.tv client with native Typescript support and quality of life features
199 lines (176 loc) • 4.21 kB
text/typescript
import { AxiosError, AxiosInstance, AxiosResponseHeaders } from 'axios';
import { CommentSortByMedia, ListQueryByType, RecommendedPeriod, ReleasesCountry, UpdatedStartDate } from '../trakt';
import { buildUrl } from './buildUrl';
import { TraktHttpError } from './error';
export interface Filters {
/**
* Search titles and descriptions.
* @example batman
*/
query?: string;
/**
* 4 digit year or range of years.
* @example 2016
*/
years?: string;
/**
* Genre slugs.
* @example action
* @see {@link Genre.slug | Genre slug}
*/
genres?: string[];
/**
* 2 character language code.
* @example en
*/
languages?: string[];
/**
* 2 character country code.
* @example us
*/
countries?: string[];
/**
* Range in minutes.
* @example 30-90
*/
runtimes?: string;
/**
* Studio slugs.
* @example marvel-studios
*/
studios?: string[];
}
/**
* Pagination Options
*/
export interface Pagination {
/**
* Current page
*/
page: number;
/**
* Items per page
*/
limit: number;
}
/**
* Pagination Response Obj
*/
export interface PaginationResponse extends Pagination {
/**
* Total number of pages
*/
pageCount: number;
/**
* Total number of items
*/
itemCount: number;
}
export interface ApiResponse<T> {
/**
* Reponse data
*/
data?: T;
/**
* Pagination info
*/
pagination?: PaginationResponse;
/**
* API response headers
*
* @remarks
* Can be useful for things like cache control, ratelimiting, or general debuging
*/
headers: AxiosResponseHeaders | Partial<Record<string, string> & { 'set-cookie'?: string[] | undefined }>;
/**
* Error object in the event of an error
*/
error?: TraktHttpError;
}
export interface FetchOptions {
/**
* Token to access trakt api
*/
accessToken?: string;
/**
* Pagination settings
*/
pagination?: Pagination;
/**
* filter options
*/
filters?: Filters;
/**
* Period to pull from
*/
period?: RecommendedPeriod;
/**
* Start date
*/
startDate?: UpdatedStartDate;
/**
* Specify country to look for
*/
country?: ReleasesCountry;
/**
* Specify a language
*/
language?: string;
/**
* Sorting options
*
* (This is just the most inclusive type, not always this permissive.)
*/
sort?: CommentSortByMedia;
/**
* Types of lists one can query by
*/
type?: ListQueryByType;
}
/**
* Custom fetch func for calling trakt api
* @param client axios instance
* @param url trakt api uri
* @param accessToken access token for oauth related actions
* @returns Specified type or undefined
* @internal
*/
export async function fetch<T>(client: AxiosInstance, url: string, options?: FetchOptions): Promise<ApiResponse<T>> {
try {
const response = await client.get<T>(buildUrl(url, options), {
headers:
options !== undefined && options.accessToken !== undefined
? { Authorization: `Bearer ${options.accessToken}` }
: undefined,
// parseJson: (text: string) => Bourne.parse(text),
});
const res: ApiResponse<T> = {
data: response.data,
headers: response.headers,
};
if (
response.headers['X-Pagination-Page'] !== undefined &&
response.headers['X-Pagination-Limit'] !== undefined &&
response.headers['X-Pagination-Page-Count'] !== undefined &&
response.headers['X-Pagination-Item-Count'] !== undefined
) {
res.pagination = {
page: parseInt(response.headers['X-Pagination-Page']),
limit: parseInt(response.headers['X-Pagination-Limit']),
pageCount: parseInt(response.headers['X-Pagination-Page-Count']),
itemCount: parseInt(response.headers['X-Pagination-Item-Count']),
};
}
return res;
} catch (e) {
if (e instanceof AxiosError && e.response !== undefined) {
// throw new TraktHttpError(e.response.status, e.response.data, e.response.headers);
return {
error: new TraktHttpError(e.response.status, e.response.data, e.response.headers),
headers: e.response.headers,
};
}
// console.error(e);
throw e;
}
}