import { pickAuthInput } from './auth.ts' import { airtableRequest, airtableUrl, inferOperationFromPath, isMutatingMethod } from './client.ts' import { AIRTABLE_API_BASE_URL } from './setup.ts' import type { AirtableAuthInput, JsonRecord } from './types.ts' import { optionalBoolean, optionalString, requireRecord, requireString } from './types.ts' export type AirtableRawRequestInput = AirtableAuthInput & { path: string method?: string query?: JsonRecord body?: JsonRecord confirm?: boolean dryRun?: boolean } /** * Call the Airtable REST API with a saved OAuth integration or personal access * token. Unknown and mutating operations require `confirm: true`; use * `dryRun: true` to preview. * @example * import request from 'kody:@kody/airtable/request' * const result = await request({ path: '/meta/bases' }) */ export async function request(input: AirtableRawRequestInput) { const path = requireString(input.path, 'path') const method = (input.method ?? 'GET').toUpperCase() const operation = inferOperationFromPath(method, path) const integrationName = optionalString(input.integrationName, 'integrationName') ?? optionalString(input.integration, 'integration') const secretName = optionalString(input.secretName, 'secretName') const account = optionalString(input.account, 'account') const mutating = isMutatingMethod(method) if (input.dryRun) { return { dryRun: true, url: airtableUrl(path, input.query), apiBaseUrl: AIRTABLE_API_BASE_URL, method, operation, path, query: input.query ?? {}, body: input.body ?? null, integrationName: integrationName ?? null, secretName: secretName ?? null, account: account ?? null, readOnly: !mutating, } } if (mutating && input.confirm !== true) { throw new Error( 'This Airtable request may mutate data. Pass confirm: true only after explicit user approval, or use dryRun: true.', ) } return airtableRequest({ path, method, query: input.query, body: input.body, operation, ...pickAuthInput(input), }) } /** * Call the Airtable REST API with a saved OAuth integration or personal access * token. Mutating methods require `confirm: true`; use `dryRun: true` to preview. * @example * import request from 'kody:@kody/airtable/request' * const result = await request({ path: '/meta/whoami' }) */ export default async function requestEntrypoint( params: Partial & Record = {}, ) { const input = requireRecord(params, 'request') return request({ path: requireString(input.path, 'path'), method: optionalString(input.method, 'method'), query: input.query as JsonRecord | undefined, body: input.body as JsonRecord | undefined, ...pickAuthInput(input), confirm: optionalBoolean(input.confirm, 'confirm'), dryRun: optionalBoolean(input.dryRun, 'dryRun'), }) }