@bcts/dcbor 1.0.0-alpha.10

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 (45) hide show
  1. package/LICENSE +48 -0
  2. package/README.md +13 -0
  3. package/dist/index.cjs +9151 -0
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.d.cts +3107 -0
  6. package/dist/index.d.cts.map +1 -0
  7. package/dist/index.d.mts +3107 -0
  8. package/dist/index.d.mts.map +1 -0
  9. package/dist/index.iife.js +9155 -0
  10. package/dist/index.iife.js.map +1 -0
  11. package/dist/index.mjs +9027 -0
  12. package/dist/index.mjs.map +1 -0
  13. package/package.json +80 -0
  14. package/src/.claude-flow/metrics/agent-metrics.json +1 -0
  15. package/src/.claude-flow/metrics/performance.json +87 -0
  16. package/src/.claude-flow/metrics/task-metrics.json +10 -0
  17. package/src/byte-string.ts +300 -0
  18. package/src/cbor-codable.ts +170 -0
  19. package/src/cbor-tagged-codable.ts +72 -0
  20. package/src/cbor-tagged-decodable.ts +184 -0
  21. package/src/cbor-tagged-encodable.ts +138 -0
  22. package/src/cbor-tagged.ts +104 -0
  23. package/src/cbor.ts +869 -0
  24. package/src/conveniences.ts +840 -0
  25. package/src/date.ts +553 -0
  26. package/src/decode.ts +276 -0
  27. package/src/diag.ts +462 -0
  28. package/src/dump.ts +277 -0
  29. package/src/error.ts +259 -0
  30. package/src/exact.ts +714 -0
  31. package/src/float.ts +279 -0
  32. package/src/global.d.ts +34 -0
  33. package/src/globals.d.ts +0 -0
  34. package/src/index.ts +180 -0
  35. package/src/map.ts +308 -0
  36. package/src/prelude.ts +70 -0
  37. package/src/set.ts +515 -0
  38. package/src/simple.ts +153 -0
  39. package/src/stdlib.ts +55 -0
  40. package/src/string-util.ts +55 -0
  41. package/src/tag.ts +53 -0
  42. package/src/tags-store.ts +294 -0
  43. package/src/tags.ts +231 -0
  44. package/src/varint.ts +124 -0
  45. package/src/walk.ts +516 -0
@@ -0,0 +1,840 @@
1
+ /**
2
+ * Convenience utilities for working with CBOR values.
3
+ *
4
+ * Provides type-safe helpers for checking types, extracting values,
5
+ * and working with arrays, maps, and tagged values.
6
+ *
7
+ * @module conveniences
8
+ */
9
+
10
+ import {
11
+ type Cbor,
12
+ MajorType,
13
+ type CborNumber,
14
+ type CborInput,
15
+ type CborUnsignedType,
16
+ type CborNegativeType,
17
+ type CborByteStringType,
18
+ type CborTextType,
19
+ type CborArrayType,
20
+ type CborMapType,
21
+ type CborTaggedType,
22
+ type CborSimpleType,
23
+ type CborMethods,
24
+ } from "./cbor";
25
+ import type { CborMap } from "./map";
26
+ import { isFloat as isSimpleFloat } from "./simple";
27
+ import { decodeCbor } from "./decode";
28
+ import { CborError } from "./error";
29
+
30
+ // ============================================================================
31
+ // Extraction
32
+ // ============================================================================
33
+
34
+ /**
35
+ * Extract native JavaScript value from CBOR.
36
+ * Converts CBOR types to their JavaScript equivalents.
37
+ */
38
+ export const extractCbor = (cbor: Cbor | Uint8Array): unknown => {
39
+ let c: Cbor;
40
+ if (cbor instanceof Uint8Array) {
41
+ c = decodeCbor(cbor);
42
+ } else {
43
+ c = cbor;
44
+ }
45
+ switch (c.type) {
46
+ case MajorType.Unsigned:
47
+ return c.value;
48
+ case MajorType.Negative:
49
+ if (typeof c.value === "bigint") {
50
+ return -c.value - 1n;
51
+ } else {
52
+ return -c.value - 1;
53
+ }
54
+ case MajorType.ByteString:
55
+ return c.value;
56
+ case MajorType.Text:
57
+ return c.value;
58
+ case MajorType.Array:
59
+ return c.value.map(extractCbor);
60
+ case MajorType.Map:
61
+ return c.value;
62
+ case MajorType.Tagged:
63
+ return c;
64
+ case MajorType.Simple:
65
+ if (c.value.type === "True") return true;
66
+ if (c.value.type === "False") return false;
67
+ if (c.value.type === "Null") return null;
68
+ if (c.value.type === "Float") return c.value.value;
69
+ return c;
70
+ }
71
+ return undefined;
72
+ };
73
+
74
+ // ============================================================================
75
+ // Type Guards
76
+ // ============================================================================
77
+
78
+ /**
79
+ * Check if CBOR value is an unsigned integer.
80
+ *
81
+ * @param cbor - CBOR value to check
82
+ * @returns True if value is unsigned integer
83
+ *
84
+ * @example
85
+ * ```typescript
86
+ * if (isUnsigned(value)) {
87
+ * console.log('Unsigned:', value.value);
88
+ * }
89
+ * ```
90
+ */
91
+ export const isUnsigned = (cbor: Cbor): cbor is CborUnsignedType & CborMethods => {
92
+ return cbor.type === MajorType.Unsigned;
93
+ };
94
+
95
+ /**
96
+ * Check if CBOR value is a negative integer.
97
+ *
98
+ * @param cbor - CBOR value to check
99
+ * @returns True if value is negative integer
100
+ */
101
+ export const isNegative = (cbor: Cbor): cbor is CborNegativeType & CborMethods => {
102
+ return cbor.type === MajorType.Negative;
103
+ };
104
+
105
+ /**
106
+ * Check if CBOR value is any integer (unsigned or negative).
107
+ *
108
+ * @param cbor - CBOR value to check
109
+ * @returns True if value is an integer
110
+ */
111
+ export const isInteger = (
112
+ cbor: Cbor,
113
+ ): cbor is (CborUnsignedType | CborNegativeType) & CborMethods => {
114
+ return cbor.type === MajorType.Unsigned || cbor.type === MajorType.Negative;
115
+ };
116
+
117
+ /**
118
+ * Check if CBOR value is a byte string.
119
+ *
120
+ * @param cbor - CBOR value to check
121
+ * @returns True if value is byte string
122
+ */
123
+ export const isBytes = (cbor: Cbor): cbor is CborByteStringType & CborMethods => {
124
+ return cbor.type === MajorType.ByteString;
125
+ };
126
+
127
+ /**
128
+ * Check if CBOR value is a text string.
129
+ *
130
+ * @param cbor - CBOR value to check
131
+ * @returns True if value is text string
132
+ */
133
+ export const isText = (cbor: Cbor): cbor is CborTextType & CborMethods => {
134
+ return cbor.type === MajorType.Text;
135
+ };
136
+
137
+ /**
138
+ * Check if CBOR value is an array.
139
+ *
140
+ * @param cbor - CBOR value to check
141
+ * @returns True if value is array
142
+ */
143
+ export const isArray = (cbor: Cbor): cbor is CborArrayType & CborMethods => {
144
+ return cbor.type === MajorType.Array;
145
+ };
146
+
147
+ /**
148
+ * Check if CBOR value is a map.
149
+ *
150
+ * @param cbor - CBOR value to check
151
+ * @returns True if value is map
152
+ */
153
+ export const isMap = (cbor: Cbor): cbor is CborMapType & CborMethods => {
154
+ return cbor.type === MajorType.Map;
155
+ };
156
+
157
+ /**
158
+ * Check if CBOR value is tagged.
159
+ *
160
+ * @param cbor - CBOR value to check
161
+ * @returns True if value is tagged
162
+ */
163
+ export const isTagged = (cbor: Cbor): cbor is CborTaggedType & CborMethods => {
164
+ return cbor.type === MajorType.Tagged;
165
+ };
166
+
167
+ /**
168
+ * Check if CBOR value is a simple value.
169
+ *
170
+ * @param cbor - CBOR value to check
171
+ * @returns True if value is simple
172
+ */
173
+ export const isSimple = (cbor: Cbor): cbor is CborSimpleType & CborMethods => {
174
+ return cbor.type === MajorType.Simple;
175
+ };
176
+
177
+ /**
178
+ * Check if CBOR value is a boolean (true or false).
179
+ *
180
+ * @param cbor - CBOR value to check
181
+ * @returns True if value is boolean
182
+ */
183
+ export const isBoolean = (
184
+ cbor: Cbor,
185
+ ): cbor is CborSimpleType &
186
+ CborMethods & { readonly value: { readonly type: "False" } | { readonly type: "True" } } => {
187
+ if (cbor.type !== MajorType.Simple) {
188
+ return false;
189
+ }
190
+ return cbor.value.type === "False" || cbor.value.type === "True";
191
+ };
192
+
193
+ /**
194
+ * Check if CBOR value is null.
195
+ *
196
+ * @param cbor - CBOR value to check
197
+ * @returns True if value is null
198
+ */
199
+ export const isNull = (
200
+ cbor: Cbor,
201
+ ): cbor is CborSimpleType & CborMethods & { readonly value: { readonly type: "Null" } } => {
202
+ if (cbor.type !== MajorType.Simple) {
203
+ return false;
204
+ }
205
+ return cbor.value.type === "Null";
206
+ };
207
+
208
+ /**
209
+ * Check if CBOR value is a float (f16, f32, or f64).
210
+ *
211
+ * @param cbor - CBOR value to check
212
+ * @returns True if value is float
213
+ */
214
+ export const isFloat = (
215
+ cbor: Cbor,
216
+ ): cbor is CborSimpleType &
217
+ CborMethods & { readonly value: { readonly type: "Float"; readonly value: number } } => {
218
+ if (cbor.type !== MajorType.Simple) {
219
+ return false;
220
+ }
221
+ return isSimpleFloat(cbor.value);
222
+ };
223
+
224
+ // ============================================================================
225
+ // Safe Extraction (returns undefined on type mismatch)
226
+ // ============================================================================
227
+
228
+ /**
229
+ * Extract unsigned integer value if type matches.
230
+ *
231
+ * @param cbor - CBOR value
232
+ * @returns Unsigned integer or undefined
233
+ */
234
+ export const asUnsigned = (cbor: Cbor): number | bigint | undefined => {
235
+ if (cbor.type === MajorType.Unsigned) {
236
+ return cbor.value;
237
+ }
238
+ return undefined;
239
+ };
240
+
241
+ /**
242
+ * Extract negative integer value if type matches.
243
+ *
244
+ * @param cbor - CBOR value
245
+ * @returns Negative integer or undefined
246
+ */
247
+ export const asNegative = (cbor: Cbor): number | bigint | undefined => {
248
+ if (cbor.type === MajorType.Negative) {
249
+ // Convert stored magnitude back to actual negative value
250
+ if (typeof cbor.value === "bigint") {
251
+ return -cbor.value - 1n;
252
+ } else {
253
+ return -cbor.value - 1;
254
+ }
255
+ }
256
+ return undefined;
257
+ };
258
+
259
+ /**
260
+ * Extract any integer value (unsigned or negative) if type matches.
261
+ *
262
+ * @param cbor - CBOR value
263
+ * @returns Integer or undefined
264
+ */
265
+ export const asInteger = (cbor: Cbor): number | bigint | undefined => {
266
+ if (cbor.type === MajorType.Unsigned) {
267
+ return cbor.value;
268
+ } else if (cbor.type === MajorType.Negative) {
269
+ // Convert stored magnitude back to actual negative value
270
+ if (typeof cbor.value === "bigint") {
271
+ return -cbor.value - 1n;
272
+ } else {
273
+ return -cbor.value - 1;
274
+ }
275
+ }
276
+ return undefined;
277
+ };
278
+
279
+ /**
280
+ * Extract byte string value if type matches.
281
+ *
282
+ * @param cbor - CBOR value
283
+ * @returns Byte string or undefined
284
+ */
285
+ export const asBytes = (cbor: Cbor): Uint8Array | undefined => {
286
+ if (cbor.type === MajorType.ByteString) {
287
+ return cbor.value;
288
+ }
289
+ return undefined;
290
+ };
291
+
292
+ /**
293
+ * Extract text string value if type matches.
294
+ *
295
+ * @param cbor - CBOR value
296
+ * @returns Text string or undefined
297
+ */
298
+ export const asText = (cbor: Cbor): string | undefined => {
299
+ if (cbor.type === MajorType.Text) {
300
+ return cbor.value;
301
+ }
302
+ return undefined;
303
+ };
304
+
305
+ /**
306
+ * Extract array value if type matches.
307
+ *
308
+ * @param cbor - CBOR value
309
+ * @returns Array or undefined
310
+ */
311
+ export const asArray = (cbor: Cbor): readonly Cbor[] | undefined => {
312
+ if (cbor.type === MajorType.Array) {
313
+ return cbor.value;
314
+ }
315
+ return undefined;
316
+ };
317
+
318
+ /**
319
+ * Extract map value if type matches.
320
+ *
321
+ * @param cbor - CBOR value
322
+ * @returns Map or undefined
323
+ */
324
+ export const asMap = (cbor: Cbor): CborMap | undefined => {
325
+ if (cbor.type === MajorType.Map) {
326
+ return cbor.value;
327
+ }
328
+ return undefined;
329
+ };
330
+
331
+ /**
332
+ * Extract boolean value if type matches.
333
+ *
334
+ * @param cbor - CBOR value
335
+ * @returns Boolean or undefined
336
+ */
337
+ export const asBoolean = (cbor: Cbor): boolean | undefined => {
338
+ if (cbor.type !== MajorType.Simple) {
339
+ return undefined;
340
+ }
341
+ if (cbor.value.type === "True") {
342
+ return true;
343
+ }
344
+ if (cbor.value.type === "False") {
345
+ return false;
346
+ }
347
+ return undefined;
348
+ };
349
+
350
+ /**
351
+ * Extract float value if type matches.
352
+ *
353
+ * @param cbor - CBOR value
354
+ * @returns Float or undefined
355
+ */
356
+ export const asFloat = (cbor: Cbor): number | undefined => {
357
+ if (cbor.type !== MajorType.Simple) {
358
+ return undefined;
359
+ }
360
+ const simple = cbor.value;
361
+ if (isSimpleFloat(simple)) {
362
+ return simple.value;
363
+ }
364
+ return undefined;
365
+ };
366
+
367
+ /**
368
+ * Extract any numeric value (integer or float).
369
+ *
370
+ * @param cbor - CBOR value
371
+ * @returns Number or undefined
372
+ */
373
+ export const asNumber = (cbor: Cbor): CborNumber | undefined => {
374
+ if (cbor.type === MajorType.Unsigned) {
375
+ return cbor.value;
376
+ }
377
+ if (cbor.type === MajorType.Negative) {
378
+ // Convert stored magnitude back to actual negative value
379
+ if (typeof cbor.value === "bigint") {
380
+ return -cbor.value - 1n;
381
+ } else {
382
+ return -cbor.value - 1;
383
+ }
384
+ }
385
+ if (cbor.type === MajorType.Simple) {
386
+ const simple = cbor.value;
387
+ if (isSimpleFloat(simple)) {
388
+ return simple.value;
389
+ }
390
+ }
391
+ return undefined;
392
+ };
393
+
394
+ // ============================================================================
395
+ // Expectations (throw on type mismatch)
396
+ // ============================================================================
397
+
398
+ /**
399
+ * Extract unsigned integer value, throwing if type doesn't match.
400
+ *
401
+ * @param cbor - CBOR value
402
+ * @returns Unsigned integer
403
+ * @throws {CborError} With type 'WrongType' if cbor is not an unsigned integer
404
+ */
405
+ export const expectUnsigned = (cbor: Cbor): number | bigint => {
406
+ const value = asUnsigned(cbor);
407
+ if (value === undefined) {
408
+ throw new CborError({ type: "WrongType" });
409
+ }
410
+ return value;
411
+ };
412
+
413
+ /**
414
+ * Extract negative integer value, throwing if type doesn't match.
415
+ *
416
+ * @param cbor - CBOR value
417
+ * @returns Negative integer
418
+ * @throws {CborError} With type 'WrongType' if cbor is not a negative integer
419
+ */
420
+ export const expectNegative = (cbor: Cbor): number | bigint => {
421
+ const value = asNegative(cbor);
422
+ if (value === undefined) {
423
+ throw new CborError({ type: "WrongType" });
424
+ }
425
+ return value;
426
+ };
427
+
428
+ /**
429
+ * Extract any integer value, throwing if type doesn't match.
430
+ *
431
+ * @param cbor - CBOR value
432
+ * @returns Integer
433
+ * @throws {CborError} With type 'WrongType' if cbor is not an integer
434
+ */
435
+ export const expectInteger = (cbor: Cbor): number | bigint => {
436
+ const value = asInteger(cbor);
437
+ if (value === undefined) {
438
+ throw new CborError({ type: "WrongType" });
439
+ }
440
+ return value;
441
+ };
442
+
443
+ /**
444
+ * Extract byte string value, throwing if type doesn't match.
445
+ *
446
+ * @param cbor - CBOR value
447
+ * @returns Byte string
448
+ * @throws {CborError} With type 'WrongType' if cbor is not a byte string
449
+ */
450
+ export const expectBytes = (cbor: Cbor): Uint8Array => {
451
+ const value = asBytes(cbor);
452
+ if (value === undefined) {
453
+ throw new CborError({ type: "WrongType" });
454
+ }
455
+ return value;
456
+ };
457
+
458
+ /**
459
+ * Extract text string value, throwing if type doesn't match.
460
+ *
461
+ * @param cbor - CBOR value
462
+ * @returns Text string
463
+ * @throws {CborError} With type 'WrongType' if cbor is not a text string
464
+ */
465
+ export const expectText = (cbor: Cbor): string => {
466
+ const value = asText(cbor);
467
+ if (value === undefined) {
468
+ throw new CborError({ type: "WrongType" });
469
+ }
470
+ return value;
471
+ };
472
+
473
+ /**
474
+ * Extract array value, throwing if type doesn't match.
475
+ *
476
+ * @param cbor - CBOR value
477
+ * @returns Array
478
+ * @throws {CborError} With type 'WrongType' if cbor is not an array
479
+ */
480
+ export const expectArray = (cbor: Cbor): readonly Cbor[] => {
481
+ const value = asArray(cbor);
482
+ if (value === undefined) {
483
+ throw new CborError({ type: "WrongType" });
484
+ }
485
+ return value;
486
+ };
487
+
488
+ /**
489
+ * Extract map value, throwing if type doesn't match.
490
+ *
491
+ * @param cbor - CBOR value
492
+ * @returns Map
493
+ * @throws {CborError} With type 'WrongType' if cbor is not a map
494
+ */
495
+ export const expectMap = (cbor: Cbor): CborMap => {
496
+ const value = asMap(cbor);
497
+ if (value === undefined) {
498
+ throw new CborError({ type: "WrongType" });
499
+ }
500
+ return value;
501
+ };
502
+
503
+ /**
504
+ * Extract boolean value, throwing if type doesn't match.
505
+ *
506
+ * @param cbor - CBOR value
507
+ * @returns Boolean
508
+ * @throws {CborError} With type 'WrongType' if cbor is not a boolean
509
+ */
510
+ export const expectBoolean = (cbor: Cbor): boolean => {
511
+ const value = asBoolean(cbor);
512
+ if (value === undefined) {
513
+ throw new CborError({ type: "WrongType" });
514
+ }
515
+ return value;
516
+ };
517
+
518
+ /**
519
+ * Extract float value, throwing if type doesn't match.
520
+ *
521
+ * @param cbor - CBOR value
522
+ * @returns Float
523
+ * @throws {CborError} With type 'WrongType' if cbor is not a float
524
+ */
525
+ export const expectFloat = (cbor: Cbor): number => {
526
+ const value = asFloat(cbor);
527
+ if (value === undefined) {
528
+ throw new CborError({ type: "WrongType" });
529
+ }
530
+ return value;
531
+ };
532
+
533
+ /**
534
+ * Extract any numeric value, throwing if type doesn't match.
535
+ *
536
+ * @param cbor - CBOR value
537
+ * @returns Number
538
+ * @throws {CborError} With type 'WrongType' if cbor is not a number
539
+ */
540
+ export const expectNumber = (cbor: Cbor): CborNumber => {
541
+ const value = asNumber(cbor);
542
+ if (value === undefined) {
543
+ throw new CborError({ type: "WrongType" });
544
+ }
545
+ return value;
546
+ };
547
+
548
+ // ============================================================================
549
+ // Array Operations
550
+ // ============================================================================
551
+
552
+ /**
553
+ * Get array item at index.
554
+ *
555
+ * @param cbor - CBOR value (must be array)
556
+ * @param index - Array index
557
+ * @returns Item at index or undefined
558
+ */
559
+ export const arrayItem = (cbor: Cbor, index: number): Cbor | undefined => {
560
+ if (cbor.type !== MajorType.Array) {
561
+ return undefined;
562
+ }
563
+ const array = cbor.value;
564
+ if (index < 0 || index >= array.length) {
565
+ return undefined;
566
+ }
567
+ return array[index];
568
+ };
569
+
570
+ /**
571
+ * Get array length.
572
+ *
573
+ * @param cbor - CBOR value (must be array)
574
+ * @returns Array length or undefined
575
+ */
576
+ export const arrayLength = (cbor: Cbor): number | undefined => {
577
+ if (cbor.type !== MajorType.Array) {
578
+ return undefined;
579
+ }
580
+ return cbor.value.length;
581
+ };
582
+
583
+ /**
584
+ * Check if array is empty.
585
+ *
586
+ * @param cbor - CBOR value (must be array)
587
+ * @returns True if empty, false if not empty, undefined if not array
588
+ */
589
+ export const arrayIsEmpty = (cbor: Cbor): boolean | undefined => {
590
+ if (cbor.type !== MajorType.Array) {
591
+ return undefined;
592
+ }
593
+ return cbor.value.length === 0;
594
+ };
595
+
596
+ // ============================================================================
597
+ // Map Operations
598
+ // ============================================================================
599
+
600
+ /**
601
+ * Get map value by key.
602
+ *
603
+ * @param cbor - CBOR value (must be map)
604
+ * @param key - Map key
605
+ * @returns Value for key or undefined
606
+ */
607
+ export function mapValue<K extends CborInput, V>(cbor: Cbor, key: K): V | undefined {
608
+ if (cbor.type !== MajorType.Map) {
609
+ return undefined;
610
+ }
611
+ return cbor.value.get<K, V>(key);
612
+ }
613
+
614
+ /**
615
+ * Check if map has key.
616
+ *
617
+ * @param cbor - CBOR value (must be map)
618
+ * @param key - Map key
619
+ * @returns True if key exists, false otherwise, undefined if not map
620
+ */
621
+ export function mapHas<K extends CborInput>(cbor: Cbor, key: K): boolean | undefined {
622
+ if (cbor.type !== MajorType.Map) {
623
+ return undefined;
624
+ }
625
+ return cbor.value.has(key);
626
+ }
627
+
628
+ /**
629
+ * Get all map keys.
630
+ *
631
+ * @param cbor - CBOR value (must be map)
632
+ * @returns Array of keys or undefined
633
+ */
634
+ export const mapKeys = (cbor: Cbor): Cbor[] | undefined => {
635
+ if (cbor.type !== MajorType.Map) {
636
+ return undefined;
637
+ }
638
+ return cbor.value.entriesArray.map((e) => e.key);
639
+ };
640
+
641
+ /**
642
+ * Get all map values.
643
+ *
644
+ * @param cbor - CBOR value (must be map)
645
+ * @returns Array of values or undefined
646
+ */
647
+ export const mapValues = (cbor: Cbor): Cbor[] | undefined => {
648
+ if (cbor.type !== MajorType.Map) {
649
+ return undefined;
650
+ }
651
+ return cbor.value.entriesArray.map((e) => e.value);
652
+ };
653
+
654
+ /**
655
+ * Get map size.
656
+ *
657
+ * @param cbor - CBOR value (must be map)
658
+ * @returns Map size or undefined
659
+ */
660
+ export const mapSize = (cbor: Cbor): number | undefined => {
661
+ if (cbor.type !== MajorType.Map) {
662
+ return undefined;
663
+ }
664
+ return cbor.value.size;
665
+ };
666
+
667
+ /**
668
+ * Check if map is empty.
669
+ *
670
+ * @param cbor - CBOR value (must be map)
671
+ * @returns True if empty, false if not empty, undefined if not map
672
+ */
673
+ export const mapIsEmpty = (cbor: Cbor): boolean | undefined => {
674
+ if (cbor.type !== MajorType.Map) {
675
+ return undefined;
676
+ }
677
+ return cbor.value.size === 0;
678
+ };
679
+
680
+ // ============================================================================
681
+ // Tagged Value Operations
682
+ // ============================================================================
683
+
684
+ /**
685
+ * Get tag value from tagged CBOR.
686
+ *
687
+ * @param cbor - CBOR value (must be tagged)
688
+ * @returns Tag value or undefined
689
+ */
690
+ export const tagValue = (cbor: Cbor): number | bigint | undefined => {
691
+ if (cbor.type !== MajorType.Tagged) {
692
+ return undefined;
693
+ }
694
+ return cbor.tag;
695
+ };
696
+
697
+ /**
698
+ * Get content from tagged CBOR.
699
+ *
700
+ * @param cbor - CBOR value (must be tagged)
701
+ * @returns Tagged content or undefined
702
+ */
703
+ export const tagContent = (cbor: Cbor): Cbor | undefined => {
704
+ if (cbor.type !== MajorType.Tagged) {
705
+ return undefined;
706
+ }
707
+ return cbor.value;
708
+ };
709
+
710
+ /**
711
+ * Check if CBOR has a specific tag.
712
+ *
713
+ * @param cbor - CBOR value
714
+ * @param tag - Tag value to check
715
+ * @returns True if has tag, false otherwise
716
+ */
717
+ export const hasTag = (cbor: Cbor, tag: number | bigint): boolean => {
718
+ if (cbor.type !== MajorType.Tagged) {
719
+ return false;
720
+ }
721
+ return cbor.tag === tag;
722
+ };
723
+
724
+ /**
725
+ * Extract content if has specific tag.
726
+ *
727
+ * @param cbor - CBOR value
728
+ * @param tag - Expected tag value
729
+ * @returns Tagged content or undefined
730
+ */
731
+ export const getTaggedContent = (cbor: Cbor, tag: number | bigint): Cbor | undefined => {
732
+ if (cbor.type === MajorType.Tagged && cbor.tag === tag) {
733
+ return cbor.value;
734
+ }
735
+ return undefined;
736
+ };
737
+
738
+ /**
739
+ * Extract content if has specific tag, throwing if not.
740
+ *
741
+ * @param cbor - CBOR value
742
+ * @param tag - Expected tag value
743
+ * @returns Tagged content
744
+ * @throws {CborError} With type 'WrongType' if cbor is not tagged with the expected tag
745
+ */
746
+ export const expectTaggedContent = (cbor: Cbor, tag: number | bigint): Cbor => {
747
+ const content = getTaggedContent(cbor, tag);
748
+ if (content === undefined) {
749
+ throw new CborError({ type: "WrongType" });
750
+ }
751
+ return content;
752
+ };
753
+
754
+ // ============================================================================
755
+ // Envelope Compatibility Functions
756
+ // These functions provide the API expected by the envelope package
757
+ // ============================================================================
758
+
759
+ import type { Tag } from "./tag";
760
+
761
+ /**
762
+ * Extract tagged value as tuple [Tag, Cbor] if CBOR is tagged.
763
+ * This is used by envelope for decoding.
764
+ *
765
+ * @param cbor - CBOR value
766
+ * @returns [Tag, Cbor] tuple or undefined
767
+ */
768
+ export const asTaggedValue = (cbor: Cbor): [Tag, Cbor] | undefined => {
769
+ if (cbor.type !== MajorType.Tagged) {
770
+ return undefined;
771
+ }
772
+ const tag: Tag = { value: cbor.tag, name: `tag-${cbor.tag}` };
773
+ return [tag, cbor.value];
774
+ };
775
+
776
+ /**
777
+ * Alias for asBytes - extract byte string value if type matches.
778
+ * Named asByteString for envelope compatibility.
779
+ *
780
+ * @param cbor - CBOR value
781
+ * @returns Byte string or undefined
782
+ */
783
+ export const asByteString = asBytes;
784
+
785
+ /**
786
+ * A wrapper around CBOR arrays that provides a get(index) method
787
+ * for envelope compatibility.
788
+ */
789
+ export interface CborArrayWrapper {
790
+ readonly length: number;
791
+ get(index: number): Cbor | undefined;
792
+ [Symbol.iterator](): Iterator<Cbor>;
793
+ }
794
+
795
+ /**
796
+ * Extract array value with get() method for envelope compatibility.
797
+ *
798
+ * @param cbor - CBOR value
799
+ * @returns Array wrapper with get() method or undefined
800
+ */
801
+ export const asCborArray = (cbor: Cbor): CborArrayWrapper | undefined => {
802
+ if (cbor.type !== MajorType.Array) {
803
+ return undefined;
804
+ }
805
+ const arr = cbor.value;
806
+ return {
807
+ length: arr.length,
808
+ get(index: number): Cbor | undefined {
809
+ return arr[index];
810
+ },
811
+ [Symbol.iterator](): Iterator<Cbor> {
812
+ return arr[Symbol.iterator]();
813
+ },
814
+ };
815
+ };
816
+
817
+ /**
818
+ * Alias for asMap - extract map value if type matches.
819
+ * Named asCborMap for envelope compatibility.
820
+ *
821
+ * @param cbor - CBOR value
822
+ * @returns Map or undefined
823
+ */
824
+ export const asCborMap = asMap;
825
+
826
+ /**
827
+ * Check if CBOR value is any numeric type (unsigned, negative, or float).
828
+ *
829
+ * @param cbor - CBOR value
830
+ * @returns True if value is numeric
831
+ */
832
+ export const isNumber = (cbor: Cbor): boolean => {
833
+ if (cbor.type === MajorType.Unsigned || cbor.type === MajorType.Negative) {
834
+ return true;
835
+ }
836
+ if (cbor.type === MajorType.Simple) {
837
+ return isSimpleFloat(cbor.value);
838
+ }
839
+ return false;
840
+ };