@bharper/atv-js 0.2.4 → 0.3.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.
package/dist/index.d.ts CHANGED
@@ -45,9 +45,24 @@ export interface AppleTVConnection {
45
45
  protocol: CompanionProtocol;
46
46
  device: AppleTVDevice;
47
47
  credentials: Credentials;
48
+ /** Credentials + endpoint used for this connection attempt/result. */
49
+ usedCredentials: ConnectionCredentialsSnapshot;
50
+ /** True when usedCredentials exactly match the values passed to connect(...). */
51
+ usedCredentialsMatchProvided: boolean;
48
52
  /** @internal */
49
53
  _keyboardFocusState: KeyboardFocusState;
50
54
  }
55
+ export interface ConnectionCredentialsSnapshot {
56
+ airplay: string;
57
+ companion: string;
58
+ device: {
59
+ name: string;
60
+ address: string;
61
+ port: number;
62
+ airplayPort: number;
63
+ identifier: string;
64
+ };
65
+ }
51
66
  /**
52
67
  * Connect to an Apple TV using stored credentials.
53
68
  * Performs pair-verify and sets up encrypted Companion channel.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC5G,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAEvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,2BAA2B,EAAE,MAAM,kBAAkB,CAAC;AAM/D,OAAO,EAAE,cAAc,EAAE,WAAW,EAA0C,MAAM,uBAAuB,CAAC;AAC5G,OAAO,EACL,qBAAqB,EAGtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAgB,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACrF,OAAO,EAKL,kBAAkB,EACnB,MAAM,sBAAsB,CAAC;AAM9B,MAAM,WAAW,cAAc;IAC7B,gBAAgB;IAChB,KAAK,EAAE,SAAS,GAAG,WAAW,CAAC;IAC/B,gBAAgB;IAChB,QAAQ,CAAC,EAAE,qBAAqB,CAAC;IACjC,gBAAgB;IAChB,kBAAkB,CAAC,EAAE,iBAAiB,CAAC;IACvC,gBAAgB;IAChB,mBAAmB,CAAC,EAAE,2BAA2B,CAAC;CACnD;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC,CAGxF;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,cAAc,EACvB,GAAG,EAAE,MAAM,EACX,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,cAAc,CAAC,CAKzB;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC,CAe1F;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,cAAc,EACvB,GAAG,EAAE,MAAM,EACX,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,cAAc,CAAC,CAYzB;AAID,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,MAAM,EAAE,aAAa,CAAC;IACtB,WAAW,EAAE,WAAW,CAAC;IACzB,gBAAgB;IAChB,mBAAmB,EAAE,kBAAkB,CAAC;CACzC;AAED;;;GAGG;AACH,wBAAsB,OAAO,CAC3B,MAAM,EAAE,aAAa,EACrB,WAAW,EAAE,WAAW,GACvB,OAAO,CAAC,iBAAiB,CAAC,CA2D5B;AAID;;GAEG;AACH,wBAAsB,OAAO,CAAC,IAAI,EAAE,iBAAiB,EAAE,GAAG,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE7F;AAED,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC;AAIlC;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC,CAErF;AAED;;GAEG;AACH,wBAAsB,OAAO,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAE7E;AAED;;GAEG;AACH,wBAAsB,OAAO,CAAC,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAElF;AAID;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAEhG;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAExD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAE5D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -28,6 +28,7 @@ Object.defineProperty(exports, "HidCommand", { enumerable: true, get: function (
28
28
  Object.defineProperty(exports, "MediaControlCommand", { enumerable: true, get: function () { return remote_1.MediaControlCommand; } });
29
29
  var keyboard_1 = require("./companion/keyboard");
30
30
  Object.defineProperty(exports, "KeyboardFocusState", { enumerable: true, get: function () { return keyboard_1.KeyboardFocusState; } });
31
+ const mdns_2 = require("./mdns");
31
32
  const connection_1 = require("./companion/connection");
32
33
  const protocol_1 = require("./companion/protocol");
33
34
  const auth_1 = require("./companion/auth");
@@ -88,16 +89,142 @@ async function finishCompanionPairing(session, pin, displayName) {
88
89
  }
89
90
  return creds;
90
91
  }
92
+ function errorMessage(error) {
93
+ if (error instanceof Error)
94
+ return error.message;
95
+ return String(error);
96
+ }
97
+ const ID_PROPERTY_KEYS = new Set(['rpmrtid', 'deviceid', 'macaddress']);
98
+ function normalizeIdentifier(value) {
99
+ return value.trim().toLowerCase();
100
+ }
101
+ function getIdentifiers(device) {
102
+ const identifiers = new Set();
103
+ if (device.identifier) {
104
+ identifiers.add(normalizeIdentifier(device.identifier));
105
+ }
106
+ for (const [key, value] of Object.entries(device.properties || {})) {
107
+ if (!value || !ID_PROPERTY_KEYS.has(key.toLowerCase()))
108
+ continue;
109
+ identifiers.add(normalizeIdentifier(value));
110
+ }
111
+ return identifiers;
112
+ }
113
+ function sharesIdentifier(target, candidate) {
114
+ const targetIds = getIdentifiers(target);
115
+ if (targetIds.size === 0)
116
+ return false;
117
+ for (const identifier of getIdentifiers(candidate)) {
118
+ if (targetIds.has(identifier))
119
+ return true;
120
+ }
121
+ return false;
122
+ }
123
+ function deviceMatchScore(target, candidate) {
124
+ if (sharesIdentifier(target, candidate))
125
+ return 100;
126
+ if (candidate.address === target.address)
127
+ return 10;
128
+ if (candidate.name === target.name)
129
+ return 1;
130
+ return 0;
131
+ }
132
+ function mergeDiscoveredDevice(target, discovered) {
133
+ return {
134
+ ...target,
135
+ ...discovered,
136
+ properties: { ...target.properties, ...discovered.properties },
137
+ };
138
+ }
139
+ function hasCompanionEndpointChanged(current, discovered) {
140
+ return current.address !== discovered.address || current.port !== discovered.port;
141
+ }
142
+ function toCredentialSnapshot(device, credentials) {
143
+ return {
144
+ airplay: credentials.airplay,
145
+ companion: credentials.companion,
146
+ device: {
147
+ name: device.name,
148
+ address: device.address,
149
+ port: device.port,
150
+ airplayPort: device.airplayPort,
151
+ identifier: device.identifier,
152
+ },
153
+ };
154
+ }
155
+ function snapshotsEqual(left, right) {
156
+ return left.airplay === right.airplay
157
+ && left.companion === right.companion
158
+ && left.device.name === right.device.name
159
+ && left.device.address === right.device.address
160
+ && left.device.port === right.device.port
161
+ && left.device.airplayPort === right.device.airplayPort
162
+ && left.device.identifier === right.device.identifier;
163
+ }
164
+ async function connectCompanion(device, companionCredentials) {
165
+ const connection = new connection_1.CompanionConnection(device.address, device.port);
166
+ const protocol = new protocol_1.CompanionProtocol(connection, companionCredentials);
167
+ connection.setListener(protocol);
168
+ await protocol.start();
169
+ return protocol;
170
+ }
171
+ async function discoverLatestDevice(device) {
172
+ const discovered = await (0, mdns_2.scan)(3000, false);
173
+ let bestMatch = null;
174
+ let bestScore = 0;
175
+ for (const candidate of discovered) {
176
+ const score = deviceMatchScore(device, candidate);
177
+ if (score === 0)
178
+ continue;
179
+ if (!bestMatch || score > bestScore) {
180
+ bestMatch = candidate;
181
+ bestScore = score;
182
+ continue;
183
+ }
184
+ if (score === bestScore) {
185
+ const candidatePortMatches = candidate.port === device.port;
186
+ const currentPortMatches = bestMatch.port === device.port;
187
+ if (candidatePortMatches && !currentPortMatches) {
188
+ bestMatch = candidate;
189
+ }
190
+ }
191
+ }
192
+ return bestMatch;
193
+ }
91
194
  /**
92
195
  * Connect to an Apple TV using stored credentials.
93
196
  * Performs pair-verify and sets up encrypted Companion channel.
94
197
  */
95
198
  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();
199
+ let activeDevice = device;
200
+ const providedCredentials = toCredentialSnapshot(device, credentials);
201
+ let protocol;
202
+ try {
203
+ protocol = await connectCompanion(activeDevice, credentials.companion);
204
+ }
205
+ catch (initialError) {
206
+ let discovered = null;
207
+ try {
208
+ discovered = await discoverLatestDevice(activeDevice);
209
+ }
210
+ catch {
211
+ discovered = null;
212
+ }
213
+ if (!discovered) {
214
+ throw initialError;
215
+ }
216
+ const mergedDevice = mergeDiscoveredDevice(activeDevice, discovered);
217
+ if (!hasCompanionEndpointChanged(activeDevice, mergedDevice)) {
218
+ throw initialError;
219
+ }
220
+ activeDevice = mergedDevice;
221
+ try {
222
+ protocol = await connectCompanion(activeDevice, credentials.companion);
223
+ }
224
+ catch (retryError) {
225
+ throw new Error(`Companion connection failed on saved endpoint ${device.address}:${device.port} and discovered endpoint ${activeDevice.address}:${activeDevice.port}: ${errorMessage(retryError)}`, { cause: initialError instanceof Error ? initialError : undefined });
226
+ }
227
+ }
101
228
  // Post-connection initialization (order matters!)
102
229
  // 1. Send system info
103
230
  // Client ID is stored hex-encoded in credentials, decode to get the actual UUID bytes
@@ -133,10 +260,13 @@ async function connect(device, credentials) {
133
260
  protocol.subscribeEvent('_iMC');
134
261
  const conn = {
135
262
  protocol,
136
- device,
263
+ device: activeDevice,
137
264
  credentials,
265
+ usedCredentials: toCredentialSnapshot(activeDevice, credentials),
266
+ usedCredentialsMatchProvided: false,
138
267
  _keyboardFocusState: keyboard_2.KeyboardFocusState.Unknown,
139
268
  };
269
+ conn.usedCredentialsMatchProvided = snapshotsEqual(conn.usedCredentials, providedCredentials);
140
270
  // Watch keyboard focus state
141
271
  (0, keyboard_2.watchKeyboardFocus)(protocol, (state) => {
142
272
  conn._keyboardFocusState = state;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -1 +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"}
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;AAgCD,wBAAsB,IAAI,CAAC,OAAO,SAAO,EAAE,WAAW,UAAO,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAiKvF"}
package/dist/mdns.js CHANGED
@@ -24,6 +24,14 @@ function isAppleTvModel(model) {
24
24
  return true;
25
25
  return APPLE_TV_MODELS.has(model);
26
26
  }
27
+ function getPropertyIgnoreCase(properties, key) {
28
+ const expected = key.toLowerCase();
29
+ for (const [property, value] of Object.entries(properties)) {
30
+ if (property.toLowerCase() === expected)
31
+ return value;
32
+ }
33
+ return undefined;
34
+ }
27
35
  async function scan(timeout = 5000, onlyAppleTV = true) {
28
36
  return new Promise((resolve) => {
29
37
  const browser = (0, multicast_dns_1.default)();
@@ -145,15 +153,22 @@ async function scan(timeout = 5000, onlyAppleTV = true) {
145
153
  continue;
146
154
  const allProps = { ...companion.properties, ...airplay?.properties };
147
155
  // Model comes from _device-info._tcp.local service, not companion/airplay
148
- const model = deviceInfoModels.get(name) || allProps['model'] || allProps['rpmd'] || '';
156
+ const model = deviceInfoModels.get(name)
157
+ || getPropertyIgnoreCase(allProps, 'model')
158
+ || getPropertyIgnoreCase(allProps, 'rpmd')
159
+ || '';
149
160
  if (onlyAppleTV && !isAppleTvModel(model))
150
161
  continue;
162
+ const identifier = getPropertyIgnoreCase(allProps, 'rpmrtid')
163
+ || getPropertyIgnoreCase(allProps, 'deviceid')
164
+ || getPropertyIgnoreCase(allProps, 'macaddress')
165
+ || name;
151
166
  devices.push({
152
167
  name,
153
168
  address,
154
169
  port: companion.port,
155
170
  airplayPort: airplay?.port || 7000,
156
- identifier: allProps['deviceid'] || allProps['MACAddress'] || name,
171
+ identifier,
157
172
  model,
158
173
  properties: allProps,
159
174
  });
package/dist/mdns.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"mdns.js","sourceRoot":"","sources":["../src/mdns.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mdns.js","sourceRoot":"","sources":["../src/mdns.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ const fs = require('node:fs');
2
+ const path = require('node:path');
3
+
4
+ // prints the contents of device.json in the format atv-desktop-remote uses, useful for debugging and testing
5
+
6
+ const devicePath = path.join(__dirname, 'device.json');
7
+ const raw = fs.readFileSync(devicePath, 'utf8');
8
+ const parsed = JSON.parse(raw);
9
+
10
+ const output = {
11
+ airplay: parsed.credentials.airplay,
12
+ companion: parsed.credentials.companion,
13
+ device: {
14
+ name: parsed.name,
15
+ address: parsed.address,
16
+ port: parsed.port,
17
+ airplayPort: parsed.airplayPort,
18
+ identifier: parsed.identifier,
19
+ },
20
+ };
21
+
22
+ console.log(JSON.stringify(output, null, 2));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bharper/atv-js",
3
- "version": "0.2.4",
3
+ "version": "0.3.0",
4
4
  "description": "Apple TV control library - mDNS discovery, AirPlay/Companion pairing, remote control, keyboard input",
5
5
  "repository": {
6
6
  "type": "git",
@@ -15,7 +15,6 @@
15
15
  "remote": "ts-node examples/remote.ts"
16
16
  },
17
17
  "dependencies": {
18
- "@bharper/atv-js": "^0.2.3",
19
18
  "@noble/ciphers": "^2.1.1",
20
19
  "bplist-creator": "^0.1.0",
21
20
  "bplist-parser": "^0.3.2",
@@ -24,7 +23,7 @@
24
23
  },
25
24
  "devDependencies": {
26
25
  "@types/multicast-dns": "^7.2.4",
27
- "@types/node": "^20.0.0",
26
+ "@types/node": "^20.19.33",
28
27
  "ts-node": "^10.9.0",
29
28
  "typescript": "^5.3.0"
30
29
  },
package/src/index.ts CHANGED
@@ -8,7 +8,7 @@ export { HapCredentials, Credentials, parseCredentials, serializeCredentials } f
8
8
  export { RemoteKey, HidCommand, MediaControlCommand } from './companion/remote';
9
9
  export { KeyboardFocusState } from './companion/keyboard';
10
10
 
11
- import { AppleTVDevice } from './mdns';
11
+ import { AppleTVDevice, scan as scanDevices } from './mdns';
12
12
  import { CompanionConnection } from './companion/connection';
13
13
  import { CompanionProtocol } from './companion/protocol';
14
14
  import { CompanionPairSetupProcedure } from './companion/auth';
@@ -118,10 +118,150 @@ export interface AppleTVConnection {
118
118
  protocol: CompanionProtocol;
119
119
  device: AppleTVDevice;
120
120
  credentials: Credentials;
121
+ /** Credentials + endpoint used for this connection attempt/result. */
122
+ usedCredentials: ConnectionCredentialsSnapshot;
123
+ /** True when usedCredentials exactly match the values passed to connect(...). */
124
+ usedCredentialsMatchProvided: boolean;
121
125
  /** @internal */
122
126
  _keyboardFocusState: KeyboardFocusState;
123
127
  }
124
128
 
129
+ export interface ConnectionCredentialsSnapshot {
130
+ airplay: string;
131
+ companion: string;
132
+ device: {
133
+ name: string;
134
+ address: string;
135
+ port: number;
136
+ airplayPort: number;
137
+ identifier: string;
138
+ };
139
+ }
140
+
141
+ function errorMessage(error: unknown): string {
142
+ if (error instanceof Error) return error.message;
143
+ return String(error);
144
+ }
145
+
146
+ const ID_PROPERTY_KEYS = new Set(['rpmrtid', 'deviceid', 'macaddress']);
147
+
148
+ function normalizeIdentifier(value: string): string {
149
+ return value.trim().toLowerCase();
150
+ }
151
+
152
+ function getIdentifiers(device: AppleTVDevice): Set<string> {
153
+ const identifiers = new Set<string>();
154
+
155
+ if (device.identifier) {
156
+ identifiers.add(normalizeIdentifier(device.identifier));
157
+ }
158
+
159
+ for (const [key, value] of Object.entries(device.properties || {})) {
160
+ if (!value || !ID_PROPERTY_KEYS.has(key.toLowerCase())) continue;
161
+ identifiers.add(normalizeIdentifier(value));
162
+ }
163
+
164
+ return identifiers;
165
+ }
166
+
167
+ function sharesIdentifier(target: AppleTVDevice, candidate: AppleTVDevice): boolean {
168
+ const targetIds = getIdentifiers(target);
169
+ if (targetIds.size === 0) return false;
170
+
171
+ for (const identifier of getIdentifiers(candidate)) {
172
+ if (targetIds.has(identifier)) return true;
173
+ }
174
+
175
+ return false;
176
+ }
177
+
178
+ function deviceMatchScore(target: AppleTVDevice, candidate: AppleTVDevice): number {
179
+ if (sharesIdentifier(target, candidate)) return 100;
180
+ if (candidate.address === target.address) return 10;
181
+ if (candidate.name === target.name) return 1;
182
+ return 0;
183
+ }
184
+
185
+ function mergeDiscoveredDevice(target: AppleTVDevice, discovered: AppleTVDevice): AppleTVDevice {
186
+ return {
187
+ ...target,
188
+ ...discovered,
189
+ properties: { ...target.properties, ...discovered.properties },
190
+ };
191
+ }
192
+
193
+ function hasCompanionEndpointChanged(current: AppleTVDevice, discovered: AppleTVDevice): boolean {
194
+ return current.address !== discovered.address || current.port !== discovered.port;
195
+ }
196
+
197
+ function toCredentialSnapshot(
198
+ device: AppleTVDevice,
199
+ credentials: Credentials,
200
+ ): ConnectionCredentialsSnapshot {
201
+ return {
202
+ airplay: credentials.airplay,
203
+ companion: credentials.companion,
204
+ device: {
205
+ name: device.name,
206
+ address: device.address,
207
+ port: device.port,
208
+ airplayPort: device.airplayPort,
209
+ identifier: device.identifier,
210
+ },
211
+ };
212
+ }
213
+
214
+ function snapshotsEqual(
215
+ left: ConnectionCredentialsSnapshot,
216
+ right: ConnectionCredentialsSnapshot,
217
+ ): boolean {
218
+ return left.airplay === right.airplay
219
+ && left.companion === right.companion
220
+ && left.device.name === right.device.name
221
+ && left.device.address === right.device.address
222
+ && left.device.port === right.device.port
223
+ && left.device.airplayPort === right.device.airplayPort
224
+ && left.device.identifier === right.device.identifier;
225
+ }
226
+
227
+ async function connectCompanion(
228
+ device: AppleTVDevice,
229
+ companionCredentials: string,
230
+ ): Promise<CompanionProtocol> {
231
+ const connection = new CompanionConnection(device.address, device.port);
232
+ const protocol = new CompanionProtocol(connection, companionCredentials);
233
+ connection.setListener(protocol);
234
+ await protocol.start();
235
+ return protocol;
236
+ }
237
+
238
+ async function discoverLatestDevice(device: AppleTVDevice): Promise<AppleTVDevice | null> {
239
+ const discovered = await scanDevices(3000, false);
240
+ let bestMatch: AppleTVDevice | null = null;
241
+ let bestScore = 0;
242
+
243
+ for (const candidate of discovered) {
244
+ const score = deviceMatchScore(device, candidate);
245
+ if (score === 0) continue;
246
+
247
+ if (!bestMatch || score > bestScore) {
248
+ bestMatch = candidate;
249
+ bestScore = score;
250
+ continue;
251
+ }
252
+
253
+ if (score === bestScore) {
254
+ const candidatePortMatches = candidate.port === device.port;
255
+ const currentPortMatches = bestMatch.port === device.port;
256
+ if (candidatePortMatches && !currentPortMatches) {
257
+ bestMatch = candidate;
258
+ }
259
+ }
260
+ }
261
+
262
+ return bestMatch;
263
+ }
264
+
125
265
  /**
126
266
  * Connect to an Apple TV using stored credentials.
127
267
  * Performs pair-verify and sets up encrypted Companion channel.
@@ -130,12 +270,40 @@ export async function connect(
130
270
  device: AppleTVDevice,
131
271
  credentials: Credentials,
132
272
  ): Promise<AppleTVConnection> {
133
- const connection = new CompanionConnection(device.address, device.port);
134
- const protocol = new CompanionProtocol(connection, credentials.companion);
135
- connection.setListener(protocol);
136
-
137
- // Connect, verify credentials, enable encryption
138
- await protocol.start();
273
+ let activeDevice = device;
274
+ const providedCredentials = toCredentialSnapshot(device, credentials);
275
+ let protocol: CompanionProtocol;
276
+
277
+ try {
278
+ protocol = await connectCompanion(activeDevice, credentials.companion);
279
+ } catch (initialError) {
280
+ let discovered: AppleTVDevice | null = null;
281
+ try {
282
+ discovered = await discoverLatestDevice(activeDevice);
283
+ } catch {
284
+ discovered = null;
285
+ }
286
+
287
+ if (!discovered) {
288
+ throw initialError;
289
+ }
290
+
291
+ const mergedDevice = mergeDiscoveredDevice(activeDevice, discovered);
292
+ if (!hasCompanionEndpointChanged(activeDevice, mergedDevice)) {
293
+ throw initialError;
294
+ }
295
+
296
+ activeDevice = mergedDevice;
297
+
298
+ try {
299
+ protocol = await connectCompanion(activeDevice, credentials.companion);
300
+ } catch (retryError) {
301
+ throw new Error(
302
+ `Companion connection failed on saved endpoint ${device.address}:${device.port} and discovered endpoint ${activeDevice.address}:${activeDevice.port}: ${errorMessage(retryError)}`,
303
+ { cause: initialError instanceof Error ? initialError : undefined },
304
+ );
305
+ }
306
+ }
139
307
 
140
308
  // Post-connection initialization (order matters!)
141
309
  // 1. Send system info
@@ -177,10 +345,13 @@ export async function connect(
177
345
 
178
346
  const conn: AppleTVConnection = {
179
347
  protocol,
180
- device,
348
+ device: activeDevice,
181
349
  credentials,
350
+ usedCredentials: toCredentialSnapshot(activeDevice, credentials),
351
+ usedCredentialsMatchProvided: false,
182
352
  _keyboardFocusState: KeyboardFocusState.Unknown,
183
353
  };
354
+ conn.usedCredentialsMatchProvided = snapshotsEqual(conn.usedCredentials, providedCredentials);
184
355
 
185
356
  // Watch keyboard focus state
186
357
  _watchKeyboardFocus(protocol, (state) => {
package/src/mdns.ts CHANGED
@@ -42,6 +42,14 @@ function isAppleTvModel(model: string): boolean {
42
42
  return APPLE_TV_MODELS.has(model);
43
43
  }
44
44
 
45
+ function getPropertyIgnoreCase(properties: Record<string, string>, key: string): string | undefined {
46
+ const expected = key.toLowerCase();
47
+ for (const [property, value] of Object.entries(properties)) {
48
+ if (property.toLowerCase() === expected) return value;
49
+ }
50
+ return undefined;
51
+ }
52
+
45
53
  export async function scan(timeout = 5000, onlyAppleTV = true): Promise<AppleTVDevice[]> {
46
54
  return new Promise((resolve) => {
47
55
  const browser = mdns();
@@ -177,16 +185,24 @@ export async function scan(timeout = 5000, onlyAppleTV = true): Promise<AppleTVD
177
185
  const allProps = { ...companion.properties, ...airplay?.properties };
178
186
 
179
187
  // Model comes from _device-info._tcp.local service, not companion/airplay
180
- const model = deviceInfoModels.get(name) || allProps['model'] || allProps['rpmd'] || '';
188
+ const model = deviceInfoModels.get(name)
189
+ || getPropertyIgnoreCase(allProps, 'model')
190
+ || getPropertyIgnoreCase(allProps, 'rpmd')
191
+ || '';
181
192
 
182
193
  if (onlyAppleTV && !isAppleTvModel(model)) continue;
183
194
 
195
+ const identifier = getPropertyIgnoreCase(allProps, 'rpmrtid')
196
+ || getPropertyIgnoreCase(allProps, 'deviceid')
197
+ || getPropertyIgnoreCase(allProps, 'macaddress')
198
+ || name;
199
+
184
200
  devices.push({
185
201
  name,
186
202
  address,
187
203
  port: companion.port,
188
204
  airplayPort: airplay?.port || 7000,
189
- identifier: allProps['deviceid'] || allProps['MACAddress'] || name,
205
+ identifier,
190
206
  model,
191
207
  properties: allProps,
192
208
  });