// ── SDK v2 — TeamsClient ─────────────────────────────────────────────────────── // // Covers: // GET /v2/teams // POST /v2/teams // GET /v2/teams/:id // PATCH /v2/teams/:id // DELETE /v2/teams/:id // POST /v2/teams/:id/invitations // GET /v2/teams/:id/invitations // DELETE /v2/teams/:id/invitations/:uid import type { Fetcher } from "../http/fetcher"; import type { RequestOptions } from "../http/types"; import type { Team, TeamCreate, TeamUpdate, TeamMember, TeamMemberCreate, TeamMemberUpdate, InviteCreate, Invite, ListParams, Paginated, } from "../types/index"; export class TeamsClient { constructor(private readonly fetcher: Fetcher) {} // ── Teams CRUD ─────────────────────────────────────────────────────────────── /** * Lists teams with cursor pagination and optional DSL filtering. * * @example * ```ts * const page = await client.teams.list({ limit: 20 }); * for (const team of page.data) console.log(team.name); * ``` */ list(params?: ListParams, opts?: RequestOptions): Promise> { return this.fetcher.list("/teams", params, opts); } /** * Creates a new team. * * @example * ```ts * const team = await client.teams.create({ name: "Engineering", description: "..." }); * ``` */ create(data: TeamCreate, opts?: RequestOptions): Promise { return this.fetcher.post("/teams", data, opts); } /** * Gets a single team by ID. * * @throws {NotFoundError} when no team with `id` exists. */ get(id: string, opts?: RequestOptions): Promise { return this.fetcher.get(`/teams/${id}`, undefined, opts); } /** * Partially updates a team. Only provided fields are changed. * * @throws {NotFoundError} when no team with `id` exists. */ update(id: string, data: TeamUpdate, opts?: RequestOptions): Promise { return this.fetcher.patch(`/teams/${id}`, data, opts); } /** * Deletes a team and all its members. * * @throws {NotFoundError} when no team with `id` exists. */ delete(id: string, opts?: RequestOptions): Promise { return this.fetcher.delete(`/teams/${id}`, opts); } // ── Team Members ───────────────────────────────────────────────────────────── /** * Lists members of a team. * * @example * ```ts * const members = await client.teams.listMembers(teamId); * ``` */ listMembers(teamId: string, params?: ListParams, opts?: RequestOptions): Promise> { return this.fetcher.list(`/teams/${teamId}/members`, params, opts); } /** * Adds a member to a team. * * @example * ```ts * const member = await client.teams.addMember(teamId, { * user_id: "user-123", role: "member", full_name: "Alice" * }); * ``` */ addMember(teamId: string, data: TeamMemberCreate, opts?: RequestOptions): Promise { return this.fetcher.post(`/teams/${teamId}/members`, data, opts); } /** * Updates a team member's role or profile fields. * * @throws {NotFoundError} when the member doesn't exist in the team. */ updateMember(teamId: string, memberId: string, data: TeamMemberUpdate, opts?: RequestOptions): Promise { return this.fetcher.patch(`/teams/${teamId}/members/${memberId}`, data, opts); } /** * Removes a member from a team. * * @throws {NotFoundError} when the member doesn't exist in the team. */ removeMember(teamId: string, memberId: string, opts?: RequestOptions): Promise { return this.fetcher.delete(`/teams/${teamId}/members/${memberId}`, opts); } // ── Invitations ─────────────────────────────────────────────────────────────── /** * Invites a user to a team by email. * Creates a new Firebase user if the email doesn't exist yet. * Returns `is_new_user: true` and a `temp_code` for new accounts. * * @example * ```ts * const result = await client.teams.invite(teamId, { * email: "alice@example.com", * role: "member", * full_name: "Alice", * }); * if (result.is_new_user) console.log("Temp code:", result.temp_code); * ``` */ invite(teamId: string, data: InviteCreate, opts?: RequestOptions): Promise { return this.fetcher.post(`/teams/${teamId}/invitations`, data, opts); } /** * Lists pending invitations for a team. */ listInvitations(teamId: string, params?: ListParams, opts?: RequestOptions): Promise> { return this.fetcher.list(`/teams/${teamId}/invitations`, params, opts); } /** * Removes (cancels) a pending invitation. * * @throws {NotFoundError} when the invitation doesn't exist. */ deleteInvitation(teamId: string, uid: string, opts?: RequestOptions): Promise { return this.fetcher.delete(`/teams/${teamId}/invitations/${uid}`, opts); } }