pnpm
Version:
A fast implementation of npm install
80 lines • 3.45 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator.throw(value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments)).next());
});
};
const debug_1 = require('../debug');
const debug = debug_1.default('pnpm:fetch');
const crypto = require('crypto');
const gunzip = require('gunzip-maybe');
const tar = require('tar-fs');
const fs = require('fs');
function createRemoteTarballFetcher(dist) {
return (target, opts) => fetchFromRemoteTarball(target, dist, opts);
}
exports.createRemoteTarballFetcher = createRemoteTarballFetcher;
function createLocalTarballFetcher(dist) {
return (target, opts) => fetchFromLocalTarball(target, dist, opts);
}
exports.createLocalTarballFetcher = createLocalTarballFetcher;
/**
* Fetches a tarball `tarball` and extracts it into `dir`
*/
function fetchFromRemoteTarball(dir, dist, opts) {
return __awaiter(this, void 0, void 0, function* () {
const stream = yield opts.got.getStream(dist.tarball);
return fetchStream(dir, dist, opts.log, stream);
});
}
exports.fetchFromRemoteTarball = fetchFromRemoteTarball;
function fetchFromLocalTarball(dir, dist, opts) {
return unpackStream(fs.createReadStream(dist.tarball), dir);
}
exports.fetchFromLocalTarball = fetchFromLocalTarball;
function fetchStream(dir, dist, log, stream) {
return new Promise((resolve, reject) => {
const actualShasum = crypto.createHash('sha1');
let size = 0;
let downloaded = 0;
unpackStream(stream
.on('response', start)
.on('data', (_) => { actualShasum.update(_); })
.on('error', reject), dir).then(finish).catch(reject);
// without pausing, gunzip/tar-fs would miss the beginning of the stream
stream.resume();
function start(res) {
if (res.statusCode !== 200) {
return reject(new Error('' + dist.tarball + ': invalid response ' + res.statusCode));
}
log('download-start');
if ('content-length' in res.headers) {
size = +res.headers['content-length'];
res.on('data', (chunk) => {
downloaded += chunk.length;
log('downloading', { done: downloaded, total: size });
});
}
}
function finish() {
const digest = actualShasum.digest('hex');
debug(`finish ${dist.shasum} ${dist.tarball}`);
if (dist.shasum && digest !== dist.shasum) {
return reject(new Error('' + dist.tarball + ': incorrect shasum (expected ' + dist.shasum + ', got ' + digest + ')'));
}
return resolve(dir);
}
});
}
function unpackStream(stream, dir) {
return new Promise((resolve, reject) => {
stream
.pipe(gunzip()).on('error', reject)
.pipe(tar.extract(dir, { strip: 1 })).on('error', reject)
.on('finish', resolve);
});
}
//# sourceMappingURL=fetch.js.map