import { HttpApiBuilder } from "effect/unstable/httpapi";import { Effect } from "effect"; import { capture } from "@executor-js/api";import { ConnectionNotFoundError, type Connection, type ConnectionRef, type CreateConnectionInput, type HealthCheckResult, type Tool, type ValidateConnectionInput,} from "@executor-js/sdk"; import { ExecutorApi } from "../api";import { ExecutorService } from "../services"; const toResponse = (c: Connection) => ({ owner: c.owner, name: c.name, integration: c.integration, template: c.template, provider: c.provider, address: c.address, identityLabel: c.identityLabel ?? null, description: c.description ?? null, expiresAt: c.expiresAt ?? null, oauthClient: c.oauthClient ?? null, oauthClientOwner: c.oauthClientOwner ?? null, oauthScope: c.oauthScope ?? null, lastHealth: c.lastHealth ?? null,}); const toolToResponse = (t: Tool) => ({ address: String(t.address), owner: t.owner, integration: t.integration, connection: t.connection, name: String(t.name), pluginId: t.pluginId, description: t.description,}); const toHealthResponse = (r: HealthCheckResult) => ({ status: r.status, checkedAt: r.checkedAt, ...(r.httpStatus !== undefined ? { httpStatus: r.httpStatus } : {}), ...(r.identity !== undefined ? { identity: r.identity } : {}), ...(r.detail !== undefined ? { detail: r.detail } : {}), ...(r.responseSample !== undefined ? { responseSample: r.responseSample } : {}),}); export const ConnectionsHandlers = HttpApiBuilder.group(ExecutorApi, "connections", (handlers) => handlers .handle("list", ({ query }) => capture( Effect.gen(function* () { const executor = yield* ExecutorService; const connections = yield* executor.connections.list({ integration: query.integration, owner: query.owner, }); return connections.map(toResponse); }), ), ) .handle("create", ({ payload }) => capture( Effect.gen(function* () { const executor = yield* ExecutorService; // The payload is the discriminated `CreateConnectionInput` union // (`{ value }` | `{ values }` | `{ from }`); pass it through verbatim. const created = yield* executor.connections.create(payload as CreateConnectionInput); return toResponse(created); }), ), ) .handle("get", ({ params: path }) => capture( Effect.gen(function* () { const executor = yield* ExecutorService; const ref: ConnectionRef = { owner: path.owner, integration: path.integration, name: path.name, }; const connection = yield* executor.connections.get(ref); if (connection === null) { return yield* new ConnectionNotFoundError({ owner: path.owner, integration: path.integration, name: path.name, }); } return toResponse(connection); }), ), ) .handle("update", ({ params: path, payload }) => capture( Effect.gen(function* () { const executor = yield* ExecutorService; const updated = yield* executor.connections.update( { owner: path.owner, integration: path.integration, name: path.name, }, { ...(payload.description !== undefined ? { description: payload.description } : {}), ...(payload.identityLabel !== undefined ? { identityLabel: payload.identityLabel } : {}), }, ); return toResponse(updated); }), ), ) .handle("remove", ({ params: path }) => capture( Effect.gen(function* () { const executor = yield* ExecutorService; yield* executor.connections.remove({ owner: path.owner, integration: path.integration, name: path.name, }); return { removed: true }; }), ), ) .handle("refresh", ({ params: path }) => capture( Effect.gen(function* () { const executor = yield* ExecutorService; const tools = yield* executor.connections.refresh({ owner: path.owner, integration: path.integration, name: path.name, }); return tools.map(toolToResponse); }), ), ) .handle("checkHealth", ({ params: path, query }) => capture( Effect.gen(function* () { const executor = yield* ExecutorService; const result = yield* executor.connections.checkHealth( { owner: path.owner, integration: path.integration, name: path.name, }, query.ifStaleMs !== undefined ? { ifStaleMs: query.ifStaleMs } : undefined, ); return toHealthResponse(result); }), ), ) .handle("validate", ({ payload }) => capture( Effect.gen(function* () { const executor = yield* ExecutorService; // The payload mirrors `ValidateConnectionInput`: owner/integration/ // template/spec plus a single credential origin (`value` | `values` | // `from`). Pass it through verbatim. const result = yield* executor.connections.validate(payload as ValidateConnectionInput); return toHealthResponse(result); }), ), ),);
import { HttpApiBuilder } from "effect/unstable/httpapi";
import { Effect } from "effect";
import { capture } from "@executor-js/api";
import {
ConnectionNotFoundError,
type Connection,
type ConnectionRef,
type CreateConnectionInput,
type HealthCheckResult,
type Tool,
type ValidateConnectionInput,
} from "@executor-js/sdk";
import { ExecutorApi } from "../api";
import { ExecutorService } from "../services";
const toResponse = (c: Connection) => ({
owner: c.owner,
name: c.name,
integration: c.integration,
template: c.template,
provider: c.provider,
address: c.address,
identityLabel: c.identityLabel ?? null,
description: c.description ?? null,
expiresAt: c.expiresAt ?? null,
oauthClient: c.oauthClient ?? null,
oauthClientOwner: c.oauthClientOwner ?? null,
oauthScope: c.oauthScope ?? null,
lastHealth: c.lastHealth ?? null,
});
const toolToResponse = (t: Tool) => ({
address: String(t.address),
owner: t.owner,
integration: t.integration,
connection: t.connection,
name: String(t.name),
pluginId: t.pluginId,
description: t.description,
});
const toHealthResponse = (r: HealthCheckResult) => ({
status: r.status,
checkedAt: r.checkedAt,
...(r.httpStatus !== undefined ? { httpStatus: r.httpStatus } : {}),
...(r.identity !== undefined ? { identity: r.identity } : {}),
...(r.detail !== undefined ? { detail: r.detail } : {}),
...(r.responseSample !== undefined ? { responseSample: r.responseSample } : {}),
});
export const ConnectionsHandlers = HttpApiBuilder.group(ExecutorApi, "connections", (handlers) =>
handlers
.handle("list", ({ query }) =>
capture(
Effect.gen(function* () {
const executor = yield* ExecutorService;
const connections = yield* executor.connections.list({
integration: query.integration,
owner: query.owner,
});
return connections.map(toResponse);
}),
),
)
.handle("create", ({ payload }) =>
capture(
Effect.gen(function* () {
const executor = yield* ExecutorService;
// The payload is the discriminated `CreateConnectionInput` union
// (`{ value }` | `{ values }` | `{ from }`); pass it through verbatim.
const created = yield* executor.connections.create(payload as CreateConnectionInput);
return toResponse(created);
}),
),
)
.handle("get", ({ params: path }) =>
capture(
Effect.gen(function* () {
const executor = yield* ExecutorService;
const ref: ConnectionRef = {
owner: path.owner,
integration: path.integration,
name: path.name,
};
const connection = yield* executor.connections.get(ref);
if (connection === null) {
return yield* new ConnectionNotFoundError({
owner: path.owner,
integration: path.integration,
name: path.name,
});
}
return toResponse(connection);
}),
),
)
.handle("update", ({ params: path, payload }) =>
capture(
Effect.gen(function* () {
const executor = yield* ExecutorService;
const updated = yield* executor.connections.update(
{
owner: path.owner,
integration: path.integration,
name: path.name,
},
{
...(payload.description !== undefined ? { description: payload.description } : {}),
...(payload.identityLabel !== undefined
? { identityLabel: payload.identityLabel }
: {}),
},
);
return toResponse(updated);
}),
),
)
.handle("remove", ({ params: path }) =>
capture(
Effect.gen(function* () {
const executor = yield* ExecutorService;
yield* executor.connections.remove({
owner: path.owner,
integration: path.integration,
name: path.name,
});
return { removed: true };
}),
),
)
.handle("refresh", ({ params: path }) =>
capture(
Effect.gen(function* () {
const executor = yield* ExecutorService;
const tools = yield* executor.connections.refresh({
owner: path.owner,
integration: path.integration,
name: path.name,
});
return tools.map(toolToResponse);
}),
),
)
.handle("checkHealth", ({ params: path, query }) =>
capture(
Effect.gen(function* () {
const executor = yield* ExecutorService;
const result = yield* executor.connections.checkHealth(
{
owner: path.owner,
integration: path.integration,
name: path.name,
},
query.ifStaleMs !== undefined ? { ifStaleMs: query.ifStaleMs } : undefined,
);
return toHealthResponse(result);
}),
),
)
.handle("validate", ({ payload }) =>
capture(
Effect.gen(function* () {
const executor = yield* ExecutorService;
// The payload mirrors `ValidateConnectionInput`: owner/integration/
// template/spec plus a single credential origin (`value` | `values` |
// `from`). Pass it through verbatim.
const result = yield* executor.connections.validate(payload as ValidateConnectionInput);
return toHealthResponse(result);
}),
),
),
);