/** Explicit, portable navigation metadata. Never derive identities from prose. */ type ReferencePresentation = { label: string; href: string; url?: string; imageUrl?: string; objectIcon?: string; }; export type WorkspaceReference = ReferencePresentation & ( | { kind: "crm-entry"; objectName: string; entryId: string } | { kind: "crm-object"; objectName: string; objectId?: string } | { kind: "campaign"; sequenceId: string } ); export type WorkspaceReferenceCoverage = { returned: number; /** References available in this result, never the total matching dataset. */ available: number; truncated: boolean; }; export type WorkspaceReferences = { references: WorkspaceReference[]; referenceCoverage: WorkspaceReferenceCoverage; }; export const WORKSPACE_REFERENCE_LIMIT = 100; export const WORKSPACE_REFERENCE_BYTE_LIMIT = 16 * 1024; export function workspaceReferenceKey(reference: WorkspaceReference): string { if (reference.kind === "campaign") return `campaign:${reference.sequenceId}`; if (reference.kind === "crm-object") return `crm-object:${reference.objectName}`; return `crm-entry:${reference.objectName}:${reference.entryId}`; } export function workspaceReferenceHref( reference: | { kind: "crm-entry"; objectName: string; entryId: string } | { kind: "crm-object"; objectName: string } | { kind: "campaign"; sequenceId: string }, ): string { if (reference.kind === "campaign") return `/?path=${encodeURIComponent(`~outreach/sequences/${reference.sequenceId}`)}`; const object = encodeURIComponent(reference.objectName); return reference.kind === "crm-object" ? `/?path=${object}` : `/?path=${object}&entry=${object}:${encodeURIComponent(reference.entryId)}`; } export function withWorkspaceReferenceUrls( reference: WorkspaceReference, context: { host?: string; workspaceSlug?: string }, ): WorkspaceReference { const href = workspaceReferenceHref(reference); const { url: _oldUrl, ...rest } = reference; const slug = context.workspaceSlug?.trim(); const host = context.host?.trim(); if (!host || !slug) return { ...rest, href }; try { const origin = new URL( /^https?:\/\//i.test(host) ? host : `https://${host}`, ); if (!["http:", "https:"].includes(origin.protocol)) return { ...rest, href }; return { ...rest, href, url: `${origin.origin}/${encodeURIComponent(slug)}${href.slice(1)}`, }; } catch { return { ...rest, href }; } } const text = (value: unknown, max: number): value is string => typeof value === "string" && value.trim().length > 0 && value.length <= max; /** Validate typed metadata at the display boundary; ignore arbitrary ID fields. */ export function parseWorkspaceReference( value: unknown, ): WorkspaceReference | null { if (!value || typeof value !== "object" || Array.isArray(value)) return null; const row = value as Record; if (!text(row.label, 2048) || !text(row.href, 4096)) return null; const presentation: ReferencePresentation = { label: row.label, href: row.href, }; if (text(row.objectIcon, 128)) presentation.objectIcon = row.objectIcon; for (const key of ["imageUrl", "url"] as const) { if (!text(row[key], 4096)) continue; try { const url = new URL(row[key]); if (["http:", "https:"].includes(url.protocol)) presentation[key] = row[key]; } catch { /* optional invalid URLs do not make an identity valid */ } } let reference: WorkspaceReference; if (row.kind === "campaign" && text(row.sequenceId, 256)) { reference = { ...presentation, kind: "campaign", sequenceId: row.sequenceId, }; } else if ( row.kind === "crm-entry" && text(row.objectName, 256) && text(row.entryId, 256) ) { reference = { ...presentation, kind: "crm-entry", objectName: row.objectName, entryId: row.entryId, }; } else if (row.kind === "crm-object" && text(row.objectName, 256)) { reference = { ...presentation, kind: "crm-object", objectName: row.objectName, ...(text(row.objectId, 256) ? { objectId: row.objectId } : {}), }; } else return null; return reference.href === workspaceReferenceHref(reference) ? reference : null; } /** Bound complete serialized metadata, including its coverage, in UTF-8 bytes. */ export function boundWorkspaceReferences( candidates: readonly WorkspaceReference[], available?: number, ): WorkspaceReferences { const unique = new Map(); for (const candidate of candidates) { const reference = parseWorkspaceReference(candidate); if (reference) unique.set(workspaceReferenceKey(reference), reference); } const count = Math.max( unique.size, typeof available === "number" && Number.isFinite(available) ? Math.max(0, Math.trunc(available)) : unique.size, ); const result: WorkspaceReferences = { references: [], referenceCoverage: { returned: 0, available: count, truncated: count > 0 }, }; const encoder = new TextEncoder(); for (const reference of unique.values()) { if (result.references.length >= WORKSPACE_REFERENCE_LIMIT) break; result.references.push(reference); result.referenceCoverage.returned = result.references.length; result.referenceCoverage.truncated = result.references.length < count; if ( encoder.encode(JSON.stringify(result)).byteLength > WORKSPACE_REFERENCE_BYTE_LIMIT ) { result.references.pop(); result.referenceCoverage.returned = result.references.length; result.referenceCoverage.truncated = result.references.length < count; break; } } return result; } /** Add shareable links only to the explicit envelope, never inside user data. */ export function withWorkspaceReferenceEnvelopeUrls( value: unknown, context: { host?: string; workspaceSlug?: string }, ): unknown { if (!value || typeof value !== "object" || Array.isArray(value)) return value; const record = value as Record; if (!Array.isArray(record.references)) return value; const coverage = record.referenceCoverage as | Partial | undefined; if ( !coverage || typeof coverage !== "object" || Array.isArray(coverage) || !Number.isSafeInteger(coverage.returned) || coverage.returned !== record.references.length || typeof coverage.available !== "number" || !Number.isSafeInteger(coverage.available) || coverage.available < coverage.returned || typeof coverage.truncated !== "boolean" || coverage.truncated !== coverage.available > coverage.returned ) return value; const refs: WorkspaceReference[] = []; for (const raw of record.references) { const reference = parseWorkspaceReference(raw); if (!reference) return value; refs.push(withWorkspaceReferenceUrls(reference, context)); } const metadata = boundWorkspaceReferences(refs, coverage.available); return { ...record, ...metadata }; }