@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,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* String utilities for dCBOR, including Unicode normalization.
|
|
3
|
+
*
|
|
4
|
+
* @module string-util
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Flank a string with left and right strings.
|
|
9
|
+
*
|
|
10
|
+
* @param s - String to flank
|
|
11
|
+
* @param left - Left flanking string
|
|
12
|
+
* @param right - Right flanking string
|
|
13
|
+
* @returns Flanked string
|
|
14
|
+
*/
|
|
15
|
+
export const flanked = (s: string, left: string, right: string): string => left + s + right;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Check if a character is printable.
|
|
19
|
+
*
|
|
20
|
+
* @param c - Character to check
|
|
21
|
+
* @returns True if printable
|
|
22
|
+
*/
|
|
23
|
+
export const isPrintable = (c: string): boolean => {
|
|
24
|
+
if (c.length !== 1) return false;
|
|
25
|
+
const code = c.charCodeAt(0);
|
|
26
|
+
// Non-ASCII or ASCII printable (32-126)
|
|
27
|
+
return code > 127 || (code >= 32 && code <= 126);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Sanitize a string by replacing non-printable characters with dots.
|
|
32
|
+
* Returns None if the string has no printable characters.
|
|
33
|
+
*
|
|
34
|
+
* @param str - String to sanitize
|
|
35
|
+
* @returns Sanitized string or undefined if no printable characters
|
|
36
|
+
*/
|
|
37
|
+
export const sanitized = (str: string): string | undefined => {
|
|
38
|
+
let hasPrintable = false;
|
|
39
|
+
const chars: string[] = [];
|
|
40
|
+
|
|
41
|
+
for (const c of str) {
|
|
42
|
+
if (isPrintable(c)) {
|
|
43
|
+
hasPrintable = true;
|
|
44
|
+
chars.push(c);
|
|
45
|
+
} else {
|
|
46
|
+
chars.push(".");
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (!hasPrintable) {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return chars.join("");
|
|
55
|
+
};
|
package/src/tag.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CBOR Tag support for semantic tagging of values.
|
|
3
|
+
*
|
|
4
|
+
* Tags provide semantic information about CBOR data items.
|
|
5
|
+
* For example, tag 1 indicates a date/time value.
|
|
6
|
+
*
|
|
7
|
+
* @module tag
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { CborNumber } from "./cbor";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* A CBOR tag with an optional name.
|
|
14
|
+
*
|
|
15
|
+
* Tags consist of a numeric value and an optional human-readable name.
|
|
16
|
+
*/
|
|
17
|
+
export interface Tag {
|
|
18
|
+
/** The numeric tag value */
|
|
19
|
+
readonly value: CborNumber;
|
|
20
|
+
/** Optional human-readable name for the tag */
|
|
21
|
+
readonly name?: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Create a new Tag.
|
|
26
|
+
*
|
|
27
|
+
* @param value - The numeric tag value
|
|
28
|
+
* @param name - Optional human-readable name
|
|
29
|
+
* @returns A new Tag object
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```typescript
|
|
33
|
+
* const dateTag = createTag(1, 'date');
|
|
34
|
+
* const customTag = createTag(12345, 'myCustomTag');
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export const createTag = (value: CborNumber, name?: string): Tag => {
|
|
38
|
+
if (name !== undefined) {
|
|
39
|
+
return { value, name };
|
|
40
|
+
}
|
|
41
|
+
return { value };
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Get the string representation of a tag.
|
|
46
|
+
* Internal function used for error messages.
|
|
47
|
+
*
|
|
48
|
+
* @param tag - The tag to represent
|
|
49
|
+
* @returns String representation (name if available, otherwise value)
|
|
50
|
+
*
|
|
51
|
+
* @internal
|
|
52
|
+
*/
|
|
53
|
+
export const tagToString = (tag: Tag): string => tag.name ?? tag.value.toString();
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tag registry and management system.
|
|
3
|
+
*
|
|
4
|
+
* The TagsStore provides a centralized registry for CBOR tags,
|
|
5
|
+
* including name resolution and custom summarizer functions.
|
|
6
|
+
*
|
|
7
|
+
* @module tags-store
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { Cbor, CborNumber } from "./cbor";
|
|
11
|
+
import type { Tag } from "./tag";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Function type for custom CBOR value summarizers.
|
|
15
|
+
*
|
|
16
|
+
* Summarizers provide custom string representations for tagged values.
|
|
17
|
+
*
|
|
18
|
+
* @param cbor - The CBOR value to summarize
|
|
19
|
+
* @param flat - If true, produce single-line output
|
|
20
|
+
* @returns String summary of the value
|
|
21
|
+
*/
|
|
22
|
+
export type CborSummarizer = (cbor: Cbor, flat: boolean) => string;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Interface for tag store operations.
|
|
26
|
+
*/
|
|
27
|
+
export interface TagsStoreTrait {
|
|
28
|
+
/**
|
|
29
|
+
* Get the assigned name for a tag, if any.
|
|
30
|
+
*
|
|
31
|
+
* @param tag - The tag to look up
|
|
32
|
+
* @returns The assigned name, or undefined if no name is registered
|
|
33
|
+
*/
|
|
34
|
+
assignedNameForTag(tag: Tag): string | undefined;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Get a display name for a tag.
|
|
38
|
+
*
|
|
39
|
+
* @param tag - The tag to get a name for
|
|
40
|
+
* @returns The assigned name if available, otherwise the tag value as a string
|
|
41
|
+
*/
|
|
42
|
+
nameForTag(tag: Tag): string;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Look up a tag by its numeric value.
|
|
46
|
+
*
|
|
47
|
+
* @param value - The numeric tag value
|
|
48
|
+
* @returns The Tag object if found, undefined otherwise
|
|
49
|
+
*/
|
|
50
|
+
tagForValue(value: CborNumber): Tag | undefined;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Look up a tag by its name.
|
|
54
|
+
*
|
|
55
|
+
* @param name - The tag name
|
|
56
|
+
* @returns The Tag object if found, undefined otherwise
|
|
57
|
+
*/
|
|
58
|
+
tagForName(name: string): Tag | undefined;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Get a display name for a tag value.
|
|
62
|
+
*
|
|
63
|
+
* @param value - The numeric tag value
|
|
64
|
+
* @returns The tag name if registered, otherwise the value as a string
|
|
65
|
+
*/
|
|
66
|
+
nameForValue(value: CborNumber): string;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Get a custom summarizer function for a tag, if registered.
|
|
70
|
+
*
|
|
71
|
+
* @param tag - The numeric tag value
|
|
72
|
+
* @returns The summarizer function if registered, undefined otherwise
|
|
73
|
+
*/
|
|
74
|
+
summarizer(tag: CborNumber): CborSummarizer | undefined;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Tag registry implementation.
|
|
79
|
+
*
|
|
80
|
+
* Stores tags with their names and optional summarizer functions.
|
|
81
|
+
*/
|
|
82
|
+
export class TagsStore implements TagsStoreTrait {
|
|
83
|
+
readonly #tagsByValue = new Map<string, Tag>();
|
|
84
|
+
readonly #tagsByName = new Map<string, Tag>();
|
|
85
|
+
readonly #summarizers = new Map<string, CborSummarizer>();
|
|
86
|
+
|
|
87
|
+
constructor() {
|
|
88
|
+
// Start with empty store, matching Rust's Default implementation
|
|
89
|
+
// Tags must be explicitly registered using insert() or registerTags()
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Insert a tag into the registry.
|
|
94
|
+
*
|
|
95
|
+
* @param tag - The tag to register
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* ```typescript
|
|
99
|
+
* const store = new TagsStore();
|
|
100
|
+
* store.insert(createTag(12345, 'myCustomTag'));
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
insert(tag: Tag): void {
|
|
104
|
+
const key = this.#valueKey(tag.value);
|
|
105
|
+
this.#tagsByValue.set(key, tag);
|
|
106
|
+
if (tag.name !== undefined) {
|
|
107
|
+
this.#tagsByName.set(tag.name, tag);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Insert multiple tags into the registry.
|
|
113
|
+
* Matches Rust's insert_all() method.
|
|
114
|
+
*
|
|
115
|
+
* @param tags - Array of tags to register
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```typescript
|
|
119
|
+
* const store = new TagsStore();
|
|
120
|
+
* store.insertAll([
|
|
121
|
+
* createTag(1, 'date'),
|
|
122
|
+
* createTag(100, 'custom')
|
|
123
|
+
* ]);
|
|
124
|
+
* ```
|
|
125
|
+
*/
|
|
126
|
+
insertAll(tags: Tag[]): void {
|
|
127
|
+
for (const tag of tags) {
|
|
128
|
+
this.insert(tag);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Register a custom summarizer function for a tag.
|
|
134
|
+
*
|
|
135
|
+
* @param tagValue - The numeric tag value
|
|
136
|
+
* @param summarizer - The summarizer function
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* ```typescript
|
|
140
|
+
* store.setSummarizer(1, (cbor, flat) => {
|
|
141
|
+
* // Custom date formatting
|
|
142
|
+
* return `Date(${extractCbor(cbor)})`;
|
|
143
|
+
* });
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
146
|
+
setSummarizer(tagValue: CborNumber, summarizer: CborSummarizer): void {
|
|
147
|
+
const key = this.#valueKey(tagValue);
|
|
148
|
+
this.#summarizers.set(key, summarizer);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Remove a tag from the registry.
|
|
153
|
+
*
|
|
154
|
+
* @param tagValue - The numeric tag value to remove
|
|
155
|
+
* @returns true if a tag was removed, false otherwise
|
|
156
|
+
*/
|
|
157
|
+
remove(tagValue: CborNumber): boolean {
|
|
158
|
+
const key = this.#valueKey(tagValue);
|
|
159
|
+
const tag = this.#tagsByValue.get(key);
|
|
160
|
+
if (tag === undefined) {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
this.#tagsByValue.delete(key);
|
|
165
|
+
if (tag.name !== undefined) {
|
|
166
|
+
this.#tagsByName.delete(tag.name);
|
|
167
|
+
}
|
|
168
|
+
this.#summarizers.delete(key);
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
assignedNameForTag(tag: Tag): string | undefined {
|
|
173
|
+
const key = this.#valueKey(tag.value);
|
|
174
|
+
const stored = this.#tagsByValue.get(key);
|
|
175
|
+
return stored?.name;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
nameForTag(tag: Tag): string {
|
|
179
|
+
return this.assignedNameForTag(tag) ?? tag.value.toString();
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
tagForValue(value: CborNumber): Tag | undefined {
|
|
183
|
+
const key = this.#valueKey(value);
|
|
184
|
+
return this.#tagsByValue.get(key);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
tagForName(name: string): Tag | undefined {
|
|
188
|
+
return this.#tagsByName.get(name);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
nameForValue(value: CborNumber): string {
|
|
192
|
+
const tag = this.tagForValue(value);
|
|
193
|
+
return tag !== undefined ? this.nameForTag(tag) : value.toString();
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
summarizer(tag: CborNumber): CborSummarizer | undefined {
|
|
197
|
+
const key = this.#valueKey(tag);
|
|
198
|
+
return this.#summarizers.get(key);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Get all registered tags.
|
|
203
|
+
*
|
|
204
|
+
* @returns Array of all registered tags
|
|
205
|
+
*/
|
|
206
|
+
getAllTags(): Tag[] {
|
|
207
|
+
return Array.from(this.#tagsByValue.values());
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Clear all registered tags and summarizers.
|
|
212
|
+
*/
|
|
213
|
+
clear(): void {
|
|
214
|
+
this.#tagsByValue.clear();
|
|
215
|
+
this.#tagsByName.clear();
|
|
216
|
+
this.#summarizers.clear();
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Get the number of registered tags.
|
|
221
|
+
*
|
|
222
|
+
* @returns Number of tags in the registry
|
|
223
|
+
*/
|
|
224
|
+
get size(): number {
|
|
225
|
+
return this.#tagsByValue.size;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Create a string key for a numeric tag value.
|
|
230
|
+
* Handles both number and bigint types.
|
|
231
|
+
*
|
|
232
|
+
* @private
|
|
233
|
+
*/
|
|
234
|
+
#valueKey(value: CborNumber): string {
|
|
235
|
+
return value.toString();
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// ============================================================================
|
|
240
|
+
// Global Tags Store Singleton
|
|
241
|
+
// ============================================================================
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Global singleton instance of the tags store.
|
|
245
|
+
*/
|
|
246
|
+
let globalTagsStore: TagsStore | undefined;
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Get the global tags store instance.
|
|
250
|
+
*
|
|
251
|
+
* Creates the instance on first access.
|
|
252
|
+
*
|
|
253
|
+
* @returns The global TagsStore instance
|
|
254
|
+
*
|
|
255
|
+
* @example
|
|
256
|
+
* ```typescript
|
|
257
|
+
* const store = getGlobalTagsStore();
|
|
258
|
+
* store.insert(createTag(999, 'myTag'));
|
|
259
|
+
* ```
|
|
260
|
+
*/
|
|
261
|
+
export const getGlobalTagsStore = (): TagsStore => {
|
|
262
|
+
globalTagsStore ??= new TagsStore();
|
|
263
|
+
return globalTagsStore;
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Execute a function with access to the global tags store.
|
|
268
|
+
*
|
|
269
|
+
* @template T - Return type of the action function
|
|
270
|
+
* @param action - Function to execute with the tags store
|
|
271
|
+
* @returns Result of the action function
|
|
272
|
+
*
|
|
273
|
+
* @example
|
|
274
|
+
* ```typescript
|
|
275
|
+
* const tagName = withTags(store => store.nameForValue(1));
|
|
276
|
+
* console.log(tagName); // 'date'
|
|
277
|
+
* ```
|
|
278
|
+
*/
|
|
279
|
+
export const withTags = <T>(action: (tags: TagsStore) => T): T => {
|
|
280
|
+
return action(getGlobalTagsStore());
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Execute a function with mutable access to the global tags store.
|
|
285
|
+
*
|
|
286
|
+
* This is an alias for withTags() for consistency with Rust API.
|
|
287
|
+
*
|
|
288
|
+
* @template T - Return type of the action function
|
|
289
|
+
* @param action - Function to execute with the tags store
|
|
290
|
+
* @returns Result of the action function
|
|
291
|
+
*/
|
|
292
|
+
export const withTagsMut = <T>(action: (tags: TagsStore) => T): T => {
|
|
293
|
+
return action(getGlobalTagsStore());
|
|
294
|
+
};
|
package/src/tags.ts
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standard CBOR tag definitions from the IANA registry.
|
|
3
|
+
*
|
|
4
|
+
* @module tags
|
|
5
|
+
* @see https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { type Tag, createTag } from "./tag";
|
|
9
|
+
|
|
10
|
+
// ============================================================================
|
|
11
|
+
// Standard Date/Time Tags
|
|
12
|
+
// ============================================================================
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Tag 0: Standard date/time string (RFC 3339)
|
|
16
|
+
*/
|
|
17
|
+
export const TAG_DATE_TIME_STRING = 0;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Tag 1: Epoch-based date/time (seconds since 1970-01-01T00:00:00Z)
|
|
21
|
+
*/
|
|
22
|
+
export const TAG_EPOCH_DATE_TIME = 1;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Tag 100: Epoch-based date (days since 1970-01-01)
|
|
26
|
+
*/
|
|
27
|
+
export const TAG_EPOCH_DATE = 100;
|
|
28
|
+
|
|
29
|
+
// ============================================================================
|
|
30
|
+
// Numeric Tags
|
|
31
|
+
// ============================================================================
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Tag 2: Positive bignum (unsigned arbitrary-precision integer)
|
|
35
|
+
*/
|
|
36
|
+
export const TAG_POSITIVE_BIGNUM = 2;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Tag 3: Negative bignum (signed arbitrary-precision integer)
|
|
40
|
+
*/
|
|
41
|
+
export const TAG_NEGATIVE_BIGNUM = 3;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Tag 4: Decimal fraction [exponent, mantissa]
|
|
45
|
+
*/
|
|
46
|
+
export const TAG_DECIMAL_FRACTION = 4;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Tag 5: Bigfloat [exponent, mantissa]
|
|
50
|
+
*/
|
|
51
|
+
export const TAG_BIGFLOAT = 5;
|
|
52
|
+
|
|
53
|
+
// ============================================================================
|
|
54
|
+
// Encoding Hints
|
|
55
|
+
// ============================================================================
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Tag 21: Expected conversion to base64url encoding
|
|
59
|
+
*/
|
|
60
|
+
export const TAG_BASE64URL = 21;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Tag 22: Expected conversion to base64 encoding
|
|
64
|
+
*/
|
|
65
|
+
export const TAG_BASE64 = 22;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Tag 23: Expected conversion to base16 encoding
|
|
69
|
+
*/
|
|
70
|
+
export const TAG_BASE16 = 23;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Tag 24: Encoded CBOR data item
|
|
74
|
+
*/
|
|
75
|
+
export const TAG_ENCODED_CBOR = 24;
|
|
76
|
+
|
|
77
|
+
// ============================================================================
|
|
78
|
+
// URI and Network Tags
|
|
79
|
+
// ============================================================================
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Tag 32: URI (text string)
|
|
83
|
+
*/
|
|
84
|
+
export const TAG_URI = 32;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Tag 33: base64url-encoded text
|
|
88
|
+
*/
|
|
89
|
+
export const TAG_BASE64URL_TEXT = 33;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Tag 34: base64-encoded text
|
|
93
|
+
*/
|
|
94
|
+
export const TAG_BASE64_TEXT = 34;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Tag 35: Regular expression (PCRE/ECMA262)
|
|
98
|
+
*/
|
|
99
|
+
export const TAG_REGEXP = 35;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Tag 36: MIME message
|
|
103
|
+
*/
|
|
104
|
+
export const TAG_MIME_MESSAGE = 36;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Tag 37: Binary UUID
|
|
108
|
+
*/
|
|
109
|
+
export const TAG_UUID = 37;
|
|
110
|
+
|
|
111
|
+
// ============================================================================
|
|
112
|
+
// Cryptography Tags
|
|
113
|
+
// ============================================================================
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Tag 256: string reference (namespace)
|
|
117
|
+
*/
|
|
118
|
+
export const TAG_STRING_REF_NAMESPACE = 256;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Tag 257: binary UUID reference
|
|
122
|
+
*/
|
|
123
|
+
export const TAG_BINARY_UUID = 257;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Tag 258: Set of values (array with no duplicates)
|
|
127
|
+
*/
|
|
128
|
+
export const TAG_SET = 258;
|
|
129
|
+
|
|
130
|
+
// ============================================================================
|
|
131
|
+
// NOTE: Blockchain Commons envelope and extension tags (TAG_ENVELOPE, TAG_LEAF,
|
|
132
|
+
// TAG_KNOWN_VALUE, TAG_COMPRESSED, etc.) are defined in the @bcts/tags
|
|
133
|
+
// package, NOT in dcbor. This matches the Rust architecture where bc-dcbor-rust
|
|
134
|
+
// only defines TAG_DATE, and bc-tags-rust defines all envelope-related tags.
|
|
135
|
+
// ============================================================================
|
|
136
|
+
|
|
137
|
+
// ============================================================================
|
|
138
|
+
// Self-describing CBOR
|
|
139
|
+
// ============================================================================
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Tag 55799: Self-describe CBOR (magic number 0xd9d9f7)
|
|
143
|
+
*/
|
|
144
|
+
export const TAG_SELF_DESCRIBE_CBOR = 55799;
|
|
145
|
+
|
|
146
|
+
// ============================================================================
|
|
147
|
+
// Global Tags Store Registration
|
|
148
|
+
// Matches Rust's register_tags() functionality
|
|
149
|
+
// ============================================================================
|
|
150
|
+
|
|
151
|
+
import type { TagsStore } from "./tags-store";
|
|
152
|
+
import { getGlobalTagsStore } from "./tags-store";
|
|
153
|
+
import { CborDate } from "./date";
|
|
154
|
+
import type { Cbor } from "./cbor";
|
|
155
|
+
import { diagnostic } from "./diag";
|
|
156
|
+
|
|
157
|
+
// Tag constants matching Rust
|
|
158
|
+
export const TAG_DATE = 1;
|
|
159
|
+
export const TAG_NAME_DATE = "date";
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Register standard tags in a specific tags store.
|
|
163
|
+
* Matches Rust's register_tags_in() function.
|
|
164
|
+
*
|
|
165
|
+
* @param tagsStore - The tags store to register tags into
|
|
166
|
+
*/
|
|
167
|
+
export const registerTagsIn = (tagsStore: TagsStore): void => {
|
|
168
|
+
const tags = [createTag(TAG_DATE, TAG_NAME_DATE)];
|
|
169
|
+
tagsStore.insertAll(tags);
|
|
170
|
+
|
|
171
|
+
// Set summarizer for date tag
|
|
172
|
+
tagsStore.setSummarizer(TAG_DATE, (untaggedCbor: Cbor, _flat: boolean): string => {
|
|
173
|
+
try {
|
|
174
|
+
return CborDate.fromUntaggedCbor(untaggedCbor).toString();
|
|
175
|
+
} catch {
|
|
176
|
+
return diagnostic(untaggedCbor);
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Register standard tags in the global tags store.
|
|
183
|
+
* Matches Rust's register_tags() function.
|
|
184
|
+
*
|
|
185
|
+
* This function is idempotent - calling it multiple times is safe.
|
|
186
|
+
*/
|
|
187
|
+
export const registerTags = (): void => {
|
|
188
|
+
const globalStore = getGlobalTagsStore();
|
|
189
|
+
registerTagsIn(globalStore);
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Converts an array of tag values to their corresponding Tag objects.
|
|
194
|
+
* Matches Rust's tags_for_values() function.
|
|
195
|
+
*
|
|
196
|
+
* This function looks up each tag value in the global tag registry and returns
|
|
197
|
+
* an array of complete Tag objects. For any tag values that aren't
|
|
198
|
+
* registered in the global registry, it creates a basic Tag with just the
|
|
199
|
+
* value (no name).
|
|
200
|
+
*
|
|
201
|
+
* @param values - Array of numeric tag values to convert
|
|
202
|
+
* @returns Array of Tag objects corresponding to the input values
|
|
203
|
+
*
|
|
204
|
+
* @example
|
|
205
|
+
* ```typescript
|
|
206
|
+
* // Register some tags first
|
|
207
|
+
* registerTags();
|
|
208
|
+
*
|
|
209
|
+
* // Convert tag values to Tag objects
|
|
210
|
+
* const tags = tagsForValues([1, 42, 999]);
|
|
211
|
+
*
|
|
212
|
+
* // The first tag (value 1) should be registered as "date"
|
|
213
|
+
* console.log(tags[0].value); // 1
|
|
214
|
+
* console.log(tags[0].name); // "date"
|
|
215
|
+
*
|
|
216
|
+
* // Unregistered tags will have a value but no name
|
|
217
|
+
* console.log(tags[1].value); // 42
|
|
218
|
+
* console.log(tags[2].value); // 999
|
|
219
|
+
* ```
|
|
220
|
+
*/
|
|
221
|
+
export const tagsForValues = (values: (number | bigint)[]): Tag[] => {
|
|
222
|
+
const globalStore = getGlobalTagsStore();
|
|
223
|
+
return values.map((value) => {
|
|
224
|
+
const tag = globalStore.tagForValue(value);
|
|
225
|
+
if (tag !== undefined) {
|
|
226
|
+
return tag;
|
|
227
|
+
}
|
|
228
|
+
// Create basic tag with just the value
|
|
229
|
+
return createTag(value);
|
|
230
|
+
});
|
|
231
|
+
};
|