/**
* Scaffolded by Kody from an OpenAPI spec.
* Spec: https://cal.com/docs/api-reference/v2/openapi.json (Cal.com API v2)
* Slugs: mecontroller_getme, bookingscontroller_2026_05_01_getbookings,
* bookingscontroller_2026_02_25_getbooking|createbooking|cancelbooking|reschedulebooking,
* eventtypescontroller_2024_06_14_geteventtypes|geteventtypebyid,
* slotscontroller_2024_09_04_getavailableslots,
* webhookscontroller_getwebhooks|createwebhook
* Auth: API key secret calComApiKey, or OAuth integration cal-com
*
* Host approval is enforced by Kody's fetch gateway and never widened by this spec.
*/
import { createAuthenticatedFetch } from 'kody:runtime'
import {
API_BASE_URL,
API_KEY_SECRET,
assertNoRetiredAlias,
authSetupMessage,
} from './setup.js'
export function buildUrl(pathTemplate, params = {}) {
return API_BASE_URL + pathTemplate.replace(/\{([^}]+)\}/g, (_match, name) => {
const value = params[name]
if (value === undefined || value === null) {
throw new Error(`Missing required path parameter: ${name}`)
}
return encodeURIComponent(String(value))
})
}
export function appendQuery(url, query = {}) {
const search = new URLSearchParams()
for (const [key, value] of Object.entries(query)) {
if (value === undefined || value === null || value === '') continue
if (Array.isArray(value)) {
for (const item of value) {
if (item === undefined || item === null || item === '') continue
search.append(key, String(item))
}
continue
}
search.append(key, String(value))
}
const qs = search.toString()
return qs ? `${url}?${qs}` : url
}
function mergeHeaders(userHeaders, authHeaders) {
const merged = { ...(userHeaders ?? {}) }
for (const [key, value] of Object.entries(authHeaders)) {
const lower = key.toLowerCase()
for (const existing of Object.keys(merged)) {
if (existing.toLowerCase() === lower) delete merged[existing]
}
merged[key] = value
}
return merged
}
function hasHeader(headers, name) {
const lower = name.toLowerCase()
return Object.keys(headers).some((key) => key.toLowerCase() === lower)
}
function assertSecretName(name) {
if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(name)) {
throw new Error('Cal.com secretName must be a safe secret identifier (letters, numbers, dot, underscore, hyphen).')
}
return name
}
function resolveSecretName(input = {}) {
assertNoRetiredAlias(input.secretName, 'secretName')
assertNoRetiredAlias(input.account, 'account')
if (typeof input.secretName === 'string' && input.secretName.trim()) {
return assertSecretName(input.secretName.trim())
}
if (typeof input.account === 'string' && input.account.trim()) {
return assertSecretName(`${API_KEY_SECRET}-${input.account.trim()}`)
}
return API_KEY_SECRET
}
async function resolveTransport(input = {}) {
assertNoRetiredAlias(input.integrationName, 'integrationName')
if (typeof input.integrationName === 'string' && input.integrationName.trim()) {
try {
return {
fetchImpl: await createAuthenticatedFetch(input.integrationName.trim()),
authHeaders: {},
}
} catch (error) {
const message = error instanceof Error ? error.message : String(error)
throw new Error(authSetupMessage(`Cal.com OAuth integration "${input.integrationName}" is not connected. ${message}`))
}
}
return {
fetchImpl: fetch,
authHeaders: { Authorization: `Bearer {{secret:${resolveSecretName(input)}}}` },
}
}
async function call(method, pathTemplate, input = {}, requiredParams = []) {
const params = input.params ?? {}
for (const name of requiredParams) {
if (params[name] === undefined || params[name] === null) {
throw new Error(`Missing required path parameter: ${name}`)
}
}
const url = appendQuery(buildUrl(pathTemplate, params), input.query)
const { fetchImpl, authHeaders } = await resolveTransport(input)
const headers = mergeHeaders(input.headers, authHeaders)
let body
if (input.body !== undefined) {
body = JSON.stringify(input.body)
if (!hasHeader(headers, 'content-type')) headers['content-type'] = 'application/json'
}
return fetchImpl(url, { method, headers, body })
}
/** GET /v2/me — Get my profile */
export async function mecontroller_getme(input = {}) {
return call('GET', '/v2/me', input)
}
/** GET /v2/bookings — Get all bookings */
export async function bookingscontroller_2026_05_01_getbookings(input = {}) {
return call('GET', '/v2/bookings', input)
}
/** GET /v2/bookings/{bookingUid} — Get a booking */
export async function bookingscontroller_2026_02_25_getbooking(input = {}) {
return call('GET', '/v2/bookings/{bookingUid}', input, ['bookingUid'])
}
/** POST /v2/bookings — Create a booking */
export async function bookingscontroller_2026_02_25_createbooking(input = {}) {
return call('POST', '/v2/bookings', input)
}
/** POST /v2/bookings/{bookingUid}/cancel — Cancel a booking */
export async function bookingscontroller_2026_02_25_cancelbooking(input = {}) {
return call('POST', '/v2/bookings/{bookingUid}/cancel', input, ['bookingUid'])
}
/** POST /v2/bookings/{bookingUid}/reschedule — Reschedule a booking */
export async function bookingscontroller_2026_02_25_reschedulebooking(input = {}) {
return call('POST', '/v2/bookings/{bookingUid}/reschedule', input, ['bookingUid'])
}
/** GET /v2/event-types — Get all event types */
export async function eventtypescontroller_2024_06_14_geteventtypes(input = {}) {
return call('GET', '/v2/event-types', input)
}
/** GET /v2/event-types/{eventTypeId} — Get an event type */
export async function eventtypescontroller_2024_06_14_geteventtypebyid(input = {}) {
return call('GET', '/v2/event-types/{eventTypeId}', input, ['eventTypeId'])
}
/** GET /v2/slots — Get available time slots for an event type */
export async function slotscontroller_2024_09_04_getavailableslots(input = {}) {
return call('GET', '/v2/slots', input)
}
/** GET /v2/webhooks — Get all webhooks */
export async function webhookscontroller_getwebhooks(input = {}) {
return call('GET', '/v2/webhooks', input)
}
/** POST /v2/webhooks — Create a webhook */
export async function webhookscontroller_createwebhook(input = {}) {
return call('POST', '/v2/webhooks', input)
}
/**
* Escape-hatch fetch for Cal.com API v2 paths not covered by the scaffold.
* `path` is relative to https://api.cal.com (include `/v2/...`).
*/
export async function rawCalRequest(path, options = {}) {
if (typeof path !== 'string' || path.trim() === '') {
throw new Error('Cal.com request requires a non-empty path string.')
}
if (/^https?:\/\//i.test(path)) {
throw new Error('Cal.com request path must be relative, for example /v2/me.')
}
const normalized = path.startsWith('/') ? path : `/${path}`
const url = appendQuery(`${API_BASE_URL}${normalized}`, options.query)
const { fetchImpl, authHeaders } = await resolveTransport(options)
const headers = mergeHeaders(
{
Accept: 'application/json',
...(options.headers ?? {}),
},
authHeaders,
)
let body = options.body
if (body !== undefined && typeof body !== 'string') {
body = JSON.stringify(body)
if (!hasHeader(headers, 'content-type')) headers['content-type'] = 'application/json'
}
return fetchImpl(url, { method: options.method ?? (body === undefined ? 'GET' : 'POST'), headers, body })
}