UNPKG

nestjs-otel

Version:
78 lines (77 loc) 2.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.WideEventField = WideEventField; const opentelemetry_utils_1 = require("../opentelemetry.utils"); const wide_event_context_1 = require("./wide-event.context"); const isAttributeValue = (value) => { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { return true; } if (!Array.isArray(value)) { return false; } let elementType; for (const el of value) { if (el == null) continue; const t = typeof el; if (t !== "string" && t !== "number" && t !== "boolean") return false; if (elementType && t !== elementType) return false; elementType = t; } return true; }; const record = (key, pick, result) => { const bag = (0, wide_event_context_1.getWideEventBag)(); if (!bag) { return; } try { const value = pick ? pick(result) : result; if (isAttributeValue(value)) { bag.set(key, value); } } catch { // a failing pick must never break the decorated method } }; /** * Captures the decorated method's return value (resolved value for async * methods) as an attribute on the current wide event. * * No-op when called outside a request handled by the WideEventInterceptor, * when `pick` throws, or when the value is not a valid attribute value. * * @param key The wide event attribute key. * @param pick Optional projection of the return value to an attribute value. * * @publicApi */ function WideEventField(key, pick) { return (_target, propertyKey, propertyDescriptor) => { const originalFunction = propertyDescriptor.value; if (typeof originalFunction !== "function") { throw new Error(`The @WideEventField decorator can be only used on functions, but ${propertyKey.toString()} is not a function.`); } const wrappedFunction = function WideEventFieldWrapper(...args) { const result = originalFunction.apply(this, args); if (result instanceof Promise) { return result.then((resolved) => { record(key, pick, resolved); return resolved; }); } record(key, pick, result); return result; }; propertyDescriptor.value = new Proxy(originalFunction, { apply: (_, thisArg, args) => wrappedFunction.apply(thisArg, args), }); (0, opentelemetry_utils_1.copyMetadataFromFunctionToFunction)(originalFunction, propertyDescriptor.value); }; }