Comparing version 0.2.0 to 0.3.0
@@ -12,2 +12,3 @@ 'use strict'; | ||
, http = require('http') | ||
, https = require('https') | ||
, sizeOf = require('image-size') | ||
@@ -18,3 +19,11 @@ , helpers = require('./helpers'); | ||
img: { | ||
layout: 'responsive' | ||
layout: 'responsive', | ||
width: 600, | ||
height: 400, | ||
}, | ||
iframe: { | ||
layout: 'responsive', | ||
width: 600, | ||
height: 400, | ||
sandbox: 'allow-scripts allow-same-origin' | ||
} | ||
@@ -117,27 +126,93 @@ }; | ||
/** | ||
* Get the image sizes (width and heigth plus type of image) | ||
* | ||
* https://github.com/image-size/image-size | ||
* | ||
* @param {Object} element | ||
* @return {Object} element incl. width and height | ||
*/ | ||
function getImageSize(element) { | ||
var options = url.parse(element.attribs.src); | ||
var request = element.attribs.src.indexOf('https') === 0 ? https : http; | ||
// We need the user-agent, otherwise some https request may fail (e. g. cloudfare) | ||
options.headers = { 'User-Agent': 'Mozilla/5.0' }; | ||
return request.get(options, function (response) { | ||
var chunks = []; | ||
response.on('data', function (chunk) { | ||
chunks.push(chunk); | ||
}).on('end', function () { | ||
try { | ||
var dimensions = sizeOf(Buffer.concat(chunks)); | ||
element.attribs.width = dimensions.width; | ||
element.attribs.height = dimensions.height; | ||
return enter(); | ||
} catch (err) { | ||
// fallback to default values, so the HTML get validated at least | ||
element.attribs.width = amperize.config.img.width; | ||
element.attribs.height = amperize.config.img.height; | ||
return enter(); | ||
} | ||
}); | ||
}).on('error', function () { | ||
// fallback to default values, so the HTML get validated at least | ||
element.attribs.width = amperize.config.img.width; | ||
element.attribs.height = amperize.config.img.height; | ||
return enter(); | ||
}); | ||
} | ||
if ((element.name === 'img' || element.name === 'iframe') && !element.attribs.src) { | ||
return enter(); | ||
} | ||
if (element.name === 'img' && amperize.config.img) { | ||
element.name = 'amp-img'; | ||
// when we have a gif it should be <amp-anim>. | ||
element.name = element.attribs.src.match(/(\.gif$)/) ? 'amp-anim' : 'amp-img'; | ||
if (!element.attribs.layout) { | ||
element.attribs.layout = amperize.config.img.layout; | ||
if (!element.attribs.width || !element.attribs.height || !element.attribs.layout) { | ||
element.attribs.layout = !element.attribs.layout ? amperize.config.iframe.layout : element.attribs.layout; | ||
if (element.attribs.src.indexOf('http') === 0) { | ||
return getImageSize(element); | ||
} else { | ||
element.attribs.width = amperize.config.img.width; | ||
element.attribs.height = amperize.config.img.height; | ||
} | ||
} | ||
} | ||
if ((!element.attribs.width || !element.attribs.height) && element.attribs.src.indexOf('http') === 0) { | ||
var options = url.parse(element.attribs.src); | ||
if (element.name ==='iframe') { | ||
element.name = 'amp-iframe'; | ||
return http.get(options, function (response) { | ||
var chunks = []; | ||
if (!element.attribs.width || !element.attribs.height || !element.attribs.layout) { | ||
response.on('data', function (chunk) { | ||
chunks.push(chunk); | ||
}).on('end', function () { | ||
var dimensions = sizeOf(Buffer.concat(chunks)); | ||
element.attribs.width = dimensions.width; | ||
element.attribs.height = dimensions.height; | ||
return enter(); | ||
}); | ||
}); | ||
element.attribs.layout = !element.attribs.layout ? amperize.config.iframe.layout : element.attribs.layout; | ||
element.attribs.width = !element.attribs.width ? amperize.config.iframe.width : element.attribs.width; | ||
element.attribs.height = !element.attribs.height ? amperize.config.iframe.height : element.attribs.height; | ||
element.attribs.sandbox = !element.attribs.sandbox ? amperize.config.iframe.sandbox : element.attribs.sandbox; | ||
} | ||
} | ||
if (element.name === 'audio') { | ||
element.name = 'amp-audio'; | ||
} | ||
if (element.attribs && element.attribs.src) { | ||
// Every src attribute must be with 'https' protocol otherwise it will not get validated by AMP. | ||
// If we're unable to replace it, we will deal with the valitation error, but at least | ||
// we tried. | ||
if (element.attribs.src.indexOf('https://') === -1) { | ||
if (element.attribs.src.indexOf('http://') === 0) { | ||
// Replace 'http' with 'https', so the validation passes | ||
element.attribs.src = element.attribs.src.replace(/^http:\/\//i, 'https://'); | ||
} else if (element.attribs.src.indexOf('//') === 0) { | ||
// Giphy embedded iFrames are without protocol and start with '//', so at least | ||
// we can fix those cases. | ||
element.attribs.src = 'https:' + element.attribs.src; | ||
} | ||
} | ||
} | ||
return enter(); | ||
@@ -144,0 +219,0 @@ }, done); |
@@ -9,3 +9,4 @@ 'use strict'; | ||
'area', 'base', 'br', 'col', 'command', 'embed', 'hr', | ||
'img', 'input', 'link', 'meta', 'param', 'source', 'wbr' | ||
'img', 'input', 'link', 'meta', 'param', 'source', 'wbr', | ||
'track' | ||
]; | ||
@@ -12,0 +13,0 @@ |
{ | ||
"name": "amperize", | ||
"version": "0.2.0", | ||
"version": "0.3.0", | ||
"description": "AMP up your plain HTML", | ||
@@ -10,7 +10,8 @@ "main": "./lib/amperize", | ||
"coverage": "istanbul cover ./node_modules/.bin/_mocha -- $(find test -name '*.test.js')", | ||
"test-travis": "istanbul cover node_modules/.bin/_mocha --report lcovonly -- $(find test -name '*.test.js')" | ||
"test-travis": "istanbul cover node_modules/.bin/_mocha --report lcovonly -- $(find test -name '*.test.js')", | ||
"semantic-release": "semantic-release pre && npm publish && semantic-release post" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/jbhannah/amperize.git" | ||
"url": "https://github.com/jbhannah/amperize.git" | ||
}, | ||
@@ -28,16 +29,25 @@ "keywords": [ | ||
"dependencies": { | ||
"async": "1.4.2", | ||
"async": "2.0.1", | ||
"emits": "3.0.0", | ||
"htmlparser2": "3.8.3", | ||
"image-size": "0.3.5", | ||
"lodash.merge": "3.3.2", | ||
"node-uuid": "1.4.3" | ||
"htmlparser2": "3.9.1", | ||
"image-size": "0.5.0", | ||
"lodash.merge": "4.6.0", | ||
"nock": "^8.0.0", | ||
"node-uuid": "1.4.7", | ||
"rewire": "^2.5.2" | ||
}, | ||
"devDependencies": { | ||
"chai": "3.4.0", | ||
"istanbul": "0.4.0", | ||
"mocha": "2.3.3", | ||
"sinon": "1.17.2", | ||
"chai": "3.5.0", | ||
"cz-conventional-changelog": "1.2.0", | ||
"istanbul": "0.4.4", | ||
"mocha": "3.0.2", | ||
"semantic-release": "4.3.5", | ||
"sinon": "1.17.5", | ||
"sinon-chai": "2.8.0" | ||
}, | ||
"config": { | ||
"commitizen": { | ||
"path": "./node_modules/cz-conventional-changelog" | ||
} | ||
} | ||
} |
@@ -7,3 +7,5 @@ 'use strict'; | ||
, sinonChai = require('sinon-chai') | ||
, Amperize = require('../lib/amperize') | ||
, nock = require('nock') | ||
, rewire = require('rewire') | ||
, Amperize = rewire('../lib/amperize') | ||
, amperize; | ||
@@ -31,5 +33,13 @@ | ||
expect(amperize.config).to.be.eql({ | ||
img: { | ||
layout: 'responsive' | ||
} | ||
img: { | ||
layout: 'responsive', | ||
width: 600, | ||
height: 400, | ||
}, | ||
iframe: { | ||
layout: 'responsive', | ||
width: 600, | ||
height: 400, | ||
sandbox: 'allow-scripts allow-same-origin' | ||
} | ||
}); | ||
@@ -61,2 +71,14 @@ }); | ||
describe('#parse', function () { | ||
var sizeOfMock, | ||
sizeOfStub; | ||
beforeEach(function () { | ||
// stubbing the `image-size` lib, so we don't to a request everytime | ||
sizeOfStub = sinon.stub(); | ||
}); | ||
afterEach(function () { | ||
sinon.restore(); | ||
}); | ||
it('throws an error if no callback provided', function () { | ||
@@ -70,7 +92,189 @@ function err() { | ||
it('transforms <img> into <amp-img></amp-img>', function () { | ||
amperize.parse('<img src="http://lorempixel.com/output/abstract-q-c-640-480-3.jpg">', function (error, result) { | ||
expect(result).to.be.equal('<amp-img src="http://lorempixel.com/output/abstract-q-c-640-480-3.jpg" layout="responsive" width="640" height="480"></amp-img>'); | ||
it('transforms <img> with layout property into <amp-img></amp-img> without overriding it and full image dimensions', function (done) { | ||
sizeOfMock = nock('http://static.wixstatic.com') | ||
.get('/media/355241_d31358572a2542c5a44738ddcb59e7ea.jpg_256') | ||
.reply(200, { | ||
data: '<Buffer 2c be a4 40 f7 87 73 1e 57 2c c1 e4 0d 79 03 95 42 f0 42 2e 41 95 27 c9 5c 35 a7 71 2c 09 5a 57 d3 04 1e 83 03 28 07 96 b0 c8 88 65 07 7a d1 d6 63 50>' | ||
}); | ||
sizeOfStub.returns({width: 50, height: 50, type: 'jpg'}); | ||
Amperize.__set__('sizeOf', sizeOfStub); | ||
amperize.parse('<img src="http://static.wixstatic.com/media/355241_d31358572a2542c5a44738ddcb59e7ea.jpg_256" layout="FIXED">', function (error, result) { | ||
expect(result).to.exist; | ||
expect(result).to.contain('<amp-img'); | ||
expect(result).to.contain('src="http://static.wixstatic.com/media/355241_d31358572a2542c5a44738ddcb59e7ea.jpg_256"'); | ||
expect(result).to.contain('layout="FIXED"'); | ||
expect(result).to.contain('width="50"'); | ||
expect(result).to.contain('height="50"'); | ||
expect(result).to.contain('</amp-img>'); | ||
done(); | ||
}); | ||
}); | ||
it('transforms .gif <img> with only height property into <amp-anim></amp-anim> with full dimensions by overriding them', function (done) { | ||
sizeOfMock = nock('https://media.giphy.com') | ||
.get('/media/l46CtzgjhTm29Cbjq/giphy.gif') | ||
.reply(200, { | ||
data: '<Buffer 2c be a4 40 f7 87 73 1e 57 2c c1 e4 0d 79 03 95 42 f0 42 2e 41 95 27 c9 5c 35 a7 71 2c 09 5a 57 d3 04 1e 83 03 28 07 96 b0 c8 88 65 07 7a d1 d6 63 50>' | ||
}); | ||
sizeOfStub.returns({width: 800, height: 600, type: 'gif'}); | ||
Amperize.__set__('sizeOf', sizeOfStub); | ||
amperize.parse('<img src="https://media.giphy.com/media/l46CtzgjhTm29Cbjq/giphy.gif" height="500">', function (error, result) { | ||
expect(result).to.exist; | ||
expect(result).to.contain('<amp-anim'); | ||
expect(result).to.contain('src="https://media.giphy.com/media/l46CtzgjhTm29Cbjq/giphy.gif"'); | ||
expect(result).to.contain('layout="responsive"'); | ||
expect(result).to.contain('width="800"'); | ||
expect(result).to.contain('height="600"'); | ||
expect(result).to.contain('</amp-anim>'); | ||
done(); | ||
}); | ||
}); | ||
it('transforms <iframe> with only width property into <amp-iframe></amp-iframe> with full dimensions withour overriding them', function (done) { | ||
amperize.parse('<iframe src="https://www.youtube.com/embed/HMQkV5cTuoY" width="400"></iframe>', function (error, result) { | ||
expect(result).to.exist; | ||
expect(result).to.contain('<amp-iframe'); | ||
expect(result).to.contain('src="https://www.youtube.com/embed/HMQkV5cTuoY"'); | ||
expect(result).to.contain('layout="responsive"'); | ||
expect(result).to.contain('width="400"'); | ||
expect(result).to.contain('height="400"'); | ||
expect(result).to.contain('</amp-iframe>'); | ||
expect(result).to.contain('sandbox="allow-scripts allow-same-origin"') | ||
done(); | ||
}); | ||
}); | ||
it('adds \'https\' protocol to <iframe> if no protocol is supplied (e. e. giphy)', function (done) { | ||
var url = '<iframe src="//giphy.com/embed/3oEduKP4VaUxJvLwuA" width="480" height="372" frameBorder="0" class="giphy-embed" allowFullScreen></iframe>'; | ||
amperize.parse(url, function (error, result) { | ||
expect(result).to.exist; | ||
expect(result).to.contain('<amp-iframe'); | ||
expect(result).to.contain('src="https://giphy.com/embed/3oEduKP4VaUxJvLwuA"'); | ||
expect(result).to.contain('layout="responsive"'); | ||
expect(result).to.contain('width="480"'); | ||
expect(result).to.contain('height="372"'); | ||
expect(result).to.contain('</amp-iframe>'); | ||
expect(result).to.contain('sandbox="allow-scripts allow-same-origin"') | ||
done(); | ||
}); | ||
}); | ||
it('adds \'https\' protocol to <iframe> if only \'http\' protocol is supplied', function (done) { | ||
var url = '<iframe src="http://giphy.com/embed/3oEduKP4VaUxJvLwuA" width="480" height="372" frameBorder="0" class="giphy-embed" allowFullScreen></iframe><p><a href="http://giphy.com/gifs/afv-funny-fail-lol-3oEduKP4VaUxJvLwuA">via GIPHY</a></p></p>'; | ||
amperize.parse(url, function (error, result) { | ||
expect(result).to.exist; | ||
expect(result).to.contain('<amp-iframe'); | ||
expect(result).to.contain('src="https://giphy.com/embed/3oEduKP4VaUxJvLwuA"'); | ||
expect(result).to.contain('layout="responsive"'); | ||
expect(result).to.contain('width="480"'); | ||
expect(result).to.contain('height="372"'); | ||
expect(result).to.contain('</amp-iframe>'); | ||
expect(result).to.contain('sandbox="allow-scripts allow-same-origin"') | ||
done(); | ||
}); | ||
}); | ||
it('transforms local <img> into <amp-img></amp-img> with default image dimensions', function (done) { | ||
amperize.parse('<img src="/content/images/IMG_xyz.jpg">', function (error, result) { | ||
expect(result).to.exist; | ||
expect(result).to.contain('<amp-img'); | ||
expect(result).to.contain('src="/content/images/IMG_xyz.jpg"'); | ||
expect(result).to.contain('layout="responsive"'); | ||
expect(result).to.contain('width="600"'); | ||
expect(result).to.contain('height="400"'); | ||
expect(result).to.contain('</amp-img>'); | ||
done(); | ||
}); | ||
}); | ||
it('can handle <img> tag without src and does not transform it', function (done) { | ||
amperize.parse('<img><//img><p>some text here</p>', function (error, result) { | ||
expect(result).to.exist; | ||
expect(result).to.be.equal('<img><p>some text here</p>'); | ||
done(); | ||
}); | ||
}); | ||
it('can handle <iframe> tag without src and does not transform it', function (done) { | ||
amperize.parse('<iframe>', function (error, result) { | ||
expect(result).to.exist; | ||
expect(result).to.be.equal('<iframe></iframe>'); | ||
done(); | ||
}); | ||
}); | ||
it('transforms <audio> with a fallback to <amp-audio>', function (done) { | ||
amperize.parse('<audio src="http://foo.mp3" autoplay>Your browser does not support the <code>audio</code> element.</audio>', function (error, result) { | ||
expect(result).to.exist; | ||
expect(result).to.contain('<amp-audio src="https://foo.mp3" autoplay="">'); | ||
expect(result).to.contain('Your browser does not support the <code>audio</code> element.'); | ||
expect(result).to.contain('</amp-audio>'); | ||
done(); | ||
}); | ||
}); | ||
it('transforms <audio> with a <source> tag to <amp-audio> and maintains the attributes', function (done) { | ||
amperize.parse('<audio controls="controls" width="auto" height="50" autoplay="mobile">Your browser does not support the <code>audio</code> element.<source src="//foo.wav" type="audio/wav"></audio>', function (error, result) { | ||
expect(result).to.exist; | ||
expect(result).to.contain('<amp-audio'); | ||
expect(result).to.contain('controls="controls" width="auto" height="50" autoplay="mobile"'); | ||
expect(result).to.contain('<source src="https://foo.wav" type="audio/wav">'); | ||
expect(result).to.contain('</amp-audio>'); | ||
done(); | ||
}); | ||
}); | ||
it('transforms <audio> with a <track> tag to <amp-audio>', function (done) { | ||
amperize.parse('<audio src="foo.ogg"><track kind="captions" src="https://foo.en.vtt" srclang="en" label="English"><track kind="captions" src="https://foo.sv.vtt" srclang="sv" label="Svenska"></audio>', function (error, result) { | ||
expect(result).to.exist; | ||
expect(result).to.contain('<amp-audio src="foo.ogg">'); | ||
expect(result).to.contain('<track kind="captions" src="https://foo.en.vtt" srclang="en" label="English">'); | ||
expect(result).to.contain('<track kind="captions" src="https://foo.sv.vtt" srclang="sv" label="Svenska">'); | ||
expect(result).to.contain('</amp-audio>'); | ||
done(); | ||
}); | ||
}); | ||
it('can handle request errors by falling back to the default values defined in config', function (done) { | ||
sizeOfMock = nock('http://example.com') | ||
.get('/images/IMG_xyz.jpg') | ||
.replyWithError('something awful happened'); | ||
amperize.parse('<img src="http://example.com/images/IMG_xyz.jpg">', function (error, result) { | ||
expect(result).to.exist; | ||
expect(result).to.contain('<amp-img'); | ||
expect(result).to.contain('src="http://example.com/images/IMG_xyz.jpg"'); | ||
expect(result).to.contain('layout="responsive"'); | ||
expect(result).to.contain('width="600"'); | ||
expect(result).to.contain('height="400"'); | ||
expect(result).to.contain('</amp-img>'); | ||
done(); | ||
}); | ||
}); | ||
it('can handle errors of image-size module by falling back to the default values defined in config', function (done) { | ||
sizeOfMock = nock('http://example.com') | ||
.get('/images/IMG_xyz.jpg') | ||
.reply(200, { | ||
data: '<Buffer 2c be a4 40 f7 87 73 1e 57 2c c1 e4 0d 79 03 95 42 f0 42 2e 41 95 27 c9 5c 35 a7 71 2c 09 5a 57 d3 04 1e 83 03 28 07 96 b0 c8 88 65 07 7a d1 d6 63 50>' | ||
}); | ||
sizeOfStub.throws('Not found'); | ||
Amperize.__set__('sizeOf', sizeOfStub); | ||
amperize.parse('<img src="http://example.com/images/IMG_xyz.jpg">', function (error, result) { | ||
expect(result).to.exist; | ||
expect(result).to.contain('<amp-img'); | ||
expect(result).to.contain('src="http://example.com/images/IMG_xyz.jpg"'); | ||
expect(result).to.contain('layout="responsive"'); | ||
expect(result).to.contain('width="600"'); | ||
expect(result).to.contain('height="400"'); | ||
expect(result).to.contain('</amp-img>'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
@@ -77,0 +281,0 @@ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
27486
564
8
7
2
+ Addednock@^8.0.0
+ Addedrewire@^2.5.2
+ Addedassertion-error@1.1.0(transitive)
+ Addedasync@2.0.1(transitive)
+ Addedcall-bind@1.0.7(transitive)
+ Addedchai@3.5.0(transitive)
+ Addeddebug@2.6.9(transitive)
+ Addeddeep-eql@0.1.3(transitive)
+ Addeddeep-equal@1.1.2(transitive)
+ Addeddefine-data-property@1.1.4(transitive)
+ Addeddefine-properties@1.2.1(transitive)
+ Addeddomhandler@2.4.2(transitive)
+ Addeddomutils@1.7.0(transitive)
+ Addedentities@1.1.2(transitive)
+ Addedes-define-property@1.0.0(transitive)
+ Addedes-errors@1.3.0(transitive)
+ Addedfunction-bind@1.1.2(transitive)
+ Addedfunctions-have-names@1.2.3(transitive)
+ Addedget-intrinsic@1.2.4(transitive)
+ Addedgopd@1.0.1(transitive)
+ Addedhas-property-descriptors@1.0.2(transitive)
+ Addedhas-proto@1.0.3(transitive)
+ Addedhas-symbols@1.0.3(transitive)
+ Addedhas-tostringtag@1.0.2(transitive)
+ Addedhasown@2.0.2(transitive)
+ Addedhtmlparser2@3.9.1(transitive)
+ Addedimage-size@0.5.0(transitive)
+ Addedis-arguments@1.1.1(transitive)
+ Addedis-date-object@1.0.5(transitive)
+ Addedis-regex@1.1.4(transitive)
+ Addedisarray@1.0.0(transitive)
+ Addedjson-stringify-safe@5.0.1(transitive)
+ Addedlodash@4.17.214.9.0(transitive)
+ Addedlodash.merge@4.6.0(transitive)
+ Addedminimist@1.2.8(transitive)
+ Addedmkdirp@0.5.6(transitive)
+ Addedms@2.0.0(transitive)
+ Addednock@8.2.2(transitive)
+ Addednode-uuid@1.4.7(transitive)
+ Addedobject-inspect@1.13.2(transitive)
+ Addedobject-is@1.1.6(transitive)
+ Addedobject-keys@1.1.1(transitive)
+ Addedprocess-nextick-args@2.0.1(transitive)
+ Addedpropagate@0.4.0(transitive)
+ Addedqs@6.13.0(transitive)
+ Addedreadable-stream@2.3.8(transitive)
+ Addedregexp.prototype.flags@1.5.3(transitive)
+ Addedrewire@2.5.2(transitive)
+ Addedsafe-buffer@5.1.2(transitive)
+ Addedset-function-length@1.2.2(transitive)
+ Addedset-function-name@2.0.2(transitive)
+ Addedside-channel@1.0.6(transitive)
+ Addedstring_decoder@1.1.1(transitive)
+ Addedtype-detect@0.1.11.0.0(transitive)
+ Addedutil-deprecate@1.0.2(transitive)
- Removedasync@1.4.2(transitive)
- Removeddomhandler@2.3.0(transitive)
- Removeddomutils@1.5.1(transitive)
- Removedentities@1.0.0(transitive)
- Removedhtmlparser2@3.8.3(transitive)
- Removedimage-size@0.3.5(transitive)
- Removedisarray@0.0.1(transitive)
- Removedlodash._arraycopy@3.0.0(transitive)
- Removedlodash._arrayeach@3.0.0(transitive)
- Removedlodash._basecopy@3.0.1(transitive)
- Removedlodash._basefor@3.0.3(transitive)
- Removedlodash._bindcallback@3.0.1(transitive)
- Removedlodash._createassigner@3.1.1(transitive)
- Removedlodash._getnative@3.9.1(transitive)
- Removedlodash._isiterateecall@3.0.9(transitive)
- Removedlodash.isarguments@3.1.0(transitive)
- Removedlodash.isarray@3.0.4(transitive)
- Removedlodash.isplainobject@3.2.0(transitive)
- Removedlodash.istypedarray@3.0.6(transitive)
- Removedlodash.keys@3.1.2(transitive)
- Removedlodash.keysin@3.0.8(transitive)
- Removedlodash.merge@3.3.2(transitive)
- Removedlodash.restparam@3.6.1(transitive)
- Removedlodash.toplainobject@3.0.0(transitive)
- Removednode-uuid@1.4.3(transitive)
- Removedreadable-stream@1.1.14(transitive)
- Removedstring_decoder@0.10.31(transitive)
Updatedasync@2.0.1
Updatedhtmlparser2@3.9.1
Updatedimage-size@0.5.0
Updatedlodash.merge@4.6.0
Updatednode-uuid@1.4.7