// Connector logo registry — maps a stable `logo` id (from a connector's API descriptor) to the
// brand's real monochrome mark, plus a human label. The brand color is deliberately NOT stored
// here: it comes from the API (`brand_color`) so the descriptor stays the single source of truth.
// Unknown / empty ids resolve to FALLBACK (a neutral plug glyph).
//
// Most marks come from the `simple-icons` package: official 24x24 single-path monochrome brand
// glyphs that paint with `currentColor`, so ConnectorIcon / ConnectorBadge tint them with the
// connector's brand color. Slack, Salesforce, Outlook, and Canva are no longer distributed by
// the package (removed at the trademark holders' request), so their path data is vendored below in
// the same format. Brands with no published monochrome mark (Attio, Apollo.io, Hunter,
// Amplitude, Descript, Clay, Close, Docusign — whose current post-rebrand mark no icon pack
// ships) and the non-brand utilities (email, browser, MCP, fallback plug) keep simple custom
// glyphs. (Filename is `.tsx` because the entries are JSX — the spec's `registry.ts` can't hold
// JSX.)
import type { SimpleIcon } from "simple-icons";
import {
siAsana,
siBox,
siClickup,
siConfluence,
siDatadog,
siDiscord,
siDropbox,
siFigma,
siGithub,
siGitlab,
siGmail,
siGooglecalendar,
siGoogledrive,
siHubspot,
siJira,
siLinear,
siMixpanel,
siNotion,
siPagerduty,
siPosthog,
siQuickbooks,
siStripe,
siTelegram,
siWhatsapp,
siZendesk,
} from "simple-icons";
// `JSX` is global with the react-jsx runtime + @types/react.
type LogoComponent = () => JSX.Element;
export interface ConnectorRegistryEntry {
label: string;
logo: LogoComponent;
}
/** 24x24 single-path brand mark (simple-icons path format) painting with `currentColor`. */
function pathLogo(d: string): LogoComponent {
return () => (
);
}
function brand(icon: SimpleIcon): ConnectorRegistryEntry {
return { label: icon.title, logo: pathLogo(icon.path) };
}
// Path data vendored from simple-icons v9 (CC0) — these brands were later removed from the
// package and can't be imported from v16.
const SLACK_PATH =
"M5.042 15.165a2.528 2.528 0 0 1-2.52 2.523A2.528 2.528 0 0 1 0 15.165a2.527 2.527 0 0 1 2.522-2.52h2.52v2.52zM6.313 15.165a2.527 2.527 0 0 1 2.521-2.52 2.527 2.527 0 0 1 2.521 2.52v6.313A2.528 2.528 0 0 1 8.834 24a2.528 2.528 0 0 1-2.521-2.522v-6.313zM8.834 5.042a2.528 2.528 0 0 1-2.521-2.52A2.528 2.528 0 0 1 8.834 0a2.528 2.528 0 0 1 2.521 2.522v2.52H8.834zM8.834 6.313a2.528 2.528 0 0 1 2.521 2.521 2.528 2.528 0 0 1-2.521 2.521H2.522A2.528 2.528 0 0 1 0 8.834a2.528 2.528 0 0 1 2.522-2.521h6.312zM18.956 8.834a2.528 2.528 0 0 1 2.522-2.521A2.528 2.528 0 0 1 24 8.834a2.528 2.528 0 0 1-2.522 2.521h-2.522V8.834zM17.688 8.834a2.528 2.528 0 0 1-2.523 2.521 2.527 2.527 0 0 1-2.52-2.521V2.522A2.527 2.527 0 0 1 15.165 0a2.528 2.528 0 0 1 2.523 2.522v6.312zM15.165 18.956a2.528 2.528 0 0 1 2.523 2.522A2.528 2.528 0 0 1 15.165 24a2.527 2.527 0 0 1-2.52-2.522v-2.522h2.52zM15.165 17.688a2.527 2.527 0 0 1-2.52-2.523 2.526 2.526 0 0 1 2.52-2.52h6.313A2.527 2.527 0 0 1 24 15.165a2.528 2.528 0 0 1-2.522 2.523h-6.313z";
const SALESFORCE_PATH =
"M10.006 5.415a4.195 4.195 0 013.045-1.306c1.56 0 2.954.9 3.69 2.205.63-.3 1.35-.45 2.1-.45 2.85 0 5.159 2.34 5.159 5.22s-2.31 5.22-5.176 5.22c-.345 0-.69-.044-1.02-.104a3.75 3.75 0 01-3.3 1.95c-.6 0-1.155-.15-1.65-.375A4.314 4.314 0 018.88 20.4a4.302 4.302 0 01-4.05-2.82c-.27.062-.54.076-.825.076-2.204 0-4.005-1.8-4.005-4.05 0-1.5.811-2.805 2.01-3.51-.255-.57-.39-1.2-.39-1.846 0-2.58 2.1-4.65 4.65-4.65 1.53 0 2.85.705 3.72 1.8";
const CANVA_PATH =
"M12 0C5.373 0 0 5.373 0 12s5.373 12 12 12 12-5.373 12-12S18.627 0 12 0zM6.962 7.68c.754 0 1.337.549 1.405 1.2.069.583-.171 1.097-.822 1.406-.343.171-.48.172-.549.069-.034-.069 0-.137.069-.206.617-.514.617-.926.548-1.508-.034-.378-.308-.618-.583-.618-1.2 0-2.914 2.674-2.674 4.629.103.754.549 1.646 1.509 1.646.308 0 .65-.103.96-.24.5-.264.799-.47 1.097-.8-.073-.885.704-2.046 1.851-2.046.515 0 .926.205.96.583.068.514-.377.582-.514.582s-.378-.034-.378-.17c-.034-.138.309-.07.275-.378-.035-.206-.24-.274-.446-.274-.72 0-1.131.994-1.029 1.611.035.275.172.549.447.549.205 0 .514-.31.617-.755.068-.308.343-.514.583-.514.102 0 .17.034.205.171v.138c-.034.137-.137.548-.102.651 0 .069.034.171.17.171.092 0 .436-.18.777-.459.117-.59.253-1.298.253-1.357.034-.24.137-.48.617-.48.103 0 .171.034.205.171v.138l-.136.617c.445-.583 1.097-.994 1.508-.994.172 0 .309.102.309.274 0 .103 0 .274-.069.446-.137.377-.309.96-.412 1.474 0 .137.035.274.207.274.171 0 .685-.206 1.096-.754l.007-.004c-.002-.068-.007-.134-.007-.202 0-.411.035-.754.104-.994.068-.274.411-.514.617-.514.103 0 .205.069.205.171 0 .035 0 .103-.034.137-.137.446-.24.857-.24 1.269 0 .24.034.582.102.788 0 .034.035.069.07.069.068 0 .548-.445.89-1.028-.308-.206-.48-.549-.48-.96 0-.72.446-1.097.858-1.097.343 0 .617.24.617.72 0 .308-.103.65-.274.96h.102a.77.77 0 0 0 .584-.24.293.293 0 0 1 .134-.117c.335-.425.83-.74 1.41-.74.48 0 .924.205.959.582.068.515-.378.618-.515.618l-.002-.002c-.138 0-.377-.035-.377-.172 0-.137.309-.068.274-.376-.034-.206-.24-.275-.446-.275-.686 0-1.13.891-1.028 1.611.034.275.171.583.445.583.206 0 .515-.308.652-.754.068-.274.343-.514.583-.514.103 0 .17.034.205.171 0 .069 0 .206-.137.652-.17.308-.171.48-.137.617.034.274.171.48.309.583.034.034.068.102.068.102 0 .069-.034.138-.137.138-.034 0-.068 0-.103-.035-.514-.205-.72-.548-.789-.891-.205.24-.445.377-.72.377-.445 0-.89-.411-.96-.926a1.609 1.609 0 0 1 .075-.649c-.203.13-.422.203-.623.203h-.17c-.447.652-.927 1.098-1.27 1.303a.896.896 0 0 1-.377.104c-.068 0-.171-.035-.205-.104-.095-.152-.156-.392-.193-.667-.481.527-1.145.805-1.453.805-.343 0-.548-.206-.582-.55v-.376c.102-.754.377-1.2.377-1.337a.074.074 0 0 0-.069-.07c-.24 0-1.028.824-1.166 1.373l-.103.445c-.068.309-.377.515-.582.515-.103 0-.172-.035-.206-.172v-.137l.046-.233c-.435.31-.87.508-1.075.508-.308 0-.48-.172-.514-.412-.206.274-.445.412-.754.412-.352 0-.696-.24-.862-.593-.244.275-.523.553-.852.764-.48.309-1.028.549-1.68.549-.582 0-1.097-.309-1.371-.583-.412-.377-.651-.96-.686-1.509-.205-1.68.823-3.84 2.4-4.8.378-.205.755-.343 1.132-.343zm9.77 3.291c-.104 0-.172.172-.172.343 0 .274.137.583.309.755a1.74 1.74 0 0 0 .102-.583c0-.343-.137-.515-.24-.515z";
const OUTLOOK_PATH =
"M7.88 12.04q0 .45-.11.87-.1.41-.33.74-.22.33-.58.52-.37.2-.87.2t-.85-.2q-.35-.21-.57-.55-.22-.33-.33-.75-.1-.42-.1-.86t.1-.87q.1-.43.34-.76.22-.34.59-.54.36-.2.87-.2t.86.2q.35.21.57.55.22.34.31.77.1.43.1.88zM24 12v9.38q0 .46-.33.8-.33.32-.8.32H7.13q-.46 0-.8-.33-.32-.33-.32-.8V18H1q-.41 0-.7-.3-.3-.29-.3-.7V7q0-.41.3-.7Q.58 6 1 6h6.5V2.55q0-.44.3-.75.3-.3.75-.3h12.9q.44 0 .75.3.3.3.3.75V10.85l1.24.72h.01q.1.07.18.18.07.12.07.25zm-6-8.25v3h3v-3zm0 4.5v3h3v-3zm0 4.5v1.83l3.05-1.83zm-5.25-9v3h3.75v-3zm0 4.5v3h3.75v-3zm0 4.5v2.03l2.41 1.5 1.34-.8v-2.73zM9 3.75V6h2l.13.01.12.04v-2.3zM5.98 15.98q.9 0 1.6-.3.7-.32 1.19-.86.48-.55.73-1.28.25-.74.25-1.61 0-.83-.25-1.55-.24-.71-.71-1.24t-1.15-.83q-.68-.3-1.55-.3-.92 0-1.64.3-.71.3-1.2.85-.5.54-.75 1.3-.25.74-.25 1.63 0 .85.26 1.56.26.72.74 1.23.48.52 1.17.81.69.3 1.56.3zM7.5 21h12.39L12 16.08V17q0 .41-.3.7-.29.3-.7.3H7.5zm15-.13v-7.24l-5.9 3.54Z";
/** Shared shell for the custom stroke glyphs (utilities + brands with no published mono mark). */
function strokeLogo(children: JSX.Element): LogoComponent {
return () => (
);
}
const EmailLogo = strokeLogo(
<>
>,
);
const BrowserLogo = strokeLogo(
<>
>,
);
const McpLogo = strokeLogo(
<>
>,
);
const AttioLogo = strokeLogo(
<>
>,
);
// monday.com's mark is three staggered capsule bars; no simple-icons mono mark exists.
const MondayLogo = strokeLogo(
<>
>,
);
const AmplitudeLogo = strokeLogo(
<>
>,
);
const ApolloLogo = strokeLogo(
<>
>,
);
const DescriptLogo = strokeLogo(
<>
>,
);
const ClayLogo = strokeLogo(
<>
>,
);
const CloseLogo = strokeLogo(
<>
>,
);
const DocusignLogo = strokeLogo(
<>
>,
);
const HunterLogo = strokeLogo(
<>
>,
);
const PlugLogo = strokeLogo(
<>
>,
);
/** Neutral fallback for unknown / empty logo ids. */
export const FALLBACK: ConnectorRegistryEntry = { label: "Connector", logo: PlugLogo };
export const CONNECTORS: Record = {
// Real brand marks from simple-icons.
asana: brand(siAsana),
box: brand(siBox),
clickup: brand(siClickup),
confluence: brand(siConfluence),
datadog: brand(siDatadog),
discord: brand(siDiscord),
dropbox: brand(siDropbox),
figma: brand(siFigma),
github: brand(siGithub),
gitlab: brand(siGitlab),
gmail: brand(siGmail),
google_calendar: brand(siGooglecalendar),
google_drive: brand(siGoogledrive),
hubspot: brand(siHubspot),
jira: brand(siJira),
linear: brand(siLinear),
mixpanel: brand(siMixpanel),
notion: brand(siNotion),
pagerduty: brand(siPagerduty),
posthog: brand(siPosthog),
quickbooks: brand(siQuickbooks),
stripe: brand(siStripe),
telegram: brand(siTelegram),
whatsapp: brand(siWhatsapp),
zendesk: brand(siZendesk),
// Real brand marks vendored from simple-icons v9.
slack: { label: "Slack", logo: pathLogo(SLACK_PATH) },
salesforce: { label: "Salesforce", logo: pathLogo(SALESFORCE_PATH) },
outlook: { label: "Outlook", logo: pathLogo(OUTLOOK_PATH) },
canva: { label: "Canva", logo: pathLogo(CANVA_PATH) },
// No published monochrome mark — custom glyphs, tinted with the real brand color.
attio: { label: "Attio", logo: AttioLogo },
monday: { label: "monday.com", logo: MondayLogo },
descript: { label: "Descript", logo: DescriptLogo },
clay: { label: "Clay", logo: ClayLogo },
close: { label: "Close", logo: CloseLogo },
docusign: { label: "Docusign", logo: DocusignLogo },
amplitude: { label: "Amplitude", logo: AmplitudeLogo },
apollo: { label: "Apollo.io", logo: ApolloLogo },
hunter: { label: "Hunter", logo: HunterLogo },
// Non-brand utilities.
email: { label: "Email", logo: EmailLogo },
browser: { label: "Browser", logo: BrowserLogo },
mcp: { label: "MCP", logo: McpLogo },
};
/**
* Resolve a logo id to its registry entry plus the matched key. Unknown / empty ids return the
* FALLBACK entry with key `"fallback"` (so callers and tests can distinguish a hit from a miss).
*/
export function resolveConnector(logo?: string): { key: string; entry: ConnectorRegistryEntry } {
const id = (logo ?? "").trim();
if (id && Object.prototype.hasOwnProperty.call(CONNECTORS, id)) {
return { key: id, entry: CONNECTORS[id] };
}
return { key: "fallback", entry: FALLBACK };
}