{"version":3,"file":"axiom.mjs","names":[],"sources":["../../src/adapters/axiom.ts"],"sourcesContent":["import type { WideEvent } from '../types'\nimport type { ConfigField } from './_config'\nimport { resolveAdapterConfig } from './_config'\nimport { defineDrain } from './_drain'\nimport { httpPost } from './_http'\n\ninterface BaseAxiomConfig {\n  /** Axiom dataset name */\n  dataset: string\n  /** Axiom API token */\n  token: string\n  /** Organization ID (required for Personal Access Tokens) */\n  orgId?: string\n  /** Request timeout in milliseconds. Default: 5000 */\n  timeout?: number\n}\n\ninterface EdgeAxiomConfig {\n  /**\n   * Edge URL for Axiom ingest/query endpoints.\n   * If no path is provided, uses /v1/ingest/{dataset}.\n   * If a custom path is provided, it is used as-is (trailing slash trimmed).\n   */\n  edgeUrl: string\n  /** Mutually exclusive with edgeUrl. */\n  baseUrl?: never\n}\n\ninterface EndpointAxiomConfig {\n  /** Base URL for Axiom API. Uses /v1/datasets/{dataset}/ingest. */\n  baseUrl?: string\n  /** Mutually exclusive with baseUrl. */\n  edgeUrl?: never\n}\n\nexport type AxiomConfig = BaseAxiomConfig & (EdgeAxiomConfig | EndpointAxiomConfig)\n\ntype ResolvedAxiomConfig = BaseAxiomConfig & {\n  edgeUrl?: string\n  baseUrl?: string\n}\n\nconst AXIOM_FIELDS: ConfigField<ResolvedAxiomConfig>[] = [\n  { key: 'dataset', env: ['NUXT_AXIOM_DATASET', 'AXIOM_DATASET'] },\n  { key: 'token', env: ['NUXT_AXIOM_TOKEN', 'AXIOM_TOKEN'] },\n  { key: 'orgId', env: ['NUXT_AXIOM_ORG_ID', 'AXIOM_ORG_ID'] },\n  { key: 'edgeUrl', env: ['NUXT_AXIOM_EDGE_URL', 'AXIOM_EDGE_URL'] },\n  { key: 'baseUrl', env: ['NUXT_AXIOM_URL', 'AXIOM_URL'] },\n  { key: 'timeout' },\n]\n\n/**\n * Create a drain function for sending logs to Axiom.\n *\n * Configuration priority (highest to lowest):\n * 1. Overrides passed to createAxiomDrain()\n * 2. runtimeConfig.mxllog.axiom\n * 3. runtimeConfig.axiom\n * 4. Environment variables: NUXT_AXIOM_*, AXIOM_*\n *\n * @example\n * ```ts\n * // Zero config - just set NUXT_AXIOM_TOKEN and NUXT_AXIOM_DATASET env vars\n * nitroApp.hooks.hook('mxllog:drain', createAxiomDrain())\n *\n * // With overrides\n * nitroApp.hooks.hook('mxllog:drain', createAxiomDrain({\n *   dataset: 'my-dataset',\n * }))\n * ```\n */\nexport function createAxiomDrain(overrides?: Partial<AxiomConfig>) {\n  return defineDrain<AxiomConfig>({\n    name: 'axiom',\n    resolve: () => {\n      const config = resolveAdapterConfig<ResolvedAxiomConfig>(\n        'axiom',\n        AXIOM_FIELDS,\n        overrides as Partial<ResolvedAxiomConfig>,\n      )\n      if (!config.dataset || !config.token) {\n        console.error('[mxllog/axiom] Missing dataset or token. Set NUXT_AXIOM_TOKEN/NUXT_AXIOM_DATASET env vars or pass to createAxiomDrain()')\n        return null\n      }\n\n      if (config.edgeUrl && config.baseUrl) {\n        console.warn('[mxllog/axiom] Both edgeUrl and baseUrl are set. edgeUrl takes precedence for ingest.')\n        delete config.baseUrl\n      }\n\n      return config as AxiomConfig\n    },\n    send: sendBatchToAxiom,\n  })\n}\n\n/**\n * Send a single event to Axiom.\n *\n * @example\n * ```ts\n * await sendToAxiom(event, {\n *   dataset: 'my-logs',\n *   token: process.env.AXIOM_TOKEN!,\n * })\n * ```\n */\nexport async function sendToAxiom(event: WideEvent, config: AxiomConfig): Promise<void> {\n  await sendBatchToAxiom([event], config)\n}\n\n/**\n * Send a batch of events to Axiom.\n *\n * @example\n * ```ts\n * await sendBatchToAxiom(events, {\n *   dataset: 'my-logs',\n *   token: process.env.AXIOM_TOKEN!,\n * })\n * ```\n */\nexport async function sendBatchToAxiom(events: WideEvent[], config: AxiomConfig): Promise<void> {\n  const url = resolveIngestUrl(config)\n\n  const headers: Record<string, string> = {\n    'Content-Type': 'application/json',\n    'Authorization': `Bearer ${config.token}`,\n  }\n\n  if (config.orgId) {\n    headers['X-Axiom-Org-Id'] = config.orgId\n  }\n\n  await httpPost({\n    url,\n    headers,\n    body: JSON.stringify(events),\n    timeout: config.timeout ?? 5000,\n    label: 'Axiom',\n  })\n}\n\nfunction resolveIngestUrl(config: AxiomConfig): string {\n  const encodedDataset = encodeURIComponent(config.dataset)\n\n  if (!config.edgeUrl) {\n    const baseUrl = config.baseUrl ?? 'https://api.axiom.co'\n    return `${baseUrl}/v1/datasets/${encodedDataset}/ingest`\n  }\n\n  try {\n    const parsed = new URL(config.edgeUrl)\n\n    if (parsed.pathname === '' || parsed.pathname === '/') {\n      parsed.pathname = `/v1/ingest/${encodedDataset}`\n      return parsed.toString()\n    }\n\n    parsed.pathname = parsed.pathname.replace(/\\/+$/, '')\n    return parsed.toString()\n  } catch {\n    console.warn(`[mxllog/axiom] edgeUrl \"${config.edgeUrl}\" is not a valid URL, falling back to string concatenation.`)\n    const trimmed = config.edgeUrl.replace(/\\/+$/, '')\n    return `${trimmed}/v1/ingest/${encodedDataset}`\n  }\n}\n"],"mappings":";;AA0CA,MAAM,eAAmD;CACvD;EAAE,KAAK;EAAW,KAAK,CAAC,sBAAsB,gBAAgB;EAAE;CAChE;EAAE,KAAK;EAAS,KAAK,CAAC,oBAAoB,cAAc;EAAE;CAC1D;EAAE,KAAK;EAAS,KAAK,CAAC,qBAAqB,eAAe;EAAE;CAC5D;EAAE,KAAK;EAAW,KAAK,CAAC,uBAAuB,iBAAiB;EAAE;CAClE;EAAE,KAAK;EAAW,KAAK,CAAC,kBAAkB,YAAY;EAAE;CACxD,EAAE,KAAK,WAAW;CACnB;;;;;;;;;;;;;;;;;;;;;AAsBD,SAAgB,iBAAiB,WAAkC;AACjE,QAAO,YAAyB;EAC9B,MAAM;EACN,eAAe;GACb,MAAM,SAAS,qBACb,SACA,cACA,UACD;AACD,OAAI,CAAC,OAAO,WAAW,CAAC,OAAO,OAAO;AACpC,YAAQ,MAAM,0HAA0H;AACxI,WAAO;;AAGT,OAAI,OAAO,WAAW,OAAO,SAAS;AACpC,YAAQ,KAAK,wFAAwF;AACrG,WAAO,OAAO;;AAGhB,UAAO;;EAET,MAAM;EACP,CAAC;;;;;;;;;;;;;AAcJ,eAAsB,YAAY,OAAkB,QAAoC;AACtF,OAAM,iBAAiB,CAAC,MAAM,EAAE,OAAO;;;;;;;;;;;;;AAczC,eAAsB,iBAAiB,QAAqB,QAAoC;CAC9F,MAAM,MAAM,iBAAiB,OAAO;CAEpC,MAAM,UAAkC;EACtC,gBAAgB;EAChB,iBAAiB,UAAU,OAAO;EACnC;AAED,KAAI,OAAO,MACT,SAAQ,oBAAoB,OAAO;AAGrC,OAAM,SAAS;EACb;EACA;EACA,MAAM,KAAK,UAAU,OAAO;EAC5B,SAAS,OAAO,WAAW;EAC3B,OAAO;EACR,CAAC;;AAGJ,SAAS,iBAAiB,QAA6B;CACrD,MAAM,iBAAiB,mBAAmB,OAAO,QAAQ;AAEzD,KAAI,CAAC,OAAO,QAEV,QAAO,GADS,OAAO,WAAW,uBAChB,eAAe,eAAe;AAGlD,KAAI;EACF,MAAM,SAAS,IAAI,IAAI,OAAO,QAAQ;AAEtC,MAAI,OAAO,aAAa,MAAM,OAAO,aAAa,KAAK;AACrD,UAAO,WAAW,cAAc;AAChC,UAAO,OAAO,UAAU;;AAG1B,SAAO,WAAW,OAAO,SAAS,QAAQ,QAAQ,GAAG;AACrD,SAAO,OAAO,UAAU;SAClB;AACN,UAAQ,KAAK,2BAA2B,OAAO,QAAQ,6DAA6D;AAEpH,SAAO,GADS,OAAO,QAAQ,QAAQ,QAAQ,GAAG,CAChC,aAAa"}