cborg 4.5.7 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/.github/dependabot.yml +4 -0
  2. package/.github/workflows/test-and-release.yml +2 -4
  3. package/CHANGELOG.md +51 -0
  4. package/README.md +213 -9
  5. package/cborg.js +4 -4
  6. package/example-extended.js +122 -0
  7. package/interface.ts +15 -3
  8. package/lib/0uint.js +2 -2
  9. package/lib/1negint.js +2 -2
  10. package/lib/2bytes.js +2 -2
  11. package/lib/3string.js +2 -2
  12. package/lib/4array.js +2 -2
  13. package/lib/5map.js +2 -2
  14. package/lib/6tag.js +2 -2
  15. package/lib/7float.js +5 -4
  16. package/lib/decode.js +94 -4
  17. package/lib/diagnostic.js +10 -3
  18. package/lib/encode.js +7 -7
  19. package/lib/extended/extended.js +250 -0
  20. package/lib/json/decode.js +2 -2
  21. package/lib/json/encode.js +3 -3
  22. package/lib/jump.js +1 -1
  23. package/lib/length.js +3 -3
  24. package/lib/taglib.js +452 -0
  25. package/package.json +23 -18
  26. package/test/common.js +2 -1
  27. package/test/node-test-bin.js +26 -9
  28. package/test/test-6tag.js +2 -1
  29. package/test/test-cbor-vectors.js +14 -6
  30. package/test/test-extended-vectors.js +293 -0
  31. package/test/test-extended.js +684 -0
  32. package/test/test-taglib.js +634 -0
  33. package/tsconfig.json +7 -11
  34. package/types/cborg.d.ts +4 -4
  35. package/types/cborg.d.ts.map +1 -1
  36. package/types/interface.d.ts +14 -3
  37. package/types/interface.d.ts.map +1 -1
  38. package/types/lib/0uint.d.ts +4 -4
  39. package/types/lib/0uint.d.ts.map +1 -1
  40. package/types/lib/1negint.d.ts +4 -4
  41. package/types/lib/1negint.d.ts.map +1 -1
  42. package/types/lib/2bytes.d.ts +2 -2
  43. package/types/lib/2bytes.d.ts.map +1 -1
  44. package/types/lib/3string.d.ts +2 -2
  45. package/types/lib/3string.d.ts.map +1 -1
  46. package/types/lib/4array.d.ts +2 -2
  47. package/types/lib/4array.d.ts.map +1 -1
  48. package/types/lib/5map.d.ts +2 -2
  49. package/types/lib/5map.d.ts.map +1 -1
  50. package/types/lib/6tag.d.ts +4 -4
  51. package/types/lib/6tag.d.ts.map +1 -1
  52. package/types/lib/7float.d.ts +6 -6
  53. package/types/lib/7float.d.ts.map +1 -1
  54. package/types/lib/byte-utils.d.ts +5 -2
  55. package/types/lib/byte-utils.d.ts.map +1 -1
  56. package/types/lib/decode.d.ts +4 -3
  57. package/types/lib/decode.d.ts.map +1 -1
  58. package/types/lib/diagnostic.d.ts.map +1 -1
  59. package/types/lib/encode.d.ts +8 -8
  60. package/types/lib/encode.d.ts.map +1 -1
  61. package/types/lib/extended/extended.d.ts +78 -0
  62. package/types/lib/extended/extended.d.ts.map +1 -0
  63. package/types/lib/json/decode.d.ts +5 -5
  64. package/types/lib/json/decode.d.ts.map +1 -1
  65. package/types/lib/json/encode.d.ts +3 -3
  66. package/types/lib/json/encode.d.ts.map +1 -1
  67. package/types/lib/jump.d.ts +1 -1
  68. package/types/lib/jump.d.ts.map +1 -1
  69. package/types/lib/length.d.ts +3 -3
  70. package/types/lib/length.d.ts.map +1 -1
  71. package/types/lib/taglib.d.ts +143 -0
  72. package/types/lib/taglib.d.ts.map +1 -0
  73. package/types/tsconfig.tsbuildinfo +1 -1
  74. package/taglib.js +0 -73
  75. package/types/taglib.d.ts +0 -18
  76. package/types/taglib.d.ts.map +0 -1
@@ -0,0 +1,634 @@
1
+ /* eslint-env mocha */
2
+
3
+ import * as chai from 'chai'
4
+ import { encode, decode } from '../cborg.js'
5
+ import {
6
+ // Tag constants
7
+ TAG_DATE_EPOCH,
8
+ TAG_BIGINT_POS,
9
+ TAG_BIGINT_NEG,
10
+ TAG_UINT8_ARRAY,
11
+ TAG_UINT8_CLAMPED_ARRAY,
12
+ TAG_INT8_ARRAY,
13
+ TAG_UINT16_ARRAY_LE,
14
+ TAG_UINT32_ARRAY_LE,
15
+ TAG_BIGUINT64_ARRAY_LE,
16
+ TAG_INT16_ARRAY_LE,
17
+ TAG_INT32_ARRAY_LE,
18
+ TAG_BIGINT64_ARRAY_LE,
19
+ TAG_FLOAT32_ARRAY_LE,
20
+ TAG_FLOAT64_ARRAY_LE,
21
+ TAG_SET,
22
+ TAG_MAP,
23
+ TAG_REGEXP,
24
+
25
+ // BigInt
26
+ bigIntEncoder,
27
+ bigIntDecoder,
28
+ bigNegIntDecoder,
29
+ structBigIntEncoder,
30
+
31
+ // Date
32
+ dateEncoder,
33
+ dateDecoder,
34
+
35
+ // RegExp
36
+ regExpEncoder,
37
+ regExpDecoder,
38
+
39
+ // Set
40
+ setEncoder,
41
+ setDecoder,
42
+
43
+ // Map
44
+ mapEncoder,
45
+ mapDecoder,
46
+
47
+ // TypedArrays
48
+ uint8ArrayEncoder,
49
+ uint8ArrayDecoder,
50
+ uint8ClampedArrayEncoder,
51
+ uint8ClampedArrayDecoder,
52
+ int8ArrayEncoder,
53
+ int8ArrayDecoder,
54
+ uint16ArrayEncoder,
55
+ uint16ArrayDecoder,
56
+ uint32ArrayEncoder,
57
+ uint32ArrayDecoder,
58
+ bigUint64ArrayEncoder,
59
+ bigUint64ArrayDecoder,
60
+ int16ArrayEncoder,
61
+ int16ArrayDecoder,
62
+ int32ArrayEncoder,
63
+ int32ArrayDecoder,
64
+ bigInt64ArrayEncoder,
65
+ bigInt64ArrayDecoder,
66
+ float32ArrayEncoder,
67
+ float32ArrayDecoder,
68
+ float64ArrayEncoder,
69
+ float64ArrayDecoder
70
+ } from '../lib/taglib.js'
71
+
72
+ const { assert } = chai
73
+
74
+ /**
75
+ * Create a mock decode control for unit testing decoders
76
+ * @param {any} value - The value that decode() should return
77
+ * @param {Array<[any, any]>} [entries] - Optional entries for decode.entries()
78
+ * @returns {import('../interface').TagDecodeControl}
79
+ */
80
+ function mockDecode (value, entries) {
81
+ const fn = () => value
82
+ fn.entries = () => entries || []
83
+ return fn
84
+ }
85
+
86
+ describe('taglib', () => {
87
+ describe('tag constants', () => {
88
+ it('has correct standard tag values', () => {
89
+ assert.strictEqual(TAG_DATE_EPOCH, 1)
90
+ assert.strictEqual(TAG_BIGINT_POS, 2)
91
+ assert.strictEqual(TAG_BIGINT_NEG, 3)
92
+ })
93
+
94
+ it('has correct TypedArray tag values', () => {
95
+ assert.strictEqual(TAG_UINT8_ARRAY, 64)
96
+ assert.strictEqual(TAG_UINT8_CLAMPED_ARRAY, 68)
97
+ assert.strictEqual(TAG_INT8_ARRAY, 72)
98
+ assert.strictEqual(TAG_UINT16_ARRAY_LE, 69)
99
+ assert.strictEqual(TAG_UINT32_ARRAY_LE, 70)
100
+ assert.strictEqual(TAG_BIGUINT64_ARRAY_LE, 71)
101
+ assert.strictEqual(TAG_INT16_ARRAY_LE, 77)
102
+ assert.strictEqual(TAG_INT32_ARRAY_LE, 78)
103
+ assert.strictEqual(TAG_BIGINT64_ARRAY_LE, 79)
104
+ assert.strictEqual(TAG_FLOAT32_ARRAY_LE, 85)
105
+ assert.strictEqual(TAG_FLOAT64_ARRAY_LE, 86)
106
+ })
107
+
108
+ it('has correct extended tag values', () => {
109
+ assert.strictEqual(TAG_SET, 258)
110
+ assert.strictEqual(TAG_MAP, 259)
111
+ assert.strictEqual(TAG_REGEXP, 21066)
112
+ })
113
+ })
114
+
115
+ describe('BigInt', () => {
116
+ describe('bigIntDecoder', () => {
117
+ it('decodes zero', () => {
118
+ assert.strictEqual(bigIntDecoder(mockDecode(new Uint8Array([0]))), 0n)
119
+ })
120
+
121
+ it('decodes small positive', () => {
122
+ assert.strictEqual(bigIntDecoder(mockDecode(new Uint8Array([100]))), 100n)
123
+ })
124
+
125
+ it('decodes large positive', () => {
126
+ // 0x0100000000000000 = 72057594037927936
127
+ assert.strictEqual(
128
+ bigIntDecoder(mockDecode(new Uint8Array([1, 0, 0, 0, 0, 0, 0, 0]))),
129
+ 72057594037927936n
130
+ )
131
+ })
132
+ })
133
+
134
+ describe('bigNegIntDecoder', () => {
135
+ it('decodes -1', () => {
136
+ assert.strictEqual(bigNegIntDecoder(mockDecode(new Uint8Array([0]))), -1n)
137
+ })
138
+
139
+ it('decodes negative', () => {
140
+ // -1 - 100 = -101
141
+ assert.strictEqual(bigNegIntDecoder(mockDecode(new Uint8Array([100]))), -101n)
142
+ })
143
+ })
144
+
145
+ describe('bigIntEncoder (IPLD compatible)', () => {
146
+ it('returns null for small values (within 64-bit range)', () => {
147
+ assert.strictEqual(bigIntEncoder(0n), null)
148
+ assert.strictEqual(bigIntEncoder(100n), null)
149
+ assert.strictEqual(bigIntEncoder(-100n), null)
150
+ assert.strictEqual(bigIntEncoder(BigInt('18446744073709551615')), null)
151
+ assert.strictEqual(bigIntEncoder(BigInt('-18446744073709551616')), null)
152
+ })
153
+
154
+ it('returns tokens for large positive values', () => {
155
+ const tokens = bigIntEncoder(BigInt('18446744073709551616'))
156
+ assert.ok(Array.isArray(tokens))
157
+ assert.strictEqual(tokens[0].value, TAG_BIGINT_POS)
158
+ })
159
+
160
+ it('returns tokens for large negative values', () => {
161
+ const tokens = bigIntEncoder(BigInt('-18446744073709551617'))
162
+ assert.ok(Array.isArray(tokens))
163
+ assert.strictEqual(tokens[0].value, TAG_BIGINT_NEG)
164
+ })
165
+ })
166
+
167
+ describe('structBigIntEncoder (always tags)', () => {
168
+ it('returns tokens for zero', () => {
169
+ const tokens = structBigIntEncoder(0n)
170
+ assert.ok(Array.isArray(tokens))
171
+ assert.strictEqual(tokens[0].value, TAG_BIGINT_POS)
172
+ })
173
+
174
+ it('returns tokens for small positive', () => {
175
+ const tokens = structBigIntEncoder(100n)
176
+ assert.ok(Array.isArray(tokens))
177
+ assert.strictEqual(tokens[0].value, TAG_BIGINT_POS)
178
+ })
179
+
180
+ it('returns tokens for small negative', () => {
181
+ const tokens = structBigIntEncoder(-1n)
182
+ assert.ok(Array.isArray(tokens))
183
+ assert.strictEqual(tokens[0].value, TAG_BIGINT_NEG)
184
+ })
185
+ })
186
+
187
+ describe('round-trip via encode/decode', () => {
188
+ const opts = {
189
+ typeEncoders: { bigint: structBigIntEncoder },
190
+ tags: { [TAG_BIGINT_POS]: bigIntDecoder, [TAG_BIGINT_NEG]: bigNegIntDecoder }
191
+ }
192
+
193
+ it('round-trips 0n', () => {
194
+ const result = decode(encode(0n, opts), opts)
195
+ assert.strictEqual(typeof result, 'bigint')
196
+ assert.strictEqual(result, 0n)
197
+ })
198
+
199
+ it('round-trips 100n', () => {
200
+ const result = decode(encode(100n, opts), opts)
201
+ assert.strictEqual(typeof result, 'bigint')
202
+ assert.strictEqual(result, 100n)
203
+ })
204
+
205
+ it('round-trips -1n', () => {
206
+ const result = decode(encode(-1n, opts), opts)
207
+ assert.strictEqual(typeof result, 'bigint')
208
+ assert.strictEqual(result, -1n)
209
+ })
210
+
211
+ it('round-trips large positive', () => {
212
+ const n = BigInt('9007199254740993')
213
+ const result = decode(encode(n, opts), opts)
214
+ assert.strictEqual(result, n)
215
+ })
216
+
217
+ it('round-trips large negative', () => {
218
+ const n = BigInt('-18446744073709551617')
219
+ const result = decode(encode(n, opts), opts)
220
+ assert.strictEqual(result, n)
221
+ })
222
+ })
223
+ })
224
+
225
+ describe('Date', () => {
226
+ describe('dateEncoder', () => {
227
+ it('returns tag 1 with float seconds', () => {
228
+ const tokens = dateEncoder(new Date(1000))
229
+ assert.strictEqual(tokens[0].value, TAG_DATE_EPOCH)
230
+ assert.strictEqual(tokens[1].value, 1) // 1000ms = 1 second
231
+ })
232
+
233
+ it('handles milliseconds', () => {
234
+ const tokens = dateEncoder(new Date(1500))
235
+ assert.strictEqual(tokens[1].value, 1.5)
236
+ })
237
+
238
+ it('handles epoch', () => {
239
+ const tokens = dateEncoder(new Date(0))
240
+ assert.strictEqual(tokens[1].value, 0)
241
+ })
242
+ })
243
+
244
+ describe('dateDecoder', () => {
245
+ it('decodes seconds to Date', () => {
246
+ const date = dateDecoder(mockDecode(1))
247
+ assert.ok(date instanceof Date)
248
+ assert.strictEqual(date.getTime(), 1000)
249
+ })
250
+
251
+ it('decodes float seconds', () => {
252
+ const date = dateDecoder(mockDecode(1.5))
253
+ assert.strictEqual(date.getTime(), 1500)
254
+ })
255
+ })
256
+
257
+ describe('round-trip via encode/decode', () => {
258
+ const opts = {
259
+ typeEncoders: { Date: dateEncoder },
260
+ tags: { [TAG_DATE_EPOCH]: dateDecoder }
261
+ }
262
+
263
+ it('round-trips a date', () => {
264
+ const d = new Date('2024-01-15T12:30:00.000Z')
265
+ const result = decode(encode(d, opts), opts)
266
+ assert.ok(result instanceof Date)
267
+ assert.strictEqual(result.getTime(), d.getTime())
268
+ })
269
+
270
+ it('round-trips date with milliseconds', () => {
271
+ const d = new Date('2024-01-15T12:30:00.123Z')
272
+ const result = decode(encode(d, opts), opts)
273
+ assert.strictEqual(result.getTime(), d.getTime())
274
+ })
275
+
276
+ it('round-trips epoch date', () => {
277
+ const d = new Date(0)
278
+ const result = decode(encode(d, opts), opts)
279
+ assert.strictEqual(result.getTime(), 0)
280
+ })
281
+ })
282
+ })
283
+
284
+ describe('RegExp', () => {
285
+ describe('regExpEncoder', () => {
286
+ it('encodes pattern without flags', () => {
287
+ const tokens = regExpEncoder(/foo/)
288
+ assert.strictEqual(tokens[0].value, TAG_REGEXP)
289
+ assert.strictEqual(tokens[1].value, 1) // array length 1
290
+ assert.strictEqual(tokens[2].value, 'foo')
291
+ })
292
+
293
+ it('encodes pattern with flags', () => {
294
+ const tokens = regExpEncoder(/foo/gi)
295
+ assert.strictEqual(tokens[0].value, TAG_REGEXP)
296
+ assert.strictEqual(tokens[1].value, 2) // array length 2
297
+ assert.strictEqual(tokens[2].value, 'foo')
298
+ assert.strictEqual(tokens[3].value, 'gi')
299
+ })
300
+ })
301
+
302
+ describe('regExpDecoder', () => {
303
+ it('decodes array with pattern only', () => {
304
+ const re = regExpDecoder(mockDecode(['foo']))
305
+ assert.ok(re instanceof RegExp)
306
+ assert.strictEqual(re.source, 'foo')
307
+ assert.strictEqual(re.flags, '')
308
+ })
309
+
310
+ it('decodes array with pattern and flags', () => {
311
+ const re = regExpDecoder(mockDecode(['foo', 'gi']))
312
+ assert.strictEqual(re.source, 'foo')
313
+ assert.strictEqual(re.flags, 'gi')
314
+ })
315
+ })
316
+
317
+ describe('round-trip via encode/decode', () => {
318
+ const opts = {
319
+ typeEncoders: { RegExp: regExpEncoder },
320
+ tags: { [TAG_REGEXP]: regExpDecoder }
321
+ }
322
+
323
+ it('round-trips pattern without flags', () => {
324
+ const re = /foo.*bar/
325
+ const result = decode(encode(re, opts), opts)
326
+ assert.ok(result instanceof RegExp)
327
+ assert.strictEqual(result.source, re.source)
328
+ assert.strictEqual(result.flags, re.flags)
329
+ })
330
+
331
+ it('round-trips pattern with flags', () => {
332
+ const re = /foo.*bar/gim
333
+ const result = decode(encode(re, opts), opts)
334
+ assert.strictEqual(result.source, re.source)
335
+ assert.strictEqual(result.flags, re.flags)
336
+ })
337
+
338
+ it('round-trips empty pattern', () => {
339
+ const re = /(?:)/
340
+ const result = decode(encode(re, opts), opts)
341
+ assert.strictEqual(result.source, '(?:)')
342
+ })
343
+ })
344
+ })
345
+
346
+ describe('Set', () => {
347
+ describe('setEncoder', () => {
348
+ it('encodes empty set', () => {
349
+ const tokens = setEncoder(new Set(), 'Set', {})
350
+ assert.strictEqual(tokens[0].value, TAG_SET)
351
+ assert.strictEqual(tokens[1].value, 0) // array length 0
352
+ })
353
+ })
354
+
355
+ describe('setDecoder', () => {
356
+ it('decodes array to Set', () => {
357
+ const s = setDecoder(mockDecode([1, 2, 3]))
358
+ assert.ok(s instanceof Set)
359
+ assert.strictEqual(s.size, 3)
360
+ assert.ok(s.has(1))
361
+ assert.ok(s.has(2))
362
+ assert.ok(s.has(3))
363
+ })
364
+ })
365
+
366
+ describe('round-trip via encode/decode', () => {
367
+ const opts = {
368
+ typeEncoders: { Set: setEncoder },
369
+ tags: { [TAG_SET]: setDecoder }
370
+ }
371
+
372
+ it('round-trips empty set', () => {
373
+ const s = new Set()
374
+ const result = decode(encode(s, opts), opts)
375
+ assert.ok(result instanceof Set)
376
+ assert.strictEqual(result.size, 0)
377
+ })
378
+
379
+ it('round-trips set with primitives', () => {
380
+ const s = new Set([1, 2, 3, 'a', 'b'])
381
+ const result = decode(encode(s, opts), opts)
382
+ assert.ok(result instanceof Set)
383
+ assert.strictEqual(result.size, 5)
384
+ assert.ok(result.has(1))
385
+ assert.ok(result.has('a'))
386
+ })
387
+
388
+ it('round-trips set with nested objects', () => {
389
+ const s = new Set([{ x: 1 }, { y: 2 }])
390
+ const result = decode(encode(s, opts), opts)
391
+ assert.strictEqual(result.size, 2)
392
+ const arr = [...result]
393
+ assert.deepStrictEqual(arr[0], { x: 1 })
394
+ assert.deepStrictEqual(arr[1], { y: 2 })
395
+ })
396
+ })
397
+ })
398
+
399
+ describe('Map (Tag 259)', () => {
400
+ describe('mapEncoder', () => {
401
+ it('encodes empty map', () => {
402
+ const tokens = mapEncoder(new Map(), 'Map', {})
403
+ assert.strictEqual(tokens[0].value, TAG_MAP)
404
+ assert.strictEqual(tokens[1].value, 0) // map length 0
405
+ })
406
+ })
407
+
408
+ describe('mapDecoder', () => {
409
+ it('decodes entries as Map', () => {
410
+ const result = mapDecoder(mockDecode(null, [['a', 1]]))
411
+ assert.ok(result instanceof Map)
412
+ assert.strictEqual(result.get('a'), 1)
413
+ })
414
+
415
+ it('decodes multiple entries as Map', () => {
416
+ const result = mapDecoder(mockDecode(null, [['a', 1], ['b', 2]]))
417
+ assert.ok(result instanceof Map)
418
+ assert.strictEqual(result.get('a'), 1)
419
+ assert.strictEqual(result.get('b'), 2)
420
+ })
421
+
422
+ it('preserves non-string keys', () => {
423
+ const result = mapDecoder(mockDecode(null, [[1, 'one'], [2, 'two']]))
424
+ assert.ok(result instanceof Map)
425
+ assert.strictEqual(result.get(1), 'one')
426
+ assert.strictEqual(result.get(2), 'two')
427
+ })
428
+ })
429
+
430
+ describe('round-trip via encode/decode', () => {
431
+ const opts = {
432
+ typeEncoders: { Map: mapEncoder },
433
+ tags: { [TAG_MAP]: mapDecoder }
434
+ // useMaps not needed - mapDecoder uses decode.entries() to preserve key types
435
+ }
436
+
437
+ it('round-trips empty map', () => {
438
+ const m = new Map()
439
+ const result = decode(encode(m, opts), opts)
440
+ assert.ok(result instanceof Map)
441
+ assert.strictEqual(result.size, 0)
442
+ })
443
+
444
+ it('round-trips map with string keys', () => {
445
+ const m = new Map([['a', 1], ['b', 2]])
446
+ const result = decode(encode(m, opts), opts)
447
+ assert.ok(result instanceof Map)
448
+ assert.strictEqual(result.get('a'), 1)
449
+ assert.strictEqual(result.get('b'), 2)
450
+ })
451
+
452
+ it('round-trips map with number keys', () => {
453
+ const m = new Map([[1, 'one'], [2, 'two']])
454
+ const result = decode(encode(m, opts), opts)
455
+ assert.ok(result instanceof Map)
456
+ assert.strictEqual(result.get(1), 'one')
457
+ assert.strictEqual(result.get(2), 'two')
458
+ })
459
+ })
460
+ })
461
+
462
+ describe('TypedArrays', () => {
463
+ describe('Uint8Array', () => {
464
+ const opts = {
465
+ typeEncoders: { Uint8Array: uint8ArrayEncoder },
466
+ tags: { [TAG_UINT8_ARRAY]: uint8ArrayDecoder }
467
+ }
468
+
469
+ it('encodes with tag 64', () => {
470
+ const tokens = uint8ArrayEncoder(new Uint8Array([1, 2, 3]))
471
+ assert.strictEqual(tokens[0].value, TAG_UINT8_ARRAY)
472
+ })
473
+
474
+ it('round-trips', () => {
475
+ const arr = new Uint8Array([1, 2, 3, 4, 5])
476
+ const result = decode(encode(arr, opts), opts)
477
+ assert.ok(result instanceof Uint8Array)
478
+ assert.deepStrictEqual([...result], [1, 2, 3, 4, 5])
479
+ })
480
+
481
+ it('round-trips view of larger buffer', () => {
482
+ const buffer = new ArrayBuffer(100)
483
+ const view = new Uint8Array(buffer, 10, 5)
484
+ view.set([1, 2, 3, 4, 5])
485
+ const result = decode(encode(view, opts), opts)
486
+ assert.strictEqual(result.length, 5)
487
+ assert.deepStrictEqual([...result], [1, 2, 3, 4, 5])
488
+ })
489
+ })
490
+
491
+ describe('Uint8ClampedArray', () => {
492
+ const opts = {
493
+ typeEncoders: { Uint8ClampedArray: uint8ClampedArrayEncoder },
494
+ tags: { [TAG_UINT8_CLAMPED_ARRAY]: uint8ClampedArrayDecoder }
495
+ }
496
+
497
+ it('round-trips', () => {
498
+ const arr = new Uint8ClampedArray([0, 128, 255])
499
+ const result = decode(encode(arr, opts), opts)
500
+ assert.ok(result instanceof Uint8ClampedArray)
501
+ assert.deepStrictEqual([...result], [0, 128, 255])
502
+ })
503
+ })
504
+
505
+ describe('Int8Array', () => {
506
+ const opts = {
507
+ typeEncoders: { Int8Array: int8ArrayEncoder },
508
+ tags: { [TAG_INT8_ARRAY]: int8ArrayDecoder }
509
+ }
510
+
511
+ it('round-trips', () => {
512
+ const arr = new Int8Array([-128, 0, 127])
513
+ const result = decode(encode(arr, opts), opts)
514
+ assert.ok(result instanceof Int8Array)
515
+ assert.deepStrictEqual([...result], [-128, 0, 127])
516
+ })
517
+ })
518
+
519
+ describe('Uint16Array', () => {
520
+ const opts = {
521
+ typeEncoders: { Uint16Array: uint16ArrayEncoder },
522
+ tags: { [TAG_UINT16_ARRAY_LE]: uint16ArrayDecoder }
523
+ }
524
+
525
+ it('round-trips', () => {
526
+ const arr = new Uint16Array([0, 256, 65535])
527
+ const result = decode(encode(arr, opts), opts)
528
+ assert.ok(result instanceof Uint16Array)
529
+ assert.deepStrictEqual([...result], [0, 256, 65535])
530
+ })
531
+ })
532
+
533
+ describe('Uint32Array', () => {
534
+ const opts = {
535
+ typeEncoders: { Uint32Array: uint32ArrayEncoder },
536
+ tags: { [TAG_UINT32_ARRAY_LE]: uint32ArrayDecoder }
537
+ }
538
+
539
+ it('round-trips', () => {
540
+ const arr = new Uint32Array([0, 65536, 4294967295])
541
+ const result = decode(encode(arr, opts), opts)
542
+ assert.ok(result instanceof Uint32Array)
543
+ assert.deepStrictEqual([...result], [0, 65536, 4294967295])
544
+ })
545
+ })
546
+
547
+ describe('Int16Array', () => {
548
+ const opts = {
549
+ typeEncoders: { Int16Array: int16ArrayEncoder },
550
+ tags: { [TAG_INT16_ARRAY_LE]: int16ArrayDecoder }
551
+ }
552
+
553
+ it('round-trips', () => {
554
+ const arr = new Int16Array([-32768, 0, 32767])
555
+ const result = decode(encode(arr, opts), opts)
556
+ assert.ok(result instanceof Int16Array)
557
+ assert.deepStrictEqual([...result], [-32768, 0, 32767])
558
+ })
559
+ })
560
+
561
+ describe('Int32Array', () => {
562
+ const opts = {
563
+ typeEncoders: { Int32Array: int32ArrayEncoder },
564
+ tags: { [TAG_INT32_ARRAY_LE]: int32ArrayDecoder }
565
+ }
566
+
567
+ it('round-trips', () => {
568
+ const arr = new Int32Array([-2147483648, 0, 2147483647])
569
+ const result = decode(encode(arr, opts), opts)
570
+ assert.ok(result instanceof Int32Array)
571
+ assert.deepStrictEqual([...result], [-2147483648, 0, 2147483647])
572
+ })
573
+ })
574
+
575
+ describe('Float32Array', () => {
576
+ const opts = {
577
+ typeEncoders: { Float32Array: float32ArrayEncoder },
578
+ tags: { [TAG_FLOAT32_ARRAY_LE]: float32ArrayDecoder }
579
+ }
580
+
581
+ it('round-trips', () => {
582
+ const arr = new Float32Array([1.5, -2.5, 3.14])
583
+ const result = decode(encode(arr, opts), opts)
584
+ assert.ok(result instanceof Float32Array)
585
+ // Float32 has limited precision
586
+ assert.strictEqual(result[0], 1.5)
587
+ assert.strictEqual(result[1], -2.5)
588
+ assert.ok(Math.abs(result[2] - 3.14) < 0.001)
589
+ })
590
+ })
591
+
592
+ describe('Float64Array', () => {
593
+ const opts = {
594
+ typeEncoders: { Float64Array: float64ArrayEncoder },
595
+ tags: { [TAG_FLOAT64_ARRAY_LE]: float64ArrayDecoder }
596
+ }
597
+
598
+ it('round-trips', () => {
599
+ const arr = new Float64Array([1.1, -2.2, Math.PI, Infinity, -Infinity])
600
+ const result = decode(encode(arr, opts), opts)
601
+ assert.ok(result instanceof Float64Array)
602
+ assert.deepStrictEqual([...result], [1.1, -2.2, Math.PI, Infinity, -Infinity])
603
+ })
604
+ })
605
+
606
+ describe('BigUint64Array', () => {
607
+ const opts = {
608
+ typeEncoders: { BigUint64Array: bigUint64ArrayEncoder },
609
+ tags: { [TAG_BIGUINT64_ARRAY_LE]: bigUint64ArrayDecoder }
610
+ }
611
+
612
+ it('round-trips', () => {
613
+ const arr = new BigUint64Array([0n, 1n, BigInt('18446744073709551615')])
614
+ const result = decode(encode(arr, opts), opts)
615
+ assert.ok(result instanceof BigUint64Array)
616
+ assert.deepStrictEqual([...result], [0n, 1n, BigInt('18446744073709551615')])
617
+ })
618
+ })
619
+
620
+ describe('BigInt64Array', () => {
621
+ const opts = {
622
+ typeEncoders: { BigInt64Array: bigInt64ArrayEncoder },
623
+ tags: { [TAG_BIGINT64_ARRAY_LE]: bigInt64ArrayDecoder }
624
+ }
625
+
626
+ it('round-trips', () => {
627
+ const arr = new BigInt64Array([BigInt('-9223372036854775808'), 0n, BigInt('9223372036854775807')])
628
+ const result = decode(encode(arr, opts), opts)
629
+ assert.ok(result instanceof BigInt64Array)
630
+ assert.deepStrictEqual([...result], [BigInt('-9223372036854775808'), 0n, BigInt('9223372036854775807')])
631
+ })
632
+ })
633
+ })
634
+ })
package/tsconfig.json CHANGED
@@ -16,30 +16,26 @@
16
16
  "strict": true,
17
17
  "alwaysStrict": true,
18
18
  "esModuleInterop": true,
19
- "target": "ES2018",
20
- "moduleResolution": "node",
19
+ "target": "ES2020",
20
+ "module": "nodenext",
21
+ "moduleResolution": "nodenext",
21
22
  "declaration": true,
22
23
  "declarationMap": true,
23
24
  "outDir": "types",
24
25
  "skipLibCheck": true,
25
26
  "stripInternal": true,
26
27
  "resolveJsonModule": true,
27
- "baseUrl": ".",
28
- "emitDeclarationOnly": true,
29
- "paths": {
30
- "cborg": [
31
- "cborg.js"
32
- ]
33
- }
28
+ "emitDeclarationOnly": true
34
29
  },
35
30
  "include": [
36
31
  "cborg.js",
37
- "example.js",
38
32
  "taglib.js",
33
+ "interface.ts",
39
34
  "lib/"
40
35
  ],
41
36
  "exclude": [
42
- "node_modules"
37
+ "node_modules",
38
+ "lib/bin.js"
43
39
  ],
44
40
  "compileOnSave": false
45
41
  }
package/types/cborg.d.ts CHANGED
@@ -1,19 +1,19 @@
1
1
  /**
2
2
  * There was originally just `TypeEncoder` so don't break types by renaming or not exporting
3
3
  */
4
- export type TagDecoder = import("./interface").TagDecoder;
4
+ export type TagDecoder = import("./interface.js").TagDecoder;
5
5
  /**
6
6
  * Export the types that were present in the original manual cborg.d.ts
7
7
  */
8
- export type TypeEncoder = import("./interface").OptionalTypeEncoder;
8
+ export type TypeEncoder = import("./interface.js").OptionalTypeEncoder;
9
9
  /**
10
10
  * Export the types that were present in the original manual cborg.d.ts
11
11
  */
12
- export type DecodeOptions = import("./interface").DecodeOptions;
12
+ export type DecodeOptions = import("./interface.js").DecodeOptions;
13
13
  /**
14
14
  * Export the types that were present in the original manual cborg.d.ts
15
15
  */
16
- export type EncodeOptions = import("./interface").EncodeOptions;
16
+ export type EncodeOptions = import("./interface.js").EncodeOptions;
17
17
  import { decode } from './lib/decode.js';
18
18
  import { decodeFirst } from './lib/decode.js';
19
19
  import { Tokeniser } from './lib/decode.js';
@@ -1 +1 @@
1
- {"version":3,"file":"cborg.d.ts","sourceRoot":"","sources":["../cborg.js"],"names":[],"mappings":";;;yBAMa,OAAO,aAAa,EAAE,UAAU;;;;0BAEhC,OAAO,aAAa,EAAE,mBAAmB;;;;4BACzC,OAAO,aAAa,EAAE,aAAa;;;;4BACnC,OAAO,aAAa,EAAE,aAAa;uBATe,iBAAiB;4BAAjB,iBAAiB;0BAAjB,iBAAiB;+BAAjB,iBAAiB;uBADvB,iBAAiB;2BAAjB,iBAAiB;qCAAjB,iBAAiB;sBAE9C,gBAAgB;qBAAhB,gBAAgB"}
1
+ {"version":3,"file":"cborg.d.ts","sourceRoot":"","sources":["../cborg.js"],"names":[],"mappings":";;;yBAMa,OAAO,gBAAgB,EAAE,UAAU;;;;0BAEnC,OAAO,gBAAgB,EAAE,mBAAmB;;;;4BAC5C,OAAO,gBAAgB,EAAE,aAAa;;;;4BACtC,OAAO,gBAAgB,EAAE,aAAa;uBATY,iBAAiB;4BAAjB,iBAAiB;0BAAjB,iBAAiB;+BAAjB,iBAAiB;uBADvB,iBAAiB;2BAAjB,iBAAiB;qCAAjB,iBAAiB;sBAE9C,gBAAgB;qBAAhB,gBAAgB"}