1 | "use strict";
|
2 | var __importDefault = (this && this.__importDefault) || function (mod) {
|
3 | return (mod && mod.__esModule) ? mod : { "default": mod };
|
4 | };
|
5 | Object.defineProperty(exports, "__esModule", { value: true });
|
6 | const assert_1 = __importDefault(require("assert"));
|
7 | const node_fetch_1 = __importDefault(require("node-fetch"));
|
8 | const multistream_1 = __importDefault(require("multistream"));
|
9 | const async_retry_1 = __importDefault(require("async-retry"));
|
10 | const async_sema_1 = __importDefault(require("async-sema"));
|
11 | const semaToDownloadFromS3 = new async_sema_1.default(5);
|
12 | class BailableError extends Error {
|
13 | constructor(...args) {
|
14 | super(...args);
|
15 | this.bail = false;
|
16 | }
|
17 | }
|
18 | class FileRef {
|
19 | constructor({ mode = 0o100644, digest, contentType, mutable = false, }) {
|
20 | assert_1.default(typeof mode === 'number');
|
21 | assert_1.default(typeof digest === 'string');
|
22 | this.type = 'FileRef';
|
23 | this.mode = mode;
|
24 | this.digest = digest;
|
25 | this.contentType = contentType;
|
26 | this.mutable = mutable;
|
27 | }
|
28 | async toStreamAsync() {
|
29 | let url = '';
|
30 |
|
31 | const [digestType, digestHash] = this.digest.split(':');
|
32 | if (digestType === 'sha') {
|
33 |
|
34 |
|
35 |
|
36 | url = this.mutable
|
37 | ? `https://now-files.s3.amazonaws.com/${digestHash}`
|
38 | : `https://dmmcy0pwk6bqi.cloudfront.net/${digestHash}`;
|
39 | }
|
40 | else if (digestType === 'sha+ephemeral') {
|
41 |
|
42 |
|
43 |
|
44 | url = `https://now-ephemeral-files.s3.amazonaws.com/${digestHash}`;
|
45 | }
|
46 | else {
|
47 | throw new Error('Expected digest to be sha');
|
48 | }
|
49 | await semaToDownloadFromS3.acquire();
|
50 |
|
51 | try {
|
52 | return await async_retry_1.default(async () => {
|
53 | const resp = await node_fetch_1.default(url);
|
54 | if (!resp.ok) {
|
55 | const error = new BailableError(`download: ${resp.status} ${resp.statusText} for ${url}`);
|
56 | if (resp.status === 403)
|
57 | error.bail = true;
|
58 | throw error;
|
59 | }
|
60 | return resp.body;
|
61 | }, { factor: 1, retries: 3 });
|
62 | }
|
63 | finally {
|
64 |
|
65 | semaToDownloadFromS3.release();
|
66 | }
|
67 | }
|
68 | toStream() {
|
69 | let flag = false;
|
70 |
|
71 | return multistream_1.default(cb => {
|
72 | if (flag)
|
73 | return cb(null, null);
|
74 | flag = true;
|
75 | this.toStreamAsync()
|
76 | .then(stream => {
|
77 | cb(null, stream);
|
78 | })
|
79 | .catch(error => {
|
80 | cb(error, null);
|
81 | });
|
82 | });
|
83 | }
|
84 | }
|
85 | exports.default = FileRef;
|