@bharper/atv-js 0.2.3

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 (86) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +80 -0
  3. package/dist/airplay/auth.d.ts +24 -0
  4. package/dist/airplay/auth.d.ts.map +1 -0
  5. package/dist/airplay/auth.js +195 -0
  6. package/dist/airplay/auth.js.map +1 -0
  7. package/dist/bplist.d.ts +19 -0
  8. package/dist/bplist.d.ts.map +1 -0
  9. package/dist/bplist.js +141 -0
  10. package/dist/bplist.js.map +1 -0
  11. package/dist/companion/auth.d.ts +34 -0
  12. package/dist/companion/auth.d.ts.map +1 -0
  13. package/dist/companion/auth.js +119 -0
  14. package/dist/companion/auth.js.map +1 -0
  15. package/dist/companion/connection.d.ts +50 -0
  16. package/dist/companion/connection.d.ts.map +1 -0
  17. package/dist/companion/connection.js +170 -0
  18. package/dist/companion/connection.js.map +1 -0
  19. package/dist/companion/keyboard.d.ts +39 -0
  20. package/dist/companion/keyboard.d.ts.map +1 -0
  21. package/dist/companion/keyboard.js +127 -0
  22. package/dist/companion/keyboard.js.map +1 -0
  23. package/dist/companion/pairing_keepalive.d.ts +4 -0
  24. package/dist/companion/pairing_keepalive.d.ts.map +1 -0
  25. package/dist/companion/pairing_keepalive.js +68 -0
  26. package/dist/companion/pairing_keepalive.js.map +1 -0
  27. package/dist/companion/protocol.d.ts +64 -0
  28. package/dist/companion/protocol.d.ts.map +1 -0
  29. package/dist/companion/protocol.js +246 -0
  30. package/dist/companion/protocol.js.map +1 -0
  31. package/dist/companion/remote.d.ts +75 -0
  32. package/dist/companion/remote.d.ts.map +1 -0
  33. package/dist/companion/remote.js +142 -0
  34. package/dist/companion/remote.js.map +1 -0
  35. package/dist/crypto/chacha20.d.ts +27 -0
  36. package/dist/crypto/chacha20.d.ts.map +1 -0
  37. package/dist/crypto/chacha20.js +88 -0
  38. package/dist/crypto/chacha20.js.map +1 -0
  39. package/dist/crypto/hkdf.d.ts +6 -0
  40. package/dist/crypto/hkdf.d.ts.map +1 -0
  41. package/dist/crypto/hkdf.js +45 -0
  42. package/dist/crypto/hkdf.js.map +1 -0
  43. package/dist/index.d.ts +85 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +191 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/mdns.d.ts +20 -0
  48. package/dist/mdns.d.ts.map +1 -0
  49. package/dist/mdns.js +165 -0
  50. package/dist/mdns.js.map +1 -0
  51. package/dist/opack.d.ts +21 -0
  52. package/dist/opack.d.ts.map +1 -0
  53. package/dist/opack.js +350 -0
  54. package/dist/opack.js.map +1 -0
  55. package/dist/pairing/credentials.d.ts +23 -0
  56. package/dist/pairing/credentials.d.ts.map +1 -0
  57. package/dist/pairing/credentials.js +31 -0
  58. package/dist/pairing/credentials.js.map +1 -0
  59. package/dist/pairing/srp.d.ts +54 -0
  60. package/dist/pairing/srp.d.ts.map +1 -0
  61. package/dist/pairing/srp.js +221 -0
  62. package/dist/pairing/srp.js.map +1 -0
  63. package/dist/pairing/tlv.d.ts +26 -0
  64. package/dist/pairing/tlv.d.ts.map +1 -0
  65. package/dist/pairing/tlv.js +68 -0
  66. package/dist/pairing/tlv.js.map +1 -0
  67. package/examples/pair.ts +103 -0
  68. package/examples/remote.ts +212 -0
  69. package/package.json +33 -0
  70. package/src/airplay/auth.ts +207 -0
  71. package/src/bplist.ts +136 -0
  72. package/src/companion/auth.ts +141 -0
  73. package/src/companion/connection.ts +161 -0
  74. package/src/companion/keyboard.ts +155 -0
  75. package/src/companion/pairing_keepalive.ts +75 -0
  76. package/src/companion/protocol.ts +253 -0
  77. package/src/companion/remote.ts +151 -0
  78. package/src/crypto/chacha20.ts +93 -0
  79. package/src/crypto/hkdf.ts +18 -0
  80. package/src/index.ts +248 -0
  81. package/src/mdns.ts +198 -0
  82. package/src/opack.ts +299 -0
  83. package/src/pairing/credentials.ts +44 -0
  84. package/src/pairing/srp.ts +234 -0
  85. package/src/pairing/tlv.ts +64 -0
  86. package/tsconfig.json +19 -0
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ /**
3
+ * HKDF-SHA512 key derivation.
4
+ * Port of pyatv/auth/hap_srp.py hkdf_expand().
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || (function () {
23
+ var ownKeys = function(o) {
24
+ ownKeys = Object.getOwnPropertyNames || function (o) {
25
+ var ar = [];
26
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
+ return ar;
28
+ };
29
+ return ownKeys(o);
30
+ };
31
+ return function (mod) {
32
+ if (mod && mod.__esModule) return mod;
33
+ var result = {};
34
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
+ __setModuleDefault(result, mod);
36
+ return result;
37
+ };
38
+ })();
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.hkdfExpand = hkdfExpand;
41
+ const crypto = __importStar(require("crypto"));
42
+ function hkdfExpand(salt, info, sharedSecret) {
43
+ return Buffer.from(crypto.hkdfSync('sha512', sharedSecret, Buffer.from(salt, 'utf-8'), Buffer.from(info, 'utf-8'), 32));
44
+ }
45
+ //# sourceMappingURL=hkdf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hkdf.js","sourceRoot":"","sources":["../../src/crypto/hkdf.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIH,gCAUC;AAZD,+CAAiC;AAEjC,SAAgB,UAAU,CAAC,IAAY,EAAE,IAAY,EAAE,YAAoB;IACzE,OAAO,MAAM,CAAC,IAAI,CAChB,MAAM,CAAC,QAAQ,CACb,QAAQ,EACR,YAAY,EACZ,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,EAC1B,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,EAC1B,EAAE,CACH,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * atv-js: Apple TV control library.
3
+ * mDNS discovery, AirPlay/Companion pairing, remote control, keyboard input.
4
+ */
5
+ export { AppleTVDevice, scan } from './mdns';
6
+ export { HapCredentials, Credentials, parseCredentials, serializeCredentials } from './pairing/credentials';
7
+ export { RemoteKey, HidCommand, MediaControlCommand } from './companion/remote';
8
+ export { KeyboardFocusState } from './companion/keyboard';
9
+ import { AppleTVDevice } from './mdns';
10
+ import { CompanionProtocol } from './companion/protocol';
11
+ import { CompanionPairSetupProcedure } from './companion/auth';
12
+ import { HapCredentials, Credentials } from './pairing/credentials';
13
+ import { AirPlayPairingSession } from './airplay/auth';
14
+ import { sendKeyDown, sendKeyUp, RemoteKey } from './companion/remote';
15
+ import { KeyboardFocusState } from './companion/keyboard';
16
+ export interface PairingSession {
17
+ /** @internal */
18
+ _type: 'airplay' | 'companion';
19
+ /** @internal */
20
+ _airplay?: AirPlayPairingSession;
21
+ /** @internal */
22
+ _companionProtocol?: CompanionProtocol;
23
+ /** @internal */
24
+ _companionProcedure?: CompanionPairSetupProcedure;
25
+ }
26
+ /**
27
+ * Start AirPlay pairing with a discovered device.
28
+ * This triggers the PIN display on the Apple TV.
29
+ */
30
+ export declare function startAirPlayPairing(device: AppleTVDevice): Promise<PairingSession>;
31
+ /**
32
+ * Finish AirPlay pairing with the PIN shown on screen.
33
+ */
34
+ export declare function finishAirPlayPairing(session: PairingSession, pin: string, displayName?: string): Promise<HapCredentials>;
35
+ /**
36
+ * Start Companion protocol pairing with a discovered device.
37
+ * This triggers a second PIN display on the Apple TV.
38
+ */
39
+ export declare function startCompanionPairing(device: AppleTVDevice): Promise<PairingSession>;
40
+ /**
41
+ * Finish Companion pairing with the PIN shown on screen.
42
+ */
43
+ export declare function finishCompanionPairing(session: PairingSession, pin: string, displayName?: string): Promise<HapCredentials>;
44
+ export interface AppleTVConnection {
45
+ protocol: CompanionProtocol;
46
+ device: AppleTVDevice;
47
+ credentials: Credentials;
48
+ /** @internal */
49
+ _keyboardFocusState: KeyboardFocusState;
50
+ }
51
+ /**
52
+ * Connect to an Apple TV using stored credentials.
53
+ * Performs pair-verify and sets up encrypted Companion channel.
54
+ */
55
+ export declare function connect(device: AppleTVDevice, credentials: Credentials): Promise<AppleTVConnection>;
56
+ /**
57
+ * Send a remote control key press (button down + up).
58
+ */
59
+ export declare function sendKey(conn: AppleTVConnection, key: RemoteKey | string): Promise<void>;
60
+ export { sendKeyDown, sendKeyUp };
61
+ /**
62
+ * Check if keyboard is currently focused.
63
+ */
64
+ export declare function getKeyboardFocusState(conn: AppleTVConnection): Promise<boolean>;
65
+ /**
66
+ * Get the current text from a focused keyboard field.
67
+ */
68
+ export declare function getText(conn: AppleTVConnection): Promise<string | null>;
69
+ /**
70
+ * Set (replace) the text in a focused keyboard field.
71
+ */
72
+ export declare function setText(conn: AppleTVConnection, text: string): Promise<void>;
73
+ /**
74
+ * Set a handler for connection loss events.
75
+ */
76
+ export declare function onConnectionLost(conn: AppleTVConnection, handler: (error?: Error) => void): void;
77
+ /**
78
+ * Disconnect from the Apple TV.
79
+ */
80
+ export declare function disconnect(conn: AppleTVConnection): void;
81
+ /**
82
+ * Check if still connected to the Apple TV.
83
+ */
84
+ export declare function isConnected(conn: AppleTVConnection): boolean;
85
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,191 @@
1
+ "use strict";
2
+ /**
3
+ * atv-js: Apple TV control library.
4
+ * mDNS discovery, AirPlay/Companion pairing, remote control, keyboard input.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.sendKeyUp = exports.sendKeyDown = exports.KeyboardFocusState = exports.MediaControlCommand = exports.HidCommand = exports.RemoteKey = exports.serializeCredentials = exports.parseCredentials = exports.scan = void 0;
8
+ exports.startAirPlayPairing = startAirPlayPairing;
9
+ exports.finishAirPlayPairing = finishAirPlayPairing;
10
+ exports.startCompanionPairing = startCompanionPairing;
11
+ exports.finishCompanionPairing = finishCompanionPairing;
12
+ exports.connect = connect;
13
+ exports.sendKey = sendKey;
14
+ exports.getKeyboardFocusState = getKeyboardFocusState;
15
+ exports.getText = getText;
16
+ exports.setText = setText;
17
+ exports.onConnectionLost = onConnectionLost;
18
+ exports.disconnect = disconnect;
19
+ exports.isConnected = isConnected;
20
+ var mdns_1 = require("./mdns");
21
+ Object.defineProperty(exports, "scan", { enumerable: true, get: function () { return mdns_1.scan; } });
22
+ var credentials_1 = require("./pairing/credentials");
23
+ Object.defineProperty(exports, "parseCredentials", { enumerable: true, get: function () { return credentials_1.parseCredentials; } });
24
+ Object.defineProperty(exports, "serializeCredentials", { enumerable: true, get: function () { return credentials_1.serializeCredentials; } });
25
+ var remote_1 = require("./companion/remote");
26
+ Object.defineProperty(exports, "RemoteKey", { enumerable: true, get: function () { return remote_1.RemoteKey; } });
27
+ Object.defineProperty(exports, "HidCommand", { enumerable: true, get: function () { return remote_1.HidCommand; } });
28
+ Object.defineProperty(exports, "MediaControlCommand", { enumerable: true, get: function () { return remote_1.MediaControlCommand; } });
29
+ var keyboard_1 = require("./companion/keyboard");
30
+ Object.defineProperty(exports, "KeyboardFocusState", { enumerable: true, get: function () { return keyboard_1.KeyboardFocusState; } });
31
+ const connection_1 = require("./companion/connection");
32
+ const protocol_1 = require("./companion/protocol");
33
+ const auth_1 = require("./companion/auth");
34
+ const pairing_keepalive_1 = require("./companion/pairing_keepalive");
35
+ const srp_1 = require("./pairing/srp");
36
+ const auth_2 = require("./airplay/auth");
37
+ const remote_2 = require("./companion/remote");
38
+ Object.defineProperty(exports, "sendKeyDown", { enumerable: true, get: function () { return remote_2.sendKeyDown; } });
39
+ Object.defineProperty(exports, "sendKeyUp", { enumerable: true, get: function () { return remote_2.sendKeyUp; } });
40
+ const keyboard_2 = require("./companion/keyboard");
41
+ const opack_1 = require("./opack");
42
+ /**
43
+ * Start AirPlay pairing with a discovered device.
44
+ * This triggers the PIN display on the Apple TV.
45
+ */
46
+ async function startAirPlayPairing(device) {
47
+ const session = await (0, auth_2.startAirPlayPairing)(device.address, device.airplayPort);
48
+ return { _type: 'airplay', _airplay: session };
49
+ }
50
+ /**
51
+ * Finish AirPlay pairing with the PIN shown on screen.
52
+ */
53
+ async function finishAirPlayPairing(session, pin, displayName) {
54
+ if (session._type !== 'airplay' || !session._airplay) {
55
+ throw new Error('Not an AirPlay pairing session');
56
+ }
57
+ return (0, auth_2.finishAirPlayPairing)(session._airplay, pin, displayName);
58
+ }
59
+ /**
60
+ * Start Companion protocol pairing with a discovered device.
61
+ * This triggers a second PIN display on the Apple TV.
62
+ */
63
+ async function startCompanionPairing(device) {
64
+ const connection = (0, pairing_keepalive_1.getCompanionPairingConnection)(device.address, device.port);
65
+ const protocol = new protocol_1.CompanionProtocol(connection, null);
66
+ connection.setListener(protocol);
67
+ const srp = new srp_1.SRPAuthHandler();
68
+ const procedure = new auth_1.CompanionPairSetupProcedure(protocol, srp);
69
+ // Start pairing (connects + sends PS_Start)
70
+ await procedure.startPairing();
71
+ return {
72
+ _type: 'companion',
73
+ _companionProtocol: protocol,
74
+ _companionProcedure: procedure,
75
+ };
76
+ }
77
+ /**
78
+ * Finish Companion pairing with the PIN shown on screen.
79
+ */
80
+ async function finishCompanionPairing(session, pin, displayName) {
81
+ if (session._type !== 'companion' || !session._companionProcedure) {
82
+ throw new Error('Not a Companion pairing session');
83
+ }
84
+ const creds = await session._companionProcedure.finishPairing(pin.trim(), displayName);
85
+ // Release the pairing connection back to the keep-alive cache
86
+ if (session._companionProtocol) {
87
+ (0, pairing_keepalive_1.releaseCompanionPairingConnection)(session._companionProtocol.connection);
88
+ }
89
+ return creds;
90
+ }
91
+ /**
92
+ * Connect to an Apple TV using stored credentials.
93
+ * Performs pair-verify and sets up encrypted Companion channel.
94
+ */
95
+ async function connect(device, credentials) {
96
+ const connection = new connection_1.CompanionConnection(device.address, device.port);
97
+ const protocol = new protocol_1.CompanionProtocol(connection, credentials.companion);
98
+ connection.setListener(protocol);
99
+ // Connect, verify credentials, enable encryption
100
+ await protocol.start();
101
+ // Post-connection initialization (order matters!)
102
+ // 1. Send system info
103
+ // Client ID is stored hex-encoded in credentials, decode to get the actual UUID bytes
104
+ const clientIdHex = credentials.companion.split(':')[3] || '';
105
+ const clientIdBytes = Buffer.from(clientIdHex, 'hex'); // UUID as bytes
106
+ await protocol.sendCommand('_systemInfo', {
107
+ _bf: 0,
108
+ _cf: 512,
109
+ _clFl: 128,
110
+ _i: null,
111
+ _idsID: clientIdBytes,
112
+ _pubID: 'FF:70:79:61:74:76',
113
+ _sf: 256,
114
+ _sv: '170.18',
115
+ model: 'iPhone10,6',
116
+ name: 'atv-js',
117
+ });
118
+ // 2. Start touch input (must be before _sessionStart)
119
+ await protocol.sendCommand('_touchStart', {
120
+ _height: (0, opack_1.opackFloat)(1000.0),
121
+ _tFl: 0,
122
+ _width: (0, opack_1.opackFloat)(1000.0),
123
+ });
124
+ // 3. Start a session
125
+ const sessionId = Math.floor(Math.random() * 0xFFFFFFFF);
126
+ await protocol.sendCommand('_sessionStart', {
127
+ _srvT: 'com.apple.tvremoteservices',
128
+ _sid: sessionId,
129
+ });
130
+ // 4. Start text input session
131
+ await protocol.sendCommand('_tiStart', {});
132
+ // 5. Subscribe to media control events
133
+ protocol.subscribeEvent('_iMC');
134
+ const conn = {
135
+ protocol,
136
+ device,
137
+ credentials,
138
+ _keyboardFocusState: keyboard_2.KeyboardFocusState.Unknown,
139
+ };
140
+ // Watch keyboard focus state
141
+ (0, keyboard_2.watchKeyboardFocus)(protocol, (state) => {
142
+ conn._keyboardFocusState = state;
143
+ });
144
+ return conn;
145
+ }
146
+ // ---- Remote Control ----
147
+ /**
148
+ * Send a remote control key press (button down + up).
149
+ */
150
+ async function sendKey(conn, key) {
151
+ return (0, remote_2.sendKeyPress)(conn.protocol, key);
152
+ }
153
+ // ---- Keyboard ----
154
+ /**
155
+ * Check if keyboard is currently focused.
156
+ */
157
+ async function getKeyboardFocusState(conn) {
158
+ return (0, keyboard_2.getKeyboardFocus)(conn.protocol);
159
+ }
160
+ /**
161
+ * Get the current text from a focused keyboard field.
162
+ */
163
+ async function getText(conn) {
164
+ return (0, keyboard_2.getText)(conn.protocol);
165
+ }
166
+ /**
167
+ * Set (replace) the text in a focused keyboard field.
168
+ */
169
+ async function setText(conn, text) {
170
+ return (0, keyboard_2.setText)(conn.protocol, text);
171
+ }
172
+ // ---- Connection Management ----
173
+ /**
174
+ * Set a handler for connection loss events.
175
+ */
176
+ function onConnectionLost(conn, handler) {
177
+ conn.protocol.onConnectionLost = handler;
178
+ }
179
+ /**
180
+ * Disconnect from the Apple TV.
181
+ */
182
+ function disconnect(conn) {
183
+ conn.protocol.close();
184
+ }
185
+ /**
186
+ * Check if still connected to the Apple TV.
187
+ */
188
+ function isConnected(conn) {
189
+ return conn.protocol.connection.isConnected;
190
+ }
191
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/mdns.d.ts ADDED
@@ -0,0 +1,20 @@
1
+ /**
2
+ * mDNS device scanning for Apple TV discovery.
3
+ * Queries for _companion-link._tcp and _airplay._tcp services.
4
+ */
5
+ export interface AppleTVDevice {
6
+ name: string;
7
+ address: string;
8
+ /** Companion protocol port */
9
+ port: number;
10
+ /** AirPlay port */
11
+ airplayPort: number;
12
+ /** Unique device identifier (from mDNS name or properties) */
13
+ identifier: string;
14
+ /** Device model (e.g. "AppleTV6,2") */
15
+ model: string;
16
+ /** Raw mDNS TXT properties */
17
+ properties: Record<string, string>;
18
+ }
19
+ export declare function scan(timeout?: number, onlyAppleTV?: boolean): Promise<AppleTVDevice[]>;
20
+ //# sourceMappingURL=mdns.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mdns.d.ts","sourceRoot":"","sources":["../src/mdns.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,mBAAmB;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,8DAA8D;IAC9D,UAAU,EAAE,MAAM,CAAC;IACnB,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,8BAA8B;IAC9B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAwBD,wBAAsB,IAAI,CAAC,OAAO,SAAO,EAAE,WAAW,UAAO,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAyJvF"}
package/dist/mdns.js ADDED
@@ -0,0 +1,165 @@
1
+ "use strict";
2
+ /**
3
+ * mDNS device scanning for Apple TV discovery.
4
+ * Queries for _companion-link._tcp and _airplay._tcp services.
5
+ */
6
+ var __importDefault = (this && this.__importDefault) || function (mod) {
7
+ return (mod && mod.__esModule) ? mod : { "default": mod };
8
+ };
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.scan = scan;
11
+ const multicast_dns_1 = __importDefault(require("multicast-dns"));
12
+ const APPLE_TV_MODELS = new Set([
13
+ 'J33AP',
14
+ 'J33DAP',
15
+ 'J42dAP',
16
+ 'J105aAP',
17
+ 'J305AP',
18
+ 'J255AP',
19
+ ]);
20
+ function isAppleTvModel(model) {
21
+ if (!model)
22
+ return false;
23
+ if (model.startsWith('J'))
24
+ return true;
25
+ return APPLE_TV_MODELS.has(model);
26
+ }
27
+ async function scan(timeout = 5000, onlyAppleTV = true) {
28
+ return new Promise((resolve) => {
29
+ const browser = (0, multicast_dns_1.default)();
30
+ const companionServices = new Map();
31
+ const airplayServices = new Map();
32
+ const deviceInfoModels = new Map(); // device name → model from _device-info
33
+ const addressMap = new Map();
34
+ browser.on('response', (response) => {
35
+ // Collect A/AAAA records for hostname→IP resolution
36
+ for (const answer of [...(response.answers || []), ...(response.additionals || [])]) {
37
+ if (answer.type === 'A') {
38
+ addressMap.set(answer.name, answer.data);
39
+ }
40
+ }
41
+ // Process all records (answers + additionals)
42
+ const allRecords = [...(response.answers || []), ...(response.additionals || [])];
43
+ for (const answer of allRecords) {
44
+ if (answer.type === 'SRV') {
45
+ const name = answer.name;
46
+ const isCompanion = name.endsWith('._companion-link._tcp.local');
47
+ const isAirplay = name.endsWith('._airplay._tcp.local');
48
+ if (isCompanion || isAirplay) {
49
+ const deviceName = name.split('.')[0];
50
+ const target = answer.data?.target;
51
+ const port = answer.data?.port;
52
+ const ip = addressMap.get(target) || '';
53
+ const svc = {
54
+ name: deviceName,
55
+ address: ip,
56
+ port,
57
+ properties: {},
58
+ };
59
+ if (isCompanion) {
60
+ companionServices.set(deviceName, svc);
61
+ }
62
+ else {
63
+ airplayServices.set(deviceName, svc);
64
+ }
65
+ }
66
+ }
67
+ if (answer.type === 'TXT') {
68
+ const name = answer.name;
69
+ const isCompanion = name.endsWith('._companion-link._tcp.local');
70
+ const isAirplay = name.endsWith('._airplay._tcp.local');
71
+ const isDeviceInfo = name.endsWith('._device-info._tcp.local');
72
+ const deviceName = name.split('.')[0];
73
+ const props = {};
74
+ if (Array.isArray(answer.data)) {
75
+ for (const entry of answer.data) {
76
+ const str = entry instanceof Buffer ? entry.toString('utf-8') : String(entry);
77
+ const eqIdx = str.indexOf('=');
78
+ if (eqIdx >= 0) {
79
+ props[str.substring(0, eqIdx)] = str.substring(eqIdx + 1);
80
+ }
81
+ }
82
+ }
83
+ if (isCompanion) {
84
+ const existing = companionServices.get(deviceName);
85
+ if (existing)
86
+ existing.properties = { ...existing.properties, ...props };
87
+ }
88
+ else if (isAirplay) {
89
+ const existing = airplayServices.get(deviceName);
90
+ if (existing)
91
+ existing.properties = { ...existing.properties, ...props };
92
+ }
93
+ else if (isDeviceInfo && props['model']) {
94
+ // _device-info._tcp.local contains the actual device model
95
+ deviceInfoModels.set(deviceName, props['model']);
96
+ }
97
+ }
98
+ }
99
+ // Also resolve addresses found in SRV targets
100
+ for (const svc of [...companionServices.values(), ...airplayServices.values()]) {
101
+ if (!svc.address) {
102
+ for (const answer of allRecords) {
103
+ if (answer.type === 'A') {
104
+ addressMap.set(answer.name, answer.data);
105
+ }
106
+ }
107
+ }
108
+ }
109
+ });
110
+ // Send queries for companion, airplay, and device-info services
111
+ const queryServices = () => {
112
+ browser.query([
113
+ { name: '_companion-link._tcp.local', type: 'PTR' },
114
+ { name: '_airplay._tcp.local', type: 'PTR' },
115
+ { name: '_device-info._tcp.local', type: 'PTR' },
116
+ ]);
117
+ };
118
+ // Send initial query
119
+ queryServices();
120
+ // Send a second query midway for better discovery
121
+ setTimeout(queryServices, timeout / 2);
122
+ setTimeout(() => {
123
+ browser.destroy();
124
+ // Merge companion and airplay services by device name
125
+ const devices = [];
126
+ const allNames = new Set([...companionServices.keys(), ...airplayServices.keys()]);
127
+ for (const name of allNames) {
128
+ const companion = companionServices.get(name);
129
+ const airplay = airplayServices.get(name);
130
+ // Need at least companion service for remote control
131
+ if (!companion)
132
+ continue;
133
+ // Resolve address from either service or address map
134
+ let address = companion.address || airplay?.address || '';
135
+ if (!address) {
136
+ // Try to find address from addressMap
137
+ for (const [hostname, ip] of addressMap) {
138
+ if (hostname.includes(name.replace(/ /g, '-'))) {
139
+ address = ip;
140
+ break;
141
+ }
142
+ }
143
+ }
144
+ if (!address)
145
+ continue;
146
+ const allProps = { ...companion.properties, ...airplay?.properties };
147
+ // Model comes from _device-info._tcp.local service, not companion/airplay
148
+ const model = deviceInfoModels.get(name) || allProps['model'] || allProps['rpmd'] || '';
149
+ if (onlyAppleTV && !isAppleTvModel(model))
150
+ continue;
151
+ devices.push({
152
+ name,
153
+ address,
154
+ port: companion.port,
155
+ airplayPort: airplay?.port || 7000,
156
+ identifier: allProps['deviceid'] || allProps['MACAddress'] || name,
157
+ model,
158
+ properties: allProps,
159
+ });
160
+ }
161
+ resolve(devices);
162
+ }, timeout);
163
+ });
164
+ }
165
+ //# sourceMappingURL=mdns.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mdns.js","sourceRoot":"","sources":["../src/mdns.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * OPACK serialization format - Apple's binary encoding (similar to MessagePack).
3
+ * Direct port of pyatv/support/opack.py.
4
+ */
5
+ /**
6
+ * Wrapper to force a number to be encoded as float64.
7
+ * In JavaScript, 1000.0 === 1000, so we can't distinguish floats from integers.
8
+ * Use opackFloat(1000) to ensure encoding as float64.
9
+ */
10
+ export declare class OpackFloat {
11
+ readonly value: number;
12
+ constructor(value: number);
13
+ }
14
+ export declare function opackFloat(value: number): OpackFloat;
15
+ export declare function pack(data: unknown): Buffer;
16
+ export interface UnpackResult {
17
+ value: unknown;
18
+ remaining: Buffer;
19
+ }
20
+ export declare function unpack(data: Buffer): UnpackResult;
21
+ //# sourceMappingURL=opack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opack.d.ts","sourceRoot":"","sources":["../src/opack.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;GAIG;AACH,qBAAa,UAAU;aACO,KAAK,EAAE,MAAM;gBAAb,KAAK,EAAE,MAAM;CAC1C;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAEpD;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAE1C;AA0JD,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAGjD"}