import { projectAuth } from './setup.ts'
import {
assertFilteredWrite,
assertMutationAllowed,
readMutationFlags,
} from './safety.ts'
import { asLive, projectRequest } from './client.ts'
import {
filterQuery,
optionalSchema,
profileHeaders,
readFilters,
requireTable,
restPath,
} from './table.ts'
import {
optionalBoolean,
optionalString,
type DryRunResult,
type JsonRecord,
type SupabaseAuthInput,
} from './types.ts'
/**
* Delete rows from a PostgREST table. Requires `confirm: true`, or use `dryRun: true`.
* Unfiltered deletes also need `allowUnfiltered: true`.
* @example
* import deleteRows from 'kody:@kody/supabase/delete-rows'
* const preview = await deleteRows({
* projectRef: 'abcdefghijklmnop',
* table: 'items',
* filters: { id: 'eq.1' },
* dryRun: true,
* })
*/
export async function deleteRows(
input: SupabaseAuthInput & {
table: string
schema?: string
filters?: Record<string, string>
allowUnfiltered?: boolean
dryRun?: boolean
confirm?: boolean
},
) {
const table = requireTable(input.table)
const flags = readMutationFlags(input)
assertFilteredWrite(
{
hasFilters: Boolean(input.filters && Object.keys(input.filters).length > 0),
allowUnfiltered: input.allowUnfiltered,
dryRun: flags.dryRun,
confirm: flags.confirm,
},
'delete-rows',
)
const allowed = assertMutationAllowed(flags, 'delete-rows')
const path = restPath(table)
if (allowed.dryRun) {
const preview: DryRunResult = {
dryRun: true,
method: 'DELETE',
path,
query: input.filters,
}
return preview
}
const live = asLive<{ data: unknown }>(
await projectRequest({
auth: projectAuth(input),
method: 'DELETE',
path,
headers: {
...profileHeaders(optionalSchema(input.schema)),
Prefer: 'return=representation',
},
query: filterQuery(input.filters),
}),
)
const items = Array.isArray(live.data) ? (live.data as Array<JsonRecord>) : []
return { items, count: items.length }
}
/**
* Delete rows from a PostgREST table. Requires `confirm: true`, or use `dryRun: true`.
* @example
* import deleteRows from 'kody:@kody/supabase/delete-rows'
* const preview = await deleteRows({ projectRef: 'abcdefghijklmnop', table: 'items', filters: { id: 'eq.1' }, dryRun: true })
*/
export default async function deleteRowsEntrypoint(
params: Partial<SupabaseAuthInput> & Record<string, unknown> = {},
) {
return await deleteRows({
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),
filters: readFilters(params.filters),
allowUnfiltered: optionalBoolean(params.allowUnfiltered, 'allowUnfiltered'),
dryRun: optionalBoolean(params.dryRun, 'dryRun'),
confirm: optionalBoolean(params.confirm, 'confirm'),
})
}