ox 0.9.13 → 0.9.15

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 (46) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/Cbor/package.json +6 -0
  3. package/_cjs/core/AbiConstructor.js +1 -1
  4. package/_cjs/core/AbiConstructor.js.map +1 -1
  5. package/_cjs/core/AbiError.js +1 -1
  6. package/_cjs/core/AbiError.js.map +1 -1
  7. package/_cjs/core/AbiFunction.js +1 -1
  8. package/_cjs/core/AbiFunction.js.map +1 -1
  9. package/_cjs/core/Cbor.js +690 -0
  10. package/_cjs/core/Cbor.js.map +1 -0
  11. package/_cjs/core/Errors.js +38 -4
  12. package/_cjs/core/Errors.js.map +1 -1
  13. package/_cjs/index.js +3 -2
  14. package/_cjs/index.js.map +1 -1
  15. package/_cjs/version.js +1 -1
  16. package/_esm/core/AbiConstructor.js +1 -1
  17. package/_esm/core/AbiConstructor.js.map +1 -1
  18. package/_esm/core/AbiError.js +1 -1
  19. package/_esm/core/AbiError.js.map +1 -1
  20. package/_esm/core/AbiFunction.js +1 -1
  21. package/_esm/core/AbiFunction.js.map +1 -1
  22. package/_esm/core/Cbor.js +771 -0
  23. package/_esm/core/Cbor.js.map +1 -0
  24. package/_esm/core/Errors.js +38 -4
  25. package/_esm/core/Errors.js.map +1 -1
  26. package/_esm/index.js +32 -0
  27. package/_esm/index.js.map +1 -1
  28. package/_esm/version.js +1 -1
  29. package/_types/core/Cbor.d.ts +187 -0
  30. package/_types/core/Cbor.d.ts.map +1 -0
  31. package/_types/core/Errors.d.ts +22 -0
  32. package/_types/core/Errors.d.ts.map +1 -1
  33. package/_types/core/WebAuthnP256.d.ts +1 -0
  34. package/_types/core/WebAuthnP256.d.ts.map +1 -1
  35. package/_types/index.d.ts +32 -0
  36. package/_types/index.d.ts.map +1 -1
  37. package/_types/version.d.ts +1 -1
  38. package/core/AbiConstructor.ts +1 -1
  39. package/core/AbiError.ts +1 -1
  40. package/core/AbiFunction.ts +1 -1
  41. package/core/Cbor.ts +912 -0
  42. package/core/Errors.ts +43 -4
  43. package/core/WebAuthnP256.ts +28 -0
  44. package/index.ts +33 -0
  45. package/package.json +6 -1
  46. package/version.ts +1 -1
@@ -0,0 +1,771 @@
1
+ import * as Bytes from './Bytes.js';
2
+ import * as Errors from './Errors.js';
3
+ import * as Hex from './Hex.js';
4
+ import * as Cursor from './internal/cursor.js';
5
+ /**
6
+ * Encodes a value into CBOR (Concise Binary Object Representation) format.
7
+ *
8
+ * @example
9
+ * ```ts twoslash
10
+ * import { Cbor } from 'ox'
11
+ *
12
+ * Cbor.encode([1, 2, 3])
13
+ * // @log: '0x83010203'
14
+ *
15
+ * Cbor.encode({ foo: 'bar', baz: [1, 2, 3] })
16
+ * // @log: '0xa263666f6f636261726362617a83010203'
17
+ *
18
+ * Cbor.encode('hello', { as: 'Bytes' })
19
+ * // @log: Uint8Array(6) [ 101, 104, 101, 108, 108, 111 ]
20
+ * ```
21
+ *
22
+ * @param data - The value to encode.
23
+ * @param options - Encoding options.
24
+ * @returns The CBOR-encoded value.
25
+ */
26
+ export function encode(data, options = {}) {
27
+ const { as = 'Hex' } = options;
28
+ const encodable = getEncodable(data);
29
+ const cursor = Cursor.create(new Uint8Array(encodable.length));
30
+ encodable.encode(cursor);
31
+ if (as === 'Hex')
32
+ return Hex.fromBytes(cursor.bytes);
33
+ return cursor.bytes;
34
+ }
35
+ /**
36
+ * Decodes CBOR (Concise Binary Object Representation) data into a JavaScript value.
37
+ *
38
+ * @example
39
+ * ```ts twoslash
40
+ * import { Cbor } from 'ox'
41
+ *
42
+ * Cbor.decode('0x83010203')
43
+ * // @log: [1, 2, 3]
44
+ *
45
+ * Cbor.decode('0xa263666f6f636261726362617a83010203')
46
+ * // @log: { foo: 'bar', baz: [1, 2, 3] }
47
+ *
48
+ * Cbor.decode(new Uint8Array([101, 104, 101, 108, 108, 111]))
49
+ * // @log: 'hello'
50
+ * ```
51
+ *
52
+ * @param data - The CBOR-encoded data to decode.
53
+ * @param options - Decoding options.
54
+ * @returns The decoded value.
55
+ */
56
+ export function decode(data) {
57
+ const bytes = (() => {
58
+ if (typeof data === 'string') {
59
+ if (data.length > 3 && data.length % 2 !== 0)
60
+ throw new Hex.InvalidLengthError(data);
61
+ return Bytes.fromHex(data);
62
+ }
63
+ return data;
64
+ })();
65
+ const cursor = Cursor.create(bytes);
66
+ return decodeCursor(cursor);
67
+ }
68
+ export class InvalidMajorTypeError extends Errors.BaseError {
69
+ constructor({ majorType }) {
70
+ super(`Invalid CBOR major type: ${majorType}`);
71
+ Object.defineProperty(this, "name", {
72
+ enumerable: true,
73
+ configurable: true,
74
+ writable: true,
75
+ value: 'Cbor.InvalidMajorTypeError'
76
+ });
77
+ }
78
+ }
79
+ export class InvalidAdditionalInfoError extends Errors.BaseError {
80
+ constructor({ additionalInfo }) {
81
+ super(`Invalid CBOR additional info: ${additionalInfo}`);
82
+ Object.defineProperty(this, "name", {
83
+ enumerable: true,
84
+ configurable: true,
85
+ writable: true,
86
+ value: 'Cbor.InvalidAdditionalInfoError'
87
+ });
88
+ }
89
+ }
90
+ export class Unsupported64BitIntegerError extends Errors.BaseError {
91
+ constructor() {
92
+ super('64-bit integers are not supported in CBOR decoding.');
93
+ Object.defineProperty(this, "name", {
94
+ enumerable: true,
95
+ configurable: true,
96
+ writable: true,
97
+ value: 'Cbor.Unsupported64BitIntegerError'
98
+ });
99
+ }
100
+ }
101
+ export class UnsupportedTagError extends Errors.BaseError {
102
+ constructor({ tag }) {
103
+ super(`CBOR tagged data (tag ${tag}) is not yet supported.`);
104
+ Object.defineProperty(this, "name", {
105
+ enumerable: true,
106
+ configurable: true,
107
+ writable: true,
108
+ value: 'Cbor.UnsupportedTagError'
109
+ });
110
+ }
111
+ }
112
+ export class InvalidIndefiniteLengthChunkError extends Errors.BaseError {
113
+ constructor({ type }) {
114
+ super(`Invalid chunk type in indefinite-length ${type}`);
115
+ Object.defineProperty(this, "name", {
116
+ enumerable: true,
117
+ configurable: true,
118
+ writable: true,
119
+ value: 'Cbor.InvalidIndefiniteLengthChunkError'
120
+ });
121
+ }
122
+ }
123
+ export class InvalidSimpleValueError extends Errors.BaseError {
124
+ constructor({ value }) {
125
+ super(`Invalid CBOR simple value: ${value}`);
126
+ Object.defineProperty(this, "name", {
127
+ enumerable: true,
128
+ configurable: true,
129
+ writable: true,
130
+ value: 'Cbor.InvalidSimpleValueError'
131
+ });
132
+ }
133
+ }
134
+ export class UnsupportedBigIntError extends Errors.BaseError {
135
+ constructor() {
136
+ super('BigInt values are not supported in CBOR encoding.');
137
+ Object.defineProperty(this, "name", {
138
+ enumerable: true,
139
+ configurable: true,
140
+ writable: true,
141
+ value: 'Cbor.UnsupportedBigIntError'
142
+ });
143
+ }
144
+ }
145
+ export class UnexpectedTokenError extends Errors.BaseError {
146
+ constructor({ token }) {
147
+ super(`Unexpected token: ${token}`);
148
+ Object.defineProperty(this, "name", {
149
+ enumerable: true,
150
+ configurable: true,
151
+ writable: true,
152
+ value: 'Cbor.UnexpectedTokenError'
153
+ });
154
+ }
155
+ }
156
+ export class NumberTooLargeError extends Errors.BaseError {
157
+ constructor({ number }) {
158
+ super(`Number exceeds maximum safe integer (${Number.MAX_SAFE_INTEGER}): ${number}`);
159
+ Object.defineProperty(this, "name", {
160
+ enumerable: true,
161
+ configurable: true,
162
+ writable: true,
163
+ value: 'Cbor.NumberTooLargeError'
164
+ });
165
+ }
166
+ }
167
+ export class StringTooLargeError extends Errors.BaseError {
168
+ constructor({ size }) {
169
+ super(`String length exceeds maximum (4294967295): ${size}`);
170
+ Object.defineProperty(this, "name", {
171
+ enumerable: true,
172
+ configurable: true,
173
+ writable: true,
174
+ value: 'Cbor.StringTooLargeError'
175
+ });
176
+ }
177
+ }
178
+ export class ArrayTooLargeError extends Errors.BaseError {
179
+ constructor({ size }) {
180
+ super(`Array length exceeds maximum (4294967295): ${size}`);
181
+ Object.defineProperty(this, "name", {
182
+ enumerable: true,
183
+ configurable: true,
184
+ writable: true,
185
+ value: 'Cbor.ArrayTooLargeError'
186
+ });
187
+ }
188
+ }
189
+ export class ObjectTooLargeError extends Errors.BaseError {
190
+ constructor({ size }) {
191
+ super(`Object size exceeds maximum (4294967295): ${size}`);
192
+ Object.defineProperty(this, "name", {
193
+ enumerable: true,
194
+ configurable: true,
195
+ writable: true,
196
+ value: 'Cbor.ObjectTooLargeError'
197
+ });
198
+ }
199
+ }
200
+ export class ByteStringTooLargeError extends Errors.BaseError {
201
+ constructor({ size }) {
202
+ super(`Byte string length exceeds maximum (4294967295): ${size}`);
203
+ Object.defineProperty(this, "name", {
204
+ enumerable: true,
205
+ configurable: true,
206
+ writable: true,
207
+ value: 'Cbor.ByteStringTooLargeError'
208
+ });
209
+ }
210
+ }
211
+ /** @internal */
212
+ // biome-ignore lint/correctness/noUnusedVariables: _
213
+ function getEncodable(value) {
214
+ if (typeof value === 'undefined')
215
+ return { length: 1, encode: (cursor) => cursor.pushUint8(0xf7) };
216
+ if (value === null)
217
+ return { length: 1, encode: (cursor) => cursor.pushUint8(0xf6) };
218
+ if (typeof value === 'boolean')
219
+ return {
220
+ length: 1,
221
+ encode: (cursor) => cursor.pushUint8(value ? 0xf5 : 0xf4),
222
+ };
223
+ if (typeof value === 'number')
224
+ return getEncodable.number(value);
225
+ if (typeof value === 'bigint')
226
+ throw new UnsupportedBigIntError();
227
+ if (typeof value === 'string')
228
+ return getEncodable.string(value);
229
+ if (Array.isArray(value))
230
+ return getEncodable.array(value);
231
+ if (value instanceof Uint8Array)
232
+ return getEncodable.byteString(value);
233
+ if (value instanceof ArrayBuffer)
234
+ return getEncodable.byteString(new Uint8Array(value));
235
+ if (ArrayBuffer.isView(value))
236
+ return getEncodable.byteString(new Uint8Array(value.buffer, value.byteOffset, value.byteLength));
237
+ if (typeof value === 'object')
238
+ return getEncodable.object(value);
239
+ throw new UnexpectedTokenError({ token: String(value) });
240
+ }
241
+ /** @internal */
242
+ (function (getEncodable) {
243
+ /** @internal */
244
+ function number(value) {
245
+ // Handle non-safe integers (floats, NaN, Infinity)
246
+ if (!Number.isSafeInteger(value)) {
247
+ // Use Float32 if the value can be represented without precision loss
248
+ // This creates smaller encodings when possible (5 bytes vs 9 bytes)
249
+ const float32 = Math.fround(value);
250
+ if (Number.isNaN(value) || value === float32)
251
+ return {
252
+ length: 5, // 1 byte prefix + 4 bytes float32
253
+ encode(cursor) {
254
+ cursor.pushUint8(0xfa);
255
+ cursor.dataView.setFloat32(cursor.position, value, false);
256
+ cursor.position += 4;
257
+ },
258
+ };
259
+ return {
260
+ length: 9, // 1 byte prefix + 8 bytes float64
261
+ encode(cursor) {
262
+ cursor.pushUint8(0xfb);
263
+ cursor.dataView.setFloat64(cursor.position, value, false);
264
+ cursor.position += 8;
265
+ },
266
+ };
267
+ }
268
+ // Handle positive integers
269
+ if (value >= 0) {
270
+ if (value <= 0x17)
271
+ return { length: 1, encode: (cursor) => cursor.pushUint8(value) };
272
+ if (value <= 0xff)
273
+ return {
274
+ length: 2, // 1 byte prefix + 1 byte uint8
275
+ encode: (cursor) => {
276
+ cursor.pushUint8(0x18);
277
+ cursor.pushUint8(value);
278
+ },
279
+ };
280
+ if (value <= 0xffff)
281
+ return {
282
+ length: 3, // 1 byte prefix + 2 bytes uint16
283
+ encode: (cursor) => {
284
+ cursor.pushUint8(0x19);
285
+ cursor.pushUint16(value);
286
+ },
287
+ };
288
+ if (value <= 0xffffffff)
289
+ return {
290
+ length: 5, // 1 byte prefix + 4 bytes uint32
291
+ encode: (cursor) => {
292
+ cursor.pushUint8(0x1a);
293
+ cursor.pushUint32(value);
294
+ },
295
+ };
296
+ throw new NumberTooLargeError({ number: value.toString(10) });
297
+ }
298
+ // Handle negative integers
299
+ // CBOR encodes -n as (n-1)
300
+ const positiveNumber = -1 - value;
301
+ if (value >= -24)
302
+ return {
303
+ length: 1,
304
+ encode: (cursor) => cursor.pushUint8(0x20 + positiveNumber),
305
+ };
306
+ if (positiveNumber <= 0xff)
307
+ return {
308
+ length: 2, // 1 byte prefix + 1 byte uint8
309
+ encode: (cursor) => {
310
+ cursor.pushUint8(0x38);
311
+ cursor.pushUint8(positiveNumber);
312
+ },
313
+ };
314
+ if (positiveNumber <= 0xffff)
315
+ return {
316
+ length: 3, // 1 byte prefix + 2 bytes uint16
317
+ encode: (cursor) => {
318
+ cursor.pushUint8(0x39);
319
+ cursor.pushUint16(positiveNumber);
320
+ },
321
+ };
322
+ if (positiveNumber <= 0xffffffff)
323
+ return {
324
+ length: 5, // 1 byte prefix + 4 bytes uint32
325
+ encode: (cursor) => {
326
+ cursor.pushUint8(0x3a);
327
+ cursor.pushUint32(positiveNumber);
328
+ },
329
+ };
330
+ throw new NumberTooLargeError({ number: value.toString(10) });
331
+ }
332
+ getEncodable.number = number;
333
+ /** @internal */
334
+ function string(value) {
335
+ const encoded = Bytes.fromString(value);
336
+ const size = encoded.length;
337
+ if (size <= 0x17)
338
+ return {
339
+ length: 1 + size, // 1 byte prefix + size bytes
340
+ encode(cursor) {
341
+ cursor.pushUint8(0x60 + size);
342
+ if (size > 0)
343
+ cursor.pushBytes(encoded);
344
+ },
345
+ };
346
+ if (size <= 0xff)
347
+ return {
348
+ length: 2 + size, // 1 byte prefix + 1 byte uint8 + size bytes
349
+ encode(cursor) {
350
+ cursor.pushUint8(0x78);
351
+ cursor.pushUint8(size);
352
+ cursor.pushBytes(encoded);
353
+ },
354
+ };
355
+ if (size <= 0xffff)
356
+ return {
357
+ length: 3 + size, // 1 byte prefix + 2 bytes uint16 + size bytes
358
+ encode(cursor) {
359
+ cursor.pushUint8(0x79);
360
+ cursor.pushUint16(size);
361
+ cursor.pushBytes(encoded);
362
+ },
363
+ };
364
+ if (size <= 0xffffffff)
365
+ return {
366
+ length: 5 + size, // 1 byte prefix + 4 bytes uint32 + size bytes
367
+ encode(cursor) {
368
+ cursor.pushUint8(0x7a);
369
+ cursor.pushUint32(size);
370
+ cursor.pushBytes(encoded);
371
+ },
372
+ };
373
+ throw new StringTooLargeError({ size });
374
+ }
375
+ getEncodable.string = string;
376
+ /** @internal */
377
+ function array(value) {
378
+ const items = value.map((item) => getEncodable(item));
379
+ const bodyLength = items.reduce((acc, item) => acc + item.length, 0);
380
+ const size = value.length;
381
+ if (size <= 0x17)
382
+ return {
383
+ length: 1 + bodyLength, // 1 byte prefix + body length
384
+ encode(cursor) {
385
+ cursor.pushUint8(0x80 + size);
386
+ for (const item of items)
387
+ item.encode(cursor);
388
+ },
389
+ };
390
+ if (size <= 0xff)
391
+ return {
392
+ length: 2 + bodyLength, // 1 byte prefix + 1 byte uint8 + body length
393
+ encode(cursor) {
394
+ cursor.pushUint8(0x98);
395
+ cursor.pushUint8(size);
396
+ for (const item of items)
397
+ item.encode(cursor);
398
+ },
399
+ };
400
+ if (size <= 0xffff)
401
+ return {
402
+ length: 3 + bodyLength, // 1 byte prefix + 2 bytes uint16 + body length
403
+ encode(cursor) {
404
+ cursor.pushUint8(0x99);
405
+ cursor.pushUint16(size);
406
+ for (const item of items)
407
+ item.encode(cursor);
408
+ },
409
+ };
410
+ if (size <= 0xffffffff)
411
+ return {
412
+ length: 5 + bodyLength, // 1 byte prefix + 4 bytes uint32 + body length
413
+ encode(cursor) {
414
+ cursor.pushUint8(0x9a);
415
+ cursor.pushUint32(size);
416
+ for (const item of items)
417
+ item.encode(cursor);
418
+ },
419
+ };
420
+ throw new ArrayTooLargeError({ size });
421
+ }
422
+ getEncodable.array = array;
423
+ /** @internal */
424
+ function byteString(value) {
425
+ const size = value.byteLength;
426
+ if (size <= 0x17)
427
+ return {
428
+ length: 1 + size, // 1 byte prefix + size bytes
429
+ encode(cursor) {
430
+ cursor.pushUint8(0x40 + size);
431
+ cursor.pushBytes(value);
432
+ },
433
+ };
434
+ if (size <= 0xff)
435
+ return {
436
+ length: 2 + size, // 1 byte prefix + 1 byte uint8 + size bytes
437
+ encode(cursor) {
438
+ cursor.pushUint8(0x58);
439
+ cursor.pushUint8(size);
440
+ cursor.pushBytes(value);
441
+ },
442
+ };
443
+ if (size <= 0xffff)
444
+ return {
445
+ length: 3 + size, // 1 byte prefix + 2 bytes uint16 + size bytes
446
+ encode(cursor) {
447
+ cursor.pushUint8(0x59);
448
+ cursor.pushUint16(size);
449
+ cursor.pushBytes(value);
450
+ },
451
+ };
452
+ if (size <= 0xffffffff)
453
+ return {
454
+ length: 5 + size, // 1 byte prefix + 4 bytes uint32 + size bytes
455
+ encode(cursor) {
456
+ cursor.pushUint8(0x5a);
457
+ cursor.pushUint32(size);
458
+ cursor.pushBytes(value);
459
+ },
460
+ };
461
+ throw new ByteStringTooLargeError({ size });
462
+ }
463
+ getEncodable.byteString = byteString;
464
+ /** @internal */
465
+ function object(value) {
466
+ const keys = Object.keys(value);
467
+ const entries = keys.map((key) => ({
468
+ key: getEncodable(key),
469
+ value: getEncodable(value[key]),
470
+ }));
471
+ const bodyLength = entries.reduce((acc, entry) => acc + entry.key.length + entry.value.length, 0);
472
+ const size = keys.length;
473
+ if (size <= 0x17)
474
+ return {
475
+ length: 1 + bodyLength, // 1 byte prefix + body length
476
+ encode(cursor) {
477
+ cursor.pushUint8(0xa0 + size);
478
+ for (const entry of entries) {
479
+ entry.key.encode(cursor);
480
+ entry.value.encode(cursor);
481
+ }
482
+ },
483
+ };
484
+ if (size <= 0xff)
485
+ return {
486
+ length: 2 + bodyLength, // 1 byte prefix + 1 byte uint8 + body length
487
+ encode(cursor) {
488
+ cursor.pushUint8(0xb8);
489
+ cursor.pushUint8(size);
490
+ for (const entry of entries) {
491
+ entry.key.encode(cursor);
492
+ entry.value.encode(cursor);
493
+ }
494
+ },
495
+ };
496
+ if (size <= 0xffff)
497
+ return {
498
+ length: 3 + bodyLength, // 1 byte prefix + 2 bytes uint16 + body length
499
+ encode(cursor) {
500
+ cursor.pushUint8(0xb9);
501
+ cursor.pushUint16(size);
502
+ for (const entry of entries) {
503
+ entry.key.encode(cursor);
504
+ entry.value.encode(cursor);
505
+ }
506
+ },
507
+ };
508
+ if (size <= 0xffffffff)
509
+ return {
510
+ length: 5 + bodyLength, // 1 byte prefix + 4 bytes uint32 + body length
511
+ encode(cursor) {
512
+ cursor.pushUint8(0xba);
513
+ cursor.pushUint32(size);
514
+ for (const entry of entries) {
515
+ entry.key.encode(cursor);
516
+ entry.value.encode(cursor);
517
+ }
518
+ },
519
+ };
520
+ throw new ObjectTooLargeError({ size });
521
+ }
522
+ getEncodable.object = object;
523
+ })(getEncodable || (getEncodable = {}));
524
+ /** @internal */
525
+ // biome-ignore lint/correctness/noUnusedVariables: _
526
+ function decodeCursor(cursor) {
527
+ const initialByte = cursor.readUint8();
528
+ const majorType = initialByte >> 5;
529
+ const additionalInfo = initialByte & 0b00011111;
530
+ switch (majorType) {
531
+ // Major type 0: Unsigned integer
532
+ case 0:
533
+ return decodeCursor.readUnsignedInteger(cursor, additionalInfo);
534
+ // Major type 1: Negative integer
535
+ case 1:
536
+ return decodeCursor.readNegativeInteger(cursor, additionalInfo);
537
+ // Major type 2: Byte string
538
+ case 2:
539
+ return decodeCursor.readByteString(cursor, additionalInfo);
540
+ // Major type 3: Text string
541
+ case 3:
542
+ return decodeCursor.readTextString(cursor, additionalInfo);
543
+ // Major type 4: Array
544
+ case 4:
545
+ return decodeCursor.readArray(cursor, additionalInfo);
546
+ // Major type 5: Map
547
+ case 5:
548
+ return decodeCursor.readMap(cursor, additionalInfo);
549
+ // Major type 6: Tagged data (not yet supported)
550
+ case 6:
551
+ throw new UnsupportedTagError({ tag: additionalInfo });
552
+ // Major type 7: Simple values and floats
553
+ case 7:
554
+ return decodeCursor.readSimpleOrFloat(cursor, additionalInfo);
555
+ default:
556
+ throw new InvalidMajorTypeError({ majorType });
557
+ }
558
+ }
559
+ /** @internal */
560
+ (function (decodeCursor) {
561
+ /** @internal */
562
+ // biome-ignore lint/correctness/noUnusedVariables: _
563
+ function readLength(cursor, additionalInfo) {
564
+ if (additionalInfo < 24)
565
+ return additionalInfo;
566
+ if (additionalInfo === 24)
567
+ return cursor.readUint8();
568
+ if (additionalInfo === 25)
569
+ return cursor.readUint16();
570
+ if (additionalInfo === 26)
571
+ return cursor.readUint32();
572
+ if (additionalInfo === 27)
573
+ throw new Unsupported64BitIntegerError();
574
+ throw new InvalidAdditionalInfoError({ additionalInfo });
575
+ }
576
+ /** @internal */
577
+ function readUnsignedInteger(cursor, additionalInfo) {
578
+ return readLength(cursor, additionalInfo);
579
+ }
580
+ decodeCursor.readUnsignedInteger = readUnsignedInteger;
581
+ /** @internal */
582
+ function readNegativeInteger(cursor, additionalInfo) {
583
+ const value = readLength(cursor, additionalInfo);
584
+ return -1 - value;
585
+ }
586
+ decodeCursor.readNegativeInteger = readNegativeInteger;
587
+ /** @internal */
588
+ function readByteString(cursor, additionalInfo) {
589
+ // Indefinite-length byte string
590
+ if (additionalInfo === 31) {
591
+ const chunks = [];
592
+ let totalLength = 0;
593
+ while (true) {
594
+ const byte = cursor.inspectUint8();
595
+ if (byte === 0xff) {
596
+ cursor.readUint8(); // consume the break byte
597
+ break;
598
+ }
599
+ const chunk = decodeCursor(cursor);
600
+ if (!(chunk instanceof Uint8Array))
601
+ throw new InvalidIndefiniteLengthChunkError({ type: 'byte string' });
602
+ chunks.push(chunk);
603
+ totalLength += chunk.length;
604
+ }
605
+ // Concatenate chunks
606
+ const result = new Uint8Array(totalLength);
607
+ let offset = 0;
608
+ for (const chunk of chunks) {
609
+ result.set(chunk, offset);
610
+ offset += chunk.length;
611
+ }
612
+ return result;
613
+ }
614
+ const length = readLength(cursor, additionalInfo);
615
+ return cursor.readBytes(length);
616
+ }
617
+ decodeCursor.readByteString = readByteString;
618
+ /** @internal */
619
+ function readTextString(cursor, additionalInfo) {
620
+ // Indefinite-length text string
621
+ if (additionalInfo === 31) {
622
+ const chunks = [];
623
+ while (true) {
624
+ const byte = cursor.inspectUint8();
625
+ if (byte === 0xff) {
626
+ cursor.readUint8(); // consume the break byte
627
+ break;
628
+ }
629
+ const chunk = decodeCursor(cursor);
630
+ if (typeof chunk !== 'string')
631
+ throw new InvalidIndefiniteLengthChunkError({ type: 'text string' });
632
+ chunks.push(chunk);
633
+ }
634
+ return chunks.join('');
635
+ }
636
+ const length = readLength(cursor, additionalInfo);
637
+ const bytes = cursor.readBytes(length);
638
+ return Bytes.toString(bytes);
639
+ }
640
+ decodeCursor.readTextString = readTextString;
641
+ /** @internal */
642
+ function readArray(cursor, additionalInfo) {
643
+ // Indefinite-length array
644
+ if (additionalInfo === 31) {
645
+ const result = [];
646
+ while (true) {
647
+ const byte = cursor.inspectUint8();
648
+ if (byte === 0xff) {
649
+ cursor.readUint8(); // consume the break byte
650
+ break;
651
+ }
652
+ result.push(decodeCursor(cursor));
653
+ }
654
+ return result;
655
+ }
656
+ const length = readLength(cursor, additionalInfo);
657
+ const result = [];
658
+ for (let i = 0; i < length; i++) {
659
+ result.push(decodeCursor(cursor));
660
+ }
661
+ return result;
662
+ }
663
+ decodeCursor.readArray = readArray;
664
+ /** @internal */
665
+ function readMap(cursor, additionalInfo) {
666
+ // Indefinite-length map
667
+ if (additionalInfo === 31) {
668
+ const result = {};
669
+ while (true) {
670
+ const byte = cursor.inspectUint8();
671
+ if (byte === 0xff) {
672
+ cursor.readUint8(); // consume the break byte
673
+ break;
674
+ }
675
+ const key = decodeCursor(cursor);
676
+ // Support both string and number keys (for COSE_Key with integer keys)
677
+ const keyStr = typeof key === 'string'
678
+ ? key
679
+ : typeof key === 'number'
680
+ ? String(key)
681
+ : String(key);
682
+ const value = decodeCursor(cursor);
683
+ result[keyStr] = value;
684
+ }
685
+ return result;
686
+ }
687
+ const length = readLength(cursor, additionalInfo);
688
+ const result = {};
689
+ for (let i = 0; i < length; i++) {
690
+ const key = decodeCursor(cursor);
691
+ // Support both string and number keys (for COSE_Key with integer keys)
692
+ const keyStr = typeof key === 'string'
693
+ ? key
694
+ : typeof key === 'number'
695
+ ? String(key)
696
+ : String(key);
697
+ const value = decodeCursor(cursor);
698
+ result[keyStr] = value;
699
+ }
700
+ return result;
701
+ }
702
+ decodeCursor.readMap = readMap;
703
+ /** @internal */
704
+ function readSimpleOrFloat(cursor, additionalInfo) {
705
+ // Simple values
706
+ if (additionalInfo === 20)
707
+ return false;
708
+ if (additionalInfo === 21)
709
+ return true;
710
+ if (additionalInfo === 22)
711
+ return null;
712
+ if (additionalInfo === 23)
713
+ return undefined;
714
+ // Float16 (half-precision)
715
+ if (additionalInfo === 25) {
716
+ const bits = cursor.readUint16();
717
+ return getFloat16(bits);
718
+ }
719
+ // Float32
720
+ if (additionalInfo === 26) {
721
+ const value = cursor.dataView.getFloat32(cursor.position, false);
722
+ cursor.position += 4;
723
+ return value;
724
+ }
725
+ // Float64
726
+ if (additionalInfo === 27) {
727
+ const value = cursor.dataView.getFloat64(cursor.position, false);
728
+ cursor.position += 8;
729
+ return value;
730
+ }
731
+ // Simple value (additional byte)
732
+ if (additionalInfo === 24) {
733
+ const simpleValue = cursor.readUint8();
734
+ // Simple values 0-19 are assigned, 20-23 are in the initial byte
735
+ // 24-31 are reserved, 32-255 are unassigned
736
+ if (simpleValue < 32)
737
+ throw new InvalidSimpleValueError({ value: simpleValue });
738
+ // For now, treat unassigned simple values as undefined
739
+ return undefined;
740
+ }
741
+ throw new InvalidAdditionalInfoError({ additionalInfo });
742
+ }
743
+ decodeCursor.readSimpleOrFloat = readSimpleOrFloat;
744
+ /** @internal */
745
+ function getFloat16(bits) {
746
+ // IEEE 754 half-precision (16-bit) float decoding
747
+ // Format: 1 sign bit, 5 exponent bits, 10 fraction bits
748
+ const sign = (bits >> 15) & 0x1;
749
+ const exponent = (bits >> 10) & 0x1f;
750
+ const fraction = bits & 0x3ff;
751
+ // Handle special cases
752
+ if (exponent === 0) {
753
+ // Subnormal numbers or zero
754
+ if (fraction === 0)
755
+ return sign ? -0 : 0;
756
+ // Subnormal: (-1)^sign × 2^(-14) × (0 + fraction/1024)
757
+ const value = 2 ** -14 * (fraction / 1024);
758
+ return sign ? -value : value;
759
+ }
760
+ if (exponent === 0x1f) {
761
+ // Infinity or NaN
762
+ if (fraction === 0)
763
+ return sign ? -Infinity : Infinity;
764
+ return NaN;
765
+ }
766
+ // Normal numbers: (-1)^sign × 2^(exponent-15) × (1 + fraction/1024)
767
+ const value = 2 ** (exponent - 15) * (1 + fraction / 1024);
768
+ return sign ? -value : value;
769
+ }
770
+ })(decodeCursor || (decodeCursor = {}));
771
+ //# sourceMappingURL=Cbor.js.map