@marcuspuchalla/nachos 0.1.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 (100) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/LICENSE +674 -0
  3. package/README.md +345 -0
  4. package/dist/chunk-2FUTHZQQ.cjs +755 -0
  5. package/dist/chunk-2FUTHZQQ.cjs.map +1 -0
  6. package/dist/chunk-2HBCILJS.cjs +2034 -0
  7. package/dist/chunk-2HBCILJS.cjs.map +1 -0
  8. package/dist/chunk-7CFYWHS6.js +742 -0
  9. package/dist/chunk-7CFYWHS6.js.map +1 -0
  10. package/dist/chunk-PD72MVTX.cjs +160 -0
  11. package/dist/chunk-PD72MVTX.cjs.map +1 -0
  12. package/dist/chunk-ZDZ2B5PE.js +149 -0
  13. package/dist/chunk-ZDZ2B5PE.js.map +1 -0
  14. package/dist/chunk-ZRPJUEIZ.js +2020 -0
  15. package/dist/chunk-ZRPJUEIZ.js.map +1 -0
  16. package/dist/encoder/index.cjs +57 -0
  17. package/dist/encoder/index.cjs.map +1 -0
  18. package/dist/encoder/index.d.cts +72 -0
  19. package/dist/encoder/index.d.ts +72 -0
  20. package/dist/encoder/index.js +4 -0
  21. package/dist/encoder/index.js.map +1 -0
  22. package/dist/index.cjs +606 -0
  23. package/dist/index.cjs.map +1 -0
  24. package/dist/index.d.cts +494 -0
  25. package/dist/index.d.ts +494 -0
  26. package/dist/index.js +523 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/metafile-cjs.json +1 -0
  29. package/dist/metafile-esm.json +1 -0
  30. package/dist/parser/index.cjs +85 -0
  31. package/dist/parser/index.cjs.map +1 -0
  32. package/dist/parser/index.d.cts +72 -0
  33. package/dist/parser/index.d.ts +72 -0
  34. package/dist/parser/index.js +4 -0
  35. package/dist/parser/index.js.map +1 -0
  36. package/dist/types-DvNlfbKB.d.cts +301 -0
  37. package/dist/types-DvNlfbKB.d.ts +301 -0
  38. package/dist/useCborSimpleEncoder-ButVU988.d.cts +268 -0
  39. package/dist/useCborSimpleEncoder-TVxzNJ_9.d.ts +268 -0
  40. package/dist/useCborTag-B_iaShG6.d.ts +142 -0
  41. package/dist/useCborTag-BfTIV8HM.d.cts +142 -0
  42. package/package.json +102 -0
  43. package/src/__tests__/public-api.test.ts +326 -0
  44. package/src/encoder/__tests__/cbor-collection-encoder.test.ts +331 -0
  45. package/src/encoder/__tests__/cbor-integer-encoder.test.ts +283 -0
  46. package/src/encoder/__tests__/cbor-simple-encoder.test.ts +224 -0
  47. package/src/encoder/__tests__/cbor-string-encoder.test.ts +345 -0
  48. package/src/encoder/__tests__/cbor-tag-encoder.test.ts +565 -0
  49. package/src/encoder/composables/#useCborTagEncoder.ts# +158 -0
  50. package/src/encoder/composables/useCborCollectionEncoder.ts +424 -0
  51. package/src/encoder/composables/useCborEncoder.ts +203 -0
  52. package/src/encoder/composables/useCborIntegerEncoder.ts +188 -0
  53. package/src/encoder/composables/useCborSimpleEncoder.ts +266 -0
  54. package/src/encoder/composables/useCborStringEncoder.ts +266 -0
  55. package/src/encoder/composables/useCborTagEncoder.ts +158 -0
  56. package/src/encoder/index.ts +35 -0
  57. package/src/encoder/types.ts +88 -0
  58. package/src/encoder/utils.ts +80 -0
  59. package/src/index.ts +434 -0
  60. package/src/parser/__tests__/ast-tree-structure.test.ts +311 -0
  61. package/src/parser/__tests__/cbor-collection-errors.test.ts +296 -0
  62. package/src/parser/__tests__/cbor-collection.test.ts +369 -0
  63. package/src/parser/__tests__/cbor-deterministic-encoding.test.ts +432 -0
  64. package/src/parser/__tests__/cbor-diagnostic.test.ts +333 -0
  65. package/src/parser/__tests__/cbor-duplicate-keys.test.ts +235 -0
  66. package/src/parser/__tests__/cbor-float-errors.test.ts +222 -0
  67. package/src/parser/__tests__/cbor-float.test.ts +502 -0
  68. package/src/parser/__tests__/cbor-integer-errors.test.ts +139 -0
  69. package/src/parser/__tests__/cbor-integer.test.ts +200 -0
  70. package/src/parser/__tests__/cbor-map-duplicate-keys.test.ts +403 -0
  71. package/src/parser/__tests__/cbor-parser-errors.test.ts +126 -0
  72. package/src/parser/__tests__/cbor-security-dos-protection.test.ts +503 -0
  73. package/src/parser/__tests__/cbor-sequences.test.ts +150 -0
  74. package/src/parser/__tests__/cbor-source-map.test.ts +321 -0
  75. package/src/parser/__tests__/cbor-standard-tags.test.ts +340 -0
  76. package/src/parser/__tests__/cbor-string-errors.test.ts +227 -0
  77. package/src/parser/__tests__/cbor-string.test.ts +224 -0
  78. package/src/parser/__tests__/cbor-tag-advanced.test.ts +500 -0
  79. package/src/parser/__tests__/cbor-tag-errors.test.ts +447 -0
  80. package/src/parser/__tests__/cbor-tag-source-map.test.ts +360 -0
  81. package/src/parser/__tests__/cbor-tag.test.ts +684 -0
  82. package/src/parser/__tests__/extreme-edge-cases.test.ts +146 -0
  83. package/src/parser/__tests__/pathBuilder.test.ts +256 -0
  84. package/src/parser/__tests__/rfc-test-vectors.test.ts +607 -0
  85. package/src/parser/__tests__/security-limits.test.ts +248 -0
  86. package/src/parser/__tests__/utils-errors.test.ts +127 -0
  87. package/src/parser/composables/useCborCollection.ts +509 -0
  88. package/src/parser/composables/useCborDiagnostic.ts +381 -0
  89. package/src/parser/composables/useCborFloat.ts +256 -0
  90. package/src/parser/composables/useCborInteger.ts +114 -0
  91. package/src/parser/composables/useCborParser.ts +951 -0
  92. package/src/parser/composables/useCborString.ts +330 -0
  93. package/src/parser/composables/useCborStringTypes.ts +129 -0
  94. package/src/parser/composables/useCborTag.ts +739 -0
  95. package/src/parser/index.ts +56 -0
  96. package/src/parser/types.ts +371 -0
  97. package/src/parser/utils/pathBuilder.ts +259 -0
  98. package/src/parser/utils.ts +398 -0
  99. package/src/utils/__tests__/logger.test.ts +186 -0
  100. package/src/utils/logger.ts +96 -0
@@ -0,0 +1,2034 @@
1
+ 'use strict';
2
+
3
+ var chunkPD72MVTX_cjs = require('./chunk-PD72MVTX.cjs');
4
+
5
+ // src/parser/utils.ts
6
+ var hexToBytes = (hex) => {
7
+ const bytes = hex.match(/.{1,2}/g);
8
+ if (!bytes) return new Uint8Array(0);
9
+ return new Uint8Array(bytes.map((byte) => parseInt(byte, 16)));
10
+ };
11
+ var bytesToHex = (bytes) => {
12
+ return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
13
+ };
14
+ var readByte = (buffer, offset) => {
15
+ if (offset >= buffer.length) {
16
+ throw new Error(`Offset ${offset} is out of bounds (buffer length: ${buffer.length})`);
17
+ }
18
+ const byte = buffer[offset];
19
+ if (byte === void 0) {
20
+ throw new Error(`Unexpected undefined byte at offset ${offset}`);
21
+ }
22
+ return byte;
23
+ };
24
+ var readUint = (buffer, offset, length) => {
25
+ if (length < 1 || length > 8) {
26
+ throw new Error(`Invalid length: ${length} (must be 1-8)`);
27
+ }
28
+ if (offset + length > buffer.length) {
29
+ throw new Error(`Cannot read ${length} bytes at offset ${offset} (buffer length: ${buffer.length})`);
30
+ }
31
+ let result = 0;
32
+ for (let i = 0; i < length; i++) {
33
+ result = result * 256 + readByte(buffer, offset + i);
34
+ }
35
+ return result;
36
+ };
37
+ var readBigUint = (buffer, offset, length) => {
38
+ if (length < 1 || length > 8) {
39
+ throw new Error(`Invalid length: ${length} (must be 1-8)`);
40
+ }
41
+ if (offset + length > buffer.length) {
42
+ throw new Error(`Cannot read ${length} bytes at offset ${offset} (buffer length: ${buffer.length})`);
43
+ }
44
+ let result = 0n;
45
+ for (let i = 0; i < length; i++) {
46
+ result = result * 256n + BigInt(readByte(buffer, offset + i));
47
+ }
48
+ return result;
49
+ };
50
+ var extractCborHeader = (initialByte) => {
51
+ return {
52
+ majorType: initialByte >> 5,
53
+ additionalInfo: initialByte & 31
54
+ };
55
+ };
56
+ function validateUtf8Strict(bytes) {
57
+ let i = 0;
58
+ while (i < bytes.length) {
59
+ const byte = bytes[i];
60
+ if (byte === void 0) {
61
+ throw new Error(`Unexpected undefined byte at position ${i}`);
62
+ }
63
+ if (byte === 192 || byte === 193 || byte >= 245) {
64
+ throw new Error(
65
+ `Invalid UTF-8 start byte 0x${byte.toString(16).padStart(2, "0")} at position ${i}`
66
+ );
67
+ }
68
+ if (byte < 128) {
69
+ i++;
70
+ continue;
71
+ }
72
+ if (byte >= 194 && byte <= 223) {
73
+ if (i + 1 >= bytes.length) {
74
+ throw new Error(`Incomplete UTF-8 sequence at position ${i}`);
75
+ }
76
+ const byte2 = bytes[i + 1];
77
+ if (byte2 === void 0) {
78
+ throw new Error(`Incomplete UTF-8 sequence at position ${i}`);
79
+ }
80
+ if ((byte2 & 192) !== 128) {
81
+ throw new Error(`Invalid UTF-8 continuation byte at position ${i + 1}`);
82
+ }
83
+ const codepoint = (byte & 31) << 6 | byte2 & 63;
84
+ if (codepoint < 128) {
85
+ throw new Error(
86
+ `Overlong UTF-8 encoding at position ${i}: U+${codepoint.toString(16).padStart(4, "0").toUpperCase()} encoded as 2 bytes (should be 1 byte)`
87
+ );
88
+ }
89
+ i += 2;
90
+ continue;
91
+ }
92
+ if (byte >= 224 && byte <= 239) {
93
+ if (i + 2 >= bytes.length) {
94
+ throw new Error(`Incomplete UTF-8 sequence at position ${i}`);
95
+ }
96
+ const byte2 = bytes[i + 1];
97
+ const byte3 = bytes[i + 2];
98
+ if (byte2 === void 0 || byte3 === void 0) {
99
+ throw new Error(`Incomplete UTF-8 sequence at position ${i}`);
100
+ }
101
+ if ((byte2 & 192) !== 128 || (byte3 & 192) !== 128) {
102
+ throw new Error(
103
+ `Invalid UTF-8 continuation byte at position ${i + 1} or ${i + 2}`
104
+ );
105
+ }
106
+ const codepoint = (byte & 15) << 12 | (byte2 & 63) << 6 | byte3 & 63;
107
+ if (codepoint < 2048) {
108
+ throw new Error(
109
+ `Overlong UTF-8 encoding at position ${i}: U+${codepoint.toString(16).padStart(4, "0").toUpperCase()} encoded as 3 bytes (should be 2 bytes or less)`
110
+ );
111
+ }
112
+ if (codepoint >= 55296 && codepoint <= 57343) {
113
+ throw new Error(
114
+ `Invalid UTF-8 surrogate codepoint U+${codepoint.toString(16).padStart(4, "0").toUpperCase()} at position ${i} (surrogates are not valid Unicode scalar values)`
115
+ );
116
+ }
117
+ i += 3;
118
+ continue;
119
+ }
120
+ if (byte >= 240 && byte <= 244) {
121
+ if (i + 3 >= bytes.length) {
122
+ throw new Error(`Incomplete UTF-8 sequence at position ${i}`);
123
+ }
124
+ const byte2 = bytes[i + 1];
125
+ const byte3 = bytes[i + 2];
126
+ const byte4 = bytes[i + 3];
127
+ if (byte2 === void 0 || byte3 === void 0 || byte4 === void 0) {
128
+ throw new Error(`Incomplete UTF-8 sequence at position ${i}`);
129
+ }
130
+ if ((byte2 & 192) !== 128 || (byte3 & 192) !== 128 || (byte4 & 192) !== 128) {
131
+ throw new Error(
132
+ `Invalid UTF-8 continuation byte at position ${i + 1}, ${i + 2}, or ${i + 3}`
133
+ );
134
+ }
135
+ const codepoint = (byte & 7) << 18 | (byte2 & 63) << 12 | (byte3 & 63) << 6 | byte4 & 63;
136
+ if (codepoint < 65536) {
137
+ throw new Error(
138
+ `Overlong UTF-8 encoding at position ${i}: U+${codepoint.toString(16).padStart(6, "0").toUpperCase()} encoded as 4 bytes (should be 3 bytes or less)`
139
+ );
140
+ }
141
+ if (codepoint > 1114111) {
142
+ throw new Error(
143
+ `UTF-8 codepoint U+${codepoint.toString(16).padStart(6, "0").toUpperCase()} exceeds maximum U+10FFFF at position ${i}`
144
+ );
145
+ }
146
+ i += 4;
147
+ continue;
148
+ }
149
+ throw new Error(
150
+ `Invalid UTF-8 byte 0x${byte.toString(16).padStart(2, "0")} at position ${i}`
151
+ );
152
+ }
153
+ }
154
+ function validateCanonicalInteger(value, ai) {
155
+ const v = typeof value === "bigint" ? value : BigInt(value);
156
+ if (v >= 0n && v <= 23n && ai !== Number(v)) {
157
+ throw new Error(
158
+ `Non-canonical integer: value ${v} must use AI ${v}, not AI ${ai}`
159
+ );
160
+ }
161
+ if (v >= 24n && v <= 255n && ai !== 24) {
162
+ throw new Error(
163
+ `Non-canonical integer: value ${v} must use AI 24 (1-byte), not AI ${ai}`
164
+ );
165
+ }
166
+ if (v >= 256n && v <= 65535n && ai !== 25) {
167
+ throw new Error(
168
+ `Non-canonical integer: value ${v} must use AI 25 (2-byte), not AI ${ai}`
169
+ );
170
+ }
171
+ if (v >= 65536n && v <= 4294967295n && ai !== 26) {
172
+ throw new Error(
173
+ `Non-canonical integer: value ${v} must use AI 26 (4-byte), not AI ${ai}`
174
+ );
175
+ }
176
+ if (v > 4294967295n && ai !== 27) {
177
+ throw new Error(
178
+ `Non-canonical integer: value ${v} must use AI 27 (8-byte), not AI ${ai}`
179
+ );
180
+ }
181
+ }
182
+ function compareBytes(a, b) {
183
+ if (!a || !b) {
184
+ throw new Error("compareBytes: arguments cannot be null or undefined");
185
+ }
186
+ if (a.length !== b.length) {
187
+ return a.length - b.length;
188
+ }
189
+ for (let i = 0; i < a.length; i++) {
190
+ const byteA = a[i];
191
+ const byteB = b[i];
192
+ if (byteA === void 0 || byteB === void 0) {
193
+ throw new Error(`Unexpected undefined byte at index ${i}`);
194
+ }
195
+ if (byteA !== byteB) {
196
+ return byteA - byteB;
197
+ }
198
+ }
199
+ return 0;
200
+ }
201
+ function serializeValueForComparison(value) {
202
+ if (value === null) return "null";
203
+ if (value === void 0) return "undefined";
204
+ if (typeof value === "boolean") return value.toString();
205
+ if (typeof value === "number") return `num:${value}`;
206
+ if (typeof value === "bigint") return `bigint:${value.toString()}`;
207
+ if (typeof value === "string") return `str:${value}`;
208
+ if (value instanceof Uint8Array) {
209
+ return `bytes:${Array.from(value).map((b) => b.toString(16).padStart(2, "0")).join("")}`;
210
+ }
211
+ if (Array.isArray(value)) {
212
+ return `array:[${value.map((v) => serializeValueForComparison(v)).join(",")}]`;
213
+ }
214
+ if (typeof value === "object") {
215
+ if ("tag" in value && "value" in value) {
216
+ return `tag:${value.tag}:${serializeValueForComparison(value.value)}`;
217
+ }
218
+ const keys = Object.keys(value).sort();
219
+ const pairs = keys.map((k) => `${k}:${serializeValueForComparison(value[k])}`);
220
+ return `map:{${pairs.join(",")}}`;
221
+ }
222
+ return String(value);
223
+ }
224
+ function hasDuplicates(items) {
225
+ const seen = /* @__PURE__ */ new Set();
226
+ for (const item of items) {
227
+ const serialized = serializeValueForComparison(item);
228
+ if (seen.has(serialized)) {
229
+ return true;
230
+ }
231
+ seen.add(serialized);
232
+ }
233
+ return false;
234
+ }
235
+
236
+ // src/parser/composables/useCborInteger.ts
237
+ function useCborInteger() {
238
+ const parseInteger = (hexString, options) => {
239
+ const buffer = hexToBytes(hexString);
240
+ const initialByte = readByte(buffer, 0);
241
+ const { majorType, additionalInfo } = extractCborHeader(initialByte);
242
+ let rawValue;
243
+ let bytesRead;
244
+ if (additionalInfo < 24) {
245
+ rawValue = additionalInfo;
246
+ bytesRead = 1;
247
+ } else if (additionalInfo === 24) {
248
+ rawValue = readByte(buffer, 1);
249
+ bytesRead = 2;
250
+ } else if (additionalInfo === 25) {
251
+ rawValue = readUint(buffer, 1, 2);
252
+ bytesRead = 3;
253
+ } else if (additionalInfo === 26) {
254
+ rawValue = readUint(buffer, 1, 4);
255
+ bytesRead = 5;
256
+ } else if (additionalInfo === 27) {
257
+ const bigValue = readBigUint(buffer, 1, 8);
258
+ if (bigValue <= BigInt(Number.MAX_SAFE_INTEGER)) {
259
+ rawValue = Number(bigValue);
260
+ } else {
261
+ rawValue = bigValue;
262
+ }
263
+ bytesRead = 9;
264
+ } else {
265
+ throw new Error(`Invalid additional info: ${additionalInfo}`);
266
+ }
267
+ if (options?.validateCanonical) {
268
+ validateCanonicalInteger(rawValue, additionalInfo);
269
+ }
270
+ let finalValue;
271
+ if (majorType === 0) {
272
+ finalValue = rawValue;
273
+ } else if (majorType === 1) {
274
+ if (typeof rawValue === "bigint") {
275
+ const negValue = -1n - rawValue;
276
+ if (negValue >= BigInt(Number.MIN_SAFE_INTEGER) && negValue <= BigInt(Number.MAX_SAFE_INTEGER)) {
277
+ finalValue = Number(negValue);
278
+ } else {
279
+ finalValue = negValue;
280
+ }
281
+ } else {
282
+ const negValue = -1 - rawValue;
283
+ if (negValue >= Number.MIN_SAFE_INTEGER) {
284
+ finalValue = negValue;
285
+ } else {
286
+ finalValue = BigInt(negValue);
287
+ }
288
+ }
289
+ } else {
290
+ throw new Error(`Expected major type 0 or 1, got ${majorType}`);
291
+ }
292
+ return {
293
+ value: finalValue,
294
+ bytesRead
295
+ };
296
+ };
297
+ return {
298
+ parseInteger
299
+ };
300
+ }
301
+
302
+ // src/parser/composables/useCborString.ts
303
+ function useCborString() {
304
+ const { create: createByteString } = chunkPD72MVTX_cjs.useCborByteString();
305
+ const { create: createTextString } = chunkPD72MVTX_cjs.useCborTextString();
306
+ const parseLength = (buffer, offset, ai, options) => {
307
+ if (ai < 24) {
308
+ return { length: ai, bytesConsumed: 0 };
309
+ } else if (ai === 24) {
310
+ const length = readByte(buffer, offset);
311
+ if (options?.validateCanonical && length < 24) {
312
+ throw new Error(`Non-canonical length encoding: ${length} should use direct encoding (AI < 24), not AI=24`);
313
+ }
314
+ return { length, bytesConsumed: 1 };
315
+ } else if (ai === 25) {
316
+ const length = readUint(buffer, offset, 2);
317
+ if (options?.validateCanonical && length < 256) {
318
+ throw new Error(`Non-canonical length encoding: ${length} should use ${length < 24 ? "direct encoding" : "1-byte encoding (AI=24)"}, not AI=25`);
319
+ }
320
+ return { length, bytesConsumed: 2 };
321
+ } else if (ai === 26) {
322
+ const length = readUint(buffer, offset, 4);
323
+ if (options?.validateCanonical && length < 65536) {
324
+ throw new Error(`Non-canonical length encoding: ${length} should use shorter encoding, not AI=26`);
325
+ }
326
+ return { length, bytesConsumed: 4 };
327
+ } else if (ai === 27) {
328
+ const lengthBigInt = readBigUint(buffer, offset, 8);
329
+ if (lengthBigInt > BigInt(Number.MAX_SAFE_INTEGER)) {
330
+ throw new Error(`String length ${lengthBigInt} exceeds maximum safe integer`);
331
+ }
332
+ const length = Number(lengthBigInt);
333
+ if (options?.validateCanonical && length < 4294967296) {
334
+ throw new Error(`Non-canonical length encoding: ${length} should use shorter encoding, not AI=27`);
335
+ }
336
+ return { length, bytesConsumed: 8 };
337
+ } else if (ai === 31) {
338
+ return { length: -1, bytesConsumed: 0 };
339
+ } else {
340
+ throw new Error(`Invalid additional info: ${ai}`);
341
+ }
342
+ };
343
+ const parseByteString = (buffer, offset = 0, options) => {
344
+ const initialByte = readByte(buffer, offset);
345
+ const { majorType, additionalInfo } = extractCborHeader(initialByte);
346
+ if (majorType !== 2) {
347
+ throw new Error(`Expected major type 2 (byte string), got ${majorType}`);
348
+ }
349
+ if (additionalInfo === 31 && options?.allowIndefinite === false) {
350
+ throw new Error("Indefinite-length encoding is not allowed in strict mode");
351
+ }
352
+ const { length, bytesConsumed } = parseLength(buffer, offset + 1, additionalInfo, options);
353
+ if (length === -1) {
354
+ const chunks = [];
355
+ let currentOffset = offset + 1 + bytesConsumed;
356
+ let totalLength = 0;
357
+ while (currentOffset < buffer.length) {
358
+ if (currentOffset >= buffer.length) {
359
+ throw new Error(`Incomplete indefinite byte string: missing break marker`);
360
+ }
361
+ const nextByte = buffer[currentOffset];
362
+ if (nextByte === 255) {
363
+ currentOffset++;
364
+ break;
365
+ }
366
+ let chunkResult;
367
+ try {
368
+ chunkResult = parseByteString(buffer, currentOffset, options);
369
+ } catch (error2) {
370
+ throw new Error(`Error parsing indefinite byte string chunk at offset ${currentOffset}: ${error2.message}`);
371
+ }
372
+ if (!(chunkResult.value instanceof Uint8Array)) {
373
+ throw new Error("Indefinite byte string must contain only byte string chunks");
374
+ }
375
+ chunks.push(chunkResult.value);
376
+ totalLength += chunkResult.value.length;
377
+ currentOffset += chunkResult.bytesRead;
378
+ if (options?.limits?.maxStringLength && totalLength > options.limits.maxStringLength) {
379
+ throw new Error(`Byte string length ${totalLength} exceeds limit of ${options.limits.maxStringLength} bytes`);
380
+ }
381
+ }
382
+ const bytes = new Uint8Array(totalLength);
383
+ let destOffset = 0;
384
+ for (const chunk of chunks) {
385
+ bytes.set(chunk, destOffset);
386
+ destOffset += chunk.length;
387
+ }
388
+ return {
389
+ value: createByteString(bytes, true, chunks),
390
+ bytesRead: currentOffset - offset
391
+ };
392
+ }
393
+ if (options?.limits?.maxStringLength && length > options.limits.maxStringLength) {
394
+ throw new Error(`Byte string length ${length} exceeds limit of ${options.limits.maxStringLength} bytes`);
395
+ }
396
+ const payloadOffset = offset + 1 + bytesConsumed;
397
+ if (payloadOffset + length > buffer.length) {
398
+ throw new Error(`Insufficient data: expected ${length} bytes at offset ${payloadOffset}, but only ${buffer.length - payloadOffset} bytes available`);
399
+ }
400
+ const payload = buffer.slice(payloadOffset, payloadOffset + length);
401
+ return {
402
+ value: payload,
403
+ bytesRead: 1 + bytesConsumed + length
404
+ };
405
+ };
406
+ const parseTextString = (buffer, offset = 0, options) => {
407
+ const initialByte = readByte(buffer, offset);
408
+ const { majorType, additionalInfo } = extractCborHeader(initialByte);
409
+ if (majorType !== 3) {
410
+ throw new Error(`Expected major type 3 (text string), got ${majorType}`);
411
+ }
412
+ if (additionalInfo === 31 && options?.allowIndefinite === false) {
413
+ throw new Error("Indefinite-length encoding is not allowed in strict mode");
414
+ }
415
+ const { length, bytesConsumed } = parseLength(buffer, offset + 1, additionalInfo, options);
416
+ if (length === -1) {
417
+ const chunks = [];
418
+ let currentOffset = offset + 1 + bytesConsumed;
419
+ let totalLength = 0;
420
+ while (currentOffset < buffer.length) {
421
+ if (currentOffset >= buffer.length) {
422
+ throw new Error(`Incomplete indefinite text string: missing break marker`);
423
+ }
424
+ const nextByte = buffer[currentOffset];
425
+ if (nextByte === 255) {
426
+ currentOffset++;
427
+ break;
428
+ }
429
+ let chunkResult;
430
+ try {
431
+ chunkResult = parseTextString(buffer, currentOffset, options);
432
+ } catch (error2) {
433
+ throw new Error(`Error parsing indefinite text string chunk at offset ${currentOffset}: ${error2.message}`);
434
+ }
435
+ if (typeof chunkResult.value !== "string") {
436
+ throw new Error("Indefinite text string must contain only text string chunks");
437
+ }
438
+ chunks.push(chunkResult.value);
439
+ totalLength += chunkResult.value.length;
440
+ currentOffset += chunkResult.bytesRead;
441
+ if (options?.limits?.maxStringLength && totalLength > options.limits.maxStringLength) {
442
+ throw new Error(`Text string length ${totalLength} exceeds limit of ${options.limits.maxStringLength} characters`);
443
+ }
444
+ }
445
+ const text2 = chunks.join("");
446
+ return {
447
+ value: createTextString(text2, true, chunks),
448
+ bytesRead: currentOffset - offset
449
+ };
450
+ }
451
+ if (options?.limits?.maxStringLength && length > options.limits.maxStringLength) {
452
+ throw new Error(`Text string length ${length} bytes exceeds limit of ${options.limits.maxStringLength} bytes`);
453
+ }
454
+ const payloadOffset = offset + 1 + bytesConsumed;
455
+ if (payloadOffset + length > buffer.length) {
456
+ throw new Error(`Insufficient data: expected ${length} bytes at offset ${payloadOffset}, but only ${buffer.length - payloadOffset} bytes available`);
457
+ }
458
+ const payload = buffer.slice(payloadOffset, payloadOffset + length);
459
+ if (options?.validateUtf8Strict) {
460
+ validateUtf8Strict(payload);
461
+ }
462
+ const decoder = new TextDecoder("utf-8");
463
+ const text = decoder.decode(payload);
464
+ return {
465
+ value: text,
466
+ bytesRead: 1 + bytesConsumed + length
467
+ };
468
+ };
469
+ const parseString = (hexString, options) => {
470
+ const buffer = hexToBytes(hexString);
471
+ const initialByte = readByte(buffer, 0);
472
+ const { majorType } = extractCborHeader(initialByte);
473
+ if (majorType === 2) {
474
+ return parseByteString(buffer, 0, options);
475
+ } else if (majorType === 3) {
476
+ return parseTextString(buffer, 0, options);
477
+ } else {
478
+ throw new Error(`Expected major type 2 or 3 (string), got ${majorType}`);
479
+ }
480
+ };
481
+ return {
482
+ parseString,
483
+ parseByteString,
484
+ parseTextString
485
+ };
486
+ }
487
+
488
+ // src/parser/composables/useCborFloat.ts
489
+ function useCborFloat() {
490
+ const float16ToFloat64 = (buffer, offset) => {
491
+ const byte1 = readByte(buffer, offset);
492
+ const byte2 = readByte(buffer, offset + 1);
493
+ const value = byte1 << 8 | byte2;
494
+ const sign = (value & 32768) >> 15;
495
+ const exponent = (value & 31744) >> 10;
496
+ const fraction = value & 1023;
497
+ if (exponent === 0) {
498
+ if (fraction === 0) {
499
+ return sign === 0 ? 0 : -0;
500
+ }
501
+ return (sign === 0 ? 1 : -1) * Math.pow(2, -14) * (fraction / 1024);
502
+ }
503
+ if (exponent === 31) {
504
+ if (fraction === 0) {
505
+ return sign === 0 ? Infinity : -Infinity;
506
+ }
507
+ return NaN;
508
+ }
509
+ return (sign === 0 ? 1 : -1) * Math.pow(2, exponent - 15) * (1 + fraction / 1024);
510
+ };
511
+ const parseSimpleFromBuffer = (buffer, offset) => {
512
+ const initialByte = readByte(buffer, offset);
513
+ const { majorType, additionalInfo } = extractCborHeader(initialByte);
514
+ if (majorType !== 7) {
515
+ throw new Error(`Expected major type 7 (simple/float), got ${majorType}`);
516
+ }
517
+ if (additionalInfo < 20) {
518
+ return {
519
+ value: { simpleValue: additionalInfo },
520
+ bytesRead: 1
521
+ };
522
+ }
523
+ switch (additionalInfo) {
524
+ case 20:
525
+ return { value: false, bytesRead: 1 };
526
+ case 21:
527
+ return { value: true, bytesRead: 1 };
528
+ case 22:
529
+ return { value: null, bytesRead: 1 };
530
+ case 23:
531
+ return { value: void 0, bytesRead: 1 };
532
+ case 24: {
533
+ if (offset + 1 >= buffer.length) {
534
+ throw new Error("Unexpected end of buffer while reading simple value");
535
+ }
536
+ const simpleValue = readByte(buffer, offset + 1);
537
+ if (simpleValue < 32) {
538
+ throw new Error(`Invalid 1-byte encoding for simple value ${simpleValue}`);
539
+ }
540
+ return {
541
+ value: { simpleValue },
542
+ bytesRead: 2
543
+ };
544
+ }
545
+ case 25:
546
+ // Float16
547
+ case 26:
548
+ // Float32
549
+ case 27:
550
+ throw new Error(`Additional info ${additionalInfo} is a float, use parseFloat instead`);
551
+ case 28:
552
+ case 29:
553
+ case 30:
554
+ throw new Error(`Reserved additional info value: ${additionalInfo}`);
555
+ case 31:
556
+ throw new Error("Break marker (0xff) should only appear in indefinite-length items");
557
+ default:
558
+ throw new Error(`Invalid additional info: ${additionalInfo}`);
559
+ }
560
+ };
561
+ const parseFloatFromBuffer = (buffer, offset) => {
562
+ const initialByte = readByte(buffer, offset);
563
+ const { majorType, additionalInfo } = extractCborHeader(initialByte);
564
+ if (majorType !== 7) {
565
+ throw new Error(`Expected major type 7 (simple/float), got ${majorType}`);
566
+ }
567
+ switch (additionalInfo) {
568
+ case 25: {
569
+ if (offset + 2 >= buffer.length) {
570
+ throw new Error("Unexpected end of buffer while reading Float16");
571
+ }
572
+ const value = float16ToFloat64(buffer, offset + 1);
573
+ return { value, bytesRead: 3 };
574
+ }
575
+ case 26: {
576
+ if (offset + 4 >= buffer.length) {
577
+ throw new Error("Unexpected end of buffer while reading Float32");
578
+ }
579
+ const dataView = new DataView(buffer.buffer, buffer.byteOffset + offset + 1, 4);
580
+ const value = dataView.getFloat32(0, false);
581
+ return { value, bytesRead: 5 };
582
+ }
583
+ case 27: {
584
+ if (offset + 8 >= buffer.length) {
585
+ throw new Error("Unexpected end of buffer while reading Float64");
586
+ }
587
+ const dataView = new DataView(buffer.buffer, buffer.byteOffset + offset + 1, 8);
588
+ const value = dataView.getFloat64(0, false);
589
+ return { value, bytesRead: 9 };
590
+ }
591
+ default:
592
+ throw new Error(`Additional info ${additionalInfo} is not a float type`);
593
+ }
594
+ };
595
+ const parseFromBuffer = (buffer, offset) => {
596
+ const initialByte = readByte(buffer, offset);
597
+ const { majorType, additionalInfo } = extractCborHeader(initialByte);
598
+ if (majorType !== 7) {
599
+ throw new Error(`Expected major type 7 (simple/float), got ${majorType}`);
600
+ }
601
+ if (additionalInfo === 25 || additionalInfo === 26 || additionalInfo === 27) {
602
+ return parseFloatFromBuffer(buffer, offset);
603
+ } else {
604
+ return parseSimpleFromBuffer(buffer, offset);
605
+ }
606
+ };
607
+ const parseSimple = (hexString, _options) => {
608
+ const buffer = hexToBytes(hexString);
609
+ return parseSimpleFromBuffer(buffer, 0);
610
+ };
611
+ const parseFloat = (hexString, _options) => {
612
+ const buffer = hexToBytes(hexString);
613
+ return parseFloatFromBuffer(buffer, 0);
614
+ };
615
+ const parse = (hexString, _options) => {
616
+ const buffer = hexToBytes(hexString);
617
+ return parseFromBuffer(buffer, 0);
618
+ };
619
+ return {
620
+ parse,
621
+ parseFloat,
622
+ parseSimple
623
+ };
624
+ }
625
+
626
+ // src/parser/composables/useCborTag.ts
627
+ function useCborTag() {
628
+ const { parseInteger } = useCborInteger();
629
+ const { parseByteString, parseTextString } = useCborString();
630
+ const { parseFloat, parseSimple } = useCborFloat();
631
+ const parseItem = (buffer, offset, options, tagDepth = 0) => {
632
+ if (offset >= buffer.length) {
633
+ throw new Error(`Unexpected end of buffer at offset ${offset}`);
634
+ }
635
+ const initialByte = readByte(buffer, offset);
636
+ const { majorType, additionalInfo } = extractCborHeader(initialByte);
637
+ switch (majorType) {
638
+ case 0:
639
+ // Unsigned integer
640
+ case 1: {
641
+ const intHex = Array.from(buffer.slice(offset)).map((b) => b.toString(16).padStart(2, "0")).join("");
642
+ const result = parseInteger(intHex, options);
643
+ return { value: result.value, bytesRead: result.bytesRead };
644
+ }
645
+ case 2:
646
+ return parseByteString(buffer, offset, options);
647
+ case 3:
648
+ return parseTextString(buffer, offset, options);
649
+ case 4:
650
+ return parseArrayInternal(buffer, offset, options);
651
+ case 5:
652
+ return parseMapInternal(buffer, offset, options);
653
+ case 6:
654
+ return parseTagFromBuffer(buffer, offset, options, tagDepth);
655
+ case 7: {
656
+ const simpleHex = Array.from(buffer.slice(offset)).map((b) => b.toString(16).padStart(2, "0")).join("");
657
+ if (additionalInfo >= 25 && additionalInfo <= 27) {
658
+ const result = parseFloat(simpleHex, options);
659
+ return { value: result.value, bytesRead: result.bytesRead };
660
+ } else {
661
+ const result = parseSimple(simpleHex, options);
662
+ return { value: result.value, bytesRead: result.bytesRead };
663
+ }
664
+ }
665
+ default:
666
+ throw new Error(`Unknown major type: ${majorType}`);
667
+ }
668
+ };
669
+ const parseArrayInternal = (buffer, offset, options) => {
670
+ const initialByte = readByte(buffer, offset);
671
+ const { majorType, additionalInfo } = extractCborHeader(initialByte);
672
+ if (majorType !== 4) {
673
+ throw new Error(`Expected major type 4 (array), got ${majorType}`);
674
+ }
675
+ let length;
676
+ let bytesConsumed;
677
+ if (additionalInfo < 24) {
678
+ length = additionalInfo;
679
+ bytesConsumed = 0;
680
+ } else if (additionalInfo === 24) {
681
+ length = readByte(buffer, offset + 1);
682
+ bytesConsumed = 1;
683
+ } else if (additionalInfo === 25) {
684
+ length = readUint(buffer, offset + 1, 2);
685
+ bytesConsumed = 2;
686
+ } else if (additionalInfo === 26) {
687
+ length = readUint(buffer, offset + 1, 4);
688
+ bytesConsumed = 4;
689
+ } else if (additionalInfo === 27) {
690
+ const lengthBigInt = readBigUint(buffer, offset + 1, 8);
691
+ if (lengthBigInt > BigInt(Number.MAX_SAFE_INTEGER)) {
692
+ throw new Error(`Array length ${lengthBigInt} exceeds maximum safe integer`);
693
+ }
694
+ length = Number(lengthBigInt);
695
+ bytesConsumed = 8;
696
+ } else if (additionalInfo === 31) {
697
+ length = null;
698
+ bytesConsumed = 0;
699
+ } else {
700
+ throw new Error(`Invalid additional info for array: ${additionalInfo}`);
701
+ }
702
+ let currentOffset = offset + 1 + bytesConsumed;
703
+ const items = [];
704
+ if (length === null) {
705
+ while (currentOffset < buffer.length) {
706
+ const nextByte = readByte(buffer, currentOffset);
707
+ if (nextByte === 255) {
708
+ currentOffset++;
709
+ break;
710
+ }
711
+ const itemResult = parseItem(buffer, currentOffset, options);
712
+ items.push(itemResult.value);
713
+ currentOffset += itemResult.bytesRead;
714
+ }
715
+ items[chunkPD72MVTX_cjs.INDEFINITE_SYMBOL] = true;
716
+ } else {
717
+ for (let i = 0; i < length; i++) {
718
+ const itemResult = parseItem(buffer, currentOffset, options);
719
+ items.push(itemResult.value);
720
+ currentOffset += itemResult.bytesRead;
721
+ }
722
+ }
723
+ return {
724
+ value: items,
725
+ bytesRead: currentOffset - offset
726
+ };
727
+ };
728
+ const parseMapInternal = (buffer, offset, options) => {
729
+ const initialByte = readByte(buffer, offset);
730
+ const { majorType, additionalInfo } = extractCborHeader(initialByte);
731
+ if (majorType !== 5) {
732
+ throw new Error(`Expected major type 5 (map), got ${majorType}`);
733
+ }
734
+ let length;
735
+ let bytesConsumed;
736
+ if (additionalInfo < 24) {
737
+ length = additionalInfo;
738
+ bytesConsumed = 0;
739
+ } else if (additionalInfo === 24) {
740
+ length = readByte(buffer, offset + 1);
741
+ bytesConsumed = 1;
742
+ } else if (additionalInfo === 25) {
743
+ length = readUint(buffer, offset + 1, 2);
744
+ bytesConsumed = 2;
745
+ } else if (additionalInfo === 26) {
746
+ length = readUint(buffer, offset + 1, 4);
747
+ bytesConsumed = 4;
748
+ } else if (additionalInfo === 27) {
749
+ const lengthBigInt = readBigUint(buffer, offset + 1, 8);
750
+ if (lengthBigInt > BigInt(Number.MAX_SAFE_INTEGER)) {
751
+ throw new Error(`Map length ${lengthBigInt} exceeds maximum safe integer`);
752
+ }
753
+ length = Number(lengthBigInt);
754
+ bytesConsumed = 8;
755
+ } else if (additionalInfo === 31) {
756
+ length = null;
757
+ bytesConsumed = 0;
758
+ } else {
759
+ throw new Error(`Invalid additional info for map: ${additionalInfo}`);
760
+ }
761
+ let currentOffset = offset + 1 + bytesConsumed;
762
+ const map = /* @__PURE__ */ new Map();
763
+ if (length === null) {
764
+ while (currentOffset < buffer.length) {
765
+ const nextByte = readByte(buffer, currentOffset);
766
+ if (nextByte === 255) {
767
+ currentOffset++;
768
+ break;
769
+ }
770
+ const keyResult = parseItem(buffer, currentOffset, options);
771
+ currentOffset += keyResult.bytesRead;
772
+ const valueResult = parseItem(buffer, currentOffset, options);
773
+ currentOffset += valueResult.bytesRead;
774
+ map.set(keyResult.value, valueResult.value);
775
+ }
776
+ map[chunkPD72MVTX_cjs.INDEFINITE_SYMBOL] = true;
777
+ } else {
778
+ for (let i = 0; i < length; i++) {
779
+ const keyResult = parseItem(buffer, currentOffset, options);
780
+ currentOffset += keyResult.bytesRead;
781
+ const valueResult = parseItem(buffer, currentOffset, options);
782
+ currentOffset += valueResult.bytesRead;
783
+ map.set(keyResult.value, valueResult.value);
784
+ }
785
+ }
786
+ return {
787
+ value: map,
788
+ bytesRead: currentOffset - offset
789
+ };
790
+ };
791
+ const parseTagNumber = (buffer, offset, ai) => {
792
+ if (ai < 24) {
793
+ return { tagNumber: ai, bytesConsumed: 0 };
794
+ } else if (ai === 24) {
795
+ const tagNumber = readByte(buffer, offset);
796
+ return { tagNumber, bytesConsumed: 1 };
797
+ } else if (ai === 25) {
798
+ const tagNumber = readUint(buffer, offset, 2);
799
+ return { tagNumber, bytesConsumed: 2 };
800
+ } else if (ai === 26) {
801
+ const tagNumber = readUint(buffer, offset, 4);
802
+ return { tagNumber, bytesConsumed: 4 };
803
+ } else if (ai === 27) {
804
+ const tagBigInt = readBigUint(buffer, offset, 8);
805
+ if (tagBigInt <= BigInt(Number.MAX_SAFE_INTEGER)) {
806
+ return { tagNumber: Number(tagBigInt), bytesConsumed: 8 };
807
+ } else {
808
+ throw new Error(`Tag number ${tagBigInt} exceeds maximum safe integer`);
809
+ }
810
+ } else if (ai >= 28 && ai <= 30) {
811
+ throw new Error(`Reserved additional info ${ai} for major type 6`);
812
+ } else {
813
+ throw new Error(`Invalid additional info ${ai} for tags`);
814
+ }
815
+ };
816
+ const isValidRfc3339 = (dateStr) => {
817
+ const rfc3339Regex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})?$/i;
818
+ return rfc3339Regex.test(dateStr);
819
+ };
820
+ const isValidUri = (uri) => {
821
+ const uriRegex = /^[a-zA-Z][a-zA-Z0-9+.-]*:/;
822
+ return uriRegex.test(uri);
823
+ };
824
+ const isTextString = (value) => {
825
+ if (typeof value === "string") return true;
826
+ if (value && typeof value === "object" && "type" in value && value.type === "cbor-text-string") {
827
+ return true;
828
+ }
829
+ return false;
830
+ };
831
+ const getTextStringValue = (value) => {
832
+ if (typeof value === "string") return value;
833
+ if (value && typeof value === "object" && "text" in value) {
834
+ return value.text;
835
+ }
836
+ return String(value);
837
+ };
838
+ const validateTagSemantics = (tagNumber, value, options) => {
839
+ const shouldValidateStandard = options?.strict || options?.validateTagSemantics;
840
+ switch (tagNumber) {
841
+ case 0:
842
+ if (!shouldValidateStandard) break;
843
+ if (!isTextString(value)) {
844
+ throw new Error(`Tag 0 (date/time string) must contain a text string, got ${typeof value}`);
845
+ }
846
+ const dateStr = getTextStringValue(value);
847
+ if (!isValidRfc3339(dateStr)) {
848
+ throw new Error(`Tag 0 (date/time string) contains invalid RFC 3339 date format: "${dateStr}"`);
849
+ }
850
+ break;
851
+ case 1:
852
+ if (!shouldValidateStandard) break;
853
+ if (typeof value !== "number" && typeof value !== "bigint") {
854
+ throw new Error(`Tag 1 (epoch time) must contain a number (integer or float), got ${typeof value}`);
855
+ }
856
+ break;
857
+ case 4:
858
+ if (!shouldValidateStandard) break;
859
+ if (!Array.isArray(value)) {
860
+ throw new Error(`Tag 4 (decimal fraction) must contain an array, got ${typeof value}`);
861
+ }
862
+ if (value.length !== 2) {
863
+ throw new Error(`Tag 4 (decimal fraction) array must have exactly 2 elements [exponent, mantissa], got ${value.length}`);
864
+ }
865
+ if (typeof value[0] !== "number" && typeof value[0] !== "bigint") {
866
+ throw new Error(`Tag 4 (decimal fraction) exponent must be an integer, got ${typeof value[0]}`);
867
+ }
868
+ if (typeof value[1] !== "number" && typeof value[1] !== "bigint") {
869
+ throw new Error(`Tag 4 (decimal fraction) mantissa must be an integer, got ${typeof value[1]}`);
870
+ }
871
+ break;
872
+ case 5:
873
+ if (!shouldValidateStandard) break;
874
+ if (!Array.isArray(value)) {
875
+ throw new Error(`Tag 5 (bigfloat) must contain an array, got ${typeof value}`);
876
+ }
877
+ if (value.length !== 2) {
878
+ throw new Error(`Tag 5 (bigfloat) array must have exactly 2 elements [exponent, mantissa], got ${value.length}`);
879
+ }
880
+ if (typeof value[0] !== "number" && typeof value[0] !== "bigint") {
881
+ throw new Error(`Tag 5 (bigfloat) exponent must be an integer, got ${typeof value[0]}`);
882
+ }
883
+ if (typeof value[1] !== "number" && typeof value[1] !== "bigint") {
884
+ throw new Error(`Tag 5 (bigfloat) mantissa must be an integer, got ${typeof value[1]}`);
885
+ }
886
+ break;
887
+ case 32:
888
+ if (!shouldValidateStandard) break;
889
+ if (!isTextString(value)) {
890
+ throw new Error(`Tag 32 (URI) must contain a text string, got ${typeof value}`);
891
+ }
892
+ const uriStr = getTextStringValue(value);
893
+ if (!isValidUri(uriStr)) {
894
+ throw new Error(`Tag 32 (URI) contains invalid URI format (missing scheme): "${uriStr}"`);
895
+ }
896
+ break;
897
+ case 33:
898
+ // base64url without padding
899
+ case 34:
900
+ if (!shouldValidateStandard) break;
901
+ if (!isTextString(value)) {
902
+ throw new Error(`Tag ${tagNumber} (base64${tagNumber === 33 ? "url" : ""}) must contain a text string, got ${typeof value}`);
903
+ }
904
+ break;
905
+ case 35:
906
+ if (!shouldValidateStandard) break;
907
+ if (!isTextString(value)) {
908
+ throw new Error(`Tag 35 (regexp) must contain a text string, got ${typeof value}`);
909
+ }
910
+ break;
911
+ case 36:
912
+ if (!shouldValidateStandard) break;
913
+ if (!isTextString(value)) {
914
+ throw new Error(`Tag 36 (MIME message) must contain a text string, got ${typeof value}`);
915
+ }
916
+ break;
917
+ case 258:
918
+ {
919
+ const shouldValidateUniqueness = options?.strict || options?.validateSetUniqueness;
920
+ if (shouldValidateUniqueness) {
921
+ if (!Array.isArray(value)) {
922
+ throw new Error(`Tag 258 (set) must contain an array, got ${typeof value}`);
923
+ }
924
+ if (hasDuplicates(value)) {
925
+ throw new Error(
926
+ `Tag 258 (set) contains duplicate items. Sets must contain only unique values (RFC 8949). Use validateSetUniqueness: false to allow duplicates.`
927
+ );
928
+ }
929
+ }
930
+ }
931
+ break;
932
+ // Plutus Constructor tags
933
+ case 102:
934
+ validatePlutusAlternativeConstructor(value, options);
935
+ break;
936
+ // No validation needed for other tags (yet)
937
+ default:
938
+ if (tagNumber >= 121 && tagNumber <= 127) {
939
+ validatePlutusCompactConstructor(tagNumber, value, options);
940
+ } else if (tagNumber >= 1280 && tagNumber <= 1400) {
941
+ validatePlutusExtendedConstructor(tagNumber, value, options);
942
+ }
943
+ break;
944
+ }
945
+ };
946
+ const validatePlutusCompactConstructor = (tagNumber, value, options) => {
947
+ const shouldValidate = options?.strict || options?.validatePlutusSemantics;
948
+ if (!shouldValidate) {
949
+ return;
950
+ }
951
+ if (!Array.isArray(value)) {
952
+ throw new Error(
953
+ `Plutus constructor tag ${tagNumber} must contain an array, got ${typeof value}`
954
+ );
955
+ }
956
+ };
957
+ const validatePlutusAlternativeConstructor = (value, options) => {
958
+ const shouldValidate = options?.strict || options?.validatePlutusSemantics;
959
+ if (!shouldValidate) {
960
+ return;
961
+ }
962
+ if (!Array.isArray(value)) {
963
+ throw new Error(
964
+ `Plutus alternative constructor (tag 102) must contain an array, got ${typeof value}`
965
+ );
966
+ }
967
+ if (value.length !== 2) {
968
+ throw new Error(
969
+ `Plutus alternative constructor (tag 102) must be [constructor_index, fields], got array of length ${value.length}`
970
+ );
971
+ }
972
+ const constructorIndex = value[0];
973
+ const fields = value[1];
974
+ if (typeof constructorIndex !== "number" || constructorIndex < 0 || !Number.isInteger(constructorIndex)) {
975
+ throw new Error(
976
+ `Plutus constructor index must be non-negative integer, got ${typeof constructorIndex}`
977
+ );
978
+ }
979
+ if (!Array.isArray(fields)) {
980
+ throw new Error(
981
+ `Plutus constructor fields must be an array, got ${typeof fields}`
982
+ );
983
+ }
984
+ };
985
+ const validatePlutusExtendedConstructor = (tagNumber, value, options) => {
986
+ const shouldValidate = options?.strict || options?.validatePlutusSemantics;
987
+ if (!shouldValidate) {
988
+ return;
989
+ }
990
+ if (!Array.isArray(value)) {
991
+ throw new Error(
992
+ `Plutus constructor tag ${tagNumber} must contain an array, got ${typeof value}`
993
+ );
994
+ }
995
+ const constructorIndex = tagNumber - 1280 + 7;
996
+ if (constructorIndex < 7 || constructorIndex > 127) {
997
+ throw new Error(
998
+ `Plutus extended constructor tag ${tagNumber} produces invalid constructor index ${constructorIndex} (expected 7-127)`
999
+ );
1000
+ }
1001
+ };
1002
+ const decodePlutusConstructor = (tagNumber, value) => {
1003
+ if (tagNumber === 102) {
1004
+ if (!Array.isArray(value) || value.length !== 2) {
1005
+ return null;
1006
+ }
1007
+ const [constructorIndex, fields] = value;
1008
+ if (typeof constructorIndex !== "number" || !Array.isArray(fields)) {
1009
+ return null;
1010
+ }
1011
+ return {
1012
+ constructor: constructorIndex,
1013
+ fields
1014
+ };
1015
+ }
1016
+ if (tagNumber >= 121 && tagNumber <= 127) {
1017
+ if (!Array.isArray(value)) {
1018
+ return null;
1019
+ }
1020
+ const constructorIndex = tagNumber - 121;
1021
+ return {
1022
+ constructor: constructorIndex,
1023
+ fields: value
1024
+ };
1025
+ }
1026
+ if (tagNumber >= 1280 && tagNumber <= 1400) {
1027
+ if (!Array.isArray(value)) {
1028
+ return null;
1029
+ }
1030
+ const constructorIndex = tagNumber - 1280 + 7;
1031
+ return {
1032
+ constructor: constructorIndex,
1033
+ fields: value
1034
+ };
1035
+ }
1036
+ return null;
1037
+ };
1038
+ const parseTagFromBuffer = (buffer, offset, options, tagDepth = 0) => {
1039
+ const initialByte = readByte(buffer, offset);
1040
+ const { majorType, additionalInfo } = extractCborHeader(initialByte);
1041
+ if (majorType !== 6) {
1042
+ throw new Error(`Expected major type 6 (tag), got ${majorType}`);
1043
+ }
1044
+ const maxTagDepth = options?.limits?.maxTagDepth ?? 64;
1045
+ if (tagDepth >= maxTagDepth) {
1046
+ throw new Error(`Tag nesting depth ${tagDepth} exceeds limit of ${maxTagDepth}`);
1047
+ }
1048
+ const { tagNumber, bytesConsumed } = parseTagNumber(buffer, offset + 1, additionalInfo);
1049
+ let currentOffset = offset + 1 + bytesConsumed;
1050
+ if (currentOffset >= buffer.length) {
1051
+ throw new Error(`Unexpected end of buffer after tag ${tagNumber}`);
1052
+ }
1053
+ const valueResult = parseItem(buffer, currentOffset, options, tagDepth + 1);
1054
+ currentOffset += valueResult.bytesRead;
1055
+ if ((tagNumber === 2 || tagNumber === 3) && valueResult.value instanceof Uint8Array) {
1056
+ const maxBignumBytes = options?.limits?.maxBignumBytes ?? 1024;
1057
+ if (valueResult.value.length > maxBignumBytes) {
1058
+ throw new Error(
1059
+ `Bignum (tag ${tagNumber}) size ${valueResult.value.length} bytes exceeds limit of ${maxBignumBytes} bytes`
1060
+ );
1061
+ }
1062
+ const bytes = valueResult.value;
1063
+ let bigintValue = 0n;
1064
+ for (let i = 0; i < bytes.length; i++) {
1065
+ bigintValue = bigintValue << 8n | BigInt(bytes[i]);
1066
+ }
1067
+ if (tagNumber === 2) {
1068
+ valueResult.value = bigintValue;
1069
+ } else if (tagNumber === 3) {
1070
+ valueResult.value = -1n - bigintValue;
1071
+ }
1072
+ }
1073
+ validateTagSemantics(tagNumber, valueResult.value, options);
1074
+ const plutusConstr = decodePlutusConstructor(tagNumber, valueResult.value);
1075
+ const taggedValue = {
1076
+ tag: tagNumber,
1077
+ value: valueResult.value,
1078
+ ...plutusConstr && { plutus: plutusConstr }
1079
+ };
1080
+ return {
1081
+ value: taggedValue,
1082
+ bytesRead: currentOffset - offset
1083
+ };
1084
+ };
1085
+ const parseTag = (hexString, options) => {
1086
+ const cleanHex = hexString.replace(/\s+/g, "");
1087
+ const buffer = hexToBytes(cleanHex);
1088
+ return parseTagFromBuffer(buffer, 0, options);
1089
+ };
1090
+ const parse = parseTag;
1091
+ return {
1092
+ parseTag,
1093
+ parse
1094
+ };
1095
+ }
1096
+
1097
+ // src/utils/logger.ts
1098
+ var LOG_LEVELS = {
1099
+ debug: 0,
1100
+ info: 1,
1101
+ warn: 2,
1102
+ error: 3,
1103
+ silent: 4
1104
+ };
1105
+ var config = {
1106
+ level: "warn",
1107
+ prefix: "[CBOR]"
1108
+ };
1109
+ function configureLogger(newConfig) {
1110
+ config = { ...config, ...newConfig };
1111
+ }
1112
+ function getLoggerConfig() {
1113
+ return { ...config };
1114
+ }
1115
+ function shouldLog(level) {
1116
+ return LOG_LEVELS[level] >= LOG_LEVELS[config.level];
1117
+ }
1118
+ function formatMessage(message) {
1119
+ return config.prefix ? `${config.prefix} ${message}` : message;
1120
+ }
1121
+ function debug(message, ...args) {
1122
+ if (shouldLog("debug")) {
1123
+ console.debug(formatMessage(message), ...args);
1124
+ }
1125
+ }
1126
+ function info(message, ...args) {
1127
+ if (shouldLog("info")) {
1128
+ console.info(formatMessage(message), ...args);
1129
+ }
1130
+ }
1131
+ function warn(message, ...args) {
1132
+ if (shouldLog("warn")) {
1133
+ console.warn(formatMessage(message), ...args);
1134
+ }
1135
+ }
1136
+ function error(message, ...args) {
1137
+ if (shouldLog("error")) {
1138
+ console.error(formatMessage(message), ...args);
1139
+ }
1140
+ }
1141
+ var logger = {
1142
+ debug,
1143
+ info,
1144
+ warn,
1145
+ error,
1146
+ configure: configureLogger,
1147
+ getConfig: getLoggerConfig
1148
+ };
1149
+
1150
+ // src/parser/composables/useCborCollection.ts
1151
+ function useCborCollection() {
1152
+ const { parseInteger } = useCborInteger();
1153
+ const { parseByteString, parseTextString } = useCborString();
1154
+ const { parse: parseFloatOrSimple } = useCborFloat();
1155
+ const { parseTag } = useCborTag();
1156
+ const convertKeyToString = (key) => {
1157
+ if (key instanceof Uint8Array) {
1158
+ return bytesToHex(key);
1159
+ }
1160
+ return String(key);
1161
+ };
1162
+ const parseItem = (buffer, offset, options, depth = 0) => {
1163
+ if (offset >= buffer.length) {
1164
+ throw new Error(`Unexpected end of buffer at offset ${offset}`);
1165
+ }
1166
+ const initialByte = readByte(buffer, offset);
1167
+ const { majorType } = extractCborHeader(initialByte);
1168
+ switch (majorType) {
1169
+ case 0:
1170
+ // Unsigned integer
1171
+ case 1: {
1172
+ const intHex = Array.from(buffer.slice(offset)).map((b) => b.toString(16).padStart(2, "0")).join("");
1173
+ const result = parseInteger(intHex, options);
1174
+ return { value: result.value, bytesRead: result.bytesRead };
1175
+ }
1176
+ case 2:
1177
+ return parseByteString(buffer, offset, options);
1178
+ case 3:
1179
+ return parseTextString(buffer, offset, options);
1180
+ case 4:
1181
+ return parseArrayFromBuffer(buffer, offset, options, depth);
1182
+ case 5:
1183
+ return parseMapFromBuffer(buffer, offset, options, depth);
1184
+ case 6: {
1185
+ const tagHex = Array.from(buffer.slice(offset)).map((b) => b.toString(16).padStart(2, "0")).join("");
1186
+ const result = parseTag(tagHex, options);
1187
+ return { value: result.value, bytesRead: result.bytesRead };
1188
+ }
1189
+ case 7: {
1190
+ const floatHex = Array.from(buffer.slice(offset)).map((b) => b.toString(16).padStart(2, "0")).join("");
1191
+ const result = parseFloatOrSimple(floatHex, options);
1192
+ return { value: result.value, bytesRead: result.bytesRead };
1193
+ }
1194
+ default:
1195
+ throw new Error(`Unknown major type: ${majorType}`);
1196
+ }
1197
+ };
1198
+ const parseLength = (buffer, offset, ai, options) => {
1199
+ if (ai < 24) {
1200
+ return { length: ai, bytesConsumed: 0 };
1201
+ } else if (ai === 24) {
1202
+ const length = readByte(buffer, offset);
1203
+ if (options?.validateCanonical && length < 24) {
1204
+ throw new Error(`Non-canonical length encoding: ${length} should use direct encoding (AI < 24), not AI=24`);
1205
+ }
1206
+ return { length, bytesConsumed: 1 };
1207
+ } else if (ai === 25) {
1208
+ const length = readUint(buffer, offset, 2);
1209
+ if (options?.validateCanonical && length < 256) {
1210
+ throw new Error(`Non-canonical length encoding: ${length} should use ${length < 24 ? "direct encoding" : "1-byte encoding (AI=24)"}, not AI=25`);
1211
+ }
1212
+ return { length, bytesConsumed: 2 };
1213
+ } else if (ai === 26) {
1214
+ const length = readUint(buffer, offset, 4);
1215
+ if (options?.validateCanonical && length < 65536) {
1216
+ throw new Error(`Non-canonical length encoding: ${length} should use shorter encoding, not AI=26`);
1217
+ }
1218
+ return { length, bytesConsumed: 4 };
1219
+ } else if (ai === 27) {
1220
+ const lengthBigInt = readBigUint(buffer, offset, 8);
1221
+ if (lengthBigInt > BigInt(Number.MAX_SAFE_INTEGER)) {
1222
+ throw new Error(`Collection length ${lengthBigInt} exceeds maximum safe integer`);
1223
+ }
1224
+ const length = Number(lengthBigInt);
1225
+ if (options?.validateCanonical && length < 4294967296) {
1226
+ throw new Error(`Non-canonical length encoding: ${length} should use shorter encoding, not AI=27`);
1227
+ }
1228
+ return { length, bytesConsumed: 8 };
1229
+ } else if (ai === 31) {
1230
+ return { length: null, bytesConsumed: 0 };
1231
+ } else {
1232
+ throw new Error(`Invalid additional info: ${ai}`);
1233
+ }
1234
+ };
1235
+ const parseArrayFromBuffer = (buffer, offset, options, depth = 0) => {
1236
+ const initialByte = readByte(buffer, offset);
1237
+ const { majorType, additionalInfo } = extractCborHeader(initialByte);
1238
+ if (majorType !== 4) {
1239
+ throw new Error(`Expected major type 4 (array), got ${majorType}`);
1240
+ }
1241
+ const isIndefiniteAllowed = options?.allowIndefinite ?? !(options?.validateCanonical || options?.strict);
1242
+ if (additionalInfo === 31 && !isIndefiniteAllowed) {
1243
+ throw new Error("Indefinite-length encoding is not allowed (strict/canonical mode)");
1244
+ }
1245
+ if (options?.limits?.maxDepth && depth >= options.limits.maxDepth) {
1246
+ throw new Error(`Maximum nesting depth ${options.limits.maxDepth} exceeded`);
1247
+ }
1248
+ const { length, bytesConsumed } = parseLength(buffer, offset + 1, additionalInfo, options);
1249
+ let currentOffset = offset + 1 + bytesConsumed;
1250
+ const items = [];
1251
+ if (length === null) {
1252
+ let index = 0;
1253
+ let foundBreak = false;
1254
+ while (currentOffset < buffer.length) {
1255
+ const nextByte = readByte(buffer, currentOffset);
1256
+ if (nextByte === 255) {
1257
+ currentOffset++;
1258
+ foundBreak = true;
1259
+ break;
1260
+ }
1261
+ if (options?.limits?.maxArrayLength && index >= options.limits.maxArrayLength) {
1262
+ throw new Error(`Array length exceeds limit of ${options.limits.maxArrayLength}`);
1263
+ }
1264
+ const itemResult = parseItem(buffer, currentOffset, options, depth + 1);
1265
+ items.push(itemResult.value);
1266
+ currentOffset += itemResult.bytesRead;
1267
+ index++;
1268
+ }
1269
+ if (!foundBreak) {
1270
+ throw new Error("Indefinite-length array missing break code (0xFF)");
1271
+ }
1272
+ items[chunkPD72MVTX_cjs.INDEFINITE_SYMBOL] = true;
1273
+ } else {
1274
+ if (options?.limits?.maxArrayLength && length > options.limits.maxArrayLength) {
1275
+ throw new Error(`Array length ${length} exceeds limit of ${options.limits.maxArrayLength}`);
1276
+ }
1277
+ for (let i = 0; i < length; i++) {
1278
+ if (currentOffset >= buffer.length) {
1279
+ throw new Error(`Unexpected end of buffer while parsing array element ${i}/${length}`);
1280
+ }
1281
+ const itemResult = parseItem(buffer, currentOffset, options, depth + 1);
1282
+ items.push(itemResult.value);
1283
+ currentOffset += itemResult.bytesRead;
1284
+ }
1285
+ }
1286
+ return {
1287
+ value: items,
1288
+ bytesRead: currentOffset - offset
1289
+ };
1290
+ };
1291
+ const parseMapFromBuffer = (buffer, offset, options, depth = 0) => {
1292
+ const initialByte = readByte(buffer, offset);
1293
+ const { majorType, additionalInfo } = extractCborHeader(initialByte);
1294
+ if (majorType !== 5) {
1295
+ throw new Error(`Expected major type 5 (map), got ${majorType}`);
1296
+ }
1297
+ const isIndefiniteAllowed = options?.allowIndefinite ?? !(options?.validateCanonical || options?.strict);
1298
+ if (additionalInfo === 31 && !isIndefiniteAllowed) {
1299
+ throw new Error("Indefinite-length encoding is not allowed (strict/canonical mode)");
1300
+ }
1301
+ if (options?.limits?.maxDepth && depth >= options.limits.maxDepth) {
1302
+ throw new Error(`Maximum nesting depth ${options.limits.maxDepth} exceeded`);
1303
+ }
1304
+ const { length, bytesConsumed } = parseLength(buffer, offset + 1, additionalInfo, options);
1305
+ let currentOffset = offset + 1 + bytesConsumed;
1306
+ const map = /* @__PURE__ */ new Map();
1307
+ const seenKeys = /* @__PURE__ */ new Set();
1308
+ const keyBytes = [];
1309
+ const allEntries = [];
1310
+ if (length === null) {
1311
+ let index = 0;
1312
+ let foundBreak = false;
1313
+ while (currentOffset < buffer.length) {
1314
+ const nextByte = readByte(buffer, currentOffset);
1315
+ if (nextByte === 255) {
1316
+ currentOffset++;
1317
+ foundBreak = true;
1318
+ break;
1319
+ }
1320
+ if (options?.limits?.maxMapSize && index >= options.limits.maxMapSize) {
1321
+ throw new Error(`Map size exceeds limit of ${options.limits.maxMapSize}`);
1322
+ }
1323
+ const keyStart = currentOffset;
1324
+ const keyResult = parseItem(buffer, currentOffset, options, depth + 1);
1325
+ const keyEnd = currentOffset + keyResult.bytesRead;
1326
+ currentOffset += keyResult.bytesRead;
1327
+ if (options?.validateCanonical) {
1328
+ keyBytes.push(buffer.slice(keyStart, keyEnd));
1329
+ }
1330
+ if (currentOffset >= buffer.length) {
1331
+ throw new Error("Unexpected end of buffer while parsing map value");
1332
+ }
1333
+ const valueResult = parseItem(buffer, currentOffset, options, depth + 1);
1334
+ currentOffset += valueResult.bytesRead;
1335
+ const keyString = convertKeyToString(keyResult.value);
1336
+ if (seenKeys.has(keyString)) {
1337
+ const mode = options?.dupMapKeyMode || "allow";
1338
+ if (mode === "reject") {
1339
+ throw new Error(`Duplicate map key detected: ${keyString} at offset ${keyStart}`);
1340
+ } else if (mode === "warn") {
1341
+ logger.warn(`Duplicate map key detected: ${keyString} at offset ${keyStart}`);
1342
+ }
1343
+ }
1344
+ seenKeys.add(keyString);
1345
+ map.set(keyResult.value, valueResult.value);
1346
+ allEntries.push([keyResult.value, valueResult.value]);
1347
+ index++;
1348
+ }
1349
+ if (!foundBreak) {
1350
+ throw new Error("Indefinite-length map missing break code (0xFF)");
1351
+ }
1352
+ map[chunkPD72MVTX_cjs.INDEFINITE_SYMBOL] = true;
1353
+ } else {
1354
+ if (options?.limits?.maxMapSize && length > options.limits.maxMapSize) {
1355
+ throw new Error(`Map size ${length} exceeds limit of ${options.limits.maxMapSize}`);
1356
+ }
1357
+ for (let i = 0; i < length; i++) {
1358
+ if (currentOffset >= buffer.length) {
1359
+ throw new Error(`Unexpected end of buffer while parsing map entry ${i}/${length}`);
1360
+ }
1361
+ const keyStart = currentOffset;
1362
+ const keyResult = parseItem(buffer, currentOffset, options, depth + 1);
1363
+ const keyEnd = currentOffset + keyResult.bytesRead;
1364
+ currentOffset += keyResult.bytesRead;
1365
+ if (options?.validateCanonical) {
1366
+ keyBytes.push(buffer.slice(keyStart, keyEnd));
1367
+ }
1368
+ if (currentOffset >= buffer.length) {
1369
+ throw new Error(`Unexpected end of buffer while parsing map value for entry ${i}/${length}`);
1370
+ }
1371
+ const valueResult = parseItem(buffer, currentOffset, options, depth + 1);
1372
+ currentOffset += valueResult.bytesRead;
1373
+ const keyString = convertKeyToString(keyResult.value);
1374
+ if (seenKeys.has(keyString)) {
1375
+ const mode = options?.dupMapKeyMode || "allow";
1376
+ if (mode === "reject") {
1377
+ throw new Error(`Duplicate map key detected: ${keyString} at offset ${keyStart}`);
1378
+ } else if (mode === "warn") {
1379
+ logger.warn(`Duplicate map key detected: ${keyString} at offset ${keyStart}`);
1380
+ }
1381
+ }
1382
+ seenKeys.add(keyString);
1383
+ map.set(keyResult.value, valueResult.value);
1384
+ allEntries.push([keyResult.value, valueResult.value]);
1385
+ }
1386
+ }
1387
+ map[chunkPD72MVTX_cjs.ALL_ENTRIES_SYMBOL] = allEntries;
1388
+ if (options?.validateCanonical && keyBytes.length > 1) {
1389
+ for (let i = 1; i < keyBytes.length; i++) {
1390
+ const prevKey = keyBytes[i - 1];
1391
+ const currKey = keyBytes[i];
1392
+ if (prevKey && currKey) {
1393
+ const cmp = compareBytes(prevKey, currKey);
1394
+ if (cmp > 0) {
1395
+ throw new Error(
1396
+ `Map keys are not in canonical order: key at index ${i} should come before key at index ${i - 1}`
1397
+ );
1398
+ }
1399
+ if (cmp === 0) {
1400
+ throw new Error(`Duplicate map keys detected in canonical validation`);
1401
+ }
1402
+ }
1403
+ }
1404
+ }
1405
+ return {
1406
+ value: map,
1407
+ bytesRead: currentOffset - offset
1408
+ };
1409
+ };
1410
+ const parseArray = (hexString, options) => {
1411
+ const cleanHex = hexString.replace(/\s+/g, "");
1412
+ const buffer = hexToBytes(cleanHex);
1413
+ return parseArrayFromBuffer(buffer, 0, options, 0);
1414
+ };
1415
+ const parseMap = (hexString, options) => {
1416
+ const cleanHex = hexString.replace(/\s+/g, "");
1417
+ const buffer = hexToBytes(cleanHex);
1418
+ return parseMapFromBuffer(buffer, 0, options, 0);
1419
+ };
1420
+ return {
1421
+ parseArray,
1422
+ parseMap
1423
+ };
1424
+ }
1425
+
1426
+ // src/parser/composables/useCborParser.ts
1427
+ function useCborParser() {
1428
+ const mergeOptions = (options) => {
1429
+ if (!options) return chunkPD72MVTX_cjs.DEFAULT_OPTIONS;
1430
+ const isCanonical = options.validateCanonical ?? (options.strict ? true : false);
1431
+ return {
1432
+ strict: options.strict ?? chunkPD72MVTX_cjs.DEFAULT_OPTIONS.strict,
1433
+ validateCanonical: isCanonical,
1434
+ // RFC 8949 Section 4.2: Deterministic encoding MUST NOT use indefinite-length
1435
+ allowIndefinite: options.allowIndefinite ?? (isCanonical || options.strict ? false : chunkPD72MVTX_cjs.DEFAULT_OPTIONS.allowIndefinite),
1436
+ // Auto-enable duplicate key rejection for canonical or strict mode
1437
+ dupMapKeyMode: options.dupMapKeyMode ?? (isCanonical || options.strict ? "reject" : chunkPD72MVTX_cjs.DEFAULT_OPTIONS.dupMapKeyMode),
1438
+ validateUtf8Strict: options.validateUtf8Strict ?? (options.strict ? true : chunkPD72MVTX_cjs.DEFAULT_OPTIONS.validateUtf8Strict),
1439
+ validateSetUniqueness: options.validateSetUniqueness ?? (options.strict ? true : chunkPD72MVTX_cjs.DEFAULT_OPTIONS.validateSetUniqueness),
1440
+ validateTagSemantics: options.validateTagSemantics ?? (options.strict ? true : chunkPD72MVTX_cjs.DEFAULT_OPTIONS.validateTagSemantics),
1441
+ validatePlutusSemantics: options.validatePlutusSemantics ?? (options.strict ? true : chunkPD72MVTX_cjs.DEFAULT_OPTIONS.validatePlutusSemantics),
1442
+ limits: {
1443
+ maxInputSize: options.limits?.maxInputSize ?? chunkPD72MVTX_cjs.DEFAULT_LIMITS.maxInputSize,
1444
+ maxOutputSize: options.limits?.maxOutputSize ?? chunkPD72MVTX_cjs.DEFAULT_LIMITS.maxOutputSize,
1445
+ maxStringLength: options.limits?.maxStringLength ?? chunkPD72MVTX_cjs.DEFAULT_LIMITS.maxStringLength,
1446
+ maxArrayLength: options.limits?.maxArrayLength ?? chunkPD72MVTX_cjs.DEFAULT_LIMITS.maxArrayLength,
1447
+ maxMapSize: options.limits?.maxMapSize ?? chunkPD72MVTX_cjs.DEFAULT_LIMITS.maxMapSize,
1448
+ maxDepth: options.limits?.maxDepth ?? chunkPD72MVTX_cjs.DEFAULT_LIMITS.maxDepth,
1449
+ maxTagDepth: options.limits?.maxTagDepth ?? chunkPD72MVTX_cjs.DEFAULT_LIMITS.maxTagDepth,
1450
+ maxBignumBytes: options.limits?.maxBignumBytes ?? chunkPD72MVTX_cjs.DEFAULT_LIMITS.maxBignumBytes,
1451
+ maxParseTime: options.limits?.maxParseTime ?? chunkPD72MVTX_cjs.DEFAULT_LIMITS.maxParseTime
1452
+ }
1453
+ };
1454
+ };
1455
+ const checkTimeout = (ctx) => {
1456
+ if (!ctx.startTime || !ctx.options?.limits?.maxParseTime) return;
1457
+ const elapsed = Date.now() - ctx.startTime;
1458
+ if (elapsed > ctx.options.limits.maxParseTime) {
1459
+ throw new Error(`Parse timeout: exceeded ${ctx.options.limits.maxParseTime}ms limit (elapsed: ${elapsed}ms)`);
1460
+ }
1461
+ };
1462
+ const { parseInteger } = useCborInteger();
1463
+ const { parseString } = useCborString();
1464
+ const { parseArray, parseMap } = useCborCollection();
1465
+ const { parseTag } = useCborTag();
1466
+ const { parse: parseFloatOrSimple } = useCborFloat();
1467
+ const parse = (hexString, options) => {
1468
+ const cleanHex = hexString.replace(/\s+/g, "");
1469
+ if (!cleanHex || cleanHex.length === 0) {
1470
+ throw new Error("Empty hex string");
1471
+ }
1472
+ if (cleanHex.length % 2 !== 0) {
1473
+ throw new Error("Hex string must have even length");
1474
+ }
1475
+ if (!/^[0-9a-fA-F]+$/.test(cleanHex)) {
1476
+ throw new Error(`Invalid hex character in: ${cleanHex}`);
1477
+ }
1478
+ const mergedOptions = mergeOptions(options);
1479
+ const inputSize = cleanHex.length / 2;
1480
+ if (mergedOptions.limits?.maxInputSize && inputSize > mergedOptions.limits.maxInputSize) {
1481
+ throw new Error(`Input size ${inputSize} bytes exceeds limit of ${mergedOptions.limits.maxInputSize} bytes`);
1482
+ }
1483
+ const buffer = hexToBytes(cleanHex);
1484
+ const initialByte = readByte(buffer, 0);
1485
+ const { majorType } = extractCborHeader(initialByte);
1486
+ switch (majorType) {
1487
+ case 0:
1488
+ // Unsigned integer
1489
+ case 1:
1490
+ return parseInteger(cleanHex, mergedOptions);
1491
+ case 2:
1492
+ // Byte string
1493
+ case 3:
1494
+ return parseString(cleanHex, mergedOptions);
1495
+ case 4:
1496
+ return parseArray(cleanHex, mergedOptions);
1497
+ case 5:
1498
+ return parseMap(cleanHex, mergedOptions);
1499
+ case 6:
1500
+ return parseTag(cleanHex, mergedOptions);
1501
+ case 7:
1502
+ return parseFloatOrSimple(cleanHex, mergedOptions);
1503
+ default:
1504
+ throw new Error(`Unknown major type: ${majorType}`);
1505
+ }
1506
+ };
1507
+ const parseWithSourceMap = (hexString, options) => {
1508
+ const cleanHex = hexString.replace(/\s+/g, "");
1509
+ if (!cleanHex || cleanHex.length === 0) {
1510
+ throw new Error("Empty hex string");
1511
+ }
1512
+ if (cleanHex.length % 2 !== 0) {
1513
+ throw new Error("Hex string must have even length");
1514
+ }
1515
+ if (!/^[0-9a-fA-F]+$/.test(cleanHex)) {
1516
+ throw new Error(`Invalid hex character in: ${cleanHex}`);
1517
+ }
1518
+ const mergedOptions = mergeOptions(options);
1519
+ const inputSize = cleanHex.length / 2;
1520
+ if (mergedOptions.limits?.maxInputSize && inputSize > mergedOptions.limits.maxInputSize) {
1521
+ throw new Error(`Input size ${inputSize} bytes exceeds limit of ${mergedOptions.limits.maxInputSize} bytes`);
1522
+ }
1523
+ const buffer = hexToBytes(cleanHex);
1524
+ const sourceMap = [];
1525
+ const ctx = {
1526
+ buffer,
1527
+ startTime: Date.now(),
1528
+ bytesAllocated: 0,
1529
+ options: mergedOptions
1530
+ };
1531
+ const result = parseValueWithMap(ctx, 0, "", sourceMap);
1532
+ return {
1533
+ value: result.value,
1534
+ bytesRead: result.bytesRead,
1535
+ sourceMap
1536
+ };
1537
+ };
1538
+ const parseValueWithMap = (ctx, offset, path, sourceMap) => {
1539
+ checkTimeout(ctx);
1540
+ const initialByte = readByte(ctx.buffer, offset);
1541
+ const { majorType, additionalInfo } = extractCborHeader(initialByte);
1542
+ const startOffset = offset;
1543
+ let result;
1544
+ let typeDescription;
1545
+ switch (majorType) {
1546
+ case 0:
1547
+ typeDescription = "Unsigned Integer";
1548
+ result = parseIntegerFromBuffer(ctx.buffer, offset, ctx.options);
1549
+ sourceMap.push({
1550
+ path,
1551
+ start: startOffset,
1552
+ end: startOffset + result.bytesRead,
1553
+ majorType,
1554
+ type: typeDescription
1555
+ });
1556
+ break;
1557
+ case 1:
1558
+ typeDescription = "Negative Integer";
1559
+ result = parseIntegerFromBuffer(ctx.buffer, offset, ctx.options);
1560
+ sourceMap.push({
1561
+ path,
1562
+ start: startOffset,
1563
+ end: startOffset + result.bytesRead,
1564
+ majorType,
1565
+ type: typeDescription
1566
+ });
1567
+ break;
1568
+ case 2:
1569
+ {
1570
+ result = parseStringFromBuffer(ctx.buffer, offset, ctx.options);
1571
+ if (ctx.bytesAllocated !== void 0 && result.value instanceof Uint8Array) {
1572
+ ctx.bytesAllocated += result.value.length;
1573
+ if (ctx.options?.limits?.maxOutputSize && ctx.bytesAllocated > ctx.options.limits.maxOutputSize) {
1574
+ throw new Error(`Output size ${ctx.bytesAllocated} bytes exceeds limit of ${ctx.options.limits.maxOutputSize} bytes`);
1575
+ }
1576
+ }
1577
+ const headerBytes = additionalInfo < 24 ? 1 : additionalInfo === 24 ? 2 : additionalInfo === 25 ? 3 : additionalInfo === 26 ? 5 : additionalInfo === 27 ? 9 : 1;
1578
+ const headerEnd = startOffset + headerBytes;
1579
+ const contentLength = result.value instanceof Uint8Array ? result.value.length : 0;
1580
+ typeDescription = `bytes(${contentLength})`;
1581
+ sourceMap.push({
1582
+ path,
1583
+ start: startOffset,
1584
+ end: headerEnd,
1585
+ majorType,
1586
+ type: typeDescription,
1587
+ isHeader: true,
1588
+ headerEnd,
1589
+ contentPath: contentLength > 0 ? `${path}#content` : void 0,
1590
+ children: contentLength > 0 ? [`${path}#content`] : []
1591
+ });
1592
+ if (contentLength > 0) {
1593
+ sourceMap.push({
1594
+ path: `${path}#content`,
1595
+ start: headerEnd,
1596
+ end: startOffset + result.bytesRead,
1597
+ majorType: 2,
1598
+ type: `\u2192 ${contentLength} bytes`,
1599
+ isContent: true,
1600
+ parent: path
1601
+ });
1602
+ }
1603
+ }
1604
+ break;
1605
+ case 3:
1606
+ {
1607
+ result = parseStringFromBuffer(ctx.buffer, offset, ctx.options);
1608
+ if (ctx.bytesAllocated !== void 0 && typeof result.value === "string") {
1609
+ ctx.bytesAllocated += result.value.length;
1610
+ if (ctx.options?.limits?.maxOutputSize && ctx.bytesAllocated > ctx.options.limits.maxOutputSize) {
1611
+ throw new Error(`Output size ${ctx.bytesAllocated} bytes exceeds limit of ${ctx.options.limits.maxOutputSize} bytes`);
1612
+ }
1613
+ }
1614
+ const headerBytes = additionalInfo < 24 ? 1 : additionalInfo === 24 ? 2 : additionalInfo === 25 ? 3 : additionalInfo === 26 ? 5 : additionalInfo === 27 ? 9 : 1;
1615
+ const headerEnd = startOffset + headerBytes;
1616
+ const contentLength = typeof result.value === "string" ? result.value.length : 0;
1617
+ typeDescription = `text(${contentLength})`;
1618
+ sourceMap.push({
1619
+ path,
1620
+ start: startOffset,
1621
+ end: headerEnd,
1622
+ majorType,
1623
+ type: typeDescription,
1624
+ isHeader: true,
1625
+ headerEnd,
1626
+ contentPath: contentLength > 0 ? `${path}#content` : void 0,
1627
+ children: contentLength > 0 ? [`${path}#content`] : []
1628
+ });
1629
+ if (contentLength > 0) {
1630
+ sourceMap.push({
1631
+ path: `${path}#content`,
1632
+ start: headerEnd,
1633
+ end: startOffset + result.bytesRead,
1634
+ majorType: 3,
1635
+ type: `\u2192 "${result.value}"`,
1636
+ isContent: true,
1637
+ parent: path
1638
+ });
1639
+ }
1640
+ }
1641
+ break;
1642
+ case 4:
1643
+ typeDescription = "Array";
1644
+ result = parseArrayWithMap(ctx, offset, path, sourceMap);
1645
+ break;
1646
+ case 5:
1647
+ typeDescription = "Map";
1648
+ result = parseMapWithMap(ctx, offset, path, sourceMap);
1649
+ break;
1650
+ case 6:
1651
+ result = parseTagWithMap(ctx, offset, path, sourceMap);
1652
+ break;
1653
+ case 7:
1654
+ typeDescription = getSimpleTypeDescription(additionalInfo);
1655
+ result = parseFloatFromBuffer(ctx.buffer, offset, ctx.options);
1656
+ sourceMap.push({
1657
+ path,
1658
+ start: startOffset,
1659
+ end: startOffset + result.bytesRead,
1660
+ majorType,
1661
+ type: typeDescription
1662
+ });
1663
+ break;
1664
+ default:
1665
+ throw new Error(`Unknown major type: ${majorType}`);
1666
+ }
1667
+ return result;
1668
+ };
1669
+ const parseIntegerFromBuffer = (buffer, offset, options) => {
1670
+ const hexString = Array.from(buffer.slice(offset)).map((b) => b.toString(16).padStart(2, "0")).join("");
1671
+ return parseInteger(hexString, options);
1672
+ };
1673
+ const parseStringFromBuffer = (buffer, offset, options) => {
1674
+ const hexString = Array.from(buffer.slice(offset)).map((b) => b.toString(16).padStart(2, "0")).join("");
1675
+ return parseString(hexString, options);
1676
+ };
1677
+ const parseFloatFromBuffer = (buffer, offset, options) => {
1678
+ const hexString = Array.from(buffer.slice(offset)).map((b) => b.toString(16).padStart(2, "0")).join("");
1679
+ return parseFloatOrSimple(hexString, options);
1680
+ };
1681
+ const parseArrayWithMap = (ctx, offset, path, sourceMap) => {
1682
+ const startOffset = offset;
1683
+ const initialByte = readByte(ctx.buffer, offset);
1684
+ const { additionalInfo } = extractCborHeader(initialByte);
1685
+ let currentOffset = offset + 1;
1686
+ const items = [];
1687
+ let length;
1688
+ let isIndefinite = false;
1689
+ if (additionalInfo < 24) {
1690
+ length = additionalInfo;
1691
+ } else if (additionalInfo === 24) {
1692
+ length = readByte(ctx.buffer, currentOffset);
1693
+ currentOffset += 1;
1694
+ } else if (additionalInfo === 25) {
1695
+ length = readUint(ctx.buffer, currentOffset, 2);
1696
+ currentOffset += 2;
1697
+ } else if (additionalInfo === 26) {
1698
+ length = readUint(ctx.buffer, currentOffset, 4);
1699
+ currentOffset += 4;
1700
+ } else if (additionalInfo === 27) {
1701
+ const bigLength = readBigUint(ctx.buffer, currentOffset, 8);
1702
+ if (bigLength > BigInt(Number.MAX_SAFE_INTEGER)) {
1703
+ throw new Error("Array length exceeds maximum safe integer");
1704
+ }
1705
+ length = Number(bigLength);
1706
+ currentOffset += 8;
1707
+ } else if (additionalInfo === 31) {
1708
+ isIndefinite = true;
1709
+ length = 0;
1710
+ } else {
1711
+ throw new Error(`Invalid additional info: ${additionalInfo}`);
1712
+ }
1713
+ const headerEnd = currentOffset;
1714
+ const arrayEntryIndex = sourceMap.length;
1715
+ sourceMap.push({
1716
+ path,
1717
+ start: startOffset,
1718
+ end: headerEnd,
1719
+ majorType: 4,
1720
+ type: isIndefinite ? "array(indefinite)" : `array(${length})`,
1721
+ isHeader: true,
1722
+ headerEnd
1723
+ });
1724
+ const childPaths = [];
1725
+ if (isIndefinite) {
1726
+ let index = 0;
1727
+ while (currentOffset < ctx.buffer.length) {
1728
+ const nextByte = readByte(ctx.buffer, currentOffset);
1729
+ if (nextByte === 255) {
1730
+ currentOffset++;
1731
+ break;
1732
+ }
1733
+ const elementPath = `${path}[${index}]`;
1734
+ childPaths.push(elementPath);
1735
+ const elementResult = parseValueWithMap(ctx, currentOffset, elementPath, sourceMap);
1736
+ items.push(elementResult.value);
1737
+ currentOffset += elementResult.bytesRead;
1738
+ const elementEntry = sourceMap.find((e) => e.path === elementPath);
1739
+ if (elementEntry) {
1740
+ elementEntry.parent = path;
1741
+ }
1742
+ index++;
1743
+ }
1744
+ } else {
1745
+ for (let i = 0; i < length; i++) {
1746
+ const elementPath = `${path}[${i}]`;
1747
+ childPaths.push(elementPath);
1748
+ const elementResult = parseValueWithMap(ctx, currentOffset, elementPath, sourceMap);
1749
+ items.push(elementResult.value);
1750
+ currentOffset += elementResult.bytesRead;
1751
+ const elementEntry = sourceMap.find((e) => e.path === elementPath);
1752
+ if (elementEntry) {
1753
+ elementEntry.parent = path;
1754
+ }
1755
+ }
1756
+ }
1757
+ const bytesRead = currentOffset - offset;
1758
+ if (childPaths.length > 0 && sourceMap[arrayEntryIndex]) {
1759
+ sourceMap[arrayEntryIndex].children = childPaths;
1760
+ }
1761
+ return {
1762
+ value: items,
1763
+ bytesRead
1764
+ };
1765
+ };
1766
+ const parseMapWithMap = (ctx, offset, path, sourceMap) => {
1767
+ const startOffset = offset;
1768
+ const initialByte = readByte(ctx.buffer, offset);
1769
+ const { additionalInfo } = extractCborHeader(initialByte);
1770
+ let currentOffset = offset + 1;
1771
+ const map = /* @__PURE__ */ new Map();
1772
+ let length;
1773
+ let isIndefinite = false;
1774
+ if (additionalInfo < 24) {
1775
+ length = additionalInfo;
1776
+ } else if (additionalInfo === 24) {
1777
+ length = readByte(ctx.buffer, currentOffset);
1778
+ currentOffset += 1;
1779
+ } else if (additionalInfo === 25) {
1780
+ length = readUint(ctx.buffer, currentOffset, 2);
1781
+ currentOffset += 2;
1782
+ } else if (additionalInfo === 26) {
1783
+ length = readUint(ctx.buffer, currentOffset, 4);
1784
+ currentOffset += 4;
1785
+ } else if (additionalInfo === 27) {
1786
+ const bigLength = readBigUint(ctx.buffer, currentOffset, 8);
1787
+ if (bigLength > BigInt(Number.MAX_SAFE_INTEGER)) {
1788
+ throw new Error("Map length exceeds maximum safe integer");
1789
+ }
1790
+ length = Number(bigLength);
1791
+ currentOffset += 8;
1792
+ } else if (additionalInfo === 31) {
1793
+ isIndefinite = true;
1794
+ length = 0;
1795
+ } else {
1796
+ throw new Error(`Invalid additional info: ${additionalInfo}`);
1797
+ }
1798
+ const headerEnd = currentOffset;
1799
+ const mapEntryIndex = sourceMap.length;
1800
+ sourceMap.push({
1801
+ path,
1802
+ start: startOffset,
1803
+ end: headerEnd,
1804
+ majorType: 5,
1805
+ type: isIndefinite ? "map(indefinite)" : `map(${length})`,
1806
+ isHeader: true,
1807
+ headerEnd
1808
+ });
1809
+ const childPaths = [];
1810
+ const seenKeys = /* @__PURE__ */ new Set();
1811
+ if (isIndefinite) {
1812
+ while (currentOffset < ctx.buffer.length) {
1813
+ const nextByte = readByte(ctx.buffer, currentOffset);
1814
+ if (nextByte === 255) {
1815
+ currentOffset++;
1816
+ break;
1817
+ }
1818
+ const keyPath = `${path}${path ? "." : ""}#key`;
1819
+ const keyResult = parseValueWithMap(ctx, currentOffset, keyPath, sourceMap);
1820
+ currentOffset += keyResult.bytesRead;
1821
+ const keyString = keyResult.value instanceof Uint8Array ? Array.from(keyResult.value).map((b) => b.toString(16).padStart(2, "0")).join("") : String(keyResult.value);
1822
+ if (seenKeys.has(keyString)) {
1823
+ const mode = ctx.options?.dupMapKeyMode || "allow";
1824
+ if (mode === "reject") {
1825
+ throw new Error(`Duplicate map key detected: ${keyString} at offset ${currentOffset}`);
1826
+ } else if (mode === "warn") {
1827
+ logger.warn(`Duplicate map key detected: ${keyString} at offset ${currentOffset}`);
1828
+ }
1829
+ }
1830
+ seenKeys.add(keyString);
1831
+ const valuePath = path ? `${path}.${keyString}` : `.${keyString}`;
1832
+ childPaths.push(valuePath);
1833
+ const valueResult = parseValueWithMap(ctx, currentOffset, valuePath, sourceMap);
1834
+ map.set(keyResult.value, valueResult.value);
1835
+ currentOffset += valueResult.bytesRead;
1836
+ const valueEntry = sourceMap.find((e) => e.path === valuePath);
1837
+ if (valueEntry) {
1838
+ valueEntry.parent = path;
1839
+ }
1840
+ }
1841
+ } else {
1842
+ for (let i = 0; i < length; i++) {
1843
+ const keyPath = `${path}${path ? "." : ""}#key${i}`;
1844
+ const keyResult = parseValueWithMap(ctx, currentOffset, keyPath, sourceMap);
1845
+ currentOffset += keyResult.bytesRead;
1846
+ const keyString = keyResult.value instanceof Uint8Array ? Array.from(keyResult.value).map((b) => b.toString(16).padStart(2, "0")).join("") : String(keyResult.value);
1847
+ if (seenKeys.has(keyString)) {
1848
+ const mode = ctx.options?.dupMapKeyMode || "allow";
1849
+ if (mode === "reject") {
1850
+ throw new Error(`Duplicate map key detected: ${keyString} at offset ${currentOffset}`);
1851
+ } else if (mode === "warn") {
1852
+ logger.warn(`Duplicate map key detected: ${keyString} at offset ${currentOffset}`);
1853
+ }
1854
+ }
1855
+ seenKeys.add(keyString);
1856
+ const valuePath = path ? `${path}.${keyString}` : `.${keyString}`;
1857
+ childPaths.push(valuePath);
1858
+ const valueResult = parseValueWithMap(ctx, currentOffset, valuePath, sourceMap);
1859
+ map.set(keyResult.value, valueResult.value);
1860
+ currentOffset += valueResult.bytesRead;
1861
+ const valueEntry = sourceMap.find((e) => e.path === valuePath);
1862
+ if (valueEntry) {
1863
+ valueEntry.parent = path;
1864
+ }
1865
+ }
1866
+ }
1867
+ const bytesRead = currentOffset - offset;
1868
+ if (sourceMap[mapEntryIndex]) {
1869
+ sourceMap[mapEntryIndex].children = childPaths;
1870
+ }
1871
+ return {
1872
+ value: map,
1873
+ bytesRead
1874
+ };
1875
+ };
1876
+ const parseTagNumberHelper = (buffer, offset, ai) => {
1877
+ if (ai < 24) {
1878
+ return { tagNumber: ai, bytesConsumed: 0 };
1879
+ } else if (ai === 24) {
1880
+ const tagNumber = readByte(buffer, offset);
1881
+ return { tagNumber, bytesConsumed: 1 };
1882
+ } else if (ai === 25) {
1883
+ const tagNumber = readUint(buffer, offset, 2);
1884
+ return { tagNumber, bytesConsumed: 2 };
1885
+ } else if (ai === 26) {
1886
+ const tagNumber = readUint(buffer, offset, 4);
1887
+ return { tagNumber, bytesConsumed: 4 };
1888
+ } else if (ai === 27) {
1889
+ const tagBigInt = readBigUint(buffer, offset, 8);
1890
+ if (tagBigInt <= BigInt(Number.MAX_SAFE_INTEGER)) {
1891
+ return { tagNumber: Number(tagBigInt), bytesConsumed: 8 };
1892
+ } else {
1893
+ throw new Error(`Tag number ${tagBigInt} exceeds maximum safe integer`);
1894
+ }
1895
+ } else if (ai >= 28 && ai <= 30) {
1896
+ throw new Error(`Reserved additional info ${ai} for major type 6`);
1897
+ } else {
1898
+ throw new Error(`Invalid additional info ${ai} for tags`);
1899
+ }
1900
+ };
1901
+ const parseTagWithMap = (ctx, offset, path, sourceMap) => {
1902
+ const startOffset = offset;
1903
+ const initialByte = readByte(ctx.buffer, offset);
1904
+ const { additionalInfo } = extractCborHeader(initialByte);
1905
+ const { tagNumber, bytesConsumed } = parseTagNumberHelper(
1906
+ ctx.buffer,
1907
+ offset + 1,
1908
+ additionalInfo
1909
+ );
1910
+ let currentOffset = offset + 1 + bytesConsumed;
1911
+ const headerEnd = currentOffset;
1912
+ const tagEntryIndex = sourceMap.length;
1913
+ sourceMap.push({
1914
+ path,
1915
+ start: startOffset,
1916
+ end: headerEnd,
1917
+ majorType: 6,
1918
+ type: `tag(${tagNumber})`,
1919
+ isHeader: true,
1920
+ headerEnd,
1921
+ children: []
1922
+ });
1923
+ const valuePath = `${path}.value`;
1924
+ const valueResult = parseValueWithMap(ctx, currentOffset, valuePath, sourceMap);
1925
+ currentOffset += valueResult.bytesRead;
1926
+ if (sourceMap[tagEntryIndex]) {
1927
+ sourceMap[tagEntryIndex].children = [valuePath];
1928
+ }
1929
+ const valueEntry = sourceMap.find((e) => e.path === valuePath);
1930
+ if (valueEntry) {
1931
+ valueEntry.parent = path;
1932
+ }
1933
+ const hexString = Array.from(ctx.buffer.slice(startOffset, currentOffset)).map((b) => b.toString(16).padStart(2, "0")).join("");
1934
+ const tagResult = parseTag(hexString, ctx.options);
1935
+ return {
1936
+ value: tagResult.value,
1937
+ bytesRead: currentOffset - startOffset
1938
+ };
1939
+ };
1940
+ const getSimpleTypeDescription = (ai) => {
1941
+ if (ai === 20) return "Simple: false";
1942
+ if (ai === 21) return "Simple: true";
1943
+ if (ai === 22) return "Simple: null";
1944
+ if (ai === 23) return "Simple: undefined";
1945
+ if (ai === 25) return "Float16";
1946
+ if (ai === 26) return "Float32";
1947
+ if (ai === 27) return "Float64";
1948
+ if (ai < 20) return `Simple Value ${ai}`;
1949
+ return "Simple Value";
1950
+ };
1951
+ const parseSequence = (hexString, options) => {
1952
+ const cleanHex = hexString.replace(/\s+/g, "");
1953
+ if (!cleanHex || cleanHex.length === 0) {
1954
+ return [];
1955
+ }
1956
+ if (cleanHex.length % 2 !== 0) {
1957
+ throw new Error("Hex string must have even length");
1958
+ }
1959
+ if (!/^[0-9a-fA-F]+$/.test(cleanHex)) {
1960
+ throw new Error(`Invalid hex character in: ${cleanHex}`);
1961
+ }
1962
+ const mergedOptions = mergeOptions(options);
1963
+ const buffer = hexToBytes(cleanHex);
1964
+ const results = [];
1965
+ let offset = 0;
1966
+ while (offset < buffer.length) {
1967
+ const byte = readByte(buffer, offset);
1968
+ if (byte === 255) {
1969
+ throw new Error(`Unexpected break code (0xff) at offset ${offset} - not inside indefinite-length item`);
1970
+ }
1971
+ const remainingHex = Array.from(buffer.slice(offset)).map((b) => b.toString(16).padStart(2, "0")).join("");
1972
+ const result = parse(remainingHex, mergedOptions);
1973
+ results.push(result.value);
1974
+ offset += result.bytesRead;
1975
+ }
1976
+ return results;
1977
+ };
1978
+ const parseSequenceWithSourceMap = (hexString, options) => {
1979
+ const cleanHex = hexString.replace(/\s+/g, "");
1980
+ if (!cleanHex || cleanHex.length === 0) {
1981
+ return { values: [], sourceMaps: [] };
1982
+ }
1983
+ if (cleanHex.length % 2 !== 0) {
1984
+ throw new Error("Hex string must have even length");
1985
+ }
1986
+ if (!/^[0-9a-fA-F]+$/.test(cleanHex)) {
1987
+ throw new Error(`Invalid hex character in: ${cleanHex}`);
1988
+ }
1989
+ const mergedOptions = mergeOptions(options);
1990
+ const buffer = hexToBytes(cleanHex);
1991
+ const values = [];
1992
+ const sourceMaps = [];
1993
+ let offset = 0;
1994
+ while (offset < buffer.length) {
1995
+ const byte = readByte(buffer, offset);
1996
+ if (byte === 255) {
1997
+ throw new Error(`Unexpected break code (0xff) at offset ${offset}`);
1998
+ }
1999
+ const remainingHex = Array.from(buffer.slice(offset)).map((b) => b.toString(16).padStart(2, "0")).join("");
2000
+ const result = parseWithSourceMap(remainingHex, mergedOptions);
2001
+ const adjustedSourceMap = result.sourceMap.map((entry) => ({
2002
+ ...entry,
2003
+ start: entry.start + offset,
2004
+ end: entry.end + offset
2005
+ }));
2006
+ values.push(result.value);
2007
+ sourceMaps.push(adjustedSourceMap);
2008
+ offset += result.bytesRead;
2009
+ }
2010
+ return { values, sourceMaps };
2011
+ };
2012
+ return {
2013
+ parse,
2014
+ parseWithSourceMap,
2015
+ parseSequence,
2016
+ parseSequenceWithSourceMap
2017
+ };
2018
+ }
2019
+
2020
+ exports.bytesToHex = bytesToHex;
2021
+ exports.extractCborHeader = extractCborHeader;
2022
+ exports.hexToBytes = hexToBytes;
2023
+ exports.readBigUint = readBigUint;
2024
+ exports.readByte = readByte;
2025
+ exports.readUint = readUint;
2026
+ exports.useCborCollection = useCborCollection;
2027
+ exports.useCborFloat = useCborFloat;
2028
+ exports.useCborInteger = useCborInteger;
2029
+ exports.useCborParser = useCborParser;
2030
+ exports.useCborString = useCborString;
2031
+ exports.useCborTag = useCborTag;
2032
+ exports.validateUtf8Strict = validateUtf8Strict;
2033
+ //# sourceMappingURL=chunk-2HBCILJS.cjs.map
2034
+ //# sourceMappingURL=chunk-2HBCILJS.cjs.map