UNPKG

genshin-manager

Version:

<div align="center"> <p> <a href="https://www.npmjs.com/package/genshin-manager"><img src="https://img.shields.io/npm/v/genshin-manager.svg?maxAge=3600" alt="npm version" /></a> <a href="https://www.npmjs.com/package/genshin-manager"><img src="https:

223 lines (222 loc) 10.2 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()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.EnkaManager = exports.EnkaManagerEvents = void 0; const ts_deepmerge_1 = require("ts-deepmerge"); const EnkaManagerError_1 = require("../errors/EnkaManagerError"); const EnkaNetWorkError_1 = require("../errors/EnkaNetWorkError"); const EnkaNetWorkStatusError_1 = require("../errors/EnkaNetWorkStatusError"); const CharacterDetail_1 = require("../models/enka/CharacterDetail"); const EnkaAccount_1 = require("../models/enka/EnkaAccount"); const GenshinAccount_1 = require("../models/enka/GenshinAccount"); const PlayerDetail_1 = require("../models/enka/PlayerDetail"); const PromiseEventEmitter_1 = require("../utils/PromiseEventEmitter"); /** * EnkaManager events * @see {@link EnkaManager} */ var EnkaManagerEvents; (function (EnkaManagerEvents) { /** * When new data is added to the cache, fires * @event GET_NEW_ENKA_DATA * @listener * | param | type | description | * | --- | --- | --- | * | data | {@link EnkaData} | New data added to the cache | */ EnkaManagerEvents["GET_NEW_ENKA_DATA"] = "GET_NEW_ENKA_DATA"; })(EnkaManagerEvents || (exports.EnkaManagerEvents = EnkaManagerEvents = {})); /** * Class for fetching EnkaData from enka.network */ class EnkaManager extends PromiseEventEmitter_1.PromiseEventEmitter { /** * Create a EnkaManager */ constructor() { super(); /** * Cache of EnkaData * @key UID * @value Cached EnkaData */ this.cache = new Map(); } /** * Fetch All from enka.network * @description The data fetched by this method is stored as a temporary cache. * The storage period depends on ttl. * @param uid UID * @param fetchOption Fetch option * @returns EnkaData */ fetchAll(uid, fetchOption) { return __awaiter(this, void 0, void 0, function* () { const url = `${EnkaManager.ENKA_BASE_URL}/api/uid/${uid}`; return yield this.fetchUID(uid, url, fetchOption); }); } /** * Fetch PlayerDetail from enka.network * @description The data fetched by this method is stored as a temporary cache. * The storage period depends on ttl. * @param uid UID * @param fetchOption Fetch option * @returns PlayerDetail */ fetchPlayerDetail(uid, fetchOption) { return __awaiter(this, void 0, void 0, function* () { const url = `${EnkaManager.ENKA_BASE_URL}/api/uid/${uid}/?info`; return (yield this.fetchUID(uid, url, fetchOption)).playerDetail; }); } /** * Clear cache over nextShowCaseDate */ clearCacheOverNextShowCaseDate() { this.cache.forEach((value, key) => { if (new Date().getTime() > value.nextShowCaseDate.getTime()) this.cache.delete(key); }); } /** * Fetch EnkaAccount from enka.network * @description Data fetched by this method is not stored as a temporary cache. * @param username Enka Account Username * @param fetchOption Fetch option * @returns EnkaAccount */ fetchEnkaAccount(username, fetchOption) { return __awaiter(this, void 0, void 0, function* () { const getOwnerURL = `${EnkaManager.ENKA_BASE_URL}/api/profile/${username}`; const mergedFetchOption = ts_deepmerge_1.merge.withOptions({ mergeArrays: false }, EnkaManager.defaultFetchOption, fetchOption !== null && fetchOption !== void 0 ? fetchOption : {}); const ownerRes = yield fetch(getOwnerURL, mergedFetchOption); if (!ownerRes.ok) throw new EnkaNetWorkError_1.EnkaNetworkError(ownerRes); const owner = (yield ownerRes.json()); return new EnkaAccount_1.EnkaAccount(owner, EnkaManager.ENKA_BASE_URL); }); } /** * Fetch GenshinAccounts from enka.network * @description Data fetched by this method is not stored as a temporary cache. * @param username Enka Account Username * @param fetchOption Fetch option * @returns GenshinAccounts */ fetchGenshinAccounts(username, fetchOption) { return __awaiter(this, void 0, void 0, function* () { const getGameAccountsURL = `${EnkaManager.ENKA_BASE_URL}/api/profile/${username}/hoyos`; const mergedFetchOption = ts_deepmerge_1.merge.withOptions({ mergeArrays: false }, EnkaManager.defaultFetchOption, fetchOption !== null && fetchOption !== void 0 ? fetchOption : {}); const gameAccountsRes = yield fetch(getGameAccountsURL, mergedFetchOption); if (!gameAccountsRes.ok) throw new EnkaNetWorkError_1.EnkaNetworkError(gameAccountsRes); const gameAccounts = (yield gameAccountsRes.json()); return yield Promise.all(Object.values(gameAccounts) .sort((a, b) => a.order - b.order) .filter((account) => account.hoyo_type === 0) .map((account) => __awaiter(this, void 0, void 0, function* () { const getBuildsURL = `${EnkaManager.ENKA_BASE_URL}/api/profile/${username}/hoyos/${account.hash}/builds`; const buildsRes = yield fetch(getBuildsURL, mergedFetchOption); if (!buildsRes.ok) throw new EnkaNetWorkError_1.EnkaNetworkError(buildsRes); const builds = (yield buildsRes.json()); return new GenshinAccount_1.GenshinAccount(account, builds, username, EnkaManager.ENKA_BASE_URL); }))); }); } /** * Fetch Status from 1 hour ago to now * @param fetchOption Fetch option * @returns Status from 1 hour ago to now */ fetchAllStatus(fetchOption) { return __awaiter(this, void 0, void 0, function* () { const getStatusURL = `${EnkaManager.ENKA_STATUS_BASE_URL}/api/status`; const mergedFetchOption = ts_deepmerge_1.merge.withOptions({ mergeArrays: false }, EnkaManager.defaultFetchOption, fetchOption !== null && fetchOption !== void 0 ? fetchOption : {}); const statusRes = yield fetch(getStatusURL, mergedFetchOption); if (!statusRes.ok) throw new EnkaNetWorkStatusError_1.EnkaNetWorkStatusError(statusRes); return (yield statusRes.json()); }); } /** * Fetch now Status * @param fetchOption Fetch option * @returns Now status */ fetchNowStatus(fetchOption) { return __awaiter(this, void 0, void 0, function* () { const getStatusURL = `${EnkaManager.ENKA_STATUS_BASE_URL}/api/now`; const mergedFetchOption = ts_deepmerge_1.merge.withOptions({ mergeArrays: false }, EnkaManager.defaultFetchOption, fetchOption !== null && fetchOption !== void 0 ? fetchOption : {}); const statusRes = yield fetch(getStatusURL, mergedFetchOption); if (!statusRes.ok) throw new EnkaNetWorkStatusError_1.EnkaNetWorkStatusError(statusRes); return (yield statusRes.json()); }); } /** * Fetch UIDEndPoint from URL * @param uid UID * @param url URL * @param fetchOption Fetch option * @returns EnkaData */ fetchUID(uid, url, fetchOption) { return __awaiter(this, void 0, void 0, function* () { var _a, _b, _c; this.clearCacheOverNextShowCaseDate(); if (!/1?\d{9}/.test(String(uid))) throw new EnkaManagerError_1.EnkaManagerError(`The UID format is not correct(${uid})`); const cachedData = this.cache.get(uid); if (cachedData && cachedData.characterDetails && new Date().getTime() < cachedData.nextShowCaseDate.getTime()) return cachedData; const mergedFetchOption = ts_deepmerge_1.merge.withOptions({ mergeArrays: false }, EnkaManager.defaultFetchOption, fetchOption !== null && fetchOption !== void 0 ? fetchOption : {}); const res = yield fetch(url, mergedFetchOption); if (!res.ok) throw new EnkaNetWorkError_1.EnkaNetworkError(res); const result = (yield res.json()); const enkaData = { uid: uid, playerDetail: new PlayerDetail_1.PlayerDetail(result.playerInfo), characterDetails: (_b = (_a = result.avatarInfoList) === null || _a === void 0 ? void 0 : _a.map((avatarInfo) => new CharacterDetail_1.CharacterDetail(avatarInfo))) !== null && _b !== void 0 ? _b : [], owner: result.owner ? new EnkaAccount_1.EnkaAccount(result.owner, EnkaManager.ENKA_BASE_URL) : undefined, nextShowCaseDate: new Date(new Date().getTime() + ((_c = result.ttl) !== null && _c !== void 0 ? _c : 60) * 1000), url: `${EnkaManager.ENKA_BASE_URL}/u/${uid}`, }; this.cache.set(enkaData.uid, enkaData); this.emit(EnkaManagerEvents.GET_NEW_ENKA_DATA, enkaData); return enkaData; }); } } exports.EnkaManager = EnkaManager; /** * URL of enka.network */ EnkaManager.ENKA_BASE_URL = 'https://enka.network'; /** * URL of status.enka.network */ EnkaManager.ENKA_STATUS_BASE_URL = 'http://status.enka.network'; /** * Default fetch option */ EnkaManager.defaultFetchOption = { headers: { 'user-agent': `genshin-manager/${process.env.npm_package_version}`, }, };