UNPKG

@nekolab/hanime

Version:

Fast and efficient hanime.tv API wrapper written in TypeScript.

187 lines (186 loc) 6.17 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.HanimeClient = void 0; const crypto_1 = require("../modules/crypto"); const requests_1 = require("./requests"); const constants_1 = require("../constants"); const logging_1 = require("./logging"); const utility_1 = require("../modules/utility"); /** * Hanime client. Based on mobile and web API. */ class HanimeClient { /** * Requests client */ reqClient; /** * Logging client */ loggingClient; /** * User session token */ sessionToken = null; /** * Information about the app and currently logged in user */ info = null; /** * Base URL for the requests */ BASE_URLS = { appV8: 'https://www.universal-cdn.com/api/v8', app: 'https://www.universal-cdn.com/rapi/v4', web: 'https://hanime.tv/', search: '', }; /** * Create a new instance of the AppClient * @param sessionToken User session token * @returns AppClient instance */ constructor(sessionToken, loggingConfig = { enabled: false, level: 'info' }) { this.sessionToken = sessionToken || null; this.loggingClient = new logging_1.LoggingClient(loggingConfig); this.reqClient = new requests_1.RequestsClient(({ baseUrl }) => { const t = Math.floor(new Date().getTime() / 1000); return baseUrl === this.BASE_URLS.web ? { 'x-time': t.toString(), 'x-signature-version': 'web2', 'x-session-token': this.sessionToken || '', } : { 'x-claim': t.toString(), 'x-signature-version': 'app2', 'x-signature': (0, crypto_1.getAppSignature)(t), 'x-session-token': this.sessionToken || '', }; }, this.loggingClient); } /** * Login to the APP * @param login User login * @param password User password * @returns Login response. */ async login(login, password) { const rsp = await this.reqClient.request(this.BASE_URLS.app, '/sessions', { burger: login, fries: password, // Just put fries in da bag bro }, 'POST'); this.sessionToken = rsp.sessionToken; this.info = rsp; return rsp; } /** * Get base info about current user * @returns User info */ async getInfo() { return this.info || (await this.reqClient.request(this.BASE_URLS.app, '/user_base_data')); } /** * Get the home page * @returns Home page response */ async getHomePage() { const rsp = await this.reqClient.request(this.BASE_URLS.app, '/home'); rsp.sections = rsp.sections.map((section) => { section.data = section.data.map((hentaiId) => { return rsp.hentaiVideos.find((hentai) => hentai.id === hentaiId); }); return section; }); return (0, utility_1.omit)(rsp, ['hentaiVideos']); } /** * Claim coins. Raises 401 if cooldown is not over. * @returns Coins response */ async claimCoins() { if (!this.info) { this.info = await this.getInfo(); } const t = Math.floor(new Date().getTime() / 1000); const signature = (0, crypto_1.getRewardTokenSignature)(t, this.info.user.id, this.info.env.mobileApps.buildNumber); return await this.reqClient.request(this.BASE_URLS.app, '/coins', { rewardToken: `${signature}|${t}`, deviceInfo: constants_1.DEVICE_INFO, version: this.info.env.mobileApps.buildNumber, }, 'POST'); } /** * Get hentai downloads * @param slug Slug of the hentai * @returns Downloads response */ async getHentaiDownloads(slug) { return await this.reqClient.request(this.BASE_URLS.app, `/downloads/${slug}`); } /** * Get hentai video * @param id ID of the hentai * @returns Hentai video */ async getHentaiVideo(id) { return await this.reqClient.request(this.BASE_URLS.app, `/hentai-videos/${id}`); } /** * Get current account channel * @returns Channel response */ async getMyChannel() { return await this.reqClient.request(this.BASE_URLS.web, '/rapi/v7/my_channel'); } /** * Get other user channel * @param slug Slug of the user * @returns Channel response */ async getChannel(slug) { return await this.reqClient.request(this.BASE_URLS.web, `/rapi/v7/channels/${slug}`); } /** * Get hentai comments * @param hentaiId ID of the hentai * @param offset Offset * @param count Comments count * @param order Order * @returns Comments */ async getComments(hentaiId, offset = 0, count = 20, sortBy = 'upvotes') { const params = new URLSearchParams({ hv_id: hentaiId.toString(), offset: offset.toString(), count: count.toString(), order: sortBy === 'createdAt' ? 'created_at,desc' : 'upvotes,desc', }); return await this.reqClient.request(this.BASE_URLS.appV8, '/hthreads?' + params.toString()); } /** * Get comments users * @param userIds User IDs * @returns Comment users */ async getCommentsUsers(userIds) { const params = new URLSearchParams({ source: 'comments' }); userIds.forEach((id) => params.append('user_ids[]', id.toString())); return await this.reqClient.request(this.BASE_URLS.app, '/users?' + params.toString()); } /** * Claim Premium * @returns Premium response */ async claimPremium() { if (!this.info) { this.info = await this.getInfo(); } return await this.reqClient.request(this.BASE_URLS.app, '/alt_subscriptions', { deviceInfo: constants_1.DEVICE_INFO, version: this.info.env.mobileApps.buildNumber, }, 'POST'); } } exports.HanimeClient = HanimeClient;