Class: Teams
Defined in: teams/src/teams.ts:157
Team membership and email invitations for multi-user tenants. Decoupled from auth and tenancy: identifiers are passed in. Optionally mirrors role changes into a RoleAssigner (e.g. @basaltkit/permissions).
Constructors
Constructor
> new Teams(options?): Teams
Defined in: teams/src/teams.ts:168
Parameters
options?
TeamsOptions = {}
Returns
Teams
Methods
accept()
> accept(token, userId, acceptingEmail?): Promise<Membership>
Defined in: teams/src/teams.ts:305
Consumes an invitation token and enrolls userId at the invited role. Idempotent for an already-accepted membership of the same user.
Parameters
token
string
userId
string
acceptingEmail?
string
Returns
Promise<Membership>
addMember()
> addMember(tenantId, userId, role, opts?): Promise<Membership>
Defined in: teams/src/teams.ts:227
Directly adds/updates a membership — used to seed a team's first owner.
Parameters
tenantId
string
userId
string
role
string
opts?
actingUserId?
string
Returns
Promise<Membership>
can()
> can(tenantId, userId, required): Promise<boolean>
Defined in: teams/src/teams.ts:441
True when the user holds required or a higher-ranked role in the team.
Only a ranked required role has a hierarchy, and only a ranked member role can climb it. A required role outside roleRank (a custom role from grantableRoles, or a typo such as 'Admin') is matched exactly — it never ranks 0 and admits every member. An empty or non-string required is always false.
Parameters
tenantId
string
userId
string
required
string
Returns
Promise<boolean>
changeRole()
> changeRole(tenantId, userId, role, opts?): Promise<Membership>
Defined in: teams/src/teams.ts:449
Parameters
tenantId
string
userId
string
role
string
opts?
actingUserId?
string
Returns
Promise<Membership>
invitation()
> invitation(id): Promise<PublicInvitation | null>
Defined in: teams/src/teams.ts:416
Parameters
id
string
Returns
Promise<PublicInvitation | null>
invite()
> invite(input): Promise<{ invitation: PublicInvitation; token: string; }>
Defined in: teams/src/teams.ts:263
Creates (or refreshes) an invitation and emits team:invited for the app to email. Returns the public invitation plus the token (for building the link). One pending invite per email per team — a new one supersedes it.
Parameters
input
actingUserId?
string
When set, enforce that the inviter can't grant a role above their own.
email
string
invitedBy?
string
role?
string
tenantId
string
Returns
Promise<{ invitation: PublicInvitation; token: string; }>
isKnownRole()
> isKnownRole(role): role is string
Defined in: teams/src/teams.ts:195
True for a role this service knows: ranked in roleRank or listed in grantableRoles. The meta.teamRole guard refuses anything else with UnknownTeamRoleError, so a typo can never rank 0 and admit everyone.
Parameters
role
unknown
Returns
role is string
members()
> members(tenantId): Promise<Membership[]>
Defined in: teams/src/teams.ts:336
Parameters
tenantId
string
Returns
Promise<Membership[]>
membersWithUsers()
> membersWithUsers(tenantId): Promise<TeamMemberWithUser[]>
Defined in: teams/src/teams.ts:358
The tenant's memberships with each member's contact details attached — the primitive behind "notify everyone with this role", and the ONE place the user lookup is batched.
Requires a users directory (an @basaltkit/auth UserSource fits). When it implements findByIds the whole team resolves in a single bulk lookup; otherwise it falls back to one findById per member, so an app gets the fast path automatically the day its driver grows one, with no code change.
Tenant safety: the ids come from THIS tenant's membership records and nowhere else — a caller never chooses which accounts are looked up — and a user the directory returns that was not asked for is discarded. A membership whose account does not exist is skipped (see TeamMemberWithUser); the membership record itself is left alone.
Order follows members.
Parameters
tenantId
string
Returns
Promise<TeamMemberWithUser[]>
pendingInvites()
> pendingInvites(tenantId): Promise<PublicInvitation[]>
Defined in: teams/src/teams.ts:411
Parameters
tenantId
string
Returns
Promise<PublicInvitation[]>
rankOf()
> rankOf(role): number
Defined in: teams/src/teams.ts:180
Parameters
role
string
Returns
number
removeMember()
> removeMember(tenantId, userId, opts?): Promise<void>
Defined in: teams/src/teams.ts:486
Removes a membership. When actingUserId is given (HTTP routes), the actor must be a member and may only remove themselves or someone who does not outrank them — an admin can't remove an owner. Omit the actor for trusted server-side flows.
Parameters
tenantId
string
userId
string
opts?
actingUserId?
string
Returns
Promise<void>
revokeInvite()
> revokeInvite(id): Promise<void>
Defined in: teams/src/teams.ts:421
Parameters
id
string
Returns
Promise<void>
roleOf()
> roleOf(tenantId, userId): Promise<string | null>
Defined in: teams/src/teams.ts:428
Parameters
tenantId
string
userId
string
Returns
Promise<string | null>
roleRecipients()
> roleRecipients(tenantId, role, opts?): Promise<TeamMemberWithUser[]>
Defined in: teams/src/teams.ts:398
Who to notify for a role — a thin filter over membersWithUsers, so it costs no extra lookup.
A ranked role (one present in roleRank) includes everyone at or above it: roleRecipients(t, 'admin') also returns the owners, which is what "tell the admins" almost always means. Roles outside roleRank have no hierarchy — every unranked role ranks 0, so treating them by rank would notify all of them — and are therefore matched exactly; ranked roles can be narrowed the same way with { exact: true }.
Parameters
tenantId
string
role
string
opts?
exact?
boolean
Returns
Promise<TeamMemberWithUser[]>