refactor: Classes for Plugins (#631)

* set target to ES5

* refactor types

* use .gitkeep

* use dot to make dist/js dirs on top

* add hako

* add Hako

* add madara

* fix: url path js -> .js

* fix: branch

* freestyle for using UA, cookie

* add parseNovels for Hako

* update readme

* fix: conflict types

* add Kolnovel, remove node-fetch

* add bestlightnovel

* add plugins

* WQMangaStreamScraper
* PandaMTL
* NobleMTL
* LightNovelBrasil
* WPMangaStream

* add filters for popularNovels

* fix undefined json

* Linovelib (#26)

* linovelib CN

* icon for linovelib

* fix undefined chapter

* add check

* fix: add artist

* TuNovelaLigera ES + Madara Fix (#28)

* app repo test

* POST is now working

* update madara template + run generator

* template fix didnt get pushed commited idk why

* template update POST

* generated

* fix: useNewChapterEndpoint update (#29)

* useNewChapterEndpoint update

* Update Selectors

---------

Co-authored-by: K1ngfish3r <trulyihu@gmail.com>
This commit is contained in:
nyagami
2023-11-04 17:15:49 +07:00
committed by GitHub
parent 538841ddee
commit 20efcf404c
295 changed files with 67636 additions and 57286 deletions
+44 -48
View File
@@ -1,46 +1,32 @@
import { Filter } from "@libs/filterInputs";
import { languages } from "@libs/languages";
import { NodeFetchParams } from "@libs/nodeFetch";
export namespace Chapter {
export interface Item {
export namespace Plugin {
export interface ChapterItem {
name: string;
url: string;
releaseTime?: string | null;
}
export interface instance {
sourceId: number;
novelUrl: string;
chapterUrl: string;
name?: string;
chapterText?: string;
}
}
export namespace Novel {
export interface Item {
export interface NovelItem {
name: string;
url: string;
cover?: string;
}
export interface instance {
export interface SourceNovel {
url: string;
name?: string;
cover?: string;
genres?: string;
summary?: string;
author?: string;
artist?: string;
status?: string;
chapters?: Chapter.Item[];
chapters?: ChapterItem[];
}
}
export namespace Plugin {
export interface Options {
export interface PopularNovelsOptions {
showLatestNovels?: boolean;
filters?: Record<string, string | string[]>;
}
export interface Info {
export interface PluginItem {
id: string;
name: string;
lang: (typeof languages)[keyof typeof languages];
@@ -48,43 +34,51 @@ export namespace Plugin {
requirePath: string;
icon: string;
}
export interface instance {
id: string;
name: string;
version: string;
export interface PluginBase {
id: string,
name: string,
/**
* Relative path without icon. E.g:
* ```js
* "src/vi/hakolightnovel/icon.png"
* ```
*/
icon: string;
site: string;
popularNovels: popularNovels;
parseNovelAndChapters: parseNovelAndChapters;
parseChapter: parseChapter;
searchNovels: searchNovels;
fetchImage: fetchImage;
filters?: Filter[];
version: string;
userAgent: string;
cookieString: string;
popularNovels(pageNo: number, options: PopularNovelsOptions): Promise<NovelItem[]>;
parseNovelAndChapters(novelUrl: string): Promise<SourceNovel>;
parseChapter(chapterUrl: string): Promise<string>;
searchNovels(searchTerm: string, pageNo?: number): Promise<NovelItem[]>;
/**
*
* @param url Image url
* @returns {string} Base64 of image
* @example
* ```ts
* const headers = {
* Referer: "https://ln.hako.vn",
* };
* return await fetchFile(url, { headers: headers });
* ```
*/
fetchImage(url: string): Promise<string | undefined>;
}
export type popularNovels = (
page: number,
options: Plugin.Options
) => Promise<PopularNovelsResponse>;
export type PopularNovelsResponse = Novel.Item[];
export type parseNovelAndChapters = (
novelUrl: string
) => Promise<Novel.instance>;
export type parseChapter = (chapterUrl: string) => Promise<string | null>;
export type searchNovels = (searchTerm: string) => Promise<Novel.Item[]>;
export type fetchImage = (
...params: NodeFetchParams
) => Promise<string | undefined>;
}
export const isPlugin = (p: any): p is Plugin.instance => {
const pl = p as Plugin.instance;
export const isPlugin = (p: any): p is Plugin.PluginBase => {
const pl = p as Plugin.PluginBase;
const errorOut = (key: string) => {
console.error(`Plugin ${pl.name} doesn't have ${key}!`);
return false;
};
const required_funcs: (keyof Plugin.instance)[] = [
const required_funcs: (keyof Plugin.PluginBase)[] = [
"popularNovels",
"parseNovelAndChapters",
"parseChapter",
@@ -95,12 +89,14 @@ export const isPlugin = (p: any): p is Plugin.instance => {
const key = required_funcs[i];
if (!pl[key] || typeof pl[key] !== "function") return errorOut(key);
}
const requireds_fields: (keyof Plugin.instance)[] = [
const requireds_fields: (keyof Plugin.PluginBase)[] = [
"id",
"name",
"version",
"icon",
"site",
"userAgent",
"cookieString",
];
for (let i = 0; i < requireds_fields.length; i++) {
const key = requireds_fields[i];
+1 -1
View File
@@ -1,5 +1,5 @@
import { Plugin } from "@typings/plugin";
export type PluginList = {
[key: string]: Plugin.Info[];
[key: string]: Plugin.PluginItem[];
};