Unified · Split
| @@ -6,7 +6,7 @@ import { cn } from "../lib/utils"; · 5 unmodified lines | |||
| 6 | import { IconPlus, IconCopy, IconCheck } from "./icons"; | 6 | import { IconPlus, IconCopy, IconCheck } from "./icons"; |
| 7 | import { LoadableBlock } from "./loadable"; | 7 | import { LoadableBlock } from "./loadable"; |
| 8 | import { SourceFavicon } from "./source-favicon"; | 8 | import { SourceFavicon } from "./source-favicon"; |
| 9 | import { getSourceFrontendPaths } from "../source-plugins"; | 9 | import { getSourceFrontendPaths } from "../plugins"; |
| 10 | 10 | ||
| 11 | // ── Status dot color ───────────────────────────────────────────────────── | 11 | // ── Status dot color ───────────────────────────────────────────────────── |
| 12 | 12 | ||
| @@ -324,7 +324,7 @@ function SourceItem(props: { · 311 unmodified lines | |||
| 324 | return ( | 324 | return ( |
| 325 | <div className="group flex items-center gap-2 rounded-md px-2.5 py-1.5 text-[13px] text-sidebar-foreground/60"> | 325 | <div className="group flex items-center gap-2 rounded-md px-2.5 py-1.5 text-[13px] text-sidebar-foreground/60"> |
| 326 | <div className="flex size-3 shrink-0 items-center justify-center text-muted-foreground/50"> | 326 | <div className="flex size-3 shrink-0 items-center justify-center text-muted-foreground/50"> |
| 327 | <SourceFavicon kind={props.source.kind} className="size-3" /> | 327 | <SourceFavicon source={props.source} className="size-3" /> |
| 328 | </div> | 328 | </div> |
| 329 | <span className="flex-1 truncate">{props.source.name}</span> | 329 | <span className="flex-1 truncate">{props.source.name}</span> |
| 330 | <span | 330 | <span |
| @@ -352,7 +352,7 @@ function SourceItem(props: { · 21 unmodified lines | |||
| 352 | )} | 352 | )} |
| 353 | > | 353 | > |
| 354 | <div className="flex size-3 shrink-0 items-center justify-center text-muted-foreground/50"> | 354 | <div className="flex size-3 shrink-0 items-center justify-center text-muted-foreground/50"> |
| 355 | <SourceFavicon kind={props.source.kind} className="size-3" /> | 355 | <SourceFavicon source={props.source} className="size-3" /> |
| 356 | </div> | 356 | </div> |
| 357 | <span className="flex-1 truncate">{props.source.name}</span> | 357 | <span className="flex-1 truncate">{props.source.name}</span> |
| 358 | <span | 358 | <span |
| @@ -1,30 +1,25 @@ | |||
| 1 | import { useMemo, useState } from "react"; | 1 | import { useState } from "react"; |
| 2 | import type { Source } from "@executor/react"; | 2 | import type { Source } from "@executor/react"; |
| 3 | import { getGoogleProductIconUrl, getSourceFaviconUrl } from "../lib/source-favicon"; | 3 | import { getSourceFrontendIconUrl } from "../plugins"; |
| 4 | import { cn } from "../lib/utils"; | 4 | import { cn } from "../lib/utils"; |
| 5 | 5 | ||
| 6 | type SourceKind = Source["kind"] | string; | 6 | type SourceKind = Source["kind"] | string; |
| 7 | 7 | ||
| 8 | export function SourceFavicon({ | 8 | export function SourceFavicon({ |
| 9 | endpoint, | 9 | source, |
| 10 | kind: _kind, | ||
| 11 | className, | 10 | className, |
| 12 | size = 16, | 11 | size = 16, |
| 13 | }: { | 12 | }: { |
| 14 | endpoint?: string | null; | 13 | source: Source; |
| 15 | kind: SourceKind; | ||
| 16 | className?: string; | 14 | className?: string; |
| 17 | size?: number; | 15 | size?: number; |
| 18 | }) { | 16 | }) { |
| 19 | const faviconUrl = useMemo(() => { | 17 | const faviconUrl = getSourceFrontendIconUrl(source); |
| 20 | return getGoogleProductIconUrl(endpoint) ?? getSourceFaviconUrl(endpoint); | ||
| 21 | }, [endpoint]); | ||
| 22 | |||
| 23 | const [failedUrl, setFailedUrl] = useState<string | null>(null); | 18 | const [failedUrl, setFailedUrl] = useState<string | null>(null); |
| 24 | const isFailed = Boolean(faviconUrl && failedUrl === faviconUrl); | 19 | const isFailed = Boolean(faviconUrl && failedUrl === faviconUrl); |
| 25 | 20 | ||
| 26 | if (!faviconUrl || isFailed) { | 21 | if (!faviconUrl || isFailed) { |
| 27 | return <DefaultSourceIcon kind={_kind} className={className} />; | 22 | return <DefaultSourceIcon kind={source.kind} className={className} />; |
| 28 | } | 23 | } |
| 29 | 24 | ||
| 30 | return ( | 25 | return ( |
| @@ -1,123 +0,0 @@ | |||
| 1 | import { parse as parseDomain } from "tldts"; | ||
| 2 | |||
| 3 | const RAW_HOSTS = new Set([ | ||
| 4 | "raw.githubusercontent.com", | ||
| 5 | "cdn.jsdelivr.net", | ||
| 6 | "unpkg.com", | ||
| 7 | "raw.github.com", | ||
| 8 | ]); | ||
| 9 | |||
| 10 | // --------------------------------------------------------------------------- | ||
| 11 | // Google product icon URLs (official CDN assets) | ||
| 12 | // --------------------------------------------------------------------------- | ||
| 13 | |||
| 14 | const GOOGLE_SERVICE_ICONS: Record<string, string> = { | ||
| 15 | calendar: "https://ssl.gstatic.com/calendar/images/dynamiclogo_2020q4/calendar_31_2x.png", | ||
| 16 | drive: "https://ssl.gstatic.com/images/branding/product/2x/drive_2020q4_48dp.png", | ||
| 17 | gmail: "https://ssl.gstatic.com/ui/v1/icons/mail/rfr/gmail.ico", | ||
| 18 | docs: "https://ssl.gstatic.com/docs/documents/images/kix-favicon7.ico", | ||
| 19 | sheets: "https://ssl.gstatic.com/docs/spreadsheets/favicon3.ico", | ||
| 20 | slides: "https://ssl.gstatic.com/docs/presentations/images/favicon5.ico", | ||
| 21 | forms: "https://ssl.gstatic.com/docs/forms/device_home/android_192.png", | ||
| 22 | searchconsole: "https://ssl.gstatic.com/search-console/scfe/search_console-64.png", | ||
| 23 | people: "https://ssl.gstatic.com/images/branding/product/2x/contacts_2022_48dp.png", | ||
| 24 | tasks: "https://ssl.gstatic.com/tasks/images/favicon.ico", | ||
| 25 | chat: "https://ssl.gstatic.com/chat/favicon/favicon_v2.ico", | ||
| 26 | keep: "https://ssl.gstatic.com/keep/icon_2020q4v2_128.png", | ||
| 27 | classroom: "https://ssl.gstatic.com/classroom/favicon.png", | ||
| 28 | admin: "https://ssl.gstatic.com/images/branding/product/2x/admin_2020q4_48dp.png", | ||
| 29 | script: "https://ssl.gstatic.com/script/images/favicon.ico", | ||
| 30 | bigquery: "https://ssl.gstatic.com/bqui1/favicon.ico", | ||
| 31 | cloudresourcemanager: "https://www.gstatic.com/devrel-devsite/prod/v0e0f589edd85502a40d78d7d0825db8ea5ef3b99b1571571945f0f3f764ff61b/cloud/images/favicons/onecloud/favicon.ico", | ||
| 32 | youtube: "https://www.youtube.com/s/desktop/a94e1818/img/favicon_32x32.png", | ||
| 33 | }; | ||
| 34 | |||
| 35 | /** | ||
| 36 | * For google_discovery endpoints, extract the service name and return | ||
| 37 | * the official product icon URL if we have one. | ||
| 38 | */ | ||
| 39 | const getGoogleServiceIconUrl = (endpoint: string | null | undefined): string | null => { | ||
| 40 | if (!endpoint) return null; | ||
| 41 | try { | ||
| 42 | const url = new URL(endpoint); | ||
| 43 | const host = url.hostname; | ||
| 44 | |||
| 45 | // Direct service subdomain: "calendar-json.googleapis.com", "gmail.googleapis.com" | ||
| 46 | if (host.endsWith(".googleapis.com")) { | ||
| 47 | const sub = host.replace(/\.googleapis\.com$/, "").replace(/-json$/, ""); | ||
| 48 | if (GOOGLE_SERVICE_ICONS[sub]) return GOOGLE_SERVICE_ICONS[sub]; | ||
| 49 | } | ||
| 50 | |||
| 51 | // Discovery URL pattern: /discovery/v1/apis/{service}/{version}/rest | ||
| 52 | const discoveryMatch = url.pathname.match(/\/apis\/([^/]+)\//); | ||
| 53 | if (discoveryMatch?.[1] && GOOGLE_SERVICE_ICONS[discoveryMatch[1]]) { | ||
| 54 | return GOOGLE_SERVICE_ICONS[discoveryMatch[1]]; | ||
| 55 | } | ||
| 56 | |||
| 57 | // $discovery/rest pattern on service subdomains is already handled above | ||
| 58 | } catch { | ||
| 59 | // fall through | ||
| 60 | } | ||
| 61 | return null; | ||
| 62 | }; | ||
| 63 | |||
| 64 | // --------------------------------------------------------------------------- | ||
| 65 | // General favicon resolution | ||
| 66 | // --------------------------------------------------------------------------- | ||
| 67 | |||
| 68 | const parseUrl = (value: string | null | undefined): URL | null => { | ||
| 69 | if (!value) { | ||
| 70 | return null; | ||
| 71 | } | ||
| 72 | |||
| 73 | try { | ||
| 74 | return new URL(value); | ||
| 75 | } catch { | ||
| 76 | return null; | ||
| 77 | } | ||
| 78 | }; | ||
| 79 | |||
| 80 | const normalizeSeedUrl = (value: string | null | undefined): string | null => { | ||
| 81 | const parsed = parseUrl(value); | ||
| 82 | if (!parsed) { | ||
| 83 | return null; | ||
| 84 | } | ||
| 85 | |||
| 86 | if (!RAW_HOSTS.has(parsed.hostname)) { | ||
| 87 | return parsed.origin; | ||
| 88 | } | ||
| 89 | |||
| 90 | const segments = parsed.pathname | ||
| 91 | .split("/") | ||
| 92 | .map((segment) => segment.trim()) | ||
| 93 | .filter((segment) => segment.length > 0); | ||
| 94 | |||
| 95 | for (const segment of segments) { | ||
| 96 | const withoutExtension = segment.replace(/\.(ya?ml|json)$/i, ""); | ||
| 97 | if (/^[a-z0-9-]+(\.[a-z0-9-]+)+$/i.test(withoutExtension)) { | ||
| 98 | return `https://${withoutExtension}`; | ||
| 99 | } | ||
| 100 | } | ||
| 101 | |||
| 102 | return parsed.origin; | ||
| 103 | }; | ||
| 104 | |||
| 105 | export const getGoogleProductIconUrl = getGoogleServiceIconUrl; | ||
| 106 | |||
| 107 | export const getSourceFaviconUrl = ( | ||
| 108 | value: string | null | undefined, | ||
| 109 | ): string | null => { | ||
| 110 | const seedUrl = normalizeSeedUrl(value); | ||
| 111 | if (!seedUrl) { | ||
| 112 | return null; | ||
| 113 | } | ||
| 114 | |||
| 115 | try { | ||
| 116 | const hostname = new URL(seedUrl).hostname; | ||
| 117 | const parsed = parseDomain(hostname); | ||
| 118 | const domain = parsed.domain ?? hostname; | ||
| 119 | return `https://www.google.com/s2/favicons?domain=${encodeURIComponent(domain)}&sz=32`; | ||
| 120 | } catch { | ||
| 121 | return null; | ||
| 122 | } | ||
| 123 | }; | ||
| @@ -24,7 +24,7 @@ import { AppShell } from "./components/shell"; · 23 unmodified lines | |||
| 24 | import { | 24 | import { |
| 25 | registeredFrontendPluginRoutes, | 25 | registeredFrontendPluginRoutes, |
| 26 | registeredSourceFrontendTypes, | 26 | registeredSourceFrontendTypes, |
| 27 | } from "./source-plugins"; | 27 | } from "./plugins"; |
| 28 | import { | 28 | import { |
| 29 | ExecutorPluginRoutePage, | 29 | ExecutorPluginRoutePage, |
| 30 | SourcePluginAddPage, | 30 | SourcePluginAddPage, |
| @@ -32,7 +32,7 @@ import { · 1 unmodified line | |||
| 32 | SourcePluginDetailPage, | 32 | SourcePluginDetailPage, |
| 33 | SourcePluginEditPage, | 33 | SourcePluginEditPage, |
| 34 | SourcePluginsIndexPage, | 34 | SourcePluginsIndexPage, |
| 35 | } from "./source-plugins/pages"; | 35 | } from "./plugins/pages"; |
| 36 | import { HomePage } from "./views/home"; | 36 | import { HomePage } from "./views/home"; |
| 37 | import { SecretsPage } from "./views/secrets"; | 37 | import { SecretsPage } from "./views/secrets"; |
| 38 | 38 | ||
| @@ -1,3 +1,4 @@ | |||
| 1 | import type { Source } from "@executor/react"; | ||
| 1 | import { | 2 | import { |
| 2 | GoogleDiscoveryReactPlugin, | 3 | GoogleDiscoveryReactPlugin, |
| 3 | } from "@executor/plugin-google-discovery-react"; | 4 | } from "@executor/plugin-google-discovery-react"; |
| @@ -59,3 +60,6 @@ export const getSourceFrontendPaths = (kind: string) => { · 55 unmodified lines | |||
| 59 | const definition = getSourceFrontendType(kind); | 60 | const definition = getSourceFrontendType(kind); |
| 60 | return definition ? createSourcePluginPaths(definition.key) : null; | 61 | return definition ? createSourcePluginPaths(definition.key) : null; |
| 61 | }; | 62 | }; |
| 63 | |||
| 64 | export const getSourceFrontendIconUrl = (source: Source) => | ||
| 65 | getSourceFrontendTypeEntry(source.kind)?.definition.getIconUrl?.(source) ?? null; | ||
File renamed without changes.
| @@ -8,7 +8,7 @@ import { SourcePluginsResetState } from "../components/source-plugins-reset-stat · 7 unmodified lines | |||
| 8 | import { | 8 | import { |
| 9 | getSourceFrontendPaths, | 9 | getSourceFrontendPaths, |
| 10 | registeredSourceFrontendTypes, | 10 | registeredSourceFrontendTypes, |
| 11 | } from "../source-plugins"; | 11 | } from "../plugins"; |
| 12 | 12 | ||
| 13 | export function HomePage() { | 13 | export function HomePage() { |
| 14 | const sources = useSources(); | 14 | const sources = useSources(); |
| @@ -123,18 +123,6 @@ · 122 unmodified lines | |||
| 123 | "bun-types": "catalog:", | 123 | "bun-types": "catalog:", |
| 124 | }, | 124 | }, |
| 125 | }, | 125 | }, |
| 126 | "packages/auth/mcp-oauth": { | ||
| 127 | "name": "@executor/auth-mcp-oauth", | ||
| 128 | "version": "0.0.0", | ||
| 129 | "dependencies": { | ||
| 130 | "@modelcontextprotocol/sdk": "^1.26.0", | ||
| 131 | "effect": "catalog:", | ||
| 132 | }, | ||
| 133 | "devDependencies": { | ||
| 134 | "@types/node": "catalog:", | ||
| 135 | "bun-types": "catalog:", | ||
| 136 | }, | ||
| 137 | }, | ||
| 138 | "packages/clients/react": { | 126 | "packages/clients/react": { |
| 139 | "name": "@executor/react", | 127 | "name": "@executor/react", |
| 140 | "version": "0.0.0", | 128 | "version": "0.0.0", |
| @@ -587,7 +575,6 @@ · 446 unmodified lines | |||
| 587 | "name": "@executor/plugin-mcp-sdk", | 575 | "name": "@executor/plugin-mcp-sdk", |
| 588 | "version": "0.0.0", | 576 | "version": "0.0.0", |
| 589 | "dependencies": { | 577 | "dependencies": { |
| 590 | "@executor/auth-mcp-oauth": "workspace:*", | ||
| 591 | "@executor/codemode-core": "workspace:*", | 578 | "@executor/codemode-core": "workspace:*", |
| 592 | "@executor/ir": "workspace:*", | 579 | "@executor/ir": "workspace:*", |
| 593 | "@executor/platform-sdk": "workspace:*", | 580 | "@executor/platform-sdk": "workspace:*", |
| @@ -883,8 +870,6 @@ · 289 unmodified lines | |||
| 883 | 870 | ||
| 884 | "@executor/ai-sdk-adapter": ["@executor/ai-sdk-adapter@workspace:packages/hosts/ai-sdk"], | 871 | "@executor/ai-sdk-adapter": ["@executor/ai-sdk-adapter@workspace:packages/hosts/ai-sdk"], |
| 885 | 872 | ||
| 886 | "@executor/auth-mcp-oauth": ["@executor/auth-mcp-oauth@workspace:packages/auth/mcp-oauth"], | ||
| 887 | |||
| 888 | "@executor/codemode-core": ["@executor/codemode-core@workspace:packages/kernel/core"], | 873 | "@executor/codemode-core": ["@executor/codemode-core@workspace:packages/kernel/core"], |
| 889 | 874 | ||
| 890 | "@executor/docs": ["@executor/docs@workspace:apps/docs"], | 875 | "@executor/docs": ["@executor/docs@workspace:apps/docs"], |
| @@ -1,23 +0,0 @@ | |||
| 1 | { | ||
| 2 | "name": "@executor/auth-mcp-oauth", | ||
| 3 | "private": true, | ||
| 4 | "type": "module", | ||
| 5 | "exports": { | ||
| 6 | ".": "./src/index.ts" | ||
| 7 | }, | ||
| 8 | "files": [ | ||
| 9 | "src" | ||
| 10 | ], | ||
| 11 | "scripts": { | ||
| 12 | "typecheck": "bunx tsc --noEmit -p tsconfig.json" | ||
| 13 | }, | ||
| 14 | "dependencies": { | ||
| 15 | "@modelcontextprotocol/sdk": "^1.26.0", | ||
| 16 | "effect": "catalog:" | ||
| 17 | }, | ||
| 18 | "devDependencies": { | ||
| 19 | "@types/node": "catalog:", | ||
| 20 | "bun-types": "catalog:" | ||
| 21 | }, | ||
| 22 | "version": "0.0.0" | ||
| 23 | } | ||
| @@ -1,19 +0,0 @@ | |||
| 1 | { | ||
| 2 | "compilerOptions": { | ||
| 3 | "target": "ES2022", | ||
| 4 | "module": "ESNext", | ||
| 5 | "moduleResolution": "Bundler", | ||
| 6 | "strict": true, | ||
| 7 | "skipLibCheck": true, | ||
| 8 | "noEmit": true, | ||
| 9 | "lib": ["ES2022"], | ||
| 10 | "types": ["bun-types", "node"] | ||
| 11 | }, | ||
| 12 | "include": [ | ||
| 13 | "src/**/*.ts", | ||
| 14 | "src/**/*.d.ts" | ||
| 15 | ], | ||
| 16 | "exclude": [ | ||
| 17 | "src/**/*.test.ts" | ||
| 18 | ] | ||
| 19 | } | ||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
| @@ -1 +1,104 @@ | |||
| 1 | export * from "../source-plugins/index"; | 1 | export type { |
| 2 | ExecutorFrontendPlugin, | ||
| 3 | ExecutorPluginNavigation, | ||
| 4 | ExecutorPluginRouteContextValue, | ||
| 5 | FrontendPluginRouteDefinition, | ||
| 6 | FrontendPluginRouteParams, | ||
| 7 | FrontendPluginRouteSearch, | ||
| 8 | FrontendSourceDetailRouteDefinition, | ||
| 9 | FrontendSourceTypeDefinition, | ||
| 10 | SourcePluginNavigation, | ||
| 11 | SourcePluginRouteContextValue, | ||
| 12 | SourcePluginRouteParams, | ||
| 13 | SourcePluginRouteSearch, | ||
| 14 | } from "./types"; | ||
| 15 | |||
| 16 | export { | ||
| 17 | createExecutorPluginPaths, | ||
| 18 | createSourcePluginPaths, | ||
| 19 | executorPluginBasePath, | ||
| 20 | executorPluginRoutePath, | ||
| 21 | executorPluginRoutePattern, | ||
| 22 | normalizeExecutorPluginPath, | ||
| 23 | normalizeSourcePluginPath, | ||
| 24 | sourcePluginAddPath, | ||
| 25 | sourcePluginChildPath, | ||
| 26 | sourcePluginChildPattern, | ||
| 27 | sourcePluginDetailPath, | ||
| 28 | sourcePluginDetailPattern, | ||
| 29 | sourcePluginEditPath, | ||
| 30 | sourcePluginEditPattern, | ||
| 31 | sourcePluginsIndexPath, | ||
| 32 | type ExecutorPluginPaths, | ||
| 33 | type SourcePluginPaths, | ||
| 34 | } from "./paths"; | ||
| 35 | |||
| 36 | export { | ||
| 37 | defineExecutorFrontendPlugin, | ||
| 38 | defineFrontendPluginRoute, | ||
| 39 | defineFrontendSourceType, | ||
| 40 | registerExecutorFrontendPlugins, | ||
| 41 | type RegisteredFrontendPluginRoute, | ||
| 42 | type RegisteredFrontendSourceType, | ||
| 43 | } from "./registry"; | ||
| 44 | |||
| 45 | export { | ||
| 46 | ExecutorPluginRouteProvider, | ||
| 47 | useExecutorPlugin, | ||
| 48 | useExecutorPluginNavigation, | ||
| 49 | useExecutorPluginPaths, | ||
| 50 | useExecutorPluginRoute, | ||
| 51 | useExecutorPluginRouteDefinition, | ||
| 52 | useExecutorPluginRouteParams, | ||
| 53 | useExecutorPluginSearch, | ||
| 54 | } from "./plugin-route-context"; | ||
| 55 | |||
| 56 | export { | ||
| 57 | SourcePluginRouteProvider, | ||
| 58 | useSourcePlugin, | ||
| 59 | useSourcePluginDefinition, | ||
| 60 | useSourcePluginNavigation, | ||
| 61 | useSourcePluginPaths, | ||
| 62 | useSourcePluginRoute, | ||
| 63 | useSourcePluginRouteParams, | ||
| 64 | useSourcePluginSearch, | ||
| 65 | } from "./route-context"; | ||
| 66 | |||
| 67 | export { | ||
| 68 | cn, | ||
| 69 | } from "./lib/cn"; | ||
| 70 | |||
| 71 | export { | ||
| 72 | Badge, | ||
| 73 | MethodBadge, | ||
| 74 | } from "./components/badge"; | ||
| 75 | export { | ||
| 76 | CodeBlock, | ||
| 77 | } from "./components/code-block"; | ||
| 78 | export { | ||
| 79 | DocumentPanel, | ||
| 80 | } from "./components/document-panel"; | ||
| 81 | export { | ||
| 82 | IconCheck, | ||
| 83 | IconChevron, | ||
| 84 | IconClose, | ||
| 85 | IconCopy, | ||
| 86 | IconEmpty, | ||
| 87 | IconFolder, | ||
| 88 | IconPencil, | ||
| 89 | IconSearch, | ||
| 90 | IconSpinner, | ||
| 91 | IconTool, | ||
| 92 | } from "./components/icons"; | ||
| 93 | export { | ||
| 94 | EmptyState, | ||
| 95 | LoadableBlock, | ||
| 96 | } from "./components/loadable"; | ||
| 97 | export { | ||
| 98 | Markdown, | ||
| 99 | } from "./components/markdown"; | ||
| 100 | export { | ||
| 101 | SourceToolExplorer, | ||
| 102 | type SourceToolExplorerSearch, | ||
| 103 | parseSourceToolExplorerSearch, | ||
| 104 | } from "./components/source-tool-explorer"; | ||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
| @@ -59,6 +59,7 @@ export type FrontendSourceTypeDefinition = { · 58 unmodified lines | |||
| 59 | kind: string; | 59 | kind: string; |
| 60 | displayName: string; | 60 | displayName: string; |
| 61 | description?: string; | 61 | description?: string; |
| 62 | getIconUrl?: (source: Source) => string | null; | ||
| 62 | renderAddPage: ComponentType; | 63 | renderAddPage: ComponentType; |
| 63 | renderEditPage?: ComponentType<{ source: Source }>; | 64 | renderEditPage?: ComponentType<{ source: Source }>; |
| 64 | renderDetailPage?: ComponentType<{ source: Source }>; | 65 | renderDetailPage?: ComponentType<{ source: Source }>; |
| @@ -1,104 +1 @@ | |||
| 1 | export type { | 1 | export * from "../plugins/index"; |
| 2 | ExecutorFrontendPlugin, | ||
| 3 | ExecutorPluginNavigation, | ||
| 4 | ExecutorPluginRouteContextValue, | ||
| 5 | FrontendPluginRouteDefinition, | ||
| 6 | FrontendPluginRouteParams, | ||
| 7 | FrontendPluginRouteSearch, | ||
| 8 | FrontendSourceDetailRouteDefinition, | ||
| 9 | FrontendSourceTypeDefinition, | ||
| 10 | SourcePluginNavigation, | ||
| 11 | SourcePluginRouteContextValue, | ||
| 12 | SourcePluginRouteParams, | ||
| 13 | SourcePluginRouteSearch, | ||
| 14 | } from "./types"; | ||
| 15 | |||
| 16 | export { | ||
| 17 | createExecutorPluginPaths, | ||
| 18 | createSourcePluginPaths, | ||
| 19 | executorPluginBasePath, | ||
| 20 | executorPluginRoutePath, | ||
| 21 | executorPluginRoutePattern, | ||
| 22 | normalizeExecutorPluginPath, | ||
| 23 | normalizeSourcePluginPath, | ||
| 24 | sourcePluginAddPath, | ||
| 25 | sourcePluginChildPath, | ||
| 26 | sourcePluginChildPattern, | ||
| 27 | sourcePluginDetailPath, | ||
| 28 | sourcePluginDetailPattern, | ||
| 29 | sourcePluginEditPath, | ||
| 30 | sourcePluginEditPattern, | ||
| 31 | sourcePluginsIndexPath, | ||
| 32 | type ExecutorPluginPaths, | ||
| 33 | type SourcePluginPaths, | ||
| 34 | } from "./paths"; | ||
| 35 | |||
| 36 | export { | ||
| 37 | defineExecutorFrontendPlugin, | ||
| 38 | defineFrontendPluginRoute, | ||
| 39 | defineFrontendSourceType, | ||
| 40 | registerExecutorFrontendPlugins, | ||
| 41 | type RegisteredFrontendPluginRoute, | ||
| 42 | type RegisteredFrontendSourceType, | ||
| 43 | } from "./registry"; | ||
| 44 | |||
| 45 | export { | ||
| 46 | ExecutorPluginRouteProvider, | ||
| 47 | useExecutorPlugin, | ||
| 48 | useExecutorPluginNavigation, | ||
| 49 | useExecutorPluginPaths, | ||
| 50 | useExecutorPluginRoute, | ||
| 51 | useExecutorPluginRouteDefinition, | ||
| 52 | useExecutorPluginRouteParams, | ||
| 53 | useExecutorPluginSearch, | ||
| 54 | } from "./plugin-route-context"; | ||
| 55 | |||
| 56 | export { | ||
| 57 | SourcePluginRouteProvider, | ||
| 58 | useSourcePlugin, | ||
| 59 | useSourcePluginDefinition, | ||
| 60 | useSourcePluginNavigation, | ||
| 61 | useSourcePluginPaths, | ||
| 62 | useSourcePluginRoute, | ||
| 63 | useSourcePluginRouteParams, | ||
| 64 | useSourcePluginSearch, | ||
| 65 | } from "./route-context"; | ||
| 66 | |||
| 67 | export { | ||
| 68 | cn, | ||
| 69 | } from "./lib/cn"; | ||
| 70 | |||
| 71 | export { | ||
| 72 | Badge, | ||
| 73 | MethodBadge, | ||
| 74 | } from "./components/badge"; | ||
| 75 | export { | ||
| 76 | CodeBlock, | ||
| 77 | } from "./components/code-block"; | ||
| 78 | export { | ||
| 79 | DocumentPanel, | ||
| 80 | } from "./components/document-panel"; | ||
| 81 | export { | ||
| 82 | IconCheck, | ||
| 83 | IconChevron, | ||
| 84 | IconClose, | ||
| 85 | IconCopy, | ||
| 86 | IconEmpty, | ||
| 87 | IconFolder, | ||
| 88 | IconPencil, | ||
| 89 | IconSearch, | ||
| 90 | IconSpinner, | ||
| 91 | IconTool, | ||
| 92 | } from "./components/icons"; | ||
| 93 | export { | ||
| 94 | EmptyState, | ||
| 95 | LoadableBlock, | ||
| 96 | } from "./components/loadable"; | ||
| 97 | export { | ||
| 98 | Markdown, | ||
| 99 | } from "./components/markdown"; | ||
| 100 | export { | ||
| 101 | SourceToolExplorer, | ||
| 102 | type SourceToolExplorerSearch, | ||
| 103 | parseSourceToolExplorerSearch, | ||
| 104 | } from "./components/source-tool-explorer"; | ||
| @@ -25,6 +25,9 @@ import * as Effect from "effect/Effect"; · 24 unmodified lines | |||
| 25 | import * as Schema from "effect/Schema"; | 25 | import * as Schema from "effect/Schema"; |
| 26 | 26 | ||
| 27 | import { | 27 | import { |
| 28 | GOOGLE_DISCOVERY_EXECUTOR_KEY, | ||
| 29 | GOOGLE_DISCOVERY_OAUTH_STORAGE_PREFIX, | ||
| 30 | GOOGLE_DISCOVERY_PLUGIN_KEY, | ||
| 28 | GoogleDiscoveryConnectInputSchema, | 31 | GoogleDiscoveryConnectInputSchema, |
| 29 | GoogleDiscoveryOAuthPopupResultSchema, | 32 | GoogleDiscoveryOAuthPopupResultSchema, |
| 30 | GoogleDiscoverySourceConfigPayloadSchema, | 33 | GoogleDiscoverySourceConfigPayloadSchema, |
| @@ -39,7 +42,7 @@ import { · 8 unmodified lines | |||
| 39 | } from "@executor/plugin-google-discovery-shared"; | 42 | } from "@executor/plugin-google-discovery-shared"; |
| 40 | 43 | ||
| 41 | type GoogleDiscoveryExecutorExtension = { | 44 | type GoogleDiscoveryExecutorExtension = { |
| 42 | googleDiscovery: { | 45 | [GOOGLE_DISCOVERY_EXECUTOR_KEY]: { |
| 43 | createSource: ( | 46 | createSource: ( |
| 44 | input: GoogleDiscoveryConnectInput, | 47 | input: GoogleDiscoveryConnectInput, |
| 45 | ) => Effect.Effect<Source, Error>; | 48 | ) => Effect.Effect<Source, Error>; |
| @@ -77,7 +80,7 @@ const callbackParamsSchema = Schema.Struct({ · 31 unmodified lines | |||
| 77 | error_description: Schema.optional(Schema.String), | 80 | error_description: Schema.optional(Schema.String), |
| 78 | }); | 81 | }); |
| 79 | 82 | ||
| 80 | export const GoogleDiscoveryHttpGroup = HttpApiGroup.make("googleDiscovery") | 83 | export const GoogleDiscoveryHttpGroup = HttpApiGroup.make(GOOGLE_DISCOVERY_PLUGIN_KEY) |
| 81 | .add( | 84 | .add( |
| 82 | HttpApiEndpoint.post("createSource")`/workspaces/${workspaceIdParam}/plugins/google-discovery/sources` | 85 | HttpApiEndpoint.post("createSource")`/workspaces/${workspaceIdParam}/plugins/google-discovery/sources` |
| 83 | .setPayload(GoogleDiscoveryConnectInputSchema) | 86 | .setPayload(GoogleDiscoveryConnectInputSchema) |
| @@ -129,7 +132,7 @@ export const GoogleDiscoveryHttpGroup = HttpApiGroup.make("googleDiscovery") · 45 unmodified lines | |||
| 129 | .prefix("/v1"); | 132 | .prefix("/v1"); |
| 130 | 133 | ||
| 131 | export const googleDiscoveryHttpApiExtension = { | 134 | export const googleDiscoveryHttpApiExtension = { |
| 132 | key: "googleDiscovery", | 135 | key: GOOGLE_DISCOVERY_PLUGIN_KEY, |
| 133 | group: GoogleDiscoveryHttpGroup, | 136 | group: GoogleDiscoveryHttpGroup, |
| 134 | } satisfies ExecutorHttpApiExtension<typeof GoogleDiscoveryHttpGroup>; | 137 | } satisfies ExecutorHttpApiExtension<typeof GoogleDiscoveryHttpGroup>; |
| 135 | 138 | ||
| @@ -199,7 +202,7 @@ const popupDocument = (payload: GoogleDiscoveryOAuthPopupResult): string => { · 63 unmodified lines | |||
| 199 | (() => { | 202 | (() => { |
| 200 | const payload = ${serialized}; | 203 | const payload = ${serialized}; |
| 201 | try { | 204 | try { |
| 202 | window.localStorage.setItem("executor:google-discovery-oauth:" + (payload.ok ? payload.sessionId : "failed"), JSON.stringify(payload)); | 205 | window.localStorage.setItem("${GOOGLE_DISCOVERY_OAUTH_STORAGE_PREFIX}" + (payload.ok ? payload.sessionId : "failed"), JSON.stringify(payload)); |
| 203 | } catch {} | 206 | } catch {} |
| 204 | try { | 207 | try { |
| 205 | if (window.opener) { | 208 | if (window.opener) { |
| @@ -218,17 +221,19 @@ export const googleDiscoveryHttpPlugin = (): ExecutorHttpPlugin< · 12 unmodified lines | |||
| 218 | typeof GoogleDiscoveryHttpGroup, | 221 | typeof GoogleDiscoveryHttpGroup, |
| 219 | GoogleDiscoveryExecutorExtension | 222 | GoogleDiscoveryExecutorExtension |
| 220 | > => ({ | 223 | > => ({ |
| 221 | key: "googleDiscovery", | 224 | key: GOOGLE_DISCOVERY_PLUGIN_KEY, |
| 222 | group: GoogleDiscoveryHttpGroup, | 225 | group: GoogleDiscoveryHttpGroup, |
| 223 | build: ({ executor }) => | 226 | build: ({ executor }) => |
| 224 | HttpApiBuilder.group(GoogleDiscoveryHttpApi, "googleDiscovery", (handlers) => | 227 | HttpApiBuilder.group(GoogleDiscoveryHttpApi, GOOGLE_DISCOVERY_PLUGIN_KEY, (handlers) => |
| 225 | handlers | 228 | handlers |
| 226 | .handle("createSource", ({ path, payload }) => | 229 | .handle("createSource", ({ path, payload }) => |
| 227 | resolveRequestedLocalWorkspace( | 230 | resolveRequestedLocalWorkspace( |
| 228 | "googleDiscovery.createSource", | 231 | "googleDiscovery.createSource", |
| 229 | path.workspaceId, | 232 | path.workspaceId, |
| 230 | ).pipe( | 233 | ).pipe( |
| 231 | Effect.flatMap(() => executor.googleDiscovery.createSource(payload)), | 234 | Effect.flatMap(() => |
| 235 | executor[GOOGLE_DISCOVERY_EXECUTOR_KEY].createSource(payload) | ||
| 236 | ), | ||
| 232 | Effect.mapError((cause) => | 237 | Effect.mapError((cause) => |
| 233 | toStorageError("googleDiscovery.createSource", cause) | 238 | toStorageError("googleDiscovery.createSource", cause) |
| 234 | ), | 239 | ), |
| @@ -240,7 +245,9 @@ export const googleDiscoveryHttpPlugin = (): ExecutorHttpPlugin< · 5 unmodified lines | |||
| 240 | path.workspaceId, | 245 | path.workspaceId, |
| 241 | ).pipe( | 246 | ).pipe( |
| 242 | Effect.flatMap(() => | 247 | Effect.flatMap(() => |
| 243 | executor.googleDiscovery.getSourceConfig(path.sourceId) | 248 | executor[GOOGLE_DISCOVERY_EXECUTOR_KEY].getSourceConfig( |
| 249 | path.sourceId, | ||
| 250 | ) | ||
| 244 | ), | 251 | ), |
| 245 | Effect.mapError((cause) => | 252 | Effect.mapError((cause) => |
| 246 | mapPluginStorageError("googleDiscovery.getSourceConfig", cause) | 253 | mapPluginStorageError("googleDiscovery.getSourceConfig", cause) |
| @@ -253,7 +260,7 @@ export const googleDiscoveryHttpPlugin = (): ExecutorHttpPlugin< · 6 unmodified lines | |||
| 253 | path.workspaceId, | 260 | path.workspaceId, |
| 254 | ).pipe( | 261 | ).pipe( |
| 255 | Effect.flatMap(() => | 262 | Effect.flatMap(() => |
| 256 | executor.googleDiscovery.updateSource({ | 263 | executor[GOOGLE_DISCOVERY_EXECUTOR_KEY].updateSource({ |
| 257 | sourceId: path.sourceId, | 264 | sourceId: path.sourceId, |
| 258 | config: payload, | 265 | config: payload, |
| 259 | }) | 266 | }) |
| @@ -269,7 +276,9 @@ export const googleDiscoveryHttpPlugin = (): ExecutorHttpPlugin< · 9 unmodified lines | |||
| 269 | path.workspaceId, | 276 | path.workspaceId, |
| 270 | ).pipe( | 277 | ).pipe( |
| 271 | Effect.flatMap(() => | 278 | Effect.flatMap(() => |
| 272 | executor.googleDiscovery.removeSource(path.sourceId) | 279 | executor[GOOGLE_DISCOVERY_EXECUTOR_KEY].removeSource( |
| 280 | path.sourceId, | ||
| 281 | ) | ||
| 273 | ), | 282 | ), |
| 274 | Effect.map((removed) => ({ removed })), | 283 | Effect.map((removed) => ({ removed })), |
| 275 | Effect.mapError((cause) => | 284 | Effect.mapError((cause) => |
| @@ -282,14 +291,16 @@ export const googleDiscoveryHttpPlugin = (): ExecutorHttpPlugin< · 6 unmodified lines | |||
| 282 | "googleDiscovery.startOAuth", | 291 | "googleDiscovery.startOAuth", |
| 283 | path.workspaceId, | 292 | path.workspaceId, |
| 284 | ).pipe( | 293 | ).pipe( |
| 285 | Effect.flatMap(() => executor.googleDiscovery.startOAuth(payload)), | 294 | Effect.flatMap(() => |
| 295 | executor[GOOGLE_DISCOVERY_EXECUTOR_KEY].startOAuth(payload) | ||
| 296 | ), | ||
| 286 | Effect.mapError((cause) => | 297 | Effect.mapError((cause) => |
| 287 | toStorageError("googleDiscovery.startOAuth", cause) | 298 | toStorageError("googleDiscovery.startOAuth", cause) |
| 288 | ), | 299 | ), |
| 289 | ) | 300 | ) |
| 290 | ) | 301 | ) |
| 291 | .handle("oauthCallback", ({ urlParams }) => | 302 | .handle("oauthCallback", ({ urlParams }) => |
| 292 | executor.googleDiscovery.completeOAuth({ | 303 | executor[GOOGLE_DISCOVERY_EXECUTOR_KEY].completeOAuth({ |
| 293 | state: urlParams.state, | 304 | state: urlParams.state, |
| 294 | code: urlParams.code, | 305 | code: urlParams.code, |
| 295 | error: urlParams.error, | 306 | error: urlParams.error, |
| @@ -24,6 +24,10 @@ import { · 23 unmodified lines | |||
| 24 | googleDiscoveryHttpApiExtension, | 24 | googleDiscoveryHttpApiExtension, |
| 25 | } from "@executor/plugin-google-discovery-http"; | 25 | } from "@executor/plugin-google-discovery-http"; |
| 26 | import { | 26 | import { |
| 27 | GOOGLE_DISCOVERY_OAUTH_CALLBACK_PATH, | ||
| 28 | GOOGLE_DISCOVERY_OAUTH_STORAGE_PREFIX, | ||
| 29 | GOOGLE_DISCOVERY_PLUGIN_KEY, | ||
| 30 | GOOGLE_DISCOVERY_SOURCE_KIND, | ||
| 27 | defaultGoogleDiscoveryUrl, | 31 | defaultGoogleDiscoveryUrl, |
| 28 | type GoogleDiscoveryConnectInput, | 32 | type GoogleDiscoveryConnectInput, |
| 29 | type GoogleDiscoveryConnectionAuth, | 33 | type GoogleDiscoveryConnectionAuth, |
| @@ -31,9 +35,47 @@ import { · 1 unmodified line | |||
| 31 | type GoogleDiscoveryStartOAuthInput, | 35 | type GoogleDiscoveryStartOAuthInput, |
| 32 | } from "@executor/plugin-google-discovery-shared"; | 36 | } from "@executor/plugin-google-discovery-shared"; |
| 33 | 37 | ||
| 34 | const OAUTH_STORAGE_PREFIX = "executor:google-discovery-oauth:"; | ||
| 35 | const OAUTH_TIMEOUT_MS = 2 * 60_000; | 38 | const OAUTH_TIMEOUT_MS = 2 * 60_000; |
| 36 | 39 | ||
| 40 | const GOOGLE_DISCOVERY_SERVICE_ICONS: Record<string, string> = { | ||
| 41 | admin: "https://ssl.gstatic.com/images/branding/product/2x/admin_2020q4_48dp.png", | ||
| 42 | bigquery: "https://ssl.gstatic.com/bqui1/favicon.ico", | ||
| 43 | calendar: "https://ssl.gstatic.com/calendar/images/dynamiclogo_2020q4/calendar_31_2x.png", | ||
| 44 | chat: "https://ssl.gstatic.com/chat/favicon/favicon_v2.ico", | ||
| 45 | classroom: "https://ssl.gstatic.com/classroom/favicon.png", | ||
| 46 | cloudresourcemanager: "https://www.gstatic.com/devrel-devsite/prod/v0e0f589edd85502a40d78d7d0825db8ea5ef3b99b1571571945f0f3f764ff61b/cloud/images/favicons/onecloud/favicon.ico", | ||
| 47 | docs: "https://ssl.gstatic.com/docs/documents/images/kix-favicon7.ico", | ||
| 48 | drive: "https://ssl.gstatic.com/images/branding/product/2x/drive_2020q4_48dp.png", | ||
| 49 | forms: "https://ssl.gstatic.com/docs/forms/device_home/android_192.png", | ||
| 50 | gmail: "https://ssl.gstatic.com/ui/v1/icons/mail/rfr/gmail.ico", | ||
| 51 | keep: "https://ssl.gstatic.com/keep/icon_2020q4v2_128.png", | ||
| 52 | people: "https://ssl.gstatic.com/images/branding/product/2x/contacts_2022_48dp.png", | ||
| 53 | script: "https://ssl.gstatic.com/script/images/favicon.ico", | ||
| 54 | searchconsole: "https://ssl.gstatic.com/search-console/scfe/search_console-64.png", | ||
| 55 | sheets: "https://ssl.gstatic.com/docs/spreadsheets/favicon3.ico", | ||
| 56 | slides: "https://ssl.gstatic.com/docs/presentations/images/favicon5.ico", | ||
| 57 | tasks: "https://ssl.gstatic.com/tasks/images/favicon.ico", | ||
| 58 | youtube: "https://www.youtube.com/s/desktop/a94e1818/img/favicon_32x32.png", | ||
| 59 | }; | ||
| 60 | |||
| 61 | const getGoogleDiscoveryServiceKey = ( | ||
| 62 | source: Pick<Source, "namespace">, | ||
| 63 | ): string | null => { | ||
| 64 | const namespace = source.namespace?.trim(); | ||
| 65 | if (!namespace || !namespace.startsWith("google.")) { | ||
| 66 | return null; | ||
| 67 | } | ||
| 68 | |||
| 69 | return namespace.slice("google.".length).replaceAll(".", ""); | ||
| 70 | }; | ||
| 71 | |||
| 72 | const getGoogleDiscoveryIconUrl = ( | ||
| 73 | source: Pick<Source, "namespace">, | ||
| 74 | ): string | null => { | ||
| 75 | const serviceKey = getGoogleDiscoveryServiceKey(source); | ||
| 76 | return serviceKey ? GOOGLE_DISCOVERY_SERVICE_ICONS[serviceKey] ?? null : null; | ||
| 77 | }; | ||
| 78 | |||
| 37 | const getGoogleDiscoveryHttpClient = | 79 | const getGoogleDiscoveryHttpClient = |
| 38 | defineExecutorPluginHttpApiClient<"GoogleDiscoveryReactHttpClient">()( | 80 | defineExecutorPluginHttpApiClient<"GoogleDiscoveryReactHttpClient">()( |
| 39 | "GoogleDiscoveryReactHttpClient", | 81 | "GoogleDiscoveryReactHttpClient", |
| @@ -105,7 +147,7 @@ const waitForOauthPopupResult = async ( · 65 unmodified lines | |||
| 105 | sessionId: string, | 147 | sessionId: string, |
| 106 | ): Promise<GoogleDiscoveryOAuthPopupResult> => | 148 | ): Promise<GoogleDiscoveryOAuthPopupResult> => |
| 107 | new Promise((resolve, reject) => { | 149 | new Promise((resolve, reject) => { |
| 108 | const storageKey = `${OAUTH_STORAGE_PREFIX}${sessionId}`; | 150 | const storageKey = `${GOOGLE_DISCOVERY_OAUTH_STORAGE_PREFIX}${sessionId}`; |
| 109 | const startedAt = Date.now(); | 151 | const startedAt = Date.now(); |
| 110 | 152 | ||
| 111 | const cleanup = () => { | 153 | const cleanup = () => { |
| @@ -168,7 +210,7 @@ function GoogleDiscoverySourceForm(props: { · 56 unmodified lines | |||
| 168 | const client = getGoogleDiscoveryHttpClient(); | 210 | const client = getGoogleDiscoveryHttpClient(); |
| 169 | const secrets = useSecrets(); | 211 | const secrets = useSecrets(); |
| 170 | const startOAuth = useAtomSet( | 212 | const startOAuth = useAtomSet( |
| 171 | client.mutation("googleDiscovery", "startOAuth"), | 213 | client.mutation(GOOGLE_DISCOVERY_PLUGIN_KEY, "startOAuth"), |
| 172 | { mode: "promise" }, | 214 | { mode: "promise" }, |
| 173 | ); | 215 | ); |
| 174 | const submitMutation = useExecutorMutation<GoogleDiscoveryConnectInput, void>(props.onSubmit); | 216 | const submitMutation = useExecutorMutation<GoogleDiscoveryConnectInput, void>(props.onSubmit); |
| @@ -219,7 +261,7 @@ function GoogleDiscoverySourceForm(props: { · 44 unmodified lines | |||
| 219 | : null, | 261 | : null, |
| 220 | clientAuthentication: clientSecretRef ? "client_secret_post" : "none", | 262 | clientAuthentication: clientSecretRef ? "client_secret_post" : "none", |
| 221 | redirectUrl: new URL( | 263 | redirectUrl: new URL( |
| 222 | "/v1/plugins/google-discovery/oauth/callback", | 264 | GOOGLE_DISCOVERY_OAUTH_CALLBACK_PATH, |
| 223 | window.location.origin, | 265 | window.location.origin, |
| 224 | ).toString(), | 266 | ).toString(), |
| 225 | }; | 267 | }; |
| @@ -492,7 +534,7 @@ function GoogleDiscoveryAddPage() { · 266 unmodified lines | |||
| 492 | const installation = useLocalInstallation(); | 534 | const installation = useLocalInstallation(); |
| 493 | const client = getGoogleDiscoveryHttpClient(); | 535 | const client = getGoogleDiscoveryHttpClient(); |
| 494 | const createSource = useAtomSet( | 536 | const createSource = useAtomSet( |
| 495 | client.mutation("googleDiscovery", "createSource"), | 537 | client.mutation(GOOGLE_DISCOVERY_PLUGIN_KEY, "createSource"), |
| 496 | { mode: "promise" }, | 538 | { mode: "promise" }, |
| 497 | ); | 539 | ); |
| 498 | 540 | ||
| @@ -533,7 +575,7 @@ function GoogleDiscoveryEditPage(props: { · 34 unmodified lines | |||
| 533 | const client = getGoogleDiscoveryHttpClient(); | 575 | const client = getGoogleDiscoveryHttpClient(); |
| 534 | const configResult = useAtomValue( | 576 | const configResult = useAtomValue( |
| 535 | installation.status === "ready" | 577 | installation.status === "ready" |
| 536 | ? client.query("googleDiscovery", "getSourceConfig", { | 578 | ? client.query(GOOGLE_DISCOVERY_PLUGIN_KEY, "getSourceConfig", { |
| 537 | path: { | 579 | path: { |
| 538 | workspaceId: installation.data.scopeId, | 580 | workspaceId: installation.data.scopeId, |
| 539 | sourceId: props.source.id, | 581 | sourceId: props.source.id, |
| @@ -548,7 +590,7 @@ function GoogleDiscoveryEditPage(props: { · 8 unmodified lines | |||
| 548 | }) as never, | 590 | }) as never, |
| 549 | ); | 591 | ); |
| 550 | const updateSource = useAtomSet( | 592 | const updateSource = useAtomSet( |
| 551 | client.mutation("googleDiscovery", "updateSource"), | 593 | client.mutation(GOOGLE_DISCOVERY_PLUGIN_KEY, "updateSource"), |
| 552 | { mode: "promise" }, | 594 | { mode: "promise" }, |
| 553 | ); | 595 | ); |
| 554 | 596 | ||
| @@ -608,12 +650,12 @@ function GoogleDiscoveryDetailPage(props: { · 53 unmodified lines | |||
| 608 | const installation = useLocalInstallation(); | 650 | const installation = useLocalInstallation(); |
| 609 | const client = getGoogleDiscoveryHttpClient(); | 651 | const client = getGoogleDiscoveryHttpClient(); |
| 610 | const removeSource = useAtomSet( | 652 | const removeSource = useAtomSet( |
| 611 | client.mutation("googleDiscovery", "removeSource"), | 653 | client.mutation(GOOGLE_DISCOVERY_PLUGIN_KEY, "removeSource"), |
| 612 | { mode: "promise" }, | 654 | { mode: "promise" }, |
| 613 | ); | 655 | ); |
| 614 | const configResult = useAtomValue( | 656 | const configResult = useAtomValue( |
| 615 | installation.status === "ready" | 657 | installation.status === "ready" |
| 616 | ? client.query("googleDiscovery", "getSourceConfig", { | 658 | ? client.query(GOOGLE_DISCOVERY_PLUGIN_KEY, "getSourceConfig", { |
| 617 | path: { | 659 | path: { |
| 618 | workspaceId: installation.data.scopeId, | 660 | workspaceId: installation.data.scopeId, |
| 619 | sourceId: props.source.id, | 661 | sourceId: props.source.id, |
| @@ -710,16 +752,17 @@ function GoogleDiscoveryDetailPage(props: { · 90 unmodified lines | |||
| 710 | } | 752 | } |
| 711 | 753 | ||
| 712 | const googleDiscoverySourceType = defineFrontendSourceType({ | 754 | const googleDiscoverySourceType = defineFrontendSourceType({ |
| 713 | key: "google-discovery", | 755 | key: GOOGLE_DISCOVERY_PLUGIN_KEY, |
| 714 | kind: "google_discovery", | 756 | kind: GOOGLE_DISCOVERY_SOURCE_KIND, |
| 715 | displayName: "Google Discovery", | 757 | displayName: "Google Discovery", |
| 716 | description: "Import Google APIs from discovery documents with plugin-owned OAuth.", | 758 | description: "Import Google APIs from discovery documents with plugin-owned OAuth.", |
| 759 | getIconUrl: getGoogleDiscoveryIconUrl, | ||
| 717 | renderAddPage: GoogleDiscoveryAddPage, | 760 | renderAddPage: GoogleDiscoveryAddPage, |
| 718 | renderEditPage: GoogleDiscoveryEditPage, | 761 | renderEditPage: GoogleDiscoveryEditPage, |
| 719 | renderDetailPage: GoogleDiscoveryDetailPage, | 762 | renderDetailPage: GoogleDiscoveryDetailPage, |
| 720 | }); | 763 | }); |
| 721 | 764 | ||
| 722 | export const GoogleDiscoveryReactPlugin = defineExecutorFrontendPlugin({ | 765 | export const GoogleDiscoveryReactPlugin = defineExecutorFrontendPlugin({ |
| 723 | key: "google-discovery", | 766 | key: GOOGLE_DISCOVERY_PLUGIN_KEY, |
| 724 | sourceTypes: [googleDiscoverySourceType], | 767 | sourceTypes: [googleDiscoverySourceType], |
| 725 | }); | 768 | }); |
| @@ -38,6 +38,7 @@ import { · 37 unmodified lines | |||
| 38 | stableHash, | 38 | stableHash, |
| 39 | toolPathSegments, | 39 | toolPathSegments, |
| 40 | } from "@executor/source-core"; | 40 | } from "@executor/source-core"; |
| 41 | import { GOOGLE_DISCOVERY_SOURCE_KIND } from "@executor/plugin-google-discovery-shared"; | ||
| 41 | 42 | ||
| 42 | import type { GoogleDiscoveryToolProviderData } from "./types"; | 43 | import type { GoogleDiscoveryToolProviderData } from "./types"; |
| 43 | 44 | ||
| @@ -284,7 +285,7 @@ const createHttpCapabilityFromGoogleDiscovery = (input: { · 240 unmodified lines | |||
| 284 | id: executableId, | 285 | id: executableId, |
| 285 | capabilityId, | 286 | capabilityId, |
| 286 | scopeId: input.serviceScopeId, | 287 | scopeId: input.serviceScopeId, |
| 287 | pluginKey: "google_discovery", | 288 | pluginKey: GOOGLE_DISCOVERY_SOURCE_KIND, |
| 288 | bindingVersion: EXECUTABLE_BINDING_VERSION, | 289 | bindingVersion: EXECUTABLE_BINDING_VERSION, |
| 289 | binding: input.operation.providerData, | 290 | binding: input.operation.providerData, |
| 290 | projection: { | 291 | projection: { |
| @@ -384,7 +385,7 @@ export const createGoogleDiscoveryCatalogSnapshot = (input: { · 93 unmodified lines | |||
| 384 | createCatalogSnapshotV1FromFragments({ | 385 | createCatalogSnapshotV1FromFragments({ |
| 385 | import: createCatalogImportMetadata({ | 386 | import: createCatalogImportMetadata({ |
| 386 | source: input.source, | 387 | source: input.source, |
| 387 | pluginKey: "google_discovery", | 388 | pluginKey: GOOGLE_DISCOVERY_SOURCE_KIND, |
| 388 | }), | 389 | }), |
| 389 | fragments: [createGoogleDiscoveryCatalogFragment(input)], | 390 | fragments: [createGoogleDiscoveryCatalogFragment(input)], |
| 390 | }); | 391 | }); |
| @@ -20,6 +20,8 @@ import { · 19 unmodified lines | |||
| 20 | provideExecutorRuntime, | 20 | provideExecutorRuntime, |
| 21 | } from "@executor/platform-sdk/runtime"; | 21 | } from "@executor/platform-sdk/runtime"; |
| 22 | import { | 22 | import { |
| 23 | GOOGLE_DISCOVERY_EXECUTOR_KEY, | ||
| 24 | GOOGLE_DISCOVERY_SOURCE_KIND, | ||
| 23 | GoogleDiscoveryConnectionAuthSchema, | 25 | GoogleDiscoveryConnectionAuthSchema, |
| 24 | GoogleDiscoveryOAuthSessionSchema, | 26 | GoogleDiscoveryOAuthSessionSchema, |
| 25 | defaultGoogleDiscoveryUrl, | 27 | defaultGoogleDiscoveryUrl, |
| @@ -115,7 +117,7 @@ export type GoogleDiscoverySdk = { · 89 unmodified lines | |||
| 115 | }; | 117 | }; |
| 116 | 118 | ||
| 117 | const GoogleDiscoveryExecutorAddInputSchema = Schema.Struct({ | 119 | const GoogleDiscoveryExecutorAddInputSchema = Schema.Struct({ |
| 118 | kind: Schema.Literal("google_discovery"), | 120 | kind: Schema.Literal(GOOGLE_DISCOVERY_SOURCE_KIND), |
| 119 | name: Schema.String, | 121 | name: Schema.String, |
| 120 | service: Schema.String, | 122 | service: Schema.String, |
| 121 | version: Schema.String, | 123 | version: Schema.String, |
| @@ -476,7 +478,7 @@ const createGoogleDiscoverySourceSdk = ( · 354 unmodified lines | |||
| 476 | getSourceConfig: (sourceId: Source["id"]) => | 478 | getSourceConfig: (sourceId: Source["id"]) => |
| 477 | Effect.gen(function* () { | 479 | Effect.gen(function* () { |
| 478 | const source = yield* host.sources.get(sourceId); | 480 | const source = yield* host.sources.get(sourceId); |
| 479 | if (source.kind !== "google_discovery") { | 481 | if (source.kind !== GOOGLE_DISCOVERY_SOURCE_KIND) { |
| 480 | return yield* Effect.fail( | 482 | return yield* Effect.fail( |
| 481 | new Error(`Source ${sourceId} is not a Google Discovery source.`), | 483 | new Error(`Source ${sourceId} is not a Google Discovery source.`), |
| 482 | ); | 484 | ); |
| @@ -500,7 +502,7 @@ const createGoogleDiscoverySourceSdk = ( · 17 unmodified lines | |||
| 500 | const createdSource = yield* host.sources.create({ | 502 | const createdSource = yield* host.sources.create({ |
| 501 | source: { | 503 | source: { |
| 502 | name: input.name.trim(), | 504 | name: input.name.trim(), |
| 503 | kind: "google_discovery", | 505 | kind: GOOGLE_DISCOVERY_SOURCE_KIND, |
| 504 | status: "connected", | 506 | status: "connected", |
| 505 | enabled: true, | 507 | enabled: true, |
| 506 | namespace: deriveGoogleDiscoveryNamespace(input.service), | 508 | namespace: deriveGoogleDiscoveryNamespace(input.service), |
| @@ -518,7 +520,7 @@ const createGoogleDiscoverySourceSdk = ( · 11 unmodified lines | |||
| 518 | updateSource: (input: GoogleDiscoveryUpdateSourceInput) => | 520 | updateSource: (input: GoogleDiscoveryUpdateSourceInput) => |
| 519 | Effect.gen(function* () { | 521 | Effect.gen(function* () { |
| 520 | const source = yield* host.sources.get(input.sourceId as Source["id"]); | 522 | const source = yield* host.sources.get(input.sourceId as Source["id"]); |
| 521 | if (source.kind !== "google_discovery") { | 523 | if (source.kind !== GOOGLE_DISCOVERY_SOURCE_KIND) { |
| 522 | return yield* Effect.fail( | 524 | return yield* Effect.fail( |
| 523 | new Error(`Source ${input.sourceId} is not a Google Discovery source.`), | 525 | new Error(`Source ${input.sourceId} is not a Google Discovery source.`), |
| 524 | ); | 526 | ); |
| @@ -542,7 +544,7 @@ const createGoogleDiscoverySourceSdk = ( · 17 unmodified lines | |||
| 542 | removeSource: (sourceId: Source["id"]) => | 544 | removeSource: (sourceId: Source["id"]) => |
| 543 | Effect.gen(function* () { | 545 | Effect.gen(function* () { |
| 544 | const source = yield* host.sources.get(sourceId); | 546 | const source = yield* host.sources.get(sourceId); |
| 545 | if (source.kind !== "google_discovery") { | 547 | if (source.kind !== GOOGLE_DISCOVERY_SOURCE_KIND) { |
| 546 | return yield* Effect.fail( | 548 | return yield* Effect.fail( |
| 547 | new Error(`Source ${sourceId} is not a Google Discovery source.`), | 549 | new Error(`Source ${sourceId} is not a Google Discovery source.`), |
| 548 | ); | 550 | ); |
| @@ -577,7 +579,7 @@ const googleDiscoverySourceConnector = ( · 28 unmodified lines | |||
| 577 | oauthSessions: GoogleDiscoveryOAuthSessionStorage; | 579 | oauthSessions: GoogleDiscoveryOAuthSessionStorage; |
| 578 | }, | 580 | }, |
| 579 | ): ExecutorSourceConnector<GoogleDiscoveryExecutorAddInput> => ({ | 581 | ): ExecutorSourceConnector<GoogleDiscoveryExecutorAddInput> => ({ |
| 580 | kind: "google_discovery", | 582 | kind: GOOGLE_DISCOVERY_SOURCE_KIND, |
| 581 | displayName: "Google Discovery", | 583 | displayName: "Google Discovery", |
| 582 | inputSchema: GoogleDiscoveryExecutorAddInputSchema, | 584 | inputSchema: GoogleDiscoveryExecutorAddInputSchema, |
| 583 | inputSignatureWidth: 320, | 585 | inputSignatureWidth: 320, |
| @@ -592,11 +594,11 @@ const googleDiscoverySourceConnector = ( · 8 unmodified lines | |||
| 592 | const createGoogleDiscoverySourceRuntime = (options: { | 594 | const createGoogleDiscoverySourceRuntime = (options: { |
| 593 | storage: GoogleDiscoverySourceStorage; | 595 | storage: GoogleDiscoverySourceStorage; |
| 594 | }): SourcePluginRuntime => ({ | 596 | }): SourcePluginRuntime => ({ |
| 595 | kind: "google_discovery", | 597 | kind: GOOGLE_DISCOVERY_SOURCE_KIND, |
| 596 | displayName: "Google Discovery", | 598 | displayName: "Google Discovery", |
| 597 | catalogKind: "imported", | 599 | catalogKind: "imported", |
| 598 | catalogIdentity: ({ source }) => ({ | 600 | catalogIdentity: ({ source }) => ({ |
| 599 | kind: "google_discovery", | 601 | kind: GOOGLE_DISCOVERY_SOURCE_KIND, |
| 600 | sourceId: source.id, | 602 | sourceId: source.id, |
| 601 | }), | 603 | }), |
| 602 | getIrModel: ({ source }) => | 604 | getIrModel: ({ source }) => |
| @@ -613,7 +615,7 @@ const createGoogleDiscoverySourceRuntime = (options: { · 10 unmodified lines | |||
| 613 | importMetadata: { | 615 | importMetadata: { |
| 614 | ...createCatalogImportMetadata({ | 616 | ...createCatalogImportMetadata({ |
| 615 | source, | 617 | source, |
| 616 | pluginKey: "google_discovery", | 618 | pluginKey: GOOGLE_DISCOVERY_SOURCE_KIND, |
| 617 | }), | 619 | }), |
| 618 | importerVersion: "ir.v1.google_discovery", | 620 | importerVersion: "ir.v1.google_discovery", |
| 619 | sourceConfigHash: "missing", | 621 | sourceConfigHash: "missing", |
| @@ -647,7 +649,7 @@ const createGoogleDiscoverySourceRuntime = (options: { · 27 unmodified lines | |||
| 647 | source, | 649 | source, |
| 648 | documents: [ | 650 | documents: [ |
| 649 | { | 651 | { |
| 650 | documentKind: "google_discovery", | 652 | documentKind: GOOGLE_DISCOVERY_SOURCE_KIND, |
| 651 | documentKey: stored.discoveryUrl, | 653 | documentKey: stored.discoveryUrl, |
| 652 | contentText: document, | 654 | contentText: document, |
| 653 | fetchedAt: now, | 655 | fetchedAt: now, |
| @@ -658,7 +660,7 @@ const createGoogleDiscoverySourceRuntime = (options: { · 4 unmodified lines | |||
| 658 | importMetadata: { | 660 | importMetadata: { |
| 659 | ...createCatalogImportMetadata({ | 661 | ...createCatalogImportMetadata({ |
| 660 | source, | 662 | source, |
| 661 | pluginKey: "google_discovery", | 663 | pluginKey: GOOGLE_DISCOVERY_SOURCE_KIND, |
| 662 | }), | 664 | }), |
| 663 | importerVersion: "ir.v1.google_discovery", | 665 | importerVersion: "ir.v1.google_discovery", |
| 664 | }, | 666 | }, |
| @@ -753,8 +755,8 @@ const createGoogleDiscoverySourceRuntime = (options: { · 88 unmodified lines | |||
| 753 | export const googleDiscoverySdkPlugin = (options: { | 755 | export const googleDiscoverySdkPlugin = (options: { |
| 754 | storage: GoogleDiscoverySourceStorage; | 756 | storage: GoogleDiscoverySourceStorage; |
| 755 | oauthSessions: GoogleDiscoveryOAuthSessionStorage; | 757 | oauthSessions: GoogleDiscoveryOAuthSessionStorage; |
| 756 | }): ExecutorSdkPlugin<"googleDiscovery", GoogleDiscoverySdk> => ({ | 758 | }): ExecutorSdkPlugin<typeof GOOGLE_DISCOVERY_EXECUTOR_KEY, GoogleDiscoverySdk> => ({ |
| 757 | key: "googleDiscovery", | 759 | key: GOOGLE_DISCOVERY_EXECUTOR_KEY, |
| 758 | sources: [createGoogleDiscoverySourceRuntime(options)], | 760 | sources: [createGoogleDiscoverySourceRuntime(options)], |
| 759 | sourceConnectors: [googleDiscoverySourceConnector(options)], | 761 | sourceConnectors: [googleDiscoverySourceConnector(options)], |
| 760 | extendExecutor: ({ host, executor }) => { | 762 | extendExecutor: ({ host, executor }) => { |
| @@ -18,6 +18,7 @@ import { sourceCoreEffectError } from "@executor/source-core"; · 17 unmodified lines | |||
| 18 | import * as Effect from "effect/Effect"; | 18 | import * as Effect from "effect/Effect"; |
| 19 | import * as Layer from "effect/Layer"; | 19 | import * as Layer from "effect/Layer"; |
| 20 | import * as Schema from "effect/Schema"; | 20 | import * as Schema from "effect/Schema"; |
| 21 | import { GOOGLE_DISCOVERY_SOURCE_KIND } from "@executor/plugin-google-discovery-shared"; | ||
| 21 | 22 | ||
| 22 | import type { | 23 | import type { |
| 23 | GoogleDiscoveryManifestMethod, | 24 | GoogleDiscoveryManifestMethod, |
| @@ -43,7 +44,7 @@ export const googleDiscoveryProviderDataFromDefinition = ( · 19 unmodified lines | |||
| 43 | definition: GoogleDiscoveryManifestMethod; | 44 | definition: GoogleDiscoveryManifestMethod; |
| 44 | }, | 45 | }, |
| 45 | ): typeof GoogleDiscoveryToolProviderDataSchema.Type => ({ | 46 | ): typeof GoogleDiscoveryToolProviderDataSchema.Type => ({ |
| 46 | kind: "google_discovery", | 47 | kind: GOOGLE_DISCOVERY_SOURCE_KIND, |
| 47 | service: input.service, | 48 | service: input.service, |
| 48 | version: input.version, | 49 | version: input.version, |
| 49 | toolId: input.definition.toolId, | 50 | toolId: input.definition.toolId, |
| @@ -467,7 +468,7 @@ export const createGoogleDiscoveryToolFromDefinition = ( · 417 unmodified lines | |||
| 467 | : {}), | 468 | : {}), |
| 468 | }, | 469 | }, |
| 469 | sourceKey: input.sourceKey, | 470 | sourceKey: input.sourceKey, |
| 470 | pluginKind: "google_discovery", | 471 | pluginKind: GOOGLE_DISCOVERY_SOURCE_KIND, |
| 471 | pluginData: providerData, | 472 | pluginData: providerData, |
| 472 | }; | 473 | }; |
| 473 | 474 | ||
| @@ -1,4 +1,5 @@ | |||
| 1 | import { Schema } from "effect"; | 1 | import { Schema } from "effect"; |
| 2 | import { GOOGLE_DISCOVERY_SOURCE_KIND } from "@executor/plugin-google-discovery-shared"; | ||
| 2 | 3 | ||
| 3 | export const GOOGLE_DISCOVERY_HTTP_METHODS = [ | 4 | export const GOOGLE_DISCOVERY_HTTP_METHODS = [ |
| 4 | "get", | 5 | "get", |
| @@ -52,7 +53,7 @@ export const GoogleDiscoveryInvocationPayloadSchema = Schema.Struct({ · 47 unmodified lines | |||
| 52 | }); | 53 | }); |
| 53 | 54 | ||
| 54 | export const GoogleDiscoveryToolProviderDataSchema = Schema.Struct({ | 55 | export const GoogleDiscoveryToolProviderDataSchema = Schema.Struct({ |
| 55 | kind: Schema.Literal("google_discovery"), | 56 | kind: Schema.Literal(GOOGLE_DISCOVERY_SOURCE_KIND), |
| 56 | service: Schema.String, | 57 | service: Schema.String, |
| 57 | version: Schema.String, | 58 | version: Schema.String, |
| 58 | toolId: Schema.String, | 59 | toolId: Schema.String, |
| @@ -5,6 +5,14 @@ import { · 4 unmodified lines | |||
| 5 | StringMapSchema, | 5 | StringMapSchema, |
| 6 | } from "@executor/platform-sdk/schema"; | 6 | } from "@executor/platform-sdk/schema"; |
| 7 | 7 | ||
| 8 | export const GOOGLE_DISCOVERY_SOURCE_KIND = "google_discovery" as const; | ||
| 9 | export const GOOGLE_DISCOVERY_PLUGIN_KEY = "google-discovery" as const; | ||
| 10 | export const GOOGLE_DISCOVERY_EXECUTOR_KEY = "googleDiscovery" as const; | ||
| 11 | export const GOOGLE_DISCOVERY_OAUTH_STORAGE_PREFIX = | ||
| 12 | "executor:google-discovery-oauth:" as const; | ||
| 13 | export const GOOGLE_DISCOVERY_OAUTH_CALLBACK_PATH = | ||
| 14 | `/v1/plugins/${GOOGLE_DISCOVERY_PLUGIN_KEY}/oauth/callback` as const; | ||
| 15 | |||
| 8 | export const GoogleDiscoveryOAuthClientAuthenticationSchema = Schema.Literal( | 16 | export const GoogleDiscoveryOAuthClientAuthenticationSchema = Schema.Literal( |
| 9 | "none", | 17 | "none", |
| 10 | "client_secret_post", | 18 | "client_secret_post", |
| @@ -6,11 +6,11 @@ import { · 5 unmodified lines | |||
| 6 | type SourceDiscoveryProbeInput, | 6 | type SourceDiscoveryProbeInput, |
| 7 | type SourceDiscoveryResult, | 7 | type SourceDiscoveryResult, |
| 8 | } from "@executor/source-core"; | 8 | } from "@executor/source-core"; |
| 9 | import { startMcpOAuthAuthorization } from "@executor/auth-mcp-oauth"; | ||
| 10 | import * as Either from "effect/Either"; | 9 | import * as Either from "effect/Either"; |
| 11 | import * as Effect from "effect/Effect"; | 10 | import * as Effect from "effect/Effect"; |
| 12 | 11 | ||
| 13 | import { createSdkMcpConnector } from "./connection"; | 12 | import { createSdkMcpConnector } from "./connection"; |
| 13 | import { startMcpOAuthAuthorization } from "./oauth"; | ||
| 14 | import { discoverMcpToolsFromConnector } from "./tools"; | 14 | import { discoverMcpToolsFromConnector } from "./tools"; |
| 15 | 15 | ||
| 16 | export const detectMcpSource = ( | 16 | export const detectMcpSource = ( |
| @@ -14,7 +14,7 @@ import type { · 13 unmodified lines | |||
| 14 | import { | 14 | import { |
| 15 | exchangeMcpOAuthAuthorizationCode, | 15 | exchangeMcpOAuthAuthorizationCode, |
| 16 | startMcpOAuthAuthorization, | 16 | startMcpOAuthAuthorization, |
| 17 | } from "@executor/auth-mcp-oauth"; | 17 | } from "./oauth"; |
| 18 | import { | 18 | import { |
| 19 | contentHash, | 19 | contentHash, |
| 20 | createCatalogImportMetadata, | 20 | createCatalogImportMetadata, |
File renamed without changes.
| @@ -8,7 +8,8 @@ import type { · 7 unmodified lines | |||
| 8 | OAuthTokens, | 8 | OAuthTokens, |
| 9 | } from "@modelcontextprotocol/sdk/shared/auth.js"; | 9 | } from "@modelcontextprotocol/sdk/shared/auth.js"; |
| 10 | import * as Effect from "effect/Effect"; | 10 | import * as Effect from "effect/Effect"; |
| 11 | import { mcpOAuthEffectError } from "./effect-errors"; | 11 | |
| 12 | import { mcpOAuthEffectError } from "./oauth-effect-errors"; | ||
| 12 | 13 | ||
| 13 | type JsonValue = | 14 | type JsonValue = |
| 14 | | string | 15 | | string |
| @@ -123,7 +124,7 @@ export const startMcpOAuthAuthorization = (input: { · 108 unmodified lines | |||
| 123 | }); | 124 | }); |
| 124 | 125 | ||
| 125 | if (result !== "REDIRECT" || !captured.authorizationUrl || !captured.codeVerifier) { | 126 | if (result !== "REDIRECT" || !captured.authorizationUrl || !captured.codeVerifier) { |
| 126 | return yield* mcpOAuthEffectError("index", "OAuth flow did not produce an authorization redirect"); | 127 | return yield* mcpOAuthEffectError("oauth", "OAuth flow did not produce an authorization redirect"); |
| 127 | } | 128 | } |
| 128 | 129 | ||
| 129 | return { | 130 | return { |
| @@ -196,7 +197,7 @@ export const exchangeMcpOAuthAuthorizationCode = (input: { · 66 unmodified lines | |||
| 196 | }); | 197 | }); |
| 197 | 198 | ||
| 198 | if (result !== "AUTHORIZED" || !captured.tokens) { | 199 | if (result !== "AUTHORIZED" || !captured.tokens) { |
| 199 | return yield* mcpOAuthEffectError("index", "OAuth redirect did not complete MCP OAuth setup"); | 200 | return yield* mcpOAuthEffectError("oauth", "OAuth redirect did not complete MCP OAuth setup"); |
| 200 | } | 201 | } |
| 201 | 202 | ||
| 202 | return { | 203 | return { |
| @@ -12,7 +12,6 @@ · 11 unmodified lines | |||
| 12 | "typecheck": "bunx tsc --noEmit -p tsconfig.json" | 12 | "typecheck": "bunx tsc --noEmit -p tsconfig.json" |
| 13 | }, | 13 | }, |
| 14 | "dependencies": { | 14 | "dependencies": { |
| 15 | "@executor/auth-mcp-oauth": "workspace:*", | ||
| 16 | "@executor/codemode-core": "workspace:*", | 15 | "@executor/codemode-core": "workspace:*", |
| 17 | "@executor/ir": "workspace:*", | 16 | "@executor/ir": "workspace:*", |
| 18 | "@executor/platform-sdk": "workspace:*", | 17 | "@executor/platform-sdk": "workspace:*", |