feat(server): plugins list says which sources sign in with a device code

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
Lucas Winther
2026-10-30 22:13:24 +01:00
co-authored by Claude Opus 5.5
parent c2e8c83f86
commit 53d9e7c9c9
3 changed files with 10 additions and 2 deletions
+2 -2
View File
@@ -38,9 +38,9 @@ export const sourceRoutes = [
route({
method: "GET",
path: "plugins",
summary: "Installed source plugins (manifests).",
summary: "Installed source plugins (manifests, plus deviceAuth: whether sign-in uses a device code).",
auth: "any:read",
handler: async ({ deps }) => deps.registry.list(),
handler: async ({ deps }) => deps.registry.list().map((m) => ({ ...m, deviceAuth: !!deps.registry.get(m.id)?.deviceAuth })),
}),
route({
method: "GET",
+6
View File
@@ -348,6 +348,12 @@ forEachDialect("api", (getDb) => {
expect(await (await call(app, "GET", "copies", { cookie: ana })).json()).toEqual([expect.objectContaining({ workTitle: "Dune", format: "Paperback" })]);
});
test("plugins: manifests say whether the source signs in with a device code", async () => {
const ana = await signUp(app, "ana");
const list = (await (await call(app, "GET", "plugins", { cookie: ana })).json()) as { id: string; deviceAuth: boolean; config: unknown[] }[];
expect(list.find((p) => p.id === "echo")).toEqual(expect.objectContaining({ deviceAuth: false, config: expect.any(Array) }));
});
test("JSON bodies need Content-Type application/json (415)", async () => {
const res = await app.fetch(
new Request(`${BASE}/auth/register`, {
+2
View File
@@ -17,6 +17,8 @@ No index: `grep -n '^## ' docs/DECISIONS.md` lists every entry (date, title, lin
list to its name; null when gone) **and, on merged events, `intoTitle`**: the title of the entry that the same
connection's `intoKey` record maps to, else null. Titles come from a fixed number of batched queries
(`packages/core/src/titles.ts`), not one per event.
- **`GET plugins` adds `deviceAuth: boolean`** to each manifest, so the Sources screen knows when to offer the
device-code sign-in (the manifest itself has no such capability).
- **`listCopies` items carry `workTitle`** (override-aware, null while unmatched) so Owned needs no per-row work lookups.
The export bundle is unchanged.