@runtime-digital-twin/sdk 1.0.0
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/README.md +214 -0
- package/dist/constants.d.ts +11 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +13 -0
- package/dist/db-wrapper.d.ts +258 -0
- package/dist/db-wrapper.d.ts.map +1 -0
- package/dist/db-wrapper.js +636 -0
- package/dist/event-envelope.d.ts +35 -0
- package/dist/event-envelope.d.ts.map +1 -0
- package/dist/event-envelope.js +101 -0
- package/dist/fastify-plugin.d.ts +29 -0
- package/dist/fastify-plugin.d.ts.map +1 -0
- package/dist/fastify-plugin.js +243 -0
- package/dist/http-sentinels.d.ts +39 -0
- package/dist/http-sentinels.d.ts.map +1 -0
- package/dist/http-sentinels.js +169 -0
- package/dist/http-wrapper.d.ts +25 -0
- package/dist/http-wrapper.d.ts.map +1 -0
- package/dist/http-wrapper.js +477 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +93 -0
- package/dist/invariants.d.ts +58 -0
- package/dist/invariants.d.ts.map +1 -0
- package/dist/invariants.js +192 -0
- package/dist/multi-service-edge-builder.d.ts +80 -0
- package/dist/multi-service-edge-builder.d.ts.map +1 -0
- package/dist/multi-service-edge-builder.js +107 -0
- package/dist/outbound-matcher.d.ts +192 -0
- package/dist/outbound-matcher.d.ts.map +1 -0
- package/dist/outbound-matcher.js +457 -0
- package/dist/peer-service-resolver.d.ts +22 -0
- package/dist/peer-service-resolver.d.ts.map +1 -0
- package/dist/peer-service-resolver.js +85 -0
- package/dist/redaction.d.ts +111 -0
- package/dist/redaction.d.ts.map +1 -0
- package/dist/redaction.js +487 -0
- package/dist/replay-logger.d.ts +438 -0
- package/dist/replay-logger.d.ts.map +1 -0
- package/dist/replay-logger.js +434 -0
- package/dist/root-cause-analyzer.d.ts +45 -0
- package/dist/root-cause-analyzer.d.ts.map +1 -0
- package/dist/root-cause-analyzer.js +606 -0
- package/dist/shape-digest-utils.d.ts +45 -0
- package/dist/shape-digest-utils.d.ts.map +1 -0
- package/dist/shape-digest-utils.js +154 -0
- package/dist/trace-bundle-writer.d.ts +52 -0
- package/dist/trace-bundle-writer.d.ts.map +1 -0
- package/dist/trace-bundle-writer.js +267 -0
- package/dist/trace-loader.d.ts +69 -0
- package/dist/trace-loader.d.ts.map +1 -0
- package/dist/trace-loader.js +146 -0
- package/dist/trace-uploader.d.ts +25 -0
- package/dist/trace-uploader.d.ts.map +1 -0
- package/dist/trace-uploader.js +132 -0
- package/package.json +63 -0
|
@@ -0,0 +1,477 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.setTraceContext = setTraceContext;
|
|
4
|
+
exports.getTraceContext = getTraceContext;
|
|
5
|
+
exports.wrapFetch = wrapFetch;
|
|
6
|
+
const trace_bundle_writer_1 = require("./trace-bundle-writer");
|
|
7
|
+
const async_hooks_1 = require("async_hooks");
|
|
8
|
+
const peer_service_resolver_1 = require("./peer-service-resolver");
|
|
9
|
+
const shape_digest_utils_1 = require("./shape-digest-utils");
|
|
10
|
+
const http_sentinels_1 = require("./http-sentinels");
|
|
11
|
+
// Use AsyncLocalStorage for request-scoped trace context
|
|
12
|
+
const traceContextStorage = new async_hooks_1.AsyncLocalStorage();
|
|
13
|
+
/**
|
|
14
|
+
* Set the current trace context (called by Fastify plugin)
|
|
15
|
+
* Note: This uses enterWith which sets the context for the current async execution
|
|
16
|
+
*/
|
|
17
|
+
function setTraceContext(bundle, spanId) {
|
|
18
|
+
if (bundle && spanId) {
|
|
19
|
+
traceContextStorage.enterWith({ bundle, spanId });
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
// For clearing, we can't use enterWith with null, so we'll check in getTraceContext
|
|
23
|
+
// In practice, the context will be naturally cleared when the async context ends
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Get the current trace context
|
|
28
|
+
*/
|
|
29
|
+
function getTraceContext() {
|
|
30
|
+
const context = traceContextStorage.getStore();
|
|
31
|
+
if (!context) {
|
|
32
|
+
return { bundle: null, spanId: null };
|
|
33
|
+
}
|
|
34
|
+
return { bundle: context.bundle, spanId: context.spanId };
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Wrap fetch/undici to capture outbound HTTP calls
|
|
38
|
+
*/
|
|
39
|
+
function wrapFetch(originalFetch) {
|
|
40
|
+
return async function wrappedFetch(input, init) {
|
|
41
|
+
const { bundle, spanId } = getTraceContext();
|
|
42
|
+
const mode = process.env.RDT_MODE;
|
|
43
|
+
const mockBase = process.env.RDT_MOCK_BASE;
|
|
44
|
+
// L2-5: SUBGRAPH mode - route calls based on service boundaries
|
|
45
|
+
// In replay mode, check if call is leaving subgraph
|
|
46
|
+
if (mode === 'replay' && mockBase) {
|
|
47
|
+
const url = typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url;
|
|
48
|
+
const urlObj = new URL(url);
|
|
49
|
+
// L2-5: Check if this call is leaving the subgraph
|
|
50
|
+
const subgraphServicesJson = process.env.RDT_SUBGRAPH_SERVICES;
|
|
51
|
+
const stubServicesJson = process.env.RDT_STUB_SERVICES;
|
|
52
|
+
let shouldRouteToMock = true; // Default: route to mock server
|
|
53
|
+
if (subgraphServicesJson) {
|
|
54
|
+
try {
|
|
55
|
+
const subgraphServices = JSON.parse(subgraphServicesJson);
|
|
56
|
+
const stubServices = stubServicesJson ? JSON.parse(stubServicesJson) : [];
|
|
57
|
+
// Resolve peer service from hostname
|
|
58
|
+
const hostname = urlObj.hostname;
|
|
59
|
+
const { peerService } = (0, peer_service_resolver_1.resolvePeerService)(hostname);
|
|
60
|
+
// L2-5: Route logic:
|
|
61
|
+
// - If peerService is in subgraphServices → route to actual service (not implemented yet, route to mock for now)
|
|
62
|
+
// - If peerService is in stubServices → route to mock server (stub)
|
|
63
|
+
// - If peerService is NOT in subgraphServices → route to mock server (stub)
|
|
64
|
+
// - If peerService is null → route to mock server (stub)
|
|
65
|
+
if (peerService) {
|
|
66
|
+
if (subgraphServices.includes(peerService)) {
|
|
67
|
+
// Call is to a service in subgraph - should route to actual service
|
|
68
|
+
// TODO: Implement actual service routing (requires service discovery/URL mapping)
|
|
69
|
+
// For now, route to mock server as fallback
|
|
70
|
+
shouldRouteToMock = true;
|
|
71
|
+
}
|
|
72
|
+
else if (stubServices.includes(peerService)) {
|
|
73
|
+
// Call is to a stubbed service - route to mock server
|
|
74
|
+
shouldRouteToMock = true;
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
// Call is to a service outside subgraph - route to mock server (stub)
|
|
78
|
+
shouldRouteToMock = true;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
// Cannot resolve peer service - route to mock server (safe default)
|
|
83
|
+
shouldRouteToMock = true;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
// Failed to parse subgraph config - fall back to routing all to mock
|
|
88
|
+
console.warn(`[SDK] Failed to parse SUBGRAPH config: ${error}`);
|
|
89
|
+
shouldRouteToMock = true;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// Route to mock server but keep path+query for matching
|
|
93
|
+
// The mock server will match based on method + path+query + body hash
|
|
94
|
+
const mockUrl = `${mockBase}${urlObj.pathname}${urlObj.search}`;
|
|
95
|
+
// Make request to mock server
|
|
96
|
+
try {
|
|
97
|
+
const response = await originalFetch(mockUrl, init);
|
|
98
|
+
// L2-5: Check if mock server returned 502 (no match) - FAIL LOUDLY
|
|
99
|
+
if (response.status === 502) {
|
|
100
|
+
let errorBody = {};
|
|
101
|
+
try {
|
|
102
|
+
errorBody = await response.json();
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
// Ignore JSON parse errors
|
|
106
|
+
}
|
|
107
|
+
// L2-5: Typed error for missing stub
|
|
108
|
+
const errorMessage = `[Replay] Outbound HTTP call not found in trace (missing stub): ${url}\n` +
|
|
109
|
+
`Computed match key: ${errorBody.computedKey || 'unknown'}\n` +
|
|
110
|
+
`This call was not recorded in the trace bundle.\n` +
|
|
111
|
+
`In SUBGRAPH mode, calls leaving the subgraph must have recorded stubs.`;
|
|
112
|
+
throw new Error(errorMessage);
|
|
113
|
+
}
|
|
114
|
+
return response;
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
// Block unknown network calls - fail loudly
|
|
118
|
+
if (error.message.includes('[Replay]')) {
|
|
119
|
+
throw error; // Re-throw our custom error
|
|
120
|
+
}
|
|
121
|
+
throw new Error(`[Replay] Outbound HTTP call blocked: ${url}\n` +
|
|
122
|
+
`Mock server base: ${mockBase}\n` +
|
|
123
|
+
`Original error: ${error.message}`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// Record mode: capture and make real request
|
|
127
|
+
if (!bundle || !spanId) {
|
|
128
|
+
// No trace context - in replay mode this should not happen
|
|
129
|
+
if (mode === 'replay') {
|
|
130
|
+
throw new Error('[Replay] Outbound HTTP call made without trace context');
|
|
131
|
+
}
|
|
132
|
+
return originalFetch(input, init);
|
|
133
|
+
}
|
|
134
|
+
const url = typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url;
|
|
135
|
+
const method = init?.method || 'GET';
|
|
136
|
+
const headers = init?.headers ? init.headers : {};
|
|
137
|
+
const body = init?.body || null;
|
|
138
|
+
const requestSpanId = (0, trace_bundle_writer_1.generateSpanId)();
|
|
139
|
+
const startTime = Date.now();
|
|
140
|
+
// Extract peer service and hostname
|
|
141
|
+
let hostname = null;
|
|
142
|
+
try {
|
|
143
|
+
const urlObj = new URL(url);
|
|
144
|
+
hostname = urlObj.hostname;
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
// URL parsing failed, try to extract hostname manually
|
|
148
|
+
const hostMatch = url.match(/^https?:\/\/([^\/]+)/);
|
|
149
|
+
if (hostMatch) {
|
|
150
|
+
hostname = hostMatch[1];
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
const { peerService, peerHost } = hostname ? (0, peer_service_resolver_1.resolvePeerService)(hostname) : { peerService: null, peerHost: null };
|
|
154
|
+
const urlTemplate = (0, peer_service_resolver_1.extractUrlTemplate)(url);
|
|
155
|
+
// Process request body
|
|
156
|
+
let requestBody = null;
|
|
157
|
+
if (body) {
|
|
158
|
+
if (typeof body === 'string') {
|
|
159
|
+
requestBody = body;
|
|
160
|
+
}
|
|
161
|
+
else if (Buffer.isBuffer(body)) {
|
|
162
|
+
requestBody = body;
|
|
163
|
+
}
|
|
164
|
+
else if (body instanceof FormData || body instanceof URLSearchParams) {
|
|
165
|
+
// For FormData/URLSearchParams, we'll skip body capture for P0
|
|
166
|
+
requestBody = null;
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
requestBody = JSON.stringify(body);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
const { bodyHash: requestBodyHash, bodyBlob: requestBodyBlob } = await (0, trace_bundle_writer_1.processBody)(requestBody, bundle.writeBlob);
|
|
173
|
+
// Filter headers
|
|
174
|
+
const filteredHeaders = (0, trace_bundle_writer_1.filterHeaders)(headers);
|
|
175
|
+
// Inject trace context propagation headers
|
|
176
|
+
const propagationHeaders = {};
|
|
177
|
+
if (bundle.traceId) {
|
|
178
|
+
propagationHeaders['x-wraith-trace-id'] = bundle.traceId;
|
|
179
|
+
}
|
|
180
|
+
propagationHeaders['x-wraith-parent-span-id'] = requestSpanId;
|
|
181
|
+
// Merge propagation headers with existing headers
|
|
182
|
+
// Note: Headers object might be Headers instance, Record, or array of tuples
|
|
183
|
+
let mergedHeaders;
|
|
184
|
+
if (init?.headers instanceof Headers) {
|
|
185
|
+
const headers = new Headers(init.headers);
|
|
186
|
+
Object.entries(propagationHeaders).forEach(([key, value]) => {
|
|
187
|
+
headers.set(key, value);
|
|
188
|
+
});
|
|
189
|
+
mergedHeaders = headers;
|
|
190
|
+
}
|
|
191
|
+
else if (Array.isArray(init?.headers)) {
|
|
192
|
+
mergedHeaders = [
|
|
193
|
+
...init.headers,
|
|
194
|
+
...Object.entries(propagationHeaders),
|
|
195
|
+
];
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
mergedHeaders = {
|
|
199
|
+
...(init?.headers || {}),
|
|
200
|
+
...propagationHeaders,
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
// Create new init object with merged headers
|
|
204
|
+
const enhancedInit = {
|
|
205
|
+
...init,
|
|
206
|
+
headers: mergedHeaders,
|
|
207
|
+
};
|
|
208
|
+
try {
|
|
209
|
+
// Make the actual HTTP request with propagation headers
|
|
210
|
+
const response = await originalFetch(input, enhancedInit);
|
|
211
|
+
const endTime = Date.now();
|
|
212
|
+
const durationMs = endTime - startTime;
|
|
213
|
+
// Debug logging
|
|
214
|
+
if (process.env.DEBUG_HTTP_WRAPPER) {
|
|
215
|
+
console.log('[HTTP_WRAPPER] Response received:', {
|
|
216
|
+
status: response.status,
|
|
217
|
+
headersType: response.headers?.constructor?.name,
|
|
218
|
+
hasForEach: typeof response.headers?.forEach === 'function',
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
// Read response body (clone response so we can read it without consuming the original)
|
|
222
|
+
let responseClone;
|
|
223
|
+
try {
|
|
224
|
+
responseClone = response.clone();
|
|
225
|
+
}
|
|
226
|
+
catch (error) {
|
|
227
|
+
if (process.env.DEBUG_HTTP_WRAPPER) {
|
|
228
|
+
console.error('[HTTP_WRAPPER] Failed to clone response:', error);
|
|
229
|
+
}
|
|
230
|
+
throw error;
|
|
231
|
+
}
|
|
232
|
+
let responseBody = null;
|
|
233
|
+
let responseBodyForDigest = null;
|
|
234
|
+
try {
|
|
235
|
+
const contentType = response.headers.get('content-type') || '';
|
|
236
|
+
if (process.env.DEBUG_HTTP_WRAPPER) {
|
|
237
|
+
console.log('[HTTP_WRAPPER] Content-Type:', contentType);
|
|
238
|
+
}
|
|
239
|
+
if (contentType.includes('application/json') || contentType.includes('text/')) {
|
|
240
|
+
responseBody = await responseClone.text();
|
|
241
|
+
responseBodyForDigest = responseBody;
|
|
242
|
+
if (process.env.DEBUG_HTTP_WRAPPER) {
|
|
243
|
+
console.log('[HTTP_WRAPPER] Response body read, length:', responseBody?.length);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
// For shape digest, try to read body even if content-type isn't explicitly JSON/text
|
|
248
|
+
// This allows us to compute digests for JSON responses with missing/wrong content-type
|
|
249
|
+
try {
|
|
250
|
+
responseBodyForDigest = await responseClone.text();
|
|
251
|
+
// Try to parse as JSON - if it fails, we'll skip digest computation
|
|
252
|
+
try {
|
|
253
|
+
JSON.parse(responseBodyForDigest);
|
|
254
|
+
// If parse succeeds, use it for digest
|
|
255
|
+
}
|
|
256
|
+
catch {
|
|
257
|
+
// Not JSON, don't use for digest
|
|
258
|
+
responseBodyForDigest = null;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
catch {
|
|
262
|
+
// Failed to read, skip
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
catch (error) {
|
|
267
|
+
if (process.env.DEBUG_HTTP_WRAPPER) {
|
|
268
|
+
console.error('[HTTP_WRAPPER] Failed to read response body:', error);
|
|
269
|
+
}
|
|
270
|
+
// Failed to read response body, continue without it
|
|
271
|
+
}
|
|
272
|
+
const { bodyHash: responseBodyHash, bodyBlob: responseBodyBlob } = await (0, trace_bundle_writer_1.processBody)(responseBody, bundle.writeBlob);
|
|
273
|
+
// Filter response headers
|
|
274
|
+
const responseHeaders = {};
|
|
275
|
+
try {
|
|
276
|
+
response.headers.forEach((value, key) => {
|
|
277
|
+
responseHeaders[key] = value;
|
|
278
|
+
});
|
|
279
|
+
if (process.env.DEBUG_HTTP_WRAPPER) {
|
|
280
|
+
console.log('[HTTP_WRAPPER] Response headers processed:', Object.keys(responseHeaders));
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
catch (error) {
|
|
284
|
+
if (process.env.DEBUG_HTTP_WRAPPER) {
|
|
285
|
+
console.error('[HTTP_WRAPPER] Failed to process response headers:', error);
|
|
286
|
+
console.error('[HTTP_WRAPPER] Headers object:', {
|
|
287
|
+
type: typeof response.headers,
|
|
288
|
+
constructor: response.headers?.constructor?.name,
|
|
289
|
+
hasForEach: typeof response.headers?.forEach === 'function',
|
|
290
|
+
keys: response.headers ? Object.keys(response.headers) : 'null',
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
// Try to extract headers manually if forEach fails
|
|
294
|
+
if (response.headers && typeof response.headers === 'object') {
|
|
295
|
+
try {
|
|
296
|
+
for (const [key, value] of Object.entries(response.headers)) {
|
|
297
|
+
responseHeaders[key] = String(value);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
catch (e) {
|
|
301
|
+
// Ignore
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
const filteredResponseHeaders = (0, trace_bundle_writer_1.filterHeaders)(responseHeaders);
|
|
306
|
+
// Compute shape digests (async, non-blocking)
|
|
307
|
+
const mode = (0, shape_digest_utils_1.getShapeDigestMode)();
|
|
308
|
+
const sampleRate = (0, shape_digest_utils_1.getShapeDigestSampleRate)();
|
|
309
|
+
const requestContentType = (0, shape_digest_utils_1.getContentType)(headers);
|
|
310
|
+
const responseContentType = (0, shape_digest_utils_1.getContentType)(response.headers);
|
|
311
|
+
if (process.env.DEBUG_HTTP_WRAPPER) {
|
|
312
|
+
console.log('[HTTP_WRAPPER] Content types:', {
|
|
313
|
+
request: requestContentType,
|
|
314
|
+
response: responseContentType,
|
|
315
|
+
mode,
|
|
316
|
+
sampleRate,
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
const statusCode = response.status;
|
|
320
|
+
const hasError = statusCode >= 400;
|
|
321
|
+
let requestShapeDigest = null;
|
|
322
|
+
let responseShapeDigest = null;
|
|
323
|
+
try {
|
|
324
|
+
[requestShapeDigest, responseShapeDigest] = await Promise.all([
|
|
325
|
+
(0, shape_digest_utils_1.computeBodyShapeDigest)(requestBody, requestContentType, {
|
|
326
|
+
mode,
|
|
327
|
+
sampleRate,
|
|
328
|
+
statusCode,
|
|
329
|
+
hasError,
|
|
330
|
+
}),
|
|
331
|
+
(0, shape_digest_utils_1.computeBodyShapeDigest)(responseBodyForDigest || responseBody, responseContentType, {
|
|
332
|
+
mode,
|
|
333
|
+
sampleRate,
|
|
334
|
+
statusCode,
|
|
335
|
+
hasError,
|
|
336
|
+
}),
|
|
337
|
+
]);
|
|
338
|
+
if (process.env.DEBUG_HTTP_WRAPPER) {
|
|
339
|
+
console.log('[HTTP_WRAPPER] Shape digests computed:', {
|
|
340
|
+
request: !!requestShapeDigest,
|
|
341
|
+
response: !!responseShapeDigest,
|
|
342
|
+
responseKind: responseShapeDigest?.kind,
|
|
343
|
+
responseNullPaths: responseShapeDigest?.nullPaths?.length,
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
catch (error) {
|
|
348
|
+
if (process.env.DEBUG_HTTP_WRAPPER) {
|
|
349
|
+
console.error('[HTTP_WRAPPER] Failed to compute shape digests:', error);
|
|
350
|
+
}
|
|
351
|
+
// Continue without digests
|
|
352
|
+
}
|
|
353
|
+
const requestSizeBytes = (0, shape_digest_utils_1.getBodySizeBytes)(requestBody);
|
|
354
|
+
const responseSizeBytes = (0, shape_digest_utils_1.getBodySizeBytes)(responseBody);
|
|
355
|
+
if (process.env.DEBUG_HTTP_WRAPPER) {
|
|
356
|
+
console.log('[HTTP_WRAPPER] Body sizes:', {
|
|
357
|
+
request: requestSizeBytes,
|
|
358
|
+
response: responseSizeBytes,
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
// Check response sentinels (automatic contract checking)
|
|
362
|
+
// This emits state.invariant events for contract violations
|
|
363
|
+
try {
|
|
364
|
+
await (0, http_sentinels_1.checkResponseSentinels)(responseShapeDigest, statusCode, responseBodyForDigest || responseBody, requestSpanId, // Use requestSpanId so sentinel is attached to outbound call
|
|
365
|
+
spanId // parentSpanId
|
|
366
|
+
);
|
|
367
|
+
if (process.env.DEBUG_HTTP_WRAPPER) {
|
|
368
|
+
console.log('[HTTP_WRAPPER] Sentinels checked');
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
catch (error) {
|
|
372
|
+
if (process.env.DEBUG_HTTP_WRAPPER) {
|
|
373
|
+
console.error('[HTTP_WRAPPER] Failed to check sentinels:', error);
|
|
374
|
+
}
|
|
375
|
+
// Continue without sentinels
|
|
376
|
+
}
|
|
377
|
+
// Write http.request.outbound event (after completion with statusCode and durationMs)
|
|
378
|
+
const outboundEvent = {
|
|
379
|
+
type: 'http.request.outbound',
|
|
380
|
+
timestamp: startTime, // Use start time for request timestamp
|
|
381
|
+
spanId: requestSpanId,
|
|
382
|
+
parentSpanId: spanId,
|
|
383
|
+
method,
|
|
384
|
+
url,
|
|
385
|
+
headers: filteredHeaders,
|
|
386
|
+
bodyHash: requestBodyHash,
|
|
387
|
+
bodyBlob: requestBodyBlob,
|
|
388
|
+
peerService,
|
|
389
|
+
peerHost,
|
|
390
|
+
urlTemplate,
|
|
391
|
+
statusCode: response.status,
|
|
392
|
+
durationMs,
|
|
393
|
+
...(requestShapeDigest && { requestShapeDigest }),
|
|
394
|
+
...(requestContentType && { requestContentType }),
|
|
395
|
+
...(requestSizeBytes !== undefined && { requestSizeBytes }),
|
|
396
|
+
...(responseShapeDigest && { responseShapeDigest }),
|
|
397
|
+
...(responseContentType && { responseContentType }),
|
|
398
|
+
...(responseSizeBytes !== undefined && { responseSizeBytes }),
|
|
399
|
+
};
|
|
400
|
+
if (process.env.DEBUG_HTTP_WRAPPER) {
|
|
401
|
+
console.log('[HTTP_WRAPPER] Writing outbound event with fields:', {
|
|
402
|
+
statusCode: outboundEvent.statusCode,
|
|
403
|
+
responseContentType: outboundEvent.responseContentType,
|
|
404
|
+
responseSizeBytes: outboundEvent.responseSizeBytes,
|
|
405
|
+
hasResponseShapeDigest: !!outboundEvent.responseShapeDigest,
|
|
406
|
+
hasRequestShapeDigest: !!outboundEvent.requestShapeDigest,
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
await bundle.writeEvent(outboundEvent);
|
|
410
|
+
// Write http.response.outbound event
|
|
411
|
+
await bundle.writeEvent({
|
|
412
|
+
type: 'http.response.outbound',
|
|
413
|
+
timestamp: endTime,
|
|
414
|
+
spanId: requestSpanId,
|
|
415
|
+
parentSpanId: spanId,
|
|
416
|
+
statusCode: response.status,
|
|
417
|
+
headers: filteredResponseHeaders,
|
|
418
|
+
bodyHash: responseBodyHash,
|
|
419
|
+
bodyBlob: responseBodyBlob,
|
|
420
|
+
durationMs,
|
|
421
|
+
});
|
|
422
|
+
return response;
|
|
423
|
+
}
|
|
424
|
+
catch (error) {
|
|
425
|
+
if (process.env.DEBUG_HTTP_WRAPPER) {
|
|
426
|
+
console.error('[HTTP_WRAPPER] Error in fetch wrapper:', error);
|
|
427
|
+
console.error('[HTTP_WRAPPER] Error stack:', error.stack);
|
|
428
|
+
}
|
|
429
|
+
const endTime = Date.now();
|
|
430
|
+
const durationMs = endTime - startTime;
|
|
431
|
+
// Compute shape digest for request (errors always include digest)
|
|
432
|
+
const mode = (0, shape_digest_utils_1.getShapeDigestMode)();
|
|
433
|
+
const sampleRate = (0, shape_digest_utils_1.getShapeDigestSampleRate)();
|
|
434
|
+
const requestContentType = (0, shape_digest_utils_1.getContentType)(headers);
|
|
435
|
+
const requestShapeDigest = await (0, shape_digest_utils_1.computeBodyShapeDigest)(requestBody, requestContentType, {
|
|
436
|
+
mode,
|
|
437
|
+
sampleRate,
|
|
438
|
+
statusCode: null,
|
|
439
|
+
hasError: true, // Always compute for errors
|
|
440
|
+
});
|
|
441
|
+
const requestSizeBytes = (0, shape_digest_utils_1.getBodySizeBytes)(requestBody);
|
|
442
|
+
// Write http.request.outbound event (after error with durationMs, null statusCode)
|
|
443
|
+
await bundle.writeEvent({
|
|
444
|
+
type: 'http.request.outbound',
|
|
445
|
+
timestamp: startTime, // Use start time for request timestamp
|
|
446
|
+
spanId: requestSpanId,
|
|
447
|
+
parentSpanId: spanId,
|
|
448
|
+
method,
|
|
449
|
+
url,
|
|
450
|
+
headers: filteredHeaders,
|
|
451
|
+
bodyHash: requestBodyHash,
|
|
452
|
+
bodyBlob: requestBodyBlob,
|
|
453
|
+
peerService,
|
|
454
|
+
peerHost,
|
|
455
|
+
urlTemplate,
|
|
456
|
+
statusCode: null, // Error - no status code
|
|
457
|
+
durationMs,
|
|
458
|
+
...(requestShapeDigest && { requestShapeDigest }),
|
|
459
|
+
...(requestContentType && { requestContentType }),
|
|
460
|
+
...(requestSizeBytes !== undefined && { requestSizeBytes }),
|
|
461
|
+
});
|
|
462
|
+
// Write error event
|
|
463
|
+
await bundle.writeEvent({
|
|
464
|
+
type: 'error',
|
|
465
|
+
timestamp: endTime,
|
|
466
|
+
spanId: requestSpanId,
|
|
467
|
+
parentSpanId: spanId,
|
|
468
|
+
error: {
|
|
469
|
+
name: error.name || 'Error',
|
|
470
|
+
message: error.message || String(error),
|
|
471
|
+
stack: error.stack || undefined,
|
|
472
|
+
},
|
|
473
|
+
});
|
|
474
|
+
throw error;
|
|
475
|
+
}
|
|
476
|
+
};
|
|
477
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime Digital Twin SDK
|
|
3
|
+
*
|
|
4
|
+
* In-process instrumentation for capturing runtime behavior.
|
|
5
|
+
*/
|
|
6
|
+
export { CURRENT_TRACE_FORMAT_VERSION } from "./constants";
|
|
7
|
+
export { createTrace, processBody, filterHeaders, generateSpanId, type CreateTraceOptions, type TraceBundle, } from "./trace-bundle-writer";
|
|
8
|
+
export { loadTraceMeta, validateTraceStructure, formatTraceLoadFailure, type TraceLoadFailure, type TraceMetadata, type TraceVersionWarning, type TraceLoadResult, } from "./trace-loader";
|
|
9
|
+
export { fastifyTracing, type FastifyTracingOptions } from "./fastify-plugin";
|
|
10
|
+
export { wrapFetch, setTraceContext, getTraceContext } from "./http-wrapper";
|
|
11
|
+
export { OutboundMatcher, normalizeUrl, normalizeHeaders, computeBodyHash, computeMatchSignature, compareOutboundCalls, parseRecordedOutboundCalls, formatOutboundMismatch, formatUnexpectedOutboundCall, formatMissingOutboundCall, formatOutboundCallFailure, type ReplayMode, type OutboundRequestMismatch, type UnexpectedOutboundCall, type MissingOutboundCall, type OutboundCallFailure, type OutboundDivergence, type RecordedOutboundCall, type OutboundCallSignature, } from "./outbound-matcher";
|
|
12
|
+
export { DbQueryMatcher, wrapDbClient, createWrappedDbClient, normalizeSql, computeParamsHash, extractOperation, compareDbQueries, parseRecordedDbQueries, formatDbQueryMismatch, formatUnexpectedDbQuery, formatMissingDbQuery, formatBlockedDbAccess, formatDbQueryFailure, type DbReplayMode, type DbQueryMismatch, type UnexpectedDbQuery, type MissingDbQuery, type BlockedDbAccess, type DbQueryFailure, type DbQueryDivergence, type RecordedDbQuery, type DbQuerySignature, type DbClient, type WrappedDbClient, type WrapDbClientOptions, type CreateWrappedDbClientOptions, } from "./db-wrapper";
|
|
13
|
+
export { ReplayLogger, getReplayLogger, resetReplayLogger, createReplayLogger, type ReplayLogFormat, type ReplayLogLevel, type ReplayEventCategory, type ReplayEventBase, type ReplayEvent, type ReplayLoggerConfig, type HttpOutboundMatchEvent, type HttpOutboundReturnEvent, type HttpOutboundMismatchEvent, type HttpOutboundUnexpectedEvent, type HttpOutboundMissingEvent, type HttpOutboundBlockedEvent, type DbQueryMatchEvent, type DbQueryReturnEvent, type DbQueryMismatchEvent, type DbQueryUnexpectedEvent, type DbQueryMissingEvent, type DbQueryBlockedEvent, type TraceLoadEvent, type TraceLoadWarningEvent, type TraceLoadErrorEvent, type ReplayStartEvent, type ReplayCompleteEvent, type ReplayErrorEvent, type ReplayDivergenceEvent, } from "./replay-logger";
|
|
14
|
+
export { buildEdges, buildEdgesForTrace, type TraceEvent, type ServiceEdge, } from "./multi-service-edge-builder";
|
|
15
|
+
export { analyzeMultiServiceRootCause, type RootCauseAnalysis, } from "./root-cause-analyzer";
|
|
16
|
+
export { redactHeaders, redactBody, redactBodyObject, redactBodyPatterns, redactQueryParams, redactUrl, loadRedactionConfig, setRedactionConfig, getRedactionConfig, resetRedactionConfig, computeRedactionHash, createRedactedValue, shouldRedactHeader, shouldRedactQueryParam, containsSensitivePatterns, SENSITIVE_HEADERS, SENSITIVE_QUERY_PARAMS, SENSITIVE_BODY_FIELDS, type RedactionRule, type RedactionRuleType, type RedactionConfig, } from "./redaction";
|
|
17
|
+
export { emitInvariant, assertNonNull, assertHasKeys, assertInRange, type InvariantDetails, type EmitInvariantOptions, } from "./invariants";
|
|
18
|
+
export { uploadTrace, type TraceUploadOptions, type TraceUploadResult, } from "./trace-uploader";
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Runtime Digital Twin SDK
|
|
4
|
+
*
|
|
5
|
+
* In-process instrumentation for capturing runtime behavior.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.loadRedactionConfig = exports.redactUrl = exports.redactQueryParams = exports.redactBodyPatterns = exports.redactBodyObject = exports.redactBody = exports.redactHeaders = exports.analyzeMultiServiceRootCause = exports.buildEdgesForTrace = exports.buildEdges = exports.createReplayLogger = exports.resetReplayLogger = exports.getReplayLogger = exports.ReplayLogger = exports.formatDbQueryFailure = exports.formatBlockedDbAccess = exports.formatMissingDbQuery = exports.formatUnexpectedDbQuery = exports.formatDbQueryMismatch = exports.parseRecordedDbQueries = exports.compareDbQueries = exports.extractOperation = exports.computeParamsHash = exports.normalizeSql = exports.createWrappedDbClient = exports.wrapDbClient = exports.DbQueryMatcher = exports.formatOutboundCallFailure = exports.formatMissingOutboundCall = exports.formatUnexpectedOutboundCall = exports.formatOutboundMismatch = exports.parseRecordedOutboundCalls = exports.compareOutboundCalls = exports.computeMatchSignature = exports.computeBodyHash = exports.normalizeHeaders = exports.normalizeUrl = exports.OutboundMatcher = exports.getTraceContext = exports.setTraceContext = exports.wrapFetch = exports.fastifyTracing = exports.formatTraceLoadFailure = exports.validateTraceStructure = exports.loadTraceMeta = exports.generateSpanId = exports.filterHeaders = exports.processBody = exports.createTrace = exports.CURRENT_TRACE_FORMAT_VERSION = void 0;
|
|
9
|
+
exports.uploadTrace = exports.assertInRange = exports.assertHasKeys = exports.assertNonNull = exports.emitInvariant = exports.SENSITIVE_BODY_FIELDS = exports.SENSITIVE_QUERY_PARAMS = exports.SENSITIVE_HEADERS = exports.containsSensitivePatterns = exports.shouldRedactQueryParam = exports.shouldRedactHeader = exports.createRedactedValue = exports.computeRedactionHash = exports.resetRedactionConfig = exports.getRedactionConfig = exports.setRedactionConfig = void 0;
|
|
10
|
+
var constants_1 = require("./constants");
|
|
11
|
+
Object.defineProperty(exports, "CURRENT_TRACE_FORMAT_VERSION", { enumerable: true, get: function () { return constants_1.CURRENT_TRACE_FORMAT_VERSION; } });
|
|
12
|
+
var trace_bundle_writer_1 = require("./trace-bundle-writer");
|
|
13
|
+
Object.defineProperty(exports, "createTrace", { enumerable: true, get: function () { return trace_bundle_writer_1.createTrace; } });
|
|
14
|
+
Object.defineProperty(exports, "processBody", { enumerable: true, get: function () { return trace_bundle_writer_1.processBody; } });
|
|
15
|
+
Object.defineProperty(exports, "filterHeaders", { enumerable: true, get: function () { return trace_bundle_writer_1.filterHeaders; } });
|
|
16
|
+
Object.defineProperty(exports, "generateSpanId", { enumerable: true, get: function () { return trace_bundle_writer_1.generateSpanId; } });
|
|
17
|
+
var trace_loader_1 = require("./trace-loader");
|
|
18
|
+
Object.defineProperty(exports, "loadTraceMeta", { enumerable: true, get: function () { return trace_loader_1.loadTraceMeta; } });
|
|
19
|
+
Object.defineProperty(exports, "validateTraceStructure", { enumerable: true, get: function () { return trace_loader_1.validateTraceStructure; } });
|
|
20
|
+
Object.defineProperty(exports, "formatTraceLoadFailure", { enumerable: true, get: function () { return trace_loader_1.formatTraceLoadFailure; } });
|
|
21
|
+
var fastify_plugin_1 = require("./fastify-plugin");
|
|
22
|
+
Object.defineProperty(exports, "fastifyTracing", { enumerable: true, get: function () { return fastify_plugin_1.fastifyTracing; } });
|
|
23
|
+
var http_wrapper_1 = require("./http-wrapper");
|
|
24
|
+
Object.defineProperty(exports, "wrapFetch", { enumerable: true, get: function () { return http_wrapper_1.wrapFetch; } });
|
|
25
|
+
Object.defineProperty(exports, "setTraceContext", { enumerable: true, get: function () { return http_wrapper_1.setTraceContext; } });
|
|
26
|
+
Object.defineProperty(exports, "getTraceContext", { enumerable: true, get: function () { return http_wrapper_1.getTraceContext; } });
|
|
27
|
+
var outbound_matcher_1 = require("./outbound-matcher");
|
|
28
|
+
Object.defineProperty(exports, "OutboundMatcher", { enumerable: true, get: function () { return outbound_matcher_1.OutboundMatcher; } });
|
|
29
|
+
Object.defineProperty(exports, "normalizeUrl", { enumerable: true, get: function () { return outbound_matcher_1.normalizeUrl; } });
|
|
30
|
+
Object.defineProperty(exports, "normalizeHeaders", { enumerable: true, get: function () { return outbound_matcher_1.normalizeHeaders; } });
|
|
31
|
+
Object.defineProperty(exports, "computeBodyHash", { enumerable: true, get: function () { return outbound_matcher_1.computeBodyHash; } });
|
|
32
|
+
Object.defineProperty(exports, "computeMatchSignature", { enumerable: true, get: function () { return outbound_matcher_1.computeMatchSignature; } });
|
|
33
|
+
Object.defineProperty(exports, "compareOutboundCalls", { enumerable: true, get: function () { return outbound_matcher_1.compareOutboundCalls; } });
|
|
34
|
+
Object.defineProperty(exports, "parseRecordedOutboundCalls", { enumerable: true, get: function () { return outbound_matcher_1.parseRecordedOutboundCalls; } });
|
|
35
|
+
Object.defineProperty(exports, "formatOutboundMismatch", { enumerable: true, get: function () { return outbound_matcher_1.formatOutboundMismatch; } });
|
|
36
|
+
Object.defineProperty(exports, "formatUnexpectedOutboundCall", { enumerable: true, get: function () { return outbound_matcher_1.formatUnexpectedOutboundCall; } });
|
|
37
|
+
Object.defineProperty(exports, "formatMissingOutboundCall", { enumerable: true, get: function () { return outbound_matcher_1.formatMissingOutboundCall; } });
|
|
38
|
+
Object.defineProperty(exports, "formatOutboundCallFailure", { enumerable: true, get: function () { return outbound_matcher_1.formatOutboundCallFailure; } });
|
|
39
|
+
var db_wrapper_1 = require("./db-wrapper");
|
|
40
|
+
Object.defineProperty(exports, "DbQueryMatcher", { enumerable: true, get: function () { return db_wrapper_1.DbQueryMatcher; } });
|
|
41
|
+
Object.defineProperty(exports, "wrapDbClient", { enumerable: true, get: function () { return db_wrapper_1.wrapDbClient; } });
|
|
42
|
+
Object.defineProperty(exports, "createWrappedDbClient", { enumerable: true, get: function () { return db_wrapper_1.createWrappedDbClient; } });
|
|
43
|
+
Object.defineProperty(exports, "normalizeSql", { enumerable: true, get: function () { return db_wrapper_1.normalizeSql; } });
|
|
44
|
+
Object.defineProperty(exports, "computeParamsHash", { enumerable: true, get: function () { return db_wrapper_1.computeParamsHash; } });
|
|
45
|
+
Object.defineProperty(exports, "extractOperation", { enumerable: true, get: function () { return db_wrapper_1.extractOperation; } });
|
|
46
|
+
Object.defineProperty(exports, "compareDbQueries", { enumerable: true, get: function () { return db_wrapper_1.compareDbQueries; } });
|
|
47
|
+
Object.defineProperty(exports, "parseRecordedDbQueries", { enumerable: true, get: function () { return db_wrapper_1.parseRecordedDbQueries; } });
|
|
48
|
+
Object.defineProperty(exports, "formatDbQueryMismatch", { enumerable: true, get: function () { return db_wrapper_1.formatDbQueryMismatch; } });
|
|
49
|
+
Object.defineProperty(exports, "formatUnexpectedDbQuery", { enumerable: true, get: function () { return db_wrapper_1.formatUnexpectedDbQuery; } });
|
|
50
|
+
Object.defineProperty(exports, "formatMissingDbQuery", { enumerable: true, get: function () { return db_wrapper_1.formatMissingDbQuery; } });
|
|
51
|
+
Object.defineProperty(exports, "formatBlockedDbAccess", { enumerable: true, get: function () { return db_wrapper_1.formatBlockedDbAccess; } });
|
|
52
|
+
Object.defineProperty(exports, "formatDbQueryFailure", { enumerable: true, get: function () { return db_wrapper_1.formatDbQueryFailure; } });
|
|
53
|
+
var replay_logger_1 = require("./replay-logger");
|
|
54
|
+
Object.defineProperty(exports, "ReplayLogger", { enumerable: true, get: function () { return replay_logger_1.ReplayLogger; } });
|
|
55
|
+
Object.defineProperty(exports, "getReplayLogger", { enumerable: true, get: function () { return replay_logger_1.getReplayLogger; } });
|
|
56
|
+
Object.defineProperty(exports, "resetReplayLogger", { enumerable: true, get: function () { return replay_logger_1.resetReplayLogger; } });
|
|
57
|
+
Object.defineProperty(exports, "createReplayLogger", { enumerable: true, get: function () { return replay_logger_1.createReplayLogger; } });
|
|
58
|
+
// Multi-service edge builder
|
|
59
|
+
var multi_service_edge_builder_1 = require("./multi-service-edge-builder");
|
|
60
|
+
Object.defineProperty(exports, "buildEdges", { enumerable: true, get: function () { return multi_service_edge_builder_1.buildEdges; } });
|
|
61
|
+
Object.defineProperty(exports, "buildEdgesForTrace", { enumerable: true, get: function () { return multi_service_edge_builder_1.buildEdgesForTrace; } });
|
|
62
|
+
// Root cause analyzer
|
|
63
|
+
var root_cause_analyzer_1 = require("./root-cause-analyzer");
|
|
64
|
+
Object.defineProperty(exports, "analyzeMultiServiceRootCause", { enumerable: true, get: function () { return root_cause_analyzer_1.analyzeMultiServiceRootCause; } });
|
|
65
|
+
// Redaction module
|
|
66
|
+
var redaction_1 = require("./redaction");
|
|
67
|
+
Object.defineProperty(exports, "redactHeaders", { enumerable: true, get: function () { return redaction_1.redactHeaders; } });
|
|
68
|
+
Object.defineProperty(exports, "redactBody", { enumerable: true, get: function () { return redaction_1.redactBody; } });
|
|
69
|
+
Object.defineProperty(exports, "redactBodyObject", { enumerable: true, get: function () { return redaction_1.redactBodyObject; } });
|
|
70
|
+
Object.defineProperty(exports, "redactBodyPatterns", { enumerable: true, get: function () { return redaction_1.redactBodyPatterns; } });
|
|
71
|
+
Object.defineProperty(exports, "redactQueryParams", { enumerable: true, get: function () { return redaction_1.redactQueryParams; } });
|
|
72
|
+
Object.defineProperty(exports, "redactUrl", { enumerable: true, get: function () { return redaction_1.redactUrl; } });
|
|
73
|
+
Object.defineProperty(exports, "loadRedactionConfig", { enumerable: true, get: function () { return redaction_1.loadRedactionConfig; } });
|
|
74
|
+
Object.defineProperty(exports, "setRedactionConfig", { enumerable: true, get: function () { return redaction_1.setRedactionConfig; } });
|
|
75
|
+
Object.defineProperty(exports, "getRedactionConfig", { enumerable: true, get: function () { return redaction_1.getRedactionConfig; } });
|
|
76
|
+
Object.defineProperty(exports, "resetRedactionConfig", { enumerable: true, get: function () { return redaction_1.resetRedactionConfig; } });
|
|
77
|
+
Object.defineProperty(exports, "computeRedactionHash", { enumerable: true, get: function () { return redaction_1.computeRedactionHash; } });
|
|
78
|
+
Object.defineProperty(exports, "createRedactedValue", { enumerable: true, get: function () { return redaction_1.createRedactedValue; } });
|
|
79
|
+
Object.defineProperty(exports, "shouldRedactHeader", { enumerable: true, get: function () { return redaction_1.shouldRedactHeader; } });
|
|
80
|
+
Object.defineProperty(exports, "shouldRedactQueryParam", { enumerable: true, get: function () { return redaction_1.shouldRedactQueryParam; } });
|
|
81
|
+
Object.defineProperty(exports, "containsSensitivePatterns", { enumerable: true, get: function () { return redaction_1.containsSensitivePatterns; } });
|
|
82
|
+
Object.defineProperty(exports, "SENSITIVE_HEADERS", { enumerable: true, get: function () { return redaction_1.SENSITIVE_HEADERS; } });
|
|
83
|
+
Object.defineProperty(exports, "SENSITIVE_QUERY_PARAMS", { enumerable: true, get: function () { return redaction_1.SENSITIVE_QUERY_PARAMS; } });
|
|
84
|
+
Object.defineProperty(exports, "SENSITIVE_BODY_FIELDS", { enumerable: true, get: function () { return redaction_1.SENSITIVE_BODY_FIELDS; } });
|
|
85
|
+
// Invariant checking
|
|
86
|
+
var invariants_1 = require("./invariants");
|
|
87
|
+
Object.defineProperty(exports, "emitInvariant", { enumerable: true, get: function () { return invariants_1.emitInvariant; } });
|
|
88
|
+
Object.defineProperty(exports, "assertNonNull", { enumerable: true, get: function () { return invariants_1.assertNonNull; } });
|
|
89
|
+
Object.defineProperty(exports, "assertHasKeys", { enumerable: true, get: function () { return invariants_1.assertHasKeys; } });
|
|
90
|
+
Object.defineProperty(exports, "assertInRange", { enumerable: true, get: function () { return invariants_1.assertInRange; } });
|
|
91
|
+
// Trace upload
|
|
92
|
+
var trace_uploader_1 = require("./trace-uploader");
|
|
93
|
+
Object.defineProperty(exports, "uploadTrace", { enumerable: true, get: function () { return trace_uploader_1.uploadTrace; } });
|