{"version":3,"file":"node.mjs","names":[],"sources":["../../src/reporters/node.ts"],"sourcesContent":["import type { Diagnostic, DiagnosticReporter } from '../diagnostic'\nimport { appendFileSync } from 'node:fs'\n\nexport interface FileReporterOptions {\n  /**\n   * Path to the log file.\n   * @default '.nostics.log'\n   */\n  logFile?: string\n\n  /**\n   * Stack frames matching ANY of these patterns are removed from\n   * `diagnostic.stack` before it is written to the log file. Useful to strip\n   * `node_modules` and Node internals. The `Error: ...` header line is\n   * always preserved.\n   *\n   * Pass an empty array to keep every frame.\n   * @default [/\\/node_modules\\//i]\n   */\n  excludeStackFrames?: readonly RegExp[]\n}\n\nconst DEFAULT_EXCLUDE_STACK_FRAMES: readonly RegExp[] = [/\\/node_modules\\//i]\n\nfunction applyExcludeStackFrames(raw: string, exclude: readonly RegExp[]): string {\n  const [header, ...frames] = raw.split('\\n')\n  return [header, ...frames.filter(frame => !exclude.some(re => re.test(frame)))].join('\\n')\n}\n\n/**\n * Creates a reporter that appends diagnostics as NDJSON to a local file.\n * Each diagnostic is written as a single JSON line. The diagnostic's `stack`\n * (if present) is included in the payload; noisy frames can be removed via\n * {@link FileReporterOptions.excludeStackFrames}.\n *\n * @example\n * ```ts\n * import { defineDiagnostics } from 'nostics'\n * import { createFileReporter } from 'nostics/reporters/node'\n *\n * const diagnostics = defineDiagnostics({\n *   codes: { ... },\n *   reporters: [createFileReporter({\n *     excludeStackFrames: [/\\/node_modules\\//, /\\(node:/],\n *   })],\n * })\n * ```\n */\n/* @__NO_SIDE_EFFECTS__ */\nexport function createFileReporter(options?: FileReporterOptions): DiagnosticReporter {\n  const logFile = options?.logFile ?? '.nostics.log'\n  const excludeStackFrames = options?.excludeStackFrames ?? DEFAULT_EXCLUDE_STACK_FRAMES\n  return (diagnostic) => {\n    try {\n      const d = diagnostic as Diagnostic & Record<string, unknown>\n      const base: Record<string, unknown>\n        = typeof d.toJSON === 'function' ? (d.toJSON() as Record<string, unknown>) : { ...d }\n      if (d.stack) {\n        base.stack = excludeStackFrames?.length\n          ? applyExcludeStackFrames(d.stack, excludeStackFrames)\n          : d.stack\n      }\n      appendFileSync(logFile, `${JSON.stringify(base)}\\n`)\n    }\n    catch (err: unknown) {\n      console.error(`[nostics]: Failed to write log to \"${logFile}\":`, err)\n    }\n  }\n}\n"],"mappings":";;AAsBA,MAAM,+BAAkD,CAAC,mBAAmB;AAE5E,SAAS,wBAAwB,KAAa,SAAoC;CAChF,MAAM,CAAC,QAAQ,GAAG,UAAU,IAAI,MAAM,IAAI;CAC1C,OAAO,CAAC,QAAQ,GAAG,OAAO,QAAO,UAAS,CAAC,QAAQ,MAAK,OAAM,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI;AAC3F;;;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,mBAAmB,SAAmD;CACpF,MAAM,UAAU,SAAS,WAAW;CACpC,MAAM,qBAAqB,SAAS,sBAAsB;CAC1D,QAAQ,eAAe;EACrB,IAAI;GACF,MAAM,IAAI;GACV,MAAM,OACF,OAAO,EAAE,WAAW,aAAc,EAAE,OAAO,IAAgC,EAAE,GAAG,EAAE;GACtF,IAAI,EAAE,OACJ,KAAK,QAAQ,oBAAoB,SAC7B,wBAAwB,EAAE,OAAO,kBAAkB,IACnD,EAAE;GAER,eAAe,SAAS,GAAG,KAAK,UAAU,IAAI,EAAE,GAAG;EACrD,SACO,KAAc;GACnB,QAAQ,MAAM,sCAAsC,QAAQ,KAAK,GAAG;EACtE;CACF;AACF"}