{"version":3,"sources":["../src/reporter.ts"],"sourcesContent":["/**\n * Vitest reporter that reads task.meta.story from tests and writes reports\n * using the executable-stories-formatters package.\n *\n * Do not add value imports from \"vitest\" or \"./story-api.js\" here; this entry is loaded in vitest.config\n * before Vitest is ready. Use only `import type` from those modules.\n *\n * Type strategy: this reporter is duck-typed against vitest's runner contract,\n * not nominally typed via `implements Reporter`. That keeps it compatible with\n * any vitest-compatible runner (including forks like vite-plus) where the\n * `Vitest` class type carries different private fields and would otherwise\n * fail nominal assignability checks at the consumer's call site.\n *\n * Vitest types are imported only for parameter typing of internal helpers,\n * never as `implements`. Anything we touch on `ctx` is captured by the local\n * `VitestContext` structural type below.\n */\nimport type {\n  SerializedError,\n  TestModule,\n  TestCase,\n  TestRunEndReason,\n} from \"vitest/node\";\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport type { StoryMeta } from \"./types\";\nimport { assertionComparison } from \"executable-stories-core/utils/assertion-comparison\";\n\n// Import from formatters package\nimport {\n  ReportGenerator,\n  canonicalizeRun,\n  readGitSha,\n  readPackageVersion,\n  detectCI,\n  sendNotifications,\n  toCIInfo,\n  loadHistory,\n  updateHistory,\n  saveHistory,\n  type RawFeature,\n  type RawRun,\n  type RawTestCase,\n  type RawAttachment,\n  type RawStepEvent,\n  type FormatterOptions,\n  type CoverageSummary,\n  type OtelSpan,\n} from \"executable-stories-formatters\";\n\n// Re-export types from formatters for convenience\nexport type {\n  OutputFormat,\n  OutputMode,\n  ColocatedStyle,\n  OutputRule,\n  FormatterOptions,\n} from \"executable-stories-formatters\";\n\n// ============================================================================\n// Structural runner context\n// ----------------------------------------------------------------------------\n// We only read `ctx.config.root`. Avoid importing the full `Vitest` class as\n// a parameter type — its private fields (`_clearScreenPending`, etc.) make\n// nominal assignability fail across vitest forks. A structural type lets the\n// reporter accept any vitest-compatible runner.\n// ============================================================================\n\nexport type VitestContext = {\n  config?: {\n    root?: string;\n    /**\n     * Set by `vitest -t` / `--testNamePattern`. Vitest reports only the tests\n     * that match, so a run carrying one cannot speak for the rest of a file.\n     */\n    testNamePattern?: string | RegExp;\n  };\n};\n\n// ============================================================================\n// Reporter Protocol (duck-typed interface for reporters)\n// ============================================================================\n// Exported protocol that captures the reporter contract. This allows\n// StoryReporter to be properly typed without nominal `implements Reporter`,\n// enabling duck-typing compatibility across vitest forks while maintaining\n// type safety at the consumer call site.\n// ============================================================================\n\n// Public-facing protocol uses loose params on runner-supplied callbacks so the\n// returned reporter is structurally assignable to any vitest-compatible runner's\n// `Reporter` type (vitest, vite-plus, future forks). The concrete StoryReporter\n// class still uses strict vitest types internally — method bivariance lets the\n// narrower class satisfy this looser protocol.\nexport interface StoryReporterProtocol {\n  onInit(ctx: VitestContext): void;\n  onCoverage(coverage: unknown): void;\n  onTestRunEnd(\n    testModules: readonly unknown[],\n    unhandledErrors: readonly unknown[],\n    reason: unknown,\n  ): Promise<void>;\n}\n\n// ============================================================================\n// Reporter Options (delegates to FormatterOptions)\n// ============================================================================\n\nexport interface StoryReporterOptions extends FormatterOptions {\n  /** When GITHUB_ACTIONS, append report to job summary via @actions/core. Default: true */\n  enableGithubActionsSummary?: boolean;\n  /** If set, write raw run JSON (schemaVersion 1) to this path for use with the executable-stories CLI/binary */\n  rawRunPath?: string;\n}\n\n// ============================================================================\n// Coverage Types\n// ============================================================================\n\ntype CoverageMetric = { total: number; covered: number; pct: number };\ntype CoverageData = {\n  statements: CoverageMetric;\n  branches: CoverageMetric;\n  functions: CoverageMetric;\n  lines?: CoverageMetric;\n};\ntype CoverageFile = {\n  s: Record<string, number>;\n  f: Record<string, number>;\n  b: Record<string, number[]>;\n  l?: Record<string, number>;\n};\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/**\n * Normalize Vitest onCoverage payload to coverage data.\n */\nfunction normalizeCoveragePayload(\n  coverage: unknown\n): Record<string, CoverageFile> | undefined {\n  if (!coverage || typeof coverage !== \"object\" || Array.isArray(coverage))\n    return undefined;\n  const raw = coverage as Record<string, unknown>;\n  const data: Record<string, CoverageFile> = {};\n  for (const [filePath, file] of Object.entries(raw)) {\n    if (\n      file &&\n      typeof file === \"object\" &&\n      \"s\" in file &&\n      \"f\" in file &&\n      \"b\" in file\n    ) {\n      data[filePath] = file as CoverageFile;\n    }\n  }\n  if (Object.keys(data).length === 0) return undefined;\n  return data;\n}\n\n/**\n * Summarize coverage data.\n */\nfunction summarizeCoverage(\n  data: Record<string, CoverageFile>\n): CoverageData | undefined {\n  let statementsTotal = 0;\n  let statementsCovered = 0;\n  let functionsTotal = 0;\n  let functionsCovered = 0;\n  let branchesTotal = 0;\n  let branchesCovered = 0;\n  let linesTotal = 0;\n  let linesCovered = 0;\n  let hasLines = false;\n\n  for (const file of Object.values(data)) {\n    for (const count of Object.values(file.s)) {\n      statementsTotal += 1;\n      if (count > 0) statementsCovered += 1;\n    }\n    for (const count of Object.values(file.f)) {\n      functionsTotal += 1;\n      if (count > 0) functionsCovered += 1;\n    }\n    for (const counts of Object.values(file.b)) {\n      for (const count of counts) {\n        branchesTotal += 1;\n        if (count > 0) branchesCovered += 1;\n      }\n    }\n    if (file.l) {\n      hasLines = true;\n      for (const count of Object.values(file.l)) {\n        linesTotal += 1;\n        if (count > 0) linesCovered += 1;\n      }\n    }\n  }\n\n  if (\n    statementsTotal === 0 &&\n    functionsTotal === 0 &&\n    branchesTotal === 0 &&\n    !hasLines\n  ) {\n    return undefined;\n  }\n\n  const metric = (covered: number, total: number): CoverageMetric => ({\n    total,\n    covered,\n    pct: total === 0 ? 100 : Math.round((covered / total) * 100),\n  });\n\n  const summary: CoverageData = {\n    statements: metric(statementsCovered, statementsTotal),\n    branches: metric(branchesCovered, branchesTotal),\n    functions: metric(functionsCovered, functionsTotal),\n  };\n  if (hasLines) {\n    summary.lines = metric(linesCovered, linesTotal);\n  }\n  return summary;\n}\n\n/**\n * Convert internal coverage data to formatters CoverageSummary.\n */\nfunction toCoverageSummary(\n  data: CoverageData | undefined\n): CoverageSummary | undefined {\n  if (!data) return undefined;\n  return {\n    statementsPct: data.statements.pct,\n    branchesPct: data.branches.pct,\n    functionsPct: data.functions.pct,\n    linesPct: data.lines?.pct,\n  };\n}\n\n/**\n * Convert path to relative posix format.\n */\nfunction toRelativePosix(absolutePath: string, projectRoot: string): string {\n  return path.relative(projectRoot, absolutePath).split(path.sep).join(\"/\");\n}\n\n// ============================================================================\n// Reporter Implementation\n// ============================================================================\n\n/**\n * Vitest reporter that generates reports using executable-stories-formatters.\n *\n * Reads `task.meta.story` from each test and generates reports in configured formats.\n * Supports output routing (aggregated/colocated) and multiple output formats.\n *\n * Implements StoryReporterProtocol for type-safe duck-typing across vitest forks.\n *\n * Prefer {@link createStoryReporter} in `vitest.config.ts`: it returns this same\n * reporter already typed as StoryReporterProtocol, so the config needs no cast.\n * Construct the class directly only when you need to subclass or wrap it.\n */\nexport default class StoryReporter implements StoryReporterProtocol {\n  private options: StoryReporterOptions;\n  private ctx: VitestContext | undefined;\n  private startTime: number = 0;\n  private packageVersion: string | undefined;\n  private gitSha: string | undefined;\n  /**\n   * Left unknown until onInit sees a config. Claiming full coverage without\n   * having looked would let a later merge retire scenarios on a guess.\n   */\n  private runScope: \"full\" | \"filtered\" | undefined;\n  private coverageByFile: Record<string, CoverageFile> = {};\n\n  constructor(options: StoryReporterOptions = {}) {\n    this.options = options;\n  }\n\n  onInit(ctx: VitestContext): void {\n    this.ctx = ctx;\n    this.startTime = Date.now();\n    const root = ctx.config?.root ?? process.cwd();\n    // `vitest -t` reports the matching tests and nothing else, so consumers\n    // must not read this run as the full contents of the files it touches.\n    // Vitest hands us the pattern either way, so the answer is never a guess.\n    if (ctx.config) {\n      this.runScope = ctx.config.testNamePattern != null ? \"filtered\" : \"full\";\n    }\n\n    // Read metadata if needed\n    const includeMetadata = this.options.markdown?.includeMetadata ?? true;\n    if (includeMetadata) {\n      this.packageVersion = readPackageVersion(root);\n      this.gitSha = readGitSha(root);\n    }\n  }\n\n  onCoverage(coverage: unknown): void {\n    const data = normalizeCoveragePayload(coverage);\n    if (data) {\n      this.coverageByFile = { ...this.coverageByFile, ...data };\n    }\n  }\n\n  async onTestRunEnd(\n    testModules: ReadonlyArray<TestModule>,\n    _unhandledErrors: ReadonlyArray<SerializedError>,\n    reason: TestRunEndReason\n  ): Promise<void> {\n    if (reason === \"interrupted\") return;\n\n    const root = this.ctx?.config?.root ?? process.cwd();\n\n    // Collect test cases\n    const rawTestCases = this.collectTestCases(testModules, root);\n    const coveredSourceFiles = this.collectCoveredSourceFiles(testModules, root);\n    const incompleteSourceFiles = this.collectIncompleteSourceFiles(testModules, root);\n    const features = collectFeatures(testModules, root);\n\n    // Build RawRun\n    const rawRun: RawRun = {\n      testCases: rawTestCases,\n      ...(features.length > 0 ? { features } : {}),\n      startedAtMs: this.startTime,\n      finishedAtMs: Date.now(),\n      projectRoot: root,\n      packageVersion: this.packageVersion,\n      gitSha: this.gitSha,\n      ci: detectCI(),\n      ...(this.runScope ? { runScope: this.runScope } : {}),\n      ...(coveredSourceFiles.length > 0 ? { coveredSourceFiles } : {}),\n      ...(incompleteSourceFiles.length > 0 ? { incompleteSourceFiles } : {}),\n    };\n\n    // Optionally write raw run JSON for CLI/binary consumption\n    const rawRunPath = this.options.rawRunPath;\n    if (rawRunPath) {\n      try {\n        const absolutePath = path.isAbsolute(rawRunPath)\n          ? rawRunPath\n          : path.join(root, rawRunPath);\n        const dir = path.dirname(absolutePath);\n        if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });\n        const payload = { schemaVersion: 1, ...rawRun };\n        fs.writeFileSync(absolutePath, JSON.stringify(payload, null, 2), \"utf8\");\n      } catch (err) {\n        console.error(\"Failed to write raw run JSON:\", err);\n      }\n    }\n\n    // Canonicalize\n    const canonicalRun = canonicalizeRun(rawRun);\n\n    // Add coverage if available\n    const coverageData = summarizeCoverage(this.coverageByFile);\n    if (coverageData) {\n      canonicalRun.coverage = toCoverageSummary(coverageData);\n    }\n\n    // 1. Generate reports\n    const generator = new ReportGenerator(this.options);\n    try {\n      const results = await generator.generate(canonicalRun);\n\n      // Append to GitHub Actions summary if enabled\n      const enableGithubSummary = this.options.enableGithubActionsSummary ?? true;\n      if (process.env.GITHUB_ACTIONS === \"true\" && enableGithubSummary) {\n        const markdownPaths = results.get(\"markdown\") ?? [];\n        if (markdownPaths.length > 0) {\n          const firstPath = markdownPaths[0];\n          const content = fs.readFileSync(firstPath, \"utf8\");\n          await this.appendGithubSummary(content).catch(() => {});\n        }\n      }\n    } catch (err) {\n      console.error(\"Failed to generate reports:\", err);\n    }\n\n    // 2. Update history (independent of report generation)\n    try {\n      const histOpts = this.options.history;\n      if (histOpts?.filePath) {\n        const historyPath = path.isAbsolute(histOpts.filePath)\n          ? histOpts.filePath\n          : path.join(root, histOpts.filePath);\n        const store = loadHistory(\n          { filePath: historyPath },\n          {\n            readFile: (p: string) => { try { return fs.readFileSync(p, \"utf8\"); } catch { return undefined; } },\n            logger: console,\n          },\n        );\n        const updated = updateHistory({ store, run: canonicalRun, maxRuns: histOpts.maxRuns ?? 10 });\n        const dir = path.dirname(historyPath);\n        if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });\n        saveHistory(\n          { filePath: historyPath, store: updated },\n          { writeFile: (p: string, c: string) => fs.writeFileSync(p, c, \"utf8\") },\n        );\n      }\n    } catch (err) {\n      console.error(\"Failed to update history:\", err);\n    }\n\n    // 3. Send notifications (independent of both above)\n    try {\n      if (this.options.notification) {\n        await sendNotifications(\n          { run: canonicalRun, notification: this.options.notification },\n          { fetch: globalThis.fetch, logger: console, toCIInfo },\n        );\n      }\n    } catch (err) {\n      console.error(\"Failed to send notifications:\", err);\n    }\n  }\n\n  /**\n   * Collect test cases from Vitest test modules.\n   */\n  /**\n   * Every module vitest ran, whether or not it produced a story.\n   *\n   * The collected test cases only name modules that produced something, so a\n   * file whose last story was deleted would otherwise look like a file that did\n   * not run and keep its old scenarios for good.\n   */\n  private collectCoveredSourceFiles(\n    testModules: ReadonlyArray<TestModule>,\n    root: string\n  ): string[] {\n    const files = new Set<string>();\n    for (const mod of testModules) {\n      const moduleId =\n        mod.moduleId ?? (mod as { relativeModuleId?: string }).relativeModuleId ?? \"\";\n      if (!moduleId) continue;\n      const absolute = path.isAbsolute(moduleId) ? moduleId : path.resolve(root, moduleId);\n      files.add(toRelativePosix(absolute, root));\n    }\n    return [...files].sort();\n  }\n\n  /**\n   * Files whose scenarios could not be collected in full.\n   *\n   * A module that errored, or a test that failed without ever declaring a\n   * story, is missing scenarios because the run broke. Treating that as\n   * deletion would throw away documentation at the exact moment the suite is\n   * unhealthy. Checked per test, not per file: one healthy story in a module\n   * does not vouch for its broken siblings.\n   */\n  private collectIncompleteSourceFiles(\n    testModules: ReadonlyArray<TestModule>,\n    root: string\n  ): string[] {\n    const incomplete = new Set<string>();\n    for (const mod of testModules) {\n      const moduleId =\n        mod.moduleId ?? (mod as { relativeModuleId?: string }).relativeModuleId ?? \"\";\n      if (!moduleId) continue;\n      const absolute = path.isAbsolute(moduleId) ? moduleId : path.resolve(root, moduleId);\n      const sourceFile = toRelativePosix(absolute, root);\n\n      const errors = (mod as { errors?: () => unknown[] }).errors?.() ?? [];\n      const collection = mod.children;\n      if (errors.length > 0 || !collection) {\n        const state = (mod as { state?: () => string }).state?.();\n        if (errors.length > 0 || state === \"failed\") incomplete.add(sourceFile);\n        continue;\n      }\n\n      for (const test of collection.allTests()) {\n        const meta = this.getStoryMeta(test);\n        if (meta?.scenario && Array.isArray(meta.steps)) continue;\n        if (test.options?.mode === \"todo\") continue;\n        if (test.result?.()?.state === \"failed\") {\n          incomplete.add(sourceFile);\n          break;\n        }\n      }\n    }\n    return [...incomplete].sort();\n  }\n\n  private collectTestCases(\n    testModules: ReadonlyArray<TestModule>,\n    root: string\n  ): RawTestCase[] {\n    const testCases: RawTestCase[] = [];\n\n    for (const mod of testModules) {\n      const collection = mod.children;\n      if (!collection) continue;\n\n      const moduleId =\n        mod.moduleId ??\n        (mod as { relativeModuleId?: string }).relativeModuleId ??\n        \"\";\n      const absoluteModuleId = path.isAbsolute(moduleId)\n        ? moduleId\n        : path.resolve(root, moduleId);\n      const sourceFile = toRelativePosix(absoluteModuleId, root);\n\n      // Bodyless `it.todo(...)` never runs `story.init()`, so those tests have\n      // no story meta. Collect them separately and emit them as planned\n      // scenarios — but only for modules that contain story tests, so plain\n      // (non-story) suites full of todos don't leak into the generated docs.\n      const plannedTests: TestCase[] = [];\n      let moduleHasStoryTests = false;\n\n      for (const test of collection.allTests()) {\n        const meta = this.getStoryMeta(test);\n        if (!meta?.scenario || !Array.isArray(meta.steps)) {\n          if (test.options?.mode === \"todo\") plannedTests.push(test);\n          continue;\n        }\n        moduleHasStoryTests = true;\n\n        const result = test.result?.();\n        const state = result?.state ?? \"pending\";\n        const durationMs =\n          typeof (result as { duration?: number } | undefined)?.duration ===\n          \"number\"\n            ? (result as unknown as { duration: number }).duration\n            : 0;\n\n        // Get error details\n        let errorMessage: string | undefined;\n        let errorStack: string | undefined;\n        let comparison: { expected?: string; actual?: string } = {};\n        if (state === \"failed\" && result) {\n          const errors = (result as { errors?: SerializedError[] }).errors;\n          if (errors?.length) {\n            const err = errors[0];\n            errorMessage = err.message;\n            errorStack = err.stack;\n            comparison = assertionComparison(err, { preformatted: true });\n          }\n        }\n\n        // Map Vitest state to raw status\n        const statusMap: Record<string, string> = {\n          passed: \"pass\",\n          failed: \"fail\",\n          skipped: \"skip\",\n          pending: \"pending\",\n          todo: \"pending\",\n        };\n\n        // Extract attachments from task.meta.storyAttachments\n        const taskMeta = test.meta() as Record<string, unknown>;\n        const scopedAttachments = (taskMeta?.storyAttachments ?? []) as Array<{\n          name: string;\n          mediaType: string;\n          path?: string;\n          body?: string;\n          encoding?: \"BASE64\" | \"IDENTITY\";\n          charset?: string;\n          fileName?: string;\n          stepIndex?: number;\n          stepId?: string;\n        }>;\n        const attachments: RawAttachment[] = scopedAttachments.map((a) => ({\n          name: a.name,\n          mediaType: a.mediaType,\n          path: a.path,\n          body: a.body,\n          encoding: a.encoding,\n          charset: a.charset,\n          fileName: a.fileName,\n          stepIndex: a.stepIndex,\n          stepId: a.stepId,\n        }));\n\n        // Extract step events (timing) from story steps\n        const stepEvents: RawStepEvent[] = meta.steps\n          .filter((s: { durationMs?: number }) => s.durationMs !== undefined)\n          .map((s: { durationMs?: number }, i: number) => ({\n            index: i,\n            title: (s as { text: string }).text,\n            durationMs: s.durationMs,\n          }));\n\n        // Read autotel OTel spans from task.meta.otelSpans\n        const otelSpans = taskMeta?.otelSpans;\n        if (Array.isArray(otelSpans) && otelSpans.length > 0) {\n          const valid = otelSpans.filter(\n            (s: unknown): s is OtelSpan =>\n              s != null &&\n              typeof s === \"object\" &&\n              typeof (s as Record<string, unknown>).spanId === \"string\" &&\n              typeof (s as Record<string, unknown>).name === \"string\",\n          );\n          if (valid.length > 0) {\n            meta.otelSpans = valid;\n          }\n        }\n\n        // Retry info from Vitest result\n        const retryCount = (result as { retryCount?: number } | undefined)?.retryCount ?? 0;\n        const configuredRetries = Math.max(\n          retryCount,\n          (test as { retries?: number }).retries ??\n            (test as { options?: { retry?: number } }).options?.retry ??\n            0,\n        );\n\n        testCases.push({\n          title: meta.scenario,\n          titlePath: meta.suitePath\n            ? [...meta.suitePath, meta.scenario]\n            : [meta.scenario],\n          story: meta,\n          sourceFile,\n          sourceLine: Math.max(1, meta.sourceOrder ?? 1),\n          status: (statusMap[state] ?? \"unknown\") as RawTestCase[\"status\"],\n          durationMs,\n          error: errorMessage\n            ? {\n                message: errorMessage,\n                stack: errorStack,\n                ...comparison,\n              }\n            : undefined,\n          attachments: attachments.length > 0 ? attachments : undefined,\n          stepEvents: stepEvents.length > 0 ? stepEvents : undefined,\n          retry: retryCount,\n          retries: configuredRetries,\n        });\n      }\n\n      if (moduleHasStoryTests) {\n        for (const test of plannedTests) {\n          const titlePath = test.fullName.split(\" > \");\n          testCases.push({\n            title: test.name,\n            titlePath,\n            story: {\n              scenario: test.name,\n              steps: [],\n              suitePath: titlePath.slice(0, -1),\n            },\n            sourceFile,\n            sourceLine: 1,\n            status: \"todo\",\n            durationMs: 0,\n          });\n        }\n      }\n    }\n\n    return testCases;\n  }\n\n  private getStoryMeta(test: TestCase): StoryMeta | undefined {\n    const meta = test.meta() as Record<string, unknown>;\n    return meta?.[\"story\"] as StoryMeta | undefined;\n  }\n\n  private async appendGithubSummary(reportText: string): Promise<void> {\n    try {\n      const { summary } = await import(\"@actions/core\");\n      summary.addRaw(reportText);\n      await summary.write();\n    } catch {\n      // @actions/core not available or not in Actions\n    }\n  }\n}\n\n// ============================================================================\n// Factory Function (recommended API)\n// ============================================================================\n// Type-safe factory for creating story reporters. Returns a properly-typed\n// instance that implements StoryReporterProtocol, enabling clean usage in\n// vite.config.ts without type casts.\n//\n// Usage:\n//   import { createStoryReporter } from 'executable-stories-vitest/reporter';\n//   export default defineConfig({\n//     test: {\n//       reporters: [\n//         'default',\n//         createStoryReporter({\n//           formats: ['html', 'markdown'],\n//           outputDir: 'reports',\n//         }),\n//       ],\n//     },\n//   });\n// ============================================================================\n\nexport function createStoryReporter(\n  options?: StoryReporterOptions\n): StoryReporterProtocol {\n  return new StoryReporter(options);\n}\n\nexport { StoryReporter };\n\n/**\n * Read the feature declarations tests attached to their metadata.\n *\n * `story.feature(...)` runs in the worker, so the declaration travels on\n * `task.meta` like everything else. Every test in a file carries the same one;\n * keying by the module's path collapses them back to one per file.\n */\nfunction collectFeatures(\n  testModules: ReadonlyArray<TestModule>,\n  root: string\n): RawFeature[] {\n  const byFile = new Map<string, RawFeature>();\n\n  for (const mod of testModules) {\n    const collection = mod.children;\n    if (!collection) continue;\n\n    const moduleId =\n      mod.moduleId ?? (mod as { relativeModuleId?: string }).relativeModuleId ?? \"\";\n    const absoluteModuleId = path.isAbsolute(moduleId)\n      ? moduleId\n      : path.resolve(root, moduleId);\n    const sourceFile = toRelativePosix(absoluteModuleId, root);\n\n    for (const test of collection.allTests()) {\n      const declared = (test.meta() as { storyFeature?: RawFeature } | undefined)?.storyFeature;\n      if (declared?.title) {\n        byFile.set(sourceFile, { ...declared, sourceFile });\n        break;\n      }\n    }\n  }\n\n  return [...byFile.values()];\n}\n"],"mappings":"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","names":[]}