History

Fix execute-path web/runtime regressions and add GitHub source

Rhys Sullivan committed 7 months ago

Commit 2cc6c8b1 parent d03db829 files · +106 −13Browse files

Unified · Split

9 files
  1. .executor/executor.jsonc +13 −0
  2. apps/web/src/components/shell.tsx +9 −2
  3. apps/web/src/views/source-detail.tsx +44 −4
  4. bun.lock +0 −2
  5. packages/clients/react/src/index.ts +3 −1
  6. packages/platform/sdk/package.json +0 −2
  7. packages/platform/sdk/src/runtime/control-plane-runtime.test.ts +1 −1
  8. packages/platform/sdk/src/runtime/execution/test-http-client.ts +1 −1
  9. packages/platform/server/src/index.ts +35 −0
.executor/executor.jsonc+13−0
@@ -1,4 +1,17 @@
11 {
2+ "sources": {
3+ "github": {
4+ "kind": "openapi",
5+ "name": "GitHub",
6+ "connection": {
7+ "endpoint": "https://api.github.com/"
8+ },
9+ "binding": {
10+ "specUrl": "https://raw.githubusercontent.com/github/rest-api-description/main/descriptions/api.github.com/api.github.com.json",
11+ "defaultHeaders": null
12+ }
13+ }
14+ },
215 "policies": {
316 "demo.*": {
417 "match": "demo.*",
apps/web/src/components/shell.tsx+9−2
@@ -27,6 +27,8 @@ const { VITE_APP_VERSION, VITE_GITHUB_URL } = (import.meta as ImportMeta & { · 26 unmodified lines
2727
2828 type UpdateChannel = "latest" | "beta";
2929
30+const EXECUTOR_DIST_TAGS_PATH = "/v1/app/npm/dist-tags";
31+
3032 type ParsedVersion = {
3133 readonly major: number;
3234 readonly minor: number;
@@ -139,8 +141,13 @@ function useLatestVersion(currentVersion: string) { · 106 unmodified lines
139141
140142 useEffect(() => {
141143 let cancelled = false;
142− fetch("https://registry.npmjs.org/-/package/executor/dist-tags")
143− .then((res) => res.json())
144+ fetch(EXECUTOR_DIST_TAGS_PATH)
145+ .then(async (res) => {
146+ if (!res.ok) {
147+ throw new Error(`Failed to load dist tags: ${res.status}`);
148+ }
149+ return res.json() as Promise<Partial<Record<UpdateChannel, string>>>;
150+ })
144151 .then((data: Partial<Record<UpdateChannel, string>>) => {
145152 if (!cancelled) {
146153 setLatestVersion(data[channel] ?? null);
apps/web/src/views/source-detail.tsx+44−4
@@ -122,12 +122,50 @@ const readBindingTransport = (source: Source): "auto" | "streamable-http" | "sse · 121 unmodified lines
122122 : undefined;
123123 };
124124
125+type RefreshableHttpAuth =
126+ | { kind: "none" }
127+ | {
128+ kind: "bearer";
129+ headerName?: string | null;
130+ prefix?: string | null;
131+ token?: string | null;
132+ tokenRef?: { providerId: string; handle: string } | null;
133+ }
134+ | {
135+ kind: "oauth2";
136+ headerName?: string | null;
137+ prefix?: string | null;
138+ accessToken?: string | null;
139+ accessTokenRef?: { providerId: string; handle: string } | null;
140+ refreshToken?: string | null;
141+ refreshTokenRef?: { providerId: string; handle: string } | null;
142+ };
143+
125144 const refreshableHttpAuth = (
126145 auth: Source["auth"],
127−): Extract<Source["auth"], { kind: "none" | "bearer" | "oauth2" }> | undefined =>
128− auth.kind === "none" || auth.kind === "bearer" || auth.kind === "oauth2"
129− ? auth
130− : undefined;
146+): RefreshableHttpAuth | undefined => {
147+ switch (auth.kind) {
148+ case "none":
149+ return { kind: "none" };
150+ case "bearer":
151+ return {
152+ kind: "bearer",
153+ headerName: auth.headerName,
154+ prefix: auth.prefix,
155+ tokenRef: auth.token,
156+ };
157+ case "oauth2":
158+ return {
159+ kind: "oauth2",
160+ headerName: auth.headerName,
161+ prefix: auth.prefix,
162+ accessTokenRef: auth.accessToken,
163+ refreshTokenRef: auth.refreshToken,
164+ };
165+ default:
166+ return undefined;
167+ }
168+};
131169
132170 const refreshPayloadFromSource = (source: Source): ConnectSourcePayload | null => {
133171 switch (source.kind) {
@@ -193,6 +231,8 @@ const refreshPayloadFromSource = (source: Source): ConnectSourcePayload | null = · 59 unmodified lines
193231 auth: refreshableHttpAuth(source.auth),
194232 };
195233 }
234+ default:
235+ return null;
196236 }
197237 };
198238
bun.lock+0−2
@@ -325,8 +325,6 @@ · 324 unmodified lines
325325 },
326326 "devDependencies": {
327327 "@effect/vitest": "catalog:",
328− "@executor/platform-api": "workspace:*",
329− "@executor/platform-internal": "workspace:*",
330328 "@modelcontextprotocol/sdk": "^1.26.0",
331329 "@types/node": "catalog:",
332330 "bun-types": "catalog:",
packages/clients/react/src/index.ts+3−1
@@ -3,12 +3,14 @@ import type * as Registry from "@effect-atom/atom/Registry"; · 2 unmodified lines
33 import { RegistryContext, RegistryProvider, useAtomValue } from "@effect-atom/atom-react";
44 import {
55 createControlPlaneClient,
6+ type ControlPlaneClient,
7+} from "@executor/platform-api/client";
8+import {
69 type CompleteSourceOAuthResult,
710 type ConnectSourceBatchPayload,
811 type ConnectSourceBatchResult,
912 type ConnectSourcePayload,
1013 type ConnectSourceResult,
11− type ControlPlaneClient,
1214 type CreateSecretPayload,
1315 type CreateSecretResult,
1416 type CreateSourcePayload,
packages/platform/sdk/package.json+0−2
@@ -49,8 +49,6 @@ · 48 unmodified lines
4949 },
5050 "devDependencies": {
5151 "@effect/vitest": "catalog:",
52− "@executor/platform-api": "workspace:*",
53− "@executor/platform-internal": "workspace:*",
5452 "@modelcontextprotocol/sdk": "^1.26.0",
5553 "@types/node": "catalog:",
5654 "bun-types": "catalog:",
packages/platform/sdk/src/runtime/control-plane-runtime.test.ts+1−1
@@ -23,7 +23,7 @@ import { · 22 unmodified lines
2323 import type { ToolPath } from "@executor/codemode-core";
2424 import { createCatalogImportMetadata } from "@executor/source-core";
2525 import { createGraphqlCatalogFragment } from "@executor/source-graphql";
26−import { createExecutorAdminToolMap } from "@executor/platform-internal";
26+import { createExecutorAdminToolMap } from "../../../internal/src/index";
2727
2828 import {
2929 type ControlPlaneRuntime,
packages/platform/sdk/src/runtime/execution/test-http-client.ts+1−1
@@ -6,7 +6,7 @@ import { NodeHttpServer } from "@effect/platform-node"; · 5 unmodified lines
66 import {
77 ControlPlaneApi,
88 createControlPlaneApiLayer,
9−} from "@executor/platform-api";
9+} from "../../../../api/src/index";
1010 import * as Effect from "effect/Effect";
1111 import * as Layer from "effect/Layer";
1212
packages/platform/server/src/index.ts+35−0
@@ -98,6 +98,10 @@ export type LocalExecutorRequestHandler = { · 97 unmodified lines
9898 type ControlPlaneWebHandler = ReturnType<typeof HttpApiBuilder.toWebHandler>;
9999 type ExecutorMcpHandler = ReturnType<typeof createExecutorMcpRequestHandler>;
100100
101+const EXECUTOR_NPM_DIST_TAGS_PATHNAME = "/v1/app/npm/dist-tags";
102+const EXECUTOR_NPM_DIST_TAGS_URL =
103+ "https://registry.npmjs.org/-/package/executor/dist-tags";
104+
101105 const disposeRuntime = (runtime: ControlPlaneRuntime) =>
102106 Effect.tryPromise({
103107 try: () => runtime.close(),
@@ -306,6 +310,34 @@ const isApiRequest = (request: Request): boolean => { · 202 unmodified lines
306310 return pathname === "/mcp" || pathname === "/v1" || pathname.startsWith("/v1/");
307311 };
308312
313+const handleExecutorNpmDistTagsRequest = async (): Promise<Response> => {
314+ try {
315+ const upstream = await fetch(EXECUTOR_NPM_DIST_TAGS_URL, {
316+ headers: {
317+ accept: "application/json",
318+ },
319+ });
320+ const body = upstream.ok ? await upstream.text() : "{}";
321+ return new Response(body, {
322+ status: upstream.ok ? 200 : 502,
323+ headers: {
324+ "cache-control": upstream.ok
325+ ? upstream.headers.get("cache-control") ?? "public, max-age=300"
326+ : "no-store",
327+ "content-type": "application/json; charset=utf-8",
328+ },
329+ });
330+ } catch {
331+ return new Response("{}", {
332+ status: 502,
333+ headers: {
334+ "cache-control": "no-store",
335+ "content-type": "application/json; charset=utf-8",
336+ },
337+ });
338+ }
339+};
340+
309341 export const createLocalExecutorRequestHandler = (
310342 options: StartLocalExecutorServerOptions = {},
311343 ): Effect.Effect<LocalExecutorRequestHandler, Error, Scope.Scope> =>
@@ -359,6 +391,9 @@ export const createLocalExecutorRequestHandler = ( · 47 unmodified lines
359391 runtime,
360392 handleApiRequest: (request) => {
361393 const pathname = new URL(request.url).pathname;
394+ if (pathname === EXECUTOR_NPM_DIST_TAGS_PATHNAME) {
395+ return handleExecutorNpmDistTagsRequest();
396+ }
362397 return pathname === "/mcp"
363398 ? mcpHandler.handleRequest(request)
364399 : apiHandler.handler(request);