fetch-base64
Advanced tools
Comparing version 1.0.0 to 2.0.0
10
index.js
@@ -45,7 +45,7 @@ 'use strict'; | ||
function auto(...paths) { | ||
return new Promise((resolve) => { | ||
resolve( | ||
(uriMatcher.isRemote(paths[0])) ? fetchRemote(...paths) : fetchLocal(...paths) | ||
); | ||
}); | ||
try { | ||
return (uriMatcher.isRemote(paths[0])) ? fetchRemote(...paths) : fetchLocal(...paths) | ||
} catch (e) { | ||
return Promise.reject(e); | ||
} | ||
} | ||
@@ -52,0 +52,0 @@ |
'use strict'; | ||
const url = require('url'); | ||
const { URL } = require('url'); | ||
const legacyUrl = require('url'); | ||
const http = require('http'); | ||
const https = require('https'); | ||
const ua = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36'; | ||
@@ -10,14 +12,15 @@ | ||
const promise = new Promise((resolve, reject) => { | ||
const uri = (paths.length > 1) ? url.resolve(...paths) : paths[0]; | ||
let options; | ||
const uri = (paths.length > 1) ? legacyUrl.resolve(...paths) : paths[0]; | ||
let myUrl; | ||
try { | ||
options = url.parse(uri); | ||
myUrl = new URL(uri); | ||
} catch (e) { | ||
reject(`URL Parse error: ${e}`); | ||
} | ||
options.method = 'GET'; // add http method | ||
options.headers = { // Spoof user agent | ||
myUrl.method = 'GET'; // add http method | ||
myUrl.headers = { // Spoof user agent | ||
'User-Agent': ua, | ||
}; | ||
const req = http.request(options, (res) => { | ||
const agent = (myUrl.protocol === 'https:') ? https : http; | ||
const req = agent.request(myUrl, (res) => { | ||
if (res.statusCode !== 200) { | ||
@@ -24,0 +27,0 @@ reject(`Status code ${res.statusCode} returned when trying to fetch file`); |
{ | ||
"name": "fetch-base64", | ||
"version": "1.0.0", | ||
"description": "A node package to retrieve fetch local or remote images in base64 encoding.", | ||
"version": "2.0.0", | ||
"description": "A node package to retrieve fetch local or remote files in base64 encoding.", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "mocha --harmony --recursive ./test", | ||
"test": "mocha --recursive ./test", | ||
"publish-please": "publish-please", | ||
@@ -24,3 +24,5 @@ "prepublish": "publish-please guard" | ||
"embedding", | ||
"mime" | ||
"mime", | ||
"inline", | ||
"inlining" | ||
], | ||
@@ -34,17 +36,15 @@ "author": "Joan Gamell", | ||
"dependencies": { | ||
"mime-types": "^2.1.11" | ||
"mime-types": "^2.1.15" | ||
}, | ||
"devDependencies": { | ||
"chai": "^3.5.0", | ||
"eslint": "^2.10.1", | ||
"eslint-config-airbnb": "^9.0.1", | ||
"eslint-plugin-import": "^1.8.1", | ||
"eslint-plugin-jsx-a11y": "^1.0.4", | ||
"eslint-plugin-react": "^5.2.2", | ||
"mocha": "^2.5.3", | ||
"publish-please": "2.1.4", | ||
"sinon": "^1.17.4" | ||
"chai": "^4.1.0", | ||
"eslint": "^4.2.0", | ||
"eslint-config-airbnb-base": "^11.2.0", | ||
"eslint-plugin-import": "^2.7.0", | ||
"mocha": "^3.4.2", | ||
"publish-please": "^2.3.1", | ||
"sinon": "^2.3.8" | ||
}, | ||
"engines": { | ||
"node": ">= 5.0.0" | ||
"node": ">= 7.5.0" | ||
}, | ||
@@ -51,0 +51,0 @@ "eslintConfig": { |
# Fetch Base64 | ||
A node package to retrieve fetch local or remote files in base64 encoding. Useful for embedding assets (images, web fonts, etc.) into HTML or CSS documents. | ||
[![Build Status](https://travis-ci.org/gamell/fetch-base64.svg?branch=master)](https://travis-ci.org/gamell/fetch-base64) | ||
A node package to fetch local or remote files in base64 encoding. Useful for inlining assets (images, web fonts, etc.) into HTML or CSS documents. | ||
Disclaimer: I've only used this for images so far, but there is no reason why it shouldn't work for any other kind of files. | ||
@@ -5,0 +8,0 @@ |
@@ -23,3 +23,3 @@ const fetch = require('../../index'); | ||
}); | ||
it('should fail for unexistent file', (done) => { | ||
it('should fail for nonexistent file', (done) => { | ||
fetch.local('/no.jpg').catch((reason) => { | ||
@@ -39,3 +39,3 @@ assert.equal(reason, 'Error reading local file: Error: ENOENT: no such file or directory, open \'/no.jpg\''); | ||
}); | ||
it('should fetch file with form, to URL', (done) => { | ||
it('should fetch file with `form, to` style URL', (done) => { | ||
fetch.remote('http://gamell.io/', '/sprite.png').then((data) => { | ||
@@ -47,3 +47,10 @@ assert.include(data[0], 'iVBORw0KGgoAAAANSUhEU'); | ||
}); | ||
it('should fail for unexistent file', (done) => { | ||
it('should fetch file from https resource', (done) => { | ||
fetch.remote('https://gamell.io/sprite.png').then((data) => { | ||
assert.include(data[0], 'iVBORw0KGgoAAAANSUhEU'); | ||
assert.include(data[1], 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAC6'); | ||
done(); | ||
}).catch((e) => done(e)); | ||
}); | ||
it('should fail for nonexistent file', (done) => { | ||
fetch.remote('http://gamell.io/ajndjdnfjsdn.jpg').catch((reason) => { | ||
@@ -70,3 +77,10 @@ assert.equal(reason, 'Status code 404 returned when trying to fetch file'); | ||
}); | ||
it('should fail for unexistent file', (done) => { | ||
it('should fetch file from https resource', (done) => { | ||
fetch.auto('https://gamell.io/sprite.png').then((data) => { | ||
assert.include(data[0], 'iVBORw0KGgoAAAANSUhEU'); | ||
assert.include(data[1], 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAC6'); | ||
done(); | ||
}).catch((e) => done(e)); | ||
}); | ||
it('should fail for nonexistent file', (done) => { | ||
fetch.auto('http://gamell.io/ajndjdnfjsdn.jpg').catch((reason) => { | ||
@@ -73,0 +87,0 @@ assert.equal(reason, 'Status code 404 returned when trying to fetch file'); |
@@ -12,2 +12,4 @@ 'use strict'; | ||
function swallow() {} | ||
describe('index.js (Unit)', () => { | ||
@@ -23,8 +25,10 @@ beforeEach(() => { | ||
it('should always return a promise', () => { | ||
assert(typeof index.auto('non-existant-path').then === 'function'); | ||
assert(typeof index.auto().then === 'function'); | ||
assert(typeof index.auto().then === 'function'); | ||
const auto1 = index.auto('non-existant-path'); | ||
const auto2 = index.auto(); | ||
assert(typeof auto1.then === 'function'); | ||
assert(typeof auto2.then === 'function'); | ||
Promise.all([auto1, auto2]).catch(swallow); | ||
}); | ||
it('it should call local.fetch() to fetch local files', (done) => { | ||
const fetchLocalStub = sandbox.stub(local, 'fetch', () => Promise.resolve('image-data')); | ||
it('it should call local.fetch() to fetch local images', (done) => { | ||
const fetchLocalStub = sandbox.stub(local, 'fetch').callsFake(() => Promise.resolve('image-data')); | ||
const shouldNotBeCalled = sandbox.spy(remote, 'fetch'); | ||
@@ -40,3 +44,3 @@ index.auto('/several/', '/paths/', '/image.gif').then((data) => { | ||
it('it should call remote.fetch() to fetch remote images', (done) => { | ||
const fetchRemoteStub = sandbox.stub(remote, 'fetch', () => Promise.resolve('image-data')); | ||
const fetchRemoteStub = sandbox.stub(remote, 'fetch').callsFake(() => Promise.resolve('image-data')); | ||
const shouldNotBeCalled = sandbox.spy(local, 'fetch'); | ||
@@ -61,3 +65,3 @@ index.auto('http://remote.com/image.jpg').then((data) => { | ||
it('it should call fetch.remote if first path passed is remote', (done) => { | ||
const fetchRemoteStub = sandbox.stub(remote, 'fetch', () => Promise.resolve('image-data')); | ||
const fetchRemoteStub = sandbox.stub(remote, 'fetch').callsFake(() => Promise.resolve('image-data')); | ||
const shouldNotBeCalled = sandbox.spy(local, 'fetch'); | ||
@@ -73,3 +77,3 @@ index.auto('http://thisisremote.com/', '/paths/', '/image.gif').then((data) => { | ||
it('it should call fetch.local if first path passed is local', (done) => { | ||
const fetchLocalStub = sandbox.stub(local, 'fetch', () => Promise.resolve('image-data')); | ||
const fetchLocalStub = sandbox.stub(local, 'fetch').callsFake(() => Promise.resolve('image-data')); | ||
const shouldNotBeCalled = sandbox.spy(remote, 'fetch'); | ||
@@ -87,9 +91,11 @@ index.auto('/localPath/', '/paths/', '/image.gif').then((data) => { | ||
it('should always return a promise', () => { | ||
assert(typeof index.local('non-existant-path').then === 'function'); | ||
assert(typeof index.local().then === 'function'); | ||
const local1 = index.local('non-existant-path'); | ||
const local2 = index.local(); | ||
assert(typeof local1.then === 'function'); | ||
assert(typeof local2.then === 'function'); | ||
Promise.all([local1, local2]).catch(swallow); | ||
}); | ||
it('should return a rejected promise if there is an issue retrieveing the image', (done) => { | ||
const localFecthStub = sandbox.stub( | ||
local, 'fetch', () => Promise.reject('error getting image') | ||
); | ||
const localFecthStub = sandbox.stub(local, 'fetch') | ||
.callsFake(() => Promise.reject('error getting image')); | ||
index.local('path/to/existing-image.gif').catch((res) => { | ||
@@ -102,3 +108,3 @@ assert.equal(res, 'error getting image'); | ||
it('should call local.fetch() for local files', (done) => { | ||
const localFetchStub = sandbox.stub(local, 'fetch', () => Promise.resolve('gif-data')); | ||
const localFetchStub = sandbox.stub(local, 'fetch').callsFake(() => Promise.resolve('gif-data')); | ||
const shouldNotBeCalled = sandbox.spy(remote, 'fetch'); | ||
@@ -113,3 +119,3 @@ index.local('/root/', '/path/to/existing-image.gif').then((res) => { | ||
it('should handle multiple paths correctly', (done) => { | ||
const localFetchStub = sandbox.stub(local, 'fetch', () => Promise.resolve('gif-data')); | ||
const localFetchStub = sandbox.stub(local, 'fetch').callsFake(() => Promise.resolve('gif-data')); | ||
const shouldNotBeCalled = sandbox.spy(remote, 'fetch'); | ||
@@ -131,8 +137,10 @@ index.local('/root/', '/another/path/', '/path/to/existing-image.gif').then((res) => { | ||
it('should always return a promise', () => { | ||
assert(typeof index.remote(true, 'non-existant-path').then === 'function'); | ||
assert(typeof index.remote(true).then === 'function'); | ||
assert(typeof index.remote().then === 'function'); | ||
const remote1 = index.remote('non-existant-path'); | ||
const remote2 = index.remote(); | ||
assert(typeof remote1.then === 'function'); | ||
assert(typeof remote2.then === 'function'); | ||
Promise.all([remote1, remote2]).catch(swallow); | ||
}); | ||
it('should return a rejected promise if there is an issue retrieveing the file', (done) => { | ||
const remoteFecthStub = sandbox.stub(remote, 'fetch', () => Promise.reject('error getting image')); | ||
const remoteFecthStub = sandbox.stub(remote, 'fetch').callsFake(() => Promise.reject('error getting image')); | ||
index.remote('https://domain.com/to/existing-image.gif').catch((reason) => { | ||
@@ -145,3 +153,3 @@ assert.equal(reason, 'error getting image'); | ||
it('should call remote.fetch() for remote files', (done) => { | ||
const remoteFecthStub = sandbox.stub(remote, 'fetch', () => Promise.resolve('gif-data')); | ||
const remoteFecthStub = sandbox.stub(remote, 'fetch').callsFake(() => Promise.resolve('gif-data')); | ||
const shouldNotBeCalled = sandbox.spy(local, 'fetch'); | ||
@@ -148,0 +156,0 @@ index.remote('https://deomain.com/to/existing-image.gif').then((res) => { |
@@ -10,2 +10,4 @@ 'use strict'; | ||
function swallow() {} | ||
describe('fetchLocal (Unit)', () => { | ||
@@ -19,4 +21,7 @@ beforeEach(() => { | ||
it('should always return a promise', () => { | ||
assert(typeof fetchLocal.fetch('something').then === 'function'); | ||
assert(typeof fetchLocal.fetch().then === 'function'); | ||
const local1 = fetchLocal.fetch('something'); | ||
const local2 = fetchLocal.fetch(); | ||
assert(typeof local1.then === 'function'); | ||
assert(typeof local2.then === 'function'); | ||
Promise.all([local1, local2]).catch(swallow); | ||
}); | ||
@@ -43,2 +48,12 @@ it('should call fs.readFile with correct path', (done) => { | ||
}); | ||
it('should return a rejected promise when parameter is wrong type', (done) => { | ||
const fsStub = sandbox.stub(fs, 'readFile'); | ||
const shouldNotBeCalled = sandbox.spy(); | ||
fetchLocal.fetch(() => {}).then(shouldNotBeCalled, (error) => { | ||
assert.equal(error, 'TypeError: Path must be a string. Received [Function]'); | ||
assert.equal(fsStub.callCount, 0); | ||
assert.equal(shouldNotBeCalled.callCount, 0); | ||
done(); | ||
}).catch((e) => done(e)); | ||
}); | ||
}); |
@@ -7,3 +7,4 @@ 'use strict'; | ||
const http = require('http'); | ||
const url = require('url'); | ||
const https = require('https'); | ||
const legacyUrl = require('url'); | ||
const PassThrough = require('stream').PassThrough; | ||
@@ -14,3 +15,3 @@ | ||
let response; | ||
let httpRequestStub; | ||
let requestStub; | ||
@@ -25,7 +26,9 @@ function setupReqRes(statusCode) { | ||
function setupSuccessfulResponseMock(sb) { | ||
function setupSuccessfulResponseMock(sb, agent) { | ||
setupReqRes(200); | ||
httpRequestStub = sb.stub(http, 'request').callsArgWith(1, response).returns(request); | ||
requestStub = sb.stub(agent, 'request').callsArgWith(1, response).returns(request); | ||
} | ||
function swallow() {} | ||
describe('fetchRemote (Unit)', () => { | ||
@@ -39,18 +42,10 @@ beforeEach(() => { | ||
it('should always return a promise', () => { | ||
assert(typeof fetchRemote.fetch('something').then === 'function'); | ||
assert(typeof fetchRemote.fetch().then === 'function'); | ||
const remote1 = fetchRemote.fetch('something'); | ||
const remote2 = fetchRemote.fetch(); | ||
assert(typeof remote1.then === 'function'); | ||
assert(typeof remote2.then === 'function'); | ||
Promise.all([remote1, remote2]).catch(swallow); | ||
}); | ||
it('should call url.parse with correct url', (done) => { | ||
const urlStub = sandbox.stub(url, 'parse', () => ({ prop1: 'value1' })); | ||
// setup http.requests stubs | ||
setupSuccessfulResponseMock(sandbox); | ||
fetchRemote.fetch('http://url.com/existing-image.gif').then(() => { | ||
assert(urlStub.calledOnce); | ||
assert(urlStub.calledWith('http://url.com/existing-image.gif')); | ||
done(); | ||
}).catch((e) => done(e)); | ||
}); | ||
it('should call http.request with correct url and options', (done) => { | ||
setupSuccessfulResponseMock(sandbox); | ||
sandbox.stub(url, 'parse', () => ({})); | ||
setupSuccessfulResponseMock(sandbox, http); | ||
fetchRemote.fetch('http://url.com/existing-image.gif').then(() => { | ||
@@ -61,4 +56,4 @@ const expectedOptions = { | ||
}; | ||
assert(httpRequestStub.calledOnce); | ||
sinon.assert.calledWith(httpRequestStub, | ||
assert(requestStub.calledOnce); | ||
sinon.assert.calledWith(requestStub, | ||
sinon.match(expectedOptions), | ||
@@ -71,9 +66,7 @@ sinon.match.typeOf('function') | ||
it('should call url.resolve if several paths passed', (done) => { | ||
setupSuccessfulResponseMock(sandbox); | ||
const urlParseStub = sandbox.stub(url, 'parse', () => ({})); | ||
const urlResolveStub = sandbox.stub(url, 'resolve', () => 'http://url.com/existing-image.gif'); | ||
setupSuccessfulResponseMock(sandbox, http); | ||
const urlResolveStub = sandbox.stub(legacyUrl, 'resolve').callsFake(() => 'http://url.com/existing-image.gif'); | ||
fetchRemote.fetch('http://url.com', '/existing-image.gif').then(() => { | ||
assert(urlResolveStub.calledOnce); | ||
sinon.assert.calledWith(urlResolveStub, 'http://url.com', '/existing-image.gif'); | ||
assert(urlParseStub.calledWith('http://url.com/existing-image.gif')); | ||
done(); | ||
@@ -83,16 +76,18 @@ }).catch((e) => done(e)); | ||
it('should not call url.resolve if only one path passed', (done) => { | ||
setupSuccessfulResponseMock(sandbox); | ||
const urlParseStub = sandbox.stub(url, 'parse', () => ({})); | ||
const urlResolveStub = sandbox.stub(url, 'resolve', () => ({})); | ||
setupSuccessfulResponseMock(sandbox, http); | ||
const urlResolveStub = sandbox.stub(legacyUrl, 'resolve').callsFake(() => ({})); | ||
fetchRemote.fetch('http://url.com/image.gif').then(() => { | ||
assert.equal(urlResolveStub.callCount, 0); | ||
assert(urlParseStub.calledOnce); | ||
sinon.assert.calledWith(urlParseStub, 'http://url.com/image.gif'); | ||
done(); | ||
}).catch((e) => done(e)); | ||
}); | ||
describe('http.request', () => { | ||
describe('http', () => { | ||
it('should be called for http resources', (done) => { | ||
setupSuccessfulResponseMock(sandbox, http); | ||
fetchRemote.fetch('http://gamell.io/sprite.png').then(() => { | ||
assert.equal(requestStub.callCount, 1); | ||
done(); | ||
}).catch((e) => done(e)); | ||
}); | ||
it('should return with expected error', (done) => { | ||
setupReqRes(200); | ||
sandbox.stub(url, 'parse', () => ({})); | ||
const shouldNotBeCalled = sinon.spy(); | ||
@@ -105,2 +100,18 @@ fetchRemote.fetch('http://127.0.0.1/existing-image.gif').then(shouldNotBeCalled, (error) => { | ||
}); | ||
describe('https', () => { | ||
it('should be called for https resources', (done) => { | ||
setupSuccessfulResponseMock(sandbox, https); | ||
fetchRemote.fetch('https://gamell.io/sprite.png').then(() => { | ||
assert.equal(requestStub.callCount, 1); | ||
done(); | ||
}).catch((e) => done(e)); | ||
}); | ||
it('should return with expected error', (done) => { | ||
const shouldNotBeCalled = sinon.spy(); | ||
fetchRemote.fetch('https://127.0.0.1/existing-image.gif').then(shouldNotBeCalled, (error) => { | ||
assert.equal(error, 'HTTP Request error: Error: connect ECONNREFUSED 127.0.0.1:443'); | ||
done(); | ||
}).catch((e) => done(e)); | ||
}); | ||
}); | ||
}); |
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
NPM Shrinkwrap
Supply chain riskPackage contains a shrinkwrap file. This may allow the package to bypass normal install procedures.
Found 1 instance in 1 package
31654
7
574
160
0
17
Updatedmime-types@^2.1.15