Test sudo tar
This commit is contained in:
parent
a631fadf14
commit
7527073910
5266
dist/restore/index.js
vendored
Normal file
5266
dist/restore/index.js
vendored
Normal file
@ -0,0 +1,5266 @@
|
||||
module.exports =
|
||||
/******/ (function(modules, runtime) { // webpackBootstrap
|
||||
/******/ "use strict";
|
||||
/******/ // The module cache
|
||||
/******/ var installedModules = {};
|
||||
/******/
|
||||
/******/ // The require function
|
||||
/******/ function __webpack_require__(moduleId) {
|
||||
/******/
|
||||
/******/ // Check if module is in cache
|
||||
/******/ if(installedModules[moduleId]) {
|
||||
/******/ return installedModules[moduleId].exports;
|
||||
/******/ }
|
||||
/******/ // Create a new module (and put it into the cache)
|
||||
/******/ var module = installedModules[moduleId] = {
|
||||
/******/ i: moduleId,
|
||||
/******/ l: false,
|
||||
/******/ exports: {}
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Execute the module function
|
||||
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
||||
/******/
|
||||
/******/ // Flag the module as loaded
|
||||
/******/ module.l = true;
|
||||
/******/
|
||||
/******/ // Return the exports of the module
|
||||
/******/ return module.exports;
|
||||
/******/ }
|
||||
/******/
|
||||
/******/
|
||||
/******/ __webpack_require__.ab = __dirname + "/";
|
||||
/******/
|
||||
/******/ // the startup function
|
||||
/******/ function startup() {
|
||||
/******/ // Load entry module and return exports
|
||||
/******/ return __webpack_require__(778);
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // run startup
|
||||
/******/ return startup();
|
||||
/******/ })
|
||||
/************************************************************************/
|
||||
/******/ ({
|
||||
|
||||
/***/ 1:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
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());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const childProcess = __webpack_require__(129);
|
||||
const path = __webpack_require__(622);
|
||||
const util_1 = __webpack_require__(669);
|
||||
const ioUtil = __webpack_require__(672);
|
||||
const exec = util_1.promisify(childProcess.exec);
|
||||
/**
|
||||
* Copies a file or folder.
|
||||
* Based off of shelljs - https://github.com/shelljs/shelljs/blob/9237f66c52e5daa40458f94f9565e18e8132f5a6/src/cp.js
|
||||
*
|
||||
* @param source source path
|
||||
* @param dest destination path
|
||||
* @param options optional. See CopyOptions.
|
||||
*/
|
||||
function cp(source, dest, options = {}) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const { force, recursive } = readCopyOptions(options);
|
||||
const destStat = (yield ioUtil.exists(dest)) ? yield ioUtil.stat(dest) : null;
|
||||
// Dest is an existing file, but not forcing
|
||||
if (destStat && destStat.isFile() && !force) {
|
||||
return;
|
||||
}
|
||||
// If dest is an existing directory, should copy inside.
|
||||
const newDest = destStat && destStat.isDirectory()
|
||||
? path.join(dest, path.basename(source))
|
||||
: dest;
|
||||
if (!(yield ioUtil.exists(source))) {
|
||||
throw new Error(`no such file or directory: ${source}`);
|
||||
}
|
||||
const sourceStat = yield ioUtil.stat(source);
|
||||
if (sourceStat.isDirectory()) {
|
||||
if (!recursive) {
|
||||
throw new Error(`Failed to copy. ${source} is a directory, but tried to copy without recursive flag.`);
|
||||
}
|
||||
else {
|
||||
yield cpDirRecursive(source, newDest, 0, force);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (path.relative(source, newDest) === '') {
|
||||
// a file cannot be copied to itself
|
||||
throw new Error(`'${newDest}' and '${source}' are the same file`);
|
||||
}
|
||||
yield copyFile(source, newDest, force);
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.cp = cp;
|
||||
/**
|
||||
* Moves a path.
|
||||
*
|
||||
* @param source source path
|
||||
* @param dest destination path
|
||||
* @param options optional. See MoveOptions.
|
||||
*/
|
||||
function mv(source, dest, options = {}) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (yield ioUtil.exists(dest)) {
|
||||
let destExists = true;
|
||||
if (yield ioUtil.isDirectory(dest)) {
|
||||
// If dest is directory copy src into dest
|
||||
dest = path.join(dest, path.basename(source));
|
||||
destExists = yield ioUtil.exists(dest);
|
||||
}
|
||||
if (destExists) {
|
||||
if (options.force == null || options.force) {
|
||||
yield rmRF(dest);
|
||||
}
|
||||
else {
|
||||
throw new Error('Destination already exists');
|
||||
}
|
||||
}
|
||||
}
|
||||
yield mkdirP(path.dirname(dest));
|
||||
yield ioUtil.rename(source, dest);
|
||||
});
|
||||
}
|
||||
exports.mv = mv;
|
||||
/**
|
||||
* Remove a path recursively with force
|
||||
*
|
||||
* @param inputPath path to remove
|
||||
*/
|
||||
function rmRF(inputPath) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (ioUtil.IS_WINDOWS) {
|
||||
// Node doesn't provide a delete operation, only an unlink function. This means that if the file is being used by another
|
||||
// program (e.g. antivirus), it won't be deleted. To address this, we shell out the work to rd/del.
|
||||
try {
|
||||
if (yield ioUtil.isDirectory(inputPath, true)) {
|
||||
yield exec(`rd /s /q "${inputPath}"`);
|
||||
}
|
||||
else {
|
||||
yield exec(`del /f /a "${inputPath}"`);
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
// if you try to delete a file that doesn't exist, desired result is achieved
|
||||
// other errors are valid
|
||||
if (err.code !== 'ENOENT')
|
||||
throw err;
|
||||
}
|
||||
// Shelling out fails to remove a symlink folder with missing source, this unlink catches that
|
||||
try {
|
||||
yield ioUtil.unlink(inputPath);
|
||||
}
|
||||
catch (err) {
|
||||
// if you try to delete a file that doesn't exist, desired result is achieved
|
||||
// other errors are valid
|
||||
if (err.code !== 'ENOENT')
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
else {
|
||||
let isDir = false;
|
||||
try {
|
||||
isDir = yield ioUtil.isDirectory(inputPath);
|
||||
}
|
||||
catch (err) {
|
||||
// if you try to delete a file that doesn't exist, desired result is achieved
|
||||
// other errors are valid
|
||||
if (err.code !== 'ENOENT')
|
||||
throw err;
|
||||
return;
|
||||
}
|
||||
if (isDir) {
|
||||
yield exec(`rm -rf "${inputPath}"`);
|
||||
}
|
||||
else {
|
||||
yield ioUtil.unlink(inputPath);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.rmRF = rmRF;
|
||||
/**
|
||||
* Make a directory. Creates the full path with folders in between
|
||||
* Will throw if it fails
|
||||
*
|
||||
* @param fsPath path to create
|
||||
* @returns Promise<void>
|
||||
*/
|
||||
function mkdirP(fsPath) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
yield ioUtil.mkdirP(fsPath);
|
||||
});
|
||||
}
|
||||
exports.mkdirP = mkdirP;
|
||||
/**
|
||||
* Returns path of a tool had the tool actually been invoked. Resolves via paths.
|
||||
* If you check and the tool does not exist, it will throw.
|
||||
*
|
||||
* @param tool name of the tool
|
||||
* @param check whether to check if tool exists
|
||||
* @returns Promise<string> path to tool
|
||||
*/
|
||||
function which(tool, check) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (!tool) {
|
||||
throw new Error("parameter 'tool' is required");
|
||||
}
|
||||
// recursive when check=true
|
||||
if (check) {
|
||||
const result = yield which(tool, false);
|
||||
if (!result) {
|
||||
if (ioUtil.IS_WINDOWS) {
|
||||
throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also verify the file has a valid extension for an executable file.`);
|
||||
}
|
||||
else {
|
||||
throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
// build the list of extensions to try
|
||||
const extensions = [];
|
||||
if (ioUtil.IS_WINDOWS && process.env.PATHEXT) {
|
||||
for (const extension of process.env.PATHEXT.split(path.delimiter)) {
|
||||
if (extension) {
|
||||
extensions.push(extension);
|
||||
}
|
||||
}
|
||||
}
|
||||
// if it's rooted, return it if exists. otherwise return empty.
|
||||
if (ioUtil.isRooted(tool)) {
|
||||
const filePath = yield ioUtil.tryGetExecutablePath(tool, extensions);
|
||||
if (filePath) {
|
||||
return filePath;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
// if any path separators, return empty
|
||||
if (tool.includes('/') || (ioUtil.IS_WINDOWS && tool.includes('\\'))) {
|
||||
return '';
|
||||
}
|
||||
// build the list of directories
|
||||
//
|
||||
// Note, technically "where" checks the current directory on Windows. From a toolkit perspective,
|
||||
// it feels like we should not do this. Checking the current directory seems like more of a use
|
||||
// case of a shell, and the which() function exposed by the toolkit should strive for consistency
|
||||
// across platforms.
|
||||
const directories = [];
|
||||
if (process.env.PATH) {
|
||||
for (const p of process.env.PATH.split(path.delimiter)) {
|
||||
if (p) {
|
||||
directories.push(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
// return the first match
|
||||
for (const directory of directories) {
|
||||
const filePath = yield ioUtil.tryGetExecutablePath(directory + path.sep + tool, extensions);
|
||||
if (filePath) {
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
catch (err) {
|
||||
throw new Error(`which failed with message ${err.message}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.which = which;
|
||||
function readCopyOptions(options) {
|
||||
const force = options.force == null ? true : options.force;
|
||||
const recursive = Boolean(options.recursive);
|
||||
return { force, recursive };
|
||||
}
|
||||
function cpDirRecursive(sourceDir, destDir, currentDepth, force) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
// Ensure there is not a run away recursive copy
|
||||
if (currentDepth >= 255)
|
||||
return;
|
||||
currentDepth++;
|
||||
yield mkdirP(destDir);
|
||||
const files = yield ioUtil.readdir(sourceDir);
|
||||
for (const fileName of files) {
|
||||
const srcFile = `${sourceDir}/${fileName}`;
|
||||
const destFile = `${destDir}/${fileName}`;
|
||||
const srcFileStat = yield ioUtil.lstat(srcFile);
|
||||
if (srcFileStat.isDirectory()) {
|
||||
// Recurse
|
||||
yield cpDirRecursive(srcFile, destFile, currentDepth, force);
|
||||
}
|
||||
else {
|
||||
yield copyFile(srcFile, destFile, force);
|
||||
}
|
||||
}
|
||||
// Change the mode for the newly created directory
|
||||
yield ioUtil.chmod(destDir, (yield ioUtil.stat(sourceDir)).mode);
|
||||
});
|
||||
}
|
||||
// Buffered file copy
|
||||
function copyFile(srcFile, destFile, force) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if ((yield ioUtil.lstat(srcFile)).isSymbolicLink()) {
|
||||
// unlink/re-link it
|
||||
try {
|
||||
yield ioUtil.lstat(destFile);
|
||||
yield ioUtil.unlink(destFile);
|
||||
}
|
||||
catch (e) {
|
||||
// Try to override file permission
|
||||
if (e.code === 'EPERM') {
|
||||
yield ioUtil.chmod(destFile, '0666');
|
||||
yield ioUtil.unlink(destFile);
|
||||
}
|
||||
// other errors = it doesn't exist, no work to do
|
||||
}
|
||||
// Copy over symlink
|
||||
const symlinkFull = yield ioUtil.readlink(srcFile);
|
||||
yield ioUtil.symlink(symlinkFull, destFile, ioUtil.IS_WINDOWS ? 'junction' : null);
|
||||
}
|
||||
else if (!(yield ioUtil.exists(destFile)) || force) {
|
||||
yield ioUtil.copyFile(srcFile, destFile);
|
||||
}
|
||||
});
|
||||
}
|
||||
//# sourceMappingURL=io.js.map
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 9:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
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());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const os = __webpack_require__(87);
|
||||
const events = __webpack_require__(614);
|
||||
const child = __webpack_require__(129);
|
||||
/* eslint-disable @typescript-eslint/unbound-method */
|
||||
const IS_WINDOWS = process.platform === 'win32';
|
||||
/*
|
||||
* Class for running command line tools. Handles quoting and arg parsing in a platform agnostic way.
|
||||
*/
|
||||
class ToolRunner extends events.EventEmitter {
|
||||
constructor(toolPath, args, options) {
|
||||
super();
|
||||
if (!toolPath) {
|
||||
throw new Error("Parameter 'toolPath' cannot be null or empty.");
|
||||
}
|
||||
this.toolPath = toolPath;
|
||||
this.args = args || [];
|
||||
this.options = options || {};
|
||||
}
|
||||
_debug(message) {
|
||||
if (this.options.listeners && this.options.listeners.debug) {
|
||||
this.options.listeners.debug(message);
|
||||
}
|
||||
}
|
||||
_getCommandString(options, noPrefix) {
|
||||
const toolPath = this._getSpawnFileName();
|
||||
const args = this._getSpawnArgs(options);
|
||||
let cmd = noPrefix ? '' : '[command]'; // omit prefix when piped to a second tool
|
||||
if (IS_WINDOWS) {
|
||||
// Windows + cmd file
|
||||
if (this._isCmdFile()) {
|
||||
cmd += toolPath;
|
||||
for (const a of args) {
|
||||
cmd += ` ${a}`;
|
||||
}
|
||||
}
|
||||
// Windows + verbatim
|
||||
else if (options.windowsVerbatimArguments) {
|
||||
cmd += `"${toolPath}"`;
|
||||
for (const a of args) {
|
||||
cmd += ` ${a}`;
|
||||
}
|
||||
}
|
||||
// Windows (regular)
|
||||
else {
|
||||
cmd += this._windowsQuoteCmdArg(toolPath);
|
||||
for (const a of args) {
|
||||
cmd += ` ${this._windowsQuoteCmdArg(a)}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// OSX/Linux - this can likely be improved with some form of quoting.
|
||||
// creating processes on Unix is fundamentally different than Windows.
|
||||
// on Unix, execvp() takes an arg array.
|
||||
cmd += toolPath;
|
||||
for (const a of args) {
|
||||
cmd += ` ${a}`;
|
||||
}
|
||||
}
|
||||
return cmd;
|
||||
}
|
||||
_processLineBuffer(data, strBuffer, onLine) {
|
||||
try {
|
||||
let s = strBuffer + data.toString();
|
||||
let n = s.indexOf(os.EOL);
|
||||
while (n > -1) {
|
||||
const line = s.substring(0, n);
|
||||
onLine(line);
|
||||
// the rest of the string ...
|
||||
s = s.substring(n + os.EOL.length);
|
||||
n = s.indexOf(os.EOL);
|
||||
}
|
||||
strBuffer = s;
|
||||
}
|
||||
catch (err) {
|
||||
// streaming lines to console is best effort. Don't fail a build.
|
||||
this._debug(`error processing line. Failed with error ${err}`);
|
||||
}
|
||||
}
|
||||
_getSpawnFileName() {
|
||||
if (IS_WINDOWS) {
|
||||
if (this._isCmdFile()) {
|
||||
return process.env['COMSPEC'] || 'cmd.exe';
|
||||
}
|
||||
}
|
||||
return this.toolPath;
|
||||
}
|
||||
_getSpawnArgs(options) {
|
||||
if (IS_WINDOWS) {
|
||||
if (this._isCmdFile()) {
|
||||
let argline = `/D /S /C "${this._windowsQuoteCmdArg(this.toolPath)}`;
|
||||
for (const a of this.args) {
|
||||
argline += ' ';
|
||||
argline += options.windowsVerbatimArguments
|
||||
? a
|
||||
: this._windowsQuoteCmdArg(a);
|
||||
}
|
||||
argline += '"';
|
||||
return [argline];
|
||||
}
|
||||
}
|
||||
return this.args;
|
||||
}
|
||||
_endsWith(str, end) {
|
||||
return str.endsWith(end);
|
||||
}
|
||||
_isCmdFile() {
|
||||
const upperToolPath = this.toolPath.toUpperCase();
|
||||
return (this._endsWith(upperToolPath, '.CMD') ||
|
||||
this._endsWith(upperToolPath, '.BAT'));
|
||||
}
|
||||
_windowsQuoteCmdArg(arg) {
|
||||
// for .exe, apply the normal quoting rules that libuv applies
|
||||
if (!this._isCmdFile()) {
|
||||
return this._uvQuoteCmdArg(arg);
|
||||
}
|
||||
// otherwise apply quoting rules specific to the cmd.exe command line parser.
|
||||
// the libuv rules are generic and are not designed specifically for cmd.exe
|
||||
// command line parser.
|
||||
//
|
||||
// for a detailed description of the cmd.exe command line parser, refer to
|
||||
// http://stackoverflow.com/questions/4094699/how-does-the-windows-command-interpreter-cmd-exe-parse-scripts/7970912#7970912
|
||||
// need quotes for empty arg
|
||||
if (!arg) {
|
||||
return '""';
|
||||
}
|
||||
// determine whether the arg needs to be quoted
|
||||
const cmdSpecialChars = [
|
||||
' ',
|
||||
'\t',
|
||||
'&',
|
||||
'(',
|
||||
')',
|
||||
'[',
|
||||
']',
|
||||
'{',
|
||||
'}',
|
||||
'^',
|
||||
'=',
|
||||
';',
|
||||
'!',
|
||||
"'",
|
||||
'+',
|
||||
',',
|
||||
'`',
|
||||
'~',
|
||||
'|',
|
||||
'<',
|
||||
'>',
|
||||
'"'
|
||||
];
|
||||
let needsQuotes = false;
|
||||
for (const char of arg) {
|
||||
if (cmdSpecialChars.some(x => x === char)) {
|
||||
needsQuotes = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// short-circuit if quotes not needed
|
||||
if (!needsQuotes) {
|
||||
return arg;
|
||||
}
|
||||
// the following quoting rules are very similar to the rules that by libuv applies.
|
||||
//
|
||||
// 1) wrap the string in quotes
|
||||
//
|
||||
// 2) double-up quotes - i.e. " => ""
|
||||
//
|
||||
// this is different from the libuv quoting rules. libuv replaces " with \", which unfortunately
|
||||
// doesn't work well with a cmd.exe command line.
|
||||
//
|
||||
// note, replacing " with "" also works well if the arg is passed to a downstream .NET console app.
|
||||
// for example, the command line:
|
||||
// foo.exe "myarg:""my val"""
|
||||
// is parsed by a .NET console app into an arg array:
|
||||
// [ "myarg:\"my val\"" ]
|
||||
// which is the same end result when applying libuv quoting rules. although the actual
|
||||
// command line from libuv quoting rules would look like:
|
||||
// foo.exe "myarg:\"my val\""
|
||||
//
|
||||
// 3) double-up slashes that precede a quote,
|
||||
// e.g. hello \world => "hello \world"
|
||||
// hello\"world => "hello\\""world"
|
||||
// hello\\"world => "hello\\\\""world"
|
||||
// hello world\ => "hello world\\"
|
||||
//
|
||||
// technically this is not required for a cmd.exe command line, or the batch argument parser.
|
||||
// the reasons for including this as a .cmd quoting rule are:
|
||||
//
|
||||
// a) this is optimized for the scenario where the argument is passed from the .cmd file to an
|
||||
// external program. many programs (e.g. .NET console apps) rely on the slash-doubling rule.
|
||||
//
|
||||
// b) it's what we've been doing previously (by deferring to node default behavior) and we
|
||||
// haven't heard any complaints about that aspect.
|
||||
//
|
||||
// note, a weakness of the quoting rules chosen here, is that % is not escaped. in fact, % cannot be
|
||||
// escaped when used on the command line directly - even though within a .cmd file % can be escaped
|
||||
// by using %%.
|
||||
//
|
||||
// the saving grace is, on the command line, %var% is left as-is if var is not defined. this contrasts
|
||||
// the line parsing rules within a .cmd file, where if var is not defined it is replaced with nothing.
|
||||
//
|
||||
// one option that was explored was replacing % with ^% - i.e. %var% => ^%var^%. this hack would
|
||||
// often work, since it is unlikely that var^ would exist, and the ^ character is removed when the
|
||||
// variable is used. the problem, however, is that ^ is not removed when %* is used to pass the args
|
||||
// to an external program.
|
||||
//
|
||||
// an unexplored potential solution for the % escaping problem, is to create a wrapper .cmd file.
|
||||
// % can be escaped within a .cmd file.
|
||||
let reverse = '"';
|
||||
let quoteHit = true;
|
||||
for (let i = arg.length; i > 0; i--) {
|
||||
// walk the string in reverse
|
||||
reverse += arg[i - 1];
|
||||
if (quoteHit && arg[i - 1] === '\\') {
|
||||
reverse += '\\'; // double the slash
|
||||
}
|
||||
else if (arg[i - 1] === '"') {
|
||||
quoteHit = true;
|
||||
reverse += '"'; // double the quote
|
||||
}
|
||||
else {
|
||||
quoteHit = false;
|
||||
}
|
||||
}
|
||||
reverse += '"';
|
||||
return reverse
|
||||
.split('')
|
||||
.reverse()
|
||||
.join('');
|
||||
}
|
||||
_uvQuoteCmdArg(arg) {
|
||||
// Tool runner wraps child_process.spawn() and needs to apply the same quoting as
|
||||
// Node in certain cases where the undocumented spawn option windowsVerbatimArguments
|
||||
// is used.
|
||||
//
|
||||
// Since this function is a port of quote_cmd_arg from Node 4.x (technically, lib UV,
|
||||
// see https://github.com/nodejs/node/blob/v4.x/deps/uv/src/win/process.c for details),
|
||||
// pasting copyright notice from Node within this function:
|
||||
//
|
||||
// Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
if (!arg) {
|
||||
// Need double quotation for empty argument
|
||||
return '""';
|
||||
}
|
||||
if (!arg.includes(' ') && !arg.includes('\t') && !arg.includes('"')) {
|
||||
// No quotation needed
|
||||
return arg;
|
||||
}
|
||||
if (!arg.includes('"') && !arg.includes('\\')) {
|
||||
// No embedded double quotes or backslashes, so I can just wrap
|
||||
// quote marks around the whole thing.
|
||||
return `"${arg}"`;
|
||||
}
|
||||
// Expected input/output:
|
||||
// input : hello"world
|
||||
// output: "hello\"world"
|
||||
// input : hello""world
|
||||
// output: "hello\"\"world"
|
||||
// input : hello\world
|
||||
// output: hello\world
|
||||
// input : hello\\world
|
||||
// output: hello\\world
|
||||
// input : hello\"world
|
||||
// output: "hello\\\"world"
|
||||
// input : hello\\"world
|
||||
// output: "hello\\\\\"world"
|
||||
// input : hello world\
|
||||
// output: "hello world\\" - note the comment in libuv actually reads "hello world\"
|
||||
// but it appears the comment is wrong, it should be "hello world\\"
|
||||
let reverse = '"';
|
||||
let quoteHit = true;
|
||||
for (let i = arg.length; i > 0; i--) {
|
||||
// walk the string in reverse
|
||||
reverse += arg[i - 1];
|
||||
if (quoteHit && arg[i - 1] === '\\') {
|
||||
reverse += '\\';
|
||||
}
|
||||
else if (arg[i - 1] === '"') {
|
||||
quoteHit = true;
|
||||
reverse += '\\';
|
||||
}
|
||||
else {
|
||||
quoteHit = false;
|
||||
}
|
||||
}
|
||||
reverse += '"';
|
||||
return reverse
|
||||
.split('')
|
||||
.reverse()
|
||||
.join('');
|
||||
}
|
||||
_cloneExecOptions(options) {
|
||||
options = options || {};
|
||||
const result = {
|
||||
cwd: options.cwd || process.cwd(),
|
||||
env: options.env || process.env,
|
||||
silent: options.silent || false,
|
||||
windowsVerbatimArguments: options.windowsVerbatimArguments || false,
|
||||
failOnStdErr: options.failOnStdErr || false,
|
||||
ignoreReturnCode: options.ignoreReturnCode || false,
|
||||
delay: options.delay || 10000
|
||||
};
|
||||
result.outStream = options.outStream || process.stdout;
|
||||
result.errStream = options.errStream || process.stderr;
|
||||
return result;
|
||||
}
|
||||
_getSpawnOptions(options, toolPath) {
|
||||
options = options || {};
|
||||
const result = {};
|
||||
result.cwd = options.cwd;
|
||||
result.env = options.env;
|
||||
result['windowsVerbatimArguments'] =
|
||||
options.windowsVerbatimArguments || this._isCmdFile();
|
||||
if (options.windowsVerbatimArguments) {
|
||||
result.argv0 = `"${toolPath}"`;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Exec a tool.
|
||||
* Output will be streamed to the live console.
|
||||
* Returns promise with return code
|
||||
*
|
||||
* @param tool path to tool to exec
|
||||
* @param options optional exec options. See ExecOptions
|
||||
* @returns number
|
||||
*/
|
||||
exec() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
return new Promise((resolve, reject) => {
|
||||
this._debug(`exec tool: ${this.toolPath}`);
|
||||
this._debug('arguments:');
|
||||
for (const arg of this.args) {
|
||||
this._debug(` ${arg}`);
|
||||
}
|
||||
const optionsNonNull = this._cloneExecOptions(this.options);
|
||||
if (!optionsNonNull.silent && optionsNonNull.outStream) {
|
||||
optionsNonNull.outStream.write(this._getCommandString(optionsNonNull) + os.EOL);
|
||||
}
|
||||
const state = new ExecState(optionsNonNull, this.toolPath);
|
||||
state.on('debug', (message) => {
|
||||
this._debug(message);
|
||||
});
|
||||
const fileName = this._getSpawnFileName();
|
||||
const cp = child.spawn(fileName, this._getSpawnArgs(optionsNonNull), this._getSpawnOptions(this.options, fileName));
|
||||
const stdbuffer = '';
|
||||
if (cp.stdout) {
|
||||
cp.stdout.on('data', (data) => {
|
||||
if (this.options.listeners && this.options.listeners.stdout) {
|
||||
this.options.listeners.stdout(data);
|
||||
}
|
||||
if (!optionsNonNull.silent && optionsNonNull.outStream) {
|
||||
optionsNonNull.outStream.write(data);
|
||||
}
|
||||
this._processLineBuffer(data, stdbuffer, (line) => {
|
||||
if (this.options.listeners && this.options.listeners.stdline) {
|
||||
this.options.listeners.stdline(line);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
const errbuffer = '';
|
||||
if (cp.stderr) {
|
||||
cp.stderr.on('data', (data) => {
|
||||
state.processStderr = true;
|
||||
if (this.options.listeners && this.options.listeners.stderr) {
|
||||
this.options.listeners.stderr(data);
|
||||
}
|
||||
if (!optionsNonNull.silent &&
|
||||
optionsNonNull.errStream &&
|
||||
optionsNonNull.outStream) {
|
||||
const s = optionsNonNull.failOnStdErr
|
||||
? optionsNonNull.errStream
|
||||
: optionsNonNull.outStream;
|
||||
s.write(data);
|
||||
}
|
||||
this._processLineBuffer(data, errbuffer, (line) => {
|
||||
if (this.options.listeners && this.options.listeners.errline) {
|
||||
this.options.listeners.errline(line);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
cp.on('error', (err) => {
|
||||
state.processError = err.message;
|
||||
state.processExited = true;
|
||||
state.processClosed = true;
|
||||
state.CheckComplete();
|
||||
});
|
||||
cp.on('exit', (code) => {
|
||||
state.processExitCode = code;
|
||||
state.processExited = true;
|
||||
this._debug(`Exit code ${code} received from tool '${this.toolPath}'`);
|
||||
state.CheckComplete();
|
||||
});
|
||||
cp.on('close', (code) => {
|
||||
state.processExitCode = code;
|
||||
state.processExited = true;
|
||||
state.processClosed = true;
|
||||
this._debug(`STDIO streams have closed for tool '${this.toolPath}'`);
|
||||
state.CheckComplete();
|
||||
});
|
||||
state.on('done', (error, exitCode) => {
|
||||
if (stdbuffer.length > 0) {
|
||||
this.emit('stdline', stdbuffer);
|
||||
}
|
||||
if (errbuffer.length > 0) {
|
||||
this.emit('errline', errbuffer);
|
||||
}
|
||||
cp.removeAllListeners();
|
||||
if (error) {
|
||||
reject(error);
|
||||
}
|
||||
else {
|
||||
resolve(exitCode);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.ToolRunner = ToolRunner;
|
||||
/**
|
||||
* Convert an arg string to an array of args. Handles escaping
|
||||
*
|
||||
* @param argString string of arguments
|
||||
* @returns string[] array of arguments
|
||||
*/
|
||||
function argStringToArray(argString) {
|
||||
const args = [];
|
||||
let inQuotes = false;
|
||||
let escaped = false;
|
||||
let arg = '';
|
||||
function append(c) {
|
||||
// we only escape double quotes.
|
||||
if (escaped && c !== '"') {
|
||||
arg += '\\';
|
||||
}
|
||||
arg += c;
|
||||
escaped = false;
|
||||
}
|
||||
for (let i = 0; i < argString.length; i++) {
|
||||
const c = argString.charAt(i);
|
||||
if (c === '"') {
|
||||
if (!escaped) {
|
||||
inQuotes = !inQuotes;
|
||||
}
|
||||
else {
|
||||
append(c);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (c === '\\' && escaped) {
|
||||
append(c);
|
||||
continue;
|
||||
}
|
||||
if (c === '\\' && inQuotes) {
|
||||
escaped = true;
|
||||
continue;
|
||||
}
|
||||
if (c === ' ' && !inQuotes) {
|
||||
if (arg.length > 0) {
|
||||
args.push(arg);
|
||||
arg = '';
|
||||
}
|
||||
continue;
|
||||
}
|
||||
append(c);
|
||||
}
|
||||
if (arg.length > 0) {
|
||||
args.push(arg.trim());
|
||||
}
|
||||
return args;
|
||||
}
|
||||
exports.argStringToArray = argStringToArray;
|
||||
class ExecState extends events.EventEmitter {
|
||||
constructor(options, toolPath) {
|
||||
super();
|
||||
this.processClosed = false; // tracks whether the process has exited and stdio is closed
|
||||
this.processError = '';
|
||||
this.processExitCode = 0;
|
||||
this.processExited = false; // tracks whether the process has exited
|
||||
this.processStderr = false; // tracks whether stderr was written to
|
||||
this.delay = 10000; // 10 seconds
|
||||
this.done = false;
|
||||
this.timeout = null;
|
||||
if (!toolPath) {
|
||||
throw new Error('toolPath must not be empty');
|
||||
}
|
||||
this.options = options;
|
||||
this.toolPath = toolPath;
|
||||
if (options.delay) {
|
||||
this.delay = options.delay;
|
||||
}
|
||||
}
|
||||
CheckComplete() {
|
||||
if (this.done) {
|
||||
return;
|
||||
}
|
||||
if (this.processClosed) {
|
||||
this._setResult();
|
||||
}
|
||||
else if (this.processExited) {
|
||||
this.timeout = setTimeout(ExecState.HandleTimeout, this.delay, this);
|
||||
}
|
||||
}
|
||||
_debug(message) {
|
||||
this.emit('debug', message);
|
||||
}
|
||||
_setResult() {
|
||||
// determine whether there is an error
|
||||
let error;
|
||||
if (this.processExited) {
|
||||
if (this.processError) {
|
||||
error = new Error(`There was an error when attempting to execute the process '${this.toolPath}'. This may indicate the process failed to start. Error: ${this.processError}`);
|
||||
}
|
||||
else if (this.processExitCode !== 0 && !this.options.ignoreReturnCode) {
|
||||
error = new Error(`The process '${this.toolPath}' failed with exit code ${this.processExitCode}`);
|
||||
}
|
||||
else if (this.processStderr && this.options.failOnStdErr) {
|
||||
error = new Error(`The process '${this.toolPath}' failed because one or more lines were written to the STDERR stream`);
|
||||
}
|
||||
}
|
||||
// clear the timeout
|
||||
if (this.timeout) {
|
||||
clearTimeout(this.timeout);
|
||||
this.timeout = null;
|
||||
}
|
||||
this.done = true;
|
||||
this.emit('done', error, this.processExitCode);
|
||||
}
|
||||
static HandleTimeout(state) {
|
||||
if (state.done) {
|
||||
return;
|
||||
}
|
||||
if (!state.processClosed && state.processExited) {
|
||||
const message = `The STDIO streams did not close within ${state.delay /
|
||||
1000} seconds of the exit event from process '${state.toolPath}'. This may indicate a child process inherited the STDIO streams and has not yet exited.`;
|
||||
state._debug(message);
|
||||
}
|
||||
state._setResult();
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=toolrunner.js.map
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 12:
|
||||
/***/ (function(__unusedmodule, exports) {
|
||||
|
||||
"use strict";
|
||||
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
class BasicCredentialHandler {
|
||||
constructor(username, password) {
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
}
|
||||
// currently implements pre-authorization
|
||||
// TODO: support preAuth = false where it hooks on 401
|
||||
prepareRequest(options) {
|
||||
options.headers['Authorization'] = 'Basic ' + new Buffer(this.username + ':' + this.password).toString('base64');
|
||||
options.headers['X-TFS-FedAuthRedirect'] = 'Suppress';
|
||||
}
|
||||
// This handler cannot handle 401
|
||||
canHandleAuthentication(response) {
|
||||
return false;
|
||||
}
|
||||
handleAuthentication(httpClient, requestInfo, objs) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
exports.BasicCredentialHandler = BasicCredentialHandler;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 16:
|
||||
/***/ (function(module) {
|
||||
|
||||
module.exports = require("tls");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 87:
|
||||
/***/ (function(module) {
|
||||
|
||||
module.exports = require("os");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 105:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
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());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const httpm = __webpack_require__(874);
|
||||
const util = __webpack_require__(729);
|
||||
class RestClient {
|
||||
/**
|
||||
* Creates an instance of the RestClient
|
||||
* @constructor
|
||||
* @param {string} userAgent - userAgent for requests
|
||||
* @param {string} baseUrl - (Optional) If not specified, use full urls per request. If supplied and a function passes a relative url, it will be appended to this
|
||||
* @param {ifm.IRequestHandler[]} handlers - handlers are typically auth handlers (basic, bearer, ntlm supplied)
|
||||
* @param {ifm.IRequestOptions} requestOptions - options for each http requests (http proxy setting, socket timeout)
|
||||
*/
|
||||
constructor(userAgent, baseUrl, handlers, requestOptions) {
|
||||
this.client = new httpm.HttpClient(userAgent, handlers, requestOptions);
|
||||
if (baseUrl) {
|
||||
this._baseUrl = baseUrl;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Gets a resource from an endpoint
|
||||
* Be aware that not found returns a null. Other error conditions reject the promise
|
||||
* @param {string} requestUrl - fully qualified or relative url
|
||||
* @param {IRequestOptions} requestOptions - (optional) requestOptions object
|
||||
*/
|
||||
options(requestUrl, options) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let url = util.getUrl(requestUrl, this._baseUrl);
|
||||
let res = yield this.client.options(url, this._headersFromOptions(options));
|
||||
return this._processResponse(res, options);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Gets a resource from an endpoint
|
||||
* Be aware that not found returns a null. Other error conditions reject the promise
|
||||
* @param {string} resource - fully qualified url or relative path
|
||||
* @param {IRequestOptions} requestOptions - (optional) requestOptions object
|
||||
*/
|
||||
get(resource, options) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let url = util.getUrl(resource, this._baseUrl);
|
||||
let res = yield this.client.get(url, this._headersFromOptions(options));
|
||||
return this._processResponse(res, options);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Deletes a resource from an endpoint
|
||||
* Be aware that not found returns a null. Other error conditions reject the promise
|
||||
* @param {string} resource - fully qualified or relative url
|
||||
* @param {IRequestOptions} requestOptions - (optional) requestOptions object
|
||||
*/
|
||||
del(resource, options) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let url = util.getUrl(resource, this._baseUrl);
|
||||
let res = yield this.client.del(url, this._headersFromOptions(options));
|
||||
return this._processResponse(res, options);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Creates resource(s) from an endpoint
|
||||
* T type of object returned.
|
||||
* Be aware that not found returns a null. Other error conditions reject the promise
|
||||
* @param {string} resource - fully qualified or relative url
|
||||
* @param {IRequestOptions} requestOptions - (optional) requestOptions object
|
||||
*/
|
||||
create(resource, resources, options) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let url = util.getUrl(resource, this._baseUrl);
|
||||
let headers = this._headersFromOptions(options, true);
|
||||
let data = JSON.stringify(resources, null, 2);
|
||||
let res = yield this.client.post(url, data, headers);
|
||||
return this._processResponse(res, options);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Updates resource(s) from an endpoint
|
||||
* T type of object returned.
|
||||
* Be aware that not found returns a null. Other error conditions reject the promise
|
||||
* @param {string} resource - fully qualified or relative url
|
||||
* @param {IRequestOptions} requestOptions - (optional) requestOptions object
|
||||
*/
|
||||
update(resource, resources, options) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let url = util.getUrl(resource, this._baseUrl);
|
||||
let headers = this._headersFromOptions(options, true);
|
||||
let data = JSON.stringify(resources, null, 2);
|
||||
let res = yield this.client.patch(url, data, headers);
|
||||
return this._processResponse(res, options);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Replaces resource(s) from an endpoint
|
||||
* T type of object returned.
|
||||
* Be aware that not found returns a null. Other error conditions reject the promise
|
||||
* @param {string} resource - fully qualified or relative url
|
||||
* @param {IRequestOptions} requestOptions - (optional) requestOptions object
|
||||
*/
|
||||
replace(resource, resources, options) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let url = util.getUrl(resource, this._baseUrl);
|
||||
let headers = this._headersFromOptions(options, true);
|
||||
let data = JSON.stringify(resources, null, 2);
|
||||
let res = yield this.client.put(url, data, headers);
|
||||
return this._processResponse(res, options);
|
||||
});
|
||||
}
|
||||
uploadStream(verb, requestUrl, stream, options) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let url = util.getUrl(requestUrl, this._baseUrl);
|
||||
let headers = this._headersFromOptions(options, true);
|
||||
let res = yield this.client.sendStream(verb, url, stream, headers);
|
||||
return this._processResponse(res, options);
|
||||
});
|
||||
}
|
||||
_headersFromOptions(options, contentType) {
|
||||
options = options || {};
|
||||
let headers = options.additionalHeaders || {};
|
||||
headers["Accept"] = options.acceptHeader || "application/json";
|
||||
if (contentType) {
|
||||
let found = false;
|
||||
for (let header in headers) {
|
||||
if (header.toLowerCase() == "content-type") {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
headers["Content-Type"] = 'application/json; charset=utf-8';
|
||||
}
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
static dateTimeDeserializer(key, value) {
|
||||
if (typeof value === 'string') {
|
||||
let a = new Date(value);
|
||||
if (!isNaN(a.valueOf())) {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
_processResponse(res, options) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
||||
const statusCode = res.message.statusCode;
|
||||
const response = {
|
||||
statusCode: statusCode,
|
||||
result: null,
|
||||
headers: {}
|
||||
};
|
||||
// not found leads to null obj returned
|
||||
if (statusCode == httpm.HttpCodes.NotFound) {
|
||||
resolve(response);
|
||||
}
|
||||
let obj;
|
||||
let contents;
|
||||
// get the result from the body
|
||||
try {
|
||||
contents = yield res.readBody();
|
||||
if (contents && contents.length > 0) {
|
||||
if (options && options.deserializeDates) {
|
||||
obj = JSON.parse(contents, RestClient.dateTimeDeserializer);
|
||||
}
|
||||
else {
|
||||
obj = JSON.parse(contents);
|
||||
}
|
||||
if (options && options.responseProcessor) {
|
||||
response.result = options.responseProcessor(obj);
|
||||
}
|
||||
else {
|
||||
response.result = obj;
|
||||
}
|
||||
}
|
||||
response.headers = res.message.headers;
|
||||
}
|
||||
catch (err) {
|
||||
// Invalid resource (contents not json); leaving result obj null
|
||||
}
|
||||
// note that 3xx redirects are handled by the http layer.
|
||||
if (statusCode > 299) {
|
||||
let msg;
|
||||
// if exception/error in body, attempt to get better error
|
||||
if (obj && obj.message) {
|
||||
msg = obj.message;
|
||||
}
|
||||
else if (contents && contents.length > 0) {
|
||||
// it may be the case that the exception is in the body message as string
|
||||
msg = contents;
|
||||
}
|
||||
else {
|
||||
msg = "Failed request: (" + statusCode + ")";
|
||||
}
|
||||
let err = new Error(msg);
|
||||
// attach statusCode and body obj (if available) to the error object
|
||||
err['statusCode'] = statusCode;
|
||||
if (response.result) {
|
||||
err['result'] = response.result;
|
||||
}
|
||||
reject(err);
|
||||
}
|
||||
else {
|
||||
resolve(response);
|
||||
}
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.RestClient = RestClient;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 129:
|
||||
/***/ (function(module) {
|
||||
|
||||
module.exports = require("child_process");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 139:
|
||||
/***/ (function(module, __unusedexports, __webpack_require__) {
|
||||
|
||||
// Unique ID creation requires a high quality random # generator. In node.js
|
||||
// this is pretty straight-forward - we use the crypto API.
|
||||
|
||||
var crypto = __webpack_require__(417);
|
||||
|
||||
module.exports = function nodeRNG() {
|
||||
return crypto.randomBytes(16);
|
||||
};
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 141:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
var net = __webpack_require__(631);
|
||||
var tls = __webpack_require__(16);
|
||||
var http = __webpack_require__(605);
|
||||
var https = __webpack_require__(211);
|
||||
var events = __webpack_require__(614);
|
||||
var assert = __webpack_require__(357);
|
||||
var util = __webpack_require__(669);
|
||||
|
||||
|
||||
exports.httpOverHttp = httpOverHttp;
|
||||
exports.httpsOverHttp = httpsOverHttp;
|
||||
exports.httpOverHttps = httpOverHttps;
|
||||
exports.httpsOverHttps = httpsOverHttps;
|
||||
|
||||
|
||||
function httpOverHttp(options) {
|
||||
var agent = new TunnelingAgent(options);
|
||||
agent.request = http.request;
|
||||
return agent;
|
||||
}
|
||||
|
||||
function httpsOverHttp(options) {
|
||||
var agent = new TunnelingAgent(options);
|
||||
agent.request = http.request;
|
||||
agent.createSocket = createSecureSocket;
|
||||
return agent;
|
||||
}
|
||||
|
||||
function httpOverHttps(options) {
|
||||
var agent = new TunnelingAgent(options);
|
||||
agent.request = https.request;
|
||||
return agent;
|
||||
}
|
||||
|
||||
function httpsOverHttps(options) {
|
||||
var agent = new TunnelingAgent(options);
|
||||
agent.request = https.request;
|
||||
agent.createSocket = createSecureSocket;
|
||||
return agent;
|
||||
}
|
||||
|
||||
|
||||
function TunnelingAgent(options) {
|
||||
var self = this;
|
||||
self.options = options || {};
|
||||
self.proxyOptions = self.options.proxy || {};
|
||||
self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets;
|
||||
self.requests = [];
|
||||
self.sockets = [];
|
||||
|
||||
self.on('free', function onFree(socket, host, port, localAddress) {
|
||||
var options = toOptions(host, port, localAddress);
|
||||
for (var i = 0, len = self.requests.length; i < len; ++i) {
|
||||
var pending = self.requests[i];
|
||||
if (pending.host === options.host && pending.port === options.port) {
|
||||
// Detect the request to connect same origin server,
|
||||
// reuse the connection.
|
||||
self.requests.splice(i, 1);
|
||||
pending.request.onSocket(socket);
|
||||
return;
|
||||
}
|
||||
}
|
||||
socket.destroy();
|
||||
self.removeSocket(socket);
|
||||
});
|
||||
}
|
||||
util.inherits(TunnelingAgent, events.EventEmitter);
|
||||
|
||||
TunnelingAgent.prototype.addRequest = function addRequest(req, host, port, localAddress) {
|
||||
var self = this;
|
||||
var options = mergeOptions({request: req}, self.options, toOptions(host, port, localAddress));
|
||||
|
||||
if (self.sockets.length >= this.maxSockets) {
|
||||
// We are over limit so we'll add it to the queue.
|
||||
self.requests.push(options);
|
||||
return;
|
||||
}
|
||||
|
||||
// If we are under maxSockets create a new one.
|
||||
self.createSocket(options, function(socket) {
|
||||
socket.on('free', onFree);
|
||||
socket.on('close', onCloseOrRemove);
|
||||
socket.on('agentRemove', onCloseOrRemove);
|
||||
req.onSocket(socket);
|
||||
|
||||
function onFree() {
|
||||
self.emit('free', socket, options);
|
||||
}
|
||||
|
||||
function onCloseOrRemove(err) {
|
||||
self.removeSocket(socket);
|
||||
socket.removeListener('free', onFree);
|
||||
socket.removeListener('close', onCloseOrRemove);
|
||||
socket.removeListener('agentRemove', onCloseOrRemove);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
TunnelingAgent.prototype.createSocket = function createSocket(options, cb) {
|
||||
var self = this;
|
||||
var placeholder = {};
|
||||
self.sockets.push(placeholder);
|
||||
|
||||
var connectOptions = mergeOptions({}, self.proxyOptions, {
|
||||
method: 'CONNECT',
|
||||
path: options.host + ':' + options.port,
|
||||
agent: false
|
||||
});
|
||||
if (connectOptions.proxyAuth) {
|
||||
connectOptions.headers = connectOptions.headers || {};
|
||||
connectOptions.headers['Proxy-Authorization'] = 'Basic ' +
|
||||
new Buffer(connectOptions.proxyAuth).toString('base64');
|
||||
}
|
||||
|
||||
debug('making CONNECT request');
|
||||
var connectReq = self.request(connectOptions);
|
||||
connectReq.useChunkedEncodingByDefault = false; // for v0.6
|
||||
connectReq.once('response', onResponse); // for v0.6
|
||||
connectReq.once('upgrade', onUpgrade); // for v0.6
|
||||
connectReq.once('connect', onConnect); // for v0.7 or later
|
||||
connectReq.once('error', onError);
|
||||
connectReq.end();
|
||||
|
||||
function onResponse(res) {
|
||||
// Very hacky. This is necessary to avoid http-parser leaks.
|
||||
res.upgrade = true;
|
||||
}
|
||||
|
||||
function onUpgrade(res, socket, head) {
|
||||
// Hacky.
|
||||
process.nextTick(function() {
|
||||
onConnect(res, socket, head);
|
||||
});
|
||||
}
|
||||
|
||||
function onConnect(res, socket, head) {
|
||||
connectReq.removeAllListeners();
|
||||
socket.removeAllListeners();
|
||||
|
||||
if (res.statusCode === 200) {
|
||||
assert.equal(head.length, 0);
|
||||
debug('tunneling connection has established');
|
||||
self.sockets[self.sockets.indexOf(placeholder)] = socket;
|
||||
cb(socket);
|
||||
} else {
|
||||
debug('tunneling socket could not be established, statusCode=%d',
|
||||
res.statusCode);
|
||||
var error = new Error('tunneling socket could not be established, ' +
|
||||
'statusCode=' + res.statusCode);
|
||||
error.code = 'ECONNRESET';
|
||||
options.request.emit('error', error);
|
||||
self.removeSocket(placeholder);
|
||||
}
|
||||
}
|
||||
|
||||
function onError(cause) {
|
||||
connectReq.removeAllListeners();
|
||||
|
||||
debug('tunneling socket could not be established, cause=%s\n',
|
||||
cause.message, cause.stack);
|
||||
var error = new Error('tunneling socket could not be established, ' +
|
||||
'cause=' + cause.message);
|
||||
error.code = 'ECONNRESET';
|
||||
options.request.emit('error', error);
|
||||
self.removeSocket(placeholder);
|
||||
}
|
||||
};
|
||||
|
||||
TunnelingAgent.prototype.removeSocket = function removeSocket(socket) {
|
||||
var pos = this.sockets.indexOf(socket)
|
||||
if (pos === -1) {
|
||||
return;
|
||||
}
|
||||
this.sockets.splice(pos, 1);
|
||||
|
||||
var pending = this.requests.shift();
|
||||
if (pending) {
|
||||
// If we have pending requests and a socket gets closed a new one
|
||||
// needs to be created to take over in the pool for the one that closed.
|
||||
this.createSocket(pending, function(socket) {
|
||||
pending.request.onSocket(socket);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function createSecureSocket(options, cb) {
|
||||
var self = this;
|
||||
TunnelingAgent.prototype.createSocket.call(self, options, function(socket) {
|
||||
var hostHeader = options.request.getHeader('host');
|
||||
var tlsOptions = mergeOptions({}, self.options, {
|
||||
socket: socket,
|
||||
servername: hostHeader ? hostHeader.replace(/:.*$/, '') : options.host
|
||||
});
|
||||
|
||||
// 0 is dummy port for v0.6
|
||||
var secureSocket = tls.connect(0, tlsOptions);
|
||||
self.sockets[self.sockets.indexOf(socket)] = secureSocket;
|
||||
cb(secureSocket);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function toOptions(host, port, localAddress) {
|
||||
if (typeof host === 'string') { // since v0.10
|
||||
return {
|
||||
host: host,
|
||||
port: port,
|
||||
localAddress: localAddress
|
||||
};
|
||||
}
|
||||
return host; // for v0.11 or later
|
||||
}
|
||||
|
||||
function mergeOptions(target) {
|
||||
for (var i = 1, len = arguments.length; i < len; ++i) {
|
||||
var overrides = arguments[i];
|
||||
if (typeof overrides === 'object') {
|
||||
var keys = Object.keys(overrides);
|
||||
for (var j = 0, keyLen = keys.length; j < keyLen; ++j) {
|
||||
var k = keys[j];
|
||||
if (overrides[k] !== undefined) {
|
||||
target[k] = overrides[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
|
||||
var debug;
|
||||
if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) {
|
||||
debug = function() {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
if (typeof args[0] === 'string') {
|
||||
args[0] = 'TUNNEL: ' + args[0];
|
||||
} else {
|
||||
args.unshift('TUNNEL:');
|
||||
}
|
||||
console.error.apply(console, args);
|
||||
}
|
||||
} else {
|
||||
debug = function() {};
|
||||
}
|
||||
exports.debug = debug; // for test
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 154:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
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 __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 core = __importStar(__webpack_require__(470));
|
||||
const fs = __importStar(__webpack_require__(747));
|
||||
const Handlers_1 = __webpack_require__(941);
|
||||
const HttpClient_1 = __webpack_require__(874);
|
||||
const RestClient_1 = __webpack_require__(105);
|
||||
function getCacheUrl() {
|
||||
// Ideally we just use ACTIONS_CACHE_URL
|
||||
const cacheUrl = (process.env["ACTIONS_CACHE_URL"] ||
|
||||
process.env["ACTIONS_RUNTIME_URL"] ||
|
||||
"").replace("pipelines", "artifactcache");
|
||||
if (!cacheUrl) {
|
||||
throw new Error("Cache Service Url not found, unable to restore cache.");
|
||||
}
|
||||
core.debug(`Cache Url: ${cacheUrl}`);
|
||||
return cacheUrl;
|
||||
}
|
||||
function createAcceptHeader(type, apiVersion) {
|
||||
return `${type};api-version=${apiVersion}`;
|
||||
}
|
||||
function getRequestOptions() {
|
||||
const requestOptions = {
|
||||
acceptHeader: createAcceptHeader("application/json", "5.2-preview.1")
|
||||
};
|
||||
return requestOptions;
|
||||
}
|
||||
function getCacheEntry(keys) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const cacheUrl = getCacheUrl();
|
||||
const token = process.env["ACTIONS_RUNTIME_TOKEN"] || "";
|
||||
const bearerCredentialHandler = new Handlers_1.BearerCredentialHandler(token);
|
||||
const resource = `_apis/artifactcache/cache?keys=${encodeURIComponent(keys.join(","))}`;
|
||||
const restClient = new RestClient_1.RestClient("actions/cache", cacheUrl, [
|
||||
bearerCredentialHandler
|
||||
]);
|
||||
const response = yield restClient.get(resource, getRequestOptions());
|
||||
if (response.statusCode === 204) {
|
||||
return null;
|
||||
}
|
||||
if (response.statusCode !== 200) {
|
||||
throw new Error(`Cache service responded with ${response.statusCode}`);
|
||||
}
|
||||
const cacheResult = response.result;
|
||||
if (!cacheResult || !cacheResult.archiveLocation) {
|
||||
throw new Error("Cache not found.");
|
||||
}
|
||||
core.setSecret(cacheResult.archiveLocation);
|
||||
core.debug(`Cache Result:`);
|
||||
core.debug(JSON.stringify(cacheResult));
|
||||
return cacheResult;
|
||||
});
|
||||
}
|
||||
exports.getCacheEntry = getCacheEntry;
|
||||
function pipeResponseToStream(response, stream) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
return new Promise(resolve => {
|
||||
response.message.pipe(stream).on("close", () => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
function downloadCache(cacheEntry, archivePath) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const stream = fs.createWriteStream(archivePath);
|
||||
const httpClient = new HttpClient_1.HttpClient("actions/cache");
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const downloadResponse = yield httpClient.get(cacheEntry.archiveLocation);
|
||||
yield pipeResponseToStream(downloadResponse, stream);
|
||||
});
|
||||
}
|
||||
exports.downloadCache = downloadCache;
|
||||
function saveCache(key, archivePath) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const stream = fs.createReadStream(archivePath);
|
||||
const cacheUrl = getCacheUrl();
|
||||
const token = process.env["ACTIONS_RUNTIME_TOKEN"] || "";
|
||||
const bearerCredentialHandler = new Handlers_1.BearerCredentialHandler(token);
|
||||
const resource = `_apis/artifactcache/cache/${encodeURIComponent(key)}`;
|
||||
const postUrl = cacheUrl + resource;
|
||||
const restClient = new RestClient_1.RestClient("actions/cache", undefined, [
|
||||
bearerCredentialHandler
|
||||
]);
|
||||
const requestOptions = getRequestOptions();
|
||||
requestOptions.additionalHeaders = {
|
||||
"Content-Type": "application/octet-stream"
|
||||
};
|
||||
const response = yield restClient.uploadStream("POST", postUrl, stream, requestOptions);
|
||||
if (response.statusCode !== 200) {
|
||||
throw new Error(`Cache service responded with ${response.statusCode}`);
|
||||
}
|
||||
core.info("Cache saved successfully");
|
||||
});
|
||||
}
|
||||
exports.saveCache = saveCache;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 211:
|
||||
/***/ (function(module) {
|
||||
|
||||
module.exports = require("https");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 327:
|
||||
/***/ (function(__unusedmodule, exports) {
|
||||
|
||||
"use strict";
|
||||
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
class PersonalAccessTokenCredentialHandler {
|
||||
constructor(token) {
|
||||
this.token = token;
|
||||
}
|
||||
// currently implements pre-authorization
|
||||
// TODO: support preAuth = false where it hooks on 401
|
||||
prepareRequest(options) {
|
||||
options.headers['Authorization'] = 'Basic ' + new Buffer('PAT:' + this.token).toString('base64');
|
||||
options.headers['X-TFS-FedAuthRedirect'] = 'Suppress';
|
||||
}
|
||||
// This handler cannot handle 401
|
||||
canHandleAuthentication(response) {
|
||||
return false;
|
||||
}
|
||||
handleAuthentication(httpClient, requestInfo, objs) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
exports.PersonalAccessTokenCredentialHandler = PersonalAccessTokenCredentialHandler;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 357:
|
||||
/***/ (function(module) {
|
||||
|
||||
module.exports = require("assert");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 413:
|
||||
/***/ (function(module, __unusedexports, __webpack_require__) {
|
||||
|
||||
module.exports = __webpack_require__(141);
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 417:
|
||||
/***/ (function(module) {
|
||||
|
||||
module.exports = require("crypto");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 431:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const os = __webpack_require__(87);
|
||||
/**
|
||||
* Commands
|
||||
*
|
||||
* Command Format:
|
||||
* ##[name key=value;key=value]message
|
||||
*
|
||||
* Examples:
|
||||
* ##[warning]This is the user warning message
|
||||
* ##[set-secret name=mypassword]definitelyNotAPassword!
|
||||
*/
|
||||
function issueCommand(command, properties, message) {
|
||||
const cmd = new Command(command, properties, message);
|
||||
process.stdout.write(cmd.toString() + os.EOL);
|
||||
}
|
||||
exports.issueCommand = issueCommand;
|
||||
function issue(name, message = '') {
|
||||
issueCommand(name, {}, message);
|
||||
}
|
||||
exports.issue = issue;
|
||||
const CMD_STRING = '::';
|
||||
class Command {
|
||||
constructor(command, properties, message) {
|
||||
if (!command) {
|
||||
command = 'missing.command';
|
||||
}
|
||||
this.command = command;
|
||||
this.properties = properties;
|
||||
this.message = message;
|
||||
}
|
||||
toString() {
|
||||
let cmdStr = CMD_STRING + this.command;
|
||||
if (this.properties && Object.keys(this.properties).length > 0) {
|
||||
cmdStr += ' ';
|
||||
for (const key in this.properties) {
|
||||
if (this.properties.hasOwnProperty(key)) {
|
||||
const val = this.properties[key];
|
||||
if (val) {
|
||||
// safely append the val - avoid blowing up when attempting to
|
||||
// call .replace() if message is not a string for some reason
|
||||
cmdStr += `${key}=${escape(`${val || ''}`)},`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
cmdStr += CMD_STRING;
|
||||
// safely append the message - avoid blowing up when attempting to
|
||||
// call .replace() if message is not a string for some reason
|
||||
const message = `${this.message || ''}`;
|
||||
cmdStr += escapeData(message);
|
||||
return cmdStr;
|
||||
}
|
||||
}
|
||||
function escapeData(s) {
|
||||
return s.replace(/\r/g, '%0D').replace(/\n/g, '%0A');
|
||||
}
|
||||
function escape(s) {
|
||||
return s
|
||||
.replace(/\r/g, '%0D')
|
||||
.replace(/\n/g, '%0A')
|
||||
.replace(/]/g, '%5D')
|
||||
.replace(/;/g, '%3B');
|
||||
}
|
||||
//# sourceMappingURL=command.js.map
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 432:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
var crypto = __webpack_require__(417);
|
||||
|
||||
var flags = {
|
||||
NTLM_NegotiateUnicode : 0x00000001,
|
||||
NTLM_NegotiateOEM : 0x00000002,
|
||||
NTLM_RequestTarget : 0x00000004,
|
||||
NTLM_Unknown9 : 0x00000008,
|
||||
NTLM_NegotiateSign : 0x00000010,
|
||||
NTLM_NegotiateSeal : 0x00000020,
|
||||
NTLM_NegotiateDatagram : 0x00000040,
|
||||
NTLM_NegotiateLanManagerKey : 0x00000080,
|
||||
NTLM_Unknown8 : 0x00000100,
|
||||
NTLM_NegotiateNTLM : 0x00000200,
|
||||
NTLM_NegotiateNTOnly : 0x00000400,
|
||||
NTLM_Anonymous : 0x00000800,
|
||||
NTLM_NegotiateOemDomainSupplied : 0x00001000,
|
||||
NTLM_NegotiateOemWorkstationSupplied : 0x00002000,
|
||||
NTLM_Unknown6 : 0x00004000,
|
||||
NTLM_NegotiateAlwaysSign : 0x00008000,
|
||||
NTLM_TargetTypeDomain : 0x00010000,
|
||||
NTLM_TargetTypeServer : 0x00020000,
|
||||
NTLM_TargetTypeShare : 0x00040000,
|
||||
NTLM_NegotiateExtendedSecurity : 0x00080000,
|
||||
NTLM_NegotiateIdentify : 0x00100000,
|
||||
NTLM_Unknown5 : 0x00200000,
|
||||
NTLM_RequestNonNTSessionKey : 0x00400000,
|
||||
NTLM_NegotiateTargetInfo : 0x00800000,
|
||||
NTLM_Unknown4 : 0x01000000,
|
||||
NTLM_NegotiateVersion : 0x02000000,
|
||||
NTLM_Unknown3 : 0x04000000,
|
||||
NTLM_Unknown2 : 0x08000000,
|
||||
NTLM_Unknown1 : 0x10000000,
|
||||
NTLM_Negotiate128 : 0x20000000,
|
||||
NTLM_NegotiateKeyExchange : 0x40000000,
|
||||
NTLM_Negotiate56 : 0x80000000
|
||||
};
|
||||
var typeflags = {
|
||||
NTLM_TYPE1_FLAGS : flags.NTLM_NegotiateUnicode
|
||||
+ flags.NTLM_NegotiateOEM
|
||||
+ flags.NTLM_RequestTarget
|
||||
+ flags.NTLM_NegotiateNTLM
|
||||
+ flags.NTLM_NegotiateOemDomainSupplied
|
||||
+ flags.NTLM_NegotiateOemWorkstationSupplied
|
||||
+ flags.NTLM_NegotiateAlwaysSign
|
||||
+ flags.NTLM_NegotiateExtendedSecurity
|
||||
+ flags.NTLM_NegotiateVersion
|
||||
+ flags.NTLM_Negotiate128
|
||||
+ flags.NTLM_Negotiate56,
|
||||
|
||||
NTLM_TYPE2_FLAGS : flags.NTLM_NegotiateUnicode
|
||||
+ flags.NTLM_RequestTarget
|
||||
+ flags.NTLM_NegotiateNTLM
|
||||
+ flags.NTLM_NegotiateAlwaysSign
|
||||
+ flags.NTLM_NegotiateExtendedSecurity
|
||||
+ flags.NTLM_NegotiateTargetInfo
|
||||
+ flags.NTLM_NegotiateVersion
|
||||
+ flags.NTLM_Negotiate128
|
||||
+ flags.NTLM_Negotiate56
|
||||
};
|
||||
|
||||
function createType1Message(options){
|
||||
var domain = escape(options.domain.toUpperCase());
|
||||
var workstation = escape(options.workstation.toUpperCase());
|
||||
var protocol = 'NTLMSSP\0';
|
||||
|
||||
var BODY_LENGTH = 40;
|
||||
|
||||
var type1flags = typeflags.NTLM_TYPE1_FLAGS;
|
||||
if(!domain || domain === '')
|
||||
type1flags = type1flags - flags.NTLM_NegotiateOemDomainSupplied;
|
||||
|
||||
var pos = 0;
|
||||
var buf = new Buffer(BODY_LENGTH + domain.length + workstation.length);
|
||||
|
||||
|
||||
buf.write(protocol, pos, protocol.length); pos += protocol.length; // protocol
|
||||
buf.writeUInt32LE(1, pos); pos += 4; // type 1
|
||||
buf.writeUInt32LE(type1flags, pos); pos += 4; // TYPE1 flag
|
||||
|
||||
buf.writeUInt16LE(domain.length, pos); pos += 2; // domain length
|
||||
buf.writeUInt16LE(domain.length, pos); pos += 2; // domain max length
|
||||
buf.writeUInt32LE(BODY_LENGTH + workstation.length, pos); pos += 4; // domain buffer offset
|
||||
|
||||
buf.writeUInt16LE(workstation.length, pos); pos += 2; // workstation length
|
||||
buf.writeUInt16LE(workstation.length, pos); pos += 2; // workstation max length
|
||||
buf.writeUInt32LE(BODY_LENGTH, pos); pos += 4; // workstation buffer offset
|
||||
|
||||
buf.writeUInt8(5, pos); pos += 1; //ProductMajorVersion
|
||||
buf.writeUInt8(1, pos); pos += 1; //ProductMinorVersion
|
||||
buf.writeUInt16LE(2600, pos); pos += 2; //ProductBuild
|
||||
|
||||
buf.writeUInt8(0 , pos); pos += 1; //VersionReserved1
|
||||
buf.writeUInt8(0 , pos); pos += 1; //VersionReserved2
|
||||
buf.writeUInt8(0 , pos); pos += 1; //VersionReserved3
|
||||
buf.writeUInt8(15, pos); pos += 1; //NTLMRevisionCurrent
|
||||
|
||||
buf.write(workstation, pos, workstation.length, 'ascii'); pos += workstation.length; // workstation string
|
||||
buf.write(domain , pos, domain.length , 'ascii'); pos += domain.length;
|
||||
|
||||
return 'NTLM ' + buf.toString('base64');
|
||||
}
|
||||
|
||||
function parseType2Message(rawmsg, callback){
|
||||
var match = rawmsg.match(/NTLM (.+)?/);
|
||||
if(!match || !match[1])
|
||||
return callback(new Error("Couldn't find NTLM in the message type2 comming from the server"));
|
||||
|
||||
var buf = new Buffer(match[1], 'base64');
|
||||
|
||||
var msg = {};
|
||||
|
||||
msg.signature = buf.slice(0, 8);
|
||||
msg.type = buf.readInt16LE(8);
|
||||
|
||||
if(msg.type != 2)
|
||||
return callback(new Error("Server didn't return a type 2 message"));
|
||||
|
||||
msg.targetNameLen = buf.readInt16LE(12);
|
||||
msg.targetNameMaxLen = buf.readInt16LE(14);
|
||||
msg.targetNameOffset = buf.readInt32LE(16);
|
||||
msg.targetName = buf.slice(msg.targetNameOffset, msg.targetNameOffset + msg.targetNameMaxLen);
|
||||
|
||||
msg.negotiateFlags = buf.readInt32LE(20);
|
||||
msg.serverChallenge = buf.slice(24, 32);
|
||||
msg.reserved = buf.slice(32, 40);
|
||||
|
||||
if(msg.negotiateFlags & flags.NTLM_NegotiateTargetInfo){
|
||||
msg.targetInfoLen = buf.readInt16LE(40);
|
||||
msg.targetInfoMaxLen = buf.readInt16LE(42);
|
||||
msg.targetInfoOffset = buf.readInt32LE(44);
|
||||
msg.targetInfo = buf.slice(msg.targetInfoOffset, msg.targetInfoOffset + msg.targetInfoLen);
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
function createType3Message(msg2, options){
|
||||
var nonce = msg2.serverChallenge;
|
||||
var username = options.username;
|
||||
var password = options.password;
|
||||
var negotiateFlags = msg2.negotiateFlags;
|
||||
|
||||
var isUnicode = negotiateFlags & flags.NTLM_NegotiateUnicode;
|
||||
var isNegotiateExtendedSecurity = negotiateFlags & flags.NTLM_NegotiateExtendedSecurity;
|
||||
|
||||
var BODY_LENGTH = 72;
|
||||
|
||||
var domainName = escape(options.domain.toUpperCase());
|
||||
var workstation = escape(options.workstation.toUpperCase());
|
||||
|
||||
var workstationBytes, domainNameBytes, usernameBytes, encryptedRandomSessionKeyBytes;
|
||||
|
||||
var encryptedRandomSessionKey = "";
|
||||
if(isUnicode){
|
||||
workstationBytes = new Buffer(workstation, 'utf16le');
|
||||
domainNameBytes = new Buffer(domainName, 'utf16le');
|
||||
usernameBytes = new Buffer(username, 'utf16le');
|
||||
encryptedRandomSessionKeyBytes = new Buffer(encryptedRandomSessionKey, 'utf16le');
|
||||
}else{
|
||||
workstationBytes = new Buffer(workstation, 'ascii');
|
||||
domainNameBytes = new Buffer(domainName, 'ascii');
|
||||
usernameBytes = new Buffer(username, 'ascii');
|
||||
encryptedRandomSessionKeyBytes = new Buffer(encryptedRandomSessionKey, 'ascii');
|
||||
}
|
||||
|
||||
var lmChallengeResponse = calc_resp(create_LM_hashed_password_v1(password), nonce);
|
||||
var ntChallengeResponse = calc_resp(create_NT_hashed_password_v1(password), nonce);
|
||||
|
||||
if(isNegotiateExtendedSecurity){
|
||||
var pwhash = create_NT_hashed_password_v1(password);
|
||||
var clientChallenge = "";
|
||||
for(var i=0; i < 8; i++){
|
||||
clientChallenge += String.fromCharCode( Math.floor(Math.random()*256) );
|
||||
}
|
||||
var clientChallengeBytes = new Buffer(clientChallenge, 'ascii');
|
||||
var challenges = ntlm2sr_calc_resp(pwhash, nonce, clientChallengeBytes);
|
||||
lmChallengeResponse = challenges.lmChallengeResponse;
|
||||
ntChallengeResponse = challenges.ntChallengeResponse;
|
||||
}
|
||||
|
||||
var signature = 'NTLMSSP\0';
|
||||
|
||||
var pos = 0;
|
||||
var buf = new Buffer(BODY_LENGTH + domainNameBytes.length + usernameBytes.length + workstationBytes.length + lmChallengeResponse.length + ntChallengeResponse.length + encryptedRandomSessionKeyBytes.length);
|
||||
|
||||
buf.write(signature, pos, signature.length); pos += signature.length;
|
||||
buf.writeUInt32LE(3, pos); pos += 4; // type 1
|
||||
|
||||
buf.writeUInt16LE(lmChallengeResponse.length, pos); pos += 2; // LmChallengeResponseLen
|
||||
buf.writeUInt16LE(lmChallengeResponse.length, pos); pos += 2; // LmChallengeResponseMaxLen
|
||||
buf.writeUInt32LE(BODY_LENGTH + domainNameBytes.length + usernameBytes.length + workstationBytes.length, pos); pos += 4; // LmChallengeResponseOffset
|
||||
|
||||
buf.writeUInt16LE(ntChallengeResponse.length, pos); pos += 2; // NtChallengeResponseLen
|
||||
buf.writeUInt16LE(ntChallengeResponse.length, pos); pos += 2; // NtChallengeResponseMaxLen
|
||||
buf.writeUInt32LE(BODY_LENGTH + domainNameBytes.length + usernameBytes.length + workstationBytes.length + lmChallengeResponse.length, pos); pos += 4; // NtChallengeResponseOffset
|
||||
|
||||
buf.writeUInt16LE(domainNameBytes.length, pos); pos += 2; // DomainNameLen
|
||||
buf.writeUInt16LE(domainNameBytes.length, pos); pos += 2; // DomainNameMaxLen
|
||||
buf.writeUInt32LE(BODY_LENGTH, pos); pos += 4; // DomainNameOffset
|
||||
|
||||
buf.writeUInt16LE(usernameBytes.length, pos); pos += 2; // UserNameLen
|
||||
buf.writeUInt16LE(usernameBytes.length, pos); pos += 2; // UserNameMaxLen
|
||||
buf.writeUInt32LE(BODY_LENGTH + domainNameBytes.length, pos); pos += 4; // UserNameOffset
|
||||
|
||||
buf.writeUInt16LE(workstationBytes.length, pos); pos += 2; // WorkstationLen
|
||||
buf.writeUInt16LE(workstationBytes.length, pos); pos += 2; // WorkstationMaxLen
|
||||
buf.writeUInt32LE(BODY_LENGTH + domainNameBytes.length + usernameBytes.length, pos); pos += 4; // WorkstationOffset
|
||||
|
||||
buf.writeUInt16LE(encryptedRandomSessionKeyBytes.length, pos); pos += 2; // EncryptedRandomSessionKeyLen
|
||||
buf.writeUInt16LE(encryptedRandomSessionKeyBytes.length, pos); pos += 2; // EncryptedRandomSessionKeyMaxLen
|
||||
buf.writeUInt32LE(BODY_LENGTH + domainNameBytes.length + usernameBytes.length + workstationBytes.length + lmChallengeResponse.length + ntChallengeResponse.length, pos); pos += 4; // EncryptedRandomSessionKeyOffset
|
||||
|
||||
buf.writeUInt32LE(typeflags.NTLM_TYPE2_FLAGS, pos); pos += 4; // NegotiateFlags
|
||||
|
||||
buf.writeUInt8(5, pos); pos++; // ProductMajorVersion
|
||||
buf.writeUInt8(1, pos); pos++; // ProductMinorVersion
|
||||
buf.writeUInt16LE(2600, pos); pos += 2; // ProductBuild
|
||||
buf.writeUInt8(0, pos); pos++; // VersionReserved1
|
||||
buf.writeUInt8(0, pos); pos++; // VersionReserved2
|
||||
buf.writeUInt8(0, pos); pos++; // VersionReserved3
|
||||
buf.writeUInt8(15, pos); pos++; // NTLMRevisionCurrent
|
||||
|
||||
domainNameBytes.copy(buf, pos); pos += domainNameBytes.length;
|
||||
usernameBytes.copy(buf, pos); pos += usernameBytes.length;
|
||||
workstationBytes.copy(buf, pos); pos += workstationBytes.length;
|
||||
lmChallengeResponse.copy(buf, pos); pos += lmChallengeResponse.length;
|
||||
ntChallengeResponse.copy(buf, pos); pos += ntChallengeResponse.length;
|
||||
encryptedRandomSessionKeyBytes.copy(buf, pos); pos += encryptedRandomSessionKeyBytes.length;
|
||||
|
||||
return 'NTLM ' + buf.toString('base64');
|
||||
}
|
||||
|
||||
function create_LM_hashed_password_v1(password){
|
||||
// fix the password length to 14 bytes
|
||||
password = password.toUpperCase();
|
||||
var passwordBytes = new Buffer(password, 'ascii');
|
||||
|
||||
var passwordBytesPadded = new Buffer(14);
|
||||
passwordBytesPadded.fill("\0");
|
||||
var sourceEnd = 14;
|
||||
if(passwordBytes.length < 14) sourceEnd = passwordBytes.length;
|
||||
passwordBytes.copy(passwordBytesPadded, 0, 0, sourceEnd);
|
||||
|
||||
// split into 2 parts of 7 bytes:
|
||||
var firstPart = passwordBytesPadded.slice(0,7);
|
||||
var secondPart = passwordBytesPadded.slice(7);
|
||||
|
||||
function encrypt(buf){
|
||||
var key = insertZerosEvery7Bits(buf);
|
||||
var des = crypto.createCipheriv('DES-ECB', key, '');
|
||||
return des.update("KGS!@#$%"); // page 57 in [MS-NLMP]);
|
||||
}
|
||||
|
||||
var firstPartEncrypted = encrypt(firstPart);
|
||||
var secondPartEncrypted = encrypt(secondPart);
|
||||
|
||||
return Buffer.concat([firstPartEncrypted, secondPartEncrypted]);
|
||||
}
|
||||
|
||||
function insertZerosEvery7Bits(buf){
|
||||
var binaryArray = bytes2binaryArray(buf);
|
||||
var newBinaryArray = [];
|
||||
for(var i=0; i<binaryArray.length; i++){
|
||||
newBinaryArray.push(binaryArray[i]);
|
||||
|
||||
if((i+1)%7 === 0){
|
||||
newBinaryArray.push(0);
|
||||
}
|
||||
}
|
||||
return binaryArray2bytes(newBinaryArray);
|
||||
}
|
||||
|
||||
function bytes2binaryArray(buf){
|
||||
var hex2binary = {
|
||||
0: [0,0,0,0],
|
||||
1: [0,0,0,1],
|
||||
2: [0,0,1,0],
|
||||
3: [0,0,1,1],
|
||||
4: [0,1,0,0],
|
||||
5: [0,1,0,1],
|
||||
6: [0,1,1,0],
|
||||
7: [0,1,1,1],
|
||||
8: [1,0,0,0],
|
||||
9: [1,0,0,1],
|
||||
A: [1,0,1,0],
|
||||
B: [1,0,1,1],
|
||||
C: [1,1,0,0],
|
||||
D: [1,1,0,1],
|
||||
E: [1,1,1,0],
|
||||
F: [1,1,1,1]
|
||||
};
|
||||
|
||||
var hexString = buf.toString('hex').toUpperCase();
|
||||
var array = [];
|
||||
for(var i=0; i<hexString.length; i++){
|
||||
var hexchar = hexString.charAt(i);
|
||||
array = array.concat(hex2binary[hexchar]);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
function binaryArray2bytes(array){
|
||||
var binary2hex = {
|
||||
'0000': 0,
|
||||
'0001': 1,
|
||||
'0010': 2,
|
||||
'0011': 3,
|
||||
'0100': 4,
|
||||
'0101': 5,
|
||||
'0110': 6,
|
||||
'0111': 7,
|
||||
'1000': 8,
|
||||
'1001': 9,
|
||||
'1010': 'A',
|
||||
'1011': 'B',
|
||||
'1100': 'C',
|
||||
'1101': 'D',
|
||||
'1110': 'E',
|
||||
'1111': 'F'
|
||||
};
|
||||
|
||||
var bufArray = [];
|
||||
|
||||
for(var i=0; i<array.length; i +=8 ){
|
||||
if((i+7) > array.length)
|
||||
break;
|
||||
|
||||
var binString1 = '' + array[i] + '' + array[i+1] + '' + array[i+2] + '' + array[i+3];
|
||||
var binString2 = '' + array[i+4] + '' + array[i+5] + '' + array[i+6] + '' + array[i+7];
|
||||
var hexchar1 = binary2hex[binString1];
|
||||
var hexchar2 = binary2hex[binString2];
|
||||
|
||||
var buf = new Buffer(hexchar1 + '' + hexchar2, 'hex');
|
||||
bufArray.push(buf);
|
||||
}
|
||||
|
||||
return Buffer.concat(bufArray);
|
||||
}
|
||||
|
||||
function create_NT_hashed_password_v1(password){
|
||||
var buf = new Buffer(password, 'utf16le');
|
||||
var md4 = crypto.createHash('md4');
|
||||
md4.update(buf);
|
||||
return new Buffer(md4.digest());
|
||||
}
|
||||
|
||||
function calc_resp(password_hash, server_challenge){
|
||||
// padding with zeros to make the hash 21 bytes long
|
||||
var passHashPadded = new Buffer(21);
|
||||
passHashPadded.fill("\0");
|
||||
password_hash.copy(passHashPadded, 0, 0, password_hash.length);
|
||||
|
||||
var resArray = [];
|
||||
|
||||
var des = crypto.createCipheriv('DES-ECB', insertZerosEvery7Bits(passHashPadded.slice(0,7)), '');
|
||||
resArray.push( des.update(server_challenge.slice(0,8)) );
|
||||
|
||||
des = crypto.createCipheriv('DES-ECB', insertZerosEvery7Bits(passHashPadded.slice(7,14)), '');
|
||||
resArray.push( des.update(server_challenge.slice(0,8)) );
|
||||
|
||||
des = crypto.createCipheriv('DES-ECB', insertZerosEvery7Bits(passHashPadded.slice(14,21)), '');
|
||||
resArray.push( des.update(server_challenge.slice(0,8)) );
|
||||
|
||||
return Buffer.concat(resArray);
|
||||
}
|
||||
|
||||
function ntlm2sr_calc_resp(responseKeyNT, serverChallenge, clientChallenge){
|
||||
// padding with zeros to make the hash 16 bytes longer
|
||||
var lmChallengeResponse = new Buffer(clientChallenge.length + 16);
|
||||
lmChallengeResponse.fill("\0");
|
||||
clientChallenge.copy(lmChallengeResponse, 0, 0, clientChallenge.length);
|
||||
|
||||
var buf = Buffer.concat([serverChallenge, clientChallenge]);
|
||||
var md5 = crypto.createHash('md5');
|
||||
md5.update(buf);
|
||||
var sess = md5.digest();
|
||||
var ntChallengeResponse = calc_resp(responseKeyNT, sess.slice(0,8));
|
||||
|
||||
return {
|
||||
lmChallengeResponse: lmChallengeResponse,
|
||||
ntChallengeResponse: ntChallengeResponse
|
||||
};
|
||||
}
|
||||
|
||||
exports.createType1Message = createType1Message;
|
||||
exports.parseType2Message = parseType2Message;
|
||||
exports.createType3Message = createType3Message;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 443:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
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 __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 core = __importStar(__webpack_require__(470));
|
||||
const io = __importStar(__webpack_require__(1));
|
||||
const fs = __importStar(__webpack_require__(747));
|
||||
const os = __importStar(__webpack_require__(87));
|
||||
const path = __importStar(__webpack_require__(622));
|
||||
const uuidV4 = __importStar(__webpack_require__(826));
|
||||
const constants_1 = __webpack_require__(694);
|
||||
// From https://github.com/actions/toolkit/blob/master/packages/tool-cache/src/tool-cache.ts#L23
|
||||
function createTempDirectory() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const IS_WINDOWS = process.platform === "win32";
|
||||
let tempDirectory = process.env["RUNNER_TEMP"] || "";
|
||||
if (!tempDirectory) {
|
||||
let baseLocation;
|
||||
if (IS_WINDOWS) {
|
||||
// On Windows use the USERPROFILE env variable
|
||||
baseLocation = process.env["USERPROFILE"] || "C:\\";
|
||||
}
|
||||
else {
|
||||
if (process.platform === "darwin") {
|
||||
baseLocation = "/Users";
|
||||
}
|
||||
else {
|
||||
baseLocation = "/home";
|
||||
}
|
||||
}
|
||||
tempDirectory = path.join(baseLocation, "actions", "temp");
|
||||
}
|
||||
const dest = path.join(tempDirectory, uuidV4.default());
|
||||
yield io.mkdirP(dest);
|
||||
return dest;
|
||||
});
|
||||
}
|
||||
exports.createTempDirectory = createTempDirectory;
|
||||
function getArchiveFileSize(path) {
|
||||
return fs.statSync(path).size;
|
||||
}
|
||||
exports.getArchiveFileSize = getArchiveFileSize;
|
||||
function isExactKeyMatch(key, cacheResult) {
|
||||
return !!(cacheResult &&
|
||||
cacheResult.cacheKey &&
|
||||
cacheResult.cacheKey.localeCompare(key, undefined, {
|
||||
sensitivity: "accent"
|
||||
}) === 0);
|
||||
}
|
||||
exports.isExactKeyMatch = isExactKeyMatch;
|
||||
function setCacheState(state) {
|
||||
core.saveState(constants_1.State.CacheResult, JSON.stringify(state));
|
||||
}
|
||||
exports.setCacheState = setCacheState;
|
||||
function setCacheHitOutput(isCacheHit) {
|
||||
core.setOutput(constants_1.Outputs.CacheHit, isCacheHit.toString());
|
||||
}
|
||||
exports.setCacheHitOutput = setCacheHitOutput;
|
||||
function setOutputAndState(key, cacheResult) {
|
||||
setCacheHitOutput(isExactKeyMatch(key, cacheResult));
|
||||
// Store the cache result if it exists
|
||||
cacheResult && setCacheState(cacheResult);
|
||||
}
|
||||
exports.setOutputAndState = setOutputAndState;
|
||||
function getCacheState() {
|
||||
const stateData = core.getState(constants_1.State.CacheResult);
|
||||
core.debug(`State: ${stateData}`);
|
||||
if (stateData) {
|
||||
return JSON.parse(stateData);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
exports.getCacheState = getCacheState;
|
||||
function logWarning(message) {
|
||||
const warningPrefix = "[warning]";
|
||||
core.info(`${warningPrefix}${message}`);
|
||||
}
|
||||
exports.logWarning = logWarning;
|
||||
function resolvePath(filePath) {
|
||||
if (filePath[0] === "~") {
|
||||
const home = os.homedir();
|
||||
if (!home) {
|
||||
throw new Error("Unable to resolve `~` to HOME");
|
||||
}
|
||||
return path.join(home, filePath.slice(1));
|
||||
}
|
||||
return path.resolve(filePath);
|
||||
}
|
||||
exports.resolvePath = resolvePath;
|
||||
function getSupportedEvents() {
|
||||
return [constants_1.Events.Push, constants_1.Events.PullRequest];
|
||||
}
|
||||
exports.getSupportedEvents = getSupportedEvents;
|
||||
// Currently the cache token is only authorized for push and pull_request events
|
||||
// All other events will fail when reading and saving the cache
|
||||
// See GitHub Context https://help.github.com/actions/automating-your-workflow-with-github-actions/contexts-and-expression-syntax-for-github-actions#github-context
|
||||
function isValidEvent() {
|
||||
const githubEvent = process.env[constants_1.Events.Key] || "";
|
||||
return getSupportedEvents().includes(githubEvent);
|
||||
}
|
||||
exports.isValidEvent = isValidEvent;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 470:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
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());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const command_1 = __webpack_require__(431);
|
||||
const os = __webpack_require__(87);
|
||||
const path = __webpack_require__(622);
|
||||
/**
|
||||
* The code to exit an action
|
||||
*/
|
||||
var ExitCode;
|
||||
(function (ExitCode) {
|
||||
/**
|
||||
* A code indicating that the action was successful
|
||||
*/
|
||||
ExitCode[ExitCode["Success"] = 0] = "Success";
|
||||
/**
|
||||
* A code indicating that the action was a failure
|
||||
*/
|
||||
ExitCode[ExitCode["Failure"] = 1] = "Failure";
|
||||
})(ExitCode = exports.ExitCode || (exports.ExitCode = {}));
|
||||
//-----------------------------------------------------------------------
|
||||
// Variables
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Sets env variable for this action and future actions in the job
|
||||
* @param name the name of the variable to set
|
||||
* @param val the value of the variable
|
||||
*/
|
||||
function exportVariable(name, val) {
|
||||
process.env[name] = val;
|
||||
command_1.issueCommand('set-env', { name }, val);
|
||||
}
|
||||
exports.exportVariable = exportVariable;
|
||||
/**
|
||||
* Registers a secret which will get masked from logs
|
||||
* @param secret value of the secret
|
||||
*/
|
||||
function setSecret(secret) {
|
||||
command_1.issueCommand('add-mask', {}, secret);
|
||||
}
|
||||
exports.setSecret = setSecret;
|
||||
/**
|
||||
* Prepends inputPath to the PATH (for this action and future actions)
|
||||
* @param inputPath
|
||||
*/
|
||||
function addPath(inputPath) {
|
||||
command_1.issueCommand('add-path', {}, inputPath);
|
||||
process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`;
|
||||
}
|
||||
exports.addPath = addPath;
|
||||
/**
|
||||
* Gets the value of an input. The value is also trimmed.
|
||||
*
|
||||
* @param name name of the input to get
|
||||
* @param options optional. See InputOptions.
|
||||
* @returns string
|
||||
*/
|
||||
function getInput(name, options) {
|
||||
const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || '';
|
||||
if (options && options.required && !val) {
|
||||
throw new Error(`Input required and not supplied: ${name}`);
|
||||
}
|
||||
return val.trim();
|
||||
}
|
||||
exports.getInput = getInput;
|
||||
/**
|
||||
* Sets the value of an output.
|
||||
*
|
||||
* @param name name of the output to set
|
||||
* @param value value to store
|
||||
*/
|
||||
function setOutput(name, value) {
|
||||
command_1.issueCommand('set-output', { name }, value);
|
||||
}
|
||||
exports.setOutput = setOutput;
|
||||
//-----------------------------------------------------------------------
|
||||
// Results
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Sets the action status to failed.
|
||||
* When the action exits it will be with an exit code of 1
|
||||
* @param message add error issue message
|
||||
*/
|
||||
function setFailed(message) {
|
||||
process.exitCode = ExitCode.Failure;
|
||||
error(message);
|
||||
}
|
||||
exports.setFailed = setFailed;
|
||||
//-----------------------------------------------------------------------
|
||||
// Logging Commands
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Writes debug message to user log
|
||||
* @param message debug message
|
||||
*/
|
||||
function debug(message) {
|
||||
command_1.issueCommand('debug', {}, message);
|
||||
}
|
||||
exports.debug = debug;
|
||||
/**
|
||||
* Adds an error issue
|
||||
* @param message error issue message
|
||||
*/
|
||||
function error(message) {
|
||||
command_1.issue('error', message);
|
||||
}
|
||||
exports.error = error;
|
||||
/**
|
||||
* Adds an warning issue
|
||||
* @param message warning issue message
|
||||
*/
|
||||
function warning(message) {
|
||||
command_1.issue('warning', message);
|
||||
}
|
||||
exports.warning = warning;
|
||||
/**
|
||||
* Writes info to log with console.log.
|
||||
* @param message info message
|
||||
*/
|
||||
function info(message) {
|
||||
process.stdout.write(message + os.EOL);
|
||||
}
|
||||
exports.info = info;
|
||||
/**
|
||||
* Begin an output group.
|
||||
*
|
||||
* Output until the next `groupEnd` will be foldable in this group
|
||||
*
|
||||
* @param name The name of the output group
|
||||
*/
|
||||
function startGroup(name) {
|
||||
command_1.issue('group', name);
|
||||
}
|
||||
exports.startGroup = startGroup;
|
||||
/**
|
||||
* End an output group.
|
||||
*/
|
||||
function endGroup() {
|
||||
command_1.issue('endgroup');
|
||||
}
|
||||
exports.endGroup = endGroup;
|
||||
/**
|
||||
* Wrap an asynchronous function call in a group.
|
||||
*
|
||||
* Returns the same type as the function itself.
|
||||
*
|
||||
* @param name The name of the group
|
||||
* @param fn The function to wrap in the group
|
||||
*/
|
||||
function group(name, fn) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
startGroup(name);
|
||||
let result;
|
||||
try {
|
||||
result = yield fn();
|
||||
}
|
||||
finally {
|
||||
endGroup();
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
exports.group = group;
|
||||
//-----------------------------------------------------------------------
|
||||
// Wrapper action state
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Saves state for current action, the state can only be retrieved by this action's post job execution.
|
||||
*
|
||||
* @param name name of the state to store
|
||||
* @param value value to store
|
||||
*/
|
||||
function saveState(name, value) {
|
||||
command_1.issueCommand('save-state', { name }, value);
|
||||
}
|
||||
exports.saveState = saveState;
|
||||
/**
|
||||
* Gets the value of an state set by this action's main execution.
|
||||
*
|
||||
* @param name name of the state to get
|
||||
* @returns string
|
||||
*/
|
||||
function getState(name) {
|
||||
return process.env[`STATE_${name}`] || '';
|
||||
}
|
||||
exports.getState = getState;
|
||||
//# sourceMappingURL=core.js.map
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 525:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const http = __webpack_require__(605);
|
||||
const https = __webpack_require__(211);
|
||||
const _ = __webpack_require__(891);
|
||||
const ntlm = __webpack_require__(432);
|
||||
class NtlmCredentialHandler {
|
||||
constructor(username, password, workstation, domain) {
|
||||
this._ntlmOptions = {};
|
||||
this._ntlmOptions.username = username;
|
||||
this._ntlmOptions.password = password;
|
||||
if (domain !== undefined) {
|
||||
this._ntlmOptions.domain = domain;
|
||||
}
|
||||
else {
|
||||
this._ntlmOptions.domain = '';
|
||||
}
|
||||
if (workstation !== undefined) {
|
||||
this._ntlmOptions.workstation = workstation;
|
||||
}
|
||||
else {
|
||||
this._ntlmOptions.workstation = '';
|
||||
}
|
||||
}
|
||||
prepareRequest(options) {
|
||||
// No headers or options need to be set. We keep the credentials on the handler itself.
|
||||
// If a (proxy) agent is set, remove it as we don't support proxy for NTLM at this time
|
||||
if (options.agent) {
|
||||
delete options.agent;
|
||||
}
|
||||
}
|
||||
canHandleAuthentication(response) {
|
||||
if (response && response.message && response.message.statusCode === 401) {
|
||||
// Ensure that we're talking NTLM here
|
||||
// Once we have the www-authenticate header, split it so we can ensure we can talk NTLM
|
||||
const wwwAuthenticate = response.message.headers['www-authenticate'];
|
||||
if (wwwAuthenticate) {
|
||||
const mechanisms = wwwAuthenticate.split(', ');
|
||||
const index = mechanisms.indexOf("NTLM");
|
||||
if (index >= 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
handleAuthentication(httpClient, requestInfo, objs) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const callbackForResult = function (err, res) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
}
|
||||
// We have to readbody on the response before continuing otherwise there is a hang.
|
||||
res.readBody().then(() => {
|
||||
resolve(res);
|
||||
});
|
||||
};
|
||||
this.handleAuthenticationPrivate(httpClient, requestInfo, objs, callbackForResult);
|
||||
});
|
||||
}
|
||||
handleAuthenticationPrivate(httpClient, requestInfo, objs, finalCallback) {
|
||||
// Set up the headers for NTLM authentication
|
||||
requestInfo.options = _.extend(requestInfo.options, {
|
||||
username: this._ntlmOptions.username,
|
||||
password: this._ntlmOptions.password,
|
||||
domain: this._ntlmOptions.domain,
|
||||
workstation: this._ntlmOptions.workstation
|
||||
});
|
||||
if (httpClient.isSsl === true) {
|
||||
requestInfo.options.agent = new https.Agent({ keepAlive: true });
|
||||
}
|
||||
else {
|
||||
requestInfo.options.agent = new http.Agent({ keepAlive: true });
|
||||
}
|
||||
let self = this;
|
||||
// The following pattern of sending the type1 message following immediately (in a setImmediate) is
|
||||
// critical for the NTLM exchange to happen. If we removed setImmediate (or call in a different manner)
|
||||
// the NTLM exchange will always fail with a 401.
|
||||
this.sendType1Message(httpClient, requestInfo, objs, function (err, res) {
|
||||
if (err) {
|
||||
return finalCallback(err, null, null);
|
||||
}
|
||||
/// We have to readbody on the response before continuing otherwise there is a hang.
|
||||
res.readBody().then(() => {
|
||||
// It is critical that we have setImmediate here due to how connection requests are queued.
|
||||
// If setImmediate is removed then the NTLM handshake will not work.
|
||||
// setImmediate allows us to queue a second request on the same connection. If this second
|
||||
// request is not queued on the connection when the first request finishes then node closes
|
||||
// the connection. NTLM requires both requests to be on the same connection so we need this.
|
||||
setImmediate(function () {
|
||||
self.sendType3Message(httpClient, requestInfo, objs, res, finalCallback);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
// The following method is an adaptation of code found at https://github.com/SamDecrock/node-http-ntlm/blob/master/httpntlm.js
|
||||
sendType1Message(httpClient, requestInfo, objs, finalCallback) {
|
||||
const type1msg = ntlm.createType1Message(this._ntlmOptions);
|
||||
const type1options = {
|
||||
headers: {
|
||||
'Connection': 'keep-alive',
|
||||
'Authorization': type1msg
|
||||
},
|
||||
timeout: requestInfo.options.timeout || 0,
|
||||
agent: requestInfo.httpModule,
|
||||
};
|
||||
const type1info = {};
|
||||
type1info.httpModule = requestInfo.httpModule;
|
||||
type1info.parsedUrl = requestInfo.parsedUrl;
|
||||
type1info.options = _.extend(type1options, _.omit(requestInfo.options, 'headers'));
|
||||
return httpClient.requestRawWithCallback(type1info, objs, finalCallback);
|
||||
}
|
||||
// The following method is an adaptation of code found at https://github.com/SamDecrock/node-http-ntlm/blob/master/httpntlm.js
|
||||
sendType3Message(httpClient, requestInfo, objs, res, callback) {
|
||||
if (!res.message.headers && !res.message.headers['www-authenticate']) {
|
||||
throw new Error('www-authenticate not found on response of second request');
|
||||
}
|
||||
const type2msg = ntlm.parseType2Message(res.message.headers['www-authenticate']);
|
||||
const type3msg = ntlm.createType3Message(type2msg, this._ntlmOptions);
|
||||
const type3options = {
|
||||
headers: {
|
||||
'Authorization': type3msg,
|
||||
'Connection': 'Close'
|
||||
},
|
||||
agent: requestInfo.httpModule,
|
||||
};
|
||||
const type3info = {};
|
||||
type3info.httpModule = requestInfo.httpModule;
|
||||
type3info.parsedUrl = requestInfo.parsedUrl;
|
||||
type3options.headers = _.extend(type3options.headers, requestInfo.options.headers);
|
||||
type3info.options = _.extend(type3options, _.omit(requestInfo.options, 'headers'));
|
||||
return httpClient.requestRawWithCallback(type3info, objs, callback);
|
||||
}
|
||||
}
|
||||
exports.NtlmCredentialHandler = NtlmCredentialHandler;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 571:
|
||||
/***/ (function(__unusedmodule, exports) {
|
||||
|
||||
"use strict";
|
||||
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
class BearerCredentialHandler {
|
||||
constructor(token) {
|
||||
this.token = token;
|
||||
}
|
||||
// currently implements pre-authorization
|
||||
// TODO: support preAuth = false where it hooks on 401
|
||||
prepareRequest(options) {
|
||||
options.headers['Authorization'] = 'Bearer ' + this.token;
|
||||
options.headers['X-TFS-FedAuthRedirect'] = 'Suppress';
|
||||
}
|
||||
// This handler cannot handle 401
|
||||
canHandleAuthentication(response) {
|
||||
return false;
|
||||
}
|
||||
handleAuthentication(httpClient, requestInfo, objs) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
exports.BearerCredentialHandler = BearerCredentialHandler;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 605:
|
||||
/***/ (function(module) {
|
||||
|
||||
module.exports = require("http");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 614:
|
||||
/***/ (function(module) {
|
||||
|
||||
module.exports = require("events");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 622:
|
||||
/***/ (function(module) {
|
||||
|
||||
module.exports = require("path");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 631:
|
||||
/***/ (function(module) {
|
||||
|
||||
module.exports = require("net");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 669:
|
||||
/***/ (function(module) {
|
||||
|
||||
module.exports = require("util");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 672:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
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 _a;
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const assert_1 = __webpack_require__(357);
|
||||
const fs = __webpack_require__(747);
|
||||
const path = __webpack_require__(622);
|
||||
_a = fs.promises, exports.chmod = _a.chmod, exports.copyFile = _a.copyFile, exports.lstat = _a.lstat, exports.mkdir = _a.mkdir, exports.readdir = _a.readdir, exports.readlink = _a.readlink, exports.rename = _a.rename, exports.rmdir = _a.rmdir, exports.stat = _a.stat, exports.symlink = _a.symlink, exports.unlink = _a.unlink;
|
||||
exports.IS_WINDOWS = process.platform === 'win32';
|
||||
function exists(fsPath) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
yield exports.stat(fsPath);
|
||||
}
|
||||
catch (err) {
|
||||
if (err.code === 'ENOENT') {
|
||||
return false;
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
exports.exists = exists;
|
||||
function isDirectory(fsPath, useStat = false) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const stats = useStat ? yield exports.stat(fsPath) : yield exports.lstat(fsPath);
|
||||
return stats.isDirectory();
|
||||
});
|
||||
}
|
||||
exports.isDirectory = isDirectory;
|
||||
/**
|
||||
* On OSX/Linux, true if path starts with '/'. On Windows, true for paths like:
|
||||
* \, \hello, \\hello\share, C:, and C:\hello (and corresponding alternate separator cases).
|
||||
*/
|
||||
function isRooted(p) {
|
||||
p = normalizeSeparators(p);
|
||||
if (!p) {
|
||||
throw new Error('isRooted() parameter "p" cannot be empty');
|
||||
}
|
||||
if (exports.IS_WINDOWS) {
|
||||
return (p.startsWith('\\') || /^[A-Z]:/i.test(p) // e.g. \ or \hello or \\hello
|
||||
); // e.g. C: or C:\hello
|
||||
}
|
||||
return p.startsWith('/');
|
||||
}
|
||||
exports.isRooted = isRooted;
|
||||
/**
|
||||
* Recursively create a directory at `fsPath`.
|
||||
*
|
||||
* This implementation is optimistic, meaning it attempts to create the full
|
||||
* path first, and backs up the path stack from there.
|
||||
*
|
||||
* @param fsPath The path to create
|
||||
* @param maxDepth The maximum recursion depth
|
||||
* @param depth The current recursion depth
|
||||
*/
|
||||
function mkdirP(fsPath, maxDepth = 1000, depth = 1) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
assert_1.ok(fsPath, 'a path argument must be provided');
|
||||
fsPath = path.resolve(fsPath);
|
||||
if (depth >= maxDepth)
|
||||
return exports.mkdir(fsPath);
|
||||
try {
|
||||
yield exports.mkdir(fsPath);
|
||||
return;
|
||||
}
|
||||
catch (err) {
|
||||
switch (err.code) {
|
||||
case 'ENOENT': {
|
||||
yield mkdirP(path.dirname(fsPath), maxDepth, depth + 1);
|
||||
yield exports.mkdir(fsPath);
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
let stats;
|
||||
try {
|
||||
stats = yield exports.stat(fsPath);
|
||||
}
|
||||
catch (err2) {
|
||||
throw err;
|
||||
}
|
||||
if (!stats.isDirectory())
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.mkdirP = mkdirP;
|
||||
/**
|
||||
* Best effort attempt to determine whether a file exists and is executable.
|
||||
* @param filePath file path to check
|
||||
* @param extensions additional file extensions to try
|
||||
* @return if file exists and is executable, returns the file path. otherwise empty string.
|
||||
*/
|
||||
function tryGetExecutablePath(filePath, extensions) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let stats = undefined;
|
||||
try {
|
||||
// test file exists
|
||||
stats = yield exports.stat(filePath);
|
||||
}
|
||||
catch (err) {
|
||||
if (err.code !== 'ENOENT') {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`);
|
||||
}
|
||||
}
|
||||
if (stats && stats.isFile()) {
|
||||
if (exports.IS_WINDOWS) {
|
||||
// on Windows, test for valid extension
|
||||
const upperExt = path.extname(filePath).toUpperCase();
|
||||
if (extensions.some(validExt => validExt.toUpperCase() === upperExt)) {
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (isUnixExecutable(stats)) {
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
// try each extension
|
||||
const originalFilePath = filePath;
|
||||
for (const extension of extensions) {
|
||||
filePath = originalFilePath + extension;
|
||||
stats = undefined;
|
||||
try {
|
||||
stats = yield exports.stat(filePath);
|
||||
}
|
||||
catch (err) {
|
||||
if (err.code !== 'ENOENT') {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`);
|
||||
}
|
||||
}
|
||||
if (stats && stats.isFile()) {
|
||||
if (exports.IS_WINDOWS) {
|
||||
// preserve the case of the actual file (since an extension was appended)
|
||||
try {
|
||||
const directory = path.dirname(filePath);
|
||||
const upperName = path.basename(filePath).toUpperCase();
|
||||
for (const actualName of yield exports.readdir(directory)) {
|
||||
if (upperName === actualName.toUpperCase()) {
|
||||
filePath = path.join(directory, actualName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`Unexpected error attempting to determine the actual case of the file '${filePath}': ${err}`);
|
||||
}
|
||||
return filePath;
|
||||
}
|
||||
else {
|
||||
if (isUnixExecutable(stats)) {
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return '';
|
||||
});
|
||||
}
|
||||
exports.tryGetExecutablePath = tryGetExecutablePath;
|
||||
function normalizeSeparators(p) {
|
||||
p = p || '';
|
||||
if (exports.IS_WINDOWS) {
|
||||
// convert slashes on Windows
|
||||
p = p.replace(/\//g, '\\');
|
||||
// remove redundant slashes
|
||||
return p.replace(/\\\\+/g, '\\');
|
||||
}
|
||||
// remove redundant slashes
|
||||
return p.replace(/\/\/+/g, '/');
|
||||
}
|
||||
// on Mac/Linux, test the execute bit
|
||||
// R W X R W X R W X
|
||||
// 256 128 64 32 16 8 4 2 1
|
||||
function isUnixExecutable(stats) {
|
||||
return ((stats.mode & 1) > 0 ||
|
||||
((stats.mode & 8) > 0 && stats.gid === process.getgid()) ||
|
||||
((stats.mode & 64) > 0 && stats.uid === process.getuid()));
|
||||
}
|
||||
//# sourceMappingURL=io-util.js.map
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 694:
|
||||
/***/ (function(__unusedmodule, exports) {
|
||||
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var Inputs;
|
||||
(function (Inputs) {
|
||||
Inputs["Key"] = "key";
|
||||
Inputs["Path"] = "path";
|
||||
Inputs["RestoreKeys"] = "restore-keys";
|
||||
})(Inputs = exports.Inputs || (exports.Inputs = {}));
|
||||
var Outputs;
|
||||
(function (Outputs) {
|
||||
Outputs["CacheHit"] = "cache-hit";
|
||||
})(Outputs = exports.Outputs || (exports.Outputs = {}));
|
||||
var State;
|
||||
(function (State) {
|
||||
State["CacheKey"] = "CACHE_KEY";
|
||||
State["CacheResult"] = "CACHE_RESULT";
|
||||
})(State = exports.State || (exports.State = {}));
|
||||
var Events;
|
||||
(function (Events) {
|
||||
Events["Key"] = "GITHUB_EVENT_NAME";
|
||||
Events["Push"] = "push";
|
||||
Events["PullRequest"] = "pull_request";
|
||||
})(Events = exports.Events || (exports.Events = {}));
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 722:
|
||||
/***/ (function(module) {
|
||||
|
||||
/**
|
||||
* Convert array of 16 byte values to UUID string format of the form:
|
||||
* XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
|
||||
*/
|
||||
var byteToHex = [];
|
||||
for (var i = 0; i < 256; ++i) {
|
||||
byteToHex[i] = (i + 0x100).toString(16).substr(1);
|
||||
}
|
||||
|
||||
function bytesToUuid(buf, offset) {
|
||||
var i = offset || 0;
|
||||
var bth = byteToHex;
|
||||
// join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4
|
||||
return ([bth[buf[i++]], bth[buf[i++]],
|
||||
bth[buf[i++]], bth[buf[i++]], '-',
|
||||
bth[buf[i++]], bth[buf[i++]], '-',
|
||||
bth[buf[i++]], bth[buf[i++]], '-',
|
||||
bth[buf[i++]], bth[buf[i++]], '-',
|
||||
bth[buf[i++]], bth[buf[i++]],
|
||||
bth[buf[i++]], bth[buf[i++]],
|
||||
bth[buf[i++]], bth[buf[i++]]]).join('');
|
||||
}
|
||||
|
||||
module.exports = bytesToUuid;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 729:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const url = __webpack_require__(835);
|
||||
const path = __webpack_require__(622);
|
||||
/**
|
||||
* creates an url from a request url and optional base url (http://server:8080)
|
||||
* @param {string} resource - a fully qualified url or relative path
|
||||
* @param {string} baseUrl - an optional baseUrl (http://server:8080)
|
||||
* @return {string} - resultant url
|
||||
*/
|
||||
function getUrl(resource, baseUrl) {
|
||||
const pathApi = path.posix || path;
|
||||
if (!baseUrl) {
|
||||
return resource;
|
||||
}
|
||||
else if (!resource) {
|
||||
return baseUrl;
|
||||
}
|
||||
else {
|
||||
const base = url.parse(baseUrl);
|
||||
const resultantUrl = url.parse(resource);
|
||||
// resource (specific per request) elements take priority
|
||||
resultantUrl.protocol = resultantUrl.protocol || base.protocol;
|
||||
resultantUrl.auth = resultantUrl.auth || base.auth;
|
||||
resultantUrl.host = resultantUrl.host || base.host;
|
||||
resultantUrl.pathname = pathApi.resolve(base.pathname, resultantUrl.pathname);
|
||||
if (!resultantUrl.pathname.endsWith('/') && resource.endsWith('/')) {
|
||||
resultantUrl.pathname += '/';
|
||||
}
|
||||
return url.format(resultantUrl);
|
||||
}
|
||||
}
|
||||
exports.getUrl = getUrl;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 747:
|
||||
/***/ (function(module) {
|
||||
|
||||
module.exports = require("fs");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 778:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
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 __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 core = __importStar(__webpack_require__(470));
|
||||
const path = __importStar(__webpack_require__(622));
|
||||
const cacheHttpClient = __importStar(__webpack_require__(154));
|
||||
const constants_1 = __webpack_require__(694);
|
||||
const tar_1 = __webpack_require__(943);
|
||||
const utils = __importStar(__webpack_require__(443));
|
||||
function run() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
// Validate inputs, this can cause task failure
|
||||
if (!utils.isValidEvent()) {
|
||||
utils.logWarning(`Event Validation Error: The event type ${process.env[constants_1.Events.Key]} is not supported. Only ${utils
|
||||
.getSupportedEvents()
|
||||
.join(", ")} events are supported at this time.`);
|
||||
return;
|
||||
}
|
||||
const cachePath = utils.resolvePath(core.getInput(constants_1.Inputs.Path, { required: true }));
|
||||
core.debug(`Cache Path: ${cachePath}`);
|
||||
const primaryKey = core.getInput(constants_1.Inputs.Key, { required: true });
|
||||
core.saveState(constants_1.State.CacheKey, primaryKey);
|
||||
const restoreKeys = core
|
||||
.getInput(constants_1.Inputs.RestoreKeys)
|
||||
.split("\n")
|
||||
.filter(x => x !== "");
|
||||
const keys = [primaryKey, ...restoreKeys];
|
||||
core.debug("Resolved Keys:");
|
||||
core.debug(JSON.stringify(keys));
|
||||
if (keys.length > 10) {
|
||||
core.setFailed(`Key Validation Error: Keys are limited to a maximum of 10.`);
|
||||
return;
|
||||
}
|
||||
for (const key of keys) {
|
||||
if (key.length > 512) {
|
||||
core.setFailed(`Key Validation Error: ${key} cannot be larger than 512 characters.`);
|
||||
return;
|
||||
}
|
||||
const regex = /^[^,]*$/;
|
||||
if (!regex.test(key)) {
|
||||
core.setFailed(`Key Validation Error: ${key} cannot contain commas.`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
try {
|
||||
const cacheEntry = yield cacheHttpClient.getCacheEntry(keys);
|
||||
if (!cacheEntry) {
|
||||
core.info(`Cache not found for input keys: ${keys.join(", ")}.`);
|
||||
return;
|
||||
}
|
||||
const archivePath = path.join(yield utils.createTempDirectory(), "cache.tgz");
|
||||
core.debug(`Archive Path: ${archivePath}`);
|
||||
// Store the cache result
|
||||
utils.setCacheState(cacheEntry);
|
||||
// Download the cache from the cache entry
|
||||
yield cacheHttpClient.downloadCache(cacheEntry, archivePath);
|
||||
const archiveFileSize = utils.getArchiveFileSize(archivePath);
|
||||
core.info(`Cache Size: ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B)`);
|
||||
yield tar_1.extractTar(archivePath, cachePath);
|
||||
const isExactKeyMatch = utils.isExactKeyMatch(primaryKey, cacheEntry);
|
||||
utils.setCacheHitOutput(isExactKeyMatch);
|
||||
core.info(`Cache restored from key: ${cacheEntry && cacheEntry.cacheKey}`);
|
||||
}
|
||||
catch (error) {
|
||||
utils.logWarning(error.message);
|
||||
utils.setCacheHitOutput(false);
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
core.setFailed(error.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
run();
|
||||
exports.default = run;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 826:
|
||||
/***/ (function(module, __unusedexports, __webpack_require__) {
|
||||
|
||||
var rng = __webpack_require__(139);
|
||||
var bytesToUuid = __webpack_require__(722);
|
||||
|
||||
function v4(options, buf, offset) {
|
||||
var i = buf && offset || 0;
|
||||
|
||||
if (typeof(options) == 'string') {
|
||||
buf = options === 'binary' ? new Array(16) : null;
|
||||
options = null;
|
||||
}
|
||||
options = options || {};
|
||||
|
||||
var rnds = options.random || (options.rng || rng)();
|
||||
|
||||
// Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
|
||||
rnds[6] = (rnds[6] & 0x0f) | 0x40;
|
||||
rnds[8] = (rnds[8] & 0x3f) | 0x80;
|
||||
|
||||
// Copy bytes to buffer, if provided
|
||||
if (buf) {
|
||||
for (var ii = 0; ii < 16; ++ii) {
|
||||
buf[i + ii] = rnds[ii];
|
||||
}
|
||||
}
|
||||
|
||||
return buf || bytesToUuid(rnds);
|
||||
}
|
||||
|
||||
module.exports = v4;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 835:
|
||||
/***/ (function(module) {
|
||||
|
||||
module.exports = require("url");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 874:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
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());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const url = __webpack_require__(835);
|
||||
const http = __webpack_require__(605);
|
||||
const https = __webpack_require__(211);
|
||||
let fs;
|
||||
let tunnel;
|
||||
var HttpCodes;
|
||||
(function (HttpCodes) {
|
||||
HttpCodes[HttpCodes["OK"] = 200] = "OK";
|
||||
HttpCodes[HttpCodes["MultipleChoices"] = 300] = "MultipleChoices";
|
||||
HttpCodes[HttpCodes["MovedPermanently"] = 301] = "MovedPermanently";
|
||||
HttpCodes[HttpCodes["ResourceMoved"] = 302] = "ResourceMoved";
|
||||
HttpCodes[HttpCodes["SeeOther"] = 303] = "SeeOther";
|
||||
HttpCodes[HttpCodes["NotModified"] = 304] = "NotModified";
|
||||
HttpCodes[HttpCodes["UseProxy"] = 305] = "UseProxy";
|
||||
HttpCodes[HttpCodes["SwitchProxy"] = 306] = "SwitchProxy";
|
||||
HttpCodes[HttpCodes["TemporaryRedirect"] = 307] = "TemporaryRedirect";
|
||||
HttpCodes[HttpCodes["PermanentRedirect"] = 308] = "PermanentRedirect";
|
||||
HttpCodes[HttpCodes["BadRequest"] = 400] = "BadRequest";
|
||||
HttpCodes[HttpCodes["Unauthorized"] = 401] = "Unauthorized";
|
||||
HttpCodes[HttpCodes["PaymentRequired"] = 402] = "PaymentRequired";
|
||||
HttpCodes[HttpCodes["Forbidden"] = 403] = "Forbidden";
|
||||
HttpCodes[HttpCodes["NotFound"] = 404] = "NotFound";
|
||||
HttpCodes[HttpCodes["MethodNotAllowed"] = 405] = "MethodNotAllowed";
|
||||
HttpCodes[HttpCodes["NotAcceptable"] = 406] = "NotAcceptable";
|
||||
HttpCodes[HttpCodes["ProxyAuthenticationRequired"] = 407] = "ProxyAuthenticationRequired";
|
||||
HttpCodes[HttpCodes["RequestTimeout"] = 408] = "RequestTimeout";
|
||||
HttpCodes[HttpCodes["Conflict"] = 409] = "Conflict";
|
||||
HttpCodes[HttpCodes["Gone"] = 410] = "Gone";
|
||||
HttpCodes[HttpCodes["InternalServerError"] = 500] = "InternalServerError";
|
||||
HttpCodes[HttpCodes["NotImplemented"] = 501] = "NotImplemented";
|
||||
HttpCodes[HttpCodes["BadGateway"] = 502] = "BadGateway";
|
||||
HttpCodes[HttpCodes["ServiceUnavailable"] = 503] = "ServiceUnavailable";
|
||||
HttpCodes[HttpCodes["GatewayTimeout"] = 504] = "GatewayTimeout";
|
||||
})(HttpCodes = exports.HttpCodes || (exports.HttpCodes = {}));
|
||||
const HttpRedirectCodes = [HttpCodes.MovedPermanently, HttpCodes.ResourceMoved, HttpCodes.SeeOther, HttpCodes.TemporaryRedirect, HttpCodes.PermanentRedirect];
|
||||
const HttpResponseRetryCodes = [HttpCodes.BadGateway, HttpCodes.ServiceUnavailable, HttpCodes.GatewayTimeout];
|
||||
const RetryableHttpVerbs = ['OPTIONS', 'GET', 'DELETE', 'HEAD'];
|
||||
const ExponentialBackoffCeiling = 10;
|
||||
const ExponentialBackoffTimeSlice = 5;
|
||||
class HttpClientResponse {
|
||||
constructor(message) {
|
||||
this.message = message;
|
||||
}
|
||||
readBody() {
|
||||
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
||||
let output = '';
|
||||
this.message.on('data', (chunk) => {
|
||||
output += chunk;
|
||||
});
|
||||
this.message.on('end', () => {
|
||||
resolve(output);
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
exports.HttpClientResponse = HttpClientResponse;
|
||||
function isHttps(requestUrl) {
|
||||
let parsedUrl = url.parse(requestUrl);
|
||||
return parsedUrl.protocol === 'https:';
|
||||
}
|
||||
exports.isHttps = isHttps;
|
||||
var EnvironmentVariables;
|
||||
(function (EnvironmentVariables) {
|
||||
EnvironmentVariables["HTTP_PROXY"] = "HTTP_PROXY";
|
||||
EnvironmentVariables["HTTPS_PROXY"] = "HTTPS_PROXY";
|
||||
})(EnvironmentVariables || (EnvironmentVariables = {}));
|
||||
class HttpClient {
|
||||
constructor(userAgent, handlers, requestOptions) {
|
||||
this._ignoreSslError = false;
|
||||
this._allowRedirects = true;
|
||||
this._maxRedirects = 50;
|
||||
this._allowRetries = false;
|
||||
this._maxRetries = 1;
|
||||
this._keepAlive = false;
|
||||
this._disposed = false;
|
||||
this.userAgent = userAgent;
|
||||
this.handlers = handlers || [];
|
||||
this.requestOptions = requestOptions;
|
||||
if (requestOptions) {
|
||||
if (requestOptions.ignoreSslError != null) {
|
||||
this._ignoreSslError = requestOptions.ignoreSslError;
|
||||
}
|
||||
this._socketTimeout = requestOptions.socketTimeout;
|
||||
this._httpProxy = requestOptions.proxy;
|
||||
if (requestOptions.proxy && requestOptions.proxy.proxyBypassHosts) {
|
||||
this._httpProxyBypassHosts = [];
|
||||
requestOptions.proxy.proxyBypassHosts.forEach(bypass => {
|
||||
this._httpProxyBypassHosts.push(new RegExp(bypass, 'i'));
|
||||
});
|
||||
}
|
||||
this._certConfig = requestOptions.cert;
|
||||
if (this._certConfig) {
|
||||
// If using cert, need fs
|
||||
fs = __webpack_require__(747);
|
||||
// cache the cert content into memory, so we don't have to read it from disk every time
|
||||
if (this._certConfig.caFile && fs.existsSync(this._certConfig.caFile)) {
|
||||
this._ca = fs.readFileSync(this._certConfig.caFile, 'utf8');
|
||||
}
|
||||
if (this._certConfig.certFile && fs.existsSync(this._certConfig.certFile)) {
|
||||
this._cert = fs.readFileSync(this._certConfig.certFile, 'utf8');
|
||||
}
|
||||
if (this._certConfig.keyFile && fs.existsSync(this._certConfig.keyFile)) {
|
||||
this._key = fs.readFileSync(this._certConfig.keyFile, 'utf8');
|
||||
}
|
||||
}
|
||||
if (requestOptions.allowRedirects != null) {
|
||||
this._allowRedirects = requestOptions.allowRedirects;
|
||||
}
|
||||
if (requestOptions.maxRedirects != null) {
|
||||
this._maxRedirects = Math.max(requestOptions.maxRedirects, 0);
|
||||
}
|
||||
if (requestOptions.keepAlive != null) {
|
||||
this._keepAlive = requestOptions.keepAlive;
|
||||
}
|
||||
if (requestOptions.allowRetries != null) {
|
||||
this._allowRetries = requestOptions.allowRetries;
|
||||
}
|
||||
if (requestOptions.maxRetries != null) {
|
||||
this._maxRetries = requestOptions.maxRetries;
|
||||
}
|
||||
}
|
||||
}
|
||||
options(requestUrl, additionalHeaders) {
|
||||
return this.request('OPTIONS', requestUrl, null, additionalHeaders || {});
|
||||
}
|
||||
get(requestUrl, additionalHeaders) {
|
||||
return this.request('GET', requestUrl, null, additionalHeaders || {});
|
||||
}
|
||||
del(requestUrl, additionalHeaders) {
|
||||
return this.request('DELETE', requestUrl, null, additionalHeaders || {});
|
||||
}
|
||||
post(requestUrl, data, additionalHeaders) {
|
||||
return this.request('POST', requestUrl, data, additionalHeaders || {});
|
||||
}
|
||||
patch(requestUrl, data, additionalHeaders) {
|
||||
return this.request('PATCH', requestUrl, data, additionalHeaders || {});
|
||||
}
|
||||
put(requestUrl, data, additionalHeaders) {
|
||||
return this.request('PUT', requestUrl, data, additionalHeaders || {});
|
||||
}
|
||||
head(requestUrl, additionalHeaders) {
|
||||
return this.request('HEAD', requestUrl, null, additionalHeaders || {});
|
||||
}
|
||||
sendStream(verb, requestUrl, stream, additionalHeaders) {
|
||||
return this.request(verb, requestUrl, stream, additionalHeaders);
|
||||
}
|
||||
/**
|
||||
* Makes a raw http request.
|
||||
* All other methods such as get, post, patch, and request ultimately call this.
|
||||
* Prefer get, del, post and patch
|
||||
*/
|
||||
request(verb, requestUrl, data, headers) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (this._disposed) {
|
||||
throw new Error("Client has already been disposed.");
|
||||
}
|
||||
let info = this._prepareRequest(verb, requestUrl, headers);
|
||||
// Only perform retries on reads since writes may not be idempotent.
|
||||
let maxTries = (this._allowRetries && RetryableHttpVerbs.indexOf(verb) != -1) ? this._maxRetries + 1 : 1;
|
||||
let numTries = 0;
|
||||
let response;
|
||||
while (numTries < maxTries) {
|
||||
response = yield this.requestRaw(info, data);
|
||||
// Check if it's an authentication challenge
|
||||
if (response && response.message && response.message.statusCode === HttpCodes.Unauthorized) {
|
||||
let authenticationHandler;
|
||||
for (let i = 0; i < this.handlers.length; i++) {
|
||||
if (this.handlers[i].canHandleAuthentication(response)) {
|
||||
authenticationHandler = this.handlers[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (authenticationHandler) {
|
||||
return authenticationHandler.handleAuthentication(this, info, data);
|
||||
}
|
||||
else {
|
||||
// We have received an unauthorized response but have no handlers to handle it.
|
||||
// Let the response return to the caller.
|
||||
return response;
|
||||
}
|
||||
}
|
||||
let redirectsRemaining = this._maxRedirects;
|
||||
while (HttpRedirectCodes.indexOf(response.message.statusCode) != -1
|
||||
&& this._allowRedirects
|
||||
&& redirectsRemaining > 0) {
|
||||
const redirectUrl = response.message.headers["location"];
|
||||
if (!redirectUrl) {
|
||||
// if there's no location to redirect to, we won't
|
||||
break;
|
||||
}
|
||||
// we need to finish reading the response before reassigning response
|
||||
// which will leak the open socket.
|
||||
yield response.readBody();
|
||||
// let's make the request with the new redirectUrl
|
||||
info = this._prepareRequest(verb, redirectUrl, headers);
|
||||
response = yield this.requestRaw(info, data);
|
||||
redirectsRemaining--;
|
||||
}
|
||||
if (HttpResponseRetryCodes.indexOf(response.message.statusCode) == -1) {
|
||||
// If not a retry code, return immediately instead of retrying
|
||||
return response;
|
||||
}
|
||||
numTries += 1;
|
||||
if (numTries < maxTries) {
|
||||
yield response.readBody();
|
||||
yield this._performExponentialBackoff(numTries);
|
||||
}
|
||||
}
|
||||
return response;
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Needs to be called if keepAlive is set to true in request options.
|
||||
*/
|
||||
dispose() {
|
||||
if (this._agent) {
|
||||
this._agent.destroy();
|
||||
}
|
||||
this._disposed = true;
|
||||
}
|
||||
/**
|
||||
* Raw request.
|
||||
* @param info
|
||||
* @param data
|
||||
*/
|
||||
requestRaw(info, data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let callbackForResult = function (err, res) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
}
|
||||
resolve(res);
|
||||
};
|
||||
this.requestRawWithCallback(info, data, callbackForResult);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Raw request with callback.
|
||||
* @param info
|
||||
* @param data
|
||||
* @param onResult
|
||||
*/
|
||||
requestRawWithCallback(info, data, onResult) {
|
||||
let socket;
|
||||
let isDataString = typeof (data) === 'string';
|
||||
if (typeof (data) === 'string') {
|
||||
info.options.headers["Content-Length"] = Buffer.byteLength(data, 'utf8');
|
||||
}
|
||||
let callbackCalled = false;
|
||||
let handleResult = (err, res) => {
|
||||
if (!callbackCalled) {
|
||||
callbackCalled = true;
|
||||
onResult(err, res);
|
||||
}
|
||||
};
|
||||
let req = info.httpModule.request(info.options, (msg) => {
|
||||
let res = new HttpClientResponse(msg);
|
||||
handleResult(null, res);
|
||||
});
|
||||
req.on('socket', (sock) => {
|
||||
socket = sock;
|
||||
});
|
||||
// If we ever get disconnected, we want the socket to timeout eventually
|
||||
req.setTimeout(this._socketTimeout || 3 * 60000, () => {
|
||||
if (socket) {
|
||||
socket.end();
|
||||
}
|
||||
handleResult(new Error('Request timeout: ' + info.options.path), null);
|
||||
});
|
||||
req.on('error', function (err) {
|
||||
// err has statusCode property
|
||||
// res should have headers
|
||||
handleResult(err, null);
|
||||
});
|
||||
if (data && typeof (data) === 'string') {
|
||||
req.write(data, 'utf8');
|
||||
}
|
||||
if (data && typeof (data) !== 'string') {
|
||||
data.on('close', function () {
|
||||
req.end();
|
||||
});
|
||||
data.pipe(req);
|
||||
}
|
||||
else {
|
||||
req.end();
|
||||
}
|
||||
}
|
||||
_prepareRequest(method, requestUrl, headers) {
|
||||
const info = {};
|
||||
info.parsedUrl = url.parse(requestUrl);
|
||||
const usingSsl = info.parsedUrl.protocol === 'https:';
|
||||
info.httpModule = usingSsl ? https : http;
|
||||
const defaultPort = usingSsl ? 443 : 80;
|
||||
info.options = {};
|
||||
info.options.host = info.parsedUrl.hostname;
|
||||
info.options.port = info.parsedUrl.port ? parseInt(info.parsedUrl.port) : defaultPort;
|
||||
info.options.path = (info.parsedUrl.pathname || '') + (info.parsedUrl.search || '');
|
||||
info.options.method = method;
|
||||
info.options.headers = this._mergeHeaders(headers);
|
||||
info.options.headers["user-agent"] = this.userAgent;
|
||||
info.options.agent = this._getAgent(requestUrl);
|
||||
// gives handlers an opportunity to participate
|
||||
if (this.handlers && !this._isPresigned(requestUrl)) {
|
||||
this.handlers.forEach((handler) => {
|
||||
handler.prepareRequest(info.options);
|
||||
});
|
||||
}
|
||||
return info;
|
||||
}
|
||||
_isPresigned(requestUrl) {
|
||||
if (this.requestOptions && this.requestOptions.presignedUrlPatterns) {
|
||||
const patterns = this.requestOptions.presignedUrlPatterns;
|
||||
for (let i = 0; i < patterns.length; i++) {
|
||||
if (requestUrl.match(patterns[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
_mergeHeaders(headers) {
|
||||
const lowercaseKeys = obj => Object.keys(obj).reduce((c, k) => (c[k.toLowerCase()] = obj[k], c), {});
|
||||
if (this.requestOptions && this.requestOptions.headers) {
|
||||
return Object.assign({}, lowercaseKeys(this.requestOptions.headers), lowercaseKeys(headers));
|
||||
}
|
||||
return lowercaseKeys(headers || {});
|
||||
}
|
||||
_getAgent(requestUrl) {
|
||||
let agent;
|
||||
let proxy = this._getProxy(requestUrl);
|
||||
let useProxy = proxy.proxyUrl && proxy.proxyUrl.hostname && !this._isBypassProxy(requestUrl);
|
||||
if (this._keepAlive && useProxy) {
|
||||
agent = this._proxyAgent;
|
||||
}
|
||||
if (this._keepAlive && !useProxy) {
|
||||
agent = this._agent;
|
||||
}
|
||||
// if agent is already assigned use that agent.
|
||||
if (!!agent) {
|
||||
return agent;
|
||||
}
|
||||
let parsedUrl = url.parse(requestUrl);
|
||||
const usingSsl = parsedUrl.protocol === 'https:';
|
||||
let maxSockets = 100;
|
||||
if (!!this.requestOptions) {
|
||||
maxSockets = this.requestOptions.maxSockets || http.globalAgent.maxSockets;
|
||||
}
|
||||
if (useProxy) {
|
||||
// If using proxy, need tunnel
|
||||
if (!tunnel) {
|
||||
tunnel = __webpack_require__(413);
|
||||
}
|
||||
const agentOptions = {
|
||||
maxSockets: maxSockets,
|
||||
keepAlive: this._keepAlive,
|
||||
proxy: {
|
||||
proxyAuth: proxy.proxyAuth,
|
||||
host: proxy.proxyUrl.hostname,
|
||||
port: proxy.proxyUrl.port
|
||||
},
|
||||
};
|
||||
let tunnelAgent;
|
||||
const overHttps = proxy.proxyUrl.protocol === 'https:';
|
||||
if (usingSsl) {
|
||||
tunnelAgent = overHttps ? tunnel.httpsOverHttps : tunnel.httpsOverHttp;
|
||||
}
|
||||
else {
|
||||
tunnelAgent = overHttps ? tunnel.httpOverHttps : tunnel.httpOverHttp;
|
||||
}
|
||||
agent = tunnelAgent(agentOptions);
|
||||
this._proxyAgent = agent;
|
||||
}
|
||||
// if reusing agent across request and tunneling agent isn't assigned create a new agent
|
||||
if (this._keepAlive && !agent) {
|
||||
const options = { keepAlive: this._keepAlive, maxSockets: maxSockets };
|
||||
agent = usingSsl ? new https.Agent(options) : new http.Agent(options);
|
||||
this._agent = agent;
|
||||
}
|
||||
// if not using private agent and tunnel agent isn't setup then use global agent
|
||||
if (!agent) {
|
||||
agent = usingSsl ? https.globalAgent : http.globalAgent;
|
||||
}
|
||||
if (usingSsl && this._ignoreSslError) {
|
||||
// we don't want to set NODE_TLS_REJECT_UNAUTHORIZED=0 since that will affect request for entire process
|
||||
// http.RequestOptions doesn't expose a way to modify RequestOptions.agent.options
|
||||
// we have to cast it to any and change it directly
|
||||
agent.options = Object.assign(agent.options || {}, { rejectUnauthorized: false });
|
||||
}
|
||||
if (usingSsl && this._certConfig) {
|
||||
agent.options = Object.assign(agent.options || {}, { ca: this._ca, cert: this._cert, key: this._key, passphrase: this._certConfig.passphrase });
|
||||
}
|
||||
return agent;
|
||||
}
|
||||
_getProxy(requestUrl) {
|
||||
const parsedUrl = url.parse(requestUrl);
|
||||
let usingSsl = parsedUrl.protocol === 'https:';
|
||||
let proxyConfig = this._httpProxy;
|
||||
// fallback to http_proxy and https_proxy env
|
||||
let https_proxy = process.env[EnvironmentVariables.HTTPS_PROXY];
|
||||
let http_proxy = process.env[EnvironmentVariables.HTTP_PROXY];
|
||||
if (!proxyConfig) {
|
||||
if (https_proxy && usingSsl) {
|
||||
proxyConfig = {
|
||||
proxyUrl: https_proxy
|
||||
};
|
||||
}
|
||||
else if (http_proxy) {
|
||||
proxyConfig = {
|
||||
proxyUrl: http_proxy
|
||||
};
|
||||
}
|
||||
}
|
||||
let proxyUrl;
|
||||
let proxyAuth;
|
||||
if (proxyConfig) {
|
||||
if (proxyConfig.proxyUrl.length > 0) {
|
||||
proxyUrl = url.parse(proxyConfig.proxyUrl);
|
||||
}
|
||||
if (proxyConfig.proxyUsername || proxyConfig.proxyPassword) {
|
||||
proxyAuth = proxyConfig.proxyUsername + ":" + proxyConfig.proxyPassword;
|
||||
}
|
||||
}
|
||||
return { proxyUrl: proxyUrl, proxyAuth: proxyAuth };
|
||||
}
|
||||
_isBypassProxy(requestUrl) {
|
||||
if (!this._httpProxyBypassHosts) {
|
||||
return false;
|
||||
}
|
||||
let bypass = false;
|
||||
this._httpProxyBypassHosts.forEach(bypassHost => {
|
||||
if (bypassHost.test(requestUrl)) {
|
||||
bypass = true;
|
||||
}
|
||||
});
|
||||
return bypass;
|
||||
}
|
||||
_performExponentialBackoff(retryNumber) {
|
||||
retryNumber = Math.min(ExponentialBackoffCeiling, retryNumber);
|
||||
const ms = ExponentialBackoffTimeSlice * Math.pow(2, retryNumber);
|
||||
return new Promise(resolve => setTimeout(() => resolve(), ms));
|
||||
}
|
||||
}
|
||||
exports.HttpClient = HttpClient;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 891:
|
||||
/***/ (function(module, exports) {
|
||||
|
||||
// Underscore.js 1.8.3
|
||||
// http://underscorejs.org
|
||||
// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
||||
// Underscore may be freely distributed under the MIT license.
|
||||
|
||||
(function() {
|
||||
|
||||
// Baseline setup
|
||||
// --------------
|
||||
|
||||
// Establish the root object, `window` in the browser, or `exports` on the server.
|
||||
var root = this;
|
||||
|
||||
// Save the previous value of the `_` variable.
|
||||
var previousUnderscore = root._;
|
||||
|
||||
// Save bytes in the minified (but not gzipped) version:
|
||||
var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
|
||||
|
||||
// Create quick reference variables for speed access to core prototypes.
|
||||
var
|
||||
push = ArrayProto.push,
|
||||
slice = ArrayProto.slice,
|
||||
toString = ObjProto.toString,
|
||||
hasOwnProperty = ObjProto.hasOwnProperty;
|
||||
|
||||
// All **ECMAScript 5** native function implementations that we hope to use
|
||||
// are declared here.
|
||||
var
|
||||
nativeIsArray = Array.isArray,
|
||||
nativeKeys = Object.keys,
|
||||
nativeBind = FuncProto.bind,
|
||||
nativeCreate = Object.create;
|
||||
|
||||
// Naked function reference for surrogate-prototype-swapping.
|
||||
var Ctor = function(){};
|
||||
|
||||
// Create a safe reference to the Underscore object for use below.
|
||||
var _ = function(obj) {
|
||||
if (obj instanceof _) return obj;
|
||||
if (!(this instanceof _)) return new _(obj);
|
||||
this._wrapped = obj;
|
||||
};
|
||||
|
||||
// Export the Underscore object for **Node.js**, with
|
||||
// backwards-compatibility for the old `require()` API. If we're in
|
||||
// the browser, add `_` as a global object.
|
||||
if (true) {
|
||||
if ( true && module.exports) {
|
||||
exports = module.exports = _;
|
||||
}
|
||||
exports._ = _;
|
||||
} else {}
|
||||
|
||||
// Current version.
|
||||
_.VERSION = '1.8.3';
|
||||
|
||||
// Internal function that returns an efficient (for current engines) version
|
||||
// of the passed-in callback, to be repeatedly applied in other Underscore
|
||||
// functions.
|
||||
var optimizeCb = function(func, context, argCount) {
|
||||
if (context === void 0) return func;
|
||||
switch (argCount == null ? 3 : argCount) {
|
||||
case 1: return function(value) {
|
||||
return func.call(context, value);
|
||||
};
|
||||
case 2: return function(value, other) {
|
||||
return func.call(context, value, other);
|
||||
};
|
||||
case 3: return function(value, index, collection) {
|
||||
return func.call(context, value, index, collection);
|
||||
};
|
||||
case 4: return function(accumulator, value, index, collection) {
|
||||
return func.call(context, accumulator, value, index, collection);
|
||||
};
|
||||
}
|
||||
return function() {
|
||||
return func.apply(context, arguments);
|
||||
};
|
||||
};
|
||||
|
||||
// A mostly-internal function to generate callbacks that can be applied
|
||||
// to each element in a collection, returning the desired result — either
|
||||
// identity, an arbitrary callback, a property matcher, or a property accessor.
|
||||
var cb = function(value, context, argCount) {
|
||||
if (value == null) return _.identity;
|
||||
if (_.isFunction(value)) return optimizeCb(value, context, argCount);
|
||||
if (_.isObject(value)) return _.matcher(value);
|
||||
return _.property(value);
|
||||
};
|
||||
_.iteratee = function(value, context) {
|
||||
return cb(value, context, Infinity);
|
||||
};
|
||||
|
||||
// An internal function for creating assigner functions.
|
||||
var createAssigner = function(keysFunc, undefinedOnly) {
|
||||
return function(obj) {
|
||||
var length = arguments.length;
|
||||
if (length < 2 || obj == null) return obj;
|
||||
for (var index = 1; index < length; index++) {
|
||||
var source = arguments[index],
|
||||
keys = keysFunc(source),
|
||||
l = keys.length;
|
||||
for (var i = 0; i < l; i++) {
|
||||
var key = keys[i];
|
||||
if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key];
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
};
|
||||
|
||||
// An internal function for creating a new object that inherits from another.
|
||||
var baseCreate = function(prototype) {
|
||||
if (!_.isObject(prototype)) return {};
|
||||
if (nativeCreate) return nativeCreate(prototype);
|
||||
Ctor.prototype = prototype;
|
||||
var result = new Ctor;
|
||||
Ctor.prototype = null;
|
||||
return result;
|
||||
};
|
||||
|
||||
var property = function(key) {
|
||||
return function(obj) {
|
||||
return obj == null ? void 0 : obj[key];
|
||||
};
|
||||
};
|
||||
|
||||
// Helper for collection methods to determine whether a collection
|
||||
// should be iterated as an array or as an object
|
||||
// Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
|
||||
// Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094
|
||||
var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;
|
||||
var getLength = property('length');
|
||||
var isArrayLike = function(collection) {
|
||||
var length = getLength(collection);
|
||||
return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;
|
||||
};
|
||||
|
||||
// Collection Functions
|
||||
// --------------------
|
||||
|
||||
// The cornerstone, an `each` implementation, aka `forEach`.
|
||||
// Handles raw objects in addition to array-likes. Treats all
|
||||
// sparse array-likes as if they were dense.
|
||||
_.each = _.forEach = function(obj, iteratee, context) {
|
||||
iteratee = optimizeCb(iteratee, context);
|
||||
var i, length;
|
||||
if (isArrayLike(obj)) {
|
||||
for (i = 0, length = obj.length; i < length; i++) {
|
||||
iteratee(obj[i], i, obj);
|
||||
}
|
||||
} else {
|
||||
var keys = _.keys(obj);
|
||||
for (i = 0, length = keys.length; i < length; i++) {
|
||||
iteratee(obj[keys[i]], keys[i], obj);
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
|
||||
// Return the results of applying the iteratee to each element.
|
||||
_.map = _.collect = function(obj, iteratee, context) {
|
||||
iteratee = cb(iteratee, context);
|
||||
var keys = !isArrayLike(obj) && _.keys(obj),
|
||||
length = (keys || obj).length,
|
||||
results = Array(length);
|
||||
for (var index = 0; index < length; index++) {
|
||||
var currentKey = keys ? keys[index] : index;
|
||||
results[index] = iteratee(obj[currentKey], currentKey, obj);
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
// Create a reducing function iterating left or right.
|
||||
function createReduce(dir) {
|
||||
// Optimized iterator function as using arguments.length
|
||||
// in the main function will deoptimize the, see #1991.
|
||||
function iterator(obj, iteratee, memo, keys, index, length) {
|
||||
for (; index >= 0 && index < length; index += dir) {
|
||||
var currentKey = keys ? keys[index] : index;
|
||||
memo = iteratee(memo, obj[currentKey], currentKey, obj);
|
||||
}
|
||||
return memo;
|
||||
}
|
||||
|
||||
return function(obj, iteratee, memo, context) {
|
||||
iteratee = optimizeCb(iteratee, context, 4);
|
||||
var keys = !isArrayLike(obj) && _.keys(obj),
|
||||
length = (keys || obj).length,
|
||||
index = dir > 0 ? 0 : length - 1;
|
||||
// Determine the initial value if none is provided.
|
||||
if (arguments.length < 3) {
|
||||
memo = obj[keys ? keys[index] : index];
|
||||
index += dir;
|
||||
}
|
||||
return iterator(obj, iteratee, memo, keys, index, length);
|
||||
};
|
||||
}
|
||||
|
||||
// **Reduce** builds up a single result from a list of values, aka `inject`,
|
||||
// or `foldl`.
|
||||
_.reduce = _.foldl = _.inject = createReduce(1);
|
||||
|
||||
// The right-associative version of reduce, also known as `foldr`.
|
||||
_.reduceRight = _.foldr = createReduce(-1);
|
||||
|
||||
// Return the first value which passes a truth test. Aliased as `detect`.
|
||||
_.find = _.detect = function(obj, predicate, context) {
|
||||
var key;
|
||||
if (isArrayLike(obj)) {
|
||||
key = _.findIndex(obj, predicate, context);
|
||||
} else {
|
||||
key = _.findKey(obj, predicate, context);
|
||||
}
|
||||
if (key !== void 0 && key !== -1) return obj[key];
|
||||
};
|
||||
|
||||
// Return all the elements that pass a truth test.
|
||||
// Aliased as `select`.
|
||||
_.filter = _.select = function(obj, predicate, context) {
|
||||
var results = [];
|
||||
predicate = cb(predicate, context);
|
||||
_.each(obj, function(value, index, list) {
|
||||
if (predicate(value, index, list)) results.push(value);
|
||||
});
|
||||
return results;
|
||||
};
|
||||
|
||||
// Return all the elements for which a truth test fails.
|
||||
_.reject = function(obj, predicate, context) {
|
||||
return _.filter(obj, _.negate(cb(predicate)), context);
|
||||
};
|
||||
|
||||
// Determine whether all of the elements match a truth test.
|
||||
// Aliased as `all`.
|
||||
_.every = _.all = function(obj, predicate, context) {
|
||||
predicate = cb(predicate, context);
|
||||
var keys = !isArrayLike(obj) && _.keys(obj),
|
||||
length = (keys || obj).length;
|
||||
for (var index = 0; index < length; index++) {
|
||||
var currentKey = keys ? keys[index] : index;
|
||||
if (!predicate(obj[currentKey], currentKey, obj)) return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
// Determine if at least one element in the object matches a truth test.
|
||||
// Aliased as `any`.
|
||||
_.some = _.any = function(obj, predicate, context) {
|
||||
predicate = cb(predicate, context);
|
||||
var keys = !isArrayLike(obj) && _.keys(obj),
|
||||
length = (keys || obj).length;
|
||||
for (var index = 0; index < length; index++) {
|
||||
var currentKey = keys ? keys[index] : index;
|
||||
if (predicate(obj[currentKey], currentKey, obj)) return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
// Determine if the array or object contains a given item (using `===`).
|
||||
// Aliased as `includes` and `include`.
|
||||
_.contains = _.includes = _.include = function(obj, item, fromIndex, guard) {
|
||||
if (!isArrayLike(obj)) obj = _.values(obj);
|
||||
if (typeof fromIndex != 'number' || guard) fromIndex = 0;
|
||||
return _.indexOf(obj, item, fromIndex) >= 0;
|
||||
};
|
||||
|
||||
// Invoke a method (with arguments) on every item in a collection.
|
||||
_.invoke = function(obj, method) {
|
||||
var args = slice.call(arguments, 2);
|
||||
var isFunc = _.isFunction(method);
|
||||
return _.map(obj, function(value) {
|
||||
var func = isFunc ? method : value[method];
|
||||
return func == null ? func : func.apply(value, args);
|
||||
});
|
||||
};
|
||||
|
||||
// Convenience version of a common use case of `map`: fetching a property.
|
||||
_.pluck = function(obj, key) {
|
||||
return _.map(obj, _.property(key));
|
||||
};
|
||||
|
||||
// Convenience version of a common use case of `filter`: selecting only objects
|
||||
// containing specific `key:value` pairs.
|
||||
_.where = function(obj, attrs) {
|
||||
return _.filter(obj, _.matcher(attrs));
|
||||
};
|
||||
|
||||
// Convenience version of a common use case of `find`: getting the first object
|
||||
// containing specific `key:value` pairs.
|
||||
_.findWhere = function(obj, attrs) {
|
||||
return _.find(obj, _.matcher(attrs));
|
||||
};
|
||||
|
||||
// Return the maximum element (or element-based computation).
|
||||
_.max = function(obj, iteratee, context) {
|
||||
var result = -Infinity, lastComputed = -Infinity,
|
||||
value, computed;
|
||||
if (iteratee == null && obj != null) {
|
||||
obj = isArrayLike(obj) ? obj : _.values(obj);
|
||||
for (var i = 0, length = obj.length; i < length; i++) {
|
||||
value = obj[i];
|
||||
if (value > result) {
|
||||
result = value;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
iteratee = cb(iteratee, context);
|
||||
_.each(obj, function(value, index, list) {
|
||||
computed = iteratee(value, index, list);
|
||||
if (computed > lastComputed || computed === -Infinity && result === -Infinity) {
|
||||
result = value;
|
||||
lastComputed = computed;
|
||||
}
|
||||
});
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
// Return the minimum element (or element-based computation).
|
||||
_.min = function(obj, iteratee, context) {
|
||||
var result = Infinity, lastComputed = Infinity,
|
||||
value, computed;
|
||||
if (iteratee == null && obj != null) {
|
||||
obj = isArrayLike(obj) ? obj : _.values(obj);
|
||||
for (var i = 0, length = obj.length; i < length; i++) {
|
||||
value = obj[i];
|
||||
if (value < result) {
|
||||
result = value;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
iteratee = cb(iteratee, context);
|
||||
_.each(obj, function(value, index, list) {
|
||||
computed = iteratee(value, index, list);
|
||||
if (computed < lastComputed || computed === Infinity && result === Infinity) {
|
||||
result = value;
|
||||
lastComputed = computed;
|
||||
}
|
||||
});
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
// Shuffle a collection, using the modern version of the
|
||||
// [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
|
||||
_.shuffle = function(obj) {
|
||||
var set = isArrayLike(obj) ? obj : _.values(obj);
|
||||
var length = set.length;
|
||||
var shuffled = Array(length);
|
||||
for (var index = 0, rand; index < length; index++) {
|
||||
rand = _.random(0, index);
|
||||
if (rand !== index) shuffled[index] = shuffled[rand];
|
||||
shuffled[rand] = set[index];
|
||||
}
|
||||
return shuffled;
|
||||
};
|
||||
|
||||
// Sample **n** random values from a collection.
|
||||
// If **n** is not specified, returns a single random element.
|
||||
// The internal `guard` argument allows it to work with `map`.
|
||||
_.sample = function(obj, n, guard) {
|
||||
if (n == null || guard) {
|
||||
if (!isArrayLike(obj)) obj = _.values(obj);
|
||||
return obj[_.random(obj.length - 1)];
|
||||
}
|
||||
return _.shuffle(obj).slice(0, Math.max(0, n));
|
||||
};
|
||||
|
||||
// Sort the object's values by a criterion produced by an iteratee.
|
||||
_.sortBy = function(obj, iteratee, context) {
|
||||
iteratee = cb(iteratee, context);
|
||||
return _.pluck(_.map(obj, function(value, index, list) {
|
||||
return {
|
||||
value: value,
|
||||
index: index,
|
||||
criteria: iteratee(value, index, list)
|
||||
};
|
||||
}).sort(function(left, right) {
|
||||
var a = left.criteria;
|
||||
var b = right.criteria;
|
||||
if (a !== b) {
|
||||
if (a > b || a === void 0) return 1;
|
||||
if (a < b || b === void 0) return -1;
|
||||
}
|
||||
return left.index - right.index;
|
||||
}), 'value');
|
||||
};
|
||||
|
||||
// An internal function used for aggregate "group by" operations.
|
||||
var group = function(behavior) {
|
||||
return function(obj, iteratee, context) {
|
||||
var result = {};
|
||||
iteratee = cb(iteratee, context);
|
||||
_.each(obj, function(value, index) {
|
||||
var key = iteratee(value, index, obj);
|
||||
behavior(result, value, key);
|
||||
});
|
||||
return result;
|
||||
};
|
||||
};
|
||||
|
||||
// Groups the object's values by a criterion. Pass either a string attribute
|
||||
// to group by, or a function that returns the criterion.
|
||||
_.groupBy = group(function(result, value, key) {
|
||||
if (_.has(result, key)) result[key].push(value); else result[key] = [value];
|
||||
});
|
||||
|
||||
// Indexes the object's values by a criterion, similar to `groupBy`, but for
|
||||
// when you know that your index values will be unique.
|
||||
_.indexBy = group(function(result, value, key) {
|
||||
result[key] = value;
|
||||
});
|
||||
|
||||
// Counts instances of an object that group by a certain criterion. Pass
|
||||
// either a string attribute to count by, or a function that returns the
|
||||
// criterion.
|
||||
_.countBy = group(function(result, value, key) {
|
||||
if (_.has(result, key)) result[key]++; else result[key] = 1;
|
||||
});
|
||||
|
||||
// Safely create a real, live array from anything iterable.
|
||||
_.toArray = function(obj) {
|
||||
if (!obj) return [];
|
||||
if (_.isArray(obj)) return slice.call(obj);
|
||||
if (isArrayLike(obj)) return _.map(obj, _.identity);
|
||||
return _.values(obj);
|
||||
};
|
||||
|
||||
// Return the number of elements in an object.
|
||||
_.size = function(obj) {
|
||||
if (obj == null) return 0;
|
||||
return isArrayLike(obj) ? obj.length : _.keys(obj).length;
|
||||
};
|
||||
|
||||
// Split a collection into two arrays: one whose elements all satisfy the given
|
||||
// predicate, and one whose elements all do not satisfy the predicate.
|
||||
_.partition = function(obj, predicate, context) {
|
||||
predicate = cb(predicate, context);
|
||||
var pass = [], fail = [];
|
||||
_.each(obj, function(value, key, obj) {
|
||||
(predicate(value, key, obj) ? pass : fail).push(value);
|
||||
});
|
||||
return [pass, fail];
|
||||
};
|
||||
|
||||
// Array Functions
|
||||
// ---------------
|
||||
|
||||
// Get the first element of an array. Passing **n** will return the first N
|
||||
// values in the array. Aliased as `head` and `take`. The **guard** check
|
||||
// allows it to work with `_.map`.
|
||||
_.first = _.head = _.take = function(array, n, guard) {
|
||||
if (array == null) return void 0;
|
||||
if (n == null || guard) return array[0];
|
||||
return _.initial(array, array.length - n);
|
||||
};
|
||||
|
||||
// Returns everything but the last entry of the array. Especially useful on
|
||||
// the arguments object. Passing **n** will return all the values in
|
||||
// the array, excluding the last N.
|
||||
_.initial = function(array, n, guard) {
|
||||
return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));
|
||||
};
|
||||
|
||||
// Get the last element of an array. Passing **n** will return the last N
|
||||
// values in the array.
|
||||
_.last = function(array, n, guard) {
|
||||
if (array == null) return void 0;
|
||||
if (n == null || guard) return array[array.length - 1];
|
||||
return _.rest(array, Math.max(0, array.length - n));
|
||||
};
|
||||
|
||||
// Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
|
||||
// Especially useful on the arguments object. Passing an **n** will return
|
||||
// the rest N values in the array.
|
||||
_.rest = _.tail = _.drop = function(array, n, guard) {
|
||||
return slice.call(array, n == null || guard ? 1 : n);
|
||||
};
|
||||
|
||||
// Trim out all falsy values from an array.
|
||||
_.compact = function(array) {
|
||||
return _.filter(array, _.identity);
|
||||
};
|
||||
|
||||
// Internal implementation of a recursive `flatten` function.
|
||||
var flatten = function(input, shallow, strict, startIndex) {
|
||||
var output = [], idx = 0;
|
||||
for (var i = startIndex || 0, length = getLength(input); i < length; i++) {
|
||||
var value = input[i];
|
||||
if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) {
|
||||
//flatten current level of array or arguments object
|
||||
if (!shallow) value = flatten(value, shallow, strict);
|
||||
var j = 0, len = value.length;
|
||||
output.length += len;
|
||||
while (j < len) {
|
||||
output[idx++] = value[j++];
|
||||
}
|
||||
} else if (!strict) {
|
||||
output[idx++] = value;
|
||||
}
|
||||
}
|
||||
return output;
|
||||
};
|
||||
|
||||
// Flatten out an array, either recursively (by default), or just one level.
|
||||
_.flatten = function(array, shallow) {
|
||||
return flatten(array, shallow, false);
|
||||
};
|
||||
|
||||
// Return a version of the array that does not contain the specified value(s).
|
||||
_.without = function(array) {
|
||||
return _.difference(array, slice.call(arguments, 1));
|
||||
};
|
||||
|
||||
// Produce a duplicate-free version of the array. If the array has already
|
||||
// been sorted, you have the option of using a faster algorithm.
|
||||
// Aliased as `unique`.
|
||||
_.uniq = _.unique = function(array, isSorted, iteratee, context) {
|
||||
if (!_.isBoolean(isSorted)) {
|
||||
context = iteratee;
|
||||
iteratee = isSorted;
|
||||
isSorted = false;
|
||||
}
|
||||
if (iteratee != null) iteratee = cb(iteratee, context);
|
||||
var result = [];
|
||||
var seen = [];
|
||||
for (var i = 0, length = getLength(array); i < length; i++) {
|
||||
var value = array[i],
|
||||
computed = iteratee ? iteratee(value, i, array) : value;
|
||||
if (isSorted) {
|
||||
if (!i || seen !== computed) result.push(value);
|
||||
seen = computed;
|
||||
} else if (iteratee) {
|
||||
if (!_.contains(seen, computed)) {
|
||||
seen.push(computed);
|
||||
result.push(value);
|
||||
}
|
||||
} else if (!_.contains(result, value)) {
|
||||
result.push(value);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
// Produce an array that contains the union: each distinct element from all of
|
||||
// the passed-in arrays.
|
||||
_.union = function() {
|
||||
return _.uniq(flatten(arguments, true, true));
|
||||
};
|
||||
|
||||
// Produce an array that contains every item shared between all the
|
||||
// passed-in arrays.
|
||||
_.intersection = function(array) {
|
||||
var result = [];
|
||||
var argsLength = arguments.length;
|
||||
for (var i = 0, length = getLength(array); i < length; i++) {
|
||||
var item = array[i];
|
||||
if (_.contains(result, item)) continue;
|
||||
for (var j = 1; j < argsLength; j++) {
|
||||
if (!_.contains(arguments[j], item)) break;
|
||||
}
|
||||
if (j === argsLength) result.push(item);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
// Take the difference between one array and a number of other arrays.
|
||||
// Only the elements present in just the first array will remain.
|
||||
_.difference = function(array) {
|
||||
var rest = flatten(arguments, true, true, 1);
|
||||
return _.filter(array, function(value){
|
||||
return !_.contains(rest, value);
|
||||
});
|
||||
};
|
||||
|
||||
// Zip together multiple lists into a single array -- elements that share
|
||||
// an index go together.
|
||||
_.zip = function() {
|
||||
return _.unzip(arguments);
|
||||
};
|
||||
|
||||
// Complement of _.zip. Unzip accepts an array of arrays and groups
|
||||
// each array's elements on shared indices
|
||||
_.unzip = function(array) {
|
||||
var length = array && _.max(array, getLength).length || 0;
|
||||
var result = Array(length);
|
||||
|
||||
for (var index = 0; index < length; index++) {
|
||||
result[index] = _.pluck(array, index);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
// Converts lists into objects. Pass either a single array of `[key, value]`
|
||||
// pairs, or two parallel arrays of the same length -- one of keys, and one of
|
||||
// the corresponding values.
|
||||
_.object = function(list, values) {
|
||||
var result = {};
|
||||
for (var i = 0, length = getLength(list); i < length; i++) {
|
||||
if (values) {
|
||||
result[list[i]] = values[i];
|
||||
} else {
|
||||
result[list[i][0]] = list[i][1];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
// Generator function to create the findIndex and findLastIndex functions
|
||||
function createPredicateIndexFinder(dir) {
|
||||
return function(array, predicate, context) {
|
||||
predicate = cb(predicate, context);
|
||||
var length = getLength(array);
|
||||
var index = dir > 0 ? 0 : length - 1;
|
||||
for (; index >= 0 && index < length; index += dir) {
|
||||
if (predicate(array[index], index, array)) return index;
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
}
|
||||
|
||||
// Returns the first index on an array-like that passes a predicate test
|
||||
_.findIndex = createPredicateIndexFinder(1);
|
||||
_.findLastIndex = createPredicateIndexFinder(-1);
|
||||
|
||||
// Use a comparator function to figure out the smallest index at which
|
||||
// an object should be inserted so as to maintain order. Uses binary search.
|
||||
_.sortedIndex = function(array, obj, iteratee, context) {
|
||||
iteratee = cb(iteratee, context, 1);
|
||||
var value = iteratee(obj);
|
||||
var low = 0, high = getLength(array);
|
||||
while (low < high) {
|
||||
var mid = Math.floor((low + high) / 2);
|
||||
if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;
|
||||
}
|
||||
return low;
|
||||
};
|
||||
|
||||
// Generator function to create the indexOf and lastIndexOf functions
|
||||
function createIndexFinder(dir, predicateFind, sortedIndex) {
|
||||
return function(array, item, idx) {
|
||||
var i = 0, length = getLength(array);
|
||||
if (typeof idx == 'number') {
|
||||
if (dir > 0) {
|
||||
i = idx >= 0 ? idx : Math.max(idx + length, i);
|
||||
} else {
|
||||
length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1;
|
||||
}
|
||||
} else if (sortedIndex && idx && length) {
|
||||
idx = sortedIndex(array, item);
|
||||
return array[idx] === item ? idx : -1;
|
||||
}
|
||||
if (item !== item) {
|
||||
idx = predicateFind(slice.call(array, i, length), _.isNaN);
|
||||
return idx >= 0 ? idx + i : -1;
|
||||
}
|
||||
for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) {
|
||||
if (array[idx] === item) return idx;
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
}
|
||||
|
||||
// Return the position of the first occurrence of an item in an array,
|
||||
// or -1 if the item is not included in the array.
|
||||
// If the array is large and already in sort order, pass `true`
|
||||
// for **isSorted** to use binary search.
|
||||
_.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex);
|
||||
_.lastIndexOf = createIndexFinder(-1, _.findLastIndex);
|
||||
|
||||
// Generate an integer Array containing an arithmetic progression. A port of
|
||||
// the native Python `range()` function. See
|
||||
// [the Python documentation](http://docs.python.org/library/functions.html#range).
|
||||
_.range = function(start, stop, step) {
|
||||
if (stop == null) {
|
||||
stop = start || 0;
|
||||
start = 0;
|
||||
}
|
||||
step = step || 1;
|
||||
|
||||
var length = Math.max(Math.ceil((stop - start) / step), 0);
|
||||
var range = Array(length);
|
||||
|
||||
for (var idx = 0; idx < length; idx++, start += step) {
|
||||
range[idx] = start;
|
||||
}
|
||||
|
||||
return range;
|
||||
};
|
||||
|
||||
// Function (ahem) Functions
|
||||
// ------------------
|
||||
|
||||
// Determines whether to execute a function as a constructor
|
||||
// or a normal function with the provided arguments
|
||||
var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) {
|
||||
if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);
|
||||
var self = baseCreate(sourceFunc.prototype);
|
||||
var result = sourceFunc.apply(self, args);
|
||||
if (_.isObject(result)) return result;
|
||||
return self;
|
||||
};
|
||||
|
||||
// Create a function bound to a given object (assigning `this`, and arguments,
|
||||
// optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
|
||||
// available.
|
||||
_.bind = function(func, context) {
|
||||
if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
|
||||
if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function');
|
||||
var args = slice.call(arguments, 2);
|
||||
var bound = function() {
|
||||
return executeBound(func, bound, context, this, args.concat(slice.call(arguments)));
|
||||
};
|
||||
return bound;
|
||||
};
|
||||
|
||||
// Partially apply a function by creating a version that has had some of its
|
||||
// arguments pre-filled, without changing its dynamic `this` context. _ acts
|
||||
// as a placeholder, allowing any combination of arguments to be pre-filled.
|
||||
_.partial = function(func) {
|
||||
var boundArgs = slice.call(arguments, 1);
|
||||
var bound = function() {
|
||||
var position = 0, length = boundArgs.length;
|
||||
var args = Array(length);
|
||||
for (var i = 0; i < length; i++) {
|
||||
args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i];
|
||||
}
|
||||
while (position < arguments.length) args.push(arguments[position++]);
|
||||
return executeBound(func, bound, this, this, args);
|
||||
};
|
||||
return bound;
|
||||
};
|
||||
|
||||
// Bind a number of an object's methods to that object. Remaining arguments
|
||||
// are the method names to be bound. Useful for ensuring that all callbacks
|
||||
// defined on an object belong to it.
|
||||
_.bindAll = function(obj) {
|
||||
var i, length = arguments.length, key;
|
||||
if (length <= 1) throw new Error('bindAll must be passed function names');
|
||||
for (i = 1; i < length; i++) {
|
||||
key = arguments[i];
|
||||
obj[key] = _.bind(obj[key], obj);
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
|
||||
// Memoize an expensive function by storing its results.
|
||||
_.memoize = function(func, hasher) {
|
||||
var memoize = function(key) {
|
||||
var cache = memoize.cache;
|
||||
var address = '' + (hasher ? hasher.apply(this, arguments) : key);
|
||||
if (!_.has(cache, address)) cache[address] = func.apply(this, arguments);
|
||||
return cache[address];
|
||||
};
|
||||
memoize.cache = {};
|
||||
return memoize;
|
||||
};
|
||||
|
||||
// Delays a function for the given number of milliseconds, and then calls
|
||||
// it with the arguments supplied.
|
||||
_.delay = function(func, wait) {
|
||||
var args = slice.call(arguments, 2);
|
||||
return setTimeout(function(){
|
||||
return func.apply(null, args);
|
||||
}, wait);
|
||||
};
|
||||
|
||||
// Defers a function, scheduling it to run after the current call stack has
|
||||
// cleared.
|
||||
_.defer = _.partial(_.delay, _, 1);
|
||||
|
||||
// Returns a function, that, when invoked, will only be triggered at most once
|
||||
// during a given window of time. Normally, the throttled function will run
|
||||
// as much as it can, without ever going more than once per `wait` duration;
|
||||
// but if you'd like to disable the execution on the leading edge, pass
|
||||
// `{leading: false}`. To disable execution on the trailing edge, ditto.
|
||||
_.throttle = function(func, wait, options) {
|
||||
var context, args, result;
|
||||
var timeout = null;
|
||||
var previous = 0;
|
||||
if (!options) options = {};
|
||||
var later = function() {
|
||||
previous = options.leading === false ? 0 : _.now();
|
||||
timeout = null;
|
||||
result = func.apply(context, args);
|
||||
if (!timeout) context = args = null;
|
||||
};
|
||||
return function() {
|
||||
var now = _.now();
|
||||
if (!previous && options.leading === false) previous = now;
|
||||
var remaining = wait - (now - previous);
|
||||
context = this;
|
||||
args = arguments;
|
||||
if (remaining <= 0 || remaining > wait) {
|
||||
if (timeout) {
|
||||
clearTimeout(timeout);
|
||||
timeout = null;
|
||||
}
|
||||
previous = now;
|
||||
result = func.apply(context, args);
|
||||
if (!timeout) context = args = null;
|
||||
} else if (!timeout && options.trailing !== false) {
|
||||
timeout = setTimeout(later, remaining);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
};
|
||||
|
||||
// Returns a function, that, as long as it continues to be invoked, will not
|
||||
// be triggered. The function will be called after it stops being called for
|
||||
// N milliseconds. If `immediate` is passed, trigger the function on the
|
||||
// leading edge, instead of the trailing.
|
||||
_.debounce = function(func, wait, immediate) {
|
||||
var timeout, args, context, timestamp, result;
|
||||
|
||||
var later = function() {
|
||||
var last = _.now() - timestamp;
|
||||
|
||||
if (last < wait && last >= 0) {
|
||||
timeout = setTimeout(later, wait - last);
|
||||
} else {
|
||||
timeout = null;
|
||||
if (!immediate) {
|
||||
result = func.apply(context, args);
|
||||
if (!timeout) context = args = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return function() {
|
||||
context = this;
|
||||
args = arguments;
|
||||
timestamp = _.now();
|
||||
var callNow = immediate && !timeout;
|
||||
if (!timeout) timeout = setTimeout(later, wait);
|
||||
if (callNow) {
|
||||
result = func.apply(context, args);
|
||||
context = args = null;
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
};
|
||||
|
||||
// Returns the first function passed as an argument to the second,
|
||||
// allowing you to adjust arguments, run code before and after, and
|
||||
// conditionally execute the original function.
|
||||
_.wrap = function(func, wrapper) {
|
||||
return _.partial(wrapper, func);
|
||||
};
|
||||
|
||||
// Returns a negated version of the passed-in predicate.
|
||||
_.negate = function(predicate) {
|
||||
return function() {
|
||||
return !predicate.apply(this, arguments);
|
||||
};
|
||||
};
|
||||
|
||||
// Returns a function that is the composition of a list of functions, each
|
||||
// consuming the return value of the function that follows.
|
||||
_.compose = function() {
|
||||
var args = arguments;
|
||||
var start = args.length - 1;
|
||||
return function() {
|
||||
var i = start;
|
||||
var result = args[start].apply(this, arguments);
|
||||
while (i--) result = args[i].call(this, result);
|
||||
return result;
|
||||
};
|
||||
};
|
||||
|
||||
// Returns a function that will only be executed on and after the Nth call.
|
||||
_.after = function(times, func) {
|
||||
return function() {
|
||||
if (--times < 1) {
|
||||
return func.apply(this, arguments);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Returns a function that will only be executed up to (but not including) the Nth call.
|
||||
_.before = function(times, func) {
|
||||
var memo;
|
||||
return function() {
|
||||
if (--times > 0) {
|
||||
memo = func.apply(this, arguments);
|
||||
}
|
||||
if (times <= 1) func = null;
|
||||
return memo;
|
||||
};
|
||||
};
|
||||
|
||||
// Returns a function that will be executed at most one time, no matter how
|
||||
// often you call it. Useful for lazy initialization.
|
||||
_.once = _.partial(_.before, 2);
|
||||
|
||||
// Object Functions
|
||||
// ----------------
|
||||
|
||||
// Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.
|
||||
var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString');
|
||||
var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
|
||||
'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];
|
||||
|
||||
function collectNonEnumProps(obj, keys) {
|
||||
var nonEnumIdx = nonEnumerableProps.length;
|
||||
var constructor = obj.constructor;
|
||||
var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto;
|
||||
|
||||
// Constructor is a special case.
|
||||
var prop = 'constructor';
|
||||
if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop);
|
||||
|
||||
while (nonEnumIdx--) {
|
||||
prop = nonEnumerableProps[nonEnumIdx];
|
||||
if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) {
|
||||
keys.push(prop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve the names of an object's own properties.
|
||||
// Delegates to **ECMAScript 5**'s native `Object.keys`
|
||||
_.keys = function(obj) {
|
||||
if (!_.isObject(obj)) return [];
|
||||
if (nativeKeys) return nativeKeys(obj);
|
||||
var keys = [];
|
||||
for (var key in obj) if (_.has(obj, key)) keys.push(key);
|
||||
// Ahem, IE < 9.
|
||||
if (hasEnumBug) collectNonEnumProps(obj, keys);
|
||||
return keys;
|
||||
};
|
||||
|
||||
// Retrieve all the property names of an object.
|
||||
_.allKeys = function(obj) {
|
||||
if (!_.isObject(obj)) return [];
|
||||
var keys = [];
|
||||
for (var key in obj) keys.push(key);
|
||||
// Ahem, IE < 9.
|
||||
if (hasEnumBug) collectNonEnumProps(obj, keys);
|
||||
return keys;
|
||||
};
|
||||
|
||||
// Retrieve the values of an object's properties.
|
||||
_.values = function(obj) {
|
||||
var keys = _.keys(obj);
|
||||
var length = keys.length;
|
||||
var values = Array(length);
|
||||
for (var i = 0; i < length; i++) {
|
||||
values[i] = obj[keys[i]];
|
||||
}
|
||||
return values;
|
||||
};
|
||||
|
||||
// Returns the results of applying the iteratee to each element of the object
|
||||
// In contrast to _.map it returns an object
|
||||
_.mapObject = function(obj, iteratee, context) {
|
||||
iteratee = cb(iteratee, context);
|
||||
var keys = _.keys(obj),
|
||||
length = keys.length,
|
||||
results = {},
|
||||
currentKey;
|
||||
for (var index = 0; index < length; index++) {
|
||||
currentKey = keys[index];
|
||||
results[currentKey] = iteratee(obj[currentKey], currentKey, obj);
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
// Convert an object into a list of `[key, value]` pairs.
|
||||
_.pairs = function(obj) {
|
||||
var keys = _.keys(obj);
|
||||
var length = keys.length;
|
||||
var pairs = Array(length);
|
||||
for (var i = 0; i < length; i++) {
|
||||
pairs[i] = [keys[i], obj[keys[i]]];
|
||||
}
|
||||
return pairs;
|
||||
};
|
||||
|
||||
// Invert the keys and values of an object. The values must be serializable.
|
||||
_.invert = function(obj) {
|
||||
var result = {};
|
||||
var keys = _.keys(obj);
|
||||
for (var i = 0, length = keys.length; i < length; i++) {
|
||||
result[obj[keys[i]]] = keys[i];
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
// Return a sorted list of the function names available on the object.
|
||||
// Aliased as `methods`
|
||||
_.functions = _.methods = function(obj) {
|
||||
var names = [];
|
||||
for (var key in obj) {
|
||||
if (_.isFunction(obj[key])) names.push(key);
|
||||
}
|
||||
return names.sort();
|
||||
};
|
||||
|
||||
// Extend a given object with all the properties in passed-in object(s).
|
||||
_.extend = createAssigner(_.allKeys);
|
||||
|
||||
// Assigns a given object with all the own properties in the passed-in object(s)
|
||||
// (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
|
||||
_.extendOwn = _.assign = createAssigner(_.keys);
|
||||
|
||||
// Returns the first key on an object that passes a predicate test
|
||||
_.findKey = function(obj, predicate, context) {
|
||||
predicate = cb(predicate, context);
|
||||
var keys = _.keys(obj), key;
|
||||
for (var i = 0, length = keys.length; i < length; i++) {
|
||||
key = keys[i];
|
||||
if (predicate(obj[key], key, obj)) return key;
|
||||
}
|
||||
};
|
||||
|
||||
// Return a copy of the object only containing the whitelisted properties.
|
||||
_.pick = function(object, oiteratee, context) {
|
||||
var result = {}, obj = object, iteratee, keys;
|
||||
if (obj == null) return result;
|
||||
if (_.isFunction(oiteratee)) {
|
||||
keys = _.allKeys(obj);
|
||||
iteratee = optimizeCb(oiteratee, context);
|
||||
} else {
|
||||
keys = flatten(arguments, false, false, 1);
|
||||
iteratee = function(value, key, obj) { return key in obj; };
|
||||
obj = Object(obj);
|
||||
}
|
||||
for (var i = 0, length = keys.length; i < length; i++) {
|
||||
var key = keys[i];
|
||||
var value = obj[key];
|
||||
if (iteratee(value, key, obj)) result[key] = value;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
// Return a copy of the object without the blacklisted properties.
|
||||
_.omit = function(obj, iteratee, context) {
|
||||
if (_.isFunction(iteratee)) {
|
||||
iteratee = _.negate(iteratee);
|
||||
} else {
|
||||
var keys = _.map(flatten(arguments, false, false, 1), String);
|
||||
iteratee = function(value, key) {
|
||||
return !_.contains(keys, key);
|
||||
};
|
||||
}
|
||||
return _.pick(obj, iteratee, context);
|
||||
};
|
||||
|
||||
// Fill in a given object with default properties.
|
||||
_.defaults = createAssigner(_.allKeys, true);
|
||||
|
||||
// Creates an object that inherits from the given prototype object.
|
||||
// If additional properties are provided then they will be added to the
|
||||
// created object.
|
||||
_.create = function(prototype, props) {
|
||||
var result = baseCreate(prototype);
|
||||
if (props) _.extendOwn(result, props);
|
||||
return result;
|
||||
};
|
||||
|
||||
// Create a (shallow-cloned) duplicate of an object.
|
||||
_.clone = function(obj) {
|
||||
if (!_.isObject(obj)) return obj;
|
||||
return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
|
||||
};
|
||||
|
||||
// Invokes interceptor with the obj, and then returns obj.
|
||||
// The primary purpose of this method is to "tap into" a method chain, in
|
||||
// order to perform operations on intermediate results within the chain.
|
||||
_.tap = function(obj, interceptor) {
|
||||
interceptor(obj);
|
||||
return obj;
|
||||
};
|
||||
|
||||
// Returns whether an object has a given set of `key:value` pairs.
|
||||
_.isMatch = function(object, attrs) {
|
||||
var keys = _.keys(attrs), length = keys.length;
|
||||
if (object == null) return !length;
|
||||
var obj = Object(object);
|
||||
for (var i = 0; i < length; i++) {
|
||||
var key = keys[i];
|
||||
if (attrs[key] !== obj[key] || !(key in obj)) return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
// Internal recursive comparison function for `isEqual`.
|
||||
var eq = function(a, b, aStack, bStack) {
|
||||
// Identical objects are equal. `0 === -0`, but they aren't identical.
|
||||
// See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
|
||||
if (a === b) return a !== 0 || 1 / a === 1 / b;
|
||||
// A strict comparison is necessary because `null == undefined`.
|
||||
if (a == null || b == null) return a === b;
|
||||
// Unwrap any wrapped objects.
|
||||
if (a instanceof _) a = a._wrapped;
|
||||
if (b instanceof _) b = b._wrapped;
|
||||
// Compare `[[Class]]` names.
|
||||
var className = toString.call(a);
|
||||
if (className !== toString.call(b)) return false;
|
||||
switch (className) {
|
||||
// Strings, numbers, regular expressions, dates, and booleans are compared by value.
|
||||
case '[object RegExp]':
|
||||
// RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
|
||||
case '[object String]':
|
||||
// Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
|
||||
// equivalent to `new String("5")`.
|
||||
return '' + a === '' + b;
|
||||
case '[object Number]':
|
||||
// `NaN`s are equivalent, but non-reflexive.
|
||||
// Object(NaN) is equivalent to NaN
|
||||
if (+a !== +a) return +b !== +b;
|
||||
// An `egal` comparison is performed for other numeric values.
|
||||
return +a === 0 ? 1 / +a === 1 / b : +a === +b;
|
||||
case '[object Date]':
|
||||
case '[object Boolean]':
|
||||
// Coerce dates and booleans to numeric primitive values. Dates are compared by their
|
||||
// millisecond representations. Note that invalid dates with millisecond representations
|
||||
// of `NaN` are not equivalent.
|
||||
return +a === +b;
|
||||
}
|
||||
|
||||
var areArrays = className === '[object Array]';
|
||||
if (!areArrays) {
|
||||
if (typeof a != 'object' || typeof b != 'object') return false;
|
||||
|
||||
// Objects with different constructors are not equivalent, but `Object`s or `Array`s
|
||||
// from different frames are.
|
||||
var aCtor = a.constructor, bCtor = b.constructor;
|
||||
if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor &&
|
||||
_.isFunction(bCtor) && bCtor instanceof bCtor)
|
||||
&& ('constructor' in a && 'constructor' in b)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Assume equality for cyclic structures. The algorithm for detecting cyclic
|
||||
// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
|
||||
|
||||
// Initializing stack of traversed objects.
|
||||
// It's done here since we only need them for objects and arrays comparison.
|
||||
aStack = aStack || [];
|
||||
bStack = bStack || [];
|
||||
var length = aStack.length;
|
||||
while (length--) {
|
||||
// Linear search. Performance is inversely proportional to the number of
|
||||
// unique nested structures.
|
||||
if (aStack[length] === a) return bStack[length] === b;
|
||||
}
|
||||
|
||||
// Add the first object to the stack of traversed objects.
|
||||
aStack.push(a);
|
||||
bStack.push(b);
|
||||
|
||||
// Recursively compare objects and arrays.
|
||||
if (areArrays) {
|
||||
// Compare array lengths to determine if a deep comparison is necessary.
|
||||
length = a.length;
|
||||
if (length !== b.length) return false;
|
||||
// Deep compare the contents, ignoring non-numeric properties.
|
||||
while (length--) {
|
||||
if (!eq(a[length], b[length], aStack, bStack)) return false;
|
||||
}
|
||||
} else {
|
||||
// Deep compare objects.
|
||||
var keys = _.keys(a), key;
|
||||
length = keys.length;
|
||||
// Ensure that both objects contain the same number of properties before comparing deep equality.
|
||||
if (_.keys(b).length !== length) return false;
|
||||
while (length--) {
|
||||
// Deep compare each member
|
||||
key = keys[length];
|
||||
if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false;
|
||||
}
|
||||
}
|
||||
// Remove the first object from the stack of traversed objects.
|
||||
aStack.pop();
|
||||
bStack.pop();
|
||||
return true;
|
||||
};
|
||||
|
||||
// Perform a deep comparison to check if two objects are equal.
|
||||
_.isEqual = function(a, b) {
|
||||
return eq(a, b);
|
||||
};
|
||||
|
||||
// Is a given array, string, or object empty?
|
||||
// An "empty" object has no enumerable own-properties.
|
||||
_.isEmpty = function(obj) {
|
||||
if (obj == null) return true;
|
||||
if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0;
|
||||
return _.keys(obj).length === 0;
|
||||
};
|
||||
|
||||
// Is a given value a DOM element?
|
||||
_.isElement = function(obj) {
|
||||
return !!(obj && obj.nodeType === 1);
|
||||
};
|
||||
|
||||
// Is a given value an array?
|
||||
// Delegates to ECMA5's native Array.isArray
|
||||
_.isArray = nativeIsArray || function(obj) {
|
||||
return toString.call(obj) === '[object Array]';
|
||||
};
|
||||
|
||||
// Is a given variable an object?
|
||||
_.isObject = function(obj) {
|
||||
var type = typeof obj;
|
||||
return type === 'function' || type === 'object' && !!obj;
|
||||
};
|
||||
|
||||
// Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError.
|
||||
_.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) {
|
||||
_['is' + name] = function(obj) {
|
||||
return toString.call(obj) === '[object ' + name + ']';
|
||||
};
|
||||
});
|
||||
|
||||
// Define a fallback version of the method in browsers (ahem, IE < 9), where
|
||||
// there isn't any inspectable "Arguments" type.
|
||||
if (!_.isArguments(arguments)) {
|
||||
_.isArguments = function(obj) {
|
||||
return _.has(obj, 'callee');
|
||||
};
|
||||
}
|
||||
|
||||
// Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8,
|
||||
// IE 11 (#1621), and in Safari 8 (#1929).
|
||||
if ( true && typeof Int8Array != 'object') {
|
||||
_.isFunction = function(obj) {
|
||||
return typeof obj == 'function' || false;
|
||||
};
|
||||
}
|
||||
|
||||
// Is a given object a finite number?
|
||||
_.isFinite = function(obj) {
|
||||
return isFinite(obj) && !isNaN(parseFloat(obj));
|
||||
};
|
||||
|
||||
// Is the given value `NaN`? (NaN is the only number which does not equal itself).
|
||||
_.isNaN = function(obj) {
|
||||
return _.isNumber(obj) && obj !== +obj;
|
||||
};
|
||||
|
||||
// Is a given value a boolean?
|
||||
_.isBoolean = function(obj) {
|
||||
return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
|
||||
};
|
||||
|
||||
// Is a given value equal to null?
|
||||
_.isNull = function(obj) {
|
||||
return obj === null;
|
||||
};
|
||||
|
||||
// Is a given variable undefined?
|
||||
_.isUndefined = function(obj) {
|
||||
return obj === void 0;
|
||||
};
|
||||
|
||||
// Shortcut function for checking if an object has a given property directly
|
||||
// on itself (in other words, not on a prototype).
|
||||
_.has = function(obj, key) {
|
||||
return obj != null && hasOwnProperty.call(obj, key);
|
||||
};
|
||||
|
||||
// Utility Functions
|
||||
// -----------------
|
||||
|
||||
// Run Underscore.js in *noConflict* mode, returning the `_` variable to its
|
||||
// previous owner. Returns a reference to the Underscore object.
|
||||
_.noConflict = function() {
|
||||
root._ = previousUnderscore;
|
||||
return this;
|
||||
};
|
||||
|
||||
// Keep the identity function around for default iteratees.
|
||||
_.identity = function(value) {
|
||||
return value;
|
||||
};
|
||||
|
||||
// Predicate-generating functions. Often useful outside of Underscore.
|
||||
_.constant = function(value) {
|
||||
return function() {
|
||||
return value;
|
||||
};
|
||||
};
|
||||
|
||||
_.noop = function(){};
|
||||
|
||||
_.property = property;
|
||||
|
||||
// Generates a function for a given object that returns a given property.
|
||||
_.propertyOf = function(obj) {
|
||||
return obj == null ? function(){} : function(key) {
|
||||
return obj[key];
|
||||
};
|
||||
};
|
||||
|
||||
// Returns a predicate for checking whether an object has a given set of
|
||||
// `key:value` pairs.
|
||||
_.matcher = _.matches = function(attrs) {
|
||||
attrs = _.extendOwn({}, attrs);
|
||||
return function(obj) {
|
||||
return _.isMatch(obj, attrs);
|
||||
};
|
||||
};
|
||||
|
||||
// Run a function **n** times.
|
||||
_.times = function(n, iteratee, context) {
|
||||
var accum = Array(Math.max(0, n));
|
||||
iteratee = optimizeCb(iteratee, context, 1);
|
||||
for (var i = 0; i < n; i++) accum[i] = iteratee(i);
|
||||
return accum;
|
||||
};
|
||||
|
||||
// Return a random integer between min and max (inclusive).
|
||||
_.random = function(min, max) {
|
||||
if (max == null) {
|
||||
max = min;
|
||||
min = 0;
|
||||
}
|
||||
return min + Math.floor(Math.random() * (max - min + 1));
|
||||
};
|
||||
|
||||
// A (possibly faster) way to get the current timestamp as an integer.
|
||||
_.now = Date.now || function() {
|
||||
return new Date().getTime();
|
||||
};
|
||||
|
||||
// List of HTML entities for escaping.
|
||||
var escapeMap = {
|
||||
'&': '&',
|
||||
'<': '<',
|
||||
'>': '>',
|
||||
'"': '"',
|
||||
"'": ''',
|
||||
'`': '`'
|
||||
};
|
||||
var unescapeMap = _.invert(escapeMap);
|
||||
|
||||
// Functions for escaping and unescaping strings to/from HTML interpolation.
|
||||
var createEscaper = function(map) {
|
||||
var escaper = function(match) {
|
||||
return map[match];
|
||||
};
|
||||
// Regexes for identifying a key that needs to be escaped
|
||||
var source = '(?:' + _.keys(map).join('|') + ')';
|
||||
var testRegexp = RegExp(source);
|
||||
var replaceRegexp = RegExp(source, 'g');
|
||||
return function(string) {
|
||||
string = string == null ? '' : '' + string;
|
||||
return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;
|
||||
};
|
||||
};
|
||||
_.escape = createEscaper(escapeMap);
|
||||
_.unescape = createEscaper(unescapeMap);
|
||||
|
||||
// If the value of the named `property` is a function then invoke it with the
|
||||
// `object` as context; otherwise, return it.
|
||||
_.result = function(object, property, fallback) {
|
||||
var value = object == null ? void 0 : object[property];
|
||||
if (value === void 0) {
|
||||
value = fallback;
|
||||
}
|
||||
return _.isFunction(value) ? value.call(object) : value;
|
||||
};
|
||||
|
||||
// Generate a unique integer id (unique within the entire client session).
|
||||
// Useful for temporary DOM ids.
|
||||
var idCounter = 0;
|
||||
_.uniqueId = function(prefix) {
|
||||
var id = ++idCounter + '';
|
||||
return prefix ? prefix + id : id;
|
||||
};
|
||||
|
||||
// By default, Underscore uses ERB-style template delimiters, change the
|
||||
// following template settings to use alternative delimiters.
|
||||
_.templateSettings = {
|
||||
evaluate : /<%([\s\S]+?)%>/g,
|
||||
interpolate : /<%=([\s\S]+?)%>/g,
|
||||
escape : /<%-([\s\S]+?)%>/g
|
||||
};
|
||||
|
||||
// When customizing `templateSettings`, if you don't want to define an
|
||||
// interpolation, evaluation or escaping regex, we need one that is
|
||||
// guaranteed not to match.
|
||||
var noMatch = /(.)^/;
|
||||
|
||||
// Certain characters need to be escaped so that they can be put into a
|
||||
// string literal.
|
||||
var escapes = {
|
||||
"'": "'",
|
||||
'\\': '\\',
|
||||
'\r': 'r',
|
||||
'\n': 'n',
|
||||
'\u2028': 'u2028',
|
||||
'\u2029': 'u2029'
|
||||
};
|
||||
|
||||
var escaper = /\\|'|\r|\n|\u2028|\u2029/g;
|
||||
|
||||
var escapeChar = function(match) {
|
||||
return '\\' + escapes[match];
|
||||
};
|
||||
|
||||
// JavaScript micro-templating, similar to John Resig's implementation.
|
||||
// Underscore templating handles arbitrary delimiters, preserves whitespace,
|
||||
// and correctly escapes quotes within interpolated code.
|
||||
// NB: `oldSettings` only exists for backwards compatibility.
|
||||
_.template = function(text, settings, oldSettings) {
|
||||
if (!settings && oldSettings) settings = oldSettings;
|
||||
settings = _.defaults({}, settings, _.templateSettings);
|
||||
|
||||
// Combine delimiters into one regular expression via alternation.
|
||||
var matcher = RegExp([
|
||||
(settings.escape || noMatch).source,
|
||||
(settings.interpolate || noMatch).source,
|
||||
(settings.evaluate || noMatch).source
|
||||
].join('|') + '|$', 'g');
|
||||
|
||||
// Compile the template source, escaping string literals appropriately.
|
||||
var index = 0;
|
||||
var source = "__p+='";
|
||||
text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
|
||||
source += text.slice(index, offset).replace(escaper, escapeChar);
|
||||
index = offset + match.length;
|
||||
|
||||
if (escape) {
|
||||
source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
|
||||
} else if (interpolate) {
|
||||
source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
|
||||
} else if (evaluate) {
|
||||
source += "';\n" + evaluate + "\n__p+='";
|
||||
}
|
||||
|
||||
// Adobe VMs need the match returned to produce the correct offest.
|
||||
return match;
|
||||
});
|
||||
source += "';\n";
|
||||
|
||||
// If a variable is not specified, place data values in local scope.
|
||||
if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
|
||||
|
||||
source = "var __t,__p='',__j=Array.prototype.join," +
|
||||
"print=function(){__p+=__j.call(arguments,'');};\n" +
|
||||
source + 'return __p;\n';
|
||||
|
||||
try {
|
||||
var render = new Function(settings.variable || 'obj', '_', source);
|
||||
} catch (e) {
|
||||
e.source = source;
|
||||
throw e;
|
||||
}
|
||||
|
||||
var template = function(data) {
|
||||
return render.call(this, data, _);
|
||||
};
|
||||
|
||||
// Provide the compiled source as a convenience for precompilation.
|
||||
var argument = settings.variable || 'obj';
|
||||
template.source = 'function(' + argument + '){\n' + source + '}';
|
||||
|
||||
return template;
|
||||
};
|
||||
|
||||
// Add a "chain" function. Start chaining a wrapped Underscore object.
|
||||
_.chain = function(obj) {
|
||||
var instance = _(obj);
|
||||
instance._chain = true;
|
||||
return instance;
|
||||
};
|
||||
|
||||
// OOP
|
||||
// ---------------
|
||||
// If Underscore is called as a function, it returns a wrapped object that
|
||||
// can be used OO-style. This wrapper holds altered versions of all the
|
||||
// underscore functions. Wrapped objects may be chained.
|
||||
|
||||
// Helper function to continue chaining intermediate results.
|
||||
var result = function(instance, obj) {
|
||||
return instance._chain ? _(obj).chain() : obj;
|
||||
};
|
||||
|
||||
// Add your own custom functions to the Underscore object.
|
||||
_.mixin = function(obj) {
|
||||
_.each(_.functions(obj), function(name) {
|
||||
var func = _[name] = obj[name];
|
||||
_.prototype[name] = function() {
|
||||
var args = [this._wrapped];
|
||||
push.apply(args, arguments);
|
||||
return result(this, func.apply(_, args));
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
// Add all of the Underscore functions to the wrapper object.
|
||||
_.mixin(_);
|
||||
|
||||
// Add all mutator Array functions to the wrapper.
|
||||
_.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
|
||||
var method = ArrayProto[name];
|
||||
_.prototype[name] = function() {
|
||||
var obj = this._wrapped;
|
||||
method.apply(obj, arguments);
|
||||
if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0];
|
||||
return result(this, obj);
|
||||
};
|
||||
});
|
||||
|
||||
// Add all accessor Array functions to the wrapper.
|
||||
_.each(['concat', 'join', 'slice'], function(name) {
|
||||
var method = ArrayProto[name];
|
||||
_.prototype[name] = function() {
|
||||
return result(this, method.apply(this._wrapped, arguments));
|
||||
};
|
||||
});
|
||||
|
||||
// Extracts the result from a wrapped and chained object.
|
||||
_.prototype.value = function() {
|
||||
return this._wrapped;
|
||||
};
|
||||
|
||||
// Provide unwrapping proxy for some methods used in engine operations
|
||||
// such as arithmetic and JSON stringification.
|
||||
_.prototype.valueOf = _.prototype.toJSON = _.prototype.value;
|
||||
|
||||
_.prototype.toString = function() {
|
||||
return '' + this._wrapped;
|
||||
};
|
||||
|
||||
// AMD registration happens at the end for compatibility with AMD loaders
|
||||
// that may not enforce next-turn semantics on modules. Even though general
|
||||
// practice for AMD registration is to be anonymous, underscore registers
|
||||
// as a named module because, like jQuery, it is a base library that is
|
||||
// popular enough to be bundled in a third party lib, but not be part of
|
||||
// an AMD load request. Those cases could generate an error when an
|
||||
// anonymous define() is called outside of a loader request.
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define('underscore', [], function() {
|
||||
return _;
|
||||
});
|
||||
}
|
||||
}.call(this));
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 941:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var basiccreds_1 = __webpack_require__(12);
|
||||
exports.BasicCredentialHandler = basiccreds_1.BasicCredentialHandler;
|
||||
var bearertoken_1 = __webpack_require__(571);
|
||||
exports.BearerCredentialHandler = bearertoken_1.BearerCredentialHandler;
|
||||
var ntlm_1 = __webpack_require__(525);
|
||||
exports.NtlmCredentialHandler = ntlm_1.NtlmCredentialHandler;
|
||||
var personalaccesstoken_1 = __webpack_require__(327);
|
||||
exports.PersonalAccessTokenCredentialHandler = personalaccesstoken_1.PersonalAccessTokenCredentialHandler;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 943:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
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 __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 exec_1 = __webpack_require__(986);
|
||||
const io = __importStar(__webpack_require__(1));
|
||||
const fs_1 = __webpack_require__(747);
|
||||
function getTarPath() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
// Explicitly use BSD Tar on Windows
|
||||
const IS_WINDOWS = process.platform === "win32";
|
||||
if (IS_WINDOWS) {
|
||||
const systemTar = `${process.env["windir"]}\\System32\\tar.exe`;
|
||||
if (fs_1.existsSync(systemTar)) {
|
||||
return systemTar;
|
||||
}
|
||||
}
|
||||
return yield io.which("tar", true);
|
||||
});
|
||||
}
|
||||
function execTar(args) {
|
||||
var _a, _b;
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
const tarPath = yield getTarPath();
|
||||
const tarExec = process.platform !== "win32" ? `sudo ${tarPath}` : tarPath;
|
||||
yield exec_1.exec(`"${tarExec}"`, args);
|
||||
}
|
||||
catch (error) {
|
||||
const IS_WINDOWS = process.platform === "win32";
|
||||
if (IS_WINDOWS) {
|
||||
throw new Error(`Tar failed with error: ${(_a = error) === null || _a === void 0 ? void 0 : _a.message}. Ensure BSD tar is installed and on the PATH.`);
|
||||
}
|
||||
throw new Error(`Tar failed with error: ${(_b = error) === null || _b === void 0 ? void 0 : _b.message}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
function extractTar(archivePath, targetDirectory) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
// Create directory to extract tar into
|
||||
yield io.mkdirP(targetDirectory);
|
||||
const args = ["-xz", "-f", archivePath, "-C", targetDirectory];
|
||||
yield execTar(args);
|
||||
});
|
||||
}
|
||||
exports.extractTar = extractTar;
|
||||
function createTar(archivePath, sourceDirectory) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const args = ["-cz", "-f", archivePath, "-C", sourceDirectory, "."];
|
||||
yield execTar(args);
|
||||
});
|
||||
}
|
||||
exports.createTar = createTar;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 986:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
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());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const tr = __webpack_require__(9);
|
||||
/**
|
||||
* Exec a command.
|
||||
* Output will be streamed to the live console.
|
||||
* Returns promise with return code
|
||||
*
|
||||
* @param commandLine command to execute (can include additional args). Must be correctly escaped.
|
||||
* @param args optional arguments for tool. Escaping is handled by the lib.
|
||||
* @param options optional exec options. See ExecOptions
|
||||
* @returns Promise<number> exit code
|
||||
*/
|
||||
function exec(commandLine, args, options) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const commandArgs = tr.argStringToArray(commandLine);
|
||||
if (commandArgs.length === 0) {
|
||||
throw new Error(`Parameter 'commandLine' cannot be null or empty.`);
|
||||
}
|
||||
// Path to tool to execute should be first arg
|
||||
const toolPath = commandArgs[0];
|
||||
args = commandArgs.slice(1).concat(args || []);
|
||||
const runner = new tr.ToolRunner(toolPath, args, options);
|
||||
return runner.exec();
|
||||
});
|
||||
}
|
||||
exports.exec = exec;
|
||||
//# sourceMappingURL=exec.js.map
|
||||
|
||||
/***/ })
|
||||
|
||||
/******/ });
|
||||
5240
dist/save/index.js
vendored
Normal file
5240
dist/save/index.js
vendored
Normal file
@ -0,0 +1,5240 @@
|
||||
module.exports =
|
||||
/******/ (function(modules, runtime) { // webpackBootstrap
|
||||
/******/ "use strict";
|
||||
/******/ // The module cache
|
||||
/******/ var installedModules = {};
|
||||
/******/
|
||||
/******/ // The require function
|
||||
/******/ function __webpack_require__(moduleId) {
|
||||
/******/
|
||||
/******/ // Check if module is in cache
|
||||
/******/ if(installedModules[moduleId]) {
|
||||
/******/ return installedModules[moduleId].exports;
|
||||
/******/ }
|
||||
/******/ // Create a new module (and put it into the cache)
|
||||
/******/ var module = installedModules[moduleId] = {
|
||||
/******/ i: moduleId,
|
||||
/******/ l: false,
|
||||
/******/ exports: {}
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Execute the module function
|
||||
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
||||
/******/
|
||||
/******/ // Flag the module as loaded
|
||||
/******/ module.l = true;
|
||||
/******/
|
||||
/******/ // Return the exports of the module
|
||||
/******/ return module.exports;
|
||||
/******/ }
|
||||
/******/
|
||||
/******/
|
||||
/******/ __webpack_require__.ab = __dirname + "/";
|
||||
/******/
|
||||
/******/ // the startup function
|
||||
/******/ function startup() {
|
||||
/******/ // Load entry module and return exports
|
||||
/******/ return __webpack_require__(681);
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // run startup
|
||||
/******/ return startup();
|
||||
/******/ })
|
||||
/************************************************************************/
|
||||
/******/ ({
|
||||
|
||||
/***/ 1:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
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());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const childProcess = __webpack_require__(129);
|
||||
const path = __webpack_require__(622);
|
||||
const util_1 = __webpack_require__(669);
|
||||
const ioUtil = __webpack_require__(672);
|
||||
const exec = util_1.promisify(childProcess.exec);
|
||||
/**
|
||||
* Copies a file or folder.
|
||||
* Based off of shelljs - https://github.com/shelljs/shelljs/blob/9237f66c52e5daa40458f94f9565e18e8132f5a6/src/cp.js
|
||||
*
|
||||
* @param source source path
|
||||
* @param dest destination path
|
||||
* @param options optional. See CopyOptions.
|
||||
*/
|
||||
function cp(source, dest, options = {}) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const { force, recursive } = readCopyOptions(options);
|
||||
const destStat = (yield ioUtil.exists(dest)) ? yield ioUtil.stat(dest) : null;
|
||||
// Dest is an existing file, but not forcing
|
||||
if (destStat && destStat.isFile() && !force) {
|
||||
return;
|
||||
}
|
||||
// If dest is an existing directory, should copy inside.
|
||||
const newDest = destStat && destStat.isDirectory()
|
||||
? path.join(dest, path.basename(source))
|
||||
: dest;
|
||||
if (!(yield ioUtil.exists(source))) {
|
||||
throw new Error(`no such file or directory: ${source}`);
|
||||
}
|
||||
const sourceStat = yield ioUtil.stat(source);
|
||||
if (sourceStat.isDirectory()) {
|
||||
if (!recursive) {
|
||||
throw new Error(`Failed to copy. ${source} is a directory, but tried to copy without recursive flag.`);
|
||||
}
|
||||
else {
|
||||
yield cpDirRecursive(source, newDest, 0, force);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (path.relative(source, newDest) === '') {
|
||||
// a file cannot be copied to itself
|
||||
throw new Error(`'${newDest}' and '${source}' are the same file`);
|
||||
}
|
||||
yield copyFile(source, newDest, force);
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.cp = cp;
|
||||
/**
|
||||
* Moves a path.
|
||||
*
|
||||
* @param source source path
|
||||
* @param dest destination path
|
||||
* @param options optional. See MoveOptions.
|
||||
*/
|
||||
function mv(source, dest, options = {}) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (yield ioUtil.exists(dest)) {
|
||||
let destExists = true;
|
||||
if (yield ioUtil.isDirectory(dest)) {
|
||||
// If dest is directory copy src into dest
|
||||
dest = path.join(dest, path.basename(source));
|
||||
destExists = yield ioUtil.exists(dest);
|
||||
}
|
||||
if (destExists) {
|
||||
if (options.force == null || options.force) {
|
||||
yield rmRF(dest);
|
||||
}
|
||||
else {
|
||||
throw new Error('Destination already exists');
|
||||
}
|
||||
}
|
||||
}
|
||||
yield mkdirP(path.dirname(dest));
|
||||
yield ioUtil.rename(source, dest);
|
||||
});
|
||||
}
|
||||
exports.mv = mv;
|
||||
/**
|
||||
* Remove a path recursively with force
|
||||
*
|
||||
* @param inputPath path to remove
|
||||
*/
|
||||
function rmRF(inputPath) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (ioUtil.IS_WINDOWS) {
|
||||
// Node doesn't provide a delete operation, only an unlink function. This means that if the file is being used by another
|
||||
// program (e.g. antivirus), it won't be deleted. To address this, we shell out the work to rd/del.
|
||||
try {
|
||||
if (yield ioUtil.isDirectory(inputPath, true)) {
|
||||
yield exec(`rd /s /q "${inputPath}"`);
|
||||
}
|
||||
else {
|
||||
yield exec(`del /f /a "${inputPath}"`);
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
// if you try to delete a file that doesn't exist, desired result is achieved
|
||||
// other errors are valid
|
||||
if (err.code !== 'ENOENT')
|
||||
throw err;
|
||||
}
|
||||
// Shelling out fails to remove a symlink folder with missing source, this unlink catches that
|
||||
try {
|
||||
yield ioUtil.unlink(inputPath);
|
||||
}
|
||||
catch (err) {
|
||||
// if you try to delete a file that doesn't exist, desired result is achieved
|
||||
// other errors are valid
|
||||
if (err.code !== 'ENOENT')
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
else {
|
||||
let isDir = false;
|
||||
try {
|
||||
isDir = yield ioUtil.isDirectory(inputPath);
|
||||
}
|
||||
catch (err) {
|
||||
// if you try to delete a file that doesn't exist, desired result is achieved
|
||||
// other errors are valid
|
||||
if (err.code !== 'ENOENT')
|
||||
throw err;
|
||||
return;
|
||||
}
|
||||
if (isDir) {
|
||||
yield exec(`rm -rf "${inputPath}"`);
|
||||
}
|
||||
else {
|
||||
yield ioUtil.unlink(inputPath);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.rmRF = rmRF;
|
||||
/**
|
||||
* Make a directory. Creates the full path with folders in between
|
||||
* Will throw if it fails
|
||||
*
|
||||
* @param fsPath path to create
|
||||
* @returns Promise<void>
|
||||
*/
|
||||
function mkdirP(fsPath) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
yield ioUtil.mkdirP(fsPath);
|
||||
});
|
||||
}
|
||||
exports.mkdirP = mkdirP;
|
||||
/**
|
||||
* Returns path of a tool had the tool actually been invoked. Resolves via paths.
|
||||
* If you check and the tool does not exist, it will throw.
|
||||
*
|
||||
* @param tool name of the tool
|
||||
* @param check whether to check if tool exists
|
||||
* @returns Promise<string> path to tool
|
||||
*/
|
||||
function which(tool, check) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (!tool) {
|
||||
throw new Error("parameter 'tool' is required");
|
||||
}
|
||||
// recursive when check=true
|
||||
if (check) {
|
||||
const result = yield which(tool, false);
|
||||
if (!result) {
|
||||
if (ioUtil.IS_WINDOWS) {
|
||||
throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also verify the file has a valid extension for an executable file.`);
|
||||
}
|
||||
else {
|
||||
throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
// build the list of extensions to try
|
||||
const extensions = [];
|
||||
if (ioUtil.IS_WINDOWS && process.env.PATHEXT) {
|
||||
for (const extension of process.env.PATHEXT.split(path.delimiter)) {
|
||||
if (extension) {
|
||||
extensions.push(extension);
|
||||
}
|
||||
}
|
||||
}
|
||||
// if it's rooted, return it if exists. otherwise return empty.
|
||||
if (ioUtil.isRooted(tool)) {
|
||||
const filePath = yield ioUtil.tryGetExecutablePath(tool, extensions);
|
||||
if (filePath) {
|
||||
return filePath;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
// if any path separators, return empty
|
||||
if (tool.includes('/') || (ioUtil.IS_WINDOWS && tool.includes('\\'))) {
|
||||
return '';
|
||||
}
|
||||
// build the list of directories
|
||||
//
|
||||
// Note, technically "where" checks the current directory on Windows. From a toolkit perspective,
|
||||
// it feels like we should not do this. Checking the current directory seems like more of a use
|
||||
// case of a shell, and the which() function exposed by the toolkit should strive for consistency
|
||||
// across platforms.
|
||||
const directories = [];
|
||||
if (process.env.PATH) {
|
||||
for (const p of process.env.PATH.split(path.delimiter)) {
|
||||
if (p) {
|
||||
directories.push(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
// return the first match
|
||||
for (const directory of directories) {
|
||||
const filePath = yield ioUtil.tryGetExecutablePath(directory + path.sep + tool, extensions);
|
||||
if (filePath) {
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
catch (err) {
|
||||
throw new Error(`which failed with message ${err.message}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.which = which;
|
||||
function readCopyOptions(options) {
|
||||
const force = options.force == null ? true : options.force;
|
||||
const recursive = Boolean(options.recursive);
|
||||
return { force, recursive };
|
||||
}
|
||||
function cpDirRecursive(sourceDir, destDir, currentDepth, force) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
// Ensure there is not a run away recursive copy
|
||||
if (currentDepth >= 255)
|
||||
return;
|
||||
currentDepth++;
|
||||
yield mkdirP(destDir);
|
||||
const files = yield ioUtil.readdir(sourceDir);
|
||||
for (const fileName of files) {
|
||||
const srcFile = `${sourceDir}/${fileName}`;
|
||||
const destFile = `${destDir}/${fileName}`;
|
||||
const srcFileStat = yield ioUtil.lstat(srcFile);
|
||||
if (srcFileStat.isDirectory()) {
|
||||
// Recurse
|
||||
yield cpDirRecursive(srcFile, destFile, currentDepth, force);
|
||||
}
|
||||
else {
|
||||
yield copyFile(srcFile, destFile, force);
|
||||
}
|
||||
}
|
||||
// Change the mode for the newly created directory
|
||||
yield ioUtil.chmod(destDir, (yield ioUtil.stat(sourceDir)).mode);
|
||||
});
|
||||
}
|
||||
// Buffered file copy
|
||||
function copyFile(srcFile, destFile, force) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if ((yield ioUtil.lstat(srcFile)).isSymbolicLink()) {
|
||||
// unlink/re-link it
|
||||
try {
|
||||
yield ioUtil.lstat(destFile);
|
||||
yield ioUtil.unlink(destFile);
|
||||
}
|
||||
catch (e) {
|
||||
// Try to override file permission
|
||||
if (e.code === 'EPERM') {
|
||||
yield ioUtil.chmod(destFile, '0666');
|
||||
yield ioUtil.unlink(destFile);
|
||||
}
|
||||
// other errors = it doesn't exist, no work to do
|
||||
}
|
||||
// Copy over symlink
|
||||
const symlinkFull = yield ioUtil.readlink(srcFile);
|
||||
yield ioUtil.symlink(symlinkFull, destFile, ioUtil.IS_WINDOWS ? 'junction' : null);
|
||||
}
|
||||
else if (!(yield ioUtil.exists(destFile)) || force) {
|
||||
yield ioUtil.copyFile(srcFile, destFile);
|
||||
}
|
||||
});
|
||||
}
|
||||
//# sourceMappingURL=io.js.map
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 9:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
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());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const os = __webpack_require__(87);
|
||||
const events = __webpack_require__(614);
|
||||
const child = __webpack_require__(129);
|
||||
/* eslint-disable @typescript-eslint/unbound-method */
|
||||
const IS_WINDOWS = process.platform === 'win32';
|
||||
/*
|
||||
* Class for running command line tools. Handles quoting and arg parsing in a platform agnostic way.
|
||||
*/
|
||||
class ToolRunner extends events.EventEmitter {
|
||||
constructor(toolPath, args, options) {
|
||||
super();
|
||||
if (!toolPath) {
|
||||
throw new Error("Parameter 'toolPath' cannot be null or empty.");
|
||||
}
|
||||
this.toolPath = toolPath;
|
||||
this.args = args || [];
|
||||
this.options = options || {};
|
||||
}
|
||||
_debug(message) {
|
||||
if (this.options.listeners && this.options.listeners.debug) {
|
||||
this.options.listeners.debug(message);
|
||||
}
|
||||
}
|
||||
_getCommandString(options, noPrefix) {
|
||||
const toolPath = this._getSpawnFileName();
|
||||
const args = this._getSpawnArgs(options);
|
||||
let cmd = noPrefix ? '' : '[command]'; // omit prefix when piped to a second tool
|
||||
if (IS_WINDOWS) {
|
||||
// Windows + cmd file
|
||||
if (this._isCmdFile()) {
|
||||
cmd += toolPath;
|
||||
for (const a of args) {
|
||||
cmd += ` ${a}`;
|
||||
}
|
||||
}
|
||||
// Windows + verbatim
|
||||
else if (options.windowsVerbatimArguments) {
|
||||
cmd += `"${toolPath}"`;
|
||||
for (const a of args) {
|
||||
cmd += ` ${a}`;
|
||||
}
|
||||
}
|
||||
// Windows (regular)
|
||||
else {
|
||||
cmd += this._windowsQuoteCmdArg(toolPath);
|
||||
for (const a of args) {
|
||||
cmd += ` ${this._windowsQuoteCmdArg(a)}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// OSX/Linux - this can likely be improved with some form of quoting.
|
||||
// creating processes on Unix is fundamentally different than Windows.
|
||||
// on Unix, execvp() takes an arg array.
|
||||
cmd += toolPath;
|
||||
for (const a of args) {
|
||||
cmd += ` ${a}`;
|
||||
}
|
||||
}
|
||||
return cmd;
|
||||
}
|
||||
_processLineBuffer(data, strBuffer, onLine) {
|
||||
try {
|
||||
let s = strBuffer + data.toString();
|
||||
let n = s.indexOf(os.EOL);
|
||||
while (n > -1) {
|
||||
const line = s.substring(0, n);
|
||||
onLine(line);
|
||||
// the rest of the string ...
|
||||
s = s.substring(n + os.EOL.length);
|
||||
n = s.indexOf(os.EOL);
|
||||
}
|
||||
strBuffer = s;
|
||||
}
|
||||
catch (err) {
|
||||
// streaming lines to console is best effort. Don't fail a build.
|
||||
this._debug(`error processing line. Failed with error ${err}`);
|
||||
}
|
||||
}
|
||||
_getSpawnFileName() {
|
||||
if (IS_WINDOWS) {
|
||||
if (this._isCmdFile()) {
|
||||
return process.env['COMSPEC'] || 'cmd.exe';
|
||||
}
|
||||
}
|
||||
return this.toolPath;
|
||||
}
|
||||
_getSpawnArgs(options) {
|
||||
if (IS_WINDOWS) {
|
||||
if (this._isCmdFile()) {
|
||||
let argline = `/D /S /C "${this._windowsQuoteCmdArg(this.toolPath)}`;
|
||||
for (const a of this.args) {
|
||||
argline += ' ';
|
||||
argline += options.windowsVerbatimArguments
|
||||
? a
|
||||
: this._windowsQuoteCmdArg(a);
|
||||
}
|
||||
argline += '"';
|
||||
return [argline];
|
||||
}
|
||||
}
|
||||
return this.args;
|
||||
}
|
||||
_endsWith(str, end) {
|
||||
return str.endsWith(end);
|
||||
}
|
||||
_isCmdFile() {
|
||||
const upperToolPath = this.toolPath.toUpperCase();
|
||||
return (this._endsWith(upperToolPath, '.CMD') ||
|
||||
this._endsWith(upperToolPath, '.BAT'));
|
||||
}
|
||||
_windowsQuoteCmdArg(arg) {
|
||||
// for .exe, apply the normal quoting rules that libuv applies
|
||||
if (!this._isCmdFile()) {
|
||||
return this._uvQuoteCmdArg(arg);
|
||||
}
|
||||
// otherwise apply quoting rules specific to the cmd.exe command line parser.
|
||||
// the libuv rules are generic and are not designed specifically for cmd.exe
|
||||
// command line parser.
|
||||
//
|
||||
// for a detailed description of the cmd.exe command line parser, refer to
|
||||
// http://stackoverflow.com/questions/4094699/how-does-the-windows-command-interpreter-cmd-exe-parse-scripts/7970912#7970912
|
||||
// need quotes for empty arg
|
||||
if (!arg) {
|
||||
return '""';
|
||||
}
|
||||
// determine whether the arg needs to be quoted
|
||||
const cmdSpecialChars = [
|
||||
' ',
|
||||
'\t',
|
||||
'&',
|
||||
'(',
|
||||
')',
|
||||
'[',
|
||||
']',
|
||||
'{',
|
||||
'}',
|
||||
'^',
|
||||
'=',
|
||||
';',
|
||||
'!',
|
||||
"'",
|
||||
'+',
|
||||
',',
|
||||
'`',
|
||||
'~',
|
||||
'|',
|
||||
'<',
|
||||
'>',
|
||||
'"'
|
||||
];
|
||||
let needsQuotes = false;
|
||||
for (const char of arg) {
|
||||
if (cmdSpecialChars.some(x => x === char)) {
|
||||
needsQuotes = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// short-circuit if quotes not needed
|
||||
if (!needsQuotes) {
|
||||
return arg;
|
||||
}
|
||||
// the following quoting rules are very similar to the rules that by libuv applies.
|
||||
//
|
||||
// 1) wrap the string in quotes
|
||||
//
|
||||
// 2) double-up quotes - i.e. " => ""
|
||||
//
|
||||
// this is different from the libuv quoting rules. libuv replaces " with \", which unfortunately
|
||||
// doesn't work well with a cmd.exe command line.
|
||||
//
|
||||
// note, replacing " with "" also works well if the arg is passed to a downstream .NET console app.
|
||||
// for example, the command line:
|
||||
// foo.exe "myarg:""my val"""
|
||||
// is parsed by a .NET console app into an arg array:
|
||||
// [ "myarg:\"my val\"" ]
|
||||
// which is the same end result when applying libuv quoting rules. although the actual
|
||||
// command line from libuv quoting rules would look like:
|
||||
// foo.exe "myarg:\"my val\""
|
||||
//
|
||||
// 3) double-up slashes that precede a quote,
|
||||
// e.g. hello \world => "hello \world"
|
||||
// hello\"world => "hello\\""world"
|
||||
// hello\\"world => "hello\\\\""world"
|
||||
// hello world\ => "hello world\\"
|
||||
//
|
||||
// technically this is not required for a cmd.exe command line, or the batch argument parser.
|
||||
// the reasons for including this as a .cmd quoting rule are:
|
||||
//
|
||||
// a) this is optimized for the scenario where the argument is passed from the .cmd file to an
|
||||
// external program. many programs (e.g. .NET console apps) rely on the slash-doubling rule.
|
||||
//
|
||||
// b) it's what we've been doing previously (by deferring to node default behavior) and we
|
||||
// haven't heard any complaints about that aspect.
|
||||
//
|
||||
// note, a weakness of the quoting rules chosen here, is that % is not escaped. in fact, % cannot be
|
||||
// escaped when used on the command line directly - even though within a .cmd file % can be escaped
|
||||
// by using %%.
|
||||
//
|
||||
// the saving grace is, on the command line, %var% is left as-is if var is not defined. this contrasts
|
||||
// the line parsing rules within a .cmd file, where if var is not defined it is replaced with nothing.
|
||||
//
|
||||
// one option that was explored was replacing % with ^% - i.e. %var% => ^%var^%. this hack would
|
||||
// often work, since it is unlikely that var^ would exist, and the ^ character is removed when the
|
||||
// variable is used. the problem, however, is that ^ is not removed when %* is used to pass the args
|
||||
// to an external program.
|
||||
//
|
||||
// an unexplored potential solution for the % escaping problem, is to create a wrapper .cmd file.
|
||||
// % can be escaped within a .cmd file.
|
||||
let reverse = '"';
|
||||
let quoteHit = true;
|
||||
for (let i = arg.length; i > 0; i--) {
|
||||
// walk the string in reverse
|
||||
reverse += arg[i - 1];
|
||||
if (quoteHit && arg[i - 1] === '\\') {
|
||||
reverse += '\\'; // double the slash
|
||||
}
|
||||
else if (arg[i - 1] === '"') {
|
||||
quoteHit = true;
|
||||
reverse += '"'; // double the quote
|
||||
}
|
||||
else {
|
||||
quoteHit = false;
|
||||
}
|
||||
}
|
||||
reverse += '"';
|
||||
return reverse
|
||||
.split('')
|
||||
.reverse()
|
||||
.join('');
|
||||
}
|
||||
_uvQuoteCmdArg(arg) {
|
||||
// Tool runner wraps child_process.spawn() and needs to apply the same quoting as
|
||||
// Node in certain cases where the undocumented spawn option windowsVerbatimArguments
|
||||
// is used.
|
||||
//
|
||||
// Since this function is a port of quote_cmd_arg from Node 4.x (technically, lib UV,
|
||||
// see https://github.com/nodejs/node/blob/v4.x/deps/uv/src/win/process.c for details),
|
||||
// pasting copyright notice from Node within this function:
|
||||
//
|
||||
// Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
if (!arg) {
|
||||
// Need double quotation for empty argument
|
||||
return '""';
|
||||
}
|
||||
if (!arg.includes(' ') && !arg.includes('\t') && !arg.includes('"')) {
|
||||
// No quotation needed
|
||||
return arg;
|
||||
}
|
||||
if (!arg.includes('"') && !arg.includes('\\')) {
|
||||
// No embedded double quotes or backslashes, so I can just wrap
|
||||
// quote marks around the whole thing.
|
||||
return `"${arg}"`;
|
||||
}
|
||||
// Expected input/output:
|
||||
// input : hello"world
|
||||
// output: "hello\"world"
|
||||
// input : hello""world
|
||||
// output: "hello\"\"world"
|
||||
// input : hello\world
|
||||
// output: hello\world
|
||||
// input : hello\\world
|
||||
// output: hello\\world
|
||||
// input : hello\"world
|
||||
// output: "hello\\\"world"
|
||||
// input : hello\\"world
|
||||
// output: "hello\\\\\"world"
|
||||
// input : hello world\
|
||||
// output: "hello world\\" - note the comment in libuv actually reads "hello world\"
|
||||
// but it appears the comment is wrong, it should be "hello world\\"
|
||||
let reverse = '"';
|
||||
let quoteHit = true;
|
||||
for (let i = arg.length; i > 0; i--) {
|
||||
// walk the string in reverse
|
||||
reverse += arg[i - 1];
|
||||
if (quoteHit && arg[i - 1] === '\\') {
|
||||
reverse += '\\';
|
||||
}
|
||||
else if (arg[i - 1] === '"') {
|
||||
quoteHit = true;
|
||||
reverse += '\\';
|
||||
}
|
||||
else {
|
||||
quoteHit = false;
|
||||
}
|
||||
}
|
||||
reverse += '"';
|
||||
return reverse
|
||||
.split('')
|
||||
.reverse()
|
||||
.join('');
|
||||
}
|
||||
_cloneExecOptions(options) {
|
||||
options = options || {};
|
||||
const result = {
|
||||
cwd: options.cwd || process.cwd(),
|
||||
env: options.env || process.env,
|
||||
silent: options.silent || false,
|
||||
windowsVerbatimArguments: options.windowsVerbatimArguments || false,
|
||||
failOnStdErr: options.failOnStdErr || false,
|
||||
ignoreReturnCode: options.ignoreReturnCode || false,
|
||||
delay: options.delay || 10000
|
||||
};
|
||||
result.outStream = options.outStream || process.stdout;
|
||||
result.errStream = options.errStream || process.stderr;
|
||||
return result;
|
||||
}
|
||||
_getSpawnOptions(options, toolPath) {
|
||||
options = options || {};
|
||||
const result = {};
|
||||
result.cwd = options.cwd;
|
||||
result.env = options.env;
|
||||
result['windowsVerbatimArguments'] =
|
||||
options.windowsVerbatimArguments || this._isCmdFile();
|
||||
if (options.windowsVerbatimArguments) {
|
||||
result.argv0 = `"${toolPath}"`;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Exec a tool.
|
||||
* Output will be streamed to the live console.
|
||||
* Returns promise with return code
|
||||
*
|
||||
* @param tool path to tool to exec
|
||||
* @param options optional exec options. See ExecOptions
|
||||
* @returns number
|
||||
*/
|
||||
exec() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
return new Promise((resolve, reject) => {
|
||||
this._debug(`exec tool: ${this.toolPath}`);
|
||||
this._debug('arguments:');
|
||||
for (const arg of this.args) {
|
||||
this._debug(` ${arg}`);
|
||||
}
|
||||
const optionsNonNull = this._cloneExecOptions(this.options);
|
||||
if (!optionsNonNull.silent && optionsNonNull.outStream) {
|
||||
optionsNonNull.outStream.write(this._getCommandString(optionsNonNull) + os.EOL);
|
||||
}
|
||||
const state = new ExecState(optionsNonNull, this.toolPath);
|
||||
state.on('debug', (message) => {
|
||||
this._debug(message);
|
||||
});
|
||||
const fileName = this._getSpawnFileName();
|
||||
const cp = child.spawn(fileName, this._getSpawnArgs(optionsNonNull), this._getSpawnOptions(this.options, fileName));
|
||||
const stdbuffer = '';
|
||||
if (cp.stdout) {
|
||||
cp.stdout.on('data', (data) => {
|
||||
if (this.options.listeners && this.options.listeners.stdout) {
|
||||
this.options.listeners.stdout(data);
|
||||
}
|
||||
if (!optionsNonNull.silent && optionsNonNull.outStream) {
|
||||
optionsNonNull.outStream.write(data);
|
||||
}
|
||||
this._processLineBuffer(data, stdbuffer, (line) => {
|
||||
if (this.options.listeners && this.options.listeners.stdline) {
|
||||
this.options.listeners.stdline(line);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
const errbuffer = '';
|
||||
if (cp.stderr) {
|
||||
cp.stderr.on('data', (data) => {
|
||||
state.processStderr = true;
|
||||
if (this.options.listeners && this.options.listeners.stderr) {
|
||||
this.options.listeners.stderr(data);
|
||||
}
|
||||
if (!optionsNonNull.silent &&
|
||||
optionsNonNull.errStream &&
|
||||
optionsNonNull.outStream) {
|
||||
const s = optionsNonNull.failOnStdErr
|
||||
? optionsNonNull.errStream
|
||||
: optionsNonNull.outStream;
|
||||
s.write(data);
|
||||
}
|
||||
this._processLineBuffer(data, errbuffer, (line) => {
|
||||
if (this.options.listeners && this.options.listeners.errline) {
|
||||
this.options.listeners.errline(line);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
cp.on('error', (err) => {
|
||||
state.processError = err.message;
|
||||
state.processExited = true;
|
||||
state.processClosed = true;
|
||||
state.CheckComplete();
|
||||
});
|
||||
cp.on('exit', (code) => {
|
||||
state.processExitCode = code;
|
||||
state.processExited = true;
|
||||
this._debug(`Exit code ${code} received from tool '${this.toolPath}'`);
|
||||
state.CheckComplete();
|
||||
});
|
||||
cp.on('close', (code) => {
|
||||
state.processExitCode = code;
|
||||
state.processExited = true;
|
||||
state.processClosed = true;
|
||||
this._debug(`STDIO streams have closed for tool '${this.toolPath}'`);
|
||||
state.CheckComplete();
|
||||
});
|
||||
state.on('done', (error, exitCode) => {
|
||||
if (stdbuffer.length > 0) {
|
||||
this.emit('stdline', stdbuffer);
|
||||
}
|
||||
if (errbuffer.length > 0) {
|
||||
this.emit('errline', errbuffer);
|
||||
}
|
||||
cp.removeAllListeners();
|
||||
if (error) {
|
||||
reject(error);
|
||||
}
|
||||
else {
|
||||
resolve(exitCode);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.ToolRunner = ToolRunner;
|
||||
/**
|
||||
* Convert an arg string to an array of args. Handles escaping
|
||||
*
|
||||
* @param argString string of arguments
|
||||
* @returns string[] array of arguments
|
||||
*/
|
||||
function argStringToArray(argString) {
|
||||
const args = [];
|
||||
let inQuotes = false;
|
||||
let escaped = false;
|
||||
let arg = '';
|
||||
function append(c) {
|
||||
// we only escape double quotes.
|
||||
if (escaped && c !== '"') {
|
||||
arg += '\\';
|
||||
}
|
||||
arg += c;
|
||||
escaped = false;
|
||||
}
|
||||
for (let i = 0; i < argString.length; i++) {
|
||||
const c = argString.charAt(i);
|
||||
if (c === '"') {
|
||||
if (!escaped) {
|
||||
inQuotes = !inQuotes;
|
||||
}
|
||||
else {
|
||||
append(c);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (c === '\\' && escaped) {
|
||||
append(c);
|
||||
continue;
|
||||
}
|
||||
if (c === '\\' && inQuotes) {
|
||||
escaped = true;
|
||||
continue;
|
||||
}
|
||||
if (c === ' ' && !inQuotes) {
|
||||
if (arg.length > 0) {
|
||||
args.push(arg);
|
||||
arg = '';
|
||||
}
|
||||
continue;
|
||||
}
|
||||
append(c);
|
||||
}
|
||||
if (arg.length > 0) {
|
||||
args.push(arg.trim());
|
||||
}
|
||||
return args;
|
||||
}
|
||||
exports.argStringToArray = argStringToArray;
|
||||
class ExecState extends events.EventEmitter {
|
||||
constructor(options, toolPath) {
|
||||
super();
|
||||
this.processClosed = false; // tracks whether the process has exited and stdio is closed
|
||||
this.processError = '';
|
||||
this.processExitCode = 0;
|
||||
this.processExited = false; // tracks whether the process has exited
|
||||
this.processStderr = false; // tracks whether stderr was written to
|
||||
this.delay = 10000; // 10 seconds
|
||||
this.done = false;
|
||||
this.timeout = null;
|
||||
if (!toolPath) {
|
||||
throw new Error('toolPath must not be empty');
|
||||
}
|
||||
this.options = options;
|
||||
this.toolPath = toolPath;
|
||||
if (options.delay) {
|
||||
this.delay = options.delay;
|
||||
}
|
||||
}
|
||||
CheckComplete() {
|
||||
if (this.done) {
|
||||
return;
|
||||
}
|
||||
if (this.processClosed) {
|
||||
this._setResult();
|
||||
}
|
||||
else if (this.processExited) {
|
||||
this.timeout = setTimeout(ExecState.HandleTimeout, this.delay, this);
|
||||
}
|
||||
}
|
||||
_debug(message) {
|
||||
this.emit('debug', message);
|
||||
}
|
||||
_setResult() {
|
||||
// determine whether there is an error
|
||||
let error;
|
||||
if (this.processExited) {
|
||||
if (this.processError) {
|
||||
error = new Error(`There was an error when attempting to execute the process '${this.toolPath}'. This may indicate the process failed to start. Error: ${this.processError}`);
|
||||
}
|
||||
else if (this.processExitCode !== 0 && !this.options.ignoreReturnCode) {
|
||||
error = new Error(`The process '${this.toolPath}' failed with exit code ${this.processExitCode}`);
|
||||
}
|
||||
else if (this.processStderr && this.options.failOnStdErr) {
|
||||
error = new Error(`The process '${this.toolPath}' failed because one or more lines were written to the STDERR stream`);
|
||||
}
|
||||
}
|
||||
// clear the timeout
|
||||
if (this.timeout) {
|
||||
clearTimeout(this.timeout);
|
||||
this.timeout = null;
|
||||
}
|
||||
this.done = true;
|
||||
this.emit('done', error, this.processExitCode);
|
||||
}
|
||||
static HandleTimeout(state) {
|
||||
if (state.done) {
|
||||
return;
|
||||
}
|
||||
if (!state.processClosed && state.processExited) {
|
||||
const message = `The STDIO streams did not close within ${state.delay /
|
||||
1000} seconds of the exit event from process '${state.toolPath}'. This may indicate a child process inherited the STDIO streams and has not yet exited.`;
|
||||
state._debug(message);
|
||||
}
|
||||
state._setResult();
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=toolrunner.js.map
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 12:
|
||||
/***/ (function(__unusedmodule, exports) {
|
||||
|
||||
"use strict";
|
||||
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
class BasicCredentialHandler {
|
||||
constructor(username, password) {
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
}
|
||||
// currently implements pre-authorization
|
||||
// TODO: support preAuth = false where it hooks on 401
|
||||
prepareRequest(options) {
|
||||
options.headers['Authorization'] = 'Basic ' + new Buffer(this.username + ':' + this.password).toString('base64');
|
||||
options.headers['X-TFS-FedAuthRedirect'] = 'Suppress';
|
||||
}
|
||||
// This handler cannot handle 401
|
||||
canHandleAuthentication(response) {
|
||||
return false;
|
||||
}
|
||||
handleAuthentication(httpClient, requestInfo, objs) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
exports.BasicCredentialHandler = BasicCredentialHandler;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 16:
|
||||
/***/ (function(module) {
|
||||
|
||||
module.exports = require("tls");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 87:
|
||||
/***/ (function(module) {
|
||||
|
||||
module.exports = require("os");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 105:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
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());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const httpm = __webpack_require__(874);
|
||||
const util = __webpack_require__(729);
|
||||
class RestClient {
|
||||
/**
|
||||
* Creates an instance of the RestClient
|
||||
* @constructor
|
||||
* @param {string} userAgent - userAgent for requests
|
||||
* @param {string} baseUrl - (Optional) If not specified, use full urls per request. If supplied and a function passes a relative url, it will be appended to this
|
||||
* @param {ifm.IRequestHandler[]} handlers - handlers are typically auth handlers (basic, bearer, ntlm supplied)
|
||||
* @param {ifm.IRequestOptions} requestOptions - options for each http requests (http proxy setting, socket timeout)
|
||||
*/
|
||||
constructor(userAgent, baseUrl, handlers, requestOptions) {
|
||||
this.client = new httpm.HttpClient(userAgent, handlers, requestOptions);
|
||||
if (baseUrl) {
|
||||
this._baseUrl = baseUrl;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Gets a resource from an endpoint
|
||||
* Be aware that not found returns a null. Other error conditions reject the promise
|
||||
* @param {string} requestUrl - fully qualified or relative url
|
||||
* @param {IRequestOptions} requestOptions - (optional) requestOptions object
|
||||
*/
|
||||
options(requestUrl, options) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let url = util.getUrl(requestUrl, this._baseUrl);
|
||||
let res = yield this.client.options(url, this._headersFromOptions(options));
|
||||
return this._processResponse(res, options);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Gets a resource from an endpoint
|
||||
* Be aware that not found returns a null. Other error conditions reject the promise
|
||||
* @param {string} resource - fully qualified url or relative path
|
||||
* @param {IRequestOptions} requestOptions - (optional) requestOptions object
|
||||
*/
|
||||
get(resource, options) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let url = util.getUrl(resource, this._baseUrl);
|
||||
let res = yield this.client.get(url, this._headersFromOptions(options));
|
||||
return this._processResponse(res, options);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Deletes a resource from an endpoint
|
||||
* Be aware that not found returns a null. Other error conditions reject the promise
|
||||
* @param {string} resource - fully qualified or relative url
|
||||
* @param {IRequestOptions} requestOptions - (optional) requestOptions object
|
||||
*/
|
||||
del(resource, options) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let url = util.getUrl(resource, this._baseUrl);
|
||||
let res = yield this.client.del(url, this._headersFromOptions(options));
|
||||
return this._processResponse(res, options);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Creates resource(s) from an endpoint
|
||||
* T type of object returned.
|
||||
* Be aware that not found returns a null. Other error conditions reject the promise
|
||||
* @param {string} resource - fully qualified or relative url
|
||||
* @param {IRequestOptions} requestOptions - (optional) requestOptions object
|
||||
*/
|
||||
create(resource, resources, options) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let url = util.getUrl(resource, this._baseUrl);
|
||||
let headers = this._headersFromOptions(options, true);
|
||||
let data = JSON.stringify(resources, null, 2);
|
||||
let res = yield this.client.post(url, data, headers);
|
||||
return this._processResponse(res, options);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Updates resource(s) from an endpoint
|
||||
* T type of object returned.
|
||||
* Be aware that not found returns a null. Other error conditions reject the promise
|
||||
* @param {string} resource - fully qualified or relative url
|
||||
* @param {IRequestOptions} requestOptions - (optional) requestOptions object
|
||||
*/
|
||||
update(resource, resources, options) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let url = util.getUrl(resource, this._baseUrl);
|
||||
let headers = this._headersFromOptions(options, true);
|
||||
let data = JSON.stringify(resources, null, 2);
|
||||
let res = yield this.client.patch(url, data, headers);
|
||||
return this._processResponse(res, options);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Replaces resource(s) from an endpoint
|
||||
* T type of object returned.
|
||||
* Be aware that not found returns a null. Other error conditions reject the promise
|
||||
* @param {string} resource - fully qualified or relative url
|
||||
* @param {IRequestOptions} requestOptions - (optional) requestOptions object
|
||||
*/
|
||||
replace(resource, resources, options) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let url = util.getUrl(resource, this._baseUrl);
|
||||
let headers = this._headersFromOptions(options, true);
|
||||
let data = JSON.stringify(resources, null, 2);
|
||||
let res = yield this.client.put(url, data, headers);
|
||||
return this._processResponse(res, options);
|
||||
});
|
||||
}
|
||||
uploadStream(verb, requestUrl, stream, options) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let url = util.getUrl(requestUrl, this._baseUrl);
|
||||
let headers = this._headersFromOptions(options, true);
|
||||
let res = yield this.client.sendStream(verb, url, stream, headers);
|
||||
return this._processResponse(res, options);
|
||||
});
|
||||
}
|
||||
_headersFromOptions(options, contentType) {
|
||||
options = options || {};
|
||||
let headers = options.additionalHeaders || {};
|
||||
headers["Accept"] = options.acceptHeader || "application/json";
|
||||
if (contentType) {
|
||||
let found = false;
|
||||
for (let header in headers) {
|
||||
if (header.toLowerCase() == "content-type") {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
headers["Content-Type"] = 'application/json; charset=utf-8';
|
||||
}
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
static dateTimeDeserializer(key, value) {
|
||||
if (typeof value === 'string') {
|
||||
let a = new Date(value);
|
||||
if (!isNaN(a.valueOf())) {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
_processResponse(res, options) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
||||
const statusCode = res.message.statusCode;
|
||||
const response = {
|
||||
statusCode: statusCode,
|
||||
result: null,
|
||||
headers: {}
|
||||
};
|
||||
// not found leads to null obj returned
|
||||
if (statusCode == httpm.HttpCodes.NotFound) {
|
||||
resolve(response);
|
||||
}
|
||||
let obj;
|
||||
let contents;
|
||||
// get the result from the body
|
||||
try {
|
||||
contents = yield res.readBody();
|
||||
if (contents && contents.length > 0) {
|
||||
if (options && options.deserializeDates) {
|
||||
obj = JSON.parse(contents, RestClient.dateTimeDeserializer);
|
||||
}
|
||||
else {
|
||||
obj = JSON.parse(contents);
|
||||
}
|
||||
if (options && options.responseProcessor) {
|
||||
response.result = options.responseProcessor(obj);
|
||||
}
|
||||
else {
|
||||
response.result = obj;
|
||||
}
|
||||
}
|
||||
response.headers = res.message.headers;
|
||||
}
|
||||
catch (err) {
|
||||
// Invalid resource (contents not json); leaving result obj null
|
||||
}
|
||||
// note that 3xx redirects are handled by the http layer.
|
||||
if (statusCode > 299) {
|
||||
let msg;
|
||||
// if exception/error in body, attempt to get better error
|
||||
if (obj && obj.message) {
|
||||
msg = obj.message;
|
||||
}
|
||||
else if (contents && contents.length > 0) {
|
||||
// it may be the case that the exception is in the body message as string
|
||||
msg = contents;
|
||||
}
|
||||
else {
|
||||
msg = "Failed request: (" + statusCode + ")";
|
||||
}
|
||||
let err = new Error(msg);
|
||||
// attach statusCode and body obj (if available) to the error object
|
||||
err['statusCode'] = statusCode;
|
||||
if (response.result) {
|
||||
err['result'] = response.result;
|
||||
}
|
||||
reject(err);
|
||||
}
|
||||
else {
|
||||
resolve(response);
|
||||
}
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.RestClient = RestClient;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 129:
|
||||
/***/ (function(module) {
|
||||
|
||||
module.exports = require("child_process");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 139:
|
||||
/***/ (function(module, __unusedexports, __webpack_require__) {
|
||||
|
||||
// Unique ID creation requires a high quality random # generator. In node.js
|
||||
// this is pretty straight-forward - we use the crypto API.
|
||||
|
||||
var crypto = __webpack_require__(417);
|
||||
|
||||
module.exports = function nodeRNG() {
|
||||
return crypto.randomBytes(16);
|
||||
};
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 141:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
var net = __webpack_require__(631);
|
||||
var tls = __webpack_require__(16);
|
||||
var http = __webpack_require__(605);
|
||||
var https = __webpack_require__(211);
|
||||
var events = __webpack_require__(614);
|
||||
var assert = __webpack_require__(357);
|
||||
var util = __webpack_require__(669);
|
||||
|
||||
|
||||
exports.httpOverHttp = httpOverHttp;
|
||||
exports.httpsOverHttp = httpsOverHttp;
|
||||
exports.httpOverHttps = httpOverHttps;
|
||||
exports.httpsOverHttps = httpsOverHttps;
|
||||
|
||||
|
||||
function httpOverHttp(options) {
|
||||
var agent = new TunnelingAgent(options);
|
||||
agent.request = http.request;
|
||||
return agent;
|
||||
}
|
||||
|
||||
function httpsOverHttp(options) {
|
||||
var agent = new TunnelingAgent(options);
|
||||
agent.request = http.request;
|
||||
agent.createSocket = createSecureSocket;
|
||||
return agent;
|
||||
}
|
||||
|
||||
function httpOverHttps(options) {
|
||||
var agent = new TunnelingAgent(options);
|
||||
agent.request = https.request;
|
||||
return agent;
|
||||
}
|
||||
|
||||
function httpsOverHttps(options) {
|
||||
var agent = new TunnelingAgent(options);
|
||||
agent.request = https.request;
|
||||
agent.createSocket = createSecureSocket;
|
||||
return agent;
|
||||
}
|
||||
|
||||
|
||||
function TunnelingAgent(options) {
|
||||
var self = this;
|
||||
self.options = options || {};
|
||||
self.proxyOptions = self.options.proxy || {};
|
||||
self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets;
|
||||
self.requests = [];
|
||||
self.sockets = [];
|
||||
|
||||
self.on('free', function onFree(socket, host, port, localAddress) {
|
||||
var options = toOptions(host, port, localAddress);
|
||||
for (var i = 0, len = self.requests.length; i < len; ++i) {
|
||||
var pending = self.requests[i];
|
||||
if (pending.host === options.host && pending.port === options.port) {
|
||||
// Detect the request to connect same origin server,
|
||||
// reuse the connection.
|
||||
self.requests.splice(i, 1);
|
||||
pending.request.onSocket(socket);
|
||||
return;
|
||||
}
|
||||
}
|
||||
socket.destroy();
|
||||
self.removeSocket(socket);
|
||||
});
|
||||
}
|
||||
util.inherits(TunnelingAgent, events.EventEmitter);
|
||||
|
||||
TunnelingAgent.prototype.addRequest = function addRequest(req, host, port, localAddress) {
|
||||
var self = this;
|
||||
var options = mergeOptions({request: req}, self.options, toOptions(host, port, localAddress));
|
||||
|
||||
if (self.sockets.length >= this.maxSockets) {
|
||||
// We are over limit so we'll add it to the queue.
|
||||
self.requests.push(options);
|
||||
return;
|
||||
}
|
||||
|
||||
// If we are under maxSockets create a new one.
|
||||
self.createSocket(options, function(socket) {
|
||||
socket.on('free', onFree);
|
||||
socket.on('close', onCloseOrRemove);
|
||||
socket.on('agentRemove', onCloseOrRemove);
|
||||
req.onSocket(socket);
|
||||
|
||||
function onFree() {
|
||||
self.emit('free', socket, options);
|
||||
}
|
||||
|
||||
function onCloseOrRemove(err) {
|
||||
self.removeSocket(socket);
|
||||
socket.removeListener('free', onFree);
|
||||
socket.removeListener('close', onCloseOrRemove);
|
||||
socket.removeListener('agentRemove', onCloseOrRemove);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
TunnelingAgent.prototype.createSocket = function createSocket(options, cb) {
|
||||
var self = this;
|
||||
var placeholder = {};
|
||||
self.sockets.push(placeholder);
|
||||
|
||||
var connectOptions = mergeOptions({}, self.proxyOptions, {
|
||||
method: 'CONNECT',
|
||||
path: options.host + ':' + options.port,
|
||||
agent: false
|
||||
});
|
||||
if (connectOptions.proxyAuth) {
|
||||
connectOptions.headers = connectOptions.headers || {};
|
||||
connectOptions.headers['Proxy-Authorization'] = 'Basic ' +
|
||||
new Buffer(connectOptions.proxyAuth).toString('base64');
|
||||
}
|
||||
|
||||
debug('making CONNECT request');
|
||||
var connectReq = self.request(connectOptions);
|
||||
connectReq.useChunkedEncodingByDefault = false; // for v0.6
|
||||
connectReq.once('response', onResponse); // for v0.6
|
||||
connectReq.once('upgrade', onUpgrade); // for v0.6
|
||||
connectReq.once('connect', onConnect); // for v0.7 or later
|
||||
connectReq.once('error', onError);
|
||||
connectReq.end();
|
||||
|
||||
function onResponse(res) {
|
||||
// Very hacky. This is necessary to avoid http-parser leaks.
|
||||
res.upgrade = true;
|
||||
}
|
||||
|
||||
function onUpgrade(res, socket, head) {
|
||||
// Hacky.
|
||||
process.nextTick(function() {
|
||||
onConnect(res, socket, head);
|
||||
});
|
||||
}
|
||||
|
||||
function onConnect(res, socket, head) {
|
||||
connectReq.removeAllListeners();
|
||||
socket.removeAllListeners();
|
||||
|
||||
if (res.statusCode === 200) {
|
||||
assert.equal(head.length, 0);
|
||||
debug('tunneling connection has established');
|
||||
self.sockets[self.sockets.indexOf(placeholder)] = socket;
|
||||
cb(socket);
|
||||
} else {
|
||||
debug('tunneling socket could not be established, statusCode=%d',
|
||||
res.statusCode);
|
||||
var error = new Error('tunneling socket could not be established, ' +
|
||||
'statusCode=' + res.statusCode);
|
||||
error.code = 'ECONNRESET';
|
||||
options.request.emit('error', error);
|
||||
self.removeSocket(placeholder);
|
||||
}
|
||||
}
|
||||
|
||||
function onError(cause) {
|
||||
connectReq.removeAllListeners();
|
||||
|
||||
debug('tunneling socket could not be established, cause=%s\n',
|
||||
cause.message, cause.stack);
|
||||
var error = new Error('tunneling socket could not be established, ' +
|
||||
'cause=' + cause.message);
|
||||
error.code = 'ECONNRESET';
|
||||
options.request.emit('error', error);
|
||||
self.removeSocket(placeholder);
|
||||
}
|
||||
};
|
||||
|
||||
TunnelingAgent.prototype.removeSocket = function removeSocket(socket) {
|
||||
var pos = this.sockets.indexOf(socket)
|
||||
if (pos === -1) {
|
||||
return;
|
||||
}
|
||||
this.sockets.splice(pos, 1);
|
||||
|
||||
var pending = this.requests.shift();
|
||||
if (pending) {
|
||||
// If we have pending requests and a socket gets closed a new one
|
||||
// needs to be created to take over in the pool for the one that closed.
|
||||
this.createSocket(pending, function(socket) {
|
||||
pending.request.onSocket(socket);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function createSecureSocket(options, cb) {
|
||||
var self = this;
|
||||
TunnelingAgent.prototype.createSocket.call(self, options, function(socket) {
|
||||
var hostHeader = options.request.getHeader('host');
|
||||
var tlsOptions = mergeOptions({}, self.options, {
|
||||
socket: socket,
|
||||
servername: hostHeader ? hostHeader.replace(/:.*$/, '') : options.host
|
||||
});
|
||||
|
||||
// 0 is dummy port for v0.6
|
||||
var secureSocket = tls.connect(0, tlsOptions);
|
||||
self.sockets[self.sockets.indexOf(socket)] = secureSocket;
|
||||
cb(secureSocket);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function toOptions(host, port, localAddress) {
|
||||
if (typeof host === 'string') { // since v0.10
|
||||
return {
|
||||
host: host,
|
||||
port: port,
|
||||
localAddress: localAddress
|
||||
};
|
||||
}
|
||||
return host; // for v0.11 or later
|
||||
}
|
||||
|
||||
function mergeOptions(target) {
|
||||
for (var i = 1, len = arguments.length; i < len; ++i) {
|
||||
var overrides = arguments[i];
|
||||
if (typeof overrides === 'object') {
|
||||
var keys = Object.keys(overrides);
|
||||
for (var j = 0, keyLen = keys.length; j < keyLen; ++j) {
|
||||
var k = keys[j];
|
||||
if (overrides[k] !== undefined) {
|
||||
target[k] = overrides[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
|
||||
var debug;
|
||||
if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) {
|
||||
debug = function() {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
if (typeof args[0] === 'string') {
|
||||
args[0] = 'TUNNEL: ' + args[0];
|
||||
} else {
|
||||
args.unshift('TUNNEL:');
|
||||
}
|
||||
console.error.apply(console, args);
|
||||
}
|
||||
} else {
|
||||
debug = function() {};
|
||||
}
|
||||
exports.debug = debug; // for test
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 154:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
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 __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 core = __importStar(__webpack_require__(470));
|
||||
const fs = __importStar(__webpack_require__(747));
|
||||
const Handlers_1 = __webpack_require__(941);
|
||||
const HttpClient_1 = __webpack_require__(874);
|
||||
const RestClient_1 = __webpack_require__(105);
|
||||
function getCacheUrl() {
|
||||
// Ideally we just use ACTIONS_CACHE_URL
|
||||
const cacheUrl = (process.env["ACTIONS_CACHE_URL"] ||
|
||||
process.env["ACTIONS_RUNTIME_URL"] ||
|
||||
"").replace("pipelines", "artifactcache");
|
||||
if (!cacheUrl) {
|
||||
throw new Error("Cache Service Url not found, unable to restore cache.");
|
||||
}
|
||||
core.debug(`Cache Url: ${cacheUrl}`);
|
||||
return cacheUrl;
|
||||
}
|
||||
function createAcceptHeader(type, apiVersion) {
|
||||
return `${type};api-version=${apiVersion}`;
|
||||
}
|
||||
function getRequestOptions() {
|
||||
const requestOptions = {
|
||||
acceptHeader: createAcceptHeader("application/json", "5.2-preview.1")
|
||||
};
|
||||
return requestOptions;
|
||||
}
|
||||
function getCacheEntry(keys) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const cacheUrl = getCacheUrl();
|
||||
const token = process.env["ACTIONS_RUNTIME_TOKEN"] || "";
|
||||
const bearerCredentialHandler = new Handlers_1.BearerCredentialHandler(token);
|
||||
const resource = `_apis/artifactcache/cache?keys=${encodeURIComponent(keys.join(","))}`;
|
||||
const restClient = new RestClient_1.RestClient("actions/cache", cacheUrl, [
|
||||
bearerCredentialHandler
|
||||
]);
|
||||
const response = yield restClient.get(resource, getRequestOptions());
|
||||
if (response.statusCode === 204) {
|
||||
return null;
|
||||
}
|
||||
if (response.statusCode !== 200) {
|
||||
throw new Error(`Cache service responded with ${response.statusCode}`);
|
||||
}
|
||||
const cacheResult = response.result;
|
||||
if (!cacheResult || !cacheResult.archiveLocation) {
|
||||
throw new Error("Cache not found.");
|
||||
}
|
||||
core.setSecret(cacheResult.archiveLocation);
|
||||
core.debug(`Cache Result:`);
|
||||
core.debug(JSON.stringify(cacheResult));
|
||||
return cacheResult;
|
||||
});
|
||||
}
|
||||
exports.getCacheEntry = getCacheEntry;
|
||||
function pipeResponseToStream(response, stream) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
return new Promise(resolve => {
|
||||
response.message.pipe(stream).on("close", () => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
function downloadCache(cacheEntry, archivePath) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const stream = fs.createWriteStream(archivePath);
|
||||
const httpClient = new HttpClient_1.HttpClient("actions/cache");
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const downloadResponse = yield httpClient.get(cacheEntry.archiveLocation);
|
||||
yield pipeResponseToStream(downloadResponse, stream);
|
||||
});
|
||||
}
|
||||
exports.downloadCache = downloadCache;
|
||||
function saveCache(key, archivePath) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const stream = fs.createReadStream(archivePath);
|
||||
const cacheUrl = getCacheUrl();
|
||||
const token = process.env["ACTIONS_RUNTIME_TOKEN"] || "";
|
||||
const bearerCredentialHandler = new Handlers_1.BearerCredentialHandler(token);
|
||||
const resource = `_apis/artifactcache/cache/${encodeURIComponent(key)}`;
|
||||
const postUrl = cacheUrl + resource;
|
||||
const restClient = new RestClient_1.RestClient("actions/cache", undefined, [
|
||||
bearerCredentialHandler
|
||||
]);
|
||||
const requestOptions = getRequestOptions();
|
||||
requestOptions.additionalHeaders = {
|
||||
"Content-Type": "application/octet-stream"
|
||||
};
|
||||
const response = yield restClient.uploadStream("POST", postUrl, stream, requestOptions);
|
||||
if (response.statusCode !== 200) {
|
||||
throw new Error(`Cache service responded with ${response.statusCode}`);
|
||||
}
|
||||
core.info("Cache saved successfully");
|
||||
});
|
||||
}
|
||||
exports.saveCache = saveCache;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 211:
|
||||
/***/ (function(module) {
|
||||
|
||||
module.exports = require("https");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 327:
|
||||
/***/ (function(__unusedmodule, exports) {
|
||||
|
||||
"use strict";
|
||||
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
class PersonalAccessTokenCredentialHandler {
|
||||
constructor(token) {
|
||||
this.token = token;
|
||||
}
|
||||
// currently implements pre-authorization
|
||||
// TODO: support preAuth = false where it hooks on 401
|
||||
prepareRequest(options) {
|
||||
options.headers['Authorization'] = 'Basic ' + new Buffer('PAT:' + this.token).toString('base64');
|
||||
options.headers['X-TFS-FedAuthRedirect'] = 'Suppress';
|
||||
}
|
||||
// This handler cannot handle 401
|
||||
canHandleAuthentication(response) {
|
||||
return false;
|
||||
}
|
||||
handleAuthentication(httpClient, requestInfo, objs) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
exports.PersonalAccessTokenCredentialHandler = PersonalAccessTokenCredentialHandler;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 357:
|
||||
/***/ (function(module) {
|
||||
|
||||
module.exports = require("assert");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 413:
|
||||
/***/ (function(module, __unusedexports, __webpack_require__) {
|
||||
|
||||
module.exports = __webpack_require__(141);
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 417:
|
||||
/***/ (function(module) {
|
||||
|
||||
module.exports = require("crypto");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 431:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const os = __webpack_require__(87);
|
||||
/**
|
||||
* Commands
|
||||
*
|
||||
* Command Format:
|
||||
* ##[name key=value;key=value]message
|
||||
*
|
||||
* Examples:
|
||||
* ##[warning]This is the user warning message
|
||||
* ##[set-secret name=mypassword]definitelyNotAPassword!
|
||||
*/
|
||||
function issueCommand(command, properties, message) {
|
||||
const cmd = new Command(command, properties, message);
|
||||
process.stdout.write(cmd.toString() + os.EOL);
|
||||
}
|
||||
exports.issueCommand = issueCommand;
|
||||
function issue(name, message = '') {
|
||||
issueCommand(name, {}, message);
|
||||
}
|
||||
exports.issue = issue;
|
||||
const CMD_STRING = '::';
|
||||
class Command {
|
||||
constructor(command, properties, message) {
|
||||
if (!command) {
|
||||
command = 'missing.command';
|
||||
}
|
||||
this.command = command;
|
||||
this.properties = properties;
|
||||
this.message = message;
|
||||
}
|
||||
toString() {
|
||||
let cmdStr = CMD_STRING + this.command;
|
||||
if (this.properties && Object.keys(this.properties).length > 0) {
|
||||
cmdStr += ' ';
|
||||
for (const key in this.properties) {
|
||||
if (this.properties.hasOwnProperty(key)) {
|
||||
const val = this.properties[key];
|
||||
if (val) {
|
||||
// safely append the val - avoid blowing up when attempting to
|
||||
// call .replace() if message is not a string for some reason
|
||||
cmdStr += `${key}=${escape(`${val || ''}`)},`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
cmdStr += CMD_STRING;
|
||||
// safely append the message - avoid blowing up when attempting to
|
||||
// call .replace() if message is not a string for some reason
|
||||
const message = `${this.message || ''}`;
|
||||
cmdStr += escapeData(message);
|
||||
return cmdStr;
|
||||
}
|
||||
}
|
||||
function escapeData(s) {
|
||||
return s.replace(/\r/g, '%0D').replace(/\n/g, '%0A');
|
||||
}
|
||||
function escape(s) {
|
||||
return s
|
||||
.replace(/\r/g, '%0D')
|
||||
.replace(/\n/g, '%0A')
|
||||
.replace(/]/g, '%5D')
|
||||
.replace(/;/g, '%3B');
|
||||
}
|
||||
//# sourceMappingURL=command.js.map
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 432:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
var crypto = __webpack_require__(417);
|
||||
|
||||
var flags = {
|
||||
NTLM_NegotiateUnicode : 0x00000001,
|
||||
NTLM_NegotiateOEM : 0x00000002,
|
||||
NTLM_RequestTarget : 0x00000004,
|
||||
NTLM_Unknown9 : 0x00000008,
|
||||
NTLM_NegotiateSign : 0x00000010,
|
||||
NTLM_NegotiateSeal : 0x00000020,
|
||||
NTLM_NegotiateDatagram : 0x00000040,
|
||||
NTLM_NegotiateLanManagerKey : 0x00000080,
|
||||
NTLM_Unknown8 : 0x00000100,
|
||||
NTLM_NegotiateNTLM : 0x00000200,
|
||||
NTLM_NegotiateNTOnly : 0x00000400,
|
||||
NTLM_Anonymous : 0x00000800,
|
||||
NTLM_NegotiateOemDomainSupplied : 0x00001000,
|
||||
NTLM_NegotiateOemWorkstationSupplied : 0x00002000,
|
||||
NTLM_Unknown6 : 0x00004000,
|
||||
NTLM_NegotiateAlwaysSign : 0x00008000,
|
||||
NTLM_TargetTypeDomain : 0x00010000,
|
||||
NTLM_TargetTypeServer : 0x00020000,
|
||||
NTLM_TargetTypeShare : 0x00040000,
|
||||
NTLM_NegotiateExtendedSecurity : 0x00080000,
|
||||
NTLM_NegotiateIdentify : 0x00100000,
|
||||
NTLM_Unknown5 : 0x00200000,
|
||||
NTLM_RequestNonNTSessionKey : 0x00400000,
|
||||
NTLM_NegotiateTargetInfo : 0x00800000,
|
||||
NTLM_Unknown4 : 0x01000000,
|
||||
NTLM_NegotiateVersion : 0x02000000,
|
||||
NTLM_Unknown3 : 0x04000000,
|
||||
NTLM_Unknown2 : 0x08000000,
|
||||
NTLM_Unknown1 : 0x10000000,
|
||||
NTLM_Negotiate128 : 0x20000000,
|
||||
NTLM_NegotiateKeyExchange : 0x40000000,
|
||||
NTLM_Negotiate56 : 0x80000000
|
||||
};
|
||||
var typeflags = {
|
||||
NTLM_TYPE1_FLAGS : flags.NTLM_NegotiateUnicode
|
||||
+ flags.NTLM_NegotiateOEM
|
||||
+ flags.NTLM_RequestTarget
|
||||
+ flags.NTLM_NegotiateNTLM
|
||||
+ flags.NTLM_NegotiateOemDomainSupplied
|
||||
+ flags.NTLM_NegotiateOemWorkstationSupplied
|
||||
+ flags.NTLM_NegotiateAlwaysSign
|
||||
+ flags.NTLM_NegotiateExtendedSecurity
|
||||
+ flags.NTLM_NegotiateVersion
|
||||
+ flags.NTLM_Negotiate128
|
||||
+ flags.NTLM_Negotiate56,
|
||||
|
||||
NTLM_TYPE2_FLAGS : flags.NTLM_NegotiateUnicode
|
||||
+ flags.NTLM_RequestTarget
|
||||
+ flags.NTLM_NegotiateNTLM
|
||||
+ flags.NTLM_NegotiateAlwaysSign
|
||||
+ flags.NTLM_NegotiateExtendedSecurity
|
||||
+ flags.NTLM_NegotiateTargetInfo
|
||||
+ flags.NTLM_NegotiateVersion
|
||||
+ flags.NTLM_Negotiate128
|
||||
+ flags.NTLM_Negotiate56
|
||||
};
|
||||
|
||||
function createType1Message(options){
|
||||
var domain = escape(options.domain.toUpperCase());
|
||||
var workstation = escape(options.workstation.toUpperCase());
|
||||
var protocol = 'NTLMSSP\0';
|
||||
|
||||
var BODY_LENGTH = 40;
|
||||
|
||||
var type1flags = typeflags.NTLM_TYPE1_FLAGS;
|
||||
if(!domain || domain === '')
|
||||
type1flags = type1flags - flags.NTLM_NegotiateOemDomainSupplied;
|
||||
|
||||
var pos = 0;
|
||||
var buf = new Buffer(BODY_LENGTH + domain.length + workstation.length);
|
||||
|
||||
|
||||
buf.write(protocol, pos, protocol.length); pos += protocol.length; // protocol
|
||||
buf.writeUInt32LE(1, pos); pos += 4; // type 1
|
||||
buf.writeUInt32LE(type1flags, pos); pos += 4; // TYPE1 flag
|
||||
|
||||
buf.writeUInt16LE(domain.length, pos); pos += 2; // domain length
|
||||
buf.writeUInt16LE(domain.length, pos); pos += 2; // domain max length
|
||||
buf.writeUInt32LE(BODY_LENGTH + workstation.length, pos); pos += 4; // domain buffer offset
|
||||
|
||||
buf.writeUInt16LE(workstation.length, pos); pos += 2; // workstation length
|
||||
buf.writeUInt16LE(workstation.length, pos); pos += 2; // workstation max length
|
||||
buf.writeUInt32LE(BODY_LENGTH, pos); pos += 4; // workstation buffer offset
|
||||
|
||||
buf.writeUInt8(5, pos); pos += 1; //ProductMajorVersion
|
||||
buf.writeUInt8(1, pos); pos += 1; //ProductMinorVersion
|
||||
buf.writeUInt16LE(2600, pos); pos += 2; //ProductBuild
|
||||
|
||||
buf.writeUInt8(0 , pos); pos += 1; //VersionReserved1
|
||||
buf.writeUInt8(0 , pos); pos += 1; //VersionReserved2
|
||||
buf.writeUInt8(0 , pos); pos += 1; //VersionReserved3
|
||||
buf.writeUInt8(15, pos); pos += 1; //NTLMRevisionCurrent
|
||||
|
||||
buf.write(workstation, pos, workstation.length, 'ascii'); pos += workstation.length; // workstation string
|
||||
buf.write(domain , pos, domain.length , 'ascii'); pos += domain.length;
|
||||
|
||||
return 'NTLM ' + buf.toString('base64');
|
||||
}
|
||||
|
||||
function parseType2Message(rawmsg, callback){
|
||||
var match = rawmsg.match(/NTLM (.+)?/);
|
||||
if(!match || !match[1])
|
||||
return callback(new Error("Couldn't find NTLM in the message type2 comming from the server"));
|
||||
|
||||
var buf = new Buffer(match[1], 'base64');
|
||||
|
||||
var msg = {};
|
||||
|
||||
msg.signature = buf.slice(0, 8);
|
||||
msg.type = buf.readInt16LE(8);
|
||||
|
||||
if(msg.type != 2)
|
||||
return callback(new Error("Server didn't return a type 2 message"));
|
||||
|
||||
msg.targetNameLen = buf.readInt16LE(12);
|
||||
msg.targetNameMaxLen = buf.readInt16LE(14);
|
||||
msg.targetNameOffset = buf.readInt32LE(16);
|
||||
msg.targetName = buf.slice(msg.targetNameOffset, msg.targetNameOffset + msg.targetNameMaxLen);
|
||||
|
||||
msg.negotiateFlags = buf.readInt32LE(20);
|
||||
msg.serverChallenge = buf.slice(24, 32);
|
||||
msg.reserved = buf.slice(32, 40);
|
||||
|
||||
if(msg.negotiateFlags & flags.NTLM_NegotiateTargetInfo){
|
||||
msg.targetInfoLen = buf.readInt16LE(40);
|
||||
msg.targetInfoMaxLen = buf.readInt16LE(42);
|
||||
msg.targetInfoOffset = buf.readInt32LE(44);
|
||||
msg.targetInfo = buf.slice(msg.targetInfoOffset, msg.targetInfoOffset + msg.targetInfoLen);
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
function createType3Message(msg2, options){
|
||||
var nonce = msg2.serverChallenge;
|
||||
var username = options.username;
|
||||
var password = options.password;
|
||||
var negotiateFlags = msg2.negotiateFlags;
|
||||
|
||||
var isUnicode = negotiateFlags & flags.NTLM_NegotiateUnicode;
|
||||
var isNegotiateExtendedSecurity = negotiateFlags & flags.NTLM_NegotiateExtendedSecurity;
|
||||
|
||||
var BODY_LENGTH = 72;
|
||||
|
||||
var domainName = escape(options.domain.toUpperCase());
|
||||
var workstation = escape(options.workstation.toUpperCase());
|
||||
|
||||
var workstationBytes, domainNameBytes, usernameBytes, encryptedRandomSessionKeyBytes;
|
||||
|
||||
var encryptedRandomSessionKey = "";
|
||||
if(isUnicode){
|
||||
workstationBytes = new Buffer(workstation, 'utf16le');
|
||||
domainNameBytes = new Buffer(domainName, 'utf16le');
|
||||
usernameBytes = new Buffer(username, 'utf16le');
|
||||
encryptedRandomSessionKeyBytes = new Buffer(encryptedRandomSessionKey, 'utf16le');
|
||||
}else{
|
||||
workstationBytes = new Buffer(workstation, 'ascii');
|
||||
domainNameBytes = new Buffer(domainName, 'ascii');
|
||||
usernameBytes = new Buffer(username, 'ascii');
|
||||
encryptedRandomSessionKeyBytes = new Buffer(encryptedRandomSessionKey, 'ascii');
|
||||
}
|
||||
|
||||
var lmChallengeResponse = calc_resp(create_LM_hashed_password_v1(password), nonce);
|
||||
var ntChallengeResponse = calc_resp(create_NT_hashed_password_v1(password), nonce);
|
||||
|
||||
if(isNegotiateExtendedSecurity){
|
||||
var pwhash = create_NT_hashed_password_v1(password);
|
||||
var clientChallenge = "";
|
||||
for(var i=0; i < 8; i++){
|
||||
clientChallenge += String.fromCharCode( Math.floor(Math.random()*256) );
|
||||
}
|
||||
var clientChallengeBytes = new Buffer(clientChallenge, 'ascii');
|
||||
var challenges = ntlm2sr_calc_resp(pwhash, nonce, clientChallengeBytes);
|
||||
lmChallengeResponse = challenges.lmChallengeResponse;
|
||||
ntChallengeResponse = challenges.ntChallengeResponse;
|
||||
}
|
||||
|
||||
var signature = 'NTLMSSP\0';
|
||||
|
||||
var pos = 0;
|
||||
var buf = new Buffer(BODY_LENGTH + domainNameBytes.length + usernameBytes.length + workstationBytes.length + lmChallengeResponse.length + ntChallengeResponse.length + encryptedRandomSessionKeyBytes.length);
|
||||
|
||||
buf.write(signature, pos, signature.length); pos += signature.length;
|
||||
buf.writeUInt32LE(3, pos); pos += 4; // type 1
|
||||
|
||||
buf.writeUInt16LE(lmChallengeResponse.length, pos); pos += 2; // LmChallengeResponseLen
|
||||
buf.writeUInt16LE(lmChallengeResponse.length, pos); pos += 2; // LmChallengeResponseMaxLen
|
||||
buf.writeUInt32LE(BODY_LENGTH + domainNameBytes.length + usernameBytes.length + workstationBytes.length, pos); pos += 4; // LmChallengeResponseOffset
|
||||
|
||||
buf.writeUInt16LE(ntChallengeResponse.length, pos); pos += 2; // NtChallengeResponseLen
|
||||
buf.writeUInt16LE(ntChallengeResponse.length, pos); pos += 2; // NtChallengeResponseMaxLen
|
||||
buf.writeUInt32LE(BODY_LENGTH + domainNameBytes.length + usernameBytes.length + workstationBytes.length + lmChallengeResponse.length, pos); pos += 4; // NtChallengeResponseOffset
|
||||
|
||||
buf.writeUInt16LE(domainNameBytes.length, pos); pos += 2; // DomainNameLen
|
||||
buf.writeUInt16LE(domainNameBytes.length, pos); pos += 2; // DomainNameMaxLen
|
||||
buf.writeUInt32LE(BODY_LENGTH, pos); pos += 4; // DomainNameOffset
|
||||
|
||||
buf.writeUInt16LE(usernameBytes.length, pos); pos += 2; // UserNameLen
|
||||
buf.writeUInt16LE(usernameBytes.length, pos); pos += 2; // UserNameMaxLen
|
||||
buf.writeUInt32LE(BODY_LENGTH + domainNameBytes.length, pos); pos += 4; // UserNameOffset
|
||||
|
||||
buf.writeUInt16LE(workstationBytes.length, pos); pos += 2; // WorkstationLen
|
||||
buf.writeUInt16LE(workstationBytes.length, pos); pos += 2; // WorkstationMaxLen
|
||||
buf.writeUInt32LE(BODY_LENGTH + domainNameBytes.length + usernameBytes.length, pos); pos += 4; // WorkstationOffset
|
||||
|
||||
buf.writeUInt16LE(encryptedRandomSessionKeyBytes.length, pos); pos += 2; // EncryptedRandomSessionKeyLen
|
||||
buf.writeUInt16LE(encryptedRandomSessionKeyBytes.length, pos); pos += 2; // EncryptedRandomSessionKeyMaxLen
|
||||
buf.writeUInt32LE(BODY_LENGTH + domainNameBytes.length + usernameBytes.length + workstationBytes.length + lmChallengeResponse.length + ntChallengeResponse.length, pos); pos += 4; // EncryptedRandomSessionKeyOffset
|
||||
|
||||
buf.writeUInt32LE(typeflags.NTLM_TYPE2_FLAGS, pos); pos += 4; // NegotiateFlags
|
||||
|
||||
buf.writeUInt8(5, pos); pos++; // ProductMajorVersion
|
||||
buf.writeUInt8(1, pos); pos++; // ProductMinorVersion
|
||||
buf.writeUInt16LE(2600, pos); pos += 2; // ProductBuild
|
||||
buf.writeUInt8(0, pos); pos++; // VersionReserved1
|
||||
buf.writeUInt8(0, pos); pos++; // VersionReserved2
|
||||
buf.writeUInt8(0, pos); pos++; // VersionReserved3
|
||||
buf.writeUInt8(15, pos); pos++; // NTLMRevisionCurrent
|
||||
|
||||
domainNameBytes.copy(buf, pos); pos += domainNameBytes.length;
|
||||
usernameBytes.copy(buf, pos); pos += usernameBytes.length;
|
||||
workstationBytes.copy(buf, pos); pos += workstationBytes.length;
|
||||
lmChallengeResponse.copy(buf, pos); pos += lmChallengeResponse.length;
|
||||
ntChallengeResponse.copy(buf, pos); pos += ntChallengeResponse.length;
|
||||
encryptedRandomSessionKeyBytes.copy(buf, pos); pos += encryptedRandomSessionKeyBytes.length;
|
||||
|
||||
return 'NTLM ' + buf.toString('base64');
|
||||
}
|
||||
|
||||
function create_LM_hashed_password_v1(password){
|
||||
// fix the password length to 14 bytes
|
||||
password = password.toUpperCase();
|
||||
var passwordBytes = new Buffer(password, 'ascii');
|
||||
|
||||
var passwordBytesPadded = new Buffer(14);
|
||||
passwordBytesPadded.fill("\0");
|
||||
var sourceEnd = 14;
|
||||
if(passwordBytes.length < 14) sourceEnd = passwordBytes.length;
|
||||
passwordBytes.copy(passwordBytesPadded, 0, 0, sourceEnd);
|
||||
|
||||
// split into 2 parts of 7 bytes:
|
||||
var firstPart = passwordBytesPadded.slice(0,7);
|
||||
var secondPart = passwordBytesPadded.slice(7);
|
||||
|
||||
function encrypt(buf){
|
||||
var key = insertZerosEvery7Bits(buf);
|
||||
var des = crypto.createCipheriv('DES-ECB', key, '');
|
||||
return des.update("KGS!@#$%"); // page 57 in [MS-NLMP]);
|
||||
}
|
||||
|
||||
var firstPartEncrypted = encrypt(firstPart);
|
||||
var secondPartEncrypted = encrypt(secondPart);
|
||||
|
||||
return Buffer.concat([firstPartEncrypted, secondPartEncrypted]);
|
||||
}
|
||||
|
||||
function insertZerosEvery7Bits(buf){
|
||||
var binaryArray = bytes2binaryArray(buf);
|
||||
var newBinaryArray = [];
|
||||
for(var i=0; i<binaryArray.length; i++){
|
||||
newBinaryArray.push(binaryArray[i]);
|
||||
|
||||
if((i+1)%7 === 0){
|
||||
newBinaryArray.push(0);
|
||||
}
|
||||
}
|
||||
return binaryArray2bytes(newBinaryArray);
|
||||
}
|
||||
|
||||
function bytes2binaryArray(buf){
|
||||
var hex2binary = {
|
||||
0: [0,0,0,0],
|
||||
1: [0,0,0,1],
|
||||
2: [0,0,1,0],
|
||||
3: [0,0,1,1],
|
||||
4: [0,1,0,0],
|
||||
5: [0,1,0,1],
|
||||
6: [0,1,1,0],
|
||||
7: [0,1,1,1],
|
||||
8: [1,0,0,0],
|
||||
9: [1,0,0,1],
|
||||
A: [1,0,1,0],
|
||||
B: [1,0,1,1],
|
||||
C: [1,1,0,0],
|
||||
D: [1,1,0,1],
|
||||
E: [1,1,1,0],
|
||||
F: [1,1,1,1]
|
||||
};
|
||||
|
||||
var hexString = buf.toString('hex').toUpperCase();
|
||||
var array = [];
|
||||
for(var i=0; i<hexString.length; i++){
|
||||
var hexchar = hexString.charAt(i);
|
||||
array = array.concat(hex2binary[hexchar]);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
function binaryArray2bytes(array){
|
||||
var binary2hex = {
|
||||
'0000': 0,
|
||||
'0001': 1,
|
||||
'0010': 2,
|
||||
'0011': 3,
|
||||
'0100': 4,
|
||||
'0101': 5,
|
||||
'0110': 6,
|
||||
'0111': 7,
|
||||
'1000': 8,
|
||||
'1001': 9,
|
||||
'1010': 'A',
|
||||
'1011': 'B',
|
||||
'1100': 'C',
|
||||
'1101': 'D',
|
||||
'1110': 'E',
|
||||
'1111': 'F'
|
||||
};
|
||||
|
||||
var bufArray = [];
|
||||
|
||||
for(var i=0; i<array.length; i +=8 ){
|
||||
if((i+7) > array.length)
|
||||
break;
|
||||
|
||||
var binString1 = '' + array[i] + '' + array[i+1] + '' + array[i+2] + '' + array[i+3];
|
||||
var binString2 = '' + array[i+4] + '' + array[i+5] + '' + array[i+6] + '' + array[i+7];
|
||||
var hexchar1 = binary2hex[binString1];
|
||||
var hexchar2 = binary2hex[binString2];
|
||||
|
||||
var buf = new Buffer(hexchar1 + '' + hexchar2, 'hex');
|
||||
bufArray.push(buf);
|
||||
}
|
||||
|
||||
return Buffer.concat(bufArray);
|
||||
}
|
||||
|
||||
function create_NT_hashed_password_v1(password){
|
||||
var buf = new Buffer(password, 'utf16le');
|
||||
var md4 = crypto.createHash('md4');
|
||||
md4.update(buf);
|
||||
return new Buffer(md4.digest());
|
||||
}
|
||||
|
||||
function calc_resp(password_hash, server_challenge){
|
||||
// padding with zeros to make the hash 21 bytes long
|
||||
var passHashPadded = new Buffer(21);
|
||||
passHashPadded.fill("\0");
|
||||
password_hash.copy(passHashPadded, 0, 0, password_hash.length);
|
||||
|
||||
var resArray = [];
|
||||
|
||||
var des = crypto.createCipheriv('DES-ECB', insertZerosEvery7Bits(passHashPadded.slice(0,7)), '');
|
||||
resArray.push( des.update(server_challenge.slice(0,8)) );
|
||||
|
||||
des = crypto.createCipheriv('DES-ECB', insertZerosEvery7Bits(passHashPadded.slice(7,14)), '');
|
||||
resArray.push( des.update(server_challenge.slice(0,8)) );
|
||||
|
||||
des = crypto.createCipheriv('DES-ECB', insertZerosEvery7Bits(passHashPadded.slice(14,21)), '');
|
||||
resArray.push( des.update(server_challenge.slice(0,8)) );
|
||||
|
||||
return Buffer.concat(resArray);
|
||||
}
|
||||
|
||||
function ntlm2sr_calc_resp(responseKeyNT, serverChallenge, clientChallenge){
|
||||
// padding with zeros to make the hash 16 bytes longer
|
||||
var lmChallengeResponse = new Buffer(clientChallenge.length + 16);
|
||||
lmChallengeResponse.fill("\0");
|
||||
clientChallenge.copy(lmChallengeResponse, 0, 0, clientChallenge.length);
|
||||
|
||||
var buf = Buffer.concat([serverChallenge, clientChallenge]);
|
||||
var md5 = crypto.createHash('md5');
|
||||
md5.update(buf);
|
||||
var sess = md5.digest();
|
||||
var ntChallengeResponse = calc_resp(responseKeyNT, sess.slice(0,8));
|
||||
|
||||
return {
|
||||
lmChallengeResponse: lmChallengeResponse,
|
||||
ntChallengeResponse: ntChallengeResponse
|
||||
};
|
||||
}
|
||||
|
||||
exports.createType1Message = createType1Message;
|
||||
exports.parseType2Message = parseType2Message;
|
||||
exports.createType3Message = createType3Message;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 443:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
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 __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 core = __importStar(__webpack_require__(470));
|
||||
const io = __importStar(__webpack_require__(1));
|
||||
const fs = __importStar(__webpack_require__(747));
|
||||
const os = __importStar(__webpack_require__(87));
|
||||
const path = __importStar(__webpack_require__(622));
|
||||
const uuidV4 = __importStar(__webpack_require__(826));
|
||||
const constants_1 = __webpack_require__(694);
|
||||
// From https://github.com/actions/toolkit/blob/master/packages/tool-cache/src/tool-cache.ts#L23
|
||||
function createTempDirectory() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const IS_WINDOWS = process.platform === "win32";
|
||||
let tempDirectory = process.env["RUNNER_TEMP"] || "";
|
||||
if (!tempDirectory) {
|
||||
let baseLocation;
|
||||
if (IS_WINDOWS) {
|
||||
// On Windows use the USERPROFILE env variable
|
||||
baseLocation = process.env["USERPROFILE"] || "C:\\";
|
||||
}
|
||||
else {
|
||||
if (process.platform === "darwin") {
|
||||
baseLocation = "/Users";
|
||||
}
|
||||
else {
|
||||
baseLocation = "/home";
|
||||
}
|
||||
}
|
||||
tempDirectory = path.join(baseLocation, "actions", "temp");
|
||||
}
|
||||
const dest = path.join(tempDirectory, uuidV4.default());
|
||||
yield io.mkdirP(dest);
|
||||
return dest;
|
||||
});
|
||||
}
|
||||
exports.createTempDirectory = createTempDirectory;
|
||||
function getArchiveFileSize(path) {
|
||||
return fs.statSync(path).size;
|
||||
}
|
||||
exports.getArchiveFileSize = getArchiveFileSize;
|
||||
function isExactKeyMatch(key, cacheResult) {
|
||||
return !!(cacheResult &&
|
||||
cacheResult.cacheKey &&
|
||||
cacheResult.cacheKey.localeCompare(key, undefined, {
|
||||
sensitivity: "accent"
|
||||
}) === 0);
|
||||
}
|
||||
exports.isExactKeyMatch = isExactKeyMatch;
|
||||
function setCacheState(state) {
|
||||
core.saveState(constants_1.State.CacheResult, JSON.stringify(state));
|
||||
}
|
||||
exports.setCacheState = setCacheState;
|
||||
function setCacheHitOutput(isCacheHit) {
|
||||
core.setOutput(constants_1.Outputs.CacheHit, isCacheHit.toString());
|
||||
}
|
||||
exports.setCacheHitOutput = setCacheHitOutput;
|
||||
function setOutputAndState(key, cacheResult) {
|
||||
setCacheHitOutput(isExactKeyMatch(key, cacheResult));
|
||||
// Store the cache result if it exists
|
||||
cacheResult && setCacheState(cacheResult);
|
||||
}
|
||||
exports.setOutputAndState = setOutputAndState;
|
||||
function getCacheState() {
|
||||
const stateData = core.getState(constants_1.State.CacheResult);
|
||||
core.debug(`State: ${stateData}`);
|
||||
if (stateData) {
|
||||
return JSON.parse(stateData);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
exports.getCacheState = getCacheState;
|
||||
function logWarning(message) {
|
||||
const warningPrefix = "[warning]";
|
||||
core.info(`${warningPrefix}${message}`);
|
||||
}
|
||||
exports.logWarning = logWarning;
|
||||
function resolvePath(filePath) {
|
||||
if (filePath[0] === "~") {
|
||||
const home = os.homedir();
|
||||
if (!home) {
|
||||
throw new Error("Unable to resolve `~` to HOME");
|
||||
}
|
||||
return path.join(home, filePath.slice(1));
|
||||
}
|
||||
return path.resolve(filePath);
|
||||
}
|
||||
exports.resolvePath = resolvePath;
|
||||
function getSupportedEvents() {
|
||||
return [constants_1.Events.Push, constants_1.Events.PullRequest];
|
||||
}
|
||||
exports.getSupportedEvents = getSupportedEvents;
|
||||
// Currently the cache token is only authorized for push and pull_request events
|
||||
// All other events will fail when reading and saving the cache
|
||||
// See GitHub Context https://help.github.com/actions/automating-your-workflow-with-github-actions/contexts-and-expression-syntax-for-github-actions#github-context
|
||||
function isValidEvent() {
|
||||
const githubEvent = process.env[constants_1.Events.Key] || "";
|
||||
return getSupportedEvents().includes(githubEvent);
|
||||
}
|
||||
exports.isValidEvent = isValidEvent;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 470:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
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());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const command_1 = __webpack_require__(431);
|
||||
const os = __webpack_require__(87);
|
||||
const path = __webpack_require__(622);
|
||||
/**
|
||||
* The code to exit an action
|
||||
*/
|
||||
var ExitCode;
|
||||
(function (ExitCode) {
|
||||
/**
|
||||
* A code indicating that the action was successful
|
||||
*/
|
||||
ExitCode[ExitCode["Success"] = 0] = "Success";
|
||||
/**
|
||||
* A code indicating that the action was a failure
|
||||
*/
|
||||
ExitCode[ExitCode["Failure"] = 1] = "Failure";
|
||||
})(ExitCode = exports.ExitCode || (exports.ExitCode = {}));
|
||||
//-----------------------------------------------------------------------
|
||||
// Variables
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Sets env variable for this action and future actions in the job
|
||||
* @param name the name of the variable to set
|
||||
* @param val the value of the variable
|
||||
*/
|
||||
function exportVariable(name, val) {
|
||||
process.env[name] = val;
|
||||
command_1.issueCommand('set-env', { name }, val);
|
||||
}
|
||||
exports.exportVariable = exportVariable;
|
||||
/**
|
||||
* Registers a secret which will get masked from logs
|
||||
* @param secret value of the secret
|
||||
*/
|
||||
function setSecret(secret) {
|
||||
command_1.issueCommand('add-mask', {}, secret);
|
||||
}
|
||||
exports.setSecret = setSecret;
|
||||
/**
|
||||
* Prepends inputPath to the PATH (for this action and future actions)
|
||||
* @param inputPath
|
||||
*/
|
||||
function addPath(inputPath) {
|
||||
command_1.issueCommand('add-path', {}, inputPath);
|
||||
process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`;
|
||||
}
|
||||
exports.addPath = addPath;
|
||||
/**
|
||||
* Gets the value of an input. The value is also trimmed.
|
||||
*
|
||||
* @param name name of the input to get
|
||||
* @param options optional. See InputOptions.
|
||||
* @returns string
|
||||
*/
|
||||
function getInput(name, options) {
|
||||
const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || '';
|
||||
if (options && options.required && !val) {
|
||||
throw new Error(`Input required and not supplied: ${name}`);
|
||||
}
|
||||
return val.trim();
|
||||
}
|
||||
exports.getInput = getInput;
|
||||
/**
|
||||
* Sets the value of an output.
|
||||
*
|
||||
* @param name name of the output to set
|
||||
* @param value value to store
|
||||
*/
|
||||
function setOutput(name, value) {
|
||||
command_1.issueCommand('set-output', { name }, value);
|
||||
}
|
||||
exports.setOutput = setOutput;
|
||||
//-----------------------------------------------------------------------
|
||||
// Results
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Sets the action status to failed.
|
||||
* When the action exits it will be with an exit code of 1
|
||||
* @param message add error issue message
|
||||
*/
|
||||
function setFailed(message) {
|
||||
process.exitCode = ExitCode.Failure;
|
||||
error(message);
|
||||
}
|
||||
exports.setFailed = setFailed;
|
||||
//-----------------------------------------------------------------------
|
||||
// Logging Commands
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Writes debug message to user log
|
||||
* @param message debug message
|
||||
*/
|
||||
function debug(message) {
|
||||
command_1.issueCommand('debug', {}, message);
|
||||
}
|
||||
exports.debug = debug;
|
||||
/**
|
||||
* Adds an error issue
|
||||
* @param message error issue message
|
||||
*/
|
||||
function error(message) {
|
||||
command_1.issue('error', message);
|
||||
}
|
||||
exports.error = error;
|
||||
/**
|
||||
* Adds an warning issue
|
||||
* @param message warning issue message
|
||||
*/
|
||||
function warning(message) {
|
||||
command_1.issue('warning', message);
|
||||
}
|
||||
exports.warning = warning;
|
||||
/**
|
||||
* Writes info to log with console.log.
|
||||
* @param message info message
|
||||
*/
|
||||
function info(message) {
|
||||
process.stdout.write(message + os.EOL);
|
||||
}
|
||||
exports.info = info;
|
||||
/**
|
||||
* Begin an output group.
|
||||
*
|
||||
* Output until the next `groupEnd` will be foldable in this group
|
||||
*
|
||||
* @param name The name of the output group
|
||||
*/
|
||||
function startGroup(name) {
|
||||
command_1.issue('group', name);
|
||||
}
|
||||
exports.startGroup = startGroup;
|
||||
/**
|
||||
* End an output group.
|
||||
*/
|
||||
function endGroup() {
|
||||
command_1.issue('endgroup');
|
||||
}
|
||||
exports.endGroup = endGroup;
|
||||
/**
|
||||
* Wrap an asynchronous function call in a group.
|
||||
*
|
||||
* Returns the same type as the function itself.
|
||||
*
|
||||
* @param name The name of the group
|
||||
* @param fn The function to wrap in the group
|
||||
*/
|
||||
function group(name, fn) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
startGroup(name);
|
||||
let result;
|
||||
try {
|
||||
result = yield fn();
|
||||
}
|
||||
finally {
|
||||
endGroup();
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
exports.group = group;
|
||||
//-----------------------------------------------------------------------
|
||||
// Wrapper action state
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Saves state for current action, the state can only be retrieved by this action's post job execution.
|
||||
*
|
||||
* @param name name of the state to store
|
||||
* @param value value to store
|
||||
*/
|
||||
function saveState(name, value) {
|
||||
command_1.issueCommand('save-state', { name }, value);
|
||||
}
|
||||
exports.saveState = saveState;
|
||||
/**
|
||||
* Gets the value of an state set by this action's main execution.
|
||||
*
|
||||
* @param name name of the state to get
|
||||
* @returns string
|
||||
*/
|
||||
function getState(name) {
|
||||
return process.env[`STATE_${name}`] || '';
|
||||
}
|
||||
exports.getState = getState;
|
||||
//# sourceMappingURL=core.js.map
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 525:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const http = __webpack_require__(605);
|
||||
const https = __webpack_require__(211);
|
||||
const _ = __webpack_require__(891);
|
||||
const ntlm = __webpack_require__(432);
|
||||
class NtlmCredentialHandler {
|
||||
constructor(username, password, workstation, domain) {
|
||||
this._ntlmOptions = {};
|
||||
this._ntlmOptions.username = username;
|
||||
this._ntlmOptions.password = password;
|
||||
if (domain !== undefined) {
|
||||
this._ntlmOptions.domain = domain;
|
||||
}
|
||||
else {
|
||||
this._ntlmOptions.domain = '';
|
||||
}
|
||||
if (workstation !== undefined) {
|
||||
this._ntlmOptions.workstation = workstation;
|
||||
}
|
||||
else {
|
||||
this._ntlmOptions.workstation = '';
|
||||
}
|
||||
}
|
||||
prepareRequest(options) {
|
||||
// No headers or options need to be set. We keep the credentials on the handler itself.
|
||||
// If a (proxy) agent is set, remove it as we don't support proxy for NTLM at this time
|
||||
if (options.agent) {
|
||||
delete options.agent;
|
||||
}
|
||||
}
|
||||
canHandleAuthentication(response) {
|
||||
if (response && response.message && response.message.statusCode === 401) {
|
||||
// Ensure that we're talking NTLM here
|
||||
// Once we have the www-authenticate header, split it so we can ensure we can talk NTLM
|
||||
const wwwAuthenticate = response.message.headers['www-authenticate'];
|
||||
if (wwwAuthenticate) {
|
||||
const mechanisms = wwwAuthenticate.split(', ');
|
||||
const index = mechanisms.indexOf("NTLM");
|
||||
if (index >= 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
handleAuthentication(httpClient, requestInfo, objs) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const callbackForResult = function (err, res) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
}
|
||||
// We have to readbody on the response before continuing otherwise there is a hang.
|
||||
res.readBody().then(() => {
|
||||
resolve(res);
|
||||
});
|
||||
};
|
||||
this.handleAuthenticationPrivate(httpClient, requestInfo, objs, callbackForResult);
|
||||
});
|
||||
}
|
||||
handleAuthenticationPrivate(httpClient, requestInfo, objs, finalCallback) {
|
||||
// Set up the headers for NTLM authentication
|
||||
requestInfo.options = _.extend(requestInfo.options, {
|
||||
username: this._ntlmOptions.username,
|
||||
password: this._ntlmOptions.password,
|
||||
domain: this._ntlmOptions.domain,
|
||||
workstation: this._ntlmOptions.workstation
|
||||
});
|
||||
if (httpClient.isSsl === true) {
|
||||
requestInfo.options.agent = new https.Agent({ keepAlive: true });
|
||||
}
|
||||
else {
|
||||
requestInfo.options.agent = new http.Agent({ keepAlive: true });
|
||||
}
|
||||
let self = this;
|
||||
// The following pattern of sending the type1 message following immediately (in a setImmediate) is
|
||||
// critical for the NTLM exchange to happen. If we removed setImmediate (or call in a different manner)
|
||||
// the NTLM exchange will always fail with a 401.
|
||||
this.sendType1Message(httpClient, requestInfo, objs, function (err, res) {
|
||||
if (err) {
|
||||
return finalCallback(err, null, null);
|
||||
}
|
||||
/// We have to readbody on the response before continuing otherwise there is a hang.
|
||||
res.readBody().then(() => {
|
||||
// It is critical that we have setImmediate here due to how connection requests are queued.
|
||||
// If setImmediate is removed then the NTLM handshake will not work.
|
||||
// setImmediate allows us to queue a second request on the same connection. If this second
|
||||
// request is not queued on the connection when the first request finishes then node closes
|
||||
// the connection. NTLM requires both requests to be on the same connection so we need this.
|
||||
setImmediate(function () {
|
||||
self.sendType3Message(httpClient, requestInfo, objs, res, finalCallback);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
// The following method is an adaptation of code found at https://github.com/SamDecrock/node-http-ntlm/blob/master/httpntlm.js
|
||||
sendType1Message(httpClient, requestInfo, objs, finalCallback) {
|
||||
const type1msg = ntlm.createType1Message(this._ntlmOptions);
|
||||
const type1options = {
|
||||
headers: {
|
||||
'Connection': 'keep-alive',
|
||||
'Authorization': type1msg
|
||||
},
|
||||
timeout: requestInfo.options.timeout || 0,
|
||||
agent: requestInfo.httpModule,
|
||||
};
|
||||
const type1info = {};
|
||||
type1info.httpModule = requestInfo.httpModule;
|
||||
type1info.parsedUrl = requestInfo.parsedUrl;
|
||||
type1info.options = _.extend(type1options, _.omit(requestInfo.options, 'headers'));
|
||||
return httpClient.requestRawWithCallback(type1info, objs, finalCallback);
|
||||
}
|
||||
// The following method is an adaptation of code found at https://github.com/SamDecrock/node-http-ntlm/blob/master/httpntlm.js
|
||||
sendType3Message(httpClient, requestInfo, objs, res, callback) {
|
||||
if (!res.message.headers && !res.message.headers['www-authenticate']) {
|
||||
throw new Error('www-authenticate not found on response of second request');
|
||||
}
|
||||
const type2msg = ntlm.parseType2Message(res.message.headers['www-authenticate']);
|
||||
const type3msg = ntlm.createType3Message(type2msg, this._ntlmOptions);
|
||||
const type3options = {
|
||||
headers: {
|
||||
'Authorization': type3msg,
|
||||
'Connection': 'Close'
|
||||
},
|
||||
agent: requestInfo.httpModule,
|
||||
};
|
||||
const type3info = {};
|
||||
type3info.httpModule = requestInfo.httpModule;
|
||||
type3info.parsedUrl = requestInfo.parsedUrl;
|
||||
type3options.headers = _.extend(type3options.headers, requestInfo.options.headers);
|
||||
type3info.options = _.extend(type3options, _.omit(requestInfo.options, 'headers'));
|
||||
return httpClient.requestRawWithCallback(type3info, objs, callback);
|
||||
}
|
||||
}
|
||||
exports.NtlmCredentialHandler = NtlmCredentialHandler;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 571:
|
||||
/***/ (function(__unusedmodule, exports) {
|
||||
|
||||
"use strict";
|
||||
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
class BearerCredentialHandler {
|
||||
constructor(token) {
|
||||
this.token = token;
|
||||
}
|
||||
// currently implements pre-authorization
|
||||
// TODO: support preAuth = false where it hooks on 401
|
||||
prepareRequest(options) {
|
||||
options.headers['Authorization'] = 'Bearer ' + this.token;
|
||||
options.headers['X-TFS-FedAuthRedirect'] = 'Suppress';
|
||||
}
|
||||
// This handler cannot handle 401
|
||||
canHandleAuthentication(response) {
|
||||
return false;
|
||||
}
|
||||
handleAuthentication(httpClient, requestInfo, objs) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
exports.BearerCredentialHandler = BearerCredentialHandler;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 605:
|
||||
/***/ (function(module) {
|
||||
|
||||
module.exports = require("http");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 614:
|
||||
/***/ (function(module) {
|
||||
|
||||
module.exports = require("events");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 622:
|
||||
/***/ (function(module) {
|
||||
|
||||
module.exports = require("path");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 631:
|
||||
/***/ (function(module) {
|
||||
|
||||
module.exports = require("net");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 669:
|
||||
/***/ (function(module) {
|
||||
|
||||
module.exports = require("util");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 672:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
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 _a;
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const assert_1 = __webpack_require__(357);
|
||||
const fs = __webpack_require__(747);
|
||||
const path = __webpack_require__(622);
|
||||
_a = fs.promises, exports.chmod = _a.chmod, exports.copyFile = _a.copyFile, exports.lstat = _a.lstat, exports.mkdir = _a.mkdir, exports.readdir = _a.readdir, exports.readlink = _a.readlink, exports.rename = _a.rename, exports.rmdir = _a.rmdir, exports.stat = _a.stat, exports.symlink = _a.symlink, exports.unlink = _a.unlink;
|
||||
exports.IS_WINDOWS = process.platform === 'win32';
|
||||
function exists(fsPath) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
yield exports.stat(fsPath);
|
||||
}
|
||||
catch (err) {
|
||||
if (err.code === 'ENOENT') {
|
||||
return false;
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
exports.exists = exists;
|
||||
function isDirectory(fsPath, useStat = false) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const stats = useStat ? yield exports.stat(fsPath) : yield exports.lstat(fsPath);
|
||||
return stats.isDirectory();
|
||||
});
|
||||
}
|
||||
exports.isDirectory = isDirectory;
|
||||
/**
|
||||
* On OSX/Linux, true if path starts with '/'. On Windows, true for paths like:
|
||||
* \, \hello, \\hello\share, C:, and C:\hello (and corresponding alternate separator cases).
|
||||
*/
|
||||
function isRooted(p) {
|
||||
p = normalizeSeparators(p);
|
||||
if (!p) {
|
||||
throw new Error('isRooted() parameter "p" cannot be empty');
|
||||
}
|
||||
if (exports.IS_WINDOWS) {
|
||||
return (p.startsWith('\\') || /^[A-Z]:/i.test(p) // e.g. \ or \hello or \\hello
|
||||
); // e.g. C: or C:\hello
|
||||
}
|
||||
return p.startsWith('/');
|
||||
}
|
||||
exports.isRooted = isRooted;
|
||||
/**
|
||||
* Recursively create a directory at `fsPath`.
|
||||
*
|
||||
* This implementation is optimistic, meaning it attempts to create the full
|
||||
* path first, and backs up the path stack from there.
|
||||
*
|
||||
* @param fsPath The path to create
|
||||
* @param maxDepth The maximum recursion depth
|
||||
* @param depth The current recursion depth
|
||||
*/
|
||||
function mkdirP(fsPath, maxDepth = 1000, depth = 1) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
assert_1.ok(fsPath, 'a path argument must be provided');
|
||||
fsPath = path.resolve(fsPath);
|
||||
if (depth >= maxDepth)
|
||||
return exports.mkdir(fsPath);
|
||||
try {
|
||||
yield exports.mkdir(fsPath);
|
||||
return;
|
||||
}
|
||||
catch (err) {
|
||||
switch (err.code) {
|
||||
case 'ENOENT': {
|
||||
yield mkdirP(path.dirname(fsPath), maxDepth, depth + 1);
|
||||
yield exports.mkdir(fsPath);
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
let stats;
|
||||
try {
|
||||
stats = yield exports.stat(fsPath);
|
||||
}
|
||||
catch (err2) {
|
||||
throw err;
|
||||
}
|
||||
if (!stats.isDirectory())
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.mkdirP = mkdirP;
|
||||
/**
|
||||
* Best effort attempt to determine whether a file exists and is executable.
|
||||
* @param filePath file path to check
|
||||
* @param extensions additional file extensions to try
|
||||
* @return if file exists and is executable, returns the file path. otherwise empty string.
|
||||
*/
|
||||
function tryGetExecutablePath(filePath, extensions) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let stats = undefined;
|
||||
try {
|
||||
// test file exists
|
||||
stats = yield exports.stat(filePath);
|
||||
}
|
||||
catch (err) {
|
||||
if (err.code !== 'ENOENT') {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`);
|
||||
}
|
||||
}
|
||||
if (stats && stats.isFile()) {
|
||||
if (exports.IS_WINDOWS) {
|
||||
// on Windows, test for valid extension
|
||||
const upperExt = path.extname(filePath).toUpperCase();
|
||||
if (extensions.some(validExt => validExt.toUpperCase() === upperExt)) {
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (isUnixExecutable(stats)) {
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
// try each extension
|
||||
const originalFilePath = filePath;
|
||||
for (const extension of extensions) {
|
||||
filePath = originalFilePath + extension;
|
||||
stats = undefined;
|
||||
try {
|
||||
stats = yield exports.stat(filePath);
|
||||
}
|
||||
catch (err) {
|
||||
if (err.code !== 'ENOENT') {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`);
|
||||
}
|
||||
}
|
||||
if (stats && stats.isFile()) {
|
||||
if (exports.IS_WINDOWS) {
|
||||
// preserve the case of the actual file (since an extension was appended)
|
||||
try {
|
||||
const directory = path.dirname(filePath);
|
||||
const upperName = path.basename(filePath).toUpperCase();
|
||||
for (const actualName of yield exports.readdir(directory)) {
|
||||
if (upperName === actualName.toUpperCase()) {
|
||||
filePath = path.join(directory, actualName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`Unexpected error attempting to determine the actual case of the file '${filePath}': ${err}`);
|
||||
}
|
||||
return filePath;
|
||||
}
|
||||
else {
|
||||
if (isUnixExecutable(stats)) {
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return '';
|
||||
});
|
||||
}
|
||||
exports.tryGetExecutablePath = tryGetExecutablePath;
|
||||
function normalizeSeparators(p) {
|
||||
p = p || '';
|
||||
if (exports.IS_WINDOWS) {
|
||||
// convert slashes on Windows
|
||||
p = p.replace(/\//g, '\\');
|
||||
// remove redundant slashes
|
||||
return p.replace(/\\\\+/g, '\\');
|
||||
}
|
||||
// remove redundant slashes
|
||||
return p.replace(/\/\/+/g, '/');
|
||||
}
|
||||
// on Mac/Linux, test the execute bit
|
||||
// R W X R W X R W X
|
||||
// 256 128 64 32 16 8 4 2 1
|
||||
function isUnixExecutable(stats) {
|
||||
return ((stats.mode & 1) > 0 ||
|
||||
((stats.mode & 8) > 0 && stats.gid === process.getgid()) ||
|
||||
((stats.mode & 64) > 0 && stats.uid === process.getuid()));
|
||||
}
|
||||
//# sourceMappingURL=io-util.js.map
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 681:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
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 __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 core = __importStar(__webpack_require__(470));
|
||||
const path = __importStar(__webpack_require__(622));
|
||||
const cacheHttpClient = __importStar(__webpack_require__(154));
|
||||
const constants_1 = __webpack_require__(694);
|
||||
const tar_1 = __webpack_require__(943);
|
||||
const utils = __importStar(__webpack_require__(443));
|
||||
function run() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
if (!utils.isValidEvent()) {
|
||||
utils.logWarning(`Event Validation Error: The event type ${process.env[constants_1.Events.Key]} is not supported. Only ${utils
|
||||
.getSupportedEvents()
|
||||
.join(", ")} events are supported at this time.`);
|
||||
return;
|
||||
}
|
||||
const state = utils.getCacheState();
|
||||
// Inputs are re-evaluted before the post action, so we want the original key used for restore
|
||||
const primaryKey = core.getState(constants_1.State.CacheKey);
|
||||
if (!primaryKey) {
|
||||
utils.logWarning(`Error retrieving key from state.`);
|
||||
return;
|
||||
}
|
||||
if (utils.isExactKeyMatch(primaryKey, state)) {
|
||||
core.info(`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`);
|
||||
return;
|
||||
}
|
||||
const cachePath = utils.resolvePath(core.getInput(constants_1.Inputs.Path, { required: true }));
|
||||
core.debug(`Cache Path: ${cachePath}`);
|
||||
const archivePath = path.join(yield utils.createTempDirectory(), "cache.tgz");
|
||||
core.debug(`Archive Path: ${archivePath}`);
|
||||
yield tar_1.createTar(archivePath, cachePath);
|
||||
const fileSizeLimit = 400 * 1024 * 1024; // 400MB
|
||||
const archiveFileSize = utils.getArchiveFileSize(archivePath);
|
||||
core.debug(`File Size: ${archiveFileSize}`);
|
||||
if (archiveFileSize > fileSizeLimit) {
|
||||
utils.logWarning(`Cache size of ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B) is over the 400MB limit, not saving cache.`);
|
||||
return;
|
||||
}
|
||||
yield cacheHttpClient.saveCache(primaryKey, archivePath);
|
||||
}
|
||||
catch (error) {
|
||||
utils.logWarning(error.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
run();
|
||||
exports.default = run;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 694:
|
||||
/***/ (function(__unusedmodule, exports) {
|
||||
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var Inputs;
|
||||
(function (Inputs) {
|
||||
Inputs["Key"] = "key";
|
||||
Inputs["Path"] = "path";
|
||||
Inputs["RestoreKeys"] = "restore-keys";
|
||||
})(Inputs = exports.Inputs || (exports.Inputs = {}));
|
||||
var Outputs;
|
||||
(function (Outputs) {
|
||||
Outputs["CacheHit"] = "cache-hit";
|
||||
})(Outputs = exports.Outputs || (exports.Outputs = {}));
|
||||
var State;
|
||||
(function (State) {
|
||||
State["CacheKey"] = "CACHE_KEY";
|
||||
State["CacheResult"] = "CACHE_RESULT";
|
||||
})(State = exports.State || (exports.State = {}));
|
||||
var Events;
|
||||
(function (Events) {
|
||||
Events["Key"] = "GITHUB_EVENT_NAME";
|
||||
Events["Push"] = "push";
|
||||
Events["PullRequest"] = "pull_request";
|
||||
})(Events = exports.Events || (exports.Events = {}));
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 722:
|
||||
/***/ (function(module) {
|
||||
|
||||
/**
|
||||
* Convert array of 16 byte values to UUID string format of the form:
|
||||
* XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
|
||||
*/
|
||||
var byteToHex = [];
|
||||
for (var i = 0; i < 256; ++i) {
|
||||
byteToHex[i] = (i + 0x100).toString(16).substr(1);
|
||||
}
|
||||
|
||||
function bytesToUuid(buf, offset) {
|
||||
var i = offset || 0;
|
||||
var bth = byteToHex;
|
||||
// join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4
|
||||
return ([bth[buf[i++]], bth[buf[i++]],
|
||||
bth[buf[i++]], bth[buf[i++]], '-',
|
||||
bth[buf[i++]], bth[buf[i++]], '-',
|
||||
bth[buf[i++]], bth[buf[i++]], '-',
|
||||
bth[buf[i++]], bth[buf[i++]], '-',
|
||||
bth[buf[i++]], bth[buf[i++]],
|
||||
bth[buf[i++]], bth[buf[i++]],
|
||||
bth[buf[i++]], bth[buf[i++]]]).join('');
|
||||
}
|
||||
|
||||
module.exports = bytesToUuid;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 729:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const url = __webpack_require__(835);
|
||||
const path = __webpack_require__(622);
|
||||
/**
|
||||
* creates an url from a request url and optional base url (http://server:8080)
|
||||
* @param {string} resource - a fully qualified url or relative path
|
||||
* @param {string} baseUrl - an optional baseUrl (http://server:8080)
|
||||
* @return {string} - resultant url
|
||||
*/
|
||||
function getUrl(resource, baseUrl) {
|
||||
const pathApi = path.posix || path;
|
||||
if (!baseUrl) {
|
||||
return resource;
|
||||
}
|
||||
else if (!resource) {
|
||||
return baseUrl;
|
||||
}
|
||||
else {
|
||||
const base = url.parse(baseUrl);
|
||||
const resultantUrl = url.parse(resource);
|
||||
// resource (specific per request) elements take priority
|
||||
resultantUrl.protocol = resultantUrl.protocol || base.protocol;
|
||||
resultantUrl.auth = resultantUrl.auth || base.auth;
|
||||
resultantUrl.host = resultantUrl.host || base.host;
|
||||
resultantUrl.pathname = pathApi.resolve(base.pathname, resultantUrl.pathname);
|
||||
if (!resultantUrl.pathname.endsWith('/') && resource.endsWith('/')) {
|
||||
resultantUrl.pathname += '/';
|
||||
}
|
||||
return url.format(resultantUrl);
|
||||
}
|
||||
}
|
||||
exports.getUrl = getUrl;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 747:
|
||||
/***/ (function(module) {
|
||||
|
||||
module.exports = require("fs");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 826:
|
||||
/***/ (function(module, __unusedexports, __webpack_require__) {
|
||||
|
||||
var rng = __webpack_require__(139);
|
||||
var bytesToUuid = __webpack_require__(722);
|
||||
|
||||
function v4(options, buf, offset) {
|
||||
var i = buf && offset || 0;
|
||||
|
||||
if (typeof(options) == 'string') {
|
||||
buf = options === 'binary' ? new Array(16) : null;
|
||||
options = null;
|
||||
}
|
||||
options = options || {};
|
||||
|
||||
var rnds = options.random || (options.rng || rng)();
|
||||
|
||||
// Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
|
||||
rnds[6] = (rnds[6] & 0x0f) | 0x40;
|
||||
rnds[8] = (rnds[8] & 0x3f) | 0x80;
|
||||
|
||||
// Copy bytes to buffer, if provided
|
||||
if (buf) {
|
||||
for (var ii = 0; ii < 16; ++ii) {
|
||||
buf[i + ii] = rnds[ii];
|
||||
}
|
||||
}
|
||||
|
||||
return buf || bytesToUuid(rnds);
|
||||
}
|
||||
|
||||
module.exports = v4;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 835:
|
||||
/***/ (function(module) {
|
||||
|
||||
module.exports = require("url");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 874:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
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());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const url = __webpack_require__(835);
|
||||
const http = __webpack_require__(605);
|
||||
const https = __webpack_require__(211);
|
||||
let fs;
|
||||
let tunnel;
|
||||
var HttpCodes;
|
||||
(function (HttpCodes) {
|
||||
HttpCodes[HttpCodes["OK"] = 200] = "OK";
|
||||
HttpCodes[HttpCodes["MultipleChoices"] = 300] = "MultipleChoices";
|
||||
HttpCodes[HttpCodes["MovedPermanently"] = 301] = "MovedPermanently";
|
||||
HttpCodes[HttpCodes["ResourceMoved"] = 302] = "ResourceMoved";
|
||||
HttpCodes[HttpCodes["SeeOther"] = 303] = "SeeOther";
|
||||
HttpCodes[HttpCodes["NotModified"] = 304] = "NotModified";
|
||||
HttpCodes[HttpCodes["UseProxy"] = 305] = "UseProxy";
|
||||
HttpCodes[HttpCodes["SwitchProxy"] = 306] = "SwitchProxy";
|
||||
HttpCodes[HttpCodes["TemporaryRedirect"] = 307] = "TemporaryRedirect";
|
||||
HttpCodes[HttpCodes["PermanentRedirect"] = 308] = "PermanentRedirect";
|
||||
HttpCodes[HttpCodes["BadRequest"] = 400] = "BadRequest";
|
||||
HttpCodes[HttpCodes["Unauthorized"] = 401] = "Unauthorized";
|
||||
HttpCodes[HttpCodes["PaymentRequired"] = 402] = "PaymentRequired";
|
||||
HttpCodes[HttpCodes["Forbidden"] = 403] = "Forbidden";
|
||||
HttpCodes[HttpCodes["NotFound"] = 404] = "NotFound";
|
||||
HttpCodes[HttpCodes["MethodNotAllowed"] = 405] = "MethodNotAllowed";
|
||||
HttpCodes[HttpCodes["NotAcceptable"] = 406] = "NotAcceptable";
|
||||
HttpCodes[HttpCodes["ProxyAuthenticationRequired"] = 407] = "ProxyAuthenticationRequired";
|
||||
HttpCodes[HttpCodes["RequestTimeout"] = 408] = "RequestTimeout";
|
||||
HttpCodes[HttpCodes["Conflict"] = 409] = "Conflict";
|
||||
HttpCodes[HttpCodes["Gone"] = 410] = "Gone";
|
||||
HttpCodes[HttpCodes["InternalServerError"] = 500] = "InternalServerError";
|
||||
HttpCodes[HttpCodes["NotImplemented"] = 501] = "NotImplemented";
|
||||
HttpCodes[HttpCodes["BadGateway"] = 502] = "BadGateway";
|
||||
HttpCodes[HttpCodes["ServiceUnavailable"] = 503] = "ServiceUnavailable";
|
||||
HttpCodes[HttpCodes["GatewayTimeout"] = 504] = "GatewayTimeout";
|
||||
})(HttpCodes = exports.HttpCodes || (exports.HttpCodes = {}));
|
||||
const HttpRedirectCodes = [HttpCodes.MovedPermanently, HttpCodes.ResourceMoved, HttpCodes.SeeOther, HttpCodes.TemporaryRedirect, HttpCodes.PermanentRedirect];
|
||||
const HttpResponseRetryCodes = [HttpCodes.BadGateway, HttpCodes.ServiceUnavailable, HttpCodes.GatewayTimeout];
|
||||
const RetryableHttpVerbs = ['OPTIONS', 'GET', 'DELETE', 'HEAD'];
|
||||
const ExponentialBackoffCeiling = 10;
|
||||
const ExponentialBackoffTimeSlice = 5;
|
||||
class HttpClientResponse {
|
||||
constructor(message) {
|
||||
this.message = message;
|
||||
}
|
||||
readBody() {
|
||||
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
||||
let output = '';
|
||||
this.message.on('data', (chunk) => {
|
||||
output += chunk;
|
||||
});
|
||||
this.message.on('end', () => {
|
||||
resolve(output);
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
exports.HttpClientResponse = HttpClientResponse;
|
||||
function isHttps(requestUrl) {
|
||||
let parsedUrl = url.parse(requestUrl);
|
||||
return parsedUrl.protocol === 'https:';
|
||||
}
|
||||
exports.isHttps = isHttps;
|
||||
var EnvironmentVariables;
|
||||
(function (EnvironmentVariables) {
|
||||
EnvironmentVariables["HTTP_PROXY"] = "HTTP_PROXY";
|
||||
EnvironmentVariables["HTTPS_PROXY"] = "HTTPS_PROXY";
|
||||
})(EnvironmentVariables || (EnvironmentVariables = {}));
|
||||
class HttpClient {
|
||||
constructor(userAgent, handlers, requestOptions) {
|
||||
this._ignoreSslError = false;
|
||||
this._allowRedirects = true;
|
||||
this._maxRedirects = 50;
|
||||
this._allowRetries = false;
|
||||
this._maxRetries = 1;
|
||||
this._keepAlive = false;
|
||||
this._disposed = false;
|
||||
this.userAgent = userAgent;
|
||||
this.handlers = handlers || [];
|
||||
this.requestOptions = requestOptions;
|
||||
if (requestOptions) {
|
||||
if (requestOptions.ignoreSslError != null) {
|
||||
this._ignoreSslError = requestOptions.ignoreSslError;
|
||||
}
|
||||
this._socketTimeout = requestOptions.socketTimeout;
|
||||
this._httpProxy = requestOptions.proxy;
|
||||
if (requestOptions.proxy && requestOptions.proxy.proxyBypassHosts) {
|
||||
this._httpProxyBypassHosts = [];
|
||||
requestOptions.proxy.proxyBypassHosts.forEach(bypass => {
|
||||
this._httpProxyBypassHosts.push(new RegExp(bypass, 'i'));
|
||||
});
|
||||
}
|
||||
this._certConfig = requestOptions.cert;
|
||||
if (this._certConfig) {
|
||||
// If using cert, need fs
|
||||
fs = __webpack_require__(747);
|
||||
// cache the cert content into memory, so we don't have to read it from disk every time
|
||||
if (this._certConfig.caFile && fs.existsSync(this._certConfig.caFile)) {
|
||||
this._ca = fs.readFileSync(this._certConfig.caFile, 'utf8');
|
||||
}
|
||||
if (this._certConfig.certFile && fs.existsSync(this._certConfig.certFile)) {
|
||||
this._cert = fs.readFileSync(this._certConfig.certFile, 'utf8');
|
||||
}
|
||||
if (this._certConfig.keyFile && fs.existsSync(this._certConfig.keyFile)) {
|
||||
this._key = fs.readFileSync(this._certConfig.keyFile, 'utf8');
|
||||
}
|
||||
}
|
||||
if (requestOptions.allowRedirects != null) {
|
||||
this._allowRedirects = requestOptions.allowRedirects;
|
||||
}
|
||||
if (requestOptions.maxRedirects != null) {
|
||||
this._maxRedirects = Math.max(requestOptions.maxRedirects, 0);
|
||||
}
|
||||
if (requestOptions.keepAlive != null) {
|
||||
this._keepAlive = requestOptions.keepAlive;
|
||||
}
|
||||
if (requestOptions.allowRetries != null) {
|
||||
this._allowRetries = requestOptions.allowRetries;
|
||||
}
|
||||
if (requestOptions.maxRetries != null) {
|
||||
this._maxRetries = requestOptions.maxRetries;
|
||||
}
|
||||
}
|
||||
}
|
||||
options(requestUrl, additionalHeaders) {
|
||||
return this.request('OPTIONS', requestUrl, null, additionalHeaders || {});
|
||||
}
|
||||
get(requestUrl, additionalHeaders) {
|
||||
return this.request('GET', requestUrl, null, additionalHeaders || {});
|
||||
}
|
||||
del(requestUrl, additionalHeaders) {
|
||||
return this.request('DELETE', requestUrl, null, additionalHeaders || {});
|
||||
}
|
||||
post(requestUrl, data, additionalHeaders) {
|
||||
return this.request('POST', requestUrl, data, additionalHeaders || {});
|
||||
}
|
||||
patch(requestUrl, data, additionalHeaders) {
|
||||
return this.request('PATCH', requestUrl, data, additionalHeaders || {});
|
||||
}
|
||||
put(requestUrl, data, additionalHeaders) {
|
||||
return this.request('PUT', requestUrl, data, additionalHeaders || {});
|
||||
}
|
||||
head(requestUrl, additionalHeaders) {
|
||||
return this.request('HEAD', requestUrl, null, additionalHeaders || {});
|
||||
}
|
||||
sendStream(verb, requestUrl, stream, additionalHeaders) {
|
||||
return this.request(verb, requestUrl, stream, additionalHeaders);
|
||||
}
|
||||
/**
|
||||
* Makes a raw http request.
|
||||
* All other methods such as get, post, patch, and request ultimately call this.
|
||||
* Prefer get, del, post and patch
|
||||
*/
|
||||
request(verb, requestUrl, data, headers) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (this._disposed) {
|
||||
throw new Error("Client has already been disposed.");
|
||||
}
|
||||
let info = this._prepareRequest(verb, requestUrl, headers);
|
||||
// Only perform retries on reads since writes may not be idempotent.
|
||||
let maxTries = (this._allowRetries && RetryableHttpVerbs.indexOf(verb) != -1) ? this._maxRetries + 1 : 1;
|
||||
let numTries = 0;
|
||||
let response;
|
||||
while (numTries < maxTries) {
|
||||
response = yield this.requestRaw(info, data);
|
||||
// Check if it's an authentication challenge
|
||||
if (response && response.message && response.message.statusCode === HttpCodes.Unauthorized) {
|
||||
let authenticationHandler;
|
||||
for (let i = 0; i < this.handlers.length; i++) {
|
||||
if (this.handlers[i].canHandleAuthentication(response)) {
|
||||
authenticationHandler = this.handlers[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (authenticationHandler) {
|
||||
return authenticationHandler.handleAuthentication(this, info, data);
|
||||
}
|
||||
else {
|
||||
// We have received an unauthorized response but have no handlers to handle it.
|
||||
// Let the response return to the caller.
|
||||
return response;
|
||||
}
|
||||
}
|
||||
let redirectsRemaining = this._maxRedirects;
|
||||
while (HttpRedirectCodes.indexOf(response.message.statusCode) != -1
|
||||
&& this._allowRedirects
|
||||
&& redirectsRemaining > 0) {
|
||||
const redirectUrl = response.message.headers["location"];
|
||||
if (!redirectUrl) {
|
||||
// if there's no location to redirect to, we won't
|
||||
break;
|
||||
}
|
||||
// we need to finish reading the response before reassigning response
|
||||
// which will leak the open socket.
|
||||
yield response.readBody();
|
||||
// let's make the request with the new redirectUrl
|
||||
info = this._prepareRequest(verb, redirectUrl, headers);
|
||||
response = yield this.requestRaw(info, data);
|
||||
redirectsRemaining--;
|
||||
}
|
||||
if (HttpResponseRetryCodes.indexOf(response.message.statusCode) == -1) {
|
||||
// If not a retry code, return immediately instead of retrying
|
||||
return response;
|
||||
}
|
||||
numTries += 1;
|
||||
if (numTries < maxTries) {
|
||||
yield response.readBody();
|
||||
yield this._performExponentialBackoff(numTries);
|
||||
}
|
||||
}
|
||||
return response;
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Needs to be called if keepAlive is set to true in request options.
|
||||
*/
|
||||
dispose() {
|
||||
if (this._agent) {
|
||||
this._agent.destroy();
|
||||
}
|
||||
this._disposed = true;
|
||||
}
|
||||
/**
|
||||
* Raw request.
|
||||
* @param info
|
||||
* @param data
|
||||
*/
|
||||
requestRaw(info, data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let callbackForResult = function (err, res) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
}
|
||||
resolve(res);
|
||||
};
|
||||
this.requestRawWithCallback(info, data, callbackForResult);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Raw request with callback.
|
||||
* @param info
|
||||
* @param data
|
||||
* @param onResult
|
||||
*/
|
||||
requestRawWithCallback(info, data, onResult) {
|
||||
let socket;
|
||||
let isDataString = typeof (data) === 'string';
|
||||
if (typeof (data) === 'string') {
|
||||
info.options.headers["Content-Length"] = Buffer.byteLength(data, 'utf8');
|
||||
}
|
||||
let callbackCalled = false;
|
||||
let handleResult = (err, res) => {
|
||||
if (!callbackCalled) {
|
||||
callbackCalled = true;
|
||||
onResult(err, res);
|
||||
}
|
||||
};
|
||||
let req = info.httpModule.request(info.options, (msg) => {
|
||||
let res = new HttpClientResponse(msg);
|
||||
handleResult(null, res);
|
||||
});
|
||||
req.on('socket', (sock) => {
|
||||
socket = sock;
|
||||
});
|
||||
// If we ever get disconnected, we want the socket to timeout eventually
|
||||
req.setTimeout(this._socketTimeout || 3 * 60000, () => {
|
||||
if (socket) {
|
||||
socket.end();
|
||||
}
|
||||
handleResult(new Error('Request timeout: ' + info.options.path), null);
|
||||
});
|
||||
req.on('error', function (err) {
|
||||
// err has statusCode property
|
||||
// res should have headers
|
||||
handleResult(err, null);
|
||||
});
|
||||
if (data && typeof (data) === 'string') {
|
||||
req.write(data, 'utf8');
|
||||
}
|
||||
if (data && typeof (data) !== 'string') {
|
||||
data.on('close', function () {
|
||||
req.end();
|
||||
});
|
||||
data.pipe(req);
|
||||
}
|
||||
else {
|
||||
req.end();
|
||||
}
|
||||
}
|
||||
_prepareRequest(method, requestUrl, headers) {
|
||||
const info = {};
|
||||
info.parsedUrl = url.parse(requestUrl);
|
||||
const usingSsl = info.parsedUrl.protocol === 'https:';
|
||||
info.httpModule = usingSsl ? https : http;
|
||||
const defaultPort = usingSsl ? 443 : 80;
|
||||
info.options = {};
|
||||
info.options.host = info.parsedUrl.hostname;
|
||||
info.options.port = info.parsedUrl.port ? parseInt(info.parsedUrl.port) : defaultPort;
|
||||
info.options.path = (info.parsedUrl.pathname || '') + (info.parsedUrl.search || '');
|
||||
info.options.method = method;
|
||||
info.options.headers = this._mergeHeaders(headers);
|
||||
info.options.headers["user-agent"] = this.userAgent;
|
||||
info.options.agent = this._getAgent(requestUrl);
|
||||
// gives handlers an opportunity to participate
|
||||
if (this.handlers && !this._isPresigned(requestUrl)) {
|
||||
this.handlers.forEach((handler) => {
|
||||
handler.prepareRequest(info.options);
|
||||
});
|
||||
}
|
||||
return info;
|
||||
}
|
||||
_isPresigned(requestUrl) {
|
||||
if (this.requestOptions && this.requestOptions.presignedUrlPatterns) {
|
||||
const patterns = this.requestOptions.presignedUrlPatterns;
|
||||
for (let i = 0; i < patterns.length; i++) {
|
||||
if (requestUrl.match(patterns[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
_mergeHeaders(headers) {
|
||||
const lowercaseKeys = obj => Object.keys(obj).reduce((c, k) => (c[k.toLowerCase()] = obj[k], c), {});
|
||||
if (this.requestOptions && this.requestOptions.headers) {
|
||||
return Object.assign({}, lowercaseKeys(this.requestOptions.headers), lowercaseKeys(headers));
|
||||
}
|
||||
return lowercaseKeys(headers || {});
|
||||
}
|
||||
_getAgent(requestUrl) {
|
||||
let agent;
|
||||
let proxy = this._getProxy(requestUrl);
|
||||
let useProxy = proxy.proxyUrl && proxy.proxyUrl.hostname && !this._isBypassProxy(requestUrl);
|
||||
if (this._keepAlive && useProxy) {
|
||||
agent = this._proxyAgent;
|
||||
}
|
||||
if (this._keepAlive && !useProxy) {
|
||||
agent = this._agent;
|
||||
}
|
||||
// if agent is already assigned use that agent.
|
||||
if (!!agent) {
|
||||
return agent;
|
||||
}
|
||||
let parsedUrl = url.parse(requestUrl);
|
||||
const usingSsl = parsedUrl.protocol === 'https:';
|
||||
let maxSockets = 100;
|
||||
if (!!this.requestOptions) {
|
||||
maxSockets = this.requestOptions.maxSockets || http.globalAgent.maxSockets;
|
||||
}
|
||||
if (useProxy) {
|
||||
// If using proxy, need tunnel
|
||||
if (!tunnel) {
|
||||
tunnel = __webpack_require__(413);
|
||||
}
|
||||
const agentOptions = {
|
||||
maxSockets: maxSockets,
|
||||
keepAlive: this._keepAlive,
|
||||
proxy: {
|
||||
proxyAuth: proxy.proxyAuth,
|
||||
host: proxy.proxyUrl.hostname,
|
||||
port: proxy.proxyUrl.port
|
||||
},
|
||||
};
|
||||
let tunnelAgent;
|
||||
const overHttps = proxy.proxyUrl.protocol === 'https:';
|
||||
if (usingSsl) {
|
||||
tunnelAgent = overHttps ? tunnel.httpsOverHttps : tunnel.httpsOverHttp;
|
||||
}
|
||||
else {
|
||||
tunnelAgent = overHttps ? tunnel.httpOverHttps : tunnel.httpOverHttp;
|
||||
}
|
||||
agent = tunnelAgent(agentOptions);
|
||||
this._proxyAgent = agent;
|
||||
}
|
||||
// if reusing agent across request and tunneling agent isn't assigned create a new agent
|
||||
if (this._keepAlive && !agent) {
|
||||
const options = { keepAlive: this._keepAlive, maxSockets: maxSockets };
|
||||
agent = usingSsl ? new https.Agent(options) : new http.Agent(options);
|
||||
this._agent = agent;
|
||||
}
|
||||
// if not using private agent and tunnel agent isn't setup then use global agent
|
||||
if (!agent) {
|
||||
agent = usingSsl ? https.globalAgent : http.globalAgent;
|
||||
}
|
||||
if (usingSsl && this._ignoreSslError) {
|
||||
// we don't want to set NODE_TLS_REJECT_UNAUTHORIZED=0 since that will affect request for entire process
|
||||
// http.RequestOptions doesn't expose a way to modify RequestOptions.agent.options
|
||||
// we have to cast it to any and change it directly
|
||||
agent.options = Object.assign(agent.options || {}, { rejectUnauthorized: false });
|
||||
}
|
||||
if (usingSsl && this._certConfig) {
|
||||
agent.options = Object.assign(agent.options || {}, { ca: this._ca, cert: this._cert, key: this._key, passphrase: this._certConfig.passphrase });
|
||||
}
|
||||
return agent;
|
||||
}
|
||||
_getProxy(requestUrl) {
|
||||
const parsedUrl = url.parse(requestUrl);
|
||||
let usingSsl = parsedUrl.protocol === 'https:';
|
||||
let proxyConfig = this._httpProxy;
|
||||
// fallback to http_proxy and https_proxy env
|
||||
let https_proxy = process.env[EnvironmentVariables.HTTPS_PROXY];
|
||||
let http_proxy = process.env[EnvironmentVariables.HTTP_PROXY];
|
||||
if (!proxyConfig) {
|
||||
if (https_proxy && usingSsl) {
|
||||
proxyConfig = {
|
||||
proxyUrl: https_proxy
|
||||
};
|
||||
}
|
||||
else if (http_proxy) {
|
||||
proxyConfig = {
|
||||
proxyUrl: http_proxy
|
||||
};
|
||||
}
|
||||
}
|
||||
let proxyUrl;
|
||||
let proxyAuth;
|
||||
if (proxyConfig) {
|
||||
if (proxyConfig.proxyUrl.length > 0) {
|
||||
proxyUrl = url.parse(proxyConfig.proxyUrl);
|
||||
}
|
||||
if (proxyConfig.proxyUsername || proxyConfig.proxyPassword) {
|
||||
proxyAuth = proxyConfig.proxyUsername + ":" + proxyConfig.proxyPassword;
|
||||
}
|
||||
}
|
||||
return { proxyUrl: proxyUrl, proxyAuth: proxyAuth };
|
||||
}
|
||||
_isBypassProxy(requestUrl) {
|
||||
if (!this._httpProxyBypassHosts) {
|
||||
return false;
|
||||
}
|
||||
let bypass = false;
|
||||
this._httpProxyBypassHosts.forEach(bypassHost => {
|
||||
if (bypassHost.test(requestUrl)) {
|
||||
bypass = true;
|
||||
}
|
||||
});
|
||||
return bypass;
|
||||
}
|
||||
_performExponentialBackoff(retryNumber) {
|
||||
retryNumber = Math.min(ExponentialBackoffCeiling, retryNumber);
|
||||
const ms = ExponentialBackoffTimeSlice * Math.pow(2, retryNumber);
|
||||
return new Promise(resolve => setTimeout(() => resolve(), ms));
|
||||
}
|
||||
}
|
||||
exports.HttpClient = HttpClient;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 891:
|
||||
/***/ (function(module, exports) {
|
||||
|
||||
// Underscore.js 1.8.3
|
||||
// http://underscorejs.org
|
||||
// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
||||
// Underscore may be freely distributed under the MIT license.
|
||||
|
||||
(function() {
|
||||
|
||||
// Baseline setup
|
||||
// --------------
|
||||
|
||||
// Establish the root object, `window` in the browser, or `exports` on the server.
|
||||
var root = this;
|
||||
|
||||
// Save the previous value of the `_` variable.
|
||||
var previousUnderscore = root._;
|
||||
|
||||
// Save bytes in the minified (but not gzipped) version:
|
||||
var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
|
||||
|
||||
// Create quick reference variables for speed access to core prototypes.
|
||||
var
|
||||
push = ArrayProto.push,
|
||||
slice = ArrayProto.slice,
|
||||
toString = ObjProto.toString,
|
||||
hasOwnProperty = ObjProto.hasOwnProperty;
|
||||
|
||||
// All **ECMAScript 5** native function implementations that we hope to use
|
||||
// are declared here.
|
||||
var
|
||||
nativeIsArray = Array.isArray,
|
||||
nativeKeys = Object.keys,
|
||||
nativeBind = FuncProto.bind,
|
||||
nativeCreate = Object.create;
|
||||
|
||||
// Naked function reference for surrogate-prototype-swapping.
|
||||
var Ctor = function(){};
|
||||
|
||||
// Create a safe reference to the Underscore object for use below.
|
||||
var _ = function(obj) {
|
||||
if (obj instanceof _) return obj;
|
||||
if (!(this instanceof _)) return new _(obj);
|
||||
this._wrapped = obj;
|
||||
};
|
||||
|
||||
// Export the Underscore object for **Node.js**, with
|
||||
// backwards-compatibility for the old `require()` API. If we're in
|
||||
// the browser, add `_` as a global object.
|
||||
if (true) {
|
||||
if ( true && module.exports) {
|
||||
exports = module.exports = _;
|
||||
}
|
||||
exports._ = _;
|
||||
} else {}
|
||||
|
||||
// Current version.
|
||||
_.VERSION = '1.8.3';
|
||||
|
||||
// Internal function that returns an efficient (for current engines) version
|
||||
// of the passed-in callback, to be repeatedly applied in other Underscore
|
||||
// functions.
|
||||
var optimizeCb = function(func, context, argCount) {
|
||||
if (context === void 0) return func;
|
||||
switch (argCount == null ? 3 : argCount) {
|
||||
case 1: return function(value) {
|
||||
return func.call(context, value);
|
||||
};
|
||||
case 2: return function(value, other) {
|
||||
return func.call(context, value, other);
|
||||
};
|
||||
case 3: return function(value, index, collection) {
|
||||
return func.call(context, value, index, collection);
|
||||
};
|
||||
case 4: return function(accumulator, value, index, collection) {
|
||||
return func.call(context, accumulator, value, index, collection);
|
||||
};
|
||||
}
|
||||
return function() {
|
||||
return func.apply(context, arguments);
|
||||
};
|
||||
};
|
||||
|
||||
// A mostly-internal function to generate callbacks that can be applied
|
||||
// to each element in a collection, returning the desired result — either
|
||||
// identity, an arbitrary callback, a property matcher, or a property accessor.
|
||||
var cb = function(value, context, argCount) {
|
||||
if (value == null) return _.identity;
|
||||
if (_.isFunction(value)) return optimizeCb(value, context, argCount);
|
||||
if (_.isObject(value)) return _.matcher(value);
|
||||
return _.property(value);
|
||||
};
|
||||
_.iteratee = function(value, context) {
|
||||
return cb(value, context, Infinity);
|
||||
};
|
||||
|
||||
// An internal function for creating assigner functions.
|
||||
var createAssigner = function(keysFunc, undefinedOnly) {
|
||||
return function(obj) {
|
||||
var length = arguments.length;
|
||||
if (length < 2 || obj == null) return obj;
|
||||
for (var index = 1; index < length; index++) {
|
||||
var source = arguments[index],
|
||||
keys = keysFunc(source),
|
||||
l = keys.length;
|
||||
for (var i = 0; i < l; i++) {
|
||||
var key = keys[i];
|
||||
if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key];
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
};
|
||||
|
||||
// An internal function for creating a new object that inherits from another.
|
||||
var baseCreate = function(prototype) {
|
||||
if (!_.isObject(prototype)) return {};
|
||||
if (nativeCreate) return nativeCreate(prototype);
|
||||
Ctor.prototype = prototype;
|
||||
var result = new Ctor;
|
||||
Ctor.prototype = null;
|
||||
return result;
|
||||
};
|
||||
|
||||
var property = function(key) {
|
||||
return function(obj) {
|
||||
return obj == null ? void 0 : obj[key];
|
||||
};
|
||||
};
|
||||
|
||||
// Helper for collection methods to determine whether a collection
|
||||
// should be iterated as an array or as an object
|
||||
// Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
|
||||
// Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094
|
||||
var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;
|
||||
var getLength = property('length');
|
||||
var isArrayLike = function(collection) {
|
||||
var length = getLength(collection);
|
||||
return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;
|
||||
};
|
||||
|
||||
// Collection Functions
|
||||
// --------------------
|
||||
|
||||
// The cornerstone, an `each` implementation, aka `forEach`.
|
||||
// Handles raw objects in addition to array-likes. Treats all
|
||||
// sparse array-likes as if they were dense.
|
||||
_.each = _.forEach = function(obj, iteratee, context) {
|
||||
iteratee = optimizeCb(iteratee, context);
|
||||
var i, length;
|
||||
if (isArrayLike(obj)) {
|
||||
for (i = 0, length = obj.length; i < length; i++) {
|
||||
iteratee(obj[i], i, obj);
|
||||
}
|
||||
} else {
|
||||
var keys = _.keys(obj);
|
||||
for (i = 0, length = keys.length; i < length; i++) {
|
||||
iteratee(obj[keys[i]], keys[i], obj);
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
|
||||
// Return the results of applying the iteratee to each element.
|
||||
_.map = _.collect = function(obj, iteratee, context) {
|
||||
iteratee = cb(iteratee, context);
|
||||
var keys = !isArrayLike(obj) && _.keys(obj),
|
||||
length = (keys || obj).length,
|
||||
results = Array(length);
|
||||
for (var index = 0; index < length; index++) {
|
||||
var currentKey = keys ? keys[index] : index;
|
||||
results[index] = iteratee(obj[currentKey], currentKey, obj);
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
// Create a reducing function iterating left or right.
|
||||
function createReduce(dir) {
|
||||
// Optimized iterator function as using arguments.length
|
||||
// in the main function will deoptimize the, see #1991.
|
||||
function iterator(obj, iteratee, memo, keys, index, length) {
|
||||
for (; index >= 0 && index < length; index += dir) {
|
||||
var currentKey = keys ? keys[index] : index;
|
||||
memo = iteratee(memo, obj[currentKey], currentKey, obj);
|
||||
}
|
||||
return memo;
|
||||
}
|
||||
|
||||
return function(obj, iteratee, memo, context) {
|
||||
iteratee = optimizeCb(iteratee, context, 4);
|
||||
var keys = !isArrayLike(obj) && _.keys(obj),
|
||||
length = (keys || obj).length,
|
||||
index = dir > 0 ? 0 : length - 1;
|
||||
// Determine the initial value if none is provided.
|
||||
if (arguments.length < 3) {
|
||||
memo = obj[keys ? keys[index] : index];
|
||||
index += dir;
|
||||
}
|
||||
return iterator(obj, iteratee, memo, keys, index, length);
|
||||
};
|
||||
}
|
||||
|
||||
// **Reduce** builds up a single result from a list of values, aka `inject`,
|
||||
// or `foldl`.
|
||||
_.reduce = _.foldl = _.inject = createReduce(1);
|
||||
|
||||
// The right-associative version of reduce, also known as `foldr`.
|
||||
_.reduceRight = _.foldr = createReduce(-1);
|
||||
|
||||
// Return the first value which passes a truth test. Aliased as `detect`.
|
||||
_.find = _.detect = function(obj, predicate, context) {
|
||||
var key;
|
||||
if (isArrayLike(obj)) {
|
||||
key = _.findIndex(obj, predicate, context);
|
||||
} else {
|
||||
key = _.findKey(obj, predicate, context);
|
||||
}
|
||||
if (key !== void 0 && key !== -1) return obj[key];
|
||||
};
|
||||
|
||||
// Return all the elements that pass a truth test.
|
||||
// Aliased as `select`.
|
||||
_.filter = _.select = function(obj, predicate, context) {
|
||||
var results = [];
|
||||
predicate = cb(predicate, context);
|
||||
_.each(obj, function(value, index, list) {
|
||||
if (predicate(value, index, list)) results.push(value);
|
||||
});
|
||||
return results;
|
||||
};
|
||||
|
||||
// Return all the elements for which a truth test fails.
|
||||
_.reject = function(obj, predicate, context) {
|
||||
return _.filter(obj, _.negate(cb(predicate)), context);
|
||||
};
|
||||
|
||||
// Determine whether all of the elements match a truth test.
|
||||
// Aliased as `all`.
|
||||
_.every = _.all = function(obj, predicate, context) {
|
||||
predicate = cb(predicate, context);
|
||||
var keys = !isArrayLike(obj) && _.keys(obj),
|
||||
length = (keys || obj).length;
|
||||
for (var index = 0; index < length; index++) {
|
||||
var currentKey = keys ? keys[index] : index;
|
||||
if (!predicate(obj[currentKey], currentKey, obj)) return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
// Determine if at least one element in the object matches a truth test.
|
||||
// Aliased as `any`.
|
||||
_.some = _.any = function(obj, predicate, context) {
|
||||
predicate = cb(predicate, context);
|
||||
var keys = !isArrayLike(obj) && _.keys(obj),
|
||||
length = (keys || obj).length;
|
||||
for (var index = 0; index < length; index++) {
|
||||
var currentKey = keys ? keys[index] : index;
|
||||
if (predicate(obj[currentKey], currentKey, obj)) return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
// Determine if the array or object contains a given item (using `===`).
|
||||
// Aliased as `includes` and `include`.
|
||||
_.contains = _.includes = _.include = function(obj, item, fromIndex, guard) {
|
||||
if (!isArrayLike(obj)) obj = _.values(obj);
|
||||
if (typeof fromIndex != 'number' || guard) fromIndex = 0;
|
||||
return _.indexOf(obj, item, fromIndex) >= 0;
|
||||
};
|
||||
|
||||
// Invoke a method (with arguments) on every item in a collection.
|
||||
_.invoke = function(obj, method) {
|
||||
var args = slice.call(arguments, 2);
|
||||
var isFunc = _.isFunction(method);
|
||||
return _.map(obj, function(value) {
|
||||
var func = isFunc ? method : value[method];
|
||||
return func == null ? func : func.apply(value, args);
|
||||
});
|
||||
};
|
||||
|
||||
// Convenience version of a common use case of `map`: fetching a property.
|
||||
_.pluck = function(obj, key) {
|
||||
return _.map(obj, _.property(key));
|
||||
};
|
||||
|
||||
// Convenience version of a common use case of `filter`: selecting only objects
|
||||
// containing specific `key:value` pairs.
|
||||
_.where = function(obj, attrs) {
|
||||
return _.filter(obj, _.matcher(attrs));
|
||||
};
|
||||
|
||||
// Convenience version of a common use case of `find`: getting the first object
|
||||
// containing specific `key:value` pairs.
|
||||
_.findWhere = function(obj, attrs) {
|
||||
return _.find(obj, _.matcher(attrs));
|
||||
};
|
||||
|
||||
// Return the maximum element (or element-based computation).
|
||||
_.max = function(obj, iteratee, context) {
|
||||
var result = -Infinity, lastComputed = -Infinity,
|
||||
value, computed;
|
||||
if (iteratee == null && obj != null) {
|
||||
obj = isArrayLike(obj) ? obj : _.values(obj);
|
||||
for (var i = 0, length = obj.length; i < length; i++) {
|
||||
value = obj[i];
|
||||
if (value > result) {
|
||||
result = value;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
iteratee = cb(iteratee, context);
|
||||
_.each(obj, function(value, index, list) {
|
||||
computed = iteratee(value, index, list);
|
||||
if (computed > lastComputed || computed === -Infinity && result === -Infinity) {
|
||||
result = value;
|
||||
lastComputed = computed;
|
||||
}
|
||||
});
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
// Return the minimum element (or element-based computation).
|
||||
_.min = function(obj, iteratee, context) {
|
||||
var result = Infinity, lastComputed = Infinity,
|
||||
value, computed;
|
||||
if (iteratee == null && obj != null) {
|
||||
obj = isArrayLike(obj) ? obj : _.values(obj);
|
||||
for (var i = 0, length = obj.length; i < length; i++) {
|
||||
value = obj[i];
|
||||
if (value < result) {
|
||||
result = value;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
iteratee = cb(iteratee, context);
|
||||
_.each(obj, function(value, index, list) {
|
||||
computed = iteratee(value, index, list);
|
||||
if (computed < lastComputed || computed === Infinity && result === Infinity) {
|
||||
result = value;
|
||||
lastComputed = computed;
|
||||
}
|
||||
});
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
// Shuffle a collection, using the modern version of the
|
||||
// [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
|
||||
_.shuffle = function(obj) {
|
||||
var set = isArrayLike(obj) ? obj : _.values(obj);
|
||||
var length = set.length;
|
||||
var shuffled = Array(length);
|
||||
for (var index = 0, rand; index < length; index++) {
|
||||
rand = _.random(0, index);
|
||||
if (rand !== index) shuffled[index] = shuffled[rand];
|
||||
shuffled[rand] = set[index];
|
||||
}
|
||||
return shuffled;
|
||||
};
|
||||
|
||||
// Sample **n** random values from a collection.
|
||||
// If **n** is not specified, returns a single random element.
|
||||
// The internal `guard` argument allows it to work with `map`.
|
||||
_.sample = function(obj, n, guard) {
|
||||
if (n == null || guard) {
|
||||
if (!isArrayLike(obj)) obj = _.values(obj);
|
||||
return obj[_.random(obj.length - 1)];
|
||||
}
|
||||
return _.shuffle(obj).slice(0, Math.max(0, n));
|
||||
};
|
||||
|
||||
// Sort the object's values by a criterion produced by an iteratee.
|
||||
_.sortBy = function(obj, iteratee, context) {
|
||||
iteratee = cb(iteratee, context);
|
||||
return _.pluck(_.map(obj, function(value, index, list) {
|
||||
return {
|
||||
value: value,
|
||||
index: index,
|
||||
criteria: iteratee(value, index, list)
|
||||
};
|
||||
}).sort(function(left, right) {
|
||||
var a = left.criteria;
|
||||
var b = right.criteria;
|
||||
if (a !== b) {
|
||||
if (a > b || a === void 0) return 1;
|
||||
if (a < b || b === void 0) return -1;
|
||||
}
|
||||
return left.index - right.index;
|
||||
}), 'value');
|
||||
};
|
||||
|
||||
// An internal function used for aggregate "group by" operations.
|
||||
var group = function(behavior) {
|
||||
return function(obj, iteratee, context) {
|
||||
var result = {};
|
||||
iteratee = cb(iteratee, context);
|
||||
_.each(obj, function(value, index) {
|
||||
var key = iteratee(value, index, obj);
|
||||
behavior(result, value, key);
|
||||
});
|
||||
return result;
|
||||
};
|
||||
};
|
||||
|
||||
// Groups the object's values by a criterion. Pass either a string attribute
|
||||
// to group by, or a function that returns the criterion.
|
||||
_.groupBy = group(function(result, value, key) {
|
||||
if (_.has(result, key)) result[key].push(value); else result[key] = [value];
|
||||
});
|
||||
|
||||
// Indexes the object's values by a criterion, similar to `groupBy`, but for
|
||||
// when you know that your index values will be unique.
|
||||
_.indexBy = group(function(result, value, key) {
|
||||
result[key] = value;
|
||||
});
|
||||
|
||||
// Counts instances of an object that group by a certain criterion. Pass
|
||||
// either a string attribute to count by, or a function that returns the
|
||||
// criterion.
|
||||
_.countBy = group(function(result, value, key) {
|
||||
if (_.has(result, key)) result[key]++; else result[key] = 1;
|
||||
});
|
||||
|
||||
// Safely create a real, live array from anything iterable.
|
||||
_.toArray = function(obj) {
|
||||
if (!obj) return [];
|
||||
if (_.isArray(obj)) return slice.call(obj);
|
||||
if (isArrayLike(obj)) return _.map(obj, _.identity);
|
||||
return _.values(obj);
|
||||
};
|
||||
|
||||
// Return the number of elements in an object.
|
||||
_.size = function(obj) {
|
||||
if (obj == null) return 0;
|
||||
return isArrayLike(obj) ? obj.length : _.keys(obj).length;
|
||||
};
|
||||
|
||||
// Split a collection into two arrays: one whose elements all satisfy the given
|
||||
// predicate, and one whose elements all do not satisfy the predicate.
|
||||
_.partition = function(obj, predicate, context) {
|
||||
predicate = cb(predicate, context);
|
||||
var pass = [], fail = [];
|
||||
_.each(obj, function(value, key, obj) {
|
||||
(predicate(value, key, obj) ? pass : fail).push(value);
|
||||
});
|
||||
return [pass, fail];
|
||||
};
|
||||
|
||||
// Array Functions
|
||||
// ---------------
|
||||
|
||||
// Get the first element of an array. Passing **n** will return the first N
|
||||
// values in the array. Aliased as `head` and `take`. The **guard** check
|
||||
// allows it to work with `_.map`.
|
||||
_.first = _.head = _.take = function(array, n, guard) {
|
||||
if (array == null) return void 0;
|
||||
if (n == null || guard) return array[0];
|
||||
return _.initial(array, array.length - n);
|
||||
};
|
||||
|
||||
// Returns everything but the last entry of the array. Especially useful on
|
||||
// the arguments object. Passing **n** will return all the values in
|
||||
// the array, excluding the last N.
|
||||
_.initial = function(array, n, guard) {
|
||||
return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));
|
||||
};
|
||||
|
||||
// Get the last element of an array. Passing **n** will return the last N
|
||||
// values in the array.
|
||||
_.last = function(array, n, guard) {
|
||||
if (array == null) return void 0;
|
||||
if (n == null || guard) return array[array.length - 1];
|
||||
return _.rest(array, Math.max(0, array.length - n));
|
||||
};
|
||||
|
||||
// Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
|
||||
// Especially useful on the arguments object. Passing an **n** will return
|
||||
// the rest N values in the array.
|
||||
_.rest = _.tail = _.drop = function(array, n, guard) {
|
||||
return slice.call(array, n == null || guard ? 1 : n);
|
||||
};
|
||||
|
||||
// Trim out all falsy values from an array.
|
||||
_.compact = function(array) {
|
||||
return _.filter(array, _.identity);
|
||||
};
|
||||
|
||||
// Internal implementation of a recursive `flatten` function.
|
||||
var flatten = function(input, shallow, strict, startIndex) {
|
||||
var output = [], idx = 0;
|
||||
for (var i = startIndex || 0, length = getLength(input); i < length; i++) {
|
||||
var value = input[i];
|
||||
if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) {
|
||||
//flatten current level of array or arguments object
|
||||
if (!shallow) value = flatten(value, shallow, strict);
|
||||
var j = 0, len = value.length;
|
||||
output.length += len;
|
||||
while (j < len) {
|
||||
output[idx++] = value[j++];
|
||||
}
|
||||
} else if (!strict) {
|
||||
output[idx++] = value;
|
||||
}
|
||||
}
|
||||
return output;
|
||||
};
|
||||
|
||||
// Flatten out an array, either recursively (by default), or just one level.
|
||||
_.flatten = function(array, shallow) {
|
||||
return flatten(array, shallow, false);
|
||||
};
|
||||
|
||||
// Return a version of the array that does not contain the specified value(s).
|
||||
_.without = function(array) {
|
||||
return _.difference(array, slice.call(arguments, 1));
|
||||
};
|
||||
|
||||
// Produce a duplicate-free version of the array. If the array has already
|
||||
// been sorted, you have the option of using a faster algorithm.
|
||||
// Aliased as `unique`.
|
||||
_.uniq = _.unique = function(array, isSorted, iteratee, context) {
|
||||
if (!_.isBoolean(isSorted)) {
|
||||
context = iteratee;
|
||||
iteratee = isSorted;
|
||||
isSorted = false;
|
||||
}
|
||||
if (iteratee != null) iteratee = cb(iteratee, context);
|
||||
var result = [];
|
||||
var seen = [];
|
||||
for (var i = 0, length = getLength(array); i < length; i++) {
|
||||
var value = array[i],
|
||||
computed = iteratee ? iteratee(value, i, array) : value;
|
||||
if (isSorted) {
|
||||
if (!i || seen !== computed) result.push(value);
|
||||
seen = computed;
|
||||
} else if (iteratee) {
|
||||
if (!_.contains(seen, computed)) {
|
||||
seen.push(computed);
|
||||
result.push(value);
|
||||
}
|
||||
} else if (!_.contains(result, value)) {
|
||||
result.push(value);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
// Produce an array that contains the union: each distinct element from all of
|
||||
// the passed-in arrays.
|
||||
_.union = function() {
|
||||
return _.uniq(flatten(arguments, true, true));
|
||||
};
|
||||
|
||||
// Produce an array that contains every item shared between all the
|
||||
// passed-in arrays.
|
||||
_.intersection = function(array) {
|
||||
var result = [];
|
||||
var argsLength = arguments.length;
|
||||
for (var i = 0, length = getLength(array); i < length; i++) {
|
||||
var item = array[i];
|
||||
if (_.contains(result, item)) continue;
|
||||
for (var j = 1; j < argsLength; j++) {
|
||||
if (!_.contains(arguments[j], item)) break;
|
||||
}
|
||||
if (j === argsLength) result.push(item);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
// Take the difference between one array and a number of other arrays.
|
||||
// Only the elements present in just the first array will remain.
|
||||
_.difference = function(array) {
|
||||
var rest = flatten(arguments, true, true, 1);
|
||||
return _.filter(array, function(value){
|
||||
return !_.contains(rest, value);
|
||||
});
|
||||
};
|
||||
|
||||
// Zip together multiple lists into a single array -- elements that share
|
||||
// an index go together.
|
||||
_.zip = function() {
|
||||
return _.unzip(arguments);
|
||||
};
|
||||
|
||||
// Complement of _.zip. Unzip accepts an array of arrays and groups
|
||||
// each array's elements on shared indices
|
||||
_.unzip = function(array) {
|
||||
var length = array && _.max(array, getLength).length || 0;
|
||||
var result = Array(length);
|
||||
|
||||
for (var index = 0; index < length; index++) {
|
||||
result[index] = _.pluck(array, index);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
// Converts lists into objects. Pass either a single array of `[key, value]`
|
||||
// pairs, or two parallel arrays of the same length -- one of keys, and one of
|
||||
// the corresponding values.
|
||||
_.object = function(list, values) {
|
||||
var result = {};
|
||||
for (var i = 0, length = getLength(list); i < length; i++) {
|
||||
if (values) {
|
||||
result[list[i]] = values[i];
|
||||
} else {
|
||||
result[list[i][0]] = list[i][1];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
// Generator function to create the findIndex and findLastIndex functions
|
||||
function createPredicateIndexFinder(dir) {
|
||||
return function(array, predicate, context) {
|
||||
predicate = cb(predicate, context);
|
||||
var length = getLength(array);
|
||||
var index = dir > 0 ? 0 : length - 1;
|
||||
for (; index >= 0 && index < length; index += dir) {
|
||||
if (predicate(array[index], index, array)) return index;
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
}
|
||||
|
||||
// Returns the first index on an array-like that passes a predicate test
|
||||
_.findIndex = createPredicateIndexFinder(1);
|
||||
_.findLastIndex = createPredicateIndexFinder(-1);
|
||||
|
||||
// Use a comparator function to figure out the smallest index at which
|
||||
// an object should be inserted so as to maintain order. Uses binary search.
|
||||
_.sortedIndex = function(array, obj, iteratee, context) {
|
||||
iteratee = cb(iteratee, context, 1);
|
||||
var value = iteratee(obj);
|
||||
var low = 0, high = getLength(array);
|
||||
while (low < high) {
|
||||
var mid = Math.floor((low + high) / 2);
|
||||
if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;
|
||||
}
|
||||
return low;
|
||||
};
|
||||
|
||||
// Generator function to create the indexOf and lastIndexOf functions
|
||||
function createIndexFinder(dir, predicateFind, sortedIndex) {
|
||||
return function(array, item, idx) {
|
||||
var i = 0, length = getLength(array);
|
||||
if (typeof idx == 'number') {
|
||||
if (dir > 0) {
|
||||
i = idx >= 0 ? idx : Math.max(idx + length, i);
|
||||
} else {
|
||||
length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1;
|
||||
}
|
||||
} else if (sortedIndex && idx && length) {
|
||||
idx = sortedIndex(array, item);
|
||||
return array[idx] === item ? idx : -1;
|
||||
}
|
||||
if (item !== item) {
|
||||
idx = predicateFind(slice.call(array, i, length), _.isNaN);
|
||||
return idx >= 0 ? idx + i : -1;
|
||||
}
|
||||
for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) {
|
||||
if (array[idx] === item) return idx;
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
}
|
||||
|
||||
// Return the position of the first occurrence of an item in an array,
|
||||
// or -1 if the item is not included in the array.
|
||||
// If the array is large and already in sort order, pass `true`
|
||||
// for **isSorted** to use binary search.
|
||||
_.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex);
|
||||
_.lastIndexOf = createIndexFinder(-1, _.findLastIndex);
|
||||
|
||||
// Generate an integer Array containing an arithmetic progression. A port of
|
||||
// the native Python `range()` function. See
|
||||
// [the Python documentation](http://docs.python.org/library/functions.html#range).
|
||||
_.range = function(start, stop, step) {
|
||||
if (stop == null) {
|
||||
stop = start || 0;
|
||||
start = 0;
|
||||
}
|
||||
step = step || 1;
|
||||
|
||||
var length = Math.max(Math.ceil((stop - start) / step), 0);
|
||||
var range = Array(length);
|
||||
|
||||
for (var idx = 0; idx < length; idx++, start += step) {
|
||||
range[idx] = start;
|
||||
}
|
||||
|
||||
return range;
|
||||
};
|
||||
|
||||
// Function (ahem) Functions
|
||||
// ------------------
|
||||
|
||||
// Determines whether to execute a function as a constructor
|
||||
// or a normal function with the provided arguments
|
||||
var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) {
|
||||
if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);
|
||||
var self = baseCreate(sourceFunc.prototype);
|
||||
var result = sourceFunc.apply(self, args);
|
||||
if (_.isObject(result)) return result;
|
||||
return self;
|
||||
};
|
||||
|
||||
// Create a function bound to a given object (assigning `this`, and arguments,
|
||||
// optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
|
||||
// available.
|
||||
_.bind = function(func, context) {
|
||||
if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
|
||||
if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function');
|
||||
var args = slice.call(arguments, 2);
|
||||
var bound = function() {
|
||||
return executeBound(func, bound, context, this, args.concat(slice.call(arguments)));
|
||||
};
|
||||
return bound;
|
||||
};
|
||||
|
||||
// Partially apply a function by creating a version that has had some of its
|
||||
// arguments pre-filled, without changing its dynamic `this` context. _ acts
|
||||
// as a placeholder, allowing any combination of arguments to be pre-filled.
|
||||
_.partial = function(func) {
|
||||
var boundArgs = slice.call(arguments, 1);
|
||||
var bound = function() {
|
||||
var position = 0, length = boundArgs.length;
|
||||
var args = Array(length);
|
||||
for (var i = 0; i < length; i++) {
|
||||
args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i];
|
||||
}
|
||||
while (position < arguments.length) args.push(arguments[position++]);
|
||||
return executeBound(func, bound, this, this, args);
|
||||
};
|
||||
return bound;
|
||||
};
|
||||
|
||||
// Bind a number of an object's methods to that object. Remaining arguments
|
||||
// are the method names to be bound. Useful for ensuring that all callbacks
|
||||
// defined on an object belong to it.
|
||||
_.bindAll = function(obj) {
|
||||
var i, length = arguments.length, key;
|
||||
if (length <= 1) throw new Error('bindAll must be passed function names');
|
||||
for (i = 1; i < length; i++) {
|
||||
key = arguments[i];
|
||||
obj[key] = _.bind(obj[key], obj);
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
|
||||
// Memoize an expensive function by storing its results.
|
||||
_.memoize = function(func, hasher) {
|
||||
var memoize = function(key) {
|
||||
var cache = memoize.cache;
|
||||
var address = '' + (hasher ? hasher.apply(this, arguments) : key);
|
||||
if (!_.has(cache, address)) cache[address] = func.apply(this, arguments);
|
||||
return cache[address];
|
||||
};
|
||||
memoize.cache = {};
|
||||
return memoize;
|
||||
};
|
||||
|
||||
// Delays a function for the given number of milliseconds, and then calls
|
||||
// it with the arguments supplied.
|
||||
_.delay = function(func, wait) {
|
||||
var args = slice.call(arguments, 2);
|
||||
return setTimeout(function(){
|
||||
return func.apply(null, args);
|
||||
}, wait);
|
||||
};
|
||||
|
||||
// Defers a function, scheduling it to run after the current call stack has
|
||||
// cleared.
|
||||
_.defer = _.partial(_.delay, _, 1);
|
||||
|
||||
// Returns a function, that, when invoked, will only be triggered at most once
|
||||
// during a given window of time. Normally, the throttled function will run
|
||||
// as much as it can, without ever going more than once per `wait` duration;
|
||||
// but if you'd like to disable the execution on the leading edge, pass
|
||||
// `{leading: false}`. To disable execution on the trailing edge, ditto.
|
||||
_.throttle = function(func, wait, options) {
|
||||
var context, args, result;
|
||||
var timeout = null;
|
||||
var previous = 0;
|
||||
if (!options) options = {};
|
||||
var later = function() {
|
||||
previous = options.leading === false ? 0 : _.now();
|
||||
timeout = null;
|
||||
result = func.apply(context, args);
|
||||
if (!timeout) context = args = null;
|
||||
};
|
||||
return function() {
|
||||
var now = _.now();
|
||||
if (!previous && options.leading === false) previous = now;
|
||||
var remaining = wait - (now - previous);
|
||||
context = this;
|
||||
args = arguments;
|
||||
if (remaining <= 0 || remaining > wait) {
|
||||
if (timeout) {
|
||||
clearTimeout(timeout);
|
||||
timeout = null;
|
||||
}
|
||||
previous = now;
|
||||
result = func.apply(context, args);
|
||||
if (!timeout) context = args = null;
|
||||
} else if (!timeout && options.trailing !== false) {
|
||||
timeout = setTimeout(later, remaining);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
};
|
||||
|
||||
// Returns a function, that, as long as it continues to be invoked, will not
|
||||
// be triggered. The function will be called after it stops being called for
|
||||
// N milliseconds. If `immediate` is passed, trigger the function on the
|
||||
// leading edge, instead of the trailing.
|
||||
_.debounce = function(func, wait, immediate) {
|
||||
var timeout, args, context, timestamp, result;
|
||||
|
||||
var later = function() {
|
||||
var last = _.now() - timestamp;
|
||||
|
||||
if (last < wait && last >= 0) {
|
||||
timeout = setTimeout(later, wait - last);
|
||||
} else {
|
||||
timeout = null;
|
||||
if (!immediate) {
|
||||
result = func.apply(context, args);
|
||||
if (!timeout) context = args = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return function() {
|
||||
context = this;
|
||||
args = arguments;
|
||||
timestamp = _.now();
|
||||
var callNow = immediate && !timeout;
|
||||
if (!timeout) timeout = setTimeout(later, wait);
|
||||
if (callNow) {
|
||||
result = func.apply(context, args);
|
||||
context = args = null;
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
};
|
||||
|
||||
// Returns the first function passed as an argument to the second,
|
||||
// allowing you to adjust arguments, run code before and after, and
|
||||
// conditionally execute the original function.
|
||||
_.wrap = function(func, wrapper) {
|
||||
return _.partial(wrapper, func);
|
||||
};
|
||||
|
||||
// Returns a negated version of the passed-in predicate.
|
||||
_.negate = function(predicate) {
|
||||
return function() {
|
||||
return !predicate.apply(this, arguments);
|
||||
};
|
||||
};
|
||||
|
||||
// Returns a function that is the composition of a list of functions, each
|
||||
// consuming the return value of the function that follows.
|
||||
_.compose = function() {
|
||||
var args = arguments;
|
||||
var start = args.length - 1;
|
||||
return function() {
|
||||
var i = start;
|
||||
var result = args[start].apply(this, arguments);
|
||||
while (i--) result = args[i].call(this, result);
|
||||
return result;
|
||||
};
|
||||
};
|
||||
|
||||
// Returns a function that will only be executed on and after the Nth call.
|
||||
_.after = function(times, func) {
|
||||
return function() {
|
||||
if (--times < 1) {
|
||||
return func.apply(this, arguments);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Returns a function that will only be executed up to (but not including) the Nth call.
|
||||
_.before = function(times, func) {
|
||||
var memo;
|
||||
return function() {
|
||||
if (--times > 0) {
|
||||
memo = func.apply(this, arguments);
|
||||
}
|
||||
if (times <= 1) func = null;
|
||||
return memo;
|
||||
};
|
||||
};
|
||||
|
||||
// Returns a function that will be executed at most one time, no matter how
|
||||
// often you call it. Useful for lazy initialization.
|
||||
_.once = _.partial(_.before, 2);
|
||||
|
||||
// Object Functions
|
||||
// ----------------
|
||||
|
||||
// Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.
|
||||
var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString');
|
||||
var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
|
||||
'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];
|
||||
|
||||
function collectNonEnumProps(obj, keys) {
|
||||
var nonEnumIdx = nonEnumerableProps.length;
|
||||
var constructor = obj.constructor;
|
||||
var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto;
|
||||
|
||||
// Constructor is a special case.
|
||||
var prop = 'constructor';
|
||||
if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop);
|
||||
|
||||
while (nonEnumIdx--) {
|
||||
prop = nonEnumerableProps[nonEnumIdx];
|
||||
if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) {
|
||||
keys.push(prop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve the names of an object's own properties.
|
||||
// Delegates to **ECMAScript 5**'s native `Object.keys`
|
||||
_.keys = function(obj) {
|
||||
if (!_.isObject(obj)) return [];
|
||||
if (nativeKeys) return nativeKeys(obj);
|
||||
var keys = [];
|
||||
for (var key in obj) if (_.has(obj, key)) keys.push(key);
|
||||
// Ahem, IE < 9.
|
||||
if (hasEnumBug) collectNonEnumProps(obj, keys);
|
||||
return keys;
|
||||
};
|
||||
|
||||
// Retrieve all the property names of an object.
|
||||
_.allKeys = function(obj) {
|
||||
if (!_.isObject(obj)) return [];
|
||||
var keys = [];
|
||||
for (var key in obj) keys.push(key);
|
||||
// Ahem, IE < 9.
|
||||
if (hasEnumBug) collectNonEnumProps(obj, keys);
|
||||
return keys;
|
||||
};
|
||||
|
||||
// Retrieve the values of an object's properties.
|
||||
_.values = function(obj) {
|
||||
var keys = _.keys(obj);
|
||||
var length = keys.length;
|
||||
var values = Array(length);
|
||||
for (var i = 0; i < length; i++) {
|
||||
values[i] = obj[keys[i]];
|
||||
}
|
||||
return values;
|
||||
};
|
||||
|
||||
// Returns the results of applying the iteratee to each element of the object
|
||||
// In contrast to _.map it returns an object
|
||||
_.mapObject = function(obj, iteratee, context) {
|
||||
iteratee = cb(iteratee, context);
|
||||
var keys = _.keys(obj),
|
||||
length = keys.length,
|
||||
results = {},
|
||||
currentKey;
|
||||
for (var index = 0; index < length; index++) {
|
||||
currentKey = keys[index];
|
||||
results[currentKey] = iteratee(obj[currentKey], currentKey, obj);
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
// Convert an object into a list of `[key, value]` pairs.
|
||||
_.pairs = function(obj) {
|
||||
var keys = _.keys(obj);
|
||||
var length = keys.length;
|
||||
var pairs = Array(length);
|
||||
for (var i = 0; i < length; i++) {
|
||||
pairs[i] = [keys[i], obj[keys[i]]];
|
||||
}
|
||||
return pairs;
|
||||
};
|
||||
|
||||
// Invert the keys and values of an object. The values must be serializable.
|
||||
_.invert = function(obj) {
|
||||
var result = {};
|
||||
var keys = _.keys(obj);
|
||||
for (var i = 0, length = keys.length; i < length; i++) {
|
||||
result[obj[keys[i]]] = keys[i];
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
// Return a sorted list of the function names available on the object.
|
||||
// Aliased as `methods`
|
||||
_.functions = _.methods = function(obj) {
|
||||
var names = [];
|
||||
for (var key in obj) {
|
||||
if (_.isFunction(obj[key])) names.push(key);
|
||||
}
|
||||
return names.sort();
|
||||
};
|
||||
|
||||
// Extend a given object with all the properties in passed-in object(s).
|
||||
_.extend = createAssigner(_.allKeys);
|
||||
|
||||
// Assigns a given object with all the own properties in the passed-in object(s)
|
||||
// (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
|
||||
_.extendOwn = _.assign = createAssigner(_.keys);
|
||||
|
||||
// Returns the first key on an object that passes a predicate test
|
||||
_.findKey = function(obj, predicate, context) {
|
||||
predicate = cb(predicate, context);
|
||||
var keys = _.keys(obj), key;
|
||||
for (var i = 0, length = keys.length; i < length; i++) {
|
||||
key = keys[i];
|
||||
if (predicate(obj[key], key, obj)) return key;
|
||||
}
|
||||
};
|
||||
|
||||
// Return a copy of the object only containing the whitelisted properties.
|
||||
_.pick = function(object, oiteratee, context) {
|
||||
var result = {}, obj = object, iteratee, keys;
|
||||
if (obj == null) return result;
|
||||
if (_.isFunction(oiteratee)) {
|
||||
keys = _.allKeys(obj);
|
||||
iteratee = optimizeCb(oiteratee, context);
|
||||
} else {
|
||||
keys = flatten(arguments, false, false, 1);
|
||||
iteratee = function(value, key, obj) { return key in obj; };
|
||||
obj = Object(obj);
|
||||
}
|
||||
for (var i = 0, length = keys.length; i < length; i++) {
|
||||
var key = keys[i];
|
||||
var value = obj[key];
|
||||
if (iteratee(value, key, obj)) result[key] = value;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
// Return a copy of the object without the blacklisted properties.
|
||||
_.omit = function(obj, iteratee, context) {
|
||||
if (_.isFunction(iteratee)) {
|
||||
iteratee = _.negate(iteratee);
|
||||
} else {
|
||||
var keys = _.map(flatten(arguments, false, false, 1), String);
|
||||
iteratee = function(value, key) {
|
||||
return !_.contains(keys, key);
|
||||
};
|
||||
}
|
||||
return _.pick(obj, iteratee, context);
|
||||
};
|
||||
|
||||
// Fill in a given object with default properties.
|
||||
_.defaults = createAssigner(_.allKeys, true);
|
||||
|
||||
// Creates an object that inherits from the given prototype object.
|
||||
// If additional properties are provided then they will be added to the
|
||||
// created object.
|
||||
_.create = function(prototype, props) {
|
||||
var result = baseCreate(prototype);
|
||||
if (props) _.extendOwn(result, props);
|
||||
return result;
|
||||
};
|
||||
|
||||
// Create a (shallow-cloned) duplicate of an object.
|
||||
_.clone = function(obj) {
|
||||
if (!_.isObject(obj)) return obj;
|
||||
return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
|
||||
};
|
||||
|
||||
// Invokes interceptor with the obj, and then returns obj.
|
||||
// The primary purpose of this method is to "tap into" a method chain, in
|
||||
// order to perform operations on intermediate results within the chain.
|
||||
_.tap = function(obj, interceptor) {
|
||||
interceptor(obj);
|
||||
return obj;
|
||||
};
|
||||
|
||||
// Returns whether an object has a given set of `key:value` pairs.
|
||||
_.isMatch = function(object, attrs) {
|
||||
var keys = _.keys(attrs), length = keys.length;
|
||||
if (object == null) return !length;
|
||||
var obj = Object(object);
|
||||
for (var i = 0; i < length; i++) {
|
||||
var key = keys[i];
|
||||
if (attrs[key] !== obj[key] || !(key in obj)) return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
// Internal recursive comparison function for `isEqual`.
|
||||
var eq = function(a, b, aStack, bStack) {
|
||||
// Identical objects are equal. `0 === -0`, but they aren't identical.
|
||||
// See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
|
||||
if (a === b) return a !== 0 || 1 / a === 1 / b;
|
||||
// A strict comparison is necessary because `null == undefined`.
|
||||
if (a == null || b == null) return a === b;
|
||||
// Unwrap any wrapped objects.
|
||||
if (a instanceof _) a = a._wrapped;
|
||||
if (b instanceof _) b = b._wrapped;
|
||||
// Compare `[[Class]]` names.
|
||||
var className = toString.call(a);
|
||||
if (className !== toString.call(b)) return false;
|
||||
switch (className) {
|
||||
// Strings, numbers, regular expressions, dates, and booleans are compared by value.
|
||||
case '[object RegExp]':
|
||||
// RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
|
||||
case '[object String]':
|
||||
// Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
|
||||
// equivalent to `new String("5")`.
|
||||
return '' + a === '' + b;
|
||||
case '[object Number]':
|
||||
// `NaN`s are equivalent, but non-reflexive.
|
||||
// Object(NaN) is equivalent to NaN
|
||||
if (+a !== +a) return +b !== +b;
|
||||
// An `egal` comparison is performed for other numeric values.
|
||||
return +a === 0 ? 1 / +a === 1 / b : +a === +b;
|
||||
case '[object Date]':
|
||||
case '[object Boolean]':
|
||||
// Coerce dates and booleans to numeric primitive values. Dates are compared by their
|
||||
// millisecond representations. Note that invalid dates with millisecond representations
|
||||
// of `NaN` are not equivalent.
|
||||
return +a === +b;
|
||||
}
|
||||
|
||||
var areArrays = className === '[object Array]';
|
||||
if (!areArrays) {
|
||||
if (typeof a != 'object' || typeof b != 'object') return false;
|
||||
|
||||
// Objects with different constructors are not equivalent, but `Object`s or `Array`s
|
||||
// from different frames are.
|
||||
var aCtor = a.constructor, bCtor = b.constructor;
|
||||
if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor &&
|
||||
_.isFunction(bCtor) && bCtor instanceof bCtor)
|
||||
&& ('constructor' in a && 'constructor' in b)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Assume equality for cyclic structures. The algorithm for detecting cyclic
|
||||
// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
|
||||
|
||||
// Initializing stack of traversed objects.
|
||||
// It's done here since we only need them for objects and arrays comparison.
|
||||
aStack = aStack || [];
|
||||
bStack = bStack || [];
|
||||
var length = aStack.length;
|
||||
while (length--) {
|
||||
// Linear search. Performance is inversely proportional to the number of
|
||||
// unique nested structures.
|
||||
if (aStack[length] === a) return bStack[length] === b;
|
||||
}
|
||||
|
||||
// Add the first object to the stack of traversed objects.
|
||||
aStack.push(a);
|
||||
bStack.push(b);
|
||||
|
||||
// Recursively compare objects and arrays.
|
||||
if (areArrays) {
|
||||
// Compare array lengths to determine if a deep comparison is necessary.
|
||||
length = a.length;
|
||||
if (length !== b.length) return false;
|
||||
// Deep compare the contents, ignoring non-numeric properties.
|
||||
while (length--) {
|
||||
if (!eq(a[length], b[length], aStack, bStack)) return false;
|
||||
}
|
||||
} else {
|
||||
// Deep compare objects.
|
||||
var keys = _.keys(a), key;
|
||||
length = keys.length;
|
||||
// Ensure that both objects contain the same number of properties before comparing deep equality.
|
||||
if (_.keys(b).length !== length) return false;
|
||||
while (length--) {
|
||||
// Deep compare each member
|
||||
key = keys[length];
|
||||
if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false;
|
||||
}
|
||||
}
|
||||
// Remove the first object from the stack of traversed objects.
|
||||
aStack.pop();
|
||||
bStack.pop();
|
||||
return true;
|
||||
};
|
||||
|
||||
// Perform a deep comparison to check if two objects are equal.
|
||||
_.isEqual = function(a, b) {
|
||||
return eq(a, b);
|
||||
};
|
||||
|
||||
// Is a given array, string, or object empty?
|
||||
// An "empty" object has no enumerable own-properties.
|
||||
_.isEmpty = function(obj) {
|
||||
if (obj == null) return true;
|
||||
if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0;
|
||||
return _.keys(obj).length === 0;
|
||||
};
|
||||
|
||||
// Is a given value a DOM element?
|
||||
_.isElement = function(obj) {
|
||||
return !!(obj && obj.nodeType === 1);
|
||||
};
|
||||
|
||||
// Is a given value an array?
|
||||
// Delegates to ECMA5's native Array.isArray
|
||||
_.isArray = nativeIsArray || function(obj) {
|
||||
return toString.call(obj) === '[object Array]';
|
||||
};
|
||||
|
||||
// Is a given variable an object?
|
||||
_.isObject = function(obj) {
|
||||
var type = typeof obj;
|
||||
return type === 'function' || type === 'object' && !!obj;
|
||||
};
|
||||
|
||||
// Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError.
|
||||
_.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) {
|
||||
_['is' + name] = function(obj) {
|
||||
return toString.call(obj) === '[object ' + name + ']';
|
||||
};
|
||||
});
|
||||
|
||||
// Define a fallback version of the method in browsers (ahem, IE < 9), where
|
||||
// there isn't any inspectable "Arguments" type.
|
||||
if (!_.isArguments(arguments)) {
|
||||
_.isArguments = function(obj) {
|
||||
return _.has(obj, 'callee');
|
||||
};
|
||||
}
|
||||
|
||||
// Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8,
|
||||
// IE 11 (#1621), and in Safari 8 (#1929).
|
||||
if ( true && typeof Int8Array != 'object') {
|
||||
_.isFunction = function(obj) {
|
||||
return typeof obj == 'function' || false;
|
||||
};
|
||||
}
|
||||
|
||||
// Is a given object a finite number?
|
||||
_.isFinite = function(obj) {
|
||||
return isFinite(obj) && !isNaN(parseFloat(obj));
|
||||
};
|
||||
|
||||
// Is the given value `NaN`? (NaN is the only number which does not equal itself).
|
||||
_.isNaN = function(obj) {
|
||||
return _.isNumber(obj) && obj !== +obj;
|
||||
};
|
||||
|
||||
// Is a given value a boolean?
|
||||
_.isBoolean = function(obj) {
|
||||
return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
|
||||
};
|
||||
|
||||
// Is a given value equal to null?
|
||||
_.isNull = function(obj) {
|
||||
return obj === null;
|
||||
};
|
||||
|
||||
// Is a given variable undefined?
|
||||
_.isUndefined = function(obj) {
|
||||
return obj === void 0;
|
||||
};
|
||||
|
||||
// Shortcut function for checking if an object has a given property directly
|
||||
// on itself (in other words, not on a prototype).
|
||||
_.has = function(obj, key) {
|
||||
return obj != null && hasOwnProperty.call(obj, key);
|
||||
};
|
||||
|
||||
// Utility Functions
|
||||
// -----------------
|
||||
|
||||
// Run Underscore.js in *noConflict* mode, returning the `_` variable to its
|
||||
// previous owner. Returns a reference to the Underscore object.
|
||||
_.noConflict = function() {
|
||||
root._ = previousUnderscore;
|
||||
return this;
|
||||
};
|
||||
|
||||
// Keep the identity function around for default iteratees.
|
||||
_.identity = function(value) {
|
||||
return value;
|
||||
};
|
||||
|
||||
// Predicate-generating functions. Often useful outside of Underscore.
|
||||
_.constant = function(value) {
|
||||
return function() {
|
||||
return value;
|
||||
};
|
||||
};
|
||||
|
||||
_.noop = function(){};
|
||||
|
||||
_.property = property;
|
||||
|
||||
// Generates a function for a given object that returns a given property.
|
||||
_.propertyOf = function(obj) {
|
||||
return obj == null ? function(){} : function(key) {
|
||||
return obj[key];
|
||||
};
|
||||
};
|
||||
|
||||
// Returns a predicate for checking whether an object has a given set of
|
||||
// `key:value` pairs.
|
||||
_.matcher = _.matches = function(attrs) {
|
||||
attrs = _.extendOwn({}, attrs);
|
||||
return function(obj) {
|
||||
return _.isMatch(obj, attrs);
|
||||
};
|
||||
};
|
||||
|
||||
// Run a function **n** times.
|
||||
_.times = function(n, iteratee, context) {
|
||||
var accum = Array(Math.max(0, n));
|
||||
iteratee = optimizeCb(iteratee, context, 1);
|
||||
for (var i = 0; i < n; i++) accum[i] = iteratee(i);
|
||||
return accum;
|
||||
};
|
||||
|
||||
// Return a random integer between min and max (inclusive).
|
||||
_.random = function(min, max) {
|
||||
if (max == null) {
|
||||
max = min;
|
||||
min = 0;
|
||||
}
|
||||
return min + Math.floor(Math.random() * (max - min + 1));
|
||||
};
|
||||
|
||||
// A (possibly faster) way to get the current timestamp as an integer.
|
||||
_.now = Date.now || function() {
|
||||
return new Date().getTime();
|
||||
};
|
||||
|
||||
// List of HTML entities for escaping.
|
||||
var escapeMap = {
|
||||
'&': '&',
|
||||
'<': '<',
|
||||
'>': '>',
|
||||
'"': '"',
|
||||
"'": ''',
|
||||
'`': '`'
|
||||
};
|
||||
var unescapeMap = _.invert(escapeMap);
|
||||
|
||||
// Functions for escaping and unescaping strings to/from HTML interpolation.
|
||||
var createEscaper = function(map) {
|
||||
var escaper = function(match) {
|
||||
return map[match];
|
||||
};
|
||||
// Regexes for identifying a key that needs to be escaped
|
||||
var source = '(?:' + _.keys(map).join('|') + ')';
|
||||
var testRegexp = RegExp(source);
|
||||
var replaceRegexp = RegExp(source, 'g');
|
||||
return function(string) {
|
||||
string = string == null ? '' : '' + string;
|
||||
return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;
|
||||
};
|
||||
};
|
||||
_.escape = createEscaper(escapeMap);
|
||||
_.unescape = createEscaper(unescapeMap);
|
||||
|
||||
// If the value of the named `property` is a function then invoke it with the
|
||||
// `object` as context; otherwise, return it.
|
||||
_.result = function(object, property, fallback) {
|
||||
var value = object == null ? void 0 : object[property];
|
||||
if (value === void 0) {
|
||||
value = fallback;
|
||||
}
|
||||
return _.isFunction(value) ? value.call(object) : value;
|
||||
};
|
||||
|
||||
// Generate a unique integer id (unique within the entire client session).
|
||||
// Useful for temporary DOM ids.
|
||||
var idCounter = 0;
|
||||
_.uniqueId = function(prefix) {
|
||||
var id = ++idCounter + '';
|
||||
return prefix ? prefix + id : id;
|
||||
};
|
||||
|
||||
// By default, Underscore uses ERB-style template delimiters, change the
|
||||
// following template settings to use alternative delimiters.
|
||||
_.templateSettings = {
|
||||
evaluate : /<%([\s\S]+?)%>/g,
|
||||
interpolate : /<%=([\s\S]+?)%>/g,
|
||||
escape : /<%-([\s\S]+?)%>/g
|
||||
};
|
||||
|
||||
// When customizing `templateSettings`, if you don't want to define an
|
||||
// interpolation, evaluation or escaping regex, we need one that is
|
||||
// guaranteed not to match.
|
||||
var noMatch = /(.)^/;
|
||||
|
||||
// Certain characters need to be escaped so that they can be put into a
|
||||
// string literal.
|
||||
var escapes = {
|
||||
"'": "'",
|
||||
'\\': '\\',
|
||||
'\r': 'r',
|
||||
'\n': 'n',
|
||||
'\u2028': 'u2028',
|
||||
'\u2029': 'u2029'
|
||||
};
|
||||
|
||||
var escaper = /\\|'|\r|\n|\u2028|\u2029/g;
|
||||
|
||||
var escapeChar = function(match) {
|
||||
return '\\' + escapes[match];
|
||||
};
|
||||
|
||||
// JavaScript micro-templating, similar to John Resig's implementation.
|
||||
// Underscore templating handles arbitrary delimiters, preserves whitespace,
|
||||
// and correctly escapes quotes within interpolated code.
|
||||
// NB: `oldSettings` only exists for backwards compatibility.
|
||||
_.template = function(text, settings, oldSettings) {
|
||||
if (!settings && oldSettings) settings = oldSettings;
|
||||
settings = _.defaults({}, settings, _.templateSettings);
|
||||
|
||||
// Combine delimiters into one regular expression via alternation.
|
||||
var matcher = RegExp([
|
||||
(settings.escape || noMatch).source,
|
||||
(settings.interpolate || noMatch).source,
|
||||
(settings.evaluate || noMatch).source
|
||||
].join('|') + '|$', 'g');
|
||||
|
||||
// Compile the template source, escaping string literals appropriately.
|
||||
var index = 0;
|
||||
var source = "__p+='";
|
||||
text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
|
||||
source += text.slice(index, offset).replace(escaper, escapeChar);
|
||||
index = offset + match.length;
|
||||
|
||||
if (escape) {
|
||||
source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
|
||||
} else if (interpolate) {
|
||||
source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
|
||||
} else if (evaluate) {
|
||||
source += "';\n" + evaluate + "\n__p+='";
|
||||
}
|
||||
|
||||
// Adobe VMs need the match returned to produce the correct offest.
|
||||
return match;
|
||||
});
|
||||
source += "';\n";
|
||||
|
||||
// If a variable is not specified, place data values in local scope.
|
||||
if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
|
||||
|
||||
source = "var __t,__p='',__j=Array.prototype.join," +
|
||||
"print=function(){__p+=__j.call(arguments,'');};\n" +
|
||||
source + 'return __p;\n';
|
||||
|
||||
try {
|
||||
var render = new Function(settings.variable || 'obj', '_', source);
|
||||
} catch (e) {
|
||||
e.source = source;
|
||||
throw e;
|
||||
}
|
||||
|
||||
var template = function(data) {
|
||||
return render.call(this, data, _);
|
||||
};
|
||||
|
||||
// Provide the compiled source as a convenience for precompilation.
|
||||
var argument = settings.variable || 'obj';
|
||||
template.source = 'function(' + argument + '){\n' + source + '}';
|
||||
|
||||
return template;
|
||||
};
|
||||
|
||||
// Add a "chain" function. Start chaining a wrapped Underscore object.
|
||||
_.chain = function(obj) {
|
||||
var instance = _(obj);
|
||||
instance._chain = true;
|
||||
return instance;
|
||||
};
|
||||
|
||||
// OOP
|
||||
// ---------------
|
||||
// If Underscore is called as a function, it returns a wrapped object that
|
||||
// can be used OO-style. This wrapper holds altered versions of all the
|
||||
// underscore functions. Wrapped objects may be chained.
|
||||
|
||||
// Helper function to continue chaining intermediate results.
|
||||
var result = function(instance, obj) {
|
||||
return instance._chain ? _(obj).chain() : obj;
|
||||
};
|
||||
|
||||
// Add your own custom functions to the Underscore object.
|
||||
_.mixin = function(obj) {
|
||||
_.each(_.functions(obj), function(name) {
|
||||
var func = _[name] = obj[name];
|
||||
_.prototype[name] = function() {
|
||||
var args = [this._wrapped];
|
||||
push.apply(args, arguments);
|
||||
return result(this, func.apply(_, args));
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
// Add all of the Underscore functions to the wrapper object.
|
||||
_.mixin(_);
|
||||
|
||||
// Add all mutator Array functions to the wrapper.
|
||||
_.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
|
||||
var method = ArrayProto[name];
|
||||
_.prototype[name] = function() {
|
||||
var obj = this._wrapped;
|
||||
method.apply(obj, arguments);
|
||||
if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0];
|
||||
return result(this, obj);
|
||||
};
|
||||
});
|
||||
|
||||
// Add all accessor Array functions to the wrapper.
|
||||
_.each(['concat', 'join', 'slice'], function(name) {
|
||||
var method = ArrayProto[name];
|
||||
_.prototype[name] = function() {
|
||||
return result(this, method.apply(this._wrapped, arguments));
|
||||
};
|
||||
});
|
||||
|
||||
// Extracts the result from a wrapped and chained object.
|
||||
_.prototype.value = function() {
|
||||
return this._wrapped;
|
||||
};
|
||||
|
||||
// Provide unwrapping proxy for some methods used in engine operations
|
||||
// such as arithmetic and JSON stringification.
|
||||
_.prototype.valueOf = _.prototype.toJSON = _.prototype.value;
|
||||
|
||||
_.prototype.toString = function() {
|
||||
return '' + this._wrapped;
|
||||
};
|
||||
|
||||
// AMD registration happens at the end for compatibility with AMD loaders
|
||||
// that may not enforce next-turn semantics on modules. Even though general
|
||||
// practice for AMD registration is to be anonymous, underscore registers
|
||||
// as a named module because, like jQuery, it is a base library that is
|
||||
// popular enough to be bundled in a third party lib, but not be part of
|
||||
// an AMD load request. Those cases could generate an error when an
|
||||
// anonymous define() is called outside of a loader request.
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define('underscore', [], function() {
|
||||
return _;
|
||||
});
|
||||
}
|
||||
}.call(this));
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 941:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var basiccreds_1 = __webpack_require__(12);
|
||||
exports.BasicCredentialHandler = basiccreds_1.BasicCredentialHandler;
|
||||
var bearertoken_1 = __webpack_require__(571);
|
||||
exports.BearerCredentialHandler = bearertoken_1.BearerCredentialHandler;
|
||||
var ntlm_1 = __webpack_require__(525);
|
||||
exports.NtlmCredentialHandler = ntlm_1.NtlmCredentialHandler;
|
||||
var personalaccesstoken_1 = __webpack_require__(327);
|
||||
exports.PersonalAccessTokenCredentialHandler = personalaccesstoken_1.PersonalAccessTokenCredentialHandler;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 943:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
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 __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 exec_1 = __webpack_require__(986);
|
||||
const io = __importStar(__webpack_require__(1));
|
||||
const fs_1 = __webpack_require__(747);
|
||||
function getTarPath() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
// Explicitly use BSD Tar on Windows
|
||||
const IS_WINDOWS = process.platform === "win32";
|
||||
if (IS_WINDOWS) {
|
||||
const systemTar = `${process.env["windir"]}\\System32\\tar.exe`;
|
||||
if (fs_1.existsSync(systemTar)) {
|
||||
return systemTar;
|
||||
}
|
||||
}
|
||||
return yield io.which("tar", true);
|
||||
});
|
||||
}
|
||||
function execTar(args) {
|
||||
var _a, _b;
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
const tarPath = yield getTarPath();
|
||||
const tarExec = process.platform !== "win32" ? `sudo ${tarPath}` : tarPath;
|
||||
yield exec_1.exec(`"${tarExec}"`, args);
|
||||
}
|
||||
catch (error) {
|
||||
const IS_WINDOWS = process.platform === "win32";
|
||||
if (IS_WINDOWS) {
|
||||
throw new Error(`Tar failed with error: ${(_a = error) === null || _a === void 0 ? void 0 : _a.message}. Ensure BSD tar is installed and on the PATH.`);
|
||||
}
|
||||
throw new Error(`Tar failed with error: ${(_b = error) === null || _b === void 0 ? void 0 : _b.message}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
function extractTar(archivePath, targetDirectory) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
// Create directory to extract tar into
|
||||
yield io.mkdirP(targetDirectory);
|
||||
const args = ["-xz", "-f", archivePath, "-C", targetDirectory];
|
||||
yield execTar(args);
|
||||
});
|
||||
}
|
||||
exports.extractTar = extractTar;
|
||||
function createTar(archivePath, sourceDirectory) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const args = ["-cz", "-f", archivePath, "-C", sourceDirectory, "."];
|
||||
yield execTar(args);
|
||||
});
|
||||
}
|
||||
exports.createTar = createTar;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 986:
|
||||
/***/ (function(__unusedmodule, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
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());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const tr = __webpack_require__(9);
|
||||
/**
|
||||
* Exec a command.
|
||||
* Output will be streamed to the live console.
|
||||
* Returns promise with return code
|
||||
*
|
||||
* @param commandLine command to execute (can include additional args). Must be correctly escaped.
|
||||
* @param args optional arguments for tool. Escaping is handled by the lib.
|
||||
* @param options optional exec options. See ExecOptions
|
||||
* @returns Promise<number> exit code
|
||||
*/
|
||||
function exec(commandLine, args, options) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const commandArgs = tr.argStringToArray(commandLine);
|
||||
if (commandArgs.length === 0) {
|
||||
throw new Error(`Parameter 'commandLine' cannot be null or empty.`);
|
||||
}
|
||||
// Path to tool to execute should be first arg
|
||||
const toolPath = commandArgs[0];
|
||||
args = commandArgs.slice(1).concat(args || []);
|
||||
const runner = new tr.ToolRunner(toolPath, args, options);
|
||||
return runner.exec();
|
||||
});
|
||||
}
|
||||
exports.exec = exec;
|
||||
//# sourceMappingURL=exec.js.map
|
||||
|
||||
/***/ })
|
||||
|
||||
/******/ });
|
||||
@ -16,7 +16,9 @@ async function getTarPath(): Promise<string> {
|
||||
|
||||
async function execTar(args: string[]): Promise<void> {
|
||||
try {
|
||||
await exec(`"${await getTarPath()}"`, args);
|
||||
const tarPath = await getTarPath();
|
||||
const tarExec = process.platform !== "win32" ? `sudo ${tarPath}` : tarPath;
|
||||
await exec(`"${tarExec}"`, args);
|
||||
} catch (error) {
|
||||
const IS_WINDOWS = process.platform === "win32";
|
||||
if (IS_WINDOWS) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user