@basmilius/apple-encoding 0.9.19 → 0.10.1
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.mts +300 -32
- package/dist/index.mjs +363 -12
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
declare namespace daap_d_exports {
|
|
2
|
-
export { ContentCode, ContentCodeKey, DecodedTag, PlaybackStatus, TagType, TrackMetadata, decode$
|
|
2
|
+
export { ContentCode, ContentCodeKey, DecodedTag, PlaybackStatus, TagType, TrackMetadata, decode$4 as decode, decodeTag, decodeToObject, decodeTrackMetadata, encodeContainer, encodePlaybackStatus, encodeTag, encodeTagWithSize, encodeTrackMetadata };
|
|
3
3
|
}
|
|
4
|
+
/**
|
|
5
|
+
* Maps four-character DAAP tag codes to their human-readable DMAP/DAAP content code names.
|
|
6
|
+
* Used to identify the semantic meaning of tags in DAAP protocol messages.
|
|
7
|
+
*/
|
|
4
8
|
declare const ContentCode: {
|
|
5
9
|
readonly mlit: "dmap.listingitem";
|
|
6
10
|
readonly mlcl: "dmap.listing";
|
|
@@ -30,6 +34,15 @@ declare const ContentCode: {
|
|
|
30
34
|
readonly cavs: "daap.songvisiblestate";
|
|
31
35
|
readonly aePP: "com.apple.itunes.photo-properties";
|
|
32
36
|
};
|
|
37
|
+
/**
|
|
38
|
+
* Maps four-character DAAP tag codes to their data type identifiers.
|
|
39
|
+
*
|
|
40
|
+
* Type values: 1=byte, 2=unsigned byte, 3=short, 4=unsigned short,
|
|
41
|
+
* 5=int, 6=unsigned int, 7=long, 8=unsigned long,
|
|
42
|
+
* 9=string, 10=date, 11=version, 12=container.
|
|
43
|
+
*
|
|
44
|
+
* Used by the decoder to determine how to interpret the raw bytes of each tag.
|
|
45
|
+
*/
|
|
33
46
|
declare const TagType: {
|
|
34
47
|
readonly mlit: 12;
|
|
35
48
|
readonly mlcl: 12;
|
|
@@ -59,87 +72,288 @@ declare const TagType: {
|
|
|
59
72
|
readonly cavs: 1;
|
|
60
73
|
readonly aePP: 9;
|
|
61
74
|
};
|
|
75
|
+
/**
|
|
76
|
+
* Encodes a single DAAP tag with an automatically sized value.
|
|
77
|
+
* Numbers are encoded in the smallest big-endian representation that fits.
|
|
78
|
+
*
|
|
79
|
+
* @param tag - Four-character ASCII tag code (e.g. 'minm', 'asar').
|
|
80
|
+
* @param value - The value to encode: string (UTF-8), number (auto-sized BE), bigint (8-byte BE), or raw Buffer.
|
|
81
|
+
* @returns A buffer containing the tag, length, and value.
|
|
82
|
+
* @throws Error if the tag is not exactly 4 characters.
|
|
83
|
+
*/
|
|
62
84
|
declare function encodeTag(tag: string, value: Buffer | string | number | bigint): Buffer;
|
|
85
|
+
/**
|
|
86
|
+
* Encodes a DAAP container tag that wraps other encoded tags.
|
|
87
|
+
*
|
|
88
|
+
* @param tag - Four-character ASCII container tag code (e.g. 'mlit', 'mlcl').
|
|
89
|
+
* @param content - Pre-encoded buffer containing the container's child tags.
|
|
90
|
+
* @returns A buffer containing the container tag, length, and nested content.
|
|
91
|
+
* @throws Error if the tag is not exactly 4 characters.
|
|
92
|
+
*/
|
|
63
93
|
declare function encodeContainer(tag: string, content: Buffer): Buffer;
|
|
94
|
+
/**
|
|
95
|
+
* Encodes playback status fields (playing, shuffle, repeat) into DAAP tags.
|
|
96
|
+
* Only includes tags for fields that are defined in the status object.
|
|
97
|
+
*
|
|
98
|
+
* @param status - The playback status to encode.
|
|
99
|
+
* @returns A buffer containing the encoded DAAP status tags.
|
|
100
|
+
*/
|
|
64
101
|
declare function encodePlaybackStatus(status: PlaybackStatus): Buffer;
|
|
102
|
+
/**
|
|
103
|
+
* Encodes a DAAP tag with an explicitly specified byte size for the numeric value.
|
|
104
|
+
* Useful when the protocol requires a specific size regardless of the value magnitude.
|
|
105
|
+
*
|
|
106
|
+
* @param tag - Four-character ASCII tag code.
|
|
107
|
+
* @param value - The numeric value to encode.
|
|
108
|
+
* @param byteSize - The exact number of bytes to use for the value (1, 2, 4, or 8).
|
|
109
|
+
* @returns A buffer containing the tag, length, and fixed-size value.
|
|
110
|
+
* @throws Error if the tag is not exactly 4 characters.
|
|
111
|
+
*/
|
|
65
112
|
declare function encodeTagWithSize(tag: string, value: number, byteSize: 1 | 2 | 4 | 8): Buffer;
|
|
113
|
+
/**
|
|
114
|
+
* Encodes track metadata into a DAAP listing item (`mlit`) container.
|
|
115
|
+
* Only includes tags for fields that are defined in the metadata object.
|
|
116
|
+
* Duration is converted from seconds to milliseconds for the `astm` tag.
|
|
117
|
+
*
|
|
118
|
+
* @param metadata - The track metadata to encode.
|
|
119
|
+
* @returns A buffer containing an `mlit` container with all defined metadata tags.
|
|
120
|
+
*/
|
|
66
121
|
declare function encodeTrackMetadata(metadata: TrackMetadata): Buffer;
|
|
67
|
-
|
|
122
|
+
/**
|
|
123
|
+
* Decodes all DAAP tags from a buffer sequentially.
|
|
124
|
+
* Stops when the buffer is exhausted or a tag cannot be fully decoded.
|
|
125
|
+
*
|
|
126
|
+
* @param buffer - The raw DAAP-encoded buffer.
|
|
127
|
+
* @returns An array of decoded tags with their raw value buffers.
|
|
128
|
+
*/
|
|
129
|
+
declare function decode$4(buffer: Buffer): DecodedTag[];
|
|
130
|
+
/**
|
|
131
|
+
* Decodes a single DAAP tag from the start of a buffer.
|
|
132
|
+
* Returns the decoded tag and the remaining unconsumed buffer.
|
|
133
|
+
*
|
|
134
|
+
* @param buffer - The buffer to decode from. Must contain at least 8 bytes (4 tag + 4 length).
|
|
135
|
+
* @returns A tuple of the decoded tag and remaining buffer, or null if the buffer is too short.
|
|
136
|
+
*/
|
|
68
137
|
declare function decodeTag(buffer: Buffer): [DecodedTag, Buffer] | null;
|
|
138
|
+
/**
|
|
139
|
+
* Decodes a DAAP buffer into a plain object, interpreting values based on {@link TagType}.
|
|
140
|
+
* Container tags (type 12) are recursively decoded. Unknown tags are kept as raw buffers.
|
|
141
|
+
*
|
|
142
|
+
* @param buffer - The raw DAAP-encoded buffer.
|
|
143
|
+
* @returns An object mapping tag codes to their decoded values.
|
|
144
|
+
*/
|
|
69
145
|
declare function decodeToObject(buffer: Buffer): Record<string, unknown>;
|
|
146
|
+
/**
|
|
147
|
+
* Decodes a DAAP buffer into a structured {@link TrackMetadata} object.
|
|
148
|
+
* Handles both bare tag lists and `mlit`-wrapped containers.
|
|
149
|
+
* Duration is converted from the DAAP millisecond `astm` value back to seconds.
|
|
150
|
+
*
|
|
151
|
+
* @param buffer - The raw DAAP-encoded buffer containing track metadata.
|
|
152
|
+
* @returns The decoded track metadata.
|
|
153
|
+
*/
|
|
70
154
|
declare function decodeTrackMetadata(buffer: Buffer): TrackMetadata;
|
|
155
|
+
/** Union type of all valid four-character DAAP content code keys. */
|
|
71
156
|
type ContentCodeKey = keyof typeof ContentCode;
|
|
157
|
+
/** Represents a single decoded DAAP tag with its raw value buffer. */
|
|
72
158
|
type DecodedTag = {
|
|
73
|
-
readonly tag: string;
|
|
74
|
-
readonly length: number;
|
|
159
|
+
/** The four-character ASCII tag code. */readonly tag: string; /** The byte length of the value. */
|
|
160
|
+
readonly length: number; /** The raw undecoded value bytes. */
|
|
75
161
|
readonly value: Buffer;
|
|
76
162
|
};
|
|
163
|
+
/** Represents the playback state of a DAAP media player. */
|
|
77
164
|
type PlaybackStatus = {
|
|
78
|
-
readonly playing?: boolean;
|
|
79
|
-
readonly shuffle?: boolean;
|
|
165
|
+
/** Whether the player is currently playing. */readonly playing?: boolean; /** Whether shuffle mode is enabled. */
|
|
166
|
+
readonly shuffle?: boolean; /** The repeat mode: off, repeat one track, or repeat all. */
|
|
80
167
|
readonly repeat?: "off" | "one" | "all";
|
|
81
168
|
};
|
|
169
|
+
/** Metadata for a single media track in the DAAP protocol. */
|
|
82
170
|
type TrackMetadata = {
|
|
83
|
-
readonly title?: string;
|
|
84
|
-
readonly artist?: string;
|
|
85
|
-
readonly albumArtist?: string;
|
|
86
|
-
readonly album?: string;
|
|
87
|
-
readonly composer?: string;
|
|
88
|
-
readonly genre?: string;
|
|
89
|
-
readonly duration?: number;
|
|
90
|
-
readonly trackNumber?: number;
|
|
91
|
-
readonly trackCount?: number;
|
|
92
|
-
readonly discNumber?: number;
|
|
93
|
-
readonly discCount?: number;
|
|
94
|
-
readonly year?: number;
|
|
95
|
-
readonly bitrate?: number;
|
|
96
|
-
readonly sampleRate?: number;
|
|
171
|
+
/** Track title (DAAP tag `minm`). */readonly title?: string; /** Track artist (DAAP tag `asar`). */
|
|
172
|
+
readonly artist?: string; /** Album artist (DAAP tag `asaa`). */
|
|
173
|
+
readonly albumArtist?: string; /** Album name (DAAP tag `asal`). */
|
|
174
|
+
readonly album?: string; /** Composer name (DAAP tag `ascp`). */
|
|
175
|
+
readonly composer?: string; /** Genre name (DAAP tag `asgn`). */
|
|
176
|
+
readonly genre?: string; /** Track duration in seconds. Converted to/from milliseconds during encoding/decoding. */
|
|
177
|
+
readonly duration?: number; /** Track number within the album (DAAP tag `astn`). */
|
|
178
|
+
readonly trackNumber?: number; /** Total number of tracks on the album (DAAP tag `astc`). */
|
|
179
|
+
readonly trackCount?: number; /** Disc number within the set (DAAP tag `asdn`). */
|
|
180
|
+
readonly discNumber?: number; /** Total number of discs in the set (DAAP tag `asdc`). */
|
|
181
|
+
readonly discCount?: number; /** Release year (DAAP tag `asyr`). */
|
|
182
|
+
readonly year?: number; /** Bitrate in kbps (DAAP tag `asbr`). */
|
|
183
|
+
readonly bitrate?: number; /** Sample rate in Hz (DAAP tag `assr`). */
|
|
184
|
+
readonly sampleRate?: number; /** File size in bytes (DAAP tag `assz`). */
|
|
97
185
|
readonly size?: number;
|
|
98
186
|
};
|
|
187
|
+
declare namespace nskeyedarchiver_d_exports {
|
|
188
|
+
export { decode$3 as decode, decodeAsArray };
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Decodes an NSKeyedArchiver binary plist into plain JavaScript objects.
|
|
192
|
+
* Resolves CF$UID references, decodes NS.objects/NS.keys into arrays/dicts,
|
|
193
|
+
* and strips $class metadata.
|
|
194
|
+
*
|
|
195
|
+
* @param archive - The parsed plist archive containing `$objects` and `$top` keys.
|
|
196
|
+
* @returns The resolved root object, or null if the archive is invalid.
|
|
197
|
+
*/
|
|
198
|
+
declare function decode$3(archive: any): unknown;
|
|
199
|
+
/**
|
|
200
|
+
* Decodes an NSKeyedArchiver plist and returns the root as an array.
|
|
201
|
+
* If the root is not an array, wraps it in one.
|
|
202
|
+
*
|
|
203
|
+
* @param archive - The parsed plist archive containing `$objects` and `$top` keys.
|
|
204
|
+
* @returns The resolved root as an array. Non-array roots are wrapped in a single-element array.
|
|
205
|
+
*/
|
|
206
|
+
declare function decodeAsArray(archive: any): unknown[];
|
|
99
207
|
declare namespace ntp_d_exports {
|
|
100
|
-
export { PacketFields, decode$2 as decode, encode$2 as encode, now,
|
|
208
|
+
export { PacketFields, decode$2 as decode, encode$2 as encode, now, parts };
|
|
101
209
|
}
|
|
210
|
+
/**
|
|
211
|
+
* Returns the current wall-clock time as a 64-bit NTP timestamp.
|
|
212
|
+
* The upper 32 bits are whole seconds since the NTP epoch (1900-01-01),
|
|
213
|
+
* and the lower 32 bits are the fractional second.
|
|
214
|
+
*
|
|
215
|
+
* Uses `Date.now()` (wall-clock) rather than a monotone clock because Apple
|
|
216
|
+
* devices expect NTP timestamps anchored to real time.
|
|
217
|
+
*
|
|
218
|
+
* @returns The current time as a 64-bit NTP timestamp.
|
|
219
|
+
*/
|
|
102
220
|
declare function now(): bigint;
|
|
103
|
-
|
|
221
|
+
/**
|
|
222
|
+
* Splits a 64-bit NTP timestamp into its seconds and fractional parts.
|
|
223
|
+
*
|
|
224
|
+
* @param ntp - A 64-bit NTP timestamp (upper 32 bits = seconds, lower 32 bits = fraction).
|
|
225
|
+
* @returns A tuple of [seconds, fraction] as 32-bit unsigned integers.
|
|
226
|
+
*/
|
|
104
227
|
declare function parts(ntp: bigint): [number, number];
|
|
228
|
+
/**
|
|
229
|
+
* Decodes an NTP timing packet from a buffer into its constituent fields.
|
|
230
|
+
* Expects at least 24 bytes; the send timestamp fields (bytes 24-31) default
|
|
231
|
+
* to 0 if the buffer is shorter than 32 bytes.
|
|
232
|
+
*
|
|
233
|
+
* @param buffer - The raw NTP packet buffer (minimum 24 bytes).
|
|
234
|
+
* @returns The decoded packet fields.
|
|
235
|
+
* @throws RangeError if the buffer is shorter than 24 bytes.
|
|
236
|
+
*/
|
|
105
237
|
declare function decode$2(buffer: Buffer): PacketFields;
|
|
238
|
+
/**
|
|
239
|
+
* Encodes NTP timing packet fields into a 32-byte buffer.
|
|
240
|
+
*
|
|
241
|
+
* @param fields - The packet fields to encode.
|
|
242
|
+
* @returns A 32-byte buffer containing the encoded NTP packet.
|
|
243
|
+
*/
|
|
106
244
|
declare function encode$2(fields: PacketFields): Buffer;
|
|
245
|
+
/** Fields of an NTP timing packet used for clock synchronization with Apple devices. */
|
|
107
246
|
type PacketFields = {
|
|
108
|
-
readonly proto: number;
|
|
109
|
-
readonly type: number;
|
|
110
|
-
readonly seqno: number;
|
|
111
|
-
readonly padding: number;
|
|
112
|
-
readonly reftime_sec: number;
|
|
113
|
-
readonly reftime_frac: number;
|
|
114
|
-
readonly recvtime_sec: number;
|
|
115
|
-
readonly recvtime_frac: number;
|
|
116
|
-
readonly sendtime_sec: number;
|
|
247
|
+
/** Protocol identifier byte. */readonly proto: number; /** Packet type (e.g. request or response). */
|
|
248
|
+
readonly type: number; /** Sequence number for correlating requests and responses. */
|
|
249
|
+
readonly seqno: number; /** Padding field (typically zero). */
|
|
250
|
+
readonly padding: number; /** Reference timestamp, seconds part. */
|
|
251
|
+
readonly reftime_sec: number; /** Reference timestamp, fractional part. */
|
|
252
|
+
readonly reftime_frac: number; /** Receive timestamp, seconds part. */
|
|
253
|
+
readonly recvtime_sec: number; /** Receive timestamp, fractional part. */
|
|
254
|
+
readonly recvtime_frac: number; /** Send timestamp, seconds part. */
|
|
255
|
+
readonly sendtime_sec: number; /** Send timestamp, fractional part. */
|
|
117
256
|
readonly sendtime_frac: number;
|
|
118
257
|
};
|
|
119
258
|
declare namespace opack_d_exports {
|
|
120
259
|
export { decode$1 as decode, encode$1 as encode, float, int, sizedInteger };
|
|
121
260
|
}
|
|
261
|
+
/**
|
|
262
|
+
* Wrapper that forces a number to be encoded as an OPack float (FLOAT64).
|
|
263
|
+
* Without this wrapper, JavaScript numbers that happen to be integers
|
|
264
|
+
* would be encoded as OPack integers instead.
|
|
265
|
+
*/
|
|
122
266
|
declare class Float {
|
|
123
267
|
#private;
|
|
268
|
+
/** The wrapped floating-point value. */
|
|
124
269
|
get value(): number;
|
|
270
|
+
/**
|
|
271
|
+
* @param value - The floating-point number to wrap.
|
|
272
|
+
*/
|
|
125
273
|
constructor(value: number);
|
|
126
274
|
}
|
|
275
|
+
/**
|
|
276
|
+
* Wrapper that forces a number to be encoded as an OPack integer.
|
|
277
|
+
* Useful when a value must be encoded as an integer even if it could
|
|
278
|
+
* be represented as an inline value.
|
|
279
|
+
*/
|
|
127
280
|
declare class Integer {
|
|
128
281
|
#private;
|
|
282
|
+
/** The wrapped integer value. */
|
|
129
283
|
get value(): number;
|
|
284
|
+
/**
|
|
285
|
+
* @param value - The integer number to wrap.
|
|
286
|
+
*/
|
|
130
287
|
constructor(value: number);
|
|
131
288
|
}
|
|
289
|
+
/**
|
|
290
|
+
* An integer with an explicit byte size. Produced during OPack decoding when
|
|
291
|
+
* the wire format specifies the exact byte width (1, 2, 4, or 8). During
|
|
292
|
+
* encoding, the specified size is preserved to maintain wire compatibility.
|
|
293
|
+
*/
|
|
132
294
|
declare class SizedInteger {
|
|
133
295
|
#private;
|
|
296
|
+
/** The byte width of this integer on the wire (1, 2, 4, or 8). */
|
|
134
297
|
get size(): number;
|
|
298
|
+
/** The numeric value. */
|
|
135
299
|
get value(): number;
|
|
300
|
+
/**
|
|
301
|
+
* @param value - The integer value.
|
|
302
|
+
* @param size - The byte width for wire encoding (1, 2, 4, or 8).
|
|
303
|
+
*/
|
|
136
304
|
constructor(value: number, size: number);
|
|
305
|
+
/**
|
|
306
|
+
* Returns the numeric value, enabling implicit numeric coercion.
|
|
307
|
+
*
|
|
308
|
+
* @returns The integer value.
|
|
309
|
+
*/
|
|
137
310
|
valueOf(): number;
|
|
138
311
|
}
|
|
312
|
+
/**
|
|
313
|
+
* Creates an OPack float wrapper, ensuring the value is encoded as FLOAT64
|
|
314
|
+
* on the wire regardless of whether it is a whole number.
|
|
315
|
+
*
|
|
316
|
+
* @param value - The floating-point number.
|
|
317
|
+
* @returns A Float wrapper for OPack encoding.
|
|
318
|
+
*/
|
|
139
319
|
declare function float(value: number): Float;
|
|
320
|
+
/**
|
|
321
|
+
* Creates an OPack integer wrapper, ensuring the value is encoded as an
|
|
322
|
+
* explicit integer type on the wire.
|
|
323
|
+
*
|
|
324
|
+
* @param value - The integer number.
|
|
325
|
+
* @returns An Integer wrapper for OPack encoding.
|
|
326
|
+
*/
|
|
140
327
|
declare function int(value: number): Integer;
|
|
328
|
+
/**
|
|
329
|
+
* Creates an OPack sized integer with an explicit byte width.
|
|
330
|
+
* Used during decoding to preserve the original wire size, and during
|
|
331
|
+
* encoding to force a specific byte width.
|
|
332
|
+
*
|
|
333
|
+
* @param value - The integer value.
|
|
334
|
+
* @param size - The byte width (1, 2, 4, or 8).
|
|
335
|
+
* @returns A SizedInteger wrapper for OPack encoding.
|
|
336
|
+
*/
|
|
141
337
|
declare function sizedInteger(value: number, size: number): SizedInteger;
|
|
338
|
+
/**
|
|
339
|
+
* Decodes an OPack-encoded byte array into a JavaScript value.
|
|
340
|
+
* OPack is Apple's compact binary serialization format used in
|
|
341
|
+
* Companion Link and other protocols.
|
|
342
|
+
*
|
|
343
|
+
* @param data - The raw OPack-encoded bytes.
|
|
344
|
+
* @returns The decoded JavaScript value (object, array, string, number, boolean, null, or Uint8Array).
|
|
345
|
+
*/
|
|
142
346
|
declare function decode$1(data: Uint8Array): any;
|
|
347
|
+
/**
|
|
348
|
+
* Encodes a JavaScript value into OPack binary format.
|
|
349
|
+
* Supports null, booleans, numbers, strings, Uint8Array/Buffer, arrays,
|
|
350
|
+
* plain objects, and the explicit type wrappers ({@link float}, {@link int}, {@link sizedInteger}).
|
|
351
|
+
* Automatically deduplicates repeated values using back-references.
|
|
352
|
+
*
|
|
353
|
+
* @param data - The value to encode.
|
|
354
|
+
* @returns The OPack-encoded bytes.
|
|
355
|
+
* @throws TypeError if the value type is unsupported.
|
|
356
|
+
*/
|
|
143
357
|
declare function encode$1(data: any): Uint8Array;
|
|
144
358
|
//#endregion
|
|
145
359
|
//#region ../../node_modules/.bun/@plist+common@1.1.0/node_modules/@plist/common/lib/cjs/types.d.ts
|
|
@@ -159,9 +373,17 @@ declare namespace plist_d_exports {
|
|
|
159
373
|
declare namespace tlv8_d_exports {
|
|
160
374
|
export { ErrorCode, Flags, Method, State, TLV8PairingError, Value, bail, decode, encode };
|
|
161
375
|
}
|
|
376
|
+
/**
|
|
377
|
+
* TLV8 pairing flags used during HAP pair-setup and pair-verify.
|
|
378
|
+
* Sent as part of the TLV8 Flags (0x13) value.
|
|
379
|
+
*/
|
|
162
380
|
declare const Flags: {
|
|
163
381
|
readonly TransientPairing: 0x10;
|
|
164
382
|
};
|
|
383
|
+
/**
|
|
384
|
+
* TLV8 error codes returned by the accessory during pairing.
|
|
385
|
+
* Included in the Error (0x07) TLV value.
|
|
386
|
+
*/
|
|
165
387
|
declare const ErrorCode: {
|
|
166
388
|
readonly Unknown: 0x01;
|
|
167
389
|
readonly Authentication: 0x02;
|
|
@@ -171,6 +393,10 @@ declare const ErrorCode: {
|
|
|
171
393
|
readonly Unavailable: 0x06;
|
|
172
394
|
readonly Busy: 0x07;
|
|
173
395
|
};
|
|
396
|
+
/**
|
|
397
|
+
* HAP pairing method identifiers. Sent in the Method (0x00) TLV value
|
|
398
|
+
* to indicate which pairing operation is being performed.
|
|
399
|
+
*/
|
|
174
400
|
declare const Method: {
|
|
175
401
|
readonly PairSetup: 0x00;
|
|
176
402
|
readonly PairSetupWithAuth: 0x01;
|
|
@@ -179,6 +405,10 @@ declare const Method: {
|
|
|
179
405
|
readonly RemovePairing: 0x04;
|
|
180
406
|
readonly ListPairing: 0x05;
|
|
181
407
|
};
|
|
408
|
+
/**
|
|
409
|
+
* HAP pairing state machine steps (M1 through M6).
|
|
410
|
+
* Each state corresponds to a message in the SRP pair-setup or pair-verify flow.
|
|
411
|
+
*/
|
|
182
412
|
declare const State: {
|
|
183
413
|
readonly M1: 0x01;
|
|
184
414
|
readonly M2: 0x02;
|
|
@@ -187,6 +417,10 @@ declare const State: {
|
|
|
187
417
|
readonly M5: 0x05;
|
|
188
418
|
readonly M6: 0x06;
|
|
189
419
|
};
|
|
420
|
+
/**
|
|
421
|
+
* TLV8 type identifiers for the fields exchanged during HAP pairing.
|
|
422
|
+
* Each value is the type byte that precedes the length and data in a TLV8 entry.
|
|
423
|
+
*/
|
|
190
424
|
declare const Value: {
|
|
191
425
|
readonly Method: 0x00;
|
|
192
426
|
readonly Identifier: 0x01;
|
|
@@ -205,12 +439,46 @@ declare const Value: {
|
|
|
205
439
|
readonly Name: 0x11;
|
|
206
440
|
readonly Flags: 0x13;
|
|
207
441
|
};
|
|
442
|
+
/**
|
|
443
|
+
* Error thrown when a TLV8 pairing exchange fails.
|
|
444
|
+
* Carries the numeric error code from the accessory when available.
|
|
445
|
+
*/
|
|
208
446
|
declare class TLV8PairingError extends Error {
|
|
447
|
+
/** The TLV8 error code from the accessory, if present. */
|
|
209
448
|
readonly code: number | undefined;
|
|
449
|
+
/**
|
|
450
|
+
* @param message - Human-readable error description.
|
|
451
|
+
* @param code - The TLV8 error code from the accessory response.
|
|
452
|
+
*/
|
|
210
453
|
constructor(message: string, code?: number);
|
|
211
454
|
}
|
|
455
|
+
/**
|
|
456
|
+
* Inspects a decoded TLV8 response for error or back-off conditions and throws
|
|
457
|
+
* an appropriate {@link TLV8PairingError}. Always throws; the return type `never`
|
|
458
|
+
* signals to the compiler that execution does not continue past this call.
|
|
459
|
+
*
|
|
460
|
+
* @param data - The decoded TLV8 map from a pairing response.
|
|
461
|
+
* @throws TLV8PairingError with the specific error code, back-off time, or a generic message.
|
|
462
|
+
*/
|
|
212
463
|
declare function bail(data: Map<number, Buffer>): never;
|
|
464
|
+
/**
|
|
465
|
+
* Encodes an array of TLV8 entries into a single buffer.
|
|
466
|
+
* Values longer than 255 bytes are automatically split into multiple
|
|
467
|
+
* consecutive TLV fragments of the same type, as required by the TLV8 spec.
|
|
468
|
+
*
|
|
469
|
+
* @param entries - An array of [type, value] tuples. Values can be a single byte (number),
|
|
470
|
+
* a Buffer, or a Uint8Array.
|
|
471
|
+
* @returns A buffer containing all TLV8 entries concatenated.
|
|
472
|
+
*/
|
|
213
473
|
declare function encode(entries: [number, number | Buffer | Uint8Array][]): Buffer;
|
|
474
|
+
/**
|
|
475
|
+
* Decodes a TLV8 buffer into a map of type to value.
|
|
476
|
+
* Consecutive entries with the same type are automatically concatenated,
|
|
477
|
+
* reassembling fragmented values as required by the TLV8 spec.
|
|
478
|
+
*
|
|
479
|
+
* @param buf - The raw TLV8-encoded buffer.
|
|
480
|
+
* @returns A map from TLV8 type byte to the reassembled value buffer.
|
|
481
|
+
*/
|
|
214
482
|
declare function decode(buf: Buffer): Map<number, Buffer>;
|
|
215
483
|
//#endregion
|
|
216
|
-
export { daap_d_exports as DAAP, ntp_d_exports as NTP, opack_d_exports as OPack, plist_d_exports as Plist, tlv8_d_exports as TLV8 };
|
|
484
|
+
export { daap_d_exports as DAAP, nskeyedarchiver_d_exports as NSKeyedArchiver, ntp_d_exports as NTP, opack_d_exports as OPack, plist_d_exports as Plist, tlv8_d_exports as TLV8 };
|
package/dist/index.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import { t as __exportAll } from "./chunk-DQk6qfdC.mjs";
|
|
|
4
4
|
var daap_exports = /* @__PURE__ */ __exportAll({
|
|
5
5
|
ContentCode: () => ContentCode,
|
|
6
6
|
TagType: () => TagType,
|
|
7
|
-
decode: () => decode$
|
|
7
|
+
decode: () => decode$4,
|
|
8
8
|
decodeTag: () => decodeTag,
|
|
9
9
|
decodeToObject: () => decodeToObject,
|
|
10
10
|
decodeTrackMetadata: () => decodeTrackMetadata,
|
|
@@ -14,6 +14,10 @@ var daap_exports = /* @__PURE__ */ __exportAll({
|
|
|
14
14
|
encodeTagWithSize: () => encodeTagWithSize,
|
|
15
15
|
encodeTrackMetadata: () => encodeTrackMetadata
|
|
16
16
|
});
|
|
17
|
+
/**
|
|
18
|
+
* Maps four-character DAAP tag codes to their human-readable DMAP/DAAP content code names.
|
|
19
|
+
* Used to identify the semantic meaning of tags in DAAP protocol messages.
|
|
20
|
+
*/
|
|
17
21
|
const ContentCode = {
|
|
18
22
|
mlit: "dmap.listingitem",
|
|
19
23
|
mlcl: "dmap.listing",
|
|
@@ -43,6 +47,15 @@ const ContentCode = {
|
|
|
43
47
|
cavs: "daap.songvisiblestate",
|
|
44
48
|
aePP: "com.apple.itunes.photo-properties"
|
|
45
49
|
};
|
|
50
|
+
/**
|
|
51
|
+
* Maps four-character DAAP tag codes to their data type identifiers.
|
|
52
|
+
*
|
|
53
|
+
* Type values: 1=byte, 2=unsigned byte, 3=short, 4=unsigned short,
|
|
54
|
+
* 5=int, 6=unsigned int, 7=long, 8=unsigned long,
|
|
55
|
+
* 9=string, 10=date, 11=version, 12=container.
|
|
56
|
+
*
|
|
57
|
+
* Used by the decoder to determine how to interpret the raw bytes of each tag.
|
|
58
|
+
*/
|
|
46
59
|
const TagType = {
|
|
47
60
|
mlit: 12,
|
|
48
61
|
mlcl: 12,
|
|
@@ -72,6 +85,15 @@ const TagType = {
|
|
|
72
85
|
cavs: 1,
|
|
73
86
|
aePP: 9
|
|
74
87
|
};
|
|
88
|
+
/**
|
|
89
|
+
* Encodes a single DAAP tag with an automatically sized value.
|
|
90
|
+
* Numbers are encoded in the smallest big-endian representation that fits.
|
|
91
|
+
*
|
|
92
|
+
* @param tag - Four-character ASCII tag code (e.g. 'minm', 'asar').
|
|
93
|
+
* @param value - The value to encode: string (UTF-8), number (auto-sized BE), bigint (8-byte BE), or raw Buffer.
|
|
94
|
+
* @returns A buffer containing the tag, length, and value.
|
|
95
|
+
* @throws Error if the tag is not exactly 4 characters.
|
|
96
|
+
*/
|
|
75
97
|
function encodeTag(tag, value) {
|
|
76
98
|
if (tag.length !== 4) throw new Error(`Invalid DAAP tag: ${tag}. Tags must be exactly 4 characters.`);
|
|
77
99
|
const tagBuffer = Buffer.from(tag, "ascii");
|
|
@@ -102,6 +124,14 @@ function encodeTag(tag, value) {
|
|
|
102
124
|
valueBuffer
|
|
103
125
|
]);
|
|
104
126
|
}
|
|
127
|
+
/**
|
|
128
|
+
* Encodes a DAAP container tag that wraps other encoded tags.
|
|
129
|
+
*
|
|
130
|
+
* @param tag - Four-character ASCII container tag code (e.g. 'mlit', 'mlcl').
|
|
131
|
+
* @param content - Pre-encoded buffer containing the container's child tags.
|
|
132
|
+
* @returns A buffer containing the container tag, length, and nested content.
|
|
133
|
+
* @throws Error if the tag is not exactly 4 characters.
|
|
134
|
+
*/
|
|
105
135
|
function encodeContainer(tag, content) {
|
|
106
136
|
if (tag.length !== 4) throw new Error(`Invalid DAAP tag: ${tag}. Tags must be exactly 4 characters.`);
|
|
107
137
|
const tagBuffer = Buffer.from(tag, "ascii");
|
|
@@ -113,6 +143,13 @@ function encodeContainer(tag, content) {
|
|
|
113
143
|
content
|
|
114
144
|
]);
|
|
115
145
|
}
|
|
146
|
+
/**
|
|
147
|
+
* Encodes playback status fields (playing, shuffle, repeat) into DAAP tags.
|
|
148
|
+
* Only includes tags for fields that are defined in the status object.
|
|
149
|
+
*
|
|
150
|
+
* @param status - The playback status to encode.
|
|
151
|
+
* @returns A buffer containing the encoded DAAP status tags.
|
|
152
|
+
*/
|
|
116
153
|
function encodePlaybackStatus(status) {
|
|
117
154
|
const tags = [];
|
|
118
155
|
if (status.playing !== void 0) tags.push(encodeTagWithSize("caps", status.playing ? 4 : 3, 1));
|
|
@@ -125,6 +162,16 @@ function encodePlaybackStatus(status) {
|
|
|
125
162
|
}
|
|
126
163
|
return Buffer.concat(tags);
|
|
127
164
|
}
|
|
165
|
+
/**
|
|
166
|
+
* Encodes a DAAP tag with an explicitly specified byte size for the numeric value.
|
|
167
|
+
* Useful when the protocol requires a specific size regardless of the value magnitude.
|
|
168
|
+
*
|
|
169
|
+
* @param tag - Four-character ASCII tag code.
|
|
170
|
+
* @param value - The numeric value to encode.
|
|
171
|
+
* @param byteSize - The exact number of bytes to use for the value (1, 2, 4, or 8).
|
|
172
|
+
* @returns A buffer containing the tag, length, and fixed-size value.
|
|
173
|
+
* @throws Error if the tag is not exactly 4 characters.
|
|
174
|
+
*/
|
|
128
175
|
function encodeTagWithSize(tag, value, byteSize) {
|
|
129
176
|
if (tag.length !== 4) throw new Error(`Invalid DAAP tag: ${tag}. Tags must be exactly 4 characters.`);
|
|
130
177
|
const tagBuffer = Buffer.from(tag, "ascii");
|
|
@@ -151,6 +198,14 @@ function encodeTagWithSize(tag, value, byteSize) {
|
|
|
151
198
|
valueBuffer
|
|
152
199
|
]);
|
|
153
200
|
}
|
|
201
|
+
/**
|
|
202
|
+
* Encodes track metadata into a DAAP listing item (`mlit`) container.
|
|
203
|
+
* Only includes tags for fields that are defined in the metadata object.
|
|
204
|
+
* Duration is converted from seconds to milliseconds for the `astm` tag.
|
|
205
|
+
*
|
|
206
|
+
* @param metadata - The track metadata to encode.
|
|
207
|
+
* @returns A buffer containing an `mlit` container with all defined metadata tags.
|
|
208
|
+
*/
|
|
154
209
|
function encodeTrackMetadata(metadata) {
|
|
155
210
|
const tags = [];
|
|
156
211
|
if (metadata.title !== void 0) tags.push(encodeTag("minm", metadata.title));
|
|
@@ -170,7 +225,14 @@ function encodeTrackMetadata(metadata) {
|
|
|
170
225
|
if (metadata.size !== void 0) tags.push(encodeTagWithSize("assz", metadata.size, 4));
|
|
171
226
|
return encodeContainer("mlit", Buffer.concat(tags));
|
|
172
227
|
}
|
|
173
|
-
|
|
228
|
+
/**
|
|
229
|
+
* Decodes all DAAP tags from a buffer sequentially.
|
|
230
|
+
* Stops when the buffer is exhausted or a tag cannot be fully decoded.
|
|
231
|
+
*
|
|
232
|
+
* @param buffer - The raw DAAP-encoded buffer.
|
|
233
|
+
* @returns An array of decoded tags with their raw value buffers.
|
|
234
|
+
*/
|
|
235
|
+
function decode$4(buffer) {
|
|
174
236
|
const tags = [];
|
|
175
237
|
let remaining = buffer;
|
|
176
238
|
while (remaining.length > 0) {
|
|
@@ -182,6 +244,13 @@ function decode$3(buffer) {
|
|
|
182
244
|
}
|
|
183
245
|
return tags;
|
|
184
246
|
}
|
|
247
|
+
/**
|
|
248
|
+
* Decodes a single DAAP tag from the start of a buffer.
|
|
249
|
+
* Returns the decoded tag and the remaining unconsumed buffer.
|
|
250
|
+
*
|
|
251
|
+
* @param buffer - The buffer to decode from. Must contain at least 8 bytes (4 tag + 4 length).
|
|
252
|
+
* @returns A tuple of the decoded tag and remaining buffer, or null if the buffer is too short.
|
|
253
|
+
*/
|
|
185
254
|
function decodeTag(buffer) {
|
|
186
255
|
if (buffer.length < 8) return null;
|
|
187
256
|
const tag = buffer.subarray(0, 4).toString("ascii");
|
|
@@ -195,9 +264,16 @@ function decodeTag(buffer) {
|
|
|
195
264
|
value
|
|
196
265
|
}, remaining];
|
|
197
266
|
}
|
|
267
|
+
/**
|
|
268
|
+
* Decodes a DAAP buffer into a plain object, interpreting values based on {@link TagType}.
|
|
269
|
+
* Container tags (type 12) are recursively decoded. Unknown tags are kept as raw buffers.
|
|
270
|
+
*
|
|
271
|
+
* @param buffer - The raw DAAP-encoded buffer.
|
|
272
|
+
* @returns An object mapping tag codes to their decoded values.
|
|
273
|
+
*/
|
|
198
274
|
function decodeToObject(buffer) {
|
|
199
275
|
const result = {};
|
|
200
|
-
const tags = decode$
|
|
276
|
+
const tags = decode$4(buffer);
|
|
201
277
|
for (const { tag, value } of tags) {
|
|
202
278
|
const tagType = TagType[tag];
|
|
203
279
|
if (tagType === void 0) result[tag] = value;
|
|
@@ -211,6 +287,14 @@ function decodeToObject(buffer) {
|
|
|
211
287
|
}
|
|
212
288
|
return result;
|
|
213
289
|
}
|
|
290
|
+
/**
|
|
291
|
+
* Decodes a DAAP buffer into a structured {@link TrackMetadata} object.
|
|
292
|
+
* Handles both bare tag lists and `mlit`-wrapped containers.
|
|
293
|
+
* Duration is converted from the DAAP millisecond `astm` value back to seconds.
|
|
294
|
+
*
|
|
295
|
+
* @param buffer - The raw DAAP-encoded buffer containing track metadata.
|
|
296
|
+
* @returns The decoded track metadata.
|
|
297
|
+
*/
|
|
214
298
|
function decodeTrackMetadata(buffer) {
|
|
215
299
|
const obj = decodeToObject(buffer);
|
|
216
300
|
const mlit = obj.mlit ?? obj;
|
|
@@ -233,28 +317,107 @@ function decodeTrackMetadata(buffer) {
|
|
|
233
317
|
};
|
|
234
318
|
}
|
|
235
319
|
|
|
320
|
+
//#endregion
|
|
321
|
+
//#region src/nskeyedarchiver.ts
|
|
322
|
+
var nskeyedarchiver_exports = /* @__PURE__ */ __exportAll({
|
|
323
|
+
decode: () => decode$3,
|
|
324
|
+
decodeAsArray: () => decodeAsArray
|
|
325
|
+
});
|
|
326
|
+
/**
|
|
327
|
+
* Decodes an NSKeyedArchiver binary plist into plain JavaScript objects.
|
|
328
|
+
* Resolves CF$UID references, decodes NS.objects/NS.keys into arrays/dicts,
|
|
329
|
+
* and strips $class metadata.
|
|
330
|
+
*
|
|
331
|
+
* @param archive - The parsed plist archive containing `$objects` and `$top` keys.
|
|
332
|
+
* @returns The resolved root object, or null if the archive is invalid.
|
|
333
|
+
*/
|
|
334
|
+
function decode$3(archive) {
|
|
335
|
+
const objects = archive?.["$objects"];
|
|
336
|
+
const top = archive?.["$top"];
|
|
337
|
+
if (!objects || !top) return null;
|
|
338
|
+
const resolve = (ref) => {
|
|
339
|
+
if (ref && typeof ref === "object" && "CF$UID" in ref) return resolve(objects[ref["CF$UID"]]);
|
|
340
|
+
if (ref === "$null") return null;
|
|
341
|
+
if (ref && typeof ref === "object") {
|
|
342
|
+
const obj = ref;
|
|
343
|
+
if (obj["NS.objects"] && Array.isArray(obj["NS.objects"])) return obj["NS.objects"].map(resolve);
|
|
344
|
+
if (obj["NS.keys"] && Array.isArray(obj["NS.keys"])) {
|
|
345
|
+
const keys = obj["NS.keys"].map(resolve);
|
|
346
|
+
const values = obj["NS.objects"].map(resolve);
|
|
347
|
+
const result = {};
|
|
348
|
+
for (let i = 0; i < keys.length; i++) result[keys[i]] = values[i];
|
|
349
|
+
return result;
|
|
350
|
+
}
|
|
351
|
+
const result = {};
|
|
352
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
353
|
+
if (key === "$class" || key === "$classname" || key === "$classes") continue;
|
|
354
|
+
result[key] = resolve(value);
|
|
355
|
+
}
|
|
356
|
+
return result;
|
|
357
|
+
}
|
|
358
|
+
return ref;
|
|
359
|
+
};
|
|
360
|
+
return resolve(top.root ?? top);
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Decodes an NSKeyedArchiver plist and returns the root as an array.
|
|
364
|
+
* If the root is not an array, wraps it in one.
|
|
365
|
+
*
|
|
366
|
+
* @param archive - The parsed plist archive containing `$objects` and `$top` keys.
|
|
367
|
+
* @returns The resolved root as an array. Non-array roots are wrapped in a single-element array.
|
|
368
|
+
*/
|
|
369
|
+
function decodeAsArray(archive) {
|
|
370
|
+
const root = decode$3(archive);
|
|
371
|
+
return Array.isArray(root) ? root : [root];
|
|
372
|
+
}
|
|
373
|
+
|
|
236
374
|
//#endregion
|
|
237
375
|
//#region src/ntp.ts
|
|
238
376
|
var ntp_exports = /* @__PURE__ */ __exportAll({
|
|
239
377
|
decode: () => decode$2,
|
|
240
378
|
encode: () => encode$2,
|
|
241
379
|
now: () => now,
|
|
242
|
-
ns: () => ns,
|
|
243
380
|
parts: () => parts
|
|
244
381
|
});
|
|
382
|
+
/**
|
|
383
|
+
* NTP epoch offset: the number of seconds between the NTP epoch (1900-01-01)
|
|
384
|
+
* and the Unix epoch (1970-01-01).
|
|
385
|
+
*/
|
|
245
386
|
const EPOCH$1 = 2208988800n;
|
|
387
|
+
/**
|
|
388
|
+
* Returns the current wall-clock time as a 64-bit NTP timestamp.
|
|
389
|
+
* The upper 32 bits are whole seconds since the NTP epoch (1900-01-01),
|
|
390
|
+
* and the lower 32 bits are the fractional second.
|
|
391
|
+
*
|
|
392
|
+
* Uses `Date.now()` (wall-clock) rather than a monotone clock because Apple
|
|
393
|
+
* devices expect NTP timestamps anchored to real time.
|
|
394
|
+
*
|
|
395
|
+
* @returns The current time as a 64-bit NTP timestamp.
|
|
396
|
+
*/
|
|
246
397
|
function now() {
|
|
247
|
-
const
|
|
248
|
-
const seconds =
|
|
249
|
-
const frac =
|
|
250
|
-
return seconds + EPOCH$1 << 32n | (frac << 32n) /
|
|
251
|
-
}
|
|
252
|
-
function ns() {
|
|
253
|
-
return process.hrtime.bigint();
|
|
398
|
+
const nowMs = BigInt(Date.now());
|
|
399
|
+
const seconds = nowMs / 1000n;
|
|
400
|
+
const frac = nowMs - seconds * 1000n;
|
|
401
|
+
return seconds + EPOCH$1 << 32n | (frac << 32n) / 1000n;
|
|
254
402
|
}
|
|
403
|
+
/**
|
|
404
|
+
* Splits a 64-bit NTP timestamp into its seconds and fractional parts.
|
|
405
|
+
*
|
|
406
|
+
* @param ntp - A 64-bit NTP timestamp (upper 32 bits = seconds, lower 32 bits = fraction).
|
|
407
|
+
* @returns A tuple of [seconds, fraction] as 32-bit unsigned integers.
|
|
408
|
+
*/
|
|
255
409
|
function parts(ntp) {
|
|
256
410
|
return [Number(ntp >> 32n), Number(ntp & 4294967295n)];
|
|
257
411
|
}
|
|
412
|
+
/**
|
|
413
|
+
* Decodes an NTP timing packet from a buffer into its constituent fields.
|
|
414
|
+
* Expects at least 24 bytes; the send timestamp fields (bytes 24-31) default
|
|
415
|
+
* to 0 if the buffer is shorter than 32 bytes.
|
|
416
|
+
*
|
|
417
|
+
* @param buffer - The raw NTP packet buffer (minimum 24 bytes).
|
|
418
|
+
* @returns The decoded packet fields.
|
|
419
|
+
* @throws RangeError if the buffer is shorter than 24 bytes.
|
|
420
|
+
*/
|
|
258
421
|
function decode$2(buffer) {
|
|
259
422
|
if (buffer.length < 24) throw new RangeError(`NTP packet too small: expected at least 24 bytes, got ${buffer.length}`);
|
|
260
423
|
return {
|
|
@@ -270,6 +433,12 @@ function decode$2(buffer) {
|
|
|
270
433
|
sendtime_frac: buffer.length >= 32 ? buffer.readUInt32BE(28) : 0
|
|
271
434
|
};
|
|
272
435
|
}
|
|
436
|
+
/**
|
|
437
|
+
* Encodes NTP timing packet fields into a 32-byte buffer.
|
|
438
|
+
*
|
|
439
|
+
* @param fields - The packet fields to encode.
|
|
440
|
+
* @returns A 32-byte buffer containing the encoded NTP packet.
|
|
441
|
+
*/
|
|
273
442
|
function encode$2(fields) {
|
|
274
443
|
const buffer = Buffer.allocUnsafe(32);
|
|
275
444
|
buffer.writeUInt8(fields.proto, 0);
|
|
@@ -294,6 +463,11 @@ var opack_exports = /* @__PURE__ */ __exportAll({
|
|
|
294
463
|
int: () => int,
|
|
295
464
|
sizedInteger: () => sizedInteger
|
|
296
465
|
});
|
|
466
|
+
/**
|
|
467
|
+
* OPack wire-format tag bytes. Each tag identifies the type and sometimes
|
|
468
|
+
* the inline length of the value that follows. Apple uses OPack for
|
|
469
|
+
* Companion Link and other device-to-device communication.
|
|
470
|
+
*/
|
|
297
471
|
const TAG = {
|
|
298
472
|
TRUE: 1,
|
|
299
473
|
FALSE: 2,
|
|
@@ -335,59 +509,147 @@ const TAG = {
|
|
|
335
509
|
};
|
|
336
510
|
const textDecoder = new TextDecoder();
|
|
337
511
|
const textEncoder = new TextEncoder();
|
|
512
|
+
/**
|
|
513
|
+
* Wrapper that forces a number to be encoded as an OPack float (FLOAT64).
|
|
514
|
+
* Without this wrapper, JavaScript numbers that happen to be integers
|
|
515
|
+
* would be encoded as OPack integers instead.
|
|
516
|
+
*/
|
|
338
517
|
var Float = class {
|
|
518
|
+
/** The wrapped floating-point value. */
|
|
339
519
|
get value() {
|
|
340
520
|
return this.#value;
|
|
341
521
|
}
|
|
342
522
|
#value;
|
|
523
|
+
/**
|
|
524
|
+
* @param value - The floating-point number to wrap.
|
|
525
|
+
*/
|
|
343
526
|
constructor(value) {
|
|
344
527
|
this.#value = value;
|
|
345
528
|
}
|
|
346
529
|
};
|
|
530
|
+
/**
|
|
531
|
+
* Wrapper that forces a number to be encoded as an OPack integer.
|
|
532
|
+
* Useful when a value must be encoded as an integer even if it could
|
|
533
|
+
* be represented as an inline value.
|
|
534
|
+
*/
|
|
347
535
|
var Integer = class {
|
|
536
|
+
/** The wrapped integer value. */
|
|
348
537
|
get value() {
|
|
349
538
|
return this.#value;
|
|
350
539
|
}
|
|
351
540
|
#value;
|
|
541
|
+
/**
|
|
542
|
+
* @param value - The integer number to wrap.
|
|
543
|
+
*/
|
|
352
544
|
constructor(value) {
|
|
353
545
|
this.#value = value;
|
|
354
546
|
}
|
|
355
547
|
};
|
|
548
|
+
/**
|
|
549
|
+
* An integer with an explicit byte size. Produced during OPack decoding when
|
|
550
|
+
* the wire format specifies the exact byte width (1, 2, 4, or 8). During
|
|
551
|
+
* encoding, the specified size is preserved to maintain wire compatibility.
|
|
552
|
+
*/
|
|
356
553
|
var SizedInteger = class {
|
|
554
|
+
/** The byte width of this integer on the wire (1, 2, 4, or 8). */
|
|
357
555
|
get size() {
|
|
358
556
|
return this.#size;
|
|
359
557
|
}
|
|
558
|
+
/** The numeric value. */
|
|
360
559
|
get value() {
|
|
361
560
|
return this.#value;
|
|
362
561
|
}
|
|
363
562
|
#size;
|
|
364
563
|
#value;
|
|
564
|
+
/**
|
|
565
|
+
* @param value - The integer value.
|
|
566
|
+
* @param size - The byte width for wire encoding (1, 2, 4, or 8).
|
|
567
|
+
*/
|
|
365
568
|
constructor(value, size) {
|
|
366
569
|
this.#size = size;
|
|
367
570
|
this.#value = value;
|
|
368
571
|
}
|
|
572
|
+
/**
|
|
573
|
+
* Returns the numeric value, enabling implicit numeric coercion.
|
|
574
|
+
*
|
|
575
|
+
* @returns The integer value.
|
|
576
|
+
*/
|
|
369
577
|
valueOf() {
|
|
370
578
|
return this.#value;
|
|
371
579
|
}
|
|
372
580
|
};
|
|
581
|
+
/**
|
|
582
|
+
* Creates an OPack float wrapper, ensuring the value is encoded as FLOAT64
|
|
583
|
+
* on the wire regardless of whether it is a whole number.
|
|
584
|
+
*
|
|
585
|
+
* @param value - The floating-point number.
|
|
586
|
+
* @returns A Float wrapper for OPack encoding.
|
|
587
|
+
*/
|
|
373
588
|
function float(value) {
|
|
374
589
|
return new Float(value);
|
|
375
590
|
}
|
|
591
|
+
/**
|
|
592
|
+
* Creates an OPack integer wrapper, ensuring the value is encoded as an
|
|
593
|
+
* explicit integer type on the wire.
|
|
594
|
+
*
|
|
595
|
+
* @param value - The integer number.
|
|
596
|
+
* @returns An Integer wrapper for OPack encoding.
|
|
597
|
+
*/
|
|
376
598
|
function int(value) {
|
|
377
599
|
return new Integer(value);
|
|
378
600
|
}
|
|
601
|
+
/**
|
|
602
|
+
* Creates an OPack sized integer with an explicit byte width.
|
|
603
|
+
* Used during decoding to preserve the original wire size, and during
|
|
604
|
+
* encoding to force a specific byte width.
|
|
605
|
+
*
|
|
606
|
+
* @param value - The integer value.
|
|
607
|
+
* @param size - The byte width (1, 2, 4, or 8).
|
|
608
|
+
* @returns A SizedInteger wrapper for OPack encoding.
|
|
609
|
+
*/
|
|
379
610
|
function sizedInteger(value, size) {
|
|
380
611
|
return new SizedInteger(value, size);
|
|
381
612
|
}
|
|
613
|
+
/**
|
|
614
|
+
* Decodes an OPack-encoded byte array into a JavaScript value.
|
|
615
|
+
* OPack is Apple's compact binary serialization format used in
|
|
616
|
+
* Companion Link and other protocols.
|
|
617
|
+
*
|
|
618
|
+
* @param data - The raw OPack-encoded bytes.
|
|
619
|
+
* @returns The decoded JavaScript value (object, array, string, number, boolean, null, or Uint8Array).
|
|
620
|
+
*/
|
|
382
621
|
function decode$1(data) {
|
|
383
622
|
return _unpackAt(data, 0, []).value;
|
|
384
623
|
}
|
|
624
|
+
/**
|
|
625
|
+
* Encodes a JavaScript value into OPack binary format.
|
|
626
|
+
* Supports null, booleans, numbers, strings, Uint8Array/Buffer, arrays,
|
|
627
|
+
* plain objects, and the explicit type wrappers ({@link float}, {@link int}, {@link sizedInteger}).
|
|
628
|
+
* Automatically deduplicates repeated values using back-references.
|
|
629
|
+
*
|
|
630
|
+
* @param data - The value to encode.
|
|
631
|
+
* @returns The OPack-encoded bytes.
|
|
632
|
+
* @throws TypeError if the value type is unsupported.
|
|
633
|
+
*/
|
|
385
634
|
function encode$1(data) {
|
|
386
635
|
return _pack(data, []);
|
|
387
636
|
}
|
|
637
|
+
/**
|
|
638
|
+
* Creates a single-byte Uint8Array.
|
|
639
|
+
*
|
|
640
|
+
* @param b - The byte value (0-255).
|
|
641
|
+
* @returns A Uint8Array containing the single byte.
|
|
642
|
+
*/
|
|
388
643
|
function u8(b) {
|
|
389
644
|
return Uint8Array.of(b);
|
|
390
645
|
}
|
|
646
|
+
/**
|
|
647
|
+
* Converts an unsigned integer to a little-endian byte array.
|
|
648
|
+
*
|
|
649
|
+
* @param value - The integer value to convert.
|
|
650
|
+
* @param byteLen - The number of bytes to produce.
|
|
651
|
+
* @returns A Uint8Array of length `byteLen` in little-endian order.
|
|
652
|
+
*/
|
|
391
653
|
function uintToLEBytes(value, byteLen) {
|
|
392
654
|
const out = new Uint8Array(byteLen);
|
|
393
655
|
let v = BigInt(value);
|
|
@@ -397,6 +659,15 @@ function uintToLEBytes(value, byteLen) {
|
|
|
397
659
|
}
|
|
398
660
|
return out;
|
|
399
661
|
}
|
|
662
|
+
/**
|
|
663
|
+
* Reads a little-endian unsigned integer of arbitrary byte length from a buffer.
|
|
664
|
+
* Returns 0 if the read would exceed the buffer bounds.
|
|
665
|
+
*
|
|
666
|
+
* @param buf - The source buffer.
|
|
667
|
+
* @param offset - The byte offset to start reading from.
|
|
668
|
+
* @param len - The number of bytes to read (1, 2, 4, or any).
|
|
669
|
+
* @returns The decoded unsigned integer value.
|
|
670
|
+
*/
|
|
400
671
|
function readLittleEndian(buf, offset, len) {
|
|
401
672
|
if (offset + len > buf.length) return 0;
|
|
402
673
|
if (len === 1) return buf[offset];
|
|
@@ -408,6 +679,16 @@ function readLittleEndian(buf, offset, len) {
|
|
|
408
679
|
return Number(v);
|
|
409
680
|
}
|
|
410
681
|
}
|
|
682
|
+
/**
|
|
683
|
+
* Recursively packs a JavaScript value into OPack binary format.
|
|
684
|
+
* Maintains an object list for back-reference deduplication: if a packed
|
|
685
|
+
* value already exists in the list, a compact reference tag is emitted instead.
|
|
686
|
+
*
|
|
687
|
+
* @param data - The value to pack.
|
|
688
|
+
* @param objectList - Accumulator of previously packed objects for deduplication.
|
|
689
|
+
* @returns The OPack-encoded bytes for this value.
|
|
690
|
+
* @throws TypeError if the value type is unsupported.
|
|
691
|
+
*/
|
|
411
692
|
function _pack(data, objectList) {
|
|
412
693
|
let packed = null;
|
|
413
694
|
if (data === null || data === void 0) packed = u8(TAG.NULL);
|
|
@@ -444,6 +725,10 @@ function _pack(data, objectList) {
|
|
|
444
725
|
packed = new Uint8Array(9);
|
|
445
726
|
packed[0] = TAG.FLOAT64;
|
|
446
727
|
new DataView(packed.buffer, packed.byteOffset + 1, 8).setFloat64(0, data, true);
|
|
728
|
+
} else if (data < 0) {
|
|
729
|
+
packed = new Uint8Array(9);
|
|
730
|
+
packed[0] = TAG.INT_8BYTE;
|
|
731
|
+
new DataView(packed.buffer, packed.byteOffset + 1, 8).setBigInt64(0, BigInt(data), true);
|
|
447
732
|
} else if (data <= TAG.INT_INLINE_MAX_VALUE) packed = u8(TAG.INT_BASE + data);
|
|
448
733
|
else if (data <= 255) {
|
|
449
734
|
packed = new Uint8Array(2);
|
|
@@ -612,6 +897,18 @@ function _pack(data, objectList) {
|
|
|
612
897
|
else if (packed.length > 1) objectList.push(packed);
|
|
613
898
|
return packed;
|
|
614
899
|
}
|
|
900
|
+
/**
|
|
901
|
+
* Unpacks a single OPack value starting at the given offset.
|
|
902
|
+
* Handles all OPack types: booleans, null, UUID, timestamp, integers, floats,
|
|
903
|
+
* strings, byte arrays, arrays, dictionaries, and back-references.
|
|
904
|
+
* Decoded non-reference values are added to the object list for future reference resolution.
|
|
905
|
+
*
|
|
906
|
+
* @param data - The full OPack-encoded buffer.
|
|
907
|
+
* @param offset - The byte offset to start unpacking from.
|
|
908
|
+
* @param objectList - Accumulator of previously unpacked objects for reference resolution.
|
|
909
|
+
* @returns The unpacked value and the new byte offset.
|
|
910
|
+
* @throws TypeError if the buffer is exhausted or an unknown tag is encountered.
|
|
911
|
+
*/
|
|
615
912
|
function _unpackAt(data, offset, objectList) {
|
|
616
913
|
if (offset >= data.length) throw new TypeError("No data to unpack");
|
|
617
914
|
const tag = data[offset];
|
|
@@ -1261,7 +1558,15 @@ var tlv8_exports = /* @__PURE__ */ __exportAll({
|
|
|
1261
1558
|
decode: () => decode,
|
|
1262
1559
|
encode: () => encode
|
|
1263
1560
|
});
|
|
1561
|
+
/**
|
|
1562
|
+
* TLV8 pairing flags used during HAP pair-setup and pair-verify.
|
|
1563
|
+
* Sent as part of the TLV8 Flags (0x13) value.
|
|
1564
|
+
*/
|
|
1264
1565
|
const Flags = { TransientPairing: 16 };
|
|
1566
|
+
/**
|
|
1567
|
+
* TLV8 error codes returned by the accessory during pairing.
|
|
1568
|
+
* Included in the Error (0x07) TLV value.
|
|
1569
|
+
*/
|
|
1265
1570
|
const ErrorCode = {
|
|
1266
1571
|
Unknown: 1,
|
|
1267
1572
|
Authentication: 2,
|
|
@@ -1271,6 +1576,10 @@ const ErrorCode = {
|
|
|
1271
1576
|
Unavailable: 6,
|
|
1272
1577
|
Busy: 7
|
|
1273
1578
|
};
|
|
1579
|
+
/**
|
|
1580
|
+
* HAP pairing method identifiers. Sent in the Method (0x00) TLV value
|
|
1581
|
+
* to indicate which pairing operation is being performed.
|
|
1582
|
+
*/
|
|
1274
1583
|
const Method = {
|
|
1275
1584
|
PairSetup: 0,
|
|
1276
1585
|
PairSetupWithAuth: 1,
|
|
@@ -1279,6 +1588,10 @@ const Method = {
|
|
|
1279
1588
|
RemovePairing: 4,
|
|
1280
1589
|
ListPairing: 5
|
|
1281
1590
|
};
|
|
1591
|
+
/**
|
|
1592
|
+
* HAP pairing state machine steps (M1 through M6).
|
|
1593
|
+
* Each state corresponds to a message in the SRP pair-setup or pair-verify flow.
|
|
1594
|
+
*/
|
|
1282
1595
|
const State = {
|
|
1283
1596
|
M1: 1,
|
|
1284
1597
|
M2: 2,
|
|
@@ -1287,6 +1600,10 @@ const State = {
|
|
|
1287
1600
|
M5: 5,
|
|
1288
1601
|
M6: 6
|
|
1289
1602
|
};
|
|
1603
|
+
/**
|
|
1604
|
+
* TLV8 type identifiers for the fields exchanged during HAP pairing.
|
|
1605
|
+
* Each value is the type byte that precedes the length and data in a TLV8 entry.
|
|
1606
|
+
*/
|
|
1290
1607
|
const Value = {
|
|
1291
1608
|
Method: 0,
|
|
1292
1609
|
Identifier: 1,
|
|
@@ -1305,14 +1622,31 @@ const Value = {
|
|
|
1305
1622
|
Name: 17,
|
|
1306
1623
|
Flags: 19
|
|
1307
1624
|
};
|
|
1625
|
+
/**
|
|
1626
|
+
* Error thrown when a TLV8 pairing exchange fails.
|
|
1627
|
+
* Carries the numeric error code from the accessory when available.
|
|
1628
|
+
*/
|
|
1308
1629
|
var TLV8PairingError = class extends Error {
|
|
1630
|
+
/** The TLV8 error code from the accessory, if present. */
|
|
1309
1631
|
code;
|
|
1632
|
+
/**
|
|
1633
|
+
* @param message - Human-readable error description.
|
|
1634
|
+
* @param code - The TLV8 error code from the accessory response.
|
|
1635
|
+
*/
|
|
1310
1636
|
constructor(message, code) {
|
|
1311
1637
|
super(message);
|
|
1312
1638
|
this.name = "TLV8PairingError";
|
|
1313
1639
|
this.code = code;
|
|
1314
1640
|
}
|
|
1315
1641
|
};
|
|
1642
|
+
/**
|
|
1643
|
+
* Inspects a decoded TLV8 response for error or back-off conditions and throws
|
|
1644
|
+
* an appropriate {@link TLV8PairingError}. Always throws; the return type `never`
|
|
1645
|
+
* signals to the compiler that execution does not continue past this call.
|
|
1646
|
+
*
|
|
1647
|
+
* @param data - The decoded TLV8 map from a pairing response.
|
|
1648
|
+
* @throws TLV8PairingError with the specific error code, back-off time, or a generic message.
|
|
1649
|
+
*/
|
|
1316
1650
|
function bail(data) {
|
|
1317
1651
|
if (data.has(Value.BackOff)) {
|
|
1318
1652
|
const buffer = data.get(Value.BackOff);
|
|
@@ -1326,6 +1660,15 @@ function bail(data) {
|
|
|
1326
1660
|
}
|
|
1327
1661
|
throw new TLV8PairingError("Invalid response");
|
|
1328
1662
|
}
|
|
1663
|
+
/**
|
|
1664
|
+
* Encodes an array of TLV8 entries into a single buffer.
|
|
1665
|
+
* Values longer than 255 bytes are automatically split into multiple
|
|
1666
|
+
* consecutive TLV fragments of the same type, as required by the TLV8 spec.
|
|
1667
|
+
*
|
|
1668
|
+
* @param entries - An array of [type, value] tuples. Values can be a single byte (number),
|
|
1669
|
+
* a Buffer, or a Uint8Array.
|
|
1670
|
+
* @returns A buffer containing all TLV8 entries concatenated.
|
|
1671
|
+
*/
|
|
1329
1672
|
function encode(entries) {
|
|
1330
1673
|
let totalSize = 0;
|
|
1331
1674
|
for (const [, valueRaw] of entries) {
|
|
@@ -1361,6 +1704,14 @@ function encode(entries) {
|
|
|
1361
1704
|
}
|
|
1362
1705
|
return result;
|
|
1363
1706
|
}
|
|
1707
|
+
/**
|
|
1708
|
+
* Decodes a TLV8 buffer into a map of type to value.
|
|
1709
|
+
* Consecutive entries with the same type are automatically concatenated,
|
|
1710
|
+
* reassembling fragmented values as required by the TLV8 spec.
|
|
1711
|
+
*
|
|
1712
|
+
* @param buf - The raw TLV8-encoded buffer.
|
|
1713
|
+
* @returns A map from TLV8 type byte to the reassembled value buffer.
|
|
1714
|
+
*/
|
|
1364
1715
|
function decode(buf) {
|
|
1365
1716
|
const map = /* @__PURE__ */ new Map();
|
|
1366
1717
|
let i = 0;
|
|
@@ -1380,4 +1731,4 @@ function decode(buf) {
|
|
|
1380
1731
|
}
|
|
1381
1732
|
|
|
1382
1733
|
//#endregion
|
|
1383
|
-
export { daap_exports as DAAP, ntp_exports as NTP, opack_exports as OPack, plist_exports as Plist, tlv8_exports as TLV8 };
|
|
1734
|
+
export { daap_exports as DAAP, nskeyedarchiver_exports as NSKeyedArchiver, ntp_exports as NTP, opack_exports as OPack, plist_exports as Plist, tlv8_exports as TLV8 };
|