@camunda8/sdk
Version:
[](https://www.npmjs.com/package/@camunda8/sdk)
101 lines • 4.22 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.originContextStorage = void 0;
exports.captureOrigin = captureOrigin;
exports.TraceOrigin = TraceOrigin;
const node_async_hooks_1 = require("node:async_hooks");
const node_crypto_1 = require("node:crypto");
const node_fs_1 = __importDefault(require("node:fs"));
const node_path_1 = __importDefault(require("node:path"));
exports.originContextStorage = new node_async_hooks_1.AsyncLocalStorage();
const INTERNAL_PATTERNS = [
'/TrackedGot.',
'node:internal/modules',
'diagnostics_channel',
];
function isInternalFrame(line) {
// Drop the explicit capture helper frame but keep decorated method frames
if (line.includes('captureOrigin ('))
return true;
return INTERNAL_PATTERNS.some((p) => line.includes(p));
}
// Cache for method line lookup
const methodLineCache = {};
function findMethodLine(classFile, methodName) {
if (methodLineCache[methodName])
return methodLineCache[methodName];
try {
const contents = node_fs_1.default.readFileSync(classFile, 'utf8').split('\n');
for (let i = 0; i < contents.length; i++) {
if (contents[i].includes(`${methodName}(`)) {
methodLineCache[methodName] = i + 1; // 1-based
return methodLineCache[methodName];
}
}
}
catch {
return undefined;
}
return undefined;
}
function remapDecoratorFrame(line) {
// Only adjust frames where the method belongs to CamundaRestClient but file is OriginTracing
if (!/CamundaRestClient\./.test(line) || !/OriginTracing\.\w+/.test(line))
return line;
// Resolve potential source file paths (dist and src)
const distPath = node_path_1.default.join(node_path_1.default.dirname(__filename), 'CamundaRestClient.js');
const srcPath = node_path_1.default.join(process.cwd(), 'src', 'c8', 'lib', 'CamundaRestClient.ts');
const preferDist = node_fs_1.default.existsSync(distPath);
const targetFile = preferDist ? distPath : srcPath;
const methodMatch = line.match(/CamundaRestClient\.(\w+)/);
const methodName = methodMatch?.[1];
if (!methodName)
return line;
const targetLine = findMethodLine(targetFile, methodName);
if (!targetLine)
return line;
// Replace parenthetical file reference
return line.replace(/\(.*OriginTracing.*\)/, `(${targetFile}:${targetLine}:1)`); // column unknown, set to 1
}
function captureOrigin() {
const raw = new Error('capture-origin').stack?.split('\n').slice(1) ?? [];
const cleaned = raw
.map((l) => l.trim())
.filter((l) => !isInternalFrame(l))
.map(remapDecoratorFrame);
return {
requestId: (0, node_crypto_1.randomUUID)(),
frames: cleaned,
capturedAt: Date.now(),
};
}
/** Legacy class decorator (single-argument) that wraps instance methods to seed origin context. */
// Legacy decorator: mutate prototype in place, do not return a new constructor.
// eslint-disable-next-line @typescript-eslint/ban-types
function TraceOrigin(Ctor) {
const proto = Ctor.prototype;
for (const key of Object.getOwnPropertyNames(proto)) {
if (key === 'constructor')
continue;
const desc = Object.getOwnPropertyDescriptor(proto, key);
if (!desc || typeof desc.value !== 'function')
continue;
const original = desc.value;
// Use computed property to preserve method name in stack traces
const wrapped = {
[key]: function (...args) {
const existing = exports.originContextStorage.getStore();
if (existing)
return original.apply(this, args);
const origin = captureOrigin();
origin.apiMethod = key;
return exports.originContextStorage.run(origin, () => original.apply(this, args));
},
}[key];
Object.defineProperty(proto, key, { ...desc, value: wrapped });
}
}
//# sourceMappingURL=OriginTracing.js.map