UNPKG

nyaa.si-client

Version:
439 lines (434 loc) 14.2 kB
// Generated by dts-bundle-generator v9.5.1 import { AxiosInstance } from 'axios'; import { Browser, Page } from 'puppeteer'; import UserAgent from 'user-agents'; export declare abstract class Method<RunTime extends RunTimes, const in out AdditionalDetails extends (DetailsOptions | boolean) = false> { readonly job: Job<RunTime>; readonly url: string; readonly loadAdditionalInfo: AdditionalDetails; constructor({ job, url, loadAdditionalInfo }: MethodOptions<RunTime, AdditionalDetails>); abstract extract(params: string): Promise<ListData<AdditionalDetails>>; abstract details<AdditionalDetails extends (DetailsOptions | boolean)>(id: number | string | TorrentData, options?: AdditionalDetails): Promise<MapDetailsOptions<AdditionalDetails>>; } export declare class Cheerio<RunTime extends RunTimes.Cheerio, const in out AdditionalDetails extends (DetailsOptions | boolean) = false> extends Method<RunTime, AdditionalDetails> { extract(params: string): Promise<ListData<AdditionalDetails>>; details<AdditionalDetails extends (DetailsOptions | boolean)>(url: string, options?: AdditionalDetails): Promise<MapDetailsOptions<AdditionalDetails>>; static parseTorrentComponents(parent: string | null): (FileEntity | FolderEntity)[]; static parseSizeToBytes(sizeString: string): number; static extractPageNumber(url: string): number | undefined; } export declare class Client<const in out RunTime extends RunTimes = RunTimes.Cheerio> { static session: SessionManager; readonly runTime: RunTime; browser: BrowserInstance<RunTime>; readonly jobs: Map<string, Job<RunTime>>; readonly timeout: number; readonly showNavigator: boolean; readonly concurrentJobs: number; readonly requestQueue: ((job: Job<RunTime>) => void)[]; private host; private readonly emitter; on<K extends keyof JobEvents<RunTime>>(event: K, listener: (...args: JobEvents<RunTime>[K]) => void): void; emit<K extends keyof JobEvents<RunTime>>(event: K, ...args: JobEvents<RunTime>[K]): void; constructor(options?: ClientOptions<RunTime>); initialize(): Promise<void>; setupPuppeteer(): Promise<this>; setupCheerio(): this; set setURL(url: string); getURL(): string; newAxiosInstance(): { instance: import("axios").AxiosInstance; instanceId: string; }; newPage(): Promise<{ page: import("puppeteer").Page; pageId: string; }>; requestJob(): Promise<Job<RunTime>>; private setupQueueListener; } export declare class Exporter<AdditionalDetails extends (DetailsOptions | boolean), RunTime extends RunTimes> { private scraper; private search; private data; constructor(options: ExporterProps<AdditionalDetails, RunTime>); getData(): ListData<AdditionalDetails>; private setData; addNextPage(loadPages?: number): Promise<this>; getNextPage(loadPages?: number): Promise<Exporter<AdditionalDetails, RunTime>>; } export declare class Job<RunTime extends RunTimes> { id: string; status: JobStatus; readonly timeout: number; readonly runTime: RunTime; api: RunTimeAPI<RunTime>; client: Client<RunTime>; constructor({ runTime, timeout, client, api, id }: JobProps<RunTime>); finishedTask(): Promise<void>; stop(): void; } export declare class Puppeteer<RunTime extends RunTimes.Puppeteer, const in out AdditionalDetails extends (DetailsOptions | boolean) = false> extends Method<RunTime, AdditionalDetails> { extract(params: string): Promise<ListData<AdditionalDetails>>; details<AdditionalDetails extends (DetailsOptions | boolean)>(id: number | string | TorrentData, options?: AdditionalDetails): Promise<MapDetailsOptions<AdditionalDetails>>; private waitForConnect; } export declare class Scraper<AdditionalDetails extends (DetailsOptions | boolean), RunTime extends RunTimes> { readonly pagesToLoad: number; readonly loadAdditionalInfo: AdditionalDetails; readonly client: Client<RunTime>; constructor(options: ({ client: Client<RunTime>; }) & ScraperProps<AdditionalDetails>); search<PageNumber extends number | undefined = undefined>(content: string, options?: { filter?: FilterParams; page?: PageNumber; loadOnlyPage?: PageNumber extends number ? boolean : never; }, cache?: Exporter<AdditionalDetails, RunTime>): Promise<Exporter<AdditionalDetails, RunTime>>; /** * @example * * const scraper = new Scraper() * * await scraper.details(1918530) * await scraper.details('1918530') * await scraper.details('https://nyaa.si/view/1918530') * * const extract = await scraper.search('re: zero') * scraper.details(extract.getData().torrents[0]) * * @public * @param {(number | string | TorrentData)} id - Identifier for the torrent (ID, URL, or object). * @param {DetailsOptions} options - Options for fetching details. */ details(id: number | string | TorrentData, options?: AdditionalDetails): Promise<MapDetailsOptions<AdditionalDetails>>; static getSearchParams(content: string, page?: number | undefined, filter?: FilterParams): string; /** * Normalizes various input types into a numeric ID. * * @private * @param {(number | string | TorrentData)} id - Input data to normalize. * @returns {(number | null)} - Normalized numeric ID, or `null` if invalid. */ static normalizeId(id: number | string | TorrentData): number | null; /** * Extracts the Id from a url * * @example * * Scraper.extractId('https://nyaa.si/view/1918510') // 1918510 * * @param {string} url * @returns {*} */ static extractId(url: string): number | undefined; } export declare class SessionManager { private options?; private sessions; constructor(options?: SessionOptions | undefined); create(id: string, filter?: SessionOptions["userAgentOptions"]): string; get(id: string): string | undefined; createOrGet(id: string, filter?: SessionOptions["userAgentOptions"]): string; clear(id: string): boolean; } export declare class TypedEventEmitter<Events extends Record<string, unknown[]>> { private readonly emitter; on<K extends keyof Events>(event: K, listener: (...args: Events[K]) => void): this; emit<K extends keyof Events>(event: K, ...args: Events[K]): boolean; off<K extends keyof Events>(event: K, listener: (...args: Events[K]) => void): this; } export declare const FilterObject: { readonly anime: readonly [ "anime_music_video", "english_translated", "non_english_translated", "raw" ]; readonly audio: readonly [ "lossless", "lossy" ]; readonly literature: readonly [ "english_translated", "non_english_translated", "raw" ]; readonly live_action: readonly [ "english_translated", "idol_promotional_video", "non_english_translated", "raw" ]; readonly pictures: readonly [ "graphics", "photos" ]; readonly software: readonly [ "applications", "games" ]; }; export declare enum DataTypes { List = "list", Details = "details" } export declare enum ElementPropertyTypes { TextContent = "textContent", Href = "href", GetAttribute = "getAttribute" } export declare enum FileEntityType { File = "file", Folder = "folder" } export declare enum Filters { /** * All torrents. */ NoFilter = 0, /** * entries (remake) are torrents that match any of the following: * -> Reencode of original release. * -> Remux of another uploader's original release for hardsubbing and/or fixing purposes. * -> Reupload of original release using non-original file names. * -> Reupload of original release with missing and/or unrelated additional files. */ NoRemakes = 1, /** * Torrents uploaded by trusted users. */ TrustedOnly = 2 } export declare enum JobStatus { Reserved = "reserved", Listening = "listening", Dead = "dead" } export declare enum RunTimes { Puppeteer = "puppeteer", Cheerio = "cheerio" } export type BrowserInstance<RunTime extends RunTimes> = RunTime extends RunTimes.Puppeteer ? Browser : never; export type ClientOptions<RunTime extends RunTimes> = { session?: SessionManager; /** * Total number of pages to be processed in parallel * * @default 1 */ concurrentJobs?: number; /** * This limits the time for the next job request, I don't recommend decreasing this to less than 3000 ms * * @default 3000 */ timeout?: number; runTime?: RunTime; /** * Shows the browser and the actions being taken to perform webscraping * * @default false */ showNavigator?: RunTime extends RunTimes.Puppeteer ? boolean : never; }; export type ConditionalField<T, K extends keyof T, Condition> = Condition extends true | string ? Pick<T, K> : OptionalField<T, K>; export type DetailsEntity = { type: DataTypes.Details; description: string; submitter: Submitter; information: string; files: (FileEntity | FolderEntity)[]; comments: Comment$1[]; }; export type DetailsOptions = { /** * @default 'markdown' * @type {?(boolean | 'markdown' | 'html' | 'text')} */ description?: boolean | "markdown" | "html" | "text"; submitter?: boolean | undefined; information?: boolean; files?: boolean; comments?: boolean; }; export type ElementGetAttribute = { type: ElementPropertyTypes.GetAttribute; attributeName: string; element: HTMLElement; }; export type ElementHref = { type: ElementPropertyTypes.Href; element: HTMLAnchorElement; }; export type ElementPropertyOptions = (ElementHref | ElementTextContent | ElementGetAttribute); export type ElementSelector = { row: Element; selector: string; subSelector?: string; }; export type ElementTextContent = { type: ElementPropertyTypes.TextContent; element: HTMLElement; }; export type ExporterProps<AdditionalDetails extends (DetailsOptions | boolean), RunTime extends RunTimes> = { scraper: Scraper<AdditionalDetails, RunTime>; search: { content: string; filter?: FilterParams; }; data: ListData<AdditionalDetails>; }; export type FileEntity = { type: FileEntityType.File; /** * The name of the file. */ fileName: string; /** * The size of the file as a human-readable string (e.g., "1 MiB"). */ readableSize: string; /** * The size of the file in bytes. */ sizeInBytes: number; }; export type FilterKeys = keyof FilterSearch; export type FilterParams = { category?: FilterSearchPaths; /** * @default Filters.NoFilter */ filter?: Filters; }; export type FilterSearch = typeof FilterObject; export type FilterSearchPaths = NestedKeys<FilterSearch>; export type FilterValues = FilterSearch[keyof FilterSearch][number]; export type FolderEntity = { type: FileEntityType.Folder; /** * The name of the folder. */ name: string; /** * The list of files contained within the folder. */ files: (FileEntity | FolderEntity)[]; }; export type JobEvents<RunTime extends RunTimes> = { died: [ Omit<Job<RunTime>, "create" | "finishedTask"> ]; started: [ Omit<Job<RunTime>, "create" | "finishedTask"> ]; reserved: [ Omit<Job<RunTime>, "create" | "finishedTask"> ]; listening: [ Omit<Job<RunTime>, "create" | "finishedTask"> ]; }; export type JobProps<RunTime extends RunTimes> = { id: string; api: RunTimeAPI<RunTime>; client: Client<RunTime>; timeout: number; runTime: RunTime; }; export type ListData<AdditionalDetails extends (DetailsOptions | boolean)> = { type: DataTypes.List; metadata: { hasPreviousPage: boolean; previousPage?: number; previousPageLink?: string; hasNextPage: boolean; nextPage?: number; nextPageLink?: string; current: number; total: number; timestamp: number; timeTaken: number; }; count: number; torrents: (AdditionalDetails extends (DetailsOptions | boolean) ? TorrentDataWithDetails<AdditionalDetails> : TorrentData)[]; }; export type MapDetailsOptions<AdditionalDetails extends (DetailsOptions | boolean)> = { type: DataTypes.Details; } & (AdditionalDetails extends true ? DetailsEntity : AdditionalDetails extends DetailsOptions ? ConditionalField<DetailsEntity, "description", AdditionalDetails["description"]> & ConditionalField<DetailsEntity, "submitter", AdditionalDetails["submitter"]> & ConditionalField<DetailsEntity, "information", AdditionalDetails["information"]> & ConditionalField<DetailsEntity, "files", AdditionalDetails["files"]> & ConditionalField<DetailsEntity, "comments", AdditionalDetails["comments"]> & ConditionalField<DetailsEntity, "description", AdditionalDetails["description"]> : undefined); export type MethodOptions<RunTime extends RunTimes, AdditionalDetails extends (DetailsOptions | boolean)> = { job: Job<RunTime>; url: string; loadAdditionalInfo: AdditionalDetails; }; export type NestedKeys<T> = T extends readonly unknown[] ? T[number] & string : T extends Record<string, unknown> ? { [K in keyof T]: `${K & string}` | `${K & string}.${NestedKeys<T[K]>}`; }[keyof T] : never; export type OptionalField<T, K extends keyof T> = { [P in K]?: T[P]; }; export type RunTimeAPI<RunTime extends RunTimes> = RunTime extends RunTimes.Puppeteer ? Page : AxiosInstance; export type ScraperProps<AdditionalDetails extends (DetailsOptions | boolean)> = { /** * How many pages will be loaded for web scraping, each page has 75 torrents * * @default 1 */ pagesToLoad?: number; /** * This carries additional information such as: * description, submitter, information, files, comments * * But it results in 75 requests per page, so I don't recommend using it! * @default false */ loadAdditionalInfo: AdditionalDetails | DetailsOptions; }; export type SessionOptions = { /** * @link https://www.npmjs.com/package/user-agents */ userAgentOptions?: Partial<UserAgent["data"]>; /** * If not defined, it will generate a userAgent on every call (recommended) */ defaultUserAgent?: string; }; export type Submitter = { name: string; url: string; }; export type TorrentData = { id: number; hash: string; name: string; timestamp: number; size: string; category: string; links: { page: string; magnet: string; torrent: string; }; stats: { seeders: number; leechers: number; downloaded: number; }; }; export type TorrentDataWithDetails<AdditionalDetails extends (DetailsOptions | boolean)> = { details: MapDetailsOptions<AdditionalDetails>; } & TorrentData; type Comment$1 = { userName: string; avatarURL: string; timestamp: number; publishDate: string; message: string; isUploader: boolean; }; export { Comment$1 as Comment, }; export {};