autotel-adapters 0.2.9 → 0.2.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-VFTRQVDR.js → chunk-AD3QBS5J.js} +3 -3
- package/dist/{chunk-VFTRQVDR.js.map → chunk-AD3QBS5J.js.map} +1 -1
- package/dist/{chunk-HC3ZQAZV.js → chunk-CITNYQ2G.js} +3 -3
- package/dist/{chunk-HC3ZQAZV.js.map → chunk-CITNYQ2G.js.map} +1 -1
- package/dist/{chunk-2MUUBQJZ.js → chunk-GBSB7IX7.js} +28 -3
- package/dist/chunk-GBSB7IX7.js.map +1 -0
- package/dist/{chunk-F2K6UTRF.js → chunk-GPWONOFN.js} +3 -3
- package/dist/{chunk-F2K6UTRF.js.map → chunk-GPWONOFN.js.map} +1 -1
- package/dist/{chunk-LFDWJWP2.js → chunk-JC3TNPQD.js} +3 -3
- package/dist/{chunk-LFDWJWP2.js.map → chunk-JC3TNPQD.js.map} +1 -1
- package/dist/{chunk-FPHF553F.js → chunk-UUDK5U3L.js} +3 -3
- package/dist/{chunk-FPHF553F.js.map → chunk-UUDK5U3L.js.map} +1 -1
- package/dist/cloudflare.cjs.map +1 -1
- package/dist/cloudflare.js +2 -2
- package/dist/core.cjs +27 -0
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +41 -1
- package/dist/core.d.ts +41 -1
- package/dist/core.js +1 -1
- package/dist/hono.cjs.map +1 -1
- package/dist/hono.js +2 -2
- package/dist/index.cjs +27 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +6 -6
- package/dist/next.cjs.map +1 -1
- package/dist/next.js +2 -2
- package/dist/nitro.cjs.map +1 -1
- package/dist/nitro.js +2 -2
- package/dist/tanstack.cjs.map +1 -1
- package/dist/tanstack.js +2 -2
- package/package.json +6 -6
- package/src/core.ts +83 -0
- package/src/resolve-adapter-config.test.ts +110 -0
- package/dist/chunk-2MUUBQJZ.js.map +0 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core.ts","../src/next.ts","../src/nitro.ts","../src/cloudflare.ts","../src/hono.ts","../src/tanstack.ts"],"names":["useLogger","getRequestLogger","parseError","createStructuredError","createDrainPipeline","AsyncLocalStorage","trace","baseUseLogger","enrichFromRequest"],"mappings":"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","file":"index.cjs","sourcesContent":["import {\n createDrainPipeline,\n createStructuredError,\n getRequestLogger,\n parseError,\n type ParsedError,\n type RequestLogger,\n type RequestLoggerOptions,\n type RequestLogSnapshot,\n type DrainPipelineOptions,\n type PipelineDrainFn,\n type StructuredError,\n type StructuredErrorInput,\n} from 'autotel';\n\nexport interface AdapterUseLoggerOptions<TContext> {\n adapterName: string;\n enrich?: (context: TContext) => Record<string, unknown> | undefined;\n}\n\nexport interface AdapterToolkit<TContext> {\n useLogger: (\n context?: TContext,\n options?: RequestLoggerOptions,\n ) => RequestLogger;\n parseError: (error: unknown) => ParsedError;\n createStructuredError: (input: StructuredErrorInput) => StructuredError;\n createDrainPipeline: <T = unknown>(\n options?: DrainPipelineOptions<T>,\n ) => (drain: (batch: T[]) => void | Promise<void>) => PipelineDrainFn<T>;\n}\n\nexport function createUseLogger<TContext = unknown>(\n options: AdapterUseLoggerOptions<TContext>,\n) {\n return function useLogger(\n context?: TContext,\n requestLoggerOptions?: RequestLoggerOptions,\n ): RequestLogger {\n let logger: RequestLogger;\n try {\n logger = getRequestLogger(undefined, requestLoggerOptions);\n } catch {\n throw new Error(\n `[autotel-adapters/${options.adapterName}] No active trace context. ` +\n `Wrap your handler with autotel trace instrumentation before calling useLogger().`,\n );\n }\n\n if (context && options.enrich) {\n const extra = options.enrich(context);\n if (extra && Object.keys(extra).length > 0) {\n logger.set(extra);\n }\n }\n\n return logger;\n };\n}\n\nexport function createAdapterToolkit<TContext = unknown>(\n options: AdapterUseLoggerOptions<TContext>,\n): AdapterToolkit<TContext> {\n return {\n useLogger: createUseLogger(options),\n parseError,\n createStructuredError,\n createDrainPipeline,\n };\n}\n\nexport type HeadersLike =\n | { get(name: string): string | null }\n | Record<string, string | undefined>;\n\nexport function getHeader(\n headers: HeadersLike | undefined,\n name: string,\n): string | undefined {\n if (!headers) return undefined;\n if ('get' in headers && typeof headers.get === 'function') {\n return headers.get(name) ?? undefined;\n }\n const dictionary = headers as Record<string, string | undefined>;\n const value = dictionary[name] ?? dictionary[name.toLowerCase()];\n return typeof value === 'string' ? value : undefined;\n}\n\nexport type {\n RequestLogger,\n RequestLoggerOptions,\n RequestLogSnapshot,\n ParsedError,\n StructuredError,\n StructuredErrorInput,\n DrainPipelineOptions,\n PipelineDrainFn,\n};\n","import { AsyncLocalStorage } from 'node:async_hooks';\nimport {\n createDrainPipeline,\n getRequestLogger,\n parseError,\n trace,\n createStructuredError,\n type RequestLogger,\n type RequestLoggerOptions,\n type ParsedError,\n type DrainPipelineOptions,\n type PipelineDrainFn,\n type StructuredError,\n type StructuredErrorInput,\n} from 'autotel';\nimport { createAdapterToolkit, createUseLogger, getHeader } from './core';\n\nexport interface NextRequestLike {\n method?: string;\n url?: string;\n headers?:\n | { get(name: string): string | null }\n | Record<string, string | undefined>;\n}\n\nexport interface NextWithAutotelOptions {\n spanName?: string | ((request?: NextRequestLike) => string);\n requestLoggerOptions?: RequestLoggerOptions;\n enrich?: (request?: NextRequestLike) => Record<string, unknown> | undefined;\n}\n\nconst nextLoggerStorage = new AsyncLocalStorage<RequestLogger>();\n\nfunction enrichFromRequest(\n request?: NextRequestLike,\n): Record<string, unknown> | undefined {\n if (!request) return undefined;\n\n let route = '/';\n if (request.url) {\n try {\n route = new URL(request.url).pathname;\n } catch {\n route = request.url;\n }\n }\n const requestId = getHeader(request.headers, 'x-request-id');\n\n return {\n ...(request.method ? { 'http.request.method': request.method } : {}),\n ...(request.url ? { 'url.full': request.url } : {}),\n ...(route ? { 'http.route': route } : {}),\n ...(requestId ? { 'http.request.header.x-request-id': requestId } : {}),\n };\n}\n\nconst baseUseLogger = createUseLogger<NextRequestLike>({\n adapterName: 'next',\n enrich: enrichFromRequest,\n});\n\nexport function useLogger(\n request?: NextRequestLike,\n requestLoggerOptions?: RequestLoggerOptions,\n): RequestLogger {\n const logger = nextLoggerStorage.getStore();\n if (logger) return logger;\n return baseUseLogger(request, requestLoggerOptions);\n}\n\nexport function withAutotel<TArgs extends unknown[], TReturn>(\n handler: (...args: TArgs) => TReturn | Promise<TReturn>,\n options?: NextWithAutotelOptions,\n): (...args: TArgs) => Promise<TReturn> {\n return async (...args: TArgs): Promise<TReturn> => {\n const request = args[0] as NextRequestLike | undefined;\n const spanName =\n typeof options?.spanName === 'function'\n ? options.spanName(request)\n : (options?.spanName ?? 'next.request');\n\n const wrapped = trace(\n { name: spanName },\n (ctx) => async (...innerArgs: TArgs) => {\n const innerRequest = innerArgs[0] as NextRequestLike | undefined;\n const log = getRequestLogger(ctx, options?.requestLoggerOptions);\n const auto = enrichFromRequest(innerRequest);\n if (auto && Object.keys(auto).length > 0) {\n log.set(auto);\n }\n const custom = options?.enrich?.(innerRequest);\n if (custom && Object.keys(custom).length > 0) {\n log.set(custom);\n }\n return await nextLoggerStorage.run(log, async () => handler(...innerArgs));\n },\n );\n return await wrapped(...args);\n };\n}\n\nexport function createNextAdapter(options?: NextWithAutotelOptions) {\n return {\n withAutotel: <TArgs extends unknown[], TReturn>(\n handler: (...args: TArgs) => TReturn | Promise<TReturn>,\n ) => withAutotel(handler, options),\n useLogger: (\n request?: NextRequestLike,\n requestLoggerOptions?: RequestLoggerOptions,\n ): RequestLogger => useLogger(request, requestLoggerOptions),\n parseError: (error: unknown): ParsedError => parseError(error),\n createStructuredError: (\n input: StructuredErrorInput,\n ): StructuredError => createStructuredError(input),\n createDrainPipeline: <T = unknown>(\n drainOptions?: DrainPipelineOptions<T>,\n ): ((batchDrain: (batch: T[]) => void | Promise<void>) => PipelineDrainFn<T>) =>\n createDrainPipeline(drainOptions),\n };\n}\n\nexport const nextToolkit = createAdapterToolkit<NextRequestLike>({\n adapterName: 'next',\n enrich: enrichFromRequest,\n});\n\nexport { parseError, createDrainPipeline, createStructuredError };\n","import { AsyncLocalStorage } from 'node:async_hooks';\nimport {\n getRequestLogger,\n trace,\n type RequestLogger,\n type RequestLoggerOptions,\n} from 'autotel';\nimport { createAdapterToolkit, createUseLogger } from './core';\n\nexport interface NitroEventLike {\n method?: string;\n path?: string;\n context?: Record<string, unknown>;\n}\n\nexport interface NitroWithAutotelOptions {\n spanName?: string | ((event: NitroEventLike) => string);\n requestLoggerOptions?: RequestLoggerOptions;\n enrich?: (event: NitroEventLike) => Record<string, unknown> | undefined;\n}\n\nfunction enrichFromEvent(\n event?: NitroEventLike,\n): Record<string, unknown> | undefined {\n if (!event) return undefined;\n\n return {\n ...(event.method ? { 'http.request.method': event.method } : {}),\n ...(event.path ? { 'http.route': event.path } : {}),\n ...(typeof event.context?.requestId === 'string'\n ? { 'http.request.id': event.context.requestId }\n : {}),\n };\n}\n\nconst baseUseLogger = createUseLogger<NitroEventLike>({\n adapterName: 'nitro',\n enrich: enrichFromEvent,\n});\nconst nitroLoggerStorage = new AsyncLocalStorage<RequestLogger>();\n\nexport function useLogger(\n event?: NitroEventLike,\n serviceOrOptions?: string | RequestLoggerOptions,\n): RequestLogger {\n const stored = nitroLoggerStorage.getStore();\n const logger = stored ??\n (\n typeof serviceOrOptions === 'string'\n ? baseUseLogger(event)\n : baseUseLogger(event, serviceOrOptions)\n );\n\n if (typeof serviceOrOptions === 'string' && serviceOrOptions.length > 0) {\n logger.set({ service: serviceOrOptions });\n }\n\n return logger;\n}\n\nexport function withAutotelEventHandler<TEvent extends NitroEventLike, TReturn>(\n handler: (event: TEvent) => TReturn | Promise<TReturn>,\n options?: NitroWithAutotelOptions,\n): (event: TEvent) => Promise<TReturn> {\n return async (event: TEvent): Promise<TReturn> => {\n const spanName =\n typeof options?.spanName === 'function'\n ? options.spanName(event)\n : (options?.spanName ?? `nitro.${event.method ?? 'request'}`);\n\n const wrapped = trace({ name: spanName }, (ctx) => async (innerEvent: TEvent) => {\n const log = getRequestLogger(ctx, options?.requestLoggerOptions);\n const auto = enrichFromEvent(innerEvent);\n if (auto && Object.keys(auto).length > 0) {\n log.set(auto);\n }\n const custom = options?.enrich?.(innerEvent);\n if (custom && Object.keys(custom).length > 0) {\n log.set(custom);\n }\n return await nitroLoggerStorage.run(log, async () => handler(innerEvent));\n });\n\n return await wrapped(event);\n };\n}\n\nexport function createNitroAdapter(options?: NitroWithAutotelOptions) {\n const toolkit = createAdapterToolkit<NitroEventLike>({\n adapterName: 'nitro',\n enrich: (event) => ({\n ...enrichFromEvent(event),\n ...(options?.enrich?.(event) ?? {}),\n }),\n });\n\n return {\n withAutotelEventHandler: <TEvent extends NitroEventLike, TReturn>(\n handler: (event: TEvent) => TReturn | Promise<TReturn>,\n ) => withAutotelEventHandler(handler, options),\n useLogger,\n parseError: toolkit.parseError,\n createStructuredError: toolkit.createStructuredError,\n createDrainPipeline: toolkit.createDrainPipeline,\n };\n}\n\nexport const nitroToolkit = createAdapterToolkit<NitroEventLike>({\n adapterName: 'nitro',\n enrich: enrichFromEvent,\n});\n","import {\n createDrainPipeline,\n createStructuredError,\n getRequestLogger,\n parseError,\n trace,\n type DrainPipelineOptions,\n type ParsedError,\n type PipelineDrainFn,\n type RequestLogger,\n type RequestLoggerOptions,\n type StructuredError,\n type StructuredErrorInput,\n} from 'autotel';\nimport { createAdapterToolkit, createUseLogger, getHeader } from './core';\n\nexport interface CloudflareRequestLike {\n method?: string;\n url?: string;\n headers?:\n | { get(name: string): string | null }\n | Record<string, string | undefined>;\n cf?: Record<string, unknown>;\n}\n\nexport interface CloudflareExecutionContextLike {\n waitUntil?: (promise: Promise<unknown>) => void;\n passThroughOnException?: () => void;\n}\n\nexport interface CloudflareWithAutotelOptions<TEnv = unknown> {\n spanName?: string | ((request: CloudflareRequestLike, env: TEnv) => string);\n requestLoggerOptions?: RequestLoggerOptions;\n enrich?: (\n request: CloudflareRequestLike,\n env: TEnv,\n ctx: CloudflareExecutionContextLike,\n ) => Record<string, unknown> | undefined;\n}\n\nconst requestLoggers = new WeakMap<object, RequestLogger>();\n\nfunction enrichFromRequest(\n request?: CloudflareRequestLike,\n): Record<string, unknown> | undefined {\n if (!request) return undefined;\n\n let route = '/';\n if (request.url) {\n try {\n route = new URL(request.url).pathname;\n } catch {\n route = request.url;\n }\n }\n\n const requestId =\n getHeader(request.headers, 'x-request-id') ??\n getHeader(request.headers, 'cf-ray');\n\n return {\n ...(request.method ? { 'http.request.method': request.method } : {}),\n ...(request.url ? { 'url.full': request.url } : {}),\n ...(route ? { 'http.route': route } : {}),\n ...(requestId ? { 'http.request.id': requestId } : {}),\n ...(request.cf?.country ? { 'cloudflare.country': request.cf.country } : {}),\n ...(request.cf?.colo ? { 'cloudflare.colo': request.cf.colo } : {}),\n ...(request.cf?.city ? { 'cloudflare.city': request.cf.city } : {}),\n };\n}\n\nconst baseUseLogger = createUseLogger<CloudflareRequestLike>({\n adapterName: 'cloudflare',\n enrich: enrichFromRequest,\n});\n\nexport function useLogger(\n request?: CloudflareRequestLike,\n requestLoggerOptions?: RequestLoggerOptions,\n): RequestLogger {\n if (request) {\n const existing = requestLoggers.get(request as object);\n if (existing) return existing;\n }\n return baseUseLogger(request, requestLoggerOptions);\n}\n\nexport function withAutotelFetch<\n TEnv,\n TRequest extends CloudflareRequestLike,\n TContext extends CloudflareExecutionContextLike,\n TReturn,\n>(\n handler: (\n request: TRequest,\n env: TEnv,\n ctx: TContext,\n ) => TReturn | Promise<TReturn>,\n options?: CloudflareWithAutotelOptions<TEnv>,\n): (\n request: TRequest,\n env: TEnv,\n ctx: TContext,\n) => Promise<TReturn> {\n return async (\n request: TRequest,\n env: TEnv,\n executionContext: TContext,\n ): Promise<TReturn> => {\n const spanName =\n typeof options?.spanName === 'function'\n ? options.spanName(request, env)\n : (options?.spanName ?? `cloudflare.${request.method ?? 'request'}`);\n\n const wrapped = trace(\n { name: spanName },\n (ctx) => async (\n innerRequest: TRequest,\n innerEnv: TEnv,\n innerExecutionContext: TContext,\n ) => {\n const log = getRequestLogger(ctx, options?.requestLoggerOptions);\n const auto = enrichFromRequest(innerRequest);\n if (auto && Object.keys(auto).length > 0) {\n log.set(auto);\n }\n const custom = options?.enrich?.(\n innerRequest,\n innerEnv,\n innerExecutionContext,\n );\n if (custom && Object.keys(custom).length > 0) {\n log.set(custom);\n }\n\n requestLoggers.set(innerRequest as object, log);\n try {\n return await handler(innerRequest, innerEnv, innerExecutionContext);\n } finally {\n requestLoggers.delete(innerRequest as object);\n }\n },\n );\n\n return await wrapped(request, env, executionContext);\n };\n}\n\nexport function createCloudflareAdapter<TEnv = unknown>(\n options?: CloudflareWithAutotelOptions<TEnv>,\n) {\n return {\n withAutotelFetch: <\n TRequest extends CloudflareRequestLike,\n TContext extends CloudflareExecutionContextLike,\n TReturn,\n >(\n handler: (\n request: TRequest,\n env: TEnv,\n ctx: TContext,\n ) => TReturn | Promise<TReturn>,\n ) => withAutotelFetch(handler, options),\n useLogger,\n parseError: (error: unknown): ParsedError => parseError(error),\n createStructuredError: (\n input: StructuredErrorInput,\n ): StructuredError => createStructuredError(input),\n createDrainPipeline: <T = unknown>(\n drainOptions?: DrainPipelineOptions<T>,\n ): ((batchDrain: (batch: T[]) => void | Promise<void>) => PipelineDrainFn<T>) =>\n createDrainPipeline(drainOptions),\n };\n}\n\nexport const cloudflareToolkit = createAdapterToolkit<CloudflareRequestLike>({\n adapterName: 'cloudflare',\n enrich: enrichFromRequest,\n});\n\nexport { parseError, createDrainPipeline, createStructuredError };\n","import type { Context } from 'hono';\nimport { createUseLogger, createAdapterToolkit } from './core';\n\nexport const useLogger = createUseLogger<Context>({\n adapterName: 'hono',\n enrich: (c) => ({\n 'http.request.method': c.req.method,\n 'url.full': c.req.url,\n 'http.route': c.req.path,\n }),\n});\n\nexport const honoToolkit = createAdapterToolkit<Context>({\n adapterName: 'hono',\n enrich: (c) => ({\n 'http.request.method': c.req.method,\n 'url.full': c.req.url,\n 'http.route': c.req.path,\n }),\n});\n","import { createUseLogger, createAdapterToolkit } from './core';\n\nexport const useLogger = createUseLogger<{\n pathname?: string;\n method?: string;\n}>({\n adapterName: 'tanstack',\n enrich: (ctx) => ({\n ...(ctx.method ? { 'http.request.method': ctx.method } : {}),\n ...(ctx.pathname ? { 'http.route': ctx.pathname } : {}),\n }),\n});\n\nexport const tanstackToolkit = createAdapterToolkit<{\n pathname?: string;\n method?: string;\n}>({\n adapterName: 'tanstack',\n enrich: (ctx) => ({\n ...(ctx.method ? { 'http.request.method': ctx.method } : {}),\n ...(ctx.pathname ? { 'http.route': ctx.pathname } : {}),\n }),\n});\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/core.ts","../src/next.ts","../src/nitro.ts","../src/cloudflare.ts","../src/hono.ts","../src/tanstack.ts"],"names":["useLogger","getRequestLogger","parseError","createStructuredError","createDrainPipeline","AsyncLocalStorage","trace","baseUseLogger","enrichFromRequest"],"mappings":"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","file":"index.cjs","sourcesContent":["import {\n createDrainPipeline,\n createStructuredError,\n getRequestLogger,\n parseError,\n type ParsedError,\n type RequestLogger,\n type RequestLoggerOptions,\n type RequestLogSnapshot,\n type DrainPipelineOptions,\n type PipelineDrainFn,\n type StructuredError,\n type StructuredErrorInput,\n} from 'autotel';\n\nexport interface AdapterUseLoggerOptions<TContext> {\n adapterName: string;\n enrich?: (context: TContext) => Record<string, unknown> | undefined;\n}\n\nexport interface AdapterToolkit<TContext> {\n useLogger: (\n context?: TContext,\n options?: RequestLoggerOptions,\n ) => RequestLogger;\n parseError: (error: unknown) => ParsedError;\n createStructuredError: (input: StructuredErrorInput) => StructuredError;\n createDrainPipeline: <T = unknown>(\n options?: DrainPipelineOptions<T>,\n ) => (drain: (batch: T[]) => void | Promise<void>) => PipelineDrainFn<T>;\n}\n\nexport function createUseLogger<TContext = unknown>(\n options: AdapterUseLoggerOptions<TContext>,\n) {\n return function useLogger(\n context?: TContext,\n requestLoggerOptions?: RequestLoggerOptions,\n ): RequestLogger {\n let logger: RequestLogger;\n try {\n logger = getRequestLogger(undefined, requestLoggerOptions);\n } catch {\n throw new Error(\n `[autotel-adapters/${options.adapterName}] No active trace context. ` +\n `Wrap your handler with autotel trace instrumentation before calling useLogger().`,\n );\n }\n\n if (context && options.enrich) {\n const extra = options.enrich(context);\n if (extra && Object.keys(extra).length > 0) {\n logger.set(extra);\n }\n }\n\n return logger;\n };\n}\n\nexport function createAdapterToolkit<TContext = unknown>(\n options: AdapterUseLoggerOptions<TContext>,\n): AdapterToolkit<TContext> {\n return {\n useLogger: createUseLogger(options),\n parseError,\n createStructuredError,\n createDrainPipeline,\n };\n}\n\n/**\n * Description of a single adapter config field. `env` is the ordered list of\n * environment variables to fall back to.\n */\nexport interface ConfigField<T> {\n key: keyof T & string;\n env?: string[];\n}\n\nfunction resolveEnv(envKeys?: string[]): string | undefined {\n if (!envKeys) return undefined;\n for (const key of envKeys) {\n const value = process.env[key];\n if (value) return value;\n }\n return undefined;\n}\n\n/**\n * Returns true when at least one env-backed field is not provided via\n * `overrides`, meaning runtime config may still contribute and should be\n * probed to preserve precedence (`overrides > runtime > env`).\n *\n * @example\n * ```ts\n * const FIELDS: ConfigField<MyAdapterConfig>[] = [\n * { key: 'token', env: ['MY_ADAPTER_TOKEN'] },\n * { key: 'endpoint', env: ['MY_ADAPTER_URL'] },\n * ]\n *\n * if (shouldProbeRuntime(FIELDS, overrides)) {\n * runtimeConfig = await loadRuntimeConfig()\n * }\n * ```\n */\nexport function shouldProbeRuntime<T>(\n fields: ConfigField<T>[],\n overrides?: Partial<T>,\n): boolean {\n return fields.some(({ key, env }) => {\n if (!env || env.length === 0) return false;\n if (overrides?.[key] !== undefined) return false;\n return true;\n });\n}\n\n/**\n * Resolve adapter configuration with the standard priority chain:\n *\n * 1. `overrides` passed to the adapter factory\n * 2. `runtimeConfig.autotel.{namespace}.{key}` (if a probe was performed)\n * 3. `runtimeConfig.{namespace}.{key}` (if a probe was performed)\n * 4. `process.env[envKey]` for each env in `field.env`\n *\n * Pass an async `probe` to defer the runtime config lookup so it is only\n * invoked when runtime resolution is needed (i.e. at least one env-backed\n * field is not set by overrides). Adapters that have no probe target may pass\n * `() => Promise.resolve(undefined)`.\n */\nexport async function resolveAdapterConfig<T>(\n namespace: string,\n fields: ConfigField<T>[],\n overrides: Partial<T> | undefined,\n probe: () => Promise<Record<string, any> | undefined>,\n): Promise<Partial<T>> {\n const runtimeConfig = shouldProbeRuntime(fields, overrides)\n ? await probe()\n : undefined;\n const autotelNs = runtimeConfig?.autotel?.[namespace];\n const rootNs = runtimeConfig?.[namespace];\n\n const config: Record<string, unknown> = {};\n for (const { key, env } of fields) {\n config[key] =\n overrides?.[key] ??\n autotelNs?.[key] ??\n rootNs?.[key] ??\n resolveEnv(env);\n }\n\n return config as Partial<T>;\n}\n\nexport type HeadersLike =\n | { get(name: string): string | null }\n | Record<string, string | undefined>;\n\nexport function getHeader(\n headers: HeadersLike | undefined,\n name: string,\n): string | undefined {\n if (!headers) return undefined;\n if ('get' in headers && typeof headers.get === 'function') {\n return headers.get(name) ?? undefined;\n }\n const dictionary = headers as Record<string, string | undefined>;\n const value = dictionary[name] ?? dictionary[name.toLowerCase()];\n return typeof value === 'string' ? value : undefined;\n}\n\nexport type {\n RequestLogger,\n RequestLoggerOptions,\n RequestLogSnapshot,\n ParsedError,\n StructuredError,\n StructuredErrorInput,\n DrainPipelineOptions,\n PipelineDrainFn,\n};\n","import { AsyncLocalStorage } from 'node:async_hooks';\nimport {\n createDrainPipeline,\n getRequestLogger,\n parseError,\n trace,\n createStructuredError,\n type RequestLogger,\n type RequestLoggerOptions,\n type ParsedError,\n type DrainPipelineOptions,\n type PipelineDrainFn,\n type StructuredError,\n type StructuredErrorInput,\n} from 'autotel';\nimport { createAdapterToolkit, createUseLogger, getHeader } from './core';\n\nexport interface NextRequestLike {\n method?: string;\n url?: string;\n headers?:\n | { get(name: string): string | null }\n | Record<string, string | undefined>;\n}\n\nexport interface NextWithAutotelOptions {\n spanName?: string | ((request?: NextRequestLike) => string);\n requestLoggerOptions?: RequestLoggerOptions;\n enrich?: (request?: NextRequestLike) => Record<string, unknown> | undefined;\n}\n\nconst nextLoggerStorage = new AsyncLocalStorage<RequestLogger>();\n\nfunction enrichFromRequest(\n request?: NextRequestLike,\n): Record<string, unknown> | undefined {\n if (!request) return undefined;\n\n let route = '/';\n if (request.url) {\n try {\n route = new URL(request.url).pathname;\n } catch {\n route = request.url;\n }\n }\n const requestId = getHeader(request.headers, 'x-request-id');\n\n return {\n ...(request.method ? { 'http.request.method': request.method } : {}),\n ...(request.url ? { 'url.full': request.url } : {}),\n ...(route ? { 'http.route': route } : {}),\n ...(requestId ? { 'http.request.header.x-request-id': requestId } : {}),\n };\n}\n\nconst baseUseLogger = createUseLogger<NextRequestLike>({\n adapterName: 'next',\n enrich: enrichFromRequest,\n});\n\nexport function useLogger(\n request?: NextRequestLike,\n requestLoggerOptions?: RequestLoggerOptions,\n): RequestLogger {\n const logger = nextLoggerStorage.getStore();\n if (logger) return logger;\n return baseUseLogger(request, requestLoggerOptions);\n}\n\nexport function withAutotel<TArgs extends unknown[], TReturn>(\n handler: (...args: TArgs) => TReturn | Promise<TReturn>,\n options?: NextWithAutotelOptions,\n): (...args: TArgs) => Promise<TReturn> {\n return async (...args: TArgs): Promise<TReturn> => {\n const request = args[0] as NextRequestLike | undefined;\n const spanName =\n typeof options?.spanName === 'function'\n ? options.spanName(request)\n : (options?.spanName ?? 'next.request');\n\n const wrapped = trace(\n { name: spanName },\n (ctx) => async (...innerArgs: TArgs) => {\n const innerRequest = innerArgs[0] as NextRequestLike | undefined;\n const log = getRequestLogger(ctx, options?.requestLoggerOptions);\n const auto = enrichFromRequest(innerRequest);\n if (auto && Object.keys(auto).length > 0) {\n log.set(auto);\n }\n const custom = options?.enrich?.(innerRequest);\n if (custom && Object.keys(custom).length > 0) {\n log.set(custom);\n }\n return await nextLoggerStorage.run(log, async () => handler(...innerArgs));\n },\n );\n return await wrapped(...args);\n };\n}\n\nexport function createNextAdapter(options?: NextWithAutotelOptions) {\n return {\n withAutotel: <TArgs extends unknown[], TReturn>(\n handler: (...args: TArgs) => TReturn | Promise<TReturn>,\n ) => withAutotel(handler, options),\n useLogger: (\n request?: NextRequestLike,\n requestLoggerOptions?: RequestLoggerOptions,\n ): RequestLogger => useLogger(request, requestLoggerOptions),\n parseError: (error: unknown): ParsedError => parseError(error),\n createStructuredError: (\n input: StructuredErrorInput,\n ): StructuredError => createStructuredError(input),\n createDrainPipeline: <T = unknown>(\n drainOptions?: DrainPipelineOptions<T>,\n ): ((batchDrain: (batch: T[]) => void | Promise<void>) => PipelineDrainFn<T>) =>\n createDrainPipeline(drainOptions),\n };\n}\n\nexport const nextToolkit = createAdapterToolkit<NextRequestLike>({\n adapterName: 'next',\n enrich: enrichFromRequest,\n});\n\nexport { parseError, createDrainPipeline, createStructuredError };\n","import { AsyncLocalStorage } from 'node:async_hooks';\nimport {\n getRequestLogger,\n trace,\n type RequestLogger,\n type RequestLoggerOptions,\n} from 'autotel';\nimport { createAdapterToolkit, createUseLogger } from './core';\n\nexport interface NitroEventLike {\n method?: string;\n path?: string;\n context?: Record<string, unknown>;\n}\n\nexport interface NitroWithAutotelOptions {\n spanName?: string | ((event: NitroEventLike) => string);\n requestLoggerOptions?: RequestLoggerOptions;\n enrich?: (event: NitroEventLike) => Record<string, unknown> | undefined;\n}\n\nfunction enrichFromEvent(\n event?: NitroEventLike,\n): Record<string, unknown> | undefined {\n if (!event) return undefined;\n\n return {\n ...(event.method ? { 'http.request.method': event.method } : {}),\n ...(event.path ? { 'http.route': event.path } : {}),\n ...(typeof event.context?.requestId === 'string'\n ? { 'http.request.id': event.context.requestId }\n : {}),\n };\n}\n\nconst baseUseLogger = createUseLogger<NitroEventLike>({\n adapterName: 'nitro',\n enrich: enrichFromEvent,\n});\nconst nitroLoggerStorage = new AsyncLocalStorage<RequestLogger>();\n\nexport function useLogger(\n event?: NitroEventLike,\n serviceOrOptions?: string | RequestLoggerOptions,\n): RequestLogger {\n const stored = nitroLoggerStorage.getStore();\n const logger = stored ??\n (\n typeof serviceOrOptions === 'string'\n ? baseUseLogger(event)\n : baseUseLogger(event, serviceOrOptions)\n );\n\n if (typeof serviceOrOptions === 'string' && serviceOrOptions.length > 0) {\n logger.set({ service: serviceOrOptions });\n }\n\n return logger;\n}\n\nexport function withAutotelEventHandler<TEvent extends NitroEventLike, TReturn>(\n handler: (event: TEvent) => TReturn | Promise<TReturn>,\n options?: NitroWithAutotelOptions,\n): (event: TEvent) => Promise<TReturn> {\n return async (event: TEvent): Promise<TReturn> => {\n const spanName =\n typeof options?.spanName === 'function'\n ? options.spanName(event)\n : (options?.spanName ?? `nitro.${event.method ?? 'request'}`);\n\n const wrapped = trace({ name: spanName }, (ctx) => async (innerEvent: TEvent) => {\n const log = getRequestLogger(ctx, options?.requestLoggerOptions);\n const auto = enrichFromEvent(innerEvent);\n if (auto && Object.keys(auto).length > 0) {\n log.set(auto);\n }\n const custom = options?.enrich?.(innerEvent);\n if (custom && Object.keys(custom).length > 0) {\n log.set(custom);\n }\n return await nitroLoggerStorage.run(log, async () => handler(innerEvent));\n });\n\n return await wrapped(event);\n };\n}\n\nexport function createNitroAdapter(options?: NitroWithAutotelOptions) {\n const toolkit = createAdapterToolkit<NitroEventLike>({\n adapterName: 'nitro',\n enrich: (event) => ({\n ...enrichFromEvent(event),\n ...(options?.enrich?.(event) ?? {}),\n }),\n });\n\n return {\n withAutotelEventHandler: <TEvent extends NitroEventLike, TReturn>(\n handler: (event: TEvent) => TReturn | Promise<TReturn>,\n ) => withAutotelEventHandler(handler, options),\n useLogger,\n parseError: toolkit.parseError,\n createStructuredError: toolkit.createStructuredError,\n createDrainPipeline: toolkit.createDrainPipeline,\n };\n}\n\nexport const nitroToolkit = createAdapterToolkit<NitroEventLike>({\n adapterName: 'nitro',\n enrich: enrichFromEvent,\n});\n","import {\n createDrainPipeline,\n createStructuredError,\n getRequestLogger,\n parseError,\n trace,\n type DrainPipelineOptions,\n type ParsedError,\n type PipelineDrainFn,\n type RequestLogger,\n type RequestLoggerOptions,\n type StructuredError,\n type StructuredErrorInput,\n} from 'autotel';\nimport { createAdapterToolkit, createUseLogger, getHeader } from './core';\n\nexport interface CloudflareRequestLike {\n method?: string;\n url?: string;\n headers?:\n | { get(name: string): string | null }\n | Record<string, string | undefined>;\n cf?: Record<string, unknown>;\n}\n\nexport interface CloudflareExecutionContextLike {\n waitUntil?: (promise: Promise<unknown>) => void;\n passThroughOnException?: () => void;\n}\n\nexport interface CloudflareWithAutotelOptions<TEnv = unknown> {\n spanName?: string | ((request: CloudflareRequestLike, env: TEnv) => string);\n requestLoggerOptions?: RequestLoggerOptions;\n enrich?: (\n request: CloudflareRequestLike,\n env: TEnv,\n ctx: CloudflareExecutionContextLike,\n ) => Record<string, unknown> | undefined;\n}\n\nconst requestLoggers = new WeakMap<object, RequestLogger>();\n\nfunction enrichFromRequest(\n request?: CloudflareRequestLike,\n): Record<string, unknown> | undefined {\n if (!request) return undefined;\n\n let route = '/';\n if (request.url) {\n try {\n route = new URL(request.url).pathname;\n } catch {\n route = request.url;\n }\n }\n\n const requestId =\n getHeader(request.headers, 'x-request-id') ??\n getHeader(request.headers, 'cf-ray');\n\n return {\n ...(request.method ? { 'http.request.method': request.method } : {}),\n ...(request.url ? { 'url.full': request.url } : {}),\n ...(route ? { 'http.route': route } : {}),\n ...(requestId ? { 'http.request.id': requestId } : {}),\n ...(request.cf?.country ? { 'cloudflare.country': request.cf.country } : {}),\n ...(request.cf?.colo ? { 'cloudflare.colo': request.cf.colo } : {}),\n ...(request.cf?.city ? { 'cloudflare.city': request.cf.city } : {}),\n };\n}\n\nconst baseUseLogger = createUseLogger<CloudflareRequestLike>({\n adapterName: 'cloudflare',\n enrich: enrichFromRequest,\n});\n\nexport function useLogger(\n request?: CloudflareRequestLike,\n requestLoggerOptions?: RequestLoggerOptions,\n): RequestLogger {\n if (request) {\n const existing = requestLoggers.get(request as object);\n if (existing) return existing;\n }\n return baseUseLogger(request, requestLoggerOptions);\n}\n\nexport function withAutotelFetch<\n TEnv,\n TRequest extends CloudflareRequestLike,\n TContext extends CloudflareExecutionContextLike,\n TReturn,\n>(\n handler: (\n request: TRequest,\n env: TEnv,\n ctx: TContext,\n ) => TReturn | Promise<TReturn>,\n options?: CloudflareWithAutotelOptions<TEnv>,\n): (\n request: TRequest,\n env: TEnv,\n ctx: TContext,\n) => Promise<TReturn> {\n return async (\n request: TRequest,\n env: TEnv,\n executionContext: TContext,\n ): Promise<TReturn> => {\n const spanName =\n typeof options?.spanName === 'function'\n ? options.spanName(request, env)\n : (options?.spanName ?? `cloudflare.${request.method ?? 'request'}`);\n\n const wrapped = trace(\n { name: spanName },\n (ctx) => async (\n innerRequest: TRequest,\n innerEnv: TEnv,\n innerExecutionContext: TContext,\n ) => {\n const log = getRequestLogger(ctx, options?.requestLoggerOptions);\n const auto = enrichFromRequest(innerRequest);\n if (auto && Object.keys(auto).length > 0) {\n log.set(auto);\n }\n const custom = options?.enrich?.(\n innerRequest,\n innerEnv,\n innerExecutionContext,\n );\n if (custom && Object.keys(custom).length > 0) {\n log.set(custom);\n }\n\n requestLoggers.set(innerRequest as object, log);\n try {\n return await handler(innerRequest, innerEnv, innerExecutionContext);\n } finally {\n requestLoggers.delete(innerRequest as object);\n }\n },\n );\n\n return await wrapped(request, env, executionContext);\n };\n}\n\nexport function createCloudflareAdapter<TEnv = unknown>(\n options?: CloudflareWithAutotelOptions<TEnv>,\n) {\n return {\n withAutotelFetch: <\n TRequest extends CloudflareRequestLike,\n TContext extends CloudflareExecutionContextLike,\n TReturn,\n >(\n handler: (\n request: TRequest,\n env: TEnv,\n ctx: TContext,\n ) => TReturn | Promise<TReturn>,\n ) => withAutotelFetch(handler, options),\n useLogger,\n parseError: (error: unknown): ParsedError => parseError(error),\n createStructuredError: (\n input: StructuredErrorInput,\n ): StructuredError => createStructuredError(input),\n createDrainPipeline: <T = unknown>(\n drainOptions?: DrainPipelineOptions<T>,\n ): ((batchDrain: (batch: T[]) => void | Promise<void>) => PipelineDrainFn<T>) =>\n createDrainPipeline(drainOptions),\n };\n}\n\nexport const cloudflareToolkit = createAdapterToolkit<CloudflareRequestLike>({\n adapterName: 'cloudflare',\n enrich: enrichFromRequest,\n});\n\nexport { parseError, createDrainPipeline, createStructuredError };\n","import type { Context } from 'hono';\nimport { createUseLogger, createAdapterToolkit } from './core';\n\nexport const useLogger = createUseLogger<Context>({\n adapterName: 'hono',\n enrich: (c) => ({\n 'http.request.method': c.req.method,\n 'url.full': c.req.url,\n 'http.route': c.req.path,\n }),\n});\n\nexport const honoToolkit = createAdapterToolkit<Context>({\n adapterName: 'hono',\n enrich: (c) => ({\n 'http.request.method': c.req.method,\n 'url.full': c.req.url,\n 'http.route': c.req.path,\n }),\n});\n","import { createUseLogger, createAdapterToolkit } from './core';\n\nexport const useLogger = createUseLogger<{\n pathname?: string;\n method?: string;\n}>({\n adapterName: 'tanstack',\n enrich: (ctx) => ({\n ...(ctx.method ? { 'http.request.method': ctx.method } : {}),\n ...(ctx.pathname ? { 'http.route': ctx.pathname } : {}),\n }),\n});\n\nexport const tanstackToolkit = createAdapterToolkit<{\n pathname?: string;\n method?: string;\n}>({\n adapterName: 'tanstack',\n enrich: (ctx) => ({\n ...(ctx.method ? { 'http.request.method': ctx.method } : {}),\n ...(ctx.pathname ? { 'http.route': ctx.pathname } : {}),\n }),\n});\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { AdapterToolkit, AdapterUseLoggerOptions, HeadersLike, createAdapterToolkit, createUseLogger, getHeader } from './core.cjs';
|
|
1
|
+
export { AdapterToolkit, AdapterUseLoggerOptions, ConfigField, HeadersLike, createAdapterToolkit, createUseLogger, getHeader, resolveAdapterConfig, shouldProbeRuntime } from './core.cjs';
|
|
2
2
|
export { createNextAdapter, withAutotel } from './next.cjs';
|
|
3
3
|
export { createNitroAdapter, withAutotelEventHandler } from './nitro.cjs';
|
|
4
4
|
export { createCloudflareAdapter, withAutotelFetch } from './cloudflare.cjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { AdapterToolkit, AdapterUseLoggerOptions, HeadersLike, createAdapterToolkit, createUseLogger, getHeader } from './core.js';
|
|
1
|
+
export { AdapterToolkit, AdapterUseLoggerOptions, ConfigField, HeadersLike, createAdapterToolkit, createUseLogger, getHeader, resolveAdapterConfig, shouldProbeRuntime } from './core.js';
|
|
2
2
|
export { createNextAdapter, withAutotel } from './next.js';
|
|
3
3
|
export { createNitroAdapter, withAutotelEventHandler } from './nitro.js';
|
|
4
4
|
export { createCloudflareAdapter, withAutotelFetch } from './cloudflare.js';
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export { honoToolkit } from './chunk-
|
|
2
|
-
export { tanstackToolkit } from './chunk-
|
|
3
|
-
export { createNextAdapter, withAutotel } from './chunk-
|
|
4
|
-
export { createNitroAdapter, withAutotelEventHandler } from './chunk-
|
|
5
|
-
export { createCloudflareAdapter, withAutotelFetch } from './chunk-
|
|
6
|
-
export { createAdapterToolkit, createUseLogger, getHeader } from './chunk-
|
|
1
|
+
export { honoToolkit } from './chunk-UUDK5U3L.js';
|
|
2
|
+
export { tanstackToolkit } from './chunk-JC3TNPQD.js';
|
|
3
|
+
export { createNextAdapter, withAutotel } from './chunk-GPWONOFN.js';
|
|
4
|
+
export { createNitroAdapter, withAutotelEventHandler } from './chunk-AD3QBS5J.js';
|
|
5
|
+
export { createCloudflareAdapter, withAutotelFetch } from './chunk-CITNYQ2G.js';
|
|
6
|
+
export { createAdapterToolkit, createUseLogger, getHeader, resolveAdapterConfig, shouldProbeRuntime } from './chunk-GBSB7IX7.js';
|
|
7
7
|
//# sourceMappingURL=index.js.map
|
|
8
8
|
//# sourceMappingURL=index.js.map
|
package/dist/next.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core.ts","../src/next.ts"],"names":["useLogger","getRequestLogger","parseError","createStructuredError","createDrainPipeline","AsyncLocalStorage","trace"],"mappings":"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","file":"next.cjs","sourcesContent":["import {\n createDrainPipeline,\n createStructuredError,\n getRequestLogger,\n parseError,\n type ParsedError,\n type RequestLogger,\n type RequestLoggerOptions,\n type RequestLogSnapshot,\n type DrainPipelineOptions,\n type PipelineDrainFn,\n type StructuredError,\n type StructuredErrorInput,\n} from 'autotel';\n\nexport interface AdapterUseLoggerOptions<TContext> {\n adapterName: string;\n enrich?: (context: TContext) => Record<string, unknown> | undefined;\n}\n\nexport interface AdapterToolkit<TContext> {\n useLogger: (\n context?: TContext,\n options?: RequestLoggerOptions,\n ) => RequestLogger;\n parseError: (error: unknown) => ParsedError;\n createStructuredError: (input: StructuredErrorInput) => StructuredError;\n createDrainPipeline: <T = unknown>(\n options?: DrainPipelineOptions<T>,\n ) => (drain: (batch: T[]) => void | Promise<void>) => PipelineDrainFn<T>;\n}\n\nexport function createUseLogger<TContext = unknown>(\n options: AdapterUseLoggerOptions<TContext>,\n) {\n return function useLogger(\n context?: TContext,\n requestLoggerOptions?: RequestLoggerOptions,\n ): RequestLogger {\n let logger: RequestLogger;\n try {\n logger = getRequestLogger(undefined, requestLoggerOptions);\n } catch {\n throw new Error(\n `[autotel-adapters/${options.adapterName}] No active trace context. ` +\n `Wrap your handler with autotel trace instrumentation before calling useLogger().`,\n );\n }\n\n if (context && options.enrich) {\n const extra = options.enrich(context);\n if (extra && Object.keys(extra).length > 0) {\n logger.set(extra);\n }\n }\n\n return logger;\n };\n}\n\nexport function createAdapterToolkit<TContext = unknown>(\n options: AdapterUseLoggerOptions<TContext>,\n): AdapterToolkit<TContext> {\n return {\n useLogger: createUseLogger(options),\n parseError,\n createStructuredError,\n createDrainPipeline,\n };\n}\n\nexport type HeadersLike =\n | { get(name: string): string | null }\n | Record<string, string | undefined>;\n\nexport function getHeader(\n headers: HeadersLike | undefined,\n name: string,\n): string | undefined {\n if (!headers) return undefined;\n if ('get' in headers && typeof headers.get === 'function') {\n return headers.get(name) ?? undefined;\n }\n const dictionary = headers as Record<string, string | undefined>;\n const value = dictionary[name] ?? dictionary[name.toLowerCase()];\n return typeof value === 'string' ? value : undefined;\n}\n\nexport type {\n RequestLogger,\n RequestLoggerOptions,\n RequestLogSnapshot,\n ParsedError,\n StructuredError,\n StructuredErrorInput,\n DrainPipelineOptions,\n PipelineDrainFn,\n};\n","import { AsyncLocalStorage } from 'node:async_hooks';\nimport {\n createDrainPipeline,\n getRequestLogger,\n parseError,\n trace,\n createStructuredError,\n type RequestLogger,\n type RequestLoggerOptions,\n type ParsedError,\n type DrainPipelineOptions,\n type PipelineDrainFn,\n type StructuredError,\n type StructuredErrorInput,\n} from 'autotel';\nimport { createAdapterToolkit, createUseLogger, getHeader } from './core';\n\nexport interface NextRequestLike {\n method?: string;\n url?: string;\n headers?:\n | { get(name: string): string | null }\n | Record<string, string | undefined>;\n}\n\nexport interface NextWithAutotelOptions {\n spanName?: string | ((request?: NextRequestLike) => string);\n requestLoggerOptions?: RequestLoggerOptions;\n enrich?: (request?: NextRequestLike) => Record<string, unknown> | undefined;\n}\n\nconst nextLoggerStorage = new AsyncLocalStorage<RequestLogger>();\n\nfunction enrichFromRequest(\n request?: NextRequestLike,\n): Record<string, unknown> | undefined {\n if (!request) return undefined;\n\n let route = '/';\n if (request.url) {\n try {\n route = new URL(request.url).pathname;\n } catch {\n route = request.url;\n }\n }\n const requestId = getHeader(request.headers, 'x-request-id');\n\n return {\n ...(request.method ? { 'http.request.method': request.method } : {}),\n ...(request.url ? { 'url.full': request.url } : {}),\n ...(route ? { 'http.route': route } : {}),\n ...(requestId ? { 'http.request.header.x-request-id': requestId } : {}),\n };\n}\n\nconst baseUseLogger = createUseLogger<NextRequestLike>({\n adapterName: 'next',\n enrich: enrichFromRequest,\n});\n\nexport function useLogger(\n request?: NextRequestLike,\n requestLoggerOptions?: RequestLoggerOptions,\n): RequestLogger {\n const logger = nextLoggerStorage.getStore();\n if (logger) return logger;\n return baseUseLogger(request, requestLoggerOptions);\n}\n\nexport function withAutotel<TArgs extends unknown[], TReturn>(\n handler: (...args: TArgs) => TReturn | Promise<TReturn>,\n options?: NextWithAutotelOptions,\n): (...args: TArgs) => Promise<TReturn> {\n return async (...args: TArgs): Promise<TReturn> => {\n const request = args[0] as NextRequestLike | undefined;\n const spanName =\n typeof options?.spanName === 'function'\n ? options.spanName(request)\n : (options?.spanName ?? 'next.request');\n\n const wrapped = trace(\n { name: spanName },\n (ctx) => async (...innerArgs: TArgs) => {\n const innerRequest = innerArgs[0] as NextRequestLike | undefined;\n const log = getRequestLogger(ctx, options?.requestLoggerOptions);\n const auto = enrichFromRequest(innerRequest);\n if (auto && Object.keys(auto).length > 0) {\n log.set(auto);\n }\n const custom = options?.enrich?.(innerRequest);\n if (custom && Object.keys(custom).length > 0) {\n log.set(custom);\n }\n return await nextLoggerStorage.run(log, async () => handler(...innerArgs));\n },\n );\n return await wrapped(...args);\n };\n}\n\nexport function createNextAdapter(options?: NextWithAutotelOptions) {\n return {\n withAutotel: <TArgs extends unknown[], TReturn>(\n handler: (...args: TArgs) => TReturn | Promise<TReturn>,\n ) => withAutotel(handler, options),\n useLogger: (\n request?: NextRequestLike,\n requestLoggerOptions?: RequestLoggerOptions,\n ): RequestLogger => useLogger(request, requestLoggerOptions),\n parseError: (error: unknown): ParsedError => parseError(error),\n createStructuredError: (\n input: StructuredErrorInput,\n ): StructuredError => createStructuredError(input),\n createDrainPipeline: <T = unknown>(\n drainOptions?: DrainPipelineOptions<T>,\n ): ((batchDrain: (batch: T[]) => void | Promise<void>) => PipelineDrainFn<T>) =>\n createDrainPipeline(drainOptions),\n };\n}\n\nexport const nextToolkit = createAdapterToolkit<NextRequestLike>({\n adapterName: 'next',\n enrich: enrichFromRequest,\n});\n\nexport { parseError, createDrainPipeline, createStructuredError };\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/core.ts","../src/next.ts"],"names":["useLogger","getRequestLogger","parseError","createStructuredError","createDrainPipeline","AsyncLocalStorage","trace"],"mappings":"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","file":"next.cjs","sourcesContent":["import {\n createDrainPipeline,\n createStructuredError,\n getRequestLogger,\n parseError,\n type ParsedError,\n type RequestLogger,\n type RequestLoggerOptions,\n type RequestLogSnapshot,\n type DrainPipelineOptions,\n type PipelineDrainFn,\n type StructuredError,\n type StructuredErrorInput,\n} from 'autotel';\n\nexport interface AdapterUseLoggerOptions<TContext> {\n adapterName: string;\n enrich?: (context: TContext) => Record<string, unknown> | undefined;\n}\n\nexport interface AdapterToolkit<TContext> {\n useLogger: (\n context?: TContext,\n options?: RequestLoggerOptions,\n ) => RequestLogger;\n parseError: (error: unknown) => ParsedError;\n createStructuredError: (input: StructuredErrorInput) => StructuredError;\n createDrainPipeline: <T = unknown>(\n options?: DrainPipelineOptions<T>,\n ) => (drain: (batch: T[]) => void | Promise<void>) => PipelineDrainFn<T>;\n}\n\nexport function createUseLogger<TContext = unknown>(\n options: AdapterUseLoggerOptions<TContext>,\n) {\n return function useLogger(\n context?: TContext,\n requestLoggerOptions?: RequestLoggerOptions,\n ): RequestLogger {\n let logger: RequestLogger;\n try {\n logger = getRequestLogger(undefined, requestLoggerOptions);\n } catch {\n throw new Error(\n `[autotel-adapters/${options.adapterName}] No active trace context. ` +\n `Wrap your handler with autotel trace instrumentation before calling useLogger().`,\n );\n }\n\n if (context && options.enrich) {\n const extra = options.enrich(context);\n if (extra && Object.keys(extra).length > 0) {\n logger.set(extra);\n }\n }\n\n return logger;\n };\n}\n\nexport function createAdapterToolkit<TContext = unknown>(\n options: AdapterUseLoggerOptions<TContext>,\n): AdapterToolkit<TContext> {\n return {\n useLogger: createUseLogger(options),\n parseError,\n createStructuredError,\n createDrainPipeline,\n };\n}\n\n/**\n * Description of a single adapter config field. `env` is the ordered list of\n * environment variables to fall back to.\n */\nexport interface ConfigField<T> {\n key: keyof T & string;\n env?: string[];\n}\n\nfunction resolveEnv(envKeys?: string[]): string | undefined {\n if (!envKeys) return undefined;\n for (const key of envKeys) {\n const value = process.env[key];\n if (value) return value;\n }\n return undefined;\n}\n\n/**\n * Returns true when at least one env-backed field is not provided via\n * `overrides`, meaning runtime config may still contribute and should be\n * probed to preserve precedence (`overrides > runtime > env`).\n *\n * @example\n * ```ts\n * const FIELDS: ConfigField<MyAdapterConfig>[] = [\n * { key: 'token', env: ['MY_ADAPTER_TOKEN'] },\n * { key: 'endpoint', env: ['MY_ADAPTER_URL'] },\n * ]\n *\n * if (shouldProbeRuntime(FIELDS, overrides)) {\n * runtimeConfig = await loadRuntimeConfig()\n * }\n * ```\n */\nexport function shouldProbeRuntime<T>(\n fields: ConfigField<T>[],\n overrides?: Partial<T>,\n): boolean {\n return fields.some(({ key, env }) => {\n if (!env || env.length === 0) return false;\n if (overrides?.[key] !== undefined) return false;\n return true;\n });\n}\n\n/**\n * Resolve adapter configuration with the standard priority chain:\n *\n * 1. `overrides` passed to the adapter factory\n * 2. `runtimeConfig.autotel.{namespace}.{key}` (if a probe was performed)\n * 3. `runtimeConfig.{namespace}.{key}` (if a probe was performed)\n * 4. `process.env[envKey]` for each env in `field.env`\n *\n * Pass an async `probe` to defer the runtime config lookup so it is only\n * invoked when runtime resolution is needed (i.e. at least one env-backed\n * field is not set by overrides). Adapters that have no probe target may pass\n * `() => Promise.resolve(undefined)`.\n */\nexport async function resolveAdapterConfig<T>(\n namespace: string,\n fields: ConfigField<T>[],\n overrides: Partial<T> | undefined,\n probe: () => Promise<Record<string, any> | undefined>,\n): Promise<Partial<T>> {\n const runtimeConfig = shouldProbeRuntime(fields, overrides)\n ? await probe()\n : undefined;\n const autotelNs = runtimeConfig?.autotel?.[namespace];\n const rootNs = runtimeConfig?.[namespace];\n\n const config: Record<string, unknown> = {};\n for (const { key, env } of fields) {\n config[key] =\n overrides?.[key] ??\n autotelNs?.[key] ??\n rootNs?.[key] ??\n resolveEnv(env);\n }\n\n return config as Partial<T>;\n}\n\nexport type HeadersLike =\n | { get(name: string): string | null }\n | Record<string, string | undefined>;\n\nexport function getHeader(\n headers: HeadersLike | undefined,\n name: string,\n): string | undefined {\n if (!headers) return undefined;\n if ('get' in headers && typeof headers.get === 'function') {\n return headers.get(name) ?? undefined;\n }\n const dictionary = headers as Record<string, string | undefined>;\n const value = dictionary[name] ?? dictionary[name.toLowerCase()];\n return typeof value === 'string' ? value : undefined;\n}\n\nexport type {\n RequestLogger,\n RequestLoggerOptions,\n RequestLogSnapshot,\n ParsedError,\n StructuredError,\n StructuredErrorInput,\n DrainPipelineOptions,\n PipelineDrainFn,\n};\n","import { AsyncLocalStorage } from 'node:async_hooks';\nimport {\n createDrainPipeline,\n getRequestLogger,\n parseError,\n trace,\n createStructuredError,\n type RequestLogger,\n type RequestLoggerOptions,\n type ParsedError,\n type DrainPipelineOptions,\n type PipelineDrainFn,\n type StructuredError,\n type StructuredErrorInput,\n} from 'autotel';\nimport { createAdapterToolkit, createUseLogger, getHeader } from './core';\n\nexport interface NextRequestLike {\n method?: string;\n url?: string;\n headers?:\n | { get(name: string): string | null }\n | Record<string, string | undefined>;\n}\n\nexport interface NextWithAutotelOptions {\n spanName?: string | ((request?: NextRequestLike) => string);\n requestLoggerOptions?: RequestLoggerOptions;\n enrich?: (request?: NextRequestLike) => Record<string, unknown> | undefined;\n}\n\nconst nextLoggerStorage = new AsyncLocalStorage<RequestLogger>();\n\nfunction enrichFromRequest(\n request?: NextRequestLike,\n): Record<string, unknown> | undefined {\n if (!request) return undefined;\n\n let route = '/';\n if (request.url) {\n try {\n route = new URL(request.url).pathname;\n } catch {\n route = request.url;\n }\n }\n const requestId = getHeader(request.headers, 'x-request-id');\n\n return {\n ...(request.method ? { 'http.request.method': request.method } : {}),\n ...(request.url ? { 'url.full': request.url } : {}),\n ...(route ? { 'http.route': route } : {}),\n ...(requestId ? { 'http.request.header.x-request-id': requestId } : {}),\n };\n}\n\nconst baseUseLogger = createUseLogger<NextRequestLike>({\n adapterName: 'next',\n enrich: enrichFromRequest,\n});\n\nexport function useLogger(\n request?: NextRequestLike,\n requestLoggerOptions?: RequestLoggerOptions,\n): RequestLogger {\n const logger = nextLoggerStorage.getStore();\n if (logger) return logger;\n return baseUseLogger(request, requestLoggerOptions);\n}\n\nexport function withAutotel<TArgs extends unknown[], TReturn>(\n handler: (...args: TArgs) => TReturn | Promise<TReturn>,\n options?: NextWithAutotelOptions,\n): (...args: TArgs) => Promise<TReturn> {\n return async (...args: TArgs): Promise<TReturn> => {\n const request = args[0] as NextRequestLike | undefined;\n const spanName =\n typeof options?.spanName === 'function'\n ? options.spanName(request)\n : (options?.spanName ?? 'next.request');\n\n const wrapped = trace(\n { name: spanName },\n (ctx) => async (...innerArgs: TArgs) => {\n const innerRequest = innerArgs[0] as NextRequestLike | undefined;\n const log = getRequestLogger(ctx, options?.requestLoggerOptions);\n const auto = enrichFromRequest(innerRequest);\n if (auto && Object.keys(auto).length > 0) {\n log.set(auto);\n }\n const custom = options?.enrich?.(innerRequest);\n if (custom && Object.keys(custom).length > 0) {\n log.set(custom);\n }\n return await nextLoggerStorage.run(log, async () => handler(...innerArgs));\n },\n );\n return await wrapped(...args);\n };\n}\n\nexport function createNextAdapter(options?: NextWithAutotelOptions) {\n return {\n withAutotel: <TArgs extends unknown[], TReturn>(\n handler: (...args: TArgs) => TReturn | Promise<TReturn>,\n ) => withAutotel(handler, options),\n useLogger: (\n request?: NextRequestLike,\n requestLoggerOptions?: RequestLoggerOptions,\n ): RequestLogger => useLogger(request, requestLoggerOptions),\n parseError: (error: unknown): ParsedError => parseError(error),\n createStructuredError: (\n input: StructuredErrorInput,\n ): StructuredError => createStructuredError(input),\n createDrainPipeline: <T = unknown>(\n drainOptions?: DrainPipelineOptions<T>,\n ): ((batchDrain: (batch: T[]) => void | Promise<void>) => PipelineDrainFn<T>) =>\n createDrainPipeline(drainOptions),\n };\n}\n\nexport const nextToolkit = createAdapterToolkit<NextRequestLike>({\n adapterName: 'next',\n enrich: enrichFromRequest,\n});\n\nexport { parseError, createDrainPipeline, createStructuredError };\n"]}
|
package/dist/next.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { createDrainPipeline, createNextAdapter, createStructuredError, nextToolkit, parseError, useLogger, withAutotel } from './chunk-
|
|
2
|
-
import './chunk-
|
|
1
|
+
export { createDrainPipeline, createNextAdapter, createStructuredError, nextToolkit, parseError, useLogger, withAutotel } from './chunk-GPWONOFN.js';
|
|
2
|
+
import './chunk-GBSB7IX7.js';
|
|
3
3
|
//# sourceMappingURL=next.js.map
|
|
4
4
|
//# sourceMappingURL=next.js.map
|
package/dist/nitro.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core.ts","../src/nitro.ts"],"names":["useLogger","getRequestLogger","parseError","createStructuredError","createDrainPipeline","AsyncLocalStorage","trace"],"mappings":"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","file":"nitro.cjs","sourcesContent":["import {\n createDrainPipeline,\n createStructuredError,\n getRequestLogger,\n parseError,\n type ParsedError,\n type RequestLogger,\n type RequestLoggerOptions,\n type RequestLogSnapshot,\n type DrainPipelineOptions,\n type PipelineDrainFn,\n type StructuredError,\n type StructuredErrorInput,\n} from 'autotel';\n\nexport interface AdapterUseLoggerOptions<TContext> {\n adapterName: string;\n enrich?: (context: TContext) => Record<string, unknown> | undefined;\n}\n\nexport interface AdapterToolkit<TContext> {\n useLogger: (\n context?: TContext,\n options?: RequestLoggerOptions,\n ) => RequestLogger;\n parseError: (error: unknown) => ParsedError;\n createStructuredError: (input: StructuredErrorInput) => StructuredError;\n createDrainPipeline: <T = unknown>(\n options?: DrainPipelineOptions<T>,\n ) => (drain: (batch: T[]) => void | Promise<void>) => PipelineDrainFn<T>;\n}\n\nexport function createUseLogger<TContext = unknown>(\n options: AdapterUseLoggerOptions<TContext>,\n) {\n return function useLogger(\n context?: TContext,\n requestLoggerOptions?: RequestLoggerOptions,\n ): RequestLogger {\n let logger: RequestLogger;\n try {\n logger = getRequestLogger(undefined, requestLoggerOptions);\n } catch {\n throw new Error(\n `[autotel-adapters/${options.adapterName}] No active trace context. ` +\n `Wrap your handler with autotel trace instrumentation before calling useLogger().`,\n );\n }\n\n if (context && options.enrich) {\n const extra = options.enrich(context);\n if (extra && Object.keys(extra).length > 0) {\n logger.set(extra);\n }\n }\n\n return logger;\n };\n}\n\nexport function createAdapterToolkit<TContext = unknown>(\n options: AdapterUseLoggerOptions<TContext>,\n): AdapterToolkit<TContext> {\n return {\n useLogger: createUseLogger(options),\n parseError,\n createStructuredError,\n createDrainPipeline,\n };\n}\n\nexport type HeadersLike =\n | { get(name: string): string | null }\n | Record<string, string | undefined>;\n\nexport function getHeader(\n headers: HeadersLike | undefined,\n name: string,\n): string | undefined {\n if (!headers) return undefined;\n if ('get' in headers && typeof headers.get === 'function') {\n return headers.get(name) ?? undefined;\n }\n const dictionary = headers as Record<string, string | undefined>;\n const value = dictionary[name] ?? dictionary[name.toLowerCase()];\n return typeof value === 'string' ? value : undefined;\n}\n\nexport type {\n RequestLogger,\n RequestLoggerOptions,\n RequestLogSnapshot,\n ParsedError,\n StructuredError,\n StructuredErrorInput,\n DrainPipelineOptions,\n PipelineDrainFn,\n};\n","import { AsyncLocalStorage } from 'node:async_hooks';\nimport {\n getRequestLogger,\n trace,\n type RequestLogger,\n type RequestLoggerOptions,\n} from 'autotel';\nimport { createAdapterToolkit, createUseLogger } from './core';\n\nexport interface NitroEventLike {\n method?: string;\n path?: string;\n context?: Record<string, unknown>;\n}\n\nexport interface NitroWithAutotelOptions {\n spanName?: string | ((event: NitroEventLike) => string);\n requestLoggerOptions?: RequestLoggerOptions;\n enrich?: (event: NitroEventLike) => Record<string, unknown> | undefined;\n}\n\nfunction enrichFromEvent(\n event?: NitroEventLike,\n): Record<string, unknown> | undefined {\n if (!event) return undefined;\n\n return {\n ...(event.method ? { 'http.request.method': event.method } : {}),\n ...(event.path ? { 'http.route': event.path } : {}),\n ...(typeof event.context?.requestId === 'string'\n ? { 'http.request.id': event.context.requestId }\n : {}),\n };\n}\n\nconst baseUseLogger = createUseLogger<NitroEventLike>({\n adapterName: 'nitro',\n enrich: enrichFromEvent,\n});\nconst nitroLoggerStorage = new AsyncLocalStorage<RequestLogger>();\n\nexport function useLogger(\n event?: NitroEventLike,\n serviceOrOptions?: string | RequestLoggerOptions,\n): RequestLogger {\n const stored = nitroLoggerStorage.getStore();\n const logger = stored ??\n (\n typeof serviceOrOptions === 'string'\n ? baseUseLogger(event)\n : baseUseLogger(event, serviceOrOptions)\n );\n\n if (typeof serviceOrOptions === 'string' && serviceOrOptions.length > 0) {\n logger.set({ service: serviceOrOptions });\n }\n\n return logger;\n}\n\nexport function withAutotelEventHandler<TEvent extends NitroEventLike, TReturn>(\n handler: (event: TEvent) => TReturn | Promise<TReturn>,\n options?: NitroWithAutotelOptions,\n): (event: TEvent) => Promise<TReturn> {\n return async (event: TEvent): Promise<TReturn> => {\n const spanName =\n typeof options?.spanName === 'function'\n ? options.spanName(event)\n : (options?.spanName ?? `nitro.${event.method ?? 'request'}`);\n\n const wrapped = trace({ name: spanName }, (ctx) => async (innerEvent: TEvent) => {\n const log = getRequestLogger(ctx, options?.requestLoggerOptions);\n const auto = enrichFromEvent(innerEvent);\n if (auto && Object.keys(auto).length > 0) {\n log.set(auto);\n }\n const custom = options?.enrich?.(innerEvent);\n if (custom && Object.keys(custom).length > 0) {\n log.set(custom);\n }\n return await nitroLoggerStorage.run(log, async () => handler(innerEvent));\n });\n\n return await wrapped(event);\n };\n}\n\nexport function createNitroAdapter(options?: NitroWithAutotelOptions) {\n const toolkit = createAdapterToolkit<NitroEventLike>({\n adapterName: 'nitro',\n enrich: (event) => ({\n ...enrichFromEvent(event),\n ...(options?.enrich?.(event) ?? {}),\n }),\n });\n\n return {\n withAutotelEventHandler: <TEvent extends NitroEventLike, TReturn>(\n handler: (event: TEvent) => TReturn | Promise<TReturn>,\n ) => withAutotelEventHandler(handler, options),\n useLogger,\n parseError: toolkit.parseError,\n createStructuredError: toolkit.createStructuredError,\n createDrainPipeline: toolkit.createDrainPipeline,\n };\n}\n\nexport const nitroToolkit = createAdapterToolkit<NitroEventLike>({\n adapterName: 'nitro',\n enrich: enrichFromEvent,\n});\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/core.ts","../src/nitro.ts"],"names":["useLogger","getRequestLogger","parseError","createStructuredError","createDrainPipeline","AsyncLocalStorage","trace"],"mappings":"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","file":"nitro.cjs","sourcesContent":["import {\n createDrainPipeline,\n createStructuredError,\n getRequestLogger,\n parseError,\n type ParsedError,\n type RequestLogger,\n type RequestLoggerOptions,\n type RequestLogSnapshot,\n type DrainPipelineOptions,\n type PipelineDrainFn,\n type StructuredError,\n type StructuredErrorInput,\n} from 'autotel';\n\nexport interface AdapterUseLoggerOptions<TContext> {\n adapterName: string;\n enrich?: (context: TContext) => Record<string, unknown> | undefined;\n}\n\nexport interface AdapterToolkit<TContext> {\n useLogger: (\n context?: TContext,\n options?: RequestLoggerOptions,\n ) => RequestLogger;\n parseError: (error: unknown) => ParsedError;\n createStructuredError: (input: StructuredErrorInput) => StructuredError;\n createDrainPipeline: <T = unknown>(\n options?: DrainPipelineOptions<T>,\n ) => (drain: (batch: T[]) => void | Promise<void>) => PipelineDrainFn<T>;\n}\n\nexport function createUseLogger<TContext = unknown>(\n options: AdapterUseLoggerOptions<TContext>,\n) {\n return function useLogger(\n context?: TContext,\n requestLoggerOptions?: RequestLoggerOptions,\n ): RequestLogger {\n let logger: RequestLogger;\n try {\n logger = getRequestLogger(undefined, requestLoggerOptions);\n } catch {\n throw new Error(\n `[autotel-adapters/${options.adapterName}] No active trace context. ` +\n `Wrap your handler with autotel trace instrumentation before calling useLogger().`,\n );\n }\n\n if (context && options.enrich) {\n const extra = options.enrich(context);\n if (extra && Object.keys(extra).length > 0) {\n logger.set(extra);\n }\n }\n\n return logger;\n };\n}\n\nexport function createAdapterToolkit<TContext = unknown>(\n options: AdapterUseLoggerOptions<TContext>,\n): AdapterToolkit<TContext> {\n return {\n useLogger: createUseLogger(options),\n parseError,\n createStructuredError,\n createDrainPipeline,\n };\n}\n\n/**\n * Description of a single adapter config field. `env` is the ordered list of\n * environment variables to fall back to.\n */\nexport interface ConfigField<T> {\n key: keyof T & string;\n env?: string[];\n}\n\nfunction resolveEnv(envKeys?: string[]): string | undefined {\n if (!envKeys) return undefined;\n for (const key of envKeys) {\n const value = process.env[key];\n if (value) return value;\n }\n return undefined;\n}\n\n/**\n * Returns true when at least one env-backed field is not provided via\n * `overrides`, meaning runtime config may still contribute and should be\n * probed to preserve precedence (`overrides > runtime > env`).\n *\n * @example\n * ```ts\n * const FIELDS: ConfigField<MyAdapterConfig>[] = [\n * { key: 'token', env: ['MY_ADAPTER_TOKEN'] },\n * { key: 'endpoint', env: ['MY_ADAPTER_URL'] },\n * ]\n *\n * if (shouldProbeRuntime(FIELDS, overrides)) {\n * runtimeConfig = await loadRuntimeConfig()\n * }\n * ```\n */\nexport function shouldProbeRuntime<T>(\n fields: ConfigField<T>[],\n overrides?: Partial<T>,\n): boolean {\n return fields.some(({ key, env }) => {\n if (!env || env.length === 0) return false;\n if (overrides?.[key] !== undefined) return false;\n return true;\n });\n}\n\n/**\n * Resolve adapter configuration with the standard priority chain:\n *\n * 1. `overrides` passed to the adapter factory\n * 2. `runtimeConfig.autotel.{namespace}.{key}` (if a probe was performed)\n * 3. `runtimeConfig.{namespace}.{key}` (if a probe was performed)\n * 4. `process.env[envKey]` for each env in `field.env`\n *\n * Pass an async `probe` to defer the runtime config lookup so it is only\n * invoked when runtime resolution is needed (i.e. at least one env-backed\n * field is not set by overrides). Adapters that have no probe target may pass\n * `() => Promise.resolve(undefined)`.\n */\nexport async function resolveAdapterConfig<T>(\n namespace: string,\n fields: ConfigField<T>[],\n overrides: Partial<T> | undefined,\n probe: () => Promise<Record<string, any> | undefined>,\n): Promise<Partial<T>> {\n const runtimeConfig = shouldProbeRuntime(fields, overrides)\n ? await probe()\n : undefined;\n const autotelNs = runtimeConfig?.autotel?.[namespace];\n const rootNs = runtimeConfig?.[namespace];\n\n const config: Record<string, unknown> = {};\n for (const { key, env } of fields) {\n config[key] =\n overrides?.[key] ??\n autotelNs?.[key] ??\n rootNs?.[key] ??\n resolveEnv(env);\n }\n\n return config as Partial<T>;\n}\n\nexport type HeadersLike =\n | { get(name: string): string | null }\n | Record<string, string | undefined>;\n\nexport function getHeader(\n headers: HeadersLike | undefined,\n name: string,\n): string | undefined {\n if (!headers) return undefined;\n if ('get' in headers && typeof headers.get === 'function') {\n return headers.get(name) ?? undefined;\n }\n const dictionary = headers as Record<string, string | undefined>;\n const value = dictionary[name] ?? dictionary[name.toLowerCase()];\n return typeof value === 'string' ? value : undefined;\n}\n\nexport type {\n RequestLogger,\n RequestLoggerOptions,\n RequestLogSnapshot,\n ParsedError,\n StructuredError,\n StructuredErrorInput,\n DrainPipelineOptions,\n PipelineDrainFn,\n};\n","import { AsyncLocalStorage } from 'node:async_hooks';\nimport {\n getRequestLogger,\n trace,\n type RequestLogger,\n type RequestLoggerOptions,\n} from 'autotel';\nimport { createAdapterToolkit, createUseLogger } from './core';\n\nexport interface NitroEventLike {\n method?: string;\n path?: string;\n context?: Record<string, unknown>;\n}\n\nexport interface NitroWithAutotelOptions {\n spanName?: string | ((event: NitroEventLike) => string);\n requestLoggerOptions?: RequestLoggerOptions;\n enrich?: (event: NitroEventLike) => Record<string, unknown> | undefined;\n}\n\nfunction enrichFromEvent(\n event?: NitroEventLike,\n): Record<string, unknown> | undefined {\n if (!event) return undefined;\n\n return {\n ...(event.method ? { 'http.request.method': event.method } : {}),\n ...(event.path ? { 'http.route': event.path } : {}),\n ...(typeof event.context?.requestId === 'string'\n ? { 'http.request.id': event.context.requestId }\n : {}),\n };\n}\n\nconst baseUseLogger = createUseLogger<NitroEventLike>({\n adapterName: 'nitro',\n enrich: enrichFromEvent,\n});\nconst nitroLoggerStorage = new AsyncLocalStorage<RequestLogger>();\n\nexport function useLogger(\n event?: NitroEventLike,\n serviceOrOptions?: string | RequestLoggerOptions,\n): RequestLogger {\n const stored = nitroLoggerStorage.getStore();\n const logger = stored ??\n (\n typeof serviceOrOptions === 'string'\n ? baseUseLogger(event)\n : baseUseLogger(event, serviceOrOptions)\n );\n\n if (typeof serviceOrOptions === 'string' && serviceOrOptions.length > 0) {\n logger.set({ service: serviceOrOptions });\n }\n\n return logger;\n}\n\nexport function withAutotelEventHandler<TEvent extends NitroEventLike, TReturn>(\n handler: (event: TEvent) => TReturn | Promise<TReturn>,\n options?: NitroWithAutotelOptions,\n): (event: TEvent) => Promise<TReturn> {\n return async (event: TEvent): Promise<TReturn> => {\n const spanName =\n typeof options?.spanName === 'function'\n ? options.spanName(event)\n : (options?.spanName ?? `nitro.${event.method ?? 'request'}`);\n\n const wrapped = trace({ name: spanName }, (ctx) => async (innerEvent: TEvent) => {\n const log = getRequestLogger(ctx, options?.requestLoggerOptions);\n const auto = enrichFromEvent(innerEvent);\n if (auto && Object.keys(auto).length > 0) {\n log.set(auto);\n }\n const custom = options?.enrich?.(innerEvent);\n if (custom && Object.keys(custom).length > 0) {\n log.set(custom);\n }\n return await nitroLoggerStorage.run(log, async () => handler(innerEvent));\n });\n\n return await wrapped(event);\n };\n}\n\nexport function createNitroAdapter(options?: NitroWithAutotelOptions) {\n const toolkit = createAdapterToolkit<NitroEventLike>({\n adapterName: 'nitro',\n enrich: (event) => ({\n ...enrichFromEvent(event),\n ...(options?.enrich?.(event) ?? {}),\n }),\n });\n\n return {\n withAutotelEventHandler: <TEvent extends NitroEventLike, TReturn>(\n handler: (event: TEvent) => TReturn | Promise<TReturn>,\n ) => withAutotelEventHandler(handler, options),\n useLogger,\n parseError: toolkit.parseError,\n createStructuredError: toolkit.createStructuredError,\n createDrainPipeline: toolkit.createDrainPipeline,\n };\n}\n\nexport const nitroToolkit = createAdapterToolkit<NitroEventLike>({\n adapterName: 'nitro',\n enrich: enrichFromEvent,\n});\n"]}
|
package/dist/nitro.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { createNitroAdapter, nitroToolkit, useLogger, withAutotelEventHandler } from './chunk-
|
|
2
|
-
import './chunk-
|
|
1
|
+
export { createNitroAdapter, nitroToolkit, useLogger, withAutotelEventHandler } from './chunk-AD3QBS5J.js';
|
|
2
|
+
import './chunk-GBSB7IX7.js';
|
|
3
3
|
//# sourceMappingURL=nitro.js.map
|
|
4
4
|
//# sourceMappingURL=nitro.js.map
|
package/dist/tanstack.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core.ts","../src/tanstack.ts"],"names":["useLogger","getRequestLogger","parseError","createStructuredError","createDrainPipeline"],"mappings":";;;;;AAgCO,SAAS,gBACd,OAAA,EACA;AACA,EAAA,OAAO,SAASA,UAAAA,CACd,OAAA,EACA,oBAAA,EACe;AACf,IAAA,IAAI,MAAA;AACJ,IAAA,IAAI;AACF,MAAA,MAAA,GAASC,wBAAA,CAAiB,QAAW,oBAAoB,CAAA;AAAA,IAC3D,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,kBAAA,EAAqB,QAAQ,WAAW,CAAA,2GAAA;AAAA,OAE1C;AAAA,IACF;AAEA,IAAA,IAAI,OAAA,IAAW,QAAQ,MAAA,EAAQ;AAC7B,MAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,MAAA,CAAO,OAAO,CAAA;AACpC,MAAA,IAAI,SAAS,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA,CAAE,SAAS,CAAA,EAAG;AAC1C,QAAA,MAAA,CAAO,IAAI,KAAK,CAAA;AAAA,MAClB;AAAA,IACF;AAEA,IAAA,OAAO,MAAA;AAAA,EACT,CAAA;AACF;AAEO,SAAS,qBACd,OAAA,EAC0B;AAC1B,EAAA,OAAO;AAAA,IACL,SAAA,EAAW,gBAAgB,OAAO,CAAA;AAAA,gBAClCC,kBAAA;AAAA,2BACAC,6BAAA;AAAA,yBACAC;AAAA,GACF;AACF;;;ACnEO,IAAM,YAAY,eAAA,CAGtB;AAAA,EACD,WAAA,EAAa,UAAA;AAAA,EACb,MAAA,EAAQ,CAAC,GAAA,MAAS;AAAA,IAChB,GAAI,IAAI,MAAA,GAAS,EAAE,uBAAuB,GAAA,CAAI,MAAA,KAAW,EAAC;AAAA,IAC1D,GAAI,IAAI,QAAA,GAAW,EAAE,cAAc,GAAA,CAAI,QAAA,KAAa;AAAC,GACvD;AACF,CAAC;AAEM,IAAM,kBAAkB,oBAAA,CAG5B;AAAA,EACD,WAAA,EAAa,UAAA;AAAA,EACb,MAAA,EAAQ,CAAC,GAAA,MAAS;AAAA,IAChB,GAAI,IAAI,MAAA,GAAS,EAAE,uBAAuB,GAAA,CAAI,MAAA,KAAW,EAAC;AAAA,IAC1D,GAAI,IAAI,QAAA,GAAW,EAAE,cAAc,GAAA,CAAI,QAAA,KAAa;AAAC,GACvD;AACF,CAAC","file":"tanstack.cjs","sourcesContent":["import {\n createDrainPipeline,\n createStructuredError,\n getRequestLogger,\n parseError,\n type ParsedError,\n type RequestLogger,\n type RequestLoggerOptions,\n type RequestLogSnapshot,\n type DrainPipelineOptions,\n type PipelineDrainFn,\n type StructuredError,\n type StructuredErrorInput,\n} from 'autotel';\n\nexport interface AdapterUseLoggerOptions<TContext> {\n adapterName: string;\n enrich?: (context: TContext) => Record<string, unknown> | undefined;\n}\n\nexport interface AdapterToolkit<TContext> {\n useLogger: (\n context?: TContext,\n options?: RequestLoggerOptions,\n ) => RequestLogger;\n parseError: (error: unknown) => ParsedError;\n createStructuredError: (input: StructuredErrorInput) => StructuredError;\n createDrainPipeline: <T = unknown>(\n options?: DrainPipelineOptions<T>,\n ) => (drain: (batch: T[]) => void | Promise<void>) => PipelineDrainFn<T>;\n}\n\nexport function createUseLogger<TContext = unknown>(\n options: AdapterUseLoggerOptions<TContext>,\n) {\n return function useLogger(\n context?: TContext,\n requestLoggerOptions?: RequestLoggerOptions,\n ): RequestLogger {\n let logger: RequestLogger;\n try {\n logger = getRequestLogger(undefined, requestLoggerOptions);\n } catch {\n throw new Error(\n `[autotel-adapters/${options.adapterName}] No active trace context. ` +\n `Wrap your handler with autotel trace instrumentation before calling useLogger().`,\n );\n }\n\n if (context && options.enrich) {\n const extra = options.enrich(context);\n if (extra && Object.keys(extra).length > 0) {\n logger.set(extra);\n }\n }\n\n return logger;\n };\n}\n\nexport function createAdapterToolkit<TContext = unknown>(\n options: AdapterUseLoggerOptions<TContext>,\n): AdapterToolkit<TContext> {\n return {\n useLogger: createUseLogger(options),\n parseError,\n createStructuredError,\n createDrainPipeline,\n };\n}\n\nexport type HeadersLike =\n | { get(name: string): string | null }\n | Record<string, string | undefined>;\n\nexport function getHeader(\n headers: HeadersLike | undefined,\n name: string,\n): string | undefined {\n if (!headers) return undefined;\n if ('get' in headers && typeof headers.get === 'function') {\n return headers.get(name) ?? undefined;\n }\n const dictionary = headers as Record<string, string | undefined>;\n const value = dictionary[name] ?? dictionary[name.toLowerCase()];\n return typeof value === 'string' ? value : undefined;\n}\n\nexport type {\n RequestLogger,\n RequestLoggerOptions,\n RequestLogSnapshot,\n ParsedError,\n StructuredError,\n StructuredErrorInput,\n DrainPipelineOptions,\n PipelineDrainFn,\n};\n","import { createUseLogger, createAdapterToolkit } from './core';\n\nexport const useLogger = createUseLogger<{\n pathname?: string;\n method?: string;\n}>({\n adapterName: 'tanstack',\n enrich: (ctx) => ({\n ...(ctx.method ? { 'http.request.method': ctx.method } : {}),\n ...(ctx.pathname ? { 'http.route': ctx.pathname } : {}),\n }),\n});\n\nexport const tanstackToolkit = createAdapterToolkit<{\n pathname?: string;\n method?: string;\n}>({\n adapterName: 'tanstack',\n enrich: (ctx) => ({\n ...(ctx.method ? { 'http.request.method': ctx.method } : {}),\n ...(ctx.pathname ? { 'http.route': ctx.pathname } : {}),\n }),\n});\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/core.ts","../src/tanstack.ts"],"names":["useLogger","getRequestLogger","parseError","createStructuredError","createDrainPipeline"],"mappings":";;;;;AAgCO,SAAS,gBACd,OAAA,EACA;AACA,EAAA,OAAO,SAASA,UAAAA,CACd,OAAA,EACA,oBAAA,EACe;AACf,IAAA,IAAI,MAAA;AACJ,IAAA,IAAI;AACF,MAAA,MAAA,GAASC,wBAAA,CAAiB,QAAW,oBAAoB,CAAA;AAAA,IAC3D,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,kBAAA,EAAqB,QAAQ,WAAW,CAAA,2GAAA;AAAA,OAE1C;AAAA,IACF;AAEA,IAAA,IAAI,OAAA,IAAW,QAAQ,MAAA,EAAQ;AAC7B,MAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,MAAA,CAAO,OAAO,CAAA;AACpC,MAAA,IAAI,SAAS,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA,CAAE,SAAS,CAAA,EAAG;AAC1C,QAAA,MAAA,CAAO,IAAI,KAAK,CAAA;AAAA,MAClB;AAAA,IACF;AAEA,IAAA,OAAO,MAAA;AAAA,EACT,CAAA;AACF;AAEO,SAAS,qBACd,OAAA,EAC0B;AAC1B,EAAA,OAAO;AAAA,IACL,SAAA,EAAW,gBAAgB,OAAO,CAAA;AAAA,gBAClCC,kBAAA;AAAA,2BACAC,6BAAA;AAAA,yBACAC;AAAA,GACF;AACF;;;ACnEO,IAAM,YAAY,eAAA,CAGtB;AAAA,EACD,WAAA,EAAa,UAAA;AAAA,EACb,MAAA,EAAQ,CAAC,GAAA,MAAS;AAAA,IAChB,GAAI,IAAI,MAAA,GAAS,EAAE,uBAAuB,GAAA,CAAI,MAAA,KAAW,EAAC;AAAA,IAC1D,GAAI,IAAI,QAAA,GAAW,EAAE,cAAc,GAAA,CAAI,QAAA,KAAa;AAAC,GACvD;AACF,CAAC;AAEM,IAAM,kBAAkB,oBAAA,CAG5B;AAAA,EACD,WAAA,EAAa,UAAA;AAAA,EACb,MAAA,EAAQ,CAAC,GAAA,MAAS;AAAA,IAChB,GAAI,IAAI,MAAA,GAAS,EAAE,uBAAuB,GAAA,CAAI,MAAA,KAAW,EAAC;AAAA,IAC1D,GAAI,IAAI,QAAA,GAAW,EAAE,cAAc,GAAA,CAAI,QAAA,KAAa;AAAC,GACvD;AACF,CAAC","file":"tanstack.cjs","sourcesContent":["import {\n createDrainPipeline,\n createStructuredError,\n getRequestLogger,\n parseError,\n type ParsedError,\n type RequestLogger,\n type RequestLoggerOptions,\n type RequestLogSnapshot,\n type DrainPipelineOptions,\n type PipelineDrainFn,\n type StructuredError,\n type StructuredErrorInput,\n} from 'autotel';\n\nexport interface AdapterUseLoggerOptions<TContext> {\n adapterName: string;\n enrich?: (context: TContext) => Record<string, unknown> | undefined;\n}\n\nexport interface AdapterToolkit<TContext> {\n useLogger: (\n context?: TContext,\n options?: RequestLoggerOptions,\n ) => RequestLogger;\n parseError: (error: unknown) => ParsedError;\n createStructuredError: (input: StructuredErrorInput) => StructuredError;\n createDrainPipeline: <T = unknown>(\n options?: DrainPipelineOptions<T>,\n ) => (drain: (batch: T[]) => void | Promise<void>) => PipelineDrainFn<T>;\n}\n\nexport function createUseLogger<TContext = unknown>(\n options: AdapterUseLoggerOptions<TContext>,\n) {\n return function useLogger(\n context?: TContext,\n requestLoggerOptions?: RequestLoggerOptions,\n ): RequestLogger {\n let logger: RequestLogger;\n try {\n logger = getRequestLogger(undefined, requestLoggerOptions);\n } catch {\n throw new Error(\n `[autotel-adapters/${options.adapterName}] No active trace context. ` +\n `Wrap your handler with autotel trace instrumentation before calling useLogger().`,\n );\n }\n\n if (context && options.enrich) {\n const extra = options.enrich(context);\n if (extra && Object.keys(extra).length > 0) {\n logger.set(extra);\n }\n }\n\n return logger;\n };\n}\n\nexport function createAdapterToolkit<TContext = unknown>(\n options: AdapterUseLoggerOptions<TContext>,\n): AdapterToolkit<TContext> {\n return {\n useLogger: createUseLogger(options),\n parseError,\n createStructuredError,\n createDrainPipeline,\n };\n}\n\n/**\n * Description of a single adapter config field. `env` is the ordered list of\n * environment variables to fall back to.\n */\nexport interface ConfigField<T> {\n key: keyof T & string;\n env?: string[];\n}\n\nfunction resolveEnv(envKeys?: string[]): string | undefined {\n if (!envKeys) return undefined;\n for (const key of envKeys) {\n const value = process.env[key];\n if (value) return value;\n }\n return undefined;\n}\n\n/**\n * Returns true when at least one env-backed field is not provided via\n * `overrides`, meaning runtime config may still contribute and should be\n * probed to preserve precedence (`overrides > runtime > env`).\n *\n * @example\n * ```ts\n * const FIELDS: ConfigField<MyAdapterConfig>[] = [\n * { key: 'token', env: ['MY_ADAPTER_TOKEN'] },\n * { key: 'endpoint', env: ['MY_ADAPTER_URL'] },\n * ]\n *\n * if (shouldProbeRuntime(FIELDS, overrides)) {\n * runtimeConfig = await loadRuntimeConfig()\n * }\n * ```\n */\nexport function shouldProbeRuntime<T>(\n fields: ConfigField<T>[],\n overrides?: Partial<T>,\n): boolean {\n return fields.some(({ key, env }) => {\n if (!env || env.length === 0) return false;\n if (overrides?.[key] !== undefined) return false;\n return true;\n });\n}\n\n/**\n * Resolve adapter configuration with the standard priority chain:\n *\n * 1. `overrides` passed to the adapter factory\n * 2. `runtimeConfig.autotel.{namespace}.{key}` (if a probe was performed)\n * 3. `runtimeConfig.{namespace}.{key}` (if a probe was performed)\n * 4. `process.env[envKey]` for each env in `field.env`\n *\n * Pass an async `probe` to defer the runtime config lookup so it is only\n * invoked when runtime resolution is needed (i.e. at least one env-backed\n * field is not set by overrides). Adapters that have no probe target may pass\n * `() => Promise.resolve(undefined)`.\n */\nexport async function resolveAdapterConfig<T>(\n namespace: string,\n fields: ConfigField<T>[],\n overrides: Partial<T> | undefined,\n probe: () => Promise<Record<string, any> | undefined>,\n): Promise<Partial<T>> {\n const runtimeConfig = shouldProbeRuntime(fields, overrides)\n ? await probe()\n : undefined;\n const autotelNs = runtimeConfig?.autotel?.[namespace];\n const rootNs = runtimeConfig?.[namespace];\n\n const config: Record<string, unknown> = {};\n for (const { key, env } of fields) {\n config[key] =\n overrides?.[key] ??\n autotelNs?.[key] ??\n rootNs?.[key] ??\n resolveEnv(env);\n }\n\n return config as Partial<T>;\n}\n\nexport type HeadersLike =\n | { get(name: string): string | null }\n | Record<string, string | undefined>;\n\nexport function getHeader(\n headers: HeadersLike | undefined,\n name: string,\n): string | undefined {\n if (!headers) return undefined;\n if ('get' in headers && typeof headers.get === 'function') {\n return headers.get(name) ?? undefined;\n }\n const dictionary = headers as Record<string, string | undefined>;\n const value = dictionary[name] ?? dictionary[name.toLowerCase()];\n return typeof value === 'string' ? value : undefined;\n}\n\nexport type {\n RequestLogger,\n RequestLoggerOptions,\n RequestLogSnapshot,\n ParsedError,\n StructuredError,\n StructuredErrorInput,\n DrainPipelineOptions,\n PipelineDrainFn,\n};\n","import { createUseLogger, createAdapterToolkit } from './core';\n\nexport const useLogger = createUseLogger<{\n pathname?: string;\n method?: string;\n}>({\n adapterName: 'tanstack',\n enrich: (ctx) => ({\n ...(ctx.method ? { 'http.request.method': ctx.method } : {}),\n ...(ctx.pathname ? { 'http.route': ctx.pathname } : {}),\n }),\n});\n\nexport const tanstackToolkit = createAdapterToolkit<{\n pathname?: string;\n method?: string;\n}>({\n adapterName: 'tanstack',\n enrich: (ctx) => ({\n ...(ctx.method ? { 'http.request.method': ctx.method } : {}),\n ...(ctx.pathname ? { 'http.route': ctx.pathname } : {}),\n }),\n});\n"]}
|
package/dist/tanstack.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { tanstackToolkit, useLogger } from './chunk-
|
|
2
|
-
import './chunk-
|
|
1
|
+
export { tanstackToolkit, useLogger } from './chunk-JC3TNPQD.js';
|
|
2
|
+
import './chunk-GBSB7IX7.js';
|
|
3
3
|
//# sourceMappingURL=tanstack.js.map
|
|
4
4
|
//# sourceMappingURL=tanstack.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "autotel-adapters",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.13",
|
|
4
4
|
"description": "Framework adapters and composable DX helpers for autotel",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -49,15 +49,15 @@
|
|
|
49
49
|
"README.md"
|
|
50
50
|
],
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"autotel": "
|
|
52
|
+
"autotel": "3.0.3"
|
|
53
53
|
},
|
|
54
54
|
"peerDependencies": {
|
|
55
55
|
"hono": ">=4.12.15",
|
|
56
|
-
"@tanstack/react-start": "^1.167.
|
|
57
|
-
"@tanstack/solid-start": "^1.167.
|
|
56
|
+
"@tanstack/react-start": "^1.167.59",
|
|
57
|
+
"@tanstack/solid-start": "^1.167.56",
|
|
58
58
|
"next": ">=16.2.4",
|
|
59
59
|
"h3": "^2.0.0",
|
|
60
|
-
"nitropack": "^2.13.
|
|
60
|
+
"nitropack": "^2.13.4"
|
|
61
61
|
},
|
|
62
62
|
"peerDependenciesMeta": {
|
|
63
63
|
"hono": {
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
},
|
|
82
82
|
"devDependencies": {
|
|
83
83
|
"@types/node": "^25.6.0",
|
|
84
|
-
"hono": "^4.12.
|
|
84
|
+
"hono": "^4.12.16",
|
|
85
85
|
"rimraf": "^6.1.3",
|
|
86
86
|
"tsup": "^8.5.1",
|
|
87
87
|
"typescript": "^6.0.3",
|
package/src/core.ts
CHANGED
|
@@ -69,6 +69,89 @@ export function createAdapterToolkit<TContext = unknown>(
|
|
|
69
69
|
};
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
/**
|
|
73
|
+
* Description of a single adapter config field. `env` is the ordered list of
|
|
74
|
+
* environment variables to fall back to.
|
|
75
|
+
*/
|
|
76
|
+
export interface ConfigField<T> {
|
|
77
|
+
key: keyof T & string;
|
|
78
|
+
env?: string[];
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function resolveEnv(envKeys?: string[]): string | undefined {
|
|
82
|
+
if (!envKeys) return undefined;
|
|
83
|
+
for (const key of envKeys) {
|
|
84
|
+
const value = process.env[key];
|
|
85
|
+
if (value) return value;
|
|
86
|
+
}
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Returns true when at least one env-backed field is not provided via
|
|
92
|
+
* `overrides`, meaning runtime config may still contribute and should be
|
|
93
|
+
* probed to preserve precedence (`overrides > runtime > env`).
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* ```ts
|
|
97
|
+
* const FIELDS: ConfigField<MyAdapterConfig>[] = [
|
|
98
|
+
* { key: 'token', env: ['MY_ADAPTER_TOKEN'] },
|
|
99
|
+
* { key: 'endpoint', env: ['MY_ADAPTER_URL'] },
|
|
100
|
+
* ]
|
|
101
|
+
*
|
|
102
|
+
* if (shouldProbeRuntime(FIELDS, overrides)) {
|
|
103
|
+
* runtimeConfig = await loadRuntimeConfig()
|
|
104
|
+
* }
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
export function shouldProbeRuntime<T>(
|
|
108
|
+
fields: ConfigField<T>[],
|
|
109
|
+
overrides?: Partial<T>,
|
|
110
|
+
): boolean {
|
|
111
|
+
return fields.some(({ key, env }) => {
|
|
112
|
+
if (!env || env.length === 0) return false;
|
|
113
|
+
if (overrides?.[key] !== undefined) return false;
|
|
114
|
+
return true;
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Resolve adapter configuration with the standard priority chain:
|
|
120
|
+
*
|
|
121
|
+
* 1. `overrides` passed to the adapter factory
|
|
122
|
+
* 2. `runtimeConfig.autotel.{namespace}.{key}` (if a probe was performed)
|
|
123
|
+
* 3. `runtimeConfig.{namespace}.{key}` (if a probe was performed)
|
|
124
|
+
* 4. `process.env[envKey]` for each env in `field.env`
|
|
125
|
+
*
|
|
126
|
+
* Pass an async `probe` to defer the runtime config lookup so it is only
|
|
127
|
+
* invoked when runtime resolution is needed (i.e. at least one env-backed
|
|
128
|
+
* field is not set by overrides). Adapters that have no probe target may pass
|
|
129
|
+
* `() => Promise.resolve(undefined)`.
|
|
130
|
+
*/
|
|
131
|
+
export async function resolveAdapterConfig<T>(
|
|
132
|
+
namespace: string,
|
|
133
|
+
fields: ConfigField<T>[],
|
|
134
|
+
overrides: Partial<T> | undefined,
|
|
135
|
+
probe: () => Promise<Record<string, any> | undefined>,
|
|
136
|
+
): Promise<Partial<T>> {
|
|
137
|
+
const runtimeConfig = shouldProbeRuntime(fields, overrides)
|
|
138
|
+
? await probe()
|
|
139
|
+
: undefined;
|
|
140
|
+
const autotelNs = runtimeConfig?.autotel?.[namespace];
|
|
141
|
+
const rootNs = runtimeConfig?.[namespace];
|
|
142
|
+
|
|
143
|
+
const config: Record<string, unknown> = {};
|
|
144
|
+
for (const { key, env } of fields) {
|
|
145
|
+
config[key] =
|
|
146
|
+
overrides?.[key] ??
|
|
147
|
+
autotelNs?.[key] ??
|
|
148
|
+
rootNs?.[key] ??
|
|
149
|
+
resolveEnv(env);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return config as Partial<T>;
|
|
153
|
+
}
|
|
154
|
+
|
|
72
155
|
export type HeadersLike =
|
|
73
156
|
| { get(name: string): string | null }
|
|
74
157
|
| Record<string, string | undefined>;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
2
|
+
import {
|
|
3
|
+
resolveAdapterConfig,
|
|
4
|
+
shouldProbeRuntime,
|
|
5
|
+
type ConfigField,
|
|
6
|
+
} from './core';
|
|
7
|
+
|
|
8
|
+
interface AdapterConfig {
|
|
9
|
+
token?: string;
|
|
10
|
+
endpoint?: string;
|
|
11
|
+
timeout?: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const FIELDS: ConfigField<AdapterConfig>[] = [
|
|
15
|
+
{ key: 'token', env: ['MY_ADAPTER_TOKEN'] },
|
|
16
|
+
{ key: 'endpoint', env: ['MY_ADAPTER_ENDPOINT'] },
|
|
17
|
+
{ key: 'timeout' }, // optional tuning field, no env fallback
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
describe('shouldProbeRuntime', () => {
|
|
21
|
+
beforeEach(() => {
|
|
22
|
+
delete process.env.MY_ADAPTER_TOKEN;
|
|
23
|
+
delete process.env.MY_ADAPTER_ENDPOINT;
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('returns false when overrides cover every env-backed field', () => {
|
|
27
|
+
expect(
|
|
28
|
+
shouldProbeRuntime(FIELDS, { token: 't', endpoint: 'u' }),
|
|
29
|
+
).toBe(false);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('returns false when env covers every env-backed field', () => {
|
|
33
|
+
process.env.MY_ADAPTER_TOKEN = 't';
|
|
34
|
+
process.env.MY_ADAPTER_ENDPOINT = 'u';
|
|
35
|
+
expect(shouldProbeRuntime(FIELDS)).toBe(true);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('returns true when an env-backed field is still missing', () => {
|
|
39
|
+
process.env.MY_ADAPTER_TOKEN = 't';
|
|
40
|
+
expect(shouldProbeRuntime(FIELDS)).toBe(true);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('ignores fields with no env list (optional tuning fields)', () => {
|
|
44
|
+
process.env.MY_ADAPTER_TOKEN = 't';
|
|
45
|
+
process.env.MY_ADAPTER_ENDPOINT = 'u';
|
|
46
|
+
// `timeout` is still a runtime-resolvable field, so probing may still apply.
|
|
47
|
+
expect(shouldProbeRuntime(FIELDS)).toBe(true);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
describe('resolveAdapterConfig', () => {
|
|
52
|
+
beforeEach(() => {
|
|
53
|
+
delete process.env.MY_ADAPTER_TOKEN;
|
|
54
|
+
delete process.env.MY_ADAPTER_ENDPOINT;
|
|
55
|
+
});
|
|
56
|
+
afterEach(() => vi.restoreAllMocks());
|
|
57
|
+
|
|
58
|
+
it('calls the probe when overrides do not fully resolve config', async () => {
|
|
59
|
+
process.env.MY_ADAPTER_TOKEN = 't';
|
|
60
|
+
process.env.MY_ADAPTER_ENDPOINT = 'u';
|
|
61
|
+
|
|
62
|
+
const probe = vi.fn().mockResolvedValue(undefined);
|
|
63
|
+
const cfg = await resolveAdapterConfig('my-adapter', FIELDS, undefined, probe);
|
|
64
|
+
|
|
65
|
+
expect(probe).toHaveBeenCalledOnce();
|
|
66
|
+
expect(cfg.token).toBe('t');
|
|
67
|
+
expect(cfg.endpoint).toBe('u');
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('calls the probe and merges runtimeConfig.autotel.<namespace>.<key>', async () => {
|
|
71
|
+
const probe = vi.fn().mockResolvedValue({
|
|
72
|
+
autotel: { 'my-adapter': { token: 'from-runtime', endpoint: 'rt-url' } },
|
|
73
|
+
});
|
|
74
|
+
const cfg = await resolveAdapterConfig('my-adapter', FIELDS, undefined, probe);
|
|
75
|
+
|
|
76
|
+
expect(probe).toHaveBeenCalledOnce();
|
|
77
|
+
expect(cfg.token).toBe('from-runtime');
|
|
78
|
+
expect(cfg.endpoint).toBe('rt-url');
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it('overrides win over runtime and env', async () => {
|
|
82
|
+
process.env.MY_ADAPTER_TOKEN = 'env-token';
|
|
83
|
+
const probe = vi.fn().mockResolvedValue({
|
|
84
|
+
autotel: { 'my-adapter': { token: 'rt-token', endpoint: 'rt-url' } },
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
const cfg = await resolveAdapterConfig(
|
|
88
|
+
'my-adapter',
|
|
89
|
+
FIELDS,
|
|
90
|
+
{ token: 'override' },
|
|
91
|
+
probe,
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
expect(cfg.token).toBe('override');
|
|
95
|
+
expect(cfg.endpoint).toBe('rt-url');
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it('runtime config wins over env when both are present', async () => {
|
|
99
|
+
process.env.MY_ADAPTER_TOKEN = 'env-token';
|
|
100
|
+
process.env.MY_ADAPTER_ENDPOINT = 'env-url';
|
|
101
|
+
|
|
102
|
+
const probe = vi.fn().mockResolvedValue({
|
|
103
|
+
autotel: { 'my-adapter': { token: 'rt-token', endpoint: 'rt-url' } },
|
|
104
|
+
});
|
|
105
|
+
const cfg = await resolveAdapterConfig('my-adapter', FIELDS, undefined, probe);
|
|
106
|
+
|
|
107
|
+
expect(cfg.token).toBe('rt-token');
|
|
108
|
+
expect(cfg.endpoint).toBe('rt-url');
|
|
109
|
+
});
|
|
110
|
+
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core.ts"],"names":[],"mappings":";;;AAgCO,SAAS,gBACd,OAAA,EACA;AACA,EAAA,OAAO,SAAS,SAAA,CACd,OAAA,EACA,oBAAA,EACe;AACf,IAAA,IAAI,MAAA;AACJ,IAAA,IAAI;AACF,MAAA,MAAA,GAAS,gBAAA,CAAiB,QAAW,oBAAoB,CAAA;AAAA,IAC3D,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,kBAAA,EAAqB,QAAQ,WAAW,CAAA,2GAAA;AAAA,OAE1C;AAAA,IACF;AAEA,IAAA,IAAI,OAAA,IAAW,QAAQ,MAAA,EAAQ;AAC7B,MAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,MAAA,CAAO,OAAO,CAAA;AACpC,MAAA,IAAI,SAAS,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA,CAAE,SAAS,CAAA,EAAG;AAC1C,QAAA,MAAA,CAAO,IAAI,KAAK,CAAA;AAAA,MAClB;AAAA,IACF;AAEA,IAAA,OAAO,MAAA;AAAA,EACT,CAAA;AACF;AAEO,SAAS,qBACd,OAAA,EAC0B;AAC1B,EAAA,OAAO;AAAA,IACL,SAAA,EAAW,gBAAgB,OAAO,CAAA;AAAA,IAClC,UAAA;AAAA,IACA,qBAAA;AAAA,IACA;AAAA,GACF;AACF;AAMO,SAAS,SAAA,CACd,SACA,IAAA,EACoB;AACpB,EAAA,IAAI,CAAC,SAAS,OAAO,MAAA;AACrB,EAAA,IAAI,KAAA,IAAS,OAAA,IAAW,OAAO,OAAA,CAAQ,QAAQ,UAAA,EAAY;AACzD,IAAA,OAAO,OAAA,CAAQ,GAAA,CAAI,IAAI,CAAA,IAAK,MAAA;AAAA,EAC9B;AACA,EAAA,MAAM,UAAA,GAAa,OAAA;AACnB,EAAA,MAAM,QAAQ,UAAA,CAAW,IAAI,KAAK,UAAA,CAAW,IAAA,CAAK,aAAa,CAAA;AAC/D,EAAA,OAAO,OAAO,KAAA,KAAU,QAAA,GAAW,KAAA,GAAQ,MAAA;AAC7C","file":"chunk-2MUUBQJZ.js","sourcesContent":["import {\n createDrainPipeline,\n createStructuredError,\n getRequestLogger,\n parseError,\n type ParsedError,\n type RequestLogger,\n type RequestLoggerOptions,\n type RequestLogSnapshot,\n type DrainPipelineOptions,\n type PipelineDrainFn,\n type StructuredError,\n type StructuredErrorInput,\n} from 'autotel';\n\nexport interface AdapterUseLoggerOptions<TContext> {\n adapterName: string;\n enrich?: (context: TContext) => Record<string, unknown> | undefined;\n}\n\nexport interface AdapterToolkit<TContext> {\n useLogger: (\n context?: TContext,\n options?: RequestLoggerOptions,\n ) => RequestLogger;\n parseError: (error: unknown) => ParsedError;\n createStructuredError: (input: StructuredErrorInput) => StructuredError;\n createDrainPipeline: <T = unknown>(\n options?: DrainPipelineOptions<T>,\n ) => (drain: (batch: T[]) => void | Promise<void>) => PipelineDrainFn<T>;\n}\n\nexport function createUseLogger<TContext = unknown>(\n options: AdapterUseLoggerOptions<TContext>,\n) {\n return function useLogger(\n context?: TContext,\n requestLoggerOptions?: RequestLoggerOptions,\n ): RequestLogger {\n let logger: RequestLogger;\n try {\n logger = getRequestLogger(undefined, requestLoggerOptions);\n } catch {\n throw new Error(\n `[autotel-adapters/${options.adapterName}] No active trace context. ` +\n `Wrap your handler with autotel trace instrumentation before calling useLogger().`,\n );\n }\n\n if (context && options.enrich) {\n const extra = options.enrich(context);\n if (extra && Object.keys(extra).length > 0) {\n logger.set(extra);\n }\n }\n\n return logger;\n };\n}\n\nexport function createAdapterToolkit<TContext = unknown>(\n options: AdapterUseLoggerOptions<TContext>,\n): AdapterToolkit<TContext> {\n return {\n useLogger: createUseLogger(options),\n parseError,\n createStructuredError,\n createDrainPipeline,\n };\n}\n\nexport type HeadersLike =\n | { get(name: string): string | null }\n | Record<string, string | undefined>;\n\nexport function getHeader(\n headers: HeadersLike | undefined,\n name: string,\n): string | undefined {\n if (!headers) return undefined;\n if ('get' in headers && typeof headers.get === 'function') {\n return headers.get(name) ?? undefined;\n }\n const dictionary = headers as Record<string, string | undefined>;\n const value = dictionary[name] ?? dictionary[name.toLowerCase()];\n return typeof value === 'string' ? value : undefined;\n}\n\nexport type {\n RequestLogger,\n RequestLoggerOptions,\n RequestLogSnapshot,\n ParsedError,\n StructuredError,\n StructuredErrorInput,\n DrainPipelineOptions,\n PipelineDrainFn,\n};\n"]}
|