@zennomi/mangadex-full-api
Version:
A MangaDex api based around the official API.
178 lines (164 loc) • 5.42 kB
text/typescript
import IDObject from '../internal/IDObject';
import {
fetchMD,
fetchMDByArrayParam,
fetchMDData,
fetchMDDataWithBody,
fetchMDSearch,
fetchMDWithFormData,
} from '../util/Network';
import Relationship from '../internal/Relationship';
import type Manga from './Manga';
import type {
CoverAttributesSchema,
CoverEditSchema,
CoverListSchema,
CoverResponseSchema,
CoverSchema,
GetCoverParamsSchema,
ResponseSchema,
Cover as CoverNamespace,
} from '../types/schema';
import type { Merge } from '../types/helpers';
import type User from './User';
type CoverSearchParams = Partial<Merge<GetCoverParamsSchema, { ids: Cover[]; manga: Manga[] }>>;
type CoverExpandedTypes = CoverSearchParams['includes'];
type CoverUploadBody = Omit<CoverNamespace.UploadCover.RequestBody, 'file'> & { file: Blob };
export default class Cover extends IDObject implements CoverAttributesSchema {
/**
* MangaDex UUID for this object
*/
id: string;
/**
* What volume is this cover for, if any
*/
volume: string | null;
/**
* The file name of this cover's image
*/
fileName: string;
/**
* Description of this cover. May be an empty string
*/
description: string | null;
/**
* What language is this cover in
*/
locale: string | null;
/**
* The version of this cover (incremented by updating the cover)
*/
version: number;
/**
* The date this cover was uploaded
*/
createdAt: Date;
/**
* The date this cover was last updated
*/
updatedAt: Date;
/**
* Url to this cover's image
* Can be null because of undefined manga
*/
url: string | null;
/**
* Relationship to the manga this cover belongs to
*/
manga: Relationship<Manga>;
/**
* Relationship to the user who uploaded this cover
*/
uploader: Relationship<User>;
constructor(schem: CoverSchema) {
super();
this.id = schem.id;
this.volume = schem.attributes.volume;
this.fileName = schem.attributes.fileName;
this.description = schem.attributes.description;
this.locale = schem.attributes.locale;
this.version = schem.attributes.version;
this.createdAt = new Date(schem.attributes.createdAt);
this.updatedAt = new Date(schem.attributes.updatedAt);
this.manga = Relationship.convertType<Manga>('manga', schem.relationships).pop()!;
this.url = this.manga ? `https://mangadex.org/covers/${this.manga.id}/${this.fileName}` : null;
this.uploader = Relationship.convertType<User>('user', schem.relationships).pop()!;
}
/**
* Retrieves a cover by its id
*/
static async get(id: string | Manga, expandedTypes?: CoverExpandedTypes): Promise<Cover> {
if (id instanceof IDObject) id = id.id;
return new Cover(await fetchMDData<CoverResponseSchema>(`/cover/${id}`, { includes: expandedTypes }));
}
/**
* Retrieves a list of covers according to the specified search parameters
*/
static async search(query?: CoverSearchParams) {
const res = await fetchMDSearch<CoverListSchema>(`/cover`, query);
return res.map((m) => new Cover(m));
}
/**
* Performs a search for a cover and returns the first one found. If no results are
* found, null is returned
*/
static async getByQuery(query?: CoverSearchParams): Promise<Cover | null> {
const res = await this.search(query);
return res[0] ?? null;
}
/**
* Retrieves an array of covers by an array of ids
*/
static async getMultiple(ids: string[]): Promise<Cover[]> {
const res = await fetchMDByArrayParam<CoverListSchema>('/cover', ids);
return res.map((a) => new Cover(a));
}
/**
* Returns an array of covers from an array of manga ids or a single manga
*/
static async getMangaCovers(
manga: Manga | string | Manga[] | string[],
expandedTypes?: CoverExpandedTypes,
): Promise<Cover[]> {
if (!Array.isArray(manga)) manga = [typeof manga === 'string' ? manga : manga.id];
if (manga.length === 0) return [];
const ids = manga.map((m) => (typeof m === 'string' ? m : m.id));
return Cover.search({ manga: ids, includes: expandedTypes });
}
/**
* Deletes a cover by their id
*/
static async delete(id: string) {
await fetchMD<ResponseSchema>(`/cover/${id}`, undefined, { method: 'DELETE' });
}
/**
* Deletes this cover
*/
async delete() {
await Cover.delete(this.id);
}
/**
* Updates a cover's information.
*/
async update(data: Omit<CoverEditSchema, 'version'>) {
return new Cover(
await fetchMDDataWithBody<CoverResponseSchema>(
`/cover/${this.id}`,
{
...data,
version: this.version + 1,
},
undefined,
'PUT',
),
);
}
/**
* Uploads a new cover
*/
static async create(manga: string | Manga, data: CoverUploadBody) {
if (typeof manga !== 'string') manga = manga.id;
const res = await fetchMDWithFormData<CoverResponseSchema>(`/cover/${manga}`, data);
return new Cover(res.data);
}
}