UNPKG

@rexxhayanasi/nhentai

Version:

A scraper for NHentai with types

188 lines (187 loc) 9.41 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; var _NHentai_axios; Object.defineProperty(exports, "__esModule", { value: true }); exports.NHentai = void 0; const axios_1 = __importDefault(require("axios")); const cheerio_1 = require("cheerio"); const tough_cookie_1 = require("tough-cookie"); const http_1 = require("http-cookie-agent/http"); const Parser_1 = require("../../Parser"); const constants_1 = require("../constants"); const util_1 = require("../util"); const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); class NHentai { /** * Constructs an instance of the NHentai class * @param _options Options of the NHentai class */ constructor(_options = { site: 'https://nhentai.to' }) { this._options = _options; _NHentai_axios.set(this, void 0); /** * Gets a random doujin * @returns Info of the random doujin */ this.getRandom = () => __awaiter(this, void 0, void 0, function* () { return yield __classPrivateFieldGet(this, _NHentai_axios, "f") .get(`${this._options.site}/random`) .then(({ data }) => __awaiter(this, void 0, void 0, function* () { return (0, Parser_1.parseDoujinInfo)((0, cheerio_1.load)(data), this._options.site.split('nhentai.')[1], this._options.site.includes('net') ? yield (0, util_1.getAPIGalleryPages)(__classPrivateFieldGet(this, _NHentai_axios, "f"), data) : undefined); })) .catch((err) => { throw new Error(err.message); }); }); /** * Explores the list of doujin * @param page Page number of the list * @returns The doujin list */ this.explore = (page = 1) => __awaiter(this, void 0, void 0, function* () { if (isNaN(page) || page < 1) page = 1; return yield __classPrivateFieldGet(this, _NHentai_axios, "f") .get(`${this._options.site}?page=${page}`) .then(({ data }) => (0, Parser_1.parseDoujinList)((0, cheerio_1.load)(data), this._options.site.split('nhentai.')[1])) .catch((err) => { throw new Error(err.message); }); }); /** * Searches for a doujin by a query * @param query Query of the doujin to search * @param options Options for searching * @returns The result of the search */ this.search = (query, options) => __awaiter(this, void 0, void 0, function* () { if (!query) throw new Error("The 'query' parameter shouldn't be undefined"); let page = 1; if ((options === null || options === void 0 ? void 0 : options.page) && options.page > 0) page = options.page; return yield __classPrivateFieldGet(this, _NHentai_axios, "f") .get(`${this._options.site}/search?q=${query}&page=${page}`) .then((res) => { const results = (0, Parser_1.parseDoujinList)((0, cheerio_1.load)(res.data), this._options.site.split('nhentai.')[1]); if (!results.data.length) throw new Error('No doujin results found'); return results; }); }); /** * Gets the info of a doujin by its ID * @param id ID of the doujin * @returns Info of the doujin */ this.getDoujin = (id) => __awaiter(this, void 0, void 0, function* () { if (!id) throw new Error("The 'id' parameter shouldn't be undefined"); const valid = yield this.validate(id); if (!valid) throw new Error('Invalid doujin ID'); return yield __classPrivateFieldGet(this, _NHentai_axios, "f") .get(`${this._options.site}/g/${id}`) .then((res) => __awaiter(this, void 0, void 0, function* () { return (0, Parser_1.parseDoujinInfo)((0, cheerio_1.load)(res.data), this._options.site.split('nhentai.')[1], this._options.site.includes('net') ? yield (0, util_1.getAPIGalleryPages)(__classPrivateFieldGet(this, _NHentai_axios, "f"), res.data) : undefined); })) .catch((err) => { throw new Error(err.message); }); }); /** * Validates the ID of a doujin * @param id ID of the doujin to check */ this.validate = (id) => __classPrivateFieldGet(this, _NHentai_axios, "f") .get(`${this._options.site}/g/${id}`) .then(() => true) .catch(() => false); __classPrivateFieldSet(this, _NHentai_axios, axios_1.default, "f"); // Validasi domain if (!constants_1.sites.includes(this._options.site .replace('https:', '') .replace(/\//g, ''))) this._options.site = 'https://nhentai.to'; if (!this._options.site.startsWith('https://')) this._options.site = `https://${this._options.site}`; // ✅ Ambil cookie default dari file jika tidak diberikan user let defaultCookie = ''; const cookiePath = path_1.default.resolve(__dirname, '../lib/cookies.txt'); if (fs_1.default.existsSync(cookiePath)) { defaultCookie = fs_1.default.readFileSync(cookiePath, 'utf8').trim(); } // ✅ Gunakan defaultCookie kalau site nhentai.net tapi user tidak kasih cookie if (this._options.site.includes('nhentai.net') && (!this._options.cookie_value || !this._options.user_agent)) { if (!this._options.cookie_value && defaultCookie) { this._options.cookie_value = defaultCookie; } else { throw new Error(`Assign the 'user_agent' in the instance of the class to use this site.`); } } // Set cookie dan agent if (this._options.cookie_value) { const jar = new tough_cookie_1.CookieJar(); jar.setCookie(this._options.cookie_value, this._options.site); const httpsAgent = new http_1.HttpsCookieAgent({ cookies: { jar } }); __classPrivateFieldSet(this, _NHentai_axios, axios_1.default.create({ httpsAgent }), "f"); } if (this._options.user_agent) __classPrivateFieldGet(this, _NHentai_axios, "f").defaults.headers.common['User-Agent'] = this._options.user_agent; } /** * Ganti cookie secara dinamis saat runtime */ setCookie(cookie) { const jar = new tough_cookie_1.CookieJar(); jar.setCookieSync(cookie, this._options.site); const httpsAgent = new http_1.HttpsCookieAgent({ cookies: { jar } }); __classPrivateFieldSet(this, _NHentai_axios, axios_1.default.create({ httpsAgent }), "f"); if (this._options.user_agent) __classPrivateFieldGet(this, _NHentai_axios, "f").defaults.headers.common['User-Agent'] = this._options.user_agent; this._options.cookie_value = cookie; } /** * Ganti user-agent secara dinamis */ setUserAgent(ua) { __classPrivateFieldGet(this, _NHentai_axios, "f").defaults.headers.common['User-Agent'] = ua; this._options.user_agent = ua; } } exports.NHentai = NHentai; _NHentai_axios = new WeakMap();