Build ts type definitions

pull/81/head
MillenniumEarl 2021-03-05 12:27:36 +01:00
parent 20b4802dc1
commit c53f084758
33 changed files with 1660 additions and 0 deletions

84
index.d.ts vendored Normal file
View File

@ -0,0 +1,84 @@
import { IBasic } from "./scripts/interfaces.js";
import LoginResult from "./scripts/classes/login-result.js";
import UserProfile from "./scripts/classes/mapping/user-profile.js";
import LatestSearchQuery from "./scripts/classes/query/latest-search-query.js";
import HandiworkSearchQuery from "./scripts/classes/query/handiwork-search-query.js";
import HandiWork from "./scripts/classes/handiwork/handiwork.js";
export { default as Animation } from "./scripts/classes/handiwork/animation.js";
export { default as Asset } from "./scripts/classes/handiwork/asset.js";
export { default as Comic } from "./scripts/classes/handiwork/comic.js";
export { default as Game } from "./scripts/classes/handiwork/game.js";
export { default as Handiwork } from "./scripts/classes/handiwork/handiwork.js";
export { default as PlatformUser } from "./scripts/classes/mapping/platform-user.js";
export { default as Post } from "./scripts/classes/mapping/post.js";
export { default as Thread } from "./scripts/classes/mapping/thread.js";
export { default as UserProfile } from "./scripts/classes/mapping/user-profile.js";
export { default as HandiworkSearchQuery } from "./scripts/classes/query/handiwork-search-query.js";
export { default as LatestSearchQuery } from "./scripts/classes/query/latest-search-query.js";
export { default as ThreadSearchQuery } from "./scripts/classes/query/thread-search-query.js";
/**
* Set the logger level for module debugging.
*/
export declare let loggerLevel: string;
/**
* Indicates whether a user is logged in to the F95Zone platform or not.
*/
export declare function isLogged(): boolean;
/**
* Log in to the F95Zone platform.
*
* This **must** be the first operation performed before accessing any other script functions.
*
* @param cb2fa
* Callback used if two-factor authentication is required for the profile.
* It must return he OTP code to use for the login.
*/
export declare function login(
username: string,
password: string,
cb2fa?: () => Promise<number>
): Promise<LoginResult>;
/**
* Chek if exists a new version of the handiwork.
*
* You **must** be logged in to the portal before calling this method.
*/
export declare function checkIfHandiworkHasUpdate(hw: HandiWork): Promise<boolean>;
/**
* Search for one or more handiworks identified by a specific query.
*
* You **must** be logged in to the portal before calling this method.
*
* @param {HandiworkSearchQuery} query Parameters used for the search.
* @param {Number} limit Maximum number of results. Default: 10
*/
export declare function searchHandiwork<T extends IBasic>(
query: HandiworkSearchQuery,
limit?: number
): Promise<T[]>;
/**
* Given the url, it gets all the information about the handiwork requested.
*
* You **must** be logged in to the portal before calling this method.
*/
export declare function getHandiworkFromURL<T extends IBasic>(url: string): Promise<T>;
/**
* Gets the data of the currently logged in user.
*
* You **must** be logged in to the portal before calling this method.
*
* @returns {Promise<UserProfile>} Data of the user currently logged in
*/
export declare function getUserData(): Promise<UserProfile>;
/**
* Gets the latest updated games that match the specified parameters.
*
* You **must** be logged in to the portal before calling this method.
*
* @param {LatestSearchQuery} query Parameters used for the search.
* @param {Number} limit Maximum number of results. Default: 10
*/
export declare function getLatestUpdates<T extends IBasic>(
query: LatestSearchQuery,
limit?: number
): Promise<T[]>;

22
scripts/classes/credentials.d.ts vendored Normal file
View File

@ -0,0 +1,22 @@
/**
* Represents the credentials used to access the platform.
*/
export default class Credentials {
/**
* Username
*/
username: string;
/**
* Password of the user.
*/
password: string;
/**
* One time token used during login.
*/
token: string;
constructor(username: string, password: string);
/**
* Fetch and save the token used to log in to F95Zone.
*/
fetchToken(): Promise<void>;
}

30
scripts/classes/errors.d.ts vendored Normal file
View File

@ -0,0 +1,30 @@
interface IBaseError {
/**
* Unique identifier of the error.
*/
id: number;
/**
* Error message.
*/
message: string;
/**
* Error to report.
*/
error: Error;
}
export declare class GenericAxiosError extends Error implements IBaseError {
id: number;
message: string;
error: Error;
constructor(args: IBaseError);
}
export declare class UnexpectedResponseContentType extends Error implements IBaseError {
id: number;
message: string;
error: Error;
constructor(args: IBaseError);
}
export declare class InvalidF95Token extends Error {}
export declare class UserNotLogged extends Error {}
export declare class ParameterError extends Error {}
export {};

View File

@ -0,0 +1,23 @@
import { TAuthor, IAnimation, TRating, TCategory } from "../../interfaces";
export default class Animation implements IAnimation {
censored: boolean;
genre: string[];
installation: string;
language: string[];
lenght: string;
pages: string;
resolution: string[];
authors: TAuthor[];
category: TCategory;
changelog: string[];
cover: string;
id: number;
lastThreadUpdate: Date;
name: string;
overview: string;
prefixes: string[];
rating: TRating;
tags: string[];
threadPublishingDate: Date;
url: string;
}

22
scripts/classes/handiwork/asset.d.ts vendored Normal file
View File

@ -0,0 +1,22 @@
import { TAuthor, IAsset, TRating, TCategory } from "../../interfaces";
export default class Asset implements IAsset {
assetLink: string;
associatedAssets: string[];
compatibleSoftware: string;
includedAssets: string[];
officialLinks: string[];
sku: string;
authors: TAuthor[];
category: TCategory;
changelog: string[];
cover: string;
id: number;
lastThreadUpdate: Date;
name: string;
overview: string;
prefixes: string[];
rating: TRating;
tags: string[];
threadPublishingDate: Date;
url: string;
}

19
scripts/classes/handiwork/comic.d.ts vendored Normal file
View File

@ -0,0 +1,19 @@
import { TAuthor, IComic, TRating, TCategory } from "../../interfaces";
export default class Comic implements IComic {
genre: string[];
pages: string;
resolution: string[];
authors: TAuthor[];
category: TCategory;
changelog: string[];
cover: string;
id: number;
lastThreadUpdate: Date;
name: string;
overview: string;
prefixes: string[];
rating: TRating;
tags: string[];
threadPublishingDate: Date;
url: string;
}

26
scripts/classes/handiwork/game.d.ts vendored Normal file
View File

@ -0,0 +1,26 @@
import { TAuthor, TEngine, IGame, TRating, TStatus, TCategory } from "../../interfaces";
export default class Game implements IGame {
censored: boolean;
engine: TEngine;
genre: string[];
installation: string;
language: string[];
lastRelease: Date;
mod: boolean;
os: string[];
status: TStatus;
version: string;
authors: TAuthor[];
category: TCategory;
changelog: string[];
cover: string;
id: number;
lastThreadUpdate: Date;
name: string;
overview: string;
prefixes: string[];
rating: TRating;
tags: string[];
threadPublishingDate: Date;
url: string;
}

View File

@ -0,0 +1,45 @@
import {
TAuthor,
TRating,
IHandiwork,
TEngine,
TCategory,
TStatus
} from "../../interfaces";
/**
* It represents a generic work, be it a game, a comic, an animation or an asset.
*/
export default class HandiWork implements IHandiwork {
censored: boolean;
engine: TEngine;
genre: string[];
installation: string;
language: string[];
lastRelease: Date;
mod: boolean;
os: string[];
status: TStatus;
version: string;
authors: TAuthor[];
category: TCategory;
changelog: string[];
cover: string;
id: number;
lastThreadUpdate: Date;
name: string;
overview: string;
prefixes: string[];
rating: TRating;
tags: string[];
threadPublishingDate: Date;
url: string;
pages: string;
resolution: string[];
lenght: string;
assetLink: string;
associatedAssets: string[];
compatibleSoftware: string;
includedAssets: string[];
officialLinks: string[];
sku: string;
}

25
scripts/classes/login-result.d.ts vendored Normal file
View File

@ -0,0 +1,25 @@
/**
* Object obtained in response to an attempt to login to the portal.
*/
export default class LoginResult {
static REQUIRE_2FA: number;
static AUTH_SUCCESSFUL: number;
static AUTH_SUCCESSFUL_2FA: number;
static ALREADY_AUTHENTICATED: number;
static UNKNOWN_ERROR: number;
static INCORRECT_CREDENTIALS: number;
static INCORRECT_2FA_CODE: number;
/**
* Result of the login operation
*/
readonly success: boolean;
/**
* Code associated with the result of the login operation.
*/
readonly code: number;
/**
* Login response message
*/
readonly message: string;
constructor(success: boolean, code: number, message?: string);
}

View File

@ -0,0 +1,83 @@
/**
* Represents a generic user registered on the platform.
*/
export default class PlatformUser {
private _id;
private _name;
private _title;
private _banners;
private _messages;
private _reactionScore;
private _points;
private _ratingsReceived;
private _joined;
private _lastSeen;
private _followed;
private _ignored;
private _private;
private _avatar;
private _amountDonated;
/**
* Unique user ID.
*/
get id(): number;
/**
* Username.
*/
get name(): string;
/**
* Title assigned to the user by the platform.
*/
get title(): string;
/**
* List of banners assigned by the platform.
*/
get banners(): string[];
/**
* Number of messages written by the user.
*/
get messages(): number;
/**
* @todo Reaction score.
*/
get reactionScore(): number;
/**
* @todo Points.
*/
get points(): number;
/**
* Number of ratings received.
*/
get ratingsReceived(): number;
/**
* Date of joining the platform.
*/
get joined(): Date;
/**
* Date of the last connection to the platform.
*/
get lastSeen(): Date;
/**
* Indicates whether the user is followed by the currently logged in user.
*/
get followed(): boolean;
/**
* Indicates whether the user is ignored by the currently logged on user.
*/
get ignored(): boolean;
/**
* Indicates that the profile is private and not viewable by the user.
*/
get private(): boolean;
/**
* URL of the image used as the user's avatar.
*/
get avatar(): string;
/**
* Value of donations made.
*/
get donation(): number;
constructor(id?: number);
setID(id: number): void;
fetch(): Promise<void>;
}

53
scripts/classes/mapping/post.d.ts vendored Normal file
View File

@ -0,0 +1,53 @@
import PlatformUser from "./platform-user.js";
import { IPostElement } from "../../scrape-data/post-parse.js";
/**
* Represents a post published by a user on the F95Zone platform.
*/
export default class Post {
private _id;
private _number;
private _published;
private _lastEdit;
private _owner;
private _bookmarked;
private _message;
private _body;
/**
* Represents a post published by a user on the F95Zone platform.
*/
get id(): number;
/**
* Unique ID of the post within the thread in which it is present.
*/
get number(): number;
/**
* Date the post was first published.
*/
get published(): Date;
/**
* Date the post was last modified.
*/
get lastEdit(): Date;
/**
* User who owns the post.
*/
get owner(): PlatformUser;
/**
* Indicates whether the post has been bookmarked.
*/
get bookmarked(): boolean;
/**
* Post message text.
*/
get message(): string;
/**
* Set of the elements that make up the body of the post.
*/
get body(): IPostElement[];
constructor(id: number);
/**
* Gets the post data starting from its unique ID for the entire platform.
*/
fetch(): Promise<void>;
private parsePost;
}

101
scripts/classes/mapping/thread.d.ts vendored Normal file
View File

@ -0,0 +1,101 @@
import Post from "./post.js";
import PlatformUser from "./platform-user.js";
import { TCategory, TRating } from "../../interfaces.js";
/**
* Represents a generic F95Zone platform thread.
*/
export default class Thread {
private POST_FOR_PAGE;
private _id;
private _url;
private _title;
private _tags;
private _prefixes;
private _rating;
private _owner;
private _publication;
private _modified;
private _category;
/**
* Unique ID of the thread on the platform.
*/
get id(): number;
/**
* URL of the thread.
*
* It may vary depending on any versions of the contained product.
*/
get url(): string;
/**
* Thread title.
*/
get title(): string;
/**
* Tags associated with the thread.
*/
get tags(): string[];
/**
* Prefixes associated with the thread
*/
get prefixes(): string[];
/**
* Rating assigned to the thread.
*/
get rating(): TRating;
/**
* Owner of the thread.
*/
get owner(): PlatformUser;
/**
* Date the thread was first published.
*/
get publication(): Date;
/**
* Date the thread was last modified.
*/
get modified(): Date;
/**
* Category to which the content of the thread belongs.
*/
get category(): TCategory;
/**
* Initializes an object for mapping a thread.
*
* The unique ID of the thread must be specified.
*/
constructor(id: number);
/**
* Set the number of posts to display for the current thread.
*/
private setMaximumPostsForPage;
/**
* Gets all posts on a page.
*/
private parsePostsInPage;
/**
* Gets all posts in the thread.
*/
private fetchPosts;
/**
* It processes the rating of the thread
* starting from the data contained in the JSON+LD tag.
*/
private parseRating;
/**
* Clean the title of a thread, removing prefixes
* and generic elements between square brackets, and
* returns the clean title of the work.
*/
private cleanHeadline;
/**
* Gets information about this thread.
*/
fetch(): Promise<void>;
/**
* Gets the post in the `index` position with respect to the posts in the thread.
*
* `index` must be greater or equal to 1.
* If the post is not found, `null` is returned.
*/
getPost(index: number): Promise<Post | null>;
}

View File

@ -0,0 +1,60 @@
import Post from "./post.js";
import PlatformUser from "./platform-user.js";
interface IWatchedThread {
/**
* URL of the thread
*/
url: string;
/**
* Indicates whether the thread has any unread posts.
*/
unread: boolean;
/**
* Specifies the forum to which the thread belongs.
*/
forum: string;
}
/**
* Class containing the data of the user currently connected to the F95Zone platform.
*/
export default class UserProfile extends PlatformUser {
private _watched;
private _bookmarks;
private _alerts;
private _conversations;
/**
* List of followed thread data.
*/
get watched(): IWatchedThread[];
/**
* List of bookmarked posts.
* @todo
*/
get bookmarks(): Post[];
/**
* List of alerts.
* @todo
*/
get alerts(): string[];
/**
* List of conversations.
* @todo
*/
get conversation(): string[];
constructor();
fetch(): Promise<void>;
private fetchUserID;
private fetchWatchedThread;
/**
* Gets the pages containing the thread data.
* @param url Base URL to use for scraping a page
* @param n Total number of pages
* @param s Page to start from
*/
private fetchPages;
/**
* Gets thread data starting from the source code of the page passed by parameter.
*/
private fetchPageThreadElements;
}
export {};

34
scripts/classes/prefix-parser.d.ts vendored Normal file
View File

@ -0,0 +1,34 @@
/**
* Convert prefixes and platform tags from string to ID and vice versa.
*/
export default class PrefixParser {
/**
* Gets the key associated with a given value from a dictionary.
* @param {Object} object Dictionary to search
* @param {Any} value Value associated with the key
* @returns {String|undefined} Key found or undefined
*/
private getKeyByValue;
/**
* Makes an array of strings uppercase.
*/
private toUpperCaseArray;
/**
* Check if `dict` contains `value` as a value.
*/
private valueInDict;
/**
* Search within the platform prefixes for the
* desired element and return the dictionary that contains it.
* @param element Element to search in the prefixes as a key or as a value
*/
private searchElementInPrefixes;
/**
* Convert a list of prefixes to their respective IDs.
*/
prefixesToIDs(prefixes: string[]): number[];
/**
* It converts a list of IDs into their respective prefixes.
*/
idsToPrefixes(ids: number[]): string[];
}

View File

@ -0,0 +1,70 @@
import { AxiosResponse } from "axios";
import { IQuery, TCategory, TQueryInterface } from "../../interfaces.js";
import { GenericAxiosError } from "../errors.js";
import { Result } from "../result.js";
/**
* Method of sorting results. Try to unify the two types of
* sorts in the "Latest" section and in the "Thread search"
* section. Being dynamic research, if a sorting type is not
* available, the replacement sort is chosen.
*
* `date`: Order based on the latest update
*
* `likes`: Order based on the number of likes received. Replacement: `replies`.
*
* `relevance`: Order based on the relevance of the result (or rating).
*
* `replies`: Order based on the number of answers to the thread. Replacement: `views`.
*
* `title`: Order based on the growing alphabetical order of the titles.
*
* `views`: Order based on the number of visits. Replacement: `replies`.
*/
declare type THandiworkOrder =
| "date"
| "likes"
| "relevance"
| "replies"
| "title"
| "views";
declare type TExecuteResult = Result<GenericAxiosError, AxiosResponse<any>>;
export default class HandiworkSearchQuery implements IQuery {
static MIN_PAGE: number;
/**
* Keywords to use in the search.
*/
keywords: string;
/**
* The results must be more recent than the date indicated.
*/
newerThan: Date;
/**
* The results must be older than the date indicated.
*/
olderThan: Date;
includedTags: string[];
/**
* Tags to exclude from the search.
*/
excludedTags: string[];
includedPrefixes: string[];
category: TCategory;
/**
* Results presentation order.
*/
order: THandiworkOrder;
page: number;
itype: TQueryInterface;
/**
* Select what kind of search should be
* performed based on the properties of
* the query.
*/
selectSearchType(): "latest" | "thread";
validate(): boolean;
execute(): Promise<TExecuteResult>;
cast<T extends IQuery>(type: TQueryInterface): T;
private castToLatest;
private castToThread;
}
export {};

View File

@ -0,0 +1,46 @@
import { IQuery, TCategory, TQueryInterface } from "../../interfaces.js";
import { AxiosResponse } from "axios";
import { GenericAxiosError } from "../errors.js";
import { Result } from "../result.js";
export declare type TLatestOrder = "date" | "likes" | "views" | "title" | "rating";
declare type TDate = 365 | 180 | 90 | 30 | 14 | 7 | 3 | 1;
/**
* Query used to search handiwork in the "Latest" tab.
*/
export default class LatestSearchQuery implements IQuery {
private static MAX_TAGS;
private static MIN_PAGE;
category: TCategory;
/**
* Ordering type.
*
* Default: `date`.
*/
order: TLatestOrder;
/**
* Date limit in days, to be understood as "less than".
* Use `1` to indicate "today" or `null` to indicate "anytime".
*
* Default: `null`
*/
date: TDate;
includedTags: string[];
includedPrefixes: string[];
page: number;
itype: TQueryInterface;
validate(): boolean;
execute(): Promise<Result<GenericAxiosError, AxiosResponse<any>>>;
/**
* Gets the value (in days) acceptable in the query starting from a generic date.
*/
findNearestDate(d: Date): TDate;
/**
* Prepare the URL by filling out the GET parameters with the data in the query.
*/
private prepareGETurl;
/**
*
*/
private dateDiffInDays;
}
export {};

View File

@ -0,0 +1,55 @@
import { IQuery, TCategory, TQueryInterface } from "../../interfaces.js";
import { AxiosResponse } from "axios";
import { GenericAxiosError } from "../errors.js";
import { Result } from "../result.js";
export declare type TThreadOrder = "relevance" | "date" | "last_update" | "replies";
export default class ThreadSearchQuery implements IQuery {
static MIN_PAGE: number;
/**
* Keywords to use in the search.
*/
keywords: string;
/**
* Indicates to search by checking only the thread titles and not the content.
*/
onlyTitles: boolean;
/**
* The results must be more recent than the date indicated.
*/
newerThan: Date;
/**
* The results must be older than the date indicated.
*/
olderThan: Date;
includedTags: string[];
/**
* Tags to exclude from the search.
*/
excludedTags: string[];
/**
* Minimum number of answers that the thread must possess.
*/
minimumReplies: number;
includedPrefixes: string[];
category: TCategory;
/**
* Results presentation order.
*/
order: TThreadOrder;
page: number;
itype: TQueryInterface;
validate(): boolean;
execute(): Promise<Result<GenericAxiosError, AxiosResponse<any>>>;
/**
* Prepare the parameters for post request with the data in the query.
*/
private preparePOSTParameters;
/**
* Convert a date in the YYYY-MM-DD format taking into account the time zone.
*/
private convertShortDate;
/**
* Gets the unique ID of the selected category.
*/
private categoryToID;
}

17
scripts/classes/result.d.ts vendored Normal file
View File

@ -0,0 +1,17 @@
export declare type Result<L, A> = Failure<L, A> | Success<L, A>;
export declare class Failure<L, A> {
readonly value: L;
constructor(value: L);
isFailure(): this is Failure<L, A>;
isSuccess(): this is Success<L, A>;
applyOnSuccess<B>(_: (a: A) => B): Result<L, B>;
}
export declare class Success<L, A> {
readonly value: A;
constructor(value: A);
isFailure(): this is Failure<L, A>;
isSuccess(): this is Success<L, A>;
applyOnSuccess<B>(func: (a: A) => B): Result<L, B>;
}
export declare const failure: <L, A>(l: L) => Result<L, A>;
export declare const success: <L, A>(a: A) => Result<L, A>;

71
scripts/classes/session.d.ts vendored Normal file
View File

@ -0,0 +1,71 @@
import tough from "tough-cookie";
export default class Session {
/**
* Max number of days the session is valid.
*/
private readonly SESSION_TIME;
private readonly COOKIEJAR_FILENAME;
private _path;
private _isMapped;
private _created;
private _hash;
private _token;
private _cookieJar;
private _cookieJarPath;
/**
* Path of the session map file on disk.
*/
get path(): string;
/**
* Indicates if the session is mapped on disk.
*/
get isMapped(): boolean;
/**
* Date of creation of the session.
*/
get created(): Date;
/**
* MD5 hash of the username and the password.
*/
get hash(): string;
/**
* Token used to login to F95Zone.
*/
get token(): string;
/**
* Cookie holder.
*/
get cookieJar(): tough.CookieJar;
/**
* Initializes the session by setting the path for saving information to disk.
*/
constructor(p: string);
/**
* Get the difference in days between two dates.
*/
private dateDiffInDays;
/**
* Convert the object to a dictionary serializable in JSON.
*/
private toJSON;
/**
* Create a new session.
*/
create(username: string, password: string, token: string): void;
/**
* Save the session to disk.
*/
save(): Promise<void>;
/**
* Load the session from disk.
*/
load(): Promise<void>;
/**
* Delete the session from disk.
*/
delete(): Promise<void>;
/**
* Check if the session is valid.
*/
isValid(username: string, password: string): boolean;
}

203
scripts/constants/css-selector.d.ts vendored Normal file
View File

@ -0,0 +1,203 @@
export declare const selectors: {
WT_FILTER_POPUP_BUTTON: string;
WT_NEXT_PAGE: string;
WT_URLS: string;
WT_UNREAD_THREAD_CHECKBOX: string;
GS_POSTS: string;
GS_RESULT_THREAD_TITLE: string;
GS_RESULT_BODY: string;
GS_MEMBERSHIP: string;
GET_REQUEST_TOKEN: string;
UD_USERNAME_ELEMENT: string;
UD_AVATAR_PIC: string;
LOGIN_MESSAGE_ERROR: string;
LU_TAGS_SCRIPT: string;
BK_RESULTS: string;
BK_POST_URL: string;
BK_DESCRIPTION: string;
BK_POST_OWNER: string;
BK_TAGS: string;
/**
* Attribute `datetime` contains an ISO date.
*/
BK_TIME: string;
};
export declare const GENERIC: {
/**
* The ID of the user currently logged into
* the platform in the attribute `data-user-id`.
*/
CURRENT_USER_ID: string;
/**
* Banner containing any error messages as text.
*/
ERROR_BANNER: string;
};
export declare const WATCHED_THREAD: {
/**
* List of elements containing the data of the watched threads.
*/
BODIES: string;
/**
* Link element containing the partial URL
* of the thread in the `href` attribute.
*
* It may be followed by the `/unread` segment.
*
* For use within a `WATCHED_THREAD.BODIES` selector.
*/
URL: string;
/**
* Name of the forum to which the thread belongs as text.
*
* For use within a `WATCHED_THREAD.BODIES` selector.
*/
FORUM: string;
/**
* Index of the last page available as text.
*/
LAST_PAGE: string;
};
export declare const THREAD: {
/**
* Number of pages in the thread (as text of the element).
*
* Two identical elements are identified.
*/
LAST_PAGE: string;
/**
* Identify the creator of the thread.
*
* The ID is contained in the `data-user-id` attribute.
*/
OWNER_ID: string;
/**
* Contains the creation date of the thread.
*
* The date is contained in the `datetime` attribute as an ISO string.
*/
CREATION: string;
/**
* List of tags assigned to the thread.
*/
TAGS: string;
/**
* List of prefixes assigned to the thread.
*/
PREFIXES: string;
/**
* Thread title.
*/
TITLE: string;
/**
* JSON containing thread information.
*
* Two different elements are found.
*/
JSONLD: string;
/**
* Posts on the current page.
*/
POSTS_IN_PAGE: string;
};
export declare const POST: {
/**
* Unique post number for the current thread.
*
* For use within a `THREAD.POSTS_IN_PAGE` selector.
*/
NUMBER: string;
/**
* Unique ID of the post in the F95Zone platform in the `id` attribute.
*
* For use within a `THREAD.POSTS_IN_PAGE` selector.
*/
ID: string;
/**
* Unique ID of the post author in the `data-user-id` attribute.
*
* For use within a `THREAD.POSTS_IN_PAGE` selector.
*/
OWNER_ID: string;
/**
* Main body of the post where the message written by the user is contained.
*
* For use within a `THREAD.POSTS_IN_PAGE` selector.
*/
BODY: string;
/**
* Publication date of the post contained in the `datetime` attribute as an ISO date.
*
* For use within a `THREAD.POSTS_IN_PAGE` selector.
*/
PUBLISH_DATE: string;
/**
* Last modified date of the post contained in the `datetime` attribute as the ISO date.
*
* For use within a `THREAD.POSTS_IN_PAGE` selector.
*/
LAST_EDIT: string;
/**
* Gets the element only if the post has been bookmarked.
*
* For use within a `THREAD.POSTS_IN_PAGE` selector.
*/
BOOKMARKED: string;
};
export declare const MEMBER: {
/**
* Name of the user.
*
* It also contains the unique ID of the user in the `data-user-id` attribute.
*/
NAME: string;
/**
* Title of the user in the platform.
*
* i.e.: Member
*/
TITLE: string;
/**
* Avatar used by the user.
*
* Source in the attribute `src`.
*/
AVATAR: string;
/**
* User assigned banners.
*
* The last element is always empty and can be ignored.
*/
BANNERS: string;
/**
* Date the user joined the platform.
*
* The date is contained in the `datetime` attribute as an ISO string.
*/
JOINED: string;
/**
* Last time the user connected to the platform.
*
* The date is contained in the `datetime` attribute as an ISO string.
*/
LAST_SEEN: string;
MESSAGES: string;
REACTION_SCORE: string;
POINTS: string;
RATINGS_RECEIVED: string;
AMOUNT_DONATED: string;
/**
* Button used to follow/unfollow the user.
*
* If the text is `Unfollow` then the user is followed.
* If the text is `Follow` then the user is not followed.
*/
FOLLOWED: string;
/**
* Button used to ignore/unignore the user.
*
* If the text is `Unignore` then the user is ignored.
* If the text is `Ignore` then the user is not ignored.
*/
IGNORED: string;
};

27
scripts/constants/url.d.ts vendored Normal file
View File

@ -0,0 +1,27 @@
export declare const urls: {
F95_BASE_URL: string;
F95_2FA_LOGIN: string;
F95_SEARCH_URL: string;
F95_LATEST_UPDATES: string;
F95_THREADS: string;
F95_LOGIN_URL: string;
F95_WATCHED_THREADS: string;
F95_LATEST_PHP: string;
F95_BOOKMARKS: string;
/**
* Add the unique ID of the post to
* get the thread page where the post
* is present.
*/
F95_POSTS: string;
/**
* @todo
*/
F95_CONVERSATIONS: string;
/**
* @todo
*/
F95_ALERTS: string;
F95_POSTS_NUMBER: string;
F95_MEMBERS: string;
};

14
scripts/fetch-data/fetch-handiwork.d.ts vendored Normal file
View File

@ -0,0 +1,14 @@
import HandiworkSearchQuery from "../classes/query/handiwork-search-query";
/**
* Gets the URLs of the handiworks that match the passed parameters.
* You *must* be logged.
* @param {LatestSearchQuery} query
* Query used for the search
* @param {Number} limit
* Maximum number of items to get. Default: 30
* @returns {Promise<String[]>} URLs of the handiworks
*/
export default function fetchHandiworkURLs(
query: HandiworkSearchQuery,
limit?: number
): Promise<string[]>;

15
scripts/fetch-data/fetch-latest.d.ts vendored Normal file
View File

@ -0,0 +1,15 @@
import LatestSearchQuery from "../classes/query/latest-search-query.js";
/**
* Gets the URLs of the latest handiworks that match the passed parameters.
*
* You *must* be logged.
* @param {LatestSearchQuery} query
* Query used for the search
* @param {Number} limit
* Maximum number of items to get. Default: 30
* @returns {Promise<String[]>} URLs of the handiworks
*/
export default function fetchLatestHandiworkURLs(
query: LatestSearchQuery,
limit?: number
): Promise<string[]>;

View File

@ -0,0 +1,5 @@
/**
* Gets the basic data used for game data processing
* (such as graphics engines and progress statuses)
*/
export default function fetchPlatformData(): Promise<void>;

10
scripts/fetch-data/fetch-query.d.ts vendored Normal file
View File

@ -0,0 +1,10 @@
import { IQuery } from "../interfaces.js";
/**
* @param query Query used for the search
* @param limit Maximum number of items to get. Default: 30
* @returns URLs of the fetched games
*/
export default function getURLsFromQuery(
query: IQuery,
limit?: number
): Promise<string[]>;

15
scripts/fetch-data/fetch-thread.d.ts vendored Normal file
View File

@ -0,0 +1,15 @@
import ThreadSearchQuery from "../classes/query/thread-search-query.js";
/**
* Gets the URLs of the handiwork' threads that match the passed parameters.
*
* You *must* be logged.
* @param {ThreadSearchQuery} query
* Query used for the search
* @param {number} limit
* Maximum number of items to get. Default: 30
* @returns {Promise<String[]>} URLs of the handiworks
*/
export default function fetchThreadHandiworkURLs(
query: ThreadSearchQuery,
limit?: number
): Promise<string[]>;

300
scripts/interfaces.d.ts vendored Normal file
View File

@ -0,0 +1,300 @@
/**
* Data relating to an external platform (i.e. Patreon).
*/
export declare type TExternalPlatform = {
/**
* name of the platform.
*/
name: string;
/**
* link to the platform.
*/
link: string;
};
/**
* Information about the author of a work.
*/
export declare type TAuthor = {
/**
* Plain name or username of the author.
*/
name: string;
/**
*
*/
platforms: TExternalPlatform[];
};
/**
* Information on the evaluation of a work.
*/
export declare type TRating = {
/**
* average value of evaluations.
*/
average: number;
/**
* Best rating received.
*/
best: number;
/**
* Number of ratings made by users.
*/
count: number;
};
/**
* List of possible graphics engines used for game development.
*/
export declare type TEngine =
| "QSP"
| "RPGM"
| "Unity"
| "HTML"
| "RAGS"
| "Java"
| "Ren'Py"
| "Flash"
| "ADRIFT"
| "Others"
| "Tads"
| "Wolf RPG"
| "Unreal Engine"
| "WebGL";
/**
* List of possible progress states associated with a game.
*/
export declare type TStatus = "Completed" | "Ongoing" | "Abandoned" | "Onhold";
/**
* List of possible categories of a particular work.
*/
export declare type TCategory = "games" | "mods" | "comics" | "animations" | "assets";
/**
* Valid names of classes that implement the IQuery interface.
*/
export declare type TQueryInterface =
| "LatestSearchQuery"
| "ThreadSearchQuery"
| "HandiworkSearchQuery";
/**
* Collection of values defined for each
* handiwork on the F95Zone platform.
*/
export interface IBasic {
/**
* Authors of the work.
*/
authors: TAuthor[];
/**
* Category of the work..
*/
category: TCategory;
/**
* List of changes of the work for each version.
*/
changelog: string[];
/**
* link to the cover image of the work.
*/
cover: string;
/**
* Unique ID of the work on the platform.
*/
id: number;
/**
* Last update of the opera thread.
*/
lastThreadUpdate: Date;
/**
* Plain name of the work (without tags and/or prefixes)
*/
name: string;
/**
* Work description
*/
overview: string;
/**
* List of prefixes associated with the work.
*/
prefixes: string[];
/**
* Evaluation of the work by the users of the platform.
*/
rating: TRating;
/**
* List of tags associated with the work.
*/
tags: string[];
/**
* Date of publication of the thread associated with the work.
*/
threadPublishingDate: Date;
/**
* URL to the work's official conversation on the F95Zone portal.
*/
url: string;
}
/**
* Collection of values representing a game present on the F95Zone platform.
*/
export interface IGame extends IBasic {
/**
* Specify whether the work has censorship
* measures regarding NSFW scenes
*/
censored: boolean;
/**
* Graphics engine used for game development.
*/
engine: TEngine;
/**
* List of genres associated with the work.
*/
genre: string[];
/**
* Author's Guide to Installation.
*/
installation: string;
/**
* List of available languages.
*/
language: string[];
/**
* Last time the work underwent updates.
*/
lastRelease: Date;
/**
* Indicates that this item represents a mod.
*/
mod: boolean;
/**
* List of OS for which the work is compatible.
*/
os: string[];
/**
* Indicates the progress of a game.
*/
status: TStatus;
/**
* Version of the work.
*/
version: string;
}
/**
* Collection of values representing a comic present on the F95Zone platform.
*/
export interface IComic extends IBasic {
/**
* List of genres associated with the work.
*/
genre: string[];
/**
* Number of pages or elements that make up the work.
*/
pages: string;
/**
* List of resolutions available for the work.
*/
resolution: string[];
}
/**
* Collection of values representing an animation present on the F95Zone platform.
*/
export interface IAnimation extends IBasic {
/**
* Specify whether the work has censorship
* measures regarding NSFW scenes
*/
censored: boolean;
/**
* List of genres associated with the work.
*/
genre: string[];
/**
* Author's Guide to Installation.
*/
installation: string;
/**
* List of available languages.
*/
language: string[];
/**
* Length of the animation.
*/
lenght: string;
/**
* Number of pages or elements that make up the work.
*/
pages: string;
/**
* List of resolutions available for the work.
*/
resolution: string[];
}
/**
* Collection of values representing an asset present on the F95Zone platform.
*/
export interface IAsset extends IBasic {
/**
* External URL of the asset.
*/
assetLink: string;
/**
* List of URLs of assets associated with the work
* (for example same collection).
*/
associatedAssets: string[];
/**
* Software compatible with the work.
*/
compatibleSoftware: string;
/**
* List of assets url included in the work or used to develop it.
*/
includedAssets: string[];
/**
* List of official links of the work, external to the platform.
*/
officialLinks: string[];
/**
* Unique SKU value of the work.
*/
sku: string;
}
/**
* Collection of values extrapolated from the
* F95 platform representing a particular work.
*/
export interface IHandiwork extends IGame, IComic, IAnimation, IAsset {}
export interface IQuery {
/**
* Name of the implemented interface.
*/
itype: TQueryInterface;
/**
* Category of items to search among.
*/
category: TCategory;
/**
* Tags to be include in the search.
* Max. 5 tags
*/
includedTags: string[];
/**
* Prefixes to include in the search.
*/
includedPrefixes: string[];
/**
* Index of the page to be obtained.
* Between 1 and infinity.
*/
page: number;
/**
* Verify that the query values are valid.
*/
validate(): boolean;
/**
* Search with the data in the query and returns the result.
*
* If the query is invalid it throws an exception.
*/
execute(): any;
}

85
scripts/network-helper.d.ts vendored Normal file
View File

@ -0,0 +1,85 @@
import { AxiosResponse } from "axios";
import LoginResult from "./classes/login-result.js";
import { Result } from "./classes/result.js";
import { GenericAxiosError, UnexpectedResponseContentType } from "./classes/errors.js";
import Credentials from "./classes/credentials.js";
/**
* Gets the HTML code of a page.
*/
export declare function fetchHTML(
url: string
): Promise<Result<GenericAxiosError | UnexpectedResponseContentType, string>>;
/**
* It authenticates to the platform using the credentials
* and token obtained previously. Save cookies on your
* device after authentication.
* @param {Credentials} credentials Platform access credentials
* @param {Boolean} force Specifies whether the request should be forced, ignoring any saved cookies
* @returns {Promise<LoginResult>} Result of the operation
*/
export declare function authenticate(
credentials: Credentials,
force?: boolean
): Promise<LoginResult>;
/**
* Send an OTP code if the login procedure requires it.
* @param code OTP code.
* @param token Unique token for the session associated with the credentials in use.
* @param trustedDevice If the device in use is trusted, 2FA authentication is not required for 30 days.
*/
export declare function send2faCode(
code: number,
token: string,
trustedDevice?: boolean
): Promise<Result<GenericAxiosError, LoginResult>>;
/**
* Obtain the token used to authenticate the user to the platform.
*/
export declare function getF95Token(): Promise<string>;
/**
* Performs a GET request to a specific URL and returns the response.
*/
export declare function fetchGETResponse(
url: string
): Promise<Result<GenericAxiosError, AxiosResponse<any>>>;
/**
* Performs a POST request through axios.
* @param url URL to request
* @param params List of value pairs to send with the request
* @param force If `true`, the request ignores the sending of cookies already present on the device.
*/
export declare function fetchPOSTResponse(
url: string,
params: {
[s: string]: string;
},
force?: boolean
): Promise<Result<GenericAxiosError, AxiosResponse<any>>>;
/**
* Enforces the scheme of the URL is https and returns the new URL.
*/
export declare function enforceHttpsUrl(url: string): string;
/**
* Check if the url belongs to the domain of the F95 platform.
*/
export declare function isF95URL(url: string): boolean;
/**
* Checks if the string passed by parameter has a
* properly formatted and valid path to a URL (HTTP/HTTPS).
*/
export declare function isStringAValidURL(url: string): boolean;
/**
* Check if a particular URL is valid and reachable on the web.
* @param {string} url URL to check
* @param {boolean} [checkRedirect]
* If true, the function will consider redirects a violation and return false.
* Default: false
* @returns {Promise<Boolean>} true if the URL exists, false otherwise
*/
export declare function urlExists(url: string, checkRedirect?: boolean): Promise<boolean>;
/**
* Check if the URL has a redirect to another page.
* @param {String} url URL to check for redirect
* @returns {Promise<String>} Redirect URL or the passed URL
*/
export declare function getUrlRedirect(url: string): Promise<string>;

View File

@ -0,0 +1,18 @@
import Thread from "../classes/mapping/thread.js";
import { IBasic } from "../interfaces.js";
export declare function getHandiworkInformation<T extends IBasic>(
url: string
): Promise<T>;
export declare function getHandiworkInformation<T extends IBasic>(
url: string
): Promise<T>;
/**
* Gets information of a particular handiwork from its thread.
*
* If you don't want to specify the object type, use `HandiWork`.
*
* @todo It does not currently support assets.
*/
export default function getHandiworkInformation<T extends IBasic>(
arg: string | Thread
): Promise<T>;

13
scripts/scrape-data/json-ld.d.ts vendored Normal file
View File

@ -0,0 +1,13 @@
/// <reference types="cheerio" />
/**
* Represents information contained in a JSON+LD tag.
*/
export declare type TJsonLD = {
[s: string]: string | TJsonLD;
};
/**
* Extracts and processes the JSON-LD values of the page.
* @param {cheerio.Cheerio} body Page `body` selector
* @returns {TJsonLD[]} List of data obtained from the page
*/
export declare function getJSONLD(body: cheerio.Cheerio): TJsonLD;

18
scripts/scrape-data/post-parse.d.ts vendored Normal file
View File

@ -0,0 +1,18 @@
/// <reference types="cheerio" />
export interface IPostElement {
type: "Empty" | "Text" | "Link" | "Image" | "Spoiler";
name: string;
text: string;
content: IPostElement[];
}
export interface ILink extends IPostElement {
type: "Image" | "Link";
href: string;
}
/**
* Given a post of a thread page it extracts the information contained in the body.
*/
export declare function parseF95ThreadPost(
$: cheerio.Root,
post: cheerio.Cheerio
): IPostElement[];

11
scripts/search.d.ts vendored Normal file
View File

@ -0,0 +1,11 @@
import { IBasic, IQuery } from "./interfaces.js";
/**
* Gets the handiworks that match the passed parameters.
* You *must* be logged.
* @param {Number} limit
* Maximum number of items to get. Default: 30
*/
export default function search<T extends IBasic>(
query: IQuery,
limit?: number
): Promise<T[]>;

40
scripts/shared.d.ts vendored Normal file
View File

@ -0,0 +1,40 @@
import log4js from "log4js";
import Session from "./classes/session.js";
export declare type TPrefixDict = {
[n: number]: string;
};
declare type TPrefixKey = "engines" | "statuses" | "tags" | "others";
/**
* Class containing variables shared between modules.
*/
export default abstract class Shared {
private static _isLogged;
private static _prefixes;
private static _logger;
private static _session;
/**
* Indicates whether a user is logged in to the F95Zone platform or not.
*/
static get isLogged(): boolean;
/**
* List of platform prefixes and tags.
*/
static get prefixes(): {
[s: string]: TPrefixDict;
};
/**
* Logger object used to write to both file and console.
*/
static get logger(): log4js.Logger;
/**
* Path to the cache used by this module wich contains engines, statuses, tags...
*/
static get cachePath(): string;
/**
* Session on the F95Zone platform.
*/
static get session(): Session;
static setPrefixPair(key: TPrefixKey, val: TPrefixDict): void;
static setIsLogged(val: boolean): void;
}
export {};