import { managementAuth } from './setup.ts'
import { assertMutationAllowed, readMutationFlags } from './safety.ts'
import { managementRequest as sendManagement } from './client.ts'
import {
isReadMethod,
isRecord,
normalizeHttpMethod,
optionalBoolean,
optionalString,
requireString,
type HttpMethod,
type Json,
type SupabaseAuthInput,
} from './types.ts'
export type ManagementRequestInput = SupabaseAuthInput & {
path: string
method?: HttpMethod
query?: Record<string, string | number | boolean | undefined>
body?: Json
dryRun?: boolean
confirm?: boolean
}
function normalizeManagementPath(path: string): string {
const trimmed = path.startsWith('/') ? path : `/${path}`
if (trimmed.startsWith('/v1/') || trimmed === '/v1') return trimmed
return `/v1${trimmed}`
}
/**
* Call the Supabase Management API (`https://api.supabase.com`).
* Prefer named helpers. Mutating methods require `dryRun: true` or `confirm: true`.
* @example
* import managementRequest from 'kody:@kody/supabase/management-request'
* const result = await managementRequest({ path: '/v1/projects' })
*/
export async function managementRequest(input: ManagementRequestInput) {
const method = normalizeHttpMethod(input.method, 'GET')
if (!isReadMethod(method)) {
assertMutationAllowed(readMutationFlags(input), `management-request ${method}`)
}
return await sendManagement({
auth: managementAuth(input),
method,
path: normalizeManagementPath(requireString(input.path, 'path')),
query: input.query,
body: input.body,
dryRun: input.dryRun === true,
})
}
/**
* Call the Supabase Management API. Prefer named helpers.
* Mutating methods require `dryRun: true` or `confirm: true`.
* @example
* import managementRequest from 'kody:@kody/supabase/management-request'
* const result = await managementRequest({ path: '/projects' })
*/
export default async function managementRequestEntrypoint(
params: Partial<ManagementRequestInput> & Record<string, unknown> = {},
) {
return await managementRequest({
account: optionalString(params.account, 'account'),
secretName: optionalString(params.secretName, 'secretName'),
patSecretName: optionalString(params.patSecretName, 'patSecretName'),
path: requireString(params.path, 'path'),
method: normalizeHttpMethod(params.method, 'GET'),
query: isRecord(params.query)
? (params.query as Record<string, string | number | boolean | undefined>)
: undefined,
body: params.body as Json | undefined,
dryRun: optionalBoolean(params.dryRun, 'dryRun'),
confirm: optionalBoolean(params.confirm, 'confirm'),
})
}