@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,244 @@
|
|
|
1
|
+
// Cbor type available if needed later
|
|
2
|
+
import { Envelope } from "./envelope";
|
|
3
|
+
import type { EnvelopeEncodableValue } from "./envelope-encodable";
|
|
4
|
+
import { EnvelopeError } from "./error";
|
|
5
|
+
|
|
6
|
+
/// Provides methods for querying envelope structure and extracting data.
|
|
7
|
+
///
|
|
8
|
+
/// The `queries` module contains methods for:
|
|
9
|
+
///
|
|
10
|
+
/// 1. **Structural queries**: Methods for examining the envelope's structure
|
|
11
|
+
/// (`subject()`, `assertions()`)
|
|
12
|
+
/// 2. **Type queries**: Methods for determining the envelope's type
|
|
13
|
+
/// (`isLeaf()`, `isNode()`, etc.)
|
|
14
|
+
/// 3. **Content extraction**: Methods for extracting typed content from
|
|
15
|
+
/// envelopes (`extractSubject()`, `extractObjectForPredicate()`)
|
|
16
|
+
/// 4. **Assertion queries**: Methods for finding assertions with specific
|
|
17
|
+
/// predicates (`assertionWithPredicate()`)
|
|
18
|
+
///
|
|
19
|
+
/// These methods enable traversal and inspection of envelope hierarchies,
|
|
20
|
+
/// allowing for flexible manipulation and access to envelope data structures.
|
|
21
|
+
|
|
22
|
+
/// Implementation of hasAssertions()
|
|
23
|
+
Envelope.prototype.hasAssertions = function (this: Envelope): boolean {
|
|
24
|
+
const c = this.case();
|
|
25
|
+
return c.type === "node" && c.assertions.length > 0;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/// Implementation of asAssertion()
|
|
29
|
+
Envelope.prototype.asAssertion = function (this: Envelope): Envelope | undefined {
|
|
30
|
+
const c = this.case();
|
|
31
|
+
return c.type === "assertion" ? this : undefined;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/// Implementation of tryAssertion()
|
|
35
|
+
Envelope.prototype.tryAssertion = function (this: Envelope): Envelope {
|
|
36
|
+
const result = this.asAssertion();
|
|
37
|
+
if (result === undefined) {
|
|
38
|
+
throw EnvelopeError.notAssertion();
|
|
39
|
+
}
|
|
40
|
+
return result;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/// Implementation of asPredicate()
|
|
44
|
+
Envelope.prototype.asPredicate = function (this: Envelope): Envelope | undefined {
|
|
45
|
+
// Refer to subject in case the assertion is a node and therefore has
|
|
46
|
+
// its own assertions
|
|
47
|
+
const subj = this.subject();
|
|
48
|
+
const c = subj.case();
|
|
49
|
+
if (c.type === "assertion") {
|
|
50
|
+
return c.assertion.predicate();
|
|
51
|
+
}
|
|
52
|
+
return undefined;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/// Implementation of tryPredicate()
|
|
56
|
+
Envelope.prototype.tryPredicate = function (this: Envelope): Envelope {
|
|
57
|
+
const result = this.asPredicate();
|
|
58
|
+
if (result === undefined) {
|
|
59
|
+
throw EnvelopeError.notAssertion();
|
|
60
|
+
}
|
|
61
|
+
return result;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/// Implementation of asObject()
|
|
65
|
+
Envelope.prototype.asObject = function (this: Envelope): Envelope | undefined {
|
|
66
|
+
// Refer to subject in case the assertion is a node and therefore has
|
|
67
|
+
// its own assertions
|
|
68
|
+
const subj = this.subject();
|
|
69
|
+
const c = subj.case();
|
|
70
|
+
if (c.type === "assertion") {
|
|
71
|
+
return c.assertion.object();
|
|
72
|
+
}
|
|
73
|
+
return undefined;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
/// Implementation of tryObject()
|
|
77
|
+
Envelope.prototype.tryObject = function (this: Envelope): Envelope {
|
|
78
|
+
const result = this.asObject();
|
|
79
|
+
if (result === undefined) {
|
|
80
|
+
throw EnvelopeError.notAssertion();
|
|
81
|
+
}
|
|
82
|
+
return result;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
/// Implementation of isAssertion()
|
|
86
|
+
Envelope.prototype.isAssertion = function (this: Envelope): boolean {
|
|
87
|
+
return this.case().type === "assertion";
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
/// Implementation of isElided()
|
|
91
|
+
Envelope.prototype.isElided = function (this: Envelope): boolean {
|
|
92
|
+
return this.case().type === "elided";
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
/// Implementation of isLeaf()
|
|
96
|
+
Envelope.prototype.isLeaf = function (this: Envelope): boolean {
|
|
97
|
+
return this.case().type === "leaf";
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
/// Implementation of isNode()
|
|
101
|
+
Envelope.prototype.isNode = function (this: Envelope): boolean {
|
|
102
|
+
return this.case().type === "node";
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
/// Implementation of isWrapped()
|
|
106
|
+
Envelope.prototype.isWrapped = function (this: Envelope): boolean {
|
|
107
|
+
return this.case().type === "wrapped";
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
/// Implementation of isInternal()
|
|
111
|
+
Envelope.prototype.isInternal = function (this: Envelope): boolean {
|
|
112
|
+
const type = this.case().type;
|
|
113
|
+
return type === "node" || type === "wrapped" || type === "assertion";
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
/// Implementation of isObscured()
|
|
117
|
+
Envelope.prototype.isObscured = function (this: Envelope): boolean {
|
|
118
|
+
const type = this.case().type;
|
|
119
|
+
return type === "elided" || type === "encrypted" || type === "compressed";
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
/// Implementation of assertionsWithPredicate()
|
|
123
|
+
Envelope.prototype.assertionsWithPredicate = function (
|
|
124
|
+
this: Envelope,
|
|
125
|
+
predicate: EnvelopeEncodableValue,
|
|
126
|
+
): Envelope[] {
|
|
127
|
+
const predicateEnv = Envelope.new(predicate);
|
|
128
|
+
const predicateDigest = predicateEnv.digest();
|
|
129
|
+
|
|
130
|
+
return this.assertions().filter((assertion) => {
|
|
131
|
+
const pred = assertion.subject().asPredicate();
|
|
132
|
+
return pred?.digest().equals(predicateDigest) === true;
|
|
133
|
+
});
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
/// Implementation of assertionWithPredicate()
|
|
137
|
+
Envelope.prototype.assertionWithPredicate = function (
|
|
138
|
+
this: Envelope,
|
|
139
|
+
predicate: EnvelopeEncodableValue,
|
|
140
|
+
): Envelope {
|
|
141
|
+
const matches = this.assertionsWithPredicate(predicate);
|
|
142
|
+
|
|
143
|
+
if (matches.length === 0) {
|
|
144
|
+
throw EnvelopeError.nonexistentPredicate();
|
|
145
|
+
}
|
|
146
|
+
if (matches.length > 1) {
|
|
147
|
+
throw EnvelopeError.ambiguousPredicate();
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return matches[0];
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
/// Implementation of optionalAssertionWithPredicate()
|
|
154
|
+
Envelope.prototype.optionalAssertionWithPredicate = function (
|
|
155
|
+
this: Envelope,
|
|
156
|
+
predicate: EnvelopeEncodableValue,
|
|
157
|
+
): Envelope | undefined {
|
|
158
|
+
const matches = this.assertionsWithPredicate(predicate);
|
|
159
|
+
|
|
160
|
+
if (matches.length === 0) {
|
|
161
|
+
return undefined;
|
|
162
|
+
}
|
|
163
|
+
if (matches.length > 1) {
|
|
164
|
+
throw EnvelopeError.ambiguousPredicate();
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return matches[0];
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
/// Implementation of objectForPredicate()
|
|
171
|
+
Envelope.prototype.objectForPredicate = function (
|
|
172
|
+
this: Envelope,
|
|
173
|
+
predicate: EnvelopeEncodableValue,
|
|
174
|
+
): Envelope {
|
|
175
|
+
const assertion = this.assertionWithPredicate(predicate);
|
|
176
|
+
const obj = assertion.asObject();
|
|
177
|
+
if (obj === undefined) {
|
|
178
|
+
throw EnvelopeError.notAssertion();
|
|
179
|
+
}
|
|
180
|
+
return obj;
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
/// Implementation of optionalObjectForPredicate()
|
|
184
|
+
Envelope.prototype.optionalObjectForPredicate = function (
|
|
185
|
+
this: Envelope,
|
|
186
|
+
predicate: EnvelopeEncodableValue,
|
|
187
|
+
): Envelope | undefined {
|
|
188
|
+
const matches = this.assertionsWithPredicate(predicate);
|
|
189
|
+
|
|
190
|
+
if (matches.length === 0) {
|
|
191
|
+
return undefined;
|
|
192
|
+
}
|
|
193
|
+
if (matches.length > 1) {
|
|
194
|
+
throw EnvelopeError.ambiguousPredicate();
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const obj = matches[0].subject().asObject();
|
|
198
|
+
return obj;
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
/// Implementation of objectsForPredicate()
|
|
202
|
+
Envelope.prototype.objectsForPredicate = function (
|
|
203
|
+
this: Envelope,
|
|
204
|
+
predicate: EnvelopeEncodableValue,
|
|
205
|
+
): Envelope[] {
|
|
206
|
+
return this.assertionsWithPredicate(predicate).map((assertion) => {
|
|
207
|
+
const obj = assertion.asObject();
|
|
208
|
+
if (obj === undefined) {
|
|
209
|
+
throw EnvelopeError.notAssertion();
|
|
210
|
+
}
|
|
211
|
+
return obj;
|
|
212
|
+
});
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
/// Implementation of elementsCount()
|
|
216
|
+
Envelope.prototype.elementsCount = function (this: Envelope): number {
|
|
217
|
+
let count = 1; // Count this envelope
|
|
218
|
+
|
|
219
|
+
const c = this.case();
|
|
220
|
+
switch (c.type) {
|
|
221
|
+
case "node":
|
|
222
|
+
count += c.subject.elementsCount();
|
|
223
|
+
for (const assertion of c.assertions) {
|
|
224
|
+
count += assertion.elementsCount();
|
|
225
|
+
}
|
|
226
|
+
break;
|
|
227
|
+
case "assertion":
|
|
228
|
+
count += c.assertion.predicate().elementsCount();
|
|
229
|
+
count += c.assertion.object().elementsCount();
|
|
230
|
+
break;
|
|
231
|
+
case "wrapped":
|
|
232
|
+
count += c.envelope.elementsCount();
|
|
233
|
+
break;
|
|
234
|
+
case "leaf":
|
|
235
|
+
case "elided":
|
|
236
|
+
case "knownValue":
|
|
237
|
+
case "encrypted":
|
|
238
|
+
case "compressed":
|
|
239
|
+
// These cases don't contribute additional elements
|
|
240
|
+
break;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return count;
|
|
244
|
+
};
|
package/src/base/walk.ts
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { Envelope } from "./envelope";
|
|
2
|
+
|
|
3
|
+
/// Functions for traversing and manipulating the envelope hierarchy.
|
|
4
|
+
///
|
|
5
|
+
/// This module provides functionality for traversing the hierarchical structure
|
|
6
|
+
/// of envelopes, allowing for operations such as inspection, transformation,
|
|
7
|
+
/// and extraction of specific elements. It implements a visitor pattern that
|
|
8
|
+
/// enables executing arbitrary code on each element of an envelope in a
|
|
9
|
+
/// structured way.
|
|
10
|
+
///
|
|
11
|
+
/// The traversal can be performed in two modes:
|
|
12
|
+
/// - Structure-based traversal: Visits every element in the envelope hierarchy
|
|
13
|
+
/// - Tree-based traversal: Skips node elements and focuses on the semantic
|
|
14
|
+
/// content
|
|
15
|
+
|
|
16
|
+
/// The type of incoming edge provided to the visitor.
|
|
17
|
+
///
|
|
18
|
+
/// This enum identifies how an envelope element is connected to its parent in
|
|
19
|
+
/// the hierarchy during traversal. It helps the visitor function understand the
|
|
20
|
+
/// semantic relationship between elements.
|
|
21
|
+
export enum EdgeType {
|
|
22
|
+
/// No incoming edge (root)
|
|
23
|
+
None = "none",
|
|
24
|
+
/// Element is the subject of a node
|
|
25
|
+
Subject = "subject",
|
|
26
|
+
/// Element is an assertion on a node
|
|
27
|
+
Assertion = "assertion",
|
|
28
|
+
/// Element is the predicate of an assertion
|
|
29
|
+
Predicate = "predicate",
|
|
30
|
+
/// Element is the object of an assertion
|
|
31
|
+
Object = "object",
|
|
32
|
+
/// Element is the content wrapped by another envelope
|
|
33
|
+
Content = "content",
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/// Returns a short text label for the edge type, or undefined if no label is
|
|
37
|
+
/// needed.
|
|
38
|
+
///
|
|
39
|
+
/// This is primarily used for tree formatting to identify relationships
|
|
40
|
+
/// between elements.
|
|
41
|
+
///
|
|
42
|
+
/// @param edgeType - The edge type
|
|
43
|
+
/// @returns A short label or undefined
|
|
44
|
+
export function edgeLabel(edgeType: EdgeType): string | undefined {
|
|
45
|
+
switch (edgeType) {
|
|
46
|
+
case EdgeType.Subject:
|
|
47
|
+
return "subj";
|
|
48
|
+
case EdgeType.Content:
|
|
49
|
+
return "cont";
|
|
50
|
+
case EdgeType.Predicate:
|
|
51
|
+
return "pred";
|
|
52
|
+
case EdgeType.Object:
|
|
53
|
+
return "obj";
|
|
54
|
+
case EdgeType.None:
|
|
55
|
+
case EdgeType.Assertion:
|
|
56
|
+
return undefined;
|
|
57
|
+
default:
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/// A visitor function that is called for each element in the envelope.
|
|
63
|
+
///
|
|
64
|
+
/// The visitor function takes the following parameters:
|
|
65
|
+
/// - `envelope`: The current envelope element being visited
|
|
66
|
+
/// - `level`: The depth level in the hierarchy (0 for root)
|
|
67
|
+
/// - `incomingEdge`: The type of edge connecting this element to its parent
|
|
68
|
+
/// - `state`: Optional context passed down from the parent's visitor call
|
|
69
|
+
///
|
|
70
|
+
/// The visitor returns a tuple of:
|
|
71
|
+
/// - The state that will be passed to child elements
|
|
72
|
+
/// - A boolean indicating whether to stop traversal (true = stop)
|
|
73
|
+
///
|
|
74
|
+
/// This enables accumulating state or passing context during traversal.
|
|
75
|
+
export type Visitor<State> = (
|
|
76
|
+
envelope: Envelope,
|
|
77
|
+
level: number,
|
|
78
|
+
incomingEdge: EdgeType,
|
|
79
|
+
state: State,
|
|
80
|
+
) => [State, boolean];
|
|
81
|
+
|
|
82
|
+
/// Implementation of walk()
|
|
83
|
+
Envelope.prototype.walk = function <State>(
|
|
84
|
+
this: Envelope,
|
|
85
|
+
hideNodes: boolean,
|
|
86
|
+
state: State,
|
|
87
|
+
visit: Visitor<State>,
|
|
88
|
+
): void {
|
|
89
|
+
if (hideNodes) {
|
|
90
|
+
walkTree(this, 0, EdgeType.None, state, visit);
|
|
91
|
+
} else {
|
|
92
|
+
walkStructure(this, 0, EdgeType.None, state, visit);
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
/// Recursive implementation of structure-based traversal.
|
|
97
|
+
///
|
|
98
|
+
/// This internal function performs the actual recursive traversal of the
|
|
99
|
+
/// envelope structure, visiting every element and maintaining the
|
|
100
|
+
/// correct level and edge relationships.
|
|
101
|
+
function walkStructure<State>(
|
|
102
|
+
envelope: Envelope,
|
|
103
|
+
level: number,
|
|
104
|
+
incomingEdge: EdgeType,
|
|
105
|
+
state: State,
|
|
106
|
+
visit: Visitor<State>,
|
|
107
|
+
): void {
|
|
108
|
+
// Visit this envelope
|
|
109
|
+
const [newState, stop] = visit(envelope, level, incomingEdge, state);
|
|
110
|
+
if (stop) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const nextLevel = level + 1;
|
|
115
|
+
const c = envelope.case();
|
|
116
|
+
|
|
117
|
+
switch (c.type) {
|
|
118
|
+
case "node":
|
|
119
|
+
// Visit subject
|
|
120
|
+
walkStructure(c.subject, nextLevel, EdgeType.Subject, newState, visit);
|
|
121
|
+
// Visit all assertions
|
|
122
|
+
for (const assertion of c.assertions) {
|
|
123
|
+
walkStructure(assertion, nextLevel, EdgeType.Assertion, newState, visit);
|
|
124
|
+
}
|
|
125
|
+
break;
|
|
126
|
+
|
|
127
|
+
case "wrapped":
|
|
128
|
+
// Visit wrapped envelope
|
|
129
|
+
walkStructure(c.envelope, nextLevel, EdgeType.Content, newState, visit);
|
|
130
|
+
break;
|
|
131
|
+
|
|
132
|
+
case "assertion":
|
|
133
|
+
// Visit predicate and object
|
|
134
|
+
walkStructure(c.assertion.predicate(), nextLevel, EdgeType.Predicate, newState, visit);
|
|
135
|
+
walkStructure(c.assertion.object(), nextLevel, EdgeType.Object, newState, visit);
|
|
136
|
+
break;
|
|
137
|
+
|
|
138
|
+
case "leaf":
|
|
139
|
+
case "elided":
|
|
140
|
+
case "knownValue":
|
|
141
|
+
case "encrypted":
|
|
142
|
+
case "compressed":
|
|
143
|
+
// Leaf nodes and other types have no children
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/// Recursive implementation of tree-based traversal.
|
|
149
|
+
///
|
|
150
|
+
/// This internal function performs the actual recursive traversal of the
|
|
151
|
+
/// envelope's semantic tree, skipping node containers and focusing on
|
|
152
|
+
/// the semantic content elements. It maintains the correct level and
|
|
153
|
+
/// edge relationships while skipping structural elements.
|
|
154
|
+
function walkTree<State>(
|
|
155
|
+
envelope: Envelope,
|
|
156
|
+
level: number,
|
|
157
|
+
incomingEdge: EdgeType,
|
|
158
|
+
state: State,
|
|
159
|
+
visit: Visitor<State>,
|
|
160
|
+
): State {
|
|
161
|
+
let currentState = state;
|
|
162
|
+
let subjectLevel = level;
|
|
163
|
+
|
|
164
|
+
// Skip visiting if this is a node
|
|
165
|
+
if (!envelope.isNode()) {
|
|
166
|
+
const [newState, stop] = visit(envelope, level, incomingEdge, currentState);
|
|
167
|
+
if (stop) {
|
|
168
|
+
return newState;
|
|
169
|
+
}
|
|
170
|
+
currentState = newState;
|
|
171
|
+
subjectLevel = level + 1;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const c = envelope.case();
|
|
175
|
+
|
|
176
|
+
switch (c.type) {
|
|
177
|
+
case "node": {
|
|
178
|
+
// Visit subject
|
|
179
|
+
const assertionState = walkTree(
|
|
180
|
+
c.subject,
|
|
181
|
+
subjectLevel,
|
|
182
|
+
EdgeType.Subject,
|
|
183
|
+
currentState,
|
|
184
|
+
visit,
|
|
185
|
+
);
|
|
186
|
+
// Visit all assertions
|
|
187
|
+
const assertionLevel = subjectLevel + 1;
|
|
188
|
+
for (const assertion of c.assertions) {
|
|
189
|
+
walkTree(assertion, assertionLevel, EdgeType.Assertion, assertionState, visit);
|
|
190
|
+
}
|
|
191
|
+
break;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
case "wrapped":
|
|
195
|
+
// Visit wrapped envelope
|
|
196
|
+
walkTree(c.envelope, subjectLevel, EdgeType.Content, currentState, visit);
|
|
197
|
+
break;
|
|
198
|
+
|
|
199
|
+
case "assertion":
|
|
200
|
+
// Visit predicate and object
|
|
201
|
+
walkTree(c.assertion.predicate(), subjectLevel, EdgeType.Predicate, currentState, visit);
|
|
202
|
+
walkTree(c.assertion.object(), subjectLevel, EdgeType.Object, currentState, visit);
|
|
203
|
+
break;
|
|
204
|
+
|
|
205
|
+
case "leaf":
|
|
206
|
+
case "elided":
|
|
207
|
+
case "knownValue":
|
|
208
|
+
case "encrypted":
|
|
209
|
+
case "compressed":
|
|
210
|
+
// Leaf nodes and other types have no children
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return currentState;
|
|
215
|
+
}
|
package/src/base/wrap.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Envelope } from "./envelope";
|
|
2
|
+
import { EnvelopeError } from "./error";
|
|
3
|
+
|
|
4
|
+
/// Support for wrapping and unwrapping envelopes.
|
|
5
|
+
///
|
|
6
|
+
/// Wrapping allows treating an envelope (including its assertions) as a single
|
|
7
|
+
/// unit, making it possible to add assertions about the envelope as a whole.
|
|
8
|
+
|
|
9
|
+
/// Implementation of wrap()
|
|
10
|
+
Envelope.prototype.wrap = function (this: Envelope): Envelope {
|
|
11
|
+
return Envelope.newWrapped(this);
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
/// Implementation of tryUnwrap()
|
|
15
|
+
Envelope.prototype.tryUnwrap = function (this: Envelope): Envelope {
|
|
16
|
+
const c = this.subject().case();
|
|
17
|
+
if (c.type === "wrapped") {
|
|
18
|
+
return c.envelope;
|
|
19
|
+
}
|
|
20
|
+
throw EnvelopeError.notWrapped();
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/// Implementation of unwrap() - alias for tryUnwrap()
|
|
24
|
+
Envelope.prototype.unwrap = function (this: Envelope): Envelope {
|
|
25
|
+
return this.tryUnwrap();
|
|
26
|
+
};
|