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
JavaScript
;
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}`,
},
};