@better-auth-ui/core
Version:
Authentication components and data utilities for [Better Auth](https://better-auth.com), available for React and Solid.
154 lines (136 loc) • 4.67 kB
text/typescript
import type { MutationOptions, QueryKey } from "@tanstack/query-core"
import type { BetterFetchError } from "better-auth/client"
import type { OrganizationRolesAuthClient } from "./organization-auth-client"
import { organizationMutationKeys } from "./organization-mutation-keys"
import { organizationQueryKeys } from "./organization-query-keys"
type RoleMethod = "createRole" | "updateRole" | "deleteRole"
type RoleParams<
TAuthClient extends OrganizationRolesAuthClient,
TMethod extends RoleMethod
> = NonNullable<Parameters<TAuthClient["organization"][TMethod]>[0]>
function roleMutationOptions<
TAuthClient extends OrganizationRolesAuthClient,
TMethod extends RoleMethod
>(
authClient: TAuthClient,
method: TMethod,
mutationKey: readonly string[],
userId?: string,
organizationId?: string
) {
const mutationFn = async (params: RoleParams<TAuthClient, TMethod>) => {
const resolvedOrganizationId = params.organizationId ?? organizationId
if (!resolvedOrganizationId) {
throw new Error(
`[Better Auth UI] organizationId is required for ${method}.`
)
}
const input = {
...params,
organizationId: resolvedOrganizationId,
fetchOptions: { ...params.fetchOptions, throw: true }
}
if (method === "deleteRole") {
const roleSelector = params as DeleteRoleParams<TAuthClient>
const role = await authClient.organization.getRole({
query: {
organizationId: resolvedOrganizationId,
roleId: roleSelector.roleId,
roleName: roleSelector.roleName
},
fetchOptions: { throw: true }
})
if (role) {
const assignments = await authClient.organization.listMembers({
query: {
organizationId: resolvedOrganizationId,
filterField: "role",
filterOperator: "contains",
filterValue: role.role,
limit: 1
},
fetchOptions: { throw: true }
})
if (assignments?.members.length) {
throw new Error(
`[Better Auth UI] Move members out of the "${role.role}" role before deleting it.`
)
}
}
}
const roleMethod = authClient.organization[method] as (
body: typeof input
) => ReturnType<TAuthClient["organization"][TMethod]>
return await roleMethod(input)
}
const relatedQueries: QueryKey[] = [
organizationQueryKeys.roles.all(userId),
organizationQueryKeys.members.all(userId),
organizationQueryKeys.invitations.all(userId),
organizationQueryKeys.fullDetails(userId)
]
return {
mutationKey,
mutationFn,
meta: {
awaits: relatedQueries,
invalidates: [organizationQueryKeys.permissions.all(userId)]
}
} as MutationOptions<
Awaited<ReturnType<typeof mutationFn>>,
BetterFetchError,
Parameters<typeof mutationFn>[0]
>
}
export type CreateRoleParams<
TAuthClient extends OrganizationRolesAuthClient = OrganizationRolesAuthClient
> = RoleParams<TAuthClient, "createRole">
export type UpdateRoleParams<
TAuthClient extends OrganizationRolesAuthClient = OrganizationRolesAuthClient
> = RoleParams<TAuthClient, "updateRole">
export type DeleteRoleParams<
TAuthClient extends OrganizationRolesAuthClient = OrganizationRolesAuthClient
> = RoleParams<TAuthClient, "deleteRole">
type PublicMutationOptions<T> = Omit<T, "mutationKey" | "mutationFn" | "meta">
export const createRoleOptions = <T extends OrganizationRolesAuthClient>(
authClient: T,
userId?: string,
organizationId?: string
) =>
roleMutationOptions(
authClient,
"createRole",
organizationMutationKeys.roles.create,
userId,
organizationId
)
export const updateRoleOptions = <T extends OrganizationRolesAuthClient>(
authClient: T,
userId?: string,
organizationId?: string
) =>
roleMutationOptions(
authClient,
"updateRole",
organizationMutationKeys.roles.update,
userId,
organizationId
)
export const deleteRoleOptions = <T extends OrganizationRolesAuthClient>(
authClient: T,
userId?: string,
organizationId?: string
) =>
roleMutationOptions(
authClient,
"deleteRole",
organizationMutationKeys.roles.delete,
userId,
organizationId
)
export type CreateRoleOptions<T extends OrganizationRolesAuthClient> =
PublicMutationOptions<ReturnType<typeof createRoleOptions<T>>>
export type UpdateRoleOptions<T extends OrganizationRolesAuthClient> =
PublicMutationOptions<ReturnType<typeof updateRoleOptions<T>>>
export type DeleteRoleOptions<T extends OrganizationRolesAuthClient> =
PublicMutationOptions<ReturnType<typeof deleteRoleOptions<T>>>