@bcts/dcbor-parse 1.0.0-alpha.13
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 +1141 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +433 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +433 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.iife.js +1142 -0
- package/dist/index.iife.js.map +1 -0
- package/dist/index.mjs +1118 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +84 -0
- package/src/compose.ts +156 -0
- package/src/error.ts +373 -0
- package/src/index.ts +82 -0
- package/src/parse.ts +411 -0
- package/src/token.ts +641 -0
package/src/error.ts
ADDED
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @bcts/dcbor-parse - Error types
|
|
3
|
+
*
|
|
4
|
+
* This is a 1:1 TypeScript port of bc-dcbor-parse-rust error.rs
|
|
5
|
+
*
|
|
6
|
+
* @module dcbor-parse/error
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { Token } from "./token";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Represents a span (range) in the source string.
|
|
13
|
+
*
|
|
14
|
+
* Corresponds to the Rust `logos::Span` type.
|
|
15
|
+
*/
|
|
16
|
+
export interface Span {
|
|
17
|
+
readonly start: number;
|
|
18
|
+
readonly end: number;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Creates a span with the given start and end positions.
|
|
23
|
+
*/
|
|
24
|
+
export function span(start: number, end: number): Span {
|
|
25
|
+
return { start, end };
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Creates a default (empty) span.
|
|
30
|
+
*/
|
|
31
|
+
export function defaultSpan(): Span {
|
|
32
|
+
return { start: 0, end: 0 };
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Parse error types.
|
|
37
|
+
*
|
|
38
|
+
* Corresponds to the Rust `Error` enum in error.rs
|
|
39
|
+
*/
|
|
40
|
+
export type ParseError =
|
|
41
|
+
| { readonly type: "EmptyInput" }
|
|
42
|
+
| { readonly type: "UnexpectedEndOfInput" }
|
|
43
|
+
| { readonly type: "ExtraData"; readonly span: Span }
|
|
44
|
+
| { readonly type: "UnexpectedToken"; readonly token: Token; readonly span: Span }
|
|
45
|
+
| { readonly type: "UnrecognizedToken"; readonly span: Span }
|
|
46
|
+
| { readonly type: "ExpectedComma"; readonly span: Span }
|
|
47
|
+
| { readonly type: "ExpectedColon"; readonly span: Span }
|
|
48
|
+
| { readonly type: "UnmatchedParentheses"; readonly span: Span }
|
|
49
|
+
| { readonly type: "UnmatchedBraces"; readonly span: Span }
|
|
50
|
+
| { readonly type: "ExpectedMapKey"; readonly span: Span }
|
|
51
|
+
| { readonly type: "InvalidTagValue"; readonly value: string; readonly span: Span }
|
|
52
|
+
| { readonly type: "UnknownTagName"; readonly name: string; readonly span: Span }
|
|
53
|
+
| { readonly type: "InvalidHexString"; readonly span: Span }
|
|
54
|
+
| { readonly type: "InvalidBase64String"; readonly span: Span }
|
|
55
|
+
| { readonly type: "UnknownUrType"; readonly urType: string; readonly span: Span }
|
|
56
|
+
| { readonly type: "InvalidUr"; readonly message: string; readonly span: Span }
|
|
57
|
+
| { readonly type: "InvalidKnownValue"; readonly value: string; readonly span: Span }
|
|
58
|
+
| { readonly type: "UnknownKnownValueName"; readonly name: string; readonly span: Span }
|
|
59
|
+
| { readonly type: "InvalidDateString"; readonly dateString: string; readonly span: Span }
|
|
60
|
+
| { readonly type: "DuplicateMapKey"; readonly span: Span };
|
|
61
|
+
|
|
62
|
+
// Error constructors (lowercase to differentiate from the type)
|
|
63
|
+
export const parseError = {
|
|
64
|
+
emptyInput(): ParseError {
|
|
65
|
+
return { type: "EmptyInput" };
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
unexpectedEndOfInput(): ParseError {
|
|
69
|
+
return { type: "UnexpectedEndOfInput" };
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
extraData(span: Span): ParseError {
|
|
73
|
+
return { type: "ExtraData", span };
|
|
74
|
+
},
|
|
75
|
+
|
|
76
|
+
unexpectedToken(token: Token, span: Span): ParseError {
|
|
77
|
+
return { type: "UnexpectedToken", token, span };
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
unrecognizedToken(span: Span): ParseError {
|
|
81
|
+
return { type: "UnrecognizedToken", span };
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
expectedComma(span: Span): ParseError {
|
|
85
|
+
return { type: "ExpectedComma", span };
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
expectedColon(span: Span): ParseError {
|
|
89
|
+
return { type: "ExpectedColon", span };
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
unmatchedParentheses(span: Span): ParseError {
|
|
93
|
+
return { type: "UnmatchedParentheses", span };
|
|
94
|
+
},
|
|
95
|
+
|
|
96
|
+
unmatchedBraces(span: Span): ParseError {
|
|
97
|
+
return { type: "UnmatchedBraces", span };
|
|
98
|
+
},
|
|
99
|
+
|
|
100
|
+
expectedMapKey(span: Span): ParseError {
|
|
101
|
+
return { type: "ExpectedMapKey", span };
|
|
102
|
+
},
|
|
103
|
+
|
|
104
|
+
invalidTagValue(value: string, span: Span): ParseError {
|
|
105
|
+
return { type: "InvalidTagValue", value, span };
|
|
106
|
+
},
|
|
107
|
+
|
|
108
|
+
unknownTagName(name: string, span: Span): ParseError {
|
|
109
|
+
return { type: "UnknownTagName", name, span };
|
|
110
|
+
},
|
|
111
|
+
|
|
112
|
+
invalidHexString(span: Span): ParseError {
|
|
113
|
+
return { type: "InvalidHexString", span };
|
|
114
|
+
},
|
|
115
|
+
|
|
116
|
+
invalidBase64String(span: Span): ParseError {
|
|
117
|
+
return { type: "InvalidBase64String", span };
|
|
118
|
+
},
|
|
119
|
+
|
|
120
|
+
unknownUrType(urType: string, span: Span): ParseError {
|
|
121
|
+
return { type: "UnknownUrType", urType, span };
|
|
122
|
+
},
|
|
123
|
+
|
|
124
|
+
invalidUr(message: string, span: Span): ParseError {
|
|
125
|
+
return { type: "InvalidUr", message, span };
|
|
126
|
+
},
|
|
127
|
+
|
|
128
|
+
invalidKnownValue(value: string, span: Span): ParseError {
|
|
129
|
+
return { type: "InvalidKnownValue", value, span };
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
unknownKnownValueName(name: string, span: Span): ParseError {
|
|
133
|
+
return { type: "UnknownKnownValueName", name, span };
|
|
134
|
+
},
|
|
135
|
+
|
|
136
|
+
invalidDateString(dateString: string, span: Span): ParseError {
|
|
137
|
+
return { type: "InvalidDateString", dateString, span };
|
|
138
|
+
},
|
|
139
|
+
|
|
140
|
+
duplicateMapKey(span: Span): ParseError {
|
|
141
|
+
return { type: "DuplicateMapKey", span };
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Checks if an error is the default unrecognized token error.
|
|
147
|
+
*
|
|
148
|
+
* Corresponds to Rust `Error::is_default()`
|
|
149
|
+
*/
|
|
150
|
+
export function isDefaultError(error: ParseError): boolean {
|
|
151
|
+
return error.type === "UnrecognizedToken";
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Gets the error message for a parse error.
|
|
156
|
+
*
|
|
157
|
+
* Corresponds to Rust's `Display` implementation for `Error`
|
|
158
|
+
*/
|
|
159
|
+
export function errorMessage(error: ParseError): string {
|
|
160
|
+
switch (error.type) {
|
|
161
|
+
case "EmptyInput":
|
|
162
|
+
return "Empty input";
|
|
163
|
+
case "UnexpectedEndOfInput":
|
|
164
|
+
return "Unexpected end of input";
|
|
165
|
+
case "ExtraData":
|
|
166
|
+
return "Extra data at end of input";
|
|
167
|
+
case "UnexpectedToken":
|
|
168
|
+
return `Unexpected token ${tokenDebugString(error.token)}`;
|
|
169
|
+
case "UnrecognizedToken":
|
|
170
|
+
return "Unrecognized token";
|
|
171
|
+
case "ExpectedComma":
|
|
172
|
+
return "Expected comma";
|
|
173
|
+
case "ExpectedColon":
|
|
174
|
+
return "Expected colon";
|
|
175
|
+
case "UnmatchedParentheses":
|
|
176
|
+
return "Unmatched parentheses";
|
|
177
|
+
case "UnmatchedBraces":
|
|
178
|
+
return "Unmatched braces";
|
|
179
|
+
case "ExpectedMapKey":
|
|
180
|
+
return "Expected map key";
|
|
181
|
+
case "InvalidTagValue":
|
|
182
|
+
return `Invalid tag value '${error.value}'`;
|
|
183
|
+
case "UnknownTagName":
|
|
184
|
+
return `Unknown tag name '${error.name}'`;
|
|
185
|
+
case "InvalidHexString":
|
|
186
|
+
return "Invalid hex string";
|
|
187
|
+
case "InvalidBase64String":
|
|
188
|
+
return "Invalid base64 string";
|
|
189
|
+
case "UnknownUrType":
|
|
190
|
+
return `Unknown UR type '${error.urType}'`;
|
|
191
|
+
case "InvalidUr":
|
|
192
|
+
return `Invalid UR '${error.message}'`;
|
|
193
|
+
case "InvalidKnownValue":
|
|
194
|
+
return `Invalid known value '${error.value}'`;
|
|
195
|
+
case "UnknownKnownValueName":
|
|
196
|
+
return `Unknown known value name '${error.name}'`;
|
|
197
|
+
case "InvalidDateString":
|
|
198
|
+
return `Invalid date string '${error.dateString}'`;
|
|
199
|
+
case "DuplicateMapKey":
|
|
200
|
+
return "Duplicate map key";
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Gets the span for a parse error, if applicable.
|
|
206
|
+
*/
|
|
207
|
+
export function errorSpan(error: ParseError): Span | undefined {
|
|
208
|
+
switch (error.type) {
|
|
209
|
+
case "EmptyInput":
|
|
210
|
+
case "UnexpectedEndOfInput":
|
|
211
|
+
return undefined;
|
|
212
|
+
case "ExtraData":
|
|
213
|
+
case "UnexpectedToken":
|
|
214
|
+
case "UnrecognizedToken":
|
|
215
|
+
case "ExpectedComma":
|
|
216
|
+
case "ExpectedColon":
|
|
217
|
+
case "UnmatchedParentheses":
|
|
218
|
+
case "UnmatchedBraces":
|
|
219
|
+
case "ExpectedMapKey":
|
|
220
|
+
case "InvalidTagValue":
|
|
221
|
+
case "UnknownTagName":
|
|
222
|
+
case "InvalidHexString":
|
|
223
|
+
case "InvalidBase64String":
|
|
224
|
+
case "UnknownUrType":
|
|
225
|
+
case "InvalidUr":
|
|
226
|
+
case "InvalidKnownValue":
|
|
227
|
+
case "UnknownKnownValueName":
|
|
228
|
+
case "InvalidDateString":
|
|
229
|
+
case "DuplicateMapKey":
|
|
230
|
+
return error.span;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Formats an error message with source context, line number, and caret.
|
|
236
|
+
*
|
|
237
|
+
* Corresponds to Rust `Error::format_message()`
|
|
238
|
+
*/
|
|
239
|
+
function formatMessage(message: string, source: string, range: Span): string {
|
|
240
|
+
const start = range.start;
|
|
241
|
+
const end = range.end;
|
|
242
|
+
|
|
243
|
+
// Walk through the characters up to `start` to find line number and line start offset
|
|
244
|
+
let lineNumber = 1;
|
|
245
|
+
let lineStart = 0;
|
|
246
|
+
|
|
247
|
+
for (let idx = 0; idx < source.length && idx < start; idx++) {
|
|
248
|
+
if (source[idx] === "\n") {
|
|
249
|
+
lineNumber++;
|
|
250
|
+
lineStart = idx + 1;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Grab the exact line text (or empty if out of bounds)
|
|
255
|
+
const lines = source.split("\n");
|
|
256
|
+
const line = lines[lineNumber - 1] ?? "";
|
|
257
|
+
|
|
258
|
+
// Column is byte-offset into that line
|
|
259
|
+
const column = Math.max(0, start - lineStart);
|
|
260
|
+
|
|
261
|
+
// Underline at least one caret, even for zero-width spans
|
|
262
|
+
const underlineLen = Math.max(1, end - start);
|
|
263
|
+
const caret = " ".repeat(column) + "^".repeat(underlineLen);
|
|
264
|
+
|
|
265
|
+
return `line ${lineNumber}: ${message}\n${line}\n${caret}`;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Gets the full error message with source context.
|
|
270
|
+
*
|
|
271
|
+
* Corresponds to Rust `Error::full_message()`
|
|
272
|
+
*/
|
|
273
|
+
export function fullErrorMessage(error: ParseError, source: string): string {
|
|
274
|
+
const message = errorMessage(error);
|
|
275
|
+
|
|
276
|
+
switch (error.type) {
|
|
277
|
+
case "EmptyInput":
|
|
278
|
+
return formatMessage(message, source, defaultSpan());
|
|
279
|
+
case "UnexpectedEndOfInput":
|
|
280
|
+
return formatMessage(message, source, span(source.length, source.length));
|
|
281
|
+
case "ExtraData":
|
|
282
|
+
case "UnexpectedToken":
|
|
283
|
+
case "UnrecognizedToken":
|
|
284
|
+
case "ExpectedComma":
|
|
285
|
+
case "ExpectedColon":
|
|
286
|
+
case "UnmatchedParentheses":
|
|
287
|
+
case "UnmatchedBraces":
|
|
288
|
+
case "ExpectedMapKey":
|
|
289
|
+
case "InvalidTagValue":
|
|
290
|
+
case "UnknownTagName":
|
|
291
|
+
case "InvalidHexString":
|
|
292
|
+
case "InvalidBase64String":
|
|
293
|
+
case "UnknownUrType":
|
|
294
|
+
case "InvalidUr":
|
|
295
|
+
case "InvalidKnownValue":
|
|
296
|
+
case "UnknownKnownValueName":
|
|
297
|
+
case "InvalidDateString":
|
|
298
|
+
case "DuplicateMapKey":
|
|
299
|
+
return formatMessage(message, source, error.span);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Creates a default parse error (UnrecognizedToken with empty span).
|
|
305
|
+
*
|
|
306
|
+
* Corresponds to Rust `Error::default()`
|
|
307
|
+
*/
|
|
308
|
+
export function defaultParseError(): ParseError {
|
|
309
|
+
return parseError.unrecognizedToken(defaultSpan());
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Result type for parse operations.
|
|
314
|
+
*
|
|
315
|
+
* Corresponds to Rust `Result<T, Error>`
|
|
316
|
+
*/
|
|
317
|
+
export type ParseResult<T> =
|
|
318
|
+
| { readonly ok: true; readonly value: T }
|
|
319
|
+
| { readonly ok: false; readonly error: ParseError };
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Creates a successful result.
|
|
323
|
+
*/
|
|
324
|
+
export function ok<T>(value: T): ParseResult<T> {
|
|
325
|
+
return { ok: true, value };
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Creates an error result.
|
|
330
|
+
*/
|
|
331
|
+
export function err<T>(error: ParseError): ParseResult<T> {
|
|
332
|
+
return { ok: false, error };
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Checks if a result is successful.
|
|
337
|
+
*/
|
|
338
|
+
export function isOk<T>(result: ParseResult<T>): result is { ok: true; value: T } {
|
|
339
|
+
return result.ok;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Checks if a result is an error.
|
|
344
|
+
*/
|
|
345
|
+
export function isErr<T>(result: ParseResult<T>): result is { ok: false; error: ParseError } {
|
|
346
|
+
return !result.ok;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Unwraps a result, throwing if it's an error.
|
|
351
|
+
*/
|
|
352
|
+
export function unwrap<T>(result: ParseResult<T>): T {
|
|
353
|
+
if (result.ok) {
|
|
354
|
+
return result.value;
|
|
355
|
+
}
|
|
356
|
+
throw new Error(errorMessage(result.error));
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Unwraps a result error, throwing if it's successful.
|
|
361
|
+
*/
|
|
362
|
+
export function unwrapErr<T>(result: ParseResult<T>): ParseError {
|
|
363
|
+
if (!result.ok) {
|
|
364
|
+
return result.error;
|
|
365
|
+
}
|
|
366
|
+
throw new Error("Called unwrapErr on an Ok result");
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// Helper function to get debug string for a token (forward declaration resolved at runtime)
|
|
370
|
+
function tokenDebugString(token: Token): string {
|
|
371
|
+
// Simple debug representation
|
|
372
|
+
return JSON.stringify(token);
|
|
373
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* # dCBOR Diagnostic Parser and Composer
|
|
3
|
+
*
|
|
4
|
+
* This package provides tools for parsing and composing the [CBOR diagnostic
|
|
5
|
+
* notation](https://datatracker.ietf.org/doc/html/rfc8949#name-diagnostic-notation)
|
|
6
|
+
* into [dCBOR (deterministic CBOR)](https://datatracker.ietf.org/doc/draft-mcnally-deterministic-cbor/)
|
|
7
|
+
* data items.
|
|
8
|
+
*
|
|
9
|
+
* It is intended for use in testing, debugging, and other scenarios where a
|
|
10
|
+
* human-readable representation of dCBOR is useful. It is not optimized for
|
|
11
|
+
* performance and should not be used in production environments where binary
|
|
12
|
+
* dCBOR is expected.
|
|
13
|
+
*
|
|
14
|
+
* The primary functions provided are:
|
|
15
|
+
*
|
|
16
|
+
* - `parseDcborItem`: Parses a string in CBOR diagnostic notation into a `Cbor` object.
|
|
17
|
+
* - `composeDcborArray`: Composes a `Cbor` array from a slice of strings
|
|
18
|
+
* representing dCBOR items in diagnostic notation.
|
|
19
|
+
* - `composeDcborMap`: Composes a `Cbor` map from a slice of strings
|
|
20
|
+
* representing the key-value pairs in dCBOR diagnostic notation.
|
|
21
|
+
*
|
|
22
|
+
* ## Supported Types
|
|
23
|
+
*
|
|
24
|
+
* | Type | Example(s) |
|
|
25
|
+
* | ------------------- | ----------------------------------------------------------- |
|
|
26
|
+
* | Boolean | `true`, `false` |
|
|
27
|
+
* | Null | `null` |
|
|
28
|
+
* | Integers | `0`, `1`, `-1`, `42` |
|
|
29
|
+
* | Floats | `3.14`, `-2.5`, `Infinity`, `-Infinity`, `NaN` |
|
|
30
|
+
* | Strings | `"hello"`, `"🌎"` |
|
|
31
|
+
* | Date Literals | `2023-02-08`, `2023-02-08T15:30:45Z`, `1965-05-15` |
|
|
32
|
+
* | Hex Byte Strings | `h'68656c6c6f'` |
|
|
33
|
+
* | Base64 Byte Strings | `b64'AQIDBAUGBwgJCg=='` |
|
|
34
|
+
* | Tagged Values | `1234("hello")`, `5678(3.14)` |
|
|
35
|
+
* | Name-Tagged Values | `tag-name("hello")`, `tag-name(3.14)` |
|
|
36
|
+
* | Known Values | `'1'`, `'isA'` |
|
|
37
|
+
* | Unit Known Value | `Unit`, `''`, `'0'` |
|
|
38
|
+
* | URs | `ur:date/cyisdadmlasgtapttl` |
|
|
39
|
+
* | Arrays | `[1, 2, 3]`, `["hello", "world"]`, `[1, [2, 3]]` |
|
|
40
|
+
* | Maps | `{1: 2, 3: 4}`, `{"key": "value"}`, `{1: [2, 3], 4: 5}` |
|
|
41
|
+
*
|
|
42
|
+
* @module dcbor-parse
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
// Parse functions
|
|
46
|
+
export { parseDcborItem, parseDcborItemPartial } from "./parse";
|
|
47
|
+
|
|
48
|
+
// Token types
|
|
49
|
+
export { type Token, token, Lexer } from "./token";
|
|
50
|
+
|
|
51
|
+
// Error types
|
|
52
|
+
export {
|
|
53
|
+
type Span,
|
|
54
|
+
span,
|
|
55
|
+
defaultSpan,
|
|
56
|
+
type ParseError,
|
|
57
|
+
parseError,
|
|
58
|
+
type ParseResult,
|
|
59
|
+
ok,
|
|
60
|
+
err,
|
|
61
|
+
isOk,
|
|
62
|
+
isErr,
|
|
63
|
+
unwrap,
|
|
64
|
+
unwrapErr,
|
|
65
|
+
isDefaultError,
|
|
66
|
+
errorMessage,
|
|
67
|
+
errorSpan,
|
|
68
|
+
fullErrorMessage,
|
|
69
|
+
defaultParseError,
|
|
70
|
+
} from "./error";
|
|
71
|
+
|
|
72
|
+
// Compose functions
|
|
73
|
+
export {
|
|
74
|
+
type ComposeError,
|
|
75
|
+
composeError,
|
|
76
|
+
type ComposeResult,
|
|
77
|
+
composeOk,
|
|
78
|
+
composeErr,
|
|
79
|
+
composeErrorMessage,
|
|
80
|
+
composeDcborArray,
|
|
81
|
+
composeDcborMap,
|
|
82
|
+
} from "./compose";
|