import { projectAuth } from './setup.ts'
import { asLive, projectRequest } from './client.ts'
import {
filterQuery,
optionalSchema,
profileHeaders,
readFilters,
requireTable,
restPath,
} from './table.ts'
import {
clampInt,
optionalString,
type JsonRecord,
type SupabaseAuthInput,
} from './types.ts'
/**
* Read rows from a PostgREST table (service role, bypasses RLS).
* @example
* import selectRows from 'kody:@kody/supabase/select-rows'
* const { items } = await selectRows({
* projectRef: 'abcdefghijklmnop',
* table: 'items',
* select: 'id,name',
* filters: { status: 'eq.active' },
* limit: 20,
* })
*/
export async function selectRows(
input: SupabaseAuthInput & {
table: string
schema?: string
select?: string
filters?: Record<string, string>
order?: string
limit?: number
offset?: number
},
): Promise<{ items: Array<JsonRecord>; count: number }> {
const table = requireTable(input.table)
const limit = clampInt(input.limit, 1, 1000, 50)
const offset = clampInt(input.offset, 0, 1_000_000, 0, 'offset')
const live = asLive<{ data: unknown }>(
await projectRequest({
auth: projectAuth(input),
method: 'GET',
path: restPath(table),
headers: profileHeaders(optionalSchema(input.schema)),
query: filterQuery(input.filters, {
select: optionalString(input.select, 'select') ?? '*',
order: optionalString(input.order, 'order'),
limit,
offset,
}),
}),
)
const items = Array.isArray(live.data) ? (live.data as Array<JsonRecord>) : []
return { items, count: items.length }
}
/**
* Read rows from a PostgREST table (service role, bypasses RLS).
* @example
* import selectRows from 'kody:@kody/supabase/select-rows'
* const result = await selectRows({ projectRef: 'abcdefghijklmnop', table: 'items' })
*/
export default async function selectRowsEntrypoint(
params: Partial<SupabaseAuthInput> & Record<string, unknown> = {},
) {
return await selectRows({
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'),
table: requireTable(params.table),
schema: optionalSchema(params.schema),
select: optionalString(params.select, 'select'),
filters: readFilters(params.filters),
order: optionalString(params.order, 'order'),
limit: typeof params.limit === 'number' ? params.limit : undefined,
offset: typeof params.offset === 'number' ? params.offset : undefined,
})
}