Skip to content

Commit b3bead4

Browse files
authored
feat: platform specific open options (#2428)
Make it a bit easier to have platform specific open options. I'm in love with the solution but it doesn't seem possible to filter the generic via a typecheck and have it apply to the open options. So casting the open options is the only recouse I've figured out.
1 parent 956de7e commit b3bead4

File tree

5 files changed

+39
-31
lines changed

5 files changed

+39
-31
lines changed

packages/serialport/lib/index.test.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { randomBytes } from 'crypto'
33
import { SerialPort as SerialPortAutoDetect, SerialPortMock } from './'
44
import { assert } from '../../../test/assert'
55
import { testOnPlatform } from '../../../test/testOnPlatform'
6+
import { LinuxBinding, LinuxOpenOptions } from '@serialport/bindings-cpp'
67

78
const platform = process.platform
89
if (platform !== 'win32' && platform !== 'darwin' && platform !== 'linux') {
@@ -31,13 +32,13 @@ function testSerialPortClass(
3132

3233
beforeEach(() => {
3334
if (platform === 'mock') {
34-
SerialPortMock.MockBinding.createPort('/dev/exists', { echo: true, maxReadSize: 50 })
35+
SerialPortMock.binding.createPort('/dev/exists', { echo: true, maxReadSize: 50 })
3536
}
3637
})
3738

3839
afterEach(() => {
3940
if (platform === 'mock') {
40-
SerialPortMock.MockBinding.reset()
41+
SerialPortMock.binding.reset()
4142
}
4243
})
4344

@@ -73,6 +74,16 @@ function testSerialPortClass(
7374
done()
7475
})
7576
})
77+
78+
it('allows platform specific options', done => {
79+
new SerialPort({
80+
path: '/bad/port',
81+
baudRate: 9600,
82+
vmin: 10,
83+
} as LinuxOpenOptions).on('error', () => {
84+
done()
85+
})
86+
})
7687
})
7788

7889
describe('opening and closing', () => {

packages/serialport/lib/serialport-mock.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export type SerialPortMockOpenOptions = Omit<OpenOptions<MockBindingInterface>,
55

66
export class SerialPortMock extends SerialPortStream<MockBindingInterface> {
77
static list = MockBinding.list
8-
static readonly MockBinding = MockBinding
8+
static readonly binding = MockBinding
99

1010
constructor(options: SerialPortMockOpenOptions, openCallback?: ErrorCallback) {
1111
const opts: OpenOptions<MockBindingInterface> = {

packages/serialport/lib/serialport.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import { ErrorCallback, OpenOptions, SerialPortStream } from '@serialport/stream'
2-
import { autoDetect, AutoDetectTypes } from '@serialport/bindings-cpp'
1+
import { ErrorCallback, OpenOptions, SerialPortStream, StreamOptions } from '@serialport/stream'
2+
import { autoDetect, AutoDetectTypes, OpenOptionsFromBinding } from '@serialport/bindings-cpp'
33

44
const DetectedBinding = autoDetect()
55

6-
export type SerialPortOpenOptions = Omit<OpenOptions<AutoDetectTypes>, 'binding'>
6+
export type SerialPortOpenOptions<T extends AutoDetectTypes> = Omit<StreamOptions<T>, 'binding'> & OpenOptionsFromBinding<T>
77

8-
export class SerialPort extends SerialPortStream<AutoDetectTypes> {
8+
export class SerialPort<T extends AutoDetectTypes = AutoDetectTypes> extends SerialPortStream<T> {
99
/**
1010
* Retrieves a list of available serial ports with metadata. Only the `path` is guaranteed. If unavailable the other fields will be undefined. The `path` is either the path or an identifier (eg `COM1`) used to open the SerialPort.
1111
*
@@ -57,10 +57,11 @@ export class SerialPort extends SerialPortStream<AutoDetectTypes> {
5757
```
5858
*/
5959
static list = DetectedBinding.list
60+
static readonly binding = DetectedBinding
6061

61-
constructor(options: SerialPortOpenOptions, openCallback?: ErrorCallback) {
62-
const opts: OpenOptions<AutoDetectTypes> = {
63-
binding: DetectedBinding,
62+
constructor(options: SerialPortOpenOptions<T>, openCallback?: ErrorCallback) {
63+
const opts: OpenOptions<T> = {
64+
binding: DetectedBinding as T,
6465
...options,
6566
}
6667
super(opts, openCallback)

packages/stream/lib/index.ts

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
11
import { Duplex } from 'stream'
22
import debugFactory from 'debug'
3-
import { SetOptions, BindingInterface, PortInterfaceFromBinding, OpenOptions as BindingOpenOptions } from '@serialport/bindings-interface'
3+
import { SetOptions, BindingInterface, PortInterfaceFromBinding, OpenOptionsFromBinding } from '@serialport/bindings-interface'
44
const debug = debugFactory('serialport/stream')
55

6-
interface InternalSettings<T extends BindingInterface> extends OpenOptions<T> {
6+
export class DisconnectedError extends Error {
7+
disconnected: true
8+
constructor(message: string) {
9+
super(message)
10+
this.disconnected = true
11+
}
12+
}
13+
14+
interface InternalSettings<T extends BindingInterface> {
15+
binding: T
716
autoOpen: boolean
817
endOnClose: boolean
918
highWaterMark: number
@@ -33,12 +42,14 @@ export type ErrorCallback = (err: Error | null) => void
3342

3443
export type ModemBitsCallback = (err: Error | null, options?: { cts: boolean; dsr: boolean; dcd: boolean }) => void
3544

45+
export type OpenOptions<T extends BindingInterface = BindingInterface> = StreamOptions<T> & OpenOptionsFromBinding<T>
46+
3647
/**
3748
* Options to open a port
3849
*/
39-
export interface OpenOptions<T extends BindingInterface> extends BindingOpenOptions {
50+
export interface StreamOptions<T extends BindingInterface> {
4051
/**
41-
* The hardware access binding. `Bindings` are how Node-Serialport talks to the underlying system. By default we auto detect Windows (`WindowsBinding`), Linux (`LinuxBinding`) and OS X (`DarwinBinding`) and load the appropriate module for your system.
52+
* The hardware access binding. `Bindings` are how Node-Serialport talks to the underlying system. If you're using the `serialport` package, this defaults to `'@serialport/bindings-cpp'` which auto detects Windows (`WindowsBinding`), Linux (`LinuxBinding`) and OS X (`DarwinBinding`) and load the appropriate module for your system.
4253
*/
4354
binding: T
4455

@@ -56,31 +67,16 @@ export interface OpenOptions<T extends BindingInterface> extends BindingOpenOpti
5667
endOnClose?: boolean
5768
}
5869

59-
export class DisconnectedError extends Error {
60-
disconnected: true
61-
constructor(message: string) {
62-
super(message)
63-
this.disconnected = true
64-
}
65-
}
66-
6770
export class SerialPortStream<T extends BindingInterface = BindingInterface> extends Duplex {
6871
port?: PortInterfaceFromBinding<T>
6972
private _pool: PoolBuffer
7073
private _kMinPoolSpace: number
7174
opening: boolean
7275
closing: boolean
73-
readonly settings: InternalSettings<T>
76+
readonly settings: InternalSettings<T> & OpenOptionsFromBinding<T>
7477

7578
/**
7679
* Create a new serial port object for the `path`. In the case of invalid arguments or invalid options, when constructing a new SerialPort it will throw an error. The port will open automatically by default, which is the equivalent of calling `port.open(openCallback)` in the next tick. You can disable this by setting the option `autoOpen` to `false`.
77-
* @param {OpenOptions=} options - Port configuration options
78-
* @param {ErrorCallback=} openCallback - If `autoOpen` is true (the default) it will be provided to `port.open()` and run after the port is opened. The callback will be ignored if `autoOpen` is set to `false`.
79-
* @property {number} baudRate The port's baudRate. Use `.update` to change it. Read-only.
80-
* @property {string} path The system path or name of the serial port. Read-only.
81-
* @property {boolean} isOpen `true` if the port is open, `false` otherwise. Read-only.
82-
* @property {InternalSettings} settings The current settings of the port
83-
* @throws {TypeError} When given invalid arguments, a `TypeError` will be thrown.
8480
* @emits open
8581
* @emits data
8682
* @emits close

packages/terminal/lib/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ const args = program.opts<{
3030
path?: string
3131
baud: number
3232
databits: 8 | 7 | 6 | 5
33-
parity: string
33+
parity: OpenOptions<AutoDetectTypes>['parity']
3434
stopbits: 1 | 1.5 | 2
3535
echo: boolean
3636
flowCtl?: string

0 commit comments

Comments
 (0)