import type { ZoomQuery } from './types.ts' export function asRecord(value: unknown): Record { return value && typeof value === 'object' ? (value as Record) : {} } export function asString(value: unknown): string | null { return typeof value === 'string' ? value : null } export function asNumber(value: unknown): number | null { return typeof value === 'number' && Number.isFinite(value) ? value : null } export function asBoolean(value: unknown): boolean | null { return typeof value === 'boolean' ? value : null } export function pickQuery( params: Record, keys: readonly string[], ): ZoomQuery { const query: ZoomQuery = {} for (const key of keys) { const value = params[key] if (value === undefined || value === null) continue if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') { query[key] = value } } return query } export function readOptionalBoolean(value: unknown): boolean | undefined { return typeof value === 'boolean' ? value : undefined } export function readOptionalNumber(value: unknown): number | undefined { if (typeof value === 'number' && Number.isFinite(value)) return value if (typeof value === 'string' && value.trim() && Number.isFinite(Number(value))) { return Number(value) } return undefined } export function readOptionalString(value: unknown): string | undefined { return typeof value === 'string' && value.trim() ? value.trim() : undefined } export function slimUser(data: Record) { return { id: asString(data.id), email: asString(data.email), displayName: asString(data.display_name), firstName: asString(data.first_name), lastName: asString(data.last_name), type: asNumber(data.type), status: asString(data.status), timezone: asString(data.timezone), dept: asString(data.dept), } } export function slimMeeting(data: Record) { return { id: asNumber(data.id) ?? asString(data.id), uuid: asString(data.uuid), topic: asString(data.topic), type: asNumber(data.type), status: asString(data.status), startTime: asString(data.start_time), duration: asNumber(data.duration), timezone: asString(data.timezone), joinUrl: asString(data.join_url), hostId: asString(data.host_id), hostEmail: asString(data.host_email), agenda: asString(data.agenda), createdAt: asString(data.created_at), } } export function slimRecordingMeeting(data: Record) { const files = Array.isArray(data.recording_files) ? data.recording_files.map((file) => slimRecordingFile(asRecord(file))) : [] return { id: asNumber(data.id) ?? asString(data.id), uuid: asString(data.uuid), topic: asString(data.topic), startTime: asString(data.start_time), duration: asNumber(data.duration), shareUrl: asString(data.share_url), totalSize: asNumber(data.total_size), recordingCount: asNumber(data.recording_count), files, } } export function slimRecordingFile(data: Record) { return { id: asString(data.id), meetingId: asString(data.meeting_id), recordingStart: asString(data.recording_start), recordingEnd: asString(data.recording_end), fileType: asString(data.file_type), fileSize: asNumber(data.file_size), playUrl: asString(data.play_url), downloadUrl: asString(data.download_url), status: asString(data.status), recordingType: asString(data.recording_type), } } export function slimWebinar(data: Record) { return { id: asNumber(data.id) ?? asString(data.id), uuid: asString(data.uuid), topic: asString(data.topic), type: asNumber(data.type), status: asString(data.status), startTime: asString(data.start_time), duration: asNumber(data.duration), timezone: asString(data.timezone), joinUrl: asString(data.join_url), hostId: asString(data.host_id), agenda: asString(data.agenda), } } export function pageMeta(data: Record) { return { pageCount: asNumber(data.page_count), pageNumber: asNumber(data.page_number), pageSize: asNumber(data.page_size), totalRecords: asNumber(data.total_records), nextPageToken: asString(data.next_page_token), } } const MEETING_BODY_KEYS = [ 'topic', 'type', 'start_time', 'duration', 'timezone', 'password', 'agenda', 'schedule_for', 'recurrence', 'settings', 'tracking_fields', 'template_id', ] as const const WEBINAR_BODY_KEYS = [ 'topic', 'type', 'start_time', 'duration', 'timezone', 'password', 'agenda', 'schedule_for', 'recurrence', 'settings', 'tracking_fields', ] as const export function buildMeetingBody(params: Record): Record { return pickBody(params, MEETING_BODY_KEYS, { start_time: ['start_time', 'startTime'], schedule_for: ['schedule_for', 'scheduleFor'], template_id: ['template_id', 'templateId'], tracking_fields: ['tracking_fields', 'trackingFields'], }) } export function buildWebinarBody(params: Record): Record { return pickBody(params, WEBINAR_BODY_KEYS, { start_time: ['start_time', 'startTime'], schedule_for: ['schedule_for', 'scheduleFor'], tracking_fields: ['tracking_fields', 'trackingFields'], }) } function pickBody( params: Record, keys: readonly string[], aliases: Record = {}, ): Record { const body: Record = {} for (const key of keys) { const names = aliases[key] ?? [key] for (const name of names) { if (params[name] !== undefined) { body[key] = params[name] break } } } return body }