xs-dev 1.9.1 → 1.9.2--canary.987899d.0

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xs-dev",
3
- "version": "1.9.1",
3
+ "version": "1.9.2--canary.987899d.0",
4
4
  "description": "CLI for automating the setup and usage of Moddable XS tools",
5
5
  "type": "module",
6
6
  "types": "build/types/types.d.ts",
@@ -0,0 +1,55 @@
1
+ const KNOWN_DEVICES = {
2
+ 0x2e8a: {
3
+ 0x0003: 'Raspberry Pi Pico',
4
+ 0x000f: 'Raspberry Pi Pico 2',
5
+ 0x0004: 'Raspberry Pi Pico',
6
+ 0x0005: 'RP2040 MicroPython',
7
+ 0x0009: 'RP2350 CDC Serial',
8
+ 0x000a: 'RP2040 CDC Serial',
9
+ 0x000b: 'Raspberry Pi Pico 2',
10
+ 0x000c: 'Raspberry Pi Pico 2 W',
11
+ },
12
+ 0x1b4f: {
13
+ 0x0046: 'SparkFun XRP 2350',
14
+ },
15
+ 0x303a: {
16
+ 0x0002: 'ESP32-S2',
17
+ 0x1001: 'ESP32-S3',
18
+ 0x8086: 'ESP32-C3',
19
+ },
20
+ };
21
+ const VENDOR_FALLBACKS = {
22
+ 0x2e8a: 'Raspberry Pi RP Device',
23
+ 0x303a: 'Espressif ESP Device',
24
+ };
25
+ const BRIDGE_VENDORS = {
26
+ 0x10c4: 'CP210x',
27
+ 0x1a86: 'CH340',
28
+ 0x0403: 'FTDI',
29
+ 0x067b: 'PL2303',
30
+ };
31
+ export function identifyDevice(vendorId, productId) {
32
+ if (vendorId === undefined)
33
+ return null;
34
+ const vid = parseInt(vendorId, 16);
35
+ const pid = productId !== undefined ? parseInt(productId, 16) : 0;
36
+ if (isNaN(vid))
37
+ return null;
38
+ const exactMatch = KNOWN_DEVICES[vid]?.[pid];
39
+ if (exactMatch !== undefined) {
40
+ // features require chip-level probing (e.g. picoboot protocol) — not available via VID/PID alone
41
+ return { device: exactMatch, features: '' };
42
+ }
43
+ const vendorFallback = VENDOR_FALLBACKS[vid];
44
+ if (vendorFallback !== undefined) {
45
+ // features require chip-level probing (e.g. picoboot protocol) — not available via VID/PID alone
46
+ return { device: vendorFallback, features: '' };
47
+ }
48
+ const bridge = BRIDGE_VENDORS[vid];
49
+ if (bridge !== undefined) {
50
+ // serial bridge chip identified — features require chip-level probing (e.g. picoboot protocol) — not available via VID/PID alone
51
+ return { device: `Serial Device (${bridge})`, features: '' };
52
+ }
53
+ return null;
54
+ }
55
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGV2aWNlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy90b29sYm94L3NjYW4vZGV2aWNlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFLQSxNQUFNLGFBQWEsR0FBMkM7SUFDNUQsTUFBTSxFQUFFO1FBQ04sTUFBTSxFQUFFLG1CQUFtQjtRQUMzQixNQUFNLEVBQUUscUJBQXFCO1FBQzdCLE1BQU0sRUFBRSxtQkFBbUI7UUFDM0IsTUFBTSxFQUFFLG9CQUFvQjtRQUM1QixNQUFNLEVBQUUsbUJBQW1CO1FBQzNCLE1BQU0sRUFBRSxtQkFBbUI7UUFDM0IsTUFBTSxFQUFFLHFCQUFxQjtRQUM3QixNQUFNLEVBQUUsdUJBQXVCO0tBQ2hDO0lBQ0QsTUFBTSxFQUFFO1FBQ04sTUFBTSxFQUFFLG1CQUFtQjtLQUM1QjtJQUNELE1BQU0sRUFBRTtRQUNOLE1BQU0sRUFBRSxVQUFVO1FBQ2xCLE1BQU0sRUFBRSxVQUFVO1FBQ2xCLE1BQU0sRUFBRSxVQUFVO0tBQ25CO0NBQ0YsQ0FBQTtBQUVELE1BQU0sZ0JBQWdCLEdBQTJCO0lBQy9DLE1BQU0sRUFBRSx3QkFBd0I7SUFDaEMsTUFBTSxFQUFFLHNCQUFzQjtDQUMvQixDQUFBO0FBRUQsTUFBTSxjQUFjLEdBQTJCO0lBQzdDLE1BQU0sRUFBRSxRQUFRO0lBQ2hCLE1BQU0sRUFBRSxPQUFPO0lBQ2YsTUFBTSxFQUFFLE1BQU07SUFDZCxNQUFNLEVBQUUsUUFBUTtDQUNqQixDQUFBO0FBRUQsTUFBTSxVQUFVLGNBQWMsQ0FDNUIsUUFBNEIsRUFDNUIsU0FBNkI7SUFFN0IsSUFBSSxRQUFRLEtBQUssU0FBUztRQUFFLE9BQU8sSUFBSSxDQUFBO0lBQ3ZDLE1BQU0sR0FBRyxHQUFHLFFBQVEsQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDLENBQUE7SUFDbEMsTUFBTSxHQUFHLEdBQUcsU0FBUyxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBO0lBQ2pFLElBQUksS0FBSyxDQUFDLEdBQUcsQ0FBQztRQUFFLE9BQU8sSUFBSSxDQUFBO0lBRTNCLE1BQU0sVUFBVSxHQUFHLGFBQWEsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFBO0lBQzVDLElBQUksVUFBVSxLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQzdCLGlHQUFpRztRQUNqRyxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFLENBQUE7SUFDN0MsQ0FBQztJQUVELE1BQU0sY0FBYyxHQUFHLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxDQUFBO0lBQzVDLElBQUksY0FBYyxLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQ2pDLGlHQUFpRztRQUNqRyxPQUFPLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFLENBQUE7SUFDakQsQ0FBQztJQUVELE1BQU0sTUFBTSxHQUFHLGNBQWMsQ0FBQyxHQUFHLENBQUMsQ0FBQTtJQUNsQyxJQUFJLE1BQU0sS0FBSyxTQUFTLEVBQUUsQ0FBQztRQUN6QixpSUFBaUk7UUFDakksT0FBTyxFQUFFLE1BQU0sRUFBRSxrQkFBa0IsTUFBTSxHQUFHLEVBQUUsUUFBUSxFQUFFLEVBQUUsRUFBRSxDQUFBO0lBQzlELENBQUM7SUFFRCxPQUFPLElBQUksQ0FBQTtBQUNiLENBQUMifQ==
@@ -1,102 +1,36 @@
1
- import { setTimeout as sleep } from 'node:timers/promises';
2
- import { execSync } from 'node:child_process';
1
+ import { debuglog } from 'node:util';
3
2
  import { SerialPort } from 'serialport';
4
- import { findBySerialNumber } from 'usb';
5
- import { parseScanResult } from './parse.js';
6
- import { toolchains } from '../toolchains/registry.js';
7
- import { getHostContext } from '../toolchains/context.js';
3
+ import { identifyDevice } from './devices.js';
4
+ const debug = debuglog('xs-dev:scan');
5
+ function normalizePath(portPath) {
6
+ return portPath.replace('/dev/tty.', '/dev/cu.');
7
+ }
8
8
  export default async function* scanDevices() {
9
- const ctx = getHostContext();
10
- for (const toolchain of Object.values(toolchains).filter((a) => a.platforms.includes(ctx.platform))) {
11
- Object.assign(process.env, toolchain.getEnvVars(ctx));
12
- }
13
- const esptoolPath = (() => {
14
- try {
15
- const result = execSync('which esptool.py', { encoding: 'utf8' }).trim();
16
- return result.length > 0 ? result : null;
17
- }
18
- catch {
19
- return null;
20
- }
21
- })();
22
- if (esptoolPath === null) {
23
- yield {
24
- type: 'warning',
25
- message: 'esptool.py required to scan for Espressif devices. Setup environment for ESP8266 or ESP32:\n xs-dev setup --device esp32\n xs-dev setup --device esp8266.',
26
- };
27
- }
28
- const picotoolPath = (() => {
29
- try {
30
- const result = execSync('which picotool', { encoding: 'utf8' }).trim();
31
- return result.length > 0 ? result : null;
32
- }
33
- catch {
34
- return null;
35
- }
36
- })();
37
- const hasPicotool = picotoolPath !== null;
38
- if (hasPicotool) {
39
- try {
40
- yield {
41
- type: 'step:start',
42
- message: 'Found picotool, rebooting device before scanning',
43
- };
44
- execSync('picotool reboot -fa');
45
- await sleep(1000);
46
- yield { type: 'step:done' };
47
- }
48
- catch {
49
- yield { type: 'step:done' }; // best-effort reboot, continue scanning
50
- }
51
- }
52
9
  yield { type: 'step:start', message: 'Scanning for devices...' };
53
10
  const ports = await SerialPort.list();
54
- const result = await Promise.all(ports
55
- .filter((port) => port.serialNumber !== undefined)
56
- .map(async (port) => {
57
- try {
58
- if (port.vendorId === '2e8a' && hasPicotool) {
59
- const device = await findBySerialNumber(port.serialNumber ?? '');
60
- if (device === null || typeof device === 'undefined') {
61
- return [undefined, port.path];
62
- }
63
- const bus = String(device.busNumber);
64
- const address = String(device.deviceAddress);
65
- const buffer = execSync(`picotool info --bus ${bus} --address ${address} -fa`);
66
- return [buffer, port.path];
67
- }
68
- if (esptoolPath === null) {
69
- return [undefined, port.path];
70
- }
71
- const buffer = execSync(`esptool.py --port ${port.path} read_mac`);
72
- return [buffer, port.path];
73
- }
74
- catch { }
75
- return [undefined, port.path];
76
- }));
77
- const record = parseScanResult(result);
78
- const rows = Object.keys(record).map((port) => {
79
- const { device, features } = record[port];
80
- return [port, device, features];
11
+ const rows = ports
12
+ .filter((port) => port.vendorId !== undefined)
13
+ .flatMap((port) => {
14
+ debug(JSON.stringify(port, null, 2));
15
+ const info = identifyDevice(port.vendorId, port.productId);
16
+ if (info === null)
17
+ return [];
18
+ return [[normalizePath(port.path), info.device, info.features]];
81
19
  });
82
20
  if (rows.length === 0) {
83
21
  yield { type: 'warning', message: 'No available devices found.' };
22
+ return;
84
23
  }
85
- else {
24
+ yield { type: 'step:done', message: 'Found the following available devices!' };
25
+ const allRows = [['Port', 'Device', 'Features'], ...rows];
26
+ const colWidths = allRows[0].map((_, colIdx) => Math.max(...allRows.map((row) => String(row[colIdx]).length)));
27
+ for (const row of allRows) {
86
28
  yield {
87
- type: 'step:done',
88
- message: 'Found the following available devices!',
29
+ type: 'info',
30
+ message: row
31
+ .map((cell, idx) => String(cell).padEnd(colWidths[idx]))
32
+ .join(' '),
89
33
  };
90
- const allRows = [['Port', 'Device', 'Features'], ...rows];
91
- const colWidths = allRows[0].map((_, colIdx) => Math.max(...allRows.map((row) => String(row[colIdx]).length)));
92
- for (const row of allRows) {
93
- yield {
94
- type: 'info',
95
- message: row
96
- .map((cell, idx) => String(cell).padEnd(colWidths[idx]))
97
- .join(' '),
98
- };
99
- }
100
34
  }
101
35
  }
102
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvdG9vbGJveC9zY2FuL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLElBQUksS0FBSyxFQUFFLE1BQU0sc0JBQXNCLENBQUE7QUFDMUQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLG9CQUFvQixDQUFBO0FBQzdDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxZQUFZLENBQUE7QUFDdkMsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sS0FBSyxDQUFBO0FBRXhDLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxZQUFZLENBQUE7QUFDNUMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDJCQUEyQixDQUFBO0FBQ3RELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQTtBQUV6RCxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssU0FBUyxDQUFDLENBQUMsV0FBVztJQUN4QyxNQUFNLEdBQUcsR0FBRyxjQUFjLEVBQUUsQ0FBQTtJQUM1QixLQUFLLE1BQU0sU0FBUyxJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FDN0QsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUNuQyxFQUFFLENBQUM7UUFDRixNQUFNLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsU0FBUyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFBO0lBQ3ZELENBQUM7SUFFRCxNQUFNLFdBQVcsR0FBRyxDQUFDLEdBQUcsRUFBRTtRQUN4QixJQUFJLENBQUM7WUFDSCxNQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsa0JBQWtCLEVBQUUsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQTtZQUN4RSxPQUFPLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQTtRQUMxQyxDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsT0FBTyxJQUFJLENBQUE7UUFDYixDQUFDO0lBQ0gsQ0FBQyxDQUFDLEVBQUUsQ0FBQTtJQUVKLElBQUksV0FBVyxLQUFLLElBQUksRUFBRSxDQUFDO1FBQ3pCLE1BQU07WUFDSixJQUFJLEVBQUUsU0FBUztZQUNmLE9BQU8sRUFDTCwySkFBMko7U0FDOUosQ0FBQTtJQUNILENBQUM7SUFFRCxNQUFNLFlBQVksR0FBRyxDQUFDLEdBQUcsRUFBRTtRQUN6QixJQUFJLENBQUM7WUFDSCxNQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQTtZQUN0RSxPQUFPLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQTtRQUMxQyxDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsT0FBTyxJQUFJLENBQUE7UUFDYixDQUFDO0lBQ0gsQ0FBQyxDQUFDLEVBQUUsQ0FBQTtJQUNKLE1BQU0sV0FBVyxHQUFHLFlBQVksS0FBSyxJQUFJLENBQUE7SUFFekMsSUFBSSxXQUFXLEVBQUUsQ0FBQztRQUNoQixJQUFJLENBQUM7WUFDSCxNQUFNO2dCQUNKLElBQUksRUFBRSxZQUFZO2dCQUNsQixPQUFPLEVBQUUsa0RBQWtEO2FBQzVELENBQUE7WUFDRCxRQUFRLENBQUMscUJBQXFCLENBQUMsQ0FBQTtZQUMvQixNQUFNLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQTtZQUNqQixNQUFNLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxDQUFBO1FBQzdCLENBQUM7UUFBQyxNQUFNLENBQUM7WUFDUCxNQUFNLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxDQUFBLENBQUMsd0NBQXdDO1FBQ3RFLENBQUM7SUFDSCxDQUFDO0lBRUQsTUFBTSxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLHlCQUF5QixFQUFFLENBQUE7SUFFaEUsTUFBTSxLQUFLLEdBQUcsTUFBTSxVQUFVLENBQUMsSUFBSSxFQUFFLENBQUE7SUFDckMsTUFBTSxNQUFNLEdBRVIsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUNuQixLQUFLO1NBQ0YsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsWUFBWSxLQUFLLFNBQVMsQ0FBQztTQUNqRCxHQUFHLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxFQUFFO1FBQ2xCLElBQUksQ0FBQztZQUNILElBQUksSUFBSSxDQUFDLFFBQVEsS0FBSyxNQUFNLElBQUksV0FBVyxFQUFFLENBQUM7Z0JBQzVDLE1BQU0sTUFBTSxHQUFHLE1BQU0sa0JBQWtCLENBQUMsSUFBSSxDQUFDLFlBQVksSUFBSSxFQUFFLENBQUMsQ0FBQTtnQkFDaEUsSUFBSSxNQUFNLEtBQUssSUFBSSxJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVcsRUFBRSxDQUFDO29CQUNyRCxPQUFPLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQXdCLENBQUE7Z0JBQ3RELENBQUM7Z0JBQ0QsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQTtnQkFDcEMsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQTtnQkFDNUMsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUNyQix1QkFBdUIsR0FBRyxjQUFjLE9BQU8sTUFBTSxDQUN0RCxDQUFBO2dCQUNELE9BQU8sQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBcUIsQ0FBQTtZQUNoRCxDQUFDO1lBQ0QsSUFBSSxXQUFXLEtBQUssSUFBSSxFQUFFLENBQUM7Z0JBQ3pCLE9BQU8sQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBd0IsQ0FBQTtZQUN0RCxDQUFDO1lBQ0QsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLHFCQUFxQixJQUFJLENBQUMsSUFBSSxXQUFXLENBQUMsQ0FBQTtZQUNsRSxPQUFPLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQXFCLENBQUE7UUFDaEQsQ0FBQztRQUFDLE1BQU0sQ0FBQyxDQUFBLENBQUM7UUFDVixPQUFPLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUMvQixDQUFDLENBQUMsQ0FDTCxDQUFBO0lBRUQsTUFBTSxNQUFNLEdBQUcsZUFBZSxDQUFDLE1BQU0sQ0FBQyxDQUFBO0lBQ3RDLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUU7UUFDNUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDekMsT0FBTyxDQUFDLElBQUksRUFBRSxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUE7SUFDakMsQ0FBQyxDQUFDLENBQUE7SUFFRixJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDdEIsTUFBTSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLDZCQUE2QixFQUFFLENBQUE7SUFDbkUsQ0FBQztTQUFNLENBQUM7UUFDTixNQUFNO1lBQ0osSUFBSSxFQUFFLFdBQVc7WUFDakIsT0FBTyxFQUFFLHdDQUF3QztTQUNsRCxDQUFBO1FBQ0QsTUFBTSxPQUFPLEdBQUcsQ0FBQyxDQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsVUFBVSxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQTtRQUN6RCxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxFQUFFLENBQzdDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FDOUQsQ0FBQTtRQUNELEtBQUssTUFBTSxHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7WUFDMUIsTUFBTTtnQkFDSixJQUFJLEVBQUUsTUFBTTtnQkFDWixPQUFPLEVBQUUsR0FBRztxQkFDVCxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO3FCQUN2RCxJQUFJLENBQUMsSUFBSSxDQUFDO2FBQ2QsQ0FBQTtRQUNILENBQUM7SUFDSCxDQUFDO0FBQ0gsQ0FBQyJ9
36
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvdG9vbGJveC9zY2FuL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxXQUFXLENBQUE7QUFDcEMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLFlBQVksQ0FBQTtBQUV2QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sY0FBYyxDQUFBO0FBRTdDLE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsQ0FBQTtBQUVyQyxTQUFTLGFBQWEsQ0FBQyxRQUFnQjtJQUNyQyxPQUFPLFFBQVEsQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFLFVBQVUsQ0FBQyxDQUFBO0FBQ2xELENBQUM7QUFFRCxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssU0FBUyxDQUFDLENBQUMsV0FBVztJQUN4QyxNQUFNLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxPQUFPLEVBQUUseUJBQXlCLEVBQUUsQ0FBQTtJQUVoRSxNQUFNLEtBQUssR0FBRyxNQUFNLFVBQVUsQ0FBQyxJQUFJLEVBQUUsQ0FBQTtJQUVyQyxNQUFNLElBQUksR0FBRyxLQUFLO1NBQ2YsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsUUFBUSxLQUFLLFNBQVMsQ0FBQztTQUM3QyxPQUFPLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtRQUNoQixLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFDcEMsTUFBTSxJQUFJLEdBQUcsY0FBYyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFBO1FBQzFELElBQUksSUFBSSxLQUFLLElBQUk7WUFBRSxPQUFPLEVBQUUsQ0FBQTtRQUM1QixPQUFPLENBQUMsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUE7SUFDakUsQ0FBQyxDQUFDLENBQUE7SUFFSixJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDdEIsTUFBTSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLDZCQUE2QixFQUFFLENBQUE7UUFDakUsT0FBTTtJQUNSLENBQUM7SUFFRCxNQUFNLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxPQUFPLEVBQUUsd0NBQXdDLEVBQUUsQ0FBQTtJQUM5RSxNQUFNLE9BQU8sR0FBRyxDQUFDLENBQUMsTUFBTSxFQUFFLFFBQVEsRUFBRSxVQUFVLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFBO0lBQ3pELE1BQU0sU0FBUyxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxFQUFFLEVBQUUsQ0FDN0MsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUM5RCxDQUFBO0lBQ0QsS0FBSyxNQUFNLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQztRQUMxQixNQUFNO1lBQ0osSUFBSSxFQUFFLE1BQU07WUFDWixPQUFPLEVBQUUsR0FBRztpQkFDVCxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO2lCQUN2RCxJQUFJLENBQUMsSUFBSSxDQUFDO1NBQ2QsQ0FBQTtJQUNILENBQUM7QUFDSCxDQUFDIn0=
@@ -0,0 +1,5 @@
1
+ export interface DeviceInfo {
2
+ device: string;
3
+ features: string;
4
+ }
5
+ export declare function identifyDevice(vendorId: string | undefined, productId: string | undefined): DeviceInfo | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xs-dev",
3
- "version": "1.9.1",
3
+ "version": "1.9.2--canary.987899d.0",
4
4
  "description": "CLI for automating the setup and usage of Moddable XS tools",
5
5
  "type": "module",
6
6
  "types": "build/types/types.d.ts",
@@ -1,82 +0,0 @@
1
- function parseEsptoolLines(lines) {
2
- let state = 'searching';
3
- let currentPort = null;
4
- return lines.reduce((result, line) => {
5
- if (state === 'searching') {
6
- if (line.startsWith('Serial port')) {
7
- currentPort = line.replace('Serial port ', '').replace('tty', 'cu');
8
- result[currentPort] = { device: '', features: '' };
9
- state = 'portFound';
10
- }
11
- }
12
- if (state === 'portFound') {
13
- if (line.startsWith('Chip is ') && currentPort !== null) {
14
- const device = line.replace('Chip is ', '');
15
- result[currentPort].device = device;
16
- state = 'deviceFound';
17
- }
18
- if (line.includes('failed to connect') && currentPort !== null) {
19
- // oxlint-disable-next-line @typescript-eslint/no-dynamic-delete
20
- delete result[currentPort];
21
- currentPort = null;
22
- state = 'searching';
23
- }
24
- }
25
- if (state === 'deviceFound') {
26
- if (line.startsWith('Features: ') && currentPort !== null) {
27
- const features = line.replace('Features: ', '');
28
- result[currentPort].features = features;
29
- state = 'featuresFound';
30
- }
31
- }
32
- if (state === 'featuresFound') {
33
- if (line.startsWith('Hard resetting')) {
34
- currentPort = null;
35
- state = 'searching';
36
- }
37
- }
38
- return result;
39
- }, {});
40
- }
41
- function parsePicotoolLines(lines, port) {
42
- let state = 'searching';
43
- const currentPort = port.replace('tty', 'cu');
44
- return lines.reduce((result, line) => {
45
- if (state === 'searching') {
46
- result[currentPort] = { device: '', features: '' };
47
- state = 'portFound';
48
- }
49
- if (state === 'portFound') {
50
- if (line.trim().startsWith('features')) {
51
- const [, features] = line.split(':');
52
- result[currentPort].features = features.trim();
53
- state = 'featuresFound';
54
- }
55
- }
56
- if (state === 'featuresFound') {
57
- if (line.trim().startsWith('pico_board')) {
58
- const [, device] = line.split(':');
59
- result[currentPort].device = device.trim();
60
- state = 'deviceFound';
61
- }
62
- }
63
- if (state === 'deviceFound') {
64
- if (line.includes('asked to reboot')) {
65
- state = 'searching';
66
- }
67
- }
68
- return result;
69
- }, {});
70
- }
71
- export function parseScanResult(scans) {
72
- return scans.reduce((result, [output, port]) => {
73
- if (typeof output === 'undefined')
74
- return result;
75
- const lines = String(output).split('\n');
76
- if (output.includes('pico_board')) {
77
- return { ...result, ...parsePicotoolLines(lines, port) };
78
- }
79
- return { ...result, ...parseEsptoolLines(lines) };
80
- }, {});
81
- }
82
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvdG9vbGJveC9zY2FuL3BhcnNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUdBLFNBQVMsaUJBQWlCLENBQUMsS0FBZTtJQUN4QyxJQUFJLEtBQUssR0FBZSxXQUFXLENBQUE7SUFDbkMsSUFBSSxXQUFXLEdBQWtCLElBQUksQ0FBQTtJQUVyQyxPQUFPLEtBQUssQ0FBQyxNQUFNLENBQWEsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLEVBQUU7UUFDL0MsSUFBSSxLQUFLLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDMUIsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUM7Z0JBQ25DLFdBQVcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLGNBQWMsRUFBRSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFBO2dCQUNuRSxNQUFNLENBQUMsV0FBVyxDQUFDLEdBQUcsRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsQ0FBQTtnQkFDbEQsS0FBSyxHQUFHLFdBQVcsQ0FBQTtZQUNyQixDQUFDO1FBQ0gsQ0FBQztRQUVELElBQUksS0FBSyxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQzFCLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsSUFBSSxXQUFXLEtBQUssSUFBSSxFQUFFLENBQUM7Z0JBQ3hELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQyxDQUFBO2dCQUMzQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQTtnQkFDbkMsS0FBSyxHQUFHLGFBQWEsQ0FBQTtZQUN2QixDQUFDO1lBQ0QsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLG1CQUFtQixDQUFDLElBQUksV0FB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
@@ -1,9 +0,0 @@
1
- type ScanResult = Record<string, {
2
- device: string;
3
- features: string;
4
- }>;
5
- export declare function parseScanResult(scans: Array<[
6
- output: Buffer,
7
- port: string
8
- ] | [output: undefined, port: string]>): ScanResult;
9
- export {};