Socket
Socket
Sign inDemoInstall

@serialport/bindings

Package Overview
Dependencies
Maintainers
2
Versions
34
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@serialport/bindings - npm Package Compare versions

Comparing version 2.0.8 to 3.0.0

lib/legacy.js

23

CHANGELOG.md

@@ -6,2 +6,25 @@ # Change Log

# [3.0.0](https://github.com/node-serialport/node-serialport/compare/@serialport/bindings@2.0.8...@serialport/bindings@3.0.0) (2019-05-16)
### Bug Fixes
* remove PURGE_RXABORT flag on flush for Windows ([#1817](https://github.com/node-serialport/node-serialport/issues/1817)) ([1daa919](https://github.com/node-serialport/node-serialport/commit/1daa919))
* RTS/CTS flow control for Windows ([#1809](https://github.com/node-serialport/node-serialport/issues/1809)) ([cd112ca](https://github.com/node-serialport/node-serialport/commit/cd112ca))
### chore
* remove node6 support and upgrade codebase ([#1851](https://github.com/node-serialport/node-serialport/issues/1851)) ([d4f15c0](https://github.com/node-serialport/node-serialport/commit/d4f15c0))
### BREAKING CHANGES
* flush behavior on windows no longer cancels inflight reads
* bindings now use async functions so they’ll never throw, only reject
## [2.0.8](https://github.com/node-serialport/node-serialport/compare/@serialport/bindings@2.0.7...@serialport/bindings@2.0.8) (2019-04-27)

@@ -8,0 +31,0 @@

15

lib/bindings-test.js

@@ -33,3 +33,3 @@ let platform

const listFields = ['comName', 'manufacturer', 'serialNumber', 'pnpId', 'locationId', 'vendorId', 'productId']
const listFields = ['path', 'manufacturer', 'serialNumber', 'pnpId', 'locationId', 'vendorId', 'productId']

@@ -92,2 +92,3 @@ const bindingsToTest = ['mock', platform]

})
assert.equal(port.comName, port.path)
})

@@ -184,5 +185,3 @@ })

it('cannot open if already open', () => {
const options = Object.assign({}, defaultOpenOptions, {
lock: false,
})
const options = { ...defaultOpenOptions, lock: false }
return binding.open(testPort, options).then(() => {

@@ -206,5 +205,3 @@ return binding.open(testPort, options).catch(err => {

describe(`${testBaud} baud`, () => {
const customRates = Object.assign({}, defaultOpenOptions, {
baudRate: testBaud,
})
const customRates = { ...defaultOpenOptions, baudRate: testBaud }
testFeature(`baudrate.${testBaud}`, `opens at ${testBaud} baud`, () => {

@@ -249,5 +246,3 @@ return binding.open(testPort, customRates).then(() => {

testFeature('open.unlock', 'can unlock the port', () => {
const noLock = Object.assign({}, defaultOpenOptions, {
lock: false,
})
const noLock = { ...defaultOpenOptions, lock: false }
const binding2 = new Binding({ disconnect })

@@ -254,0 +249,0 @@

@@ -31,6 +31,6 @@ const serialNumParser = require('./win32-sn-parser')

describe('serialNumParser', () => {
Object.keys(devices).forEach(device => {
Object.entries(devices).forEach(([device, info]) => {
it(`parses pnp id for ${device}`, () => {
const pnpId = devices[device].pnpId
const serialNumber = devices[device].serialNumber
const pnpId = info.pnpId
const serialNumber = info.serialNumber
assert.equal(serialNumParser(pnpId), serialNumber)

@@ -37,0 +37,0 @@ })

@@ -0,7 +1,8 @@

const { promisify } = require('util')
const binding = require('bindings')('bindings.node')
const AbstractBinding = require('@serialport/binding-abstract')
const Poller = require('./poller')
const promisify = require('./util').promisify
const unixRead = require('./unix-read')
const unixWrite = require('./unix-write')
const { wrapWithHiddenComName } = require('./legacy')

@@ -13,2 +14,12 @@ const defaultBindingOptions = Object.freeze({

const asyncList = promisify(binding.list)
const asyncOpen = promisify(binding.open)
const asyncClose = promisify(binding.close)
const asyncUpdate = promisify(binding.update)
const asyncSet = promisify(binding.set)
const asyncGet = promisify(binding.get)
const asyncGetBaudRate = promisify(binding.getBaudRate)
const asyncDrain = promisify(binding.drain)
const asyncFlush = promisify(binding.flush)
/**

@@ -19,3 +30,3 @@ * The Darwin binding layer for OSX

static list() {
return promisify(binding.list)()
return wrapWithHiddenComName(asyncList())
}

@@ -25,3 +36,3 @@

super(opt)
this.bindingOptions = Object.assign({}, defaultBindingOptions, opt.bindingOptions || {})
this.bindingOptions = { ...defaultBindingOptions, ...opt.bindingOptions }
this.fd = null

@@ -35,69 +46,68 @@ this.writeOperation = null

open(path, options) {
return super
.open(path, options)
.then(() => {
this.openOptions = Object.assign({}, this.bindingOptions, options)
return promisify(binding.open)(path, this.openOptions)
})
.then(fd => {
this.fd = fd
this.poller = new Poller(fd)
})
async open(path, options) {
await super.open(path, options)
this.openOptions = { ...this.bindingOptions, ...options }
const fd = await asyncOpen(path, this.openOptions)
this.fd = fd
this.poller = new Poller(fd)
}
close() {
return super.close().then(() => {
const fd = this.fd
this.poller.stop()
this.poller.destroy()
this.poller = null
this.openOptions = null
this.fd = null
return promisify(binding.close)(fd)
})
async close() {
await super.close()
const fd = this.fd
this.poller.stop()
this.poller.destroy()
this.poller = null
this.openOptions = null
this.fd = null
return asyncClose(fd)
}
read(buffer, offset, length) {
return super.read(buffer, offset, length).then(() => unixRead.call(this, buffer, offset, length))
async read(buffer, offset, length) {
await super.read(buffer, offset, length)
return unixRead.call(this, buffer, offset, length)
}
write(buffer) {
if (buffer.length > 0) {
this.writeOperation = super
.write(buffer)
.then(() => unixWrite.call(this, buffer))
.then(() => {
this.writeOperation = null
})
return this.writeOperation
async write(buffer) {
if (buffer.length === 0) {
return
}
return Promise.resolve()
this.writeOperation = super
.write(buffer)
.then(() => unixWrite.call(this, buffer))
.then(() => {
this.writeOperation = null
})
return this.writeOperation
}
update(options) {
return super.update(options).then(() => promisify(binding.update)(this.fd, options))
async update(options) {
await super.update(options)
return asyncUpdate(this.fd, options)
}
set(options) {
return super.set(options).then(() => promisify(binding.set)(this.fd, options))
async set(options) {
await super.set(options)
return asyncSet(this.fd, options)
}
get() {
return super.get().then(() => promisify(binding.get)(this.fd))
async get() {
await super.get()
return asyncGet(this.fd)
}
getBaudRate() {
return super.get().then(() => promisify(binding.getBaudRate)(this.fd))
async getBaudRate() {
await super.get()
return asyncGetBaudRate(this.fd)
}
drain() {
return super
.drain()
.then(() => Promise.resolve(this.writeOperation))
.then(() => promisify(binding.drain)(this.fd))
async drain() {
await super.drain()
await this.writeOperation
return asyncDrain(this.fd)
}
flush() {
return super.flush().then(() => promisify(binding.flush)(this.fd))
async flush() {
await super.flush()
return asyncFlush(this.fd)
}

@@ -104,0 +114,0 @@ }

@@ -78,9 +78,9 @@ const listLinux = require('./mocks/linux-list')

{
comName: '/dev/ttyS0',
path: '/dev/ttyS0',
},
{
comName: '/dev/ttyS1',
path: '/dev/ttyS1',
},
{
comName: '/dev/ttyACM0',
path: '/dev/ttyACM0',
manufacturer: 'Arduino (www.arduino.cc)',

@@ -93,7 +93,7 @@ serialNumber: '752303138333518011C1',

{
comName: '/dev/ttyAMA_im_a_programmer',
path: '/dev/ttyAMA_im_a_programmer',
pnpId: 'pci-NATA_Siolynx2_C8T6VI1F-if00-port0',
},
{
comName: '/dev/ttyMFD0',
path: '/dev/ttyMFD0',
vendorId: '2343',

@@ -103,3 +103,3 @@ productId: '0043',

{
comName: '/dev/rfcomm4',
path: '/dev/rfcomm4',
},

@@ -106,0 +106,0 @@ ]

@@ -11,3 +11,3 @@ const childProcess = require('child_process')

return {
DEVNAME: 'comName',
DEVNAME: 'path',
ID_VENDOR_ENC: 'manufacturer',

@@ -14,0 +14,0 @@ ID_SERIAL_SHORT: 'serialNumber',

@@ -0,1 +1,2 @@

const { promisify } = require('util')
const binding = require('bindings')('bindings.node')

@@ -5,5 +6,5 @@ const AbstractBinding = require('@serialport/binding-abstract')

const Poller = require('./poller')
const promisify = require('./util').promisify
const unixRead = require('./unix-read')
const unixWrite = require('./unix-write')
const { wrapWithHiddenComName } = require('./legacy')

@@ -14,2 +15,12 @@ const defaultBindingOptions = Object.freeze({

})
const asyncOpen = promisify(binding.open)
const asyncClose = promisify(binding.close)
const asyncUpdate = promisify(binding.update)
const asyncSet = promisify(binding.set)
const asyncGet = promisify(binding.get)
const asyncGetBaudRate = promisify(binding.getBaudRate)
const asyncDrain = promisify(binding.drain)
const asyncFlush = promisify(binding.flush)
/**

@@ -20,3 +31,3 @@ * The linux binding layer

static list() {
return linuxList()
return wrapWithHiddenComName(linuxList())
}

@@ -26,3 +37,3 @@

super(opt)
this.bindingOptions = Object.assign({}, defaultBindingOptions, opt.bindingOptions || {})
this.bindingOptions = { ...defaultBindingOptions, ...opt.bindingOptions }
this.fd = null

@@ -36,69 +47,68 @@ this.writeOperation = null

open(path, options) {
return super
.open(path, options)
.then(() => {
this.openOptions = Object.assign({}, this.bindingOptions, options)
return promisify(binding.open)(path, this.openOptions)
})
.then(fd => {
this.fd = fd
this.poller = new Poller(fd)
})
async open(path, options) {
await super.open(path, options)
this.openOptions = { ...this.bindingOptions, ...options }
const fd = await asyncOpen(path, this.openOptions)
this.fd = fd
this.poller = new Poller(fd)
}
close() {
return super.close().then(() => {
const fd = this.fd
this.poller.stop()
this.poller.destroy()
this.poller = null
this.openOptions = null
this.fd = null
return promisify(binding.close)(fd)
})
async close() {
await super.close()
const fd = this.fd
this.poller.stop()
this.poller.destroy()
this.poller = null
this.openOptions = null
this.fd = null
return asyncClose(fd)
}
read(buffer, offset, length) {
return super.read(buffer, offset, length).then(() => unixRead.call(this, buffer, offset, length))
async read(buffer, offset, length) {
await super.read(buffer, offset, length)
return unixRead.call(this, buffer, offset, length)
}
write(buffer) {
if (buffer.length > 0) {
this.writeOperation = super
.write(buffer)
.then(() => unixWrite.call(this, buffer))
.then(() => {
this.writeOperation = null
})
return this.writeOperation
async write(buffer) {
if (buffer.length === 0) {
return
}
return Promise.resolve()
this.writeOperation = super
.write(buffer)
.then(() => unixWrite.call(this, buffer))
.then(() => {
this.writeOperation = null
})
return this.writeOperation
}
update(options) {
return super.update(options).then(() => promisify(binding.update)(this.fd, options))
async update(options) {
await super.update(options)
return asyncUpdate(this.fd, options)
}
set(options) {
return super.set(options).then(() => promisify(binding.set)(this.fd, options))
async set(options) {
await super.set(options)
return asyncSet(this.fd, options)
}
get() {
return super.get().then(() => promisify(binding.get)(this.fd))
async get() {
await super.get()
return asyncGet(this.fd)
}
getBaudRate() {
return super.getBaudRate().then(() => promisify(binding.getBaudRate)(this.fd))
async getBaudRate() {
await super.get()
return asyncGetBaudRate(this.fd)
}
drain() {
return super
.drain()
.then(() => Promise.resolve(this.writeOperation))
.then(() => promisify(binding.drain)(this.fd))
async drain() {
await super.drain()
await this.writeOperation
return asyncDrain(this.fd)
}
flush() {
return super.flush().then(() => promisify(binding.flush)(this.fd))
async flush() {
await super.flush()
return asyncFlush(this.fd)
}

@@ -105,0 +115,0 @@ }

@@ -48,3 +48,3 @@ const debug = require('debug')

*/
once(event) {
once(event, callback) {
switch (event) {

@@ -61,3 +61,3 @@ case 'readable':

}
return EventEmitter.prototype.once.apply(this, arguments)
return super.once(event, callback)
}

@@ -64,0 +64,0 @@

const fs = require('fs')
const debug = require('debug')
const logger = debug('serialport/bindings/unixRead')
const { promisify } = require('util')
module.exports = function unixRead(buffer, offset, length) {
const readAsync = promisify(fs.read)
const readable = binding => {
return new Promise((resolve, reject) => {
binding.poller.once('readable', err => (err ? reject(err) : resolve()))
})
}
module.exports = async function unixRead(buffer, offset, length) {
logger('Starting read')
if (!this.isOpen) {
return Promise.reject(new Error('Port is not open'))
throw new Error('Port is not open')
}
return new Promise((resolve, reject) => {
fs.read(this.fd, buffer, offset, length, null, (err, bytesRead) => {
if (err && (err.code === 'EAGAIN' || err.code === 'EWOULDBLOCK' || err.code === 'EINTR')) {
if (!this.isOpen) {
return reject(new Error('Port is not open'))
}
logger('waiting for readable because of code:', err.code)
this.poller.once('readable', err => {
if (err) {
return reject(err)
}
resolve(this.read(buffer, offset, length))
})
return
}
const disconnectError =
err &&
(err.code === 'EBADF' || // Bad file number means we got closed
err.code === 'ENXIO' || // No such device or address probably usb disconnect
err.code === 'UNKNOWN' ||
err.errno === -1) // generic error
try {
const bytesRead = await readAsync(this.fd, buffer, offset, length, null)
if (bytesRead === 0) {
return this.read(buffer, offset, length)
}
if (disconnectError) {
err.disconnect = true
logger('disconnecting', err)
logger('Finished read', bytesRead, 'bytes')
return bytesRead
} catch (err) {
if (err.code === 'EAGAIN' || err.code === 'EWOULDBLOCK' || err.code === 'EINTR') {
if (!this.isOpen) {
throw new Error('Port is not open')
}
logger('waiting for readable because of code:', err.code)
await readable(this)
return this.read(buffer, offset, length)
}
if (err) {
return reject(err)
}
const disconnectError =
err.code === 'EBADF' || // Bad file number means we got closed
err.code === 'ENXIO' || // No such device or address probably usb disconnect
err.code === 'UNKNOWN' ||
err.errno === -1 // generic error
if (bytesRead === 0) {
resolve(this.read(buffer, offset, length))
return
}
if (disconnectError) {
err.disconnect = true
logger('disconnecting', err)
}
logger('Finished read', bytesRead, 'bytes')
resolve(bytesRead)
})
})
throw err
}
}
const fs = require('fs')
const debug = require('debug')
const logger = debug('serialport/bindings/unixWrite')
const { promisify } = require('util')
module.exports = function unixWrite(buffer, offset) {
const writeAsync = promisify(fs.write)
const writable = binding => {
return new Promise((resolve, reject) => {
binding.poller.once('writable', err => (err ? reject(err) : resolve()))
})
}
module.exports = async function unixWrite(buffer, offset) {
offset = offset || 0

@@ -10,50 +19,40 @@ const bytesToWrite = buffer.length - offset

if (!this.isOpen) {
return Promise.reject(new Error('Port is not open'))
throw new Error('Port is not open')
}
return new Promise((resolve, reject) => {
fs.write(this.fd, buffer, offset, bytesToWrite, (err, bytesWritten) => {
logger('write returned', err, bytesWritten)
if (err && (err.code === 'EAGAIN' || err.code === 'EWOULDBLOCK' || err.code === 'EINTR')) {
if (!this.isOpen) {
return reject(new Error('Port is not open'))
}
logger('waiting for writable because of code:', err.code)
this.poller.once('writable', err => {
if (err) {
return reject(err)
}
resolve(unixWrite.call(this, buffer, offset))
})
return
try {
const bytesWritten = await writeAsync(this.fd, buffer, offset, bytesToWrite)
logger('write returned: wrote', bytesWritten, 'bytes')
if (bytesWritten + offset < buffer.length) {
if (!this.isOpen) {
throw new Error('Port is not open')
}
return resolve(unixWrite.call(this, buffer, bytesWritten + offset))
}
const disconnectError =
err &&
(err.code === 'EBADF' || // Bad file number means we got closed
err.code === 'ENXIO' || // No such device or address probably usb disconnect
err.code === 'UNKNOWN' ||
err.errno === -1) // generic error
if (disconnectError) {
err.disconnect = true
logger('disconnecting', err)
logger('Finished writing', bytesWritten + offset, 'bytes')
} catch (err) {
logger('write errored', err)
if (err.code === 'EAGAIN' || err.code === 'EWOULDBLOCK' || err.code === 'EINTR') {
if (!this.isOpen) {
throw new Error('Port is not open')
}
logger('waiting for writable because of code:', err.code)
await writable(this)
return unixWrite.call(this, buffer, offset)
}
if (err) {
logger('error', err)
return reject(err)
}
const disconnectError =
err.code === 'EBADF' || // Bad file number means we got closed
err.code === 'ENXIO' || // No such device or address probably usb disconnect
err.code === 'UNKNOWN' ||
err.errno === -1 // generic error
logger('wrote', bytesWritten, 'bytes')
if (bytesWritten + offset < buffer.length) {
if (!this.isOpen) {
return reject(new Error('Port is not open'))
}
return resolve(unixWrite.call(this, buffer, bytesWritten + offset))
}
if (disconnectError) {
err.disconnect = true
logger('disconnecting', err)
}
logger('Finished writing', bytesWritten + offset, 'bytes')
resolve()
})
})
logger('error', err)
throw err
}
}

@@ -7,4 +7,3 @@ const PARSERS = [/USB\\(?:.+)\\(.+)/, /FTDIBUS\\(?:.+)\+(.+?)A?\\.+/]

}
for (let index = 0; index < PARSERS.length; index++) {
const parser = PARSERS[index]
for (const parser of PARSERS) {
const sn = pnpId.match(parser)

@@ -11,0 +10,0 @@ if (sn) {

const binding = require('bindings')('bindings.node')
const AbstractBinding = require('@serialport/binding-abstract')
const promisify = require('./util').promisify
const { promisify } = require('util')
const serialNumParser = require('./win32-sn-parser')
const asyncList = promisify(binding.list)
const asyncOpen = promisify(binding.open)
const asyncRead = promisify(binding.read)
const asyncWrite = promisify(binding.write)
const asyncUpdate = promisify(binding.update)
const asyncSet = promisify(binding.set)
const asyncGet = promisify(binding.get)
const asyncGetBaudRate = promisify(binding.getBaudRate)
const asyncDrain = promisify(binding.drain)
const asyncFlush = promisify(binding.flush)
const { wrapWithHiddenComName } = require('./legacy')
/**

@@ -10,15 +22,19 @@ * The Windows binding layer

class WindowsBinding extends AbstractBinding {
static list() {
return promisify(binding.list)().then(ports => {
// Grab the serial number from the pnp id
ports.forEach(port => {
static async list() {
const ports = await asyncList()
// Grab the serial number from the pnp id
return wrapWithHiddenComName(
ports.map(port => {
if (port.pnpId && !port.serialNumber) {
const serialNumber = serialNumParser(port.pnpId)
if (serialNumber) {
port.serialNumber = serialNumber
return {
...port,
serialNumber,
}
}
}
return port
})
return ports
})
)
}

@@ -28,3 +44,3 @@

super(opt)
this.bindingOptions = Object.assign({}, opt.bindingOptions || {})
this.bindingOptions = { ...opt.bindingOptions }
this.fd = null

@@ -38,72 +54,68 @@ this.writeOperation = null

open(path, options) {
return super
.open(path, options)
.then(() => {
this.openOptions = Object.assign({}, this.bindingOptions, options)
return promisify(binding.open)(path, this.openOptions)
})
.then(fd => {
this.fd = fd
})
async open(path, options) {
await super.open(path, options)
this.openOptions = { ...this.bindingOptions, ...options }
const fd = await asyncOpen(path, this.openOptions)
this.fd = fd
}
close() {
return super.close().then(() => {
const fd = this.fd
this.fd = null
return promisify(binding.close)(fd)
})
async close() {
await super.close()
const fd = this.fd
this.fd = null
return asyncClose(fd)
}
read(buffer, offset, length) {
return super
.read(buffer, offset, length)
.then(() => promisify(binding.read)(this.fd, buffer, offset, length))
.catch(err => {
if (!this.isOpen) {
err.canceled = true
}
throw err
})
async read(buffer, offset, length) {
await super.read(buffer, offset, length)
return asyncRead(this.fd, buffer, offset, length).catch(err => {
if (!this.isOpen) {
err.canceled = true
}
throw err
})
}
write(buffer) {
if (buffer.length > 0) {
this.writeOperation = super
.write(buffer)
.then(() => promisify(binding.write)(this.fd, buffer))
.then(() => {
this.writeOperation = null
})
return this.writeOperation
async write(buffer) {
if (buffer.length === 0) {
return
}
return Promise.resolve()
this.writeOperation = super
.write(buffer)
.then(() => asyncWrite(this.fd, buffer))
.then(() => {
this.writeOperation = null
})
return this.writeOperation
}
update(options) {
return super.update(options).then(() => promisify(binding.update)(this.fd, options))
async update(options) {
await super.update(options)
return asyncUpdate(this.fd, options)
}
set(options) {
return super.set(options).then(() => promisify(binding.set)(this.fd, options))
async set(options) {
await super.set(options)
return asyncSet(this.fd, options)
}
get() {
return super.get().then(() => promisify(binding.get)(this.fd))
async get() {
await super.get()
return asyncGet(this.fd)
}
getBaudRate() {
return super.get().then(() => promisify(binding.getBaudRate)(this.fd))
async getBaudRate() {
await super.get()
return asyncGetBaudRate(this.fd)
}
drain() {
return super
.drain()
.then(() => Promise.resolve(this.writeOperation))
.then(() => promisify(binding.drain)(this.fd))
async drain() {
await super.drain()
await this.writeOperation
return asyncDrain(this.fd)
}
flush() {
return super.flush().then(() => promisify(binding.flush)(this.fd))
async flush() {
await super.flush()
return asyncFlush(this.fd)
}

@@ -110,0 +122,0 @@ }

{
"name": "@serialport/bindings",
"version": "2.0.8",
"version": "3.0.0",
"main": "lib",

@@ -9,14 +9,14 @@ "keywords": [

"dependencies": {
"@serialport/binding-abstract": "^2.0.5",
"@serialport/parser-readline": "^2.0.2",
"bindings": "^1.3.0",
"@serialport/binding-abstract": "^3.0.0",
"@serialport/parser-readline": "^3.0.0",
"bindings": "^1.5.0",
"debug": "^4.1.1",
"nan": "^2.13.2",
"prebuild-install": "^5.2.1"
"prebuild-install": "^5.3.0"
},
"devDependencies": {
"@serialport/binding-mock": "^2.0.5"
"@serialport/binding-mock": "^3.0.0"
},
"engines": {
"node": ">=6.0.0"
"node": ">=8.6.0"
},

@@ -49,3 +49,3 @@ "scripts": {

},
"gitHead": "4c723cc89e454017a28396e934bf7a00946fe866"
"gitHead": "524a2729003a94c9575904448d878a151f4f3790"
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc