Skip to content
← Public packages

@kody/salesforce

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

src/create-record.ts

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

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

export type CreateRecordResult = {
	id: string
	success: boolean
	errors: unknown[]
	[key: string]: unknown
}

/**
 * Create a Salesforce record. Requires `confirm: true`, or use `dryRun: true`.
 * @param input.sobject - Salesforce sObject API name.
 * @param input.fields - Field map to write.
 * @param input.confirm - Required true to mutate; use dryRun to preview.
 * @returns Created record result or dry-run preview.
 * @example
 * import createRecord from 'kody:@kody/salesforce/create-record'
 * const preview = await createRecord({
 *   sobject: 'Lead',
 *   fields: { LastName: 'Lovelace', Company: 'Analytical Engines' },
 *   dryRun: true,
 * })
 */
export async function createRecord(
	input: CreateRecordInput,
): Promise<CreateRecordResult | JsonRecord> {
	const sobject = requireSObjectName(input.sobject)
	const fields = requireRecord(input.fields, 'fields')

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

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

	return salesforceJson<CreateRecordResult>({
		path: `sobjects/${sobject}`,
		method: 'POST',
		body: fields,
		instanceUrl: optionalString(input.instanceUrl, 'instanceUrl'),
		apiVersion: optionalString(input.apiVersion, 'apiVersion'),
		integrationName: optionalString(input.integrationName, 'integrationName'),
		confirm: true,
	})
}

/**
 * Create a Salesforce record. Requires `confirm: true`, or use `dryRun: true`.
 * @example
 * import createRecord from 'kody:@kody/salesforce/create-record'
 * const preview = await createRecord({
 *   sobject: 'Lead',
 *   fields: { LastName: 'Lovelace', Company: 'Analytical Engines' },
 *   dryRun: true,
 * })
 */
export default async function createRecordEntrypoint(
	params: Partial<CreateRecordInput> & Record<string, unknown> = {},
) {
	const input = requireRecord(params, 'create-record')
	requireSObjectName(input.sobject)
	requireRecord(input.fields, 'fields')
	return createRecord({
		...(input as CreateRecordInput),
		confirm: optionalBoolean(input.confirm, 'confirm'),
		dryRun: optionalBoolean(input.dryRun, 'dryRun'),
	})
}