@marcuspuchalla/nachos 0.1.1 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +55 -0
- package/dist/{chunk-ZRPJUEIZ.js → chunk-5IWW5H47.js} +546 -227
- package/dist/chunk-5IWW5H47.js.map +1 -0
- package/dist/{chunk-2HBCILJS.cjs → chunk-RVG2BY32.cjs} +545 -226
- package/dist/chunk-RVG2BY32.cjs.map +1 -0
- package/dist/{chunk-2FUTHZQQ.cjs → chunk-S4RXO6IB.cjs} +244 -166
- package/dist/chunk-S4RXO6IB.cjs.map +1 -0
- package/dist/{chunk-7CFYWHS6.js → chunk-UMAX5MX5.js} +244 -166
- package/dist/chunk-UMAX5MX5.js.map +1 -0
- package/dist/encoder/index.cjs +13 -13
- package/dist/encoder/index.d.cts +2 -2
- package/dist/encoder/index.d.ts +2 -2
- package/dist/encoder/index.js +1 -1
- package/dist/index.cjs +32 -32
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +28 -19
- package/dist/index.d.ts +28 -19
- package/dist/index.js +16 -16
- package/dist/index.js.map +1 -1
- package/dist/metafile-cjs.json +1 -1
- package/dist/metafile-esm.json +1 -1
- package/dist/parser/index.cjs +14 -14
- package/dist/parser/index.d.cts +3 -1
- package/dist/parser/index.d.ts +3 -1
- package/dist/parser/index.js +1 -1
- package/dist/{useCborSimpleEncoder-TVxzNJ_9.d.ts → useCborSimpleEncoder-BoKEmjP9.d.ts} +0 -2
- package/dist/{useCborSimpleEncoder-ButVU988.d.cts → useCborSimpleEncoder-C_OHxoB8.d.cts} +0 -2
- package/dist/{useCborTag-B_iaShG6.d.ts → useCborTag-BD6Sqp7p.d.ts} +11 -6
- package/dist/{useCborTag-BfTIV8HM.d.cts → useCborTag-QpZR-Er2.d.cts} +11 -6
- package/package.json +1 -1
- package/src/__tests__/public-api.test.ts +153 -0
- package/src/__tests__/roundtrip.test.ts +701 -0
- package/src/encoder/__tests__/cbor-collection-encoder.test.ts +129 -5
- package/src/encoder/__tests__/cbor-encoder-errors.test.ts +847 -0
- package/src/encoder/__tests__/cbor-simple-encoder.test.ts +126 -0
- package/src/encoder/__tests__/cbor-string-encoder.test.ts +14 -0
- package/src/encoder/composables/useCborCollectionEncoder.ts +56 -23
- package/src/encoder/composables/useCborEncoder.ts +27 -1
- package/src/encoder/composables/useCborSimpleEncoder.ts +40 -8
- package/src/encoder/composables/useCborStringEncoder.ts +23 -10
- package/src/encoder/types.ts +0 -2
- package/src/index.ts +29 -20
- package/src/parser/__tests__/buffer-native-parsing.test.ts +338 -0
- package/src/parser/__tests__/cbor-float-errors.test.ts +41 -0
- package/src/parser/__tests__/cbor-map-duplicate-keys.test.ts +97 -7
- package/src/parser/__tests__/cbor-security-dos-protection.test.ts +166 -33
- package/src/parser/__tests__/cbor-standard-tags.test.ts +104 -7
- package/src/parser/__tests__/cbor-string-errors.test.ts +4 -4
- package/src/parser/__tests__/cbor-tag-errors.test.ts +1 -1
- package/src/parser/__tests__/cbor-tag-reparse-fix.test.ts +268 -0
- package/src/parser/composables/useCborCollection.ts +45 -42
- package/src/parser/composables/useCborFloat.ts +95 -9
- package/src/parser/composables/useCborInteger.ts +24 -10
- package/src/parser/composables/useCborParser.ts +387 -216
- package/src/parser/composables/useCborString.ts +22 -4
- package/src/parser/composables/useCborTag.ts +149 -53
- package/src/parser/utils.ts +11 -0
- package/dist/chunk-2FUTHZQQ.cjs.map +0 -1
- package/dist/chunk-2HBCILJS.cjs.map +0 -1
- package/dist/chunk-7CFYWHS6.js.map +0 -1
- package/dist/chunk-ZRPJUEIZ.js.map +0 -1
- package/src/encoder/composables/#useCborTagEncoder.ts# +0 -158
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import { describe, it, expect } from 'vitest'
|
|
7
7
|
import { useCborCollectionEncoder } from '../composables/useCborCollectionEncoder'
|
|
8
8
|
import type { EncodableValue } from '../types'
|
|
9
|
+
import { ALL_ENTRIES_SYMBOL } from '../types'
|
|
9
10
|
|
|
10
11
|
describe('CBOR Collection Encoder', () => {
|
|
11
12
|
describe('Arrays (Major Type 4)', () => {
|
|
@@ -122,6 +123,13 @@ describe('CBOR Collection Encoder', () => {
|
|
|
122
123
|
expect(() => encodeArray([], { indefinite: true }))
|
|
123
124
|
.toThrow('Indefinite-length encoding not allowed in canonical mode')
|
|
124
125
|
})
|
|
126
|
+
|
|
127
|
+
it('should reject indefinite arrays when allowIndefinite is false', () => {
|
|
128
|
+
const { encodeArray } = useCborCollectionEncoder({ allowIndefinite: false })
|
|
129
|
+
|
|
130
|
+
expect(() => encodeArray([], { indefinite: true }))
|
|
131
|
+
.toThrow('Indefinite-length encoding is not allowed')
|
|
132
|
+
})
|
|
125
133
|
})
|
|
126
134
|
})
|
|
127
135
|
|
|
@@ -258,6 +266,118 @@ describe('CBOR Collection Encoder', () => {
|
|
|
258
266
|
expect(() => encodeMap({}, { indefinite: true }))
|
|
259
267
|
.toThrow('Indefinite-length encoding not allowed in canonical mode')
|
|
260
268
|
})
|
|
269
|
+
|
|
270
|
+
it('should reject indefinite maps when allowIndefinite is false', () => {
|
|
271
|
+
const { encodeMap } = useCborCollectionEncoder({ allowIndefinite: false })
|
|
272
|
+
|
|
273
|
+
expect(() => encodeMap({}, { indefinite: true }))
|
|
274
|
+
.toThrow('Indefinite-length encoding is not allowed')
|
|
275
|
+
})
|
|
276
|
+
})
|
|
277
|
+
|
|
278
|
+
describe('Duplicate key handling', () => {
|
|
279
|
+
it('should reject duplicate keys when rejectDuplicateKeys is true', () => {
|
|
280
|
+
const { encodeMap } = useCborCollectionEncoder({ rejectDuplicateKeys: true })
|
|
281
|
+
const map = new Map<EncodableValue, EncodableValue>([['a', 1]])
|
|
282
|
+
;(map as any)[ALL_ENTRIES_SYMBOL] = [['a', 1], ['a', 2]]
|
|
283
|
+
|
|
284
|
+
expect(() => encodeMap(map))
|
|
285
|
+
.toThrow('Duplicate map key detected')
|
|
286
|
+
})
|
|
287
|
+
})
|
|
288
|
+
|
|
289
|
+
describe('Canonical sort pre-encoding optimization', () => {
|
|
290
|
+
it('should produce identical output for canonical sort with many keys', () => {
|
|
291
|
+
const { encodeMap } = useCborCollectionEncoder({ canonical: true })
|
|
292
|
+
|
|
293
|
+
// Use many keys to exercise sorting — result must be deterministic
|
|
294
|
+
const map = new Map<EncodableValue, EncodableValue>([
|
|
295
|
+
['zebra', 1],
|
|
296
|
+
['apple', 2],
|
|
297
|
+
['mango', 3],
|
|
298
|
+
['banana', 4],
|
|
299
|
+
['kiwi', 5],
|
|
300
|
+
['cherry', 6],
|
|
301
|
+
['date', 7],
|
|
302
|
+
['fig', 8],
|
|
303
|
+
['grape', 9],
|
|
304
|
+
['lemon', 10],
|
|
305
|
+
])
|
|
306
|
+
const result1 = encodeMap(map)
|
|
307
|
+
const result2 = encodeMap(map)
|
|
308
|
+
|
|
309
|
+
// Must be deterministic
|
|
310
|
+
expect(result1.hex).toBe(result2.hex)
|
|
311
|
+
|
|
312
|
+
// Verify canonical order: sorted by encoded key length first, then bytewise
|
|
313
|
+
// 3-char keys: fig, 4-char keys: date, kiwi, 5-char keys: apple, grape, lemon, mango
|
|
314
|
+
// 6-char keys: banana, cherry, zebra
|
|
315
|
+
const hex = result1.hex
|
|
316
|
+
const figPos = hex.indexOf('6366696703') // "fig" + integer 8 (but let's just check key order)
|
|
317
|
+
const datePos = hex.indexOf('6464617465') // "date"
|
|
318
|
+
const bananaPos = hex.indexOf('6662616e616e61') // "banana"
|
|
319
|
+
|
|
320
|
+
// fig (3 chars) should come before date (4 chars) should come before banana (6 chars)
|
|
321
|
+
expect(figPos).toBeLessThan(datePos)
|
|
322
|
+
expect(datePos).toBeLessThan(bananaPos)
|
|
323
|
+
})
|
|
324
|
+
|
|
325
|
+
it('should produce correct canonical order with mixed-type Map keys', () => {
|
|
326
|
+
const { encodeMap } = useCborCollectionEncoder({ canonical: true })
|
|
327
|
+
|
|
328
|
+
// Integer keys encode shorter than string keys
|
|
329
|
+
const map = new Map<EncodableValue, EncodableValue>([
|
|
330
|
+
['z', 3],
|
|
331
|
+
[1, 1],
|
|
332
|
+
['a', 2],
|
|
333
|
+
])
|
|
334
|
+
const result = encodeMap(map)
|
|
335
|
+
|
|
336
|
+
// Integer 1 encodes as 0x01 (1 byte), "a" as 0x6161 (2 bytes), "z" as 0x617a (2 bytes)
|
|
337
|
+
// Canonical order: 1 (shortest), then "a" < "z" (same length, bytewise)
|
|
338
|
+
const hex = result.hex
|
|
339
|
+
// After map header (0xa3), first key should be integer 1 (0x01)
|
|
340
|
+
expect(hex.startsWith('a3')).toBe(true)
|
|
341
|
+
expect(hex.substring(2, 4)).toBe('01') // integer key 1
|
|
342
|
+
})
|
|
343
|
+
|
|
344
|
+
it('should reject duplicates when both canonical and rejectDuplicateKeys are on', () => {
|
|
345
|
+
const { encodeMap } = useCborCollectionEncoder({
|
|
346
|
+
canonical: true,
|
|
347
|
+
rejectDuplicateKeys: true
|
|
348
|
+
})
|
|
349
|
+
|
|
350
|
+
const map = new Map<EncodableValue, EncodableValue>([['x', 1]])
|
|
351
|
+
;(map as any)[ALL_ENTRIES_SYMBOL] = [['x', 1], ['x', 2]]
|
|
352
|
+
|
|
353
|
+
expect(() => encodeMap(map))
|
|
354
|
+
.toThrow('Duplicate map key detected')
|
|
355
|
+
})
|
|
356
|
+
|
|
357
|
+
it('should not reject unique keys when both canonical and rejectDuplicateKeys are on', () => {
|
|
358
|
+
const { encodeMap } = useCborCollectionEncoder({
|
|
359
|
+
canonical: true,
|
|
360
|
+
rejectDuplicateKeys: true
|
|
361
|
+
})
|
|
362
|
+
|
|
363
|
+
const map = new Map<EncodableValue, EncodableValue>([
|
|
364
|
+
['b', 2],
|
|
365
|
+
['a', 1],
|
|
366
|
+
['c', 3],
|
|
367
|
+
])
|
|
368
|
+
const result = encodeMap(map)
|
|
369
|
+
|
|
370
|
+
// Should succeed and produce canonical order
|
|
371
|
+
expect(result.bytes[0]).toBe(0xa3) // 3 entries
|
|
372
|
+
|
|
373
|
+
// Keys in canonical order: a, b, c
|
|
374
|
+
const hex = result.hex
|
|
375
|
+
const aPos = hex.indexOf('6161') // "a"
|
|
376
|
+
const bPos = hex.indexOf('6162') // "b"
|
|
377
|
+
const cPos = hex.indexOf('6163') // "c"
|
|
378
|
+
expect(aPos).toBeLessThan(bPos)
|
|
379
|
+
expect(bPos).toBeLessThan(cPos)
|
|
380
|
+
})
|
|
261
381
|
})
|
|
262
382
|
})
|
|
263
383
|
|
|
@@ -294,18 +414,22 @@ describe('CBOR Collection Encoder', () => {
|
|
|
294
414
|
})
|
|
295
415
|
|
|
296
416
|
describe('Output size limits', () => {
|
|
297
|
-
it('should
|
|
417
|
+
it('should not enforce maxOutputSize at the collection level (enforced at root encoder)', () => {
|
|
418
|
+
// maxOutputSize is now checked at the root level in useCborEncoder,
|
|
419
|
+
// not inside the collection encoder. The collection encoder should
|
|
420
|
+
// encode without throwing, and the root encoder applies the check.
|
|
298
421
|
const { encodeArray } = useCborCollectionEncoder({ maxOutputSize: 10 })
|
|
299
|
-
const
|
|
422
|
+
const smallArray = Array(20).fill(1)
|
|
300
423
|
|
|
301
|
-
|
|
302
|
-
|
|
424
|
+
// Collection encoder no longer throws on size - it just encodes
|
|
425
|
+
const result = encodeArray(smallArray)
|
|
426
|
+
expect(result.bytes.length).toBeGreaterThan(10)
|
|
303
427
|
})
|
|
304
428
|
})
|
|
305
429
|
|
|
306
430
|
describe('Real-world Cardano examples', () => {
|
|
307
431
|
it('should encode Cardano transaction structure', () => {
|
|
308
|
-
const { encodeMap
|
|
432
|
+
const { encodeMap } = useCborCollectionEncoder()
|
|
309
433
|
|
|
310
434
|
// Simplified Cardano transaction
|
|
311
435
|
const tx = {
|