(targetName: string, endpoint: string | undefined, json?: string)
| 382 | }; |
| 383 | |
| 384 | const apiCall = async (targetName: string, endpoint: string | undefined, json?: string) => { |
| 385 | if (!endpoint?.includes(".")) { |
| 386 | throw new Error("usage: api <target> <group.endpoint> [json] — e.g. api selfhost tools.list"); |
| 387 | } |
| 388 | const { target } = await loadTarget(targetName); |
| 389 | const [group, method] = endpoint.split(".", 2) as [string, string]; |
| 390 | // No-arg endpoints (tools.list) reject a spurious {}; only pass what was given. |
| 391 | const args = json === undefined ? undefined : (JSON.parse(json) as Record<string, unknown>); |
| 392 | |
| 393 | const { Effect } = await import("effect"); |
| 394 | const { FetchHttpClient } = await import("effect/unstable/http"); |
| 395 | const { composePluginApi } = await import("@executor-js/api/server"); |
| 396 | const { openApiHttpPlugin } = await import("@executor-js/plugin-openapi/api"); |
| 397 | const { graphqlHttpPlugin } = await import("@executor-js/plugin-graphql/api"); |
| 398 | const { mcpHttpPlugin } = await import("@executor-js/plugin-mcp/api"); |
| 399 | const { makeApiSurface } = await import("../src/surfaces/api"); |
| 400 | |
| 401 | const apiDef = composePluginApi([ |
| 402 | openApiHttpPlugin(), |
| 403 | graphqlHttpPlugin(), |
| 404 | mcpHttpPlugin(), |
| 405 | ] as const); |
| 406 | const surface = makeApiSurface(target); |
| 407 | |
| 408 | // The endpoint is picked at runtime, so the client is driven untyped here — |
| 409 | // the full static typing lives in scenarios; this is the interactive probe. |
| 410 | const program = Effect.gen(function* () { |
| 411 | const who = yield* target.newIdentity(); |
| 412 | // eslint-disable-next-line @typescript-eslint/no-explicit-any |
| 413 | const client: any = yield* surface.client(apiDef as any, who); |
| 414 | if (typeof client[group]?.[method] !== "function") { |
| 415 | const groups = Object.keys(client).filter((k) => typeof client[k] === "object"); |
| 416 | throw new Error(`no endpoint ${endpoint}; groups: ${groups.join(", ")}`); |
| 417 | } |
| 418 | return yield* client[group][method](args); |
| 419 | }) as import("effect").Effect.Effect< |
| 420 | unknown, |
| 421 | unknown, |
| 422 | import("effect/unstable/http").HttpClient.HttpClient |
| 423 | >; |
| 424 | const result = await Effect.runPromise(program.pipe(Effect.provide(FetchHttpClient.layer))); |
| 425 | console.log(JSON.stringify(result, null, 2)); |
| 426 | }; |
| 427 | |
| 428 | const mcpCall = async ( |
| 429 | targetName: string, |
no test coverage detected