@camunda8/sdk
Version:
[](https://www.npmjs.com/package/@camunda8/sdk)
112 lines • 4 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.createTrackedGot = createTrackedGot;
const node_crypto_1 = require("node:crypto");
const OriginTracing_1 = require("./OriginTracing");
/**
* Wrap a got instance with a Proxy that injects AsyncLocalStorage-derived stack context
* into each request's options.context.__stackTrace.
* It preserves the full surface of the original got instance (HTTP verb helpers, extend, etc.).
*/
function createTrackedGot(gotInstance) {
// Capture stack synchronously before got does internal async work
const capture = () => {
const raw = new Error('tracked-got-capture').stack?.split('\n').slice(1) ?? [];
const frames = raw.map((line) => ({
location: line.trim(),
stack: line.trim(),
timestamp: Date.now(),
}));
return { frames, flat: frames.map((f) => f.location).join('\n') };
};
const withStackContext = (options) => {
const base = options ? { ...options } : {};
const origin = OriginTracing_1.originContextStorage.getStore();
let frames;
let flat;
let requestId;
let capturedAt;
if (origin) {
frames = origin.frames.map((loc) => ({
location: loc,
stack: loc,
timestamp: origin.capturedAt,
}));
flat = origin.frames.join('\n');
requestId = origin.requestId;
capturedAt = origin.capturedAt;
}
else {
const local = capture();
frames = local.frames;
flat = local.flat;
requestId = (0, node_crypto_1.randomUUID)();
capturedAt = Date.now();
}
const structured = {
stacks: frames,
requestId,
capturedAt,
apiMethod: origin?.apiMethod,
};
return {
...base,
context: {
...(base.context ?? {}),
stack: flat,
__stackTrace: structured,
},
};
};
const httpVerbs = new Set([
'get',
'post',
'put',
'patch',
'delete',
'head',
'options',
'trace',
]);
const proxy = new Proxy(gotInstance, {
apply(target, thisArg, argArray) {
const [url, options] = argArray;
const enhanced = withStackContext(options);
// eslint-disable-next-line @typescript-eslint/ban-types
return Reflect.apply(target, thisArg, [
url,
enhanced,
]);
},
get(target, prop, receiver) {
if (prop === 'extend') {
return (...extendArgs) => {
// @ts-expect-error dynamic call
const extended = target.extend(...extendArgs);
return createTrackedGot(extended);
};
}
if (httpVerbs.has(String(prop))) {
const original = Reflect.get(target, prop, receiver);
if (typeof original === 'function') {
return (...methodArgs) => {
if (methodArgs.length === 0)
return original();
const lastIndex = methodArgs.length - 1;
const last = methodArgs.at(lastIndex);
if (last && typeof last === 'object' && !Array.isArray(last)) {
methodArgs[lastIndex] = withStackContext(last);
}
else {
methodArgs.push(withStackContext());
}
return original(...methodArgs);
};
}
}
return Reflect.get(target, prop, receiver);
},
});
return proxy;
}
//# sourceMappingURL=TrackedGot.js.map