Skip to content

Built for people who want to own their automations. Join the waitlist for an invite.

Package listing

@kody/airtable

src/delete-record.ts

95 lines · 2.8 KB · TypeScript
import { pickAuthInput } from './auth.ts'
import { airtableRequest } from './client.ts'
import { recordsPath } from './setup.ts'
import type { AirtableAuthInput, DryRunResult, JsonRecord } from './types.ts'
import { optionalBoolean, requireConfirmOrDryRun, requireRecord, requireString } from './types.ts'

export type DeleteRecordInput = AirtableAuthInput & {
	baseId: string
	tableIdOrName: string
	recordId: string
	confirm?: boolean
	dryRun?: boolean
}

export type DeleteRecordResult = {
	id: string
	deleted: boolean
}

function deleteCall(input: DeleteRecordInput): {
	path: string
	query: JsonRecord
} {
	return {
		path: recordsPath(
			requireString(input.baseId, 'baseId'),
			requireString(input.tableIdOrName, 'tableIdOrName'),
		),
		query: { 'records[]': requireString(input.recordId, 'recordId') },
	}
}

/**
 * Delete an Airtable record. Requires `confirm: true`, or use `dryRun: true`.
 * Needs `data.records:write`.
 * @example
 * import deleteRecord from 'kody:@kody/airtable/delete-record'
 * const preview = await deleteRecord({
 *   baseId: 'appXXXXXXXXXXXXXX',
 *   tableIdOrName: 'tblXXXXXXXXXXXXXX',
 *   recordId: 'recXXXXXXXXXXXXXX',
 *   dryRun: true,
 * })
 */
export async function deleteRecord(
	input: DeleteRecordInput,
): Promise<
	DeleteRecordResult | DryRunResult<{ method: string; path: string; query: JsonRecord }>
> {
	const payload = deleteCall(input)
	if (requireConfirmOrDryRun(input, 'Deleting an Airtable record') === 'dryRun') {
		return { dryRun: true, wouldCall: { method: 'DELETE', ...payload } }
	}

	const result = await airtableRequest<{ records?: Array<{ id?: string; deleted?: boolean }> }>(
		{
			...input,
			operation: 'records.write',
			method: 'DELETE',
			path: payload.path,
			query: payload.query,
		},
	)
	const body = result.data && typeof result.data === 'object' ? result.data : {}
	const deleted = Array.isArray(body.records) ? body.records[0] : null
	return {
		id: deleted?.id || requireString(input.recordId, 'recordId'),
		deleted: deleted?.deleted === true,
	}
}

/**
 * Delete an Airtable record. Requires `confirm: true`, or use `dryRun: true`.
 * @example
 * import deleteRecord from 'kody:@kody/airtable/delete-record'
 * const preview = await deleteRecord({
 *   baseId: 'appXXXXXXXXXXXXXX',
 *   tableIdOrName: 'Tasks',
 *   recordId: 'recXXXXXXXXXXXXXX',
 *   dryRun: true,
 * })
 */
export default async function deleteRecordEntrypoint(
	params: Partial<DeleteRecordInput> & Record<string, unknown> = {},
) {
	const input = requireRecord(params, 'delete-record')
	return deleteRecord({
		baseId: requireString(input.baseId, 'baseId'),
		tableIdOrName: requireString(input.tableIdOrName, 'tableIdOrName'),
		recordId: requireString(input.recordId, 'recordId'),
		...pickAuthInput(input),
		confirm: optionalBoolean(input.confirm, 'confirm'),
		dryRun: optionalBoolean(input.dryRun, 'dryRun'),
	})
}