History

Cover custom tools resolver options

Rhys Sullivan committed 4 months ago

Commit 807d08c1 parent 24629212 files · +54 −1Browse files

Unified · Split

2 files
  1. packages/plugins/apps/src/plugin/resolver.test.ts +46 −0
  2. packages/plugins/apps/src/plugin/resolver.ts +8 −1
packages/plugins/apps/src/plugin/resolver.test.ts+46−0
@@ -0,0 +1,46 @@
1import { describe, expect, it } from "@effect/vitest";
2import { Effect } from "effect";
3import type { InvokeOptions } from "@executor-js/sdk";
4
5import { makePluginCtxAppsResolver, type AppsResolverPluginCtx } from "./resolver";
6
7const run = <A, E>(effect: Effect.Effect<A, E>): Promise<A> => Effect.runPromise(effect);
8
9describe("makePluginCtxAppsResolver", () => {
10 it("passes caller invoke options through bridged integration calls", async () => {
11 const invokeOptions = { onElicitation: "accept-all" } satisfies InvokeOptions;
12 let seenAddress = "";
13 let seenPayload: unknown;
14 let seenOptions: InvokeOptions | undefined;
15
16 const ctx: AppsResolverPluginCtx = {
17 connections: {
18 list: () => Effect.succeed([]),
19 get: () => Effect.succeed(null),
20 },
21 execute: (address: unknown, payload: unknown, options?: InvokeOptions) =>
22 Effect.sync(() => {
23 seenAddress = String(address);
24 seenPayload = payload;
25 seenOptions = options;
26 return "called";
27 }),
28 };
29
30 const resolver = makePluginCtxAppsResolver({ ctx });
31 const result = await run(
32 resolver.call({
33 integration: "github",
34 connection: "tools.github.user.main",
35 path: ["issues", "listForRepo"],
36 args: [{ owner: "acme", repo: "tools" }],
37 invokeOptions,
38 }),
39 );
40
41 expect(result).toBe("called");
42 expect(seenAddress).toBe("tools.github.user.main.issues.listForRepo");
43 expect(seenPayload).toEqual({ owner: "acme", repo: "tools" });
44 expect(seenOptions).toBe(invokeOptions);
45 });
46});
packages/plugins/apps/src/plugin/resolver.ts+8−1
@@ -11,6 +11,11 @@ import { · 10 unmodified lines
11} from "@executor-js/sdk";11} from "@executor-js/sdk";
12import { BindingError, type ClientResolver, type ConnectionCandidate } from "./bindings";12import { BindingError, type ClientResolver, type ConnectionCandidate } from "./bindings";
13 13
14export interface AppsResolverPluginCtx {
15 readonly connections: Pick<PluginCtx["connections"], "list" | "get">;
16 readonly execute: PluginCtx["execute"];
17}
18
14const parseConnectionAddress = (address: string): ConnectionRef | null => {19const parseConnectionAddress = (address: string): ConnectionRef | null => {
15 const parts = address.split(".");20 const parts = address.split(".");
16 if (parts.length !== 4 || parts[0] !== "tools") return null;21 if (parts.length !== 4 || parts[0] !== "tools") return null;
@@ -36,7 +41,9 @@ const toCandidate = (connection: { · 19 unmodified lines
36 ...(connection.owner !== undefined ? { owner: String(connection.owner) } : {}),41 ...(connection.owner !== undefined ? { owner: String(connection.owner) } : {}),
37});42});
38 43
39export const makePluginCtxAppsResolver = (input: { readonly ctx: PluginCtx }): ClientResolver => ({44export const makePluginCtxAppsResolver = (input: {
45 readonly ctx: AppsResolverPluginCtx;
46}): ClientResolver => ({
40 listConnections: ({ integration }) =>47 listConnections: ({ integration }) =>
41 input.ctx.connections.list({ integration: IntegrationSlug.make(integration) }).pipe(48 input.ctx.connections.list({ integration: IntegrationSlug.make(integration) }).pipe(
42 Effect.map((connections) => connections.map(toCandidate)),49 Effect.map((connections) => connections.map(toCandidate)),