Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
fetcher.js93 linesDownload Raw Back to dist
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 });
6exports.DefaultFetcher = exports.BaseFetcher = void 0;
7const debug_1 = __importDefault(require("debug"));
8const fs_1 = __importDefault(require("fs"));
9const make_fetch_happen_1 = __importDefault(require("make-fetch-happen"));
10const util_1 = __importDefault(require("util"));
11const error_1 = require("./error");
12const tmpfile_1 = require("./utils/tmpfile");
13const log = (0, debug_1.default)('tuf:fetch');
14const USER_AGENT_HEADER = 'User-Agent';
15class BaseFetcher {
16    // Download file from given URL. The file is downloaded to a temporary
17    // location and then passed to the given handler. The handler is responsible
18    // for moving the file to its final location. The temporary file is deleted
19    // after the handler returns.
20    async downloadFile(url, maxLength, handler) {
21        return (0, tmpfile_1.withTempFile)(async (tmpFile) => {
22            const reader = await this.fetch(url);
23            let numberOfBytesReceived = 0;
24            const fileStream = fs_1.default.createWriteStream(tmpFile);
25            // Read the stream a chunk at a time so that we can check
26            // the length of the file as we go
27            try {
28                for await (const chunk of reader) {
29                    numberOfBytesReceived += chunk.length;
30                    if (numberOfBytesReceived > maxLength) {
31                        throw new error_1.DownloadLengthMismatchError('Max length reached');
32                    }
33                    await writeBufferToStream(fileStream, chunk);
34                }
35            }
36            finally {
37                // Make sure we always close the stream
38                // eslint-disable-next-line @typescript-eslint/unbound-method
39                await util_1.default.promisify(fileStream.close).bind(fileStream)();
40            }
41            return handler(tmpFile);
42        });
43    }
44    // Download bytes from given URL.
45    async downloadBytes(url, maxLength) {
46        return this.downloadFile(url, maxLength, async (file) => {
47            const stream = fs_1.default.createReadStream(file);
48            const chunks = [];
49            for await (const chunk of stream) {
50                chunks.push(chunk);
51            }
52            return Buffer.concat(chunks);
53        });
54    }
55}
56exports.BaseFetcher = BaseFetcher;
57class DefaultFetcher extends BaseFetcher {
58    userAgent;
59    timeout;
60    retry;
61    constructor(options = {}) {
62        super();
63        this.userAgent = options.userAgent;
64        this.timeout = options.timeout;
65        this.retry = options.retry;
66    }
67    async fetch(url) {
68        log('GET %s', url);
69        const response = await (0, make_fetch_happen_1.default)(url, {
70            headers: {
71                [USER_AGENT_HEADER]: this.userAgent || '',
72            },
73            timeout: this.timeout,
74            retry: this.retry,
75        });
76        if (!response.ok || !response?.body) {
77            throw new error_1.DownloadHTTPError('Failed to download', response.status);
78        }
79        return response.body;
80    }
81}
82exports.DefaultFetcher = DefaultFetcher;
83const writeBufferToStream = async (stream, buffer) => {
84    return new Promise((resolve, reject) => {
85        stream.write(buffer, (err) => {
86            if (err) {
87                reject(err);
88            }
89            resolve(true);
90        });
91    });
92};
93 
codekingpro/portable-devtools · Team Ai