Skip to content

Instantly share code, notes, and snippets.

@joshua-gould
Last active April 23, 2024 06:21
Show Gist options
  • Save joshua-gould/58e1b114a67127273eef239ec0af8989 to your computer and use it in GitHub Desktop.
Save joshua-gould/58e1b114a67127273eef239ec0af8989 to your computer and use it in GitHub Desktop.
node-fetch file URL
const fs = require('fs');
const path = require('path');
const nodeFetch = require('node-fetch');
const Request = nodeFetch.Request;
const Request = nodeFetch.Response;
fetch = function (url, options) {
const request = new Request(url, options);
if (request.url.substring(0, 5) === 'file:') {
return new Promise((resolve, reject) => {
const filePath = path.normalize(url.substring('file:///'.length));
if (!fs.existsSync(filePath)) {
reject(`File not found: ${filePath}`);
}
const readStream = fs.createReadStream(filePath);
readStream.on('open', function () {
resolve(new Response(readStream, {
url: request.url,
status: 200,
statusText: 'OK',
size: fs.statSync(filePath).size,
timeout: request.timeout
}));
});
});
} else {
return nodeFetch(url, options);
}
};
@jimmywarting
Copy link

jimmywarting commented Oct 31, 2017

  • rename Request variable to Response on line 5
  • size: fs.statSync(filePath).size, should be changed to
    headers: { "Content-Length": fs.statSync(filePath).size }
  • timeout should be replaced with AbortController

@guest271314
Copy link

Node.js' undici fetch() implementation can be modified at or around https://github.com/nodejs/undici/blob/main/lib/web/fetch/index.js#L129 to include something like

  const p = createDeferredPromise()
  const url = new URL(input);
  if (url.protocol === "file:") {
    return import("node:fs").then((fs) => {
      p.resolve(new Response(fs.readFileSync(url)));
      return p.promise;
    })       
  }

see https://gist.github.com/guest271314/a4f005d9a6b5b433ae6d6e6c5c6d7595 for some other options I tried.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment