diff --git a/apps/client/src/features/app-settings/panel/sources-panel/GSheetSetup.tsx b/apps/client/src/features/app-settings/panel/sources-panel/GSheetSetup.tsx index 5fcf863c9..489b10723 100644 --- a/apps/client/src/features/app-settings/panel/sources-panel/GSheetSetup.tsx +++ b/apps/client/src/features/app-settings/panel/sources-panel/GSheetSetup.tsx @@ -55,15 +55,14 @@ export default function GSheetSetup(props: GSheetSetupProps) { setLoading(''); }; - const handleCancelFlow = async () => { + const handleCancelFlow = () => { onCancel(); }; /** * Gets file from input - * @param event */ - const handleClientSecret = async (event: ChangeEvent) => { + const handleClientSecret = (event: ChangeEvent) => { if (!event.target.files?.length) { return; } diff --git a/apps/server/src/api-data/automation/__tests__/automation.dao.test.ts b/apps/server/src/api-data/automation/__tests__/automation.dao.test.ts index 0c12f20ad..20d869444 100644 --- a/apps/server/src/api-data/automation/__tests__/automation.dao.test.ts +++ b/apps/server/src/api-data/automation/__tests__/automation.dao.test.ts @@ -40,43 +40,43 @@ afterAll(() => { }); describe('addTrigger()', () => { - beforeEach(() => { - deleteAllTriggers(); + beforeEach(async () => { + await deleteAllTriggers(); }); - it('should accept a valid automation', () => { + it('should accept a valid trigger', async () => { const testData: TriggerDTO = { title: 'test', trigger: TimerLifeCycle.onLoad, automationId: 'test-automation-id', }; - const trigger = addTrigger(testData); + const trigger = await addTrigger(testData); expect(trigger).toMatchObject(testData); }); }); describe('editTrigger()', () => { - beforeEach(() => { - deleteAllTriggers(); - addTrigger({ + beforeEach(async () => { + await deleteAllTriggers(); + await addTrigger({ title: 'test-osc', trigger: TimerLifeCycle.onLoad, automationId: 'test-osc-automation', }); - addTrigger({ + await addTrigger({ title: 'test-http', trigger: TimerLifeCycle.onFinish, automationId: 'test-http-automation', }); }); - it('should edit the contents of an automation', () => { + it('should edit the contents of a trigger', async () => { const triggers = getAutomationTriggers(); const fistTrigger = triggers[0]; expect(fistTrigger).toMatchObject({ id: expect.any(String), title: 'test-osc' }); - const editedOSC = editTrigger(fistTrigger.id, { + const editedOSC = await editTrigger(fistTrigger.id, { title: 'edited-title', trigger: TimerLifeCycle.onDanger, automationId: 'test-osc-automation', @@ -92,9 +92,9 @@ describe('editTrigger()', () => { }); describe('deleteTrigger()', () => { - beforeEach(() => { - deleteAllTriggers(); - addTrigger({ + beforeEach(async () => { + await deleteAllTriggers(); + await addTrigger({ title: 'test-osc', trigger: TimerLifeCycle.onLoad, automationId: 'test-osc-automation', @@ -106,13 +106,13 @@ describe('deleteTrigger()', () => { }); }); - it('should remove an automation from the list', () => { + it('should remove an automation from the list', async () => { const triggers = getAutomationTriggers(); expect(triggers.length).toEqual(2); const fistTrigger = triggers[0]; expect(fistTrigger).toMatchObject({ id: expect.any(String), title: 'test-osc' }); - deleteTrigger(fistTrigger.id); + await deleteTrigger(fistTrigger.id); const removed = getAutomationTriggers(); expect(removed.length).toEqual(1); expect(removed[0].title).not.toEqual('test-osc'); @@ -120,11 +120,11 @@ describe('deleteTrigger()', () => { }); describe('addAutomation()', () => { - beforeEach(() => { - deleteAll(); + beforeEach(async () => { + await deleteAll(); }); - it('should accept a valid automation', () => { + it('should accept a valid automation', async () => { const testData: AutomationDTO = { title: 'test', filterRule: 'all', @@ -132,24 +132,24 @@ describe('addAutomation()', () => { outputs: [makeOSCAction(), makeHTTPAction()], }; - const automation = addAutomation(testData); + const automation = await addAutomation(testData); const automations = getAutomations(); expect(automations[automation.id]).toMatchObject(testData); }); }); -describe('editAutomation()', () => { +describe('editAutomation()', async () => { // saving the ID of the added automation let firstAutomation: Automation; - beforeEach(() => { - deleteAll(); - firstAutomation = addAutomation({ + beforeEach(async () => { + await deleteAll(); + firstAutomation = await addAutomation({ title: 'test-osc', filterRule: 'all', filters: [], outputs: [], }); - addAutomation({ + await addAutomation({ title: 'test-http', filterRule: 'all', filters: [], @@ -157,7 +157,7 @@ describe('editAutomation()', () => { }); }); - it('should edit the contents of an automation', () => { + it('should edit the contents of an automation', async () => { const automations = getAutomations(); expect(Object.keys(automations).length).toEqual(2); expect(automations[firstAutomation.id]).toMatchObject({ @@ -168,7 +168,7 @@ describe('editAutomation()', () => { outputs: expect.any(Array), }); - const editedOSC = editAutomation(firstAutomation.id, { + const editedOSC = await editAutomation(firstAutomation.id, { title: 'edited-title', filterRule: 'any', filters: [], @@ -188,9 +188,9 @@ describe('editAutomation()', () => { describe('deleteAutomation()', () => { // saving the ID of the added automation let firstAutomation: Automation; - beforeEach(() => { - deleteAll(); - firstAutomation = addAutomation({ + beforeEach(async () => { + await deleteAll(); + firstAutomation = await addAutomation({ title: 'test-osc', filterRule: 'all', filters: [], @@ -198,18 +198,18 @@ describe('deleteAutomation()', () => { }); }); - it('should remove m automation from the list', () => { + it('should remove m automation from the list', async () => { const automations = getAutomations(); expect(Object.keys(automations).length).toEqual(1); - deleteAutomation(Object.keys(automations)[0]); + await deleteAutomation(Object.keys(automations)[0]); const removed = getAutomations(); expect(Object.keys(removed).length).toEqual(0); }); - it('should not remove an automation which is in use', () => { + it('should not remove an automation which is in use', async () => { const automations = getAutomations(); - addTrigger({ + await addTrigger({ title: 'test-automation', trigger: TimerLifeCycle.onLoad, automationId: firstAutomation.id, @@ -227,6 +227,6 @@ describe('deleteAutomation()', () => { outputs: expect.any(Array), }); - expect(() => deleteAutomation(automationId)).toThrowError(); + await expect(deleteAutomation(automationId)).rejects.toThrowError(); }); }); diff --git a/apps/server/src/api-data/automation/__tests__/automation.service.test.ts b/apps/server/src/api-data/automation/__tests__/automation.service.test.ts index d00661f70..d8e300006 100644 --- a/apps/server/src/api-data/automation/__tests__/automation.service.test.ts +++ b/apps/server/src/api-data/automation/__tests__/automation.service.test.ts @@ -39,29 +39,29 @@ describe('triggerAction()', () => { let oscSpy = vi.spyOn(oscClient, 'emitOSC'); let httpSpy = vi.spyOn(httpClient, 'emitHTTP'); - beforeEach(() => { + beforeEach(async () => { oscSpy = vi.spyOn(oscClient, 'emitOSC').mockImplementation(() => {}); httpSpy = vi.spyOn(httpClient, 'emitHTTP').mockImplementation(() => {}); - deleteAllTriggers(); - const oscAutomation = addAutomation({ + await deleteAllTriggers(); + const oscAutomation = await addAutomation({ title: 'test-osc', filterRule: 'all', filters: [], outputs: [makeOSCAction()], }); - const httpAutomation = addAutomation({ + const httpAutomation = await addAutomation({ title: 'test-http', filterRule: 'any', filters: [], outputs: [makeHTTPAction()], }); - addTrigger({ + await addTrigger({ title: 'test-osc', trigger: TimerLifeCycle.onLoad, automationId: oscAutomation.id, }); - addTrigger({ + await addTrigger({ title: 'test-http', trigger: TimerLifeCycle.onFinish, automationId: httpAutomation.id, diff --git a/apps/server/src/api-data/automation/automation.controller.ts b/apps/server/src/api-data/automation/automation.controller.ts index fe1c9f367..9b177c956 100644 --- a/apps/server/src/api-data/automation/automation.controller.ts +++ b/apps/server/src/api-data/automation/automation.controller.ts @@ -11,10 +11,10 @@ export function getAutomationSettings(_req: Request, res: Response) { +export async function postAutomationSettings(req: Request, res: Response) { try { // body payload is a patch object that must contain root properties - const automationSettings = automationDao.editAutomationSettings({ + const automationSettings = await automationDao.editAutomationSettings({ enabledAutomations: req.body.enabledAutomations, enabledOscIn: req.body.enabledOscIn, oscPortIn: req.body.oscPortIn, @@ -33,9 +33,9 @@ export function postAutomationSettings(req: Request, res: Response) { +export async function postTrigger(req: Request, res: Response) { try { - const automation = automationDao.addTrigger({ + const automation = await automationDao.addTrigger({ title: req.body.title, trigger: req.body.trigger, automationId: req.body.automationId, @@ -47,10 +47,10 @@ export function postTrigger(req: Request, res: Response } } -export function putTrigger(req: Request, res: Response) { +export async function putTrigger(req: Request, res: Response) { try { // body payload is a patch object - const automation = automationDao.editTrigger(req.params.id, { + const automation = await automationDao.editTrigger(req.params.id, { title: req.body.title ?? undefined, trigger: req.body.trigger ?? undefined, automationId: req.body.automationId ?? undefined, @@ -62,9 +62,9 @@ export function putTrigger(req: Request, res: Response) } } -export function deleteTrigger(req: Request, res: Response) { +export async function deleteTrigger(req: Request, res: Response) { try { - automationDao.deleteTrigger(req.params.id); + await automationDao.deleteTrigger(req.params.id); res.status(204).send(); } catch (error) { const message = getErrorMessage(error); @@ -72,9 +72,9 @@ export function deleteTrigger(req: Request, res: Response) } } -export function postAutomation(req: Request, res: Response) { +export async function postAutomation(req: Request, res: Response) { try { - const newAutomation = automationDao.addAutomation({ + const newAutomation = await automationDao.addAutomation({ title: req.body.title, filterRule: req.body.filterRule, filters: req.body.filters, @@ -87,9 +87,9 @@ export function postAutomation(req: Request, res: Response) { +export async function editAutomation(req: Request, res: Response) { try { - const newAutomation = automationDao.editAutomation(req.params.id, { + const newAutomation = await automationDao.editAutomation(req.params.id, { title: req.body.title, filterRule: req.body.filterRule, filters: req.body.filters, @@ -102,9 +102,9 @@ export function editAutomation(req: Request, res: Response) { +export async function deleteAutomation(req: Request, res: Response) { try { - automationDao.deleteAutomation(req.params.id); + await automationDao.deleteAutomation(req.params.id); res.status(204).send(); } catch (error) { const message = getErrorMessage(error); diff --git a/apps/server/src/api-data/automation/automation.dao.ts b/apps/server/src/api-data/automation/automation.dao.ts index 9a8ba2fb2..66f7244a9 100644 --- a/apps/server/src/api-data/automation/automation.dao.ts +++ b/apps/server/src/api-data/automation/automation.dao.ts @@ -1,4 +1,11 @@ -import type { Automation, AutomationDTO, AutomationSettings, NormalisedAutomation, Trigger, TriggerDTO } from 'ontime-types'; +import type { + Automation, + AutomationDTO, + AutomationSettings, + NormalisedAutomation, + Trigger, + TriggerDTO, +} from 'ontime-types'; import { deleteAtIndex, generateId } from 'ontime-utils'; import { getDataProvider } from '../../classes/data-provider/DataProvider.js'; @@ -34,27 +41,27 @@ export function getAutomations(): NormalisedAutomation { /** * Patches the automation settings object */ -export function editAutomationSettings(settings: Partial): AutomationSettings { - saveChanges(settings); +export async function editAutomationSettings(settings: Partial): Promise { + await saveChanges(settings); return getAutomationSettings(); } /** * Adds a validated automation to the store */ -export function addTrigger(newTrigger: TriggerDTO): Trigger { +export async function addTrigger(newTrigger: TriggerDTO): Promise { const triggers = getAutomationTriggers(); const id = getUniqueTriggerId(triggers); const trigger = { ...newTrigger, id }; triggers.push(trigger); - saveChanges({ triggers }); + await saveChanges({ triggers }); return trigger; } /** * Patches an existing automation trigger */ -export function editTrigger(id: string, newTrigger: TriggerDTO): Trigger { +export async function editTrigger(id: string, newTrigger: TriggerDTO): Promise { const triggers = getAutomationTriggers(); const index = triggers.findIndex((trigger) => trigger.id === id); @@ -63,14 +70,14 @@ export function editTrigger(id: string, newTrigger: TriggerDTO): Trigger { } triggers[index] = { ...triggers[index], ...newTrigger }; - saveChanges({ triggers }); + await saveChanges({ triggers }); return triggers[index]; } /** * Deletes an automation trigger given its ID */ -export function deleteTrigger(id: string): void { +export async function deleteTrigger(id: string): Promise { let triggers = getAutomationTriggers(); const index = triggers.findIndex((trigger) => trigger.id === id); @@ -79,53 +86,53 @@ export function deleteTrigger(id: string): void { } triggers = deleteAtIndex(index, triggers); - saveChanges({ triggers }); + await saveChanges({ triggers }); } /** * Deletes all project automation triggers */ -export function deleteAllTriggers(): void { - saveChanges({ triggers: [] }); +export async function deleteAllTriggers(): Promise { + await saveChanges({ triggers: [] }); } /** * Deletes all project automation triggers and automations * We do this together to avoid issues with missing references */ -export function deleteAll(): void { - saveChanges({ triggers: [], automations: {} }); +export async function deleteAll() { + await saveChanges({ triggers: [], automations: {} }); } /** * Adds a validated automation to the store */ -export function addAutomation(newAutomation: AutomationDTO): Automation { +export async function addAutomation(newAutomation: AutomationDTO): Promise { const automations = getAutomations(); const id = getUniqueAutomationId(automations); automations[id] = { ...newAutomation, id }; - saveChanges({ automations }); + await saveChanges({ automations }); return automations[id]; } /** * Updates an existing automation with a new entry */ -export function editAutomation(id: string, newAutomation: AutomationDTO): Automation { +export async function editAutomation(id: string, newAutomation: AutomationDTO): Promise { const automations = getAutomations(); if (!Object.hasOwn(automations, id)) { throw new Error(`Automation with id ${id} not found`); } automations[id] = { ...newAutomation, id }; - saveChanges({ automations }); + await saveChanges({ automations }); return automations[id]; } /** * Deletes a automation given its ID */ -export function deleteAutomation(id: string): void { +export async function deleteAutomation(id: string): Promise { const automations = getAutomations(); // ignore request if automation does not exist if (!Object.hasOwn(automations, id)) { @@ -140,7 +147,7 @@ export function deleteAutomation(id: string): void { } } delete automations[id]; - saveChanges({ automations }); + await saveChanges({ automations }); } /** diff --git a/apps/server/src/app.ts b/apps/server/src/app.ts index 9102d78ea..1c9591169 100644 --- a/apps/server/src/app.ts +++ b/apps/server/src/app.ts @@ -144,7 +144,7 @@ export const initAssets = async () => { checkStart(OntimeStartOrder.InitAssets); await clearUploadfolder(); populateStyles(); - populateDemo(); + await populateDemo(); const project = await initialiseProject(); logger.info(LogOrigin.Server, `Initialised Ontime with ${project}`); }; @@ -200,7 +200,7 @@ export const startServer = async ( // initialise rundown service const persistedRundown = getDataProvider().getRundown(); const persistedCustomFields = getDataProvider().getCustomFields(); - initRundown(persistedRundown, persistedCustomFields); + await initRundown(persistedRundown, persistedCustomFields); // initialise message service messageService.init(eventStore.set, eventStore.get); diff --git a/apps/server/src/services/sheet-service/SheetService.ts b/apps/server/src/services/sheet-service/SheetService.ts index a3b67e1c1..a30f148fc 100644 --- a/apps/server/src/services/sheet-service/SheetService.ts +++ b/apps/server/src/services/sheet-service/SheetService.ts @@ -114,18 +114,13 @@ async function getDeviceCodes(clientSecret: ClientSecret): Promise void, + postAction: () => Promise, ) { // create poller to check for auth pollInterval = setInterval(pollForAuth, interval * 1000); diff --git a/apps/server/src/setup/loadDemo.ts b/apps/server/src/setup/loadDemo.ts index 9beab42ef..43a7b6ca0 100644 --- a/apps/server/src/setup/loadDemo.ts +++ b/apps/server/src/setup/loadDemo.ts @@ -6,14 +6,14 @@ import { publicDir, publicFiles, srcDir, srcFiles } from './index.js'; /** * @description ensures directories exist and populates demo folder */ -export const populateDemo = () => { +export async function populateDemo() { ensureDirectory(publicDir.demoDir); try { copyFileSync(srcFiles.externalReadme, publicFiles.externalReadme); // even if demo exist we want to use startup demo - copyDirectory(srcDir.demoDir, publicDir.demoDir); + await copyDirectory(srcDir.demoDir, publicDir.demoDir); } catch (_) { /* we do not handle this */ } -}; +}