refactor(core): simplify integration credentials (#31968)
This commit is contained in:
parent
a9c810cbbc
commit
30aec297d8
112 changed files with 2467 additions and 47728 deletions
|
|
@ -650,49 +650,67 @@ const scenarios: Scenario[] = [
|
|||
http.protected.get("/api/agent", "v2.agent.list").json(200, locationData(array)),
|
||||
http.protected.get("/api/model", "v2.model.list").json(200, locationData(array)),
|
||||
http.protected.get("/api/provider", "v2.provider.list").json(200, locationData(array)),
|
||||
http.protected.get("/api/connector", "v2.connector.list").json(200, locationData(array)),
|
||||
http.protected.get("/api/integration", "v2.integration.list").json(200, locationData(array)),
|
||||
http.protected
|
||||
.get("/api/connector/{connectorID}", "v2.connector.get")
|
||||
.at((ctx) => ({ path: route("/api/connector/{connectorID}", { connectorID: "missing" }), headers: ctx.headers() }))
|
||||
.get("/api/integration/{integrationID}", "v2.integration.get")
|
||||
.at((ctx) => ({
|
||||
path: route("/api/integration/{integrationID}", { integrationID: "missing" }),
|
||||
headers: ctx.headers(),
|
||||
}))
|
||||
.json(200, object),
|
||||
http.protected
|
||||
.post("/api/connector/{connectorID}/connect/key", "v2.connector.connect.key")
|
||||
.post("/api/integration/{integrationID}/connect/key", "v2.integration.connect.key")
|
||||
.at((ctx) => ({
|
||||
path: route("/api/connector/{connectorID}/connect/key", { connectorID: "missing" }),
|
||||
path: route("/api/integration/{integrationID}/connect/key", { integrationID: "missing" }),
|
||||
headers: ctx.headers(),
|
||||
body: { methodID: "missing", key: "test", inputs: {} },
|
||||
body: { key: "test" },
|
||||
}))
|
||||
.status(500, undefined, "status"),
|
||||
http.protected
|
||||
.post("/api/connector/{connectorID}/connect/oauth", "v2.connector.connect.oauth.begin")
|
||||
.post("/api/integration/{integrationID}/connect/oauth", "v2.integration.connect.oauth")
|
||||
.at((ctx) => ({
|
||||
path: route("/api/connector/{connectorID}/connect/oauth", { connectorID: "missing" }),
|
||||
path: route("/api/integration/{integrationID}/connect/oauth", { integrationID: "missing" }),
|
||||
headers: ctx.headers(),
|
||||
body: { methodID: "missing", inputs: {} },
|
||||
}))
|
||||
.status(500, undefined, "status"),
|
||||
http.protected
|
||||
.get("/api/connector/oauth/{attemptID}", "v2.connector.connect.oauth.status")
|
||||
.get("/api/integration/attempt/{attemptID}", "v2.integration.attempt.status")
|
||||
.at((ctx) => ({
|
||||
path: route("/api/connector/oauth/{attemptID}", { attemptID: "con_missing" }),
|
||||
path: route("/api/integration/attempt/{attemptID}", { attemptID: "con_missing" }),
|
||||
headers: ctx.headers(),
|
||||
}))
|
||||
.status(500, undefined, "status"),
|
||||
http.protected
|
||||
.post("/api/connector/oauth/{attemptID}/complete", "v2.connector.connect.oauth.complete")
|
||||
.post("/api/integration/attempt/{attemptID}/complete", "v2.integration.attempt.complete")
|
||||
.at((ctx) => ({
|
||||
path: route("/api/connector/oauth/{attemptID}/complete", { attemptID: "con_missing" }),
|
||||
path: route("/api/integration/attempt/{attemptID}/complete", { attemptID: "con_missing" }),
|
||||
headers: ctx.headers(),
|
||||
body: {},
|
||||
}))
|
||||
.status(500, undefined, "status"),
|
||||
http.protected
|
||||
.delete("/api/connector/oauth/{attemptID}", "v2.connector.connect.oauth.cancel")
|
||||
.delete("/api/integration/attempt/{attemptID}", "v2.integration.attempt.cancel")
|
||||
.at((ctx) => ({
|
||||
path: route("/api/connector/oauth/{attemptID}", { attemptID: "con_missing" }),
|
||||
path: route("/api/integration/attempt/{attemptID}", { attemptID: "con_missing" }),
|
||||
headers: ctx.headers(),
|
||||
}))
|
||||
.status(204, undefined, "status"),
|
||||
http.protected
|
||||
.delete("/api/credential/{credentialID}", "v2.credential.remove")
|
||||
.at((ctx) => ({
|
||||
path: route("/api/credential/{credentialID}", { credentialID: "cred_missing" }),
|
||||
headers: ctx.headers(),
|
||||
}))
|
||||
.status(204, undefined, "status"),
|
||||
http.protected
|
||||
.patch("/api/credential/{credentialID}", "v2.credential.update")
|
||||
.at((ctx) => ({
|
||||
path: route("/api/credential/{credentialID}", { credentialID: "cred_missing" }),
|
||||
headers: ctx.headers(),
|
||||
body: { label: "Work" },
|
||||
}))
|
||||
.status(204, undefined, "status"),
|
||||
http.protected.get("/api/command", "v2.command.list").json(200, locationData(array)),
|
||||
http.protected.get("/api/skill", "v2.skill.list").json(200, locationData(array)),
|
||||
http.protected
|
||||
|
|
|
|||
|
|
@ -115,25 +115,27 @@ describe("PublicApi OpenAPI v2 errors", () => {
|
|||
}
|
||||
})
|
||||
|
||||
test("documents connector discovery and connection routes", () => {
|
||||
test("documents integration discovery and connection routes", () => {
|
||||
const spec = OpenApi.fromApi(PublicApi) as OpenApiSpec
|
||||
|
||||
for (const [method, path] of [
|
||||
["get", "/api/connector"],
|
||||
["get", "/api/connector/{connectorID}"],
|
||||
["post", "/api/connector/{connectorID}/connect/key"],
|
||||
["post", "/api/connector/{connectorID}/connect/oauth"],
|
||||
["get", "/api/connector/oauth/{attemptID}"],
|
||||
["post", "/api/connector/oauth/{attemptID}/complete"],
|
||||
["delete", "/api/connector/oauth/{attemptID}"],
|
||||
["get", "/api/integration"],
|
||||
["get", "/api/integration/{integrationID}"],
|
||||
["post", "/api/integration/{integrationID}/connect/key"],
|
||||
["post", "/api/integration/{integrationID}/connect/oauth"],
|
||||
["get", "/api/integration/attempt/{attemptID}"],
|
||||
["post", "/api/integration/attempt/{attemptID}/complete"],
|
||||
["delete", "/api/integration/attempt/{attemptID}"],
|
||||
["delete", "/api/credential/{credentialID}"],
|
||||
["patch", "/api/credential/{credentialID}"],
|
||||
] as const) {
|
||||
expect(spec.paths[path]?.[method], `${method.toUpperCase()} ${path}`).toBeDefined()
|
||||
}
|
||||
|
||||
for (const path of [
|
||||
"/api/connector/{connectorID}/connect/key",
|
||||
"/api/connector/{connectorID}/connect/oauth",
|
||||
"/api/connector/oauth/{attemptID}/complete",
|
||||
"/api/integration/{integrationID}/connect/key",
|
||||
"/api/integration/{integrationID}/connect/oauth",
|
||||
"/api/integration/attempt/{attemptID}/complete",
|
||||
]) {
|
||||
expect(spec.paths[path]?.post?.requestBody?.required, path).toBe(true)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,50 +0,0 @@
|
|||
import { describe, expect, test } from "bun:test"
|
||||
import { Database } from "bun:sqlite"
|
||||
import { drizzle } from "drizzle-orm/bun-sqlite"
|
||||
import { migrate } from "drizzle-orm/bun-sqlite/migrator"
|
||||
import { existsSync, readFileSync, readdirSync } from "fs"
|
||||
import path from "path"
|
||||
|
||||
const target = "20260507164347_add_workspace_time"
|
||||
|
||||
function migrations() {
|
||||
return readdirSync(path.join(import.meta.dirname, "../../../core/migration"), { withFileTypes: true })
|
||||
.filter(
|
||||
(entry) =>
|
||||
entry.isDirectory() &&
|
||||
existsSync(path.join(import.meta.dirname, "../../../core/migration", entry.name, "migration.sql")),
|
||||
)
|
||||
.map((entry) => ({
|
||||
name: entry.name,
|
||||
timestamp: Number(entry.name.split("_")[0]),
|
||||
sql: readFileSync(
|
||||
path.join(import.meta.dirname, "../../../core/migration", entry.name, "migration.sql"),
|
||||
"utf-8",
|
||||
),
|
||||
}))
|
||||
.sort((a, b) => a.timestamp - b.timestamp)
|
||||
}
|
||||
|
||||
describe("workspace time migration", () => {
|
||||
test("discards existing workspace rows during the beta reset", () => {
|
||||
const sqlite = new Database(":memory:")
|
||||
const db = drizzle({ client: sqlite })
|
||||
const entries = migrations()
|
||||
const index = entries.findIndex((entry) => entry.name === target)
|
||||
|
||||
expect(index).toBeGreaterThan(0)
|
||||
|
||||
migrate(db, entries.slice(0, index))
|
||||
sqlite.run(
|
||||
"INSERT INTO project (id, worktree, vcs, name, time_created, time_updated, sandboxes) VALUES (?, ?, ?, ?, ?, ?, ?)",
|
||||
["project_1", "/tmp/project", "git", "project", 1, 1, "[]"],
|
||||
)
|
||||
sqlite.run(
|
||||
"INSERT INTO workspace (id, type, name, branch, directory, extra, project_id) VALUES (?, ?, ?, ?, ?, ?, ?)",
|
||||
["workspace_1", "local", "main", "main", "/tmp/project", null, "project_1"],
|
||||
)
|
||||
|
||||
expect(() => migrate(db, entries.slice(index))).not.toThrow()
|
||||
expect(sqlite.query("SELECT time_used FROM workspace WHERE id = ?").get("workspace_1")).toBeNull()
|
||||
})
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue