Skip to content
← Public packages

@kody/salesforce

Salesforce REST helpers for identity, SOQL, multi-org routing, and error investigation.

src/delete-record.ts

98 lines · 2.7 KB · TypeScript
import { request, salesforceRequestWithResponse } from './request.ts'
import type { JsonRecord } from './types.ts'
import {
	optionalBoolean,
	optionalString,
	requireRecord,
	requireSalesforceId,
	requireSObjectName,
} from './types.ts'

export type DeleteRecordInput = {
	sobject: string
	id: string
	instanceUrl?: string
	apiVersion?: string
	/** Saved OAuth integration name. Defaults to `salesforce`. */
	integrationName?: string
	confirm?: boolean
	dryRun?: boolean
}

/**
 * Delete a Salesforce record. Requires `confirm: true`, or use `dryRun: true`.
 * @param input.sobject - Salesforce sObject API name.
 * @param input.id - Record id to delete.
 * @param input.confirm - Required true to mutate; use dryRun to preview.
 * @returns Delete result or dry-run preview.
 * @example
 * import deleteRecord from 'kody:@kody/salesforce/delete-record'
 * const preview = await deleteRecord({
 *   sobject: 'Lead',
 *   id: '00QXXXXXXXXXXXXXXX',
 *   dryRun: true,
 * })
 */
export async function deleteRecord(
	input: DeleteRecordInput,
): Promise<JsonRecord> {
	const sobject = requireSObjectName(input.sobject)
	const id = requireSalesforceId(input.id)

	if (input.dryRun) {
		return request({
			path: `sobjects/${sobject}/${id}`,
			method: 'DELETE',
			instanceUrl: optionalString(input.instanceUrl, 'instanceUrl'),
			apiVersion: optionalString(input.apiVersion, 'apiVersion'),
			integrationName: optionalString(input.integrationName, 'integrationName'),
			dryRun: true,
		})
	}

	if (input.confirm !== true) {
		throw new Error(
			'Deleting a Salesforce record requires confirm: true after explicit user approval, or dryRun: true.',
		)
	}

	const result = await salesforceRequestWithResponse({
		path: `sobjects/${sobject}/${id}`,
		method: 'DELETE',
		instanceUrl: optionalString(input.instanceUrl, 'instanceUrl'),
		apiVersion: optionalString(input.apiVersion, 'apiVersion'),
		integrationName: optionalString(input.integrationName, 'integrationName'),
		confirm: true,
	})

	return {
		ok: true,
		status: result.status,
		sobject,
		id,
		deleted: true,
	}
}

/**
 * Delete a Salesforce record. Requires `confirm: true`, or use `dryRun: true`.
 * @example
 * import deleteRecord from 'kody:@kody/salesforce/delete-record'
 * const preview = await deleteRecord({
 *   sobject: 'Lead',
 *   id: '00QXXXXXXXXXXXXXXX',
 *   dryRun: true,
 * })
 */
export default async function deleteRecordEntrypoint(
	params: Partial<DeleteRecordInput> & Record<string, unknown> = {},
) {
	const input = requireRecord(params, 'delete-record')
	requireSObjectName(input.sobject)
	requireSalesforceId(input.id)
	return deleteRecord({
		...(input as DeleteRecordInput),
		confirm: optionalBoolean(input.confirm, 'confirm'),
		dryRun: optionalBoolean(input.dryRun, 'dryRun'),
	})
}