@bcts/dcbor 1.0.0-alpha.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +48 -0
- package/README.md +13 -0
- package/dist/index.cjs +9151 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +3107 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +3107 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.iife.js +9155 -0
- package/dist/index.iife.js.map +1 -0
- package/dist/index.mjs +9027 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +80 -0
- package/src/.claude-flow/metrics/agent-metrics.json +1 -0
- package/src/.claude-flow/metrics/performance.json +87 -0
- package/src/.claude-flow/metrics/task-metrics.json +10 -0
- package/src/byte-string.ts +300 -0
- package/src/cbor-codable.ts +170 -0
- package/src/cbor-tagged-codable.ts +72 -0
- package/src/cbor-tagged-decodable.ts +184 -0
- package/src/cbor-tagged-encodable.ts +138 -0
- package/src/cbor-tagged.ts +104 -0
- package/src/cbor.ts +869 -0
- package/src/conveniences.ts +840 -0
- package/src/date.ts +553 -0
- package/src/decode.ts +276 -0
- package/src/diag.ts +462 -0
- package/src/dump.ts +277 -0
- package/src/error.ts +259 -0
- package/src/exact.ts +714 -0
- package/src/float.ts +279 -0
- package/src/global.d.ts +34 -0
- package/src/globals.d.ts +0 -0
- package/src/index.ts +180 -0
- package/src/map.ts +308 -0
- package/src/prelude.ts +70 -0
- package/src/set.ts +515 -0
- package/src/simple.ts +153 -0
- package/src/stdlib.ts +55 -0
- package/src/string-util.ts +55 -0
- package/src/tag.ts +53 -0
- package/src/tags-store.ts +294 -0
- package/src/tags.ts +231 -0
- package/src/varint.ts +124 -0
- package/src/walk.ts +516 -0
|
@@ -0,0 +1,840 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convenience utilities for working with CBOR values.
|
|
3
|
+
*
|
|
4
|
+
* Provides type-safe helpers for checking types, extracting values,
|
|
5
|
+
* and working with arrays, maps, and tagged values.
|
|
6
|
+
*
|
|
7
|
+
* @module conveniences
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
type Cbor,
|
|
12
|
+
MajorType,
|
|
13
|
+
type CborNumber,
|
|
14
|
+
type CborInput,
|
|
15
|
+
type CborUnsignedType,
|
|
16
|
+
type CborNegativeType,
|
|
17
|
+
type CborByteStringType,
|
|
18
|
+
type CborTextType,
|
|
19
|
+
type CborArrayType,
|
|
20
|
+
type CborMapType,
|
|
21
|
+
type CborTaggedType,
|
|
22
|
+
type CborSimpleType,
|
|
23
|
+
type CborMethods,
|
|
24
|
+
} from "./cbor";
|
|
25
|
+
import type { CborMap } from "./map";
|
|
26
|
+
import { isFloat as isSimpleFloat } from "./simple";
|
|
27
|
+
import { decodeCbor } from "./decode";
|
|
28
|
+
import { CborError } from "./error";
|
|
29
|
+
|
|
30
|
+
// ============================================================================
|
|
31
|
+
// Extraction
|
|
32
|
+
// ============================================================================
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Extract native JavaScript value from CBOR.
|
|
36
|
+
* Converts CBOR types to their JavaScript equivalents.
|
|
37
|
+
*/
|
|
38
|
+
export const extractCbor = (cbor: Cbor | Uint8Array): unknown => {
|
|
39
|
+
let c: Cbor;
|
|
40
|
+
if (cbor instanceof Uint8Array) {
|
|
41
|
+
c = decodeCbor(cbor);
|
|
42
|
+
} else {
|
|
43
|
+
c = cbor;
|
|
44
|
+
}
|
|
45
|
+
switch (c.type) {
|
|
46
|
+
case MajorType.Unsigned:
|
|
47
|
+
return c.value;
|
|
48
|
+
case MajorType.Negative:
|
|
49
|
+
if (typeof c.value === "bigint") {
|
|
50
|
+
return -c.value - 1n;
|
|
51
|
+
} else {
|
|
52
|
+
return -c.value - 1;
|
|
53
|
+
}
|
|
54
|
+
case MajorType.ByteString:
|
|
55
|
+
return c.value;
|
|
56
|
+
case MajorType.Text:
|
|
57
|
+
return c.value;
|
|
58
|
+
case MajorType.Array:
|
|
59
|
+
return c.value.map(extractCbor);
|
|
60
|
+
case MajorType.Map:
|
|
61
|
+
return c.value;
|
|
62
|
+
case MajorType.Tagged:
|
|
63
|
+
return c;
|
|
64
|
+
case MajorType.Simple:
|
|
65
|
+
if (c.value.type === "True") return true;
|
|
66
|
+
if (c.value.type === "False") return false;
|
|
67
|
+
if (c.value.type === "Null") return null;
|
|
68
|
+
if (c.value.type === "Float") return c.value.value;
|
|
69
|
+
return c;
|
|
70
|
+
}
|
|
71
|
+
return undefined;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
// ============================================================================
|
|
75
|
+
// Type Guards
|
|
76
|
+
// ============================================================================
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Check if CBOR value is an unsigned integer.
|
|
80
|
+
*
|
|
81
|
+
* @param cbor - CBOR value to check
|
|
82
|
+
* @returns True if value is unsigned integer
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```typescript
|
|
86
|
+
* if (isUnsigned(value)) {
|
|
87
|
+
* console.log('Unsigned:', value.value);
|
|
88
|
+
* }
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
export const isUnsigned = (cbor: Cbor): cbor is CborUnsignedType & CborMethods => {
|
|
92
|
+
return cbor.type === MajorType.Unsigned;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Check if CBOR value is a negative integer.
|
|
97
|
+
*
|
|
98
|
+
* @param cbor - CBOR value to check
|
|
99
|
+
* @returns True if value is negative integer
|
|
100
|
+
*/
|
|
101
|
+
export const isNegative = (cbor: Cbor): cbor is CborNegativeType & CborMethods => {
|
|
102
|
+
return cbor.type === MajorType.Negative;
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Check if CBOR value is any integer (unsigned or negative).
|
|
107
|
+
*
|
|
108
|
+
* @param cbor - CBOR value to check
|
|
109
|
+
* @returns True if value is an integer
|
|
110
|
+
*/
|
|
111
|
+
export const isInteger = (
|
|
112
|
+
cbor: Cbor,
|
|
113
|
+
): cbor is (CborUnsignedType | CborNegativeType) & CborMethods => {
|
|
114
|
+
return cbor.type === MajorType.Unsigned || cbor.type === MajorType.Negative;
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Check if CBOR value is a byte string.
|
|
119
|
+
*
|
|
120
|
+
* @param cbor - CBOR value to check
|
|
121
|
+
* @returns True if value is byte string
|
|
122
|
+
*/
|
|
123
|
+
export const isBytes = (cbor: Cbor): cbor is CborByteStringType & CborMethods => {
|
|
124
|
+
return cbor.type === MajorType.ByteString;
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Check if CBOR value is a text string.
|
|
129
|
+
*
|
|
130
|
+
* @param cbor - CBOR value to check
|
|
131
|
+
* @returns True if value is text string
|
|
132
|
+
*/
|
|
133
|
+
export const isText = (cbor: Cbor): cbor is CborTextType & CborMethods => {
|
|
134
|
+
return cbor.type === MajorType.Text;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Check if CBOR value is an array.
|
|
139
|
+
*
|
|
140
|
+
* @param cbor - CBOR value to check
|
|
141
|
+
* @returns True if value is array
|
|
142
|
+
*/
|
|
143
|
+
export const isArray = (cbor: Cbor): cbor is CborArrayType & CborMethods => {
|
|
144
|
+
return cbor.type === MajorType.Array;
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Check if CBOR value is a map.
|
|
149
|
+
*
|
|
150
|
+
* @param cbor - CBOR value to check
|
|
151
|
+
* @returns True if value is map
|
|
152
|
+
*/
|
|
153
|
+
export const isMap = (cbor: Cbor): cbor is CborMapType & CborMethods => {
|
|
154
|
+
return cbor.type === MajorType.Map;
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Check if CBOR value is tagged.
|
|
159
|
+
*
|
|
160
|
+
* @param cbor - CBOR value to check
|
|
161
|
+
* @returns True if value is tagged
|
|
162
|
+
*/
|
|
163
|
+
export const isTagged = (cbor: Cbor): cbor is CborTaggedType & CborMethods => {
|
|
164
|
+
return cbor.type === MajorType.Tagged;
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Check if CBOR value is a simple value.
|
|
169
|
+
*
|
|
170
|
+
* @param cbor - CBOR value to check
|
|
171
|
+
* @returns True if value is simple
|
|
172
|
+
*/
|
|
173
|
+
export const isSimple = (cbor: Cbor): cbor is CborSimpleType & CborMethods => {
|
|
174
|
+
return cbor.type === MajorType.Simple;
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Check if CBOR value is a boolean (true or false).
|
|
179
|
+
*
|
|
180
|
+
* @param cbor - CBOR value to check
|
|
181
|
+
* @returns True if value is boolean
|
|
182
|
+
*/
|
|
183
|
+
export const isBoolean = (
|
|
184
|
+
cbor: Cbor,
|
|
185
|
+
): cbor is CborSimpleType &
|
|
186
|
+
CborMethods & { readonly value: { readonly type: "False" } | { readonly type: "True" } } => {
|
|
187
|
+
if (cbor.type !== MajorType.Simple) {
|
|
188
|
+
return false;
|
|
189
|
+
}
|
|
190
|
+
return cbor.value.type === "False" || cbor.value.type === "True";
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Check if CBOR value is null.
|
|
195
|
+
*
|
|
196
|
+
* @param cbor - CBOR value to check
|
|
197
|
+
* @returns True if value is null
|
|
198
|
+
*/
|
|
199
|
+
export const isNull = (
|
|
200
|
+
cbor: Cbor,
|
|
201
|
+
): cbor is CborSimpleType & CborMethods & { readonly value: { readonly type: "Null" } } => {
|
|
202
|
+
if (cbor.type !== MajorType.Simple) {
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
return cbor.value.type === "Null";
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Check if CBOR value is a float (f16, f32, or f64).
|
|
210
|
+
*
|
|
211
|
+
* @param cbor - CBOR value to check
|
|
212
|
+
* @returns True if value is float
|
|
213
|
+
*/
|
|
214
|
+
export const isFloat = (
|
|
215
|
+
cbor: Cbor,
|
|
216
|
+
): cbor is CborSimpleType &
|
|
217
|
+
CborMethods & { readonly value: { readonly type: "Float"; readonly value: number } } => {
|
|
218
|
+
if (cbor.type !== MajorType.Simple) {
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
221
|
+
return isSimpleFloat(cbor.value);
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
// ============================================================================
|
|
225
|
+
// Safe Extraction (returns undefined on type mismatch)
|
|
226
|
+
// ============================================================================
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Extract unsigned integer value if type matches.
|
|
230
|
+
*
|
|
231
|
+
* @param cbor - CBOR value
|
|
232
|
+
* @returns Unsigned integer or undefined
|
|
233
|
+
*/
|
|
234
|
+
export const asUnsigned = (cbor: Cbor): number | bigint | undefined => {
|
|
235
|
+
if (cbor.type === MajorType.Unsigned) {
|
|
236
|
+
return cbor.value;
|
|
237
|
+
}
|
|
238
|
+
return undefined;
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Extract negative integer value if type matches.
|
|
243
|
+
*
|
|
244
|
+
* @param cbor - CBOR value
|
|
245
|
+
* @returns Negative integer or undefined
|
|
246
|
+
*/
|
|
247
|
+
export const asNegative = (cbor: Cbor): number | bigint | undefined => {
|
|
248
|
+
if (cbor.type === MajorType.Negative) {
|
|
249
|
+
// Convert stored magnitude back to actual negative value
|
|
250
|
+
if (typeof cbor.value === "bigint") {
|
|
251
|
+
return -cbor.value - 1n;
|
|
252
|
+
} else {
|
|
253
|
+
return -cbor.value - 1;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return undefined;
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Extract any integer value (unsigned or negative) if type matches.
|
|
261
|
+
*
|
|
262
|
+
* @param cbor - CBOR value
|
|
263
|
+
* @returns Integer or undefined
|
|
264
|
+
*/
|
|
265
|
+
export const asInteger = (cbor: Cbor): number | bigint | undefined => {
|
|
266
|
+
if (cbor.type === MajorType.Unsigned) {
|
|
267
|
+
return cbor.value;
|
|
268
|
+
} else if (cbor.type === MajorType.Negative) {
|
|
269
|
+
// Convert stored magnitude back to actual negative value
|
|
270
|
+
if (typeof cbor.value === "bigint") {
|
|
271
|
+
return -cbor.value - 1n;
|
|
272
|
+
} else {
|
|
273
|
+
return -cbor.value - 1;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
return undefined;
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Extract byte string value if type matches.
|
|
281
|
+
*
|
|
282
|
+
* @param cbor - CBOR value
|
|
283
|
+
* @returns Byte string or undefined
|
|
284
|
+
*/
|
|
285
|
+
export const asBytes = (cbor: Cbor): Uint8Array | undefined => {
|
|
286
|
+
if (cbor.type === MajorType.ByteString) {
|
|
287
|
+
return cbor.value;
|
|
288
|
+
}
|
|
289
|
+
return undefined;
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Extract text string value if type matches.
|
|
294
|
+
*
|
|
295
|
+
* @param cbor - CBOR value
|
|
296
|
+
* @returns Text string or undefined
|
|
297
|
+
*/
|
|
298
|
+
export const asText = (cbor: Cbor): string | undefined => {
|
|
299
|
+
if (cbor.type === MajorType.Text) {
|
|
300
|
+
return cbor.value;
|
|
301
|
+
}
|
|
302
|
+
return undefined;
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Extract array value if type matches.
|
|
307
|
+
*
|
|
308
|
+
* @param cbor - CBOR value
|
|
309
|
+
* @returns Array or undefined
|
|
310
|
+
*/
|
|
311
|
+
export const asArray = (cbor: Cbor): readonly Cbor[] | undefined => {
|
|
312
|
+
if (cbor.type === MajorType.Array) {
|
|
313
|
+
return cbor.value;
|
|
314
|
+
}
|
|
315
|
+
return undefined;
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Extract map value if type matches.
|
|
320
|
+
*
|
|
321
|
+
* @param cbor - CBOR value
|
|
322
|
+
* @returns Map or undefined
|
|
323
|
+
*/
|
|
324
|
+
export const asMap = (cbor: Cbor): CborMap | undefined => {
|
|
325
|
+
if (cbor.type === MajorType.Map) {
|
|
326
|
+
return cbor.value;
|
|
327
|
+
}
|
|
328
|
+
return undefined;
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Extract boolean value if type matches.
|
|
333
|
+
*
|
|
334
|
+
* @param cbor - CBOR value
|
|
335
|
+
* @returns Boolean or undefined
|
|
336
|
+
*/
|
|
337
|
+
export const asBoolean = (cbor: Cbor): boolean | undefined => {
|
|
338
|
+
if (cbor.type !== MajorType.Simple) {
|
|
339
|
+
return undefined;
|
|
340
|
+
}
|
|
341
|
+
if (cbor.value.type === "True") {
|
|
342
|
+
return true;
|
|
343
|
+
}
|
|
344
|
+
if (cbor.value.type === "False") {
|
|
345
|
+
return false;
|
|
346
|
+
}
|
|
347
|
+
return undefined;
|
|
348
|
+
};
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Extract float value if type matches.
|
|
352
|
+
*
|
|
353
|
+
* @param cbor - CBOR value
|
|
354
|
+
* @returns Float or undefined
|
|
355
|
+
*/
|
|
356
|
+
export const asFloat = (cbor: Cbor): number | undefined => {
|
|
357
|
+
if (cbor.type !== MajorType.Simple) {
|
|
358
|
+
return undefined;
|
|
359
|
+
}
|
|
360
|
+
const simple = cbor.value;
|
|
361
|
+
if (isSimpleFloat(simple)) {
|
|
362
|
+
return simple.value;
|
|
363
|
+
}
|
|
364
|
+
return undefined;
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Extract any numeric value (integer or float).
|
|
369
|
+
*
|
|
370
|
+
* @param cbor - CBOR value
|
|
371
|
+
* @returns Number or undefined
|
|
372
|
+
*/
|
|
373
|
+
export const asNumber = (cbor: Cbor): CborNumber | undefined => {
|
|
374
|
+
if (cbor.type === MajorType.Unsigned) {
|
|
375
|
+
return cbor.value;
|
|
376
|
+
}
|
|
377
|
+
if (cbor.type === MajorType.Negative) {
|
|
378
|
+
// Convert stored magnitude back to actual negative value
|
|
379
|
+
if (typeof cbor.value === "bigint") {
|
|
380
|
+
return -cbor.value - 1n;
|
|
381
|
+
} else {
|
|
382
|
+
return -cbor.value - 1;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
if (cbor.type === MajorType.Simple) {
|
|
386
|
+
const simple = cbor.value;
|
|
387
|
+
if (isSimpleFloat(simple)) {
|
|
388
|
+
return simple.value;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
return undefined;
|
|
392
|
+
};
|
|
393
|
+
|
|
394
|
+
// ============================================================================
|
|
395
|
+
// Expectations (throw on type mismatch)
|
|
396
|
+
// ============================================================================
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* Extract unsigned integer value, throwing if type doesn't match.
|
|
400
|
+
*
|
|
401
|
+
* @param cbor - CBOR value
|
|
402
|
+
* @returns Unsigned integer
|
|
403
|
+
* @throws {CborError} With type 'WrongType' if cbor is not an unsigned integer
|
|
404
|
+
*/
|
|
405
|
+
export const expectUnsigned = (cbor: Cbor): number | bigint => {
|
|
406
|
+
const value = asUnsigned(cbor);
|
|
407
|
+
if (value === undefined) {
|
|
408
|
+
throw new CborError({ type: "WrongType" });
|
|
409
|
+
}
|
|
410
|
+
return value;
|
|
411
|
+
};
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* Extract negative integer value, throwing if type doesn't match.
|
|
415
|
+
*
|
|
416
|
+
* @param cbor - CBOR value
|
|
417
|
+
* @returns Negative integer
|
|
418
|
+
* @throws {CborError} With type 'WrongType' if cbor is not a negative integer
|
|
419
|
+
*/
|
|
420
|
+
export const expectNegative = (cbor: Cbor): number | bigint => {
|
|
421
|
+
const value = asNegative(cbor);
|
|
422
|
+
if (value === undefined) {
|
|
423
|
+
throw new CborError({ type: "WrongType" });
|
|
424
|
+
}
|
|
425
|
+
return value;
|
|
426
|
+
};
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Extract any integer value, throwing if type doesn't match.
|
|
430
|
+
*
|
|
431
|
+
* @param cbor - CBOR value
|
|
432
|
+
* @returns Integer
|
|
433
|
+
* @throws {CborError} With type 'WrongType' if cbor is not an integer
|
|
434
|
+
*/
|
|
435
|
+
export const expectInteger = (cbor: Cbor): number | bigint => {
|
|
436
|
+
const value = asInteger(cbor);
|
|
437
|
+
if (value === undefined) {
|
|
438
|
+
throw new CborError({ type: "WrongType" });
|
|
439
|
+
}
|
|
440
|
+
return value;
|
|
441
|
+
};
|
|
442
|
+
|
|
443
|
+
/**
|
|
444
|
+
* Extract byte string value, throwing if type doesn't match.
|
|
445
|
+
*
|
|
446
|
+
* @param cbor - CBOR value
|
|
447
|
+
* @returns Byte string
|
|
448
|
+
* @throws {CborError} With type 'WrongType' if cbor is not a byte string
|
|
449
|
+
*/
|
|
450
|
+
export const expectBytes = (cbor: Cbor): Uint8Array => {
|
|
451
|
+
const value = asBytes(cbor);
|
|
452
|
+
if (value === undefined) {
|
|
453
|
+
throw new CborError({ type: "WrongType" });
|
|
454
|
+
}
|
|
455
|
+
return value;
|
|
456
|
+
};
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* Extract text string value, throwing if type doesn't match.
|
|
460
|
+
*
|
|
461
|
+
* @param cbor - CBOR value
|
|
462
|
+
* @returns Text string
|
|
463
|
+
* @throws {CborError} With type 'WrongType' if cbor is not a text string
|
|
464
|
+
*/
|
|
465
|
+
export const expectText = (cbor: Cbor): string => {
|
|
466
|
+
const value = asText(cbor);
|
|
467
|
+
if (value === undefined) {
|
|
468
|
+
throw new CborError({ type: "WrongType" });
|
|
469
|
+
}
|
|
470
|
+
return value;
|
|
471
|
+
};
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* Extract array value, throwing if type doesn't match.
|
|
475
|
+
*
|
|
476
|
+
* @param cbor - CBOR value
|
|
477
|
+
* @returns Array
|
|
478
|
+
* @throws {CborError} With type 'WrongType' if cbor is not an array
|
|
479
|
+
*/
|
|
480
|
+
export const expectArray = (cbor: Cbor): readonly Cbor[] => {
|
|
481
|
+
const value = asArray(cbor);
|
|
482
|
+
if (value === undefined) {
|
|
483
|
+
throw new CborError({ type: "WrongType" });
|
|
484
|
+
}
|
|
485
|
+
return value;
|
|
486
|
+
};
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* Extract map value, throwing if type doesn't match.
|
|
490
|
+
*
|
|
491
|
+
* @param cbor - CBOR value
|
|
492
|
+
* @returns Map
|
|
493
|
+
* @throws {CborError} With type 'WrongType' if cbor is not a map
|
|
494
|
+
*/
|
|
495
|
+
export const expectMap = (cbor: Cbor): CborMap => {
|
|
496
|
+
const value = asMap(cbor);
|
|
497
|
+
if (value === undefined) {
|
|
498
|
+
throw new CborError({ type: "WrongType" });
|
|
499
|
+
}
|
|
500
|
+
return value;
|
|
501
|
+
};
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* Extract boolean value, throwing if type doesn't match.
|
|
505
|
+
*
|
|
506
|
+
* @param cbor - CBOR value
|
|
507
|
+
* @returns Boolean
|
|
508
|
+
* @throws {CborError} With type 'WrongType' if cbor is not a boolean
|
|
509
|
+
*/
|
|
510
|
+
export const expectBoolean = (cbor: Cbor): boolean => {
|
|
511
|
+
const value = asBoolean(cbor);
|
|
512
|
+
if (value === undefined) {
|
|
513
|
+
throw new CborError({ type: "WrongType" });
|
|
514
|
+
}
|
|
515
|
+
return value;
|
|
516
|
+
};
|
|
517
|
+
|
|
518
|
+
/**
|
|
519
|
+
* Extract float value, throwing if type doesn't match.
|
|
520
|
+
*
|
|
521
|
+
* @param cbor - CBOR value
|
|
522
|
+
* @returns Float
|
|
523
|
+
* @throws {CborError} With type 'WrongType' if cbor is not a float
|
|
524
|
+
*/
|
|
525
|
+
export const expectFloat = (cbor: Cbor): number => {
|
|
526
|
+
const value = asFloat(cbor);
|
|
527
|
+
if (value === undefined) {
|
|
528
|
+
throw new CborError({ type: "WrongType" });
|
|
529
|
+
}
|
|
530
|
+
return value;
|
|
531
|
+
};
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
* Extract any numeric value, throwing if type doesn't match.
|
|
535
|
+
*
|
|
536
|
+
* @param cbor - CBOR value
|
|
537
|
+
* @returns Number
|
|
538
|
+
* @throws {CborError} With type 'WrongType' if cbor is not a number
|
|
539
|
+
*/
|
|
540
|
+
export const expectNumber = (cbor: Cbor): CborNumber => {
|
|
541
|
+
const value = asNumber(cbor);
|
|
542
|
+
if (value === undefined) {
|
|
543
|
+
throw new CborError({ type: "WrongType" });
|
|
544
|
+
}
|
|
545
|
+
return value;
|
|
546
|
+
};
|
|
547
|
+
|
|
548
|
+
// ============================================================================
|
|
549
|
+
// Array Operations
|
|
550
|
+
// ============================================================================
|
|
551
|
+
|
|
552
|
+
/**
|
|
553
|
+
* Get array item at index.
|
|
554
|
+
*
|
|
555
|
+
* @param cbor - CBOR value (must be array)
|
|
556
|
+
* @param index - Array index
|
|
557
|
+
* @returns Item at index or undefined
|
|
558
|
+
*/
|
|
559
|
+
export const arrayItem = (cbor: Cbor, index: number): Cbor | undefined => {
|
|
560
|
+
if (cbor.type !== MajorType.Array) {
|
|
561
|
+
return undefined;
|
|
562
|
+
}
|
|
563
|
+
const array = cbor.value;
|
|
564
|
+
if (index < 0 || index >= array.length) {
|
|
565
|
+
return undefined;
|
|
566
|
+
}
|
|
567
|
+
return array[index];
|
|
568
|
+
};
|
|
569
|
+
|
|
570
|
+
/**
|
|
571
|
+
* Get array length.
|
|
572
|
+
*
|
|
573
|
+
* @param cbor - CBOR value (must be array)
|
|
574
|
+
* @returns Array length or undefined
|
|
575
|
+
*/
|
|
576
|
+
export const arrayLength = (cbor: Cbor): number | undefined => {
|
|
577
|
+
if (cbor.type !== MajorType.Array) {
|
|
578
|
+
return undefined;
|
|
579
|
+
}
|
|
580
|
+
return cbor.value.length;
|
|
581
|
+
};
|
|
582
|
+
|
|
583
|
+
/**
|
|
584
|
+
* Check if array is empty.
|
|
585
|
+
*
|
|
586
|
+
* @param cbor - CBOR value (must be array)
|
|
587
|
+
* @returns True if empty, false if not empty, undefined if not array
|
|
588
|
+
*/
|
|
589
|
+
export const arrayIsEmpty = (cbor: Cbor): boolean | undefined => {
|
|
590
|
+
if (cbor.type !== MajorType.Array) {
|
|
591
|
+
return undefined;
|
|
592
|
+
}
|
|
593
|
+
return cbor.value.length === 0;
|
|
594
|
+
};
|
|
595
|
+
|
|
596
|
+
// ============================================================================
|
|
597
|
+
// Map Operations
|
|
598
|
+
// ============================================================================
|
|
599
|
+
|
|
600
|
+
/**
|
|
601
|
+
* Get map value by key.
|
|
602
|
+
*
|
|
603
|
+
* @param cbor - CBOR value (must be map)
|
|
604
|
+
* @param key - Map key
|
|
605
|
+
* @returns Value for key or undefined
|
|
606
|
+
*/
|
|
607
|
+
export function mapValue<K extends CborInput, V>(cbor: Cbor, key: K): V | undefined {
|
|
608
|
+
if (cbor.type !== MajorType.Map) {
|
|
609
|
+
return undefined;
|
|
610
|
+
}
|
|
611
|
+
return cbor.value.get<K, V>(key);
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
/**
|
|
615
|
+
* Check if map has key.
|
|
616
|
+
*
|
|
617
|
+
* @param cbor - CBOR value (must be map)
|
|
618
|
+
* @param key - Map key
|
|
619
|
+
* @returns True if key exists, false otherwise, undefined if not map
|
|
620
|
+
*/
|
|
621
|
+
export function mapHas<K extends CborInput>(cbor: Cbor, key: K): boolean | undefined {
|
|
622
|
+
if (cbor.type !== MajorType.Map) {
|
|
623
|
+
return undefined;
|
|
624
|
+
}
|
|
625
|
+
return cbor.value.has(key);
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
/**
|
|
629
|
+
* Get all map keys.
|
|
630
|
+
*
|
|
631
|
+
* @param cbor - CBOR value (must be map)
|
|
632
|
+
* @returns Array of keys or undefined
|
|
633
|
+
*/
|
|
634
|
+
export const mapKeys = (cbor: Cbor): Cbor[] | undefined => {
|
|
635
|
+
if (cbor.type !== MajorType.Map) {
|
|
636
|
+
return undefined;
|
|
637
|
+
}
|
|
638
|
+
return cbor.value.entriesArray.map((e) => e.key);
|
|
639
|
+
};
|
|
640
|
+
|
|
641
|
+
/**
|
|
642
|
+
* Get all map values.
|
|
643
|
+
*
|
|
644
|
+
* @param cbor - CBOR value (must be map)
|
|
645
|
+
* @returns Array of values or undefined
|
|
646
|
+
*/
|
|
647
|
+
export const mapValues = (cbor: Cbor): Cbor[] | undefined => {
|
|
648
|
+
if (cbor.type !== MajorType.Map) {
|
|
649
|
+
return undefined;
|
|
650
|
+
}
|
|
651
|
+
return cbor.value.entriesArray.map((e) => e.value);
|
|
652
|
+
};
|
|
653
|
+
|
|
654
|
+
/**
|
|
655
|
+
* Get map size.
|
|
656
|
+
*
|
|
657
|
+
* @param cbor - CBOR value (must be map)
|
|
658
|
+
* @returns Map size or undefined
|
|
659
|
+
*/
|
|
660
|
+
export const mapSize = (cbor: Cbor): number | undefined => {
|
|
661
|
+
if (cbor.type !== MajorType.Map) {
|
|
662
|
+
return undefined;
|
|
663
|
+
}
|
|
664
|
+
return cbor.value.size;
|
|
665
|
+
};
|
|
666
|
+
|
|
667
|
+
/**
|
|
668
|
+
* Check if map is empty.
|
|
669
|
+
*
|
|
670
|
+
* @param cbor - CBOR value (must be map)
|
|
671
|
+
* @returns True if empty, false if not empty, undefined if not map
|
|
672
|
+
*/
|
|
673
|
+
export const mapIsEmpty = (cbor: Cbor): boolean | undefined => {
|
|
674
|
+
if (cbor.type !== MajorType.Map) {
|
|
675
|
+
return undefined;
|
|
676
|
+
}
|
|
677
|
+
return cbor.value.size === 0;
|
|
678
|
+
};
|
|
679
|
+
|
|
680
|
+
// ============================================================================
|
|
681
|
+
// Tagged Value Operations
|
|
682
|
+
// ============================================================================
|
|
683
|
+
|
|
684
|
+
/**
|
|
685
|
+
* Get tag value from tagged CBOR.
|
|
686
|
+
*
|
|
687
|
+
* @param cbor - CBOR value (must be tagged)
|
|
688
|
+
* @returns Tag value or undefined
|
|
689
|
+
*/
|
|
690
|
+
export const tagValue = (cbor: Cbor): number | bigint | undefined => {
|
|
691
|
+
if (cbor.type !== MajorType.Tagged) {
|
|
692
|
+
return undefined;
|
|
693
|
+
}
|
|
694
|
+
return cbor.tag;
|
|
695
|
+
};
|
|
696
|
+
|
|
697
|
+
/**
|
|
698
|
+
* Get content from tagged CBOR.
|
|
699
|
+
*
|
|
700
|
+
* @param cbor - CBOR value (must be tagged)
|
|
701
|
+
* @returns Tagged content or undefined
|
|
702
|
+
*/
|
|
703
|
+
export const tagContent = (cbor: Cbor): Cbor | undefined => {
|
|
704
|
+
if (cbor.type !== MajorType.Tagged) {
|
|
705
|
+
return undefined;
|
|
706
|
+
}
|
|
707
|
+
return cbor.value;
|
|
708
|
+
};
|
|
709
|
+
|
|
710
|
+
/**
|
|
711
|
+
* Check if CBOR has a specific tag.
|
|
712
|
+
*
|
|
713
|
+
* @param cbor - CBOR value
|
|
714
|
+
* @param tag - Tag value to check
|
|
715
|
+
* @returns True if has tag, false otherwise
|
|
716
|
+
*/
|
|
717
|
+
export const hasTag = (cbor: Cbor, tag: number | bigint): boolean => {
|
|
718
|
+
if (cbor.type !== MajorType.Tagged) {
|
|
719
|
+
return false;
|
|
720
|
+
}
|
|
721
|
+
return cbor.tag === tag;
|
|
722
|
+
};
|
|
723
|
+
|
|
724
|
+
/**
|
|
725
|
+
* Extract content if has specific tag.
|
|
726
|
+
*
|
|
727
|
+
* @param cbor - CBOR value
|
|
728
|
+
* @param tag - Expected tag value
|
|
729
|
+
* @returns Tagged content or undefined
|
|
730
|
+
*/
|
|
731
|
+
export const getTaggedContent = (cbor: Cbor, tag: number | bigint): Cbor | undefined => {
|
|
732
|
+
if (cbor.type === MajorType.Tagged && cbor.tag === tag) {
|
|
733
|
+
return cbor.value;
|
|
734
|
+
}
|
|
735
|
+
return undefined;
|
|
736
|
+
};
|
|
737
|
+
|
|
738
|
+
/**
|
|
739
|
+
* Extract content if has specific tag, throwing if not.
|
|
740
|
+
*
|
|
741
|
+
* @param cbor - CBOR value
|
|
742
|
+
* @param tag - Expected tag value
|
|
743
|
+
* @returns Tagged content
|
|
744
|
+
* @throws {CborError} With type 'WrongType' if cbor is not tagged with the expected tag
|
|
745
|
+
*/
|
|
746
|
+
export const expectTaggedContent = (cbor: Cbor, tag: number | bigint): Cbor => {
|
|
747
|
+
const content = getTaggedContent(cbor, tag);
|
|
748
|
+
if (content === undefined) {
|
|
749
|
+
throw new CborError({ type: "WrongType" });
|
|
750
|
+
}
|
|
751
|
+
return content;
|
|
752
|
+
};
|
|
753
|
+
|
|
754
|
+
// ============================================================================
|
|
755
|
+
// Envelope Compatibility Functions
|
|
756
|
+
// These functions provide the API expected by the envelope package
|
|
757
|
+
// ============================================================================
|
|
758
|
+
|
|
759
|
+
import type { Tag } from "./tag";
|
|
760
|
+
|
|
761
|
+
/**
|
|
762
|
+
* Extract tagged value as tuple [Tag, Cbor] if CBOR is tagged.
|
|
763
|
+
* This is used by envelope for decoding.
|
|
764
|
+
*
|
|
765
|
+
* @param cbor - CBOR value
|
|
766
|
+
* @returns [Tag, Cbor] tuple or undefined
|
|
767
|
+
*/
|
|
768
|
+
export const asTaggedValue = (cbor: Cbor): [Tag, Cbor] | undefined => {
|
|
769
|
+
if (cbor.type !== MajorType.Tagged) {
|
|
770
|
+
return undefined;
|
|
771
|
+
}
|
|
772
|
+
const tag: Tag = { value: cbor.tag, name: `tag-${cbor.tag}` };
|
|
773
|
+
return [tag, cbor.value];
|
|
774
|
+
};
|
|
775
|
+
|
|
776
|
+
/**
|
|
777
|
+
* Alias for asBytes - extract byte string value if type matches.
|
|
778
|
+
* Named asByteString for envelope compatibility.
|
|
779
|
+
*
|
|
780
|
+
* @param cbor - CBOR value
|
|
781
|
+
* @returns Byte string or undefined
|
|
782
|
+
*/
|
|
783
|
+
export const asByteString = asBytes;
|
|
784
|
+
|
|
785
|
+
/**
|
|
786
|
+
* A wrapper around CBOR arrays that provides a get(index) method
|
|
787
|
+
* for envelope compatibility.
|
|
788
|
+
*/
|
|
789
|
+
export interface CborArrayWrapper {
|
|
790
|
+
readonly length: number;
|
|
791
|
+
get(index: number): Cbor | undefined;
|
|
792
|
+
[Symbol.iterator](): Iterator<Cbor>;
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
/**
|
|
796
|
+
* Extract array value with get() method for envelope compatibility.
|
|
797
|
+
*
|
|
798
|
+
* @param cbor - CBOR value
|
|
799
|
+
* @returns Array wrapper with get() method or undefined
|
|
800
|
+
*/
|
|
801
|
+
export const asCborArray = (cbor: Cbor): CborArrayWrapper | undefined => {
|
|
802
|
+
if (cbor.type !== MajorType.Array) {
|
|
803
|
+
return undefined;
|
|
804
|
+
}
|
|
805
|
+
const arr = cbor.value;
|
|
806
|
+
return {
|
|
807
|
+
length: arr.length,
|
|
808
|
+
get(index: number): Cbor | undefined {
|
|
809
|
+
return arr[index];
|
|
810
|
+
},
|
|
811
|
+
[Symbol.iterator](): Iterator<Cbor> {
|
|
812
|
+
return arr[Symbol.iterator]();
|
|
813
|
+
},
|
|
814
|
+
};
|
|
815
|
+
};
|
|
816
|
+
|
|
817
|
+
/**
|
|
818
|
+
* Alias for asMap - extract map value if type matches.
|
|
819
|
+
* Named asCborMap for envelope compatibility.
|
|
820
|
+
*
|
|
821
|
+
* @param cbor - CBOR value
|
|
822
|
+
* @returns Map or undefined
|
|
823
|
+
*/
|
|
824
|
+
export const asCborMap = asMap;
|
|
825
|
+
|
|
826
|
+
/**
|
|
827
|
+
* Check if CBOR value is any numeric type (unsigned, negative, or float).
|
|
828
|
+
*
|
|
829
|
+
* @param cbor - CBOR value
|
|
830
|
+
* @returns True if value is numeric
|
|
831
|
+
*/
|
|
832
|
+
export const isNumber = (cbor: Cbor): boolean => {
|
|
833
|
+
if (cbor.type === MajorType.Unsigned || cbor.type === MajorType.Negative) {
|
|
834
|
+
return true;
|
|
835
|
+
}
|
|
836
|
+
if (cbor.type === MajorType.Simple) {
|
|
837
|
+
return isSimpleFloat(cbor.value);
|
|
838
|
+
}
|
|
839
|
+
return false;
|
|
840
|
+
};
|