// ---------------------------------------------------------------------------// Tool-row projection coverage. The invoke and list hot paths select away the// heavy input_schema/output_schema JSON (TOOL_INVOCATION_COLUMNS) — a tool row// is ~KBs of schemas, but routing/policy needs only the names. These tests pin// the contract through a real dynamic integration:// - tools.list returns metadata without the schemas,// - invoke works end-to-end off the projected row,// - tools.schema (describe) still serves the full schemas.// --------------------------------------------------------------------------- import { describe, expect, it } from "@effect/vitest";import { Effect, Schema } from "effect";import { FetchHttpClient, HttpServerRequest } from "effect/unstable/http";import { HttpApi, HttpApiBuilder, HttpApiEndpoint, HttpApiGroup } from "effect/unstable/httpapi"; import { createExecutor, AuthTemplateSlug, ConnectionName, IntegrationSlug, ToolAddress,} from "@executor-js/sdk";import { makeTestConfig, memoryCredentialsPlugin } from "@executor-js/sdk/testing";import { variable } from "@executor-js/sdk/http-auth"; import { openApiPlugin } from "./plugin";import { serveOpenApiHttpApiTestServer, unwrapInvocation } from "../testing"; const testPlugins = (httpClientLayer = FetchHttpClient.layer) => [openApiPlugin({ httpClientLayer }), memoryCredentialsPlugin()] as const; const EchoHeaders = Schema.Struct({ "x-api-key": Schema.optional(Schema.String),}); const EchoGroup = HttpApiGroup.make("items").add( HttpApiEndpoint.get("echoHeaders", "/echo-headers", { success: EchoHeaders }),);const TestApi = HttpApi.make("testApi").add(EchoGroup); const EchoGroupLive = HttpApiBuilder.group(TestApi, "items", (handlers) => handlers.handle("echoHeaders", () => Effect.gen(function* () { const req = yield* HttpServerRequest.HttpServerRequest; return EchoHeaders.make({ "x-api-key": req.headers["x-api-key"] }); }), ),); const apiKeyTemplate = { slug: AuthTemplateSlug.make("apiKey"), type: "apiKey" as const, headers: { "x-api-key": [variable("token")] },}; const setup = Effect.gen(function* () { const server = yield* serveOpenApiHttpApiTestServer({ api: TestApi, handlersLayer: EchoGroupLive, }); const executor = yield* createExecutor(makeTestConfig({ plugins: testPlugins() })); yield* executor.openapi.addSpec({ spec: { kind: "blob", value: server.specJson }, slug: "proj_api", baseUrl: server.baseUrl, authenticationTemplate: [apiKeyTemplate], }); yield* executor.connections.create({ owner: "org", name: ConnectionName.make("main"), integration: IntegrationSlug.make("proj_api"), template: AuthTemplateSlug.make("apiKey"), value: "secret-key-123", }); return executor;}); const TOOL_ADDRESS = ToolAddress.make("tools.proj_api.org.main.items.echoHeaders"); describe("tool-row projection on hot paths", () => { it.effect("tools.list returns metadata without loading the schema columns", () => Effect.scoped( Effect.gen(function* () { const executor = yield* setup; const tools = yield* executor.tools.list({ integration: IntegrationSlug.make("proj_api"), }); const tool = tools.find((entry) => entry.address === TOOL_ADDRESS); expect(tool).toBeDefined(); expect(tool!.description.length).toBeGreaterThan(0); // The list surface is metadata-only: the projected query never loads // input/output schema JSON, so the Tool carries none. expect(tool!.inputSchema).toBeUndefined(); expect(tool!.outputSchema).toBeUndefined(); }), ), ); it.effect("invoke routes and executes off the projected row", () => Effect.scoped( Effect.gen(function* () { const executor = yield* setup; const result = unwrapInvocation(yield* executor.execute(TOOL_ADDRESS, {})).data as { "x-api-key"?: string; }; expect(result["x-api-key"]).toBe("secret-key-123"); }), ), ); it.effect("tools.schema still serves the full schemas", () => Effect.scoped( Effect.gen(function* () { const executor = yield* setup; const schema = yield* executor.tools.schema(TOOL_ADDRESS); expect(schema).not.toBeNull(); expect(schema!.outputSchema).toBeDefined(); }), ), );});
// ---------------------------------------------------------------------------
// Tool-row projection coverage. The invoke and list hot paths select away the
// heavy input_schema/output_schema JSON (TOOL_INVOCATION_COLUMNS) — a tool row
// is ~KBs of schemas, but routing/policy needs only the names. These tests pin
// the contract through a real dynamic integration:
// - tools.list returns metadata without the schemas,
// - invoke works end-to-end off the projected row,
// - tools.schema (describe) still serves the full schemas.
// ---------------------------------------------------------------------------
import { describe, expect, it } from "@effect/vitest";
import { Effect, Schema } from "effect";
import { FetchHttpClient, HttpServerRequest } from "effect/unstable/http";
import { HttpApi, HttpApiBuilder, HttpApiEndpoint, HttpApiGroup } from "effect/unstable/httpapi";
import {
createExecutor,
AuthTemplateSlug,
ConnectionName,
IntegrationSlug,
ToolAddress,
} from "@executor-js/sdk";
import { makeTestConfig, memoryCredentialsPlugin } from "@executor-js/sdk/testing";
import { variable } from "@executor-js/sdk/http-auth";
import { openApiPlugin } from "./plugin";
import { serveOpenApiHttpApiTestServer, unwrapInvocation } from "../testing";
const testPlugins = (httpClientLayer = FetchHttpClient.layer) =>
[openApiPlugin({ httpClientLayer }), memoryCredentialsPlugin()] as const;
const EchoHeaders = Schema.Struct({
"x-api-key": Schema.optional(Schema.String),
});
const EchoGroup = HttpApiGroup.make("items").add(
HttpApiEndpoint.get("echoHeaders", "/echo-headers", { success: EchoHeaders }),
);
const TestApi = HttpApi.make("testApi").add(EchoGroup);
const EchoGroupLive = HttpApiBuilder.group(TestApi, "items", (handlers) =>
handlers.handle("echoHeaders", () =>
Effect.gen(function* () {
const req = yield* HttpServerRequest.HttpServerRequest;
return EchoHeaders.make({ "x-api-key": req.headers["x-api-key"] });
}),
),
);
const apiKeyTemplate = {
slug: AuthTemplateSlug.make("apiKey"),
type: "apiKey" as const,
headers: { "x-api-key": [variable("token")] },
};
const setup = Effect.gen(function* () {
const server = yield* serveOpenApiHttpApiTestServer({
api: TestApi,
handlersLayer: EchoGroupLive,
});
const executor = yield* createExecutor(makeTestConfig({ plugins: testPlugins() }));
yield* executor.openapi.addSpec({
spec: { kind: "blob", value: server.specJson },
slug: "proj_api",
baseUrl: server.baseUrl,
authenticationTemplate: [apiKeyTemplate],
});
yield* executor.connections.create({
owner: "org",
name: ConnectionName.make("main"),
integration: IntegrationSlug.make("proj_api"),
template: AuthTemplateSlug.make("apiKey"),
value: "secret-key-123",
});
return executor;
});
const TOOL_ADDRESS = ToolAddress.make("tools.proj_api.org.main.items.echoHeaders");
describe("tool-row projection on hot paths", () => {
it.effect("tools.list returns metadata without loading the schema columns", () =>
Effect.scoped(
Effect.gen(function* () {
const executor = yield* setup;
const tools = yield* executor.tools.list({
integration: IntegrationSlug.make("proj_api"),
});
const tool = tools.find((entry) => entry.address === TOOL_ADDRESS);
expect(tool).toBeDefined();
expect(tool!.description.length).toBeGreaterThan(0);
// The list surface is metadata-only: the projected query never loads
// input/output schema JSON, so the Tool carries none.
expect(tool!.inputSchema).toBeUndefined();
expect(tool!.outputSchema).toBeUndefined();
}),
),
);
it.effect("invoke routes and executes off the projected row", () =>
Effect.scoped(
Effect.gen(function* () {
const executor = yield* setup;
const result = unwrapInvocation(yield* executor.execute(TOOL_ADDRESS, {})).data as {
"x-api-key"?: string;
};
expect(result["x-api-key"]).toBe("secret-key-123");
}),
),
);
it.effect("tools.schema still serves the full schemas", () =>
Effect.scoped(
Effect.gen(function* () {
const executor = yield* setup;
const schema = yield* executor.tools.schema(TOOL_ADDRESS);
expect(schema).not.toBeNull();
expect(schema!.outputSchema).toBeDefined();
}),
),
);
});