import { EndAction, OntimeEvent, TimerType, isKeyOfType, isOntimeEvent } from 'ontime-types'; import { MILLIS_PER_SECOND, maxDuration } from 'ontime-utils'; import { editEvent } from '../services/rundown-service/RundownService.js'; import { getEntryWithId } from '../services/rundown-service/rundownUtils.js'; import { coerceBoolean, coerceColour, coerceEnum, coerceNumber, coerceString } from '../utils/coerceType.js'; import { getDataProvider } from '../classes/data-provider/DataProvider.js'; /** * * @param {number} value time amount in seconds * @returns {number} time in milliseconds clamped to 0 and max duration */ function clampDuration(value: number): number { const valueInMillis = value * MILLIS_PER_SECOND; if (valueInMillis > maxDuration || valueInMillis < 0) { throw new Error('Times should be from 0 to 23:59:59'); } return valueInMillis; } const propertyConversion = { title: coerceString, note: coerceString, cue: coerceString, isPublic: coerceBoolean, skip: coerceBoolean, colour: coerceColour, custom: coerceString, timeWarning: (value: unknown) => clampDuration(coerceNumber(value)), timeDanger: (value: unknown) => clampDuration(coerceNumber(value)), endAction: (value: unknown) => coerceEnum(value, EndAction), timerType: (value: unknown) => coerceEnum(value, TimerType), duration: (value: unknown) => clampDuration(coerceNumber(value)), timeStart: (value: unknown) => clampDuration(coerceNumber(value)), timeEnd: (value: unknown) => clampDuration(coerceNumber(value)), }; export function parseProperty(property: string, value: unknown) { if (property.startsWith('custom:')) { const customKey = property.split(':')[1].toLocaleLowerCase(); // all custom fields keys are lowercase const customFields = getDataProvider().getCustomFields(); if (!(customKey in customFields)) { throw new Error(`Custom field ${customKey} not found`); } const parserFn = propertyConversion.custom; return { custom: { [customKey]: parserFn(value) } }; } if (!isKeyOfType(property, propertyConversion)) { throw new Error(`Property ${property} not permitted`); } const parserFn = propertyConversion[property]; return { [property]: parserFn(value) }; } /** * Updates a property of the event with the given id * @param {Partial} patchEvent */ export function updateEvent(patchEvent: Partial & { id: string }) { const event = getEntryWithId(patchEvent?.id ?? ''); if (!event) { throw new Error(`Event with ID ${patchEvent?.id} not found`); } if (!isOntimeEvent(event)) { throw new Error('Can only update events'); } editEvent(patchEvent); }