Rhys Sullivanrework naminge5818557 months agoHistory
2390 lines · 77.4 KB · TypeScript
RawDownload
import {  createServer,} from "node:http";import {  join,} from "node:path"; import {  FileSystem,  HttpApi,  HttpApiEndpoint,  HttpApiGroup,  HttpApiSchema,  HttpApiBuilder,} from "@effect/platform";import {  NodeFileSystem,} from "@effect/platform-node";import {  describe,  expect,  it,} from "@effect/vitest";import {  assertTrue,} from "@effect/vitest/utils";import * as Either from "effect/Either";import * as Effect from "effect/Effect";import * as Fiber from "effect/Fiber";import * as Layer from "effect/Layer";import * as Option from "effect/Option";import * as Schema from "effect/Schema"; import {  ExecutionIdSchema,  ExecutionInteractionIdSchema,  type ExecutionInteraction,  ProviderAuthGrantIdSchema,  SecretMaterialIdSchema,  SourceAuthSessionIdSchema,  SourceIdSchema,  ScopeOauthClientIdSchema,} from "#schema";import type {  ToolPath,} from "@executor/codemode-core";import {  makeOpenApiTestServer,} from "@executor/effect-test-utils";import {  createCatalogImportMetadata,} from "@executor/source-core";import {  createGraphqlCatalogFragment,} from "@executor/source-graphql";import {  createWorkspaceExecutorAdminToolMap,} from "../../../internal/src/index"; import {  type ExecutorRuntime,  type ExecutorStateStoreShape,  LiveExecutionManagerService,  provideExecutorRuntime,  RuntimeExecutionResolverService,} from "./index";import {  createSourceFromPayload,} from "./sources/source-definitions";import {  decodeSourceCredentialSelectionContent,} from "./sources/source-credential-interactions";import {  persistSource,} from "./sources/source-store";import {  withExecutorApiClient,  withExecutorApiRequestHandler,} from "./execution/test-http-client";import {  runtimeEffectError,} from "./effect-errors";import {  buildLocalSourceArtifact,  deriveLocalInstallation,  readLocalSourceArtifact,  resolveLocalWorkspaceContext,  writeLocalExecutorStateSnapshot,  writeLocalSourceArtifact,  writeProjectLocalExecutorConfig,  writeLocalWorkspaceState,} from "../../../sdk-file/src/effect";import {  createLocalExecutorRuntime as createExecutorRuntime,} from "../../../sdk-file/src/runtime";import {  decodeSourceCredentialInteraction,  submitSourceCredentialInteraction,} from "../local/operations"; const makeRuntime = Effect.gen(function* () {  const fs = yield* FileSystem.FileSystem;  const scopeRoot = yield* fs.makeTempDirectoryScoped({    prefix: "executor-runtime-",  });  const homeConfigPath = join(scopeRoot, ".executor-home.jsonc");  const homeStateDirectory = join(scopeRoot, ".executor-home-state");   return yield* Effect.acquireRelease(    createExecutorRuntime({      workspaceRoot: scopeRoot,      homeConfigPath,      homeStateDirectory,      createInternalToolMap: createWorkspaceExecutorAdminToolMap,    }),    (runtime) => Effect.promise(() => runtime.close()).pipe(Effect.orDie),  );}).pipe(Effect.provide(NodeFileSystem.layer)); const ownerParam = HttpApiSchema.param("owner", Schema.String);const repoParam = HttpApiSchema.param("repo", Schema.String); class RuntimeTestReposApi extends HttpApiGroup.make("repos")  .add(    HttpApiEndpoint.get("getRepo")`/repos/${ownerParam}/${repoParam}`      .addSuccess(Schema.Unknown),  ){} class RuntimeTestOpenApi extends HttpApi.make("runtimeTest").add(  RuntimeTestReposApi,) {} type GoogleWorkspaceTestServer = {  baseUrl: string;  tokenEndpoint: string;  discoveryUrl: (input: {    service: string;    version: string;    scope: string;  }) => string;  queueTokenResponse: (response: {    access_token: string;    refresh_token?: string;    expires_in?: number;    scope?: string;  }) => void;  tokenRequests: URLSearchParams[];  discoveryAuthorizations: string[];  close: () => Promise<void>;}; const runtimeTestOpenApiLive = HttpApiBuilder.group(  RuntimeTestOpenApi,  "repos",  (handlers) =>    handlers.handle("getRepo", ({ path }) =>      Effect.succeed({        full_name: `${path.owner}/${path.repo}`,        private: false,      }),    ),); const runtimeTestOpenApiLayer = HttpApiBuilder.api(RuntimeTestOpenApi).pipe(  Layer.provide(runtimeTestOpenApiLive),); const makeOpenApiSpecServer = makeOpenApiTestServer({  apiLayer: runtimeTestOpenApiLayer,}); const makeGoogleWorkspaceTestServer = Effect.acquireRelease(  Effect.promise<GoogleWorkspaceTestServer>(    () =>      new Promise<GoogleWorkspaceTestServer>((resolve, reject) => {        const discoveryScopes = new Map<string, string>();        const tokenResponses: Array<{          access_token: string;          refresh_token?: string;          expires_in?: number;          scope?: string;        }> = [];        const tokenRequests: URLSearchParams[] = [];        const discoveryAuthorizations: string[] = [];        let baseUrl = "";         const server = createServer(async (request, response) => {          const requestUrl = new URL(            request.url ?? "/",            `http://${request.headers.host ?? "127.0.0.1"}`,          );           if (            request.method === "POST" &&            requestUrl.pathname === "/oauth/token"          ) {            const chunks: Buffer[] = [];            for await (const chunk of request) {              chunks.push(Buffer.from(chunk));            }             const params = new URLSearchParams(              Buffer.concat(chunks).toString("utf8"),            );            tokenRequests.push(params);            const nextResponse = tokenResponses.shift();            if (!nextResponse) {              response.statusCode = 500;              response.setHeader("content-type", "application/json");              response.end(                JSON.stringify({                  error: "missing_token_response",                }),              );              return;            }             response.statusCode = 200;            response.setHeader("content-type", "application/json");            response.end(              JSON.stringify({                token_type: "Bearer",                expires_in: 3600,                ...nextResponse,              }),            );            return;          }           const discoveryMatch = /^\/([^/]+)\/\$discovery\/rest$/.exec(            requestUrl.pathname,          );          if (request.method === "GET" && discoveryMatch) {            const service = discoveryMatch[1]!;            const version = requestUrl.searchParams.get("version") ?? "v1";            const authorizationHeader =              typeof request.headers.authorization === "string"                ? request.headers.authorization                : Array.isArray(request.headers.authorization)                  ? (request.headers.authorization[0] ?? "")                  : "";            if (authorizationHeader.length > 0) {              discoveryAuthorizations.push(authorizationHeader);            }             const scope =              discoveryScopes.get(`${service}:${version}`) ??              `https://example.test/auth/${service}`;            response.statusCode = 200;            response.setHeader("content-type", "application/json");            response.end(              JSON.stringify({                name: service,                version,                title: `${service} API`,                description: `Test ${service} API`,                rootUrl: `${baseUrl}/`,                servicePath: `${service}/${version}/`,                auth: {                  oauth2: {                    scopes: {                      [scope]: {                        description: `${service} scope`,                      },                    },                  },                },                methods: {                  list: {                    id: `${service}.list`,                    path: "items",                    httpMethod: "GET",                    response: {                      $ref: "ListResponse",                    },                  },                },                schemas: {                  ListResponse: {                    id: "ListResponse",                    type: "object",                    properties: {                      items: {                        type: "array",                        items: {                          type: "string",                        },                      },                    },                  },                },              }),            );            return;          }           response.statusCode = 404;          response.end();        });         server.once("error", reject);        server.listen(0, "127.0.0.1", () => {          const address = server.address();          if (!address || typeof address === "string") {            reject(new Error("Failed to bind Google workspace test server"));            return;          }           baseUrl = `http://127.0.0.1:${address.port}`;          resolve({            baseUrl,            tokenEndpoint: `${baseUrl}/oauth/token`,            discoveryUrl: ({ service, version, scope }) => {              discoveryScopes.set(`${service}:${version}`, scope);              return `${baseUrl}/${service}/$discovery/rest?version=${encodeURIComponent(version)}`;            },            queueTokenResponse: (tokenResponse) => {              tokenResponses.push(tokenResponse);            },            tokenRequests,            discoveryAuthorizations,            close: () =>              new Promise<void>((closeResolve, closeReject) => {                server.close((error) => {                  if (error) {                    closeReject(error);                    return;                  }                   closeResolve();                });              }),          });        });      }),  ),  (server) => Effect.promise(() => server.close()).pipe(Effect.orDie),); const upsertLocalSecret = (  runtime: ExecutorRuntime,  input: {    id: string;    name: string;    purpose: "oauth_refresh_token" | "oauth_client_info" | "oauth_access_token";    value: string;  },) =>  executorStateForRuntime(runtime).secretMaterials.upsert({    id: SecretMaterialIdSchema.make(input.id),    providerId: "local",    handle: input.id,    name: input.name,    purpose: input.purpose,    value: input.value,    createdAt: Date.now(),    updatedAt: Date.now(),  }); const executorStateForRuntime = (  runtime: ExecutorRuntime,): ExecutorStateStoreShape => ({  authArtifacts: runtime.storage.auth.artifacts,  authLeases: runtime.storage.auth.leases,  sourceOauthClients: runtime.storage.auth.sourceOauthClients,  scopeOauthClients: runtime.storage.auth.scopeOauthClients,  providerAuthGrants: runtime.storage.auth.providerGrants,  sourceAuthSessions: runtime.storage.auth.sourceSessions,  secretMaterials: runtime.storage.secrets,  executions: runtime.storage.executions.runs,  executionInteractions: runtime.storage.executions.interactions,  executionSteps: runtime.storage.executions.steps,}); const createPersistedGoogleSource = (input: {  runtime: ExecutorRuntime;  name: string;  namespace: string;  service: string;  version: string;  discoveryUrl: string;  scopes: ReadonlyArray<string>;  auth:    | {        kind: "none";      }    | {        kind: "provider_grant_ref";        grantId: ReturnType<typeof ProviderAuthGrantIdSchema.make>;        providerKey: string;        requiredScopes: ReadonlyArray<string>;        headerName: string;        prefix: string;      };}) =>  Effect.gen(function* () {    const installation = input.runtime.localInstallation;    const source = yield* createSourceFromPayload({      scopeId: installation.scopeId,      sourceId: SourceIdSchema.make(`src_${crypto.randomUUID()}`),      payload: {        name: input.name,        kind: "google_discovery",        endpoint: input.discoveryUrl,        namespace: input.namespace,        binding: {          service: input.service,          version: input.version,          discoveryUrl: input.discoveryUrl,          scopes: [...input.scopes],        },        importAuthPolicy: "reuse_runtime",        importAuth: { kind: "none" },        auth: input.auth as any,        status: "connected",        enabled: true,      },      now: Date.now(),    });     return yield* persistSource(executorStateForRuntime(input.runtime), source, {      actorScopeId: installation.actorScopeId,    }).pipe((effect) => provideExecutorRuntime(effect, input.runtime));  }); const expectLeft = <A, E>(effect: Effect.Effect<A, E, never>) =>  Effect.either(effect).pipe(    Effect.flatMap((result) =>      Either.isLeft(result)        ? Effect.succeed(result.left)        : Effect.fail(            runtimeEffectError(              "executor-runtime.test",              "Expected effect to fail",            ),          ),    ),  ); const invokeWorkspaceTool = <A>(input: {  runtime: ExecutorRuntime;  path: ToolPath;  args: unknown;}) =>  provideExecutorRuntime(    Effect.gen(function* () {      const installation = input.runtime.localInstallation;      const resolveEnvironment = yield* RuntimeExecutionResolverService;      const environment = yield* resolveEnvironment({        scopeId: installation.scopeId,        actorScopeId: installation.actorScopeId,        executionId: ExecutionIdSchema.make(`exec_tool_${crypto.randomUUID()}`),      });       return (yield* environment.toolInvoker.invoke({        path: input.path,        args: input.args,      })) as A;    }),    input.runtime,  ); describe("executor-runtime", () => {  it.scoped(    "writes local source changes through executor.jsonc",    () =>      Effect.gen(function* () {        const fs = yield* FileSystem.FileSystem;        const scopeRoot = yield* fs.makeTempDirectoryScoped({          prefix: "executor-local-config-runtime-",        });        const homeConfigPath = join(scopeRoot, ".executor-home.jsonc");        const homeStateDirectory = join(scopeRoot, ".executor-home-state");        const runtime = yield* Effect.acquireRelease(          createExecutorRuntime({            workspaceRoot: scopeRoot,            homeConfigPath,            homeStateDirectory,          }),          (createdRuntime) =>            Effect.promise(() => createdRuntime.close()).pipe(Effect.orDie),        );        const openApiServer = yield* makeOpenApiSpecServer;        const installation = runtime.localInstallation;         const createdSource = yield* withExecutorApiClient(          { runtime, actorScopeId: installation.actorScopeId },          (client) =>            client.sources.create({              path: { workspaceId: installation.scopeId },              payload: {                name: "GitHub",                kind: "openapi",                endpoint: openApiServer.baseUrl,                namespace: "github",                binding: {                  specUrl: openApiServer.specUrl,                  defaultHeaders: null,                },

Lines 1–500 of 2390.