UNPKG

@oselvar/c4

Version:

Test helpers for Cloudflare Workers

75 lines 2.28 kB
// src/decorators/index.ts import { basename, extname } from "node:path"; import { trace } from "@opentelemetry/api"; import ErrorStackParser from "error-stack-parser"; function C4Component(params) { return (component) => { const tracer = trace.getTracer("@oselvar/c4"); const span = tracer.startSpan("component"); span.setAttribute("name", component.name); span.setAttribute("tags", params?.tags || []); span.end(); return component; }; } function C4Operation() { return function(...args) { if (args.length === 2 && args[1] && typeof args[1] === "object" && args[1].kind === "method") { const method = args[0]; return c4OperationWrapper(method); } else { const descriptor = args[2]; if (descriptor && typeof descriptor.value === "function") { const originalMethod = descriptor.value; descriptor.value = c4OperationWrapper(originalMethod); } return descriptor; } }; } function c4OperationWrapper(method) { async function wrapper(...args) { const calleeName = this.constructor.name; const stack = ErrorStackParser.parse(new Error()); const callerClassNameCandidates = stack.filter((frame) => !frame.fileName?.match(/\/node_modules\//)).filter((frame) => !frame.fileName?.match(/^node:internal/)).flatMap(toClassNames); const callerName = callerClassNameCandidates.find( (callerName2) => callerName2 !== calleeName ); const operationName = method.name; const tracer = trace.getTracer("@oselvar/c4"); return tracer.startActiveSpan( "call", { attributes: { callerName, calleeName, operationName } }, async (span) => { try { return await method.apply(this, args); } finally { span.end(); } } ); } return wrapper; } function toClassNames(frame) { const classNames = []; const functioNameParts = frame.functionName?.split(".") || []; if (functioNameParts.length === 2) { classNames.push(functioNameParts[0]); } if (frame.fileName) { classNames.push(basename(frame.fileName, extname(frame.fileName))); } return classNames; } export { C4Component, C4Operation }; //# sourceMappingURL=index.js.map