UNPKG

2.87 kBJavaScriptView Raw
1"use strict";
2var __importDefault = (this && this.__importDefault) || function (mod) {
3 return (mod && mod.__esModule) ? mod : { "default": mod };
4};
5Object.defineProperty(exports, "__esModule", { value: true });
6const errors_1 = require("./errors");
7const node_persist_1 = __importDefault(require("node-persist"));
8const got_1 = __importDefault(require("got"));
9exports.REQUEST_CACHE_DIR = '/tmp/dockter-request-cache';
10let REQUEST_CACHE_INITIALISED = false;
11/**
12 * The default URL fetcher that Dockter uses. Fetches using `got` and caches results using `persist`
13 */
14class CachingUrlFetcher {
15 /**
16 * Fetch a URL using `got`, attempting to retrieve it from cache first.
17 */
18 async fetchUrl(url, options = { json: true }) {
19 let value = await CachingUrlFetcher.getFromCache(url);
20 if (value)
21 return value;
22 try {
23 const response = await got_1.default(url, options);
24 value = response.body;
25 }
26 catch (error) {
27 if (error.statusCode === 404) {
28 value = null;
29 }
30 else if (['ENOTFOUND', 'ECONNRESET', 'EAI_AGAIN', 'DEPTH_ZERO_SELF_SIGNED_CERT'].includes(error.code)) {
31 // These are usually connection errors
32 throw new errors_1.NetworkError(`There was a problem fetching ${url} (${error.code}). Are you connected to the internet?`);
33 }
34 else {
35 throw error;
36 }
37 }
38 await CachingUrlFetcher.setToCache(url, value);
39 return value;
40 }
41 /**
42 * Try to get a result from the `persist` cache. This method with initialise the `persist` cache if it has not been
43 * set up.
44 */
45 static async getFromCache(url) {
46 if (!REQUEST_CACHE_INITIALISED) {
47 await node_persist_1.default.init({
48 dir: exports.REQUEST_CACHE_DIR,
49 ttl: 60 * 60 * 1000 // Milliseconds to cache responses for
50 });
51 REQUEST_CACHE_INITIALISED = true;
52 }
53 try {
54 return await node_persist_1.default.getItem(url);
55 }
56 catch (error) {
57 if (error.message.includes('does not look like a valid storage file')) {
58 // It seems that `persist.setItem` is not atomic and that the storage file can
59 // have zero bytes when we make multiple requests, some of which are for the same
60 // url. So we ignore this error and continue with the duplicate request.
61 return null;
62 }
63 else {
64 throw error;
65 }
66 }
67 }
68 /**
69 * Set a value (URL response body, usually) to the `persist` cache.
70 */
71 static async setToCache(url, value) {
72 await node_persist_1.default.setItem(url, value);
73 }
74}
75exports.default = CachingUrlFetcher;