veendor
Version:
a tool for stroing your npm dependencies in arbitraty storage
134 lines (133 loc) • 5.9 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
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) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const http_1 = __importDefault(require("http"));
const https_1 = __importDefault(require("https"));
const url_1 = __importDefault(require("url"));
const tarWrapper = __importStar(require("../commandWrappers/tarWrapper"));
const errors = __importStar(require("../errors"));
function validateOptions(options) {
if (options.compression && !(options.compression in tarWrapper.compression)) {
throw new errors.InvalidOptionsError(`Invalid compression: ${options.compression}`);
}
if (!options.compression) {
options.compression = 'gzip';
}
if (!options.resolveUrl) {
throw new errors.InvalidOptionsError('`resolveUrl` function must be provided');
}
if (!options.strict) {
options.strict = false;
}
}
exports.validateOptions = validateOptions;
function pull(hash, options, _cachedir, toolsProvider) {
return __awaiter(this, void 0, void 0, function* () {
let resolvedUrlPromise = options.resolveUrl(hash);
if (!(resolvedUrlPromise instanceof Promise)) {
resolvedUrlPromise = Promise.resolve(resolvedUrlPromise);
}
const resolvedUrl = yield resolvedUrlPromise;
const parsedUrl = url_1.default.parse(resolvedUrl);
let done = false;
if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') {
done = true;
throw new InvalidProtocolError(`http backend can't work with \`${parsedUrl.protocol}\` protocol. ` +
`Only \`http:\` and \`https:\` are supported`);
}
const transport = parsedUrl.protocol === 'https:' ? https_1.default : http_1.default;
if (typeof parsedUrl.href !== 'string') {
done = true;
throw new InvalidUrlError(`${parsedUrl.href} is not a valid URL`);
}
const href = parsedUrl.href;
return new Promise((resolve, reject) => {
transport.get(href, res => {
if (res.statusCode === 404) {
done = true;
reject(new errors.BundleNotFoundError());
return;
}
else if (res.statusCode !== 200) {
if (done) {
return;
}
done = true;
if (options.strict) {
reject(new InvalidStatusCodeError(`Request to \'${parsedUrl}\' failed. Invalid status code: \`${res.statusCode}\``));
return;
}
reject(new errors.BundleNotFoundError());
return;
}
const contentLengthHeader = res.headers['content-length'];
const contentLength = typeof contentLengthHeader === 'string' ?
(parseInt(contentLengthHeader, 10)) : undefined;
const progressStream = toolsProvider.getProgressStream('pull', contentLength);
res.pipe(progressStream);
progressStream.toggleVisibility(true);
const tarWrapperToken = {};
tarWrapper.extractArchiveFromStream(progressStream, options.compression, { controlToken: tarWrapperToken })
.then(() => {
if (!done) {
resolve();
done = true;
}
}, (error) => {
if (!done) {
reject(error);
done = true;
}
});
res.on('error', (error) => {
if (done) {
return;
}
done = true;
if (tarWrapperToken.terminate) {
tarWrapperToken.terminate();
}
if (options.strict) {
return reject(new BundleDownloadError(error.stack));
}
return reject(new errors.BundleNotFoundError(error.stack));
});
});
});
});
}
exports.pull = pull;
class InvalidUrlError extends errors.VeendorError {
}
exports.InvalidUrlError = InvalidUrlError;
class InvalidProtocolError extends errors.VeendorError {
}
exports.InvalidProtocolError = InvalidProtocolError;
class InvalidStatusCodeError extends errors.VeendorError {
}
exports.InvalidStatusCodeError = InvalidStatusCodeError;
class BundleDownloadError extends errors.VeendorError {
}
exports.BundleDownloadError = BundleDownloadError;
function push() {
throw new errors.VeendorError('`http` backend is read-only, pushing is not implemented');
}
exports.push = push;