import { twilioRequest } from './client.ts'
import { mutationPreview } from './helpers.ts'
import {
inputRecord,
optionalString,
requiredString,
type TwilioAuthOptions,
} from './validation.ts'
function normalizeResource(value: string): string {
const trimmed = value.trim()
if (trimmed.startsWith('http://') || trimmed.startsWith('https://')) {
throw new Error(
'Pass pageUri for pagination, or a resource path such as /Messages.json. Do not pass arbitrary https URLs.',
)
}
if (trimmed.startsWith('.') || trimmed.startsWith('/')) return trimmed
return '/' + trimmed
}
/**
* Escape hatch for unwrapped 2010-04-01 Account resources.
* POST (and any write) defaults to dry-run and requires confirm: true to execute.
*/
export default async function request(
params: TwilioAuthOptions & {
resource?: string
pageUri?: string
method?: 'GET' | 'POST'
query?: Record<string, unknown>
body?: Record<string, unknown>
dryRun?: boolean
confirm?: boolean
} = {},
) {
const input = inputRecord(params)
const method =
input.method === 'POST' || input.method === 'GET'
? input.method
: 'GET'
const resource = normalizeResource(
optionalString(input, 'resource') ??
(method === 'GET' ? '.json' : requiredString(input, 'resource')),
)
const pageUri = optionalString(input, 'pageUri')
const mutating = method === 'POST'
if (mutating) {
const preview = mutationPreview(
input,
resource,
(input.body as Record<string, unknown> | undefined) ?? {},
)
if (preview) return preview
}
const result = await twilioRequest({
...input,
resource,
href: pageUri,
method,
query: (input.query as Record<string, unknown> | undefined) ?? {},
body: (input.body as Record<string, unknown> | undefined) ?? {},
})
return { ok: true, method, resource, result }
}