make-fetch-happen.ts 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. import path from 'node:path';
  2. import fs from 'node:fs';
  3. import makeFetchHappen from 'make-fetch-happen';
  4. import type { FetchOptions } from 'make-fetch-happen';
  5. import cacache from 'cacache';
  6. import picocolors from 'picocolors';
  7. // eslint-disable-next-line @typescript-eslint/no-restricted-imports -- type only
  8. import type { Response as NodeFetchResponse } from 'node-fetch';
  9. export type { NodeFetchResponse };
  10. const cachePath = path.resolve(__dirname, '../../.cache/__make_fetch_happen__');
  11. fs.mkdirSync(cachePath, { recursive: true });
  12. const _fetch = makeFetchHappen.defaults({
  13. cachePath,
  14. maxSockets: 32, /**
  15. * They said 15 is a good default that prevents knocking out others' routers,
  16. * I disagree. 32 is a good number.
  17. */
  18. headers: {
  19. 'User-Agent': 'curl/8.9.1 (https://github.com/SukkaW/Surge)'
  20. },
  21. retry: {
  22. retries: 5,
  23. randomize: true
  24. }
  25. });
  26. export function $fetch(uriOrRequest: string | Request, opts?: FetchOptions) {
  27. return _fetch(uriOrRequest, opts).then((resp) => {
  28. printResponseStatus(resp);
  29. return resp;
  30. });
  31. }
  32. export async function $delete(resp: NodeFetchResponse) {
  33. const cacheKey = resp.headers.get('X-Local-Cache-Key');
  34. if (cacheKey) {
  35. await cacache.rm.entry(cachePath, cacheKey);
  36. await cacache.verify(cachePath, { concurrency: 64 });
  37. }
  38. }
  39. export function printResponseStatus(resp: NodeFetchResponse) {
  40. const status = resp.headers.get('X-Local-Cache-Status');
  41. if (status) {
  42. console.log('[$fetch cache]', { status }, picocolors.gray(resp.url));
  43. }
  44. }