@bcts/envelope 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 +23 -0
- package/dist/index.cjs +2646 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +782 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +782 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.iife.js +2644 -0
- package/dist/index.iife.js.map +1 -0
- package/dist/index.mjs +2552 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +84 -0
- package/src/base/assertion.ts +179 -0
- package/src/base/assertions.ts +153 -0
- package/src/base/cbor.ts +122 -0
- package/src/base/digest.ts +204 -0
- package/src/base/elide.ts +390 -0
- package/src/base/envelope-decodable.ts +186 -0
- package/src/base/envelope-encodable.ts +71 -0
- package/src/base/envelope.ts +988 -0
- package/src/base/error.ts +421 -0
- package/src/base/index.ts +56 -0
- package/src/base/leaf.ts +147 -0
- package/src/base/queries.ts +244 -0
- package/src/base/walk.ts +215 -0
- package/src/base/wrap.ts +26 -0
- package/src/extension/attachment.ts +280 -0
- package/src/extension/compress.ts +176 -0
- package/src/extension/encrypt.ts +297 -0
- package/src/extension/expression.ts +404 -0
- package/src/extension/index.ts +72 -0
- package/src/extension/proof.ts +227 -0
- package/src/extension/recipient.ts +440 -0
- package/src/extension/salt.ts +114 -0
- package/src/extension/signature.ts +398 -0
- package/src/extension/types.ts +92 -0
- package/src/format/diagnostic.ts +116 -0
- package/src/format/hex.ts +25 -0
- package/src/format/index.ts +13 -0
- package/src/format/tree.ts +168 -0
- package/src/index.ts +32 -0
- package/src/utils/index.ts +8 -0
- package/src/utils/string.ts +48 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { Envelope } from "../base/envelope";
|
|
2
|
+
import { type EdgeType, edgeLabel } from "../base/walk";
|
|
3
|
+
|
|
4
|
+
/// Tree formatting for Gordian Envelopes.
|
|
5
|
+
///
|
|
6
|
+
/// This module provides functionality for creating textual tree
|
|
7
|
+
/// representations of envelopes, which is useful for debugging and visualizing
|
|
8
|
+
/// the hierarchical structure of complex envelopes.
|
|
9
|
+
///
|
|
10
|
+
/// The tree format displays each component of an envelope (subject and
|
|
11
|
+
/// assertions) as nodes in a tree, making it easy to understand the
|
|
12
|
+
/// hierarchical structure of nested envelopes. Each node includes:
|
|
13
|
+
///
|
|
14
|
+
/// - The first 8 characters of the element's digest (for easy reference)
|
|
15
|
+
/// - The type of the element (NODE, ASSERTION, ELIDED, etc.)
|
|
16
|
+
/// - The content of the element (for leaf nodes)
|
|
17
|
+
|
|
18
|
+
/// Options for tree formatting
|
|
19
|
+
export interface TreeFormatOptions {
|
|
20
|
+
/// If true, hides NODE identifiers and only shows semantic content
|
|
21
|
+
hideNodes?: boolean;
|
|
22
|
+
/// Set of digest strings to highlight in the tree
|
|
23
|
+
highlightDigests?: Set<string>;
|
|
24
|
+
/// Format for displaying digests
|
|
25
|
+
digestDisplay?: "short" | "full";
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/// Represents an element in the tree representation
|
|
29
|
+
interface TreeElement {
|
|
30
|
+
/// Indentation level
|
|
31
|
+
level: number;
|
|
32
|
+
/// The envelope element
|
|
33
|
+
envelope: Envelope;
|
|
34
|
+
/// Type of incoming edge
|
|
35
|
+
incomingEdge: EdgeType;
|
|
36
|
+
/// Whether to show the digest ID
|
|
37
|
+
showId: boolean;
|
|
38
|
+
/// Whether this element is highlighted
|
|
39
|
+
isHighlighted: boolean;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Note: Method declarations are in the base Envelope class.
|
|
43
|
+
// This module provides the prototype implementations.
|
|
44
|
+
|
|
45
|
+
/// Implementation of shortId()
|
|
46
|
+
Envelope.prototype.shortId = function (this: Envelope, format: "short" | "full" = "short"): string {
|
|
47
|
+
const digest = this.digest();
|
|
48
|
+
if (format === "full") {
|
|
49
|
+
return digest.hex();
|
|
50
|
+
}
|
|
51
|
+
return digest.short();
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/// Implementation of summary()
|
|
55
|
+
Envelope.prototype.summary = function (this: Envelope, maxLength = 40): string {
|
|
56
|
+
const c = this.case();
|
|
57
|
+
|
|
58
|
+
switch (c.type) {
|
|
59
|
+
case "node":
|
|
60
|
+
return "NODE";
|
|
61
|
+
case "leaf": {
|
|
62
|
+
// Try to extract a readable value
|
|
63
|
+
try {
|
|
64
|
+
const text = this.asText();
|
|
65
|
+
if (text !== undefined) {
|
|
66
|
+
const truncated = text.length > maxLength ? `${text.substring(0, maxLength)}...` : text;
|
|
67
|
+
return JSON.stringify(truncated);
|
|
68
|
+
}
|
|
69
|
+
} catch {
|
|
70
|
+
// Fall through
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
try {
|
|
74
|
+
const num = this.extractNumber();
|
|
75
|
+
return String(num);
|
|
76
|
+
} catch {
|
|
77
|
+
// Fall through
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
try {
|
|
81
|
+
const bool = this.extractBoolean();
|
|
82
|
+
return String(bool);
|
|
83
|
+
} catch {
|
|
84
|
+
// Fall through
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (this.isNull()) {
|
|
88
|
+
return "null";
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Fallback: show byte string
|
|
92
|
+
const bytes = this.asByteString();
|
|
93
|
+
if (bytes !== undefined && bytes.length <= 16) {
|
|
94
|
+
const hex = Array.from(bytes)
|
|
95
|
+
.map((b) => b.toString(16).padStart(2, "0"))
|
|
96
|
+
.join("");
|
|
97
|
+
return `h'${hex}'`;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return "LEAF";
|
|
101
|
+
}
|
|
102
|
+
case "wrapped":
|
|
103
|
+
return "WRAPPED";
|
|
104
|
+
case "assertion":
|
|
105
|
+
return "ASSERTION";
|
|
106
|
+
case "elided":
|
|
107
|
+
return "ELIDED";
|
|
108
|
+
case "encrypted":
|
|
109
|
+
return "ENCRYPTED";
|
|
110
|
+
case "compressed":
|
|
111
|
+
return "COMPRESSED";
|
|
112
|
+
case "knownValue":
|
|
113
|
+
return "KNOWN_VALUE";
|
|
114
|
+
default:
|
|
115
|
+
return "UNKNOWN";
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
/// Implementation of treeFormat()
|
|
120
|
+
Envelope.prototype.treeFormat = function (this: Envelope, options: TreeFormatOptions = {}): string {
|
|
121
|
+
const hideNodes = options.hideNodes ?? false;
|
|
122
|
+
const highlightDigests = options.highlightDigests ?? new Set<string>();
|
|
123
|
+
const digestDisplay = options.digestDisplay ?? "short";
|
|
124
|
+
|
|
125
|
+
const elements: TreeElement[] = [];
|
|
126
|
+
|
|
127
|
+
// Walk the envelope and collect elements
|
|
128
|
+
this.walk(hideNodes, undefined, (envelope, level, incomingEdge, _state) => {
|
|
129
|
+
const digestStr = envelope.digest().short();
|
|
130
|
+
const isHighlighted = highlightDigests.has(digestStr);
|
|
131
|
+
|
|
132
|
+
elements.push({
|
|
133
|
+
level,
|
|
134
|
+
envelope,
|
|
135
|
+
incomingEdge,
|
|
136
|
+
showId: !hideNodes,
|
|
137
|
+
isHighlighted,
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
return [undefined, false];
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
// Format each element as a line
|
|
144
|
+
const lines = elements.map((elem) => {
|
|
145
|
+
const parts: string[] = [];
|
|
146
|
+
|
|
147
|
+
if (elem.isHighlighted) {
|
|
148
|
+
parts.push("*");
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (elem.showId) {
|
|
152
|
+
parts.push(elem.envelope.shortId(digestDisplay));
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const label = edgeLabel(elem.incomingEdge);
|
|
156
|
+
if (label !== undefined && label !== "") {
|
|
157
|
+
parts.push(label);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
parts.push(elem.envelope.summary(40));
|
|
161
|
+
|
|
162
|
+
const line = parts.join(" ");
|
|
163
|
+
const indent = " ".repeat(elem.level * 4);
|
|
164
|
+
return indent + line;
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
return lines.join("\n");
|
|
168
|
+
};
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/// Gordian Envelope TypeScript Library
|
|
2
|
+
///
|
|
3
|
+
/// A TypeScript implementation of Blockchain Commons' Gordian Envelope
|
|
4
|
+
/// specification for structured, privacy-focused data containers.
|
|
5
|
+
///
|
|
6
|
+
/// This is a 1:1 port of the Rust bc-envelope library, maintaining the same
|
|
7
|
+
/// API structure and functionality.
|
|
8
|
+
///
|
|
9
|
+
/// @module bc-envelope
|
|
10
|
+
|
|
11
|
+
// Re-export everything from the base module
|
|
12
|
+
export * from "./base";
|
|
13
|
+
|
|
14
|
+
// Re-export everything from the extension module
|
|
15
|
+
export * from "./extension";
|
|
16
|
+
|
|
17
|
+
// Import registration functions and call them to ensure proper initialization order
|
|
18
|
+
import { registerEncryptExtension } from "./extension/encrypt";
|
|
19
|
+
import { registerCompressExtension } from "./extension/compress";
|
|
20
|
+
registerEncryptExtension();
|
|
21
|
+
registerCompressExtension();
|
|
22
|
+
|
|
23
|
+
// Re-export everything from the format module
|
|
24
|
+
// Import for side effects (registers prototype extensions like treeFormat)
|
|
25
|
+
import "./format";
|
|
26
|
+
export type * from "./format";
|
|
27
|
+
|
|
28
|
+
// Re-export everything from the utils module
|
|
29
|
+
export * from "./utils";
|
|
30
|
+
|
|
31
|
+
// Version information
|
|
32
|
+
export const VERSION = "0.37.0";
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* String utility functions used throughout the envelope library.
|
|
3
|
+
*
|
|
4
|
+
* Provides helper methods for string formatting and manipulation.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Flanks a string with specified left and right delimiters.
|
|
9
|
+
*
|
|
10
|
+
* @param str - The string to flank
|
|
11
|
+
* @param left - The left delimiter
|
|
12
|
+
* @param right - The right delimiter
|
|
13
|
+
* @returns The flanked string
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* flanked('hello', '"', '"') // Returns: "hello"
|
|
18
|
+
* flanked('name', "'", "'") // Returns: 'name'
|
|
19
|
+
* flanked('item', '[', ']') // Returns: [item]
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export function flanked(str: string, left: string, right: string): string {
|
|
23
|
+
return `${left}${str}${right}`;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Extension methods for String objects to support fluent API style.
|
|
28
|
+
*/
|
|
29
|
+
declare global {
|
|
30
|
+
interface String {
|
|
31
|
+
/**
|
|
32
|
+
* Flanks this string with specified left and right delimiters.
|
|
33
|
+
*
|
|
34
|
+
* @param left - The left delimiter
|
|
35
|
+
* @param right - The right delimiter
|
|
36
|
+
* @returns The flanked string
|
|
37
|
+
*/
|
|
38
|
+
flankedBy(left: string, right: string): string;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Extend String prototype with flankedBy method
|
|
43
|
+
String.prototype.flankedBy = function (this: string, left: string, right: string): string {
|
|
44
|
+
return flanked(this, left, right);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// Export the extension for side-effects
|
|
48
|
+
export {};
|