{"version":3,"sources":["../src/decorators.ts"],"names":["getConfig","createTraceContext","SpanStatusCode"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAmGO,SAAS,KAAA,CACd,eACA,YAAA,EAIK;AAEL,EAAA,MAAM,IAAA,GACJ,OAAO,aAAA,KAAkB,QAAA,GAAW,gBAAgB,aAAA,EAAe,IAAA;AASrE,EAAA,OAAO,SACL,gBACA,OAAA,EACG;AACH,IAAA,MAAM,UAAA,GAAa,MAAA,CAAO,OAAA,CAAQ,IAAI,CAAA;AAKtC,IAAA,MAAM,SAAA,GAAY,cAAA,EAAgB,QAAA,EAAS,IAAK,EAAA;AAChD,IAAA,MAAM,UACJ,cAAA,KACC,cAAA,CAAe,aAAa,IAAA,KAAS,eAAA,IACpC,UAAU,IAAA,EAAK,CAAE,UAAA,CAAW,QAAQ,KACnC,SAAA,CAAU,QAAA,CAAS,eAAe,CAAA,IAAK,SAAA,CAAU,SAAS,OAAO,CAAA;AAAA,IAElE,UAAA,CAAW,KAAK,SAAS,CAAA,CAAA;AAE7B,IAAA,IAAI,CAAC,OAAA,EAAS;AAEZ,MAAA,OAAO,cAAA;AAAA,IACT;AAEA,IAAA,MAAM,WAAW,IAAA,IAAQ,UAAA;AAEzB,IAAA,OAAO,kBAEF,IAAA,EACe;AAClB,MAAA,MAAM,SAASA,2BAAA,EAAU;AACzB,MAAA,MAAM,SAAS,MAAA,CAAO,MAAA;AAEtB,MAAA,OAAO,MAAA,CAAO,eAAA,CAAgB,QAAA,EAAU,OAAO,IAAA,KAAS;AACtD,QAAA,IAAI;AAEF,UAAA,MAAM,GAAA,GAAoBC,qCAAmB,IAAI,CAAA;AAEjD,UAAA,MAAM,cAAe,IAAA,CAAgC,GAAA;AACrD,UAAA,IAAI;AACF,YAAC,KAAgC,GAAA,GAAM,GAAA;AACvC,YAAA,MAAM,MAAA,GAAS,MAAM,cAAA,CAAe,KAAA,CAAM,MAAM,IAAU,CAAA;AAC1D,YAAA,IAAA,CAAK,SAAA,CAAU,EAAE,IAAA,EAAMC,kBAAA,CAAe,IAAI,CAAA;AAC1C,YAAA,OAAO,MAAA;AAAA,UACT,CAAA,SAAE;AAEA,YAAA,IAAI,gBAAgB,KAAA,CAAA,EAAW;AAC7B,cAAA,OAAQ,IAAA,CAAgC,GAAA;AAAA,YAC1C,CAAA,MAAO;AACL,cAAC,KAAgC,GAAA,GAAM,WAAA;AAAA,YACzC;AAAA,UACF;AAAA,QACF,SAAS,KAAA,EAAO;AACd,UAAA,IAAA,CAAK,SAAA,CAAU;AAAA,YACb,MAAMA,kBAAA,CAAe,KAAA;AAAA,YACrB,OAAA,EAAS,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU;AAAA,WACnD,CAAA;AACD,UAAA,IAAA,CAAK,eAAA;AAAA,YACH,iBAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,KAAA,CAAM,MAAA,CAAO,KAAK,CAAC;AAAA,WAC1D;AACA,UAAA,MAAM,KAAA;AAAA,QACR,CAAA,SAAE;AACA,UAAA,IAAA,CAAK,GAAA,EAAI;AAAA,QACX;AAAA,MACF,CAAC,CAAA;AAAA,IACH,CAAA;AAAA,EACF,CAAA;AACF","file":"decorators.cjs","sourcesContent":["/**\n * TypeScript 5+ Decorators for autotel\n *\n * Provides @Trace decorator for class-based code.\n *\n * **Requires TypeScript 5.0+**\n *\n * @example Method decorator\n * ```typescript\n * import { Trace } from 'autotel/decorators'\n *\n * class OrderService {\n *   @Trace('order.create', { withMetrics: true })\n *   async createOrder(data: OrderData) {\n *     return await db.orders.create(data)\n *   }\n *\n *   @Trace() // Uses method name as span name\n *   async processPayment(orderId: string) {\n *     return await stripe.charge(orderId)\n *   }\n * }\n * ```\n */\n\nimport type { TracingOptions, TraceContext } from './functional';\nimport { getConfig } from './config';\nimport { SpanStatusCode } from '@opentelemetry/api';\nimport { createTraceContext } from './trace-context';\n\n/**\n * Options for @Trace method decorator\n */\nexport interface TraceDecoratorOptions extends Omit<TracingOptions, 'name'> {\n  /**\n   * Custom span name. If not provided, uses the method name.\n   */\n  name?: string;\n}\n\n/**\n * @Trace - Method decorator for fine-grained tracing\n *\n * Wraps a class method with automatic tracing. Supports both patterns:\n * - Simple: method doesn't use ctx\n * - Advanced: method accesses ctx via this.ctx\n *\n * @example Simple usage (no ctx)\n * ```typescript\n * class OrderService {\n *   @Trace()\n *   async createOrder(data: OrderData) {\n *     return await db.orders.create(data)\n *   }\n * }\n * ```\n *\n * @example With custom name and options\n * ```typescript\n * class PaymentService {\n *   @Trace('payment.charge', { withMetrics: true })\n *   async chargeCard(amount: number) {\n *     return await stripe.charges.create({ amount })\n *   }\n * }\n * ```\n *\n * @example Accessing ctx\n * ```typescript\n * interface WithTraceContext {\n *   ctx?: TraceContext\n * }\n *\n * class UserService {\n *   @Trace()\n *   async createUser(data: UserData) {\n *     // Access ctx via this.ctx (available during execution)\n *     const ctx = (this as unknown as WithTraceContext).ctx\n *     if (ctx) {\n *       ctx.setAttribute('user.id', data.id)\n *     }\n *     return await db.users.create(data)\n *   }\n * }\n * ```\n */\nexport function Trace(\n  options?: TraceDecoratorOptions,\n): <T extends (...args: unknown[]) => Promise<unknown>>(\n  originalMethod: T,\n  context: ClassMethodDecoratorContext,\n) => T;\nexport function Trace(\n  name?: string,\n  options?: TraceDecoratorOptions,\n): <T extends (...args: unknown[]) => Promise<unknown>>(\n  originalMethod: T,\n  context: ClassMethodDecoratorContext,\n) => T;\nexport function Trace(\n  nameOrOptions?: string | TraceDecoratorOptions,\n  maybeOptions?: TraceDecoratorOptions,\n): <T extends (...args: unknown[]) => Promise<unknown>>(\n  originalMethod: T,\n  context: ClassMethodDecoratorContext,\n) => T {\n  // Parse arguments\n  const name =\n    typeof nameOrOptions === 'string' ? nameOrOptions : nameOrOptions?.name;\n  // Options are used in the returned decorator function, not here\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  const _options: TraceDecoratorOptions =\n    typeof nameOrOptions === 'string'\n      ? maybeOptions || {}\n      : nameOrOptions || {};\n\n  // TypeScript 5+ decorator signature\n  return function <T extends (...args: unknown[]) => Promise<unknown>>(\n    originalMethod: T,\n    context: ClassMethodDecoratorContext,\n  ): T {\n    const methodName = String(context.name);\n\n    // Skip if not an async function\n    // Check multiple ways to detect async functions (for different transpilation environments)\n    // TypeScript decorators run at class definition time, so we need robust detection\n    const methodStr = originalMethod?.toString() || '';\n    const isAsync =\n      originalMethod &&\n      (originalMethod.constructor?.name === 'AsyncFunction' ||\n        methodStr.trim().startsWith('async ') ||\n        (methodStr.includes('[native code]') && methodStr.includes('async')) ||\n        // Fallback: if function has async in its string representation\n        /async\\s+/.test(methodStr));\n\n    if (!isAsync) {\n      // Not an async function, return as-is\n      return originalMethod;\n    }\n\n    const spanName = name || methodName;\n\n    return async function <This>(\n      this: This,\n      ...args: unknown[]\n    ): Promise<unknown> {\n      const config = getConfig();\n      const tracer = config.tracer;\n\n      return tracer.startActiveSpan(spanName, async (span) => {\n        try {\n          // Make ctx available via this.ctx for methods that need it\n          const ctx: TraceContext = createTraceContext(span);\n\n          const originalCtx = (this as { ctx?: TraceContext }).ctx;\n          try {\n            (this as { ctx?: TraceContext }).ctx = ctx;\n            const result = await originalMethod.apply(this, args as []);\n            span.setStatus({ code: SpanStatusCode.OK });\n            return result;\n          } finally {\n            // Restore original ctx\n            if (originalCtx === undefined) {\n              delete (this as { ctx?: TraceContext }).ctx;\n            } else {\n              (this as { ctx?: TraceContext }).ctx = originalCtx;\n            }\n          }\n        } catch (error) {\n          span.setStatus({\n            code: SpanStatusCode.ERROR,\n            message: error instanceof Error ? error.message : 'Unknown error',\n          });\n          span.recordException(\n            error instanceof Error ? error : new Error(String(error)),\n          );\n          throw error;\n        } finally {\n          span.end();\n        }\n      });\n    } as T;\n  };\n}\n\n// Re-export types for convenience\n\nexport { type TraceContext, type TracingOptions } from './functional';\n"]}