diff options
Diffstat (limited to 'src/constants.ts')
-rw-r--r-- | src/constants.ts | 136 |
1 files changed, 80 insertions, 56 deletions
diff --git a/src/constants.ts b/src/constants.ts index 5f20147..1652b6b 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -2,11 +2,15 @@ * Fetch and edit constants from the skyblock-constants repo */ -import fetch from 'node-fetch' +// we have to do this so we can mock the function from the tests properly +import * as constants from './constants' + import * as nodeFetch from 'node-fetch' -import { Agent } from 'https' import NodeCache from 'node-cache' import Queue from 'queue-promise' +import fetch from 'node-fetch' +import { Agent } from 'https' +import { debug } from '.' const httpsAgent = new Agent({ keepAlive: true @@ -16,10 +20,10 @@ const githubApiBase = 'https://api.github.com' const owner = 'skyblockstats' const repo = 'skyblock-constants' -// we use a queue for editing so it doesnt hit the github ratelimit as much +// we use a queue for editing so it always utilizes the cache if possible, and to avoid hitting the github rateimit const queue = new Queue({ concurrent: 1, - interval: 500 + interval: 10 }) /** @@ -31,6 +35,7 @@ const queue = new Queue({ */ async function fetchGithubApi(method: string, route: string, headers?: any, json?: any): Promise<nodeFetch.Response> { try { + if (debug) console.debug('fetching github api', method, route) return await fetch( githubApiBase + route, { @@ -67,26 +72,30 @@ const fileCache = new NodeCache({ * Fetch a file from skyblock-constants * @param path The file path, for example stats.json */ -async function fetchFile(path: string): Promise<GithubFile> { - if (fileCache.has(path)) - return fileCache.get(path) - - const r = await fetchGithubApi( - 'GET', - `/repos/${owner}/${repo}/contents/${path}`, - { - 'Accept': 'application/vnd.github.v3+json', - }, - ) - const data = await r.json() - - const file = { - path: data.path, - content: Buffer.from(data.content, data.encoding).toString(), - sha: data.sha - } - fileCache.set(path, file) - return file +function fetchFile(path: string): Promise<GithubFile> { + return new Promise(resolve => { + queue.enqueue(async() => { + if (fileCache.has(path)) + return resolve(fileCache.get(path)) + + const r = await fetchGithubApi( + 'GET', + `/repos/${owner}/${repo}/contents/${path}`, + { + 'Accept': 'application/vnd.github.v3+json', + }, + ) + const data = await r.json() + + const file = { + path: data.path, + content: Buffer.from(data.content, data.encoding).toString(), + sha: data.sha + } + fileCache.set(path, file) + resolve(file) + }) + }) } /** @@ -115,7 +124,8 @@ async function editFile(file: GithubFile, message: string, newContent: string): }) } -async function fetchJSONConstant(filename: string): Promise<string[]> { +export async function fetchJSONConstant(filename: string): Promise<string[]> { + console.log('actually fetchJSONConstant') const file = await fetchFile(filename) try { return JSON.parse(file.content) @@ -129,80 +139,94 @@ async function fetchJSONConstant(filename: string): Promise<string[]> { export async function addJSONConstants(filename: string, addingValues: string[], unit: string='stat'): Promise<void> { if (addingValues.length === 0) return // no stats provided, just return - queue.enqueue(async() => { - const file = await fetchFile(filename) - if (!file.path) - return - let oldStats: string[] - try { - oldStats = JSON.parse(file.content) - } catch { - // invalid json, set it as an empty array - oldStats = [] - } - const updatedStats = oldStats - .concat(addingValues) - // remove duplicates - .filter((value, index, array) => array.indexOf(value) === index) - .sort((a, b) => a.localeCompare(b)) - const newStats = updatedStats.filter(value => !oldStats.includes(value)) + let file: GithubFile = await fetchFile(filename) + if (!file.path) + return + let oldStats: string[] + try { + oldStats = JSON.parse(file.content) + } catch { + // invalid json, set it as an empty array + oldStats = [] + } + const updatedStats = oldStats + .concat(addingValues) + // remove duplicates + .filter((value, index, array) => array.indexOf(value) === index) + .sort((a, b) => a.localeCompare(b)) + const newStats = updatedStats.filter(value => !oldStats.includes(value)) - // there's not actually any new stats, just return - if (newStats.length === 0) return + // there's not actually any new stats, just return + if (newStats.length === 0) return - const commitMessage = newStats.length >= 2 ? `Add ${newStats.length} new ${unit}s` : `Add '${newStats[0]}' ${unit}` + const commitMessage = newStats.length >= 2 ? `Add ${newStats.length} new ${unit}s` : `Add '${newStats[0]}' ${unit}` + try { await editFile(file, commitMessage, JSON.stringify(updatedStats, null, 2)) - }) + } catch { + // the file probably changed or something, try again + file = await fetchFile(filename) + await editFile(file, commitMessage, JSON.stringify(updatedStats, null, 2)) + } } /** Fetch all the known SkyBlock stats as an array of strings */ export async function fetchStats(): Promise<string[]> { - return await fetchJSONConstant('stats.json') + return await constants.fetchJSONConstant('stats.json') } /** Add stats to skyblock-constants. This has caching so it's fine to call many times */ export async function addStats(addingStats: string[]): Promise<void> { - await addJSONConstants('stats.json', addingStats, 'stat') + await constants.addJSONConstants('stats.json', addingStats, 'stat') } /** Fetch all the known SkyBlock collections as an array of strings */ export async function fetchCollections(): Promise<string[]> { - return await fetchJSONConstant('collections.json') + return await constants.fetchJSONConstant('collections.json') } /** Add collections to skyblock-constants. This has caching so it's fine to call many times */ export async function addCollections(addingCollections: string[]): Promise<void> { - await addJSONConstants('collections.json', addingCollections, 'collection') + await constants.addJSONConstants('collections.json', addingCollections, 'collection') } /** Fetch all the known SkyBlock collections as an array of strings */ export async function fetchSkills(): Promise<string[]> { - return await fetchJSONConstant('skills.json') + return await constants.fetchJSONConstant('skills.json') } /** Add skills to skyblock-constants. This has caching so it's fine to call many times */ export async function addSkills(addingSkills: string[]): Promise<void> { - await addJSONConstants('skills.json', addingSkills, 'skill') + await constants.addJSONConstants('skills.json', addingSkills, 'skill') } /** Fetch all the known SkyBlock collections as an array of strings */ export async function fetchZones(): Promise<string[]> { - return await fetchJSONConstant('zones.json') + return await constants.fetchJSONConstant('zones.json') } /** Add skills to skyblock-constants. This has caching so it's fine to call many times */ export async function addZones(addingZones: string[]): Promise<void> { - await addJSONConstants('zones.json', addingZones, 'zone') + await constants.addJSONConstants('zones.json', addingZones, 'zone') } /** Fetch all the known SkyBlock slayer names as an array of strings */ export async function fetchSlayers(): Promise<string[]> { - return await fetchJSONConstant('slayers.json') + return await constants.fetchJSONConstant('slayers.json') } /** Add skills to skyblock-constants. This has caching so it's fine to call many times */ export async function addSlayers(addingSlayers: string[]): Promise<void> { - await addJSONConstants('slayers.json', addingSlayers, 'slayer') + await constants.addJSONConstants('slayers.json', addingSlayers, 'slayer') +} + +/** Fetch all the known SkyBlock slayer names as an array of strings */ +export async function fetchMinions(): Promise<string[]> { + return await constants.fetchJSONConstant('minions.json') +} + +/** Add skills to skyblock-constants. This has caching so it's fine to call many times */ +export async function addMinions(addingMinions: string[]): Promise<void> { + await constants.addJSONConstants('minions.json', addingMinions, 'minion') } |