@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.
Files changed (44) hide show
  1. package/LICENSE +48 -0
  2. package/README.md +23 -0
  3. package/dist/index.cjs +2646 -0
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.d.cts +782 -0
  6. package/dist/index.d.cts.map +1 -0
  7. package/dist/index.d.mts +782 -0
  8. package/dist/index.d.mts.map +1 -0
  9. package/dist/index.iife.js +2644 -0
  10. package/dist/index.iife.js.map +1 -0
  11. package/dist/index.mjs +2552 -0
  12. package/dist/index.mjs.map +1 -0
  13. package/package.json +84 -0
  14. package/src/base/assertion.ts +179 -0
  15. package/src/base/assertions.ts +153 -0
  16. package/src/base/cbor.ts +122 -0
  17. package/src/base/digest.ts +204 -0
  18. package/src/base/elide.ts +390 -0
  19. package/src/base/envelope-decodable.ts +186 -0
  20. package/src/base/envelope-encodable.ts +71 -0
  21. package/src/base/envelope.ts +988 -0
  22. package/src/base/error.ts +421 -0
  23. package/src/base/index.ts +56 -0
  24. package/src/base/leaf.ts +147 -0
  25. package/src/base/queries.ts +244 -0
  26. package/src/base/walk.ts +215 -0
  27. package/src/base/wrap.ts +26 -0
  28. package/src/extension/attachment.ts +280 -0
  29. package/src/extension/compress.ts +176 -0
  30. package/src/extension/encrypt.ts +297 -0
  31. package/src/extension/expression.ts +404 -0
  32. package/src/extension/index.ts +72 -0
  33. package/src/extension/proof.ts +227 -0
  34. package/src/extension/recipient.ts +440 -0
  35. package/src/extension/salt.ts +114 -0
  36. package/src/extension/signature.ts +398 -0
  37. package/src/extension/types.ts +92 -0
  38. package/src/format/diagnostic.ts +116 -0
  39. package/src/format/hex.ts +25 -0
  40. package/src/format/index.ts +13 -0
  41. package/src/format/tree.ts +168 -0
  42. package/src/index.ts +32 -0
  43. package/src/utils/index.ts +8 -0
  44. 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,8 @@
1
+ /**
2
+ * Utility functions for the envelope library.
3
+ */
4
+
5
+ export { flanked } from "./string";
6
+
7
+ // Side-effect import to extend String prototype
8
+ import "./string";
@@ -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 {};