@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.
Files changed (62) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/dist/{chunk-ZRPJUEIZ.js → chunk-5IWW5H47.js} +546 -227
  3. package/dist/chunk-5IWW5H47.js.map +1 -0
  4. package/dist/{chunk-2HBCILJS.cjs → chunk-RVG2BY32.cjs} +545 -226
  5. package/dist/chunk-RVG2BY32.cjs.map +1 -0
  6. package/dist/{chunk-2FUTHZQQ.cjs → chunk-S4RXO6IB.cjs} +244 -166
  7. package/dist/chunk-S4RXO6IB.cjs.map +1 -0
  8. package/dist/{chunk-7CFYWHS6.js → chunk-UMAX5MX5.js} +244 -166
  9. package/dist/chunk-UMAX5MX5.js.map +1 -0
  10. package/dist/encoder/index.cjs +13 -13
  11. package/dist/encoder/index.d.cts +2 -2
  12. package/dist/encoder/index.d.ts +2 -2
  13. package/dist/encoder/index.js +1 -1
  14. package/dist/index.cjs +32 -32
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d.cts +28 -19
  17. package/dist/index.d.ts +28 -19
  18. package/dist/index.js +16 -16
  19. package/dist/index.js.map +1 -1
  20. package/dist/metafile-cjs.json +1 -1
  21. package/dist/metafile-esm.json +1 -1
  22. package/dist/parser/index.cjs +14 -14
  23. package/dist/parser/index.d.cts +3 -1
  24. package/dist/parser/index.d.ts +3 -1
  25. package/dist/parser/index.js +1 -1
  26. package/dist/{useCborSimpleEncoder-TVxzNJ_9.d.ts → useCborSimpleEncoder-BoKEmjP9.d.ts} +0 -2
  27. package/dist/{useCborSimpleEncoder-ButVU988.d.cts → useCborSimpleEncoder-C_OHxoB8.d.cts} +0 -2
  28. package/dist/{useCborTag-B_iaShG6.d.ts → useCborTag-BD6Sqp7p.d.ts} +11 -6
  29. package/dist/{useCborTag-BfTIV8HM.d.cts → useCborTag-QpZR-Er2.d.cts} +11 -6
  30. package/package.json +1 -1
  31. package/src/__tests__/public-api.test.ts +153 -0
  32. package/src/__tests__/roundtrip.test.ts +701 -0
  33. package/src/encoder/__tests__/cbor-collection-encoder.test.ts +129 -5
  34. package/src/encoder/__tests__/cbor-encoder-errors.test.ts +847 -0
  35. package/src/encoder/__tests__/cbor-simple-encoder.test.ts +126 -0
  36. package/src/encoder/__tests__/cbor-string-encoder.test.ts +14 -0
  37. package/src/encoder/composables/useCborCollectionEncoder.ts +56 -23
  38. package/src/encoder/composables/useCborEncoder.ts +27 -1
  39. package/src/encoder/composables/useCborSimpleEncoder.ts +40 -8
  40. package/src/encoder/composables/useCborStringEncoder.ts +23 -10
  41. package/src/encoder/types.ts +0 -2
  42. package/src/index.ts +29 -20
  43. package/src/parser/__tests__/buffer-native-parsing.test.ts +338 -0
  44. package/src/parser/__tests__/cbor-float-errors.test.ts +41 -0
  45. package/src/parser/__tests__/cbor-map-duplicate-keys.test.ts +97 -7
  46. package/src/parser/__tests__/cbor-security-dos-protection.test.ts +166 -33
  47. package/src/parser/__tests__/cbor-standard-tags.test.ts +104 -7
  48. package/src/parser/__tests__/cbor-string-errors.test.ts +4 -4
  49. package/src/parser/__tests__/cbor-tag-errors.test.ts +1 -1
  50. package/src/parser/__tests__/cbor-tag-reparse-fix.test.ts +268 -0
  51. package/src/parser/composables/useCborCollection.ts +45 -42
  52. package/src/parser/composables/useCborFloat.ts +95 -9
  53. package/src/parser/composables/useCborInteger.ts +24 -10
  54. package/src/parser/composables/useCborParser.ts +387 -216
  55. package/src/parser/composables/useCborString.ts +22 -4
  56. package/src/parser/composables/useCborTag.ts +149 -53
  57. package/src/parser/utils.ts +11 -0
  58. package/dist/chunk-2FUTHZQQ.cjs.map +0 -1
  59. package/dist/chunk-2HBCILJS.cjs.map +0 -1
  60. package/dist/chunk-7CFYWHS6.js.map +0 -1
  61. package/dist/chunk-ZRPJUEIZ.js.map +0 -1
  62. 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 respect maxOutputSize option', () => {
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 largeArray = Array(100).fill(1)
422
+ const smallArray = Array(20).fill(1)
300
423
 
301
- expect(() => encodeArray(largeArray))
302
- .toThrow('Encoded output exceeds maximum size')
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, encodeArray } = useCborCollectionEncoder()
432
+ const { encodeMap } = useCborCollectionEncoder()
309
433
 
310
434
  // Simplified Cardano transaction
311
435
  const tx = {