// Connection endpoints — create / list / get / remove round-trip and error// fidelity within a single org (v2).//// Ports the v1 "secrets api" suite. In v2 a connection IS the credential:// owner-scoped, bound 1:1 to an integration, identified by (owner, integration,// name). There is no scope id and no separate secret value endpoint — the value// is stored through the connection's provider and never echoed back. import { describe, expect, it } from "@effect/vitest";import { Effect, Result } from "effect";import { HttpApi, HttpApiEndpoint, HttpApiGroup, OpenApi } from "effect/unstable/httpapi";import { Schema } from "effect"; import { AuthTemplateSlug, ConnectionName, IntegrationSlug, connectionIdentifier,} from "@executor-js/sdk";import { makeOpenApiHttpApiTestAddSpecPayload } from "@executor-js/plugin-openapi/testing"; import { asOrg } from "../testing/api-harness"; const PingApi = HttpApi.make("connectionsApiTest") .add( HttpApiGroup.make("default", { topLevel: true }).add( HttpApiEndpoint.get("ping", "/ping", { success: Schema.Unknown }), ), ) .annotateMerge(OpenApi.annotations({ title: "Connections API Test", version: "1.0.0" })); const TEMPLATE_API_KEY = AuthTemplateSlug.make("apiKey");const canonicalConnectionName = (name: ConnectionName): ConnectionName => connectionIdentifier(String(name)); // Registers a minimal openapi integration so connections have something to bind// to, then returns its slug.const registerIntegration = (org: string) => Effect.gen(function* () { const slug = IntegrationSlug.make(`ns_${crypto.randomUUID().replace(/-/g, "_")}`); yield* asOrg(org, (client) => client.openapi.addSpec({ payload: makeOpenApiHttpApiTestAddSpecPayload(PingApi, { slug, baseUrl: "http://example.com", }), }), ); return slug; }); describe("connections api (HTTP)", () => { it.effect("create → list → get returns connection metadata without the value", () => Effect.gen(function* () { const org = `org_${crypto.randomUUID()}`; const integration = yield* registerIntegration(org); const name = ConnectionName.make(`conn_${crypto.randomUUID().slice(0, 8)}`); const storedName = canonicalConnectionName(name); const secretValue = "sk-test-abc"; const created = yield* asOrg(org, (client) => client.connections.create({ payload: { owner: "org", name, integration, template: TEMPLATE_API_KEY, identityLabel: "My API Token", value: secretValue, }, }), ); expect(created.name).toBe(storedName); expect(created.owner).toBe("org"); expect(JSON.stringify(created)).not.toContain(secretValue); const list = yield* asOrg(org, (client) => client.connections.list({ query: { integration } }), ); expect(list.find((c) => c.name === storedName)?.identityLabel).toBe("My API Token"); expect(JSON.stringify(list)).not.toContain(secretValue); const fetched = yield* asOrg(org, (client) => client.connections.get({ params: { owner: "org", integration, name: storedName } }), ); expect(fetched.name).toBe(storedName); expect(fetched.integration).toBe(integration); }), ); it.effect("get on an unknown connection fails with ConnectionNotFoundError", () => Effect.gen(function* () { const org = `org_${crypto.randomUUID()}`; const integration = yield* registerIntegration(org); const missing = ConnectionName.make(`missing_${crypto.randomUUID().slice(0, 8)}`); const result = yield* asOrg(org, (client) => client.connections .get({ params: { owner: "org", integration, name: missing } }) .pipe(Effect.result), ); expect(Result.isFailure(result)).toBe(true); }), ); it.effect("remove deletes the connection; list drops it and get fails", () => Effect.gen(function* () { const org = `org_${crypto.randomUUID()}`; const integration = yield* registerIntegration(org); const name = ConnectionName.make(`conn_${crypto.randomUUID().slice(0, 8)}`); const storedName = canonicalConnectionName(name); yield* asOrg(org, (client) => Effect.gen(function* () { yield* client.connections.create({ payload: { owner: "org", name, integration, template: TEMPLATE_API_KEY, value: "v" }, }); const removed = yield* client.connections.remove({ params: { owner: "org", integration, name: storedName }, }); expect(removed.removed).toBe(true); }), ); const list = yield* asOrg(org, (client) => client.connections.list({ query: { integration } }), ); expect(list.map((c) => c.name)).not.toContain(storedName); const afterGet = yield* asOrg(org, (client) => client.connections .get({ params: { owner: "org", integration, name: storedName } }) .pipe(Effect.result), ); expect(Result.isFailure(afterGet)).toBe(true); }), ); it.effect("remove on an unknown connection fails with ConnectionNotFoundError", () => Effect.gen(function* () { const org = `org_${crypto.randomUUID()}`; const integration = yield* registerIntegration(org); const missing = ConnectionName.make(`missing_${crypto.randomUUID().slice(0, 8)}`); const result = yield* asOrg(org, (client) => client.connections .remove({ params: { owner: "org", integration, name: missing } }) .pipe(Effect.result), ); expect(Result.isFailure(result)).toBe(true); }), ); it.effect("create with the same (owner, integration, name) twice updates the metadata", () => Effect.gen(function* () { const org = `org_${crypto.randomUUID()}`; const integration = yield* registerIntegration(org); const name = ConnectionName.make(`conn_${crypto.randomUUID().slice(0, 8)}`); const storedName = canonicalConnectionName(name); const first = yield* asOrg(org, (client) => Effect.gen(function* () { yield* client.connections.create({ payload: { owner: "org", name, integration, template: TEMPLATE_API_KEY, identityLabel: "first", value: "first-value", }, }); return yield* client.connections.list({ query: { integration } }); }), ); expect(first.find((c) => c.name === storedName)?.identityLabel).toBe("first"); const second = yield* asOrg(org, (client) => Effect.gen(function* () { yield* client.connections.create({ payload: { owner: "org", name, integration, template: TEMPLATE_API_KEY, identityLabel: "updated", value: "second-value", }, }); return yield* client.connections.list({ query: { integration } }); }), ); expect(second.find((c) => c.name === storedName)?.identityLabel).toBe("updated"); }), );});
// Connection endpoints — create / list / get / remove round-trip and error
// fidelity within a single org (v2).
//
// Ports the v1 "secrets api" suite. In v2 a connection IS the credential:
// owner-scoped, bound 1:1 to an integration, identified by (owner, integration,
// name). There is no scope id and no separate secret value endpoint — the value
// is stored through the connection's provider and never echoed back.
import { describe, expect, it } from "@effect/vitest";
import { Effect, Result } from "effect";
import { HttpApi, HttpApiEndpoint, HttpApiGroup, OpenApi } from "effect/unstable/httpapi";
import { Schema } from "effect";
import {
AuthTemplateSlug,
ConnectionName,
IntegrationSlug,
connectionIdentifier,
} from "@executor-js/sdk";
import { makeOpenApiHttpApiTestAddSpecPayload } from "@executor-js/plugin-openapi/testing";
import { asOrg } from "../testing/api-harness";
const PingApi = HttpApi.make("connectionsApiTest")
.add(
HttpApiGroup.make("default", { topLevel: true }).add(
HttpApiEndpoint.get("ping", "/ping", { success: Schema.Unknown }),
),
)
.annotateMerge(OpenApi.annotations({ title: "Connections API Test", version: "1.0.0" }));
const TEMPLATE_API_KEY = AuthTemplateSlug.make("apiKey");
const canonicalConnectionName = (name: ConnectionName): ConnectionName =>
connectionIdentifier(String(name));
// Registers a minimal openapi integration so connections have something to bind
// to, then returns its slug.
const registerIntegration = (org: string) =>
Effect.gen(function* () {
const slug = IntegrationSlug.make(`ns_${crypto.randomUUID().replace(/-/g, "_")}`);
yield* asOrg(org, (client) =>
client.openapi.addSpec({
payload: makeOpenApiHttpApiTestAddSpecPayload(PingApi, {
slug,
baseUrl: "http://example.com",
}),
}),
);
return slug;
});
describe("connections api (HTTP)", () => {
it.effect("create → list → get returns connection metadata without the value", () =>
Effect.gen(function* () {
const org = `org_${crypto.randomUUID()}`;
const integration = yield* registerIntegration(org);
const name = ConnectionName.make(`conn_${crypto.randomUUID().slice(0, 8)}`);
const storedName = canonicalConnectionName(name);
const secretValue = "sk-test-abc";
const created = yield* asOrg(org, (client) =>
client.connections.create({
payload: {
owner: "org",
name,
integration,
template: TEMPLATE_API_KEY,
identityLabel: "My API Token",
value: secretValue,
},
}),
);
expect(created.name).toBe(storedName);
expect(created.owner).toBe("org");
expect(JSON.stringify(created)).not.toContain(secretValue);
const list = yield* asOrg(org, (client) =>
client.connections.list({ query: { integration } }),
);
expect(list.find((c) => c.name === storedName)?.identityLabel).toBe("My API Token");
expect(JSON.stringify(list)).not.toContain(secretValue);
const fetched = yield* asOrg(org, (client) =>
client.connections.get({ params: { owner: "org", integration, name: storedName } }),
);
expect(fetched.name).toBe(storedName);
expect(fetched.integration).toBe(integration);
}),
);
it.effect("get on an unknown connection fails with ConnectionNotFoundError", () =>
Effect.gen(function* () {
const org = `org_${crypto.randomUUID()}`;
const integration = yield* registerIntegration(org);
const missing = ConnectionName.make(`missing_${crypto.randomUUID().slice(0, 8)}`);
const result = yield* asOrg(org, (client) =>
client.connections
.get({ params: { owner: "org", integration, name: missing } })
.pipe(Effect.result),
);
expect(Result.isFailure(result)).toBe(true);
}),
);
it.effect("remove deletes the connection; list drops it and get fails", () =>
Effect.gen(function* () {
const org = `org_${crypto.randomUUID()}`;
const integration = yield* registerIntegration(org);
const name = ConnectionName.make(`conn_${crypto.randomUUID().slice(0, 8)}`);
const storedName = canonicalConnectionName(name);
yield* asOrg(org, (client) =>
Effect.gen(function* () {
yield* client.connections.create({
payload: { owner: "org", name, integration, template: TEMPLATE_API_KEY, value: "v" },
});
const removed = yield* client.connections.remove({
params: { owner: "org", integration, name: storedName },
});
expect(removed.removed).toBe(true);
}),
);
const list = yield* asOrg(org, (client) =>
client.connections.list({ query: { integration } }),
);
expect(list.map((c) => c.name)).not.toContain(storedName);
const afterGet = yield* asOrg(org, (client) =>
client.connections
.get({ params: { owner: "org", integration, name: storedName } })
.pipe(Effect.result),
);
expect(Result.isFailure(afterGet)).toBe(true);
}),
);
it.effect("remove on an unknown connection fails with ConnectionNotFoundError", () =>
Effect.gen(function* () {
const org = `org_${crypto.randomUUID()}`;
const integration = yield* registerIntegration(org);
const missing = ConnectionName.make(`missing_${crypto.randomUUID().slice(0, 8)}`);
const result = yield* asOrg(org, (client) =>
client.connections
.remove({ params: { owner: "org", integration, name: missing } })
.pipe(Effect.result),
);
expect(Result.isFailure(result)).toBe(true);
}),
);
it.effect("create with the same (owner, integration, name) twice updates the metadata", () =>
Effect.gen(function* () {
const org = `org_${crypto.randomUUID()}`;
const integration = yield* registerIntegration(org);
const name = ConnectionName.make(`conn_${crypto.randomUUID().slice(0, 8)}`);
const storedName = canonicalConnectionName(name);
const first = yield* asOrg(org, (client) =>
Effect.gen(function* () {
yield* client.connections.create({
payload: {
owner: "org",
name,
integration,
template: TEMPLATE_API_KEY,
identityLabel: "first",
value: "first-value",
},
});
return yield* client.connections.list({ query: { integration } });
}),
);
expect(first.find((c) => c.name === storedName)?.identityLabel).toBe("first");
const second = yield* asOrg(org, (client) =>
Effect.gen(function* () {
yield* client.connections.create({
payload: {
owner: "org",
name,
integration,
template: TEMPLATE_API_KEY,
identityLabel: "updated",
value: "second-value",
},
});
return yield* client.connections.list({ query: { integration } });
}),
);
expect(second.find((c) => c.name === storedName)?.identityLabel).toBe("updated");
}),
);
});