mirror of
https://github.com/langgenius/dify.git
synced 2026-06-07 16:32:01 +08:00
76 lines
2.4 KiB
TypeScript
76 lines
2.4 KiB
TypeScript
import type { ActiveContext } from '@/auth/hosts'
|
|
import type { HttpClient } from '@/http/types'
|
|
import type { IOStreams } from '@/sys/io/streams'
|
|
import { MembersClient } from '@/api/members'
|
|
import { BaseError } from '@/errors/base'
|
|
import { ErrorCode } from '@/errors/codes'
|
|
import { colorEnabled, colorScheme } from '@/sys/io/color'
|
|
import { runWithSpinner } from '@/sys/io/spinner'
|
|
import { nullStreams } from '@/sys/io/streams'
|
|
import { resolveWorkspaceId } from '@/workspace/resolver'
|
|
import { InviteOutput } from './handlers.js'
|
|
|
|
export type CreateMemberOptions = {
|
|
readonly email: string
|
|
readonly role: string
|
|
readonly workspace?: string
|
|
readonly format?: string
|
|
}
|
|
|
|
export type CreateMemberDeps = {
|
|
readonly active: ActiveContext
|
|
readonly http: HttpClient
|
|
readonly io?: IOStreams
|
|
readonly envLookup?: (k: string) => string | undefined
|
|
readonly membersFactory?: (http: HttpClient) => MembersClient
|
|
}
|
|
|
|
export type CreateMemberResult = {
|
|
readonly data: InviteOutput
|
|
readonly workspaceId: string
|
|
}
|
|
|
|
// `owner` is intentionally absent — ownership transfer is console-only.
|
|
const ASSIGNABLE_ROLES = new Set(['normal', 'admin'])
|
|
|
|
export async function runCreateMember(
|
|
opts: CreateMemberOptions,
|
|
deps: CreateMemberDeps,
|
|
): Promise<CreateMemberResult> {
|
|
if (opts.email === undefined || opts.email === '') {
|
|
throw new BaseError({
|
|
code: ErrorCode.UsageMissingArg,
|
|
message: '--email is required',
|
|
})
|
|
}
|
|
if (!ASSIGNABLE_ROLES.has(opts.role)) {
|
|
throw new BaseError({
|
|
code: ErrorCode.UsageInvalidFlag,
|
|
message: `invalid --role "${opts.role}"`,
|
|
hint: 'expected: normal | admin (ownership transfer is console-only)',
|
|
})
|
|
}
|
|
|
|
const env = deps.envLookup ?? ((k: string) => process.env[k])
|
|
const factory = deps.membersFactory ?? ((h: HttpClient) => new MembersClient(h))
|
|
const io = deps.io ?? nullStreams()
|
|
const cs = colorScheme(colorEnabled(io.isErrTTY))
|
|
|
|
const wsId = resolveWorkspaceId({
|
|
flag: opts.workspace,
|
|
env: env('DIFY_WORKSPACE_ID'),
|
|
active: deps.active,
|
|
})
|
|
|
|
const response = await runWithSpinner(
|
|
{ io, label: `Inviting ${opts.email}` },
|
|
() => factory(deps.http).invite(wsId, {
|
|
email: opts.email,
|
|
role: opts.role as 'normal' | 'admin',
|
|
}),
|
|
)
|
|
|
|
const textLine = `${cs.successIcon()} Invited ${response.email} as ${response.role}\n`
|
|
return { data: new InviteOutput(response, textLine), workspaceId: wsId }
|
|
}
|