MOBILE-3501 gulp: Support uploading patches to Jira
parent
719ffa2ff1
commit
05fa577577
33
gulp/git.js
33
gulp/git.js
|
@ -13,6 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
const exec = require('child_process').exec;
|
const exec = require('child_process').exec;
|
||||||
|
const fs = require('fs');
|
||||||
const DevConfig = require('./dev-config');
|
const DevConfig = require('./dev-config');
|
||||||
const Utils = require('./utils');
|
const Utils = require('./utils');
|
||||||
|
|
||||||
|
@ -21,6 +22,38 @@ const Utils = require('./utils');
|
||||||
*/
|
*/
|
||||||
class Git {
|
class Git {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a patch.
|
||||||
|
*
|
||||||
|
* @param range Show only commits in the specified revision range.
|
||||||
|
* @param saveTo Path to the file to save the patch to. If not defined, the patch contents will be returned.
|
||||||
|
* @return Promise resolved when done. If saveTo not provided, it will return the patch contents.
|
||||||
|
*/
|
||||||
|
createPatch(range, saveTo) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
exec(`git format-patch ${range} --stdout`, (err, result) => {
|
||||||
|
if (err) {
|
||||||
|
reject(err || 'Cannot create patch.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!saveTo) {
|
||||||
|
resolve(result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save it to a file.
|
||||||
|
const directory = saveTo.substring(0, saveTo.lastIndexOf('/'));
|
||||||
|
if (directory && directory != '.' && directory != '..' && !fs.existsSync(directory)) {
|
||||||
|
fs.mkdirSync(directory);
|
||||||
|
}
|
||||||
|
fs.writeFileSync(saveTo, result);
|
||||||
|
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get current branch.
|
* Get current branch.
|
||||||
*
|
*
|
||||||
|
|
128
gulp/jira.js
128
gulp/jira.js
|
@ -16,6 +16,8 @@ const exec = require('child_process').exec;
|
||||||
const https = require('https');
|
const https = require('https');
|
||||||
const keytar = require('keytar');
|
const keytar = require('keytar');
|
||||||
const inquirer = require('inquirer');
|
const inquirer = require('inquirer');
|
||||||
|
const fs = require('fs');
|
||||||
|
const request = require('request'); // This lib is deprecated, but it was the only way I found to make upload files work.
|
||||||
const DevConfig = require('./dev-config');
|
const DevConfig = require('./dev-config');
|
||||||
const Git = require('./git');
|
const Git = require('./git');
|
||||||
const Url = require('./url');
|
const Url = require('./url');
|
||||||
|
@ -73,6 +75,30 @@ class Jira {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build URL to perform requests to Jira.
|
||||||
|
*
|
||||||
|
* @param uri URI to add the the Jira URL.
|
||||||
|
* @return URL.
|
||||||
|
*/
|
||||||
|
buildRequestUrl(uri) {
|
||||||
|
return Utils.concatenatePaths([this.url, this.uri, '/rest/api/', apiVersion, uri]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete an attachment.
|
||||||
|
*
|
||||||
|
* @param attachmentId Attachment ID.
|
||||||
|
* @return Promise resolved when done.
|
||||||
|
*/
|
||||||
|
async deleteAttachment(attachmentId) {
|
||||||
|
const response = await this.request(`attachment/${attachmentId}`, 'DELETE');
|
||||||
|
|
||||||
|
if (response.status != 204) {
|
||||||
|
throw new Error('Could not delete the attachment');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load the issue info from jira server using a REST API call.
|
* Load the issue info from jira server using a REST API call.
|
||||||
*
|
*
|
||||||
|
@ -248,6 +274,18 @@ class Jira {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a certain issue could be a security issue.
|
||||||
|
*
|
||||||
|
* @param key Key to identify the issue. E.g. MOBILE-1234.
|
||||||
|
* @return Promise resolved with boolean: whether it's a security issue.
|
||||||
|
*/
|
||||||
|
async isSecurityIssue(key) {
|
||||||
|
const issue = await this.getIssue(key, 'security');
|
||||||
|
|
||||||
|
return issue.fields && !!issue.fields.security;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a request to the server and returns the data.
|
* Sends a request to the server and returns the data.
|
||||||
*
|
*
|
||||||
|
@ -269,16 +307,23 @@ class Jira {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|
||||||
// Build the request URL.
|
// Build the request URL.
|
||||||
let url = Utils.concatenatePaths([this.url, this.uri, '/rest/api/', apiVersion, uri]);
|
const url = Url.addParamsToUrl(this.buildRequestUrl(uri), params);
|
||||||
url = Url.addParamsToUrl(url, params);
|
|
||||||
|
|
||||||
// Perform the request.
|
// Initialize the request.
|
||||||
const options = {
|
const options = {
|
||||||
method: method,
|
method: method,
|
||||||
auth: `${this.username}:${this.password}`,
|
auth: `${this.username}:${this.password}`,
|
||||||
headers: headers,
|
headers: headers,
|
||||||
};
|
};
|
||||||
const request = https.request(url, options, (response) => {
|
const request = https.request(url, options);
|
||||||
|
|
||||||
|
// Add data.
|
||||||
|
if (data) {
|
||||||
|
request.write(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Treat response.
|
||||||
|
request.on('response', (response) => {
|
||||||
// Read the result.
|
// Read the result.
|
||||||
let result = '';
|
let result = '';
|
||||||
response.on('data', (chunk) => {
|
response.on('data', (chunk) => {
|
||||||
|
@ -302,11 +347,7 @@ class Jira {
|
||||||
reject(e);
|
reject(e);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Send data.
|
// Send the request.
|
||||||
if (data) {
|
|
||||||
request.write(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
request.end();
|
request.end();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -359,6 +400,75 @@ class Jira {
|
||||||
|
|
||||||
console.log('Issue updated successfully.');
|
console.log('Issue updated successfully.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upload a new attachment to an issue.
|
||||||
|
*
|
||||||
|
* @param key Key to identify the issue. E.g. MOBILE-1234.
|
||||||
|
* @param filePath Path to the file to upload.
|
||||||
|
* @return Promise resolved when done.
|
||||||
|
*/
|
||||||
|
async upload(key, filePath) {
|
||||||
|
|
||||||
|
const uri = `issue/${key}/attachments`;
|
||||||
|
const headers = {
|
||||||
|
'X-Atlassian-Token': 'nocheck',
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await this.uploadFile(uri, 'file', filePath, headers);
|
||||||
|
|
||||||
|
if (response.status != 200) {
|
||||||
|
throw new Error('Could not upload file to Jira issue');
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('File successfully uploaded.')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upload a file to Jira.
|
||||||
|
*
|
||||||
|
* @param uri URI to add the the Jira URL.
|
||||||
|
* @param fieldName Name of the form field where to put the file.
|
||||||
|
* @param filePath Path to the file.
|
||||||
|
* @param headers Headers.
|
||||||
|
* @return Promise resolved with the result.
|
||||||
|
*/
|
||||||
|
async uploadFile(uri, fieldName, filePath, headers) {
|
||||||
|
uri = uri || '';
|
||||||
|
headers = headers || {};
|
||||||
|
headers['Content-Type'] = 'multipart/form-data';
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
// Add the file to the form data.
|
||||||
|
const formData = {};
|
||||||
|
formData[fieldName] = {
|
||||||
|
value: fs.createReadStream(filePath),
|
||||||
|
options: {
|
||||||
|
filename: filePath.substr(filePath.lastIndexOf('/') + 1),
|
||||||
|
contentType: 'multipart/form-data',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Perform the request.
|
||||||
|
const options = {
|
||||||
|
url: this.buildRequestUrl(uri),
|
||||||
|
method: 'POST',
|
||||||
|
headers: headers,
|
||||||
|
auth: {
|
||||||
|
user: this.username,
|
||||||
|
pass: this.password,
|
||||||
|
},
|
||||||
|
formData: formData,
|
||||||
|
};
|
||||||
|
|
||||||
|
request(options, (err, httpResponse, body) => {
|
||||||
|
resolve({
|
||||||
|
status: httpResponse.statusCode,
|
||||||
|
data: body,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = new Jira();
|
module.exports = new Jira();
|
||||||
|
|
|
@ -24,6 +24,56 @@ const Utils = require('./utils');
|
||||||
*/
|
*/
|
||||||
class PushTask {
|
class PushTask {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Push a patch to the tracker and remove the previous one.
|
||||||
|
*
|
||||||
|
* @param branch Branch name.
|
||||||
|
* @param branchData Parsed branch data.
|
||||||
|
* @param remote Remote used.
|
||||||
|
* @return Promise resolved when done.
|
||||||
|
*/
|
||||||
|
async pushPatch(branch, branchData, remote) {
|
||||||
|
const headCommit = await Git.getHeadCommit(branch, branchData);
|
||||||
|
|
||||||
|
if (!headCommit) {
|
||||||
|
throw new Error('Head commit not resolved, abort pushing patch.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the patch file.
|
||||||
|
const fileName = branch + '.patch';
|
||||||
|
const tmpPatchPath = `./tmp/${fileName}`;
|
||||||
|
|
||||||
|
await Git.createPatch(`${headCommit}...${branch}`, tmpPatchPath);
|
||||||
|
console.log('Git patch created');
|
||||||
|
|
||||||
|
// Check if there is an attachment with same name in the issue.
|
||||||
|
const issue = await Jira.getIssue(branchData.issue, 'attachment');
|
||||||
|
|
||||||
|
let existingAttachmentId;
|
||||||
|
const attachments = (issue.fields && issue.fields.attachment) || [];
|
||||||
|
for (const i in attachments) {
|
||||||
|
if (attachments[i].filename == fileName) {
|
||||||
|
// Found an existing attachment with the same name, we keep track of it.
|
||||||
|
existingAttachmentId = attachments[i].id;
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Push the patch to the tracker.
|
||||||
|
console.log(`Uploading patch ${fileName} to the tracker...`);
|
||||||
|
await Jira.upload(branchData.issue, tmpPatchPath);
|
||||||
|
|
||||||
|
if (existingAttachmentId) {
|
||||||
|
// On success, deleting file that was there before.
|
||||||
|
try {
|
||||||
|
console.log('Deleting older patch...')
|
||||||
|
await Jira.deleteAttachment(existingAttachmentId);
|
||||||
|
} catch (error) {
|
||||||
|
console.log('Could not delete older attachment.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run the task.
|
* Run the task.
|
||||||
*
|
*
|
||||||
|
@ -46,7 +96,9 @@ class PushTask {
|
||||||
throw new Error('Cannot push HEAD branch');
|
throw new Error('Cannot push HEAD branch');
|
||||||
}
|
}
|
||||||
|
|
||||||
const keepRunning = await this.validateLastCommitMessage(branch);
|
// Parse the branch to get the project and issue number.
|
||||||
|
const branchData = Utils.parseBranch(branch);
|
||||||
|
const keepRunning = await this.validateLastCommitMessage(branchData);
|
||||||
|
|
||||||
if (!keepRunning) {
|
if (!keepRunning) {
|
||||||
// Last commit not valid, stop.
|
// Last commit not valid, stop.
|
||||||
|
@ -55,13 +107,31 @@ class PushTask {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push the branch.
|
if (!args.patch) {
|
||||||
console.log(`Pushing branch ${branch} to remote ${remote}...`);
|
// Check if it's a security issue to force patch mode.
|
||||||
await Git.push(remote, branch, force);
|
try {
|
||||||
|
args.patch = await Jira.isSecurityIssue(branchData.issue);
|
||||||
|
|
||||||
// Update tracker info.
|
if (args.patch) {
|
||||||
console.log(`Branch pushed, update tracker info...`);
|
console.log(`${branchData.issue} appears to be a security issue, switching to patch mode...`);
|
||||||
await this.updateTrackerGitInfo(branch, remote);
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(`Could not check if ${branchData.issue} is a security issue.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.patch) {
|
||||||
|
// Create and upload a patch file.
|
||||||
|
await this.pushPatch(branch, branchData, remote);
|
||||||
|
} else {
|
||||||
|
// Push the branch.
|
||||||
|
console.log(`Pushing branch ${branch} to remote ${remote}...`);
|
||||||
|
await Git.push(remote, branch, force);
|
||||||
|
|
||||||
|
// Update tracker info.
|
||||||
|
console.log(`Branch pushed, update tracker info...`);
|
||||||
|
await this.updateTrackerGitInfo(branch, branchData, remote);
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
|
@ -73,13 +143,11 @@ class PushTask {
|
||||||
* Update git info in the tracker issue.
|
* Update git info in the tracker issue.
|
||||||
*
|
*
|
||||||
* @param branch Branch name.
|
* @param branch Branch name.
|
||||||
|
* @param branchData Parsed branch data.
|
||||||
* @param remote Remote used.
|
* @param remote Remote used.
|
||||||
* @return Promise resolved when done.
|
* @return Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
async updateTrackerGitInfo(branch, remote) {
|
async updateTrackerGitInfo(branch, branchData, remote) {
|
||||||
// Parse the branch to get the project and issue number.
|
|
||||||
const branchData = Utils.parseBranch(branch);
|
|
||||||
|
|
||||||
// Get the repository data for the project.
|
// Get the repository data for the project.
|
||||||
let repositoryUrl = DevConfig.get(branchData.project + '.repositoryUrl');
|
let repositoryUrl = DevConfig.get(branchData.project + '.repositoryUrl');
|
||||||
let diffUrlTemplate = DevConfig.get(branchData.project + '.diffUrlTemplate', '');
|
let diffUrlTemplate = DevConfig.get(branchData.project + '.diffUrlTemplate', '');
|
||||||
|
@ -134,12 +202,10 @@ class PushTask {
|
||||||
/**
|
/**
|
||||||
* Validate last commit message comparing it with the branch name.
|
* Validate last commit message comparing it with the branch name.
|
||||||
*
|
*
|
||||||
* @param branch Branch name.
|
* @param branchData Parsed branch data.
|
||||||
* @return True if value is ok or the user wants to continue anyway, false to stop.
|
* @return True if value is ok or the user wants to continue anyway, false to stop.
|
||||||
*/
|
*/
|
||||||
async validateLastCommitMessage(branch) {
|
async validateLastCommitMessage(branchData) {
|
||||||
const branchData = Utils.parseBranch(branch);
|
|
||||||
|
|
||||||
const messages = await Git.messages(1);
|
const messages = await Git.messages(1);
|
||||||
const message = messages[0];
|
const message = messages[0];
|
||||||
|
|
||||||
|
|
|
@ -2259,9 +2259,9 @@
|
||||||
"integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
|
"integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
|
||||||
},
|
},
|
||||||
"aws4": {
|
"aws4": {
|
||||||
"version": "1.8.0",
|
"version": "1.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz",
|
||||||
"integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ=="
|
"integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA=="
|
||||||
},
|
},
|
||||||
"babel-code-frame": {
|
"babel-code-frame": {
|
||||||
"version": "6.26.0",
|
"version": "6.26.0",
|
||||||
|
@ -5356,8 +5356,7 @@
|
||||||
"extend": {
|
"extend": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||||
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
|
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"extend-shallow": {
|
"extend-shallow": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
|
@ -6179,16 +6178,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
|
||||||
"integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
|
"integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
|
||||||
},
|
},
|
||||||
"form-data": {
|
|
||||||
"version": "2.3.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
|
|
||||||
"integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
|
|
||||||
"requires": {
|
|
||||||
"asynckit": "^0.4.0",
|
|
||||||
"combined-stream": "^1.0.6",
|
|
||||||
"mime-types": "^2.1.12"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"formidable": {
|
"formidable": {
|
||||||
"version": "1.2.2",
|
"version": "1.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.2.tgz",
|
||||||
|
@ -8400,29 +8389,6 @@
|
||||||
"requires": {
|
"requires": {
|
||||||
"ajv": "^6.5.5",
|
"ajv": "^6.5.5",
|
||||||
"har-schema": "^2.0.0"
|
"har-schema": "^2.0.0"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"ajv": {
|
|
||||||
"version": "6.9.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.9.1.tgz",
|
|
||||||
"integrity": "sha512-XDN92U311aINL77ieWHmqCcNlwjoP5cHXDxIxbf2MaPYuCXOHS7gHH8jktxeK5omgd52XbSTX6a4Piwd1pQmzA==",
|
|
||||||
"requires": {
|
|
||||||
"fast-deep-equal": "^2.0.1",
|
|
||||||
"fast-json-stable-stringify": "^2.0.0",
|
|
||||||
"json-schema-traverse": "^0.4.1",
|
|
||||||
"uri-js": "^4.2.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fast-deep-equal": {
|
|
||||||
"version": "2.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
|
|
||||||
"integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk="
|
|
||||||
},
|
|
||||||
"json-schema-traverse": {
|
|
||||||
"version": "0.4.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
|
||||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"has": {
|
"has": {
|
||||||
|
@ -12117,7 +12083,8 @@
|
||||||
"punycode": {
|
"punycode": {
|
||||||
"version": "1.4.1",
|
"version": "1.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
|
||||||
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
|
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"q": {
|
"q": {
|
||||||
"version": "1.5.1",
|
"version": "1.5.1",
|
||||||
|
@ -12500,9 +12467,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"request": {
|
"request": {
|
||||||
"version": "2.88.0",
|
"version": "2.88.2",
|
||||||
"resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
|
"resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
|
||||||
"integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
|
"integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"aws-sign2": "~0.7.0",
|
"aws-sign2": "~0.7.0",
|
||||||
"aws4": "^1.8.0",
|
"aws4": "^1.8.0",
|
||||||
|
@ -12511,7 +12478,7 @@
|
||||||
"extend": "~3.0.2",
|
"extend": "~3.0.2",
|
||||||
"forever-agent": "~0.6.1",
|
"forever-agent": "~0.6.1",
|
||||||
"form-data": "~2.3.2",
|
"form-data": "~2.3.2",
|
||||||
"har-validator": "~5.1.0",
|
"har-validator": "~5.1.3",
|
||||||
"http-signature": "~1.2.0",
|
"http-signature": "~1.2.0",
|
||||||
"is-typedarray": "~1.0.0",
|
"is-typedarray": "~1.0.0",
|
||||||
"isstream": "~0.1.2",
|
"isstream": "~0.1.2",
|
||||||
|
@ -12521,15 +12488,20 @@
|
||||||
"performance-now": "^2.1.0",
|
"performance-now": "^2.1.0",
|
||||||
"qs": "~6.5.2",
|
"qs": "~6.5.2",
|
||||||
"safe-buffer": "^5.1.2",
|
"safe-buffer": "^5.1.2",
|
||||||
"tough-cookie": "~2.4.3",
|
"tough-cookie": "~2.5.0",
|
||||||
"tunnel-agent": "^0.6.0",
|
"tunnel-agent": "^0.6.0",
|
||||||
"uuid": "^3.3.2"
|
"uuid": "^3.3.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"extend": {
|
"form-data": {
|
||||||
"version": "3.0.2",
|
"version": "2.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
|
||||||
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
|
"integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
|
||||||
|
"requires": {
|
||||||
|
"asynckit": "^0.4.0",
|
||||||
|
"combined-stream": "^1.0.6",
|
||||||
|
"mime-types": "^2.1.12"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -14407,12 +14379,19 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tough-cookie": {
|
"tough-cookie": {
|
||||||
"version": "2.4.3",
|
"version": "2.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
|
||||||
"integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
|
"integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"psl": "^1.1.24",
|
"psl": "^1.1.28",
|
||||||
"punycode": "^1.4.1"
|
"punycode": "^2.1.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"punycode": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tree-kill": {
|
"tree-kill": {
|
||||||
|
|
|
@ -159,6 +159,7 @@
|
||||||
"minimist": "^1.2.5",
|
"minimist": "^1.2.5",
|
||||||
"native-run": "^1.0.0",
|
"native-run": "^1.0.0",
|
||||||
"node-loader": "^0.6.0",
|
"node-loader": "^0.6.0",
|
||||||
|
"request": "^2.88.2",
|
||||||
"through": "^2.3.8",
|
"through": "^2.3.8",
|
||||||
"typescript": "~2.6.2",
|
"typescript": "~2.6.2",
|
||||||
"vinyl": "^2.2.0",
|
"vinyl": "^2.2.0",
|
||||||
|
|
Loading…
Reference in New Issue