usb 1.9.2 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/.eslintignore +4 -0
  2. package/.eslintrc.json +87 -0
  3. package/.gitattributes +1 -0
  4. package/.vscode/launch.json +15 -0
  5. package/.vscode/tasks.json +23 -0
  6. package/CHANGELOG.md +13 -0
  7. package/README.md +400 -175
  8. package/dist/index.d.ts +17 -0
  9. package/dist/index.js +138 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/usb/bindings.d.ts +253 -0
  12. package/dist/usb/bindings.js +10 -0
  13. package/dist/usb/bindings.js.map +1 -0
  14. package/dist/usb/capability.d.ts +14 -0
  15. package/dist/usb/capability.js +18 -0
  16. package/dist/usb/capability.js.map +1 -0
  17. package/dist/usb/descriptors.d.ts +129 -0
  18. package/dist/usb/descriptors.js +3 -0
  19. package/dist/usb/descriptors.js.map +1 -0
  20. package/dist/usb/device.d.ts +94 -0
  21. package/dist/usb/device.js +300 -0
  22. package/dist/usb/device.js.map +1 -0
  23. package/dist/usb/endpoint.d.ts +91 -0
  24. package/dist/usb/endpoint.js +236 -0
  25. package/dist/usb/endpoint.js.map +1 -0
  26. package/dist/usb/index.d.ts +25 -0
  27. package/dist/usb/index.js +116 -0
  28. package/dist/usb/index.js.map +1 -0
  29. package/dist/usb/interface.d.ts +78 -0
  30. package/dist/usb/interface.js +137 -0
  31. package/dist/usb/interface.js.map +1 -0
  32. package/dist/webusb/index.d.ts +56 -0
  33. package/dist/webusb/index.js +412 -0
  34. package/dist/webusb/index.js.map +1 -0
  35. package/dist/webusb/mutex.d.ts +22 -0
  36. package/dist/webusb/mutex.js +89 -0
  37. package/dist/webusb/mutex.js.map +1 -0
  38. package/dist/webusb/webusb-device.d.ts +49 -0
  39. package/dist/webusb/webusb-device.js +892 -0
  40. package/dist/webusb/webusb-device.js.map +1 -0
  41. package/package.json +28 -15
  42. package/prebuilds/win32-ia32/node.napi.node +0 -0
  43. package/prebuilds/win32-x64/node.napi.node +0 -0
  44. package/src/device.cc +2 -2
  45. package/test/usb.coffee +13 -7
  46. package/test/webusb.coffee +189 -0
  47. package/tsc/index.ts +72 -0
  48. package/tsc/usb/bindings.ts +304 -0
  49. package/tsc/usb/capability.ts +22 -0
  50. package/tsc/usb/descriptors.ts +180 -0
  51. package/tsc/usb/device.ts +325 -0
  52. package/tsc/usb/endpoint.ts +228 -0
  53. package/tsc/usb/index.ts +111 -0
  54. package/tsc/usb/interface.ts +172 -0
  55. package/tsc/webusb/index.ts +363 -0
  56. package/tsc/webusb/mutex.ts +38 -0
  57. package/tsc/webusb/webusb-device.ts +541 -0
  58. package/tsconfig.json +17 -0
  59. package/typedoc.json +9 -0
  60. package/usb.js +0 -573
@@ -0,0 +1,541 @@
1
+ import * as usb from '../usb';
2
+ import { promisify } from 'util';
3
+ import { Endpoint, InEndpoint, OutEndpoint } from '../usb/endpoint';
4
+ import { Mutex } from './mutex';
5
+
6
+ const LIBUSB_TRANSFER_TYPE_MASK = 0x03;
7
+ const ENDPOINT_NUMBER_MASK = 0x7f;
8
+ const CLEAR_FEATURE = 0x01;
9
+ const ENDPOINT_HALT = 0x00;
10
+
11
+ /**
12
+ * Wrapper to make a node-usb device look like a webusb device
13
+ */
14
+ export class WebUSBDevice implements USBDevice {
15
+ public static async createInstance(device: usb.Device): Promise<WebUSBDevice | undefined> {
16
+ try {
17
+ const instance = new WebUSBDevice(device);
18
+ await instance.initialize();
19
+ return instance;
20
+ } catch {
21
+ return undefined;
22
+ }
23
+ }
24
+
25
+ public readonly usbVersionMajor: number;
26
+ public readonly usbVersionMinor: number;
27
+ public readonly usbVersionSubminor: number;
28
+ public readonly deviceClass: number;
29
+ public readonly deviceSubclass: number;
30
+ public readonly deviceProtocol: number;
31
+ public readonly vendorId: number;
32
+ public readonly productId: number;
33
+ public readonly deviceVersionMajor: number;
34
+ public readonly deviceVersionMinor: number;
35
+ public readonly deviceVersionSubminor: number;
36
+
37
+ public manufacturerName?: string | undefined;
38
+ public productName?: string | undefined;
39
+ public serialNumber?: string | undefined;
40
+ public configurations: USBConfiguration[] = [];
41
+
42
+ private deviceMutex = new Mutex();
43
+
44
+ private constructor(private device: usb.Device) {
45
+ const usbVersion = this.decodeVersion(device.deviceDescriptor.bcdUSB);
46
+ this.usbVersionMajor = usbVersion.major;
47
+ this.usbVersionMinor = usbVersion.minor;
48
+ this.usbVersionSubminor = usbVersion.sub;
49
+
50
+ this.deviceClass = device.deviceDescriptor.bDeviceClass;
51
+ this.deviceSubclass = device.deviceDescriptor.bDeviceSubClass;
52
+ this.deviceProtocol = device.deviceDescriptor.bDeviceProtocol;
53
+ this.vendorId = device.deviceDescriptor.idVendor;
54
+ this.productId = device.deviceDescriptor.idProduct;
55
+
56
+ const deviceVersion = this.decodeVersion(device.deviceDescriptor.bcdDevice);
57
+ this.deviceVersionMajor = deviceVersion.major;
58
+ this.deviceVersionMinor = deviceVersion.minor;
59
+ this.deviceVersionSubminor = deviceVersion.sub;
60
+ }
61
+
62
+ public get configuration(): USBConfiguration | undefined {
63
+ if (!this.device.configDescriptor) {
64
+ return undefined;
65
+ }
66
+ const currentConfiguration = this.device.configDescriptor.bConfigurationValue;
67
+ return this.configurations.find(configuration => configuration.configurationValue === currentConfiguration);
68
+ }
69
+
70
+ public get opened(): boolean {
71
+ return (!!this.device.interfaces);
72
+ }
73
+
74
+ public async open(): Promise<void> {
75
+ try {
76
+ await this.deviceMutex.lock();
77
+
78
+ if (this.opened) {
79
+ return;
80
+ }
81
+
82
+ this.device.open();
83
+ } catch (error) {
84
+ throw new Error(`open error: ${error}`);
85
+ } finally {
86
+ this.deviceMutex.unlock();
87
+ }
88
+ }
89
+
90
+ public async close(): Promise<void> {
91
+ try {
92
+ await this.deviceMutex.lock();
93
+
94
+ if (!this.opened) {
95
+ return;
96
+ }
97
+
98
+ try {
99
+ if (this.configuration) {
100
+ for (const iface of this.configuration?.interfaces) {
101
+ await this._releaseInterface(iface.interfaceNumber);
102
+ // Re-create the USBInterface to set the claimed attribute
103
+ this.configuration.interfaces[this.configuration.interfaces.indexOf(iface)] = {
104
+ interfaceNumber: iface.interfaceNumber,
105
+ alternate: iface.alternate,
106
+ alternates: iface.alternates,
107
+ claimed: false
108
+ };
109
+ }
110
+ }
111
+ } catch (_error) {
112
+ // Ignore
113
+ }
114
+
115
+ this.device.close();
116
+ } catch (error) {
117
+ throw new Error(`close error: ${error}`);
118
+ } finally {
119
+ this.deviceMutex.unlock();
120
+ }
121
+ }
122
+
123
+ public async selectConfiguration(configurationValue: number): Promise<void> {
124
+ try {
125
+ await this.deviceMutex.lock();
126
+
127
+ if (!this.opened || !this.device.configDescriptor) {
128
+ throw new Error('selectConfiguration error: invalid state');
129
+ }
130
+
131
+ if (this.device.configDescriptor.bConfigurationValue === configurationValue) {
132
+ return;
133
+ }
134
+
135
+ const config = this.configurations.find(configuration => configuration.configurationValue === configurationValue);
136
+ if (!config) {
137
+ throw new Error('selectConfiguration error: configuration not found');
138
+ }
139
+
140
+ try {
141
+ const setConfiguration = promisify(this.device.setConfiguration).bind(this.device);
142
+ await setConfiguration(configurationValue);
143
+ } catch (error) {
144
+ throw new Error(`selectConfiguration error: ${error}`);
145
+ }
146
+ } finally {
147
+ this.deviceMutex.unlock();
148
+ }
149
+ }
150
+
151
+ public async claimInterface(interfaceNumber: number): Promise<void> {
152
+ try {
153
+ await this.deviceMutex.lock();
154
+
155
+ if (!this.opened) {
156
+ throw new Error('claimInterface error: invalid state');
157
+ }
158
+
159
+ if (!this.configuration) {
160
+ throw new Error('claimInterface error: interface not found');
161
+ }
162
+
163
+ const iface = this.configuration.interfaces.find(usbInterface => usbInterface.interfaceNumber === interfaceNumber);
164
+ if (!iface) {
165
+ throw new Error('claimInterface error: interface not found');
166
+ }
167
+
168
+ if (iface.claimed) {
169
+ return;
170
+ }
171
+
172
+ try {
173
+ this.device.interface(interfaceNumber).claim();
174
+
175
+ // Re-create the USBInterface to set the claimed attribute
176
+ this.configuration.interfaces[this.configuration.interfaces.indexOf(iface)] = {
177
+ interfaceNumber,
178
+ alternate: iface.alternate,
179
+ alternates: iface.alternates,
180
+ claimed: true
181
+ };
182
+ } catch (error) {
183
+ throw new Error(`claimInterface error: ${error}`);
184
+ }
185
+ } finally {
186
+ this.deviceMutex.unlock();
187
+ }
188
+ }
189
+
190
+ public async releaseInterface(interfaceNumber: number): Promise<void> {
191
+ try {
192
+ await this.deviceMutex.lock();
193
+ await this._releaseInterface(interfaceNumber);
194
+
195
+ if (this.configuration) {
196
+ const iface = this.configuration.interfaces.find(usbInterface => usbInterface.interfaceNumber === interfaceNumber);
197
+ if (iface) {
198
+ // Re-create the USBInterface to set the claimed attribute
199
+ this.configuration.interfaces[this.configuration.interfaces.indexOf(iface)] = {
200
+ interfaceNumber,
201
+ alternate: iface.alternate,
202
+ alternates: iface.alternates,
203
+ claimed: false
204
+ };
205
+ }
206
+ }
207
+
208
+ } finally {
209
+ this.deviceMutex.unlock();
210
+ }
211
+ }
212
+
213
+ public async selectAlternateInterface(interfaceNumber: number, alternateSetting: number): Promise<void> {
214
+ try {
215
+ await this.deviceMutex.lock();
216
+
217
+ if (!this.opened) {
218
+ throw new Error('selectAlternateInterface error: invalid state');
219
+ }
220
+
221
+ if (!this.configuration) {
222
+ throw new Error('selectAlternateInterface error: interface not found');
223
+ }
224
+
225
+ const iface = this.configuration.interfaces.find(usbInterface => usbInterface.interfaceNumber === interfaceNumber);
226
+ if (!iface) {
227
+ throw new Error('selectAlternateInterface error: interface not found');
228
+ }
229
+
230
+ if (!iface.claimed) {
231
+ throw new Error('selectAlternateInterface error: invalid state');
232
+ }
233
+
234
+ try {
235
+ const iface = this.device.interface(interfaceNumber);
236
+ const setAltSetting = promisify(iface.setAltSetting).bind(iface);
237
+ await setAltSetting(alternateSetting);
238
+ } catch (error) {
239
+ throw new Error(`selectAlternateInterface error: ${error}`);
240
+ }
241
+ } finally {
242
+ this.deviceMutex.unlock();
243
+ }
244
+ }
245
+
246
+ public async controlTransferIn(setup: USBControlTransferParameters, length: number): Promise<USBInTransferResult> {
247
+ try {
248
+ await this.deviceMutex.lock();
249
+ const type = this.controlTransferParamsToType(setup, usb.LIBUSB_ENDPOINT_IN);
250
+ const controlTransfer = promisify(this.device.controlTransfer).bind(this.device);
251
+ const result = await controlTransfer(type, setup.request, setup.value, setup.index, length);
252
+
253
+ return {
254
+ data: result ? new DataView(new Uint8Array(result as Buffer).buffer) : undefined,
255
+ status: 'ok'
256
+ };
257
+ } catch (error) {
258
+ if (error.errno === usb.LIBUSB_TRANSFER_STALL) {
259
+ return {
260
+ status: 'stall'
261
+ };
262
+ }
263
+
264
+ if (error.errno === usb.LIBUSB_TRANSFER_OVERFLOW) {
265
+ return {
266
+ status: 'babble'
267
+ };
268
+ }
269
+
270
+ throw new Error(`controlTransferIn error: ${error}`);
271
+ } finally {
272
+ this.deviceMutex.unlock();
273
+ }
274
+ }
275
+
276
+ public async controlTransferOut(setup: USBControlTransferParameters, data?: ArrayBuffer): Promise<USBOutTransferResult> {
277
+ try {
278
+ await this.deviceMutex.lock();
279
+ const type = this.controlTransferParamsToType(setup, usb.LIBUSB_ENDPOINT_OUT);
280
+ const controlTransfer = promisify(this.device.controlTransfer).bind(this.device);
281
+ const buffer = data ? Buffer.from(data) : Buffer.alloc(0);
282
+ const bytesWritten = <number>await controlTransfer(type, setup.request, setup.value, setup.index, buffer);
283
+
284
+ return {
285
+ bytesWritten,
286
+ status: 'ok'
287
+ };
288
+ } catch (error) {
289
+ if (error.errno === usb.LIBUSB_TRANSFER_STALL) {
290
+ return {
291
+ bytesWritten: 0,
292
+ status: 'stall'
293
+ };
294
+ }
295
+
296
+ throw new Error(`controlTransferOut error: ${error}`);
297
+ } finally {
298
+ this.deviceMutex.unlock();
299
+ }
300
+ }
301
+
302
+ public async clearHalt(direction: USBDirection, endpointNumber: number): Promise<void> {
303
+ try {
304
+ await this.deviceMutex.lock();
305
+ const wIndex = endpointNumber | (direction === 'in' ? usb.LIBUSB_ENDPOINT_IN : usb.LIBUSB_ENDPOINT_OUT);
306
+ const controlTransfer = promisify(this.device.controlTransfer).bind(this.device);
307
+ await controlTransfer(usb.LIBUSB_RECIPIENT_ENDPOINT, CLEAR_FEATURE, ENDPOINT_HALT, wIndex, 0);
308
+ } catch (error) {
309
+ throw new Error(`clearHalt error: ${error}`);
310
+ } finally {
311
+ this.deviceMutex.unlock();
312
+ }
313
+ }
314
+
315
+ public async transferIn(endpointNumber: number, length: number): Promise<USBInTransferResult> {
316
+ try {
317
+ await this.deviceMutex.lock();
318
+ const endpoint = this.getEndpoint(endpointNumber | usb.LIBUSB_ENDPOINT_IN) as InEndpoint;
319
+ const transfer = promisify(endpoint.transfer).bind(endpoint);
320
+ const result = await transfer(length);
321
+
322
+ return {
323
+ data: result ? new DataView(new Uint8Array(result).buffer) : undefined,
324
+ status: 'ok'
325
+ };
326
+ } catch (error) {
327
+ if (error.errno === usb.LIBUSB_TRANSFER_STALL) {
328
+ return {
329
+ status: 'stall'
330
+ };
331
+ }
332
+
333
+ if (error.errno === usb.LIBUSB_TRANSFER_OVERFLOW) {
334
+ return {
335
+ status: 'babble'
336
+ };
337
+ }
338
+
339
+ throw new Error(`transferIn error: ${error}`);
340
+ } finally {
341
+ this.deviceMutex.unlock();
342
+ }
343
+ }
344
+
345
+ public async transferOut(endpointNumber: number, data: ArrayBuffer): Promise<USBOutTransferResult> {
346
+ try {
347
+ await this.deviceMutex.lock();
348
+ const endpoint = this.getEndpoint(endpointNumber | usb.LIBUSB_ENDPOINT_OUT) as OutEndpoint;
349
+ const transfer = promisify(endpoint.transfer).bind(endpoint);
350
+ const buffer = Buffer.from(data);
351
+ const bytesWritten = await transfer(buffer);
352
+
353
+ return {
354
+ bytesWritten,
355
+ status: 'ok'
356
+ };
357
+ } catch (error) {
358
+ if (error.errno === usb.LIBUSB_TRANSFER_STALL) {
359
+ return {
360
+ bytesWritten: 0,
361
+ status: 'stall'
362
+ };
363
+ }
364
+
365
+ throw new Error(`transferOut error: ${error}`);
366
+ } finally {
367
+ this.deviceMutex.unlock();
368
+ }
369
+ }
370
+
371
+ public async isochronousTransferIn(_endpointNumber: number, _packetLengths: number[]): Promise<USBIsochronousInTransferResult> {
372
+ throw new Error('isochronousTransferIn error: method not implemented');
373
+ }
374
+
375
+ public async isochronousTransferOut(_endpointNumber: number, _data: BufferSource, _packetLengths: number[]): Promise<USBIsochronousOutTransferResult> {
376
+ throw new Error('isochronousTransferOut error: method not implemented');
377
+ }
378
+
379
+ public async reset(): Promise<void> {
380
+ try {
381
+ await this.deviceMutex.lock();
382
+ const reset = promisify(this.device.reset).bind(this.device);
383
+ await reset();
384
+ } catch (error) {
385
+ throw new Error(`reset error: ${error}`);
386
+ } finally {
387
+ this.deviceMutex.unlock();
388
+ }
389
+ }
390
+
391
+ private async initialize(): Promise<void> {
392
+ try {
393
+ await this.deviceMutex.lock();
394
+
395
+ if (!this.opened) {
396
+ this.device.open();
397
+ }
398
+
399
+ this.manufacturerName = await this.getStringDescriptor(this.device.deviceDescriptor.iManufacturer);
400
+ this.productName = await this.getStringDescriptor(this.device.deviceDescriptor.iProduct);
401
+ this.serialNumber = await this.getStringDescriptor(this.device.deviceDescriptor.iSerialNumber);
402
+ this.configurations = await this.getConfigurations();
403
+ } finally {
404
+ if (this.opened) {
405
+ this.device.close();
406
+ }
407
+
408
+ this.deviceMutex.unlock();
409
+ }
410
+ }
411
+
412
+ private decodeVersion(version: number): { [key: string]: number } {
413
+ const hex = `0000${version.toString(16)}`.slice(-4);
414
+ return {
415
+ major: parseInt(hex.substr(0, 2), undefined),
416
+ minor: parseInt(hex.substr(2, 1), undefined),
417
+ sub: parseInt(hex.substr(3, 1), undefined),
418
+ };
419
+ }
420
+
421
+ private async getStringDescriptor(index: number): Promise<string> {
422
+ try {
423
+ const getStringDescriptor = promisify(this.device.getStringDescriptor).bind(this.device);
424
+ const buffer = await getStringDescriptor(index);
425
+ return buffer ? buffer.toString() : '';
426
+ } catch (error) {
427
+ return '';
428
+ }
429
+ }
430
+
431
+ private async getConfigurations(): Promise<USBConfiguration[]> {
432
+ const configs: USBConfiguration[] = [];
433
+
434
+ for (const config of this.device.allConfigDescriptors) {
435
+ const interfaces: USBInterface[] = [];
436
+
437
+ for (const iface of config.interfaces) {
438
+ const alternates: USBAlternateInterface[] = [];
439
+
440
+ for (const alternate of iface) {
441
+ const endpoints: USBEndpoint[] = [];
442
+
443
+ for (const endpoint of alternate.endpoints) {
444
+ endpoints.push({
445
+ endpointNumber: endpoint.bEndpointAddress & ENDPOINT_NUMBER_MASK,
446
+ direction: endpoint.bEndpointAddress & usb.LIBUSB_ENDPOINT_IN ? 'in' : 'out',
447
+ type: (endpoint.bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) === usb.LIBUSB_TRANSFER_TYPE_BULK ? 'bulk'
448
+ : (endpoint.bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) === usb.LIBUSB_TRANSFER_TYPE_INTERRUPT ? 'interrupt'
449
+ : 'isochronous',
450
+ packetSize: endpoint.wMaxPacketSize
451
+ });
452
+ }
453
+
454
+ alternates.push({
455
+ alternateSetting: alternate.bAlternateSetting,
456
+ interfaceClass: alternate.bInterfaceClass,
457
+ interfaceSubclass: alternate.bInterfaceSubClass,
458
+ interfaceProtocol: alternate.bInterfaceProtocol,
459
+ interfaceName: await this.getStringDescriptor(alternate.iInterface),
460
+ endpoints
461
+ });
462
+ }
463
+
464
+ const interfaceNumber = iface[0].bInterfaceNumber;
465
+ const alternate = alternates.find(alt => alt.alternateSetting === this.device.interface(interfaceNumber).altSetting);
466
+
467
+ if (alternate) {
468
+ interfaces.push({
469
+ interfaceNumber,
470
+ alternate,
471
+ alternates,
472
+ claimed: false
473
+ });
474
+ }
475
+ }
476
+
477
+ configs.push({
478
+ configurationValue: config.bConfigurationValue,
479
+ configurationName: await this.getStringDescriptor(config.iConfiguration),
480
+ interfaces
481
+ });
482
+ }
483
+
484
+ return configs;
485
+ }
486
+
487
+ private getEndpoint(address: number): Endpoint | undefined {
488
+ if (!this.device.interfaces) {
489
+ return undefined;
490
+ }
491
+
492
+ for (const iface of this.device.interfaces) {
493
+ const endpoint = iface.endpoint(address);
494
+ if (endpoint) {
495
+ return endpoint;
496
+ }
497
+ }
498
+
499
+ return undefined;
500
+ }
501
+
502
+ private controlTransferParamsToType(setup: USBControlTransferParameters, direction: number): number {
503
+ const recipient = setup.recipient === 'device' ? usb.LIBUSB_RECIPIENT_DEVICE
504
+ : setup.recipient === 'interface' ? usb.LIBUSB_RECIPIENT_INTERFACE
505
+ : setup.recipient === 'endpoint' ? usb.LIBUSB_RECIPIENT_ENDPOINT
506
+ : usb.LIBUSB_RECIPIENT_OTHER;
507
+
508
+ const requestType = setup.requestType === 'standard' ? usb.LIBUSB_REQUEST_TYPE_STANDARD
509
+ : setup.requestType === 'class' ? usb.LIBUSB_REQUEST_TYPE_CLASS
510
+ : usb.LIBUSB_REQUEST_TYPE_VENDOR;
511
+
512
+ return recipient | requestType | direction;
513
+ }
514
+
515
+ private async _releaseInterface(interfaceNumber: number): Promise<void> {
516
+ if (!this.opened) {
517
+ throw new Error('releaseInterface error: invalid state');
518
+ }
519
+
520
+ if (!this.configuration) {
521
+ throw new Error('releaseInterface error: interface not found');
522
+ }
523
+
524
+ const iface = this.configuration.interfaces.find(usbInterface => usbInterface.interfaceNumber === interfaceNumber);
525
+ if (!iface) {
526
+ throw new Error('releaseInterface error: interface not found');
527
+ }
528
+
529
+ if (!iface.claimed) {
530
+ return;
531
+ }
532
+
533
+ try {
534
+ const iface = this.device.interface(interfaceNumber);
535
+ const release = promisify(iface.release).bind(iface);
536
+ await release();
537
+ } catch (error) {
538
+ throw new Error(`releaseInterface error: ${error}`);
539
+ }
540
+ }
541
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,17 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es5",
4
+ "strict": true,
5
+ "downlevelIteration": true,
6
+ "noImplicitReturns": true,
7
+ "noEmitOnError": true,
8
+ "noUnusedLocals": true,
9
+ "noUnusedParameters": true,
10
+ "sourceMap": true,
11
+ "declaration": true,
12
+ "outDir": "dist"
13
+ },
14
+ "include": [
15
+ "tsc"
16
+ ]
17
+ }
package/typedoc.json ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "Node USB",
3
+ "entryPoints": [
4
+ "tsc"
5
+ ],
6
+ "excludeExternals": true,
7
+ "excludePrivate": true,
8
+ "hideGenerator": true
9
+ }