History

One-click add from the picker

Registry rows already carry the URL and auth indicators, so clicking Add now registers in place: the card flips to a View link into the integration's hub, the user stays on the picker, and several adds can run at once. Each plugin exposes a headless useQuickAdd on its client plugin — MCP probes and declares the detected methods (sharing the add page's seed policy via mcpDetectedAuthSeeds), OpenAPI lets the spec carry auth, GraphQL declares the registry's header pattern. A quick add that cannot complete falls back to the configuration screen prefilled with the same facts. Also fixes two latent bugs this surfaced: the probe API response schema stripped versionNegotiation, so the legacy-protocol pin never survived the HTTP boundary; and per-row state keyed on domain|kind, which conflated two same-kind products on one domain (Google Photos Library and Picker).

Rhys Sullivan committed 2 months ago

Commit f2d7fb61 parent 63741dd11 files · +554 −101Browse files

Showing the changes to packages/plugins/openapi/src/react (1 of 11 files). Show all

Unified · Split

packages/plugins/openapi/src/react/integration-plugin.ts+51−2
@@ -1,6 +1,54 @@
1−import { lazy } from "react";
2−import type { IntegrationPlugin, IntegrationPreset } from "@executor-js/sdk/client";
1+import { lazy, useCallback } from "react";
2+import { useAtomSet } from "@effect/atom-react";
3+import * as Exit from "effect/Exit";
4+import type {
5+ IntegrationPlugin,
6+ IntegrationPreset,
7+ IntegrationQuickAddInput,
8+ IntegrationQuickAddResult,
9+} from "@executor-js/sdk/client";
10+import { slugifyNamespace } from "@executor-js/react/plugins/integration-identity";
11+import { integrationWriteKeys } from "@executor-js/react/api/reactivity-keys";
312 import { openApiPresets } from "../sdk/presets";
13+import { addOpenApiSpec } from "./atoms";
14+import { decodeOpenApiSpecOverrides } from "../sdk/spec-overrides";
15+
16+/** One-click add for a registry OpenAPI row. The spec itself is the
17+ * configuration: omitting `authenticationTemplate` and `baseUrl` tells the
18+ * server to derive both from the document, exactly what the add page's
19+ * untouched defaults submit. Registry spec overrides ride along. */
20+function useOpenApiQuickAdd(): (
21+ input: IntegrationQuickAddInput,
22+) => Promise<IntegrationQuickAddResult> {
23+ const doAdd = useAtomSet(addOpenApiSpec, { mode: "promiseExit" });
24+ return useCallback(
25+ async (input) => {
26+ const slug = slugifyNamespace(input.slug ?? input.name);
27+ if (!slug) return { ok: false, reason: "no derivable slug" };
28+ // Registry overrides arrive as untyped JSON; a malformed patch goes to
29+ // the configuration screen (its editor renders the parse error) rather
30+ // than being silently dropped from a "successful" quick add.
31+ const specOverrides = input.specOverrides
32+ ? decodeOpenApiSpecOverrides(input.specOverrides)
33+ : undefined;
34+ if (input.specOverrides && input.specOverrides.length > 0 && specOverrides === undefined) {
35+ return { ok: false, reason: "unparseable spec overrides" };
36+ }
37+ const exit = await doAdd({
38+ payload: {
39+ spec: { kind: "url" as const, url: input.url },
40+ slug,
41+ name: input.name,
42+ ...(specOverrides && specOverrides.length > 0 ? { specOverrides } : {}),
43+ },
44+ reactivityKeys: integrationWriteKeys,
45+ });
46+ if (Exit.isFailure(exit)) return { ok: false, reason: "add failed" };
47+ return { ok: true, slug: String(exit.value.slug) };
48+ },
49+ [doAdd],
50+ );
51+}
452
553 const importAdd = () => import("./AddOpenApiIntegration");
654 const importEditSheet = () => import("./UpdateSpecSection");
@@ -24,6 +72,7 @@ export const createOpenApiIntegrationPlugin = ( · 17 unmodified lines
2472 void importEditSheet();
2573 void importAccounts();
2674 },
75+ useQuickAdd: useOpenApiQuickAdd,
2776 });
2877
2978 export const openApiIntegrationPlugin: IntegrationPlugin = createOpenApiIntegrationPlugin();

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t