Download superlog/apps/api/src/mcp/projects.ts from smlflg/Experimente: direct link, hf CLI and curl.
- Browser
- Download file 2.26 kB
-
https://huggingface.co/smlflg/Experimente/resolve/main/superlog/apps/api/src/mcp/projects.ts
- Command line
-
hf download hf://smlflg/Experimente/superlog/apps/api/src/mcp/projects.ts
-
curl -L -o projects.ts https://huggingface.co/smlflg/Experimente/resolve/main/superlog/apps/api/src/mcp/projects.ts
2.26 kB
| import { db, schema } from "@superlog/db"; | |
| import { and, eq, inArray } from "drizzle-orm"; | |
| import { HTTPException } from "hono/http-exception"; | |
| export type AccessibleProject = { | |
| id: string; | |
| name: string; | |
| slug: string; | |
| orgId: string; | |
| orgName: string; | |
| orgSlug: string; | |
| }; | |
| export async function listAccessibleProjects(userId: string): Promise<AccessibleProject[]> { | |
| const memberships = await db.query.orgMembers.findMany({ | |
| where: eq(schema.orgMembers.userId, userId), | |
| }); | |
| if (memberships.length === 0) return []; | |
| const orgIds = memberships.map((m) => m.orgId); | |
| const orgs = await db.query.orgs.findMany({ | |
| where: inArray(schema.orgs.id, orgIds), | |
| }); | |
| const orgById = new Map(orgs.map((o) => [o.id, o])); | |
| const projects = await db.query.projects.findMany({ | |
| where: inArray(schema.projects.orgId, orgIds), | |
| }); | |
| return projects | |
| .map((p) => { | |
| const o = orgById.get(p.orgId); | |
| if (!o) return null; | |
| return { | |
| id: p.id, | |
| name: p.name, | |
| slug: p.slug, | |
| orgId: o.id, | |
| orgName: o.name, | |
| orgSlug: o.slug, | |
| }; | |
| }) | |
| .filter((x): x is AccessibleProject => x !== null); | |
| } | |
| export async function assertProjectAccess(userId: string, projectId: string): Promise<void> { | |
| const project = await db.query.projects.findFirst({ | |
| where: eq(schema.projects.id, projectId), | |
| }); | |
| if (!project) throw new HTTPException(404, { message: "project not found" }); | |
| const membership = await db.query.orgMembers.findFirst({ | |
| where: and( | |
| eq(schema.orgMembers.userId, userId), | |
| eq(schema.orgMembers.orgId, project.orgId), | |
| ), | |
| }); | |
| if (!membership) throw new HTTPException(403, { message: "no access to project" }); | |
| } | |
| export async function setActiveProjectForToken( | |
| tokenId: string, | |
| userId: string, | |
| projectId: string, | |
| ): Promise<AccessibleProject> { | |
| await assertProjectAccess(userId, projectId); | |
| await db | |
| .update(schema.mcpOauthTokens) | |
| .set({ projectId }) | |
| .where(eq(schema.mcpOauthTokens.id, tokenId)); | |
| const projects = await listAccessibleProjects(userId); | |
| const found = projects.find((p) => p.id === projectId); | |
| if (!found) throw new HTTPException(500, { message: "project vanished after switch" }); | |
| return found; | |
| } | |