import { projectAuth } from './setup.ts' import { assertMutationAllowed, readMutationFlags } from './safety.ts' import { projectRequest } from './client.ts' import { isReadMethod, isRecord, normalizeHttpMethod, optionalBoolean, optionalString, requireString, type HttpMethod, type Json, type SupabaseAuthInput, } from './types.ts' export type ProjectRequestInput = SupabaseAuthInput & { path: string method?: HttpMethod query?: Record headers?: Record body?: Json dryRun?: boolean confirm?: boolean } /** * Call a project API path (Auth, PostgREST, Storage, or another /.../v1 route). * Prefer named helpers. Mutating methods require `dryRun: true` or `confirm: true`. * @example * import request from 'kody:@kody/supabase/request' * const result = await request({ * projectRef: 'abcdefghijklmnop', * path: '/rest/v1/items', * query: { select: 'id,name', limit: 5 }, * }) */ export async function request(input: ProjectRequestInput) { const path = requireString(input.path, 'path') if (!path.startsWith('/')) { throw new Error('path must start with "/".') } const method = normalizeHttpMethod(input.method, 'GET') if (!isReadMethod(method)) { assertMutationAllowed(readMutationFlags(input), `request ${method}`) } return await projectRequest({ auth: projectAuth(input), method, path, query: input.query, headers: input.headers, body: input.body, dryRun: input.dryRun === true, }) } /** * Call a project API path. Prefer named helpers. * Mutating methods require `dryRun: true` or `confirm: true`. * @example * import request from 'kody:@kody/supabase/request' * const result = await request({ projectRef: 'abcdefghijklmnop', path: '/rest/v1/items?select=id' }) */ export default async function requestEntrypoint( params: Partial & Record = {}, ) { return await request({ 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'), path: requireString(params.path, 'path'), method: normalizeHttpMethod(params.method, 'GET'), query: isRecord(params.query) ? (params.query as Record) : undefined, headers: isRecord(params.headers) ? Object.fromEntries( Object.entries(params.headers).filter( (entry): entry is [string, string] => typeof entry[1] === 'string', ), ) : undefined, body: params.body as Json | undefined, dryRun: optionalBoolean(params.dryRun, 'dryRun'), confirm: optionalBoolean(params.confirm, 'confirm'), }) }