Skip to content

Commit

Permalink
fix: remove support for HID.HID and HID.Async devices in setupXKeysPa…
Browse files Browse the repository at this point in the history
…nel.

This is because previously we used a hack where we used .devicePath for these. This property (as far as I can tell) doesn't exist anymore, so we should not support it.
As a backwards compatibility, a blind implementation for supporting { devicePath: string } was added.
  • Loading branch information
nytamin committed Dec 4, 2023
1 parent e1d41ad commit 1bc87ba
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 20 deletions.
11 changes: 1 addition & 10 deletions packages/node/src/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,11 @@ import type * as HID from 'node-hid'
* This file contains internal convenience functions
*/

export function isHID_Device(device: HID.Device | HID.HIDAsync | string): device is HID.Device {
export function isHID_Device(device: HID.Device | HID.HID | HID.HIDAsync | string): device is HID.Device {
return (
typeof device === 'object' &&
(device as HID.Device).vendorId !== undefined &&
(device as HID.Device).productId !== undefined &&
(device as HID.Device).interface !== undefined
)
}
type HID_HID = HID.HIDAsync & { devicePath: string }
export function isHID_HID(device: HID.Device | HID.HIDAsync | string): device is HID_HID {
return (
typeof device === 'object' &&
(device as HID_HID).write !== undefined &&
(device as HID_HID).getFeatureReport !== undefined &&
(device as HID_HID).devicePath !== undefined // yes, HID.HID exposes this, we're using that
)
}
37 changes: 27 additions & 10 deletions packages/node/src/methods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,21 @@ import { PRODUCTS } from '@xkeys-lib/core'
import * as HID from 'node-hid'
import { NodeHIDDevice } from './node-hid-wrapper'

import { isHID_Device, isHID_HID } from './lib'
import { isHID_Device } from './lib'

import { HID_Device } from './api'

/** Sets up a connection to a HID device (the X-keys panel) */
/**
* Sets up a connection to a HID device (the X-keys panel)
*
* If called without arguments, it will select any connected X-keys panel.
*/
export function setupXkeysPanel(): Promise<XKeys>
export function setupXkeysPanel(HIDDevice: HID.Device): Promise<XKeys>
export function setupXkeysPanel(HIDDevice: HID.HIDAsync): Promise<XKeys>
export function setupXkeysPanel(devicePath: string): Promise<XKeys>
export async function setupXkeysPanel(devicePathOrHIDDevice?: HID.Device | HID.HIDAsync | string): Promise<XKeys> {
export async function setupXkeysPanel(
devicePathOrHIDDevice?: HID.Device | HID.HID | HID.HIDAsync | string
): Promise<XKeys> {
let devicePath: string
let device: HID.HIDAsync | undefined
let deviceInfo:
Expand Down Expand Up @@ -52,26 +57,38 @@ export async function setupXkeysPanel(devicePathOrHIDDevice?: HID.Device | HID.H
productId: devicePathOrHIDDevice.productId,
interface: devicePathOrHIDDevice.interface,
}
} else if (isHID_HID(devicePathOrHIDDevice)) {
// is HID.HID
} else if (
typeof devicePathOrHIDDevice === 'object' &&
typeof (devicePathOrHIDDevice as any).devicePath === 'string'
) {
// (backwards compatibility): has { devicePath: string }

device = devicePathOrHIDDevice
devicePath = devicePathOrHIDDevice.devicePath
// deviceInfo is set later
devicePath = (devicePathOrHIDDevice as any).devicePath
device = await HID.HIDAsync.open(devicePath)
} else if (typeof devicePathOrHIDDevice === 'string') {
// is string (path)

devicePath = devicePathOrHIDDevice
device = await HID.HIDAsync.open(devicePath)
// deviceInfo is set later
} else if (devicePathOrHIDDevice instanceof HID.HID) {
// Can't use this, since devicePath is missing
throw new Error(
'HID.HID not supported as argument to setupXkeysPanel, use HID.devices() to find the device and provide that instead.'
)
} else if (devicePathOrHIDDevice instanceof HID.HIDAsync) {
// Can't use this, since devicePath is missing
throw new Error(
'HID.HIDAsync not supported as argument to setupXkeysPanel, use HID.devicesAsync() to find the device and provide that instead.'
)
} else {
throw new Error('setupXkeysPanel: invalid arguments')
}

if (!deviceInfo) {
// @ts-expect-error getDeviceInfo missing in typings
const nodeHidInfo: HID.Device = await device.getDeviceInfo()
// Look through HID.devices(), bevause HID.Device contains the productId
// Look through HID.devices(), because HID.Device contains the productId
deviceInfo = {
product: nodeHidInfo.product,
productId: nodeHidInfo.productId,
Expand Down

0 comments on commit 1bc87ba

Please sign in to comment.