cborg 4.5.8 → 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 (73) hide show
  1. package/.github/dependabot.yml +4 -0
  2. package/.github/workflows/test-and-release.yml +2 -4
  3. package/CHANGELOG.md +44 -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/encode.js +7 -7
  18. package/lib/extended/extended.js +250 -0
  19. package/lib/json/decode.js +2 -2
  20. package/lib/json/encode.js +3 -3
  21. package/lib/jump.js +1 -1
  22. package/lib/length.js +3 -3
  23. package/lib/taglib.js +452 -0
  24. package/package.json +21 -17
  25. package/test/common.js +2 -1
  26. package/test/test-6tag.js +2 -1
  27. package/test/test-cbor-vectors.js +14 -6
  28. package/test/test-extended-vectors.js +293 -0
  29. package/test/test-extended.js +684 -0
  30. package/test/test-taglib.js +634 -0
  31. package/tsconfig.json +7 -11
  32. package/types/cborg.d.ts +4 -4
  33. package/types/cborg.d.ts.map +1 -1
  34. package/types/interface.d.ts +14 -3
  35. package/types/interface.d.ts.map +1 -1
  36. package/types/lib/0uint.d.ts +4 -4
  37. package/types/lib/0uint.d.ts.map +1 -1
  38. package/types/lib/1negint.d.ts +4 -4
  39. package/types/lib/1negint.d.ts.map +1 -1
  40. package/types/lib/2bytes.d.ts +2 -2
  41. package/types/lib/2bytes.d.ts.map +1 -1
  42. package/types/lib/3string.d.ts +2 -2
  43. package/types/lib/3string.d.ts.map +1 -1
  44. package/types/lib/4array.d.ts +2 -2
  45. package/types/lib/4array.d.ts.map +1 -1
  46. package/types/lib/5map.d.ts +2 -2
  47. package/types/lib/5map.d.ts.map +1 -1
  48. package/types/lib/6tag.d.ts +4 -4
  49. package/types/lib/6tag.d.ts.map +1 -1
  50. package/types/lib/7float.d.ts +6 -6
  51. package/types/lib/7float.d.ts.map +1 -1
  52. package/types/lib/byte-utils.d.ts +5 -2
  53. package/types/lib/byte-utils.d.ts.map +1 -1
  54. package/types/lib/decode.d.ts +4 -3
  55. package/types/lib/decode.d.ts.map +1 -1
  56. package/types/lib/encode.d.ts +8 -8
  57. package/types/lib/encode.d.ts.map +1 -1
  58. package/types/lib/extended/extended.d.ts +78 -0
  59. package/types/lib/extended/extended.d.ts.map +1 -0
  60. package/types/lib/json/decode.d.ts +5 -5
  61. package/types/lib/json/decode.d.ts.map +1 -1
  62. package/types/lib/json/encode.d.ts +3 -3
  63. package/types/lib/json/encode.d.ts.map +1 -1
  64. package/types/lib/jump.d.ts +1 -1
  65. package/types/lib/jump.d.ts.map +1 -1
  66. package/types/lib/length.d.ts +3 -3
  67. package/types/lib/length.d.ts.map +1 -1
  68. package/types/lib/taglib.d.ts +143 -0
  69. package/types/lib/taglib.d.ts.map +1 -0
  70. package/types/tsconfig.tsbuildinfo +1 -1
  71. package/taglib.js +0 -73
  72. package/types/taglib.d.ts +0 -18
  73. package/types/taglib.d.ts.map +0 -1
package/lib/taglib.js ADDED
@@ -0,0 +1,452 @@
1
+ import { Token, Type } from '../cborg.js'
2
+ import { objectToTokens, Ref } from './encode.js'
3
+
4
+ /*
5
+ A collection of standard CBOR tags for extended JavaScript type support.
6
+
7
+ There are no tags included by default in the cborg encoder or decoder, you have
8
+ to include them by passing options. `typeEncoders` for encode() and `tags` for
9
+ decode().
10
+
11
+ The encoders here can be included with these options (see the tests for how this
12
+ can be done), or as examples for writing additional tags.
13
+
14
+ For convenience, cborg/extended provides a pre-configured encode/decode that
15
+ includes all of these, with type support similar to the browser's structured
16
+ clone algorithm.
17
+ */
18
+
19
+ // =============================================================================
20
+ // Tag Constants
21
+ // =============================================================================
22
+
23
+ // Standard Tags (RFC 8949)
24
+ export const TAG_DATE_STRING = 0 // RFC 3339 date/time string
25
+ export const TAG_DATE_EPOCH = 1 // Epoch-based date/time (integer or float)
26
+ export const TAG_BIGINT_POS = 2 // Unsigned bignum
27
+ export const TAG_BIGINT_NEG = 3 // Negative bignum
28
+
29
+ // TypedArray Tags (RFC 8746) - Single-byte arrays (no endianness)
30
+ export const TAG_UINT8_ARRAY = 64
31
+ export const TAG_UINT8_CLAMPED_ARRAY = 68
32
+ export const TAG_INT8_ARRAY = 72
33
+
34
+ // TypedArray Tags (RFC 8746) - Little-endian multi-byte arrays
35
+ export const TAG_UINT16_ARRAY_LE = 69
36
+ export const TAG_UINT32_ARRAY_LE = 70
37
+ export const TAG_BIGUINT64_ARRAY_LE = 71
38
+ export const TAG_INT16_ARRAY_LE = 77
39
+ export const TAG_INT32_ARRAY_LE = 78
40
+ export const TAG_BIGINT64_ARRAY_LE = 79
41
+ export const TAG_FLOAT32_ARRAY_LE = 85
42
+ export const TAG_FLOAT64_ARRAY_LE = 86
43
+
44
+ // Generic Object Tag (IANA Registry)
45
+ export const TAG_OBJECT_CLASS = 27 // Serialised object with class name and constructor arguments
46
+
47
+ // Extended Tags (IANA Registry)
48
+ export const TAG_SET = 258 // Mathematical finite set
49
+ export const TAG_MAP = 259 // Map datatype
50
+ export const TAG_REGEXP = 21066 // ECMAScript RegExp
51
+
52
+ // =============================================================================
53
+ // BigInt (Tags 2/3) - RFC 8949 Section 3.4.3
54
+ // =============================================================================
55
+
56
+ const neg1b = BigInt(-1)
57
+ const pos1b = BigInt(1)
58
+ const zerob = BigInt(0)
59
+ const eightb = BigInt(8)
60
+
61
+ /**
62
+ * Decode a positive bignum from bytes (Tag 2)
63
+ * @param {import('../interface.js').TagDecodeControl} decode
64
+ * @returns {bigint}
65
+ */
66
+ export function bigIntDecoder (decode) {
67
+ const bytes = /** @type {Uint8Array} */ (decode())
68
+ let bi = zerob
69
+ for (let ii = 0; ii < bytes.length; ii++) {
70
+ bi = (bi << eightb) + BigInt(bytes[ii])
71
+ }
72
+ return bi
73
+ }
74
+
75
+ /**
76
+ * Convert a BigInt to bytes
77
+ * @param {bigint} bi
78
+ * @returns {Uint8Array}
79
+ */
80
+ const ffb = BigInt(0xff)
81
+ /**
82
+ * @param {bigint} bi
83
+ */
84
+ function fromBigInt (bi) {
85
+ const buf = []
86
+ while (bi > 0) {
87
+ // Use BigInt operations to avoid Number precision loss
88
+ buf.unshift(Number(bi & ffb))
89
+ bi >>= eightb
90
+ }
91
+ return Uint8Array.from(buf.length ? buf : [0])
92
+ }
93
+
94
+ // For IPLD compatibility: only tag BigInts outside 64-bit range
95
+ const maxSafeBigInt = BigInt('18446744073709551615') // 2^64 - 1
96
+ const minSafeBigInt = BigInt('-18446744073709551616') // -2^64
97
+
98
+ /**
99
+ * Encode a BigInt, only using tags for values outside 64-bit range (IPLD compatible)
100
+ * @param {bigint} obj
101
+ * @returns {Token[]|null}
102
+ */
103
+ export function bigIntEncoder (obj) {
104
+ if (obj >= minSafeBigInt && obj <= maxSafeBigInt) {
105
+ return null // null = encode as native CBOR integer
106
+ }
107
+ return [
108
+ new Token(Type.tag, obj >= zerob ? TAG_BIGINT_POS : TAG_BIGINT_NEG),
109
+ new Token(Type.bytes, fromBigInt(obj >= zerob ? obj : obj * neg1b - pos1b))
110
+ ]
111
+ }
112
+
113
+ /**
114
+ * Encode a BigInt, always using tags 2/3 (for extended mode, full round-trip fidelity)
115
+ * @param {bigint} obj
116
+ * @returns {Token[]}
117
+ */
118
+ export function structBigIntEncoder (obj) {
119
+ return [
120
+ new Token(Type.tag, obj >= zerob ? TAG_BIGINT_POS : TAG_BIGINT_NEG),
121
+ new Token(Type.bytes, fromBigInt(obj >= zerob ? obj : obj * neg1b - pos1b))
122
+ ]
123
+ }
124
+
125
+ /**
126
+ * Decode a negative bignum from bytes (Tag 3)
127
+ * @param {import('../interface.js').TagDecodeControl} decode
128
+ * @returns {bigint}
129
+ */
130
+ export function bigNegIntDecoder (decode) {
131
+ const bytes = /** @type {Uint8Array} */ (decode())
132
+ let bi = zerob
133
+ for (let ii = 0; ii < bytes.length; ii++) {
134
+ bi = (bi << eightb) + BigInt(bytes[ii])
135
+ }
136
+ return neg1b - bi
137
+ }
138
+
139
+ // =============================================================================
140
+ // Date (Tag 1) - RFC 8949 Section 3.4.2
141
+ // =============================================================================
142
+
143
+ /**
144
+ * Encode a Date as Tag 1 (epoch seconds as float)
145
+ * @param {Date} date
146
+ * @returns {Token[]}
147
+ */
148
+ export function dateEncoder (date) {
149
+ // Use float for millisecond precision
150
+ const seconds = date.getTime() / 1000
151
+ return [
152
+ new Token(Type.tag, TAG_DATE_EPOCH),
153
+ new Token(Type.float, seconds)
154
+ ]
155
+ }
156
+
157
+ /**
158
+ * Decode Tag 1 (epoch seconds) to a Date
159
+ * @param {import('../interface.js').TagDecodeControl} decode
160
+ * @returns {Date}
161
+ */
162
+ export function dateDecoder (decode) {
163
+ const seconds = /** @type {number} */ (decode())
164
+ return new Date(seconds * 1000)
165
+ }
166
+
167
+ // =============================================================================
168
+ // RegExp (Tag 21066) - IANA Registry
169
+ // =============================================================================
170
+
171
+ /**
172
+ * Encode a RegExp as Tag 21066
173
+ * @param {RegExp} re
174
+ * @returns {Token[]}
175
+ */
176
+ export function regExpEncoder (re) {
177
+ if (re.flags) {
178
+ return [
179
+ new Token(Type.tag, TAG_REGEXP),
180
+ new Token(Type.array, 2),
181
+ new Token(Type.string, re.source),
182
+ new Token(Type.string, re.flags)
183
+ ]
184
+ }
185
+ return [
186
+ new Token(Type.tag, TAG_REGEXP),
187
+ new Token(Type.array, 1),
188
+ new Token(Type.string, re.source)
189
+ ]
190
+ }
191
+
192
+ /**
193
+ * Decode Tag 21066 to a RegExp
194
+ * @param {import('../interface.js').TagDecodeControl} decode
195
+ * @returns {RegExp}
196
+ */
197
+ export function regExpDecoder (decode) {
198
+ const val = /** @type {string[]|string} */ (decode())
199
+ if (Array.isArray(val)) {
200
+ return new RegExp(val[0], val[1] || '')
201
+ }
202
+ return new RegExp(val)
203
+ }
204
+
205
+ // =============================================================================
206
+ // Set (Tag 258) - IANA Registry
207
+ // =============================================================================
208
+
209
+ /**
210
+ * Encode a Set as Tag 258 + array
211
+ * This is a typeEncoder, receives (obj, typ, options, refStack)
212
+ * @param {Set<any>} set
213
+ * @param {string} _typ
214
+ * @param {import('../interface.js').EncodeOptions} options
215
+ * @param {import('../interface.js').Reference} [refStack]
216
+ * @returns {import('../interface.js').TokenOrNestedTokens[]}
217
+ */
218
+ export function setEncoder (set, _typ, options, refStack) {
219
+ if (set.size === 0) {
220
+ return [
221
+ new Token(Type.tag, TAG_SET),
222
+ new Token(Type.array, 0)
223
+ ]
224
+ }
225
+
226
+ refStack = Ref.createCheck(refStack, set)
227
+ const values = []
228
+ for (const v of set) {
229
+ values.push(objectToTokens(v, options, refStack))
230
+ }
231
+
232
+ return [
233
+ new Token(Type.tag, TAG_SET),
234
+ new Token(Type.array, set.size),
235
+ values
236
+ ]
237
+ }
238
+
239
+ /**
240
+ * Decode Tag 258 to a Set
241
+ * @param {import('../interface.js').TagDecodeControl} decode
242
+ * @returns {Set<any>}
243
+ */
244
+ export function setDecoder (decode) {
245
+ const val = /** @type {any[]} */ (decode())
246
+ return new Set(val)
247
+ }
248
+
249
+ // =============================================================================
250
+ // Map (Tag 259) - IANA Registry
251
+ // Tag 259 wraps a CBOR map to indicate it should decode as a JS Map
252
+ // =============================================================================
253
+
254
+ /**
255
+ * Encode a Map as Tag 259 + CBOR map
256
+ * This is a typeEncoder, receives (obj, typ, options, refStack)
257
+ * @param {Map<any, any>} map
258
+ * @param {string} _typ
259
+ * @param {import('../interface.js').EncodeOptions} options
260
+ * @param {import('../interface.js').Reference} [refStack]
261
+ * @returns {import('../interface.js').TokenOrNestedTokens[]}
262
+ */
263
+ export function mapEncoder (map, _typ, options, refStack) {
264
+ if (map.size === 0) {
265
+ return [
266
+ new Token(Type.tag, TAG_MAP),
267
+ new Token(Type.map, 0)
268
+ ]
269
+ }
270
+
271
+ refStack = Ref.createCheck(refStack, map)
272
+ const entries = []
273
+ for (const [key, value] of map) {
274
+ entries.push([
275
+ objectToTokens(key, options, refStack),
276
+ objectToTokens(value, options, refStack)
277
+ ])
278
+ }
279
+
280
+ // Sort entries if mapSorter is provided (for deterministic encoding)
281
+ if (options.mapSorter) {
282
+ entries.sort(options.mapSorter)
283
+ }
284
+
285
+ return [
286
+ new Token(Type.tag, TAG_MAP),
287
+ new Token(Type.map, map.size),
288
+ entries
289
+ ]
290
+ }
291
+
292
+ /**
293
+ * Decode Tag 259 to a Map
294
+ * Uses decode.entries() to preserve key types (integers, etc.) regardless of useMaps setting
295
+ * @param {import('../interface.js').TagDecodeControl} decode
296
+ * @returns {Map<any, any>}
297
+ */
298
+ export function mapDecoder (decode) {
299
+ return new Map(decode.entries())
300
+ }
301
+
302
+ // =============================================================================
303
+ // TypedArrays (Tags 64-87) - RFC 8746
304
+ // Uses little-endian tags for multi-byte arrays (JS native byte order)
305
+ // =============================================================================
306
+
307
+ /**
308
+ * Helper to create a TypedArray from an ArrayBuffer
309
+ * @template {ArrayBufferView} T
310
+ * @param {new (buffer: ArrayBuffer) => T} TypedArrayClass
311
+ * @returns {(decode: import('../interface.js').TagDecodeControl) => T}
312
+ */
313
+ function createTypedArrayDecoder (TypedArrayClass) {
314
+ return function (decode) {
315
+ const bytes = /** @type {Uint8Array} */ (decode())
316
+ // bytes is a Uint8Array, need to get properly sliced ArrayBuffer
317
+ const buffer = /** @type {ArrayBuffer} */ (bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength))
318
+ return new TypedArrayClass(buffer)
319
+ }
320
+ }
321
+
322
+ /**
323
+ * Helper to create a TypedArray encoder
324
+ * @param {number} tag
325
+ * @returns {(arr: ArrayBufferView) => Token[]}
326
+ */
327
+ function createTypedArrayEncoder (tag) {
328
+ return function (arr) {
329
+ // Get the bytes from the TypedArray's underlying buffer
330
+ const bytes = new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength)
331
+ return [
332
+ new Token(Type.tag, tag),
333
+ new Token(Type.bytes, bytes)
334
+ ]
335
+ }
336
+ }
337
+
338
+ // Uint8Array (Tag 64), no endianness concerns
339
+ export const uint8ArrayEncoder = createTypedArrayEncoder(TAG_UINT8_ARRAY)
340
+ export const uint8ArrayDecoder = createTypedArrayDecoder(Uint8Array)
341
+
342
+ // Uint8ClampedArray (Tag 68), no endianness concerns
343
+ export const uint8ClampedArrayEncoder = createTypedArrayEncoder(TAG_UINT8_CLAMPED_ARRAY)
344
+ export const uint8ClampedArrayDecoder = createTypedArrayDecoder(Uint8ClampedArray)
345
+
346
+ // Int8Array (Tag 72), no endianness concerns
347
+ export const int8ArrayEncoder = createTypedArrayEncoder(TAG_INT8_ARRAY)
348
+ export const int8ArrayDecoder = createTypedArrayDecoder(Int8Array)
349
+
350
+ // Uint16Array (Tag 69, little endian)
351
+ export const uint16ArrayEncoder = createTypedArrayEncoder(TAG_UINT16_ARRAY_LE)
352
+ export const uint16ArrayDecoder = createTypedArrayDecoder(Uint16Array)
353
+
354
+ // Uint32Array (Tag 70, little endian)
355
+ export const uint32ArrayEncoder = createTypedArrayEncoder(TAG_UINT32_ARRAY_LE)
356
+ export const uint32ArrayDecoder = createTypedArrayDecoder(Uint32Array)
357
+
358
+ // BigUint64Array (Tag 71, little endian)
359
+ export const bigUint64ArrayEncoder = createTypedArrayEncoder(TAG_BIGUINT64_ARRAY_LE)
360
+ export const bigUint64ArrayDecoder = createTypedArrayDecoder(BigUint64Array)
361
+
362
+ // Int16Array (Tag 77, little endian)
363
+ export const int16ArrayEncoder = createTypedArrayEncoder(TAG_INT16_ARRAY_LE)
364
+ export const int16ArrayDecoder = createTypedArrayDecoder(Int16Array)
365
+
366
+ // Int32Array (Tag 78, little endian)
367
+ export const int32ArrayEncoder = createTypedArrayEncoder(TAG_INT32_ARRAY_LE)
368
+ export const int32ArrayDecoder = createTypedArrayDecoder(Int32Array)
369
+
370
+ // BigInt64Array (Tag 79, little endian)
371
+ export const bigInt64ArrayEncoder = createTypedArrayEncoder(TAG_BIGINT64_ARRAY_LE)
372
+ export const bigInt64ArrayDecoder = createTypedArrayDecoder(BigInt64Array)
373
+
374
+ // Float32Array (Tag 85, little endian)
375
+ export const float32ArrayEncoder = createTypedArrayEncoder(TAG_FLOAT32_ARRAY_LE)
376
+ export const float32ArrayDecoder = createTypedArrayDecoder(Float32Array)
377
+
378
+ // Float64Array (Tag 86, little endian)
379
+ export const float64ArrayEncoder = createTypedArrayEncoder(TAG_FLOAT64_ARRAY_LE)
380
+ export const float64ArrayDecoder = createTypedArrayDecoder(Float64Array)
381
+
382
+ // =============================================================================
383
+ // Error (Tag 27) - IANA "object with class name and constructor arguments"
384
+ // Format: Tag 27: [className, message, options?]
385
+ // =============================================================================
386
+
387
+ /**
388
+ * Known JavaScript Error constructors
389
+ * @type {Record<string, ErrorConstructor>}
390
+ */
391
+ const errorConstructors = {
392
+ Error,
393
+ EvalError,
394
+ RangeError,
395
+ ReferenceError,
396
+ SyntaxError,
397
+ TypeError,
398
+ URIError
399
+ }
400
+
401
+ /**
402
+ * Encode an Error as Tag 27: [className, message]
403
+ * @param {Error} err
404
+ * @returns {Token[]}
405
+ */
406
+ export function errorEncoder (err) {
407
+ const className = err.name
408
+ // Only encode name and message (not stack, which is environment-specific)
409
+ return [
410
+ new Token(Type.tag, TAG_OBJECT_CLASS),
411
+ new Token(Type.array, 2),
412
+ new Token(Type.string, className),
413
+ new Token(Type.string, err.message)
414
+ ]
415
+ }
416
+
417
+ /**
418
+ * Decode Tag 27 to an Error (or Error subclass)
419
+ * @param {import('../interface.js').TagDecodeControl} decode
420
+ * @returns {Error}
421
+ */
422
+ export function errorDecoder (decode) {
423
+ const arr = /** @type {[string, string]} */ (decode())
424
+ const [className, message] = arr
425
+ const Ctor = errorConstructors[className] || Error
426
+ const err = new Ctor(message)
427
+ // If the constructor doesn't match (e.g., custom error name), set the name
428
+ if (err.name !== className && className in errorConstructors) {
429
+ err.name = className
430
+ }
431
+ return err
432
+ }
433
+
434
+ // =============================================================================
435
+ // Negative Zero (-0) Support
436
+ // CBOR can represent -0 as a float, but by default numbers encode as integers.
437
+ // This encoder ensures -0 is preserved by encoding it as a float.
438
+ // =============================================================================
439
+
440
+ /**
441
+ * Encode a number, preserving -0 as a float
442
+ * Use this as a typeEncoder for 'number' to preserve -0 fidelity
443
+ * @param {number} num
444
+ * @returns {Token[] | null}
445
+ */
446
+ export function negativeZeroEncoder (num) {
447
+ if (Object.is(num, -0)) {
448
+ return [new Token(Type.float, -0)]
449
+ }
450
+ // Return null to fall through to default number encoding
451
+ return null
452
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cborg",
3
- "version": "4.5.8",
3
+ "version": "5.0.0",
4
4
  "description": "Fast CBOR with a focus on strictness",
5
5
  "main": "cborg.js",
6
6
  "type": "module",
@@ -30,23 +30,23 @@
30
30
  "license": "Apache-2.0",
31
31
  "devDependencies": {
32
32
  "@semantic-release/changelog": "^6.0.3",
33
- "@semantic-release/commit-analyzer": "^13.0.0",
33
+ "@semantic-release/commit-analyzer": "^13.0.1",
34
34
  "@semantic-release/git": "^10.0.1",
35
- "@semantic-release/github": "^12.0.0",
36
- "@semantic-release/npm": "^13.0.0",
37
- "@semantic-release/release-notes-generator": "^14.0.1",
38
- "@types/chai": "^5.0.0",
39
- "@types/mocha": "^10.0.8",
40
- "@types/node": "^25.0.0",
41
- "c8": "^10.1.2",
42
- "chai": "^6.0.1",
43
- "conventional-changelog-conventionalcommits": "^9.0.0",
35
+ "@semantic-release/github": "^12.0.6",
36
+ "@semantic-release/npm": "^13.1.5",
37
+ "@semantic-release/release-notes-generator": "^14.1.0",
38
+ "@types/chai": "^5.2.3",
39
+ "@types/mocha": "^10.0.10",
40
+ "@types/node": "^25.5.0",
41
+ "c8": "^11.0.0",
42
+ "chai": "^6.2.2",
43
+ "conventional-changelog-conventionalcommits": "^9.3.0",
44
44
  "ipld-garbage": "^5.0.0",
45
- "mocha": "^11.0.1",
46
- "polendina": "^3.2.2",
47
- "semantic-release": "^25.0.0",
45
+ "mocha": "^11.7.5",
46
+ "polendina": "^3.2.20",
47
+ "semantic-release": "^25.0.3",
48
48
  "standard": "^17.1.2",
49
- "typescript": "^5.6.2"
49
+ "typescript": "^6.0.2"
50
50
  },
51
51
  "exports": {
52
52
  ".": {
@@ -58,13 +58,17 @@
58
58
  "types": "./types/lib/length.d.ts"
59
59
  },
60
60
  "./taglib": {
61
- "import": "./taglib.js",
62
- "types": "./types/taglib.d.ts"
61
+ "import": "./lib/taglib.js",
62
+ "types": "./types/lib/taglib.d.ts"
63
63
  },
64
64
  "./json": {
65
65
  "import": "./lib/json/json.js",
66
66
  "types": "./types/lib/json/json.d.ts"
67
67
  },
68
+ "./extended": {
69
+ "import": "./lib/extended/extended.js",
70
+ "types": "./types/lib/extended/extended.d.ts"
71
+ },
68
72
  "./interface": {
69
73
  "types": "./types/interface.d.ts"
70
74
  }
package/test/common.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { Token, Type } from '../lib/token.js'
2
2
 
3
- export function dateDecoder (obj) {
3
+ export function dateDecoder (decode) {
4
+ const obj = decode()
4
5
  if (typeof obj !== 'string') {
5
6
  throw new Error('expected string for tag 1')
6
7
  }
package/test/test-6tag.js CHANGED
@@ -17,7 +17,8 @@ const encodeIntoBytes = (data, dest, options) => {
17
17
 
18
18
  const fixedDest = new Uint8Array(1024)
19
19
 
20
- function Uint16ArrayDecoder (obj) {
20
+ function Uint16ArrayDecoder (decode) {
21
+ const obj = decode()
21
22
  if (typeof obj !== 'string') {
22
23
  throw new Error('expected string for tag 23')
23
24
  }
@@ -21,14 +21,16 @@ const fixedDest = new Uint8Array(1024)
21
21
  const tags = []
22
22
  const typeEncoders = {}
23
23
 
24
- tags[0] = function (obj) {
24
+ tags[0] = function (decode) {
25
+ const obj = decode()
25
26
  if (typeof obj !== 'string') {
26
27
  throw new Error('expected string for tag 1')
27
28
  }
28
29
  return `0("${new Date(obj).toISOString().replace(/\.000Z$/, 'Z')}")`
29
30
  }
30
31
 
31
- tags[1] = function (obj) {
32
+ tags[1] = function (decode) {
33
+ const obj = decode()
32
34
  if (typeof obj !== 'number') {
33
35
  throw new Error('expected number for tag 1')
34
36
  }
@@ -39,19 +41,25 @@ tags[2] = taglib.bigIntDecoder
39
41
  typeEncoders.bigint = taglib.bigIntEncoder
40
42
  tags[3] = taglib.bigNegIntDecoder
41
43
 
42
- tags[23] = function (obj) {
44
+ tags[23] = function (decode) {
43
45
  // expected conversion to base16
46
+ const obj = decode()
44
47
  if (!(obj instanceof Uint8Array)) {
45
48
  throw new Error('expected byte array for tag 23')
46
49
  }
47
50
  return `23(h'${toHex(obj)}')`
48
51
  }
49
52
 
50
- tags[24] = function (obj) { // embedded cbor, oh my
51
- return tags[23](obj).replace(/^23/, '24')
53
+ tags[24] = function (decode) { // embedded cbor, oh my
54
+ const obj = decode()
55
+ if (!(obj instanceof Uint8Array)) {
56
+ throw new Error('expected byte array for tag 24')
57
+ }
58
+ return `24(h'${toHex(obj)}')`
52
59
  }
53
60
 
54
- tags[32] = function (obj) { // url
61
+ tags[32] = function (decode) { // url
62
+ const obj = decode()
55
63
  if (typeof obj !== 'string') {
56
64
  throw new Error('expected string for tag 32')
57
65
  }