import { projectAuth } from './setup.ts' import { assertMutationAllowed, readMutationFlags } from './safety.ts' import { asLive, projectRequest } from './client.ts' import { summarizeAuthUser } from './list-users.ts' import { isRecord, optionalBoolean, optionalString, type DryRunResult, type JsonRecord, type SupabaseAuthInput, } from './types.ts' export type CreateUserInput = SupabaseAuthInput & { email?: string phone?: string password?: string emailConfirm?: boolean phoneConfirm?: boolean userMetadata?: JsonRecord appMetadata?: JsonRecord dryRun?: boolean confirm?: boolean } /** * Create an Auth user. Requires `confirm: true`, or use `dryRun: true`. * @example * import createUser from 'kody:@kody/supabase/create-user' * const preview = await createUser({ * projectRef: 'abcdefghijklmnop', * email: 'ada@example.com', * dryRun: true, * }) */ export async function createUser(input: CreateUserInput) { const flags = readMutationFlags(input) const email = optionalString(input.email, 'email') const phone = optionalString(input.phone, 'phone') if (!email && !phone) { throw new Error('create-user requires email or phone.') } const body: JsonRecord = { email, phone, password: optionalString(input.password, 'password'), email_confirm: optionalBoolean(input.emailConfirm, 'emailConfirm'), phone_confirm: optionalBoolean(input.phoneConfirm, 'phoneConfirm'), user_metadata: input.userMetadata, app_metadata: input.appMetadata, } const previewBody = { ...body, password: body.password ? '[redacted]' : undefined } const allowed = assertMutationAllowed(flags, 'create-user') if (allowed.dryRun) { const preview: DryRunResult = { dryRun: true, method: 'POST', path: '/auth/v1/admin/users', body: previewBody, } return preview } const live = asLive<{ data: unknown }>( await projectRequest({ auth: projectAuth(input), method: 'POST', path: '/auth/v1/admin/users', body, }), ) return summarizeAuthUser(live.data, true) } /** * Create an Auth user. Requires `confirm: true`, or use `dryRun: true`. * @example * import createUser from 'kody:@kody/supabase/create-user' * const preview = await createUser({ projectRef: 'abcdefghijklmnop', email: 'ada@example.com', dryRun: true }) */ export default async function createUserEntrypoint( params: Partial & Record = {}, ) { return await createUser({ account: optionalString(params.account, 'account'), secretName: optionalString(params.secretName, 'secretName'), serviceRoleSecretName: optionalString( params.serviceRoleSecretName, 'serviceRoleSecretName', ), projectRef: optionalString(params.projectRef, 'projectRef'), projectUrl: optionalString(params.projectUrl, 'projectUrl'), email: optionalString(params.email, 'email'), phone: optionalString(params.phone, 'phone'), password: optionalString(params.password, 'password'), emailConfirm: optionalBoolean(params.emailConfirm, 'emailConfirm'), phoneConfirm: optionalBoolean(params.phoneConfirm, 'phoneConfirm'), userMetadata: isRecord(params.userMetadata) ? params.userMetadata : undefined, appMetadata: isRecord(params.appMetadata) ? params.appMetadata : undefined, dryRun: optionalBoolean(params.dryRun, 'dryRun'), confirm: optionalBoolean(params.confirm, 'confirm'), }) }