UNPKG

1.66 kBPlain TextView Raw
1import * as os from 'os';
2import * as path from 'path';
3import * as fs from 'fs';
4
5import nodeFetch, {
6 RequestInit as FetchOptions,
7 Response,
8 Request,
9 Headers,
10} from 'node-fetch';
11import {CLIError} from './errors';
12import logger from './logger';
13
14async function unwrapFetchResult(response: Response) {
15 const data = await response.text();
16
17 try {
18 return JSON.parse(data);
19 } catch (e) {
20 return data;
21 }
22}
23
24/**
25 * Downloads the given `url` to the OS's temp folder and
26 * returns the path to it.
27 */
28const fetchToTemp = (url: string): Promise<string> => {
29 try {
30 return new Promise((resolve, reject) => {
31 const fileName = path.basename(url);
32 const tmpDir = path.join(os.tmpdir(), fileName);
33
34 nodeFetch(url).then((result) => {
35 if (result.status >= 400) {
36 return reject(`Fetch request failed with status ${result.status}`);
37 }
38
39 const dest = fs.createWriteStream(tmpDir);
40 result.body.pipe(dest);
41
42 result.body.on('end', () => {
43 resolve(tmpDir);
44 });
45
46 result.body.on('error', reject);
47 });
48 });
49 } catch (e) {
50 logger.error(e);
51 throw e;
52 }
53};
54
55const fetch = async (
56 url: string | Request,
57 options?: FetchOptions,
58): Promise<{status: number; data: any; headers: Headers}> => {
59 const result = await nodeFetch(url, options);
60 const data = await unwrapFetchResult(result);
61
62 if (result.status >= 400) {
63 throw new CLIError(
64 `Fetch request failed with status ${result.status}: ${data}.`,
65 );
66 }
67
68 return {
69 status: result.status,
70 headers: result.headers,
71 data,
72 };
73};
74
75export {fetch, fetchToTemp};