@stainlessdev/xray-core 0.1.0-dev.f7bff1d → 0.2.0-branch.bg-basic-auth.f77d251
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/dist/{chunk-SQHI5JZH.js → chunk-HTZYZB7O.js} +14 -1
- package/dist/chunk-HTZYZB7O.js.map +1 -0
- package/dist/index.cjs +137 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +105 -27
- package/dist/index.js.map +1 -1
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-SQHI5JZH.js.map +0 -1
|
@@ -37,6 +37,18 @@ function encodeBase64(bytes) {
|
|
|
37
37
|
}
|
|
38
38
|
return "";
|
|
39
39
|
}
|
|
40
|
+
function encodeBase64String(value) {
|
|
41
|
+
if (maybeBuffer) {
|
|
42
|
+
return maybeBuffer.from(value, "utf8").toString("base64");
|
|
43
|
+
}
|
|
44
|
+
if (typeof TextEncoder !== "undefined") {
|
|
45
|
+
return encodeBase64(new TextEncoder().encode(value));
|
|
46
|
+
}
|
|
47
|
+
if (typeof btoa !== "undefined") {
|
|
48
|
+
return btoa(unescape(encodeURIComponent(value)));
|
|
49
|
+
}
|
|
50
|
+
return "";
|
|
51
|
+
}
|
|
40
52
|
function isValidUtf8(bytes) {
|
|
41
53
|
if (!utf8Decoder) {
|
|
42
54
|
return false;
|
|
@@ -160,6 +172,7 @@ function findNestedTarget(obj) {
|
|
|
160
172
|
}
|
|
161
173
|
|
|
162
174
|
export {
|
|
175
|
+
encodeBase64String,
|
|
163
176
|
logWithLevel,
|
|
164
177
|
sanitizeLogString,
|
|
165
178
|
sanitizeHeaderValues,
|
|
@@ -169,4 +182,4 @@ export {
|
|
|
169
182
|
bindObject,
|
|
170
183
|
getContextFromObject
|
|
171
184
|
};
|
|
172
|
-
//# sourceMappingURL=chunk-
|
|
185
|
+
//# sourceMappingURL=chunk-HTZYZB7O.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/logger.ts","../src/encoding.ts","../src/request_log.ts","../src/state.ts"],"sourcesContent":["import type { Logger, LogLevel } from './types';\n\nconst logLevelOrder: Record<LogLevel, number> = {\n debug: 10,\n info: 20,\n warn: 30,\n error: 40,\n};\n\nexport function logWithLevel(\n logger: Logger,\n level: LogLevel,\n threshold: LogLevel,\n message: string,\n fields?: Record<string, unknown>,\n): void {\n if (logLevelOrder[level] < logLevelOrder[threshold]) {\n return;\n }\n\n const fn =\n logger[level] ?? logger.warn ?? logger.info ?? logger.debug ?? logger.error ?? console.log;\n\n try {\n fn.call(logger, message, fields);\n } catch {\n // Logging should never disrupt instrumentation.\n }\n}\n","const utf8Decoder =\n typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8', { fatal: true }) : null;\nconst utf8DecoderLenient = typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8') : null;\nconst maybeBuffer = (\n globalThis as typeof globalThis & {\n Buffer?: {\n from(\n data: Uint8Array | string,\n encoding?: string,\n ): {\n toString(encoding?: string): string;\n };\n };\n }\n).Buffer;\n\nexport function encodeBase64(bytes: Uint8Array): string {\n if (maybeBuffer) {\n return maybeBuffer.from(bytes).toString('base64');\n }\n let binary = '';\n for (let i = 0; i < bytes.length; i += 1) {\n const byte = bytes[i];\n if (byte === undefined) {\n continue;\n }\n binary += String.fromCharCode(byte);\n }\n if (typeof btoa !== 'undefined') {\n return btoa(binary);\n }\n return '';\n}\n\nexport function encodeBase64String(value: string): string {\n if (maybeBuffer) {\n return maybeBuffer.from(value, 'utf8').toString('base64');\n }\n if (typeof TextEncoder !== 'undefined') {\n return encodeBase64(new TextEncoder().encode(value));\n }\n if (typeof btoa !== 'undefined') {\n return btoa(unescape(encodeURIComponent(value)));\n }\n return '';\n}\n\nexport function isValidUtf8(bytes: Uint8Array): boolean {\n if (!utf8Decoder) {\n return false;\n }\n try {\n utf8Decoder.decode(bytes);\n return true;\n } catch {\n return false;\n }\n}\n\nexport function decodeUtf8(bytes: Uint8Array): string {\n if (utf8DecoderLenient) {\n return utf8DecoderLenient.decode(bytes);\n }\n if (maybeBuffer) {\n return maybeBuffer.from(bytes).toString('utf8');\n }\n return '';\n}\n","import type { CapturedBody } from './types';\nimport { decodeUtf8, encodeBase64, isValidUtf8 } from './encoding';\n\n// eslint-disable-next-line no-control-regex\nconst controlChars = /[\\x00-\\x1F\\x7F]/g;\n\nexport function sanitizeLogString(value: string): string {\n if (!value) {\n return value;\n }\n return value.replace(controlChars, '');\n}\n\nexport function sanitizeHeaderValues(\n headers: Record<string, string | string[]> | undefined,\n): Record<string, string | string[]> | undefined {\n if (!headers) {\n return undefined;\n }\n\n const sanitized: Record<string, string | string[]> = {};\n for (const [key, value] of Object.entries(headers)) {\n const name = sanitizeLogString(key);\n if (Array.isArray(value)) {\n sanitized[name] = value.map((entry) => sanitizeLogString(entry));\n } else {\n sanitized[name] = sanitizeLogString(value);\n }\n }\n return sanitized;\n}\n\nexport function makeCapturedBody(\n bytes: Uint8Array | undefined,\n totalBytes: number,\n truncated: boolean,\n mode: 'text' | 'base64',\n): CapturedBody | undefined {\n if (!bytes) {\n return undefined;\n }\n\n if (mode === 'base64') {\n return {\n bytes: totalBytes,\n encoding: 'base64',\n truncated,\n value: encodeBase64(bytes),\n };\n }\n\n if (isValidUtf8(bytes)) {\n return {\n bytes: totalBytes,\n encoding: 'utf8',\n truncated,\n value: decodeUtf8(bytes),\n };\n }\n\n return {\n bytes: totalBytes,\n encoding: 'base64',\n truncated,\n value: encodeBase64(bytes),\n };\n}\n","import type { Span } from '@opentelemetry/api';\nimport type { AttributeValue, NormalizedRequest, XrayContext } from './types';\nimport type { CaptureConfig, RedactionConfig, ResolvedXrayConfig } from './config';\n\nexport type RequestState = {\n request: NormalizedRequest;\n config: ResolvedXrayConfig;\n span?: Span;\n context: XrayContext;\n attributes: Record<string, AttributeValue>;\n events: Array<{ name: string; attributes?: Record<string, AttributeValue> }>;\n userId?: string;\n sessionId?: string;\n error?: unknown;\n captureOverride?: Partial<CaptureConfig>;\n redactionOverride?: Partial<RedactionConfig>;\n};\n\nconst contextMap = new WeakMap<XrayContext, RequestState>();\nconst objectMap = new WeakMap<object, RequestState>();\n\nexport function bindContext(ctx: XrayContext, state: RequestState): void {\n contextMap.set(ctx, state);\n}\n\nexport function getContextState(ctx: XrayContext): RequestState | undefined {\n return contextMap.get(ctx);\n}\n\nexport function bindObject(target: object, state: RequestState): void {\n objectMap.set(target, state);\n}\n\nexport function getContextFromObject(target: unknown): XrayContext | undefined {\n const state = getStateFromObject(target);\n return state?.context;\n}\n\nexport function getStateFromObject(target: unknown): RequestState | undefined {\n if (!target || typeof target !== 'object') {\n return undefined;\n }\n if (objectMap.has(target)) {\n return objectMap.get(target);\n }\n\n const fallback = findNestedTarget(target as Record<string, unknown>);\n if (fallback && objectMap.has(fallback)) {\n return objectMap.get(fallback);\n }\n return undefined;\n}\n\nfunction findNestedTarget(obj: Record<string, unknown>): object | null {\n if (obj.raw && typeof obj.raw === 'object') {\n return obj.raw as object;\n }\n if (obj.req && typeof obj.req === 'object') {\n const req = obj.req as Record<string, unknown>;\n if (req.raw && typeof req.raw === 'object') {\n return req.raw as object;\n }\n return req as object;\n }\n if (obj.request && typeof obj.request === 'object') {\n const request = obj.request as Record<string, unknown>;\n if (request.raw && typeof request.raw === 'object') {\n return request.raw as object;\n }\n return request as object;\n }\n return null;\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.cjs
CHANGED
|
@@ -26,6 +26,40 @@ __export(index_exports, {
|
|
|
26
26
|
});
|
|
27
27
|
module.exports = __toCommonJS(index_exports);
|
|
28
28
|
|
|
29
|
+
// src/encoding.ts
|
|
30
|
+
var utf8Decoder = typeof TextDecoder !== "undefined" ? new TextDecoder("utf-8", { fatal: true }) : null;
|
|
31
|
+
var utf8DecoderLenient = typeof TextDecoder !== "undefined" ? new TextDecoder("utf-8") : null;
|
|
32
|
+
var maybeBuffer = globalThis.Buffer;
|
|
33
|
+
function encodeBase64(bytes) {
|
|
34
|
+
if (maybeBuffer) {
|
|
35
|
+
return maybeBuffer.from(bytes).toString("base64");
|
|
36
|
+
}
|
|
37
|
+
let binary = "";
|
|
38
|
+
for (let i = 0; i < bytes.length; i += 1) {
|
|
39
|
+
const byte = bytes[i];
|
|
40
|
+
if (byte === void 0) {
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
binary += String.fromCharCode(byte);
|
|
44
|
+
}
|
|
45
|
+
if (typeof btoa !== "undefined") {
|
|
46
|
+
return btoa(binary);
|
|
47
|
+
}
|
|
48
|
+
return "";
|
|
49
|
+
}
|
|
50
|
+
function encodeBase64String(value) {
|
|
51
|
+
if (maybeBuffer) {
|
|
52
|
+
return maybeBuffer.from(value, "utf8").toString("base64");
|
|
53
|
+
}
|
|
54
|
+
if (typeof TextEncoder !== "undefined") {
|
|
55
|
+
return encodeBase64(new TextEncoder().encode(value));
|
|
56
|
+
}
|
|
57
|
+
if (typeof btoa !== "undefined") {
|
|
58
|
+
return btoa(unescape(encodeURIComponent(value)));
|
|
59
|
+
}
|
|
60
|
+
return "";
|
|
61
|
+
}
|
|
62
|
+
|
|
29
63
|
// src/route.ts
|
|
30
64
|
function normalizeRoutePattern(route) {
|
|
31
65
|
if (!route) {
|
|
@@ -35,7 +69,8 @@ function normalizeRoutePattern(route) {
|
|
|
35
69
|
if (!cleaned) {
|
|
36
70
|
return "/";
|
|
37
71
|
}
|
|
38
|
-
const
|
|
72
|
+
const withoutMethod = stripMethodPrefix(cleaned);
|
|
73
|
+
const leading = withoutMethod.startsWith("/") ? withoutMethod : `/${withoutMethod}`;
|
|
39
74
|
const segments = leading.split("/").filter(Boolean);
|
|
40
75
|
if (segments.length === 0) {
|
|
41
76
|
return "/";
|
|
@@ -43,6 +78,16 @@ function normalizeRoutePattern(route) {
|
|
|
43
78
|
const normalized = segments.map(normalizeRouteSegment).join("/");
|
|
44
79
|
return `/${normalized}`;
|
|
45
80
|
}
|
|
81
|
+
function stripMethodPrefix(value) {
|
|
82
|
+
if (!/^[A-Z]+\s+\//.test(value)) {
|
|
83
|
+
return value;
|
|
84
|
+
}
|
|
85
|
+
const spaceIndex = value.search(/\s+/);
|
|
86
|
+
if (spaceIndex < 0) {
|
|
87
|
+
return value;
|
|
88
|
+
}
|
|
89
|
+
return value.slice(spaceIndex).trim();
|
|
90
|
+
}
|
|
46
91
|
function stripQueryAndFragment(value) {
|
|
47
92
|
const hashIndex = value.indexOf("#");
|
|
48
93
|
const beforeHash = hashIndex >= 0 ? value.slice(0, hashIndex) : value;
|
|
@@ -51,25 +96,57 @@ function stripQueryAndFragment(value) {
|
|
|
51
96
|
}
|
|
52
97
|
function normalizeRouteSegment(segment) {
|
|
53
98
|
if (segment === "*") {
|
|
54
|
-
return "
|
|
99
|
+
return "{wildcard}";
|
|
100
|
+
}
|
|
101
|
+
const param = extractRouteParam(segment);
|
|
102
|
+
if (param) {
|
|
103
|
+
return `{${param}}`;
|
|
104
|
+
}
|
|
105
|
+
return segment;
|
|
106
|
+
}
|
|
107
|
+
function extractRouteParam(segment) {
|
|
108
|
+
if (!segment) {
|
|
109
|
+
return null;
|
|
55
110
|
}
|
|
56
111
|
if (segment.startsWith("[") && segment.endsWith("]")) {
|
|
57
|
-
|
|
58
|
-
if (inner.startsWith("...") || inner.startsWith("[...")) {
|
|
59
|
-
return "*";
|
|
60
|
-
}
|
|
61
|
-
return `:${inner}`;
|
|
112
|
+
return normalizeNextParam(segment);
|
|
62
113
|
}
|
|
63
114
|
if (segment.startsWith("{") && segment.endsWith("}")) {
|
|
64
|
-
|
|
115
|
+
const inner = segment.slice(1, -1);
|
|
116
|
+
const trimmed = stripParamDecorators(inner);
|
|
117
|
+
return extractParamName(trimmed);
|
|
118
|
+
}
|
|
119
|
+
if (segment.startsWith(":") || segment.startsWith("$")) {
|
|
120
|
+
return extractParamName(segment.slice(1));
|
|
65
121
|
}
|
|
66
|
-
|
|
67
|
-
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
function normalizeNextParam(segment) {
|
|
125
|
+
let inner = segment.slice(1, -1);
|
|
126
|
+
if (inner.startsWith("[") && inner.endsWith("]")) {
|
|
127
|
+
inner = inner.slice(1, -1);
|
|
68
128
|
}
|
|
69
|
-
if (
|
|
70
|
-
|
|
129
|
+
if (inner.startsWith("...")) {
|
|
130
|
+
inner = inner.slice(3);
|
|
71
131
|
}
|
|
72
|
-
return
|
|
132
|
+
return extractParamName(inner);
|
|
133
|
+
}
|
|
134
|
+
function stripParamDecorators(value) {
|
|
135
|
+
let trimmed = value.trim();
|
|
136
|
+
if (!trimmed) {
|
|
137
|
+
return trimmed;
|
|
138
|
+
}
|
|
139
|
+
if (trimmed.endsWith("...")) {
|
|
140
|
+
trimmed = trimmed.slice(0, -3);
|
|
141
|
+
}
|
|
142
|
+
return trimmed.replace(/[?*+]+$/, "");
|
|
143
|
+
}
|
|
144
|
+
function extractParamName(value) {
|
|
145
|
+
if (!value) {
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
const match = value.match(/^[A-Za-z0-9_-]+/);
|
|
149
|
+
return match?.[0] ?? null;
|
|
73
150
|
}
|
|
74
151
|
|
|
75
152
|
// src/config.ts
|
|
@@ -95,9 +172,10 @@ var defaultRoute = {
|
|
|
95
172
|
normalizer: normalizeRoutePattern
|
|
96
173
|
};
|
|
97
174
|
var DEFAULT_ENDPOINT_URL = "http://localhost:4318";
|
|
175
|
+
var defaultExporterHeaders = {};
|
|
98
176
|
var defaultExporterBase = {
|
|
99
177
|
endpointUrl: DEFAULT_ENDPOINT_URL,
|
|
100
|
-
headers:
|
|
178
|
+
headers: defaultExporterHeaders,
|
|
101
179
|
timeoutMs: 5e3,
|
|
102
180
|
spanProcessor: "batch",
|
|
103
181
|
sampler: { type: "ratio", ratio: 1 }
|
|
@@ -190,14 +268,15 @@ function normalizeRoute(cfg) {
|
|
|
190
268
|
return route;
|
|
191
269
|
}
|
|
192
270
|
function normalizeExporter(endpointUrl, cfg) {
|
|
193
|
-
const
|
|
271
|
+
const resolved = normalizeExporterEndpoint(cfg?.endpointUrl ?? endpointUrl);
|
|
194
272
|
const enabled = cfg?.enabled ?? true;
|
|
273
|
+
const headers = normalizeExporterHeaders(cfg?.headers, resolved.authHeader);
|
|
195
274
|
const exporter = {
|
|
196
275
|
...defaultExporterBase,
|
|
197
276
|
...cfg,
|
|
198
277
|
enabled,
|
|
199
|
-
endpointUrl:
|
|
200
|
-
headers
|
|
278
|
+
endpointUrl: resolved.endpointUrl,
|
|
279
|
+
headers,
|
|
201
280
|
timeoutMs: cfg?.timeoutMs ?? defaultExporterBase.timeoutMs,
|
|
202
281
|
spanProcessor: cfg?.spanProcessor ?? defaultExporterBase.spanProcessor,
|
|
203
282
|
sampler: cfg?.sampler ?? defaultExporterBase.sampler
|
|
@@ -212,14 +291,12 @@ function normalizeExporter(endpointUrl, cfg) {
|
|
|
212
291
|
return exporter;
|
|
213
292
|
}
|
|
214
293
|
function normalizeExporterEndpoint(endpointUrl) {
|
|
215
|
-
const envUrl = typeof process !== "undefined" ? process.env?.["
|
|
294
|
+
const envUrl = typeof process !== "undefined" ? process.env?.["STAINLESS_XRAY_ENDPOINT_URL"] : void 0;
|
|
216
295
|
const resolved = endpointUrl ?? envUrl ?? DEFAULT_ENDPOINT_URL;
|
|
217
296
|
const trimmed = resolved.trim();
|
|
218
297
|
const withoutTrailingSlash = trimmed.endsWith("/") ? trimmed.slice(0, -1) : trimmed;
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
}
|
|
222
|
-
return `${withoutTrailingSlash}/v1/traces`;
|
|
298
|
+
const withTraces = withoutTrailingSlash.endsWith("/v1/traces") ? withoutTrailingSlash : `${withoutTrailingSlash}/v1/traces`;
|
|
299
|
+
return extractBasicAuth(withTraces);
|
|
223
300
|
}
|
|
224
301
|
function normalizeStringList(values) {
|
|
225
302
|
if (!values) {
|
|
@@ -227,6 +304,37 @@ function normalizeStringList(values) {
|
|
|
227
304
|
}
|
|
228
305
|
return values.map((entry) => entry.trim()).filter(Boolean);
|
|
229
306
|
}
|
|
307
|
+
function normalizeExporterHeaders(headers, authHeader) {
|
|
308
|
+
const resolved = headers ?? defaultExporterHeaders;
|
|
309
|
+
if (!authHeader) {
|
|
310
|
+
return resolved;
|
|
311
|
+
}
|
|
312
|
+
if (hasHeader(resolved, "authorization")) {
|
|
313
|
+
return resolved;
|
|
314
|
+
}
|
|
315
|
+
return { ...resolved, Authorization: authHeader };
|
|
316
|
+
}
|
|
317
|
+
function extractBasicAuth(endpointUrl) {
|
|
318
|
+
try {
|
|
319
|
+
const url = new URL(endpointUrl);
|
|
320
|
+
if (!url.username && !url.password) {
|
|
321
|
+
return { endpointUrl };
|
|
322
|
+
}
|
|
323
|
+
const username = url.username;
|
|
324
|
+
const password = url.password;
|
|
325
|
+
url.username = "";
|
|
326
|
+
url.password = "";
|
|
327
|
+
const credentials = `${username}:${password}`;
|
|
328
|
+
const authHeader = `Basic ${encodeBase64String(credentials)}`;
|
|
329
|
+
return { endpointUrl: url.toString(), authHeader };
|
|
330
|
+
} catch {
|
|
331
|
+
return { endpointUrl };
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
function hasHeader(headers, name) {
|
|
335
|
+
const target = name.toLowerCase();
|
|
336
|
+
return Object.keys(headers).some((key) => key.toLowerCase() === target);
|
|
337
|
+
}
|
|
230
338
|
|
|
231
339
|
// src/logger.ts
|
|
232
340
|
var logLevelOrder = {
|
|
@@ -596,11 +704,6 @@ function redactJsonPath(value, segments, replacement) {
|
|
|
596
704
|
}
|
|
597
705
|
}
|
|
598
706
|
|
|
599
|
-
// src/encoding.ts
|
|
600
|
-
var utf8Decoder = typeof TextDecoder !== "undefined" ? new TextDecoder("utf-8", { fatal: true }) : null;
|
|
601
|
-
var utf8DecoderLenient = typeof TextDecoder !== "undefined" ? new TextDecoder("utf-8") : null;
|
|
602
|
-
var maybeBuffer = globalThis.Buffer;
|
|
603
|
-
|
|
604
707
|
// src/request_log.ts
|
|
605
708
|
var controlChars = /[\x00-\x1F\x7F]/g;
|
|
606
709
|
function sanitizeLogString(value) {
|
|
@@ -888,7 +991,7 @@ function createSampler(config) {
|
|
|
888
991
|
}
|
|
889
992
|
function sdkVersion() {
|
|
890
993
|
if (true) {
|
|
891
|
-
return "0.
|
|
994
|
+
return "0.2.0";
|
|
892
995
|
}
|
|
893
996
|
return "unknown";
|
|
894
997
|
}
|
|
@@ -1064,6 +1167,10 @@ function endRequest(config, ctx, res, err) {
|
|
|
1064
1167
|
timestamp: new Date(endTimeMs).toISOString()
|
|
1065
1168
|
};
|
|
1066
1169
|
const redacted = applyRedaction(redaction, log);
|
|
1170
|
+
if (redacted.route && config.route.normalize) {
|
|
1171
|
+
const normalized = config.route.normalizer ? config.route.normalizer(redacted.route) : normalizeRoutePattern(redacted.route);
|
|
1172
|
+
redacted.route = normalized;
|
|
1173
|
+
}
|
|
1067
1174
|
const span = state.span;
|
|
1068
1175
|
if (span) {
|
|
1069
1176
|
try {
|
|
@@ -1074,9 +1181,8 @@ function endRequest(config, ctx, res, err) {
|
|
|
1074
1181
|
setResponseStatusAttribute(span, redacted.statusCode);
|
|
1075
1182
|
}
|
|
1076
1183
|
if (redacted.route) {
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
span.updateName(`${request.method} ${normalized}`);
|
|
1184
|
+
setRouteAttribute(span, redacted.route);
|
|
1185
|
+
span.updateName(`${request.method} ${redacted.route}`);
|
|
1080
1186
|
} else {
|
|
1081
1187
|
span.updateName(spanNameFromRequest(request));
|
|
1082
1188
|
}
|