/** * Single source of truth for "what does clicking THIS row do?" across * the chat-adjacent surfaces (source chips, inline cards, search results). * * Lib-side refactor of the hub's `lib/utils/source-row-cta.ts`. Drops: * - `currentPlatform()` — host injects via `ctx.currentPlatform` * - `traceCompose()` logging — lib stays log-free; hosts can wrap * - `tableIdForDocumentType` — host injects via `ctx.tableIdForDocumentType` * * The contract: * - `icon` + `iconLabel` — for visual + a11y. Sourced from * `SOURCE_ICON_NAMES` keyed by the row's `sourceRepo` (config id), * resolved to a React component via `ICON_REGISTRY`. * - `href` — destination URL. `null` means "no public viewer; Ask is * the only action". Honors the inline card / chip / search bar's * existing fallback chain (externalUrl → in-app path → null) and * also runs `safeHref()` on the final value so a hostile RAG row * can't land `javascript:` / `data:` in the DOM. * - `askable` — whether the Ask drill-in flow can fire. Requires a * non-empty `id` AND a `documentType`. * - `chatRef` — pre-synthesized `ChatRef` for the Ask handler. */ import React from 'react'; import type { ChatRef } from '../chat-ref.types'; import type { ComposeContentUrl } from '../../../utils/content-href'; export interface SourceRowInput { /** RagTableConfig.id (e.g. 'blog-posts', 'financial-cap-table'). Drives * icon resolution via `SOURCE_ICON_NAMES` + `ICON_REGISTRY`. */ sourceRepo?: string | null; /** The config's `documentType` (e.g. 'blog_post', 'cap_table'). Drives * the Ask drill-in's `ChatRef.type`. */ documentType?: string | null; /** Primary-key value of the row (config.primaryKey). Required for Ask. */ id?: string | null; /** Display title. */ title: string; /** Resolved public URL when the row HAS a viewer. `null`/undefined when * the row has no public destination — surface decides Ask-only behavior. */ externalUrl?: string | null; /** Platform that owns `externalUrl`. */ targetPlatform?: string | null; /** In-app navigator path (e.g. `legal/fundraising/.../safe`). */ path?: string | null; } export interface SourceRowContext { /** Chat shell's base route — `/data-room`, `/knowledge-base`, etc. */ baseRoute?: string; /** Cross-platform target for the chip / card click. */ chipBasePlatform?: string; /** * Host-supplied current-platform identifier. Used as the * `targetPlatform` for path-based fallback URLs that point to the * host's own surface. When omitted, path-based fallback rows get a * `null` targetPlatform — consumers fall back to their legacy * origin-check. */ currentPlatform?: string | null; /** * Host-supplied reverse map: documentType → tableId. Used to derive * `sourceRepo` from `documentType` when the caller didn't supply it * (inline cards know `ref.type` but not `sourceRepo`). When omitted, * the resolver falls back to the documentType reverse-map miss and * keeps the FileText icon. */ tableIdForDocumentType?: (documentType: string) => string | null; /** * Host-supplied unified content-href resolver (`runtime.composeContentUrl`). * When provided, entity rows WITH a public `externalUrl` resolve their href * through it — so the host's `hostedTypes` / `overrides` route a chat card to * the SAME destination as the equivalent page-view card (in-app for hosted * types, the hub URL otherwise). When omitted, the row's `externalUrl` is used * verbatim (legacy). */ composeContentUrl?: ComposeContentUrl; /** * Host-supplied per-`documentType` doc-viewer targets — the UNIFIED, DYNAMIC * replacement for the single `chipBasePlatform`. Maps a doc-table documentType * (`'markdown'`, `'data_room_doc'`, …) → the platform whose PUBLIC doc viewer * hosts it + that viewer's base path. A doc chip with no `externalUrl` resolves * to `getBaseUrl(platform)//` PER ROW — so a chat mixing several * doc sources sends EACH to its own home (markdown→flamingo/knowledge-base, * data_room_doc→company-hub/data-room) instead of one static fallback for all. * Wins over `chipBasePlatform` when a row's documentType has an entry. */ docPlatformTargets?: Record; } export interface SourceRowCTA { /** Source icon component. Always defined — falls back to `FileText`. */ icon: React.ComponentType<{ className?: string; }>; /** Human-readable label for the icon. */ iconLabel: string; /** Resolved destination URL. `null` when the row has no openable * target. Already passed through `safeHref()`. */ href: string | null; /** Platform that owns the destination. `null` when the row has no * openable target OR the destination is external/unknown. */ targetPlatform: string | null; /** When true, the surface can fire the Ask drill-in flow for this row. */ askable: boolean; /** Pre-synthesized `ChatRef` for the Ask handler. `null` when not askable. */ chatRef: ChatRef | null; } /** * Build a `SourceRowContext` from a `ChatRuntime` + the surface's `baseRoute` / * `chipBasePlatform`. The runtime-derived fields (`currentPlatform`, `composeContentUrl`, * `docPlatformTargets`) are wired identically at every `resolveSourceRowCTA` call site * (source chips + inline cards), so they live here once — adding a ctx field is then a * one-line change instead of editing all three call sites. */ export declare function sourceRowCtxFromRuntime(runtime: { source?: string; composeContentUrl?: ComposeContentUrl; docPlatformTargets?: SourceRowContext['docPlatformTargets']; }, surface?: { baseRoute?: string; chipBasePlatform?: string; }): SourceRowContext; /** * Doc-table documentTypes — rows that carry an in-app `path` (not an entity * `externalUrl`) and resolve to a doc viewer. The SAME set an embedder keys its * `docPlatformTargets` map by (markdown = product docs, data_room_doc = data room), * declared once so the two can't silently diverge. */ export declare const DOC_TABLE_TYPES: readonly ["markdown", "data_room_doc"]; /** * Resolve the CTA contract for a row. Pure function — no DOM, no fetch, * no logging. Call from any surface (chip, card, search result) with the * same row shape and get the same answer back. */ export declare function resolveSourceRowCTA(row: SourceRowInput, ctx?: SourceRowContext): SourceRowCTA; /** * Convenience helper for callers that just need the source icon — * inline cards' tracking strip + the search-bar dropdown row, today. * * Single source of truth: every consumer (chips, search results, * inline cards) routes through `SOURCE_ICON_NAMES` + `ICON_REGISTRY`. * * Accepts a string for backward-compatibility with the single-arg call * shape — treated as `documentType`. */ export declare function resolveSourceIcon(input: { sourceRepo?: string | null; documentType?: string | null; } | string | null | undefined, ctx?: { tableIdForDocumentType?: (documentType: string) => string | null; }): { Icon: React.ComponentType<{ className?: string; }>; label: string; }; //# sourceMappingURL=source-row-cta.d.ts.map