Skip to content

Instantly share code, notes, and snippets.

@piglovesyou
Last active April 9, 2025 03:37
Show Gist options
  • Save piglovesyou/8141ea2d776f7a0da300c097e9de8489 to your computer and use it in GitHub Desktop.
Save piglovesyou/8141ea2d776f7a0da300c097e9de8489 to your computer and use it in GitHub Desktop.
Oktokit.js caching snippet in 2025
/**
* This Gist shares a snippet of caching solution for Oktokit.js
* In essense this defines a custom fetch function that wraps native fetch with caching,
* where it stores cache in filesystem with path ./cache/<md5 of url>.json.
* Inspired by https://github.com/octokit/octokit.js/issues/215.
*/
import crypto from 'crypto'
import { existsSync } from 'node:fs'
import { writeFile, readFile } from 'node:fs/promises'
import { Octokit } from '@octokit/core'
main().catch((err) => (console.error(err), process.exit(1)))
async function main() {
const octokit = new Octokit({
auth,
request: {
fetch: fetchAndCache
}
})
// Access GitHub server first. Next time it doesn't and returns cached JSON response.
await octokit.request('GET /repos/{owner}/{repo}/actions/runs/{run_id}/attempts/{attempt_number}', {
owner: "xxx",
repo: "xxx",
run_id: "xxx",
attempt_number: "xxx"
})
}
async function fetchAndCache(url: any, options: any) {
const key = md5(url)
const path = `./cache/${key}.json`
if (existsSync(path)) {
console.info(`Cache hit: url=${url}`)
const cache = await readFile(path, 'utf-8')
return {
status: 200,
url,
headers: new Map([
['content-type', 'application/json']
]),
text: () => Promise.resolve(cache)
}
} else {
console.info(`No cache hit: url=${url}`)
}
const res = await fetch(url, options)
if (!res.ok) return res
const cache = await res.text()
await writeFile(path, cache)
return Object.assign(res, {
text: () => Promise.resolve(cache)
})
}
function md5(string: string) {
return crypto.createHash('md5').update(string, 'utf8').digest('hex')
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment