diff --git a/_cp.bat b/bat/cp.bat similarity index 100% rename from _cp.bat rename to bat/cp.bat diff --git a/_mkdir.bat b/bat/mkdir.bat similarity index 100% rename from _mkdir.bat rename to bat/mkdir.bat diff --git a/_rm.bat b/bat/rm.bat similarity index 100% rename from _rm.bat rename to bat/rm.bat diff --git a/index.js b/index.js index 5b34da5..194cacf 100644 --- a/index.js +++ b/index.js @@ -2,40 +2,28 @@ const path = require('path'); - -const rootPath = __dirname.replace(/\\/g, '/'); - -const nanInclude = path.dirname(require.resolve('nan')).replace(/\\/g, '/'); -const thisInclude = `${rootPath}/include`; +const download = require('./js/download'); -const isWindows = process.platform === 'win32'; - -const names = ['win32', 'win64', 'linux32', 'linux64', 'mac64']; +const NAMES = ['win32', 'win64', 'linux64', 'mac64']; const prefixName = name => `bin-${name}`; -const getPlatformDir = platform => { - switch (platform) { - case 'win32' : return process.arch === 'x64' ? 'win64' : 'win32'; - case 'linux' : - if (process.arch === 'x32') { - throw new Error('Linux x32 not supported since 4.0.0.'); - } - return 'linux64'; - case 'darwin' : - if (process.arch === 'x32') { - throw new Error('Mac x32 not supported.'); - } - return 'mac64'; - default : throw new Error(`Platform "${platform}" is not supported.`); +const getPlatformDir = () => { + switch (process.platform) { + case 'win32' : return process.arch === 'x64' ? 'win64' : 'win32'; + case 'linux' : return 'linux64'; + case 'darwin' : return 'mac64'; + default : throw new Error(`Platform "${process.platform}" is not supported.`); } }; - -const currentDir = prefixName(getPlatformDir(process.platform)); -const remDirs = names.map(prefixName).filter(n => n !== currentDir); - +const rootPath = __dirname.replace(/\\/g, '/'); +const nanInclude = path.dirname(require.resolve('nan')).replace(/\\/g, '/'); +const thisInclude = `${rootPath}/include`; +const isWindows = process.platform === 'win32'; +const currentDir = prefixName(getPlatformDir()); +const remDirs = NAMES.map(prefixName).filter(n => n !== currentDir); const paths = dir => { @@ -68,9 +56,9 @@ const paths = dir => { const includePath = `${nanInclude} ${thisInclude}`; const binPath = currentDir; -const mkdirPath = isWindows ? `${rootPath}/_mkdir.bat` : 'mkdir'; -const rmPath = isWindows ? `${rootPath}/_rm.bat` : 'rm'; -const cpPath = isWindows ? `${rootPath}/_cp.bat` : 'cp'; +const mkdirPath = isWindows ? `${rootPath}/bat/mkdir.bat` : 'mkdir'; +const rmPath = isWindows ? `${rootPath}/bat/rm.bat` : 'rm'; +const cpPath = isWindows ? `${rootPath}/bat/cp.bat` : 'cp'; module.exports = { diff --git a/js/download.js b/js/download.js new file mode 100644 index 0000000..80a2a9c --- /dev/null +++ b/js/download.js @@ -0,0 +1,30 @@ +'use strict'; + +const https = require('https'); +const http = require('http'); + +const WritableBuffer = require('./writable-buffer'); + + +const protocols = { http, https }; + + +module.exports = url => new Promise( + (res, rej) => { + + url = url.toLowerCase(); + + const stream = new WritableBuffer(); + const proto = protocols[url.match(/^https?/)[0]]; + + proto.get(url, response => { + + response.pipe(stream); + + response.on('end', () => res(stream.get())); + response.on('error', err => rej(err)); + + }); + + } +); diff --git a/js/writable-buffer.js b/js/writable-buffer.js new file mode 100644 index 0000000..87db2ac --- /dev/null +++ b/js/writable-buffer.js @@ -0,0 +1,65 @@ +'use strict'; + +const { Writable } = require('stream'); + +const CHUNK_SIZE = 1024; +const INITIAL_SIZE = 8 * CHUNK_SIZE; +const INCREMENT_SIZE = 8 * CHUNK_SIZE; + + +class WritableBuffer extends Writable { + + constructor() { + + super(); + + this._buffer = new Buffer(INITIAL_SIZE); + this._size = 0; + + } + + get() { + + if ( ! this._size ) { + return null; + } + + const data = new Buffer(this._size); + this._buffer.copy(data, 0, 0, this._size); + + return data; + + } + + + _increaseAsNeeded(incomingSize) { + + if ( (this._buffer.length - this._size) >= incomingSize ) { + return; + } + + const freeSpace = this._buffer.length - this._size; + const factor = Math.ceil((incomingSize - freeSpace) / INCREMENT_SIZE); + + const newBuffer = new Buffer(this._buffer.length + (INCREMENT_SIZE * factor)); + this._buffer.copy(newBuffer, 0, 0, this._size); + + this._buffer = newBuffer; + + } + + + _write(chunk, encoding, callback) { + + this._increaseAsNeeded(chunk.length); + + chunk.copy(this._buffer, this._size, 0); + this._size += chunk.length; + + callback(); + + } + +} + +module.exports = WritableBuffer;