diff --git a/linux/ReadMe.txt b/linux/ReadMe.txt new file mode 100644 index 0000000..d33c01c --- /dev/null +++ b/linux/ReadMe.txt @@ -0,0 +1,5 @@ +To install the native application + 1. Open a terminal window and point it into this directory + 2. run ./install.sh + +Note: The script needs administrator permission (sudo) to copy files successfully. diff --git a/linux/app/host.js b/linux/app/host.js new file mode 100755 index 0000000..85d1302 --- /dev/null +++ b/linux/app/host.js @@ -0,0 +1,69 @@ +'use strict'; + +var spawn = require('child_process').spawn; + +var config = { + version: '0.1.0', + isWin: /^win/.test(process.platform) +}; + +function observe (msg, push, done) { + if (msg.cmd === 'version') { + push({ + version: config.version + }); + done(); + } + else if (msg.cmd === 'echo') { + push(msg); + done(); + } + else if (msg.cmd === 'spawn') { + let sp = spawn(msg.command, msg.arguments); + sp.stdout.on('data', stdout => push({stdout})); + sp.stderr.on('data', stderr => push({stderr})); + sp.on('close', (code) => { + push({code}); + done(); + }); + } + else if (msg.cmd === 'exec') { + let sp = spawn(msg.command, msg.arguments); + let stderr = '', stdout = ''; + sp.stdout.on('data', data => stdout += data); + sp.stderr.on('data', data => stderr += data); + sp.on('close', (code) => { + push({ + code, + stderr, + stdout + }); + done(); + }); + } + else if (msg.cmd === 'env') { + push({ + env: process.env + }); + done(); + } + else { + push({ + error: 'cmd is unknown', + cmd: msg.cmd + }); + done(); + } +} +/* message passing */ +var nativeMessage = require('./messaging'); + +var input = new nativeMessage.Input(); +var transform = new nativeMessage.Transform(observe); +var output = new nativeMessage.Output(); + +process.stdin + .pipe(input) + .pipe(transform) + .pipe(output) + .pipe(process.stdout); diff --git a/linux/app/install.js b/linux/app/install.js new file mode 100644 index 0000000..18c7224 --- /dev/null +++ b/linux/app/install.js @@ -0,0 +1,115 @@ +'use strict'; + +var fs = require('fs'); +var path = require('path'); + +function exists (directory, callback) { + let root = '/'; + let dirs = directory.split('/'); + function one () { + root = path.join(root, dirs.shift()); + fs.stat(root, (e) => { + if (!e && dirs.length) { + one(); + } + else if (e && e.code === 'ENOENT') { + fs.mkdir(root, (e) => { + if (e) { + callback(e); + } + else if (dirs.length) { + one(); + } + else { + callback(); + } + }); + } + else { + callback(e); + } + }); + } + one(); +} + +var dir = path.join('/usr/share', 'com.add0n.node'); +var name = 'com.add0n.node'; +var ids = { + chrome: ['mbpegmnngblolkfjoegdinohffomfljn'], + firefox: ['something@mozilla.org'] +}; + +function manifest (root, type, callback) { + exists(root, (e) => { + if (e) { + throw e; + } + let origins; + if (type === 'chrome') { + origins = '"allowed_origins": ' + JSON.stringify(ids.chrome.map(id => 'chrome-extension://' + id + '/')); + } + else { + origins = '"allowed_extensions": ' + JSON.stringify(ids.firefox); + } + fs.writeFile(path.join(root, name + '.json'), `{ + "name": "${name}", + "description": "Node Host for Native Messaging", + "path": "${path.join(dir, 'run.sh')}", + "type": "stdio", + ${origins} + }`, (e) => { + if (e) { + throw e; + } + callback(); + }); + + }); +} +function application (callback) { + exists(dir, (e) => { + if (e) { + throw e; + } + let isNode = process.argv[2] !== '--add_node'; + let run = isNode ? '#!/bin/bash\nnode host.js' : '#!/bin/bash\n./node host.js'; + fs.writeFile(path.join(dir, 'run.sh'), run, (e) => { + if (e) { + throw e; + } + fs.chmodSync(path.join(dir, 'run.sh'), '0755'); + if (!isNode) { + fs.createReadStream('../node').pipe(fs.createWriteStream(path.join(dir, 'node'))); + fs.chmodSync(path.join(dir, 'node'), '0755'); + } + fs.createReadStream('host.js').pipe(fs.createWriteStream(path.join(dir, 'host.js'))); + fs.createReadStream('messaging.js').pipe(fs.createWriteStream(path.join(dir, 'messaging.js'))); + callback(); + }); + }); +} +function chrome (callback) { + if (ids.chrome.length) { + manifest('/etc/opt/chrome/native-messaging-hosts', 'chrome', callback); + console.error('Chrome Browser is supported'); + } + else { + callback(); + } +} +function firefox (callback) { + if (ids.firefox.length) { + manifest('/usr/lib/mozilla/native-messaging-hosts', 'firefox', callback); + console.error('Firefox Browser is supported'); + } + else { + callback(); + } +} +chrome(() => firefox(() => { + application(() => { + console.error('Native Host is installed in', dir); + console.error('>> Application is ready to use <<'); + }); +})); diff --git a/linux/app/messaging.js b/linux/app/messaging.js new file mode 100644 index 0000000..d62ec9c --- /dev/null +++ b/linux/app/messaging.js @@ -0,0 +1,128 @@ +// chrome-native-messaging module +// +// Defines three Transform streams: +// +// - Input - transform native messages to JavaScript objects +// - Output - transform JavaScript objects to native messages +// - Transform - transform message objects to reply objects +// - Debug - transform JavaScript objects to lines of JSON (for debugging, obviously) + +var stream = require('stream'); +var util = require('util'); + +function Input() { + stream.Transform.call(this); + + // Transform bytes... + this._writableState.objectMode = false; + // ...into objects. + this._readableState.objectMode = true; + + // Unparsed data. + this.buf = new Buffer(0); + // Parsed length. + this.len = null; +} + +util.inherits(Input, stream.Transform); + +Input.prototype._transform = function(chunk, encoding, done) { + // Save this chunk. + this.buf = Buffer.concat([ this.buf, chunk ]); + + var self = this; + + function parseBuf() { + // Do we have a length yet? + if (typeof self.len !== 'number') { + // Nope. Do we have enough bytes for the length? + if (self.buf.length >= 4) { + // Yep. Parse the bytes. + self.len = self.buf.readUInt32LE(0); + // Remove the length bytes from the buffer. + self.buf = self.buf.slice(4); + } + } + + // Do we have a length yet? (We may have just parsed it.) + if (typeof self.len === 'number') { + // Yep. Do we have enough bytes for the message? + if (self.buf.length >= self.len) { + // Yep. Slice off the bytes we need. + var message = self.buf.slice(0, self.len); + // Remove the bytes for the message from the buffer. + self.buf = self.buf.slice(self.len); + // Clear the length so we know we need to parse it again. + self.len = null; + // Parse the message bytes. + var obj = JSON.parse(message.toString()); + // Enqueue it for reading. + self.push(obj); + // We could have more messages in the buffer so check again. + parseBuf(); + } + } + } + + // Check for a parsable buffer (both length and message). + parseBuf(); + + // We're done. + done(); +}; + +function Output() { + stream.Transform.call(this); + + this._writableState.objectMode = true; + this._readableState.objectMode = false; +} + +util.inherits(Output, stream.Transform); + +Output.prototype._transform = function(chunk, encoding, done) { + var len = new Buffer(4); + var buf = new Buffer(JSON.stringify(chunk)); + + len.writeUInt32LE(buf.length, 0); + + this.push(len); + this.push(buf); + + done(); +}; + +function Transform(handler) { + stream.Transform.call(this); + + this._writableState.objectMode = true; + this._readableState.objectMode = true; + + this.handler = handler; +} + +util.inherits(Transform, stream.Transform); + +Transform.prototype._transform = function(msg, encoding, done) { + this.handler(msg, this.push.bind(this), done); +}; + +function Debug() { + stream.Transform.call(this); + + this._writableState.objectMode = true; + this._readableState.objectMode = false; +} + +util.inherits(Debug, stream.Transform); + +Debug.prototype._transform = function(chunk, encoding, done) { + this.push(JSON.stringify(chunk) + '\n'); + + done(); +}; + +exports.Input = Input; +exports.Output = Output; +exports.Transform = Transform; +exports.Debug = Debug; diff --git a/linux/install.sh b/linux/install.sh new file mode 100755 index 0000000..9222530 --- /dev/null +++ b/linux/install.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +cd ./app + +if type node 2>/dev/null; then + echo Installer is using your system node.js + sudo node install.js +else + echo Installer is using the attached node.js + sudo ../node install.js --add_node +fi + diff --git a/linux/node b/linux/node new file mode 100755 index 0000000..4e394ab Binary files /dev/null and b/linux/node differ diff --git a/mac/ReadMe.txt b/mac/ReadMe.txt new file mode 100644 index 0000000..d33c01c --- /dev/null +++ b/mac/ReadMe.txt @@ -0,0 +1,5 @@ +To install the native application + 1. Open a terminal window and point it into this directory + 2. run ./install.sh + +Note: The script needs administrator permission (sudo) to copy files successfully. diff --git a/mac/app/host.js b/mac/app/host.js new file mode 100755 index 0000000..85d1302 --- /dev/null +++ b/mac/app/host.js @@ -0,0 +1,69 @@ +'use strict'; + +var spawn = require('child_process').spawn; + +var config = { + version: '0.1.0', + isWin: /^win/.test(process.platform) +}; + +function observe (msg, push, done) { + if (msg.cmd === 'version') { + push({ + version: config.version + }); + done(); + } + else if (msg.cmd === 'echo') { + push(msg); + done(); + } + else if (msg.cmd === 'spawn') { + let sp = spawn(msg.command, msg.arguments); + sp.stdout.on('data', stdout => push({stdout})); + sp.stderr.on('data', stderr => push({stderr})); + sp.on('close', (code) => { + push({code}); + done(); + }); + } + else if (msg.cmd === 'exec') { + let sp = spawn(msg.command, msg.arguments); + let stderr = '', stdout = ''; + sp.stdout.on('data', data => stdout += data); + sp.stderr.on('data', data => stderr += data); + sp.on('close', (code) => { + push({ + code, + stderr, + stdout + }); + done(); + }); + } + else if (msg.cmd === 'env') { + push({ + env: process.env + }); + done(); + } + else { + push({ + error: 'cmd is unknown', + cmd: msg.cmd + }); + done(); + } +} +/* message passing */ +var nativeMessage = require('./messaging'); + +var input = new nativeMessage.Input(); +var transform = new nativeMessage.Transform(observe); +var output = new nativeMessage.Output(); + +process.stdin + .pipe(input) + .pipe(transform) + .pipe(output) + .pipe(process.stdout); diff --git a/mac/app/install.js b/mac/app/install.js new file mode 100644 index 0000000..9b66dc8 --- /dev/null +++ b/mac/app/install.js @@ -0,0 +1,118 @@ +'use strict'; + +var fs = require('fs'); +var path = require('path'); + +function exists (directory, callback) { + let root = '/'; + let dirs = directory.split('/'); + function one () { + root = path.join(root, dirs.shift()); + fs.stat(root, (e) => { + if (!e && dirs.length) { + one(); + } + else if (e && e.code === 'ENOENT') { + fs.mkdir(root, (e) => { + if (e) { + callback(e); + } + else if (dirs.length) { + one(); + } + else { + callback(); + } + }); + } + else { + callback(e); + } + }); + } + one(); +} + +var dir = path.join('/usr/share', 'com.add0n.node'); +var name = 'com.add0n.node'; +var ids = { + chrome: ['pghoffeollloldpepedofbmlokimpblo'], + firefox: ['something@mozilla.org'] +}; + +function manifest (root, type, callback) { + exists(root, (e) => { + if (e) { + throw e; + } + + let origins; + if (type === 'chrome') { + origins = '"allowed_origins": ' + JSON.stringify(ids.chrome.map(id => 'chrome-extension://' + id + '/')); + } + else { + origins = '"allowed_extensions": ' + JSON.stringify(ids.firefox); + } + fs.writeFile(path.join(root, name + '.json'), `{ + "name": "${name}", + "description": "Node Host for Native Messaging", + "path": "${path.join(dir, 'run.sh')}", + "type": "stdio", + ${origins} +}`, (e) => { + if (e) { + throw e; + } + callback(); + }); + + }); +} +function application (callback) { + exists(dir, (e) => { + if (e) { + throw e; + } + + let isNode = process.argv[2] !== '--add_node'; + let run = isNode ? '#!/bin/bash\nnode host.js' : '#!/bin/bash\n./node host.js'; + fs.writeFile(path.join(dir, 'run.sh'), run, (e) => { + if (e) { + throw e; + } + fs.chmodSync(path.join(dir, 'run.sh'), '0755'); + if (!isNode) { + fs.createReadStream('../node').pipe(fs.createWriteStream(path.join(dir, 'node'))); + fs.chmodSync(path.join(dir, 'node'), '0755'); + } + fs.createReadStream('host.js').pipe(fs.createWriteStream(path.join(dir, 'host.js'))); + fs.createReadStream('messaging.js').pipe(fs.createWriteStream(path.join(dir, 'messaging.js'))); + callback(); + }); + }); +} + +function chrome (callback) { + if (ids.chrome.length) { + manifest('/Library/Google/Chrome/NativeMessagingHosts', 'chrome', callback); + console.error('Chrome Browser is supported'); + } + else { + callback(); + } +} +function firefox (callback) { + if (ids.firefox.length) { + manifest('/Library/Application Support/Mozilla/NativeMessagingHosts', 'firefox', callback); + console.error('Firefox Browser is supported'); + } + else { + callback(); + } +} +chrome(() => firefox(() => { + application(() => { + console.error('Native Host is installed in', dir); + console.error('>> Application is ready to use <<'); + }); +})); diff --git a/mac/app/messaging.js b/mac/app/messaging.js new file mode 100644 index 0000000..d62ec9c --- /dev/null +++ b/mac/app/messaging.js @@ -0,0 +1,128 @@ +// chrome-native-messaging module +// +// Defines three Transform streams: +// +// - Input - transform native messages to JavaScript objects +// - Output - transform JavaScript objects to native messages +// - Transform - transform message objects to reply objects +// - Debug - transform JavaScript objects to lines of JSON (for debugging, obviously) + +var stream = require('stream'); +var util = require('util'); + +function Input() { + stream.Transform.call(this); + + // Transform bytes... + this._writableState.objectMode = false; + // ...into objects. + this._readableState.objectMode = true; + + // Unparsed data. + this.buf = new Buffer(0); + // Parsed length. + this.len = null; +} + +util.inherits(Input, stream.Transform); + +Input.prototype._transform = function(chunk, encoding, done) { + // Save this chunk. + this.buf = Buffer.concat([ this.buf, chunk ]); + + var self = this; + + function parseBuf() { + // Do we have a length yet? + if (typeof self.len !== 'number') { + // Nope. Do we have enough bytes for the length? + if (self.buf.length >= 4) { + // Yep. Parse the bytes. + self.len = self.buf.readUInt32LE(0); + // Remove the length bytes from the buffer. + self.buf = self.buf.slice(4); + } + } + + // Do we have a length yet? (We may have just parsed it.) + if (typeof self.len === 'number') { + // Yep. Do we have enough bytes for the message? + if (self.buf.length >= self.len) { + // Yep. Slice off the bytes we need. + var message = self.buf.slice(0, self.len); + // Remove the bytes for the message from the buffer. + self.buf = self.buf.slice(self.len); + // Clear the length so we know we need to parse it again. + self.len = null; + // Parse the message bytes. + var obj = JSON.parse(message.toString()); + // Enqueue it for reading. + self.push(obj); + // We could have more messages in the buffer so check again. + parseBuf(); + } + } + } + + // Check for a parsable buffer (both length and message). + parseBuf(); + + // We're done. + done(); +}; + +function Output() { + stream.Transform.call(this); + + this._writableState.objectMode = true; + this._readableState.objectMode = false; +} + +util.inherits(Output, stream.Transform); + +Output.prototype._transform = function(chunk, encoding, done) { + var len = new Buffer(4); + var buf = new Buffer(JSON.stringify(chunk)); + + len.writeUInt32LE(buf.length, 0); + + this.push(len); + this.push(buf); + + done(); +}; + +function Transform(handler) { + stream.Transform.call(this); + + this._writableState.objectMode = true; + this._readableState.objectMode = true; + + this.handler = handler; +} + +util.inherits(Transform, stream.Transform); + +Transform.prototype._transform = function(msg, encoding, done) { + this.handler(msg, this.push.bind(this), done); +}; + +function Debug() { + stream.Transform.call(this); + + this._writableState.objectMode = true; + this._readableState.objectMode = false; +} + +util.inherits(Debug, stream.Transform); + +Debug.prototype._transform = function(chunk, encoding, done) { + this.push(JSON.stringify(chunk) + '\n'); + + done(); +}; + +exports.Input = Input; +exports.Output = Output; +exports.Transform = Transform; +exports.Debug = Debug; diff --git a/mac/install.sh b/mac/install.sh new file mode 100755 index 0000000..9222530 --- /dev/null +++ b/mac/install.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +cd ./app + +if type node 2>/dev/null; then + echo Installer is using your system node.js + sudo node install.js +else + echo Installer is using the attached node.js + sudo ../node install.js --add_node +fi + diff --git a/mac/node b/mac/node new file mode 100755 index 0000000..ac3b433 Binary files /dev/null and b/mac/node differ diff --git a/windows/ReadMe.txt b/windows/ReadMe.txt new file mode 100644 index 0000000..8b20042 --- /dev/null +++ b/windows/ReadMe.txt @@ -0,0 +1,5 @@ +To install the native application + 1. Right-click on "install.bat" and use "Run as Administrator" + 2. Wait for the script to display the successful message. + +Note: The script needs administrator permission to copy files successfully. diff --git a/windows/app/host.js b/windows/app/host.js new file mode 100755 index 0000000..85d1302 --- /dev/null +++ b/windows/app/host.js @@ -0,0 +1,69 @@ +'use strict'; + +var spawn = require('child_process').spawn; + +var config = { + version: '0.1.0', + isWin: /^win/.test(process.platform) +}; + +function observe (msg, push, done) { + if (msg.cmd === 'version') { + push({ + version: config.version + }); + done(); + } + else if (msg.cmd === 'echo') { + push(msg); + done(); + } + else if (msg.cmd === 'spawn') { + let sp = spawn(msg.command, msg.arguments); + sp.stdout.on('data', stdout => push({stdout})); + sp.stderr.on('data', stderr => push({stderr})); + sp.on('close', (code) => { + push({code}); + done(); + }); + } + else if (msg.cmd === 'exec') { + let sp = spawn(msg.command, msg.arguments); + let stderr = '', stdout = ''; + sp.stdout.on('data', data => stdout += data); + sp.stderr.on('data', data => stderr += data); + sp.on('close', (code) => { + push({ + code, + stderr, + stdout + }); + done(); + }); + } + else if (msg.cmd === 'env') { + push({ + env: process.env + }); + done(); + } + else { + push({ + error: 'cmd is unknown', + cmd: msg.cmd + }); + done(); + } +} +/* message passing */ +var nativeMessage = require('./messaging'); + +var input = new nativeMessage.Input(); +var transform = new nativeMessage.Transform(observe); +var output = new nativeMessage.Output(); + +process.stdin + .pipe(input) + .pipe(transform) + .pipe(output) + .pipe(process.stdout); diff --git a/windows/app/install.js b/windows/app/install.js new file mode 100644 index 0000000..7e5b230 --- /dev/null +++ b/windows/app/install.js @@ -0,0 +1,86 @@ +'use strict'; + +var fs = require('fs'); +var path = require('path'); + +function exists (directory, callback) { + fs.stat(directory, (e) => { + + if (e && e.code === 'ENOENT') { + fs.mkdir(directory, callback); + } + else { + callback(e); + } + }); +} + +var dir = path.join(process.argv[2], 'com.add0n.node'); +var name = 'com.add0n.node'; +var ids = { + chrome: ['gfhloibcnnngmfkpnpbbgblbgcghaapb'], + firefox: ['something@mozilla.org'] +}; + +function manifest (type, callback) { + exists(dir, (e) => { + if (e) { + throw e; + } + let origins; + if (type === 'chrome') { + origins = '"allowed_origins": ' + JSON.stringify(ids.chrome.map(id => 'chrome-extension://' + id + '/')); + } + else { + origins = '"allowed_extensions": ' + JSON.stringify(ids.firefox); + } + fs.writeFile(path.join(dir, 'manifest-' + type + '.json'), `{ + "name": "${name}", + "description": "Node Host for Native Messaging", + "path": "run.bat", + "type": "stdio", + ${origins} +}`, (e) => { + if (e) { + throw e; + } + callback(); + }); + }); +} +function application (callback) { + fs.writeFile(path.join(dir, 'run.bat'), `@echo off\n\n"%~dp0node.exe" "%~dp0host.js"`, (e) => { + if (e) { + throw e; + } + fs.createReadStream('..\\node.exe').pipe(fs.createWriteStream(path.join(dir, 'node.exe'))); + fs.createReadStream('host.js').pipe(fs.createWriteStream(path.join(dir, 'host.js'))); + fs.createReadStream('messaging.js').pipe(fs.createWriteStream(path.join(dir, 'messaging.js'))); + callback(); + }); +} + +function chrome (callback) { + if (ids.chrome.length) { + manifest('chrome', callback); + console.error('Chrome Browser is supported'); + } + else { + callback(); + } +} +function firefox (callback) { + if (ids.firefox.length) { + manifest('firefox', callback); + console.error('Firefox Browser is supported'); + } + else { + callback(); + } +} +chrome(() => firefox(() => { + application(() => { + console.error('Native Host is installed in', dir); + console.error('>> Application is ready to use <<'); + }); +})); diff --git a/windows/app/messaging.js b/windows/app/messaging.js new file mode 100644 index 0000000..d62ec9c --- /dev/null +++ b/windows/app/messaging.js @@ -0,0 +1,128 @@ +// chrome-native-messaging module +// +// Defines three Transform streams: +// +// - Input - transform native messages to JavaScript objects +// - Output - transform JavaScript objects to native messages +// - Transform - transform message objects to reply objects +// - Debug - transform JavaScript objects to lines of JSON (for debugging, obviously) + +var stream = require('stream'); +var util = require('util'); + +function Input() { + stream.Transform.call(this); + + // Transform bytes... + this._writableState.objectMode = false; + // ...into objects. + this._readableState.objectMode = true; + + // Unparsed data. + this.buf = new Buffer(0); + // Parsed length. + this.len = null; +} + +util.inherits(Input, stream.Transform); + +Input.prototype._transform = function(chunk, encoding, done) { + // Save this chunk. + this.buf = Buffer.concat([ this.buf, chunk ]); + + var self = this; + + function parseBuf() { + // Do we have a length yet? + if (typeof self.len !== 'number') { + // Nope. Do we have enough bytes for the length? + if (self.buf.length >= 4) { + // Yep. Parse the bytes. + self.len = self.buf.readUInt32LE(0); + // Remove the length bytes from the buffer. + self.buf = self.buf.slice(4); + } + } + + // Do we have a length yet? (We may have just parsed it.) + if (typeof self.len === 'number') { + // Yep. Do we have enough bytes for the message? + if (self.buf.length >= self.len) { + // Yep. Slice off the bytes we need. + var message = self.buf.slice(0, self.len); + // Remove the bytes for the message from the buffer. + self.buf = self.buf.slice(self.len); + // Clear the length so we know we need to parse it again. + self.len = null; + // Parse the message bytes. + var obj = JSON.parse(message.toString()); + // Enqueue it for reading. + self.push(obj); + // We could have more messages in the buffer so check again. + parseBuf(); + } + } + } + + // Check for a parsable buffer (both length and message). + parseBuf(); + + // We're done. + done(); +}; + +function Output() { + stream.Transform.call(this); + + this._writableState.objectMode = true; + this._readableState.objectMode = false; +} + +util.inherits(Output, stream.Transform); + +Output.prototype._transform = function(chunk, encoding, done) { + var len = new Buffer(4); + var buf = new Buffer(JSON.stringify(chunk)); + + len.writeUInt32LE(buf.length, 0); + + this.push(len); + this.push(buf); + + done(); +}; + +function Transform(handler) { + stream.Transform.call(this); + + this._writableState.objectMode = true; + this._readableState.objectMode = true; + + this.handler = handler; +} + +util.inherits(Transform, stream.Transform); + +Transform.prototype._transform = function(msg, encoding, done) { + this.handler(msg, this.push.bind(this), done); +}; + +function Debug() { + stream.Transform.call(this); + + this._writableState.objectMode = true; + this._readableState.objectMode = false; +} + +util.inherits(Debug, stream.Transform); + +Debug.prototype._transform = function(chunk, encoding, done) { + this.push(JSON.stringify(chunk) + '\n'); + + done(); +}; + +exports.Input = Input; +exports.Output = Output; +exports.Transform = Transform; +exports.Debug = Debug; diff --git a/windows/install.bat b/windows/install.bat new file mode 100644 index 0000000..28fac87 --- /dev/null +++ b/windows/install.bat @@ -0,0 +1,36 @@ +@echo off + +call :isAdmin + +if %errorlevel% == 0 ( + goto :run +) else ( + echo . + echo . + echo ************ERROR***************** + echo *******Run as administrator******* + echo ********************************** + echo . + echo . + pause +) + +exit /b + +:isAdmin +fsutil dirty query %systemdrive% >nul +exit /b + +:run + +copy +REG ADD "HKCU\Software\Google\Chrome\NativeMessagingHosts\com.add0n.node" /ve /t REG_SZ /d "%ProgramFiles%\com.add0n.node\manifest-chrome.json" /f + +for %%f in ("%PROGRAMFILES%") do SET SHORT_PATH=%%~sf +REG ADD "HKEY_LOCAL_MACHINE\SOFTWARE\Mozilla\NativeMessagingHosts\com.add0n.node" /ve /t REG_SZ /d "%SHORT_PATH%\com.add0n.node\manifest-firefox.json" /f + +pushd "%~dp0" +cd app +..\node.exe install.js "%ProgramFiles%" + +pause diff --git a/windows/node.exe b/windows/node.exe new file mode 100644 index 0000000..f2e09c9 Binary files /dev/null and b/windows/node.exe differ